diff --git a/build.xml b/build.xml index b6a1307ad..23e2ef293 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + diff --git a/sonar/examples/pom.xml b/sonar/examples/pom.xml index 5a04f8d16..ea53c0597 100644 --- a/sonar/examples/pom.xml +++ b/sonar/examples/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-examples jar diff --git a/sonar/excelant/pom.xml b/sonar/excelant/pom.xml index 3aaf8eae3..a7b9408dc 100644 --- a/sonar/excelant/pom.xml +++ b/sonar/excelant/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-excelant jar diff --git a/sonar/main/pom.xml b/sonar/main/pom.xml index 7a9da5ae0..36422a83c 100644 --- a/sonar/main/pom.xml +++ b/sonar/main/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-main jar diff --git a/sonar/ooxml-schema-encryption/pom.xml b/sonar/ooxml-schema-encryption/pom.xml index e21fce2b3..cbb2eff7d 100644 --- a/sonar/ooxml-schema-encryption/pom.xml +++ b/sonar/ooxml-schema-encryption/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT .. poi-ooxml-schema-encryption diff --git a/sonar/ooxml-schema-security/pom.xml b/sonar/ooxml-schema-security/pom.xml index 542ea9e34..a822c7343 100644 --- a/sonar/ooxml-schema-security/pom.xml +++ b/sonar/ooxml-schema-security/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT .. poi-ooxml-schema-security diff --git a/sonar/ooxml-schema/pom.xml b/sonar/ooxml-schema/pom.xml index 66ad1cbe2..5e2b9fef5 100644 --- a/sonar/ooxml-schema/pom.xml +++ b/sonar/ooxml-schema/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT .. poi-ooxml-schema diff --git a/sonar/ooxml/pom.xml b/sonar/ooxml/pom.xml index e7ffcc2d1..27636cdfa 100644 --- a/sonar/ooxml/pom.xml +++ b/sonar/ooxml/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-ooxml jar diff --git a/sonar/pom.xml b/sonar/pom.xml index 738c3ec5e..8e2a9fc42 100644 --- a/sonar/pom.xml +++ b/sonar/pom.xml @@ -3,7 +3,7 @@ org.apache.poi poi-parent pom - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT Apache POI - the Java API for Microsoft Documents Maven build of Apache POI for Sonar checks http://poi.apache.org/ diff --git a/sonar/scratchpad/pom.xml b/sonar/scratchpad/pom.xml index 2645cdca9..6760762d6 100644 --- a/sonar/scratchpad/pom.xml +++ b/sonar/scratchpad/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.16-beta2-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-scratchpad jar diff --git a/trunk/.classpath b/trunk/.classpath deleted file mode 100644 index 3238145f4..000000000 --- a/trunk/.classpath +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/.project b/trunk/.project deleted file mode 100644 index 274051f30..000000000 --- a/trunk/.project +++ /dev/null @@ -1,18 +0,0 @@ - - - ApachePOI - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.sonar.ide.eclipse.core.sonarNature - org.eclipse.jdt.core.javanature - - diff --git a/trunk/.settings/org.eclipse.core.resources.prefs b/trunk/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 4824b8026..000000000 --- a/trunk/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/trunk/.settings/org.eclipse.jdt.core.prefs b/trunk/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2b245ec7a..000000000 --- a/trunk/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,395 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/trunk/.settings/org.eclipse.jdt.ui.prefs b/trunk/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 5227bd285..000000000 --- a/trunk/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,131 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=false -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=false -cleanup.format_source_code=false -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=true -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=true -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=false -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=false -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=true -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=false -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=false -cleanup.use_this_for_non_static_field_access_only_if_necessary=true -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Apache POI -cleanup_settings_version=2 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false -formatter_profile=_Apache POI -formatter_settings_version=12 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=true -org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;org;com; -org.eclipse.jdt.ui.javadoc=false -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=20 -org.eclipse.jdt.ui.overrideannotation=false -org.eclipse.jdt.ui.staticondemandthreshold=10 -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=true -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=false -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=false -sp_cleanup.organize_imports=false -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=false -sp_cleanup.remove_trailing_whitespaces=false -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true -sp_cleanup.use_type_arguments=false diff --git a/trunk/.settings/org.moreunit.core.prefs b/trunk/.settings/org.moreunit.core.prefs deleted file mode 100644 index efd9d77f2..000000000 --- a/trunk/.settings/org.moreunit.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.moreunit.core.anyLanguage.srcFolderPathTemplate=${srcProject} -org.moreunit.core.anyLanguage.testFileNameTemplate=${srcFile}Test -org.moreunit.core.anyLanguage.testFolderPathTemplate=${srcProject} diff --git a/trunk/.settings/org.moreunit.prefs b/trunk/.settings/org.moreunit.prefs deleted file mode 100644 index 659afaf8c..000000000 --- a/trunk/.settings/org.moreunit.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.moreunit.preferences.version=2 -org.moreunit.unitsourcefolder=ApachePOI\:src/java\:ApachePOI\:src/testcases\#ApachePOI\:src/java\:ApachePOI\:src/ooxml/testcases\#ApachePOI\:src/java\:ApachePOI\:src/scratchpad/testcases\#ApachePOI\:src/java\:ApachePOI\:src/excelant/testcases\#ApachePOI\:src/java\:ApachePOI\:src/integrationtest -org.moreunit.useprojectsettings=true diff --git a/trunk/KEYS b/trunk/KEYS deleted file mode 100644 index 5926e7c28..000000000 --- a/trunk/KEYS +++ /dev/null @@ -1,2495 +0,0 @@ -This file contains the PGP keys of various developers. - -Users: pgp < KEYS - gpg --import KEYS -Developers: - gpg --list-key and append it to this file. - gpg -a --export and append it to this file. - - (gpg --list-key - && gpg --armor --export ) >> this file. - -Since the KEYS may be needed to check signatures for archived -releases, it is important that all keys that have ever been used -to sign releases are retained in the file. Entries should only -be added, not removed. -To keep the KEYS file manageable, it's recommended to only add -the keys of committers who have signed releases. -https://www.apache.org/dev/release-signing#keys-policy -https://people.apache.org/keys/ - - -pub 1024D/12DAE9BE 2004-01-25 Glen Stampoultzis -sig 3 12DAE9BE 2004-01-25 Glen Stampoultzis -sub 1024g/2BBB28EA 2004-01-25 -sig 12DAE9BE 2004-01-25 Glen Stampoultzis - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.2 (Cygwin) - -mQGiBEATU6gRBACo3iUkfku4/G2q8ldWFiiCekHK5oqx0U1N6fyO+Xgs+6V6btEZ -drF2DUCyto6ig4FJT81L34HUQ6l9bPnpa4nNsl2EMBknY42LjmC55x7Q5rsQbiRj -+2JkoQJk2Jc3hneuh4Wsv49stOCDQMOV5BtjZs31t7rr+wuKPMkIw/Nf1wCgngI9 -ZWFyLxspoi9bL1/xBID18jsD/RxGBep4F8HwXEdHTeHnmjEuJSlYhmAKQ6Fd7bdb -ex16a54Gsg7fVD0rIIsytzVUACQMi7V6tmE4Wf/XaY7+ma5w4gCsxUCIeujU4Y7i -WUDwtlTkr2IudmoxSIDDpS12NPZqCP7PbU2RK+KwnnITjs80a+QlHYaO9te7HVcL -F6YIA/9YZkYp5TpoMO1ISnlv0gXMcIaznbNMoRgeXZHvYyEvy014jArHmG41LVBj -6TnBHFLQi4xA7Ql98oIgfszaRr/9GshvoL6Iu1x1SoV7dMrqFBC6e2JD9N/IgBtZ -EGg7US3nIJnlCjJSIkXKfPJL4FyYWwt6IEZcF6Mi/USsyLA6wrQkR2xlbiBTdGFt -cG91bHR6aXMgPGdsZW5zQGFwYWNoZS5vcmc+iFsEExECABsFAkATU6gGCwkIBwMC -AxUCAwMWAgECHgECF4AACgkQONrI4hLa6b48RgCaAqQg0wtiOQ8jqX6S7tZi1OMg -CQAAn2Ty1d/UdGLqlGkCPMkaB6otTMhZuQENBEATU6kQBADUbn5pT2D8vi64RU5E -SeTn/rNzLglJ4nzoOfeIcHm7p3hppjT0Q1YbHvdOSaigYApzxoiSf+0Mt8NSCfDf -B/wjfndHlrcdPkiJi4fBkQHihcuJtEgOkAwXfSJ+MUXG+fEgEuGdYm7tNV3n/eOY -gn9Vzs/LofrQ7nY3+WkNOUia/wADBwQAnqZ4wPm0VY/fjCWJ34wvSfPk6Qg8m502 -MfHIGY/UZ+BY5DK3iQR8hrIu6FU0tn0qoF7PCNehOtd2cR9kA7I2gyfaVR8JY2Ek -F18jungrNRrNuNx3rJeUD6ViQjC44K4vf6y8CkxmkHTmB9ZC2+uGdMeOdDvbck/u -JA+XB2tykJWIRgQYEQIABgUCQBNTqQAKCRA42sjiEtrpvpy3AJ4trdVLGCzJwB2R -Z/zxD3xBnTdY5QCeNUdw2VcsrzAF541sawFRxOmL3eY= -=la1N ------END PGP PUBLIC KEY BLOCK----- - - -pub 1024D/4CEED75F 2004-03-24 [expires: 2010-01-01] -uid Nick Burch -uid Nick Burch -sub 1024g/5E0E1748 2004-03-24 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.9 (GNU/Linux) - -mQGiBEBhnKkRBACOPYQoULwS4a37UsNiinwqJ+2XVMal5FQyMOc6hNneyvdau4cO -oSNgdEkNtAN9fecSh06wke9mFBR9iVD4QpCqiRk8s20lr4QAFw4urxbe6iOf/Ytr -q7I0t3/zpzx4MuzwvN7ffPaE5EzE6F3ryQDkSulMeLzDbdRSZIezocDyQwCgpKTA -UtpUwP38GH81VCtbEWfEJpMD/jraHQdr4KXnv7iIvGtOLbODrmgfGfZYPsGoJlHl -+IIFdTfRCbUNc1Mh9/vcP45bnX62Crsp2JuDxZo8Dq4buE77pZ/Yw1aaIzhHBGcP -YlIvLz/S2WCZxKyNrIE86WK/DlMAXoHAJigErD+X1UYLNVb0+u5MeHN+FF0yLMS4 -9Cp4A/wJznIOc7sO+L6psNNUWSu1G9TAPo6QRu/6CTaYHMy8uMzovjrlYF9bjZFe -9TVJUkHYMv2tsthZ7eWG0jAyHabvn1XgCDRjJcs10FZ6obIU5BDaJLjaxMU+u91k -F/AiO1zStA9wuasITcurU3BF4f/ZywJXwVDFvpYUh0xV1pK0qrQfTmljayBCdXJj -aCA8bmlja0BnYWdyYXZhcnIub3JnPohlBBMRAgAdBQJAYZypBQkJZgGABQsHCgME -AxUDAgMWAgECF4AAEgkQ9cJgFkzu118HZUdQRwABASjeAKCXv83+hBN7PMqx9Ate -13EN+mCsNQCfSWj1wVXl3vKBZizH3yQzDDl6yuGIRgQQEQIABgUCQGGc+wAKCRDI -h7WuwLlVejPLAKDoFiCmPsApgl99/Sgbi5+GD6pXXACeLQyS8rg+rz7zOagcMJ+T -XdY87wKIRgQQEQIABgUCQGGeNwAKCRB4Ma11Ja7RdocaAKDVs5beITXLa/9rW5r8 -Qptyhzp1dwCfVxgAMgL00Muh6gSnk7MI23xUgpmJAJUDBRBAYf1wIBRZzICIOAEB -AcEcA/9fO1E2pj1QSOZiX53ngKxF+Vxo8XfuBxbplXQaN2/acUsOGZVp8r5oo+3w -0qzn7YLXpStlnFz40UAjAWJBPtYTnzGR3twpChZRDTRrmaGVAssG+DuJwHBdsC4D -W5QisDTRFg+lyZ5d7bI/H+ckbXma+7BRwPtG0rRXK67O1p3lo4hGBBARAgAGBQJA -YfNUAAoJEEPSiApOm1UCnSIAnjg0phq4MhuzTnBoHoHIbqO7Jj5+AKCQ9HC/d/gO -Hitfw2bcjHMKSwgDeIhMBBARAgAMBQJEEDtmBYMFt2LDAAoJEGao+or0Qx8mutAA -nR8OikkgQDLxBxdaFtFHtsc09lR+AJ48A1Nkex+ZNl0VAEgWLqqoFVkWDIhiBBMR -AgAaBQsHCgMEAxUDAgMWAgECF4ACGQEFAkaCzIEAEgdlR1BHAAEBCRD1wmAWTO7X -X4ExAJ91jwqu1pGuK21TBKNtW+ennH9ppACdGrI/+kN/rkWMAsNgU+uJbjDE7YeI -cwQQEQIAMwUCRBBGKQWDAeEzgCYaaHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4 -LnBocD9pZD0xMAAKCRDSuw0BZdD9WK2kAJ9QCMJBHbpzbL+Fh503iw+o1ByNnwCf -f+UFND1piZvaF5XybwKoQ5Wu/NuIRgQTEQIABgUCREvNBQAKCRBghaOGQ6aJantc -AJ9QGBq5kkoI5vMhXi9LKx6b3HdETgCfXVqP43fiL+uQ7VsByLpVLDjFlFOIRgQQ -EQIABgUCRKP0UwAKCRA39o/1AVr8iho4AKDZ1rVmNXD2KAHHJZshHvwGpRz3VwCg -5Z7hpclWyw3OkKaz/G4T08lIhxaIRgQQEQIABgUCRKfNKwAKCRDVM051sTE94iuk -AJ4h3TVd62OH3GpfbNku1tT3XJcvVgCgtSV/04an+u0VSRADSRq/5uBNDeGIRgQQ -EQIABgUCRKkt2wAKCRAyyeTONkLLS6iUAJ97ELvsa6Wlmg5UCsa4AAephiEDFwCg -n0YHqUwx2bVWL1elR53bTWaqEqKIRgQQEQIABgUCRKquQwAKCRA1i6ozUPlhFmyZ -AJ0ajTr1w6VG+Rp8j9MwbziOKQIVrgCeID7Mg0N3mDFE414J21I6As5ad4uIRgQQ -EQIABgUCRKrPUQAKCRD7N9pAMy5jzVa+AJ44NFxehfXUyS5Fwkx5g58Qznv1zACf -arUp2KPdpN0vu5ppqNsFs3F1IfOIRgQQEQIABgUCRQ+CKwAKCRCyvrxAFSkkr6Fg -AJ9RvBUJ4WpvI5sY50PPCQQDrOW0CQCbB9HoxMfs6zZFF0Rm0h8IZ9ONzZyITAQQ -EQIADAUCRKMCVQWDBSSb1AAKCRCUUEP1NcEA8Hd1AJ4sVLyTaUk7hNmxCMO0KmAI -IAJQ5ACdEyi6yNEOsuQrmZ8fvtl8CYp+E/OITAQQEQIADAUCRKON0QWDBSQQWAAK -CRAtIatlZUYbeVBwAJ0YCGDcAhRSdD7iHbqONN4ZJsEeqACcCus5Mck12rdUNuH3 -INWTm5MmX0eITAQQEQIADAUCRKRJ+AWDBSNUMQAKCRArfoLnQ+8hHytfAJ0busES -2PyWxOkyRidcllRSX0rLsQCeKcKHsQjCn6fd/nV7VN/9pwAJRfKITAQREQIADAUC -RKMbGAWDBSSDEQAKCRBWDQhh7n3HTviwAJwKn/we6Khznqlq3svyYn6Z/6FZsQCg -3acpog5M5TXkneKEoml3q9TjmC6ITAQREQIADAUCRKMbKAWDBSSDAQAKCRDKcp1i -YD1PVH7JAJ9M7kVdEF8mLbkjpe9YwHiytkn/HACfa9YGteCB615GB2umE8N5FrIF -uSyITAQTEQIADAUCRKOpaQWDBSP0wAAKCRDdumS6LDEtL8KaAJ91mvnnKJ1sP/tW -8V5ZH9pmVXLy0QCgiZnT7s9rsdAAO7wY/gqctT9rDrGITAQTEQIADAUCRKOpdwWD -BSP0sgAKCRBQjq7FMC2laILDAJsH0OlzaG31pD6ciEJdzzyn8R6kDQCgqY0Wp4Cz -qVRVeZDacRKj13J3fMSITAQTEQIADAUCRKYBJgWDBSGdAwAKCRBMBCgYMRo95cNi -AKC7fFzLCq2StE07S6rzg6qlF2tS8gCcCvoT7YvhqabHSuph+hbrF2KmabWInAQQ -AQIABgUCRKkt6gAKCRA34/Rf7mXjIWs5A/9xV456Fiy+QelbGJ79sHIPl5Kn8VEK -MuWvR+dknShRg88XdrGshMFrX+t2enDxr2upL3R8CA+eVDC/0yRj8SLbvn6nfEOJ -qS8eYKkggdDtWU5nbb4BZvBKAXlddAOsZSFD/h6qw6Rl3ZiDTHOJKjq9Tip/Y9uH -MpdxkKBNS1bqJ4iiBBMBAgAMBQJEo6lgBYMFI/TJAAoJEJrNPMCpn3XdHO0D/jpi -VLkyBXm9pyAaVk+pwEswGiGSheHuJWlkBZDOrMFjM1JKJVb5AQ/VNwxNCmvayrWx -jQEUXCR7eCT3Cp83Xh5YbbdEw9SHkgL7wEtGsK5zYbvtbWt7691P7hf0nuOwCOHM -0oYTtRvwtEPvhwyfh/sSaMrCB40dHcER3Ah8pQBmiEYEEBECAAYFAkY44mwACgkQ -FUWz/uIi3k9ExACePdDgJJIIbFmHOlKsujJWTC/qrA4An0uHorCRVAz8+kKQZgIx -5NqYTsZYiEYEEBECAAYFAkY451cACgkQY9CtrpESA+RUtQCePtNKg8jbrN3ueYjS -trawh3G5lDIAnAnQ/v9Ma/qv5wr9XMDqy1J0HmSfiEYEEBECAAYFAkY8i3YACgkQ -mHDv8/EvYHJ7FwCdEWzRg49FioAHJYyA4aGaBq+E6qAAn1EJYuOIapCkdTNtgSdO -VED8qNk9iEYEExECAAYFAkY9n+AACgkQLrlGgoiBdALMyQCgnKtTU45W/5/onEQw -vmelpzjD3kQAoLbovb7PYL17191lNkhqXQwPfhx4iEYEEBECAAYFAkY99HEACgkQ -oHLU0ENYxYSPdgCeL76rvCWZZS54TQdBEdmUjVTRSLQAoIxh3bzlylWpbwcoX7cF -vXWH7H0OiEYEEBECAAYFAkY+A8sACgkQAqWmBQt+bPrESACfa1xOCw7mLohF9UT8 -LPrwfLiBoUcAoJ5wZPWEgX48CYqq1AgvCU/sno/AiEYEExECAAYFAkY9sPQACgkQ -4eHysJkO1KoEBACfWIcYHg2ATN2RHfro75oc3UUjGU8An108ccnwGPCSlBy/hMD/ -/5FNUMpCiEYEEBECAAYFAkY+FSQACgkQVCINLMh0FVwjQgCff9ekxXn5ThZg1Jh8 -6BI6ijHxqTMAnjNNj/bANMs8/qMqNIMaXt+U+4zViEYEEBECAAYFAkY+FTcACgkQ -Pipvwl8piCQrNwCfUmbCJLjfK96uCHgFoCyRwxj/F2wAoLwy5kBVlUE5lRZeIHt0 -WkMi3TYuiHEEEBECADEFAkZIxWEqHEhlbm5pbmcgU2NobWllZGVoYXVzZW4gPGhw -c0BpbnRlcm1ldGEuZGU+AAoJEDKGTkGchSIrm6oAn2N1GZofPwqJQR/Q3UeE90Lt -/Vf0AJ0QjqyO+yEKrIGxCnwBgXSy+6AjJYhGBBARAgAGBQJGOPRmAAoJEHPdjBYB -UwI1Km0AoIa21wJevepbT/5TPll7QJECGD7kAKCdCWkWAzDVYslcO5Ph4dzwScxD -T4hGBBARAgAGBQJGQPXcAAoJEA9FCiZiEL/A1PwAn3LhRkQs08VQQlFARFK34dt+ -R6l1AJ9rYqkIQ8HyRW4hNkoqBGrEBhf+SYhGBBARAgAGBQJGRhEFAAoJEKIRWuFf -a4tymwAAoNT4GmHKozQ6hH9VS+4LSLwYJTeIAKDgpVB3iBZ3YfLsP3dSUFXS59A1 -zohGBBARAgAGBQJEow8CAAoJEMuuvjmkbEyhuz4AoJP5fyaw7b51/Rxj2T3ErVFi -L63EAJ4zUAt6oDiAYcGM8aIPpdTbHj4gZ4hGBBARAgAGBQJGTENCAAoJEB8hI8Nr -2HKg3BsAoLG2CWQCFOdb7dp+CEm3F1srkOUxAJ4wxo52iD70bLDz1Ic+zxWYNwwL -oYhGBBARAgAGBQJGUm0/AAoJEDLB1u8PFDvByzoAoLey7JpjuwxQEbJcsf30OR4+ -DUCQAJ96lZ1+sFa5/uS86DqtEzYZXfxqY4hoBBMRAgAgBQkJZgGABQsHCgMEAxUD -AgMWAgECF4AFAkQQQhkCGQEAEgdlR1BHAAEBCRD1wmAWTO7XX5UOAJsHKnihLRiV -svMt6Iwss6k9ZkqAmwCeMz7aSaQp088fLrL6c/5cdEsM/haIRgQQEQIABgUCRl7U -3wAKCRCahtfM0arqYE0OAKCcCVPPi6ffL/SlJaVRYL6k3xhinACglATLwd4moxdf -ZMJABjncPlX4P9qIRgQQEQIABgUCRqVKAQAKCRA5vlGhCEyRE0svAJ9pJVwmNOqp -ltECGy6d65RrZGnSeQCeNQ/r+SK4BWuC+a9LunFXLXg4KZuIRgQQEQIABgUCRq3L -OwAKCRAzzWczr17EUo37AKDDROCi7WMPHymORd8X1I87WSRlrwCeJtcghuuOz9rZ -hQe5ByqdzSuCRy+IYgQTEQIAGgULBwoDBAMVAwIDFgIBAheAAhkBBQJHYW1qABIH -ZUdQRwABAQkQ9cJgFkzu11+WUACeIhfw6jEXCkbuMfGSdCsodaPnWYkAoJw+G8jG -If3bd0jQg/QW/AqrlVjPiEYEEhECAAYFAkf9LD4ACgkQi5YpQ/wkPzw7tQCfdDjJ -ZTmP0ZAzsMmTHSQEHiiu0tQAniAq3s1bshQPtH3TPfJGIuxkrmgaiGsEExECACsF -Akf9JskkGmh0dHBzOi8vd3d3LmNhY2VydC5vcmcvY3BzLnBocCNwNS4yAAoJEH9Y -T55N2dHEV3EAninabeLlvGJ3Wt98u4g8kaKBcnGyAKC2wa4tnUZmkIXtpNoOZuoo -1nac+4hGBBARAgAGBQJH/UV2AAoJEJA4TZo1x+lCZ2gAoK8UmpEcOcsdzAJdabmC -ZB4IqOAyAKDXFVEr6z/OE7H/WDExzjhdLWzatYhGBBARAgAGBQJH/cTeAAoJEBg4 -H9dLG+aY4d4AoMts+aAWK7LfgBsTvqqqPogrAv2sAJ0fSkPBoE1EFWiHrH16eSVa -wqnfXYhGBBARAgAGBQJH/k7HAAoJEP1viMYh0KcbFO8AoKLGi3vvTxj7BwDrAxiw -AcCLIqQtAKCjuo95uLA2prqo3ka5tGp4ffQgTohGBBMRAgAGBQJH/guEAAoJEIEv -IIXC1Qv79jgAoITINhmKDZneFsQl6VlZTHpNEAjZAJ0dwAKhbQARulL+l94nzkgW -23uAJoicBBABAgAGBQJH/k1hAAoJEDGmPZbsFAuBNcUD/36NVaC/kXiu24JZKq7n -ZWEk7qLa212rRIRxJwAZJKta0ov68dyO1CPgm9e9zgValGLcN52JPCA4kcA6dMar -MPqk9wWB6Pb6UfAM940Sk92AU/W29lRwaWhyMh1fC1twHELqW6VpNy5mNnhR4dXv -tvaNMkMjq32sQCCFidLAtTgHiEYEEBECAAYFAkUPgjEACgkQsr68QBUpJK+5zACg -oAz0aq1OrUoq/dnzhr7Z3XUanvAAoJrqRNBuE+n38oXZTi1oJ+k6qDbsiEYEEBEC -AAYFAkY44nIACgkQFUWz/uIi3k+VgwCfV+TKT3qn1PBzfALIPO3DMNpeMFkAnjsn -B4L1Tgl/LCRcYEH/fGkDW6JRiEYEEBECAAYFAkY451wACgkQY9CtrpESA+SZ5wCZ -AdCisYSpjSXFMlrhHDUeW7/BhCgAnjehPdZrqLC3DvP5gDpqdBPT3pS0iEYEEBEC -AAYFAkf/TFUACgkQPJpCBAwIhbSGwQCePTdVbRJtPyhsAAEKYzSu2pUOKEAAnRKO -vEhP5ZOWQLM85ZfRNVdlmNmGiEYEEBECAAYFAkgFPukACgkQjqOwaEx2V/ERfACe -MUKrZm8MAyt21NIdwCjDMigcXFwAoLp14Kws4vz+LprDCcJtjBv9O3gZiEYEEBEC -AAYFAkgPSo8ACgkQGGHDIsVgFLLczACeLNnpzZRTHXiIV2V0bM2nFI5ZELIAoNG7 -VqZlLd8CQZ46kRabdF/Wo1lMiEYEEBEIAAYFAkoEAQwACgkQwOq+CPYjp6vPtQCc -DCOVFKt7nwos4X8xQ7mIKtISPxIAnRZ1O2ohl/Yf8vjkaQBDOCYGQROwiEYEExEC -AAYFAkgJ8B4ACgkQ3oDmVhn5KRhdZgCgjmpf2g5P/76QN0uQ6AoCRB+g3sEAn1rb -byYCJYZTVm7UBTDmx8lvYFxSiEkEEBECAAkFAkicZZICBwAACgkQpHjEe8toN4bP -igCgw07F8KB86KuNxDSUeNi7ofke50UAnRGaC7wlGB+J084g5xpebaCu4h4piF4E -ExECAB4CGyMGCwkIBwMCAxUCAwMWAgECHgECF4AFAkaCzIUACgkQ9cJgFkzu11+k -QgCfb/FwMf0C2WOU/feUvPG8x1mqDJkAn2e/lNVAcx0c+iyuo59vBJ2zAbtQiG8E -ExECACcCF4ACGQEFCwkIBwMFFQoJCAsFFgIDAQACHgEFAksVNmcFCQrceCYAEgdl -R1BHAAEBCRD1wmAWTO7XX4LkAJ4/1h41iGzV1TC9yA2fKqgarsIOJQCfWNllqdJJ -VcS2DKwoxnrO19Cq/j2IcgQQEQIAMgUCSAtk1yscQmVybmQgRm9uZGVybWFubiAo -QVNGKSA8YmVybmRmQGFwYWNoZS5vcmc+AAoJELOX3RpTbavtE7IAn30QKKf3CDm/ -zE+wuKMPv9GywgyOAJ0Xc07ZuVYHWy+zUmyalUUTgMjFYoiiBBMBAgAMBQJEo6lg -BYMFI/TJAAoJEJrNPMCpn3XdHO0D/jpiVLkyBXm9pyAaVk+pwEswGiGSheHuJWlk -BZDOrMFjM1JKJVb///////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -////////iMoEEBECAIoFAkgDeRkfHEppbSBKYWdpZWxza2kgPGppbUBhcGFjaGUu -b3JnPiAcSmltIEphZ2llbHNraSA8amltQGphZ3VORVQuY29tPh8cSmltIEphZ2ll -bHNraSA8amltQGppbWphZy5jb20+IhxKaW0gSmFnaWVsc2tpIDxqaW1qQGNvdmFs -ZW50Lm5ldD4ACgkQizpgHwjJdeUxJACfa18wFcsXHhn+iqVupgy4TL5xuHsAn3bi -2H5OV7TTP0LqaEkZ53Bv/4/KiQEcBBABAgAGBQJICJ7zAAoJEBllhVDDEQYR4rsI -ANYOyVHLcQ+e/DVhYu7cDwM7sCFQxuXD45QgljCOA1B5VBCHD8D6J5LmjD+jYLTC -mwypEH4OPzCtYzlepdq2tr3aMloLRpCbbmkv6g7Ap3bc9ocmjic4TKDJSHogZ5GL -7KvMKNvGfB5STxkau0V/RY72dZFTymKWhy+7ovee7sRwQ9FZty4vdlMwy7IwE45C -HACblt4Sr4yhkHJQzI9qSLDXJ/z1Aclz+B+r+eFLijUNzGzDi4GfrFEsZNJmvP8Q -y870RY/IW1/6ESvhEiBhRAsSkOUg/MCetXc4rXmCYl6z4raHmFc7KCJiR0Jpuik/ -iPIvlI/xuvP7EPIaNRU7eaGJAhwEEAECAAYFAkhEBG8ACgkQGT8YCrVdmXdOLhAA -tnh567oUERY1k0xSh/eZu1ZnTCelRxZRBQox8x+4yqUYCVhkme+qclxNxEgSArCT -9w1cZgSvs7nxG4xzyK+O0kyrRfpYipHtDar9M4zbYiRs69pe2dS4ZaMvzozH9XrB -2tSwlrO7AHSyLurCPeHLhrU/EQ43B/ICm78ZIOrpMi4MFQjJhDjA52NVpG5ksusY -GAl14zWg4iX/srpEpwP41JTTI9MhSSS/81+UBihr6cprvP51BjysYCrwQjRjpo1B -EYiUa4O3Bcjeuye3YcJ3wv2lC7Xl8g/8y7BBo4npOrstVLNRXakWIuMCpi+tndYm -qrVKBqWBjkuKkzrw8dUYfs7xf2Pg4NfQNg8IjYgtocAHp9gv8Gjv6Bwspd8I96Lz -06hxLuPgzJ3vWRYr5HeolLOdbibkGxc+G7MBXSDyc0l3jmeoIYWjZpH4/ofLI1Gs -XwNr7Tyx+vVo3uwSarxo8s0Jny+WsBcGIstfnRqlf7hwhXxOINKid1aNpOy75QbD -bZ1PT8QTxzL2ydSxVlO/FduB9I9eWEp8/u65axQyjb2WcsmNW5B/PkPp9Qa6tg5T -TtUH2h1FGMPsD4ac8R46EyXwBFz7/5i4kb7vV3Egf0sa9COrGE3Q07cUdguh0Ku3 -GF3mrffy8/NUzMxG2IrYmK1vSBARk9slREmc0fvOsGS0HE5pY2sgQnVyY2ggPG5p -Y2tAYXBhY2hlLm9yZz6IXgQTEQIAHgIbIwYLCQgHAwIDFQIDAxYCAQIeAQIXgAUC -RoLMhQAKCRD1wmAWTO7XX6RCAJ9v8XAx/QLZY5T995S88bzHWaoMmQCfZ7+U1UBz -HRz6LK6jn28EnbMBu1CITAQQEQIADAUCRBA7ZgWDBbdiwwAKCRBmqPqK9EMfJjr6 -AJ9FwtGlQgcpWEduud3+AZG2sbtutwCeLvVMa/2tK4aFNaPF4NQWhxQQLrOIcwQQ -EQIAMwUCRBBGKQWDAeEzgCYaaHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBo -cD9pZD0xMAAKCRDSuw0BZdD9WLC4AKCHTJJJ8aK6ozLNbGzaF2jumWx9zwCbBTaW -tC+3EHcOAQCQDxJvyWyNOtCIRgQTEQIABgUCREvNDQAKCRBghaOGQ6aJauc/AKCk -Tym6ExTuynqqgyjUGf64SvSCRgCgiM9BjXX1llh/GplOrLsX9pR7F7mIRgQQEQIA -BgUCRKP0UwAKCRA39o/1AVr8iho4AKDZ1rVmNXD2KAHHJZshHvwGpRz3VwCg5Z7h -pclWyw3OkKaz/G4T08lIhxaIRgQQEQIABgUCRKP0VAAKCRA39o/1AVr8iv7vAKDm -8vafCQje4clfIK8zMM9p49iXZgCgs0yNw4/TKBiLOivD9EYbg/2AdRaIRgQQEQIA -BgUCRKfNMgAKCRDVM051sTE94gSBAKCuLDG2Y+1QIc3laYplWyMHXyhsjACgju2+ -lpq9xGv1M+b5PYdAhDFm0vyIRgQQEQIABgUCRKkt2wAKCRAyyeTONkLLS6iUAJ97 -ELvsa6Wlmg5UCsa4AAephiEDFwCgn0YHqUwx2bVWL1elR53bTWaqEqKIRgQQEQIA -BgUCRKkt3AAKCRAyyeTONkLLS8u0AKCVHlUT9Z1DNo0a4e4Kd0dF1w9D/QCfdD4p -fO7Q7Mj85WYli/d8Hj8fHeSIRgQQEQIABgUCRKquQwAKCRA1i6ozUPlhFmyZAJ0a -jTr1w6VG+Rp8j9MwbziOKQIVrgCeID7Mg0N3mDFE414J21I6As5ad4uIRgQQEQIA -BgUCRKquRwAKCRA1i6ozUPlhFuGVAJ9tFzH7Ps/aLNuIZDKyYEu86ZHDNQCePZ/6 -g83Q7/umflsLEDmjwJWGVc6IRgQQEQIABgUCRKrPUQAKCRD7N9pAMy5jzVa+AJ44 -NFxehfXUyS5Fwkx5g58Qznv1zACfarUp2KPdpN0vu5ppqNsFs3F1IfOIRgQQEQIA -BgUCRKrPVQAKCRD7N9pAMy5jzVG3AJ9ijwFqX09n3y1DRB5oTYaKrnbpEQCfW6Pe -rlHB+pr/LOsVFXBBjazXFWyIRgQQEQIABgUCRQ+CMQAKCRCyvrxAFSkkr7nMAKCg -DPRqrU6tSir92fOGvtnddRqe8ACgmupE0G4T6ffyhdlOLWgn6TqoNuyITAQQEQIA -DAUCRKMCVQWDBSSb1AAKCRCUUEP1NcEA8PHWAKDTxu78kl7H4II+e7zf+J3elYsh -9QCfV2hd9pGysjeTnQvGd9d+sHdWlSiITAQQEQIADAUCRKON0QWDBSQQWAAKCRAt -IatlZUYbeaNPAKCBhlOXXBp70dXL1rK0EQKXbBAW3gCeLI2XEHubbA+0QsuW5Txc -imxGOuuITAQQEQIADAUCRKRJ+AWDBSNUMQAKCRArfoLnQ+8hH+HCAJ99jqLaljMH -/0r+xQwPStGcdFi10wCfcGFifDf1/kNoeRGhrqLV2gxIVgGITAQREQIADAUCRKMb -GAWDBSSDEQAKCRBWDQhh7n3HThrjAJ9TRkel0blwKVBdskNlFU9UfkwkSgCfanH+ -p7oU6n/ZSYI5IGiC47crml2ITAQREQIADAUCRKMbGAWDBSSDEQAKCRBWDQhh7n3H -TviwAJwKn/we6Khznqlq3svyYn6Z/6FZsQCg3acpog5M5TXkneKEoml3q9TjmC6I -TAQREQIADAUCRKMbKAWDBSSDAQAKCRDKcp1iYD1PVH7JAJ9M7kVdEF8mLbkjpe9Y -wHiytkn/HACfa9YGteCB615GB2umE8N5FrIFuSyITAQREQIADAUCRKMbKAWDBSSD -AQAKCRDKcp1iYD1PVN3rAJ9N1tyJKWm1F9vL8ZL5XNGNepUToQCgs5VQVYaWpUD/ -yMYfZJGVo9iMb1+ITAQTEQIADAUCRKOpaQWDBSP0wAAKCRDdumS6LDEtLxzJAKD7 -xSTQm2ISTPu81XyR0FKCzW6KEwCfQqQmq1WwHfpPbCiQH1rm2Nx9/bCITAQTEQIA -DAUCRKOpdwWDBSP0sgAKCRBQjq7FMC2laGkcAJ9RpqozM8POhvOxFelODFK23OIE -sQCgm4nREEmun8CuTh4wwnSOigN+oVSITAQTEQIADAUCRKYBJgWDBSGdAwAKCRBM -BCgYMRo95cNiAKC7fFzLCq2StE07S6rzg6qlF2tS8gCcCvoT7YvhqabHSuph+hbr -F2KmabWITAQTEQIADAUCRKYBJgWDBSGdAwAKCRBMBCgYMRo95dDjAKCe1C9PugyI -om1OSp1h8NexosdYKQCfdrvNdRnQQAOwUKynG2FNT+uvnNeIYAQTEQIAIAUJCWYB -gAULBwoDBAMVAwIDFgIBAheABQJEEEIZAhkBAAoJEPXCYBZM7tdflQ4AmwcqeKEt -GJWy8y3ojCyzqT1mSoCbAJ4zPtpJpCnTzx8usvpz/lx0Swz+FoicBBABAgAGBQJE -qS3qAAoJEDfj9F/uZeMhazkD/3FXjnoWLL5B6VsYnv2wcg+XkqfxUQoy5a9H52Sd -KFGDzxd2sayEwWtf63Z6cPGva6kvdHwID55UML/TJGPxItu+fqd8Q4mpLx5gqSCB -0O1ZTmdtvgFm8EoBeV10A6xlIUP+HqrDpGXdmINMc4kqOr1OKn9j24cyl3GQoE1L -VuoniJwEEAECAAYFAkSpLeoACgkQN+P0X+5l4yHqQgQApwmwLY1GIuEUdhjFdSNL -itGjmhScR2WtVcc9B8ycqiHwdp1slM2JpiI8ywPZQvGiSlrZjpydYUm2ZuMrfm0f -3HVqDdGU/PBouKdomQvH18RSlj/IGGh+Vawo+RZdAYwT1Uz1uE/Ufr/p0hwiJw9/ -m22NxkzXhT/a5ffYHnlWy5uIogQTAQIADAUCRKOpYAWDBSP0yQAKCRCazTzAqZ91 -3XTiA/4ghbGL8OrQXctihIJr+7TZL4WnBVeWNvkkQQn/6nlKj+ESN2jwSw1mKLBT -jJldAbvRYfrmmgjys55Qu5UajovVO7nM2AZgPIFQi1M84m0zuaKZ08oIZchXjSfL -tFU18FsubAqvyEP0ZzIkQq4Ei6NDC1VxIDUFECRZxl2L1R69qIhGBBARAgAGBQJG -OOJsAAoJEBVFs/7iIt5PRMQAnj3Q4CSSCGxZhzpSrLoyVkwv6qwOAJ9Lh6KwkVQM -/PpCkGYCMeTamE7GWIhGBBARAgAGBQJGOOJyAAoJEBVFs/7iIt5PlYMAn1fkyk96 -p9Twc3wCyDztwzDaXjBZAJ47JweC9U4JfywkXGBB/3xpA1uiUYhGBBARAgAGBQJG -OOdXAAoJEGPQra6REgPkVLUAnj7TSoPI26zd7nmI0ra2sIdxuZQyAJwJ0P7/TGv6 -r+cK/VzA6stSdB5kn4hGBBARAgAGBQJGOOdcAAoJEGPQra6REgPkmecAmQHQorGE -qY0lxTJa4Rw1Hlu/wYQoAJ43oT3Wa6iwtw7z+YA6anQT096UtIhGBBARAgAGBQJG -PIt2AAoJEJhw7/PxL2ByFlMAn0ObZB//ygm5IRIrBEedKao+1fHLAJ0SE2jSlD2d -QrM9ZOTjhk69d1zLu4hGBBMRAgAGBQJGPZ/gAAoJEC65RoKIgXQCbh8An2T3UfcJ -aOBD2PxeO1jB02rsZO7YAKCfxHO8P9bgiQ1PiTYkJG7mv3Ve1IhGBBARAgAGBQJG -PfRxAAoJEKBy1NBDWMWEj3YAni++q7wlmWUueE0HQRHZlI1U0Ui0AKCMYd285cpV -qW8HKF+3Bb11h+x9DohGBBARAgAGBQJGPfRzAAoJEKBy1NBDWMWE+ggAoIQn9ssN -M+ielErvMV86t7NzFjF6AJ40Qvweaacehp2LDVPRqwI45CC6rIhGBBARAgAGBQJG -PgPLAAoJEAKlpgULfmz6CbAAoJj7TA2PSbwAV6mIxDJ5S2szAU6IAJ9ZvPJF4Xbo -RyamzXJuBmqvAzNUrIhGBBARAgAGBQJGPgPLAAoJEAKlpgULfmz6xEgAn2tcTgsO -5i6IRfVE/Cz68Hy4gaFHAKCecGT1hIF+PAmKqtQILwlP7J6PwIhGBBMRAgAGBQJG -PbD0AAoJEOHh8rCZDtSqBAQAn1iHGB4NgEzdkR366O+aHN1FIxlPAJ9dPHHJ8Bjw -kpQcv4TA//+RTVDKQohGBBMRAgAGBQJGPbD7AAoJEOHh8rCZDtSqE/EAn2eZe8Bm -9tEOD3TVq9uUFI6jWPekAJ9WBbUrwzBgcwPLkqwBkbB+5F2J74hFBBARAgAGBQJG -PhUtAAoJEFQiDSzIdBVc264AmOfhnlKk+Ln1yGp5KH/2jao0/E8AoKdc2kxlZ3AS -b3ev8mkt07CTmbxhiHEEEBECADEFAkZIxWEqHEhlbm5pbmcgU2NobWllZGVoYXVz -ZW4gPGhwc0BpbnRlcm1ldGEuZGU+AAoJEDKGTkGchSIrm6oAn2N1GZofPwqJQR/Q -3UeE90Lt/Vf0AJ0QjqyO+yEKrIGxCnwBgXSy+6AjJYhGBBARAgAGBQJGQPXcAAoJ -EA9FCiZiEL/AQakAnAnGA4d9aoF9ULf/XXv+DL6D1x88AJ44p8T/4+a7KdXmRHSF -oKlO+flPO4hGBBARAgAGBQJGQPXcAAoJEA9FCiZiEL/A1PwAn3LhRkQs08VQQlFA -RFK34dt+R6l1AJ9rYqkIQ8HyRW4hNkoqBGrEBhf+SYhGBBARAgAGBQJGRhEMAAoJ -EKIRWuFfa4ty1j0AoN4A23s1qAmCu6prVzPxgwTQEwDWAJ0Yu+TVfAK4yd7+Bt5O -iLl2CefS+ohGBBMRAgAGBQJGPZ/gAAoJEC65RoKIgXQCzMkAoJyrU1OOVv+f6JxE -ML5npac4w95EAKC26L2+z2C9e9fdZTZIal0MD34ceIhGBBARAgAGBQJEow8FAAoJ -EMuuvjmkbEyhJBYAoMrzBmjYbeIUnFGs4fWrefAS8IMcAJ9oDOjlH7YiCY8JVq1z -6jPcw4nDCIhGBBARAgAGBQJGTENCAAoJEB8hI8Nr2HKgpGMAnjSWEkAVSXLFQ+dR -D6iptacCBEN9AKCvoFa15NhmreLXEXFVVF297ZcL2IhGBBARAgAGBQJGTENCAAoJ -EB8hI8Nr2HKg3BsAoLG2CWQCFOdb7dp+CEm3F1srkOUxAJ4wxo52iD70bLDz1Ic+ -zxWYNwwLoYhGBBARAgAGBQJGUm0/AAoJEDLB1u8PFDvBVdgAnApoExYfK52LGHDP -BVFnVICqOxsVAKCiOZg2IETKtbaNJMq8s6VIxuU41YhkBBMRAgAkBQJEDXF+Ahsj -BQkJZgGABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEPXCYBZM7tdfe9YAniX3VLEq -LKdM+LUFpmTEAcx0TYt1AKCAKSb/vNAIQB9V53ir6lh0GepeXIhGBBARAgAGBQJG -XtTfAAoJEJqG18zRqupgB9gAn2pvBZD96AHWbRO1LglVVoImpYDTAJ9/PnueQo3f -ANGfjL6Ky3YhPc90vYhGBBARAgAGBQJGXtTfAAoJEJqG18zRqupgTQ4AoJwJU8+L -p98v9KUlpVFgvqTfGGKcAKCUBMvB3iajF19kwkAGOdw+Vfg/2ohGBBARAgAGBQJG -pUoDAAoJEDm+UaEITJETPccAn1toaclGPSaJ4Lyxiarj66eh/simAKC7kxmfF9pi -2YPPHUF9h7AFYE6lH4hGBBARAgAGBQJGrcs/AAoJEDPNZzOvXsRSXF0AoM3+o0ta -CMlQsPVNrWR3Q1oCdQNZAKCSDcyBFTomrWQjr3qU8Njz5cBr3YheBBMRAgAeAhsj -BgsJCAcDAgMVAgMDFgIBAh4BAheABQJHYW1tAAoJEPXCYBZM7tdf84MAoIf/NewT -tz5S1FV/I4PLOE9Uu95RAJ9iJFOqoGqFnClrlj0BnOOtEyK0AYhGBBIRAgAGBQJH -/SxCAAoJEIuWKUP8JD88O7YAn0RrApjTMPoApGlA2K8asendTgDVAJ0exP17HNvi -RetossL2IoT3RFDp9ohrBBMRAgArBQJH/SbLJBpodHRwczovL3d3dy5jYWNlcnQu -b3JnL2Nwcy5waHAjcDUuMgAKCRB/WE+eTdnRxFivAJsHddxj4My03ph50YCpYou1 -rV5CgQCbBI1k1KOhStMeAatumKxHl6uBGvaIRgQQEQIABgUCR/1FdgAKCRCQOE2a -NcfpQmdoAKCvFJqRHDnLHcwCXWm5gmQeCKjgMgCg1xVRK+s/zhOx/1gxMc44XS1s -2rWIRgQQEQIABgUCR/1FdgAKCRCQOE2aNcfpQvxRAJ450WRlG9019v/H7Z8NUDA2 -iPWuGgCeO8drcUcRvka4Nf+rBx54f0vPxROIRgQQEQIABgUCR/29+wAKCRBz3YwW -AVMCNQonAKCD5WyYnjhCbYoiH1kECtaZ+SwDWwCeJceq6Cx/ezn3guilX54oPv6q -zGOIRgQQEQIABgUCR/3E4wAKCRAYOB/XSxvmmBSiAKCt+n9yBVnsWcYz1/pxDgNB -sqMTSwCdEWY2/bqHvX4pnNmz5NJgjsaywqeIRgQQEQIABgUCR/5OxwAKCRD9b4jG -IdCnG3KAAKCnX6lv3Lp2seZjIpTfNBvm7ot69QCg6gdaH92+hllrNo1I4aYoEnAu -qcOIRgQTEQIABgUCR/4LhwAKCRCBLyCFwtUL+9hlAJ4sUdJVdkc5Bo52Qvl61mMj -RQ2LgwCaArN7TVN/mpHlK1B+sZ07WOAWMvGInAQQAQIABgUCR/5NYQAKCRAxpj2W -7BQLgWl6A/9Ir/CmmvJ5OIgsALH2hdoLieerdOvd0IUv6Ymu6Hd2UFJQRxcvuKlp -dbxuW9Rd82LIHxhQ/2qwdMrENF21vwDqp0tB6pyeqU9E1DM0/ON07BGYYmFvOqK5 -LaN4chgt0QmnTWit49WdivDd+ry3K2efE3VWD+YoDlS1EKUWbc0EUohGBBARAgAG -BQJH/0xVAAoJEDyaQgQMCIW0I7oAn24xvOl5noE/TQby/Kr5XxDf2GWBAJ49Ti4Q -o3iB+2j5JCeaMYYa0CHC9YhGBBARAgAGBQJIBT7pAAoJEI6jsGhMdlfxEXwAnjFC -q2ZvDAMrdtTSHcAowzIoHFxcAKC6deCsLOL8/i6awwnCbYwb/Tt4GYhGBBARAgAG -BQJIBT7pAAoJEI6jsGhMdlfxk5AAn0lc4Rfm9HIFB0iWqRzehNsNcrDSAJ9Teb/0 -V5Zn15NtvtEPb2Oy353ZvYhGBBARAgAGBQJID0rtAAoJEBhhwyLFYBSyASIAn2uq -5Nb+RDXubzlSM/RT2zKyrg6EAJ9OyRlc/Fzax3pOyX1CFKFLoTnhpohGBBARCAAG -BQJKBAEMAAoJEMDqvgj2I6erNW4An2cy0Lld/cf75SPfDLO92LFZt2wKAJwIR6xX -JUBgvWBbGBQZKGhXh7It/ohGBBMRAgAGBQJICfAfAAoJEN6A5lYZ+SkYw4QAn3Y2 -5DbJ/qb/xnXQHgdWtVXpez89AKCoAO3juvgHNvk7TjQjsDH2dMXS1ohMBBARAgAM -BQJEowJVBYMFJJvUAAoJEJRQQ/U1wQDwd3UAnixUvJNpSTuE2bEIw7QqYAggAlDk -AJ0TKLrI0Q6y5CuZnx++2XwJin4T84hMBBARAgAMBQJEo43RBYMFJBBYAAoJEC0h -q2VlRht5UHAAnRgIYNwCFFJ0PuIduo403hkmwR6oAJwK6zkxyTXat1Q24fcg1ZOb -kyZfR4hMBBMRAgAMBQJEo6lpBYMFI/TAAAoJEN26ZLosMS0vwpoAn3Wa+econWw/ -+1bxXlkf2mZVcvLRAKCJmdPuz2ux0AA7vBj+Cpy1P2sOsYhMBBMRAgAMBQJEo6l3 -BYMFI/SyAAoJEFCOrsUwLaVogsMAmwfQ6XNobfWkPpyIQl3PPKfxHqQNAKCpjRan -gLOpVFV5kNpxEqPXcnd8xIhnBBMRAgAnAhsjAh4BAheABQsJCAcDBRUKCQgLBRYC -AwEABQJLFTZqBQkK3HgmAAoJEPXCYBZM7tdfuJoAnRtou2khXTC6XAJ28xvsR4Ji -1h/QAJ48KdVtZKn2j4gUN9Anm+EckLctvohyBBARAgAyBQJIC2TXKxxCZXJuZCBG -b25kZXJtYW5uIChBU0YpIDxiZXJuZGZAYXBhY2hlLm9yZz4ACgkQs5fdGlNtq+0T -sgCffRAop/cIOb/MT7C4ow+/0bLCDI4AnRdzTtm5VgdbL7NSbJqVRROAyMViiKIE -EwECAAwFAkSjqWAFgwUj9MkACgkQms08wKmfdd0c7QP+OmJUuTIFeb2nIBpWT6nA -SzAaIZKF4e4laWQFkM6swWMzUkolVvkBD9U3DE0Ka9rKtbGNARRcJHt4JPcKnzde -Hlhtt0TD1IeSAvvAS0awrnNhu+1ta3vr3U/uF/Se47AI4czShhO1G/C0Q++HDJ+H -+xJoysIHjR0dwRHcCHylAGaIygQQEQIAigUCSAN5GR8cSmltIEphZ2llbHNraSA8 -amltQGFwYWNoZS5vcmc+IBxKaW0gSmFnaWVsc2tpIDxqaW1AamFndU5FVC5jb20+ -HxxKaW0gSmFnaWVsc2tpIDxqaW1AamltamFnLmNvbT4iHEppbSBKYWdpZWxza2kg -PGppbWpAY292YWxlbnQubmV0PgAKCRCLOmAfCMl15TEkAJ9rXzAVyxceGf6KpW6m -DLhMvnG4ewCfduLYfk5XtNM/QupoSRnncG//j8qJARwEEAECAAYFAkgInvMACgkQ -GWWFUMMRBhHAhggAu4x4MuU3QKtLUUhaIYMl58gIfvODPYLZRlOXvm6mIgI9zEYW -mwJ9wugIzSNlufKOahoqwOoTCFL5sdR7ExzZamNZFAwR80hQYKibGIadp0jFhne0 -MgMVMxm69bnVt6mmJjHroHVuPyjNEJvKHqxD0dvzdBjT7jqzCEsaduK0RV7fRy9M -9d6uFRoCOrjLWhdNvCH3+D3GSVJPP88M2ghOd5L/DBij77rFF6ZeXe89D8vfyq0W -lQZYh5/gkMIE3ZL1FfxYmCCgOeYSa3I1Qa6grwM4S+JBymd9+3JtzpLoAgNBxM+P -BG71Ss12xVxATwPw9SueYyFkEeSVnFAWAW2oeYkCHAQQAQIABgUCSEQEbwAKCRAZ -PxgKtV2ZdyvuEADIaZ/6lr5QL+aYDA+hqojD6fm7jQqobeAGq9e5n41EbcggEcYf -VSaHh6KUJ/nWwM61FSiA3q4Juo/JWLAU6KF4rsSfB6fHTar5N8h0kSJGGENEIqM1 -rNHwaVwqenhI9OUbJxBaKUXb/m+zIY3O4cgTtEy85uUxgDcZe+ATNT7AQOhJkWgm -GnEafJ/VCYCIsuV+aHbFqtGd1IN7NYFKKpcyVNloeXjz7n2hKe8T6Bp4RhSbGjLA -fDySukHNQDEaf4cgQr9XKaCIti15AFs+3p7beQMusMXgjKiBWaFgC6ptLsGqDgo7 -36NIyPzSsb/C/XZbebuFsyKyzxWEArlo0wzc8BZsjAfbbXvcOHqcJKi3qwFK2q/T -m9N0Fv08h0fTh/kLIuZcCY5vr57SKZxzndZSCxsm6GJMYEaX0IfzgbA1JllDWgMV -GTmAahO+pCnScYFswiftRdW5BY3+aH2+61HgLZmQwhpbnYvU4bWy/Y5xjUQoLZ9N -2QBgYH/z4FPg/jlLYQHlMTollG9EbteNLjACCuYXnKXHUsgFSJKSo09KK17wqlDp -BljARzdsF3XEfgMPfOsLQzG8gkK3OuY0NCw3uK57oiwInJL9DYJomQR71Bua+Opl -BqLn3HG4NyaLuosUeLw4x54ixFDkLD25GcUGsdseJhGh6kq+/0zf0BSesrkBDQRA -YZyuEAQAjlaXJffYOFtdSmqYmxHHSAxAnWxEtT7JQP+eYvmITOJJVLZiNCP6/smn -WBvmUduWVkyND0Yg4/L8tcQF7ZHtOg+Xz9tOM/9ojBs9K7C5Iiyt385hbzyO14jZ -DMa3/IJO4nsRq0aXuAIYw8g6f3yuYkG3xR8kb1RtSB4HBZxBF4MAAwUD/0GMHXYP -nrmwdoRGP+qLLypqTchAQWxc7JTMVpFLC9O6NAxtkuYiLB5EE7eMcfO9lYWEEOKH -TOqNYSTZwe3+N3v5+P1oRLT08ge9Ue2vF3FQfzs/4rSDvWhQIrgXypHRGGkd6rhc -yIf2Lh+Czc9UCdm3oQptczMGTXNRqAHa2YbkiFQEGBECAAwFAkBhnK4FCQlmAYAA -EgkQ9cJgFkzu118HZUdQRwABASqQAKCJnWqgmo4RHeb55WKcuvatypqlawCgiAop -7VhXP77oefACKJXYKwyHiCSITgQYEQIABgUCR2FtmQASB2VHUEcAAQEJEPXCYBZM -7tdfP7oAn23vRtAJ0vDIniIXqfsRPnpsO62YAKCEyvgx95NgRj2n1WMrKw2RPO2W -Mw== -=8rmt ------END PGP PUBLIC KEY BLOCK----- - - -pub 8192R/D84E41AE 2009-05-08 -uid Nick Burch -uid Nick Burch -sub 8192R/18C4CB00 2009-05-08 -sub 8192R/7092622C 2009-05-08 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.9 (GNU/Linux) - -mQQNBEoELHkBIAC0A5jg65W9e4W/w2lAO/vG6OkbXwOaMRF+frCgqDPIkkVU7AeF -O30xmuPpRR3ZSfbvOvOdEm4RygyxHRHgl6WUKGF6aRk3U9gxD6xfTl3n+va2U16q -Qf3lDpB1/H3QfZST3wGTtn2yIRYcbFzqz/e3GfIEKDmPHEQDhgHNDjXBU1sBnWk7 -GugPUrYbfikHzfjfVhEXNr6WdzKFpPKt9tW1oDhspGFxg3A6cgWtJhlGutb7QBTO -gQ+KeQvhNEfEAMo74rhC/6Lj1evshoJf42AOk00IlI1c12JIQY9ZEAwjbrn/592g -CrbSlQkzmh/bMeKX5qJHHE+RiknzzpOXLIicqD2uJxN+uY1WT+js2AytoF67U4k6 -+kJJiftkKgOZDml/BlgWNLAFio7D6kjl9DppcsmbYUmNF1gH/prpvA7w3uzmluso -XzyMA9LGPTg3UBN1x85D2KUAc9O1plbBi+RgBL+v7ON9oxNHS4orwcxdR7LHDxEO -oW+a4TGgN1mCvK7hgSZ9OtKMu/VoLuXSh565b9IF8QY80rESqyThSuaC+s73wjJT -0MADvmhgWsq9q5GdVxvG3m3B56wbq2Xb0Vmn7wxUVl5ASSgiHGPyAu0PP4JVSGJJ -mv0HLnAyVBWYn2Wo1+O2ac39exwkBQXWdT7hv7pnuVvqix7lKkPqxbOF5w/HBqaG -arOUQM+I+Z9XhdK1htZ92rgz0uI9BEjg0hHm+XDlLGwHHFC23HEjKrqVd7OEbE7g -b8qGse/PIjTOeDHa4xjHD5PfBMfvOIdNxvtu1Wc+GWrtJm2BllPJwN/YxtQp5nu1 -ZV8+cHGJAZ2DYfihNzZrtzoEcSBG+nCErkqQS97B9cQHh8Iu2OkNVY3ABPjEghKt -gs5H+B4foohiD6X/6hNSCzgLJ4VTxGBojUAFsL2TqX/gVgnhcvZHXwv66QBf7Tyc -zyDgEj0soqsc5kkZq2Fn4voXDVzUmviXjZCXQYmoRTsZFhe2bnlpW9i7tMIM04TU -soM/FB5LV3Em7b2olt0j9ctaLRTEnJu3hGMPFpcmKYv4R2gBM/kT2JBDAZIhyljl -iI+VpqFT8YHnHKD8gkhXL8pRHKhbFpi8RgGKV0uRZjJllJy7F5YQQrptgOb7obhR -R56H8+avh91Qyj8Lj4pG5479m5ltRW6AeYbCX1J+GcG0ekmVVmXRzc7UOZ7oP8Xs -oa1EzEFS9pCLxWBSb9sMm4uqeAPDOK+gnyhPBOk9OIsESpTxda9Jw2sBRmy+hIRI -N1maGfHXGoEotxRmZ4wLMlBzWjOoZCfpbZgJhawNkwNvJVnwpPkdFS3KxMrBFa6u -2GSSFEl+08OEFGVvLU5wiiEck3L0s7y8BBEfABEBAAG0HE5pY2sgQnVyY2ggPG5p -Y2tAYXBhY2hlLm9yZz6JBDYEEwEIACAFAkoELa0CGwMGCwkIBwMCBBUCCAMEFgID -AQIeAQIXgAAKCRCKr4jW2E5Brq5FH/4ryVlBMELqMG+FbVWQa5S0WMRaZ7iZ4jyO -rwbmYeXwg68WaiuoN5DVt0JaA8qD07q0YDFtKcZ3UxJDJ7NHhOTQyTiXUSjFyLWH -6Qtv6whBHnJxOIxEdFArxutIQsgOw0iRvGmOR3qov8+NWhmZstwcX1ERRa9f47YQ -aV8lILrDuc5IMaOkVYGngwI+k6MQ26HbzD6H8YNJOFYUxRK0mdM2O1vbqboQNK7+ -ltoEk8EwSdfTRiWmUoSmGJAE/yoqIYG+DVOCwew8xaCiaQltcHU9nldyyJvLl/GC -pRY/hoZymti+b9oXqH9ZQZ+K8374Ehn7dHa6A6GXt9W6G+LsqyP+tvNLOa1wf4uZ -ag1YauH7riXkkIX0jAwiikvM31egFUbWHRS7dHqiMyBbTowHrdEvDD+wMo9eJJ2b -Ce2Xn4pwjXgppnzUBjj+t7zm9wvAw9FsK9lZ5M20x9qjWPx0L921Tj3DWBRnEr13 -Z3gdpv/d1ByZfPA2WGh+zKr8yxOAA3Qml+cdZltEQNMrKEoPcTOaI57WEHZw8wjV -FNQEIUQit97kAeXKYE9gQAuk3ew7saabsBCjfXi3yIRwHqoPdcI1iBub6QA5jxrl -/fEPcAJv+pV7uCTtXv7HjFoo4/mQSLxYB5tg2YsBXMGXCGHaI4E2Bj4c9Ai2A7tu -UGoIE4+WfeN7yH6SjcfH54Im1QSh4MHTrcI8D7MEUNEwpJ2fjG6+5Wa+yx88vnNY -Pq31UMB6UGGF/5W6RO47OjsdGSVgHB3POwEuPDCPORALZTXh1GspraGAfwbhHyIs -j2CkQ9sR7A23OYJSgGR4lte7Ve5SsC2a0R8kn/AHS7F1bPq3WVnY2Sw2d5XBBupw -2zWQJANi0ie61pbqa5T1ySG+tzIJmkqwEt6E4i9Mku9hZrs1KAGC8mgRrZlhVK1B -ee3JKL3acpHe/vIq0CWRZeBV0jD4rP1s7vf3CsUdYoBkycSTOaHG42yDmER6jG+v -FYAD3Mf7z+6Xp3GXmBYhEkFo7llc3kyQ/lRAqzhYwj6lbYO+SanTAOe8GLzPoxRC -snIvkzEZFAEdEa/mDnRm+jtCgBnpVi5wVmj5RqnUE2mdMuyEwaV33lgEum1EHeXg -IkyrPsqETjGh8YntN0pyesl4Q4MubTn6Av4jbSXt9Of66viw3BP4Lthxv7b1Rh58 -HkSUrxSwyRojXlVGiWqgc/cGs0YBaTpsZSIgqYQnEUpQZKQZWSGtbSeXlDqZCRiN -3Hx5eMLysc1Kl7EPt4nseZRdt/uqgvn+CuZym6VWg1MlAdoJ5Rnc4mkQhFM1v+bV -knAc40CddFCY/YZ4nSbGwoUGdTCgy/OKeLUdL5Qs9TP4vgRZYyRciEYEEBEIAAYF -AkoEMPsACgkQ9cJgFkzu11+QpwCfTnrrGd8BVgF9t08+W9aL++BoBVcAoKGNMzwr -BNipD6R9dSck/fwSrckLiEYEEBECAAYFAkoERU4ACgkQ1TNOdbExPeJyXQCfdZg0 -oS8dfOiE2WAhAGT6lwz6rg4AnjY9DDcwDgq2OQ6+v2c3BfClTb/riEYEEBECAAYF -AkqhhAoACgkQYzuFKFF44qXqNACdHXtNK+o2I8IBn5jJTyBKYGgW4REAoMH+wJBJ -/t4s1WWRY5/a64x7r/SOiEYEEBECAAYFAkr7BScACgkQEy5J1OQe3H5R4ACePe6O -kKfKNZ6Ldq0ivre+1pWfbjMAoI6XDzq6JRlOENrK4LtutGYELNv5iEYEEBECAAYF -Akr8hPcACgkQyceSTlEEfWZVYgCgkZp3OkShIFxOm3mreN2v2T2UUtAAn2CuwqHK -6jITsLhbN0ej8uuFa9UxiEYEEBEKAAYFAkrzvA8ACgkQmx/anzwGIjESHwCfdjfj -xeExb4avvsl2g+uWfUaDt2AAnAvUTw4mA5qrQG7QFukF3WuzzefoiQIcBBABCAAG -BQJK814HAAoJEIWPxMT0OFajVtgP+QFkTX5/+15HJd6EEfKf6L4+Fox11JCgc8sI -E9uizJYBUikjwM5PYQ3WYiRoAUmbY8vu+c9iRNKrCYQ3Xzd+JE5CYR3lrR3XqxdB -icdMoQsr7IfV2dAUgp+AkMmMNSlhtsRyXwSamfW+LoXjXT21N+SawNhICEiWMfEy -8poNdKuB87kFZdQjnbB7C2Rs0cEMFJVqKXtwBNPaE8vGL2+m4BTLlZrg4T0TrC4L -iPaizxAy4X/TmEuWWqXjEmdgIzULZSQJ//gnBDlJ9ldoO2ZdaALPJJGPTx7XsiSW -ptbmbl6M0NczjqgWh402a/g4A+2Uty1NkOjKdS4kH7zkkkAIV3p8166u2Tr8YGsV -4ktqXWNt6KV0pVi9d1VE6kwiy9cNGAMLfCcsyo7sGK7JNXaUzjvo7M/orZdetGuA -ipmJc3JygB2LmTcASPYp6pMMLZJIhIFGx3CZ6qp5SINzX5uEw+NSpnibXWhk+8YV -wgd10yVqAXqZBFaQr5cTKzioqqHWqJnhaDuEs594EKaUo8TC7AsJJyIl2OWOqO08 -YaTjaOc58Ahyu1UrRIrL1dGrifF0THSqxMx1TkKq792Srtq2U+OvfjSmg3rs1v62 -TXNORwXNVFqcoExK3JH+YJyc2in4b+55qsndrRl5U3NA+v9ZDE9e1+NOPbz5io5/ -bd2N4E5xiQIcBBABCgAGBQJK8zm4AAoJEDF8bfg8dwXPh1gQAJ4tALW+m9CAyzin -VhNQI9grw+N6e5QkbDTPFM6/AKcZcytUZ7wlh7qaTWUC8eQXi7Wt2oEHvOMy/Qp4 -yw8awWaIANzKS4yU8hW/iwfTsWLHU/685IpJJrP70BMDCTbbyOUuDE20/DSRqIeT -YVjq+h2zgdHivJXaJAJLUoEGR28RefSyOlzK9rGGyYL8PYkQQuJkfb63uUscwdDI -kjUeqKpwWMUEX33SC4AahNfy5BrzbAK4L8IdrVCtgSHi3s3z9aWxzYyDcIdL7wkY -/47LXbdnAWpxtIvgGTvyiWDnGDCbKDY3UlwM7yAid3jF/RiIme7FksHlK7/UtbI4 -/a8get3xETX8r6ZMBZOuRs3iczK/VZI8OLIWHw+7VfUshd4y1BJDb78QP3b9hZWY -UhGBHa0kcz1pCfvswzT02xupc28X5/Ye6CinbXwFW2wh8GKkqkdN2Ni3b/inIFDj -jSuELFX+NVV3UhTlu4XGftyVwOD7m+CeTRtjLPzMdXxt7jrtillWu2cUOpvxu9pa -zk/UgfBYZS3ZKksaOK13krRXGCpBp4vR17Z2WQycXAPEJiAF6t1Ip30l9cU3bZsm -rQhpP8+nxrqekhH30aVSdv1zLlOyPA8X+foTnRTn/A5+P+JEEpLuGLdyT9Tm1Orb -Z3TW1GbcR/qLEEKHdRw42Qk5GOXOiQIcBBABCgAGBQJK82DJAAoJEJmgMCnd+hme -RiYP/3+oOsn2JiNvF5yq2Q+5XWg/B333XY6Ab/dSUg85c21M0RDGk0r2/ZvlS/Ie -Z/ijcm0LUQv+bYgP5DjnKX2QEm1GJYEhOvRfOw1vY+mZfC+bj2WV/nTRo2wnc7Ig -5XZdr/rqLoTlEdealwQdv6fjoocJ3d0r9vDfZl4YC3ueNW1WATmTPJqLrbm6L3it -v3xeW6rARr6zUhWkYRE/3h1/Io6LbU6VIqASsIXwtNn5Cxxkf7fjfvkzPpTU5V7g -JPhC9e0+/U5qXRi9bsLGqhC2Twf9SwdtX3pRtc1CZIl1ux72YZNoEnF3bGBCr1ZA -yvJJR43SobEgIqZkx4ykOJA7LHgNuz7Q8lehhtpyocYPuTFbZSKUnuBIO64qjiYt -OMp7C2GraFuVO9z9gxLPcCQKjDiDS7f2HuAv4YGQW7GDssO4V9/NnxM8WbtMjO+N -xuVcb7YFrQPJBlCINvk1ThJgsbrXPVa8IP9NWUCn9tQj4whno+/Mqmenlw+iiX+L -LeOs2NnJ+FI+9TUQuf4/aX5uTRM2yV6wl9tj6Wny+bejJxUaZOXvs7YBN6G0UW/Q -cMFV0GXQlhfEG2LXA62mVRgXC9LcpOtJDeXrR/tzUA12VFEqnhpqx06NGzWIj+bg -K3WH3PUA1jMJZqhScMT6xJqR733G74ufXC6IjzSJkY5CJ4UhiQIcBBABCgAGBQJK -87rxAAoJECBchnPcdCx8HroQAMuKTK6tUNzN8a2TQ+LBI+pF2adOkY4kqO6cyJb4 -2VqYapTCmbaDBxw+10MW3pZxAh0WJKXrMJZMA48cKTowwsa7kDBuzDllQQO+DH5n -4OFvNnmtqvnnHBJuWEN9mWaSLf5KcpWFp5dnqqkVRYn1SFQqX1QSI7yUZUQ19Kfx -ocGiPy3EZM+xyxlTxzBjIAST7ywsrSP8/VPsYSehwOv/XL9qXeJk5fRsWezm4CF6 -Nqv+vcOjXVqsRB8KflEDuUk/1lfGcBrnClqoJXxLK04YujxgFTzPQy/CbtIIqsbM -q/qr2H8RyBuwhT3rA8guNBmZmS/DHA26wH9ieefQKX/zJclO+GGUoJSlsiKRLV2W -Ultw11MWwLMzvPm9fjk+btx7v/eUcIH9MldOo1ovIuQhtPXCpdbOUdIh/0drGf6T -86KhjRD2l6UKbiJ8WZKtBg+eDNf8CmLpENxBN9V1wf+MLHbmjg6oudq+yNbjrOYF -AIDs4lbn/2oUJjiyxMnOCh7MitRq4arSZDr1d/SzavchCMueaowh5hCUG08J3ZQz -ZYFppQ9MbD9ctnBzFeBbHobIQeSHERhwrdE1GeioM1AItodVKHphASIPBJHI1O8w -INXsh6xSYPdnDwwy1RvUiFjIcEpO5eEjjsAhuOpgnxer99b0WK5totjE48NIXWow -JZXjiQIcBBABCgAGBQJK+J4mAAoJEBDAHFovYFnnA7kP/2IyYgAF6n/RehprPXAX -dPPPG3yP4/xksAOl2IQR+6HEt9pwU9AZu2Ha8vumnXnohX6CAxbT96JhObBMCQny -O4EPFOZ/9dCGJRz6hFtac2es91r31vIPapYcN/Lkq3XC8kOQOalJwT3MG+7gnIPe -gk0H+bfG10wQ89Pm/jm6U9jNvG81ZMeRkolQx46piS+xletRVagNN6f+jaUQZeyL -hkq1F4WUgrFWBNqJkvjIgtyyU6e0/Q9FnbxFL8pz8qayP+DnABoeC5ZpjfPqRzhb -4XPWK0bRRg0KJ1JcVGlTq+TslSsdyinvbWqQjLhAAcIQztIFzvw9KTPAkUNigKV6 -ubec4gFMVwtC4SN6LuWIedy9iQvutALhbZ9VkwF5LGWc9DTPOKB23DLHR5vBaEPo -rEaQDXWZ3UwZS7LJrlPcNy5+7/PhGwz3Ws9P0efdT8Bd+z6J3VeMgpZnifV5T+ZB -CtbQ0vbFf63+rD9kDE/hE8yO5UoLfvNZF3xXf16tHsGr2IMFfDaaEEcQx8mSZkuJ -kGirf0KqfQcg/KM5bHOnx4XlgrcQEX+WK2zrIdFA/G68aFv+lBMIuEkuH6dEg4xC -RC47xNCFBL0POGGYd3504EHRmQMRloom3kapkb1YOS5pdVoOq+H5WiRb+qvq4aMt -/wiK0FYCXZsxy/OSuuqieJvviQIcBBABCgAGBQJK+J44AAoJEDGBeFpSfIEki88P -/1JuTI2vnOwNzphUVZ5kIueHy7uTJEji+FqtoK//eDy/49JWxSJZ42bgN6oFBhGF -GY/cGxRzB/iqgudJ0FQ+uJJxNp3fMnFBSsriquNy1/TNaquuTRme5e9UQ6yDF4pD -NjI0Cr5i88nD5RhWqCldpJ6cEBxzchx2FwtA0jGXNb32YXLSTYReAkOvS9ogaqsm -+FYYL7Yy+6cVn4JHRCtjY7Zw9LsMfsVKwXVAvlxvVY/aDEHUMemQC4XCHDKonemV -SyeUpdWhdL9UlltecscoYvyNKAnrgiCND1Mpl460XH3q9RKrfl0N2aLBk1+b5x1b -+BrK/u4KMklXRbi5S6pZQak4gWplQ2C532DY4xDiVzRMvobEaJxVF2rUA+KT5EHw -r6xyVxj/GAWFuMxIOLbgndLt0i0hbeVBXtf56BZvRSC4O8C+MHSNT986O+nUjCGn -OxKDGoK/c+0DIgVEuLUGsRjTdvS7Vrvi8vs5f1gAcZeuDvaLoLMnen1CHJagYMFL -7xNgJRy2Jtr1fKyA+7aRYkNidV4ozKjp40pyOuboIKUPgAnJfnXscmo3htoSI8I+ -Ygu9AfGQmROuZbT2FOQEo5BCydmUlnbfZWBUtf2c6gTqJ4pizypCk/FT76u6OdWh -zkglEXAMvyS+nBFmm8eGJKfRkhHi4b59GbmM6tM3AnX8iQIcBBABCgAGBQJK+zWG -AAoJEDWVOV6z2OG6DFsP/j4ntteVJIovS5/ZSKf9hvYkxqxJteXIfilqqe+y+lkR -AJZVtT8L8GrVJYIBPadvBBI6ok5PuwTB82blWyobOh5Qwzj1ZMNbgKtXnWVBm7oz -ZQE6Qm9gvlnwLy1qjCSsNMRa9w6qkALAQL/0g1j5Y1i4G50bqUy5Urbq2P/UhzDq -lsOP1/0GjvdPgiy1WhuMmZvpwuOXPQT/33WjiKfRtiQoU2B9nhsm4rxEuvD3hgxm -/aHwShjJMB7saXFjYOQM+8wcHFR9NV27pn9df+rdaZivm44dU/TieqFYVBw7/bLw -p2wj76xc1/QKK29r+6WYtZbVLE61JCTT6sjlxmGa3a3UWj9V+uhUANvpUrtXa708 -ZQ9xowaJ9rxeif2KeiO/F07jS5BMRIMHu4JXSKwSmwF6xpfL4DPJKD8oQGUtpK6j -UuijLZjZzGA5Csy/OC7IzFq47PeDBuXekWTiCQrwUBQRfU+KJi0+xOKVyfZECCH2 -6kIsau3Z2DJbaRbWNEHqUXrpiQiiJVRuiRitrm9ZReBvNK5ApVs8CoHGqZCJV1vW -WE5WJgoeGeTl3iq+vdpCmAYEmeFuTCGN0ByNJ4m+GzEm9SKnkVPfy6OHnX6QOUEk -K48z9+RAlQ6LF0kNL3lfDHbJoQvJ2meQUNbUvXPHsoQkQ5WGyo/EXTlo5zhbtQ4T -iQJ+BBABAgBoBQJLDN5oIBxTYW5kZXIgVGVtbWUgPHNhbmRlckB0ZW1tZS5uZXQ+ -IhxTYW5kZXIgVGVtbWUgPHNjdGVtbWVAYXBhY2hlLm9yZz4dHFNhbmRlciBUZW1t -ZSA8c2FuZGVyQG1lLmNvbT4ACgkQm7hjsPUbuIpmcg//cupmIq7H7z1n3ttnshpT -U6h1RD7vZvsRwW1ei/g06xog8h6OQXFVmMDuQqFp8cxHFlCGF1C8vklYv2a3b+fZ -AC8SPh91VpHu1pvMQx+hXRtmZM1KasxSv+uYWGOiJooKYj6upP3B8Oz1GAqFsJyO -toBKn2FcnI17faU5ATPp3ZR4KMWHDvh6Q+NlaVkhBzJz7bVe4qR1TvHBP3l+gRnp -UV4BnsginWv71kz+msMXWlEWoCd2LuI02xOaTIRWxkVMmTdsWSh7G7iYjGp141AD -fbYRN8fvntg3JW3L26OXyHQdZHx9zB2PiBrqhBsCln0lfi9lxjN8HY39PcZsLDZJ -7PH6QYxBr6wfpipzdO3kvmdDWxO2OKJRwF1PN/YhyIl3NW3o57XZbzdqY46eOoxg -J4LYkemXs7405ePfPvHYPqihyO7iyE3qmG2JeSbupHAkR5t2GjtahTuI1p3h1eXm -M9+fRP2qJwmxrVb8clhIzotSXbx+P/W7JaQDOnyPfIQvfdTIqlxk2YqOyKWt3RMG -2Cl5YR5gYM8vNAcFAb0upi51kd9aP0FkThUNEbdiAqCjA6cplV7HcmMnqpdjXusK -6ekTQ53C0Zvgx+/oJoKQNtPQSobnIqlE/5wC+iRkfeMKFZ0QQYTExnxboSsIHr66 -iPo6N99MkDsAkwRdabCO/WyJBDcEEwEIACECGwMCHgECF4AFAkoEQTQFCwkIBwMF -FQoJCAsFFgIDAQAACgkQiq+I1thOQa4Ghh//bW7IOcCGkShncJIvG+B3WM5/o/24 -h4cJtAKr+L5l/SXpf7ImMSpcI1PGxHk76KZjIaeCDtDNvUr79Lj/aC4oGzCbdGJe -weX5Q6/xJZ/EFwzp1g9g5Bu6BuL5oJeKDFIRgJPyUkvndYoONyzwucbHCmdEhfuZ -V8Ekipq+XWP2LsAtR7vlBDLFdLHjqrrHokaGySaAavIJwLp5WhHRZHs2AUwt5Qp9 -QyREdQhVzNJyfLkm/BfHqSbJbot2l5FrJ0EGwG9ZDA3+vkiAQk1O5FmGSScI+kYl -dE5amDWRptG9jWZWGgG00gfZo2dZxhmJ9Gj7oqKTN+mZfIGk4P27lwIEG4K+p5xL -L2mT36cMrx/8LD+wi7sGoNkMlF+qo1AGNIyHXaQKviy0KO11CTV4tcX+ZfOSe2yU -0b0KqFOyMd6MA8pdv1kqkPBhkZTVvLmcZapXrSAYTgZ2urQIKJ7Gyw+Tb1VjQtbY -4zJbis3AKcCs4pIcoNzU7pXBO18/ATMtIlpLWq/HXeVyibX24peUdjbJPZb0wtE5 -fPecNjM8vykztlZTDtkWn9xE0x9lJdGopY+GK0pE9aG9DDzsr/IHAajf05MgpGEv -3+usLoxQ9mdg3Ud9BDkeftyA1vYTKaPb+E7Yj9WZynBlYnTSP/DWC2SoncGQTPim -4TRJsaH3ygt/Xc5gJ16Q9Uc2reRV0veX1/7pdqQqM7eqj/+7hCmnZ17qBvYFhwN7 -XVUft2V9INMWHDw5Is3NiA3PbQpLeDZbD7HFakKwH71idb+NB+/nNTM9ERK0YRPK -In6Ac0FuCG+CVEfDGl3Tvnejlnw28XpKAEjyOC4ouXZBkZ60RAnRGYNXpW2etWnU -ErSmJ68+k6okHpi+6OMF3B/PH9864vzjOW5LcHsY+ntvITABKnhX85Dl5Nbi6lU9 -QL3bjMPU5WkNqPVNYPMpvdK7R3cyU94KvCwdzNKscE+5S0CU0kcZtmUye2jjSD0w -UbDkVt7R77E4Am+6QlNwDTgYqIYViIXLNDOZK5ISYagJ+ZlKtGbLhcI+HpcbLjsQ -Hxbi/gW/JCM8id/Fh6F4cbtpCz1mWsxRpEslwMpl6XhZC87mqBPI/8KMa/NyjGjX -8zKJW5TOZ+/VJA+E5+Fwh24oPyNJOtjEYW2tXv/FnVZ7y/lX/xhkYCM9BYZyP516 -p+2xqU+ieU4Z6VLdeil69lVDi1NgigYXF8D4TXnYxXhxab6u+WCCCeC/M2fxYn9n -aZ0xSh+LSjXaQ8MK6KBv60Sqeh+rxASAouRteH0YcrQ2fTQWt0KaaEMTwkp7uBQg -12rYIDnZ6kf0FjH2dyHpkBBbPE+qOvj/Oi9cJRgnYN5jSCgj1dZ7GmZEm7QfTmlj -ayBCdXJjaCA8bmlja0BnYWdyYXZhcnIub3JnPokENgQTAQgAIAUCSgQseQIbAwYL -CQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEIqviNbYTkGu3Vsf/RLJj2GzT2OpJLje -UFRY27aGbQSqJOYhKz8yHwSWNtdZNSURjSlV3icitj1PVEyptdstrgYyKeZpdUzH -L+CmfKr9yhqFsfv3JY2DM4nnhbmDb+PRq04MtlbTeCMRLXmsu5z/I4qd4EIJzrG3 -kmOBCbO1Q+BkaShwP/zQPaThICOrHNS/5FyoTdDyVZWUgCG90MD0hA9Hd3L+BsRh -ka1wRAR0xN1Qn4aLDRYhh2sZb4LrMvh2V1YOOKsUuvlv2ABtS4F+i4kua/TbDp9t -5m8tOJkZfTWbtMSiVcL/uYSgFEq7a3ck7Xi2kbe/guQlGqJcVK+RCj1/3qyW64Iv -liPwDmjArtzFaPiEGjH8POScrimyalNbx4WyLOtU/Jic9rFymt3hHE5WtPX4OF2l -ielpkyPgtCLiLJMrXcUW/GwreWvDOiCLUhXQ9clXTh6duKfJq6TxYvtdIbEIex9k -Oxd4NayBqoP4YEkLlybyzDWZi+q4HE44gx3S3FqX+VJThk9G7W0eyN04kM2Z/Yd8 -yPYx8evv9mwN4+YfRLjWmCcg+XzekW1Q0c9/BD3Is1axqRy4+e1Z12rrcg8QiXE7 -sy/a1PlHTAfwNnNolRpzRflpLIseZ/7kOGIQm5BCmh+8Saoq8cjMIVadDu2r5W69 -dJVDna3lK8vEd+Vax/luywSYSnhiB5kOv5Oq7jgvXi9c70PH9X+x6mxtACD8KoAN -Ccffi8X/ABbyil8U3k6opUEcX5aF/csmvI2vMsR0u41YFwLZN4+M3Ww4FYen2i6z -mLvCuNt346GrXMno0MX8ZH13cKb/bY/wgcFQTxBoaIypkxzzWjx0GEHtletnBNwV -pjAtrOMQk7/NvUXOoVEG2uQO05IErogspv8fW5+o5KK7x+tOZaNC5FnFJHx7hb/c -vgz9fJxv/hbFmAcF3rN1HnmpmklCfvniaB7xeD6Ddcf7ATXI6CQasqaiwjhN8/0r -pcsB52h9T07BPLLsj1vyIAueNKjsGfL2Yb6zO092hGV3WQ4+PoKOW9gr1tyeS4id -3bBHBWfHnFtW3+mWMZFArryuBm3cNEV/4nApZrFyhoQH8o5SEqLFgsMjg6ASO3kr -jtwHAVUqDOUVC/CoAM3nQFrExvoeuYrv7cII4q4MATnJPtwcrvbuikjqtCNddaaI -c3YtmyLjEaaP9oiFGFCy0ZMm30CMflpm09i6R+1pbqoeUx1lJjnvLV5cy4WDqH1S -4Uz2E+oVbnmQKxYqy+ZKJC6nUj2ZxRzD1vrKnN0RNQlOXcA0oomwpt8M8YlHACKj -fenxMiJ/x1Ih8h6pRkPuNHghgM+lZlGbGijaeueWYkK7Xr45R2RaSj6mxC6nJvyl -JqX/DDyIRgQQEQgABgUCSgQw+wAKCRD1wmAWTO7XX0+QAJsEWE4s0i3hIk6z2iTr -3+aGT3rNVwCcCgXLmSRklbh9kfiHvBesBsZsSHiIRgQQEQIABgUCSgRFRAAKCRDV -M051sTE94nTfAJ9jCZrnvqVJo0tA/7PdmvLcNFwiOQCfQ9zvp5X2V1DlsIwWiOKC -Sh/CvPaIRgQQEQIABgUCSqGECgAKCRBjO4UoUXjipTLVAKDenG1e5ezGLHhyGLYp -UumBmW8bDACeLk2jnCExhcXc8DvA59mQUV+F33CIRgQQEQIABgUCSvsFJwAKCRAT -LknU5B7cfrndAJ0aaFg2t0tU8CGSEToroSUVLgrXywCgjUiXCowy3s3xdtEhl3wg -4zqEijmIRgQQEQIABgUCSvyE9wAKCRDJx5JOUQR9ZniWAJ420lKnPDZmdDFU9qdn -EGfBT0yK9QCfQiP5mzqfGo1KhgmZc2PStbVfMlWIRgQQEQoABgUCSvO8DwAKCRCb -H9qfPAYiMdz1AKDbRUifshBTo9sSZxzd5Lvlfq6nkACfcnWjGlZd+EstKn5SM8ph -xTafHquJAhwEEAEIAAYFAkrzXgcACgkQhY/ExPQ4VqN4EA//YzVYinjJyD2sh1fe -3kv2I8f7XgcDYgN5k3LIEKAmwUzk89z7dMwtykqICS9Jj/bVI14Jnmc43YueHFmZ -XklLr5923B/CbrLakd00Y0AQX4X6z/JPL+mYwdgxuHZSc2udbR2r8cPf603k3+xy -xlJ6PJIk2nzweYB9H/yMKcpfJ5UhZqX+oQd4t3KKmq7Kx0h0ezagFtdT4cZaTG/j -XXJ5pkYXfX+rQtOMvOEmMNvlkiMYemygbKefhW9gLAiLr4gKuL7ViqqQSi+FCm6Q -3o87Xp874qQXxWRIdmw/0Pm75Q0vZSm4t5gsW2G4ha2zx+wmqPtNEam8qlx4pe+i -QoIRreCv1DnNvzXyEzObEQ7HldxHECFFWMSAoVWFZ+If8dJ3fkKEcTDKlCcq+TAh -mYqLm5Mc+bgNhbXh/4Ptapi7aM0R6OLHexc5Ik542e/42aj0xpsJTcggxR+erJoI -tF1ZBVWIBwFKC5Ec5pwMgc0AAIU09+IgAOwtaAsRloAXZXx6oB6nqJA5JS1435gQ -aj3ROCULyM+pjggp4XqccDsxWCt1yituhxHCpcCNQD8V73235+D71EgSoX7UKJS4 -xxkxnL4+jaYB8PIh7DZ5pmBvN/bb3RhHk2VOCdcz5J+HEP/FrvNdvwik3OnXxzFQ -be2mkMFZC7FHjlJ88ir8x4JIVfqJAhwEEAEKAAYFAkrzOb4ACgkQMXxt+Dx3Bc/T -Qw/9Gv4v7Y87zOzYoJzmKvmK012AE05MkxC8bjTDvzV5XH/Tr2mHE+5blOQgPvJp -BeZI7qRYMC98+BOg8yPfweaiOADsCO+CV6obNcTRbmBNiGeFplrWSSR4GB0ZB0Yy -74QJLrI8zig267oxrpO+b3KSV+Q3Juz/Qx6Rhpm7EyB4JuVjGG75oYi1l3yAPTfU -NTTTA6i9gbPTGiMd5wQcsgRUN9nv37JSNhP8xz4GUtUmxDKdaSVo6JiR0HvbgecT -hzN42t+9P351SMDiMOsAV/o5Cr0WMRqXOJi36bUyLeY61AwTQuohkzjLKHm/MQuv -0R/9rZ8fnIk/F27OSjkFM0w4vrraST0yOJB6xdSK2WB21TNp8JRncp1c4UsUjLIj -Knu9Rq15FDJ0/dvCbv/B+Gy+x735rvhy8jLTurthndC3vwpBhlEThXhGah6TkkRL -Y3exXZM2Dew3f4cbEKNVS6/4CAf9WsstGAFLcQyR4gDBTeRQF2UDyFnHxOnq9HgW -G4MwlScv94vd7hE+zuX+76n3Dyqlc5roHQPFFkRncTP+FTCclNph5eh2ssNyqwtl -AoGKpqv5zJU/lebs2nH/x7GpLIqSNp4cJwDHpAkBMpaBQV27DbpXF+WfI2lxTxIE -2IYGMZmRDAlKDmbBMs9Oqk3ChLQETEVEDT8viZD0NFvjWMmJAhwEEAEKAAYFAkrz -YMgACgkQmaAwKd36GZ60ZRAApqsfylg4CRZsFqaql9nWJU0QVud+L56F2PaUwxWi -3MrqroocXxeM37so2Vg/LDm/pRFQWZ9kWkPOZcEvvO50ztz7n7T76Q/y221B9pb7 -54BKAWr7xVCuHQgMNKQaiblbgLtgQvJ2BNInCw2tkJrEzoTMpkGShdPlBpUrYsuO -Wn4499LcDzS0p6B2NXRgALlKjoWKZu4vbCLAbf/oeXH0MAHvpbsOZzvpSon5YoXM -mM/Wcrrrlw2rsKJZ+9baojcn6tyKtnDCJEmm2xuOxO3cOvQFqrhXIZfO7gaI0j+G -yH+eyrsoLJJI2fLT6CVqlSgmR4gx7d55ccHQMobwD18YrQDXczlazoBzinrV9uBr -G9uO29zD8KSrTZfM54o6JATwu9UASThob1ovhUy8GqDE1d8gcZy2iwep3i86ptfU -sqq+9mgar1J/3o8iV+mxxhmcQpPTnA5qPiSoIsnvfsUf5XkccxByiEM/CWP52IOG -hErgTb7LJOcrCwcU5Wm174r04m0D7B5YyTYWa/znL7siCrn9wQ+DrE6S4vBwsNP+ -NiNxCjFMG8NT3+UPblp7oryrSW0XNyHVWpRy79Z6k7aAllgW+n3d0j7+TzRAnrrS -gAt4o1eGwCsSIjWWS5jcHELfPLWn0nugTqruXTOAx8anHkdzghgSWn1TXRFeP454 -y8qJAhwEEAEKAAYFAkrzuvEACgkQIFyGc9x0LHzx6BAA53K7EaCVX0X9l2Jh7ys6 -28otsX+gWZjVAAzM4fJu4NxcQB77geV0HR1w8+9thE4FZG4v0TM7Ye+7OurxRASl -dUVv29qC4JuSL+YnknjD8/UJdVfhqu/VSTESIOsoEUYHBJquy1NHK+FI2Un7NQFF -Ebf4KyY+N7XQpVsROko+iHB0p6tOR8//8UpgtnQ29wgrXdOCCyTVDDNwAkL81q6q -qXKvI9UJvPuKyjkWcxPW+NYK/n7ubp/rfk5LqUOJi6dn+XIkAWI0PHXcsRj26Rqe -FMTP2zFoV+sSpUksloJG/EZaQ+UHSJxs1ZKiiixuf0n7H8WFNERFtjs00leo/ha6 -0KdwqeiLIRhavtVNQSfWYIkjLEAIgl0XGp3Wem8HK6yxM+20mdIHwS3gIvAxB6xj -cbNBjHLmJL52SbEOxuQZPpGZ9+nQXY+KUAN1z4cAEAbbQu6yP/EOFutuJdl0W9ct -9+DtHYOWEQvGuZMirSzU5ApF3JT2Svezq0FcF9JmAROu3kQ1AI1wS1FrvmFTEFDC -16Hl7IyVA088QA+UgnTmC6QDd4XbPo4k2pSuL1XP5+mMlmuKEHjZQv5vUfm5nTBS -GiPMAqcS6ggoMQV3LTLQxx1AwYHZwIR+mRKx3uMAvm0xqd7qnLEbyda1vM5hX8G6 -brbmRk+973k8XOl7aSlaEAOJAhwEEAEKAAYFAkr4niYACgkQEMAcWi9gWec4fQ// -QUMBiunb/qCNoON7b+jdb2GfRFivs0zRFkOKxUMJAzwkcjj8D8ruoaseL+QzUpxa -thWkmoXBmSGc4cBxxB2pFgyITtYvGmQxEmwMBYRx0SEoprEUCfC0lUVdq6JRXb3D -MJ91y8HwKkkKjqOtXeSKMJBGxe4k6qb3FP/ddqvyt+fN7axxANgqeY/JhhAXT4Ph -ivbgAdiqU6ToW90qJxyVlLlj1H8AkSeis0vjJo0sIzis813ftVLgjvYOlXZSLcpW -xsXTYr+Nv1+T9dOF9FoMS4LQzZvf056lEwE58+5O+xbPGniD7o5FyJu8KyV6ptj3 -5ldLx/GK/ervKR8nUr/L8Al5jhnsr3XDgdSUMLsBJ79KHMI5lwAVblQ7Ol0GLmyy -3t2rsMxDDxJEACPrNm0/0HxZUkGL6uX9lXm+Q7TuJ9RmXyU/DTHuDmhsOusw+g+x -XJWXZuIgcdoDo2PJTwq9pV9QDo9GgM4c8HB9kgqlstWsqbtcrZ3d9UXBYUpbZEks -5HcLd4RuWZO57iutSNWwNkbsGtPrmvfiVndzx1BNDv3AIUl1HVUTCtZICluYdQuM -a2mJgNR35ylA7kFRvbGu0beD9PfWxFyFusEWhnuNiDfB6NMSu/VszIWR6hutM6QI -x80bSDVyDhBp5v+OAQeE1n/uV9Kjft2cuDf55lKH3FOJAhwEEAEKAAYFAkr4njgA -CgkQMYF4WlJ8gSTBQQ/+Lbvk4+gH0I1FmZhvgipVy2qMRCivTsRhsRtXU3AlZYyX -Y2mCtx+DvrL7z6EYAuguXEJUIrihcJPmJ3hiKMjUDovLzZ6rLojqkMR1NN7k2nVw -7YEvCRyq9MMH8Cy5jGiQvH5q2oqY8xM6L4+ZEpvl4KCI4W9JBsNmF2ynJ1K+m90Q -TZnyDSUkMqKk4KofyjfCBRNTrOylM5aT+EavEFfE6W1k5nQOnNO1MuvxHrHxC4Sm -cqWVdVMrSGZN5Xx5/j/0WiHGtCv/4r3l9N/nfqW7hVmDuSoPGV2ZoCKuHKFYUetI -3+vv3teOOsiG/weyD6/T0ysM/PkFNAEaOU917DUGKbLB+T5qrA7Ijrf7FwIiJW0N -7SW08ihADqEXmgILW6zE1SdMZEBYDZHSZOJzQARKOg/RYkiaov3khNm3cu3BlysT -zx7XW05sTshtSSFkjvXBcNlEVsijTiv3aSFEOWEJiGlE4231e6nwqyyt1rwF8w0V -AoVp01tylK9B6S2mzR4u+3bdte34ugh77PYAd0nqrNToKMgoDwLOR5JvFTH5jYGL -YMOnN647EAoLEHjWpqpsbO5M8nhlPRkzb6XfZcSutWgbNKNhlAsDyBvggAAPI1Bz -FnGjDiFIDxxT4f5NDgvfkAq3dqydLSpqLWbWcmkHFLpq73yy0vQM3iyeYME8Os6J -AhwEEAEKAAYFAkr7NYYACgkQNZU5XrPY4brIeBAAvCmtrm/GQq76lEcN926ZgC0z -gSFUlYJeslyuPJv3rBqRKVvlO9O3npbmpBWTjZH6RdNU9SSUyszToOb/Q59fGL/h -ADeAJWP2pdvmvAGu2MvLxQmOqQTxABFa9iFcwLSztyC8BW7Sj8AaqeCB/6iclkpn -cBDB8nZeY3RPOJVT66WFMaEhCL6/SpM7ix02wcDlTPyUNUMCOL9grPsMqVkSjWPT -tOqrE3a/n9MDzrWuWsw9tQsD+vVp3SVjZ7W5yLroQbmrGBKhcK4boDwtUHJCqVYC -Ivn8ExoZ9x056MEb67LSiFn5S4tBRtjpc3H9d9MTjuzDdP2WgL+CUHPuGJ8bbNyu -4LpTWfiCQu8DcFFxHzsuIjYCST696STXiePxKqMVWqst8BQIISUpdj7y0dRKY6No -l9KDtyQ/YiB83+A8PLqnet1z5Kvs3R1jOd3NRhfskHWIBfwzK6lI6iJmGH1UwXHX -GUJfD5b/ocaJpR8GWGNVp4REqUKbRJSEXBhXAwF/nWZXwtVYVoakNk5TrgPnBQwE -i2usNehJDXyaRr4lWHnmLO9dLDx5ou9JsuZeTj7Ct1jRHKSOrP5iSPhSFpaoKuhw -sS+cOwpNifgbYVVSy6hCHZx5dG6Xbc1A0/nSl531BMAFUrAjs5z2rbpcJJyO4sTu -nG0YTZwh2gw3a8foShmJAn4EEAECAGgFAksM3mggHFNhbmRlciBUZW1tZSA8c2Fu -ZGVyQHRlbW1lLm5ldD4iHFNhbmRlciBUZW1tZSA8c2N0ZW1tZUBhcGFjaGUub3Jn -Ph0cU2FuZGVyIFRlbW1lIDxzYW5kZXJAbWUuY29tPgAKCRCbuGOw9Ru4imZyD/9y -6mYirsfvPWfe22eyGlNTqHVEPu9m+xHBbV6L+DTrGiDyHo5BcVWYwO5CoWnxzEcW -UIYXULy+SVi/Zrdv59kALxI+H3VWke7Wm8xDH6FdG2ZkzUpqzFK/65hYY6Imigpi -Pq6k/cHw7PUYCoWwnI62gEqfYVycjXt9pTkBM+ndlHgoxYcO+HpD42VpWSEHMnPt -tV7ipHVO8cE/eX6BGelRXgGeyCKda/vWTP6awxdaURagJ3Yu4jTbE5pMhFbGRUyZ -N2xZKHsbuJiManXjUAN9thE3x++e2Dclbcvbo5fIdB1kfH3MHY+IGuqEGwKWfSV+ -L2XGM3wdjf09xmwsNkns8fpBjEGvrB+mKnN07eS+Z0NbE7Y4olHAXU839iHIiXc1 -bejntdlvN2pjjp46jGAngtiR6ZezvjTl498+8dg+qKHI7uLITeqYbYl5Ju6kcCRH -m3YaO1qFO4jWneHV5eYz359E/aonCbGtVvxyWEjOi1JdvH4/9bslpAM6fI98hC99 -1MiqXGTZio7Ipa3dEwbYKXlhHmBgzy80BwUBvS6mLnWR31o/QWROFQ0Rt2ICoKMD -pymVXsdyYyeql2Ne6wrp6RNDncLRm+DH7+gmgpA209BKhuciqUT/nAL6JGR94woV -nRBBhMTGfFuhKwgevrqI+jo330yQOwCTBF1psI79bIkEOgQTAQgAJAIbAwIeAQIX -gAULCQgHAwUVCgkICwUWAgMBAAUCSgRBcwIZAQAKCRCKr4jW2E5BruD9H/0Tm++Q -wXxDbUCVU2jPGcrWhUlb0MH/hShduYc9Pw7TkR4KidPdssSMEeGDfUdgSpLjMiYD -Dj1DQAgBuJUyvpdR42176BypRfCPSmCgTMyeVErA+9nBp5UcVLT0XlZyDa5nU8XB -fXrZizmfrSlsz/CtjulNI9YvICvn7E+xeTXDM9WC1I/A1l48I7QMo6mtzn3cbnzV -rwE8/ap69P4z6NVTcrhkukoEJJ7uDRFtio3O4Sw7zAO+rseNLBa4uAbh6n1m6nyX -4nGiP4D5cPAUHPZt6ROgjh/od6qFOHGOa3G7UMhoiNzK+e3ce8rn1cpFbxEdoEpM -atsOej7hnsH7xFD1mqu8KcUohskgFKY1QHG+Auz9TRp8ThuDpGRvDZXHt6mONlo1 -WdTdA9vNNzzkr+yVMibxPyXMZBXBoJiK1MRCvsVwhKy6hhAGKBtBfNeLkbgSwGXO -mlFp4r5sWjfNmWnqSIFtvI0u6GhsmiveCiLbcSiiSKVGEkih3108yy2CD5wUjPoE -S62R+6CSiA9XCw+eucabhft8DSi3qXUJF5qswSPcqA4tKjOGlBUYwf1MfukdXAh1 -YnA7TEOLw+iRC5akkWXtn6uwOFmexP/4N6dvzlIuRYMgTG6hNwuoorF1cROv7BkH -VcLEqIwZN3aUnaLWz969wYY6SVMzh/6G8fuynAsSWWwHXFdRj9k1VNjPiN3dVYLB -fuUI5OOt8EsiSDgGmGJoWpnD3uHkoYfLAjnwwx0ilQHi9X79sCIZdyjgAYftsED0 -cPvi4b7fOhlWjPbL4ycSsaXmHvYTVpt1I7oKt9IJRdMEaivFxjWp+h2JK2JJ7fNJ -V/41GP3v/dmUt3zz/ai89h6cD0L0eXvcb7g39WU9Z+lTRv1Zbr/aZKRM2twl7iBJ -8dMygXwmSJNIkt9MVmklr3pxzcgtMBf3MzFJJbgaWmKg6ZQM4o37xlesijVrEX0s -jbyvrR81f18GyB9SXsMjEV5zkuE86UbxoUqtmxYKefVzbCpugo/PYkhaPgk04Tox -JH+zZLYYNH3yqt4RmwN4F6KHhh2BrQIFhKNHPrd7Hd9WEZ58fZOFcqKzWEtUZ4DX -46jJvcSyO1EsD6xLpVMzZU9J+H23IkLqmnAokijjyC0LYZzuVlxdEHRM1iTOF2mL -b6iMr8wLAqoyrmHI0Vu/Sd3amreBj4aRRTcOxriTSBUbE0EeQ+E/6MvkjF1qO4vR -DaSfrl25Mry4y917V/lDExkVVZkAz4wnpTlFYOKDxDtDs00ZaC4N/1buJRDwQoa6 -p0f/oW5f1obEqsDA6KEazSC9aikIE67++guj75vhryPgFo1XR8JNaApFiwshtZzx -mjXHrlG7i1Lt5FtwuQQNBEoELeEBIADZVO2q6wIlvBr+TTW8jfqO0cZuqo4Prk5y -4q1oMrXI3yl84VJ1s1+gTY7g9OEcb3SJPX9T7DRWj83p7GyVGVxr7flnQD2jCtTo -lejmuhvp5l+oDES8rIFfc039+HesBX9mjR3aBqYubWLefawnkxi7q7gdqFoFJNSv -w5MfHw9tLMUzF54NxsLaUHc4IQtginqchM7e6C+38BjEYhpK6wiRvfbkp2k9z+w2 -AwNY9vjw2MbOtjYxXNNL3cK+IUPBEXqxvsXsm8dLwJhU/AGYSvUgZIUAjyqpDure -hPYSmCmVeloZvlYBdzMJUEtMtmPgOuB/nkFjKQALFvxbt5IeQmQyc48UWmcgCza/ -LJn4/cqA6DjEnN9fM9LCT9Y8d9NwIeE5N94vQkvQjGYuaWL/URv1wp0UC40sDCo7 -PfwcKl8v/+O6mbq1u+qNjMCvU9AT5g7y+AEf+yv/SWlihe81v5H4vcO3H6Oi/l1n -yCMEcvktX56WgAITgNZs2GQyL2+GEfYx9BATz4X0IfA6WFStrLJrAc92MZv89i6Y -seOsBwVhg/aCuIHb8D0Ukmu35x0usSarP4522u0j+Lqt0eqPOfhEnpGpha+NtuaD -XjvwBKJ0Pe+9ZsdH/7AIX8CIXwpS7u8M24Ibqaro7AFPZWLLL6P65jXKe98AtZfX -h3xoGx7SbiC6EDRrQmRpVsGX/tCo6sQGKhWpaiCecpeDOHoOa0po3ABx8jipzBTT -qS+B6P+TAUOSuMvQWp271PwX0mFNG51sF2Xe7XnxtQCZPK3S9ML7LiwmF9cN4tBw -8zmvC0vGYsp1ajHbq7brmGzXFOZ48ISGGzSHYEj1Uff2DRXsvxUktDY9ba/7319K -nactywtzuZqbjpqFO9+SU0v9btDr7ap9jfuYIepy1bNHs5Z1v/Ig3ZlDwjD7NwYh -/xr6Pe8oT/mw9iEIlPH4bXqNAExw6JjKn6B/R2h/LOHP/liu552sBr48ynLnoIH7 -jORoPcNPJGASRpGgM9F6ZqOo8qizLFLniP3VQztMamMFj791o4qvgjp/oxhTRuYo -3p7HwfLZ6N6cpjtL3rMtQEstartLwGsVpxYqvDkQaMYcbwphnnmuYXQCUIDPoYNK -LTi+0rcgIYaGT6czPo2fbN93TovkCMxXHScwor1wGfkDCsd+PrvdyoyNOlUYP8dM -kM3iGmUTA8h49rA6E9a7Hp1+F75XrfgyDeGX02WlXl/wByByxdNAszlLfXuWzHKm -mWSRLDEEFUyDG/ub9WKXO9kOm4aYjn6RmU9jUx5ypIg43DVlUrnh2RdHyYDy3kwU -UBcZbdLp++y1J34THRZ+53+uEcvE8+kV614+LI2zMyWLDr0vyWvXABEBAAGJCD4E -GAEIAAkFAkoELeECGwIEKQkQiq+I1thOQa7DXSAEGQEIAAYFAkoELeEACgkQ72am -4xjEywDFFR//WNNReLoLcWc4xZxas533Hfk8gHm88bXes/cJ3sF9Vwq212rDpK6A -NrMcU27TfSl6F4aH49DZt0WwLysPJysKcL9ssgcn8PeVUW2U59apa3X/xtm03Gqz -suwqgRwWapfulFF/gl55+ZZCl/mvHgiQ9bdhnT99xiuYV3b/D6iGg+MKjEsYOkNd -9PirbwwXbvC48tnPA+XezMIQsggsk1852I3cLfRi/X8qNDkZ/DzzVoD+qTpccCR1 -Iw09iADo95TdCUjubu27WW3Zhesly9/J/AzbcSB85pvX3EhlV7EoN7xHvgJMiAHi -KYBD2myUOv/+XuA0zB9Z/mp1yiSH+jQntd8UMSH2gK8ykBtWM+R0mbuBZ6nTovZD -K92Mh3DgpB7YeU6iuubtXrbNlXJOVziUl4J+4I9QVyjQeLUDJXKnJ+j3QlW1kN5g -9tGbo/I6stYGJZ4DP8yzy6lD6sww51YYwI+hB2QKjf8NWupphim5whrVW58UWrIs -lVpKJOMzXmlHKlKRaLUXzkkRlKB7I4BS440MErIVBlkOtGXB1gVbfNgQAPtypN+D -EFfZHvwt4THIPsBFptbcIw3VQQf3cbzLxjkqDdSz8uc0cGBMc+lb2/BeJoGKtUhB -6jt8rxE1tDhjOL1pTPi2300pSHnLUtjZsXyMvUrTkNA2AqwIBFmWBU92Zid5TDWs -1uebs7GoW4qdeHGkCHTDlcqy44/9XJHe0fxXx0bau+cx73hI93VV62KyHP2WyhON -We+jWkB6XS4/Vt26RyvsQUUggf/PyKu3zSz4O+vpdy6kW56KbglCWWSyjDlng012 -TP0TRXpjRh5/B2anIi4DWwvYGd+5bCd6Cn2YD19wVKmG6wfUcMW49l6mgLUPQO11 -TCbaT94Pn9+0qREkUJZ9gDaFKBj5ssXxvVLZDWe28v5pM52Fz4E4IUlpc11RfAKg -x8AUc7fNuz14AFwkzIrXinBPcRT4c+etMc2bNAbU1mf219tG5Ag8fDLS/IGuNaHy -UodaqzthLV+sg6W9XacC9TQSGslLOOwAMy7N34JQ7iapzdCN62pFeWP9B7jF27pM -WKuYwvBewC4tOBw5OH7QyrPSNEwIRHL8QxZ3j+ySBEQ8KVs3GfJsATRuvQckf76M -8GaOFfBD3usFHq8WQ8vhAotUgYvRyxrUuQJ7nQX0ivHOly9NIRpdl7S9rVOsuhR2 -yUL0TPuQw/Wn4+rA79HyFNxBuEg753GbHJMCPlYwnK3lnquLLJhQyOtX/1TIT7hS -C+koXMpfBskft85vl4DejSZSYmWxfxU4ctVyvZwtEvOewUzfSAgNSwIrTHYooyAe -uE+W37vUg2en8yKlZZLkel/4lWV98sQrPDVAIACgKu7YqUeumQTpDTlgGrWk2fls -G25Qcnu0T7sywY7CKPjU3O4ZsZ1mu+fdIxlcmutIrRqra4FyRaSRBxplE1HCUjI2 -J5B57zGKYP77B0EeO3ThJHsT4D/E+wyi3wJ2Wp68cgvooj9hXvaDIHOj5Eu7TdTp -ksFtmxVa3stc06EiGc+9ZIH5mk+pO7heybOeXEXttFvs/8NEQwffhyz48W92jOGt -53+iS4+2faH+xio9hYHQLOgLJ7GMBGrSQ0sYBvRGvQZOlijjbMNsi9Fo1ffZB4Ks -XdtKRufvfq6Dhw0/1ZkIAdFLxMVZ3DXsGOHQi+SU9c2Px1zvRTAyLTpT7LaB43Ti -MWLDKmRXLFbFQJpzm23HuFONPbfRYJYk/J/QaEWT1tSSpI48KYao0vz7tfkxsQkh -k9lM0g/rq6YrtPZDZxVvZRncAyjMB3gaNHw8Pf/f78eTWsBKsuDWlbOsT+NpQZ+C -qN5r/zj3FpPXbdlu/3/u4fZKJCGF3IrqqJmGnDyx8lUCqwzfLIZ0xesKHJ2IxsyA -C1RGp5cWSTIEHarvqKbIHJI3c02gA94IqxerwzH+5A+RLCX7encDbyGyRLP7mrva -C3zxNJfFIjojB1W+MkH5mjQZY/h5G71dsWIOZlvm33paB17XjcUsAJ2ER/+rqlb5 -V/fw8xoB2HxuN7hFNgvkABww6HTRlM0Oq7I+ZtN0bnw0k1OmYgN6w9DPFGx4PZa+ -LmBpTgVudfHLe8jFF8Prw1/Nhc16B8EEaUkaXfdiahlx9By8Zh+fRvYKvP3ZD1S+ -8PaNgLQQ2I/l0GhbLnwFT0dd/D4jz2SrF/OLxwjSWeKFHdmuDkk5Ky5aPMKoFTdB -z66t1HpU6AqmNjClN+0TRTXZe4iCOcwsgMu68BDIeUElLr36qt/Hl66Abp0sY+fp -/YOSME0SQZ11Hvs7gAdkGINKV9xpXxNPtNEeINQg8w7IC7tFqPv67zVZ87+/xrCn -1PsVCfvfdh1SF594+FviqaTolL8HGR2KAPVGsUt122CQRuXu5gRNrAGxwKHtb88m -9iWPNLba7FDZUZARL0HRThpeF/T8hKABG68aIpZ761QgX/7MptCZAxuvz3h02OT6 -b0B4atxy1QdK/7AHYKsyLP7U8GGT5OL2O7kokcsiDaJa+k2FQ8HIlZ3l8CAJgYTd -DC+QxhyRn01pR+eTK6alymfMcCHT1/bsXPSW8ca112/z3zUg8eDkkImR/vIFaG6o -KBZB0iag+L2veU3uIXqHC/CW8ox2jOJyjTjApsAp5VU6XTQza/fRgPZzgWlhnxja -ospUWdghpt/4LWZfwUrsgCQJsWVN/KR+7tmR3u1rPm46qf+0QAe80v47QEJEuQQN -BEoELp8BIAC9Xd6Jo/GoT8pa+DzdcgNRr9rIU6u/VhObpc3eIz3uenXlGz9/91Vg -HbuxSY3nqIllxvuNWboC6RPnTrDvieOUIik22J06DYiXklbc9rlEKy4nB2Gu6njK -hrrNtD7V2YqL988xtfGh2SzuTP5LTaAZFS2CpJthdT/QbxiE2QJmjAfjPEdpkgDC -0rcpB2nISDpJn2LmZVDYhuKLBDyG95SdwhBapL1puFnQMQ1P9mUMpIDtYadz/X37 -wgORHa+a2k1es2qXTRo5LRlUs/N7cqfjgCwCSvZLZIcQ8r2ik+KCOHqYYrRu8G7f -qn9ipJcM8u1M3G2zkrUorzHBpn2jP0e+ChulkacIIv9Cd7Pdl56V3/y4t9dkpdGL -E+9HWSRxn4nPVCNI2j2bGyT6cSZtEnfeiHj2pmsBIfg9w7n4oSPQwtNLkDwxp+Fv -UYrbehD3gB1M4Mx6b0+7ZyZptk1PY2I9eRbOpTiqSTLY/dQhe2L5aYZ6vDPl0I6j -tkcWDuVnxcFIREWBEw7tqpHn/IhQy9xNMQu3GvrFlCyP6XiXtZZATDl6EPgY52C7 -0689jEnky2mpvViza3h253vJOEuGb26BKQ/Qov+Pukdp4q8NMOby8VVGcjKrhTtM -QBRCuKruOzMBtdcNP5uKUPsnykVpG7Uvqy9vFps1Ff6LW7Sj07y/7MVlv8wDKdZW -SSiqyGM9YiWL/lIfFUqHw967j3LlKjtMgYWqtE915GWOYWbkXPE6M0YdyzwUyTi2 -oWYbPMjTJmOe1FGGpW5rNhAISSn1a8xngjmt+eKCbJJCzReLzGeuA3A1Vh0G51jy -ge9Tr3KM7mSJ5kcNQVaxwLEIZTn+nef7wnvfWEmDKHtjmtzwja5BlZzss3I1l+Zf -akjBLcqM31mWjjiBjtzU49/91Ubwf5tHvV0yWcvRO4nCgB5rxitrCtOqB7PfS8SV -jMs9ItpT6ZGW034tfWoinz6LiaSQq+dsmW764gxcprjMI9z7K3ikP+n8B//oFShm -rR5jLYy1nUWq2KfLwFKO481KjUcF72bDzSpqYcrniyzqFkUGItTJ/Y8LneCBZSSA -uMjaVJNujNhDHJJlJ1nDXysDBPnwsIZnPUVvpJvEfKmoxvpVol4FHm7Uuuy+ZjuS -qsbzKXhsfM/5ai/fSvo1Rr1kHPwm7Iyhlem/CXGKzsSc47SNWLrnnnEbuuXprbfL -fxZ1NfFQPAgkOuk+v6TbJFXb/94SiO+qEh8yuYVBweQ8bWY6BgydZXwsznHh9+aJ -I9jPbBaLMoC01bBgCDid57ljKIxWYm0Vv9fKAD8hoEQG6caAQxcQqHEpxeAMFwW8 -fAc4I/obmkpMLL2krOkfzstRcv6aJD5jABEBAAGJBB8EGAEIAAkFAkoELp8CGwwA -CgkQiq+I1thOQa44JiAAnrvDJCUU8Yj6m67hYYEiS0bjcpagMnt42isVuSCmHU4B -aSJQtAEC+gqw+kbNuOITJSk7ONZf8TI3BSAEq9EloqdloOV3+/xlT9zPz9vy0u0K -2nbQN8SWNk5mjo4QPtmd44eqeYFShx3A5iLXT327oOwaU1ocDk36dE+0n/ia8SzB -eRSDm9aCB+boY+Nf1Ze4f3E7fLQEw6/Do69/fQWvOgXZQ0r9vnO43rQFY/Rukcrg -FX46fuiiNvTKI8V/uwtwd29xFl1pDpFfYgggIfdK43AxxazQkrxIRf1/X94w4T6q -7GMJ6RWSiPcQJRJ1Ci7EoJqXbK7d6g6JDX70aTL6ZBLH+TxOYGWAmZjgftNH/DkA -S2KhPdK350qZERlG+h/nw8q66Q09K5quGRIZ9zcKz0vBrIv8tTlcpux22midjcvm -edvr63qgoySJDB4t5+iVBQfaicpR7jVaJDD+XYeMc4EMf59izjGLc9UCiyH2Btb6 -N8P/3wJ/JjIqZ6f+vpJ0H5t8HDq/566MYN2Wg0il7SgrlimbXfCLqLAgaLkVlDqy -6lJvNHhWW+gjzl9IGawOlC/v4ciX+/poixulXiJIKPcIDb4SwQ4DT21TuX7fF2uK -tWFcMTgDBpQGF36kP9ViY7WjZTUGlsmeKBV9ugeaf4MhhaqxT6WgALTOrLuC2GwP -8O7L0Wq/269HzwUDxiFGyUywB5Cwiig4b6lgLoArnPYHJyAq+MwTgw25homK+Mnr -jjA02YbjronTTJ78orHxw8hx3VtQbSsMu25PdOqvpomamlTlq9ex5jHkUKL8B4Q2 -JFD7sL1cTHYISZn1DL1djlv4FIR5c4HdGWDBLCqI/n4wv4cWfnfkElbOatyTpWDY -IeWWqBeE/wqjB+HsYR6p+ImpDvSHk0F1ilytTZ6pgWKVkFj34fNu5yQ+fVxx3ERm -dxJDbMMzmqtnB9tRWJBs0If0o17JktN3iba6Jcpk//isPaBiP92+TLX3EImaDQRr -ZmgdL1Q/0JIXvi0mGV7Lfb7SBrEFdYGWF9kI3EREGyLj9Hl6CGwMwbnPBsuAmZwX -phgoJj9UwTM/VNYLremXwrCCGWwzC1l7v17klCVWVjDmZsAZz10szf07WhNuS/Eg -C6wFTnl6s5/Fr9JcNK3n0raGjcFPPmt/YNJYlrfWDmBzXACkTFY1POdyHGTjCQP+ -qJWKuYRVfKjosiSGDrSMA6QsHXOCfvzlT8jWACu0qEbcXJCEyCXnenJJSIw5VO4E -paQ/2mXqEbMbgUlwODFRp0ly0zRQiRlLU4Du+ZMTmiJy2Clvh81BNGZaZf2uV5fS -BRp49fNc4LZVJoOM5B8Z5hQ5U4iMkljJcdToI5W/QA== -=p2JK ------END PGP PUBLIC KEY BLOCK----- - - -pub 1024D/84B5A42E 2003-01-02 -uid Rainer Klute -uid Rainer Klute -uid Rainer Klute -uid Rainer Klute -sub 1024g/F1090E28 2003-01-02 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.2 (GNU/Linux) - -mQGiBD4T++ERBADHIT28sBr2bmkqNoZBj2jOaTG4GKS/4cMxI0Jr6kkuO2PYuOQc -PoK0X7D6u48SMJX01d2oMVoEAeysmvuwkux3bw5rtcHZqQFfRtFV20n37RN/tkKY -SvkHYB6ifhGfghcAvRFYXaIxolexdblUhJlGQc2ZTDLKqtTaQsc5axRvdwCg9DPw -Sr06VUMVWXerGfLJUzE8i+ED+wWgT7/0ypt0rhZTf5wgMWjyXJ5QelaeROiWoVqR -6GWZiN65kFDG1e8y+pEfvp1JUxz0f+RVhREomdfw001CuI19cRaN1mHbY0nMLEzf -PMJgpJ3by8A3n0/fpsW72LVXRdGL94bYbY6XcHWYZDcT02zb4yap2GneEHry/Jgp -sZS9A/93qOeNZD87uQKOXZi/a32VETr4aNQclsRhRUtzkUIJNklPxjwNbYLY2CdS -N5gO3rR7e/dgdvq6ivd/xkQXyqqIe+i+OFIoV5Ur8b3+WQha5mednLryh6UbTIk5 -1hQUQDiKRtWA31rRlyKHMJBMZLPjpQOLqxxMpZNut/fNKTo7+rQkUmFpbmVyIEts -dXRlIDxyYWluZXIua2x1dGVAYXJjb3IuZGU+iF4EExECAB4FAkR8IpMCGyMGCwkI -BwMCAxUCAwMWAgECHgECF4AACgkQU0NGFYS1pC44cQCfTjPeJm8+4pDss9jrP86F -A4iE8BkAoLuEAaDOfQvBeT3u2QpMpVRT50wliEYEExECAAYFAkUHCvkACgkQY/UP -uSC5JsIYjgCgj2Y4MTf6IjxyJIentadTAxGSTRMAoJ1BvGa3LSy+rliiktyn+94w -MOcKiEYEEBECAAYFAkURkHUACgkQlM+NQ5LdW0tnewCggA77IG1Ns1ISxlCaorGv -+bgslV8AoLq9HtGgsiuxxdc0r8+3LRYhrf0utB9SYWluZXIgS2x1dGUgPGtsdXRl -QGFwYWNoZS5vcmc+iF4EExECAB4FAkL4/hgCGyMGCwkIBwMCAxUCAwMWAgECHgEC -F4AACgkQU0NGFYS1pC4cYQCcDTDDS7uRbXnvez+uZhGrEZlXUJwAoNX/GgTq1vZW -gxMWf2vPEO6IDhhUiEYEExECAAYFAkL9kd4ACgkQyFGoreGTVbonBACfepLmeRA1 -jslInl1sCByn8/cO51IAnjCnyfMFY0kTLZWK9bi2kVJJCogbiEYEExECAAYFAkUH -CvkACgkQY/UPuSC5JsKw9wCg3ahE1gb0Jxf3NMcYYi9ww6TKMcAAn2Js4AoO/Ss7 -8XOV+09ZaYvO2km4iEYEEBECAAYFAkURkHsACgkQlM+NQ5LdW0sE9gCgoabl0JSe -X3aXkkO9Ud6UOHaDWaYAn0ZQqf7t/fb5GMVmlDMnT8omAsQVtCJSYWluZXIgS2x1 -dGUgPHJhaW5lci5rbHV0ZUBnbXguZGU+iGEEExECACECGyMGCwkIBwMCAxUCAwMW -AgECHgECF4AFAkV3u4gCGQEACgkQU0NGFYS1pC5xrgCfQjByS4KWDDSpZ19ueCjg -dQr1uUEAoL8U+/gRJtG6Doh615dcO0QslINfiEYEExECAAYFAkL9keUACgkQyFGo -reGTVbodnACfdsIKmkq80XuOT3i1keFCaRIlXzcAoL13+rjtfhm92Q1IKB3m9cih -DHN+iEYEExECAAYFAkUHCvkACgkQY/UPuSC5JsI5ZgCeJTPavF1zdAfMGlmvkKcs -ePjlVpoAoMlRD6SeOF9O7m/xfeSxiI9OoreQiEYEEBECAAYFAkURkHsACgkQlM+N -Q5LdW0saYQCffjiXMP8G10ds7N2HNStVb++PTx4AniuSrYMcn+jA9pKlWaBBBAn7 -9mL5tCRSYWluZXIgS2x1dGUgPGtsdXRlQHJhaW5lci1rbHV0ZS5kZT6IVwQTEQIA -FwUCPhP74QULBwoDBAMVAwIDFgIBAheAAAoJEFNDRhWEtaQuju4An36nIBKzMpzA -rH2FQvFp2oWnhV6gAKCyVnUiRGz0VwsLkrEVxxgpqg8o/YhGBBMRAgAGBQJC/ZHl -AAoJEMhRqK3hk1W6dLEAoJyrrxDfMBbVLqo/os4wz/WOHmNSAKDEa6hOmBnfKk2X -5rA0F7ArAa8ggYhGBBARAgAGBQJC+Q75AAoJEO+sVzojurMr87YAoIZp9qeer38f -47KVVYFMAwO1TLkSAJ94LbmF8B98/ih2Z1BJaGBQtmBqBohGBBMRAgAGBQJFBwr5 -AAoJEGP1D7kguSbCXRcAoLaeuDGAbIkPf/PZJv0Uxf9CJxA+AJ0TbAOoaPwk4HKo -rOw6+mgH+ekRWYhGBBARAgAGBQJFEZB7AAoJEJTPjUOS3VtL3ZcAnjCFahSecBBS -kFnk6bhnkRCRHNrhAKCbMAJqK4O00zdRyaqbbI5XAFDHYrkBDQQ+E/vjEAQAhzT8 -TzjRECMxye0XlxeRn96HLlr9omOp4iagwDieoKePhKHU0OGaTYo/k0HISy32nTdS -ZyFg6inlz4UB6odhLp1vj5GtMXbpH5MAz7WyIWcfm2uXujRpZzg7cb6NHSPYDamf -09QxybFXcc19UBLkawrJDPszwY5kgB5A70CVOZsAAwUD/R41zgJToLPexypUNz01 -97/2Do1dQuySyuyUCmriv9O6sa2Vi3XIbwZImnHIqvIwu5Q/lEVBrZk4X6BRu+hq -Flm6R0z9n4WtMyFlSxUJan11xPy5rFHxu2Zpk8ciwSLrT5Dl1EqNwLvBFgZZ/L+r -/PLM0if+zVI5dbZQdmzsFpaxiEYEGBECAAYFAj4T++MACgkQU0NGFYS1pC5ExACe -PsnsMnIHlxboIe4iFG7JOxG7GwUAniGlU9WWfXiPl2deXWnB9kY35Bu5 -=JOCc ------END PGP PUBLIC KEY BLOCK----- - - -pub 1024D/F5BB52CD 2007-06-18 -uid Yegor Kozlov -uid Yegor Kozlov -uid Yegor Kozlov -sub 4096g/7B45A98A 2007-06-18 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.11 (GNU/Linux) - -mQGiBEZ2p+oRBACNjPpUsJ6ZXK72LZCEnd+eWLBtsAbf9Gm7+NSxvxCZCdIcJZIR -OVji/IHKa9BfsI3F3nZ2381k0Ri2qK6ZDVRZFLCFxmUjwC/oVReDNiOFVHVNZkR8 -GBhc0QLxIQ/Gq6UUOu7hj6IAcaGS+oFKP5fPuSZi7qvVd7I1UXaqqJP8ewCgokfw -xMgkbnchyx8qqfWQyQ8SSIMD/32VLN5n0juPyrQ9X1N1Vw6qka4avF/9HG3EN9pc -MQi4uA90RnQPJ4LJ1cg5a0nsUcctqi+kHsa58/Fd555ZTf8sWGVhsdHeBv2YcwpM -kqw96Wka2C1CUrsGNsAVYmTvCWyAgPJWv+Ytsn2idzIWLhyqgAVqr7bqEjiv+tr6 -aTyKA/40RzPaZNmCfWrEZUMcN02P99sm5pP0M+1w59Uvj4HssjCfM4yffp7CNMhO -1UuXdoZMAvv2G1L8OcwPoxBqN1reo1VgjAf5LZalas8EzyOZpWWerkzpeCld9V62 -WwpTEDgcVq14jjtYFYmrtlb/WJVCqoj/oq16BbeAleNBVL6hLLQfWWVnb3IgS296 -bG92IDx5ZWdvckBhcGFjaGUub3JnPohgBBMRAgAgAhsDBgsJCAcDAgQVAggDBBYC -AwECHgECF4AFAlCzcM8ACgkQaTQKAvW7Us1kDACfRKl+wh0gYan5rCwGIYAjOzm9 -tmsAn1QOozU3kRgrub7EDmhksis5n7MsiEUEEBECAAYFAkc7x+4ACgkQW5aAEOBP -mol+QQCcDkcA+ygeInykabJt3OPNjLBTZKMAlRLRUjiw+fn+EfbdEFyW63TfXB6I -RgQQEQIABgUCRz0HjQAKCRAAvma0h4AibqjJAJ4sKQhpZkutP88QtqFWWRrNnDSv -fACgp31ekx2zqtzY3Tq6yKP+v2xuEwqIRgQQEQIABgUCRz0V8AAKCRAs1qgDIEbQ -9boCAKCkVGjldjCwV0YW+dgE+yCgL+28hwCgn01O53q/6MkCfs9nCtYVgbW8VJOI -RgQQEQIABgUCRz0o6AAKCRARiOjcOrhZi+uuAKCqwy43KpAnxC4jU0yIbGnpNTN8 -sgCfcQ+Y0SlvcxqUCIyB+LPZonfRl++IRgQQEQIABgUCRz9hcwAKCRA5Nfoub9Be -SaJgAJ9sT7R+x3QhNmsYlKAGtX3c2AOr7QCfSmicLEpwn/f92NrNwAAVqnHU6DqI -RgQQEQIABgUCR0CEpgAKCRDW3fAx61H7unL8AKClE3l8U6VhHVvdunLLhV/o8zYF -CwCdHpdz/WddsQt823V70tEeidwQ5HWIcQQQEQIAMQUCRzzQpSocSGVubmluZyBT -Y2htaWVkZWhhdXNlbiA8aHBzQGludGVybWV0YS5kZT4ACgkQMoZOQZyFIisNbwCd -EsXeA27pCnLPTRZpyi2Hp9zAA1cAn0mTL9QX9Uo2ppraETrCw3Xet9sIiQEcBBAB -AgAGBQJHPLrfAAoJEBllhVDDEQYR5LYIAI7ae+p5SDF6aybdOEKbzMiPCe/bpGO4 -QTfHq+lCGctkOIvcvwIFFheqm97LEqFjzgASGaJYSLqUwtQl0zFbYh2HxcaTiK9X -UrVL4cTBn+v5ae3I4zYXipKHOEM1B3yiFrObwLze6lAN3bKti9iXBaGrD/H5aFk1 -zaU0XhNpBFpDYcdMsmVjhumL5nCGA4Qd3jjvnotMj6LE0NFTm6x4QB+fHqPzjaaj -Rq2rjrTfBxBatOpb6MyZf0+cxxO/cBmslay+0b921cJ6UsuXGkzRzgIg9Va2smc6 -bgDDs/NhOjJG0NmKVZ1+ZTE5GjlyLknN1PHLtwR2A1aZz9yurDUQCDOIRgQQEQIA -BgUCR0CUbgAKCRA39o/1AVr8iuVFAJ4+m5BfqHq7LDAdQom/8gLTApNsOgCg0w0H -exbhIr7AjBfMYPnPDXtLJj2IRgQQEQIABgUCR0MbcAAKCRDtTu+wac7rG0RdAJ4s -BbRjTnDMDbvzbjs1+b2QA5UK0ACdHuQBnVCBDbaTuIG+XzQa3hUHalKIRgQQEQIA -BgUCR1arcwAKCRATLknU5B7cfr+wAKCHUgF99Y0sf1To4026XDo1GUw+fgCfQdtq -KughaQa7Yo0SQwUiE5fgCqCIRgQQEQIABgUCR2echwAKCRBAwqscHOF+3CE+AKCF -KpSGvHMUK0K41YfosMS/weK+dACfeYMblBKZ68lu6WdR2r4IKGRjx0SIRgQQEQIA -BgUCSAilXwAKCRChYGPsuM4wbtPsAJ9WSWjYZmDFkRRuA+ltNmG+kVvIVACdHf4G -74oalm4osHwCpMCkDfeMqXaIRgQQEQIABgUCSBOggAAKCRAPRQomYhC/wDS0AKCO -AzYQsUZ+10RZb1k+fxRguQ8TWgCfalShzaPGRwdb7Ocyvql7lt0WFu+IRgQQEQIA -BgUCSvyGtgAKCRDJx5JOUQR9ZhxbAJ0R4Qvl/Fv7CzcyamdZYCTDttYEFwCeIvSX -l/wkFYbdBsboh9Z6TnccEpCIRgQTEQIABgUCR0E9xwAKCRDtsQWJb5Ui2IMBAJ4h -Skr1sOJkaSqbgT8w3TEF8QNlKwCeMcBfh7GzdPh7sPEcyomSCfxcft6IZQQTEQIA -JgUCRnan6gIbAwUJCWYBgAYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEGk0CgL1 -u1LNshsAn2jXy5dYyq9PyYGlQJOqgmml/uQDAJjQQ+lRwxOxIrpQjWZtqGQe9TOG -iKkEEBECAGkFAkdDlCggHFNhbmRlciBUZW1tZSA8c2FuZGVyQHRlbW1lLm5ldD4i -HFNhbmRlciBUZW1tZSA8c2N0ZW1tZUBhcGFjaGUub3JnPh4cU2FuZGVyIFRlbW1l -IDxzYW5kZXJAbWFjLmNvbT4ACgkQsr68QBUpJK8WCACg2n+RmlCWI8XD1gdOb+Qb -6KRLe9EAoPq6F2PJ4XDmi2Fklu0pawNYsfMpiQIcBBABCAAGBQJK82JzAAoJEIWP -xMT0OFaj8UEP/jO9SpC9Na0wzL3lV2AUm+CBq1gXhpAr6ThSystevEQzmLIVanNd -EH2MsaUCbmvp/3NCrljeekyUdras8aqLyT1RcIuf1bo6r4UcwecA9DrukBO+zmD1 -kPl8gOR9s8PLe4+I0KLQPDY2i/4A6vq1ayYwBVhKUmXqCZW03cpTcgObuMfHyaUd -fQ82A8Qx2e94ckTnWrX5yFGt1yy8s34JvDv2GQT1Ski8ghG37vOlNGZI0H2MjBY6 -kZYJNf8ZNGMz/oWzHB7YtEEJYO/eSiOASK6Pd0ENWrYWbtg/84XaHmpJsjMPjbA0 -Zr5s8UjHLcXIFjwXGYbx/Pe+DkYxKsld7AwAmnYezUouSL2yQ9tZmO+UCEwjmANs -wN5UgEopykF9rqIBWWkFkMpLPA8JYlHhPjuim710crHusD1dYXF3KbcGl6SMVM2U -cqVvZiop2hTIjqpfISPMZtp9hRkcswz00TuPUmAx/D2PhQuUvA+Vw8gPviDJHkUk -79K9qcniu/nf9VCTaYosJ+IR6XVAEOUydLPzlcMNPctcwL17nExVXCu5GDnXZJz3 -TwIPeSIW0XswY7MakX2dxULTmv0NkO3ogdu4vzK0DtQdTJD4VFllXq0x2gMK9k2H -AVmRznU7WEDbRumePWS+dtr8hm+Du9FEDyZ7G3Jd47VAn3ANV/skWjACiQIcBBAB -CgAGBQJK+zeMAAoJEDWVOV6z2OG6688QALtQBTR5TbYHyJflc8lzwue6vqnwoOpE -xoicT3jANlMVctg2sTgXBNCFIf+7qi89YSdpQWJUPxdALJDoj9fy/hWbTbde4bQZ -fDbCfDelcAVXryBr9gE4WxxcBx29XdODAAlQGup/no5UvsMsL21KSdQgp9LpKxMW -Srhz40LyGJQNC0vyMzzNrJTAJMJ1ewRt8cTu/8xxNvCjg5ALPUOZqy+ZD5V4DLNT -jBLi7uVEU6KKht0KKCd2GE0QwJD716QllokpDcS2FAHul/DkocgLc1nwgkgZbPIB -wAeW/Rmx+g9ayCwAx3kjlrgdUy9NDXQloK6TlscyqfK3zf3pvv+vG/6dJuTclxaN -d5ISp36jZamg3t9hinFoZUEm2Cyc6kWlVojhy8Mu0DoOcfhH6uBYjPwdoP6wZZTZ -6NVLPKzEYCPYNZ7Y8ELCujl6xFWRjzzqk+sNOKOCugZHqS1AVNZJsg4dkqXq44AN -Kil8feC6Mu3JONTf6DbwqsLcgVHQ5WDczzdj09SWOO9hVAOOI3AOwyXLS3VPrylx -rbSWeXzsBlHM3YfjNe791RbmpRU3lW3/4dRF6p6HdL6pPKIpmZ0FDrrzOUtXRdQu -W/vDk0cRSD/ZZyzMqytTZx9tBUPMlN/unb8LQq9t/w/2oAivCu/1XmXVX8GpXIcZ -Da/YciQe+alPiQIcBBABCgAGBQJLJTVyAAoJEDF8bfg8dwXPoowQAKvQoxgs7kGR -R1AlxdLUlg+CwyEP2fXUnEdNKTeFUCMVB13jcPQfcHZfUDKwd/wBZFqA5IpyIyoE -GO9o6jnVy080qWTE1Y3bDTRVZYUumt2ZO0l7gPruZ9bu8TuZtXx1H6y9uJ8fIU82 -ha4OseEzduB43AweQkBkUkPmXfbTF0yzU0kEVABH93hn4zFq+E4PTpqF2KAH6+X+ -CuWzNwpE0whflgmir79OqVUpFHXJ94tOK1/Fiepvq3PmUdJdf0o1fiH0rb0EobkH -fe61/DlvUgAqYfenDfsRAbv2SpcVoPSMMLPA47byyZRT76+VKtlsgSFfKelAvB4Y -n29HvxOPC85mdKhSlkQCpYXsLJBJqItXND1g2MhSvRjTsxoWZzi9wQOtWMbaefOU -ZiLblz1diPL86hdf3Yyb2kuRpbVq3U8XKmUJ+F85e0yQ9/qlLKVd2Pfm2oLL+tOu -6W88IFhumcrT9R86AOCS1B7Biz7H5/KpyLEdYpuOeQQqLhVgy82YLc8g5C9SfJhQ -raoraSOuto6HdTxMemSd1MUqDQhMKQixNWKQ+hEs0BB1o7BjFO6KF7KPud6TN3t8 -cUyfrna1OhbpJPnrlNrzdXSPKWh1gCuRI2EaokOeSCviL36nnFkTPeTtrASDAraV -pZ9abN4OYL4JHwK5QpIDW6kQed4GMvHOiQJ+BBABAgBoBQJLDN5oIBxTYW5kZXIg -VGVtbWUgPHNhbmRlckB0ZW1tZS5uZXQ+IhxTYW5kZXIgVGVtbWUgPHNjdGVtbWVA -YXBhY2hlLm9yZz4dHFNhbmRlciBUZW1tZSA8c2FuZGVyQG1lLmNvbT4ACgkQm7hj -sPUbuIrJ+A//XYCi43ISP+krVXnOFbXO61jTloIilYeg1nMMtSZwAJtP6kaBeZVl -DeFiYJFUOiZfJIy4Ull3eMI29EVsi46Porc3/o6lpMvOFcs+zSpqcmoxEPmQtbmR -yLZawC6xmCPO+Hs41MeqPhEq16M4rMZn7KejUu16Ujs54W1Us0H7CXGHI8Ic7/9m -PZB7jHD+iCirYOB/CeZp4xubR9rJYUn/IhdRlMmK59VOh10www7CSSMcW0/7FaZ1 -60D1jS9/Ad5pGT7I8V8KdUVDtXNeEfxlloCuxmt+3lDFL3Ee02mhy656qTxV6B32 -/qYYeg+OU0zP9IKD1SVITzRx6rahzX/vVVFIma8YlkCjvsVZlTZKJ/xz1cuHJeKE -72r1HVoi6ywsCItxVjwrJD4QQJdNPGIjh97gDwkrOBCkYiTia2xNyH1Wchpj64Kh -+fBRoRGxcdoF2ZhyOUzGMdtmtzy7OwrckPtWJeZ5nnM32EzAIakugQq7rSmXBS+J -0/E/KrouejsOWzMMQrHjVS1keuowF6+PJtWyZgzH0fbi8SZ2Ym/yabv5zVb5OTOL -siUCdPA2zAU1jBkE9htIHqIakFYDnfUNbEAmWMYnEtxY8wr4fDgOTIZ84qZN8A+g -qnvkzoc9kN3kVq0WCZw/KNxtKMcJMFij1kg0ISMwmbcmKfH/b9jXgAeJBBwEEAEI -AAYFAkr+G9cACgkQiq+I1thOQa6GvB/8D29GySol2rtkm1MFd4UoJl0h/WV0cVkv -UhH8G5rcwntyjK48nf//hiNKjEY/Uchi1Ai7GJU8klvEYzDm4SVauBEERTxaDQhP -FvKQeKqpAGVaeID3C8puaTHwlOUB+e+yFXVeCxRZswbs+fEP5YvT4JmMuSpu0RDO -oC8Q9cONssqgfTM1uedCVuN2NGnLHRUKAkAH0q+fQTyN4oBZiVuMRTQ2Py0uVOt1 -WV1mtOudmivJ1CxJ+34CokcmUbvnxPnGLxi7HZN1sQgxQqNHFR2N7SjLn4O5NBSj -m+AID5dKOIAnW/Urv8Ek4j+kM3oaxES9+OWZbZWxeoKTIsNtT7Q58XOpuRnD/DtH -P/q9FsOlm4u6NhKyKF7EPeEu4z/WTemoXDF6LHN/8QCDV4cZ7wfC95eIyuh5PT7g -4vsZD7J9tq2jWCZvwWOxGmuX8E9HIqXZgEzcEq+2rOJpCZYtHS1MilzXuhp9ak4L -VmhSAL49d1t/IHwyDvBByB/F3FItiKYf+SAiKNq68cTgwvY/m5hcOJJEfnyr5ho2 -EV5rdwu3HLISnykNUXUizylrBhuql6Hnj42UKd1UdMyAe/uTe0NPYZKwRl3xWxpT -g7yB72jO/mT+rlAsOu8R/EIC9iF2OaGkUY6BV99xEoW7m2KBuAauAmh1Z5H3ZY9/ -D9ubL21XEGyFb0I8IUor+gu5HVk4/LqcI2Fj1DO+83vbTicYsTJrPY4Bb1zhRrje -vwNmZHBshQYoWFUJA3C89OHG+biTn2uKnleKMhvv4ZIr/WoENkyGimfSos9ZTQ3g -/1kKxOCY5yGW61SMmD00JjHIMg7gZjjuI/KKzbGr6kjsA1zMGB9rxIcy434wdauu -VnaD8Ld8kLcuk5myWh8cgjE6XsVG4H2lIBp8FXwHNZv9RWhglV1B1VooYyErxthe -FPMTmSGd0y+cou6tm46H0qclNg6Lg2qshXggkf4ONamE1vmGh/8XI8vX6Y1NQbwL -yFElQx3caaN+04Yxzws/Gh+JpaLNsqR2an7DgwOWmbKuguSkcjNyI77tOsCXmc2j -v3aHJH40enUmRZlcMKL7bI4w6vEOXWULiHEbO0/XBhi0lqtqoMfwh6FkTthEMxhY -6cfZPIb9uO1V5pdHGz3F6p5rRHmNuRgbOik5xDHJ91cavEKZue/1WMaZmGGtz2l7 -eCdFxDqmhW5apOA90JRR+b/8ga+JI9bnynpOrs8tgalsLmXUJRfqQTTAoghEReVS -P8iA3SoL0ovKhD8aeaVoy80IyQZkzMzd4rMNmXhaxBJycrPyT/sWOE23QBqKBZW0 -xZjKrFuLGOf88hD9Wvgj9rNs5lmBZ1dDUjWtGAVdvdN5+NOtBlCi2rQlWWVnb3Ig -S296bG92IDx5ZWdvci5rb3psb3ZAZ21haWwuY29tPohgBBMRAgAgAhsDBgsJCAcD -AgQVAggDBBYCAwECHgECF4AFAlCzcMcACgkQaTQKAvW7Us0kWgCfe3LGW7t+o2Pg -mB4XjmQuhdVMIjMAn0ugRyWGr+J48hkZWoH15r5qBDCGiEYEEBECAAYFAkc7x+kA -CgkQW5aAEOBPmok4+wCggbJpCeaTzQ8cORgx3nvaF52hrmoAn2WJluH7qjuvJ68y -t9kaLuPm/wa2iEYEEBECAAYFAkc81RkACgkQr9WcwWXV45qWYACeN1qluJ4cGMN+ -1vLRSMjmWCGzFKYAnRO/7iuMiM/3CJPQ85mEdlNZJ6MiiEYEEBECAAYFAkc9B40A -CgkQAL5mtIeAIm677gCgnFp8wUVuMss0cgb86rttjL5vbHMAn1kEGh+sANT9Kd+m -ofcGpryQPyFCiEYEEBECAAYFAkc9Cx8ACgkQwT0w2KecbhhHPgCgtQXQrZ7Tbq3w -cDTQWnVIZSIluPkAnAvzwLC4JL7y/5QyhoUoGCT31XYviEYEEBECAAYFAkc9FfAA -CgkQLNaoAyBG0PX0bwCfWGjRnBwSDVTaJzCjBcVXA3KOKdgAnjeg2zn/QpGP8akq -rIYYg727GBQUiEYEEBECAAYFAkc/YXMACgkQOTX6Lm/QXkmLoQCdHkNDnW3yQCSE -m/7AZsq5KAKp5GwAniCHiB/ZXHDpWJw9dlKhUxoh0o1oiEYEEBECAAYFAkdAhJwA -CgkQ1t3wMetR+7qRCACcDpGP2wZcL2DPIDR5LZbEpJZBTz0AnAjTjRjWOtXgsHty -eY7UP2m6ybGNiHEEEBECADEFAkc80KUqHEhlbm5pbmcgU2NobWllZGVoYXVzZW4g -PGhwc0BpbnRlcm1ldGEuZGU+AAoJEDKGTkGchSIrDW8AnRLF3gNu6Qpyz00Wacot -h6fcwANXAJ9Jky/UF/VKNqaa2hE6wsN13rfbCIkBHAQQAQIABgUCRzy63wAKCRAZ -ZYVQwxEGEXrwCACrKhlffitTUkp+mk7XCdZPMBeiGbhd/Xj0V5L/MdhErUE1XI2P -k9JAS8h/I6CjmfAzS71I2eLxUzb7yYb9vn+5ZRTXreQoqYMmPxENbkgi+1C6L1Wx -PgCxI4uZHY3WmAZDyES5rKNaAYT+zAgiH0b/5PUToybBZsKRUo5lADiS6pGOJBXN -BaboQQot5uV3ZDq84A4/okRa/+wt4gxzhUR6E0b5SiUzTkZyfBGV1N7QyLC0Ws35 -UyPo57D7JJYuhkwL3Wal/kUdLcOuul5Eq2EZ6m4FwngOvtMaXvJ8A8FyI0T1ttW6 -n9D9vBRbLINsTI7RrD4Nv7Sdah51VxxshljpiEYEEBECAAYFAkdAlGsACgkQN/aP -9QFa/IpMIQCgyLBVj9zl4fth6W7rTwSKpb6UvxUAoLq0SiiARb1R7GtgnR7eoQx2 -zEgBiEYEEBECAAYFAkdDBRcACgkQsOAY/LO02Ytt5wCfcvC5zL6PYmwzEhZA9NkL -RDx73B8AoI+U7IGaCZ6DdcGuKI+rqBIe5JVPiEYEEBECAAYFAkdDG3AACgkQ7U7v -sGnO6xtUEQCeKDMqBM34QGCzvPnyrNZxYbB8md8An0r1hU0ldenY8AtuRXvGdPGt -TDENiEYEEBECAAYFAkdWq3MACgkQEy5J1OQe3H5NjwCfW8JyfNbz/Chm3wcjCljG -Hy2IsTcAoJXof3FdnHhYVh39HHAltAe6s014iEYEEBECAAYFAkdnnIcACgkQQMKr -HBzhftx7cQCcCqNzs1uy7ph9bzjm9CluyoqTjlwAoJPUbx7MGjJSc1U/97S0cRmY -ODcqiEYEEBECAAYFAkgIpV8ACgkQoWBj7LjOMG5enACeLvCCM639HjYKCXtK9Qjm -PBZgebEAn3Dx6np/KjXT/uMMYa31Y6l8cezNiEYEEBECAAYFAkgToIAACgkQD0UK -JmIQv8BTHgCeK7P55Hu/64pwXyirPRs06lGh6UQAoMF3ulXYzJ/PNqFGSHm7YTz8 -q58uiEYEEBECAAYFAkr8hrYACgkQyceSTlEEfWaXsACglYTSo8g5908jpIw36+e8 -8pYitsYAn2pUJR+lGXzWRDYYlmYUupU1zJtJiEYEExECAAYFAkdBPccACgkQ7bEF -iW+VIti5hQCffUJo0Y8mHOunsflJVIW3gJAYd7wAoIX/ypbPbFvfRrgy47b3h6FO -cvj2iGYEExECACYFAkcc6X8CGwMFCQlmAYAGCwkIBwMCBBUCCAMEFgIDAQIeAQIX -gAAKCRBpNAoC9btSzRUVAJsGGkGTv9wasU3v1KSCnKoGDq21wQCdEfFFDsI5Phz2 -bUYFaKsO5owE+kGIqQQQEQIAaQUCR0OUKCAcU2FuZGVyIFRlbW1lIDxzYW5kZXJA -dGVtbWUubmV0PiIcU2FuZGVyIFRlbW1lIDxzY3RlbW1lQGFwYWNoZS5vcmc+HhxT -YW5kZXIgVGVtbWUgPHNhbmRlckBtYWMuY29tPgAKCRCyvrxAFSkkrxYIAKDaf5Ga -UJYjxcPWB05v5BvopEt70QCg+roXY8nhcOaLYWSW7SlrA1ix8ymJAhwEEAEIAAYF -AkrzYnIACgkQhY/ExPQ4VqOg5g//VGrYeZ5+2y/V0G1Pk8Zwxbp1uquEHYitgHWb -zHSP54kFiD5QnQCui8p7P3j6oW1JVEMOfWaT1QZ3KSRbqh1RLirB7nNmKfq3ybro -7/0c3Rw9lDR6aHAgkdduReV8LSy6zae9Cz3ykYdPEuWF5hCtkc70t2fVSVRC6w1R -pUq30g9L5wUF+2PUW5j3FljBqf+7STOqTDFkLLlnVhlsN5q6K+WPrY8MTZxeapfE -mzGSyN+/T6BXL+WdPkZY/F+Pya48RFLbcjIuznLs2wdkylIi/oQZpUATRE6w0sHy -fZ5pQuuFNRPNmC7WH+wmKGcb9kF2D/QMdYO1cuvkh+uJzzlDtBe86BrNBLM6wnRF -7dffECwzkNFXRp7WLrH25ummxXtHtSe9YZ06fbQeC5jFjE4yMZUzLy5QNUse2/4e -m3MNa3S2LkvdmcpDvoAj0F0vjHYauG5QscE9jCyS9hkYOW/83yoS4/E3/mVQW5Tq -J4C82K+mKpoFwYnsIxdtGduF1fOuQPuxiIbBkj9xE8V/vYR1VkYTOzTkQ+YT/+hU -hF7NBgUo4eqMEoYRk4Sh8UgwZKis/ibpOIjt8XA4R2sM7AsOXmdT5UxMBXnOP9yB -d98e9H/e7VOSnCTSvwMoPktYsDEVqqkpAS6hc9vtT7acxft8GxPwiSn/3PgR2YwL -D1G1zFyJAhwEEAEKAAYFAkr7N4oACgkQNZU5XrPY4boSVA//b2WBz+m9OOPknvkz -laphU9lWkafA0zfBwazviHp+HIKoi2UjuAfkVG7vbt0AMX2RLLS9EHIb/WwBJwYO -wleld7tf58ykMAqdNTyWaP5crHiMTTw9dcK1Q1uujP+i5wgvI0Br424apW62R2mM -1INJ9WNtzrb1Ze5hONsaP2NYop7keRimbpumt1EpH9lIU7wNdwjbVoSrF43FXlvf -Rw/itT0sYSwSIAKuhs8NpmUlRpz+hGr5bqy9GZu6JkTcZH81dz3LcQDBGV5UM+zc -AKLRLoxsu/hkioGCdNy3xAbkE8RpZPwyiwBvzh7awvfAvziHSKPzahxRaKepaPod -dTrz6A38VbwAY7RXoB+fOiCVLpxm5zHUCbDsi248vSfFJg+IHvfVbWDgborU5bHw -8wJC2gkiMEOUryO/Cfqw5Ezxr9Wl0Izw27p6J7LP+T7f6UTBwU1FZeF8WU0WolGi -E77PCVKD+b6hkOtzAYLyLkz+EBhynYg3Ny2aDWLeiwNGhjExFBOl+D1/2rRfshUz -Y+nkviOVsLV80pC3T1MiDk+1WB2/F2cah6XSXtswVPAXMYpiEt2VBH/a0M7bEi+y -n9yNLbuBxfgoRVTZe+OaqncYjuadPR3xUB3Oega8HJju7DaCZHAKzjfGrybt2fMi -tQRp1Ctp24Gcy49HHJDM8pj3JzqJAhwEEAEKAAYFAkslNWMACgkQMXxt+Dx3Bc/g -OhAAoJT6RrqPfSUiY1p/rsR+aBXfTQjp2kxAz4YsWpFZQpcloBO7vAUhcuRYUiA4 -t65KCMC9XpMfaYNRfWBSsg+F0B3xfP6bXUPdLl/xK8rjv627jdFKLMVn/DUPaLj0 -1YFhuUXkYAuNyWNMBD3ZrmQv97DR0jG/VNqgP6PxtRujUM8lON7KthYKLrerESCK -ll0MFPBrL+Fn8COOURx0QVtQPQF1Ho87Y/go2MJ4afuDlXqojr3/Ipkaol2Cbf+L -6rbqZsK4L1tYHygTVorXi2U1oHQpRYP7Id91aZ7svUBm9RC/RagiYf4uR0T4iILR -/mPAELEq0FR4BZLRK/e4J1qdAG4CtxG+nvgZDgh7YBzi5udYeVJnsOkWZcyxkRLm -fchNV4Y9Az4PxfXSFOi2BMyf+wui0pkEmJeaYY9SWkj8x3g2xmttPW86/LWI3i+T -0MffEVH4d0tMZNiDlqSWaGN9uOMEYKYxG8pd97SEdAwub7JQnnod+Qg7YoCMB8gE -X5xuBqcT+A4f+ic3cqTTm41iks6qcDq8eoFeCTuhfEra4xInRJJnCMC4XNvdn/Mj -aTV9bVjR/ansjO3T2Nkkg3Hx0SiB6bFoTx5N+cMnj34mZ/YVeufQ8c35CRT+WOX8 -hB4NFK8ynJgrYUerwdl3B3RxtpIp2RMhzYCJb8kh/1Kez2GJAn4EEAECAGgFAksM -3mggHFNhbmRlciBUZW1tZSA8c2FuZGVyQHRlbW1lLm5ldD4iHFNhbmRlciBUZW1t -ZSA8c2N0ZW1tZUBhcGFjaGUub3JnPh0cU2FuZGVyIFRlbW1lIDxzYW5kZXJAbWUu -Y29tPgAKCRCbuGOw9Ru4isn4D/9dgKLjchI/6StVec4Vtc7rWNOWgiKVh6DWcwy1 -JnAAm0/qRoF5lWUN4WJgkVQ6Jl8kjLhSWXd4wjb0RWyLjo+itzf+jqWky84Vyz7N -KmpyajEQ+ZC1uZHItlrALrGYI874ezjUx6o+ESrXozisxmfsp6NS7XpSOznhbVSz -QfsJcYcjwhzv/2Y9kHuMcP6IKKtg4H8J5mnjG5tH2slhSf8iF1GUyYrn1U6HXTDD -DsJJIxxbT/sVpnXrQPWNL38B3mkZPsjxXwp1RUO1c14R/GWWgK7Ga37eUMUvcR7T -aaHLrnqpPFXoHfb+phh6D45TTM/0goPVJUhPNHHqtqHNf+9VUUiZrxiWQKO+xVmV -Nkon/HPVy4cl4oTvavUdWiLrLCwIi3FWPCskPhBAl008YiOH3uAPCSs4EKRiJOJr -bE3IfVZyGmPrgqH58FGhEbFx2gXZmHI5TMYx22a3PLs7CtyQ+1Yl5nmeczfYTMAh -qS6BCrutKZcFL4nT8T8qui56Ow5bMwxCseNVLWR66jAXr48m1bJmDMfR9uLxJnZi -b/Jpu/nNVvk5M4uyJQJ08DbMBTWMGQT2G0geohqQVgOd9Q1sQCZYxicS3FjzCvh8 -OA5Mhnzipk3wD6Cqe+TOhz2Q3eRWrRYJnD8o3G0oxwkwWKPWSDQhIzCZtyYp8f9v -2NeAB4kEHAQQAQgABgUCSv4b1wAKCRCKr4jW2E5BrsSWH/9oDkhCGlWC+d6crrXK -cM9KpjdCHeoanuuouISDjXoYGivNVocFeBtGEjihBP6dlL4BUukxmmIsG6RnYlzb -xIXTyvJ3AZqsLnG+NIPEpMev/4x8JziEvbk0XQG9R5gksyJCoR1V7B7wXd+PLszn -Gl6pFXCp6IzXlRRWUPfqWhY9JCi1WXbU++jHX+VlYelJFU00bzMJKqB40fS2HICm -3DxZjuyLJrF00BZNslhzNRqdqAPrHbzQwdQfCAi2QWFYiU6Xe8V4YtcYC/H+d9lz -VePWbdvhkrNX4LA2WNYZ0vFeaENL4N2q+kkc7bnk9iTes4rnjZxPQeENuM4YK3fO -Ra0GAsAuXsNtmkRoc0Q/5FxsbXtibwX7alj7a/CFXpNrQqf4IT1bQBfhOv61dbe6 -Ior1IMpqibvTdyDlNxqy/3mw6rsKFhCvu6YcY6i4W/+sNBdpN8ndtDlQ6MMoE7UL -Swjtg3WtdLrFkdUBuJ8mwXwqsggJR3vu4ayVqRP05VNlG0+DECIafsrpBuolNZ6j -s6Nn1g1gCayunFiFjIpL4Tu4c8Ba5n6jtKHWGwGBbD1oCP9rrQdlIHnp4Q2aj5Td -5K3QA4tGeeE+s2H7WQSrwKFYezFF87eC5P1rwcqDeyMx913ncDEhUGb2H7NS2XIK -8Qn7djV8xQe/l74DQjdkQYB88IXdFEbSszROtv/hcc/mIjWXYBWdQKcraJ+vZEoE -hRJYDwii5xUVWz7vVUKuOEIv32il/CXITLZNn676/GxctBIAwcLQsNeVwPvan34Z -I0HaCX/Bn8saaNw+7o0tZfzahiq8C+QV2GAeVyB+W95Smrj82DimNGqpdBth8wKd -9ALr2PkoWdIVOkZGfCSlB/1dX3xGyZ1DYhwgpHlzXH+ZLSIt2z5HiKlX3lhKGxGD -bce4yEMRkvkx9LdVieB6SNWTSkfQafFBbvBeOCdHOa9I3/s+WnWxBqTHGAEUxEzF -SIKlmC5AhhuuthgSbStGU+2O2P3ONZoCPlNrRYom6/v3Bzxa9UBQ6d6qnui2aBGM -HCEiGe2q0vcKQUXm9L8vzCf9iuzsz45KzBzNUtW6xHW0Ky1LjDtT2oH2LiEUKW35 -/iHAkdv5Yyn2skukMjqymLf0tfAsHNIiLqtAhZIVrNOACb7IvTUbiOcjAyDXiCAW -VQX42ld5j8etsHJXck0AzF+/dKIHlVildIkemoCD67wcLo/7GCZZgtRMrTVXFNsy -rW3Tw3zopcmN4Sm+rInyAAsRXuwtF2NbxQnn4m+u6dhsFVCblkSqkA+VGsz+T4kR -hsEsaRUrjInTU9DxKGC6hF7/TesmD9A7Rxulr2oHtoBfKfq9cXX0EnYBK0+lSAUe -WaSktB1ZZWdvciBLb3psb3YgPHllZ29yQGRpbm9tLnJ1PohgBBMRAgAgAhsDBgsJ -CAcDAgQVAggDBBYCAwECHgECF4AFAlCzcM8ACgkQaTQKAvW7Us1/igCfRzTQRiqs -5fpVO1jFXvQpzT9pmi0AnRlrGgPoOIdqM5EKPXkyzkWSzcgIiEYEEBECAAYFAkc7 -x+4ACgkQW5aAEOBPmonL8wCfS5rtAC749vL6FpC+YUBfLJIQeJgAoIYMe7gjxF3i -+zmJJdhnC4bSf20biEYEEBECAAYFAkc9B40ACgkQAL5mtIeAIm6QrACfYUNdfqrs -63mko5/lIlriZyyUgEEAoITeW+CQ0anB1wPDZu4MfH+AOSTriEYEEBECAAYFAkc9 -FfAACgkQLNaoAyBG0PW7pwCdGao21jiEoKBoEYup9X8HayPo9w4AoIpFQuabehJx -aeySgrig5TCglgsDiEYEEBECAAYFAkc9KOgACgkQEYjo3Dq4WYsKqQCggoh1CiIT -Zw14pFY/5GFkgGxJd6MAnA9KmCnJi5MUo1OSzEGlVkSyr0rIiEYEEBECAAYFAkc/ -YXMACgkQOTX6Lm/QXknhFACfdtlRhfz92Z696fqwCiq43966eKkAnR5qnQLxRETQ -LaEzjoQvlV5WPcLeiEYEEBECAAYFAkdAhKYACgkQ1t3wMetR+7q/aQCfd8Js41Xt -YOMSsiDMSbRGeejhawEAnjwMLdiIhV3z88/iEYg0NPtIwb4xiHEEEBECADEFAkc8 -0KUqHEhlbm5pbmcgU2NobWllZGVoYXVzZW4gPGhwc0BpbnRlcm1ldGEuZGU+AAoJ -EDKGTkGchSIrDW8AnRLF3gNu6Qpyz00Wacoth6fcwANXAJ9Jky/UF/VKNqaa2hE6 -wsN13rfbCIkBHAQQAQIABgUCRzy63wAKCRAZZYVQwxEGEf13CACgbMOUvzMV0LWr -9L8dL5+TJrWzukGzn1u0QkiS1pivR9xE0+cQPdSawZ9FkSoYXGm7fLs2z8BNP4Q7 -vT3ZsTpunyEnzY9GRu9850RstY6sN8VorAyWhiyJu9JUe9zEdL5DGbCm2udAajV2 -Asg0hR211CkAf9mkw46YN4KvS+P/oAUseU5bO0u9NrnKHp0WTGfntMhzgl2TMhEi -ijZWWGOOMnzdyFaPve2vuIB3p0mQmdS6eG1O2lf+fVnwhI1tnZi3FMhr6TV17fb1 -r7ya9kdWOpL5s/Uj7E57+dUjixorCX41QDi31cPMLNGisy3eGqFJKS4yySMYSDU6 -afpC2cNaiEYEEBECAAYFAkdAlG4ACgkQN/aP9QFa/IpoEgCg0wCejp7xt8XTqmUd -uqTAgR8mOo0AnR/bKM0/tEoBALIJkkdm3GYijGDciEYEEBECAAYFAkdDG3AACgkQ -7U7vsGnO6xs/cACgnAi8cqIhJtE00J4g9srhXDFUVJQAnjC/kDy2g36oLOtwzzEO -FjTCDjwSiEYEEBECAAYFAkdWq3MACgkQEy5J1OQe3H6SZQCdHoUxaiAD9VxJtZ1j -9Y34L/8+Wm8An1046xZYFH3N7rVYY9zaL5PRjf3diEYEEBECAAYFAkdnnIcACgkQ -QMKrHBzhftwYbgCfbQPf3QIxDwiYjo+QgQid929TDlgAn3P54V1Xgg93mt7TvVzu -YHY6G9ZZiEYEEBECAAYFAkgIpV8ACgkQoWBj7LjOMG4bdwCeJp6pEj/RQqchTKMG -d8YIPYbGvYIAn26PiUKXScFxB4D0BlyQ9LG2rYcriEYEEBECAAYFAkgToIAACgkQ -D0UKJmIQv8BTHgCeK7P55Hu/64pwXyirPRs06lGh6UQAoMF3ulXYzJ/PNqFGSHm7 -YTz8q58uiEYEEBECAAYFAkgToIAACgkQD0UKJmIQv8BXPwCcDLNCzMocXBb63gGA -q81RiUuVuUcAoLRoqK7+ofE8wHExNGdV56tlsgkqiEYEEBECAAYFAkr8hrYACgkQ -yceSTlEEfWbEQgCfdmT1g9iwAP71zMvCl8JV0ZHP55AAnj99S2pvBgAF9Iay0Ac7 -1k422flWiEYEExECAAYFAkdBPccACgkQ7bEFiW+VIth9NwCbBUIhpl1FQue+LThR -KyZfr8LjL0wAoLTW6rcst1NQit4HapOqvjypxaqJiGYEExECACYFAkah6OYCGwMF -CQlmAYAGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRBpNAoC9btSzYtHAJ45cKwY -tOEtQLDggb5bfNMu1gB8OACfUAofp3+GRcPD7GMJIBfbdzM+7pKIqQQQEQIAaQUC -R0OUKCAcU2FuZGVyIFRlbW1lIDxzYW5kZXJAdGVtbWUubmV0PiIcU2FuZGVyIFRl -bW1lIDxzY3RlbW1lQGFwYWNoZS5vcmc+HhxTYW5kZXIgVGVtbWUgPHNhbmRlckBt -YWMuY29tPgAKCRCyvrxAFSkkrxYIAKDaf5GaUJYjxcPWB05v5BvopEt70QCg+roX -Y8nhcOaLYWSW7SlrA1ix8ymJAhwEEAEIAAYFAkrzYnIACgkQhY/ExPQ4VqOMUw/9 -EG0BVSF44bFzG5PEFSVThr8ZtGCnuUNirRBHgrB6SVL0bRrlB/sk55kYKe9bCgmG -tjcj5/F1nmboZ8ZGISM8Kzl6Yxghsnk8xH6SEhMFtRutKlxtWac8txgVuiWpJpC2 -87i5/SlCFaGxS9U273pqNurlXMTYPzNsYvBLKuNds86Woe5mN51WnfrOSJcHJOpz -74FIkyT28I10yxpa5iAFSanTbup4SyNQlFUdAw4tkKl40Lz8ijzAnWYeaZHgBTnI -nEynYgBU7abXws4j03MB4m7ZbpbPOqjZhmXRtUXNDuykFlnQV3o0jsOzT45OuCh4 -GOjI/s4GW7ot1rb9+mSB8bwqsAgw0tGdyrcRmXqgThKoDjR3h3YRED2QHUHfT66p -pHj8cPN26FlJSUlCiLaUfo8a94SUOP3Xqy2EyB7337AL+51JG699M0zpTMX2Ym4m -1dp0XdbhST8xGLTN+Acy1LThUx7dP0MlWoy2DIbQjANQx2sc6FvyipL0xax5qE/n -TDUiYeQdfIn+kVtEERUwhiS9/M582h4Zsvde/Cb363ggMoF8sUdD4LSVBjKjRpu2 -zHpuuVCp4hfGAhhfB3FhzRSWRgx7eYAVHGJh9Hba60LlyB+MJ7blsQeXnsEuElBH -agvrH9VyhPLIzDapOrJu9VGhORBV+sdrNCAx1LpIgzaJAhwEEAEKAAYFAkr7N4sA -CgkQNZU5XrPY4bprYw//bf8ZeGLXZBCCxyeQxC7u8CT0BrOOWmHTtxJoH/MHk4tj -Dr5QS9d7UstAcXZ1WKh+K9f/9G8xBYdLPXOOWwLHvsr5UoG8HSccyGjti2XUz/8+ -dU0XfgjfyVEE0+/3qMtilIH8wI/GO+oJoWt4v8pQpRDGLrXFVOUrdYx3JT9UQxRK -sFye5uHzM4C7yjOPEohz2bIxRNZfshyq0QTbCw4StFhziWDQgsKkuCZWJlbAg9pG -YXwiPaZKR7tuNhdavVtJMYqru8cl7tc7G9TAVEggM2gGFtdwTTIBLa8wKQzlfVgf -RHEaDfW9nuRZl2ci39P4ld5z69vN63V5qB76dR+w47G6w8+owuLqeL4RzMl/zI3Z -LCTTjDG6sksxMgQzYiojO8JKvK1IrHyNKJP9n+aEP3g/mMX8X+gRfpprfpjNKzd6 -ILfYqYm3q9h3rLBX9r49c0Ovdh4hjb8nr6BLYAmTqeb8uO2ZowpRafzYo4Ql+SDJ -VaXI3CRqKDTQ/zfbJtj7XvMcwwRa1j+PwsmpMUVLNEY6IXe7inXTxM5UuzIxtBq2 -kEjDgrcZLW/UY+vIN8+cVBdpThqQDaJOvs/RWDRKR9BVZkm1Zwtnhe9MouzQNFaw -Tb99vcdiPPwJbB17YK/ZXNnCgOAd9/I4tG8BCBmqE1iphKAOOgOSN3gBe84mC6+J -AhwEEAEKAAYFAkslNXEACgkQMXxt+Dx3Bc/kWxAAgb/nsHB5FtsJeVbBTdf9ggsb -d5nj4kzUfsesRlfEVluelP4/y6SWOoWZd27jmXLI+7oy7IFZzbM81Xy5E39mWWHu -mVd5k3h/BtHnh3kBoFpdCKJGTGaLTAG12oSd+FUb3BWWPg6cn1L7ZBcYe9aqucge -Y3fXqH4JUsOPP+v96MnjSVDinjirVJmXRPB2Uh0rMYSpq8YFT1VKagx1maiabi6X -4pv5hWN1+YvOtsbAhwd/CGJUo8sgM3B00GhaS+39WeWXkAMXX0maxEqC8wRYIhOV -/8yEwQ4T7MqhTa1SHqoAD4uJjOpfAtChxv7HJNIuXiI/yW5uUOUrxabV7VUM9WYB -cxthJOkqdG1Bu9bDihacJDY8QRugfp5O+eBLKngbTZ/b8UNJ2PmvjinvYT2Eu9rO -wEtm/Y4EtYffa8JyBlwdPc1TDKZUZ9iYCYtcOKJZxkxYpasl0dz29KWbR9RCyiZ6 -XLXcDfcqAIFxCH099t5vtTYIpPRJAY0qcP/NTIgZFXwcwCXndexZVAY3EfxcZijF -VSlZklgx0lcxnCRTyQRw5uMLMA0Tzn32VgwelT5GsYtoO+tgJFjClF4XD1uvTl71 -bI13adZCqDGjtoQTYFWgpP1c4qwMG8LfpfMReGwgBgkLJ/yYYVkzXK5T/aRPV5ec -N07rylZZYSUNlgUw9zKJAn4EEAECAGgFAksM3mggHFNhbmRlciBUZW1tZSA8c2Fu -ZGVyQHRlbW1lLm5ldD4iHFNhbmRlciBUZW1tZSA8c2N0ZW1tZUBhcGFjaGUub3Jn -Ph0cU2FuZGVyIFRlbW1lIDxzYW5kZXJAbWUuY29tPgAKCRCbuGOw9Ru4isn4D/9d -gKLjchI/6StVec4Vtc7rWNOWgiKVh6DWcwy1JnAAm0/qRoF5lWUN4WJgkVQ6Jl8k -jLhSWXd4wjb0RWyLjo+itzf+jqWky84Vyz7NKmpyajEQ+ZC1uZHItlrALrGYI874 -ezjUx6o+ESrXozisxmfsp6NS7XpSOznhbVSzQfsJcYcjwhzv/2Y9kHuMcP6IKKtg -4H8J5mnjG5tH2slhSf8iF1GUyYrn1U6HXTDDDsJJIxxbT/sVpnXrQPWNL38B3mkZ -PsjxXwp1RUO1c14R/GWWgK7Ga37eUMUvcR7TaaHLrnqpPFXoHfb+phh6D45TTM/0 -goPVJUhPNHHqtqHNf+9VUUiZrxiWQKO+xVmVNkon/HPVy4cl4oTvavUdWiLrLCwI -i3FWPCskPhBAl008YiOH3uAPCSs4EKRiJOJrbE3IfVZyGmPrgqH58FGhEbFx2gXZ -mHI5TMYx22a3PLs7CtyQ+1Yl5nmeczfYTMAhqS6BCrutKZcFL4nT8T8qui56Ow5b -MwxCseNVLWR66jAXr48m1bJmDMfR9uLxJnZib/Jpu/nNVvk5M4uyJQJ08DbMBTWM -GQT2G0geohqQVgOd9Q1sQCZYxicS3FjzCvh8OA5Mhnzipk3wD6Cqe+TOhz2Q3eRW -rRYJnD8o3G0oxwkwWKPWSDQhIzCZtyYp8f9v2NeAB4kEHAQQAQgABgUCSv4b1wAK -CRCKr4jW2E5BrmKCH/4q0o88i+g59u+Fj6dg83l8PBdRqTepFhQveT9XxINcWpTb -bQB7R0GdrdJukuyehz4yU/pPSRizzHBWGneDLEx2dMVzDOCGyfacpwT0FB+Je9Xj -E+hfyytvwWF+Gz7hrQ1Rkr4d1RGoLOnBJb+EIsty88XjCO7rBpE344DQEDIb4dIo -0+EGf3131JXyIJLSKuVD58X6vFiF6bfr4KXAfL2z5vzm/UMhBf9jKHgKgqbNrqYG -O4Natw2hTRRovHKI/7AxRvXE8JoqQK0kldrxTlp1ht6hg/DrIwznc6FHIh/yzEo5 -4ulm19PNLwfwVnfB2mT+TcPDX6/ISNaPQIzXRY29G/oGzm0X3Y9R5u3LF1kf0nte -OOeMnlEx7zJvBT1lIRLKJBs1lUMwgMhCUGYLbEgxd6xj0Coo+Qizko5xzHewpjeB -Hh7Swrq2Nw6wkP4RIfiRVILtSlZ79x7JF9x3ioBcdBalY5H91sRD6PUtu1N86FjK -7ZbkB/fW+5rUnM5ZrUXaRByCMUunYMTM6e0jNkaub3DLg80mYN/2uSbIVLrqclpv -fDoUvwO5ePUsevg/FANtNjr6tO85PXl1XfastF9FlLe8niOIzQ6unPvCecuONPN7 -lvUv7ZdvloUzAxBNeDBSVCbFiAmZVq8+2z5/gO6AWD6Mor53IT9W1T4gOpu0n4U7 -8Ih/Op/HP42ctjhw80505VjiMesIVolrRF201aqrnQdp5nxaUNhWN6LtMUoanPbZ -0YPBHO3wpmI1eV3JME0szThMpvTQtsVQ6je8g9JtICrk2Tr7QDc9CvZojTpWQfXz -+c2K4nudmAsytWg1RSUOzrL/EJiyeh8JzuPMMnHSRX5jjR0zBvuy12RuWjXZmllb -hqzCyRYAn+R+v7noF0teKc/72yJtMNX5qVlmHd5TtfWBUdiEdxKR5avuJEvesaIp -L7h4AC9THnVY8NVp/QAvCbK5llHes86e/hDVSIuWyAVHFpfeU0zRT7IqZFlbFFo3 -+gSh6zQZ7ZyoYF1bndQtRDEapmpOIvjfaDjJJVyiH0HuCKuzMOpeXlcNLP2A/uUO -AETMyQzkaR02JwraPPbwpLz/5sR32+wztGBr0WBHy8DfZnQ1Kr8s5DcvIrcMmBXZ -94f59sTZIIHGUiA3+aKL/gtS3tV7GrbAbLq9BmaXC0wJ3SBaGYMlvC+7151Vp7YD -5t+JNyzjrAzIOd+LhFd3Qj0lOdSXyWR++vradOBAfjWbnUqgbA2QFYp+ftqeiVT/ -Zd7+C/Y8ZU4h3CYs5DZOML+Jz7K4uKmFjZ+M6MAvSqHrnv7SomHLQraP2asnG3lE -MQ3J1n2MFYmzbGi36SADsU+Xxqbld5EX5yLD6WHvuQQNBEZ2qJYQEAColB8p5fyU -wbsCLeaX6uSDxG2ShSXxtsKlb77PfNYz//9V0zyrybOLRfZ5DEiFcdyuFUAp8swX -Qm0+62bWws6dpcs1dYkOxYt9JIchxIyLuK3z5Qobsm9F0eBdBoVch73bzmVHF5lG -h0u/9YegTqakSor8jkr0Je65tqxBL/jTBGSTT7T+7OSnMqoT9AP9XDiELqqBhuwK -2W/BLxLIhmhmpD6E1qIwUNzogADMrvLi6N8ol+6M/8OQYp5ZQpimlkl8i2tATD52 -bpy/37RR4hhTNKTpU4J/MeEEggsmmpQdfW1Gl/8u0QoW3p6kpSEwDaPbwjwhMjVD -8FOCSfc4GI9vFq307QosudNVmoElZ0OluKiv+oHfYM7FdAKpwOA1K4By2nP8Sd49 -lzRtCyghN1nNErsxuMncZ7cDX+YT4qfhfd998GO+teZQ98iM8tLpCozsh2JifA6H -USWCi2L6iiq6+Pz5z/D4l/eA+PES9cirUX3bpZ0rMcOxTdqYcizlYgjOYT9gUJow -EXwrN79by2teQTqgkdmXFEyglm9KWX09JR7F6sEq8UzbHpBJaxA3PUx+sP2qFu3A -CsltcnvY/KSUImE/YLYxR0wFspftC6UeqqRgByTZUxHHS/uO/DV5Oxu8aaNtxURE -bxuDJozgHbYd6B4dXCtOzUM1/onjDtFObwADBQ/7BUDDXIh8RRFDguozqFR29VAl -ncXNp1fWW48jPa7baj/FJayKt4J3CkgjYoQ/ddo6qccRzpTs/ws0vGPNDGFa5GQN -5/0GqWmd46e9vJ/HJQLuc49HQ0ooMGkg0uKMu3BKNo4PJ4mUwKD8uQEh4pXicblJ -pEOYAeUPQhiNkrdFhHrwXMFiMiasmYVeIGZZ2NENfJ1sq8f/0DMryMHpjs5kav6U -CC3I1lkMOxFdvWPe6UoAOZy0PESdyqXOn39j+BFRreRDQhLWO7QECaDH6zj/0f4z -y/yaCBPcdm5ynisi91JV8wNmxAMq9cj16h3YXRlDMvWDBAqv0b7M1ev43aOmdSwf -pxBolLEv+WxNigV768g/m/7RijVH9kjai5zI892M3DcEngLbaVGGBOMTLFtQn3aJ -AjIie6fUVT+fILbzX6j7AquadatTZHHTzT3GnlU+TYgxdTrvcHJQiB3sTxBVeJ21 -hzd2kqiBuUjkB59NYx30zbKx60wAK6ZLnKPSDrVa844s+LXKj5elnEQOFj5BV1Y1 -0Fg8bam2Lcx4EDyk2k3QzuuMqsFfNgJGIc5HiWww5jHw4eiNtxOowWNY0D8ZxnH/ -uiI/7++rWqwb0RNGauvteHtB1LWcWU16QWKefX2ft65pXzVXr2QGWeVHUUd8wEL+ -r9PuSL9rSjXlKBfuis2ISQQYEQIACQIbDAUCULNzJAAKCRBpNAoC9btSzY9XAKCA -0b+mUJ4D7fOjxuCCKhZXFLLfqACgh2XP1ylDq9w/Bdn0/KSV7Nkqq0E= -=x7FB ------END PGP PUBLIC KEY BLOCK----- - - -pub 4096R/3C7705CF 2009-11-05 -uid David Fisher -uid David Fisher -uid David Fisher -sub 4096R/CB372680 2009-11-05 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG/MacGPG2 v2.0.12 (Darwin) - -mQINBErzNZ0BEADBZhY4T2tcnILY+OaZMfy5AOPx+c81qyhe/fN1ym0kgCD/iCQ2 -ORLE12YY2JWFR16Q9THmQzBX+oqBpDRMlXpGm6X5DuZ21ZCQ2A06QwhpMA9zILpo -z2m4QQ/boiOWgj1ztUFjwd1c+VMvqSF9OLP3rrDiOTaKElLwDWV5DhW2nhronjnO -84EbM/5JB3TeFOhLcoMPMMeUZipSiJdMowAqGIha/q5xW1DrE9u8d7gZ9QzjndEP -EutUszt53NaG0L3mi0CQK+bu6ddWwiUCXBijRLq2TA8rlJptDgTHIQZF2Zbo9001 -ZD+1EvRrRyc9lghnJBmluAT/cyM/2HQUejHkR7hhIon3wp82OgM6sleSIyBLdt7h -tnFR0N+vSUacMnr62m7skZ/MjyW838Otel7IgJpq3eNCm+m+eegRMQDLe28lk/8/ -8flIaQl1LexcSAr3jSRYD67+RdmN9UsE/y+OcOgTclJTBRFV1/ptBXuZeC8HgJJ4 -BuluwmZ7S3jP5wqvqm3cOIhlbkJic3Os6weAcYGLpruDLUhPn2hZfPiOX7B0Y9aC -3X/0EiFGXR+GLx6xgAx0xV17S5SSk/lfsT2e5lAt0/jxd0b3x8E2/MRB9pD2nFx/ -pSpfPkivRkDpo7ioqZdGZa0YNVk6i67jFaehnpq/+PBzdetmJwcHHcr+AwARAQAB -tCVEYXZpZCBGaXNoZXIgPGRmaXNoZXJAam1sYWZmZXJ0eS5jb20+iQI3BBMBCgAh -BQJK8zaGAhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEDF8bfg8dwXPWEwP -/19bXw6m5QzXjS74vdRcYQ2lB3zH+r8zdPSA4P0Kr/Mou9PeXAWzNP7IQvi8nU1N -zIEyQgErj26ARsaNdk9FTevr4e/vU/JsbEit48YKSOIrAxINCohAJ9lwUC4FqqLS -ShvZycXyRpyDDlhbENQg2MFLvZhau33iEVCtPJm6yyGJ8IZnQBb17gI8SkPKHT7b -Syvp6NVxFP+/ML1mvdJA+B307X0x8ZeXGWMphT3zPkPsoFZDU+zvMwPJA63295qQ -oxiUvgJuOQGUhdtdyjPflremYrD2nIx9tHUi5vDSydOIO9O+fsodwWYaNXNaXQUq -XzwkhZhE2ihbzyqA92hNAGy5N25xB6jXmMOwVnei8BdtsRZQIyCqZ9BBqluabnCZ -I7559eKjJtHDrgzMZXZdcu8xjqECslYeFB3wAFH7t2I29X0D8l/fxMGIl1d45w+7 -nJIiz0uCb1H6X5C1ZhWMwWgDCPN2Ij8aGBoY92DgB4LVQeUd7mQquExP3a122BAa -xX5gyKLErO++2VdNrX2XXLi6d0DZoaDZKE8qUdtIcxpGIypvnhaqLcb/PadjWN7r -vvyAXVmNH0JviRRyIzc1HJAcKv2m+2BTz4w7MixpZMjdJWbd+jrEdornnqZkrUwQ -UCVc30XcenaU2DGA7LDX38YAvQ8deha9F+eiCDZLDcl3iQQcBBABCAAGBQJK8zjw -AAoJEIqviNbYTkGuN1If+wT97beyUm5emTdpGt3Ae21wVwA/bXvi0YSDRkKM+Sbz -NspqLQZ9JM9WZb8+hQv2blIJ2v7+P7FwB8cXwWbrDWA8ESBKw0PYSxTkaibuiN7D -8Ys+qNkcWRvCgJBrSkUU9b8t6dqKCDdZjwQxzfjn/Xu7927rJC9O0rpCmMRT78m5 -kLH9ae7OSE6vzILGz1u6jzfw86e8TJHVxMO66XVlZyEcytCBdc11dVlWEFZEDN2T -QSZG1QQlckBKwEKaYSvGYNoQEOPeZADLxSDdi/LuuY2Ag7SHfWkOVZvhURt8iNKD -o4OsKEfVHRxZaMqMFZaX7Jf9b4ACyz6245CdISGFs/xAlst+c9T91DDL7gAUZjpr -Zy9ZMWIECZs+ti9NEskOZmcZWMscCGg7oZkzGCYECPRxttatAZsBQLg6e0kMIQ8s -5sBH7YxlW/TgYDphNmsem2hQkbGeI61BiSjWsVycXNOSZdguWISs7fTzZAA1VhTx -a5yz3TNzxKapykA1i21YZJuSstKzHmW2T3jLTDDG6/O7Zt/yWtZNSV6FfpbYVXC3 -B6GyCQEbLugVMDoRpF+BmbeUVui/KoNaiBgmkNWFVXajQr+36D3friy9jRLWKlX7 -OcKl3uro/fubya07jfwQWMb0ZNBorsOIDsPttLLbRcufNq6uqnmBZMrZ/LhRZ7Xc -sh4DfnYOefWpW9Moc7tKU+RfIzudpUxZnk4oHGWggXwHp75s1rRoI2EyAakiQYz+ -Z6pfKvlXYlGqX3b07+L9MxqFUcChCID6WOenYt2Uqq7dtn1CvybFAgE/ANZE1O7w -ruiJd5RATgY/FfA9NXvKAim1DlUL0FitIo1KiuZyePXjXvvFuK4TTQupRqmKmXxe -c0iiora7Dbn59EQvJ1yHrG6qYZQJiHbv8bXNdGPA+q4Kz3ggDEKovdhW8jL1utdo -URptx/TDmui5CF8sIUxPsOJvhDF0BwSA4Mv5IlTj3vZboHeEORANY6JCdIMZkWDT -GneIdApO08bmfMaakZ2BdUcjWqzlUuiFQUdk92eHwCMVqgR/7yFZKXCpR2eXv9FR -KjoIDNFaahu9EjgXKXz/LamLE2YjuLqdz3At/eQiZLCMyow4DJu4XLveRxqw5MmF -dYEleXk+hfAnEcoAaaU9XaFbQezR9xg3wQgTas2O3WDSAhOYSWC7rQ9V75hujWN+ -Dn5RW5S7PWYfn0oM+TAOBO+W3EZSoqep5EiptX7PcjLd8FpAgn+hoy/urQbLoslH -VjdrXZNzJXEIRDPPPp6s5bMCMO76l1E0nJlabVLHzkbC052fDg0M7MP9iBK3tidi -hd/w+Nj/GOMi6gkRXuthzv8OZQOIsXdf1XZ2w/NBEEO0HkRhdmlkIEZpc2hlciA8 -d2F2ZUBhcGFjaGUub3JnPokCNwQTAQoAIQUCSvM1nQIbAwULCQgHAwUVCgkICwUW -AgMBAAIeAQIXgAAKCRAxfG34PHcFz7mgEACo73C7eGcOpo5dcqacym+Bb/yGOiF8 -cT1pgxeSCw5s21jkhrScqCwRko+j6T40zQa7m8j+BZ2LSawHa+fw8GeUtgReWcyK -B+x5J4iGHBpIMxcDRCCNDlAhg+WhLFCfCEQOrInU0KR1CdUQCfw7q6aycDooCg4j -44z7FuirPzam+lOPicvGozFFaJZaUYO2xtgZu14r2bnd7cbq/mv8TeHMTCSX5O0O -ohehkze6CP8jVP0h1N7zADuOqgj+EXh2Wp13CxYbc31jpsCBMA8XIgF3uN6zL8BM -POaqs2dLOWaJsKFq22AOy1PuWhPMZ35fIBydhs3H3m3lEvI+oLcYheqI6QgChIzS -+NKeOX6VelbWjbFI5kBrJuoRVk/Sf2CZJY8qq9dCAOcSfmxUvr+1udH9cn4JuwjE -XrtVTNdI/mtRdAnQ60fhPUgw09z292oeNcgYnmwBJdNIi+Dj/lDX8i+4eaP+gA7w -3wBbSKwgb2VBQ8Gwpb9QsoWUYQxrpi2Z2XwIkDQeIA91j8sLsj6/RZlPsYgM306k -adkO0t46aq7Vh1hUdgQQI2cEMhn4dN+Nc6J60AbquSVMq5PngP5uxrLbfCwcIC47 -zfTVN8K2XfzzpPC3dCWiMp6mdV1M7w7s7IBxH9r742kBX9NyjrB7eEkIUz5HGt4n -0UD5ZIzRonkRiYkEHAQQAQgABgUCSvM48AAKCRCKr4jW2E5BrhT0H/9w8sW1WLpB -jR0MKbY4zeHP5pATxXog0GtANzV4UWaVA5N8jE1f3GTJzpXfc1mSckKSFXtu7ldS -bud66asoZAwOFr1x9gnynGpSlP5jNqIa7VVEvI3XUH16qPWM0a9lDCUSTPV0pN4L -89eThd8HVVs1ff+HEbpn+SQSch9b/bwGfgfZrzs/uX6FYfkEzkiiFge7jkrhKJpg -Cs5ZzgtYT1BmvXcJWeSJUpu/+wOjNEArWPxtvULBcMi2Miaq3Uw3r+TgpC5xFEhS -s03BczA1E4D0HfESk0z+TOLQHyxhOSscjxnzIBjgGCTpqZ6v+bsZID03bIuI7PJY -C2+EwHjokY46WJm9/DHOZ2nb5f7vWjr2NDHhC+Qfl8/3B+1YBxTmv0dsOaI+OZRY -v1te4QKc0ebWc9yWMuX4BkI0gitxd6VNWVTaXU89p8hSUEEKYzkXZ3VKxBfmr3Sg -c84kQEAtpzmvFuCdFky7SB8Ju859wfUvuP+IkYBmY2bJdDuDryO391xebduGeib7 -YCe4Q+yei6fWWHRDh/PWZ0+WazRmfirvaiD+RU5rFUrXzpiVz2Ir9E6azkFAaISi -DxGOKBge+0CTFK8wxyMMytZLLdGAntw7yHbyd0ziWzbdIoWwclCsOeW+eqFtN/fk -LcIjLS+e9Pm2RJUsCKv/0Cwf7F7GH93nDUhKTN19j3gq7BfDnHV1pPh4gJKPa14Z -f1dwSpZj4gN53derP4JKZLmUkFA2kEVmjQhWsTZ+5uup6I8o+x6tmhEdlhk+2IVL -rNUdLnHmeFZzzNogvMK0rcaIdEYCAXES0bu+tY/ib01bvqgQyzMk5Go0HKtFwpNt -mQ2mrrGUqe/QAhWVVfE+JJxPcC57HiwuaREN53/vccndHi8CfsB6tqlfjsCImvIC -0aaE7ThXLJTiBrvoidgpc23sCeC1KjQj1qFyzEmsfAmtyTsxei7mprfY754o6c0l -PXs59ZfiJ/jOzEzP8abNmq9JYQ4P7f/vwKAtbvxS4Zodi4OW/ZatUXzOUm8hWHml -Yo+sOr5F9Bfrqp+tTqRxMGgh6C9vwTW2bqI6RnQ6KaDMxkknyPODZ/oZRc2awswC -DKkHt0fpfijN+s9w+ppGPebGtol69RW88rT1XcKh7uDigZuMaaoXohnMrIB1lHp8 -1/RMog+6whzWN4rZLn9Jbj7rulX0eS9S/xW/3Ug3OLafdVaNpQIbgm43/qDPgC9v -2n+Vt3BLtMzxw/KEWiIi1bew84sh/5RSJXI3lapZfVz2uUIRnuuDrr3sYJvmw16o -wq9Og5mnZNPzyOwvbgj5v0eZhmQFC4493FF7B/FRMi2u8adZN3PxqIuaPjQO3bJv -kfwh4c6oX/ustCREYXZpZCBGaXNoZXIgPGRhdmUyd2F2ZUBjb21jYXN0Lm5ldD6J -AjcEEwEKACEFAkrzNsECGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQMXxt -+Dx3Bc+IPA/+K4Wu2chy+544orDFxfb50Yej8u3fCGHG/Di3fltpxWpN/QRbBwzH -wkRhhp5yH7p3cVMeJnhWPfP5ZROOU8TYdCF2M9vApF8cNoOCeLt941O7dj0rE9gI -hqDOVEXZ0rfG/AM7s3MHNFoTMWoeBJdneH8W06NOkP89ABwf/Rf41khpgsDBw+9s -3v0/CW1c1ZdY5WKbjIoUBFq4V1JQfwyTArdMsOsGwONmIYGLcA6h1FEi93bCpRnD -crDG2aFN9OHguHWMUb7ru4bpKERjUzpLhX8fPE9xEXjIegM9c2t9dkTcWgQg7EcK -kaFjn7FqNah/26b6PnHOAQi9TdLPlrPVxoTpCrS2bGAtL6AtsSTqEtc5eDHA+gHo -Mdtut9Yw8FW0rVyDllXM1EyWNGBfPCpFFNDCW2QTrmS0dXTN+S7N5ZsZI5lpqQ2Q -4DHNyVQt614RPPuC3Z3xtZdu9i5+npHGstXRYc70zVwxOR+oqzeTlmOsq6C8OdIp -qXHxKjZgYXFcnhdzEolzwWQUAVPw7pCXQ0zAnpY84XTJ0/QYLuJdji6FNpzUlTmG -Uf1lIRzC4TKU2HIAZN+YJszG7qjAbVmJVWB3ZvvcfoxDqGiY9oCsJ5H9K7GOhXGU -HKrHyJQAbLuo0HABWnZ/3t04gUyXjAYEF3RVwimw/TNDAy5IkjUQhVmJBBwEEAEI -AAYFAkrzOPAACgkQiq+I1thOQa5kiyAAs9bnjt2z0pAW0id16P5XyiJURSRYqeuA -4ayI2Ohib8/hP+7ukefiMba29VNMAUzjDqdVklBlxyJoDGRg5WYrSc5VQpZbloSo -IzaGYeuEijRcyOD7f5M3bZuquoYDG3dViPp808w7fc74zIVKAFKsOh3zgv0UKcuJ -KwycZL7WZY87e454++P4A7s2sfhrWQk/NFsHxDGpIk7vX2KHkcGiNsVj7W0DCdHg -WZtJfcQqJwOlQEHJqKQ/m7qayFzX7VFNi5UTs0fFfBTx5ydbOfATt1Kqvc1qmHlF -VGoRFmg7wqa+ERBuwis9LnwckHsejx1pYmywLT3hjoXCtl9EaT/CEiLIatv9Q/op -23ZJ1nlqY4WEYW7eWA1pgrtaKCbHp5b421ig73oOZcyyfFCMsNN30OSlyXG6tmiz -XZB2A/U99Ev8+Sgb6yh0CyO2VslZtdMUmsOoJEiKu+H9PyoYLv+1VHFSDn38qNQL -tQOna+I1CKEBtfopw7niHMlKophmHoVYFHoQ1RYhA4RLR+3tdAFszVM6/sJejW20 -41s0am8Ssddl8lnHbXxldnPNO7XMKQWP+8NIxoGfLcNjBQlkQVm141z9YsQmMG5Q -Bg3C4R3IhXGZ3R0PmsGqCpWrZCaFdmRzfRbisB8HbSU2RX2W7I2Dx2DAjDs1nzQ3 -RYQlnTMneJhwERBs13zbTvu1stCrUl5AvoPiH1B/t7JQukV1aTj/7+EXoipCAYYj -BvvJqczVKIuIqH/HW7vZvml+4mefkXwrRqG6fshE1vp1eK99cW0edUjND72ftLnn -wnu8Hs8ps/G8krDa9yjHEcWTuaZE3SZjoBuFjlD8q8VdSqSwMRXjaYQoVJOE06UL -tMXfy5AG9mQnZzzeHXP+h/RHGgldyFQ6uzHzfs85rqubk0ZMo7PK6iQbEXmpqkLa -xpLrc8C+UTt1R9MsLY5SLX/fcvq+AfMIqCE4VYCtmEfQcCm6u2oAhRfzJzXISv7z -cZbUJuP6CjQlICqEyj1RmUFbg7SkUrW6Kszy+/MZ11pw3yQkfL2su+5Z/UcRDrKS -n2gXZa4tv7ygiA4JPpZWyhroReWySb6sSPIbq2EpyLhb63ukFPGxTBKSg3sv3w3V -EYG82Ss054MNf4D9S1MtSjHWL6RTGId0Ln90woj/N504h9oCIUMM0vVlIj/c+TaB -mTg1at96NTYpC5oCGnI9J/G0DEYPrKipH4alJ+F8CosVdLscMSpRHnjOXMs7Rcpo -tdxQR8csDzhdPQlfM/JlMp/PVEgGoTv0El8QQWIUp7dGC33i9U6PUUiyDXq9Gm+Z -0/nH2/tz58JTIscdAEF1VlikrgLT4AuP0vJlWzRKKmR+zpHgCeFon7kCDQRK8zWd -ARAAn/mG90gdj8EjngWqmBu0/hYfL5kdTkFHeeY3OKReQkaOxhxpdxrDP2kepVkp -B57QQ3ul2CNu/Zv6hy1MCU0ML0Qh1av/VSWlEbRfPBTgbTwu32WXDnewNloEoTvy -Oz5ZShhgFyo97ULOeh9HpjVPSqRh6nX8DWlSiVDgpPlOmU3nNBck0UD0AEj/pf57 -ANtvDO0EEB7Bp4CmSbR6YNSaTOm5AvlpR7pBjYmBBbtAn5ovpN868vGWoquOIhMy -9z9CW5LPDKbn6Ci5mHXGgmlJV7OEQIeqJ6hkh2zsqqxVRzo5Nc6YShcW/pqX80Kx -5mLOOstIxjx15YUc088roBtnSNnDu8/oynJv9W85HBzBG+P7zuma+WthGN2i2LyV -VZaA9VUEQcFLtYiv65GSMUIMj5H9HsjOJJ6kw+x19MFWbHVBSSSroZ9iZduhRXTE -fmnNu1rtYPOrZub9Eh5SOm18h88k/9uPmnj/8kDsPTCouuNLHWl4yFWcV5D5u3Vy -lQg0A6wXxDazahvQu40B9z52pQXq33m4OZQ18F7Z8l7stw8zRKVakPp1BrngghsC -iR7HCAkh1FA7IWSGvDD6/YOOgIBfMOQC2DnG9WhTpR0m0XpfQdDwqN9n/lx2tj3Z -grT1fJ2pK8VUwWNPvjGbtCou3baVZiIUKVE1ciQSucHTst0AEQEAAYkCHwQYAQoA -CQUCSvM1nQIbDAAKCRAxfG34PHcFz3e2D/47+jDJ8OW4WH+wIzs4c1SKJTrcOcgy -MlTbOu+FV9iOuxpnTXaVgzRRhBg2JkZxpkg1aDAzJEqf6XIzCEeanNmYzUJ+cCc+ -YItpQvgAmlGH929XBSJ9g1ErS20sTbExDzJQuxtdjoVPa2ocECVsEhAuW7n/JUfZ -FRuQtx8San37CEze+nySB5uAfFt5AQ7ZxK3W/57xE/DMRLxvyjwVgMPOPpkZ7P3Z -KphNZ9VjPJjtgZE73fIOJ9D2VZzVlmyCeMASXp46UHIzjLcHSXvpXY/9CcP4wAy4 -fBHcw4liNzf9KP4sX7VhlAxs/7rTMN8uOBTmf3rpnMQ67m3hL//4rrPIUQUreVXq -iAgH3V0ZkkhgYUdyrv1G1qfrnlMnRB3xIJQLo4fAoy1+fjSV8Rl+pLjB4iB01eLB -4su8sdC1obzy5wxjwNOKwYAOiAn9BuO3HzB4X4Cou7Lb2mCu7WF9pei5f+rpn69P -cqdkk1qkXTmmZJU3VFS8+ZPthLIKvhiAJWKoOd7iidNgw9kfzkWKDID34qCz3gZ5 -1u4N0B1/a89+tinnZd6JarDjK2F2yILxeafPHZ4iEhAGpjhJ+krBtmmD9RsPgmPq -jtjkQxGn9HwWZPKxNPu8wwpL/ewSamc3No3lW8qoauaoc/aH+3SJ9W2Q2go+2ZYg -ThwM1UqUgNRjNg== -=nttW ------END PGP PUBLIC KEY BLOCK----- - - -pub 1024D/D1F99590 2006-09-08 -uid Josh Micich (Software engineer) -uid Josh Micich (POI Contributor) -uid Josh Micich (Australian software engineer) -uid Josh Micich (Australian software engineer) -sub 2048g/5979F244 2006-09-08 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.9 (GNU/Linux) - -mQGiBEUB+2cRBACXiwHbncLW3UfHBiKXjisziEeDOxEqNAe7JWkuaN6YEsI6MWrc -iCov5fegHMD51wmSukjty/ic9c0c6bZudaRRarIMQ618vRYrjAIO0RUPawA6nGfw -x/oLnuRaClgFL56YexkynC7qLZWGlgttbOuNIKkg4y0nDpC7mAw4lYKS/wCg1o7U -R7MEk3Rkk6cDaSAFpCt/i0sD/Ayf7LG5sj8TkXDm5sQNclNOBkJ2KFXzv1zFZ+mb -a5769Vd6nu+cj0UjRsYtq1hI0uXWiz+0twJ7XjAmAVNU4KEbmKixQkTwoN5PlDa1 -GXVfbQisCGzfx5vA4VRVGYt6zoCWWzOxxWBD3S+Z4itQrY+jgMvgqa89qhpHo0qw -CxrtA/42JoEK/zXb5qgbsrg3OebuT2NK2lDBmFRbbuHF73VhLSnTy253/ppsgvCY -eNBwC9QuoRYOWTQV3q+oI8w/enEKegN6QritBDZXw7aKb+QFt0+OZ292tLGqxkBu -rppVqYdcUHLiOI6PWZMkMwqwIiODlI36+T8c+yf7gRkseHLZH7QvSm9zaCBNaWNp -Y2ggKFBPSSBDb250cmlidXRvcikgPGpvc2hAYXBhY2hlLm9yZz6IYAQTEQIAIAUC -SBYNwAIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEIYLvubR+ZWQaWgAnRSN -H8v5hqExDJ9pGzAcxu2g2xtPAJ9JlcazJqcWKvlPt2iP5VT4Ht8hookCfgQQAQIA -aAUCSwzeZyAcU2FuZGVyIFRlbW1lIDxzYW5kZXJAdGVtbWUubmV0PiIcU2FuZGVy -IFRlbW1lIDxzY3RlbW1lQGFwYWNoZS5vcmc+HRxTYW5kZXIgVGVtbWUgPHNhbmRl -ckBtZS5jb20+AAoJEJu4Y7D1G7iKnSsQAKhxZFxWXRjGRIrQBL1lxPiMJkE2IsYr -Z84CvdhzP/SyJTUpjvk4tdruxFtGxgiO7VITFnHR0KMi70ErUxcvIqYBYtOHDabp -Iic501Ix/Q9MOg0BmPpco2i2m8ZzUXa+KGC6NLht3m5r6bG6qKlfvodzZnbOr7nV -V6G5tVHaZQGEfOvMgUQf2z2q/5+XkiDDmJiaatfYrrA5H21tSs74GOCEwxHCZVqp -Y6w61APYWG7t0cMpfcXSJjsn/VCjviXV3DIVkQZU8uf+U6wiJNCMgaVPSm0gIHZM -qNndzGMYycfzUQp1/wPZxFQLylx39XsNC6HHUdgwtl6OZz0klLtp40tJyBgKz6Q0 -ij28NNuX5fLturfCDk+GB9kT4PNzNixgEW0aHF2pfhfW5KPlOYAn787t80MorXxA -8nEi8fty66HFaRwwAuNPJjxMMOwgfpZMh3IkoFtCLzX81A4/8ISYftPGvA+ka15T -h/KpuX2vpUKR1EsKHy/nAaUFRG2aDd0AjkwmC817Oma4urirYme1UchG50A/WKRT -BEm9YpFxoEvfc0fecy8KT2zkHFH5+mvGPyk6goOqgoqyVjuNhka+sco5yDKyNLDo -HaIKLyaGMlYFmLTN7fmBSBj4WTWcHtQBPcuQNLuszqu/Ib49+bAdJK0Ac6y7osYF -veclSVx9rj01iQQcBBABCAAGBQJLFDYfAAoJEIqviNbYTkGuD6If/3Zin5nJwrf6 -EbYJfJiGaLZPBxDaBIriiR0Xa8qy7bsNAoOlLmyhX6SK3i/ZNcr1qvQvArPnul5+ -AtdWTH/eRq2je13qNHQzy006pUkvdQ4t4MhnS1faUUvBlwHTyNYu1uiKcGOGX7Y6 -XfsZIpH7ReMLRc7jasVsOJysNBToXasIpTz8Rg0/vKMfe7RinvsOFgyvk7eoM5LV -s6D/z1gKTmTrs5t/j0EEYYLbCeAT7eHYGCtjM9SVQG9cVCXybqpQSs/mgUopXGFk -qhfFvIstvIh8FmXQJ/riWmWt8jh5xSkAH86SM/SmWbJ/8rmiOhTB8xwT74g+CJAl -8kqSgoWu2QcQ7Dmm5+fRvbbf5Tkk2fcyrBChMO+MWFBvVaaZZRefB38d+ilP5cTE -xxlmDN7s0EKIaObo5RLtlmX+DG8WUNNty228R4dMuQ6IyXf9GFjujr7o2Hi/kqBH -8CLH1dFt4fpUe92hMlvv48mqolIu+s0LOEf1u2likatd9x6IDIaR6SJFINTb5tzF -QR4Hm6/smvsY9u3ArJUEPG46giA0lOB4KUif1zsrRDGTl3AZALlXcUOY9Zxk/LVe -PIFjrly9VhnXJd9kQRp9QRY+4Ogwe2XGLwVqkgmr0udCUpV7AAKrwSajGbMMNLZW -+j/7fYwedrxubO4Cd24EaP5qZGfhYJmzIVjbR6z3UpH7k9CUjiCQdbRKHMoFr+Yr -xBf2sRUwtdhR3/hR5CaVYIWT9/cEGtQI2WUeOLJelPYUPNq1JOrlTXsUvy6Zu+Z5 -onokpqizBJK9QQVSjpuN7TYBlOPeFVd/lJMWgEOqiPDJQLqX0IkOpqQAEWcVINwE -Ng4cqaCaXmt5398glk8j2waJuJcfzSJUFmZ7E0ItKrKprnw6QoX1OmU5s4nYsqoc -3d29SEqiGkgwY7TLB3kZGvPF1LGAqe51keSixxY2MrQw/pzlU36wdpVJXe7qpgNn -bbqv6Tw/SEa2ixWsQFUYpt+U48RPdHpdkpUmPu8yimZOOKZ/ghUmmo5HVtSPQiRm -Ry54khdi66ZWXz7rJ5GQmJWimigKiV5ix2wQNNeoclcO7jhI8mzLlGC4pVrME4F2 -azEbkL85lubNJvFWVIt+K+ngBeQmjfO8IYmENowtAZT0HsUdjot60Y2EhH/U7GoD -IEhysjNIXQSTsGk9/Gk8wiAnTfO6hBu2qM9snvvODI9fOZxGCxmQ5tODDdB/LiQI -cUBHaOcQs+dp70sh/E6v5pWH2FGAoPwx8fG2QctVn6fsT6yg2sqJ2dzNCTsJUSnt -fpfcqD7Tiq6frec6Nmj/zV+YUFOoIp7ppWMM7PRA1HvcY8g/B0KJsyfb412/UC74 -NDido3J0t560NUpvc2ggTWljaWNoIChTb2Z0d2FyZSBlbmdpbmVlcikgPGpvc2hA -Z2lsZGVkdHJlZS5jb20+iGAEExECACAFAkgWDtMCGwMGCwkIBwMCBBUCCAMEFgID -AQIeAQIXgAAKCRCGC77m0fmVkHvRAJwPCMlYxFQUTXFNR21qRQnBu/c7zQCfTtLK -FpwL2KCgeO/3J1UWZZx+1CqJAn4EEAECAGgFAksM3mcgHFNhbmRlciBUZW1tZSA8 -c2FuZGVyQHRlbW1lLm5ldD4iHFNhbmRlciBUZW1tZSA8c2N0ZW1tZUBhcGFjaGUu -b3JnPh0cU2FuZGVyIFRlbW1lIDxzYW5kZXJAbWUuY29tPgAKCRCbuGOw9Ru4ip0r -EACocWRcVl0YxkSK0AS9ZcT4jCZBNiLGK2fOAr3Ycz/0siU1KY75OLXa7sRbRsYI -ju1SExZx0dCjIu9BK1MXLyKmAWLThw2m6SInOdNSMf0PTDoNAZj6XKNotpvGc1F2 -vihgujS4bd5ua+mxuqipX76Hc2Z2zq+51VehubVR2mUBhHzrzIFEH9s9qv+fl5Ig -w5iYmmrX2K6wOR9tbUrO+BjghMMRwmVaqWOsOtQD2Fhu7dHDKX3F0iY7J/1Qo74l -1dwyFZEGVPLn/lOsIiTQjIGlT0ptICB2TKjZ3cxjGMnH81EKdf8D2cRUC8pcd/V7 -DQuhx1HYMLZejmc9JJS7aeNLScgYCs+kNIo9vDTbl+Xy7bq3wg5PhgfZE+DzczYs -YBFtGhxdqX4X1uSj5TmAJ+/O7fNDKK18QPJxIvH7cuuhxWkcMALjTyY8TDDsIH6W -TIdyJKBbQi81/NQOP/CEmH7TxrwPpGteU4fyqbl9r6VCkdRLCh8v5wGlBURtmg3d -AI5MJgvNezpmuLq4q2JntVHIRudAP1ikUwRJvWKRcaBL33NH3nMvCk9s5BxR+fpr -xj8pOoKDqoKKslY7jYZGvrHKOcgysjSw6B2iCi8mhjJWBZi0ze35gUgY+Fk1nB7U -AT3LkDS7rM6rvyG+PfmwHSStAHOsu6LGBb3nJUlcfa49NYkEHAQQAQgABgUCSxQ2 -HwAKCRCKr4jW2E5BrnZbH/9WDwkyzVozA6uCQpqY8a3oqibtLnJgYQYetviHx7YS -+2rWfXrBP4opLIGcI8twdtuvCanxdoH5eyFzlirYmXAglgB7DTJlweSnUJEQpXIc -VAcrRqg5yY01qxPOfMA/1oR4dEPHg1rk6dHWjMgXXWRZ8v3lzuvKXxdSWD3ktQp2 -BYV/RYdcsLM+Y9mR8d50di41HwucoV+RY6LcaeddLIzMrcLoxLNqbS6DTlQL5m2z -LSJvok9W1wtt2qSxWAFgHZjGwm68MukPumwEm7+XafQLDka9/EihirLn9trcqDj1 -KlLqzxkj/ptTxZowEpBpOdpdWyK7Zk4RNhPdqbdXECkWpGqvddQXTCGs/65JdmiB -3dotYr9n6gHotxh3GUi2pHNdw44nCwlmpyRYYgOTpyyD2lSP5Zak0NiPahmhPf4p -mmtXIrhAHi+tlM8yp6mbo5mhcbK3+1RQZ/t47IOCpFRkZoZCYeFB6CJRnpoR8QNt -fl0VoL0+gAbl1orvLf/d0C/5EqAFdT+7ZyIb/hAM2epKRgV2GaJcIMO3DC3acJfK -9+jMtWZ0+5bZ7Ld2Cr6vlfaHrew6L7GKHVZBwsqbOeMFfKU+RuAw6KNIHyALzPDx -cmSWRDcjNmsnEBP03JYT+/P5Cl3oG7i/GIiBKJkqApyaKAkclCKXCRnIc9/9E84j -EpNcqVb18O+irr+NTUmgd2vIBk9xhxcPrys0d7DAoVKkJHq7YQxfthwA23cfEZSw -w8bZIoTcqE9wjWlZDH0J8OBtsXHKD+vnbFSm4015XxqfUlFyq5hBPMGP9EwyjM/9 -LepHzOT8UStDtY6oaSqU/P9+GZq3l/sza9IRcSZmzBYY0ixEZ5sCPMBsZjiQltBn -k0NzY4k1uZfg1v0WpS/tpSlFtgB6bSCtUyU31f7Chy+jjXM0GmMfvnRX6d1yqA2I -PKsvLVBMBLbZ49lXLt12cUgmej9QALMRWRbcIO+MS3LBf4FjhE3KfVNMFdW4Ltp4 -yqsBWPLPVwqixuH5GckYe2O7Ewk59BeplrXiavgsyK4I2BAB1O7Vt1JrChjYQRVd -YGtP3BCkCT2A0WmyHjNBGhyjD/aCOpGqfq8Ain0z4pTF0Sm6RBIrBd0n1xal7nFH -LfFKfDRkV+qLCoQ7kueJYwNv1TPIeCRd2IGd2UfJPjoO0uJBPRA7l+jCZrS6OXkd -VOWJ/cX89Au4E+VSuQOkTz2dnEzmz5Y1RgzkW69DaxF85Id5aBVLZtwpW5ZAPApd -ZOzUkubFWl0V8hRzvCueG31KhQX4x2mXY/Hvb0ep7o7purDpBtAhU1ECLz/EYS3Q -4952rUy7rDBV9H7qVvGgu/6xWFmUiUnysGUSZ4jTib0jtEJKb3NoIE1pY2ljaCAo -QXVzdHJhbGlhbiBzb2Z0d2FyZSBlbmdpbmVlcikgPGpvc2gubWljaWNoQGdtYWls -LmNvbT6IYAQTEQIAIAUCSBYFAgIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJ -EIYLvubR+ZWQedYAn1TlCzBv16k6YxFD6UPjKfG9p1qBAKDN7OCk8bZvxamBpfPF -htCxBn5NgokCfgQQAQIAaAUCSwzeZyAcU2FuZGVyIFRlbW1lIDxzYW5kZXJAdGVt -bWUubmV0PiIcU2FuZGVyIFRlbW1lIDxzY3RlbW1lQGFwYWNoZS5vcmc+HRxTYW5k -ZXIgVGVtbWUgPHNhbmRlckBtZS5jb20+AAoJEJu4Y7D1G7iKnSsQAKhxZFxWXRjG -RIrQBL1lxPiMJkE2IsYrZ84CvdhzP/SyJTUpjvk4tdruxFtGxgiO7VITFnHR0KMi -70ErUxcvIqYBYtOHDabpIic501Ix/Q9MOg0BmPpco2i2m8ZzUXa+KGC6NLht3m5r -6bG6qKlfvodzZnbOr7nVV6G5tVHaZQGEfOvMgUQf2z2q/5+XkiDDmJiaatfYrrA5 -H21tSs74GOCEwxHCZVqpY6w61APYWG7t0cMpfcXSJjsn/VCjviXV3DIVkQZU8uf+ -U6wiJNCMgaVPSm0gIHZMqNndzGMYycfzUQp1/wPZxFQLylx39XsNC6HHUdgwtl6O -Zz0klLtp40tJyBgKz6Q0ij28NNuX5fLturfCDk+GB9kT4PNzNixgEW0aHF2pfhfW -5KPlOYAn787t80MorXxA8nEi8fty66HFaRwwAuNPJjxMMOwgfpZMh3IkoFtCLzX8 -1A4/8ISYftPGvA+ka15Th/KpuX2vpUKR1EsKHy/nAaUFRG2aDd0AjkwmC817Oma4 -urirYme1UchG50A/WKRTBEm9YpFxoEvfc0fecy8KT2zkHFH5+mvGPyk6goOqgoqy -VjuNhka+sco5yDKyNLDoHaIKLyaGMlYFmLTN7fmBSBj4WTWcHtQBPcuQNLuszqu/ -Ib49+bAdJK0Ac6y7osYFveclSVx9rj01iQQcBBABCAAGBQJLFDYfAAoJEIqviNbY -TkGuB9UgAJKvaMoAGjiHObVeIXnsohpQIjKfs0nMVj+uItqVQqdPKdeko6xA9NSN -O47PuiCDOP99b2Sinzd0l7T2SF6O52uymVNJbYOqdYkTaqAMXY98Koq8EKJhThXz -naHrAZP1vgtSWUIsAaiHe6yOhdyNNkwzjneYLRgnICvSBEpJiXPg5FYujIKXKrxM -i1meQ7UbXxR0COj5LHVxJlI5ZqcVlAGdAkzr7TXEnDsWa5ToHz+X60Yt92GtwhBl -gcgbX5QpgX15hHuIMrTJbrrvBuphMI3xdu4FRxJKJsNDkc4VTrroDGA7aqlCAsOa -4bCpWBUy5TEZg0iGy86bg6lAkV9hvMZjqEU2V4OXuGnmwOQcAunpQw60Fkk1uJEu -+IYyZdkPC2pcHoHa0NONeKbCvgLvjHVgUj7KxXYhE9+pehfg0x09uQ3nPXhY7QJ8 -z2Ru2iVwssHwhKiLUlRcgyv0HTZaPKF7kMcWf48dN8vz+wFxcd2AMxEwuVYtcgeK -nMimTG5KL6fboyT327ylFr1aiJd8fBjbO+lSUqVJN+WHZ+FpeMW7sRSlw0BG5jFc -t0wkAkDjKBwWUQ4YnjgIZGSbD7JRqG7GRz6LrBOqHLmXsb1HTUAEkL2KlFm0ImnN -9C33EseYd8v5QW/iXLtcawC3fAVqQcnqRZEmbua6C/I7hcGD42/Cb1NLmiMdnJ3H -nN7N+eglK7VWsrsnoLUVYIj+8NeStPkP8f0tUbsLVGyT4Lz6I5oUvQpanhYAVrg2 -76poqtPRAHdQt5WA0hyZoibeMHeriZGo6gGkspnQrjYTqyCK07vZH2QwVOxVppLp -N7duWkUTFqWovmRTnL7XMKTkdl5ssZ0whXPcmRLkB1PQz2PVU/c9vcIPsLehGMl+ -6RWldzTb4hMUhx07fScNx7iBAuW14oBXMpuXRKtG+nw+HJmQCRrqHgAVgO10ekTP -qYt72lhPhhMHfWjVU/oO9FflDkMrHEiVHX3MC9z47Es4Junu+EQ7LWA+rHthn0Io -wllvXTX2BcuxRu9y1zlEwPSiS97Jw55ieAKcVz/RpAoDD1eAzQp9+t6W6BIFmrMD -mMToDqMr8hDGXDlL2GNjTXqqyApvEXBZNywg2HknIN65wvUnxDBx0k847xTPpp7e -t/mMJucYQK/ZDCb+DEfukuq+4OA/Sem64Qq7xfGXNJiWheN3mKXrhXeSDLWs0zya -d9yZ9JAVGXvnuWFMPEV0zU/xWbQlwxuo0Bs6ycH+BqeHvicig/VaMbaRAIwWfHNV -8vRHyzDQpRlCBinQUc8gGeWPRyAqQh+uUNGf3D5lVK5QhAE/hzzNB5J2u75doEqJ -mfnFchXQBUcH5QaA11FWLIjEtbsACcW0Qkpvc2ggTWljaWNoIChBdXN0cmFsaWFu -IHNvZnR3YXJlIGVuZ2luZWVyKSA8am9zaF9taWNpY2hAeWFob28uY29tPohgBBMR -AgAgBQJFAftnAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQhgu+5tH5lZAS -bACgzdpXuT9bzU+ogdc1FfUPGo5PgMgAn04+PeVIXHjJNGwMnwcmAqhoQnYaiQJ+ -BBABAgBoBQJLDN5nIBxTYW5kZXIgVGVtbWUgPHNhbmRlckB0ZW1tZS5uZXQ+IhxT -YW5kZXIgVGVtbWUgPHNjdGVtbWVAYXBhY2hlLm9yZz4dHFNhbmRlciBUZW1tZSA8 -c2FuZGVyQG1lLmNvbT4ACgkQm7hjsPUbuIqdKxAAqHFkXFZdGMZEitAEvWXE+Iwm -QTYixitnzgK92HM/9LIlNSmO+Ti12u7EW0bGCI7tUhMWcdHQoyLvQStTFy8ipgFi -04cNpukiJznTUjH9D0w6DQGY+lyjaLabxnNRdr4oYLo0uG3ebmvpsbqoqV++h3Nm -ds6vudVXobm1UdplAYR868yBRB/bPar/n5eSIMOYmJpq19iusDkfbW1KzvgY4ITD -EcJlWqljrDrUA9hYbu3Rwyl9xdImOyf9UKO+JdXcMhWRBlTy5/5TrCIk0IyBpU9K -bSAgdkyo2d3MYxjJx/NRCnX/A9nEVAvKXHf1ew0LocdR2DC2Xo5nPSSUu2njS0nI -GArPpDSKPbw025fl8u26t8IOT4YH2RPg83M2LGARbRocXal+F9bko+U5gCfvzu3z -QyitfEDycSLx+3LrocVpHDAC408mPEww7CB+lkyHciSgW0IvNfzUDj/whJh+08a8 -D6RrXlOH8qm5fa+lQpHUSwofL+cBpQVEbZoN3QCOTCYLzXs6Zri6uKtiZ7VRyEbn -QD9YpFMESb1ikXGgS99zR95zLwpPbOQcUfn6a8Y/KTqCg6qCirJWO42GRr6xyjnI -MrI0sOgdogovJoYyVgWYtM3t+YFIGPhZNZwe1AE9y5A0u6zOq78hvj35sB0krQBz -rLuixgW95yVJXH2uPTWJBBwEEAEIAAYFAksUNh8ACgkQiq+I1thOQa4ivCAAj2Ai -cKuzJ1jZFY8uGBdw6FKripnfdpA49M9avUpw9kcnf3pQueN91CZdkmYFjlvdpNjj -+HtWzY3KvmMuhNF4Bm5LyGGXOSBq0hH0Mv1Ce5Fwbo4do7JgaAIUFflKOksd2Ff5 -RHHpFts2X8NfLxHpTsUp00ni3VH3EcEFX+8HtKslR+izCrOZ6wvzDWw13Wv58skV -NfuFP/YmeA0ra+GNPT00DQa/GK37ykP3ayPUoMyzAEqlReiJxeMXQOZt/UvMFHyY -DV0De/aR14VNRB6KWxyRAcmyRbct2t56Pk7KO8guxF5zSmX6AJfTIUGTRJ8OUIBo -2pvysT82wNbcq/77dTfGz/trZ/DJNKQP0Q7P2mtmwvVtEbcy6NrqK4X+AD+ZsVYA -X9TdTb3XLE5nd+Pp0DudOdtuJQIv73hWoKbInbL/6FAx1d1uSjwbQeqDdDvUM5mT -QatnYuzHKSQkdVsA2SljaOnTeAnD15bFqF5Ebu8YZharywtK50QWDv+pUFF2KWn6 -pYbHRYdLrpaI7+mP9wolaBMNtbc5e2q4DgIm1ITrihDV70jT2cS10U43rkr9zMWv -ESIUXMS4/aUyFitmFW30b+YRe6JbCxmCqdRhCodqLPn4BWH+cK0G718wN8n/vHPF -Yt0JoR+k4+xuiVUpk9zTGkFzItWobrVAftfZCh0X/Z46Z4aZGwzY0ZH+9W1ZmJij -ipwVsNlXIPowiBboh3VfihcR0pBVeU5+D8xcitHAO3HIYF3/57KucuSRnFwsLFD/ -x2tlSwtBoVj2fE+WEcCwgU/hXr5DkMT+QIV29o+cbgmnbdeVWmxphWXBRBcxU+5V -fV/2yEKn7JcybOH6C3T1mZkg1pDgzKvfzm9LvlIqojjFXrRh4EgCCom0MpMNB73F -a4R7Cf5XOzkGJi70RtzvfBjNXUxfEU5KNZ0Eg3mvCg2gJovZvquiJB1t8MBVbZEg -RCS5IEvYTZxPmmP+fgdFNah1ebJELyTeB0roOvL977dixpp1nnhXEvzaIdelR7xa -DPTBx7G9To8Phqte2FnRAHQOWGpaU6N423BUtNCqOlgfkjk50QLQYuUz2/D5KXMV -XcPTPUM3EwSQPwdyW+TN5x9jjn4ZBh/f0OI/IP8Fm5xTxTcIGDSu/cBxBTzyuAIj -9xQwTsIyeXio2lhAFS+N7zlc96SNmIKUKSwFoI+l+JzSR+5594TCouKg1rccsP8R -d9p7qbHbaUB4Pa4TUizwqfZRbOJtbmJIc2Mm0TDq7J7vblHXeudY10gvsNWffn2P -dGkzSq8rEYJ3whePF1j/f/SrGK/TPnMlHkkvbSw/dGcg9ItSI6gE7wNqR4K/m5Tn -LXVgiE0Htl4QPo4MOrkCDQRFAft+EAgAmPNAsOAG7MLnz0cLQJHJDlWZIzavFZyd -DrzueYsBja8XC0rkaM5mljUVb37deH8NR884sWQuzRN2Xfr9FIK+Qz5oZAeWv7Bv -xCAJ4JAe+/6UmdfvVuVUhJ/HFWgRu0U2gA0uEx1+9u8OsJ1LkKuYoZIVdtiqqlge -B5UY77tlmcMPsMBTwIB3ER3DOm0ayzegXIlqkPnKGeU9VdmwimkAqrqxyFmqVPNj -PZTTJH8vzTxCQGLQn/g7LKQiFAJwW7Oc6iP4jQCt+HRcH/5moeXvj0jMkZNGYwJ+ -iHdaC8ZZemDc6fxkkQVn79AqZBfmJ/g7QwMYqUcd6S6387/ARV/arwADBQf+LQ8q -7xqICLqTVaaJvgvs/JsTVNysl/79jfjiiozggJ+WamxY/zf/Nzivtf990ZQBnS/4 -2V/Nhv/LNJuUwhqx4Huw6kEVClWI6c6Upt3vZ3rTBIzvIhNgqXcHCrMX2oiCVPcj -MFQkUZf9XOmM6iPhQkVztXcyjB2lJQDhDdfrRISC8PfHF9pZk8/mdkx4QNs9IpX4 -EMxRXaR9NIinxg+bvV+xxfsfFr5n8T8rL9GaaZtOYHeGr+guZ/fTtqdCwjPDYgJO -PdXSV5JqYEYLigXpTEEd/ZUJl12nSOAOKYrRnsqXqfD+TlxcwqlNs4otlz0CQjDQ -gSbPwyNwr1ivwMe63ohJBBgRAgAJBQJFAft+AhsMAAoJEIYLvubR+ZWQWrsAni4F -oW69heOcb/0dIMNOOo3dVYe9AKCnMWg/qUv18zXtCMDq4UQzAEGZyA== -=1wCP ------END PGP PUBLIC KEY BLOCK----- -pub 3072R/97EDDE66 2013-07-29 -uid tallison (apache_distro_keys) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.14 (GNU/Linux) - -mQGNBFH2rQ0BDAC2DQ5+8uTR+mG26y+M3jl01EXQOtGCIZIqRYnQgz8cC/4/SQhK -Nn8SwEMQXElgPMs7GAhXBGnCQJWAcatO1dd3/r4bMWiLJ+5vQumujgFJlavUqN+v -PAAsRWncoVUwZGZFVCz+tnIzA5dDk7tVXJcfgkcvATb+XcsPX3x5R7uq8f9AkTE1 -KmRGA9UrvS0gG/GpHw40eUgrv0KY6uFBSJDRCRv0UXVJ7+P/cU3qTDCZ9BteXI1L -udLbfz98x8l16DBehffLM+Cf4HvBuRnzeTpEWLvuSZb71Vht0nJ4oLw1zgeKCFZI -dhioIXrF+F8gL6W5FNmAAd2sgi9gfPr5A56dbLFYILyoY4q25txX6W9UQ0fXqjxv -CDpaOGrc4N5TZrI0qbMz6xWfE66F1eavBl0/Z5IFFQ5EXKUidn9Rbch3cKGGs4YT -dPcz7vHks0ZmOWnl0e3gzDP/WedQyVNDOhGmB704FZ/wrz9M1gWqKOtPPLscys6n -MAL+pKXbiST86JsAEQEAAbQzdGFsbGlzb24gKGFwYWNoZV9kaXN0cm9fa2V5cykg -PHRhbGxpc29uQGFwYWNoZS5vcmc+iQG5BBMBAgAjBQJR9q0NAhsPBwsJCAcDAgEG -FQgCCQoLBBYCAwECHgECF4AACgkQfLHiapft3mZwTAv/U0B6bjC/LwTcDo2UWkgJ -nC1H9AZvEhe/JElqE1gN53N6VZedPu93YZAWDwaoU4HQrfPCghpKLGxJsjoz85ON -8D2fmbzjgSjfpTBp8rxYi941A7TxvI+ogrLWJ5W7ZDi8v7e1xOeQiewblr2ELaZg -bxDFA8snbau3RdCixWgFBpPgYcttgOhAcaDSyIsG0U5rquAae0/IqJxZrV13WK84 -yqtNaMMN8F3Kk/RVYg7aOlzB+LMuWrcaz/sXjDfKyz94eTr5liI/g8FazdiJ4lQK -QdyyMrB5wzP1zujy54Zfhv1Wad/9THX0YvQNd5SvuIHstL4dwI9jQMGifUC09Y0l -jCEo8mdDGZXOqtq97+2mdxcPNFaDjw+T3yCNuvgTqYhEqht9AeVeYDhjI9QJTjcP -ZwsmQlmiAOZwPUv6ML9YghnXsmUFAFalq94DaRvPhCZRwt2ZcC8b36J/37HRu5Pq -v1vqRTcvl7xy7+ZRS9mEiq77/GrxbB8WPx22F5YufHra -=zVcc ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/E1EE085F 2009-11-05 - Key fingerprint = 0186 F8B2 4C5B C02C 94A0 E0E4 86F7 5E83 E1EE 085F -uid Uwe Schindler (CODE SIGNING KEY) -sub 4096R/39B38462 2013-07-22 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.19 (FreeBSD) - -mQINBErzSRABEADXae0zl0Bgh82XTF5ioznJM9uctS2op/+/uilHKcmGsILQ66GI -+cy4MH2tKNULp5wah0mXE8k16EkaKPIunXggFto015L4Y/7vsY24LhmzI6jiweEy -lsq1P5bi7RQyJmmr0JDQ70uD2i3zIHMjqLKgvOMmhXnOnstCEQR0xPauEkkcHyY9 -fSZkpoD+c/i+1NvElX8/pgf3Gx9gs2jSgVJ4eREuvTm3j4ro+D6oYRbdSFHn7+RH -1GF3Dm4pgB9b/QQVgOSOQGrn0OGyn6zGDbc06JyOQ6EdzLQv1bzl0agLO0/wVGwt -r63HSf9C1Fy5PmcLqP3A7e9vMJ6NYCYhfj/kXdg2YyiW9MrkD30aHg97Gpqy3/jI -emSmu0tqVqeFADS4iNXyxnpPO7pNorGmyYvAN8ONHbSyX2zL9RusEIvAbgPWZ2sd -5UpwSg5iw1tBNjpbprPgcRzNgdOnlKYvHcfETvVM3a0g9pf5/2buMCKijrWi6nTk -tJ9F1xXuVKCzY++AyQaZIDnk6m+bOPxUWvcIPdqxrm3IGzUcHAU26bD8nvWAKStD -sIlf/9C/+Wa4wQW6R7Q6NGZBa09K8MRAuesNbannvczSoCKS0npTLfAJX7KjNh0+ -ycagnocbhln1I8RuRmvSMbTD4npX7rdUmDFGyTQvT7WmOUbn99NC5arpfwARAQAB -tDhVd2UgU2NoaW5kbGVyIChDT0RFIFNJR05JTkcgS0VZKSA8dXNjaGluZGxlckBh -cGFjaGUub3JnPohGBBARAgAGBQJK86kyAAoJEDyaQgQMCIW0RmcAnRKLDze5E2VN -4votoLcv0C9vLHf4AKCunu6IrkDzqdKh5ToeR8xK4qcjB4kCHAQQAQIABgUCSvOp -EAAKCRCZKv7uwJ+1RsenD/9nw6J+Y6t2CYbDXFupqtsx6A940HLOAP53KmMM5La8 -x9e8dsF3ABByX5vhPMMJqR6QD6S1ZiADNtQcHxx5AXd19tnW49fDofHvn6Qzeeno -MAJjzUvfsubsbpk2B53jZ8M7mBx6xaVoLoBsap9gw17FdnYYIAr52bk2MGd9lS9Q -yQC5P1v8erNCuOxnC7vcYv6LpbpB8N96eFS9qNa6dn3jjbHxcrzmVmaCQZqsi+H+ -SNekZYCynmlbjRa/c6+yAO9avnYwtFWCLGTgKILNdzeBI/9c1NnSreRqKKVb6dDm -jTELUEp8jXD6CzpaRPfwkNq92pimwujD38720Tu51CMn98ilqI5K8kI/dxF/XKnq -KvrZLjOYEEyTZG8ksQVBziMyawzKl1RPPH1Gxf/rrYo1QCyLvLskJaryPIBzGX2S -TEcF3oOKv5oSBafMnnRMBhOn8EQsW6HYBTzuNzKGCAtyS5jpfl5ISwjXyraCH7f0 -EbjkFuAUYvwEr8vMYnX0zfZKdS4I6ScyfmJM58D2sLCWdB17bgZULpL0zE6dcUCY -bWp8Y0RBjm6pPzFalo3ChvEZkZQtAGA30H92L6ykhVd8Jf9VcVkOcvB1T7V7Jdnz -QQlTm72c25z0hrADDjEZ1C4/c45qjC5sFXYeKR/5czeAne5Uj2598wP8cSorzvmw -gYkCHAQQAQoABgUCSvNYmwAKCRCBeuHdMi1+ypZAD/9O/oQeeSVSXst9rvEStYq/ -oohtlkfS1qhBMmlw6dUHL4szh13IpWNzLVEQr2qphNAzfYhlddKN7acWzhpEGf/z -wi3lX5jmwG+Jxk7BzR+t1Lsm6dEJ7IxMZPMuEFX+29oDb+LGON7nviYY6Uw1/F61 -CBfrzaqqyqwk/TauYMePpiuPc7EhMC3NfxFfvB2TgGQD75MfqBUah/n9C94sZ1+O -ijf5owaGX/0YSN+wkCZ3xd79JSWZLf6jvzudpxOCMc60tDfWrMGvlaax0n+ThhOe -h5NtvLwjHW5STMHklx5nZSaqilXGm5A9AgBNmd6LOJlgXvg2A8XiZ/aWRM04AEgm -mBwsrCWCWsHqtZ9w1PIKOH08P8DfQ3lg+m9VDCIfutGEhlrblLNFLErBTJrI3jjl -srt0umxoDawc2cT+3mc6PnNLCbk4HmKLGIN93aR5sesfMtrIXSf/2T4SwGFolZn3 -8H4zn5dcMb6hYw7jlsHsvJeAirXYe8YFuenT5nMF7XEzp1otnmafZYdFdlu8Lt51 -+IHHNGoK3OwG1ySGLw+LmE1p0EF4Dbvs5xpABx+iKBPW4HDxOFAJZiSS7PkaTxAM -AVv/dFeUVtfwn5GCugT1tI1/+jz034Z1BhGigRr6LdtGuTynDGjwrSdFLxmy1jPK -6DFL/Ojvfp3tsOHgfFiCYokCHAQQAQoABgUCSvNYwAAKCRCKincf/gRZZkbbD/0e -SunGQr7t2o9ZLnRGHPRTTmV1uNKTjni5OsL56QEmeyIzbh0/rPstl47ei1vNPFK9 -SdsSu/Rte+kTdn/DbPI8jOG2gLaFYY767LRCVlL5cV/GGVWI2Wjk48mjvhhP2sqA -sUXqit/xe8MiWiuTm/GQ7x4/hCyLbbDmBmSqe3kvjtvcrprjTOliJnVLy5FcPtO4 -n8d0l8hS3Hrmy9a4BELrDsh9dE7Fh1gykZpycNzp0Gy0UVDoOfcA4yVYerqDxHFj -QkTaGDK/Div6+aMn0//dT5QBwX2YPYE3eI24fsYNd0sLeKGwsE+EH6hyX2XKqh3c -ObwZTq2ADsr2Nb0U2uxfHDYECtL/ztu9BERmFFSGsVGbDnrEcCik3zrbg7MS7QWd -yacdQ/RSp5EPtbbJEiZ/iVteHpPMlEHW5X6shae7hUKUsqKIZ0QMSQKWBRfPk7F5 -WQgGpVAbn1efFo7NJWtr6yC+B90fNgXiV71XAYTLYpX3mhHZoJl0Mkz1EjQvsaXV -TF11S9T5SmIXWKlf/u0qtP30n6uCraOl32K8MxZ9feJSotSzUvAUhiopNH9yb+m7 -PZi/zWS9BJDMEl2oER001VqsUE6WIUqUhStQERnILHauVJd/aMzEPJiQu3/xMvuS -xF8fvS6KLDRFiUUXX3XUKeXrJzzREdk9sGjoVqQlvIkCHAQQAQoABgUCSvRlvwAK -CRCI4nyiDtdjP4V5D/0YfBumC822QRdVRfqGq3YP5Fujep/papNfilAX3Dz3gM6F -VEBDjR4qaUgv+5Ek3mdkmgK/BiTOFm5picYqWATjlRXInOjItSglztDkdG6+N6eq -Se+nj61oZ1CVexiFmnOfOtqMd1YOprUlrWTQdnnlvX0RxhqXazWubPzK2i+VjUst -Nk6Youl8j2fbSjbfEsN0Lyygcta7kUK9PR8TsLcJ9yhueIxsEHbXM74rOaEMlTqf -qGNHdwsi+bSrYDhaRq4WhkhgmBOIDyGtpxUwuhT88vm2G1rPZDUMgLU9w/b+drYg -hmRL0krWq1bQNPQE5RpQamJh7HOpnhtmOLOMnk4lOUl0N65MR1blGqwjn7WcDIxu -UjQoe+5QYQoYC+jJiv2EpZXGz7Qim25qbmQ4fYvw03I2YEXH3SNfLBCAk04CIkG2 -OBAdS+eZVTjaeQh1U0fM/eh59weZyUftslmEgL9MLqg3ha++Na/KH0jE5nEDKkSI -lpiCj0ntNbVmlzgRdb9p3nGlMFWz4in7wnP17+GUWASVM9yXGT+izTFdNIhO70Wy -NN6ZN1ac83V2AegiQPll6Gj0K2aEi/tcVT4eJE4bjDCYQmVZQdfNic0GZMVb6bhE -OuBmDb0NYnBtnDwuzUPnQYD+UAAY6UqrC/M57SJmFHKDcpG0eXknK8spAQObt4kC -HAQQAQoABgUCSvRqAwAKCRCI0z2G2EVkLRZhEACWKu1hOXz3PBbgQLWG1RR0NDhG -o8ACnGAGIXN+NIGRwAm16QDlBEEqP7jYiYQfOD/QEXa1LThRzb88ij4bpvFIRhtL -ERmDJ4/QNmClLJBdPvlmP1lIkQIimX3yktk6XMHmAFr2/132xtC7qd3Ft7OGYWqg -G13/83JgREO2XuLItaYIPhNpvmI+5j8YhJpQ/fdRnsS7VILU0PVftQR+Pix9vnjt -dvAjw/TvubWLf0CtpavId8Z48fev1ar0SALA5lqIcwoyqWytfrFgt8uSbW+tqeKy -coKH/VXaOOl6VlMHPHPAQ1GIfwWkAiGM8dFolt5A9gjSI2f15SucRYg+tw/Mkepm -vT9wqmg2Eb4zXSX+WtYnKTw+j0w8VJO9YJt9yZBPWPxyCeF6dHeHjmS7EbuxxRLE -OcZe/h+Br6YJMyd0V75jKB71R4NUsORgUdYaQaIG+amjm5RNDb1lNcJvmdm+aMd+ -B4G7OZq8k+RZdwOHMl9W+BIC+mVUTRCyISMmn1UWCmvCCkJlzDVOHXDlBY7B7Zq7 -/APzoTPfPUFBuO7VGVeUlAVw3OTepFuFccXcFSi6fca7YHHP3KcHRDSC5jpZ8fTJ -MS0JQUY5I0Gkr6t7UgFfT5JadfMASyJdmmQwURQCdS3acCpbwwBIxHPbW7d1rLRf -KwG2itgmoV9Y+bhXsIkCNwQTAQoAIQUCSvNJEAIbAwULCQgHAwUVCgkICwUWAgMB -AAIeAQIXgAAKCRCG916D4e4IX+kwD/wKF4tKQHOhUEjMt8jQBrUoyXX5eDLDAA9B -CAAvCVRAejV8aLqJHNnHRhY48Zt4pfIVo0j74Tr0kwLl0xR1kgnVUG3a6nZUsK48 -iQg6jNJxMKXq217gKZdM4S3u84DRXiZKj4tAtAviaEVz6AXcg7xfsEoOn4DpArB0 -KzBM0Y/3D2tOSyFflFcPlefn0F+Uxx3SstXVhkBUkKOym6eRnLmgFBXW+d6bYkXw -O5f+dkLHsIB1PRwJVraXQwGCooSyUM5cidXg+QCJLHR9Q2WHReKEKAM8Ujm7976E -pOV+Pr18NYF7TF/UUNE9ZpLkiLoe7lqnwnLBkVQ0YsLNfqMrK6ReFlKvofzC1raK -usFwxKuTXXeI2yMH7/ywsEF3Kwz7SdMZOkmKyM0coRntf8spgof6pf6Hwwv/8RBo -AJofZrXbwgrHyWSVXJiDxNQ+QCLvVRhQOTb+J3lwhzEFdAXeJLHOvbXMlE2g/8JH -HaQzyA3pQkGMJ9I2r5OKcM6VGZH+jDFD2jjiuznbNCDLp99E657yixtJQOTC/VJs -xeLlMwQh53U6yxR0GxdPdfxiQX+ZrwgvXN+95WZWXmOPIrmkMv9Sx0wU6pTjcNF1 -6/rNw5lr1Fr90TGpStiuYio1hfLL7UpiQ7Uu2ehxp8eofGy/72XTFS9XqNp1Bz9u -XVjPr6D+vIkCHAQQAQoABgUCUe3BigAKCRAyN1o534K0v6nKD/wKv6VdlCtBjOP8 -W8h6y/xPEbyln8I1CLOfHSSXm1Gj4ARqi5aQdKBHjEY9JTR6zQ2EZ7dX2j6dHcEs -iXKURfYje7pg6ux21tKvb/oE/J6xskwMtSrYvIQaBdh5zv0m9QG7NSAbhyWXWgSu -jN/nzbGmKZlECkUtxazMKTaHltZm4ButAqR3Cy+XfTSUiynFKi/uqeuT6sf5SF5C -tdCdMKO3TF7TbYdWQDmETz5y5fOaZvWTrbbn6uCeofvT9/Hfr77fKMnvunaHoKfr -l4vka/6phLkuX5nmAFHGRH5jIpSXEk7kYJY6hGm4eWkBo2U8QHOhiygkmKuk0w1B -KChUSlRo2W9AfWbMIbzVZPyeSEsXC+fSM3UjqVeUrdv/uMAYpftL/FxL49w8Bmm8 -eozYkhmfmpTQe2envIipK8BKuiWnkBufjN1+WHcVxPDNGI/OWhyQJJ5+juHEz+UW -TDzHbtQDXGaLEa2ZlJbEIpFID2y+9cv3f4IBIPgZzAGQc3v5RcH5KevemLNWkV4B -1roEguYwNaWJsrX/PSaTdtRdk2iy2ipJKpkzemLuoguULiyoIe9WvRafyNqcs9ll -76XE525oMCz7XKjLEWNHsFerCNulUOz6fyYQSCN6d0OZh+wnd96oLpvKiiyepsQt -4uXoscdHwVD+DvdJufHBPeCo34UZQIkCHwQwAQoACQUCUe3XFgIdAAAKCRAyN1o5 -34K0v7EpEACJvrQdkaRsthUlCTgNHub7jL0G+lmK0vNt/DsaH26B4tpciCkRPmFl -fd/+MSyU4eRESzRKcWnX5LklKfaWjDNvhLXc84yedVJsqtJxKTgOfwU/gHt8+OvM -IHsZu95jY1wCXXDYojZPgg1/3HG4G6qdAhydwLLytiZnqaYgYdvUXH5WTr1EzjZQ -KakQwkhjTDIiz2zvbaWqZj5TWmTO4jHlCEkyO/kfv7Op0jeqmqZyRj1PItami6hH -g1kL2aFsuSqxZL3rn9v/KeAnMu0bcw/25Tji/IWObAWG2mOOYVx1LUIqk+jwep1k -1wlFLXM7S42JWG2sIOvOH7XtOB1k/jmxoP5qFBErdMyHmLAK0Wl3ksYDYo7dqW1d -DDpFtWr/F4v9HFNzDGiOPna0I0vOGhfWXumaLLgMHsdY+Uhr8WxBs0tSYBZQ4YFp -YK/MxCFP63w34BISQOjXWkggFH28vdJ66FSh/m+iVg4gmcgOQggZxgPoQYMGlUkQ -mmFupLKS/h3SLTfx54SOvlS9Hs5zhv6rX+gnklYmWuFyO7b/rx3VUzH6SgXYalNt -ajtMUcp2W5LB5ZS7DONhC5RjREQvdYYEIzYHPzfkmiUB7Zp2QR+VuvAcscvhedX/ -j0P10CmrT71PwZl1yJWRuvHMbzliP/xwIS5o+59Vci/ekZq7pdOG9oheBBMRCAAG -BQJTHd1BAAoJEHZPGRZQ1jTc9YcA/RbKPFmF1rZMEvIOWHeYWLiBB4IfwY13ZmG9 -0vlyIcG1AP9ciUtklPZjy9fGcQ06r+pEai61QCXvSUJBU+4dcopOfokBnAQTAQIA -BgUCUx3dGgAKCRCDZaeFsBQ/ToVEC/sHiBUIqFZREJprBZdHIKqc2WfxAOuD78qZ -OpxFE9/3eEm4ROH5XdRXdkl4P2SRoToCCAPkr9IVZaZhulwpub2yLkzzOnhfi9LZ -p6PSporQP1Nf9+OUq52BqRmLn2/mocaJ1WDrjSj6RbySysv8zAW69aMO2Y4wRCSX -lTI2U9dd8+VDRdWYKtufxdlDmt/ioSIfKNJUZYBZ1CFTMg6BwvrmTG5ZHQLGd3HN -cT4c4OglfGx1AgWyeURgOtgJ7csc4ykO9DVOZ88KkE+ysjfCiNra6RzrLjrABLOI -MRhCVqDZwR8FqcIETaZf/0Sr+sno8kls13iljiZOP3nDmkycu8e9pTweRQ5YV5ps -rf3/9SDeTtPqHGhlb6wdy+lO2HYpZtx39lzd0NLt7+rdLYJNgEmVixnJUcVK8t2l -GU9CMp3STJvWgzmudWSulDOL/eKq0b2LJUPtSmyS9QUIGx8seu3kQ8hqqL61CL3T -vb/LPctXeYgr/7/XUCEd5IaQyBv+uC25Ag0EUe3DZwEQAKOsnsKa0kMxTfm0hE4M -Zj3N7cA6KmE//9c45+uLQ8DEvQ0m0jEriuyUFkjY+RInGGX18YQnuATOaw6ZpVlK -U3YZC8dePDsbRIos0z1RRNzqVm9UMR1QpL1qzJwezyOKxOuoURaPzpoLYC6cux6E -Fdk085FDmT1qpB9CpPyVnK4DcfbKlxIearbnafahrx/5ittD1rkM53JJln/tO7Je -FCoIgHS7SD1vxs7XXM/3LrFzbdZuLtZttJHbjXr++xfc2bKV7ySpkyefi9cgku2x -JhSBVNEy6JU6fPzGQ1Iz0xqiwDk7CHBr3hnI/WKsL1QfKcrqhW6fwKGEmYLO5vWw -6pzngID5egm9gnzQSFCme9Kh4uCqAlFV9V1twC2CvW9th+hx4nmWpKzpNV4SbFD2 -IEwYDFJbrJTaacmiMFjq3OZir1mMI1K85EwY7pmlyZkn+QaFqE3+HKi70CoLroZ0 -1/nlD47BbzRsZeCFDw3C2U2vlwu2/kdH/NBfTrP+h+JSYBtzg8Dm4NfQJEh7bLo8 -r1wgGBTlhUmJAZPTIiZ3r3cne4yVf/VhxadcdtIPfcJn7HLDItf++ZTFQyoLw4Vn -sZJVQrjBUtzs6amJ7KT9Ai2oU5nXhE5Cs5w5cD6p5gql+RQ8pRqEM7TufN1GnV5s -R3cDU9a3yJK+i02wcT7Fvt5LABEBAAGJAh8EGAEKAAkFAlHtw2cCGwwACgkQhvde -g+HuCF8KgQ/7BzKiS+bZ9L8OEl4KJZbO3R600D82QIk0f2MGdEymavX6QpzX3/mX -v2E2xetQUjrA+tYMIXwKO8Z6u8derrouhkZmJSOrMlSxsYgndIkLmeAtKKDUYnuv -X6R5YuzTPxOE1IGMDpt0EsE00/O6i39ZW3FRWCmea4NQ2pwntJi1OVh+jZnFXIN2 -NdZydNqGvOVH0Oc4D7JRtMImpLSIyElccPywUR2/zOyjWLeELtJnch5YF/hH6m6p -nDMyhOpq2KuDg4axLeTBDY0LQ+2dxgIqoJJN/gRv9Tfaxjpkl9et4Jw4L2J+UoZn -jkkwoRvYOtZc8/qxjVEEPe8HMkV9JPZ08DZhcOxeSmrStcJ4hY+MT28yEW4rqa5L -pRj98A4Be7kRMRH1za94cUa4TPR1KaquR087gKI4qtgUAG1gWtG2VVto+tl1naaR -a0sfHTE+9BMBMtuJtFRVsLqEZUBokOKH1Wzi1oYCa3LO4LoZjGW29XbQhowIjBXx -OJIYr3ZP42ZYO2HEHttemIOmRpM3To8QeooPRW5h1wCZhV440DtXnvbqHqKcYwTp -W45jdvBkYoPdQtS+8Vy+q0997zobctz8i5hfXzxg51/IuSU4uNtgr26XapsoLDur -7PoqJGZ6UdBVwyb0qZqs6KLGQkEyJ8358ivjJsjxUR8diK027wWnW/s= -=/Vu1 ------END PGP PUBLIC KEY BLOCK----- - -pub rsa2048/26062CE3 2014-08-17 [expires: 2018-08-21] -uid [ultimate] Andreas Beeker -uid [ultimate] Andreas Beeker (kiwiwings) -sub rsa2048/EE864ED6 2014-08-17 [expires: 2018-08-21] - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 - -mQENBFPwtjQBCADWg7jYCGq+QFGfB8nLLQs/WEw4XJiAY9q65qWX1clNuVgTF9Nn -ABBOy4KiSDR9XWmARZlC2trKfdoFEnNJ6EnFkLhOjzZKiy4jkyxCctKfbV+sMzCm -ODjjNQtn+nYmOu7a8Xg3g3vTnikkuHZqWvK0O0VYouW/p1NHelUejQbOPuUKukD1 -omzskuYgteTZ9Jn8efJMIymg9dGubuvN4HvUdEO0/u6K2MCZjIqNEPeqWIuZXeMb -+4nGv2r0jSQAU94g3hueooqbUf+Mk2+H5O1d/h2Cii9qVvi6gELdVw9H+5Ir9AFc -ynsmvxrPIxraBMPgrXmvPFOTlqlizyFv2O7pABEBAAG0JUFuZHJlYXMgQmVla2Vy -IDxraXdpd2luZ3NAYXBhY2hlLm9yZz6JAUEEEwECACsCGwMGCwkIBwMCBhUIAgkK -CwQWAgMBAh4BAheAAhkBBQJXuYpTBQkHizsfAAoJEKk+HEsmBizjNa0H/AjJPguQ -WIn9AV/jstRN4OPM6eY7VUMG1DYoABRQSVsksPki5jZii0bI9VB3AUFgfXj0y6qk -CwQyKCJwZjcP3JuciJ5brQr/7D12hoTkYSCzCaECIpMoB7HWCpdoFusrgU2PUUwJ -i8xBTC+sLxIn3h5abTU68tnynCYhlA0mJ8zZ8CTvQJyEjidY1UgSohXClG2k/mo7 -z/IyW16x4dlpdkNfiBhL2v/5Ol7Vuz9g1lXvWvMdNQZ2PVK6w5dmCziCkih/qRgK -SUzn65ASEKiCN7afzUkCTdzrI71r3rOkJtlT1NWn2RAv6xT6AuhCPZzH2I3ImuFI -mkUKYhKzRN6AdmCJAT4EEwECACgFAlPxECkCGwMFCQPCZwAGCwkIBwMCBhUIAgkK -CwQWAgMBAh4BAheAAAoJEKk+HEsmBizjvfYIALS1vlaqN/f7/YzpnOwlH2Wo4jpI -jBrG7SqcdVQk3NGsXTXzzq5p7uTTzpEJW8ReZLGeYaTzqh1vH97uAPR6wL3GjHMZ -F2jkC0wSHXxvh9Gyrdx3LA8NSO+BAG9ZfD6OGklsl7tFFEplLpfR1EsAKfbi0bAY -86SfVwTmCQfFStoSTzg8qLr3OcJQtqw85XVfjrFTaPjY36/RcLcXVmAVN6y8E+E7 -019qP30afGkvw+ZbIq8qbxJItObMuhn5xdI0YaMm2yudCfm2aGYSCnkrgNfuWzH6 -WZ8n1fv45TGBUd2R6zPr13eH73AG1WXpapoD45yf/TFavRfnknU6xb7U3ZK0MkFu -ZHJlYXMgQmVla2VyIChraXdpd2luZ3MpIDxhbmRyZWFzLmJlZWtlckBnbXguZGU+ -iQE+BBMBAgAoAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAUCV7mKXAUJB4s7 -HwAKCRCpPhxLJgYs4zheCACgc3m2FH5kmXtYO44BdYYwdV2dyLMCxvVl7GUWqJF8 -wKmDWlUxBwrpzDBQXpmHyb+rqX/kvfEkH2wb9TZwginLecbZbMKubNUWUqGJBHQo -CaV8o6L/iEUJa5NXzY2OJCp32CHsmpefYkU+WgAnmTVe8Se7JEmJeu+2OfStV5m6 -zVK5xzlciYSc29LpA3dsv5hxE6YZ8kJBJaFyv2AvVzaouSR7nPNrdw3/jXaOz+Hb -VpP/CEf5IdvF/o37sv8o7WWcH1AjvMdGQNp6Zr5Te2E35V8PmpqLH4Z8W0/PXij2 -67i565JZc1Kmpqxm59jg1vs2X7rHNn0k+r9BFiCQC1LKiQIcBBABCgAGBQJV5hIJ -AAoJEOGWdUUnufY1qh8P/03uvjuU1V9UZY9t/4J/K0wbU8Re9c/HfgmJrCn+wvDI -OtxpOg3m07ZoIrosYEA2CIm+kLCYuNbzGSz6ZPZlpoq5FvxzO9OAYMO76r3ktxUw -Snbxd9TCkjCCQ8RMxT/JGDBU77nAJPyhCUZF2/SyrXnexloNP9TR/IDQZNOXzlxR -gu+zIrpl/ihfqxozqXYFIlhlP+k3GhiQt6e5yw+bLRiJZPR+NLzS4vfTeYEvWT2d -tQJ8FFyJF2HypiVcFFF0AwskiVRR9xxkdbONeJ0DnOHfRmnStfl14EDXUNDZ34Qn -IgMkw8vydc1GeQQE44BZYlN1d4J/h6eSji5Ftex1nbRuTeesXg5AzAHi/zWn8dRU -KCdKxjjn+t7k1SQEK1+h6Ja+CwBTZpHWpHPEbFzVSTXcoC0qU+QULD9eq1Av4OTi -Bnrf1/qYGZas6K0KYL84ZTH7JAZtgkXrn1sDiOMEMB8Hdqpw57wPaSt/6mbtmkCd -bCTWigBIWSY9FGfSTZdRk/KoIIK+VqxCPkS++RQ5ltwwq7Y6rcEsMFdUwMWc3hCD -Qu9C+djVRZrsSo6nLUGKGjoKYb1xmcqr03VquVVH36XNRmy3TC/8RqSstP/Q4dtx -a0bgqi+iu9vwLVUWtgLSQJr2OxTcU640DlVCJdvqTfS4SUP5Zht1HOkVzh3l3KiM -uQENBFPwtjQBCACln6mHC8Js3T3KJgNydimOCAFhLmS4e0ur03Y1nckB9zB/pMTL -ulDgtZwWSin3Kd40VZDyKi6mqOp5ldz6AsZ2CSx1GfI9iVhfuFqOaiBLqpNpdvf9 -nGL9OVoy1SdwTXgnboiIFtbTG3sVwD4x4qTRbmT22Ln/mIAICR2wxFBkzpbIQ7Mf -R/zEgRh2VlRUUrWUsnYdOh0xfxuYgsnPCjpTY8hvEno3H6kzXKmj2GQJtawMVs5b -Ro/GCM9lBBR/PAhB65ACzLmUUSsxjlmjZw0tCcOufg1RyAF/l6YVw1UOJaqXBfSP -eZkLQBj9p8VNpasX/acIfpEaZLE8QhoO11ajABEBAAGJASUEGAECAA8CGwwFAle5 -inIFCQeLOz4ACgkQqT4cSyYGLOMvsAf+J2EyV9+GNqT8UmEU6OFnw/sdR1oE+vZ9 -fe4mifAfjQ+SKYf+MS0lU3lTuwcQKwFklePoYsvJEO7jNEgjTQ+zKiDSlV5yufSn -Idy8+sCYygPn5fSjGdRaMpCCfs5xrljLUPK5U8+vjeteRJW0o2/wmsYdHRz6A74B -kRq8kYu1M8VgZ6JD1YI/mp0mHTTB+H69/DNo6cA+7W/CibeTrffbJ35+OXGsJxqJ -b/QH/4lqsceNJtJThkHPQeM18R7/4t7Vhb5htOk2eB7coKzdYRKpHMzkm7elm8bI -uwsky9+6hIUMKD5hhc8G7g9lWOLSXCeNRUdqWTOfZaU5KOK70kKUeQ== -=PCbZ ------END PGP PUBLIC KEY BLOCK----- - -pub 4096R/B4812553 2014-02-26 [expires: 2019-02-25] -uid David North -uid David North (Oxford CompSoc) -uid David North (ASF Committer ID) - - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mQINBFMOLVsBEADW2N1bQ6GFDDSbC+IKggdS/lwhaEo5Av4Z5B2es83A43boyJZ1 -bn9xfd5TriHubI6VBgjbuB0peoCZye3PzEz9cfZYXsPiAqZngWk95or0N+vwrGoI -9gJM6aBYjE06fxHZRTAi4ADPLW5sV0bT230/u1xpqg1lcko5eGV5sAjI9HaVdfvR -68gQdNVK6TciOeM2EQcTHlRd8D9D2/XTp9aCFynNaFoKmBTOsc+VlczmIgd+1jzW -qWcaGTkEtZKzAxUfxlWgO0xHjs3H4CGqtWWCqj8W1alkwIVHBeXIwHDoHlbmkXok -65jfeQd9tWzTHGXETU7bBbxksbwRlrJrutgolLW+/v9F1je2aG/BKMwOLjF7dk8+ -gvSKlu4PwoItGN0qraWsqAGDR4/bWLihqPluW+pUL544li702DUeZiVxFEb22yDb -p2oWdFafEFhQz4FxRCam/4bfVt6bGLGE8GEd1jeahgmpkIAcbAoI9UOFAVaoSWFv -AqYphVfONeZz7MMIcNlyHth5VAvQQF7/uBWCsNtlvBtVirR+nis+eEwoNRDwYx3N -OKu1GTFPMMHUauB0ORD2ywsFQkIjDbnQMNhwQoC49bs46vCusBb42qmOpjP0viVs -qGI3Ae78F4KEBpa5AVbYRbbicOPeV/tRrHFWMyXmH312898j29qO57e+awARAQAB -tB5EYXZpZCBOb3J0aCA8ZGF2aWRAZG5vcnRoLm5ldD6JAkAEEwEIACoCGwMFCQlm -AYAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAlMOL4ECGQEACgkQ+bj6w7SBJVML -Mg//To6EADRjfp11ZGu3cARitfx67276xAkt017sxw76LBzHoF60RtPjcRBBRCYk -0P1URdip6nC2M7Ol151YdTUIfKNWDRzAUVgpWrGfUIRPUgClyO2boTijblS3heZS -gCKz9x3WwRn5elR3Qf6u/wZGIuHBjmh9Jwoa/c6G6ikIoLjoUvXBWR53FlLIpHIF -/q6mzwhXdCwohDsfDI7ckSuSv5yMJsYLZRpEKB3zLgWo4CQP6edaewBd0bVb/Uzy -/5aeolwEfwoNSJ2J4+tQ39U1vxPr1NLEALNl4qW4Gn2fSACnWyEjDHrLltDvolU/ -iLXjgb//9ge93vZUfZmH6vPkrt4TzOfar4wLHTgiEX8nKaOwiMU72wgSL1DLJgry -udf0zSIYDldm/Wy4ggywd/mSyp4oWR3pJFI926CyiQrnA4fSxKrE3yI4Pm5kZNBM -5fhDwtPEtp4F/7kLxGK6MCxyeL94x9QnZdp4FHyRcO3XCCMhfAKT3qLiuHpTiNOt -mOu3Ea1DsEVbSOw+gJzqEZN2ruB8z9DsOxNxlLsdW+sSQRSNgErnLlBLlkXpSawB -imhbwfOHKqZ6eoEqz9ufbrJjIkOEDbIbW93hpyG7zdKSkKsXLR9HbOZ7kgMgzPVi -KNAhc7axmvps55Jx7aXP7G+8c9d8iWhuwD9MemqvhRKyzeeJAj0EEwEIACcFAlMO -LVsCGwMFCQlmAYAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ+bj6w7SBJVPR -6A/9Gk3J6BV0IPuybnmxrkKUicPsIoXgRnzU9LF2TIC6mYJBjb3Tllw0kahsTwLa -vfXEEk971zushOUH/z/wLLgrQ8rzJq3RfbvWRMz9BurIJYGWCnkkINr+lURV0Od1 -IzilZlLuCWCh+WS8w4sJuoziF71Ick3Pf0DCpPIte6PMqBWerrbmXlRfYZgP+vrH -JZ6ZHUEkOVawuY91QRW5HKsM/8RDwgLP7zvXtt7BaVey0XW9pRVQM0fzYzW9wufc -B9DMQeampdXv2R3iXVDQRo86zCRo+7UrqEpBGNXBNhWozucw5eidJo28U+76fWng -7rpDrOPSOUWcg/IfWDrm+zrPyjX/9sFuyjP2w+/dsxmerYk4yXYOQaVHJYaBgAO4 -O11WsjhZZ0bvYgxqJjHs9WGfg7ZfuobzIK2Pl1ZwU0lAcePwuHTBTBFlI6wUxmhG -KM2V8vZUMopxUSw3AE4lWZV756ST8Tc9cVVllBg9eRGHdFN2NKullRzTvLMuUwLc -IGkL6h7VrPmQUhgjyHO4mWgE0or4bm7pHRjP+1D+dxTlr/OZUAiCMgxaBo749Mas -zgvDqcxJOtH/9J3dUeTzN8C1RoKPQPv1znmJ3OgpOKs0cNz1qNIQGQkYasl4awq3 -nPz7QUqcKeZgy/6KIInOPJ8ys2+R54hFhOj/NUBBZID8EX+IRgQQEQIABgUCUw4x -bwAKCRA7Ok8Kx55balZeAJ99U3htpjHcxLxLS9lkGT2+YiBIdgCbBLVVwOBCU7qt -mdHezw/Xp2oxxNKIRgQQEQgABgUCUxNB9AAKCRCgJ0huCLbaUCjLAJ9Iht8ctGWu -SiDFxodDIHmyJ2z8wACbBDGyGhDA5TVJphdJm9Qo1LYKgc2JBBwEEAEKAAYFAlMT -McUACgkQsAucyC163ywE0CAAtVzeWwkCwf5ISyWjXosLnbxohXvmq7uh6bdTVoxW -d1V882pi1UAxU/UZFhb7NSvLaz/hr6+WK0wldl27BF74d6j5rE/3r47KVeOEUuAw -g/J/tLEfzhWtficG13qnLWyf/iTyP6fCIaFRNHL5PK6Br8xZHS0YF9zRHaCutwTm -MHV5KinKktgA6Su7YmGwB3f1lirXxUa+RiGAkvg8tIs8Hn+V2x+FDD22QgW4FDh4 -CFYrzz8NsUiIkYawlIHQdnCkQqiFii7MZOG+EsJ86P0lfYbfJfxEY+4nI737YfXH -SCiWjDTiZG0Hkvrx3qbt0L+Ixydn3oGkrfP+ZngPBj6n7QkALAUFBA34+cylobOD -jb1nKGM32iqPx50GpaS3KH3WmqqXaR2+6SbUUdZvmwac6vQvtRRfEhVtWB9irXUS -wn218Ki2EgprAHwrsvLeMJYoR1U9v1UvSrFj5qtiagJYecxDhsM6ozHmcB2PKdE1 -VkIv2vPRzVsfuWeEFnPOSOODsV1Zu00AfceotvAEZd+VdXNkJ3MfWEy7VT52FnG7 -FntzqDXxGkYZLxK6zn0Qh6udvRz65Q3G0nd+USkAmhEBMTr1/La1LfMAibyUyiyL -0bTRHkjXQc8SpibduFzpcWyrMELVqt1PXgaqtujcjVoHwo00NgJIedBosHVuGBXW -PpUQx2DkTnIUn5Qkncf8SpgCCGFs6Z3qwcqrc6Pb1Sg6XQ6GpMTYMZO0yaLdSSrS -vl6wdiJAzvlP1haafInnNFAo6qgaGNgdiSr1r+SpYycFHORCdqimLax5ggOxh1Y+ -V5uZxDDvOSJQUNKO8bDfREke6gIsNRCj7hRutz9F2K566pu5Tn9UAiv1ZfqYxBub -+mkjkctRw61DlqHepJkY1KQTLBphVM9CAADzWPKGRVZtjeYyLNPBap2GbciBQgzr -/2UCCWAGraxpniCizgkFRPRFaOSp4p0p8DozR3/7xftLPXNgudUbRjxNlRX+uPj4 -0jSEJT1Yrc1/hKgOWvmP13WTbT9/8F2tT+Gd8DTLHa2pXMePOX/dPmF7g7IiEUo9 -Pmci3gFMd0MU1+tgjGZlFs771MZUBnq9rrsX6K5PcikE+UV354mTuF/GdL5Qvwbn -7DQ0Z88FQ4jTatPucEghTLnO9ahB+5ZlE9ri5hWTKRMZNkX0KlCcgcNpPTJ9Ya3e -vWUnuhPHmxq7jD0Fc8VLjiKMWSMMiqTrxdgit41ocZinCH54JKtYb41lsH55rx9q -8crmWdsIKC/Dru7h0MXQW0iU92eMOxiCbXuwNqnzYxWkhjjydhUXmOcufgzfh9Ry -S8zBC/rw5AkhmuMEZK9Ksskt7SvDPqdd0209JrHt+SA8G4kCHAQQAQIABgUCUxDx -+gAKCRC9U3Jvvaau2NoJEACzaTZ8rR1F8+pIy+JdUfQxmZ80CI2CMCjUt+WieiRz -3ZH2sgKqwx4T0c53n8938cwXmwdh5xG17sGWDS8VpXUQ3eq8nHPbc12zJFOWM+Ix -fUIT6zapz18m9x4BjfP78QovU5OyqeE0KtvfwXNvp0OjdoEs70WCaGdmAAcpOd1N -Einz71DOtDcvRdS7A6jqUwfohemu2iPGj7gvUoykb5gg3Nql4K1zQg+Ymo9RH8Bu -MA+ebOvwaRaozi9q1Gjg5erXsN+H9TivoMwRiAHdlfeETuGWTFJl0EhtXMHiUjpz -fA6UsR8LgRMehar8rcsWRY2x8oH6L7Wf2JLc+XnZhAe6wKij5BlbJrJBZc7FcoMJ -KqxGlgLnMDXL5nmHfaIxiJUU6qe9DSRvGyMB1rr9xxeHp3s9DVR8G6Zaub6ufa7k -8lfCKbJBru5UD/FrWPMNztiG8fgRg9krmU41ZgvhT5ksZmH5rcFgK7IOowiN9Bxg -tAclbURX6uNc8CYmWVkR1f+zFS2ChPEebyK+R/VZm0WH3Rz6tacWUtzxr1GryLUU -wTmxGnyXflD9ySAkjEO60NdwUpofeX9qMzza/sJPpxZsGmy3PHByS/AhK7wnPSlH -52o9BTVqwY9b6B+oOnswjccgoNyQmtQu84CnGlUKG0y40ho3F1DCHH/l4jrYaxsY -J4kCHAQQAQIABgUCUxHKygAKCRDABX5xTWlPsl7XEADlAVK6EiOs88azKcH6h/uY -luxi8F97MOEcyjKrfliRxc5Wt2Ry417ngVelhrIzZPoUi4iT8znazQ+GQWBHS1SY -51AEqPN0wrbLpMnhM7cHOZ+Yh8za/G8mIpXCInrsFoDsGTm6jBuwhsmD80HJ8ctq -7DTxrxEfklPuKmQ0ZgbH4wwEmTeU8pzzLlBe9yiDOYVXscG6xffPp6Jml+H2buAb -B7zZKD/yXuNKgs7AonMLrA6d297wslMAZd9lZ67jmLvWLUhd7LGaA2xVNO2+5yNx -gMXrdL0wY6NdUY+yy/48b8izD4Hxc0+7wfnZgeND2tgg3av+hbX0sRbIoP7uZgrl -JKuYuHpgmzQ0Y4eoMklWiWl1o7A8d/vVPuGSOztXUhlQF4nKfEAyn9pFyu4UXjfu -NueBTQl8Hqii/wN2nMk9vZz2xFN2bnsqvIhjnMA2yoQl5bs576yj8Rbji9eK4ZUg -WMAkuOkB675DX5rYrXUnDNo3aBS96NQG4CbG/jaM5i0a+ClVg9tVboGksBJZRzUs -lUQxo8AXS+h74iipJrokigsrq20jO2t/WdxRdxduXu5IOs+hB6ae81JjjHjTFNDu -uteDnnLNG1dBfebw/RkH3cjp+lsvnAks/mINStMoPEH7/Obvzuku32UvAxglkY47 -QSCJfS4QpkD4G/NUvNFhVokCHAQTAQIABgUCUx5jgwAKCRCtltamwB49Z5zGD/9G -Is/hfe5iQrSP9NFNChQjaeafjprCMfi30glYsaXM3y2rrXZJh7zKAvOhYcZwbWK2 -+9meRzuMX2P2iG3WZ7iyaoPALb1WpPlSQef34g3SJRV1UDVKwYpkJSZCsqIX1bhB -sr4qjY7pN46B7GX7RrGl79qDy/CUzLciJ1bX/BiB4L3+ls4qrrfomO3+r10ngqzT -MMmn5hjVWE1BDcuViKYwhW0u/HcTulIVkIp3+Vs6nX54d7nG45YHdmBeLPA5fEFv -Xe3Q3Q0YwK4r/bZwEqlg2GVg5npYIB7SB7MbU1znuHJvyUpTeO0z8lNWjYjKFedb -YmO/tQSoJ82GQt9HMaENKxKP4Tk8Wr3SV3y177nD8+6jFWJQZ8lqsQ/GxZukFWPV -0Eo9dRsQx5v+B5h2213hK4YcOhJaiVtBggUodIKiGz8sW89V2L8EATMb3lAJsvPu -FiQkuQDOhDlbqAj0yQfyBxKmKCHOfAJ2Q3aYBhvFFXho+DBnPjS9r3QfL1z3UYNc -Y8tCT9Um+MX6h/2iAodpxtu4xqHd2PavOxLsOA0IFKIcSNOp731VaMPdptgCOoCk -r7JL7PrH+7QwBPQzCr74rQhiTfuDd1vbmgJGm/D/MuPX5+KemVqOiE+o6xotCb6Y -KqAWu9CqW2m2L8QuD4hNR9NV+StJWmmNaCoOOXZQXIkCHAQTAQIABgUCUx5k3gAK -CRAObqOOk0fwLFbMEACNkB4OlOW32GFzalq6uf2vmG9H99+/pBiKyGKvc50obLwK -x4g8RM/dH6zduHUZ/uJJ08Qvx5h53JVYPOdxk7cXvWVnFJXRQNqgRotOLj9r8Hpa -Rijh4GrTDXeVrNY1rw+Okw7v2iyNwWQDVOkAzrg/fZ5cZRp9e2Ti0cN4COcGJVQJ -lHYfa13GuiSUSdc2OisYiQZWXdT8SnjHLb5cL6GRgmDDhOC/FISiu1L+LFIsyXoZ -9pzFY/43sGTmZJjFnudoxEQHuXmbQZ4Z6o0yAncU2bow0QEQQ/949z4GHNcbXduz -eXBWXO0kA6z4Lu8YLBk9ihrka3kw1Y4VtvIuWQDuLV7DR/k3/YHZzUUvzGH3c8Vn -+DTK5f/dp2TrK63Py+x4/7E62V9uk/VB+TVy0E6vic0Tk3+KMGUHsVWGZiYXYnso -ZpVw7/2vMmiPxai35RMe/yi8r7pAYrQc6su9o/WMS1Hxhp3VPa/g4S/mBfk8jse3 -tHof6ZTYAG7t3FhxVGXgHRYa0nnmHf9bLtNOHrAJ4M07z1VB5wMkFJ491nf05oVr -cyBA3swvliwAilskCfJFFy1yttnOlYY1hLVq7fUAoMfjux9BZglXlmCPp5HlaT2t -rF6VThREOAI8/Es/zrYAgntLuPFLJcYvjqPEChttT8I0H5KlzoSMfHZybsyW04hG -BBMRAgAGBQJTHmQGAAoJECKBkcFWfiwXbtEAoNyetrXS29ORsTlasGUPwumYgHaa -AKCv7Ky87jcPLoQHLp5ugFOyMAXKc4kCHAQTAQIABgUCUx5kQwAKCRAo9QGWxDgC -6wDkEADFhTXNCEedftkHSLl6GxWCGEi1qI418U+cn01hRCtIY0nVjzGYJaxHamtD -2cepVSDDdIeXj9C4mcy3na0/mME7+H/tLuZiOv5d5rFIIK6gODmE/69LrCGSLJL/ -1ULCQMqQ8IcKDEkZTmStEKJZPvE/lPmfjn1XGf5gC8zbTg59hN6op/bRuQpQHsIi -LNn7jEW4X65Ygig/HcRK0Xj6iTEjPc0ITMthLPG5XHUjMeRt+syc65Hl+Q18zwsX -i6bjp/DKLgDUdLvmXdBSxmsDZgZjJtfE5C/C0Yom/VpVesXCWCZqe++GT/K95dSq -pZbu0DSVKtrSTqglRJf3gPeVwQUFixjj/tynZHiO/7cZq0pazRrX2qM2ZZB1hkhZ -VkISzBMUFC8YPkbVDKVYisyUJLdUEKdSB18RcX/ZxLUOsYTo3CsUIwoTH6aL4yQB -C8rB0OkbJeaZbU/3dlHnycAas4ze6hzvEdiYyb2jrg37qbJwg0CPDevsNkLu/Ie/ -6BqqXcLszWS52aNcyLMPTpjvQIC2gV1f450chsiw9yeMUtsgVFXADO6+8zM1io9B -1dtEjRXvaiI3jD/jqV+g8TV1i411NHw5sW9c/Jx0UuXDa7gmb6+6VvavIHCF0pLL -FKUCMmoFePtp0dvdqN1Ysv1RBn7GKl4GGImE0dh5T8pPlXc57IhGBBMRAgAGBQJT -HmRrAAoJEFk2rKVTkFoB0E0Aniydu8kZjiaob6/OT9hYtOkLaQRqAKCD+l2caV7i -J/SkLCBgY2relojE2YkCGwQQAQIABgUCVGuZsAAKCRAXscp9ZAiVKMxYD/iZPK6P -qwHxzEuQjquo8f9f0q1RkX4AZa1j5hvXcqAddUa3HpihHDFnW0UDpptlyonryxUE -imhD9a22/eIsCz4sF8gAgrp9b1gRBJmJMvtRgVHaFn1u02/5IEvRj7JsWgVXzWFU -yh9zLaiQtcpfvfFzmdZKtZ3hl0TGl8NFMLxUsownR2tx0iuc8r+NpzzKpxQeXlYS -98DrDLjE3AKVSZcc8DUBTlwhCZLiXEaQjAKXW+Mxfg8C2E4hQIAsqLWhj8PRQEpG -w9F0Wdrh9w4ePsKKnzsIaprkRve3vzEuDLvmHV+9DQd/sh+C5W1LjL4h+vC0eXhd -42lIWrfgOhai2rrwgfSNEFnMAsB1zdWcwMgVSP97sSVfyrqMlDJWXuW8v2KR36ws -zZnqVPsgQk0Uy53mItUnWblgabSb/udVa+ZI6NeOv1bMGMgKaFqXCn6aHD1X1/E3 -0XtCy2dE6reTAU0zNaRc9ZJOLvxJj8ymP+pUqzkvxLMWAuqpCKsM6YNFlCFkzdfO -LHxhqGp68jKPUfuG7z6yRkgDZF84k55SUK7td8lHmJpbeiL1+N8Sm9CujQ+TEAbA -ZFAQjonwnzXWxzI4N+1TWM8BbhLmFpG814JNxyswYdmps6pdKCWHi8zC60dYZ6Mw -IQZfNWpkeLh7W44NuSJ7pIXuSfEaFCKXX+RwiQIcBBABAgAGBQJV1VPTAAoJEB7i -/Oc/14DWS60P/j/c9/0Fi9O2WsDjCqHge7pAt55/CNiP/ZpVY5VFJKTuWOA90+zM -cLz4By5jUDMz3W/CQFA85Bv6sEwID7ClhahLg4UMM3kn5YyLPIpXjT4i02rsLqFU -tFb40vOlJ1LU1UdpSNVJP3nDNrrg46Ialadycmc1jB5EnoloFC3Qu6QkxcFyxJoR -hDkrU/QJnaWc/6ln8UmLPkVspfXX8PPoy7YcWzS0e6DXc18dBWCigef9tJe1p3B9 -hD1Xyjnd/oSJSkDJFcdD+8A+zdRFqaLNQx1AZJW7UGBNSbaQN9LU+0DSuJVeblU9 -Oo7y9YbemAXLMeemwdkf+EaOmhrtAmfoVMXKyQpE80wQxGIRQC1qYwGgzwwPodsW -yb+v/nfntWEXP+XJFJlcHKYaWClsyd2sGl0WASBTv0VesElYa08lkS3/JEyiDhZx -U2N1Mzngp56P4P7hTGCsKHQ2wKhL1t+ba6pc5wqdNNJEICZmodxgJuVVLq40pjGB -qs+93NZiVTaKIMBZyhrQ6R1e9KoHOSCkh0izCPgsBaiDUno7zU3JTBRI2wB9yQDa -9Hg6flkLWsX9dVn/DPz5ZreplOSjjNc7Q/mGjCW5EdJ+VmfQWSyqBhymINdNYAhU -q/1cZKR6qFd/khYwUvUikXh/xjj9f1653o48R07S6VKy+RLRPjlaI3xYiQQcBBAB -CAAGBQJWDon4AAoJEIqviNbYTkGu1uEf/3scwbutNTY3Q+8vAAEt8z0l4Cbtodbt -m8FjgpYGTod0ZaoUGCylGs9/TGO5bs/yC1w0el8NGlSnr3r2NgYlXXTTyRI4HPtm -vwnYRrC3IEnHWFcyjdgoNwhR83M3n3Pit7OybAlXcm4FrdLZXvjVxrbbzMqjOW+W -yO3cBhVxBhZvIVNeQcSxbZJVJJTj51+NFfTUewkXxZf2Rk0iuGj1I+qcf5x9u0Zd -j8dY4s/BTJ05Nam5RMx6buKUqWa7ob0rmRDoNSs8AWEYQ6bYK4OXa5jba6DnNHwu -CuwwGDeE5bUXqqr41GHk+ACjvFN12uO0O82gIKHTffJYVK6iJC7G5mHSteB9B3rS -6/IRpfRw1w5RX7sDCkhFNWCkHeEurect0YjVBwANuT0nWgGlNEwgrUxRBODe4mwC -c7M+Db9OQGBpeLivGVa+UXBUf84sBGw61zmqKJJ/tdp0XlunEsNr8btcRHKg3t/C -v84XjxG8MDmWdizTVN1qF4NCrISrb4N3rW+CbSfEtLhUAN4r/1a5J5DfVAAEDArt -S17B1zJl9umiQV3nH2r4RImvHzWRnfH0rPTM28XxeE5lDglxD5GHWtNF8iwPboSi -Y0CTIocH7Y4SAJqYm3c/gUGyUBlddsJK17SBzO6CWt2bguSQoNvf9O7Mm+/V0n8F -BKyWgNidyOq7q16RGv7GV4peZxLgIg3e3THLtKgV1FqnaHdLuQ6vudTEzfz0s3tF -GsVwVhUSQLW5k6dDFvE+zdygULUgRlWGeWteITTLiU0jHlRTadPvU63zf5kkl5sQ -/xLpLHAWoHiPpSd/DdlLMNJrKFE2CuXGzttV81+/Cd+jY38czD6yHy5nho6awHCP -NhWKCrRIRVKJ/Z3mhcwRRQ85ro1yzD4G4QBN+lEU0Rm8uqvCX7gywa0i6zMRw1L1 -r4/VMS1PKe5p3kJnJgZ1jMa1jd1Aqg/5WwO9by0SF85pL/2AZs5ldn5XyqsbNxXg -VEh4XDJqecD07gRPtSCoM/uTR8Ns6lMkgstNNHJCnv+BCKN9A0ACwTvLrfGXPW0c -RTDDBz/KDL/BPU/E52Z90hr0qUDgI+CZF429+y+DFcdnxVkth804pgVpP1x/DnGL -bC/teg8HBmGTI1QL3e7j5DrLHvLfm+VV3K5+FDsAN5bf2VoGHsCOsoLWXdnFJAiU -SVVsKRippiiv18Or+taPY4pV9IkwDnktXvllcpZr7LAsCnltK8L3flh8/NVt7eGQ -APFz+Iw6tt+zaN7cH32ntfBZCZGYJTKZYGoYesRYVSf/tDqOW2w98OPtVxyq+h/L -pSldmvWRxS5IELCc+FND6TxGPG0VI5/5sooEimZKu9EVXwhXDnj8TnW0ikRhdmlk -IE5vcnRoIChPeGZvcmQgQ29tcFNvYykgKEkgZG9uJ3QgdXNlIHRoaXMgYWRkcmVz -cyBtdWNoLCBhbmQgaXQgcm91dGVzIHRvIHRoZSBzYW1lIG1haWxib3ggYXMgbXkg -bWFpbiB1c2VyIElELikgPG5vcnRoQG94LmNvbXBzb2MubmV0PokCPQQTAQgAJwUC -Uw4uPgIbAwUJCWYBgAULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRD5uPrDtIEl -UxNfD/4+qee7EHu8GmT+tJ66cSZn6qGzCcCqNrMMt7uAEA9lcph7p8h0G7Rxmk9z -V2qUpRjuzs4BQH96AXqcdkjsix7d+rU8mCHVkpce0m/m0N0gdnsfrwf7V/4nE4EM -MAh2FuvayiCgFGR5jG+oTgfihm3Y22njvhOFThEdSMdohUzy46j1/bG/LSEJQZQc -+z2UzyXb3cvAC3BMwyq6dTPBdBOddxm/7gB98GJHjfy7UUWLNErGJWwVlqcBZ3Nb -gSzldKl5Jliyqh9HreKVi6SNhhFRiOq0A6oKHfiEd1QKnZ50Q0bRqVKMd1535PUf -xa0UBFOKHJvsN3mgw/XADqkjOGEpeX15IxeqmYW89usWIPR2U56z+C5jqybL7PRL -cGV1R76+oXXyGEgekgI0+s9zfnhWDSGCezHegcphwPu4wBL+8ms5R8lX7EVKPJId -p29f1TXQGW/2XXyy7ZsBPuzuCjTh4SV4pcnBo9VphlRVpYWZ31ZhrLQag2DxoqOR -7sWPxy8+GaGfmAeVuPr0EGi3t41wcsQBi+GOI7mQEFhGfSyQQ9G+DFqnB10b71WS -lhaLfghfuQLZzXJpAC4ZAKKjrjWiuJsH08PBTaCa+vkvvRd7GTF9PomHwvdC6vSB -ycooNG6qr0scAB6fXfUOkv4G/aqZi5RvbVzLUlhUEOlufuPYCohGBBARAgAGBQJT -DjFvAAoJEDs6TwrHnltqa2UAoLdEl0H8Kx3D6CdsiaNahUaz4TzJAKCl4wN6tADv -Y/LhKLqqCkMRYWE6EIhGBBARCAAGBQJTE0H0AAoJEKAnSG4IttpQlc4AnjHzmN6G -1BWIlXZaa15G49Cb1orpAJ4sDg2ZYQtajVf5h7J/mJU8feOn7okEHAQQAQoABgUC -UxMxxQAKCRCwC5zILXrfLDzkH/9LUrAoIgoCWmpE/jH/zXlu1mUMwWvW97hWQWhK -IICJBO2t5iUqq3ohryygCkeC9IWYIWjVLSrbbWiEiVbYC3gFUpRVaqTCYTMY/64i -YjwnON9FaR9m6TJfBi0BsNpoqfqcfWY/yAixpXdjmMzuZx9wtlWmJcT/5RW+50aO -LGic3fsGyAdX72Wn8AUgyzSsf5iXS1EWlh8BYIHA/dlU7PI9u03WBUpzctcyE84F -80b7uScXMjVvR6iv8T7S89dnilkSSdG26WWL/3kwTRaTMVu/PR/HwBUBhaQnK2oM -X+AiyOIKrkU0BhYD/sJPTk2n/eDkhtNJx4f5vLAcD8EfU8Z/7Nvx50hGHMqLsZu1 -webSQdKJFOcYSEOrLkVEPLxY4jjcozDWANXYSFLrs2zigxraDXRFmLNMMUiFB6Jr -LEziKtjPPQyZa+vhIwL6NT4fXjQzHMP5V5kJuk9MGAWgwBlXlE7hsboGI8Vnhsoa -Rdoq15ZxHZnrGTIutyatXU5DDq0oOyWpQmciBuvh5DLw+aApn5ZmLuLfRhlTrac7 -PMrwVGAFzFQtsXhAXcv9PbzasEzpgDnyl1sFNBnxFCbmCyXfOG0gLktU8xgcC2ab -11ClmCuutGEljMk4K15Im4iHXW9srRvpMctfePPJuaB561wHMjTWBdICGdzNDAmc -SO/FEDzhuWTXMAVtnIiPmH35cacIsaa6lhfnIqgn4hDK88mfrI7VxzWAxPfSMIrj -JGkZyr2ykMRPEH2T+gK1he7h1vQu+qEiyJViEHOFrnHjhbHA7KycwJVxJZKj1evg -eTJxvGy3C9lWtpP2jHL0AiMknplLye0I0ZSh/F5I92iPLPoH4tdeuA4/GHnIdUfq -8N8VDOANMhJM87go1YG84zDYheFxI0pnOaTxRAE4dMJD8/K7nZJv0wM/x3yc8J9X -FmOI77Y+m4metov7OB4GUg6bWYsxl6VglfIoXtuQTzJ5oG2YJHpuCqlGwgC7D3XD -FNcbT8HeiKJVbdZeL07rXXJwXhi+OUHlugAL23tzFLYxcUUTvlmHxrPUu4SSCr7+ -kkEJ/i/4hfGsLeTHEuY4+C7WI9W4OKC+JZt+10B4tD1uxBJC/SNH7+MZDPJCWXEe -rlqvjMpQGHFGWR7iMcYpQ5LJjOddDAIaUKC8pYtpjZYyOs+6Hm8BZsMpG85GW2j0 -mCv6lwPsfwezXfzR4TR6UFxi2Uc7SYxJfrrJyeOE1EsrMxQdkzD5Q7aaFRXT719C -Z8ZHm7j33r66yK7SQvb3HbTuAE3tEoNnT9dW5TNdoe5LytjR+G5KPYLVYhRwLLyx -O9H21bOewIbnwaw/31/KWu8G0qDe9MuOzIGhkWx8PNWaO9W4iQIcBBABAgAGBQJT -EPH6AAoJEL1Tcm+9pq7Yfw8P/j6DiZUpyUcohyuOMq+YHhjuKo5w14j82fkcHynl -XPX0B6RgNYFslf4rE9jHum62jl80BKXsswAVs23Y9WY0nbAE7cO51rTB4eigiIQq -bxosY1bDYGNBiTBMkqes7sTQjUWRfE4HJlB0AyyEgu2F9FRn6Mna43IeAKBTbxM2 -g9JReCl8Dl7kqdAXcsXRi4UUdKY4WwICYw7nD9VtXBnG+yP/QIxbiasgGMG9xHvM -SEMj9x5+HNdxTQkLqU5q7Jxrs25izbK2paoHzfA1dDTMFkjxf6UHeay0qfWR0Lpq -NF0zhU+fb0eThvGqJFb0iMv6maeboFaJMlXcbeCK+ny2xu0jvuWst8T9FSKcQ7Xp -AkKzShRyBjbWfRoVpajdzxUDtOGsC8g2LAfCJL/kLkV+l8jNQFw4lcxqqZF29Anp -SvGPpH8/3amPh1lFiDiIkWXsEnxV4bZ5wdoT93lUH2vnZJEK0IByR4sNSYPr3EXi -TaRinCp/0WDA/k3oP73NmQvx6qi2sigR+tzh3klrc/n0ajdPDo/vXnIhLJOs36q8 -dIKcfD5yJgQM3px9V6iaL3epTnbTZlggYMWpbNihj0A7uuTYIhiS6XXiN6rk2b7w -RmO2CGD7UAOpLTSiOiot/EgyY0oOhDH4xvY9FSIlhsDozOxfkkIOTv43mBHXNuuq -qDWBiQIcBBABAgAGBQJTEcrKAAoJEMAFfnFNaU+yhjcP/2wNF5GVUYGJnoVCSFFW -O/lW/XqZ6/T2hEeKcrUcMrqB18471Ra+xU2iLupOKWVjt2ynhsCcW+67T8UbnxwP -QsOoniDMU7plGqVS09VPXjlJq1Ri6Fe/XH/6kAruYihWd0y+mVwSM/6YmXZHYb+k -ZUN0lEn4BLwwYto75JHkhNTC8OWWDauvsdOfHC9PiYzMqjMVaUzT1wUxTUtjKyiH -tgmXAwxzISvs9zsP4byvopJAkDY81Vx4IgKIS80534GwFC4S4BDeqcF9DYevobJO -2QYpu73pvwKNX5TZyF8EV72Xa6VWG03Zf5HAtW5gcUGKmD2g6EtnZweNNI9X3r46 -Jp35RimVO59CmG6aMdrUV4fozWWAHtwA3EF0ZtjxkVzTC1tiQIWCxSNIWVhLgBtV -xOt2VC8QrfpaxA4/W5Wz+luwIOAf50q1EA99TNKt7yCyXKP2ga7KqdOwjIKlq9Js -vT1Q88HFARSwB2W84KynwqldPj/gNFwm+8xV4G1gcesTInWgh1Yl3nybhGWzvUK5 -zo4IlBiQsmpaRsW16ACuqhVgRc+NcI/TMGQZuWxkormjmv2bq0MNvOpqZKDQB9CA -OFu9Ya2M9cuPjRUH1wgnye0FjK4UA7riWUrWpZLwGUJKKyZbHsRxWlcive6YI8Yj -9prj9L2GV+sWo4aZnL7X4/WxiQIcBBMBAgAGBQJTHmOFAAoJEK2W1qbAHj1n8o0P -/iRTZ+tlSSXYZcX8M7nCPzCT72czzOSGoLoEw7yq4m+I1bQGGXg5jiPBWOJqxjBw -+mkPJlZb1YACmsQIIju3z2Zu9EL8HooiX2fnDqMKCD+MAhNn5hqMEyZnF0P6bwFz -jucOneJC5uxYzOW8D4454lZzQWeVy/j07OlpTeAAPnZ69lPKumNEnbOSCAvElWak -5BWaod2D8YaJwkdWRKhh8PI7UgCgBCTM3U5lEHH3zXFriEIsgXwM64ELpF75KB6V -Vw4Nh7Z0xCcNC6GB96gNM7pFp/ZQN19hxXW1sRnA7n5RXWw9tGF/K7Y9ilNhahx4 -M+7xLEpNEVtIalfxnHbQ8yQuw9ivz6JjhVyIs4nbwIrCihTqsab8s0ZO0pHKZ3uh -qUeIzgMn/+9URxnc/lfrrrJNuBnyfxSL3koREZKZJBuv9VuxOK9Rp4vTQ6fYjEvz -uP7fWCMAL/zMb+K3/l/wxGjPIOXZHaTTnA9m2Dy/jxC5qspstHh/Mjl+VX0mqZzK -fpMdJeZQl+19j5wYcyT9LEK3OkvjD+/tPuecrMPs+5Y9V3soYnQDvTXbcDmZvDUq -9pB8Qmi3BbxibV8FoW/bUD6LPsquYaRarwjzIWmIi6+NMXnp4kunoAzpd74rubG8 -ImefzTodPWp7yIVGvJsZ5oaguPUri9smfEWhTXC6bkmYiQIcBBMBAgAGBQJTHmTf -AAoJEA5uo46TR/As0JMP/2K8PauF88ChDkpKRpd0A8e6DWN1iRkJTIrxcmXuEzXI -UrBEMSOlhk5vkgBKjYO5K8HmjKzWV9ZpiYzQuBIvY42G+l2ysrbXL3R0fmj4MzzW -GFVLEpDK9c6aDbgbxcmtyj7LTfWIMd2yM18kfkf85YhNOoq4MqZ5xCzdnjzNMP1W -vdKSZWVa3Km2VzX0nOEzkUtggfdnOjWqYPIW0xbuH4fVGSSBYf4QhC7Sgt48Q5OQ -o1xmbx7X6qdyBOZx0fQtCv2WidZ1HW1vR0HTQ5RrmmbMVpWqYAdgj8aZQ7IQga6I -ABvg3klhMrERkDHEQuRpNtWEabOHz2aq3224UjCMPNj2+CHnQQz7tdA+qTp3CbZG -5/FTdv+54RQ1DJaKPc+gkIFlgTuoKwsvybGT4osxKayaCUkHvtMmbVcTsLjcIGlN -cy/sxWeMiJtWnopV+wQy0vsD+YYhJkdbG4SAbxXgLAz15dTeOdV2DrJe9i7Uk3/v -6p5s1EPlIb1rvWddBThsSw21iwL4VwXYGELgmVYwTfY7uRG54GsbbQ7tSVsKKk89 -0DAQBBbioc+U7s9CJzcCpSa+nmi/IDHMzBeSQxgM12jnx6H5KuyLS44Uxc/jxsFA -twb9vX88EpdpU2UERk/LHOjySnsOHf6BUew0nTwdxJJ/n8TEmDXXXBOpUj2BESN7 -iEYEExECAAYFAlMeZAgACgkQIoGRwVZ+LBfDXwCcCE1Pw66YHItX96ADCWi+7jHo -H14AoMNRBrelaNwfVEMFCBjnqexGY/d8iQIcBBMBAgAGBQJTHmREAAoJECj1AZbE -OALrr1gP+wb8XGlTavHxqOENZGi7tLpWRw5z0uqg2OaCSWoIN1XNilvQzJN5hAHq -2SSsKsfRKJU8CJXTnzZTUBLmK6OjEESh6pQshA4I6O0OxQWlRKJYEo3vlvhIhAZ1 -SNlFKVbZakSLOc4h7D3MWhYWdSC7Y5rqYIcRfxEmvmGernjXGbBJqGfCgsLs7ZnN -mO2yehLQYLcjY9hbdFlLlVvaqEYy6vbd4YzJyrG53o8BUv2wet21oWmRd3FFNNzF -2Jwcxhxrvzdleb4iTKBBN8DznR7O3YR4XwNxhP+vdDR6pMHGBMRok5TIOh4MBtpl -S1LDR0QBw4TnPB8/bbZZh1dNp4YmPofJnLJbf8Euf1Knx3OxzQzEjONJNaKEToPc -qT0Vcr4BkSXic/NqHkaggDtBLIQhCxBY6OFxTpDjLLUAKez7aeVk/YhaxuiUgyB8 -9cKkZPRJbSUXtsYi9HJmd12e8igo+Lm6+2j3Cirpr7oIPqsXuR2DyPbqaPFVzKxf -RP4CNvYNYIQCNgVEG/AjTgctlPijClVAsswTR/wYg64jp9iAZHidctv2huu+NTZZ -7f/pKGq+YPI1If/EnTmoiwZ6a6GKwCTtFGtk8ymEHA/0GHG82WOPO6QhZ3pySQRB -7rUOLGPJgVxwPtvgLjNOFF9uq3Avr1+ZQ9v/DOzht+o/BTZVq/rJiEYEExECAAYF -AlMeZGwACgkQWTaspVOQWgF41QCdFHvQARQXT30+2UboMa2BmersAksAoLx085Xb -vOExlzwn4qqB2jsf4cTNiQIcBBABAgAGBQJUa5mwAAoJEBexyn1kCJUoCS0P/iEN -xgmgMxAxurVoClx+XcYMOiFJ2qmq4CKAY1dnUOONVwh7T2acRH7bR9k4JgzB6bNx -zOqMyPs4H3rVsrJkbhkNpDre8E9YhrhnWXy7SeZCnVsDGXkFgacV6C4AiByfltAY -3wQbeC4QQ6rPci0Mb5E5fpVSK1GMlBwBz8xVi+TcXt+WdG31aUA6WwExb/EAVpdq -aUAEAfb4g9h8J5l9YSWl0OXjTG4f8wHljOxoGpE57NqQOH1HXvZKd5sWCJt6oEa0 -jBpnUq+e8ptY+4Jlln8O7JMySCEAqCntTbya1HbFnS0yxPmyNeBlMwOhydHfOSAx -4PDw0AKlgPdDkYRLlnZMiZdfM1uJGWaRxlTBIQSFoPawbafmjbw4eJ2dSr0utGN9 -PuofXLgKFtO+kXzddTns63KpcQNq/xE5EDiAw4qjIt5B/k8RzhCGlI5s4phP5pxo -mWlzwjsEqCPL+a6o7+ZaR0pEyQ3CaUAQ+kjXrWATYttF93hSq1qKRVR1DMW4SO3S -w5+rbrvqT8Obm5szHVc+4X51L17qTA9R8uz1tysjJkeuEdbHSdbsSaD8ZWy4xvNp -ZhLEFazk9+gyRH9+X9uDgg3OgYqJaXdbpMBB2BjCXPOU5LLjsRNeOyTR5EAjNvA3 -wThKP4UdSpYEBWr21TUY7JxZo/73ma7FnJBJNYoJiQIcBBABAgAGBQJV1VPTAAoJ -EB7i/Oc/14DWHpoP/1YA1rfaNWSDN8E3sc7oPSwhA2cd3dwgot7by3igrU06JS6N -ejpwVQ4KJxHYbzK9qZ49paJsj+fKt09Vc+Zzf5anHi3my32W/8i2fI5qdcTaFk8r -nmvaBBHMDmxfvOm8cb2qAH84sAGSuku4GbbQ0x5ye0dSjL7odViOunAk5kD9d2rg -ZuEYYDQB5JypWpCRf7CQ8sT4cooed7kN7WlI42U7rKXmUkunNuvuPZVy6Q+W1ZiT -xWGI9y2m0hpJKhANxukoqEcZuXWFGx6uDKjpc51YDAe4hMORFP92sWslL9+YMkor -RYxJLa8NZ03f/Arlzi0zinUJBbmr1PFgJLWnqIOBnhTBpvLr0mHurQnUzmCl8LdH -cGVDGQrT8fUr4WqMhQ+55RxiCFJ6cp7A726l8TDD4V7PzfwVx27lTxShJe6jd5Vm -vpxGQVoyXESox1kZRXU1WKnARHbs0dGA3Y5WcvkfiMgL93+gUfyiX7J7eafr/fFv -NpXyVbnG53zR+lnH+6MPX9Br9Mhw/PjTAQZxwdlHuie8m/DB7Eec6CKdpWDuMTNw -a/7z3kMGc0Sj2HAyKLkjrswB0N92OMgiJyNFmZtWUZdkefGQGkbY3XWoaIVYuG67 -I8apAUi+HZMLx8OgrGA2JkslalTVY/ZKEaIh6SVeib4BbxHoxvFENdDzHxUStDJE -YXZpZCBOb3J0aCAoQVNGIENvbW1pdHRlciBJRCkgPGRub3J0aEBhcGFjaGUub3Jn -PokCPQQTAQgAJwUCVW77SQIbAwUJCWYBgAULCQgHAwUVCgkICwUWAgMBAAIeAQIX -gAAKCRD5uPrDtIElU902D/wKqTNBOGlLH9tYR517p6z4Na9XOmk2LDAz/LRfbgRs -5tABEY5zrQGqHQZycY7+gCPwOvlCjO61SYXVmIRFf8FIFN1C98YO1aPgjiN/utu6 -wWiq6UXwQIBaOIXnzEuDrns2lW15XFuZEpO0uAMfsFFNoKzGCqO3/aONZ/cuE71C -qiwNgFnqLXT1pKA19KtDBgdGLSpADnRinS0ukiju51yvcY1llLvUyEFLB+ybA/S0 -QGEjlZwOSBFjQhfVUamBqk7p/BGoHY054EjndqnjJmrhGFzZD6RlLS/ZSqD/jYl8 -pqysrOGQvY9Aj7R3usVq2Cwjrne+Khuj1j/cvTwmr67qy3SG00ujdcfEozC9XoJd -UFYDqfKU4aMufMD+xGSmQrGFInXGS3O0+ufTHt421xdKrq1lNb64eZ2Nd8vICuWq -AhU7Gi0ulE+MjUkBxifCS/TQpa1WrOkwYqbDKg7VA6d4cTnbFuHH/J88Eru5kdde -0xvjgd7cJ9kzQl+HuBnBW77qTlZlO4TKwEFO40vzrDFtIHA1EHIjFUvrgWLpSx29 -vMTtQmYWiHKB6j2bJlGAosRiOdZ6WWxqgSSAnU+zVFzPI48ltV5TQ9A9Zaf6lWqq -OBDETrNpG74l9W4zIdAzdKeajK5l9yIJWsl3gQeH5Ctyrh+vO8UWaQHux3HT/8mn -u4hKBBARAgAKBQJVcC7lAwUBeAAKCRA7Ok8Kx55bahHvAKCToUw7xgzwWERRuQ/S -odkGNYKeIQCcDeeCw5UgRXOZm60QKU/C5j7xGvCJAhwEEAECAAYFAlXVU9MACgkQ -HuL85z/XgNYPcQ/9HBjF1ChWaubKJkS/pfo+I22aPEClEqyG8lJXxQUq1V78VS+i -ZFFztyRH0w4RezwD/5j1/mYw9RjTdw1me8y+NgAIKfKYzAR57V68vjTzAdN4jrl4 -XixWUCsgMyOxKURtaMdDqzpugBsN1RhV2Mo0tEGiQF35vn6dY/qAOkR7+jyGZDv/ -tLX7qg/+5XaRydbvhuR18xO8mmbZizVSUZLQeZ+wi+65uvFRnyJ61lkR3UPl7Ch4 -cFOIZ08Ll1NKhnZ7d0/GUrByouiwGK+N7+QaKZOCU10XIsHOOV8T+1xDzJ/oXGnK -Hr8tKPO2aSvURsG3RM291gQZqMjlp/fYvYg21+CeP4AydSMkYz1SPH5QSrax1Df0 -hJ4MkephCD2dg3IEcyh0aBkvpYYzEvoqHmLje5aAtsI+xponjrlkWG3Af+QbR1DK -j6AbquNSvOeJPRjS5wB/W0rc9e+tVWK0nxdUSmcl/jqnghnIxcKkgK52MZkIBysd -ykhLjsSZs2lJ1fxCNB/i8dOn10rMO+YVbYQa+hARSnpNcwLL4rCHk+JwMJ4+Ol4Z -ssfMiYPyTrPKBIRXoJKVI8s7DxgbnUiKotfQnnAAY/CG7OTEEBfgL3WboIV8oKMm -dKtStYjSf4IEVMPXo6O1mrXnMBWQeZTCNA7ZBG1ehKMHLQQYV05NoEBuYGqJBBwE -EAEIAAYFAlYOifgACgkQiq+I1thOQa7rcCAAsUZ1X2imVX98slb5xJ0ep6+HfzLF -K5zj6nEmoFMBm8LeCW+eQyeyH0rHIt2LDs5Pj1Ne+W8C+fwGgT+PzAy2iCEZgTPO -2UJfpy9nmV93mPn7MLK8c7u+FvqHrE2sGcTvOQNwujGyQ/YPU+fnneYKRbAcUz8k -bX3w6T2SYAAp3OWfRP3c+FUVPOxdsN99xDifdAzYmwrXbYr1GPGai3MQLvGE00UB -xoqCb0fCtAHpiWW3U/c/BvzM8WHRhFseHP9Do3tt5q3O9h5reRNIq7d+OXpkDRZU -GJ9dviZSVeS6+s46VXOr0liZkqWhdFy+ZJsXoIxt+yyHejI1y7KQUu4dJo4NoFyE -vgtRa15wjsOEfFRacCVeaMJ989eFQ+F1kb5LeI6xwm4CShV1SBy2pEoz+EpU7ezj -xi96PAm6kCgoaZMIgIdaWuN1uJmQsmvYK6tlr9M49YqkaFzSHFNVKc9sCw7BBT14 -jEQLKdcHZDCis42+1FnBMIVn6rTp906EkiumrHwC9YIKCUHPW83Rne6NXuT6/wmw -ho3Qiy6ob2wFFBjIlbspsZepDmBWSTX4Ej7OVzcJ5r4PXlus+wbbDob37eCzZ2ms -sASGac6d26/zRMVzMNUDmmMmpIn2qCuzqJBYOc9h5RfKfJ7pP4Erda7NIN0PTat4 -HnXFeluIjDQT9YlTVgzznq9R0el50hW35dVrRRlK+bBTV8YLgzOimDSCk4G7hgCA -XWnAQWRU4CTEoJCo6PwnrVxc6NKQIVuNTeIxPCqFrP0lWvCnW+nE5fTQk1MdpRlm -JPRk0q2QxXRgBv7piJSdDBCtxmGlI8w1hhwg5SGDj2KCGNo9nQt1Ouf43Bwla0VI -Fi13lLHrXjUC0/HJZub73zGi4Esjj6aOAllufbMTPquAH1YR1gbQuHLq+cmbzoKc -Kjitifzo/9e0WZmn7ki4SYZsjFZg7OIyNNx1N/qe/ph38VeEqNvOoM0qsvxjMusK -V+qclVqQxGHx9i3nmuXXBDjj8HkbDfBYAwXr6SbfarEYwmqs/Nv9YxnlPO5xvVFU -Fb5GTbUKhneTfnHHUDppjv6A48vRNt9AT1b3vuB24zqN0khpxVUqPsV1J8yyGMvk -umRUnNd7vPgBVsLaX9Bxwdva66OdP2rhk8YKHWHg4kVvNSFv5+Qc8T5uUXS1MMSr -d4uUT/9TvCQRrD+olffOjQ65NPbgi/GIo1XdqviyztdswaBtN8l7gP4GPBVkBLYm -KFXldmmze14EWRZZQ/gP9a9fvakKoZT4/b/r4NbKtyRcYiuucZMHd/BKTyEiy/mT -LOG5VZbg5WcWG5ZY08ibnQikfXMdQeZuA0+SjvzA3TrLY260wAkCrjZQl7kCDQRT -Di1bARAAw5bYX8BELxBpyjb1OcK9m3OrqzMyBagynF3W986L6LoSJ8UBwcMR3IEh -rYJb9AyH3OlFBqY7zaIg4L3AGZw3iK4GLhkffCXEAB+4QxLB2yY9V9lAKA4NmuWQ -Iav/huAedflUYWLCXNlRQN6Z8jOV4ih3sXMdnbMg/FRBsyY+uJL9zFSvLrfl9nRj -lhGWCr0AnOJ/SE2fHs+dmKbFXHSFUEA4mYNxzj+y3djAq8KoS4qBokMk0TzZYTlr -0qV2A+1B3KSbLFooyd6G31vxK3iVmQFJ3P3QmFKPUY+wM2Xzy6L4G4huAZahsBhV -b2BjaH+U/3kwzVg210EB1zKMZ7hGEDpP4kPl7OeKQjkQg7JvTMf0KJUM7QJlUfu2 -4a0nAFVpFINO1R015HiTrFzMWNYGZGvef16f4kP8utg83lvo/kJ/9ILliFUPqxxo -Ip1AU4E4KUQrFrZ2vl67/smCzIkJrIB1mGwe+mHSsxWdtIrkN6mJECMlGvJeIm8U -4Pg9tEDKhoDblxJFuNhU31Mt0yEKcFk2iXnP8DFPpkfYToKZy+UV9UTpSG9kV+YX -vMdMXG9T95PiR133EllxjUj7L7lvObcu4oh7lb3gOk8npp5vIFfauvk5esreMguO -yT5mh/SfGTdI44pyssGGzR21sDyC/sBghblz2IqOX1fyLcKJKNUAEQEAAYkCJQQY -AQgADwUCUw4tWwIbDAUJCWYBgAAKCRD5uPrDtIElU17gEADGZKidcCE3GiFymVMp -mlm/OrNTT73Y8YiPoPXuskPLXw3UMjrttTVcOMixHk4L8mScrae4kqKaEjKYMlm/ -5vZUsoRkX4tbgfM9Ox0R0czLNbtaywC5AZKceYQtqCRSdcuTXbNtyJ66By03zLYf -15+5Mve2X0BGRH82zgyFWDM/7ZdyU5ZXTh9rwYtb10LQwbNlAm8yTabOz/a9Xv+/ -W97chFmp4sOamSZlI1Ol0He1SYUBEqpJ268ic582o8hxGF5XPZPCGCFGfCTMkegn -0GT6sJOFTpAspm/yjht/pgo8yRjnP6XpL1Bd/fe82rAhQOfmrFrJPyRHPv8ZIKEn -23BdVV+VvlVNM/kVU1Q2MNjEK4cE+UJSKw6WseOT+Nh/yVff4kWJQxk34zvBkhqQ -d7hLJGMwQdZQKcL6I5sw/Qon4OhAkrXQeqFqH0j6IlmTyfZaRiniS3pBLAWL6DhB -otDpvJVsF5gDkk9OKRAmWltWAqsqvQItqh0fLCuWhoDqVb575YyXH1Pa3XezVdA3 -EzdaedFhgyH+cRyC1zDuZlEvqHnl6tI099dxW9ujRv6KKeD8es62MrjFTSXKkaVC -Vdx9BwyvRFo0Ay/gTGAjNCPfyMzM1rD1rnYEwrNkXzTn2xAXhV+shW3Z5lnJFRrz -hAj1He6be0CGjU5FRo60TI4mfw== -=yNIU ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/27B9F635 2015-06-22 -uid Dominik Stadler -sub 4096R/EF9D5EA6 2015-06-22 ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mQINBFWIY8gBEACj8cTCDwLduEQpiO2M1qL+/aMtct7IN9l0BIV9bL1oILyRBdi3 -3DHzP07GWLlr0LaRu/uUQuNVKy5ZIF237qn5BJoQnMQuZ2oQPDbaWdg8XkTJJ8pH -kBQfsV5CmConjBJmV1rPCSbNbwYl+3fstIRybqgIjt9AK1xPxss4BUtbwSRzP4R2 -OblNfJ2WiD2/BLD/cw5GiBIMnH6LYc4tSoEdnZEv07RJUcTXs547wfCGMfOZLjps -TRLpCQsTnpWV0X7Y7P9m62OUPEs6XIYJptY/Kv7LaEm8A5SSdTOfe0/SusIa2AR0 -ASb9zAwmuPLLNWhPiHKvXeWmxOgr//tpftvtRGlYYkXq6VbvLyhcjRSPiv1Rqx+W -byvduNzRgJfSXIwfOIuAo8w/aNebZw6v2JDQYsx+P8KIxWO+MEY3XnzRIKEbK5mW -vxIIhZhzXi+CkAYV3gSvHISDiYmw3/wJBerTO5Fs4cBIqMWfszTXJOYsPhyTF8Kl -gOawyq7+kpyil0xRAZ9c0Zq+dwrny/q8Jw22MtWxt0gP1Q2bYoLdNhLQ4NzMGAvQ -2eo0loXwR88cB1LsBHhBfUYnRbw9MXPMaBH0oHdqb+Zm1XvVJMv2xpBM7jt8LxA0 -rWkAg65tv70jTa5NM2eSda2qRMpVCY5VIvCcoEmGvnnZUA4l81um2Y+MdwARAQAB -tCNEb21pbmlrIFN0YWRsZXIgPGNlbnRpY0BhcGFjaGUub3JnPokCNwQTAQoAIQUC -VYhjyAIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRDhlnVFJ7n2Na4PD/9H -GZuGda4QN1IOFc67RSVoLj1fPgKcEiu6zzarzMGChKsdxoo0ZhmyKaAh5/JZn9nh -YlHDi1zpIjbDLEwEqr6qXjaJz2fw50BGX7yamM7pFvtNglu1KfyDLogYFDIDktaa -nHtRUgsTXDL116YfoiJlucRqv/7sTCQC2bsuDaS8jmq5Q+9tVELrivxvHfDqnb9f -+yH9HoFW6lQAPyVHVfpB0nDvmWx3twXjatrNiU+Xp+sGsfHtxD2YUjyft0diw1H+ -1U03FJGG344dUS5ZY9L/IBvIaZU+ovMSjpXshlZRZURzlN1FJljB1YkQgHEdjWHz -9Ur0boQyyMZb3pYc4hINfLChoQoOlENM05LZE1G+x6aug4EGEWnKQsBfVqu4AwgB -zQkaStHnNrmtIlEWzQtz/CZeiWpC0zXwi4gdiu/Vk+XOZE0YPxjLsFVIpK+m4B/I -9VmlXodgUkOcmU99EkmXbR6G74OPYphtlRXRnZVcLSlTKfQitZH96/XBHoQ+k+e7 -uODYS9Zyfq5bFzbCmXLieOTQZUAKL9xv5CH9x4aOcCNeSr6JIlIo8UA4QvP9QkBz -At4H4F2a80TUZtB54MwydKRInKlCdneZRJgEw2aHNuzuc8CeNxBxQ0sXtPRRjs4+ -bKHc89iggbhQCrJBijlV62jrXlVLqDTaNjOkQn20lrkCDQRViGPIARAAnDyvkbv9 -45FwvG4qU2haI3K5DG4KBUgtnuioaK0aF+GrExkIO/kjR574VTcCyTr8PBbYImOx -YNaxn9QVG9tLlISworLscur79XVcayxkI3OWFzmAkjtlgrGiymTDmIofIXIh6O6H -NkwOCkfYV2KcTO+UAf5O+DOPi+YH+Wr83GlbxRSqM6XMIXSkva3wPFWXaAmwCi1/ -JeUyEMdLWkEUfNPA53+1cq7SQEMSzdwEfazovOd4MUzQBoIDYbRdio/UBvTw/sQM -BpKkjrDqa/Z7am0+TjgmyzJVLtfivgKP8/oluwwNa4OJQNNp4kSqmB64I7YXd9dj -3FjdaVXB6E8BqOxubN9MDBGy59YOkQW6eeYYWH8zRz8BlaynieslPxZjBeEgQOS8 -ow7RRzyALU4BWrD2WBYu8Po9qr26r0NhzwNtSGt8zeB2rK+FMoKIR/EEJUqKgdWR -e/8ase0Uy70NQPqTwcZRDYaDvdvfK5YafIVODwUu1ojHqkRdPuRH5UpNdaCBk3kU -0P8yTb8/qTBee3kLvkxspaMH1kgmUSWwsR7vip7Mra/fTCLZJPhJdpuPxHgd3MtO -CgTNROlubFhHcrhjOkVTWNfoNbi1zaYZI70mzMasA4cqxMCkzhHDt61ChQa0u7Jf -kIcGBZe11QeTMmQkUoK+Z+/RR185fPtbb6EAEQEAAYkCHwQYAQoACQUCVYhjyAIb -DAAKCRDhlnVFJ7n2NV6jD/9qaa+oFiMEZ6QPdk0dc9cwTkVth267i05AxGoIu5IG -nLlxTWfKLudSaOlmlvj/ToOHCGxtqMkiOQ/r2zNOvm5A/SSzoxF5tW33kq9qTXvO -HC7OAGIlEWqUN38iiooOwX94LqTDQnQhJSAQgvLOnETY7L/G2RwWTNBNAVmSZQlo -ZHyB+eidQ2K1xPmqs7jygbI2Evgu+fy0HUkHP/pSR18E9Ed4NAn69F8T/FNBu1tx -Jiiq2L6T4cY34NWJSVTkzNeN1bKihkiw8xli7GsMAx/M13vXHVslmAf+t7Qmf5wU -EGiSxO/v9KrkJ0J70TxJ8aSuw2WpmeFD/Yvxg5RmAyvOksKd4qhPUDc1S4a1mIYw -UnpC3ToqTaFhQrC+C4V7aDD2Z2WSe1sUWEWxebTzpx7jO8Ewk6Wrc8GR/EkLEkxy -wB572tirOBouppxcUK/y2HyRfMMye550Ky8XSXnEf8BBEQCHSE8qRFNewY/ilZse -VpGw5vPPmG9LUEuFjNS+cjSacaT0/42O6V/31LKuKPmXw6rH1jo0QJbXRorX+9nD -LeC3Q0DhbExabeoz+Y20AlxvkVhOL6DlTqKPZA5iyBXBvFB/u5Bm//82FKJHiPjj -sFK2ZjwJ3yfYEsRZQYi45odzWfHA0Ca2NMsdjmRTk/N7AeaknX5KOFIvFqdZndOE -kg== -=rPGm ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/5350373C 2015-11-29 [expires: 2020-11-27] -uid David North -uid David North (ASF) -uid David North (OU CompSoc) -sub 4096R/FA3ADDC2 2015-11-29 [expires: 2020-11-27] -sub 4096R/03DB0978 2015-11-29 [expires: 2020-11-27] -sub 4096R/F8F92E4A 2015-11-29 [expires: 2020-11-27] - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mQINBFZbMhABEADSUrZOMTO1k4M12D0GzbLpvaVpXKGn6ulGt6TirGDCGrtvVZmQ -mxbe97TxGN0AqGJHZMOjvEUiUKaCHUQU1dS/qyIA5F3Oxui4IrEAj8R9gBhBvpVE -2oEHQZVYo6YrJTLJIjnVsb0RTWiL4hDGpHjcXrwBimbBT03+62UJGaxmT/pIDgxZ -i1aamnIJIEV3/2H/8BOxVIIsp5qQT5XL65nve1+5D2P9PJYtEVtVUYFnqOBqIKz2 -T7/1TbyINqMTsqtEpqjBB/RWwiX0jSIsAPcGBMRO/xDfaU9TILwcjNc0tCSpn8xr -Mn0fawkJZPj2hAwAifoX+Ryp50bYlgLiOJQE7iS6dp5RMj0au/qOuZDKLfCDXbpn -Ob0pMFyI8j7pYx8SDUfcXwTgdVK8aAgZPGwhhJQmHkaCCPcx4PxXt+7V/8u8xmoB -1bTpNPw3KiIS4AyP+m0XaZvPnDawxYWO2Ap7YowcAIjNBTvIf1J1jaoUR+RNPI5t -IZlPG+wz7adSubPyF2WTvQJriekBBo+a98e3MpZsqpJfcv3pJQVe8BTTqOOQBKHI -n97MSzBZQ/MznBiaqdm1NKFt/d+fQAE/C/Cqe1WJtgDhPigUoRQxooYIaae6rB99 -pTe+T2NXXGPL7oX47+K6EZ36AhpGMUMXtYCIP3cTneHI6c0BnmKC/mTvfwARAQAB -tB5EYXZpZCBOb3J0aCA8ZGF2aWRAZG5vcnRoLm5ldD6JAkIEEwEIACwCGwMFCQlm -AYAHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAUCVlsyWAIZAQAKCRDn6itTU1A3 -POhtEACA8tbeARBnYsUWH08HMQksEGsiysA7JOk1RlwchcYcKUPnuFA6N3bJxWv8 -LtPkP5jaEil6H59CrkXvzbU3fZAlfqdsOlTKZJl4hDht06bdB8dbGknEh2qKGoO4 -QdblIPuPhyqZwn+pM0CuzP8hhh8BdLqqJHb7aVL9Pv6nH/ZDMd4RlEuVJonQ9UIk -HD44oLx5ivdrwPOE1Y9Bwn44/AqBsDCGY5REkq5OHS5eohY1eGNBBejmf8g4gEHo -FWwnGyBmlnwfGiMdw45WAc+PXezjuanUIuDSCDz4GiTvVwja5QT/eWEmwAReKT2X -Vs3Dp+DBsG1TsSF+5hE/WIxFZs22kfQJBhShPK3+T//8i0IfEORMfnp2PNR3hZ6W -ED33cu9IkuVjsbVRWunuFp1hLRq3GiVeGpYFezqtJ+YdEgy0CQh39QcDi3UAyChI -6z+MMAO0cNAeBQD1bw+kJdccoDD87YI0R+w/dEoybxHQWlBIzwtkuG++Jvdx3miu -BBSv8bXTHg247BQKAbRbb0XxyDp6pxREP9aIgXsbjpWKNU9I/GoefmjTBwdqv22h -zp3lZpxZcJstyplIcRq/IkOj3Qt7Yb1yfztIHfRpYySlhOVMcreay9V+PC50yEHu -lioo3fzAWyNcxt2Vb+DHUEC0axNR8giuTSCzDhqqWG9lHtFMVYhGBBARAgAGBQJW -XZNKAAoJEDs6TwrHnltqQyAAoNE1UYWq3t5c+nucIwE7piAvUZk4AJ0bJaTV7QU0 -k3sd96ihjYn0oPiA07QlRGF2aWQgTm9ydGggKEFTRikgPGRub3J0aEBhcGFjaGUu -b3JnPokCPgQTAQIAKAUCVlsyNwIbAwUJCWYBgAYLCQgHAwIGFQgCCQoLBBYCAwEC -HgECF4AACgkQ5+orU1NQNzx5sRAApoRGzIxnykyf6rgS63ONFweFj4oD2/b/9Qwx -u8/UN9xoeUtfiuNE3n+4XDdDGjrwtKSL5qXF2tCn2wZgk7ptPcwyuJPGeytQrYpK -oqQP5VQjtfXvXyO2T9oKIxAeYFEw8ZXqCGn+hrdFAQJjGW/Eb4QQRv5rWKFAqptS -eA2IE0lkK2ador5U/bo7gPgiJu132af9VCotyo5Eamg+y0S4aNPnDMxADhljnq7U -0TFzQbzhcwmFruJxklF2nl1GbDfE+NVKzxlMBNMRUa8lLoxlWYeGGqPSAIt2ux53 -2nYkD2GL2twH62w84qIZuQ0+nsV+xoEwpXUMOOJHI+sOoD1ZrbEKNvfToS+uBSIv -0d7INXBROfhhXN2fNCK7e7Pkcn8bxuCDSNPzQQVUPnMFobnGYRiP98QErNG7pwyS -JjA8Y92MlFOg0SCr5Iy0GhOwPYKkBlqA4W0WhztS3+OeVmOGl/gXt8PZOV3XH0zG -qIjz9cuAxVaaBKz7/ZrghT2QKj0nu+msjPf1f0TzVdMP8osPKNTiL2JaDQCF/mfA -Q9B7MB9sI0YH46ifOPFFo6PrzaOvXGY8ObEuKpmiQB0BqOsuBhMLFQiH+OcXfcq6 -xwYxw4otXyF1iKhPPlp6YkTy+ICm6MoWSR1XMh+qLU6UuggtK5LK00QZq4kuD37v -Uxe5MR+IRgQQEQIABgUCVl2TSgAKCRA7Ok8Kx55bakvPAKCpbM3av9KV+7OCprWp -mTvMX4JTxgCgiRG4rXVGfcgwJ/1q79I9OA0MS1K0L0RhdmlkIE5vcnRoIChPVSBD -b21wU29jKSA8bm9ydGhAb3guY29tcHNvYy5uZXQ+iQI+BBMBAgAoBQJWWzJNAhsD -BQkJZgGABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDn6itTU1A3PBdRD/sF -QC4xH7qPv2cnPOry/qXSeVUW9iFsXDfKgiLDtryqxVw878E9Q0HLZfDUO97a+s4r -hH3hh6S9N4OVvJcoYX146Z1UQyV6KJBHLNcp0kXkEL/oOB0oEZDVw9StWdmuIx0w -0Ki/y/0jOKJaIfTWQy5T8AFIW32R8tQIdIwUr+N52mv4WiI/CibQ1xKo+oyvB4HM -Q2xNbSklSZOdnU9m81lotl6n9Ce6Phz7JoIE1NBjC8j14lZ41tbG6OYtr5UysOnH -dhGlM5DYDS6mOdXgeIXGxk6CbphYCapAiXOS/bhKmxBknJcoLcsgBhcmpM0FciNo -eyj7Rr+Viy0XGr4PU73IxbHx5auqqjvfHR/w+C5m1T/nS+5YpsMr1DtEy44Pctay -8oriMAgMcFz4PPqjpuYjubPAnpFM73QjzVLhKzHL9xodiUe6ycdV6zdUiWOOt9go -ZFVU5FpdvjrPWL3e4CTk1keOwFHP5w5LJ1PeZrKxdxMZQgoJIcH7pRNk/gAmpdDL -pF5diLp/ooAONOJMhVu0nfO8tErPwQgi6RuPjX23UtuTnAJlNTFTpP5LdTYRR4n+ -zCkb8C6ER2AkCA4VukscPjqEyv4+BmIqh2JZsnXZulTLKgqyxKP3leXxcfU6R8qZ -rTUIl+KG7805t/DPstAjn4QWQNQ74JKWYXtc7dPo/YhGBBARAgAGBQJWXZNKAAoJ -EDs6TwrHnltqn9MAoID72eIkZsu6YLQ8tyydTAa7GfuSAKDUu9QLb07OfvsbPqLM -DFbLxR74/LkCDQRWWzL0ARAA19834eY8CDheNnTu9G5l+CPLDMNV84akh0uxxuis -s7z7cgAeGkqeQnwMExqgam4J3ss1JAGfJZlVh/Aow6OYFIApWvszsieQXiYw9pi5 -/wC0Z+zgiciUMInhcvNTeWBS/xhnuYnVjN5TIyvxz2VJVK8iQiS9GBe/wR1MDqPq -REP61rb+xhdaHBhYr74roVRpNUOPB9I+4/AFUG5XMFs4YjjIb8kgCszTBFri6Hay -Ol2qtvD/ATth0lg229mPLzvZJmg7xkNGhtxiFaLZjbzni9pIMrsUlSAIhj7jyY+7 -RYrJzXwGOPdoo/BUdZETivXXxv5ZQzyJw5nqIJQmWBstGa7i3IonSTmJZSpCE6K5 -EkAHwksFxEvGCDnBdgDkXvCdiVA3guy6jQ+8D8H1R/6EoC7vUWk9wWwx6PLACFql -RSQzegap8iDhQ9o8feXMXkS585tPQN4j1CWWvzCahheaXrifM+9yza2l8nWyIDQx -V02AQYDEb65Twqrk/7LbJQvJ8oq24ScgRL8EFZunyEDvlFpBzGsZTahBhenIpME5 -jSff9OVt4kTuYYke+Q14+Ob/WzlgJtF3e2UyV1Xm+FUGsL5TDS8VgfPYJZeUSnEn -bhhv9bMlFFR+4HB/bWqJ58VVNUUoIc+D6ZuNT56YnJJ6DLXi1Es8qpx50gC1mM4s -1wUAEQEAAYkERAQYAQgADwUCVlsy9AIbAgUJCWYBgAIpCRDn6itTU1A3PMFdIAQZ -AQgABgUCVlsy9AAKCRBSfrgz+jrdwpaBD/9FjGA7RESbwpUAimzfhrRi7hBpUoiz -MCrrDKsjTByP/InXlR1O8127PkZQQaO3j3PL1ww1NWWr+qkct6N91DaooIjLKTR2 -7zcEKEQtv6k632uJSY53GiUi/UFXcVPKj6B+XyNiUytbCkfAyVPrY6H0kK8YNVzG -M9i0AB7RZ3gH2xaEZuOCYHNe7K3HLy023OcXSuiuU+mxYgBMOphq73uvlCL7TwHA -ym7BTagartTMGNFoLpUbYCbbHBHAkXTqF2ppWqfu/StmXN6kmzwOhYwdpcSJNrsv -V8Prf5rKVXJtpvq5t1Ux559NBX+CtrwwyshQbjR/BZhiyUZqvbQbBEorLU1mLvKM -VmT03h+Ha0K8GKDygJr15uwx1X/9wdsZr6do+OD2tM/dQzBJf/TPi28mLZ1HiR1h -LaYM1Ipn9ah6xPGdT8cpL7EM7st0fsDsmO1rU+/Jvfhdee7q/vfdQZkp/9e0YHRY -cygITVCurNGERUibjEtpjyjrztUDkVgDkc73OYOFtrR3ScrbleBSguWkx+wzUxnK -HaLCy+nDv2qVu9A4sSrJrOITDZih8mdl6Xzp3+iX9I1+Qg2pwKG1wKbgtLWFqvZs -IpOzP172I3G79zXV3Ka0jzQQjNnl/+W5AmBt2/Jw4M7V7xxVfXibrQS6tmrEWhcX -P5pMNwhRf1bvB1eQEACWYe3gIyEFT4KBrAhsfQI69X52Ex+CyeKzrUZRPisxrdEr -hnUHgBUm2XHvhS8xODlMj/EnNEg9aH/dXVvzFcSz0D+dGVDNWCN+bia2G7UVWyd/ -XG8DzRrmXvMQLkhfSl2ZL/d85PVL4HlYV0rJrqjquP/VndsRPjG5zTIfU7Gly7V5 -YpA8eUz5u8BQsGLsIMVg/0tzBJfSJU+RTQ2TL5B4sbStBzl9YzsmjQqdhQY1VX9+ -RmDtc/Nrqv7c8T4k1NzHUrb4qS6E9angSXOP3ZcDLsRPvAj1APyxEUV2RtXFngU0 -2ew9M/Ie9fEx5hU6T6HMjTFgcfnpF6NN466Aed/OuU5yaezqWfNr+an/Plg+6xUK -WoSKqq7x6o3Q3hk6fRu9sgPMgtmZYmBXvt93b14Hgzmhha81uKr5cURTYTiXERtX -SfJxarMfkZGyf4E2ABMHiI4zSJHF75rlHJEkNbGXiULXzzDBn6QK5iWiBRpVa6ID -YY2io6mDz0Ajcm2j+bcUMcIuqhqgPIUqNaxrCvOY4YKkqbmMpKMTxF/mOPoevg56 -3quK2yTATv/lbTvO/RFEos4ZQEG+4bsQ8gkzFlp1WUTisANCdYEWe4I3vkCmCCJx -lqhZJ01CVgzszeNTFKZkdYNsWx086pw6O1fCKrnhtoUK45dww/5lSH77qdple7kC -DQRWWzMOARAA51G7/MV+tpBeOMN+q/CRbGvEq105U1VVx0EoAFPi/Supa8PTA9o7 -cE+gdQX3OAkKpWV8d/evDtv7E6zERqEkf0D1KaPVPCJKIU1ffvfnRxe5Za0wPbAT -MMczgwSlLocoY8vEt1OwCp2yECNovRVigwAVdr4jfHQDaR1uAD1tGJgTTqr+vDA5 -xOtaF04LHqbZHV/bcWxBwK2STqtFn6RbZCfTDulcv9JNESr3Adxi426S68+qtPbC -5RUzERyGSaFmo5NelvV1Lbx8bYMs2By1VHed7YXtZbEK2djVNP6S8VlnzW43kkvr -1F5pNcFdOE5AD3YWMHdDdRXN8bDMhwwbKU6eeDzKnHr6hoAMEtiEE+ZP3mpkE6Sn -n3SnhIgrS7rlPZxrWpJ9Q9Eohy2XSdOZD/KImohJ7Afk6ni6MaqxfIZdAFu+f9C/ -8WgTXLT4mtd5sghro++KnH+PDIVDezQ26JJTadYcOzKaTyadoiZCttWnTZLmeYNw -m+RXRUm8hyQa58ZGPwGmdUTJyPJgHUxyjeSU/QG4mAGEXfeQzAAo56la2Hb3Kjg9 -jMjvtMD9XwqtWHJd63ih6VtXaIcyhHXFyA23YDDeodSA/2yT3Kg8tB1zNGU6xOYK -4s7wAo+mNJpCGr2nAIXj+oIFrKIGyM5qykGt23kEumLLqQd9l956ResAEQEAAYkC -JQQYAQgADwUCVlszDgIbDAUJCWYBgAAKCRDn6itTU1A3PK5qEACm21RTMohM+bnD -RyYmKz7g0Pjz+vmFtEW3YC4GoZBNSFyDP9B3WoxV37FGj6sUWkfCEXpby9OivSXA -upYxq4BYWJ7tIEb4wBsEbHaUxh81xyf4/bFu2RBSHofx/vEapvsBPqa3fTcS/mR4 -HPNez7PugSiwO9F9BUezP5G/TmrevOQI2XWSJwK7UoAyHzkqvN5inpjX6YOuiC0w -fZBy6vAcGoV+lQpRHh3cAX4bJ+BoB/hT4ZwGkA6YCaLv5MrhPLU3EqSfn5bnt6Fr -nLNYyCrsocGP6NfIMIxhbszayr+5Wt4xX/+wg0GA8xNy8ULHDoJJFjk+4BPrnvnX -/DJN4XM1o7L44SySOtSqHEHZJccQMXcaBFWHlI1HdI4C0DYASRq2a7hFVJuGFKuk -cGAjq2zKdBlFGQS5ZJkdzUDsAqgrlR/zRWACdPIo/0O+ZBkpI3K3tb35xksPa4Ch -WEaFEHHNp7X2TYIguxCSlQajtw3UggXUNj3NzQP3CkHxCHeuD0/3Ng/yBUhSlLqH -86BTd4NVNsMuc7+Od/o6Etatf+08fcKrWySLbJ6gyIxIRRiBlIMhYG5EhEs9izot -xmXPEC99X5upAYcl8wepXmAT6uS//HEeq1gLWhJ84t1m72XCgzsH8izR9EYsPuTB -XXtguDEwNLGck2RdUfmzGUpNOddyLLkCDQRWWzMoARAAthdLiAzdoDfFjS3PpbQu -aJYsPt2Lv8UyCPBx2QVl0I6ynY5U4RDnygRKtvOGupkqKwR8W3fzreFKPsJNlZ7c -Z1dKLImKXzw+DPvr+L7kKnW/F5i8hFtHgdMvqNRvty0COGtuvnU/oJ2mHi0hukvm -Y7jEZbx5M/t5dY2THtg88fn0+VppvL+LKzdNSpmiBX7EyrjIpBrS3MDts2ikhMF8 -ME2yDk1JVRdvWAMHW6Rgn4uhymrF7wbR3Gtgw3INqp1f2pBBNE2L4PbQchgqHEl7 -ikypcahU6ehsMmuGR2ueLoNF44j6qWJfCnSP5asaJ6sZJRpI2HYS0mtg60SsT52P -0iut++OOxi85sJtTwvGNFlU8/oLDRMTriHSreHV0ufw0qifO3McHQjSZ9Wx1ka+l -d+ewnPFvPpxxjXIpMxw9OGOL++pyztf3G7or85ewzogR47rtFZJ5g73AHKnMHcL1 -X12LXOVvpPfLuEFDJ7q4aLwvxehiTzHGq1ARYRQHrOJnyUE2KYerD/Aqa2imX/gE -dEgw01uZkhgP9H4DaM2h0RLCWJ4LaFamce9cdWZsYibeJwr+alRP29Q3klwx9CIw -FawUftThv3j59ZJQi0bnkIN9/NDXBkwxQGvbyWv0x6yLmtIzRNXdCHzNUnTbCh5V -Vyt9C6owqCf464+L69vOJYMAEQEAAYkCJQQYAQgADwUCVlszKAIbIAUJCWYBgAAK -CRDn6itTU1A3PJEEEAC5bvKxKzkw85IDvMGDKVviQ0V+JGriEouslFB1A1voVS+D -ulhXdpvmVGSKWB7B38fO2lcyImnqV+TDEA4pa2MX2hYRN6SeFtSs2aS51Iziqhve -3uCs96t2zAr/pKl72yTcK/qA8Zz6Why17pksDWMlwkWncFGWQNPp9Zn0Vz6DF2RS -JawZtdccHy0VfA2yx2XtvIoQMIGYT8LHu+uUFzbI3kWofUwSxNUeAaAuCWgYXJrT -D3WpZ7xcGN8MH3laxq8UQlYuBGtqmZwc4eSddY2bayP2+cT+5pihekvhPO9hrQfP -Db/Xg4A+gRsek1gkCjWGT8peoPm5TWahdEMLEYAyWirfFa2fFHkq199sTjOWAolI -D0vVW7l2M0I6dFiZwoYyQL0feUcvFKEe3i1k/684hhYQcWWaVnW+GbwsWIQ7Nrb+ -uoJ8D7JTt7K2VM8y3LFiSzWCl5aFMFQKc+H1youb47GnzlU9R9OjKVt7g7japSB4 -UmbnPdwhYsr8QYOq2KxKo/Wl1A2k+pL85qdJdnS+lXzl7nS3MlDNLRzk/1Hg+IKo -cCRRHYCeAZDU5UMxi0nonfT+060i2rLPSd7o0bstG7gb1pD99rKxL57M7uy+WBnk -YobtRLhWHvHyWS4dKqiteeTwAqG2ZFOq98KCu1LXMKj42HqwOtB3L23HlhqVyA== -=8e4G ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/8BABDD6C 2015-10-10 [expires: 2017-10-09] -uid Javen O'Neal -uid Javen O'Neal -sub 4096R/309424B4 2015-10-10 [expires: 2017-10-09] - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.22 (GNU/Linux) - -mQINBFYZkgYBEAC28IT8XHE4bm5iXgL7COy7hmh8FS67hwfnEV08rm3f8tflYxe+ -tYdRUI8y5UIFJyX2138GsV7sjV+pBiEq02xEU5pl2/AfXF+GmtW7ErS2Tk4iQ0id -SEcnyvim5LtaFYyMjYC1mzr0MaiJqWHjw6Lxjjep3s40coAkauRIcnJQ0s1YQIqk -BPlAl0rDILE8Lix+IVokUxTizh9popwDW0T/z6gzdKDeE5FPeKYWPvs34bKwe2vm -KqL2qmBh3Tk7MbtKYD79pGzYkNSyVmfWIDTjc++lNmDWYt0QN6YlaXoV4ZCAbLk+ -raHU+5aKduZNnP25FnwTyt/Xm4Pl8RdROBzsmese2UuYrfsPaZrZkhhekE7Ttjk1 -EqTob/LmgR7KSwWGT6Y9PAyROIs50yw5T7wMjdz0+C9SUZHK5lhPnFawyamWM1de -Y/f5vEvbI2Xap614bg6EPObPSQh/1r6J+7EmrbSqRE0W8FlSK2cWmB8l724lBG9f -Y5bma/F5g8eL4xcOGkaw2VCBu3i/IRUoHBP1ndkAQfIHmlGlWFc9u6PtmFyZHJJ7 -Boks8g8M9aOcUvO+K/+gBWzGXO8n/NG10iItX9ubSFbvXCKJgK7cFXDdC8F/uHXO -vfDSTrwBffm7Czyxx8AgDHxGMysNCe5Pet7bU6bZL4ANnCPfMhgN7pp5bQARAQAB -tCBKYXZlbiBPJ05lYWwgPG9uZWFsakBhcGFjaGUub3JnPokCPwQTAQIAKQUCV+cS -OwIbAwUJA8GMagcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEOZnesaLq91s -DN4P/36DX8zeM8PK9x9lb3DogipXefiMyWOZb+p64Ah6iFIxDoTNP+meG3eiQP11 -T02TeI8tZKG6kuFM6fQb3GE6g/2TgHeWnrhek2KfHbOh6/nWvrAnsaEiu+vIBIFL -kiO0ydtu1DdNjWB0PR3bcnxF1GOX38cx37SjMR3n/eaIFnHqENzHNZgZ0sv38pYt -c0FDeoqpO89aAiCi+IWuLAhYFzU+GFdHxteFMtYGYDe5iI4EHjciIO4/Mq9MyQce -rYS/ADCJV0SWS+mPk3czKRdpklZiRoOqSiZcyTUJ7H2NFcdQuYjpLlmNvt0c95bR -fxaOhFWSSvZzkcZXr4u82VDc0rSvXW1q2vFZpbYJq7uDQZpBlkLBwlZ9gDaXHa6Y -5JB7RGWMmA+mfwSmfKxfCR0HdTldNsSic20bUlJjVjKkZR+Mco5SmAW0nb1OkpD7 -lDCx6x8aunuFbf2SGnIZxtGxm31rXE7bTib4wE5X9EECLfg9hTJxPdDqvKfRBVBQ -ZVtPdq3jzyh6CxM/bygfmUjqdP91hS+wfXYq1W7d4e8EphkCiqdMXgclFEbdGp8e -+8BDvbCIchLzZ5wOxL4Ntwo4bL2Zn0IJ/K6K1WoOnMzq+6xWZOGRJ28v8go2VqO/ -o0zWgSm6zEz2kAE9s9Y1by0xL40byg0AdJzG4h1cRPOsYeB0tCNKYXZlbiBPJ05l -YWwgPGphdmVub25lYWxAZ21haWwuY29tPokCQQQTAQIAKwIbAwUJA8GMagYLCQgH -AwIGFQgCCQoLBBYCAwECHgECF4AFAlfnEmUCGQEACgkQ5md6xour3WzZxBAAjLkr -z4Roxig47WGax6ppGqIGLTNEPPvNluIgtwZYfTW6MrzQIquju4o0QEIb8mOW9uke -LnR284t/5CU36EuVan0wWYwrwIJWtbZGz14GgtHsRyErllmYWKa0aYJ3kgY8JuNT -bK40g9RlrdLsYntwFlWQB9rL4nBPoWVWRllWOMcbhdF6/p9r2EmKO/CsTYdfolEh -dKdEtSgshQgvZxfgalanqb69/zc81RLpUQ0q1uiedrN0ghNd1+XCXeopKeeAoW9Y -LOIlQ3ALz9t+A3w4Ft5h3RZBHPwSPAgRv4fDv3y016rnPSna6wC5atlW9b1jxcnS -myP3kNcAXJDWwpQmMwYG8NJGCANwYRUNGcXlMvYbMpmuYHqc7kf+AbkG3H8Z1ktJ -jfwK8aw2ZX/AlINIQZ7fVJLDOkMapbjApUNOc7UoXx9Z8qXiVDizisRCJxy2Kj9h -pR+XMIwgPwCTgmQ+W+hQ50h7S4H9VVSfEe+H/+k6kHhRxEAZq5NGIzC7Mh8xvyHa -EII5tAS8fQwfnJ75URITUp2Vrdry5aDEZ90AIlYiQVuhUwFeNimjKOr8i9Zse7JC -MucIcmBsvwThVn22e6x14cNfc4KwqcWSQvxMuzqejHq4WTMf9Ln15G7nVMulyUTZ -hfJ4Spr45BEr+4UDMNqwIRQdIMXHa+JZGs3Nj7SJAhwEEwEKAAYFAlYaCkgACgkQ -ykkN1QqzdQMHbBAAm6Y0PaDBlhiYd+nCaxpNJGG0h2F/2nPLXNaGdTQSICD8B97i -J1Hvio0mEHnkbbm6e2s0rvxervgy4BuxgwzWgguaLQsALgyGpY2pHzsQAVQVVq6H -PQdwSOy731oO7R7CeJB/UIT02ne5WnLxxUN1e4qYLHp0+QFXOd4TPuTwPEG/Gewr -EVJN4C2k373eSsWwvXCBYe5UDLqPHrVTYnyU8uFmi4yOMbmIyyb1x7At6adc8FWQ -DQQt/0YElDe3m4Xmco4OMBem8i7QFchinhLIZPwNCR4aGrhbQYuq7C8JOWjEGFg8 -k322fOwAEopr3+dHemToGde5j2u7JnatAeu7CwNVMY4Z9s/wUChP7gXlNenKIgeD -hUsG9RroqpXTLKmjz+2fSCGT5o2rBgwRnwpTcDaFWZlVzb1r/KQxTRsEkvDfSU1Y -jixoqFJYBj/2fhl1EPF7gb5WK8tBZ8PqhPaJwXAynzSGEG6QLbYwxCoKfVvl8PZj -SGg4Dmca6QpUskYwuiMMZhJJDNxKn5t2NZFEilZVaITRtNxtyRm2xvbcPXsSjAdo -VXCqKX777rfPryPW4Yjw55a7uaQQe3M6d4ndgVP491tGBMfBTHa7hKei/R1S106C -2R+rrE3o42WnhM3AarlWRqaHzuJQuofAjtRv19Ibk6ahK/qFuZBBFAWnUiSJARwE -EAECAAYFAldOVSMACgkQ28vfLzZwP7I7OQgAnDlCoagIdBNHxGAPieZt5bJTj8Mv -DtoxOAJtUjbJPTu5iw23pi2b83xmYCNQQkJ86IiSX56kILr9SP1uscChjM8aqwBK -H5vMWAzHxdbTNFrjmCm/NAF+6ArFi5snlWf3phLPUIdhNhGA4jhklWMuy6rflujy -BCgtZSh0VbaU/02ir3/QXBc331VN+qbXoCxD8lFagj0rg4GLCWFFCPJUeAr/SmIp -v28UIVNDUI9lyCB4G3utjBhDpo0LHv+X+AXkD5V9kwZBE5NzahL/3AWjm9B9Vqb1 -JO1PVYv7sXqG25+xRMJssnsoGQYH75LSwoau3Yo1l8J35LOLYPUQfO9NYokCPgQT -AQIAKAUCVhmSBgIbAwUJA8GMagYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ -5md6xour3WxiVxAAkN6x14p905j7NUB0Ky/p3da9KeIp5uAyTR/CcE9pLvvdSMyd -xH8nE35EyHT84l7/yQHQ0wXxAFilBSGBt3C6Sth8J+11zxesUeDmJ1dX2Z0xRFz+ -qO7MBJ2ccU9pK20niPgaKuBBZsDoye9wKtli2UxOCid26CeLs5Y1gAcPuY9Hmzh3 -FnGhzrI5dP0HcE9lQXKA04vqviT1hxd+LlleCij1ItQR0ZYhV7z4SZp66vEfnh/R -mtaC5L0ZFfoAartLSVX6a16dQDqbLy/ukecQeQ2qWo+IkNQe+p23GR1FihBZeHxC -G+L9igu/cFgRLubMqHelwVCwL12Uazb2tG2zAnaTi5WgU0urvLqMRCuyQ40KlQ4h -ly6oOEKWcwGBhfTD+baBsHLfrVdikz4IiV8+7oQsb/xyuQEz66FYLptDpX3obgRR -ls0xjJ1YlZsmFg/NCJaAoPILBnS8wpbQp+T8yf9YcfczsMs9wALtM2rkLZqS6dn0 -yBekDL3ZsuiS7Ot6WM351nKCvDtpe1hF4CAkE2xhCLdRyvDHmbq4vBf0nyAvzTCI -hUzgQeUKDDjxcmH1yxGNXswlfllqK6QkI9HnV/AuTI6nEjlBRNmtLg7SijHmuAZd -+X8Sy/CibqCgY0J51FlylH+Cx8qQUaUB81KKimCohTejzrfUm3xUOvautFG5Ag0E -VhmSBgEQAOQbxM1ZydIHIlnKx6LEmQdujX7Ns60NxrGdhLLHoJusuTutjTEt50Ex -MHhn/PjYVeK1JU/gTh0fPM7il9xwj+cUBbOtBQ+E2sVXXMSBMj93+6ivLBVesq27 -R3ls63EMKHGcyYsIqHafBG9EvBwHBj+UNG3qKyEZv/NaX6UUoEYrvI4yx+z+ahew -K5RMAZ1qNUqtZfsDlKW3SF3rgRBBmVWowim1G6tB0HVor4YRA/iHwH6WIu04QqzG -A0uQpvptVJ0i1Hd9SoXisJUsovXSRTqj7+eFbILGywbvM2NYwF52lW9jbz3gu/Hb -O3uPY0xdshW/8F92FZRXzuMMv3O6I5SaVRRJE2oJVJHtteEpyrbkCqhaLzkSiNxf -sqzOw03gYICnxSDY3fqKBRKq84DMbiXbv4DwqeXWZXR2Yhs85Rn5cgoNqg5oyNwy -PlQOfqZzoiDle3SWs41pCM2po1tGgZXkeRqNedRI9V+c8ZacOrTPnjRL0Ae475n4 -EFP3Ajur7UaXRe57AiSn4B30E5/D0HC0SeeRWacFeAHJ8WGvf6wXNGoAmtJL+TRJ -iSqNVjZ1EhuwYJpjUgPEfesXyCc5U6qkHMHcn0rXVteG4mrn0/191CPtfamxpDM9 -hhTZ0WEbwFRwC41QQnRCO6EQfkPwZLC9BtSSuRVCI30617HiOFwDABEBAAGJAiUE -GAECAA8FAlYZkgYCGwwFCQPBjGoACgkQ5md6xour3WwC1Q//QnYoOLfPiSI/NVI6 -agjCECNdtpUfdiGy7sEH3FYpNQGu8LDahcmTsxxcp2LeXjZIhuJt/dRPAMC/teQq -ihZvdz5iuYwqg8I7ZtZh+qxqxvjwOwtKnELpoMpZyK81v4C2oLQAzNdMC18QTBt+ -L3RSMDdnPJ92GsCoYSGdLT0Jy16l/ShUQZ85EFUEjzFEDVnlLKpfZoqVCIULe0nj -NCyNY6txc6X4uChCB5ZtsLaHgUTm0I+wb+AX0wbEDELyldzkbfVPTxbCMQgkPx0E -W7ufcM3wx9sGT9I3FNOqZKHa8xq08be7z6OJZlsuw1NfeWG+UF9f6KZjH/zxIdtY -IDoVReAU5g/LfOQTHXpg+7eArlf/hVh57uFjPJxdh8wqKfFzIVSoksCwv3w3Hrca -7eh7Po46U6Tt6icWInBUthvOja0CgDojw+mm3GKvGMif/9YZXY/RHcc3t2CQDp/c -Shzcaly9QYj0eDujTQj7XFd/AAwdj8YWA4Ha2Peh4/oK4ugt7pKwt51MvYzSYDel -NFTn1hbTXTcj21i2/C9I6oqIhKt8c+St6Tge7PkGjq5BRqvY2L/IJmS5TmSerciL -bpjAhwE2YmGQ7oB+3V798HtAmceRNf8AY0GWrZswJlg7xUn+WJNwQ9uIHI1fxYHx -2Nr+AmDDs6ZOEI5zhwxioePw/Cg= -=9lKb ------END PGP PUBLIC KEY BLOCK----- diff --git a/trunk/build.gradle b/trunk/build.gradle deleted file mode 100644 index 6368c16bc..000000000 --- a/trunk/build.gradle +++ /dev/null @@ -1,294 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -buildscript { - repositories { - maven { url "https://plugins.gradle.org/m2/" } - } - - dependencies { - classpath 'me.champeau.gradle:japicmp-gradle-plugin:0.1.2' - } -} - -// For help converting an Ant build to a Gradle build, see -// https://docs.gradle.org/current/userguide/ant.html - -ant.importBuild 'build.xml' - -/** - -Define properties for all projects, including this one - -*/ -allprojects { - apply plugin: 'eclipse' - - task wrapper(type: Wrapper) { - gradleVersion = '2.14.1' - } - - task adjustWrapperPropertiesFile << { - ant.replaceregexp(match:'^#.*', replace:'', flags:'g', byline:true) { - fileset(dir: project.projectDir, includes: 'gradle/wrapper/gradle-wrapper.properties') - } - new File(project.projectDir, 'gradle/wrapper/gradle-wrapper.properties').with { it.text = it.readLines().findAll { it }.sort().join('\n') } - ant.fixcrlf(file: 'gradle/wrapper/gradle-wrapper.properties', eol: 'lf') - } - wrapper.finalizedBy adjustWrapperPropertiesFile -} - -/** - -Define things that are only necessary in sub-projects, but not in the master-project itself - -*/ -subprojects { - //Put instructions for each sub project, but not the master - apply plugin: 'java' - apply plugin: 'jacoco' - - // See https://github.com/melix/japicmp-gradle-plugin - apply plugin: 'me.champeau.gradle.japicmp' - - version = '3.16-beta1' - ext { - japicmpversion = '3.15' - } - - tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' - } - - sourceCompatibility = 1.6 - - repositories { - mavenCentral() - } - - jar { - manifest { - attributes 'Implementation-Title': 'Apache POI', 'Implementation-Version': version - } - } - - test { - // Exclude some tests that are not actually tests or do not run cleanly on purpose - exclude '**/BaseTestBorderStyle.class' - exclude '**/BaseTestCellUtil.class' - exclude '**/TestUnfixedBugs.class' - exclude '**/TestOneFile.class' - - systemProperties = System.properties - - // set heap size for the test JVM(s) - minHeapSize = "128m" - maxHeapSize = "768m" - - // show standard out and standard error of the test JVM(s) on the console - //testLogging.showStandardStreams = true - - // http://forums.gradle.org/gradle/topics/jacoco_related_failure_in_multiproject_build - systemProperties['user.dir'] = workingDir - - systemProperties['POI.testdata.path'] = '../../test-data' - //systemProperties['user.language'] = 'en' - //systemProperties['user.country'] = 'US' - } - - test.beforeSuite { TestDescriptor suite -> - System.setProperty('user.language', 'en') - System.setProperty('user.country', 'US') - } - - jacoco { - toolVersion = '0.7.7.201606060606' - } - - // ensure the build-dir exists - projectDir.mkdirs() -} - -project('main') { - sourceSets.main.java.srcDirs = ['../../src/java'] - sourceSets.main.resources.srcDirs = ['../../src/resources/main'] - sourceSets.test.java.srcDirs = ['../../src/testcases'] - - dependencies { - compile 'commons-codec:commons-codec:1.10' - compile 'commons-logging:commons-logging:1.2' - - testCompile 'junit:junit:4.12' - } - - // Create a separate jar for test-code to depend on it in other projects - // See http://stackoverflow.com/questions/5144325/gradle-test-dependency - task testJar(type: Jar, dependsOn: testClasses) { - baseName = "test-${project.archivesBaseName}" - from sourceSets.test.output - } - - configurations { - tests - } - - artifacts { - tests testJar - } - - // TOOD: we should not duplicate this task in each project, but I did not figure out how to inject the artifactId for each project - task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask, dependsOn: jar) { - baseline = 'org.apache.poi:poi:' + japicmpversion + '@jar' - to = jar.archivePath - onlyModified = true - onlyBinaryIncompatibleModified = true - failOnModification = false - txtOutputFile = file("$buildDir/reports/japi.txt") - htmlOutputFile = file("$buildDir/reports/japi.html") - } -} - -project('ooxml') { - sourceSets.main.java.srcDirs = ['../../src/ooxml/java'] - sourceSets.main.resources.srcDirs = ['../../src/ooxml/resources', '../../src/resources/ooxml'] - sourceSets.test.java.srcDirs = ['../../src/ooxml/testcases'] - - // for now import the ant-task for building the jars from build.xml - // we need to rename the tasks as e.g. task "jar" conflicts with :ooxml:jar - ant.importBuild('../../build.xml') { antTargetName -> - 'ant-' + antTargetName - } - compileJava.dependsOn 'ant-compile-ooxml-xsds' - - dependencies { - compile 'org.apache.xmlbeans:xmlbeans:2.6.0' - compile 'org.apache.commons:commons-collections4:4.1' - compile 'org.apache.santuario:xmlsec:2.0.6' - compile 'org.bouncycastle:bcpkix-jdk15on:1.54' - compile 'com.github.virtuald:curvesapi:1.04' - - // for ooxml-lite, should we move this somewhere else? - compile 'junit:junit:4.12' - - compile project(':main') - compile project(':scratchpad') // TODO: get rid of this dependency! - compile files('../../ooxml-lib/ooxml-schemas-1.3.jar') - compile files('../../ooxml-lib/ooxml-security-1.1.jar') - - testCompile 'junit:junit:4.12' - testCompile project(path: ':main', configuration: 'tests') - } - - // TOOD: we should not duplicate this task in each project, but I did not figure out how to inject the artifactId for each project - task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask, dependsOn: jar) { - baseline = 'org.apache.poi:poi-ooxml:' + japicmpversion + '@jar' - to = jar.archivePath - onlyModified = true - onlyBinaryIncompatibleModified = true - failOnModification = false - txtOutputFile = file("$buildDir/reports/japi.txt") - htmlOutputFile = file("$buildDir/reports/japi.html") - } -} - -project('examples') { - sourceSets.main.java.srcDirs = ['../../src/examples/src'] - - dependencies { - compile project(':main') - compile project(':ooxml') - } -} - - -project('excelant') { - sourceSets.main.java.srcDirs = ['../../src/excelant/java'] - sourceSets.main.resources.srcDirs = ['../../src/excelant/resources'] - sourceSets.test.java.srcDirs = ['../../src/excelant/testcases'] - - dependencies { - compile 'org.apache.ant:ant:1.9.4' - - compile project(':main') - compile project(':ooxml') - - testCompile project(path: ':main', configuration: 'tests') - } - - // TOOD: we should not duplicate this task in each project, but I did not figure out how to inject the artifactId for each project - task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask, dependsOn: jar) { - baseline = 'org.apache.poi:poi-excelant:' + japicmpversion + '@jar' - to = jar.archivePath - onlyModified = true - onlyBinaryIncompatibleModified = true - failOnModification = false - txtOutputFile = file("$buildDir/reports/japi.txt") - htmlOutputFile = file("$buildDir/reports/japi.html") - } -} - -project('integrationtest') { - sourceSets.test.java.srcDirs = ['../../src/integrationtest'] - - dependencies { - compile 'org.apache.ant:ant:1.9.4' - - compile project(':main') - compile project(':ooxml') - compile project(':scratchpad') - compile project(':examples') - - testCompile 'junit:junit:4.12' - } - - test { - // exclude these from the normal test-run - exclude '**/TestAllFiles.class' - exclude '**/*FileHandler.class' - exclude '**/RecordsStresser.class' - } - - task integrationTest(type: Test) { - // these are just tests used during development of more test-code - exclude '**/*FileHandler.class' - exclude '**/RecordStresser.class' - } -} - -project('scratchpad') { - sourceSets.main.java.srcDirs = ['../../src/scratchpad/src'] - sourceSets.main.resources.srcDirs = ['../../src/resources/scratchpad'] - sourceSets.test.java.srcDirs = ['../../src/scratchpad/testcases'] - - dependencies { - compile project(':main') - // cyclic-dependency here: compile project(':ooxml') - - testCompile 'junit:junit:4.12' - testCompile project(path: ':main', configuration: 'tests') - } - - // TOOD: we should not duplicate this task in each project, but I did not figure out how to inject the artifactId for each project - task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask, dependsOn: jar) { - baseline = 'org.apache.poi:poi-scratchpad:' + japicmpversion + '@jar' - to = jar.archivePath - onlyModified = true - onlyBinaryIncompatibleModified = true - failOnModification = false - txtOutputFile = file("$buildDir/reports/japi.txt") - htmlOutputFile = file("$buildDir/reports/japi.html") - } -} diff --git a/trunk/build.xml b/trunk/build.xml deleted file mode 100644 index 23e2ef293..000000000 --- a/trunk/build.xml +++ /dev/null @@ -1,2671 +0,0 @@ - - - - - - The Apache POI project Ant build. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - project.setProperty(attributes.get("name"), attributes.get("value")); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This is POI ${version.id} - Java Version ${ant.java.version}/${java.version} - Timestamp ${DSTAMP} - The main targets of interest are: - - clean Erase all build work products (ie. everything in the build directory) - - compile Compile all files from main, ooxml and scratchpad - - test Run all unit tests from main, ooxml and scratchpad - - jar Produce jar files - - jar-src Produce source-jar files - - assemble Produce the zipped distribution files - - site Generate all documentation (Requires Apache Forrest) - - dist Create a distribution (Requires Apache Forrest) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var rel = ("REL_"+project.getProperty("version.id")).toUpperCase().replace(/\W/g,"_"); - if (rel.search(/BETA/) == -1) rel += "_FINAL"; - project.setProperty("RELEASE_TAG", rel); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.xmlbeans.XmlBeans.getContextTypeLoader() - org.apache.poi.POIXMLTypeLoader - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please install Apache Forrest (see - <https://forrest.apache.org/index.html>) and set the - FORREST_HOME environment variable! - - - - - - - - - - - - - - - - - - - Broken links: - - - - - - - - - - - - - - - - - - - - - - - - POI API Documentation]]> - - Copyright ${tstamp.year} The Apache Software Foundation or - its licensors, as applicable.]]> - - - DDF - Dreadful Drawing Format - - - - HPSF - Horrible Property Set Format - - - - - SS - Common Spreadsheet Format - - - - HSSF - Horrible Spreadsheet Format - - - - XSSF - Open Office XML Spreadsheet Format - - - - - SL - Common Slideshow Format - - - - HSLF - Horrible Slideshow Format - - - - XSLF - Open Office XML Slideshow Format - - - - - HWPF - Horrible Word Processor Format - - - - XWPF - Open Office XML Word Processor Format - - - - - HDGF - Horrible Diagram Format - - - - XDGF - Open Office XML Diagram Format - - - - - POIFS - POI File System - - - - Utilities - - - - Examples - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Maven POMs are located in ${dist.dir} - Use ant dist-nexus to deploy the artifacts in the remote repository - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Creating Maven POMs - - - Distribution located in ${dist.dir} - Use "ant dist-checksum" to create md5/sha1 checksums and GPG signatures - - - - - - - - - - - - - - - - - - - - - Maven ant tasks not found. - Please make sure the maven-ant-tasks jar is in ANT_HOME/lib, or made - available to Ant using other mechanisms like -lib or CLASSPATH. - - You can download the Maven Ant Tasks from https://maven.apache.org/ant-tasks/download.html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${rat.reportcontent} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.poi - @{artifactId} - - ${version.id} - ${version.id} - - ${version.id} - - ${lastUpdated} - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var relCurr = new String(project.getProperty("version.id")); - var relNext = relCurr.replace(/[0-9]+$/, function(lastNum){ return new String(new Number(lastNum)+1); }); - if (relNext.search(/beta/i) == -1) relNext += "-beta1"; - project.setProperty("rel_next", relNext); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var bytes = Number(attributes.get("bytes")); - var mega = String((bytes/(1024.0*1024.0)).toFixed(2)); - project.setProperty(attributes.get("property"), mega); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${rel_date} - POI ${version.id} available -

The Apache POI team is pleased to announce the release of ${version.id}. - Featured are a handful of new areas of functionality and numerous bug fixes.

-

A summary of changes is available in the - Release Notes. - A full list of changes is available in the change log. - People interested should also follow the dev list - to track progress.

-

- The POI source release as well as the pre-built binary deployment packages are listed below. - Pre-built versions of all POI components - are available in the central Maven repository under Group ID "org.apache.poi" and Version - "${version.id}". -

-
Binary Distribution -
    -
  • poi-bin-${version.id}-${file_date}.tar.gz - (${bin-tar-size} MB, signature (.asc)) -
    - MD5 checksum: - ${bin-tar-md5} -
    - SHA1 checksum: - ${bin-tar-sha1} -
  • -
  • poi-bin-${version.id}-${file_date}.zip - (${bin-zip-size} MB, signature (.asc)) -
    - MD5 checksum: - ${bin-zip-md5} -
    - SHA1 checksum: - ${bin-zip-sha1} -
  • -
-
-
Source Distribution -
    -
  • poi-src-${version.id}-${file_date}.tar.gz - (${src-tar-size} MB, signature (.asc)) -
    - MD5 checksum: - ${src-tar-md5} -
    - SHA1 checksum: - ${src-tar-sha1} -
  • -
  • poi-src-${version.id}-${file_date}.zip - (${src-zip-size} MB, signature (.asc)) -
    - MD5 checksum: - ${src-zip-md5} -
    - SHA1 checksum: - ${src-zip-sha1} -
  • -
-
- -]]>
-
-
diff --git a/trunk/doap_POI.rdf b/trunk/doap_POI.rdf deleted file mode 100644 index 08106f476..000000000 --- a/trunk/doap_POI.rdf +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - 2006-01-26 - - Apache POI - - - Java API To Access Microsoft Document File Formats - APIs for manipulating various file formats based upon Open Office XML (ECMA-376) and Microsoft's OLE 2 Compound Document formats using pure Java. Apache POI is your Java Excel, Word and PowerPoint solution. We have a complete API for porting other OOXML and OLE 2 Compound Document formats and welcome others to participate. - - - - Java - - - - - Apache POI 3.15 - 2016-09-21 - 3.15 - - - - - Apache POI 3.14 - 2016-03-05 - 3.14 - - - - - Apache POI 3.13 - 2015-09-29 - 3.13 - - - - - Apache POI 3.12 - 2015-05-11 - 3.12 - - - - - Apache POI 3.11 - 2014-12-21 - 3.11 - - - - - Apache POI 3.10.1 - 2014-08-18 - 3.10.1 - - - - - Apache POI 3.10 - 2014-02-08 - 3.10 - - - - - Apache POI 3.9 - 2012-12-03 - 3.9 - - - - - Apache POI 3.8 - 2012-03-26 - 3.8 - - - - - Apache POI 3.7 - 2010-10-29 - 3.7 - - - - - Apache POI 3.6 - 2009-12-14 - 3.6 - - - - - Apache POI 3.5 - 2009-09-28 - 3.5 - - - - - Apache POI 3.2 - 2008-10-19 - 3.2 - - - - - - - - - - - POI Committers - - - - - diff --git a/trunk/legal/LICENSE b/trunk/legal/LICENSE deleted file mode 100644 index 19246db04..000000000 --- a/trunk/legal/LICENSE +++ /dev/null @@ -1,513 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -APACHE POI SUBCOMPONENTS: - -Apache POI includes subcomponents with separate copyright notices and -license terms. Your use of these subcomponents is subject to the terms -and conditions of the following licenses: - - -Office Open XML schemas (ooxml-schemas-1.*.jar) - - The Office Open XML schema definitions used by Apache POI are - a part of the Office Open XML ECMA Specification (ECMA-376, [1]). - As defined in section 9.4 of the ECMA bylaws [2], this specification - is available to all interested parties without restriction: - - 9.4 All documents when approved shall be made available to - all interested parties without restriction. - - Furthermore, both Microsoft and Adobe have granted patent licenses - to this work [3,4,5]. - - [1] http://www.ecma-international.org/publications/standards/Ecma-376.htm - [2] http://www.ecma-international.org/memento/Ecmabylaws.htm - [3] http://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx - [4] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ - Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf - [5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ - Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf - - -Bouncy Castle library (bcprov-*.jar, bcpg-*.jar, bcpkix-*.jar) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - -JUnit test library (junit-4.*.jar) & JaCoCo (*jacoco*) - - Eclipse Public License - v 1.0 - - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC - LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM - CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - - 1. DEFINITIONS - - "Contribution" means: - - a) in the case of the initial Contributor, the initial code and documentation - distributed under this Agreement, and - b) in the case of each subsequent Contributor: - i) changes to the Program, and - ii) additions to the Program; - where such changes and/or additions to the Program originate from and are - distributed by that particular Contributor. A Contribution 'originates' from - a Contributor if it was added to the Program by such Contributor itself or - anyone acting on such Contributor's behalf. Contributions do not include - additions to the Program which: (i) are separate modules of software - distributed in conjunction with the Program under their own license agreement, - and (ii) are not derivative works of the Program. - - "Contributor" means any person or entity that distributes the Program. - - "Licensed Patents" mean patent claims licensable by a Contributor which are - necessarily infringed by the use or sale of its Contribution alone or when - combined with the Program. - - "Program" means the Contributions distributed in accordance with this Agreement. - - "Recipient" means anyone who receives the Program under this Agreement, - including all Contributors. - - 2. GRANT OF RIGHTS - - a) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free copyright license to - reproduce, prepare derivative works of, publicly display, publicly - perform, distribute and sublicense the Contribution of such Contributor, - if any, and such derivative works, in source code and object code form. - b) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free patent license under - Licensed Patents to make, use, sell, offer to sell, import and otherwise - transfer the Contribution of such Contributor, if any, in source code - and object code form. This patent license shall apply to the combination - of the Contribution and the Program if, at the time the Contribution is - added by the Contributor, such addition of the Contribution causes such - combination to be covered by the Licensed Patents. The patent license - shall not apply to any other combinations which include the Contribution. - No hardware per se is licensed hereunder. - c) Recipient understands that although each Contributor grants the licenses - to its Contributions set forth herein, no assurances are provided by any - Contributor that the Program does not infringe the patent or other - intellectual property rights of any other entity. Each Contributor - disclaims any liability to Recipient for claims brought by any other - entity based on infringement of intellectual property rights or - otherwise. As a condition to exercising the rights and licenses granted - hereunder, each Recipient hereby assumes sole responsibility to secure - any other intellectual property rights needed, if any. For example, if - a third party patent license is required to allow Recipient to distribute - the Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - d) Each Contributor represents that to its knowledge it has sufficient - copyright rights in its Contribution, if any, to grant the copyright - license set forth in this Agreement. - - 3. REQUIREMENTS - - A Contributor may choose to distribute the Program in object code form under - its own license agreement, provided that: - - a) it complies with the terms and conditions of this Agreement; and - b) its license agreement: - i) effectively disclaims on behalf of all Contributors all warranties and - conditions, express and implied, including warranties or conditions of - title and non-infringement, and implied warranties or conditions of - merchantability and fitness for a particular purpose; - ii) effectively excludes on behalf of all Contributors all liability for - damages, including direct, indirect, special, incidental and - consequential damages, such as lost profits; - iii) states that any provisions which differ from this Agreement are - offered by that Contributor alone and not by any other party; and - iv) states that source code for the Program is available from such - Contributor, and informs licensees how to obtain it in a reasonable - manner on or through a medium customarily used for software exchange. - - When the Program is made available in source code form: - - a) it must be made available under this Agreement; and - b) a copy of this Agreement must be included with each copy of the Program. - Contributors may not remove or alter any copyright notices contained - within the Program. - - Each Contributor must identify itself as the originator of its Contribution, - if any, in a manner that reasonably allows subsequent Recipients to identify - the originator of the Contribution. - - 4. COMMERCIAL DISTRIBUTION - - Commercial distributors of software may accept certain responsibilities with - respect to end users, business partners and the like. While this license is - intended to facilitate the commercial use of the Program, the Contributor - who includes the Program in a commercial product offering should do so in a - manner which does not create potential liability for other Contributors. - Therefore, if a Contributor includes the Program in a commercial product - offering, such Contributor ("Commercial Contributor") hereby agrees to - defend and indemnify every other Contributor ("Indemnified Contributor") - against any losses, damages and costs (collectively "Losses") arising from - claims, lawsuits and other legal actions brought by a third party against - the Indemnified Contributor to the extent caused by the acts or omissions - of such Commercial Contributor in connection with its distribution of the - Program in a commercial product offering. The obligations in this section - do not apply to any claims or Losses relating to any actual or alleged - intellectual property infringement. In order to qualify, an Indemnified - Contributor must: a) promptly notify the Commercial Contributor in writing - of such claim, and b) allow the Commercial Contributor to control, and - cooperate with the Commercial Contributor in, the defense and any related - settlement negotiations. The Indemnified Contributor may participate in any - such claim at its own expense. - - For example, a Contributor might include the Program in a commercial product - offering, Product X. That Contributor is then a Commercial Contributor. If - that Commercial Contributor then makes performance claims, or offers - warranties related to Product X, those performance claims and warranties are - such Commercial Contributor's responsibility alone. Under this section, the - Commercial Contributor would have to defend claims against the other - Contributors related to those performance claims and warranties, and if a - court requires any other Contributor to pay any damages as a result, the - Commercial Contributor must pay those damages. - - 5. NO WARRANTY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON - AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER - EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR - CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A - PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the - appropriateness of using and distributing the Program and assumes all risks - associated with its exercise of rights under this Agreement , including but - not limited to the risks and costs of program errors, compliance with - applicable laws, damage to or loss of data, programs or equipment, and - unavailability or interruption of operations. - - 6. DISCLAIMER OF LIABILITY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY - CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION - LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE - EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGES. - - 7. GENERAL - - If any provision of this Agreement is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of the - remainder of the terms of this Agreement, and without further action by the - parties hereto, such provision shall be reformed to the minimum extent - necessary to make such provision valid and enforceable. - - If Recipient institutes patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Program itself - (excluding combinations of the Program with other software or hardware) - infringes such Recipient's patent(s), then such Recipient's rights granted - under Section 2(b) shall terminate as of the date such litigation is filed. - - All Recipient's rights under this Agreement shall terminate if it fails to - comply with any of the material terms or conditions of this Agreement and - does not cure such failure in a reasonable period of time after becoming - aware of such noncompliance. If all Recipient's rights under this Agreement - terminate, Recipient agrees to cease use and distribution of the Program as - soon as reasonably practicable. However, Recipient's obligations under this - Agreement and any licenses granted by Recipient relating to the Program - shall continue and survive. - - Everyone is permitted to copy and distribute copies of this Agreement, but - in order to avoid inconsistency the Agreement is copyrighted and may only - be modified in the following manner. The Agreement Steward reserves the - right to publish new versions (including revisions) of this Agreement from - time to time. No one other than the Agreement Steward has the right to - modify this Agreement. The Eclipse Foundation is the initial Agreement - Steward. The Eclipse Foundation may assign the responsibility to serve as - the Agreement Steward to a suitable separate entity. Each new version of - the Agreement will be given a distinguishing version number. The Program - (including Contributions) may always be distributed subject to the version - of the Agreement under which it was received. In addition, after a new - version of the Agreement is published, Contributor may elect to distribute - the Program (including its Contributions) under the new version. Except as - expressly stated in Sections 2(a) and 2(b) above, Recipient receives no - rights or licenses to the intellectual property of any Contributor under - this Agreement, whether expressly, by implication, estoppel or otherwise. - All rights in the Program not expressly granted under this Agreement are - reserved. - - This Agreement is governed by the laws of the State of New York and the - intellectual property laws of the United States of America. No party to this - Agreement will bring a legal action under this Agreement more than one year - after the cause of action arose. Each party waives its rights to a jury - trial in any resulting litigation. - -Hamcrest library (hamcrest-*.jar) & CuvesAPI / Curve API - - BSD License - - Copyright (c) 2000-2006, www.hamcrest.org - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. Redistributions in binary - form must reproduce the above copyright notice, this list of conditions and - the following disclaimer in the documentation and/or other materials - provided with the distribution. - - Neither the name of Hamcrest nor the names of its contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -SLF4J library (slf4j-api-*.jar) - - Copyright (c) 2004-2013 QOS.ch - All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/trunk/legal/NOTICE b/trunk/legal/NOTICE deleted file mode 100644 index 43d9b3b23..000000000 --- a/trunk/legal/NOTICE +++ /dev/null @@ -1,23 +0,0 @@ -Apache POI -Copyright 2003-2016 The Apache Software Foundation - -This product includes software developed by -The Apache Software Foundation (https://www.apache.org/). - -This product contains parts that were originally based on software from BEA. -Copyright (c) 2000-2003, BEA Systems, . - -This product contains W3C XML Schema documents. Copyright 2001-2003 (c) -World Wide Web Consortium (Massachusetts Institute of Technology, European -Research Consortium for Informatics and Mathematics, Keio University) - -This product contains the Piccolo XML Parser for Java -(http://piccolo.sourceforge.net/). Copyright 2002 Yuval Oren. - -This product contains the chunks_parse_cmds.tbl file from the vsdump program. -Copyright (C) 2006-2007 Valek Filippov (frob@df.ru) - -This product contains parts of the eID Applet project -(http://eid-applet.googlecode.com). Copyright (c) 2009-2014 -FedICT (federal ICT department of Belgium), e-Contract.be BVBA (https://www.e-contract.be), -Bart Hanssens from FedICT diff --git a/trunk/maven/multisign.sh b/trunk/maven/multisign.sh deleted file mode 100755 index 1ba8c91f4..000000000 --- a/trunk/maven/multisign.sh +++ /dev/null @@ -1,54 +0,0 @@ -#! /bin/sh -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# create md5 checksums and gpg signatures - -echo "If you use gpg2 you need to set GPG_BIN accordingly" - -GPG_BIN=gpg - -stty -echo -echo "enter your GPG passphrase" -read passphrase -stty echo - -# Do we have md5sum and sha1sum? -# (We can use openssl if not, but the files it produces aren't as nice) -which md5sum > /dev/null -LACKING_MD5SUM=$? -which sha1sum > /dev/null -LACKING_SHA1SUM=$? - -for i in *; do - echo "" - echo Signing $i - echo $passphrase | $GPG_BIN --passphrase-fd 0 --output $i.asc --detach-sig --armor $i - $GPG_BIN --verify $i.asc $i - echo Hashing $i - - if [ "$LACKING_MD5SUM" = "1" ]; then - openssl md5 < $i > $i.md5 - else - md5sum $i > $i.md5 - fi - - if [ "$LACKING_SHA1SUM" = "1" ]; then - openssl sha1 < $i > $i.sha1 - else - sha1sum $i > $i.sha1 - fi -done diff --git a/trunk/maven/mvn-deploy.sh b/trunk/maven/mvn-deploy.sh deleted file mode 100755 index a66936a13..000000000 --- a/trunk/maven/mvn-deploy.sh +++ /dev/null @@ -1,62 +0,0 @@ -#! /bin/sh -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Shell script to deploy POI artifacts in a maven repository. -# -# Note, You should configure your settings.xml and add a server with id=apache-releases: -# -# -# apache-releases -# apacheId -# mySecurePassw0rd -# -# -# -# -# apache-releases -# -# -# -# -# -# -# Usage: -# 1. ant dist -# 2. cd build/dist -# 3. ./mvn-deploy.sh - -M2_REPOSITORY=https://repository.apache.org/service/local/staging/deploy/maven2 - -VERSION=@VERSION@ -DSTAMP=@DSTAMP@ - -for artifactId in poi poi-scratchpad poi-ooxml poi-examples poi-ooxml-schemas poi-excelant -do - SENDS="-Dfile=$artifactId-$VERSION-$DSTAMP.jar" - SENDS="$SENDS -DpomFile=$artifactId-$VERSION.pom" - if [ -r $artifactId-$VERSION-sources-$DSTAMP.jar ]; then - SENDS="$SENDS -Dsources=$artifactId-$VERSION-sources-$DSTAMP.jar" - fi - if [ -r $artifactId-$VERSION-javadocs-$DSTAMP.jar ]; then - SENDS="$SENDS -Djavadoc=$artifactId-$VERSION-javadocs-$DSTAMP.jar" - fi - - mvn gpg:sign-and-deploy-file \ - -DrepositoryId=apache-releases -P apache-releases \ - -Durl=$M2_REPOSITORY \ - $SENDS -done diff --git a/trunk/maven/ooxml-schemas.pom b/trunk/maven/ooxml-schemas.pom deleted file mode 100644 index da49544ae..000000000 --- a/trunk/maven/ooxml-schemas.pom +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - ooxml-schemas - @VERSION@ - jar - OOXML schemas - XmlBeans generated from the Ecma supplied xsds: - http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%20Part%204%20(DOCX).zip - http://poi.apache.org/ - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.xmlbeans - xmlbeans - 2.3.0 - - - diff --git a/trunk/maven/ooxml-security.pom b/trunk/maven/ooxml-security.pom deleted file mode 100644 index de9112e21..000000000 --- a/trunk/maven/ooxml-security.pom +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - ooxml-security - @VERSION@ - jar - OOXML security - - XmlBeans generated from various supplied xsds for encryption and signing: - http://msdn.microsoft.com/en-us/library/dd925810(v=office.12).aspx - http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%201st%20edition%20Part%202%20(PDF).zip - http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd - http://uri.etsi.org/01903/v1.3.2/XAdES.xsd - http://uri.etsi.org/01903/v1.4.1/XAdESv141.xsd - http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd - http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd - http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd - - http://poi.apache.org/ - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.xmlbeans - xmlbeans - 2.3.0 - - - diff --git a/trunk/maven/poi-examples.pom b/trunk/maven/poi-examples.pom deleted file mode 100644 index 249f2500f..000000000 --- a/trunk/maven/poi-examples.pom +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - poi-examples - @VERSION@ - jar - Apache POI - http://poi.apache.org/ - Apache POI Examples - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.poi - poi - @VERSION@ - - - org.apache.poi - poi-scratchpad - @VERSION@ - - - org.apache.poi - poi-ooxml - @VERSION@ - - - diff --git a/trunk/maven/poi-excelant.pom b/trunk/maven/poi-excelant.pom deleted file mode 100644 index 6b23e4a12..000000000 --- a/trunk/maven/poi-excelant.pom +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - poi-excelant - @VERSION@ - jar - Apache POI - http://poi.apache.org/ - Apache POI Excel Ant Tasks - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.poi - poi - @VERSION@ - - - org.apache.poi - poi-ooxml - @VERSION@ - - - org.apache.ant - ant - 1.8.2 - - - diff --git a/trunk/maven/poi-ooxml-schemas.pom b/trunk/maven/poi-ooxml-schemas.pom deleted file mode 100644 index baf531d54..000000000 --- a/trunk/maven/poi-ooxml-schemas.pom +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - poi-ooxml-schemas - @VERSION@ - jar - Apache POI - http://poi.apache.org/ - Apache POI - Java API To Access Microsoft Format Files - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.xmlbeans - xmlbeans - 2.6.0 - - - diff --git a/trunk/maven/poi-ooxml.pom b/trunk/maven/poi-ooxml.pom deleted file mode 100644 index 0f3cdb1d5..000000000 --- a/trunk/maven/poi-ooxml.pom +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - poi-ooxml - @VERSION@ - jar - Apache POI - http://poi.apache.org/ - Apache POI - Java API To Access Microsoft Format Files - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.poi - poi - @VERSION@ - - - org.apache.poi - poi-ooxml-schemas - @VERSION@ - - - com.github.virtuald - curvesapi - 1.04 - - - diff --git a/trunk/maven/poi-scratchpad.pom b/trunk/maven/poi-scratchpad.pom deleted file mode 100644 index d1b4392de..000000000 --- a/trunk/maven/poi-scratchpad.pom +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - poi-scratchpad - @VERSION@ - jar - Apache POI - http://poi.apache.org/ - Apache POI - Java API To Access Microsoft Format Files - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - org.apache.poi - poi - @VERSION@ - - - diff --git a/trunk/maven/poi.pom b/trunk/maven/poi.pom deleted file mode 100644 index efd24cfe0..000000000 --- a/trunk/maven/poi.pom +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - 4.0.0 - org.apache.poi - poi - @VERSION@ - jar - Apache POI - http://poi.apache.org/ - Apache POI - Java API To Access Microsoft Format Files - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - - commons-logging - commons-logging - 1.2 - runtime - true - - - log4j - log4j - 1.2.17 - runtime - true - - - commons-codec - commons-codec - 1.10 - - - - org.hamcrest - hamcrest-core - test - 1.3 - - - junit - junit - test - 4.12 - - - org.apache.commons - commons-collections4 - 4.1 - - - - diff --git a/trunk/osgi/build.xml b/trunk/osgi/build.xml deleted file mode 100644 index 35dd87bcc..000000000 --- a/trunk/osgi/build.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - The Apache POI OSGi Bundle System. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/osgi/bundle.info b/trunk/osgi/bundle.info deleted file mode 100644 index 1886a0aef..000000000 --- a/trunk/osgi/bundle.info +++ /dev/null @@ -1,38 +0,0 @@ -\u001B[1mSYNOPSIS\u001B[0m - ${project.description} - - Original Maven URLs: - \u001B[33mmvn:${pkgGroupId}/poi/${pkgVersion}\u001B[0m - \u001B[33mmvn:${pkgGroupId}/poi-ooxml/${pkgVersion}\u001B[0m - \u001B[33mmvn:${pkgGroupId}/poi-scratchpad/${pkgVersion}\u001B[0m - -\u001B[1mDESCRIPTION\u001B[0m - The Apache POI Project's mission is to create and maintain Java APIs for manipulating various file formats based - upon the Office Open XML standards (OOXML) and Microsoft's OLE 2 Compound Document format (OLE2). In short, you can - read and write MS Excel files using Java. In addition, you can read and write MS Word and MS PowerPoint files using - Java. Apache POI is your Java Excel solution (for Excel 97-2008). We have a complete API for porting other OOXML and - OLE2 formats and welcome others to participate. - - OLE2 files include most Microsoft Office files such as XLS, DOC, and PPT as well as MFC serialization API based file - formats. The project provides APIs for the OLE2 Filesystem (POIFS) and OLE2 Document Properties (HPSF). - - Office OpenXML Format is the new standards based XML file format found in Microsoft Office 2007 and 2008. This - includes XLSX, DOCX and PPTX. The project provides a low level API to support the Open Packaging Conventions using - openxml4j. - - For each MS Office application there exists a component module that attempts to provide a common high level Java api - to both OLE2 and OOXML document formats. This is most developed for Excel workbooks (SS=HSSF+XSSF). Work is - progressing for Word documents (HWPF+XWPF) and PowerPoint presentations (HSLF+XSLF). - - The project has recently added support for Outlook (HSMF). Microsoft opened the specifications to this format in - October 2007. We would welcome contributions. - - There are also projects for Visio (HDGF), TNEF (HMEF), and Publisher (HPBF). - - As a general policy we collaborate as much as possible with other projects to provide this functionality. - Examples include: Cocoon for which there are serializers for HSSF; Open Office.org with whom we collaborate in - documenting the XLS format; and Tika / Lucene, for which we provide format interpretors. - When practical, we donate components directly to those projects for POI-enabling them. - -\u001B[1mSEE ALSO\u001B[0m - \u001B[36mhttp://poi.apache.org/\u001B[0m diff --git a/trunk/osgi/pom.xml b/trunk/osgi/pom.xml deleted file mode 100644 index 2849467a9..000000000 --- a/trunk/osgi/pom.xml +++ /dev/null @@ -1,229 +0,0 @@ - - - - - 4.0.0 - - - org.apache - apache - 10 - - - - org.apache.poi - poi-bundle - bundle - Apache POI OSGi bundle - - OSGi bundle that contains Apache POI, and the dependencies. - - http://poi.apache.org/ - ${poi.version} - - - - 1.6 - 1.6 - 4.4.0 - - - - - ${project.groupId} - poi - ${poi.version} - - - ${project.groupId} - poi-scratchpad - ${poi.version} - - - ${project.groupId} - poi-ooxml - ${poi.version} - - - - - junit - junit - 4.12 - - - org.ops4j.pax.exam - pax-exam-junit4 - ${pax.exam.version} - test - - - org.ops4j.pax.exam - pax-exam-container-native - ${pax.exam.version} - test - - - org.apache.felix - org.apache.felix.framework - 4.6.0 - test - - - org.ops4j.pax.exam - pax-exam-link-assembly - ${pax.exam.version} - test - - - org.ops4j.pax.url - pax-url-aether - 2.3.0 - test - - - javax.inject - javax.inject - 1 - test - - - org.osgi - org.osgi.core - 5.0.0 - provided - - - - - - - org.apache.felix - maven-bundle-plugin - true - - - - org.apache.poi.osgi.Activator - - - poi;inline=true, - poi-scratchpad;inline=true, - poi-ooxml;inline=true, - poi-ooxml-schemas, - xmlbeans - - true - ${project.url} - - org.apache.poi.* - - - !org.junit, - *, - org.apache.xmlbeans.impl.xpath.saxon;resolution:=optional, - org.apache.xmlbeans.impl.xquery.saxon;resolution:=optional, - org.bouncycastle.cert;resolution:=optional, - org.bouncycastle.cert.ocsp;resolution:=optional, - org.bouncycastle.cms.bc;resolution:=optional, - org.bouncycastle.cert.jcajce;resolution:=optional, - org.bouncycastle.operator;resolution:=optional, - org.bouncycastle.operator.bc;resolution:=optional, - org.bouncycastle.tsp;resolution:=optional, - org.openxmlformats.schemas.officeDocument.x2006.math;resolution:=optional, - org.openxmlformats.schemas.schemaLibrary.x2006.main;resolution:=optional, - schemasMicrosoftComOfficePowerpoint;resolution:=optional, - schemasMicrosoftComOfficeWord;resolution:=optional, - - - - - - maven-compiler-plugin - 3.2 - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - - - - java6 - - [1.6,) - - - - - maven-assembly-plugin - - - pre-integration-test - - single - - - test-bundles.xml - test - false - - - - - - maven-failsafe-plugin - 2.10 - - - - integration-test - verify - - - - - - - WARN - - - - - - - - - - - The Apache Software Founation - http://www.apache.org - - - http://svn.apache.org/viewvc/poi/trunk/osgi - scm:svn:http://svn.apache.org/repos/asf/poi/trunk/osgi - scm:svn:https://svn.apache.org/repos/asf/poi/trunk/osgi - - diff --git a/trunk/osgi/src/main/java/org/apache/poi/osgi/Activator.java b/trunk/osgi/src/main/java/org/apache/poi/osgi/Activator.java deleted file mode 100644 index 2f0212bd4..000000000 --- a/trunk/osgi/src/main/java/org/apache/poi/osgi/Activator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.osgi; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -public class Activator implements BundleActivator { - public void start(BundleContext context) throws Exception { - } - public void stop(BundleContext context) throws Exception { - } -} diff --git a/trunk/osgi/src/test/java/org/apache/poi/osgi/TestOSGiBundle.java b/trunk/osgi/src/test/java/org/apache/poi/osgi/TestOSGiBundle.java deleted file mode 100644 index 738d96b99..000000000 --- a/trunk/osgi/src/test/java/org/apache/poi/osgi/TestOSGiBundle.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.osgi; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.ops4j.pax.exam.CoreOptions.bundle; -import static org.ops4j.pax.exam.CoreOptions.junitBundles; -import static org.ops4j.pax.exam.CoreOptions.options; - -import javax.inject.Inject; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerMethod; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; - -/** - * Test to ensure that all our main formats can create, write - * and read back in, when running under OSGi - */ -@RunWith(PaxExam.class) -@ExamReactorStrategy(PerMethod.class) -public class TestOSGiBundle { - - private final File TARGET = new File("target"); - - @Inject - private BundleContext bc; - - @Configuration - public Option[] configuration() throws IOException, URISyntaxException { - File base = new File(TARGET, "test-bundles"); - return options( - junitBundles(), - bundle(new File(base, "poi-bundle.jar").toURI().toURL().toString())); - } - - @Test - public void testHSSF() throws Exception { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet s = wb.createSheet("OSGi"); - s.createRow(0).createCell(0).setCellValue("With OSGi"); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - wb.write(baos); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - - wb = new HSSFWorkbook(bais); - assertEquals(1, wb.getNumberOfSheets()); - - s = wb.getSheet("OSGi"); - assertEquals("With OSGi", s.getRow(0).getCell(0).toString()); - } -} diff --git a/trunk/osgi/test-bundles.xml b/trunk/osgi/test-bundles.xml deleted file mode 100644 index 11502761e..000000000 --- a/trunk/osgi/test-bundles.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - bundles - - dir - - false - - - - ${artifact.artifactId}.jar - - org.apache.poi:poi-bundle - - - - diff --git a/trunk/patch.xml b/trunk/patch.xml deleted file mode 100644 index ed52a91d7..000000000 --- a/trunk/patch.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/settings.gradle b/trunk/settings.gradle deleted file mode 100644 index de9c7e7cb..000000000 --- a/trunk/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -rootProject.name = 'poi' - -include 'main', 'ooxml', 'excelant', 'examples', 'scratchpad', 'integrationtest' - -project(':main').projectDir = new File(settingsDir, 'build/main') -project(':ooxml').projectDir = new File(settingsDir, 'build/ooxml') -project(':excelant').projectDir = new File(settingsDir, 'build/excelant') -project(':examples').projectDir = new File(settingsDir, 'build/examples') -project(':scratchpad').projectDir = new File(settingsDir, 'build/scratchpad') -project(':integrationtest').projectDir = new File(settingsDir, 'build/integrationtest') diff --git a/trunk/sonar/examples/pom.xml b/trunk/sonar/examples/pom.xml deleted file mode 100644 index ea53c0597..000000000 --- a/trunk/sonar/examples/pom.xml +++ /dev/null @@ -1,76 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - - poi-examples - jar - - Apache POI Examples package - - - - - - maven-resources-plugin - ${maven.plugin.resources.version} - - - copy-sources - - generate-sources - - copy-resources - - - ${basedir}/src/main/java - - - ../../src/examples/src - - - - - - - - - maven-clean-plugin - ${maven.plugin.clean.version} - - - - src - false - - - - - - - - - - ${project.groupId} - poi-main - ${project.version} - - - ${project.groupId} - poi-ooxml - ${project.version} - - - - - junit - junit - ${junit.version} - - - diff --git a/trunk/sonar/excelant/pom.xml b/trunk/sonar/excelant/pom.xml deleted file mode 100644 index a7b9408dc..000000000 --- a/trunk/sonar/excelant/pom.xml +++ /dev/null @@ -1,114 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - - poi-excelant - jar - - Apache POI ExcelAnt package - - - - - - maven-resources-plugin - ${maven.plugin.resources.version} - - - copy-sources - - generate-sources - - copy-resources - - - ${basedir}/src/main/java - - - ../../src/excelant/java - - - - - - copy-resources - - generate-resources - - copy-resources - - - ${basedir}/src/main/resources - - - ../../src/excelant/resources - - - - - - copy-tests - - generate-test-sources - - copy-resources - - - ${basedir}/src/test/java - - - ../../src/excelant/testcases - - - - - - - - - maven-clean-plugin - ${maven.plugin.clean.version} - - - - src - false - - - - - - - - - - ${project.groupId} - poi-main - ${project.version} - - - ${project.groupId} - poi-main - ${project.version} - test-jar - test - - - ${project.groupId} - poi-ooxml - ${project.version} - - - - org.apache.ant - ant - 1.8.2 - - - diff --git a/trunk/sonar/main/pom.xml b/trunk/sonar/main/pom.xml deleted file mode 100644 index 36422a83c..000000000 --- a/trunk/sonar/main/pom.xml +++ /dev/null @@ -1,129 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - - poi-main - jar - - Apache POI Main package - - - - - - maven-resources-plugin - ${maven.plugin.resources.version} - - - copy-sources - generate-sources - - copy-resources - - - ${basedir}/src/main/java - - - ../../src/java - - - - - - copy-resources - generate-resources - - copy-resources - - - ${basedir}/src/main/resources - - - ../../src/resources/main - - - - - - copy-tests - - generate-test-sources - - copy-resources - - - ${basedir}/src/test/java - - - ../../src/testcases - - - - - - - - - - maven-clean-plugin - ${maven.plugin.clean.version} - - - - src - false - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven.plugin.jar.version} - - - - test-jar - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.plugin.surefire.version} - - -Duser.language=en -Duser.country=US -Xmx1024m -XX:MaxPermSize=256m -XX:-OmitStackTraceInFastThrow - - - - - - - - org.apache.commons - commons-collections4 - 4.1 - - - commons-codec - commons-codec - 1.10 - - - commons-logging - commons-logging - 1.2 - - - diff --git a/trunk/sonar/ooxml-schema-encryption/pom.xml b/trunk/sonar/ooxml-schema-encryption/pom.xml deleted file mode 100644 index cbb2eff7d..000000000 --- a/trunk/sonar/ooxml-schema-encryption/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - .. - - poi-ooxml-schema-encryption - jar - - Apache POI - Openxmlformats Encryption Schema package - - - - target/generated-sources/* - - - - - - org.apache.maven.plugins - maven-antrun-plugin - ${maven.plugin.antrun.version} - - - unzip-schema - generate-sources - - run - - - - - - - - - - - - - - - - - org.apache.xmlbeans - xmlbeans - ${xmlbeans.version} - - - diff --git a/trunk/sonar/ooxml-schema-encryption/xmlbeans.marker b/trunk/sonar/ooxml-schema-encryption/xmlbeans.marker deleted file mode 100644 index 2744493ac..000000000 --- a/trunk/sonar/ooxml-schema-encryption/xmlbeans.marker +++ /dev/null @@ -1 +0,0 @@ -This purpose of this marker file is solely to activate the xmlbeans maven profile. \ No newline at end of file diff --git a/trunk/sonar/ooxml-schema-security/pom.xml b/trunk/sonar/ooxml-schema-security/pom.xml deleted file mode 100644 index a822c7343..000000000 --- a/trunk/sonar/ooxml-schema-security/pom.xml +++ /dev/null @@ -1,144 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - .. - - poi-ooxml-schema-security - jar - - Apache POI - Openxmlformats Security-Schema package - - - - target/generated-sources/* - true - true - true - - - - - - - com.googlecode.maven-download-plugin - maven-download-plugin - ${maven.plugin.download.version} - - - install-xsds-part-1 - generate-sources - wget - - http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%201st%20edition%20Part%202%20(PDF).zip - true - c8f0eac388691d5be0d1647146400a10 - - - - install-xsds-part-2 - generate-sources - wget - - target/schemas - http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd - - - - install-xsds-part-3 - generate-sources - wget - - target/schemas - http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd - - - - install-xsds-part-4 - generate-sources - wget - - target/schemas - http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd - - - - install-xsds-part-5 - generate-sources - wget - - target/schemas - http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd - - - - install-xsds-part-6 - generate-sources - wget - - target/schemas - http://uri.etsi.org/01903/v1.3.2/XAdES.xsd - - - - install-xsds-part-7 - generate-sources - wget - - target/schemas - http://uri.etsi.org/01903/v1.4.1/XAdESv141.xsd - - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - ${maven.plugin.antrun.version} - - - unzip-schema - generate-sources - - run - - - - - - - - - - - - - - - - - - org.apache.xmlbeans - xmlbeans - ${xmlbeans.version} - - - ${project.groupId} - poi-main - ${project.version} - - - ${project.groupId} - poi-scratchpad - ${project.version} - - - diff --git a/trunk/sonar/ooxml-schema-security/xmlbeans.marker b/trunk/sonar/ooxml-schema-security/xmlbeans.marker deleted file mode 100644 index 2744493ac..000000000 --- a/trunk/sonar/ooxml-schema-security/xmlbeans.marker +++ /dev/null @@ -1 +0,0 @@ -This purpose of this marker file is solely to activate the xmlbeans maven profile. \ No newline at end of file diff --git a/trunk/sonar/ooxml-schema/pom.xml b/trunk/sonar/ooxml-schema/pom.xml deleted file mode 100644 index 5e2b9fef5..000000000 --- a/trunk/sonar/ooxml-schema/pom.xml +++ /dev/null @@ -1,89 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - .. - - poi-ooxml-schema - jar - - Apache POI - Openxmlformats Schema package - - - - target/generated-sources/* - true - ${basedir}/../../src/ooxml/resources/org/apache/poi/schemas/ooxmlSchemas.xsdconfig - - - - - - - com.googlecode.maven-download-plugin - maven-download-plugin - ${maven.plugin.download.version} - - - download-xsds - generate-sources - - wget - - - http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%201st%20edition%20Part%204%20(PDF).zip - true - abe6bb6e7799e854934b3c634e8bcf7b - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - ${maven.plugin.antrun.version} - - - unzip-schema - generate-sources - - - - - - - - - run - - - - - - - - - - ${project.groupId} - poi-main - ${project.version} - - - ${project.groupId} - poi-scratchpad - ${project.version} - - - org.apache.xmlbeans - xmlbeans - ${xmlbeans.version} - - - diff --git a/trunk/sonar/ooxml-schema/xmlbeans.marker b/trunk/sonar/ooxml-schema/xmlbeans.marker deleted file mode 100644 index 2744493ac..000000000 --- a/trunk/sonar/ooxml-schema/xmlbeans.marker +++ /dev/null @@ -1 +0,0 @@ -This purpose of this marker file is solely to activate the xmlbeans maven profile. \ No newline at end of file diff --git a/trunk/sonar/ooxml/pom.xml b/trunk/sonar/ooxml/pom.xml deleted file mode 100644 index 27636cdfa..000000000 --- a/trunk/sonar/ooxml/pom.xml +++ /dev/null @@ -1,165 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - - poi-ooxml - jar - - Apache POI OOXML package - - - - - - maven-resources-plugin - ${maven.plugin.resources.version} - - - copy-sources - generate-sources - - copy-resources - - - ${basedir}/src/main/java - - - ../../src/ooxml/java - - - - - - copy-resources - generate-resources - - copy-resources - - - ${basedir}/src/main/resources - - - ../../src/resources/ooxml - - - - - - copy-tests - generate-test-sources - - copy-resources - - - ${basedir}/src/test/java - - - ../../src/ooxml/testcases - - - - - - - - - - maven-clean-plugin - ${maven.plugin.clean.version} - - - - src - false - - - build - false - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.plugin.surefire.version} - - -Duser.language=en -Duser.country=US -Xmx1024m -XX:MaxPermSize=256m -XX:-OmitStackTraceInFastThrow - - - - - - - - ${project.groupId} - poi-ooxml-schema - ${project.version} - - - ${project.groupId} - poi-ooxml-schema-encryption - ${project.version} - - - ${project.groupId} - poi-ooxml-schema-security - ${project.version} - - - ${project.groupId} - poi-main - ${project.version} - - - ${project.groupId} - poi-main - ${project.version} - test-jar - test - - - - org.apache.xmlbeans - xmlbeans - ${xmlbeans.version} - - - - org.bouncycastle - bcpkix-jdk15on - 1.54 - - - org.bouncycastle - bcprov-jdk15on - 1.54 - - - org.apache.santuario - xmlsec - 2.0.5 - - - com.github.virtuald - curvesapi - 1.04 - - - - - junit - junit - ${junit.version} - - - diff --git a/trunk/sonar/pom.xml b/trunk/sonar/pom.xml deleted file mode 100644 index 8e2a9fc42..000000000 --- a/trunk/sonar/pom.xml +++ /dev/null @@ -1,272 +0,0 @@ - - 4.0.0 - org.apache.poi - poi-parent - pom - 3.16-beta1-SNAPSHOT - Apache POI - the Java API for Microsoft Documents - Maven build of Apache POI for Sonar checks - http://poi.apache.org/ - - - - POI Users List - user-subscribe@poi.apache.org - user-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-user/ - - - POI Developer List - dev-subscribe@poi.apache.org - dev-unsubscribe@poi.apache.org - http://mail-archives.apache.org/mod_mbox/poi-dev/ - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - Apache Software Foundation - http://www.apache.org/ - - - - bugzilla - https://issues.apache.org/bugzilla/ - - - - scm:svn:http://svn.apache.org/repos/asf/poi/trunk - scm:svn:https://svn.apache.org/repos/asf/poi/trunk - http://svn.apache.org/viewvc/poi - - - - main - ooxml-schema - ooxml-schema-encryption - ooxml-schema-security - ooxml - scratchpad - excelant - examples - - - - ASCII - - true - - - 2.6.0 - 4.12 - 3.0.1 - 3.0.1 - 3.0.0 - 1.1.0 - 1.8 - 2.19.1 - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.5.1 - - 1.6 - 1.6 - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.plugin.surefire.version} - - - org.apache.maven.surefire - surefire-junit47 - ${maven.plugin.surefire.version} - - - - - ../../test-data - true - org.apache.poi.util.NullLogger - - - -Duser.language=en -Duser.country=US -Xmx1024m - - **/All*Tests.java - **/TestUnfixedBugs.java - **/TestcaseRecordInputStream.java - **/POITestCase.java - - **/TestWordToConverterSuite*.java - **/TestExcelConverterSuite*.java - - - - - - - - - - - junit - junit - ${junit.version} - test - - - - - - - - - - - - - 32bitstuff - - - sun.arch.data.model - 32 - - - - 512m - -Xmx768m -XX:MaxPermSize=128m @{argLine} - - - - - 64bitstuff - - - sun.arch.data.model - 64 - - - - 768m - -Xmx1024m -XX:MaxPermSize=256m @{argLine} - - - - - xmlbean - - xmlbeans.marker - - - - - org.codehaus.mojo - xmlbeans-maven-plugin - 2.3.3 - - - process-sources - - xmlbeans - - - ${basedir}/target/schemas - 1.5 - true - ${xmlbeans.noUpa} - ${xmlbeans.noPvr} - - ${basedir}/../../src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsdconfig - ${basedir}/../../src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsdconfig - ${basedir}/../../src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsdconfig - ${basedir}/../../src/ooxml/resources/org/apache/poi/schemas/ooxmlSchemas.xsdconfig - - - - - - - - maven-antrun-plugin - ${maven.plugin.antrun.version} - - - copy-xmltype-and-xsdconfig - generate-sources - run - - - - - - - - - - - - - - - - - - - - - - - replace-xmltypeloader - process-sources - run - - - - org.apache.xmlbeans.XmlBeans.getContextTypeLoader() - org.apache.poi.POIXMLTypeLoader - - - - - - remove-xmltypeloader-from-schema-jar - prepare-package - run - - - - - - - - - - - - - - org.apache.xmlbeans - xmlbeans - ${xmlbeans.version} - - - - - diff --git a/trunk/sonar/scratchpad/pom.xml b/trunk/sonar/scratchpad/pom.xml deleted file mode 100644 index 6760762d6..000000000 --- a/trunk/sonar/scratchpad/pom.xml +++ /dev/null @@ -1,109 +0,0 @@ - - 4.0.0 - - org.apache.poi - poi-parent - 3.16-beta1-SNAPSHOT - - poi-scratchpad - jar - - Apache POI Scratchpad package - - - - src/main/java/org/apache/poi/hwpf/model/types/*,src/main/java/org/apache/poi/hdf/model/hdftypes/definitions/* - - - - - - - - maven-resources-plugin - ${maven.plugin.resources.version} - - - copy-sources - - generate-sources - - copy-resources - - - ${basedir}/src/main/java - - - ../../src/scratchpad/src - - - - - - copy-resources - - generate-resources - - copy-resources - - - ${basedir}/src/main/resources - - - ../../src/resources/scratchpad - - - - - - copy-tests - - generate-test-sources - - copy-resources - - - ${basedir}/src/test/java - - - ../../src/scratchpad/testcases - - - - - - - - - maven-clean-plugin - ${maven.plugin.clean.version} - - - - src - false - - - - - - - - - - ${project.groupId} - poi-main - ${project.version} - - - ${project.groupId} - poi-main - ${project.version} - test-jar - test - - - diff --git a/trunk/src/contrib/poi-ruby/Makefile b/trunk/src/contrib/poi-ruby/Makefile deleted file mode 100644 index a298da329..000000000 --- a/trunk/src/contrib/poi-ruby/Makefile +++ /dev/null @@ -1,332 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# Makefile for building Poi4R -# -# Supported operating systems: Linux, Mac OS X and Windows. -# See INSTALL file for requirements. -# -# Steps to build -# 1. Edit the sections below as documented -# 2. make all -# 3. make install -# -# The install target installs the Poi4R python extension in python's -# site-packages directory. On Mac OS X, it also installs the gcj runtime -# libraries into $(PREFIX)/lib. -# -# To successfully import the Poi4R extension into Ruby, all required -# libraries need to be found. If the locations you chose are non-standard, -# the relevant DYLD_LIBRARY_PATH (Mac OS X), LD_LIBRARY_PATH (Linux), or -# PATH (Windows) need to be set accordingly. -# - - -VERSION=0.1.0 -POI_VER=$(shell grep ' -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "org/apache/poi/hssf/usermodel/HSSFWorkbook.h" -#include "org/apache/poi/hssf/usermodel/HSSFSheet.h" -#include "org/apache/poi/hssf/usermodel/HSSFRow.h" -#include "org/apache/poi/hssf/usermodel/HSSFCell.h" -#include "org/apache/poi/hssf/usermodel/HSSFFont.h" -#include "org/apache/poi/hssf/usermodel/HSSFCellStyle.h" -#include "org/apache/poi/hssf/usermodel/HSSFDataFormat.h" -#include "org/apache/poi/hssf/usermodel/HSSFHeader.h" -#include "org/apache/poi/hssf/usermodel/HSSFFooter.h" -#include "org/apache/poi/RubyOutputStream.h" - - -typedef ::org::apache::poi::hssf::usermodel::HSSFWorkbook *jhworkbook; -typedef ::org::apache::poi::hssf::usermodel::HSSFSheet *jhsheet; -typedef ::org::apache::poi::hssf::usermodel::HSSFRow *jhrow; -typedef ::org::apache::poi::hssf::usermodel::HSSFCell *jhcell; -typedef ::org::apache::poi::hssf::usermodel::HSSFCellStyle *jhcellstyle; -typedef ::org::apache::poi::hssf::usermodel::HSSFFont *jhfont; -typedef ::org::apache::poi::hssf::usermodel::HSSFFooter *jhfooter; -typedef ::org::apache::poi::hssf::usermodel::HSSFHeader *jhheader; -typedef ::org::apache::poi::hssf::usermodel::HSSFDataFormat *jhdataformat; - -typedef ::java::util::Date *jdate; -typedef ::java::util::Calendar *jcalendar; -typedef ::java::io::OutputStream *joutputstream; -typedef ::java::io::InputStream *jinputstream; -typedef ::java::util::Collection *jstringCollection; -typedef ::java::util::Collection *jtermCollection; -typedef ::java::util::Locale *jlocale; -typedef ::java::lang::Comparable *jcomparable; -typedef JArray *jobjectArray; -typedef JArray *jstringArray; - - -static java::lang::Thread *nextThread; -static java::util::HashMap *objects; - - -static void store_reference(jobject object) { - java::lang::Integer *ji =new java::lang::Integer(java::lang::System::identityHashCode(object)); - jobject jo = objects->get(ji); - if (!jo) { - // printf("put object in hash\n"); - objects->put(ji,object); - } -} -static VALUE jo2rv(jobject object, swig_type_info *descriptor) -{ - if (object == NULL) - { - return Qnil; - } - else - { - return SWIG_NewPointerObj((void *) object, descriptor, 0); - } -} -static int cvtptr(VALUE value, void **jo, swig_type_info *info) -{ - if (SWIG_ConvertPtr(value, jo, info, 0) == 0) - return 0; - else - { - return -1; - } -} - -static int rv2jo(VALUE rv, jobject *jo, swig_type_info *descriptor) -{ - if (NIL_P(rv)) - *jo = NULL; - else - { - java::lang::Object *javaObj; - - if (cvtptr(rv, (void **) &javaObj, descriptor) == -1) - return 0; - - *jo = javaObj; - } - - return 1; -} - - -static jstring r2j(VALUE object) -{ - if (NIL_P(object)){ - return NULL; - } - else { - char *ps = STR2CSTR(object); - jstring js = JvNewStringLatin1(ps); - - if (!js) - { - rb_raise(rb_eRuntimeError, "ruby str cannot be converted to java: %s",ps); - } - - return js; - } -} - -VALUE j2r(jstring js) -{ - if (!js) - { - return Qnil; - } - else - { - jint len = JvGetStringUTFLength(js); - char buf[len + 1]; - - JvGetStringUTFRegion(js, 0, len, buf); - buf[len] = '\0'; - - return rb_str_new2(buf); - } -} - -static void free_java_obj(void* arg1) { - jobject object =(jobject) arg1; - java::lang::Integer *ji =new java::lang::Integer(java::lang::System::identityHashCode(object)); - jobject jo = objects->get(ji); - if (jo) { - // printf("removed object from hash\n"); - objects->remove(ji); - } -} - -static void raise_ruby_error(java::lang::Throwable *e) { - java::io::StringWriter *buffer = new java::io::StringWriter(); - java::io::PrintWriter *writer = new java::io::PrintWriter(buffer); - e->printStackTrace(writer); - writer->close(); - jstring message = buffer->toString(); - jint len = JvGetStringUTFLength(message); - char buf[len + 1]; - JvGetStringUTFRegion(message, 0, len, buf); - buf[len] = '\0'; - rb_raise(rb_eRuntimeError, "error calling poi \n %s", buf); -} - -%} - -typedef long jint; -typedef long long jlong; -typedef char jbyte; -typedef float jfloat; -typedef float jdouble; -typedef int jshort; -typedef bool jboolean; - -%typemap(in) SWIGTYPE * { - - if (!rv2jo($input, (jobject *) &$1, $1_descriptor)) - rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping"); -} -%typemap(out) SWIGTYPE * { - - $result = jo2rv($1, $1_descriptor); -} - -%typemap(in) org::apache::poi::hssf::usermodel::HSSFWorkbook{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFWorkbook *))) - SWIG_fail; -} -%typemap(out) org::apache::poi::hssf::usermodel::HSSFWorkbook { - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFWorkbook *)); -} - -%typemap(in) jhsheet{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFSheet *))) - SWIG_fail; -} -%typemap(out) jhsheet { - - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFSheet *)); -} -%typemap(in) jhrow{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFRow *))) - SWIG_fail; -} -%typemap(out) jhrow { - - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFRow *)); -} -%typemap(in) jhcell{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFCell *))) - SWIG_fail; -} -%typemap(out) jhcell { - - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFCell *)); -} -%typemap(in) jhfont{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFFont *))) - rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping of HSSFFont"); -} - -%typemap(out) jhfont { - - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFFont *)); -} - -%typemap(in) jhcellstyle{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFCellStyle *))) - rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping of HSSFCellStyle"); -} -%typemap(out) jhcellstyle { - - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFCellStyle *)); -} -%typemap(in) jhdataformat{ - - if (!rv2jo($input, (jobject *) &$1, - $descriptor(org::apache::poi::hssf::usermodel::HSSFDataFormat *))) - rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping of HSSFDataFormat"); -} -%typemap(out) jhdataformat { - - $result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFDataFormat *)); -} - - -%typemap(in) jstring { - $1 = r2j($input); -} -%typemap(out) jstring { - $result = j2r($1); -} -%typecheck(SWIG_TYPECHECK_STRING) jstring { - $1 = ( NIL_P($input) || TYPE($input)==T_STRING ); -} - -%typemap(in) joutputstream { - - jlong ptr; - if (!rb_respond_to($input, rb_intern("putc"))) rb_raise(rb_eTypeError,"Expected IO"); - *(VALUE *) &ptr = (VALUE) $input; - $1 = new org::apache::poi::RubyOutputStream(ptr); -} -%typemap(in) jcalendar { - $1 = java::util::Calendar::getInstance(); - //$1->setTimeInMillis((long long) NUM2DBL(rb_funcall($input,rb_intern("to_i"),0,NULL))*1000.0); - $1->set(FIX2INT(rb_funcall($input,rb_intern("year"),0,NULL)), - FIX2INT(rb_funcall($input,rb_intern("mon"),0,NULL))-1, - FIX2INT(rb_funcall($input,rb_intern("day"),0,NULL)), - FIX2INT(rb_funcall($input,rb_intern("hour"),0,NULL)), - FIX2INT(rb_funcall($input,rb_intern("min"),0,NULL)), - FIX2INT(rb_funcall($input,rb_intern("sec"),0,NULL)) - ); -} - -%typecheck(SWIG_TYPECHECK_POINTER) jcalendar { - $1 = rb_respond_to($input, rb_intern("asctime")); -} - -%typemap(out) jdate { - jlong t = ((jdate) $1)->getTime(); - //TODO: separate seconds and microsecs - int ts=t/1000; - $result=rb_time_new((time_t) ts, 0 ); -} - - -%freefunc org::apache::poi::hssf::usermodel::HSSFWorkbook "free_java_obj"; - -%exception { - try { - $action - } catch (java::lang::Throwable *e) { - raise_ruby_error(e); - } -} -%exception org::apache::poi::hssf::usermodel::HSSFWorkbook::HSSFWorkbook { - try { - $action - store_reference(result); - } catch (java::lang::Throwable *e) { - raise_ruby_error(e); - } -} - - - - -namespace java { - namespace lang { - class Object { - jstring toString(); - }; -%nodefault; - class System : public Object { - public: - static jstring getProperty(jstring); - static jstring getProperty(jstring, jstring); - static void load(jstring); - static void loadLibrary(jstring); - static void mapLibraryName(jstring); - static void runFinalization(); - static void setProperty(jstring, jstring); - }; -%makedefault; - } - namespace io { -%nodefault; - class InputStream : public ::java::lang::Object { - }; - class OutputStream : public ::java::lang::Object { - }; - -%makedefault; - } - namespace util { - class Date : public ::java::lang::Object { - public: - Date(); - Date(jlong); - void setTime(jlong); - jstring toString(); - }; - } -} - - -namespace org { - namespace apache { - namespace poi { - namespace hssf { - namespace usermodel { -%nodefault; - class HSSFWorkbook : public ::java::lang::Object { - public: - HSSFWorkbook(); - jstring getSheetName(jint); - jint getNumberOfSheets(); - void setSheetOrder(jstring,jint); - void setSheetName(jint,jstring); - void setSheetName(jint,jstring,jshort); - jint getSheetIndex(jstring); - jhsheet createSheet(); - jhsheet cloneSheet(jint); - jhsheet createSheet(jstring); - jhsheet getSheetAt(jint); - jhsheet getSheet(jstring); - void removeSheetAt(jint); - jhcellstyle createCellStyle(); - jhfont createFont(); - jhdataformat createDataFormat(); - void write(joutputstream); - - }; - - class HSSFSheet : public ::java::lang::Object { - public: - jhrow createRow(jint); - jhrow getRow(jint); - jhfooter getFooter(); - jhheader getHeader(); - }; - class HSSFRow : public ::java::lang::Object { - public: - jhcell createCell(jshort); - jhcell getCell(jshort); - //jboolean getProtect(); //only in 2.5 - - }; - class HSSFCell : public ::java::lang::Object { - public: - void setCellValue(jdouble); - void setCellValue(jstring); - void setCellValue(jboolean); - void setCellValue(jcalendar); - void setCellFormula(jstring); - jstring getStringCellValue(); - jdouble getNumericCellValue(); - jdate getDateCellValue(); - jstring getCellFormula(); - jboolean getBooleanCellValue(); - jint getCellType(); - jshort getEncoding(); - void setAsActiveCell(); - - void setCellStyle(jhcellstyle); - void setEncoding(jshort encoding); - - static const jint CELL_TYPE_BLANK; - static const jint CELL_TYPE_BOOLEAN; - static const jint CELL_TYPE_ERROR; - static const jint CELL_TYPE_FORMULA; - static const jint CELL_TYPE_NUMERIC; - static const jint CELL_TYPE_STRING; - - static const jshort ENCODING_COMPRESSED_UNICODE; - static const jshort ENCODING_UTF_16; - }; - class HSSFCellStyle : public ::java::lang::Object { - public: - static const jshort ALIGN_CENTER; - static const jshort ALIGN_CENTER_SELECTION; - static const jshort ALIGN_FILL; - static const jshort ALIGN_GENERAL; - static const jshort ALIGN_JUSTIFY; - static const jshort ALIGN_LEFT; - static const jshort ALIGN_RIGHT; - static const jshort ALT_BARS; - static const jshort BIG_SPOTS; - static const jshort BORDER_DASH_DOT; - static const jshort BORDER_DASH_DOT_DOT; - static const jshort BORDER_DASHED; - static const jshort BORDER_DOTTED; - static const jshort BORDER_DOUBLE; - static const jshort BORDER_HAIR; - static const jshort BORDER_MEDIUM; - static const jshort BORDER_MEDIUM_DASH_DOT; - static const jshort BORDER_MEDIUM_DASH_DOT_DOT; - static const jshort BORDER_MEDIUM_DASHED; - static const jshort BORDER_NONE; - static const jshort BORDER_SLANTED_DASH_DOT; - static const jshort BORDER_THICK; - static const jshort BORDER_THIN; - static const jshort BRICKS; - static const jshort DIAMONDS; - static const jshort FINE_DOTS; - static const jshort NO_FILL; - static const jshort SOLID_FOREGROUND; - static const jshort SPARSE_DOTS; - static const jshort SQUARES; - static const jshort THICK_BACKWARD_DIAG; - static const jshort THICK_FORWARD_DIAG; - static const jshort THICK_HORZ_BANDS; - static const jshort THICK_VERT_BANDS; - static const jshort THIN_BACKWARD_DIAG; - static const jshort THIN_FORWARD_DIAG; - static const jshort THIN_HORZ_BANDS; - static const jshort THIN_VERT_BANDS; - static const jshort VERTICAL_BOTTOM; - static const jshort VERTICAL_CENTER; - static const jshort VERTICAL_JUSTIFY; - static const jshort VERTICAL_TOP; - - jshort getAlignment(); - jshort getBorderBottom(); - jshort getBorderLeft(); - jshort getBorderRight(); - jshort getBorderTop(); - jshort getBottomBorderColor(); - jshort getDataFormat(); - jshort getFillBackgroundColor(); - jshort getFillForegroundColor(); - jshort getFillPattern(); - jshort getFontIndex(); - jboolean getHidden(); - jshort getIndention(); - jshort getIndex(); - jshort getLeftBorderColor(); - jboolean getLocked(); - jshort getRightBorderColor(); - jshort getRotation(); - jshort getTopBorderColor(); - jshort getVerticalAlignment(); - jboolean getWrapText(); - void setAlignment(jshort) ; - void setBorderBottom(jshort ); - void setBorderLeft(jshort ); - void setBorderRight(jshort ); - void setBorderTop(jshort ); - void setBottomBorderColor(jshort ); - void setDataFormat(jshort ); - void setFillBackgroundColor(jshort ); - void setFillForegroundColor(jshort ); - void setFillPattern(jshort ); - void setFont(jhfont ); - void setHidden(jboolean ); - void setIndention(jshort ); - void setLeftBorderColor(jshort ); - void setLocked(jboolean ); - void setRightBorderColor(jshort ); - void setRotation(jshort ); - void setTopBorderColor(jshort ); - void setVerticalAlignment(jshort ); - void setWrapText(jboolean ); - }; - class HSSFDataFormat : public ::java::lang::Object { - public: - static jstring getBuiltinFormat(jshort); - static jshort getBuiltinFormat(jstring); - jstring getFormat(jshort); - jshort getFormat(jstring); - static jint getNumberOfBuiltinBuiltinFormats(); - //TODO static jlist getBuiltinFormats(); - - }; - class HSSFFont : public ::java::lang::Object { - public: - static const jshort BOLDWEIGHT_BOLD; -static const jshort BOLDWEIGHT_NORMAL; -static const jshort COLOR_NORMAL; -static const jshort COLOR_RED; -static const jstring FONT_ARIAL; -static const jshort SS_NONE; -static const jshort SS_SUB; -static const jshort SS_SUPER; -static const jshort U_DOUBLE; -static const jshort U_DOUBLE_ACCOUNTING; -static const jshort U_NONE; -static const jshort U_SINGLE; -static const jshort U_SINGLE_ACCOUNTING; - - jshort getBoldweight(); - jshort getColor(); - jshort getFontHeight(); - jshort getFontHeightInPoints(); - jstring getFontName(); - jshort getIndex(); - jboolean getItalic(); - jboolean getStrikeout(); - jshort getTypeOffset(); - jshort getUnderline(); - void setBoldweight(jshort ); - void setColor(jshort ); - void setFontHeight(jshort ); - void setFontHeightInPoints(jshort ); - void setFontName(jstring ); - void setItalic(jboolean ); - void setStrikeout(jboolean ); - void setTypeOffset(jshort ); - void setUnderline(jshort ); -}; -%makedefault; - } - } - } - } -} - - - - - -%init %{ - - JvCreateJavaVM(NULL); - JvAttachCurrentThread(NULL, NULL); - - nextThread = new java::lang::Thread(); - objects = new java::util::HashMap(); - - java::util::HashMap *props = (java::util::HashMap *) - java::lang::System::getProperties(); - props->put(JvNewStringUTF("inRuby"), objects); - - JvInitClass(&org::apache::poi::hssf::usermodel::HSSFFont::class$); - JvInitClass(&org::apache::poi::hssf::usermodel::HSSFCell::class$); - JvInitClass(&org::apache::poi::hssf::usermodel::HSSFSheet::class$); - JvInitClass(&org::apache::poi::hssf::usermodel::HSSFCellStyle::class$); - -%} - diff --git a/trunk/src/contrib/poi-ruby/cpp/RubyIO.cpp b/trunk/src/contrib/poi-ruby/cpp/RubyIO.cpp deleted file mode 100644 index d4a4638cf..000000000 --- a/trunk/src/contrib/poi-ruby/cpp/RubyIO.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -#include - -#include "ruby.h" -#include "org/apache/poi/RubyOutputStream.h" - - -/** - * The native functions declared in org.apache.poi.RubyoutputStream - * - * @author aviks - */ - - namespace org { - namespace apache { - namespace poi { - - void RubyOutputStream::close(void) - { - rb_funcall3((VALUE ) rubyIO, rb_intern("close"), 0, NULL); - } - - void RubyOutputStream::write(jint toWrite) - { - rb_funcall((VALUE ) rubyIO, rb_intern("putc"),1,INT2FIX(toWrite)); - } - } - } -} diff --git a/trunk/src/contrib/poi-ruby/java/org/apache/poi/RubyOutputStream.java b/trunk/src/contrib/poi-ruby/java/org/apache/poi/RubyOutputStream.java deleted file mode 100644 index e23a0a7d3..000000000 --- a/trunk/src/contrib/poi-ruby/java/org/apache/poi/RubyOutputStream.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.OutputStream; -import java.io.IOException; - -/** - * @author aviks - * Wrap a java.io.OutputStream around a Ruby IO object - */ - -public class RubyOutputStream extends OutputStream { - - //pointer to native ruby VALUE - protected long rubyIO; - - public RubyOutputStream (long rubyIO) - { - this.rubyIO = rubyIO; -// incRef(); - } - - @Override - protected void finalize() - throws Throwable - { -// decRef(); - } - -// protected native void incRef(); -// protected native void decRef(); - - @Override - public native void close() - throws IOException; - - - /* (non-Javadoc) - * @see java.io.OutputStream#write(int) - */ - @Override - public native void write(int arg0) throws IOException; -} - diff --git a/trunk/src/contrib/poi-ruby/tests/tc_base_tests.rb b/trunk/src/contrib/poi-ruby/tests/tc_base_tests.rb deleted file mode 100644 index 33492c7ab..000000000 --- a/trunk/src/contrib/poi-ruby/tests/tc_base_tests.rb +++ /dev/null @@ -1,100 +0,0 @@ -# ==================================================================== -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ==================================================================== - -require 'test/unit' -require 'release/poi4r' - -class TC_base_tests < Test::Unit::TestCase - - def setup() - end - - def test_get_constant - h=Poi4r::HSSFWorkbook.new - s=h.createSheet("Sheet1") - r=s.createRow(0) - c=r.createCell(0) - assert_equal(3,Poi4r::HSSFCell.CELL_TYPE_BLANK,"Constant CELL_TYPE_BLANK") - end - - def test_base - system("rm test.xls") - h=Poi4r::HSSFWorkbook.new - - #Test Sheet Creation - s=h.createSheet("Sheet1") - s=h.createSheet("Sheet2") - assert_equal(2,h.getNumberOfSheets(),"Number of sheets is 2") - - #Test setting cell values - s=h.getSheetAt(0) - r=s.createRow(0) - c=r.createCell(0) - c.setCellValue(1.5) - assert_equal(c.getNumericCellValue(),1.5,"Numeric Cell Value") - c=r.createCell(1) - c.setCellValue("Ruby") - assert_equal(c.getStringCellValue(),"Ruby","String Cell Value") - #Test error handling - assert_raise (RuntimeError) {c.getNumericCellValue()} - - #Test styles - st = h.createCellStyle() - c=r.createCell(2) - st.setAlignment(Poi4r::HSSFCellStyle.ALIGN_CENTER) - c.setCellStyle(st) - c.setCellValue("centr'd") - - #Date handling - c=r.createCell(3) - t1=Time.now - c.setCellValue(Time.now) - t2= c.getDateCellValue().gmtime - assert_equal(t1.year,t2.year,"year") - assert_equal(t1.mon,t2.mon,"month") - assert_equal(t1.day,t2.day,"day") - assert_equal(t1.hour,t2.hour,"hour") - assert_equal(t1.min,t2.min,"min") - assert_equal(t1.sec,t2.sec,"sec") - st=h.createCellStyle(); - st.setDataFormat(Poi4r::HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm")) - c.setCellStyle(st) - - #Fonts - c=r.createCell(4) - font = h.createFont(); - font.setFontHeightInPoints(24); - font.setFontName("Courier New"); - font.setItalic(true); - font.setStrikeout(true); - style = h.createCellStyle(); - style.setFont(font); - c.setCellValue("This is a test of fonts"); - c.setCellStyle(style); - - #Formulas - c=r.createCell(5) - c.setCellFormula("A1*2") - assert_equal("A1*2",c.getCellFormula,"formula") - - #Test writing - h.write(File.new("test.xls","w")) - assert_nothing_raised {File.new("test.xls","r")} - #h.write(0.1) - end - -end diff --git a/trunk/src/contrib/poi-ruby/tests/tc_gc.rb b/trunk/src/contrib/poi-ruby/tests/tc_gc.rb deleted file mode 100644 index 82c3c2b13..000000000 --- a/trunk/src/contrib/poi-ruby/tests/tc_gc.rb +++ /dev/null @@ -1,32 +0,0 @@ -# ==================================================================== -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ==================================================================== - -require 'test/unit' -require 'release/poi4r' - -class TC_gc < Test::Unit::TestCase - def test_premature_collection - h=Poi4r::HSSFWorkbook.new - h.createSheet("Sheet1"); - 5000.times do - hh=Poi4r::HSSFWorkbook.new - GC.start() - end - assert_equal(1,h.getNumberOfSheets(),"Number of sheets") - end -end - diff --git a/trunk/src/contrib/poi-ruby/tests/ts_all.rb b/trunk/src/contrib/poi-ruby/tests/ts_all.rb deleted file mode 100644 index ef50ad5d6..000000000 --- a/trunk/src/contrib/poi-ruby/tests/ts_all.rb +++ /dev/null @@ -1,20 +0,0 @@ -# ==================================================================== -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ==================================================================== - -require 'test/unit' -require 'tests/tc_base_tests' -require 'tests/tc_gc' diff --git a/trunk/src/contrib/testcases/dummy.txt b/trunk/src/contrib/testcases/dummy.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/trunk/src/examples/jsp/HSSFExample.jsp b/trunk/src/examples/jsp/HSSFExample.jsp deleted file mode 100644 index b641846bd..000000000 --- a/trunk/src/examples/jsp/HSSFExample.jsp +++ /dev/null @@ -1,116 +0,0 @@ - -<%@page contentType="text/html" -import="java.io.*,org.apache.poi.poifs.filesystem.POIFSFileSystem,org.apache.poi -.hssf.record.*,org.apache.poi.hssf.model.*,org.apache.poi.hssf.usermodel.*,org.a -pache.poi.hssf.util.*" %> - -Read Excel file - - -An example of using Jakarta POI's HSSF package to read an excel spreadsheet: - - -
-Select an Excel file to read. - -
- -<% - String filename = request.getParameter("xls_filename"); - if (filename != null && !filename.equals("")) { -%> -
You chose the file <%= filename %>. -

It's contents are: -<% - try - { - - // create a poi workbook from the excel spreadsheet file - POIFSFileSystem fs = - new POIFSFileSystem(new FileInputStream(filename)); - HSSFWorkbook wb = new HSSFWorkbook(fs); - - for (int k = 0; k < wb.getNumberOfSheets(); k++) - { -%> -

Sheet <%= k %>
-<% - - HSSFSheet sheet = wb.getSheetAt(k); - int rows = sheet.getPhysicalNumberOfRows(); - - for (int r = 0; r < rows; r++) - { - HSSFRow row = sheet.getRow(r); - if (row != null) { - int cells = row.getPhysicalNumberOfCells(); -%> -
ROW <%= -row.getRowNum() %> -<% - for (short c = 0; c < cells; c++) - { - HSSFCell cell = row.getCell(c); - if (cell != null) { - String value = null; - - switch (cell.getCellType()) - { - - case HSSFCell.CELL_TYPE_FORMULA : - value = "FORMULA "; - break; - - case HSSFCell.CELL_TYPE_NUMERIC : - value = "NUMERIC value=" - + cell.getNumericCellValue -(); - break; - - case HSSFCell.CELL_TYPE_STRING : - value = "STRING value=" - + cell.getStringCellValue(); - break; - - default : - } -%> - <%= "CELL col=" - - + cell.getColumnIndex() - + " VALUE=" + value %> -<% - } - } - } - } - } - } - catch (Exception e) - { -%> - Error occurred: <%= e.getMessage() %> -<% - e.printStackTrace(); - } - - } -%> - - - diff --git a/trunk/src/examples/lib/dummy.txt b/trunk/src/examples/lib/dummy.txt deleted file mode 100644 index ee37f4519..000000000 --- a/trunk/src/examples/lib/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Dummy file so this directory is not deleted by CVS. It's required for the build. \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/crypt/examples/EncryptionUtils.java b/trunk/src/examples/src/org/apache/poi/crypt/examples/EncryptionUtils.java deleted file mode 100644 index c2b795cb5..000000000 --- a/trunk/src/examples/src/org/apache/poi/crypt/examples/EncryptionUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.crypt.examples; - -import java.io.InputStream; - -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; - -public class EncryptionUtils { - private EncryptionUtils() { - } - - public static InputStream decrypt(final InputStream inputStream, final String pwd) throws Exception { - try { - POIFSFileSystem fs = new POIFSFileSystem(inputStream); - EncryptionInfo info = new EncryptionInfo(fs); - Decryptor d = Decryptor.getInstance(info); - if (!d.verifyPassword(pwd)) { - throw new RuntimeException("incorrect password"); - } - return d.getDataStream(fs); - } finally { - IOUtils.closeQuietly(inputStream); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/examples/util/TempFileUtils.java b/trunk/src/examples/src/org/apache/poi/examples/util/TempFileUtils.java deleted file mode 100644 index 5d4f7ab53..000000000 --- a/trunk/src/examples/src/org/apache/poi/examples/util/TempFileUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.examples.util; - -import java.io.File; -import java.io.IOException; - -import org.apache.poi.util.TempFile; - -public class TempFileUtils { - private TempFileUtils() { - } - - public static void checkTempFiles() throws IOException { - String tmpDir = System.getProperty(TempFile.JAVA_IO_TMPDIR) + "/poifiles"; - File tempDir = new File(tmpDir); - if(tempDir.exists()) { - String[] tempFiles = tempDir.list(); - if(tempFiles != null && tempFiles.length > 0) { - System.out.println("found files in poi temp dir " + tempDir.getAbsolutePath()); - for(String filename : tempFiles) { - System.out.println("file: " + filename); - } - } - } else { - System.out.println("unable to find poi temp dir"); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java b/trunk/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java deleted file mode 100644 index 43ea2e9d8..000000000 --- a/trunk/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java +++ /dev/null @@ -1,503 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.examples; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.hpsf.HPSFRuntimeException; -import org.apache.poi.hpsf.MarkUnsupportedException; -import org.apache.poi.hpsf.MutablePropertySet; -import org.apache.poi.hpsf.NoPropertySetStreamException; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.Util; -import org.apache.poi.hpsf.WritingNotSupportedException; -import org.apache.poi.poifs.eventfilesystem.POIFSReader; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentEntry; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.TempFile; - -/** - *

This class copies a POI file system to a new file and compares the copy - * with the original.

- * - *

Property set streams are copied logically, i.e. the application - * establishes a {@link org.apache.poi.hpsf.PropertySet} of an original property - * set, creates a {@link org.apache.poi.hpsf.MutablePropertySet} from the - * {@link org.apache.poi.hpsf.PropertySet} and writes the - * {@link org.apache.poi.hpsf.MutablePropertySet} to the destination POI file - * system. - Streams which are no property set streams are copied bit by - * bit.

- * - *

The comparison of the POI file systems is done logically. That means that - * the two disk files containing the POI file systems do not need to be - * exactly identical. However, both POI file systems must contain the same - * files, and most of these files must be bitwise identical. Property set - * streams, however, are compared logically: they must have the same sections - * with the same attributs, and the sections must contain the same properties. - * Details like the ordering of the properties do not matter.

- */ -public class CopyCompare -{ - /** - *

Runs the example program. The application expects one or two - * arguments:

- * - *
    - * - *
  1. The first argument is the disk file name of the POI filesystem to - * copy.

  2. - * - *
  3. The second argument is optional. If it is given, it is the name of - * a disk file the copy of the POI filesystem will be written to. If it is - * not given, the copy will be written to a temporary file which will be - * deleted at the end of the program.

  4. - * - *
- * - * @param args Command-line arguments. - * @exception MarkUnsupportedException if a POI document stream does not - * support the mark() operation. - * @exception NoPropertySetStreamException if the application tries to - * create a property set from a POI document stream that is not a property - * set stream. - * @exception IOException if any I/O exception occurs. - * @exception UnsupportedEncodingException if a character encoding is not - * supported. - */ - public static void main(final String[] args) - throws NoPropertySetStreamException, MarkUnsupportedException, - UnsupportedEncodingException, IOException - { - String originalFileName = null; - String copyFileName = null; - - /* Check the command-line arguments. */ - if (args.length == 1) { - originalFileName = args[0]; - File f = TempFile.createTempFile("CopyOfPOIFileSystem-", ".ole2"); - f.deleteOnExit(); - copyFileName = f.getAbsolutePath(); - } else if (args.length == 2) { - originalFileName = args[0]; - copyFileName = args[1]; - } else { - System.err.println("Usage: " + CopyCompare.class.getName() + - "originPOIFS [copyPOIFS]"); - System.exit(1); - } - - /* Read the origin POIFS using the eventing API. The real work is done - * in the class CopyFile which is registered here as a POIFSReader. */ - final POIFSReader r = new POIFSReader(); - final CopyFile cf = new CopyFile(copyFileName); - r.registerListener(cf); - FileInputStream fis = new FileInputStream(originalFileName); - r.read(fis); - fis.close(); - - /* Write the new POIFS to disk. */ - cf.close(); - - /* Read all documents from the original POI file system and compare them - * with the equivalent document from the copy. */ - final POIFSFileSystem opfs = new POIFSFileSystem(new File(originalFileName)); - final POIFSFileSystem cpfs = new POIFSFileSystem(new File(copyFileName)); - - final DirectoryEntry oRoot = opfs.getRoot(); - final DirectoryEntry cRoot = cpfs.getRoot(); - final StringBuffer messages = new StringBuffer(); - if (equal(oRoot, cRoot, messages)) { - System.out.println("Equal"); - } else { - System.out.println("Not equal: " + messages.toString()); - } - cpfs.close(); - opfs.close(); - } - - - - /** - *

Compares two {@link DirectoryEntry} instances of a POI file system. - * The directories must contain the same streams with the same names and - * contents.

- * - * @param d1 The first directory. - * @param d2 The second directory. - * @param msg The method may append human-readable comparison messages to - * this string buffer. - * @return true if the directories are equal, else - * false. - * @exception MarkUnsupportedException if a POI document stream does not - * support the mark() operation. - * @exception NoPropertySetStreamException if the application tries to - * create a property set from a POI document stream that is not a property - * set stream. - * @throws UnsupportedEncodingException - * @exception IOException if any I/O exception occurs. - */ - private static boolean equal(final DirectoryEntry d1, - final DirectoryEntry d2, - final StringBuffer msg) - throws NoPropertySetStreamException, MarkUnsupportedException, - UnsupportedEncodingException, IOException - { - boolean equal = true; - /* Iterate over d1 and compare each entry with its counterpart in d2. */ - for (final Entry e1 : d1) { - final String n1 = e1.getName(); - Entry e2 = null; - try { - e2 = d2.getEntry(n1); - } catch (FileNotFoundException ex) { - msg.append("Document \"" + e1 + "\" exists, document \"" + - e2 + "\" does not.\n"); - equal = false; - break; - } - - if (e1.isDirectoryEntry() && e2.isDirectoryEntry()) { - equal = equal((DirectoryEntry) e1, (DirectoryEntry) e2, msg); - } else if (e1.isDocumentEntry() && e2.isDocumentEntry()) { - equal = equal((DocumentEntry) e1, (DocumentEntry) e2, msg); - } else { - msg.append("One of \"" + e1 + "\" and \"" + e2 + "\" is a " + - "document while the other one is a directory.\n"); - equal = false; - } - } - - /* Iterate over d2 just to make sure that there are no entries in d2 - * that are not in d1. */ - for (final Entry e2 : d2) { - final String n2 = e2.getName(); - Entry e1 = null; - try { - e1 = d1.getEntry(n2); - } catch (FileNotFoundException ex) { - msg.append("Document \"" + e2 + "\" exitsts, document \"" + - e1 + "\" does not.\n"); - equal = false; - break; - } - } - return equal; - } - - - - /** - *

Compares two {@link DocumentEntry} instances of a POI file system. - * Documents that are not property set streams must be bitwise identical. - * Property set streams must be logically equal.

- * - * @param d1 The first document. - * @param d2 The second document. - * @param msg The method may append human-readable comparison messages to - * this string buffer. - * @return true if the documents are equal, else - * false. - * @exception MarkUnsupportedException if a POI document stream does not - * support the mark() operation. - * @exception NoPropertySetStreamException if the application tries to - * create a property set from a POI document stream that is not a property - * set stream. - * @throws UnsupportedEncodingException - * @exception IOException if any I/O exception occurs. - */ - private static boolean equal(final DocumentEntry d1, final DocumentEntry d2, - final StringBuffer msg) - throws NoPropertySetStreamException, MarkUnsupportedException, - UnsupportedEncodingException, IOException - { - boolean equal = true; - final DocumentInputStream dis1 = new DocumentInputStream(d1); - final DocumentInputStream dis2 = new DocumentInputStream(d2); - try { - if (PropertySet.isPropertySetStream(dis1) && - PropertySet.isPropertySetStream(dis2)) { - final PropertySet ps1 = PropertySetFactory.create(dis1); - final PropertySet ps2 = PropertySetFactory.create(dis2); - equal = ps1.equals(ps2); - if (!equal) { - msg.append("Property sets are not equal.\n"); - return equal; - } - } else { - int i1; - int i2; - do { - i1 = dis1.read(); - i2 = dis2.read(); - if (i1 != i2) { - equal = false; - msg.append("Documents are not equal.\n"); - break; - } - } while (equal && i1 == -1); - } - } finally { - dis2.close(); - dis1.close(); - } - return true; - } - - - - /** - *

This class does all the work. Its method {@link - * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each file in - * the original POI file system. Except for property set streams it copies - * everything unmodified to the destination POI filesystem. Property set - * streams are copied by creating a new {@link PropertySet} from the - * original property set by using the {@link - * MutablePropertySet#MutablePropertySet(PropertySet)} constructor.

- */ - static class CopyFile implements POIFSReaderListener { - String dstName; - OutputStream out; - POIFSFileSystem poiFs; - - - /** - *

The constructor of a {@link CopyFile} instance creates the target - * POIFS. It also stores the name of the file the POIFS will be written - * to once it is complete.

- * - * @param dstName The name of the disk file the destination POIFS is to - * be written to. - */ - public CopyFile(final String dstName) { - this.dstName = dstName; - poiFs = new POIFSFileSystem(); - } - - - /** - *

The method is called by POI's eventing API for each file in the - * origin POIFS.

- */ - @Override - public void processPOIFSReaderEvent(final POIFSReaderEvent event) { - /* The following declarations are shortcuts for accessing the - * "event" object. */ - final POIFSDocumentPath path = event.getPath(); - final String name = event.getName(); - final DocumentInputStream stream = event.getStream(); - - Throwable t = null; - - try { - /* Find out whether the current document is a property set - * stream or not. */ - if (PropertySet.isPropertySetStream(stream)) { - /* Yes, the current document is a property set stream. - * Let's create a PropertySet instance from it. */ - PropertySet ps = null; - try { - ps = PropertySetFactory.create(stream); - } catch (NoPropertySetStreamException ex) { - /* This exception will not be thrown because we already - * checked above. */ - } - - /* Copy the property set to the destination POI file - * system. */ - copy(poiFs, path, name, ps); - } else { - /* No, the current document is not a property set stream. We - * copy it unmodified to the destination POIFS. */ - copy(poiFs, event.getPath(), event.getName(), stream); - } - } catch (MarkUnsupportedException ex) { - t = ex; - } catch (IOException ex) { - t = ex; - } catch (WritingNotSupportedException ex) { - t = ex; - } - - /* According to the definition of the processPOIFSReaderEvent method - * we cannot pass checked exceptions to the caller. The following - * lines check whether a checked exception occured and throws an - * unchecked exception. The message of that exception is that of - * the underlying checked exception. */ - if (t != null) { - throw new HPSFRuntimeException - ("Could not read file \"" + path + "/" + name + - "\". Reason: " + Util.toString(t)); - } - } - - - - /** - *

Writes a {@link PropertySet} to a POI filesystem.

- * - * @param poiFs The POI filesystem to write to. - * @param path The file's path in the POI filesystem. - * @param name The file's name in the POI filesystem. - * @param ps The property set to write. - * @throws WritingNotSupportedException - * @throws IOException - */ - public void copy(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final PropertySet ps) - throws WritingNotSupportedException, IOException { - final DirectoryEntry de = getPath(poiFs, path); - final MutablePropertySet mps = new MutablePropertySet(ps); - de.createDocument(name, mps.toInputStream()); - } - - - - /** - *

Copies the bytes from a {@link DocumentInputStream} to a new - * stream in a POI filesystem.

- * - * @param poiFs The POI filesystem to write to. - * @param path The source document's path. - * @param name The source document's name. - * @param stream The stream containing the source document. - * @throws IOException - */ - public void copy(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final DocumentInputStream stream) - throws IOException { - final DirectoryEntry de = getPath(poiFs, path); - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - int c; - while ((c = stream.read()) != -1) { - out.write(c); - } - stream.close(); - out.close(); - final InputStream in = - new ByteArrayInputStream(out.toByteArray()); - de.createDocument(name, in); - } - - - /** - *

Writes the POI file system to a disk file.

- * - * @throws FileNotFoundException - * @throws IOException - */ - public void close() throws FileNotFoundException, IOException { - out = new FileOutputStream(dstName); - poiFs.writeFilesystem(out); - out.close(); - } - - - - /** Contains the directory paths that have already been created in the - * output POI filesystem and maps them to their corresponding - * {@link org.apache.poi.poifs.filesystem.DirectoryNode}s. */ - private final Map paths = new HashMap(); - - - - /** - *

Ensures that the directory hierarchy for a document in a POI - * fileystem is in place. When a document is to be created somewhere in - * a POI filesystem its directory must be created first. This method - * creates all directories between the POI filesystem root and the - * directory the document should belong to which do not yet exist.

- * - *

Unfortunately POI does not offer a simple method to interrogate - * the POIFS whether a certain child node (file or directory) exists in - * a directory. However, since we always start with an empty POIFS which - * contains the root directory only and since each directory in the - * POIFS is created by this method we can maintain the POIFS's directory - * hierarchy ourselves: The {@link DirectoryEntry} of each directory - * created is stored in a {@link Map}. The directories' path names map - * to the corresponding {@link DirectoryEntry} instances.

- * - * @param poiFs The POI filesystem the directory hierarchy is created - * in, if needed. - * @param path The document's path. This method creates those directory - * components of this hierarchy which do not yet exist. - * @return The directory entry of the document path's parent. The caller - * should use this {@link DirectoryEntry} to create documents in it. - */ - public DirectoryEntry getPath(final POIFSFileSystem poiFs, - final POIFSDocumentPath path) { - try { - /* Check whether this directory has already been created. */ - final String s = path.toString(); - DirectoryEntry de = paths.get(s); - if (de != null) - /* Yes: return the corresponding DirectoryEntry. */ - return de; - - /* No: We have to create the directory - or return the root's - * DirectoryEntry. */ - int l = path.length(); - if (l == 0) { - /* Get the root directory. It does not have to be created - * since it always exists in a POIFS. */ - de = poiFs.getRoot(); - } else { - /* Create a subordinate directory. The first step is to - * ensure that the parent directory exists: */ - de = getPath(poiFs, path.getParent()); - /* Now create the target directory: */ - de = de.createDirectory(path.getComponent - (path.length() - 1)); - } - paths.put(s, de); - return de; - } catch (IOException ex) { - /* This exception will be thrown if the directory already - * exists. However, since we have full control about directory - * creation we can ensure that this will never happen. */ - ex.printStackTrace(System.err); - throw new RuntimeException(ex.toString()); - /* FIXME (2): Replace the previous line by the following once we - * no longer need JDK 1.3 compatibility. */ - // throw new RuntimeException(ex); - } - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hpsf/examples/ModifyDocumentSummaryInformation.java b/trunk/src/examples/src/org/apache/poi/hpsf/examples/ModifyDocumentSummaryInformation.java deleted file mode 100644 index 81a9594e7..000000000 --- a/trunk/src/examples/src/org/apache/poi/hpsf/examples/ModifyDocumentSummaryInformation.java +++ /dev/null @@ -1,173 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.examples; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Date; - -import org.apache.poi.hpsf.CustomProperties; -import org.apache.poi.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.MarkUnsupportedException; -import org.apache.poi.hpsf.NoPropertySetStreamException; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.UnexpectedPropertySetTypeException; -import org.apache.poi.hpsf.WritingNotSupportedException; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; - -/** - *

This is a sample application showing how to easily modify properties in - * the summary information and in the document summary information. The - * application reads the name of a POI filesystem from the command line and - * performs the following actions:

- * - *
    - * - *
  • Open the POI filesystem.

  • - * - *
  • Read the summary information.

  • - * - *
  • Read and print the "author" property.

  • - * - *
  • Change the author to "Rainer Klute".

  • - * - *
  • Read the document summary information.

  • - * - *
  • Read and print the "category" property.

  • - * - *
  • Change the category to "POI example".

  • - * - *
  • Read the custom properties (if available).

  • - * - *
  • Insert a new custom property.

  • - * - *
  • Write the custom properties back to the document summary - * information.

  • - * - *
  • Write the summary information to the POI filesystem.

  • - * - *
  • Write the document summary information to the POI filesystem.

  • - * - *
  • Write the POI filesystem back to the original file.

  • - * - * - */ -public class ModifyDocumentSummaryInformation { - - /** - *

    Main method - see class description.

    - * - * @param args The command-line parameters. - * @throws IOException - * @throws MarkUnsupportedException - * @throws NoPropertySetStreamException - * @throws UnexpectedPropertySetTypeException - * @throws WritingNotSupportedException - */ - public static void main(final String[] args) throws IOException, - NoPropertySetStreamException, MarkUnsupportedException, - UnexpectedPropertySetTypeException, WritingNotSupportedException - { - /* Read the name of the POI filesystem to modify from the command line. - * For brevity to boundary check is performed on the command-line - * arguments. */ - File summaryFile = new File(args[0]); - - /* Open the POI filesystem. */ - NPOIFSFileSystem poifs = new NPOIFSFileSystem(summaryFile, false); - - /* Read the summary information. */ - DirectoryEntry dir = poifs.getRoot(); - SummaryInformation si; - try - { - si = (SummaryInformation)PropertySetFactory.create( - dir, SummaryInformation.DEFAULT_STREAM_NAME); - } - catch (FileNotFoundException ex) - { - // There is no summary information yet. We have to create a new one - si = PropertySetFactory.newSummaryInformation(); - } - - /* Change the author to "Rainer Klute". Any former author value will - * be lost. If there has been no author yet, it will be created. */ - si.setAuthor("Rainer Klute"); - System.out.println("Author changed to " + si.getAuthor() + "."); - - - /* Handling the document summary information is analogous to handling - * the summary information. An additional feature, however, are the - * custom properties. */ - - /* Read the document summary information. */ - DocumentSummaryInformation dsi; - try - { - dsi = (DocumentSummaryInformation)PropertySetFactory.create( - dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME); - } - catch (FileNotFoundException ex) - { - /* There is no document summary information yet. We have to create a - * new one. */ - dsi = PropertySetFactory.newDocumentSummaryInformation(); - } - - /* Change the category to "POI example". Any former category value will - * be lost. If there has been no category yet, it will be created. */ - dsi.setCategory("POI example"); - System.out.println("Category changed to " + dsi.getCategory() + "."); - - /* Read the custom properties. If there are no custom properties yet, - * the application has to create a new CustomProperties object. It will - * serve as a container for custom properties. */ - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null) - customProperties = new CustomProperties(); - - /* Insert some custom properties into the container. */ - customProperties.put("Key 1", "Value 1"); - customProperties.put("Schl\u00fcssel 2", "Wert 2"); - customProperties.put("Sample Number", new Integer(12345)); - customProperties.put("Sample Boolean", Boolean.TRUE); - customProperties.put("Sample Date", new Date()); - - /* Read a custom property. */ - Object value = customProperties.get("Sample Number"); - System.out.println("Custom Sample Number is now " + value); - - /* Write the custom properties back to the document summary - * information. */ - dsi.setCustomProperties(customProperties); - - /* Write the summary information and the document summary information - * to the POI filesystem. */ - si.write(dir, SummaryInformation.DEFAULT_STREAM_NAME); - dsi.write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME); - - /* Write the POI filesystem back to the original file. Please note that - * in production code you should take care when write directly to the - * origin, to make sure you don't loose things on error */ - poifs.writeFilesystem(); - poifs.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java b/trunk/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java deleted file mode 100644 index 964984211..000000000 --- a/trunk/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.examples; - -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hpsf.NoPropertySetStreamException; -import org.apache.poi.hpsf.Property; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.Section; -import org.apache.poi.poifs.eventfilesystem.POIFSReader; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener; -import org.apache.poi.util.HexDump; - -/** - *

    Sample application showing how to read a document's custom property set. - * Call it with the document's file name as command-line parameter.

    - * - *

    Explanations can be found in the HPSF HOW-TO.

    - */ -public class ReadCustomPropertySets -{ - - /** - *

    Runs the example program.

    - * - * @param args Command-line arguments (unused). - * @throws IOException if any I/O exception occurs. - */ - public static void main(final String[] args) - throws IOException - { - final String filename = args[0]; - POIFSReader r = new POIFSReader(); - - /* Register a listener for *all* documents. */ - r.registerListener(new MyPOIFSReaderListener()); - r.read(new FileInputStream(filename)); - } - - - static class MyPOIFSReaderListener implements POIFSReaderListener - { - @Override - public void processPOIFSReaderEvent(final POIFSReaderEvent event) - { - PropertySet ps = null; - try - { - ps = PropertySetFactory.create(event.getStream()); - } - catch (NoPropertySetStreamException ex) - { - out("No property set stream: \"" + event.getPath() + - event.getName() + "\""); - return; - } - catch (Exception ex) - { - throw new RuntimeException - ("Property set stream \"" + - event.getPath() + event.getName() + "\": " + ex); - } - - /* Print the name of the property set stream: */ - out("Property set stream \"" + event.getPath() + - event.getName() + "\":"); - - /* Print the number of sections: */ - final long sectionCount = ps.getSectionCount(); - out(" No. of sections: " + sectionCount); - - /* Print the list of sections: */ - List
    sections = ps.getSections(); - int nr = 0; - for (Iterator
    i = sections.iterator(); i.hasNext();) - { - /* Print a single section: */ - Section sec = i.next(); - out(" Section " + nr++ + ":"); - String s = hex(sec.getFormatID().getBytes()); - s = s.substring(0, s.length() - 1); - out(" Format ID: " + s); - - /* Print the number of properties in this section. */ - int propertyCount = sec.getPropertyCount(); - out(" No. of properties: " + propertyCount); - - /* Print the properties: */ - Property[] properties = sec.getProperties(); - for (int i2 = 0; i2 < properties.length; i2++) - { - /* Print a single property: */ - Property p = properties[i2]; - long id = p.getID(); - long type = p.getType(); - Object value = p.getValue(); - out(" Property ID: " + id + ", type: " + type + - ", value: " + value); - } - } - } - } - - static void out(final String msg) - { - System.out.println(msg); - } - - static String hex(final byte[] bytes) - { - return HexDump.dump(bytes, 0L, 0); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hpsf/examples/ReadTitle.java b/trunk/src/examples/src/org/apache/poi/hpsf/examples/ReadTitle.java deleted file mode 100644 index 180544410..000000000 --- a/trunk/src/examples/src/org/apache/poi/hpsf/examples/ReadTitle.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.examples; - -import java.io.FileInputStream; -import java.io.IOException; - -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.poifs.eventfilesystem.POIFSReader; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener; - -/** - *

    Sample application showing how to read a OLE 2 document's - * title. Call it with the document's file name as command line - * parameter.

    - * - *

    Explanations can be found in the HPSF HOW-TO.

    - */ -public class ReadTitle -{ - /** - *

    Runs the example program.

    - * - * @param args Command-line arguments. The first command-line argument must - * be the name of a POI filesystem to read. - * @throws IOException if any I/O exception occurs. - */ - public static void main(final String[] args) throws IOException - { - final String filename = args[0]; - POIFSReader r = new POIFSReader(); - r.registerListener(new MyPOIFSReaderListener(), - "\005SummaryInformation"); - r.read(new FileInputStream(filename)); - } - - - static class MyPOIFSReaderListener implements POIFSReaderListener - { - @Override - public void processPOIFSReaderEvent(final POIFSReaderEvent event) - { - SummaryInformation si = null; - try - { - si = (SummaryInformation) - PropertySetFactory.create(event.getStream()); - } - catch (Exception ex) - { - throw new RuntimeException - ("Property set stream \"" + - event.getPath() + event.getName() + "\": " + ex); - } - final String title = si.getTitle(); - if (title != null) - System.out.println("Title: \"" + title + "\""); - else - System.out.println("Document has no title."); - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java b/trunk/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java deleted file mode 100644 index d08d778b0..000000000 --- a/trunk/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java +++ /dev/null @@ -1,420 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.examples; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.hpsf.HPSFRuntimeException; -import org.apache.poi.hpsf.MarkUnsupportedException; -import org.apache.poi.hpsf.MutablePropertySet; -import org.apache.poi.hpsf.MutableSection; -import org.apache.poi.hpsf.NoPropertySetStreamException; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.Util; -import org.apache.poi.hpsf.Variant; -import org.apache.poi.hpsf.WritingNotSupportedException; -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.poifs.eventfilesystem.POIFSReader; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - *

    This class is a sample application which shows how to write or modify the - * author and title property of an OLE 2 document. This could be done in two - * different ways:

    - * - *
      - * - *
    • The first approach is to open the OLE 2 file as a POI filesystem - * (see class {@link POIFSFileSystem}), read the summary information property - * set (see classes {@link SummaryInformation} and {@link PropertySet}), write - * the author and title properties into it and write the property set back into - * the POI filesystem.

    • - * - *
    • The second approach does not modify the original POI filesystem, but - * instead creates a new one. All documents from the original POIFS are copied - * to the destination POIFS, except for the summary information stream. The - * latter is modified by setting the author and title property before writing - * it to the destination POIFS. It there are several summary information streams - * in the original POIFS - e.g. in subordinate directories - they are modified - * just the same.

    • - * - *
    - * - *

    This sample application takes the second approach. It expects the name of - * the existing POI filesystem's name as its first command-line parameter and - * the name of the output POIFS as the second command-line argument. The - * program then works as described above: It copies nearly all documents - * unmodified from the input POI filesystem to the output POI filesystem. If it - * encounters a summary information stream it reads its properties. Then it sets - * the "author" and "title" properties to new values and writes the modified - * summary information stream into the output file.

    - * - *

    Further explanations can be found in the HPSF HOW-TO.

    - */ -public class WriteAuthorAndTitle -{ - /** - *

    Runs the example program.

    - * - * @param args Command-line arguments. The first command-line argument must - * be the name of a POI filesystem to read. - * @throws IOException if any I/O exception occurs. - */ - public static void main(final String[] args) throws IOException - { - /* Check whether we have exactly two command-line arguments. */ - if (args.length != 2) - { - System.err.println("Usage: " + WriteAuthorAndTitle.class.getName() + - " originPOIFS destinationPOIFS"); - System.exit(1); - } - - /* Read the names of the origin and destination POI filesystems. */ - final String srcName = args[0]; - final String dstName = args[1]; - - /* Read the origin POIFS using the eventing API. The real work is done - * in the class ModifySICopyTheRest which is registered here as a - * POIFSReader. */ - final POIFSReader r = new POIFSReader(); - final ModifySICopyTheRest msrl = new ModifySICopyTheRest(dstName); - r.registerListener(msrl); - FileInputStream fis = new FileInputStream(srcName); - r.read(fis); - fis.close(); - - /* Write the new POIFS to disk. */ - msrl.close(); - } - - - - /** - *

    This class does all the work. As its name implies it modifies a - * summary information property set and copies everything else unmodified - * to the destination POI filesystem. Since an instance of it is registered - * as a {@link POIFSReader} its method {@link - * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each document - * in the origin POIFS.

    - */ - static class ModifySICopyTheRest implements POIFSReaderListener - { - String dstName; - OutputStream out; - POIFSFileSystem poiFs; - - - /** - *

    The constructor of a {@link ModifySICopyTheRest} instance creates - * the target POIFS. It also stores the name of the file the POIFS will - * be written to once it is complete.

    - * - * @param dstName The name of the disk file the destination POIFS is to - * be written to. - */ - public ModifySICopyTheRest(final String dstName) - { - this.dstName = dstName; - poiFs = new POIFSFileSystem(); - } - - - /** - *

    The method is called by POI's eventing API for each file in the - * origin POIFS.

    - */ - @Override - public void processPOIFSReaderEvent(final POIFSReaderEvent event) - { - /* The following declarations are shortcuts for accessing the - * "event" object. */ - final POIFSDocumentPath path = event.getPath(); - final String name = event.getName(); - final DocumentInputStream stream = event.getStream(); - - Throwable t = null; - - try - { - /* Find out whether the current document is a property set - * stream or not. */ - if (PropertySet.isPropertySetStream(stream)) - { - /* Yes, the current document is a property set stream. - * Let's create a PropertySet instance from it. */ - PropertySet ps = null; - try - { - ps = PropertySetFactory.create(stream); - } - catch (NoPropertySetStreamException ex) - { - /* This exception will not be thrown because we already - * checked above. */ - } - - /* Now we know that we really have a property set. The next - * step is to find out whether it is a summary information - * or not. */ - if (ps.isSummaryInformation()) - /* Yes, it is a summary information. We will modify it - * and write the result to the destination POIFS. */ - editSI(poiFs, path, name, ps); - else - /* No, it is not a summary information. We don't care - * about its internals and copy it unmodified to the - * destination POIFS. */ - copy(poiFs, path, name, ps); - } - else - /* No, the current document is not a property set stream. We - * copy it unmodified to the destination POIFS. */ - copy(poiFs, event.getPath(), event.getName(), stream); - } - catch (MarkUnsupportedException ex) - { - t = ex; - } - catch (IOException ex) - { - t = ex; - } - catch (WritingNotSupportedException ex) - { - t = ex; - } - - /* According to the definition of the processPOIFSReaderEvent method - * we cannot pass checked exceptions to the caller. The following - * lines check whether a checked exception occured and throws an - * unchecked exception. The message of that exception is that of - * the underlying checked exception. */ - if (t != null) - { - throw new HPSFRuntimeException - ("Could not read file \"" + path + "/" + name + - "\". Reason: " + Util.toString(t)); - } - } - - - /** - *

    Receives a summary information property set modifies (or creates) - * its "author" and "title" properties and writes the result under the - * same path and name as the origin to a destination POI filesystem.

    - * - * @param poiFs The POI filesystem to write to. - * @param path The original (and destination) stream's path. - * @param name The original (and destination) stream's name. - * @param si The property set. It should be a summary information - * property set. - * @throws IOException - * @throws WritingNotSupportedException - */ - public void editSI(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final PropertySet si) - throws WritingNotSupportedException, IOException - - { - /* Get the directory entry for the target stream. */ - final DirectoryEntry de = getPath(poiFs, path); - - /* Create a mutable property set as a copy of the original read-only - * property set. */ - final MutablePropertySet mps = new MutablePropertySet(si); - - /* Retrieve the section containing the properties to modify. A - * summary information property set contains exactly one section. */ - final MutableSection s = - (MutableSection) mps.getSections().get(0); - - /* Set the properties. */ - s.setProperty(PropertyIDMap.PID_AUTHOR, Variant.VT_LPSTR, - "Rainer Klute"); - s.setProperty(PropertyIDMap.PID_TITLE, Variant.VT_LPWSTR, - "Test"); - - /* Create an input stream containing the bytes the property set - * stream consists of. */ - final InputStream pss = mps.toInputStream(); - - /* Write the property set stream to the POIFS. */ - de.createDocument(name, pss); - } - - - /** - *

    Writes a {@link PropertySet} to a POI filesystem. This method is - * simpler than {@link #editSI} because the origin property set has just - * to be copied.

    - * - * @param poiFs The POI filesystem to write to. - * @param path The file's path in the POI filesystem. - * @param name The file's name in the POI filesystem. - * @param ps The property set to write. - * @throws WritingNotSupportedException - * @throws IOException - */ - public void copy(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final PropertySet ps) - throws WritingNotSupportedException, IOException - { - final DirectoryEntry de = getPath(poiFs, path); - final MutablePropertySet mps = new MutablePropertySet(ps); - de.createDocument(name, mps.toInputStream()); - } - - - - /** - *

    Copies the bytes from a {@link DocumentInputStream} to a new - * stream in a POI filesystem.

    - * - * @param poiFs The POI filesystem to write to. - * @param path The source document's path. - * @param name The source document's name. - * @param stream The stream containing the source document. - * @throws IOException - */ - public void copy(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final DocumentInputStream stream) throws IOException - { - final DirectoryEntry de = getPath(poiFs, path); - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - int c; - while ((c = stream.read()) != -1) - out.write(c); - stream.close(); - out.close(); - final InputStream in = - new ByteArrayInputStream(out.toByteArray()); - de.createDocument(name, in); - } - - - /** - *

    Writes the POI file system to a disk file.

    - * - * @throws FileNotFoundException - * @throws IOException - */ - public void close() throws FileNotFoundException, IOException - { - out = new FileOutputStream(dstName); - poiFs.writeFilesystem(out); - out.close(); - } - - - - /** Contains the directory paths that have already been created in the - * output POI filesystem and maps them to their corresponding - * {@link org.apache.poi.poifs.filesystem.DirectoryNode}s. */ - private final Map paths = new HashMap(); - - - - /** - *

    Ensures that the directory hierarchy for a document in a POI - * fileystem is in place. When a document is to be created somewhere in - * a POI filesystem its directory must be created first. This method - * creates all directories between the POI filesystem root and the - * directory the document should belong to which do not yet exist.

    - * - *

    Unfortunately POI does not offer a simple method to interrogate - * the POIFS whether a certain child node (file or directory) exists in - * a directory. However, since we always start with an empty POIFS which - * contains the root directory only and since each directory in the - * POIFS is created by this method we can maintain the POIFS's directory - * hierarchy ourselves: The {@link DirectoryEntry} of each directory - * created is stored in a {@link Map}. The directories' path names map - * to the corresponding {@link DirectoryEntry} instances.

    - * - * @param poiFs The POI filesystem the directory hierarchy is created - * in, if needed. - * @param path The document's path. This method creates those directory - * components of this hierarchy which do not yet exist. - * @return The directory entry of the document path's parent. The caller - * should use this {@link DirectoryEntry} to create documents in it. - */ - public DirectoryEntry getPath(final POIFSFileSystem poiFs, - final POIFSDocumentPath path) - { - try - { - /* Check whether this directory has already been created. */ - final String s = path.toString(); - DirectoryEntry de = paths.get(s); - if (de != null) - /* Yes: return the corresponding DirectoryEntry. */ - return de; - - /* No: We have to create the directory - or return the root's - * DirectoryEntry. */ - int l = path.length(); - if (l == 0) - /* Get the root directory. It does not have to be created - * since it always exists in a POIFS. */ - de = poiFs.getRoot(); - else - { - /* Create a subordinate directory. The first step is to - * ensure that the parent directory exists: */ - de = getPath(poiFs, path.getParent()); - /* Now create the target directory: */ - de = de.createDirectory(path.getComponent - (path.length() - 1)); - } - paths.put(s, de); - return de; - } - catch (IOException ex) - { - /* This exception will be thrown if the directory already - * exists. However, since we have full control about directory - * creation we can ensure that this will never happen. */ - ex.printStackTrace(System.err); - throw new RuntimeException(ex); - } - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hpsf/examples/WriteTitle.java b/trunk/src/examples/src/org/apache/poi/hpsf/examples/WriteTitle.java deleted file mode 100644 index e57ef17b4..000000000 --- a/trunk/src/examples/src/org/apache/poi/hpsf/examples/WriteTitle.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hpsf.MutableProperty; -import org.apache.poi.hpsf.MutablePropertySet; -import org.apache.poi.hpsf.MutableSection; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.Variant; -import org.apache.poi.hpsf.WritingNotSupportedException; -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.hpsf.wellknown.SectionIDMap; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - *

    This class is a simple sample application showing how to create a property - * set and write it to disk.

    - */ -public class WriteTitle -{ - /** - *

    Runs the example program.

    - * - * @param args Command-line arguments. The first and only command-line - * argument is the name of the POI file system to create. - * @throws IOException if any I/O exception occurs. - * @throws WritingNotSupportedException if HPSF does not (yet) support - * writing a certain property type. - */ - public static void main(final String[] args) - throws WritingNotSupportedException, IOException - { - /* Check whether we have exactly one command-line argument. */ - if (args.length != 1) - { - System.err.println("Usage: " + WriteTitle.class.getName() + - "destinationPOIFS"); - System.exit(1); - } - - final String fileName = args[0]; - - /* Create a mutable property set. Initially it contains a single section - * with no properties. */ - final MutablePropertySet mps = new MutablePropertySet(); - - /* Retrieve the section the property set already contains. */ - final MutableSection ms = (MutableSection) mps.getSections().get(0); - - /* Turn the property set into a summary information property. This is - * done by setting the format ID of its first section to - * SectionIDMap.SUMMARY_INFORMATION_ID. */ - ms.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID); - - /* Create an empty property. */ - final MutableProperty p = new MutableProperty(); - - /* Fill the property with appropriate settings so that it specifies the - * document's title. */ - p.setID(PropertyIDMap.PID_TITLE); - p.setType(Variant.VT_LPWSTR); - p.setValue("Sample title"); - - /* Place the property into the section. */ - ms.setProperty(p); - - /* Create the POI file system the property set is to be written to. */ - final POIFSFileSystem poiFs = new POIFSFileSystem(); - - /* For writing the property set into a POI file system it has to be - * handed over to the POIFS.createDocument() method as an input stream - * which produces the bytes making out the property set stream. */ - final InputStream is = mps.toInputStream(); - - /* Create the summary information property set in the POI file - * system. It is given the default name most (if not all) summary - * information property sets have. */ - poiFs.createDocument(is, SummaryInformation.DEFAULT_STREAM_NAME); - - /* Write the whole POI file system to a disk file. */ - poiFs.writeFilesystem(new FileOutputStream(fileName)); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java deleted file mode 100644 index 578c3a679..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java +++ /dev/null @@ -1,456 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.sl.draw.DrawTableShape; -import org.apache.poi.sl.draw.SLGraphics; -import org.apache.poi.sl.usermodel.AutoShape; -import org.apache.poi.sl.usermodel.GroupShape; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.TableCell; -import org.apache.poi.sl.usermodel.TableShape; -import org.apache.poi.sl.usermodel.TextBox; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.sl.usermodel.TextRun; -import org.apache.poi.sl.usermodel.TextShape.TextPlaceholder; -import org.apache.poi.sl.usermodel.VerticalAlignment; - -/** - * Presentation for Fast Feather Track on ApacheconEU 2008 - * - * @author Yegor Kozlov - */ -public final class ApacheconEU08 { - - public static void main(String[] args) throws IOException { - SlideShow ppt = new HSLFSlideShow(); - // SlideShow ppt = new XMLSlideShow(); - ppt.setPageSize(new Dimension(720, 540)); - - slide1(ppt); - slide2(ppt); - slide3(ppt); - slide4(ppt); - slide5(ppt); - slide6(ppt); - slide7(ppt); - slide8(ppt); - slide9(ppt); - slide10(ppt); - slide11(ppt); - slide12(ppt); - - String ext = ppt.getClass().getName().contains("HSLF") ? "ppt" : "pptx"; - FileOutputStream out = new FileOutputStream("apachecon_eu_08."+ext); - ppt.write(out); - out.close(); - ppt.close(); - } - - public static void slide1(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.CENTER_TITLE); - box1.setText("POI-HSLF"); - box1.setAnchor(new Rectangle(54, 78, 612, 115)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.CENTER_BODY); - box2.setText("Java API To Access Microsoft PowerPoint Format Files"); - box2.setAnchor(new Rectangle(108, 204, 504, 138)); - - TextBox box3 = slide.createTextBox(); - box3.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(32d); - box3.setText( - "Yegor Kozlov\r" + - "yegor - apache - org"); - box3.setHorizontalCentered(true); - box3.setAnchor(new Rectangle(206, 348, 310, 84)); - } - - public static void slide2(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("What is HSLF?"); - box1.setAnchor(new Rectangle(36, 21, 648, 90)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.BODY); - box2.setText("HorribleSLideshowFormat is the POI Project's pure Java implementation " + - "of the Powerpoint binary file format. \r" + - "POI sub-project since 2005\r" + - "Started by Nick Burch, Yegor Kozlov joined soon after"); - box2.setAnchor(new Rectangle(36, 126, 648, 356)); - } - - public static void slide3(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("HSLF in a Nutshell"); - box1.setAnchor(new Rectangle(36, 15, 648, 65)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.BODY); - box2.setText( - "HSLF provides a way to read, create and modify MS PowerPoint presentations\r" + - "Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" + - "Comprehensive support of PowerPoint objects\r" + - "Rich text\r" + - "Tables\r" + - "Shapes\r" + - "Pictures\r" + - "Master slides\r" + - "Access to low level data structures" - ); - - List> tp = box2.getTextParagraphs(); - for (int i : new byte[]{0,1,2,8}) { - tp.get(i).getTextRuns().get(0).setFontSize(28d); - } - for (int i : new byte[]{3,4,5,6,7}) { - tp.get(i).getTextRuns().get(0).setFontSize(24d); - tp.get(i).setIndentLevel(1); - } - box2.setAnchor(new Rectangle(36, 80, 648, 400)); - } - - public static void slide4(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - String[][] txt1 = { - {"Note"}, - {"This presentation was created programmatically using POI HSLF"} - }; - TableShape table1 = slide.createTable(2, 1); - for (int i = 0; i < txt1.length; i++) { - for (int j = 0; j < txt1[i].length; j++) { - TableCell cell = table1.getCell(i, j); - cell.setText(txt1[i][j]); - TextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0); - rt.setFontSize(10d); - rt.setFontFamily("Arial"); - rt.setBold(true); - if(i == 0){ - rt.setFontSize(32d); - rt.setFontColor(Color.white); - cell.setFillColor(new Color(0, 153, 204)); - } else { - rt.setFontSize(28d); - cell.setFillColor(new Color(235, 239, 241)); - } - cell.setVerticalAlignment(VerticalAlignment.MIDDLE); - } - } - - DrawTableShape dts = new DrawTableShape(table1); - dts.setAllBorders(1.0, Color.black); - dts.setOutsideBorders(4.0); - - table1.setColumnWidth(0, 450); - table1.setRowHeight(0, 50); - table1.setRowHeight(1, 80); - - Dimension dim = ppt.getPageSize(); - Rectangle2D oldAnchor = table1.getAnchor(); - table1.setAnchor(new Rectangle2D.Double((dim.width-450)/2d, 100, oldAnchor.getWidth(), oldAnchor.getHeight())); - - TextBox box1 = slide.createTextBox(); - box1.setHorizontalCentered(true); - box1.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(24d); - box1.setText("The source code is available at\r" + - "http://people.apache.org/~yegor/apachecon_eu08/"); - box1.setAnchor(new Rectangle(80, 356, 553, 65)); - } - - public static void slide5(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("HSLF in Action - 1\rData Extraction"); - box1.setAnchor(new Rectangle(36, 21, 648, 100)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.BODY); - box2.setText( - "Text from slides and notes\r" + - "Images\r" + - "Shapes and their properties (type, position in the slide, color, font, etc.)"); - box2.setAnchor(new Rectangle(36, 150, 648, 300)); - } - - public static void slide6(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("HSLF in Action - 2"); - box1.setAnchor(new Rectangle(36, 20, 648, 90)); - - TextBox box2 = slide.createTextBox(); - box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d); - box2.setText("Creating a simple presentation from scratch"); - box2.setAnchor(new Rectangle(170, 100, 364, 30)); - - TextBox box3 = slide.createTextBox(); - TextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0); - rt3.setFontFamily("Courier New"); - rt3.setFontSize(8d); - box3.setText( - "SlideShow ppt = new SlideShow();\u000b" + - "Slide slide = ppt.createSlide();\u000b" + - "\u000b" + - "TextBox box2 = new TextBox();\u000b" + - "box2.setHorizontalAlignment(TextBox.AlignCenter);\u000b" + - "box2.setVerticalAlignment(TextBox.AnchorMiddle);\u000b" + - "box2.getTextRun().setText(\"Java Code\");\u000b" + - "box2.getFill().setForegroundColor(new Color(187, 224, 227));\u000b" + - "box2.setLineColor(Color.black);\u000b" + - "box2.setLineWidth(0.75);\u000b" + - "box2.setAnchor(new Rectangle(66, 243, 170, 170));\u000b" + - "slide.addShape(box2);\u000b" + - "\u000b" + - "TextBox box3 = new TextBox();\u000b" + - "box3.setHorizontalAlignment(TextBox.AlignCenter);\u000b" + - "box3.setVerticalAlignment(TextBox.AnchorMiddle);\u000b" + - "box3.getTextRun().setText(\"*.ppt file\");\u000b" + - "box3.setLineWidth(0.75);\u000b" + - "box3.setLineColor(Color.black);\u000b" + - "box3.getFill().setForegroundColor(new Color(187, 224, 227));\u000b" + - "box3.setAnchor(new Rectangle(473, 243, 170, 170));\u000b" + - "slide.addShape(box3);\u000b" + - "\u000b" + - "AutoShape box4 = new AutoShape(ShapeTypes.Arrow);\u000b" + - "box4.getFill().setForegroundColor(new Color(187, 224, 227));\u000b" + - "box4.setLineWidth(0.75);\u000b" + - "box4.setLineColor(Color.black);\u000b" + - "box4.setAnchor(new Rectangle(253, 288, 198, 85));\u000b" + - "slide.addShape(box4);\u000b" + - "\u000b" + - "FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\u000b" + - "ppt.write(out);\u000b" + - "out.close();"); - box3.setAnchor(new Rectangle(30, 150, 618, 411)); - box3.setHorizontalCentered(true); - } - - public static void slide7(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box2 = slide.createTextBox(); - box2.setHorizontalCentered(true); - box2.setVerticalAlignment(VerticalAlignment.MIDDLE); - box2.setText("Java Code"); - box2.setFillColor(new Color(187, 224, 227)); - box2.setStrokeStyle(0.75, Color.black); - box2.setAnchor(new Rectangle(66, 243, 170, 170)); - - TextBox box3 = slide.createTextBox(); - box3.setHorizontalCentered(true); - box3.setVerticalAlignment(VerticalAlignment.MIDDLE); - box3.setText("*.ppt file"); - box3.setFillColor(new Color(187, 224, 227)); - box3.setStrokeStyle(0.75, Color.black); - box3.setAnchor(new Rectangle(473, 243, 170, 170)); - - AutoShape box4 = slide.createAutoShape(); - box4.setShapeType(ShapeType.RIGHT_ARROW); - box4.setFillColor(new Color(187, 224, 227)); - box4.setStrokeStyle(0.75, Color.black); - box4.setAnchor(new Rectangle(253, 288, 198, 85)); - } - - public static void slide8(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("Wait, there is more!"); - box1.setAnchor(new Rectangle(36, 21, 648, 90)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.BODY); - box2.setText( - "Rich text\r" + - "Tables\r" + - "Pictures (JPEG, PNG, BMP, WMF, PICT)\r" + - "Comprehensive formatting features"); - box2.setAnchor(new Rectangle(36, 126, 648, 356)); - } - - public static void slide9(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("HSLF in Action - 3"); - box1.setAnchor(new Rectangle(36, 20, 648, 50)); - - TextBox box2 = slide.createTextBox(); - box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d); - box2.setText("PPGraphics2D: PowerPoint Graphics2D driver"); - box2.setAnchor(new Rectangle(178, 70, 387, 30)); - - TextBox box3 = slide.createTextBox(); - TextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0); - rt3.setFontFamily("Courier New"); - rt3.setFontSize(8d); - box3.setText( - "//bar chart data. The first value is the bar color, the second is the width\u000b" + - "Object[] def = new Object[]{\u000b" + - " Color.yellow, new Integer(100),\u000b" + - " Color.green, new Integer(150),\u000b" + - " Color.gray, new Integer(75),\u000b" + - " Color.red, new Integer(200),\u000b" + - "};\u000b" + - "\u000b" + - "SlideShow ppt = new SlideShow();\u000b" + - "Slide slide = ppt.createSlide();\u000b" + - "\u000b" + - "ShapeGroup group = new ShapeGroup();\u000b" + - "//define position of the drawing in the slide\u000b" + - "Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);\u000b" + - "group.setAnchor(bounds);\u000b" + - "slide.addShape(group);\u000b" + - "Graphics2D graphics = new PPGraphics2D(group);\u000b" + - "\u000b" + - "//draw a simple bar graph\u000b" + - "int x = bounds.x + 50, y = bounds.y + 50;\u000b" + - "graphics.setFont(new Font(\"Arial\", Font.BOLD, 10));\u000b" + - "for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {\u000b" + - " graphics.setColor(Color.black);\u000b" + - " int width = ((Integer)def[i+1]).intValue();\u000b" + - " graphics.drawString(\"Q\" + idx, x-20, y+20);\u000b" + - " graphics.drawString(width + \"%\", x + width + 10, y + 20);\u000b" + - " graphics.setColor((Color)def[i]);\u000b" + - " graphics.fill(new Rectangle(x, y, width, 30));\u000b" + - " y += 40;\u000b" + - "}\u000b" + - "graphics.setColor(Color.black);\u000b" + - "graphics.setFont(new Font(\"Arial\", Font.BOLD, 14));\u000b" + - "graphics.draw(bounds);\u000b" + - "graphics.drawString(\"Performance\", x + 70, y + 40);\u000b" + - "\u000b" + - "FileOutputStream out = new FileOutputStream(\"hslf-demo.ppt\");\u000b" + - "ppt.write(out);\u000b" + - "out.close();"); - box3.setAnchor(new Rectangle(96, 110, 499, 378)); - box3.setHorizontalCentered(true); - } - - public static void slide10(SlideShow ppt) throws IOException { - //bar chart data. The first value is the bar color, the second is the width - Object[] def = new Object[]{ - Color.yellow, 100, - Color.green, 150, - Color.gray, 75, - Color.red, 200, - }; - - Slide slide = ppt.createSlide(); - - GroupShape group = slide.createGroup(); - //define position of the drawing in the slide - Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300); - group.setAnchor(bounds); - Graphics2D graphics = new SLGraphics(group); - - //draw a simple bar graph - int x = bounds.x + 50, y = bounds.y + 50; - graphics.setFont(new Font("Arial", Font.BOLD, 10)); - for (int i = 0, idx = 1; i < def.length; i+=2, idx++) { - graphics.setColor(Color.black); - int width = ((Integer)def[i+1]).intValue(); - graphics.drawString("Q" + idx, x-20, y+20); - graphics.drawString(width + "%", x + width + 10, y + 20); - graphics.setColor((Color)def[i]); - graphics.fill(new Rectangle(x, y, width, 30)); - y += 40; - } - graphics.setColor(Color.black); - graphics.setFont(new Font("Arial", Font.BOLD, 14)); - graphics.draw(bounds); - graphics.drawString("Performance", x + 70, y + 40); - - } - - public static void slide11(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.TITLE); - box1.setText("HSLF Development Plans"); - box1.setAnchor(new Rectangle(36, 21, 648, 90)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.BODY); - box2.setText( - "Support for more PowerPoint functionality\r" + - "Rendering slides into java.awt.Graphics2D\r" + - "A way to export slides into images or other formats\r" + - "Integration with Apache FOP - Formatting Objects Processor\r" + - "Transformation of XSL-FO into PPT\r" + - "PPT2PDF transcoder" - ); - - List> tp = box2.getTextParagraphs(); - for (int i : new byte[]{0,1,3}) { - tp.get(i).getTextRuns().get(0).setFontSize(28d); - } - for (int i : new byte[]{2,4,5}) { - tp.get(i).getTextRuns().get(0).setFontSize(24d); - tp.get(i).setIndentLevel(1); - } - - box2.setAnchor(new Rectangle(36, 126, 648, 400)); - } - - public static void slide12(SlideShow ppt) throws IOException { - Slide slide = ppt.createSlide(); - - TextBox box1 = slide.createTextBox(); - box1.setTextPlaceholder(TextPlaceholder.CENTER_TITLE); - box1.setText("Questions?"); - box1.setAnchor(new Rectangle(54, 167, 612, 115)); - - TextBox box2 = slide.createTextBox(); - box2.setTextPlaceholder(TextPlaceholder.CENTER_BODY); - box2.setText( - "http://poi.apache.org/hslf/\r" + - "http://people.apache.org/~yegor"); - box2.setAnchor(new Rectangle(108, 306, 504, 138)); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java deleted file mode 100644 index 3c706e3e7..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextBox; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; - -/** - * How to create a single-level bulleted list - * and change some of the bullet attributes - * - * @author Yegor Kozlov - */ -public final class BulletsDemo { - - public static void main(String[] args) throws Exception { - - HSLFSlideShow ppt = new HSLFSlideShow(); - - HSLFSlide slide = ppt.createSlide(); - - HSLFTextBox shape = new HSLFTextBox(); - HSLFTextParagraph rt = shape.getTextParagraphs().get(0); - rt.getTextRuns().get(0).setFontSize(42d); - rt.setBullet(true); - rt.setIndent(0d); //bullet offset - rt.setLeftMargin(50d); //text offset (should be greater than bullet offset) - rt.setBulletChar('\u263A'); //bullet character - shape.setText( - "January\r" + - "February\r" + - "March\r" + - "April"); - slide.addShape(shape); - - shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300)); //position of the text box in the slide - slide.addShape(shape); - - FileOutputStream out = new FileOutputStream("bullets.ppt"); - ppt.write(out); - out.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/CreateHyperlink.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/CreateHyperlink.java deleted file mode 100644 index fc25afae5..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/CreateHyperlink.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.awt.Rectangle; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hslf.usermodel.HSLFHyperlink; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextBox; - -/** - * Demonstrates how to create hyperlinks in PowerPoint presentations - */ -public abstract class CreateHyperlink { - - public static void main(String[] args) throws IOException { - HSLFSlideShow ppt = new HSLFSlideShow(); - - HSLFSlide slideA = ppt.createSlide(); - ppt.createSlide(); - HSLFSlide slideC = ppt.createSlide(); - - // link to a URL - HSLFTextBox textBox1 = slideA.createTextBox(); - textBox1.setText("Apache POI"); - textBox1.setAnchor(new Rectangle(100, 100, 200, 50)); - - HSLFHyperlink link1 = textBox1.getTextParagraphs().get(0).getTextRuns().get(0).createHyperlink(); - link1.linkToUrl("http://www.apache.org"); - link1.setLabel(textBox1.getText()); - - // link to another slide - HSLFTextBox textBox2 = slideA.createTextBox(); - textBox2.setText("Go to slide #3"); - textBox2.setAnchor(new Rectangle(100, 300, 200, 50)); - - HSLFHyperlink link2 = textBox2.getTextParagraphs().get(0).getTextRuns().get(0).createHyperlink(); - link2.linkToSlide(slideC); - - FileOutputStream out = new FileOutputStream("hyperlink.ppt"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java deleted file mode 100644 index 514c01ba0..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; - -import org.apache.poi.hslf.model.OLEShape; -import org.apache.poi.hslf.usermodel.HSLFObjectData; -import org.apache.poi.hslf.usermodel.HSLFPictureData; -import org.apache.poi.hslf.usermodel.HSLFPictureShape; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFSoundData; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hwpf.HWPFDocument; -import org.apache.poi.hwpf.usermodel.Paragraph; -import org.apache.poi.hwpf.usermodel.Range; - -/** - * Demonstrates how you can extract misc embedded data from a ppt file - * - * @author Yegor Kozlov - */ -public final class DataExtraction { - - public static void main(String args[]) throws Exception { - - if (args.length == 0) { - usage(); - return; - } - - FileInputStream is = new FileInputStream(args[0]); - HSLFSlideShow ppt = new HSLFSlideShow(is); - is.close(); - - //extract all sound files embedded in this presentation - HSLFSoundData[] sound = ppt.getSoundData(); - for (int i = 0; i < sound.length; i++) { - String type = sound[i].getSoundType(); //*.wav - String name = sound[i].getSoundName(); //typically file name - byte[] data = sound[i].getData(); //raw bytes - - //save the sound on disk - FileOutputStream out = new FileOutputStream(name + type); - out.write(data); - out.close(); - } - - int oleIdx=-1, picIdx=-1; - for (HSLFSlide slide : ppt.getSlides()) { - //extract embedded OLE documents - for (HSLFShape shape : slide.getShapes()) { - if (shape instanceof OLEShape) { - oleIdx++; - OLEShape ole = (OLEShape) shape; - HSLFObjectData data = ole.getObjectData(); - String name = ole.getInstanceName(); - if ("Worksheet".equals(name)) { - - //read xls - @SuppressWarnings({ "unused", "resource" }) - HSSFWorkbook wb = new HSSFWorkbook(data.getData()); - - } else if ("Document".equals(name)) { - HWPFDocument doc = new HWPFDocument(data.getData()); - //read the word document - Range r = doc.getRange(); - for(int k = 0; k < r.numParagraphs(); k++) { - Paragraph p = r.getParagraph(k); - System.out.println(p.text()); - } - - //save on disk - FileOutputStream out = new FileOutputStream(name + "-("+(oleIdx)+").doc"); - doc.write(out); - out.close(); - } else { - FileOutputStream out = new FileOutputStream(ole.getProgID() + "-"+(oleIdx+1)+".dat"); - InputStream dis = data.getData(); - byte[] chunk = new byte[2048]; - int count; - while ((count = dis.read(chunk)) >= 0) { - out.write(chunk,0,count); - } - is.close(); - out.close(); - } - } - - //Pictures - else if (shape instanceof HSLFPictureShape) { - picIdx++; - HSLFPictureShape p = (HSLFPictureShape) shape; - HSLFPictureData data = p.getPictureData(); - String ext = data.getType().extension; - FileOutputStream out = new FileOutputStream("pict-" + picIdx + ext); - out.write(data.getData()); - out.close(); - } - } - - } - } - - private static void usage(){ - System.out.println("Usage: DataExtraction ppt"); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java deleted file mode 100644 index 53cd53edc..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.io.FileOutputStream; - -import org.apache.poi.hslf.model.PPGraphics2D; -import org.apache.poi.hslf.usermodel.HSLFGroupShape; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; - -/** - * Demonstrates how to draw into a slide using the HSLF Graphics2D driver. - * - * @author Yegor Kozlov - */ -public final class Graphics2DDemo { - - /** - * A simple bar chart demo - */ - public static void main(String[] args) throws Exception { - HSLFSlideShow ppt = new HSLFSlideShow(); - - //bar chart data. The first value is the bar color, the second is the width - Object[] def = new Object[]{ - Color.yellow, 40, - Color.green, 60, - Color.gray, 30, - Color.red, 80, - }; - - HSLFSlide slide = ppt.createSlide(); - - HSLFGroupShape group = new HSLFGroupShape(); - //define position of the drawing in the slide - Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300); - group.setAnchor(bounds); - group.setInteriorAnchor(new java.awt.Rectangle(0, 0, 100, 100)); - slide.addShape(group); - Graphics2D graphics = new PPGraphics2D(group); - - //draw a simple bar graph - int x = 10, y = 10; - graphics.setFont(new Font("Arial", Font.BOLD, 10)); - for (int i = 0, idx = 1; i < def.length; i+=2, idx++) { - graphics.setColor(Color.black); - int width = ((Integer)def[i+1]).intValue(); - graphics.drawString("Q" + idx, x-5, y+10); - graphics.drawString(width + "%", x + width+3, y + 10); - graphics.setColor((Color)def[i]); - graphics.fill(new Rectangle(x, y, width, 10)); - y += 15; - } - graphics.setColor(Color.black); - graphics.setFont(new Font("Arial", Font.BOLD, 14)); - graphics.draw(group.getInteriorAnchor()); - graphics.drawString("Performance", x + 30, y + 10); - - FileOutputStream out = new FileOutputStream("hslf-graphics.ppt"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/HeadersFootersDemo.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/HeadersFootersDemo.java deleted file mode 100644 index b37aed2df..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/HeadersFootersDemo.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hslf.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hslf.model.HeadersFooters; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; - -/** - * Demonstrates how to set headers / footers - */ -public abstract class HeadersFootersDemo { - public static void main(String[] args) throws IOException { - HSLFSlideShow ppt = new HSLFSlideShow(); - - HeadersFooters slideHeaders = ppt.getSlideHeadersFooters(); - slideHeaders.setFootersText("Created by POI-HSLF"); - slideHeaders.setSlideNumberVisible(true); - slideHeaders.setDateTimeText("custom date time"); - - HeadersFooters notesHeaders = ppt.getNotesHeadersFooters(); - notesHeaders.setFootersText("My notes footers"); - notesHeaders.setHeaderText("My notes header"); - - ppt.createSlide(); - - FileOutputStream out = new FileOutputStream("headers_footers.ppt"); - ppt.write(out); - out.close(); - - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java deleted file mode 100644 index 812429295..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.io.FileInputStream; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.hslf.usermodel.HSLFHyperlink; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSimpleShape; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.hslf.usermodel.HSLFTextRun; - -/** - * Demonstrates how to read hyperlinks from a presentation - * - * @author Yegor Kozlov - */ -public final class Hyperlinks { - - public static void main(String[] args) throws Exception { - for (int i = 0; i < args.length; i++) { - FileInputStream is = new FileInputStream(args[i]); - HSLFSlideShow ppt = new HSLFSlideShow(is); - is.close(); - - for (HSLFSlide slide : ppt.getSlides()) { - System.out.println("\nslide " + slide.getSlideNumber()); - - // read hyperlinks from the slide's text runs - System.out.println("- reading hyperlinks from the text runs"); - for (List paras : slide.getTextParagraphs()) { - for (HSLFTextParagraph para : paras) { - for (HSLFTextRun run : para) { - HSLFHyperlink link = run.getHyperlink(); - if (link != null) { - System.out.println(toStr(link, run.getRawText())); - } - } - } - } - - // in PowerPoint you can assign a hyperlink to a shape without text, - // for example to a Line object. The code below demonstrates how to - // read such hyperlinks - System.out.println("- reading hyperlinks from the slide's shapes"); - for (HSLFShape sh : slide.getShapes()) { - if (sh instanceof HSLFSimpleShape) { - HSLFHyperlink link = ((HSLFSimpleShape)sh).getHyperlink(); - if (link != null) { - System.out.println(toStr(link, null)); - } - } - } - } - ppt.close(); - } - } - - static String toStr(HSLFHyperlink link, String rawText) { - //in ppt end index is inclusive - String formatStr = "title: %1$s, address: %2$s" + (rawText == null ? "" : ", start: %3$s, end: %4$s, substring: %5$s"); - return String.format(Locale.ROOT, formatStr, link.getLabel(), link.getAddress(), link.getStartIndex(), link.getEndIndex(), rawText); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/PPT2PNG.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/PPT2PNG.java deleted file mode 100644 index d8fe8f41f..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/PPT2PNG.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -import javax.imageio.ImageIO; - -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; - -/** - * Demonstrates how you can use HSLF to convert each slide into a PNG image - * - * @author Yegor Kozlov - */ -public final class PPT2PNG { - - public static void main(String args[]) throws Exception { - - if (args.length == 0) { - usage(); - return; - } - - int slidenum = -1; - float scale = 1; - String file = null; - - for (int i = 0; i < args.length; i++) { - if (args[i].startsWith("-")) { - if ("-scale".equals(args[i])){ - scale = Float.parseFloat(args[++i]); - } else if ("-slide".equals(args[i])) { - slidenum = Integer.parseInt(args[++i]); - } - } else { - file = args[i]; - } - } - if(file == null){ - usage(); - return; - } - - FileInputStream is = new FileInputStream(file); - HSLFSlideShow ppt = new HSLFSlideShow(is); - is.close(); - - Dimension pgsize = ppt.getPageSize(); - int width = (int)(pgsize.width*scale); - int height = (int)(pgsize.height*scale); - - for (HSLFSlide slide : ppt.getSlides()) { - if (slidenum != -1 && slidenum != slide.getSlideNumber()) continue; - - String title = slide.getTitle(); - System.out.println("Rendering slide "+slide.getSlideNumber() + (title == null ? "" : ": " + title)); - - BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); - Graphics2D graphics = img.createGraphics(); - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - graphics.setPaint(Color.white); - graphics.fill(new Rectangle2D.Float(0, 0, width, height)); - - graphics.scale((double)width/pgsize.width, (double)height/pgsize.height); - - slide.draw(graphics); - - String fname = file.replaceAll("\\.ppt", "-" + slide.getSlideNumber() + ".png"); - FileOutputStream out = new FileOutputStream(fname); - ImageIO.write(img, "png", out); - out.close(); - } - } - - private static void usage(){ - System.out.println("Usage: PPT2PNG [-scale -slide ] ppt"); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java deleted file mode 100644 index ec0cec8dc..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hslf.examples; -import java.io.FileInputStream; -import java.io.IOException; - -import org.apache.poi.hslf.record.InteractiveInfoAtom; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFSoundData; - -/** - * For each slide iterate over shapes and found associated sound data. - */ -public class SoundFinder { - public static void main(String[] args) throws IOException { - FileInputStream fis = new FileInputStream(args[0]); - HSLFSlideShow ppt = new HSLFSlideShow(fis); - HSLFSoundData[] sounds = ppt.getSoundData(); - - for (HSLFSlide slide : ppt.getSlides()) { - for (HSLFShape shape : slide.getShapes()) { - int soundRef = getSoundReference(shape); - if(soundRef == -1) continue; - - - System.out.println("Slide["+slide.getSlideNumber()+"], shape["+shape.getShapeId()+"], soundRef: "+soundRef); - System.out.println(" " + sounds[soundRef].getSoundName()); - System.out.println(" " + sounds[soundRef].getSoundType()); - } - } - ppt.close(); - fis.close(); - } - - /** - * Check if a given shape is associated with a sound. - * @return 0-based reference to a sound in the sound collection - * or -1 if the shape is not associated with a sound - */ - protected static int getSoundReference(HSLFShape shape){ - int soundRef = -1; - //dive into the shape container and search for InteractiveInfoAtom - InteractiveInfoAtom info = shape.getClientDataRecord(RecordTypes.InteractiveInfo.typeID); - if (info != null && info.getAction() == InteractiveInfoAtom.ACTION_MEDIA) { - soundRef = info.getSoundRef(); - } - return soundRef; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java b/trunk/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java deleted file mode 100644 index e4ad98dc1..000000000 --- a/trunk/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java +++ /dev/null @@ -1,130 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.examples; - -import java.awt.Color; -import java.io.FileOutputStream; - -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTable; -import org.apache.poi.hslf.usermodel.HSLFTableCell; -import org.apache.poi.hslf.usermodel.HSLFTextRun; -import org.apache.poi.sl.draw.DrawTableShape; -import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; -import org.apache.poi.sl.usermodel.VerticalAlignment; - -/** - * Demonstrates how to create tables - * - * @author Yegor Kozlov - */ -public final class TableDemo { - - public static void main(String[] args) throws Exception { - - //test data for the first taable - String[][] txt1 = { - {"INPUT FILE", "NUMBER OF RECORDS"}, - {"Item File", "11,559"}, - {"Vendor File", "502"}, - {"Purchase History File - # of PO\u2019s\r(12/01/04 - 05/31/06)", "12,852"}, - {"Purchase History File - # of PO Lines\r(12/01/04 - 05/31/06)", "53,523" }, - {"Total PO History Spend", "$10,172,038"} - }; - - HSLFSlideShow ppt = new HSLFSlideShow(); - - HSLFSlide slide = ppt.createSlide(); - - //six rows, two columns - HSLFTable table1 = slide.createTable(6, 2); - for (int i = 0; i < txt1.length; i++) { - for (int j = 0; j < txt1[i].length; j++) { - HSLFTableCell cell = table1.getCell(i, j); - HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0); - rt.setFontFamily("Arial"); - rt.setFontSize(10d); - if(i == 0){ - cell.getFill().setForegroundColor(new Color(227, 227, 227)); - } else { - rt.setBold(true); - } - cell.setVerticalAlignment(VerticalAlignment.MIDDLE); - cell.setHorizontalCentered(true); - cell.setText(txt1[i][j]); - } - } - - DrawTableShape dts1 = new DrawTableShape(table1); - dts1.setAllBorders(1.0, Color.black); - - table1.setColumnWidth(0, 300); - table1.setColumnWidth(1, 150); - - int pgWidth = ppt.getPageSize().width; - table1.moveTo((pgWidth - table1.getAnchor().getWidth())/2., 100.); - - //test data for the second taable - String[][] txt2 = { - {"Data Source"}, - {"CAS Internal Metrics - Item Master Summary\r" + - "CAS Internal Metrics - Vendor Summary\r" + - "CAS Internal Metrics - PO History Summary"} - }; - - //two rows, one column - HSLFTable table2 = slide.createTable(2, 1); - for (int i = 0; i < txt2.length; i++) { - for (int j = 0; j < txt2[i].length; j++) { - HSLFTableCell cell = table2.getCell(i, j); - HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0); - rt.setFontSize(10d); - rt.setFontFamily("Arial"); - if(i == 0){ - cell.getFill().setForegroundColor(new Color(0, 51, 102)); - rt.setFontColor(Color.white); - rt.setBold(true); - rt.setFontSize(14d); - cell.setHorizontalCentered(true); - } else { - rt.getTextParagraph().setBullet(true); - rt.setFontSize(12d); - rt.getTextParagraph().setTextAlign(TextAlign.LEFT); - cell.setHorizontalCentered(false); - } - cell.setVerticalAlignment(VerticalAlignment.MIDDLE); - cell.setText(txt2[i][j]); - } - } - table2.setColumnWidth(0, 300); - table2.setRowHeight(0, 30); - table2.setRowHeight(1, 70); - - DrawTableShape dts2 = new DrawTableShape(table2); - dts2.setOutsideBorders(Color.black, 1.0); - - table2.moveTo(200, 400); - - FileOutputStream out = new FileOutputStream("hslf-table.ppt"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java b/trunk/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java deleted file mode 100644 index bf018a3e4..000000000 --- a/trunk/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; - -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.hsmf.datatypes.AttachmentChunks; -import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; - -/** - * Reads one or several Outlook MSG files and for each of them creates - * a text file from available chunks and a directory that contains - * attachments. - * - * @author Bruno Girin - */ -public class Msg2txt { - - /** - * The stem used to create file names for the text file and the directory - * that contains the attachments. - */ - private String fileNameStem; - - /** - * The Outlook MSG file being processed. - */ - private MAPIMessage msg; - - public Msg2txt(String fileName) throws IOException { - fileNameStem = fileName; - if(fileNameStem.endsWith(".msg") || fileNameStem.endsWith(".MSG")) { - fileNameStem = fileNameStem.substring(0, fileNameStem.length() - 4); - } - msg = new MAPIMessage(fileName); - } - - /** - * Processes the message. - * - * @throws IOException if an exception occurs while writing the message out - */ - public void processMessage() throws IOException { - String txtFileName = fileNameStem + ".txt"; - String attDirName = fileNameStem + "-att"; - PrintWriter txtOut = null; - try { - txtOut = new PrintWriter(txtFileName); - try { - String displayFrom = msg.getDisplayFrom(); - txtOut.println("From: "+displayFrom); - } catch (ChunkNotFoundException e) { - // ignore - } - try { - String displayTo = msg.getDisplayTo(); - txtOut.println("To: "+displayTo); - } catch (ChunkNotFoundException e) { - // ignore - } - try { - String displayCC = msg.getDisplayCC(); - txtOut.println("CC: "+displayCC); - } catch (ChunkNotFoundException e) { - // ignore - } - try { - String displayBCC = msg.getDisplayBCC(); - txtOut.println("BCC: "+displayBCC); - } catch (ChunkNotFoundException e) { - // ignore - } - try { - String subject = msg.getSubject(); - txtOut.println("Subject: "+subject); - } catch (ChunkNotFoundException e) { - // ignore - } - try { - String body = msg.getTextBody(); - txtOut.println(body); - } catch (ChunkNotFoundException e) { - System.err.println("No message body"); - } - - AttachmentChunks[] attachments = msg.getAttachmentFiles(); - if(attachments.length > 0) { - File d = new File(attDirName); - if(d.mkdir()) { - for(AttachmentChunks attachment : attachments) { - processAttachment(attachment, d); - } - } else { - System.err.println("Can't create directory "+attDirName); - } - } - } finally { - if(txtOut != null) { - txtOut.close(); - } - } - } - - /** - * Processes a single attachment: reads it from the Outlook MSG file and - * writes it to disk as an individual file. - * - * @param attachment the chunk group describing the attachment - * @param dir the directory in which to write the attachment file - * @throws IOException when any of the file operations fails - */ - public void processAttachment(AttachmentChunks attachment, - File dir) throws IOException { - String fileName = attachment.attachFileName.toString(); - if(attachment.attachLongFileName != null) { - fileName = attachment.attachLongFileName.toString(); - } - - File f = new File(dir, fileName); - OutputStream fileOut = null; - try { - fileOut = new FileOutputStream(f); - fileOut.write(attachment.attachData.getValue()); - } finally { - if(fileOut != null) { - fileOut.close(); - } - } - } - - /** - * Processes the list of arguments as a list of names of Outlook MSG files. - * - * @param args the list of MSG files to process - */ - public static void main(String[] args) { - if(args.length <= 0) { - System.err.println("No files names provided"); - } else { - for(int i = 0; i < args.length; i++) { - try { - Msg2txt processor = new Msg2txt(args[i]); - processor.processMessage(); - } catch (IOException e) { - System.err.println("Could not process "+args[i]+": "+e); - } - } - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java b/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java deleted file mode 100644 index 610d96174..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java +++ /dev/null @@ -1,329 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel.examples; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener; -import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; -import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; -import org.apache.poi.hssf.eventusermodel.HSSFListener; -import org.apache.poi.hssf.eventusermodel.HSSFRequest; -import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener; -import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * A XLS -> CSV processor, that uses the MissingRecordAware - * EventModel code to ensure it outputs all columns and rows. - * @author Nick Burch - */ -public class XLS2CSVmra implements HSSFListener { - private int minColumns; - private POIFSFileSystem fs; - private PrintStream output; - - private int lastRowNumber; - private int lastColumnNumber; - - /** Should we output the formula, or the value it has? */ - private boolean outputFormulaValues = true; - - /** For parsing Formulas */ - private SheetRecordCollectingListener workbookBuildingListener; - private HSSFWorkbook stubWorkbook; - - // Records we pick up as we process - private SSTRecord sstRecord; - private FormatTrackingHSSFListener formatListener; - - /** So we known which sheet we're on */ - private int sheetIndex = -1; - private BoundSheetRecord[] orderedBSRs; - private List boundSheetRecords = new ArrayList(); - - // For handling formulas with string results - private int nextRow; - private int nextColumn; - private boolean outputNextStringRecord; - - /** - * Creates a new XLS -> CSV converter - * @param fs The POIFSFileSystem to process - * @param output The PrintStream to output the CSV to - * @param minColumns The minimum number of columns to output, or -1 for no minimum - */ - public XLS2CSVmra(POIFSFileSystem fs, PrintStream output, int minColumns) { - this.fs = fs; - this.output = output; - this.minColumns = minColumns; - } - - /** - * Creates a new XLS -> CSV converter - * @param filename The file to process - * @param minColumns The minimum number of columns to output, or -1 for no minimum - * @throws IOException - * @throws FileNotFoundException - */ - public XLS2CSVmra(String filename, int minColumns) throws IOException, FileNotFoundException { - this( - new POIFSFileSystem(new FileInputStream(filename)), - System.out, minColumns - ); - } - - /** - * Initiates the processing of the XLS file to CSV - */ - public void process() throws IOException { - MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this); - formatListener = new FormatTrackingHSSFListener(listener); - - HSSFEventFactory factory = new HSSFEventFactory(); - HSSFRequest request = new HSSFRequest(); - - if(outputFormulaValues) { - request.addListenerForAllRecords(formatListener); - } else { - workbookBuildingListener = new SheetRecordCollectingListener(formatListener); - request.addListenerForAllRecords(workbookBuildingListener); - } - - factory.processWorkbookEvents(request, fs); - } - - /** - * Main HSSFListener method, processes events, and outputs the - * CSV as the file is processed. - */ - @Override - public void processRecord(Record record) { - int thisRow = -1; - int thisColumn = -1; - String thisStr = null; - - switch (record.getSid()) - { - case BoundSheetRecord.sid: - boundSheetRecords.add((BoundSheetRecord)record); - break; - case BOFRecord.sid: - BOFRecord br = (BOFRecord)record; - if(br.getType() == BOFRecord.TYPE_WORKSHEET) { - // Create sub workbook if required - if(workbookBuildingListener != null && stubWorkbook == null) { - stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook(); - } - - // Output the worksheet name - // Works by ordering the BSRs by the location of - // their BOFRecords, and then knowing that we - // process BOFRecords in byte offset order - sheetIndex++; - if(orderedBSRs == null) { - orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords); - } - output.println(); - output.println( - orderedBSRs[sheetIndex].getSheetname() + - " [" + (sheetIndex+1) + "]:" - ); - } - break; - - case SSTRecord.sid: - sstRecord = (SSTRecord) record; - break; - - case BlankRecord.sid: - BlankRecord brec = (BlankRecord) record; - - thisRow = brec.getRow(); - thisColumn = brec.getColumn(); - thisStr = ""; - break; - case BoolErrRecord.sid: - BoolErrRecord berec = (BoolErrRecord) record; - - thisRow = berec.getRow(); - thisColumn = berec.getColumn(); - thisStr = ""; - break; - - case FormulaRecord.sid: - FormulaRecord frec = (FormulaRecord) record; - - thisRow = frec.getRow(); - thisColumn = frec.getColumn(); - - if(outputFormulaValues) { - if(Double.isNaN( frec.getValue() )) { - // Formula result is a string - // This is stored in the next record - outputNextStringRecord = true; - nextRow = frec.getRow(); - nextColumn = frec.getColumn(); - } else { - thisStr = formatListener.formatNumberDateCell(frec); - } - } else { - thisStr = '"' + - HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"'; - } - break; - case StringRecord.sid: - if(outputNextStringRecord) { - // String for formula - StringRecord srec = (StringRecord)record; - thisStr = srec.getString(); - thisRow = nextRow; - thisColumn = nextColumn; - outputNextStringRecord = false; - } - break; - - case LabelRecord.sid: - LabelRecord lrec = (LabelRecord) record; - - thisRow = lrec.getRow(); - thisColumn = lrec.getColumn(); - thisStr = '"' + lrec.getValue() + '"'; - break; - case LabelSSTRecord.sid: - LabelSSTRecord lsrec = (LabelSSTRecord) record; - - thisRow = lsrec.getRow(); - thisColumn = lsrec.getColumn(); - if(sstRecord == null) { - thisStr = '"' + "(No SST Record, can't identify string)" + '"'; - } else { - thisStr = '"' + sstRecord.getString(lsrec.getSSTIndex()).toString() + '"'; - } - break; - case NoteRecord.sid: - NoteRecord nrec = (NoteRecord) record; - - thisRow = nrec.getRow(); - thisColumn = nrec.getColumn(); - // TODO: Find object to match nrec.getShapeId() - thisStr = '"' + "(TODO)" + '"'; - break; - case NumberRecord.sid: - NumberRecord numrec = (NumberRecord) record; - - thisRow = numrec.getRow(); - thisColumn = numrec.getColumn(); - - // Format - thisStr = formatListener.formatNumberDateCell(numrec); - break; - case RKRecord.sid: - RKRecord rkrec = (RKRecord) record; - - thisRow = rkrec.getRow(); - thisColumn = rkrec.getColumn(); - thisStr = '"' + "(TODO)" + '"'; - break; - default: - break; - } - - // Handle new row - if(thisRow != -1 && thisRow != lastRowNumber) { - lastColumnNumber = -1; - } - - // Handle missing column - if(record instanceof MissingCellDummyRecord) { - MissingCellDummyRecord mc = (MissingCellDummyRecord)record; - thisRow = mc.getRow(); - thisColumn = mc.getColumn(); - thisStr = ""; - } - - // If we got something to print out, do so - if(thisStr != null) { - if(thisColumn > 0) { - output.print(','); - } - output.print(thisStr); - } - - // Update column and row count - if(thisRow > -1) - lastRowNumber = thisRow; - if(thisColumn > -1) - lastColumnNumber = thisColumn; - - // Handle end of row - if(record instanceof LastCellOfRowDummyRecord) { - // Print out any missing commas if needed - if(minColumns > 0) { - // Columns are 0 based - if(lastColumnNumber == -1) { lastColumnNumber = 0; } - for(int i=lastColumnNumber; i<(minColumns); i++) { - output.print(','); - } - } - - // We're onto a new row - lastColumnNumber = -1; - - // End the row - output.println(); - } - } - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" XLS2CSVmra [min columns]"); - System.exit(1); - } - - int minColumns = -1; - if(args.length >= 2) { - minColumns = Integer.parseInt(args[1]); - } - - XLS2CSVmra xls2csv = new XLS2CSVmra(args[0], minColumns); - xls2csv.process(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java deleted file mode 100644 index 9b86cf779..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java +++ /dev/null @@ -1,944 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFClientAnchor; -import org.apache.poi.hssf.usermodel.HSSFPatriarch; -import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; - - -/** - * Demonstrates how to add an image to a worksheet and set that image's size - * to a specific number of milimetres irrespective of the width of the columns - * or height of the rows. Overridden methods are provided so that the location - * of the image - the cells row and column co-ordinates that define the top - * left hand corners of the image - can be identified either in the familiar - * Excel manner - A1 for instance - or using POI's methodolody of a column and - * row index where 0, 0 would indicate cell A1. - * - * The best way to make use of these techniques is to delay adding the image to - * the sheet until all other work has been completed. That way, the sizes of - * all rows and columns will have been adjusted - assuming that step was - * necessary. Even though the anchors type is set to prevent the image moving - * or re-sizing, this setting does not have any effect until the sheet is being - * viewed using the Excel application. - * - * The key to the process is the HSSFClientAnchor class. It accepts eight - * parameters that define, in order; - * - * * How far - in terms of co-ordinate position - the image should be inset - * from the left hand border of a cell. - * * How far - in terms of co-ordinate positions - the image should be inset - * from the from the top of the cell. - * * How far - in terms of co-ordinate positions - the right hand edge of - * the image should protrude into a cell (measured from the cell's left hand - * edge to the image's right hand edge). - * * How far - in terms of co-ordinate positions - the bottm edge of the - * image should protrude into a row (measured from the cell's top edge to - * the image's bottom edge). - * * The index of the column that contains the cell whose top left hand - * corner should be aligned with the top left hand corner of the image. - * * The index of the row that contains the cell whose top left hand corner - * should be aligned with the image's top left hand corner. - * * The index of the column that contains the cell whose top left hand - * corner should be aligned with the image's bottom right hand corner - * * The index number of the row that contains the cell whose top left - * hand corner should be aligned with the images bottom right hand corner. - * - * It can be used to add an image into cell A1, for example, in the following - * manner; - * - * HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, - * (short)0, 0, (short)1, 1); - * - * The final four parameters determine that the top left hand corner should be - * aligned with the top left hand corner of cell A1 and it's bottom right - * hand corner with the top left hand corner of cell B2. Think of the image as - * being stretched so that it's top left hand corner is aligned with the top - * left hand corner of cell A1 and it's bottom right hand corner is aligned with - * the top left hand corner of cell B1. Interestingly, this would also produce - * the same results; - * - * anchor = new HSSFClientAnchor(0, 0, 1023, 255, - * (short)0, 0, (short)0, 0); - * - * Note that the final four parameters all contain the same value and seem to - * indicate that the images top left hand corner is aligned with the top left - * hand corner of cell A1 and that it's bottom right hand corner is also - * aligned with the top left hand corner of cell A1. Yet, running this code - * would see the image fully occupying cell A1. That is the result of the - * values passed to parameters three and four; these I have referred to as - * determing the images co-ordinates within the cell. They indicate that the - * image should occupy - in order - the full width of the column and the full - * height of the row. - * - * The co-ordinate values shown are the maxima; and they are independent of - * row height/column width and of the font used. Passing 255 will always result - * in the image occupying the full height of the row and passing 1023 will - * always result in the image occupying the full width of the column. They help - * in situations where an image is larger than a column/row and must overlap - * into the next column/row. Using them does mean, however, that it is often - * necessary to perform conversions between Excel's characters units, points, - * pixels and millimetres in order to establish how many rows/columns an image - * should occupy and just what the varous insets ought to be. - * - * Note that the first two parameters of the HSSFClientAchor classes constructor - * are not made use of in the code that follows. It would be fairly trivial - * however to extend these example further and provide methods that would centre - * an image within a cell or allow the user to specify that a plain border a - * fixed number of millimetres wide should wrap around the image. Those first - * two parameters would make this sort of functionality perfectly possible. - * - * Owing to the various conversions used, the actual size of the image may vary - * from that required; testing has so far found this to be in the region of - * plus or minus two millimetres. Most likely by modifying the way the - * calculations are performed - possibly using double(s) throughout and - * rounding the values at the correct point - it is likely that these errors - * could be reduced or removed. - * - * A note concerning Excels' image resizing behaviour. The HSSFClientAnchor - * class contains a method called setAnchorType(int) which can be used to - * determine how Excel will resize an image in reponse to the user increasing - * or decreasing the dimensions of the cell containing the image. There are - * three values that can be passed to this method; 0 = To move and size the - * image with the cell, 2 = To move but don't size the image with the cell, - * 3 = To prevent the image from moving or being resized along with the cell. If - * an image is inserted using this class and placed into a single cell then if - * the setAnchorType(int) method is called and a value of either 0 or 2 passed - * to it, the resultant resizing behaviour may be a surprise. The image will not - * grow in size of the column is made wider or the row higher but it will shrink - * if the columns width or rows height are reduced. - * - * @author Mark Beardsley [msb at apache.org] - * @version 1.00 5th August 2009. - */ -public class AddDimensionedImage { - - // Four constants that determine how - and indeed whether - the rows - // and columns an image may overlie should be expanded to accomodate that - // image. - // Passing EXPAND_ROW will result in the height of a row being increased - // to accomodate the image if it is not already larger. The image will - // be layed across one or more columns. - // Passing EXPAND_COLUMN will result in the width of the column being - // increased to accomodate the image if it is not already larger. The image - // will be layed across one or many rows. - // Passing EXPAND_ROW_AND_COLUMN will result in the height of the row - // bing increased along with the width of the column to accomdate the - // image if either is not already larger. - // Passing OVERLAY_ROW_AND_COLUMN will result in the image being layed - // over one or more rows and columns. No row or column will be resized, - // instead, code will determine how many rows and columns the image should - // overlie. - public static final int EXPAND_ROW = 1; - public static final int EXPAND_COLUMN = 2; - public static final int EXPAND_ROW_AND_COLUMN = 3; - public static final int OVERLAY_ROW_AND_COLUMN = 7; - - /** - * Add an image to a worksheet. - * - * @param cellNumber A String that contains the location of the cell whose - * top left hand corner should be aligned with the top - * left hand corner of the image; for example "A1", "A2" - * etc. This is to support the familiar Excel syntax. - * Whilst images are are not actually inserted into cells - * this provides a convenient method of indicating where - * the image should be positioned on the sheet. - * @param sheet A reference to the sheet that contains the cell referenced - * above. - * @param imageFile A String that encapsulates the name of and path to - * the image that is to be 'inserted into' the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres. - * @param resizeBehaviour A primitive int whose value will determine how - * the code should react if the image is larger than - * the cell referenced by the cellNumber parameter. - * Four constants are provided to determine what - * should happen; - * AddDimensionedImage.EXPAND_ROW - * AddDimensionedImage.EXPAND_COLUMN - * AddDimensionedImage.EXPAND_ROW_AND_COLUMN - * AddDimensionedImage.OVERLAY_ROW_AND_COLUMN - * @throws java.io.FileNotFoundException If the file containing the image - * cannot be located. - * @throws java.io.IOException If a problem occurs whilst reading the file - * of image data. - * @throws java.lang.IllegalArgumentException If an invalid value is passed - * to the resizeBehaviour - * parameter. - */ - public void addImageToSheet(String cellNumber, HSSFSheet sheet, - String imageFile, double reqImageWidthMM, double reqImageHeightMM, - int resizeBehaviour) throws IOException, IllegalArgumentException { - // Convert the String into column and row indices then chain the - // call to the overridden addImageToSheet() method. - CellReference cellRef = new CellReference(cellNumber); - this.addImageToSheet(cellRef.getCol(), cellRef.getRow(), sheet, - imageFile, reqImageWidthMM, reqImageHeightMM,resizeBehaviour); - } - - /** - * Add an image to a worksheet. - * - * @param colNumber A primitive int that contains the index number of a - * column on the worksheet; POI column indices are zero - * based. Together with the rowNumber parameter's value, - * this parameter identifies a cell on the worksheet. The - * image's top left hand corner will be aligned with the - * top left hand corner of this cell. - * @param rowNumber A primtive int that contains the index number of a row - * on the worksheet; POI row indices are zero based. - * Together with the rowNumber parameter's value, this - * parameter identifies a cell on the worksheet. The - * image's top left hand corner will be aligned with the - * top left hand corner of this cell. - * @param sheet A reference to the sheet that contains the cell identified - * by the two parameters above. - * @param imageFile A String that encapsulates the name of and path to - * the image that is to be 'inserted into' the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres. - * @param resizeBehaviour A primitive int whose value will determine how - * the code should react if the image is larger than - * the cell referenced by the colNumber and - * rowNumber parameters. Four constants are provided - * to determine what should happen; - * AddDimensionedImage.EXPAND_ROW - * AddDimensionedImage.EXPAND_COLUMN - * AddDimensionedImage.EXPAND_ROW_AND_COLUMN - * AddDimensionedImage.OVERLAY_ROW_AND_COLUMN - * @throws java.io.FileNotFoundException If the file containing the image - * cannot be located. - * @throws java.io.IOException If a problem occurs whilst reading the file - * of image data. - * @throws java.lang.IllegalArgumentException If an invalid value is passed - * to the resizeBehaviour - * parameter. - */ - private void addImageToSheet(int colNumber, int rowNumber, HSSFSheet sheet, - String imageFile, double reqImageWidthMM, double reqImageHeightMM, - int resizeBehaviour) throws FileNotFoundException, IOException, - IllegalArgumentException { - HSSFClientAnchor anchor = null; - HSSFPatriarch patriarch = null; - ClientAnchorDetail rowClientAnchorDetail = null; - ClientAnchorDetail colClientAnchorDetail = null; - - // Validate the resizeBehaviour parameter. - if((resizeBehaviour != AddDimensionedImage.EXPAND_COLUMN) && - (resizeBehaviour != AddDimensionedImage.EXPAND_ROW) && - (resizeBehaviour != AddDimensionedImage.EXPAND_ROW_AND_COLUMN) && - (resizeBehaviour != AddDimensionedImage.OVERLAY_ROW_AND_COLUMN)) { - throw new IllegalArgumentException("Invalid value passed to the " + - "resizeBehaviour parameter of AddDimensionedImage.addImageToSheet()"); - } - - // Call methods to calculate how the image and sheet should be - // manipulated to accomodate the image; columns and then rows. - colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber, - reqImageWidthMM, resizeBehaviour); - rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber, - reqImageHeightMM, resizeBehaviour); - - // Having determined if and how to resize the rows, columns and/or the - // image, create the HSSFClientAnchor object to position the image on - // the worksheet. Note how the two ClientAnchorDetail records are - // interrogated to recover the row/column co-ordinates and any insets. - // The first two parameters are not used currently but could be if the - // need arose to extend the functionality of this code by adding the - // ability to specify that a clear 'border' be placed around the image. - anchor = new HSSFClientAnchor(0, - 0, - colClientAnchorDetail.getInset(), - rowClientAnchorDetail.getInset(), - (short)colClientAnchorDetail.getFromIndex(), - rowClientAnchorDetail.getFromIndex(), - (short)colClientAnchorDetail.getToIndex(), - rowClientAnchorDetail.getToIndex()); - - // For now, set the anchor type to do not move or resize the - // image as the size of the row/column is adjusted. This could easilly - // become another parameter passed to the method. - //anchor.setAnchorType(HSSFClientAnchor.DONT_MOVE_AND_RESIZE); - anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE); - - // Now, add the picture to the workbook. Note that the type is assumed - // to be a JPEG/JPG, this could easily (and should) be parameterised - // however. - //int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile), - // HSSFWorkbook.PICTURE_TYPE_JPEG); - int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile), HSSFWorkbook.PICTURE_TYPE_PNG); - - // Get the drawing patriarch and create the picture. - patriarch = sheet.createDrawingPatriarch(); - patriarch.createPicture(anchor, index); - } - - /** - * Determines whether the sheets columns should be re-sized to accomodate - * the image, adjusts the columns width if necessary and creates then - * returns a ClientAnchorDetail object that facilitates construction of - * an HSSFClientAnchor that will fix the image on the sheet and establish - * it's size. - * - * @param sheet A reference to the sheet that will 'contain' the image. - * @param colNumber A primtive int that contains the index number of a - * column on the sheet. - * @param reqImageWidthMM A primtive double that contains the required - * width of the image in millimetres - * @param resizeBehaviour A primitve int whose value will indicate how the - * width of the column should be adjusted if the - * required width of the image is greater than the - * width of the column. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the column containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number column containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the right hand - * edge of the image can protrude into the next column - expressed - * as a specific number of co-ordinate positions. - */ - private ClientAnchorDetail fitImageToColumns(HSSFSheet sheet, int colNumber, - double reqImageWidthMM, int resizeBehaviour) { - - double colWidthMM = 0.0D; - double colCoordinatesPerMM = 0.0D; - int pictureWidthCoordinates = 0; - ClientAnchorDetail colClientAnchorDetail = null; - - // Get the colum's width in millimetres - colWidthMM = ConvertImageUnits.widthUnits2Millimetres( - (short)sheet.getColumnWidth(colNumber)); - - // Check that the column's width will accomodate the image at the - // required dimension. If the width of the column is LESS than the - // required width of the image, decide how the application should - // respond - resize the column or overlay the image across one or more - // columns. - if(colWidthMM < reqImageWidthMM) { - - // Should the column's width simply be expanded? - if((resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) { - // Set the width of the column by converting the required image - // width from millimetres into Excel's column width units. - sheet.setColumnWidth(colNumber, - ConvertImageUnits.millimetres2WidthUnits(reqImageWidthMM)); - // To make the image occupy the full width of the column, convert - // the required width of the image into co-ordinates. This value - // will become the inset for the ClientAnchorDetail class that - // is then instantiated. - colWidthMM = reqImageWidthMM; - colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM); - colClientAnchorDetail = new ClientAnchorDetail(colNumber, - colNumber, pictureWidthCoordinates); - } - // If the user has chosen to overlay both rows and columns or just - // to expand ONLY the size of the rows, then calculate how to lay - // the image out across one or more columns. - else if ((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW)) { - colClientAnchorDetail = this.calculateColumnLocation(sheet, - colNumber, reqImageWidthMM); - } - } - // If the column is wider than the image. - else { - // Mow many co-ordinate positions are there per millimetre? - colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - // Given the width of the image, what should be it's co-ordinate? - pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM); - colClientAnchorDetail = new ClientAnchorDetail(colNumber, - colNumber, pictureWidthCoordinates); - } - return(colClientAnchorDetail); - } - - /** - * Determines whether the sheet's row should be re-sized to accomodate - * the image, adjusts the rows height if necessary and creates then - * returns a ClientAnchorDetail object that facilitates construction of - * an HSSFClientAnchor that will fix the image on the sheet and establish - * it's size. - * - * @param sheet A reference to the sheet that will 'contain' the image. - * @param rowNumber A primtive int that contains the index number of a - * row on the sheet. - * @param reqImageHeightMM A primtive double that contains the required - * height of the image in millimetres - * @param resizeBehaviour A primitve int whose value will indicate how the - * height of the row should be adjusted if the - * required height of the image is greater than the - * height of the row. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the row containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number of the row containing the cell whose - * top left hand corner also defines the bottom right hand - * corner of the image and an inset that determines how far the - * bottom edge of the image can protrude into the next (lower) - * row - expressed as a specific number of co-ordinate positions. - */ - private ClientAnchorDetail fitImageToRows(HSSFSheet sheet, int rowNumber, - double reqImageHeightMM, int resizeBehaviour) { - HSSFRow row = null; - double rowHeightMM = 0.0D; - double rowCoordinatesPerMM = 0.0D; - int pictureHeightCoordinates = 0; - ClientAnchorDetail rowClientAnchorDetail = null; - - // Get the row and it's height - row = sheet.getRow(rowNumber); - if(row == null) { - // Create row if it does not exist. - row = sheet.createRow(rowNumber); - } - - // Get the row's height in millimetres - rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE; - - // Check that the row's height will accomodate the image at the required - // dimensions. If the height of the row is LESS than the required height - // of the image, decide how the application should respond - resize the - // row or overlay the image across a series of rows. - if(rowHeightMM < reqImageHeightMM) { - if((resizeBehaviour == AddDimensionedImage.EXPAND_ROW) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) { - row.setHeightInPoints((float)(reqImageHeightMM * - ConvertImageUnits.POINTS_PER_MILLIMETRE)); - rowHeightMM = reqImageHeightMM; - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM); - rowClientAnchorDetail = new ClientAnchorDetail(rowNumber, - rowNumber, pictureHeightCoordinates); - } - // If the user has chosen to overlay both rows and columns or just - // to expand ONLY the size of the columns, then calculate how to lay - // the image out ver one or more rows. - else if((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN)) { - rowClientAnchorDetail = this.calculateRowLocation(sheet, - rowNumber, reqImageHeightMM); - } - } - // Else, if the image is smaller than the space available - else { - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM); - rowClientAnchorDetail = new ClientAnchorDetail(rowNumber, - rowNumber, pictureHeightCoordinates); - } - return(rowClientAnchorDetail); - } - - /** - * If the image is to overlie more than one column, calculations need to be - * performed to determine how many columns and whether the image will - * overlie just a part of one column in order to be presented at the - * required size. - * - * @param sheet The sheet that will 'contain' the image. - * @param startingColumn A primitive int whose value is the index of the - * column that contains the cell whose top left hand - * corner should be aligned with the top left hand - * corner of the image. - * @param reqImageWidthMM A primitive double whose value will indicate the - * required width of the image in millimetres. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the column containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number column containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the right hand - * edge of the image can protrude into the next column - expressed - * as a specific number of co-ordinate positions. - */ - private ClientAnchorDetail calculateColumnLocation(HSSFSheet sheet, - int startingColumn, - double reqImageWidthMM) { - ClientAnchorDetail anchorDetail = null; - double totalWidthMM = 0.0D; - double colWidthMM = 0.0D; - double overlapMM = 0.0D; - double coordinatePositionsPerMM = 0.0D; - int toColumn = startingColumn; - int inset = 0; - - // Calculate how many columns the image will have to - // span in order to be presented at the required size. - while(totalWidthMM < reqImageWidthMM) { - colWidthMM = ConvertImageUnits.widthUnits2Millimetres( - (short)(sheet.getColumnWidth(toColumn))); - // Note use of the cell border width constant. Testing with an image - // declared to fit exactly into one column demonstrated that it's - // width was greater than the width of the column the POI returned. - // Further, this difference was a constant value that I am assuming - // related to the cell's borders. Either way, that difference needs - // to be allowed for in this calculation. - totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES); - toColumn++; - } - // De-crement by one the last column value. - toColumn--; - // Highly unlikely that this will be true but, if the width of a series - // of columns is exactly equal to the required width of the image, then - // simply build a ClientAnchorDetail object with an inset equal to the - // total number of co-ordinate positions available in a column, a - // from column co-ordinate (top left hand corner) equal to the value - // of the startingColumn parameter and a to column co-ordinate equal - // to the toColumn variable. - // - // Convert both values to ints to perform the test. - if((int)totalWidthMM == (int)reqImageWidthMM) { - // A problem could occur if the image is sized to fit into one or - // more columns. If that occurs, the value in the toColumn variable - // will be in error. To overcome this, there are two options, to - // ibcrement the toColumn variable's value by one or to pass the - // total number of co-ordinate positions to the third paramater - // of the ClientAnchorDetail constructor. For no sepcific reason, - // the latter option is used below. - anchorDetail = new ClientAnchorDetail(startingColumn, - toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS); - } - // In this case, the image will overlap part of another column and it is - // necessary to calculate just how much - this will become the inset - // for the ClientAnchorDetail object. - else { - // Firstly, claculate how much of the image should overlap into - // the next column. - overlapMM = reqImageWidthMM - (totalWidthMM - colWidthMM); - - // When the required size is very close indded to the column size, - // the calcaulation above can produce a negative value. To prevent - // problems occuring in later caculations, this is simply removed - // be setting the overlapMM value to zero. - if(overlapMM < 0) { - overlapMM = 0.0D; - } - - // Next, from the columns width, calculate how many co-ordinate - // positons there are per millimetre - coordinatePositionsPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - // From this figure, determine how many co-ordinat positions to - // inset the left hand or bottom edge of the image. - inset = (int)(coordinatePositionsPerMM * overlapMM); - - // Now create the ClientAnchorDetail object, setting the from and to - // columns and the inset. - anchorDetail = new ClientAnchorDetail(startingColumn, toColumn, inset); - } - return(anchorDetail); - } - - /** - * If the image is to overlie more than one rows, calculations need to be - * performed to determine how many rows and whether the image will - * overlie just a part of one row in order to be presented at the - * required size. - * - * @param sheet The sheet that will 'contain' the image. - * @param startingRow A primitive int whose value is the index of the row - * that contains the cell whose top left hand corner - * should be aligned with the top left hand corner of - * the image. - * @param reqImageHeightMM A primitive double whose value will indicate the - * required height of the image in millimetres. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the row containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number of the row containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the bottom edge - * can protrude into the next (lower) row - expressed as a specific - * number of co-ordinate positions. - */ - private ClientAnchorDetail calculateRowLocation(HSSFSheet sheet, - int startingRow, double reqImageHeightMM) { - ClientAnchorDetail clientAnchorDetail = null; - HSSFRow row = null; - double rowHeightMM = 0.0D; - double totalRowHeightMM = 0.0D; - double overlapMM = 0.0D; - double rowCoordinatesPerMM = 0.0D; - int toRow = startingRow; - int inset = 0; - - // Step through the rows in the sheet and accumulate a total of their - // heights. - while(totalRowHeightMM < reqImageHeightMM) { - row = sheet.getRow(toRow); - // Note, if the row does not already exist on the sheet then create - // it here. - if(row == null) { - row = sheet.createRow(toRow); - } - // Get the row's height in millimetres and add to the running total. - rowHeightMM = row.getHeightInPoints() / - ConvertImageUnits.POINTS_PER_MILLIMETRE; - totalRowHeightMM += rowHeightMM; - toRow++; - } - // Owing to the way the loop above works, the rowNumber will have been - // incremented one row too far. Undo that here. - toRow--; - // Check to see whether the image should occupy an exact number of - // rows. If so, build the ClientAnchorDetail record to point - // to those rows and with an inset of the total number of co-ordinate - // position in the row. - // - // To overcome problems that can occur with comparing double values for - // equality, cast both to int(s) to truncate the value; VERY crude and - // I do not really like it!! - if((int)totalRowHeightMM == (int)reqImageHeightMM) { - clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow, - ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS); - } - else { - // Calculate how far the image will project into the next row. Note - // that the height of the last row assessed is subtracted from the - // total height of all rows assessed so far. - overlapMM = reqImageHeightMM - (totalRowHeightMM - rowHeightMM); - - // To prevent an exception being thrown when the required width of - // the image is very close indeed to the column size. - if(overlapMM < 0) { - overlapMM = 0.0D; - } - - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - inset = (int)(overlapMM * rowCoordinatesPerMM); - clientAnchorDetail = new ClientAnchorDetail(startingRow, - toRow, inset); - } - return(clientAnchorDetail); - } - - /** - * Loads - reads in and converts into an array of byte(s) - an image from - * a named file. - * - * Note: this method should be modified so that the type of the image may - * also be passed to it. Currently, it assumes that all images are - * JPG/JPEG(s). - * - * @param imageFilename A String that encapsulates the path to and name - * of the file that contains the image which is to be - * 'loaded'. - * @return An array of type byte that contains the raw data of the named - * image. - * @throws java.io.FileNotFoundException Thrown if it was not possible to - * open the specified file. - * @throws java.io.IOException Thrown if reading the file failed or was - * interrupted. - */ - private byte[] imageToBytes(String imageFilename) throws IOException { - File imageFile = null; - FileInputStream fis = null; - ByteArrayOutputStream bos = null; - int read = 0; - try { - imageFile = new File(imageFilename); - fis = new FileInputStream(imageFile); - bos = new ByteArrayOutputStream(); - while((read = fis.read()) != -1) { - bos.write(read); - } - return(bos.toByteArray()); - } - finally { - if(fis != null) { - try { - fis.close(); - fis = null; - } - catch(IOException ioEx) { - // Nothing to do here - } - } - } - } - - /** - * The main entry point to the program. It contains code that demonstrates - * one way to use the program. - * - * Note, the code is not restricted to use on new workbooks only. If an - * image is to be inserted into an existing workbook. just open that - * workbook, gat a reference to a sheet and pass that; - * - * AddDimensionedImage addImage = new AddDimensionedImage(); - * - * File file = new File("....... Existing Workbook ......."); - * FileInputStream fis = new FileInputStream(file); - * HSSFWorkbook workbook = new HSSFWorkbook(fis); - * HSSFSheet sheet = workbook.getSheetAt(0); - * addImage.addImageToSheet("C3", sheet, "image.jpg", 30, 20, - * AddDimensionedImage.EXPAND.ROW); - * - * @param args the command line arguments - */ - public static void main(String[] args) { - String imageFile = null; - String outputFile = null; - FileOutputStream fos = null; - HSSFSheet sheet = null; - try { - if(args.length < 2){ - System.err.println("Usage: AddDimensionedImage imageFile outputFile"); - return; - } - imageFile = args[0]; - outputFile = args[1]; - - HSSFWorkbook workbook = new HSSFWorkbook(); - sheet = workbook.createSheet("Picture Test"); - new AddDimensionedImage().addImageToSheet("A1", sheet, - imageFile, 125, 125, - AddDimensionedImage.EXPAND_ROW_AND_COLUMN); - fos = new FileOutputStream(outputFile); - workbook.write(fos); - workbook.close(); - } - catch(FileNotFoundException fnfEx) { - System.out.println("Caught an: " + fnfEx.getClass().getName()); - System.out.println("Message: " + fnfEx.getMessage()); - System.out.println("Stacktrace follows..........."); - fnfEx.printStackTrace(System.out); - } - catch(IOException ioEx) { - System.out.println("Caught an: " + ioEx.getClass().getName()); - System.out.println("Message: " + ioEx.getMessage()); - System.out.println("Stacktrace follows..........."); - ioEx.printStackTrace(System.out); - } - finally { - try { - if(fos != null) { - fos.close(); - fos = null; - } - } catch(IOException ioEx) { - // I G N O R E - } - } - } - - /** - * The HSSFClientAnchor class accepts eight parameters. In order, these are; - * - * * How far the left hand edge of the image is inset from the left hand - * edge of the cell - * * How far the top edge of the image is inset from the top of the cell - * * How far the right hand edge of the image is inset from the left - * hand edge of the cell - * * How far the bottom edge of the image is inset from the top of the - * cell. - * * Together, parameters five and six determine the column and row - * co-ordinates of the cell whose top left hand corner will be aligned - * with the image's top left hand corner. - * * Together, parameter seven and eight determine the column and row - * co-ordinates of the cell whose top left hand corner will be aligned - * with the images bottom right hand corner. - * - * An instance of the ClientAnchorDetail class provides three of the eight - * parameters, one of the co-ordinates for the images top left hand corner, - * one of the co-ordinates for the images bottom right hand corner and - * either how far the image should be inset from the top or the left hand - * edge of the cell. - * - * @author Mark Beardsley [mas at apache.org] - * @version 1.00 5th August 2009. - */ - public class ClientAnchorDetail { - - public int fromIndex = 0; - public int toIndex = 0; - public int inset = 0; - - /** - * Create a new instance of the ClientAnchorDetail class using the - * following parameters. - * - * @param fromIndex A primitive int that contains one of the - * co-ordinates (row or column index) for the top left - * hand corner of the image. - * @param toIndex A primitive int that contains one of the - * co-ordinates (row or column index) for the bottom - * right hand corner of the image. - * @param inset A primitive int that contains a value which indicates - * how far the image should be inset from the top or the - * left hand edge of a cell. - */ - public ClientAnchorDetail(int fromIndex, int toIndex, int inset) { - this.fromIndex = fromIndex; - this.toIndex = toIndex; - this.inset = inset; - } - - /** - * Get one of the number of the column or row that contains the cell - * whose top left hand corner will be aligned with the top left hand - * corner of the image. - * - * @return The value - row or column index - for one of the co-ordinates - * of the top left hand corner of the image. - */ - public int getFromIndex() { - return(this.fromIndex); - } - - /** - * Get one of the number of the column or row that contains the cell - * whose top left hand corner will be aligned with the bottom righ hand - * corner of the image. - * - * @return The value - row or column index - for one of the co-ordinates - * of the bottom right hand corner of the image. - */ - public int getToIndex() { - return(this.toIndex); - } - - /** - * Get the image's offset from the edge of a cell. - * - * @return How far either the right hand or bottom edge of the image is - * inset from the left hand or top edge of a cell. - */ - public int getInset() { - return(this.inset); - } - } - - /** - * Utility methods used to convert Excel's character based column and row - * size measurements into pixels and/or millimetres. The class also contains - * various constants that are required in other calculations. - * - * @author xio[darjino@hotmail.com] - * @version 1.01 30th July 2009. - * Added by Mark Beardsley [msb at apache.org]. - * Additional constants. - * widthUnits2Millimetres() and millimetres2Units() methods. - */ - public static class ConvertImageUnits { - - // Each cell conatins a fixed number of co-ordinate points; this number - // does not vary with row height or column width or with font. These two - // constants are defined below. - public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB - public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255; // MB - // The resoultion of an image can be expressed as a specific number - // of pixels per inch. Displays and printers differ but 96 pixels per - // inch is an acceptable standard to beging with. - public static final int PIXELS_PER_INCH = 96; // MB - // Cnstants that defines how many pixels and points there are in a - // millimetre. These values are required for the conversion algorithm. - public static final double PIXELS_PER_MILLIMETRES = 3.78; // MB - public static final double POINTS_PER_MILLIMETRE = 2.83; // MB - // The column width returned by HSSF and the width of a picture when - // positioned to exactly cover one cell are different by almost exactly - // 2mm - give or take rounding errors. This constant allows that - // additional amount to be accounted for when calculating how many - // celles the image ought to overlie. - public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D; // MB - public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256; - public static final int UNIT_OFFSET_LENGTH = 7; - public static final int[] UNIT_OFFSET_MAP = new int[] - { 0, 36, 73, 109, 146, 182, 219 }; - - /** - * pixel units to excel width units(units of 1/256th of a character width) - * @param pxs - * @return - */ - public static short pixel2WidthUnits(int pxs) { - short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * - (pxs / UNIT_OFFSET_LENGTH)); - widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)]; - return widthUnits; - } - - /** - * excel width units(units of 1/256th of a character width) to pixel - * units. - * - * @param widthUnits - * @return - */ - public static int widthUnits2Pixel(short widthUnits) { - int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) - * UNIT_OFFSET_LENGTH; - int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR; - pixels += Math.round(offsetWidthUnits / - ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH)); - return pixels; - } - - /** - * Convert Excel's width units into millimetres. - * - * @param widthUnits The width of the column or the height of the - * row in Excel's units. - * @return A primitive double that contains the columns width or rows - * height in millimetres. - */ - public static double widthUnits2Millimetres(short widthUnits) { - return(ConvertImageUnits.widthUnits2Pixel(widthUnits) / - ConvertImageUnits.PIXELS_PER_MILLIMETRES); - } - - /** - * Convert into millimetres Excel's width units.. - * - * @param millimetres A primitive double that contains the columns - * width or rows height in millimetres. - * @return A primitive int that contains the columns width or rows - * height in Excel's units. - */ - public static int millimetres2WidthUnits(double millimetres) { - return(ConvertImageUnits.pixel2WidthUnits((int)(millimetres * - ConvertImageUnits.PIXELS_PER_MILLIMETRES))); - } - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Alignment.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Alignment.java deleted file mode 100644 index 43fb75db1..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Alignment.java +++ /dev/null @@ -1,73 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.HorizontalAlignment; - -/** - * Shows how various alignment options work. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class Alignment { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - HSSFRow row = sheet.createRow(2); - createCell(wb, row, 0, HorizontalAlignment.CENTER); - createCell(wb, row, 1, HorizontalAlignment.CENTER_SELECTION); - createCell(wb, row, 2, HorizontalAlignment.FILL); - createCell(wb, row, 3, HorizontalAlignment.GENERAL); - createCell(wb, row, 4, HorizontalAlignment.JUSTIFY); - createCell(wb, row, 5, HorizontalAlignment.LEFT); - createCell(wb, row, 6, HorizontalAlignment.RIGHT); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } - - /** - * Creates a cell and aligns it a certain way. - * - * @param wb the workbook - * @param row the row to create the cell in - * @param column the column number to create the cell in - * @param align the alignment for the cell. - */ - private static void createCell(HSSFWorkbook wb, HSSFRow row, int column, HorizontalAlignment align) { - HSSFCell cell = row.createCell(column); - cell.setCellValue("Align It"); - HSSFCellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(align); - cell.setCellStyle(cellStyle); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java deleted file mode 100644 index cf3775200..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java +++ /dev/null @@ -1,172 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Font; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Demonstrates many features of the user API at once. Used in the HOW-TO guide. - * - * @author Glen Stampoultzis (glens at apache.org) - * @author Andrew Oliver (acoliver at apache.org) - */ -public class BigExample { - public static void main(String[] args) throws IOException { - int rownum; - - // create a new file - FileOutputStream out = new FileOutputStream("workbook.xls"); - // create a new workbook - HSSFWorkbook wb = new HSSFWorkbook(); - // create a new sheet - HSSFSheet s = wb.createSheet(); - // declare a row object reference - HSSFRow r = null; - // declare a cell object reference - HSSFCell c = null; - // create 3 cell styles - HSSFCellStyle cs = wb.createCellStyle(); - HSSFCellStyle cs2 = wb.createCellStyle(); - HSSFCellStyle cs3 = wb.createCellStyle(); - // create 2 fonts objects - HSSFFont f = wb.createFont(); - HSSFFont f2 = wb.createFont(); - - //set font 1 to 12 point type - f.setFontHeightInPoints((short) 12); - //make it red - f.setColor(HSSFColor.RED.index); - // make it bold - //arial is the default font - f.setBoldweight(Font.BOLDWEIGHT_BOLD); - - //set font 2 to 10 point type - f2.setFontHeightInPoints((short) 10); - //make it the color at palette index 0xf (white) - f2.setColor(HSSFColor.WHITE.index); - //make it bold - f2.setBoldweight(Font.BOLDWEIGHT_BOLD); - - //set cell stlye - cs.setFont(f); - //set the cell format see HSSFDataFromat for a full list - cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - - //set a thin border - cs2.setBorderBottom(CellStyle.BORDER_THIN); - //fill w fg fill color - cs2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - // set foreground fill to red - cs2.setFillForegroundColor(HSSFColor.RED.index); - - // set the font - cs2.setFont(f2); - - // set the sheet name to HSSF Test - wb.setSheetName(0, "HSSF Test"); - // create a sheet with 300 rows (0-299) - for (rownum = 0; rownum < 300; rownum++) - { - // create a row - r = s.createRow(rownum); - // on every other row - if ((rownum % 2) == 0) - { - // make the row height bigger (in twips - 1/20 of a point) - r.setHeight((short) 0x249); - } - - //r.setRowNum(( short ) rownum); - // create 50 cells (0-49) (the += 2 becomes apparent later - for (int cellnum = 0; cellnum < 50; cellnum += 2) - { - // create a numeric cell - c = r.createCell(cellnum); - // do some goofy math to demonstrate decimals - c.setCellValue(rownum * 10000 + cellnum - + (((double) rownum / 1000) - + ((double) cellnum / 10000))); - - // on every other row - if ((rownum % 2) == 0) - { - // set this cell to the first cell style we defined - c.setCellStyle(cs); - } - - // create a string cell (see why += 2 in the - c = r.createCell(cellnum + 1); - - // set the cell's string value to "TEST" - c.setCellValue("TEST"); - // make this column a bit wider - s.setColumnWidth(cellnum + 1, (int)((50 * 8) / ((double) 1 / 20))); - - // on every other row - if ((rownum % 2) == 0) - { - // set this to the white on red cell style - // we defined above - c.setCellStyle(cs2); - } - - } - } - - //draw a thick black border on the row at the bottom using BLANKS - // advance 2 rows - rownum++; - rownum++; - - r = s.createRow(rownum); - - // define the third style to be the default - // except with a thick black border at the bottom - cs3.setBorderBottom(CellStyle.BORDER_THICK); - - //create 50 cells - for (int cellnum =0; cellnum < 50; cellnum++) { - //create a blank type cell (no value) - c = r.createCell(cellnum); - // set it to the thick black border style - c.setCellStyle(cs3); - } - - //end draw thick black border - - - // demonstrate adding/naming and deleting a sheet - // create a sheet, set its title then delete it - wb.createSheet(); - wb.setSheetName(1, "DeletedSheet"); - wb.removeSheetAt(1); - //end deleted sheet - - // write the workbook to the output stream - // close our file (don't blow out our file handles - wb.write(out); - out.close(); - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Borders.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Borders.java deleted file mode 100644 index d29635004..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Borders.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.hssf.util.HSSFColor; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Demonstrates how to create borders around cells. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class Borders { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - HSSFRow row = sheet.createRow(1); - - // Create a cell and put a value in it. - HSSFCell cell = row.createCell(1); - cell.setCellValue(4); - - // Style the cell with borders all around. - HSSFCellStyle style = wb.createCellStyle(); - style.setBorderBottom(HSSFCellStyle.BORDER_THIN); - style.setBottomBorderColor(HSSFColor.BLACK.index); - style.setBorderLeft(HSSFCellStyle.BORDER_THIN); - style.setLeftBorderColor(HSSFColor.GREEN.index); - style.setBorderRight(HSSFCellStyle.BORDER_THIN); - style.setRightBorderColor(HSSFColor.BLUE.index); - style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED); - style.setTopBorderColor(HSSFColor.ORANGE.index); - cell.setCellStyle(style); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java deleted file mode 100644 index c3a213d58..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.hssf.util.HSSFColor; - -import java.io.*; - -/** - * Demonstrates how to work with excel cell comments. - * - *

    - * Excel comment is a kind of a text shape, - * so inserting a comment is very similar to placing a text box in a worksheet - *

    - * - * @author Yegor Kozlov - */ -public class CellComments { - - public static void main(String[] args) throws IOException { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF"); - - // Create the drawing patriarch. This is the top level container for all shapes including cell comments. - HSSFPatriarch patr = sheet.createDrawingPatriarch(); - - //create a cell in row 3 - HSSFCell cell1 = sheet.createRow(3).createCell(1); - cell1.setCellValue(new HSSFRichTextString("Hello, World")); - - //anchor defines size and position of the comment in worksheet - HSSFComment comment1 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 2, (short) 6, 5)); - - // set text in the comment - comment1.setString(new HSSFRichTextString("We can set comments in POI")); - - //set comment author. - //you can see it in the status bar when moving mouse over the commented cell - comment1.setAuthor("Apache Software Foundation"); - - // The first way to assign comment to a cell is via HSSFCell.setCellComment method - cell1.setCellComment(comment1); - - //create another cell in row 6 - HSSFCell cell2 = sheet.createRow(6).createCell(1); - cell2.setCellValue(36.6); - - - HSSFComment comment2 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 8, (short) 6, 11)); - //modify background color of the comment - comment2.setFillColor(204, 236, 255); - - HSSFRichTextString string = new HSSFRichTextString("Normal body temperature"); - - //apply custom font to the text in the comment - HSSFFont font = wb.createFont(); - font.setFontName("Arial"); - font.setFontHeightInPoints((short)10); - font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - font.setColor(HSSFColor.RED.index); - string.applyFont(font); - - comment2.setString(string); - comment2.setVisible(true); //by default comments are hidden. This one is always visible. - - comment2.setAuthor("Bill Gates"); - - /** - * The second way to assign comment to a cell is to implicitly specify its row and column. - * Note, it is possible to set row and column of a non-existing cell. - * It works, the comment is visible. - */ - comment2.setRow(6); - comment2.setColumn(1); - - FileOutputStream out = new FileOutputStream("poi_comment.xls"); - wb.write(out); - out.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellTypes.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellTypes.java deleted file mode 100644 index 3e31d11f2..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellTypes.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Date; - -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.CellType; - -public class CellTypes { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - HSSFRow row = sheet.createRow(2); - row.createCell(0).setCellValue(1.1); - row.createCell(1).setCellValue(new Date()); - row.createCell(2).setCellValue("a string"); - row.createCell(3).setCellValue(true); - row.createCell(4).setCellType(CellType.ERROR); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java deleted file mode 100644 index d2141b050..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFCell; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Illustrates how to create cell values. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class CreateCells { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - HSSFRow row = sheet.createRow(0); - // Create a cell and put a value in it. - HSSFCell cell = row.createCell(0); - cell.setCellValue(1); - - // Or do it on one line. - row.createCell(1).setCellValue(1.2); - row.createCell(2).setCellValue("This is a string"); - row.createCell(3).setCellValue(true); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateDateCells.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateDateCells.java deleted file mode 100644 index 746fd536b..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateDateCells.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Date; - -/** - * An example on how to cells with dates. The important thing to note - * about dates is that they are really normal numeric cells that are - * formatted specially. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class CreateDateCells { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - HSSFRow row = sheet.createRow(0); - - // Create a cell and put a date value in it. The first cell is not styled as a date. - HSSFCell cell = row.createCell(0); - cell.setCellValue(new Date()); - - // we style the second cell as a date (and time). It is important to create a new cell style from the workbook - // otherwise you can end up modifying the built in style and effecting not only this cell but other cells. - HSSFCellStyle cellStyle = wb.createCellStyle(); - cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm")); - cell = row.createCell(1); - cell.setCellValue(new Date()); - cell.setCellStyle(cellStyle); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmeddedObjects.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmeddedObjects.java deleted file mode 100644 index 9af41063e..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmeddedObjects.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileInputStream; -import java.util.Iterator; - -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; -import org.apache.poi.hssf.usermodel.HSSFObjectData; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hwpf.HWPFDocument; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * Demonstrates how you can extract embedded data from a .xls file - */ -public class EmeddedObjects { - @SuppressWarnings("unused") - public static void main(String[] args) throws Exception { - POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(args[0])); - HSSFWorkbook workbook = new HSSFWorkbook(fs); - for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) { - //the OLE2 Class Name of the object - String oleName = obj.getOLE2ClassName(); - if (oleName.equals("Worksheet")) { - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(dn, fs, false); - //System.out.println(entry.getName() + ": " + embeddedWorkbook.getNumberOfSheets()); - embeddedWorkbook.close(); - } else if (oleName.equals("Document")) { - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - HWPFDocument embeddedWordDocument = new HWPFDocument(dn); - //System.out.println(entry.getName() + ": " + embeddedWordDocument.getRange().text()); - } else if (oleName.equals("Presentation")) { - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - HSLFSlideShow embeddedPowerPointDocument = new HSLFSlideShow(new HSLFSlideShowImpl(dn)); - //System.out.println(entry.getName() + ": " + embeddedPowerPointDocument.getSlides().length); - } else { - if(obj.hasDirectoryEntry()){ - // The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - for (Iterator entries = dn.getEntries(); entries.hasNext();) { - Entry entry = entries.next(); - //System.out.println(oleName + "." + entry.getName()); - } - } else { - // There is no DirectoryEntry - // Recover the object's data from the HSSFObjectData instance. - byte[] objectData = obj.getObjectData(); - } - } - } - workbook.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java deleted file mode 100644 index a324b3af4..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java +++ /dev/null @@ -1,119 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; -import org.apache.poi.hssf.eventusermodel.HSSFListener; -import org.apache.poi.hssf.eventusermodel.HSSFRequest; -import org.apache.poi.hssf.record.*; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * This example shows how to use the event API for reading a file. - */ -public class EventExample - implements HSSFListener -{ - private SSTRecord sstrec; - - /** - * This method listens for incoming records and handles them as required. - * @param record The record that was found while reading. - */ - @Override - public void processRecord(Record record) - { - switch (record.getSid()) - { - // the BOFRecord can represent either the beginning of a sheet or the workbook - case BOFRecord.sid: - BOFRecord bof = (BOFRecord) record; - if (bof.getType() == BOFRecord.TYPE_WORKBOOK) - { - System.out.println("Encountered workbook"); - // assigned to the class level member - } else if (bof.getType() == BOFRecord.TYPE_WORKSHEET) - { - System.out.println("Encountered sheet reference"); - } - break; - case BoundSheetRecord.sid: - BoundSheetRecord bsr = (BoundSheetRecord) record; - System.out.println("New sheet named: " + bsr.getSheetname()); - break; - case RowRecord.sid: - RowRecord rowrec = (RowRecord) record; - System.out.println("Row found, first column at " - + rowrec.getFirstCol() + " last column at " + rowrec.getLastCol()); - break; - case NumberRecord.sid: - NumberRecord numrec = (NumberRecord) record; - System.out.println("Cell found with value " + numrec.getValue() - + " at row " + numrec.getRow() + " and column " + numrec.getColumn()); - break; - // SSTRecords store a array of unique strings used in Excel. - case SSTRecord.sid: - sstrec = (SSTRecord) record; - for (int k = 0; k < sstrec.getNumUniqueStrings(); k++) - { - System.out.println("String table value " + k + " = " + sstrec.getString(k)); - } - break; - case LabelSSTRecord.sid: - LabelSSTRecord lrec = (LabelSSTRecord) record; - System.out.println("String cell found with value " - + sstrec.getString(lrec.getSSTIndex())); - break; - } - } - - /** - * Read an excel file and spit out what we find. - * - * @param args Expect one argument that is the file to read. - * @throws IOException When there is an error processing the file. - */ - public static void main(String[] args) throws IOException - { - // create a new file input stream with the input file specified - // at the command line - FileInputStream fin = new FileInputStream(args[0]); - // create a new org.apache.poi.poifs.filesystem.Filesystem - POIFSFileSystem poifs = new POIFSFileSystem(fin); - // get the Workbook (excel part) stream in a InputStream - InputStream din = poifs.createDocumentInputStream("Workbook"); - // construct out HSSFRequest object - HSSFRequest req = new HSSFRequest(); - // lazy listen for ALL records with the listener shown above - req.addListenerForAllRecords(new EventExample()); - // create our event factory - HSSFEventFactory factory = new HSSFEventFactory(); - // process our events based on the document input stream - factory.processEvents(req, din); - // once all the events are processed close our file input stream - fin.close(); - // and our document input stream (don't want to leak these!) - din.close(); - System.out.println("done."); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/FrillsAndFills.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/FrillsAndFills.java deleted file mode 100644 index 02b7cb3e3..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/FrillsAndFills.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.hssf.util.HSSFColor; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Shows how to use various fills. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class FrillsAndFills { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - HSSFRow row = sheet.createRow(1); - - // Aqua background - HSSFCellStyle style = wb.createCellStyle(); - style.setFillBackgroundColor(HSSFColor.AQUA.index); - style.setFillPattern(HSSFCellStyle.BIG_SPOTS); - HSSFCell cell = row.createCell(1); - cell.setCellValue("X"); - cell.setCellStyle(style); - - // Orange "foreground", foreground being the fill foreground not the font color. - style = wb.createCellStyle(); - style.setFillForegroundColor(HSSFColor.ORANGE.index); - style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - cell = row.createCell(2); - cell.setCellValue("X"); - cell.setCellStyle(style); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java deleted file mode 100644 index 2f67f7f0e..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java +++ /dev/null @@ -1,256 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Locale; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFDataFormat; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFRichTextString; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * File for HSSF testing/examples - * - * THIS IS NOT THE MAIN HSSF FILE!! This is a utility for testing functionality. - * It does contain sample API usage that may be educational to regular API - * users. - */ -public final class HSSFReadWrite { - - /** - * creates an {@link HSSFWorkbook} the specified OS filename. - */ - private static HSSFWorkbook readFile(String filename) throws IOException { - FileInputStream fis = new FileInputStream(filename); - try { - return new HSSFWorkbook(fis); - } finally { - fis.close(); - } - } - - /** - * given a filename this outputs a sample sheet with just a set of - * rows/cells. - */ - private static void testCreateSampleSheet(String outputFilename) throws IOException { - int rownum; - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet s = wb.createSheet(); - HSSFCellStyle cs = wb.createCellStyle(); - HSSFCellStyle cs2 = wb.createCellStyle(); - HSSFCellStyle cs3 = wb.createCellStyle(); - HSSFFont f = wb.createFont(); - HSSFFont f2 = wb.createFont(); - - f.setFontHeightInPoints((short) 12); - f.setColor((short) 0xA); - f.setBold(true); - f2.setFontHeightInPoints((short) 10); - f2.setColor((short) 0xf); - f2.setBold(true); - cs.setFont(f); - cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - cs2.setBorderBottom(BorderStyle.THIN); - cs2.setFillPattern((short) 1); // fill w fg - cs2.setFillForegroundColor((short) 0xA); - cs2.setFont(f2); - wb.setSheetName(0, "HSSF Test"); - for (rownum = 0; rownum < 300; rownum++) { - HSSFRow r = s.createRow(rownum); - if ((rownum % 2) == 0) { - r.setHeight((short) 0x249); - } - - for (int cellnum = 0; cellnum < 50; cellnum += 2) { - HSSFCell c = r.createCell(cellnum); - c.setCellValue(rownum * 10000 + cellnum - + (((double) rownum / 1000) + ((double) cellnum / 10000))); - if ((rownum % 2) == 0) { - c.setCellStyle(cs); - } - c = r.createCell(cellnum + 1); - c.setCellValue(new HSSFRichTextString("TEST")); - // 50 characters divided by 1/20th of a point - s.setColumnWidth(cellnum + 1, (int) (50 * 8 / 0.05)); - if ((rownum % 2) == 0) { - c.setCellStyle(cs2); - } - } - } - - // draw a thick black border on the row at the bottom using BLANKS - rownum++; - rownum++; - HSSFRow r = s.createRow(rownum); - cs3.setBorderBottom(BorderStyle.THICK); - for (int cellnum = 0; cellnum < 50; cellnum++) { - HSSFCell c = r.createCell(cellnum); - c.setCellStyle(cs3); - } - s.addMergedRegion(new CellRangeAddress(0, 3, 0, 3)); - s.addMergedRegion(new CellRangeAddress(100, 110, 100, 110)); - - // end draw thick black border - // create a sheet, set its title then delete it - wb.createSheet(); - wb.setSheetName(1, "DeletedSheet"); - wb.removeSheetAt(1); - - // end deleted sheet - FileOutputStream out = new FileOutputStream(outputFilename); - try { - wb.write(out); - } finally { - out.close(); - } - - wb.close(); - } - - /** - * Method main - * - * Given 1 argument takes that as the filename, inputs it and dumps the - * cell values/types out to sys.out.
    - * - * given 2 arguments where the second argument is the word "write" and the - * first is the filename - writes out a sample (test) spreadsheet - * see {@link HSSFReadWrite#testCreateSampleSheet(String)}.
    - * - * given 2 arguments where the first is an input filename and the second - * an output filename (not write), attempts to fully read in the - * spreadsheet and fully write it out.
    - * - * given 3 arguments where the first is an input filename and the second an - * output filename (not write) and the third is "modify1", attempts to read in the - * spreadsheet, deletes rows 0-24, 74-99. Changes cell at row 39, col 3 to - * "MODIFIED CELL" then writes it out. Hence this is "modify test 1". If you - * take the output from the write test, you'll have a valid scenario. - */ - public static void main(String[] args) { - if (args.length < 1) { - System.err.println("At least one argument expected"); - return; - } - - String fileName = args[0]; - try { - if (args.length < 2) { - - HSSFWorkbook wb = HSSFReadWrite.readFile(fileName); - - System.out.println("Data dump:\n"); - - for (int k = 0; k < wb.getNumberOfSheets(); k++) { - HSSFSheet sheet = wb.getSheetAt(k); - int rows = sheet.getPhysicalNumberOfRows(); - System.out.println("Sheet " + k + " \"" + wb.getSheetName(k) + "\" has " + rows - + " row(s)."); - for (int r = 0; r < rows; r++) { - HSSFRow row = sheet.getRow(r); - if (row == null) { - continue; - } - - int cells = row.getPhysicalNumberOfCells(); - System.out.println("\nROW " + row.getRowNum() + " has " + cells - + " cell(s)."); - for (int c = 0; c < cells; c++) { - HSSFCell cell = row.getCell(c); - String value = null; - - switch (cell.getCellTypeEnum()) { - - case FORMULA: - value = "FORMULA value=" + cell.getCellFormula(); - break; - - case NUMERIC: - value = "NUMERIC value=" + cell.getNumericCellValue(); - break; - - case STRING: - value = "STRING value=" + cell.getStringCellValue(); - break; - - default: - } - System.out.println("CELL col=" + cell.getColumnIndex() + " VALUE=" - + value); - } - } - } - wb.close(); - } else if (args.length == 2) { - if (args[1].toLowerCase(Locale.ROOT).equals("write")) { - System.out.println("Write mode"); - long time = System.currentTimeMillis(); - HSSFReadWrite.testCreateSampleSheet(fileName); - - System.out.println("" + (System.currentTimeMillis() - time) - + " ms generation time"); - } else { - System.out.println("readwrite test"); - HSSFWorkbook wb = HSSFReadWrite.readFile(fileName); - FileOutputStream stream = new FileOutputStream(args[1]); - - wb.write(stream); - stream.close(); - wb.close(); - } - } else if (args.length == 3 && args[2].toLowerCase(Locale.ROOT).equals("modify1")) { - // delete row 0-24, row 74 - 99 && change cell 3 on row 39 to string "MODIFIED CELL!!" - - HSSFWorkbook wb = HSSFReadWrite.readFile(fileName); - FileOutputStream stream = new FileOutputStream(args[1]); - HSSFSheet sheet = wb.getSheetAt(0); - - for (int k = 0; k < 25; k++) { - HSSFRow row = sheet.getRow(k); - - sheet.removeRow(row); - } - for (int k = 74; k < 100; k++) { - HSSFRow row = sheet.getRow(k); - - sheet.removeRow(row); - } - HSSFRow row = sheet.getRow(39); - HSSFCell cell = row.getCell(3); - cell.setCellValue("MODIFIED CELL!!!!!"); - - wb.write(stream); - stream.close(); - wb.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HyperlinkFormula.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HyperlinkFormula.java deleted file mode 100644 index 148b2a58b..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HyperlinkFormula.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.CellType; - -/** - * Test if hyperlink formula, with url that got more than 127 characters, works - * - * @author Bernard Chesnoy - */ -public class HyperlinkFormula { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - HSSFRow row = sheet.createRow(0); - - HSSFCell cell = row.createCell(0); - cell.setCellType(CellType.FORMULA); - cell.setCellFormula("HYPERLINK(\"http://127.0.0.1:8080/toto/truc/index.html?test=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\", \"test\")"); - - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java deleted file mode 100644 index c1ccad910..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFCreationHelper; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFHyperlink; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor; - -/** - * Demonstrates how to create hyperlinks. - * - * @author Yegor Kozlov (yegor at apach.org) - */ -public class Hyperlinks { - - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFCreationHelper helper = wb.getCreationHelper(); - - //cell style for hyperlinks - //by default hyperlinks are blue and underlined - HSSFCellStyle hlink_style = wb.createCellStyle(); - HSSFFont hlink_font = wb.createFont(); - hlink_font.setUnderline(HSSFFont.U_SINGLE); - hlink_font.setColor(HSSFColor.BLUE.index); - hlink_style.setFont(hlink_font); - - HSSFCell cell; - HSSFSheet sheet = wb.createSheet("Hyperlinks"); - - //URL - cell = sheet.createRow(0).createCell(0); - cell.setCellValue("URL Link"); - HSSFHyperlink link = helper.createHyperlink(HyperlinkType.URL); - link.setAddress("http://poi.apache.org/"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - //link to a file in the current directory - cell = sheet.createRow(1).createCell(0); - cell.setCellValue("File Link"); - link = helper.createHyperlink(HyperlinkType.FILE); - link.setAddress("link1.xls"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - //e-mail link - cell = sheet.createRow(2).createCell(0); - cell.setCellValue("Email Link"); - link = helper.createHyperlink(HyperlinkType.EMAIL); - //note, if subject contains white spaces, make sure they are url-encoded - link.setAddress("mailto:poi@apache.org?subject=Hyperlinks"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - //link to a place in this workbook - - //create a target sheet and cell - HSSFSheet sheet2 = wb.createSheet("Target Sheet"); - sheet2.createRow(0).createCell(0).setCellValue("Target Cell"); - - cell = sheet.createRow(3).createCell(0); - cell.setCellValue("Worksheet Link"); - link = helper.createHyperlink(HyperlinkType.DOCUMENT); - link.setAddress("'Target Sheet'!A1"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - FileOutputStream out = new FileOutputStream("hssf-links.xls"); - wb.write(out); - out.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java deleted file mode 100644 index e1d4cbcbf..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java +++ /dev/null @@ -1,553 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFDataFormat; -import org.apache.poi.hssf.usermodel.HSSFRichTextString; - -/** - * This class contains code that demonstrates how to insert plain, numbered - * and bulleted lists into an Excel spreadsheet cell. - * - * Look at the code contained in the demonstrateMethodCalls() method. It calls - * other methods that create plain, numbered and bulleted single and - * multi-level lists. The demonstrateMethodCalls() method appears at the top - * of the class definition. - * - * Though different methods are provided to construct single and multi-level - * plain, numbered and bulleted lists, close examination will reveal that they - * are not strictly necessary. If the inputs to the listInCell() and - * multilLevelListInCell() methods are constructed to include the bullet - * character or the item numbers then these methods alone may be sufficient. - * - * @author Mark Beardsley [msb at apache.org] - */ -public class InCellLists { - - // This character looks like a solid, black, loser case letter 'o' - // positioned up from the base line of the text. - private static final char BULLET_CHARACTER = '\u2022'; - - // The tab character - \t - cannot be used to create a tab space - // within a cell as it is rendered as a square. Therefore, four - // spaces are used to simulate that character. - private static final String TAB = " "; - - /** - * Call each of the list creation methods. - * - * @param outputFilename A String that encapsulates the name of and path to - * the Excel spreadsheet file this code will create. - */ - public void demonstrateMethodCalls(String outputFilename) throws IOException { - HSSFWorkbook workbook = new HSSFWorkbook(); - try { - HSSFSheet sheet = workbook.createSheet("In Cell Lists"); - HSSFRow row = sheet.createRow(0); - - // Create a cell at A1 and insert a single, bulleted, item into - // that cell. - HSSFCell cell = row.createCell(0); - this.bulletedItemInCell(workbook, "List Item", cell); - - // Create a cell at A2 and insert a plain list - that is one - // whose items are neither bulleted or numbered - into that cell. - row = sheet.createRow(1); - cell = row.createCell(0); - ArrayList listItems = new ArrayList(); - listItems.add("List Item One."); - listItems.add("List Item Two."); - listItems.add("List Item Three."); - listItems.add("List Item Four."); - this.listInCell(workbook, listItems, cell); - // The row height and cell width are set here to ensure that the - // list may be seen. - row.setHeight((short)1100); - sheet.setColumnWidth(0, 9500); - - // Create a cell at A3 and insert a numbered list into that cell. - // Note that a couple of items have been added to the listItems - // ArrayList - row = sheet.createRow(2); - cell = row.createCell(0); - listItems.add("List Item Five."); - listItems.add("List Item Six."); - this.numberedListInCell(workbook, listItems, cell, 1, 2); - row.setHeight((short)1550); - - // Create a cell at A4 and insert a numbered list into that cell. - // Note that a couple of items have been added to the listItems - // ArrayList - row = sheet.createRow(3); - cell = row.createCell(0); - listItems.add("List Item Seven."); - listItems.add("List Item Eight."); - listItems.add("List Item Nine."); - listItems.add("List Item Ten."); - this.bulletedListInCell(workbook, listItems, cell); - row.setHeight((short)2550); - - // Insert a plain, multi-level list into cell A5. Note that - // the major difference here is that the list items are passed as - // an ArrayList of MultiLevelListItems. Note that an ArrayList - // of instances of an inner class was used here in preference to - // a Hashtable or HashMap as the ArrayList will preserve the - // ordering of the items added to it; the first item added will - // be the first item recovered and the last item added, the last - // item recovered. Alternatively, a LinkedHashMap could be used - // to preserve order. - row = sheet.createRow(4); - cell = row.createCell(0); - ArrayList multiLevelListItems = new ArrayList(); - listItems = new ArrayList(); - listItems.add("ML List Item One - Sub Item One."); - listItems.add("ML List Item One - Sub Item Two."); - listItems.add("ML List Item One - Sub Item Three."); - listItems.add("ML List Item One - Sub Item Four."); - multiLevelListItems.add(new MultiLevelListItem("List Item One.", listItems)); - // Passing either null or an empty ArrayList will signal that - // there are no lower level items associated with the top level - // item - multiLevelListItems.add(new MultiLevelListItem("List Item Two.", null)); - multiLevelListItems.add(new MultiLevelListItem("List Item Three.", null)); - listItems = new ArrayList(); - listItems.add("ML List Item Four - Sub Item One."); - listItems.add("ML List Item Four - Sub Item Two."); - listItems.add("ML List Item Four - Sub Item Three."); - multiLevelListItems.add(new MultiLevelListItem("List Item Four.", listItems)); - this.multiLevelListInCell(workbook, multiLevelListItems, cell); - row.setHeight((short)2800); - - // Insert a numbered multi-level list into cell A6. Note that the - // same ArrayList as constructed for the above plain multi-level - // list example will be re-used - row = sheet.createRow(5); - cell = row.createCell(0); - this.multiLevelNumberedListInCell(workbook, multiLevelListItems, - cell, 1, 1, 1, 2); - row.setHeight((short)2800); - - // Insert a numbered multi-level list into cell A7. Note that the - // same ArrayList as constructed for the plain multi-level list - // example will be re-used - row = sheet.createRow(6); - cell = row.createCell(0); - this.multiLevelBulletedListInCell(workbook, multiLevelListItems, cell); - row.setHeight((short)2800); - - // Save the completed workbook - FileOutputStream fos = new FileOutputStream(new File(outputFilename)); - try { - workbook.write(fos); - } finally { - fos.close(); - } - } - catch(FileNotFoundException fnfEx) { - System.out.println("Caught a: " + fnfEx.getClass().getName()); - System.out.println("Message: " + fnfEx.getMessage()); - System.out.println("Stacktrace follows..........."); - fnfEx.printStackTrace(System.out); - } - catch(IOException ioEx) { - System.out.println("Caught a: " + ioEx.getClass().getName()); - System.out.println("Message: " + ioEx.getMessage()); - System.out.println("Stacktrace follows..........."); - ioEx.printStackTrace(System.out); - } - finally { - workbook.close(); - } - } - - /** - * Inserts a single bulleted item into a cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param listItem An instance of the String class encapsulating the - * items text. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list item - * will be written. - */ - public void bulletedItemInCell(HSSFWorkbook workbook, String listItem, HSSFCell cell) { - // A format String must be built to ensure that the contents of the - // cell appear as a bulleted item. - HSSFDataFormat format = workbook.createDataFormat(); - String formatString = InCellLists.BULLET_CHARACTER + " @"; - int formatIndex = format.getFormat(formatString); - - // Construct an HSSFCellStyle and set it's data formt to use the - // object created above. - HSSFCellStyle bulletStyle = workbook.createCellStyle(); - bulletStyle.setDataFormat((short)formatIndex); - - // Set the cells contents and style. - cell.setCellValue(new HSSFRichTextString(listItem)); - cell.setCellStyle(bulletStyle); - } - - /** - * Inserts a list of plain items - that is items that are neither - * numbered or bulleted - into a single cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param listItems An ArrayList whose elements encapsulate the text for - * the list's items. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list - * will be written. - */ - public void listInCell(HSSFWorkbook workbook, ArrayList listItems, HSSFCell cell) { - StringBuilder buffer = new StringBuilder(); - HSSFCellStyle wrapStyle = workbook.createCellStyle(); - wrapStyle.setWrapText(true); - for(String listItem : listItems) { - buffer.append(listItem); - buffer.append("\n"); - } - // The StringBuffer's contents are the source for the contents - // of the cell. - cell.setCellValue(new HSSFRichTextString(buffer.toString().trim())); - cell.setCellStyle(wrapStyle); - } - - /** - * Inserts a numbered list into a single cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param listItems An ArrayList whose elements encapsulate the text for - * the lists items. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list - * will be written. - * @param startingValue A primitive int containing the number for the first - * item in the list. - * @param increment A primitive int containing the value that should be used - * to calculate subsequent item numbers. - */ - public void numberedListInCell(HSSFWorkbook workbook, - ArrayList listItems, - HSSFCell cell, - int startingValue, - int increment) { - StringBuilder buffer = new StringBuilder(); - int itemNumber = startingValue; - // Note that again, an HSSFCellStye object is required and that - // it's wrap text property should be set to 'true' - HSSFCellStyle wrapStyle = workbook.createCellStyle(); - wrapStyle.setWrapText(true); - // Note that the basic method is identical to the listInCell() method - // with one difference; a number prefixed to the items text. - for(String listItem : listItems) { - buffer.append(itemNumber).append(". "); - buffer.append(listItem); - buffer.append("\n"); - itemNumber += increment; - } - // The StringBuffer's contents are the source for the contents - // of the cell. - cell.setCellValue(new HSSFRichTextString(buffer.toString().trim())); - cell.setCellStyle(wrapStyle); - } - - /** - * Insert a bulleted list into a cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param listItems An ArrayList whose elements encapsulate the text for - * the lists items. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list - * will be written. - */ - public void bulletedListInCell(HSSFWorkbook workbook, - ArrayList listItems, - HSSFCell cell) { - StringBuilder buffer = new StringBuilder(); - // Note that again, an HSSFCellStye object is required and that - // it's wrap text property should be set to 'true' - HSSFCellStyle wrapStyle = workbook.createCellStyle(); - wrapStyle.setWrapText(true); - // Note that the basic method is identical to the listInCell() method - // with one difference; the bullet character prefixed to the items text. - for(String listItem : listItems) { - buffer.append(InCellLists.BULLET_CHARACTER + " "); - buffer.append(listItem); - buffer.append("\n"); - } - // The StringBuffer's contents are the source for the contents - // of the cell. - cell.setCellValue(new HSSFRichTextString(buffer.toString().trim())); - cell.setCellStyle(wrapStyle); - } - - /** - * Insert a multi-level list into a cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param multiLevelListItems An ArrayList whose elements contain instances - * of the MultiLevelListItem class. Each element - * encapsulates the text for the high level item - * along with an ArrayList. Each element of this - * ArrayList encapsulates the text for a lower - * level item. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list - * will be written. - */ - public void multiLevelListInCell(HSSFWorkbook workbook, - ArrayList multiLevelListItems, - HSSFCell cell) { - StringBuilder buffer = new StringBuilder(); - // Note that again, an HSSFCellStye object is required and that - // it's wrap text property should be set to 'true' - HSSFCellStyle wrapStyle = workbook.createCellStyle(); - wrapStyle.setWrapText(true); - // Step through the ArrayList of MultilLevelListItem instances. - for(MultiLevelListItem multiLevelListItem : multiLevelListItems) { - // For each element in the ArrayList, get the text for the high - // level list item...... - buffer.append(multiLevelListItem.getItemText()); - buffer.append("\n"); - // and then an ArrayList whose elements encapsulate the text - // for the lower level list items. - ArrayList lowerLevelItems = multiLevelListItem.getLowerLevelItems(); - if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { - for(String item : lowerLevelItems) { - buffer.append(InCellLists.TAB); - buffer.append(item); - buffer.append("\n"); - } - } - } - // The StringBuffer's contents are the source for the contents - // of the cell. - cell.setCellValue(new HSSFRichTextString(buffer.toString().trim())); - cell.setCellStyle(wrapStyle); - } - - /** - * Insert a multi-level list into a cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param multiLevelListItems An ArrayList whose elements contain instances - * of the MultiLevelListItem class. Each element - * encapsulates the text for the high level item - * along with an ArrayList. Each element of this - * ArrayList encapsulates the text for a lower - * level item. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list - * will be written. - * @param highLevelStartingValue A primitive int containing the number - * for the first high level item in the list. - * @param highLevelIncrement A primitive int containing the value that - * should be used to calculate the number of - * subsequent high level item. - * @param lowLevelStartingValue A primitive int will containing the number - * for the first low level item associated - * with a high level item. - * @param lowLevelIncrement A primitive int containing the value that - * should be used to calculate the number of - * subsequent low level item. - */ - public void multiLevelNumberedListInCell(HSSFWorkbook workbook, - ArrayList multiLevelListItems, - HSSFCell cell, - int highLevelStartingValue, - int highLevelIncrement, - int lowLevelStartingValue, - int lowLevelIncrement) { - StringBuilder buffer = new StringBuilder(); - int highLevelItemNumber = highLevelStartingValue; - // Note that again, an HSSFCellStye object is required and that - // it's wrap text property should be set to 'true' - HSSFCellStyle wrapStyle = workbook.createCellStyle(); - wrapStyle.setWrapText(true); - // Step through the ArrayList of MultilLevelListItem instances. - for(MultiLevelListItem multiLevelListItem : multiLevelListItems) { - // For each element in the ArrayList, get the text for the high - // level list item...... - buffer.append(highLevelItemNumber); - buffer.append(". "); - buffer.append(multiLevelListItem.getItemText()); - buffer.append("\n"); - // and then an ArrayList whose elements encapsulate the text - // for the lower level list items. - ArrayList lowerLevelItems = multiLevelListItem.getLowerLevelItems(); - if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { - int lowLevelItemNumber = lowLevelStartingValue; - for(String item : lowerLevelItems) { - buffer.append(InCellLists.TAB); - buffer.append(highLevelItemNumber); - buffer.append("."); - buffer.append(lowLevelItemNumber); - buffer.append(" "); - buffer.append(item); - buffer.append("\n"); - lowLevelItemNumber += lowLevelIncrement; - } - } - highLevelItemNumber += highLevelIncrement; - } - // The StringBuffer's contents are the source for the contents - // of the cell. - cell.setCellValue(new HSSFRichTextString(buffer.toString().trim())); - cell.setCellStyle(wrapStyle); - } - - /** - * Insert a bulleted multi-level list into a cell. - * - * @param workbook A reference to the HSSFWorkbook that 'contains' the - * cell. - * @param multiLevelListItems An ArrayList whose elements contain instances - * of the MultiLevelListItem class. Each element - * encapsulates the text for the high level item - * along with an ArrayList. Each element of this - * ArrayList encapsulates the text for a lower - * level item. - * @param cell An instance of the HSSFCell class that encapsulates a - * reference to the spreadsheet cell into which the list - * will be written. - */ - public void multiLevelBulletedListInCell(HSSFWorkbook workbook, - ArrayList multiLevelListItems, - HSSFCell cell) { - StringBuilder buffer = new StringBuilder(); - // Note that again, an HSSFCellStye object is required and that - // it's wrap text property should be set to 'true' - HSSFCellStyle wrapStyle = workbook.createCellStyle(); - wrapStyle.setWrapText(true); - // Step through the ArrayList of MultilLevelListItem instances. - for(MultiLevelListItem multiLevelListItem : multiLevelListItems) { - // For each element in the ArrayList, get the text for the high - // level list item...... - buffer.append(InCellLists.BULLET_CHARACTER); - buffer.append(" "); - buffer.append(multiLevelListItem.getItemText()); - buffer.append("\n"); - // and then an ArrayList whose elements encapsulate the text - // for the lower level list items. - ArrayList lowerLevelItems = multiLevelListItem.getLowerLevelItems(); - if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { - for(String item : lowerLevelItems) { - buffer.append(InCellLists.TAB); - buffer.append(InCellLists.BULLET_CHARACTER); - buffer.append(" "); - buffer.append(item); - buffer.append("\n"); - } - } - } - // The StringBuffer's contents are the source for the contents - // of the cell. - cell.setCellValue(new HSSFRichTextString(buffer.toString().trim())); - cell.setCellStyle(wrapStyle); - } - - /** - * The main entry point to the program. Demonstrates how to call the method - * that will create an Excel workbook containing many different sorts of - * lists. - * - * @param args the command line arguments. - */ - public static void main(String[] args) throws IOException { - new InCellLists().demonstrateMethodCalls("Latest In Cell List.xls"); - } - - /** - * An instance of this inner class models an item or element in a - * multi-level list. Each multi-level list item consists of the text for the - * high level items and an ArrayList containing the text for each of the - * associated lower level items. When written into a cell, each multi-level - * list item will have this general appearance. - * - * Item One - * Sub Item One. - * Sub Item Two. - * Item Two - * Sub Item One. - * Sub Item Two. - * etc. - * - * It would be quite possible to modify this class to model much more - * complex list structures descending through two, three or even more - * levels. - */ - public final class MultiLevelListItem { - - private String itemText = null; - private ArrayList lowerLevelItems = null; - - /** - * Create a new instance of the MultiLevelListItem class using the - * following parameters. - * - * @param itemText A String that encapsulates the text for the high - * level list item. - * @param lowerLevelItems An ArrayList whose elements encapsulate the - * text for the associated lower level list - * items. - */ - public MultiLevelListItem(String itemText, ArrayList lowerLevelItems) { - this.itemText = itemText; - this.lowerLevelItems = lowerLevelItems; - } - - /** - * Get the text for the high level list item. - * - * @return A String that encapsulates the text for the high level list - * item. - */ - public String getItemText() { - return(this.itemText); - } - - /** - * Get the text for the associated lower level list items. - * - * @return An ArrayList whose elements each encapsulate the text for a - * single associated lower level list item. - */ - public ArrayList getLowerLevelItems() { - return(this.lowerLevelItems); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/MergedCells.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/MergedCells.java deleted file mode 100644 index 31e5215b8..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/MergedCells.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; - -import java.io.IOException; -import java.io.FileOutputStream; - -/** - * An example of how to merge regions of cells. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class MergedCells { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - - HSSFRow row = sheet.createRow(1); - HSSFCell cell = row.createCell(1); - cell.setCellValue("This is a test of merging"); - - sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, 2)); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java deleted file mode 100644 index 018556f99..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.ss.usermodel.CellType; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Demonstrates how to use newlines in cells. - * - * @author Glen Stampoultzis (glens at apache.org) - * @author Fauzia Lala - */ -public class NewLinesInCells { - public static void main( String[] args ) throws IOException { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet s = wb.createSheet(); - HSSFRow r = null; - HSSFCell c = null; - HSSFCellStyle cs = wb.createCellStyle(); - HSSFFont f2 = wb.createFont(); - - cs = wb.createCellStyle(); - - cs.setFont(f2); - // Word Wrap MUST be turned on - cs.setWrapText(true); - - r = s.createRow(2); - r.setHeight((short) 0x349); - c = r.createCell(2); - c.setCellType(CellType.STRING); - c.setCellValue("Use \n with word wrap on to create a new line"); - c.setCellStyle(cs); - s.setColumnWidth(2, (int) ((50 * 8) / ((double) 1 / 20))); - - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewSheet.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewSheet.java deleted file mode 100644 index 495543e49..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewSheet.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.util.WorkbookUtil; - -/** - * Creates a new workbook with a sheet that's been explicitly defined. - */ -public abstract class NewSheet { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - wb.createSheet("new sheet"); - // create with default name - wb.createSheet(); - final String name = "second sheet"; - // setting sheet name later - wb.setSheetName(1, WorkbookUtil.createSafeSheetName(name)); - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewWorkbook.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewWorkbook.java deleted file mode 100644 index c1614e6c1..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewWorkbook.java +++ /dev/null @@ -1,42 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * This example creates a new blank workbook. This workbook will contain a single blank sheet. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class NewWorkbook -{ - public static void main(String[] args) - throws IOException - { - HSSFWorkbook wb = new HSSFWorkbook(); - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java deleted file mode 100644 index 68aafbc7c..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java +++ /dev/null @@ -1,322 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; - -import java.io.*; - -/** - * Demonstrates how to use the office drawing capabilities of POI. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class OfficeDrawing { - public static void main(String[] args) throws IOException { - // Create the workbook and sheets. - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet1 = wb.createSheet("new sheet"); - HSSFSheet sheet2 = wb.createSheet("second sheet"); - HSSFSheet sheet3 = wb.createSheet("third sheet"); - HSSFSheet sheet4 = wb.createSheet("fourth sheet"); - HSSFSheet sheet5 = wb.createSheet("fifth sheet"); - - // Draw stuff in them - drawSheet1( sheet1 ); - drawSheet2( sheet2 ); - drawSheet3( sheet3 ); - drawSheet4( sheet4, wb ); - drawSheet5( sheet5, wb ); - - // Write the file out. - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } - - private static void drawSheet1( HSSFSheet sheet1 ) - { - // Create a row and size one of the cells reasonably large. - HSSFRow row = sheet1.createRow(2); - row.setHeight((short) 2800); - row.createCell(1); - sheet1.setColumnWidth(2, 9000); - - // Create the drawing patriarch. This is the top level container for - // all shapes. - HSSFPatriarch patriarch = sheet1.createDrawingPatriarch(); - - // Draw some lines and an oval. - drawLinesToCenter( patriarch ); - drawManyLines( patriarch ); - drawOval( patriarch ); - drawPolygon( patriarch ); - - // Draw a rectangle. - HSSFSimpleShape rect = patriarch.createSimpleShape( new HSSFClientAnchor(100, 100, 900, 200, (short)0, 0, (short)0, 0) ); - rect.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE); - } - - private static void drawSheet2( HSSFSheet sheet2 ) - { - // Create a row and size one of the cells reasonably large. - HSSFRow row = sheet2.createRow(2); - row.createCell(1); - row.setHeightInPoints(240); - sheet2.setColumnWidth(2, 9000); - - // Create the drawing patriarch. This is the top level container for - // all shapes. This will clear out any existing shapes for that sheet. - HSSFPatriarch patriarch = sheet2.createDrawingPatriarch(); - - // Draw a grid in one of the cells. - drawGrid( patriarch ); - } - - private static void drawSheet3( HSSFSheet sheet3 ) - { - // Create a row and size one of the cells reasonably large - HSSFRow row = sheet3.createRow(2); - row.setHeightInPoints(140); - row.createCell(1); - sheet3.setColumnWidth(2, 9000); - - // Create the drawing patriarch. This is the top level container for - // all shapes. This will clear out any existing shapes for that sheet. - HSSFPatriarch patriarch = sheet3.createDrawingPatriarch(); - - // Create a shape group. - HSSFShapeGroup group = patriarch.createGroup( - new HSSFClientAnchor(0,0,900,200,(short)2,2,(short)2,2)); - - // Create a couple of lines in the group. - HSSFSimpleShape shape1 = group.createShape(new HSSFChildAnchor(3,3,500,500)); - shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - ( (HSSFChildAnchor) shape1.getAnchor() ).setAnchor((short)3,3,500,500); - HSSFSimpleShape shape2 = group.createShape(new HSSFChildAnchor((short)1,200,400,600)); - shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - - } - - private static void drawSheet4( HSSFSheet sheet4, HSSFWorkbook wb ) - { - // Create the drawing patriarch. This is the top level container for - // all shapes. This will clear out any existing shapes for that sheet. - HSSFPatriarch patriarch = sheet4.createDrawingPatriarch(); - - // Create a couple of textboxes - HSSFTextbox textbox1 = patriarch.createTextbox( - new HSSFClientAnchor(0,0,0,0,(short)1,1,(short)2,2)); - textbox1.setString(new HSSFRichTextString("This is a test") ); - HSSFTextbox textbox2 = patriarch.createTextbox( - new HSSFClientAnchor(0,0,900,100,(short)3,3,(short)3,4)); - textbox2.setString(new HSSFRichTextString("Woo") ); - textbox2.setFillColor(200,0,0); - textbox2.setLineStyle(HSSFSimpleShape.LINESTYLE_DOTGEL); - - // Create third one with some fancy font styling. - HSSFTextbox textbox3 = patriarch.createTextbox( - new HSSFClientAnchor(0,0,900,100,(short)4,4,(short)5,4+1)); - HSSFFont font = wb.createFont(); - font.setItalic(true); - font.setUnderline(HSSFFont.U_DOUBLE); - HSSFRichTextString string = new HSSFRichTextString("Woo!!!"); - string.applyFont(2,5,font); - textbox3.setString(string ); - textbox3.setFillColor(0x08000030); - textbox3.setLineStyle(HSSFSimpleShape.LINESTYLE_NONE); // no line around the textbox. - textbox3.setNoFill(true); // make it transparent - } - - private static void drawSheet5( HSSFSheet sheet5, HSSFWorkbook wb ) throws IOException - { - - // Create the drawing patriarch. This is the top level container for - // all shapes. This will clear out any existing shapes for that sheet. - HSSFPatriarch patriarch = sheet5.createDrawingPatriarch(); - - HSSFClientAnchor anchor; - anchor = new HSSFClientAnchor(0,0,0,255,(short)2,2,(short)4,7); - anchor.setAnchorType( AnchorType.MOVE_DONT_RESIZE ); - patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4.png", wb )); - - anchor = new HSSFClientAnchor(0,0,0,255,(short)4,2,(short)5,7); - anchor.setAnchorType( AnchorType.MOVE_DONT_RESIZE ); - patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4edited.png", wb )); - - anchor = new HSSFClientAnchor(0,0,1023,255,(short)6,2,(short)8,7); - anchor.setAnchorType( AnchorType.MOVE_DONT_RESIZE ); - HSSFPicture picture = patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4s.png", wb )); - //Reset the image to the original size. - picture.resize(); - picture.setLineStyle( HSSFShape.LINESTYLE_DASHDOTGEL ); - - } - - private static int loadPicture( String path, HSSFWorkbook wb ) throws IOException - { - int pictureIndex; - FileInputStream fis = null; - ByteArrayOutputStream bos = null; - try - { - fis = new FileInputStream( path); - bos = new ByteArrayOutputStream( ); - int c; - while ( (c = fis.read()) != -1) - bos.write( c ); - pictureIndex = wb.addPicture( bos.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG ); - } - finally - { - if (fis != null) - fis.close(); - if (bos != null) - bos.close(); - } - return pictureIndex; - } - - private static void drawOval( HSSFPatriarch patriarch ) - { - // Create an oval and style to taste. - HSSFClientAnchor a = new HSSFClientAnchor(); - a.setAnchor((short)2, 2, 20, 20, (short) 2, 2, 190, 80); - HSSFSimpleShape s = patriarch.createSimpleShape(a); - s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL); - s.setLineStyleColor(10,10,10); - s.setFillColor(90,10,200); - s.setLineWidth(HSSFShape.LINEWIDTH_ONE_PT * 3); - s.setLineStyle(HSSFShape.LINESTYLE_DOTSYS); - } - - private static void drawPolygon( HSSFPatriarch patriarch ) - { - // HSSFClientAnchor a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 2, 2, (short) 3, 3 ); - // HSSFPolygon p = patriarch.createPolygon(a); - // p.setPolygonDrawArea(100,100); - // p.setPoints( new int[]{30, 90, 50}, new int[]{88, 5, 44} ); - - - HSSFClientAnchor a = new HSSFClientAnchor(); - a.setAnchor( (short) 2, 2, 0, 0, (short) 3, 3, 1023, 255 ); - HSSFShapeGroup g = patriarch.createGroup( a ); - g.setCoordinates(0,0,200,200); - HSSFPolygon p1 = g.createPolygon( new HSSFChildAnchor( 0, 0, 200, 200 ) ); - p1.setPolygonDrawArea( 100, 100 ); - p1.setPoints( new int[]{0, 90, 50}, new int[]{5, 5, 44} ); - p1.setFillColor( 0, 255, 0 ); - HSSFPolygon p2 = g.createPolygon( new HSSFChildAnchor( 20, 20, 200, 200 ) ); - p2.setPolygonDrawArea( 200, 200 ); - p2.setPoints( new int[]{120, 20, 150}, new int[]{105, 30, 195} ); - p2.setFillColor( 255, 0, 0 ); - } - - private static void drawManyLines( HSSFPatriarch patriarch ) - { - // Draw bunch of lines - int x1 = 100; - int y1 = 100; - int x2 = 800; - int y2 = 200; - int color = 0; - for (int i = 0; i < 10; i++) - { - HSSFClientAnchor a2 = new HSSFClientAnchor(); - a2.setAnchor((short) 2, 2, x1, y1, (short) 2, 2, x2, y2); - HSSFSimpleShape shape2 = patriarch.createSimpleShape(a2); - shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - shape2.setLineStyleColor(color); - y1 -= 10; - y2 -= 10; - color += 30; - } - } - - private static void drawGrid( HSSFPatriarch patriarch ) - { - // This draws a grid of lines. Since the coordinates space fixed at - // 1024 by 256 we use a ratio to get a reasonably square grids. - - double xRatio = 3.22; - double yRatio = 0.6711; - - int x1 = 000; - int y1 = 000; - int x2 = 000; - int y2 = 200; - for (int i = 0; i < 20; i++) - { - HSSFClientAnchor a2 = new HSSFClientAnchor(); - a2.setAnchor((short) 2, 2, (int) ( x1 * xRatio ), (int) ( y1 * yRatio ), - (short) 2, 2, (int) ( x2 * xRatio ), (int) ( y2 * yRatio )); - HSSFSimpleShape shape2 = patriarch.createSimpleShape(a2); - shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - - x1 += 10; - x2 += 10; - } - - x1 = 000; - y1 = 000; - x2 = 200; - y2 = 000; - for (int i = 0; i < 20; i++) - { - HSSFClientAnchor a2 = new HSSFClientAnchor(); - a2.setAnchor((short) 2, 2, (int) ( x1 * xRatio ), (int) ( y1 * yRatio ), - (short) 2, 2, (int) ( x2 * xRatio ), (int) ( y2 * yRatio )); - HSSFSimpleShape shape2 = patriarch.createSimpleShape(a2); - shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - - y1 += 10; - y2 += 10; - } - } - - private static void drawLinesToCenter( HSSFPatriarch patriarch ) - { - // Draw some lines from and to the corners - { - HSSFClientAnchor a1 = new HSSFClientAnchor(); - a1.setAnchor( (short)2, 2, 0, 0, (short) 2, 2, 512, 128); - HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1); - shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - } - { - HSSFClientAnchor a1 = new HSSFClientAnchor(); - a1.setAnchor( (short)2, 2, 512, 128, (short) 2, 2, 1024, 0); - HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1); - shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - } - { - HSSFClientAnchor a1 = new HSSFClientAnchor(); - a1.setAnchor( (short)1, 1, 0, 0, (short) 1, 1, 512, 100); - HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1); - shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - } - { - HSSFClientAnchor a1 = new HSSFClientAnchor(); - a1.setAnchor( (short)1, 1, 512, 100, (short) 1, 1, 1024, 0); - HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1); - shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - } - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawingWithGraphics.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawingWithGraphics.java deleted file mode 100644 index 4de1207f4..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawingWithGraphics.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; - -import java.awt.*; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Demonstrates the use of the EscherGraphics2d library. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class OfficeDrawingWithGraphics { - public static void main( String[] args ) throws IOException { - // Create a workbook with one sheet and size the first three somewhat - // larger so we can fit the chemical structure diagram in. - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet( "my drawing" ); - sheet.setColumnWidth(1, 256 * 27); - HSSFRow row1 = sheet.createRow(0); - row1.setHeightInPoints(10 * 15); - HSSFRow row2 = sheet.createRow(1); - row2.setHeightInPoints(5 * 15); - HSSFRow row3 = sheet.createRow(2); - row3.setHeightInPoints(10 * 15); - - // Add some cells so we can test that the anchoring works when we - // sort them. - row1.createCell(0).setCellValue("C"); - row2.createCell(0).setCellValue("A"); - row3.createCell(0).setCellValue("B"); - - // Create the top level drawing patriarch. - HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); - - HSSFClientAnchor a; - HSSFShapeGroup group; - EscherGraphics g; - EscherGraphics2d g2d; - // Anchor entirely within one cell. - a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 ); - group = patriarch.createGroup( a ); - group.setCoordinates( 0, 0, 320, 276 ); - float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / Math.abs(group.getY2() - group.getY1()); - g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel ); - g2d = new EscherGraphics2d( g ); - drawStar( g2d ); - - a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 1, (short) 1, 1 ); - group = patriarch.createGroup( a ); - group.setCoordinates( 0, 0, 640, 276 ); - verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / Math.abs(group.getY2() - group.getY1()); -// verticalPixelsPerPoint = (float)Math.abs(group.getY2() - group.getY1()) / a.getAnchorHeightInPoints(sheet); - g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel ); - g2d = new EscherGraphics2d( g ); - drawStar( g2d ); - - FileOutputStream out = new FileOutputStream("workbook.xls"); - wb.write(out); - out.close(); - - } - - private static void drawStar( EscherGraphics2d g2d ) - { - g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); - for (double i = 0; i < Math.PI; i += 0.1) - { - g2d.setColor( new Color((int)(i * 5343062d) ) ); - int x1 = (int) ( Math.cos(i) * 160.0 ) + 160; - int y1 = (int) ( Math.sin(i) * 138.0 ) + 138; - int x2 = (int) ( -Math.cos(i) * 160.0 ) + 160; - int y2 = (int) ( -Math.sin(i) * 138.0 ) + 138; - g2d.setStroke(new BasicStroke(2)); - g2d.drawLine(x1,y1,x2,y2); - } - g2d.setFont(new Font("SansSerif",Font.BOLD | Font.ITALIC, 20)); - g2d.drawString("EscherGraphics2d",70,100); - g2d.setColor(Color.yellow); - g2d.fillOval( 160-20,138-20,40,40); - g2d.setColor(Color.black); - g2d.fillPolygon(new int[] {-10+160,0+160,10+160,0+160}, new int[] {0+138,10+138,0+138,-10+138}, 4); - g2d.drawPolygon(new int[] {-160+160,0+160,160+160,0+160}, new int[] {0+138,138+138,0+138,-138+138}, 4); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Outlines.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Outlines.java deleted file mode 100644 index ad93f5e71..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/Outlines.java +++ /dev/null @@ -1,187 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.Closeable; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Creates outlines. - */ -public class Outlines implements Closeable { - public static void main(String[] args) - throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { - POILogger LOGGER = POILogFactory.getLogger(Outlines.class); - for (int i=1; i<=13; i++) { - Outlines o = new Outlines(); - try { - String log = (String)Outlines.class.getDeclaredMethod("test"+i).invoke(o); - String filename = "outline"+i+".xls"; - o.writeOut(filename); - LOGGER.log(POILogger.INFO, filename+" written. "+log); - } finally { - o.close(); - } - } - } - - private final HSSFWorkbook wb = new HSSFWorkbook(); - private final HSSFSheet sheet1 = wb.createSheet("new sheet"); - - public void writeOut(String filename) throws IOException { - FileOutputStream fileOut = new FileOutputStream(filename); - try { - wb.write(fileOut); - } finally { - fileOut.close(); - } - } - - @Override - public void close() throws IOException { - wb.close(); - } - - public String test1() { - sheet1.groupColumn(4, 7); - - for (int row = 0; row < 200; row++) { - HSSFRow r = sheet1.createRow(row); - for (int column = 0; column < 200; column++) { - HSSFCell c = r.createCell(column); - c.setCellValue(column); - } - } - return "Two expanded groups."; - } - - public String test2() { - sheet1.groupColumn(2, 10); - sheet1.groupColumn(4, 7); - sheet1.setColumnGroupCollapsed(4, true); - return "Two groups. Inner group collapsed."; - } - - public String test3() { - sheet1.groupColumn(2, 10); - sheet1.groupColumn(4, 7); - sheet1.setColumnGroupCollapsed(4, true); - sheet1.setColumnGroupCollapsed(2, true); - return "Two groups. Both collapsed."; - } - - public String test4() { - sheet1.groupColumn(2, 10); - sheet1.groupColumn(4, 7); - sheet1.setColumnGroupCollapsed(4, true); - sheet1.setColumnGroupCollapsed(2, true); - - sheet1.setColumnGroupCollapsed(4, false); - return "Two groups. Collapsed then inner group expanded."; - } - - public String test5() { - sheet1.groupColumn(2, 10); - sheet1.groupColumn(4, 7); - sheet1.setColumnGroupCollapsed(4, true); - sheet1.setColumnGroupCollapsed(2, true); - - sheet1.setColumnGroupCollapsed(4, false); - sheet1.setColumnGroupCollapsed(3, false); - return "Two groups. Collapsed then reexpanded."; - } - - public String test6() { - sheet1.groupColumn(2, 10); - sheet1.groupColumn(4, 10); - sheet1.setColumnGroupCollapsed(4, true); - sheet1.setColumnGroupCollapsed(2, true); - - sheet1.setColumnGroupCollapsed(3, false); - return "Two groups with matching end points. Second group collapsed."; - } - - public String test7() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 10); - return "Row outlines."; - } - - public String test8() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 10); - sheet1.setRowGroupCollapsed(7, true); - return "Row outlines. Inner group collapsed."; - } - - public String test9() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 10); - sheet1.setRowGroupCollapsed(7, true); - sheet1.setRowGroupCollapsed(5, true); - return "Row outlines. Both collapsed."; - } - - public String test10() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 10); - sheet1.setRowGroupCollapsed(7, true); - sheet1.setRowGroupCollapsed(5, true); - sheet1.setRowGroupCollapsed(8, false); - return "Row outlines. Collapsed then inner group expanded."; - } - - public String test11() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 10); - sheet1.setRowGroupCollapsed(7, true); - sheet1.setRowGroupCollapsed(5, true); - sheet1.setRowGroupCollapsed(8, false); - sheet1.setRowGroupCollapsed(14, false); - return "Row outlines. Collapsed then expanded."; - } - - public String test12() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 14); - sheet1.setRowGroupCollapsed(7, true); - sheet1.setRowGroupCollapsed(5, true); - sheet1.setRowGroupCollapsed(6, false); - return "Row outlines. Two row groups with matching end points. Second group collapsed."; - } - - public String test13() { - sheet1.groupRow(5, 14); - sheet1.groupRow(7, 14); - sheet1.groupRow(16, 19); - - sheet1.groupColumn(4, 7); - sheet1.groupColumn(9, 12); - sheet1.groupColumn(10, 11); - return "Mixed bag."; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ReadWriteWorkbook.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ReadWriteWorkbook.java deleted file mode 100644 index 2b3553f76..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ReadWriteWorkbook.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.usermodel.CellType; - -/** - * This example demonstrates opening a workbook, modifying it and writing - * the results back out. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class ReadWriteWorkbook { - public static void main(String[] args) throws IOException { - FileInputStream fileIn = null; - FileOutputStream fileOut = null; - - try - { - fileIn = new FileInputStream("workbook.xls"); - POIFSFileSystem fs = new POIFSFileSystem(fileIn); - HSSFWorkbook wb = new HSSFWorkbook(fs); - HSSFSheet sheet = wb.getSheetAt(0); - HSSFRow row = sheet.getRow(2); - if (row == null) - row = sheet.createRow(2); - HSSFCell cell = row.getCell(3); - if (cell == null) - cell = row.createCell(3); - cell.setCellType(CellType.STRING); - cell.setCellValue("a test"); - - // Write the output to a file - fileOut = new FileOutputStream("workbookout.xls"); - wb.write(fileOut); - } finally { - if (fileOut != null) - fileOut.close(); - if (fileIn != null) - fileIn.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/RepeatingRowsAndColumns.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/RepeatingRowsAndColumns.java deleted file mode 100644 index 6ceee7c26..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/RepeatingRowsAndColumns.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.util.CellRangeAddress; - -public class RepeatingRowsAndColumns { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet1 = wb.createSheet("first sheet"); - HSSFSheet sheet2 = wb.createSheet("second sheet"); - HSSFSheet sheet3 = wb.createSheet("third sheet"); - - HSSFFont boldFont = wb.createFont(); - boldFont.setFontHeightInPoints((short)22); - boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - - HSSFCellStyle boldStyle = wb.createCellStyle(); - boldStyle.setFont(boldFont); - - HSSFRow row = sheet1.createRow(1); - HSSFCell cell = row.createCell(0); - cell.setCellValue("This quick brown fox"); - cell.setCellStyle(boldStyle); - - // Set the columns to repeat from column 0 to 2 on the first sheet - sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:C")); - // Set the rows to repeat from row 0 to 2 on the second sheet. - sheet2.setRepeatingRows(CellRangeAddress.valueOf("1:3")); - // Set the the repeating rows and columns on the third sheet. - CellRangeAddress cra = CellRangeAddress.valueOf("D1:E2"); - sheet3.setRepeatingColumns(cra); - sheet3.setRepeatingRows(cra); - - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/SplitAndFreezePanes.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/SplitAndFreezePanes.java deleted file mode 100644 index 6e93a317f..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/SplitAndFreezePanes.java +++ /dev/null @@ -1,55 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; - -import java.io.IOException; -import java.io.FileOutputStream; - -/** - * @author Glen Stampoultzis (glens at apache.org) - */ -public class SplitAndFreezePanes -{ - public static void main(String[] args) - throws IOException - { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet1 = wb.createSheet("new sheet"); - HSSFSheet sheet2 = wb.createSheet("second sheet"); - HSSFSheet sheet3 = wb.createSheet("third sheet"); - HSSFSheet sheet4 = wb.createSheet("fourth sheet"); - - // Freeze just one row - sheet1.createFreezePane( 0, 1, 0, 1 ); - // Freeze just one column - sheet2.createFreezePane( 1, 0, 1, 0 ); - // Freeze the columns and rows (forget about scrolling position of the lower right quadrant). - sheet3.createFreezePane( 2, 2 ); - // Create a split with the lower left side being the active quadrant - sheet4.createSplitPane( 2000, 2000, 0, 0, HSSFSheet.PANE_LOWER_LEFT ); - - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/WorkingWithFonts.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/WorkingWithFonts.java deleted file mode 100644 index 6cb15941f..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/WorkingWithFonts.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.*; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Demonstrates how to create and use fonts. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class WorkingWithFonts { - public static void main(String[] args) throws IOException { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - HSSFRow row = sheet.createRow(1); - - // Create a new font and alter it. - HSSFFont font = wb.createFont(); - font.setFontHeightInPoints((short)24); - font.setFontName("Courier New"); - font.setItalic(true); - font.setStrikeout(true); - - // Fonts are set into a style so create a new one to use. - HSSFCellStyle style = wb.createCellStyle(); - style.setFont(font); - - // Create a cell and put a value in it. - HSSFCell cell = row.createCell(1); - cell.setCellValue("This is a test of fonts"); - cell.setCellStyle(style); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ZoomSheet.java b/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ZoomSheet.java deleted file mode 100644 index f83b5900e..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ZoomSheet.java +++ /dev/null @@ -1,46 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel.examples; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; - -import java.io.IOException; -import java.io.FileOutputStream; - -/** - * Sets the zoom magnication for a sheet. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class ZoomSheet -{ - public static void main(String[] args) - throws IOException - { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet1 = wb.createSheet("new sheet"); - sheet1.setZoom(75); // 75 percent magnification - FileOutputStream fileOut = new FileOutputStream("workbook.xls"); - wb.write(fileOut); - fileOut.close(); - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java deleted file mode 100644 index 273ed07fd..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVBorder.java +++ /dev/null @@ -1,553 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.view; - -import java.awt.*; - -import javax.swing.border.AbstractBorder; - -import org.apache.poi.ss.usermodel.BorderStyle; - -/** - * This is an attempt to implement Excel style borders for the SheetViewer. - * Mostly just overrides stuff so the javadoc won't appear here but will - * appear in the generated stuff. - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height - */ -public class SVBorder extends AbstractBorder { - private Color northColor = null; - private Color eastColor = null; - private Color southColor = null; - private Color westColor = null; - private BorderStyle northBorderType = BorderStyle.NONE; - private BorderStyle eastBorderType = BorderStyle.NONE; - private BorderStyle southBorderType = BorderStyle.NONE; - private BorderStyle westBorderType = BorderStyle.NONE; - private boolean northBorder=false; - private boolean eastBorder=false; - private boolean southBorder=false; - private boolean westBorder=false; - private boolean selected = false; - - public void setBorder(Color northColor, Color eastColor, - Color southColor, Color westColor, - BorderStyle northBorderType, BorderStyle eastBorderType, - BorderStyle southBorderType, BorderStyle westBorderType, - boolean selected) { - this.eastColor = eastColor; - this.southColor = southColor; - this.westColor = westColor; - this.northBorderType = northBorderType; - this.eastBorderType = eastBorderType; - this.southBorderType = southBorderType; - this.westBorderType = westBorderType; - this.northBorder=northBorderType != BorderStyle.NONE; - this.eastBorder=eastBorderType != BorderStyle.NONE; - this.southBorder=southBorderType != BorderStyle.NONE; - this.westBorder=westBorderType != BorderStyle.NONE; - this.selected = selected; - } - - @Override -public void paintBorder(Component c, Graphics g, int x, int y, int width, - int height) { - Color oldColor = g.getColor(); - - - paintSelectedBorder(g, x, y, width, height); - paintNormalBorders(g, x, y, width, height); - paintDottedBorders(g, x, y, width, height); - paintDashedBorders(g, x, y, width, height); - paintDoubleBorders(g, x, y, width, height); - paintDashDotDotBorders(g, x, y, width, height); - - - g.setColor(oldColor); - } - - /** - * Called by paintBorder to paint the border of a selected cell. - * The paramaters are the Graphics object, location and dimensions of the - * cell. - */ - private void paintSelectedBorder(Graphics g, int x, int y, int width, - int height) { - if (selected) { - //Need to setup thickness of 2 - g.setColor(Color.black); - //paint the border - g.drawRect(x,y,width-1,height-1); - - //paint the filled rectangle at the bottom left hand position - g.fillRect(x+width-5, y+height-5, 5, 5); - } - } - - - /** - * Called by paintBorder to paint the various versions of normal line - * borders for a cell. - */ - private void paintNormalBorders(Graphics g, int x, int y, int width, - int height) { - - if (northBorder && - ((northBorderType == BorderStyle.THIN) || - (northBorderType == BorderStyle.MEDIUM) || - (northBorderType == BorderStyle.THICK) - ) - ) { - - int thickness = getThickness(northBorderType); - - g.setColor(northColor); - - for (int k=0; k < thickness; k++) { - g.drawLine(x,y+k,width,y+k); - } - } - - if (eastBorder && - ((eastBorderType == BorderStyle.THIN) || - (eastBorderType == BorderStyle.MEDIUM) || - (eastBorderType == BorderStyle.THICK) - ) - ) { - - int thickness = getThickness(eastBorderType); - - g.setColor(eastColor); - - for (int k=0; k < thickness; k++) { - g.drawLine(width-k,y,width-k,height); - } - } - - if (southBorder && - ((southBorderType == BorderStyle.THIN) || - (southBorderType == BorderStyle.MEDIUM) || - (southBorderType == BorderStyle.THICK) - ) - ) { - - int thickness = getThickness(southBorderType); - - g.setColor(southColor); - for (int k=0; k < thickness; k++) { - g.drawLine(x,height - k,width,height - k); - } - } - - if (westBorder && - ((westBorderType == BorderStyle.THIN) || - (westBorderType == BorderStyle.MEDIUM) || - (westBorderType == BorderStyle.THICK) - ) - ) { - - int thickness = getThickness(westBorderType); - - g.setColor(westColor); - - for (int k=0; k < thickness; k++) { - g.drawLine(x+k,y,x+k,height); - } - } - } - - /** - * Called by paintBorder to paint the dotted line - * borders for a cell. - */ - private void paintDottedBorders(Graphics g, int x, int y, int width, - int height) { - if (northBorder && - northBorderType == BorderStyle.DOTTED) { - int thickness = getThickness(northBorderType); - - g.setColor(northColor); - - for (int k=0; k < thickness; k++) { - for (int xc = x; xc < width; xc=xc+2) { - g.drawLine(xc,y+k,xc,y+k); - } - } - } - - if (eastBorder && - eastBorderType == BorderStyle.DOTTED - ) { - - int thickness = getThickness(eastBorderType); - thickness++; //need for dotted borders to show up east - - g.setColor(eastColor); - - for (int k=0; k < thickness; k++) { - for (int yc=y;yc < height; yc=yc+2) { - g.drawLine(width-k,yc,width-k,yc); - } - } - } - - if (southBorder && - southBorderType == BorderStyle.DOTTED - ) { - - int thickness = getThickness(southBorderType); - thickness++; - g.setColor(southColor); - for (int k=0; k < thickness; k++) { - for (int xc = x; xc < width; xc=xc+2) { - g.drawLine(xc,height-k,xc,height-k); - } - } - } - - if (westBorder && - westBorderType == BorderStyle.DOTTED - ) { - - int thickness = getThickness(westBorderType); -// thickness++; - - g.setColor(westColor); - - for (int k=0; k < thickness; k++) { - for (int yc=y;yc < height; yc=yc+2) { - g.drawLine(x+k,yc,x+k,yc); - } - } - } - } - - /** - * Called by paintBorder to paint the various versions of dotted line - * borders for a cell. - */ - private void paintDashedBorders(Graphics g, int x, int y, int width, - int height) { - if (northBorder && - ((northBorderType == BorderStyle.DASHED) || - (northBorderType == BorderStyle.HAIR)) - ) { - int thickness = getThickness(northBorderType); - - int dashlength = 1; - - if (northBorderType == BorderStyle.DASHED) - dashlength = 2; - - g.setColor(northColor); - - for (int k=0; k < thickness; k++) { - for (int xc = x; xc < width; xc=xc+5) { - g.drawLine(xc,y+k,xc+dashlength,y+k); - } - } - } - - if (eastBorder && - ((eastBorderType == BorderStyle.DASHED) || - (eastBorderType == BorderStyle.HAIR)) - ) { - - int thickness = getThickness(eastBorderType); - thickness++; //need for dotted borders to show up east - - - int dashlength = 1; - - if (eastBorderType == BorderStyle.DASHED) - dashlength = 2; - - g.setColor(eastColor); - - for (int k=0; k < thickness; k++) { - for (int yc=y;yc < height; yc=yc+5) { - g.drawLine(width-k,yc,width-k,yc+dashlength); - } - } - } - - if (southBorder && - ((southBorderType == BorderStyle.DASHED) || - (southBorderType == BorderStyle.HAIR)) - ) { - - int thickness = getThickness(southBorderType); - thickness++; - - int dashlength = 1; - - if (southBorderType == BorderStyle.DASHED) - dashlength = 2; - - g.setColor(southColor); - for (int k=0; k < thickness; k++) { - for (int xc = x; xc < width; xc=xc+5) { - g.drawLine(xc,height-k,xc+dashlength,height-k); - } - } - } - - if (westBorder && - ((westBorderType == BorderStyle.DASHED) || - (westBorderType == BorderStyle.HAIR)) - ) { - - int thickness = getThickness(westBorderType); -// thickness++; - - int dashlength = 1; - - if (westBorderType == BorderStyle.DASHED) - dashlength = 2; - - g.setColor(westColor); - - for (int k=0; k < thickness; k++) { - for (int yc=y;yc < height; yc=yc+5) { - g.drawLine(x+k,yc,x+k,yc+dashlength); - } - } - } - } - - /** - * Called by paintBorder to paint the double line - * borders for a cell. - */ - private void paintDoubleBorders(Graphics g, int x, int y, int width, - int height) { - if (northBorder && - northBorderType == BorderStyle.DOUBLE) { - - g.setColor(northColor); - - int leftx=x; - int rightx=width; - - // if there are borders on the west or east then - // the second line shouldn't cross them - if (westBorder) - leftx = x+3; - - if (eastBorder) - rightx = width-3; - - g.drawLine(x,y,width,y); - g.drawLine(leftx,y+2,rightx,y+2); - } - - if (eastBorder && - eastBorderType == BorderStyle.DOUBLE - ) { - - int thickness = getThickness(eastBorderType); - thickness++; //need for dotted borders to show up east - - g.setColor(eastColor); - - int topy=y; - int bottomy=height; - - if (northBorder) - topy=y+3; - - if (southBorder) - bottomy=height-3; - - g.drawLine(width-1,y,width-1,height); - g.drawLine(width-3,topy,width-3,bottomy); - } - - if (southBorder && - southBorderType == BorderStyle.DOUBLE - ) { - - g.setColor(southColor); - - int leftx=y; - int rightx=width; - - if (westBorder) - leftx=x+3; - - if (eastBorder) - rightx=width-3; - - - g.drawLine(x,height - 1,width,height - 1); - g.drawLine(leftx,height - 3,rightx,height - 3); - } - - if (westBorder && - westBorderType == BorderStyle.DOUBLE - ) { - - int thickness = getThickness(westBorderType); -// thickness++; - - g.setColor(westColor); - - int topy=y; - int bottomy=height-3; - - if (northBorder) - topy=y+2; - - if (southBorder) - bottomy=height-3; - - g.drawLine(x,y,x,height); - g.drawLine(x+2,topy,x+2,bottomy); - } - } - - /** - * Called by paintBorder to paint the various versions of dash dot dot line - * borders for a cell. - */ - private void paintDashDotDotBorders(Graphics g, int x, int y, int width, - int height) { - if (northBorder && - ((northBorderType == BorderStyle.DASH_DOT_DOT) || - (northBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT)) - ) { - int thickness = getThickness(northBorderType); - - g.setColor(northColor); - for (int l=x; l < width;) { - l=l+drawDashDotDot(g, l, y, thickness, true, true); - } - - } - - if (eastBorder && - ((eastBorderType == BorderStyle.DASH_DOT_DOT) || - (eastBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT)) - ) { - - int thickness = getThickness(eastBorderType); - - g.setColor(eastColor); - - for (int l=y;l < height;) { - //System.err.println("drawing east"); - l=l+drawDashDotDot(g,width-1,l,thickness,false,false); - } - } - - if (southBorder && - ((southBorderType == BorderStyle.DASH_DOT_DOT) || - (southBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT)) - ) { - - int thickness = getThickness(southBorderType); - - g.setColor(southColor); - - for (int l=x; l < width;) { - //System.err.println("drawing south"); - l=l+drawDashDotDot(g, l, height-1, thickness, true, false); - } - } - - if (westBorder && - ((westBorderType == BorderStyle.DASH_DOT_DOT) || - (westBorderType == BorderStyle.MEDIUM_DASH_DOT_DOT)) - ) { - - int thickness = getThickness(westBorderType); - - g.setColor(westColor); - - for (int l=y;l < height;) { - //System.err.println("drawing west"); - l=l+drawDashDotDot(g,x,l,thickness,false,true); - } - - } - } - - /** - * Draws one dash dot dot horizontally or vertically with thickness drawn - * incrementally to either the right or left. - * - * @param g graphics object for drawing with - * @param x the x origin of the line - * @param y the y origin of the line - * @param thickness the thickness of the line - * @param horizontal or vertical (true for horizontal) - * @param right/bottom or left/top thickness (true for right or top), - * if true then the x or y origin will be incremented to provide - * thickness, if false, they'll be decremented. For vertical - * borders, x is incremented or decremented, for horizontal its y. - * Just set to true for north and west, and false for east and - * south. - * @returns length - returns the length of the line. - */ - private int drawDashDotDot(Graphics g,int x, int y, int thickness, - boolean horizontal, - boolean rightBottom) { - - for (int t=0; t < thickness; t++) { - if (!rightBottom) { - t = 0 - t; //add negative thickness so we go the other way - //then we'll decrement instead of increment. - } - if (horizontal) { - g.drawLine(x,y+t,x+5,y+t); - g.drawLine(x+8,y+t,x+10,y+t); - g.drawLine(x+13,y+t,x+15,y+t); - } else { - g.drawLine(x+t,y,x+t,y+5); - g.drawLine(x+t,y+8,x+t,y+10); - g.drawLine(x+t,y+13,x+t,y+15); - } - } - return 18; - } - - /** - * @returns the line thickness for a border based on border type - */ - private int getThickness(BorderStyle thickness) { - switch (thickness) { - case DASH_DOT_DOT: - case DASHED: - case HAIR: - return 1; - case THIN: - return 2; - case MEDIUM: - case MEDIUM_DASH_DOT_DOT: - return 3; - case THICK: - return 4; - default: - return 1; - } - } - - -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java deleted file mode 100644 index 488419588..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVFractionalFormat.java +++ /dev/null @@ -1,224 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.view; - -import java.text.*; - -/** - * This class is used to format cells into their fractional format. - * - * I cant be 100% sure that the same fractional value will be displayed as in - * excel but then again it is a lossy formating mode anyway - * - * @author Jason Height - * @since 15 July 2002 - */ -public class SVFractionalFormat extends Format { - private short ONE_DIGIT = 1; - private short TWO_DIGIT = 2; - private short THREE_DIGIT = 3; - private short UNITS = 4; - private int units = 1; - private short mode = -1; - - /** Constructs a new FractionalFormatter - * - * The formatStr defines how the number will be formatted - * # ?/? Up to one digit - * # ??/?? Up to two digits - * # ???/??? Up to three digits - * # ?/2 In halves - * # ?/4 In quarters - * # ?/8 In eighths - * # ?/16 In sixteenths - * # ?/10 In tenths - * # ?/100 In hundredths - */ - public SVFractionalFormat(String formatStr) { - if ("# ?/?".equals(formatStr)) - mode = ONE_DIGIT; - else if ("# ??/??".equals(formatStr)) - mode = TWO_DIGIT; - else if ("# ???/???".equals(formatStr)) - mode = THREE_DIGIT; - else if ("# ?/2".equals(formatStr)) { - mode = UNITS; - units = 2; - } else if ("# ?/4".equals(formatStr)) { - mode = UNITS; - units = 4; - } else if ("# ?/8".equals(formatStr)) { - mode = UNITS; - units = 8; - } else if ("# ?/16".equals(formatStr)) { - mode = UNITS; - units = 16; - } else if ("# ?/10".equals(formatStr)) { - mode = UNITS; - units = 10; - } else if ("# ?/100".equals(formatStr)) { - mode = UNITS; - units = 100; - } - } - - /** - * Returns a fractional string representation of a double to a maximum denominator size - * - * This code has been translated to java from the following web page. - * http://www.codeproject.com/cpp/fraction.asp - * Originally coded in c++ By Dean Wyant dwyant@mindspring.com - * The code on the web page is freely available. - * - * @param f Description of the Parameter - * @param MaxDen Description of the Parameter - * @return Description of the Return Value - */ - private String format(final double f, final int MaxDen) { - long Whole = (long)f; - int sign = 1; - if (f < 0) { - sign = -1; - } - double Precision = 0.00001; - double AllowedError = Precision; - double d = Math.abs(f); - d -= Whole; - double Frac = d; - double Diff = Frac; - long Num = 1; - long Den = 0; - long A = 0; - long B = 0; - long i = 0; - if (Frac > Precision) { - while (true) { - d = 1.0 / d; - i = (long) (d + Precision); - d -= i; - if (A > 0) { - Num = i * Num + B; - } - Den = (long) (Num / Frac + 0.5); - Diff = Math.abs((double) Num / Den - Frac); - if (Den > MaxDen) { - if (A > 0) { - Num = A; - Den = (long) (Num / Frac + 0.5); - Diff = Math.abs((double) Num / Den - Frac); - } else { - Den = MaxDen; - Num = 1; - Diff = Math.abs((double) Num / Den - Frac); - if (Diff > Frac) { - Num = 0; - Den = 1; - // Keeps final check below from adding 1 and keeps Den from being 0 - Diff = Frac; - } - } - break; - } - if ((Diff <= AllowedError) || (d < Precision)) { - break; - } - Precision = AllowedError / Diff; - // This calcualtion of Precision does not always provide results within - // Allowed Error. It compensates for loss of significant digits that occurs. - // It helps to round the inprecise reciprocal values to i. - B = A; - A = Num; - } - } - if (Num == Den) { - Whole++; - Num = 0; - Den = 0; - } else if (Den == 0) { - Num = 0; - } - if (sign < 0) { - if (Whole == 0) { - Num = -Num; - } else { - Whole = -Whole; - } - } - return new StringBuffer().append(Whole).append(" ").append(Num).append("/").append(Den).toString(); - } - - /** This method formats the double in the units specified. - * The usints could be any number but in this current implementation it is - * halves (2), quaters (4), eigths (8) etc - */ - private String formatUnit(double f, int units) { - long Whole = (long)f; - f -= Whole; - long Num = Math.round(f * units); - - return new StringBuffer().append(Whole).append(" ").append(Num).append("/").append(units).toString(); - } - - public final String format(double val) { - if (mode == ONE_DIGIT) { - return format(val, 9); - } else if (mode == TWO_DIGIT) { - return format(val, 99); - } else if (mode == THREE_DIGIT) { - return format(val, 999); - } else if (mode == UNITS) { - return formatUnit(val , units); - } - throw new RuntimeException("Unexpected Case"); - } - - @Override -public StringBuffer format(Object obj, - StringBuffer toAppendTo, - FieldPosition pos) { - if (obj instanceof Number) { - toAppendTo.append(format(((Number)obj).doubleValue())); - return toAppendTo; - } - throw new IllegalArgumentException("Can only handle Numbers"); - } - - @Override -public Object parseObject(String source, - ParsePosition status) { - //JMH TBD - return null; - } - - @Override -public Object parseObject(String source) - throws ParseException { - //JMH TBD - return null; - } - - @Override -public Object clone() { - //JMH TBD - return null; - } - - -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java deleted file mode 100644 index 622f50643..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVRowHeader.java +++ /dev/null @@ -1,99 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - - -package org.apache.poi.hssf.view; - -import java.awt.*; -import javax.swing.*; -import javax.swing.table.*; - -import org.apache.poi.hssf.usermodel.*; - -/** - * This class presents the row header to the table. - * - * - * @author Jason Height - */ -public class SVRowHeader extends JList { - /** This model simply returns an integer number up to the number of rows - * that are present in the sheet. - * - */ - private class SVRowHeaderModel extends AbstractListModel { - private HSSFSheet sheet; - - public SVRowHeaderModel(HSSFSheet sheet) { - this.sheet = sheet; - } - - @Override - public int getSize() { - return sheet.getLastRowNum() + 1; - } - @Override - public Object getElementAt(int index) { - return Integer.toString(index+1); - } - } - - /** Renderes the row number*/ - private class RowHeaderRenderer extends JLabel implements ListCellRenderer { - private HSSFSheet sheet; - private int extraHeight; - - RowHeaderRenderer(HSSFSheet sheet, JTable table, int extraHeight) { - this.sheet = sheet; - this.extraHeight = extraHeight; - JTableHeader header = table.getTableHeader(); - setOpaque(true); - setBorder(UIManager.getBorder("TableHeader.cellBorder")); - setHorizontalAlignment(CENTER); - setForeground(header.getForeground()); - setBackground(header.getBackground()); - setFont(header.getFont()); - } - - @Override - public Component getListCellRendererComponent( JList list, - Object value, int index, boolean isSelected, boolean cellHasFocus) { - Dimension d = getPreferredSize(); - HSSFRow row = sheet.getRow(index); - int rowHeight; - if(row == null) { - rowHeight = (int)sheet.getDefaultRowHeightInPoints(); - } else { - rowHeight = (int)row.getHeightInPoints(); - } - d.height = rowHeight+extraHeight; - setPreferredSize(d); - setText((value == null) ? "" : value.toString()); - return this; - } - } - - public SVRowHeader(HSSFSheet sheet, JTable table, int extraHeight) { - ListModel lm = new SVRowHeaderModel(sheet); - this.setModel(lm); - - setFixedCellWidth(50); - setCellRenderer(new RowHeaderRenderer(sheet, table, extraHeight)); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java deleted file mode 100644 index c9e209087..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVSheetTable.java +++ /dev/null @@ -1,261 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.view; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.Toolkit; -import java.awt.event.HierarchyEvent; -import java.awt.event.HierarchyListener; - -import javax.swing.BorderFactory; -import javax.swing.JLabel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JViewport; -import javax.swing.ListSelectionModel; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.table.JTableHeader; -import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; -import javax.swing.text.JTextComponent; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.view.brush.PendingPaintings; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; - -/** - * This class is a table that represents the values in a single worksheet. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class SVSheetTable extends JTable { - private final HSSFSheet sheet; - private final PendingPaintings pendingPaintings; - private FormulaDisplayListener formulaListener; - private JScrollPane scroll; - - private static final Color HEADER_BACKGROUND = new Color(235, 235, 235); - - /** - * This field is the magic number to convert from a Character width to a java - * pixel width. - *

    - * When the "normal" font size in a workbook changes, this effects all of the - * heights and widths. Unfortunately there is no way to retrieve this - * information, hence the MAGIC number. - *

    - * This number may only work for the normal style font size of Arial size 10. - */ - private static final int magicCharFactor = 7; - - private class HeaderCell extends JLabel { - private final int row; - - public HeaderCell(Object value, int row) { - super(value.toString(), CENTER); - this.row = row; - setBackground(HEADER_BACKGROUND); - setOpaque(true); - setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); - setRowSelectionAllowed(false); - } - - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - if (row >= 0) { - d.height = getRowHeight(row); - } - return d; - } - - @Override - public Dimension getMaximumSize() { - Dimension d = super.getMaximumSize(); - if (row >= 0) { - d.height = getRowHeight(row); - } - return d; - } - - @Override - public Dimension getMinimumSize() { - Dimension d = super.getMinimumSize(); - if (row >= 0) { - d.height = getRowHeight(row); - } - return d; - } - } - - private class HeaderCellRenderer implements TableCellRenderer { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - - return new HeaderCell(value, row); - } - } - - private class FormulaDisplayListener implements ListSelectionListener { - private final JTextComponent formulaDisplay; - - public FormulaDisplayListener(JTextComponent formulaDisplay) { - this.formulaDisplay = formulaDisplay; - } - - @Override - public void valueChanged(ListSelectionEvent e) { - int row = getSelectedRow(); - int col = getSelectedColumn(); - if (row < 0 || col < 0) { - return; - } - - if (e.getValueIsAdjusting()) { - return; - } - - HSSFCell cell = (HSSFCell) getValueAt(row, col); - String formula = ""; - if (cell != null) { - if (cell.getCellTypeEnum() == CellType.FORMULA) { - formula = cell.getCellFormula(); - } else { - formula = cell.toString(); - } - if (formula == null) - formula = ""; - } - formulaDisplay.setText(formula); - } - } - - public SVSheetTable(HSSFSheet sheet) { - super(new SVTableModel(sheet)); - this.sheet = sheet; - - setIntercellSpacing(new Dimension(0, 0)); - setAutoResizeMode(AUTO_RESIZE_OFF); - JTableHeader header = getTableHeader(); - header.setDefaultRenderer(new HeaderCellRenderer()); - pendingPaintings = new PendingPaintings(this); - - //Set the columns the correct size - TableColumnModel columns = getColumnModel(); - for (int i = 0; i < columns.getColumnCount(); i++) { - TableColumn column = columns.getColumn(i); - int width = sheet.getColumnWidth(i); - //256 is because the width is in 256ths of a character - column.setPreferredWidth(width / 256 * magicCharFactor); - } - - Toolkit t = getToolkit(); - int res = t.getScreenResolution(); - TableModel model = getModel(); - for (int i = 0; i < model.getRowCount(); i++) { - Row row = sheet.getRow(i - sheet.getFirstRowNum()); - if (row != null) { - short h = row.getHeight(); - int height = (int)Math.round(Math.max(1., h / (res / 70. * 20.) + 3.)); - System.out.printf("%d: %d (%d @ %d)%n", i, height, h, res); - setRowHeight(i, height); - } - } - - addHierarchyListener(new HierarchyListener() { - @Override - public void hierarchyChanged(HierarchyEvent e) { - if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) { - Container changedParent = e.getChangedParent(); - if (changedParent instanceof JViewport) { - Container grandparent = changedParent.getParent(); - if (grandparent instanceof JScrollPane) { - JScrollPane jScrollPane = (JScrollPane) grandparent; - setupScroll(jScrollPane); - } - } - } - } - }); - } - - public void setupScroll(JScrollPane scroll) { - if (scroll == this.scroll) - return; - - this.scroll = scroll; - if (scroll == null) - return; - - SVRowHeader rowHeader = new SVRowHeader(sheet, this, 0); - scroll.setRowHeaderView(rowHeader); - scroll.setCorner(JScrollPane.UPPER_LEADING_CORNER, headerCell("?")); - } - - public void setFormulaDisplay(JTextComponent formulaDisplay) { - ListSelectionModel rowSelMod = getSelectionModel(); - ListSelectionModel colSelMod = getColumnModel().getSelectionModel(); - - if (formulaDisplay == null) { - rowSelMod.removeListSelectionListener(formulaListener); - colSelMod.removeListSelectionListener(formulaListener); - formulaListener = null; - } - - if (formulaDisplay != null) { - formulaListener = new FormulaDisplayListener(formulaDisplay); - rowSelMod.addListSelectionListener(formulaListener); - colSelMod.addListSelectionListener(formulaListener); - } - } - - public JTextComponent getFormulaDisplay() { - if (formulaListener == null) - return null; - else - return formulaListener.formulaDisplay; - } - - public Component headerCell(String text) { - return new HeaderCell(text, -1); - } - - @Override - public void paintComponent(Graphics g1) { - Graphics2D g = (Graphics2D) g1; - - pendingPaintings.clear(); - - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - super.paintComponent(g); - - pendingPaintings.paint(g); - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java deleted file mode 100644 index 3c58d5346..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellEditor.java +++ /dev/null @@ -1,219 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.view; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.util.EventObject; -import java.util.Map; - -import javax.swing.AbstractCellEditor; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.SwingConstants; -import javax.swing.table.TableCellEditor; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.FillPatternType; - -/** - * Sheet Viewer Table Cell Editor -- not commented via javadoc as it - * nearly completely consists of overridden methods. - * - * @author Jason Height - */ -public class SVTableCellEditor extends AbstractCellEditor implements TableCellEditor, ActionListener { - private static final Color black = getAWTColor(new HSSFColor.BLACK()); - private static final Color white = getAWTColor(new HSSFColor.WHITE()); - private Map colors = HSSFColor.getIndexHash(); - - - private HSSFWorkbook wb; - private JTextField editor; - - public SVTableCellEditor(HSSFWorkbook wb) { - this.wb = wb; - this.editor = new JTextField(); - } - - - /** - * Gets the cellEditable attribute of the SVTableCellEditor object - * - * @return The cellEditable value - */ - @Override -public boolean isCellEditable(java.util.EventObject e) { - if (e instanceof MouseEvent) { - return ((MouseEvent) e).getClickCount() >= 2; - } - return false; - } - - - @Override -public boolean shouldSelectCell(EventObject anEvent) { - return true; - } - - - public boolean startCellEditing(EventObject anEvent) { - System.out.println("Start Cell Editing"); - return true; - } - - - @Override -public boolean stopCellEditing() { - System.out.println("Stop Cell Editing"); - fireEditingStopped(); - return true; - } - - - @Override -public void cancelCellEditing() { - System.out.println("Cancel Cell Editing"); - fireEditingCanceled(); - } - - - @Override -public void actionPerformed(ActionEvent e) { - System.out.println("Action performed"); - stopCellEditing(); - } - - - /** - * Gets the cellEditorValue attribute of the SVTableCellEditor object - * - * @return The cellEditorValue value - */ - @Override -public Object getCellEditorValue() { - System.out.println("GetCellEditorValue"); - //JMH Look at when this method is called. Should it return a HSSFCell? - return editor.getText(); - } - - - /** - * Gets the tableCellEditorComponent attribute of the SVTableCellEditor object - * - * @return The tableCellEditorComponent value - */ - @Override -public Component getTableCellEditorComponent(JTable table, Object value, - boolean isSelected, - int row, - int column) { - System.out.println("GetTableCellEditorComponent"); - HSSFCell cell = (HSSFCell) value; - if (cell != null) { - HSSFCellStyle style = cell.getCellStyle(); - HSSFFont f = wb.getFontAt(style.getFontIndex()); - boolean isbold = f.getBold(); - boolean isitalics = f.getItalic(); - - int fontstyle = Font.PLAIN; - - if (isbold) fontstyle = Font.BOLD; - if (isitalics) fontstyle = fontstyle | Font.ITALIC; - - int fontheight = f.getFontHeightInPoints(); - if (fontheight == 9) fontheight = 10; //fix for stupid ol Windows - - Font font = new Font(f.getFontName(),fontstyle,fontheight); - editor.setFont(font); - - if (style.getFillPatternEnum() == FillPatternType.SOLID_FOREGROUND) { - editor.setBackground(getAWTColor(style.getFillForegroundColor(), white)); - } else editor.setBackground(white); - - editor.setForeground(getAWTColor(f.getColor(), black)); - - - //Set the value that is rendered for the cell - switch (cell.getCellTypeEnum()) { - case BLANK: - editor.setText(""); - break; - case BOOLEAN: - if (cell.getBooleanCellValue()) { - editor.setText("true"); - } else { - editor.setText("false"); - } - break; - case NUMERIC: - editor.setText(Double.toString(cell.getNumericCellValue())); - break; - case STRING: - editor.setText(cell.getRichStringCellValue().getString()); - break; - case FORMULA: - default: - editor.setText("?"); - } - switch (style.getAlignmentEnum()) { - case LEFT: - case JUSTIFY: - case FILL: - editor.setHorizontalAlignment(SwingConstants.LEFT); - break; - case CENTER: - case CENTER_SELECTION: - editor.setHorizontalAlignment(SwingConstants.CENTER); - break; - case GENERAL: - case RIGHT: - editor.setHorizontalAlignment(SwingConstants.RIGHT); - break; - default: - editor.setHorizontalAlignment(SwingConstants.LEFT); - break; - } - - } - return editor; - } - - /** This method retrieves the AWT Color representation from the colour hash table - * - */ - private final Color getAWTColor(int index, Color deflt) { - HSSFColor clr = colors.get(index); - if (clr == null) return deflt; - return getAWTColor(clr); - } - - private static final Color getAWTColor(HSSFColor clr) { - short[] rgb = clr.getTriplet(); - return new Color(rgb[0],rgb[1],rgb[2]); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java deleted file mode 100644 index 1448c5363..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java +++ /dev/null @@ -1,283 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.view; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Rectangle; -import java.io.Serializable; -import java.text.DecimalFormat; -import java.text.Format; -import java.text.SimpleDateFormat; - -import javax.swing.JLabel; -import javax.swing.JTable; -import javax.swing.SwingConstants; -import javax.swing.UIManager; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; -import javax.swing.table.TableCellRenderer; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.FillPatternType; - - -/** - * Sheet Viewer Table Cell Render -- not commented via javadoc as it - * nearly completely consists of overridden methods. - * - * @author Andrew C. Oliver - */ -public class SVTableCellRenderer extends JLabel - implements TableCellRenderer, Serializable -{ - protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - protected SVBorder cellBorder = new SVBorder(); - - - private HSSFWorkbook wb = null; - - /** This class holds the references to the predefined cell formats. - */ - private class CellFormatter { - private Format[] textFormatter; - - private DecimalFormat generalNumberFormat = new DecimalFormat("0"); - - public CellFormatter() { - textFormatter = new Format[0x31]; - - textFormatter[0x01] = new DecimalFormat("0"); - textFormatter[0x02] = new DecimalFormat("0.00"); - textFormatter[0x03] = new DecimalFormat("#,##0"); - textFormatter[0x04] = new DecimalFormat("#,##0.00"); - textFormatter[0x05] = new DecimalFormat("$#,##0;$#,##0"); - textFormatter[0x06] = new DecimalFormat("$#,##0;$#,##0"); - textFormatter[0x07] = new DecimalFormat("$#,##0.00;$#,##0.00"); - textFormatter[0x08] = new DecimalFormat("$#,##0.00;$#,##0.00"); - textFormatter[0x09] = new DecimalFormat("0%"); - textFormatter[0x0A] = new DecimalFormat("0.00%"); - textFormatter[0x0B] = new DecimalFormat("0.00E0"); - textFormatter[0x0C] = new SVFractionalFormat("# ?/?"); - textFormatter[0x0D] = new SVFractionalFormat("# ??/??"); - textFormatter[0x0E] = new SimpleDateFormat("M/d/yy"); - textFormatter[0x0F] = new SimpleDateFormat("d-MMM-yy"); - textFormatter[0x10] = new SimpleDateFormat("d-MMM"); - textFormatter[0x11] = new SimpleDateFormat("MMM-yy"); - textFormatter[0x12] = new SimpleDateFormat("h:mm a"); - textFormatter[0x13] = new SimpleDateFormat("h:mm:ss a"); - textFormatter[0x14] = new SimpleDateFormat("h:mm"); - textFormatter[0x15] = new SimpleDateFormat("h:mm:ss"); - textFormatter[0x16] = new SimpleDateFormat("M/d/yy h:mm"); - // 0x17 - 0x24 reserved for international and undocumented 0x25, "(#,##0_);(#,##0)" - //start at 0x26 - //jmh need to do colour - //"(#,##0_);[Red](#,##0)" - textFormatter[0x26] = new DecimalFormat("#,##0;#,##0"); - //jmh need to do colour - //(#,##0.00_);(#,##0.00) - textFormatter[0x27] = new DecimalFormat("#,##0.00;#,##0.00"); - textFormatter[0x28] = new DecimalFormat("#,##0.00;#,##0.00"); -//?? textFormatter[0x29] = new DecimalFormat("_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)"); -//?? textFormatter[0x2A] = new DecimalFormat("_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)"); -//?? textFormatter[0x2B] = new DecimalFormat("_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)"); -//?? textFormatter[0x2C] = new DecimalFormat("_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)"); - textFormatter[0x2D] = new SimpleDateFormat("mm:ss"); -//?? textFormatter[0x2E] = new SimpleDateFormat("[h]:mm:ss"); - textFormatter[0x2F] = new SimpleDateFormat("mm:ss.0"); - textFormatter[0x30] = new DecimalFormat("##0.0E0"); - } - - public String format(short index, double value) { - if ( index <= 0 ) - return generalNumberFormat.format(value); - if (textFormatter[index] == null) - throw new RuntimeException("Sorry. I cant handle the format code :"+Integer.toHexString(index)); - if (textFormatter[index] instanceof DecimalFormat) { - return ((DecimalFormat)textFormatter[index]).format(value); - } - if (textFormatter[index] instanceof SVFractionalFormat) { - return ((SVFractionalFormat)textFormatter[index]).format(value); - } - throw new RuntimeException("Sorry. I cant handle a non decimal formatter for a decimal value :"+Integer.toHexString(index)); - } - - public boolean useRedColor(short index, double value) { - return (((index == 0x06)||(index == 0x08)||(index == 0x26) || (index == 0x27)) && (value < 0)); - } - } - - private final CellFormatter cellFormatter = new CellFormatter(); - - public SVTableCellRenderer(HSSFWorkbook wb) { - super(); - setOpaque(true); - setBorder(noFocusBorder); - this.wb = wb; - } - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - boolean isBorderSet = false; - - //If the JTables default cell renderer has been setup correctly the - //value will be the HSSFCell that we are trying to render - HSSFCell c = (HSSFCell)value; - - if (c != null) { - HSSFCellStyle s = c.getCellStyle(); - HSSFFont f = wb.getFontAt(s.getFontIndex()); - setFont(SVTableUtils.makeFont(f)); - - if (s.getFillPatternEnum() == FillPatternType.SOLID_FOREGROUND) { - setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white)); - } else setBackground(SVTableUtils.white); - - setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black)); - - cellBorder.setBorder(SVTableUtils.getAWTColor(s.getTopBorderColor(), SVTableUtils.black), - SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black), - SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black), - SVTableUtils.getAWTColor(s.getLeftBorderColor(), SVTableUtils.black), - s.getBorderTopEnum(), s.getBorderRightEnum(), - s.getBorderBottomEnum(), s.getBorderLeftEnum(), - hasFocus); - setBorder(cellBorder); - isBorderSet=true; - - //Set the value that is rendered for the cell - switch (c.getCellTypeEnum()) { - case BLANK: - setValue(""); - break; - case BOOLEAN: - if (c.getBooleanCellValue()) { - setValue("true"); - } else { - setValue("false"); - } - break; - case NUMERIC: - short format = s.getDataFormat(); - double numericValue = c.getNumericCellValue(); - if (cellFormatter.useRedColor(format, numericValue)) - setForeground(Color.red); - else setForeground(null); - setValue(cellFormatter.format(format, c.getNumericCellValue())); - break; - case STRING: - setValue(c.getRichStringCellValue().getString()); - break; - case FORMULA: - default: - setValue("?"); - } - //Set the text alignment of the cell - switch (s.getAlignmentEnum()) { - case LEFT: - case JUSTIFY: - case FILL: - setHorizontalAlignment(SwingConstants.LEFT); - break; - case CENTER: - case CENTER_SELECTION: - setHorizontalAlignment(SwingConstants.CENTER); - break; - case GENERAL: - case RIGHT: - setHorizontalAlignment(SwingConstants.RIGHT); - break; - default: - setHorizontalAlignment(SwingConstants.LEFT); - break; - } - } else { - setValue(""); - setBackground(SVTableUtils.white); - } - - - if (hasFocus) { - if (!isBorderSet) { - //This is the border to paint when there is no border - //and the cell has focus - cellBorder.setBorder(SVTableUtils.black, - SVTableUtils.black, - SVTableUtils.black, - SVTableUtils.black, - BorderStyle.NONE, - BorderStyle.NONE, - BorderStyle.NONE, - BorderStyle.NONE, - isSelected); - setBorder(cellBorder); - } - if (table.isCellEditable(row, column)) { - setForeground( UIManager.getColor("Table.focusCellForeground") ); - setBackground( UIManager.getColor("Table.focusCellBackground") ); - } - } else if (!isBorderSet) { - setBorder(noFocusBorder); - } - - // ---- begin optimization to avoid painting background ---- - Color back = getBackground(); - boolean colorMatch = (back != null) && ( back.equals(table.getBackground()) ) && table.isOpaque(); - setOpaque(!colorMatch); - // ---- end optimization to aviod painting background ---- - return this; - } - - @Override - public void validate() {} - - @Override - public void revalidate() {} - - @Override - public void repaint(long tm, int x, int y, int width, int height) {} - - @Override - public void repaint(Rectangle r) { } - - @Override - protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - // Strings get interned... - if (propertyName=="text") { - super.firePropertyChange(propertyName, oldValue, newValue); - } - } - - @Override - public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { } - - /** - * Sets the string to either the value or "" if the value is null. - * - */ - protected void setValue(Object value) { - setText((value == null) ? "" : value.toString()); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java deleted file mode 100644 index 25ac83fc5..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableModel.java +++ /dev/null @@ -1,94 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - - -package org.apache.poi.hssf.view; - -import java.util.Iterator; -import javax.swing.table.*; - -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.hssf.usermodel.HSSFCell; - -/** - * Sheet Viewer Table Model - The model for the Sheet Viewer just overrides things. - * @author Andrew C. Oliver - */ - -public class SVTableModel extends AbstractTableModel { - private HSSFSheet st = null; - int maxcol = 0; - - public SVTableModel(HSSFSheet st, int maxcol) { - this.st = st; - this.maxcol=maxcol; - } - - public SVTableModel(HSSFSheet st) { - this.st = st; - Iterator i = st.rowIterator(); - - while (i.hasNext()) { - HSSFRow row = (HSSFRow)i.next(); - if (maxcol < (row.getLastCellNum()+1)) { - this.maxcol = row.getLastCellNum(); - } - } - } - - - @Override -public int getColumnCount() { - return this.maxcol+1; - } - @Override -public Object getValueAt(int row, int col) { - HSSFRow r = st.getRow(row); - HSSFCell c = null; - if (r != null) { - c = r.getCell(col); - } - return c; - } - @Override -public int getRowCount() { - return st.getLastRowNum() + 1; - } - - @Override -public Class getColumnClass(int c) { - return HSSFCell.class; - } - - @Override -public boolean isCellEditable(int rowIndex, int columnIndex) { - return true; - } - - @Override -public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - if (aValue != null) - System.out.println("SVTableModel.setValueAt. value type = "+aValue.getClass().getName()); - else System.out.println("SVTableModel.setValueAt. value type = null"); - } - - -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java deleted file mode 100644 index 395f1cdb8..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SVTableUtils.java +++ /dev/null @@ -1,93 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.view; - -import java.util.*; -import java.awt.*; -import javax.swing.border.*; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.hssf.util.*; - -/** - * SVTableCell Editor and Renderer helper functions. - * - * @author Jason Height - */ -public class SVTableUtils { - private final static Map colors = HSSFColor.getIndexHash(); - /** Description of the Field */ - public final static Color black = getAWTColor(new HSSFColor.BLACK()); - /** Description of the Field */ - public final static Color white = getAWTColor(new HSSFColor.WHITE()); - /** Description of the Field */ - public static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - - - /** - * Creates a new font for a specific cell style - */ - public static Font makeFont(HSSFFont font) { - boolean isbold = font.getBoldweight() > HSSFFont.BOLDWEIGHT_NORMAL; - boolean isitalics = font.getItalic(); - int fontstyle = Font.PLAIN; - if (isbold) { - fontstyle = Font.BOLD; - } - if (isitalics) { - fontstyle = fontstyle | Font.ITALIC; - } - - int fontheight = font.getFontHeightInPoints(); - if (fontheight == 9) { - //fix for stupid ol Windows - fontheight = 10; - } - - return new Font(font.getFontName(), fontstyle, fontheight); - } - - - /** - * This method retrieves the AWT Color representation from the colour hash table - * - * @param index Description of the Parameter - * @param deflt Description of the Parameter - * @return The aWTColor value - */ - public final static Color getAWTColor(int index, Color deflt) { - HSSFColor clr = colors.get(index); - if (clr == null) { - return deflt; - } - return getAWTColor(clr); - } - - - /** - * Gets the aWTColor attribute of the SVTableUtils class - * - * @param clr Description of the Parameter - * @return The aWTColor value - */ - public final static Color getAWTColor(HSSFColor clr) { - short[] rgb = clr.getTriplet(); - return new Color(rgb[0], rgb[1], rgb[2]); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java deleted file mode 100644 index a32399275..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SViewer.java +++ /dev/null @@ -1,180 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - - -package org.apache.poi.hssf.view; - -import java.awt.*; -import java.awt.event.*; -import java.net.*; -import java.io.*; -import javax.swing.*; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -/** - * Sheet Viewer - Views XLS files via HSSF. Can be used as an applet with - * filename="" or as a applications (pass the filename as the first parameter). - * Or you can pass it a URL in a "url" parameter when run as an applet or just - * that first parameter must start with http:// and it will guess its a url. I - * only tested it as an applet though, so it probably won't work...you fix it. - * - * @author Andrew C. Oliver - * @author Jason Height - */ -public class SViewer extends JApplet { - private SViewerPanel panel; - boolean isStandalone = false; - String filename = null; - - /**Get a parameter value*/ - public String getParameter(String key, String def) { - return isStandalone ? System.getProperty(key, def) : - (getParameter(key) != null ? getParameter(key) : def); - } - - /**Construct the applet*/ - public SViewer() { - } - - /**Initialize the applet*/ - @Override -public void init() { - try { - jbInit(); - } - catch(Exception e) { - e.printStackTrace(); - System.exit(1); - } - } - - /**Component initialization*/ - private void jbInit() throws Exception { - InputStream i = null; - boolean isurl = false; - if (filename == null) filename = getParameter("filename"); - - if (filename == null || filename.substring(0,7).equals("http://")) { - isurl = true; - if (filename == null) filename = getParameter("url"); - i = getXLSFromURL(filename); - } - - HSSFWorkbook wb = null; - if (isurl) { - wb = constructWorkbook(i); - } else { - wb = constructWorkbook(filename); - } - panel = new SViewerPanel(wb, false); - getContentPane().setLayout(new BorderLayout()); - getContentPane().add(panel, BorderLayout.CENTER); - } - - private HSSFWorkbook constructWorkbook(String filename) throws FileNotFoundException, IOException { - HSSFWorkbook wb = null; - FileInputStream in = new FileInputStream(filename); - wb = new HSSFWorkbook(in); - in.close(); - return wb; - } - - private HSSFWorkbook constructWorkbook(InputStream in) throws IOException { - HSSFWorkbook wb = null; - - wb = new HSSFWorkbook(in); - in.close(); - return wb; - } - - /**Start the applet*/ - @Override -public void start() { - } - /**Stop the applet*/ - @Override -public void stop() { - } - /**Destroy the applet*/ - @Override -public void destroy() { - } - /**Get Applet information*/ - @Override -public String getAppletInfo() { - return "Applet Information"; - } - /**Get parameter info*/ - @Override -public String[][] getParameterInfo() { - return null; - } - - /** - * opens a url and returns an inputstream - * - */ - private InputStream getXLSFromURL(String urlstring) throws MalformedURLException, IOException { - URL url = new URL(urlstring); - URLConnection uc = url.openConnection(); - String field = uc.getHeaderField(0); - for (int i=0;field != null; i++) { - System.out.println(field); - field = uc.getHeaderField(i); - } - BufferedInputStream is = new BufferedInputStream(uc.getInputStream()); - return is; - } - - - /**Main method*/ - public static void main(String[] args) { - if(args.length < 1) { - throw new IllegalArgumentException("A filename to view must be supplied as the first argument, but none was given"); - } - - SViewer applet = new SViewer(); - applet.isStandalone = true; - applet.filename = args[0]; - Frame frame; - frame = new Frame() { - @Override - protected void processWindowEvent(WindowEvent e) { - super.processWindowEvent(e); - if (e.getID() == WindowEvent.WINDOW_CLOSING) { - System.exit(0); - } - } - @Override - public synchronized void setTitle(String title) { - super.setTitle(title); - enableEvents(AWTEvent.WINDOW_EVENT_MASK); - } - }; - frame.setTitle("Applet Frame"); - frame.add(applet, BorderLayout.CENTER); - applet.init(); - applet.start(); - frame.setSize(400,320); - Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); - frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2); - frame.setVisible(true); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java b/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java deleted file mode 100644 index bf1ba4ab7..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/SViewerPanel.java +++ /dev/null @@ -1,303 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.view; - -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import javax.swing.*; -import javax.swing.table.*; - -import org.apache.poi.hssf.usermodel.*; - -/** - * This class presents the sheets to the user. - * - * - * @author Andrew C. Oliver - * @author Jason Height - */ -public class SViewerPanel extends JPanel { - /** This field is the magic number to convert from a Character width to a - * java pixel width. - * - * When the "normal" font size in a workbook changes, this effects all - * of the heights and widths. Unfortunately there is no way to retrieve this - * information, hence the MAGIC number. - * - * This number may only work for the normal style font size of Arial size 10. - * - */ - private static final int magicCharFactor = 7; - /** Reference to the wookbook that is being displayed*/ - /* package */ HSSFWorkbook wb; - /** Reference to the tabs component*/ - /* package */ JTabbedPane sheetPane; - /** Reference to the cell renderer that is used to render all cells*/ - private SVTableCellRenderer cellRenderer; - /** Reference to the cell editor that is used to edit all cells. - * Only constructed if editing is allowed - */ - private SVTableCellEditor cellEditor; - /** Flag indicating if editing is allowed. Otherwise the viewer is in - * view only mode. - */ - private boolean allowEdits; - - /**Construct the representation of the workbook*/ - public SViewerPanel(HSSFWorkbook wb, boolean allowEdits) { - this.wb = wb; - this.allowEdits = allowEdits; - - initialiseGui(); - } - - private void initialiseGui() { - cellRenderer = new SVTableCellRenderer(this.wb); - if (allowEdits) - cellEditor = new SVTableCellEditor(this.wb); - - //Initialise the Panel - sheetPane = new JTabbedPane(JTabbedPane.BOTTOM); - - if (allowEdits) - sheetPane.addMouseListener(createTabListener()); - int sheetCount = wb.getNumberOfSheets(); - for (int i=0; i - * It is up to the parent component to invoke the {@link #paint(Graphics2D)} - * method of this objet at that appropriate time. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class PendingPaintings { - /** - * The name of the client property that holds this object in the parent - * component. - */ - public static final String PENDING_PAINTINGS = - PendingPaintings.class.getSimpleName(); - - private final List paintings; - - /** A single painting description. */ - public static class Painting { - final Stroke stroke; - final Color color; - final Shape shape; - final AffineTransform transform; - - /** - * Creates a new painting description. - * - * @param stroke The stroke to paint. - * @param color The color of the stroke. - * @param shape The shape of the stroke. - * @param transform The transformation matrix to use. - */ - public Painting(Stroke stroke, Color color, Shape shape, - AffineTransform transform) { - - this.color = color; - this.shape = shape; - this.stroke = stroke; - this.transform = transform; - } - - /** - * Draw the painting. - * - * @param g The graphics object to use to draw with. - */ - public void draw(Graphics2D g) { - g.setTransform(transform); - g.setStroke(stroke); - g.setColor(color); - g.draw(shape); - } - } - - /** - * Creates a new object on the given parent. The created object will be - * stored as a client property. - * - * @param parent - */ - public PendingPaintings(JComponent parent) { - paintings = new ArrayList(); - parent.putClientProperty(PENDING_PAINTINGS, this); - } - - /** Drops all pending paintings. */ - public void clear() { - paintings.clear(); - } - - /** - * Paints all pending paintings. Once they have been painted they are - * removed from the list of pending paintings (they aren't pending anymore, - * after all). - * - * @param g The graphics object to draw with. - */ - public void paint(Graphics2D g) { - g.setBackground(Color.CYAN); - AffineTransform origTransform = g.getTransform(); - for (Painting c : paintings) { - c.draw(g); - } - g.setTransform(origTransform); - - clear(); - } - - /** - * Adds a new pending painting to the list on the given component. This - * will find the first ancestor that has a {@link PendingPaintings} client - * property, starting with the component itself. - * - * @param c The component for which the painting is being added. - * @param g The graphics object to draw with. - * @param stroke The stroke to draw. - * @param color The color to draw with. - * @param shape The shape to stroke. - */ - public static void add(JComponent c, Graphics2D g, Stroke stroke, - Color color, Shape shape) { - - add(c, new Painting(stroke, color, shape, g.getTransform())); - } - - /** - * Adds a new pending painting to the list on the given component. This - * will find the first ancestor that has a {@link PendingPaintings} client - * property, starting with the component itself. - * - * @param c The component for which the painting is being added. - * @param newPainting The new painting. - */ - public static void add(JComponent c, Painting newPainting) { - PendingPaintings pending = pendingPaintingsFor(c); - if (pending != null) { - pending.paintings.add(newPainting); - } - } - - /** - * Returns the pending painting object for the given component, if any. This - * is retrieved from the first object found that has a {@link - * #PENDING_PAINTINGS} client property, starting with this component and - * looking up its ancestors (parent, parent's parent, etc.) - *

    - * This allows any descendant of a component that has a {@link - * PendingPaintings} property to add its own pending paintings. - * - * @param c The component for which the painting is being added. - * - * @return The pending painting object for that component, or null - * if there is none. - */ - public static PendingPaintings pendingPaintingsFor(JComponent c) { - for (Component parent = c; - parent != null; - parent = parent.getParent()) { - if (parent instanceof JComponent) { - JComponent jc = (JComponent) parent; - Object pd = jc.getClientProperty(PENDING_PAINTINGS); - if (pd != null) - return (PendingPaintings) pd; - } - } - return null; - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/hssf/view/brush/package.html b/trunk/src/examples/src/org/apache/poi/hssf/view/brush/package.html deleted file mode 100644 index d9819fb66..000000000 --- a/trunk/src/examples/src/org/apache/poi/hssf/view/brush/package.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - -This package contains some brushes that are used when drawing borders for Excel -cells. - - diff --git a/trunk/src/examples/src/org/apache/poi/hwpf/Word2Forrest.java b/trunk/src/examples/src/org/apache/poi/hwpf/Word2Forrest.java deleted file mode 100644 index 3516b88e8..000000000 --- a/trunk/src/examples/src/org/apache/poi/hwpf/Word2Forrest.java +++ /dev/null @@ -1,229 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hwpf; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.Charset; - -import org.apache.poi.hwpf.model.StyleDescription; -import org.apache.poi.hwpf.model.StyleSheet; -import org.apache.poi.hwpf.usermodel.CharacterRun; -import org.apache.poi.hwpf.usermodel.Paragraph; -import org.apache.poi.hwpf.usermodel.Range; - -public final class Word2Forrest -{ - Writer _out; - HWPFDocument _doc; - - @SuppressWarnings("unused") - public Word2Forrest(HWPFDocument doc, OutputStream stream) throws IOException - { - OutputStreamWriter out = new OutputStreamWriter (stream, Charset.forName("UTF-8")); - _out = out; - _doc = doc; - - init (); - openDocument (); - openBody (); - - Range r = doc.getRange (); - StyleSheet styleSheet = doc.getStyleSheet (); - - int sectionLevel = 0; - int lenParagraph = r.numParagraphs (); - boolean inCode = false; - for (int x = 0; x < lenParagraph; x++) - { - Paragraph p = r.getParagraph (x); - String text = p.text (); - if (text.trim ().length () == 0) - { - continue; - } - StyleDescription paragraphStyle = styleSheet.getStyleDescription (p. - getStyleIndex ()); - String styleName = paragraphStyle.getName(); - if (styleName.startsWith ("Heading")) - { - if (inCode) - { - closeSource(); - inCode = false; - } - - int headerLevel = Integer.parseInt (styleName.substring (8)); - if (headerLevel > sectionLevel) - { - openSection (); - } - else - { - for (int y = 0; y < (sectionLevel - headerLevel) + 1; y++) - { - closeSection (); - } - openSection (); - } - sectionLevel = headerLevel; - openTitle (); - writePlainText (text); - closeTitle (); - } - else - { - int cruns = p.numCharacterRuns (); - CharacterRun run = p.getCharacterRun (0); - String fontName = run.getFontName(); - if (fontName.startsWith ("Courier")) - { - if (!inCode) - { - openSource (); - inCode = true; - } - writePlainText (p.text()); - } - else - { - if (inCode) - { - inCode = false; - closeSource(); - } - openParagraph(); - writePlainText(p.text()); - closeParagraph(); - } - } - } - for (int x = 0; x < sectionLevel; x++) - { - closeSection(); - } - closeBody(); - closeDocument(); - _out.flush(); - - } - - public void init () - throws IOException - { - _out.write ("\r\n"); - _out.write ("\r\n"); - } - - public void openDocument () - throws IOException - { - _out.write ("\r\n"); - } - public void closeDocument () - throws IOException - { - _out.write ("\r\n"); - } - - - public void openBody () - throws IOException - { - _out.write ("\r\n"); - } - - public void closeBody () - throws IOException - { - _out.write ("\r\n"); - } - - - public void openSection () - throws IOException - { - _out.write ("

    "); - - } - - public void closeSection () - throws IOException - { - _out.write ("
    "); - - } - - public void openTitle () - throws IOException - { - _out.write (""); - } - - public void closeTitle () - throws IOException - { - _out.write (""); - } - - public void writePlainText (String text) - throws IOException - { - _out.write (text); - } - - public void openParagraph () - throws IOException - { - _out.write ("

    "); - } - - public void closeParagraph () - throws IOException - { - _out.write ("

    "); - } - - public void openSource () - throws IOException - { - _out.write (""); - } - - - public static void main(String[] args) throws IOException { - InputStream is = new FileInputStream(args[0]); - OutputStream out = new FileOutputStream("test.xml"); - try { - new Word2Forrest(new HWPFDocument(is), out); - } finally { - out.close(); - is.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptor.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptor.java deleted file mode 100644 index 247684d1b..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptor.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.io.*; -import org.apache.poi.poifs.filesystem.*; - -/** - *

    Describes the most important (whatever that is) features of a - * {@link POIFSDocument}.

    - */ -public class DocumentDescriptor -{ - String name; - POIFSDocumentPath path; - DocumentInputStream stream; - - int size; - byte[] bytes; - - - /** - *

    Creates a {@link DocumentDescriptor}.

    - * - * @param name The stream's name. - * - * @param path The stream's path in the POI filesystem hierarchy. - * - * @param stream The stream. - * - * @param nrOfBytes The maximum number of bytes to display in a - * dump starting at the beginning of the stream. - */ - public DocumentDescriptor(final String name, - final POIFSDocumentPath path, - final DocumentInputStream stream, - final int nrOfBytes) - { - this.name = name; - this.path = path; - this.stream = stream; - try - { - size = stream.available(); - if (stream.markSupported()) - { - stream.mark(nrOfBytes); - final byte[] b = new byte[nrOfBytes]; - final int read = stream.read(b, 0, Math.min(size, b.length)); - bytes = new byte[read]; - System.arraycopy(b, 0, bytes, 0, read); - stream.reset(); - } - } - catch (IOException ex) - { - System.out.println(ex); - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptorRenderer.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptorRenderer.java deleted file mode 100644 index de1204e77..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptorRenderer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.awt.*; -import javax.swing.*; -import javax.swing.tree.*; - -import org.apache.poi.util.HexDump; - -/** - *

    {@link TreeCellRenderer} for a {@link DocumentDescriptor}. The - * renderer is extremly rudimentary since displays only the document's - * name, its size and its fist few bytes.

    - */ -public class DocumentDescriptorRenderer extends DefaultTreeCellRenderer -{ - - @Override - public Component getTreeCellRendererComponent(final JTree tree, - final Object value, - final boolean selectedCell, - final boolean expanded, - final boolean leaf, - final int row, - final boolean hasCellFocus) - { - final DocumentDescriptor d = (DocumentDescriptor) - ((DefaultMutableTreeNode) value).getUserObject(); - final JPanel p = new JPanel(); - final JTextArea text = new JTextArea(); - text.append(renderAsString(d)); - text.setFont(new Font("Monospaced", Font.PLAIN, 10)); - p.add(text); - if (selectedCell) { - Util.invert(text); - } - return p; - } - - - /** - *

    Renders {@link DocumentDescriptor} as a string.

    - */ - protected String renderAsString(final DocumentDescriptor d) - { - final StringBuilder b = new StringBuilder(); - b.append("Name: "); - b.append(d.name); - b.append(" "); - b.append(HexDump.toHex(d.name)); - b.append("\n"); - - b.append("Size: "); - b.append(d.size); - b.append(" bytes\n"); - - b.append("First bytes: "); - b.append(HexDump.toHex(d.bytes)); - - return b.toString(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/ExtendableTreeCellRenderer.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/ExtendableTreeCellRenderer.java deleted file mode 100644 index dbb759c9c..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/ExtendableTreeCellRenderer.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.awt.*; -import javax.swing.*; -import javax.swing.tree.*; -import java.util.*; - -/** - *

    This is a {@link TreeCellRenderer} implementation which is able - * to render arbitrary objects. The {@link ExtendableTreeCellRenderer} - * does not do the rendering itself but instead dispatches to - * class-specific renderers. A class/renderer pair must be registered - * using the {@link #register} method. If a class has no registered - * renderer, the renderer of its closest superclass is used. Since the - * {@link ExtendableTreeCellRenderer} always has a default renderer - * for the {@link Object} class, rendering is always possible. The - * default {@link Object} renderer can be replaced by another renderer - * but it cannot be unregistered.

    - */ -public class ExtendableTreeCellRenderer implements TreeCellRenderer -{ - - /** - *

    Maps classes to renderers.

    - */ - protected Map,TreeCellRenderer> renderers; - - - - public ExtendableTreeCellRenderer() - { - renderers = new HashMap,TreeCellRenderer>(); - register(Object.class, new DefaultTreeCellRenderer() - { - @Override - public Component getTreeCellRendererComponent - (JTree tree, Object value, boolean selectedCell, - boolean expanded, boolean leaf, int row, boolean hasCellFocus) - { - final String s = value.toString(); - final JLabel l = new JLabel(s + " "); - if (selected) - { - Util.invert(l); - l.setOpaque(true); - } - return l; - } - }); - } - - - - /** - *

    Registers a renderer for a class.

    - **/ - public void register(final Class c, final TreeCellRenderer renderer) - { - renderers.put(c, renderer); - } - - - - /** - *

    Unregisters a renderer for a class. The renderer for the - * {@link Object} class cannot be unregistered.

    - */ - public void unregister(final Class c) - { - if (c == Object.class) - throw new IllegalArgumentException - ("Renderer for Object cannot be unregistered."); - renderers.put(c, null); - } - - - - /** - *

    Renders an object in a tree cell depending of the object's - * class.

    - * - * @see TreeCellRenderer#getTreeCellRendererComponent - */ - @Override - public Component getTreeCellRendererComponent - (final JTree tree, final Object value, final boolean selected, - final boolean expanded, final boolean leaf, final int row, - final boolean hasFocus) - { - final String NULL = "null"; - TreeCellRenderer r; - Object userObject; - if (value == null) - userObject = NULL; - else - { - userObject = ((DefaultMutableTreeNode) value).getUserObject(); - if (userObject == null) - userObject = NULL; - } - r = findRenderer(userObject.getClass()); - return r.getTreeCellRendererComponent - (tree, value, selected, expanded, leaf, row, - hasFocus); - } - - - - /** - *

    Find the renderer for the specified class.

    - */ - protected TreeCellRenderer findRenderer(final Class c) - { - final TreeCellRenderer r = renderers.get(c); - if (r != null) - /* The class has a renderer. */ - return r; - - /* The class has no renderer, try the superclass, if any. */ - final Class superclass = c.getSuperclass(); - if (superclass != null) { - return findRenderer(superclass); - } - return null; - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/POIBrowser.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/POIBrowser.java deleted file mode 100644 index ec84847d6..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/POIBrowser.java +++ /dev/null @@ -1,128 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.FileInputStream; -import java.io.IOException; - -import javax.swing.JFrame; -import javax.swing.JScrollPane; -import javax.swing.JTree; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.MutableTreeNode; - -import org.apache.poi.poifs.eventfilesystem.POIFSReader; - -/** - *

    The main class of the POI Browser. It shows the structure of POI - * filesystems (Microsoft Office documents) in a {@link - * JTree}. Specify their filenames on the command line!

    - * - * @see POIFSReader - */ -@SuppressWarnings("serial") -public class POIBrowser extends JFrame -{ - - /** - *

    The tree's root node must be visible to all methods.

    - */ - protected MutableTreeNode rootNode; - - - - /** - *

    Takes a bunch of file names as command line parameters, - * opens each of them as a POI filesystem and displays their - * internal structures in a {@link JTree}.

    - */ - public static void main(String[] args) - { - new POIBrowser().run(args); - } - - - - protected void run(String[] args) - { - addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent e) - { - System.exit(0); - } - }); - - /* Create the tree model with a root node. The latter is - * invisible but it must be present because a tree model - * always needs a root. */ - rootNode = new DefaultMutableTreeNode("POI Filesystems"); - DefaultTreeModel treeModel = new DefaultTreeModel(rootNode); - - /* Create the tree UI element. */ - final JTree treeUI = new JTree(treeModel); - getContentPane().add(new JScrollPane(treeUI)); - - /* Add the POI filesystems to the tree. */ - int displayedFiles = 0; - for (int i = 0; i < args.length; i++) - { - final String filename = args[i]; - try { - FileInputStream fis = new FileInputStream(filename); - POIFSReader r = new POIFSReader(); - r.registerListener(new TreeReaderListener(filename, rootNode)); - r.read(fis); - fis.close(); - displayedFiles++; - } catch (IOException ex) { - System.err.println(filename + ": " + ex); - } catch (Exception t) { - System.err.println("Unexpected exception while reading \"" + - filename + "\":"); - t.printStackTrace(System.err); - } - } - - /* Exit if there is no file to display (none specified or only - * files with problems). */ - if (displayedFiles == 0) - { - System.out.println("No POI filesystem(s) to display."); - System.exit(0); - } - - /* Make the tree UI element visible. */ - treeUI.setRootVisible(true); - treeUI.setShowsRootHandles(true); - ExtendableTreeCellRenderer etcr = new ExtendableTreeCellRenderer(); - etcr.register(DocumentDescriptor.class, - new DocumentDescriptorRenderer()); - etcr.register(PropertySetDescriptor.class, - new PropertySetDescriptorRenderer()); - treeUI.setCellRenderer(etcr); - setSize(600, 450); - setTitle("POI Browser 0.09"); - setVisible(true); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/PropertySetDescriptor.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/PropertySetDescriptor.java deleted file mode 100644 index f9658ae03..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/PropertySetDescriptor.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -import org.apache.poi.hpsf.MarkUnsupportedException; -import org.apache.poi.hpsf.NoPropertySetStreamException; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; - -/** - *

    Describes the most important (whatever that is) features of a - * stream containing a {@link PropertySet}.

    - */ -public class PropertySetDescriptor extends DocumentDescriptor -{ - - protected PropertySet propertySet; - - /** - *

    Returns this {@link PropertySetDescriptor}'s {@link - * PropertySet}.

    - */ - public PropertySet getPropertySet() - { - return propertySet; - } - - - - /** - *

    Creates a {@link PropertySetDescriptor} by reading a {@link - * PropertySet} from a {@link DocumentInputStream}.

    - * - * @param name The stream's name. - * - * @param path The stream's path in the POI filesystem hierarchy. - * - * @param stream The stream. - * - * @param nrOfBytesToDump The maximum number of bytes to display in a - * dump starting at the beginning of the stream. - */ - public PropertySetDescriptor(final String name, - final POIFSDocumentPath path, - final DocumentInputStream stream, - final int nrOfBytesToDump) - throws NoPropertySetStreamException, - MarkUnsupportedException, UnsupportedEncodingException, - IOException - { - super(name, path, stream, nrOfBytesToDump); - propertySet = PropertySetFactory.create(stream); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/PropertySetDescriptorRenderer.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/PropertySetDescriptorRenderer.java deleted file mode 100644 index 8ce336f24..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/PropertySetDescriptorRenderer.java +++ /dev/null @@ -1,170 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -import java.util.Iterator; -import java.util.List; - -import javax.swing.JPanel; -import javax.swing.JTextArea; -import javax.swing.JTree; -import javax.swing.tree.DefaultMutableTreeNode; - -import org.apache.poi.hpsf.Property; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.Section; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.util.HexDump; - -/** - *

    Renders a {@link PropertySetDescriptor} by more or less dumping - * the stuff into a {@link JTextArea}.

    - */ -public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer -{ - - @Override - public Component getTreeCellRendererComponent(final JTree tree, - final Object value, - final boolean selectedCell, - final boolean expanded, - final boolean leaf, - final int row, - final boolean hasCellFocus) - { - final PropertySetDescriptor d = (PropertySetDescriptor) - ((DefaultMutableTreeNode) value).getUserObject(); - final PropertySet ps = d.getPropertySet(); - final JPanel p = new JPanel(); - final JTextArea text = new JTextArea(); - text.setBackground(new Color(200, 255, 200)); - text.setFont(new Font("Monospaced", Font.PLAIN, 10)); - text.append(renderAsString(d)); - text.append("\nByte order: "); - text.append(HexDump.toHex((short) ps.getByteOrder())); - text.append("\nFormat: "); - text.append(HexDump.toHex((short) ps.getFormat())); - text.append("\nOS version: "); - text.append(HexDump.toHex(ps.getOSVersion())); - text.append("\nClass ID: "); - text.append(HexDump.toHex(ps.getClassID().getBytes())); - text.append("\nSection count: " + ps.getSectionCount()); - text.append(sectionsToString(ps.getSections())); - p.add(text); - - if (ps instanceof SummaryInformation) - { - /* Use the convenience methods. */ - final SummaryInformation si = (SummaryInformation) ps; - text.append("\n"); - text.append("\nTitle: " + si.getTitle()); - text.append("\nSubject: " + si.getSubject()); - text.append("\nAuthor: " + si.getAuthor()); - text.append("\nKeywords: " + si.getKeywords()); - text.append("\nComments: " + si.getComments()); - text.append("\nTemplate: " + si.getTemplate()); - text.append("\nLast Author: " + si.getLastAuthor()); - text.append("\nRev. Number: " + si.getRevNumber()); - text.append("\nEdit Time: " + si.getEditTime()); - text.append("\nLast Printed: " + si.getLastPrinted()); - text.append("\nCreate Date/Time: " + si.getCreateDateTime()); - text.append("\nLast Save Date/Time: " + si.getLastSaveDateTime()); - text.append("\nPage Count: " + si.getPageCount()); - text.append("\nWord Count: " + si.getWordCount()); - text.append("\nChar Count: " + si.getCharCount()); - // text.append("\nThumbnail: " + si.getThumbnail()); - text.append("\nApplication Name: " + si.getApplicationName()); - text.append("\nSecurity: " + si.getSecurity()); - } - - if (selectedCell) - Util.invert(text); - return p; - } - - - - /** - *

    Returns a string representation of a list of {@link - * Section}s.

    - */ - protected String sectionsToString(final List
    sections) - { - final StringBuffer b = new StringBuffer(); - int count = 1; - for (Iterator
    i = sections.iterator(); i.hasNext();) - { - Section s = i.next(); - String d = toString(s, "Section " + count++); - b.append(d); - } - return b.toString(); - } - - - - /** - *

    Returns a string representation of a {@link Section}.

    - * @param s the section - * @param name the section's name - * @return a string representation of the {@link Section} - */ - protected String toString(final Section s, final String name) - { - final StringBuffer b = new StringBuffer(); - b.append("\n" + name + " Format ID: "); - b.append(HexDump.toHex(s.getFormatID().getBytes())); - b.append("\n" + name + " Offset: " + s.getOffset()); - b.append("\n" + name + " Section size: " + s.getSize()); - b.append("\n" + name + " Property count: " + s.getPropertyCount()); - - final Property[] properties = s.getProperties(); - for (int i = 0; i < properties.length; i++) - { - final Property p = properties[i]; - final long id = p.getID(); - final long type = p.getType(); - final Object value = p.getValue(); - b.append('\n'); - b.append(name); - b.append(", Name: "); - b.append(id); - b.append(" ("); - b.append(s.getPIDString(id)); - b.append("), Type: "); - b.append(type); - b.append(", Value: "); - if (value instanceof byte[]) { - byte[] buf = new byte[4]; - System.arraycopy(value, 0, buf, 0, 4); - b.append(HexDump.toHex(buf)); - b.append(' '); - System.arraycopy(value, ((byte[])value).length - 4, buf, 0, 4); - } else if (value != null) { - b.append(value.toString()); - } else { - b.append("null"); - } - } - return b.toString(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java deleted file mode 100644 index d2427ce15..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java +++ /dev/null @@ -1,217 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.util.HashMap; -import java.util.Map; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.MutableTreeNode; - -import org.apache.poi.hpsf.HPSFException; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; - -/** - *

    Organizes document information in a tree model in order to be - * e.g. displayed in a Swing {@link javax.swing.JTree}. An instance of this - * class is created with a root tree node ({@link MutableTreeNode}) and - * registered as a {@link POIFSReaderListener} with a {@link - * org.apache.poi.poifs.eventfilesystem.POIFSReader}. While the latter processes - * a POI filesystem it calls this class' {@link #processPOIFSReaderEvent} for - * each document it has been registered for. This method appends the document it - * processes at the appropriate position into the tree rooted at the - * above mentioned root tree node.

    - * - *

    The root tree node should be the root tree node of a {@link - * javax.swing.tree.TreeModel}.

    - * - *

    A top-level element in the tree model, i.e. an immediate child - * node of the root node, describes a POI filesystem as such. It is - * suggested to use the file's name (as seen by the operating system) - * but it could be any other string.

    - * - *

    The value of a tree node is a {@link DocumentDescriptor}. Unlike - * a {@link org.apache.poi.poifs.filesystem.POIFSDocument} which may be as heavy - * as many megabytes, an instance of {@link DocumentDescriptor} is a - * light-weight object and contains only some meta-information about a - * document.

    - */ -public class TreeReaderListener implements POIFSReaderListener -{ - - /** - *

    The tree's root node. POI filesystems get attached to this - * node as children.

    - */ - protected MutableTreeNode rootNode; - - /** - *

    Maps filenames and POI document paths to their associated - * tree nodes.

    - */ - protected Map pathToNode; - - /** - *

    The name of the file this {@link TreeReaderListener} - * processes. It is used to identify a top-level element in the - * tree. Alternatively any other string can be used. It is just a - * label which should identify a POI filesystem.

    - */ - protected String filename; - - - - /** - *

    Creates a {@link TreeReaderListener} which should then be - * registered with a - * {@link org.apache.poi.poifs.eventfilesystem.POIFSReader}.

    - * - * @param filename The name of the POI filesystem, i.e. the name - * of the file the POI filesystem resides in. Alternatively any - * other string can be used. - * - * @param rootNode All document information will be attached as - * descendands to this tree node. - */ - public TreeReaderListener(final String filename, - final MutableTreeNode rootNode) - { - this.filename = filename; - this.rootNode = rootNode; - pathToNode = new HashMap(15); // Should be a reasonable guess. - } - - - - /**

    The number of bytes to dump.

    */ - private int nrOfBytes = 50; - - public void setNrOfBytes(final int nrOfBytes) - { - this.nrOfBytes = nrOfBytes; - } - - public int getNrOfBytes() - { - return nrOfBytes; - } - - - - /** - *

    A document in the POI filesystem has been opened for - * reading. This method retrieves properties of the document and - * adds them to a tree model.

    - */ - @Override - public void processPOIFSReaderEvent(final POIFSReaderEvent event) - { - DocumentDescriptor d; - final DocumentInputStream is = event.getStream(); - if (!is.markSupported()) - throw new UnsupportedOperationException(is.getClass().getName() + - " does not support mark()."); - - /* Try do handle this document as a property set. We receive - * an exception if is no property set and handle it as a - * document of some other format. We are not concerned about - * that document's details. */ - try - { - d = new PropertySetDescriptor(event.getName(), event.getPath(), - is, nrOfBytes); - } - catch (HPSFException ex) - { - d = new DocumentDescriptor(event.getName(), event.getPath(), - is, nrOfBytes); - } - catch (Exception t) - { - System.err.println - ("Unexpected exception while processing " + - event.getName() + " in " + event.getPath().toString()); - t.printStackTrace(System.err); - throw new RuntimeException(t.getMessage()); - } - - is.close(); - - final MutableTreeNode parentNode = getNode(d.path, filename, rootNode); - final MutableTreeNode nameNode = new DefaultMutableTreeNode(d.name); - parentNode.insert(nameNode, 0); - final MutableTreeNode dNode = new DefaultMutableTreeNode(d); - nameNode.insert(dNode, 0); - } - - - - /** - *

    Locates the parent node for a document entry in the tree - * model. If the parent node does not yet exist it will be - * created, too. This is done recursively, if needed.

    - * - * @param path The tree node for this path is located. - * - * @param fsName The name of the POI filesystem. This is just a - * string which is displayed in the tree at the top lovel. - * - * @param root The root node. - */ - private MutableTreeNode getNode(final POIFSDocumentPath path, - final String fsName, - final MutableTreeNode root) - { - MutableTreeNode n = pathToNode.get(path); - if (n != null) - /* Node found in map, just return it. */ - return n; - if (path.length() == 0) - { - /* This is the root path of the POI filesystem. Its tree - * node is resp. must be located below the tree node of - * the POI filesystem itself. This is a tree node with the - * POI filesystem's name (this the operating system file's - * name) as its key it the path-to-node map. */ - n = pathToNode.get(fsName); - if (n == null) - { - /* A tree node for the POI filesystem does not yet - * exist. */ - n = new DefaultMutableTreeNode(fsName); - pathToNode.put(fsName, n); - root.insert(n, 0); - } - return n; - } - /* else - The path is somewhere down in the POI filesystem's - * hierarchy. We need the tree node of this path's parent - * and attach our new node to it. */ - final String name = path.getComponent(path.length() - 1); - final POIFSDocumentPath parentPath = path.getParent(); - final MutableTreeNode parentNode = - getNode(parentPath, fsName, root); - n = new DefaultMutableTreeNode(name); - pathToNode.put(path, n); - parentNode.insert(n, 0); - return n; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/Util.java b/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/Util.java deleted file mode 100644 index 8e86b1873..000000000 --- a/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/Util.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.poibrowser; - -import java.awt.*; -import javax.swing.*; - -/** - *

    Contains various (well, just one at the moment) static utility - * methods.

    - */ -public class Util { - - /** - *

    Makes a Swing component inverted by swapping its foreground - * and background colors. Hint: Depending on your needs it might - * also be a good idea to call c.setOpaque(true).

    - */ - public static void invert(JComponent c) { - Color invBackground = c.getForeground(); - Color invForeground = c.getBackground(); - c.setBackground(invBackground); - c.setForeground(invForeground); - } -} - diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java b/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java deleted file mode 100644 index 5eb10c242..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java +++ /dev/null @@ -1,1048 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.ss.examples; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.util.Locale; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.IOUtils; - - -/** - * Demonstrates how to add an image to a worksheet and set that images size - * to a specific number of millimetres irrespective of the width of the columns - * or height of the rows. Overridden methods are provided so that the location - * of the image - the cells row and column coordinates that define the top - * left hand corners of the image - can be identified either in the familiar - * Excel manner - A1 for instance - or using POI's methodology of a column and - * row index where 0, 0 would indicate cell A1. - * - * The best way to make use of these techniques is to delay adding the image to - * the sheet until all other work has been completed. That way, the sizes of - * all rows and columns will have been adjusted - assuming that step was - * necessary. Even though the anchors type is set to prevent the image moving - * or re-sizing, this setting does not have any effect until the sheet is being - * viewed using the Excel application. - * - * The key to the process is the ClientAnchor class. It defines methods that allow - * us to define the location of an image by specifying the following; - * - * * How far - in terms of coordinate positions - the image should be inset - * from the left hand border of a cell. - * * How far - in terms of coordinate positions - the image should be inset - * from the from the top of the cell. - * * How far - in terms of coordinate positions - the right hand edge of - * the image should protrude into a cell (measured from the cells left hand - * edge to the images right hand edge). - * * How far - in terms of coordinate positions - the bottom edge of the - * image should protrude into a row (measured from the cells top edge to - * the images bottom edge). - * * The index of the column that contains the cell whose top left hand - * corner should be aligned with the top left hand corner of the image. - * * The index of the row that contains the cell whose top left hand corner - * should be aligned with the images top left hand corner. - * * The index of the column that contains the cell whose top left hand - * corner should be aligned with the images bottom right hand corner - * * The index number of the row that contains the cell whose top left - * hand corner should be aligned with the images bottom right hand corner. - * - * It can be used to add an image into cell A1, for example, in the following - * manner; - * - * ClientAnchor anchor = sheet.getWorkbook().getCreationHelper().createClientAnchor(); - * - * anchor.setDx1(0); - * anchor.setDy1(0); - * anchor.setDx2(0); - * anchor.setDy2(0); - * anchor.setCol1(0); - * anchor.setRow1(0); - * anchor.setCol2(1); - * anchor.setRow2(1); - * - * Taken together, the first four methods define the locations of the top left - * and bottom right hand corners of the image if you imagine that the image is - * represented by a simple rectangle. The setDx1() and setDy1() methods locate - * the top left hand corner of the image while setDx2() and and Dy2() locate the - * bottom right hand corner of the image. An individual image can be inserted - * into a single cell or is can lie across many cells and the latter four methods - * are used to define just where the image should be positioned. They do this by - * again by identifying where the top left and bottom right hand corners of the - * image should be located but this time in terms of the indexes of the cells - * in which those corners should be located. The setCol1() and setRow1() methods - * together identify the cell that should contain the top left hand corner of - * the image while setCol2() and setRow2() do the same for the images bottom - * right hand corner. - * - * Knowing that, it is possible to look again at the example above and to see - * that the top left hand corner of the image will be located in cell A1 (0, 0) - * and it will be aligned with the very top left hand corner of the cell. Likewise, - * the bottom right hand corner of the image will be located in cell B2 (1, 1) and - * it will again be aligned with the top left hand corner of the cell. This has the - * effect of making the image seem to occupy the whole of cell A1. Interestingly, it - * also has an effect on the images resizing behaviour because testing has - * demonstrated that if the image is wholly contained within one cell and is not - * 'attached' for want of a better word, to a neighbouring cell, then that image - * will not increase in size in response to the user dragging the column wider - * or the cell higher. - * - * The following example demonstrates a slightly different way to insert an - * image into cell A1 and to ensure that it occupies the whole of the cell. This - * is accomplished by specifying the the images bottom right hand corner should be - * aligned with the bottom right hand corner of the cell. It is also a case - * where the image will not increase in size if the user increases the size of - * the enclosing cell - irrespective of the anchors type - but it will reduce in - * size if the cell is made smaller. - * - * ClientAnchor anchor = sheet.getWorkbook().getCreationHelper().createClientAnchor(); - * - * anchor.setDx1(0); - * anchor.setDy1(0); - * anchor.setDx2(1023); - * anchor.setDy2(255); - * anchor.setCol1(0); - * anchor.setRow1(0); - * anchor.setCol2(0); - * anchor.setRow2(0); - * - * Note that the final four method calls all pass the same value and seem to - * indicate that the images top left hand corner is aligned with the top left - * hand corner of cell A1 and that it's bottom right hand corner is also - * aligned with the top left hand corner of cell A1. Yet, running this code - * would see the image fully occupying cell A1. That is the result of the - * values passed to parameters three and four; these I have referred to as - * determining the images coordinates within the cell. They indicate that the - * image should occupy - in order - the full width of the column and the full - * height of the row. - * - * The co-ordinate values shown are the maxima; and they are independent of - * row height/column width and of the font used. Passing 255 will always result - * in the image occupying the full height of the row and passing 1023 will - * always result in the image occupying the full width of the column. They help - * in situations where an image is larger than a column/row and must overlap - * into the next column/row. Using them does mean, however, that it is often - * necessary to perform conversions between Excels characters units, points, - * pixels and millimetres in order to establish how many rows/columns an image - * should occupy and just what the various insets ought to be. - * - * Note that the setDx1(int) and setDy1(int) methods of the ClientAchor class - * are not made use of in the code that follows. It would be fairly trivial - * however to extend this example further and provide methods that would centre - * an image within a cell or allow the user to specify that a plain border a - * fixed number of millimetres wide should wrap around the image. Those first - * two parameters would make this sort of functionality perfectly possible. - * - * Owing to the various conversions used, the actual size of the image may vary - * from that required; testing has so far found this to be in the region of - * plus or minus two millimetres. Most likely by modifying the way the - * calculations are performed - possibly using double(s) throughout and - * rounding the values at the correct point - it is likely that these errors - * could be reduced or removed. - * - * A note concerning Excels image resizing behaviour. The ClientAnchor - * class contains a method called setAnchorType(int) which can be used to - * determine how Excel will resize an image in response to the user increasing - * or decreasing the dimensions of the cell containing the image. There are - * three values that can be passed to this method; 0 = To move and size the - * image with the cell, 2 = To move but don't size the image with the cell, - * 3 = To prevent the image from moving or being resized along with the cell. If - * an image is inserted using this class and placed into a single cell then if - * the setAnchorType(int) method is called and a value of either 0 or 2 passed - * to it, the resultant resizing behaviour may be a surprise. The image will not - * grow in size of the column is made wider or the row higher but it will shrink - * if the columns width or rows height are reduced. - * - * @author Mark Beardsley [msb at apache.org] and Mark Southern [southern at scripps.edu] - * @version 1.00 5th August 2009. - * 2.00 26th February 2010. - * Ported to make use of the the SS usermodel classes. - * Ability to reuse the Drawing Patriarch so that multiple images - * can be inserted without unintentionally erasing earlier images. - * Check on image type added; i.e. jpg, jpeg or png. - * The String used to contain the files name is now converted - * into a URL. - * 2.10 17th May 2012 - * Corrected gross error that occurred when using the code with - * XSSF or SXSSF workbooks. In short, the code did not correctly - * calculate the size of the image(s) owing to the use of EMUs - * within the OOXML file format. That problem has largely been - * corrected although it should be mentioned that images are not - * sized with the same level of accuracy. Discrepancies of up to - * 2mm have been noted in testing. Further investigation will - * continue to rectify this issue. - */ -public class AddDimensionedImage { - - // Four constants that determine how - and indeed whether - the rows - // and columns an image may overlie should be expanded to accomodate that - // image. - // Passing EXPAND_ROW will result in the height of a row being increased - // to accomodate the image if it is not already larger. The image will - // be layed across one or more columns. - // Passing EXPAND_COLUMN will result in the width of the column being - // increased to accomodate the image if it is not already larger. The image - // will be layed across one or many rows. - // Passing EXPAND_ROW_AND_COLUMN will result in the height of the row - // bing increased along with the width of the column to accomdate the - // image if either is not already larger. - // Passing OVERLAY_ROW_AND_COLUMN will result in the image being layed - // over one or more rows and columns. No row or column will be resized, - // instead, code will determine how many rows and columns the image should - // overlie. - public static final int EXPAND_ROW = 1; - public static final int EXPAND_COLUMN = 2; - public static final int EXPAND_ROW_AND_COLUMN = 3; - public static final int OVERLAY_ROW_AND_COLUMN = 7; - - // Modified to support EMU - English Metric Units - used within the OOXML - // workbooks, this multoplier is used to convert between measurements in - // millimetres and in EMUs - private static final int EMU_PER_MM = 36000; - - /** - * Add an image to a worksheet. - * - * @param cellNumber A String that contains the location of the cell whose - * top left hand corner should be aligned with the top - * left hand corner of the image; for example "A1", "A2" - * etc. This is to support the familiar Excel syntax. - * Whilst images are are not actually inserted into cells - * this provides a convenient method of indicating where - * the image should be positioned on the sheet. - * @param sheet A reference to the sheet that contains the cell referenced - * above. - * @param drawing An instance of the DrawingPatriarch class. This is now - * passed into the method where it was, previously, recovered - * from the sheet in order to allow multiple pictures be - * inserted. If the patriarch was not 'cached in this manner - * each time it was created any previously positioned images - * would be simply over-written. - * @param imageFile An instance of the URL class that encapsulates the name - * of and path to the image that is to be 'inserted into' - * the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres. - * @param resizeBehaviour A primitive int whose value will determine how - * the code should react if the image is larger than - * the cell referenced by the cellNumber parameter. - * Four constants are provided to determine what - * should happen; - * AddDimensionedImage.EXPAND_ROW - * AddDimensionedImage.EXPAND_COLUMN - * AddDimensionedImage.EXPAND_ROW_AND_COLUMN - * AddDimensionedImage.OVERLAY_ROW_AND_COLUMN - * @throws java.io.FileNotFoundException If the file containing the image - * cannot be located. - * @throws java.io.IOException If a problem occurs whilst reading the file - * of image data. - * @throws java.lang.IllegalArgumentException If an invalid value is passed - * to the resizeBehaviour - * parameter. - */ - public void addImageToSheet(String cellNumber, Sheet sheet, Drawing drawing, - URL imageFile, double reqImageWidthMM, double reqImageHeightMM, - int resizeBehaviour) throws IOException, IllegalArgumentException { - // Convert the String into column and row indices then chain the - // call to the overridden addImageToSheet() method. - CellReference cellRef = new CellReference(cellNumber); - this.addImageToSheet(cellRef.getCol(), cellRef.getRow(), sheet, drawing, - imageFile, reqImageWidthMM, reqImageHeightMM,resizeBehaviour); - } - - /** - * Add an image to a worksheet. - * - * @param colNumber A primitive int that contains the index number of a - * column on the worksheet; POI column indices are zero - * based. Together with the rowNumber parameter's value, - * this parameter identifies a cell on the worksheet. The - * images top left hand corner will be aligned with the - * top left hand corner of this cell. - * @param rowNumber A primitive int that contains the index number of a row - * on the worksheet; POI row indices are zero based. - * Together with the rowNumber parameter's value, this - * parameter identifies a cell on the worksheet. The - * images top left hand corner will be aligned with the - * top left hand corner of this cell. - * @param sheet A reference to the sheet that contains the cell identified - * by the two parameters above. - * @param drawing An instance of the DrawingPatriarch class. This is now - * passed into the method where it was, previously, recovered - * from the sheet in order to allow multiple pictures be - * inserted. If the patriarch was not 'cached in this manner - * each time it was created any previously positioned images - * would be simply over-written. - * @param imageFile An instance of the URL class that encapsulates the name - * of and path to the image that is to be 'inserted into' - * the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres. - * @param resizeBehaviour A primitive int whose value will determine how - * the code should react if the image is larger than - * the cell referenced by the colNumber and - * rowNumber parameters. Four constants are provided - * to determine what should happen; - * AddDimensionedImage.EXPAND_ROW - * AddDimensionedImage.EXPAND_COLUMN - * AddDimensionedImage.EXPAND_ROW_AND_COLUMN - * AddDimensionedImage.OVERLAY_ROW_AND_COLUMN - * @throws java.io.FileNotFoundException If the file containing the image - * cannot be located. - * @throws java.io.IOException If a problem occurs whilst reading the file - * of image data. - * @throws java.lang.IllegalArgumentException If an invalid value is passed - * to the resizeBehaviour - * parameter or if the extension - * of the image file indicates that - * it is of a type that cannot - * currently be added to the worksheet. - */ - public void addImageToSheet(int colNumber, int rowNumber, Sheet sheet, Drawing drawing, - URL imageFile, double reqImageWidthMM, double reqImageHeightMM, - int resizeBehaviour) throws IOException, - IllegalArgumentException { - ClientAnchor anchor = null; - ClientAnchorDetail rowClientAnchorDetail = null; - ClientAnchorDetail colClientAnchorDetail = null; - int imageType = 0; - - // Validate the resizeBehaviour parameter. - if((resizeBehaviour != AddDimensionedImage.EXPAND_COLUMN) && - (resizeBehaviour != AddDimensionedImage.EXPAND_ROW) && - (resizeBehaviour != AddDimensionedImage.EXPAND_ROW_AND_COLUMN) && - (resizeBehaviour != AddDimensionedImage.OVERLAY_ROW_AND_COLUMN)) { - throw new IllegalArgumentException("Invalid value passed to the " + - "resizeBehaviour parameter of AddDimensionedImage.addImageToSheet()"); - } - - // Call methods to calculate how the image and sheet should be - // manipulated to accomodate the image; columns and then rows. - colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber, - reqImageWidthMM, resizeBehaviour); - rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber, - reqImageHeightMM, resizeBehaviour); - - // Having determined if and how to resize the rows, columns and/or the - // image, create the ClientAnchor object to position the image on - // the worksheet. Note how the two ClientAnchorDetail records are - // interrogated to recover the row/column co-ordinates and any insets. - // The first two parameters are not used currently but could be if the - // need arose to extend the functionality of this code by adding the - // ability to specify that a clear 'border' be placed around the image. - anchor = sheet.getWorkbook().getCreationHelper().createClientAnchor(); - - anchor.setDx1(0); - anchor.setDy1(0); - anchor.setDx2(colClientAnchorDetail.getInset()); - anchor.setDy2(rowClientAnchorDetail.getInset()); - anchor.setCol1(colClientAnchorDetail.getFromIndex()); - anchor.setRow1(rowClientAnchorDetail.getFromIndex()); - anchor.setCol2(colClientAnchorDetail.getToIndex()); - anchor.setRow2(rowClientAnchorDetail.getToIndex()); - - // For now, set the anchor type to do not move or resize the - // image as the size of the row/column is adjusted. This could easily - // become another parameter passed to the method. Please read the note - // above regarding the behaviour of image resizing. - anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE); - - // Now, add the picture to the workbook. Note that unlike the similar - // method in the HSSF Examples section, the image type is checked. First, - // the image files location is identified by interrogating the URL passed - // to the method, the images type is identified before it is added to the - // sheet. - String sURL = imageFile.toString().toLowerCase(Locale.ROOT); - if( sURL.endsWith(".png") ) { - imageType = Workbook.PICTURE_TYPE_PNG; - } - else if( sURL.endsWith("jpg") || sURL.endsWith(".jpeg") ) { - imageType = Workbook.PICTURE_TYPE_JPEG; - } - else { - throw new IllegalArgumentException("Invalid Image file : " + - sURL); - } - int index = sheet.getWorkbook().addPicture( - IOUtils.toByteArray(imageFile.openStream()), imageType); - drawing.createPicture(anchor, index); - } - - /** - * Determines whether the sheets columns should be re-sized to accommodate - * the image, adjusts the columns width if necessary and creates then - * returns a ClientAnchorDetail object that facilitates construction of - * an ClientAnchor that will fix the image on the sheet and establish - * it's size. - * - * @param sheet A reference to the sheet that will 'contain' the image. - * @param colNumber A primitive int that contains the index number of a - * column on the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres - * @param resizeBehaviour A primitive int whose value will indicate how the - * width of the column should be adjusted if the - * required width of the image is greater than the - * width of the column. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the column containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number column containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the right hand - * edge of the image can protrude into the next column - expressed - * as a specific number of coordinate positions. - */ - private ClientAnchorDetail fitImageToColumns(Sheet sheet, int colNumber, - double reqImageWidthMM, int resizeBehaviour) { - - double colWidthMM = 0.0D; - double colCoordinatesPerMM = 0.0D; - int pictureWidthCoordinates = 0; - ClientAnchorDetail colClientAnchorDetail = null; - - // Get the colum's width in millimetres - colWidthMM = ConvertImageUnits.widthUnits2Millimetres( - (short)sheet.getColumnWidth(colNumber)); - - // Check that the column's width will accomodate the image at the - // required dimension. If the width of the column is LESS than the - // required width of the image, decide how the application should - // respond - resize the column or overlay the image across one or more - // columns. - if(colWidthMM < reqImageWidthMM) { - - // Should the column's width simply be expanded? - if((resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) { - // Set the width of the column by converting the required image - // width from millimetres into Excel's column width units. - sheet.setColumnWidth(colNumber, - ConvertImageUnits.millimetres2WidthUnits(reqImageWidthMM)); - // To make the image occupy the full width of the column, convert - // the required width of the image into co-ordinates. This value - // will become the inset for the ClientAnchorDetail class that - // is then instantiated. - if(sheet instanceof HSSFSheet) { - colWidthMM = reqImageWidthMM; - colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM); - - } - else { - pictureWidthCoordinates = (int)reqImageWidthMM * AddDimensionedImage.EMU_PER_MM; - } - colClientAnchorDetail = new ClientAnchorDetail(colNumber, - colNumber, pictureWidthCoordinates); - } - // If the user has chosen to overlay both rows and columns or just - // to expand ONLY the size of the rows, then calculate how to lay - // the image out across one or more columns. - else if ((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW)) { - colClientAnchorDetail = this.calculateColumnLocation(sheet, - colNumber, reqImageWidthMM); - } - } - // If the column is wider than the image. - else { - if(sheet instanceof HSSFSheet) { - // Mow many co-ordinate positions are there per millimetre? - colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - // Given the width of the image, what should be it's co-ordinate? - pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM); - } - else { - pictureWidthCoordinates = (int)reqImageWidthMM * - AddDimensionedImage.EMU_PER_MM; - } - colClientAnchorDetail = new ClientAnchorDetail(colNumber, - colNumber, pictureWidthCoordinates); - } - return(colClientAnchorDetail); - } - - /** - * Determines whether the sheets row should be re-sized to accomodate - * the image, adjusts the rows height if necessary and creates then - * returns a ClientAnchorDetail object that facilitates construction of - * a ClientAnchor that will fix the image on the sheet and establish - * it's size. - * - * @param sheet A reference to the sheet that will 'contain' the image. - * @param rowNumber A primitive int that contains the index number of a - * row on the sheet. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres - * @param resizeBehaviour A primitive int whose value will indicate how the - * height of the row should be adjusted if the - * required height of the image is greater than the - * height of the row. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the row containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number of the row containing the cell whose - * top left hand corner also defines the bottom right hand - * corner of the image and an inset that determines how far the - * bottom edge of the image can protrude into the next (lower) - * row - expressed as a specific number of coordinate positions. - */ - private ClientAnchorDetail fitImageToRows(Sheet sheet, int rowNumber, - double reqImageHeightMM, int resizeBehaviour) { - Row row = null; - double rowHeightMM = 0.0D; - double rowCoordinatesPerMM = 0.0D; - int pictureHeightCoordinates = 0; - ClientAnchorDetail rowClientAnchorDetail = null; - - // Get the row and it's height - row = sheet.getRow(rowNumber); - if(row == null) { - // Create row if it does not exist. - row = sheet.createRow(rowNumber); - } - - // Get the row's height in millimetres - rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE; - - // Check that the row's height will accomodate the image at the required - // dimensions. If the height of the row is LESS than the required height - // of the image, decide how the application should respond - resize the - // row or overlay the image across a series of rows. - if(rowHeightMM < reqImageHeightMM) { - if((resizeBehaviour == AddDimensionedImage.EXPAND_ROW) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) { - row.setHeightInPoints((float)(reqImageHeightMM * - ConvertImageUnits.POINTS_PER_MILLIMETRE)); - if(sheet instanceof HSSFSheet) { - rowHeightMM = reqImageHeightMM; - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - pictureHeightCoordinates = (int)(reqImageHeightMM * - rowCoordinatesPerMM); - } - else { - pictureHeightCoordinates = (int)(reqImageHeightMM * - AddDimensionedImage.EMU_PER_MM); - } - rowClientAnchorDetail = new ClientAnchorDetail(rowNumber, - rowNumber, pictureHeightCoordinates); - } - // If the user has chosen to overlay both rows and columns or just - // to expand ONLY the size of the columns, then calculate how to lay - // the image out ver one or more rows. - else if((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN)) { - rowClientAnchorDetail = this.calculateRowLocation(sheet, - rowNumber, reqImageHeightMM); - } - } - // Else, if the image is smaller than the space available - else { - if(sheet instanceof HSSFSheet) { - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM); - } - else { - pictureHeightCoordinates = (int)(reqImageHeightMM * - AddDimensionedImage.EMU_PER_MM); - } - rowClientAnchorDetail = new ClientAnchorDetail(rowNumber, - rowNumber, pictureHeightCoordinates); - } - return(rowClientAnchorDetail); - } - - /** - * If the image is to overlie more than one column, calculations need to be - * performed to determine how many columns and whether the image will - * overlie just a part of one column in order to be presented at the - * required size. - * - * @param sheet The sheet that will 'contain' the image. - * @param startingColumn A primitive int whose value is the index of the - * column that contains the cell whose top left hand - * corner should be aligned with the top left hand - * corner of the image. - * @param reqImageWidthMM A primitive double whose value will indicate the - * required width of the image in millimetres. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the column containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number column containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the right hand - * edge of the image can protrude into the next column - expressed - * as a specific number of coordinate positions. - */ - private ClientAnchorDetail calculateColumnLocation(Sheet sheet, - int startingColumn, - double reqImageWidthMM) { - ClientAnchorDetail anchorDetail = null; - double totalWidthMM = 0.0D; - double colWidthMM = 0.0D; - double overlapMM = 0.0D; - double coordinatePositionsPerMM = 0.0D; - int toColumn = startingColumn; - int inset = 0; - - // Calculate how many columns the image will have to - // span in order to be presented at the required size. - while(totalWidthMM < reqImageWidthMM) { - colWidthMM = ConvertImageUnits.widthUnits2Millimetres( - (short)(sheet.getColumnWidth(toColumn))); - // Note use of the cell border width constant. Testing with an image - // declared to fit exactly into one column demonstrated that it's - // width was greater than the width of the column the POI returned. - // Further, this difference was a constant value that I am assuming - // related to the cell's borders. Either way, that difference needs - // to be allowed for in this calculation. - totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES); - toColumn++; - } - // De-crement by one the last column value. - toColumn--; - // Highly unlikely that this will be true but, if the width of a series - // of columns is exactly equal to the required width of the image, then - // simply build a ClientAnchorDetail object with an inset equal to the - // total number of co-ordinate positions available in a column, a - // from column co-ordinate (top left hand corner) equal to the value - // of the startingColumn parameter and a to column co-ordinate equal - // to the toColumn variable. - // - // Convert both values to ints to perform the test. - if((int)totalWidthMM == (int)reqImageWidthMM) { - // A problem could occur if the image is sized to fit into one or - // more columns. If that occurs, the value in the toColumn variable - // will be in error. To overcome this, there are two options, to - // ibcrement the toColumn variable's value by one or to pass the - // total number of co-ordinate positions to the third paramater - // of the ClientAnchorDetail constructor. For no sepcific reason, - // the latter option is used below. - if(sheet instanceof HSSFSheet) { - anchorDetail = new ClientAnchorDetail(startingColumn, - toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS); - } - else { - anchorDetail = new ClientAnchorDetail(startingColumn, - toColumn, (int)reqImageWidthMM * AddDimensionedImage.EMU_PER_MM); - } - } - // In this case, the image will overlap part of another column and it is - // necessary to calculate just how much - this will become the inset - // for the ClientAnchorDetail object. - else { - // Firstly, claculate how much of the image should overlap into - // the next column. - overlapMM = reqImageWidthMM - (totalWidthMM - colWidthMM); - - // When the required size is very close indded to the column size, - // the calcaulation above can produce a negative value. To prevent - // problems occuring in later caculations, this is simply removed - // be setting the overlapMM value to zero. - if(overlapMM < 0) { - overlapMM = 0.0D; - } - - if(sheet instanceof HSSFSheet) { - // Next, from the columns width, calculate how many co-ordinate - // positons there are per millimetre - coordinatePositionsPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - // From this figure, determine how many co-ordinat positions to - // inset the left hand or bottom edge of the image. - inset = (int)(coordinatePositionsPerMM * overlapMM); - } - else { - inset = (int)overlapMM * AddDimensionedImage.EMU_PER_MM; - } - - // Now create the ClientAnchorDetail object, setting the from and to - // columns and the inset. - anchorDetail = new ClientAnchorDetail(startingColumn, toColumn, inset); - } - return(anchorDetail); - } - - /** - * If the image is to overlie more than one rows, calculations need to be - * performed to determine how many rows and whether the image will - * overlie just a part of one row in order to be presented at the - * required size. - * - * @param sheet The sheet that will 'contain' the image. - * @param startingRow A primitive int whose value is the index of the row - * that contains the cell whose top left hand corner - * should be aligned with the top left hand corner of - * the image. - * @param reqImageHeightMM A primitive double whose value will indicate the - * required height of the image in millimetres. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the row containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number of the row containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the bottom edge - * can protrude into the next (lower) row - expressed as a specific - * number of co-ordinate positions. - */ - private ClientAnchorDetail calculateRowLocation(Sheet sheet, - int startingRow, double reqImageHeightMM) { - ClientAnchorDetail clientAnchorDetail = null; - Row row = null; - double rowHeightMM = 0.0D; - double totalRowHeightMM = 0.0D; - double overlapMM = 0.0D; - double rowCoordinatesPerMM = 0.0D; - int toRow = startingRow; - int inset = 0; - - // Step through the rows in the sheet and accumulate a total of their - // heights. - while(totalRowHeightMM < reqImageHeightMM) { - row = sheet.getRow(toRow); - // Note, if the row does not already exist on the sheet then create - // it here. - if(row == null) { - row = sheet.createRow(toRow); - } - // Get the row's height in millimetres and add to the running total. - rowHeightMM = row.getHeightInPoints() / - ConvertImageUnits.POINTS_PER_MILLIMETRE; - totalRowHeightMM += rowHeightMM; - toRow++; - } - // Owing to the way the loop above works, the rowNumber will have been - // incremented one row too far. Undo that here. - toRow--; - // Check to see whether the image should occupy an exact number of - // rows. If so, build the ClientAnchorDetail record to point - // to those rows and with an inset of the total number of co-ordinate - // position in the row. - // - // To overcome problems that can occur with comparing double values for - // equality, cast both to int(s) to truncate the value; VERY crude and - // I do not really like it!! - if((int)totalRowHeightMM == (int)reqImageHeightMM) { - if(sheet instanceof HSSFSheet) { - clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow, - ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS); - } - else { - clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow, - (int)reqImageHeightMM * AddDimensionedImage.EMU_PER_MM); - } - } - else { - // Calculate how far the image will project into the next row. Note - // that the height of the last row assessed is subtracted from the - // total height of all rows assessed so far. - overlapMM = reqImageHeightMM - (totalRowHeightMM - rowHeightMM); - - // To prevent an exception being thrown when the required width of - // the image is very close indeed to the column size. - if(overlapMM < 0) { - overlapMM = 0.0D; - } - - if(sheet instanceof HSSFSheet) { - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - inset = (int)(overlapMM * rowCoordinatesPerMM); - } - else { - inset = (int)overlapMM * AddDimensionedImage.EMU_PER_MM; - } - clientAnchorDetail = new ClientAnchorDetail(startingRow, - toRow, inset); - } - return(clientAnchorDetail); - } - - /** - * The main entry point to the program. It contains code that demonstrates - * one way to use the program. - * - * Note, the code is not restricted to use on new workbooks only. If an - * image is to be inserted into an existing workbook. just open that - * workbook, gat a reference to a sheet and pass that; - * - * AddDimensionedImage addImage = new AddDimensionedImage(); - * - * File file = new File("....... Existing Workbook ......."); - * FileInputStream fis = new FileInputStream(file); - * Workbook workbook = new HSSFWorkbook(fis); - * HSSFSheet sheet = workbook.getSheetAt(0); - * addImage.addImageToSheet("C3", sheet, "image.jpg", 30, 20, - * AddDimensionedImage.EXPAND.ROW); - * - * @param args the command line arguments - */ - public static void main(String[] args) { - String imageFile = null; - String outputFile = null; - FileOutputStream fos = null; - Workbook workbook = null; - Sheet sheet = null; - try { - if(args.length < 2){ - System.err.println("Usage: AddDimensionedImage imageFile outputFile"); - return; - } - workbook = new HSSFWorkbook(); // OR XSSFWorkbook - sheet = workbook.createSheet("Picture Test"); - imageFile = args[0]; - outputFile = args[1]; - new AddDimensionedImage().addImageToSheet("B5", sheet, sheet.createDrawingPatriarch(), - new File(imageFile).toURI().toURL(), 100, 40, - AddDimensionedImage.EXPAND_ROW_AND_COLUMN); - fos = new FileOutputStream(outputFile); - workbook.write(fos); - } - catch(FileNotFoundException fnfEx) { - System.out.println("Caught an: " + fnfEx.getClass().getName()); - System.out.println("Message: " + fnfEx.getMessage()); - System.out.println("Stacktrace follows..........."); - fnfEx.printStackTrace(System.out); - } - catch(IOException ioEx) { - System.out.println("Caught an: " + ioEx.getClass().getName()); - System.out.println("Message: " + ioEx.getMessage()); - System.out.println("Stacktrace follows..........."); - ioEx.printStackTrace(System.out); - } - finally { - if(fos != null) { - try { - fos.close(); - fos = null; - } - catch(IOException ioEx) { - // I G N O R E - } - } - } - } - - /** - * The HSSFClientAnchor class accepts eight arguments. In order, these are; - * - * * How far the left hand edge of the image is inset from the left hand - * edge of the cell - * * How far the top edge of the image is inset from the top of the cell - * * How far the right hand edge of the image is inset from the left - * hand edge of the cell - * * How far the bottom edge of the image is inset from the top of the - * cell. - * * Together, arguments five and six determine the column and row - * coordinates of the cell whose top left hand corner will be aligned - * with the images top left hand corner. - * * Together, arguments seven and eight determine the column and row - * coordinates of the cell whose top left hand corner will be aligned - * with the images bottom right hand corner. - * - * An instance of the ClientAnchorDetail class provides three of the eight - * parameters, one of the coordinates for the images top left hand corner, - * one of the coordinates for the images bottom right hand corner and - * either how far the image should be inset from the top or the left hand - * edge of the cell. - * - * @author Mark Beardsley [msb at apache.org] - * @version 1.00 5th August 2009. - */ - public class ClientAnchorDetail { - - public int fromIndex = 0; - public int toIndex = 0; - public int inset = 0; - - /** - * Create a new instance of the ClientAnchorDetail class using the - * following parameters. - * - * @param fromIndex A primitive int that contains one of the - * coordinates (row or column index) for the top left - * hand corner of the image. - * @param toIndex A primitive int that contains one of the - * coordinates (row or column index) for the bottom - * right hand corner of the image. - * @param inset A primitive int that contains a value which indicates - * how far the image should be inset from the top or the - * left hand edge of a cell. - */ - public ClientAnchorDetail(int fromIndex, int toIndex, int inset) { - this.fromIndex = fromIndex; - this.toIndex = toIndex; - this.inset = inset; - } - - /** - * Get one of the number of the column or row that contains the cell - * whose top left hand corner will be aligned with the top left hand - * corner of the image. - * - * @return The value - row or column index - for one of the coordinates - * of the top left hand corner of the image. - */ - public int getFromIndex() { - return(this.fromIndex); - } - - /** - * Get one of the number of the column or row that contains the cell - * whose top left hand corner will be aligned with the bottom right hand - * corner of the image. - * - * @return The value - row or column index - for one of the coordinates - * of the bottom right hand corner of the image. - */ - public int getToIndex() { - return(this.toIndex); - } - - /** - * Get the images offset from the edge of a cell. - * - * @return How far either the right hand or bottom edge of the image is - * inset from the left hand or top edge of a cell. - */ - public int getInset() { - return(this.inset); - } - } - - /** - * Utility methods used to convert Excels character based column and row - * size measurements into pixels and/or millimetres. The class also contains - * various constants that are required in other calculations. - * - * @author xio[darjino@hotmail.com] - * @version 1.01 30th July 2009. - * Added by Mark Beardsley [msb at apache.org]. - * Additional constants. - * widthUnits2Millimetres() and millimetres2Units() methods. - */ - public static class ConvertImageUnits { - - // Each cell conatins a fixed number of co-ordinate points; this number - // does not vary with row height or column width or with font. These two - // constants are defined below. - public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB - public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255; // MB - // The resoultion of an image can be expressed as a specific number - // of pixels per inch. Displays and printers differ but 96 pixels per - // inch is an acceptable standard to beging with. - public static final int PIXELS_PER_INCH = 96; // MB - // Cnstants that defines how many pixels and points there are in a - // millimetre. These values are required for the conversion algorithm. - public static final double PIXELS_PER_MILLIMETRES = 3.78; // MB - public static final double POINTS_PER_MILLIMETRE = 2.83; // MB - // The column width returned by HSSF and the width of a picture when - // positioned to exactly cover one cell are different by almost exactly - // 2mm - give or take rounding errors. This constant allows that - // additional amount to be accounted for when calculating how many - // celles the image ought to overlie. - public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D; // MB - public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256; - public static final int UNIT_OFFSET_LENGTH = 7; - public static final int[] UNIT_OFFSET_MAP = new int[] - { 0, 36, 73, 109, 146, 182, 219 }; - - /** - * pixel units to excel width units(units of 1/256th of a character width) - * @param pxs - * @return - */ - public static short pixel2WidthUnits(int pxs) { - short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * - (pxs / UNIT_OFFSET_LENGTH)); - widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)]; - return widthUnits; - } - - /** - * excel width units(units of 1/256th of a character width) to pixel - * units. - * - * @param widthUnits - * @return - */ - public static int widthUnits2Pixel(short widthUnits) { - int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) - * UNIT_OFFSET_LENGTH; - int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR; - pixels += Math.round(offsetWidthUnits / - ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH)); - return pixels; - } - - /** - * Convert Excels width units into millimetres. - * - * @param widthUnits The width of the column or the height of the - * row in Excels units. - * @return A primitive double that contains the columns width or rows - * height in millimetres. - */ - public static double widthUnits2Millimetres(short widthUnits) { - return(ConvertImageUnits.widthUnits2Pixel(widthUnits) / - ConvertImageUnits.PIXELS_PER_MILLIMETRES); - } - - /** - * Convert into millimetres Excels width units.. - * - * @param millimetres A primitive double that contains the columns - * width or rows height in millimetres. - * @return A primitive int that contains the columns width or rows - * height in Excels units. - */ - public static int millimetres2WidthUnits(double millimetres) { - return(ConvertImageUnits.pixel2WidthUnits((int)(millimetres * - ConvertImageUnits.PIXELS_PER_MILLIMETRES))); - } - - public static int pointsToPixels(double points) { - return (int) Math.round(points / 72D * PIXELS_PER_INCH); - } - - public static double pointsToMillimeters(double points) { - return points / 72D * 25.4; - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/AligningCells.java b/trunk/src/examples/src/org/apache/poi/ss/examples/AligningCells.java deleted file mode 100644 index 8ee6440fd..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/AligningCells.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Shows how various alignment options work. - */ -public class AligningCells { - - public static void main(String[] args) throws IOException { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - - Sheet sheet = wb.createSheet(); - Row row = sheet.createRow(2); - row.setHeightInPoints(30); - for (int i = 0; i < 8; i++) { - //column width is set in units of 1/256th of a character width - sheet.setColumnWidth(i, 256 * 15); - } - - createCell(wb, row, 0, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM); - createCell(wb, row, 1, HorizontalAlignment.CENTER_SELECTION, VerticalAlignment.BOTTOM); - createCell(wb, row, 2, HorizontalAlignment.FILL, VerticalAlignment.CENTER); - createCell(wb, row, 3, HorizontalAlignment.GENERAL, VerticalAlignment.CENTER); - createCell(wb, row, 4, HorizontalAlignment.JUSTIFY, VerticalAlignment.JUSTIFY); - createCell(wb, row, 5, HorizontalAlignment.LEFT, VerticalAlignment.TOP); - createCell(wb, row, 6, HorizontalAlignment.RIGHT, VerticalAlignment.TOP); - - // Write the output to a file - OutputStream fileOut = new FileOutputStream("ss-example-align.xlsx"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } - - /** - * Creates a cell and aligns it a certain way. - * - * @param wb the workbook - * @param row the row to create the cell in - * @param column the column number to create the cell in - * @param halign the horizontal alignment for the cell. - */ - private static void createCell(Workbook wb, Row row, int column, HorizontalAlignment halign, VerticalAlignment valign) { - CreationHelper ch = wb.getCreationHelper(); - Cell cell = row.createCell(column); - cell.setCellValue(ch.createRichTextString("Align It")); - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(halign); - cellStyle.setVerticalAlignment(valign); - cell.setCellStyle(cellStyle); - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java b/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java deleted file mode 100644 index d263494ec..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java +++ /dev/null @@ -1,330 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples; - -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import java.util.Map; -import java.util.HashMap; -import java.util.Calendar; -import java.io.FileOutputStream; -import java.text.SimpleDateFormat; - -/** - * A business plan demo - * Usage: - * BusinessPlan -xls|xlsx - * - * @author Yegor Kozlov - */ -public class BusinessPlan { - - private static SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM"); - - private static final String[] titles = { - "ID", "Project Name", "Owner", "Days", "Start", "End"}; - - //sample data to fill the sheet. - private static final String[][] data = { - {"1.0", "Marketing Research Tactical Plan", "J. Dow", "70", "9-Jul", null, - "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x"}, - null, - {"1.1", "Scope Definition Phase", "J. Dow", "10", "9-Jul", null, - "x", "x", null, null, null, null, null, null, null, null, null}, - {"1.1.1", "Define research objectives", "J. Dow", "3", "9-Jul", null, - "x", null, null, null, null, null, null, null, null, null, null}, - {"1.1.2", "Define research requirements", "S. Jones", "7", "10-Jul", null, - "x", "x", null, null, null, null, null, null, null, null, null}, - {"1.1.3", "Determine in-house resource or hire vendor", "J. Dow", "2", "15-Jul", null, - "x", "x", null, null, null, null, null, null, null, null, null}, - null, - {"1.2", "Vendor Selection Phase", "J. Dow", "19", "19-Jul", null, - null, "x", "x", "x", "x", null, null, null, null, null, null}, - {"1.2.1", "Define vendor selection criteria", "J. Dow", "3", "19-Jul", null, - null, "x", null, null, null, null, null, null, null, null, null}, - {"1.2.2", "Develop vendor selection questionnaire", "S. Jones, T. Wates", "2", "22-Jul", null, - null, "x", "x", null, null, null, null, null, null, null, null}, - {"1.2.3", "Develop Statement of Work", "S. Jones", "4", "26-Jul", null, - null, null, "x", "x", null, null, null, null, null, null, null}, - {"1.2.4", "Evaluate proposal", "J. Dow, S. Jones", "4", "2-Aug", null, - null, null, null, "x", "x", null, null, null, null, null, null}, - {"1.2.5", "Select vendor", "J. Dow", "1", "6-Aug", null, - null, null, null, null, "x", null, null, null, null, null, null}, - null, - {"1.3", "Research Phase", "G. Lee", "47", "9-Aug", null, - null, null, null, null, "x", "x", "x", "x", "x", "x", "x"}, - {"1.3.1", "Develop market research information needs questionnaire", "G. Lee", "2", "9-Aug", null, - null, null, null, null, "x", null, null, null, null, null, null}, - {"1.3.2", "Interview marketing group for market research needs", "G. Lee", "2", "11-Aug", null, - null, null, null, null, "x", "x", null, null, null, null, null}, - {"1.3.3", "Document information needs", "G. Lee, S. Jones", "1", "13-Aug", null, - null, null, null, null, null, "x", null, null, null, null, null}, - }; - - public static void main(String[] args) throws Exception { - Workbook wb; - - if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook(); - else wb = new XSSFWorkbook(); - - Map styles = createStyles(wb); - - Sheet sheet = wb.createSheet("Business Plan"); - - //turn off gridlines - sheet.setDisplayGridlines(false); - sheet.setPrintGridlines(false); - sheet.setFitToPage(true); - sheet.setHorizontallyCenter(true); - PrintSetup printSetup = sheet.getPrintSetup(); - printSetup.setLandscape(true); - - //the following three statements are required only for HSSF - sheet.setAutobreaks(true); - printSetup.setFitHeight((short)1); - printSetup.setFitWidth((short)1); - - //the header row: centered text in 48pt font - Row headerRow = sheet.createRow(0); - headerRow.setHeightInPoints(12.75f); - for (int i = 0; i < titles.length; i++) { - Cell cell = headerRow.createCell(i); - cell.setCellValue(titles[i]); - cell.setCellStyle(styles.get("header")); - } - //columns for 11 weeks starting from 9-Jul - Calendar calendar = Calendar.getInstance(); - int year = calendar.get(Calendar.YEAR); - - calendar.setTime(fmt.parse("9-Jul")); - calendar.set(Calendar.YEAR, year); - for (int i = 0; i < 11; i++) { - Cell cell = headerRow.createCell(titles.length + i); - cell.setCellValue(calendar); - cell.setCellStyle(styles.get("header_date")); - calendar.roll(Calendar.WEEK_OF_YEAR, true); - } - //freeze the first row - sheet.createFreezePane(0, 1); - - Row row; - Cell cell; - int rownum = 1; - for (int i = 0; i < data.length; i++, rownum++) { - row = sheet.createRow(rownum); - if(data[i] == null) continue; - - for (int j = 0; j < data[i].length; j++) { - cell = row.createCell(j); - String styleName; - boolean isHeader = i == 0 || data[i-1] == null; - switch(j){ - case 0: - if(isHeader) { - styleName = "cell_b"; - cell.setCellValue(Double.parseDouble(data[i][j])); - } else { - styleName = "cell_normal"; - cell.setCellValue(data[i][j]); - } - break; - case 1: - if(isHeader) { - styleName = i == 0 ? "cell_h" : "cell_bb"; - } else { - styleName = "cell_indented"; - } - cell.setCellValue(data[i][j]); - break; - case 2: - styleName = isHeader ? "cell_b" : "cell_normal"; - cell.setCellValue(data[i][j]); - break; - case 3: - styleName = isHeader ? "cell_b_centered" : "cell_normal_centered"; - cell.setCellValue(Integer.parseInt(data[i][j])); - break; - case 4: { - calendar.setTime(fmt.parse(data[i][j])); - calendar.set(Calendar.YEAR, year); - cell.setCellValue(calendar); - styleName = isHeader ? "cell_b_date" : "cell_normal_date"; - break; - } - case 5: { - int r = rownum + 1; - String fmla = "IF(AND(D"+r+",E"+r+"),E"+r+"+D"+r+",\"\")"; - cell.setCellFormula(fmla); - styleName = isHeader ? "cell_bg" : "cell_g"; - break; - } - default: - styleName = data[i][j] != null ? "cell_blue" : "cell_normal"; - } - - cell.setCellStyle(styles.get(styleName)); - } - } - - //group rows for each phase, row numbers are 0-based - sheet.groupRow(4, 6); - sheet.groupRow(9, 13); - sheet.groupRow(16, 18); - - //set column widths, the width is measured in units of 1/256th of a character width - sheet.setColumnWidth(0, 256*6); - sheet.setColumnWidth(1, 256*33); - sheet.setColumnWidth(2, 256*20); - sheet.setZoom(75); //75% scale - - - // Write the output to a file - String file = "businessplan.xls"; - if(wb instanceof XSSFWorkbook) file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - - wb.close(); - } - - /** - * create a library of cell styles - */ - private static Map createStyles(Workbook wb){ - Map styles = new HashMap(); - DataFormat df = wb.createDataFormat(); - - CellStyle style; - Font headerFont = wb.createFont(); - headerFont.setBold(true); - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setFont(headerFont); - styles.put("header", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setFont(headerFont); - style.setDataFormat(df.getFormat("d-mmm")); - styles.put("header_date", style); - - Font font1 = wb.createFont(); - font1.setBold(true); - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.LEFT); - style.setFont(font1); - styles.put("cell_b", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.CENTER); - style.setFont(font1); - styles.put("cell_b_centered", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(font1); - style.setDataFormat(df.getFormat("d-mmm")); - styles.put("cell_b_date", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(font1); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setDataFormat(df.getFormat("d-mmm")); - styles.put("cell_g", style); - - Font font2 = wb.createFont(); - font2.setColor(IndexedColors.BLUE.getIndex()); - font2.setBold(true); - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.LEFT); - style.setFont(font2); - styles.put("cell_bb", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(font1); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setDataFormat(df.getFormat("d-mmm")); - styles.put("cell_bg", style); - - Font font3 = wb.createFont(); - font3.setFontHeightInPoints((short)14); - font3.setColor(IndexedColors.DARK_BLUE.getIndex()); - font3.setBold(true); - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.LEFT); - style.setFont(font3); - style.setWrapText(true); - styles.put("cell_h", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.LEFT); - style.setWrapText(true); - styles.put("cell_normal", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.CENTER); - style.setWrapText(true); - styles.put("cell_normal_centered", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setWrapText(true); - style.setDataFormat(df.getFormat("d-mmm")); - styles.put("cell_normal_date", style); - - style = createBorderedStyle(wb); - style.setAlignment(HorizontalAlignment.LEFT); - style.setIndention((short)1); - style.setWrapText(true); - styles.put("cell_indented", style); - - style = createBorderedStyle(wb); - style.setFillForegroundColor(IndexedColors.BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - styles.put("cell_blue", style); - - return styles; - } - - private static CellStyle createBorderedStyle(Workbook wb){ - BorderStyle thin = BorderStyle.THIN; - short black = IndexedColors.BLACK.getIndex(); - - CellStyle style = wb.createCellStyle(); - style.setBorderRight(thin); - style.setRightBorderColor(black); - style.setBorderBottom(thin); - style.setBottomBorderColor(black); - style.setBorderLeft(thin); - style.setLeftBorderColor(black); - style.setBorderTop(thin); - style.setTopBorderColor(black); - return style; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/CalendarDemo.java b/trunk/src/examples/src/org/apache/poi/ss/examples/CalendarDemo.java deleted file mode 100644 index 4438f22c1..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/CalendarDemo.java +++ /dev/null @@ -1,245 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples; - -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import java.io.FileOutputStream; -import java.util.Calendar; -import java.util.Map; -import java.util.HashMap; - -/** - * A monthly calendar created using Apache POI. Each month is on a separate sheet. - *
    - * Usage:
    - * CalendarDemo -xls|xlsx 
    - * 
    - * - * @author Yegor Kozlov - */ -public class CalendarDemo { - - private static final String[] days = { - "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", "Saturday"}; - - private static final String[] months = { - "January", "February", "March","April", "May", "June","July", "August", - "September","October", "November", "December"}; - - public static void main(String[] args) throws Exception { - - Calendar calendar = Calendar.getInstance(); - boolean xlsx = true; - for (int i = 0; i < args.length; i++) { - if(args[i].charAt(0) == '-'){ - xlsx = args[i].equals("-xlsx"); - } else { - calendar.set(Calendar.YEAR, Integer.parseInt(args[i])); - } - } - int year = calendar.get(Calendar.YEAR); - - Workbook wb = xlsx ? new XSSFWorkbook() : new HSSFWorkbook(); - - Map styles = createStyles(wb); - - for (int month = 0; month < 12; month++) { - calendar.set(Calendar.MONTH, month); - calendar.set(Calendar.DAY_OF_MONTH, 1); - //create a sheet for each month - Sheet sheet = wb.createSheet(months[month]); - - //turn off gridlines - sheet.setDisplayGridlines(false); - sheet.setPrintGridlines(false); - sheet.setFitToPage(true); - sheet.setHorizontallyCenter(true); - PrintSetup printSetup = sheet.getPrintSetup(); - printSetup.setLandscape(true); - - //the following three statements are required only for HSSF - sheet.setAutobreaks(true); - printSetup.setFitHeight((short)1); - printSetup.setFitWidth((short)1); - - //the header row: centered text in 48pt font - Row headerRow = sheet.createRow(0); - headerRow.setHeightInPoints(80); - Cell titleCell = headerRow.createCell(0); - titleCell.setCellValue(months[month] + " " + year); - titleCell.setCellStyle(styles.get("title")); - sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$N$1")); - - //header with month titles - Row monthRow = sheet.createRow(1); - for (int i = 0; i < days.length; i++) { - //set column widths, the width is measured in units of 1/256th of a character width - sheet.setColumnWidth(i*2, 5*256); //the column is 5 characters wide - sheet.setColumnWidth(i*2 + 1, 13*256); //the column is 13 characters wide - sheet.addMergedRegion(new CellRangeAddress(1, 1, i*2, i*2+1)); - Cell monthCell = monthRow.createCell(i*2); - monthCell.setCellValue(days[i]); - monthCell.setCellStyle(styles.get("month")); - } - - int cnt = 1, day=1; - int rownum = 2; - for (int j = 0; j < 6; j++) { - Row row = sheet.createRow(rownum++); - row.setHeightInPoints(100); - for (int i = 0; i < days.length; i++) { - Cell dayCell_1 = row.createCell(i*2); - Cell dayCell_2 = row.createCell(i*2 + 1); - - int day_of_week = calendar.get(Calendar.DAY_OF_WEEK); - if(cnt >= day_of_week && calendar.get(Calendar.MONTH) == month) { - dayCell_1.setCellValue(day); - calendar.set(Calendar.DAY_OF_MONTH, ++day); - - if(i == 0 || i == days.length-1) { - dayCell_1.setCellStyle(styles.get("weekend_left")); - dayCell_2.setCellStyle(styles.get("weekend_right")); - } else { - dayCell_1.setCellStyle(styles.get("workday_left")); - dayCell_2.setCellStyle(styles.get("workday_right")); - } - } else { - dayCell_1.setCellStyle(styles.get("grey_left")); - dayCell_2.setCellStyle(styles.get("grey_right")); - } - cnt++; - } - if(calendar.get(Calendar.MONTH) > month) break; - } - } - - // Write the output to a file - String file = "calendar.xls"; - if(wb instanceof XSSFWorkbook) file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - - wb.close(); - } - - /** - * cell styles used for formatting calendar sheets - */ - private static Map createStyles(Workbook wb){ - Map styles = new HashMap(); - - short borderColor = IndexedColors.GREY_50_PERCENT.getIndex(); - - CellStyle style; - Font titleFont = wb.createFont(); - titleFont.setFontHeightInPoints((short)48); - titleFont.setColor(IndexedColors.DARK_BLUE.getIndex()); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFont(titleFont); - styles.put("title", style); - - Font monthFont = wb.createFont(); - monthFont.setFontHeightInPoints((short)12); - monthFont.setColor(IndexedColors.WHITE.getIndex()); - monthFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.DARK_BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setFont(monthFont); - styles.put("month", style); - - Font dayFont = wb.createFont(); - dayFont.setFontHeightInPoints((short)14); - dayFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.LEFT); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderLeft(BorderStyle.THIN); - style.setLeftBorderColor(borderColor); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(borderColor); - style.setFont(dayFont); - styles.put("weekend_left", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(borderColor); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(borderColor); - styles.put("weekend_right", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.LEFT); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setBorderLeft(BorderStyle.THIN); - style.setFillForegroundColor(IndexedColors.WHITE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setLeftBorderColor(borderColor); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(borderColor); - style.setFont(dayFont); - styles.put("workday_left", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setFillForegroundColor(IndexedColors.WHITE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(borderColor); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(borderColor); - styles.put("workday_right", style); - - style = wb.createCellStyle(); - style.setBorderLeft(BorderStyle.THIN); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(borderColor); - styles.put("grey_left", style); - - style = wb.createCellStyle(); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(borderColor); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(borderColor); - styles.put("grey_right", style); - - return styles; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/CellStyleDetails.java b/trunk/src/examples/src/org/apache/poi/ss/examples/CellStyleDetails.java deleted file mode 100644 index 7bf8c55e8..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/CellStyleDetails.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples; - -import java.io.File; - -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.xssf.usermodel.XSSFFont; - -/** - * Demonstrates how to read excel styles for cells - */ -public class CellStyleDetails { - public static void main(String[] args) throws Exception { - if(args.length == 0) { - throw new IllegalArgumentException("Filename must be given"); - } - - Workbook wb = WorkbookFactory.create(new File(args[0])); - DataFormatter formatter = new DataFormatter(); - - for(int sn=0; sn - * Partly based on the code snippets from - * http://www.contextures.com/xlcondformat03.html - *

    - */ -public class ConditionalFormats { - - public static void main(String[] args) throws IOException { - Workbook wb; - - if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook(); - else wb = new XSSFWorkbook(); - - sameCell(wb.createSheet("Same Cell")); - multiCell(wb.createSheet("MultiCell")); - overlapping(wb.createSheet("Overlapping")); - errors(wb.createSheet("Errors")); - hideDupplicates(wb.createSheet("Hide Dups")); - formatDuplicates(wb.createSheet("Duplicates")); - inList(wb.createSheet("In List")); - expiry(wb.createSheet("Expiry")); - shadeAlt(wb.createSheet("Shade Alt")); - shadeBands(wb.createSheet("Shade Bands")); - iconSets(wb.createSheet("Icon Sets")); - colourScales(wb.createSheet("Colour Scales")); - dataBars(wb.createSheet("Data Bars")); - - // Write the output to a file - String file = "cf-poi.xls"; - if(wb instanceof XSSFWorkbook) file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - System.out.println("Generated: " + file); - } - - /** - * Highlight cells based on their values - */ - static void sameCell(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue(84); - sheet.createRow(1).createCell(0).setCellValue(74); - sheet.createRow(2).createCell(0).setCellValue(50); - sheet.createRow(3).createCell(0).setCellValue(51); - sheet.createRow(4).createCell(0).setCellValue(49); - sheet.createRow(5).createCell(0).setCellValue(41); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Cell Value Is greater than 70 (Blue Fill) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.GT, "70"); - PatternFormatting fill1 = rule1.createPatternFormatting(); - fill1.setFillBackgroundColor(IndexedColors.BLUE.index); - fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - // Condition 2: Cell Value Is less than 50 (Green Fill) - ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.LT, "50"); - PatternFormatting fill2 = rule2.createPatternFormatting(); - fill2.setFillBackgroundColor(IndexedColors.GREEN.index); - fill2.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A1:A6") - }; - - sheetCF.addConditionalFormatting(regions, rule1, rule2); - - sheet.getRow(0).createCell(2).setCellValue("<== Condition 1: Cell Value Is greater than 70 (Blue Fill)"); - sheet.getRow(4).createCell(2).setCellValue("<== Condition 2: Cell Value Is less than 50 (Green Fill)"); - } - - /** - * Highlight multiple cells based on a formula - */ - static void multiCell(Sheet sheet) { - // header row - Row row0 = sheet.createRow(0); - row0.createCell(0).setCellValue("Units"); - row0.createCell(1).setCellValue("Cost"); - row0.createCell(2).setCellValue("Total"); - - Row row1 = sheet.createRow(1); - row1.createCell(0).setCellValue(71); - row1.createCell(1).setCellValue(29); - row1.createCell(2).setCellValue(2059); - - Row row2 = sheet.createRow(2); - row2.createCell(0).setCellValue(85); - row2.createCell(1).setCellValue(29); - row2.createCell(2).setCellValue(2059); - - Row row3 = sheet.createRow(3); - row3.createCell(0).setCellValue(71); - row3.createCell(1).setCellValue(29); - row3.createCell(2).setCellValue(2059); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =$B2>75 (Blue Fill) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("$A2>75"); - PatternFormatting fill1 = rule1.createPatternFormatting(); - fill1.setFillBackgroundColor(IndexedColors.BLUE.index); - fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A2:C4") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.getRow(2).createCell(4).setCellValue("<== Condition 1: Formula Is =$B2>75 (Blue Fill)"); - } - - /** - * Multiple conditional formatting rules can apply to - * one cell, some combining, some beating others. - * Done in order of the rules added to the - * SheetConditionalFormatting object - */ - static void overlapping(Sheet sheet) { - for (int i=0; i<40; i++) { - int rn = i+1; - Row r = sheet.createRow(i); - r.createCell(0).setCellValue("This is row " + rn + " (" + i + ")"); - String str = ""; - if (rn%2 == 0) str = str + "even "; - if (rn%3 == 0) str = str + "x3 "; - if (rn%5 == 0) str = str + "x5 "; - if (rn%10 == 0) str = str + "x10 "; - if (str.length() == 0) str = "nothing special..."; - r.createCell(1).setCellValue("It is " + str); - } - sheet.autoSizeColumn(0); - sheet.autoSizeColumn(1); - - sheet.getRow(1).createCell(3).setCellValue("Even rows are blue"); - sheet.getRow(2).createCell(3).setCellValue("Multiples of 3 have a grey background"); - sheet.getRow(4).createCell(3).setCellValue("Multiples of 5 are bold"); - sheet.getRow(9).createCell(3).setCellValue("Multiples of 10 are red (beats even)"); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Row divides by 10, red (will beat #1) - ConditionalFormattingRule rule1 = - sheetCF.createConditionalFormattingRule("MOD(ROW(),10)=0"); - FontFormatting font1 = rule1.createFontFormatting(); - font1.setFontColorIndex(IndexedColors.RED.index); - - // Condition 2: Row is even, blue - ConditionalFormattingRule rule2 = - sheetCF.createConditionalFormattingRule("MOD(ROW(),2)=0"); - FontFormatting font2 = rule2.createFontFormatting(); - font2.setFontColorIndex(IndexedColors.BLUE.index); - - // Condition 3: Row divides by 5, bold - ConditionalFormattingRule rule3 = - sheetCF.createConditionalFormattingRule("MOD(ROW(),5)=0"); - FontFormatting font3 = rule3.createFontFormatting(); - font3.setFontStyle(false, true); - - // Condition 4: Row divides by 3, grey background - ConditionalFormattingRule rule4 = - sheetCF.createConditionalFormattingRule("MOD(ROW(),3)=0"); - PatternFormatting fill4 = rule4.createPatternFormatting(); - fill4.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index); - fill4.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - // Apply - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A1:F41") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - sheetCF.addConditionalFormatting(regions, rule2); - sheetCF.addConditionalFormatting(regions, rule3); - sheetCF.addConditionalFormatting(regions, rule4); - } - - /** - * Use Excel conditional formatting to check for errors, - * and change the font colour to match the cell colour. - * In this example, if formula result is #DIV/0! then it will have white font colour. - */ - static void errors(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue(84); - sheet.createRow(1).createCell(0).setCellValue(0); - sheet.createRow(2).createCell(0).setCellFormula("ROUND(A1/A2,0)"); - sheet.createRow(3).createCell(0).setCellValue(0); - sheet.createRow(4).createCell(0).setCellFormula("ROUND(A6/A4,0)"); - sheet.createRow(5).createCell(0).setCellValue(41); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =ISERROR(C2) (White Font) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("ISERROR(A1)"); - FontFormatting font = rule1.createFontFormatting(); - font.setFontColorIndex(IndexedColors.WHITE.index); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A1:A6") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.getRow(2).createCell(1).setCellValue("<== The error in this cell is hidden. Condition: Formula Is =ISERROR(C2) (White Font)"); - sheet.getRow(4).createCell(1).setCellValue("<== The error in this cell is hidden. Condition: Formula Is =ISERROR(C2) (White Font)"); - } - - /** - * Use Excel conditional formatting to hide the duplicate values, - * and make the list easier to read. In this example, when the table is sorted by Region, - * the second (and subsequent) occurences of each region name will have white font colour. - */ - static void hideDupplicates(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue("City"); - sheet.createRow(1).createCell(0).setCellValue("Boston"); - sheet.createRow(2).createCell(0).setCellValue("Boston"); - sheet.createRow(3).createCell(0).setCellValue("Chicago"); - sheet.createRow(4).createCell(0).setCellValue("Chicago"); - sheet.createRow(5).createCell(0).setCellValue("New York"); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =A2=A1 (White Font) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("A2=A1"); - FontFormatting font = rule1.createFontFormatting(); - font.setFontColorIndex(IndexedColors.WHITE.index); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A2:A6") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " + - "occurences of each region name will have white font colour. " + - "Condition: Formula Is =A2=A1 (White Font)"); - } - - /** - * Use Excel conditional formatting to highlight duplicate entries in a column. - */ - static void formatDuplicates(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue("Code"); - sheet.createRow(1).createCell(0).setCellValue(4); - sheet.createRow(2).createCell(0).setCellValue(3); - sheet.createRow(3).createCell(0).setCellValue(6); - sheet.createRow(4).createCell(0).setCellValue(3); - sheet.createRow(5).createCell(0).setCellValue(5); - sheet.createRow(6).createCell(0).setCellValue(8); - sheet.createRow(7).createCell(0).setCellValue(0); - sheet.createRow(8).createCell(0).setCellValue(2); - sheet.createRow(9).createCell(0).setCellValue(8); - sheet.createRow(10).createCell(0).setCellValue(6); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =A2=A1 (White Font) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($A$2:$A$11,A2)>1"); - FontFormatting font = rule1.createFontFormatting(); - font.setFontStyle(false, true); - font.setFontColorIndex(IndexedColors.BLUE.index); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A2:A11") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.getRow(2).createCell(1).setCellValue("<== Duplicates numbers in the column are highlighted. " + - "Condition: Formula Is =COUNTIF($A$2:$A$11,A2)>1 (Blue Font)"); - } - - /** - * Use Excel conditional formatting to highlight items that are in a list on the worksheet. - */ - static void inList(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue("Codes"); - sheet.createRow(1).createCell(0).setCellValue("AA"); - sheet.createRow(2).createCell(0).setCellValue("BB"); - sheet.createRow(3).createCell(0).setCellValue("GG"); - sheet.createRow(4).createCell(0).setCellValue("AA"); - sheet.createRow(5).createCell(0).setCellValue("FF"); - sheet.createRow(6).createCell(0).setCellValue("XX"); - sheet.createRow(7).createCell(0).setCellValue("CC"); - - sheet.getRow(0).createCell(2).setCellValue("Valid"); - sheet.getRow(1).createCell(2).setCellValue("AA"); - sheet.getRow(2).createCell(2).setCellValue("BB"); - sheet.getRow(3).createCell(2).setCellValue("CC"); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =A2=A1 (White Font) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($C$2:$C$4,A2)"); - PatternFormatting fill1 = rule1.createPatternFormatting(); - fill1.setFillBackgroundColor(IndexedColors.LIGHT_BLUE.index); - fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A2:A8") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.getRow(2).createCell(3).setCellValue("<== Use Excel conditional formatting to highlight items that are in a list on the worksheet"); - } - - /** - * Use Excel conditional formatting to highlight payments that are due in the next thirty days. - * In this example, Due dates are entered in cells A2:A4. - */ - static void expiry(Sheet sheet) { - CellStyle style = sheet.getWorkbook().createCellStyle(); - style.setDataFormat((short)BuiltinFormats.getBuiltinFormat("d-mmm")); - - sheet.createRow(0).createCell(0).setCellValue("Date"); - sheet.createRow(1).createCell(0).setCellFormula("TODAY()+29"); - sheet.createRow(2).createCell(0).setCellFormula("A2+1"); - sheet.createRow(3).createCell(0).setCellFormula("A3+1"); - - for(int rownum = 1; rownum <= 3; rownum++) sheet.getRow(rownum).getCell(0).setCellStyle(style); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =A2=A1 (White Font) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("AND(A2-TODAY()>=0,A2-TODAY()<=30)"); - FontFormatting font = rule1.createFontFormatting(); - font.setFontStyle(false, true); - font.setFontColorIndex(IndexedColors.BLUE.index); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A2:A4") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.getRow(0).createCell(1).setCellValue("Dates within the next 30 days are highlighted"); - } - - /** - * Use Excel conditional formatting to shade alternating rows on the worksheet - */ - static void shadeAlt(Sheet sheet) { - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - // Condition 1: Formula Is =A2=A1 (White Font) - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),2)"); - PatternFormatting fill1 = rule1.createPatternFormatting(); - fill1.setFillBackgroundColor(IndexedColors.LIGHT_GREEN.index); - fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A1:Z100") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.createRow(0).createCell(1).setCellValue("Shade Alternating Rows"); - sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is =MOD(ROW(),2) (Light Green Fill)"); - } - - /** - * You can use Excel conditional formatting to shade bands of rows on the worksheet. - * In this example, 3 rows are shaded light grey, and 3 are left with no shading. - * In the MOD function, the total number of rows in the set of banded rows (6) is entered. - */ - static void shadeBands(Sheet sheet) { - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),6)<3"); - PatternFormatting fill1 = rule1.createPatternFormatting(); - fill1.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index); - fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND); - - CellRangeAddress[] regions = { - CellRangeAddress.valueOf("A1:Z100") - }; - - sheetCF.addConditionalFormatting(regions, rule1); - - sheet.createRow(0).createCell(1).setCellValue("Shade Bands of Rows"); - sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is =MOD(ROW(),6)<2 (Light Grey Fill)"); - } - - /** - * Icon Sets / Multi-States allow you to have icons shown which vary - * based on the values, eg Red traffic light / Yellow traffic light / - * Green traffic light - */ - static void iconSets(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue("Icon Sets"); - Row r = sheet.createRow(1); - r.createCell(0).setCellValue("Reds"); - r.createCell(1).setCellValue(0); - r.createCell(2).setCellValue(0); - r.createCell(3).setCellValue(0); - r = sheet.createRow(2); - r.createCell(0).setCellValue("Yellows"); - r.createCell(1).setCellValue(5); - r.createCell(2).setCellValue(5); - r.createCell(3).setCellValue(5); - r = sheet.createRow(3); - r.createCell(0).setCellValue("Greens"); - r.createCell(1).setCellValue(10); - r.createCell(2).setCellValue(10); - r.createCell(3).setCellValue(10); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") }; - ConditionalFormattingRule rule1 = - sheetCF.createConditionalFormattingRule(IconSet.GYR_3_TRAFFIC_LIGHTS); - IconMultiStateFormatting im1 = rule1.getMultiStateFormatting(); - im1.getThresholds()[0].setRangeType(RangeType.MIN); - im1.getThresholds()[1].setRangeType(RangeType.PERCENT); - im1.getThresholds()[1].setValue(33d); - im1.getThresholds()[2].setRangeType(RangeType.MAX); - sheetCF.addConditionalFormatting(regions, rule1); - - regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C1:C4") }; - ConditionalFormattingRule rule2 = - sheetCF.createConditionalFormattingRule(IconSet.GYR_3_FLAGS); - IconMultiStateFormatting im2 = rule1.getMultiStateFormatting(); - im2.getThresholds()[0].setRangeType(RangeType.PERCENT); - im2.getThresholds()[0].setValue(0d); - im2.getThresholds()[1].setRangeType(RangeType.PERCENT); - im2.getThresholds()[1].setValue(33d); - im2.getThresholds()[2].setRangeType(RangeType.PERCENT); - im2.getThresholds()[2].setValue(67d); - sheetCF.addConditionalFormatting(regions, rule2); - - regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D1:D4") }; - ConditionalFormattingRule rule3 = - sheetCF.createConditionalFormattingRule(IconSet.GYR_3_SYMBOLS_CIRCLE); - IconMultiStateFormatting im3 = rule1.getMultiStateFormatting(); - im3.setIconOnly(true); - im3.getThresholds()[0].setRangeType(RangeType.MIN); - im3.getThresholds()[1].setRangeType(RangeType.NUMBER); - im3.getThresholds()[1].setValue(3d); - im3.getThresholds()[2].setRangeType(RangeType.NUMBER); - im3.getThresholds()[2].setValue(7d); - sheetCF.addConditionalFormatting(regions, rule3); - } - - /** - * Color Scales / Colour Scales / Colour Gradients allow you shade the - * background colour of the cell based on the values, eg from Red to - * Yellow to Green. - */ - static void colourScales(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue("Colour Scales"); - Row r = sheet.createRow(1); - r.createCell(0).setCellValue("Red-Yellow-Green"); - for (int i=1; i<=7; i++) { - r.createCell(i).setCellValue((i-1)*5); - } - r = sheet.createRow(2); - r.createCell(0).setCellValue("Red-White-Blue"); - for (int i=1; i<=9; i++) { - r.createCell(i).setCellValue((i-1)*5); - } - r = sheet.createRow(3); - r.createCell(0).setCellValue("Blue-Green"); - for (int i=1; i<=16; i++) { - r.createCell(i).setCellValue((i-1)); - } - sheet.setColumnWidth(0, 5000); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:H2") }; - ConditionalFormattingRule rule1 = - sheetCF.createConditionalFormattingColorScaleRule(); - ColorScaleFormatting cs1 = rule1.getColorScaleFormatting(); - cs1.getThresholds()[0].setRangeType(RangeType.MIN); - cs1.getThresholds()[1].setRangeType(RangeType.PERCENTILE); - cs1.getThresholds()[1].setValue(50d); - cs1.getThresholds()[2].setRangeType(RangeType.MAX); - ((ExtendedColor)cs1.getColors()[0]).setARGBHex("FFF8696B"); - ((ExtendedColor)cs1.getColors()[1]).setARGBHex("FFFFEB84"); - ((ExtendedColor)cs1.getColors()[2]).setARGBHex("FF63BE7B"); - sheetCF.addConditionalFormatting(regions, rule1); - - regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B3:J3") }; - ConditionalFormattingRule rule2 = - sheetCF.createConditionalFormattingColorScaleRule(); - ColorScaleFormatting cs2 = rule2.getColorScaleFormatting(); - cs2.getThresholds()[0].setRangeType(RangeType.MIN); - cs2.getThresholds()[1].setRangeType(RangeType.PERCENTILE); - cs2.getThresholds()[1].setValue(50d); - cs2.getThresholds()[2].setRangeType(RangeType.MAX); - ((ExtendedColor)cs2.getColors()[0]).setARGBHex("FFF8696B"); - ((ExtendedColor)cs2.getColors()[1]).setARGBHex("FFFCFCFF"); - ((ExtendedColor)cs2.getColors()[2]).setARGBHex("FF5A8AC6"); - sheetCF.addConditionalFormatting(regions, rule2); - - regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B4:Q4") }; - ConditionalFormattingRule rule3= - sheetCF.createConditionalFormattingColorScaleRule(); - ColorScaleFormatting cs3 = rule3.getColorScaleFormatting(); - cs3.setNumControlPoints(2); - cs3.getThresholds()[0].setRangeType(RangeType.MIN); - cs3.getThresholds()[1].setRangeType(RangeType.MAX); - ((ExtendedColor)cs3.getColors()[0]).setARGBHex("FF5A8AC6"); - ((ExtendedColor)cs3.getColors()[1]).setARGBHex("FF63BE7B"); - sheetCF.addConditionalFormatting(regions, rule3); - } - - /** - * DataBars / Data-Bars allow you to have bars shown vary - * based on the values, from full to empty - */ - static void dataBars(Sheet sheet) { - sheet.createRow(0).createCell(0).setCellValue("Data Bars"); - Row r = sheet.createRow(1); - r.createCell(1).setCellValue("Green Positive"); - r.createCell(2).setCellValue("Blue Mix"); - r.createCell(3).setCellValue("Red Negative"); - r = sheet.createRow(2); - r.createCell(1).setCellValue(0); - r.createCell(2).setCellValue(0); - r.createCell(3).setCellValue(0); - r = sheet.createRow(3); - r.createCell(1).setCellValue(5); - r.createCell(2).setCellValue(-5); - r.createCell(3).setCellValue(-5); - r = sheet.createRow(4); - r.createCell(1).setCellValue(10); - r.createCell(2).setCellValue(10); - r.createCell(3).setCellValue(-10); - r = sheet.createRow(5); - r.createCell(1).setCellValue(5); - r.createCell(2).setCellValue(5); - r.createCell(3).setCellValue(-5); - r = sheet.createRow(6); - r.createCell(1).setCellValue(20); - r.createCell(2).setCellValue(-10); - r.createCell(3).setCellValue(-20); - sheet.setColumnWidth(0, 3000); - sheet.setColumnWidth(1, 5000); - sheet.setColumnWidth(2, 5000); - sheet.setColumnWidth(3, 5000); - - SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - - ExtendedColor color = sheet.getWorkbook().getCreationHelper().createExtendedColor(); - color.setARGBHex("FF63BE7B"); - CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:B7") }; - ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(color); - DataBarFormatting db1 = rule1.getDataBarFormatting(); - db1.getMinThreshold().setRangeType(RangeType.MIN); - db1.getMaxThreshold().setRangeType(RangeType.MAX); - sheetCF.addConditionalFormatting(regions, rule1); - - color = sheet.getWorkbook().getCreationHelper().createExtendedColor(); - color.setARGBHex("FF5A8AC6"); - regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C2:C7") }; - ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(color); - DataBarFormatting db2 = rule2.getDataBarFormatting(); - db2.getMinThreshold().setRangeType(RangeType.MIN); - db2.getMaxThreshold().setRangeType(RangeType.MAX); - sheetCF.addConditionalFormatting(regions, rule2); - - color = sheet.getWorkbook().getCreationHelper().createExtendedColor(); - color.setARGBHex("FFF8696B"); - regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D2:D7") }; - ConditionalFormattingRule rule3 = sheetCF.createConditionalFormattingRule(color); - DataBarFormatting db3 = rule3.getDataBarFormatting(); - db3.getMinThreshold().setRangeType(RangeType.MIN); - db3.getMaxThreshold().setRangeType(RangeType.MAX); - sheetCF.addConditionalFormatting(regions, rule3); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java b/trunk/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java deleted file mode 100644 index 105e73df7..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.BorderExtent; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.PropertyTemplate; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Excel Border Drawing - examples - * - *

    - * Partly based on the code snippets from - * org.apache.poi.ss.examples.ConditionalFormats - *

    - */ -public class DrawingBorders { - - public static void main(String[] args) throws IOException { - Workbook wb; - - if (args.length > 0 && args[0].equals("-xls")) { - wb = new HSSFWorkbook(); - } else { - wb = new XSSFWorkbook(); - } - - // add a sheet, and put some values into it - Sheet sh1 = wb.createSheet("Sheet1"); - Row r = sh1.createRow(0); - Cell c = r.createCell(1); - c.setCellValue("All Borders Medium Width"); - r = sh1.createRow(4); - c = r.createCell(1); - c.setCellValue("Medium Outside / Thin Inside Borders"); - r = sh1.createRow(8); - c = r.createCell(1); - c.setCellValue("Colored Borders"); - - // draw borders (three 3x3 grids) - PropertyTemplate pt = new PropertyTemplate(); - // #1) these borders will all be medium in default color - pt.drawBorders(new CellRangeAddress(1, 3, 1, 3), - BorderStyle.MEDIUM, BorderExtent.ALL); - // #2) these cells will have medium outside borders and thin inside borders - pt.drawBorders(new CellRangeAddress(5, 7, 1, 3), - BorderStyle.MEDIUM, BorderExtent.OUTSIDE); - pt.drawBorders(new CellRangeAddress(5, 7, 1, 3), BorderStyle.THIN, - BorderExtent.INSIDE); - // #3) these cells will all be medium weight with different colors for the - // outside, inside horizontal, and inside vertical borders. The center - // cell will have no borders. - pt.drawBorders(new CellRangeAddress(9, 11, 1, 3), - BorderStyle.MEDIUM, IndexedColors.RED.getIndex(), - BorderExtent.OUTSIDE); - pt.drawBorders(new CellRangeAddress(9, 11, 1, 3), - BorderStyle.MEDIUM, IndexedColors.BLUE.getIndex(), - BorderExtent.INSIDE_VERTICAL); - pt.drawBorders(new CellRangeAddress(9, 11, 1, 3), - BorderStyle.MEDIUM, IndexedColors.GREEN.getIndex(), - BorderExtent.INSIDE_HORIZONTAL); - pt.drawBorders(new CellRangeAddress(10, 10, 2, 2), - BorderStyle.NONE, - BorderExtent.ALL); - - // apply borders to sheet - pt.applyBorders(sh1); - - // add another sheet and apply the borders to it - Sheet sh2 = wb.createSheet("Sheet2"); - pt.applyBorders(sh2); - - // Write the output to a file - String file = "db-poi.xls"; - if (wb instanceof XSSFWorkbook) - file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - wb.close(); - System.out.println("Generated: " + file); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java b/trunk/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java deleted file mode 100644 index 5ed404e2d..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java +++ /dev/null @@ -1,614 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples; - -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFColor; - -/** - * Utility to compare Excel File Contents cell by cell for all sheets. - * - *

    This utility will be used to compare Excel File Contents cell by cell for all sheets programmatically.

    - * - *

    Below are the list of Attribute comparison supported in this version.

    - * - *
      - *
    • Cell Alignment
    • - *
    • Cell Border Attributes
    • - *
    • Cell Data
    • - *
    • Cell Data-Type
    • - *
    • Cell Fill Color
    • - *
    • Cell Fill pattern
    • - *
    • Cell Font Attributes
    • - *
    • Cell Font Family
    • - *
    • Cell Font Size
    • - *
    • Cell Protection
    • - *
    • Name of the sheets
    • - *
    • Number of Columns
    • - *
    • Number of Rows
    • - *
    • Number of Sheet
    • - *
    - * - *

    (Some of the above attribute comparison only work for *.xlsx format currently. In future it can be enhanced.)

    - * - *

    Usage:

    - * - *
    - * {@code
    - *  Workbook wb1 = WorkbookFactory.create(new File("workBook1.xls"));
    - *  Workbook wb2 = WorkbookFactory.create(new File("workBook2.xls"));
    - *  List listOfDifferences = ExcelComparator.compare(wb1, wb2);
    - *  for (String differences : listOfDifferences)
    - *      System.out.println(differences);
    - *  System.out.println("DifferenceFound = "+ excelFileDifference.isDifferenceFound);
    - *  }
    - * 
    - */ -public class ExcelComparator { - - private static final String CELL_DATA_DOES_NOT_MATCH = "Cell Data does not Match ::"; - private static final String CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH = "Cell Font Attributes does not Match ::"; - - private static class Locator { - Workbook workbook; - Sheet sheet; - Row row; - Cell cell; - } - - List listOfDifferences = new ArrayList(); - - public static void main(String args[]) throws Exception { - if (args.length != 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) { - System.err.println("java -cp "+ExcelComparator.class.getCanonicalName()+" compare(Workbook wb1, Workbook wb2) { - Locator loc1 = new Locator(); - Locator loc2 = new Locator(); - loc1.workbook = wb1; - loc2.workbook = wb2; - - ExcelComparator excelComparator = new ExcelComparator(); - excelComparator.compareNumberOfSheets(loc1, loc2 ); - excelComparator.compareSheetNames(loc1, loc2); - excelComparator.compareSheetData(loc1, loc2); - - return excelComparator.listOfDifferences; - } - - /** - * Compare data in all sheets. - * - * @param workbook1 the workbook1 - * @param workbook2 the workbook2 - * @param listOfDifferences the list of differences - * @throws ExcelCompareException the excel compare exception - */ - private void compareDataInAllSheets(Locator loc1, Locator loc2) { - for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) { - if (loc2.workbook.getNumberOfSheets() <= i) return; - - loc1.sheet = loc1.workbook.getSheetAt(i); - loc2.sheet = loc2.workbook.getSheetAt(i); - - compareDataInSheet(loc1, loc2); - } - } - - private void compareDataInSheet(Locator loc1, Locator loc2) { - for (int j = 0; j < loc1.sheet.getPhysicalNumberOfRows(); j++) { - if (loc2.sheet.getPhysicalNumberOfRows() <= j) return; - - loc1.row = loc1.sheet.getRow(j); - loc2.row = loc2.sheet.getRow(j); - - if ((loc1.row == null) || (loc2.row == null)) { - continue; - } - - compareDataInRow(loc1, loc2); - } - } - - private void compareDataInRow(Locator loc1, Locator loc2) { - for (int k = 0; k < loc1.row.getLastCellNum(); k++) { - if (loc2.row.getPhysicalNumberOfCells() <= k) return; - - loc1.cell = loc1.row.getCell(k); - loc2.cell = loc2.row.getCell(k); - - if ((loc1.cell == null) || (loc2.cell == null)) { - continue; - } - - compareDataInCell(loc1, loc2); - } - } - - private void compareDataInCell(Locator loc1, Locator loc2) { - if (isCellTypeMatches(loc1, loc2)) { - final CellType loc1cellType = loc1.cell.getCellTypeEnum(); - switch(loc1cellType) { - case BLANK: - case STRING: - case ERROR: - isCellContentMatches(loc1,loc2); - break; - case BOOLEAN: - isCellContentMatchesForBoolean(loc1,loc2); - break; - case FORMULA: - isCellContentMatchesForFormula(loc1,loc2); - break; - case NUMERIC: - if (DateUtil.isCellDateFormatted(loc1.cell)) { - isCellContentMatchesForDate(loc1,loc2); - } else { - isCellContentMatchesForNumeric(loc1,loc2); - } - break; - default: - throw new IllegalStateException("Unexpected cell type: " + loc1cellType); - } - } - - isCellFillPatternMatches(loc1,loc2); - isCellAlignmentMatches(loc1,loc2); - isCellHiddenMatches(loc1,loc2); - isCellLockedMatches(loc1,loc2); - isCellFontFamilyMatches(loc1,loc2); - isCellFontSizeMatches(loc1,loc2); - isCellFontBoldMatches(loc1,loc2); - isCellUnderLineMatches(loc1,loc2); - isCellFontItalicsMatches(loc1,loc2); - isCellBorderMatches(loc1,loc2,'t'); - isCellBorderMatches(loc1,loc2,'l'); - isCellBorderMatches(loc1,loc2,'b'); - isCellBorderMatches(loc1,loc2,'r'); - isCellFillBackGroundMatches(loc1,loc2); - } - - /** - * Compare number of columns in sheets. - */ - private void compareNumberOfColumnsInSheets(Locator loc1, Locator loc2) { - for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) { - if (loc2.workbook.getNumberOfSheets() <= i) return; - - loc1.sheet = loc1.workbook.getSheetAt(i); - loc2.sheet = loc2.workbook.getSheetAt(i); - - Iterator ri1 = loc1.sheet.rowIterator(); - Iterator ri2 = loc2.sheet.rowIterator(); - - int num1 = (ri1.hasNext()) ? ri1.next().getPhysicalNumberOfCells() : 0; - int num2 = (ri2.hasNext()) ? ri2.next().getPhysicalNumberOfCells() : 0; - - if (num1 != num2) { - String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]", - "Number Of Columns does not Match ::", - loc1.sheet.getSheetName(), num1, - loc2.sheet.getSheetName(), num2 - ); - listOfDifferences.add(str); - } - } - } - - /** - * Compare number of rows in sheets. - */ - private void compareNumberOfRowsInSheets(Locator loc1, Locator loc2) { - for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) { - if (loc2.workbook.getNumberOfSheets() <= i) return; - - loc1.sheet = loc1.workbook.getSheetAt(i); - loc2.sheet = loc2.workbook.getSheetAt(i); - - int num1 = loc1.sheet.getPhysicalNumberOfRows(); - int num2 = loc2.sheet.getPhysicalNumberOfRows(); - - if (num1 != num2) { - String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]", - "Number Of Rows does not Match ::", - loc1.sheet.getSheetName(), num1, - loc2.sheet.getSheetName(), num2 - ); - listOfDifferences.add(str); - } - } - - } - - /** - * Compare number of sheets. - */ - private void compareNumberOfSheets(Locator loc1, Locator loc2) { - int num1 = loc1.workbook.getNumberOfSheets(); - int num2 = loc2.workbook.getNumberOfSheets(); - if (num1 != num2) { - String str = String.format(Locale.ROOT, "%s\nworkbook1 [%d] != workbook2 [%d]", - "Number of Sheets do not match ::", - num1, num2 - ); - - listOfDifferences.add(str); - - } - } - - /** - * Compare sheet data. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param listOfDifferences - * - * @throws ExcelCompareException - * the excel compare exception - */ - private void compareSheetData(Locator loc1, Locator loc2) { - compareNumberOfRowsInSheets(loc1, loc2); - compareNumberOfColumnsInSheets(loc1, loc2); - compareDataInAllSheets(loc1, loc2); - - } - - /** - * Compare sheet names. - */ - private void compareSheetNames(Locator loc1, Locator loc2) { - for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) { - String name1 = loc1.workbook.getSheetName(i); - String name2 = (loc2.workbook.getNumberOfSheets() > i) ? loc2.workbook.getSheetName(i) : ""; - - if (!name1.equals(name2)) { - String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]", - "Name of the sheets do not match ::", name1, i+1, name2, i+1 - ); - listOfDifferences.add(str); - } - } - } - - /** - * Formats the message. - */ - private void addMessage(Locator loc1, Locator loc2, String messageStart, String value1, String value2) { - String str = - String.format(Locale.ROOT, "%s\nworkbook1 -> %s -> %s [%s] != workbook2 -> %s -> %s [%s]", - messageStart, - loc1.sheet.getSheetName(), new CellReference(loc1.cell).formatAsString(), value1, - loc2.sheet.getSheetName(), new CellReference(loc2.cell).formatAsString(), value2 - ); - listOfDifferences.add(str); - } - - /** - * Checks if cell alignment matches. - */ - private void isCellAlignmentMatches(Locator loc1, Locator loc2) { - // TODO: check for NPE - short align1 = loc1.cell.getCellStyle().getAlignment(); - short align2 = loc2.cell.getCellStyle().getAlignment(); - if (align1 != align2) { - addMessage(loc1, loc2, - "Cell Alignment does not Match ::", - Short.toString(align1), - Short.toString(align2) - ); - } - } - - /** - * Checks if cell border bottom matches. - */ - private void isCellBorderMatches(Locator loc1, Locator loc2, char borderSide) { - if (!(loc1.cell instanceof XSSFCell)) return; - XSSFCellStyle style1 = ((XSSFCell)loc1.cell).getCellStyle(); - XSSFCellStyle style2 = ((XSSFCell)loc2.cell).getCellStyle(); - boolean b1, b2; - String borderName; - switch (borderSide) { - case 't': default: - b1 = style1.getBorderTopEnum() == BorderStyle.THIN; - b2 = style2.getBorderTopEnum() == BorderStyle.THIN; - borderName = "TOP"; - break; - case 'b': - b1 = style1.getBorderBottomEnum() == BorderStyle.THIN; - b2 = style2.getBorderBottomEnum() == BorderStyle.THIN; - borderName = "BOTTOM"; - break; - case 'l': - b1 = style1.getBorderLeftEnum() == BorderStyle.THIN; - b2 = style2.getBorderLeftEnum() == BorderStyle.THIN; - borderName = "LEFT"; - break; - case 'r': - b1 = style1.getBorderRightEnum() == BorderStyle.THIN; - b2 = style2.getBorderRightEnum() == BorderStyle.THIN; - borderName = "RIGHT"; - break; - } - if (b1 != b2) { - addMessage(loc1, loc2, - "Cell Border Attributes does not Match ::", - (b1 ? "" : "NOT ")+borderName+" BORDER", - (b2 ? "" : "NOT ")+borderName+" BORDER" - ); - } - } - - /** - * Checks if cell content matches. - */ - private void isCellContentMatches(Locator loc1, Locator loc2) { - // TODO: check for null and non-rich-text cells - String str1 = loc1.cell.getRichStringCellValue().getString(); - String str2 = loc2.cell.getRichStringCellValue().getString(); - if (!str1.equals(str2)) { - addMessage(loc1,loc2,CELL_DATA_DOES_NOT_MATCH,str1,str2); - } - } - - /** - * Checks if cell content matches for boolean. - */ - private void isCellContentMatchesForBoolean(Locator loc1, Locator loc2) { - boolean b1 = loc1.cell.getBooleanCellValue(); - boolean b2 = loc2.cell.getBooleanCellValue(); - if (b1 != b2) { - addMessage(loc1,loc2,CELL_DATA_DOES_NOT_MATCH,Boolean.toString(b1),Boolean.toString(b2)); - } - } - - /** - * Checks if cell content matches for date. - */ - private void isCellContentMatchesForDate(Locator loc1, Locator loc2) { - Date date1 = loc1.cell.getDateCellValue(); - Date date2 = loc2.cell.getDateCellValue(); - if (!date1.equals(date2)) { - addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, date1.toGMTString(), date2.toGMTString()); - } - } - - - /** - * Checks if cell content matches for formula. - */ - private void isCellContentMatchesForFormula(Locator loc1, Locator loc2) { - // TODO: actually evaluate the formula / NPE checks - String form1 = loc1.cell.getCellFormula(); - String form2 = loc2.cell.getCellFormula(); - if (!form1.equals(form2)) { - addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, form1, form2); - } - } - - /** - * Checks if cell content matches for numeric. - */ - private void isCellContentMatchesForNumeric(Locator loc1, Locator loc2) { - // TODO: Check for NaN - double num1 = loc1.cell.getNumericCellValue(); - double num2 = loc2.cell.getNumericCellValue(); - if (num1 != num2) { - addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, Double.toString(num1), Double.toString(num2)); - } - } - - private String getCellFillBackground(Locator loc) { - Color col = loc.cell.getCellStyle().getFillForegroundColorColor(); - return (col instanceof XSSFColor) ? ((XSSFColor)col).getARGBHex() : "NO COLOR"; - } - - /** - * Checks if cell file back ground matches. - */ - private void isCellFillBackGroundMatches(Locator loc1, Locator loc2) { - String col1 = getCellFillBackground(loc1); - String col2 = getCellFillBackground(loc2); - if (!col1.equals(col2)) { - addMessage(loc1, loc2, "Cell Fill Color does not Match ::", col1, col2); - } - } - /** - * Checks if cell fill pattern matches. - */ - private void isCellFillPatternMatches(Locator loc1, Locator loc2) { - // TOOO: Check for NPE - short fill1 = loc1.cell.getCellStyle().getFillPattern(); - short fill2 = loc2.cell.getCellStyle().getFillPattern(); - if (fill1 != fill2) { - addMessage(loc1, loc2, - "Cell Fill pattern does not Match ::", - Short.toString(fill1), - Short.toString(fill2) - ); - } - } - - /** - * Checks if cell font bold matches. - */ - private void isCellFontBoldMatches(Locator loc1, Locator loc2) { - if (!(loc1.cell instanceof XSSFCell)) return; - boolean b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getBold(); - boolean b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getBold(); - if (b1 != b2) { - addMessage(loc1, loc2, - CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH, - (b1 ? "" : "NOT ")+"BOLD", - (b2 ? "" : "NOT ")+"BOLD" - ); - } - } - - /** - * Checks if cell font family matches. - */ - private void isCellFontFamilyMatches(Locator loc1, Locator loc2) { - // TODO: Check for NPEs - if (!(loc1.cell instanceof XSSFCell)) return; - String family1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getFontName(); - String family2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getFontName(); - if (!family1.equals(family2)) { - addMessage(loc1, loc2, "Cell Font Family does not Match ::", family1, family2); - } - } - - /** - * Checks if cell font italics matches. - */ - private void isCellFontItalicsMatches(Locator loc1, Locator loc2) { - if (!(loc1.cell instanceof XSSFCell)) return; - boolean b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getItalic(); - boolean b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getItalic(); - if (b1 != b2) { - addMessage(loc1, loc2, - CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH, - (b1 ? "" : "NOT ")+"ITALICS", - (b2 ? "" : "NOT ")+"ITALICS" - ); - } - } - - /** - * Checks if cell font size matches. - */ - private void isCellFontSizeMatches(Locator loc1, Locator loc2) { - if (!(loc1.cell instanceof XSSFCell)) return; - short size1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getFontHeightInPoints(); - short size2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getFontHeightInPoints(); - if (size1 != size2) { - addMessage(loc1, loc2, - "Cell Font Size does not Match ::", - Short.toString(size1), - Short.toString(size2) - ); - } - } - - /** - * Checks if cell hidden matches. - */ - private void isCellHiddenMatches(Locator loc1, Locator loc2) { - boolean b1 = loc1.cell.getCellStyle().getHidden(); - boolean b2 = loc1.cell.getCellStyle().getHidden(); - if (b1 != b2) { - addMessage(loc1, loc2, - "Cell Visibility does not Match ::", - (b1 ? "" : "NOT ")+"HIDDEN", - (b2 ? "" : "NOT ")+"HIDDEN" - ); - } - } - - /** - * Checks if cell locked matches. - */ - private void isCellLockedMatches(Locator loc1, Locator loc2) { - boolean b1 = loc1.cell.getCellStyle().getLocked(); - boolean b2 = loc1.cell.getCellStyle().getLocked(); - if (b1 != b2) { - addMessage(loc1, loc2, - "Cell Protection does not Match ::", - (b1 ? "" : "NOT ")+"LOCKED", - (b2 ? "" : "NOT ")+"LOCKED" - ); - } - } - - /** - * Checks if cell type matches. - */ - private boolean isCellTypeMatches(Locator loc1, Locator loc2) { - CellType type1 = loc1.cell.getCellTypeEnum(); - CellType type2 = loc2.cell.getCellTypeEnum(); - if (type1 == type2) return true; - addMessage(loc1, loc2, - "Cell Data-Type does not Match in :: ", - type1.name(), type2.name() - ); - return false; - } - - /** - * Checks if cell under line matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell under line matches - */ - private void isCellUnderLineMatches(Locator loc1, Locator loc2) { - // TOOO: distinguish underline type - if (!(loc1.cell instanceof XSSFCell)) return; - byte b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getUnderline(); - byte b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getUnderline(); - if (b1 != b2) { - addMessage(loc1, loc2, - CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH, - (b1 == 1 ? "" : "NOT ")+"UNDERLINE", - (b2 == 1 ? "" : "NOT ")+"UNDERLINE" - ); - } - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/LinkedDropDownLists.java b/trunk/src/examples/src/org/apache/poi/ss/examples/LinkedDropDownLists.java deleted file mode 100644 index b0efc4f0c..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/LinkedDropDownLists.java +++ /dev/null @@ -1,228 +0,0 @@ - /* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== */ - -package org.apache.poi.ss.examples; -import java.io.*; -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddressList; - -/** - * Demonstrates one technique that may be used to create linked or dependent - * drop down lists. This refers to a situation in which the selection made - * in one drop down list affects the options that are displayed in the second - * or subsequent drop down list(s). In this example, the value the user selects - * from the down list in cell A1 will affect the values displayed in the linked - * drop down list in cell B1. For the sake of simplicity, the data for the drop - * down lists is included on the same worksheet but this does not have to be the - * case; the data could appear on a separate sheet. If this were done, then the - * names for the regions would have to be different, they would have to include - * the name of the sheet. - * - * There are two keys to this technique. The first is the use of named area or - * regions of cells to hold the data for the drop down lists and the second is - * making use of the INDIRECT() function to convert a name into the addresses - * of the cells it refers to. - * - * Note that whilst this class builds just two linked drop down lists, there is - * nothing to prevent more being created. Quite simply, use the value selected - * by the user in one drop down list to determine what is shown in another and the - * value selected in that drop down list to determine what is shown in a third, - * and so on. Also, note that the data for the drop down lists is contained on - * contained on the same sheet as the validations themselves. This is done simply - * for simplicity and there is nothing to prevent a separate sheet being created - * and used to hold the data. If this is done then problems may be encountered - * if the sheet is opened with OpenOffice Calc. To prevent these problems, it is - * better to include the name of the sheet when calling the setRefersToFormula() - * method. - * - * @author Mark Beardsley [msb at apache.org] - * @version 1.00 30th March 2012 - */ -public class LinkedDropDownLists { - - LinkedDropDownLists(String workbookName) { - File file = null; - FileOutputStream fos = null; - Workbook workbook = null; - Sheet sheet = null; - DataValidationHelper dvHelper = null; - DataValidationConstraint dvConstraint = null; - DataValidation validation = null; - CellRangeAddressList addressList = null; - try { - - // Using the ss.usermodel allows this class to support both binary - // and xml based workbooks. The choice of which one to create is - // made by checking the file extension. - if (workbookName.endsWith(".xlsx")) { - workbook = new XSSFWorkbook(); - } else { - workbook = new HSSFWorkbook(); - } - - // Build the sheet that will hold the data for the validations. This - // must be done first as it will create names that are referenced - // later. - sheet = workbook.createSheet("Linked Validations"); - LinkedDropDownLists.buildDataSheet(sheet); - - // Build the first data validation to occupy cell A1. Note - // that it retrieves it's data from the named area or region called - // CHOICES. Further information about this can be found in the - // static buildDataSheet() method below. - addressList = new CellRangeAddressList(0, 0, 0, 0); - dvHelper = sheet.getDataValidationHelper(); - dvConstraint = dvHelper.createFormulaListConstraint("CHOICES"); - validation = dvHelper.createValidation(dvConstraint, addressList); - sheet.addValidationData(validation); - - // Now, build the linked or dependent drop down list that will - // occupy cell B1. The key to the whole process is the use of the - // INDIRECT() function. In the buildDataSheet(0 method, a series of - // named regions are created and the names of three of them mirror - // the options available to the user in the first drop down list - // (in cell A1). Using the INDIRECT() function makes it possible - // to convert the selection the user makes in that first drop down - // into the addresses of a named region of cells and then to use - // those cells to populate the second drop down list. - addressList = new CellRangeAddressList(0, 0, 1, 1); - dvConstraint = dvHelper.createFormulaListConstraint( - "INDIRECT(UPPER($A$1))"); - validation = dvHelper.createValidation(dvConstraint, addressList); - sheet.addValidationData(validation); - - file = new File(workbookName); - fos = new FileOutputStream(file); - workbook.write(fos); - } catch (IOException ioEx) { - System.out.println("Caught a: " + ioEx.getClass().getName()); - System.out.println("Message: " + ioEx.getMessage()); - System.out.println("Stacktrace follws:....."); - ioEx.printStackTrace(System.out); - } finally { - try { - if (fos != null) { - fos.close(); - fos = null; - } - } catch (IOException ioEx) { - System.out.println("Caught a: " + ioEx.getClass().getName()); - System.out.println("Message: " + ioEx.getMessage()); - System.out.println("Stacktrace follws:....."); - ioEx.printStackTrace(System.out); - } - } - } - - /** - * Called to populate the named areas/regions. The contents of the cells on - * row one will be used to populate the first drop down list. The contents of - * the cells on rows two, three and four will be used to populate the second - * drop down list, just which row will be determined by the choice the user - * makes in the first drop down list. - * - * In all cases, the approach is to create a row, create and populate cells - * with data and then specify a name that identifies those cells. With the - * exception of the first range, the names that are chosen for each range - * of cells are quite important. In short, each of the options the user - * could select in the first drop down list is used as the name for another - * range of cells. Thus, in this example, the user can select either - * 'Animal', 'Vegetable' or 'Mineral' in the first drop down and so the - * sheet contains ranges named 'ANIMAL', 'VEGETABLE' and 'MINERAL'. - * - * @param dataSheet An instance of a class that implements the Sheet Sheet - * interface (HSSFSheet or XSSFSheet). - */ - private static final void buildDataSheet(Sheet dataSheet) { - Row row = null; - Cell cell = null; - Name name = null; - - // The first row will hold the data for the first validation. - row = dataSheet.createRow(10); - cell = row.createCell(0); - cell.setCellValue("Animal"); - cell = row.createCell(1); - cell.setCellValue("Vegetable"); - cell = row.createCell(2); - cell.setCellValue("Mineral"); - name = dataSheet.getWorkbook().createName(); - name.setRefersToFormula("$A$11:$C$11"); - name.setNameName("CHOICES"); - - // The next three rows will hold the data that will be used to - // populate the second, or linked, drop down list. - row = dataSheet.createRow(11); - cell = row.createCell(0); - cell.setCellValue("Lion"); - cell = row.createCell(1); - cell.setCellValue("Tiger"); - cell = row.createCell(2); - cell.setCellValue("Leopard"); - cell = row.createCell(3); - cell.setCellValue("Elephant"); - cell = row.createCell(4); - cell.setCellValue("Eagle"); - cell = row.createCell(5); - cell.setCellValue("Horse"); - cell = row.createCell(6); - cell.setCellValue("Zebra"); - name = dataSheet.getWorkbook().createName(); - name.setRefersToFormula("$A$12:$G$12"); - name.setNameName("ANIMAL"); - - row = dataSheet.createRow(12); - cell = row.createCell(0); - cell.setCellValue("Cabbage"); - cell = row.createCell(1); - cell.setCellValue("Cauliflower"); - cell = row.createCell(2); - cell.setCellValue("Potato"); - cell = row.createCell(3); - cell.setCellValue("Onion"); - cell = row.createCell(4); - cell.setCellValue("Beetroot"); - cell = row.createCell(5); - cell.setCellValue("Asparagus"); - cell = row.createCell(6); - cell.setCellValue("Spinach"); - cell = row.createCell(7); - cell.setCellValue("Chard"); - name = dataSheet.getWorkbook().createName(); - name.setRefersToFormula("$A$13:$H$13"); - name.setNameName("VEGETABLE"); - - row = dataSheet.createRow(13); - cell = row.createCell(0); - cell.setCellValue("Bauxite"); - cell = row.createCell(1); - cell.setCellValue("Quartz"); - cell = row.createCell(2); - cell.setCellValue("Feldspar"); - cell = row.createCell(3); - cell.setCellValue("Shist"); - cell = row.createCell(4); - cell.setCellValue("Shale"); - cell = row.createCell(5); - cell.setCellValue("Mica"); - name = dataSheet.getWorkbook().createName(); - name.setRefersToFormula("$A$14:$F$14"); - name.setNameName("MINERAL"); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/LoadEmbedded.java b/trunk/src/examples/src/org/apache/poi/ss/examples/LoadEmbedded.java deleted file mode 100644 index 66ca8ba7b..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/LoadEmbedded.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples; - -import java.io.File; -import java.io.InputStream; - -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hssf.usermodel.HSSFObjectData; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hwpf.HWPFDocument; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xwpf.usermodel.XWPFDocument; - -/** - * Loads embedded resources from Workbooks. Code taken from the website: - * https://poi.apache.org/spreadsheet/quick-guide.html#Embedded - */ -public class LoadEmbedded { - public static void main(String[] args) throws Exception { - Workbook wb = WorkbookFactory.create(new File(args[0])); - loadEmbedded(wb); - } - - public static void loadEmbedded(Workbook wb) throws Exception { - if (wb instanceof HSSFWorkbook) { - loadEmbedded((HSSFWorkbook)wb); - } - else if (wb instanceof XSSFWorkbook) { - loadEmbedded((XSSFWorkbook)wb); - } - else { - throw new IllegalArgumentException(wb.getClass().getName()); - } - } - - public static void loadEmbedded(HSSFWorkbook workbook) throws Exception { - for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) { - //the OLE2 Class Name of the object - String oleName = obj.getOLE2ClassName(); - if (oleName.equals("Worksheet")) { - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(dn, false); - //System.out.println(entry.getName() + ": " + embeddedWorkbook.getNumberOfSheets()); - } else if (oleName.equals("Document")) { - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - HWPFDocument embeddedWordDocument = new HWPFDocument(dn); - //System.out.println(entry.getName() + ": " + embeddedWordDocument.getRange().text()); - } else if (oleName.equals("Presentation")) { - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - SlideShow embeddedPowerPointDocument = new HSLFSlideShow(dn); - //System.out.println(entry.getName() + ": " + embeddedPowerPointDocument.getSlides().length); - } else { - if(obj.hasDirectoryEntry()){ - // The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is - DirectoryNode dn = (DirectoryNode) obj.getDirectory(); - for (Entry entry : dn) { - //System.out.println(oleName + "." + entry.getName()); - } - } else { - // There is no DirectoryEntry - // Recover the object's data from the HSSFObjectData instance. - byte[] objectData = obj.getObjectData(); - } - } - } - } - - public static void loadEmbedded(XSSFWorkbook workbook) throws Exception { - for (PackagePart pPart : workbook.getAllEmbedds()) { - String contentType = pPart.getContentType(); - // Excel Workbook - either binary or OpenXML - if (contentType.equals("application/vnd.ms-excel")) { - HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(pPart.getInputStream()); - } - // Excel Workbook - OpenXML file format - else if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) { - OPCPackage docPackage = OPCPackage.open(pPart.getInputStream()); - XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(docPackage); - } - // Word Document - binary (OLE2CDF) file format - else if (contentType.equals("application/msword")) { - HWPFDocument document = new HWPFDocument(pPart.getInputStream()); - } - // Word Document - OpenXML file format - else if (contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) { - OPCPackage docPackage = OPCPackage.open(pPart.getInputStream()); - XWPFDocument document = new XWPFDocument(docPackage); - } - // PowerPoint Document - binary file format - else if (contentType.equals("application/vnd.ms-powerpoint")) { - HSLFSlideShow slideShow = new HSLFSlideShow(pPart.getInputStream()); - } - // PowerPoint Document - OpenXML file format - else if (contentType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")) { - OPCPackage docPackage = OPCPackage.open(pPart.getInputStream()); - XSLFSlideShow slideShow = new XSLFSlideShow(docPackage); - } - // Any other type of embedded object. - else { - System.out.println("Unknown Embedded Document: " + contentType); - InputStream inputStream = pPart.getInputStream(); - } - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/LoanCalculator.java b/trunk/src/examples/src/org/apache/poi/ss/examples/LoanCalculator.java deleted file mode 100644 index d6375dc43..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/LoanCalculator.java +++ /dev/null @@ -1,305 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples; - -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import java.util.Map; -import java.util.HashMap; -import java.io.FileOutputStream; - -/** - * Simple Loan Calculator. Demonstrates advance usage of cell formulas and named ranges. - * - * Usage: - * LoanCalculator -xls|xlsx - * - * @author Yegor Kozlov - */ -public class LoanCalculator { - - public static void main(String[] args) throws Exception { - Workbook wb; - - if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook(); - else wb = new XSSFWorkbook(); - - Map styles = createStyles(wb); - Sheet sheet = wb.createSheet("Loan Calculator"); - sheet.setPrintGridlines(false); - sheet.setDisplayGridlines(false); - - PrintSetup printSetup = sheet.getPrintSetup(); - printSetup.setLandscape(true); - sheet.setFitToPage(true); - sheet.setHorizontallyCenter(true); - - sheet.setColumnWidth(0, 3*256); - sheet.setColumnWidth(1, 3*256); - sheet.setColumnWidth(2, 11*256); - sheet.setColumnWidth(3, 14*256); - sheet.setColumnWidth(4, 14*256); - sheet.setColumnWidth(5, 14*256); - sheet.setColumnWidth(6, 14*256); - - createNames(wb); - - Row titleRow = sheet.createRow(0); - titleRow.setHeightInPoints(35); - for (int i = 1; i <= 7; i++) { - titleRow.createCell(i).setCellStyle(styles.get("title")); - } - Cell titleCell = titleRow.getCell(2); - titleCell.setCellValue("Simple Loan Calculator"); - sheet.addMergedRegion(CellRangeAddress.valueOf("$C$1:$H$1")); - - Row row = sheet.createRow(2); - Cell cell = row.createCell(4); - cell.setCellValue("Enter values"); - cell.setCellStyle(styles.get("item_right")); - - row = sheet.createRow(3); - cell = row.createCell(2); - cell.setCellValue("Loan amount"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellStyle(styles.get("input_$")); - cell.setAsActiveCell(); - - row = sheet.createRow(4); - cell = row.createCell(2); - cell.setCellValue("Annual interest rate"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellStyle(styles.get("input_%")); - - row = sheet.createRow(5); - cell = row.createCell(2); - cell.setCellValue("Loan period in years"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellStyle(styles.get("input_i")); - - row = sheet.createRow(6); - cell = row.createCell(2); - cell.setCellValue("Start date of loan"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellStyle(styles.get("input_d")); - - row = sheet.createRow(8); - cell = row.createCell(2); - cell.setCellValue("Monthly payment"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellFormula("IF(Values_Entered,Monthly_Payment,\"\")"); - cell.setCellStyle(styles.get("formula_$")); - - row = sheet.createRow(9); - cell = row.createCell(2); - cell.setCellValue("Number of payments"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellFormula("IF(Values_Entered,Loan_Years*12,\"\")"); - cell.setCellStyle(styles.get("formula_i")); - - row = sheet.createRow(10); - cell = row.createCell(2); - cell.setCellValue("Total interest"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellFormula("IF(Values_Entered,Total_Cost-Loan_Amount,\"\")"); - cell.setCellStyle(styles.get("formula_$")); - - row = sheet.createRow(11); - cell = row.createCell(2); - cell.setCellValue("Total cost of loan"); - cell.setCellStyle(styles.get("item_left")); - cell = row.createCell(4); - cell.setCellFormula("IF(Values_Entered,Monthly_Payment*Number_of_Payments,\"\")"); - cell.setCellStyle(styles.get("formula_$")); - - - // Write the output to a file - String file = "loan-calculator.xls"; - if(wb instanceof XSSFWorkbook) file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - } - - /** - * cell styles used for formatting calendar sheets - */ - private static Map createStyles(Workbook wb){ - Map styles = new HashMap(); - - CellStyle style; - Font titleFont = wb.createFont(); - titleFont.setFontHeightInPoints((short)14); - titleFont.setFontName("Trebuchet MS"); - style = wb.createCellStyle(); - style.setFont(titleFont); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - styles.put("title", style); - - Font itemFont = wb.createFont(); - itemFont.setFontHeightInPoints((short)9); - itemFont.setFontName("Trebuchet MS"); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.LEFT); - style.setFont(itemFont); - styles.put("item_left", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(itemFont); - styles.put("item_right", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(itemFont); - style.setBorderRight(BorderStyle.DOTTED); - style.setRightBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderLeft(BorderStyle.DOTTED); - style.setLeftBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderTop(BorderStyle.DOTTED); - style.setTopBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setDataFormat(wb.createDataFormat().getFormat("_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(@_)")); - styles.put("input_$", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(itemFont); - style.setBorderRight(BorderStyle.DOTTED); - style.setRightBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderLeft(BorderStyle.DOTTED); - style.setLeftBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderTop(BorderStyle.DOTTED); - style.setTopBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setDataFormat(wb.createDataFormat().getFormat("0.000%")); - styles.put("input_%", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(itemFont); - style.setBorderRight(BorderStyle.DOTTED); - style.setRightBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderLeft(BorderStyle.DOTTED); - style.setLeftBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderTop(BorderStyle.DOTTED); - style.setTopBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setDataFormat(wb.createDataFormat().getFormat("0")); - styles.put("input_i", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setFont(itemFont); - style.setDataFormat(wb.createDataFormat().getFormat("m/d/yy")); - styles.put("input_d", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(itemFont); - style.setBorderRight(BorderStyle.DOTTED); - style.setRightBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderLeft(BorderStyle.DOTTED); - style.setLeftBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderTop(BorderStyle.DOTTED); - style.setTopBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setDataFormat(wb.createDataFormat().getFormat("$##,##0.00")); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - styles.put("formula_$", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.RIGHT); - style.setFont(itemFont); - style.setBorderRight(BorderStyle.DOTTED); - style.setRightBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderLeft(BorderStyle.DOTTED); - style.setLeftBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setBorderTop(BorderStyle.DOTTED); - style.setTopBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setDataFormat(wb.createDataFormat().getFormat("0")); - style.setBorderBottom(BorderStyle.DOTTED); - style.setBottomBorderColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - styles.put("formula_i", style); - - return styles; - } - - //define named ranges for the inputs and formulas - public static void createNames(Workbook wb){ - Name name; - - name = wb.createName(); - name.setNameName("Interest_Rate"); - name.setRefersToFormula("'Loan Calculator'!$E$5"); - - name = wb.createName(); - name.setNameName("Loan_Amount"); - name.setRefersToFormula("'Loan Calculator'!$E$4"); - - name = wb.createName(); - name.setNameName("Loan_Start"); - name.setRefersToFormula("'Loan Calculator'!$E$7"); - - name = wb.createName(); - name.setNameName("Loan_Years"); - name.setRefersToFormula("'Loan Calculator'!$E$6"); - - name = wb.createName(); - name.setNameName("Number_of_Payments"); - name.setRefersToFormula("'Loan Calculator'!$E$10"); - - name = wb.createName(); - name.setNameName("Monthly_Payment"); - name.setRefersToFormula("-PMT(Interest_Rate/12,Number_of_Payments,Loan_Amount)"); - - name = wb.createName(); - name.setNameName("Total_Cost"); - name.setRefersToFormula("'Loan Calculator'!$E$12"); - - name = wb.createName(); - name.setNameName("Total_Interest"); - name.setRefersToFormula("'Loan Calculator'!$E$11"); - - name = wb.createName(); - name.setNameName("Values_Entered"); - name.setRefersToFormula("IF(Loan_Amount*Interest_Rate*Loan_Years*Loan_Start>0,1,0)"); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java b/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java deleted file mode 100644 index 10c3a4a7d..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.ss.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class SSPerformanceTest { - public static void main(String[] args) throws IOException { - if (args.length != 4) usage("need four command arguments"); - - String type = args[0]; - long timeStarted = System.currentTimeMillis(); - Workbook workBook = createWorkbook(type); - boolean isHType = workBook instanceof HSSFWorkbook; - - int rows = parseInt(args[1], "Failed to parse rows value as integer"); - int cols = parseInt(args[2], "Failed to parse cols value as integer"); - boolean saveFile = parseInt(args[3], "Failed to parse saveFile value as integer") != 0; - - addContent(workBook, isHType, rows, cols); - - if (saveFile) { - String fileName = type + "_" + rows + "_" + cols + "." + getFileSuffix(args[0]); - saveFile(workBook, fileName); - } - long timeFinished = System.currentTimeMillis(); - System.out.println("Elapsed " + (timeFinished-timeStarted)/1000 + " seconds"); - - workBook.close(); - } - - private static void addContent(Workbook workBook, boolean isHType, int rows, int cols) { - Map styles = createStyles(workBook); - - Sheet sheet = workBook.createSheet("Main Sheet"); - - Cell headerCell = sheet.createRow(0).createCell(0); - headerCell.setCellValue("Header text is spanned across multiple cells"); - headerCell.setCellStyle(styles.get("header")); - sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$F$1")); - - int sheetNo = 0; - int rowIndexInSheet = 1; - double value = 0; - Calendar calendar = Calendar.getInstance(); - for (int rowIndex = 0; rowIndex < rows; rowIndex++) { - if (isHType && sheetNo != rowIndex / 0x10000) { - sheet = workBook.createSheet("Spillover from sheet " + (++sheetNo)); - headerCell.setCellValue("Header text is spanned across multiple cells"); - headerCell.setCellStyle(styles.get("header")); - sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$F$1")); - rowIndexInSheet = 1; - } - - Row row = sheet.createRow(rowIndexInSheet); - for (int colIndex = 0; colIndex < cols; colIndex++) { - value = populateCell(styles, value, calendar, rowIndex, row, colIndex); - } - rowIndexInSheet++; - } - } - - private static double populateCell(Map styles, double value, Calendar calendar, int rowIndex, Row row, int colIndex) { - Cell cell = row.createCell(colIndex); - String address = new CellReference(cell).formatAsString(); - switch (colIndex){ - case 0: - // column A: default number format - cell.setCellValue(value++); - break; - case 1: - // column B: #,##0 - cell.setCellValue(value++); - cell.setCellStyle(styles.get("#,##0.00")); - break; - case 2: - // column C: $#,##0.00 - cell.setCellValue(value++); - cell.setCellStyle(styles.get("$#,##0.00")); - break; - case 3: - // column D: red bold text on yellow background - cell.setCellValue(address); - cell.setCellStyle(styles.get("red-bold")); - break; - case 4: - // column E: boolean - // TODO booleans are shown as 1/0 instead of TRUE/FALSE - cell.setCellValue(rowIndex % 2 == 0); - break; - case 5: - // column F: date / time - cell.setCellValue(calendar); - cell.setCellStyle(styles.get("m/d/yyyy")); - calendar.roll(Calendar.DAY_OF_YEAR, -1); - break; - case 6: - // column F: formula - // TODO formulas are not yet supported in SXSSF - //cell.setCellFormula("SUM(A" + (rowIndex+1) + ":E" + (rowIndex+1)+ ")"); - //break; - default: - cell.setCellValue(value++); - break; - } - return value; - } - - private static void saveFile(Workbook workBook, String fileName) { - try { - FileOutputStream out = new FileOutputStream(fileName); - workBook.write(out); - out.close(); - } catch (IOException ioe) { - System.err.println("Error: failed to write to file \"" + fileName + "\", reason=" + ioe.getMessage()); - } - } - - static Map createStyles(Workbook wb) { - Map styles = new HashMap(); - CellStyle style; - - Font headerFont = wb.createFont(); - headerFont.setFontHeightInPoints((short) 14); - headerFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFont(headerFont); - style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - styles.put("header", style); - - Font monthFont = wb.createFont(); - monthFont.setFontHeightInPoints((short)12); - monthFont.setColor(IndexedColors.RED.getIndex()); - monthFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.YELLOW.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setFont(monthFont); - styles.put("red-bold", style); - - String[] nfmt = {"#,##0.00", "$#,##0.00", "m/d/yyyy"}; - for(String fmt : nfmt){ - style = wb.createCellStyle(); - style.setDataFormat(wb.createDataFormat().getFormat(fmt)); - styles.put(fmt, style); - } - - return styles; - } - - - static void usage(String message) { - System.err.println(message); - System.err.println("usage: java SSPerformanceTest HSSF|XSSF|SXSSF rows cols saveFile (0|1)? "); - System.exit(1); - } - - static Workbook createWorkbook(String type) { - if ("HSSF".equals(type)) - return new HSSFWorkbook(); - else if ("XSSF".equals(type)) - return new XSSFWorkbook(); - else if ("SXSSF".equals(type)) - return new SXSSFWorkbook(); - else - usage("Unknown type \"" + type + "\""); - return null; - } - - static String getFileSuffix(String type) { - if ("HSSF".equals(type)) - return "xls"; - else if ("XSSF".equals(type)) - return "xlsx"; - else if ("SXSSF".equals(type)) - return "xlsx"; - return null; - } - - static int parseInt(String value, String msg) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - usage(msg); - } - return 0; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java b/trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java deleted file mode 100644 index 8ef20fe43..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java +++ /dev/null @@ -1,220 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples; - -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import java.util.Map; -import java.util.HashMap; -import java.io.FileOutputStream; - -/** - * A weekly timesheet created using Apache POI. - * Usage: - * TimesheetDemo -xls|xlsx - * - * @author Yegor Kozlov - */ -public class TimesheetDemo { - private static final String[] titles = { - "Person", "ID", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", - "Total\nHrs", "Overtime\nHrs", "Regular\nHrs" - }; - - private static Object[][] sample_data = { - {"Yegor Kozlov", "YK", 5.0, 8.0, 10.0, 5.0, 5.0, 7.0, 6.0}, - {"Gisella Bronzetti", "GB", 4.0, 3.0, 1.0, 3.5, null, null, 4.0}, - }; - - public static void main(String[] args) throws Exception { - Workbook wb; - - if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook(); - else wb = new XSSFWorkbook(); - - Map styles = createStyles(wb); - - Sheet sheet = wb.createSheet("Timesheet"); - PrintSetup printSetup = sheet.getPrintSetup(); - printSetup.setLandscape(true); - sheet.setFitToPage(true); - sheet.setHorizontallyCenter(true); - - //title row - Row titleRow = sheet.createRow(0); - titleRow.setHeightInPoints(45); - Cell titleCell = titleRow.createCell(0); - titleCell.setCellValue("Weekly Timesheet"); - titleCell.setCellStyle(styles.get("title")); - sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$L$1")); - - //header row - Row headerRow = sheet.createRow(1); - headerRow.setHeightInPoints(40); - Cell headerCell; - for (int i = 0; i < titles.length; i++) { - headerCell = headerRow.createCell(i); - headerCell.setCellValue(titles[i]); - headerCell.setCellStyle(styles.get("header")); - } - - int rownum = 2; - for (int i = 0; i < 10; i++) { - Row row = sheet.createRow(rownum++); - for (int j = 0; j < titles.length; j++) { - Cell cell = row.createCell(j); - if(j == 9){ - //the 10th cell contains sum over week days, e.g. SUM(C3:I3) - String ref = "C" +rownum+ ":I" + rownum; - cell.setCellFormula("SUM("+ref+")"); - cell.setCellStyle(styles.get("formula")); - } else if (j == 11){ - cell.setCellFormula("J" +rownum+ "-K" + rownum); - cell.setCellStyle(styles.get("formula")); - } else { - cell.setCellStyle(styles.get("cell")); - } - } - } - - //row with totals below - Row sumRow = sheet.createRow(rownum++); - sumRow.setHeightInPoints(35); - Cell cell; - cell = sumRow.createCell(0); - cell.setCellStyle(styles.get("formula")); - cell = sumRow.createCell(1); - cell.setCellValue("Total Hrs:"); - cell.setCellStyle(styles.get("formula")); - - for (int j = 2; j < 12; j++) { - cell = sumRow.createCell(j); - String ref = (char)('A' + j) + "3:" + (char)('A' + j) + "12"; - cell.setCellFormula("SUM(" + ref + ")"); - if(j >= 9) cell.setCellStyle(styles.get("formula_2")); - else cell.setCellStyle(styles.get("formula")); - } - rownum++; - sumRow = sheet.createRow(rownum++); - sumRow.setHeightInPoints(25); - cell = sumRow.createCell(0); - cell.setCellValue("Total Regular Hours"); - cell.setCellStyle(styles.get("formula")); - cell = sumRow.createCell(1); - cell.setCellFormula("L13"); - cell.setCellStyle(styles.get("formula_2")); - sumRow = sheet.createRow(rownum++); - sumRow.setHeightInPoints(25); - cell = sumRow.createCell(0); - cell.setCellValue("Total Overtime Hours"); - cell.setCellStyle(styles.get("formula")); - cell = sumRow.createCell(1); - cell.setCellFormula("K13"); - cell.setCellStyle(styles.get("formula_2")); - - //set sample data - for (int i = 0; i < sample_data.length; i++) { - Row row = sheet.getRow(2 + i); - for (int j = 0; j < sample_data[i].length; j++) { - if(sample_data[i][j] == null) continue; - - if(sample_data[i][j] instanceof String) { - row.getCell(j).setCellValue((String)sample_data[i][j]); - } else { - row.getCell(j).setCellValue((Double)sample_data[i][j]); - } - } - } - - //finally set column widths, the width is measured in units of 1/256th of a character width - sheet.setColumnWidth(0, 30*256); //30 characters wide - for (int i = 2; i < 9; i++) { - sheet.setColumnWidth(i, 6*256); //6 characters wide - } - sheet.setColumnWidth(10, 10*256); //10 characters wide - - // Write the output to a file - String file = "timesheet.xls"; - if(wb instanceof XSSFWorkbook) file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - } - - /** - * Create a library of cell styles - */ - private static Map createStyles(Workbook wb){ - Map styles = new HashMap(); - CellStyle style; - Font titleFont = wb.createFont(); - titleFont.setFontHeightInPoints((short)18); - titleFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFont(titleFont); - styles.put("title", style); - - Font monthFont = wb.createFont(); - monthFont.setFontHeightInPoints((short)11); - monthFont.setColor(IndexedColors.WHITE.getIndex()); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setFont(monthFont); - style.setWrapText(true); - styles.put("header", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setWrapText(true); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(IndexedColors.BLACK.getIndex()); - style.setBorderLeft(BorderStyle.THIN); - style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); - style.setBorderTop(BorderStyle.THIN); - style.setTopBorderColor(IndexedColors.BLACK.getIndex()); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); - styles.put("cell", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setDataFormat(wb.createDataFormat().getFormat("0.00")); - styles.put("formula", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex()); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setDataFormat(wb.createDataFormat().getFormat("0.00")); - styles.put("formula_2", style); - - return styles; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/ToCSV.java b/trunk/src/examples/src/org/apache/poi/ss/examples/ToCSV.java deleted file mode 100644 index b6c5ea972..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/ToCSV.java +++ /dev/null @@ -1,774 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples; - - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; - -/** - * Demonstrates one way to convert an Excel spreadsheet into a CSV - * file. This class makes the following assumptions; - * - *
  • 1. Where the Excel workbook contains more that one worksheet, then a single - * CSV file will contain the data from all of the worksheets.
  • - *
  • 2. The data matrix contained in the CSV file will be square. This means that - * the number of fields in each record of the CSV file will match the number - * of cells in the longest row found in the Excel workbook. Any short records - * will be 'padded' with empty fields - an empty field is represented in the - * the CSV file in this way - ,,.
  • - *
  • 3. Empty fields will represent missing cells.
  • - *
  • 4. A record consisting of empty fields will be used to represent an empty row - * in the Excel workbook.
  • - *
    - * Therefore, if the worksheet looked like this; - * - *
    - *  ___________________________________________
    - *     |       |       |       |       |       |
    - *     |   A   |   B   |   C   |   D   |   E   |
    - *  ___|_______|_______|_______|_______|_______|
    - *     |       |       |       |       |       |
    - *   1 |   1   |   2   |   3   |   4   |   5   |
    - *  ___|_______|_______|_______|_______|_______|
    - *     |       |       |       |       |       |
    - *   2 |       |       |       |       |       |
    - *  ___|_______|_______|_______|_______|_______|
    - *     |       |       |       |       |       |
    - *   3 |       |   A   |       |   B   |       |
    - *  ___|_______|_______|_______|_______|_______|
    - *     |       |       |       |       |       |
    - *   4 |       |       |       |       |   Z   |
    - *  ___|_______|_______|_______|_______|_______|
    - *     |       |       |       |       |       |
    - *   5 | 1,400 |       |  250  |       |       |
    - *  ___|_______|_______|_______|_______|_______|
    - *
    - * 
    - * - * Then, the resulting CSV file will contain the following lines (records); - *
    - * 1,2,3,4,5
    - * ,,,,
    - * ,A,,B,
    - * ,,,,Z
    - * "1,400",,250,,
    - * 

    - * Typically, the comma is used to separate each of the fields that, together, - * constitute a single record or line within the CSV file. This is not however - * a hard and fast rule and so this class allows the user to determine which - * character is used as the field separator and assumes the comma if none other - * is specified. - *

    - * If a field contains the separator then it will be escaped. If the file should - * obey Excel's CSV formatting rules, then the field will be surrounded with - * speech marks whilst if it should obey UNIX conventions, each occurrence of - * the separator will be preceded by the backslash character. - *

    - * If a field contains an end of line (EOL) character then it too will be - * escaped. If the file should obey Excel's CSV formatting rules then the field - * will again be surrounded by speech marks. On the other hand, if the file - * should follow UNIX conventions then a single backslash will precede the - * EOL character. There is no single applicable standard for UNIX and some - * appications replace the CR with \r and the LF with \n but this class will - * not do so. - *

    - * If the field contains double quotes then that character will be escaped. It - * seems as though UNIX does not define a standard for this whilst Excel does. - * Should the CSV file have to obey Excel's formmating rules then the speech - * mark character will be escaped with a second set of speech marks. Finally, an - * enclosing set of speah marks will also surround the entire field. Thus, if - * the following line of text appeared in a cell - "Hello" he said - it would - * look like this when converted into a field within a CSV file - """Hello"" he - * said". - *

    - * Finally, it is worth noting that talk of CSV 'standards' is really slightly - * missleading as there is no such thing. It may well be that the code in this - * class has to be modified to produce files to suit a specific application - * or requirement. - *

    - * @author Mark B - * @version 1.00 9th April 2010 - * 1.10 13th April 2010 - Added support for processing all Excel - * workbooks in a folder along with the ability - * to specify a field separator character. - * 2.00 14th April 2010 - Added support for embedded characters; the - * field separator, EOL and double quotes or - * speech marks. In addition, gave the client - * the ability to select how these are handled, - * either obeying Excel's or UNIX formatting - * conventions. - */ -public class ToCSV { - - private Workbook workbook = null; - private ArrayList> csvData = null; - private int maxRowWidth = 0; - private int formattingConvention = 0; - private DataFormatter formatter = null; - private FormulaEvaluator evaluator = null; - private String separator = null; - - private static final String CSV_FILE_EXTENSION = ".csv"; - private static final String DEFAULT_SEPARATOR = ","; - - /** - * Identifies that the CSV file should obey Excel's formatting conventions - * with regard to escaping certain embedded characters - the field separator, - * speech mark and end of line (EOL) character - */ - public static final int EXCEL_STYLE_ESCAPING = 0; - - /** - * Identifies that the CSV file should obey UNIX formatting conventions - * with regard to escaping certain embedded characters - the field separator - * and end of line (EOL) character - */ - public static final int UNIX_STYLE_ESCAPING = 1; - - /** - * Process the contents of a folder, convert the contents of each Excel - * workbook into CSV format and save the resulting file to the specified - * folder using the same name as the original workbook with the .xls or - * .xlsx extension replaced by .csv. This method will ensure that the - * CSV file created contains the comma field separator and that embedded - * characters such as the field separator, the EOL and double quotes are - * escaped in accordance with Excel's convention. - * - * @param strSource An instance of the String class that encapsulates the - * name of and path to either a folder containing those Excel - * workbook(s) or the name of and path to an individual Excel workbook - * that is/are to be converted. - * @param strDestination An instance of the String class encapsulating the - * name of and path to a folder that will contain the resulting CSV - * files. - * @throws java.io.FileNotFoundException Thrown if any file cannot be located - * on the filesystem during processing. - * @throws java.io.IOException Thrown if the filesystem encounters any - * problems during processing. - * @throws java.lang.IllegalArgumentException Thrown if the values passed - * to the strSource parameter refers to a file or folder that does not - * exist or if the value passed to the strDestination paramater refers - * to a folder that does not exist or simply does not refer to a - * folder. - * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException Thrown - * if the xml markup encountered whilst parsing a SpreadsheetML - * file (.xlsx) is invalid. - */ - public void convertExcelToCSV(String strSource, String strDestination) - throws FileNotFoundException, IOException, - IllegalArgumentException, InvalidFormatException { - - // Simply chain the call to the overloaded convertExcelToCSV(String, - // String, String, int) method, pass the default separator and ensure - // that certain embedded characters are escaped in accordance with - // Excel's formatting conventions - this.convertExcelToCSV(strSource, strDestination, - ToCSV.DEFAULT_SEPARATOR, ToCSV.EXCEL_STYLE_ESCAPING); - } - - /** - * Process the contents of a folder, convert the contents of each Excel - * workbook into CSV format and save the resulting file to the specified - * folder using the same name as the original workbook with the .xls or - * .xlsx extension replaced by .csv. This method allows the client to - * define the field separator but will ensure that embedded characters such - * as the field separator, the EOL and double quotes are escaped in - * accordance with Excel's convention. - * - * @param strSource An instance of the String class that encapsulates the - * name of and path to either a folder containing those Excel - * workbook(s) or the name of and path to an individual Excel workbook - * that is/are to be converted. - * @param strDestination An instance of the String class encapsulating the - * name of and path to a folder that will contain the resulting CSV - * files. - * @param separator An instance of the String class that encapsulates the - * character or characters the client wishes to use as the field - * separator. - * @throws java.io.FileNotFoundException Thrown if any file cannot be located - * on the filesystem during processing. - * @throws java.io.IOException Thrown if the filesystem encounters any - * problems during processing. - * @throws java.lang.IllegalArgumentException Thrown if the values passed - * to the strSource parameter refers to a file or folder that does not - * exist or if the value passed to the strDestination paramater refers - * to a folder that does not exist or simply does not refer to a - * folder. - * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException Thrown - * if the xml markup encounetered whilst parsing a SpreadsheetML - * file (.xlsx) is invalid. - */ - public void convertExcelToCSV(String strSource, String strDestination, - String separator) - throws FileNotFoundException, IOException, - IllegalArgumentException, InvalidFormatException { - - // Simply chain the call to the overloaded convertExcelToCSV(String, - // String, String, int) method and ensure that certain embedded - // characters are escaped in accordance with Excel's formatting - // conventions - this.convertExcelToCSV(strSource, strDestination, - separator, ToCSV.EXCEL_STYLE_ESCAPING); - } - - /** - * Process the contents of a folder, convert the contents of each Excel - * workbook into CSV format and save the resulting file to the specified - * folder using the same name as the original workbook with the .xls or - * .xlsx extension replaced by .csv - * - * @param strSource An instance of the String class that encapsulates the - * name of and path to either a folder containing those Excel - * workbook(s) or the name of and path to an individual Excel workbook - * that is/are to be converted. - * @param strDestination An instance of the String class encapsulating the name - * of and path to a folder that will contain the resulting CSV files. - * @param formattingConvention A primitive int whose value will determine - * whether certain embedded characters should be escaped in accordance - * with Excel's or UNIX formatting conventions. Two constants are - * defined to support this option; ToCSV.EXCEL_STYLE_ESCAPING and - * ToCSV.UNIX_STYLE_ESCAPING - * @param separator An instance of the String class encapsulating the - * characters or characters that should be used to separate items - * on a line within the CSV file. - * @throws java.io.FileNotFoundException Thrown if any file cannot be located - * on the filesystem during processing. - * @throws java.io.IOException Thrown if the filesystem encounters any - * problems during processing. - * @throws java.lang.IllegalArgumentException Thrown if the values passed - * to the strSource parameter refers to a file or folder that does not - * exist, if the value passed to the strDestination paramater refers - * to a folder that does not exist, if the value passed to the - * strDestination parameter does not refer to a folder or if the - * value passed to the formattingConvention parameter is other than - * one of the values defined by the constants ToCSV.EXCEL_STYLE_ESCAPING - * and ToCSV.UNIX_STYLE_ESCAPING. - * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException Thrown - * if the xml markup encounetered whilst parsing a SpreadsheetML - * file (.xlsx) is invalid. - */ - public void convertExcelToCSV(String strSource, String strDestination, - String separator, int formattingConvention) - throws FileNotFoundException, IOException, - IllegalArgumentException, InvalidFormatException { - File source = new File(strSource); - File destination = new File(strDestination); - File[] filesList = null; - String destinationFilename = null; - - // Check that the source file/folder exists. - if(!source.exists()) { - throw new IllegalArgumentException("The source for the Excel " + - "file(s) cannot be found."); - } - - // Ensure thaat the folder the user has chosen to save the CSV files - // away into firstly exists and secondly is a folder rather than, for - // instance, a data file. - if(!destination.exists()) { - throw new IllegalArgumentException("The folder/directory for the " + - "converted CSV file(s) does not exist."); - } - if(!destination.isDirectory()) { - throw new IllegalArgumentException("The destination for the CSV " + - "file(s) is not a directory/folder."); - } - - // Ensure the value passed to the formattingConvention parameter is - // within range. - if(formattingConvention != ToCSV.EXCEL_STYLE_ESCAPING && - formattingConvention != ToCSV.UNIX_STYLE_ESCAPING) { - throw new IllegalArgumentException("The value passed to the " + - "formattingConvention parameter is out of range."); - } - - // Copy the spearator character and formatting convention into local - // variables for use in other methods. - this.separator = separator; - this.formattingConvention = formattingConvention; - - // Check to see if the sourceFolder variable holds a reference to - // a file or a folder full of files. - if(source.isDirectory()) { - // Get a list of all of the Excel spreadsheet files (workbooks) in - // the source folder/directory - filesList = source.listFiles(new ExcelFilenameFilter()); - } - else { - // Assume that it must be a file handle - although there are other - // options the code should perhaps check - and store the reference - // into the filesList variable. - filesList = new File[]{source}; - } - - // Step through each of the files in the source folder and for each - // open the workbook, convert it's contents to CSV format and then - // save the resulting file away into the folder specified by the - // contents of the destination variable. Note that the name of the - // csv file will be created by taking the name of the Excel file, - // removing the extension and replacing it with .csv. Note that there - // is one drawback with this approach; if the folder holding the files - // contains two workbooks whose names match but one is a binary file - // (.xls) and the other a SpreadsheetML file (.xlsx), then the names - // for both CSV files will be identical and one CSV file will, - // therefore, over-write the other. - if (filesList != null) { - for(File excelFile : filesList) { - // Open the workbook - this.openWorkbook(excelFile); - - // Convert it's contents into a CSV file - this.convertToCSV(); - - // Build the name of the csv folder from that of the Excel workbook. - // Simply replace the .xls or .xlsx file extension with .csv - destinationFilename = excelFile.getName(); - destinationFilename = destinationFilename.substring( - 0, destinationFilename.lastIndexOf(".")) + - ToCSV.CSV_FILE_EXTENSION; - - // Save the CSV file away using the newly constricted file name - // and to the specified directory. - this.saveCSVFile(new File(destination, destinationFilename)); - } - } - } - - /** - * Open an Excel workbook ready for conversion. - * - * @param file An instance of the File class that encapsulates a handle - * to a valid Excel workbook. Note that the workbook can be in - * either binary (.xls) or SpreadsheetML (.xlsx) format. - * @throws java.io.FileNotFoundException Thrown if the file cannot be located. - * @throws java.io.IOException Thrown if a problem occurs in the file system. - * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException Thrown - * if invalid xml is found whilst parsing an input SpreadsheetML - * file. - */ - private void openWorkbook(File file) throws FileNotFoundException, - IOException, InvalidFormatException { - FileInputStream fis = null; - try { - System.out.println("Opening workbook [" + file.getName() + "]"); - - fis = new FileInputStream(file); - - // Open the workbook and then create the FormulaEvaluator and - // DataFormatter instances that will be needed to, respectively, - // force evaluation of forumlae found in cells and create a - // formatted String encapsulating the cells contents. - this.workbook = WorkbookFactory.create(fis); - this.evaluator = this.workbook.getCreationHelper().createFormulaEvaluator(); - this.formatter = new DataFormatter(true); - } - finally { - if(fis != null) { - fis.close(); - } - } - } - - /** - * Called to convert the contents of the currently opened workbook into - * a CSV file. - */ - private void convertToCSV() { - Sheet sheet = null; - Row row = null; - int lastRowNum = 0; - this.csvData = new ArrayList>(); - - System.out.println("Converting files contents to CSV format."); - - // Discover how many sheets there are in the workbook.... - int numSheets = this.workbook.getNumberOfSheets(); - - // and then iterate through them. - for(int i = 0; i < numSheets; i++) { - - // Get a reference to a sheet and check to see if it contains - // any rows. - sheet = this.workbook.getSheetAt(i); - if(sheet.getPhysicalNumberOfRows() > 0) { - - // Note down the index number of the bottom-most row and - // then iterate through all of the rows on the sheet starting - // from the very first row - number 1 - even if it is missing. - // Recover a reference to the row and then call another method - // which will strip the data from the cells and build lines - // for inclusion in the resylting CSV file. - lastRowNum = sheet.getLastRowNum(); - for(int j = 0; j <= lastRowNum; j++) { - row = sheet.getRow(j); - this.rowToCSV(row); - } - } - } - } - - /** - * Called to actually save the data recovered from the Excel workbook - * as a CSV file. - * - * @param file An instance of the File class that encapsulates a handle - * referring to the CSV file. - * @throws java.io.FileNotFoundException Thrown if the file cannot be found. - * @throws java.io.IOException Thrown to indicate and error occurred in the - * underylying file system. - */ - private void saveCSVFile(File file) - throws FileNotFoundException, IOException { - FileWriter fw = null; - BufferedWriter bw = null; - ArrayList line = null; - StringBuffer buffer = null; - String csvLineElement = null; - try { - - System.out.println("Saving the CSV file [" + file.getName() + "]"); - - // Open a writer onto the CSV file. - fw = new FileWriter(file); - bw = new BufferedWriter(fw); - - // Step through the elements of the ArrayList that was used to hold - // all of the data recovered from the Excel workbooks' sheets, rows - // and cells. - for(int i = 0; i < this.csvData.size(); i++) { - buffer = new StringBuffer(); - - // Get an element from the ArrayList that contains the data for - // the workbook. This element will itself be an ArrayList - // containing Strings and each String will hold the data recovered - // from a single cell. The for() loop is used to recover elements - // from this 'row' ArrayList one at a time and to write the Strings - // away to a StringBuffer thus assembling a single line for inclusion - // in the CSV file. If a row was empty or if it was short, then - // the ArrayList that contains it's data will also be shorter than - // some of the others. Therefore, it is necessary to check within - // the for loop to ensure that the ArrayList contains data to be - // processed. If it does, then an element will be recovered and - // appended to the StringBuffer. - line = this.csvData.get(i); - for(int j = 0; j < this.maxRowWidth; j++) { - if(line.size() > j) { - csvLineElement = line.get(j); - if(csvLineElement != null) { - buffer.append(this.escapeEmbeddedCharacters( - csvLineElement)); - } - } - if(j < (this.maxRowWidth - 1)) { - buffer.append(this.separator); - } - } - - // Once the line is built, write it away to the CSV file. - bw.write(buffer.toString().trim()); - - // Condition the inclusion of new line characters so as to - // avoid an additional, superfluous, new line at the end of - // the file. - if(i < (this.csvData.size() - 1)) { - bw.newLine(); - } - } - } - finally { - if(bw != null) { - bw.flush(); - bw.close(); - } - } - } - - /** - * Called to convert a row of cells into a line of data that can later be - * output to the CSV file. - * - * @param row An instance of either the HSSFRow or XSSFRow classes that - * encapsulates information about a row of cells recovered from - * an Excel workbook. - */ - private void rowToCSV(Row row) { - Cell cell = null; - int lastCellNum = 0; - ArrayList csvLine = new ArrayList(); - - // Check to ensure that a row was recovered from the sheet as it is - // possible that one or more rows between other populated rows could be - // missing - blank. If the row does contain cells then... - if(row != null) { - - // Get the index for the right most cell on the row and then - // step along the row from left to right recovering the contents - // of each cell, converting that into a formatted String and - // then storing the String into the csvLine ArrayList. - lastCellNum = row.getLastCellNum(); - for(int i = 0; i <= lastCellNum; i++) { - cell = row.getCell(i); - if(cell == null) { - csvLine.add(""); - } - else { - if(cell.getCellTypeEnum() != CellType.FORMULA) { - csvLine.add(this.formatter.formatCellValue(cell)); - } - else { - csvLine.add(this.formatter.formatCellValue(cell, this.evaluator)); - } - } - } - // Make a note of the index number of the right most cell. This value - // will later be used to ensure that the matrix of data in the CSV file - // is square. - if(lastCellNum > this.maxRowWidth) { - this.maxRowWidth = lastCellNum; - } - } - this.csvData.add(csvLine); - } - - /** - * Checks to see whether the field - which consists of the formatted - * contents of an Excel worksheet cell encapsulated within a String - contains - * any embedded characters that must be escaped. The method is able to - * comply with either Excel's or UNIX formatting conventions in the - * following manner; - * - * With regard to UNIX conventions, if the field contains any embedded - * field separator or EOL characters they will each be escaped by prefixing - * a leading backspace character. These are the only changes that have yet - * emerged following some research as being required. - * - * Excel has other embedded character escaping requirements, some that emerged - * from empirical testing, other through research. Firstly, with regards to - * any embedded speech marks ("), each occurrence should be escaped with - * another speech mark and the whole field then surrounded with speech marks. - * Thus if a field holds "Hello" he said then it should be modified - * to appear as """Hello"" he said". Furthermore, if the field - * contains either embedded separator or EOL characters, it should also - * be surrounded with speech marks. As a result 1,400 would become - * "1,400" assuming that the comma is the required field separator. - * This has one consequence in, if a field contains embedded speech marks - * and embedded separator characters, checks for both are not required as the - * additional set of speech marks that should be placed around ay field - * containing embedded speech marks will also account for the embedded - * separator. - * - * It is worth making one further note with regard to embedded EOL - * characters. If the data in a worksheet is exported as a CSV file using - * Excel itself, then the field will be surounded with speech marks. If the - * resulting CSV file is then re-imports into another worksheet, the EOL - * character will result in the original simgle field occupying more than - * one cell. This same 'feature' is replicated in this classes behaviour. - * - * @param field An instance of the String class encapsulating the formatted - * contents of a cell on an Excel worksheet. - * @return A String that encapsulates the formatted contents of that - * Excel worksheet cell but with any embedded separator, EOL or - * speech mark characters correctly escaped. - */ - private String escapeEmbeddedCharacters(String field) { - StringBuffer buffer = null; - - // If the fields contents should be formatted to confrom with Excel's - // convention.... - if(this.formattingConvention == ToCSV.EXCEL_STYLE_ESCAPING) { - - // Firstly, check if there are any speech marks (") in the field; - // each occurrence must be escaped with another set of spech marks - // and then the entire field should be enclosed within another - // set of speech marks. Thus, "Yes" he said would become - // """Yes"" he said" - if(field.contains("\"")) { - buffer = new StringBuffer(field.replaceAll("\"", "\\\"\\\"")); - buffer.insert(0, "\""); - buffer.append("\""); - } - else { - // If the field contains either embedded separator or EOL - // characters, then escape the whole field by surrounding it - // with speech marks. - buffer = new StringBuffer(field); - if((buffer.indexOf(this.separator)) > -1 || - (buffer.indexOf("\n")) > -1) { - buffer.insert(0, "\""); - buffer.append("\""); - } - } - return(buffer.toString().trim()); - } - // The only other formatting convention this class obeys is the UNIX one - // where any occurrence of the field separator or EOL character will - // be escaped by preceding it with a backslash. - else { - if(field.contains(this.separator)) { - field = field.replaceAll(this.separator, ("\\\\" + this.separator)); - } - if(field.contains("\n")) { - field = field.replaceAll("\n", "\\\\\n"); - } - return(field); - } - } - - /** - * The main() method contains code that demonstrates how to use the class. - * - * @param args An array containing zero, one or more elements all of type - * String. Each element will encapsulate an argument specified by the - * user when running the program from the command prompt. - */ - public static void main(String[] args) { - // Check the number of arguments passed to the main method. There - // must be two, three or four; the name of and path to either the folder - // containing the Excel files or an individual Excel workbook that is/are - // to be converted, the name of and path to the folder to which the CSV - // files should be written, - optionally - the separator character - // that should be used to separate individual items (fields) on the - // lines (records) of the CSV file and - again optionally - an integer - // that idicates whether the CSV file ought to obey Excel's or UNIX - // convnetions with regard to formatting fields that contain embedded - // separator, Speech mark or EOL character(s). - // - // Note that the names of the CSV files will be derived from those - // of the Excel file(s). Put simply the .xls or .xlsx extension will be - // replaced with .csv. Therefore, if the source folder contains files - // with matching names but different extensions - Test.xls and Test.xlsx - // for example - then the CSV file generated from one will overwrite - // that generated from the other. - ToCSV converter = null; - boolean converted = true; - long startTime = System.currentTimeMillis(); - try { - converter = new ToCSV(); - if(args.length == 2) { - // Just the Source File/Folder and Destination Folder were - // passed to the main method. - converter.convertExcelToCSV(args[0], args[1]); - } - else if(args.length == 3){ - // The Source File/Folder, Destination Folder and Separator - // were passed to the main method. - converter.convertExcelToCSV(args[0], args[1], args[2]); - } - else if(args.length == 4) { - // The Source File/Folder, Destination Folder, Separator and - // Formatting Convnetion were passed to the main method. - converter.convertExcelToCSV(args[0], args[1], - args[2], Integer.parseInt(args[3])); - } - else { - // None or more than four parameters were passed so display - //a Usage message. - System.out.println("Usage: java ToCSV [Source File/Folder] " + - "[Destination Folder] [Separator] [Formatting Convention]\n" + - "\tSource File/Folder\tThis argument should contain the name of and\n" + - "\t\t\t\tpath to either a single Excel workbook or a\n" + - "\t\t\t\tfolder containing one or more Excel workbooks.\n" + - "\tDestination Folder\tThe name of and path to the folder that the\n" + - "\t\t\t\tCSV files should be written out into. The\n" + - "\t\t\t\tfolder must exist before running the ToCSV\n" + - "\t\t\t\tcode as it will not check for or create it.\n" + - "\tSeparator\t\tOptional. The character or characters that\n" + - "\t\t\t\tshould be used to separate fields in the CSV\n" + - "\t\t\t\trecord. If no value is passed then the comma\n" + - "\t\t\t\twill be assumed.\n" + - "\tFormatting Convention\tOptional. This argument can take one of two\n" + - "\t\t\t\tvalues. Passing 0 (zero) will result in a CSV\n" + - "\t\t\t\tfile that obeys Excel's formatting conventions\n" + - "\t\t\t\twhilst passing 1 (one) will result in a file\n" + - "\t\t\t\tthat obeys UNIX formatting conventions. If no\n" + - "\t\t\t\tvalue is passed, then the CSV file produced\n" + - "\t\t\t\twill obey Excel's formatting conventions."); - converted = false; - } - } - // It is not wise to have such a wide catch clause - Exception is very - // close to being at the top of the inheritance hierarchy - though it - // will suffice for this example as it is really not possible to recover - // easilly from an exceptional set of circumstances at this point in the - // program. It should however, ideally be replaced with one or more - // catch clauses optimised to handle more specific problems. - catch(Exception ex) { - System.out.println("Caught an: " + ex.getClass().getName()); - System.out.println("Message: " + ex.getMessage()); - System.out.println("Stacktrace follows:....."); - ex.printStackTrace(System.out); - converted = false; - } - - if (converted) { - System.out.println("Conversion took " + - (int)((System.currentTimeMillis() - startTime)/1000) + " seconds"); - } - } - - /** - * An instance of this class can be used to control the files returned - * be a call to the listFiles() method when made on an instance of the - * File class and that object refers to a folder/directory - */ - class ExcelFilenameFilter implements FilenameFilter { - - /** - * Determine those files that will be returned by a call to the - * listFiles() method. In this case, the name of the file must end with - * either of the following two extension; '.xls' or '.xlsx'. For the - * future, it is very possible to parameterise this and allow the - * containing class to pass, for example, an array of Strings to this - * class on instantiation. Each element in that array could encapsulate - * a valid file extension - '.xls', '.xlsx', '.xlt', '.xlst', etc. These - * could then be used to control which files were returned by the call - * to the listFiles() method. - * - * @param file An instance of the File class that encapsulates a handle - * referring to the folder/directory that contains the file. - * @param name An instance of the String class that encapsulates the - * name of the file. - * @return A boolean value that indicates whether the file should be - * included in the array retirned by the call to the listFiles() - * method. In this case true will be returned if the name of the - * file ends with either '.xls' or '.xlsx' and false will be - * returned in all other instances. - */ - @Override - public boolean accept(File file, String name) { - return(name.endsWith(".xls") || name.endsWith(".xlsx")); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/CalculateMortgage.java b/trunk/src/examples/src/org/apache/poi/ss/examples/formula/CalculateMortgage.java deleted file mode 100644 index 3d6b4423a..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/CalculateMortgage.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.formula; - -import org.apache.poi.ss.formula.OperationEvaluationContext ; -import org.apache.poi.ss.formula.eval.ErrorEval ; -import org.apache.poi.ss.formula.eval.EvaluationException ; -import org.apache.poi.ss.formula.eval.NumberEval ; -import org.apache.poi.ss.formula.eval.OperandResolver ; -import org.apache.poi.ss.formula.eval.ValueEval ; -import org.apache.poi.ss.formula.functions.FreeRefFunction ; - -/** - * A simple user-defined function to calculate principal and interest. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class CalculateMortgage implements FreeRefFunction { - - @Override - public ValueEval evaluate( ValueEval[] args, OperationEvaluationContext ec ) { - - // verify that we have enough data - if (args.length != 3) { - return ErrorEval.VALUE_INVALID; - } - - // declare doubles for values - double principal, rate, years, result; - try { - // extract values as ValueEval - ValueEval v1 = OperandResolver.getSingleValue( args[0], - ec.getRowIndex(), - ec.getColumnIndex() ) ; - ValueEval v2 = OperandResolver.getSingleValue( args[1], - ec.getRowIndex(), - ec.getColumnIndex() ) ; - ValueEval v3 = OperandResolver.getSingleValue( args[2], - ec.getRowIndex(), - ec.getColumnIndex() ) ; - - // get data as doubles - principal = OperandResolver.coerceValueToDouble( v1 ) ; - rate = OperandResolver.coerceValueToDouble( v2 ) ; - years = OperandResolver.coerceValueToDouble( v3 ) ; - - result = calculateMortgagePayment( principal, rate, years ) ; - System.out.println( "Result = " + result ) ; - - checkValue(result); - - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return new NumberEval( result ) ; - } - - public double calculateMortgagePayment( double p, double r, double y ) { - double i = r / 12 ; - double n = y * 12 ; - - double principalAndInterest = - p * (( i * Math.pow((1 + i),n ) ) / ( Math.pow((1 + i),n) - 1)) ; - - return principalAndInterest ; - } - /** - * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases - * - * @throws EvaluationException (#NUM!) if result is NaN or Infinity - */ - private void checkValue(double result) throws EvaluationException { - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/CheckFunctionsSupported.java b/trunk/src/examples/src/org/apache/poi/ss/examples/formula/CheckFunctionsSupported.java deleted file mode 100644 index cf6c176cc..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/CheckFunctionsSupported.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.formula; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.apache.poi.ss.formula.eval.NotImplementedException; -import org.apache.poi.ss.formula.eval.NotImplementedFunctionException; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.ss.util.CellReference; - -/** - * Attempts to re-evaluate all the formulas in the workbook, and - * reports what (if any) formula functions used are not (currently) - * supported by Apache POI. - * - *

    This provides examples of how to evaluate formulas in excel - * files using Apache POI, along with how to handle errors whilst - * doing so. - */ -public class CheckFunctionsSupported { - public static void main(String[] args) throws Exception { - if (args.length < 1) { - System.err.println("Use:"); - System.err.println(" CheckFunctionsSupported "); - return; - } - - Workbook wb = WorkbookFactory.create(new File(args[0])); - CheckFunctionsSupported check = new CheckFunctionsSupported(wb); - - // Fetch all the problems - List problems = new ArrayList(); - for (int sn=0; sn unsupportedFunctions = new TreeSet(); - for (FormulaEvaluationProblems p : problems) { - unsupportedFunctions.addAll(p.unsupportedFunctions); - } - if (unsupportedFunctions.isEmpty()) { - System.out.println("There are no unsupported formula functions used"); - } else { - System.out.println("Unsupported formula functions:"); - for (String function : unsupportedFunctions) { - System.out.println(" " + function); - } - System.out.println("Total unsupported functions = " + unsupportedFunctions.size()); - } - - // Report sheet by sheet - for (int sn=0; sn getUnsupportedFunctions(String sheetName) { - return getUnsupportedFunctions(workbook.getSheet(sheetName)); - } - public Set getUnsupportedFunctions(int sheetIndex) { - return getUnsupportedFunctions(workbook.getSheetAt(sheetIndex)); - } - public Set getUnsupportedFunctions(Sheet sheet) { - FormulaEvaluationProblems problems = getEvaluationProblems(sheet); - return problems.unsupportedFunctions; - } - - public FormulaEvaluationProblems getEvaluationProblems(String sheetName) { - return getEvaluationProblems(workbook.getSheet(sheetName)); - } - public FormulaEvaluationProblems getEvaluationProblems(int sheetIndex) { - return getEvaluationProblems(workbook.getSheetAt(sheetIndex)); - } - public FormulaEvaluationProblems getEvaluationProblems(Sheet sheet) { - Set unsupportedFunctions = new HashSet(); - Map unevaluatableCells = new HashMap(); - - for (Row r : sheet) { - for (Cell c : r) { - try { - evaluator.evaluate(c); - } catch (Exception e) { - if (e instanceof NotImplementedException && e.getCause() != null) { - // Has been wrapped with cell details, but we know those - e = (Exception)e.getCause(); - } - - if (e instanceof NotImplementedFunctionException) { - NotImplementedFunctionException nie = (NotImplementedFunctionException)e; - unsupportedFunctions.add(nie.getFunctionName()); - } - unevaluatableCells.put(new CellReference(c), e); - } - } - } - - return new FormulaEvaluationProblems(unsupportedFunctions, unevaluatableCells); - } - - public static class FormulaEvaluationProblems { - /** Which used functions are unsupported by POI at this time */ - public Set unsupportedFunctions; - /** Which cells had unevaluatable formulas, and why? */ - public Map unevaluatableCells; - - protected FormulaEvaluationProblems(Set unsupportedFunctions, - Map unevaluatableCells) { - this.unsupportedFunctions = Collections.unmodifiableSet(unsupportedFunctions); - this.unevaluatableCells = Collections.unmodifiableMap(unevaluatableCells); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/SettingExternalFunction.java b/trunk/src/examples/src/org/apache/poi/ss/examples/formula/SettingExternalFunction.java deleted file mode 100644 index bf4018f3d..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/SettingExternalFunction.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.examples.formula; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -/** - * Demonstrates how to use functions provided by third-party add-ins, e.g. Bloomberg Excel Add-in. - * - * There can be situations when you are not interested in formula evaluation, - * you just need to set the formula and the workbook will be evaluation by the client. - * - * @author Yegor Kozlov - */ -public class SettingExternalFunction { - - /** - * wrap external functions in a plugin - */ - public static class BloombergAddIn implements UDFFinder { - private final Map _functionsByName; - - public BloombergAddIn() { - // dummy function that returns NA - // don't care about the implementation, we are not interested in evaluation - // and this method will never be called - FreeRefFunction NA = new FreeRefFunction() { - @Override - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - return ErrorEval.NA; - } - }; - _functionsByName = new HashMap(); - _functionsByName.put("BDP", NA); - _functionsByName.put("BDH", NA); - _functionsByName.put("BDS", NA); - } - - @Override - public FreeRefFunction findFunction(String name) { - return _functionsByName.get(name.toUpperCase(Locale.ROOT)); - } - - } - - public static void main( String[] args ) throws IOException { - - Workbook wb = new XSSFWorkbook(); // or new HSSFWorkbook() - - // register the add-in - wb.addToolPack(new BloombergAddIn()); - - Sheet sheet = wb.createSheet(); - Row row = sheet.createRow(0); - row.createCell(0).setCellFormula("BDP(\"GOOG Equity\",\"CHG_PCT_YTD\")/100"); - row.createCell(1).setCellFormula("BDH(\"goog us equity\",\"EBIT\",\"1/1/2005\",\"12/31/2009\",\"per=cy\",\"curr=USD\") "); - row.createCell(2).setCellFormula("BDS(\"goog us equity\",\"top_20_holders_public_filings\") "); - - FileOutputStream out = new FileOutputStream("bloomberg-demo.xlsx"); - wb.write(out); - out.close(); - - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/UserDefinedFunctionExample.java b/trunk/src/examples/src/org/apache/poi/ss/examples/formula/UserDefinedFunctionExample.java deleted file mode 100644 index 74dca7d1b..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/UserDefinedFunctionExample.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.formula; - -import java.io.File ; -import java.io.FileInputStream ; -import java.io.FileNotFoundException ; -import java.io.IOException ; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException ; -import org.apache.poi.ss.formula.functions.FreeRefFunction ; -import org.apache.poi.ss.formula.udf.DefaultUDFFinder ; -import org.apache.poi.ss.formula.udf.UDFFinder ; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellReference ; - - -/** - * An example class of how to invoke a User Defined Function for a given - * XLS instance using POI's UDFFinder implementation. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class UserDefinedFunctionExample { - - public static void main( String[] args ) { - - if( args.length != 2 ) { - System.out.println( "usage: UserDefinedFunctionExample fileName cellId" ) ; - return; - } - - System.out.println( "fileName: " + args[0] ) ; - System.out.println( "cell: " + args[1] ) ; - - File workbookFile = new File( args[0] ) ; - - try { - FileInputStream fis = new FileInputStream(workbookFile); - Workbook workbook = WorkbookFactory.create(fis); - fis.close(); - - String[] functionNames = { "calculatePayment" } ; - FreeRefFunction[] functionImpls = { new CalculateMortgage() } ; - - UDFFinder udfToolpack = new DefaultUDFFinder( functionNames, functionImpls ) ; - - // register the user-defined function in the workbook - workbook.addToolPack(udfToolpack); - - FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); - - CellReference cr = new CellReference( args[1] ) ; - String sheetName = cr.getSheetName() ; - Sheet sheet = workbook.getSheet( sheetName ) ; - int rowIdx = cr.getRow() ; - int colIdx = cr.getCol() ; - Row row = sheet.getRow( rowIdx ) ; - Cell cell = row.getCell( colIdx ) ; - - CellValue value = evaluator.evaluate( cell ) ; - - System.out.println("returns value: " + value ) ; - - } catch( FileNotFoundException e ) { - e.printStackTrace(); - } catch( InvalidFormatException e ) { - e.printStackTrace(); - } catch( IOException e ) { - e.printStackTrace(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/mortgage-calculation.xls b/trunk/src/examples/src/org/apache/poi/ss/examples/formula/mortgage-calculation.xls deleted file mode 100644 index 4e71ba8e6..000000000 Binary files a/trunk/src/examples/src/org/apache/poi/ss/examples/formula/mortgage-calculation.xls and /dev/null differ diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/html/HSSFHtmlHelper.java b/trunk/src/examples/src/org/apache/poi/ss/examples/html/HSSFHtmlHelper.java deleted file mode 100644 index 677a38ab7..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/html/HSSFHtmlHelper.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.html; - -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFPalette; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.CellStyle; - -import java.util.Formatter; - -/** - * Implementation of {@link HtmlHelper} for HSSF files. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class HSSFHtmlHelper implements HtmlHelper { - private final HSSFWorkbook wb; - private final HSSFPalette colors; - - private static final HSSFColor HSSF_AUTO = new HSSFColor.AUTOMATIC(); - - public HSSFHtmlHelper(HSSFWorkbook wb) { - this.wb = wb; - // If there is no custom palette, then this creates a new one that is - // a copy of the default - colors = wb.getCustomPalette(); - } - - @Override - public void colorStyles(CellStyle style, Formatter out) { - HSSFCellStyle cs = (HSSFCellStyle) style; - out.format(" /* fill pattern = %d */%n", cs.getFillPattern()); - styleColor(out, "background-color", cs.getFillForegroundColor()); - styleColor(out, "color", cs.getFont(wb).getColor()); - styleColor(out, "border-left-color", cs.getLeftBorderColor()); - styleColor(out, "border-right-color", cs.getRightBorderColor()); - styleColor(out, "border-top-color", cs.getTopBorderColor()); - styleColor(out, "border-bottom-color", cs.getBottomBorderColor()); - } - - private void styleColor(Formatter out, String attr, short index) { - HSSFColor color = colors.getColor(index); - if (index == HSSF_AUTO.getIndex() || color == null) { - out.format(" /* %s: index = %d */%n", attr, index); - } else { - short[] rgb = color.getTriplet(); - out.format(" %s: #%02x%02x%02x; /* index = %d */%n", attr, rgb[0], - rgb[1], rgb[2], index); - } - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/html/HtmlHelper.java b/trunk/src/examples/src/org/apache/poi/ss/examples/html/HtmlHelper.java deleted file mode 100644 index 2cb1a9173..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/html/HtmlHelper.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.examples.html; - -import org.apache.poi.ss.usermodel.CellStyle; - -import java.util.Formatter; - -/** - * This interface is used where code wants to be independent of the workbook - * formats. If you are writing such code, you can add a method to this - * interface, and then implement it for both HSSF and XSSF workbooks, letting - * the driving code stay independent of format. - * - * @author Ken Arnold, Industrious Media LLC - */ -public interface HtmlHelper { - /** - * Outputs the appropriate CSS style for the given cell style. - * - * @param style The cell style. - * @param out The place to write the output. - */ - void colorStyles(CellStyle style, Formatter out); -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java b/trunk/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java deleted file mode 100644 index f5d2ecba8..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java +++ /dev/null @@ -1,465 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.html; - -import java.io.BufferedReader; -import java.io.Closeable; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.util.Formatter; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.format.CellFormat; -import org.apache.poi.ss.format.CellFormatResult; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * This example shows how to display a spreadsheet in HTML using the classes for - * spreadsheet display. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class ToHtml { - private final Workbook wb; - private final Appendable output; - private boolean completeHTML; - private Formatter out; - private boolean gotBounds; - private int firstColumn; - private int endColumn; - private HtmlHelper helper; - - private static final String DEFAULTS_CLASS = "excelDefaults"; - private static final String COL_HEAD_CLASS = "colHeader"; - private static final String ROW_HEAD_CLASS = "rowHeader"; - - private static final Map HALIGN = mapFor( - HorizontalAlignment.LEFT, "left", - HorizontalAlignment.CENTER, "center", - HorizontalAlignment.RIGHT, "right", - HorizontalAlignment.FILL, "left", - HorizontalAlignment.JUSTIFY, "left", - HorizontalAlignment.CENTER_SELECTION, "center"); - - private static final Map VALIGN = mapFor( - VerticalAlignment.BOTTOM, "bottom", - VerticalAlignment.CENTER, "middle", - VerticalAlignment.TOP, "top"); - - private static final Map BORDER = mapFor( - BorderStyle.DASH_DOT, "dashed 1pt", - BorderStyle.DASH_DOT_DOT, "dashed 1pt", - BorderStyle.DASHED, "dashed 1pt", - BorderStyle.DOTTED, "dotted 1pt", - BorderStyle.DOUBLE, "double 3pt", - BorderStyle.HAIR, "solid 1px", - BorderStyle.MEDIUM, "solid 2pt", - BorderStyle.MEDIUM_DASH_DOT, "dashed 2pt", - BorderStyle.MEDIUM_DASH_DOT_DOT, "dashed 2pt", - BorderStyle.MEDIUM_DASHED, "dashed 2pt", - BorderStyle.NONE, "none", - BorderStyle.SLANTED_DASH_DOT, "dashed 2pt", - BorderStyle.THICK, "solid 3pt", - BorderStyle.THIN, "dashed 1pt"); - - @SuppressWarnings({"unchecked"}) - private static Map mapFor(Object... mapping) { - Map map = new HashMap(); - for (int i = 0; i < mapping.length; i += 2) { - map.put((K) mapping[i], (V) mapping[i + 1]); - } - return map; - } - - /** - * Creates a new converter to HTML for the given workbook. - * - * @param wb The workbook. - * @param output Where the HTML output will be written. - * - * @return An object for converting the workbook to HTML. - */ - public static ToHtml create(Workbook wb, Appendable output) { - return new ToHtml(wb, output); - } - - /** - * Creates a new converter to HTML for the given workbook. If the path ends - * with ".xlsx" an {@link XSSFWorkbook} will be used; otherwise - * this will use an {@link HSSFWorkbook}. - * - * @param path The file that has the workbook. - * @param output Where the HTML output will be written. - * - * @return An object for converting the workbook to HTML. - */ - public static ToHtml create(String path, Appendable output) - throws IOException { - return create(new FileInputStream(path), output); - } - - /** - * Creates a new converter to HTML for the given workbook. This attempts to - * detect whether the input is XML (so it should create an {@link - * XSSFWorkbook} or not (so it should create an {@link HSSFWorkbook}). - * - * @param in The input stream that has the workbook. - * @param output Where the HTML output will be written. - * - * @return An object for converting the workbook to HTML. - */ - public static ToHtml create(InputStream in, Appendable output) - throws IOException { - try { - Workbook wb = WorkbookFactory.create(in); - return create(wb, output); - } catch (InvalidFormatException e){ - throw new IllegalArgumentException("Cannot create workbook from stream", e); - } - } - - private ToHtml(Workbook wb, Appendable output) { - if (wb == null) - throw new NullPointerException("wb"); - if (output == null) - throw new NullPointerException("output"); - this.wb = wb; - this.output = output; - setupColorMap(); - } - - private void setupColorMap() { - if (wb instanceof HSSFWorkbook) - helper = new HSSFHtmlHelper((HSSFWorkbook) wb); - else if (wb instanceof XSSFWorkbook) - helper = new XSSFHtmlHelper(); - else - throw new IllegalArgumentException( - "unknown workbook type: " + wb.getClass().getSimpleName()); - } - - /** - * Run this class as a program - * - * @param args The command line arguments. - * - * @throws Exception Exception we don't recover from. - */ - public static void main(String[] args) throws Exception { - if(args.length < 2){ - System.err.println("usage: ToHtml inputWorkbook outputHtmlFile"); - return; - } - - ToHtml toHtml = create(args[0], new PrintWriter(new FileWriter(args[1]))); - toHtml.setCompleteHTML(true); - toHtml.printPage(); - } - - public void setCompleteHTML(boolean completeHTML) { - this.completeHTML = completeHTML; - } - - public void printPage() throws IOException { - try { - ensureOut(); - if (completeHTML) { - out.format( - "%n"); - out.format("%n"); - out.format("%n"); - out.format("%n"); - out.format("%n"); - } - - print(); - - if (completeHTML) { - out.format("%n"); - out.format("%n"); - } - } finally { - if (out != null) - out.close(); - if (output instanceof Closeable) { - Closeable closeable = (Closeable) output; - closeable.close(); - } - } - } - - public void print() { - printInlineStyle(); - printSheets(); - } - - private void printInlineStyle() { - //out.format("%n"); - out.format("%n"); - } - - private void ensureOut() { - if (out == null) - out = new Formatter(output); - } - - public void printStyles() { - ensureOut(); - - // First, copy the base css - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader( - getClass().getResourceAsStream("excelStyle.css"))); - String line; - while ((line = in.readLine()) != null) { - out.format("%s%n", line); - } - } catch (IOException e) { - throw new IllegalStateException("Reading standard css", e); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - //noinspection ThrowFromFinallyBlock - throw new IllegalStateException("Reading standard css", e); - } - } - } - - // now add css for each used style - Set seen = new HashSet(); - for (int i = 0; i < wb.getNumberOfSheets(); i++) { - Sheet sheet = wb.getSheetAt(i); - Iterator rows = sheet.rowIterator(); - while (rows.hasNext()) { - Row row = rows.next(); - for (Cell cell : row) { - CellStyle style = cell.getCellStyle(); - if (!seen.contains(style)) { - printStyle(style); - seen.add(style); - } - } - } - } - } - - private void printStyle(CellStyle style) { - out.format(".%s .%s {%n", DEFAULTS_CLASS, styleName(style)); - styleContents(style); - out.format("}%n"); - } - - private void styleContents(CellStyle style) { - styleOut("text-align", style.getAlignmentEnum(), HALIGN); - styleOut("vertical-align", style.getVerticalAlignmentEnum(), VALIGN); - fontStyle(style); - borderStyles(style); - helper.colorStyles(style, out); - } - - private void borderStyles(CellStyle style) { - styleOut("border-left", style.getBorderLeftEnum(), BORDER); - styleOut("border-right", style.getBorderRightEnum(), BORDER); - styleOut("border-top", style.getBorderTopEnum(), BORDER); - styleOut("border-bottom", style.getBorderBottomEnum(), BORDER); - } - - private void fontStyle(CellStyle style) { - Font font = wb.getFontAt(style.getFontIndex()); - - if (font.getBold()) - out.format(" font-weight: bold;%n"); - if (font.getItalic()) - out.format(" font-style: italic;%n"); - - int fontheight = font.getFontHeightInPoints(); - if (fontheight == 9) { - //fix for stupid ol Windows - fontheight = 10; - } - out.format(" font-size: %dpt;%n", fontheight); - - // Font color is handled with the other colors - } - - private String styleName(CellStyle style) { - if (style == null) - style = wb.getCellStyleAt((short) 0); - StringBuilder sb = new StringBuilder(); - Formatter fmt = new Formatter(sb); - try { - fmt.format("style_%02x", style.getIndex()); - return fmt.toString(); - } finally { - fmt.close(); - } - } - - private void styleOut(String attr, K key, Map mapping) { - String value = mapping.get(key); - if (value != null) { - out.format(" %s: %s;%n", attr, value); - } - } - - private static CellType ultimateCellType(Cell c) { - CellType type = c.getCellTypeEnum(); - if (type == CellType.FORMULA) - type = c.getCachedFormulaResultTypeEnum(); - return type; - } - - private void printSheets() { - ensureOut(); - Sheet sheet = wb.getSheetAt(0); - printSheet(sheet); - } - - public void printSheet(Sheet sheet) { - ensureOut(); - out.format("%n", DEFAULTS_CLASS); - printCols(sheet); - printSheetContent(sheet); - out.format("
    %n"); - } - - private void printCols(Sheet sheet) { - out.format("%n"); - ensureColumnBounds(sheet); - for (int i = firstColumn; i < endColumn; i++) { - out.format("%n"); - } - } - - private void ensureColumnBounds(Sheet sheet) { - if (gotBounds) - return; - - Iterator iter = sheet.rowIterator(); - firstColumn = (iter.hasNext() ? Integer.MAX_VALUE : 0); - endColumn = 0; - while (iter.hasNext()) { - Row row = iter.next(); - short firstCell = row.getFirstCellNum(); - if (firstCell >= 0) { - firstColumn = Math.min(firstColumn, firstCell); - endColumn = Math.max(endColumn, row.getLastCellNum()); - } - } - gotBounds = true; - } - - private void printColumnHeads() { - out.format("%n"); - out.format(" %n", COL_HEAD_CLASS); - out.format(" ◊%n", COL_HEAD_CLASS); - //noinspection UnusedDeclaration - StringBuilder colName = new StringBuilder(); - for (int i = firstColumn; i < endColumn; i++) { - colName.setLength(0); - int cnum = i; - do { - colName.insert(0, (char) ('A' + cnum % 26)); - cnum /= 26; - } while (cnum > 0); - out.format(" %s%n", COL_HEAD_CLASS, colName); - } - out.format(" %n"); - out.format("%n"); - } - - private void printSheetContent(Sheet sheet) { - printColumnHeads(); - - out.format("%n"); - Iterator rows = sheet.rowIterator(); - while (rows.hasNext()) { - Row row = rows.next(); - - out.format(" %n"); - out.format(" %d%n", ROW_HEAD_CLASS, - row.getRowNum() + 1); - for (int i = firstColumn; i < endColumn; i++) { - String content = " "; - String attrs = ""; - CellStyle style = null; - if (i >= row.getFirstCellNum() && i < row.getLastCellNum()) { - Cell cell = row.getCell(i); - if (cell != null) { - style = cell.getCellStyle(); - attrs = tagStyle(cell, style); - //Set the value that is rendered for the cell - //also applies the format - CellFormat cf = CellFormat.getInstance( - style.getDataFormatString()); - CellFormatResult result = cf.apply(cell); - content = result.text; - if (content.equals("")) - content = " "; - } - } - out.format(" %s%n", styleName(style), - attrs, content); - } - out.format(" %n"); - } - out.format("%n"); - } - - private String tagStyle(Cell cell, CellStyle style) { - if (style.getAlignmentEnum() == HorizontalAlignment.GENERAL) { - switch (ultimateCellType(cell)) { - case STRING: - return "style=\"text-align: left;\""; - case BOOLEAN: - case ERROR: - return "style=\"text-align: center;\""; - case NUMERIC: - default: - // "right" is the default - break; - } - } - return ""; - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/html/XSSFHtmlHelper.java b/trunk/src/examples/src/org/apache/poi/ss/examples/html/XSSFHtmlHelper.java deleted file mode 100644 index 20a30ed2e..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/html/XSSFHtmlHelper.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.html; - -import java.util.Formatter; - -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFColor; - -/** - * Implementation of {@link HtmlHelper} for XSSF files. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class XSSFHtmlHelper implements HtmlHelper { - @Override - public void colorStyles(CellStyle style, Formatter out) { - XSSFCellStyle cs = (XSSFCellStyle) style; - styleColor(out, "background-color", cs.getFillForegroundXSSFColor()); - styleColor(out, "text-color", cs.getFont().getXSSFColor()); - } - - private void styleColor(Formatter out, String attr, XSSFColor color) { - if (color == null || color.isAuto()) { - return; - } - - byte[] rgb = color.getRGB(); - if (rgb == null) { - return; - } - - // This is done twice -- rgba is new with CSS 3, and browser that don't - // support it will ignore the rgba specification and stick with the - // solid color, which is declared first - out.format(" %s: #%02x%02x%02x;%n", attr, rgb[0], rgb[1], rgb[2]); - byte[] argb = color.getARGB(); - if (argb == null) { - return; - } - out.format(" %s: rgba(0x%02x, 0x%02x, 0x%02x, 0x%02x);%n", attr, - argb[3], argb[0], argb[1], argb[2]); - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/html/excelStyle.css b/trunk/src/examples/src/org/apache/poi/ss/examples/html/excelStyle.css deleted file mode 100644 index 1083b637a..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/html/excelStyle.css +++ /dev/null @@ -1,72 +0,0 @@ -/* - ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== - */ -/* - * This is the default style sheet for html generated by ToHtml - * - * @author Ken Arnold, Industrious Media LLC - */ -.excelDefaults { - background-color: white; - color: black; - text-decoration: none; - direction: ltr; - text-transform: none; - text-indent: 0; - letter-spacing: 0; - word-spacing: 0; - white-space: normal; - unicode-bidi: normal; - vertical-align: 0; - background-image: none; - text-shadow: none; - list-style-image: none; - list-style-type: none; - padding: 0; - margin: 0; - border-collapse: collapse; - white-space: pre; - vertical-align: bottom; - font-style: normal; - font-family: sans-serif; - font-variant: normal; - font-weight: normal; - font-size: 10pt; - text-align: right; -} - -.excelDefaults td { - padding: 1px 5px; - border: 1px solid silver; -} - -.excelDefaults .colHeader { - background-color: silver; - font-weight: bold; - border: 1px solid black; - text-align: center; - padding: 1px 5px; -} - -.excelDefaults .rowHeader { - background-color: silver; - font-weight: bold; - border: 1px solid black; - text-align: right; - padding: 1px 5px; -} diff --git a/trunk/src/examples/src/org/apache/poi/ss/examples/html/package.html b/trunk/src/examples/src/org/apache/poi/ss/examples/html/package.html deleted file mode 100644 index 1c8e6af5c..000000000 --- a/trunk/src/examples/src/org/apache/poi/ss/examples/html/package.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -This package contains an example that uses POI to convert a workbook into -an HTML representation of the data. It can use both XSSF and HSSF workbooks. - - diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/AddVideoToPptx.java.txt b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/AddVideoToPptx.java.txt deleted file mode 100644 index 2d32c4d81..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/AddVideoToPptx.java.txt +++ /dev/null @@ -1,251 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Rectangle; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; -import java.text.DecimalFormat; - -import javax.imageio.ImageIO; -import javax.xml.namespace.QName; - -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.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.xmlbeans.XmlCursor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink; -import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; -import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; -import org.openxmlformats.schemas.presentationml.x2006.main.CTExtension; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; -import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonMediaNodeData; -import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonTimeNodeData; -import org.openxmlformats.schemas.presentationml.x2006.main.CTTimeNodeList; -import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeIndefinite; -import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeFillType; -import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeRestartType; -import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeType; - -import com.xuggle.mediatool.IMediaReader; -import com.xuggle.mediatool.MediaListenerAdapter; -import com.xuggle.mediatool.ToolFactory; -import com.xuggle.mediatool.event.IVideoPictureEvent; -import com.xuggle.xuggler.Global; -import com.xuggle.xuggler.IContainer; -import com.xuggle.xuggler.io.InputOutputStreamHandler; - -/** - * Adding multiple videos to a slide - * - * need the Xuggler 5.4 jars: - * <repositories> - * <repository> - * <id>xuggle repo</id> - * <url>http://xuggle.googlecode.com/svn/trunk/repo/share/java/</url> - * </repository> - * </repositories> - * ... - * <dependency> - * <groupId>xuggle</groupId> - * <artifactId>xuggle-xuggler</artifactId> - * <version>5.4</version> - * </dependency> - * - * @see Apache POI XSLF Adding movie to the slide - * @see Question about embedded video in PPTX files - */ -public class AddVideoToPptx { - static DecimalFormat df_time = new DecimalFormat("0.####"); - - public static void main(String[] args) throws Exception { - URL video = new URL("http://archive.org/download/test-mpeg/test-mpeg.mpg"); - // URL video = new URL("file:test-mpeg.mpg"); - - XMLSlideShow pptx = new XMLSlideShow(); - - // add video file - String videoFileName = video.getPath().substring(video.getPath().lastIndexOf('/')+1); - PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/"+videoFileName); - PackagePart part = pptx.getPackage().createPart(partName, "video/mpeg"); - OutputStream partOs = part.getOutputStream(); - InputStream fis = video.openStream(); - byte buf[] = new byte[1024]; - for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes)); - fis.close(); - partOs.close(); - - XSLFSlide slide1 = pptx.createSlide(); - XSLFPictureShape pv1 = addPreview(pptx, slide1, part, 5, 50, 50); - addVideo(pptx, slide1, part, pv1, 5); - addTimingInfo(slide1, pv1); - XSLFPictureShape pv2 = addPreview(pptx, slide1, part, 9, 50, 250); - addVideo(pptx, slide1, part, pv2, 9); - addTimingInfo(slide1, pv2); - - FileOutputStream fos = new FileOutputStream("pptx-with-video.pptx"); - pptx.write(fos); - fos.close(); - - pptx.close(); - } - - static XSLFPictureShape addPreview(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, double seconds, int x, int y) throws IOException { - // get preview after 5 sec. - IContainer ic = IContainer.make(); - InputOutputStreamHandler iosh = new InputOutputStreamHandler(videoPart.getInputStream()); - if (ic.open(iosh, IContainer.Type.READ, null) < 0) return null; - - IMediaReader mediaReader = ToolFactory.makeReader(ic); - - // stipulate that we want BufferedImages created in BGR 24bit color space - mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR); - - ImageSnapListener isl = new ImageSnapListener(seconds); - mediaReader.addListener(isl); - - // read out the contents of the media file and - // dispatch events to the attached listener - while (!isl.hasFired && mediaReader.readPacket() == null) ; - - mediaReader.close(); - ic.close(); - - // add snapshot - BufferedImage image1 = isl.image; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ImageIO.write(image1, "jpeg", bos); - XSLFPictureData snap = pptx.addPicture(bos.toByteArray(), PictureType.JPEG); - XSLFPictureShape pic1 = slide1.createPicture(snap); - pic1.setAnchor(new Rectangle(x, y, image1.getWidth(), image1.getHeight())); - return pic1; - } - - static void addVideo(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, XSLFPictureShape pic1, double seconds) throws IOException { - - // add video shape - PackagePartName partName = videoPart.getPartName(); - PackageRelationship prsEmbed1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.microsoft.com/office/2007/relationships/media"); - PackageRelationship prsExec1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); - CTPicture xpic1 = (CTPicture)pic1.getXmlObject(); - CTHyperlink link1 = xpic1.getNvPicPr().getCNvPr().addNewHlinkClick(); - link1.setId(""); - link1.setAction("ppaction://media"); - - // add video relation - CTApplicationNonVisualDrawingProps nvPr = xpic1.getNvPicPr().getNvPr(); - nvPr.addNewVideoFile().setLink(prsExec1.getId()); - CTExtension ext = nvPr.addNewExtLst().addNewExt(); - // see http://msdn.microsoft.com/en-us/library/dd950140(v=office.12).aspx - ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}"); - String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main"; - XmlCursor cur = ext.newCursor(); - cur.toEndToken(); - cur.beginElement(new QName(p14Ns, "media", "p14")); - cur.insertNamespace("p14", p14Ns); - cur.insertAttributeWithValue(new QName(STRelationshipId.type.getName().getNamespaceURI(), "embed"), prsEmbed1.getId()); - cur.beginElement(new QName(p14Ns, "trim", "p14")); - cur.insertAttributeWithValue("st", df_time.format(seconds*1000.0)); - cur.dispose(); - - } - - static void addTimingInfo(XSLFSlide slide1, XSLFPictureShape pic1) { - // add slide timing information, so video can be controlled - CTSlide xslide = slide1.getXmlObject(); - CTTimeNodeList ctnl; - if (!xslide.isSetTiming()) { - CTTLCommonTimeNodeData ctn = xslide.addNewTiming().addNewTnLst().addNewPar().addNewCTn(); - ctn.setDur(STTLTimeIndefinite.INDEFINITE); - ctn.setRestart(STTLTimeNodeRestartType.NEVER); - ctn.setNodeType(STTLTimeNodeType.TM_ROOT); - ctnl = ctn.addNewChildTnLst(); - } else { - ctnl = xslide.getTiming().getTnLst().getParArray(0).getCTn().getChildTnLst(); - } - - CTTLCommonMediaNodeData cmedia = ctnl.addNewVideo().addNewCMediaNode(); - cmedia.setVol(80000); - CTTLCommonTimeNodeData ctn = cmedia.addNewCTn(); - ctn.setFill(STTLTimeNodeFillType.HOLD); - ctn.setDisplay(false); - ctn.addNewStCondLst().addNewCond().setDelay(STTLTimeIndefinite.INDEFINITE); - cmedia.addNewTgtEl().addNewSpTgt().setSpid(""+pic1.getShapeId()); - } - - - static class ImageSnapListener extends MediaListenerAdapter { - final double SECONDS_BETWEEN_FRAMES; - final long MICRO_SECONDS_BETWEEN_FRAMES; - boolean hasFired = false; - BufferedImage image = null; - - // The video stream index, used to ensure we display frames from one and - // only one video stream from the media container. - int mVideoStreamIndex = -1; - - // Time of last frame write - long mLastPtsWrite = Global.NO_PTS; - - public ImageSnapListener(double seconds) { - SECONDS_BETWEEN_FRAMES = seconds; - MICRO_SECONDS_BETWEEN_FRAMES = - (long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES); - } - - - @Override - public void onVideoPicture(IVideoPictureEvent event) { - - if (event.getStreamIndex() != mVideoStreamIndex) { - // if the selected video stream id is not yet set, go ahead an - // select this lucky video stream - if (mVideoStreamIndex != -1) return; - mVideoStreamIndex = event.getStreamIndex(); - } - - long evtTS = event.getTimeStamp(); - - // if uninitialized, back date mLastPtsWrite to get the very first frame - if (mLastPtsWrite == Global.NO_PTS) - mLastPtsWrite = Math.max(0, evtTS - MICRO_SECONDS_BETWEEN_FRAMES); - - // if it's time to write the next frame - if (evtTS - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) { - if (!hasFired) { - image = event.getImage(); - hasFired = true; - } - // update last write time - mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES; - } - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/DataExtraction.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/DataExtraction.java deleted file mode 100644 index 335840685..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/DataExtraction.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Dimension; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; - -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.PackagePart; - -/** - * Demonstrates how you can extract data from a .pptx file - */ -public final class DataExtraction { - - public static void main(String args[]) throws IOException, OpenXML4JException { - - PrintStream out = System.out; - - if (args.length == 0) { - out.println("Input file is required"); - return; - } - - FileInputStream is = new FileInputStream(args[0]); - XMLSlideShow ppt = new XMLSlideShow(is); - is.close(); - - // Get the document's embedded files. - for (PackagePart p : ppt.getAllEmbedds()) { - String type = p.getContentType(); - // typically file name - String name = p.getPartName().getName(); - out.println("Embedded file ("+type+"): "+name); - - InputStream pIs = p.getInputStream(); - // make sense of the part data - pIs.close(); - - } - - // Get the document's embedded files. - for (XSLFPictureData data : ppt.getPictureData()) { - String type = data.getContentType(); - String name = data.getFileName(); - out.println("Picture ("+type+"): "+name); - - InputStream pIs = data.getInputStream(); - // make sense of the image data - pIs.close(); - } - - // size of the canvas in points - Dimension pageSize = ppt.getPageSize(); - out.println("Pagesize: "+pageSize); - - for(XSLFSlide slide : ppt.getSlides()) { - for(XSLFShape shape : slide){ - if(shape instanceof XSLFTextShape) { - XSLFTextShape txShape = (XSLFTextShape)shape; - out.println(txShape.getText()); - } else if (shape instanceof XSLFPictureShape){ - XSLFPictureShape pShape = (XSLFPictureShape)shape; - XSLFPictureData pData = pShape.getPictureData(); - out.println(pData.getFileName()); - } else { - out.println("Process me: " + shape.getClass()); - } - } - } - - ppt.close(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/MergePresentations.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/MergePresentations.java deleted file mode 100644 index 38e928501..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/MergePresentations.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.io.FileInputStream; -import java.io.FileOutputStream; - -/** - * Merge multiple pptx presentations together - * - * @author Yegor Kozlov - */ -public final class MergePresentations { - - public static void main(String args[]) throws Exception { - XMLSlideShow ppt = new XMLSlideShow(); - - for(String arg : args){ - FileInputStream is = new FileInputStream(arg); - XMLSlideShow src = new XMLSlideShow(is); - is.close(); - - for(XSLFSlide srcSlide : src.getSlides()){ - ppt.createSlide().importContent(srcSlide); - } - - src.close(); - } - - FileOutputStream out = new FileOutputStream("merged.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PPTX2SVG.txt b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PPTX2SVG.txt deleted file mode 100644 index dbe089ac3..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PPTX2SVG.txt +++ /dev/null @@ -1,176 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.batik.dom.svg.SVGDOMImplementation; -import org.apache.batik.svggen.SVGGraphics2D; -import org.apache.batik.transcoder.wmf.tosvg.WMFPainter; -import org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Document; - -import javax.imageio.ImageIO; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.DataInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; - -/** - * Convert each slide of a .pptx presentation into SVG - * - * @author Yegor Kozlov - */ -public class PPTX2SVG { - - static void usage() { - System.out.println("Usage: PPTX2SVG "); - } - - public static void main(String[] args) throws Exception { - if (args.length == 0) { - usage(); - return; - } - - String file = args[0]; - - System.out.println("Processing " + file); - - // read the .pptx file - XMLSlideShow ppt = new XMLSlideShow(OPCPackage.open(file)); - - Dimension pgsize = ppt.getPageSize(); - - // convert each slide into a .svg file - XSLFSlide[] slide = ppt.getSlides(); - for (int i = 0; i < slide.length; i++) { - // Create initial SVG DOM - DOMImplementation domImpl = SVGDOMImplementation.getDOMImplementation(); - Document doc = domImpl.createDocument("http://www.w3.org/2000/svg", "svg", null); - //Use Batik SVG Graphics2D driver - SVGGraphics2D graphics = new SVGGraphics2D(doc); - graphics.setRenderingHint(XSLFRenderingHint.IMAGE_RENDERER, new WMFImageRender()); - graphics.setSVGCanvasSize(pgsize); - - String title = slide[i].getTitle(); - System.out.println("Rendering slide " + (i + 1) + (title == null ? "" : ": " + title)); - - // draw stuff. All the heavy-lifting happens here - slide[i].draw(graphics); - - // save the result. - int sep = file.lastIndexOf("."); - String fname = file.substring(0, sep == -1 ? file.length() : sep) + "-" + (i + 1) + ".svg"; - OutputStreamWriter out = - new OutputStreamWriter(new FileOutputStream(fname), "UTF-8"); - DOMSource domSource = new DOMSource(graphics.getRoot()); - StreamResult streamResult = new StreamResult(out); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer serializer = tf.newTransformer(); - serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - serializer.setOutputProperty(OutputKeys.INDENT, "yes"); - serializer.transform(domSource, streamResult); - out.flush(); - out.close(); - } - System.out.println("Done"); - } - - /** - * Image renderer with support for .wmf images - */ - static class WMFImageRender extends XSLFImageRendener { - - /** - * Use Apache Batik to render WMF, - * delegate all other types of images to the javax.imageio framework - */ - @Override - public boolean drawImage(Graphics2D graphics, XSLFPictureData data, - Rectangle2D anchor) { - try { - // see what type of image we are - PackagePart part = data.getPackagePart(); - String contentType = part.getContentType(); - if (contentType.equals("image/x-wmf")) { - WMFRecordStore currentStore = new WMFRecordStore(); - currentStore.read(new DataInputStream(part.getInputStream())); - int wmfwidth = currentStore.getWidthPixels(); - float conv = (float) anchor.getWidth() / wmfwidth; - - // Build a painter for the RecordStore - WMFPainter painter = new WMFPainter(currentStore, - (int) anchor.getX(), (int) anchor.getY(), conv); - painter.paint(graphics); - } else { - BufferedImage img = ImageIO.read(data.getPackagePart().getInputStream()); - graphics.drawImage(img, - (int) anchor.getX(), (int) anchor.getY(), - (int) anchor.getWidth(), (int) anchor.getHeight(), null); - } - } catch (Exception e) { - return false; - } - return true; - } - - /** - * Convert data form the supplied package part into a BufferedImage. - * This method is used to create texture paint. - */ - @Override - public BufferedImage readImage(PackagePart packagePart) throws IOException { - String contentType = packagePart.getContentType(); - if (contentType.equals("image/x-wmf")) { - try { - WMFRecordStore currentStore = new WMFRecordStore(); - currentStore.read(new DataInputStream(packagePart.getInputStream())); - int wmfwidth = currentStore.getWidthPixels(); - int wmfheight = currentStore.getHeightPixels(); - - BufferedImage img = new BufferedImage(wmfwidth, wmfheight, BufferedImage.TYPE_INT_RGB); - Graphics2D graphics = img.createGraphics(); - - // Build a painter for the RecordStore - WMFPainter painter = new WMFPainter(currentStore, 0, 0, 1.0f); - painter.paint(graphics); - - return img; - } catch (IOException e) { - return null; - } - } else { - return ImageIO.read(packagePart.getInputStream()); - } - } - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java deleted file mode 100644 index df98b9296..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.OutputStream; - -/** - * Build a pie chart from a template pptx - * - * @author Yegor Kozlov - */ -public class PieChartDemo { - private static void usage(){ - System.out.println("Usage: PieChartDemo "); - System.out.println(" pie-chart-template.pptx template with a pie chart"); - System.out.println(" pie-chart-data.txt the model to set. First line is chart title, " + - "then go pairs {axis-label value}"); - } - - public static void main(String[] args) throws Exception { - if(args.length < 2) { - usage(); - return; - } - - BufferedReader modelReader = new BufferedReader(new FileReader(args[1])); - XMLSlideShow pptx = null; - try { - String chartTitle = modelReader.readLine(); // first line is chart title - - pptx = new XMLSlideShow(new FileInputStream(args[0])); - XSLFSlide slide = pptx.getSlides().get(0); - - // find chart in the slide - XSLFChart chart = null; - for(POIXMLDocumentPart part : slide.getRelations()){ - if(part instanceof XSLFChart){ - chart = (XSLFChart) part; - break; - } - } - - if(chart == null) throw new IllegalStateException("chart not found in the template"); - - // embedded Excel workbook that holds the chart data - POIXMLDocumentPart xlsPart = chart.getRelations().get(0); - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - - CTChart ctChart = chart.getCTChart(); - CTPlotArea plotArea = ctChart.getPlotArea(); - - CTPieChart pieChart = plotArea.getPieChartArray(0); - //Pie Chart Series - CTPieSer ser = pieChart.getSerArray(0); - - // Series Text - CTSerTx tx = ser.getTx(); - tx.getStrRef().getStrCache().getPtArray(0).setV(chartTitle); - sheet.createRow(0).createCell(1).setCellValue(chartTitle); - String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString(); - tx.getStrRef().setF(titleRef); - - // Category Axis Data - CTAxDataSource cat = ser.getCat(); - CTStrData strData = cat.getStrRef().getStrCache(); - - // Values - CTNumDataSource val = ser.getVal(); - CTNumData numData = val.getNumRef().getNumCache(); - - strData.setPtArray(null); // unset old axis text - numData.setPtArray(null); // unset old values - - // set model - int idx = 0; - int rownum = 1; - String ln; - while((ln = modelReader.readLine()) != null){ - String[] vals = ln.split("\\s+"); - CTNumVal numVal = numData.addNewPt(); - numVal.setIdx(idx); - numVal.setV(vals[1]); - - CTStrVal sVal = strData.addNewPt(); - sVal.setIdx(idx); - sVal.setV(vals[0]); - - idx++; - XSSFRow row = sheet.createRow(rownum++); - row.createCell(0).setCellValue(vals[0]); - row.createCell(1).setCellValue(Double.valueOf(vals[1])); - } - numData.getPtCount().setVal(idx); - strData.getPtCount().setVal(idx); - - String numDataRange = new CellRangeAddress(1, rownum-1, 1, 1).formatAsString(sheet.getSheetName(), true); - val.getNumRef().setF(numDataRange); - String axisDataRange = new CellRangeAddress(1, rownum-1, 0, 0).formatAsString(sheet.getSheetName(), true); - cat.getStrRef().setF(axisDataRange); - - // updated the embedded workbook with the data - OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream(); - try { - wb.write(xlsOut); - } finally { - xlsOut.close(); - } - - // save the result - OutputStream out = new FileOutputStream("pie-chart-demo-output.pptx"); - try { - pptx.write(out); - } finally { - out.close(); - } - } finally { - wb.close(); - } - } finally { - if (pptx != null) pptx.close(); - modelReader.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial1.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial1.java deleted file mode 100644 index 60f5d7121..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial1.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Demonstrates how to create slides with predefined layout - * and fill the placeholder shapes - * - * @author Yegor Kozlov - */ -public class Tutorial1 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - // XSLFSlide#createSlide() with no arguments creates a blank slide - /*XSLFSlide blankSlide =*/ ppt.createSlide(); - - - XSLFSlideMaster master = ppt.getSlideMasters().get(0); - - XSLFSlideLayout layout1 = master.getLayout(SlideLayout.TITLE); - XSLFSlide slide1 = ppt.createSlide(layout1) ; - XSLFTextShape[] ph1 = slide1.getPlaceholders(); - XSLFTextShape titlePlaceholder1 = ph1[0]; - titlePlaceholder1.setText("This is a title"); - XSLFTextShape subtitlePlaceholder1 = ph1[1]; - subtitlePlaceholder1.setText("this is a subtitle"); - - XSLFSlideLayout layout2 = master.getLayout(SlideLayout.TITLE_AND_CONTENT); - XSLFSlide slide2 = ppt.createSlide(layout2) ; - XSLFTextShape[] ph2 = slide2.getPlaceholders(); - XSLFTextShape titlePlaceholder2 = ph2[0]; - titlePlaceholder2.setText("This is a title"); - XSLFTextShape bodyPlaceholder = ph2[1]; - // we are going to add text by paragraphs. Clear the default placehoder text before that - bodyPlaceholder.clearText(); - XSLFTextParagraph p1 = bodyPlaceholder.addNewTextParagraph(); - p1.setIndentLevel(0); - p1.addNewTextRun().setText("Level1 text"); - XSLFTextParagraph p2 = bodyPlaceholder.addNewTextParagraph(); - p2.setIndentLevel(1); - p2.addNewTextRun().setText("Level2 text"); - XSLFTextParagraph p3 = bodyPlaceholder.addNewTextParagraph(); - p3.setIndentLevel(2); - p3.addNewTextRun().setText("Level3 text"); - - FileOutputStream out = new FileOutputStream("slides.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial2.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial2.java deleted file mode 100644 index af05962ee..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial2.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.Rectangle; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Basic paragraph and text formatting - * - * @author Yegor Kozlov - */ -public class Tutorial2 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlide slide1 = ppt.createSlide(); - XSLFTextBox shape1 = slide1.createTextBox(); - // initial height of the text box is 100 pt but - Rectangle anchor = new Rectangle(10, 100, 300, 100); - shape1.setAnchor(anchor); - - XSLFTextParagraph p1 = shape1.addNewTextParagraph(); - XSLFTextRun r1 = p1.addNewTextRun(); - r1.setText("Paragraph Formatting"); - r1.setFontSize(24d); - r1.setFontColor(new Color(85, 142, 213)); - - XSLFTextParagraph p2 = shape1.addNewTextParagraph(); - // If spaceBefore >= 0, then space is a percentage of normal line height. - // If spaceBefore < 0, the absolute value of linespacing is the spacing in points - p2.setSpaceBefore(-20d); // 20 pt from the previous paragraph - p2.setSpaceAfter(300d); // 3 lines after the paragraph - XSLFTextRun r2 = p2.addNewTextRun(); - r2.setText("Paragraph properties apply to all text residing within the corresponding paragraph."); - r2.setFontSize(16d); - - XSLFTextParagraph p3 = shape1.addNewTextParagraph(); - - XSLFTextRun r3 = p3.addNewTextRun(); - r3.setText("Run Formatting"); - r3.setFontSize(24d); - r3.setFontColor(new Color(85, 142, 213)); - - XSLFTextParagraph p4 = shape1.addNewTextParagraph(); - p4.setSpaceBefore(-20d); // 20 pt from the previous paragraph - p4.setSpaceAfter(300d); // 3 lines after the paragraph - XSLFTextRun r4 = p4.addNewTextRun(); - r4.setFontSize(16d); - r4.setText( - "Run level formatting is the most granular property level and allows " + - "for the specifying of all low level text properties. The text run is " + - "what all paragraphs are derived from and thus specifying various " + - "properties per run will allow for a diversely formatted text paragraph."); - - // resize the shape to fit text - shape1.resizeToFitText(); - - FileOutputStream out = new FileOutputStream("text.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java deleted file mode 100644 index 4433605f3..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Rectangle; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.Placeholder; - -/** - * How to set slide title - * - * @author Yegor Kozlov - */ -public class Tutorial3 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlide slide = ppt.createSlide(); - - XSLFTextShape titleShape = slide.createTextBox(); - titleShape.setPlaceholder(Placeholder.TITLE); - titleShape.setText("This is a slide title"); - titleShape.setAnchor(new Rectangle(50, 50, 400, 100)); - - FileOutputStream out = new FileOutputStream("title.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java deleted file mode 100644 index 94082a2ef..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.Rectangle; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.TableCell.BorderEdge; -import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; - -/** - * PPTX Tables - * - * @author Yegor Kozlov - */ -public class Tutorial4 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - // XSLFSlide#createSlide() with no arguments creates a blank slide - XSLFSlide slide = ppt.createSlide(); - - XSLFTable tbl = slide.createTable(); - tbl.setAnchor(new Rectangle(50, 50, 450, 300)); - - int numColumns = 3; - int numRows = 5; - XSLFTableRow headerRow = tbl.addRow(); - headerRow.setHeight(50); - // header - for(int i = 0; i < numColumns; i++) { - XSLFTableCell th = headerRow.addCell(); - XSLFTextParagraph p = th.addNewTextParagraph(); - p.setTextAlign(TextAlign.CENTER); - XSLFTextRun r = p.addNewTextRun(); - r.setText("Header " + (i+1)); - r.setBold(true); - r.setFontColor(Color.white); - th.setFillColor(new Color(79, 129, 189)); - th.setBorderWidth(BorderEdge.bottom, 2.0); - th.setBorderColor(BorderEdge.bottom, Color.white); - - tbl.setColumnWidth(i, 150); // all columns are equally sized - } - - // rows - - for(int rownum = 0; rownum < numRows; rownum ++){ - XSLFTableRow tr = tbl.addRow(); - tr.setHeight(50); - // header - for(int i = 0; i < numColumns; i++) { - XSLFTableCell cell = tr.addCell(); - XSLFTextParagraph p = cell.addNewTextParagraph(); - XSLFTextRun r = p.addNewTextRun(); - - r.setText("Cell " + (i+1)); - if(rownum % 2 == 0) - cell.setFillColor(new Color(208, 216, 232)); - else - cell.setFillColor(new Color(233, 247, 244)); - - } - - } - - - FileOutputStream out = new FileOutputStream("table.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial5.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial5.java deleted file mode 100644 index 06542afd9..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial5.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.PictureData.PictureType; - -/** - * Images - * - * @author Yegor Kozlov - */ -public class Tutorial5 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlide slide = ppt.createSlide(); - - File img = new File(System.getProperty("POI.testdata.path", "test-data"), "slideshow/clock.jpg"); - XSLFPictureData pictureData = ppt.addPicture(img, PictureType.PNG); - - /*XSLFPictureShape shape =*/ slide.createPicture(pictureData); - - FileOutputStream out = new FileOutputStream("images.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial6.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial6.java deleted file mode 100644 index 73a59d0b8..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial6.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Rectangle; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Hyperlinks - * - * @author Yegor Kozlov - */ -public class Tutorial6 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlide slide1 = ppt.createSlide(); - XSLFSlide slide2 = ppt.createSlide(); - - XSLFTextBox shape1 = slide1.createTextBox(); - shape1.setAnchor(new Rectangle(50, 50, 200, 50)); - XSLFTextRun r1 = shape1.addNewTextParagraph().addNewTextRun(); - XSLFHyperlink link1 = r1.createHyperlink(); - r1.setText("http://poi.apache.org"); // visible text - link1.setAddress("http://poi.apache.org"); // link address - - XSLFTextBox shape2 = slide1.createTextBox(); - shape2.setAnchor(new Rectangle(300, 50, 200, 50)); - XSLFTextRun r2 = shape2.addNewTextParagraph().addNewTextRun(); - XSLFHyperlink link2 = r2.createHyperlink(); - r2.setText("Go to the second slide"); // visible text - link2.linkToSlide(slide2); // link address - - - - FileOutputStream out = new FileOutputStream("hyperlinks.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial7.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial7.java deleted file mode 100644 index 26f822d1c..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial7.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.Rectangle; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.AutoNumberingScheme; - -/** - * Bullets and numbering - * - * @author Yegor Kozlov - */ -public class Tutorial7 { - - public static void main(String[] args) throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlide slide = ppt.createSlide(); - XSLFTextBox shape = slide.createTextBox(); - shape.setAnchor(new Rectangle(50, 50, 400, 200)); - - XSLFTextParagraph p1 = shape.addNewTextParagraph(); - p1.setIndentLevel(0); - p1.setBullet(true); - XSLFTextRun r1 = p1.addNewTextRun(); - r1.setText("Bullet1"); - - XSLFTextParagraph p2 = shape.addNewTextParagraph(); - // indentation before text - p2.setLeftMargin(60d); - // the bullet is set 40 pt before the text - p2.setIndent(-40d); - p2.setBullet(true); - // customize bullets - p2.setBulletFontColor(Color.red); - p2.setBulletFont("Wingdings"); - p2.setBulletCharacter("\u0075"); - p2.setIndentLevel(1); - XSLFTextRun r2 = p2.addNewTextRun(); - r2.setText("Bullet2"); - - // the next three paragraphs form an auto-numbered list - XSLFTextParagraph p3 = shape.addNewTextParagraph(); - p3.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 1); - p3.setIndentLevel(2); - XSLFTextRun r3 = p3.addNewTextRun(); - r3.setText("Numbered List Item - 1"); - - XSLFTextParagraph p4 = shape.addNewTextParagraph(); - p4.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 2); - p4.setIndentLevel(2); - XSLFTextRun r4 = p4.addNewTextRun(); - r4.setText("Numbered List Item - 2"); - - XSLFTextParagraph p5 = shape.addNewTextParagraph(); - p5.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 3); - p5.setIndentLevel(2); - XSLFTextRun r5 = p5.addNewTextRun(); - r5.setText("Numbered List Item - 3"); - - shape.resizeToFitText(); - - FileOutputStream out = new FileOutputStream("list.pptx"); - ppt.write(out); - out.close(); - - ppt.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/pie-chart-data.txt b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/pie-chart-data.txt deleted file mode 100644 index 40b6959c2..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/pie-chart-data.txt +++ /dev/null @@ -1,4 +0,0 @@ -My Chart -First 1.0 -Second 3.0 -Third 4.0 \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/pie-chart-template.pptx b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/pie-chart-template.pptx deleted file mode 100644 index 33d28e154..000000000 Binary files a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/pie-chart-template.pptx and /dev/null differ diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step1.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step1.java deleted file mode 100644 index 41c6cc2da..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step1.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel.tutorial; - -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.poi.xslf.usermodel.XSLFSlide; -import org.apache.poi.xslf.usermodel.XSLFTextParagraph; -import org.apache.poi.xslf.usermodel.XSLFTextRun; -import org.apache.poi.xslf.usermodel.XSLFTextShape; - -import java.io.FileInputStream; - -/** - * Reading a .pptx presentation and printing basic shape properties - * - * @author Yegor Kozlov - */ -public class Step1 { - - public static void main(String[] args) throws Exception { - if(args.length == 0) { - System.out.println("Input file is required"); - return; - } - - XMLSlideShow ppt = new XMLSlideShow(new FileInputStream(args[0])); - - for(XSLFSlide slide : ppt.getSlides()){ - System.out.println("Title: " + slide.getTitle()); - - for(XSLFShape shape : slide.getShapes()){ - if(shape instanceof XSLFTextShape) { - XSLFTextShape tsh = (XSLFTextShape)shape; - for(XSLFTextParagraph p : tsh){ - System.out.println("Paragraph level: " + p.getIndentLevel()); - for(XSLFTextRun r : p){ - System.out.println(r.getRawText()); - System.out.println(" bold: " + r.isBold()); - System.out.println(" italic: " + r.isItalic()); - System.out.println(" underline: " + r.isUnderlined()); - System.out.println(" font.family: " + r.getFontFamily()); - System.out.println(" font.size: " + r.getFontSize()); - System.out.println(" font.color: " + r.getFontColor()); - } - } - } - } - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step2.java b/trunk/src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step2.java deleted file mode 100644 index cd01d60c8..000000000 --- a/trunk/src/examples/src/org/apache/poi/xslf/usermodel/tutorial/Step2.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel.tutorial; - -import org.apache.poi.xslf.usermodel.SlideLayout; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFSlide; -import org.apache.poi.xslf.usermodel.XSLFSlideLayout; -import org.apache.poi.xslf.usermodel.XSLFSlideMaster; -import org.apache.poi.xslf.usermodel.XSLFTextShape; - -import java.io.FileOutputStream; - -/** - * Create slides from pre-defined slide layouts - * - * @author Yegor Kozlov - */ -public class Step2 { - public static void main(String[] args) throws Exception{ - XMLSlideShow ppt = new XMLSlideShow(); - - - // first see what slide layouts are available by default - System.out.println("Available slide layouts:"); - for(XSLFSlideMaster master : ppt.getSlideMasters()){ - for(XSLFSlideLayout layout : master.getSlideLayouts()){ - System.out.println(layout.getType()); - } - } - - // blank slide - /*XSLFSlide blankSlide =*/ ppt.createSlide(); - - XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0); - - // title slide - XSLFSlideLayout titleLayout = defaultMaster.getLayout(SlideLayout.TITLE); - XSLFSlide slide1 = ppt.createSlide(titleLayout); - XSLFTextShape title1 = slide1.getPlaceholder(0); - title1.setText("First Title"); - - // title and content - XSLFSlideLayout titleBodyLayout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT); - XSLFSlide slide2 = ppt.createSlide(titleBodyLayout); - - XSLFTextShape title2 = slide2.getPlaceholder(0); - title2.setText("Second Title"); - - XSLFTextShape body2 = slide2.getPlaceholder(1); - body2.clearText(); // unset any existing text - body2.addNewTextParagraph().addNewTextRun().setText("First paragraph"); - body2.addNewTextParagraph().addNewTextRun().setText("Second paragraph"); - body2.addNewTextParagraph().addNewTextRun().setText("Third paragraph"); - - - - FileOutputStream out = new FileOutputStream("step2.pptx"); - ppt.write(out); - out.close(); - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java b/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java deleted file mode 100644 index 0f84ce91f..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java +++ /dev/null @@ -1,248 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; - -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.SAXHelper; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; -import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.XSSFComment; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; - -/** - * A rudimentary XLSX -> CSV processor modeled on the - * POI sample program XLS2CSVmra from the package - * org.apache.poi.hssf.eventusermodel.examples. - * As with the HSSF version, this tries to spot missing - * rows and cells, and output empty entries for them. - *

    - * Data sheets are read using a SAX parser to keep the - * memory footprint relatively small, so this should be - * able to read enormous workbooks. The styles table and - * the shared-string table must be kept in memory. The - * standard POI styles table class is used, but a custom - * (read-only) class is used for the shared string table - * because the standard POI SharedStringsTable grows very - * quickly with the number of unique strings. - *

    - * For a more advanced implementation of SAX event parsing - * of XLSX files, see {@link XSSFEventBasedExcelExtractor} - * and {@link XSSFSheetXMLHandler}. Note that for many cases, - * it may be possible to simply use those with a custom - * {@link SheetContentsHandler} and no SAX code needed of - * your own! - */ -public class XLSX2CSV { - /** - * Uses the XSSF Event SAX helpers to do most of the work - * of parsing the Sheet XML, and outputs the contents - * as a (basic) CSV. - */ - private class SheetToCSV implements SheetContentsHandler { - private boolean firstCellOfRow = false; - private int currentRow = -1; - private int currentCol = -1; - - private void outputMissingRows(int number) { - for (int i=0; i CSV converter - * - * @param pkg The XLSX package to process - * @param output The PrintStream to output the CSV to - * @param minColumns The minimum number of columns to output, or -1 for no minimum - */ - public XLSX2CSV(OPCPackage pkg, PrintStream output, int minColumns) { - this.xlsxPackage = pkg; - this.output = output; - this.minColumns = minColumns; - } - - /** - * Parses and shows the content of one sheet - * using the specified styles and shared-strings tables. - * - * @param styles - * @param strings - * @param sheetInputStream - */ - public void processSheet( - StylesTable styles, - ReadOnlySharedStringsTable strings, - SheetContentsHandler sheetHandler, - InputStream sheetInputStream) - throws IOException, ParserConfigurationException, SAXException { - DataFormatter formatter = new DataFormatter(); - InputSource sheetSource = new InputSource(sheetInputStream); - try { - XMLReader sheetParser = SAXHelper.newXMLReader(); - ContentHandler handler = new XSSFSheetXMLHandler( - styles, null, strings, sheetHandler, formatter, false); - sheetParser.setContentHandler(handler); - sheetParser.parse(sheetSource); - } catch(ParserConfigurationException e) { - throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage()); - } - } - - /** - * Initiates the processing of the XLS workbook file to CSV. - * - * @throws IOException - * @throws OpenXML4JException - * @throws ParserConfigurationException - * @throws SAXException - */ - public void process() - throws IOException, OpenXML4JException, ParserConfigurationException, SAXException { - ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(this.xlsxPackage); - XSSFReader xssfReader = new XSSFReader(this.xlsxPackage); - StylesTable styles = xssfReader.getStylesTable(); - XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); - int index = 0; - while (iter.hasNext()) { - InputStream stream = iter.next(); - String sheetName = iter.getSheetName(); - this.output.println(); - this.output.println(sheetName + " [index=" + index + "]:"); - processSheet(styles, strings, new SheetToCSV(), stream); - stream.close(); - ++index; - } - } - - public static void main(String[] args) throws Exception { - if (args.length < 1) { - System.err.println("Use:"); - System.err.println(" XLSX2CSV [min columns]"); - return; - } - - File xlsxFile = new File(args[0]); - if (!xlsxFile.exists()) { - System.err.println("Not found or not a file: " + xlsxFile.getPath()); - return; - } - - int minColumns = -1; - if (args.length >= 2) - minColumns = Integer.parseInt(args[1]); - - // The package open is instantaneous, as it should be. - OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ); - XLSX2CSV xlsx2csv = new XLSX2CSV(p, System.out, minColumns); - xlsx2csv.process(); - p.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/examples/FromHowTo.java b/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/examples/FromHowTo.java deleted file mode 100644 index 6e35e8cdb..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/examples/FromHowTo.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel.examples; - -import java.io.InputStream; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.xssf.eventusermodel.XLSX2CSV; -import org.apache.poi.xssf.eventusermodel.XSSFReader; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * XSSF and SAX (Event API) basic example. - * See {@link XLSX2CSV} for a fuller example of doing - * XSLX processing with the XSSF Event code. - */ -public class FromHowTo { - public void processFirstSheet(String filename) throws Exception { - OPCPackage pkg = OPCPackage.open(filename, PackageAccess.READ); - try { - XSSFReader r = new XSSFReader(pkg); - SharedStringsTable sst = r.getSharedStringsTable(); - - XMLReader parser = fetchSheetParser(sst); - - // process the first sheet - InputStream sheet2 = r.getSheetsData().next(); - InputSource sheetSource = new InputSource(sheet2); - parser.parse(sheetSource); - sheet2.close(); - } finally { - pkg.close(); - } - } - - public void processAllSheets(String filename) throws Exception { - OPCPackage pkg = OPCPackage.open(filename, PackageAccess.READ); - try { - XSSFReader r = new XSSFReader(pkg); - SharedStringsTable sst = r.getSharedStringsTable(); - - XMLReader parser = fetchSheetParser(sst); - - Iterator sheets = r.getSheetsData(); - while (sheets.hasNext()) { - System.out.println("Processing new sheet:\n"); - InputStream sheet = sheets.next(); - InputSource sheetSource = new InputSource(sheet); - parser.parse(sheetSource); - sheet.close(); - System.out.println(""); - } - } finally { - pkg.close(); - } - } - - public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException { - XMLReader parser = XMLReaderFactory.createXMLReader(); - ContentHandler handler = new SheetHandler(sst); - parser.setContentHandler(handler); - return parser; - } - - /** - * See org.xml.sax.helpers.DefaultHandler javadocs - */ - private static class SheetHandler extends DefaultHandler { - private final SharedStringsTable sst; - private String lastContents; - private boolean nextIsString; - private boolean inlineStr; - private final LruCache lruCache = new LruCache(50); - - private static class LruCache extends LinkedHashMap { - private final int maxEntries; - - public LruCache(final int maxEntries) { - super(maxEntries + 1, 1.0f, true); - this.maxEntries = maxEntries; - } - - @Override - protected boolean removeEldestEntry(final Map.Entry eldest) { - return super.size() > maxEntries; - } - } - - private SheetHandler(SharedStringsTable sst) { - this.sst = sst; - } - - @Override - public void startElement(String uri, String localName, String name, - Attributes attributes) throws SAXException { - // c => cell - if(name.equals("c")) { - // Print the cell reference - System.out.print(attributes.getValue("r") + " - "); - // Figure out if the value is an index in the SST - String cellType = attributes.getValue("t"); - nextIsString = cellType != null && cellType.equals("s"); - inlineStr = cellType != null && cellType.equals("inlineStr"); - } - // Clear contents cache - lastContents = ""; - } - - @Override - public void endElement(String uri, String localName, String name) - throws SAXException { - // Process the last contents as required. - // Do now, as characters() may be called more than once - if(nextIsString) { - Integer idx = Integer.valueOf(lastContents); - lastContents = lruCache.get(idx); - if (lastContents == null && !lruCache.containsKey(idx)) { - lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); - lruCache.put(idx, lastContents); - } - nextIsString = false; - } - - // v => contents of a cell - // Output after we've seen the string contents - if(name.equals("v") || (inlineStr && name.equals("c"))) { - System.out.println(lastContents); - } - } - - @Override - public void characters(char[] ch, int start, int length) throws SAXException { // NOSONAR - lastContents += new String(ch, start, length); - } - } - - public static void main(String[] args) throws Exception { - FromHowTo howto = new FromHowTo(); - howto.processFirstSheet(args[0]); - howto.processAllSheets(args[0]); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/examples/LoadPasswordProtectedXlsxStreaming.java b/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/examples/LoadPasswordProtectedXlsxStreaming.java deleted file mode 100644 index 80e4c7320..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/examples/LoadPasswordProtectedXlsxStreaming.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel.examples; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.crypt.examples.EncryptionUtils; -import org.apache.poi.examples.util.TempFileUtils; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.eventusermodel.XSSFReader; -import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator; - -/** - * An example that loads a password protected workbook and counts the sheets. - * The example highlights how to do this in streaming way. - *

      - *
    • The example demonstrates that all temp files are removed. - *
    • AesZipFileZipEntrySource is used to ensure that temp files are encrypted. - *

    - */ -public class LoadPasswordProtectedXlsxStreaming { - - public static void main(String[] args) throws Exception { - if(args.length != 2) { - throw new IllegalArgumentException("Expected 2 params: filename and password"); - } - TempFileUtils.checkTempFiles(); - String filename = args[0]; - String password = args[1]; - FileInputStream fis = new FileInputStream(filename); - try { - InputStream unencryptedStream = EncryptionUtils.decrypt(fis, password); - try { - printSheetCount(unencryptedStream); - } finally { - IOUtils.closeQuietly(unencryptedStream); - } - } finally { - IOUtils.closeQuietly(fis); - } - TempFileUtils.checkTempFiles(); - } - - public static void printSheetCount(final InputStream inputStream) throws Exception { - AesZipFileZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(inputStream); - try { - OPCPackage pkg = OPCPackage.open(source); - try { - XSSFReader reader = new XSSFReader(pkg); - SheetIterator iter = (SheetIterator)reader.getSheetsData(); - int count = 0; - while(iter.hasNext()) { - iter.next(); - count++; - } - System.out.println("sheet count: " + count); - } finally { - IOUtils.closeQuietly(pkg); - } - } finally { - IOUtils.closeQuietly(source); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/HybridStreaming.java b/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/HybridStreaming.java deleted file mode 100644 index 31b5e859f..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/HybridStreaming.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming.examples; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; -import org.apache.poi.xssf.usermodel.XSSFComment; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; -import org.xml.sax.SAXException; - -/** - * This demonstrates how a hybrid approach to workbook read can be taken, using - * a mix of traditional XSSF and streaming one particular worksheet (perhaps one - * which is too big for the ordinary DOM parse). - */ -public class HybridStreaming { - - private static final String SHEET_TO_STREAM = "large sheet"; - - public static void main(String[] args) throws IOException, SAXException { - InputStream sourceBytes = new FileInputStream("workbook.xlsx"); - XSSFWorkbook workbook = new XSSFWorkbook(sourceBytes) { - /** Avoid DOM parse of large sheet */ - @Override - public void parseSheet(java.util.Map shIdMap, CTSheet ctSheet) { - if (!SHEET_TO_STREAM.equals(ctSheet.getName())) { - super.parseSheet(shIdMap, ctSheet); - } - } - }; - - // Having avoided a DOM-based parse of the sheet, we can stream it instead. - ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(workbook.getPackage()); - new XSSFSheetXMLHandler(workbook.getStylesSource(), strings, createSheetContentsHandler(), false); - workbook.close(); - sourceBytes.close(); - } - - private static SheetContentsHandler createSheetContentsHandler() { - return new SheetContentsHandler() { - - @Override - public void startRow(int rowNum) { - } - - @Override - public void headerFooter(String text, boolean isHeader, String tagName) { - } - - @Override - public void endRow(int rowNum) { - } - - @Override - public void cell(String cellReference, String formattedValue, XSSFComment comment) { - } - }; - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/Outlining.java b/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/Outlining.java deleted file mode 100644 index 4c0b35c85..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/Outlining.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.xssf.streaming.SXSSFSheet; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; - -public class Outlining { - - public static void main(String[] args) throws IOException { - Outlining o = new Outlining(); - o.collapseRow(); - } - - private void collapseRow() throws IOException { - SXSSFWorkbook wb2 = new SXSSFWorkbook(100); - SXSSFSheet sheet2 = wb2.createSheet("new sheet"); - - int rowCount = 20; - for (int i = 0; i < rowCount; i++) { - sheet2.createRow(i); - } - - sheet2.groupRow(4, 9); - sheet2.groupRow(11, 19); - - sheet2.setRowGroupCollapsed(4, true); - - FileOutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx"); - try { - wb2.write(fileOut); - } finally { - fileOut.close(); - wb2.dispose(); - wb2.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/SavePasswordProtectedXlsx.java b/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/SavePasswordProtectedXlsx.java deleted file mode 100644 index 9aaa8bf27..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/streaming/examples/SavePasswordProtectedXlsx.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; - -import org.apache.poi.examples.util.TempFileUtils; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionMode; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.crypt.temp.EncryptedTempData; -import org.apache.poi.poifs.crypt.temp.SXSSFWorkbookWithCustomZipEntrySource; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.streaming.SXSSFCell; -import org.apache.poi.xssf.streaming.SXSSFRow; -import org.apache.poi.xssf.streaming.SXSSFSheet; - -/** - * An example that outputs a simple generated workbook that is password protected. - * The example highlights how to do this in streaming way. - *

      - *
    • The example demonstrates that all temp files are removed. - *
    • SXSSFWorkbookWithCustomZipEntrySource extends SXSSFWorkbook to ensure temp files are encrypted. - *

    - */ -public class SavePasswordProtectedXlsx { - - public static void main(String[] args) throws Exception { - if(args.length != 2) { - throw new IllegalArgumentException("Expected 2 params: filename and password"); - } - TempFileUtils.checkTempFiles(); - String filename = args[0]; - String password = args[1]; - SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource(); - try { - for(int i = 0; i < 10; i++) { - SXSSFSheet sheet = wb.createSheet("Sheet" + i); - for(int r = 0; r < 1000; r++) { - SXSSFRow row = sheet.createRow(r); - for(int c = 0; c < 100; c++) { - SXSSFCell cell = row.createCell(c); - cell.setCellValue("abcd"); - } - } - } - EncryptedTempData tempData = new EncryptedTempData(); - try { - wb.write(tempData.getOutputStream()); - save(tempData.getInputStream(), filename, password); - System.out.println("Saved " + filename); - } finally { - tempData.dispose(); - } - } finally { - wb.close(); - wb.dispose(); - } - TempFileUtils.checkTempFiles(); - } - - public static void save(final InputStream inputStream, final String filename, final String pwd) - throws InvalidFormatException, IOException, GeneralSecurityException { - try { - POIFSFileSystem fs = new POIFSFileSystem(); - EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile); - Encryptor enc = Encryptor.getInstance(info); - enc.confirmPassword(pwd); - OPCPackage opc = OPCPackage.open(inputStream); - try { - FileOutputStream fos = new FileOutputStream(filename); - try { - opc.save(enc.getDataStream(fs)); - fs.writeFilesystem(fos); - } finally { - IOUtils.closeQuietly(fos); - } - } finally { - IOUtils.closeQuietly(opc); - } - } finally { - IOUtils.closeQuietly(inputStream); - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java deleted file mode 100644 index 0bb002fb3..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ==================================================================== -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl; - -/** - * Shows how various alignment options work. - * - * Modified by Cristian Petrula, Romania on May 26, 2010 - * New method was added centerAcrossSelection to center a column content over - * one selection using {@link HorizontalAlignment#CENTER_SELECTION} - * To create this method example was change for XSSF only and the previous - * AligningCells.java example has been moved into the SS examples folder. - */ -public class AligningCells { - - public static void main(String[] args) throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - - XSSFSheet sheet = wb.createSheet(); - XSSFRow row = sheet.createRow(2); - row.setHeightInPoints(30); - for (int i = 0; i < 8; i++) { - //column width is set in units of 1/256th of a character width - sheet.setColumnWidth(i, 256 * 15); - } - - createCell(wb, row, 0, HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM); - createCell(wb, row, 1, HorizontalAlignment.CENTER_SELECTION, VerticalAlignment.BOTTOM); - createCell(wb, row, 2, HorizontalAlignment.FILL, VerticalAlignment.CENTER); - createCell(wb, row, 3, HorizontalAlignment.GENERAL, VerticalAlignment.CENTER); - createCell(wb, row, 4, HorizontalAlignment.JUSTIFY, VerticalAlignment.JUSTIFY); - createCell(wb, row, 5, HorizontalAlignment.LEFT, VerticalAlignment.TOP); - createCell(wb, row, 6, HorizontalAlignment.RIGHT, VerticalAlignment.TOP); - - //center text over B4, C4, D4 - row = sheet.createRow(3); - centerAcrossSelection(wb, row, 1, 3, VerticalAlignment.CENTER); - - // Write the output to a file - OutputStream fileOut = new FileOutputStream("xssf-align.xlsx"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } - - /** - * Creates a cell and aligns it a certain way. - * - * @param wb the workbook - * @param row the row to create the cell in - * @param column the column number to create the cell in - * @param halign the horizontal alignment for the cell. - */ - private static void createCell(XSSFWorkbook wb, XSSFRow row, int column, - HorizontalAlignment halign, VerticalAlignment valign) { - CreationHelper ch = wb.getCreationHelper(); - XSSFCell cell = row.createCell(column); - cell.setCellValue(ch.createRichTextString("Align It")); - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(halign); - cellStyle.setVerticalAlignment(valign); - cell.setCellStyle(cellStyle); - } - - /** - * Center a text over multiple columns using ALIGN_CENTER_SELECTION - * - * @param wb the workbook - * @param row the row to create the cell in - * @param start_column the column number to create the cell in and where the selection starts - * @param end_column the column number where the selection ends - * @param valign the horizontal alignment for the cell. - */ - private static void centerAcrossSelection(XSSFWorkbook wb, XSSFRow row, - int start_column, int end_column, VerticalAlignment valign) { - CreationHelper ch = wb.getCreationHelper(); - - // Create cell style with ALIGN_CENTER_SELECTION - XSSFCellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION); - cellStyle.setVerticalAlignment(valign); - - // Create cells over the selected area - for (int i = start_column; i <= end_column; i++) { - XSSFCell cell = row.createCell(i); - cell.setCellStyle(cellStyle); - } - - // Set value to the first cell - XSSFCell cell = row.getCell(start_column); - cell.setCellValue(ch.createRichTextString("Align It")); - - // Make the selection - CTRowImpl ctRow = (CTRowImpl) row.getCTRow(); - - // Add object with format start_coll:end_coll. For example 1:3 will span from - // cell 1 to cell 3, where the column index starts with 0 - // - // You can add multiple spans for one row - Object span = start_column + ":" + end_column; - - List spanList = new ArrayList(); - spanList.add(span); - - //add spns to the row - ctRow.setSpans(spanList); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java deleted file mode 100644 index 66bb59762..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java +++ /dev/null @@ -1,300 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Calendar; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import org.apache.poi.openxml4j.opc.internal.ZipHelper; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFDataFormat; -import org.apache.poi.xssf.usermodel.XSSFFont; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Demonstrates a workaround you can use to generate large workbooks and avoid OutOfMemory exception. - * - * Note - You probably don't want to use this approach any more! POI - * now includes the SXSSF which handles all of this for you, you should - * be using that instead! This code remains mostly for historical interest. - *

    - * See - * http://poi.apache.org/spreadsheet/how-to.html#sxssf. - *

    - * If you really want to use this approach, which is also the one that SXSSF - * does for you, it works as follows: - * - * 1. create a template workbook, create sheets and global objects such as cell styles, number formats, etc. - * 2. create an application that streams data in a text file - * 3. Substitute the sheet in the template with the generated data - * - *

    - * Since 3.8 POI provides a low-memory footprint SXSSF API, which implements - * ths "BigGridDemo" strategy. SXSSF is an API-compatible streaming extension - * of XSSF to be used when very large spreadsheets have to be produced, and - * heap space is limited. SXSSF achieves its low memory footprint by limiting - * access to the rows that are within a sliding window, while XSSF gives access - * to all rows in the document. Older rows that are no longer in the window - * become inaccessible, as they are written to the disk. - *

    - * See - * http://poi.apache.org/spreadsheet/how-to.html#sxssf. - - * - * @author Yegor Kozlov - */ -public class BigGridDemo { - private static final String XML_ENCODING = "UTF-8"; - - public static void main(String[] args) throws Exception { - - // Step 1. Create a template file. Setup sheets and workbook-level objects such as - // cell styles, number formats, etc. - - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet("Big Grid"); - - Map styles = createStyles(wb); - //name of the zip entry holding sheet data, e.g. /xl/worksheets/sheet1.xml - String sheetRef = sheet.getPackagePart().getPartName().getName(); - - //save the template - FileOutputStream os = new FileOutputStream("template.xlsx"); - wb.write(os); - os.close(); - - //Step 2. Generate XML file. - File tmp = File.createTempFile("sheet", ".xml"); - Writer fw = new OutputStreamWriter(new FileOutputStream(tmp), XML_ENCODING); - generate(fw, styles); - fw.close(); - - //Step 3. Substitute the template entry with the generated data - FileOutputStream out = new FileOutputStream("big-grid.xlsx"); - substitute(new File("template.xlsx"), tmp, sheetRef.substring(1), out); - out.close(); - - wb.close(); - } - - /** - * Create a library of cell styles. - */ - private static Map createStyles(XSSFWorkbook wb){ - Map styles = new HashMap(); - XSSFDataFormat fmt = wb.createDataFormat(); - - XSSFCellStyle style1 = wb.createCellStyle(); - style1.setAlignment(HorizontalAlignment.RIGHT); - style1.setDataFormat(fmt.getFormat("0.0%")); - styles.put("percent", style1); - - XSSFCellStyle style2 = wb.createCellStyle(); - style2.setAlignment(HorizontalAlignment.CENTER); - style2.setDataFormat(fmt.getFormat("0.0X")); - styles.put("coeff", style2); - - XSSFCellStyle style3 = wb.createCellStyle(); - style3.setAlignment(HorizontalAlignment.RIGHT); - style3.setDataFormat(fmt.getFormat("$#,##0.00")); - styles.put("currency", style3); - - XSSFCellStyle style4 = wb.createCellStyle(); - style4.setAlignment(HorizontalAlignment.RIGHT); - style4.setDataFormat(fmt.getFormat("mmm dd")); - styles.put("date", style4); - - XSSFCellStyle style5 = wb.createCellStyle(); - XSSFFont headerFont = wb.createFont(); - headerFont.setBold(true); - style5.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - style5.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style5.setFont(headerFont); - styles.put("header", style5); - - return styles; - } - - private static void generate(Writer out, Map styles) throws Exception { - - Random rnd = new Random(); - Calendar calendar = Calendar.getInstance(); - - SpreadsheetWriter sw = new SpreadsheetWriter(out); - sw.beginSheet(); - - //insert header row - sw.insertRow(0); - int styleIndex = styles.get("header").getIndex(); - sw.createCell(0, "Title", styleIndex); - sw.createCell(1, "% Change", styleIndex); - sw.createCell(2, "Ratio", styleIndex); - sw.createCell(3, "Expenses", styleIndex); - sw.createCell(4, "Date", styleIndex); - - sw.endRow(); - - //write data rows - for (int rownum = 1; rownum < 100000; rownum++) { - sw.insertRow(rownum); - - sw.createCell(0, "Hello, " + rownum + "!"); - sw.createCell(1, (double)rnd.nextInt(100)/100, styles.get("percent").getIndex()); - sw.createCell(2, (double)rnd.nextInt(10)/10, styles.get("coeff").getIndex()); - sw.createCell(3, rnd.nextInt(10000), styles.get("currency").getIndex()); - sw.createCell(4, calendar, styles.get("date").getIndex()); - - sw.endRow(); - - calendar.roll(Calendar.DAY_OF_YEAR, 1); - } - sw.endSheet(); - } - - /** - * - * @param zipfile the template file - * @param tmpfile the XML file with the sheet data - * @param entry the name of the sheet entry to substitute, e.g. xl/worksheets/sheet1.xml - * @param out the stream to write the result to - */ - private static void substitute(File zipfile, File tmpfile, String entry, OutputStream out) throws IOException { - ZipFile zip = ZipHelper.openZipFile(zipfile); - try { - ZipOutputStream zos = new ZipOutputStream(out); - - Enumeration en = zip.entries(); - while (en.hasMoreElements()) { - ZipEntry ze = en.nextElement(); - if(!ze.getName().equals(entry)){ - zos.putNextEntry(new ZipEntry(ze.getName())); - InputStream is = zip.getInputStream(ze); - copyStream(is, zos); - is.close(); - } - } - zos.putNextEntry(new ZipEntry(entry)); - InputStream is = new FileInputStream(tmpfile); - copyStream(is, zos); - is.close(); - - zos.close(); - } finally { - zip.close(); - } - } - - private static void copyStream(InputStream in, OutputStream out) throws IOException { - byte[] chunk = new byte[1024]; - int count; - while ((count = in.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - } - - /** - * Writes spreadsheet data in a Writer. - * (YK: in future it may evolve in a full-featured API for streaming data in Excel) - */ - public static class SpreadsheetWriter { - private final Writer _out; - private int _rownum; - - public SpreadsheetWriter(Writer out){ - _out = out; - } - - public void beginSheet() throws IOException { - _out.write("" + - "" ); - _out.write("\n"); - } - - public void endSheet() throws IOException { - _out.write(""); - _out.write(""); - } - - /** - * Insert a new row - * - * @param rownum 0-based row number - */ - public void insertRow(int rownum) throws IOException { - _out.write("\n"); - this._rownum = rownum; - } - - /** - * Insert row end marker - */ - public void endRow() throws IOException { - _out.write("\n"); - } - - public void createCell(int columnIndex, String value, int styleIndex) throws IOException { - String ref = new CellReference(_rownum, columnIndex).formatAsString(); - _out.write(""); - _out.write(""+value+""); - _out.write(""); - } - - public void createCell(int columnIndex, String value) throws IOException { - createCell(columnIndex, value, -1); - } - - public void createCell(int columnIndex, double value, int styleIndex) throws IOException { - String ref = new CellReference(_rownum, columnIndex).formatAsString(); - _out.write(""); - _out.write(""+value+""); - _out.write(""); - } - - public void createCell(int columnIndex, double value) throws IOException { - createCell(columnIndex, value, -1); - } - - public void createCell(int columnIndex, Calendar value, int styleIndex) throws IOException { - createCell(columnIndex, DateUtil.getExcelDate(value, false), styleIndex); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CalendarDemo.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CalendarDemo.java deleted file mode 100644 index 48e3fd122..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CalendarDemo.java +++ /dev/null @@ -1,230 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.usermodel.*; - -import java.io.FileOutputStream; -import java.util.Calendar; -import java.util.Map; -import java.util.HashMap; - -/** - * A monthly calendar created using Apache POI. Each month is on a separate sheet. - * This is a version of org.apache.poi.ss.examples.CalendarDemo that demonstrates - * some XSSF features not avaiable when using common HSSF-XSSF interfaces. - * - *
    - * Usage:
    - * CalendarDemo 
    - * 
    - * - * @author Yegor Kozlov - */ -public class CalendarDemo { - - private static final String[] days = { - "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", "Saturday"}; - - private static final String[] months = { - "January", "February", "March","April", "May", "June","July", "August", - "September","October", "November", "December"}; - - public static void main(String[] args) throws Exception { - - Calendar calendar = Calendar.getInstance(); - if(args.length > 0) calendar.set(Calendar.YEAR, Integer.parseInt(args[0])); - - int year = calendar.get(Calendar.YEAR); - - XSSFWorkbook wb = new XSSFWorkbook(); - Map styles = createStyles(wb); - - for (int month = 0; month < 12; month++) { - calendar.set(Calendar.MONTH, month); - calendar.set(Calendar.DAY_OF_MONTH, 1); - //create a sheet for each month - XSSFSheet sheet = wb.createSheet(months[month]); - - //turn off gridlines - sheet.setDisplayGridlines(false); - sheet.setPrintGridlines(false); - XSSFPrintSetup printSetup = sheet.getPrintSetup(); - printSetup.setOrientation(PrintOrientation.LANDSCAPE); - sheet.setFitToPage(true); - sheet.setHorizontallyCenter(true); - - //the header row: centered text in 48pt font - XSSFRow headerRow = sheet.createRow(0); - headerRow.setHeightInPoints(80); - XSSFCell titleCell = headerRow.createCell(0); - titleCell.setCellValue(months[month] + " " + year); - titleCell.setCellStyle(styles.get("title")); - sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$N$1")); - - //header with month titles - XSSFRow monthRow = sheet.createRow(1); - for (int i = 0; i < days.length; i++) { - //for compatibility with HSSF we have to set column width in units of 1/256th of a character width - sheet.setColumnWidth(i*2, 5*256); //the column is 5 characters wide - sheet.setColumnWidth(i*2 + 1, 13*256); //the column is 13 characters wide - sheet.addMergedRegion(new CellRangeAddress(1, 1, i*2, i*2+1)); - XSSFCell monthCell = monthRow.createCell(i*2); - monthCell.setCellValue(days[i]); - monthCell.setCellStyle(styles.get("month")); - } - - int cnt = 1, day=1; - int rownum = 2; - for (int j = 0; j < 6; j++) { - XSSFRow row = sheet.createRow(rownum++); - row.setHeightInPoints(100); - for (int i = 0; i < days.length; i++) { - XSSFCell dayCell_1 = row.createCell(i*2); - XSSFCell dayCell_2 = row.createCell(i*2 + 1); - - int day_of_week = calendar.get(Calendar.DAY_OF_WEEK); - if(cnt >= day_of_week && calendar.get(Calendar.MONTH) == month) { - dayCell_1.setCellValue(day); - calendar.set(Calendar.DAY_OF_MONTH, ++day); - - if(i == 0 || i == days.length-1) { - dayCell_1.setCellStyle(styles.get("weekend_left")); - dayCell_2.setCellStyle(styles.get("weekend_right")); - } else { - dayCell_1.setCellStyle(styles.get("workday_left")); - dayCell_2.setCellStyle(styles.get("workday_right")); - } - } else { - dayCell_1.setCellStyle(styles.get("grey_left")); - dayCell_2.setCellStyle(styles.get("grey_right")); - } - cnt++; - } - if(calendar.get(Calendar.MONTH) > month) break; - } - } - - // Write the output to a file - FileOutputStream out = new FileOutputStream("calendar-"+year+".xlsx"); - wb.write(out); - out.close(); - - wb.close(); - } - - /** - * cell styles used for formatting calendar sheets - */ - private static Map createStyles(XSSFWorkbook wb){ - Map styles = new HashMap(); - - XSSFCellStyle style; - XSSFFont titleFont = wb.createFont(); - titleFont.setFontHeightInPoints((short)48); - titleFont.setColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFont(titleFont); - styles.put("title", style); - - XSSFFont monthFont = wb.createFont(); - monthFont.setFontHeightInPoints((short)12); - monthFont.setColor(new XSSFColor(new java.awt.Color(255, 255, 255))); - monthFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setFont(monthFont); - styles.put("month", style); - - XSSFFont dayFont = wb.createFont(); - dayFont.setFontHeightInPoints((short)14); - dayFont.setBold(true); - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.LEFT); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(228, 232, 243))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderLeft(BorderStyle.THIN); - style.setLeftBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setFont(dayFont); - styles.put("weekend_left", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(228, 232, 243))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - styles.put("weekend_right", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.LEFT); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setBorderLeft(BorderStyle.THIN); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 255, 255))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setLeftBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setFont(dayFont); - styles.put("workday_left", style); - - style = wb.createCellStyle(); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.TOP); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 255, 255))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - styles.put("workday_right", style); - - style = wb.createCellStyle(); - style.setBorderLeft(BorderStyle.THIN); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(234, 234, 234))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - styles.put("grey_left", style); - - style = wb.createCellStyle(); - style.setFillForegroundColor(new XSSFColor(new java.awt.Color(234, 234, 234))); - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - style.setBorderRight(BorderStyle.THIN); - style.setRightBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - style.setBorderBottom(BorderStyle.THIN); - style.setBottomBorderColor(new XSSFColor(new java.awt.Color(39, 51, 89))); - styles.put("grey_right", style); - - return styles; - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CellComments.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CellComments.java deleted file mode 100644 index a94e58a34..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CellComments.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import java.io.IOException; -import java.io.FileOutputStream; - -/** - * Demonstrates how to work with excel cell comments. - * - *

    - * Excel comment is a kind of a text shape, - * so inserting a comment is very similar to placing a text box in a worksheet - *

    - * - * @author Yegor Kozlov - */ -public class CellComments { - public static void main(String[] args) throws IOException { - Workbook wb = new XSSFWorkbook(); - - CreationHelper factory = wb.getCreationHelper(); - - Sheet sheet = wb.createSheet(); - - Cell cell1 = sheet.createRow(3).createCell(5); - cell1.setCellValue("F4"); - - Drawing drawing = sheet.createDrawingPatriarch(); - - ClientAnchor anchor = factory.createClientAnchor(); - - Comment comment1 = drawing.createCellComment(anchor); - RichTextString str1 = factory.createRichTextString("Hello, World!"); - comment1.setString(str1); - comment1.setAuthor("Apache POI"); - cell1.setCellComment(comment1); - - Cell cell2 = sheet.createRow(2).createCell(2); - cell2.setCellValue("C3"); - - Comment comment2 = drawing.createCellComment(anchor); - RichTextString str2 = factory.createRichTextString("XSSF can set cell comments"); - //apply custom font to the text in the comment - Font font = wb.createFont(); - font.setFontName("Arial"); - font.setFontHeightInPoints((short)14); - font.setBoldweight(Font.BOLDWEIGHT_BOLD); - font.setColor(IndexedColors.RED.getIndex()); - str2.applyFont(font); - - comment2.setString(str2); - comment2.setAuthor("Apache POI"); - comment2.setAddress(new CellAddress("C3")); - - String fname = "comments.xlsx"; - FileOutputStream out = new FileOutputStream(fname); - wb.write(out); - out.close(); - - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateCell.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateCell.java deleted file mode 100644 index 3e6736014..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateCell.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.util.Date; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Illustrates how to create cell and set values of different types. - */ -public class CreateCell { - - - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - CreationHelper creationHelper = wb.getCreationHelper(); - Sheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - Row row = sheet.createRow((short)0); - // Create a cell and put a value in it. - Cell cell = row.createCell((short)0); - cell.setCellValue(1); - - //numeric value - row.createCell(1).setCellValue(1.2); - - //plain string value - row.createCell(2).setCellValue("This is a string cell"); - - //rich text string - RichTextString str = creationHelper.createRichTextString("Apache"); - Font font = wb.createFont(); - font.setItalic(true); - font.setUnderline(Font.U_SINGLE); - str.applyFont(font); - row.createCell(3).setCellValue(str); - - //boolean value - row.createCell(4).setCellValue(true); - - //formula - row.createCell(5).setCellFormula("SUM(A1:B1)"); - - //date - CellStyle style = wb.createCellStyle(); - style.setDataFormat(creationHelper.createDataFormat().getFormat("m/d/yy h:mm")); - cell = row.createCell(6); - cell.setCellValue(new Date()); - cell.setCellStyle(style); - - //hyperlink - row.createCell(7).setCellFormula("SUM(A1:B1)"); - cell.setCellFormula("HYPERLINK(\"http://google.com\",\"Google\")"); - - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("ooxml-cell.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java deleted file mode 100644 index a855feeda..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.DataConsolidateFunction; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFPivotTable; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class CreatePivotTable { - - public static void main(String[] args) throws FileNotFoundException, IOException, InvalidFormatException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - - //Create some data to build the pivot table on - setCellData(sheet); - - AreaReference source = new AreaReference("A1:D4", SpreadsheetVersion.EXCEL2007); - CellReference position = new CellReference("H5"); - // Create a pivot table on this sheet, with H5 as the top-left cell.. - // The pivot table's data source is on the same sheet in A1:D4 - XSSFPivotTable pivotTable = sheet.createPivotTable(source, position); - //Configure the pivot table - //Use first column as row label - pivotTable.addRowLabel(0); - //Sum up the second column - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1); - //Set the third column as filter - pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 2); - //Add filter on forth column - pivotTable.addReportFilter(3); - - FileOutputStream fileOut = new FileOutputStream("ooxml-pivottable.xlsx"); - wb.write(fileOut); - fileOut.close(); - wb.close(); - } - - public static void setCellData(XSSFSheet sheet){ - Row row1 = sheet.createRow(0); - // Create a cell and put a value in it. - Cell cell11 = row1.createCell(0); - cell11.setCellValue("Names"); - Cell cell12 = row1.createCell(1); - cell12.setCellValue("#"); - Cell cell13 = row1.createCell(2); - cell13.setCellValue("%"); - Cell cell14 = row1.createCell(3); - cell14.setCellValue("Human"); - - Row row2 = sheet.createRow(1); - Cell cell21 = row2.createCell(0); - cell21.setCellValue("Jane"); - Cell cell22 = row2.createCell(1); - cell22.setCellValue(10); - Cell cell23 = row2.createCell(2); - cell23.setCellValue(100); - Cell cell24 = row2.createCell(3); - cell24.setCellValue("Yes"); - - Row row3 = sheet.createRow(2); - Cell cell31 = row3.createCell(0); - cell31.setCellValue("Tarzan"); - Cell cell32 = row3.createCell(1); - cell32.setCellValue(5); - Cell cell33 = row3.createCell(2); - cell33.setCellValue(90); - Cell cell34 = row3.createCell(3); - cell34.setCellValue("Yes"); - - Row row4 = sheet.createRow(3); - Cell cell41 = row4.createCell(0); - cell41.setCellValue("Terk"); - Cell cell42 = row4.createCell(1); - cell42.setCellValue(10); - Cell cell43 = row4.createCell(2); - cell43.setCellValue(90); - Cell cell44 = row4.createCell(3); - cell44.setCellValue("No"); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java deleted file mode 100644 index c26ff067c..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFTable; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleInfo; - -/** - * Demonstrates how to create a simple table using Apache POI. - */ -public class CreateTable { - - public static void main(String[] args) throws FileNotFoundException, - IOException { - - Workbook wb = new XSSFWorkbook(); - XSSFSheet sheet = (XSSFSheet) wb.createSheet(); - - //Create - XSSFTable table = sheet.createTable(); - table.setDisplayName("Test"); - CTTable cttable = table.getCTTable(); - - //Style configurations - CTTableStyleInfo style = cttable.addNewTableStyleInfo(); - style.setName("TableStyleMedium2"); - style.setShowColumnStripes(false); - style.setShowRowStripes(true); - - //Set which area the table should be placed in - AreaReference reference = new AreaReference(new CellReference(0, 0), - new CellReference(2,2)); - cttable.setRef(reference.formatAsString()); - cttable.setId(1); - cttable.setName("Test"); - cttable.setTotalsRowCount(1); - - CTTableColumns columns = cttable.addNewTableColumns(); - columns.setCount(3); - CTTableColumn column; - XSSFRow row; - XSSFCell cell; - for(int i=0; i<3; i++) { - //Create column - column = columns.addNewTableColumn(); - column.setName("Column"); - column.setId(i+1); - //Create row - row = sheet.createRow(i); - for(int j=0; j<3; j++) { - //Create cell - cell = row.createCell(j); - if(i == 0) { - cell.setCellValue("Column"+j); - } else { - cell.setCellValue("0"); - } - } - } - - FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateUserDefinedDataFormats.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateUserDefinedDataFormats.java deleted file mode 100644 index 4ebaa46fc..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateUserDefinedDataFormats.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.DataFormat; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * How to set user-defined date formats - */ -public class CreateUserDefinedDataFormats { - - - public static void main(String[]args) throws IOException { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("format sheet"); - CellStyle style; - DataFormat format = wb.createDataFormat(); - Row row; - Cell cell; - short rowNum = 0; - short colNum = 0; - - row = sheet.createRow(rowNum); - cell = row.createCell(colNum); - cell.setCellValue(11111.25); - style = wb.createCellStyle(); - style.setDataFormat(format.getFormat("0.0")); - cell.setCellStyle(style); - - row = sheet.createRow(++rowNum); - cell = row.createCell(colNum); - cell.setCellValue(11111.25); - style = wb.createCellStyle(); - style.setDataFormat(format.getFormat("#,##0.0000")); - cell.setCellStyle(style); - - FileOutputStream fileOut = new FileOutputStream("ooxml_dataFormat.xlsx"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CustomXMLMapping.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CustomXMLMapping.java deleted file mode 100644 index 1add0d2fb..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/CustomXMLMapping.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xssf.extractor.XSSFExportToXml; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFMap; - -import java.io.ByteArrayOutputStream; - -/** - * Print all custom XML mappings registered in the given workbook - */ -public class CustomXMLMapping { - - public static void main(String[] args) throws Exception { - OPCPackage pkg = OPCPackage.open(args[0]); - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - for (XSSFMap map : wb.getCustomXMLMappings()) { - XSSFExportToXml exporter = new XSSFExportToXml(map); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xml = os.toString("UTF-8"); - System.out.println(xml); - } - pkg.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/EmbeddedObjects.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/EmbeddedObjects.java deleted file mode 100644 index 3f044c839..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/EmbeddedObjects.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; -import org.apache.poi.hwpf.HWPFDocument; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -import java.io.InputStream; - -/** - * Demonstrates how you can extract embedded data from a .xlsx file - */ -public class EmbeddedObjects { - public static void main(String[] args) throws Exception { - OPCPackage pkg = OPCPackage.open(args[0]); - XSSFWorkbook workbook = new XSSFWorkbook(pkg); - for (PackagePart pPart : workbook.getAllEmbedds()) { - String contentType = pPart.getContentType(); - // Excel Workbook - either binary or OpenXML - if (contentType.equals("application/vnd.ms-excel")) { - HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(pPart.getInputStream()); - } - // Excel Workbook - OpenXML file format - else if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) { - XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(pPart.getInputStream()); - } - // Word Document - binary (OLE2CDF) file format - else if (contentType.equals("application/msword")) { - HWPFDocument document = new HWPFDocument(pPart.getInputStream()); - } - // Word Document - OpenXML file format - else if (contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) { - XWPFDocument document = new XWPFDocument(pPart.getInputStream()); - } - // PowerPoint Document - binary file format - else if (contentType.equals("application/vnd.ms-powerpoint")) { - HSLFSlideShowImpl slideShow = new HSLFSlideShowImpl(pPart.getInputStream()); - } - // PowerPoint Document - OpenXML file format - else if (contentType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")) { - OPCPackage docPackage = OPCPackage.open(pPart.getInputStream()); - XSLFSlideShow slideShow = new XSLFSlideShow(docPackage); - } - // Any other type of embedded object. - else { - System.out.println("Unknown Embedded Document: " + contentType); - InputStream inputStream = pPart.getInputStream(); - } - } - pkg.close(); - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java deleted file mode 100644 index f5edd4a8e..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Fills and Colors - */ -public class FillsAndColors { - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("new sheet"); - - // Create a row and put some cells in it. Rows are 0 based. - Row row = sheet.createRow(1); - - // Aqua background - CellStyle style = wb.createCellStyle(); - style.setFillBackgroundColor(IndexedColors.AQUA.getIndex()); - style.setFillPattern(CellStyle.BIG_SPOTS); - Cell cell = row.createCell(1); - cell.setCellValue(new XSSFRichTextString("X")); - cell.setCellStyle(style); - - // Orange "foreground", foreground being the fill foreground not the font color. - style = wb.createCellStyle(); - style.setFillForegroundColor(IndexedColors.ORANGE.getIndex()); - style.setFillPattern(CellStyle.SOLID_FOREGROUND); - cell = row.createCell(2); - cell.setCellValue(new XSSFRichTextString("X")); - cell.setCellStyle(style); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("fill_colors.xlsx"); - wb.write(fileOut); - fileOut.close(); - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/FitSheetToOnePage.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/FitSheetToOnePage.java deleted file mode 100644 index a781688c3..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/FitSheetToOnePage.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.PrintSetup; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class FitSheetToOnePage { - - - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("format sheet"); - PrintSetup ps = sheet.getPrintSetup(); - - sheet.setAutobreaks(true); - - ps.setFitHeight((short) 1); - ps.setFitWidth((short) 1); - - // Create various cells and rows for spreadsheet. - - FileOutputStream fileOut = new FileOutputStream("fitSheetToOnePage.xlsx"); - wb.write(fileOut); - fileOut.close(); - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/HeadersAndFooters.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/HeadersAndFooters.java deleted file mode 100644 index 8b95fe63c..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/HeadersAndFooters.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.Footer; -import org.apache.poi.ss.usermodel.Header; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class HeadersAndFooters { - - - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("first-header - format sheet"); - sheet.createRow(0).createCell(0).setCellValue(123); - - //set page numbers in the footer - Footer footer = sheet.getFooter(); - //&P == current page number - //&N == page numbers - footer.setRight("Page &P of &N"); - - - Header firstHeader=((XSSFSheet)sheet).getFirstHeader(); - //&F == workbook file name - firstHeader.setLeft("&F ......... first header"); - - for(int i=0;i<100;i=i+10){ - sheet.createRow(i).createCell(0).setCellValue(123); - } - - - XSSFSheet sheet2 = (XSSFSheet)wb.createSheet("odd header-even footer"); - Header oddHeader=sheet2.getOddHeader(); - //&B == bold - //&E == double underline - //&D == date - oddHeader.setCenter("&B &E oddHeader &D "); - - Footer evenFooter=sheet2.getEvenFooter(); - evenFooter.setRight("even footer &P"); - sheet2.createRow(10).createCell(0).setCellValue("Second sheet with an oddHeader and an evenFooter"); - - for(int i=0;i<200;i=i+10){ - sheet2.createRow(i).createCell(0).setCellValue(123); - } - - XSSFSheet sheet3 = (XSSFSheet)wb.createSheet("odd header- odd footer"); - sheet3.createRow(10).createCell(0).setCellValue("Third sheet with oddHeader and oddFooter"); - Header oddH=sheet3.getOddHeader(); - //&C == centered - oddH.setCenter("centered oddHeader"); - oddH.setLeft("left "); - oddH.setRight("right "); - - Footer oddF=sheet3.getOddFooter(); - oddF.setLeft("Page &P"); - oddF.setRight("Pages &N "); - - FileOutputStream fileOut = new FileOutputStream("headerFooter.xlsx"); - wb.write(fileOut); - fileOut.close(); - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/HyperlinkExample.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/HyperlinkExample.java deleted file mode 100644 index a84d32a19..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/HyperlinkExample.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Demonstrates how to create hyperlinks. - */ -public class HyperlinkExample { - - - public static void main(String[]args) throws IOException { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - CreationHelper createHelper = wb.getCreationHelper(); - - //cell style for hyperlinks - //by default hyperlinks are blue and underlined - CellStyle hlink_style = wb.createCellStyle(); - Font hlink_font = wb.createFont(); - hlink_font.setUnderline(Font.U_SINGLE); - hlink_font.setColor(IndexedColors.BLUE.getIndex()); - hlink_style.setFont(hlink_font); - - Cell cell; - Sheet sheet = wb.createSheet("Hyperlinks"); - //URL - cell = sheet.createRow(0).createCell(0); - cell.setCellValue("URL Link"); - - Hyperlink link = createHelper.createHyperlink(HyperlinkType.URL); - link.setAddress("http://poi.apache.org/"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - //link to a file in the current directory - cell = sheet.createRow(1).createCell(0); - cell.setCellValue("File Link"); - link = createHelper.createHyperlink(HyperlinkType.FILE); - link.setAddress("link1.xls"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - //e-mail link - cell = sheet.createRow(2).createCell(0); - cell.setCellValue("Email Link"); - link = createHelper.createHyperlink(HyperlinkType.EMAIL); - //note, if subject contains white spaces, make sure they are url-encoded - link.setAddress("mailto:poi@apache.org?subject=Hyperlinks"); - cell.setHyperlink(link); - cell.setCellStyle(hlink_style); - - //link to a place in this workbook - - //create a target sheet and cell - Sheet sheet2 = wb.createSheet("Target Sheet"); - sheet2.createRow(0).createCell(0).setCellValue("Target Cell"); - - cell = sheet.createRow(3).createCell(0); - cell.setCellValue("Worksheet Link"); - Hyperlink link2 = createHelper.createHyperlink(HyperlinkType.DOCUMENT); - link2.setAddress("'Target Sheet'!A1"); - cell.setHyperlink(link2); - cell.setCellStyle(hlink_style); - - FileOutputStream out = new FileOutputStream("hyperinks.xlsx"); - wb.write(out); - out.close(); - - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/IterateCells.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/IterateCells.java deleted file mode 100644 index 99d1cacf6..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/IterateCells.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; - -import java.io.FileInputStream; - -/** - * Iterate over rows and cells - */ -public class IterateCells { - - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(new FileInputStream(args[0])); - for (int i = 0; i < wb.getNumberOfSheets(); i++) { - Sheet sheet = wb.getSheetAt(i); - System.out.println(wb.getSheetName(i)); - for (Row row : sheet) { - System.out.println("rownum: " + row.getRowNum()); - for (Cell cell : row) { - System.out.println(cell.toString()); - } - } - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java deleted file mode 100644 index d8564c523..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.LegendPosition; -import org.apache.poi.ss.usermodel.charts.LineChartData; -import org.apache.poi.ss.usermodel.charts.ValueAxis; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Line chart example. - */ -public class LineChart { - - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("linechart"); - final int NUM_OF_ROWS = 3; - final int NUM_OF_COLUMNS = 10; - - // Create a row and put some cells in it. Rows are 0 based. - Row row; - Cell cell; - for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) { - row = sheet.createRow((short) rowIndex); - for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) { - cell = row.createCell((short) colIndex); - cell.setCellValue(colIndex * (rowIndex + 1)); - } - } - - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); - - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - legend.setPosition(LegendPosition.TOP_RIGHT); - - LineChartData data = chart.getChartDataFactory().createLineChartData(); - - // Use a category axis for the bottom axis. - ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); - ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); - leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); - - ChartDataSource xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); - ChartDataSource ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); - ChartDataSource ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); - - - data.addSeries(xs, ys1); - data.addSeries(xs, ys2); - - chart.plot(data, bottomAxis, leftAxis); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/LoadPasswordProtectedXlsx.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/LoadPasswordProtectedXlsx.java deleted file mode 100644 index da6032f86..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/LoadPasswordProtectedXlsx.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.crypt.examples.EncryptionUtils; -import org.apache.poi.examples.util.TempFileUtils; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * An example that loads a password protected workbook and counts the sheets. - *

      - *
    • The example demonstrates that all temp files are removed. - *
    • AesZipFileZipEntrySource is used to ensure that temp files are encrypted. - *

    - */ -public class LoadPasswordProtectedXlsx { - - public static void main(String[] args) throws Exception { - if(args.length != 2) { - throw new IllegalArgumentException("Expected 2 params: filename and password"); - } - TempFileUtils.checkTempFiles(); - String filename = args[0]; - String password = args[1]; - FileInputStream fis = new FileInputStream(filename); - try { - InputStream unencryptedStream = EncryptionUtils.decrypt(fis, password); - try { - printSheetCount(unencryptedStream); - } finally { - IOUtils.closeQuietly(unencryptedStream); - } - } finally { - IOUtils.closeQuietly(fis); - } - TempFileUtils.checkTempFiles(); - } - - public static void printSheetCount(final InputStream inputStream) throws Exception { - AesZipFileZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(inputStream); - try { - OPCPackage pkg = OPCPackage.open(source); - try { - XSSFWorkbook workbook = new XSSFWorkbook(pkg); - try { - System.out.println("sheet count: " + workbook.getNumberOfSheets()); - } finally { - IOUtils.closeQuietly(workbook); - } - } finally { - IOUtils.closeQuietly(pkg); - } - } finally { - IOUtils.closeQuietly(source); - } - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/MergingCells.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/MergingCells.java deleted file mode 100644 index 9d63268fc..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/MergingCells.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; - -import java.io.FileOutputStream; - -/** - * An example of how to merge regions of cells. - */ -public class MergingCells { - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("new sheet"); - - Row row = sheet.createRow((short) 1); - Cell cell = row.createCell((short) 1); - cell.setCellValue(new XSSFRichTextString("This is a test of merging")); - - sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, 2)); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("merging_cells.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/NewLinesInCells.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/NewLinesInCells.java deleted file mode 100644 index eb179357d..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/NewLinesInCells.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * How to use newlines in cells - */ -public class NewLinesInCells { - - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - Row row = sheet.createRow(2); - Cell cell = row.createCell(2); - cell.setCellValue("Use \n with word wrap on to create a new line"); - - //to enable newlines you need set a cell styles with wrap=true - CellStyle cs = wb.createCellStyle(); - cs.setWrapText(true); - cell.setCellStyle(cs); - - //increase row height to accomodate two lines of text - row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints())); - - //adjust column width to fit the content - sheet.autoSizeColumn(2); - - FileOutputStream fileOut = new FileOutputStream("ooxml-newlines.xlsx"); - wb.write(fileOut); - fileOut.close(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/Outlining.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/Outlining.java deleted file mode 100644 index 869316f08..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/Outlining.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.io.OutputStream; - -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class Outlining { - - public static void main(String[] args) throws Exception { - Outlining o=new Outlining(); - o.groupRowColumn(); - o.collapseExpandRowColumn(); - } - - - private void groupRowColumn() throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet1 = wb.createSheet("new sheet"); - - sheet1.groupRow( 5, 14 ); - sheet1.groupRow( 7, 14 ); - sheet1.groupRow( 16, 19 ); - - sheet1.groupColumn( (short)4, (short)7 ); - sheet1.groupColumn( (short)9, (short)12 ); - sheet1.groupColumn( (short)10, (short)11 ); - - OutputStream fileOut = new FileOutputStream("outlining.xlsx"); - try { - wb.write(fileOut); - } finally { - fileOut.close(); - } - } - - private void collapseExpandRowColumn() throws Exception { - Workbook wb2 = new XSSFWorkbook(); - Sheet sheet2 = wb2.createSheet("new sheet"); - sheet2.groupRow( 5, 14 ); - sheet2.groupRow( 7, 14 ); - sheet2.groupRow( 16, 19 ); - - sheet2.groupColumn( (short)4, (short)7 ); - sheet2.groupColumn( (short)9, (short)12 ); - sheet2.groupColumn( (short)10, (short)11 ); - - - sheet2.setRowGroupCollapsed( 7, true ); - //sheet1.setRowGroupCollapsed(7,false); - - sheet2.setColumnGroupCollapsed( (short)4, true ); - sheet2.setColumnGroupCollapsed( (short)4, false ); - - OutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx"); - try { - wb2.write(fileOut); - } finally { - fileOut.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java deleted file mode 100644 index f0a94777f..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.*; -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Illustrates how to create a simple scatter chart. - * - * @author Roman Kashitsyn - */ -public class ScatterChart { - - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("Sheet 1"); - final int NUM_OF_ROWS = 3; - final int NUM_OF_COLUMNS = 10; - - // Create a row and put some cells in it. Rows are 0 based. - Row row; - Cell cell; - for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) { - row = sheet.createRow((short) rowIndex); - for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) { - cell = row.createCell((short) colIndex); - cell.setCellValue(colIndex * (rowIndex + 1)); - } - } - - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); - - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - legend.setPosition(LegendPosition.TOP_RIGHT); - - ScatterChartData data = chart.getChartDataFactory().createScatterChartData(); - - ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM); - ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); - leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); - - ChartDataSource xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); - ChartDataSource ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); - ChartDataSource ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); - - - data.addSerie(xs, ys1); - data.addSerie(xs, ys2); - - chart.plot(data, bottomAxis, leftAxis); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/SelectedSheet.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/SelectedSheet.java deleted file mode 100644 index 43a6b4847..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/SelectedSheet.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public abstract class SelectedSheet { - - public static void main(String[]args) throws IOException { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - - wb.createSheet("row sheet"); - wb.createSheet("another sheet"); - Sheet sheet3 = wb.createSheet(" sheet 3 "); - sheet3.setSelected(true); - wb.setActiveSheet(2); - - // Create various cells and rows for spreadsheet. - - FileOutputStream fileOut = new FileOutputStream("selectedSheet.xlsx"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/ShiftRows.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/ShiftRows.java deleted file mode 100644 index ec4bb2139..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/ShiftRows.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * How to shift rows up or down - */ -public class ShiftRows { - - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("Sheet1"); - - Row row1 = sheet.createRow(1); - row1.createCell(0).setCellValue(1); - - Row row2 = sheet.createRow(4); - row2.createCell(1).setCellValue(2); - - Row row3 = sheet.createRow(5); - row3.createCell(2).setCellValue(3); - - Row row4 = sheet.createRow(6); - row4.createCell(3).setCellValue(4); - - Row row5 = sheet.createRow(9); - row5.createCell(4).setCellValue(5); - - // Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5) - sheet.shiftRows(5, 10, -4); - - FileOutputStream fileOut = new FileOutputStream("shiftRows.xlsx"); - wb.write(fileOut); - fileOut.close(); - - } - - -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/SplitAndFreezePanes.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/SplitAndFreezePanes.java deleted file mode 100644 index 937086b85..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/SplitAndFreezePanes.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import java.io.FileOutputStream; - -/** - * How to set spklit and freeze panes - */ -public class SplitAndFreezePanes { - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet1 = wb.createSheet("new sheet"); - Sheet sheet2 = wb.createSheet("second sheet"); - Sheet sheet3 = wb.createSheet("third sheet"); - Sheet sheet4 = wb.createSheet("fourth sheet"); - - // Freeze just one row - sheet1.createFreezePane(0, 1, 0, 1); - // Freeze just one column - sheet2.createFreezePane(1, 0, 1, 0); - // Freeze the columns and rows (forget about scrolling position of the lower right quadrant). - sheet3.createFreezePane(2, 2); - // Create a split with the lower left side being the active quadrant - sheet4.createSplitPane(2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT); - - FileOutputStream fileOut = new FileOutputStream("splitFreezePane.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkbookProperties.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkbookProperties.java deleted file mode 100644 index 3a8fd56d0..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkbookProperties.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.POIXMLProperties; - -/** - * How to set extended and custom properties - * - * @author Yegor Kozlov - */ -public class WorkbookProperties { - - public static void main(String[]args) throws Exception { - - XSSFWorkbook workbook = new XSSFWorkbook(); - workbook.createSheet("Workbook Properties"); - - POIXMLProperties props = workbook.getProperties(); - - /** - * Extended properties are a predefined set of metadata properties - * that are specifically applicable to Office Open XML documents. - * Extended properties consist of 24 simple properties and 3 complex properties stored in the - * part targeted by the relationship of type - */ - POIXMLProperties.ExtendedProperties ext = props.getExtendedProperties(); - ext.getUnderlyingProperties().setCompany("Apache Software Foundation"); - ext.getUnderlyingProperties().setTemplate("XSSF"); - - /** - * Custom properties enable users to define custom metadata properties. - */ - - POIXMLProperties.CustomProperties cust = props.getCustomProperties(); - cust.addProperty("Author", "John Smith"); - cust.addProperty("Year", 2009); - cust.addProperty("Price", 45.50); - cust.addProperty("Available", true); - - FileOutputStream out = new FileOutputStream("workbook.xlsx"); - workbook.write(out); - out.close(); - - } - - -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithBorders.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithBorders.java deleted file mode 100644 index 6e12fffe7..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithBorders.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.*; - -import java.io.FileOutputStream; - -/** - * Working with borders - */ -public class WorkingWithBorders { - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("borders"); - - // Create a row and put some cells in it. Rows are 0 based. - Row row = sheet.createRow((short) 1); - - // Create a cell and put a value in it. - Cell cell = row.createCell((short) 1); - cell.setCellValue(4); - - // Style the cell with borders all around. - CellStyle style = wb.createCellStyle(); - style.setBorderBottom(CellStyle.BORDER_THIN); - style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); - style.setBorderLeft(CellStyle.BORDER_THIN); - style.setLeftBorderColor(IndexedColors.GREEN.getIndex()); - style.setBorderRight(CellStyle.BORDER_THIN); - style.setRightBorderColor(IndexedColors.BLUE.getIndex()); - style.setBorderTop(CellStyle.BORDER_MEDIUM_DASHED); - style.setTopBorderColor(IndexedColors.BLACK.getIndex()); - cell.setCellStyle(style); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("xssf-borders.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithFonts.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithFonts.java deleted file mode 100644 index 3d4393ba1..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithFonts.java +++ /dev/null @@ -1,101 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.IndexedColors; - -import java.io.FileOutputStream; - -/** - * Working with Fonts - */ -public class WorkingWithFonts { - public static void main(String[] args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - Sheet sheet = wb.createSheet("Fonts"); - - Font font0 = wb.createFont(); - font0.setColor(IndexedColors.BROWN.getIndex()); - CellStyle style0 = wb.createCellStyle(); - style0.setFont(font0); - - Font font1 = wb.createFont(); - font1.setFontHeightInPoints((short)14); - font1.setFontName("Courier New"); - font1.setColor(IndexedColors.RED.getIndex()); - CellStyle style1 = wb.createCellStyle(); - style1.setFont(font1); - - Font font2 = wb.createFont(); - font2.setFontHeightInPoints((short)16); - font2.setFontName("Arial"); - font2.setColor(IndexedColors.GREEN.getIndex()); - CellStyle style2 = wb.createCellStyle(); - style2.setFont(font2); - - Font font3 = wb.createFont(); - font3.setFontHeightInPoints((short)18); - font3.setFontName("Times New Roman"); - font3.setColor(IndexedColors.LAVENDER.getIndex()); - CellStyle style3 = wb.createCellStyle(); - style3.setFont(font3); - - Font font4 = wb.createFont(); - font4.setFontHeightInPoints((short)18); - font4.setFontName("Wingdings"); - font4.setColor(IndexedColors.GOLD.getIndex()); - CellStyle style4 = wb.createCellStyle(); - style4.setFont(font4); - - Font font5 = wb.createFont(); - font5.setFontName("Symbol"); - CellStyle style5 = wb.createCellStyle(); - style5.setFont(font5); - - Cell cell0 = sheet.createRow(0).createCell(1); - cell0.setCellValue("Default"); - cell0.setCellStyle(style0); - - Cell cell1 = sheet.createRow(1).createCell(1); - cell1.setCellValue("Courier"); - cell1.setCellStyle(style1); - - Cell cell2 = sheet.createRow(2).createCell(1); - cell2.setCellValue("Arial"); - cell2.setCellStyle(style2); - - Cell cell3 = sheet.createRow(3).createCell(1); - cell3.setCellValue("Times New Roman"); - cell3.setCellStyle(style3); - - Cell cell4 = sheet.createRow(4).createCell(1); - cell4.setCellValue("Wingdings"); - cell4.setCellStyle(style4); - - Cell cell5 = sheet.createRow(5).createCell(1); - cell5.setCellValue("Symbol"); - cell5.setCellStyle(style5); - - // Write the output to a file - FileOutputStream fileOut = new FileOutputStream("xssf-fonts.xlsx"); - wb.write(fileOut); - fileOut.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPageSetup.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPageSetup.java deleted file mode 100644 index 25f994f95..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPageSetup.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Demonstrates various settings avaiable in the Page Setup dialog - */ -public class WorkingWithPageSetup { - - public static void main(String[]args) throws Exception { - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - - /** - * It's possible to set up repeating rows and columns in your printouts by using the setRepeatingRowsAndColumns() function in the Workbook object. - * - * This function Contains 5 parameters: - * The first parameter is the index to the sheet (0 = first sheet). - * The second and third parameters specify the range for the columns to repreat. - * To stop the columns from repeating pass in -1 as the start and end column. - * The fourth and fifth parameters specify the range for the rows to repeat. - * To stop the columns from repeating pass in -1 as the start and end rows. - */ - Sheet sheet1 = wb.createSheet("new sheet"); - Sheet sheet2 = wb.createSheet("second sheet"); - - // Set the columns to repeat from column 0 to 2 on the first sheet - Row row1 = sheet1.createRow(0); - row1.createCell(0).setCellValue(1); - row1.createCell(1).setCellValue(2); - row1.createCell(2).setCellValue(3); - Row row2 = sheet1.createRow(1); - row2.createCell(1).setCellValue(4); - row2.createCell(2).setCellValue(5); - - - Row row3 = sheet2.createRow(1); - row3.createCell(0).setCellValue(2.1); - row3.createCell(4).setCellValue(2.2); - row3.createCell(5).setCellValue(2.3); - Row row4 = sheet2.createRow(2); - row4.createCell(4).setCellValue(2.4); - row4.createCell(5).setCellValue(2.5); - - // Set the columns to repeat from column 0 to 2 on the first sheet - sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:C")); - // Set the the repeating rows and columns on the second sheet. - CellRangeAddress cra = CellRangeAddress.valueOf("E2:F3"); - sheet2.setRepeatingColumns(cra); - sheet2.setRepeatingRows(cra); - - //set the print area for the first sheet - wb.setPrintArea(0, 1, 2, 0, 3); - - - FileOutputStream fileOut = new FileOutputStream("xssf-printsetup.xlsx"); - wb.write(fileOut); - fileOut.close(); - - wb.close(); - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPictures.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPictures.java deleted file mode 100644 index e7aeaaac1..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPictures.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.xssf.usermodel.*; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.util.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.OutputStream; - -/** - * Demonstrates how to insert pictures in a SpreadsheetML document - * - * @author Yegor Kozlov - */ -public class WorkingWithPictures { - public static void main(String[] args) throws IOException { - - //create a new workbook - Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - try { - CreationHelper helper = wb.getCreationHelper(); - - //add a picture in this workbook. - InputStream is = new FileInputStream(args[0]); - byte[] bytes = IOUtils.toByteArray(is); - is.close(); - int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); - - //create sheet - Sheet sheet = wb.createSheet(); - - //create drawing - Drawing drawing = sheet.createDrawingPatriarch(); - - //add a picture shape - ClientAnchor anchor = helper.createClientAnchor(); - anchor.setCol1(1); - anchor.setRow1(1); - Picture pict = drawing.createPicture(anchor, pictureIdx); - - //auto-size picture - pict.resize(2); - - //save workbook - String file = "picture.xls"; - if(wb instanceof XSSFWorkbook) file += "x"; // NOSONAR - OutputStream fileOut = new FileOutputStream(file); - try { - wb.write(fileOut); - } finally { - fileOut.close(); - } - } finally { - wb.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithRichText.java b/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithRichText.java deleted file mode 100644 index 09def9446..000000000 --- a/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithRichText.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.xssf.usermodel.*; - -import java.io.FileOutputStream; -import java.io.OutputStream; - -/** - * Demonstrates how to work with rich text - */ -public class WorkingWithRichText { - - public static void main(String[] args) throws Exception { - - XSSFWorkbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - XSSFRow row = sheet.createRow((short) 2); - - XSSFCell cell = row.createCell(1); - XSSFRichTextString rt = new XSSFRichTextString("The quick brown fox"); - - XSSFFont font1 = wb.createFont(); - font1.setBold(true); - font1.setColor(new XSSFColor(new java.awt.Color(255, 0, 0))); - rt.applyFont(0, 10, font1); - - XSSFFont font2 = wb.createFont(); - font2.setItalic(true); - font2.setUnderline(XSSFFont.U_DOUBLE); - font2.setColor(new XSSFColor(new java.awt.Color(0, 255, 0))); - rt.applyFont(10, 19, font2); - - XSSFFont font3 = wb.createFont(); - font3.setColor(new XSSFColor(new java.awt.Color(0, 0, 255))); - rt.append(" Jumped over the lazy dog", font3); - - cell.setCellValue(rt); - - // Write the output to a file - OutputStream fileOut = new FileOutputStream("xssf-richtext.xlsx"); - try { - wb.write(fileOut); - } finally { - fileOut.close(); - } - } finally { - wb.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/BetterHeaderFooterExample.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/BetterHeaderFooterExample.java deleted file mode 100644 index fe5f5ad44..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/BetterHeaderFooterExample.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.wp.usermodel.HeaderFooterType; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFFooter; -import org.apache.poi.xwpf.usermodel.XWPFHeader; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; - -public class BetterHeaderFooterExample { - - public static void main(String[] args) { - XWPFDocument doc = new XWPFDocument(); - - XWPFParagraph p = doc.createParagraph(); - - XWPFRun r = p.createRun(); - r.setText("Some Text"); - r.setBold(true); - r = p.createRun(); - r.setText("Goodbye"); - - // create header/footer functions insert an empty paragraph - XWPFHeader head = doc.createHeader(HeaderFooterType.DEFAULT); - head.createParagraph().createRun().setText("header"); - - XWPFFooter foot = doc.createFooter(HeaderFooterType.DEFAULT); - foot.createParagraph().createRun().setText("footer"); - - try { - OutputStream os = new FileOutputStream(new File("header2.docx")); - doc.write(os); - doc.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/HeaderFooterTable.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/HeaderFooterTable.java deleted file mode 100644 index a2b9103a4..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/HeaderFooterTable.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.math.BigInteger; - -import org.apache.poi.wp.usermodel.HeaderFooterType; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFFooter; -import org.apache.poi.xwpf.usermodel.XWPFHeader; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; -import org.apache.poi.xwpf.usermodel.XWPFTable; -import org.apache.poi.xwpf.usermodel.XWPFTableCell; -import org.apache.poi.xwpf.usermodel.XWPFTableRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblLayoutType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblLayoutType; - -public class HeaderFooterTable { - - public static void main(String[] args) throws IOException { - XWPFDocument doc = new XWPFDocument(); - - // Create a header with a 1 row, 3 column table - // changes made for issue 57366 allow a new header or footer - // to be created empty. This is a change. You will have to add - // either a paragraph or a table to the header or footer for - // the document to be considered valid. - XWPFHeader hdr = doc.createHeader(HeaderFooterType.DEFAULT); - XWPFTable tbl = hdr.createTable(1, 3); - - // Set the padding around text in the cells to 1/10th of an inch - int pad = (int) (.1 * 1440); - tbl.setCellMargins(pad, pad, pad, pad); - - // Set table width to 6.5 inches in 1440ths of a point - tbl.setWidth((int)(6.5 * 1440)); - // Can not yet set table or cell width properly, tables default to - // autofit layout, and this requires fixed layout - CTTbl ctTbl = tbl.getCTTbl(); - CTTblPr ctTblPr = ctTbl.addNewTblPr(); - CTTblLayoutType layoutType = ctTblPr.addNewTblLayout(); - layoutType.setType(STTblLayoutType.FIXED); - - // Now set up a grid for the table, cells will fit into the grid - // Each cell width is 3120 in 1440ths of an inch, or 1/3rd of 6.5" - BigInteger w = new BigInteger("3120"); - CTTblGrid grid = ctTbl.addNewTblGrid(); - for (int i = 0; i < 3; i++) { - CTTblGridCol gridCol = grid.addNewGridCol(); - gridCol.setW(w); - } - - // Add paragraphs to the cells - XWPFTableRow row = tbl.getRow(0); - XWPFTableCell cell = row.getCell(0); - XWPFParagraph p = cell.getParagraphArray(0); - XWPFRun r = p.createRun(); - r.setText("header left cell"); - - cell = row.getCell(1); - p = cell.getParagraphArray(0); - r = p.createRun(); - r.setText("header center cell"); - - cell = row.getCell(2); - p = cell.getParagraphArray(0); - r = p.createRun(); - r.setText("header right cell"); - - // Create a footer with a Paragraph - XWPFFooter ftr = doc.createFooter(HeaderFooterType.DEFAULT); - p = ftr.createParagraph(); - - r = p.createRun(); - r.setText("footer text"); - - OutputStream os = new FileOutputStream(new File("headertable.docx")); - doc.write(os); - doc.close(); - } - -} diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocument.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocument.java deleted file mode 100644 index 1553321cd..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocument.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; - -import org.apache.poi.xwpf.usermodel.Borders; -import org.apache.poi.xwpf.usermodel.BreakClear; -import org.apache.poi.xwpf.usermodel.BreakType; -import org.apache.poi.xwpf.usermodel.LineSpacingRule; -import org.apache.poi.xwpf.usermodel.ParagraphAlignment; -import org.apache.poi.xwpf.usermodel.TextAlignment; -import org.apache.poi.xwpf.usermodel.UnderlinePatterns; -import org.apache.poi.xwpf.usermodel.VerticalAlign; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; - -/** - * A simple WOrdprocessingML document created by POI XWPF API - * - * @author Yegor Kozlov - */ -public class SimpleDocument { - - public static void main(String[] args) throws Exception { - XWPFDocument doc = new XWPFDocument(); - - XWPFParagraph p1 = doc.createParagraph(); - p1.setAlignment(ParagraphAlignment.CENTER); - p1.setBorderBottom(Borders.DOUBLE); - p1.setBorderTop(Borders.DOUBLE); - - p1.setBorderRight(Borders.DOUBLE); - p1.setBorderLeft(Borders.DOUBLE); - p1.setBorderBetween(Borders.SINGLE); - - p1.setVerticalAlignment(TextAlignment.TOP); - - XWPFRun r1 = p1.createRun(); - r1.setBold(true); - r1.setText("The quick brown fox"); - r1.setBold(true); - r1.setFontFamily("Courier"); - r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH); - r1.setTextPosition(100); - - XWPFParagraph p2 = doc.createParagraph(); - p2.setAlignment(ParagraphAlignment.RIGHT); - - //BORDERS - p2.setBorderBottom(Borders.DOUBLE); - p2.setBorderTop(Borders.DOUBLE); - p2.setBorderRight(Borders.DOUBLE); - p2.setBorderLeft(Borders.DOUBLE); - p2.setBorderBetween(Borders.SINGLE); - - XWPFRun r2 = p2.createRun(); - r2.setText("jumped over the lazy dog"); - r2.setStrike(true); - r2.setFontSize(20); - - XWPFRun r3 = p2.createRun(); - r3.setText("and went away"); - r3.setStrike(true); - r3.setFontSize(20); - r3.setSubscript(VerticalAlign.SUPERSCRIPT); - - - XWPFParagraph p3 = doc.createParagraph(); - p3.setWordWrap(true); - p3.setPageBreak(true); - - //p3.setAlignment(ParagraphAlignment.DISTRIBUTE); - p3.setAlignment(ParagraphAlignment.BOTH); - p3.setSpacingLineRule(LineSpacingRule.EXACT); - - p3.setIndentationFirstLine(600); - - - XWPFRun r4 = p3.createRun(); - r4.setTextPosition(20); - r4.setText("To be, or not to be: that is the question: " - + "Whether 'tis nobler in the mind to suffer " - + "The slings and arrows of outrageous fortune, " - + "Or to take arms against a sea of troubles, " - + "And by opposing end them? To die: to sleep; "); - r4.addBreak(BreakType.PAGE); - r4.setText("No more; and by a sleep to say we end " - + "The heart-ache and the thousand natural shocks " - + "That flesh is heir to, 'tis a consummation " - + "Devoutly to be wish'd. To die, to sleep; " - + "To sleep: perchance to dream: ay, there's the rub; " - + "......."); - r4.setItalic(true); -//This would imply that this break shall be treated as a simple line break, and break the line after that word: - - XWPFRun r5 = p3.createRun(); - r5.setTextPosition(-10); - r5.setText("For in that sleep of death what dreams may come"); - r5.addCarriageReturn(); - r5.setText("When we have shuffled off this mortal coil," - + "Must give us pause: there's the respect" - + "That makes calamity of so long life;"); - r5.addBreak(); - r5.setText("For who would bear the whips and scorns of time," - + "The oppressor's wrong, the proud man's contumely,"); - - r5.addBreak(BreakClear.ALL); - r5.setText("The pangs of despised love, the law's delay," - + "The insolence of office and the spurns" + "......."); - - FileOutputStream out = new FileOutputStream("simple.docx"); - doc.write(out); - out.close(); - - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocumentWithHeader.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocumentWithHeader.java deleted file mode 100644 index a798ebd43..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocumentWithHeader.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; - -/** - * - * @author Richard Ngo - * - */ -public class SimpleDocumentWithHeader { - - private static XWPFParagraph[] pars; - - public static void main(String[] args) { - XWPFDocument doc = new XWPFDocument(); - - XWPFParagraph p = doc.createParagraph(); - - XWPFRun r = p.createRun(); - r.setText("Some Text"); - r.setBold(true); - r = p.createRun(); - r.setText("Goodbye"); - - CTP ctP = CTP.Factory.newInstance(); - CTText t = ctP.addNewR().addNewT(); - t.setStringValue("header"); - pars = new XWPFParagraph[1]; - p = new XWPFParagraph(ctP, doc); - pars[0] = p; - - XWPFHeaderFooterPolicy hfPolicy = doc.createHeaderFooterPolicy(); - hfPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, pars); - - ctP = CTP.Factory.newInstance(); - t = ctP.addNewR().addNewT(); - t.setStringValue("My Footer"); - pars[0] = new XWPFParagraph(ctP, doc); - hfPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, pars); - - try { - OutputStream os = new FileOutputStream(new File("header.docx")); - doc.write(os); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } -} \ No newline at end of file diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleImages.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleImages.java deleted file mode 100644 index 7e95c7a7f..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleImages.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import org.apache.poi.util.Units; -import org.apache.poi.xwpf.usermodel.BreakType; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; - -import java.io.FileInputStream; -import java.io.FileOutputStream; - -/** - * Demonstrates how to add pictures in a .docx document - * - * @author Yegor Kozlov - */ -public class SimpleImages { - - public static void main(String[] args) throws Exception { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - XWPFRun r = p.createRun(); - - for(String imgFile : args) { - int format; - - if(imgFile.endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF; - else if(imgFile.endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF; - else if(imgFile.endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT; - else if(imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG; - else if(imgFile.endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG; - else if(imgFile.endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB; - else if(imgFile.endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF; - else if(imgFile.endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF; - else if(imgFile.endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS; - else if(imgFile.endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP; - else if(imgFile.endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG; - else { - System.err.println("Unsupported picture: " + imgFile + - ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg"); - continue; - } - - r.setText(imgFile); - r.addBreak(); - r.addPicture(new FileInputStream(imgFile), format, imgFile, Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels - r.addBreak(BreakType.PAGE); - } - - FileOutputStream out = new FileOutputStream("images.docx"); - doc.write(out); - out.close(); - } - - -} diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleTable.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleTable.java deleted file mode 100644 index a3857ff2e..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleTable.java +++ /dev/null @@ -1,214 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.util.List; - -import org.apache.poi.xwpf.usermodel.ParagraphAlignment; -import org.apache.poi.xwpf.usermodel.UnderlinePatterns; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; -import org.apache.poi.xwpf.usermodel.XWPFTable; -import org.apache.poi.xwpf.usermodel.XWPFTableCell; -import org.apache.poi.xwpf.usermodel.XWPFTableRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STShd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc; - -/** - * This program creates a simple WordprocessingML table using POI XWPF API, and - * a more complex, styled table using both XWPF and ooxml-schema. It's possible - * that not all referenced wordprocessingml classes are defined in - * poi-ooxml-schemas-3.8-beta4. If this is the case, you'll need to use the full - * ooxml-schemas.jar library. - * - * @author gisella bronzetti (original) - * @author Gregg Morris (styled table) - */ -public class SimpleTable { - - public static void main(String[] args) throws Exception { - try { - createSimpleTable(); - } - catch(Exception e) { - System.out.println("Error trying to create simple table."); - throw(e); - } - try { - createStyledTable(); - } - catch(Exception e) { - System.out.println("Error trying to create styled table."); - throw(e); - } - } - - public static void createSimpleTable() throws Exception { - XWPFDocument doc = new XWPFDocument(); - - try { - XWPFTable table = doc.createTable(3, 3); - - table.getRow(1).getCell(1).setText("EXAMPLE OF TABLE"); - - // table cells have a list of paragraphs; there is an initial - // paragraph created when the cell is created. If you create a - // paragraph in the document to put in the cell, it will also - // appear in the document following the table, which is probably - // not the desired result. - XWPFParagraph p1 = table.getRow(0).getCell(0).getParagraphs().get(0); - - XWPFRun r1 = p1.createRun(); - r1.setBold(true); - r1.setText("The quick brown fox"); - r1.setItalic(true); - r1.setFontFamily("Courier"); - r1.setUnderline(UnderlinePatterns.DOT_DOT_DASH); - r1.setTextPosition(100); - - table.getRow(2).getCell(2).setText("only text"); - - OutputStream out = new FileOutputStream("simpleTable.docx"); - try { - doc.write(out); - } finally { - out.close(); - } - } finally { - doc.close(); - } - } - - /** - * Create a table with some row and column styling. I "manually" add the - * style name to the table, but don't check to see if the style actually - * exists in the document. Since I'm creating it from scratch, it obviously - * won't exist. When opened in MS Word, the table style becomes "Normal". - * I manually set alternating row colors. This could be done using Themes, - * but that's left as an exercise for the reader. The cells in the last - * column of the table have 10pt. "Courier" font. - * I make no claims that this is the "right" way to do it, but it worked - * for me. Given the scarcity of XWPF examples, I thought this may prove - * instructive and give you ideas for your own solutions. - - * @throws Exception - */ - public static void createStyledTable() throws Exception { - // Create a new document from scratch - XWPFDocument doc = new XWPFDocument(); - - try { - // -- OR -- - // open an existing empty document with styles already defined - //XWPFDocument doc = new XWPFDocument(new FileInputStream("base_document.docx")); - - // Create a new table with 6 rows and 3 columns - int nRows = 6; - int nCols = 3; - XWPFTable table = doc.createTable(nRows, nCols); - - // Set the table style. If the style is not defined, the table style - // will become "Normal". - CTTblPr tblPr = table.getCTTbl().getTblPr(); - CTString styleStr = tblPr.addNewTblStyle(); - styleStr.setVal("StyledTable"); - - // Get a list of the rows in the table - List rows = table.getRows(); - int rowCt = 0; - int colCt = 0; - for (XWPFTableRow row : rows) { - // get table row properties (trPr) - CTTrPr trPr = row.getCtRow().addNewTrPr(); - // set row height; units = twentieth of a point, 360 = 0.25" - CTHeight ht = trPr.addNewTrHeight(); - ht.setVal(BigInteger.valueOf(360)); - - // get the cells in this row - List cells = row.getTableCells(); - // add content to each cell - for (XWPFTableCell cell : cells) { - // get a table cell properties element (tcPr) - CTTcPr tcpr = cell.getCTTc().addNewTcPr(); - // set vertical alignment to "center" - CTVerticalJc va = tcpr.addNewVAlign(); - va.setVal(STVerticalJc.CENTER); - - // create cell color element - CTShd ctshd = tcpr.addNewShd(); - ctshd.setColor("auto"); - ctshd.setVal(STShd.CLEAR); - if (rowCt == 0) { - // header row - ctshd.setFill("A7BFDE"); - } else if (rowCt % 2 == 0) { - // even row - ctshd.setFill("D3DFEE"); - } else { - // odd row - ctshd.setFill("EDF2F8"); - } - - // get 1st paragraph in cell's paragraph list - XWPFParagraph para = cell.getParagraphs().get(0); - // create a run to contain the content - XWPFRun rh = para.createRun(); - // style cell as desired - if (colCt == nCols - 1) { - // last column is 10pt Courier - rh.setFontSize(10); - rh.setFontFamily("Courier"); - } - if (rowCt == 0) { - // header row - rh.setText("header row, col " + colCt); - rh.setBold(true); - para.setAlignment(ParagraphAlignment.CENTER); - } else { - // other rows - rh.setText("row " + rowCt + ", col " + colCt); - para.setAlignment(ParagraphAlignment.LEFT); - } - colCt++; - } // for cell - colCt = 0; - rowCt++; - } // for row - - // write the file - OutputStream out = new FileOutputStream("styledTable.docx"); - try { - doc.write(out); - } finally { - out.close(); - } - } finally { - doc.close(); - } - } -} diff --git a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/UpdateEmbeddedDoc.java b/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/UpdateEmbeddedDoc.java deleted file mode 100644 index 410f3c62f..000000000 --- a/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/UpdateEmbeddedDoc.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.examples; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.List; -import java.util.Iterator; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Cell; - -/** - * Tests whether it is possible to successfully update an Excel workbook that is - * embedded into a WordprocessingML document. Note that the test has currently - * only been conducted with a binary Excel workbook and NOT yet with a - * SpreadsheetML workbook embedded into the document. - * - *

    - * This code was successfully tested with the following file from the POI test collection: - * http://svn.apache.org/repos/asf/poi/trunk/test-data/document/EmbeddedDocument.docx - *

    - * - * @author Mark B - */ -public class UpdateEmbeddedDoc { - - private XWPFDocument doc = null; - private File docFile = null; - - private static final int SHEET_NUM = 0; - private static final int ROW_NUM = 0; - private static final int CELL_NUM = 0; - private static final double NEW_VALUE = 100.98D; - private static final String BINARY_EXTENSION = "xls"; - private static final String OPENXML_EXTENSION = "xlsx"; - - /** - * Create a new instance of the UpdateEmbeddedDoc class using the following - * parameters; - * - * @param filename An instance of the String class that encapsulates the name - * of and path to a WordprocessingML Word document that contains an - * embedded binary Excel workbook. - * @throws java.io.FileNotFoundException Thrown if the file cannot be found - * on the underlying file system. - * @throws java.io.IOException Thrown if a problem occurs in the underlying - * file system. - */ - public UpdateEmbeddedDoc(String filename) throws FileNotFoundException, IOException { - this.docFile = new File(filename); - FileInputStream fis = null; - if (!this.docFile.exists()) { - throw new FileNotFoundException("The Word dcoument " + - filename + - " does not exist."); - } - try { - - // Open the Word document file and instantiate the XWPFDocument - // class. - fis = new FileInputStream(this.docFile); - this.doc = new XWPFDocument(fis); - } finally { - if (fis != null) { - try { - fis.close(); - fis = null; - } catch (IOException ioEx) { - System.out.println("IOException caught trying to close " + - "FileInputStream in the constructor of " + - "UpdateEmbeddedDoc."); - } - } - } - } - - /** - * Called to update the embedded Excel workbook. As the format and structire - * of the workbook are known in advance, all this code attempts to do is - * write a new value into the first cell on the first row of the first - * worksheet. Prior to executing this method, that cell will contain the - * value 1. - * - * @throws org.apache.poi.openxml4j.exceptions.OpenXML4JException - * Rather - * than use the specific classes (HSSF/XSSF) to handle the embedded - * workbook this method uses those defeined in the SS stream. As - * a result, it might be the case that a SpreadsheetML file is - * opened for processing, throwing this exception if that file is - * invalid. - * @throws java.io.IOException Thrown if a problem occurs in the underlying - * file system. - */ - public void updateEmbeddedDoc() throws OpenXML4JException, IOException { - Workbook workbook = null; - Sheet sheet = null; - Row row = null; - Cell cell = null; - PackagePart pPart = null; - Iterator pIter = null; - List embeddedDocs = this.doc.getAllEmbedds(); - if (embeddedDocs != null && !embeddedDocs.isEmpty()) { - pIter = embeddedDocs.iterator(); - while (pIter.hasNext()) { - pPart = pIter.next(); - if (pPart.getPartName().getExtension().equals(BINARY_EXTENSION) || - pPart.getPartName().getExtension().equals(OPENXML_EXTENSION)) { - - // Get an InputStream from the pacage part and pass that - // to the create method of the WorkbookFactory class. Update - // the resulting Workbook and then stream that out again - // using an OutputStream obtained from the same PackagePart. - workbook = WorkbookFactory.create(pPart.getInputStream()); - sheet = workbook.getSheetAt(SHEET_NUM); - row = sheet.getRow(ROW_NUM); - cell = row.getCell(CELL_NUM); - cell.setCellValue(NEW_VALUE); - workbook.write(pPart.getOutputStream()); - } - } - - // Finally, write the newly modified Word document out to file. - this.doc.write(new FileOutputStream(this.docFile)); - } - } - - /** - * Called to test whether or not the embedded workbook was correctly - * updated. This method simply recovers the first cell from the first row - * of the first workbook and tests the value it contains. - *

    - * Note that execution will not continue up to the assertion as the - * embedded workbook is now corrupted and causes an IllegalArgumentException - * with the following message - *

    - * java.lang.IllegalArgumentException: Your InputStream was neither an - * OLE2 stream, nor an OOXML stream - *

    - * to be thrown when the WorkbookFactory.createWorkbook(InputStream) method - * is executed. - * - * @throws org.apache.poi.openxml4j.exceptions.OpenXML4JException - * Rather - * than use the specific classes (HSSF/XSSF) to handle the embedded - * workbook this method uses those defeined in the SS stream. As - * a result, it might be the case that a SpreadsheetML file is - * opened for processing, throwing this exception if that file is - * invalid. - * @throws java.io.IOException Thrown if a problem occurs in the underlying - * file system. - */ - public void checkUpdatedDoc() throws OpenXML4JException, IOException { - Workbook workbook = null; - Sheet sheet = null; - Row row = null; - Cell cell = null; - PackagePart pPart = null; - Iterator pIter = null; - List embeddedDocs = this.doc.getAllEmbedds(); - if (embeddedDocs != null && !embeddedDocs.isEmpty()) { - pIter = embeddedDocs.iterator(); - while (pIter.hasNext()) { - pPart = pIter.next(); - if (pPart.getPartName().getExtension().equals(BINARY_EXTENSION) || - pPart.getPartName().getExtension().equals(OPENXML_EXTENSION)) { - workbook = WorkbookFactory.create(pPart.getInputStream()); - sheet = workbook.getSheetAt(SHEET_NUM); - row = sheet.getRow(ROW_NUM); - cell = row.getCell(CELL_NUM); - assertEquals(cell.getNumericCellValue(), NEW_VALUE, 0.0001); - } - } - } - } - - /** - * Code to test updating of the embedded Excel workbook. - * - * @param args - */ - public static void main(String[] args) { - try { - UpdateEmbeddedDoc ued = new UpdateEmbeddedDoc(args[0]); - ued.updateEmbeddedDoc(); - ued.checkUpdatedDoc(); - } catch (Exception ex) { - System.out.println(ex.getClass().getName()); - System.out.println(ex.getMessage()); - ex.printStackTrace(System.out); - } - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntEvaluateCell.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntEvaluateCell.java deleted file mode 100644 index bf1334848..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntEvaluateCell.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.poi.ss.excelant.util.ExcelAntEvaluationResult; -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; - -/** - * Instances of this class are used to evaluate a single cell. This is usually - * after some values have been set. The evaluation is actually performed - * by a WorkbookUtil instance. The evaluate() method of the WorkbookUtil - * class returns an EvaluationResult which encapsulates the results and - * information from the evaluation. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - - * - */ -public class ExcelAntEvaluateCell extends Task { - - private String cell ; - private double expectedValue ; - private double precision ; - private double precisionToUse ; - private double globalPrecision ; - private boolean requiredToPass = false ; - - - private ExcelAntEvaluationResult result ; - - private ExcelAntWorkbookUtil wbUtil ; - - private boolean showDelta = false ; - - - public ExcelAntEvaluateCell() {} - - protected void setWorkbookUtil( ExcelAntWorkbookUtil wb ) { - wbUtil = wb ; - } - - public void setShowDelta( boolean value ) { - showDelta = value ; - } - - protected boolean showDelta() { - return showDelta ; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public void setRequiredToPass( boolean val ) { - requiredToPass = val ; - } - - protected boolean requiredToPass() { - return requiredToPass ; - } - - public void setExpectedValue(double expectedValue) { - this.expectedValue = expectedValue; - } - - public void setPrecision(double precision) { - this.precision = precision; - } - - protected void setGlobalPrecision( double prec ) { - globalPrecision = prec ; - } - - protected String getCell() { - return cell; - } - - protected double getExpectedValue() { - return expectedValue; - } - - protected double getPrecision() { - return precisionToUse; - } - - @Override - public void execute() throws BuildException { - - precisionToUse = 0 ; - - // if there is a globalPrecision we will use it unless there is also - // precision set at the evaluate level, then we use that. If there - // is not a globalPrecision, we will use the local precision. - log( "test precision = " + precision + "\tglobal precision = " + globalPrecision, Project.MSG_VERBOSE ) ; - if( globalPrecision > 0 ) { - if( precision > 0 ) { - precisionToUse = precision ; - log( "Using evaluate precision of " + precision + " over the " + - "global precision of " + globalPrecision, Project.MSG_VERBOSE ) ; - } else { - precisionToUse = globalPrecision ; - log( "Using global precision of " + globalPrecision, Project.MSG_VERBOSE ) ; - } - } else { - precisionToUse = precision ; - log( "Using evaluate precision of " + precision, Project.MSG_VERBOSE ) ; - } - result = wbUtil.evaluateCell(cell, expectedValue, precisionToUse ) ; - - StringBuilder sb = new StringBuilder() ; - sb.append( "evaluation of cell " ) ; - sb.append( cell ) ; - sb.append( " resulted in " ) ; - sb.append( result.getReturnValue() ) ; - if(showDelta) { - sb.append(" with a delta of ").append(result.getDelta()); - } - - log( sb.toString(), Project.MSG_DEBUG) ; - - } - - public ExcelAntEvaluationResult getResult() { - return result ; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntHandlerTask.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntHandlerTask.java deleted file mode 100644 index 35f5420f0..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntHandlerTask.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; - -/** - * This is the class that backs the tag in the Ant task. - *

    - * Its purpose is to provide a way to manipulate a workbook in the course - * of an ExcelAnt task. The idea being to model a way for test writers to - * simulate the behaviors of the workbook. - *

    - * Suppose, for example, you have a workbook that has a worksheet that - * reacts to values entered or selected by the user. It's possible in - * Excel to change other cells based on this but this isn't easily possible - * in POI. In ExcelAnt we handle this using the Handler, which is a Java - * class you write to manipulate the workbook. - *

    - * In order to use this tag you must write a class that implements the - * IExcelAntWorkbookHandler interface. After writing the - * class you should package it and it's dependencies into a jar file to - * add as library in your Ant build file. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntHandlerTask extends Task { - - private String className ; - - private ExcelAntWorkbookUtil wbUtil ; - - public void setClassName( String cName ) { - className = cName ; - } - - protected void setEAWorkbookUtil( ExcelAntWorkbookUtil wkbkUtil ) { - wbUtil = wkbkUtil ; - } - - @Override - public void execute() throws BuildException { - log( "handling the workbook with class " + className, Project.MSG_INFO ) ; - try { - Class clazz = Class.forName( className ) ; - Object handlerObj = clazz.newInstance() ; - if( handlerObj instanceof IExcelAntWorkbookHandler ) { - IExcelAntWorkbookHandler iHandler = (IExcelAntWorkbookHandler)handlerObj ; - iHandler.setWorkbook( wbUtil.getWorkbook() ) ; - iHandler.execute() ; - } - } catch( Exception e ) { - throw new BuildException( e.getMessage(), e ) ; - } - } - } diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntPrecision.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntPrecision.java deleted file mode 100644 index 0739ef583..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntPrecision.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.tools.ant.taskdefs.Typedef; - -/** - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntPrecision extends Typedef { - - private double value ; - - public void setValue( double precision ) { - value = precision ; - } - - public double getValue() { - return value ; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSet.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSet.java deleted file mode 100644 index 974b1b9e4..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSet.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.tools.ant.Task; - -/** - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public abstract class ExcelAntSet extends Task { - - protected String cellStr ; - - protected ExcelAntWorkbookUtil wbUtil ; - - public void setCell( String cellName ) { - cellStr = cellName ; - } - - public String getCell() { - return cellStr ; - } - - - public void setWorkbookUtil( ExcelAntWorkbookUtil wb ) { - wbUtil = wb ; - } - -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetDoubleCell.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetDoubleCell.java deleted file mode 100644 index 2451a61e6..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetDoubleCell.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; - -/** - * Class for use in an Ant build script that sets the value of an Excel - * sheet cell using the cell id ('Sheet Name'!cellId). - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntSetDoubleCell extends ExcelAntSet { - private double cellValue; - - public ExcelAntSetDoubleCell() {} - - /** - * Set the value of the specified cell as the double passed in. - * @param value The double-value that should be set when this task is executed. - */ - public void setValue( double value ) { - cellValue = value ; - } - - /** - * Return the cell value as a double. - * @return The double-value of the cell as populated via setValue(), null - * if the value was not set yet. - */ - public double getCellValue() { - return cellValue; - } - - @Override - public void execute() throws BuildException { - wbUtil.setDoubleValue(cellStr, cellValue ) ; - - log( "set cell " + cellStr + " to value " + cellValue + " as double.", Project.MSG_DEBUG ) ; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetFormulaCell.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetFormulaCell.java deleted file mode 100644 index 8dc599b10..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetFormulaCell.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; - -/** - * Class for use in an Ant build script that sets the formula of an Excel - * sheet cell using the cell id ('Sheet Name'!cellId). - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntSetFormulaCell extends ExcelAntSet { - - - private String cellValue ; - - public ExcelAntSetFormulaCell() {} - - public void setValue( String value ) { - cellValue = value ; - } - - protected String getCellValue() { - return cellValue; - } - - @Override - public void execute() throws BuildException { - - wbUtil.setFormulaValue( cellStr, cellValue ) ; - - log( "set cell " + cellStr + " to formula " + cellValue, Project.MSG_DEBUG ) ; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetStringCell.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetStringCell.java deleted file mode 100644 index e1ab047fb..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntSetStringCell.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; - -/** - * Class for use in an Ant build script that sets the value of an Excel - * sheet cell using the cell id ('Sheet Name'!cellId). - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntSetStringCell extends ExcelAntSet { - private String stringValue ; - - public ExcelAntSetStringCell() {} - - /** - * Set the value of the cell to the String passed in. - * @param value The string-value that should be set when this task is executed. - */ - public void setValue(String value ) { - stringValue = value ; - } - - /** - * Return the value that will be set into the cell. - * @return The string-value of the cell as populated via setValue(), null - * if the value was not set yet. - */ - public String getCellValue() { - return stringValue; - } - - @Override - public void execute() throws BuildException { - wbUtil.setStringValue(cellStr, stringValue ) ; - - log( "set cell " + cellStr + " to value " + stringValue + " as String.", Project.MSG_DEBUG ) ; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTask.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTask.java deleted file mode 100644 index e9bb072e5..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTask.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.LinkedList; -import java.util.Locale; - -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtilFactory; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; - -/** - * Ant task class for testing Excel workbook cells. - */ -public class ExcelAntTask extends Task { - - public static final String VERSION = "0.5.0" ; - - private String excelFileName ; - - private boolean failOnError = false ; - - private ExcelAntWorkbookUtil workbookUtil ; - - private ExcelAntPrecision precision ; - - private LinkedList tests ; - private LinkedList functions ; - - public ExcelAntTask() { - tests = new LinkedList() ; - functions = new LinkedList() ; - } - - public void addPrecision( ExcelAntPrecision prec ) { - precision = prec ; - } - - public void setFailOnError( boolean value ) { - failOnError = value ; - } - public void setFileName( String fileName ) { - excelFileName = fileName ; - } - - public void addTest( ExcelAntTest testElement ) { - tests.add( testElement ) ; - } - - public void addUdf( ExcelAntUserDefinedFunction def ) { - functions.add( def ) ; - } - - @Override - public void execute() throws BuildException { - checkClassPath(); - - int totalCount = 0 ; - int successCount = 0 ; - - StringBuilder versionBffr = new StringBuilder() ; - versionBffr.append( "ExcelAnt version " ) ; - versionBffr.append( VERSION ) ; - versionBffr.append( " Copyright 2011" ) ; - SimpleDateFormat sdf = new SimpleDateFormat( "yyyy", Locale.ROOT ) ; - double currYear = Double.parseDouble( sdf.format( new Date() ) ); - if( currYear > 2011 ) { - versionBffr.append( "-" ) ; - versionBffr.append( currYear ) ; - } - log( versionBffr.toString(), Project.MSG_INFO ) ; - - log( "Using input file: " + excelFileName, Project.MSG_INFO ) ; - - workbookUtil = ExcelAntWorkbookUtilFactory.getInstance(excelFileName); - - for (ExcelAntTest test : tests) { - log("executing test: " + test.getName(), Project.MSG_DEBUG); - - if (workbookUtil == null) { - workbookUtil = ExcelAntWorkbookUtilFactory.getInstance(excelFileName); - } - - for (ExcelAntUserDefinedFunction eaUdf : functions) { - try { - workbookUtil.addFunction(eaUdf.getFunctionAlias(), eaUdf.getClassName()); - } catch (Exception e) { - throw new BuildException(e.getMessage(), e); - } - } - test.setWorkbookUtil(workbookUtil); - - if (precision != null && precision.getValue() > 0) { - log("setting precision for the test " + test.getName(), Project.MSG_VERBOSE); - test.setPrecision(precision.getValue()); - } - - test.execute(); - - if (test.didTestPass()) { - successCount++; - } else { - if (failOnError) { - throw new BuildException("Test " + test.getName() + " failed."); - } - } - totalCount++; - - workbookUtil = null; - } - - if( !tests.isEmpty() ) { - log( successCount + "/" + totalCount + " tests passed.", Project.MSG_INFO ); - } - workbookUtil = null; - } - - - /** - * ExcelAnt depends on external libraries not included in the Ant distribution. - * Give user a sensible message if any if the required jars are missing. - */ - private void checkClassPath(){ - try { - Class.forName("org.apache.poi.hssf.usermodel.HSSFWorkbook"); - Class.forName("org.apache.poi.ss.usermodel.WorkbookFactory"); - } catch (Exception e) { - throw new BuildException( - "The for must include poi.jar and poi-ooxml.jar " + - "if not in Ant's own classpath. Processing .xlsx spreadsheets requires " + - "additional poi-ooxml-schemas.jar, xmlbeans.jar" , - e, getLocation()); - } - - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTest.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTest.java deleted file mode 100644 index fd8f93091..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTest.java +++ /dev/null @@ -1,221 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import java.util.Iterator; -import java.util.LinkedList; - -import org.apache.poi.ss.excelant.util.ExcelAntEvaluationResult; -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; - -/** - * This class represents a single test. In order for the test any and all - * ExcelAntEvaluateCell evaluations must pass. Therefore it is recommended - * that you use only 1 evaluator but you can use more if you choose. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntTest extends Task{ - private LinkedList evaluators; - - private LinkedList testTasks; - - private String name; - - private double globalPrecision; - - private boolean showSuccessDetails = false; - - private boolean showFailureDetail = false; - LinkedList failureMessages; - - - private ExcelAntWorkbookUtil workbookUtil; - - private boolean passed = true; - - - public ExcelAntTest() { - evaluators = new LinkedList(); - failureMessages = new LinkedList(); - testTasks = new LinkedList(); - } - - public void setPrecision( double precision ) { - globalPrecision = precision; - } - - public void setWorkbookUtil( ExcelAntWorkbookUtil wbUtil ) { - workbookUtil = wbUtil; - } - - - public void setShowFailureDetail( boolean value ) { - showFailureDetail = value; - } - - public void setName( String nm ) { - name = nm; - } - - public String getName() { - return name; - } - - public void setShowSuccessDetails( boolean details ) { - showSuccessDetails = details; - } - - public boolean showSuccessDetails() { - return showSuccessDetails; - } - - public void addSetDouble( ExcelAntSetDoubleCell setter ) { - addSetter( setter ); - } - - public void addSetString( ExcelAntSetStringCell setter ){ - addSetter( setter ); - } - - public void addSetFormula( ExcelAntSetFormulaCell setter ) { - addSetter( setter ); - } - - public void addHandler( ExcelAntHandlerTask handler ) { - testTasks.add( handler ); - } - - private void addSetter( ExcelAntSet setter ) { -// setters.add( setter ); - testTasks.add( setter ); - } - - public void addEvaluate( ExcelAntEvaluateCell evaluator ) { -// evaluators.add( evaluator ); - testTasks.add( evaluator ); - } - -// public LinkedList getSetters() { -// return setters; -// } - - protected LinkedList getEvaluators() { - return evaluators; - } - - @Override - public void execute() throws BuildException { - - Iterator taskIt = testTasks.iterator(); - - int testCount = evaluators.size(); - int failureCount = 0; - - // roll over all sub task elements in one loop. This allows the - // ordering of the sub elements to be considered. - while( taskIt.hasNext() ) { - Task task = taskIt.next(); - - // log( task.getClass().getName(), Project.MSG_INFO ); - - if( task instanceof ExcelAntSet ) { - ExcelAntSet set = (ExcelAntSet) task; - set.setWorkbookUtil(workbookUtil); - set.execute(); - } - - if( task instanceof ExcelAntHandlerTask ) { - ExcelAntHandlerTask handler = (ExcelAntHandlerTask)task; - handler.setEAWorkbookUtil(workbookUtil ); - handler.execute(); - } - - if (task instanceof ExcelAntEvaluateCell ) { - ExcelAntEvaluateCell eval = (ExcelAntEvaluateCell)task; - eval.setWorkbookUtil( workbookUtil ); - - if( globalPrecision > 0 ) { - log( "setting globalPrecision to " + globalPrecision + " in the evaluator", Project.MSG_VERBOSE ); - eval.setGlobalPrecision( globalPrecision ); - } - - try { - eval.execute(); - ExcelAntEvaluationResult result = eval.getResult(); - if( result.didTestPass() && - !result.evaluationCompleteWithError()) { - if(showSuccessDetails) { - log("Succeeded when evaluating " + - result.getCellName() + ". It evaluated to " + - result.getReturnValue() + " when the value of " + - eval.getExpectedValue() + " with precision of " + - eval.getPrecision(), Project.MSG_INFO ); - } - } else { - if(showFailureDetail) { - failureMessages.add( "\tFailed to evaluate cell " + - result.getCellName() + ". It evaluated to " + - result.getReturnValue() + " when the value of " + - eval.getExpectedValue() + " with precision of " + - eval.getPrecision() + " was expected." ); - - } - passed = false; - failureCount++; - - if(eval.requiredToPass()) { - throw new BuildException( "\tFailed to evaluate cell " + - result.getCellName() + ". It evaluated to " + - result.getReturnValue() + " when the value of " + - eval.getExpectedValue() + " with precision of " + - eval.getPrecision() + " was expected." ); - } - } - } catch( NullPointerException npe ) { - // this means the cell reference in the test is bad. - log( "Cell assignment " + eval.getCell() + " in test " + getName() + - " appears to point to an empy cell. Please check the " + - " reference in the ant script.", Project.MSG_ERR ); - } - } - } - - if(!passed) { - log( "Test named " + name + " failed because " + failureCount + - " of " + testCount + " evaluations failed to " + - "evaluate correctly.", - Project.MSG_ERR ); - if(showFailureDetail && failureMessages.size() > 0 ) { - for (String failureMessage : failureMessages) { - log(failureMessage, Project.MSG_ERR); - } - } - } - } - - public boolean didTestPass() { - - return passed; - } - } diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntUserDefinedFunction.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntUserDefinedFunction.java deleted file mode 100644 index 5c19912b3..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/ExcelAntUserDefinedFunction.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.tools.ant.taskdefs.Typedef; - -/** - * This class encapsulates the Strings necessary to create the User Defined - * Function instances that will be passed to POI's Evaluator instance. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class ExcelAntUserDefinedFunction extends Typedef { - - - public String functionAlias ; - - public String className ; - - - public ExcelAntUserDefinedFunction() {} - - protected String getFunctionAlias() { - return functionAlias; - } - - public void setFunctionAlias(String functionAlias) { - this.functionAlias = functionAlias; - } - - protected String getClassName() { - // workaround for IBM JDK assigning the classname to the lowercase instance provided by Definer!?! - // I could not find out why that happens, the wrong assignment seems to be done somewhere deep inside Ant itself - // or even in IBM JDK as Oracle JDK does not have this problem. - if(className == null) { - return getClassname(); - } - - return className; - } - - public void setClassName(String className) { - this.className = className; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/IExcelAntWorkbookHandler.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/IExcelAntWorkbookHandler.java deleted file mode 100644 index 139e34c0d..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/IExcelAntWorkbookHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant; - -import org.apache.poi.ss.usermodel.Workbook; - - -/** - * In Excel there are many ways to handle manipulating a workbook based - * on some arbitrary user action (onChange, etc). You use this interface - * to create classes that will handle the workbook in whatever manner is needed - * that cannot be handled by POI. - *

    - * For example, suppose that in Excel when you update a cell the workbook - * does some calculations and updates other cells based on that change. In - * ExcelAnt you would set the value of the cell then write your own handler - * then call that from your Ant task after the set task. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public interface IExcelAntWorkbookHandler { - public void setWorkbook( Workbook workbook ) ; - - public void execute() ; -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntEvaluationResult.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntEvaluationResult.java deleted file mode 100644 index 4eecd4fae..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntEvaluationResult.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant.util; - -/** - * A simple class that encapsulates information about a cell evaluation - * from POI. - * - * @author Jon Svede (jon [at] loquatic [dot] com) - * @author Brian Bush (brian [dot] bush [at] nrel [dot] gov) - * - */ -public class ExcelAntEvaluationResult { - - /** - * This boolean flag is used to determine if the evaluation completed - * without error. This alone doesn't ensure that the evaluation was - * successful. - */ - private boolean evaluationCompletedWithError ; - - /** - * This boolean flag is used to determine if the result was within - * the specified precision. - */ - private boolean didPass ; - - /** - * This is the actual value returned from the evaluation. - */ - private double returnValue ; - - /** - * Any error message String values that need to be returned. - */ - private String errorMessage ; - - /** - * Stores the absolute value of the delta for this evaluation. - */ - private double actualDelta ; - - /** - * This stores the fully qualified cell name (sheetName!cellId). - */ - private String cellName ; - - - - public ExcelAntEvaluationResult(boolean completedWithError, - boolean passed, - double retValue, - String errMessage, - double delta, - String cellId) { - - evaluationCompletedWithError = completedWithError; - didPass = passed; - returnValue = retValue; - errorMessage = errMessage; - actualDelta = delta ; - cellName = cellId ; - } - - public double getReturnValue() { - return returnValue; - } - - public String getErrorMessage() { - return errorMessage; - } - - public boolean didTestPass() { - return didPass ; - } - - public boolean evaluationCompleteWithError() { - return evaluationCompletedWithError ; - } - - public double getDelta() { - return actualDelta ; - } - - public String getCellName() { - return cellName ; - } - - @Override - public String toString() { - return "ExcelAntEvaluationResult [evaluationCompletedWithError=" - + evaluationCompletedWithError + ", didPass=" + didPass - + ", returnValue=" + returnValue + ", errorMessage=" - + errorMessage + ", actualDelta=" + actualDelta + ", cellName=" - + cellName + "]"; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtil.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtil.java deleted file mode 100644 index dcb30a84c..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtil.java +++ /dev/null @@ -1,386 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant.util; - -import java.io.File; -import java.io.FileInputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.udf.AggregatingUDFFinder; -import org.apache.poi.ss.formula.udf.DefaultUDFFinder; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.Typedef; - -/** - * A general utility class that abstracts the POI details of loading the - * workbook, accessing and updating cells. - * - * @author Jon Svede (jon [at] loquatic [dot] com) - * @author Brian Bush (brian [dot] bush [at] nrel [dot] gov) - * - */ -public class ExcelAntWorkbookUtil extends Typedef { - - private String excelFileName; - - private Workbook workbook; - - private final Map xlsMacroList = new HashMap(); - - /** - * Constructs an instance using a String that contains the fully qualified - * path of the Excel file. This constructor initializes a Workbook instance - * based on that file name. - * - * @param fName The fully qualified path of the Excel file. - * @throws BuildException If the workbook cannot be loaded. - */ - protected ExcelAntWorkbookUtil(String fName) { - excelFileName = fName; - loadWorkbook(); - - } - - /** - * Constructs an instance based on a Workbook instance. - * - * @param wb The Workbook to use for this instance. - */ - protected ExcelAntWorkbookUtil(Workbook wb) { - workbook = wb; - } - - /** - * Loads the member variable workbook based on the fileName variable. - * @return The opened Workbook-instance - * @throws BuildException If the workbook cannot be loaded. - */ - private Workbook loadWorkbook() { - if (excelFileName == null) { - throw new BuildException("fileName attribute must be set!", getLocation()); - } - - try { - FileInputStream fis = new FileInputStream(excelFileName); - try { - workbook = WorkbookFactory.create(fis); - } finally { - fis.close(); - } - } catch(Exception e) { - throw new BuildException("Cannot load file " + excelFileName - + ". Make sure the path and file permissions are correct.", e); - } - - return workbook; - } - - /** - * Used to add a UDF to the evaluator. - * @param name - * @param clazzName - * @throws ClassNotFoundException - * @throws InstantiationException - * @throws IllegalAccessException - */ - public void addFunction(String name, String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { - Class clazzInst = Class.forName(clazzName); - Object newInst = clazzInst.newInstance(); - if(newInst instanceof FreeRefFunction) { - addFunction(name, (FreeRefFunction)newInst); - } - - } - - /** - * Updates the internal HashMap of functions with instance and alias passed - * in. - * - * @param name - * @param func - */ - protected void addFunction(String name, FreeRefFunction func) { - xlsMacroList.put(name, func); - } - - /** - * returns a UDFFinder that contains all of the functions added. - * - * @return - */ - protected UDFFinder getFunctions() { - - String[] names = new String[xlsMacroList.size()]; - FreeRefFunction[] functions = new FreeRefFunction[xlsMacroList.size()]; - - int x = 0; - for(Map.Entry entry : xlsMacroList.entrySet()) { - names[x] = entry.getKey(); - functions[x] = entry.getValue(); - } - - UDFFinder udff1 = new DefaultUDFFinder(names, functions); - UDFFinder udff = new AggregatingUDFFinder(udff1); - - return udff; - - } - - /** - * Returns a formula evaluator that is loaded with the functions that - * have been supplied. - * - * @param fileName - * @return - */ - protected FormulaEvaluator getEvaluator(String fileName) { - FormulaEvaluator evaluator; - if (fileName.endsWith(".xlsx")) { - if(xlsMacroList.size() > 0) { - evaluator = XSSFFormulaEvaluator.create((XSSFWorkbook) workbook, - null, - getFunctions()); - } - evaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook); - } else { - if(xlsMacroList.size() > 0) { - evaluator = HSSFFormulaEvaluator.create((HSSFWorkbook)workbook, - null, - getFunctions()); - } - - evaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook); - } - - return evaluator; - - } - - /** - * Returns the Workbook instance associated with this WorkbookUtil. - * - * @return - */ - public Workbook getWorkbook() { - return workbook; - } - - /** - * Returns the fileName that was used to initialize this instance. May - * return null if the instance was constructed from a Workbook object. - * - * @return - */ - public String getFileName() { - return excelFileName; - } - - /** - * Returns the list of sheet names. - * - * @return - */ - public List getSheets() { - ArrayList sheets = new ArrayList(); - - int sheetCount = workbook.getNumberOfSheets(); - - for(int x=0; x precision) { - evalResults = new ExcelAntEvaluationResult(false, false, - resultOfEval.getNumberValue(), - "Results was out of range based on precision " + " of " - + precision + ". Delta was actually " + delta, delta, cellName); - } else { - evalResults = new ExcelAntEvaluationResult(false, true, - resultOfEval.getNumberValue(), - "Evaluation passed without error within in range.", delta, cellName); - } - } else { - String errorMeaning = null; - try { - errorMeaning = FormulaError.forInt(resultOfEval.getErrorValue()).getString(); - } catch(IllegalArgumentException iae) { - errorMeaning = "unknown error code: " + - Byte.toString(resultOfEval.getErrorValue()); - } - - evalResults = new ExcelAntEvaluationResult(true, false, - resultOfEval.getNumberValue(), - "Evaluation failed due to an evaluation error of " - + resultOfEval.getErrorValue() - + " which is " - + errorMeaning, 0, cellName); - } - - return evalResults; - } - - /** - * Returns a Cell as a String value. - * - * @param cellName - * @return - */ - public String getCellAsString(String cellName) { - Cell cell = getCell(cellName); - return cell.getStringCellValue(); - } - - - /** - * Returns the value of the Cell as a double. - * - * @param cellName - * @return - */ - public double getCellAsDouble(String cellName) { - Cell cell = getCell(cellName); - return cell.getNumericCellValue(); - } - /** - * Returns a cell reference based on a String in standard Excel format - * (SheetName!CellId). This method will create a new cell if the - * requested cell isn't initialized yet. - * - * @param cellName - * @return - */ - private Cell getCell(String cellName) { - CellReference cellRef = new CellReference(cellName); - String sheetName = cellRef.getSheetName(); - Sheet sheet = workbook.getSheet(sheetName); - if(sheet == null) { - throw new BuildException("Sheet not found: " + sheetName); - } - - int rowIdx = cellRef.getRow(); - int colIdx = cellRef.getCol(); - Row row = sheet.getRow(rowIdx); - - if(row == null) { - row = sheet.createRow(rowIdx); - } - - Cell cell = row.getCell(colIdx); - - if(cell == null) { - cell = row.createCell(colIdx); - } - - return cell; - } -} diff --git a/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtilFactory.java b/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtilFactory.java deleted file mode 100644 index 08e7fb3d9..000000000 --- a/trunk/src/excelant/java/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtilFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.excelant.util; - -import java.util.HashMap; -import java.util.Map; - - -/** - * This is a factory class maps file names to WorkbookUtil instances. This - * helps ExcelAnt be more efficient when being run many times in an Ant build. - * - * @author Jon Svede (jon [at] loquatic [dot] com) - * @author Brian Bush (brian [dot] bush [at] nrel [dot] gov) - * - */ -public final class ExcelAntWorkbookUtilFactory { - - private static Map workbookUtilMap; - - private ExcelAntWorkbookUtilFactory() { - } - - /** - * Using the fileName, check the internal map to see if an instance - * of the WorkbookUtil exists. If not, then add an instance to the map. - * - * @param fileName The filename to use as key to look for the ExcelAntWorkbookUtil. - * @return An instance of ExcelAntWorkbookUtil associated with the filename or - * a freshly instantiated one if none did exist before. - */ - public static ExcelAntWorkbookUtil getInstance(String fileName) { - if(workbookUtilMap == null) { - workbookUtilMap = new HashMap(); - } - - if(workbookUtilMap.containsKey(fileName)) { - return workbookUtilMap.get(fileName); - } - - ExcelAntWorkbookUtil wbu = new ExcelAntWorkbookUtil(fileName); - workbookUtilMap.put(fileName, wbu); - return wbu; - } -} diff --git a/trunk/src/excelant/resources/org/apache/poi/ss/excelant/antlib.xml b/trunk/src/excelant/resources/org/apache/poi/ss/excelant/antlib.xml deleted file mode 100644 index af13cc649..000000000 --- a/trunk/src/excelant/resources/org/apache/poi/ss/excelant/antlib.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/CalculateMortgageFunction.java b/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/CalculateMortgageFunction.java deleted file mode 100644 index f1c526bf9..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/CalculateMortgageFunction.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.formula; - -import org.apache.poi.ss.formula.OperationEvaluationContext ; -import org.apache.poi.ss.formula.eval.ErrorEval ; -import org.apache.poi.ss.formula.eval.EvaluationException ; -import org.apache.poi.ss.formula.eval.NumberEval ; -import org.apache.poi.ss.formula.eval.OperandResolver ; -import org.apache.poi.ss.formula.eval.ValueEval ; -import org.apache.poi.ss.formula.functions.FreeRefFunction ; - -/** - * A simple user-defined function to calculate principal and interest. - * - * Used by {@link org.apache.poi.ss.excelant.util.TestExcelAntWorkbookUtil}. - * - * @author Jon Svede ( jon [at] loquatic [dot] com ) - * @author Brian Bush ( brian [dot] bush [at] nrel [dot] gov ) - * - */ -public class CalculateMortgageFunction implements FreeRefFunction { - - @Override - public ValueEval evaluate( ValueEval[] args, OperationEvaluationContext ec ) { - - // verify that we have enough data - if (args.length != 3) { - return ErrorEval.VALUE_INVALID; - } - - // declare doubles for values - double principal, rate, years, result; - try { - // extract values as ValueEval - ValueEval v1 = OperandResolver.getSingleValue( args[0], - ec.getRowIndex(), - ec.getColumnIndex() ) ; - ValueEval v2 = OperandResolver.getSingleValue( args[1], - ec.getRowIndex(), - ec.getColumnIndex() ) ; - ValueEval v3 = OperandResolver.getSingleValue( args[2], - ec.getRowIndex(), - ec.getColumnIndex() ) ; - - // get data as doubles - principal = OperandResolver.coerceValueToDouble( v1 ) ; - rate = OperandResolver.coerceValueToDouble( v2 ) ; - years = OperandResolver.coerceValueToDouble( v3 ) ; - - result = calculateMortgagePayment( principal, rate, years ) ; - System.out.println( "Result = " + result ) ; - - checkValue(result); - - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return new NumberEval( result ) ; - } - - public double calculateMortgagePayment( double p, double r, double y ) { - double i = r / 12 ; - double n = y * 12 ; - - double principalAndInterest = - p * (( i * Math.pow((1 + i),n ) ) / ( Math.pow((1 + i),n) - 1)) ; - - return principalAndInterest ; - } - /** - * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases - * - * @throws EvaluationException (#NUM!) if result is NaN or Infinity - */ - private void checkValue(double result) throws EvaluationException { - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - } -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/ExcelAntUserDefinedFunctionTestHelper.java b/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/ExcelAntUserDefinedFunctionTestHelper.java deleted file mode 100644 index 68e4b6957..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/ExcelAntUserDefinedFunctionTestHelper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.formula; - -import org.apache.poi.ss.excelant.ExcelAntUserDefinedFunction; - -public class ExcelAntUserDefinedFunctionTestHelper extends - ExcelAntUserDefinedFunction { - - @Override - protected String getFunctionAlias() { - // TODO Auto-generated method stub - return super.getFunctionAlias(); - } - - @Override - protected String getClassName() { - // TODO Auto-generated method stub - return super.getClassName(); - } - -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/TestExcelAntUserDefinedFunction.java b/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/TestExcelAntUserDefinedFunction.java deleted file mode 100644 index ad9851ae8..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/examples/formula/TestExcelAntUserDefinedFunction.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.examples.formula; - -import junit.framework.TestCase; - -public class TestExcelAntUserDefinedFunction extends TestCase { - - private ExcelAntUserDefinedFunctionTestHelper fixture ; - - @Override - public void setUp() { - fixture = new ExcelAntUserDefinedFunctionTestHelper() ; - } - - public void testSetClassName() { - String className = "simple.class.name" ; - - fixture.setClassName( className ) ; - String value = fixture.getClassName() ; - - assertNotNull( value ) ; - assertEquals( className, value ) ; - } - - public void testSetFunction() { - String functionAlias = "alias" ; - - fixture.setFunctionAlias( functionAlias ) ; - - String alias = fixture.getFunctionAlias() ; - - assertNotNull( alias ) ; - assertEquals( functionAlias, alias ) ; - } - -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/BuildFileTest.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/BuildFileTest.java deleted file mode 100644 index 55ea77787..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/BuildFileTest.java +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.poi.ss.excelant; - -import java.io.File; -import java.io.PrintStream; -import java.net.URL; - -import junit.framework.TestCase; - -import org.apache.poi.POIDataSamples; -import org.apache.tools.ant.BuildEvent; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.BuildListener; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.ProjectHelper; - -/** - * A BuildFileTest is a TestCase which executes targets from an Ant buildfile - * for testing. - *

    - * This class provides a number of utility methods for particular build file - * tests which extend this class. - * - * @see - * http://svn.apache.org/repos/asf/ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java - */ -public abstract class BuildFileTest extends TestCase { - - protected Project project; - - private StringBuffer logBuffer; - private StringBuffer fullLogBuffer; - private StringBuffer outBuffer; - private StringBuffer errBuffer; - private BuildException buildException; - - /** - * Default constructor for the BuildFileTest object. - */ - public BuildFileTest() { - super(); - } - - /** - * Constructor for the BuildFileTest object. - * - * @param name string to pass up to TestCase constructor - */ - public BuildFileTest(String name) { - super(name); - } - - /** - * Automatically calls the target called "tearDown" - * from the build file tested if it exits. - *

    - * This allows to use Ant tasks directly in the build file - * to clean up after each test. Note that no "setUp" target - * is automatically called, since it's trivial to have a - * test target depend on it. - */ - @Override - protected void tearDown() throws Exception { - if (project == null) { - /* - * Maybe the BuildFileTest was subclassed and there is - * no initialized project. So we could avoid getting a - * NPE. - * If there is an initialized project getTargets() does - * not return null as it is initialized by an empty - * HashSet. - */ - return; - } - final String tearDown = "tearDown"; - if (project.getTargets().containsKey(tearDown)) { - project.executeTarget(tearDown); - } - } - - /** - * run a target, expect for any build exception - * - * @param target target to run - * @param cause information string to reader of report - */ - public void expectBuildException(String target, String cause) { - expectSpecificBuildException(target, cause, null); - } - - /** - * Assert that only the given message has been logged with a - * priority <= INFO when running the given target. - */ - public void expectLog(String target, String log) { - executeTarget(target); - String realLog = getLog(); - assertEquals(log, realLog); - } - - /** - * Assert that the given substring is in the log messages. - */ - public void assertLogContaining(String substring) { - String realLog = getLog(); - assertTrue("expecting log to contain \"" + substring + "\" log was \"" - + realLog + "\"", - realLog.indexOf(substring) >= 0); - } - - /** - * Assert that the given substring is not in the log messages. - */ - public void assertLogNotContaining(String substring) { - String realLog = getLog(); - assertFalse("didn't expect log to contain \"" + substring + "\" log was \"" - + realLog + "\"", - realLog.indexOf(substring) >= 0); - } - - /** - * Assert that the given substring is in the output messages. - * - * @since Ant1.7 - */ - public void assertOutputContaining(String substring) { - assertOutputContaining(null, substring); - } - - /** - * Assert that the given substring is in the output messages. - * - * @param message Print this message if the test fails. Defaults to - * a meaningful text if null is passed. - * @since Ant1.7 - */ - public void assertOutputContaining(String message, String substring) { - String realOutput = getOutput(); - String realMessage = (message != null) - ? message - : "expecting output to contain \"" + substring + "\" output was \"" + realOutput + "\""; - assertTrue(realMessage, realOutput.indexOf(substring) >= 0); - } - - /** - * Assert that the given substring is not in the output messages. - * - * @param message Print this message if the test fails. Defaults to - * a meaningful text if null is passed. - * @since Ant1.7 - */ - public void assertOutputNotContaining(String message, String substring) { - String realOutput = getOutput(); - String realMessage = (message != null) - ? message - : "expecting output to not contain \"" + substring + "\" output was \"" + realOutput + "\""; - assertFalse(realMessage, realOutput.indexOf(substring) >= 0); - } - - /** - * Assert that the given message has been logged with a priority <= INFO when running the - * given target. - */ - public void expectLogContaining(String target, String log) { - executeTarget(target); - assertLogContaining(log); - } - - /** - * Assert that the given message has not been logged with a - * priority <= INFO when running the given target. - */ - public void expectLogNotContaining(String target, String log) { - executeTarget(target); - assertLogNotContaining(log); - } - - /** - * Gets the log the BuildFileTest object. - * Only valid if configureProject() has been called. - * - * @return The log value - * @pre logBuffer!=null - */ - public String getLog() { - return logBuffer.toString(); - } - - /** - * Assert that the given message has been logged with a priority - * >= VERBOSE when running the given target. - */ - public void expectDebuglog(String target, String log) { - executeTarget(target); - String realLog = getFullLog(); - assertEquals(log, realLog); - } - - /** - * Assert that the given substring is in the log messages. - */ - public void assertDebuglogContaining(String substring) { - String realLog = getFullLog(); - assertTrue("expecting debug log to contain \"" + substring - + "\" log was \"" - + realLog + "\"", - realLog.indexOf(substring) >= 0); - } - - /** - * Gets the log the BuildFileTest object. - *

    - * Only valid if configureProject() has been called. - * - * @return The log value - * @pre fullLogBuffer!=null - */ - public String getFullLog() { - return fullLogBuffer.toString(); - } - - /** - * execute the target, verify output matches expectations - * - * @param target target to execute - * @param output output to look for - */ - public void expectOutput(String target, String output) { - executeTarget(target); - String realOutput = getOutput(); - assertEquals(output, realOutput.trim()); - } - - /** - * Executes the target, verify output matches expectations - * and that we got the named error at the end - * - * @param target target to execute - * @param output output to look for - * @param error Description of Parameter - */ - public void expectOutputAndError(String target, String output, String error) { - executeTarget(target); - String realOutput = getOutput(); - assertEquals(output, realOutput); - String realError = getError(); - assertEquals(error, realError); - } - - public String getOutput() { - return cleanBuffer(outBuffer); - } - - public String getError() { - return cleanBuffer(errBuffer); - } - - public BuildException getBuildException() { - return buildException; - } - - private String cleanBuffer(StringBuffer buffer) { - StringBuffer cleanedBuffer = new StringBuffer(); - for (int i = 0; i < buffer.length(); i++) { - char ch = buffer.charAt(i); - if (ch != '\r') { - cleanedBuffer.append(ch); - } - } - return cleanedBuffer.toString(); - } - - /** - * Sets up to run the named project - * - * @param filename name of project file to run - */ - public void configureProject(String filename) throws BuildException { - configureProject(filename, Project.MSG_DEBUG); - } - - /** - * Sets up to run the named project - * - * @param filename name of project file to run - */ - public void configureProject(String filename, int logLevel) - throws BuildException { - logBuffer = new StringBuffer(); - fullLogBuffer = new StringBuffer(); - project = new Project(); - project.init(); - project.setNewProperty("data.dir.name", getDataDir()); - File antFile = new File(System.getProperty("root"), filename); - project.setUserProperty("ant.file", antFile.getAbsolutePath()); - project.addBuildListener(new AntTestListener(logLevel)); - ProjectHelper.configureProject(project, antFile); - } - - /** - * Executes a target we have set up - * - * @param targetName target to run - * @pre configureProject has been called - */ - public void executeTarget(String targetName) { - PrintStream sysOut = System.out; - PrintStream sysErr = System.err; - try { - sysOut.flush(); - sysErr.flush(); - outBuffer = new StringBuffer(); - PrintStream out = new PrintStream(new AntOutputStream(outBuffer)); - System.setOut(out); - errBuffer = new StringBuffer(); - PrintStream err = new PrintStream(new AntOutputStream(errBuffer)); - System.setErr(err); - logBuffer = new StringBuffer(); - fullLogBuffer = new StringBuffer(); - buildException = null; - project.executeTarget(targetName); - } finally { - System.setOut(sysOut); - System.setErr(sysErr); - } - - } - - /** - * Get the project which has been configured for a test. - * - * @return the Project instance for this test. - */ - public Project getProject() { - return project; - } - - /** - * Gets the directory of the project. - * - * @return the base dir of the project - */ - public File getProjectDir() { - return project.getBaseDir(); - } - - /** - * Runs a target, wait for a build exception. - * - * @param target target to run - * @param cause information string to reader of report - * @param msg the message value of the build exception we are waiting - * for set to null for any build exception to be valid - */ - public void expectSpecificBuildException(String target, String cause, String msg) { - try { - executeTarget(target); - } catch (org.apache.tools.ant.BuildException ex) { - buildException = ex; - if ((null != msg) && (!ex.getMessage().equals(msg))) { - fail("Should throw BuildException because '" + cause - + "' with message '" + msg - + "' (actual message '" + ex.getMessage() + "' instead)"); - } - return; - } - fail("Should throw BuildException because: " + cause); - } - - /** - * run a target, expect an exception string - * containing the substring we look for (case sensitive match) - * - * @param target target to run - * @param cause information string to reader of report - * @param contains substring of the build exception to look for - */ - public void expectBuildExceptionContaining(String target, String cause, String contains) { - try { - executeTarget(target); - } catch (org.apache.tools.ant.BuildException ex) { - buildException = ex; - if ((null != contains) && (ex.getMessage().indexOf(contains) == -1)) { - fail("Should throw BuildException because '" + cause + "' with message containing '" + contains + "' (actual message '" + ex.getMessage() + "' instead)"); - } - return; - } - fail("Should throw BuildException because: " + cause); - } - - /** - * call a target, verify property is as expected - * - * @param target build file target - * @param property property name - * @param value expected value - */ - public void expectPropertySet(String target, String property, String value) { - executeTarget(target); - assertPropertyEquals(property, value); - } - - /** - * assert that a property equals a value; comparison is case sensitive. - * - * @param property property name - * @param value expected value - */ - public void assertPropertyEquals(String property, String value) { - String result = project.getProperty(property); - assertEquals("property " + property, value, result); - } - - /** - * assert that a property equals "true". - * - * @param property property name - */ - public void assertPropertySet(String property) { - assertPropertyEquals(property, "true"); - } - - /** - * assert that a property is null. - * - * @param property property name - */ - public void assertPropertyUnset(String property) { - String result = project.getProperty(property); - if (result != null) { - fail("Expected property " + property - + " to be unset, but it is set to the value: " + result); - } - } - - /** - * call a target, verify named property is "true". - * - * @param target build file target - * @param property property name - */ - public void expectPropertySet(String target, String property) { - expectPropertySet(target, property, "true"); - } - - /** - * Call a target, verify property is null. - * - * @param target build file target - * @param property property name - */ - public void expectPropertyUnset(String target, String property) { - expectPropertySet(target, property, null); - } - - /** - * Retrieve a resource from the caller classloader to avoid - * assuming a vm working directory. The resource path must be - * relative to the package name or absolute from the root path. - * - * @param resource the resource to retrieve its url. - * @throws junit.framework.AssertionFailedError - * if the resource is not found. - */ - public URL getResource(String resource) { - URL url = getClass().getResource(resource); - assertNotNull("Could not find resource :" + resource, url); - return url; - } - - public static String getDataDir() { - String dataDirName = System.getProperty(POIDataSamples.TEST_PROPERTY); - return dataDirName == null ? "test-data" : dataDirName; - } - - /** - * an output stream which saves stuff to our buffer. - */ - protected static class AntOutputStream extends java.io.OutputStream { - private StringBuffer buffer; - - public AntOutputStream(StringBuffer buffer) { - this.buffer = buffer; - } - - @Override - public void write(int b) { - buffer.append((char) b); - } - } - - /** - * Our own personal build listener. - */ - private class AntTestListener implements BuildListener { - private int logLevel; - - /** - * Constructs a test listener which will ignore log events - * above the given level. - */ - public AntTestListener(int logLevel) { - this.logLevel = logLevel; - } - - /** - * Fired before any targets are started. - */ - @Override - public void buildStarted(BuildEvent event) { - } - - /** - * Fired after the last target has finished. This event - * will still be thrown if an error occurred during the build. - * - * @see BuildEvent#getException() - */ - @Override - public void buildFinished(BuildEvent event) { - } - - /** - * Fired when a target is started. - * - * @see BuildEvent#getTarget() - */ - @Override - public void targetStarted(BuildEvent event) { - //System.out.println("targetStarted " + event.getTarget().getName()); - } - - /** - * Fired when a target has finished. This event will - * still be thrown if an error occurred during the build. - * - * @see BuildEvent#getException() - */ - @Override - public void targetFinished(BuildEvent event) { - //System.out.println("targetFinished " + event.getTarget().getName()); - } - - /** - * Fired when a task is started. - * - * @see BuildEvent#getTask() - */ - @Override - public void taskStarted(BuildEvent event) { - //System.out.println("taskStarted " + event.getTask().getTaskName()); - } - - /** - * Fired when a task has finished. This event will still - * be throw if an error occurred during the build. - * - * @see BuildEvent#getException() - */ - @Override - public void taskFinished(BuildEvent event) { - //System.out.println("taskFinished " + event.getTask().getTaskName()); - } - - /** - * Fired whenever a message is logged. - * - * @see BuildEvent#getMessage() - * @see BuildEvent#getPriority() - */ - @Override - public void messageLogged(BuildEvent event) { - if (event.getPriority() > logLevel) { - // ignore event - return; - } - - if (event.getPriority() == Project.MSG_INFO || - event.getPriority() == Project.MSG_WARN || - event.getPriority() == Project.MSG_ERR) { - logBuffer.append(event.getMessage()); - } - fullLogBuffer.append(event.getMessage()); - } - } - -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/MockExcelAntWorkbookHandler.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/MockExcelAntWorkbookHandler.java deleted file mode 100644 index 6e52e1d4b..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/MockExcelAntWorkbookHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.poi.ss.excelant; - -import static org.junit.Assert.assertNotNull; - -import org.apache.poi.ss.usermodel.Workbook; - -public class MockExcelAntWorkbookHandler implements IExcelAntWorkbookHandler { - public static boolean executed = false; - public static Workbook workbook = null; - - - @Override - public void setWorkbook(Workbook workbook) { - MockExcelAntWorkbookHandler.workbook = workbook; - } - - @Override - public void execute() { - executed = true; - assertNotNull(workbook); - } -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestBuildFile.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestBuildFile.java deleted file mode 100644 index df1993be0..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestBuildFile.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.poi.ss.excelant; - - -/** - * JUnit test for the ExcelAnt tasks. - * Leverages Ant's test framework. - * - * @see - * http://svn.apache.org/repos/asf/ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java - */ -public class TestBuildFile extends BuildFileTest { - - @Override - public void setUp() { - configureProject(BuildFileTest.getDataDir() + "/../src/excelant/testcases/org/apache/poi/ss/excelant/tests.xml"); - } - - public void testMissingFilename() { - expectSpecificBuildException("test-nofile", "required argument not specified", - "fileName attribute must be set!"); - } - - public void testFileNotFound() { - expectSpecificBuildException("test-filenotfound", "required argument not specified", - "Cannot load file invalid.xls. Make sure the path and file permissions are correct."); - } - - public void testEvaluate() { - executeTarget("test-evaluate"); - assertLogContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4."); - } - - public void testEvaluateNoDetails() { - executeTarget("test-evaluate-nodetails"); - assertLogContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogNotContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4."); - } - - public void testPrecision() { - executeTarget("test-precision"); - - assertLogContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4. " + - "It evaluated to 2285.5761494145563 when the value of 2285.576149 with precision of 1.0E-4"); - assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4. " + - "It evaluated to 2285.5761494145563 when the value of 2285.576149 with precision of 1.0E-5"); - assertLogContaining("Failed to evaluate cell 'MortgageCalculator'!$B$4. " + - "It evaluated to 2285.5761494145563 when the value of 2285.576149 with precision of 1.0E-10 was expected."); - assertLogContaining("2/3 tests passed"); - } - - public void testPrecisionFail() { - expectSpecificBuildException("test-precision-fails", "precision not matched", - "\tFailed to evaluate cell 'MortgageCalculator'!$B$4. It evaluated to 2285.5761494145563 when the value of 2285.576149 with precision of 1.0E-10 was expected."); - } - - public void testPassOnError() { - executeTarget("test-passonerror"); - } - - public void testFailOnError() { - expectBuildException("test-failonerror", "fail on error"); - assertLogContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogNotContaining("failed because 1 of 0 evaluations failed to evaluate correctly. Failed to evaluate cell 'MortageCalculatorFunction'!$D$3"); - } - - public void testFailOnErrorNoDetails() { - expectBuildException("test-failonerror-nodetails", "fail on error"); - assertLogNotContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogNotContaining("failed because 1 of 0 evaluations failed to evaluate correctly. Failed to evaluate cell 'MortageCalculatorFunction'!$D$3"); - } - - public void testUdf() { - executeTarget("test-udf"); - assertLogContaining("1/1 tests passed"); - } - - public void testSetText() { - executeTarget("test-settext"); - assertLogContaining("1/1 tests passed"); - } - - public void testAddHandler() { - executeTarget("test-addhandler"); - assertLogContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4."); - - assertNotNull("The workbook should have been passed to the handler", MockExcelAntWorkbookHandler.workbook); - assertTrue("The handler should have been executed", MockExcelAntWorkbookHandler.executed); - } - - public void testAddHandlerWrongClass() { - executeTarget("test-addhandler-wrongclass"); - assertLogContaining("Using input file: " + BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls"); - assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4."); - } - - public void testAddHandlerFails() { - expectSpecificBuildException("test-addhandler-fails", "NullPointException", null); - } -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntPrecision.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntPrecision.java deleted file mode 100644 index 0c6f9cbf8..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntPrecision.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant; - -import junit.framework.TestCase; - -public class TestExcelAntPrecision extends TestCase { - - private ExcelAntPrecision fixture ; - - @Override - public void setUp() { - fixture = new ExcelAntPrecision() ; - } - - @Override - public void tearDown() { - fixture = null ; - } - - public void testVerifyPrecision() { - - double value = 1.0E-1 ; - - fixture.setValue( value ) ; - - double result = fixture.getValue() ; - - assertTrue( result > 0 ) ; - - assertEquals( value, result, 0.0 ) ; - } - -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntSet.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntSet.java deleted file mode 100644 index b59c886ae..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntSet.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant; - -import junit.framework.TestCase; - -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtilFactory; - -public class TestExcelAntSet extends TestCase { - - - // This is abstract in nature, so we'll use a - // concrete instance to test the set methods. - private ExcelAntSet fixture ; - - private static final String mortgageCalculatorFileName = - BuildFileTest.getDataDir() + "/spreadsheet/mortgage-calculation.xls" ; - - @Override - public void setUp() { - fixture = new ExcelAntSetDoubleCell() ; - } - - @Override - public void tearDown() { - fixture = null ; - } - - public void testSetter() { - String cell = "simpleCellRef!$F$1" ; - - fixture.setCell( cell ) ; - - String cellStr = fixture.getCell() ; - - assertNotNull( cellStr ) ; - assertEquals( cell, cellStr ) ; - } - - public void testSetWorkbookUtil() { - ExcelAntWorkbookUtil util = ExcelAntWorkbookUtilFactory.getInstance( - mortgageCalculatorFileName ) ; - - assertNotNull( util ) ; - - fixture.setWorkbookUtil( util ) ; - } -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntSetDoubleCell.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntSetDoubleCell.java deleted file mode 100644 index 3d5b11ef4..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/TestExcelAntSetDoubleCell.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant; - -import junit.framework.TestCase; - -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtil; -import org.apache.poi.ss.excelant.util.ExcelAntWorkbookUtilFactory; - -public class TestExcelAntSetDoubleCell extends TestCase { - - private ExcelAntSetDoubleCell fixture ; - - private ExcelAntWorkbookUtil util ; - - private static final String mortgageCalculatorFileName = - BuildFileTest.getDataDir() + "/spreadsheet/mortgage-calculation.xls" ; - - @Override - public void setUp() { - fixture = new ExcelAntSetDoubleCell() ; - util = ExcelAntWorkbookUtilFactory.getInstance( - mortgageCalculatorFileName ) ; - fixture.setWorkbookUtil( util ) ; - } - - @Override - public void tearDown() { - fixture = null ; - } - - public void testSetDouble() { - String cellId = "'Sheet3'!$A$1" ; - double testValue = 1.1 ; - - fixture.setCell( cellId ) ; - fixture.setValue( testValue ) ; - - double value = fixture.getCellValue() ; - - assertTrue( value > 0 ) ; - assertEquals( testValue, value, 0.0 ) ; - - fixture.execute() ; - - double setValue = util.getCellAsDouble( cellId ) ; - - assertEquals( setValue, testValue, 0.0 ) ; - } - - -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/tests.xml b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/tests.xml deleted file mode 100644 index d387aab36..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/tests.xml +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtilTestHelper.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtilTestHelper.java deleted file mode 100644 index 16189f1d5..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/ExcelAntWorkbookUtilTestHelper.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant.util; - -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * A helper class to allow testing of protected methods and constructors. - * - * @author jsvede - * - */ -public class ExcelAntWorkbookUtilTestHelper extends ExcelAntWorkbookUtil { - - public ExcelAntWorkbookUtilTestHelper(String fName) { - super(fName); - } - - public ExcelAntWorkbookUtilTestHelper(Workbook wb) { - super(wb); - } - - @Override - public UDFFinder getFunctions() { - return super.getFunctions(); - } - - @Override - public FormulaEvaluator getEvaluator(String excelFileName) { - return super.getEvaluator(excelFileName); - } - - -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntEvaluationResult.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntEvaluationResult.java deleted file mode 100644 index 9c9213e52..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntEvaluationResult.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class TestExcelAntEvaluationResult { - private ExcelAntEvaluationResult fixture; - - private boolean completedWithError = false; - private boolean passed = false; - private double retValue = 1.1; - private String errMessage = "error message"; - private double delta = 2.2; - private String cellId = "testCell!$F$1"; - - @Before - public void setUp() { - fixture = new ExcelAntEvaluationResult(completedWithError, - passed, - retValue, - errMessage, - delta, - cellId); - } - - @After - public void tearDown() { - fixture = null; - } - - @Test - public void testCompletedWithErrorMessage() { - String errMsg = fixture.getErrorMessage(); - assertNotNull(errMsg); - assertEquals(errMsg, errMessage); - } - - @Test - public void testPassed() { - boolean passedValue = fixture.didTestPass(); - assertEquals(passedValue, passed); - } - - @Test - public void testDelta() { - double deltaValue = fixture.getDelta(); - assertEquals(deltaValue, delta, 0.0); - } - - @Test - public void testCellId() { - String cellIdValue = fixture.getCellName(); - assertNotNull(cellIdValue); - assertEquals(cellIdValue, cellId); - } -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntWorkbookUtil.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntWorkbookUtil.java deleted file mode 100644 index bf68c2481..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntWorkbookUtil.java +++ /dev/null @@ -1,358 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Date; -import java.util.List; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.examples.formula.CalculateMortgageFunction; -import org.apache.poi.ss.excelant.BuildFileTest; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.tools.ant.BuildException; - -import junit.framework.TestCase; - -public class TestExcelAntWorkbookUtil extends TestCase { - - private static final String mortgageCalculatorFileName = - BuildFileTest.getDataDir() + "/spreadsheet/excelant.xls" ; - - private ExcelAntWorkbookUtilTestHelper fixture ; - - - @Override - public void tearDown() { - fixture = null ; - } - - public void testStringConstructor() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - assertNotNull(fixture); - } - - public void testLoadNotExistingFile() { - try { - assertNotNull(new ExcelAntWorkbookUtilTestHelper( - "notexistingFile" )); - fail("Should catch exception here"); - } catch (BuildException e) { - assertTrue(e.getMessage().contains("notexistingFile")); - } - } - - public void testWorkbookConstructor() throws InvalidFormatException, IOException { - File workbookFile = new File(mortgageCalculatorFileName); - FileInputStream fis = new FileInputStream(workbookFile); - Workbook workbook = WorkbookFactory.create(fis); - - fixture = new ExcelAntWorkbookUtilTestHelper(workbook); - - assertNotNull(fixture); - } - - public void testAddFunction() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - assertNotNull(fixture); - - fixture.addFunction("h2_ZFactor", new CalculateMortgageFunction()); - - UDFFinder functions = fixture.getFunctions(); - - assertNotNull(functions); - assertNotNull(functions.findFunction("h2_ZFactor")); - } - - public void testAddFunctionClassName() throws Exception { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - assertNotNull(fixture); - - fixture.addFunction("h2_ZFactor", CalculateMortgageFunction.class.getName()); - - UDFFinder functions = fixture.getFunctions(); - - assertNotNull(functions); - assertNotNull(functions.findFunction("h2_ZFactor")); - } - - public void testAddFunctionInvalidClassName() throws Exception { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - assertNotNull(fixture); - - fixture.addFunction("h2_ZFactor", String.class.getName()); - - UDFFinder functions = fixture.getFunctions(); - - assertNotNull(functions); - assertNull(functions.findFunction("h2_ZFactor")); - } - - public void testGetWorkbook() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - assertNotNull(fixture); - - Workbook workbook = fixture.getWorkbook(); - - assertNotNull(workbook); - } - - public void testFileName() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - assertNotNull(fixture); - - String fileName = fixture.getFileName(); - - assertNotNull(fileName); - - assertEquals(mortgageCalculatorFileName, fileName); - - } - - public void testGetEvaluator() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - FormulaEvaluator evaluator = fixture.getEvaluator( - mortgageCalculatorFileName); - - assertNotNull(evaluator); - } - - public void testGetEvaluatorWithUDF() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - fixture.addFunction("h2_ZFactor", new CalculateMortgageFunction()); - - FormulaEvaluator evaluator = fixture.getEvaluator( - mortgageCalculatorFileName); - - assertNotNull(evaluator); - } - - public void testGetEvaluatorXLSX() { - fixture = new ExcelAntWorkbookUtilTestHelper( - BuildFileTest.getDataDir() + "/spreadsheet/sample.xlsx"); - - FormulaEvaluator evaluator = fixture.getEvaluator( - BuildFileTest.getDataDir() + "/spreadsheet/sample.xlsx"); - - assertNotNull(evaluator); - } - - public void testGetEvaluatorXLSXWithFunction() { - fixture = new ExcelAntWorkbookUtilTestHelper( - BuildFileTest.getDataDir() + "/spreadsheet/sample.xlsx"); - - fixture.addFunction("h2_ZFactor", new CalculateMortgageFunction()); - - FormulaEvaluator evaluator = fixture.getEvaluator( - BuildFileTest.getDataDir() + "/spreadsheet/sample.xlsx"); - - assertNotNull(evaluator); - } - - public void testEvaluateCell() { - String cell = "'MortgageCalculator'!B4" ; - double expectedValue = 790.79 ; - double precision = 0.1 ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - ExcelAntEvaluationResult result = fixture.evaluateCell(cell, - expectedValue, - precision); - - //System.out.println(result); - assertTrue("Had:" + result.toString(), result.toString().contains("evaluationCompletedWithError=false")); - assertTrue("Had:" + result.toString(), result.toString().contains("returnValue=790.79")); - assertTrue("Had:" + result.toString(), result.toString().contains("cellName='MortgageCalculator'!B4")); - assertFalse(result.toString().contains("#N/A")); - - assertFalse(result.evaluationCompleteWithError()); - assertTrue(result.didTestPass()); - } - - public void testEvaluateCellFailedPrecision() { - String cell = "'MortgageCalculator'!B4" ; - double expectedValue = 790.79 ; - double precision = 0.0000000000001 ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - ExcelAntEvaluationResult result = fixture.evaluateCell(cell, - expectedValue, - precision); - - //System.out.println(result); - assertTrue("Had:" + result.toString(), result.toString().contains("evaluationCompletedWithError=false")); - assertTrue("Had:" + result.toString(), result.toString().contains("returnValue=790.79")); - assertTrue("Had:" + result.toString(), result.toString().contains("cellName='MortgageCalculator'!B4")); - assertFalse("Should not see an error, but had:" + result.toString(), result.toString().contains("#")); - - assertFalse(result.evaluationCompleteWithError()); - assertFalse(result.didTestPass()); - } - - public void testEvaluateCellWithError() { - String cell = "'ErrorCell'!A1" ; - double expectedValue = 790.79 ; - double precision = 0.1 ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - ExcelAntEvaluationResult result = fixture.evaluateCell(cell, - expectedValue, - precision); - - System.out.println(result); - assertTrue("Had:" + result.toString(), result.toString().contains("evaluationCompletedWithError=true")); - assertTrue("Had:" + result.toString(), result.toString().contains("returnValue=0.0")); - assertTrue("Had:" + result.toString(), result.toString().contains("cellName='ErrorCell'!A1")); - assertTrue("Had:" + result.toString(), result.toString().contains("#N/A")); - - assertTrue(result.evaluationCompleteWithError()); - assertFalse(result.didTestPass()); - } - - public void testGetSheets() { - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - List sheets = fixture.getSheets(); - - assertNotNull(sheets); - assertEquals(sheets.size(), 3); - } - - public void testSetString() { - String cell = "'MortgageCalculator'!C14" ; - String cellValue = "testString" ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - fixture.setStringValue(cell, cellValue); - - String value = fixture.getCellAsString(cell); - - assertNotNull(value); - assertEquals(cellValue, value); - } - - public void testSetNotExistingSheet() { - String cell = "'NotexistingSheet'!C14" ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - try { - fixture.setStringValue(cell, "some"); - fail("Should catch exception here"); - } catch (BuildException e) { - assertTrue(e.getMessage().contains("NotexistingSheet")); - } - } - - public void testSetFormula() { - String cell = "'MortgageCalculator'!C14" ; - String cellValue = "SUM(B14:B18)" ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - fixture.setFormulaValue(cell, cellValue); - - double value = fixture.getCellAsDouble(cell); - - assertNotNull(value); - assertEquals(0.0, value); - } - - public void testSetDoubleValue() { - String cell = "'MortgageCalculator'!C14" ; - double cellValue = 1.2; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - fixture.setDoubleValue(cell, cellValue); - - Double value = fixture.getCellAsDouble(cell); - - assertNotNull(value); - assertEquals(cellValue, value); - } - - public void testSetDate() { - String cell = "'MortgageCalculator'!C14" ; - Date cellValue = new Date(); - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - fixture.setDateValue(cell, cellValue); - - double value = fixture.getCellAsDouble(cell); - - assertNotNull(value); - assertEquals(DateUtil.getExcelDate(cellValue, false), value); - } - - public void testGetNonexistingString() { - String cell = "'MortgageCalculator'!C33" ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - String value = fixture.getCellAsString(cell); - - assertEquals("", value); - } - - public void testGetNonexistingDouble() { - String cell = "'MortgageCalculator'!C33" ; - - fixture = new ExcelAntWorkbookUtilTestHelper( - mortgageCalculatorFileName); - - double value = fixture.getCellAsDouble(cell); - - assertEquals(0.0, value); - } -} diff --git a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntWorkbookUtilFactory.java b/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntWorkbookUtilFactory.java deleted file mode 100644 index b69449a5f..000000000 --- a/trunk/src/excelant/testcases/org/apache/poi/ss/excelant/util/TestExcelAntWorkbookUtilFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.excelant.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.apache.poi.ss.excelant.BuildFileTest; -import org.junit.Test; - - -/** - * Tests for the ExcelAntWorbookUtilFactory. - * - * @author Jon Svede (jon [at] loquatic [dot] com) - * @author Brian Bush (brian [dot] bush [at] nrel [dot] gov) - * - */ -public class TestExcelAntWorkbookUtilFactory { - - private static final String mortgageCalculatorWorkbookFile = - BuildFileTest.getDataDir() + "/spreadsheet/mortgage-calculation.xls" ; - - - /** - * Simple test to determine if the factory properly returns an non-null - * instance of the ExcelAntWorkbookUtil class. - */ - @Test - public void testGetNewWorkbookUtilInstance() { - ExcelAntWorkbookUtil util = ExcelAntWorkbookUtilFactory.getInstance( - mortgageCalculatorWorkbookFile) ; - - assertNotNull(util) ; - } - - - /** - * Test whether or not the factory will properly return the same reference - * to an ExcelAnt WorkbookUtil when two different Strings, that point to - * the same resource, are passed in. - */ - @Test - public void testVerifyEquivalence() { - String sameFileName = BuildFileTest.getDataDir() + "/spreadsheet/mortgage-calculation.xls" ; - - ExcelAntWorkbookUtil util = ExcelAntWorkbookUtilFactory.getInstance( - mortgageCalculatorWorkbookFile) ; - - ExcelAntWorkbookUtil util2 = ExcelAntWorkbookUtilFactory.getInstance( - sameFileName) ; - - assertNotNull(util) ; - assertNotNull(util2) ; - - assertEquals(util, util2) ; - } -} diff --git a/trunk/src/integrationtest/build.xml b/trunk/src/integrationtest/build.xml deleted file mode 100644 index 8409e5354..000000000 --- a/trunk/src/integrationtest/build.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - - - Test-Ant file which verifies that the Apache POI distribution build sources can be compiled successfully. - -Before running this, you should execute the "assemble" target in the main build.xml to have the packaged files created correctly. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/integrationtest/commons-logging.properties b/trunk/src/integrationtest/commons-logging.properties deleted file mode 100644 index 45db0a7a8..000000000 --- a/trunk/src/integrationtest/commons-logging.properties +++ /dev/null @@ -1,16 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -log4j.configuration=log4j.properties \ No newline at end of file diff --git a/trunk/src/integrationtest/log4j.properties b/trunk/src/integrationtest/log4j.properties deleted file mode 100644 index f2aea6851..000000000 --- a/trunk/src/integrationtest/log4j.properties +++ /dev/null @@ -1,40 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -log4j.rootLogger=info, R - -log4j.appender.R=org.apache.log4j.RollingFileAppender -log4j.appender.R.File=build/test-integration.log - -log4j.appender.R.MaxFileSize=1000KB -# Keep one backup file -log4j.appender.R.MaxBackupIndex=5 - -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n - -log4j.logger.org.apache.poi.poifs.nio.FileBackedDataSource=ERROR -log4j.logger.org.apache.poi.hdgf.chunks.Chunk=FATAL -log4j.logger.org.apache.poi.hpsf.CodePageString=ERROR -log4j.logger.org.apache.poi.hdgf.chunks.ChunkFactory=ERROR -log4j.logger.org.apache.poi.hslf.model.textproperties.BitMaskTextProp=ERROR -log4j.logger.org.apache.poi.util.JvmBugs=ERROR -log4j.logger.org.apache.poi.hslf.usermodel.HSLFTextParagraph=ERROR -log4j.logger.org.apache.poi.openxml4j.opc.ZipPackage=ERROR -log4j.logger.org.apache.poi.POIDocument=WARN -log4j.logger.org.apache.poi.openxml4j.opc.OPCPackage=ERROR -log4j.logger.org.apache.poi.xssf.usermodel.XSSFWorkbook=ERROR -log4j.logger.org.apache.poi.hslf.usermodel.HSLFGroupShape=WARN -log4j.logger.org.apache.poi.hslf.record.Record=ERROR \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/TestAllFiles.java b/trunk/src/integrationtest/org/apache/poi/TestAllFiles.java deleted file mode 100644 index 3974c0631..000000000 --- a/trunk/src/integrationtest/org/apache/poi/TestAllFiles.java +++ /dev/null @@ -1,402 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.stress.*; -import org.apache.tools.ant.DirectoryScanner; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.*; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -/** - * This is an integration test which performs various actions on all stored test-files and tries - * to reveal problems which are introduced, but not covered (yet) by unit tests. - * - * This test looks for any file under the test-data directory and tries to do some useful - * processing with it based on it's type. - * - * The test is implemented as a junit {@link Parameterized} test, which leads - * to one test-method call for each file (currently around 950 files are handled). - * - * There is a a mapping of extension to implementations of the interface - * {@link FileHandler} which defines how the file is loaded and which actions are - * tried with the file. - * - * The test can be expanded by adding more actions to the FileHandlers, this automatically - * applies the action to any such file in our test-data repository. - * - * There is also a list of files that should actually fail. - * - * Note: It is also a test-failure if a file that is expected to fail now actually works, - * i.e. if a bug was fixed in POI itself, the file should be removed from the expected-failures - * here as well! This is to ensure that files that should not work really do not work, e.g. - * that we do not remove expected sanity checks. - */ -@RunWith(Parameterized.class) -public class TestAllFiles { - private static final File ROOT_DIR = new File("test-data"); - - static final String[] SCAN_EXCLUDES = new String[] { "**/.svn/**", "lost+found" }; - - // map file extensions to the actual mappers - static final Map HANDLERS = new HashMap(); - static { - // Excel - HANDLERS.put(".xls", new HSSFFileHandler()); - HANDLERS.put(".xlsx", new XSSFFileHandler()); - HANDLERS.put(".xlsm", new XSSFFileHandler()); - HANDLERS.put(".xltx", new XSSFFileHandler()); - HANDLERS.put(".xlsb", new XSSFFileHandler()); - - // Word - HANDLERS.put(".doc", new HWPFFileHandler()); - HANDLERS.put(".docx", new XWPFFileHandler()); - HANDLERS.put(".dotx", new XWPFFileHandler()); - HANDLERS.put(".docm", new XWPFFileHandler()); - - // OpenXML4J files - HANDLERS.put(".ooxml", new OPCFileHandler()); // OPCPackage - HANDLERS.put(".zip", new OPCFileHandler()); // OPCPackage - - // Powerpoint - HANDLERS.put(".ppt", new HSLFFileHandler()); - HANDLERS.put(".pptx", new XSLFFileHandler()); - HANDLERS.put(".pptm", new XSLFFileHandler()); - HANDLERS.put(".ppsm", new XSLFFileHandler()); - HANDLERS.put(".ppsx", new XSLFFileHandler()); - HANDLERS.put(".thmx", new XSLFFileHandler()); - HANDLERS.put(".potx", new XSLFFileHandler()); - - // Outlook - HANDLERS.put(".msg", new HSMFFileHandler()); - - // Publisher - HANDLERS.put(".pub", new HPBFFileHandler()); - - // Visio - binary - HANDLERS.put(".vsd", new HDGFFileHandler()); - - // Visio - ooxml - HANDLERS.put(".vsdm", new XDGFFileHandler()); - HANDLERS.put(".vsdx", new XDGFFileHandler()); - HANDLERS.put(".vssm", new XDGFFileHandler()); - HANDLERS.put(".vssx", new XDGFFileHandler()); - HANDLERS.put(".vstm", new XDGFFileHandler()); - HANDLERS.put(".vstx", new XDGFFileHandler()); - - // Visio - not handled yet - HANDLERS.put(".vst", new NullFileHandler()); - HANDLERS.put(".vss", new NullFileHandler()); - - // POIFS - HANDLERS.put(".ole2", new POIFSFileHandler()); - - // Microsoft Admin Template? - HANDLERS.put(".adm", new HPSFFileHandler()); - - // Microsoft TNEF - HANDLERS.put(".dat", new HMEFFileHandler()); - - // TODO: are these readable by some of the formats? - HANDLERS.put(".shw", new NullFileHandler()); - HANDLERS.put(".zvi", new NullFileHandler()); - HANDLERS.put(".mpp", new NullFileHandler()); - HANDLERS.put(".qwp", new NullFileHandler()); - HANDLERS.put(".wps", new NullFileHandler()); - HANDLERS.put(".bin", new NullFileHandler()); - HANDLERS.put(".xps", new NullFileHandler()); - HANDLERS.put(".sldprt", new NullFileHandler()); - HANDLERS.put(".mdb", new NullFileHandler()); - HANDLERS.put(".vml", new NullFileHandler()); - - // ignore some file types, images, other formats, ... - HANDLERS.put(".txt", new NullFileHandler()); - HANDLERS.put(".pdf", new NullFileHandler()); - HANDLERS.put(".rtf", new NullFileHandler()); - HANDLERS.put(".gif", new NullFileHandler()); - HANDLERS.put(".html", new NullFileHandler()); - HANDLERS.put(".png", new NullFileHandler()); - HANDLERS.put(".wmf", new NullFileHandler()); - HANDLERS.put(".emf", new NullFileHandler()); - HANDLERS.put(".dib", new NullFileHandler()); - HANDLERS.put(".svg", new NullFileHandler()); - HANDLERS.put(".pict", new NullFileHandler()); - HANDLERS.put(".jpg", new NullFileHandler()); - HANDLERS.put(".jpeg", new NullFileHandler()); - HANDLERS.put(".tif", new NullFileHandler()); - HANDLERS.put(".tiff", new NullFileHandler()); - HANDLERS.put(".wav", new NullFileHandler()); - HANDLERS.put(".pfx", new NullFileHandler()); - HANDLERS.put(".xml", new NullFileHandler()); - HANDLERS.put(".csv", new NullFileHandler()); - HANDLERS.put(".ods", new NullFileHandler()); - // VBA source files - HANDLERS.put(".vba", new NullFileHandler()); - HANDLERS.put(".bas", new NullFileHandler()); - HANDLERS.put(".frm", new NullFileHandler()); - HANDLERS.put(".frx", new NullFileHandler()); //binary - HANDLERS.put(".cls", new NullFileHandler()); - - // map some files without extension - HANDLERS.put("spreadsheet/BigSSTRecord", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR1", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR2", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR3", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR4", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR5", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR6", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecord2CR7", new NullFileHandler()); - HANDLERS.put("spreadsheet/BigSSTRecordCR", new NullFileHandler()); - HANDLERS.put("spreadsheet/test_properties1", new NullFileHandler()); - } - - // Old Word Documents where we can at least extract some text - private static final Set OLD_FILES = new HashSet(); - static { - OLD_FILES.add("document/Bug49933.doc"); - OLD_FILES.add("document/Bug51944.doc"); - OLD_FILES.add("document/Word6.doc"); - OLD_FILES.add("document/Word6_sections.doc"); - OLD_FILES.add("document/Word6_sections2.doc"); - OLD_FILES.add("document/Word95.doc"); - OLD_FILES.add("document/word95err.doc"); - OLD_FILES.add("hpsf/TestMickey.doc"); - OLD_FILES.add("document/52117.doc"); - } - - private static final Set EXPECTED_FAILURES = new HashSet(); - static { - // password protected files - EXPECTED_FAILURES.add("spreadsheet/password.xls"); - EXPECTED_FAILURES.add("spreadsheet/protected_passtika.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/51832.xls"); - EXPECTED_FAILURES.add("document/PasswordProtected.doc"); - EXPECTED_FAILURES.add("slideshow/Password_Protected-hello.ppt"); - EXPECTED_FAILURES.add("slideshow/Password_Protected-56-hello.ppt"); - EXPECTED_FAILURES.add("slideshow/Password_Protected-np-hello.ppt"); - EXPECTED_FAILURES.add("slideshow/cryptoapi-proc2356.ppt"); - //EXPECTED_FAILURES.add("document/bug53475-password-is-pass.docx"); - //EXPECTED_FAILURES.add("document/bug53475-password-is-solrcell.docx"); - EXPECTED_FAILURES.add("spreadsheet/xor-encryption-abc.xls"); - EXPECTED_FAILURES.add("spreadsheet/35897-type4.xls"); - //EXPECTED_FAILURES.add("poifs/protect.xlsx"); - //EXPECTED_FAILURES.add("poifs/protected_sha512.xlsx"); - //EXPECTED_FAILURES.add("poifs/extenxls_pwd123.xlsx"); - //EXPECTED_FAILURES.add("poifs/protected_agile.docx"); - EXPECTED_FAILURES.add("spreadsheet/58616.xlsx"); - EXPECTED_FAILURES.add("poifs/60320-protected.xlsx"); - - // TODO: fails XMLExportTest, is this ok? - EXPECTED_FAILURES.add("spreadsheet/CustomXMLMapping-singleattributenamespace.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/55864.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/57890.xlsx"); - - // TODO: these fail now with some NPE/file read error because we now try to compute every value via Cell.toString()! - EXPECTED_FAILURES.add("spreadsheet/44958.xls"); - EXPECTED_FAILURES.add("spreadsheet/44958_1.xls"); - EXPECTED_FAILURES.add("spreadsheet/testArraysAndTables.xls"); - - // TODO: good to ignore? - EXPECTED_FAILURES.add("spreadsheet/sample-beta.xlsx"); - - // This is actually a spreadsheet! - EXPECTED_FAILURES.add("hpsf/TestRobert_Flaherty.doc"); - - // some files that are broken, eg Word 95, ... - EXPECTED_FAILURES.add("spreadsheet/43493.xls"); - EXPECTED_FAILURES.add("spreadsheet/46904.xls"); - EXPECTED_FAILURES.add("document/Bug50955.doc"); - EXPECTED_FAILURES.add("document/57843.doc"); - EXPECTED_FAILURES.add("slideshow/PPT95.ppt"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_NotPresentFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_OnlyOneCorePropertiesPartFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_UnauthorizedXMLLangAttributeFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/OPCCompliance_DerivedPartNameFAIL.docx"); - EXPECTED_FAILURES.add("openxml4j/invalid.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/54764-2.xlsx"); // see TestXSSFBugs.bug54764() - EXPECTED_FAILURES.add("spreadsheet/54764.xlsx"); // see TestXSSFBugs.bug54764() - EXPECTED_FAILURES.add("spreadsheet/Simple.xlsb"); - EXPECTED_FAILURES.add("poifs/unknown_properties.msg"); // POIFS properties corrupted - EXPECTED_FAILURES.add("poifs/only-zero-byte-streams.ole2"); // No actual contents - EXPECTED_FAILURES.add("spreadsheet/poc-xmlbomb.xlsx"); // contains xml-entity-expansion - EXPECTED_FAILURES.add("spreadsheet/poc-shared-strings.xlsx"); // contains shared-string-entity-expansion - EXPECTED_FAILURES.add("spreadsheet/60255_extra_drawingparts.xlsx"); // Non-drawing drawing - - // old Excel files, which we only support simple text extraction of - EXPECTED_FAILURES.add("spreadsheet/testEXCEL_2.xls"); - EXPECTED_FAILURES.add("spreadsheet/testEXCEL_3.xls"); - EXPECTED_FAILURES.add("spreadsheet/testEXCEL_4.xls"); - EXPECTED_FAILURES.add("spreadsheet/testEXCEL_5.xls"); - EXPECTED_FAILURES.add("spreadsheet/testEXCEL_95.xls"); - EXPECTED_FAILURES.add("spreadsheet/59074.xls"); - EXPECTED_FAILURES.add("spreadsheet/60284.xls"); - - // OOXML Strict is not yet supported, see bug #57699 - EXPECTED_FAILURES.add("spreadsheet/SampleSS.strict.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/SimpleStrict.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/sample.strict.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/57914.xlsx"); - - // non-TNEF files - EXPECTED_FAILURES.add("ddf/Container.dat"); - EXPECTED_FAILURES.add("ddf/47143.dat"); - - // sheet cloning errors - EXPECTED_FAILURES.add("spreadsheet/47813.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/56450.xls"); - EXPECTED_FAILURES.add("spreadsheet/57231_MixedGasReport.xls"); - EXPECTED_FAILURES.add("spreadsheet/OddStyleRecord.xls"); - EXPECTED_FAILURES.add("spreadsheet/WithChartSheet.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/chart_sheet.xlsx"); - EXPECTED_FAILURES.add("spreadsheet/SimpleScatterChart.xlsx"); - } - - private static final Set IGNORED = new HashSet(); - static { - // need JDK8+ - https://bugs.openjdk.java.net/browse/JDK-8038081 - IGNORED.add("slideshow/42474-2.ppt"); - // OPC handler works / XSSF handler fails - IGNORED.add("spreadsheet/57181.xlsm"); - } - - @Parameters(name="{index}: {0} using {1}") - public static Iterable files() { - DirectoryScanner scanner = new DirectoryScanner(); - scanner.setBasedir(ROOT_DIR); - scanner.setExcludes(SCAN_EXCLUDES); - - scanner.scan(); - - System.out.println("Handling " + scanner.getIncludedFiles().length + " files"); - - List files = new ArrayList(); - for(String file : scanner.getIncludedFiles()) { - file = file.replace('\\', '/'); // ... failures/handlers lookup doesn't work on windows otherwise - if (IGNORED.contains(file)) { - System.out.println("Ignoring " + file); - continue; - } - FileHandler handler = HANDLERS.get(getExtension(file)); - files.add(new Object[] { file, handler }); - - // for some file-types also run OPCFileHandler - if(handler instanceof XSSFFileHandler || - handler instanceof XWPFFileHandler || - handler instanceof XSLFFileHandler || - handler instanceof XDGFFileHandler) { - files.add(new Object[] { file, HANDLERS.get(".ooxml") }); - } - } - - return files; - } - - @SuppressWarnings("DefaultAnnotationParam") - @Parameter(value=0) - public String file; - - @Parameter(value=1) - public FileHandler handler; - - @Test - public void testAllFiles() throws Exception { - System.out.println("Reading " + file + " with " + handler.getClass()); - assertNotNull("Unknown file extension for file: " + file + ": " + getExtension(file), handler); - File inputFile = new File(ROOT_DIR, file); - - try { - InputStream stream = new BufferedInputStream(new FileInputStream(inputFile), 64*1024); - try { - handler.handleFile(stream); - - assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!", - OLD_FILES.contains(file)); - } finally { - stream.close(); - } - - handler.handleExtracting(inputFile); - - // special cases where docx-handling breaks, but OPCPackage handling works - boolean ignoredOPC = (file.endsWith(".docx") || file.endsWith(".xlsx") || - file.endsWith(".xlsb") || file.endsWith(".pptx")) && - handler instanceof OPCFileHandler; - - assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!", - EXPECTED_FAILURES.contains(file) && !ignoredOPC); - } catch (OldFileFormatException e) { - // for old word files we should still support extracting text - if(OLD_FILES.contains(file)) { - handler.handleExtracting(inputFile); - } else { - // check if we expect failure for this file - if(!EXPECTED_FAILURES.contains(file) && !AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.contains(file)) { - System.out.println("Failed: " + file); - throw new Exception("While handling " + file, e); - } - } - } catch (Exception e) { - // check if we expect failure for this file - if(!EXPECTED_FAILURES.contains(file) && !AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.contains(file)) { - System.out.println("Failed: " + file); - throw new Exception("While handling " + file, e); - } - } - - // let some file handlers do additional stuff - handler.handleAdditional(inputFile); - } - - static String getExtension(String file) { - int pos = file.lastIndexOf('.'); - if(pos == -1 || pos == file.length()-1) { - return file; - } - - return file.substring(pos).toLowerCase(Locale.ROOT); - } - - private static class NullFileHandler implements FileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - } - - @Override - public void handleExtracting(File file) throws Exception { - } - - @Override - public void handleAdditional(File file) throws Exception { - } - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/hssf/usermodel/RecordsStresser.java b/trunk/src/integrationtest/org/apache/poi/hssf/usermodel/RecordsStresser.java deleted file mode 100644 index 1b712f788..000000000 --- a/trunk/src/integrationtest/org/apache/poi/hssf/usermodel/RecordsStresser.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.usermodel; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.List; - -import org.apache.poi.hssf.record.Record; -import org.junit.Test; - -/** - * Needs to be implemented in this package to have access to - * HSSFWorkbook.getWorkbook() - */ -public class RecordsStresser { - public static void handleWorkbook(HSSFWorkbook wb) { - List records = wb.getWorkbook().getRecords(); - for(Record record : records) { - // some Records do not implement clone ?! - // equals instead of instanceof is on purpose here to only skip exactly this class and not any derived ones -// if(record.getClass().equals(InterfaceHdrRecord.class) || -// record.getClass().equals(MMSRecord.class) || -// record.getClass().equals(InterfaceEndRecord.class) || -// record.getClass().equals(WriteAccessRecord.class) || -// record.getClass().equals(CodepageRecord.class) || -// record.getClass().equals(DSFRecord.class)) { -// continue; -// } - try { - Record newRecord = (Record) record.clone(); - - assertEquals("Expecting the same class back from clone(), but had Record of type " + record.getClass() + " and got back a " + newRecord.getClass() + " from clone()", - record.getClass(), newRecord.getClass()); - - byte[] origBytes = record.serialize(); - byte[] newBytes = newRecord.serialize(); - - assertArrayEquals("Record of type " + record.getClass() + " should return the same byte array via the clone() method, but did return a different array", - origBytes, newBytes); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } catch (RuntimeException e) { - // some Records do not implement clone, ignore those for now - assertTrue(e.getMessage().contains("needs to define a clone method")); - } - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/spreadsheet/15556.xls"); - try { - HSSFWorkbook wb = new HSSFWorkbook(stream); - handleWorkbook(wb); - wb.close(); - } finally { - stream.close(); - } - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java deleted file mode 100644 index 6bfeee2e7..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java +++ /dev/null @@ -1,142 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashSet; -import java.util.Set; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.POITextExtractor; -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.xmlbeans.XmlException; - -public abstract class AbstractFileHandler implements FileHandler { - public static final Set EXPECTED_EXTRACTOR_FAILURES = new HashSet(); - static { - // password protected files - EXPECTED_EXTRACTOR_FAILURES.add("document/bug53475-password-is-pass.docx"); - EXPECTED_EXTRACTOR_FAILURES.add("poifs/extenxls_pwd123.xlsx"); - EXPECTED_EXTRACTOR_FAILURES.add("poifs/protect.xlsx"); - EXPECTED_EXTRACTOR_FAILURES.add("poifs/protected_agile.docx"); - EXPECTED_EXTRACTOR_FAILURES.add("poifs/protected_sha512.xlsx"); - - // unsupported file-types, no supported OLE2 parts - EXPECTED_EXTRACTOR_FAILURES.add("hmef/quick-winmail.dat"); - EXPECTED_EXTRACTOR_FAILURES.add("hmef/winmail-sample1.dat"); - EXPECTED_EXTRACTOR_FAILURES.add("hmef/bug52400-winmail-simple.dat"); - EXPECTED_EXTRACTOR_FAILURES.add("hmef/bug52400-winmail-with-attachments.dat"); - EXPECTED_EXTRACTOR_FAILURES.add("hpsf/Test0313rur.adm"); - EXPECTED_EXTRACTOR_FAILURES.add("poifs/Notes.ole2"); - } - - @Override - public void handleExtracting(File file) throws Exception { - boolean before = ExtractorFactory.getThreadPrefersEventExtractors(); - try { - ExtractorFactory.setThreadPrefersEventExtractors(true); - handleExtractingInternal(file); - - ExtractorFactory.setThreadPrefersEventExtractors(false); - handleExtractingInternal(file); - } finally { - ExtractorFactory.setThreadPrefersEventExtractors(before); - } - - /* Did fail for some documents with special XML contents... - try { - OOXMLPrettyPrint.main(new String[] { file.getAbsolutePath(), - "/tmp/pretty-" + file.getName() }); - } catch (ZipException e) { - // ignore, not a Zip/OOXML file - }*/ - } - - private void handleExtractingInternal(File file) throws Exception { - long length = file.length(); - long modified = file.lastModified(); - - POITextExtractor extractor = ExtractorFactory.createExtractor(file); - try { - assertNotNull(extractor); - - assertNotNull(extractor.getText()); - - // also try metadata - @SuppressWarnings("resource") - POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor(); - assertNotNull(metadataExtractor.getText()); - - assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", - EXPECTED_EXTRACTOR_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())); - - assertEquals("File should not be modified by extractor", length, file.length()); - assertEquals("File should not be modified by extractor", modified, file.lastModified()); - - handleExtractingAsStream(file); - - if(extractor instanceof POIOLE2TextExtractor) { - HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor((POIOLE2TextExtractor)extractor); - try { - assertNotNull(hpsfExtractor.getDocumentSummaryInformationText()); - assertNotNull(hpsfExtractor.getSummaryInformationText()); - String text = hpsfExtractor.getText(); - //System.out.println(text); - assertNotNull(text); - } finally { - hpsfExtractor.close(); - } - } - } catch (IllegalArgumentException e) { - if(!EXPECTED_EXTRACTOR_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } finally { - extractor.close(); - } - } - - private void handleExtractingAsStream(File file) throws IOException, OpenXML4JException, XmlException { - InputStream stream = new FileInputStream(file); - try { - POITextExtractor streamExtractor = ExtractorFactory.createExtractor(stream); - try { - assertNotNull(streamExtractor); - - assertNotNull(streamExtractor.getText()); - } finally { - streamExtractor.close(); - } - } finally { - stream.close(); - } - } - - @Override - public void handleAdditional(File file) throws Exception { - // by default we do nothing here - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/FileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/FileHandler.java deleted file mode 100644 index 8b65cfa47..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/FileHandler.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import java.io.File; -import java.io.InputStream; - -/** - * Base interface for the various file types that are - * used in the stress testing. - */ -public interface FileHandler { - /** - * The FileHandler receives a stream ready for reading the - * file and should handle the content that is provided and - * try to read and interpret the data. - * - * Closing is handled by the framework outside this call. - * - * @param stream - * @throws Exception - */ - void handleFile(InputStream stream) throws Exception; - - /** - * Ensures that extracting text from the given file - * is returning some text. - */ - void handleExtracting(File file) throws Exception; - - /** - * Allows to perform some additional work, e.g. run - * some of the example applications - */ - void handleAdditional(File file) throws Exception; -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java deleted file mode 100644 index eb0e1b6c0..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hdgf.HDGFDiagram; -import org.apache.poi.hdgf.extractor.VisioTextExtractor; -import org.apache.poi.hdgf.streams.Stream; -import org.apache.poi.hdgf.streams.TrailerStream; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.junit.Test; - -public class HDGFFileHandler extends POIFSFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - POIFSFileSystem poifs = new POIFSFileSystem(stream); - HDGFDiagram diagram = new HDGFDiagram(poifs); - Stream[] topLevelStreams = diagram.getTopLevelStreams(); - assertNotNull(topLevelStreams); - for(Stream str : topLevelStreams) { - assertTrue(str.getPointer().getLength() >= 0); - } - - TrailerStream trailerStream = diagram.getTrailerStream(); - assertNotNull(trailerStream); - assertTrue(trailerStream.getPointer().getLength() >= 0); - - poifs.close(); - - // writing is not yet implemented... handlePOIDocument(diagram); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - File file = new File("test-data/diagram/44501.vsd"); - - InputStream stream = new FileInputStream(file); - try { - handleFile(stream); - } finally { - stream.close(); - } - - handleExtracting(file); - - stream = new FileInputStream(file); - try { - VisioTextExtractor extractor = new VisioTextExtractor(stream); - try { - assertNotNull(extractor.getText()); - } finally { - extractor.close(); - } - } finally { - stream.close(); - } - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java deleted file mode 100644 index 9f492bf0e..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hmef.attribute.MAPIAttribute; -import org.apache.poi.hmef.attribute.MAPIStringAttribute; -import org.junit.Test; - -public class HMEFFileHandler extends AbstractFileHandler { - - @Override - public void handleFile(InputStream stream) throws Exception { - HMEFMessage msg = new HMEFMessage(stream); - - // list all properties - StringBuilder props = new StringBuilder(); - for(MAPIAttribute att : msg.getMessageMAPIAttributes()) { - props.append(att.getType()).append(": ").append(MAPIStringAttribute.getAsString( att)).append("\n"); - } - - // there are two test-files that have no body... - if(!msg.getSubject().equals("Testing TNEF Message") && !msg.getSubject().equals("TNEF test message with attachments")) { - assertNotNull("Had: " + msg.getBody() + ", " + msg.getSubject() + ", " + msg.getAttachments() + ": " + props.toString(), - msg.getBody()); - } - assertNotNull("Had: " + msg.getBody() + ", " + msg.getSubject() + ", " + msg.getAttachments() + ": " + props.toString(), - msg.getSubject()); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/hmef/quick-winmail.dat"); - try { - handleFile(stream); - } finally { - stream.close(); - } - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java deleted file mode 100644 index 093ef0274..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hpbf.HPBFDocument; -import org.apache.poi.hpbf.extractor.PublisherTextExtractor; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.junit.Test; - -public class HPBFFileHandler extends POIFSFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - HPBFDocument pub = new HPBFDocument(new POIFSFileSystem(stream)); - assertNotNull(pub.getEscherDelayStm()); - assertNotNull(pub.getMainContents()); - assertNotNull(pub.getQuillContents()); - - // writing is not yet implemented... handlePOIDocument(pub); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - File file = new File("test-data/publisher/SampleBrochure.pub"); - - InputStream stream = new FileInputStream(file); - try { - handleFile(stream); - } finally { - stream.close(); - } - - handleExtracting(file); - - stream = new FileInputStream(file); - try { - PublisherTextExtractor extractor = new PublisherTextExtractor(stream); - try { - assertNotNull(extractor.getText()); - } finally { - extractor.close(); - } - } finally { - stream.close(); - } - } - -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java deleted file mode 100644 index 1f3dc6905..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hpsf.HPSFPropertiesOnlyDocument; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.junit.Test; - -public class HPSFFileHandler extends POIFSFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - HPSFPropertiesOnlyDocument hpsf = new HPSFPropertiesOnlyDocument(new POIFSFileSystem(stream)); - assertNotNull(hpsf.getDocumentSummaryInformation()); - assertNotNull(hpsf.getSummaryInformation()); - - handlePOIDocument(hpsf); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/hpsf/Test0313rur.adm"); - try { - handleFile(stream); - } finally { - stream.close(); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void testExtractor() throws Exception { - handleExtracting(new File("test-data/hpsf/TestBug44375.xls")); - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java deleted file mode 100644 index db9548c41..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; -import org.junit.Test; - -public class HSLFFileHandler extends SlideShowHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - HSLFSlideShowImpl slide = new HSLFSlideShowImpl(stream); - assertNotNull(slide.getCurrentUserAtom()); - assertNotNull(slide.getEmbeddedObjects()); - assertNotNull(slide.getUnderlyingBytes()); - assertNotNull(slide.getPictureData()); - Record[] records = slide.getRecords(); - assertNotNull(records); - for(Record record : records) { - assertTrue(record.getRecordType() >= 0); - } - - handlePOIDocument(slide); - - HSLFSlideShow ss = new HSLFSlideShow(slide); - handleSlideShow(ss); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/hpsf/Test_Humor-Generation.ppt"); - try { - handleFile(stream); - } finally { - stream.close(); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void testExtractor() throws Exception { - handleExtracting(new File("test-data/slideshow/ae.ac.uaeu.faculty_nafaachbili_GeomLec1.pptx")); - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java deleted file mode 100644 index c22edf2fc..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.hsmf.datatypes.AttachmentChunks; -import org.apache.poi.hsmf.datatypes.DirectoryChunk; -import org.junit.Test; - -public class HSMFFileHandler extends POIFSFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - MAPIMessage mapi = new MAPIMessage(stream); - assertNotNull(mapi.getAttachmentFiles()); - assertNotNull(mapi.getDisplayBCC()); - assertNotNull(mapi.getMessageDate()); - - AttachmentChunks[] attachments = mapi.getAttachmentFiles(); - - for(AttachmentChunks attachment : attachments) { - - DirectoryChunk chunkDirectory = attachment.attachmentDirectory; - if(chunkDirectory != null) { - MAPIMessage attachmentMSG = chunkDirectory.getAsEmbededMessage(); - assertNotNull(attachmentMSG); - String body = attachmentMSG.getTextBody(); - assertNotNull(body); - } - } - - /* => Writing isn't yet supported... - // write out the file - File file = TempFile.createTempFile("StressTest", ".msg"); - writeToFile(mapi, file); - - MAPIMessage read = new MAPIMessage(file.getAbsolutePath()); - assertNotNull(read.getAttachmentFiles()); - assertNotNull(read.getDisplayBCC()); - assertNotNull(read.getMessageDate()); - */ - - // writing is not yet supported... handlePOIDocument(mapi); - } - -// private void writeToFile(MAPIMessage mapi, File file) -// throws FileNotFoundException, IOException { -// OutputStream stream = new FileOutputStream(file); -// try { -// mapi.write(stream); -// } finally { -// stream.close(); -// } -// } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/hsmf/example_received_regular.msg"); - try { - handleFile(stream); - } finally { - stream.close(); - } - } -} \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java deleted file mode 100644 index fcea58058..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java +++ /dev/null @@ -1,113 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.hssf.dev.BiffViewer; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.util.RecordFormatException; -import org.junit.Test; - -import java.io.*; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.Assert.assertFalse; - -public class HSSFFileHandler extends SpreadsheetHandler { - private final POIFSFileHandler delegate = new POIFSFileHandler(); - @Override - public void handleFile(InputStream stream) throws Exception { - HSSFWorkbook wb = new HSSFWorkbook(stream); - handleWorkbook(wb); - - // TODO: some documents fail currently... - //HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); - //evaluator.evaluateAll(); - - delegate.handlePOIDocument(wb); - - // also try to see if some of the Records behave incorrectly - // TODO: still fails on some records... RecordsStresser.handleWorkbook(wb); - } - - private static final Set EXPECTED_ADDITIONAL_FAILURES = new HashSet(); - static { - // encrypted - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/35897-type4.xls"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/xor-encryption-abc.xls"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/password.xls"); - // broken files - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/43493.xls"); - // TODO: ok to ignore? - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/50833.xls"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/51832.xls"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/XRefCalc.xls"); - } - - @Override - public void handleAdditional(File file) throws Exception { - // redirect stdout as the examples often write lots of text - PrintStream oldOut = System.out; - try { - System.setOut(new PrintStream(new OutputStream() { - @Override - public void write(int b) throws IOException { - } - })); - - BiffViewer.main(new String[]{file.getAbsolutePath()}); - - assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", - EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())); - } catch (OldExcelFormatException e) { - // old excel formats are not supported here - } catch (EncryptedDocumentException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } catch (RecordFormatException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } catch (RuntimeException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } finally { - System.setOut(oldOut); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/spreadsheet/49219.xls"); - try { - handleFile(stream); - } finally { - stream.close(); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void testExtractor() throws Exception { - handleExtracting(new File("test-data/spreadsheet/BOOK_in_capitals.xls")); - } -} \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java deleted file mode 100644 index d762598a4..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.hwpf.HWPFDocument; -import org.apache.poi.hwpf.extractor.WordExtractor; -import org.junit.Test; - -public class HWPFFileHandler extends POIFSFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - HWPFDocument doc = new HWPFDocument(stream); - assertNotNull(doc.getBookmarks()); - assertNotNull(doc.getCharacterTable()); - assertNotNull(doc.getEndnotes()); - - handlePOIDocument(doc); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - File file = new File("test-data/document/52117.doc"); - - InputStream stream = new FileInputStream(file); - try { - handleFile(stream); - } finally { - stream.close(); - } - - handleExtracting(file); - - stream = new FileInputStream(file); - try { - WordExtractor extractor = new WordExtractor(stream); - try { - assertNotNull(extractor.getText()); - } finally { - extractor.close(); - } - } finally { - stream.close(); - } - } - - @Test - public void testExtractingOld() throws Exception { - File file = new File("test-data/document/52117.doc"); - handleExtracting(file); - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/OPCFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/OPCFileHandler.java deleted file mode 100644 index 12493e24c..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/OPCFileHandler.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.PushbackInputStream; - -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.xwpf.usermodel.XWPFRelation; -import org.junit.Test; - -public class OPCFileHandler extends AbstractFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - // ignore password protected files - if (POIXMLDocumentHandler.isEncrypted(stream)) return; - - OPCPackage p = OPCPackage.open(stream); - - for (PackagePart part : p.getParts()) { - if (part.getPartName().toString().equals("/docProps/core.xml")) { - assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType()); - } - if (part.getPartName().toString().equals("/word/document.xml")) { - assertTrue("Expected one of " + XWPFRelation.MACRO_DOCUMENT + ", " + XWPFRelation.DOCUMENT + ", " + XWPFRelation.TEMPLATE + - ", but had " + part.getContentType(), - XWPFRelation.DOCUMENT.getContentType().equals(part.getContentType()) || - XWPFRelation.MACRO_DOCUMENT.getContentType().equals(part.getContentType()) || - XWPFRelation.TEMPLATE.getContentType().equals(part.getContentType())); - } - if (part.getPartName().toString().equals("/word/theme/theme1.xml")) { - assertEquals(XWPFRelation.THEME.getContentType(), part.getContentType()); - } - } - } - - @Override - public void handleExtracting(File file) throws Exception { - // text-extraction is not possible currenlty for these types of files - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - File file = new File("test-data/diagram/test.vsdx"); - - InputStream stream = new PushbackInputStream(new FileInputStream(file), 100000); - try { - handleFile(stream); - } finally { - stream.close(); - } - - handleExtracting(file); - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java deleted file mode 100644 index 56be0d9ee..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIDocument; -import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.junit.Test; - -public class POIFSFileHandler extends AbstractFileHandler { - - @Override - public void handleFile(InputStream stream) throws Exception { - POIFSFileSystem fs = new POIFSFileSystem(stream); - try { - handlePOIFSFileSystem(fs); - handleHPSFProperties(fs); - } finally { - fs.close(); - } - } - - private void handleHPSFProperties(POIFSFileSystem fs) throws IOException { - HPSFPropertiesExtractor ext = new HPSFPropertiesExtractor(fs); - try { - // can be null - ext.getDocSummaryInformation(); - ext.getSummaryInformation(); - - assertNotNull(ext.getDocumentSummaryInformationText()); - assertNotNull(ext.getSummaryInformationText()); - assertNotNull(ext.getText()); - } finally { - ext.close(); - } - } - - private void handlePOIFSFileSystem(POIFSFileSystem fs) { - assertNotNull(fs); - assertNotNull(fs.getRoot()); - } - - protected void handlePOIDocument(POIDocument doc) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - doc.write(out); - - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - POIFSFileSystem fs = new POIFSFileSystem(in); - handlePOIFSFileSystem(fs); - fs.close(); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - File file = new File("test-data/poifs/Notes.ole2"); - - InputStream stream = new FileInputStream(file); - try { - handleFile(stream); - } finally { - stream.close(); - } - - //handleExtracting(file); - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java deleted file mode 100644 index 1a8cbf6a0..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -public final class POIXMLDocumentHandler { - protected void handlePOIXMLDocument(POIXMLDocument doc) throws Exception { - assertNotNull(doc.getAllEmbedds()); - assertNotNull(doc.getPackage()); - assertNotNull(doc.getPackagePart()); - assertNotNull(doc.getProperties()); - assertNotNull(doc.getRelations()); - } - - protected static boolean isEncrypted(InputStream stream) throws IOException { - if (POIFSFileSystem.hasPOIFSHeader(stream)) { - POIFSFileSystem poifs = new POIFSFileSystem(stream); - try { - if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { - return true; - } - } finally { - poifs.close(); - } - throw new IOException("wrong file format or file extension for OO XML file"); - } - return false; - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java deleted file mode 100644 index e798b3533..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.sl.usermodel.TextRun; -import org.apache.poi.sl.usermodel.TextShape; - -public abstract class SlideShowHandler extends POIFSFileHandler { - public void handleSlideShow(SlideShow ss) throws IOException { - renderSlides(ss); - - readContent(ss); - readPictures(ss); - - // write out the file - ByteArrayOutputStream out = writeToArray(ss); - - readContent(ss); - - // read in the writen file - SlideShow read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray())); - try { - assertNotNull(read); - readContent(read); - } finally { - read.close(); - } - } - - private ByteArrayOutputStream writeToArray(SlideShow ss) throws IOException { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - ss.write(stream); - } finally { - stream.close(); - } - - return stream; - } - - - private void readContent(SlideShow ss) { - for (Slide s : ss.getSlides()) { - s.getTitle(); - readText(s); - readText(s.getNotes()); - readText(s.getMasterSheet()); - } - } - - private void readText(ShapeContainer sc) { - if (sc == null) return; - for (Shape s : sc) { - if (s instanceof TextShape) { - for (TextParagraph tp : (TextShape)s) { - for (TextRun tr : tp) { - tr.getRawText(); - } - } - } - } - } - - private void readPictures(SlideShow ss) { - for (PictureData pd : ss.getPictureData()) { - Dimension dim = pd.getImageDimension(); - assertTrue(dim.getHeight() >= 0); - assertTrue(dim.getWidth() >= 0); - } - } - - private void renderSlides(SlideShow ss) { - Dimension pgsize = ss.getPageSize(); - - for (Slide s : ss.getSlides()) { - BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = img.createGraphics(); - DrawFactory.getInstance(graphics).fixFonts(graphics); - - // default rendering options - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - // draw stuff - s.draw(graphics); - - graphics.dispose(); - img.flush(); - } - } -} \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java deleted file mode 100644 index 123bfa745..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java +++ /dev/null @@ -1,131 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.util.RecordFormatException; - -public abstract class SpreadsheetHandler extends AbstractFileHandler { - public void handleWorkbook(Workbook wb) throws IOException { - // try to access some of the content - readContent(wb); - - // write out the file - writeToArray(wb); - - // access some more content (we had cases where writing corrupts the data in memory) - readContent(wb); - - // write once more - ByteArrayOutputStream out = writeToArray(wb); - - // read in the written file - Workbook read; - try { - read = WorkbookFactory.create(new ByteArrayInputStream(out.toByteArray())); - } catch (InvalidFormatException e) { - throw new IllegalStateException(e); - } - assertNotNull(read); - - readContent(read); - - modifyContent(read); - - read.close(); - } - - private ByteArrayOutputStream writeToArray(Workbook wb) throws IOException { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - wb.write(stream); - } finally { - stream.close(); - } - - return stream; - } - - private void readContent(Workbook wb) { - for(int i = 0;i < wb.getNumberOfSheets();i++) { - Sheet sheet = wb.getSheetAt(i); - assertNotNull(wb.getSheet(sheet.getSheetName())); - sheet.groupColumn((short) 4, (short) 5); - sheet.setColumnGroupCollapsed(4, true); - sheet.setColumnGroupCollapsed(4, false); - - // don't do this for very large sheets as it will take a long time - if(sheet.getPhysicalNumberOfRows() > 1000) { - continue; - } - - for(Row row : sheet) { - for(Cell cell : row) { - assertNotNull(cell.toString()); - } - } - } - } - - private void modifyContent(Workbook wb) { - /* a number of file fail because of various things: udf, unimplemented functions, ... - we would need quite a list of excludes and the large regression tests would probably - take a lot longer to run... - try { - // try to re-compute all formulas to find cases where parsing fails - wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); - } catch (RuntimeException e) { - // only allow a specific exception which indicates that an external - // reference was not found - if(!e.getMessage().contains("Could not resolve external workbook name")) { - throw e; - } - - }*/ - - for (int i=wb.getNumberOfSheets()-1; i>=0; i--) { - try { - wb.cloneSheet(i); - } catch (RecordFormatException e) { - if (e.getCause() instanceof CloneNotSupportedException) { - // ignore me - continue; - } - throw e; - } catch (RuntimeException e) { - if ("Could not find 'internal references' EXTERNALBOOK".equals(e.getMessage()) || - "CountryRecord not found".equals(e.getMessage()) || - "Cannot add more than 65535 shapes".equals(e.getMessage()) ) { - // ignore these here for now - continue; - } - throw e; - } - } - } -} \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java deleted file mode 100644 index 9b7d03f8a..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import java.io.InputStream; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.xdgf.usermodel.XmlVisioDocument; -import org.junit.Test; - -public class XDGFFileHandler extends AbstractFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - // ignore password protected files - if (POIXMLDocumentHandler.isEncrypted(stream)) return; - - XmlVisioDocument doc = new XmlVisioDocument(stream); - new POIXMLDocumentHandler().handlePOIXMLDocument(doc); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - OPCPackage pkg = OPCPackage.open("test-data/diagram/test.vsdx", PackageAccess.READ); - try { - XmlVisioDocument doc = new XmlVisioDocument(pkg); - new POIXMLDocumentHandler().handlePOIXMLDocument(doc); - } finally { - pkg.close(); - } - } -} \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java deleted file mode 100644 index 421f842e1..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.junit.Test; - -public class XSLFFileHandler extends SlideShowHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - XMLSlideShow slide = new XMLSlideShow(stream); - XSLFSlideShow slideInner = new XSLFSlideShow(slide.getPackage()); - assertNotNull(slideInner.getPresentation()); - assertNotNull(slideInner.getSlideMasterReferences()); - assertNotNull(slideInner.getSlideReferences()); - - new POIXMLDocumentHandler().handlePOIXMLDocument(slide); - - handleSlideShow(slide); - - slideInner.close(); - slide.close(); - } - - @Override - public void handleExtracting(File file) throws Exception { - super.handleExtracting(file); - - - // additionally try the other getText() methods - - XSLFPowerPointExtractor extractor = (XSLFPowerPointExtractor) ExtractorFactory.createExtractor(file); - try { - assertNotNull(extractor); - - assertNotNull(extractor.getText(true, true, true)); - assertEquals("With all options disabled we should not get text", - "", extractor.getText(false, false, false)); - } finally { - extractor.close(); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Override - @Test - public void test() throws Exception { - InputStream stream = new FileInputStream("test-data/slideshow/ae.ac.uaeu.faculty_nafaachbili_GeomLec1.pptx"); - try { - handleFile(stream); - } finally { - stream.close(); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void testExtractor() throws Exception { - handleExtracting(new File("test-data/slideshow/ae.ac.uaeu.faculty_nafaachbili_GeomLec1.pptx")); - } -} \ No newline at end of file diff --git a/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java deleted file mode 100644 index bfa31c712..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java +++ /dev/null @@ -1,273 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.io.*; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Locale; -import java.util.Set; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.eventusermodel.XLSX2CSV; -import org.apache.poi.xssf.eventusermodel.XSSFReader; -import org.apache.poi.xssf.eventusermodel.examples.FromHowTo; -import org.apache.poi.xssf.extractor.XSSFExportToXml; -import org.apache.poi.xssf.usermodel.XSSFMap; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; -import org.xml.sax.SAXException; - -public class XSSFFileHandler extends SpreadsheetHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - // ignore password protected files - if (POIXMLDocumentHandler.isEncrypted(stream)) return; - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copy(stream, out); - - final byte[] bytes = out.toByteArray(); - final XSSFWorkbook wb; - wb = new XSSFWorkbook(new ByteArrayInputStream(bytes)); - - // use the combined handler for HSSF/XSSF - handleWorkbook(wb); - - // TODO: some documents fail currently... - //XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(wb); - //evaluator.evaluateAll(); - - // also verify general POIFS-stuff - new POIXMLDocumentHandler().handlePOIXMLDocument(wb); - - // and finally ensure that exporting to XML works - exportToXML(wb); - - checkXSSFReader(OPCPackage.open(new ByteArrayInputStream(bytes))); - - wb.close(); - } - - - private void checkXSSFReader(OPCPackage p) throws IOException, OpenXML4JException { - XSSFReader reader = new XSSFReader(p); - - // these can be null... - InputStream sharedStringsData = reader.getSharedStringsData(); - if(sharedStringsData != null) { - sharedStringsData.close(); - } - reader.getSharedStringsTable(); - - InputStream stylesData = reader.getStylesData(); - if(stylesData != null) { - stylesData.close(); - } - reader.getStylesTable(); - - InputStream themesData = reader.getThemesData(); - if(themesData != null) { - themesData.close(); - } - - assertNotNull(reader.getWorkbookData()); - - Iterator sheetsData = reader.getSheetsData(); - while(sheetsData.hasNext()) { - InputStream str = sheetsData.next(); - str.close(); - } - } - - private void exportToXML(XSSFWorkbook wb) throws SAXException, - ParserConfigurationException, TransformerException { - for (XSSFMap map : wb.getCustomXMLMappings()) { - XSSFExportToXml exporter = new XSSFExportToXml(map); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - } - } - - private static final Set EXPECTED_ADDITIONAL_FAILURES = new HashSet(); - static { - // expected sheet-id not found - // EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/52348.xlsx"); - // EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/59021.xlsx"); - // zip-bomb - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764-2.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/poc-xmlbomb.xlsx"); - // strict OOXML - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/57914.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/SampleSS.strict.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/SimpleStrict.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/sample.strict.xlsx"); - // binary format - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/Simple.xlsb"); - // TODO: good to ignore? - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/sample-beta.xlsx"); - - // corrupt/invalid - EXPECTED_ADDITIONAL_FAILURES.add("openxml4j/invalid.xlsx"); - } - - @SuppressWarnings("resource") - @Override - public void handleAdditional(File file) throws Exception { - // redirect stdout as the examples often write lots of text - PrintStream oldOut = System.out; - try { - System.setOut(new NullPrintStream()); - FromHowTo.main(new String[]{file.getAbsolutePath()}); - XLSX2CSV.main(new String[]{file.getAbsolutePath()}); - - assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", - EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())); - - } catch (OLE2NotOfficeXmlFileException e) { - // we have some files that are not actually OOXML and thus cannot be tested here - } catch (IllegalArgumentException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } catch (InvalidFormatException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } catch (IOException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } catch (POIXMLException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { - throw e; - } - } finally { - System.setOut(oldOut); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - InputStream stream = new BufferedInputStream(new FileInputStream("test-data/spreadsheet/ref-56737.xlsx")); - try { - handleFile(stream); - } finally { - stream.close(); - } - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void testExtractor() throws Exception { - handleExtracting(new File("test-data/spreadsheet/ref-56737.xlsx")); - } - - @Test - public void testAdditional() throws Exception { - handleAdditional(new File("test-data/spreadsheet/poc-xmlbomb.xlsx")); - } - - // need to override all methods to omit calls to UTF-handling methods - static class NullPrintStream extends PrintStream { - @SuppressWarnings("resource") - NullPrintStream() { - super(new OutputStream() { - @Override - public void write(int b) {} - @Override - public void write(byte[] b) {} - @Override - public void write(byte[] b, int off, int len) {} - }); - } - @Override - public void write(int b) {} - @Override - public void write(byte[] buf, int off, int len) {} - @Override - public void print(boolean b) {} - @Override - public void print(char c) {} - @Override - public void print(int i) {} - @Override - public void print(long l) {} - @Override - public void print(float f) {} - @Override - public void print(double d) {} - @Override - public void print(char[] s) {} - @Override - public void print(String s) {} - @Override - public void print(Object obj) {} - @Override - public void println() {} - @Override - public void println(boolean x) {} - @Override - public void println(char x) {} - @Override - public void println(int x) {} - @Override - public void println(long x) {} - @Override - public void println(float x) {} - @Override - public void println(double x) {} - @Override - public void println(char[] x) {} - @Override - public void println(String x) {} - @Override - public void println(Object x) {} - @Override - public PrintStream printf(String format, Object... args) { return this; } - @Override - public PrintStream printf(Locale l, String format, Object... args) { return this; } - @Override - public PrintStream format(String format, Object... args) { return this; } - @Override - public PrintStream format(Locale l, String format, Object... args) { return this; } - @Override - public PrintStream append(CharSequence csq) { return this; } - @Override - public PrintStream append(CharSequence csq, int start, int end) { return this; } - @Override - public PrintStream append(char c) { return this; } - @Override - public void write(byte[] b) {} - } -} diff --git a/trunk/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java b/trunk/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java deleted file mode 100644 index c097dc9f7..000000000 --- a/trunk/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.stress; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.PushbackInputStream; - -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.junit.Test; - -public class XWPFFileHandler extends AbstractFileHandler { - @Override - public void handleFile(InputStream stream) throws Exception { - // ignore password protected files - if (POIXMLDocumentHandler.isEncrypted(stream)) return; - - XWPFDocument doc = new XWPFDocument(stream); - - new POIXMLDocumentHandler().handlePOIXMLDocument(doc); - } - - // a test-case to test this locally without executing the full TestAllFiles - @Test - public void test() throws Exception { - File file = new File("test-data/document/51921-Word-Crash067.docx"); - - InputStream stream = new PushbackInputStream(new FileInputStream(file), 100000); - try { - handleFile(stream); - } finally { - stream.close(); - } - - handleExtracting(file); - } - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/EmptyFileException.java b/trunk/src/java/org/apache/poi/EmptyFileException.java deleted file mode 100644 index ddbd14280..000000000 --- a/trunk/src/java/org/apache/poi/EmptyFileException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi; - -/** - * Exception thrown if an Empty (zero byte) file is supplied - */ -public class EmptyFileException extends IllegalArgumentException { - private static final long serialVersionUID = 1536449292174360166L; - - public EmptyFileException() { - super("The supplied file was empty (zero bytes long)"); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/EncryptedDocumentException.java b/trunk/src/java/org/apache/poi/EncryptedDocumentException.java deleted file mode 100644 index 4ac6123e4..000000000 --- a/trunk/src/java/org/apache/poi/EncryptedDocumentException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi; - -public class EncryptedDocumentException extends IllegalStateException -{ - private static final long serialVersionUID = 7276950444540469193L; - - public EncryptedDocumentException(String s) { - super(s); - } - - public EncryptedDocumentException(String message, Throwable cause) { - super(message, cause); - } - - public EncryptedDocumentException(Throwable cause) { - super(cause); - } -} diff --git a/trunk/src/java/org/apache/poi/OldFileFormatException.java b/trunk/src/java/org/apache/poi/OldFileFormatException.java deleted file mode 100644 index 3c01f5459..000000000 --- a/trunk/src/java/org/apache/poi/OldFileFormatException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi; - -/** - * Base class of all the exceptions that POI throws in the event - * that it's given a file that's older than currently supported. - */ -public abstract class OldFileFormatException extends UnsupportedFileFormatException { - private static final long serialVersionUID = 7849681804154571175L; - - public OldFileFormatException(String s) { - super(s); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/POIDocument.java b/trunk/src/java/org/apache/poi/POIDocument.java deleted file mode 100644 index d742c5572..000000000 --- a/trunk/src/java/org/apache/poi/POIDocument.java +++ /dev/null @@ -1,408 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; - -import org.apache.poi.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.MutablePropertySet; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIDecryptor; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This holds the common functionality for all POI - * Document classes. - * Currently, this relates to Document Information Properties - */ -public abstract class POIDocument implements Closeable { - /** Holds metadata on our document */ - private SummaryInformation sInf; - /** Holds further metadata on our document */ - private DocumentSummaryInformation dsInf; - /** The directory that our document lives in */ - protected DirectoryNode directory; - - /** For our own logging use */ - private static final POILogger logger = POILogFactory.getLogger(POIDocument.class); - - /* Have the property streams been read yet? (Only done on-demand) */ - private boolean initialized = false; - - private static final String[] encryptedStreamNames = { "EncryptedSummary" }; - - /** - * Constructs a POIDocument with the given directory node. - * - * @param dir The {@link DirectoryNode} where information is read from. - */ - protected POIDocument(DirectoryNode dir) { - this.directory = dir; - } - - /** - * Constructs from an old-style OPOIFS - * - * @param fs the filesystem the document is read from - */ - protected POIDocument(OPOIFSFileSystem fs) { - this(fs.getRoot()); - } - /** - * Constructs from an old-style OPOIFS - * - * @param fs the filesystem the document is read from - */ - protected POIDocument(NPOIFSFileSystem fs) { - this(fs.getRoot()); - } - /** - * Constructs from the default POIFS - * - * @param fs the filesystem the document is read from - */ - protected POIDocument(POIFSFileSystem fs) { - this(fs.getRoot()); - } - - /** - * Fetch the Document Summary Information of the document - * - * @return The Document Summary Information or null - * if it could not be read for this document. - */ - public DocumentSummaryInformation getDocumentSummaryInformation() { - if(!initialized) readProperties(); - return dsInf; - } - - /** - * Fetch the Summary Information of the document - * - * @return The Summary information for the document or null - * if it could not be read for this document. - */ - public SummaryInformation getSummaryInformation() { - if(!initialized) readProperties(); - return sInf; - } - - /** - * Will create whichever of SummaryInformation - * and DocumentSummaryInformation (HPSF) properties - * are not already part of your document. - * This is normally useful when creating a new - * document from scratch. - * If the information properties are already there, - * then nothing will happen. - */ - public void createInformationProperties() { - if (!initialized) readProperties(); - if (sInf == null) { - sInf = PropertySetFactory.newSummaryInformation(); - } - if (dsInf == null) { - dsInf = PropertySetFactory.newDocumentSummaryInformation(); - } - } - - /** - * Find, and create objects for, the standard - * Document Information Properties (HPSF). - * If a given property set is missing or corrupt, - * it will remain null; - */ - protected void readProperties() { - PropertySet ps; - - // DocumentSummaryInformation - ps = getPropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - if (ps instanceof DocumentSummaryInformation) { - dsInf = (DocumentSummaryInformation)ps; - } else if (ps != null) { - logger.log(POILogger.WARN, "DocumentSummaryInformation property set came back with wrong class - ", ps.getClass()); - } else { - logger.log(POILogger.WARN, "DocumentSummaryInformation property set came back as null"); - } - - // SummaryInformation - ps = getPropertySet(SummaryInformation.DEFAULT_STREAM_NAME); - if (ps instanceof SummaryInformation) { - sInf = (SummaryInformation)ps; - } else if (ps != null) { - logger.log(POILogger.WARN, "SummaryInformation property set came back with wrong class - ", ps.getClass()); - } else { - logger.log(POILogger.WARN, "SummaryInformation property set came back as null"); - } - - // Mark the fact that we've now loaded up the properties - initialized = true; - } - - /** - * For a given named property entry, either return it or null if - * if it wasn't found - * - * @param setName The property to read - * @return The value of the given property or null if it wasn't found. - */ - protected PropertySet getPropertySet(String setName) { - return getPropertySet(setName, null); - } - - /** - * For a given named property entry, either return it or null if - * if it wasn't found - * - * @param setName The property to read - * @param encryptionInfo the encryption descriptor in case of cryptoAPI encryption - * @return The value of the given property or null if it wasn't found. - */ - protected PropertySet getPropertySet(String setName, EncryptionInfo encryptionInfo) { - DirectoryNode dirNode = directory; - - NPOIFSFileSystem encPoifs = null; - String step = "getting"; - try { - if (encryptionInfo != null) { - step = "getting encrypted"; - String encryptedStream = null; - for (String s : encryptedStreamNames) { - if (dirNode.hasEntry(s)) { - encryptedStream = s; - } - } - if (encryptedStream == null) { - throw new EncryptedDocumentException("can't find matching encrypted property stream"); - } - CryptoAPIDecryptor dec = (CryptoAPIDecryptor)encryptionInfo.getDecryptor(); - encPoifs = dec.getSummaryEntries(dirNode, encryptedStream); - dirNode = encPoifs.getRoot(); - } - - //directory can be null when creating new documents - if (dirNode == null || !dirNode.hasEntry(setName)) { - return null; - } - - // Find the entry, and get an input stream for it - step = "getting"; - DocumentInputStream dis = dirNode.createDocumentInputStream( dirNode.getEntry(setName) ); - try { - // Create the Property Set - step = "creating"; - return PropertySetFactory.create(dis); - } finally { - dis.close(); - } - } catch (Exception e) { - logger.log(POILogger.WARN, "Error "+step+" property set with name " + setName, e); - return null; - } finally { - if (encPoifs != null) { - try { - encPoifs.close(); - } catch(IOException e) { - logger.log(POILogger.WARN, "Error closing encrypted property poifs", e); - } - } - } - } - - /** - * Writes out the updated standard Document Information Properties (HPSF) - * into the currently open NPOIFSFileSystem - * - * @throws IOException if an error when writing to the open - * {@link NPOIFSFileSystem} occurs - */ - protected void writeProperties() throws IOException { - validateInPlaceWritePossible(); - writeProperties(directory.getFileSystem(), null); - } - - /** - * Writes out the standard Document Information Properties (HPSF) - * @param outFS the POIFSFileSystem to write the properties into - * - * @throws IOException if an error when writing to the - * {@link NPOIFSFileSystem} occurs - */ - protected void writeProperties(NPOIFSFileSystem outFS) throws IOException { - writeProperties(outFS, null); - } - /** - * Writes out the standard Document Information Properties (HPSF) - * @param outFS the NPOIFSFileSystem to write the properties into - * @param writtenEntries a list of POIFS entries to add the property names too - * - * @throws IOException if an error when writing to the - * {@link NPOIFSFileSystem} occurs - */ - protected void writeProperties(NPOIFSFileSystem outFS, List writtenEntries) throws IOException { - SummaryInformation si = getSummaryInformation(); - if (si != null) { - writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME, si, outFS); - if(writtenEntries != null) { - writtenEntries.add(SummaryInformation.DEFAULT_STREAM_NAME); - } - } - DocumentSummaryInformation dsi = getDocumentSummaryInformation(); - if (dsi != null) { - writePropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME, dsi, outFS); - if(writtenEntries != null) { - writtenEntries.add(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - } - } - } - - /** - * Writes out a given ProperySet - * @param name the (POIFS Level) name of the property to write - * @param set the PropertySet to write out - * @param outFS the NPOIFSFileSystem to write the property into - * - * @throws IOException if an error when writing to the - * {@link NPOIFSFileSystem} occurs - */ - protected void writePropertySet(String name, PropertySet set, NPOIFSFileSystem outFS) throws IOException { - try { - MutablePropertySet mSet = new MutablePropertySet(set); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - mSet.write(bOut); - byte[] data = bOut.toByteArray(); - ByteArrayInputStream bIn = new ByteArrayInputStream(data); - - // Create or Update the Property Set stream in the POIFS - outFS.createOrUpdateDocument(bIn, name); - - logger.log(POILogger.INFO, "Wrote property set " + name + " of size " + data.length); - } catch(org.apache.poi.hpsf.WritingNotSupportedException wnse) { - logger.log( POILogger.ERROR, "Couldn't write property set with name " + name + " as not supported by HPSF yet"); - } - } - - /** - * Called during a {@link #write()} to ensure that the Document (and - * associated {@link POIFSFileSystem}) was opened in a way compatible - * with an in-place write. - * - * @throws IllegalStateException if the document was opened suitably - */ - protected void validateInPlaceWritePossible() throws IllegalStateException { - if (directory == null) { - throw new IllegalStateException("Newly created Document, cannot save in-place"); - } - if (directory.getParent() != null) { - throw new IllegalStateException("This is not the root Document, cannot save embedded resource in-place"); - } - if (directory.getFileSystem() == null || - !directory.getFileSystem().isInPlaceWriteable()) { - throw new IllegalStateException("Opened read-only or via an InputStream, a Writeable File is required"); - } - } - - /** - * Writes the document out to the currently open {@link File}, via the - * writeable {@link POIFSFileSystem} it was opened from. - * - *

    This will fail (with an {@link IllegalStateException} if the - * document was opened read-only, opened from an {@link InputStream} - * instead of a File, or if this is not the root document. For those cases, - * you must use {@link #write(OutputStream)} or {@link #write(File)} to - * write to a brand new document. - * - * @since POI 3.15 beta 3 - * - * @throws IOException thrown on errors writing to the file - * @throws IllegalStateException if this isn't from a writable File - */ - public abstract void write() throws IOException; - - /** - * Writes the document out to the specified new {@link File}. If the file - * exists, it will be replaced, otherwise a new one will be created - * - * @since POI 3.15 beta 3 - * - * @param newFile The new File to write to. - * - * @throws IOException thrown on errors writing to the file - */ - public abstract void write(File newFile) throws IOException; - - /** - * Writes the document out to the specified output stream. The - * stream is not closed as part of this operation. - * - * Note - if the Document was opened from a {@link File} rather - * than an {@link InputStream}, you must write out using - * {@link #write()} or to a different File. Overwriting the currently - * open file via an OutputStream isn't possible. - * - * If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive - * or has a high cost/latency associated with each written byte, - * consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream} - * to improve write performance, or use {@link #write()} / {@link #write(File)} - * if possible. - * - * @param out The stream to write to. - * - * @throws IOException thrown on errors writing to the stream - */ - public abstract void write(OutputStream out) throws IOException; - - /** - * Closes the underlying {@link NPOIFSFileSystem} from which - * the document was read, if any. Has no effect on documents - * opened from an InputStream, or newly created ones. - *

    Once {@link #close()} has been called, no further operations - * should be called on the document. - */ - public void close() throws IOException { - if (directory != null) { - if (directory.getNFileSystem() != null) { - directory.getNFileSystem().close(); - directory = null; - } - } - } - - @Internal - public DirectoryNode getDirectory() { - return directory; - } -} diff --git a/trunk/src/java/org/apache/poi/POIOLE2TextExtractor.java b/trunk/src/java/org/apache/poi/POIOLE2TextExtractor.java deleted file mode 100644 index 24bbb9a65..000000000 --- a/trunk/src/java/org/apache/poi/POIOLE2TextExtractor.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor; -import org.apache.poi.poifs.filesystem.DirectoryEntry; - -/** - * Common Parent for OLE2 based Text Extractors - * of POI Documents, such as .doc, .xls - * You will typically find the implementation of - * a given format's text extractor under - * org.apache.poi.[format].extractor . - * - * @see org.apache.poi.hssf.extractor.ExcelExtractor - * @see org.apache.poi.hslf.extractor.PowerPointExtractor - * @see org.apache.poi.hdgf.extractor.VisioTextExtractor - * @see org.apache.poi.hwpf.extractor.WordExtractor - */ -public abstract class POIOLE2TextExtractor extends POITextExtractor { - /** The POIDocument that's open */ - protected POIDocument document; - - /** - * Creates a new text extractor for the given document - * - * @param document The POIDocument to use in this extractor. - */ - public POIOLE2TextExtractor(POIDocument document) { - this.document = document; - - // Ensure any underlying resources, such as open files, - // will get cleaned up if the user calls #close() - setFilesystem(document); - } - - /** - * Creates a new text extractor, using the same - * document as another text extractor. Normally - * only used by properties extractors. - * - * @param otherExtractor the extractor which document to be used - */ - protected POIOLE2TextExtractor(POIOLE2TextExtractor otherExtractor) { - this.document = otherExtractor.document; - } - - /** - * Returns the document information metadata for the document - * - * @return The Document Summary Information or null - * if it could not be read for this document. - */ - public DocumentSummaryInformation getDocSummaryInformation() { - return document.getDocumentSummaryInformation(); - } - /** - * Returns the summary information metadata for the document. - * - * @return The Summary information for the document or null - * if it could not be read for this document. - */ - public SummaryInformation getSummaryInformation() { - return document.getSummaryInformation(); - } - - /** - * Returns an HPSF powered text extractor for the - * document properties metadata, such as title and author. - * - * @return an instance of POIExtractor that can extract meta-data. - */ - @Override - public POITextExtractor getMetadataTextExtractor() { - return new HPSFPropertiesExtractor(this); - } - - /** - * Return the underlying DirectoryEntry of this document. - * - * @return the DirectoryEntry that is associated with the POIDocument of this extractor. - */ - public DirectoryEntry getRoot() - { - return document.directory; - } -} diff --git a/trunk/src/java/org/apache/poi/POITextExtractor.java b/trunk/src/java/org/apache/poi/POITextExtractor.java deleted file mode 100644 index 83e26be94..000000000 --- a/trunk/src/java/org/apache/poi/POITextExtractor.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.Closeable; -import java.io.IOException; - -/** - * Common Parent for Text Extractors - * of POI Documents. - * You will typically find the implementation of - * a given format's text extractor under - * org.apache.poi.[format].extractor . - * - * @see org.apache.poi.hssf.extractor.ExcelExtractor - * @see org.apache.poi.hslf.extractor.PowerPointExtractor - * @see org.apache.poi.hdgf.extractor.VisioTextExtractor - * @see org.apache.poi.hwpf.extractor.WordExtractor - */ -public abstract class POITextExtractor implements Closeable { - private Closeable fsToClose = null; - - /** - * Retrieves all the text from the document. - * How cells, paragraphs etc are separated in the text - * is implementation specific - see the javadocs for - * a specific project for details. - * @return All the text from the document - */ - public abstract String getText(); - - /** - * Returns another text extractor, which is able to - * output the textual content of the document - * metadata / properties, such as author and title. - * - * @return the metadata and text extractor - */ - public abstract POITextExtractor getMetadataTextExtractor(); - - /** - * Used to ensure file handle cleanup. - * - * @param fs filesystem to close - */ - public void setFilesystem(Closeable fs) { - fsToClose = fs; - } - - /** - * Allows to free resources of the Extractor as soon as - * it is not needed any more. This may include closing - * open file handles and freeing memory. - * - * The Extractor cannot be used after close has been called. - */ - @Override - public void close() throws IOException { - if(fsToClose != null) { - fsToClose.close(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/UnsupportedFileFormatException.java b/trunk/src/java/org/apache/poi/UnsupportedFileFormatException.java deleted file mode 100644 index a8caebb4b..000000000 --- a/trunk/src/java/org/apache/poi/UnsupportedFileFormatException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi; - -/** - * Base class of all the exceptions that POI throws in the event - * that it's given a file that isn't supported - */ -public abstract class UnsupportedFileFormatException extends IllegalArgumentException { - private static final long serialVersionUID = -8281969197282030046L; - - public UnsupportedFileFormatException(String s) { - super(s); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/common/usermodel/Hyperlink.java b/trunk/src/java/org/apache/poi/common/usermodel/Hyperlink.java deleted file mode 100644 index abcdd112a..000000000 --- a/trunk/src/java/org/apache/poi/common/usermodel/Hyperlink.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.common.usermodel; - -import org.apache.poi.util.Removal; - -/** - * Represents a hyperlink. - */ -public interface Hyperlink { - /** - * Link to an existing file or web page - * - * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#URL} instead. - */ - @Removal(version="3.17") - public static final int LINK_URL = 1; // HyperlinkType.URL.getCode() - - /** - * Link to a place in this document - * - * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#DOCUMENT} instead. - */ - @Removal(version="3.17") - public static final int LINK_DOCUMENT = 2; // HyperlinkType.DOCUMENT.getCode() - - /** - * Link to an E-mail address - * - * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#EMAIL} instead. - */ - @Removal(version="3.17") - public static final int LINK_EMAIL = 3; // HyperlinkType.EMAIL.getCode() - - /** - * Link to an file - * - * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#FILE} instead. - */ - @Removal(version="3.17") - public static final int LINK_FILE = 4; // HyperlinkType.FILE.getCode() - - - /** - * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc. - * - * @return the address of this hyperlink - */ - public String getAddress(); - - /** - * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc. - * - * @param address the address of this hyperlink - */ - public void setAddress(String address); - - /** - * Return text label for this hyperlink - * - * @return text to display - */ - public String getLabel(); - - /** - * Sets text label for this hyperlink - * - * @param label text label for this hyperlink - */ - public void setLabel(String label); - - /** - * Return the type of this hyperlink - * - * @return the type of this hyperlink - * @see HyperlinkType#forInt(int) - * @deprecated POI 3.15 beta 3. Use {@link #getTypeEnum()} - * getType will return a HyperlinkType enum in the future. - */ - public int getType(); - - /** - * Return the type of this hyperlink - * - * @return the type of this hyperlink - * @since POI 3.15 beta 3 - */ - public HyperlinkType getTypeEnum(); -} diff --git a/trunk/src/java/org/apache/poi/common/usermodel/HyperlinkType.java b/trunk/src/java/org/apache/poi/common/usermodel/HyperlinkType.java deleted file mode 100644 index 41de80062..000000000 --- a/trunk/src/java/org/apache/poi/common/usermodel/HyperlinkType.java +++ /dev/null @@ -1,107 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.common.usermodel; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.util.Internal; - -/** - * @since POI 3.15 beta 3 - */ -public enum HyperlinkType { - /** Not a hyperlink */ - @Internal - NONE(-1), - - /** - * Link to an existing file or web page - */ - URL(1), - - /** - * Link to a place in this document - */ - DOCUMENT(2), - - /** - * Link to an E-mail address - */ - EMAIL(3), - - /** - * Link to a file - */ - FILE(4); - - - /** @deprecated POI 3.15 beta 3 */ - @Internal(since="3.15 beta 3") - @Deprecated - private final int code; - - /** - * The codes don't have any real meaning. - * They are bytes that are read in and written out from HSSF, HSLF, XSSF, and XSLF are different - * that the codes here. - * These codes only exist to assist in transitioning from using ints to enums. - * - * @param code The unique number for this type. - * @deprecated POI 3.15 beta 3 - */ - @Internal(since="3.15 beta 3") - @Deprecated - HyperlinkType(int code) { - this.code = code; - } - - private static final Map map = new HashMap(); - static { - for (HyperlinkType type : values()) { - map.put(type.getCode(), type); - } - } - - /** - * @deprecated POI 3.15 beta 3 - * - * @return the old integer code for a HyperlinkType enum - */ - @Internal(since="3.15 beta 3") - @Deprecated - public int getCode() { - return code; - } - - /** - * @deprecated POI 3.15 beta 3 - * - * @param code the old integer code - * @return the corresponding HyperlinkEnum, if it exists - * @throws IllegalArgumentException if {@code code} is not a valid HyperlinkType. - */ - @Internal(since="3.15 beta 3") - @Deprecated - public static HyperlinkType forInt(int code) { - HyperlinkType type = map.get(code); - if (type == null) { - throw new IllegalArgumentException("Invalid type: " + code); - } - return type; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java b/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java deleted file mode 100644 index c8d2c95c8..000000000 --- a/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java +++ /dev/null @@ -1,227 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ddf; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * Common abstract class for {@link EscherOptRecord} and - * {@link EscherTertiaryOptRecord} - */ -public abstract class AbstractEscherOptRecord extends EscherRecord -{ - protected List properties = new ArrayList(); - - /** - * Add a property to this record. - * - * @param prop the escher property to add - */ - public void addEscherProperty( EscherProperty prop ) - { - properties.add( prop ); - } - - @Override - public int fillFields( byte[] data, int offset, - EscherRecordFactory recordFactory ) - { - int bytesRemaining = readHeader( data, offset ); - short propertiesCount = readInstance( data, offset ); - int pos = offset + 8; - - EscherPropertyFactory f = new EscherPropertyFactory(); - properties = f.createProperties( data, pos, propertiesCount ); - return bytesRemaining + 8; - } - - /** - * The list of properties stored by this record. - * - * @return the list of properties - */ - public List getEscherProperties() - { - return properties; - } - - /** - * The list of properties stored by this record. - * - * @param index the ordinal index of the property - * @return the escher property - */ - public EscherProperty getEscherProperty( int index ) - { - return properties.get( index ); - } - - - private int getPropertiesSize() - { - int totalSize = 0; - for ( EscherProperty property : properties ) - { - totalSize += property.getPropertySize(); - } - - return totalSize; - } - - @Override - public int getRecordSize() - { - return 8 + getPropertiesSize(); - } - - public T lookup( int propId ) - { - for ( EscherProperty prop : properties ) - { - if ( prop.getPropertyNumber() == propId ) - { - @SuppressWarnings( "unchecked" ) - final T result = (T) prop; - return result; - } - } - return null; - } - - @Override - public int serialize( int offset, byte[] data, - EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - LittleEndian.putInt( data, offset + 4, getPropertiesSize() ); - int pos = offset + 8; - for ( EscherProperty property : properties ) - { - pos += property.serializeSimplePart( data, pos ); - } - for ( EscherProperty property : properties ) - { - pos += property.serializeComplexPart( data, pos ); - } - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return pos - offset; - } - - /** - * Records should be sorted by property number before being stored. - */ - public void sortProperties() - { - Collections.sort( properties, new Comparator() - { - @Override - public int compare( EscherProperty p1, EscherProperty p2 ) - { - short s1 = p1.getPropertyNumber(); - short s2 = p2.getPropertyNumber(); - return s1 < s2 ? -1 : s1 == s2 ? 0 : 1; - } - } ); - } - - /** - * Set an escher property. If a property with given propId already - exists it is replaced. - * - * @param value the property to set. - */ - public void setEscherProperty(EscherProperty value){ - for ( Iterator iterator = - properties.iterator(); iterator.hasNext(); ) { - EscherProperty prop = iterator.next(); - if (prop.getId() == value.getId()){ - iterator.remove(); - } - } - properties.add( value ); - sortProperties(); - } - - public void removeEscherProperty(int num){ - for ( Iterator iterator = getEscherProperties().iterator(); iterator.hasNext(); ) { - EscherProperty prop = iterator.next(); - if (prop.getPropertyNumber() == num){ - iterator.remove(); - } - } - } - - /** - * Retrieve the string representation of this record. - */ - @Override - public String toString() - { - String nl = System.getProperty( "line.separator" ); - - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append( getClass().getName() ); - stringBuilder.append( ":" ); - stringBuilder.append( nl ); - stringBuilder.append( " isContainer: " ); - stringBuilder.append( isContainerRecord() ); - stringBuilder.append( nl ); - stringBuilder.append( " version: 0x" ); - stringBuilder.append( HexDump.toHex( getVersion() ) ); - stringBuilder.append( nl ); - stringBuilder.append( " instance: 0x" ); - stringBuilder.append( HexDump.toHex( getInstance() ) ); - stringBuilder.append( nl ); - stringBuilder.append( " recordId: 0x" ); - stringBuilder.append( HexDump.toHex( getRecordId() ) ); - stringBuilder.append( nl ); - stringBuilder.append( " numchildren: " ); - stringBuilder.append( getChildRecords().size() ); - stringBuilder.append( nl ); - stringBuilder.append( " properties:" ); - stringBuilder.append( nl ); - - for ( EscherProperty property : properties ) - { - stringBuilder.append(" ").append(property.toString()).append(nl); - } - - return stringBuilder.toString(); - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), - HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))); - for (EscherProperty property: getEscherProperties()){ - builder.append(property.toXml(tab+"\t")); - } - builder.append(tab).append("\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java b/trunk/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java deleted file mode 100644 index 4342708bf..000000000 --- a/trunk/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.lang.reflect.Constructor; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.util.LittleEndian; - -/** - * Generates escher records when provided the byte array containing those records. - * - * @see EscherRecordFactory - */ -public class DefaultEscherRecordFactory implements EscherRecordFactory { - private static Class[] escherRecordClasses = { EscherBSERecord.class, - EscherOptRecord.class, EscherTertiaryOptRecord.class, - EscherClientAnchorRecord.class, EscherDgRecord.class, - EscherSpgrRecord.class, EscherSpRecord.class, - EscherClientDataRecord.class, EscherDggRecord.class, - EscherSplitMenuColorsRecord.class, EscherChildAnchorRecord.class, - EscherTextboxRecord.class }; - private static Map> recordsMap = recordsToMap( escherRecordClasses ); - - /** - * Creates an instance of the escher record factory - */ - public DefaultEscherRecordFactory() { - // no instance initialisation - } - - @Override - public EscherRecord createRecord(byte[] data, int offset) { - short options = LittleEndian.getShort( data, offset ); - short recordId = LittleEndian.getShort( data, offset + 2 ); - // int remainingBytes = LittleEndian.getInt( data, offset + 4 ); - - // Options of 0x000F means container record - // However, EscherTextboxRecord are containers of records for the - // host application, not of other Escher records, so treat them - // differently - if (isContainer(options, recordId)) { - EscherContainerRecord r = new EscherContainerRecord(); - r.setRecordId( recordId ); - r.setOptions( options ); - return r; - } - - if (recordId >= EscherBlipRecord.RECORD_ID_START - && recordId <= EscherBlipRecord.RECORD_ID_END) { - EscherBlipRecord r; - if (recordId == EscherBitmapBlip.RECORD_ID_DIB || - recordId == EscherBitmapBlip.RECORD_ID_JPEG || - recordId == EscherBitmapBlip.RECORD_ID_PNG) - { - r = new EscherBitmapBlip(); - } - else if (recordId == EscherMetafileBlip.RECORD_ID_EMF || - recordId == EscherMetafileBlip.RECORD_ID_WMF || - recordId == EscherMetafileBlip.RECORD_ID_PICT) - { - r = new EscherMetafileBlip(); - } else { - r = new EscherBlipRecord(); - } - r.setRecordId( recordId ); - r.setOptions( options ); - return r; - } - - Constructor recordConstructor = recordsMap.get(Short.valueOf(recordId)); - final EscherRecord escherRecord; - if (recordConstructor == null) { - return new UnknownEscherRecord(); - } - try { - escherRecord = recordConstructor.newInstance(); - } catch (Exception e) { - return new UnknownEscherRecord(); - } - escherRecord.setRecordId(recordId); - escherRecord.setOptions(options); - return escherRecord; - } - - /** - * Converts from a list of classes into a map that contains the record id as the key and - * the Constructor in the value part of the map. It does this by using reflection to look up - * the RECORD_ID field then using reflection again to find a reference to the constructor. - * - * @param recClasses The records to convert - * @return The map containing the id/constructor pairs. - */ - protected static Map> recordsToMap(Class[] recClasses) { - Map> result = new HashMap>(); - final Class[] EMPTY_CLASS_ARRAY = new Class[0]; - - for (Class recClass : recClasses) { - @SuppressWarnings("unchecked") - Class recCls = (Class) recClass; - short sid; - try { - sid = recCls.getField("RECORD_ID").getShort(null); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } - Constructor constructor; - try { - constructor = recCls.getConstructor(EMPTY_CLASS_ARRAY); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - result.put(Short.valueOf(sid), constructor); - } - return result; - } - - public static boolean isContainer(short options, short recordId){ - if(recordId >= EscherContainerRecord.DGG_CONTAINER && recordId - <= EscherContainerRecord.SOLVER_CONTAINER){ - return true; - } else { - if (recordId == EscherTextboxRecord.RECORD_ID) { - return false; - } else { - return ( options & (short) 0x000F ) == (short) 0x000F; - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java deleted file mode 100644 index bf7211d3c..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java +++ /dev/null @@ -1,233 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * Escher array properties are the most wierd construction ever invented - * with all sorts of special cases. I'm hopeful I've got them all. - */ -public final class EscherArrayProperty extends EscherComplexProperty implements Iterable { - /** - * The size of the header that goes at the - * start of the array, before the data - */ - private static final int FIXED_SIZE = 3 * 2; - /** - * Normally, the size recorded in the simple data (for the complex - * data) includes the size of the header. - * There are a few cases when it doesn't though... - */ - private boolean sizeIncludesHeaderSize = true; - - /** - * When reading a property from data stream remember if the complex part is empty and set this flag. - */ - private boolean emptyComplexPart = false; - - public EscherArrayProperty(short id, byte[] complexData) { - super(id, checkComplexData(complexData)); - emptyComplexPart = complexData.length == 0; - } - - public EscherArrayProperty(short propertyNumber, boolean isBlipId, byte[] complexData) { - super(propertyNumber, isBlipId, checkComplexData(complexData)); - } - - private static byte[] checkComplexData(byte[] complexData) { - if (complexData == null || complexData.length == 0) { - return new byte[6]; - } - - return complexData; - } - - public int getNumberOfElementsInArray() { - return (emptyComplexPart) ? 0 : LittleEndian.getUShort(_complexData, 0); - } - - public void setNumberOfElementsInArray(int numberOfElements) { - int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE; - if (expectedArraySize != _complexData.length) { - byte[] newArray = new byte[expectedArraySize]; - System.arraycopy(_complexData, 0, newArray, 0, _complexData.length); - _complexData = newArray; - } - LittleEndian.putShort(_complexData, 0, (short) numberOfElements); - } - - public int getNumberOfElementsInMemory() { - return (emptyComplexPart) ? 0 : LittleEndian.getUShort(_complexData, 2); - } - - public void setNumberOfElementsInMemory(int numberOfElements) { - int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE; - if (expectedArraySize != _complexData.length) { - byte[] newArray = new byte[expectedArraySize]; - System.arraycopy(_complexData, 0, newArray, 0, expectedArraySize); - _complexData = newArray; - } - LittleEndian.putShort(_complexData, 2, (short) numberOfElements); - } - - public short getSizeOfElements() { - return (emptyComplexPart) ? 0 : LittleEndian.getShort( _complexData, 4 ); - } - - public void setSizeOfElements(int sizeOfElements) { - LittleEndian.putShort( _complexData, 4, (short) sizeOfElements ); - - int expectedArraySize = getNumberOfElementsInArray() * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE; - if (expectedArraySize != _complexData.length) { - // Keep just the first 6 bytes. The rest is no good to us anyway. - byte[] newArray = new byte[expectedArraySize]; - System.arraycopy( _complexData, 0, newArray, 0, 6 ); - _complexData = newArray; - } - } - - public byte[] getElement(int index) { - int actualSize = getActualSizeOfElements(getSizeOfElements()); - byte[] result = new byte[actualSize]; - System.arraycopy(_complexData, FIXED_SIZE + index * actualSize, result, 0, result.length ); - return result; - } - - public void setElement(int index, byte[] element) { - int actualSize = getActualSizeOfElements(getSizeOfElements()); - System.arraycopy( element, 0, _complexData, FIXED_SIZE + index * actualSize, actualSize); - } - - @Override - public String toString() { - StringBuffer results = new StringBuffer(); - results.append(" {EscherArrayProperty:" + '\n'); - results.append(" Num Elements: " + getNumberOfElementsInArray() + '\n'); - results.append(" Num Elements In Memory: " + getNumberOfElementsInMemory() + '\n'); - results.append(" Size of elements: " + getSizeOfElements() + '\n'); - for (int i = 0; i < getNumberOfElementsInArray(); i++) { - results.append(" Element " + i + ": " + HexDump.toHex(getElement(i)) + '\n'); - } - results.append("}" + '\n'); - - return "propNum: " + getPropertyNumber() - + ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() ) - + ", complex: " + isComplex() - + ", blipId: " + isBlipId() - + ", data: " + '\n' + results.toString(); - } - - @Override - public String toXml(String tab){ - StringBuilder builder = new StringBuilder(); - builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId())) - .append("\" name=\"").append(getName()).append("\" blipId=\"") - .append(isBlipId()).append("\">\n"); - for (int i = 0; i < getNumberOfElementsInArray(); i++) { - builder.append("\t").append(tab).append("").append(HexDump.toHex(getElement(i))).append("\n"); - } - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * We have this method because the way in which arrays in escher works - * is screwed for seemly arbitary reasons. While most properties are - * fairly consistent and have a predictable array size, escher arrays - * have special cases. - * - * @param data The data array containing the escher array information - * @param offset The offset into the array to start reading from. - * @return the number of bytes used by this complex property. - */ - public int setArrayData(byte[] data, int offset) { - if (emptyComplexPart){ - _complexData = new byte[0]; - } else { - short numElements = LittleEndian.getShort(data, offset); - // LittleEndian.getShort(data, offset + 2); // numReserved - short sizeOfElements = LittleEndian.getShort(data, offset + 4); - - int arraySize = getActualSizeOfElements(sizeOfElements) * numElements; - if (arraySize == _complexData.length) { - // The stored data size in the simple block excludes the header size - _complexData = new byte[arraySize + 6]; - sizeIncludesHeaderSize = false; - } - System.arraycopy(data, offset, _complexData, 0, _complexData.length ); - } - return _complexData.length; - } - - /** - * Serializes the simple part of this property. ie the first 6 bytes. - * - * Needs special code to handle the case when the size doesn't - * include the size of the header block - */ - @Override - public int serializeSimplePart(byte[] data, int pos) { - LittleEndian.putShort(data, pos, getId()); - int recordSize = _complexData.length; - if(!sizeIncludesHeaderSize) { - recordSize -= 6; - } - LittleEndian.putInt(data, pos + 2, recordSize); - return 6; - } - - /** - * Sometimes the element size is stored as a negative number. We - * negate it and shift it to get the real value. - */ - private static int getActualSizeOfElements(short sizeOfElements) { - if (sizeOfElements < 0) { - return (short) ( ( -sizeOfElements ) >> 2 ); - } - return sizeOfElements; - } - - @Override - public Iterator iterator() { - return new Iterator(){ - int idx = 0; - @Override - public boolean hasNext() { - return (idx < getNumberOfElementsInArray()); - } - - @Override - public byte[] next() { - if (!hasNext()) throw new NoSuchElementException(); - return getElement(idx++); - } - - @Override - public void remove() { - throw new UnsupportedOperationException("not yet implemented"); - } - }; - } - - -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java b/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java deleted file mode 100644 index 776881038..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java +++ /dev/null @@ -1,424 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * The BSE record is related closely to the EscherBlipRecord and stores - * extra information about the blip. A blip record is actually stored inside - * the BSE record even though the BSE record isn't actually a container record. - * - * @see EscherBlipRecord - */ -public final class EscherBSERecord extends EscherRecord { - public static final short RECORD_ID = (short) 0xF007; - public static final String RECORD_DESCRIPTION = "MsofbtBSE"; - - public static final byte BT_ERROR = 0; - public static final byte BT_UNKNOWN = 1; - public static final byte BT_EMF = 2; - public static final byte BT_WMF = 3; - public static final byte BT_PICT = 4; - public static final byte BT_JPEG = 5; - public static final byte BT_PNG = 6; - public static final byte BT_DIB = 7; - - private byte field_1_blipTypeWin32; - private byte field_2_blipTypeMacOS; - private final byte[] field_3_uid = new byte[16]; - private short field_4_tag; - private int field_5_size; - private int field_6_ref; - private int field_7_offset; - private byte field_8_usage; - private byte field_9_name; - private byte field_10_unused2; - private byte field_11_unused3; - private EscherBlipRecord field_12_blipRecord; - - private byte[] _remainingData = new byte[0]; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - field_1_blipTypeWin32 = data[pos]; - field_2_blipTypeMacOS = data[pos + 1]; - System.arraycopy( data, pos + 2, field_3_uid, 0, 16 ); - field_4_tag = LittleEndian.getShort( data, pos + 18 ); - field_5_size = LittleEndian.getInt( data, pos + 20 ); - field_6_ref = LittleEndian.getInt( data, pos + 24 ); - field_7_offset = LittleEndian.getInt( data, pos + 28 ); - field_8_usage = data[pos + 32]; - field_9_name = data[pos + 33]; - field_10_unused2 = data[pos + 34]; - field_11_unused3 = data[pos + 35]; - bytesRemaining -= 36; - - int bytesRead = 0; - if (bytesRemaining > 0) { - // Some older escher formats skip this last record - field_12_blipRecord = (EscherBlipRecord) recordFactory.createRecord( data, pos + 36 ); - bytesRead = field_12_blipRecord.fillFields( data, pos + 36, recordFactory ); - } - pos += 36 + bytesRead; - bytesRemaining -= bytesRead; - - _remainingData = new byte[bytesRemaining]; - System.arraycopy( data, pos, _remainingData, 0, bytesRemaining ); - return bytesRemaining + 8 + 36 + (field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize()) ; - - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - if (_remainingData == null) { - _remainingData = new byte[0]; - } - - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - int blipSize = field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize(); - int remainingBytes = _remainingData.length + 36 + blipSize; - LittleEndian.putInt( data, offset + 4, remainingBytes ); - - data[offset + 8] = field_1_blipTypeWin32; - data[offset + 9] = field_2_blipTypeMacOS; - for ( int i = 0; i < 16; i++ ) - data[offset + 10 + i] = field_3_uid[i]; - LittleEndian.putShort( data, offset + 26, field_4_tag ); - LittleEndian.putInt( data, offset + 28, field_5_size ); - LittleEndian.putInt( data, offset + 32, field_6_ref ); - LittleEndian.putInt( data, offset + 36, field_7_offset ); - data[offset + 40] = field_8_usage; - data[offset + 41] = field_9_name; - data[offset + 42] = field_10_unused2; - data[offset + 43] = field_11_unused3; - int bytesWritten = 0; - if (field_12_blipRecord != null) - { - bytesWritten = field_12_blipRecord.serialize( offset + 44, data, new NullEscherSerializationListener() ); - } - System.arraycopy( _remainingData, 0, data, offset + 44 + bytesWritten, _remainingData.length ); - int pos = offset + 8 + 36 + _remainingData.length + bytesWritten; - - listener.afterRecordSerialize(pos, getRecordId(), pos - offset, this); - return pos - offset; - } - - @Override - public int getRecordSize() { - int field_12_size = 0; - if(field_12_blipRecord != null) { - field_12_size = field_12_blipRecord.getRecordSize(); - } - int remaining_size = 0; - if(_remainingData != null) { - remaining_size = _remainingData.length; - } - return 8 + 1 + 1 + 16 + 2 + 4 + 4 + 4 + 1 + 1 + - 1 + 1 + field_12_size + remaining_size; - } - - @Override - public String getRecordName() { - return "BSE"; - } - - /** - * The expected blip type under windows (failure to match this blip type will result in - * Excel converting to this format). - * - * @return win32 blip type - */ - public byte getBlipTypeWin32() { - return field_1_blipTypeWin32; - } - - /** - * Set the expected win32 blip type - * - * @param blipTypeWin32 win32 blip type - */ - public void setBlipTypeWin32(byte blipTypeWin32) { - field_1_blipTypeWin32 = blipTypeWin32; - } - - /** - * The expected blip type under MacOS (failure to match this blip type will result in - * Excel converting to this format). - * - * @return MacOS blip type - */ - public byte getBlipTypeMacOS() { - return field_2_blipTypeMacOS; - } - - /** - * Set the expected MacOS blip type - * - * @param blipTypeMacOS MacOS blip type - */ - public void setBlipTypeMacOS(byte blipTypeMacOS) { - field_2_blipTypeMacOS = blipTypeMacOS; - } - - /** - * 16 byte MD4 checksum. - * - * @return 16 byte MD4 checksum - */ - public byte[] getUid() { - return field_3_uid; - } - - /** - * 16 byte MD4 checksum. - * - * @param uid 16 byte MD4 checksum - */ - public void setUid(byte[] uid) { - if (uid == null || uid.length != 16) { - throw new IllegalArgumentException("uid must be byte[16]"); - } - System.arraycopy(uid, 0, field_3_uid, 0, field_3_uid.length); - } - - /** - * unused - * - * @return an unknown tag - */ - public short getTag() { - return field_4_tag; - } - - /** - * unused - * - * @param tag unknown tag - */ - public void setTag(short tag) { - field_4_tag = tag; - } - - /** - * Blip size in stream. - * - * @return the blip size - */ - public int getSize() { - return field_5_size; - } - - /** - * Blip size in stream. - * - * @param size blip size - */ - public void setSize(int size) { - field_5_size = size; - } - - /** - * The reference count of this blip. - * - * @return the reference count - */ - public int getRef() { - return field_6_ref; - } - - /** - * The reference count of this blip. - * - * @param ref the reference count - */ - public void setRef(int ref) { - field_6_ref = ref; - } - - /** - * File offset in the delay stream. - * - * @return the file offset - */ - public int getOffset() { - return field_7_offset; - } - - /** - * File offset in the delay stream. - * - * @param offset the file offset - */ - public void setOffset(int offset) { - field_7_offset = offset; - } - - /** - * Defines the way this blip is used. - * - * @return the blip usage - */ - public byte getUsage() { - return field_8_usage; - } - - /** - * Defines the way this blip is used. - * - * @param usage the blip usae - */ - public void setUsage(byte usage) { - field_8_usage = usage; - } - - /** - * The length in characters of the blip name. - * - * @return the blip name length - */ - public byte getName() { - return field_9_name; - } - - /** - * The length in characters of the blip name. - * - * @param name the blip name length - */ - public void setName(byte name) { - field_9_name = name; - } - - public byte getUnused2() { - return field_10_unused2; - } - - public void setUnused2(byte unused2) { - field_10_unused2 = unused2; - } - - public byte getUnused3() { - return field_11_unused3; - } - - public void setUnused3(byte unused3) { - field_11_unused3 = unused3; - } - - public EscherBlipRecord getBlipRecord() { - return field_12_blipRecord; - } - - public void setBlipRecord(EscherBlipRecord blipRecord) { - field_12_blipRecord = blipRecord; - } - - /** - * Any remaining data in this record. - * - * @return the remaining bytes - */ - public byte[] getRemainingData() { - return _remainingData; - } - - /** - * Any remaining data in this record. - * - * @param remainingData the remaining bytes - */ - public void setRemainingData(byte[] remainingData) { - if (remainingData == null) { - _remainingData = new byte[0]; - } else { - _remainingData = remainingData.clone(); - } - } - - @Override - public String toString() { - String extraData = _remainingData == null ? null : HexDump.toHex(_remainingData, 32); - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex( RECORD_ID ) + '\n' + - " Version: 0x" + HexDump.toHex( getVersion() ) + '\n' + - " Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' + - " BlipTypeWin32: " + field_1_blipTypeWin32 + '\n' + - " BlipTypeMacOS: " + field_2_blipTypeMacOS + '\n' + - " SUID: " + (field_3_uid == null ? "" : HexDump.toHex(field_3_uid)) + '\n' + - " Tag: " + field_4_tag + '\n' + - " Size: " + field_5_size + '\n' + - " Ref: " + field_6_ref + '\n' + - " Offset: " + field_7_offset + '\n' + - " Usage: " + field_8_usage + '\n' + - " Name: " + field_9_name + '\n' + - " Unused2: " + field_10_unused2 + '\n' + - " Unused3: " + field_11_unused3 + '\n' + - " blipRecord: " + field_12_blipRecord + '\n' + - " Extra Data:" + '\n' + extraData; - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(field_1_blipTypeWin32).append("\n") - .append(tab).append("\t").append("").append(field_2_blipTypeMacOS).append("\n") - .append(tab).append("\t").append("").append(field_3_uid == null ? "" : HexDump.toHex(field_3_uid)).append("\n") - .append(tab).append("\t").append("").append(field_4_tag).append("\n") - .append(tab).append("\t").append("").append(field_5_size).append("\n") - .append(tab).append("\t").append("").append(field_6_ref).append("\n") - .append(tab).append("\t").append("").append(field_7_offset).append("\n") - .append(tab).append("\t").append("").append(field_8_usage).append("\n") - .append(tab).append("\t").append("").append(field_9_name).append("\n") - .append(tab).append("\t").append("").append(field_10_unused2).append("\n") - .append(tab).append("\t").append("").append(field_11_unused3).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Retrieve the string representation given a blip id. - * - * @param b the blip type byte-encoded - * - * @return the blip type as string - */ - public static String getBlipType(byte b) { - switch (b) { - case BT_ERROR: return " ERROR"; - case BT_UNKNOWN: return " UNKNOWN"; - case BT_EMF: return " EMF"; - case BT_WMF: return " WMF"; - case BT_PICT: return " PICT"; - case BT_JPEG: return " JPEG"; - case BT_PNG: return " PNG"; - case BT_DIB: return " DIB"; - } - if ( b < 32 ) { - return " NotKnown"; - } - return " Client"; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java b/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java deleted file mode 100644 index cb2eba8fc..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -public class EscherBitmapBlip extends EscherBlipRecord { - public static final short RECORD_ID_JPEG = (short) 0xF018 + 5; - public static final short RECORD_ID_PNG = (short) 0xF018 + 6; - public static final short RECORD_ID_DIB = (short) 0xF018 + 7; - - private static final int HEADER_SIZE = 8; - - private final byte[] field_1_UID = new byte[16]; - private byte field_2_marker = (byte) 0xFF; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesAfterHeader = readHeader( data, offset ); - int pos = offset + HEADER_SIZE; - - System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16; - field_2_marker = data[pos]; pos++; - - field_pictureData = new byte[bytesAfterHeader - 17]; - System.arraycopy( data, pos, field_pictureData, 0, field_pictureData.length ); - - return bytesAfterHeader + HEADER_SIZE; - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { - listener.beforeRecordSerialize(offset, getRecordId(), this); - - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - LittleEndian.putInt( data, offset + 4, getRecordSize() - HEADER_SIZE ); - int pos = offset + HEADER_SIZE; - - System.arraycopy( field_1_UID, 0, data, pos, 16 ); - data[pos + 16] = field_2_marker; - System.arraycopy( field_pictureData, 0, data, pos + 17, field_pictureData.length ); - - listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this); - return HEADER_SIZE + 16 + 1 + field_pictureData.length; - } - - @Override - public int getRecordSize() { - return 8 + 16 + 1 + field_pictureData.length; - } - - /** - * Gets the first MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @return the first MD4 - */ - public byte[] getUID() { - return field_1_UID; - } - - /** - * Sets the first MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @param field_1_UID the first MD4 - */ - public void setUID( byte[] field_1_UID ) { - if (field_1_UID == null || field_1_UID.length != 16) { - throw new IllegalArgumentException("field_1_UID must be byte[16]"); - } - System.arraycopy(field_1_UID, 0, this.field_1_UID , 0, 16); - } - - /** - * Gets an unsigned integer that specifies an application-defined internal - * resource tag. This value MUST be 0xFF for external files. - * - * @return the marker - */ - public byte getMarker() { - return field_2_marker; - } - - /** - * Sets an unsigned integer that specifies an application-defined internal - * resource tag. This value MUST be 0xFF for external files. - * - * @param field_2_marker the marker - */ - public void setMarker( byte field_2_marker ) { - this.field_2_marker = field_2_marker; - } - - @Override - public String toString() { - String nl = System.getProperty( "line.separator" ); - - String extraData = HexDump.dump(this.field_pictureData, 0, 0); - - return getClass().getName() + ":" + nl + - " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl + - " Version: 0x" + HexDump.toHex( getVersion() ) + nl + - " Instance: 0x" + HexDump.toHex( getInstance() ) + nl + - " UID: 0x" + HexDump.toHex( field_1_UID ) + nl + - " Marker: 0x" + HexDump.toHex( field_2_marker ) + nl + - " Extra Data:" + nl + extraData; - } - - @Override - public String toXml(String tab) { - String extraData = HexDump.dump(this.field_pictureData, 0, 0); - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("0x").append(HexDump.toHex(field_1_UID)).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex(field_2_marker)).append("\n") - .append(tab).append("\t").append("").append(extraData).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java deleted file mode 100644 index 0ea893001..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.HexDump; - -public class EscherBlipRecord extends EscherRecord { - public static final short RECORD_ID_START = (short) 0xF018; - public static final short RECORD_ID_END = (short) 0xF117; - public static final String RECORD_DESCRIPTION = "msofbtBlip"; - - private static final int HEADER_SIZE = 8; - - protected byte[] field_pictureData; - - public EscherBlipRecord() { - } - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesAfterHeader = readHeader( data, offset ); - int pos = offset + HEADER_SIZE; - - field_pictureData = new byte[bytesAfterHeader]; - System.arraycopy(data, pos, field_pictureData, 0, bytesAfterHeader); - - return bytesAfterHeader + 8; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize(offset, getRecordId(), this); - - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - - System.arraycopy( field_pictureData, 0, data, offset + 4, field_pictureData.length ); - - listener.afterRecordSerialize(offset + 4 + field_pictureData.length, getRecordId(), field_pictureData.length + 4, this); - return field_pictureData.length + 4; - } - - @Override - public int getRecordSize() { - return field_pictureData.length + HEADER_SIZE; - } - - @Override - public String getRecordName() { - return "Blip"; - } - - /** - * Gets the picture data bytes - * - * @return the picture data - */ - public byte[] getPicturedata() { - return field_pictureData; - } - - /** - * Sets the picture data bytes - * - * @param pictureData the picture data - */ - public void setPictureData(byte[] pictureData) { - if (pictureData == null) { - throw new IllegalArgumentException("picture data can't be null"); - } - field_pictureData = pictureData.clone(); - } - - @Override - public String toString() { - String extraData = HexDump.toHex(field_pictureData, 32); - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' + - " Version: 0x" + HexDump.toHex( getVersion() ) + '\n' + - " Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' + - " Extra Data:" + '\n' + extraData; - } - - @Override - public String toXml(String tab) { - String extraData = HexDump.toHex(field_pictureData, 32); - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(extraData).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java deleted file mode 100644 index 1f44e2343..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java +++ /dev/null @@ -1,83 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; - -/** - * Represents a boolean property. The actual utility of this property is in doubt because many - * of the properties marked as boolean seem to actually contain special values. In other words - * they're not true booleans. - * - * @see EscherSimpleProperty - * @see EscherProperty - */ -public class EscherBoolProperty - extends EscherSimpleProperty -{ - /** - * Create an instance of an escher boolean property. - * - * @param propertyNumber The property number (or id) - * @param value The 32 bit value of this bool property - */ - public EscherBoolProperty( short propertyNumber, int value ) - { - super(propertyNumber, value); - } - - /** - * Whether this boolean property is true - * - * @return the boolean property value - */ - public boolean isTrue() - { - return propertyValue != 0; - } - - /** - * Whether this boolean property is false - * - * @return true, if this boolean property is false - * - * @deprecated use !isTrue() instead, planed to be removed in POI 3.17 - */ - public boolean isFalse() - { - return propertyValue == 0; - } - -// public String toString() -// { -// return "propNum: " + getPropertyNumber() -// + ", complex: " + isComplex() -// + ", blipId: " + isBlipId() -// + ", value: " + (getValue() != 0); -// } - - @Override - public String toXml(String tab){ - StringBuilder builder = new StringBuilder(); - builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId())) - .append("\" name=\"").append(getName()).append("\" simpleValue=\"").append(getPropertyValue()).append("\" blipId=\"") - .append(isBlipId()).append("\" value=\"").append(isTrue()).append("\"").append("/>\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java deleted file mode 100644 index 1fb16444f..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java +++ /dev/null @@ -1,210 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * The escher child achor record is used to specify the position of a shape under an - * existing group. The first level of shape records use a EscherClientAnchor record instead. - * - * @see EscherChildAnchorRecord - */ -public class EscherChildAnchorRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF00F; - public static final String RECORD_DESCRIPTION = "MsofbtChildAnchor"; - - private int field_1_dx1; - private int field_2_dy1; - private int field_3_dx2; - private int field_4_dy2; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - switch (bytesRemaining) { - case 16: // RectStruct - field_1_dx1 = LittleEndian.getInt( data, pos + size );size+=4; - field_2_dy1 = LittleEndian.getInt( data, pos + size );size+=4; - field_3_dx2 = LittleEndian.getInt( data, pos + size );size+=4; - field_4_dy2 = LittleEndian.getInt( data, pos + size );size+=4; - break; - case 8: // SmallRectStruct - field_1_dx1 = LittleEndian.getShort( data, pos + size );size+=2; - field_2_dy1 = LittleEndian.getShort( data, pos + size );size+=2; - field_3_dx2 = LittleEndian.getShort( data, pos + size );size+=2; - field_4_dy2 = LittleEndian.getShort( data, pos + size );size+=2; - break; - default: - throw new RuntimeException("Invalid EscherChildAnchorRecord - neither 8 nor 16 bytes."); - } - - return 8 + size; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - int pos = offset; - LittleEndian.putShort( data, pos, getOptions() ); pos += 2; - LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; - LittleEndian.putInt( data, pos, getRecordSize()-8 ); pos += 4; - LittleEndian.putInt( data, pos, field_1_dx1 ); pos += 4; - LittleEndian.putInt( data, pos, field_2_dy1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_dx2 ); pos += 4; - LittleEndian.putInt( data, pos, field_4_dy2 ); pos += 4; - - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return pos - offset; - } - - @Override - public int getRecordSize() - { - return 8 + 4 * 4; - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "ChildAnchor"; - } - - - /** - * The string representation of this record - */ - @Override - public String toString() - { - String nl = System.getProperty("line.separator"); - - return getClass().getName() + ":" + nl + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl + - " Version: 0x" + HexDump.toHex(getVersion()) + nl + - " Instance: 0x" + HexDump.toHex(getInstance()) + nl + - " X1: " + field_1_dx1 + nl + - " Y1: " + field_2_dy1 + nl + - " X2: " + field_3_dx2 + nl + - " Y2: " + field_4_dy2 + nl ; - - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(field_1_dx1).append("\n") - .append(tab).append("\t").append("").append(field_2_dy1).append("\n") - .append(tab).append("\t").append("").append(field_3_dx2).append("\n") - .append(tab).append("\t").append("").append(field_4_dy2).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Retrieves offset within the parent coordinate space for the top left point. - * - * @return the x offset of the top left point - */ - public int getDx1() - { - return field_1_dx1; - } - - /** - * Sets offset within the parent coordinate space for the top left point. - * - * @param field_1_dx1 the x offset of the top left point - */ - public void setDx1( int field_1_dx1 ) - { - this.field_1_dx1 = field_1_dx1; - } - - /** - * Gets offset within the parent coordinate space for the top left point. - * - * @return the y offset of the top left point - */ - public int getDy1() - { - return field_2_dy1; - } - - /** - * Sets offset within the parent coordinate space for the top left point. - * - * @param field_2_dy1 the y offset of the top left point - */ - public void setDy1( int field_2_dy1 ) - { - this.field_2_dy1 = field_2_dy1; - } - - /** - * Retrieves offset within the parent coordinate space for the bottom right point. - * - * @return the x offset of the bottom right point - */ - public int getDx2() - { - return field_3_dx2; - } - - /** - * Sets offset within the parent coordinate space for the bottom right point. - * - * @param field_3_dx2 the x offset of the bottom right point - */ - public void setDx2( int field_3_dx2 ) - { - this.field_3_dx2 = field_3_dx2; - } - - /** - * Gets the offset within the parent coordinate space for the bottom right point. - * - * @return the y offset of the bottom right point - */ - public int getDy2() - { - return field_4_dy2; - } - - /** - * Sets the offset within the parent coordinate space for the bottom right point. - * - * @param field_4_dy2 the y offset of the bottom right point - */ - public void setDy2( int field_4_dy2 ) - { - this.field_4_dy2 = field_4_dy2; - } - -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java deleted file mode 100644 index bb1cf66ee..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java +++ /dev/null @@ -1,387 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * The escher client anchor specifies which rows and cells the shape is bound to as well as - * the offsets within those cells. Each cell is 1024 units wide by 256 units long regardless - * of the actual size of the cell. The EscherClientAnchorRecord only applies to the top-most - * shapes. Shapes contained in groups are bound using the EscherChildAnchorRecords. - * - * @see EscherChildAnchorRecord - */ -public class EscherClientAnchorRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF010; - public static final String RECORD_DESCRIPTION = "MsofbtClientAnchor"; - - /** - * bit[0] - fMove (1 bit): A bit that specifies whether the shape will be kept intact when the cells are moved. - * bit[1] - fSize (1 bit): A bit that specifies whether the shape will be kept intact when the cells are resized. If fMove is 1, the value MUST be 1. - * bit[2-4] - reserved, MUST be 0 and MUST be ignored - * bit[5-15]- Undefined and MUST be ignored. - * - * it can take values: 0, 2, 3 - */ - private short field_1_flag; - private short field_2_col1; - private short field_3_dx1; - private short field_4_row1; - private short field_5_dy1; - private short field_6_col2; - private short field_7_dx2; - private short field_8_row2; - private short field_9_dy2; - private byte[] remainingData = new byte[0]; - private boolean shortRecord = false; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - - // Always find 4 two byte entries. Sometimes find 9 - /*if (bytesRemaining == 4) // Word format only 4 bytes - { - // Not sure exactly what the format is quite yet, likely a reference to a PLC - } - else */ - if (bytesRemaining != 4) // Word format only 4 bytes - { - field_1_flag = LittleEndian.getShort( data, pos + size ); size += 2; - field_2_col1 = LittleEndian.getShort( data, pos + size ); size += 2; - field_3_dx1 = LittleEndian.getShort( data, pos + size ); size += 2; - field_4_row1 = LittleEndian.getShort( data, pos + size ); size += 2; - if(bytesRemaining >= 18) { - field_5_dy1 = LittleEndian.getShort( data, pos + size ); size += 2; - field_6_col2 = LittleEndian.getShort( data, pos + size ); size += 2; - field_7_dx2 = LittleEndian.getShort( data, pos + size ); size += 2; - field_8_row2 = LittleEndian.getShort( data, pos + size ); size += 2; - field_9_dy2 = LittleEndian.getShort( data, pos + size ); size += 2; - shortRecord = false; - } else { - shortRecord = true; - } - } - bytesRemaining -= size; - remainingData = new byte[bytesRemaining]; - System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining ); - return 8 + size + bytesRemaining; - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - if (remainingData == null) remainingData = new byte[0]; - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - int remainingBytes = remainingData.length + (shortRecord ? 8 : 18); - LittleEndian.putInt( data, offset + 4, remainingBytes ); - LittleEndian.putShort( data, offset + 8, field_1_flag ); - LittleEndian.putShort( data, offset + 10, field_2_col1 ); - LittleEndian.putShort( data, offset + 12, field_3_dx1 ); - LittleEndian.putShort( data, offset + 14, field_4_row1 ); - if(!shortRecord) { - LittleEndian.putShort( data, offset + 16, field_5_dy1 ); - LittleEndian.putShort( data, offset + 18, field_6_col2 ); - LittleEndian.putShort( data, offset + 20, field_7_dx2 ); - LittleEndian.putShort( data, offset + 22, field_8_row2 ); - LittleEndian.putShort( data, offset + 24, field_9_dy2 ); - } - System.arraycopy( remainingData, 0, data, offset + (shortRecord ? 16 : 26), remainingData.length ); - int pos = offset + 8 + (shortRecord ? 8 : 18) + remainingData.length; - - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return pos - offset; - } - - @Override - public int getRecordSize() - { - return 8 + (shortRecord ? 8 : 18) + (remainingData == null ? 0 : remainingData.length); - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "ClientAnchor"; - } - - /** - * Returns the string representation for this record. - * - * @return A string - */ - @Override - public String toString() - { - String nl = System.getProperty("line.separator"); - String extraData = HexDump.dump(this.remainingData, 0, 0); - return getClass().getName() + ":" + nl + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl + - " Version: 0x" + HexDump.toHex(getVersion()) + nl + - " Instance: 0x" + HexDump.toHex(getInstance()) + nl + - " Flag: " + field_1_flag + nl + - " Col1: " + field_2_col1 + nl + - " DX1: " + field_3_dx1 + nl + - " Row1: " + field_4_row1 + nl + - " DY1: " + field_5_dy1 + nl + - " Col2: " + field_6_col2 + nl + - " DX2: " + field_7_dx2 + nl + - " Row2: " + field_8_row2 + nl + - " DY2: " + field_9_dy2 + nl + - " Extra Data:" + nl + extraData; - - } - - @Override - public String toXml(String tab) { - String extraData = HexDump.dump(this.remainingData, 0, 0).trim(); - return tab + formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance())) + - tab + "\t" + "" + field_1_flag + "\n" + - tab + "\t" + "" + field_2_col1 + "\n" + - tab + "\t" + "" + field_3_dx1 + "\n" + - tab + "\t" + "" + field_4_row1 + "\n" + - tab + "\t" + "" + field_5_dy1 + "\n" + - tab + "\t" + "" + field_6_col2 + "\n" + - tab + "\t" + "" + field_7_dx2 + "\n" + - tab + "\t" + "" + field_8_row2 + "\n" + - tab + "\t" + "" + field_9_dy2 + "\n" + - tab + "\t" + "" + extraData + "\n" + - tab + "\n"; - } - - /** - * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. - * - * @return the move/size flag - */ - public short getFlag() - { - return field_1_flag; - } - - /** - * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. - * - * @param field_1_flag the move/size flag - */ - public void setFlag( short field_1_flag ) - { - this.field_1_flag = field_1_flag; - } - - /** - * The column number for the top-left position. 0 based. - * - * @return the column number of the top-left corner - */ - public short getCol1() - { - return field_2_col1; - } - - /** - * The column number for the top-left position. 0 based. - * - * @param field_2_col1 the column number of the top-left corner - */ - public void setCol1( short field_2_col1 ) - { - this.field_2_col1 = field_2_col1; - } - - /** - * The x offset within the top-left cell. Range is from 0 to 1023. - * - * @return the x offset of the top-left corner - */ - public short getDx1() - { - return field_3_dx1; - } - - /** - * The x offset within the top-left cell. Range is from 0 to 1023. - * - * @param field_3_dx1 the x offset of the top-left corner - */ - public void setDx1( short field_3_dx1 ) - { - this.field_3_dx1 = field_3_dx1; - } - - /** - * The row number for the top-left corner of the shape. - * - * @return the row number of the top-left corner - */ - public short getRow1() - { - return field_4_row1; - } - - /** - * The row number of the top-left corner of the shape. - * - * @param field_4_row1 the row number of the top-left corner - */ - public void setRow1( short field_4_row1 ) - { - this.field_4_row1 = field_4_row1; - } - - /** - * The y offset within the top-left corner of the current shape. - * - * @return the y offset of the top-left corner - */ - public short getDy1() - { - return field_5_dy1; - } - - /** - * The y offset within the top-left corner of the current shape. - * - * @param field_5_dy1 the y offset of the top-left corner - */ - public void setDy1( short field_5_dy1 ) - { - shortRecord = false; - this.field_5_dy1 = field_5_dy1; - } - - /** - * The column of the bottom right corner of this shape. - * - * @return the column of the bottom right corner - */ - public short getCol2() - { - return field_6_col2; - } - - /** - * The column of the bottom right corner of this shape. - * - * @param field_6_col2 the column of the bottom right corner - */ - public void setCol2( short field_6_col2 ) - { - shortRecord = false; - this.field_6_col2 = field_6_col2; - } - - /** - * The x offset withing the cell for the bottom-right corner of this shape. - * - * @return the x offset of the bottom-right corner - */ - public short getDx2() - { - return field_7_dx2; - } - - /** - * The x offset withing the cell for the bottom-right corner of this shape. - * - * @param field_7_dx2 the x offset of the bottom-right corner - */ - public void setDx2( short field_7_dx2 ) - { - shortRecord = false; - this.field_7_dx2 = field_7_dx2; - } - - /** - * The row number for the bottom-right corner of the current shape. - * - * @return the row number for the bottom-right corner - */ - public short getRow2() - { - return field_8_row2; - } - - /** - * The row number for the bottom-right corner of the current shape. - * - * @param field_8_row2 the row number for the bottom-right corner - */ - public void setRow2( short field_8_row2 ) - { - shortRecord = false; - this.field_8_row2 = field_8_row2; - } - - /** - * The y offset withing the cell for the bottom-right corner of this shape. - * - * @return the y offset of the bottom-right corner - */ - public short getDy2() - { - return field_9_dy2; - } - - /** - * The y offset withing the cell for the bottom-right corner of this shape. - * - * @param field_9_dy2 the y offset of the bottom-right corner - */ - public void setDy2( short field_9_dy2 ) - { - shortRecord = false; - this.field_9_dy2 = field_9_dy2; - } - - /** - * Any remaining data in the record - * - * @return the remaining bytes - */ - public byte[] getRemainingData() - { - return remainingData; - } - - /** - * Any remaining data in the record - * - * @param remainingData the remaining bytes - */ - public void setRemainingData( byte[] remainingData ) { - if (remainingData == null) { - this.remainingData = new byte[0]; - } else { - this.remainingData = remainingData.clone(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java deleted file mode 100644 index 749007cfe..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java +++ /dev/null @@ -1,124 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * The EscherClientDataRecord is used to store client specific data about the position of a - * shape within a container. - */ -public class EscherClientDataRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF011; - public static final String RECORD_DESCRIPTION = "MsofbtClientData"; - - private byte[] remainingData; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - remainingData = new byte[bytesRemaining]; - System.arraycopy( data, pos, remainingData, 0, bytesRemaining ); - return 8 + bytesRemaining; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - if (remainingData == null) remainingData = new byte[0]; - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - LittleEndian.putInt( data, offset + 4, remainingData.length ); - System.arraycopy( remainingData, 0, data, offset + 8, remainingData.length ); - int pos = offset + 8 + remainingData.length; - - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return pos - offset; - } - - @Override - public int getRecordSize() - { - return 8 + (remainingData == null ? 0 : remainingData.length); - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "ClientData"; - } - - /** - * Returns the string representation of this record. - */ - @Override - public String toString() - { - String nl = System.getProperty("line.separator"); - String extraData = HexDump.dump(getRemainingData(), 0, 0); - return getClass().getName() + ":" + nl + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl + - " Version: 0x" + HexDump.toHex(getVersion()) + nl + - " Instance: 0x" + HexDump.toHex(getInstance()) + nl + - " Extra Data:" + nl + - extraData; - - } - - @Override - public String toXml(String tab) { - String extraData = HexDump.dump(getRemainingData(), 0, 0).trim(); - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), - HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(extraData).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Any data recording this record. - * - * @return the remaining bytes - */ - public byte[] getRemainingData() - { - return remainingData; - } - - /** - * Any data recording this record. - * - * @param remainingData the remaining bytes - */ - public void setRemainingData( byte[] remainingData ) { - this.remainingData = (remainingData == null) - ? new byte[0] - : remainingData.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java b/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java deleted file mode 100644 index 84f94301d..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java +++ /dev/null @@ -1,295 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.LittleEndian; - -/** - * An OfficeArtCOLORREF structure entry which also handles color extension opid data - */ -public class EscherColorRef { - int opid = -1; - int colorRef = 0; - - public enum SysIndexSource { - /** Use the fill color of the shape. */ - FILL_COLOR(0xF0), - /** If the shape contains a line, use the line color of the shape. Otherwise, use the fill color. */ - LINE_OR_FILL_COLOR(0xF1), - /** Use the line color of the shape. */ - LINE_COLOR(0xF2), - /** Use the shadow color of the shape. */ - SHADOW_COLOR(0xF3), - /** Use the current, or last-used, color. */ - CURRENT_OR_LAST_COLOR(0xF4), - /** Use the fill background color of the shape. */ - FILL_BACKGROUND_COLOR(0xF5), - /** Use the line background color of the shape. */ - LINE_BACKGROUND_COLOR(0xF6), - /** If the shape contains a fill, use the fill color of the shape. Otherwise, use the line color. */ - FILL_OR_LINE_COLOR(0xF7) - ; - int value; - SysIndexSource(int value) { this.value = value; } - } - - /** - * The following enum specifies values that indicate special procedural properties that - * are used to modify the color components of another color. These values are combined with - * those of the {@link SysIndexSource} enum or with a user-specified color. - * The first six values are mutually exclusive. - */ - public enum SysIndexProcedure { - /** - * Darken the color by the value that is specified in the blue field. - * A blue value of 0xFF specifies that the color is to be left unchanged, - * whereas a blue value of 0x00 specifies that the color is to be completely darkened. - */ - DARKEN_COLOR(0x01), - /** - * Lighten the color by the value that is specified in the blue field. - * A blue value of 0xFF specifies that the color is to be left unchanged, - * whereas a blue value of 0x00 specifies that the color is to be completely lightened. - */ - LIGHTEN_COLOR(0x02), - /** - * Add a gray level RGB value. The blue field contains the gray level to add: - * NewColor = SourceColor + gray - */ - ADD_GRAY_LEVEL(0x03), - /** - * Subtract a gray level RGB value. The blue field contains the gray level to subtract: - * NewColor = SourceColor - gray - */ - SUB_GRAY_LEVEL(0x04), - /** - * Reverse-subtract a gray level RGB value. The blue field contains the gray level from - * which to subtract: - * NewColor = gray - SourceColor - */ - REVERSE_GRAY_LEVEL(0x05), - /** - * If the color component being modified is less than the parameter contained in the blue - * field, set it to the minimum intensity. If the color component being modified is greater - * than or equal to the parameter, set it to the maximum intensity. - */ - THRESHOLD(0x06), - /** - * After making other modifications, invert the color. - * This enum value is only for documentation and won't be directly returned. - */ - INVERT_AFTER(0x20), - /** - * After making other modifications, invert the color by toggling just the high bit of each - * color channel. - * This enum value is only for documentation and won't be directly returned. - */ - INVERT_HIGHBIT_AFTER(0x40) - ; - BitField mask; - SysIndexProcedure(int mask) { - this.mask = new BitField(mask); - } - } - - /** - * A bit that specifies whether the system color scheme will be used to determine the color. - * A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index - * into the system color table. Values less than 0x00F0 map directly to system colors. - */ - private static final BitField FLAG_SYS_INDEX = new BitField(0x10000000); - - /** - * A bit that specifies whether the current application-defined color scheme will be used - * to determine the color. A value of 0x1 specifies that red will be treated as an index - * into the current color scheme table. If this value is 0x1, green and blue MUST be 0x00. - */ - private static final BitField FLAG_SCHEME_INDEX = new BitField(0x08000000); - - /** - * A bit that specifies whether the color is a standard RGB color. - * 0x0 : The RGB color MAY use halftone dithering to display. - * 0x1 : The color MUST be a solid color. - */ - private static final BitField FLAG_SYSTEM_RGB = new BitField(0x04000000); - - /** - * A bit that specifies whether the current palette will be used to determine the color. - * A value of 0x1 specifies that red, green, and blue contain an RGB value that will be - * matched in the current color palette. This color MUST be solid. - */ - private static final BitField FLAG_PALETTE_RGB = new BitField(0x02000000); - - /** - * A bit that specifies whether the current palette will be used to determine the color. - * A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index into - * the current color palette. This color MAY be dithered. If this value is 0x1, blue MUST be 0x00. - */ - private static final BitField FLAG_PALETTE_INDEX = new BitField(0x01000000); - - /** - * An unsigned integer that specifies the intensity of the blue color channel. A value - * of 0x00 has the minimum blue intensity. A value of 0xFF has the maximum blue intensity. - */ - private static final BitField FLAG_BLUE = new BitField(0x00FF0000); - - /** - * An unsigned integer that specifies the intensity of the green color channel. A value - * of 0x00 has the minimum green intensity. A value of 0xFF has the maximum green intensity. - */ - private static final BitField FLAG_GREEN = new BitField(0x0000FF00); - - /** - * An unsigned integer that specifies the intensity of the red color channel. A value - * of 0x00 has the minimum red intensity. A value of 0xFF has the maximum red intensity. - */ - private static final BitField FLAG_RED = new BitField(0x000000FF); - - public EscherColorRef(int colorRef) { - this.colorRef = colorRef; - } - - public EscherColorRef(byte[] source, int start, int len) { - assert(len == 4 || len == 6); - - int offset = start; - if (len == 6) { - opid = LittleEndian.getUShort(source, offset); - offset += 2; - } - colorRef = LittleEndian.getInt(source, offset); - } - - public boolean hasSysIndexFlag() { - return FLAG_SYS_INDEX.isSet(colorRef); - } - - public void setSysIndexFlag(boolean flag) { - colorRef = FLAG_SYS_INDEX.setBoolean(colorRef, flag); - } - - public boolean hasSchemeIndexFlag() { - return FLAG_SCHEME_INDEX.isSet(colorRef); - } - - public void setSchemeIndexFlag(boolean flag) { - colorRef = FLAG_SCHEME_INDEX.setBoolean(colorRef, flag); - } - - public boolean hasSystemRGBFlag() { - return FLAG_SYSTEM_RGB.isSet(colorRef); - } - - public void setSystemRGBFlag(boolean flag) { - colorRef = FLAG_SYSTEM_RGB.setBoolean(colorRef, flag); - } - - public boolean hasPaletteRGBFlag() { - return FLAG_PALETTE_RGB.isSet(colorRef); - } - - public void setPaletteRGBFlag(boolean flag) { - colorRef = FLAG_PALETTE_RGB.setBoolean(colorRef, flag); - } - - public boolean hasPaletteIndexFlag() { - return FLAG_PALETTE_INDEX.isSet(colorRef); - } - - public void setPaletteIndexFlag(boolean flag) { - colorRef = FLAG_PALETTE_INDEX.setBoolean(colorRef, flag); - } - - public int[] getRGB() { - int rgb[] = { - FLAG_RED.getValue(colorRef), - FLAG_GREEN.getValue(colorRef), - FLAG_BLUE.getValue(colorRef) - }; - return rgb; - } - - /** - * @return {@link SysIndexSource} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null - */ - public SysIndexSource getSysIndexSource() { - if (!hasSysIndexFlag()) return null; - int val = FLAG_RED.getValue(colorRef); - for (SysIndexSource sis : SysIndexSource.values()) { - if (sis.value == val) return sis; - } - return null; - } - - /** - * Return the {@link SysIndexProcedure} - for invert flag use {@link #getSysIndexInvert()} - * @return {@link SysIndexProcedure} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null - */ - public SysIndexProcedure getSysIndexProcedure() { - if (!hasSysIndexFlag()) return null; - int val = FLAG_GREEN.getValue(colorRef); - for (SysIndexProcedure sip : SysIndexProcedure.values()) { - if (sip == SysIndexProcedure.INVERT_AFTER || sip == SysIndexProcedure.INVERT_HIGHBIT_AFTER) continue; - if (sip.mask.isSet(val)) return sip; - } - return null; - } - - /** - * @return 0 for no invert flag, 1 for {@link SysIndexProcedure#INVERT_AFTER} and - * 2 for {@link SysIndexProcedure#INVERT_HIGHBIT_AFTER} - */ - public int getSysIndexInvert() { - if (!hasSysIndexFlag()) return 0; - int val = FLAG_GREEN.getValue(colorRef); - if ((SysIndexProcedure.INVERT_AFTER.mask.isSet(val))) return 1; - if ((SysIndexProcedure.INVERT_HIGHBIT_AFTER.mask.isSet(val))) return 2; - return 0; - } - - /** - * @return index of the scheme color or -1 if {@link #hasSchemeIndexFlag()} is {@code false} - * - * @see org.apache.poi.hslf.record.ColorSchemeAtom#getColor(int) - */ - public int getSchemeIndex() { - if (!hasSchemeIndexFlag()) return -1; - return FLAG_RED.getValue(colorRef); - } - - /** - * @return index of current palette (color) or -1 if {@link #hasPaletteIndexFlag()} is {@code false} - */ - public int getPaletteIndex() { - return (hasPaletteIndexFlag()) ? getIndex() : -1; - } - - /** - * @return index of system color table or -1 if {@link #hasSysIndexFlag()} is {@code false} - * - * @see org.apache.poi.sl.usermodel.PresetColor - */ - public int getSysIndex() { - return (hasSysIndexFlag()) ? getIndex() : -1; - } - - private int getIndex() { - return (FLAG_GREEN.getValue(colorRef) << 8) | FLAG_RED.getValue(colorRef); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java deleted file mode 100644 index 9a84e10c1..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.util.Arrays; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * A complex property differs from a simple property in that the data can not fit inside a 32 bit - * integer. See the specification for more detailed information regarding exactly what is - * stored here. - */ -public class EscherComplexProperty extends EscherProperty { - // TODO - make private and final - protected byte[] _complexData; - - /** - * Create a complex property using the property id and a byte array containing the complex - * data value. - * - * @param id The id consists of the property number, a flag indicating whether this is a blip id and a flag - * indicating that this is a complex property. - * @param complexData The value of this property. - */ - public EscherComplexProperty(short id, byte[] complexData) { - super(id); - if (complexData == null) { - throw new IllegalArgumentException("complexData can't be null"); - } - _complexData = complexData.clone(); - } - - /** - * Create a complex property using the property number, a flag to indicate whether this is a - * blip reference and the complex property data. - * - * @param propertyNumber The property number - * @param isBlipId Whether this is a blip id. Should be false. - * @param complexData The value of this complex property. - */ - public EscherComplexProperty(short propertyNumber, boolean isBlipId, byte[] complexData) { - super(propertyNumber, true, isBlipId); - if (complexData == null) { - throw new IllegalArgumentException("complexData can't be null"); - } - _complexData = complexData.clone(); - } - - /** - * Serializes the simple part of this property. i.e. the first 6 bytes. - */ - @Override - public int serializeSimplePart(byte[] data, int pos) { - LittleEndian.putShort(data, pos, getId()); - LittleEndian.putInt(data, pos + 2, _complexData.length); - return 6; - } - - /** - * Serializes the complex part of this property - * - * @param data The data array to serialize to - * @param pos The offset within data to start serializing to. - * @return The number of bytes serialized. - */ - @Override - public int serializeComplexPart(byte[] data, int pos) { - System.arraycopy(_complexData, 0, data, pos, _complexData.length); - return _complexData.length; - } - - /** - * Get the complex data value. - * - * @return the complex bytes - */ - public byte[] getComplexData() { - return _complexData; - } - - /** - * Determine whether this property is equal to another property. - * - * @param o The object to compare to. - * @return True if the objects are equal. - */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || !(o instanceof EscherComplexProperty)) { - return false; - } - - EscherComplexProperty escherComplexProperty = (EscherComplexProperty) o; - - return Arrays.equals(_complexData, escherComplexProperty._complexData); - - } - - /** - * Calculates the number of bytes required to serialize this property. - * - * @return Number of bytes - */ - @Override - public int getPropertySize() { - return 6 + _complexData.length; - } - - @Override - public int hashCode() { - return getId() * 11; - } - - /** - * Retrieves the string representation for this property. - */ - @Override - public String toString() { - String dataStr = HexDump.toHex( _complexData, 32); - - return "propNum: " + getPropertyNumber() - + ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() ) - + ", complex: " + isComplex() - + ", blipId: " + isBlipId() - + ", data: " + System.getProperty("line.separator") + dataStr; - } - - @Override - public String toXml(String tab){ - return tab + "<" + getClass().getSimpleName() + " id=\"0x" + HexDump.toHex(getId()) + - "\" name=\"" + getName() + "\" blipId=\"" + - isBlipId() + "\">\n" + - tab + "\n"; - //builder.append("\t").append(tab).append(dataStr); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java deleted file mode 100644 index 3b26d4211..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java +++ /dev/null @@ -1,343 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.io.PrintWriter; -import java.util.*; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Escher container records store other escher records as children. - * The container records themselves never store any information beyond - * the standard header used by all escher records. This one record is - * used to represent many different types of records. - */ -public final class EscherContainerRecord extends EscherRecord { - public static final short DGG_CONTAINER = (short)0xF000; - public static final short BSTORE_CONTAINER = (short)0xF001; - public static final short DG_CONTAINER = (short)0xF002; - public static final short SPGR_CONTAINER = (short)0xF003; - public static final short SP_CONTAINER = (short)0xF004; - public static final short SOLVER_CONTAINER = (short)0xF005; - - private static final POILogger log = POILogFactory.getLogger(EscherContainerRecord.class); - - /** - * in case if document contains any charts we have such document structure: - * BOF - * ... - * DrawingRecord - * ... - * ObjRecord|TxtObjRecord - * ... - * EOF - * ... - * BOF(Chart begin) - * ... - * DrawingRecord - * ... - * ObjRecord|TxtObjRecord - * ... - * EOF - * So, when we call EscherAggregate.createAggregate() we have not all needed data. - * When we got warning "WARNING: " + bytesRemaining + " bytes remaining but no space left" - * we should save value of bytesRemaining - * and add it to container size when we serialize it - */ - private int _remainingLength; - - private final List _childRecords = new ArrayList(); - - @Override - public int fillFields(byte[] data, int pOffset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader(data, pOffset); - int bytesWritten = 8; - int offset = pOffset + 8; - while (bytesRemaining > 0 && offset < data.length) { - EscherRecord child = recordFactory.createRecord(data, offset); - int childBytesWritten = child.fillFields(data, offset, recordFactory); - bytesWritten += childBytesWritten; - offset += childBytesWritten; - bytesRemaining -= childBytesWritten; - addChildRecord(child); - if (offset >= data.length && bytesRemaining > 0) { - _remainingLength = bytesRemaining; - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not enough Escher data: " + bytesRemaining + " bytes remaining but no space left"); - } - } - } - return bytesWritten; - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort(data, offset, getOptions()); - LittleEndian.putShort(data, offset+2, getRecordId()); - int remainingBytes = 0; - Iterator iterator = _childRecords.iterator(); - while (iterator.hasNext()) { - EscherRecord r = iterator.next(); - remainingBytes += r.getRecordSize(); - } - remainingBytes += _remainingLength; - LittleEndian.putInt(data, offset+4, remainingBytes); - int pos = offset+8; - iterator = _childRecords.iterator(); - while (iterator.hasNext()) { - EscherRecord r = iterator.next(); - pos += r.serialize(pos, data, listener ); - } - - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return pos - offset; - } - - @Override - public int getRecordSize() { - int childRecordsSize = 0; - Iterator iterator = _childRecords.iterator(); - while (iterator.hasNext()) { - EscherRecord r = iterator.next(); - childRecordsSize += r.getRecordSize(); - } - return 8 + childRecordsSize; - } - - /** - * Do any of our (top level) children have the given recordId? - * - * @param recordId the recordId of the child - * - * @return true, if any child has the given recordId - */ - public boolean hasChildOfType(short recordId) { - Iterator iterator = _childRecords.iterator(); - while (iterator.hasNext()) { - EscherRecord r = iterator.next(); - if(r.getRecordId() == recordId) { - return true; - } - } - return false; - } - @Override - public EscherRecord getChild( int index ) { - return _childRecords.get(index); - } - - /** - * @return a copy of the list of all the child records of the container. - */ - @Override - public List getChildRecords() { - return new ArrayList(_childRecords); - } - - /** - * @return an iterator over the child records - */ - public Iterator getChildIterator() { - return Collections.unmodifiableList(_childRecords).iterator(); - } - - /** - * replaces the internal child list with the contents of the supplied childRecords - */ - @Override - public void setChildRecords(List childRecords) { - if (childRecords == _childRecords) { - throw new IllegalStateException("Child records private data member has escaped"); - } - _childRecords.clear(); - _childRecords.addAll(childRecords); - } - - /** - * Removes the given escher record from the child list - * - * @param toBeRemoved the escher record to be removed - * @return true, if the record was found and removed - */ - public boolean removeChildRecord(EscherRecord toBeRemoved) { - return _childRecords.remove(toBeRemoved); - } - - - - /** - * Returns all of our children which are also - * EscherContainers (may be 0, 1, or vary rarely 2 or 3) - * - * @return EscherContainer children - */ - public List getChildContainers() { - List containers = new ArrayList(); - Iterator iterator = _childRecords.iterator(); - while (iterator.hasNext()) { - EscherRecord r = iterator.next(); - if(r instanceof EscherContainerRecord) { - containers.add((EscherContainerRecord) r); - } - } - return containers; - } - - @Override - public String getRecordName() { - switch (getRecordId()) { - case DGG_CONTAINER: - return "DggContainer"; - case BSTORE_CONTAINER: - return "BStoreContainer"; - case DG_CONTAINER: - return "DgContainer"; - case SPGR_CONTAINER: - return "SpgrContainer"; - case SP_CONTAINER: - return "SpContainer"; - case SOLVER_CONTAINER: - return "SolverContainer"; - default: - return "Container 0x" + HexDump.toHex(getRecordId()); - } - } - - @Override - public void display(PrintWriter w, int indent) { - super.display(w, indent); - for (Iterator iterator = _childRecords.iterator(); iterator.hasNext();) - { - EscherRecord escherRecord = iterator.next(); - escherRecord.display(w, indent + 1); - } - } - - /** - * Append a child record - * - * @param record the record to be added - */ - public void addChildRecord(EscherRecord record) { - _childRecords.add(record); - } - - /** - * Add a child record before the record with given recordId - * - * @param record the record to be added - * @param insertBeforeRecordId the recordId of the next sibling - */ - public void addChildBefore(EscherRecord record, int insertBeforeRecordId) { - int idx = 0; - for (EscherRecord rec : _childRecords) { - if(rec.getRecordId() == (short)insertBeforeRecordId) break; - // TODO - keep looping? Do we expect multiple matches? - idx++; - } - _childRecords.add(idx, record); - } - - @Override - public String toString() - { - String nl = System.getProperty( "line.separator" ); - - StringBuffer children = new StringBuffer(); - if ( _childRecords.size() > 0 ) - { - children.append( " children: " + nl ); - - int count = 0; - for ( Iterator iterator = _childRecords.iterator(); iterator - .hasNext(); ) - { - EscherRecord record = iterator.next(); - children.append( " Child " + count + ":" + nl ); - String childResult = String.valueOf( record ); - childResult = childResult.replaceAll( "\n", "\n " ); - children.append( " " ); - children.append( childResult ); - children.append( nl ); - count++; - } - } - - return getClass().getName() + " (" + getRecordName() + "):" + nl - + " isContainer: " + isContainerRecord() + nl - + " version: 0x" + HexDump.toHex( getVersion() ) + nl - + " instance: 0x" + HexDump.toHex( getInstance() ) + nl - + " recordId: 0x" + HexDump.toHex( getRecordId() ) + nl - + " numchildren: " + _childRecords.size() + nl - + children.toString(); - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getRecordName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))); - for ( Iterator iterator = _childRecords.iterator(); iterator - .hasNext(); ) - { - EscherRecord record = iterator.next(); - builder.append(record.toXml(tab+"\t")); - } - builder.append(tab).append("\n"); - return builder.toString(); - } - - public T getChildById( short recordId ) - { - for ( EscherRecord childRecord : _childRecords ) - { - if ( childRecord.getRecordId() == recordId ) - { - @SuppressWarnings( "unchecked" ) - final T result = (T) childRecord; - return result; - } - } - return null; - } - - /** - * Recursively find records with the specified record ID - * - * @param recordId the recordId to be searched for - * @param out - list to store found records - */ - public void getRecordsById(short recordId, List out){ - Iterator iterator = _childRecords.iterator(); - while (iterator.hasNext()) { - EscherRecord r = iterator.next(); - if(r instanceof EscherContainerRecord) { - EscherContainerRecord c = (EscherContainerRecord)r; - c.getRecordsById(recordId, out ); - } else if (r.getRecordId() == recordId){ - out.add(r); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java deleted file mode 100644 index 7de76e241..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java +++ /dev/null @@ -1,169 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * This record simply holds the number of shapes in the drawing group and the - * last shape id used for this drawing group. - */ -public class EscherDgRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF008; - public static final String RECORD_DESCRIPTION = "MsofbtDg"; - - private int field_1_numShapes; - private int field_2_lastMSOSPID; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - /*int bytesRemaining =*/ readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - field_1_numShapes = LittleEndian.getInt( data, pos + size ); size += 4; - field_2_lastMSOSPID = LittleEndian.getInt( data, pos + size ); size += 4; -// bytesRemaining -= size; -// remainingData = new byte[bytesRemaining]; -// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining ); - return getRecordSize(); - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - LittleEndian.putInt( data, offset + 4, 8 ); - LittleEndian.putInt( data, offset + 8, field_1_numShapes ); - LittleEndian.putInt( data, offset + 12, field_2_lastMSOSPID ); -// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length ); -// int pos = offset + 8 + 18 + remainingData.length; - - listener.afterRecordSerialize( offset + 16, getRecordId(), getRecordSize(), this ); - return getRecordSize(); - } - - /** - * Returns the number of bytes that are required to serialize this record. - * - * @return Number of bytes - */ - @Override - public int getRecordSize() - { - return 8 + 8; - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "Dg"; - } - - /** - * Returns the string representation of this record. - */ - @Override - public String toString() { - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + '\n' + - " Version: 0x" + HexDump.toHex(getVersion()) + '\n' + - " Instance: 0x" + HexDump.toHex(getInstance()) + '\n' + - " NumShapes: " + field_1_numShapes + '\n' + - " LastMSOSPID: " + field_2_lastMSOSPID + '\n'; - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(field_1_numShapes).append("\n") - .append(tab).append("\t").append("").append(field_2_lastMSOSPID).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * The number of shapes in this drawing group. - * - * @return the number of shapes - */ - public int getNumShapes() - { - return field_1_numShapes; - } - - /** - * The number of shapes in this drawing group. - * - * @param field_1_numShapes the number of shapes - */ - public void setNumShapes( int field_1_numShapes ) - { - this.field_1_numShapes = field_1_numShapes; - } - - /** - * The last shape id used in this drawing group. - * - * @return the last shape id - */ - public int getLastMSOSPID() - { - return field_2_lastMSOSPID; - } - - /** - * The last shape id used in this drawing group. - * - * @param field_2_lastMSOSPID the last shape id - */ - public void setLastMSOSPID( int field_2_lastMSOSPID ) - { - this.field_2_lastMSOSPID = field_2_lastMSOSPID; - } - - /** - * Gets the drawing group id for this record. This is encoded in the - * instance part of the option record. - * - * @return a drawing group id. - */ - public short getDrawingGroupId() - { - return (short) ( getOptions() >> 4 ); - } - - /** - * Increments the number of shapes - */ - public void incrementShapeCount() - { - this.field_1_numShapes++; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java deleted file mode 100644 index 5b1b8b744..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java +++ /dev/null @@ -1,300 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.RecordFormatException; - -import java.util.*; - -/** - * This record defines the drawing groups used for a particular sheet. - */ -public final class EscherDggRecord extends EscherRecord { - public static final short RECORD_ID = (short) 0xF006; - public static final String RECORD_DESCRIPTION = "MsofbtDgg"; - - private int field_1_shapeIdMax; -// private int field_2_numIdClusters; // for some reason the number of clusters is actually the real number + 1 - private int field_3_numShapesSaved; - private int field_4_drawingsSaved; - private FileIdCluster[] field_5_fileIdClusters; - private int maxDgId; - - public static class FileIdCluster - { - public FileIdCluster( int drawingGroupId, int numShapeIdsUsed ) - { - this.field_1_drawingGroupId = drawingGroupId; - this.field_2_numShapeIdsUsed = numShapeIdsUsed; - } - - private int field_1_drawingGroupId; - private int field_2_numShapeIdsUsed; - - public int getDrawingGroupId() - { - return field_1_drawingGroupId; - } - - public int getNumShapeIdsUsed() - { - return field_2_numShapeIdsUsed; - } - - public void incrementShapeId( ) - { - this.field_2_numShapeIdsUsed++; - } - } - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - field_1_shapeIdMax = LittleEndian.getInt( data, pos + size );size+=4; - // field_2_numIdClusters = LittleEndian.getInt( data, pos + size ); - size+=4; - field_3_numShapesSaved = LittleEndian.getInt( data, pos + size );size+=4; - field_4_drawingsSaved = LittleEndian.getInt( data, pos + size );size+=4; - field_5_fileIdClusters = new FileIdCluster[(bytesRemaining-size) / 8]; // Can't rely on field_2_numIdClusters - for (int i = 0; i < field_5_fileIdClusters.length; i++) - { - field_5_fileIdClusters[i] = new FileIdCluster(LittleEndian.getInt( data, pos + size ), LittleEndian.getInt( data, pos + size + 4 )); - maxDgId = Math.max(maxDgId, field_5_fileIdClusters[i].getDrawingGroupId()); - size += 8; - } - bytesRemaining -= size; - if (bytesRemaining != 0) - throw new RecordFormatException("Expecting no remaining data but got " + bytesRemaining + " byte(s)."); - return 8 + size + bytesRemaining; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - int pos = offset; - LittleEndian.putShort( data, pos, getOptions() ); pos += 2; - LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; - int remainingBytes = getRecordSize() - 8; - LittleEndian.putInt( data, pos, remainingBytes ); pos += 4; - - LittleEndian.putInt( data, pos, field_1_shapeIdMax ); pos += 4; - LittleEndian.putInt( data, pos, getNumIdClusters() ); pos += 4; - LittleEndian.putInt( data, pos, field_3_numShapesSaved ); pos += 4; - LittleEndian.putInt( data, pos, field_4_drawingsSaved ); pos += 4; - for (int i = 0; i < field_5_fileIdClusters.length; i++) { - LittleEndian.putInt( data, pos, field_5_fileIdClusters[i].field_1_drawingGroupId ); pos += 4; - LittleEndian.putInt( data, pos, field_5_fileIdClusters[i].field_2_numShapeIdsUsed ); pos += 4; - } - - listener.afterRecordSerialize( pos, getRecordId(), getRecordSize(), this ); - return getRecordSize(); - } - - @Override - public int getRecordSize() { - return 8 + 16 + (8 * field_5_fileIdClusters.length); - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "Dgg"; - } - - @Override - public String toString() { - - StringBuilder field_5_string = new StringBuilder(); - if(field_5_fileIdClusters != null) for (int i = 0; i < field_5_fileIdClusters.length; i++) { - field_5_string.append(" DrawingGroupId").append(i+1).append(": "); - field_5_string.append(field_5_fileIdClusters[i].field_1_drawingGroupId); - field_5_string.append('\n'); - field_5_string.append(" NumShapeIdsUsed").append(i+1).append(": "); - field_5_string.append(field_5_fileIdClusters[i].field_2_numShapeIdsUsed); - field_5_string.append('\n'); - } - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + '\n' + - " Version: 0x" + HexDump.toHex(getVersion()) + '\n' + - " Instance: 0x" + HexDump.toHex(getInstance()) + '\n' + - " ShapeIdMax: " + field_1_shapeIdMax + '\n' + - " NumIdClusters: " + getNumIdClusters() + '\n' + - " NumShapesSaved: " + field_3_numShapesSaved + '\n' + - " DrawingsSaved: " + field_4_drawingsSaved + '\n' + - "" + field_5_string.toString(); - - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(field_1_shapeIdMax).append("\n") - .append(tab).append("\t").append("").append(getNumIdClusters()).append("\n") - .append(tab).append("\t").append("").append(field_3_numShapesSaved).append("\n") - .append(tab).append("\t").append("").append(field_4_drawingsSaved).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Gets the next available shape id - * - * @return the next available shape id - */ - public int getShapeIdMax() { - return field_1_shapeIdMax; - } - - /** - * The maximum is actually the next available shape id. - * - * @param shapeIdMax the next available shape id - */ - public void setShapeIdMax(int shapeIdMax) { - this.field_1_shapeIdMax = shapeIdMax; - } - - /** - * Number of id clusters + 1 - * - * @return the number of id clusters + 1 - */ - public int getNumIdClusters() { - return (field_5_fileIdClusters == null ? 0 : (field_5_fileIdClusters.length + 1)); - } - - /** - * Gets the number of shapes saved - * - * @return the number of shapes saved - */ - public int getNumShapesSaved() { - return field_3_numShapesSaved; - } - - /** - * Sets the number of shapes saved - * - * @param numShapesSaved the number of shapes saved - */ - public void setNumShapesSaved(int numShapesSaved) { - this.field_3_numShapesSaved = numShapesSaved; - } - - /** - * Gets the number of drawings saved - * - * @return the number of drawings saved - */ - public int getDrawingsSaved() { - return field_4_drawingsSaved; - } - - /** - * Sets the number of drawings saved - * - * @param drawingsSaved the number of drawings saved - */ - public void setDrawingsSaved(int drawingsSaved) { - this.field_4_drawingsSaved = drawingsSaved; - } - - /** - * Gets the maximum drawing group ID - * - * @return The maximum drawing group ID - */ - public int getMaxDrawingGroupId() { - return maxDgId; - } - - /** - * Sets the maximum drawing group ID - * - * @param id the maximum drawing group ID - */ - public void setMaxDrawingGroupId(int id) { - maxDgId = id; - } - - /** - * @return the file id clusters - */ - public FileIdCluster[] getFileIdClusters() { - return field_5_fileIdClusters; - } - - /** - * Sets the file id clusters - * - * @param fileIdClusters the file id clusters - */ - public void setFileIdClusters(FileIdCluster[] fileIdClusters) { - this.field_5_fileIdClusters = fileIdClusters.clone(); - } - - - /** - * Add a new cluster - * - * @param dgId id of the drawing group (stored in the record options) - * @param numShapedUsed initial value of the numShapedUsed field - */ - public void addCluster(int dgId, int numShapedUsed) { - addCluster(dgId, numShapedUsed, true); - } - - /** - * Add a new cluster - * - * @param dgId id of the drawing group (stored in the record options) - * @param numShapedUsed initial value of the numShapedUsed field - * @param sort if true then sort clusters by drawing group id.( - * In Excel the clusters are sorted but in PPT they are not) - */ - public void addCluster( int dgId, int numShapedUsed, boolean sort ) { - List clusters = new ArrayList(Arrays.asList(field_5_fileIdClusters)); - clusters.add(new FileIdCluster(dgId, numShapedUsed)); - if(sort) Collections.sort(clusters, MY_COMP ); - maxDgId = Math.min(maxDgId, dgId); - field_5_fileIdClusters = clusters.toArray( new FileIdCluster[clusters.size()] ); - } - - private static final Comparator MY_COMP = new Comparator() { - @Override - public int compare(FileIdCluster f1, FileIdCluster f2) { - if (f1.getDrawingGroupId() == f2.getDrawingGroupId()) { - return 0; - } - if (f1.getDrawingGroupId() < f2.getDrawingGroupId()) { - return -1; - } - return +1; - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherDump.java b/trunk/src/java/org/apache/poi/ddf/EscherDump.java deleted file mode 100644 index 45905c936..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherDump.java +++ /dev/null @@ -1,924 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.HexRead; -import org.apache.poi.util.LittleEndian; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.zip.InflaterInputStream; - -/** - * Used to dump the contents of escher records to a PrintStream. - */ -public final class EscherDump { - - public EscherDump() { - // - } - - /** - * Decodes the escher stream from a byte array and dumps the results to - * a print stream. - * - * @param data The data array containing the escher records. - * @param offset The starting offset within the data array. - * @param size The number of bytes to read. - * @param out The output stream to write the results to. - * - */ - public void dump(byte[] data, int offset, int size, PrintStream out) { - EscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); - int pos = offset; - while ( pos < offset + size ) - { - EscherRecord r = recordFactory.createRecord(data, pos); - int bytesRead = r.fillFields(data, pos, recordFactory ); - out.println( r.toString() ); - pos += bytesRead; - } - } - - /** - * This version of dump is a translation from the open office escher dump routine. - * - * @param maxLength The number of bytes to read - * @param in An input stream to read from. - * @param out An output stream to write to. - * - * @throws IOException if the data can't be read or written - * @throws LittleEndian.BufferUnderrunException if an buffer underrun occurs - */ - public void dumpOld(long maxLength, InputStream in, PrintStream out) - throws IOException, LittleEndian.BufferUnderrunException { - long remainingBytes = maxLength; - short options; // 4 bits for the version and 12 bits for the instance - short recordId; - int recordBytesRemaining; // including enclosing records - short nDumpSize; - String recordName; - - boolean atEOF = false; - - while (!atEOF && (remainingBytes > 0)) { - options = LittleEndian.readShort( in ); - recordId = LittleEndian.readShort( in ); - recordBytesRemaining = LittleEndian.readInt( in ); - - remainingBytes -= 2 + 2 + 4; - - switch ( recordId ) - { - case (short) 0xF000: - recordName = "MsofbtDggContainer"; - break; - case (short) 0xF006: - recordName = "MsofbtDgg"; - break; - case (short) 0xF016: - recordName = "MsofbtCLSID"; - break; - case (short) 0xF00B: - recordName = "MsofbtOPT"; - break; - case (short) 0xF11A: - recordName = "MsofbtColorMRU"; - break; - case (short) 0xF11E: - recordName = "MsofbtSplitMenuColors"; - break; - case (short) 0xF001: - recordName = "MsofbtBstoreContainer"; - break; - case (short) 0xF007: - recordName = "MsofbtBSE"; - break; - case (short) 0xF002: - recordName = "MsofbtDgContainer"; - break; - case (short) 0xF008: - recordName = "MsofbtDg"; - break; - case (short) 0xF118: - recordName = "MsofbtRegroupItem"; - break; - case (short) 0xF120: - recordName = "MsofbtColorScheme"; - break; - case (short) 0xF003: - recordName = "MsofbtSpgrContainer"; - break; - case (short) 0xF004: - recordName = "MsofbtSpContainer"; - break; - case (short) 0xF009: - recordName = "MsofbtSpgr"; - break; - case (short) 0xF00A: - recordName = "MsofbtSp"; - break; - case (short) 0xF00C: - recordName = "MsofbtTextbox"; - break; - case (short) 0xF00D: - recordName = "MsofbtClientTextbox"; - break; - case (short) 0xF00E: - recordName = "MsofbtAnchor"; - break; - case (short) 0xF00F: - recordName = "MsofbtChildAnchor"; - break; - case (short) 0xF010: - recordName = "MsofbtClientAnchor"; - break; - case (short) 0xF011: - recordName = "MsofbtClientData"; - break; - case (short) 0xF11F: - recordName = "MsofbtOleObject"; - break; - case (short) 0xF11D: - recordName = "MsofbtDeletedPspl"; - break; - case (short) 0xF005: - recordName = "MsofbtSolverContainer"; - break; - case (short) 0xF012: - recordName = "MsofbtConnectorRule"; - break; - case (short) 0xF013: - recordName = "MsofbtAlignRule"; - break; - case (short) 0xF014: - recordName = "MsofbtArcRule"; - break; - case (short) 0xF015: - recordName = "MsofbtClientRule"; - break; - case (short) 0xF017: - recordName = "MsofbtCalloutRule"; - break; - case (short) 0xF119: - recordName = "MsofbtSelection"; - break; - case (short) 0xF122: - recordName = "MsofbtUDefProp"; - break; - default: - if ( recordId >= (short) 0xF018 && recordId <= (short) 0xF117 ) - recordName = "MsofbtBLIP"; - else if ( ( options & (short) 0x000F ) == (short) 0x000F ) - recordName = "UNKNOWN container"; - else - recordName = "UNKNOWN ID"; - } - - StringBuilder stringBuf = new StringBuilder(); - stringBuf.append( " " ); - stringBuf.append( HexDump.toHex( recordId ) ); - stringBuf.append( " " ).append( recordName ).append( " [" ); - stringBuf.append( HexDump.toHex( options ) ); - stringBuf.append( ',' ); - stringBuf.append( HexDump.toHex( recordBytesRemaining ) ); - stringBuf.append( "] instance: " ); - stringBuf.append( HexDump.toHex( ( (short) ( options >> 4 ) ) ) ); - out.println( stringBuf.toString() ); - stringBuf.setLength(0); - - - if ( recordId == (short) 0xF007 && 36 <= remainingBytes && 36 <= recordBytesRemaining ) - { // BSE, FBSE - // ULONG nP = pIn->GetRecPos(); - - byte n8; - // short n16; - // int n32; - - stringBuf = stringBuf.append( " btWin32: " ); - n8 = (byte) in.read(); - stringBuf.append( HexDump.toHex( n8 ) ); - stringBuf.append( getBlipType( n8 ) ); - stringBuf.append( " btMacOS: " ); - n8 = (byte) in.read(); - stringBuf.append( HexDump.toHex( n8 ) ); - stringBuf.append( getBlipType( n8 ) ); - out.println( stringBuf.toString() ); - - out.println( " rgbUid:" ); - HexDump.dump( in, out, 0, 16 ); - - out.print( " tag: " ); - outHex( 2, in, out ); - out.println(); - out.print( " size: " ); - outHex( 4, in, out ); - out.println(); - out.print( " cRef: " ); - outHex( 4, in, out ); - out.println(); - out.print( " offs: " ); - outHex( 4, in, out ); - out.println(); - out.print( " usage: " ); - outHex( 1, in, out ); - out.println(); - out.print( " cbName: " ); - outHex( 1, in, out ); - out.println(); - out.print( " unused2: " ); - outHex( 1, in, out ); - out.println(); - out.print( " unused3: " ); - outHex( 1, in, out ); - out.println(); - - // subtract the number of bytes we've read - remainingBytes -= 36; - //n -= pIn->GetRecPos() - nP; - recordBytesRemaining = 0; // loop to MsofbtBLIP - } - else if ( recordId == (short) 0xF010 && 0x12 <= remainingBytes && 0x12 <= recordBytesRemaining ) - { // ClientAnchor - //ULONG nP = pIn->GetRecPos(); - // short n16; - - out.print( " Flag: " ); - outHex( 2, in, out ); - out.println(); - out.print( " Col1: " ); - outHex( 2, in, out ); - out.print( " dX1: " ); - outHex( 2, in, out ); - out.print( " Row1: " ); - outHex( 2, in, out ); - out.print( " dY1: " ); - outHex( 2, in, out ); - out.println(); - out.print( " Col2: " ); - outHex( 2, in, out ); - out.print( " dX2: " ); - outHex( 2, in, out ); - out.print( " Row2: " ); - outHex( 2, in, out ); - out.print( " dY2: " ); - outHex( 2, in, out ); - out.println(); - - remainingBytes -= 18; - recordBytesRemaining -= 18; - - } - else if ( recordId == (short) 0xF00B || recordId == (short) 0xF122 ) - { // OPT - int nComplex = 0; - out.println( " PROPID VALUE" ); - while ( recordBytesRemaining >= 6 + nComplex && remainingBytes >= 6 + nComplex ) - { - short n16; - int n32; - n16 = LittleEndian.readShort( in ); - n32 = LittleEndian.readInt( in ); - - recordBytesRemaining -= 6; - remainingBytes -= 6; - out.print( " " ); - out.print( HexDump.toHex( n16 ) ); - out.print( " (" ); - int propertyId = n16 & (short) 0x3FFF; - out.print( " " + propertyId ); - if ( ( n16 & (short) 0x8000 ) == 0 ) - { - if ( ( n16 & (short) 0x4000 ) != 0 ) - out.print( ", fBlipID" ); - out.print( ") " ); - - out.print( HexDump.toHex( n32 ) ); - - if ( ( n16 & (short) 0x4000 ) == 0 ) - { - out.print( " (" ); - out.print( dec1616( n32 ) ); - out.print( ')' ); - out.print( " {" + propName( (short)propertyId ) + "}" ); - } - out.println(); - } - else - { - out.print( ", fComplex) " ); - out.print( HexDump.toHex( n32 ) ); - out.print( " - Complex prop len" ); - out.println( " {" + propName( (short)propertyId ) + "}" ); - - nComplex += n32; - } - - } - // complex property data - while ( ( nComplex & remainingBytes ) > 0 ) - { - nDumpSize = ( nComplex > (int) remainingBytes ) ? (short) remainingBytes : (short) nComplex; - HexDump.dump( in, out, 0, nDumpSize ); - nComplex -= nDumpSize; - recordBytesRemaining -= nDumpSize; - remainingBytes -= nDumpSize; - } - } - else if ( recordId == (short) 0xF012 ) - { - out.print( " Connector rule: " ); - out.print( LittleEndian.readInt( in ) ); - out.print( " ShapeID A: " ); - out.print( LittleEndian.readInt( in ) ); - out.print( " ShapeID B: " ); - out.print( LittleEndian.readInt( in ) ); - out.print( " ShapeID connector: " ); - out.print( LittleEndian.readInt( in ) ); - out.print( " Connect pt A: " ); - out.print( LittleEndian.readInt( in ) ); - out.print( " Connect pt B: " ); - out.println( LittleEndian.readInt( in ) ); - - recordBytesRemaining -= 24; - remainingBytes -= 24; - } - else if ( recordId >= (short) 0xF018 && recordId < (short) 0xF117 ) - { - out.println( " Secondary UID: " ); - HexDump.dump( in, out, 0, 16 ); - out.println( " Cache of size: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Boundary top: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Boundary left: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Boundary width: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Boundary height: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " X: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Y: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Cache of saved size: " + HexDump.toHex( LittleEndian.readInt( in ) ) ); - out.println( " Compression Flag: " + HexDump.toHex( (byte) in.read() ) ); - out.println( " Filter: " + HexDump.toHex( (byte) in.read() ) ); - out.println( " Data (after decompression): " ); - - recordBytesRemaining -= 34 + 16; - remainingBytes -= 34 + 16; - - nDumpSize = ( recordBytesRemaining > (int) remainingBytes ) ? (short) remainingBytes : (short) recordBytesRemaining; - - - byte[] buf = new byte[nDumpSize]; - int read = in.read( buf ); - while ( read != -1 && read < nDumpSize ) - read += in.read( buf, read, buf.length ); - ByteArrayInputStream bin = new ByteArrayInputStream( buf ); - - InputStream in1 = new InflaterInputStream( bin ); - int bytesToDump = -1; - HexDump.dump( in1, out, 0, bytesToDump ); - - recordBytesRemaining -= nDumpSize; - remainingBytes -= nDumpSize; - - } - - boolean isContainer = ( options & (short) 0x000F ) == (short) 0x000F; - if ( isContainer && remainingBytes >= 0 ) - { // Container - if ( recordBytesRemaining <= (int) remainingBytes ) - out.println( " completed within" ); - else - out.println( " continued elsewhere" ); - } - else if ( remainingBytes >= 0 ) - // -> 0x0000 ... 0x0FFF - { - nDumpSize = ( recordBytesRemaining > (int) remainingBytes ) ? (short) remainingBytes : (short) recordBytesRemaining; - - if ( nDumpSize != 0 ) - { - HexDump.dump( in, out, 0, nDumpSize ); - remainingBytes -= nDumpSize; - } - } - else - out.println( " >> OVERRUN <<" ); - } - - } - - /** - * Returns a property name given a property id. This is used only by the - * old escher dump routine. - * - * @param propertyId The property number for the name - * @return A descriptive name. - */ - private String propName(short propertyId) { - final class PropName { - final int _id; - final String _name; - public PropName(int id, String name) { - _id = id; - _name = name; - } - } - - final PropName[] props = new PropName[] { - new PropName(4, "transform.rotation"), - new PropName(119, "protection.lockrotation"), - new PropName(120, "protection.lockaspectratio"), - new PropName(121, "protection.lockposition"), - new PropName(122, "protection.lockagainstselect"), - new PropName(123, "protection.lockcropping"), - new PropName(124, "protection.lockvertices"), - new PropName(125, "protection.locktext"), - new PropName(126, "protection.lockadjusthandles"), - new PropName(127, "protection.lockagainstgrouping"), - new PropName(128, "text.textid"), - new PropName(129, "text.textleft"), - new PropName(130, "text.texttop"), - new PropName(131, "text.textright"), - new PropName(132, "text.textbottom"), - new PropName(133, "text.wraptext"), - new PropName(134, "text.scaletext"), - new PropName(135, "text.anchortext"), - new PropName(136, "text.textflow"), - new PropName(137, "text.fontrotation"), - new PropName(138, "text.idofnextshape"), - new PropName(139, "text.bidir"), - new PropName(187, "text.singleclickselects"), - new PropName(188, "text.usehostmargins"), - new PropName(189, "text.rotatetextwithshape"), - new PropName(190, "text.sizeshapetofittext"), - new PropName(191, "text.sizetexttofitshape"), - new PropName(192, "geotext.unicode"), - new PropName(193, "geotext.rtftext"), - new PropName(194, "geotext.alignmentoncurve"), - new PropName(195, "geotext.defaultpointsize"), - new PropName(196, "geotext.textspacing"), - new PropName(197, "geotext.fontfamilyname"), - new PropName(240, "geotext.reverseroworder"), - new PropName(241, "geotext.hastexteffect"), - new PropName(242, "geotext.rotatecharacters"), - new PropName(243, "geotext.kerncharacters"), - new PropName(244, "geotext.tightortrack"), - new PropName(245, "geotext.stretchtofitshape"), - new PropName(246, "geotext.charboundingbox"), - new PropName(247, "geotext.scaletextonpath"), - new PropName(248, "geotext.stretchcharheight"), - new PropName(249, "geotext.nomeasurealongpath"), - new PropName(250, "geotext.boldfont"), - new PropName(251, "geotext.italicfont"), - new PropName(252, "geotext.underlinefont"), - new PropName(253, "geotext.shadowfont"), - new PropName(254, "geotext.smallcapsfont"), - new PropName(255, "geotext.strikethroughfont"), - new PropName(256, "blip.cropfromtop"), - new PropName(257, "blip.cropfrombottom"), - new PropName(258, "blip.cropfromleft"), - new PropName(259, "blip.cropfromright"), - new PropName(260, "blip.bliptodisplay"), - new PropName(261, "blip.blipfilename"), - new PropName(262, "blip.blipflags"), - new PropName(263, "blip.transparentcolor"), - new PropName(264, "blip.contrastsetting"), - new PropName(265, "blip.brightnesssetting"), - new PropName(266, "blip.gamma"), - new PropName(267, "blip.pictureid"), - new PropName(268, "blip.doublemod"), - new PropName(269, "blip.picturefillmod"), - new PropName(270, "blip.pictureline"), - new PropName(271, "blip.printblip"), - new PropName(272, "blip.printblipfilename"), - new PropName(273, "blip.printflags"), - new PropName(316, "blip.nohittestpicture"), - new PropName(317, "blip.picturegray"), - new PropName(318, "blip.picturebilevel"), - new PropName(319, "blip.pictureactive"), - new PropName(320, "geometry.left"), - new PropName(321, "geometry.top"), - new PropName(322, "geometry.right"), - new PropName(323, "geometry.bottom"), - new PropName(324, "geometry.shapepath"), - new PropName(325, "geometry.vertices"), - new PropName(326, "geometry.segmentinfo"), - new PropName(327, "geometry.adjustvalue"), - new PropName(328, "geometry.adjust2value"), - new PropName(329, "geometry.adjust3value"), - new PropName(330, "geometry.adjust4value"), - new PropName(331, "geometry.adjust5value"), - new PropName(332, "geometry.adjust6value"), - new PropName(333, "geometry.adjust7value"), - new PropName(334, "geometry.adjust8value"), - new PropName(335, "geometry.adjust9value"), - new PropName(336, "geometry.adjust10value"), - new PropName(378, "geometry.shadowOK"), - new PropName(379, "geometry.3dok"), - new PropName(380, "geometry.lineok"), - new PropName(381, "geometry.geotextok"), - new PropName(382, "geometry.fillshadeshapeok"), - new PropName(383, "geometry.fillok"), - new PropName(384, "fill.filltype"), - new PropName(385, "fill.fillcolor"), - new PropName(386, "fill.fillopacity"), - new PropName(387, "fill.fillbackcolor"), - new PropName(388, "fill.backopacity"), - new PropName(389, "fill.crmod"), - new PropName(390, "fill.patterntexture"), - new PropName(391, "fill.blipfilename"), - new PropName(392, "fill.blipflags"), - new PropName(393, "fill.width"), - new PropName(394, "fill.height"), - new PropName(395, "fill.angle"), - new PropName(396, "fill.focus"), - new PropName(397, "fill.toleft"), - new PropName(398, "fill.totop"), - new PropName(399, "fill.toright"), - new PropName(400, "fill.tobottom"), - new PropName(401, "fill.rectleft"), - new PropName(402, "fill.recttop"), - new PropName(403, "fill.rectright"), - new PropName(404, "fill.rectbottom"), - new PropName(405, "fill.dztype"), - new PropName(406, "fill.shadepreset"), - new PropName(407, "fill.shadecolors"), - new PropName(408, "fill.originx"), - new PropName(409, "fill.originy"), - new PropName(410, "fill.shapeoriginx"), - new PropName(411, "fill.shapeoriginy"), - new PropName(412, "fill.shadetype"), - new PropName(443, "fill.filled"), - new PropName(444, "fill.hittestfill"), - new PropName(445, "fill.shape"), - new PropName(446, "fill.userect"), - new PropName(447, "fill.nofillhittest"), - new PropName(448, "linestyle.color"), - new PropName(449, "linestyle.opacity"), - new PropName(450, "linestyle.backcolor"), - new PropName(451, "linestyle.crmod"), - new PropName(452, "linestyle.linetype"), - new PropName(453, "linestyle.fillblip"), - new PropName(454, "linestyle.fillblipname"), - new PropName(455, "linestyle.fillblipflags"), - new PropName(456, "linestyle.fillwidth"), - new PropName(457, "linestyle.fillheight"), - new PropName(458, "linestyle.filldztype"), - new PropName(459, "linestyle.linewidth"), - new PropName(460, "linestyle.linemiterlimit"), - new PropName(461, "linestyle.linestyle"), - new PropName(462, "linestyle.linedashing"), - new PropName(463, "linestyle.linedashstyle"), - new PropName(464, "linestyle.linestartarrowhead"), - new PropName(465, "linestyle.lineendarrowhead"), - new PropName(466, "linestyle.linestartarrowwidth"), - new PropName(467, "linestyle.lineestartarrowlength"), - new PropName(468, "linestyle.lineendarrowwidth"), - new PropName(469, "linestyle.lineendarrowlength"), - new PropName(470, "linestyle.linejoinstyle"), - new PropName(471, "linestyle.lineendcapstyle"), - new PropName(507, "linestyle.arrowheadsok"), - new PropName(508, "linestyle.anyline"), - new PropName(509, "linestyle.hitlinetest"), - new PropName(510, "linestyle.linefillshape"), - new PropName(511, "linestyle.nolinedrawdash"), - new PropName(512, "shadowstyle.type"), - new PropName(513, "shadowstyle.color"), - new PropName(514, "shadowstyle.highlight"), - new PropName(515, "shadowstyle.crmod"), - new PropName(516, "shadowstyle.opacity"), - new PropName(517, "shadowstyle.offsetx"), - new PropName(518, "shadowstyle.offsety"), - new PropName(519, "shadowstyle.secondoffsetx"), - new PropName(520, "shadowstyle.secondoffsety"), - new PropName(521, "shadowstyle.scalextox"), - new PropName(522, "shadowstyle.scaleytox"), - new PropName(523, "shadowstyle.scalextoy"), - new PropName(524, "shadowstyle.scaleytoy"), - new PropName(525, "shadowstyle.perspectivex"), - new PropName(526, "shadowstyle.perspectivey"), - new PropName(527, "shadowstyle.weight"), - new PropName(528, "shadowstyle.originx"), - new PropName(529, "shadowstyle.originy"), - new PropName(574, "shadowstyle.shadow"), - new PropName(575, "shadowstyle.shadowobsured"), - new PropName(576, "perspective.type"), - new PropName(577, "perspective.offsetx"), - new PropName(578, "perspective.offsety"), - new PropName(579, "perspective.scalextox"), - new PropName(580, "perspective.scaleytox"), - new PropName(581, "perspective.scalextoy"), - new PropName(582, "perspective.scaleytox"), - new PropName(583, "perspective.perspectivex"), - new PropName(584, "perspective.perspectivey"), - new PropName(585, "perspective.weight"), - new PropName(586, "perspective.originx"), - new PropName(587, "perspective.originy"), - new PropName(639, "perspective.perspectiveon"), - new PropName(640, "3d.specularamount"), - new PropName(661, "3d.diffuseamount"), - new PropName(662, "3d.shininess"), - new PropName(663, "3d.edgethickness"), - new PropName(664, "3d.extrudeforward"), - new PropName(665, "3d.extrudebackward"), - new PropName(666, "3d.extrudeplane"), - new PropName(667, "3d.extrusioncolor"), - new PropName(648, "3d.crmod"), - new PropName(700, "3d.3deffect"), - new PropName(701, "3d.metallic"), - new PropName(702, "3d.useextrusioncolor"), - new PropName(703, "3d.lightface"), - new PropName(704, "3dstyle.yrotationangle"), - new PropName(705, "3dstyle.xrotationangle"), - new PropName(706, "3dstyle.rotationaxisx"), - new PropName(707, "3dstyle.rotationaxisy"), - new PropName(708, "3dstyle.rotationaxisz"), - new PropName(709, "3dstyle.rotationangle"), - new PropName(710, "3dstyle.rotationcenterx"), - new PropName(711, "3dstyle.rotationcentery"), - new PropName(712, "3dstyle.rotationcenterz"), - new PropName(713, "3dstyle.rendermode"), - new PropName(714, "3dstyle.tolerance"), - new PropName(715, "3dstyle.xviewpoint"), - new PropName(716, "3dstyle.yviewpoint"), - new PropName(717, "3dstyle.zviewpoint"), - new PropName(718, "3dstyle.originx"), - new PropName(719, "3dstyle.originy"), - new PropName(720, "3dstyle.skewangle"), - new PropName(721, "3dstyle.skewamount"), - new PropName(722, "3dstyle.ambientintensity"), - new PropName(723, "3dstyle.keyx"), - new PropName(724, "3dstyle.keyy"), - new PropName(725, "3dstyle.keyz"), - new PropName(726, "3dstyle.keyintensity"), - new PropName(727, "3dstyle.fillx"), - new PropName(728, "3dstyle.filly"), - new PropName(729, "3dstyle.fillz"), - new PropName(730, "3dstyle.fillintensity"), - new PropName(763, "3dstyle.constrainrotation"), - new PropName(764, "3dstyle.rotationcenterauto"), - new PropName(765, "3dstyle.parallel"), - new PropName(766, "3dstyle.keyharsh"), - new PropName(767, "3dstyle.fillharsh"), - new PropName(769, "shape.master"), - new PropName(771, "shape.connectorstyle"), - new PropName(772, "shape.blackandwhitesettings"), - new PropName(773, "shape.wmodepurebw"), - new PropName(774, "shape.wmodebw"), - new PropName(826, "shape.oleicon"), - new PropName(827, "shape.preferrelativeresize"), - new PropName(828, "shape.lockshapetype"), - new PropName(830, "shape.deleteattachedobject"), - new PropName(831, "shape.backgroundshape"), - new PropName(832, "callout.callouttype"), - new PropName(833, "callout.xycalloutgap"), - new PropName(834, "callout.calloutangle"), - new PropName(835, "callout.calloutdroptype"), - new PropName(836, "callout.calloutdropspecified"), - new PropName(837, "callout.calloutlengthspecified"), - new PropName(889, "callout.iscallout"), - new PropName(890, "callout.calloutaccentbar"), - new PropName(891, "callout.callouttextborder"), - new PropName(892, "callout.calloutminusx"), - new PropName(893, "callout.calloutminusy"), - new PropName(894, "callout.dropauto"), - new PropName(895, "callout.lengthspecified"), - new PropName(896, "groupshape.shapename"), - new PropName(897, "groupshape.description"), - new PropName(898, "groupshape.hyperlink"), - new PropName(899, "groupshape.wrappolygonvertices"), - new PropName(900, "groupshape.wrapdistleft"), - new PropName(901, "groupshape.wrapdisttop"), - new PropName(902, "groupshape.wrapdistright"), - new PropName(903, "groupshape.wrapdistbottom"), - new PropName(904, "groupshape.regroupid"), - new PropName(953, "groupshape.editedwrap"), - new PropName(954, "groupshape.behinddocument"), - new PropName(955, "groupshape.ondblclicknotify"), - new PropName(956, "groupshape.isbutton"), - new PropName(957, "groupshape.1dadjustment"), - new PropName(958, "groupshape.hidden"), - new PropName(959, "groupshape.print"), - }; - - for (int i = 0; i < props.length; i++) { - if (props[i]._id == propertyId) { - return props[i]._name; - } - } - - return "unknown property"; - } - - /** - * Returns the blip description given a blip id. - * - * @param b blip id - * @return A description. - */ - private static String getBlipType(byte b) { - return EscherBSERecord.getBlipType(b); - } - - /** - * Straight conversion from OO. Converts a type of float. - */ - private String dec1616( int n32 ) - { - String result = ""; - result += (short) ( n32 >> 16 ); - result += '.'; - result += (short) ( n32 & 0xFFFF ); - return result; - } - - /** - * Dumps out a hex value by reading from a input stream. - * - * @param bytes How many bytes this hex value consists of. - * @param in The stream to read the hex value from. - * @param out The stream to write the nicely formatted hex value to. - */ - private void outHex( int bytes, InputStream in, PrintStream out ) throws IOException, LittleEndian.BufferUnderrunException - { - switch ( bytes ) - { - case 1: - out.print( HexDump.toHex( (byte) in.read() ) ); - break; - case 2: - out.print( HexDump.toHex( LittleEndian.readShort( in ) ) ); - break; - case 4: - out.print( HexDump.toHex( LittleEndian.readInt( in ) ) ); - break; - default: - throw new IOException( "Unable to output variable of that width" ); - } - } - - /** - * A simple test stub. - * - * @param args the args - */ - public static void main( String[] args ) { - main(args, System.out); - } - - public static void main( String[] args, PrintStream out ) { - String dump = - "0F 00 00 F0 89 07 00 00 00 00 06 F0 18 00 00 00 " + - "05 04 00 00 02 00 00 00 05 00 00 00 01 00 00 00 " + - "01 00 00 00 05 00 00 00 4F 00 01 F0 2F 07 00 00 " + - "42 00 07 F0 B7 01 00 00 03 04 3F 14 AE 6B 0F 65 " + - "B0 48 BF 5E 94 63 80 E8 91 73 FF 00 93 01 00 00 " + - "01 00 00 00 00 00 00 00 00 00 FF FF 20 54 1C F0 " + - "8B 01 00 00 3F 14 AE 6B 0F 65 B0 48 BF 5E 94 63 " + - "80 E8 91 73 92 0E 00 00 00 00 00 00 00 00 00 00 " + - "D1 07 00 00 DD 05 00 00 4A AD 6F 00 8A C5 53 00 " + - "59 01 00 00 00 FE 78 9C E3 9B C4 00 04 AC 77 D9 " + - "2F 32 08 32 FD E7 61 F8 FF 0F C8 FD 05 C5 30 19 " + - "10 90 63 90 FA 0F 06 0C 8C 0C 5C 70 19 43 30 EB " + - "0E FB 05 86 85 0C DB 18 58 80 72 8C 70 16 0B 83 " + - "05 56 51 29 88 C9 60 D9 69 0C 6C 20 26 23 03 C8 " + - "74 B0 A8 0E 03 07 FB 45 56 C7 A2 CC C4 1C 06 66 " + - "A0 0D 2C 40 39 5E 86 4C 06 3D A0 4E 10 D0 60 D9 " + - "C8 58 CC E8 CF B0 80 61 3A 8A 7E 0D C6 23 AC 4F " + - "E0 E2 98 B6 12 2B 06 73 9D 12 E3 52 56 59 F6 08 " + - "8A CC 52 66 A3 50 FF 96 2B 94 E9 DF 4C A1 FE 2D " + - "3A 03 AB 9F 81 C2 F0 A3 54 BF 0F 85 EE A7 54 FF " + - "40 FB 7F A0 E3 9F D2 F4 4F 71 FE 19 58 FF 2B 31 " + - "7F 67 36 3B 25 4F 99 1B 4E 53 A6 5F 89 25 95 E9 " + - "C4 00 C7 83 12 F3 1F 26 35 4A D3 D2 47 0E 0A C3 " + - "41 8E C9 8A 52 37 DC 15 A1 D0 0D BC 4C 06 0C 2B " + - "28 2C 13 28 D4 EF 43 61 5A A0 58 3F 85 71 E0 4B " + - "69 9E 64 65 FE 39 C0 E5 22 30 1D 30 27 0E 74 3A " + - "18 60 FD 4A CC B1 2C 13 7D 07 36 2D 2A 31 85 B2 " + - "6A 0D 74 1D 1D 22 4D 99 FE 60 0A F5 9B EC 1C 58 " + - "FD 67 06 56 3F 38 0D 84 3C A5 30 0E 28 D3 AF C4 " + - "A4 CA FA 44 7A 0D 65 6E 60 7F 4D A1 1B 24 58 F7 " + - "49 AF A5 CC 0D CC DF 19 FE 03 00 F0 B1 25 4D 42 " + - "00 07 F0 E1 01 00 00 03 04 39 50 BE 98 B0 6F 57 " + - "24 31 70 5D 23 2F 9F 10 66 FF 00 BD 01 00 00 01 " + - "00 00 00 00 00 00 00 00 00 FF FF 20 54 1C F0 B5 " + - "01 00 00 39 50 BE 98 B0 6F 57 24 31 70 5D 23 2F " + - "9F 10 66 DA 03 00 00 00 00 00 00 00 00 00 00 D1 " + - "07 00 00 DD 05 00 00 4A AD 6F 00 8A C5 53 00 83 " + - "01 00 00 00 FE 78 9C A5 52 BF 4B 42 51 14 3E F7 " + - "DC 77 7A 16 45 48 8B 3C 48 A8 16 15 0D 6C 88 D0 " + - "04 C3 40 A3 32 1C 84 96 08 21 04 A1 C5 5C A2 35 " + - "82 C0 35 6A AB 1C 6A 6B A8 24 5A 83 68 08 84 84 " + - "96 A2 86 A0 7F C2 86 5E E7 5E F5 41 E4 10 BC 03 " + - "1F E7 FB F1 CE B9 F7 F1 9E 7C 05 2E 7A 37 9B E0 " + - "45 7B 10 EC 6F 96 5F 1D 74 13 55 7E B0 6C 5D 20 " + - "60 C0 49 A2 9A BD 99 4F 50 83 1B 30 38 13 0E 33 " + - "60 A6 A7 6B B5 37 EB F4 10 FA 14 15 A0 B6 6B 37 " + - "0C 1E B3 49 73 5B A5 C2 26 48 3E C1 E0 6C 08 4A " + - "30 C9 93 AA 02 B8 20 13 62 05 4E E1 E8 D7 7C C0 " + - "B8 14 95 5E BE B8 A7 CF 1E BE 55 2C 56 B9 78 DF " + - "08 7E 88 4C 27 FF 7B DB FF 7A DD B7 1A 17 67 34 " + - "6A AE BA DA 35 D1 E7 72 BE FE EC 6E FE DA E5 7C " + - "3D EC 7A DE 03 FD 50 06 0B 23 F2 0E F3 B2 A5 11 " + - "91 0D 4C B5 B5 F3 BF 94 C1 8F 24 F7 D9 6F 60 94 " + - "3B C9 9A F3 1C 6B E7 BB F0 2E 49 B2 25 2B C6 B1 " + - "EE 69 EE 15 63 4F 71 7D CE 85 CC C8 35 B9 C3 28 " + - "28 CE D0 5C 67 79 F2 4A A2 14 23 A4 38 43 73 9D " + - "2D 69 2F C1 08 31 9F C5 5C 9B EB 7B C5 69 19 B3 " + - "B4 81 F3 DC E3 B4 8E 8B CC B3 94 53 5A E7 41 2A " + - "63 9A AA 38 C5 3D 48 BB EC 57 59 6F 2B AD 73 1F " + - "1D 60 92 AE 70 8C BB 8F CE 31 C1 3C 49 27 4A EB " + - "DC A4 5B 8C D1 0B 0E 73 37 E9 11 A7 99 C7 E8 41 " + - "69 B0 7F 00 96 F2 A7 E8 42 00 07 F0 B4 01 00 00 " + - "03 04 1A BA F9 D6 A9 B9 3A 03 08 61 E9 90 FF 7B " + - "9E E6 FF 00 90 01 00 00 01 00 00 00 00 00 00 00 " + - "00 00 FF FF 20 54 1C F0 88 01 00 00 1A BA F9 D6 " + - "A9 B9 3A 03 08 61 E9 90 FF 7B 9E E6 12 0E 00 00 " + - "00 00 00 00 00 00 00 00 D1 07 00 00 DD 05 00 00 " + - "4A AD 6F 00 8A C5 53 00 56 01 00 00 00 FE 78 9C " + - "E3 13 62 00 02 D6 BB EC 17 19 04 99 FE F3 30 FC " + - "FF 07 E4 FE 82 62 98 0C 08 C8 31 48 FD 07 03 06 " + - "46 06 2E B8 8C 21 98 75 87 FD 02 C3 42 86 6D 0C " + - "2C 40 39 46 38 8B 85 C1 02 AB A8 14 C4 64 B0 EC " + - "34 06 36 10 93 91 01 64 3A 58 54 87 81 83 FD 22 " + - "AB 63 51 66 62 0E 03 33 D0 06 16 A0 1C 2F 43 26 " + - "83 1E 50 27 08 68 B0 6C 64 2C 66 F4 67 58 C0 30 " + - "1D 45 BF 06 E3 11 D6 27 70 71 4C 5B 89 15 83 B9 " + - "4E 89 71 29 AB 2C 7B 04 45 66 29 B3 51 A8 7F CB " + - "15 CA F4 6F A6 50 FF 16 9D 81 D5 CF 40 61 F8 51 " + - "AA DF 87 42 F7 53 AA 7F A0 FD 3F D0 F1 4F 69 FA " + - "A7 38 FF 0C AC FF 95 98 BF 33 9B 9D 92 A7 CC 0D " + - "A7 29 D3 AF C4 92 CA 74 62 80 E3 41 89 F9 0F 93 " + - "1A A5 69 E9 23 07 85 E1 20 C7 64 45 A9 1B EE 8A " + - "50 E8 06 5E 26 03 86 15 14 96 09 14 EA F7 A1 30 " + - "2D 50 AC 9F C2 38 F0 A5 34 4F B2 32 FF 1C E0 72 " + - "11 98 0E 98 13 07 38 1D 28 31 C7 B2 4C F4 1D D8 " + - "B4 A0 C4 14 CA AA 35 D0 75 64 88 34 65 FA 83 29 " + - "D4 6F B2 73 60 F5 9F A1 54 FF 0E CA D3 40 C8 53 " + - "0A E3 E0 09 85 6E 50 65 7D 22 BD 86 32 37 B0 BF " + - "A6 D0 0D 12 AC FB A4 D7 52 E6 06 E6 EF 0C FF 01 " + - "97 1D 12 C7 42 00 07 F0 C3 01 00 00 03 04 BA 4C " + - "B6 23 BA 8B 27 BE C8 55 59 86 24 9F 89 D4 FF 00 " + - "9F 01 00 00 01 00 00 00 00 00 00 00 00 00 FF FF " + - "20 54 1C F0 97 01 00 00 BA 4C B6 23 BA 8B 27 BE " + - "C8 55 59 86 24 9F 89 D4 AE 0E 00 00 00 00 00 00 " + - "00 00 00 00 D1 07 00 00 DD 05 00 00 4A AD 6F 00 " + - "8A C5 53 00 65 01 00 00 00 FE 78 9C E3 5B C7 00 " + - "04 AC 77 D9 2F 32 08 32 FD E7 61 F8 FF 0F C8 FD " + - "05 C5 30 19 10 90 63 90 FA 0F 06 0C 8C 0C 5C 70 " + - "19 43 30 EB 0E FB 05 86 85 0C DB 18 58 80 72 8C " + - "70 16 0B 83 05 56 51 29 88 C9 60 D9 69 0C 6C 20 " + - "26 23 03 C8 74 B0 A8 0E 03 07 FB 45 56 C7 A2 CC " + - "C4 1C 06 66 A0 0D 2C 40 39 5E 86 4C 06 3D A0 4E " + - "10 D0 60 99 C6 B8 98 D1 9F 61 01 C3 74 14 FD 1A " + - "8C 2B D8 84 B1 88 4B A5 A5 75 03 01 50 DF 59 46 " + - "77 46 0F A8 3C A6 AB 88 15 83 B9 5E 89 B1 8B D5 " + - "97 2D 82 22 B3 94 29 D5 BF E5 CA C0 EA DF AC 43 " + - "A1 FD 14 EA 67 A0 30 FC 28 D5 EF 43 A1 FB 7D 87 " + - "B8 FF 07 3A FE 07 3A FD 53 EA 7E 0A C3 4F 89 F9 " + - "0E 73 EA 69 79 CA DC 70 8A 32 FD 4A 2C 5E 4C DF " + - "87 7A 3C BC E0 A5 30 1E 3E 31 C5 33 AC A0 30 2F " + - "52 A8 DF 87 C2 30 A4 54 3F A5 65 19 85 65 A9 12 " + - "D3 2B 16 0D 8A CB 13 4A F3 E3 27 E6 09 03 9D 0E " + - "06 58 BF 12 B3 13 CB C1 01 4E 8B 4A 4C 56 AC 91 " + - "03 5D 37 86 48 53 A6 3F 98 42 FD 26 3B 07 56 FF " + - "99 1D 14 EA A7 CC 7E 70 1A 08 79 42 61 1C 3C A5 " + - "D0 0D 9C 6C C2 32 6B 29 73 03 DB 6B CA DC C0 F8 " + - "97 F5 AD CC 1A CA DC C0 F4 83 32 37 B0 A4 30 CE " + - "FC C7 48 99 1B FE 33 32 FC 07 00 6C CC 2E 23 33 " + - "00 0B F0 12 00 00 00 BF 00 08 00 08 00 81 01 09 " + - "00 00 08 C0 01 40 00 00 08 40 00 1E F1 10 00 00 " + - "00 0D 00 00 08 0C 00 00 08 17 00 00 08 F7 00 00 " + - "10 "; - - // Decode the stream to bytes - byte[] bytes = HexRead.readFromString(dump); - // Create a new instance of the escher dumper - EscherDump dumper = new EscherDump(); - // Dump the contents of scher to screen. -// dumper.dumpOld( bytes.length, new ByteArrayInputStream( bytes ), System.out ); - dumper.dump(bytes, 0, bytes.length, out); - - } - - public void dump( int recordSize, byte[] data, PrintStream out ) { - dump( data, 0, recordSize, out ); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java b/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java deleted file mode 100644 index 740df26dd..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java +++ /dev/null @@ -1,410 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.hssf.usermodel.HSSFPictureData; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.zip.InflaterInputStream; -import java.util.zip.DeflaterOutputStream; - -public final class EscherMetafileBlip extends EscherBlipRecord { - private static final POILogger log = POILogFactory.getLogger(EscherMetafileBlip.class); - - public static final short RECORD_ID_EMF = (short) 0xF018 + 2; - public static final short RECORD_ID_WMF = (short) 0xF018 + 3; - public static final short RECORD_ID_PICT = (short) 0xF018 + 4; - - private static final int HEADER_SIZE = 8; - - private final byte[] field_1_UID = new byte[16]; - /** - * The primary UID is only saved to disk if (blip_instance ^ blip_signature == 1) - */ - private final byte[] field_2_UID = new byte[16]; - private int field_2_cb; - private int field_3_rcBounds_x1; - private int field_3_rcBounds_y1; - private int field_3_rcBounds_x2; - private int field_3_rcBounds_y2; - private int field_4_ptSize_w; - private int field_4_ptSize_h; - private int field_5_cbSave; - private byte field_6_fCompression; - private byte field_7_fFilter; - - private byte[] raw_pictureData; - private byte[] remainingData; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesAfterHeader = readHeader( data, offset ); - int pos = offset + HEADER_SIZE; - System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16; - - if((getOptions() ^ getSignature()) == 0x10){ - System.arraycopy( data, pos, field_2_UID, 0, 16 ); pos += 16; - } - - field_2_cb = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_x1 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_y1 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_x2 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_y2 = LittleEndian.getInt( data, pos ); pos += 4; - field_4_ptSize_w = LittleEndian.getInt( data, pos ); pos += 4; - field_4_ptSize_h = LittleEndian.getInt( data, pos ); pos += 4; - field_5_cbSave = LittleEndian.getInt( data, pos ); pos += 4; - field_6_fCompression = data[pos]; pos++; - field_7_fFilter = data[pos]; pos++; - - raw_pictureData = new byte[field_5_cbSave]; - System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave ); - pos += field_5_cbSave; - - // 0 means DEFLATE compression - // 0xFE means no compression - if (field_6_fCompression == 0) { - field_pictureData = inflatePictureData(raw_pictureData); - } else { - field_pictureData = raw_pictureData; - } - - int remaining = bytesAfterHeader - pos + offset + HEADER_SIZE; - if(remaining > 0) { - remainingData = new byte[remaining]; - System.arraycopy( data, pos, remainingData, 0, remaining ); - } - return bytesAfterHeader + HEADER_SIZE; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize(offset, getRecordId(), this); - - int pos = offset; - LittleEndian.putShort( data, pos, getOptions() ); pos += 2; - LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; - LittleEndian.putInt( data, pos, getRecordSize() - HEADER_SIZE ); pos += 4; - - System.arraycopy( field_1_UID, 0, data, pos, field_1_UID.length ); pos += field_1_UID.length; - if ((getOptions() ^ getSignature()) == 0x10) { - System.arraycopy( field_2_UID, 0, data, pos, field_2_UID.length ); pos += field_2_UID.length; - } - LittleEndian.putInt( data, pos, field_2_cb ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_x1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_y1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_x2 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_y2 ); pos += 4; - LittleEndian.putInt( data, pos, field_4_ptSize_w ); pos += 4; - LittleEndian.putInt( data, pos, field_4_ptSize_h ); pos += 4; - LittleEndian.putInt( data, pos, field_5_cbSave ); pos += 4; - data[pos] = field_6_fCompression; pos++; - data[pos] = field_7_fFilter; pos++; - - System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length ); pos += raw_pictureData.length; - if(remainingData != null) { - System.arraycopy( remainingData, 0, data, pos, remainingData.length ); pos += remainingData.length; - } - - listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this); - return getRecordSize(); - } - - /** - * Decompresses the provided data, returning the inflated result. - * - * @param data the deflated picture data. - * @return the inflated picture data. - */ - private static byte[] inflatePictureData(byte[] data) { - try { - InflaterInputStream in = new InflaterInputStream( - new ByteArrayInputStream( data ) ); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buf = new byte[4096]; - int readBytes; - while ((readBytes = in.read(buf)) > 0) { - out.write(buf, 0, readBytes); - } - return out.toByteArray(); - } catch (IOException e) { - log.log(POILogger.WARN, "Possibly corrupt compression or non-compressed data", e); - return data; - } - } - - @Override - public int getRecordSize() { - int size = 8 + 50 + raw_pictureData.length; - if(remainingData != null) size += remainingData.length; - if((getOptions() ^ getSignature()) == 0x10){ - size += field_2_UID.length; - } - return size; - } - - /** - * Gets the first MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @return the first MD4 - */ - public byte[] getUID() { - return field_1_UID; - } - - /** - * Sets the first MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @param uid the first MD4 - */ - public void setUID(byte[] uid) { - if (uid == null || uid.length != 16) { - throw new IllegalArgumentException("uid must be byte[16]"); - } - System.arraycopy(uid, 0, field_1_UID, 0, field_1_UID.length); - } - - /** - * Gets the second MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @return the second MD4 - */ - public byte[] getPrimaryUID() { - return field_2_UID; - } - - /** - * Sets the second MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @param primaryUID the second MD4 - */ - public void setPrimaryUID(byte[] primaryUID) { - if (primaryUID == null || primaryUID.length != 16) { - throw new IllegalArgumentException("primaryUID must be byte[16]"); - } - System.arraycopy(primaryUID, 0, field_2_UID, 0, field_2_UID.length); - } - - /** - * Gets the uncompressed size (in bytes) - * - * @return the uncompressed size - */ - public int getUncompressedSize() { - return field_2_cb; - } - - /** - * Sets the uncompressed size (in bytes) - * - * @param uncompressedSize the uncompressed size - */ - public void setUncompressedSize(int uncompressedSize) { - field_2_cb = uncompressedSize; - } - - /** - * Get the clipping region of the metafile - * - * @return the clipping region - */ - public Rectangle getBounds() { - return new Rectangle(field_3_rcBounds_x1, - field_3_rcBounds_y1, - field_3_rcBounds_x2 - field_3_rcBounds_x1, - field_3_rcBounds_y2 - field_3_rcBounds_y1); - } - - /** - * Sets the clipping region - * - * @param bounds the clipping region - */ - public void setBounds(Rectangle bounds) { - field_3_rcBounds_x1 = bounds.x; - field_3_rcBounds_y1 = bounds.y; - field_3_rcBounds_x2 = bounds.x + bounds.width; - field_3_rcBounds_y2 = bounds.y + bounds.height; - } - - /** - * Gets the dimensions of the metafile - * - * @return the dimensions of the metafile - */ - public Dimension getSizeEMU() { - return new Dimension(field_4_ptSize_w, field_4_ptSize_h); - } - - /** - * Gets the dimensions of the metafile - * - * @param sizeEMU the dimensions of the metafile - */ - public void setSizeEMU(Dimension sizeEMU) { - field_4_ptSize_w = sizeEMU.width; - field_4_ptSize_h = sizeEMU.height; - } - - /** - * Gets the compressed size of the metafile (in bytes) - * - * @return the compressed size - */ - public int getCompressedSize() { - return field_5_cbSave; - } - - /** - * Sets the compressed size of the metafile (in bytes) - * - * @param compressedSize the compressed size - */ - public void setCompressedSize(int compressedSize) { - field_5_cbSave = compressedSize; - } - - /** - * Gets the compression of the metafile - * - * @return true, if the metafile is compressed - */ - public boolean isCompressed() { - return (field_6_fCompression == 0); - } - - /** - * Sets the compression of the metafile - * - * @param compressed the compression state, true if it's compressed - */ - public void setCompressed(boolean compressed) { - field_6_fCompression = compressed ? 0 : (byte)0xFE; - } - - /** - * Returns any remaining bytes - * - * @return any remaining bytes - */ - public byte[] getRemainingData() { - return remainingData; - } - - // filtering is always 254 according to available docs, so no point giving it a setter method. - - @Override - public String toString() { - String extraData = "";//HexDump.toHex(field_pictureData, 32); - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' + - " Version: 0x" + HexDump.toHex( getVersion() ) + '\n' + - " Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' + - " UID: 0x" + HexDump.toHex( field_1_UID ) + '\n' + - (field_2_UID == null ? "" : (" UID2: 0x" + HexDump.toHex( field_2_UID ) + '\n')) + - " Uncompressed Size: " + HexDump.toHex( field_2_cb ) + '\n' + - " Bounds: " + getBounds() + '\n' + - " Size in EMU: " + getSizeEMU() + '\n' + - " Compressed Size: " + HexDump.toHex( field_5_cbSave ) + '\n' + - " Compression: " + HexDump.toHex( field_6_fCompression ) + '\n' + - " Filter: " + HexDump.toHex( field_7_fFilter ) + '\n' + - " Extra Data:" + '\n' + extraData + - (remainingData == null ? null : ("\n" + - " Remaining Data: " + HexDump.toHex(remainingData, 32))); - } - - @Override - public String toXml(String tab) { - String extraData = ""; - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_1_UID ) + '\n' + - (field_2_UID == null ? "" : (" UID2: 0x" + HexDump.toHex( field_2_UID ) + '\n'))).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_2_cb )).append("\n") - .append(tab).append("\t").append("").append(getBounds()).append("\n") - .append(tab).append("\t").append("").append(getSizeEMU()).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_5_cbSave )).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_6_fCompression )).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_7_fFilter )).append("\n") - .append(tab).append("\t").append("").append(extraData).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex(remainingData, 32)).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Return the blip signature - * - * @return the blip signature - */ - public short getSignature() { - switch (getRecordId()) { - case RECORD_ID_EMF: return HSSFPictureData.MSOBI_EMF; - case RECORD_ID_WMF: return HSSFPictureData.MSOBI_WMF; - case RECORD_ID_PICT: return HSSFPictureData.MSOBI_PICT; - } - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Unknown metafile: " + getRecordId()); - } - return 0; - } - - @Override - public void setPictureData(byte[] pictureData) { - super.setPictureData(pictureData); - setUncompressedSize(pictureData.length); - - // info of chicago project: - // "... LZ compression algorithm in the format used by GNU Zip deflate/inflate with a 32k window ..." - // not sure what to do, when lookup tables exceed 32k ... - - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - DeflaterOutputStream dos = new DeflaterOutputStream(bos); - dos.write(pictureData); - dos.close(); - raw_pictureData = bos.toByteArray(); - } catch (IOException e) { - throw new RuntimeException("Can't compress metafile picture data", e); - } - - setCompressedSize(raw_pictureData.length); - setCompressed(true); - } - - /** - * Sets the filter byte - usually this is 0xFE - * - * @param filter the filter byte - */ - public void setFilter(byte filter) { - field_7_fFilter = filter; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java deleted file mode 100644 index cb6c7ad4c..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ddf; - -import org.apache.poi.util.Internal; - -/** - * The opt record is used to store property values for a shape. It is the key to - * determining the attributes of a shape. Properties can be of two types: simple - * or complex. Simple types are fixed length. Complex properties are variable - * length. - */ -public class EscherOptRecord extends AbstractEscherOptRecord -{ - public static final String RECORD_DESCRIPTION = "msofbtOPT"; - public static final short RECORD_ID = (short) 0xF00B; - - @Override - public short getInstance() - { - setInstance( (short) properties.size() ); - return super.getInstance(); - } - - /** - * Automatically recalculate the correct option - */ - @Override - @Internal - public short getOptions() - { - // update values - getInstance(); - getVersion(); - return super.getOptions(); - } - - @Override - public String getRecordName() - { - return "Opt"; - } - - @Override - public short getVersion() - { - setVersion( (short) 0x3 ); - return super.getVersion(); - } - - @Override - public void setVersion( short value ) - { - if ( value != 0x3 ) - throw new IllegalArgumentException( RECORD_DESCRIPTION - + " can have only '0x3' version" ); - - super.setVersion( value ); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java b/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java deleted file mode 100644 index 7c2acd9a9..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java +++ /dev/null @@ -1,298 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.zip.InflaterInputStream; - -public final class EscherPictBlip extends EscherBlipRecord { - private static final POILogger log = POILogFactory.getLogger(EscherPictBlip.class); - - public static final short RECORD_ID_EMF = (short) 0xF018 + 2; - public static final short RECORD_ID_WMF = (short) 0xF018 + 3; - public static final short RECORD_ID_PICT = (short) 0xF018 + 4; - - private static final int HEADER_SIZE = 8; - - private final byte[] field_1_UID = new byte[16]; - private int field_2_cb; - private int field_3_rcBounds_x1; - private int field_3_rcBounds_y1; - private int field_3_rcBounds_x2; - private int field_3_rcBounds_y2; - private int field_4_ptSize_w; - private int field_4_ptSize_h; - private int field_5_cbSave; - private byte field_6_fCompression; - private byte field_7_fFilter; - - private byte[] raw_pictureData; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesAfterHeader = readHeader(data, offset); - int pos = offset + HEADER_SIZE; - - System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16; - field_2_cb = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_x1 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_y1 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_x2 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_y2 = LittleEndian.getInt( data, pos ); pos += 4; - field_4_ptSize_w = LittleEndian.getInt( data, pos ); pos += 4; - field_4_ptSize_h = LittleEndian.getInt( data, pos ); pos += 4; - field_5_cbSave = LittleEndian.getInt( data, pos ); pos += 4; - field_6_fCompression = data[pos]; pos++; - field_7_fFilter = data[pos]; pos++; - - raw_pictureData = new byte[field_5_cbSave]; - System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave ); - - // 0 means DEFLATE compression - // 0xFE means no compression - if (field_6_fCompression == 0) - { - field_pictureData = inflatePictureData(raw_pictureData); - } - else - { - field_pictureData = raw_pictureData; - } - - return bytesAfterHeader + HEADER_SIZE; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize(offset, getRecordId(), this); - - int pos = offset; - LittleEndian.putShort( data, pos, getOptions() ); pos += 2; - LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; - LittleEndian.putInt( data, 0, getRecordSize() - HEADER_SIZE ); pos += 4; - - System.arraycopy( field_1_UID, 0, data, pos, 16 ); pos += 16; - LittleEndian.putInt( data, pos, field_2_cb ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_x1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_y1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_x2 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_y2 ); pos += 4; - LittleEndian.putInt( data, pos, field_4_ptSize_w ); pos += 4; - LittleEndian.putInt( data, pos, field_4_ptSize_h ); pos += 4; - LittleEndian.putInt( data, pos, field_5_cbSave ); pos += 4; - data[pos] = field_6_fCompression; pos++; - data[pos] = field_7_fFilter; pos++; - - System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length ); - - listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this); - return HEADER_SIZE + 16 + 1 + raw_pictureData.length; - } - - /** - * Decompresses the provided data, returning the inflated result. - * - * @param data the deflated picture data. - * @return the inflated picture data. - */ - private static byte[] inflatePictureData(byte[] data) { - try { - InflaterInputStream in = new InflaterInputStream(new ByteArrayInputStream(data)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buf = new byte[4096]; - int readBytes; - while ((readBytes = in.read(buf)) > 0) { - out.write(buf, 0, readBytes); - } - return out.toByteArray(); - } catch (IOException e) { - log.log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e); - return data; - } - } - - @Override - public int getRecordSize() { - return 8 + 50 + raw_pictureData.length; - } - - /** - * Gets the first MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @return the first MD4 - */ - public byte[] getUID() { - return field_1_UID; - } - - /** - * Sets the first MD4, that specifies the unique identifier of the - * uncompressed blip data - * - * @param uid the first MD4 - */ - public void setUID(byte[] uid) { - if (uid == null || uid.length != 16) { - throw new IllegalArgumentException("uid must be byte[16]"); - } - System.arraycopy(uid, 0, field_1_UID, 0, field_1_UID.length); - } - - /** - * Gets the uncompressed size (in bytes) - * - * @return the uncompressed size - */ - public int getUncompressedSize() { - return field_2_cb; - } - - /** - * Sets the uncompressed size (in bytes) - * - * @param uncompressedSize the uncompressed size - */ - public void setUncompressedSize(int uncompressedSize) { - field_2_cb = uncompressedSize; - } - - /** - * Get the clipping region of the pict file - * - * @return the clipping region - */ - public Rectangle getBounds() { - return new Rectangle(field_3_rcBounds_x1, - field_3_rcBounds_y1, - field_3_rcBounds_x2 - field_3_rcBounds_x1, - field_3_rcBounds_y2 - field_3_rcBounds_y1); - } - - /** - * Sets the clipping region - * - * @param bounds the clipping region - */ - public void setBounds(Rectangle bounds) { - field_3_rcBounds_x1 = bounds.x; - field_3_rcBounds_y1 = bounds.y; - field_3_rcBounds_x2 = bounds.x + bounds.width; - field_3_rcBounds_y2 = bounds.y + bounds.height; - } - - /** - * Gets the dimensions of the metafile - * - * @return the dimensions of the metafile - */ - public Dimension getSizeEMU() { - return new Dimension(field_4_ptSize_w, field_4_ptSize_h); - } - - /** - * Gets the dimensions of the metafile - * - * @param sizeEMU the dimensions of the metafile - */ - public void setSizeEMU(Dimension sizeEMU) { - field_4_ptSize_w = sizeEMU.width; - field_4_ptSize_h = sizeEMU.height; - } - - /** - * Gets the compressed size of the metafile (in bytes) - * - * @return the compressed size - */ - public int getCompressedSize() { - return field_5_cbSave; - } - - /** - * Sets the compressed size of the metafile (in bytes) - * - * @param compressedSize the compressed size - */ - public void setCompressedSize(int compressedSize) { - field_5_cbSave = compressedSize; - } - - /** - * Gets the compression of the metafile - * - * @return true, if the metafile is compressed - */ - public boolean isCompressed() { - return (field_6_fCompression == 0); - } - - /** - * Sets the compression of the metafile - * - * @param compressed the compression state, true if it's compressed - */ - public void setCompressed(boolean compressed) { - field_6_fCompression = compressed ? 0 : (byte)0xFE; - } - - // filtering is always 254 according to available docs, so no point giving it a setter method. - - @Override - public String toString() { - String extraData = HexDump.toHex(field_pictureData, 32); - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' + - " Version: 0x" + HexDump.toHex( getVersion() ) + '\n' + - " Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' + - " UID: 0x" + HexDump.toHex( field_1_UID ) + '\n' + - " Uncompressed Size: " + HexDump.toHex( field_2_cb ) + '\n' + - " Bounds: " + getBounds() + '\n' + - " Size in EMU: " + getSizeEMU() + '\n' + - " Compressed Size: " + HexDump.toHex( field_5_cbSave ) + '\n' + - " Compression: " + HexDump.toHex( field_6_fCompression ) + '\n' + - " Filter: " + HexDump.toHex( field_7_fFilter ) + '\n' + - " Extra Data:" + '\n' + extraData; - } - - @Override - public String toXml(String tab) { - String extraData = ""; - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_1_UID )).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_2_cb )).append("\n") - .append(tab).append("\t").append("").append(getBounds()).append("\n") - .append(tab).append("\t").append("").append(getSizeEMU()).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_5_cbSave )).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_6_fCompression )).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex( field_7_fFilter )).append("\n") - .append(tab).append("\t").append("").append(extraData).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherProperties.java b/trunk/src/java/org/apache/poi/ddf/EscherProperties.java deleted file mode 100644 index 096a20c57..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherProperties.java +++ /dev/null @@ -1,660 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== */ - -package org.apache.poi.ddf; - -import java.util.HashMap; -import java.util.Map; - -/** - * Provides a list of all known escher properties including the description and - * type. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class EscherProperties { - - // Property constants - public static final short TRANSFORM__ROTATION = 4; - public static final short PROTECTION__LOCKROTATION = 119; - public static final short PROTECTION__LOCKASPECTRATIO = 120; - public static final short PROTECTION__LOCKPOSITION = 121; - public static final short PROTECTION__LOCKAGAINSTSELECT = 122; - public static final short PROTECTION__LOCKCROPPING = 123; - public static final short PROTECTION__LOCKVERTICES = 124; - public static final short PROTECTION__LOCKTEXT = 125; - public static final short PROTECTION__LOCKADJUSTHANDLES = 126; - public static final short PROTECTION__LOCKAGAINSTGROUPING = 127; - public static final short TEXT__TEXTID = 128; - public static final short TEXT__TEXTLEFT = 129; - public static final short TEXT__TEXTTOP = 130; - public static final short TEXT__TEXTRIGHT = 131; - public static final short TEXT__TEXTBOTTOM = 132; - public static final short TEXT__WRAPTEXT = 133; - public static final short TEXT__SCALETEXT = 134; - public static final short TEXT__ANCHORTEXT = 135; - public static final short TEXT__TEXTFLOW = 136; - public static final short TEXT__FONTROTATION = 137; - public static final short TEXT__IDOFNEXTSHAPE = 138; - public static final short TEXT__BIDIR = 139; - public static final short TEXT__SINGLECLICKSELECTS = 187; - public static final short TEXT__USEHOSTMARGINS = 188; - public static final short TEXT__ROTATETEXTWITHSHAPE = 189; - public static final short TEXT__SIZESHAPETOFITTEXT = 190; - public static final short TEXT__SIZE_TEXT_TO_FIT_SHAPE = 191; - public static final short GEOTEXT__UNICODE = 192; - public static final short GEOTEXT__RTFTEXT = 193; - public static final short GEOTEXT__ALIGNMENTONCURVE = 194; - public static final short GEOTEXT__DEFAULTPOINTSIZE = 195; - public static final short GEOTEXT__TEXTSPACING = 196; - public static final short GEOTEXT__FONTFAMILYNAME = 197; - public static final short GEOTEXT__REVERSEROWORDER = 240; - public static final short GEOTEXT__HASTEXTEFFECT = 241; - public static final short GEOTEXT__ROTATECHARACTERS = 242; - public static final short GEOTEXT__KERNCHARACTERS = 243; - public static final short GEOTEXT__TIGHTORTRACK = 244; - public static final short GEOTEXT__STRETCHTOFITSHAPE = 245; - public static final short GEOTEXT__CHARBOUNDINGBOX = 246; - public static final short GEOTEXT__SCALETEXTONPATH = 247; - public static final short GEOTEXT__STRETCHCHARHEIGHT = 248; - public static final short GEOTEXT__NOMEASUREALONGPATH = 249; - public static final short GEOTEXT__BOLDFONT = 250; - public static final short GEOTEXT__ITALICFONT = 251; - public static final short GEOTEXT__UNDERLINEFONT = 252; - public static final short GEOTEXT__SHADOWFONT = 253; - public static final short GEOTEXT__SMALLCAPSFONT = 254; - public static final short GEOTEXT__STRIKETHROUGHFONT = 255; - public static final short BLIP__CROPFROMTOP = 256; - public static final short BLIP__CROPFROMBOTTOM = 257; - public static final short BLIP__CROPFROMLEFT = 258; - public static final short BLIP__CROPFROMRIGHT = 259; - public static final short BLIP__BLIPTODISPLAY = 260; - public static final short BLIP__BLIPFILENAME = 261; - public static final short BLIP__BLIPFLAGS = 262; - public static final short BLIP__TRANSPARENTCOLOR = 263; - public static final short BLIP__CONTRASTSETTING = 264; - public static final short BLIP__BRIGHTNESSSETTING = 265; - public static final short BLIP__GAMMA = 266; - public static final short BLIP__PICTUREID = 267; - public static final short BLIP__DOUBLEMOD = 268; - public static final short BLIP__PICTUREFILLMOD = 269; - public static final short BLIP__PICTURELINE = 270; - public static final short BLIP__PRINTBLIP = 271; - public static final short BLIP__PRINTBLIPFILENAME = 272; - public static final short BLIP__PRINTFLAGS = 273; - public static final short BLIP__NOHITTESTPICTURE = 316; - public static final short BLIP__PICTUREGRAY = 317; - public static final short BLIP__PICTUREBILEVEL = 318; - public static final short BLIP__PICTUREACTIVE = 319; - public static final short GEOMETRY__LEFT = 320; - public static final short GEOMETRY__TOP = 321; - public static final short GEOMETRY__RIGHT = 322; - public static final short GEOMETRY__BOTTOM = 323; - public static final short GEOMETRY__SHAPEPATH = 324; - public static final short GEOMETRY__VERTICES = 325; - public static final short GEOMETRY__SEGMENTINFO = 326; - public static final short GEOMETRY__ADJUSTVALUE = 327; - public static final short GEOMETRY__ADJUST2VALUE = 328; - public static final short GEOMETRY__ADJUST3VALUE = 329; - public static final short GEOMETRY__ADJUST4VALUE = 330; - public static final short GEOMETRY__ADJUST5VALUE = 331; - public static final short GEOMETRY__ADJUST6VALUE = 332; - public static final short GEOMETRY__ADJUST7VALUE = 333; - public static final short GEOMETRY__ADJUST8VALUE = 334; - public static final short GEOMETRY__ADJUST9VALUE = 335; - public static final short GEOMETRY__ADJUST10VALUE = 336; - public static final short GEOMETRY__SHADOWok = 378; - public static final short GEOMETRY__3DOK = 379; - public static final short GEOMETRY__LINEOK = 380; - public static final short GEOMETRY__GEOTEXTOK = 381; - public static final short GEOMETRY__FILLSHADESHAPEOK = 382; - public static final short GEOMETRY__FILLOK = 383; - public static final short FILL__FILLTYPE = 384; - public static final short FILL__FILLCOLOR = 385; - public static final short FILL__FILLOPACITY = 386; - public static final short FILL__FILLBACKCOLOR = 387; - public static final short FILL__BACKOPACITY = 388; - public static final short FILL__CRMOD = 389; - public static final short FILL__PATTERNTEXTURE = 390; - public static final short FILL__BLIPFILENAME = 391; - public static final short FILL__BLIPFLAGS = 392; - public static final short FILL__WIDTH = 393; - public static final short FILL__HEIGHT = 394; - public static final short FILL__ANGLE = 395; - public static final short FILL__FOCUS = 396; - public static final short FILL__TOLEFT = 397; - public static final short FILL__TOTOP = 398; - public static final short FILL__TORIGHT = 399; - public static final short FILL__TOBOTTOM = 400; - public static final short FILL__RECTLEFT = 401; - public static final short FILL__RECTTOP = 402; - public static final short FILL__RECTRIGHT = 403; - public static final short FILL__RECTBOTTOM = 404; - public static final short FILL__DZTYPE = 405; - public static final short FILL__SHADEPRESET = 406; - public static final short FILL__SHADECOLORS = 407; - public static final short FILL__ORIGINX = 408; - public static final short FILL__ORIGINY = 409; - public static final short FILL__SHAPEORIGINX = 410; - public static final short FILL__SHAPEORIGINY = 411; - public static final short FILL__SHADETYPE = 412; - public static final short FILL__FILLED = 443; - public static final short FILL__HITTESTFILL = 444; - public static final short FILL__SHAPE = 445; - public static final short FILL__USERECT = 446; - public static final short FILL__NOFILLHITTEST = 447; - public static final short LINESTYLE__COLOR = 448; - public static final short LINESTYLE__OPACITY = 449; - public static final short LINESTYLE__BACKCOLOR = 450; - public static final short LINESTYLE__CRMOD = 451; - public static final short LINESTYLE__LINETYPE = 452; - public static final short LINESTYLE__FILLBLIP = 453; - public static final short LINESTYLE__FILLBLIPNAME = 454; - public static final short LINESTYLE__FILLBLIPFLAGS = 455; - public static final short LINESTYLE__FILLWIDTH = 456; - public static final short LINESTYLE__FILLHEIGHT = 457; - public static final short LINESTYLE__FILLDZTYPE = 458; - public static final short LINESTYLE__LINEWIDTH = 459; - public static final short LINESTYLE__LINEMITERLIMIT = 460; - public static final short LINESTYLE__LINESTYLE = 461; - public static final short LINESTYLE__LINEDASHING = 462; - public static final short LINESTYLE__LINEDASHSTYLE = 463; - public static final short LINESTYLE__LINESTARTARROWHEAD = 464; - public static final short LINESTYLE__LINEENDARROWHEAD = 465; - public static final short LINESTYLE__LINESTARTARROWWIDTH = 466; - public static final short LINESTYLE__LINESTARTARROWLENGTH = 467; - public static final short LINESTYLE__LINEENDARROWWIDTH = 468; - public static final short LINESTYLE__LINEENDARROWLENGTH = 469; - public static final short LINESTYLE__LINEJOINSTYLE = 470; - public static final short LINESTYLE__LINEENDCAPSTYLE = 471; - public static final short LINESTYLE__ARROWHEADSOK = 507; - public static final short LINESTYLE__ANYLINE = 508; - public static final short LINESTYLE__HITLINETEST = 509; - public static final short LINESTYLE__LINEFILLSHAPE = 510; - public static final short LINESTYLE__NOLINEDRAWDASH = 511; - public static final short LINESTYLE__NOLINEDRAWDASH_LEFT = 0x057F; - public static final short LINESTYLE__NOLINEDRAWDASH_TOP = 0x05BF; - public static final short LINESTYLE__NOLINEDRAWDASH_BOTTOM = 0x063F; - public static final short LINESTYLE__NOLINEDRAWDASH_RIGHT = 0x05FF; - public static final short SHADOWSTYLE__TYPE = 512; - public static final short SHADOWSTYLE__COLOR = 513; - public static final short SHADOWSTYLE__HIGHLIGHT = 514; - public static final short SHADOWSTYLE__CRMOD = 515; - public static final short SHADOWSTYLE__OPACITY = 516; - public static final short SHADOWSTYLE__OFFSETX = 517; - public static final short SHADOWSTYLE__OFFSETY = 518; - public static final short SHADOWSTYLE__SECONDOFFSETX = 519; - public static final short SHADOWSTYLE__SECONDOFFSETY = 520; - public static final short SHADOWSTYLE__SCALEXTOX = 521; - public static final short SHADOWSTYLE__SCALEYTOX = 522; - public static final short SHADOWSTYLE__SCALEXTOY = 523; - public static final short SHADOWSTYLE__SCALEYTOY = 524; - public static final short SHADOWSTYLE__PERSPECTIVEX = 525; - public static final short SHADOWSTYLE__PERSPECTIVEY = 526; - public static final short SHADOWSTYLE__WEIGHT = 527; - public static final short SHADOWSTYLE__ORIGINX = 528; - public static final short SHADOWSTYLE__ORIGINY = 529; - public static final short SHADOWSTYLE__SHADOW = 574; - public static final short SHADOWSTYLE__SHADOWOBSURED = 575; - public static final short PERSPECTIVE__TYPE = 576; - public static final short PERSPECTIVE__OFFSETX = 577; - public static final short PERSPECTIVE__OFFSETY = 578; - public static final short PERSPECTIVE__SCALEXTOX = 579; - public static final short PERSPECTIVE__SCALEYTOX = 580; - public static final short PERSPECTIVE__SCALEXTOY = 581; - public static final short PERSPECTIVE__SCALEYTOY = 582; - public static final short PERSPECTIVE__PERSPECTIVEX = 583; - public static final short PERSPECTIVE__PERSPECTIVEY = 584; - public static final short PERSPECTIVE__WEIGHT = 585; - public static final short PERSPECTIVE__ORIGINX = 586; - public static final short PERSPECTIVE__ORIGINY = 587; - public static final short PERSPECTIVE__PERSPECTIVEON = 639; - public static final short THREED__SPECULARAMOUNT = 640; - public static final short THREED__DIFFUSEAMOUNT = 661; - public static final short THREED__SHININESS = 662; - public static final short THREED__EDGETHICKNESS = 663; - public static final short THREED__EXTRUDEFORWARD = 664; - public static final short THREED__EXTRUDEBACKWARD = 665; - public static final short THREED__EXTRUDEPLANE = 666; - public static final short THREED__EXTRUSIONCOLOR = 667; - public static final short THREED__CRMOD = 648; - public static final short THREED__3DEFFECT = 700; - public static final short THREED__METALLIC = 701; - public static final short THREED__USEEXTRUSIONCOLOR = 702; - public static final short THREED__LIGHTFACE = 703; - public static final short THREEDSTYLE__YROTATIONANGLE = 704; - public static final short THREEDSTYLE__XROTATIONANGLE = 705; - public static final short THREEDSTYLE__ROTATIONAXISX = 706; - public static final short THREEDSTYLE__ROTATIONAXISY = 707; - public static final short THREEDSTYLE__ROTATIONAXISZ = 708; - public static final short THREEDSTYLE__ROTATIONANGLE = 709; - public static final short THREEDSTYLE__ROTATIONCENTERX = 710; - public static final short THREEDSTYLE__ROTATIONCENTERY = 711; - public static final short THREEDSTYLE__ROTATIONCENTERZ = 712; - public static final short THREEDSTYLE__RENDERMODE = 713; - public static final short THREEDSTYLE__TOLERANCE = 714; - public static final short THREEDSTYLE__XVIEWPOINT = 715; - public static final short THREEDSTYLE__YVIEWPOINT = 716; - public static final short THREEDSTYLE__ZVIEWPOINT = 717; - public static final short THREEDSTYLE__ORIGINX = 718; - public static final short THREEDSTYLE__ORIGINY = 719; - public static final short THREEDSTYLE__SKEWANGLE = 720; - public static final short THREEDSTYLE__SKEWAMOUNT = 721; - public static final short THREEDSTYLE__AMBIENTINTENSITY = 722; - public static final short THREEDSTYLE__KEYX = 723; - public static final short THREEDSTYLE__KEYY = 724; - public static final short THREEDSTYLE__KEYZ = 725; - public static final short THREEDSTYLE__KEYINTENSITY = 726; - public static final short THREEDSTYLE__FILLX = 727; - public static final short THREEDSTYLE__FILLY = 728; - public static final short THREEDSTYLE__FILLZ = 729; - public static final short THREEDSTYLE__FILLINTENSITY = 730; - public static final short THREEDSTYLE__CONSTRAINROTATION = 763; - public static final short THREEDSTYLE__ROTATIONCENTERAUTO = 764; - public static final short THREEDSTYLE__PARALLEL = 765; - public static final short THREEDSTYLE__KEYHARSH = 766; - public static final short THREEDSTYLE__FILLHARSH = 767; - public static final short SHAPE__MASTER = 769; - public static final short SHAPE__CONNECTORSTYLE = 771; - public static final short SHAPE__BLACKANDWHITESETTINGS = 772; - public static final short SHAPE__WMODEPUREBW = 773; - public static final short SHAPE__WMODEBW = 774; - public static final short SHAPE__OLEICON = 826; - public static final short SHAPE__PREFERRELATIVERESIZE = 827; - public static final short SHAPE__LOCKSHAPETYPE = 828; - public static final short SHAPE__DELETEATTACHEDOBJECT = 830; - public static final short SHAPE__BACKGROUNDSHAPE = 831; - public static final short CALLOUT__CALLOUTTYPE = 832; - public static final short CALLOUT__XYCALLOUTGAP = 833; - public static final short CALLOUT__CALLOUTANGLE = 834; - public static final short CALLOUT__CALLOUTDROPTYPE = 835; - public static final short CALLOUT__CALLOUTDROPSPECIFIED = 836; - public static final short CALLOUT__CALLOUTLENGTHSPECIFIED = 837; - public static final short CALLOUT__ISCALLOUT = 889; - public static final short CALLOUT__CALLOUTACCENTBAR = 890; - public static final short CALLOUT__CALLOUTTEXTBORDER = 891; - public static final short CALLOUT__CALLOUTMINUSX = 892; - public static final short CALLOUT__CALLOUTMINUSY = 893; - public static final short CALLOUT__DROPAUTO = 894; - public static final short CALLOUT__LENGTHSPECIFIED = 895; - public static final short GROUPSHAPE__SHAPENAME = 0x0380; - public static final short GROUPSHAPE__DESCRIPTION = 0x0381; - public static final short GROUPSHAPE__HYPERLINK = 0x0382; - public static final short GROUPSHAPE__WRAPPOLYGONVERTICES = 0x0383; - public static final short GROUPSHAPE__WRAPDISTLEFT = 0x0384; - public static final short GROUPSHAPE__WRAPDISTTOP = 0x0385; - public static final short GROUPSHAPE__WRAPDISTRIGHT = 0x0386; - public static final short GROUPSHAPE__WRAPDISTBOTTOM = 0x0387; - public static final short GROUPSHAPE__REGROUPID = 0x0388; - public static final short GROUPSHAPE__UNUSED906 = 0x038A; - public static final short GROUPSHAPE__TOOLTIP = 0x038D; - public static final short GROUPSHAPE__SCRIPT = 0x038E; - public static final short GROUPSHAPE__POSH = 0x038F; - public static final short GROUPSHAPE__POSRELH = 0x0390; - public static final short GROUPSHAPE__POSV = 0x0391; - public static final short GROUPSHAPE__POSRELV = 0x0392; - public static final short GROUPSHAPE__HR_PCT = 0x0393; - public static final short GROUPSHAPE__HR_ALIGN = 0x0394; - public static final short GROUPSHAPE__HR_HEIGHT = 0x0395; - public static final short GROUPSHAPE__HR_WIDTH = 0x0396; - public static final short GROUPSHAPE__SCRIPTEXT = 0x0397; - public static final short GROUPSHAPE__SCRIPTLANG = 0x0398; - public static final short GROUPSHAPE__BORDERTOPCOLOR = 0x039B; - public static final short GROUPSHAPE__BORDERLEFTCOLOR = 0x039C; - public static final short GROUPSHAPE__BORDERBOTTOMCOLOR = 0x039D; - public static final short GROUPSHAPE__BORDERRIGHTCOLOR = 0x039E; - public static final short GROUPSHAPE__TABLEPROPERTIES = 0x039F; - public static final short GROUPSHAPE__TABLEROWPROPERTIES = 0x03A0; - public static final short GROUPSHAPE__WEBBOT = 0x03A5; - public static final short GROUPSHAPE__METROBLOB = 0x03A9; - public static final short GROUPSHAPE__ZORDER = 0x03AA; - public static final short GROUPSHAPE__FLAGS = 0x03BF; - public static final short GROUPSHAPE__EDITEDWRAP = 953; - public static final short GROUPSHAPE__BEHINDDOCUMENT = 954; - public static final short GROUPSHAPE__ONDBLCLICKNOTIFY = 955; - public static final short GROUPSHAPE__ISBUTTON = 956; - public static final short GROUPSHAPE__1DADJUSTMENT = 957; - public static final short GROUPSHAPE__HIDDEN = 958; - public static final short GROUPSHAPE__PRINT = 959; - - private static final Map properties = initProps(); - - private static Map initProps() { - Map m = new HashMap(); - addProp(m, TRANSFORM__ROTATION, "transform.rotation"); - addProp(m, PROTECTION__LOCKROTATION, "protection.lockrotation"); - addProp(m, PROTECTION__LOCKASPECTRATIO, "protection.lockaspectratio"); - addProp(m, PROTECTION__LOCKPOSITION, "protection.lockposition"); - addProp(m, PROTECTION__LOCKAGAINSTSELECT, "protection.lockagainstselect"); - addProp(m, PROTECTION__LOCKCROPPING, "protection.lockcropping"); - addProp(m, PROTECTION__LOCKVERTICES, "protection.lockvertices"); - addProp(m, PROTECTION__LOCKTEXT, "protection.locktext"); - addProp(m, PROTECTION__LOCKADJUSTHANDLES, "protection.lockadjusthandles"); - addProp(m, PROTECTION__LOCKAGAINSTGROUPING, "protection.lockagainstgrouping", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, TEXT__TEXTID, "text.textid"); - addProp(m, TEXT__TEXTLEFT, "text.textleft"); - addProp(m, TEXT__TEXTTOP, "text.texttop"); - addProp(m, TEXT__TEXTRIGHT, "text.textright"); - addProp(m, TEXT__TEXTBOTTOM, "text.textbottom"); - addProp(m, TEXT__WRAPTEXT, "text.wraptext"); - addProp(m, TEXT__SCALETEXT, "text.scaletext"); - addProp(m, TEXT__ANCHORTEXT, "text.anchortext"); - addProp(m, TEXT__TEXTFLOW, "text.textflow"); - addProp(m, TEXT__FONTROTATION, "text.fontrotation"); - addProp(m, TEXT__IDOFNEXTSHAPE, "text.idofnextshape"); - addProp(m, TEXT__BIDIR, "text.bidir"); - addProp(m, TEXT__SINGLECLICKSELECTS, "text.singleclickselects"); - addProp(m, TEXT__USEHOSTMARGINS, "text.usehostmargins"); - addProp(m, TEXT__ROTATETEXTWITHSHAPE, "text.rotatetextwithshape"); - addProp(m, TEXT__SIZESHAPETOFITTEXT, "text.sizeshapetofittext"); - addProp(m, TEXT__SIZE_TEXT_TO_FIT_SHAPE, "text.sizetexttofitshape", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, GEOTEXT__UNICODE, "geotext.unicode"); - addProp(m, GEOTEXT__RTFTEXT, "geotext.rtftext"); - addProp(m, GEOTEXT__ALIGNMENTONCURVE, "geotext.alignmentoncurve"); - addProp(m, GEOTEXT__DEFAULTPOINTSIZE, "geotext.defaultpointsize"); - addProp(m, GEOTEXT__TEXTSPACING, "geotext.textspacing"); - addProp(m, GEOTEXT__FONTFAMILYNAME, "geotext.fontfamilyname"); - addProp(m, GEOTEXT__REVERSEROWORDER, "geotext.reverseroworder"); - addProp(m, GEOTEXT__HASTEXTEFFECT, "geotext.hastexteffect"); - addProp(m, GEOTEXT__ROTATECHARACTERS, "geotext.rotatecharacters"); - addProp(m, GEOTEXT__KERNCHARACTERS, "geotext.kerncharacters"); - addProp(m, GEOTEXT__TIGHTORTRACK, "geotext.tightortrack"); - addProp(m, GEOTEXT__STRETCHTOFITSHAPE, "geotext.stretchtofitshape"); - addProp(m, GEOTEXT__CHARBOUNDINGBOX, "geotext.charboundingbox"); - addProp(m, GEOTEXT__SCALETEXTONPATH, "geotext.scaletextonpath"); - addProp(m, GEOTEXT__STRETCHCHARHEIGHT, "geotext.stretchcharheight"); - addProp(m, GEOTEXT__NOMEASUREALONGPATH, "geotext.nomeasurealongpath"); - addProp(m, GEOTEXT__BOLDFONT, "geotext.boldfont"); - addProp(m, GEOTEXT__ITALICFONT, "geotext.italicfont"); - addProp(m, GEOTEXT__UNDERLINEFONT, "geotext.underlinefont"); - addProp(m, GEOTEXT__SHADOWFONT, "geotext.shadowfont"); - addProp(m, GEOTEXT__SMALLCAPSFONT, "geotext.smallcapsfont"); - addProp(m, GEOTEXT__STRIKETHROUGHFONT, "geotext.strikethroughfont"); - addProp(m, BLIP__CROPFROMTOP, "blip.cropfromtop"); - addProp(m, BLIP__CROPFROMBOTTOM, "blip.cropfrombottom"); - addProp(m, BLIP__CROPFROMLEFT, "blip.cropfromleft"); - addProp(m, BLIP__CROPFROMRIGHT, "blip.cropfromright"); - addProp(m, BLIP__BLIPTODISPLAY, "blip.bliptodisplay"); - addProp(m, BLIP__BLIPFILENAME, "blip.blipfilename"); - addProp(m, BLIP__BLIPFLAGS, "blip.blipflags"); - addProp(m, BLIP__TRANSPARENTCOLOR, "blip.transparentcolor"); - addProp(m, BLIP__CONTRASTSETTING, "blip.contrastsetting"); - addProp(m, BLIP__BRIGHTNESSSETTING, "blip.brightnesssetting"); - addProp(m, BLIP__GAMMA, "blip.gamma"); - addProp(m, BLIP__PICTUREID, "blip.pictureid"); - addProp(m, BLIP__DOUBLEMOD, "blip.doublemod"); - addProp(m, BLIP__PICTUREFILLMOD, "blip.picturefillmod"); - addProp(m, BLIP__PICTURELINE, "blip.pictureline"); - addProp(m, BLIP__PRINTBLIP, "blip.printblip"); - addProp(m, BLIP__PRINTBLIPFILENAME, "blip.printblipfilename"); - addProp(m, BLIP__PRINTFLAGS, "blip.printflags"); - addProp(m, BLIP__NOHITTESTPICTURE, "blip.nohittestpicture"); - addProp(m, BLIP__PICTUREGRAY, "blip.picturegray"); - addProp(m, BLIP__PICTUREBILEVEL, "blip.picturebilevel"); - addProp(m, BLIP__PICTUREACTIVE, "blip.pictureactive"); - addProp(m, GEOMETRY__LEFT, "geometry.left"); - addProp(m, GEOMETRY__TOP, "geometry.top"); - addProp(m, GEOMETRY__RIGHT, "geometry.right"); - addProp(m, GEOMETRY__BOTTOM, "geometry.bottom"); - addProp(m, GEOMETRY__SHAPEPATH, "geometry.shapepath", EscherPropertyMetaData.TYPE_SHAPEPATH); - addProp(m, GEOMETRY__VERTICES, "geometry.vertices", EscherPropertyMetaData.TYPE_ARRAY); - addProp(m, GEOMETRY__SEGMENTINFO, "geometry.segmentinfo", EscherPropertyMetaData.TYPE_ARRAY); - addProp(m, GEOMETRY__ADJUSTVALUE, "geometry.adjustvalue"); - addProp(m, GEOMETRY__ADJUST2VALUE, "geometry.adjust2value"); - addProp(m, GEOMETRY__ADJUST3VALUE, "geometry.adjust3value"); - addProp(m, GEOMETRY__ADJUST4VALUE, "geometry.adjust4value"); - addProp(m, GEOMETRY__ADJUST5VALUE, "geometry.adjust5value"); - addProp(m, GEOMETRY__ADJUST6VALUE, "geometry.adjust6value"); - addProp(m, GEOMETRY__ADJUST7VALUE, "geometry.adjust7value"); - addProp(m, GEOMETRY__ADJUST8VALUE, "geometry.adjust8value"); - addProp(m, GEOMETRY__ADJUST9VALUE, "geometry.adjust9value"); - addProp(m, GEOMETRY__ADJUST10VALUE, "geometry.adjust10value"); - addProp(m, GEOMETRY__SHADOWok, "geometry.shadowOK"); - addProp(m, GEOMETRY__3DOK, "geometry.3dok"); - addProp(m, GEOMETRY__LINEOK, "geometry.lineok"); - addProp(m, GEOMETRY__GEOTEXTOK, "geometry.geotextok"); - addProp(m, GEOMETRY__FILLSHADESHAPEOK, "geometry.fillshadeshapeok"); - addProp(m, GEOMETRY__FILLOK, "geometry.fillok", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, FILL__FILLTYPE, "fill.filltype"); - addProp(m, FILL__FILLCOLOR, "fill.fillcolor", EscherPropertyMetaData.TYPE_RGB); - addProp(m, FILL__FILLOPACITY, "fill.fillopacity"); - addProp(m, FILL__FILLBACKCOLOR, "fill.fillbackcolor", EscherPropertyMetaData.TYPE_RGB); - addProp(m, FILL__BACKOPACITY, "fill.backopacity"); - addProp(m, FILL__CRMOD, "fill.crmod"); - addProp(m, FILL__PATTERNTEXTURE, "fill.patterntexture"); - addProp(m, FILL__BLIPFILENAME, "fill.blipfilename"); - addProp(m, FILL__BLIPFLAGS, "fill.blipflags"); - addProp(m, FILL__WIDTH, "fill.width"); - addProp(m, FILL__HEIGHT, "fill.height"); - addProp(m, FILL__ANGLE, "fill.angle"); - addProp(m, FILL__FOCUS, "fill.focus"); - addProp(m, FILL__TOLEFT, "fill.toleft"); - addProp(m, FILL__TOTOP, "fill.totop"); - addProp(m, FILL__TORIGHT, "fill.toright"); - addProp(m, FILL__TOBOTTOM, "fill.tobottom"); - addProp(m, FILL__RECTLEFT, "fill.rectleft"); - addProp(m, FILL__RECTTOP, "fill.recttop"); - addProp(m, FILL__RECTRIGHT, "fill.rectright"); - addProp(m, FILL__RECTBOTTOM, "fill.rectbottom"); - addProp(m, FILL__DZTYPE, "fill.dztype"); - addProp(m, FILL__SHADEPRESET, "fill.shadepreset"); - addProp(m, FILL__SHADECOLORS, "fill.shadecolors", EscherPropertyMetaData.TYPE_ARRAY); - addProp(m, FILL__ORIGINX, "fill.originx"); - addProp(m, FILL__ORIGINY, "fill.originy"); - addProp(m, FILL__SHAPEORIGINX, "fill.shapeoriginx"); - addProp(m, FILL__SHAPEORIGINY, "fill.shapeoriginy"); - addProp(m, FILL__SHADETYPE, "fill.shadetype"); - addProp(m, FILL__FILLED, "fill.filled"); - addProp(m, FILL__HITTESTFILL, "fill.hittestfill"); - addProp(m, FILL__SHAPE, "fill.shape"); - addProp(m, FILL__USERECT, "fill.userect"); - addProp(m, FILL__NOFILLHITTEST, "fill.nofillhittest", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, LINESTYLE__COLOR, "linestyle.color", EscherPropertyMetaData.TYPE_RGB); - addProp(m, LINESTYLE__OPACITY, "linestyle.opacity"); - addProp(m, LINESTYLE__BACKCOLOR, "linestyle.backcolor", EscherPropertyMetaData.TYPE_RGB); - addProp(m, LINESTYLE__CRMOD, "linestyle.crmod"); - addProp(m, LINESTYLE__LINETYPE, "linestyle.linetype"); - addProp(m, LINESTYLE__FILLBLIP, "linestyle.fillblip"); - addProp(m, LINESTYLE__FILLBLIPNAME, "linestyle.fillblipname"); - addProp(m, LINESTYLE__FILLBLIPFLAGS, "linestyle.fillblipflags"); - addProp(m, LINESTYLE__FILLWIDTH, "linestyle.fillwidth"); - addProp(m, LINESTYLE__FILLHEIGHT, "linestyle.fillheight"); - addProp(m, LINESTYLE__FILLDZTYPE, "linestyle.filldztype"); - addProp(m, LINESTYLE__LINEWIDTH, "linestyle.linewidth"); - addProp(m, LINESTYLE__LINEMITERLIMIT, "linestyle.linemiterlimit"); - addProp(m, LINESTYLE__LINESTYLE, "linestyle.linestyle"); - addProp(m, LINESTYLE__LINEDASHING, "linestyle.linedashing"); - addProp(m, LINESTYLE__LINEDASHSTYLE, "linestyle.linedashstyle", EscherPropertyMetaData.TYPE_ARRAY); - addProp(m, LINESTYLE__LINESTARTARROWHEAD, "linestyle.linestartarrowhead"); - addProp(m, LINESTYLE__LINEENDARROWHEAD, "linestyle.lineendarrowhead"); - addProp(m, LINESTYLE__LINESTARTARROWWIDTH, "linestyle.linestartarrowwidth"); - addProp(m, LINESTYLE__LINESTARTARROWLENGTH, "linestyle.linestartarrowlength"); - addProp(m, LINESTYLE__LINEENDARROWWIDTH, "linestyle.lineendarrowwidth"); - addProp(m, LINESTYLE__LINEENDARROWLENGTH, "linestyle.lineendarrowlength"); - addProp(m, LINESTYLE__LINEJOINSTYLE, "linestyle.linejoinstyle"); - addProp(m, LINESTYLE__LINEENDCAPSTYLE, "linestyle.lineendcapstyle"); - addProp(m, LINESTYLE__ARROWHEADSOK, "linestyle.arrowheadsok"); - addProp(m, LINESTYLE__ANYLINE, "linestyle.anyline"); - addProp(m, LINESTYLE__HITLINETEST, "linestyle.hitlinetest"); - addProp(m, LINESTYLE__LINEFILLSHAPE, "linestyle.linefillshape"); - addProp(m, LINESTYLE__NOLINEDRAWDASH, "linestyle.nolinedrawdash", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, LINESTYLE__NOLINEDRAWDASH_LEFT, "linestyle.nolinedrawdash.left", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, LINESTYLE__NOLINEDRAWDASH_TOP, "linestyle.nolinedrawdash.top", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, LINESTYLE__NOLINEDRAWDASH_BOTTOM, "linestyle.nolinedrawdash.bottom", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, LINESTYLE__NOLINEDRAWDASH_RIGHT, "linestyle.nolinedrawdash.right", EscherPropertyMetaData.TYPE_BOOLEAN); - addProp(m, SHADOWSTYLE__TYPE, "shadowstyle.type"); - addProp(m, SHADOWSTYLE__COLOR, "shadowstyle.color", EscherPropertyMetaData.TYPE_RGB); - addProp(m, SHADOWSTYLE__HIGHLIGHT, "shadowstyle.highlight"); - addProp(m, SHADOWSTYLE__CRMOD, "shadowstyle.crmod"); - addProp(m, SHADOWSTYLE__OPACITY, "shadowstyle.opacity"); - addProp(m, SHADOWSTYLE__OFFSETX, "shadowstyle.offsetx"); - addProp(m, SHADOWSTYLE__OFFSETY, "shadowstyle.offsety"); - addProp(m, SHADOWSTYLE__SECONDOFFSETX, "shadowstyle.secondoffsetx"); - addProp(m, SHADOWSTYLE__SECONDOFFSETY, "shadowstyle.secondoffsety"); - addProp(m, SHADOWSTYLE__SCALEXTOX, "shadowstyle.scalextox"); - addProp(m, SHADOWSTYLE__SCALEYTOX, "shadowstyle.scaleytox"); - addProp(m, SHADOWSTYLE__SCALEXTOY, "shadowstyle.scalextoy"); - addProp(m, SHADOWSTYLE__SCALEYTOY, "shadowstyle.scaleytoy"); - addProp(m, SHADOWSTYLE__PERSPECTIVEX, "shadowstyle.perspectivex"); - addProp(m, SHADOWSTYLE__PERSPECTIVEY, "shadowstyle.perspectivey"); - addProp(m, SHADOWSTYLE__WEIGHT, "shadowstyle.weight"); - addProp(m, SHADOWSTYLE__ORIGINX, "shadowstyle.originx"); - addProp(m, SHADOWSTYLE__ORIGINY, "shadowstyle.originy"); - addProp(m, SHADOWSTYLE__SHADOW, "shadowstyle.shadow"); - addProp(m, SHADOWSTYLE__SHADOWOBSURED, "shadowstyle.shadowobscured"); - addProp(m, PERSPECTIVE__TYPE, "perspective.type"); - addProp(m, PERSPECTIVE__OFFSETX, "perspective.offsetx"); - addProp(m, PERSPECTIVE__OFFSETY, "perspective.offsety"); - addProp(m, PERSPECTIVE__SCALEXTOX, "perspective.scalextox"); - addProp(m, PERSPECTIVE__SCALEYTOX, "perspective.scaleytox"); - addProp(m, PERSPECTIVE__SCALEXTOY, "perspective.scalextoy"); - addProp(m, PERSPECTIVE__SCALEYTOY, "perspective.scaleytoy"); - addProp(m, PERSPECTIVE__PERSPECTIVEX, "perspective.perspectivex"); - addProp(m, PERSPECTIVE__PERSPECTIVEY, "perspective.perspectivey"); - addProp(m, PERSPECTIVE__WEIGHT, "perspective.weight"); - addProp(m, PERSPECTIVE__ORIGINX, "perspective.originx"); - addProp(m, PERSPECTIVE__ORIGINY, "perspective.originy"); - addProp(m, PERSPECTIVE__PERSPECTIVEON, "perspective.perspectiveon"); - addProp(m, THREED__SPECULARAMOUNT, "3d.specularamount"); - addProp(m, THREED__DIFFUSEAMOUNT, "3d.diffuseamount"); - addProp(m, THREED__SHININESS, "3d.shininess"); - addProp(m, THREED__EDGETHICKNESS, "3d.edgethickness"); - addProp(m, THREED__EXTRUDEFORWARD, "3d.extrudeforward"); - addProp(m, THREED__EXTRUDEBACKWARD, "3d.extrudebackward"); - addProp(m, THREED__EXTRUDEPLANE, "3d.extrudeplane"); - addProp(m, THREED__EXTRUSIONCOLOR, "3d.extrusioncolor", EscherPropertyMetaData.TYPE_RGB); - addProp(m, THREED__CRMOD, "3d.crmod"); - addProp(m, THREED__3DEFFECT, "3d.3deffect"); - addProp(m, THREED__METALLIC, "3d.metallic"); - addProp(m, THREED__USEEXTRUSIONCOLOR, "3d.useextrusioncolor", EscherPropertyMetaData.TYPE_RGB); - addProp(m, THREED__LIGHTFACE, "3d.lightface"); - addProp(m, THREEDSTYLE__YROTATIONANGLE, "3dstyle.yrotationangle"); - addProp(m, THREEDSTYLE__XROTATIONANGLE, "3dstyle.xrotationangle"); - addProp(m, THREEDSTYLE__ROTATIONAXISX, "3dstyle.rotationaxisx"); - addProp(m, THREEDSTYLE__ROTATIONAXISY, "3dstyle.rotationaxisy"); - addProp(m, THREEDSTYLE__ROTATIONAXISZ, "3dstyle.rotationaxisz"); - addProp(m, THREEDSTYLE__ROTATIONANGLE, "3dstyle.rotationangle"); - addProp(m, THREEDSTYLE__ROTATIONCENTERX, "3dstyle.rotationcenterx"); - addProp(m, THREEDSTYLE__ROTATIONCENTERY, "3dstyle.rotationcentery"); - addProp(m, THREEDSTYLE__ROTATIONCENTERZ, "3dstyle.rotationcenterz"); - addProp(m, THREEDSTYLE__RENDERMODE, "3dstyle.rendermode"); - addProp(m, THREEDSTYLE__TOLERANCE, "3dstyle.tolerance"); - addProp(m, THREEDSTYLE__XVIEWPOINT, "3dstyle.xviewpoint"); - addProp(m, THREEDSTYLE__YVIEWPOINT, "3dstyle.yviewpoint"); - addProp(m, THREEDSTYLE__ZVIEWPOINT, "3dstyle.zviewpoint"); - addProp(m, THREEDSTYLE__ORIGINX, "3dstyle.originx"); - addProp(m, THREEDSTYLE__ORIGINY, "3dstyle.originy"); - addProp(m, THREEDSTYLE__SKEWANGLE, "3dstyle.skewangle"); - addProp(m, THREEDSTYLE__SKEWAMOUNT, "3dstyle.skewamount"); - addProp(m, THREEDSTYLE__AMBIENTINTENSITY, "3dstyle.ambientintensity"); - addProp(m, THREEDSTYLE__KEYX, "3dstyle.keyx"); - addProp(m, THREEDSTYLE__KEYY, "3dstyle.keyy"); - addProp(m, THREEDSTYLE__KEYZ, "3dstyle.keyz"); - addProp(m, THREEDSTYLE__KEYINTENSITY, "3dstyle.keyintensity"); - addProp(m, THREEDSTYLE__FILLX, "3dstyle.fillx"); - addProp(m, THREEDSTYLE__FILLY, "3dstyle.filly"); - addProp(m, THREEDSTYLE__FILLZ, "3dstyle.fillz"); - addProp(m, THREEDSTYLE__FILLINTENSITY, "3dstyle.fillintensity"); - addProp(m, THREEDSTYLE__CONSTRAINROTATION, "3dstyle.constrainrotation"); - addProp(m, THREEDSTYLE__ROTATIONCENTERAUTO, "3dstyle.rotationcenterauto"); - addProp(m, THREEDSTYLE__PARALLEL, "3dstyle.parallel"); - addProp(m, THREEDSTYLE__KEYHARSH, "3dstyle.keyharsh"); - addProp(m, THREEDSTYLE__FILLHARSH, "3dstyle.fillharsh"); - addProp(m, SHAPE__MASTER, "shape.master"); - addProp(m, SHAPE__CONNECTORSTYLE, "shape.connectorstyle"); - addProp(m, SHAPE__BLACKANDWHITESETTINGS, "shape.blackandwhitesettings"); - addProp(m, SHAPE__WMODEPUREBW, "shape.wmodepurebw"); - addProp(m, SHAPE__WMODEBW, "shape.wmodebw"); - addProp(m, SHAPE__OLEICON, "shape.oleicon"); - addProp(m, SHAPE__PREFERRELATIVERESIZE, "shape.preferrelativeresize"); - addProp(m, SHAPE__LOCKSHAPETYPE, "shape.lockshapetype"); - addProp(m, SHAPE__DELETEATTACHEDOBJECT, "shape.deleteattachedobject"); - addProp(m, SHAPE__BACKGROUNDSHAPE, "shape.backgroundshape"); - addProp(m, CALLOUT__CALLOUTTYPE, "callout.callouttype"); - addProp(m, CALLOUT__XYCALLOUTGAP, "callout.xycalloutgap"); - addProp(m, CALLOUT__CALLOUTANGLE, "callout.calloutangle"); - addProp(m, CALLOUT__CALLOUTDROPTYPE, "callout.calloutdroptype"); - addProp(m, CALLOUT__CALLOUTDROPSPECIFIED, "callout.calloutdropspecified"); - addProp(m, CALLOUT__CALLOUTLENGTHSPECIFIED, "callout.calloutlengthspecified"); - addProp(m, CALLOUT__ISCALLOUT, "callout.iscallout"); - addProp(m, CALLOUT__CALLOUTACCENTBAR, "callout.calloutaccentbar"); - addProp(m, CALLOUT__CALLOUTTEXTBORDER, "callout.callouttextborder"); - addProp(m, CALLOUT__CALLOUTMINUSX, "callout.calloutminusx"); - addProp(m, CALLOUT__CALLOUTMINUSY, "callout.calloutminusy"); - addProp(m, CALLOUT__DROPAUTO, "callout.dropauto"); - addProp(m, CALLOUT__LENGTHSPECIFIED, "callout.lengthspecified"); - addProp(m, GROUPSHAPE__SHAPENAME, "groupshape.shapename"); - addProp(m, GROUPSHAPE__DESCRIPTION, "groupshape.description"); - addProp(m, GROUPSHAPE__HYPERLINK, "groupshape.hyperlink"); - addProp(m, GROUPSHAPE__WRAPPOLYGONVERTICES, "groupshape.wrappolygonvertices", EscherPropertyMetaData.TYPE_ARRAY); - addProp(m, GROUPSHAPE__WRAPDISTLEFT, "groupshape.wrapdistleft"); - addProp(m, GROUPSHAPE__WRAPDISTTOP, "groupshape.wrapdisttop"); - addProp(m, GROUPSHAPE__WRAPDISTRIGHT, "groupshape.wrapdistright"); - addProp(m, GROUPSHAPE__WRAPDISTBOTTOM, "groupshape.wrapdistbottom"); - addProp(m, GROUPSHAPE__REGROUPID, "groupshape.regroupid"); - addProp( m, GROUPSHAPE__UNUSED906, "unused906" ); // 0x038A; - addProp( m, GROUPSHAPE__TOOLTIP, "groupshape.wzTooltip" ); // 0x038D; - addProp( m, GROUPSHAPE__SCRIPT, "groupshape.wzScript" ); // 0x038E; - addProp( m, GROUPSHAPE__POSH, "groupshape.posh" ); // 0x038F; - addProp( m, GROUPSHAPE__POSRELH, "groupshape.posrelh" ); // 0x0390; - addProp( m, GROUPSHAPE__POSV, "groupshape.posv" ); // 0x0391; - addProp( m, GROUPSHAPE__POSRELV, "groupshape.posrelv" ); // 0x0392; - addProp( m, GROUPSHAPE__HR_PCT, "groupshape.pctHR" ); // 0x0393; - addProp( m, GROUPSHAPE__HR_ALIGN, "groupshape.alignHR" ); // 0x0394; - addProp( m, GROUPSHAPE__HR_HEIGHT, "groupshape.dxHeightHR" ); // 0x0395; - addProp( m, GROUPSHAPE__HR_WIDTH, "groupshape.dxWidthHR" ); // 0x0396; - addProp( m, GROUPSHAPE__SCRIPTEXT, "groupshape.wzScriptExtAttr" ); // 0x0397; - addProp( m, GROUPSHAPE__SCRIPTLANG, "groupshape.scriptLang" ); // 0x0398; - addProp( m, GROUPSHAPE__BORDERTOPCOLOR, "groupshape.borderTopColor" ); // 0x039B; - addProp( m, GROUPSHAPE__BORDERLEFTCOLOR, "groupshape.borderLeftColor" ); // 0x039C; - addProp( m, GROUPSHAPE__BORDERBOTTOMCOLOR, "groupshape.borderBottomColor" ); // 0x039D; - addProp( m, GROUPSHAPE__BORDERRIGHTCOLOR, "groupshape.borderRightColor" ); // 0x039E; - addProp( m, GROUPSHAPE__TABLEPROPERTIES, "groupshape.tableProperties" ); // 0x039F; - addProp( m, GROUPSHAPE__TABLEROWPROPERTIES, "groupshape.tableRowProperties" ); // 0x03A0; - addProp( m, GROUPSHAPE__WEBBOT, "groupshape.wzWebBot" ); // 0x03A5; - addProp( m, GROUPSHAPE__METROBLOB, "groupshape.metroBlob" ); // 0x03A9; - addProp( m, GROUPSHAPE__ZORDER, "groupshape.dhgt" ); // 0x03AA; - addProp( m, GROUPSHAPE__FLAGS, "groupshape.GroupShapeBooleanProperties" ); // 0x03BF; - - addProp(m, GROUPSHAPE__EDITEDWRAP, "groupshape.editedwrap"); - addProp(m, GROUPSHAPE__BEHINDDOCUMENT, "groupshape.behinddocument"); - addProp(m, GROUPSHAPE__ONDBLCLICKNOTIFY, "groupshape.ondblclicknotify"); - addProp(m, GROUPSHAPE__ISBUTTON, "groupshape.isbutton"); - addProp(m, GROUPSHAPE__1DADJUSTMENT, "groupshape.1dadjustment"); - addProp(m, GROUPSHAPE__HIDDEN, "groupshape.hidden"); - addProp(m, GROUPSHAPE__PRINT, "groupshape.print", EscherPropertyMetaData.TYPE_BOOLEAN); - return m; - } - - private static void addProp(Map m, int s, String propName) { - m.put(Short.valueOf((short) s), new EscherPropertyMetaData(propName)); - } - - private static void addProp(Map m, int s, String propName, byte type) { - m.put(Short.valueOf((short) s), new EscherPropertyMetaData(propName, type)); - } - - public static String getPropertyName(short propertyId) { - EscherPropertyMetaData o = properties.get(Short.valueOf(propertyId)); - return o == null ? "unknown" : o.getDescription(); - } - - public static byte getPropertyType(short propertyId) { - EscherPropertyMetaData escherPropertyMetaData = properties.get(Short.valueOf(propertyId)); - return escherPropertyMetaData == null ? 0 : escherPropertyMetaData.getType(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherProperty.java deleted file mode 100644 index d883fe0d0..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherProperty.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -/** - * This is the abstract base class for all escher properties. - * - * @see EscherOptRecord - */ -public abstract class EscherProperty { - private short _id; - - /** - * The id is distinct from the actual property number. The id includes the property number the blip id - * flag and an indicator whether the property is complex or not. - * - * @param id the combined id - */ - public EscherProperty(short id) { - _id = id; - } - - /** - * Constructs a new escher property. The three parameters are combined to form a property - * id. - * - * @param propertyNumber the property number - * @param isComplex true, if this is a complex property - * @param isBlipId true, if this property is a blip id - */ - public EscherProperty(short propertyNumber, boolean isComplex, boolean isBlipId) { - _id = (short)(propertyNumber + - (isComplex ? 0x8000 : 0x0) + - (isBlipId ? 0x4000 : 0x0)); - } - - public short getId() { - return _id; - } - - public short getPropertyNumber() { - return (short) (_id & (short) 0x3FFF); - } - - public boolean isComplex() { - return (_id & (short) 0x8000) != 0; - } - - public boolean isBlipId() { - return (_id & (short) 0x4000) != 0; - } - - public String getName() { - return EscherProperties.getPropertyName(getPropertyNumber()); - } - - /** - * Most properties are just 6 bytes in length. Override this if we're - * dealing with complex properties. - * - * @return size of this property (in bytes) - */ - public int getPropertySize() { - return 6; - } - - public String toXml(String tab){ - StringBuilder builder = new StringBuilder(); - builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"").append(getId()).append("\" name=\"").append(getName()).append("\" blipId=\"") - .append(isBlipId()).append("\"/>\n"); - return builder.toString(); - } - - /** - * Escher properties consist of a simple fixed length part and a complex variable length part. - * The fixed length part is serialized first. - * - * @param data the buffer to write to - * @param pos the starting position - * - * @return the length of the part - */ - abstract public int serializeSimplePart( byte[] data, int pos ); - - /** - * Escher properties consist of a simple fixed length part and a complex variable length part. - * The fixed length part is serialized first. - * - * @param data the buffer to write to - * @param pos the starting position - * - * @return the length of the part - */ - abstract public int serializeComplexPart( byte[] data, int pos ); -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherPropertyFactory.java b/trunk/src/java/org/apache/poi/ddf/EscherPropertyFactory.java deleted file mode 100644 index 059e29ba9..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherPropertyFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.LittleEndian; - -/** - * Generates a property given a reference into the byte array storing that property. - */ -public final class EscherPropertyFactory { - /** - * Create new properties from a byte array. - * - * @param data The byte array containing the property - * @param offset The starting offset into the byte array - * @param numProperties The number of properties to be read - * @return The new properties - */ - public List createProperties(byte[] data, int offset, short numProperties) { - List results = new ArrayList(); - - int pos = offset; - - for (int i = 0; i < numProperties; i++) { - short propId; - int propData; - propId = LittleEndian.getShort( data, pos ); - propData = LittleEndian.getInt( data, pos + 2 ); - short propNumber = (short) ( propId & (short) 0x3FFF ); - boolean isComplex = ( propId & (short) 0x8000 ) != 0; - // boolean isBlipId = ( propId & (short) 0x4000 ) != 0; - - byte propertyType = EscherProperties.getPropertyType(propNumber); - if ( propertyType == EscherPropertyMetaData.TYPE_BOOLEAN ) - results.add( new EscherBoolProperty( propId, propData ) ); - else if ( propertyType == EscherPropertyMetaData.TYPE_RGB ) - results.add( new EscherRGBProperty( propId, propData ) ); - else if ( propertyType == EscherPropertyMetaData.TYPE_SHAPEPATH ) - results.add( new EscherShapePathProperty( propId, propData ) ); - else - { - if ( !isComplex ) - results.add( new EscherSimpleProperty( propId, propData ) ); - else - { - if ( propertyType == EscherPropertyMetaData.TYPE_ARRAY) - results.add( new EscherArrayProperty( propId, new byte[propData]) ); - else - results.add( new EscherComplexProperty( propId, new byte[propData]) ); - } - } - pos += 6; - } - - // Get complex data - for (EscherProperty p : results) { - if (p instanceof EscherComplexProperty) { - if (p instanceof EscherArrayProperty) { - pos += ((EscherArrayProperty)p).setArrayData(data, pos); - } else { - byte[] complexData = ((EscherComplexProperty)p).getComplexData(); - - int leftover = data.length - pos; - if (leftover < complexData.length) { - throw new IllegalStateException("Could not read complex escher property, lenght was " + complexData.length + ", but had only " + - leftover + " bytes left"); - } - - System.arraycopy(data, pos, complexData, 0, complexData.length); - pos += complexData.length; - } - } - } - return results; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherPropertyMetaData.java b/trunk/src/java/org/apache/poi/ddf/EscherPropertyMetaData.java deleted file mode 100644 index b38e52df3..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherPropertyMetaData.java +++ /dev/null @@ -1,69 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -/** - * This class stores the type and description of an escher property. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class EscherPropertyMetaData -{ - // Escher property types. - public final static byte TYPE_UNKNOWN = (byte) 0; - public final static byte TYPE_BOOLEAN = (byte) 1; - public final static byte TYPE_RGB = (byte) 2; - public final static byte TYPE_SHAPEPATH = (byte) 3; - public final static byte TYPE_SIMPLE = (byte)4; - public final static byte TYPE_ARRAY = (byte)5; - - private String description; - private byte type; - - - /** - * @param description The description of the escher property. - */ - public EscherPropertyMetaData( String description ) - { - this.description = description; - } - - /** - * - * @param description The description of the escher property. - * @param type The type of the property. - */ - public EscherPropertyMetaData( String description, byte type ) - { - this.description = description; - this.type = type; - } - - public String getDescription() - { - return description; - } - - public byte getType() - { - return type; - } - -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java deleted file mode 100644 index 155db7f4f..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; - -/** - * A color property. - */ -public class EscherRGBProperty - extends EscherSimpleProperty -{ - - public EscherRGBProperty( short propertyNumber, int rgbColor ) - { - super( propertyNumber, rgbColor ); - } - - /** - * @return the rgb color as int value - */ - public int getRgbColor() - { - return propertyValue; - } - - /** - * @return the red part - */ - public byte getRed() - { - return (byte) ( propertyValue & 0xFF ); - } - - /** - * @return the green part - */ - public byte getGreen() - { - return (byte) ( (propertyValue >> 8) & 0xFF ); - } - - /** - * @return the blue part - */ - public byte getBlue() - { - return (byte) ( (propertyValue >> 16) & 0xFF ); - } - - @Override - public String toXml(String tab){ - StringBuilder builder = new StringBuilder(); - builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId())) - .append("\" name=\"").append(getName()).append("\" blipId=\"") - .append(isBlipId()).append("\" value=\"0x").append(HexDump.toHex(propertyValue)).append("\"/>\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherRecord.java deleted file mode 100644 index 65926a8c1..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherRecord.java +++ /dev/null @@ -1,328 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.io.PrintWriter; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -/** - * The base abstract record from which all escher records are defined. Subclasses will need - * to define methods for serialization/deserialization and for determining the record size. - */ -public abstract class EscherRecord implements Cloneable { - private static final BitField fInstance = BitFieldFactory.getInstance(0xfff0); - private static final BitField fVersion = BitFieldFactory.getInstance(0x000f); - - private short _options; - private short _recordId; - - /** - * Create a new instance - */ - public EscherRecord() { - // fields uninitialised - } - - /** - * Delegates to fillFields(byte[], int, EscherRecordFactory) - * - * @param data they bytes to serialize from - * @param f the escher record factory - * @return The number of bytes written. - * - * @see #fillFields(byte[], int, org.apache.poi.ddf.EscherRecordFactory) - */ - protected int fillFields( byte[] data, EscherRecordFactory f ) - { - return fillFields( data, 0, f ); - } - - /** - * The contract of this method is to deserialize an escher record including - * it's children. - * - * @param data The byte array containing the serialized escher - * records. - * @param offset The offset into the byte array. - * @param recordFactory A factory for creating new escher records. - * @return The number of bytes written. - */ - public abstract int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ); - - /** - * Reads the 8 byte header information and populates the options - * and recordId records. - * - * @param data the byte array to read from - * @param offset the offset to start reading from - * @return the number of bytes remaining in this record. This - * may include the children if this is a container. - */ - protected int readHeader( byte[] data, int offset ) { - _options = LittleEndian.getShort( data, offset ); - _recordId = LittleEndian.getShort( data, offset + 2 ); - return LittleEndian.getInt( data, offset + 4 ); - } - - /** - * Read the options field from header and return instance part of it. - * @param data the byte array to read from - * @param offset the offset to start reading from - * @return value of instance part of options field - */ - protected static short readInstance( byte data[], int offset ) { - final short options = LittleEndian.getShort( data, offset ); - return fInstance.getShortValue( options ); - } - - /** - * Determine whether this is a container record by inspecting the option field. - * - * @return true is this is a container field. - */ - public boolean isContainerRecord() { - return getVersion() == (short)0x000f; - } - - /** - * Note that options is an internal field. - * Use {@link #setInstance(short)} ()} and {@link #setVersion(short)} ()} to set the actual fields. - * - * @return The options field for this record. All records have one. - */ - @Internal - public short getOptions() - { - return _options; - } - - /** - * Set the options this this record. Container records should have the - * last nibble set to 0xF.

    - * - * Note that {@code options} is an internal field. - * Use {@link #getInstance()} and {@link #getVersion()} to access actual fields. - * - * @param options the record options - */ - @Internal - public void setOptions( short options ) { - // call to handle correct/incorrect values - setVersion( fVersion.getShortValue( options ) ); - setInstance( fInstance.getShortValue( options ) ); - _options = options; - } - - /** - * Serializes to a new byte array. This is done by delegating to - * serialize(int, byte[]); - * - * @return the serialized record. - * @see #serialize(int, byte[]) - */ - public byte[] serialize() - { - byte[] retval = new byte[getRecordSize()]; - - serialize( 0, retval ); - return retval; - } - - /** - * Serializes to an existing byte array without serialization listener. - * This is done by delegating to serialize(int, byte[], EscherSerializationListener). - * - * @param offset the offset within the data byte array. - * @param data the data array to serialize to. - * @return The number of bytes written. - * - * @see #serialize(int, byte[], org.apache.poi.ddf.EscherSerializationListener) - */ - public int serialize( int offset, byte[] data) - { - return serialize( offset, data, new NullEscherSerializationListener() ); - } - - /** - * Serializes the record to an existing byte array. - * - * @param offset the offset within the byte array - * @param data the data array to serialize to - * @param listener a listener for begin and end serialization events. This - * is useful because the serialization is - * hierarchical/recursive and sometimes you need to be able - * break into that. - * @return the number of bytes written. - */ - public abstract int serialize( int offset, byte[] data, EscherSerializationListener listener ); - - /** - * Subclasses should effeciently return the number of bytes required to - * serialize the record. - * - * @return number of bytes - */ - abstract public int getRecordSize(); - - /** - * Return the current record id. - * - * @return The 16 bit record id. - */ - public short getRecordId() { - return _recordId; - } - - /** - * Sets the record id for this record. - * - * @param recordId the record id - */ - public void setRecordId( short recordId ) { - _recordId = recordId; - } - - /** - * @return Returns the children of this record. By default this will - * be an empty list. EscherCotainerRecord is the only record - * that may contain children. - * - * @see EscherContainerRecord - */ - public List getChildRecords() { return Collections.emptyList(); } - - /** - * Sets the child records for this record. By default this will throw - * an exception as only EscherContainerRecords may have children. - * - * @param childRecords Not used in base implementation. - */ - public void setChildRecords(List childRecords) { - throw new UnsupportedOperationException("This record does not support child records."); - } - - /** - * Escher records may need to be clonable in the future. - * - * @return the cloned object - * - * @throws CloneNotSupportedException if the subclass hasn't implemented {@link Cloneable} - */ - @Override - public EscherRecord clone() throws CloneNotSupportedException { - return (EscherRecord)super.clone(); - } - - /** - * Returns the indexed child record. - * - * @param index the index of the child within the child records - * @return the indexed child record - */ - public EscherRecord getChild( int index ) { - return getChildRecords().get(index); - } - - /** - * The display methods allows escher variables to print the record names - * according to their hierarchy. - * - * @param w The print writer to output to. - * @param indent The current indent level. - */ - public void display(PrintWriter w, int indent) - { - for (int i = 0; i < indent * 4; i++) w.print(' '); - w.println(getRecordName()); - } - - /** - * Subclasses should return the short name for this escher record. - * - * @return the short name for this escher record - */ - public abstract String getRecordName(); - - /** - * Returns the instance part of the option record. - * - * @return The instance part of the record - */ - public short getInstance() - { - return fInstance.getShortValue( _options ); - } - - /** - * Sets the instance part of record - * - * @param value instance part value - */ - public void setInstance( short value ) - { - _options = fInstance.setShortValue( _options, value ); - } - - /** - * Returns the version part of the option record. - * - * @return The version part of the option record - */ - public short getVersion() - { - return fVersion.getShortValue( _options ); - } - - /** - * Sets the version part of record - * - * @param value version part value - */ - public void setVersion( short value ) - { - _options = fVersion.setShortValue( _options, value ); - } - - /** - * @param tab - each children must be a right of his parent - * @return xml representation of this record - */ - public String toXml(String tab){ - return tab + "<" + getClass().getSimpleName() + ">\n" + - tab + "\t" + "0x" + HexDump.toHex(_recordId) + "\n" + - tab + "\t" + "" + _options + "\n" + - tab + "\n"; - } - - protected String formatXmlRecordHeader(String className, String recordId, String version, String instance){ - return "<" + className + " recordId=\"0x" + recordId + "\" version=\"0x" + - version + "\" instance=\"0x" + instance + "\" size=\"" + getRecordSize() + "\">\n"; - } - - public String toXml(){ - return toXml(""); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherRecordFactory.java b/trunk/src/java/org/apache/poi/ddf/EscherRecordFactory.java deleted file mode 100644 index 401bbd08c..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherRecordFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -/** - * The escher record factory interface allows for the creation of escher - * records from a pointer into a data array. - */ -public interface EscherRecordFactory { - /** - * Generates an escher record including any children contained under that record. - * An exception is thrown if the record could not be generated. - * - * @param data The byte array containing the records - * @param offset The starting offset into the byte array - * @return The generated escher record - */ - EscherRecord createRecord( byte[] data, int offset ); -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherSerializationListener.java b/trunk/src/java/org/apache/poi/ddf/EscherSerializationListener.java deleted file mode 100644 index dcc5eeeb8..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherSerializationListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -/** - * Interface for listening to escher serialization events. - */ -public interface EscherSerializationListener -{ - /** - * Fired before a given escher record is serialized. - * - * @param offset The position in the data array at which the record will be serialized. - * @param recordId The id of the record about to be serialized. - * @param record The record to be serialized - */ - void beforeRecordSerialize(int offset, short recordId, EscherRecord record); - - /** - * Fired after a record has been serialized. - * - * @param offset The position of the end of the serialized record + 1 - * @param recordId The id of the record about to be serialized - * @param size The number of bytes written for this record. If it is a container - * record then this will include the size of any included records. - * @param record The record which was serialized - */ - void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record); -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherShapePathProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherShapePathProperty.java deleted file mode 100644 index f495f2639..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherShapePathProperty.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -/** - * Defines the constants for the various possible shape paths. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public class EscherShapePathProperty extends EscherSimpleProperty { - - public static final int LINE_OF_STRAIGHT_SEGMENTS = 0; - public static final int CLOSED_POLYGON = 1; - public static final int CURVES = 2; - public static final int CLOSED_CURVES = 3; - public static final int COMPLEX = 4; - - public EscherShapePathProperty( short propertyNumber, int shapePath ) - { - super( propertyNumber, false, false, shapePath ); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java b/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java deleted file mode 100644 index 3872aa905..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.HexDump; - -/** - * A simple property is of fixed length and as a property number in addition - * to a 32-bit value. Properties that can't be stored in only 32-bits are - * stored as EscherComplexProperty objects. - */ -public class EscherSimpleProperty extends EscherProperty -{ - protected int propertyValue; - - /** - * The id is distinct from the actual property number. The id includes the property number the blip id - * flag and an indicator whether the property is complex or not. - * - * @param id the property id - * @param propertyValue the property value - */ - public EscherSimpleProperty( short id, int propertyValue ) - { - super( id ); - this.propertyValue = propertyValue; - } - - /** - * Constructs a new escher property. The three parameters are combined to form a property id. - * - * @param propertyNumber the property number - * @param isComplex true, if its a complex property - * @param isBlipId true, if its a blip - * @param propertyValue the property value - */ - public EscherSimpleProperty( short propertyNumber, boolean isComplex, boolean isBlipId, int propertyValue ) - { - super( propertyNumber, isComplex, isBlipId ); - this.propertyValue = propertyValue; - } - - /** - * Serialize the simple part of the escher record. - * - * @return the number of bytes serialized. - */ - @Override - public int serializeSimplePart( byte[] data, int offset ) - { - LittleEndian.putShort(data, offset, getId()); - LittleEndian.putInt(data, offset + 2, propertyValue); - return 6; - } - - /** - * Escher properties consist of a simple fixed length part and a complex variable length part. - * The fixed length part is serialized first. - */ - @Override - public int serializeComplexPart( byte[] data, int pos ) - { - return 0; - } - - /** - * @return Return the 32 bit value of this property. - */ - public int getPropertyValue() - { - return propertyValue; - } - - /** - * Returns true if one escher property is equal to another. - */ - @Override - public boolean equals( Object o ) - { - if ( this == o ) return true; - if ( !( o instanceof EscherSimpleProperty ) ) return false; - - final EscherSimpleProperty escherSimpleProperty = (EscherSimpleProperty) o; - - if ( propertyValue != escherSimpleProperty.propertyValue ) return false; - if ( getId() != escherSimpleProperty.getId() ) return false; - - return true; - } - - /** - * Returns a hashcode so that this object can be stored in collections that - * require the use of such things. - */ - @Override - public int hashCode() - { - return propertyValue; - } - - /** - * @return the string representation of this property. - */ - @Override - public String toString() - { - return "propNum: " + getPropertyNumber() - + ", RAW: 0x" + HexDump.toHex( getId() ) - + ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() ) - + ", complex: " + isComplex() - + ", blipId: " + isBlipId() - + ", value: " + propertyValue + " (0x" + HexDump.toHex(propertyValue) + ")"; - } - - @Override - public String toXml(String tab){ - StringBuilder builder = new StringBuilder(); - builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId())) - .append("\" name=\"").append(getName()).append("\" blipId=\"") - .append(isBlipId()).append("\" complex=\"").append(isComplex()).append("\" value=\"").append("0x") - .append(HexDump.toHex(propertyValue)).append("\"/>\n"); - return builder.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java deleted file mode 100644 index 3fec761ab..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java +++ /dev/null @@ -1,245 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * Together the the EscherOptRecord this record defines some of the basic - * properties of a shape. - */ -public class EscherSpRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF00A; - public static final String RECORD_DESCRIPTION = "MsofbtSp"; - - public static final int FLAG_GROUP = 0x0001; - public static final int FLAG_CHILD = 0x0002; - public static final int FLAG_PATRIARCH = 0x0004; - public static final int FLAG_DELETED = 0x0008; - public static final int FLAG_OLESHAPE = 0x0010; - public static final int FLAG_HAVEMASTER = 0x0020; - public static final int FLAG_FLIPHORIZ = 0x0040; - public static final int FLAG_FLIPVERT = 0x0080; - public static final int FLAG_CONNECTOR = 0x0100; - public static final int FLAG_HAVEANCHOR = 0x0200; - public static final int FLAG_BACKGROUND = 0x0400; - public static final int FLAG_HASSHAPETYPE = 0x0800; - - private int field_1_shapeId; - private int field_2_flags; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - /*int bytesRemaining =*/ readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - field_1_shapeId = LittleEndian.getInt( data, pos + size ); size += 4; - field_2_flags = LittleEndian.getInt( data, pos + size ); size += 4; -// bytesRemaining -= size; -// remainingData = new byte[bytesRemaining]; -// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining ); - return getRecordSize(); - } - - /** - * This method serializes this escher record into a byte array. - * - * @param offset The offset into data to start writing the record data to. - * @param data The byte array to serialize to. - * @param listener A listener to retrieve start and end callbacks. Use a NullEscherSerailizationListener to ignore these events. - * @return The number of bytes written. - * - * @see NullEscherSerializationListener - */ - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - int remainingBytes = 8; - LittleEndian.putInt( data, offset + 4, remainingBytes ); - LittleEndian.putInt( data, offset + 8, field_1_shapeId ); - LittleEndian.putInt( data, offset + 12, field_2_flags ); -// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length ); -// int pos = offset + 8 + 18 + remainingData.length; - listener.afterRecordSerialize( offset + getRecordSize(), getRecordId(), getRecordSize(), this ); - return 8 + 8; - } - - @Override - public int getRecordSize() - { - return 8 + 8; - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "Sp"; - } - - - /** - * @return the string representing this shape. - */ - @Override - public String toString() - { - String nl = System.getProperty("line.separator"); - - return getClass().getName() + ":" + nl + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl + - " Version: 0x" + HexDump.toHex(getVersion()) + nl + - " ShapeType: 0x" + HexDump.toHex(getShapeType()) + nl + - " ShapeId: " + field_1_shapeId + nl + - " Flags: " + decodeFlags(field_2_flags) + " (0x" + HexDump.toHex(field_2_flags) + ")" + nl; - - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("0x").append(HexDump.toHex(getShapeType())).append("\n") - .append(tab).append("\t").append("").append(field_1_shapeId).append("\n") - .append(tab).append("\t").append("").append(decodeFlags(field_2_flags) + " (0x" + HexDump.toHex(field_2_flags) + ")").append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Converts the shape flags into a more descriptive name. - */ - private String decodeFlags( int flags ) - { - StringBuffer result = new StringBuffer(); - result.append( ( flags & FLAG_GROUP ) != 0 ? "|GROUP" : "" ); - result.append( ( flags & FLAG_CHILD ) != 0 ? "|CHILD" : "" ); - result.append( ( flags & FLAG_PATRIARCH ) != 0 ? "|PATRIARCH" : "" ); - result.append( ( flags & FLAG_DELETED ) != 0 ? "|DELETED" : "" ); - result.append( ( flags & FLAG_OLESHAPE ) != 0 ? "|OLESHAPE" : "" ); - result.append( ( flags & FLAG_HAVEMASTER ) != 0 ? "|HAVEMASTER" : "" ); - result.append( ( flags & FLAG_FLIPHORIZ ) != 0 ? "|FLIPHORIZ" : "" ); - result.append( ( flags & FLAG_FLIPVERT ) != 0 ? "|FLIPVERT" : "" ); - result.append( ( flags & FLAG_CONNECTOR ) != 0 ? "|CONNECTOR" : "" ); - result.append( ( flags & FLAG_HAVEANCHOR ) != 0 ? "|HAVEANCHOR" : "" ); - result.append( ( flags & FLAG_BACKGROUND ) != 0 ? "|BACKGROUND" : "" ); - result.append( ( flags & FLAG_HASSHAPETYPE ) != 0 ? "|HASSHAPETYPE" : "" ); - - //need to check, else blows up on some records - bug 34435 - if(result.length() > 0) { - result.deleteCharAt(0); - } - return result.toString(); - } - - /** - * @return A number that identifies this shape - */ - public int getShapeId() - { - return field_1_shapeId; - } - - /** - * Sets a number that identifies this shape. - * - * @param field_1_shapeId the shape id - */ - public void setShapeId( int field_1_shapeId ) - { - this.field_1_shapeId = field_1_shapeId; - } - - /** - * The flags that apply to this shape. - * - * @return the flags - * - * @see #FLAG_GROUP - * @see #FLAG_CHILD - * @see #FLAG_PATRIARCH - * @see #FLAG_DELETED - * @see #FLAG_OLESHAPE - * @see #FLAG_HAVEMASTER - * @see #FLAG_FLIPHORIZ - * @see #FLAG_FLIPVERT - * @see #FLAG_CONNECTOR - * @see #FLAG_HAVEANCHOR - * @see #FLAG_BACKGROUND - * @see #FLAG_HASSHAPETYPE - */ - public int getFlags() - { - return field_2_flags; - } - - /** - * The flags that apply to this shape. - * - * @param field_2_flags the flags - * - * @see #FLAG_GROUP - * @see #FLAG_CHILD - * @see #FLAG_PATRIARCH - * @see #FLAG_DELETED - * @see #FLAG_OLESHAPE - * @see #FLAG_HAVEMASTER - * @see #FLAG_FLIPHORIZ - * @see #FLAG_FLIPVERT - * @see #FLAG_CONNECTOR - * @see #FLAG_HAVEANCHOR - * @see #FLAG_BACKGROUND - * @see #FLAG_HASSHAPETYPE - */ - public void setFlags( int field_2_flags ) - { - this.field_2_flags = field_2_flags; - } - - /** - * Returns shape type. Must be one of MSOSPT values (see [MS-ODRAW] for - * details). - * - * @return shape type - */ - public short getShapeType() - { - return getInstance(); - } - - /** - * Sets shape type. Must be one of MSOSPT values (see [MS-ODRAW] for - * details). - * - * @param value - * new shape type - */ - public void setShapeType( short value ) - { - setInstance( value ); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java deleted file mode 100644 index a4d30b39a..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java +++ /dev/null @@ -1,194 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.RecordFormatException; - -/** - * The spgr record defines information about a shape group. Groups in escher - * are simply another form of shape that you can't physically see. - */ -public class EscherSpgrRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF009; - public static final String RECORD_DESCRIPTION = "MsofbtSpgr"; - - private int field_1_rectX1; - private int field_2_rectY1; - private int field_3_rectX2; - private int field_4_rectY2; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - field_1_rectX1 = LittleEndian.getInt( data, pos + size );size+=4; - field_2_rectY1 = LittleEndian.getInt( data, pos + size );size+=4; - field_3_rectX2 = LittleEndian.getInt( data, pos + size );size+=4; - field_4_rectY2 = LittleEndian.getInt( data, pos + size );size+=4; - bytesRemaining -= size; - if (bytesRemaining != 0) throw new RecordFormatException("Expected no remaining bytes but got " + bytesRemaining); -// remainingData = new byte[bytesRemaining]; -// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining ); - return 8 + size + bytesRemaining; - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - LittleEndian.putShort( data, offset, getOptions() ); - LittleEndian.putShort( data, offset + 2, getRecordId() ); - int remainingBytes = 16; - LittleEndian.putInt( data, offset + 4, remainingBytes ); - LittleEndian.putInt( data, offset + 8, field_1_rectX1 ); - LittleEndian.putInt( data, offset + 12, field_2_rectY1 ); - LittleEndian.putInt( data, offset + 16, field_3_rectX2 ); - LittleEndian.putInt( data, offset + 20, field_4_rectY2 ); -// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length ); -// int pos = offset + 8 + 18 + remainingData.length; - listener.afterRecordSerialize( offset + getRecordSize(), getRecordId(), offset + getRecordSize(), this ); - return 8 + 16; - } - - @Override - public int getRecordSize() - { - return 8 + 16; - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "Spgr"; - } - - /** - * @return the string representation of this record. - */ - @Override - public String toString() { - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + '\n' + - " Version: 0x" + HexDump.toHex(getVersion()) + '\n' + - " Instance: 0x" + HexDump.toHex(getInstance()) + '\n' + - " RectX: " + field_1_rectX1 + '\n' + - " RectY: " + field_2_rectY1 + '\n' + - " RectWidth: " + field_3_rectX2 + '\n' + - " RectHeight: " + field_4_rectY2 + '\n'; - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(field_1_rectX1).append("\n") - .append(tab).append("\t").append("").append(field_2_rectY1).append("\n") - .append(tab).append("\t").append("").append(field_3_rectX2).append("\n") - .append(tab).append("\t").append("").append(field_4_rectY2).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * The starting top-left coordinate of child records. - * - * @return the top-left x coordinate - */ - public int getRectX1() - { - return field_1_rectX1; - } - - /** - * The top-left coordinate of child records. - * - * @param x1 the top-left x coordinate - */ - public void setRectX1( int x1 ) - { - this.field_1_rectX1 = x1; - } - - /** - * The top-left coordinate of child records. - * - * @return the top-left y coordinate - */ - public int getRectY1() - { - return field_2_rectY1; - } - - /** - * The top-left y coordinate of child records. - * - * @param y1 the top-left y coordinate - */ - public void setRectY1( int y1 ) - { - this.field_2_rectY1 = y1; - } - - /** - * The bottom-right x coordinate of child records. - * - * @return the bottom-right x coordinate - */ - public int getRectX2() - { - return field_3_rectX2; - } - - /** - * The bottom-right x coordinate of child records. - * - * @param x2 the bottom-right x coordinate - */ - public void setRectX2( int x2 ) - { - this.field_3_rectX2 = x2; - } - - /** - * The bottom-right y coordinate of child records. - * - * @return the bottom-right y coordinate - */ - public int getRectY2() - { - return field_4_rectY2; - } - - /** - * The bottom-right y coordinate of child records. - * - * @param rectY2 the bottom-right y coordinate - */ - public void setRectY2(int rectY2) { - this.field_4_rectY2 = rectY2; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java deleted file mode 100644 index 3467d0a44..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java +++ /dev/null @@ -1,187 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.RecordFormatException; - -/** - * A list of the most recently used colours for the drawings contained in - * this document. - */ -public class EscherSplitMenuColorsRecord - extends EscherRecord -{ - public static final short RECORD_ID = (short) 0xF11E; - public static final String RECORD_DESCRIPTION = "MsofbtSplitMenuColors"; - - private int field_1_color1; - private int field_2_color2; - private int field_3_color3; - private int field_4_color4; - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - int pos = offset + 8; - int size = 0; - field_1_color1 = LittleEndian.getInt( data, pos + size );size+=4; - field_2_color2 = LittleEndian.getInt( data, pos + size );size+=4; - field_3_color3 = LittleEndian.getInt( data, pos + size );size+=4; - field_4_color4 = LittleEndian.getInt( data, pos + size );size+=4; - bytesRemaining -= size; - if (bytesRemaining != 0) - throw new RecordFormatException("Expecting no remaining data but got " + bytesRemaining + " byte(s)."); - return 8 + size + bytesRemaining; - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { -// int field_2_numIdClusters = field_5_fileIdClusters.length + 1; - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - int pos = offset; - LittleEndian.putShort( data, pos, getOptions() ); pos += 2; - LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; - int remainingBytes = getRecordSize() - 8; - - LittleEndian.putInt( data, pos, remainingBytes ); pos += 4; - LittleEndian.putInt( data, pos, field_1_color1 ); pos += 4; - LittleEndian.putInt( data, pos, field_2_color2 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_color3 ); pos += 4; - LittleEndian.putInt( data, pos, field_4_color4 ); pos += 4; - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return getRecordSize(); - } - - @Override - public int getRecordSize() { - return 8 + 4 * 4; - } - - @Override - public short getRecordId() { - return RECORD_ID; - } - - @Override - public String getRecordName() { - return "SplitMenuColors"; - } - - /** - * @return a string representation of this record. - */ - @Override - public String toString() { - return getClass().getName() + ":" + '\n' + - " RecordId: 0x" + HexDump.toHex(RECORD_ID) + '\n' + - " Version: 0x" + HexDump.toHex(getVersion()) + '\n' + - " Instance: 0x" + HexDump.toHex(getInstance()) + '\n' + - " Color1: 0x" + HexDump.toHex(field_1_color1) + '\n' + - " Color2: 0x" + HexDump.toHex(field_2_color2) + '\n' + - " Color3: 0x" + HexDump.toHex(field_3_color3) + '\n' + - " Color4: 0x" + HexDump.toHex(field_4_color4) + '\n' + - ""; - } - - @Override - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("0x").append(HexDump.toHex(field_1_color1)).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex(field_2_color2)).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex(field_3_color3)).append("\n") - .append(tab).append("\t").append("0x").append(HexDump.toHex(field_4_color4)).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * Gets the fill color - * - * @return the fill color - */ - public int getColor1() { - return field_1_color1; - } - - /** - * Sets the fill color - * - * @param field_1_color1 the fill color - */ - public void setColor1( int field_1_color1 ) { - this.field_1_color1 = field_1_color1; - } - - /** - * Gets the line color - * - * @return the line color - */ - public int getColor2() { - return field_2_color2; - } - - /** - * Sets the line color - * - * @param field_2_color2 the line color - */ - public void setColor2( int field_2_color2 ) { - this.field_2_color2 = field_2_color2; - } - - /** - * Gets the shadow color - * - * @return the shadow color - */ - public int getColor3() { - return field_3_color3; - } - - /** - * Sets the shadow color - * - * @param field_3_color3 the shadow color - */ - public void setColor3( int field_3_color3 ) { - this.field_3_color3 = field_3_color3; - } - - /** - * Gets the 3-D color - * - * @return the 3-D color - */ - public int getColor4() { - return field_4_color4; - } - - /** - * Sets the 3-D color - * - * @param field_4_color4 the 3-D color - */ - public void setColor4( int field_4_color4 ) { - this.field_4_color4 = field_4_color4; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java deleted file mode 100644 index 618294211..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ddf; - -/** - * "The OfficeArtTertiaryFOPT record specifies a table of OfficeArtRGFOPTE properties, as defined in section 2.3.1." - * -- [MS-ODRAW] -- v20110608; Office Drawing Binary File Format - */ -public class EscherTertiaryOptRecord extends AbstractEscherOptRecord -{ - public static final short RECORD_ID = (short) 0xF122; - - @Override - public String getRecordName() - { - return "TertiaryOpt"; - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java b/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java deleted file mode 100644 index 779808000..000000000 --- a/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.RecordFormatException; - -/** - * Holds data from the parent application. Most commonly used to store - * text in the format of the parent application, rather than in - * Escher format. We don't attempt to understand the contents, since - * they will be in the parent's format, not Escher format. - */ -public final class EscherTextboxRecord extends EscherRecord implements Cloneable { - public static final short RECORD_ID = (short)0xF00D; - public static final String RECORD_DESCRIPTION = "msofbtClientTextbox"; - - private static final byte[] NO_BYTES = new byte[0]; - - /** The data for this record not including the the 8 byte header */ - private byte[] thedata = NO_BYTES; - - public EscherTextboxRecord() - { - } - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - - // Save the data, ready for the calling code to do something - // useful with it - thedata = new byte[bytesRemaining]; - System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining ); - return bytesRemaining + 8; - } - - @Override - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort(data, offset, getOptions()); - LittleEndian.putShort(data, offset+2, getRecordId()); - int remainingBytes = thedata.length; - LittleEndian.putInt(data, offset+4, remainingBytes); - System.arraycopy(thedata, 0, data, offset+8, thedata.length); - int pos = offset+8+thedata.length; - - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - int size = pos - offset; - if (size != getRecordSize()) - throw new RecordFormatException(size + " bytes written but getRecordSize() reports " + getRecordSize()); - return size; - } - - /** - * Returns any extra data associated with this record. In practice excel - * does not seem to put anything here, but with PowerPoint this will - * contain the bytes that make up a TextHeaderAtom followed by a - * TextBytesAtom/TextCharsAtom - * - * @return the extra data - */ - public byte[] getData() - { - return thedata; - } - - /** - * Sets the extra data (in the parent application's format) to be - * contained by the record. Used when the parent application changes - * the contents. - * - * @param b the buffer which contains the data - * @param start the start position in the buffer - * @param length the length of the block - */ - public void setData(byte[] b, int start, int length) - { - thedata = new byte[length]; - System.arraycopy(b,start,thedata,0,length); - } - - /** - * Sets the extra data (in the parent application's format) to be - * contained by the record. Used when the parent application changes - * the contents. - * - * @param b the data - */ - public void setData(byte[] b) { - setData(b,0,b.length); - } - - @Override - public int getRecordSize() - { - return 8 + thedata.length; - } - - @Override - public EscherTextboxRecord clone() { - EscherTextboxRecord etr = new EscherTextboxRecord(); - etr.setOptions(this.getOptions()); - etr.setRecordId(this.getRecordId()); - etr.thedata = this.thedata.clone(); - return etr; - } - - @Override - public String getRecordName() { - return "ClientTextbox"; - } - - @Override - public String toString() - { - String nl = System.getProperty( "line.separator" ); - - String theDumpHex = ""; - try - { - if (thedata.length != 0) - { - theDumpHex = " Extra Data:" + nl; - theDumpHex += HexDump.dump(thedata, 0, 0); - } - } - catch ( Exception e ) - { - theDumpHex = "Error!!"; - } - - return getClass().getName() + ":" + nl + - " isContainer: " + isContainerRecord() + nl + - " version: 0x" + HexDump.toHex( getVersion() ) + nl + - " instance: 0x" + HexDump.toHex( getInstance() ) + nl + - " recordId: 0x" + HexDump.toHex( getRecordId() ) + nl + - " numchildren: " + getChildRecords().size() + nl + - theDumpHex; - } - - @Override - public String toXml(String tab) { - String theDumpHex = ""; - try - { - if (thedata.length != 0) - { - theDumpHex += HexDump.dump(thedata, 0, 0); - } - } - catch ( Exception e ) - { - theDumpHex = "Error!!"; - } - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(theDumpHex).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } -} - - - diff --git a/trunk/src/java/org/apache/poi/ddf/NullEscherSerializationListener.java b/trunk/src/java/org/apache/poi/ddf/NullEscherSerializationListener.java deleted file mode 100644 index 28a8c94a6..000000000 --- a/trunk/src/java/org/apache/poi/ddf/NullEscherSerializationListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -/** - * Ignores all serialization events. - */ -public class NullEscherSerializationListener implements EscherSerializationListener { - @Override - public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) { - // do nothing - } - - @Override - public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) { - // do nothing - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java b/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java deleted file mode 100644 index 6f871528a..000000000 --- a/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java +++ /dev/null @@ -1,177 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ddf; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * This record is used whenever a escher record is encountered that - * we do not explicitly support. - */ -public final class UnknownEscherRecord extends EscherRecord implements Cloneable { - private static final byte[] NO_BYTES = new byte[0]; - - /** The data for this record not including the the 8 byte header */ - private byte[] thedata = NO_BYTES; - private List _childRecords; - - public UnknownEscherRecord() { - _childRecords = new ArrayList(); - } - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - /* - * Have a check between avaliable bytes and bytesRemaining, - * take the avaliable length if the bytesRemaining out of range. - */ - int avaliable = data.length - (offset + 8); - if (bytesRemaining > avaliable) { - bytesRemaining = avaliable; - } - - if (isContainerRecord()) { - int bytesWritten = 0; - thedata = new byte[0]; - offset += 8; - bytesWritten += 8; - while ( bytesRemaining > 0 ) - { - EscherRecord child = recordFactory.createRecord( data, offset ); - int childBytesWritten = child.fillFields( data, offset, recordFactory ); - bytesWritten += childBytesWritten; - offset += childBytesWritten; - bytesRemaining -= childBytesWritten; - getChildRecords().add( child ); - } - return bytesWritten; - } - - thedata = new byte[bytesRemaining]; - System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining ); - return bytesRemaining + 8; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort(data, offset, getOptions()); - LittleEndian.putShort(data, offset+2, getRecordId()); - int remainingBytes = thedata.length; - for (EscherRecord r : _childRecords) { - remainingBytes += r.getRecordSize(); - } - LittleEndian.putInt(data, offset+4, remainingBytes); - System.arraycopy(thedata, 0, data, offset+8, thedata.length); - int pos = offset+8+thedata.length; - for (EscherRecord r : _childRecords) { - pos += r.serialize(pos, data, listener ); - } - - listener.afterRecordSerialize( pos, getRecordId(), pos - offset, this ); - return pos - offset; - } - - /** - * @return the data which makes up this record - */ - public byte[] getData() { - return thedata; - } - - @Override - public int getRecordSize() { - return 8 + thedata.length; - } - - @Override - public List getChildRecords() { - return _childRecords; - } - - @Override - public void setChildRecords(List childRecords) { - _childRecords = childRecords; - } - - @Override - public UnknownEscherRecord clone() { - UnknownEscherRecord uer = new UnknownEscherRecord(); - uer.thedata = this.thedata.clone(); - uer.setOptions(this.getOptions()); - uer.setRecordId(this.getRecordId()); - return uer; - } - - @Override - public String getRecordName() { - return "Unknown 0x" + HexDump.toHex(getRecordId()); - } - - @Override - public String toString() { - StringBuffer children = new StringBuffer(); - if (getChildRecords().size() > 0) { - children.append( " children: " + '\n' ); - for (EscherRecord record : _childRecords) { - children.append( record.toString() ); - children.append( '\n' ); - } - } - - String theDumpHex = HexDump.toHex(thedata, 32); - - return getClass().getName() + ":" + '\n' + - " isContainer: " + isContainerRecord() + '\n' + - " version: 0x" + HexDump.toHex( getVersion() ) + '\n' + - " instance: 0x" + HexDump.toHex( getInstance() ) + '\n' + - " recordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' + - " numchildren: " + getChildRecords().size() + '\n' + - theDumpHex + - children.toString(); - } - - @Override - public String toXml(String tab) { - String theDumpHex = HexDump.toHex(thedata, 32); - StringBuilder builder = new StringBuilder(); - builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) - .append(tab).append("\t").append("").append(isContainerRecord()).append("\n") - .append(tab).append("\t").append("").append(HexDump.toHex(_childRecords.size())).append("\n"); - for ( Iterator iterator = _childRecords.iterator(); iterator - .hasNext(); ) - { - EscherRecord record = iterator.next(); - builder.append(record.toXml(tab+"\t")); - } - builder.append(theDumpHex).append("\n"); - builder.append(tab).append("\n"); - return builder.toString(); - } - - public void addChildRecord(EscherRecord childRecord) { - getChildRecords().add( childRecord ); - } -} diff --git a/trunk/src/java/org/apache/poi/ddf/package.html b/trunk/src/java/org/apache/poi/ddf/package.html deleted file mode 100644 index 6a3393d63..000000000 --- a/trunk/src/java/org/apache/poi/ddf/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -

    This package contains classes for decoding the Microsoft Office - Drawing format otherwise known as escher henceforth known in POI - as the Dreadful Drawing Format. -

    - - - diff --git a/trunk/src/java/org/apache/poi/dev/RecordGenerator.java b/trunk/src/java/org/apache/poi/dev/RecordGenerator.java deleted file mode 100644 index 585003c52..000000000 --- a/trunk/src/java/org/apache/poi/dev/RecordGenerator.java +++ /dev/null @@ -1,160 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.dev; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Locale; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.poi.util.XMLHelper; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * Description of the Class - * - *@author andy - *@since May 10, 2002 - */ -public class RecordGenerator { - /** - * The main program for the RecordGenerator class - * - *@param args The command line arguments - *@exception Exception Description of the Exception - */ - public static void main(String[] args) - throws Exception { - // Force load so that we don't start generating records and realise this hasn't compiled yet. - Class.forName("org.apache.poi.generator.FieldIterator"); - - if (args.length != 4) { - System.out.println("Usage:"); - System.out.println(" java org.apache.poi.hssf.util.RecordGenerator RECORD_DEFINTIONS RECORD_STYLES DEST_SRC_PATH TEST_SRC_PATH"); - } else { - generateRecords(args[0], args[1], args[2], args[3]); - } - } - - - private static void generateRecords(String defintionsDir, String recordStyleDir, String destSrcPathDir, String testSrcPathDir) - throws Exception { - File definitionsFiles[] = new File(defintionsDir).listFiles(); - if (definitionsFiles == null) { - System.err.println(defintionsDir+" is not a directory."); - return; - } - - for (File file : definitionsFiles) { - if (file.isFile() && - (file.getName().endsWith("_record.xml") || - file.getName().endsWith("_type.xml") - ) - ) { - // Get record name and package - DocumentBuilderFactory factory = XMLHelper.getDocumentBuilderFactory(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.parse(file); - Element record = document.getDocumentElement(); - String extendstg = record.getElementsByTagName("extends").item(0).getFirstChild().getNodeValue(); - String suffix = record.getElementsByTagName("suffix").item(0).getFirstChild().getNodeValue(); - String recordName = record.getAttributes().getNamedItem("name").getNodeValue(); - String packageName = record.getAttributes().getNamedItem("package").getNodeValue(); - packageName = packageName.replace('.', '/'); - - // Generate record - String destinationPath = destSrcPathDir + "/" + packageName; - File destinationPathFile = new File(destinationPath); - if(!destinationPathFile.mkdirs()) { - throw new IOException("Could not create directory " + destinationPathFile); - } else { - System.out.println("Created destination directory: " + destinationPath); - } - String destinationFilepath = destinationPath + "/" + recordName + suffix + ".java"; - transform(file, new File(destinationFilepath), - new File(recordStyleDir + "/" + extendstg.toLowerCase(Locale.ROOT) + ".xsl")); - System.out.println("Generated " + suffix + ": " + destinationFilepath); - - // Generate test (if not already generated) - destinationPath = testSrcPathDir + "/" + packageName; - destinationPathFile = new File(destinationPath); - if(!destinationPathFile.mkdirs()) { - throw new IOException("Could not create directory " + destinationPathFile); - } else { - System.out.println("Created destination directory: " + destinationPath); - } - destinationFilepath = destinationPath + "/Test" + recordName + suffix + ".java"; - if (!new File(destinationFilepath).exists()) { - String temp = (recordStyleDir + "/" + extendstg.toLowerCase(Locale.ROOT) + "_test.xsl"); - transform(file, new File(destinationFilepath), new File(temp)); - System.out.println("Generated test: " + destinationFilepath); - } else { - System.out.println("Skipped test generation: " + destinationFilepath); - } - } - } - } - - - - /** - *

    Executes an XSL transformation. This process transforms an XML input - * file into a text output file controlled by an XSLT specification.

    - * - * @param in the XML input file - * @param out the text output file - * @param xslt the XSLT specification, i.e. an XSL style sheet - * @throws FileNotFoundException - * @throws TransformerException - */ - private static void transform(final File in, final File out, final File xslt) - throws FileNotFoundException, TransformerException - { - final StreamSource ss = new StreamSource(xslt); - final TransformerFactory tf = TransformerFactory.newInstance(); - final Transformer t; - try - { - t = tf.newTransformer(ss); - } - catch (TransformerException ex) - { - System.err.println("Error compiling XSL style sheet " + xslt); - throw ex; - } - final Properties p = new Properties(); - p.setProperty(OutputKeys.METHOD, "text"); - t.setOutputProperties(p); - final Result result = new StreamResult(out); - t.transform(new StreamSource(in), result); - } - -} diff --git a/trunk/src/java/org/apache/poi/extractor/OLE2ExtractorFactory.java b/trunk/src/java/org/apache/poi/extractor/OLE2ExtractorFactory.java deleted file mode 100644 index 737e9e351..000000000 --- a/trunk/src/java/org/apache/poi/extractor/OLE2ExtractorFactory.java +++ /dev/null @@ -1,270 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.extractor; - -import static org.apache.poi.hssf.model.InternalWorkbook.OLD_WORKBOOK_DIR_ENTRY_NAME; -import static org.apache.poi.hssf.model.InternalWorkbook.WORKBOOK_DIR_ENTRY_NAMES; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.POITextExtractor; -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.hssf.extractor.EventBasedExcelExtractor; -import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Figures out the correct POIOLE2TextExtractor for your supplied - * document, and returns it. - * - *

    Note 1 - will fail for many file formats if the POI Scratchpad jar is - * not present on the runtime classpath

    - *

    Note 2 - for text extractor creation across all formats, use - * {@link org.apache.poi.extractor.ExtractorFactory} contained within - * the OOXML jar.

    - *

    Note 3 - rather than using this, for most cases you would be better - * off switching to Apache Tika instead!

    - */ -@SuppressWarnings("WeakerAccess") -public class OLE2ExtractorFactory { - private static final POILogger LOGGER = POILogFactory.getLogger(OLE2ExtractorFactory.class); - - /** Should this thread prefer event based over usermodel based extractors? */ - private static final ThreadLocal threadPreferEventExtractors = new ThreadLocal() { - @Override - protected Boolean initialValue() { return Boolean.FALSE; } - }; - - /** Should all threads prefer event based over usermodel based extractors? */ - private static Boolean allPreferEventExtractors; - - /** - * Should this thread prefer event based over usermodel based extractors? - * (usermodel extractors tend to be more accurate, but use more memory) - * Default is false. - */ - public static boolean getThreadPrefersEventExtractors() { - return threadPreferEventExtractors.get(); - } - - /** - * Should all threads prefer event based over usermodel based extractors? - * (usermodel extractors tend to be more accurate, but use more memory) - * Default is to use the thread level setting, which defaults to false. - */ - public static Boolean getAllThreadsPreferEventExtractors() { - return allPreferEventExtractors; - } - - /** - * Should this thread prefer event based over usermodel based extractors? - * Will only be used if the All Threads setting is null. - */ - public static void setThreadPrefersEventExtractors(boolean preferEventExtractors) { - threadPreferEventExtractors.set(preferEventExtractors); - } - - /** - * Should all threads prefer event based over usermodel based extractors? - * If set, will take preference over the Thread level setting. - */ - public static void setAllThreadsPreferEventExtractors(Boolean preferEventExtractors) { - allPreferEventExtractors = preferEventExtractors; - } - - /** - * Should this thread use event based extractors is available? - * Checks the all-threads one first, then thread specific. - */ - protected static boolean getPreferEventExtractor() { - if(allPreferEventExtractors != null) { - return allPreferEventExtractors; - } - return threadPreferEventExtractors.get(); - } - - public static POIOLE2TextExtractor createExtractor(POIFSFileSystem fs) throws IOException { - // Only ever an OLE2 one from the root of the FS - return (POIOLE2TextExtractor)createExtractor(fs.getRoot()); - } - public static POIOLE2TextExtractor createExtractor(NPOIFSFileSystem fs) throws IOException { - // Only ever an OLE2 one from the root of the FS - return (POIOLE2TextExtractor)createExtractor(fs.getRoot()); - } - public static POIOLE2TextExtractor createExtractor(OPOIFSFileSystem fs) throws IOException { - // Only ever an OLE2 one from the root of the FS - return (POIOLE2TextExtractor)createExtractor(fs.getRoot()); - } - - public static POITextExtractor createExtractor(InputStream input) throws IOException { - Class cls = getOOXMLClass(); - if (cls != null) { - // Use Reflection to get us the full OOXML-enabled version - try { - Method m = cls.getDeclaredMethod("createExtractor", InputStream.class); - return (POITextExtractor)m.invoke(null, input); - } catch (IllegalArgumentException iae) { - throw iae; - } catch (Exception e) { - throw new IllegalArgumentException("Error creating Extractor for InputStream", e); - } - } else { - // Best hope it's OLE2.... - return createExtractor(new NPOIFSFileSystem(input)); - } - } - - private static Class getOOXMLClass() { - try { - return OLE2ExtractorFactory.class.getClassLoader().loadClass( - "org.apache.poi.extractor.ExtractorFactory" - ); - } catch (ClassNotFoundException e) { - LOGGER.log(POILogger.WARN, "POI OOXML jar missing"); - return null; - } - } - private static Class getScratchpadClass() { - try { - return OLE2ExtractorFactory.class.getClassLoader().loadClass( - "org.apache.poi.extractor.OLE2ScratchpadExtractorFactory" - ); - } catch (ClassNotFoundException e) { - LOGGER.log(POILogger.ERROR, "POI Scratchpad jar missing"); - throw new IllegalStateException("POI Scratchpad jar missing, required for ExtractorFactory"); - } - } - - /** - * Create the Extractor, if possible. Generally needs the Scratchpad jar. - * Note that this won't check for embedded OOXML resources either, use - * {@link org.apache.poi.extractor.ExtractorFactory} for that. - */ - public static POITextExtractor createExtractor(DirectoryNode poifsDir) - throws IOException - { - // Look for certain entries in the stream, to figure it - // out from - for (String workbookName : WORKBOOK_DIR_ENTRY_NAMES) { - if (poifsDir.hasEntry(workbookName)) { - if (getPreferEventExtractor()) { - return new EventBasedExcelExtractor(poifsDir); - } - return new ExcelExtractor(poifsDir); - } - } - if (poifsDir.hasEntry(OLD_WORKBOOK_DIR_ENTRY_NAME)) { - throw new OldExcelFormatException("Old Excel Spreadsheet format (1-95) " - + "found. Please call OldExcelExtractor directly for basic text extraction"); - } - - // Ask Scratchpad, or fail trying - Class cls = getScratchpadClass(); - try { - Method m = cls.getDeclaredMethod("createExtractor", DirectoryNode.class); - POITextExtractor ext = (POITextExtractor)m.invoke(null, poifsDir); - if (ext != null) return ext; - } catch (IllegalArgumentException iae) { - throw iae; - } catch (Exception e) { - throw new IllegalArgumentException("Error creating Scratchpad Extractor", e); - } - - throw new IllegalArgumentException("No supported documents found in the OLE2 stream"); - } - - /** - * Returns an array of text extractors, one for each of - * the embedded documents in the file (if there are any). - * If there are no embedded documents, you'll get back an - * empty array. Otherwise, you'll get one open - * {@link POITextExtractor} for each embedded file. - */ - public static POITextExtractor[] getEmbededDocsTextExtractors(POIOLE2TextExtractor ext) - throws IOException - { - // All the embedded directories we spotted - List dirs = new ArrayList(); - // For anything else not directly held in as a POIFS directory - List nonPOIFS = new ArrayList(); - - // Find all the embedded directories - DirectoryEntry root = ext.getRoot(); - if(root == null) { - throw new IllegalStateException("The extractor didn't know which POIFS it came from!"); - } - - if(ext instanceof ExcelExtractor) { - // These are in MBD... under the root - Iterator it = root.getEntries(); - while(it.hasNext()) { - Entry entry = it.next(); - if(entry.getName().startsWith("MBD")) { - dirs.add(entry); - } - } - } else { - // Ask Scratchpad, or fail trying - Class cls = getScratchpadClass(); - try { - Method m = cls.getDeclaredMethod( - "identifyEmbeddedResources", POIOLE2TextExtractor.class, List.class, List.class); - m.invoke(null, ext, dirs, nonPOIFS); - } catch (Exception e) { - throw new IllegalArgumentException("Error checking for Scratchpad embedded resources", e); - } - } - - // Create the extractors - if(dirs.size() == 0 && nonPOIFS.size() == 0){ - return new POITextExtractor[0]; - } - - ArrayList e = new ArrayList(); - for (Entry dir : dirs) { - e.add(createExtractor( - (DirectoryNode) dir - )); - } - for (InputStream nonPOIF : nonPOIFS) { - try { - e.add(createExtractor(nonPOIF)); - } catch (IllegalArgumentException ie) { - // Ignore, just means it didn't contain - // a format we support as yet - LOGGER.log(POILogger.WARN, ie); - } catch (Exception xe) { - // Ignore, invalid format - LOGGER.log(POILogger.WARN, xe); - } - } - return e.toArray(new POITextExtractor[e.size()]); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Array.java b/trunk/src/java/org/apache/poi/hpsf/Array.java deleted file mode 100644 index 8850ab9cd..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Array.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -@Internal -class Array -{ - static class ArrayDimension - { - static final int SIZE = 8; - - private int _indexOffset; - private long _size; - - ArrayDimension( byte[] data, int offset ) - { - _size = LittleEndian.getUInt( data, offset ); - _indexOffset = LittleEndian.getInt( data, offset - + LittleEndian.INT_SIZE ); - } - } - - static class ArrayHeader - { - private ArrayDimension[] _dimensions; - private int _type; - - ArrayHeader( byte[] data, int startOffset ) - { - int offset = startOffset; - - _type = LittleEndian.getInt( data, offset ); - offset += LittleEndian.INT_SIZE; - - long numDimensionsUnsigned = LittleEndian.getUInt( data, offset ); - offset += LittleEndian.INT_SIZE; - - if ( !( 1 <= numDimensionsUnsigned && numDimensionsUnsigned <= 31 ) ) - throw new IllegalPropertySetDataException( - "Array dimension number " + numDimensionsUnsigned - + " is not in [1; 31] range" ); - int numDimensions = (int) numDimensionsUnsigned; - - _dimensions = new ArrayDimension[numDimensions]; - for ( int i = 0; i < numDimensions; i++ ) - { - _dimensions[i] = new ArrayDimension( data, offset ); - offset += ArrayDimension.SIZE; - } - } - - long getNumberOfScalarValues() - { - long result = 1; - for ( ArrayDimension dimension : _dimensions ) - result *= dimension._size; - return result; - } - - int getSize() - { - return LittleEndian.INT_SIZE * 2 + _dimensions.length - * ArrayDimension.SIZE; - } - - int getType() - { - return _type; - } - } - - private ArrayHeader _header; - private TypedPropertyValue[] _values; - - Array() - { - } - - Array( final byte[] data, final int offset ) - { - read( data, offset ); - } - - int read( final byte[] data, final int startOffset ) - { - int offset = startOffset; - - _header = new ArrayHeader( data, offset ); - offset += _header.getSize(); - - long numberOfScalarsLong = _header.getNumberOfScalarValues(); - if ( numberOfScalarsLong > Integer.MAX_VALUE ) - throw new UnsupportedOperationException( - "Sorry, but POI can't store array of properties with size of " - + numberOfScalarsLong + " in memory" ); - int numberOfScalars = (int) numberOfScalarsLong; - - _values = new TypedPropertyValue[numberOfScalars]; - final int type = _header._type; - if ( type == Variant.VT_VARIANT ) - { - for ( int i = 0; i < numberOfScalars; i++ ) - { - TypedPropertyValue typedPropertyValue = new TypedPropertyValue(); - offset += typedPropertyValue.read( data, offset ); - } - } - else - { - for ( int i = 0; i < numberOfScalars; i++ ) - { - TypedPropertyValue typedPropertyValue = new TypedPropertyValue( - type, null ); - offset += typedPropertyValue.readValuePadded( data, offset ); - } - } - - return offset - startOffset; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Blob.java b/trunk/src/java/org/apache/poi/hpsf/Blob.java deleted file mode 100644 index 547e2392b..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Blob.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -@Internal -class Blob -{ - private byte[] _value; - - Blob( byte[] data, int offset ) - { - int size = LittleEndian.getInt( data, offset ); - - if ( size == 0 ) - { - _value = new byte[0]; - return; - } - - _value = LittleEndian.getByteArray( data, offset - + LittleEndian.INT_SIZE, size ); - } - - int getSize() - { - return LittleEndian.INT_SIZE + _value.length; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/ClassID.java b/trunk/src/java/org/apache/poi/hpsf/ClassID.java deleted file mode 100644 index 1c06db015..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/ClassID.java +++ /dev/null @@ -1,265 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.StringUtil; - -/** - *

    Represents a class ID (16 bytes). Unlike other little-endian - * type the {@link ClassID} is not just 16 bytes stored in the wrong - * order. Instead, it is a double word (4 bytes) followed by two - * words (2 bytes each) followed by 8 bytes.

    - */ -public class ClassID -{ - public static final ClassID OLE10_PACKAGE = new ClassID("{0003000C-0000-0000-C000-000000000046}"); - public static final ClassID PPT_SHOW = new ClassID("{64818D10-4F9B-11CF-86EA-00AA00B929E8}"); - public static final ClassID XLS_WORKBOOK = new ClassID("{00020841-0000-0000-C000-000000000046}"); - public static final ClassID TXT_ONLY = new ClassID("{5e941d80-bf96-11cd-b579-08002b30bfeb}"); - public static final ClassID EXCEL97 = new ClassID("{00020820-0000-0000-C000-000000000046}"); - public static final ClassID EXCEL95 = new ClassID("{00020810-0000-0000-C000-000000000046}"); - public static final ClassID WORD97 = new ClassID("{00020906-0000-0000-C000-000000000046}"); - public static final ClassID WORD95 = new ClassID("{00020900-0000-0000-C000-000000000046}"); - public static final ClassID POWERPOINT97 = new ClassID("{64818D10-4F9B-11CF-86EA-00AA00B929E8}"); - public static final ClassID POWERPOINT95 = new ClassID("{EA7BAE70-FB3B-11CD-A903-00AA00510EA3}"); - public static final ClassID EQUATION30 = new ClassID("{0002CE02-0000-0000-C000-000000000046}"); - - - /** - *

    The bytes making out the class ID in correct order, - * i.e. big-endian.

    - */ - protected byte[] bytes; - - - - /** - *

    Creates a {@link ClassID} and reads its value from a byte - * array.

    - * - * @param src The byte array to read from. - * @param offset The offset of the first byte to read. - */ - public ClassID(final byte[] src, final int offset) - { - read(src, offset); - } - - - /** - *

    Creates a {@link ClassID} and initializes its value with - * 0x00 bytes.

    - */ - public ClassID() - { - bytes = new byte[LENGTH]; - for (int i = 0; i < LENGTH; i++) - bytes[i] = 0x00; - } - - - /** - *

    Creates a {@link ClassID} from a human-readable representation of the Class ID in standard - * format "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".

    - * - * @param externalForm representation of the Class ID represented by this object. - */ - public ClassID(String externalForm) { - bytes = new byte[LENGTH]; - String clsStr = externalForm.replaceAll("[{}-]", ""); - for (int i=0; iThe number of bytes occupied by this object in the byte - * stream.

    */ - public static final int LENGTH = 16; - - /** - * @return The number of bytes occupied by this object in the byte - * stream. - */ - public int length() - { - return LENGTH; - } - - - - /** - *

    Gets the bytes making out the class ID. They are returned in - * correct order, i.e. big-endian.

    - * - * @return the bytes making out the class ID. - */ - public byte[] getBytes() - { - return bytes; - } - - - - /** - *

    Sets the bytes making out the class ID.

    - * - * @param bytes The bytes making out the class ID in big-endian format. They - * are copied without their order being changed. - */ - public void setBytes(final byte[] bytes) - { - for (int i = 0; i < this.bytes.length; i++) - this.bytes[i] = bytes[i]; - } - - - - /** - *

    Reads the class ID's value from a byte array by turning - * little-endian into big-endian.

    - * - * @param src The byte array to read from - * - * @param offset The offset within the src byte array - * - * @return A byte array containing the class ID. - */ - public byte[] read(final byte[] src, final int offset) - { - bytes = new byte[16]; - - /* Read double word. */ - bytes[0] = src[3 + offset]; - bytes[1] = src[2 + offset]; - bytes[2] = src[1 + offset]; - bytes[3] = src[0 + offset]; - - /* Read first word. */ - bytes[4] = src[5 + offset]; - bytes[5] = src[4 + offset]; - - /* Read second word. */ - bytes[6] = src[7 + offset]; - bytes[7] = src[6 + offset]; - - /* Read 8 bytes. */ - for (int i = 8; i < 16; i++) - bytes[i] = src[i + offset]; - - return bytes; - } - - - - /** - *

    Writes the class ID to a byte array in the - * little-endian format.

    - * - * @param dst The byte array to write to. - * - * @param offset The offset within the dst byte array. - * - * @exception ArrayStoreException if there is not enough room for the class - * ID 16 bytes in the byte array after the offset position. - */ - public void write(final byte[] dst, final int offset) - throws ArrayStoreException - { - /* Check array size: */ - if (dst.length < 16) - throw new ArrayStoreException - ("Destination byte[] must have room for at least 16 bytes, " + - "but has a length of only " + dst.length + "."); - /* Write double word. */ - dst[0 + offset] = bytes[3]; - dst[1 + offset] = bytes[2]; - dst[2 + offset] = bytes[1]; - dst[3 + offset] = bytes[0]; - - /* Write first word. */ - dst[4 + offset] = bytes[5]; - dst[5 + offset] = bytes[4]; - - /* Write second word. */ - dst[6 + offset] = bytes[7]; - dst[7 + offset] = bytes[6]; - - /* Write 8 bytes. */ - for (int i = 8; i < 16; i++) - dst[i + offset] = bytes[i]; - } - - - - /** - *

    Checks whether this ClassID is equal to another - * object.

    - * - * @param o the object to compare this PropertySet with - * @return true if the objects are equal, else - * false. - */ - @Override - public boolean equals(final Object o) - { - if (o == null || !(o instanceof ClassID)) - return false; - final ClassID cid = (ClassID) o; - if (bytes.length != cid.bytes.length) - return false; - for (int i = 0; i < bytes.length; i++) - if (bytes[i] != cid.bytes[i]) - return false; - return true; - } - - - - /** - * @see Object#hashCode() - */ - @Override - public int hashCode() - { - return new String(bytes, StringUtil.UTF8).hashCode(); - } - - /** - *

    Returns a human-readable representation of the Class ID in standard - * format "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".

    - * - * @return String representation of the Class ID represented by this object. - */ - @Override - public String toString() - { - StringBuffer sbClassId = new StringBuffer(38); - sbClassId.append('{'); - for (int i = 0; i < 16; i++) - { - sbClassId.append(HexDump.toHex(bytes[i])); - if (i == 3 || i == 5 || i == 7 || i == 9) - sbClassId.append('-'); - } - sbClassId.append('}'); - return sbClassId.toString(); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/ClipboardData.java b/trunk/src/java/org/apache/poi/hpsf/ClipboardData.java deleted file mode 100644 index 42ce724a9..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/ClipboardData.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -@Internal -class ClipboardData -{ - private static final POILogger logger = POILogFactory - .getLogger( ClipboardData.class ); - - private int _format; - private byte[] _value; - - ClipboardData( byte[] data, int offset ) - { - int size = LittleEndian.getInt( data, offset ); - - if ( size < 4 ) - { - logger.log( POILogger.WARN, "ClipboardData at offset ", - Integer.valueOf( offset ), " size less than 4 bytes " - + "(doesn't even have format field!). " - + "Setting to format == 0 and hope for the best" ); - _format = 0; - _value = new byte[0]; - return; - } - - _format = LittleEndian.getInt( data, offset + LittleEndian.INT_SIZE ); - _value = LittleEndian.getByteArray( data, offset - + LittleEndian.INT_SIZE * 2, size - LittleEndian.INT_SIZE ); - } - - int getSize() - { - return LittleEndian.INT_SIZE * 2 + _value.length; - } - - byte[] getValue() - { - return _value; - } - - byte[] toByteArray() - { - byte[] result = new byte[getSize()]; - LittleEndian.putInt( result, 0 * LittleEndian.INT_SIZE, - LittleEndian.INT_SIZE + _value.length ); - LittleEndian.putInt( result, 1 * LittleEndian.INT_SIZE, _format ); - System.arraycopy( _value, 0, result, LittleEndian.INT_SIZE - + LittleEndian.INT_SIZE, _value.length ); - return result; - } - - int write( OutputStream out ) throws IOException - { - LittleEndian.putInt( LittleEndian.INT_SIZE + _value.length, out ); - LittleEndian.putInt( _format, out ); - out.write( _value ); - return 2 * LittleEndian.INT_SIZE + _value.length; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/CodePageString.java b/trunk/src/java/org/apache/poi/hpsf/CodePageString.java deleted file mode 100644 index 8eb8987b3..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/CodePageString.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -@Internal -class CodePageString -{ - private final static POILogger logger = POILogFactory - .getLogger( CodePageString.class ); - - private byte[] _value; - - CodePageString( final byte[] data, final int startOffset ) - { - int offset = startOffset; - - int size = LittleEndian.getInt( data, offset ); - offset += LittleEndian.INT_SIZE; - - _value = LittleEndian.getByteArray( data, offset, size ); - if ( size != 0 && _value[size - 1] != 0 ) { - // TODO Some files, such as TestVisioWithCodepage.vsd, are currently - // triggering this for values that don't look like codepages - // See Bug #52258 for details - logger.log(POILogger.WARN, "CodePageString started at offset #" + offset - + " is not NULL-terminated" ); -// throw new IllegalPropertySetDataException( -// "CodePageString started at offset #" + offset -// + " is not NULL-terminated" ); - } - } - - CodePageString( String string, int codepage ) - throws UnsupportedEncodingException - { - setJavaValue( string, codepage ); - } - - String getJavaValue( int codepage ) throws UnsupportedEncodingException - { - String result; - if ( codepage == -1 ) - result = new String( _value, StringUtil.UTF8 ); - else - result = CodePageUtil.getStringFromCodePage(_value, codepage); - final int terminator = result.indexOf( '\0' ); - if ( terminator == -1 ) - { - logger.log( - POILogger.WARN, - "String terminator (\\0) for CodePageString property value not found." - + "Continue without trimming and hope for the best." ); - return result; - } - if ( terminator != result.length() - 1 ) - { - logger.log( - POILogger.WARN, - "String terminator (\\0) for CodePageString property value occured before the end of string. " - + "Trimming and hope for the best." ); - } - return result.substring( 0, terminator ); - } - - int getSize() - { - return LittleEndian.INT_SIZE + _value.length; - } - - void setJavaValue( String string, int codepage ) - throws UnsupportedEncodingException - { - String stringNT = string + "\0"; - if ( codepage == -1 ) - _value = stringNT.getBytes(StringUtil.UTF8); - else - _value = CodePageUtil.getBytesInCodePage(stringNT, codepage); - } - - int write( OutputStream out ) throws IOException - { - LittleEndian.putInt( _value.length, out ); - out.write( _value ); - return LittleEndian.INT_SIZE + _value.length; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Currency.java b/trunk/src/java/org/apache/poi/hpsf/Currency.java deleted file mode 100644 index 8928a56a0..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Currency.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -@Internal -class Currency -{ - static final int SIZE = 8; - - private byte[] _value; - - Currency( byte[] data, int offset ) - { - _value = LittleEndian.getByteArray( data, offset, SIZE ); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/CustomProperties.java b/trunk/src/java/org/apache/poi/hpsf/CustomProperties.java deleted file mode 100644 index f305836fa..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/CustomProperties.java +++ /dev/null @@ -1,429 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hpsf.wellknown.PropertyIDMap; - -/** - *

    Maintains the instances of {@link CustomProperty} that belong to a - * {@link DocumentSummaryInformation}. The class maintains the names of the - * custom properties in a dictionary. It implements the {@link Map} interface - * and by this provides a simplified view on custom properties: A property's - * name is the key that maps to a typed value. This implementation hides - * property IDs from the developer and regards the property names as keys to - * typed values.

    - * - *

    While this class provides a simple API to custom properties, it ignores - * the fact that not names, but IDs are the real keys to properties. Under the - * hood this class maintains a 1:1 relationship between IDs and names. Therefore - * you should not use this class to process property sets with several IDs - * mapping to the same name or with properties without a name: the result will - * contain only a subset of the original properties. If you really need to deal - * such property sets, use HPSF's low-level access methods.

    - * - *

    An application can call the {@link #isPure} method to check whether a - * property set parsed by {@link CustomProperties} is still pure (i.e. - * unmodified) or whether one or more properties have been dropped.

    - * - *

    This class is not thread-safe; concurrent access to instances of this - * class must be synchronized.

    - * - *

    While this class is roughly HashMap<Long,CustomProperty>, that's the - * internal representation. To external calls, it should appear as - * HashMap<String,Object> mapping between Names and Custom Property Values.

    - */ -@SuppressWarnings("serial") -public class CustomProperties extends HashMap -{ - - /** - *

    Maps property IDs to property names.

    - */ - private final Map dictionaryIDToName = new HashMap(); - - /** - *

    Maps property names to property IDs.

    - */ - private final Map dictionaryNameToID = new HashMap(); - - /** - *

    Tells whether this object is pure or not.

    - */ - private boolean isPure = true; - - - /** - *

    Puts a {@link CustomProperty} into this map. It is assumed that the - * {@link CustomProperty} already has a valid ID. Otherwise use - * {@link #put(CustomProperty)}.

    - * - * @param name the property name - * @param cp the property - * - * @return the previous property stored under this name - */ - public CustomProperty put(final String name, final CustomProperty cp) - { - if (name == null) - { - /* Ignoring a property without a name. */ - isPure = false; - return null; - } - if (!(name.equals(cp.getName()))) - throw new IllegalArgumentException("Parameter \"name\" (" + name + - ") and custom property's name (" + cp.getName() + - ") do not match."); - - /* Register name and ID in the dictionary. Mapping in both directions is possible. If there is already a */ - final Long idKey = Long.valueOf(cp.getID()); - final Long oldID = dictionaryNameToID.get(name); - dictionaryIDToName.remove(oldID); - dictionaryNameToID.put(name, idKey); - dictionaryIDToName.put(idKey, name); - - /* Put the custom property into this map. */ - final CustomProperty oldCp = super.remove(oldID); - super.put(idKey, cp); - return oldCp; - } - - - - /** - *

    Puts a {@link CustomProperty} that has not yet a valid ID into this - * map. The method will allocate a suitable ID for the custom property:

    - * - *
      - * - *
    • If there is already a property with the same name, take the ID - * of that property.

    • - * - *
    • Otherwise find the highest ID and use its value plus one.

    • - * - *
    - * - * @param customProperty - * @return If the was already a property with the same name, the - * @throws ClassCastException - */ - private Object put(final CustomProperty customProperty) throws ClassCastException - { - final String name = customProperty.getName(); - - /* Check whether a property with this name is in the map already. */ - final Long oldId = dictionaryNameToID.get(name); - if (oldId != null) - customProperty.setID(oldId.longValue()); - else - { - long max = 1; - for (Long long1 : dictionaryIDToName.keySet()) { - final long id = long1.longValue(); - if (id > max) - max = id; - } - customProperty.setID(max + 1); - } - return this.put(name, customProperty); - } - - - - /** - *

    Removes a custom property.

    - * @param name The name of the custom property to remove - * @return The removed property or null if the specified property was not found. - * - * @see java.util.HashSet#remove(java.lang.Object) - */ - public Object remove(final String name) - { - final Long id = dictionaryNameToID.get(name); - if (id == null) - return null; - dictionaryIDToName.remove(id); - dictionaryNameToID.remove(name); - return super.remove(id); - } - - /** - *

    Adds a named string property.

    - * - * @param name The property's name. - * @param value The property's value. - * @return the property that was stored under the specified name before, or - * null if there was no such property before. - */ - public Object put(final String name, final String value) - { - final MutableProperty p = new MutableProperty(); - p.setID(-1); - p.setType(Variant.VT_LPWSTR); - p.setValue(value); - final CustomProperty cp = new CustomProperty(p, name); - return put(cp); - } - - /** - *

    Adds a named long property.

    - * - * @param name The property's name. - * @param value The property's value. - * @return the property that was stored under the specified name before, or - * null if there was no such property before. - */ - public Object put(final String name, final Long value) - { - final MutableProperty p = new MutableProperty(); - p.setID(-1); - p.setType(Variant.VT_I8); - p.setValue(value); - final CustomProperty cp = new CustomProperty(p, name); - return put(cp); - } - - /** - *

    Adds a named double property.

    - * - * @param name The property's name. - * @param value The property's value. - * @return the property that was stored under the specified name before, or - * null if there was no such property before. - */ - public Object put(final String name, final Double value) - { - final MutableProperty p = new MutableProperty(); - p.setID(-1); - p.setType(Variant.VT_R8); - p.setValue(value); - final CustomProperty cp = new CustomProperty(p, name); - return put(cp); - } - - /** - *

    Adds a named integer property.

    - * - * @param name The property's name. - * @param value The property's value. - * @return the property that was stored under the specified name before, or - * null if there was no such property before. - */ - public Object put(final String name, final Integer value) - { - final MutableProperty p = new MutableProperty(); - p.setID(-1); - p.setType(Variant.VT_I4); - p.setValue(value); - final CustomProperty cp = new CustomProperty(p, name); - return put(cp); - } - - /** - *

    Adds a named boolean property.

    - * - * @param name The property's name. - * @param value The property's value. - * @return the property that was stored under the specified name before, or - * null if there was no such property before. - */ - public Object put(final String name, final Boolean value) - { - final MutableProperty p = new MutableProperty(); - p.setID(-1); - p.setType(Variant.VT_BOOL); - p.setValue(value); - final CustomProperty cp = new CustomProperty(p, name); - return put(cp); - } - - - /** - *

    Gets a named value from the custom properties.

    - * - * @param name the name of the value to get - * @return the value or null if a value with the specified - * name is not found in the custom properties. - */ - public Object get(final String name) - { - final Long id = dictionaryNameToID.get(name); - final CustomProperty cp = super.get(id); - return cp != null ? cp.getValue() : null; - } - - - - /** - *

    Adds a named date property.

    - * - * @param name The property's name. - * @param value The property's value. - * @return the property that was stored under the specified name before, or - * null if there was no such property before. - */ - public Object put(final String name, final Date value) - { - final MutableProperty p = new MutableProperty(); - p.setID(-1); - p.setType(Variant.VT_FILETIME); - p.setValue(value); - final CustomProperty cp = new CustomProperty(p, name); - return put(cp); - } - - /** - * Returns a set of all the names of our custom properties. - * Equivalent to {@link #nameSet()} - * - * @return a set of all the names of our custom properties - */ - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Set keySet() { - return dictionaryNameToID.keySet(); - } - - /** - * Returns a set of all the names of our custom properties - * - * @return a set of all the names of our custom properties - */ - public Set nameSet() { - return dictionaryNameToID.keySet(); - } - - /** - * Returns a set of all the IDs of our custom properties - * - * @return a set of all the IDs of our custom properties - */ - public Set idSet() { - return dictionaryNameToID.keySet(); - } - - - /** - *

    Sets the codepage.

    - * - * @param codepage the codepage - */ - public void setCodepage(final int codepage) - { - final MutableProperty p = new MutableProperty(); - p.setID(PropertyIDMap.PID_CODEPAGE); - p.setType(Variant.VT_I2); - p.setValue(Integer.valueOf(codepage)); - put(new CustomProperty(p)); - } - - - - /** - *

    Gets the dictionary which contains IDs and names of the named custom - * properties. - * - * @return the dictionary. - */ - Map getDictionary() - { - return dictionaryIDToName; - } - - - /** - * Checks against both String Name and Long ID - */ - @Override - public boolean containsKey(Object key) { - if(key instanceof Long) { - return super.containsKey(key); - } - if(key instanceof String) { - return super.containsKey(dictionaryNameToID.get(key)); - } - return false; - } - - /** - * Checks against both the property, and its values. - */ - @Override - public boolean containsValue(Object value) { - if(value instanceof CustomProperty) { - return super.containsValue(value); - } else { - for(CustomProperty cp : super.values()) { - if(cp.getValue() == value) { - return true; - } - } - } - return false; - } - - - - /** - *

    Gets the codepage.

    - * - * @return the codepage or -1 if the codepage is undefined. - */ - public int getCodepage() - { - int codepage = -1; - for (final Iterator i = this.values().iterator(); codepage == -1 && i.hasNext();) - { - final CustomProperty cp = i.next(); - if (cp.getID() == PropertyIDMap.PID_CODEPAGE) - codepage = ((Integer) cp.getValue()).intValue(); - } - return codepage; - } - - - - /** - *

    Tells whether this {@link CustomProperties} instance is pure or one or - * more properties of the underlying low-level property set has been - * dropped.

    - * - * @return true if the {@link CustomProperties} is pure, else - * false. - */ - public boolean isPure() - { - return isPure; - } - - /** - *

    Sets the purity of the custom property set.

    - * - * @param isPure the purity - */ - public void setPure(final boolean isPure) - { - this.isPure = isPure; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/CustomProperty.java b/trunk/src/java/org/apache/poi/hpsf/CustomProperty.java deleted file mode 100644 index a256d94d3..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/CustomProperty.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This class represents custom properties in the document summary - * information stream. The difference to normal properties is that custom - * properties have an optional name. If the name is not null it - * will be maintained in the section's dictionary.

    - */ -public class CustomProperty extends MutableProperty -{ - - private String name; - - /** - *

    Creates an empty {@link CustomProperty}. The set methods must be - * called to make it usable.

    - */ - public CustomProperty() - { - this.name = null; - } - - /** - *

    Creates a {@link CustomProperty} without a name by copying the - * underlying {@link Property}' attributes.

    - * - * @param property the property to copy - */ - public CustomProperty(final Property property) - { - this(property, null); - } - - /** - *

    Creates a {@link CustomProperty} with a name.

    - * - * @param property This property's attributes are copied to the new custom - * property. - * @param name The new custom property's name. - */ - public CustomProperty(final Property property, final String name) - { - super(property); - this.name = name; - } - - /** - *

    Gets the property's name.

    - * - * @return the property's name. - */ - public String getName() - { - return name; - } - - /** - *

    Sets the property's name.

    - * - * @param name The name to set. - */ - public void setName(final String name) - { - this.name = name; - } - - - /** - *

    Compares two custom properties for equality. The method returns - * true if all attributes of the two custom properties are - * equal.

    - * - * @param o The custom property to compare with. - * @return true if both custom properties are equal, else - * false. - * - * @see java.util.AbstractSet#equals(java.lang.Object) - */ - public boolean equalsContents(final Object o) - { - final CustomProperty c = (CustomProperty) o; - final String name1 = c.getName(); - final String name2 = this.getName(); - boolean equalNames = true; - if (name1 == null) - equalNames = name2 == null; - else - equalNames = name1.equals(name2); - return equalNames && c.getID() == this.getID() - && c.getType() == this.getType() - && c.getValue().equals(this.getValue()); - } - - /** - * @see java.util.AbstractSet#hashCode() - */ - @Override - public int hashCode() - { - return (int) this.getID(); - } - - @Override - public boolean equals(Object o) { - return (o instanceof CustomProperty) ? equalsContents(o) : false; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Date.java b/trunk/src/java/org/apache/poi/hpsf/Date.java deleted file mode 100644 index 237420fcc..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Date.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -@Internal -class Date -{ - static final int SIZE = 8; - - private byte[] _value; - - Date( byte[] data, int offset ) - { - _value = LittleEndian.getByteArray( data, offset, SIZE ); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Decimal.java b/trunk/src/java/org/apache/poi/hpsf/Decimal.java deleted file mode 100644 index d8c404c31..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Decimal.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -@Internal -class Decimal -{ - static final int SIZE = 16; - - /** - * Findbugs: UNR_UNREAD_FIELD - */ - private short field_1_wReserved; - private byte field_2_scale; - private byte field_3_sign; - private int field_4_hi32; - private long field_5_lo64; - - Decimal( final byte[] data, final int startOffset ) - { - int offset = startOffset; - - field_1_wReserved = LittleEndian.getShort( data, offset ); - offset += LittleEndian.SHORT_SIZE; - - field_2_scale = data[offset]; - offset += LittleEndian.BYTE_SIZE; - - field_3_sign = data[offset]; - offset += LittleEndian.BYTE_SIZE; - - field_4_hi32 = LittleEndian.getInt( data, offset ); - offset += LittleEndian.INT_SIZE; - - field_5_lo64 = LittleEndian.getLong( data, offset ); - offset += LittleEndian.LONG_SIZE; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/DocumentSummaryInformation.java b/trunk/src/java/org/apache/poi/hpsf/DocumentSummaryInformation.java deleted file mode 100644 index 0f8c629cf..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/DocumentSummaryInformation.java +++ /dev/null @@ -1,928 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.util.Iterator; -import java.util.Map; - -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.hpsf.wellknown.SectionIDMap; -import org.apache.poi.util.CodePageUtil; - -/** - *

    Convenience class representing a DocumentSummary Information stream in a - * Microsoft Office document.

    - * - * @see SummaryInformation - */ -public class DocumentSummaryInformation extends SpecialPropertySet -{ - /** - *

    The document name a document summary information stream - * usually has in a POIFS filesystem.

    - */ - public static final String DEFAULT_STREAM_NAME = - "\005DocumentSummaryInformation"; - - @Override - public PropertyIDMap getPropertySetIDMap() { - return PropertyIDMap.getDocumentSummaryInformationProperties(); - } - - - /** - *

    Creates a {@link DocumentSummaryInformation} from a given - * {@link PropertySet}.

    - * - * @param ps A property set which should be created from a - * document summary information stream. - * @throws UnexpectedPropertySetTypeException if ps - * does not contain a document summary information stream. - */ - public DocumentSummaryInformation(final PropertySet ps) - throws UnexpectedPropertySetTypeException - { - super(ps); - if (!isDocumentSummaryInformation()) - throw new UnexpectedPropertySetTypeException - ("Not a " + getClass().getName()); - } - - - /** - *

    Returns the category (or {@code null}).

    - * - * @return The category value - */ - public String getCategory() - { - return getPropertyStringValue(PropertyIDMap.PID_CATEGORY); - } - - /** - *

    Sets the category.

    - * - * @param category The category to set. - */ - public void setCategory(final String category) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_CATEGORY, category); - } - - /** - *

    Removes the category.

    - */ - public void removeCategory() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_CATEGORY); - } - - - - /** - *

    Returns the presentation format (or - * {@code null}).

    - * - * @return The presentation format value - */ - public String getPresentationFormat() - { - return getPropertyStringValue(PropertyIDMap.PID_PRESFORMAT); - } - - /** - *

    Sets the presentation format.

    - * - * @param presentationFormat The presentation format to set. - */ - public void setPresentationFormat(final String presentationFormat) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_PRESFORMAT, presentationFormat); - } - - /** - *

    Removes the presentation format.

    - */ - public void removePresentationFormat() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_PRESFORMAT); - } - - - - /** - *

    Returns the byte count or 0 if the {@link - * DocumentSummaryInformation} does not contain a byte count.

    - * - * @return The byteCount value - */ - public int getByteCount() - { - return getPropertyIntValue(PropertyIDMap.PID_BYTECOUNT); - } - - /** - *

    Sets the byte count.

    - * - * @param byteCount The byte count to set. - */ - public void setByteCount(final int byteCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_BYTECOUNT, byteCount); - } - - /** - *

    Removes the byte count.

    - */ - public void removeByteCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_BYTECOUNT); - } - - - - /** - *

    Returns the line count or 0 if the {@link - * DocumentSummaryInformation} does not contain a line count.

    - * - * @return The line count value - */ - public int getLineCount() - { - return getPropertyIntValue(PropertyIDMap.PID_LINECOUNT); - } - - /** - *

    Sets the line count.

    - * - * @param lineCount The line count to set. - */ - public void setLineCount(final int lineCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_LINECOUNT, lineCount); - } - - /** - *

    Removes the line count.

    - */ - public void removeLineCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_LINECOUNT); - } - - - - /** - *

    Returns the par count or 0 if the {@link - * DocumentSummaryInformation} does not contain a par count.

    - * - * @return The par count value - */ - public int getParCount() - { - return getPropertyIntValue(PropertyIDMap.PID_PARCOUNT); - } - - /** - *

    Sets the par count.

    - * - * @param parCount The par count to set. - */ - public void setParCount(final int parCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_PARCOUNT, parCount); - } - - /** - *

    Removes the par count.

    - */ - public void removeParCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_PARCOUNT); - } - - - - /** - *

    Returns the slide count or 0 if the {@link - * DocumentSummaryInformation} does not contain a slide count.

    - * - * @return The slide count value - */ - public int getSlideCount() - { - return getPropertyIntValue(PropertyIDMap.PID_SLIDECOUNT); - } - - /** - *

    Sets the slideCount.

    - * - * @param slideCount The slide count to set. - */ - public void setSlideCount(final int slideCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_SLIDECOUNT, slideCount); - } - - /** - *

    Removes the slide count.

    - */ - public void removeSlideCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_SLIDECOUNT); - } - - - - /** - *

    Returns the note count or 0 if the {@link - * DocumentSummaryInformation} does not contain a note count.

    - * - * @return The note count value - */ - public int getNoteCount() - { - return getPropertyIntValue(PropertyIDMap.PID_NOTECOUNT); - } - - /** - *

    Sets the note count.

    - * - * @param noteCount The note count to set. - */ - public void setNoteCount(final int noteCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_NOTECOUNT, noteCount); - } - - /** - *

    Removes the noteCount.

    - */ - public void removeNoteCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_NOTECOUNT); - } - - - - /** - *

    Returns the hidden count or 0 if the {@link - * DocumentSummaryInformation} does not contain a hidden - * count.

    - * - * @return The hidden count value - */ - public int getHiddenCount() - { - return getPropertyIntValue(PropertyIDMap.PID_HIDDENCOUNT); - } - - /** - *

    Sets the hidden count.

    - * - * @param hiddenCount The hidden count to set. - */ - public void setHiddenCount(final int hiddenCount) - { - final MutableSection s = (MutableSection) getSections().get(0); - s.setProperty(PropertyIDMap.PID_HIDDENCOUNT, hiddenCount); - } - - /** - *

    Removes the hidden count.

    - */ - public void removeHiddenCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_HIDDENCOUNT); - } - - - - /** - *

    Returns the mmclip count or 0 if the {@link - * DocumentSummaryInformation} does not contain a mmclip - * count.

    - * - * @return The mmclip count value - */ - public int getMMClipCount() - { - return getPropertyIntValue(PropertyIDMap.PID_MMCLIPCOUNT); - } - - /** - *

    Sets the mmclip count.

    - * - * @param mmClipCount The mmclip count to set. - */ - public void setMMClipCount(final int mmClipCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_MMCLIPCOUNT, mmClipCount); - } - - /** - *

    Removes the mmclip count.

    - */ - public void removeMMClipCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_MMCLIPCOUNT); - } - - - - /** - *

    Returns true when scaling of the thumbnail is - * desired, false if cropping is desired.

    - * - * @return The scale value - */ - public boolean getScale() - { - return getPropertyBooleanValue(PropertyIDMap.PID_SCALE); - } - - /** - *

    Sets the scale.

    - * - * @param scale The scale to set. - */ - public void setScale(final boolean scale) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_SCALE, scale); - } - - /** - *

    Removes the scale.

    - */ - public void removeScale() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_SCALE); - } - - - - /** - *

    Returns the heading pair (or {@code null}) - * when this method is implemented. Please note that the - * return type is likely to change! - * - * @return The heading pair value - */ - public byte[] getHeadingPair() - { - notYetImplemented("Reading byte arrays "); - return (byte[]) getProperty(PropertyIDMap.PID_HEADINGPAIR); - } - - /** - *

    Sets the heading pair.

    - * - * @param headingPair The heading pair to set. - */ - public void setHeadingPair(final byte[] headingPair) - { - notYetImplemented("Writing byte arrays "); - } - - /** - *

    Removes the heading pair.

    - */ - public void removeHeadingPair() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_HEADINGPAIR); - } - - - - /** - *

    Returns the doc parts (or {@code null}) - * when this method is implemented. Please note that the - * return type is likely to change! - * - * @return The doc parts value - */ - public byte[] getDocparts() - { - notYetImplemented("Reading byte arrays"); - return (byte[]) getProperty(PropertyIDMap.PID_DOCPARTS); - } - - - - /** - *

    Sets the doc parts.

    - * - * @param docparts The doc parts to set. - */ - public void setDocparts(final byte[] docparts) - { - notYetImplemented("Writing byte arrays"); - } - - /** - *

    Removes the doc parts.

    - */ - public void removeDocparts() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_DOCPARTS); - } - - - - /** - *

    Returns the manager (or {@code null}).

    - * - * @return The manager value - */ - public String getManager() - { - return getPropertyStringValue(PropertyIDMap.PID_MANAGER); - } - - /** - *

    Sets the manager.

    - * - * @param manager The manager to set. - */ - public void setManager(final String manager) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_MANAGER, manager); - } - - /** - *

    Removes the manager.

    - */ - public void removeManager() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_MANAGER); - } - - - - /** - *

    Returns the company (or {@code null}).

    - * - * @return The company value - */ - public String getCompany() - { - return getPropertyStringValue(PropertyIDMap.PID_COMPANY); - } - - /** - *

    Sets the company.

    - * - * @param company The company to set. - */ - public void setCompany(final String company) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_COMPANY, company); - } - - /** - *

    Removes the company.

    - */ - public void removeCompany() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_COMPANY); - } - - - /** - *

    Returns true if the custom links are dirty.

    - * - * @return The links dirty value - */ - public boolean getLinksDirty() - { - return getPropertyBooleanValue(PropertyIDMap.PID_LINKSDIRTY); - } - - /** - *

    Sets the linksDirty.

    - * - * @param linksDirty The links dirty value to set. - */ - public void setLinksDirty(final boolean linksDirty) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_LINKSDIRTY, linksDirty); - } - - /** - *

    Removes the links dirty.

    - */ - public void removeLinksDirty() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_LINKSDIRTY); - } - - - /** - *

    Returns the character count including whitespace, or 0 if the - * {@link DocumentSummaryInformation} does not contain this char count.

    - *

    This is the whitespace-including version of {@link SummaryInformation#getCharCount()} - * - * @return The character count or {@code null} - */ - public int getCharCountWithSpaces() - { - return getPropertyIntValue(PropertyIDMap.PID_CCHWITHSPACES); - } - - /** - * Sets the character count including whitespace - * - * @param count The character count to set. - */ - public void setCharCountWithSpaces(int count) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_CCHWITHSPACES, count); - } - - /** - * Removes the character count - */ - public void removeCharCountWithSpaces() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_CCHWITHSPACES); - } - - - /** - * Get if the User Defined Property Set has been updated outside of the - * Application.

    - * If it has (true), the hyperlinks should be updated on document load. - * - * @return true, if the hyperlinks should be updated on document load - */ - public boolean getHyperlinksChanged() - { - return getPropertyBooleanValue(PropertyIDMap.PID_HYPERLINKSCHANGED); - } - - /** - * Set the flag for if the User Defined Property Set has been updated outside - * of the Application. - * - * @param changed true, if the User Defined Property Set has been updated - */ - public void setHyperlinksChanged(boolean changed) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_HYPERLINKSCHANGED, changed); - } - - /** - * Removes the flag for if the User Defined Property Set has been updated - * outside of the Application. - */ - public void removeHyperlinksChanged() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_HYPERLINKSCHANGED); - } - - - /** - * Gets the version of the Application which wrote the - * Property set, stored with the two high order bytes having the major - * version number, and the two low order bytes the minor version number.

    - * This will be 0 if no version is set. - * - * @return the Application version - */ - public int getApplicationVersion() - { - return getPropertyIntValue(PropertyIDMap.PID_VERSION); - } - - /** - * Sets the Application version, which must be a 4 byte int with - * the two high order bytes having the major version number, and the - * two low order bytes the minor version number. - * - * @param version the Application version - */ - public void setApplicationVersion(int version) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_VERSION, version); - } - - /** - * Removes the Application Version - */ - public void removeApplicationVersion() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_VERSION); - } - - - /** - * Returns the VBA digital signature for the VBA project - * embedded in the document (or {@code null}). - * - * @return the VBA digital signature - */ - public byte[] getVBADigitalSignature() - { - Object value = getProperty(PropertyIDMap.PID_DIGSIG); - if (value != null && value instanceof byte[]) { - return (byte[])value; - } - return null; - } - - /** - *

    Sets the VBA digital signature for the VBA project - * embedded in the document.

    - * - * @param signature VBA Digital Signature for the project - */ - public void setVBADigitalSignature(byte[] signature) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_DIGSIG, signature); - } - - /** - * Removes the VBA Digital Signature - */ - public void removeVBADigitalSignature() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_DIGSIG); - } - - - /** - * Gets the content type of the file (or {@code null}). - * - * @return the content type of the file - */ - public String getContentType() - { - return getPropertyStringValue(PropertyIDMap.PID_CONTENTTYPE); - } - - /** - * Sets the content type of the file - * - * @param type the content type of the file - */ - public void setContentType(String type) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_CONTENTTYPE, type); - } - - /** - * Removes the content type of the file - */ - public void removeContentType() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_CONTENTTYPE); - } - - - /** - * Gets the content status of the file (or {@code null}). - * - * @return the content status of the file - */ - public String getContentStatus() - { - return getPropertyStringValue(PropertyIDMap.PID_CONTENTSTATUS); - } - - /** - * Sets the content status of the file - * - * @param status the content status of the file - */ - public void setContentStatus(String status) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_CONTENTSTATUS, status); - } - - /** - * Removes the content status of the file - */ - public void removeContentStatus() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_CONTENTSTATUS); - } - - - /** - * Gets the document language, which is normally unset and empty (or {@code null}). - * - * @return the document language - */ - public String getLanguage() - { - return getPropertyStringValue(PropertyIDMap.PID_LANGUAGE); - } - - /** - * Set the document language - * - * @param language the document language - */ - public void setLanguage(String language) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_LANGUAGE, language); - } - - /** - * Removes the document language - */ - public void removeLanguage() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_LANGUAGE); - } - - - /** - *

    Gets the document version as a string, which is normally unset and empty - * (or {@code null}).

    - * - * @return the document verion - */ - public String getDocumentVersion() - { - return getPropertyStringValue(PropertyIDMap.PID_DOCVERSION); - } - - /** - * Sets the document version string - * - * @param version the document version string - */ - public void setDocumentVersion(String version) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_DOCVERSION, version); - } - - /** - * Removes the document version string - */ - public void removeDocumentVersion() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_DOCVERSION); - } - - - /** - *

    Gets the custom properties.

    - * - * @return The custom properties. - */ - public CustomProperties getCustomProperties() - { - CustomProperties cps = null; - if (getSectionCount() >= 2) - { - cps = new CustomProperties(); - final Section section = getSections().get(1); - final Map dictionary = section.getDictionary(); - final Property[] properties = section.getProperties(); - int propertyCount = 0; - for (int i = 0; i < properties.length; i++) - { - final Property p = properties[i]; - final long id = p.getID(); - if (id != 0 && id != 1) - { - propertyCount++; - final CustomProperty cp = new CustomProperty(p, - dictionary.get(Long.valueOf(id))); - cps.put(cp.getName(), cp); - } - } - if (cps.size() != propertyCount) - cps.setPure(false); - } - return cps; - } - - /** - *

    Sets the custom properties.

    - * - * @param customProperties The custom properties - */ - public void setCustomProperties(final CustomProperties customProperties) - { - ensureSection2(); - final MutableSection section = (MutableSection) getSections().get(1); - final Map dictionary = customProperties.getDictionary(); - section.clear(); - - /* Set the codepage. If both custom properties and section have a - * codepage, the codepage from the custom properties wins, else take the - * one that is defined. If none is defined, take Unicode. */ - int cpCodepage = customProperties.getCodepage(); - if (cpCodepage < 0) - cpCodepage = section.getCodepage(); - if (cpCodepage < 0) - cpCodepage = CodePageUtil.CP_UNICODE; - customProperties.setCodepage(cpCodepage); - section.setCodepage(cpCodepage); - section.setDictionary(dictionary); - for (final Iterator i = customProperties.values().iterator(); i.hasNext();) - { - final Property p = i.next(); - section.setProperty(p); - } - } - - /** - *

    Creates section 2 if it is not already present.

    - * - */ - private void ensureSection2() - { - if (getSectionCount() < 2) - { - MutableSection s2 = new MutableSection(); - s2.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[1]); - addSection(s2); - } - } - - /** - *

    Removes the custom properties.

    - */ - public void removeCustomProperties() - { - if (getSectionCount() >= 2) - getSections().remove(1); - else - throw new HPSFRuntimeException("Illegal internal format of Document SummaryInformation stream: second section is missing."); - } - - - /** - *

    Throws an {@link UnsupportedOperationException} with a message text - * telling which functionality is not yet implemented.

    - * - * @param msg text telling was leaves to be implemented, e.g. - * "Reading byte arrays". - */ - private void notYetImplemented(final String msg) - { - throw new UnsupportedOperationException(msg + " is not yet implemented."); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Filetime.java b/trunk/src/java/org/apache/poi/hpsf/Filetime.java deleted file mode 100644 index 84a58bb1d..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Filetime.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -class Filetime -{ - static final int SIZE = LittleEndian.INT_SIZE * 2; - - private int _dwHighDateTime; - private int _dwLowDateTime; - - Filetime( byte[] data, int offset ) - { - _dwLowDateTime = LittleEndian.getInt( data, offset + 0 - * LittleEndian.INT_SIZE ); - _dwHighDateTime = LittleEndian.getInt( data, offset + 1 - * LittleEndian.INT_SIZE ); - } - - Filetime( int low, int high ) - { - _dwLowDateTime = low; - _dwHighDateTime = high; - } - - long getHigh() - { - return _dwHighDateTime; - } - - long getLow() - { - return _dwLowDateTime; - } - - byte[] toByteArray() - { - byte[] result = new byte[SIZE]; - LittleEndian.putInt( result, 0 * LittleEndian.INT_SIZE, _dwLowDateTime ); - LittleEndian - .putInt( result, 1 * LittleEndian.INT_SIZE, _dwHighDateTime ); - return result; - } - - int write( OutputStream out ) throws IOException - { - LittleEndian.putInt( _dwLowDateTime, out ); - LittleEndian.putInt( _dwHighDateTime, out ); - return SIZE; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/GUID.java b/trunk/src/java/org/apache/poi/hpsf/GUID.java deleted file mode 100644 index 4bbd7f341..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/GUID.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -@Internal -class GUID -{ - static final int SIZE = 16; - - private int _data1; - private short _data2; - private short _data3; - private long _data4; - - GUID( byte[] data, int offset ) - { - _data1 = LittleEndian.getInt( data, offset + 0 ); - _data2 = LittleEndian.getShort( data, offset + 4 ); - _data3 = LittleEndian.getShort( data, offset + 6 ); - _data4 = LittleEndian.getLong( data, offset + 8 ); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/HPSFException.java b/trunk/src/java/org/apache/poi/hpsf/HPSFException.java deleted file mode 100644 index abc3b8d9f..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/HPSFException.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is the superclass of all other checked exceptions thrown - * in this package. It supports a nested "reason" throwable, i.e. an exception - * that caused this one to be thrown.

    - */ -public class HPSFException extends Exception -{ - - /** - *

    The underlying reason for this exception - may be - * null.

    - * */ - private Throwable reason; - - - - /** - *

    Creates an {@link HPSFException}.

    - */ - public HPSFException() - { - super(); - } - - - - /** - *

    Creates an {@link HPSFException} with a message string.

    - * - * @param msg The message string. - */ - public HPSFException(final String msg) - { - super(msg); - } - - - - /** - *

    Creates a new {@link HPSFException} with a reason.

    - * - * @param reason The reason, i.e. a throwable that indirectly - * caused this exception. - */ - public HPSFException(final Throwable reason) - { - super(); - this.reason = reason; - } - - - - /** - *

    Creates an {@link HPSFException} with a message string and a - * reason.

    - * - * @param msg The message string. - * @param reason The reason, i.e. a throwable that indirectly - * caused this exception. - */ - public HPSFException(final String msg, final Throwable reason) - { - super(msg); - this.reason = reason; - } - - - - /** - *

    Returns the {@link Throwable} that caused this exception to - * be thrown or null if there was no such {@link - * Throwable}.

    - * - * @return The reason - */ - public Throwable getReason() - { - return reason; - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java b/trunk/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java deleted file mode 100644 index 79a91a4b6..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.POIDocument; -import org.apache.poi.poifs.filesystem.EntryUtils; -import org.apache.poi.poifs.filesystem.FilteringDirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * A version of {@link POIDocument} which allows access to the - * HPSF Properties, but no other document contents. - * Normally used when you want to read or alter the Document Properties, - * without affecting the rest of the file - */ -public class HPSFPropertiesOnlyDocument extends POIDocument { - public HPSFPropertiesOnlyDocument(NPOIFSFileSystem fs) { - super(fs.getRoot()); - } - public HPSFPropertiesOnlyDocument(OPOIFSFileSystem fs) { - super(fs); - } - public HPSFPropertiesOnlyDocument(POIFSFileSystem fs) { - super(fs); - } - - /** - * Write out to the currently open file the properties changes, but nothing else - */ - public void write() throws IOException { - NPOIFSFileSystem fs = directory.getFileSystem(); - - validateInPlaceWritePossible(); - writeProperties(fs, null); - fs.writeFilesystem(); - } - /** - * Write out, with any properties changes, but nothing else - */ - public void write(File newFile) throws IOException { - POIFSFileSystem fs = POIFSFileSystem.create(newFile); - try { - write(fs); - fs.writeFilesystem(); - } finally { - fs.close(); - } - } - /** - * Write out, with any properties changes, but nothing else - */ - public void write(OutputStream out) throws IOException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(); - try { - write(fs); - fs.writeFilesystem(out); - } finally { - fs.close(); - } - } - - private void write(NPOIFSFileSystem fs) throws IOException { - // For tracking what we've written out, so far - List excepts = new ArrayList(2); - - // Write out our HPFS properties, with any changes - writeProperties(fs, excepts); - - // Copy over everything else unchanged - FilteringDirectoryNode src = new FilteringDirectoryNode(directory, excepts); - FilteringDirectoryNode dest = new FilteringDirectoryNode(fs.getRoot(), excepts); - EntryUtils.copyNodes(src, dest); - - // Caller will save the resultant POIFSFileSystem to the stream/file - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/HPSFRuntimeException.java b/trunk/src/java/org/apache/poi/hpsf/HPSFRuntimeException.java deleted file mode 100644 index 984a316fc..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/HPSFRuntimeException.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - - -/** - *

    This exception is the superclass of all other unchecked - * exceptions thrown in this package. It supports a nested "reason" - * throwable, i.e. an exception that caused this one to be thrown.

    - */ -public class HPSFRuntimeException extends RuntimeException -{ - private static final long serialVersionUID = -7804271670232727159L; - /**

    The underlying reason for this exception - may be - * null.

    */ - private Throwable reason; - - - - /** - *

    Creates a new {@link HPSFRuntimeException}.

    - */ - public HPSFRuntimeException() - { - super(); - } - - - - /** - *

    Creates a new {@link HPSFRuntimeException} with a message - * string.

    - * - * @param msg The message string. - */ - public HPSFRuntimeException(final String msg) - { - super(msg); - } - - - - /** - *

    Creates a new {@link HPSFRuntimeException} with a - * reason.

    - * - * @param reason The reason, i.e. a throwable that indirectly - * caused this exception. - */ - public HPSFRuntimeException(final Throwable reason) - { - super(); - this.reason = reason; - } - - - - /** - *

    Creates a new {@link HPSFRuntimeException} with a message - * string and a reason.

    - * - * @param msg The message string. - * @param reason The reason, i.e. a throwable that indirectly - * caused this exception. - */ - public HPSFRuntimeException(final String msg, final Throwable reason) - { - super(msg); - this.reason = reason; - } - - - - /** - *

    Returns the {@link Throwable} that caused this exception to - * be thrown or null if there was no such {@link - * Throwable}.

    - * - * @return The reason - */ - public Throwable getReason() - { - return reason; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/IllegalPropertySetDataException.java b/trunk/src/java/org/apache/poi/hpsf/IllegalPropertySetDataException.java deleted file mode 100644 index 3217af958..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/IllegalPropertySetDataException.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown when there is an illegal value set in a - * {@link PropertySet}. For example, a {@link Variant#VT_BOOL} must - * have a value of -1 (true) or 0 (false). - * Any other value would trigger this exception. It supports a nested - * "reason" throwable, i.e. an exception that caused this one to be - * thrown.

    - * - * @author Drew Varner(Drew.Varner atDomain sc.edu) - */ -public class IllegalPropertySetDataException extends HPSFRuntimeException -{ - - /** - *

    Constructor

    - */ - public IllegalPropertySetDataException() - { - super(); - } - - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - */ - public IllegalPropertySetDataException(final String msg) - { - super(msg); - } - - - - /** - *

    Constructor

    - * - * @param reason This exception's underlying reason - */ - public IllegalPropertySetDataException(final Throwable reason) - { - super(reason); - } - - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - * @param reason This exception's underlying reason - */ - public IllegalPropertySetDataException(final String msg, - final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/IllegalVariantTypeException.java b/trunk/src/java/org/apache/poi/hpsf/IllegalVariantTypeException.java deleted file mode 100644 index b71ff4703..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/IllegalVariantTypeException.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import org.apache.poi.util.HexDump; - -/** - *

    This exception is thrown if HPSF encounters a variant type that is illegal - * in the current context.

    - */ -public class IllegalVariantTypeException extends VariantTypeException -{ - - /** - *

    Constructor

    - * - * @param variantType The unsupported variant type - * @param value The value - * @param msg A message string - */ - public IllegalVariantTypeException(final long variantType, - final Object value, final String msg) - { - super(variantType, value, msg); - } - - /** - *

    Constructor

    - * - * @param variantType The unsupported variant type - * @param value The value - */ - public IllegalVariantTypeException(final long variantType, - final Object value) - { - this(variantType, value, "The variant type " + variantType + " (" + - Variant.getVariantName(variantType) + ", " + - HexDump.toHex(variantType) + ") is illegal in this context."); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/IndirectPropertyName.java b/trunk/src/java/org/apache/poi/hpsf/IndirectPropertyName.java deleted file mode 100644 index fc09ca6e8..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/IndirectPropertyName.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; - -@Internal -class IndirectPropertyName -{ - private CodePageString _value; - - IndirectPropertyName( byte[] data, int offset ) //NOSONAR - { - _value = new CodePageString( data, offset ); - } - - int getSize() - { - return _value.getSize(); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/MarkUnsupportedException.java b/trunk/src/java/org/apache/poi/hpsf/MarkUnsupportedException.java deleted file mode 100644 index 450c892ab..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/MarkUnsupportedException.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if an {@link java.io.InputStream} does - * not support the {@link java.io.InputStream#mark} operation.

    - */ -public class MarkUnsupportedException extends HPSFException -{ - - /** - *

    Constructor

    - */ - public MarkUnsupportedException() - { - super(); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - */ - public MarkUnsupportedException(final String msg) - { - super(msg); - } - - - /** - *

    Constructor

    - * - * @param reason This exception's underlying reason - */ - public MarkUnsupportedException(final Throwable reason) - { - super(reason); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - * @param reason This exception's underlying reason - */ - public MarkUnsupportedException(final String msg, final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/MissingSectionException.java b/trunk/src/java/org/apache/poi/hpsf/MissingSectionException.java deleted file mode 100644 index f3e81cad2..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/MissingSectionException.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if one of the {@link PropertySet}'s - * convenience methods does not find a required {@link Section}.

    - * - *

    The constructors of this class are analogous to those of its - * superclass and documented there.

    - */ -public class MissingSectionException extends HPSFRuntimeException -{ - - /** - *

    Constructor

    - */ - public MissingSectionException() - { - super(); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - */ - public MissingSectionException(final String msg) - { - super(msg); - } - - - /** - *

    Constructor

    - * - * @param reason This exception's underlying reason - */ - public MissingSectionException(final Throwable reason) - { - super(reason); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - * @param reason This exception's underlying reason - */ - public MissingSectionException(final String msg, final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/MutableProperty.java b/trunk/src/java/org/apache/poi/hpsf/MutableProperty.java deleted file mode 100644 index 9d77c0dd0..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/MutableProperty.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.CodePageUtil; - -/** - *

    Adds writing capability to the {@link Property} class.

    - * - *

    Please be aware that this class' functionality will be merged into the - * {@link Property} class at a later time, so the API will change.

    - */ -public class MutableProperty extends Property -{ - - /** - *

    Creates an empty property. It must be filled using the set method to - * be usable.

    - */ - public MutableProperty() - { } - - - - /** - *

    Creates a MutableProperty as a copy of an existing - * Property.

    - * - * @param p The property to copy. - */ - public MutableProperty(final Property p) - { - setID(p.getID()); - setType(p.getType()); - setValue(p.getValue()); - } - - - /** - *

    Sets the property's ID.

    - * - * @param id the ID - */ - public void setID(final long id) - { - this.id = id; - } - - - - /** - *

    Sets the property's type.

    - * - * @param type the property's type - */ - public void setType(final long type) - { - this.type = type; - } - - - - /** - *

    Sets the property's value.

    - * - * @param value the property's value - */ - public void setValue(final Object value) - { - this.value = value; - } - - - - /** - *

    Writes the property to an output stream.

    - * - * @param out The output stream to write to. - * @param codepage The codepage to use for writing non-wide strings - * @return the number of bytes written to the stream - * - * @exception IOException if an I/O error occurs - * @exception WritingNotSupportedException if a variant type is to be - * written that is not yet supported - */ - public int write(final OutputStream out, final int codepage) - throws IOException, WritingNotSupportedException - { - int length = 0; - long variantType = getType(); - - /* Ensure that wide strings are written if the codepage is Unicode. */ - if (codepage == CodePageUtil.CP_UNICODE && variantType == Variant.VT_LPSTR) - variantType = Variant.VT_LPWSTR; - - length += TypeWriter.writeUIntToStream(out, variantType); - length += VariantSupport.write(out, variantType, getValue(), codepage); - return length; - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/MutablePropertySet.java b/trunk/src/java/org/apache/poi/hpsf/MutablePropertySet.java deleted file mode 100644 index 5c7d38658..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/MutablePropertySet.java +++ /dev/null @@ -1,304 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.LinkedList; - -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; - -/** - *

    Adds writing support to the {@link PropertySet} class.

    - * - *

    Please be aware that this class' functionality will be merged into the - * {@link PropertySet} class at a later time, so the API will change.

    - */ -public class MutablePropertySet extends PropertySet -{ - - /** - *

    Constructs a MutablePropertySet instance. Its - * primary task is to initialize the immutable field with their proper - * values. It also sets fields that might change to reasonable defaults.

    - */ - public MutablePropertySet() - { - /* Initialize the "byteOrder" field. */ - byteOrder = LittleEndian.getUShort(BYTE_ORDER_ASSERTION); - - /* Initialize the "format" field. */ - format = LittleEndian.getUShort(FORMAT_ASSERTION); - - /* Initialize "osVersion" field as if the property has been created on - * a Win32 platform, whether this is the case or not. */ - osVersion = (OS_WIN32 << 16) | 0x0A04; - - /* Initailize the "classID" field. */ - classID = new ClassID(); - - /* Initialize the sections. Since property set must have at least - * one section it is added right here. */ - sections = new LinkedList
    (); - sections.add(new MutableSection()); - } - - - - /** - *

    Constructs a MutablePropertySet by doing a deep copy of - * an existing PropertySet. All nested elements, i.e. - * Sections and Property instances, will be their - * mutable counterparts in the new MutablePropertySet.

    - * - * @param ps The property set to copy - */ - public MutablePropertySet(final PropertySet ps) - { - byteOrder = ps.getByteOrder(); - format = ps.getFormat(); - osVersion = ps.getOSVersion(); - setClassID(ps.getClassID()); - clearSections(); - if (sections == null) - sections = new LinkedList
    (); - for (final Section section : ps.getSections()) - { - final MutableSection s = new MutableSection(section); - addSection(s); - } - } - - - - /** - *

    The length of the property set stream header.

    - */ - private final static int OFFSET_HEADER = - BYTE_ORDER_ASSERTION.length + /* Byte order */ - FORMAT_ASSERTION.length + /* Format */ - LittleEndianConsts.INT_SIZE + /* OS version */ - ClassID.LENGTH + /* Class ID */ - LittleEndianConsts.INT_SIZE; /* Section count */ - - - - /** - *

    Sets the "byteOrder" property.

    - * - * @param byteOrder the byteOrder value to set - */ - public void setByteOrder(final int byteOrder) - { - this.byteOrder = byteOrder; - } - - - - /** - *

    Sets the "format" property.

    - * - * @param format the format value to set - */ - public void setFormat(final int format) - { - this.format = format; - } - - - - /** - *

    Sets the "osVersion" property.

    - * - * @param osVersion the osVersion value to set - */ - public void setOSVersion(final int osVersion) - { - this.osVersion = osVersion; - } - - - - /** - *

    Sets the property set stream's low-level "class ID" - * field.

    - * - * @param classID The property set stream's low-level "class ID" field. - * - * @see PropertySet#getClassID() - */ - public void setClassID(final ClassID classID) - { - this.classID = classID; - } - - - - /** - *

    Removes all sections from this property set.

    - */ - public void clearSections() - { - sections = null; - } - - - - /** - *

    Adds a section to this property set.

    - * - * @param section The {@link Section} to add. It will be appended - * after any sections that are already present in the property set - * and thus become the last section. - */ - public void addSection(final Section section) - { - if (sections == null) - sections = new LinkedList
    (); - sections.add(section); - } - - - - /** - *

    Writes the property set to an output stream.

    - * - * @param out the output stream to write the section to - * @exception IOException if an error when writing to the output stream - * occurs - * @exception WritingNotSupportedException if HPSF does not yet support - * writing a property's variant type. - */ - public void write(final OutputStream out) - throws WritingNotSupportedException, IOException - { - /* Write the number of sections in this property set stream. */ - final int nrSections = sections.size(); - - /* Write the property set's header. */ - TypeWriter.writeToStream(out, (short) getByteOrder()); - TypeWriter.writeToStream(out, (short) getFormat()); - TypeWriter.writeToStream(out, getOSVersion()); - TypeWriter.writeToStream(out, getClassID()); - TypeWriter.writeToStream(out, nrSections); - int offset = OFFSET_HEADER; - - /* Write the section list, i.e. the references to the sections. Each - * entry in the section list consist of the section's class ID and the - * section's offset relative to the beginning of the stream. */ - offset += nrSections * (ClassID.LENGTH + LittleEndianConsts.INT_SIZE); - final int sectionsBegin = offset; - for (final Section section : sections) - { - final MutableSection s = (MutableSection)section; - final ClassID formatID = s.getFormatID(); - if (formatID == null) - throw new NoFormatIDException(); - TypeWriter.writeToStream(out, s.getFormatID()); - TypeWriter.writeUIntToStream(out, offset); - try - { - offset += s.getSize(); - } - catch (HPSFRuntimeException ex) - { - final Throwable cause = ex.getReason(); - if (cause instanceof UnsupportedEncodingException) { - throw new IllegalPropertySetDataException(cause); - } - throw ex; - } - } - - /* Write the sections themselves. */ - offset = sectionsBegin; - for (final Section section : sections) - { - final MutableSection s = (MutableSection)section; - offset += s.write(out); - } - - /* Indicate that we're done */ - out.close(); - } - - - - /** - *

    Returns the contents of this property set stream as an input stream. - * The latter can be used for example to write the property set into a POIFS - * document. The input stream represents a snapshot of the property set. - * If the latter is modified while the input stream is still being - * read, the modifications will not be reflected in the input stream but in - * the {@link MutablePropertySet} only.

    - * - * @return the contents of this property set stream - * - * @throws WritingNotSupportedException if HPSF does not yet support writing - * of a property's variant type. - * @throws IOException if an I/O exception occurs. - */ - public InputStream toInputStream() - throws IOException, WritingNotSupportedException - { - final ByteArrayOutputStream psStream = new ByteArrayOutputStream(); - try { - write(psStream); - } finally { - psStream.close(); - } - final byte[] streamData = psStream.toByteArray(); - return new ByteArrayInputStream(streamData); - } - - /** - *

    Writes a property set to a document in a POI filesystem directory.

    - * - * @param dir The directory in the POI filesystem to write the document to. - * @param name The document's name. If there is already a document with the - * same name in the directory the latter will be overwritten. - * - * @throws WritingNotSupportedException if the filesystem doesn't support writing - * @throws IOException if the old entry can't be deleted or the new entry be written - */ - public void write(final DirectoryEntry dir, final String name) - throws WritingNotSupportedException, IOException - { - /* If there is already an entry with the same name, remove it. */ - try - { - final Entry e = dir.getEntry(name); - e.delete(); - } - catch (FileNotFoundException ex) - { - /* Entry not found, no need to remove it. */ - } - /* Create the new entry. */ - dir.createDocument(name, toInputStream()); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/MutableSection.java b/trunk/src/java/org/apache/poi/hpsf/MutableSection.java deleted file mode 100644 index b0d71acf0..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/MutableSection.java +++ /dev/null @@ -1,699 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.LittleEndian; - -/** - *

    Adds writing capability to the {@link Section} class.

    - * - *

    Please be aware that this class' functionality will be merged into the - * {@link Section} class at a later time, so the API will change.

    - */ -public class MutableSection extends Section -{ - /** - *

    If the "dirty" flag is true, the section's size must be - * (re-)calculated before the section is written.

    - */ - private boolean dirty = true; - - - - /** - *

    List to assemble the properties. Unfortunately a wrong - * decision has been taken when specifying the "properties" field - * as an Property[]. It should have been a {@link java.util.List}.

    - */ - private List preprops; - - - - /** - *

    Contains the bytes making out the section. This byte array is - * established when the section's size is calculated and can be reused - * later. It is valid only if the "dirty" flag is false.

    - */ - private byte[] sectionBytes; - - - - /** - *

    Creates an empty mutable section.

    - */ - public MutableSection() - { - dirty = true; - formatID = null; - offset = -1; - preprops = new LinkedList(); - } - - - - /** - *

    Constructs a MutableSection by doing a deep copy of an - * existing Section. All nested Property - * instances, will be their mutable counterparts in the new - * MutableSection.

    - * - * @param s The section set to copy - */ - public MutableSection(final Section s) - { - setFormatID(s.getFormatID()); - final Property[] pa = s.getProperties(); - final MutableProperty[] mpa = new MutableProperty[pa.length]; - for (int i = 0; i < pa.length; i++) - mpa[i] = new MutableProperty(pa[i]); - setProperties(mpa); - setDictionary(s.getDictionary()); - } - - - - /** - *

    Sets the section's format ID.

    - * - * @param formatID The section's format ID - * - * @see #setFormatID(byte[]) - * @see Section#getFormatID - */ - public void setFormatID(final ClassID formatID) - { - this.formatID = formatID; - } - - - - /** - *

    Sets the section's format ID.

    - * - * @param formatID The section's format ID as a byte array. It components - * are in big-endian format. - * - * @see #setFormatID(ClassID) - * @see Section#getFormatID - */ - public void setFormatID(final byte[] formatID) - { - ClassID fid = getFormatID(); - if (fid == null) - { - fid = new ClassID(); - setFormatID(fid); - } - fid.setBytes(formatID); - } - - - - /** - *

    Sets this section's properties. Any former values are overwritten.

    - * - * @param properties This section's new properties. - */ - public void setProperties(final Property[] properties) - { - this.properties = properties; - preprops = new LinkedList(); - for (int i = 0; i < properties.length; i++) - preprops.add(properties[i]); - dirty = true; - } - - - - /** - *

    Sets the string value of the property with the specified ID.

    - * - * @param id The property's ID - * @param value The property's value. It will be written as a Unicode - * string. - * - * @see #setProperty(int, long, Object) - * @see #getProperty - */ - public void setProperty(final int id, final String value) - { - setProperty(id, Variant.VT_LPWSTR, value); - dirty = true; - } - - - - /** - *

    Sets the int value of the property with the specified ID.

    - * - * @param id The property's ID - * @param value The property's value. - * - * @see #setProperty(int, long, Object) - * @see #getProperty - */ - public void setProperty(final int id, final int value) - { - setProperty(id, Variant.VT_I4, Integer.valueOf(value)); - dirty = true; - } - - - - /** - *

    Sets the long value of the property with the specified ID.

    - * - * @param id The property's ID - * @param value The property's value. - * - * @see #setProperty(int, long, Object) - * @see #getProperty - */ - public void setProperty(final int id, final long value) - { - setProperty(id, Variant.VT_I8, Long.valueOf(value)); - dirty = true; - } - - - - /** - *

    Sets the boolean value of the property with the specified ID.

    - * - * @param id The property's ID - * @param value The property's value. - * - * @see #setProperty(int, long, Object) - * @see #getProperty - */ - public void setProperty(final int id, final boolean value) - { - setProperty(id, Variant.VT_BOOL, Boolean.valueOf(value)); - dirty = true; - } - - - - /** - *

    Sets the value and the variant type of the property with the - * specified ID. If a property with this ID is not yet present in - * the section, it will be added. An already present property with - * the specified ID will be overwritten. A default mapping will be - * used to choose the property's type.

    - * - * @param id The property's ID. - * @param variantType The property's variant type. - * @param value The property's value. - * - * @see #setProperty(int, String) - * @see #getProperty - * @see Variant - */ - public void setProperty(final int id, final long variantType, - final Object value) - { - final MutableProperty p = new MutableProperty(); - p.setID(id); - p.setType(variantType); - p.setValue(value); - setProperty(p); - dirty = true; - } - - - - /** - *

    Sets a property.

    - * - * @param p The property to be set. - * - * @see #setProperty(int, long, Object) - * @see #getProperty - * @see Variant - */ - public void setProperty(final Property p) - { - final long id = p.getID(); - removeProperty(id); - preprops.add(p); - dirty = true; - } - - - - /** - *

    Removes a property.

    - * - * @param id The ID of the property to be removed - */ - public void removeProperty(final long id) - { - for (final Iterator i = preprops.iterator(); i.hasNext();) - if (i.next().getID() == id) - { - i.remove(); - break; - } - dirty = true; - } - - - - /** - *

    Sets the value of the boolean property with the specified - * ID.

    - * - * @param id The property's ID - * @param value The property's value - * - * @see #setProperty(int, long, Object) - * @see #getProperty - * @see Variant - */ - protected void setPropertyBooleanValue(final int id, final boolean value) - { - setProperty(id, Variant.VT_BOOL, Boolean.valueOf(value)); - } - - - - /** - *

    Returns the section's size.

    - * - * @return the section's size. - */ - public int getSize() - { - if (dirty) - { - try - { - size = calcSize(); - dirty = false; - } - catch (HPSFRuntimeException ex) - { - throw ex; - } - catch (Exception ex) - { - throw new HPSFRuntimeException(ex); - } - } - return size; - } - - - - /** - *

    Calculates the section's size. It is the sum of the lengths of the - * section's header (8), the properties list (16 times the number of - * properties) and the properties themselves.

    - * - * @return the section's length in bytes. - * @throws WritingNotSupportedException - * @throws IOException - */ - private int calcSize() throws WritingNotSupportedException, IOException - { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - write(out); - out.close(); - /* Pad to multiple of 4 bytes so that even the Windows shell (explorer) - * shows custom properties. */ - sectionBytes = Util.pad4(out.toByteArray()); - return sectionBytes.length; - } - - - - /** - *

    Writes this section into an output stream.

    - * - *

    Internally this is done by writing into three byte array output - * streams: one for the properties, one for the property list and one for - * the section as such. The two former are appended to the latter when they - * have received all their data.

    - * - * @param out The stream to write into. - * - * @return The number of bytes written, i.e. the section's size. - * @exception IOException if an I/O error occurs - * @exception WritingNotSupportedException if HPSF does not yet support - * writing a property's variant type. - */ - public int write(final OutputStream out) - throws WritingNotSupportedException, IOException - { - /* Check whether we have already generated the bytes making out the - * section. */ - if (!dirty && sectionBytes != null) - { - out.write(sectionBytes); - return sectionBytes.length; - } - - /* The properties are written to this stream. */ - final ByteArrayOutputStream propertyStream = - new ByteArrayOutputStream(); - - /* The property list is established here. After each property that has - * been written to "propertyStream", a property list entry is written to - * "propertyListStream". */ - final ByteArrayOutputStream propertyListStream = - new ByteArrayOutputStream(); - - /* Maintain the current position in the list. */ - int position = 0; - - /* Increase the position variable by the size of the property list so - * that it points behind the property list and to the beginning of the - * properties themselves. */ - position += 2 * LittleEndian.INT_SIZE + - getPropertyCount() * 2 * LittleEndian.INT_SIZE; - - /* Writing the section's dictionary it tricky. If there is a dictionary - * (property 0) the codepage property (property 1) must be set, too. */ - int codepage = -1; - if (getProperty(PropertyIDMap.PID_DICTIONARY) != null) - { - final Object p1 = getProperty(PropertyIDMap.PID_CODEPAGE); - if (p1 != null) - { - if (!(p1 instanceof Integer)) - throw new IllegalPropertySetDataException - ("The codepage property (ID = 1) must be an " + - "Integer object."); - } - else - /* Warning: The codepage property is not set although a - * dictionary is present. In order to cope with this problem we - * add the codepage property and set it to Unicode. */ - setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2, - Integer.valueOf(CodePageUtil.CP_UNICODE)); - codepage = getCodepage(); - } - - /* Sort the property list by their property IDs: */ - Collections.sort(preprops, new Comparator() - { - public int compare(final Property p1, final Property p2) - { - if (p1.getID() < p2.getID()) - return -1; - else if (p1.getID() == p2.getID()) - return 0; - else - return 1; - } - }); - - /* Write the properties and the property list into their respective - * streams: */ - for (final ListIterator i = preprops.listIterator(); i.hasNext();) - { - final MutableProperty p = (MutableProperty) i.next(); - final long id = p.getID(); - - /* Write the property list entry. */ - TypeWriter.writeUIntToStream(propertyListStream, p.getID()); - TypeWriter.writeUIntToStream(propertyListStream, position); - - /* If the property ID is not equal 0 we write the property and all - * is fine. However, if it equals 0 we have to write the section's - * dictionary which has an implicit type only and an explicit - * value. */ - if (id != 0) - /* Write the property and update the position to the next - * property. */ - position += p.write(propertyStream, getCodepage()); - else - { - if (codepage == -1) - throw new IllegalPropertySetDataException - ("Codepage (property 1) is undefined."); - position += writeDictionary(propertyStream, dictionary, - codepage); - } - } - propertyStream.close(); - propertyListStream.close(); - - /* Write the section: */ - byte[] pb1 = propertyListStream.toByteArray(); - byte[] pb2 = propertyStream.toByteArray(); - - /* Write the section's length: */ - TypeWriter.writeToStream(out, LittleEndian.INT_SIZE * 2 + - pb1.length + pb2.length); - - /* Write the section's number of properties: */ - TypeWriter.writeToStream(out, getPropertyCount()); - - /* Write the property list: */ - out.write(pb1); - - /* Write the properties: */ - out.write(pb2); - - int streamLength = LittleEndian.INT_SIZE * 2 + pb1.length + pb2.length; - return streamLength; - } - - - - /** - *

    Writes the section's dictionary.

    - * - * @param out The output stream to write to. - * @param dictionary The dictionary. - * @param codepage The codepage to be used to write the dictionary items. - * @return The number of bytes written - * @exception IOException if an I/O exception occurs. - */ - private static int writeDictionary(final OutputStream out, - final Map dictionary, final int codepage) - throws IOException - { - int length = TypeWriter.writeUIntToStream(out, dictionary.size()); - for (Map.Entry ls : dictionary.entrySet()) { - final Long key = ls.getKey(); - final String value = ls.getValue(); - - if (codepage == CodePageUtil.CP_UNICODE) - { - /* Write the dictionary item in Unicode. */ - int sLength = value.length() + 1; - if ((sLength & 1) == 1) { - sLength++; - } - length += TypeWriter.writeUIntToStream(out, key.longValue()); - length += TypeWriter.writeUIntToStream(out, sLength); - final byte[] ca = CodePageUtil.getBytesInCodePage(value, codepage); - for (int j = 2; j < ca.length; j += 2) - { - out.write(ca[j+1]); - out.write(ca[j]); - length += 2; - } - sLength -= value.length(); - while (sLength > 0) - { - out.write(0x00); - out.write(0x00); - length += 2; - sLength--; - } - } - else - { - /* Write the dictionary item in another codepage than - * Unicode. */ - length += TypeWriter.writeUIntToStream(out, key.longValue()); - length += TypeWriter.writeUIntToStream(out, value.length() + 1); - final byte[] ba = CodePageUtil.getBytesInCodePage(value, codepage); - for (int j = 0; j < ba.length; j++) - { - out.write(ba[j]); - length++; - } - out.write(0x00); - length++; - } - } - return length; - } - - - - /** - *

    Overwrites the super class' method to cope with a redundancy: - * the property count is maintained in a separate member variable, but - * shouldn't.

    - * - * @return The number of properties in this section - */ - public int getPropertyCount() - { - return preprops.size(); - } - - - - /** - *

    Gets this section's properties.

    - * - * @return this section's properties. - */ - public Property[] getProperties() - { - properties = preprops.toArray(new Property[0]); - return properties; - } - - - - /** - *

    Gets a property.

    - * - * @param id The ID of the property to get - * @return The property or null if there is no such property - */ - public Object getProperty(final long id) - { - /* Calling getProperties() ensures that properties and preprops are in - * sync.

    */ - getProperties(); - return super.getProperty(id); - } - - - - /** - *

    Sets the section's dictionary. All keys in the dictionary must be - * {@link java.lang.Long} instances, all values must be - * {@link java.lang.String}s. This method overwrites the properties with IDs - * 0 and 1 since they are reserved for the dictionary and the dictionary's - * codepage. Setting these properties explicitly might have surprising - * effects. An application should never do this but always use this - * method.

    - * - * @param dictionary The dictionary - * - * @exception IllegalPropertySetDataException if the dictionary's key and - * value types are not correct. - * - * @see Section#getDictionary() - */ - public void setDictionary(final Map dictionary) - throws IllegalPropertySetDataException - { - if (dictionary != null) - { - this.dictionary = dictionary; - - /* Set the dictionary property (ID 0). Please note that the second - * parameter in the method call below is unused because dictionaries - * don't have a type. */ - setProperty(PropertyIDMap.PID_DICTIONARY, -1, dictionary); - - /* If the codepage property (ID 1) for the strings (keys and - * values) used in the dictionary is not yet defined, set it to - * Unicode. */ - final Integer codepage = - (Integer) getProperty(PropertyIDMap.PID_CODEPAGE); - if (codepage == null) - setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2, - Integer.valueOf(CodePageUtil.CP_UNICODE)); - } - else - /* Setting the dictionary to null means to remove property 0. - * However, it does not mean to remove property 1 (codepage). */ - removeProperty(PropertyIDMap.PID_DICTIONARY); - } - - - - /** - *

    Sets a property.

    - * - * @param id The property ID. - * @param value The property's value. The value's class must be one of those - * supported by HPSF. - */ - public void setProperty(final int id, final Object value) - { - if (value instanceof String) - setProperty(id, (String) value); - else if (value instanceof Long) - setProperty(id, ((Long) value).longValue()); - else if (value instanceof Integer) - setProperty(id, ((Integer) value).intValue()); - else if (value instanceof Short) - setProperty(id, ((Short) value).intValue()); - else if (value instanceof Boolean) - setProperty(id, ((Boolean) value).booleanValue()); - else if (value instanceof Date) - setProperty(id, Variant.VT_FILETIME, value); - else - throw new HPSFRuntimeException( - "HPSF does not support properties of type " + - value.getClass().getName() + "."); - } - - - - /** - *

    Removes all properties from the section including 0 (dictionary) and - * 1 (codepage).

    - */ - public void clear() - { - final Property[] properties = getProperties(); - for (int i = 0; i < properties.length; i++) - { - final Property p = properties[i]; - removeProperty(p.getID()); - } - } - - /** - *

    Sets the codepage.

    - * - * @param codepage the codepage - */ - public void setCodepage(final int codepage) - { - setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2, - Integer.valueOf(codepage)); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/NoFormatIDException.java b/trunk/src/java/org/apache/poi/hpsf/NoFormatIDException.java deleted file mode 100644 index f1a09438e..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/NoFormatIDException.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if a {@link MutablePropertySet} is to be written - * but does not have a formatID set (see {@link - * MutableSection#setFormatID(ClassID)} or - * {@link org.apache.poi.hpsf.MutableSection#setFormatID(byte[])}. - */ -public class NoFormatIDException extends HPSFRuntimeException -{ - - /** - *

    Constructor

    - */ - public NoFormatIDException() - { - super(); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - */ - public NoFormatIDException(final String msg) - { - super(msg); - } - - - /** - *

    Constructor

    - * - * @param reason This exception's underlying reason - */ - public NoFormatIDException(final Throwable reason) - { - super(reason); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - * @param reason This exception's underlying reason - */ - public NoFormatIDException(final String msg, final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/NoPropertySetStreamException.java b/trunk/src/java/org/apache/poi/hpsf/NoPropertySetStreamException.java deleted file mode 100644 index 62738d42b..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/NoPropertySetStreamException.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if a format error in a property set stream is - * detected or when the input data do not constitute a property set stream.

    - * - *

    The constructors of this class are analogous to those of its superclass - * and are documented there.

    - */ -public class NoPropertySetStreamException extends HPSFException -{ - - /** - *

    Constructor

    - */ - public NoPropertySetStreamException() - { - super(); - } - - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - */ - public NoPropertySetStreamException(final String msg) - { - super(msg); - } - - - - /** - *

    Constructor

    - * - * @param reason This exception's underlying reason - */ - public NoPropertySetStreamException(final Throwable reason) - { - super(reason); - } - - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - * @param reason This exception's underlying reason - */ - public NoPropertySetStreamException(final String msg, - final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/NoSingleSectionException.java b/trunk/src/java/org/apache/poi/hpsf/NoSingleSectionException.java deleted file mode 100644 index 2309fe561..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/NoSingleSectionException.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if one of the {@link PropertySet}'s - * convenience methods that require a single {@link Section} is called - * and the {@link PropertySet} does not contain exactly one {@link - * Section}.

    - * - *

    The constructors of this class are analogous to those of its - * superclass and documented there.

    - */ -public class NoSingleSectionException extends HPSFRuntimeException -{ - - /** - *

    Constructor

    - */ - public NoSingleSectionException() - { - super(); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - */ - public NoSingleSectionException(final String msg) - { - super(msg); - } - - - /** - *

    Constructor

    - * - * @param reason This exception's underlying reason - */ - public NoSingleSectionException(final Throwable reason) - { - super(reason); - } - - - /** - *

    Constructor

    - * - * @param msg The exception's message string - * @param reason This exception's underlying reason - */ - public NoSingleSectionException(final String msg, final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Property.java b/trunk/src/java/org/apache/poi/hpsf/Property.java deleted file mode 100644 index 14dbee027..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Property.java +++ /dev/null @@ -1,453 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - *

    A property in a {@link Section} of a {@link PropertySet}.

    - * - *

    The property's ID gives the property a meaning - * in the context of its {@link Section}. Each {@link Section} spans - * its own name space of property IDs.

    - * - *

    The property's type determines how its - * value is interpreted. For example, if the type is - * {@link Variant#VT_LPSTR} (byte string), the value consists of a - * DWord telling how many bytes the string contains. The bytes follow - * immediately, including any null bytes that terminate the - * string. The type {@link Variant#VT_I4} denotes a four-byte integer - * value, {@link Variant#VT_FILETIME} some date and time (of a - * file).

    - * - *

    Please note that not all {@link Variant} types yet. This might change - * over time but largely depends on your feedback so that the POI team knows - * which variant types are really needed. So please feel free to submit error - * reports or patches for the types you need.

    - * - *

    Microsoft documentation: - * Property Set Display Name Dictionary. - * - * @see Section - * @see Variant - */ -public class Property -{ - - /**

    The property's ID.

    */ - protected long id; - - - /** - *

    Returns the property's ID.

    - * - * @return The ID value - */ - public long getID() - { - return id; - } - - - - /**

    The property's type.

    */ - protected long type; - - - /** - *

    Returns the property's type.

    - * - * @return The type value - */ - public long getType() - { - return type; - } - - - - /**

    The property's value.

    */ - protected Object value; - - - /** - *

    Returns the property's value.

    - * - * @return The property's value - */ - public Object getValue() - { - return value; - } - - - - /** - *

    Creates a property.

    - * - * @param id the property's ID. - * @param type the property's type, see {@link Variant}. - * @param value the property's value. Only certain types are allowed, see - * {@link Variant}. - */ - public Property(final long id, final long type, final Object value) - { - this.id = id; - this.type = type; - this.value = value; - } - - - - /** - *

    Creates a {@link Property} instance by reading its bytes - * from the property set stream.

    - * - * @param id The property's ID. - * @param src The bytes the property set stream consists of. - * @param offset The property's type/value pair's offset in the - * section. - * @param length The property's type/value pair's length in bytes. - * @param codepage The section's and thus the property's - * codepage. It is needed only when reading string values. - * @exception UnsupportedEncodingException if the specified codepage is not - * supported. - */ - public Property(final long id, final byte[] src, final long offset, - final int length, final int codepage) - throws UnsupportedEncodingException - { - this.id = id; - - /* - * ID 0 is a special case since it specifies a dictionary of - * property IDs and property names. - */ - if (id == 0) - { - value = readDictionary(src, offset, length, codepage); - return; - } - - int o = (int) offset; - type = LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; - - try - { - value = VariantSupport.read(src, o, length, (int) type, codepage); - } - catch (UnsupportedVariantTypeException ex) - { - VariantSupport.writeUnsupportedTypeMessage(ex); - value = ex.getValue(); - } - } - - - - /** - *

    Creates an empty property. It must be filled using the set method to - * be usable.

    - */ - protected Property() - { } - - - - /** - *

    Reads a dictionary.

    - * - * @param src The byte array containing the bytes making out the dictionary. - * @param offset At this offset within src the dictionary - * starts. - * @param length The dictionary contains at most this many bytes. - * @param codepage The codepage of the string values. - * @return The dictonary - * @throws UnsupportedEncodingException if the dictionary's codepage is not - * (yet) supported. - */ - protected Map readDictionary(final byte[] src, final long offset, - final int length, final int codepage) - throws UnsupportedEncodingException - { - /* Check whether "offset" points into the "src" array". */ - if (offset < 0 || offset > src.length) - throw new HPSFRuntimeException - ("Illegal offset " + offset + " while HPSF stream contains " + - length + " bytes."); - int o = (int) offset; - - /* - * Read the number of dictionary entries. - */ - final long nrEntries = LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; - - final Map m = new LinkedHashMap( - (int) nrEntries, (float) 1.0 ); - - try - { - for (int i = 0; i < nrEntries; i++) - { - /* The key. */ - final Long id = Long.valueOf(LittleEndian.getUInt(src, o)); - o += LittleEndian.INT_SIZE; - - /* The value (a string). The length is the either the - * number of (two-byte) characters if the character set is Unicode - * or the number of bytes if the character set is not Unicode. - * The length includes terminating 0x00 bytes which we have to strip - * off to create a Java string. */ - long sLength = LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; - - /* Read the string. */ - final StringBuffer b = new StringBuffer(); - switch (codepage) - { - case -1: - { - /* Without a codepage the length is equal to the number of - * bytes. */ - b.append(new String(src, o, (int) sLength, Charset.forName("ASCII"))); - break; - } - case CodePageUtil.CP_UNICODE: - { - /* The length is the number of characters, i.e. the number - * of bytes is twice the number of the characters. */ - final int nrBytes = (int) (sLength * 2); - final byte[] h = new byte[nrBytes]; - for (int i2 = 0; i2 < nrBytes; i2 += 2) - { - h[i2] = src[o + i2 + 1]; - h[i2 + 1] = src[o + i2]; - } - b.append(new String(h, 0, nrBytes, - CodePageUtil.codepageToEncoding(codepage))); - break; - } - default: - { - /* For encodings other than Unicode the length is the number - * of bytes. */ - b.append(new String(src, o, (int) sLength, - VariantSupport.codepageToEncoding(codepage))); - break; - } - } - - /* Strip 0x00 characters from the end of the string: */ - while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00) - b.setLength(b.length() - 1); - if (codepage == CodePageUtil.CP_UNICODE) - { - if (sLength % 2 == 1) - sLength++; - o += (sLength + sLength); - } - else - o += sLength; - m.put(id, b.toString()); - } - } - catch (RuntimeException ex) - { - final POILogger l = POILogFactory.getLogger(getClass()); - l.log(POILogger.WARN, - "The property set's dictionary contains bogus data. " - + "All dictionary entries starting with the one with ID " - + id + " will be ignored.", ex); - } - return m; - } - - - - /** - *

    Returns the property's size in bytes. This is always a multiple of - * 4.

    - * - * @return the property's size in bytes - * - * @exception WritingNotSupportedException if HPSF does not yet support the - * property's variant type. - */ - protected int getSize() throws WritingNotSupportedException - { - int length = VariantSupport.getVariantLength(type); - if (length >= 0) - return length; /* Fixed length */ - if (length == -2) - /* Unknown length */ - throw new WritingNotSupportedException(type, null); - - /* Variable length: */ - final int PADDING = 4; /* Pad to multiples of 4. */ - switch ((int) type) - { - case Variant.VT_LPSTR: - { - int l = ((String) value).length() + 1; - int r = l % PADDING; - if (r > 0) - l += PADDING - r; - length += l; - break; - } - case Variant.VT_EMPTY: - break; - default: - throw new WritingNotSupportedException(type, value); - } - return length; - } - - - - /** - *

    Compares two properties.

    Please beware that a property with - * ID == 0 is a special case: It does not have a type, and its value is the - * section's dictionary. Another special case are strings: Two properties - * may have the different types Variant.VT_LPSTR and Variant.VT_LPWSTR;

    - * - * @see Object#equals(java.lang.Object) - */ - public boolean equals(final Object o) - { - if (!(o instanceof Property)) { - return false; - } - final Property p = (Property) o; - final Object pValue = p.getValue(); - final long pId = p.getID(); - if (id != pId || (id != 0 && !typesAreEqual(type, p.getType()))) - return false; - if (value == null && pValue == null) - return true; - if (value == null || pValue == null) - return false; - - /* It's clear now that both values are non-null. */ - final Class valueClass = value.getClass(); - final Class pValueClass = pValue.getClass(); - if (!(valueClass.isAssignableFrom(pValueClass)) && - !(pValueClass.isAssignableFrom(valueClass))) - return false; - - if (value instanceof byte[]) - return Util.equal((byte[]) value, (byte[]) pValue); - - return value.equals(pValue); - } - - - - private boolean typesAreEqual(final long t1, final long t2) - { - if (t1 == t2 || - (t1 == Variant.VT_LPSTR && t2 == Variant.VT_LPWSTR) || - (t2 == Variant.VT_LPSTR && t1 == Variant.VT_LPWSTR)) { - return true; - } - return false; - } - - - - /** - * @see Object#hashCode() - */ - public int hashCode() - { - long hashCode = 0; - hashCode += id; - hashCode += type; - if (value != null) - hashCode += value.hashCode(); - final int returnHashCode = (int) (hashCode & 0x0ffffffffL ); - return returnHashCode; - - } - - - - /** - * @see Object#toString() - */ - public String toString() - { - final StringBuffer b = new StringBuffer(); - b.append(getClass().getName()); - b.append('['); - b.append("id: "); - b.append(getID()); - b.append(", type: "); - b.append(getType()); - final Object value = getValue(); - b.append(", value: "); - if (value instanceof String) - { - b.append(value.toString()); - final String s = (String) value; - final int l = s.length(); - final byte[] bytes = new byte[l * 2]; - for (int i = 0; i < l; i++) - { - final char c = s.charAt(i); - final byte high = (byte) ((c & 0x00ff00) >> 8); - final byte low = (byte) ((c & 0x0000ff) >> 0); - bytes[i * 2] = high; - bytes[i * 2 + 1] = low; - } - b.append(" ["); - if(bytes.length > 0) { - final String hex = HexDump.dump(bytes, 0L, 0); - b.append(hex); - } - b.append("]"); - } - else if (value instanceof byte[]) - { - byte[] bytes = (byte[])value; - if(bytes.length > 0) { - String hex = HexDump.dump(bytes, 0L, 0); - b.append(hex); - } - } - else - { - b.append(value.toString()); - } - b.append(']'); - return b.toString(); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/PropertySet.java b/trunk/src/java/org/apache/poi/hpsf/PropertySet.java deleted file mode 100644 index 9c9b1876a..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/PropertySet.java +++ /dev/null @@ -1,696 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hpsf.wellknown.SectionIDMap; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; - -/** - *

    Represents a property set in the Horrible Property Set Format - * (HPSF). These are usually metadata of a Microsoft Office - * document.

    - * - *

    An application that wants to access these metadata should create - * an instance of this class or one of its subclasses by calling the - * factory method {@link PropertySetFactory#create} and then retrieve - * the information its needs by calling appropriate methods.

    - * - *

    {@link PropertySetFactory#create} does its work by calling one - * of the constructors {@link PropertySet#PropertySet(InputStream)} or - * {@link PropertySet#PropertySet(byte[])}. If the constructor's - * argument is not in the Horrible Property Set Format, i.e. not a - * property set stream, or if any other error occurs, an appropriate - * exception is thrown.

    - * - *

    A {@link PropertySet} has a list of {@link Section}s, and each - * {@link Section} has a {@link Property} array. Use {@link - * #getSections} to retrieve the {@link Section}s, then call {@link - * Section#getProperties} for each {@link Section} to get hold of the - * {@link Property} arrays.

    Since the vast majority of {@link - * PropertySet}s contains only a single {@link Section}, the - * convenience method {@link #getProperties} returns the properties of - * a {@link PropertySet}'s {@link Section} (throwing a {@link - * NoSingleSectionException} if the {@link PropertySet} contains more - * (or less) than exactly one {@link Section}). - */ -public class PropertySet -{ - - /** - *

    The "byteOrder" field must equal this value.

    - */ - static final byte[] BYTE_ORDER_ASSERTION = - {(byte) 0xFE, (byte) 0xFF}; - - /** - *

    Specifies this {@link PropertySet}'s byte order. See the - * HPFS documentation for details!

    - */ - protected int byteOrder; - - /** - *

    Returns the property set stream's low-level "byte order" - * field. It is always 0xFFFE .

    - * - * @return The property set stream's low-level "byte order" field. - */ - public int getByteOrder() - { - return byteOrder; - } - - - - /** - *

    The "format" field must equal this value.

    - */ - static final byte[] FORMAT_ASSERTION = - {(byte) 0x00, (byte) 0x00}; - - /** - *

    Specifies this {@link PropertySet}'s format. See the HPFS - * documentation for details!

    - */ - protected int format; - - /** - *

    Returns the property set stream's low-level "format" - * field. It is always 0x0000 .

    - * - * @return The property set stream's low-level "format" field. - */ - public int getFormat() - { - return format; - } - - - - /** - *

    Specifies the version of the operating system that created - * this {@link PropertySet}. See the HPFS documentation for - * details!

    - */ - protected int osVersion; - - - /** - *

    If the OS version field holds this value the property set stream was - * created on a 16-bit Windows system.

    - */ - public static final int OS_WIN16 = 0x0000; - - /** - *

    If the OS version field holds this value the property set stream was - * created on a Macintosh system.

    - */ - public static final int OS_MACINTOSH = 0x0001; - - /** - *

    If the OS version field holds this value the property set stream was - * created on a 32-bit Windows system.

    - */ - public static final int OS_WIN32 = 0x0002; - - /** - *

    Returns the property set stream's low-level "OS version" - * field.

    - * - * @return The property set stream's low-level "OS version" field. - */ - public int getOSVersion() - { - return osVersion; - } - - - - /** - *

    Specifies this {@link PropertySet}'s "classID" field. See - * the HPFS documentation for details!

    - */ - protected ClassID classID; - - /** - *

    Returns the property set stream's low-level "class ID" - * field.

    - * - * @return The property set stream's low-level "class ID" field. - */ - public ClassID getClassID() - { - return classID; - } - - - - /** - *

    Returns the number of {@link Section}s in the property - * set.

    - * - * @return The number of {@link Section}s in the property set. - */ - public int getSectionCount() - { - return sections.size(); - } - - - - /** - *

    The sections in this {@link PropertySet}.

    - */ - protected List
    sections; - - /** - *

    Returns the {@link Section}s in the property set.

    - * - * @return The {@link Section}s in the property set. - */ - public List
    getSections() - { - return sections; - } - - - - /** - *

    Creates an empty (uninitialized) {@link PropertySet}.

    - * - *

    Please note: For the time being this - * constructor is protected since it is used for internal purposes - * only, but expect it to become public once the property set's - * writing functionality is implemented.

    - */ - protected PropertySet() - { } - - - - /** - *

    Creates a {@link PropertySet} instance from an {@link - * InputStream} in the Horrible Property Set Format.

    - * - *

    The constructor reads the first few bytes from the stream - * and determines whether it is really a property set stream. If - * it is, it parses the rest of the stream. If it is not, it - * resets the stream to its beginning in order to let other - * components mess around with the data and throws an - * exception.

    - * - * @param stream Holds the data making out the property set - * stream. - * @throws MarkUnsupportedException if the stream does not support - * the {@link InputStream#markSupported} method. - * @throws IOException if the {@link InputStream} cannot be - * accessed as needed. - * @exception NoPropertySetStreamException if the input stream does not - * contain a property set. - * @exception UnsupportedEncodingException if a character encoding is not - * supported. - */ - public PropertySet(final InputStream stream) - throws NoPropertySetStreamException, MarkUnsupportedException, - IOException, UnsupportedEncodingException - { - if (isPropertySetStream(stream)) - { - final int avail = stream.available(); - final byte[] buffer = new byte[avail]; - IOUtils.readFully(stream, buffer); - init(buffer, 0, buffer.length); - } - else - throw new NoPropertySetStreamException(); - } - - - - /** - *

    Creates a {@link PropertySet} instance from a byte array - * that represents a stream in the Horrible Property Set - * Format.

    - * - * @param stream The byte array holding the stream data. - * @param offset The offset in stream where the stream - * data begin. If the stream data begin with the first byte in the - * array, the offset is 0. - * @param length The length of the stream data. - * @throws NoPropertySetStreamException if the byte array is not a - * property set stream. - * - * @exception UnsupportedEncodingException if the codepage is not supported. - */ - public PropertySet(final byte[] stream, final int offset, final int length) - throws NoPropertySetStreamException, UnsupportedEncodingException - { - if (isPropertySetStream(stream, offset, length)) - init(stream, offset, length); - else - throw new NoPropertySetStreamException(); - } - - - - /** - *

    Creates a {@link PropertySet} instance from a byte array - * that represents a stream in the Horrible Property Set - * Format.

    - * - * @param stream The byte array holding the stream data. The - * complete byte array contents is the stream data. - * @throws NoPropertySetStreamException if the byte array is not a - * property set stream. - * - * @exception UnsupportedEncodingException if the codepage is not supported. - */ - public PropertySet(final byte[] stream) - throws NoPropertySetStreamException, UnsupportedEncodingException - { - this(stream, 0, stream.length); - } - - - - /** - *

    Checks whether an {@link InputStream} is in the Horrible - * Property Set Format.

    - * - * @param stream The {@link InputStream} to check. In order to - * perform the check, the method reads the first bytes from the - * stream. After reading, the stream is reset to the position it - * had before reading. The {@link InputStream} must support the - * {@link InputStream#mark} method. - * @return true if the stream is a property set - * stream, else false. - * @throws MarkUnsupportedException if the {@link InputStream} - * does not support the {@link InputStream#mark} method. - * @exception IOException if an I/O error occurs - */ - public static boolean isPropertySetStream(final InputStream stream) - throws MarkUnsupportedException, IOException - { - /* - * Read at most this many bytes. - */ - final int BUFFER_SIZE = 50; - - /* - * Mark the current position in the stream so that we can - * reset to this position if the stream does not contain a - * property set. - */ - if (!stream.markSupported()) - throw new MarkUnsupportedException(stream.getClass().getName()); - stream.mark(BUFFER_SIZE); - - /* - * Read a couple of bytes from the stream. - */ - final byte[] buffer = new byte[BUFFER_SIZE]; - final int bytes = - stream.read(buffer, 0, - Math.min(buffer.length, stream.available())); - final boolean isPropertySetStream = - isPropertySetStream(buffer, 0, bytes); - stream.reset(); - return isPropertySetStream; - } - - - - /** - *

    Checks whether a byte array is in the Horrible Property Set - * Format.

    - * - * @param src The byte array to check. - * @param offset The offset in the byte array. - * @param length The significant number of bytes in the byte - * array. Only this number of bytes will be checked. - * @return true if the byte array is a property set - * stream, false if not. - */ - public static boolean isPropertySetStream(final byte[] src, - final int offset, - final int length) - { - /* FIXME (3): Ensure that at most "length" bytes are read. */ - - /* - * Read the header fields of the stream. They must always be - * there. - */ - int o = offset; - final int byteOrder = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; - byte[] temp = new byte[LittleEndian.SHORT_SIZE]; - LittleEndian.putShort(temp, 0, (short) byteOrder); - if (!Util.equal(temp, BYTE_ORDER_ASSERTION)) - return false; - final int format = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; - temp = new byte[LittleEndian.SHORT_SIZE]; - LittleEndian.putShort(temp, 0, (short) format); - if (!Util.equal(temp, FORMAT_ASSERTION)) - return false; - // final long osVersion = LittleEndian.getUInt(src, offset); - o += LittleEndian.INT_SIZE; - // final ClassID classID = new ClassID(src, offset); - o += ClassID.LENGTH; - final long sectionCount = LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; - if (sectionCount < 0) - return false; - return true; - } - - - - /** - *

    Initializes this {@link PropertySet} instance from a byte - * array. The method assumes that it has been checked already that - * the byte array indeed represents a property set stream. It does - * no more checks on its own.

    - * - * @param src Byte array containing the property set stream - * @param offset The property set stream starts at this offset - * from the beginning of src - * @param length Length of the property set stream. - * @throws UnsupportedEncodingException if HPSF does not (yet) support the - * property set's character encoding. - */ - private void init(final byte[] src, final int offset, final int length) - throws UnsupportedEncodingException - { - /* FIXME (3): Ensure that at most "length" bytes are read. */ - - /* - * Read the stream's header fields. - */ - int o = offset; - byteOrder = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; - format = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; - osVersion = (int) LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; - classID = new ClassID(src, o); - o += ClassID.LENGTH; - final int sectionCount = LittleEndian.getInt(src, o); - o += LittleEndian.INT_SIZE; - if (sectionCount < 0) - throw new HPSFRuntimeException("Section count " + sectionCount + - " is negative."); - - /* - * Read the sections, which are following the header. They - * start with an array of section descriptions. Each one - * consists of a format ID telling what the section contains - * and an offset telling how many bytes from the start of the - * stream the section begins. - */ - /* - * Most property sets have only one section. The Document - * Summary Information stream has 2. Everything else is a rare - * exception and is no longer fostered by Microsoft. - */ - sections = new ArrayList
    ( sectionCount ); - - /* - * Loop over the section descriptor array. Each descriptor - * consists of a ClassID and a DWord, and we have to increment - * "offset" accordingly. - */ - for (int i = 0; i < sectionCount; i++) - { - final Section s = new Section(src, o); - o += ClassID.LENGTH + LittleEndian.INT_SIZE; - sections.add(s); - } - } - - - - /** - *

    Checks whether this {@link PropertySet} represents a Summary - * Information.

    - * - * @return true if this {@link PropertySet} - * represents a Summary Information, else false. - */ - public boolean isSummaryInformation() - { - if (sections.size() <= 0) - return false; - return Util.equal(sections.get(0).getFormatID().getBytes(), - SectionIDMap.SUMMARY_INFORMATION_ID); - } - - - - /** - *

    Checks whether this {@link PropertySet} is a Document - * Summary Information.

    - * - * @return true if this {@link PropertySet} - * represents a Document Summary Information, else false. - */ - public boolean isDocumentSummaryInformation() - { - if (sections.size() <= 0) - return false; - return Util.equal(sections.get(0).getFormatID().getBytes(), - SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]); - } - - - - /** - *

    Convenience method returning the {@link Property} array - * contained in this property set. It is a shortcut for getting - * the {@link PropertySet}'s {@link Section}s list and then - * getting the {@link Property} array from the first {@link - * Section}.

    - * - * @return The properties of the only {@link Section} of this - * {@link PropertySet}. - * @throws NoSingleSectionException if the {@link PropertySet} has - * more or less than one {@link Section}. - */ - public Property[] getProperties() - throws NoSingleSectionException - { - return getFirstSection().getProperties(); - } - - - - /** - *

    Convenience method returning the value of the property with - * the specified ID. If the property is not available, - * null is returned and a subsequent call to {@link - * #wasNull} will return true .

    - * - * @param id The property ID - * @return The property value - * @throws NoSingleSectionException if the {@link PropertySet} has - * more or less than one {@link Section}. - */ - protected Object getProperty(final int id) throws NoSingleSectionException - { - return getFirstSection().getProperty(id); - } - - - - /** - *

    Convenience method returning the value of a boolean property - * with the specified ID. If the property is not available, - * false is returned. A subsequent call to {@link - * #wasNull} will return true to let the caller - * distinguish that case from a real property value of - * false.

    - * - * @param id The property ID - * @return The property value - * @throws NoSingleSectionException if the {@link PropertySet} has - * more or less than one {@link Section}. - */ - protected boolean getPropertyBooleanValue(final int id) - throws NoSingleSectionException - { - return getFirstSection().getPropertyBooleanValue(id); - } - - - - /** - *

    Convenience method returning the value of the numeric - * property with the specified ID. If the property is not - * available, 0 is returned. A subsequent call to {@link #wasNull} - * will return true to let the caller distinguish - * that case from a real property value of 0.

    - * - * @param id The property ID - * @return The propertyIntValue value - * @throws NoSingleSectionException if the {@link PropertySet} has - * more or less than one {@link Section}. - */ - protected int getPropertyIntValue(final int id) - throws NoSingleSectionException - { - return getFirstSection().getPropertyIntValue(id); - } - - - - /** - *

    Checks whether the property which the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access - * was available or not. This information might be important for - * callers of {@link #getPropertyIntValue} since the latter - * returns 0 if the property does not exist. Using {@link - * #wasNull}, the caller can distiguish this case from a - * property's real value of 0.

    - * - * @return true if the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access a - * property that was not available, else false. - * @throws NoSingleSectionException if the {@link PropertySet} has - * more than one {@link Section}. - */ - public boolean wasNull() throws NoSingleSectionException - { - return getFirstSection().wasNull(); - } - - - - /** - *

    Gets the {@link PropertySet}'s first section.

    - * - * @return The {@link PropertySet}'s first section. - */ - public Section getFirstSection() - { - if (getSectionCount() < 1) - throw new MissingSectionException("Property set does not contain any sections."); - return sections.get(0); - } - - - - /** - *

    If the {@link PropertySet} has only a single section this - * method returns it.

    - * - * @return The singleSection value - */ - public Section getSingleSection() - { - final int sectionCount = getSectionCount(); - if (sectionCount != 1) - throw new NoSingleSectionException - ("Property set contains " + sectionCount + " sections."); - return sections.get(0); - } - - - - /** - *

    Returns true if the PropertySet is equal - * to the specified parameter, else false.

    - * - * @param o the object to compare this PropertySet with - * - * @return true if the objects are equal, false - * if not - */ - @Override - public boolean equals(final Object o) - { - if (o == null || !(o instanceof PropertySet)) - return false; - final PropertySet ps = (PropertySet) o; - int byteOrder1 = ps.getByteOrder(); - int byteOrder2 = getByteOrder(); - ClassID classID1 = ps.getClassID(); - ClassID classID2 = getClassID(); - int format1 = ps.getFormat(); - int format2 = getFormat(); - int osVersion1 = ps.getOSVersion(); - int osVersion2 = getOSVersion(); - int sectionCount1 = ps.getSectionCount(); - int sectionCount2 = getSectionCount(); - if (byteOrder1 != byteOrder2 || - !classID1.equals(classID2) || - format1 != format2 || - osVersion1 != osVersion2 || - sectionCount1 != sectionCount2) - return false; - - /* Compare the sections: */ - return Util.equals(getSections(), ps.getSections()); - } - - - - /** - * @see Object#hashCode() - */ - public int hashCode() - { - throw new UnsupportedOperationException("FIXME: Not yet implemented."); - } - - - - /** - * @see Object#toString() - */ - public String toString() - { - final StringBuilder b = new StringBuilder(); - final int sectionCount = getSectionCount(); - b.append(getClass().getName()); - b.append('['); - b.append("byteOrder: "); - b.append(getByteOrder()); - b.append(", classID: "); - b.append(getClassID()); - b.append(", format: "); - b.append(getFormat()); - b.append(", OSVersion: "); - b.append(getOSVersion()); - b.append(", sectionCount: "); - b.append(sectionCount); - b.append(", sections: [\n"); - for (Section section: getSections()) - b.append(section); - b.append(']'); - b.append(']'); - return b.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/PropertySetFactory.java b/trunk/src/java/org/apache/poi/hpsf/PropertySetFactory.java deleted file mode 100644 index 4d4b4e638..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/PropertySetFactory.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -import org.apache.poi.hpsf.wellknown.SectionIDMap; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentEntry; -import org.apache.poi.poifs.filesystem.DocumentInputStream; - -/** - *

    Factory class to create instances of {@link SummaryInformation}, - * {@link DocumentSummaryInformation} and {@link PropertySet}.

    - */ -public class PropertySetFactory -{ - /** - *

    Creates the most specific {@link PropertySet} from an entry - * in the specified POIFS Directory. This is preferrably a {@link - * DocumentSummaryInformation} or a {@link SummaryInformation}. If - * the specified entry does not contain a property set stream, an - * exception is thrown. If no entry is found with the given name, - * an exception is thrown.

    - * - * @param dir The directory to find the PropertySet in - * @param name The name of the entry containing the PropertySet - * @return The created {@link PropertySet}. - * @throws FileNotFoundException if there is no entry with that name - * @throws NoPropertySetStreamException if the stream does not - * contain a property set. - * @throws IOException if some I/O problem occurs. - * @exception UnsupportedEncodingException if the specified codepage is not - * supported. - */ - public static PropertySet create(final DirectoryEntry dir, final String name) - throws FileNotFoundException, NoPropertySetStreamException, - IOException, UnsupportedEncodingException - { - InputStream inp = null; - try { - DocumentEntry entry = (DocumentEntry)dir.getEntry(name); - inp = new DocumentInputStream(entry); - try { - return create(inp); - } catch (MarkUnsupportedException e) { return null; } - } finally { - if (inp != null) inp.close(); - } - } - - /** - *

    Creates the most specific {@link PropertySet} from an {@link - * InputStream}. This is preferrably a {@link - * DocumentSummaryInformation} or a {@link SummaryInformation}. If - * the specified {@link InputStream} does not contain a property - * set stream, an exception is thrown and the {@link InputStream} - * is repositioned at its beginning.

    - * - * @param stream Contains the property set stream's data. - * @return The created {@link PropertySet}. - * @throws NoPropertySetStreamException if the stream does not - * contain a property set. - * @throws MarkUnsupportedException if the stream does not support - * the mark operation. - * @throws IOException if some I/O problem occurs. - * @exception UnsupportedEncodingException if the specified codepage is not - * supported. - */ - public static PropertySet create(final InputStream stream) - throws NoPropertySetStreamException, MarkUnsupportedException, - UnsupportedEncodingException, IOException - { - final PropertySet ps = new PropertySet(stream); - try - { - if (ps.isSummaryInformation()) - return new SummaryInformation(ps); - else if (ps.isDocumentSummaryInformation()) - return new DocumentSummaryInformation(ps); - else - return ps; - } - catch (UnexpectedPropertySetTypeException ex) - { - /* This exception will never be throws because we already checked - * explicitly for this case above. */ - throw new IllegalStateException(ex); - } - } - - /** - *

    Creates a new summary information.

    - * - * @return the new summary information. - */ - public static SummaryInformation newSummaryInformation() - { - final MutablePropertySet ps = new MutablePropertySet(); - final MutableSection s = (MutableSection) ps.getFirstSection(); - s.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID); - try - { - return new SummaryInformation(ps); - } - catch (UnexpectedPropertySetTypeException ex) - { - /* This should never happen. */ - throw new HPSFRuntimeException(ex); - } - } - - /** - *

    Creates a new document summary information.

    - * - * @return the new document summary information. - */ - public static DocumentSummaryInformation newDocumentSummaryInformation() - { - final MutablePropertySet ps = new MutablePropertySet(); - final MutableSection s = (MutableSection) ps.getFirstSection(); - s.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]); - try - { - return new DocumentSummaryInformation(ps); - } - catch (UnexpectedPropertySetTypeException ex) - { - /* This should never happen. */ - throw new HPSFRuntimeException(ex); - } - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hpsf/ReadingNotSupportedException.java b/trunk/src/java/org/apache/poi/hpsf/ReadingNotSupportedException.java deleted file mode 100644 index cb16058a7..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/ReadingNotSupportedException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown when HPSF tries to read a (yet) unsupported - * variant type.

    - * - * @see WritingNotSupportedException - * @see UnsupportedVariantTypeException - */ -public class ReadingNotSupportedException - extends UnsupportedVariantTypeException -{ - - /** - *

    Constructor

    - * - * @param variantType The unsupported variant type. - * @param value The value. - */ - public ReadingNotSupportedException(final long variantType, - final Object value) - { - super(variantType, value); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Section.java b/trunk/src/java/org/apache/poi/hpsf/Section.java deleted file mode 100644 index c54fe51ab..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Section.java +++ /dev/null @@ -1,688 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.hpsf.wellknown.SectionIDMap; -import org.apache.poi.util.LittleEndian; - -/** - *

    Represents a section in a {@link PropertySet}.

    - */ -public class Section -{ - - /** - *

    Maps property IDs to section-private PID strings. These - * strings can be found in the property with ID 0.

    - */ - protected Map dictionary; - - /** - *

    The section's format ID, {@link #getFormatID}.

    - */ - protected ClassID formatID; - - - /** - *

    Returns the format ID. The format ID is the "type" of the - * section. For example, if the format ID of the first {@link - * Section} contains the bytes specified by - * org.apache.poi.hpsf.wellknown.SectionIDMap.SUMMARY_INFORMATION_ID - * the section (and thus the property set) is a SummaryInformation.

    - * - * @return The format ID - */ - public ClassID getFormatID() - { - return formatID; - } - - - - /** - * @see #getOffset - */ - protected long offset; - - - /** - *

    Returns the offset of the section in the stream.

    - * - * @return The offset of the section in the stream. - */ - public long getOffset() - { - return offset; - } - - - - /** - * @see #getSize - */ - protected int size; - - - /** - *

    Returns the section's size in bytes.

    - * - * @return The section's size in bytes. - */ - public int getSize() - { - return size; - } - - - - /** - *

    Returns the number of properties in this section.

    - * - * @return The number of properties in this section. - */ - public int getPropertyCount() - { - return properties.length; - } - - - - /** - * @see #getProperties - */ - protected Property[] properties; - - - /** - *

    Returns this section's properties.

    - * - * @return This section's properties. - */ - public Property[] getProperties() - { - return properties; - } - - - - /** - *

    Creates an empty and uninitialized {@link Section}. - */ - protected Section() - { } - - - - /** - *

    Creates a {@link Section} instance from a byte array.

    - * - * @param src Contains the complete property set stream. - * @param offset The position in the stream that points to the - * section's format ID. - * - * @exception UnsupportedEncodingException if the section's codepage is not - * supported. - */ - @SuppressWarnings("unchecked") - public Section(final byte[] src, final int offset) - throws UnsupportedEncodingException - { - int o1 = offset; - - /* - * Read the format ID. - */ - formatID = new ClassID(src, o1); - o1 += ClassID.LENGTH; - - /* - * Read the offset from the stream's start and positions to - * the section header. - */ - this.offset = LittleEndian.getUInt(src, o1); - o1 = (int) this.offset; - - /* - * Read the section length. - */ - size = (int) LittleEndian.getUInt(src, o1); - o1 += LittleEndian.INT_SIZE; - - /* - * Read the number of properties. - */ - final int propertyCount = (int) LittleEndian.getUInt(src, o1); - o1 += LittleEndian.INT_SIZE; - - /* - * Read the properties. The offset is positioned at the first - * entry of the property list. There are two problems: - * - * 1. For each property we have to find out its length. In the - * property list we find each property's ID and its offset relative - * to the section's beginning. Unfortunately the properties in the - * property list need not to be in ascending order, so it is not - * possible to calculate the length as - * (offset of property(i+1) - offset of property(i)). Before we can - * that we first have to sort the property list by ascending offsets. - * - * 2. We have to read the property with ID 1 before we read other - * properties, at least before other properties containing strings. - * The reason is that property 1 specifies the codepage. If it is - * 1200, all strings are in Unicode. In other words: Before we can - * read any strings we have to know whether they are in Unicode or - * not. Unfortunately property 1 is not guaranteed to be the first in - * a section. - * - * The algorithm below reads the properties in two passes: The first - * one looks for property ID 1 and extracts the codepage number. The - * seconds pass reads the other properties. - */ - properties = new Property[propertyCount]; - - /* Pass 1: Read the property list. */ - int pass1Offset = o1; - final List propertyList = new ArrayList(propertyCount); - PropertyListEntry ple; - for (int i = 0; i < properties.length; i++) - { - ple = new PropertyListEntry(); - - /* Read the property ID. */ - ple.id = (int) LittleEndian.getUInt(src, pass1Offset); - pass1Offset += LittleEndian.INT_SIZE; - - /* Offset from the section's start. */ - ple.offset = (int) LittleEndian.getUInt(src, pass1Offset); - pass1Offset += LittleEndian.INT_SIZE; - - /* Add the entry to the property list. */ - propertyList.add(ple); - } - - /* Sort the property list by ascending offsets: */ - Collections.sort(propertyList); - - /* Calculate the properties' lengths. */ - for (int i = 0; i < propertyCount - 1; i++) - { - PropertyListEntry ple1 = propertyList.get(i); - PropertyListEntry ple2 = propertyList.get(i + 1); - ple1.length = ple2.offset - ple1.offset; - } - if (propertyCount > 0) - { - ple = propertyList.get(propertyCount - 1); - ple.length = size - ple.offset; - } - - /* Look for the codepage. */ - int codepage = -1; - for (final Iterator i = propertyList.iterator(); - codepage == -1 && i.hasNext();) - { - ple = i.next(); - - /* Read the codepage if the property ID is 1. */ - if (ple.id == PropertyIDMap.PID_CODEPAGE) - { - /* Read the property's value type. It must be - * VT_I2. */ - int o = (int) (this.offset + ple.offset); - final long type = LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; - - if (type != Variant.VT_I2) - throw new HPSFRuntimeException - ("Value type of property ID 1 is not VT_I2 but " + - type + "."); - - /* Read the codepage number. */ - codepage = LittleEndian.getUShort(src, o); - } - } - - /* Pass 2: Read all properties - including the codepage property, - * if available. */ - int i1 = 0; - for (final Iterator i = propertyList.iterator(); i.hasNext();) - { - ple = i.next(); - Property p = new Property(ple.id, src, - this.offset + ple.offset, - ple.length, codepage); - if (p.getID() == PropertyIDMap.PID_CODEPAGE) - p = new Property(p.getID(), p.getType(), Integer.valueOf(codepage)); - properties[i1++] = p; - } - - /* - * Extract the dictionary (if available). - */ - dictionary = (Map) getProperty(0); - } - - - - /** - *

    Represents an entry in the property list and holds a property's ID and - * its offset from the section's beginning.

    - */ - static class PropertyListEntry implements Comparable - { - int id; - int offset; - int length; - - /** - *

    Compares this {@link PropertyListEntry} with another one by their - * offsets. A {@link PropertyListEntry} is "smaller" than another one if - * its offset from the section's begin is smaller.

    - * - * @see Comparable#compareTo(java.lang.Object) - */ - public int compareTo(final PropertyListEntry o) - { - final int otherOffset = o.offset; - if (offset < otherOffset) - return -1; - else if (offset == otherOffset) - return 0; - else - return 1; - } - - - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + id; - result = prime * result + length; - result = prime * result + offset; - return result; - } - - - - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - PropertyListEntry other = (PropertyListEntry) obj; - if (id != other.id) { - return false; - } - if (length != other.length) { - return false; - } - if (offset != other.offset) { - return false; - } - return true; - } - - - - public String toString() - { - final StringBuffer b = new StringBuffer(); - b.append(getClass().getName()); - b.append("[id="); - b.append(id); - b.append(", offset="); - b.append(offset); - b.append(", length="); - b.append(length); - b.append(']'); - return b.toString(); - } - } - - - - /** - *

    Returns the value of the property with the specified ID. If - * the property is not available, null is returned - * and a subsequent call to {@link #wasNull} will return - * true.

    - * - * @param id The property's ID - * - * @return The property's value - */ - public Object getProperty(final long id) - { - wasNull = false; - for (int i = 0; i < properties.length; i++) - if (id == properties[i].getID()) - return properties[i].getValue(); - wasNull = true; - return null; - } - - - - /** - *

    Returns the value of the numeric property with the specified - * ID. If the property is not available, 0 is returned. A - * subsequent call to {@link #wasNull} will return - * true to let the caller distinguish that case from - * a real property value of 0.

    - * - * @param id The property's ID - * - * @return The property's value - */ - protected int getPropertyIntValue(final long id) - { - final Number i; - final Object o = getProperty(id); - if (o == null) - return 0; - if (!(o instanceof Long || o instanceof Integer)) - throw new HPSFRuntimeException - ("This property is not an integer type, but " + - o.getClass().getName() + "."); - i = (Number) o; - return i.intValue(); - } - - - - /** - *

    Returns the value of the boolean property with the specified - * ID. If the property is not available, false is - * returned. A subsequent call to {@link #wasNull} will return - * true to let the caller distinguish that case from - * a real property value of false.

    - * - * @param id The property's ID - * - * @return The property's value - */ - protected boolean getPropertyBooleanValue(final int id) - { - final Boolean b = (Boolean) getProperty(id); - if (b == null) { - return false; - } - return b.booleanValue(); - } - - - - /** - *

    This member is true if the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access a - * property that was not available, else false.

    - */ - private boolean wasNull; - - - /** - *

    Checks whether the property which the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access - * was available or not. This information might be important for - * callers of {@link #getPropertyIntValue} since the latter - * returns 0 if the property does not exist. Using {@link - * #wasNull} the caller can distiguish this case from a property's - * real value of 0.

    - * - * @return true if the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access a - * property that was not available, else false. - */ - public boolean wasNull() - { - return wasNull; - } - - - - /** - *

    Returns the PID string associated with a property ID. The ID - * is first looked up in the {@link Section}'s private - * dictionary. If it is not found there, the method calls {@link - * SectionIDMap#getPIDString}.

    - * - * @param pid The property ID - * - * @return The property ID's string value - */ - public String getPIDString(final long pid) - { - String s = null; - if (dictionary != null) { - s = dictionary.get(Long.valueOf(pid)); - } - if (s == null) { - s = SectionIDMap.getPIDString(getFormatID().getBytes(), pid); - } - return s; - } - - - - /** - *

    Checks whether this section is equal to another object. The result is - * false if one of the the following conditions holds:

    - * - *
      - * - *
    • The other object is not a {@link Section}.

    • - * - *
    • The format IDs of the two sections are not equal.

    • - * - *
    • The sections have a different number of properties. However, - * properties with ID 1 (codepage) are not counted.

    • - * - *
    • The other object is not a {@link Section}.

    • - * - *
    • The properties have different values. The order of the properties - * is irrelevant.

    • - * - *
    - * - * @param o The object to compare this section with - * @return true if the objects are equal, false if - * not - */ - public boolean equals(final Object o) - { - if (o == null || !(o instanceof Section)) - return false; - final Section s = (Section) o; - if (!s.getFormatID().equals(getFormatID())) - return false; - - /* Compare all properties except 0 and 1 as they must be handled - * specially. */ - Property[] pa1 = new Property[getProperties().length]; - Property[] pa2 = new Property[s.getProperties().length]; - System.arraycopy(getProperties(), 0, pa1, 0, pa1.length); - System.arraycopy(s.getProperties(), 0, pa2, 0, pa2.length); - - /* Extract properties 0 and 1 and remove them from the copy of the - * arrays. */ - Property p10 = null; - Property p20 = null; - for (int i = 0; i < pa1.length; i++) - { - final long id = pa1[i].getID(); - if (id == 0) - { - p10 = pa1[i]; - pa1 = remove(pa1, i); - i--; - } - if (id == 1) - { - // p11 = pa1[i]; - pa1 = remove(pa1, i); - i--; - } - } - for (int i = 0; i < pa2.length; i++) - { - final long id = pa2[i].getID(); - if (id == 0) - { - p20 = pa2[i]; - pa2 = remove(pa2, i); - i--; - } - if (id == 1) - { - // p21 = pa2[i]; - pa2 = remove(pa2, i); - i--; - } - } - - /* If the number of properties (not counting property 1) is unequal the - * sections are unequal. */ - if (pa1.length != pa2.length) - return false; - - /* If the dictionaries are unequal the sections are unequal. */ - boolean dictionaryEqual = true; - if (p10 != null && p20 != null) - dictionaryEqual = p10.getValue().equals(p20.getValue()); - else if (p10 != null || p20 != null) - dictionaryEqual = false; - if (dictionaryEqual) { - return Util.equals(pa1, pa2); - } - return false; - } - - - - /** - *

    Removes a field from a property array. The resulting array is - * compactified and returned.

    - * - * @param pa The property array. - * @param i The index of the field to be removed. - * @return the compactified array. - */ - private Property[] remove(final Property[] pa, final int i) - { - final Property[] h = new Property[pa.length - 1]; - if (i > 0) - System.arraycopy(pa, 0, h, 0, i); - System.arraycopy(pa, i + 1, h, i, h.length - i); - return h; - } - - - - /** - * @see Object#hashCode() - */ - public int hashCode() - { - long hashCode = 0; - hashCode += getFormatID().hashCode(); - final Property[] pa = getProperties(); - for (int i = 0; i < pa.length; i++) - hashCode += pa[i].hashCode(); - final int returnHashCode = (int) (hashCode & 0x0ffffffffL); - return returnHashCode; - } - - - - /** - * @see Object#toString() - */ - public String toString() - { - final StringBuffer b = new StringBuffer(); - final Property[] pa = getProperties(); - b.append(getClass().getName()); - b.append('['); - b.append("formatID: "); - b.append(getFormatID()); - b.append(", offset: "); - b.append(getOffset()); - b.append(", propertyCount: "); - b.append(getPropertyCount()); - b.append(", size: "); - b.append(getSize()); - b.append(", properties: [\n"); - for (int i = 0; i < pa.length; i++) - { - b.append(pa[i].toString()); - b.append(",\n"); - } - b.append(']'); - b.append(']'); - return b.toString(); - } - - - - /** - *

    Gets the section's dictionary. A dictionary allows an application to - * use human-readable property names instead of numeric property IDs. It - * contains mappings from property IDs to their associated string - * values. The dictionary is stored as the property with ID 0. The codepage - * for the strings in the dictionary is defined by property with ID 1.

    - * - * @return the dictionary or null if the section does not have - * a dictionary. - */ - public Map getDictionary() - { - return dictionary; - } - - - - /** - *

    Gets the section's codepage, if any.

    - * - * @return The section's codepage if one is defined, else -1. - */ - public int getCodepage() - { - final Integer codepage = - (Integer) getProperty(PropertyIDMap.PID_CODEPAGE); - if (codepage == null) - return -1; - int cp = codepage.intValue(); - return cp; - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/SpecialPropertySet.java b/trunk/src/java/org/apache/poi/hpsf/SpecialPropertySet.java deleted file mode 100644 index aa8f8051d..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/SpecialPropertySet.java +++ /dev/null @@ -1,413 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.List; - -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.util.LittleEndian; - -/** - *

    Abstract superclass for the convenience classes {@link - * SummaryInformation} and {@link DocumentSummaryInformation}.

    - * - *

    The motivation behind this class is quite nasty if you look - * behind the scenes, but it serves the application programmer well by - * providing him with the easy-to-use {@link SummaryInformation} and - * {@link DocumentSummaryInformation} classes. When parsing the data a - * property set stream consists of (possibly coming from an {@link - * java.io.InputStream}) we want to read and process each byte only - * once. Since we don't know in advance which kind of property set we - * have, we can expect only the most general {@link - * PropertySet}. Creating a special subclass should be as easy as - * calling the special subclass' constructor and pass the general - * {@link PropertySet} in. To make things easy internally, the special - * class just holds a reference to the general {@link PropertySet} and - * delegates all method calls to it.

    - * - *

    A cleaner implementation would have been like this: The {@link - * PropertySetFactory} parses the stream data into some internal - * object first. Then it finds out whether the stream is a {@link - * SummaryInformation}, a {@link DocumentSummaryInformation} or a - * general {@link PropertySet}. However, the current implementation - * went the other way round historically: the convenience classes came - * only late to my mind.

    - */ -public abstract class SpecialPropertySet extends MutablePropertySet -{ - /** - * The id to name mapping of the properties in this set. - * - * @return the id to name mapping of the properties in this set - */ - public abstract PropertyIDMap getPropertySetIDMap(); - - /** - *

    The "real" property set SpecialPropertySet - * delegates to.

    - */ - private final MutablePropertySet delegate; - - - - /** - *

    Creates a SpecialPropertySet. - * - * @param ps The property set to be encapsulated by the - * SpecialPropertySet - */ - public SpecialPropertySet(final PropertySet ps) - { - delegate = new MutablePropertySet(ps); - } - - - - /** - *

    Creates a SpecialPropertySet. - * - * @param ps The mutable property set to be encapsulated by the - * SpecialPropertySet - */ - public SpecialPropertySet(final MutablePropertySet ps) - { - delegate = ps; - } - - - - /** - * @see PropertySet#getByteOrder - */ - @Override - public int getByteOrder() - { - return delegate.getByteOrder(); - } - - - - /** - * @see PropertySet#getFormat - */ - @Override - public int getFormat() - { - return delegate.getFormat(); - } - - - - /** - * @see PropertySet#getOSVersion - */ - @Override - public int getOSVersion() - { - return delegate.getOSVersion(); - } - - - - /** - * @see PropertySet#getClassID - */ - @Override - public ClassID getClassID() - { - return delegate.getClassID(); - } - - - - /** - * @see PropertySet#getSectionCount - */ - @Override - public int getSectionCount() - { - return delegate.getSectionCount(); - } - - - - /** - * @see PropertySet#getSections - */ - @Override - public List

    getSections() - { - return delegate.getSections(); - } - - - - /** - * @see PropertySet#isSummaryInformation - */ - @Override - public boolean isSummaryInformation() - { - return delegate.isSummaryInformation(); - } - - - - /** - * @see PropertySet#isDocumentSummaryInformation - */ - @Override - public boolean isDocumentSummaryInformation() - { - return delegate.isDocumentSummaryInformation(); - } - - - - /** - * @see PropertySet#getSingleSection - */ - @Override - public Section getFirstSection() - { - return delegate.getFirstSection(); - } - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#addSection(org.apache.poi.hpsf.Section) - */ - @Override - public void addSection(final Section section) - { - delegate.addSection(section); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#clearSections() - */ - @Override - public void clearSections() - { - delegate.clearSections(); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#setByteOrder(int) - */ - @Override - public void setByteOrder(final int byteOrder) - { - delegate.setByteOrder(byteOrder); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#setClassID(org.apache.poi.hpsf.ClassID) - */ - @Override - public void setClassID(final ClassID classID) - { - delegate.setClassID(classID); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#setFormat(int) - */ - @Override - public void setFormat(final int format) - { - delegate.setFormat(format); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#setOSVersion(int) - */ - @Override - public void setOSVersion(final int osVersion) - { - delegate.setOSVersion(osVersion); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#toInputStream() - */ - @Override - public InputStream toInputStream() throws IOException, WritingNotSupportedException - { - return delegate.toInputStream(); - } - - - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#write(org.apache.poi.poifs.filesystem.DirectoryEntry, java.lang.String) - */ - @Override - public void write(final DirectoryEntry dir, final String name) throws WritingNotSupportedException, IOException - { - delegate.write(dir, name); - } - - /** - * @see org.apache.poi.hpsf.MutablePropertySet#write(java.io.OutputStream) - */ - @Override - public void write(final OutputStream out) throws WritingNotSupportedException, IOException - { - delegate.write(out); - } - - /** - * @see org.apache.poi.hpsf.PropertySet#equals(java.lang.Object) - */ - @Override - public boolean equals(final Object o) - { - return delegate.equals(o); - } - - /** - * @see org.apache.poi.hpsf.PropertySet#getProperties() - */ - @Override - public Property[] getProperties() throws NoSingleSectionException - { - return delegate.getProperties(); - } - - /** - * @see org.apache.poi.hpsf.PropertySet#getProperty(int) - */ - @Override - protected Object getProperty(final int id) throws NoSingleSectionException - { - return delegate.getProperty(id); - } - - - - /** - * @see org.apache.poi.hpsf.PropertySet#getPropertyBooleanValue(int) - */ - @Override - protected boolean getPropertyBooleanValue(final int id) throws NoSingleSectionException - { - return delegate.getPropertyBooleanValue(id); - } - - - - /** - * @see org.apache.poi.hpsf.PropertySet#getPropertyIntValue(int) - */ - @Override - protected int getPropertyIntValue(final int id) throws NoSingleSectionException - { - return delegate.getPropertyIntValue(id); - } - - - - /** - * Fetches the property with the given ID, then does its - * best to return it as a String - * - * @param propertyId the property id - * - * @return The property as a String, or null if unavailable - */ - protected String getPropertyStringValue(final int propertyId) { - Object propertyValue = getProperty(propertyId); - return getPropertyStringValue(propertyValue); - } - protected static String getPropertyStringValue(final Object propertyValue) { - // Normal cases - if (propertyValue == null) return null; - if (propertyValue instanceof String) return (String)propertyValue; - - // Do our best with some edge cases - if (propertyValue instanceof byte[]) { - byte[] b = (byte[])propertyValue; - if (b.length == 0) { - return ""; - } - if (b.length == 1) { - return Byte.toString(b[0]); - } - if (b.length == 2) { - return Integer.toString( LittleEndian.getUShort(b) ); - } - if (b.length == 4) { - return Long.toString( LittleEndian.getUInt(b) ); - } - // Maybe it's a string? who knows! - return new String(b, Charset.forName("ASCII")); - } - return propertyValue.toString(); - } - - - /** - * @see org.apache.poi.hpsf.PropertySet#hashCode() - */ - @Override - public int hashCode() - { - return delegate.hashCode(); - } - - - - /** - * @see org.apache.poi.hpsf.PropertySet#toString() - */ - @Override - public String toString() - { - return delegate.toString(); - } - - - - /** - * @see org.apache.poi.hpsf.PropertySet#wasNull() - */ - @Override - public boolean wasNull() throws NoSingleSectionException - { - return delegate.wasNull(); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/SummaryInformation.java b/trunk/src/java/org/apache/poi/hpsf/SummaryInformation.java deleted file mode 100644 index 5c260187c..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/SummaryInformation.java +++ /dev/null @@ -1,762 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.util.Date; - -import org.apache.poi.hpsf.wellknown.PropertyIDMap; - -/** - *

    Convenience class representing a Summary Information stream in a - * Microsoft Office document.

    - * - * @see DocumentSummaryInformation - */ -public final class SummaryInformation extends SpecialPropertySet { - - /** - *

    The document name a summary information stream usually has in a POIFS - * filesystem.

    - */ - public static final String DEFAULT_STREAM_NAME = "\005SummaryInformation"; - - public PropertyIDMap getPropertySetIDMap() { - return PropertyIDMap.getSummaryInformationProperties(); - } - - - /** - *

    Creates a {@link SummaryInformation} from a given {@link - * PropertySet}.

    - * - * @param ps A property set which should be created from a summary - * information stream. - * @throws UnexpectedPropertySetTypeException if ps does not - * contain a summary information stream. - */ - public SummaryInformation(final PropertySet ps) - throws UnexpectedPropertySetTypeException - { - super(ps); - if (!isSummaryInformation()) - throw new UnexpectedPropertySetTypeException("Not a " - + getClass().getName()); - } - - - - /** - *

    Returns the title (or null).

    - * - * @return The title or null - */ - public String getTitle() - { - return getPropertyStringValue(PropertyIDMap.PID_TITLE); - } - - - - /** - *

    Sets the title.

    - * - * @param title The title to set. - */ - public void setTitle(final String title) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_TITLE, title); - } - - - - /** - *

    Removes the title.

    - */ - public void removeTitle() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_TITLE); - } - - - - /** - *

    Returns the subject (or null).

    - * - * @return The subject or null - */ - public String getSubject() - { - return getPropertyStringValue(PropertyIDMap.PID_SUBJECT); - } - - - - /** - *

    Sets the subject.

    - * - * @param subject The subject to set. - */ - public void setSubject(final String subject) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_SUBJECT, subject); - } - - - - /** - *

    Removes the subject.

    - */ - public void removeSubject() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_SUBJECT); - } - - - - /** - *

    Returns the author (or null).

    - * - * @return The author or null - */ - public String getAuthor() - { - return getPropertyStringValue(PropertyIDMap.PID_AUTHOR); - } - - - - /** - *

    Sets the author.

    - * - * @param author The author to set. - */ - public void setAuthor(final String author) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_AUTHOR, author); - } - - - - /** - *

    Removes the author.

    - */ - public void removeAuthor() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_AUTHOR); - } - - - - /** - *

    Returns the keywords (or null).

    - * - * @return The keywords or null - */ - public String getKeywords() - { - return getPropertyStringValue(PropertyIDMap.PID_KEYWORDS); - } - - - - /** - *

    Sets the keywords.

    - * - * @param keywords The keywords to set. - */ - public void setKeywords(final String keywords) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_KEYWORDS, keywords); - } - - - - /** - *

    Removes the keywords.

    - */ - public void removeKeywords() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_KEYWORDS); - } - - - - /** - *

    Returns the comments (or null).

    - * - * @return The comments or null - */ - public String getComments() - { - return getPropertyStringValue(PropertyIDMap.PID_COMMENTS); - } - - - - /** - *

    Sets the comments.

    - * - * @param comments The comments to set. - */ - public void setComments(final String comments) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_COMMENTS, comments); - } - - - - /** - *

    Removes the comments.

    - */ - public void removeComments() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_COMMENTS); - } - - - - /** - *

    Returns the template (or null).

    - * - * @return The template or null - */ - public String getTemplate() - { - return getPropertyStringValue(PropertyIDMap.PID_TEMPLATE); - } - - - - /** - *

    Sets the template.

    - * - * @param template The template to set. - */ - public void setTemplate(final String template) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_TEMPLATE, template); - } - - - - /** - *

    Removes the template.

    - */ - public void removeTemplate() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_TEMPLATE); - } - - - - /** - *

    Returns the last author (or null).

    - * - * @return The last author or null - */ - public String getLastAuthor() - { - return getPropertyStringValue(PropertyIDMap.PID_LASTAUTHOR); - } - - - - /** - *

    Sets the last author.

    - * - * @param lastAuthor The last author to set. - */ - public void setLastAuthor(final String lastAuthor) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_LASTAUTHOR, lastAuthor); - } - - - - /** - *

    Removes the last author.

    - */ - public void removeLastAuthor() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_LASTAUTHOR); - } - - - - /** - *

    Returns the revision number (or null).

    - * - * @return The revision number or null - */ - public String getRevNumber() - { - return getPropertyStringValue(PropertyIDMap.PID_REVNUMBER); - } - - - - /** - *

    Sets the revision number.

    - * - * @param revNumber The revision number to set. - */ - public void setRevNumber(final String revNumber) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_REVNUMBER, revNumber); - } - - - - /** - *

    Removes the revision number.

    - */ - public void removeRevNumber() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_REVNUMBER); - } - - - - /** - *

    Returns the total time spent in editing the document (or - * 0).

    - * - * @return The total time spent in editing the document or 0 if the {@link - * SummaryInformation} does not contain this information. - */ - public long getEditTime() - { - final Date d = (Date) getProperty(PropertyIDMap.PID_EDITTIME); - if (d == null) { - return 0; - } - return Util.dateToFileTime(d); - } - - - - /** - *

    Sets the total time spent in editing the document.

    - * - * @param time The time to set. - */ - public void setEditTime(final long time) - { - final Date d = Util.filetimeToDate(time); - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_EDITTIME, Variant.VT_FILETIME, d); - } - - - - /** - *

    Remove the total time spent in editing the document.

    - */ - public void removeEditTime() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_EDITTIME); - } - - - - /** - *

    Returns the last printed time (or null).

    - * - * @return The last printed time or null - */ - public Date getLastPrinted() - { - return (Date) getProperty(PropertyIDMap.PID_LASTPRINTED); - } - - - - /** - *

    Sets the lastPrinted.

    - * - * @param lastPrinted The lastPrinted to set. - */ - public void setLastPrinted(final Date lastPrinted) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_LASTPRINTED, Variant.VT_FILETIME, - lastPrinted); - } - - - - /** - *

    Removes the lastPrinted.

    - */ - public void removeLastPrinted() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_LASTPRINTED); - } - - - - /** - *

    Returns the creation time (or null).

    - * - * @return The creation time or null - */ - public Date getCreateDateTime() - { - return (Date) getProperty(PropertyIDMap.PID_CREATE_DTM); - } - - - - /** - *

    Sets the creation time.

    - * - * @param createDateTime The creation time to set. - */ - public void setCreateDateTime(final Date createDateTime) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_CREATE_DTM, Variant.VT_FILETIME, - createDateTime); - } - - - - /** - *

    Removes the creation time.

    - */ - public void removeCreateDateTime() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_CREATE_DTM); - } - - - - /** - *

    Returns the last save time (or null).

    - * - * @return The last save time or null - */ - public Date getLastSaveDateTime() - { - return (Date) getProperty(PropertyIDMap.PID_LASTSAVE_DTM); - } - - - - /** - *

    Sets the total time spent in editing the document.

    - * - * @param time The time to set. - */ - public void setLastSaveDateTime(final Date time) - { - final MutableSection s = (MutableSection) getFirstSection(); - s - .setProperty(PropertyIDMap.PID_LASTSAVE_DTM, - Variant.VT_FILETIME, time); - } - - - - /** - *

    Remove the total time spent in editing the document.

    - */ - public void removeLastSaveDateTime() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_LASTSAVE_DTM); - } - - - - /** - *

    Returns the page count or 0 if the {@link SummaryInformation} does - * not contain a page count.

    - * - * @return The page count or 0 if the {@link SummaryInformation} does not - * contain a page count. - */ - public int getPageCount() - { - return getPropertyIntValue(PropertyIDMap.PID_PAGECOUNT); - } - - - - /** - *

    Sets the page count.

    - * - * @param pageCount The page count to set. - */ - public void setPageCount(final int pageCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_PAGECOUNT, pageCount); - } - - - - /** - *

    Removes the page count.

    - */ - public void removePageCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_PAGECOUNT); - } - - - - /** - *

    Returns the word count or 0 if the {@link SummaryInformation} does - * not contain a word count.

    - * - * @return The word count or null - */ - public int getWordCount() - { - return getPropertyIntValue(PropertyIDMap.PID_WORDCOUNT); - } - - - - /** - *

    Sets the word count.

    - * - * @param wordCount The word count to set. - */ - public void setWordCount(final int wordCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_WORDCOUNT, wordCount); - } - - - - /** - *

    Removes the word count.

    - */ - public void removeWordCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_WORDCOUNT); - } - - - - /** - *

    Returns the character count or 0 if the {@link SummaryInformation} - * does not contain a char count.

    - * - * @return The character count or null - */ - public int getCharCount() - { - return getPropertyIntValue(PropertyIDMap.PID_CHARCOUNT); - } - - - - /** - *

    Sets the character count.

    - * - * @param charCount The character count to set. - */ - public void setCharCount(final int charCount) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_CHARCOUNT, charCount); - } - - - - /** - *

    Removes the character count.

    - */ - public void removeCharCount() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_CHARCOUNT); - } - - - - /** - *

    Returns the thumbnail (or null) when this - * method is implemented. Please note that the return type is likely to - * change!

    - * - *

    To process this data, you may wish to make use of the - * {@link Thumbnail} class. The raw data is generally - * an image in WMF or Clipboard (BMP?) format

    - * - * @return The thumbnail or null - */ - public byte[] getThumbnail() - { - return (byte[]) getProperty(PropertyIDMap.PID_THUMBNAIL); - } - - /** - *

    Returns the thumbnail (or null), processed - * as an object which is (largely) able to unpack the thumbnail - * image data.

    - * - * @return The thumbnail or null - */ - public Thumbnail getThumbnailThumbnail() - { - byte[] data = getThumbnail(); - if (data == null) return null; - return new Thumbnail(data); - } - - - - /** - *

    Sets the thumbnail.

    - * - * @param thumbnail The thumbnail to set. - */ - public void setThumbnail(final byte[] thumbnail) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_THUMBNAIL, /* FIXME: */ - Variant.VT_LPSTR, thumbnail); - } - - - - /** - *

    Removes the thumbnail.

    - */ - public void removeThumbnail() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_THUMBNAIL); - } - - - - /** - *

    Returns the application name (or null).

    - * - * @return The application name or null - */ - public String getApplicationName() - { - return getPropertyStringValue(PropertyIDMap.PID_APPNAME); - } - - - - /** - *

    Sets the application name.

    - * - * @param applicationName The application name to set. - */ - public void setApplicationName(final String applicationName) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_APPNAME, applicationName); - } - - - - /** - *

    Removes the application name.

    - */ - public void removeApplicationName() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_APPNAME); - } - - - - /** - *

    Returns a security code which is one of the following values:

    - * - *
      - * - *
    • 0 if the {@link SummaryInformation} does not contain a - * security field or if there is no security on the document. Use - * {@link PropertySet#wasNull()} to distinguish between the two - * cases!

    • - * - *
    • 1 if the document is password protected

    • - * - *
    • 2 if the document is read-only recommended

    • - * - *
    • 4 if the document is read-only enforced

    • - * - *
    • 8 if the document is locked for annotations

    • - * - *
    - * - * @return The security code or null - */ - public int getSecurity() - { - return getPropertyIntValue(PropertyIDMap.PID_SECURITY); - } - - - - /** - *

    Sets the security code.

    - * - * @param security The security code to set. - */ - public void setSecurity(final int security) - { - final MutableSection s = (MutableSection) getFirstSection(); - s.setProperty(PropertyIDMap.PID_SECURITY, security); - } - - - - /** - *

    Removes the security code.

    - */ - public void removeSecurity() - { - final MutableSection s = (MutableSection) getFirstSection(); - s.removeProperty(PropertyIDMap.PID_SECURITY); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Thumbnail.java b/trunk/src/java/org/apache/poi/hpsf/Thumbnail.java deleted file mode 100644 index a1faf3d08..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Thumbnail.java +++ /dev/null @@ -1,273 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import org.apache.poi.util.LittleEndian; -/** - *

    Class to manipulate data in the Clipboard Variant ({@link - * Variant#VT_CF VT_CF}) format.

    - * - * @see SummaryInformation#getThumbnail() - * @see Clipboard Operations - */ -public final class Thumbnail { - - /** - *

    Offset in bytes where the Clipboard Format Tag starts in the - * byte[] returned by {@link - * SummaryInformation#getThumbnail()}

    - */ - public static final int OFFSET_CFTAG = 4; - - /** - *

    Offset in bytes where the Clipboard Format starts in the - * byte[] returned by {@link - * SummaryInformation#getThumbnail()}

    - * - *

    This is only valid if the Clipboard Format Tag is {@link - * #CFTAG_WINDOWS}

    - */ - public static final int OFFSET_CF = 8; - - /** - *

    Offset in bytes where the Windows Metafile (WMF) image data - * starts in the byte[] returned by {@link - * SummaryInformation#getThumbnail()}

    - * - *

    There is only WMF data at this point in the - * byte[] if the Clipboard Format Tag is {@link - * #CFTAG_WINDOWS} and the Clipboard Format is {@link - * #CF_METAFILEPICT}.

    - * - *

    Note: The byte[] that starts at - * OFFSET_WMFDATA and ends at - * getThumbnail().length - 1 forms a complete WMF - * image. It can be saved to disk with a .wmf file - * type and read using a WMF-capable image viewer.

    - */ - public static final int OFFSET_WMFDATA = 20; - - /** - *

    Clipboard Format Tag - Windows clipboard format

    - * - *

    A DWORD indicating a built-in Windows clipboard - * format value

    - */ - public static final int CFTAG_WINDOWS = -1; - - /** - *

    Clipboard Format Tag - Macintosh clipboard format

    - * - *

    A DWORD indicating a Macintosh clipboard format - * value

    - */ - public static final int CFTAG_MACINTOSH = -2; - - /** - *

    Clipboard Format Tag - Format ID

    - * - *

    A GUID containing a format identifier (FMTID). This is - * rarely used.

    - */ - public static final int CFTAG_FMTID = -3; - - /** - *

    Clipboard Format Tag - No Data

    - * - *

    A DWORD indicating No data. This is rarely - * used.

    - */ - public static final int CFTAG_NODATA = 0; - - /** - *

    Clipboard Format - Windows metafile format. This is the - * recommended way to store thumbnails in Property Streams.

    - * - *

    Note: This is not the same format used in - * regular WMF images. The clipboard version of this format has an - * extra clipboard-specific header.

    - */ - public static final int CF_METAFILEPICT = 3; - - /** - *

    Clipboard Format - Device Independent Bitmap

    - */ - public static final int CF_DIB = 8; - - /** - *

    Clipboard Format - Enhanced Windows metafile format

    - */ - public static final int CF_ENHMETAFILE = 14; - - /** - *

    Clipboard Format - Bitmap

    - */ - public static final int CF_BITMAP = 2; - - /** - *

    A byte[] to hold a thumbnail image in ({@link - * Variant#VT_CF VT_CF}) format.

    - */ - private byte[] _thumbnailData = null; - - - - /** - *

    Default Constructor. If you use it then one you'll have to add - * the thumbnail byte[] from {@link - * SummaryInformation#getThumbnail()} to do any useful - * manipulations, otherwise you'll get a - * NullPointerException.

    - */ - public Thumbnail() - { - super(); - } - - - - /** - *

    Creates a Thumbnail instance and initializes - * with the specified image bytes.

    - * - * @param thumbnailData The thumbnail data - */ - public Thumbnail(final byte[] thumbnailData) - { - this._thumbnailData = thumbnailData; - } - - - - /** - *

    Returns the thumbnail as a byte[] in {@link - * Variant#VT_CF VT_CF} format.

    - * - * @return The thumbnail value - * @see SummaryInformation#getThumbnail() - */ - public byte[] getThumbnail() - { - return _thumbnailData; - } - - - - /** - *

    Sets the Thumbnail's underlying byte[] in - * {@link Variant#VT_CF VT_CF} format.

    - * - * @param thumbnail The new thumbnail value - * @see SummaryInformation#getThumbnail() - */ - public void setThumbnail(final byte[] thumbnail) - { - this._thumbnailData = thumbnail; - } - - - - /** - *

    Returns an int representing the Clipboard - * Format Tag

    - * - *

    Possible return values are:

    - *
      - *
    • {@link #CFTAG_WINDOWS CFTAG_WINDOWS}
    • - *
    • {@link #CFTAG_MACINTOSH CFTAG_MACINTOSH}
    • - *
    • {@link #CFTAG_FMTID CFTAG_FMTID}
    • - *
    • {@link #CFTAG_NODATA CFTAG_NODATA}
    • - *
    - * - * @return A flag indicating the Clipboard Format Tag - */ - public long getClipboardFormatTag() - { - long clipboardFormatTag = LittleEndian.getInt(getThumbnail(), - OFFSET_CFTAG); - return clipboardFormatTag; - } - - - - /** - *

    Returns an int representing the Clipboard - * Format

    - * - *

    Will throw an exception if the Thumbnail's Clipboard Format - * Tag is not {@link Thumbnail#CFTAG_WINDOWS CFTAG_WINDOWS}.

    - * - *

    Possible return values are:

    - * - *
      - *
    • {@link #CF_METAFILEPICT CF_METAFILEPICT}
    • - *
    • {@link #CF_DIB CF_DIB}
    • - *
    • {@link #CF_ENHMETAFILE CF_ENHMETAFILE}
    • - *
    • {@link #CF_BITMAP CF_BITMAP}
    • - *
    - * - * @return a flag indicating the Clipboard Format - * @throws HPSFException if the Thumbnail isn't CFTAG_WINDOWS - */ - public long getClipboardFormat() throws HPSFException - { - if (!(getClipboardFormatTag() == CFTAG_WINDOWS)) - throw new HPSFException("Clipboard Format Tag of Thumbnail must " + - "be CFTAG_WINDOWS."); - - return LittleEndian.getInt(getThumbnail(), OFFSET_CF); - } - - - - /** - *

    Returns the Thumbnail as a byte[] of WMF data - * if the Thumbnail's Clipboard Format Tag is {@link - * #CFTAG_WINDOWS CFTAG_WINDOWS} and its Clipboard Format is - * {@link #CF_METAFILEPICT CF_METAFILEPICT}

    This - * byte[] is in the traditional WMF file, not the - * clipboard-specific version with special headers.

    - * - *

    See http://www.wvware.com/caolan/ora-wmf.html - * for more information on the WMF image format.

    - * - * @return A WMF image of the Thumbnail - * @throws HPSFException if the Thumbnail isn't CFTAG_WINDOWS and - * CF_METAFILEPICT - */ - public byte[] getThumbnailAsWMF() throws HPSFException - { - if (!(getClipboardFormatTag() == CFTAG_WINDOWS)) - throw new HPSFException("Clipboard Format Tag of Thumbnail must " + - "be CFTAG_WINDOWS."); - if (!(getClipboardFormat() == CF_METAFILEPICT)) { - throw new HPSFException("Clipboard Format of Thumbnail must " + - "be CF_METAFILEPICT."); - } - byte[] thumbnail = getThumbnail(); - int wmfImageLength = thumbnail.length - OFFSET_WMFDATA; - byte[] wmfImage = new byte[wmfImageLength]; - System.arraycopy(thumbnail, - OFFSET_WMFDATA, - wmfImage, - 0, - wmfImageLength); - return wmfImage; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/TypeWriter.java b/trunk/src/java/org/apache/poi/hpsf/TypeWriter.java deleted file mode 100644 index 16270eb1d..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/TypeWriter.java +++ /dev/null @@ -1,187 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - *

    Class for writing little-endian data and more.

    - */ -public class TypeWriter -{ - - /** - *

    Writes a two-byte value (short) to an output stream.

    - * - * @param out The stream to write to. - * @param n The value to write. - * @return The number of bytes that have been written. - * @exception IOException if an I/O error occurs - */ - public static int writeToStream( final OutputStream out, final short n ) - throws IOException - { - LittleEndian.putShort( out, n ); // FIXME: unsigned - return LittleEndian.SHORT_SIZE; - } - - /** - *

    Writes a four-byte value to an output stream.

    - * - * @param out The stream to write to. - * @param n The value to write. - * @exception IOException if an I/O error occurs - * @return The number of bytes written to the output stream. - */ - public static int writeToStream( final OutputStream out, final int n ) - throws IOException - { - LittleEndian.putInt( n, out ); - return LittleEndian.INT_SIZE; - } - - /** - *

    Writes a eight-byte value to an output stream.

    - * - * @param out The stream to write to. - * @param n The value to write. - * @exception IOException if an I/O error occurs - * @return The number of bytes written to the output stream. - */ - public static int writeToStream( final OutputStream out, final long n ) - throws IOException - { - LittleEndian.putLong( n, out ); - return LittleEndian.LONG_SIZE; - } - - /** - *

    Writes an unsigned two-byte value to an output stream.

    - * - * @param out The stream to write to - * @param n The value to write - * @exception IOException if an I/O error occurs - */ - public static void writeUShortToStream( final OutputStream out, final int n ) - throws IOException - { - int high = n & 0xFFFF0000; - if ( high != 0 ) - throw new IllegalPropertySetDataException( "Value " + n - + " cannot be represented by 2 bytes." ); - LittleEndian.putUShort( n, out ); - } - - /** - *

    Writes an unsigned four-byte value to an output stream.

    - * - * @param out The stream to write to. - * @param n The value to write. - * @return The number of bytes that have been written to the output stream. - * @exception IOException if an I/O error occurs - */ - public static int writeUIntToStream( final OutputStream out, final long n ) - throws IOException - { - long high = n & 0xFFFFFFFF00000000L; - if ( high != 0 && high != 0xFFFFFFFF00000000L ) - throw new IllegalPropertySetDataException( "Value " + n - + " cannot be represented by 4 bytes." ); - LittleEndian.putUInt( n, out ); - return LittleEndian.INT_SIZE; - } - - /** - *

    Writes a 16-byte {@link ClassID} to an output stream.

    - * - * @param out The stream to write to - * @param n The value to write - * @return The number of bytes written - * @exception IOException if an I/O error occurs - */ - public static int writeToStream(final OutputStream out, final ClassID n) - throws IOException - { - byte[] b = new byte[16]; - n.write(b, 0); - out.write(b, 0, b.length); - return b.length; - } - - - - /** - *

    Writes an array of {@link Property} instances to an output stream - * according to the Horrible Property Stream Format.

    - * - * @param out The stream to write to - * @param properties The array to write to the stream - * @param codepage The codepage number to use for writing strings - * @exception IOException if an I/O error occurs - * @throws UnsupportedVariantTypeException if HPSF does not support some - * variant type. - */ - public static void writeToStream(final OutputStream out, - final Property[] properties, - final int codepage) - throws IOException, UnsupportedVariantTypeException - { - /* If there are no properties don't write anything. */ - if (properties == null) - return; - - /* Write the property list. This is a list containing pairs of property - * ID and offset into the stream. */ - for (int i = 0; i < properties.length; i++) - { - final Property p = properties[i]; - writeUIntToStream(out, p.getID()); - writeUIntToStream(out, p.getSize()); - } - - /* Write the properties themselves. */ - for (int i = 0; i < properties.length; i++) - { - final Property p = properties[i]; - long type = p.getType(); - writeUIntToStream(out, type); - VariantSupport.write(out, (int) type, p.getValue(), codepage); - } - } - - - - /** - *

    Writes a double value value to an output stream.

    - * - * @param out The stream to write to. - * @param n The value to write. - * @exception IOException if an I/O error occurs - * @return The number of bytes written to the output stream. - */ - public static int writeToStream( final OutputStream out, final double n ) - throws IOException - { - LittleEndian.putDouble( n, out ); - return LittleEndian.DOUBLE_SIZE; - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/TypedPropertyValue.java b/trunk/src/java/org/apache/poi/hpsf/TypedPropertyValue.java deleted file mode 100644 index 3093a10af..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/TypedPropertyValue.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -@Internal -class TypedPropertyValue -{ - private static final POILogger logger = POILogFactory - .getLogger( TypedPropertyValue.class ); - - private int _type; - - private Object _value; - - TypedPropertyValue() - { - } - - TypedPropertyValue( byte[] data, int startOffset ) - { - read( data, startOffset ); - } - - TypedPropertyValue( int type, Object value ) - { - _type = type; - _value = value; - } - - Object getValue() - { - return _value; - } - - int read( byte[] data, int startOffset ) - { - int offset = startOffset; - - _type = LittleEndian.getShort( data, offset ); - offset += LittleEndian.SHORT_SIZE; - - short padding = LittleEndian.getShort( data, offset ); - offset += LittleEndian.SHORT_SIZE; - if ( padding != 0 ) - { - logger.log( POILogger.WARN, "TypedPropertyValue padding at offset " - + offset + " MUST be 0, but it's value is " + padding ); - } - - offset += readValue( data, offset ); - - return offset - startOffset; - } - - int readValue( byte[] data, int offset ) // NOSONAR - { - switch ( _type ) - { - case Variant.VT_EMPTY: - case Variant.VT_NULL: - _value = null; - return 0; - - case Variant.VT_R4: - case Variant.VT_I2: - _value = Short.valueOf( LittleEndian.getShort( data, offset ) ); - return 4; - - case Variant.VT_INT: - case Variant.VT_I4: - _value = Integer.valueOf( LittleEndian.getInt( data, offset ) ); - return 4; - - case Variant.VT_R8: - _value = Double.valueOf( LittleEndian.getDouble( data, offset ) ); - return 8; - - case Variant.VT_CY: - _value = new Currency( data, offset ); - return Currency.SIZE; - - case Variant.VT_DATE: - _value = new Date( data, offset ); - return Date.SIZE; - - case Variant.VT_BSTR: - _value = new CodePageString( data, offset ); - return ( (CodePageString) _value ).getSize(); - - case Variant.VT_BOOL: - _value = new VariantBool( data, offset ); - return VariantBool.SIZE; - - case Variant.VT_DECIMAL: - _value = new Decimal( data, offset ); - return Decimal.SIZE; - - case Variant.VT_I1: - _value = Byte.valueOf( data[offset] ); - return 1; - - case Variant.VT_UI1: - _value = Short.valueOf( LittleEndian.getUByte( data, offset ) ); - return 2; - - case Variant.VT_UI2: - _value = Integer.valueOf( LittleEndian.getUShort( data, offset ) ); - return 4; - - case Variant.VT_UINT: - case Variant.VT_UI4: - case Variant.VT_ERROR: - _value = Long.valueOf( LittleEndian.getUInt( data, offset ) ); - return 4; - - case Variant.VT_I8: - _value = Long.valueOf( LittleEndian.getLong( data, offset ) ); - return 8; - - case Variant.VT_UI8: - _value = LittleEndian.getByteArray( data, offset, 8 ); - return 8; - - case Variant.VT_LPSTR: - _value = new CodePageString( data, offset ); - return ( (CodePageString) _value ).getSize(); - - case Variant.VT_LPWSTR: - _value = new UnicodeString( data, offset ); - return ( (UnicodeString) _value ).getSize(); - - case Variant.VT_FILETIME: - _value = new Filetime( data, offset ); - return Filetime.SIZE; - - case Variant.VT_BLOB: - _value = new Blob( data, offset ); - return ( (Blob) _value ).getSize(); - - case Variant.VT_STREAM: - case Variant.VT_STORAGE: - case Variant.VT_STREAMED_OBJECT: - case Variant.VT_STORED_OBJECT: - _value = new IndirectPropertyName( data, offset ); - return ( (IndirectPropertyName) _value ).getSize(); - - case Variant.VT_BLOB_OBJECT: - _value = new Blob( data, offset ); - return ( (Blob) _value ).getSize(); - - case Variant.VT_CF: - _value = new ClipboardData( data, offset ); - return ( (ClipboardData) _value ).getSize(); - - case Variant.VT_CLSID: - _value = new GUID( data, offset ); - return GUID.SIZE; - - case Variant.VT_VERSIONED_STREAM: - _value = new VersionedStream( data, offset ); - return ( (VersionedStream) _value ).getSize(); - - case Variant.VT_VECTOR | Variant.VT_I2: - case Variant.VT_VECTOR | Variant.VT_I4: - case Variant.VT_VECTOR | Variant.VT_R4: - case Variant.VT_VECTOR | Variant.VT_R8: - case Variant.VT_VECTOR | Variant.VT_CY: - case Variant.VT_VECTOR | Variant.VT_DATE: - case Variant.VT_VECTOR | Variant.VT_BSTR: - case Variant.VT_VECTOR | Variant.VT_ERROR: - case Variant.VT_VECTOR | Variant.VT_BOOL: - case Variant.VT_VECTOR | Variant.VT_VARIANT: - case Variant.VT_VECTOR | Variant.VT_I1: - case Variant.VT_VECTOR | Variant.VT_UI1: - case Variant.VT_VECTOR | Variant.VT_UI2: - case Variant.VT_VECTOR | Variant.VT_UI4: - case Variant.VT_VECTOR | Variant.VT_I8: - case Variant.VT_VECTOR | Variant.VT_UI8: - case Variant.VT_VECTOR | Variant.VT_LPSTR: - case Variant.VT_VECTOR | Variant.VT_LPWSTR: - case Variant.VT_VECTOR | Variant.VT_FILETIME: - case Variant.VT_VECTOR | Variant.VT_CF: - case Variant.VT_VECTOR | Variant.VT_CLSID: - _value = new Vector( (short) ( _type & 0x0FFF ) ); - return ( (Vector) _value ).read( data, offset ); - - case Variant.VT_ARRAY | Variant.VT_I2: - case Variant.VT_ARRAY | Variant.VT_I4: - case Variant.VT_ARRAY | Variant.VT_R4: - case Variant.VT_ARRAY | Variant.VT_R8: - case Variant.VT_ARRAY | Variant.VT_CY: - case Variant.VT_ARRAY | Variant.VT_DATE: - case Variant.VT_ARRAY | Variant.VT_BSTR: - case Variant.VT_ARRAY | Variant.VT_ERROR: - case Variant.VT_ARRAY | Variant.VT_BOOL: - case Variant.VT_ARRAY | Variant.VT_VARIANT: - case Variant.VT_ARRAY | Variant.VT_DECIMAL: - case Variant.VT_ARRAY | Variant.VT_I1: - case Variant.VT_ARRAY | Variant.VT_UI1: - case Variant.VT_ARRAY | Variant.VT_UI2: - case Variant.VT_ARRAY | Variant.VT_UI4: - case Variant.VT_ARRAY | Variant.VT_INT: - case Variant.VT_ARRAY | Variant.VT_UINT: - _value = new Array(); - return ( (Array) _value ).read( data, offset ); - - default: - throw new UnsupportedOperationException( - "Unknown (possibly, incorrect) TypedPropertyValue type: " - + _type ); - } - } - - int readValuePadded( byte[] data, int offset ) - { - int nonPadded = readValue( data, offset ); - return ( nonPadded & 0x03 ) == 0 ? nonPadded : nonPadded - + ( 4 - ( nonPadded & 0x03 ) ); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java b/trunk/src/java/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java deleted file mode 100644 index 54efe0f44..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if a certain type of property set is - * expected (e.g. a Document Summary Information) but the provided - * property set is not of that type.

    - * - *

    The constructors of this class are analogous to those of its - * superclass and documented there.

    - */ -public class UnexpectedPropertySetTypeException extends HPSFException -{ - - /** - *

    Creates an {@link UnexpectedPropertySetTypeException}.

    - */ - public UnexpectedPropertySetTypeException() - { - super(); - } - - - /** - *

    Creates an {@link UnexpectedPropertySetTypeException} with a message - * string.

    - * - * @param msg The message string. - */ - public UnexpectedPropertySetTypeException(final String msg) - { - super(msg); - } - - - /** - *

    Creates a new {@link UnexpectedPropertySetTypeException} with a - * reason.

    - * - * @param reason The reason, i.e. a throwable that indirectly - * caused this exception. - */ - public UnexpectedPropertySetTypeException(final Throwable reason) - { - super(reason); - } - - - /** - *

    Creates an {@link UnexpectedPropertySetTypeException} with a message - * string and a reason.

    - * - * @param msg The message string. - * @param reason The reason, i.e. a throwable that indirectly - * caused this exception. - */ - public UnexpectedPropertySetTypeException(final String msg, - final Throwable reason) - { - super(msg, reason); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/UnicodeString.java b/trunk/src/java/org/apache/poi/hpsf/UnicodeString.java deleted file mode 100644 index 0d3cdbf29..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/UnicodeString.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -@Internal -class UnicodeString { - private final static POILogger logger = - POILogFactory.getLogger( UnicodeString.class ); - - private byte[] _value; - - UnicodeString(byte[] data, int offset) { - int length = LittleEndian.getInt( data, offset ); - int dataOffset = offset + LittleEndian.INT_SIZE; - - if (! validLength(length, data, dataOffset)) { - // If the length looks wrong, this might be because the offset is sometimes expected - // to be on a 4 byte boundary. Try checking with that if so, rather than blowing up with - // and ArrayIndexOutOfBoundsException below - boolean valid = false; - int past4byte = offset % 4; - if (past4byte != 0) { - offset = offset + past4byte; - length = LittleEndian.getInt( data, offset ); - dataOffset = offset + LittleEndian.INT_SIZE; - - valid = validLength(length, data, dataOffset); - } - - if (!valid) { - throw new IllegalPropertySetDataException( - "UnicodeString started at offset #" + offset + - " is not NULL-terminated" ); - } - } - - if ( length == 0 ) - { - _value = new byte[0]; - return; - } - - _value = LittleEndian.getByteArray( data, dataOffset, length * 2 ); - } - - /** - * Checks to see if the specified length seems valid, - * given the amount of data available still to read, - * and the requirement that the string be NULL-terminated - */ - boolean validLength(int length, byte[] data, int offset) { - if (length == 0) { - return true; - } - - int endOffset = offset + (length * 2); - if (endOffset <= data.length) { - // Data Length is OK, ensure it's null terminated too - if (data[endOffset-1] == 0 && data[endOffset-2] == 0) { - // Length looks plausible - return true; - } - } - - // Something's up/invalid with that length for the given data+offset - return false; - } - - int getSize() - { - return LittleEndian.INT_SIZE + _value.length; - } - - byte[] getValue() - { - return _value; - } - - String toJavaString() - { - if ( _value.length == 0 ) - return null; - - String result = StringUtil.getFromUnicodeLE( _value, 0, - _value.length >> 1 ); - - final int terminator = result.indexOf( '\0' ); - if ( terminator == -1 ) - { - logger.log( - POILogger.WARN, - "String terminator (\\0) for UnicodeString property value not found." - + "Continue without trimming and hope for the best." ); - return result; - } - if ( terminator != result.length() - 1 ) - { - logger.log( - POILogger.WARN, - "String terminator (\\0) for UnicodeString property value occured before the end of string. " - + "Trimming and hope for the best." ); - } - return result.substring( 0, terminator ); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/UnsupportedVariantTypeException.java b/trunk/src/java/org/apache/poi/hpsf/UnsupportedVariantTypeException.java deleted file mode 100644 index 12afdcb4c..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/UnsupportedVariantTypeException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import org.apache.poi.util.HexDump; - -/** - *

    This exception is thrown if HPSF encounters a variant type that isn't - * supported yet. Although a variant type is unsupported the value can still be - * retrieved using the {@link VariantTypeException#getValue} method.

    - * - *

    Obviously this class should disappear some day.

    - */ -public abstract class UnsupportedVariantTypeException -extends VariantTypeException -{ - - /** - *

    Constructor.

    - * - * @param variantType The unsupported variant type - * @param value The value who's variant type is not yet supported - */ - public UnsupportedVariantTypeException(final long variantType, - final Object value) - { - super(variantType, value, - "HPSF does not yet support the variant type " + variantType + - " (" + Variant.getVariantName(variantType) + ", " + - HexDump.toHex(variantType) + "). If you want support for " + - "this variant type in one of the next POI releases please " + - "submit a request for enhancement (RFE) to " + - "! Thank you!"); - } - - - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Util.java b/trunk/src/java/org/apache/poi/hpsf/Util.java deleted file mode 100644 index 5d75cb986..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Util.java +++ /dev/null @@ -1,357 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.util.SuppressForbidden; - -/** - *

    Provides various static utility methods.

    - */ -public class Util -{ - - /** - *

    Checks whether two byte arrays a and b - * are equal. They are equal

    - * - *
      - * - *
    • if they have the same length and

    • - * - *
    • if for each i with - * i >= 0 and - * i < a.length holds - * a[i] == b[i].

    • - * - *
    - * - * @param a The first byte array - * @param b The first byte array - * @return true if the byte arrays are equal, else - * false - */ - public static boolean equal(final byte[] a, final byte[] b) - { - if (a.length != b.length) - return false; - for (int i = 0; i < a.length; i++) - if (a[i] != b[i]) - return false; - return true; - } - - - - /** - *

    Copies a part of a byte array into another byte array.

    - * - * @param src The source byte array. - * @param srcOffset Offset in the source byte array. - * @param length The number of bytes to copy. - * @param dst The destination byte array. - * @param dstOffset Offset in the destination byte array. - */ - public static void copy(final byte[] src, final int srcOffset, - final int length, final byte[] dst, - final int dstOffset) - { - for (int i = 0; i < length; i++) - dst[dstOffset + i] = src[srcOffset + i]; - } - - - - /** - *

    Concatenates the contents of several byte arrays into a - * single one.

    - * - * @param byteArrays The byte arrays to be concatened. - * @return A new byte array containing the concatenated byte - * arrays. - */ - public static byte[] cat(final byte[][] byteArrays) - { - int capacity = 0; - for (int i = 0; i < byteArrays.length; i++) - capacity += byteArrays[i].length; - final byte[] result = new byte[capacity]; - int r = 0; - for (int i = 0; i < byteArrays.length; i++) - for (int j = 0; j < byteArrays[i].length; j++) - result[r++] = byteArrays[i][j]; - return result; - } - - - - /** - *

    Copies bytes from a source byte array into a new byte - * array.

    - * - * @param src Copy from this byte array. - * @param offset Start copying here. - * @param length Copy this many bytes. - * @return The new byte array. Its length is number of copied bytes. - */ - public static byte[] copy(final byte[] src, final int offset, - final int length) - { - final byte[] result = new byte[length]; - copy(src, offset, length, result, 0); - return result; - } - - - - /** - *

    The difference between the Windows epoch (1601-01-01 - * 00:00:00) and the Unix epoch (1970-01-01 00:00:00) in - * milliseconds: 11644473600000L. (Use your favorite spreadsheet - * program to verify the correctness of this value. By the way, - * did you notice that you can tell from the epochs which - * operating system is the modern one? :-))

    - */ - public static final long EPOCH_DIFF = 11644473600000L; - - - /** - *

    Converts a Windows FILETIME into a {@link Date}. The Windows - * FILETIME structure holds a date and time associated with a - * file. The structure identifies a 64-bit integer specifying the - * number of 100-nanosecond intervals which have passed since - * January 1, 1601. This 64-bit value is split into the two double - * words stored in the structure.

    - * - * @param high The higher double word of the FILETIME structure. - * @param low The lower double word of the FILETIME structure. - * @return The Windows FILETIME as a {@link Date}. - */ - public static Date filetimeToDate(final int high, final int low) - { - final long filetime = ((long) high) << 32 | (low & 0xffffffffL); - return filetimeToDate(filetime); - } - - /** - *

    Converts a Windows FILETIME into a {@link Date}. The Windows - * FILETIME structure holds a date and time associated with a - * file. The structure identifies a 64-bit integer specifying the - * number of 100-nanosecond intervals which have passed since - * January 1, 1601.

    - * - * @param filetime The filetime to convert. - * @return The Windows FILETIME as a {@link Date}. - */ - public static Date filetimeToDate(final long filetime) - { - final long ms_since_16010101 = filetime / (1000 * 10); - final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF; - return new Date(ms_since_19700101); - } - - - - /** - *

    Converts a {@link Date} into a filetime.

    - * - * @param date The date to be converted - * @return The filetime - * - * @see #filetimeToDate(long) - * @see #filetimeToDate(int, int) - */ - public static long dateToFileTime(final Date date) - { - long ms_since_19700101 = date.getTime(); - long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF; - return ms_since_16010101 * (1000 * 10); - } - - - /** - *

    Checks whether two collections are equal. Two collections - * C1 and C2 are equal, if the following conditions - * are true:

    - * - *
      - * - *
    • For each c1i (element of C1) there - * is a c2j (element of C2), and - * c1i equals c2j.

    • - * - *
    • For each c2i (element of C2) there - * is a c1j (element of C1) and - * c2i equals c1j.

    • - * - *
    - * - * @param c1 the first collection - * @param c2 the second collection - * @return true if the collections are equal, else - * false. - */ - public static boolean equals(Collection c1, Collection c2) - { - Object[] o1 = c1.toArray(); - Object[] o2 = c2.toArray(); - return internalEquals(o1, o2); - } - - - - /** - *

    Compares to object arrays with regarding the objects' order. For - * example, [1, 2, 3] and [2, 1, 3] are equal.

    - * - * @param c1 The first object array. - * @param c2 The second object array. - * @return true if the object arrays are equal, - * false if they are not. - */ - public static boolean equals(Object[] c1, Object[] c2) - { - final Object[] o1 = c1.clone(); - final Object[] o2 = c2.clone(); - return internalEquals(o1, o2); - } - - private static boolean internalEquals(Object[] o1, Object[] o2) - { - for (int i1 = 0; i1 < o1.length; i1++) - { - final Object obj1 = o1[i1]; - boolean matchFound = false; - for (int i2 = 0; !matchFound && i2 < o1.length; i2++) - { - final Object obj2 = o2[i2]; - if (obj1.equals(obj2)) - { - matchFound = true; - o2[i2] = null; - } - } - if (!matchFound) - return false; - } - return true; - } - - - - /** - *

    Pads a byte array with 0x00 bytes so that its length is a multiple of - * 4.

    - * - * @param ba The byte array to pad. - * @return The padded byte array. - */ - public static byte[] pad4(final byte[] ba) - { - final int PAD = 4; - final byte[] result; - int l = ba.length % PAD; - if (l == 0) - result = ba; - else - { - l = PAD - l; - result = new byte[ba.length + l]; - System.arraycopy(ba, 0, result, 0, ba.length); - } - return result; - } - - - - /** - *

    Pads a character array with 0x0000 characters so that its length is a - * multiple of 4.

    - * - * @param ca The character array to pad. - * @return The padded character array. - */ - public static char[] pad4(final char[] ca) - { - final int PAD = 4; - final char[] result; - int l = ca.length % PAD; - if (l == 0) - result = ca; - else - { - l = PAD - l; - result = new char[ca.length + l]; - System.arraycopy(ca, 0, result, 0, ca.length); - } - return result; - } - - - - /** - *

    Pads a string with 0x0000 characters so that its length is a - * multiple of 4.

    - * - * @param s The string to pad. - * @return The padded string as a character array. - */ - public static char[] pad4(final String s) - { - return pad4(s.toCharArray()); - } - - - - /** - *

    Returns a textual representation of a {@link Throwable}, including a - * stacktrace.

    - * - * @param t The {@link Throwable} - * - * @return a string containing the output of a call to - * t.printStacktrace(). - */ - @SuppressForbidden("uses printStackTrace") - public static String toString(final Throwable t) - { - final StringWriter sw = new StringWriter(); - final PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - pw.close(); - try - { - sw.close(); - return sw.toString(); - } - catch (IOException e) - { - final StringBuffer b = new StringBuffer(t.getMessage()); - b.append("\n"); - b.append("Could not create a stacktrace. Reason: "); - b.append(e.getMessage()); - return b.toString(); - } - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Variant.java b/trunk/src/java/org/apache/poi/hpsf/Variant.java deleted file mode 100644 index 3f606043a..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Variant.java +++ /dev/null @@ -1,517 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - *

    The Variant types as defined by Microsoft's COM. I - * found this information in - * http://www.marin.clara.net/COM/variant_type_definitions.htm.

    - * - *

    In the variant types descriptions the following shortcuts are - * used: [V] - may appear in a VARIANT, - * [T] - may appear in a TYPEDESC, - * [P] - may appear in an OLE property set, - * [S] - may appear in a Safe Array.

    - */ -public class Variant -{ - - /** - *

    [V][P] Nothing, i.e. not a single byte of data.

    - */ - public static final int VT_EMPTY = 0; - - /** - *

    [V][P] SQL style Null.

    - */ - public static final int VT_NULL = 1; - - /** - *

    [V][T][P][S] 2 byte signed int.

    - */ - public static final int VT_I2 = 2; - - /** - *

    [V][T][P][S] 4 byte signed int.

    - */ - public static final int VT_I4 = 3; - - /** - *

    [V][T][P][S] 4 byte real.

    - */ - public static final int VT_R4 = 4; - - /** - *

    [V][T][P][S] 8 byte real.

    - */ - public static final int VT_R8 = 5; - - /** - *

    [V][T][P][S] currency. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_CY = 6; - - /** - *

    [V][T][P][S] date. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_DATE = 7; - - /** - *

    [V][T][P][S] OLE Automation string. How long is this? How is it - * to be interpreted?

    - */ - public static final int VT_BSTR = 8; - - /** - *

    [V][T][P][S] IDispatch *. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_DISPATCH = 9; - - /** - *

    [V][T][S] SCODE. How - * long is this? How is it to be interpreted?

    - */ - public static final int VT_ERROR = 10; - - /** - *

    [V][T][P][S] True=-1, False=0.

    - */ - public static final int VT_BOOL = 11; - - /** - *

    [V][T][P][S] VARIANT *. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_VARIANT = 12; - - /** - *

    [V][T][S] IUnknown *. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_UNKNOWN = 13; - - /** - *

    [V][T][S] 16 byte fixed point.

    - */ - public static final int VT_DECIMAL = 14; - - /** - *

    [T] signed char.

    - */ - public static final int VT_I1 = 16; - - /** - *

    [V][T][P][S] unsigned char.

    - */ - public static final int VT_UI1 = 17; - - /** - *

    [T][P] unsigned short.

    - */ - public static final int VT_UI2 = 18; - - /** - *

    [T][P] unsigned int.

    - */ - public static final int VT_UI4 = 19; - - /** - *

    [T][P] signed 64-bit int.

    - */ - public static final int VT_I8 = 20; - - /** - *

    [T][P] unsigned 64-bit int.

    - */ - public static final int VT_UI8 = 21; - - /** - *

    [T] signed machine int.

    - */ - public static final int VT_INT = 22; - - /** - *

    [T] unsigned machine int.

    - */ - public static final int VT_UINT = 23; - - /** - *

    [T] C style void.

    - */ - public static final int VT_VOID = 24; - - /** - *

    [T] Standard return type. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_HRESULT = 25; - - /** - *

    [T] pointer type. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_PTR = 26; - - /** - *

    [T] (use VT_ARRAY in VARIANT).

    - */ - public static final int VT_SAFEARRAY = 27; - - /** - *

    [T] C style array. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_CARRAY = 28; - - /** - *

    [T] user defined type. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_USERDEFINED = 29; - - /** - *

    [T][P] null terminated string.

    - */ - public static final int VT_LPSTR = 30; - - /** - *

    [T][P] wide (Unicode) null terminated string.

    - */ - public static final int VT_LPWSTR = 31; - - /** - *

    [P] FILETIME. The FILETIME structure holds a date and time - * associated with a file. The structure identifies a 64-bit - * integer specifying the number of 100-nanosecond intervals which - * have passed since January 1, 1601. This 64-bit value is split - * into the two dwords stored in the structure.

    - */ - public static final int VT_FILETIME = 64; - - /** - *

    [P] Length prefixed bytes.

    - */ - public static final int VT_BLOB = 65; - - /** - *

    [P] Name of the stream follows.

    - */ - public static final int VT_STREAM = 66; - - /** - *

    [P] Name of the storage follows.

    - */ - public static final int VT_STORAGE = 67; - - /** - *

    [P] Stream contains an object. How long is this? How is it - * to be interpreted?

    - */ - public static final int VT_STREAMED_OBJECT = 68; - - /** - *

    [P] Storage contains an object. How long is this? How is it - * to be interpreted?

    - */ - public static final int VT_STORED_OBJECT = 69; - - /** - *

    [P] Blob contains an object. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_BLOB_OBJECT = 70; - - /** - *

    [P] Clipboard format. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_CF = 71; - - /** - *

    [P] A Class ID.

    - * - *

    It consists of a 32 bit unsigned integer indicating the size - * of the structure, a 32 bit signed integer indicating (Clipboard - * Format Tag) indicating the type of data that it contains, and - * then a byte array containing the data.

    - * - *

    The valid Clipboard Format Tags are:

    - * - *
      - *
    • {@link Thumbnail#CFTAG_WINDOWS}
    • - *
    • {@link Thumbnail#CFTAG_MACINTOSH}
    • - *
    • {@link Thumbnail#CFTAG_NODATA}
    • - *
    • {@link Thumbnail#CFTAG_FMTID}
    • - *
    - * - *
    typedef struct tagCLIPDATA {
    -     * // cbSize is the size of the buffer pointed to
    -     * // by pClipData, plus sizeof(ulClipFmt)
    -     * ULONG              cbSize;
    -     * long               ulClipFmt;
    -     * BYTE*              pClipData;
    -     * } CLIPDATA;
    - * - *

    See - * msdn.microsoft.com/library/en-us/com/stgrstrc_0uwk.asp.

    - */ - public static final int VT_CLSID = 72; - - /** - * "MUST be a VersionedStream. The storage representing the (non-simple) - * property set MUST have a stream element with the name in the StreamName - * field." -- [MS-OLEPS] -- v20110920; Object Linking and Embedding (OLE) - * Property Set Data Structures; page 24 / 63 - */ - public static final int VT_VERSIONED_STREAM = 0x0049; - - /** - *

    [P] simple counted array. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_VECTOR = 0x1000; - - /** - *

    [V] SAFEARRAY*. How - * long is this? How is it to be interpreted?

    - */ - public static final int VT_ARRAY = 0x2000; - - /** - *

    [V] void* for local use. How long is this? How is it to be - * interpreted?

    - */ - public static final int VT_BYREF = 0x4000; - - /** - *

    FIXME (3): Document this!

    - */ - public static final int VT_RESERVED = 0x8000; - - /** - *

    FIXME (3): Document this!

    - */ - public static final int VT_ILLEGAL = 0xFFFF; - - /** - *

    FIXME (3): Document this!

    - */ - public static final int VT_ILLEGALMASKED = 0xFFF; - - /** - *

    FIXME (3): Document this!

    - */ - public static final int VT_TYPEMASK = 0xFFF; - - - - /** - *

    Maps the numbers denoting the variant types to their corresponding - * variant type names.

    - */ - private static Map numberToName; - - private static Map numberToLength; - - /** - *

    Denotes a variant type with a length that is unknown to HPSF yet.

    - */ - public static final Integer LENGTH_UNKNOWN = Integer.valueOf(-2); - - /** - *

    Denotes a variant type with a variable length.

    - */ - public static final Integer LENGTH_VARIABLE = Integer.valueOf(-1); - - /** - *

    Denotes a variant type with a length of 0 bytes.

    - */ - public static final Integer LENGTH_0 = Integer.valueOf(0); - - /** - *

    Denotes a variant type with a length of 2 bytes.

    - */ - public static final Integer LENGTH_2 = Integer.valueOf(2); - - /** - *

    Denotes a variant type with a length of 4 bytes.

    - */ - public static final Integer LENGTH_4 = Integer.valueOf(4); - - /** - *

    Denotes a variant type with a length of 8 bytes.

    - */ - public static final Integer LENGTH_8 = Integer.valueOf(8); - - - - static - { - /* Initialize the number-to-name map: */ - Map tm1 = new HashMap(); - tm1.put(Long.valueOf(0), "VT_EMPTY"); - tm1.put(Long.valueOf(1), "VT_NULL"); - tm1.put(Long.valueOf(2), "VT_I2"); - tm1.put(Long.valueOf(3), "VT_I4"); - tm1.put(Long.valueOf(4), "VT_R4"); - tm1.put(Long.valueOf(5), "VT_R8"); - tm1.put(Long.valueOf(6), "VT_CY"); - tm1.put(Long.valueOf(7), "VT_DATE"); - tm1.put(Long.valueOf(8), "VT_BSTR"); - tm1.put(Long.valueOf(9), "VT_DISPATCH"); - tm1.put(Long.valueOf(10), "VT_ERROR"); - tm1.put(Long.valueOf(11), "VT_BOOL"); - tm1.put(Long.valueOf(12), "VT_VARIANT"); - tm1.put(Long.valueOf(13), "VT_UNKNOWN"); - tm1.put(Long.valueOf(14), "VT_DECIMAL"); - tm1.put(Long.valueOf(16), "VT_I1"); - tm1.put(Long.valueOf(17), "VT_UI1"); - tm1.put(Long.valueOf(18), "VT_UI2"); - tm1.put(Long.valueOf(19), "VT_UI4"); - tm1.put(Long.valueOf(20), "VT_I8"); - tm1.put(Long.valueOf(21), "VT_UI8"); - tm1.put(Long.valueOf(22), "VT_INT"); - tm1.put(Long.valueOf(23), "VT_UINT"); - tm1.put(Long.valueOf(24), "VT_VOID"); - tm1.put(Long.valueOf(25), "VT_HRESULT"); - tm1.put(Long.valueOf(26), "VT_PTR"); - tm1.put(Long.valueOf(27), "VT_SAFEARRAY"); - tm1.put(Long.valueOf(28), "VT_CARRAY"); - tm1.put(Long.valueOf(29), "VT_USERDEFINED"); - tm1.put(Long.valueOf(30), "VT_LPSTR"); - tm1.put(Long.valueOf(31), "VT_LPWSTR"); - tm1.put(Long.valueOf(64), "VT_FILETIME"); - tm1.put(Long.valueOf(65), "VT_BLOB"); - tm1.put(Long.valueOf(66), "VT_STREAM"); - tm1.put(Long.valueOf(67), "VT_STORAGE"); - tm1.put(Long.valueOf(68), "VT_STREAMED_OBJECT"); - tm1.put(Long.valueOf(69), "VT_STORED_OBJECT"); - tm1.put(Long.valueOf(70), "VT_BLOB_OBJECT"); - tm1.put(Long.valueOf(71), "VT_CF"); - tm1.put(Long.valueOf(72), "VT_CLSID"); - Map tm2 = new HashMap(tm1.size(), 1.0F); - tm2.putAll(tm1); - numberToName = Collections.unmodifiableMap(tm2); - - /* Initialize the number-to-length map: */ - Map tm3 = new HashMap(); - tm3.put(Long.valueOf(0), LENGTH_0); - tm3.put(Long.valueOf(1), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(2), LENGTH_2); - tm3.put(Long.valueOf(3), LENGTH_4); - tm3.put(Long.valueOf(4), LENGTH_4); - tm3.put(Long.valueOf(5), LENGTH_8); - tm3.put(Long.valueOf(6), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(7), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(8), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(9), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(10), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(11), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(12), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(13), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(14), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(16), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(17), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(18), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(19), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(20), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(21), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(22), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(23), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(24), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(25), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(26), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(27), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(28), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(29), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(30), LENGTH_VARIABLE); - tm3.put(Long.valueOf(31), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(64), LENGTH_8); - tm3.put(Long.valueOf(65), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(66), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(67), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(68), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(69), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(70), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(71), LENGTH_UNKNOWN); - tm3.put(Long.valueOf(72), LENGTH_UNKNOWN); - Map tm4 = new HashMap(tm1.size(), 1.0F); - tm4.putAll(tm3); - numberToLength = Collections.unmodifiableMap(tm4); - } - - - - /** - *

    Returns the variant type name associated with a variant type - * number.

    - * - * @param variantType The variant type number - * @return The variant type name or the string "unknown variant type" - */ - public static String getVariantName(final long variantType) - { - final String name = numberToName.get(Long.valueOf(variantType)); - return name != null ? name : "unknown variant type"; - } - - /** - *

    Returns a variant type's length.

    - * - * @param variantType The variant type number - * @return The length of the variant type's data in bytes. If the length is - * variable, i.e. the length of a string, -1 is returned. If HPSF does not - * know the length, -2 is returned. The latter usually indicates an - * unsupported variant type. - */ - public static int getVariantLength(final long variantType) - { - final Long key = Long.valueOf((int) variantType); - final Integer length = numberToLength.get(key); - if (length == null) - return -2; - return length.intValue(); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/VariantBool.java b/trunk/src/java/org/apache/poi/hpsf/VariantBool.java deleted file mode 100644 index 962674de7..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/VariantBool.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -@Internal -class VariantBool { - private final static POILogger logger = POILogFactory.getLogger( VariantBool.class ); - - static final int SIZE = 2; - - private boolean _value; - - VariantBool( byte[] data, int offset ) { - short value = LittleEndian.getShort( data, offset ); - switch (value) { - case 0: - _value = false; - break; - case -1: - _value = true; - break; - default: - logger.log( POILogger.WARN, "VARIANT_BOOL value '"+value+"' is incorrect" ); - _value = true; - break; - } - } - - boolean getValue() { - return _value; - } - - void setValue( boolean value ) { - this._value = value; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java b/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java deleted file mode 100644 index b4816eb91..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java +++ /dev/null @@ -1,427 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - *

    Supports reading and writing of variant data.

    - * - *

    FIXME (3): Reading and writing should be made more - * uniform than it is now. The following items should be resolved: - * - *

      - * - *
    • Reading requires a length parameter that is 4 byte greater than the - * actual data, because the variant type field is included.

    • - * - *
    • Reading reads from a byte array while writing writes to an byte array - * output stream.

    • - * - *
    - */ -public class VariantSupport extends Variant -{ - private static final POILogger logger = POILogFactory.getLogger(VariantSupport.class); - private static boolean logUnsupportedTypes = false; - - /** - *

    Specifies whether warnings about unsupported variant types are to be - * written to System.err or not.

    - * - * @param logUnsupportedTypes If true warnings will be written, - * if false they won't. - */ - public static void setLogUnsupportedTypes(final boolean logUnsupportedTypes) - { - VariantSupport.logUnsupportedTypes = logUnsupportedTypes; - } - - /** - *

    Checks whether logging of unsupported variant types warning is turned - * on or off.

    - * - * @return true if logging is turned on, else - * false. - */ - public static boolean isLogUnsupportedTypes() - { - return logUnsupportedTypes; - } - - - - /** - *

    Keeps a list of the variant types an "unsupported" message has already - * been issued for.

    - */ - protected static List unsupportedMessage; - - /** - *

    Writes a warning to System.err that a variant type is - * unsupported by HPSF. Such a warning is written only once for each variant - * type. Log messages can be turned on or off by

    - * - * @param ex The exception to log - */ - protected static void writeUnsupportedTypeMessage - (final UnsupportedVariantTypeException ex) - { - if (isLogUnsupportedTypes()) - { - if (unsupportedMessage == null) - unsupportedMessage = new LinkedList(); - Long vt = Long.valueOf(ex.getVariantType()); - if (!unsupportedMessage.contains(vt)) - { - logger.log( POILogger.ERROR, ex.getMessage()); - unsupportedMessage.add(vt); - } - } - } - - - /** - *

    HPSF is able to read these {@link Variant} types.

    - */ - final static public int[] SUPPORTED_TYPES = { Variant.VT_EMPTY, - Variant.VT_I2, Variant.VT_I4, Variant.VT_I8, Variant.VT_R8, - Variant.VT_FILETIME, Variant.VT_LPSTR, Variant.VT_LPWSTR, - Variant.VT_CF, Variant.VT_BOOL }; - - - - /** - *

    Checks whether HPSF supports the specified variant type. Unsupported - * types should be implemented included in the {@link #SUPPORTED_TYPES} - * array.

    - * - * @see Variant - * @param variantType the variant type to check - * @return true if HPFS supports this type, else - * false - */ - public boolean isSupportedType(final int variantType) - { - for (int i = 0; i < SUPPORTED_TYPES.length; i++) - if (variantType == SUPPORTED_TYPES[i]) - return true; - return false; - } - - - - /** - *

    Reads a variant type from a byte array.

    - * - * @param src The byte array - * @param offset The offset in the byte array where the variant starts - * @param length The length of the variant including the variant type field - * @param type The variant type to read - * @param codepage The codepage to use for non-wide strings - * @return A Java object that corresponds best to the variant field. For - * example, a VT_I4 is returned as a {@link Long}, a VT_LPSTR as a - * {@link String}. - * @exception ReadingNotSupportedException if a property is to be written - * who's variant type HPSF does not yet support - * @exception UnsupportedEncodingException if the specified codepage is not - * supported. - * @see Variant - */ - public static Object read( final byte[] src, final int offset, - final int length, final long type, final int codepage ) - throws ReadingNotSupportedException, UnsupportedEncodingException - { - TypedPropertyValue typedPropertyValue = new TypedPropertyValue( - (int) type, null ); - int unpadded; - try - { - unpadded = typedPropertyValue.readValue( src, offset ); - } - catch ( UnsupportedOperationException exc ) - { - int propLength = Math.min( length, src.length - offset ); - final byte[] v = new byte[propLength]; - System.arraycopy( src, offset, v, 0, propLength ); - throw new ReadingNotSupportedException( type, v ); - } - - switch ( (int) type ) - { - case Variant.VT_EMPTY: - case Variant.VT_I4: - case Variant.VT_I8: - case Variant.VT_R8: - /* - * we have more property types that can be converted into Java - * objects, but current API need to be preserved, and it returns - * other types as byte arrays. In future major versions it shall be - * changed -- sergey - */ - return typedPropertyValue.getValue(); - - case Variant.VT_I2: - { - /* - * also for backward-compatibility with prev. versions of POI - * --sergey - */ - return Integer.valueOf( ( (Short) typedPropertyValue.getValue() ) - .intValue() ); - } - case Variant.VT_FILETIME: - { - Filetime filetime = (Filetime) typedPropertyValue.getValue(); - return Util.filetimeToDate( (int) filetime.getHigh(), - (int) filetime.getLow() ); - } - case Variant.VT_LPSTR: - { - CodePageString string = (CodePageString) typedPropertyValue - .getValue(); - return string.getJavaValue( codepage ); - } - case Variant.VT_LPWSTR: - { - UnicodeString string = (UnicodeString) typedPropertyValue - .getValue(); - return string.toJavaString(); - } - case Variant.VT_CF: - { - // if(l1 < 0) { - /** - * YK: reading the ClipboardData packet (VT_CF) is not quite - * correct. The size of the data is determined by the first four - * bytes of the packet while the current implementation calculates - * it in the Section constructor. Test files in Bugzilla 42726 and - * 45583 clearly show that this approach does not always work. The - * workaround below attempts to gracefully handle such cases instead - * of throwing exceptions. - * - * August 20, 2009 - */ - // l1 = LittleEndian.getInt(src, o1); o1 += LittleEndian.INT_SIZE; - // } - // final byte[] v = new byte[l1]; - // System.arraycopy(src, o1, v, 0, v.length); - // value = v; - // break; - ClipboardData clipboardData = (ClipboardData) typedPropertyValue - .getValue(); - return clipboardData.toByteArray(); - } - - case Variant.VT_BOOL: - { - VariantBool bool = (VariantBool) typedPropertyValue.getValue(); - return Boolean.valueOf( bool.getValue() ); - } - - default: - { - /* - * it is not very good, but what can do without breaking current - * API? --sergey - */ - final byte[] v = new byte[unpadded]; - System.arraycopy( src, offset, v, 0, unpadded ); - throw new ReadingNotSupportedException( type, v ); - } - } - } - - /** - *

    Turns a codepage number into the equivalent character encoding's - * name.

    - * - * @param codepage The codepage number - * - * @return The character encoding's name. If the codepage number is 65001, - * the encoding name is "UTF-8". All other positive numbers are mapped to - * "cp" followed by the number, e.g. if the codepage number is 1252 the - * returned character encoding name will be "cp1252". - * - * @exception UnsupportedEncodingException if the specified codepage is - * less than zero. - */ - public static String codepageToEncoding(final int codepage) - throws UnsupportedEncodingException - { - return CodePageUtil.codepageToEncoding(codepage); - } - - - /** - *

    Writes a variant value to an output stream. This method ensures that - * always a multiple of 4 bytes is written.

    - * - *

    If the codepage is UTF-16, which is encouraged, strings - * must always be written as {@link Variant#VT_LPWSTR} - * strings, not as {@link Variant#VT_LPSTR} strings. This method ensure this - * by converting strings appropriately, if needed.

    - * - * @param out The stream to write the value to. - * @param type The variant's type. - * @param value The variant's value. - * @param codepage The codepage to use to write non-wide strings - * @return The number of entities that have been written. In many cases an - * "entity" is a byte but this is not always the case. - * @exception IOException if an I/O exceptions occurs - * @exception WritingNotSupportedException if a property is to be written - * who's variant type HPSF does not yet support - */ - public static int write(final OutputStream out, final long type, - final Object value, final int codepage) - throws IOException, WritingNotSupportedException - { - int length = 0; - switch ((int) type) - { - case Variant.VT_BOOL: - { - if ( ( (Boolean) value ).booleanValue() ) - { - out.write( 0xff ); - out.write( 0xff ); - } - else - { - out.write( 0x00 ); - out.write( 0x00 ); - } - length += 2; - break; - } - case Variant.VT_LPSTR: - { - CodePageString codePageString = new CodePageString( (String) value, - codepage ); - length += codePageString.write( out ); - break; - } - case Variant.VT_LPWSTR: - { - final int nrOfChars = ( (String) value ).length() + 1; - length += TypeWriter.writeUIntToStream( out, nrOfChars ); - char[] s = ( (String) value ).toCharArray(); - for ( int i = 0; i < s.length; i++ ) - { - final int high = ( ( s[i] & 0x0000ff00 ) >> 8 ); - final int low = ( s[i] & 0x000000ff ); - final byte highb = (byte) high; - final byte lowb = (byte) low; - out.write( lowb ); - out.write( highb ); - length += 2; - } - // NullTerminator - out.write( 0x00 ); - out.write( 0x00 ); - length += 2; - break; - } - case Variant.VT_CF: - { - final byte[] b = (byte[]) value; - out.write(b); - length = b.length; - break; - } - case Variant.VT_EMPTY: - { - length += TypeWriter.writeUIntToStream( out, Variant.VT_EMPTY ); - break; - } - case Variant.VT_I2: - { - length += TypeWriter.writeToStream( out, - ( (Integer) value ).shortValue() ); - break; - } - case Variant.VT_I4: - { - if (!(value instanceof Integer)) - { - throw new ClassCastException("Could not cast an object to " - + Integer.class.toString() + ": " - + value.getClass().toString() + ", " - + value.toString()); - } - length += TypeWriter.writeToStream(out, - ((Integer) value).intValue()); - break; - } - case Variant.VT_I8: - { - length += TypeWriter.writeToStream(out, ((Long) value).longValue()); - break; - } - case Variant.VT_R8: - { - length += TypeWriter.writeToStream(out, - ((Double) value).doubleValue()); - break; - } - case Variant.VT_FILETIME: - { - long filetime = Util.dateToFileTime((Date) value); - int high = (int) ((filetime >> 32) & 0x00000000FFFFFFFFL); - int low = (int) (filetime & 0x00000000FFFFFFFFL); - Filetime filetimeValue = new Filetime( low, high); - length += filetimeValue.write( out ); - break; - } - default: - { - /* The variant type is not supported yet. However, if the value - * is a byte array we can write it nevertheless. */ - if (value instanceof byte[]) - { - final byte[] b = (byte[]) value; - out.write(b); - length = b.length; - writeUnsupportedTypeMessage - (new WritingNotSupportedException(type, value)); - } - else - throw new WritingNotSupportedException(type, value); - break; - } - } - - /* pad values to 4-bytes */ - while ( ( length & 0x3 ) != 0 ) - { - out.write( 0x00 ); - length++; - } - - return length; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/VariantTypeException.java b/trunk/src/java/org/apache/poi/hpsf/VariantTypeException.java deleted file mode 100644 index c2d2e8f66..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/VariantTypeException.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown if HPSF encounters a problem with a variant type. - * Concrete subclasses specifiy the problem further.

    - */ -public abstract class VariantTypeException extends HPSFException -{ - - private Object value; - - private long variantType; - - - - /** - *

    Constructor.

    - * - * @param variantType The variant type causing the problem - * @param value The value who's variant type causes the problem - * @param msg A message text describing the problem - */ - public VariantTypeException(final long variantType, final Object value, - final String msg) - { - super(msg); - this.variantType = variantType; - this.value = value; - } - - - - /** - *

    Returns the offending variant type.

    - * - * @return the offending variant type. - */ - public long getVariantType() - { - return variantType; - } - - - - /** - *

    Returns the value who's variant type caused the problem.

    - * - * @return the value who's variant type caused the problem - */ - public Object getValue() - { - return value; - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/Vector.java b/trunk/src/java/org/apache/poi/hpsf/Vector.java deleted file mode 100644 index a1ddb0812..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/Vector.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; - -/** - * Holder for vector-type properties - * - * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) - */ -@Internal -class Vector -{ - private final short _type; - - private TypedPropertyValue[] _values; - - Vector( byte[] data, int startOffset, short type ) - { - this._type = type; - read( data, startOffset ); - } - - Vector( short type ) - { - this._type = type; - } - - int read( byte[] data, int startOffset ) - { - int offset = startOffset; - - final long longLength = LittleEndian.getUInt( data, offset ); - offset += LittleEndian.INT_SIZE; - - if ( longLength > Integer.MAX_VALUE ) - throw new UnsupportedOperationException( "Vector is too long -- " - + longLength ); - final int length = (int) longLength; - - _values = new TypedPropertyValue[length]; - - if ( _type == Variant.VT_VARIANT ) - { - for ( int i = 0; i < length; i++ ) - { - TypedPropertyValue value = new TypedPropertyValue(); - offset += value.read( data, offset ); - _values[i] = value; - } - } - else - { - for ( int i = 0; i < length; i++ ) - { - TypedPropertyValue value = new TypedPropertyValue( _type, null ); - // be aware: not padded here - offset += value.readValue( data, offset ); - _values[i] = value; - } - } - return offset - startOffset; - } - - TypedPropertyValue[] getValues(){ - return _values; - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/VersionedStream.java b/trunk/src/java/org/apache/poi/hpsf/VersionedStream.java deleted file mode 100644 index c3c066e4f..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/VersionedStream.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.hpsf; - -import org.apache.poi.util.Internal; - -@Internal -class VersionedStream -{ - private GUID _versionGuid; - private IndirectPropertyName _streamName; - - VersionedStream( byte[] data, int offset ) - { - _versionGuid = new GUID( data, offset ); - _streamName = new IndirectPropertyName( data, offset + GUID.SIZE ); - } - - int getSize() - { - return GUID.SIZE + _streamName.getSize(); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/WritingNotSupportedException.java b/trunk/src/java/org/apache/poi/hpsf/WritingNotSupportedException.java deleted file mode 100644 index d409999f7..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/WritingNotSupportedException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf; - -/** - *

    This exception is thrown when trying to write a (yet) unsupported variant - * type.

    - * - * @see ReadingNotSupportedException - * @see UnsupportedVariantTypeException - */ -public class WritingNotSupportedException - extends UnsupportedVariantTypeException -{ - - /** - *

    Constructor

    - * - * @param variantType The unsupported variant type. - * @param value The value. - */ - public WritingNotSupportedException(final long variantType, - final Object value) - { - super(variantType, value); - } - -} diff --git a/trunk/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java b/trunk/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java deleted file mode 100644 index fc526ee61..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.extractor; - -import java.io.File; -import java.io.IOException; - -import org.apache.poi.POIDocument; -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.POITextExtractor; -import org.apache.poi.hpsf.CustomProperties; -import org.apache.poi.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.HPSFPropertiesOnlyDocument; -import org.apache.poi.hpsf.Property; -import org.apache.poi.hpsf.SpecialPropertySet; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.wellknown.PropertyIDMap; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * Extracts all of the HPSF properties, both - * build in and custom, returning them in - * textual form. - */ -public class HPSFPropertiesExtractor extends POIOLE2TextExtractor { - public HPSFPropertiesExtractor(POIOLE2TextExtractor mainExtractor) { - super(mainExtractor); - } - public HPSFPropertiesExtractor(POIDocument doc) { - super(doc); - } - public HPSFPropertiesExtractor(POIFSFileSystem fs) { - super(new HPSFPropertiesOnlyDocument(fs)); - } - public HPSFPropertiesExtractor(NPOIFSFileSystem fs) { - super(new HPSFPropertiesOnlyDocument(fs)); - } - - public String getDocumentSummaryInformationText() { - if(document == null) { // event based extractor does not have a document - return ""; - } - - DocumentSummaryInformation dsi = document.getDocumentSummaryInformation(); - StringBuilder text = new StringBuilder(); - - // Normal properties - text.append( getPropertiesText(dsi) ); - - // Now custom ones - CustomProperties cps = dsi == null ? null : dsi.getCustomProperties(); - if (cps != null) { - for (String key : cps.nameSet()) { - String val = HelperPropertySet.getPropertyValueText(cps.get(key)); - text.append(key).append(" = ").append(val).append("\n"); - } - } - - // All done - return text.toString(); - } - public String getSummaryInformationText() { - if(document == null) { // event based extractor does not have a document - return ""; - } - - SummaryInformation si = document.getSummaryInformation(); - - // Just normal properties - return getPropertiesText(si); - } - - private static String getPropertiesText(SpecialPropertySet ps) { - if (ps == null) { - // Not defined, oh well - return ""; - } - - StringBuilder text = new StringBuilder(); - - PropertyIDMap idMap = ps.getPropertySetIDMap(); - Property[] props = ps.getProperties(); - for (Property prop : props) { - String type = Long.toString(prop.getID()); - Object typeObj = idMap.get(prop.getID()); - if (typeObj != null) { - type = typeObj.toString(); - } - - String val = HelperPropertySet.getPropertyValueText(prop.getValue()); - text.append(type).append(" = ").append(val).append("\n"); - } - - return text.toString(); - } - - /** - * @return the text of all the properties defined in - * the document. - */ - public String getText() { - return getSummaryInformationText() + getDocumentSummaryInformationText(); - } - - /** - * Prevent recursion! - */ - public POITextExtractor getMetadataTextExtractor() { - throw new IllegalStateException("You already have the Metadata Text Extractor, not recursing!"); - } - - private static abstract class HelperPropertySet extends SpecialPropertySet { - public HelperPropertySet() { - super(null); - } - public static String getPropertyValueText(Object val) { - if (val == null) { - return "(not set)"; - } - return SpecialPropertySet.getPropertyStringValue(val); - } - } - - @Override - public boolean equals(Object o) { - return super.equals(o); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - public static void main(String[] args) throws IOException { - for (String file : args) { - HPSFPropertiesExtractor ext = new HPSFPropertiesExtractor( - new NPOIFSFileSystem(new File(file))); - try { - System.out.println(ext.getText()); - } finally { - ext.close(); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/package.html b/trunk/src/java/org/apache/poi/hpsf/package.html deleted file mode 100644 index f5cfe430c..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/package.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - HPSF - - - -
    -

    Processes streams in the Horrible Property Set Format (HPSF) in POI - filesystems. Microsoft Office documents, i.e. POI filesystems, usually - contain meta data like author, title, last saving time etc. These items - are called properties and stored in - property set streams along with the document itself. These - streams are commonly named \005SummaryInformation and - \005DocumentSummaryInformation. However, a POI filesystem may - contain further property sets of other names or types.

    - -

    In order to extract the properties from a POI filesystem, a property set - stream's contents must be parsed into a {@link - org.apache.poi.hpsf.PropertySet} instance. Its subclasses {@link - org.apache.poi.hpsf.SummaryInformation} and {@link - org.apache.poi.hpsf.DocumentSummaryInformation} deal with the well-known - property set streams \005SummaryInformation and - \005DocumentSummaryInformation. (However, the streams' names are - irrelevant. What counts is the property set's first section's format ID - - see below.)

    - -

    The factory method {@link org.apache.poi.hpsf.PropertySetFactory#create} - creates a {@link org.apache.poi.hpsf.PropertySet} instance. This method - always returns the most specific property set: If it - identifies the stream data as a Summary Information or as a Document - Summary Information it returns an instance of the corresponding class, else - the general {@link org.apache.poi.hpsf.PropertySet}.

    - -

    A {@link org.apache.poi.hpsf.PropertySet} contains a list of {@link - org.apache.poi.hpsf.Section}s which can be retrieved with {@link - org.apache.poi.hpsf.PropertySet#getSections}. Each {@link - org.apache.poi.hpsf.Section} contains a {@link - org.apache.poi.hpsf.Property} array which can be retrieved with {@link - org.apache.poi.hpsf.Section#getProperties}. Since the vast majority of - {@link org.apache.poi.hpsf.PropertySet}s contains only a single {@link - org.apache.poi.hpsf.Section}, the convenience method {@link - org.apache.poi.hpsf.PropertySet#getProperties} returns the properties of a - {@link org.apache.poi.hpsf.PropertySet}'s {@link - org.apache.poi.hpsf.Section} (throwing a {@link - org.apache.poi.hpsf.NoSingleSectionException} if the {@link - org.apache.poi.hpsf.PropertySet} contains more (or less) than exactly one - {@link org.apache.poi.hpsf.Section}).

    - -

    Each {@link org.apache.poi.hpsf.Property} has an ID, a - type, and a value which can be retrieved - with {@link org.apache.poi.hpsf.Property#getID}, {@link - org.apache.poi.hpsf.Property#getType}, and {@link - org.apache.poi.hpsf.Property#getValue}, respectively. The value's class - depends on the property's type. The current implementation - does not yet support all property types and restricts the values' classes - to {@link java.lang.String}, {@link java.lang.Integer} and {@link - java.util.Date}. A value of a yet unknown type is returned as a byte array - containing the value's origin bytes from the property set stream.

    - -

    To retrieve the value of a specific {@link org.apache.poi.hpsf.Property}, - use {@link org.apache.poi.hpsf.Section#getProperty} or {@link - org.apache.poi.hpsf.Section#getPropertyIntValue}.

    - -

    The {@link org.apache.poi.hpsf.SummaryInformation} and {@link - org.apache.poi.hpsf.DocumentSummaryInformation} classes provide convenience - methods for retrieving well-known properties. For example, an application - that wants to retrieve a document's title string just calls {@link - org.apache.poi.hpsf.SummaryInformation#getTitle} instead of going through - the hassle of first finding out what the title's property ID is and then - using this ID to get the property's value.

    - -

    Writing properties can be done with the classes - {@link org.apache.poi.hpsf.MutablePropertySet}, {@link - org.apache.poi.hpsf.MutableSection}, and {@link - org.apache.poi.hpsf.MutableProperty}.

    - -

    Public documentation from Microsoft can be found in the appropriate section of the MSDN Library.

    - -
    -

    History

    - -
    -
    2003-09-11:
    - -
    -

    {@link org.apache.poi.hpsf.PropertySetFactory#create(InputStream)} no - longer throws an - {@link org.apache.poi.hpsf.UnexpectedPropertySetTypeException}.

    -
    -
    - - -
    -

    To Do

    - -

    The following is still left to be implemented. Sponsering could foster - these issues considerably.

    - -
      - -
    • -

      Convenience methods for setting summary information and document - summary information properties

      -
    • - -
    • -

      Better codepage support

      -
    • - -
    • -

      Support for more property (variant) types

      -
    • - -
    - -
    - -

    - @author Rainer Klute (klute@rainer-klute.de) -

    -
    - - - - - diff --git a/trunk/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java b/trunk/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java deleted file mode 100644 index 20e6d9f70..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java +++ /dev/null @@ -1,449 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.wellknown; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - *

    This is a dictionary which maps property ID values to property - * ID strings.

    - * - *

    The methods {@link #getSummaryInformationProperties} and {@link - * #getDocumentSummaryInformationProperties} return singleton {@link - * PropertyIDMap}s. An application that wants to extend these maps - * should treat them as unmodifiable, copy them and modifiy the - * copies.

    - */ -public class PropertyIDMap extends HashMap { - - /* - * The following definitions are for property IDs in the first - * (and only) section of the Summary Information property set. - */ - - /**

    ID of the property that denotes the document's title

    */ - public static final int PID_TITLE = 2; - - /**

    ID of the property that denotes the document's subject

    */ - public static final int PID_SUBJECT = 3; - - /**

    ID of the property that denotes the document's author

    */ - public static final int PID_AUTHOR = 4; - - /**

    ID of the property that denotes the document's keywords

    */ - public static final int PID_KEYWORDS = 5; - - /**

    ID of the property that denotes the document's comments

    */ - public static final int PID_COMMENTS = 6; - - /**

    ID of the property that denotes the document's template

    */ - public static final int PID_TEMPLATE = 7; - - /**

    ID of the property that denotes the document's last author

    */ - public static final int PID_LASTAUTHOR = 8; - - /**

    ID of the property that denotes the document's revision number

    */ - public static final int PID_REVNUMBER = 9; - - /**

    ID of the property that denotes the document's edit time

    */ - public static final int PID_EDITTIME = 10; - - /**

    ID of the property that denotes the date and time the document was - * last printed

    */ - public static final int PID_LASTPRINTED = 11; - - /**

    ID of the property that denotes the date and time the document was - * created.

    */ - public static final int PID_CREATE_DTM = 12; - - /**

    ID of the property that denotes the date and time the document was - * saved

    */ - public static final int PID_LASTSAVE_DTM = 13; - - /**

    ID of the property that denotes the number of pages in the - * document

    */ - public static final int PID_PAGECOUNT = 14; - - /**

    ID of the property that denotes the number of words in the - * document

    */ - public static final int PID_WORDCOUNT = 15; - - /**

    ID of the property that denotes the number of characters in the - * document

    */ - public static final int PID_CHARCOUNT = 16; - - /**

    ID of the property that denotes the document's thumbnail

    */ - public static final int PID_THUMBNAIL = 17; - - /**

    ID of the property that denotes the application that created the - * document

    */ - public static final int PID_APPNAME = 18; - - /**

    ID of the property that denotes whether read/write access to the - * document is allowed or whether is should be opened as read-only. It can - * have the following values:

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

    Value

    Description

    0

    No restriction

    2

    Read-only recommended

    4

    Read-only enforced

    - */ - public static final int PID_SECURITY = 19; - - - - /* - * The following definitions are for property IDs in the first - * section of the Document Summary Information property set. - */ - - /** - *

    The entry is a dictionary.

    - */ - public static final int PID_DICTIONARY = 0; - - /** - *

    The entry denotes a code page.

    - */ - public static final int PID_CODEPAGE = 1; - - /** - *

    The entry is a string denoting the category the file belongs - * to, e.g. review, memo, etc. This is useful to find documents of - * same type.

    - */ - public static final int PID_CATEGORY = 2; - - /** - *

    Target format for power point presentation, e.g. 35mm, - * printer, video etc.

    - */ - public static final int PID_PRESFORMAT = 3; - - /** - *

    Number of bytes.

    - */ - public static final int PID_BYTECOUNT = 4; - - /** - *

    Number of lines.

    - */ - public static final int PID_LINECOUNT = 5; - - /** - *

    Number of paragraphs.

    - */ - public static final int PID_PARCOUNT = 6; - - /** - *

    Number of slides in a power point presentation.

    - */ - public static final int PID_SLIDECOUNT = 7; - - /** - *

    Number of slides with notes.

    - */ - public static final int PID_NOTECOUNT = 8; - - /** - *

    Number of hidden slides.

    - */ - public static final int PID_HIDDENCOUNT = 9; - - /** - *

    Number of multimedia clips, e.g. sound or video.

    - */ - public static final int PID_MMCLIPCOUNT = 10; - - /** - *

    This entry is set to -1 when scaling of the thumbnail is - * desired. Otherwise the thumbnail should be cropped.

    - */ - public static final int PID_SCALE = 11; - - /** - *

    This entry denotes an internally used property. It is a - * vector of variants consisting of pairs of a string (VT_LPSTR) - * and a number (VT_I4). The string is a heading name, and the - * number tells how many document parts are under that - * heading.

    - */ - public static final int PID_HEADINGPAIR = 12; - - /** - *

    This entry contains the names of document parts (word: names - * of the documents in the master document, excel: sheet names, - * power point: slide titles, binder: document names).

    - */ - public static final int PID_DOCPARTS = 13; - - /** - *

    This entry contains the name of the project manager.

    - */ - public static final int PID_MANAGER = 14; - - /** - *

    This entry contains the company name.

    - */ - public static final int PID_COMPANY = 15; - - /** - *

    If this entry is -1 the links are dirty and should be - * re-evaluated.

    - */ - public static final int PID_LINKSDIRTY = 0x10; - - /** - *

    The entry specifies an estimate of the number of characters - * in the document, including whitespace, as an integer - */ - public static final int PID_CCHWITHSPACES = 0x11; - - // 0x12 Unused - // 0x13 GKPIDDSI_SHAREDDOC - Must be False - // 0x14 GKPIDDSI_LINKBASE - Must not be written - // 0x15 GKPIDDSI_HLINKS - Must not be written - - /** - *

    This entry contains a boolean which marks if the User Defined - * Property Set has been updated outside of the Application, if so the - * hyperlinks should be updated on document load. - */ - public static final int PID_HYPERLINKSCHANGED = 0x16; - - /** - *

    This entry contains the version of the Application which wrote the - * Property set, stored with the two high order bytes having the major - * version number, and the two low order bytes the minor version number. - */ - public static final int PID_VERSION = 0x17; - - /** - *

    This entry contains the VBA digital signature for the VBA project - * embedded in the document. - */ - public static final int PID_DIGSIG = 0x18; - - // 0x19 Unused - - /** - *

    This entry contains a string of the content type of the file. - */ - public static final int PID_CONTENTTYPE = 0x1A; - - /** - *

    This entry contains a string of the document status. - */ - public static final int PID_CONTENTSTATUS = 0x1B; - - /** - *

    This entry contains a string of the document language, but - * normally should be empty. - */ - public static final int PID_LANGUAGE = 0x1C; - - /** - *

    This entry contains a string of the document version, but - * normally should be empty - */ - public static final int PID_DOCVERSION = 0x1D; - - /** - *

    The highest well-known property ID. Applications are free to use - * higher values for custom purposes. (This value is based on Office 12, - * earlier versions of Office had lower values)

    - */ - public static final int PID_MAX = 0x1F; - - - - /** - *

    Contains the summary information property ID values and - * associated strings. See the overall HPSF documentation for - * details!

    - */ - private static PropertyIDMap summaryInformationProperties; - - /** - *

    Contains the summary information property ID values and - * associated strings. See the overall HPSF documentation for - * details!

    - */ - private static PropertyIDMap documentSummaryInformationProperties; - - - - /** - *

    Creates a {@link PropertyIDMap}.

    - * - * @param initialCapacity The initial capacity as defined for - * {@link HashMap} - * @param loadFactor The load factor as defined for {@link HashMap} - */ - public PropertyIDMap(final int initialCapacity, final float loadFactor) - { - super(initialCapacity, loadFactor); - } - - - - /** - *

    Creates a {@link PropertyIDMap} backed by another map.

    - * - * @param map The instance to be created is backed by this map. - */ - public PropertyIDMap(final Map map) - { - super(map); - } - - - - /** - *

    Puts a ID string for an ID into the {@link - * PropertyIDMap}.

    - * - * @param id The ID. - * @param idString The ID string. - * @return As specified by the {@link java.util.Map} interface, this method - * returns the previous value associated with the specified - * id, or null if there was no mapping for - * key. - */ - public Object put(final long id, final String idString) - { - return put(Long.valueOf(id), idString); - } - - - - /** - *

    Gets the ID string for an ID from the {@link - * PropertyIDMap}.

    - * - * @param id The ID. - * @return The ID string associated with id. - */ - public Object get(final long id) - { - return get(Long.valueOf(id)); - } - - - - /** - * @return the Summary Information properties singleton - */ - public static PropertyIDMap getSummaryInformationProperties() - { - if (summaryInformationProperties == null) - { - PropertyIDMap m = new PropertyIDMap(18, (float) 1.0); - m.put(PID_TITLE, "PID_TITLE"); - m.put(PID_SUBJECT, "PID_SUBJECT"); - m.put(PID_AUTHOR, "PID_AUTHOR"); - m.put(PID_KEYWORDS, "PID_KEYWORDS"); - m.put(PID_COMMENTS, "PID_COMMENTS"); - m.put(PID_TEMPLATE, "PID_TEMPLATE"); - m.put(PID_LASTAUTHOR, "PID_LASTAUTHOR"); - m.put(PID_REVNUMBER, "PID_REVNUMBER"); - m.put(PID_EDITTIME, "PID_EDITTIME"); - m.put(PID_LASTPRINTED, "PID_LASTPRINTED"); - m.put(PID_CREATE_DTM, "PID_CREATE_DTM"); - m.put(PID_LASTSAVE_DTM, "PID_LASTSAVE_DTM"); - m.put(PID_PAGECOUNT, "PID_PAGECOUNT"); - m.put(PID_WORDCOUNT, "PID_WORDCOUNT"); - m.put(PID_CHARCOUNT, "PID_CHARCOUNT"); - m.put(PID_THUMBNAIL, "PID_THUMBNAIL"); - m.put(PID_APPNAME, "PID_APPNAME"); - m.put(PID_SECURITY, "PID_SECURITY"); - summaryInformationProperties = - new PropertyIDMap(Collections.unmodifiableMap(m)); - } - return summaryInformationProperties; - } - - - - /** - *

    Returns the Document Summary Information properties - * singleton.

    - * - * @return The Document Summary Information properties singleton. - */ - public static PropertyIDMap getDocumentSummaryInformationProperties() - { - if (documentSummaryInformationProperties == null) - { - PropertyIDMap m = new PropertyIDMap(17, (float) 1.0); - m.put(PID_DICTIONARY, "PID_DICTIONARY"); - m.put(PID_CODEPAGE, "PID_CODEPAGE"); - m.put(PID_CATEGORY, "PID_CATEGORY"); - m.put(PID_PRESFORMAT, "PID_PRESFORMAT"); - m.put(PID_BYTECOUNT, "PID_BYTECOUNT"); - m.put(PID_LINECOUNT, "PID_LINECOUNT"); - m.put(PID_PARCOUNT, "PID_PARCOUNT"); - m.put(PID_SLIDECOUNT, "PID_SLIDECOUNT"); - m.put(PID_NOTECOUNT, "PID_NOTECOUNT"); - m.put(PID_HIDDENCOUNT, "PID_HIDDENCOUNT"); - m.put(PID_MMCLIPCOUNT, "PID_MMCLIPCOUNT"); - m.put(PID_SCALE, "PID_SCALE"); - m.put(PID_HEADINGPAIR, "PID_HEADINGPAIR"); - m.put(PID_DOCPARTS, "PID_DOCPARTS"); - m.put(PID_MANAGER, "PID_MANAGER"); - m.put(PID_COMPANY, "PID_COMPANY"); - m.put(PID_LINKSDIRTY, "PID_LINKSDIRTY"); - documentSummaryInformationProperties = - new PropertyIDMap(Collections.unmodifiableMap(m)); - } - return documentSummaryInformationProperties; - } - - - - /** - *

    For the most basic testing.

    - * - * @param args The command-line arguments - */ - public static void main(final String[] args) - { - PropertyIDMap s1 = getSummaryInformationProperties(); - PropertyIDMap s2 = getDocumentSummaryInformationProperties(); - System.out.println("s1: " + s1); - System.out.println("s2: " + s2); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/wellknown/SectionIDMap.java b/trunk/src/java/org/apache/poi/hpsf/wellknown/SectionIDMap.java deleted file mode 100644 index 1f5760df2..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/wellknown/SectionIDMap.java +++ /dev/null @@ -1,173 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpsf.wellknown; - -import java.util.HashMap; - -import org.apache.poi.util.StringUtil; - -/** - *

    Maps section format IDs to {@link PropertyIDMap}s. It is - * initialized with two well-known section format IDs: those of the - * \005SummaryInformation stream and the - * \005DocumentSummaryInformation stream.

    - * - *

    If you have a section format ID you can use it as a key to query - * this map. If you get a {@link PropertyIDMap} returned your section - * is well-known and you can query the {@link PropertyIDMap} for PID - * strings. If you get back null you are on your own.

    - * - *

    This {@link java.util.Map} expects the byte arrays of section format IDs - * as keys. A key maps to a {@link PropertyIDMap} describing the - * property IDs in sections with the specified section format ID.

    - */ -@SuppressWarnings({"rawtypes","unchecked"}) // Java Generics have issues on this style of class... -public class SectionIDMap extends HashMap { - /** - *

    The SummaryInformation's section's format ID.

    - */ - public static final byte[] SUMMARY_INFORMATION_ID = new byte[] - { - (byte) 0xF2, (byte) 0x9F, (byte) 0x85, (byte) 0xE0, - (byte) 0x4F, (byte) 0xF9, (byte) 0x10, (byte) 0x68, - (byte) 0xAB, (byte) 0x91, (byte) 0x08, (byte) 0x00, - (byte) 0x2B, (byte) 0x27, (byte) 0xB3, (byte) 0xD9 - }; - - /** - *

    The DocumentSummaryInformation's first and second sections' format - * ID.

    - */ - public static final byte[][] DOCUMENT_SUMMARY_INFORMATION_ID = new byte[][] - { - { - (byte) 0xD5, (byte) 0xCD, (byte) 0xD5, (byte) 0x02, - (byte) 0x2E, (byte) 0x9C, (byte) 0x10, (byte) 0x1B, - (byte) 0x93, (byte) 0x97, (byte) 0x08, (byte) 0x00, - (byte) 0x2B, (byte) 0x2C, (byte) 0xF9, (byte) 0xAE - }, - { - (byte) 0xD5, (byte) 0xCD, (byte) 0xD5, (byte) 0x05, - (byte) 0x2E, (byte) 0x9C, (byte) 0x10, (byte) 0x1B, - (byte) 0x93, (byte) 0x97, (byte) 0x08, (byte) 0x00, - (byte) 0x2B, (byte) 0x2C, (byte) 0xF9, (byte) 0xAE - } - }; - - /** - *

    A property without a known name is described by this string.

    - */ - public static final String UNDEFINED = "[undefined]"; - - /** - *

    The default section ID map. It maps section format IDs to - * {@link PropertyIDMap}s.

    - */ - private static SectionIDMap defaultMap; - - - - /** - *

    Returns the singleton instance of the default {@link - * SectionIDMap}.

    - * - * @return The instance value - */ - public static SectionIDMap getInstance() - { - if (defaultMap == null) - { - final SectionIDMap m = new SectionIDMap(); - m.put(SUMMARY_INFORMATION_ID, - PropertyIDMap.getSummaryInformationProperties()); - m.put(DOCUMENT_SUMMARY_INFORMATION_ID[0], - PropertyIDMap.getDocumentSummaryInformationProperties()); - defaultMap = m; - } - return defaultMap; - } - - - - /** - *

    Returns the property ID string that is associated with a - * given property ID in a section format ID's namespace.

    - * - * @param sectionFormatID Each section format ID has its own name - * space of property ID strings and thus must be specified. - * @param pid The property ID - * @return The well-known property ID string associated with the - * property ID pid in the name space spanned by - * sectionFormatID . If the pid - * /sectionFormatID combination is not well-known, the - * string "[undefined]" is returned. - */ - public static String getPIDString(final byte[] sectionFormatID, - final long pid) - { - final PropertyIDMap m = getInstance().get(sectionFormatID); - if (m == null) { - return UNDEFINED; - } - final String s = (String) m.get(pid); - if (s == null) - return UNDEFINED; - return s; - } - - - - /** - *

    Returns the {@link PropertyIDMap} for a given section format - * ID.

    - * - * @param sectionFormatID the section format ID - * @return the property ID map - */ - public PropertyIDMap get(final byte[] sectionFormatID) - { - return (PropertyIDMap)super.get(new String(sectionFormatID, StringUtil.UTF8)); - } - - /** - *

    Associates a section format ID with a {@link - * PropertyIDMap}.

    - * - * @param sectionFormatID the section format ID - * @param propertyIDMap the property ID map - * @return as defined by {@link java.util.Map#put} - */ - public PropertyIDMap put(final byte[] sectionFormatID, - final PropertyIDMap propertyIDMap) - { - return (PropertyIDMap)super.put(new String(sectionFormatID, StringUtil.UTF8), propertyIDMap); - } - - /** - * Associates the string representation of a section - * format ID with a {@link PropertyIDMap} - * - * @param key the key of the PropertyIDMap - * @param value the PropertyIDMap itself - * - * @return the previous PropertyIDMap stored under this key, or {@code null} if there wasn't one - */ - protected PropertyIDMap put(String key, PropertyIDMap value) { - return (PropertyIDMap)super.put(key, value); - } -} diff --git a/trunk/src/java/org/apache/poi/hpsf/wellknown/package.html b/trunk/src/java/org/apache/poi/hpsf/wellknown/package.html deleted file mode 100644 index 05b4ffb14..000000000 --- a/trunk/src/java/org/apache/poi/hpsf/wellknown/package.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - -
    - Specific support for DocumentSummaryInformation, SummaryInformation types. -

    Support classes for "well-known" section format IDs and property IDs. The - streams \005DocumentSummaryInformation and - \005SummaryInformation (or any streams with the same section - format IDs as the aforementioned) are considered well-known. So are most - property IDs in these streams.

    - -

    - @author Rainer Klute (klute@rainer-klute.de) -

    -
    - - - - - diff --git a/trunk/src/java/org/apache/poi/hssf/OldExcelFormatException.java b/trunk/src/java/org/apache/poi/hssf/OldExcelFormatException.java deleted file mode 100644 index beb8c02c7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/OldExcelFormatException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf; - -import org.apache.poi.OldFileFormatException; -import org.apache.poi.util.Removal; - -/** - * @deprecated POI 3.16 beta 1. Use {@link org.apache.poi.OldFileFormatException} - */ -@Removal(version="3.18") -public class OldExcelFormatException extends OldFileFormatException { - public OldExcelFormatException(String s) { - super(s); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java b/trunk/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java deleted file mode 100644 index 256d0230f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.hssf.dev; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.hssf.model.InternalWorkbook; -import org.apache.poi.hssf.record.DrawingGroupRecord; -import org.apache.poi.hssf.usermodel.HSSFPatriarch; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.util.StringUtil; - -/** - * Utility for representing drawings contained in a binary Excel file as a XML tree - */ -public class BiffDrawingToXml { - private static final String SHEET_NAME_PARAM = "-sheet-name"; - private static final String SHEET_INDEXES_PARAM = "-sheet-indexes"; - private static final String EXCLUDE_WORKBOOK_RECORDS = "-exclude-workbook"; - - private static int getAttributeIndex(String attribute, String[] params) { - for (int i = 0; i < params.length; i++) { - String param = params[i]; - if (attribute.equals(param)) { - return i; - } - } - return -1; - } - - private static boolean isExcludeWorkbookRecords(String[] params) { - return -1 != getAttributeIndex(EXCLUDE_WORKBOOK_RECORDS, params); - } - - private static List getIndexesByName(String[] params, HSSFWorkbook workbook) { - List list = new ArrayList(); - int pos = getAttributeIndex(SHEET_NAME_PARAM, params); - if (-1 != pos) { - if (pos >= params.length) { - throw new IllegalArgumentException("sheet name param value was not specified"); - } - String sheetName = params[pos + 1]; - int sheetPos = workbook.getSheetIndex(sheetName); - if (-1 == sheetPos){ - throw new IllegalArgumentException("specified sheet name has not been found in xls file"); - } - list.add(sheetPos); - } - return list; - } - - private static List getIndexesByIdArray(String[] params) { - List list = new ArrayList(); - int pos = getAttributeIndex(SHEET_INDEXES_PARAM, params); - if (-1 != pos) { - if (pos >= params.length) { - throw new IllegalArgumentException("sheet list value was not specified"); - } - String sheetParam = params[pos + 1]; - String[] sheets = sheetParam.split(","); - for (String sheet : sheets) { - list.add(Integer.parseInt(sheet)); - } - } - return list; - } - - private static List getSheetsIndexes(String[] params, HSSFWorkbook workbook) { - List list = new ArrayList(); - list.addAll(getIndexesByIdArray(params)); - list.addAll(getIndexesByName(params, workbook)); - if (0 == list.size()) { - int size = workbook.getNumberOfSheets(); - for (int i = 0; i < size; i++) { - list.add(i); - } - } - return list; - } - - private static String getInputFileName(String[] params) { - return params[params.length - 1]; - } - - private static String getOutputFileName(String input) { - if (input.contains("xls")) { - return input.replace(".xls", ".xml"); - } - return input + ".xml"; - } - - public static void main(String[] params) throws IOException { - if (0 == params.length) { - System.out.println("Usage: BiffDrawingToXml [options] inputWorkbook"); - System.out.println("Options:"); - System.out.println(" -exclude-workbook exclude workbook-level records"); - System.out.println(" -sheet-indexes output sheets with specified indexes"); - System.out.println(" -sheet-namek output sheets with specified name"); - return; - } - String input = getInputFileName(params); - FileInputStream inp = new FileInputStream(input); - String output = getOutputFileName(input); - FileOutputStream outputStream = new FileOutputStream(output); - writeToFile(outputStream, inp, isExcludeWorkbookRecords(params), params); - inp.close(); - outputStream.close(); - } - - public static void writeToFile(OutputStream fos, InputStream xlsWorkbook, boolean excludeWorkbookRecords, String[] params) throws IOException { - HSSFWorkbook workbook = new HSSFWorkbook(xlsWorkbook); - InternalWorkbook internalWorkbook = workbook.getInternalWorkbook(); - DrawingGroupRecord r = (DrawingGroupRecord) internalWorkbook.findFirstRecordBySid(DrawingGroupRecord.sid); - - StringBuilder builder = new StringBuilder(); - builder.append("\n"); - String tab = "\t"; - if (!excludeWorkbookRecords && r != null) { - r.decode(); - List escherRecords = r.getEscherRecords(); - for (EscherRecord record : escherRecords) { - builder.append(record.toXml(tab)); - } - } - List sheets = getSheetsIndexes(params, workbook); - for (Integer i : sheets) { - HSSFPatriarch p = workbook.getSheetAt(i).getDrawingPatriarch(); - if(p != null ) { - builder.append(tab).append("\n"); - builder.append(p.getBoundAggregate().toXml(tab + "\t")); - builder.append(tab).append("\n"); - } - } - builder.append("\n"); - fos.write(builder.toString().getBytes(StringUtil.UTF8)); - fos.close(); - workbook.close(); - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java deleted file mode 100644 index 5465f0ff1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ /dev/null @@ -1,880 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.dev; - -import java.io.DataInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.record.ArrayRecord; -import org.apache.poi.hssf.record.AutoFilterInfoRecord; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BackupRecord; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BookBoolRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.BottomMarginRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.CFHeader12Record; -import org.apache.poi.hssf.record.CFHeaderRecord; -import org.apache.poi.hssf.record.CFRule12Record; -import org.apache.poi.hssf.record.CFRuleRecord; -import org.apache.poi.hssf.record.CalcCountRecord; -import org.apache.poi.hssf.record.CalcModeRecord; -import org.apache.poi.hssf.record.CodepageRecord; -import org.apache.poi.hssf.record.ColumnInfoRecord; -import org.apache.poi.hssf.record.ContinueRecord; -import org.apache.poi.hssf.record.CountryRecord; -import org.apache.poi.hssf.record.DBCellRecord; -import org.apache.poi.hssf.record.DConRefRecord; -import org.apache.poi.hssf.record.DSFRecord; -import org.apache.poi.hssf.record.DVALRecord; -import org.apache.poi.hssf.record.DVRecord; -import org.apache.poi.hssf.record.DateWindow1904Record; -import org.apache.poi.hssf.record.DefaultColWidthRecord; -import org.apache.poi.hssf.record.DefaultRowHeightRecord; -import org.apache.poi.hssf.record.DeltaRecord; -import org.apache.poi.hssf.record.DimensionsRecord; -import org.apache.poi.hssf.record.DrawingGroupRecord; -import org.apache.poi.hssf.record.DrawingRecordForBiffViewer; -import org.apache.poi.hssf.record.DrawingSelectionRecord; -import org.apache.poi.hssf.record.EOFRecord; -import org.apache.poi.hssf.record.ExtSSTRecord; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.ExternSheetRecord; -import org.apache.poi.hssf.record.ExternalNameRecord; -import org.apache.poi.hssf.record.FeatHdrRecord; -import org.apache.poi.hssf.record.FeatRecord; -import org.apache.poi.hssf.record.FilePassRecord; -import org.apache.poi.hssf.record.FileSharingRecord; -import org.apache.poi.hssf.record.FnGroupCountRecord; -import org.apache.poi.hssf.record.FontRecord; -import org.apache.poi.hssf.record.FooterRecord; -import org.apache.poi.hssf.record.FormatRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.GridsetRecord; -import org.apache.poi.hssf.record.GutsRecord; -import org.apache.poi.hssf.record.HCenterRecord; -import org.apache.poi.hssf.record.HeaderRecord; -import org.apache.poi.hssf.record.HideObjRecord; -import org.apache.poi.hssf.record.HorizontalPageBreakRecord; -import org.apache.poi.hssf.record.HyperlinkRecord; -import org.apache.poi.hssf.record.IndexRecord; -import org.apache.poi.hssf.record.InterfaceEndRecord; -import org.apache.poi.hssf.record.InterfaceHdrRecord; -import org.apache.poi.hssf.record.IterationRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.LeftMarginRecord; -import org.apache.poi.hssf.record.MMSRecord; -import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.hssf.record.MulBlankRecord; -import org.apache.poi.hssf.record.MulRKRecord; -import org.apache.poi.hssf.record.NameCommentRecord; -import org.apache.poi.hssf.record.NameRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.ObjRecord; -import org.apache.poi.hssf.record.PaletteRecord; -import org.apache.poi.hssf.record.PaneRecord; -import org.apache.poi.hssf.record.PasswordRecord; -import org.apache.poi.hssf.record.PasswordRev4Record; -import org.apache.poi.hssf.record.PrecisionRecord; -import org.apache.poi.hssf.record.PrintGridlinesRecord; -import org.apache.poi.hssf.record.PrintHeadersRecord; -import org.apache.poi.hssf.record.PrintSetupRecord; -import org.apache.poi.hssf.record.ProtectRecord; -import org.apache.poi.hssf.record.ProtectionRev4Record; -import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.RecalcIdRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.RecordInputStream.LeftoverDataException; -import org.apache.poi.hssf.record.RefModeRecord; -import org.apache.poi.hssf.record.RefreshAllRecord; -import org.apache.poi.hssf.record.RightMarginRecord; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.SCLRecord; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.SaveRecalcRecord; -import org.apache.poi.hssf.record.SelectionRecord; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.hssf.record.StyleRecord; -import org.apache.poi.hssf.record.SupBookRecord; -import org.apache.poi.hssf.record.TabIdRecord; -import org.apache.poi.hssf.record.TableRecord; -import org.apache.poi.hssf.record.TableStylesRecord; -import org.apache.poi.hssf.record.TextObjectRecord; -import org.apache.poi.hssf.record.TopMarginRecord; -import org.apache.poi.hssf.record.UncalcedRecord; -import org.apache.poi.hssf.record.UnknownRecord; -import org.apache.poi.hssf.record.UseSelFSRecord; -import org.apache.poi.hssf.record.VCenterRecord; -import org.apache.poi.hssf.record.VerticalPageBreakRecord; -import org.apache.poi.hssf.record.WSBoolRecord; -import org.apache.poi.hssf.record.WindowOneRecord; -import org.apache.poi.hssf.record.WindowProtectRecord; -import org.apache.poi.hssf.record.WindowTwoRecord; -import org.apache.poi.hssf.record.WriteAccessRecord; -import org.apache.poi.hssf.record.WriteProtectRecord; -import org.apache.poi.hssf.record.chart.AreaFormatRecord; -import org.apache.poi.hssf.record.chart.AreaRecord; -import org.apache.poi.hssf.record.chart.AxisLineFormatRecord; -import org.apache.poi.hssf.record.chart.AxisOptionsRecord; -import org.apache.poi.hssf.record.chart.AxisParentRecord; -import org.apache.poi.hssf.record.chart.AxisRecord; -import org.apache.poi.hssf.record.chart.AxisUsedRecord; -import org.apache.poi.hssf.record.chart.BarRecord; -import org.apache.poi.hssf.record.chart.BeginRecord; -import org.apache.poi.hssf.record.chart.CatLabRecord; -import org.apache.poi.hssf.record.chart.CategorySeriesAxisRecord; -import org.apache.poi.hssf.record.chart.ChartEndBlockRecord; -import org.apache.poi.hssf.record.chart.ChartEndObjectRecord; -import org.apache.poi.hssf.record.chart.ChartFRTInfoRecord; -import org.apache.poi.hssf.record.chart.ChartFormatRecord; -import org.apache.poi.hssf.record.chart.ChartRecord; -import org.apache.poi.hssf.record.chart.ChartStartBlockRecord; -import org.apache.poi.hssf.record.chart.ChartStartObjectRecord; -import org.apache.poi.hssf.record.chart.DatRecord; -import org.apache.poi.hssf.record.chart.DataFormatRecord; -import org.apache.poi.hssf.record.chart.DefaultDataLabelTextPropertiesRecord; -import org.apache.poi.hssf.record.chart.EndRecord; -import org.apache.poi.hssf.record.chart.FontBasisRecord; -import org.apache.poi.hssf.record.chart.FontIndexRecord; -import org.apache.poi.hssf.record.chart.FrameRecord; -import org.apache.poi.hssf.record.chart.LegendRecord; -import org.apache.poi.hssf.record.chart.LineFormatRecord; -import org.apache.poi.hssf.record.chart.LinkedDataRecord; -import org.apache.poi.hssf.record.chart.ObjectLinkRecord; -import org.apache.poi.hssf.record.chart.PlotAreaRecord; -import org.apache.poi.hssf.record.chart.PlotGrowthRecord; -import org.apache.poi.hssf.record.chart.SeriesIndexRecord; -import org.apache.poi.hssf.record.chart.SeriesListRecord; -import org.apache.poi.hssf.record.chart.SeriesRecord; -import org.apache.poi.hssf.record.chart.SeriesTextRecord; -import org.apache.poi.hssf.record.chart.SeriesToChartGroupRecord; -import org.apache.poi.hssf.record.chart.SheetPropertiesRecord; -import org.apache.poi.hssf.record.chart.TextRecord; -import org.apache.poi.hssf.record.chart.TickRecord; -import org.apache.poi.hssf.record.chart.UnitsRecord; -import org.apache.poi.hssf.record.chart.ValueRangeRecord; -import org.apache.poi.hssf.record.pivottable.DataItemRecord; -import org.apache.poi.hssf.record.pivottable.ExtendedPivotTableViewFieldsRecord; -import org.apache.poi.hssf.record.pivottable.PageItemRecord; -import org.apache.poi.hssf.record.pivottable.StreamIDRecord; -import org.apache.poi.hssf.record.pivottable.ViewDefinitionRecord; -import org.apache.poi.hssf.record.pivottable.ViewFieldsRecord; -import org.apache.poi.hssf.record.pivottable.ViewSourceRecord; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * Utility for reading in BIFF8 records and displaying data from them. - * @see #main - */ -public final class BiffViewer { - private static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray(); - private static final POILogger logger = POILogFactory.getLogger(BiffViewer.class); - - private BiffViewer() { - // no instances of this class - } - - /** - * Create an array of records from an input stream - * - * @param is the InputStream from which the records will be obtained - * @param ps the PrintWriter to output the record data - * @param recListener the record listener to notify about read records - * @param dumpInterpretedRecords if {@code true}, the read records will be written to the PrintWriter - * - * @return an array of Records created from the InputStream - * @exception org.apache.poi.util.RecordFormatException on error processing the InputStream - */ - public static Record[] createRecords(InputStream is, PrintWriter ps, BiffRecordListener recListener, boolean dumpInterpretedRecords) - throws org.apache.poi.util.RecordFormatException { - List temp = new ArrayList(); - - RecordInputStream recStream = new RecordInputStream(is); - while (true) { - boolean hasNext; - try { - hasNext = recStream.hasNextRecord(); - } catch (LeftoverDataException e) { - logger.log(POILogger.ERROR, "Discarding " + recStream.remaining() + " bytes and continuing", e); - recStream.readRemainder(); - hasNext = recStream.hasNextRecord(); - } - if (!hasNext) { - break; - } - recStream.nextRecord(); - if (recStream.getSid() == 0) { - continue; - } - Record record; - if (dumpInterpretedRecords) { - record = createRecord (recStream); - if (record.getSid() == ContinueRecord.sid) { - continue; - } - temp.add(record); - - if (dumpInterpretedRecords) { - for (String header : recListener.getRecentHeaders()) { - ps.println(header); - } - ps.print(record.toString()); - } - } else { - recStream.readRemainder(); - } - ps.println(); - } - Record[] result = new Record[temp.size()]; - temp.toArray(result); - return result; - } - - - /** - * Essentially a duplicate of RecordFactory. Kept separate as not to screw - * up non-debug operations. - * - */ - private static Record createRecord(RecordInputStream in) { - switch (in.getSid()) { - case AreaFormatRecord.sid: return new AreaFormatRecord(in); - case AreaRecord.sid: return new AreaRecord(in); - case ArrayRecord.sid: return new ArrayRecord(in); - case AxisLineFormatRecord.sid: return new AxisLineFormatRecord(in); - case AxisOptionsRecord.sid: return new AxisOptionsRecord(in); - case AxisParentRecord.sid: return new AxisParentRecord(in); - case AxisRecord.sid: return new AxisRecord(in); - case AxisUsedRecord.sid: return new AxisUsedRecord(in); - case AutoFilterInfoRecord.sid: return new AutoFilterInfoRecord(in); - case BOFRecord.sid: return new BOFRecord(in); - case BackupRecord.sid: return new BackupRecord(in); - case BarRecord.sid: return new BarRecord(in); - case BeginRecord.sid: return new BeginRecord(in); - case BlankRecord.sid: return new BlankRecord(in); - case BookBoolRecord.sid: return new BookBoolRecord(in); - case BoolErrRecord.sid: return new BoolErrRecord(in); - case BottomMarginRecord.sid: return new BottomMarginRecord(in); - case BoundSheetRecord.sid: return new BoundSheetRecord(in); - case CFHeaderRecord.sid: return new CFHeaderRecord(in); - case CFHeader12Record.sid: return new CFHeader12Record(in); - case CFRuleRecord.sid: return new CFRuleRecord(in); - case CFRule12Record.sid: return new CFRule12Record(in); - // TODO Add CF Ex, and remove from UnknownRecord - case CalcCountRecord.sid: return new CalcCountRecord(in); - case CalcModeRecord.sid: return new CalcModeRecord(in); - case CategorySeriesAxisRecord.sid:return new CategorySeriesAxisRecord(in); - case ChartFormatRecord.sid: return new ChartFormatRecord(in); - case ChartRecord.sid: return new ChartRecord(in); - case CodepageRecord.sid: return new CodepageRecord(in); - case ColumnInfoRecord.sid: return new ColumnInfoRecord(in); - case ContinueRecord.sid: return new ContinueRecord(in); - case CountryRecord.sid: return new CountryRecord(in); - case DBCellRecord.sid: return new DBCellRecord(in); - case DSFRecord.sid: return new DSFRecord(in); - case DatRecord.sid: return new DatRecord(in); - case DataFormatRecord.sid: return new DataFormatRecord(in); - case DateWindow1904Record.sid: return new DateWindow1904Record(in); - case DConRefRecord.sid: return new DConRefRecord(in); - case DefaultColWidthRecord.sid: return new DefaultColWidthRecord(in); - case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in); - case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in); - case DeltaRecord.sid: return new DeltaRecord(in); - case DimensionsRecord.sid: return new DimensionsRecord(in); - case DrawingGroupRecord.sid: return new DrawingGroupRecord(in); - case DrawingRecordForBiffViewer.sid: return new DrawingRecordForBiffViewer(in); - case DrawingSelectionRecord.sid: return new DrawingSelectionRecord(in); - case DVRecord.sid: return new DVRecord(in); - case DVALRecord.sid: return new DVALRecord(in); - case EOFRecord.sid: return new EOFRecord(in); - case EndRecord.sid: return new EndRecord(in); - case ExtSSTRecord.sid: return new ExtSSTRecord(in); - case ExtendedFormatRecord.sid: return new ExtendedFormatRecord(in); - case ExternSheetRecord.sid: return new ExternSheetRecord(in); - case ExternalNameRecord.sid: return new ExternalNameRecord(in); - case FeatRecord.sid: return new FeatRecord(in); - case FeatHdrRecord.sid: return new FeatHdrRecord(in); - case FilePassRecord.sid: return new FilePassRecord(in); - case FileSharingRecord.sid: return new FileSharingRecord(in); - case FnGroupCountRecord.sid: return new FnGroupCountRecord(in); - case FontBasisRecord.sid: return new FontBasisRecord(in); - case FontIndexRecord.sid: return new FontIndexRecord(in); - case FontRecord.sid: return new FontRecord(in); - case FooterRecord.sid: return new FooterRecord(in); - case FormatRecord.sid: return new FormatRecord(in); - case FormulaRecord.sid: return new FormulaRecord(in); - case FrameRecord.sid: return new FrameRecord(in); - case GridsetRecord.sid: return new GridsetRecord(in); - case GutsRecord.sid: return new GutsRecord(in); - case HCenterRecord.sid: return new HCenterRecord(in); - case HeaderRecord.sid: return new HeaderRecord(in); - case HideObjRecord.sid: return new HideObjRecord(in); - case HorizontalPageBreakRecord.sid: return new HorizontalPageBreakRecord(in); - case HyperlinkRecord.sid: return new HyperlinkRecord(in); - case IndexRecord.sid: return new IndexRecord(in); - case InterfaceEndRecord.sid: return InterfaceEndRecord.create(in); - case InterfaceHdrRecord.sid: return new InterfaceHdrRecord(in); - case IterationRecord.sid: return new IterationRecord(in); - case LabelRecord.sid: return new LabelRecord(in); - case LabelSSTRecord.sid: return new LabelSSTRecord(in); - case LeftMarginRecord.sid: return new LeftMarginRecord(in); - case LegendRecord.sid: return new LegendRecord(in); - case LineFormatRecord.sid: return new LineFormatRecord(in); - case LinkedDataRecord.sid: return new LinkedDataRecord(in); - case MMSRecord.sid: return new MMSRecord(in); - case MergeCellsRecord.sid: return new MergeCellsRecord(in); - case MulBlankRecord.sid: return new MulBlankRecord(in); - case MulRKRecord.sid: return new MulRKRecord(in); - case NameRecord.sid: return new NameRecord(in); - case NameCommentRecord.sid: return new NameCommentRecord(in); - case NoteRecord.sid: return new NoteRecord(in); - case NumberRecord.sid: return new NumberRecord(in); - case ObjRecord.sid: return new ObjRecord(in); - case ObjectLinkRecord.sid: return new ObjectLinkRecord(in); - case PaletteRecord.sid: return new PaletteRecord(in); - case PaneRecord.sid: return new PaneRecord(in); - case PasswordRecord.sid: return new PasswordRecord(in); - case PasswordRev4Record.sid: return new PasswordRev4Record(in); - case PlotAreaRecord.sid: return new PlotAreaRecord(in); - case PlotGrowthRecord.sid: return new PlotGrowthRecord(in); - case PrecisionRecord.sid: return new PrecisionRecord(in); - case PrintGridlinesRecord.sid: return new PrintGridlinesRecord(in); - case PrintHeadersRecord.sid: return new PrintHeadersRecord(in); - case PrintSetupRecord.sid: return new PrintSetupRecord(in); - case ProtectRecord.sid: return new ProtectRecord(in); - case ProtectionRev4Record.sid: return new ProtectionRev4Record(in); - case RKRecord.sid: return new RKRecord(in); - case RecalcIdRecord.sid: return new RecalcIdRecord(in); - case RefModeRecord.sid: return new RefModeRecord(in); - case RefreshAllRecord.sid: return new RefreshAllRecord(in); - case RightMarginRecord.sid: return new RightMarginRecord(in); - case RowRecord.sid: return new RowRecord(in); - case SCLRecord.sid: return new SCLRecord(in); - case SSTRecord.sid: return new SSTRecord(in); - case SaveRecalcRecord.sid: return new SaveRecalcRecord(in); - case SelectionRecord.sid: return new SelectionRecord(in); - case SeriesIndexRecord.sid: return new SeriesIndexRecord(in); - case SeriesListRecord.sid: return new SeriesListRecord(in); - case SeriesRecord.sid: return new SeriesRecord(in); - case SeriesTextRecord.sid: return new SeriesTextRecord(in); - case SeriesToChartGroupRecord.sid:return new SeriesToChartGroupRecord(in); - case SharedFormulaRecord.sid: return new SharedFormulaRecord(in); - case SheetPropertiesRecord.sid: return new SheetPropertiesRecord(in); - case StringRecord.sid: return new StringRecord(in); - case StyleRecord.sid: return new StyleRecord(in); - case SupBookRecord.sid: return new SupBookRecord(in); - case TabIdRecord.sid: return new TabIdRecord(in); - case TableStylesRecord.sid: return new TableStylesRecord(in); - case TableRecord.sid: return new TableRecord(in); - case TextObjectRecord.sid: return new TextObjectRecord(in); - case TextRecord.sid: return new TextRecord(in); - case TickRecord.sid: return new TickRecord(in); - case TopMarginRecord.sid: return new TopMarginRecord(in); - case UncalcedRecord.sid: return new UncalcedRecord(in); - case UnitsRecord.sid: return new UnitsRecord(in); - case UseSelFSRecord.sid: return new UseSelFSRecord(in); - case VCenterRecord.sid: return new VCenterRecord(in); - case ValueRangeRecord.sid: return new ValueRangeRecord(in); - case VerticalPageBreakRecord.sid: return new VerticalPageBreakRecord(in); - case WSBoolRecord.sid: return new WSBoolRecord(in); - case WindowOneRecord.sid: return new WindowOneRecord(in); - case WindowProtectRecord.sid: return new WindowProtectRecord(in); - case WindowTwoRecord.sid: return new WindowTwoRecord(in); - case WriteAccessRecord.sid: return new WriteAccessRecord(in); - case WriteProtectRecord.sid: return new WriteProtectRecord(in); - - // chart - case CatLabRecord.sid: return new CatLabRecord(in); - case ChartEndBlockRecord.sid: return new ChartEndBlockRecord(in); - case ChartEndObjectRecord.sid: return new ChartEndObjectRecord(in); - case ChartFRTInfoRecord.sid: return new ChartFRTInfoRecord(in); - case ChartStartBlockRecord.sid: return new ChartStartBlockRecord(in); - case ChartStartObjectRecord.sid: return new ChartStartObjectRecord(in); - - // pivot table - case StreamIDRecord.sid: return new StreamIDRecord(in); - case ViewSourceRecord.sid: return new ViewSourceRecord(in); - case PageItemRecord.sid: return new PageItemRecord(in); - case ViewDefinitionRecord.sid: return new ViewDefinitionRecord(in); - case ViewFieldsRecord.sid: return new ViewFieldsRecord(in); - case DataItemRecord.sid: return new DataItemRecord(in); - case ExtendedPivotTableViewFieldsRecord.sid: return new ExtendedPivotTableViewFieldsRecord(in); - } - return new UnknownRecord(in); - } - - private static final class CommandArgs { - - private final boolean _biffhex; - private final boolean _noint; - private final boolean _out; - private final boolean _rawhex; - private final boolean _noHeader; - private final File _file; - - private CommandArgs(boolean biffhex, boolean noint, boolean out, boolean rawhex, boolean noHeader, File file) { - _biffhex = biffhex; - _noint = noint; - _out = out; - _rawhex = rawhex; - _file = file; - _noHeader = noHeader; - } - - public static CommandArgs parse(String[] args) throws CommandParseException { - int nArgs = args.length; - boolean biffhex = false; - boolean noint = false; - boolean out = false; - boolean rawhex = false; - boolean noheader = false; - File file = null; - for (int i=0; i - * - * Usage:

    - * - * BiffViewer [--biffhex] [--noint] [--noescher] [--out] <fileName>

    - * BiffViewer --rawhex [--out] <fileName> - * - * - * - * - * - * - * - * - *
    --biffhexshow hex dump of each BIFF record
    --nointdo not output interpretation of BIFF records
    --outsend output to <fileName>.out
    --rawhexoutput raw hex dump of whole workbook stream
    --escherturn on deserialization of escher records (default is off)
    --noheaderdo not print record header (default is on)
    - * - * @param args the command line arguments - * - * @throws IOException if the file doesn't exist or contained errors - * @throws CommandParseException if the command line contained errors - */ - public static void main(String[] args) throws IOException, CommandParseException { - // args = new String[] { "--out", "", }; - CommandArgs cmdArgs = CommandArgs.parse(args); - - PrintWriter pw; - if (cmdArgs.shouldOutputToFile()) { - OutputStream os = new FileOutputStream(cmdArgs.getFile().getAbsolutePath() + ".out"); - pw = new PrintWriter(new OutputStreamWriter(os, StringUtil.UTF8)); - } else { - // Use the system default encoding when sending to System Out - pw = new PrintWriter(new OutputStreamWriter(System.out, Charset.defaultCharset())); - } - - try { - NPOIFSFileSystem fs = new NPOIFSFileSystem(cmdArgs.getFile(), true); - try { - InputStream is = getPOIFSInputStream(fs); - - try { - if (cmdArgs.shouldOutputRawHexOnly()) { - int size = is.available(); - byte[] data = new byte[size]; - - is.read(data); - HexDump.dump(data, 0, System.out, 0); - } else { - boolean dumpInterpretedRecords = cmdArgs.shouldDumpRecordInterpretations(); - boolean dumpHex = cmdArgs.shouldDumpBiffHex(); - boolean zeroAlignHexDump = dumpInterpretedRecords; // TODO - fix non-zeroAlign - runBiffViewer(pw, is, dumpInterpretedRecords, dumpHex, zeroAlignHexDump, - cmdArgs.suppressHeader()); - } - } finally { - is.close(); - } - } finally { - fs.close(); - } - } finally { - pw.close(); - } - } - - protected static InputStream getPOIFSInputStream(NPOIFSFileSystem fs) - throws IOException, FileNotFoundException { - String workbookName = HSSFWorkbook.getWorkbookDirEntryName(fs.getRoot()); - return fs.createDocumentInputStream(workbookName); - } - - protected static void runBiffViewer(PrintWriter pw, InputStream is, - boolean dumpInterpretedRecords, boolean dumpHex, boolean zeroAlignHexDump, - boolean suppressHeader) { - BiffRecordListener recListener = new BiffRecordListener(dumpHex ? pw : null, zeroAlignHexDump, suppressHeader); - is = new BiffDumpingStream(is, recListener); - createRecords(is, pw, recListener, dumpInterpretedRecords); - } - - private static final class BiffRecordListener implements IBiffRecordListener { - private final Writer _hexDumpWriter; - private List _headers; - private final boolean _zeroAlignEachRecord; - private final boolean _noHeader; - public BiffRecordListener(Writer hexDumpWriter, boolean zeroAlignEachRecord, boolean noHeader) { - _hexDumpWriter = hexDumpWriter; - _zeroAlignEachRecord = zeroAlignEachRecord; - _noHeader = noHeader; - _headers = new ArrayList(); - } - - @Override - public void processRecord(int globalOffset, int recordCounter, int sid, int dataSize, - byte[] data) { - String header = formatRecordDetails(globalOffset, sid, dataSize, recordCounter); - if(!_noHeader) _headers.add(header); - Writer w = _hexDumpWriter; - if (w != null) { - try { - w.write(header); - w.write(NEW_LINE_CHARS); - hexDumpAligned(w, data, dataSize+4, globalOffset, _zeroAlignEachRecord); - w.flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - public List getRecentHeaders() { - List result = _headers; - _headers = new ArrayList(); - return result; - } - private static String formatRecordDetails(int globalOffset, int sid, int size, int recordCounter) { - StringBuilder sb = new StringBuilder(64); - sb.append("Offset=").append(HexDump.intToHex(globalOffset)).append("(").append(globalOffset).append(")"); - sb.append(" recno=").append(recordCounter); - sb.append( " sid=").append(HexDump.shortToHex(sid)); - sb.append( " size=").append(HexDump.shortToHex(size)).append("(").append(size).append(")"); - return sb.toString(); - } - } - - private interface IBiffRecordListener { - - void processRecord(int globalOffset, int recordCounter, int sid, int dataSize, byte[] data); - - } - - /** - * Wraps a plain {@link InputStream} and allows BIFF record information to be tapped off - * - */ - private static final class BiffDumpingStream extends InputStream { - private final DataInputStream _is; - private final IBiffRecordListener _listener; - private final byte[] _data; - private int _recordCounter; - private int _overallStreamPos; - private int _currentPos; - private int _currentSize; - private boolean _innerHasReachedEOF; - - public BiffDumpingStream(InputStream is, IBiffRecordListener listener) { - _is = new DataInputStream(is); - _listener = listener; - _data = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE + 4]; - _recordCounter = 0; - _overallStreamPos = 0; - _currentSize = 0; - _currentPos = 0; - } - - @Override - public int read() throws IOException { - if (_currentPos >= _currentSize) { - fillNextBuffer(); - } - if (_currentPos >= _currentSize) { - return -1; - } - int result = _data[_currentPos] & 0x00FF; - _currentPos ++; - _overallStreamPos ++; - formatBufferIfAtEndOfRec(); - return result; - } - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (_currentPos >= _currentSize) { - fillNextBuffer(); - } - if (_currentPos >= _currentSize) { - return -1; - } - int availSize = _currentSize - _currentPos; - int result; - if (len > availSize) { - System.err.println("Unexpected request to read past end of current biff record"); - result = availSize; - } else { - result = len; - } - System.arraycopy(_data, _currentPos, b, off, result); - _currentPos += result; - _overallStreamPos += result; - formatBufferIfAtEndOfRec(); - return result; - } - - @Override - public int available() throws IOException { - return _currentSize - _currentPos + _is.available(); - } - private void fillNextBuffer() throws IOException { - if (_innerHasReachedEOF) { - return; - } - int b0 = _is.read(); - if (b0 == -1) { - _innerHasReachedEOF = true; - return; - } - _data[0] = (byte) b0; - _is.readFully(_data, 1, 3); - int len = LittleEndian.getShort(_data, 2); - _is.readFully(_data, 4, len); - _currentPos = 0; - _currentSize = len + 4; - _recordCounter++; - } - private void formatBufferIfAtEndOfRec() { - if (_currentPos != _currentSize) { - return; - } - int dataSize = _currentSize-4; - int sid = LittleEndian.getShort(_data, 0); - int globalOffset = _overallStreamPos-_currentSize; - _listener.processRecord(globalOffset, _recordCounter, sid, dataSize, _data); - } - @Override - public void close() throws IOException { - _is.close(); - } - } - - private static final int DUMP_LINE_LEN = 16; - private static final char[] COLUMN_SEPARATOR = " | ".toCharArray(); - /** - * Hex-dumps a portion of a byte array in typical format, also preserving dump-line alignment - * @param globalOffset (somewhat arbitrary) used to calculate the addresses printed at the - * start of each line - */ - static void hexDumpAligned(Writer w, byte[] data, int dumpLen, int globalOffset, - boolean zeroAlignEachRecord) { - int baseDataOffset = 0; - - // perhaps this code should be moved to HexDump - int globalStart = globalOffset + baseDataOffset; - int globalEnd = globalOffset + baseDataOffset + dumpLen; - int startDelta = globalStart % DUMP_LINE_LEN; - int endDelta = globalEnd % DUMP_LINE_LEN; - if (zeroAlignEachRecord) { - endDelta -= startDelta; - if (endDelta < 0) { - endDelta += DUMP_LINE_LEN; - } - startDelta = 0; - } - int startLineAddr; - int endLineAddr; - if (zeroAlignEachRecord) { - endLineAddr = globalEnd - endDelta - (globalStart - startDelta); - startLineAddr = 0; - } else { - startLineAddr = globalStart - startDelta; - endLineAddr = globalEnd - endDelta; - } - - int lineDataOffset = baseDataOffset - startDelta; - int lineAddr = startLineAddr; - - // output (possibly incomplete) first line - if (startLineAddr == endLineAddr) { - hexDumpLine(w, data, lineAddr, lineDataOffset, startDelta, endDelta); - return; - } - hexDumpLine(w, data, lineAddr, lineDataOffset, startDelta, DUMP_LINE_LEN); - - // output all full lines in the middle - while (true) { - lineAddr += DUMP_LINE_LEN; - lineDataOffset += DUMP_LINE_LEN; - if (lineAddr >= endLineAddr) { - break; - } - hexDumpLine(w, data, lineAddr, lineDataOffset, 0, DUMP_LINE_LEN); - } - - - // output (possibly incomplete) last line - if (endDelta != 0) { - hexDumpLine(w, data, lineAddr, lineDataOffset, 0, endDelta); - } - } - - private static void hexDumpLine(Writer w, byte[] data, int lineStartAddress, int lineDataOffset, int startDelta, int endDelta) { - final char[] buf = new char[8+2*COLUMN_SEPARATOR.length+DUMP_LINE_LEN*3-1+DUMP_LINE_LEN+NEW_LINE_CHARS.length]; - - if (startDelta >= endDelta) { - throw new IllegalArgumentException("Bad start/end delta"); - } - int idx=0; - try { - writeHex(buf, idx, lineStartAddress, 8); - idx = arraycopy(COLUMN_SEPARATOR, buf, idx+8); - // raw hex data - for (int i=0; i< DUMP_LINE_LEN; i++) { - if (i>0) { - buf[idx++] = ' '; - } - if (i >= startDelta && i < endDelta) { - writeHex(buf, idx, data[lineDataOffset+i], 2); - } else { - buf[idx] = ' '; - buf[idx+1] = ' '; - } - idx += 2; - } - idx = arraycopy(COLUMN_SEPARATOR, buf, idx); - - // interpreted ascii - for (int i=0; i< DUMP_LINE_LEN; i++) { - char ch = ' '; - if (i >= startDelta && i < endDelta) { - ch = getPrintableChar(data[lineDataOffset+i]); - } - buf[idx++] = ch; - } - - idx = arraycopy(NEW_LINE_CHARS, buf, idx); - - w.write(buf, 0, idx); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static int arraycopy(char[] in, char[] out, int pos) { - int idx = pos; - for (char c : in) { - out[idx++] = c; - } - return idx; - } - - private static char getPrintableChar(byte b) { - char ib = (char) (b & 0x00FF); - if (ib < 32 || ib > 126) { - return '.'; - } - return ib; - } - - private static void writeHex(char buf[], int startInBuf, int value, int nDigits) throws IOException { - int acc = value; - for(int i=nDigits-1; i>=0; i--) { - int digit = acc & 0x0F; - buf[startInBuf+i] = (char) (digit < 10 ? ('0' + digit) : ('A' + digit - 10)); - acc >>>= 4; - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java b/trunk/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java deleted file mode 100644 index b136e4ca8..000000000 --- a/trunk/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.dev; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; -import org.apache.poi.hssf.eventusermodel.HSSFListener; -import org.apache.poi.hssf.eventusermodel.HSSFRequest; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; - -/** - * - * @author andy - */ - -public class EFBiffViewer -{ - String file; - - /** Creates a new instance of EFBiffViewer */ - - public EFBiffViewer() - { - } - - public void run() throws IOException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); - try { - InputStream din = BiffViewer.getPOIFSInputStream(fs); - try { - HSSFRequest req = new HSSFRequest(); - - req.addListenerForAllRecords(new HSSFListener() - { - public void processRecord(Record rec) - { - System.out.println(rec.toString()); - } - }); - HSSFEventFactory factory = new HSSFEventFactory(); - - factory.processEvents(req, din); - } finally { - din.close(); - } - } finally { - fs.close(); - } - } - - public void setFile(String file) - { - this.file = file; - } - - public static void main(String [] args) throws IOException - { - if ((args.length == 1) && !args[ 0 ].equals("--help")) - { - EFBiffViewer viewer = new EFBiffViewer(); - - viewer.setFile(args[ 0 ]); - viewer.run(); - } - else - { - System.out.println("EFBiffViewer"); - System.out.println( - "Outputs biffview of records based on HSSFEventFactory"); - System.out - .println("usage: java org.apache.poi.hssf.dev.EBBiffViewer " - + "filename"); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/dev/FormulaViewer.java b/trunk/src/java/org/apache/poi/hssf/dev/FormulaViewer.java deleted file mode 100644 index 3426d4a09..000000000 --- a/trunk/src/java/org/apache/poi/hssf/dev/FormulaViewer.java +++ /dev/null @@ -1,236 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.dev; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFactory; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.ss.formula.ptg.ExpPtg; -import org.apache.poi.ss.formula.ptg.FuncPtg; -import org.apache.poi.ss.formula.ptg.Ptg; - -/** - * FormulaViewer - finds formulas in a BIFF8 file and attempts to read them/display - * data from them. Only works if Formulas are enabled in "RecordFactory" - * @author andy - * @author Avik - */ - -public class FormulaViewer -{ - private String file; - private boolean list=false; - - /** Creates new FormulaViewer */ - - public FormulaViewer() - { - } - - /** - * Method run - * - * @throws IOException if the file contained errors - */ - public void run() throws IOException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); - try { - InputStream is = BiffViewer.getPOIFSInputStream(fs); - try { - List records = RecordFactory.createRecords(is); - - for (Record record : records) { - if (record.getSid() == FormulaRecord.sid) { - if (list) { - listFormula((FormulaRecord) record); - } else { - parseFormulaRecord((FormulaRecord) record); - } - } - } - } finally { - is.close(); - } - } finally { - fs.close(); - } - } - - private void listFormula(FormulaRecord record) { - String sep="~"; - Ptg[] tokens= record.getParsedExpression(); - Ptg token; - int numptgs = tokens.length; - String numArg; - token = tokens[numptgs-1]; - if (token instanceof FuncPtg) { - numArg = String.valueOf(numptgs-1); - } else { - numArg = String.valueOf(-1); - } - - StringBuilder buf = new StringBuilder(); - - if (token instanceof ExpPtg) return; - buf.append(token.toFormulaString()); - buf.append(sep); - switch (token.getPtgClass()) { - case Ptg.CLASS_REF : - buf.append("REF"); - break; - case Ptg.CLASS_VALUE : - buf.append("VALUE"); - break; - case Ptg.CLASS_ARRAY : - buf.append("ARRAY"); - break; - default: - throwInvalidRVAToken(token); - } - - buf.append(sep); - if (numptgs>1) { - token = tokens[numptgs-2]; - switch (token.getPtgClass()) { - case Ptg.CLASS_REF : - buf.append("REF"); - break; - case Ptg.CLASS_VALUE : - buf.append("VALUE"); - break; - case Ptg.CLASS_ARRAY : - buf.append("ARRAY"); - break; - default: - throwInvalidRVAToken(token); - } - }else { - buf.append("VALUE"); - } - buf.append(sep); - buf.append(numArg); - System.out.println(buf.toString()); - } - - /** - * Method parseFormulaRecord - * - * @param record the record to be parsed - */ - public void parseFormulaRecord(FormulaRecord record) - { - System.out.println("=============================="); - System.out.print("row = " + record.getRow()); - System.out.println(", col = " + record.getColumn()); - System.out.println("value = " + record.getValue()); - System.out.print("xf = " + record.getXFIndex()); - System.out.print(", number of ptgs = " - + record.getParsedExpression().length); - System.out.println(", options = " + record.getOptions()); - System.out.println("RPN List = "+formulaString(record)); - System.out.println("Formula text = "+ composeFormula(record)); - } - - private String formulaString(FormulaRecord record) { - - StringBuilder buf = new StringBuilder(); - Ptg[] tokens = record.getParsedExpression(); - for (Ptg token : tokens) { - buf.append( token.toFormulaString()); - switch (token.getPtgClass()) { - case Ptg.CLASS_REF : - buf.append("(R)"); - break; - case Ptg.CLASS_VALUE : - buf.append("(V)"); - break; - case Ptg.CLASS_ARRAY : - buf.append("(A)"); - break; - default: - throwInvalidRVAToken(token); - } - buf.append(' '); - } - return buf.toString(); - } - - private static void throwInvalidRVAToken(Ptg token) { - throw new IllegalStateException("Invalid RVA type (" + token.getPtgClass() + "). This should never happen."); - } - - - private static String composeFormula(FormulaRecord record) - { - return HSSFFormulaParser.toFormulaString((HSSFWorkbook)null, record.getParsedExpression()); - } - - /** - * Method setFile - * - * @param file the file to process - */ - - public void setFile(String file) - { - this.file = file; - } - - public void setList(boolean list) { - this.list=list; - } - - /** - * Method main - * - * pass me a filename and I'll try and parse the formulas from it - * - * @param args pass one argument with the filename or --help - * @throws IOException if the file can't be read or contained errors - */ - public static void main(String args[]) throws IOException - { - if ((args == null) || (args.length >2 ) - || args[ 0 ].equals("--help")) - { - System.out.println( - "FormulaViewer .8 proof that the devil lies in the details (or just in BIFF8 files in general)"); - System.out.println("usage: Give me a big fat file name"); - } else if (args[0].equals("--listFunctions")) { // undocumented attribute to research functions!~ - FormulaViewer viewer = new FormulaViewer(); - viewer.setFile(args[1]); - viewer.setList(true); - viewer.run(); - } - else - { - FormulaViewer viewer = new FormulaViewer(); - - viewer.setFile(args[ 0 ]); - viewer.run(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/dev/ReSave.java b/trunk/src/java/org/apache/poi/hssf/dev/ReSave.java deleted file mode 100644 index 7f1988897..000000000 --- a/trunk/src/java/org/apache/poi/hssf/dev/ReSave.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.poi.hssf.dev; - -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.OutputStream; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -/** - * Utility to test that POI produces readable output - * after re-saving xls files. - * - * Usage: ReSave [-dg] input.xls - * -dg initialize drawings, causes to re-build escher aggregates in all sheets - * -bos only write to memory instead of a file - */ -public class ReSave { - public static void main(String[] args) throws Exception { - boolean initDrawing = false; - boolean saveToMemory = false; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - for(String filename : args) { - if(filename.equals("-dg")) { - initDrawing = true; - } else if(filename.equals("-bos")) { - saveToMemory = true; - } else { - System.out.print("reading " + filename + "..."); - FileInputStream is = new FileInputStream(filename); - HSSFWorkbook wb = new HSSFWorkbook(is); - try { - System.out.println("done"); - - for(int i = 0; i < wb.getNumberOfSheets(); i++){ - HSSFSheet sheet = wb.getSheetAt(i); - if(initDrawing) { - /*HSSFPatriarch dg =*/ sheet.getDrawingPatriarch(); - } - } - - OutputStream os; - if (saveToMemory) { - bos.reset(); - os = bos; - } else { - String outputFile = filename.replace(".xls", "-saved.xls"); - System.out.print("saving to " + outputFile + "..."); - os = new FileOutputStream(outputFile); - } - - try { - wb.write(os); - } finally { - os.close(); - } - System.out.println("done"); - } finally { - wb.close(); - is.close(); - } - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/dev/RecordLister.java b/trunk/src/java/org/apache/poi/hssf/dev/RecordLister.java deleted file mode 100644 index 8cb71e5da..000000000 --- a/trunk/src/java/org/apache/poi/hssf/dev/RecordLister.java +++ /dev/null @@ -1,202 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.dev; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hssf.record.ContinueRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFactory; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; - -/** - * This is a low-level debugging class, which simply prints - * out what records come in what order. - * Most people will want to use {@link BiffViewer} or - * {@link EFBiffViewer}, but this can be handy when - * trying to make sense of {@link ContinueRecord} - * special cases. - * - * Output is of the form: - * SID - Length - Type (if known) - * byte0 byte1 byte2 byte3 .... byte(n-4) byte(n-3) byte(n-2) byte(n-1) - */ -public class RecordLister -{ - String file; - - public RecordLister() - { - } - - public void run() - throws IOException - { - NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); - try { - InputStream din = BiffViewer.getPOIFSInputStream(fs); - try { - RecordInputStream rinp = new RecordInputStream(din); - - while(rinp.hasNextRecord()) { - int sid = rinp.getNextSid(); - rinp.nextRecord(); - - int size = rinp.available(); - Class clz = RecordFactory.getRecordClass(sid); - - System.out.print( - formatSID(sid) + - " - " + - formatSize(size) + - " bytes" - ); - if(clz != null) { - System.out.print(" \t"); - System.out.print(clz.getName().replace("org.apache.poi.hssf.record.", "")); - } - System.out.println(); - - byte[] data = rinp.readRemainder(); - if(data.length > 0) { - System.out.print(" "); - System.out.println( formatData(data) ); - } - } - } finally { - din.close(); - } - } finally { - fs.close(); - } - } - - private static String formatSID(int sid) { - String hex = Integer.toHexString(sid); - String dec = Integer.toString(sid); - - StringBuffer s = new StringBuffer(); - s.append("0x"); - for(int i=hex.length(); i<4; i++) { - s.append('0'); - } - s.append(hex); - - s.append(" ("); - for(int i=dec.length(); i<4; i++) { - s.append('0'); - } - s.append(dec); - s.append(")"); - - return s.toString(); - } - private static String formatSize(int size) { - String hex = Integer.toHexString(size); - String dec = Integer.toString(size); - - StringBuffer s = new StringBuffer(); - for(int i=hex.length(); i<3; i++) { - s.append('0'); - } - s.append(hex); - - s.append(" ("); - for(int i=dec.length(); i<3; i++) { - s.append('0'); - } - s.append(dec); - s.append(")"); - - return s.toString(); - } - private static String formatData(byte[] data) { - if(data == null || data.length == 0) - return ""; - - // If possible, do first 4 and last 4 bytes - StringBuffer s = new StringBuffer(); - if(data.length > 9) { - s.append(byteToHex(data[0])); - s.append(' '); - s.append(byteToHex(data[1])); - s.append(' '); - s.append(byteToHex(data[2])); - s.append(' '); - s.append(byteToHex(data[3])); - s.append(' '); - - s.append(" .... "); - - s.append(' '); - s.append(byteToHex(data[data.length-4])); - s.append(' '); - s.append(byteToHex(data[data.length-3])); - s.append(' '); - s.append(byteToHex(data[data.length-2])); - s.append(' '); - s.append(byteToHex(data[data.length-1])); - } else { - for(int i=0; i - - - - - - -DEV package serves two purposes. 1. Examples for how to use HSSF and 2. tools for developing -and validating HSSF. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/hssf/eventmodel/ERFListener.java b/trunk/src/java/org/apache/poi/hssf/eventmodel/ERFListener.java deleted file mode 100644 index 91276490b..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventmodel/ERFListener.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventmodel; - -import org.apache.poi.hssf.record.Record; - -/** - * An ERFListener is registered with the EventRecordFactory. - * An ERFListener listens for Records coming from the stream - * via the EventRecordFactory - * - * @see EventRecordFactory - */ -public interface ERFListener -{ - /** - * Process a Record. This method is called by the - * EventRecordFactory when a record is returned. - * - * @param rec the record to be processed - * - * @return boolean specifying whether the effort was a success. - */ - public boolean processRecord(Record rec); -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java b/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java deleted file mode 100644 index 519d4bbdb..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventmodel; - -import java.io.InputStream; -import java.util.Arrays; - -import org.apache.poi.hssf.record.*; - -/** - * Event-based record factory. As opposed to RecordFactory - * this version sends {@link ERFListener#processRecord(Record) } messages to - * the supplied listener. Record notifications are sent one record behind - * to ensure that {@link ContinueRecord}s are processed first. - */ -public final class EventRecordFactory { - - private final ERFListener _listener; - private final short[] _sids; - - /** - * Create an EventRecordFactory - * - * @param listener the listener to be informed about events - * @param sids an array of Record.sid values identifying the records - * the listener will work with. Alternatively if this is "null" then - * all records are passed. For all 'known' record types use {@link RecordFactory#getAllKnownRecordSIDs()} - */ - public EventRecordFactory(ERFListener listener, short[] sids) { - _listener = listener; - if (sids == null) { - _sids = null; - } else { - _sids = sids.clone(); - Arrays.sort(_sids); // for faster binary search - } - } - private boolean isSidIncluded(short sid) { - if (_sids == null) { - return true; - } - return Arrays.binarySearch(_sids, sid) >= 0; - } - - - /** - * sends the record event to all registered listeners. - * @param record the record to be thrown. - * @return false to abort. This aborts - * out of the event loop should the listener return false - */ - private boolean processRecord(Record record) { - if (!isSidIncluded(record.getSid())) { - return true; - } - return _listener.processRecord(record); - } - - /** - * Create an array of records from an input stream - * - * @param in the InputStream from which the records will be - * obtained - * - * @exception RecordFormatException on error processing the - * InputStream - */ - public void processRecords(InputStream in) throws RecordFormatException { - Record last_record = null; - - RecordInputStream recStream = new RecordInputStream(in); - - while (recStream.hasNextRecord()) { - recStream.nextRecord(); - Record[] recs = RecordFactory.createRecord(recStream); // handle MulRK records - if (recs.length > 1) { - for (Record rec : recs) { - if ( last_record != null ) { - if (!processRecord(last_record)) { - return; - } - } - last_record = rec; // do to keep the algorithm homogeneous...you can't - } // actually continue a number record anyhow. - } else { - Record record = recs[ 0 ]; - - if (record != null) { - if (last_record != null) { - if (!processRecord(last_record)) { - return; - } - } - last_record = record; - } - } - } - - if (last_record != null) { - processRecord(last_record); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/AbortableHSSFListener.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/AbortableHSSFListener.java deleted file mode 100644 index 9000a7476..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/AbortableHSSFListener.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.eventusermodel; - -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.eventusermodel.HSSFUserException; - -/** - * Abstract class for use with the HSSFRequest and HSSFEventFactory, which - * allows for the halting of processing. - * Users should create subclass of this (which implements the usual - * HSSFListener), and then override the #abortableProcessRecord(Record) - * method to do their processing. - * This should then be registered with the HSSFRequest (associating - * it with Record SID's) as usual. - * - * @see org.apache.poi.hssf.eventusermodel.HSSFEventFactory - * @see org.apache.poi.hssf.eventusermodel.HSSFRequest - * @see org.apache.poi.hssf.eventusermodel.HSSFUserException - */ - -public abstract class AbortableHSSFListener implements HSSFListener -{ - /** - * This method, inherited from HSSFListener is implemented as a stub. - * It is never called by HSSFEventFactory or HSSFRequest. - * You should implement #abortableProcessRecord instead - */ - @Override - public void processRecord(Record record) - { - } - - /** - * Process an HSSF Record. Called when a record occurs in an HSSF file. - * Provides two options for halting the processing of the HSSF file. - * - * The return value provides a means of non-error termination with a - * user-defined result code. A value of zero must be returned to - * continue processing, any other value will halt processing by - * HSSFEventFactory with the code being passed back by - * its abortable process events methods. - * - * Error termination can be done by throwing the HSSFUserException. - * - * Note that HSSFEventFactory will not call the inherited process - * - * @param record the record to be processed - * - * @return result code of zero for continued processing. - * - * @throws HSSFUserException User code can throw this to abort - * file processing by HSSFEventFactory and return diagnostic information. - */ - public abstract short abortableProcessRecord(Record record) throws HSSFUserException; -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/EventWorkbookBuilder.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/EventWorkbookBuilder.java deleted file mode 100644 index eb65517ce..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/EventWorkbookBuilder.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.eventusermodel; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.model.InternalWorkbook; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.EOFRecord; -import org.apache.poi.hssf.record.ExternSheetRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.SupBookRecord; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -/** - * When working with the EventUserModel, if you want to - * process formulas, you need an instance of - * {@link InternalWorkbook} to pass to a {@link HSSFWorkbook}, - * to finally give to {@link HSSFFormulaParser}, - * and this will build you stub ones. - * Since you're working with the EventUserModel, you - * wouldn't want to get a full {@link InternalWorkbook} and - * {@link HSSFWorkbook}, as they would eat too much memory. - * Instead, you should collect a few key records as they - * go past, then call this once you have them to build a - * stub {@link InternalWorkbook}, and from that a stub - * {@link HSSFWorkbook}, to use with the {@link HSSFFormulaParser}. - * - * The records you should collect are: - * * {@link ExternSheetRecord} - * * {@link BoundSheetRecord} - * You should probably also collect {@link SSTRecord}, - * but it's not required to pass this in. - * - * To help, this class includes a HSSFListener wrapper - * that will do the collecting for you. - */ -public class EventWorkbookBuilder { - - - /** - * Creates a stub Workbook from the supplied records, - * suitable for use with the {@link HSSFFormulaParser} - * @param externs The ExternSheetRecords in your file - * @param bounds The BoundSheetRecords in your file - * @param sst The SSTRecord in your file. - * @return A stub Workbook suitable for use with {@link HSSFFormulaParser} - */ - public static InternalWorkbook createStubWorkbook(ExternSheetRecord[] externs, - BoundSheetRecord[] bounds, SSTRecord sst) { - List wbRecords = new ArrayList(); - - // Core Workbook records go first - if(bounds != null) { - for (BoundSheetRecord bound : bounds) { - wbRecords.add(bound); - } - } - if(sst != null) { - wbRecords.add(sst); - } - - // Now we can have the ExternSheetRecords, - // preceded by a SupBookRecord - if(externs != null) { - wbRecords.add(SupBookRecord.createInternalReferences( - (short)externs.length)); - for (ExternSheetRecord extern : externs) { - wbRecords.add(extern); - } - } - - // Finally we need an EoF record - wbRecords.add(EOFRecord.instance); - - return InternalWorkbook.createWorkbook(wbRecords); - } - - /** - * Creates a stub workbook from the supplied records, - * suitable for use with the {@link HSSFFormulaParser} - * @param externs The ExternSheetRecords in your file - * @param bounds The BoundSheetRecords in your file - * @return A stub Workbook suitable for use with {@link HSSFFormulaParser} - */ - public static InternalWorkbook createStubWorkbook(ExternSheetRecord[] externs, - BoundSheetRecord[] bounds) { - return createStubWorkbook(externs, bounds, null); - } - - - /** - * A wrapping HSSFListener which will collect - * {@link BoundSheetRecord}s and {@link ExternSheetRecord}s as - * they go past, so you can create a Stub {@link InternalWorkbook} from - * them once required. - */ - public static class SheetRecordCollectingListener implements HSSFListener { - private final HSSFListener childListener; - private final List boundSheetRecords = new ArrayList(); - private final List externSheetRecords = new ArrayList(); - private SSTRecord sstRecord = null; - - public SheetRecordCollectingListener(HSSFListener childListener) { - this.childListener = childListener; - } - - - public BoundSheetRecord[] getBoundSheetRecords() { - return boundSheetRecords.toArray( - new BoundSheetRecord[boundSheetRecords.size()] - ); - } - public ExternSheetRecord[] getExternSheetRecords() { - return externSheetRecords.toArray( - new ExternSheetRecord[externSheetRecords.size()] - ); - } - public SSTRecord getSSTRecord() { - return sstRecord; - } - - public HSSFWorkbook getStubHSSFWorkbook() { - // Create a base workbook - HSSFWorkbook wb = HSSFWorkbook.create(getStubWorkbook()); - // Stub the sheets, so sheet name lookups work - for (BoundSheetRecord bsr : boundSheetRecords) { - wb.createSheet(bsr.getSheetname()); - } - // Ready for Formula use! - return wb; - } - public InternalWorkbook getStubWorkbook() { - return createStubWorkbook( - getExternSheetRecords(), getBoundSheetRecords(), - getSSTRecord() - ); - } - - - /** - * Process this record ourselves, and then - * pass it on to our child listener - */ - @Override - public void processRecord(Record record) { - // Handle it ourselves - processRecordInternally(record); - - // Now pass on to our child - childListener.processRecord(record); - } - - /** - * Process the record ourselves, but do not - * pass it on to the child Listener. - * - * @param record the record to be processed - */ - public void processRecordInternally(Record record) { - if(record instanceof BoundSheetRecord) { - boundSheetRecords.add((BoundSheetRecord)record); - } - else if(record instanceof ExternSheetRecord) { - externSheetRecords.add((ExternSheetRecord)record); - } - else if(record instanceof SSTRecord) { - sstRecord = (SSTRecord)record; - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java deleted file mode 100644 index 4a786962c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java +++ /dev/null @@ -1,201 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.eventusermodel; - -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.FormatRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.usermodel.HSSFDataFormat; -import org.apache.poi.hssf.usermodel.HSSFDataFormatter; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * A proxy HSSFListener that keeps track of the document formatting records, and - * provides an easy way to look up the format strings used by cells from their - * ids. - */ -public class FormatTrackingHSSFListener implements HSSFListener { - private static POILogger logger = POILogFactory.getLogger(FormatTrackingHSSFListener.class); - private final HSSFListener _childListener; - private final HSSFDataFormatter _formatter; - private final NumberFormat _defaultFormat; - private final Map _customFormatRecords = new HashMap(); - private final List _xfRecords = new ArrayList(); - - /** - * Creates a format tracking wrapper around the given listener, using - * the {@link Locale#getDefault() default locale} for the formats. - * - * @param childListener the listener to be wrapped - */ - public FormatTrackingHSSFListener(HSSFListener childListener) { - this(childListener, LocaleUtil.getUserLocale()); - } - - /** - * Creates a format tracking wrapper around the given listener, using - * the given locale for the formats. - * - * @param childListener the listener to be wrapped - * @param locale the locale for the formats - */ - public FormatTrackingHSSFListener( - HSSFListener childListener, Locale locale) { - _childListener = childListener; - _formatter = new HSSFDataFormatter(locale); - _defaultFormat = NumberFormat.getInstance(locale); - } - - protected int getNumberOfCustomFormats() { - return _customFormatRecords.size(); - } - - protected int getNumberOfExtendedFormats() { - return _xfRecords.size(); - } - - /** - * Process this record ourselves, and then pass it on to our child listener - */ - @Override - public void processRecord(Record record) { - // Handle it ourselves - processRecordInternally(record); - - // Now pass on to our child - _childListener.processRecord(record); - } - - /** - * Process the record ourselves, but do not pass it on to the child - * Listener. - * - * @param record the record to be processed - */ - public void processRecordInternally(Record record) { - if (record instanceof FormatRecord) { - FormatRecord fr = (FormatRecord) record; - _customFormatRecords.put(Integer.valueOf(fr.getIndexCode()), fr); - } - if (record instanceof ExtendedFormatRecord) { - ExtendedFormatRecord xr = (ExtendedFormatRecord) record; - _xfRecords.add(xr); - } - } - - /** - * Formats the given numeric of date cells contents as a String, in as - * close as we can to the way that Excel would do so. Uses the various - * format records to manage this. - * - * TODO - move this to a central class in such a way that hssf.usermodel can - * make use of it too - * - * @param cell the cell - * - * @return the given numeric of date cells contents as a String - */ - public String formatNumberDateCell(CellValueRecordInterface cell) { - double value; - if (cell instanceof NumberRecord) { - value = ((NumberRecord) cell).getValue(); - } else if (cell instanceof FormulaRecord) { - value = ((FormulaRecord) cell).getValue(); - } else { - throw new IllegalArgumentException("Unsupported CellValue Record passed in " + cell); - } - - // Get the built in format, if there is one - int formatIndex = getFormatIndex(cell); - String formatString = getFormatString(cell); - - if (formatString == null) { - return _defaultFormat.format(value); - } - // Format, using the nice new - // HSSFDataFormatter to do the work for us - return _formatter.formatRawCellContents(value, formatIndex, formatString); - } - - /** - * Returns the format string, eg $##.##, for the given number format index. - * - * @param formatIndex the format index - * - * @return the format string - */ - public String getFormatString(int formatIndex) { - String format = null; - if (formatIndex >= HSSFDataFormat.getNumberOfBuiltinBuiltinFormats()) { - FormatRecord tfr = _customFormatRecords.get(Integer.valueOf(formatIndex)); - if (tfr == null) { - logger.log( POILogger.ERROR, "Requested format at index " + formatIndex - + ", but it wasn't found"); - } else { - format = tfr.getFormatString(); - } - } else { - format = HSSFDataFormat.getBuiltinFormat((short) formatIndex); - } - return format; - } - - /** - * Returns the format string, eg $##.##, used by your cell - * - * @param cell the cell - * - * @return the format string - */ - public String getFormatString(CellValueRecordInterface cell) { - int formatIndex = getFormatIndex(cell); - if (formatIndex == -1) { - // Not found - return null; - } - return getFormatString(formatIndex); - } - - /** - * Returns the index of the format string, used by your cell, or -1 if none found - * - * @param cell the cell - * - * @return the index of the format string - */ - public int getFormatIndex(CellValueRecordInterface cell) { - ExtendedFormatRecord xfr = _xfRecords.get(cell.getXFIndex()); - if (xfr == null) { - logger.log( POILogger.ERROR, "Cell " + cell.getRow() + "," + cell.getColumn() - + " uses XF with index " + cell.getXFIndex() + ", but we don't have that"); - return -1; - } - return xfr.getFormatIndex(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java deleted file mode 100644 index 929ec6cd1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java +++ /dev/null @@ -1,188 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel; - -import java.io.InputStream; -import java.io.IOException; -import java.util.Set; - -import org.apache.poi.hssf.eventusermodel.HSSFUserException; -import org.apache.poi.hssf.record.*; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import static org.apache.poi.hssf.model.InternalWorkbook.WORKBOOK_DIR_ENTRY_NAMES; - -/** - * Low level event based HSSF reader. Pass either a DocumentInputStream to - * process events along with a request object or pass a POIFS POIFSFileSystem to - * processWorkbookEvents along with a request. - * - * This will cause your file to be processed a record at a time. Each record with - * a static id matching one that you have registered in your HSSFRequest will be passed - * to your associated HSSFListener. - */ -public class HSSFEventFactory { - /** Creates a new instance of HSSFEventFactory */ - public HSSFEventFactory() { - // no instance fields - } - - /** - * Processes a file into essentially record events. - * - * @param req an Instance of HSSFRequest which has your registered listeners - * @param fs a POIFS filesystem containing your workbook - * - * @throws IOException if the workbook contained errors - */ - public void processWorkbookEvents(HSSFRequest req, POIFSFileSystem fs) throws IOException { - processWorkbookEvents(req, fs.getRoot()); - } - - /** - * Processes a file into essentially record events. - * - * @param req an Instance of HSSFRequest which has your registered listeners - * @param dir a DirectoryNode containing your workbook - * - * @throws IOException if the workbook contained errors - */ - public void processWorkbookEvents(HSSFRequest req, DirectoryNode dir) throws IOException { - // some old documents have "WORKBOOK" or "BOOK" - String name = null; - Set entryNames = dir.getEntryNames(); - for (String potentialName : WORKBOOK_DIR_ENTRY_NAMES) { - if (entryNames.contains(potentialName)) { - name = potentialName; - break; - } - } - // If in doubt, go for the default - if (name == null) { - name = WORKBOOK_DIR_ENTRY_NAMES[0]; - } - - InputStream in = dir.createDocumentInputStream(name); - try { - processEvents(req, in); - } finally { - in.close(); - } - } - - /** - * Processes a file into essentially record events. - * - * @param req an Instance of HSSFRequest which has your registered listeners - * @param fs a POIFS filesystem containing your workbook - * @return numeric user-specified result code. - * - * @throws HSSFUserException if the processing should be aborted - * @throws IOException if the workbook contained errors - */ - public short abortableProcessWorkbookEvents(HSSFRequest req, POIFSFileSystem fs) - throws IOException, HSSFUserException { - return abortableProcessWorkbookEvents(req, fs.getRoot()); - } - - /** - * Processes a file into essentially record events. - * - * @param req an Instance of HSSFRequest which has your registered listeners - * @param dir a DirectoryNode containing your workbook - * @return numeric user-specified result code. - * - * @throws HSSFUserException if the processing should be aborted - * @throws IOException if the workbook contained errors - */ - public short abortableProcessWorkbookEvents(HSSFRequest req, DirectoryNode dir) - throws IOException, HSSFUserException { - InputStream in = dir.createDocumentInputStream("Workbook"); - try { - return abortableProcessEvents(req, in); - } finally { - in.close(); - } - } - - /** - * Processes a DocumentInputStream into essentially Record events. - * - * If an AbortableHSSFListener causes a halt to processing during this call - * the method will return just as with abortableProcessEvents, but no - * user code or HSSFUserException will be passed back. - * - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String) - * @param req an Instance of HSSFRequest which has your registered listeners - * @param in a DocumentInputStream obtained from POIFS's POIFSFileSystem object - */ - public void processEvents(HSSFRequest req, InputStream in) { - try { - genericProcessEvents(req, in); - } catch (HSSFUserException hue) { - /*If an HSSFUserException user exception is thrown, ignore it.*/ - } - } - - - /** - * Processes a DocumentInputStream into essentially Record events. - * - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String) - * @param req an Instance of HSSFRequest which has your registered listeners - * @param in a DocumentInputStream obtained from POIFS's POIFSFileSystem object - * @return numeric user-specified result code. - * - * @throws HSSFUserException if the processing should be aborted - */ - public short abortableProcessEvents(HSSFRequest req, InputStream in) - throws HSSFUserException { - return genericProcessEvents(req, in); - } - - /** - * Processes a DocumentInputStream into essentially Record events. - * - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String) - * @param req an Instance of HSSFRequest which has your registered listeners - * @param in a DocumentInputStream obtained from POIFS's POIFSFileSystem object - * @return numeric user-specified result code. - */ - private short genericProcessEvents(HSSFRequest req, InputStream in) - throws HSSFUserException { - short userCode = 0; - - // Create a new RecordStream and use that - RecordFactoryInputStream recordStream = new RecordFactoryInputStream(in, false); - - // Process each record as they come in - while(true) { - Record r = recordStream.nextRecord(); - if(r == null) { - break; - } - userCode = req.processRecord(r); - if (userCode != 0) { - break; - } - } - - // All done, return our last code - return userCode; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFListener.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFListener.java deleted file mode 100644 index 8932b10cd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFListener.java +++ /dev/null @@ -1,41 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel; - -import org.apache.poi.hssf.record.Record; - -/** - * Interface for use with the HSSFRequest and HSSFEventFactory. Users should create - * a listener supporting this interface and register it with the HSSFRequest (associating - * it with Record SID's). - * - * @see org.apache.poi.hssf.eventusermodel.HSSFEventFactory - * @see org.apache.poi.hssf.eventusermodel.HSSFRequest - */ - -public interface HSSFListener -{ - - /** - * process an HSSF Record. Called when a record occurs in an HSSF file. - * - * @param record the record to be processed - */ - public void processRecord(Record record); -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFRequest.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFRequest.java deleted file mode 100644 index 64c11aa65..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFRequest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel; - -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; - -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFactory; - -/** - * An HSSFRequest object should be constructed registering an instance or multiple - * instances of HSSFListener with each Record.sid you wish to listen for. - * - * @see org.apache.poi.hssf.eventusermodel.HSSFEventFactory - * @see org.apache.poi.hssf.eventusermodel.HSSFListener - * @see org.apache.poi.hssf.eventusermodel.HSSFUserException - */ -public class HSSFRequest { - private final Map> _records; - - /** Creates a new instance of HSSFRequest */ - public HSSFRequest() { - _records = new HashMap>(50); // most folks won't listen for too many of these - } - - /** - * add an event listener for a particular record type. The trick is you have to know - * what the records are for or just start with our examples and build on them. Alternatively, - * you CAN call addListenerForAllRecords and you'll receive ALL record events in one listener, - * but if you like to squeeze every last byte of efficiency out of life you my not like this. - * (its sure as heck what I plan to do) - * - * @see #addListenerForAllRecords(HSSFListener) - * - * @param lsnr for the event - * @param sid identifier for the record type this is the .sid static member on the individual records - * for example req.addListener(myListener, BOFRecord.sid) - */ - public void addListener(HSSFListener lsnr, short sid) { - List list = _records.get(Short.valueOf(sid)); - - if (list == null) { - list = new ArrayList(1); // probably most people will use one listener - _records.put(Short.valueOf(sid), list); - } - list.add(lsnr); - } - - /** - * This is the equivalent of calling addListener(myListener, sid) for EVERY - * record in the org.apache.poi.hssf.record package. This is for lazy - * people like me. You can call this more than once with more than one listener, but - * that seems like a bad thing to do from a practice-perspective unless you have a - * compelling reason to do so (like maybe you send the event two places or log it or - * something?). - * - * @param lsnr a single listener to associate with ALL records - */ - public void addListenerForAllRecords(HSSFListener lsnr) { - short[] rectypes = RecordFactory.getAllKnownRecordSIDs(); - - for (short rectype : rectypes) { - addListener(lsnr, rectype); - } - } - - /** - * Called by HSSFEventFactory, passes the Record to each listener associated with - * a record.sid. - * - * @param rec the record to be processed - * - * @return numeric user-specified result code. If zero continue processing. - * @throws HSSFUserException User exception condition - */ - protected short processRecord(Record rec) throws HSSFUserException { - List listeners = _records.get(Short.valueOf(rec.getSid())); - short userCode = 0; - - if (listeners != null) { - - for (int k = 0; k < listeners.size(); k++) { - Object listenObj = listeners.get(k); - if (listenObj instanceof AbortableHSSFListener) { - AbortableHSSFListener listener = (AbortableHSSFListener) listenObj; - userCode = listener.abortableProcessRecord(rec); - if (userCode != 0) - break; - } else { - HSSFListener listener = (HSSFListener) listenObj; - listener.processRecord(rec); - } - } - } - return userCode; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFUserException.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFUserException.java deleted file mode 100644 index a104c253c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/HSSFUserException.java +++ /dev/null @@ -1,107 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.eventusermodel; - -/** - *

    This exception is provided as a way for API users to throw - * exceptions from their event handling code. By doing so they - * abort file processing by the HSSFEventFactory and by - * catching it from outside the HSSFEventFactory.processEvents - * method they can diagnose the cause for the abort.

    - * - *

    The HSSFUserException supports a nested "reason" - * throwable, i.e. an exception that caused this one to be thrown.

    - * - *

    The HSSF package does not itself throw any of these - * exceptions.

    - * - * @version HSSFUserException.java,v 1.0 - * @since 2002-04-19 - */ -public class HSSFUserException extends Exception -{ - - private Throwable reason; - - - - /** - *

    Creates a new {@link HSSFUserException}.

    - */ - public HSSFUserException() - { - super(); - } - - - - /** - *

    Creates a new {@link HSSFUserException} with a message - * string.

    - * - * @param msg the error message - */ - public HSSFUserException(final String msg) - { - super(msg); - } - - - - /** - *

    Creates a new {@link HSSFUserException} with a reason.

    - * - * @param reason the causing exception - */ - public HSSFUserException(final Throwable reason) - { - super(); - this.reason = reason; - } - - - - /** - *

    Creates a new {@link HSSFUserException} with a message string - * and a reason.

    - * - * @param msg the error message - * @param reason the causing exception - */ - public HSSFUserException(final String msg, final Throwable reason) - { - super(msg); - this.reason = reason; - } - - - - /** - *

    Returns the {@link Throwable} that caused this exception to - * be thrown or null if there was no such {@link - * Throwable}.

    - * - * @return the reason - */ - public Throwable getReason() - { - return reason; - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java deleted file mode 100644 index ea9b70d88..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java +++ /dev/null @@ -1,212 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel; - -import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.MulBlankRecord; -import org.apache.poi.hssf.record.MulRKRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFactory; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.StringRecord; - -/** - *

    A HSSFListener which tracks rows and columns, and will - * trigger your HSSFListener for all rows and cells, - * even the ones that aren't actually stored in the file.

    - *

    This allows your code to have a more "Excel" like - * view of the data in the file, and not have to worry - * (as much) about if a particular row/cell is in the - * file, or was skipped from being written as it was - * blank. - */ -public final class MissingRecordAwareHSSFListener implements HSSFListener { - private HSSFListener childListener; - - // Need to have different counters for cell rows and - // row rows, as you sometimes get a RowRecord in the - // middle of some cells, and that'd break everything - private int lastRowRow; - - private int lastCellRow; - private int lastCellColumn; - - /** - * Constructs a new MissingRecordAwareHSSFListener, which - * will fire processRecord on the supplied child - * HSSFListener for all Records, and missing records. - * @param listener The HSSFListener to pass records on to - */ - public MissingRecordAwareHSSFListener(HSSFListener listener) { - resetCounts(); - childListener = listener; - } - - public void processRecord(Record record) { - int thisRow; - int thisColumn; - CellValueRecordInterface[] expandedRecords = null; - - if (record instanceof CellValueRecordInterface) { - CellValueRecordInterface valueRec = (CellValueRecordInterface) record; - thisRow = valueRec.getRow(); - thisColumn = valueRec.getColumn(); - } else { - if (record instanceof StringRecord){ - //it contains only cashed result of the previous FormulaRecord evaluation - childListener.processRecord(record); - return; - } - thisRow = -1; - thisColumn = -1; - - switch (record.getSid()) { - // the BOFRecord can represent either the beginning of a sheet or - // the workbook - case BOFRecord.sid: - BOFRecord bof = (BOFRecord) record; - if (bof.getType() == BOFRecord.TYPE_WORKBOOK || - bof.getType() == BOFRecord.TYPE_WORKSHEET) { - // Reset the row and column counts - new workbook / worksheet - resetCounts(); - } - break; - case RowRecord.sid: - RowRecord rowrec = (RowRecord) record; - //System.out.println("Row " + rowrec.getRowNumber() + " found, first column at " - // + rowrec.getFirstCol() + " last column at " + rowrec.getLastCol()); - - // If there's a jump in rows, fire off missing row records - if (lastRowRow + 1 < rowrec.getRowNumber()) { - for (int i = (lastRowRow + 1); i < rowrec.getRowNumber(); i++) { - MissingRowDummyRecord dr = new MissingRowDummyRecord(i); - childListener.processRecord(dr); - } - } - - // Record this as the last row we saw - lastRowRow = rowrec.getRowNumber(); - lastCellColumn = -1; - break; - - case SharedFormulaRecord.sid: - // SharedFormulaRecord occurs after the first FormulaRecord of the cell range. - // There are probably (but not always) more cell records after this - // - so don't fire off the LastCellOfRowDummyRecord yet - childListener.processRecord(record); - return; - case MulBlankRecord.sid: - // These appear in the middle of the cell records, to - // specify that the next bunch are empty but styled - // Expand this out into multiple blank cells - MulBlankRecord mbr = (MulBlankRecord)record; - expandedRecords = RecordFactory.convertBlankRecords(mbr); - break; - case MulRKRecord.sid: - // This is multiple consecutive number cells in one record - // Exand this out into multiple regular number cells - MulRKRecord mrk = (MulRKRecord)record; - expandedRecords = RecordFactory.convertRKRecords(mrk); - break; - case NoteRecord.sid: - NoteRecord nrec = (NoteRecord) record; - thisRow = nrec.getRow(); - thisColumn = nrec.getColumn(); - break; - default: - break; - } - } - - // First part of expanded record handling - if(expandedRecords != null && expandedRecords.length > 0) { - thisRow = expandedRecords[0].getRow(); - thisColumn = expandedRecords[0].getColumn(); - } - - // If we're on cells, and this cell isn't in the same - // row as the last one, then fire the - // dummy end-of-row records - if(thisRow != lastCellRow && thisRow > 0) { - if (lastCellRow == -1) lastCellRow = 0; - for(int i=lastCellRow; i 0) { - thisColumn = expandedRecords[expandedRecords.length-1].getColumn(); - } - - - // Update cell and row counts as needed - if(thisColumn != -1) { - lastCellColumn = thisColumn; - lastCellRow = thisRow; - } - - // Pass along the record(s) - if(expandedRecords != null && expandedRecords.length > 0) { - for(CellValueRecordInterface r : expandedRecords) { - childListener.processRecord((Record)r); - } - } else { - childListener.processRecord(record); - } - } - - private void resetCounts() { - lastRowRow = -1; - lastCellRow = -1; - lastCellColumn = -1; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/DummyRecordBase.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/DummyRecordBase.java deleted file mode 100644 index ebb0c032e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/DummyRecordBase.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel.dummyrecord; - -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFormatException; - -/** - */ -abstract class DummyRecordBase extends Record { - - protected DummyRecordBase() { - // - } - - public final short getSid() { - return -1; - } - public int serialize(int offset, byte[] data) { - throw new RecordFormatException("Cannot serialize a dummy record"); - } - public final int getRecordSize() { - throw new RecordFormatException("Cannot serialize a dummy record"); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/LastCellOfRowDummyRecord.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/LastCellOfRowDummyRecord.java deleted file mode 100644 index bd4afe890..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/LastCellOfRowDummyRecord.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel.dummyrecord; - - -/** - * A dummy record to indicate that we've now had the last - * cell record for this row. - */ -public final class LastCellOfRowDummyRecord extends DummyRecordBase { - private final int row; - private final int lastColumnNumber; - - public LastCellOfRowDummyRecord(int row, int lastColumnNumber) { - this.row = row; - this.lastColumnNumber = lastColumnNumber; - } - - /** - * Returns the (0 based) number of the row we are - * currently working on. - * - * @return the (0 based) number of the row - */ - public int getRow() { - return row; - } - - /** - * Returns the (0 based) number of the last column - * seen for this row. You should have already been - * called with that record. - * This is -1 in the case of there being no columns - * for the row. - * - * @return the (0 based) number of the last column - */ - public int getLastColumnNumber() { - return lastColumnNumber; - } - - @Override - public String toString() { - return "End-of-Row for Row=" + row + " at Column=" + lastColumnNumber; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/MissingCellDummyRecord.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/MissingCellDummyRecord.java deleted file mode 100644 index 393e21f38..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/MissingCellDummyRecord.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel.dummyrecord; - - -/** - * A dummy record for when we're missing a cell in a row, - * but still want to trigger something - */ -public final class MissingCellDummyRecord extends DummyRecordBase { - private int row; - private int column; - - public MissingCellDummyRecord(int row, int column) { - this.row = row; - this.column = column; - } - public int getRow() { return row; } - public int getColumn() { return column; } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/MissingRowDummyRecord.java b/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/MissingRowDummyRecord.java deleted file mode 100644 index 4c128bd00..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/dummyrecord/MissingRowDummyRecord.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.eventusermodel.dummyrecord; - - -/** - * A dummy record for when we're missing a row, but still - * want to trigger something - */ -public final class MissingRowDummyRecord extends DummyRecordBase { - private int rowNumber; - - public MissingRowDummyRecord(int rowNumber) { - this.rowNumber = rowNumber; - } - public int getRowNumber() { - return rowNumber; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/eventusermodel/package.html b/trunk/src/java/org/apache/poi/hssf/eventusermodel/package.html deleted file mode 100644 index 0a3b111a4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/eventusermodel/package.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - -HSSF eventmodel Package provides an event-based API for reading HSSF files. - -

    Related Documentation

    -The event model can reald XLS files with a very small memory footprint. For -writing you still have to use the usermodel. The eventmodel is to the usermodel -what SAX is to DOM. - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.hssf.usermodel -@see org.apache.poi.hssf.record - - diff --git a/trunk/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java b/trunk/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java deleted file mode 100644 index 107602d1c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java +++ /dev/null @@ -1,266 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.extractor; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.POIDocument; -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; -import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; -import org.apache.poi.hssf.eventusermodel.HSSFListener; -import org.apache.poi.hssf.eventusermodel.HSSFRequest; -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * A text extractor for Excel files, that is based - * on the HSSF EventUserModel API. - * It will typically use less memory than - * {@link ExcelExtractor}, but may not provide - * the same richness of formatting. - * Returns the textual content of the file, suitable for - * indexing by something like Lucene, but not really - * intended for display to the user. - *

    - * To turn an excel file into a CSV or similar, then see - * the XLS2CSVmra example - *

    - * - * @see XLS2CSVmra - */ -public class EventBasedExcelExtractor extends POIOLE2TextExtractor implements org.apache.poi.ss.extractor.ExcelExtractor { - private DirectoryNode _dir; - boolean _includeSheetNames = true; - boolean _formulasNotResults = false; - - public EventBasedExcelExtractor( DirectoryNode dir ) - { - super( (POIDocument)null ); - _dir = dir; - } - - public EventBasedExcelExtractor(POIFSFileSystem fs) { - this(fs.getRoot()); - super.setFilesystem(fs); - } - - /** - * Would return the document information metadata for the document, - * if we supported it - */ - public DocumentSummaryInformation getDocSummaryInformation() { - throw new IllegalStateException("Metadata extraction not supported in streaming mode, please use ExcelExtractor"); - } - /** - * Would return the summary information metadata for the document, - * if we supported it - */ - public SummaryInformation getSummaryInformation() { - throw new IllegalStateException("Metadata extraction not supported in streaming mode, please use ExcelExtractor"); - } - - - /** - * Would control the inclusion of cell comments from the document, - * if we supported it - */ - public void setIncludeCellComments(boolean includeComments) { - throw new IllegalStateException("Comment extraction not supported in streaming mode, please use ExcelExtractor"); - } - - /** - * Would control the inclusion of headers and footers from the document, - * if we supported it - */ - public void setIncludeHeadersFooters(boolean includeHeadersFooters) { - throw new IllegalStateException("Header/Footer extraction not supported in streaming mode, please use ExcelExtractor"); - } - - - /** - * Should sheet names be included? Default is true - */ - public void setIncludeSheetNames(boolean includeSheetNames) { - _includeSheetNames = includeSheetNames; - } - /** - * Should we return the formula itself, and not - * the result it produces? Default is false - */ - public void setFormulasNotResults(boolean formulasNotResults) { - _formulasNotResults = formulasNotResults; - } - - - /** - * Retreives the text contents of the file - */ - public String getText() { - String text = null; - try { - TextListener tl = triggerExtraction(); - - text = tl._text.toString(); - if(! text.endsWith("\n")) { - text = text + "\n"; - } - } catch(IOException e) { - throw new RuntimeException(e); - } - - return text; - } - - private TextListener triggerExtraction() throws IOException { - TextListener tl = new TextListener(); - FormatTrackingHSSFListener ft = new FormatTrackingHSSFListener(tl); - tl._ft = ft; - - // Register and process - HSSFEventFactory factory = new HSSFEventFactory(); - HSSFRequest request = new HSSFRequest(); - request.addListenerForAllRecords(ft); - - factory.processWorkbookEvents(request, _dir); - - return tl; - } - - private class TextListener implements HSSFListener { - FormatTrackingHSSFListener _ft; - private SSTRecord sstRecord; - - private final List sheetNames; - final StringBuffer _text = new StringBuffer(); - private int sheetNum = -1; - private int rowNum; - - private boolean outputNextStringValue = false; - private int nextRow = -1; - - public TextListener() { - sheetNames = new ArrayList(); - } - public void processRecord(Record record) { - String thisText = null; - int thisRow = -1; - - switch(record.getSid()) { - case BoundSheetRecord.sid: - BoundSheetRecord sr = (BoundSheetRecord)record; - sheetNames.add(sr.getSheetname()); - break; - case BOFRecord.sid: - BOFRecord bof = (BOFRecord)record; - if(bof.getType() == BOFRecord.TYPE_WORKSHEET) { - sheetNum++; - rowNum = -1; - - if(_includeSheetNames) { - if(_text.length() > 0) _text.append("\n"); - _text.append(sheetNames.get(sheetNum)); - } - } - break; - case SSTRecord.sid: - sstRecord = (SSTRecord)record; - break; - - case FormulaRecord.sid: - FormulaRecord frec = (FormulaRecord) record; - thisRow = frec.getRow(); - - if(_formulasNotResults) { - thisText = HSSFFormulaParser.toFormulaString((HSSFWorkbook)null, frec.getParsedExpression()); - } else { - if(frec.hasCachedResultString()) { - // Formula result is a string - // This is stored in the next record - outputNextStringValue = true; - nextRow = frec.getRow(); - } else { - thisText = _ft.formatNumberDateCell(frec); - } - } - break; - case StringRecord.sid: - if(outputNextStringValue) { - // String for formula - StringRecord srec = (StringRecord)record; - thisText = srec.getString(); - thisRow = nextRow; - outputNextStringValue = false; - } - break; - case LabelRecord.sid: - LabelRecord lrec = (LabelRecord) record; - thisRow = lrec.getRow(); - thisText = lrec.getValue(); - break; - case LabelSSTRecord.sid: - LabelSSTRecord lsrec = (LabelSSTRecord) record; - thisRow = lsrec.getRow(); - if(sstRecord == null) { - throw new IllegalStateException("No SST record found"); - } - thisText = sstRecord.getString(lsrec.getSSTIndex()).toString(); - break; - case NoteRecord.sid: - NoteRecord nrec = (NoteRecord) record; - thisRow = nrec.getRow(); - // TODO: Find object to match nrec.getShapeId() - break; - case NumberRecord.sid: - NumberRecord numrec = (NumberRecord) record; - thisRow = numrec.getRow(); - thisText = _ft.formatNumberDateCell(numrec); - break; - default: - break; - } - - if(thisText != null) { - if(thisRow != rowNum) { - rowNum = thisRow; - if(_text.length() > 0) - _text.append("\n"); - } else { - _text.append("\t"); - } - _text.append(thisText); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/extractor/ExcelExtractor.java b/trunk/src/java/org/apache/poi/hssf/extractor/ExcelExtractor.java deleted file mode 100644 index c4eb04731..000000000 --- a/trunk/src/java/org/apache/poi/hssf/extractor/ExcelExtractor.java +++ /dev/null @@ -1,421 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.extractor; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Locale; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFComment; -import org.apache.poi.hssf.usermodel.HSSFDataFormatter; -import org.apache.poi.hssf.usermodel.HSSFRichTextString; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.usermodel.HeaderFooter; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; - -/** - * A text extractor for Excel files. - *

    - * Returns the textual content of the file, suitable for - * indexing by something like Lucene, but not really - * intended for display to the user. - *

    - *

    - * To turn an excel file into a CSV or similar, then see - * the XLS2CSVmra example - *

    - * - * @see XLS2CSVmra - */ -public class ExcelExtractor extends POIOLE2TextExtractor implements org.apache.poi.ss.extractor.ExcelExtractor { - private final HSSFWorkbook _wb; - private final HSSFDataFormatter _formatter; - private boolean _includeSheetNames = true; - private boolean _shouldEvaluateFormulas = true; - private boolean _includeCellComments = false; - private boolean _includeBlankCells = false; - private boolean _includeHeadersFooters = true; - - public ExcelExtractor(HSSFWorkbook wb) { - super(wb); - _wb = wb; - _formatter = new HSSFDataFormatter(); - } - public ExcelExtractor(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public ExcelExtractor(DirectoryNode dir) throws IOException { - this(new HSSFWorkbook(dir, true)); - } - - private static final class CommandParseException extends Exception { - public CommandParseException(String msg) { - super(msg); - } - } - private static final class CommandArgs { - private final boolean _requestHelp; - private final File _inputFile; - private final boolean _showSheetNames; - private final boolean _evaluateFormulas; - private final boolean _showCellComments; - private final boolean _showBlankCells; - private final boolean _headersFooters; - public CommandArgs(String[] args) throws CommandParseException { - int nArgs = args.length; - File inputFile = null; - boolean requestHelp = false; - boolean showSheetNames = true; - boolean evaluateFormulas = true; - boolean showCellComments = false; - boolean showBlankCells = false; - boolean headersFooters = true; - for (int i=0; i= nArgs) { - throw new CommandParseException("Expected filename after '-i'"); - } - arg = args[i]; - if (inputFile != null) { - throw new CommandParseException("Only one input file can be supplied"); - } - inputFile = new File(arg); - if (!inputFile.exists()) { - throw new CommandParseException("Specified input file '" + arg + "' does not exist"); - } - if (inputFile.isDirectory()) { - throw new CommandParseException("Specified input file '" + arg + "' is a directory"); - } - continue; - } - if ("--show-sheet-names".equals(arg)) { - showSheetNames = parseBoolArg(args, ++i); - continue; - } - if ("--evaluate-formulas".equals(arg)) { - evaluateFormulas = parseBoolArg(args, ++i); - continue; - } - if ("--show-comments".equals(arg)) { - showCellComments = parseBoolArg(args, ++i); - continue; - } - if ("--show-blanks".equals(arg)) { - showBlankCells = parseBoolArg(args, ++i); - continue; - } - if ("--headers-footers".equals(arg)) { - headersFooters = parseBoolArg(args, ++i); - continue; - } - throw new CommandParseException("Invalid argument '" + arg + "'"); - } - _requestHelp = requestHelp; - _inputFile = inputFile; - _showSheetNames = showSheetNames; - _evaluateFormulas = evaluateFormulas; - _showCellComments = showCellComments; - _showBlankCells = showBlankCells; - _headersFooters = headersFooters; - } - private static boolean parseBoolArg(String[] args, int i) throws CommandParseException { - if (i >= args.length) { - throw new CommandParseException("Expected value after '" + args[i-1] + "'"); - } - String value = args[i].toUpperCase(Locale.ROOT); - if ("Y".equals(value) || "YES".equals(value) || "ON".equals(value) || "TRUE".equals(value)) { - return true; - } - if ("N".equals(value) || "NO".equals(value) || "OFF".equals(value) || "FALSE".equals(value)) { - return false; - } - throw new CommandParseException("Invalid value '" + args[i] + "' for '" + args[i-1] + "'. Expected 'Y' or 'N'"); - } - public boolean isRequestHelp() { - return _requestHelp; - } - public File getInputFile() { - return _inputFile; - } - public boolean shouldShowSheetNames() { - return _showSheetNames; - } - public boolean shouldEvaluateFormulas() { - return _evaluateFormulas; - } - public boolean shouldShowCellComments() { - return _showCellComments; - } - public boolean shouldShowBlankCells() { - return _showBlankCells; - } - public boolean shouldIncludeHeadersFooters() { - return _headersFooters; - } - } - - private static void printUsageMessage(PrintStream ps) { - ps.println("Use:"); - ps.println(" " + ExcelExtractor.class.getName() + " [ [ [...]]] [-i ]"); - ps.println(" -i specifies input file (default is to use stdin)"); - ps.println(" Flags can be set on or off by using the values 'Y' or 'N'."); - ps.println(" Following are available flags and their default values:"); - ps.println(" --show-sheet-names Y"); - ps.println(" --evaluate-formulas Y"); - ps.println(" --show-comments N"); - ps.println(" --show-blanks Y"); - ps.println(" --headers-footers Y"); - } - - /** - * Command line extractor. - * - * @param args the command line parameters - * - * @throws IOException if the file can't be read or contains errors - */ - public static void main(String[] args) throws IOException { - - CommandArgs cmdArgs; - try { - cmdArgs = new CommandArgs(args); - } catch (CommandParseException e) { - System.err.println(e.getMessage()); - printUsageMessage(System.err); - System.exit(1); - return; // suppress compiler error - } - - if (cmdArgs.isRequestHelp()) { - printUsageMessage(System.out); - return; - } - - InputStream is; - if(cmdArgs.getInputFile() == null) { - is = System.in; - } else { - is = new FileInputStream(cmdArgs.getInputFile()); - } - HSSFWorkbook wb = new HSSFWorkbook(is); - is.close(); - - ExcelExtractor extractor = new ExcelExtractor(wb); - extractor.setIncludeSheetNames(cmdArgs.shouldShowSheetNames()); - extractor.setFormulasNotResults(!cmdArgs.shouldEvaluateFormulas()); - extractor.setIncludeCellComments(cmdArgs.shouldShowCellComments()); - extractor.setIncludeBlankCells(cmdArgs.shouldShowBlankCells()); - extractor.setIncludeHeadersFooters(cmdArgs.shouldIncludeHeadersFooters()); - System.out.println(extractor.getText()); - extractor.close(); - wb.close(); - } - - @Override - public void setIncludeSheetNames(boolean includeSheetNames) { - _includeSheetNames = includeSheetNames; - } - - @Override - public void setFormulasNotResults(boolean formulasNotResults) { - _shouldEvaluateFormulas = !formulasNotResults; - } - - @Override - public void setIncludeCellComments(boolean includeCellComments) { - _includeCellComments = includeCellComments; - } - - /** - * Should blank cells be output? Default is to only - * output cells that are present in the file and are - * non-blank. - * - * @param includeBlankCells {@code true} if blank cells should be included - */ - public void setIncludeBlankCells(boolean includeBlankCells) { - _includeBlankCells = includeBlankCells; - } - - @Override - public void setIncludeHeadersFooters(boolean includeHeadersFooters) { - _includeHeadersFooters = includeHeadersFooters; - } - - @Override - public String getText() { - StringBuffer text = new StringBuffer(); - - // We don't care about the difference between - // null (missing) and blank cells - _wb.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL); - - // Process each sheet in turn - for(int i=0;i<_wb.getNumberOfSheets();i++) { - HSSFSheet sheet = _wb.getSheetAt(i); - if(sheet == null) { continue; } - - if(_includeSheetNames) { - String name = _wb.getSheetName(i); - if(name != null) { - text.append(name); - text.append("\n"); - } - } - - // Header text, if there is any - if(_includeHeadersFooters) { - text.append(_extractHeaderFooter(sheet.getHeader())); - } - - int firstRow = sheet.getFirstRowNum(); - int lastRow = sheet.getLastRowNum(); - for(int j=firstRow;j<=lastRow;j++) { - HSSFRow row = sheet.getRow(j); - if(row == null) { continue; } - - // Check each cell in turn - int firstCell = row.getFirstCellNum(); - int lastCell = row.getLastCellNum(); - if(_includeBlankCells) { - firstCell = 0; - } - - for(int k=firstCell;k 0) { - text.append(str.toString()); - } - break; - case NUMERIC: - HSSFCellStyle style = cell.getCellStyle(); - double nVal = cell.getNumericCellValue(); - short df = style.getDataFormat(); - String dfs = style.getDataFormatString(); - text.append(_formatter.formatRawCellContents(nVal, df, dfs)); - break; - case BOOLEAN: - text.append(cell.getBooleanCellValue()); - break; - case ERROR: - text.append(ErrorEval.getText(cell.getErrorCellValue())); - break; - default: - throw new IllegalStateException("Unexpected cell cached formula result type: " + cell.getCachedFormulaResultTypeEnum()); - - } - } - break; - default: - throw new RuntimeException("Unexpected cell type (" + cell.getCellTypeEnum() + ")"); - } - - // Output the comment, if requested and exists - HSSFComment comment = cell.getCellComment(); - if(_includeCellComments && comment != null) { - // Replace any newlines with spaces, otherwise it - // breaks the output - String commentText = comment.getString().getString().replace('\n', ' '); - text.append(" Comment by "+comment.getAuthor()+": "+commentText); - } - } - - // Output a tab if we're not on the last cell - if(outputContents && k < (lastCell-1)) { - text.append("\t"); - } - } - - // Finish off the row - text.append("\n"); - } - - // Finally Footer text, if there is any - if(_includeHeadersFooters) { - text.append(_extractHeaderFooter(sheet.getFooter())); - } - } - - return text.toString(); - } - - public static String _extractHeaderFooter(HeaderFooter hf) { - StringBuffer text = new StringBuffer(); - - if(hf.getLeft() != null) { - text.append(hf.getLeft()); - } - if(hf.getCenter() != null) { - if(text.length() > 0) - text.append("\t"); - text.append(hf.getCenter()); - } - if(hf.getRight() != null) { - if(text.length() > 0) - text.append("\t"); - text.append(hf.getRight()); - } - if(text.length() > 0) - text.append("\n"); - - return text.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java b/trunk/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java deleted file mode 100644 index c62a3c226..000000000 --- a/trunk/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java +++ /dev/null @@ -1,319 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.extractor; - -import static org.apache.poi.hssf.model.InternalWorkbook.OLD_WORKBOOK_DIR_ENTRY_NAME; -import static org.apache.poi.hssf.model.InternalWorkbook.WORKBOOK_DIR_ENTRY_NAMES; - -import java.io.BufferedInputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.CodepageRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.OldFormulaRecord; -import org.apache.poi.hssf.record.OldLabelRecord; -import org.apache.poi.hssf.record.OldSheetRecord; -import org.apache.poi.hssf.record.OldStringRecord; -import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.NotOLE2FileException; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.util.IOUtils; - -/** - * A text extractor for old Excel files, which are too old for - * HSSFWorkbook to handle. This includes Excel 95, and very old - * (pre-OLE2) Excel files, such as Excel 4 files. - *

    - * Returns much (but not all) of the textual content of the file, - * suitable for indexing by something like Apache Lucene, or used - * by Apache Tika, but not really intended for display to the user. - *

    - */ -public class OldExcelExtractor implements Closeable { - - private final static int FILE_PASS_RECORD_SID = 0x2f; - - private RecordInputStream ris; - - // sometimes we hold the stream here and thus need to ensure it is closed at some point - private Closeable toClose; - - private int biffVersion; - private int fileType; - - public OldExcelExtractor(InputStream input) throws IOException { - open(input); - } - - public OldExcelExtractor(File f) throws IOException { - NPOIFSFileSystem poifs = null; - try { - poifs = new NPOIFSFileSystem(f); - open(poifs); - toClose = poifs; - return; - } catch (OldExcelFormatException e) { - // will be handled by workaround below - if (poifs != null) { - poifs.close(); - } - } catch (NotOLE2FileException e) { - // will be handled by workaround below - if (poifs != null) { - poifs.close(); - } - } - - @SuppressWarnings("resource") - FileInputStream biffStream = new FileInputStream(f); // NOSONAR - try { - open(biffStream); - } catch (IOException e) { - // ensure that the stream is properly closed here if an Exception - // is thrown while opening - biffStream.close(); - throw e; - } catch (RuntimeException e) { - // ensure that the stream is properly closed here if an Exception - // is thrown while opening - biffStream.close(); - throw e; - } - } - - public OldExcelExtractor(NPOIFSFileSystem fs) throws IOException { - open(fs); - } - - public OldExcelExtractor(DirectoryNode directory) throws IOException { - open(directory); - } - - private void open(InputStream biffStream) throws IOException { - BufferedInputStream bis = (biffStream instanceof BufferedInputStream) - ? (BufferedInputStream)biffStream - : new BufferedInputStream(biffStream, 8); - - if (NPOIFSFileSystem.hasPOIFSHeader(bis)) { - NPOIFSFileSystem poifs = new NPOIFSFileSystem(bis); - try { - open(poifs); - } finally { - poifs.close(); - } - } else { - ris = new RecordInputStream(bis); - toClose = bis; - prepare(); - } - } - - private void open(NPOIFSFileSystem fs) throws IOException { - open(fs.getRoot()); - } - - private void open(DirectoryNode directory) throws IOException { - DocumentNode book; - try { - book = (DocumentNode)directory.getEntry(OLD_WORKBOOK_DIR_ENTRY_NAME); - } catch (FileNotFoundException e) { - // some files have "Workbook" instead - book = (DocumentNode)directory.getEntry(WORKBOOK_DIR_ENTRY_NAMES[0]); - } - - if (book == null) { - throw new IOException("No Excel 5/95 Book stream found"); - } - - ris = new RecordInputStream(directory.createDocumentInputStream(book)); - prepare(); - } - - public static void main(String[] args) throws Exception { - if (args.length < 1) { - System.err.println("Use:"); - System.err.println(" OldExcelExtractor "); - System.exit(1); - } - OldExcelExtractor extractor = new OldExcelExtractor(new File(args[0])); - System.out.println(extractor.getText()); - extractor.close(); - } - - private void prepare() { - if (! ris.hasNextRecord()) - throw new IllegalArgumentException("File contains no records!"); - ris.nextRecord(); - - // Work out what version we're dealing with - int bofSid = ris.getSid(); - switch (bofSid) { - case BOFRecord.biff2_sid: - biffVersion = 2; - break; - case BOFRecord.biff3_sid: - biffVersion = 3; - break; - case BOFRecord.biff4_sid: - biffVersion = 4; - break; - case BOFRecord.biff5_sid: - biffVersion = 5; - break; - default: - throw new IllegalArgumentException("File does not begin with a BOF, found sid of " + bofSid); - } - - // Get the type - BOFRecord bof = new BOFRecord(ris); - fileType = bof.getType(); - } - - /** - * The Biff version, largely corresponding to the Excel version - * - * @return the Biff version - */ - public int getBiffVersion() { - return biffVersion; - } - - /** - * The kind of the file, one of {@link BOFRecord#TYPE_WORKSHEET}, - * {@link BOFRecord#TYPE_CHART}, {@link BOFRecord#TYPE_EXCEL_4_MACRO} - * or {@link BOFRecord#TYPE_WORKSPACE_FILE} - * - * @return the file type - */ - public int getFileType() { - return fileType; - } - - /** - * Retrieves the text contents of the file, as best we can - * for these old file formats - * - * @return the text contents of the file - */ - public String getText() { - StringBuffer text = new StringBuffer(); - - // To track formats and encodings - CodepageRecord codepage = null; - // TODO track the XFs and Format Strings - - // Process each record in turn, looking for interesting ones - while (ris.hasNextRecord()) { - int sid = ris.getNextSid(); - ris.nextRecord(); - - switch (sid) { - case FILE_PASS_RECORD_SID: - throw new EncryptedDocumentException("Encryption not supported for Old Excel files"); - - case OldSheetRecord.sid: - OldSheetRecord shr = new OldSheetRecord(ris); - shr.setCodePage(codepage); - text.append("Sheet: "); - text.append(shr.getSheetname()); - text.append('\n'); - break; - - case OldLabelRecord.biff2_sid: - case OldLabelRecord.biff345_sid: - OldLabelRecord lr = new OldLabelRecord(ris); - lr.setCodePage(codepage); - text.append(lr.getValue()); - text.append('\n'); - break; - case OldStringRecord.biff2_sid: - case OldStringRecord.biff345_sid: - OldStringRecord sr = new OldStringRecord(ris); - sr.setCodePage(codepage); - text.append(sr.getString()); - text.append('\n'); - break; - - case NumberRecord.sid: - NumberRecord nr = new NumberRecord(ris); - handleNumericCell(text, nr.getValue()); - break; - case OldFormulaRecord.biff2_sid: - case OldFormulaRecord.biff3_sid: - case OldFormulaRecord.biff4_sid: - // Biff 2 and 5+ share the same SID, due to a bug... - if (biffVersion == 5) { - FormulaRecord fr = new FormulaRecord(ris); - if (fr.getCachedResultType() == CellType.NUMERIC.getCode()) { - handleNumericCell(text, fr.getValue()); - } - } else { - OldFormulaRecord fr = new OldFormulaRecord(ris); - if (fr.getCachedResultType() == CellType.NUMERIC.getCode()) { - handleNumericCell(text, fr.getValue()); - } - } - break; - case RKRecord.sid: - RKRecord rr = new RKRecord(ris); - handleNumericCell(text, rr.getRKNumber()); - break; - - case CodepageRecord.sid: - codepage = new CodepageRecord(ris); - break; - - default: - ris.readFully(new byte[ris.remaining()]); - } - } - - close(); - ris = null; - - return text.toString(); - } - - @Override - public void close() { - // some cases require this close here - if(toClose != null) { - IOUtils.closeQuietly(toClose); - toClose = null; - } - } - - protected void handleNumericCell(StringBuffer text, double value) { - // TODO Need to fetch / use format strings - text.append(value); - text.append('\n'); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/ConvertAnchor.java b/trunk/src/java/org/apache/poi/hssf/model/ConvertAnchor.java deleted file mode 100644 index 60808e797..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/ConvertAnchor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.hssf.usermodel.HSSFAnchor; -import org.apache.poi.hssf.usermodel.HSSFClientAnchor; -import org.apache.poi.hssf.usermodel.HSSFChildAnchor; - -/** - * - */ -public class ConvertAnchor -{ - public static EscherRecord createAnchor( HSSFAnchor userAnchor ) - { - if (userAnchor instanceof HSSFClientAnchor) - { - HSSFClientAnchor a = (HSSFClientAnchor) userAnchor; - - EscherClientAnchorRecord anchor = new EscherClientAnchorRecord(); - anchor.setRecordId( EscherClientAnchorRecord.RECORD_ID ); - anchor.setOptions( (short) 0x0000 ); - anchor.setFlag( a.getAnchorType().value ); - anchor.setCol1( (short) Math.min(a.getCol1(), a.getCol2()) ); - anchor.setDx1( (short) a.getDx1() ); - anchor.setRow1( (short) Math.min(a.getRow1(), a.getRow2()) ); - anchor.setDy1( (short) a.getDy1() ); - - anchor.setCol2( (short) Math.max(a.getCol1(), a.getCol2()) ); - anchor.setDx2( (short) a.getDx2() ); - anchor.setRow2( (short) Math.max(a.getRow1(), a.getRow2()) ); - anchor.setDy2( (short) a.getDy2() ); - return anchor; - } - HSSFChildAnchor a = (HSSFChildAnchor) userAnchor; - EscherChildAnchorRecord anchor = new EscherChildAnchorRecord(); - anchor.setRecordId( EscherChildAnchorRecord.RECORD_ID ); - anchor.setOptions( (short) 0x0000 ); - anchor.setDx1( (short) Math.min(a.getDx1(), a.getDx2()) ); - anchor.setDy1( (short) Math.min(a.getDy1(), a.getDy2()) ); - anchor.setDx2( (short) Math.max(a.getDx2(), a.getDx1()) ); - anchor.setDy2( (short) Math.max(a.getDy2(), a.getDy1()) ); - return anchor; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/DrawingManager.java b/trunk/src/java/org/apache/poi/hssf/model/DrawingManager.java deleted file mode 100644 index 468f6b4f5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/DrawingManager.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import org.apache.poi.ddf.EscherDggRecord; -import org.apache.poi.ddf.EscherDgRecord; - -import java.util.Map; -import java.util.HashMap; - -/** - * Provides utilities to manage drawing groups. - * - * @deprecated in POI 3.15-beta2, scheduled for removal in 3.17, use DrawingManager2 instead - */ -@Deprecated -public class DrawingManager -{ - EscherDggRecord dgg; - Map dgMap = new HashMap(); // key = Short(drawingId), value=EscherDgRecord - - public DrawingManager( EscherDggRecord dgg ) - { - this.dgg = dgg; - } - - public EscherDgRecord createDgRecord() - { - EscherDgRecord dg = new EscherDgRecord(); - dg.setRecordId( EscherDgRecord.RECORD_ID ); - short dgId = findNewDrawingGroupId(); - dg.setOptions( (short) ( dgId << 4 ) ); - dg.setNumShapes( 0 ); - dg.setLastMSOSPID( -1 ); - dgg.addCluster( dgId, 0 ); - dgg.setDrawingsSaved( dgg.getDrawingsSaved() + 1 ); - dgMap.put( dgId, dg ); - return dg; - } - - /** - * Allocates new shape id for the new drawing group id. - * - * @param drawingGroupId The drawing group id - * @return a new shape id. - */ - public int allocateShapeId(short drawingGroupId) - { - // Get the last shape id for this drawing group. - EscherDgRecord dg = dgMap.get(drawingGroupId); - int lastShapeId = dg.getLastMSOSPID(); - - - // Have we run out of shapes for this cluster? - int newShapeId = 0; - if (lastShapeId % 1024 == 1023) - { - // Yes: - // Find the starting shape id of the next free cluster - newShapeId = findFreeSPIDBlock(); - // Create a new cluster in the dgg record. - dgg.addCluster(drawingGroupId, 1); - } - else - { - // No: - // Find the cluster for this drawing group with free space. - for (int i = 0; i < dgg.getFileIdClusters().length; i++) - { - EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i]; - if (c.getDrawingGroupId() == drawingGroupId) - { - if (c.getNumShapeIdsUsed() != 1024) - { - // Increment the number of shapes used for this cluster. - c.incrementShapeId(); - } - } - // If the last shape id = -1 then we know to find a free block; - if (dg.getLastMSOSPID() == -1) - { - newShapeId = findFreeSPIDBlock(); - } - else - { - // The new shape id to be the last shapeid of this cluster + 1 - newShapeId = dg.getLastMSOSPID() + 1; - } - } - } - // Increment the total number of shapes used in the dgg. - dgg.setNumShapesSaved(dgg.getNumShapesSaved() + 1); - // Is the new shape id >= max shape id for dgg? - if (newShapeId >= dgg.getShapeIdMax()) - { - // Yes: - // Set the max shape id = new shape id + 1 - dgg.setShapeIdMax(newShapeId + 1); - } - // Set last shape id for this drawing group. - dg.setLastMSOSPID(newShapeId); - // Increased the number of shapes used for this drawing group. - dg.incrementShapeCount(); - - - return newShapeId; - } - - //////////// Non-public methods ///////////// - short findNewDrawingGroupId() - { - short dgId = 1; - while ( drawingGroupExists( dgId ) ) - dgId++; - return dgId; - } - - boolean drawingGroupExists( short dgId ) - { - for ( int i = 0; i < dgg.getFileIdClusters().length; i++ ) - { - if ( dgg.getFileIdClusters()[i].getDrawingGroupId() == dgId ) - return true; - } - return false; - } - - int findFreeSPIDBlock() - { - int max = dgg.getShapeIdMax(); - int next = ( ( max / 1024 ) + 1 ) * 1024; - return next; - } - - public EscherDggRecord getDgg() - { - return dgg; - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/DrawingManager2.java b/trunk/src/java/org/apache/poi/hssf/model/DrawingManager2.java deleted file mode 100644 index e5deeb02e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/DrawingManager2.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import org.apache.poi.ddf.EscherDgRecord; -import org.apache.poi.ddf.EscherDggRecord; - -import java.util.List; -import java.util.ArrayList; - - -/** - * Provides utilities to manage drawing groups. - */ -public class DrawingManager2 -{ - EscherDggRecord dgg; - List drawingGroups = new ArrayList(); - - - public DrawingManager2( EscherDggRecord dgg ) - { - this.dgg = dgg; - } - - /** - * Clears the cached list of drawing groups - */ - public void clearDrawingGroups() { - drawingGroups.clear(); - } - - /** - * Creates a new drawing group - * - * @return a new drawing group - */ - public EscherDgRecord createDgRecord() - { - EscherDgRecord dg = new EscherDgRecord(); - dg.setRecordId( EscherDgRecord.RECORD_ID ); - short dgId = findNewDrawingGroupId(); - dg.setOptions( (short) ( dgId << 4 ) ); - dg.setNumShapes( 0 ); - dg.setLastMSOSPID( -1 ); - drawingGroups.add(dg); - dgg.addCluster( dgId, 0 ); - dgg.setDrawingsSaved( dgg.getDrawingsSaved() + 1 ); - return dg; - } - - /** - * Allocates new shape id for the drawing group id. - * - * @param drawingGroupId the drawing group id - * - * @return a new shape id - */ - public int allocateShapeId(short drawingGroupId) - { - EscherDgRecord dg = getDrawingGroup(drawingGroupId); - return allocateShapeId(drawingGroupId, dg); - } - - /** - * Allocates new shape id for the drawing group - * - * @param drawingGroupId the drawing group id - * @param dg the EscherDgRecord which receives the new shape - * - * @return a new shape id. - */ - public int allocateShapeId(short drawingGroupId, EscherDgRecord dg) - { - dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 ); - - // Add to existing cluster if space available - for (int i = 0; i < dgg.getFileIdClusters().length; i++) - { - EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i]; - if (c.getDrawingGroupId() == drawingGroupId && c.getNumShapeIdsUsed() != 1024) - { - int result = c.getNumShapeIdsUsed() + (1024 * (i+1)); - c.incrementShapeId(); - dg.setNumShapes( dg.getNumShapes() + 1 ); - dg.setLastMSOSPID( result ); - if (result >= dgg.getShapeIdMax()) - dgg.setShapeIdMax( result + 1 ); - return result; - } - } - - // Create new cluster - dgg.addCluster( drawingGroupId, 0 ); - dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId(); - dg.setNumShapes( dg.getNumShapes() + 1 ); - int result = (1024 * dgg.getFileIdClusters().length); - dg.setLastMSOSPID( result ); - if (result >= dgg.getShapeIdMax()) - dgg.setShapeIdMax( result + 1 ); - return result; - } - //////////// Non-public methods ///////////// - - /** - * Finds the next available (1 based) drawing group id - * - * @return the next available drawing group id - */ - public short findNewDrawingGroupId() - { - short dgId = 1; - while ( drawingGroupExists( dgId ) ) - dgId++; - return dgId; - } - - EscherDgRecord getDrawingGroup(int drawingGroupId) - { - return drawingGroups.get(drawingGroupId-1); - } - - boolean drawingGroupExists( short dgId ) - { - for ( int i = 0; i < dgg.getFileIdClusters().length; i++ ) - { - if ( dgg.getFileIdClusters()[i].getDrawingGroupId() == dgId ) - return true; - } - return false; - } - - int findFreeSPIDBlock() - { - int max = dgg.getShapeIdMax(); - int next = ( ( max / 1024 ) + 1 ) * 1024; - return next; - } - - /** - * Returns the drawing group container record - * - * @return the drawing group container record - */ - public EscherDggRecord getDgg() - { - return dgg; - } - - /** - * Increment the drawing counter - */ - public void incrementDrawingsSaved(){ - dgg.setDrawingsSaved(dgg.getDrawingsSaved()+1); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java b/trunk/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java deleted file mode 100644 index 774eb788f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.FormulaParseException; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaParsingWorkbook; -import org.apache.poi.ss.formula.FormulaRenderer; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; - -/** - * HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer} - */ -@Internal -public final class HSSFFormulaParser { - - private static FormulaParsingWorkbook createParsingWorkbook(HSSFWorkbook book) { - return HSSFEvaluationWorkbook.create(book); - } - - private HSSFFormulaParser() { - // no instances of this class - } - - /** - * Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, FormulaType, int)} - * @param formula The formula to parse, excluding the leading equals sign - * @param workbook The parent workbook - * @return the parsed formula tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - public static Ptg[] parse(String formula, HSSFWorkbook workbook) throws FormulaParseException { - return parse(formula, workbook, FormulaType.CELL); - } - - /** - * @param formula The formula to parse, excluding the leading equals sign - * @param workbook The parent workbook - * @param formulaType a constant from {@link FormulaType} - * @return the parsed formula tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - * - * @deprecated POI 3.15 beta 3. Use {@link #parse(String, HSSFWorkbook, FormulaType)} instead. - */ - @Removal(version="3.17") - public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) throws FormulaParseException { - return parse(formula, workbook, FormulaType.forInt(formulaType)); - } - /** - * @param formula The formula to parse, excluding the leading equals sign - * @param workbook The parent workbook - * @param formulaType The type of formula - * @return The parsed formula tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - public static Ptg[] parse(String formula, HSSFWorkbook workbook, FormulaType formulaType) throws FormulaParseException { - return parse(formula, workbook, formulaType, -1); - } - - /** - * @param formula the formula to parse - * @param workbook the parent workbook - * @param formulaType a constant from {@link FormulaType} - * @param sheetIndex the 0-based index of the sheet this formula belongs to. - * The sheet index is required to resolve sheet-level names. -1 means that - * the scope of the name will be ignored and the parser will match named ranges only by name - * - * @return the parsed formula tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - * @deprecated POI 3.15 beta 3. Use {@link #parse(String, HSSFWorkbook, FormulaType, int)} instead. - */ - @Removal(version="3.17") - public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) throws FormulaParseException { - return parse(formula, workbook, FormulaType.forInt(formulaType), sheetIndex); - } - /** - * @param formula The formula to parse - * @param workbook The parent workbook - * @param formulaType The type of formula - * @param sheetIndex The 0-based index of the sheet this formula belongs to. - * The sheet index is required to resolve sheet-level names. -1 means that - * the scope of the name will be ignored and the parser will match named ranges only by name - * - * @return the parsed formula tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - public static Ptg[] parse(String formula, HSSFWorkbook workbook, FormulaType formulaType, int sheetIndex) throws FormulaParseException { - return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex); - } - - /** - * Static method to convert an array of {@link Ptg}s in RPN order - * to a human readable string format in infix mode. - * @param book used for defined names and 3D references - * @param ptgs must not be null - * @return a human readable String - */ - public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) { - return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java b/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java deleted file mode 100644 index ab07b7c7a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java +++ /dev/null @@ -1,1718 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.CFHeader12Record; -import org.apache.poi.hssf.record.CFHeaderRecord; -import org.apache.poi.hssf.record.CalcCountRecord; -import org.apache.poi.hssf.record.CalcModeRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.ColumnInfoRecord; -import org.apache.poi.hssf.record.DVALRecord; -import org.apache.poi.hssf.record.DefaultColWidthRecord; -import org.apache.poi.hssf.record.DefaultRowHeightRecord; -import org.apache.poi.hssf.record.DeltaRecord; -import org.apache.poi.hssf.record.DimensionsRecord; -import org.apache.poi.hssf.record.DrawingRecord; -import org.apache.poi.hssf.record.EOFRecord; -import org.apache.poi.hssf.record.EscherAggregate; -import org.apache.poi.hssf.record.FeatHdrRecord; -import org.apache.poi.hssf.record.FeatRecord; -import org.apache.poi.hssf.record.GridsetRecord; -import org.apache.poi.hssf.record.GutsRecord; -import org.apache.poi.hssf.record.IndexRecord; -import org.apache.poi.hssf.record.IterationRecord; -import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.PaneRecord; -import org.apache.poi.hssf.record.PrintGridlinesRecord; -import org.apache.poi.hssf.record.PrintHeadersRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.hssf.record.RefModeRecord; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.SCLRecord; -import org.apache.poi.hssf.record.SaveRecalcRecord; -import org.apache.poi.hssf.record.SelectionRecord; -import org.apache.poi.hssf.record.UncalcedRecord; -import org.apache.poi.hssf.record.WSBoolRecord; -import org.apache.poi.hssf.record.WindowTwoRecord; -import org.apache.poi.hssf.record.aggregates.ChartSubstreamRecordAggregate; -import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; -import org.apache.poi.hssf.record.aggregates.CustomViewSettingsRecordAggregate; -import org.apache.poi.hssf.record.aggregates.DataValidityTable; -import org.apache.poi.hssf.record.aggregates.MergedCellsTable; -import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; -import org.apache.poi.hssf.record.aggregates.RecordAggregate; -import org.apache.poi.hssf.record.aggregates.RecordAggregate.PositionTrackingVisitor; -import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; -import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.PaneInformation; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Low level model implementation of a Sheet (one workbook contains many sheets) - * This file contains the low level binary records starting at the sheets BOF and - * ending with the sheets EOF. Use HSSFSheet for a high level representation. - *

    - * The structures of the highlevel API use references to this to perform most of their - * operations. Its probably unwise to use these low level structures directly unless you - * really know what you're doing. I recommend you read the Microsoft Excel 97 Developer's - * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf - * before even attempting to use this. - * - * @see org.apache.poi.hssf.model.InternalWorkbook - * @see org.apache.poi.hssf.usermodel.HSSFSheet - */ -@Internal -public final class InternalSheet { - public static final short LeftMargin = 0; - public static final short RightMargin = 1; - public static final short TopMargin = 2; - public static final short BottomMargin = 3; - - private static POILogger log = POILogFactory.getLogger(InternalSheet.class); - - private List _records; - protected PrintGridlinesRecord printGridlines = null; - protected PrintHeadersRecord printHeaders = null; - protected GridsetRecord gridset = null; - private GutsRecord _gutsRecord; - protected DefaultColWidthRecord defaultcolwidth = new DefaultColWidthRecord(); - protected DefaultRowHeightRecord defaultrowheight = new DefaultRowHeightRecord(); - private PageSettingsBlock _psBlock; - - /** - * 'Worksheet Protection Block'
    - * Aggregate object is always present, but possibly empty. - */ - private final WorksheetProtectionBlock _protectionBlock = new WorksheetProtectionBlock(); - - protected WindowTwoRecord windowTwo = null; - protected SelectionRecord _selection = null; - /** java object always present, but if empty no BIFF records are written */ - private final MergedCellsTable _mergedCellsTable; - /** always present in this POI object, not always written to Excel file */ - /*package*/ColumnInfoRecordsAggregate _columnInfos; - /** the DimensionsRecord is always present */ - private DimensionsRecord _dimensions; - /** always present */ - protected final RowRecordsAggregate _rowsAggregate; - private DataValidityTable _dataValidityTable= null; - private ConditionalFormattingTable condFormatting; - - private Iterator rowRecIterator = null; - - /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ - protected boolean _isUncalced = false; - - public static final byte PANE_LOWER_RIGHT = (byte)0; - public static final byte PANE_UPPER_RIGHT = (byte)1; - public static final byte PANE_LOWER_LEFT = (byte)2; - public static final byte PANE_UPPER_LEFT = (byte)3; - - /** - * read support (offset used as starting point for search) for low level - * API. Pass in an array of Record objects, the sheet number (0 based) and - * a record offset (should be the location of the sheets BOF record). A Sheet - * object is constructed and passed back with all of its initialization set - * to the passed in records and references to those records held. This function - * is normally called via Workbook. - * - * @param rs the stream to read records from - * - * @return Sheet object with all values set to those read from the file - * - * @see org.apache.poi.hssf.model.InternalWorkbook - * @see org.apache.poi.hssf.record.Record - */ - public static InternalSheet createSheet(RecordStream rs) { - return new InternalSheet(rs); - } - private InternalSheet(RecordStream rs) { - _mergedCellsTable = new MergedCellsTable(); - RowRecordsAggregate rra = null; - - List records = new ArrayList(128); - _records = records; // needed here due to calls to findFirstRecordLocBySid before we're done - int dimsloc = -1; - - if (rs.peekNextSid() != BOFRecord.sid) { - throw new RecordFormatException("BOF record expected"); - } - - BOFRecord bof = (BOFRecord) rs.getNext(); - if (bof.getType() == BOFRecord.TYPE_WORKSHEET) { - // Good, well supported - } else if (bof.getType() == BOFRecord.TYPE_CHART || - bof.getType() == BOFRecord.TYPE_EXCEL_4_MACRO) { - // These aren't really typical sheets... Let it go though, - // we can handle them roughly well enough as a "normal" one - } else { - // Not a supported type - // Skip onto the EOF, then complain - while (rs.hasNext()) { - Record rec = rs.getNext(); - if (rec instanceof EOFRecord) { - break; - } - } - throw new UnsupportedBOFType(bof.getType()); - } - records.add(bof); - - while (rs.hasNext()) { - int recSid = rs.peekNextSid(); - - if ( recSid == CFHeaderRecord.sid || recSid == CFHeader12Record.sid ) { - condFormatting = new ConditionalFormattingTable(rs); - records.add(condFormatting); - continue; - } - - if (recSid == ColumnInfoRecord.sid) { - _columnInfos = new ColumnInfoRecordsAggregate(rs); - records.add(_columnInfos); - continue; - } - if ( recSid == DVALRecord.sid) { - _dataValidityTable = new DataValidityTable(rs); - records.add(_dataValidityTable); - continue; - } - - if (RecordOrderer.isRowBlockRecord(recSid)) { - //only add the aggregate once - if (rra != null) { - throw new RecordFormatException("row/cell records found in the wrong place"); - } - RowBlocksReader rbr = new RowBlocksReader(rs); - _mergedCellsTable.addRecords(rbr.getLooseMergedCells()); - rra = new RowRecordsAggregate(rbr.getPlainRecordStream(), rbr.getSharedFormulaManager()); - records.add(rra); //only add the aggregate once - continue; - } - - if (CustomViewSettingsRecordAggregate.isBeginRecord(recSid)) { - // This happens three times in test sample file "29982.xls" - // Also several times in bugzilla samples 46840-23373 and 46840-23374 - records.add(new CustomViewSettingsRecordAggregate(rs)); - continue; - } - - if (PageSettingsBlock.isComponentRecord(recSid)) { - if (_psBlock == null) { - // first PSB record encountered - read all of them: - _psBlock = new PageSettingsBlock(rs); - records.add(_psBlock); - } else { - // one or more PSB records found after some intervening non-PSB records - _psBlock.addLateRecords(rs); - } - // YK: in some cases records can be moved to the preceding - // CustomViewSettingsRecordAggregate blocks - _psBlock.positionRecords(records); - continue; - } - - if (WorksheetProtectionBlock.isComponentRecord(recSid)) { - _protectionBlock.addRecords(rs); - continue; - } - - if (recSid == MergeCellsRecord.sid) { - // when the MergedCellsTable is found in the right place, we expect those records to be contiguous - _mergedCellsTable.read(rs); - continue; - } - - if (recSid == BOFRecord.sid) { - ChartSubstreamRecordAggregate chartAgg = new ChartSubstreamRecordAggregate(rs); -// if (false) { -// // TODO - would like to keep the chart aggregate packed, but one unit test needs attention -// records.add(chartAgg); -// } else { - spillAggregate(chartAgg, records); -// } - continue; - } - - Record rec = rs.getNext(); - if ( recSid == IndexRecord.sid ) { - // ignore INDEX record because it is only needed by Excel, - // and POI always re-calculates its contents - continue; - } - - - if (recSid == UncalcedRecord.sid) { - // don't add UncalcedRecord to the list - _isUncalced = true; // this flag is enough - continue; - } - - if (recSid == FeatRecord.sid || - recSid == FeatHdrRecord.sid) { - records.add(rec); - continue; - } - - if (recSid == EOFRecord.sid) { - records.add(rec); - break; - } - - if (recSid == DimensionsRecord.sid) - { - // Make a columns aggregate if one hasn't ready been created. - if (_columnInfos == null) - { - _columnInfos = new ColumnInfoRecordsAggregate(); - records.add(_columnInfos); - } - - _dimensions = ( DimensionsRecord ) rec; - dimsloc = records.size(); - } - else if (recSid == DefaultColWidthRecord.sid) - { - defaultcolwidth = ( DefaultColWidthRecord ) rec; - } - else if (recSid == DefaultRowHeightRecord.sid) - { - defaultrowheight = ( DefaultRowHeightRecord ) rec; - } - else if ( recSid == PrintGridlinesRecord.sid ) - { - printGridlines = (PrintGridlinesRecord) rec; - } - else if ( recSid == PrintHeadersRecord.sid ) - { - printHeaders = (PrintHeadersRecord) rec; - } - else if ( recSid == GridsetRecord.sid ) - { - gridset = (GridsetRecord) rec; - } - else if ( recSid == SelectionRecord.sid ) - { - _selection = (SelectionRecord) rec; - } - else if ( recSid == WindowTwoRecord.sid ) - { - windowTwo = (WindowTwoRecord) rec; - } - else if ( recSid == GutsRecord.sid ) - { - _gutsRecord = (GutsRecord) rec; - } - - records.add(rec); - } - if (windowTwo == null) { - throw new RecordFormatException("WINDOW2 was not found"); - } - if (_dimensions == null) { - // Excel seems to always write the DIMENSION record, but tolerates when it is not present - // in all cases Excel (2007) adds the missing DIMENSION record - if (rra == null) { - // bug 46206 alludes to files which skip the DIMENSION record - // when there are no row/cell records. - // Not clear which application wrote these files. - rra = new RowRecordsAggregate(); - } else { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "DIMENSION record not found even though row/cells present"); - } - // Not sure if any tools write files like this, but Excel reads them OK - } - dimsloc = findFirstRecordLocBySid(WindowTwoRecord.sid); - _dimensions = rra.createDimensions(); - records.add(dimsloc, _dimensions); - } - if (rra == null) { - rra = new RowRecordsAggregate(); - records.add(dimsloc + 1, rra); - } - _rowsAggregate = rra; - // put merged cells table in the right place (regardless of where the first MergedCellsRecord was found */ - RecordOrderer.addNewSheetRecord(records, _mergedCellsTable); - RecordOrderer.addNewSheetRecord(records, _protectionBlock); - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited"); - } - private static void spillAggregate(RecordAggregate ra, final List recs) { - ra.visitContainedRecords(new RecordVisitor() { - public void visitRecord(Record r) { - recs.add(r); - }}); - } - - public static class UnsupportedBOFType extends RecordFormatException { - private final int type; - protected UnsupportedBOFType(int type) { - super("BOF not of a supported type, found " + type); - this.type = type; - } - - public int getType() { - return type; - } - } - - private static final class RecordCloner implements RecordVisitor { - - private final List _destList; - - public RecordCloner(List destList) { - _destList = destList; - } - public void visitRecord(Record r) { - try { - _destList.add((Record)r.clone()); - } catch (CloneNotSupportedException e) { - throw new RecordFormatException(e); - } - } - } - - /** - * Clones the low level records of this sheet and returns the new sheet instance. - * This method is implemented by adding methods for deep cloning to all records that - * can be added to a sheet. The Record object does not implement cloneable. - * When adding a new record, implement a public clone method if and only if the record - * belongs to a sheet. - * - * @return the cloned sheet - */ - public InternalSheet cloneSheet() { - List clonedRecords = new ArrayList(_records.size()); - for (int i = 0; i < _records.size(); i++) { - RecordBase rb = _records.get(i); - if (rb instanceof RecordAggregate) { - ((RecordAggregate) rb).visitContainedRecords(new RecordCloner(clonedRecords)); - continue; - } - if (rb instanceof EscherAggregate){ - /** - * this record will be removed after reading actual data from EscherAggregate - */ - rb = new DrawingRecord(); - } - try { - Record rec = (Record) ((Record) rb).clone(); - clonedRecords.add(rec); - } catch (CloneNotSupportedException e) { - throw new RecordFormatException(e); - } - } - return createSheet(new RecordStream(clonedRecords, 0)); - } - - /** - * Creates a sheet with all the usual records minus values and the "index" - * record (not required). Sets the location pointer to where the first value - * records should go. Use this to create a sheet from "scratch". - * - * @return Sheet object with all values set to defaults - */ - public static InternalSheet createSheet() { - return new InternalSheet(); - } - private InternalSheet() { - _mergedCellsTable = new MergedCellsTable(); - List records = new ArrayList(32); - - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "Sheet createsheet from scratch called"); - - records.add(createBOF()); - - records.add(createCalcMode()); - records.add(createCalcCount() ); - records.add(createRefMode() ); - records.add(createIteration() ); - records.add(createDelta() ); - records.add(createSaveRecalc() ); - printHeaders = createPrintHeaders(); - records.add(printHeaders); - printGridlines = createPrintGridlines(); - records.add( printGridlines ); - gridset = createGridset(); - records.add( gridset ); - _gutsRecord = createGuts(); - records.add( _gutsRecord ); - defaultrowheight = createDefaultRowHeight(); - records.add( defaultrowheight ); - records.add( createWSBool() ); - - // 'Page Settings Block' - _psBlock = new PageSettingsBlock(); - records.add(_psBlock); - - // 'Worksheet Protection Block' (after 'Page Settings Block' and before DEFCOLWIDTH) - records.add(_protectionBlock); // initially empty - - defaultcolwidth = createDefaultColWidth(); - records.add( defaultcolwidth); - ColumnInfoRecordsAggregate columns = new ColumnInfoRecordsAggregate(); - records.add( columns ); - _columnInfos = columns; - _dimensions = createDimensions(); - records.add(_dimensions); - _rowsAggregate = new RowRecordsAggregate(); - records.add(_rowsAggregate); - // 'Sheet View Settings' - records.add(windowTwo = createWindowTwo()); - _selection = createSelection(); - records.add(_selection); - - records.add(_mergedCellsTable); // MCT comes after 'Sheet View Settings' - records.add(EOFRecord.instance); - - _records = records; - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "Sheet createsheet from scratch exit"); - } - - public RowRecordsAggregate getRowsAggregate() { - return _rowsAggregate; - } - - private MergedCellsTable getMergedRecords() { - // always present - return _mergedCellsTable; - } - - /** - * Updates formulas in cells and conditional formats due to moving of cells - * - * @param shifter the formular shifter - * @param externSheetIndex the externSheet index of this sheet - */ - public void updateFormulasAfterCellShift(FormulaShifter shifter, int externSheetIndex) { - getRowsAggregate().updateFormulasAfterRowShift(shifter, externSheetIndex); - if (condFormatting != null) { - getConditionalFormattingTable().updateFormulasAfterCellShift(shifter, externSheetIndex); - } - // TODO - adjust data validations - } - - public int addMergedRegion(int rowFrom, int colFrom, int rowTo, int colTo) { - // Validate input - if (rowTo < rowFrom) { - throw new IllegalArgumentException("The 'to' row (" + rowTo - + ") must not be less than the 'from' row (" + rowFrom + ")"); - } - if (colTo < colFrom) { - throw new IllegalArgumentException("The 'to' col (" + colTo - + ") must not be less than the 'from' col (" + colFrom + ")"); - } - - MergedCellsTable mrt = getMergedRecords(); - mrt.addArea(rowFrom, colFrom, rowTo, colTo); - return mrt.getNumberOfMergedRegions()-1; - } - - public void removeMergedRegion(int index) { - //safety checks - MergedCellsTable mrt = getMergedRecords(); - if (index >= mrt.getNumberOfMergedRegions()) { - return; - } - mrt.remove(index); - } - - public CellRangeAddress getMergedRegionAt(int index) { - //safety checks - MergedCellsTable mrt = getMergedRecords(); - if (index >= mrt.getNumberOfMergedRegions()) { - return null; - } - return mrt.get(index); - } - - public int getNumMergedRegions() { - return getMergedRecords().getNumberOfMergedRegions(); - } - public ConditionalFormattingTable getConditionalFormattingTable() { - if (condFormatting == null) { - condFormatting = new ConditionalFormattingTable(); - RecordOrderer.addNewSheetRecord(_records, condFormatting); - } - return condFormatting; - } - - /** - * Per an earlier reported bug in working with Andy Khan's excel read library. This - * sets the values in the sheet's DimensionsRecord object to be correct. Excel doesn't - * really care, but we want to play nice with other libraries. - * - * @param firstrow the first row index - * @param firstcol the first column index - * @param lastrow the last row index - * @param lastcol the last column index - * - * @see org.apache.poi.hssf.record.DimensionsRecord - */ - public void setDimensions(int firstrow, short firstcol, int lastrow, short lastcol) - { - if (log.check( POILogger.DEBUG )) - { - log.log(POILogger.DEBUG, "Sheet.setDimensions"); - log.log(POILogger.DEBUG, - (new StringBuffer("firstrow")).append(firstrow) - .append("firstcol").append(firstcol).append("lastrow") - .append(lastrow).append("lastcol").append(lastcol) - .toString()); - } - _dimensions.setFirstCol(firstcol); - _dimensions.setFirstRow(firstrow); - _dimensions.setLastCol(lastcol); - _dimensions.setLastRow(lastrow); - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "Sheet.setDimensions exiting"); - } - - public void visitContainedRecords(RecordVisitor rv, int offset) { - - PositionTrackingVisitor ptv = new PositionTrackingVisitor(rv, offset); - - boolean haveSerializedIndex = false; - - for (int k = 0; k < _records.size(); k++) { - RecordBase record = _records.get(k); - - if (record instanceof RecordAggregate) { - RecordAggregate agg = (RecordAggregate) record; - agg.visitContainedRecords(ptv); - } else { - ptv.visitRecord((Record) record); - } - - // If the BOF record was just serialized then add the IndexRecord - if (record instanceof BOFRecord) { - if (!haveSerializedIndex) { - haveSerializedIndex = true; - // Add an optional UncalcedRecord. However, we should add - // it in only the once, after the sheet's own BOFRecord. - // If there are diagrams, they have their own BOFRecords, - // and one shouldn't go in after that! - if (_isUncalced) { - ptv.visitRecord(new UncalcedRecord()); - } - //Can there be more than one BOF for a sheet? If not then we can - //remove this guard. So be safe it is left here. - if (_rowsAggregate != null) { - // find forward distance to first RowRecord - int initRecsSize = getSizeOfInitialSheetRecords(k); - int currentPos = ptv.getPosition(); - ptv.visitRecord(_rowsAggregate.createIndexRecord(currentPos, initRecsSize)); - } - } - } - } - } - /** - * 'initial sheet records' are between INDEX and the 'Row Blocks' - * @param bofRecordIndex index of record after which INDEX record is to be placed - * @return count of bytes from end of INDEX record to first ROW record. - */ - private int getSizeOfInitialSheetRecords(int bofRecordIndex) { - - int result = 0; - // start just after BOF record (INDEX is not present in this list) - for (int j = bofRecordIndex + 1; j < _records.size(); j++) { - RecordBase tmpRec = _records.get(j); - if (tmpRec instanceof RowRecordsAggregate) { - break; - } - result += tmpRec.getRecordSize(); - } - if (_isUncalced) { - result += UncalcedRecord.getStaticRecordSize(); - } - return result; - } - - /** - * Adds a value record to the sheet's contained binary records - * (i.e. LabelSSTRecord or NumberRecord). - *

    - * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. - * - * @param row the row to add the cell value to - * @param col the cell value record itself. - */ - public void addValueRecord(int row, CellValueRecordInterface col) { - - if(log.check(POILogger.DEBUG)) { - log.log(POILogger.DEBUG, "add value record row" + row); - } - DimensionsRecord d = _dimensions; - - if (col.getColumn() >= d.getLastCol()) { - d.setLastCol(( short ) (col.getColumn() + 1)); - } - if (col.getColumn() < d.getFirstCol()) { - d.setFirstCol(col.getColumn()); - } - _rowsAggregate.insertCell(col); - } - - /** - * remove a value record from the records array. - * - * This method is not loc sensitive, it resets loc to = dimsloc so no worries. - * - * @param row - the row of the value record you wish to remove - * @param col - a record supporting the CellValueRecordInterface. - * @see org.apache.poi.hssf.record.CellValueRecordInterface - */ - public void removeValueRecord(int row, CellValueRecordInterface col) { - - log.log(POILogger.DEBUG, "remove value record row "+row); - _rowsAggregate.removeCell(col); - } - - /** - * replace a value record from the records array. - * - * This method is not loc sensitive, it resets loc to = dimsloc so no worries. - * - * @param newval - a record supporting the CellValueRecordInterface. this will replace - * the cell value with the same row and column. If there isn't one, one will - * be added. - */ - - public void replaceValueRecord(CellValueRecordInterface newval) { - - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "replaceValueRecord "); - //The ValueRecordsAggregate use a tree map underneath. - //The tree Map uses the CellValueRecordInterface as both the - //key and the value, if we dont do a remove, then - //the previous instance of the key is retained, effectively using - //double the memory - _rowsAggregate.removeCell(newval); - _rowsAggregate.insertCell(newval); - } - - /** - * Adds a row record to the sheet - * - *

    - * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. - * - * @param row the row record to be added - */ - - public void addRow(RowRecord row) { - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "addRow "); - DimensionsRecord d = _dimensions; - - if (row.getRowNumber() >= d.getLastRow()) { - d.setLastRow(row.getRowNumber() + 1); - } - if (row.getRowNumber() < d.getFirstRow()) { - d.setFirstRow(row.getRowNumber()); - } - - //If the row exists remove it, so that any cells attached to the row are removed - RowRecord existingRow = _rowsAggregate.getRow(row.getRowNumber()); - if (existingRow != null) { - _rowsAggregate.removeRow(existingRow); - } - - _rowsAggregate.insertRow(row); - - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "exit addRow"); - } - - /** - * Removes a row record - * - * This method is not loc sensitive, it resets loc to = dimsloc so no worries. - * - * @param row the row record to remove - */ - public void removeRow(RowRecord row) { - _rowsAggregate.removeRow(row); - } - - /** - * Get all the value records (from LOC). Records will be returned from the first - * record (starting at LOC) which is a value record. - * - *

    - * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. For this method, set loc to dimsloc to start with, - * subsequent calls will return values in (physical) sequence or NULL when you get to the end. - * - * @return Iterator of CellValueRecordInterface representing the value records - */ - public Iterator getCellValueIterator(){ - return _rowsAggregate.getCellValueIterator(); - } - - /** - * get the NEXT RowRecord (from LOC). The first record that is a Row record - * (starting at LOC) will be returned. - *

    - * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. For this method, set loc to dimsloc to start with. - * subsequent calls will return rows in (physical) sequence or NULL when you get to the end. - * - * @return RowRecord representing the next row record or NULL if there are no more - */ - public RowRecord getNextRow() { - if (rowRecIterator == null) - { - rowRecIterator = _rowsAggregate.getIterator(); - } - if (!rowRecIterator.hasNext()) - { - return null; - } - return rowRecIterator.next(); - } - - /** - * get the NEXT (from LOC) RowRecord where rownumber matches the given rownum. - * The first record that is a Row record (starting at LOC) that has the - * same rownum as the given rownum will be returned. - *

    - * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. For this method, set loc to dimsloc to start with. - * subsequent calls will return rows in (physical) sequence or NULL when you get to the end. - * - * @param rownum which row to return (careful with LOC) - * @return RowRecord representing the next row record or NULL if there are no more - * - */ - public RowRecord getRow(int rownum) { - return _rowsAggregate.getRow(rownum); - } - - /** - * creates the BOF record - */ - /* package */ static BOFRecord createBOF() { - BOFRecord retval = new BOFRecord(); - - retval.setVersion(( short ) 0x600); - retval.setType(( short ) 0x010); - - retval.setBuild(( short ) 0x0dbb); - retval.setBuildYear(( short ) 1996); - retval.setHistoryBitMask(0xc1); - retval.setRequiredVersion(0x6); - return retval; - } - - /** - * creates the CalcMode record and sets it to 1 (automatic formula caculation) - */ - private static CalcModeRecord createCalcMode() { - CalcModeRecord retval = new CalcModeRecord(); - - retval.setCalcMode(( short ) 1); - return retval; - } - - /** - * creates the CalcCount record and sets it to 100 (default number of iterations) - */ - private static CalcCountRecord createCalcCount() { - CalcCountRecord retval = new CalcCountRecord(); - - retval.setIterations(( short ) 100); // default 100 iterations - return retval; - } - - /** - * creates the RefMode record and sets it to A1 Mode (default reference mode) - */ - private static RefModeRecord createRefMode() { - RefModeRecord retval = new RefModeRecord(); - - retval.setMode(RefModeRecord.USE_A1_MODE); - return retval; - } - - /** - * creates the Iteration record and sets it to false (don't iteratively calculate formulas) - */ - private static IterationRecord createIteration() { - return new IterationRecord(false); - } - - /** - * creates the Delta record and sets it to 0.0010 (default accuracy) - */ - private static DeltaRecord createDelta() { - return new DeltaRecord(DeltaRecord.DEFAULT_VALUE); - } - - /** - * creates the SaveRecalc record and sets it to true (recalculate before saving) - */ - private static SaveRecalcRecord createSaveRecalc() { - SaveRecalcRecord retval = new SaveRecalcRecord(); - - retval.setRecalc(true); - return retval; - } - - /** - * creates the PrintHeaders record and sets it to false (we don't create headers yet so why print them) - */ - private static PrintHeadersRecord createPrintHeaders() { - PrintHeadersRecord retval = new PrintHeadersRecord(); - - retval.setPrintHeaders(false); - return retval; - } - - /** - * creates the PrintGridlines record and sets it to false (that makes for ugly sheets). As far as I can - * tell this does the same thing as the GridsetRecord - */ - private static PrintGridlinesRecord createPrintGridlines() { - PrintGridlinesRecord retval = new PrintGridlinesRecord(); - - retval.setPrintGridlines(false); - return retval; - } - - /** - * creates the Gridset record and sets it to true (user has mucked with the gridlines) - */ - private static GridsetRecord createGridset() { - GridsetRecord retval = new GridsetRecord(); - - retval.setGridset(true); - return retval; - } - - /** - * creates the Guts record and sets leftrow/topcol guttter and rowlevelmax/collevelmax to 0 - */ - private static GutsRecord createGuts() { - GutsRecord retval = new GutsRecord(); - - retval.setLeftRowGutter(( short ) 0); - retval.setTopColGutter(( short ) 0); - retval.setRowLevelMax(( short ) 0); - retval.setColLevelMax(( short ) 0); - return retval; - } - - private GutsRecord getGutsRecord() { - if (_gutsRecord == null) { - GutsRecord result = createGuts(); - RecordOrderer.addNewSheetRecord(_records, result); - _gutsRecord = result; - } - - return _gutsRecord; - } - - /** - * creates the DefaultRowHeight Record and sets its options to 0 and rowheight to 0xff - */ - private static DefaultRowHeightRecord createDefaultRowHeight() { - DefaultRowHeightRecord retval = new DefaultRowHeightRecord(); - - retval.setOptionFlags(( short ) 0); - retval.setRowHeight(DefaultRowHeightRecord.DEFAULT_ROW_HEIGHT); - return retval; - } - - /** - * creates the WSBoolRecord and sets its values to defaults - */ - private static WSBoolRecord createWSBool() { - WSBoolRecord retval = new WSBoolRecord(); - - retval.setWSBool1(( byte ) 0x4); - retval.setWSBool2(( byte ) 0xffffffc1); - return retval; - } - - - /** - * creates the DefaultColWidth Record and sets it to 8 - */ - private static DefaultColWidthRecord createDefaultColWidth() { - DefaultColWidthRecord retval = new DefaultColWidthRecord(); - retval.setColWidth(DefaultColWidthRecord.DEFAULT_COLUMN_WIDTH); - return retval; - } - - /** - * get the default column width for the sheet (if the columns do not define their own width) - * @return default column width - */ - public int getDefaultColumnWidth() { - return defaultcolwidth.getColWidth(); - } - - /** - * @return true if gridlines are printed - */ - public boolean isGridsPrinted() { - if (gridset == null) { - gridset = createGridset(); - //Insert the newlycreated Gridset record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - _records.add(loc, gridset); - } - return !gridset.getGridset(); - } - - /** - * set whether gridlines printed or not. - * @param value True if gridlines printed. - */ - public void setGridsPrinted(boolean value) { - gridset.setGridset(!value); - } - - /** - * set the default column width for the sheet (if the columns do not define their own width) - * @param dcw default column width - */ - public void setDefaultColumnWidth(int dcw) { - defaultcolwidth.setColWidth(dcw); - } - - /** - * set the default row height for the sheet (if the rows do not define their own height) - * - * @param dch the default row height - */ - public void setDefaultRowHeight(short dch) { - defaultrowheight.setRowHeight(dch); - // set the bit that specifies that the default settings for the row height have been changed. - defaultrowheight.setOptionFlags((short)1); - } - - /** - * get the default row height for the sheet (if the rows do not define their own height) - * @return default row height - */ - public short getDefaultRowHeight() { - return defaultrowheight.getRowHeight(); - } - - /** - * get the width of a given column in units of 1/256th of a character width - * @param columnIndex index - * @see org.apache.poi.hssf.record.DefaultColWidthRecord - * @see org.apache.poi.hssf.record.ColumnInfoRecord - * @see #setColumnWidth(int, int) - * @return column width in units of 1/256th of a character width - */ - public int getColumnWidth(int columnIndex) { - - ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex); - if (ci != null) { - return ci.getColumnWidth(); - } - //default column width is measured in characters - //multiply - return (256*defaultcolwidth.getColWidth()); - } - - /** - * get the index to the ExtendedFormatRecord "associated" with - * the column at specified 0-based index. (In this case, an - * ExtendedFormatRecord index is actually associated with a - * ColumnInfoRecord which spans 1 or more columns) - *

    - * Returns the index to the default ExtendedFormatRecord (0xF) - * if no ColumnInfoRecord exists that includes the column - * index specified. - * @param columnIndex the column index - * @return index of ExtendedFormatRecord associated with - * ColumnInfoRecord that includes the column index or the - * index of the default ExtendedFormatRecord (0xF) - */ - public short getXFIndexForColAt(short columnIndex) { - ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex); - if (ci != null) { - return (short)ci.getXFIndex(); - } - return 0xF; - } - - /** - * set the width for a given column in 1/256th of a character width units - * - * @param column - - * the column number - * @param width - * (in units of 1/256th of a character width) - */ - public void setColumnWidth(int column, int width) { - if(width > 255*256) throw new IllegalArgumentException("The maximum column width for an individual cell is 255 characters."); - - setColumn(column, null, Integer.valueOf(width), null, null, null); - } - - /** - * Get the hidden property for a given column. - * @param columnIndex column index - * @see org.apache.poi.hssf.record.DefaultColWidthRecord - * @see org.apache.poi.hssf.record.ColumnInfoRecord - * @see #setColumnHidden(int, boolean) - * @return whether the column is hidden or not. - */ - public boolean isColumnHidden(int columnIndex) { - ColumnInfoRecord cir = _columnInfos.findColumnInfo(columnIndex); - if (cir == null) { - return false; - } - return cir.getHidden(); - } - - /** - * Get the hidden property for a given column. - * @param column - the column number - * @param hidden - whether the column is hidden or not - */ - public void setColumnHidden(int column, boolean hidden) { - setColumn( column, null, null, null, Boolean.valueOf(hidden), null); - } - public void setDefaultColumnStyle(int column, int styleIndex) { - setColumn(column, Short.valueOf((short)styleIndex), null, null, null, null); - } - - private void setColumn(int column, Short xfStyle, Integer width, Integer level, Boolean hidden, Boolean collapsed) { - _columnInfos.setColumn( column, xfStyle, width, level, hidden, collapsed ); - } - - - /** - * Creates an outline group for the specified columns. - * @param fromColumn group from this column (inclusive) - * @param toColumn group to this column (inclusive) - * @param indent if true the group will be indented by one level, - * if false indenting will be removed by one level. - */ - public void groupColumnRange(int fromColumn, int toColumn, boolean indent) { - - // Set the level for each column - _columnInfos.groupColumnRange( fromColumn, toColumn, indent); - - // Determine the maximum overall level - int maxLevel = _columnInfos.getMaxOutlineLevel(); - - GutsRecord guts = getGutsRecord(); - guts.setColLevelMax( (short) ( maxLevel+1 ) ); - if (maxLevel == 0) { - guts.setTopColGutter( (short)0 ); - } else { - guts.setTopColGutter( (short) ( 29 + (12 * (maxLevel-1)) ) ); - } - } - - /** - * creates the Dimensions Record and sets it to bogus values (you should set this yourself - * or let the high level API do it for you) - */ - private static DimensionsRecord createDimensions() { - DimensionsRecord retval = new DimensionsRecord(); - - retval.setFirstCol(( short ) 0); - retval.setLastRow(1); // one more than it is - retval.setFirstRow(0); - retval.setLastCol(( short ) 1); // one more than it is - return retval; - } - - /** - * creates the WindowTwo Record and sets it to:

    - * options = 0x6b6

    - * toprow = 0

    - * leftcol = 0

    - * headercolor = 0x40

    - * pagebreakzoom = 0x0

    - * normalzoom = 0x0

    - */ - private static WindowTwoRecord createWindowTwo() { - WindowTwoRecord retval = new WindowTwoRecord(); - - retval.setOptions(( short ) 0x6b6); - retval.setTopRow(( short ) 0); - retval.setLeftCol(( short ) 0); - retval.setHeaderColor(0x40); - retval.setPageBreakZoom(( short ) 0); - retval.setNormalZoom(( short ) 0); - return retval; - } - - /** - * Creates the Selection record and sets it to nothing selected - */ - private static SelectionRecord createSelection() { - return new SelectionRecord(0, 0); - } - - public short getTopRow() { - return (windowTwo==null) ? (short) 0 : windowTwo.getTopRow(); - } - - public void setTopRow(short topRow) { - if (windowTwo!=null) { - windowTwo.setTopRow(topRow); - } - } - - /** - * Sets the left column to show in desktop window pane. - * @param leftCol the left column to show in desktop window pane - */ - public void setLeftCol(short leftCol) { - if (windowTwo!=null) { - windowTwo.setLeftCol(leftCol); - } - } - - public short getLeftCol() { - return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol(); - } - - /** - * Returns the active row - * - * @see org.apache.poi.hssf.record.SelectionRecord - * @return row the active row index - */ - public int getActiveCellRow() { - if (_selection == null) { - return 0; - } - return _selection.getActiveCellRow(); - } - - /** - * Sets the active row - * - * @param row the row index - * @see org.apache.poi.hssf.record.SelectionRecord - */ - public void setActiveCellRow(int row) { - //shouldn't have a sheet w/o a SelectionRecord, but best to guard anyway - if (_selection != null) { - _selection.setActiveCellRow(row); - } - } - - /** - * @see org.apache.poi.hssf.record.SelectionRecord - * @return column of the active cell - */ - public short getActiveCellCol() { - if (_selection == null) { - return 0; - } - return (short)_selection.getActiveCellCol(); - } - - /** - * Sets the active column - * - * @param col the column index - * @see org.apache.poi.hssf.record.SelectionRecord - */ - public void setActiveCellCol(short col) { - //shouldn't have a sheet w/o a SelectionRecord, but best to guard anyway - if (_selection != null) - { - _selection.setActiveCellCol(col); - } - } - - public List getRecords() { - return _records; - } - - /** - * Gets the gridset record for this sheet. - * - * @return the gridset record for this sheet - */ - public GridsetRecord getGridsetRecord() - { - return gridset; - } - - /** - * Returns the first occurrence of a record matching a particular sid. - * - * @param sid the sid to search for - * - * @return the matching record or {@code null} if it wasn't found - */ - public Record findFirstRecordBySid(short sid) { - int ix = findFirstRecordLocBySid(sid); - if (ix < 0) { - return null; - } - return (Record) _records.get(ix); - } - - /** - * Sets the SCL record or creates it in the correct place if it does not - * already exist. - * - * @param sclRecord The record to set. - */ - public void setSCLRecord(SCLRecord sclRecord) { - int oldRecordLoc = findFirstRecordLocBySid(SCLRecord.sid); - if (oldRecordLoc == -1) { - // Insert it after the window record - int windowRecordLoc = findFirstRecordLocBySid(WindowTwoRecord.sid); - _records.add(windowRecordLoc+1, sclRecord); - } else { - _records.set(oldRecordLoc, sclRecord); - } - } - - /** - * Finds the first occurrence of a record matching a particular sid and - * returns it's position. - * @param sid the sid to search for - * @return the record position of the matching record or -1 if no match - * is made. - */ - public int findFirstRecordLocBySid( short sid ) { // TODO - remove this method - int max = _records.size(); - for (int i=0; i< max; i++) { - Object rb = _records.get(i); - if (!(rb instanceof Record)) { - continue; - } - Record record = (Record) rb; - if (record.getSid() == sid) { - return i; - } - } - return -1; - } - - public WindowTwoRecord getWindowTwo() { - return windowTwo; - } - - /** - * Returns the PrintGridlinesRecord. - * @return PrintGridlinesRecord for the sheet. - */ - public PrintGridlinesRecord getPrintGridlines () - { - return printGridlines; - } - - /** - * Sets the PrintGridlinesRecord. - * @param newPrintGridlines The new PrintGridlinesRecord for the sheet. - */ - public void setPrintGridlines (PrintGridlinesRecord newPrintGridlines) - { - printGridlines = newPrintGridlines; - } - - /** - * Returns the PrintHeadersRecord. - * @return PrintHeadersRecord for the sheet. - */ - public PrintHeadersRecord getPrintHeaders() - { - return printHeaders; - } - - /** - * Sets the PrintHeadersRecord. - * @param newPrintHeaders The new PrintHeadersRecord for the sheet. - */ - public void setPrintHeaders(PrintHeadersRecord newPrintHeaders) - { - printHeaders = newPrintHeaders; - } - - /** - * Sets whether the sheet is selected - * @param sel True to select the sheet, false otherwise. - */ - public void setSelected(boolean sel) { - windowTwo.setSelected(sel); - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - * - *

    If both colSplit and rowSplit are zero then the existing freeze pane is removed

    - * - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - * @param topRow Top row visible in bottom pane - * @param leftmostColumn Left column visible in right pane. - */ - public void createFreezePane(int colSplit, int rowSplit, int topRow, int leftmostColumn) { - int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); - if (paneLoc != -1) - _records.remove(paneLoc); - - // If both colSplit and rowSplit are zero then the existing freeze pane is removed - if(colSplit == 0 && rowSplit == 0){ - windowTwo.setFreezePanes(false); - windowTwo.setFreezePanesNoSplit(false); - SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid); - sel.setPane(PaneInformation.PANE_UPPER_LEFT); - return; - } - - int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); - PaneRecord pane = new PaneRecord(); - pane.setX((short)colSplit); - pane.setY((short)rowSplit); - pane.setTopRow((short) topRow); - pane.setLeftColumn((short) leftmostColumn); - if (rowSplit == 0) { - pane.setTopRow((short)0); - pane.setActivePane((short)1); - } else if (colSplit == 0) { - pane.setLeftColumn((short)0); - pane.setActivePane((short)2); - } else { - pane.setActivePane((short)0); - } - _records.add(loc+1, pane); - - windowTwo.setFreezePanes(true); - windowTwo.setFreezePanesNoSplit(true); - - SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid); - sel.setPane((byte)pane.getActivePane()); - - } - - /** - * Creates a split pane. Any existing freezepane or split pane is overwritten. - * @param xSplitPos Horizonatal position of split (in 1/20th of a point). - * @param ySplitPos Vertical position of split (in 1/20th of a point). - * @param topRow Top row visible in bottom pane - * @param leftmostColumn Left column visible in right pane. - * @param activePane Active pane. One of: PANE_LOWER_RIGHT, - * PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT - * @see #PANE_LOWER_LEFT - * @see #PANE_LOWER_RIGHT - * @see #PANE_UPPER_LEFT - * @see #PANE_UPPER_RIGHT - */ - public void createSplitPane(int xSplitPos, int ySplitPos, int topRow, int leftmostColumn, int activePane) { - int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); - if (paneLoc != -1) - _records.remove(paneLoc); - - int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); - PaneRecord r = new PaneRecord(); - r.setX((short)xSplitPos); - r.setY((short)ySplitPos); - r.setTopRow((short) topRow); - r.setLeftColumn((short) leftmostColumn); - r.setActivePane((short) activePane); - _records.add(loc+1, r); - - windowTwo.setFreezePanes(false); - windowTwo.setFreezePanesNoSplit(false); - - SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid); - sel.setPane(PANE_LOWER_RIGHT); - - } - - /** - * Returns the information regarding the currently configured pane (split or freeze). - * @return null if no pane configured, or the pane information. - */ - public PaneInformation getPaneInformation() { - PaneRecord rec = (PaneRecord)findFirstRecordBySid(PaneRecord.sid); - if (rec == null) - return null; - - return new PaneInformation(rec.getX(), rec.getY(), rec.getTopRow(), - rec.getLeftColumn(), (byte)rec.getActivePane(), windowTwo.getFreezePanes()); - } - - public SelectionRecord getSelection() { - return _selection; - } - - public void setSelection( SelectionRecord selection) { - _selection = selection; - } - - /** - * @return the {@link WorksheetProtectionBlock} for this sheet - */ - public WorksheetProtectionBlock getProtectionBlock() { - return _protectionBlock; - } - /** - * Sets whether the gridlines are shown in a viewer. - * @param show whether to show gridlines or not - */ - public void setDisplayGridlines(boolean show) { - windowTwo.setDisplayGridlines(show); - } - - /** - * @return true if gridlines are displayed - */ - public boolean isDisplayGridlines() { - return windowTwo.getDisplayGridlines(); - } - - /** - * Sets whether the formulas are shown in a viewer. - * @param show whether to show formulas or not - */ - public void setDisplayFormulas(boolean show) { - windowTwo.setDisplayFormulas(show); - } - - /** - * Returns if formulas are displayed. - * @return whether formulas are displayed - */ - public boolean isDisplayFormulas() { - return windowTwo.getDisplayFormulas(); - } - - /** - * Sets whether the RowColHeadings are shown in a viewer. - * @param show whether to show RowColHeadings or not - */ - public void setDisplayRowColHeadings(boolean show) { - windowTwo.setDisplayRowColHeadings(show); - } - - /** - * Returns if RowColHeadings are displayed. - * @return whether RowColHeadings are displayed - */ - public boolean isDisplayRowColHeadings() { - return windowTwo.getDisplayRowColHeadings(); - } - - /** - * Sets whether the RowColHeadings are shown in a viewer. - * @param show whether to show RowColHeadings or not - */ - public void setPrintRowColHeadings(boolean show) { - windowTwo.setDisplayRowColHeadings(show); - } - - /** - * Returns if RowColHeadings are displayed. - * @return whether RowColHeadings are displayed - */ - public boolean isPrintRowColHeadings() { - return windowTwo.getDisplayRowColHeadings(); - } - - - /** - * @return whether an uncalced record must be inserted or not at generation - */ - public boolean getUncalced() { - return _isUncalced; - } - /** - * @param uncalced whether an uncalced record must be inserted or not at generation - */ - public void setUncalced(boolean uncalced) { - this._isUncalced = uncalced; - } - - /** - * Finds the DrawingRecord for our sheet, and - * attaches it to the DrawingManager (which knows about - * the overall DrawingGroup for our workbook). - * If requested, will create a new DrawRecord - * if none currently exist - * @param drawingManager The DrawingManager2 for our workbook - * @param createIfMissing Should one be created if missing? - * @return location of EscherAggregate record. if no EscherAggregate record is found return -1 - */ - public int aggregateDrawingRecords(DrawingManager2 drawingManager, boolean createIfMissing) { - int loc = findFirstRecordLocBySid(DrawingRecord.sid); - boolean noDrawingRecordsFound = (loc == -1); - if (noDrawingRecordsFound) { - if(!createIfMissing) { - // None found, and not allowed to add in - return -1; - } - - EscherAggregate aggregate = new EscherAggregate(true); - loc = findFirstRecordLocBySid(EscherAggregate.sid); - if (loc == -1) { - loc = findFirstRecordLocBySid( WindowTwoRecord.sid ); - } else { - getRecords().remove(loc); - } - getRecords().add( loc, aggregate ); - return loc; - } - List records = getRecords(); - - EscherAggregate.createAggregate(records, loc); - - return loc; - } - - /** - * Perform any work necessary before the sheet is about to be serialized. - * For instance the escher aggregates size needs to be calculated before - * serialization so that the dgg record (which occurs first) can be written. - */ - public void preSerialize() { - for (RecordBase r: getRecords()) { - if (r instanceof EscherAggregate) { - // Trigger flattening of user model and corresponding update of dgg record. - r.getRecordSize(); - } - } - } - - - public PageSettingsBlock getPageSettings() { - if (_psBlock == null) { - _psBlock = new PageSettingsBlock(); - RecordOrderer.addNewSheetRecord(_records, _psBlock); - } - return _psBlock; - } - - - public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) { - if (collapsed) { - _columnInfos.collapseColumn(columnNumber); - } else { - _columnInfos.expandColumn(columnNumber); - } - } - - - public void groupRowRange(int fromRow, int toRow, boolean indent) - { - for (int rowNum = fromRow; rowNum <= toRow; rowNum++) - { - RowRecord row = getRow( rowNum ); - if (row == null) - { - row = RowRecordsAggregate.createRow(rowNum); - addRow( row ); - } - int level = row.getOutlineLevel(); - if (indent) level++; else level--; - level = Math.max(0, level); - level = Math.min(7, level); - row.setOutlineLevel((short) ( level )); - } - - recalcRowGutter(); - } - - private void recalcRowGutter() { - int maxLevel = 0; - Iterator iterator = _rowsAggregate.getIterator(); - while (iterator.hasNext()) { - RowRecord rowRecord = iterator.next(); - maxLevel = Math.max(rowRecord.getOutlineLevel(), maxLevel); - } - - // Grab the guts record, adding if needed - GutsRecord guts = getGutsRecord(); - // Set the levels onto it - guts.setRowLevelMax( (short) ( maxLevel + 1 ) ); - guts.setLeftRowGutter( (short) ( 29 + (12 * (maxLevel)) ) ); - } - - public DataValidityTable getOrCreateDataValidityTable() { - if (_dataValidityTable == null) { - DataValidityTable result = new DataValidityTable(); - RecordOrderer.addNewSheetRecord(_records, result); - _dataValidityTable = result; - } - return _dataValidityTable; - } - /** - * Get the {@link NoteRecord}s (related to cell comments) for this sheet - * @return never null, typically empty array - */ - public NoteRecord[] getNoteRecords() { - List temp = new ArrayList(); - for(int i=_records.size()-1; i>=0; i--) { - RecordBase rec = _records.get(i); - if (rec instanceof NoteRecord) { - temp.add((NoteRecord) rec); - } - } - if (temp.size() < 1) { - return NoteRecord.EMPTY_ARRAY; - } - NoteRecord[] result = new NoteRecord[temp.size()]; - temp.toArray(result); - return result; - } - - public int getColumnOutlineLevel(int columnIndex) { - return _columnInfos.getOutlineLevel(columnIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java deleted file mode 100644 index 3a5fc1ef5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ /dev/null @@ -1,2701 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.security.AccessControlException; -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.crypto.SecretKey; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherBoolProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherDgRecord; -import org.apache.poi.ddf.EscherDggRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherRGBProperty; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.ddf.EscherSplitMenuColorsRecord; -import org.apache.poi.hssf.extractor.OldExcelExtractor; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BackupRecord; -import org.apache.poi.hssf.record.BookBoolRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.CodepageRecord; -import org.apache.poi.hssf.record.CountryRecord; -import org.apache.poi.hssf.record.DSFRecord; -import org.apache.poi.hssf.record.DateWindow1904Record; -import org.apache.poi.hssf.record.DrawingGroupRecord; -import org.apache.poi.hssf.record.EOFRecord; -import org.apache.poi.hssf.record.EscherAggregate; -import org.apache.poi.hssf.record.ExtSSTRecord; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.ExternSheetRecord; -import org.apache.poi.hssf.record.FilePassRecord; -import org.apache.poi.hssf.record.FileSharingRecord; -import org.apache.poi.hssf.record.FnGroupCountRecord; -import org.apache.poi.hssf.record.FontRecord; -import org.apache.poi.hssf.record.FormatRecord; -import org.apache.poi.hssf.record.HideObjRecord; -import org.apache.poi.hssf.record.HyperlinkRecord; -import org.apache.poi.hssf.record.InterfaceEndRecord; -import org.apache.poi.hssf.record.InterfaceHdrRecord; -import org.apache.poi.hssf.record.MMSRecord; -import org.apache.poi.hssf.record.NameCommentRecord; -import org.apache.poi.hssf.record.NameRecord; -import org.apache.poi.hssf.record.PaletteRecord; -import org.apache.poi.hssf.record.PasswordRecord; -import org.apache.poi.hssf.record.PasswordRev4Record; -import org.apache.poi.hssf.record.PrecisionRecord; -import org.apache.poi.hssf.record.ProtectRecord; -import org.apache.poi.hssf.record.ProtectionRev4Record; -import org.apache.poi.hssf.record.RecalcIdRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RefreshAllRecord; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.StyleRecord; -import org.apache.poi.hssf.record.SupBookRecord; -import org.apache.poi.hssf.record.TabIdRecord; -import org.apache.poi.hssf.record.UseSelFSRecord; -import org.apache.poi.hssf.record.WindowOneRecord; -import org.apache.poi.hssf.record.WindowProtectRecord; -import org.apache.poi.hssf.record.WriteAccessRecord; -import org.apache.poi.hssf.record.WriteProtectRecord; -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionMode; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheetRange; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.OperandPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.BuiltinFormats; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Low level model implementation of a Workbook. Provides creational methods - * for settings and objects contained in the workbook object. - *

    - * This file contains the low level binary records starting at the workbook's BOF and - * ending with the workbook's EOF. Use HSSFWorkbook for a high level representation. - *

    - * The structures of the highlevel API use references to this to perform most of their - * operations. Its probably unwise to use these low level structures directly unless you - * really know what you're doing. I recommend you read the Microsoft Excel 97 Developer's - * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf - * before even attempting to use this. - * - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook - */ -@Internal -public final class InternalWorkbook { - /** - * Excel silently truncates long sheet names to 31 chars. - * This constant is used to ensure uniqueness in the first 31 chars - */ - private static final int MAX_SENSITIVE_SHEET_NAME_LEN = 31; - - /** - * Normally, the Workbook will be in a POIFS Stream called - * "Workbook". However, some weird XLS generators use "WORKBOOK" - * or "BOOK". - */ - public static final String[] WORKBOOK_DIR_ENTRY_NAMES = { - "Workbook", // as per BIFF8 spec - "WORKBOOK", // Typically from third party programs - "BOOK", // Typically odd Crystal Reports exports - }; - /** - * Name of older (pre-Excel 97) Workbook streams, which - * aren't supported by HSSFWorkbook, only by - * {@link OldExcelExtractor} - */ - public static final String OLD_WORKBOOK_DIR_ENTRY_NAME = "Book"; - - private static final POILogger log = POILogFactory.getLogger(InternalWorkbook.class); - private static final int DEBUG = POILogger.DEBUG; - - /** - * constant used to set the "codepage" wherever "codepage" is set in records - * (which is duplicated in more than one record) - */ - private final static short CODEPAGE = 0x04B0; - - /** - * this contains the Worksheet record objects - */ - private final WorkbookRecordList records; - - /** - * this contains a reference to the SSTRecord so that new stings can be added - * to it. - */ - protected SSTRecord sst; - - - private LinkTable linkTable; // optionally occurs if there are references in the document. (4.10.3) - - /** - * holds the "boundsheet" records (aka bundlesheet) so that they can have their - * reference to their "BOF" marker - */ - private final List boundsheets; - private final List formats; - private final List hyperlinks; - - /** the number of extended format records */ - private int numxfs; - /** the number of font records */ - private int numfonts; - /** holds the max format id */ - private int maxformatid; - /** whether 1904 date windowing is being used */ - private boolean uses1904datewindowing; - private DrawingManager2 drawingManager; - private List escherBSERecords; - private WindowOneRecord windowOne; - private FileSharingRecord fileShare; - private WriteAccessRecord writeAccess; - private WriteProtectRecord writeProtect; - - /** - * Hold the {@link NameCommentRecord}s indexed by the name of the {@link NameRecord} to which they apply. - */ - private final Map commentRecords; - - private InternalWorkbook() { - records = new WorkbookRecordList(); - - boundsheets = new ArrayList(); - formats = new ArrayList(); - hyperlinks = new ArrayList(); - numxfs = 0; - numfonts = 0; - maxformatid = -1; - uses1904datewindowing = false; - escherBSERecords = new ArrayList(); - commentRecords = new LinkedHashMap(); - } - - /** - * read support for low level - * API. Pass in an array of Record objects, A Workbook - * object is constructed and passed back with all of its initialization set - * to the passed in records and references to those records held. Unlike Sheet - * workbook does not use an offset (its assumed to be 0) since its first in a file. - * If you need an offset then construct a new array with a 0 offset or write your - * own ;-p. - * - * @param recs an array of Record objects - * @return Workbook object - */ - public static InternalWorkbook createWorkbook(List recs) { - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "Workbook (readfile) created with reclen=", - Integer.valueOf(recs.size())); - InternalWorkbook retval = new InternalWorkbook(); - List records = new ArrayList(recs.size() / 3); - retval.records.setRecords(records); - - int k; - for (k = 0; k < recs.size(); k++) { - Record rec = recs.get(k); - - if (rec.getSid() == EOFRecord.sid) { - records.add(rec); - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found workbook eof record at " + k); - break; - } - switch (rec.getSid()) { - - case BoundSheetRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found boundsheet record at " + k); - retval.boundsheets.add((BoundSheetRecord) rec); - retval.records.setBspos( k ); - break; - - case SSTRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found sst record at " + k); - retval.sst = ( SSTRecord ) rec; - break; - - case FontRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found font record at " + k); - retval.records.setFontpos( k ); - retval.numfonts++; - break; - - case ExtendedFormatRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found XF record at " + k); - retval.records.setXfpos( k ); - retval.numxfs++; - break; - - case TabIdRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found tabid record at " + k); - retval.records.setTabpos( k ); - break; - - case ProtectRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found protect record at " + k); - retval.records.setProtpos( k ); - break; - - case BackupRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found backup record at " + k); - retval.records.setBackuppos( k ); - break; - case ExternSheetRecord.sid : - throw new RuntimeException("Extern sheet is part of LinkTable"); - case NameRecord.sid : - case SupBookRecord.sid : - // LinkTable can start with either of these - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found SupBook record at " + k); - retval.linkTable = new LinkTable(recs, k, retval.records, retval.commentRecords); - k+=retval.linkTable.getRecordCount() - 1; - continue; - case FormatRecord.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found format record at " + k); - retval.formats.add((FormatRecord) rec); - retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode(); - break; - case DateWindow1904Record.sid : - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found datewindow1904 record at " + k); - retval.uses1904datewindowing = ((DateWindow1904Record)rec).getWindowing() == 1; - break; - case PaletteRecord.sid: - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found palette record at " + k); - retval.records.setPalettepos( k ); - break; - case WindowOneRecord.sid: - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found WindowOneRecord at " + k); - retval.windowOne = (WindowOneRecord) rec; - break; - case WriteAccessRecord.sid: - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found WriteAccess at " + k); - retval.writeAccess = (WriteAccessRecord) rec; - break; - case WriteProtectRecord.sid: - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found WriteProtect at " + k); - retval.writeProtect = (WriteProtectRecord) rec; - break; - case FileSharingRecord.sid: - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found FileSharing at " + k); - retval.fileShare = (FileSharingRecord) rec; - break; - - case NameCommentRecord.sid: - final NameCommentRecord ncr = (NameCommentRecord) rec; - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "found NameComment at " + k); - retval.commentRecords.put(ncr.getNameText(), ncr); - break; - default: - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "ignoring record (sid=" + rec.getSid() + ") at " + k); - break; - } - records.add(rec); - } - //What if we dont have any ranges and supbooks - // if (retval.records.supbookpos == 0) { - // retval.records.supbookpos = retval.records.bspos + 1; - // retval.records.namepos = retval.records.supbookpos + 1; - // } - - // Look for other interesting values that - // follow the EOFRecord - for ( ; k < recs.size(); k++) { - Record rec = recs.get(k); - switch (rec.getSid()) { - case HyperlinkRecord.sid: - retval.hyperlinks.add((HyperlinkRecord)rec); - break; - default: - break; - } - } - - if (retval.windowOne == null) { - retval.windowOne = createWindowOne(); - } - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "exit create workbook from existing file function"); - return retval; - } - - /** - * Creates an empty workbook object with three blank sheets and all the empty - * fields. Use this to create a workbook from scratch. - * - * @return an empty workbook object - */ - public static InternalWorkbook createWorkbook() - { - if (log.check( POILogger.DEBUG )) - log.log( DEBUG, "creating new workbook from scratch" ); - InternalWorkbook retval = new InternalWorkbook(); - List records = new ArrayList( 30 ); - retval.records.setRecords(records); - List formats = retval.formats; - - records.add(createBOF()); - records.add(new InterfaceHdrRecord(CODEPAGE)); - records.add(createMMS()); - records.add(InterfaceEndRecord.instance); - records.add(createWriteAccess()); - records.add(createCodepage()); - records.add(createDSF()); - records.add(createTabId()); - retval.records.setTabpos(records.size() - 1); - records.add(createFnGroupCount()); - records.add(createWindowProtect()); - records.add(createProtect()); - retval.records.setProtpos(records.size() - 1); - records.add(createPassword()); - records.add(createProtectionRev4()); - records.add(createPasswordRev4()); - retval.windowOne = createWindowOne(); - records.add(retval.windowOne); - records.add(createBackup()); - retval.records.setBackuppos(records.size() - 1); - records.add(createHideObj()); - records.add(createDateWindow1904()); - records.add(createPrecision()); - records.add(createRefreshAll()); - records.add(createBookBool()); - records.add(createFont()); - records.add(createFont()); - records.add(createFont()); - records.add(createFont()); - retval.records.setFontpos( records.size() - 1 ); // last font record position - retval.numfonts = 4; - - // set up format records - for (int i = 0; i <= 7; i++) { - FormatRecord rec = createFormat(i); - retval.maxformatid = retval.maxformatid >= rec.getIndexCode() ? retval.maxformatid : rec.getIndexCode(); - formats.add(rec); - records.add(rec); - } - - for (int k = 0; k < 21; k++) { - records.add(InternalWorkbook.createExtendedFormat(k)); - retval.numxfs++; - } - retval.records.setXfpos( records.size() - 1 ); - for (int k = 0; k < 6; k++) { - records.add(InternalWorkbook.createStyle(k)); - } - records.add(InternalWorkbook.createUseSelFS()); - - int nBoundSheets = 1; // now just do 1 - for (int k = 0; k < nBoundSheets; k++) { - BoundSheetRecord bsr = createBoundSheet(k); - - records.add(bsr); - retval.boundsheets.add(bsr); - retval.records.setBspos(records.size() - 1); - } - records.add( InternalWorkbook.createCountry() ); - for ( int k = 0; k < nBoundSheets; k++ ) { - retval.getOrCreateLinkTable().checkExternSheet(k); - } - retval.sst = new SSTRecord(); - records.add(retval.sst); - records.add(InternalWorkbook.createExtendedSST()); - - records.add(EOFRecord.instance); - if (log.check( POILogger.DEBUG )) - log.log( DEBUG, "exit create new workbook from scratch" ); - return retval; - } - - - /**Retrieves the Builtin NameRecord that matches the name and index - * There shouldn't be too many names to make the sequential search too slow - * @param name byte representation of the builtin name to match - * @param sheetNumber 1-based sheet number - * @return null if no builtin NameRecord matches - */ - public NameRecord getSpecificBuiltinRecord(byte name, int sheetNumber) - { - return getOrCreateLinkTable().getSpecificBuiltinRecord(name, sheetNumber); - } - - /** - * Removes the specified Builtin NameRecord that matches the name and index - * @param name byte representation of the builtin to match - * @param sheetIndex zero-based sheet reference - */ - public void removeBuiltinRecord(byte name, int sheetIndex) { - linkTable.removeBuiltinRecord(name, sheetIndex); - // TODO - do we need "this.records.remove(...);" similar to that in this.removeName(int namenum) {}? - } - - public int getNumRecords() { - return records.size(); - } - - /** - * gets the font record at the given index in the font table. Remember - * "There is No Four" (someone at M$ must have gone to Rocky Horror one too - * many times) - * - * @param idx the index to look at (0 or greater but NOT 4) - * @return FontRecord located at the given index - */ - - public FontRecord getFontRecordAt(int idx) { - int index = idx; - - if (index > 4) { - index -= 1; // adjust for "There is no 4" - } - if (index > (numfonts - 1)) { - throw new ArrayIndexOutOfBoundsException( - "There are only " + numfonts - + " font records, you asked for " + idx); - } - FontRecord retval = - ( FontRecord ) records.get((records.getFontpos() - (numfonts - 1)) + index); - - return retval; - } - - /** - * Retrieves the index of the given font - * - * @param font the font - * - * @return the font index - * - * @throws IllegalArgumentException if the font index can't be determined - */ - public int getFontIndex(FontRecord font) { - for(int i=0; i<=numfonts; i++) { - FontRecord thisFont = - ( FontRecord ) records.get((records.getFontpos() - (numfonts - 1)) + i); - if(thisFont == font) { - // There is no 4! - if(i > 3) { - return (i+1); - } - return i; - } - } - throw new IllegalArgumentException("Could not find that font!"); - } - - /** - * creates a new font record and adds it to the "font table". This causes the - * boundsheets to move down one, extended formats to move down (so this function moves - * those pointers as well) - * - * @return FontRecord that was just created - */ - - public FontRecord createNewFont() { - FontRecord rec = createFont(); - - records.add(records.getFontpos()+1, rec); - records.setFontpos( records.getFontpos() + 1 ); - numfonts++; - return rec; - } - - /** - * Removes the given font record from the - * file's list. This will make all - * subsequent font indicies drop by one, - * so you'll need to update those yourself! - * - * @param rec the font record - */ - public void removeFontRecord(FontRecord rec) { - records.remove(rec); // this updates FontPos for us - numfonts--; - } - - /** - * gets the number of font records - * - * @return number of font records in the "font table" - */ - - public int getNumberOfFontRecords() { - return numfonts; - } - - /** - * Sets the BOF for a given sheet - * - * @param sheetIndex the number of the sheet to set the positing of the bof for - * @param pos the actual bof position - */ - - public void setSheetBof(int sheetIndex, int pos) { - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "setting bof for sheetnum =", Integer.valueOf(sheetIndex), - " at pos=", Integer.valueOf(pos)); - checkSheets(sheetIndex); - getBoundSheetRec(sheetIndex) - .setPositionOfBof(pos); - } - - private BoundSheetRecord getBoundSheetRec(int sheetIndex) { - return boundsheets.get(sheetIndex); - } - - /** - * Returns the position of the backup record. - * - * @return the position of the backup record - */ - public BackupRecord getBackupRecord() { - return ( BackupRecord ) records.get(records.getBackuppos()); - } - - - /** - * sets the name for a given sheet. If the boundsheet record doesn't exist and - * its only one more than we have, go ahead and create it. If it's > 1 more than - * we have, except - * - * @param sheetnum the sheet number (0 based) - * @param sheetname the name for the sheet - */ - public void setSheetName(int sheetnum, String sheetname) { - checkSheets(sheetnum); - - // YK: Mimic Excel and silently truncate sheet names longer than 31 characters - if(sheetname.length() > 31) sheetname = sheetname.substring(0, 31); - - BoundSheetRecord sheet = boundsheets.get(sheetnum); - sheet.setSheetname(sheetname); - } - - /** - * Determines whether a workbook contains the provided sheet name. For the purpose of - * comparison, long names are truncated to 31 chars. - * - * @param name the name to test (case insensitive match) - * @param excludeSheetIdx the sheet to exclude from the check or -1 to include all sheets in the check. - * @return true if the sheet contains the name, false otherwise. - */ - public boolean doesContainsSheetName(String name, int excludeSheetIdx) { - String aName = name; - if (aName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { - aName = aName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN); - } - for (int i = 0; i < boundsheets.size(); i++) { - BoundSheetRecord boundSheetRecord = getBoundSheetRec(i); - if (excludeSheetIdx == i) { - continue; - } - String bName = boundSheetRecord.getSheetname(); - if (bName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { - bName = bName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN); - } - if (aName.equalsIgnoreCase(bName)) { - return true; - } - } - return false; - } - - /** - * sets the order of appearance for a given sheet. - * - * @param sheetname the name of the sheet to reorder - * @param pos the position that we want to insert the sheet into (0 based) - */ - public void setSheetOrder(String sheetname, int pos ) { - int sheetNumber = getSheetIndex(sheetname); - //remove the sheet that needs to be reordered and place it in the spot we want - boundsheets.add(pos, boundsheets.remove(sheetNumber)); - - // also adjust order of Records, calculate the position of the Boundsheets via getBspos()... - int initialBspos = records.getBspos(); - int pos0 = initialBspos - (boundsheets.size() - 1); - Record removed = records.get(pos0 + sheetNumber); - records.remove(pos0 + sheetNumber); - records.add(pos0 + pos, removed); - records.setBspos(initialBspos); - } - - /** - * gets the name for a given sheet. - * - * @param sheetIndex the sheet number (0 based) - * @return sheetname the name for the sheet - */ - public String getSheetName(int sheetIndex) { - return getBoundSheetRec(sheetIndex).getSheetname(); - } - - /** - * Gets the hidden flag for a given sheet. - * Note that a sheet could instead be - * set to be very hidden, which is different - * ({@link #isSheetVeryHidden(int)}) - * - * @param sheetnum the sheet number (0 based) - * @return True if sheet is hidden - */ - public boolean isSheetHidden(int sheetnum) { - return getBoundSheetRec(sheetnum).isHidden(); - } - - /** - * Gets the very hidden flag for a given sheet. - * This is different from the normal - * hidden flag - * ({@link #isSheetHidden(int)}) - * - * @param sheetnum the sheet number (0 based) - * @return True if sheet is very hidden - */ - public boolean isSheetVeryHidden(int sheetnum) { - return getBoundSheetRec(sheetnum).isVeryHidden(); - } - - /** - * Hide or unhide a sheet - * - * @param sheetnum The sheet number - * @param hidden True to mark the sheet as hidden, false otherwise - */ - public void setSheetHidden(int sheetnum, boolean hidden) { - getBoundSheetRec(sheetnum).setHidden(hidden); - } - - /** - * Hide or unhide a sheet. - * 0 = not hidden - * 1 = hidden - * 2 = very hidden. - * - * @param sheetnum The sheet number - * @param hidden 0 for not hidden, 1 for hidden, 2 for very hidden - */ - public void setSheetHidden(int sheetnum, int hidden) { - BoundSheetRecord bsr = getBoundSheetRec(sheetnum); - boolean h = false; - boolean vh = false; - if(hidden == 0) { - } else if(hidden == 1) { - h = true; - } else if(hidden == 2) { - vh = true; - } else { - throw new IllegalArgumentException("Invalid hidden flag " + hidden + " given, must be 0, 1 or 2"); - } - bsr.setHidden(h); - bsr.setVeryHidden(vh); - } - - - /** - * get the sheet's index - * @param name sheet name - * @return sheet index or -1 if it was not found. - */ - public int getSheetIndex(String name) { - int retval = -1; - - for (int k = 0; k < boundsheets.size(); k++) { - String sheet = getSheetName(k); - - if (sheet.equalsIgnoreCase(name)) { - retval = k; - break; - } - } - return retval; - } - - /** - * if we're trying to address one more sheet than we have, go ahead and add it! if we're - * trying to address >1 more than we have throw an exception! - */ - private void checkSheets(int sheetnum) { - if ((boundsheets.size()) <= sheetnum) { // if we're short one add another.. - if ((boundsheets.size() + 1) <= sheetnum) { - throw new RuntimeException("Sheet number out of bounds!"); - } - BoundSheetRecord bsr = createBoundSheet(sheetnum); - - records.add(records.getBspos()+1, bsr); - records.setBspos( records.getBspos() + 1 ); - boundsheets.add(bsr); - getOrCreateLinkTable().checkExternSheet(sheetnum); - fixTabIdRecord(); - } - } - - /** - * @param sheetIndex zero based sheet index - */ - public void removeSheet(int sheetIndex) { - if (boundsheets.size() > sheetIndex) { - records.remove(records.getBspos() - (boundsheets.size() - 1) + sheetIndex); - boundsheets.remove(sheetIndex); - fixTabIdRecord(); - } - - // Within NameRecords, it's ok to have the formula - // part point at deleted sheets. It's also ok to - // have the ExternSheetNumber point at deleted - // sheets. - // However, the sheet index must be adjusted, or - // excel will break. (Sheet index is either 0 for - // global, or 1 based index to sheet) - int sheetNum1Based = sheetIndex + 1; - for(int i=0; i sheetNum1Based) { - // Bump down by one, so still points - // at the same sheet - nr.setSheetNumber(nr.getSheetNumber()-1); - } - } - - if (linkTable != null) { - // also tell the LinkTable about the removed sheet - //index hasn't change in the linktable - linkTable.removeSheet(sheetIndex); - } - } - - /** - * make the tabid record look like the current situation. - */ - private void fixTabIdRecord() { - Record rec = records.get(records.getTabpos()); - - // see bug 55982, quite a number of documents do not have a TabIdRecord and - // thus there is no way to do the fixup here, - // we use the same check on Tabpos as done in other places - if(records.getTabpos() <= 0) { - return; - } - - TabIdRecord tir = ( TabIdRecord ) rec; - short[] tia = new short[ boundsheets.size() ]; - - for (short k = 0; k < tia.length; k++) { - tia[ k ] = k; - } - tir.setTabIdArray(tia); - } - - /** - * returns the number of boundsheet objects contained in this workbook. - * - * @return number of BoundSheet records - */ - - public int getNumSheets() { - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "getNumSheets=", Integer.valueOf(boundsheets.size())); - return boundsheets.size(); - } - - /** - * get the number of ExtendedFormat records contained in this workbook. - * - * @return int count of ExtendedFormat records - */ - - public int getNumExFormats() { - if (log.check( POILogger.DEBUG )) - log.log(DEBUG, "getXF=", Integer.valueOf(numxfs)); - return numxfs; - } - - /** - * gets the ExtendedFormatRecord at the given 0-based index - * - * @param index of the Extended format record (0-based) - * @return ExtendedFormatRecord at the given index - */ - - public ExtendedFormatRecord getExFormatAt(int index) { - int xfptr = records.getXfpos() - (numxfs - 1); - - xfptr += index; - ExtendedFormatRecord retval = - ( ExtendedFormatRecord ) records.get(xfptr); - - return retval; - } - - /** - * Removes the given ExtendedFormatRecord record from the - * file's list. This will make all - * subsequent font indicies drop by one, - * so you'll need to update those yourself! - * - * @param rec the ExtendedFormatRecord - */ - public void removeExFormatRecord(ExtendedFormatRecord rec) { - records.remove(rec); // this updates XfPos for us - numxfs--; - } - - /** - * Removes ExtendedFormatRecord record with given index from the - * file's list. This will make all - * subsequent font indicies drop by one, - * so you'll need to update those yourself! - * @param index of the Extended format record (0-based) - */ - public void removeExFormatRecord(int index) { - int xfptr = records.getXfpos() - (numxfs - 1) + index; - records.remove(xfptr); // this updates XfPos for us - numxfs--; - } - - - /** - * creates a new Cell-type Extended Format Record and adds it to the end of - * ExtendedFormatRecords collection - * - * @return ExtendedFormatRecord that was created - */ - - public ExtendedFormatRecord createCellXF() { - ExtendedFormatRecord xf = createExtendedFormat(); - - records.add(records.getXfpos()+1, xf); - records.setXfpos( records.getXfpos() + 1 ); - numxfs++; - return xf; - } - - /** - * Returns the StyleRecord for the given - * xfIndex, or null if that ExtendedFormat doesn't - * have a Style set. - * - * @param xfIndex the extended format index - * - * @return the StyleRecord, {@code null} if it that ExtendedFormat doesn't have a Style set. - */ - public StyleRecord getStyleRecord(int xfIndex) { - // Style records always follow after - // the ExtendedFormat records - for(int i=records.getXfpos(); i 0) { - TabIdRecord tir = ( TabIdRecord ) records.get(records.getTabpos()); - if(tir._tabids.length < boundsheets.size()) { - fixTabIdRecord(); - } - } - } - - private void updateEncryptionRecord() { - FilePassRecord fpr = null; - int fprPos = -1; - for (Record r : records.getRecords()) { - fprPos++; - if (r instanceof FilePassRecord) { - fpr = (FilePassRecord)r; - break; - } - } - - String password = Biff8EncryptionKey.getCurrentUserPassword(); - if (password == null) { - if (fpr != null) { - // need to remove password data - records.remove(fprPos); - } - return; - } else { - // create password record - if (fpr == null) { - fpr = new FilePassRecord(EncryptionMode.binaryRC4); - records.add(1, fpr); - } - - // check if the password has been changed - EncryptionInfo ei = fpr.getEncryptionInfo(); - byte encVer[] = ei.getVerifier().getEncryptedVerifier(); - try { - Decryptor dec = ei.getDecryptor(); - Encryptor enc = ei.getEncryptor(); - if (encVer == null || !dec.verifyPassword(password)) { - enc.confirmPassword(password); - } else { - SecretKey sk = dec.getSecretKey(); - ei.getEncryptor().setSecretKey(sk); - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException("can't validate/update encryption setting", e); - } - } - } - - public int getSize() - { - int retval = 0; - - SSTRecord sst = null; - for ( int k = 0; k < records.size(); k++ ) - { - Record record = records.get( k ); - if (record instanceof SSTRecord) - sst = (SSTRecord)record; - - if (record.getSid() == ExtSSTRecord.sid && sst != null) - retval += sst.calcExtSSTRecordSize(); - else - retval += record.getRecordSize(); - } - - return retval; - } - - private static BOFRecord createBOF() { - BOFRecord retval = new BOFRecord(); - - retval.setVersion(( short ) 0x600); - retval.setType(BOFRecord.TYPE_WORKBOOK); - retval.setBuild(( short ) 0x10d3); - retval.setBuildYear(( short ) 1996); - retval.setHistoryBitMask(0x41); // was c1 before verify - retval.setRequiredVersion(0x6); - return retval; - } - - - private static MMSRecord createMMS() { - MMSRecord retval = new MMSRecord(); - - retval.setAddMenuCount(( byte ) 0); - retval.setDelMenuCount(( byte ) 0); - return retval; - } - - /** - * creates the WriteAccess record containing the logged in user's name - */ - private static WriteAccessRecord createWriteAccess() { - WriteAccessRecord retval = new WriteAccessRecord(); - - String defaultUserName = "POI"; - try { - String username = System.getProperty("user.name"); - // Google App engine returns null for user.name, see Bug 53974 - if(username == null) username = defaultUserName; - - retval.setUsername(username); - } catch (AccessControlException e) { - // AccessControlException can occur in a restricted context - // (client applet/jws application or restricted security server) - retval.setUsername(defaultUserName); - } - return retval; - } - - private static CodepageRecord createCodepage() { - CodepageRecord retval = new CodepageRecord(); - - retval.setCodepage(CODEPAGE); - return retval; - } - - private static DSFRecord createDSF() { - return new DSFRecord(false); // we don't even support double stream files - } - - /** - * creates the TabId record containing an array - */ - private static TabIdRecord createTabId() { - return new TabIdRecord(); - } - - /** - * creates the FnGroupCount record containing the Magic number constant of 14. - */ - private static FnGroupCountRecord createFnGroupCount() { - FnGroupCountRecord retval = new FnGroupCountRecord(); - - retval.setCount(( short ) 14); - return retval; - } - - /** - * @return a new WindowProtect record with protect set to false. - */ - private static WindowProtectRecord createWindowProtect() { - // by default even when we support it we won't - // want it to be protected - return new WindowProtectRecord(false); - } - - /** - * @return a new Protect record with protect set to false. - */ - private static ProtectRecord createProtect() { - // by default even when we support it we won't - // want it to be protected - return new ProtectRecord(false); - } - - /** - * @return a new Password record with password set to 0x0000 (no password). - */ - private static PasswordRecord createPassword() { - return new PasswordRecord(0x0000); // no password by default! - } - - /** - * @return a new ProtectionRev4 record with protect set to false. - */ - private static ProtectionRev4Record createProtectionRev4() { - return new ProtectionRev4Record(false); - } - - /** - * @return a new PasswordRev4 record with password set to 0. - */ - private static PasswordRev4Record createPasswordRev4() { - return new PasswordRev4Record(0x0000); - } - - /** - * creates the WindowOne record with the following magic values:

    - * horizontal hold - 0x168

    - * vertical hold - 0x10e

    - * width - 0x3a5c

    - * height - 0x23be

    - * options - 0x38

    - * selected tab - 0

    - * displayed tab - 0

    - * num selected tab- 0

    - * tab width ratio - 0x258

    - */ - private static WindowOneRecord createWindowOne() { - WindowOneRecord retval = new WindowOneRecord(); - - retval.setHorizontalHold(( short ) 0x168); - retval.setVerticalHold(( short ) 0x10e); - retval.setWidth(( short ) 0x3a5c); - retval.setHeight(( short ) 0x23be); - retval.setOptions(( short ) 0x38); - retval.setActiveSheetIndex( 0x0); - retval.setFirstVisibleTab(0x0); - retval.setNumSelectedTabs(( short ) 1); - retval.setTabWidthRatio(( short ) 0x258); - return retval; - } - - /** - * creates the Backup record with backup set to 0. (loose the data, who cares) - */ - private static BackupRecord createBackup() { - BackupRecord retval = new BackupRecord(); - - retval.setBackup(( short ) 0); // by default DONT save backups of files...just loose data - return retval; - } - - /** - * creates the HideObj record with hide object set to 0. (don't hide) - */ - private static HideObjRecord createHideObj() { - HideObjRecord retval = new HideObjRecord(); - retval.setHideObj(( short ) 0); // by default set hide object off - return retval; - } - - /** - * creates the DateWindow1904 record with windowing set to 0. (don't window) - */ - private static DateWindow1904Record createDateWindow1904() { - DateWindow1904Record retval = new DateWindow1904Record(); - - retval.setWindowing(( short ) 0); // don't EVER use 1904 date windowing...tick tock.. - return retval; - } - - /** - * creates the Precision record with precision set to true. (full precision) - */ - private static PrecisionRecord createPrecision() { - PrecisionRecord retval = new PrecisionRecord(); - retval.setFullPrecision(true); // always use real numbers in calculations! - return retval; - } - - /** - * @return a new RefreshAll record with refreshAll set to false. (do not refresh all calcs) - */ - private static RefreshAllRecord createRefreshAll() { - return new RefreshAllRecord(false); - } - - /** - * creates the BookBool record with saveLinkValues set to 0. (don't save link values) - */ - private static BookBoolRecord createBookBool() { - BookBoolRecord retval = new BookBoolRecord(); - retval.setSaveLinkValues(( short ) 0); - return retval; - } - - /** - * creates a Font record with the following magic values:

    - * fontheight = 0xc8

    - * attributes = 0x0

    - * color palette index = 0x7fff

    - * bold weight = 0x190

    - * Font Name Length = 5

    - * Font Name = Arial

    - */ - private static FontRecord createFont() { - FontRecord retval = new FontRecord(); - - retval.setFontHeight(( short ) 0xc8); - retval.setAttributes(( short ) 0x0); - retval.setColorPaletteIndex(( short ) 0x7fff); - retval.setBoldWeight(( short ) 0x190); - retval.setFontName("Arial"); - return retval; - } - - /** - * Creates a FormatRecord object - * @param id the number of the format record to create (meaning its position in - * a file as M$ Excel would create it.) - */ - private static FormatRecord createFormat(int id) { - // we'll need multiple editions for - // the different formats - - - switch (id) { - case 0: return new FormatRecord(5, BuiltinFormats.getBuiltinFormat(5)); - case 1: return new FormatRecord(6, BuiltinFormats.getBuiltinFormat(6)); - case 2: return new FormatRecord(7, BuiltinFormats.getBuiltinFormat(7)); - case 3: return new FormatRecord(8, BuiltinFormats.getBuiltinFormat(8)); - case 4: return new FormatRecord(0x2a, BuiltinFormats.getBuiltinFormat(0x2a)); - case 5: return new FormatRecord(0x29, BuiltinFormats.getBuiltinFormat(0x29)); - case 6: return new FormatRecord(0x2c, BuiltinFormats.getBuiltinFormat(0x2c)); - case 7: return new FormatRecord(0x2b, BuiltinFormats.getBuiltinFormat(0x2b)); - } - throw new IllegalArgumentException("Unexpected id " + id); - } - - /** - * Creates an ExtendedFormatRecord object - * @param id the number of the extended format record to create (meaning its position in - * a file as MS Excel would create it.) - */ - private static ExtendedFormatRecord createExtendedFormat(int id) { // we'll need multiple editions - ExtendedFormatRecord retval = new ExtendedFormatRecord(); - - switch (id) { - - case 0 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 1 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 2 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 3 : - retval.setFontIndex(( short ) 2); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 4 : - retval.setFontIndex(( short ) 2); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 5 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 6 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 7 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 8 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 9 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 10 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 11 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 12 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 13 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 14 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff400); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - // cell records - case 15 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0x0); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - // style - case 16 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0x2b); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff800); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 17 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0x29); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff800); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 18 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0x2c); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff800); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 19 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0x2a); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff800); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 20 : - retval.setFontIndex(( short ) 1); - retval.setFormatIndex(( short ) 0x9); - retval.setCellOptions(( short ) 0xfffffff5); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0xfffff800); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - // unused from this point down - case 21 : - retval.setFontIndex(( short ) 5); - retval.setFormatIndex(( short ) 0x0); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0x800); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 22 : - retval.setFontIndex(( short ) 6); - retval.setFormatIndex(( short ) 0x0); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0x5c00); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 23 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0x31); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0x5c00); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 24 : - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0x8); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0x5c00); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - case 25 : - retval.setFontIndex(( short ) 6); - retval.setFormatIndex(( short ) 0x8); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0x5c00); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - break; - - default: - throw new IllegalStateException("Unrecognized format id: " + id); - } - return retval; - } - - /** - * creates an default cell type ExtendedFormatRecord object. - * @return ExtendedFormatRecord with intial defaults (cell-type) - */ - private static ExtendedFormatRecord createExtendedFormat() { - ExtendedFormatRecord retval = new ExtendedFormatRecord(); - - retval.setFontIndex(( short ) 0); - retval.setFormatIndex(( short ) 0x0); - retval.setCellOptions(( short ) 0x1); - retval.setAlignmentOptions(( short ) 0x20); - retval.setIndentionOptions(( short ) 0); - retval.setBorderOptions(( short ) 0); - retval.setPaletteOptions(( short ) 0); - retval.setAdtlPaletteOptions(( short ) 0); - retval.setFillPaletteOptions(( short ) 0x20c0); - retval.setTopBorderPaletteIdx(HSSFColor.BLACK.index); - retval.setBottomBorderPaletteIdx(HSSFColor.BLACK.index); - retval.setLeftBorderPaletteIdx(HSSFColor.BLACK.index); - retval.setRightBorderPaletteIdx(HSSFColor.BLACK.index); - return retval; - } - - /** - * Creates a StyleRecord object - * @param id the number of the style record to create (meaning its position in - * a file as MS Excel would create it. - */ - private static StyleRecord createStyle(int id) { // we'll need multiple editions - StyleRecord retval = new StyleRecord(); - - switch (id) { - - case 0 : - retval.setXFIndex(0x010); - retval.setBuiltinStyle(3); - retval.setOutlineStyleLevel(( byte ) 0xffffffff); - break; - - case 1 : - retval.setXFIndex(0x011); - retval.setBuiltinStyle(6); - retval.setOutlineStyleLevel(( byte ) 0xffffffff); - break; - - case 2 : - retval.setXFIndex(0x012); - retval.setBuiltinStyle(4); - retval.setOutlineStyleLevel(( byte ) 0xffffffff); - break; - - case 3 : - retval.setXFIndex(0x013); - retval.setBuiltinStyle(7); - retval.setOutlineStyleLevel(( byte ) 0xffffffff); - break; - - case 4 : - retval.setXFIndex(0x000); - retval.setBuiltinStyle(0); - retval.setOutlineStyleLevel(( byte ) 0xffffffff); - break; - - case 5 : - retval.setXFIndex(0x014); - retval.setBuiltinStyle(5); - retval.setOutlineStyleLevel(( byte ) 0xffffffff); - break; - - default: - throw new IllegalStateException("Unrecognized style id: " + id); - } - return retval; - } - - /** - * Creates a palette record initialized to the default palette - */ - private static PaletteRecord createPalette() { - return new PaletteRecord(); - } - - /** - * @return a new UseSelFS object with the use natural language flag set to 0 (false) - */ - private static UseSelFSRecord createUseSelFS() { - return new UseSelFSRecord(false); - } - - /** - * create a "bound sheet" or "bundlesheet" (depending who you ask) record - * Always sets the sheet's bof to 0. You'll need to set that yourself. - * @param id either sheet 0,1 or 2. - * @return record containing a BoundSheetRecord - * @see org.apache.poi.hssf.record.BoundSheetRecord - * @see org.apache.poi.hssf.record.Record - */ - private static BoundSheetRecord createBoundSheet(int id) { - return new BoundSheetRecord("Sheet" + (id+1)); - } - - /** - * Creates the Country record with the default country set to 1 - * and current country set to 7 in case of russian locale ("ru_RU") and 1 otherwise - */ - private static CountryRecord createCountry() { - CountryRecord retval = new CountryRecord(); - - retval.setDefaultCountry(( short ) 1); - - // from Russia with love ;) - if ( LocaleUtil.getUserLocale().toString().equals( "ru_RU" ) ) { - retval.setCurrentCountry(( short ) 7); - } - else { - retval.setCurrentCountry(( short ) 1); - } - - return retval; - } - - /** - * Creates the ExtendedSST record with numstrings per bucket set to 0x8. HSSF - * doesn't yet know what to do with this thing, but we create it with nothing in - * it hardly just to make Excel happy and our sheets look like Excel's - */ - private static ExtSSTRecord createExtendedSST() { - ExtSSTRecord retval = new ExtSSTRecord(); - retval.setNumStringsPerBucket(( short ) 0x8); - return retval; - } - - /** - * lazy initialization - * Note - creating the link table causes creation of 1 EXTERNALBOOK and 1 EXTERNALSHEET record - */ - private LinkTable getOrCreateLinkTable() { - if(linkTable == null) { - linkTable = new LinkTable((short) getNumSheets(), records); - } - return linkTable; - } - - public int linkExternalWorkbook(String name, Workbook externalWorkbook) { - return getOrCreateLinkTable().linkExternalWorkbook(name, externalWorkbook); - } - - /** - * Finds the first sheet name by his extern sheet index - * @param externSheetIndex extern sheet index - * @return first sheet name. - */ - public String findSheetFirstNameFromExternSheet(int externSheetIndex){ - int indexToSheet = linkTable.getFirstInternalSheetIndexForExtIndex(externSheetIndex); - return findSheetNameFromIndex(indexToSheet); - } - public String findSheetLastNameFromExternSheet(int externSheetIndex){ - int indexToSheet = linkTable.getLastInternalSheetIndexForExtIndex(externSheetIndex); - return findSheetNameFromIndex(indexToSheet); - } - private String findSheetNameFromIndex(int internalSheetIndex) { - if (internalSheetIndex < 0) { - // TODO - what does '-1' mean here? - //error check, bail out gracefully! - return ""; - } - if (internalSheetIndex >= boundsheets.size()) { - // Not sure if this can ever happen (See bug 45798) - return ""; // Seems to be what excel would do in this case - } - return getSheetName(internalSheetIndex); - } - - public ExternalSheet getExternalSheet(int externSheetIndex) { - String[] extNames = linkTable.getExternalBookAndSheetName(externSheetIndex); - if (extNames == null) { - return null; - } - if (extNames.length == 2) { - return new ExternalSheet(extNames[0], extNames[1]); - } else { - return new ExternalSheetRange(extNames[0], extNames[1], extNames[2]); - } - } - public ExternalName getExternalName(int externSheetIndex, int externNameIndex) { - String nameName = linkTable.resolveNameXText(externSheetIndex, externNameIndex, this); - if(nameName == null) { - return null; - } - int ix = linkTable.resolveNameXIx(externSheetIndex, externNameIndex); - return new ExternalName(nameName, externNameIndex, ix); - } - - /** - * Finds the (first) sheet index for a particular external sheet number. - * @param externSheetNumber The external sheet number to convert - * @return The index to the sheet found. - */ - public int getFirstSheetIndexFromExternSheetIndex(int externSheetNumber) - { - return linkTable.getFirstInternalSheetIndexForExtIndex(externSheetNumber); - } - - /** - * Finds the last sheet index for a particular external sheet number, - * which may be the same as the first (except for multi-sheet references) - * @param externSheetNumber The external sheet number to convert - * @return The index to the sheet found. - */ - public int getLastSheetIndexFromExternSheetIndex(int externSheetNumber) - { - return linkTable.getLastInternalSheetIndexForExtIndex(externSheetNumber); - } - - /** - * Returns the extern sheet number for specific sheet number. - * If this sheet doesn't exist in extern sheet, add it - * @param sheetNumber local sheet number - * @return index to extern sheet - */ - public short checkExternSheet(int sheetNumber){ - return (short)getOrCreateLinkTable().checkExternSheet(sheetNumber); - } - /** - * Returns the extern sheet number for specific range of sheets. - * If this sheet range doesn't exist in extern sheet, add it - * @param firstSheetNumber first local sheet number - * @param lastSheetNumber last local sheet number - * @return index to extern sheet - */ - public short checkExternSheet(int firstSheetNumber, int lastSheetNumber){ - return (short)getOrCreateLinkTable().checkExternSheet(firstSheetNumber, lastSheetNumber); - } - - public int getExternalSheetIndex(String workbookName, String sheetName) { - return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName, sheetName); - } - public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) { - return getOrCreateLinkTable().getExternalSheetIndex(workbookName, firstSheetName, lastSheetName); - } - - - /** gets the total number of names - * @return number of names - */ - public int getNumNames(){ - if(linkTable == null) { - return 0; - } - return linkTable.getNumNames(); - } - - /** - * gets the name record - * @param index name index - * @return name record - */ - public NameRecord getNameRecord(int index){ - return linkTable.getNameRecord(index); - } - - /** - * gets the name comment record - * @param nameRecord name record who's comment is required. - * @return name comment record or null if there isn't one for the given name. - */ - public NameCommentRecord getNameCommentRecord(final NameRecord nameRecord){ - return commentRecords.get(nameRecord.getNameText()); - } - - /** - * creates new name - * @return new name record - */ - public NameRecord createName(){ - return addName(new NameRecord()); - } - - - /** - * adds a name record - * - * @param name the name record to be added - * @return the given name record - */ - public NameRecord addName(NameRecord name) - { - - LinkTable linkTable = getOrCreateLinkTable(); - linkTable.addName(name); - - return name; - } - - /** - * Generates a NameRecord to represent a built-in region - * - * @param builtInName the built-in name - * @param sheetNumber the sheet number - * - * @return a new NameRecord - */ - public NameRecord createBuiltInName(byte builtInName, int sheetNumber) { - if (sheetNumber < 0 || sheetNumber+1 > Short.MAX_VALUE) { - throw new IllegalArgumentException("Sheet number ["+sheetNumber+"]is not valid "); - } - - NameRecord name = new NameRecord(builtInName, sheetNumber); - - if(linkTable.nameAlreadyExists(name)) { - throw new RuntimeException("Builtin (" + builtInName - + ") already exists for sheet (" + sheetNumber + ")"); - } - addName(name); - return name; - } - - - /** removes the name - * @param nameIndex name index - */ - public void removeName(int nameIndex){ - - if (linkTable.getNumNames() > nameIndex) { - int idx = findFirstRecordLocBySid(NameRecord.sid); - records.remove(idx + nameIndex); - linkTable.removeName(nameIndex); - } - } - - /** - * If a {@link NameCommentRecord} is added or the name it references - * is renamed, then this will update the lookup cache for it. - * - * @param commentRecord the comment record - */ - public void updateNameCommentRecordCache(final NameCommentRecord commentRecord) { - if(commentRecords.containsValue(commentRecord)) { - for(Entry entry : commentRecords.entrySet()) { - if(entry.getValue().equals(commentRecord)) { - commentRecords.remove(entry.getKey()); - break; - } - } - } - commentRecords.put(commentRecord.getNameText(), commentRecord); - } - - /** - * Returns a format index that matches the passed in format. It does not tie into HSSFDataFormat. - * @param format the format string - * @param createIfNotFound creates a new format if format not found - * @return the format id of a format that matches or -1 if none found and createIfNotFound - */ - public short getFormat(String format, boolean createIfNotFound) { - for (FormatRecord r : formats) { - if (r.getFormatString().equals(format)) { - return (short)r.getIndexCode(); - } - } - - if (createIfNotFound) { - return (short)createFormat(format); - } - - return -1; - } - - /** - * Returns the list of FormatRecords in the workbook. - * @return ArrayList of FormatRecords in the notebook - */ - public List getFormats() { - return formats; - } - - /** - * Creates a FormatRecord, inserts it, and returns the index code. - * @param formatString the format string - * @return the index code of the format record. - * @see org.apache.poi.hssf.record.FormatRecord - * @see org.apache.poi.hssf.record.Record - */ - public int createFormat(String formatString) { - - maxformatid = maxformatid >= 0xa4 ? maxformatid + 1 : 0xa4; //Starting value from M$ empircal study. - FormatRecord rec = new FormatRecord(maxformatid, formatString); - - int pos = 0; - while ( pos < records.size() && records.get( pos ).getSid() != FormatRecord.sid ) - pos++; - pos += formats.size(); - formats.add( rec ); - records.add( pos, rec ); - return maxformatid; - } - - - - /** - * Returns the first occurance of a record matching a particular sid. - * - * @param sid the sid - * - * @return the matching record or {@code null} if it wasn't found - */ - public Record findFirstRecordBySid(short sid) { - for (Record record : records) { - if (record.getSid() == sid) { - return record; - } - } - return null; - } - - /** - * Returns the index of a record matching a particular sid. - * @param sid The sid of the record to match - * @return The index of -1 if no match made. - */ - public int findFirstRecordLocBySid(short sid) { - int index = 0; - for (Record record : records) { - if (record.getSid() == sid) { - return index; - } - index ++; - } - return -1; - } - - /** - * Returns the next occurance of a record matching a particular sid. - * - * @param sid the sid - * @param pos specifies the n-th matching sid - * - * @return the matching record or {@code null} if it wasn't found - */ - public Record findNextRecordBySid(short sid, int pos) { - int matches = 0; - for (Record record : records) { - if (record.getSid() == sid) { - if (matches++ == pos) - return record; - } - } - return null; - } - - public List getHyperlinks() - { - return hyperlinks; - } - - public List getRecords() { - return records.getRecords(); - } - - /** - * Whether date windowing is based on 1/2/1904 or 1/1/1900. - * Some versions of Excel (Mac) can save workbooks using 1904 date windowing. - * - * @return true if using 1904 date windowing - */ - public boolean isUsing1904DateWindowing() { - return uses1904datewindowing; - } - - /** - * Returns the custom palette in use for this workbook; if a custom palette record - * does not exist, then it is created. - * - * @return the custom palette - */ - public PaletteRecord getCustomPalette() - { - PaletteRecord palette; - int palettePos = records.getPalettepos(); - if (palettePos != -1) { - Record rec = records.get(palettePos); - if (rec instanceof PaletteRecord) { - palette = (PaletteRecord) rec; - } else throw new RuntimeException("InternalError: Expected PaletteRecord but got a '"+rec+"'"); - } - else - { - palette = createPalette(); - //Add the palette record after the bof which is always the first record - records.add(1, palette); - records.setPalettepos(1); - } - return palette; - } - - /** - * Finds the primary drawing group, if one already exists - * - * @return the primary drawing group - */ - public DrawingManager2 findDrawingGroup() { - if(drawingManager != null) { - // We already have it! - return drawingManager; - } - - // Need to find a DrawingGroupRecord that - // contains a EscherDggRecord - for(Record r : records) { - if(r instanceof DrawingGroupRecord) { - DrawingGroupRecord dg = (DrawingGroupRecord)r; - dg.processChildRecords(); - - EscherContainerRecord cr = - dg.getEscherContainer(); - if(cr == null) { - continue; - } - - EscherDggRecord dgg = null; - EscherContainerRecord bStore = null; - for(Iterator it = cr.getChildIterator(); it.hasNext();) { - EscherRecord er = it.next(); - if(er instanceof EscherDggRecord) { - dgg = (EscherDggRecord)er; - } else if (er.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER) { - bStore = (EscherContainerRecord) er; - } - } - - if(dgg != null) { - drawingManager = new DrawingManager2(dgg); - if(bStore != null){ - for(EscherRecord bs : bStore.getChildRecords()){ - if(bs instanceof EscherBSERecord) escherBSERecords.add((EscherBSERecord)bs); - } - } - return drawingManager; - } - } - } - - // Look for the DrawingGroup record - int dgLoc = findFirstRecordLocBySid(DrawingGroupRecord.sid); - - // If there is one, does it have a EscherDggRecord? - if(dgLoc != -1) { - DrawingGroupRecord dg = (DrawingGroupRecord)records.get(dgLoc); - EscherDggRecord dgg = null; - EscherContainerRecord bStore = null; - for(EscherRecord er : dg.getEscherRecords()) { - if (er instanceof EscherDggRecord) { - dgg = (EscherDggRecord) er; - } else if (er.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER) { - bStore = (EscherContainerRecord) er; - } - } - - if(dgg != null) { - drawingManager = new DrawingManager2(dgg); - if(bStore != null){ - for(EscherRecord bs : bStore.getChildRecords()){ - if(bs instanceof EscherBSERecord) escherBSERecords.add((EscherBSERecord)bs); - } - } - } - } - return drawingManager; - } - - /** - * Creates a primary drawing group record. If it already - * exists then it's modified. - */ - public void createDrawingGroup() { - if (drawingManager == null) { - EscherContainerRecord dggContainer = new EscherContainerRecord(); - EscherDggRecord dgg = new EscherDggRecord(); - EscherOptRecord opt = new EscherOptRecord(); - EscherSplitMenuColorsRecord splitMenuColors = new EscherSplitMenuColorsRecord(); - - dggContainer.setRecordId((short) 0xF000); - dggContainer.setOptions((short) 0x000F); - dgg.setRecordId(EscherDggRecord.RECORD_ID); - dgg.setOptions((short)0x0000); - dgg.setShapeIdMax(1024); - dgg.setNumShapesSaved(0); - dgg.setDrawingsSaved(0); - dgg.setFileIdClusters(new EscherDggRecord.FileIdCluster[] {} ); - drawingManager = new DrawingManager2(dgg); - EscherContainerRecord bstoreContainer = null; - if (escherBSERecords.size() > 0) - { - bstoreContainer = new EscherContainerRecord(); - bstoreContainer.setRecordId( EscherContainerRecord.BSTORE_CONTAINER ); - bstoreContainer.setOptions( (short) ( (escherBSERecords.size() << 4) | 0xF ) ); - for (EscherRecord escherRecord : escherBSERecords) { - bstoreContainer.addChildRecord( escherRecord ); - } - } - opt.setRecordId((short) 0xF00B); - opt.setOptions((short) 0x0033); - opt.addEscherProperty( new EscherBoolProperty(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 524296) ); - opt.addEscherProperty( new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, 0x08000041) ); - opt.addEscherProperty( new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, 134217792) ); - splitMenuColors.setRecordId((short) 0xF11E); - splitMenuColors.setOptions((short) 0x0040); - splitMenuColors.setColor1(0x0800000D); - splitMenuColors.setColor2(0x0800000C); - splitMenuColors.setColor3(0x08000017); - splitMenuColors.setColor4(0x100000F7); - - dggContainer.addChildRecord(dgg); - if (bstoreContainer != null) - dggContainer.addChildRecord( bstoreContainer ); - dggContainer.addChildRecord(opt); - dggContainer.addChildRecord(splitMenuColors); - - int dgLoc = findFirstRecordLocBySid(DrawingGroupRecord.sid); - if (dgLoc == -1) { - DrawingGroupRecord drawingGroup = new DrawingGroupRecord(); - drawingGroup.addEscherRecord(dggContainer); - int loc = findFirstRecordLocBySid(CountryRecord.sid); - - getRecords().add(loc+1, drawingGroup); - } else { - DrawingGroupRecord drawingGroup = new DrawingGroupRecord(); - drawingGroup.addEscherRecord(dggContainer); - getRecords().set(dgLoc, drawingGroup); - } - - } - } - - public WindowOneRecord getWindowOne() { - return windowOne; - } - - public EscherBSERecord getBSERecord(int pictureIndex) { - return escherBSERecords.get(pictureIndex-1); - } - - public int addBSERecord(EscherBSERecord e) { - createDrawingGroup(); - - // maybe we don't need that as an instance variable anymore - escherBSERecords.add( e ); - - int dgLoc = findFirstRecordLocBySid(DrawingGroupRecord.sid); - DrawingGroupRecord drawingGroup = (DrawingGroupRecord) getRecords().get( dgLoc ); - - EscherContainerRecord dggContainer = (EscherContainerRecord) drawingGroup.getEscherRecord( 0 ); - EscherContainerRecord bstoreContainer; - if (dggContainer.getChild( 1 ).getRecordId() == EscherContainerRecord.BSTORE_CONTAINER ) - { - bstoreContainer = (EscherContainerRecord) dggContainer.getChild( 1 ); - } - else - { - bstoreContainer = new EscherContainerRecord(); - bstoreContainer.setRecordId( EscherContainerRecord.BSTORE_CONTAINER ); - List childRecords = dggContainer.getChildRecords(); - childRecords.add(1, bstoreContainer); - dggContainer.setChildRecords(childRecords); - } - bstoreContainer.setOptions( (short) ( (escherBSERecords.size() << 4) | 0xF ) ); - - bstoreContainer.addChildRecord( e ); - - return escherBSERecords.size(); - } - - public DrawingManager2 getDrawingManager() - { - return drawingManager; - } - - public WriteProtectRecord getWriteProtect() { - if (writeProtect == null) { - writeProtect = new WriteProtectRecord(); - int i = 0; - for (i = 0; - i < records.size() && !(records.get(i) instanceof BOFRecord); - i++) { - } - records.add(i+1, writeProtect); - } - return this.writeProtect; - } - - public WriteAccessRecord getWriteAccess() { - if (writeAccess == null) { - writeAccess = createWriteAccess(); - int i = 0; - for (i = 0; - i < records.size() && !(records.get(i) instanceof InterfaceEndRecord); - i++) { - } - records.add(i+1, writeAccess); - } - return writeAccess; - } - - public FileSharingRecord getFileSharing() { - if (fileShare == null) { - fileShare = new FileSharingRecord(); - int i = 0; - for (i = 0; - i < records.size() && !(records.get(i) instanceof WriteAccessRecord); - i++) { - } - records.add(i+1, fileShare); - } - return fileShare; - } - - /** - * is the workbook protected with a password (not encrypted)? - * - * @return {@code true} if the workbook is write protected - */ - public boolean isWriteProtected() { - if (fileShare == null) { - return false; - } - FileSharingRecord frec = getFileSharing(); - return frec.getReadOnly() == 1; - } - - /** - * protect a workbook with a password (not encypted, just sets writeprotect - * flags and the password. - * - * @param password the password - * @param username the username - */ - public void writeProtectWorkbook( String password, String username ) { - FileSharingRecord frec = getFileSharing(); - WriteAccessRecord waccess = getWriteAccess(); - /* WriteProtectRecord wprotect =*/ getWriteProtect(); - frec.setReadOnly((short)1); - frec.setPassword((short)CryptoFunctions.createXorVerifier1(password)); - frec.setUsername(username); - waccess.setUsername(username); - } - - /** - * removes the write protect flag - */ - public void unwriteProtectWorkbook() { - records.remove(fileShare); - records.remove(writeProtect); - fileShare = null; - writeProtect = null; - } - - /** - * @param refIndex Index to REF entry in EXTERNSHEET record in the Link Table - * @param definedNameIndex zero-based to DEFINEDNAME or EXTERNALNAME record - * @return the string representation of the defined or external name - */ - public String resolveNameXText(int refIndex, int definedNameIndex) { - return linkTable.resolveNameXText(refIndex, definedNameIndex, this); - } - - /** - * - * @param name the name of an external function, typically a name of a UDF - * @param sheetRefIndex the sheet ref index, or -1 if not known - * @param udf locator of user-defiend functions to resolve names of VBA and Add-In functions - * @return the external name or null - */ - public NameXPtg getNameXPtg(String name, int sheetRefIndex, UDFFinder udf) { - LinkTable lnk = getOrCreateLinkTable(); - NameXPtg xptg = lnk.getNameXPtg(name, sheetRefIndex); - - if(xptg == null && udf.findFunction(name) != null) { - // the name was not found in the list of external names - // check if the Workbook's UDFFinder is aware about it and register the name if it is - xptg = lnk.addNameXPtg(name); - } - return xptg; - } - public NameXPtg getNameXPtg(String name, UDFFinder udf) { - return getNameXPtg(name, -1, udf); - } - - /** - * Check if the cloned sheet has drawings. If yes, then allocate a new drawing group ID and - * re-generate shape IDs - * - * @param sheet the cloned sheet - */ - public void cloneDrawings(InternalSheet sheet){ - - findDrawingGroup(); - - if(drawingManager == null) { - //this workbook does not have drawings - return; - } - - //check if the cloned sheet has drawings - int aggLoc = sheet.aggregateDrawingRecords(drawingManager, false); - if(aggLoc != -1) { - EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid); - EscherContainerRecord escherContainer = agg.getEscherContainer(); - if (escherContainer == null) { - return; - } - - EscherDggRecord dgg = drawingManager.getDgg(); - - //register a new drawing group for the cloned sheet - int dgId = drawingManager.findNewDrawingGroupId(); - dgg.addCluster( dgId, 0 ); - dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1); - - EscherDgRecord dg = null; - for(Iterator it = escherContainer.getChildIterator(); it.hasNext();) { - EscherRecord er = it.next(); - if(er instanceof EscherDgRecord) { - dg = (EscherDgRecord)er; - //update id of the drawing in the cloned sheet - dg.setOptions( (short) ( dgId << 4 ) ); - } else if (er instanceof EscherContainerRecord){ - // iterate over shapes and re-generate shapeId - EscherContainerRecord cp = (EscherContainerRecord)er; - for(Iterator spIt = cp.getChildRecords().iterator(); spIt.hasNext();) { - EscherContainerRecord shapeContainer = (EscherContainerRecord)spIt.next(); - for(EscherRecord shapeChildRecord : shapeContainer.getChildRecords()) { - int recordId = shapeChildRecord.getRecordId(); - if (recordId == EscherSpRecord.RECORD_ID){ - EscherSpRecord sp = (EscherSpRecord)shapeChildRecord; - int shapeId = drawingManager.allocateShapeId((short)dgId, dg); - //allocateShapeId increments the number of shapes. roll back to the previous value - dg.setNumShapes(dg.getNumShapes()-1); - sp.setShapeId(shapeId); - } else if (recordId == EscherOptRecord.RECORD_ID){ - EscherOptRecord opt = (EscherOptRecord)shapeChildRecord; - EscherSimpleProperty prop = (EscherSimpleProperty)opt.lookup( - EscherProperties.BLIP__BLIPTODISPLAY ); - if (prop != null){ - int pictureIndex = prop.getPropertyValue(); - // increment reference count for pictures - EscherBSERecord bse = getBSERecord(pictureIndex); - bse.setRef(bse.getRef() + 1); - } - - } - } - } - } - } - } - } - - public NameRecord cloneFilter(int filterDbNameIndex, int newSheetIndex){ - NameRecord origNameRecord = getNameRecord(filterDbNameIndex); - // copy original formula but adjust 3D refs to the new external sheet index - int newExtSheetIx = checkExternSheet(newSheetIndex); - Ptg[] ptgs = origNameRecord.getNameDefinition(); - for (int i=0; i< ptgs.length; i++) { - Ptg ptg = ptgs[i]; - - if (ptg instanceof Area3DPtg) { - Area3DPtg a3p = (Area3DPtg) ((OperandPtg) ptg).copy(); - a3p.setExternSheetIndex(newExtSheetIx); - ptgs[i] = a3p; - } else if (ptg instanceof Ref3DPtg) { - Ref3DPtg r3p = (Ref3DPtg) ((OperandPtg) ptg).copy(); - r3p.setExternSheetIndex(newExtSheetIx); - ptgs[i] = r3p; - } - } - NameRecord newNameRecord = createBuiltInName(NameRecord.BUILTIN_FILTER_DB, newSheetIndex+1); - newNameRecord.setNameDefinition(ptgs); - newNameRecord.setHidden(true); - return newNameRecord; - - } - /** - * Updates named ranges due to moving of cells - * - * @param shifter the formula shifter - */ - public void updateNamesAfterCellShift(FormulaShifter shifter) { - for (int i = 0 ; i < getNumNames() ; ++i){ - NameRecord nr = getNameRecord(i); - Ptg[] ptgs = nr.getNameDefinition(); - if (shifter.adjustFormula(ptgs, nr.getSheetNumber())) { - nr.setNameDefinition(ptgs); - } - } - } - - /** - * Get or create RecalcIdRecord - * - * @return a new RecalcIdRecord - * - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#setForceFormulaRecalculation(boolean) - */ - public RecalcIdRecord getRecalcId(){ - RecalcIdRecord record = (RecalcIdRecord)findFirstRecordBySid(RecalcIdRecord.sid); - if(record == null){ - record = new RecalcIdRecord(); - // typically goes after the Country record - int pos = findFirstRecordLocBySid(CountryRecord.sid); - records.add(pos + 1, record); - } - return record; - } - - - /** - * Changes an external referenced file to another file. - * A formular in Excel which refers a cell in another file is saved in two parts: - * The referenced file is stored in an reference table. the row/cell information is saved separate. - * This method invokation will only change the reference in the lookup-table itself. - * @param oldUrl The old URL to search for and which is to be replaced - * @param newUrl The URL replacement - * @return true if the oldUrl was found and replaced with newUrl. Otherwise false - */ - public boolean changeExternalReference(String oldUrl, String newUrl) { - return linkTable.changeExternalReference(oldUrl, newUrl); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java b/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java deleted file mode 100644 index f6f75692c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java +++ /dev/null @@ -1,690 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.poi.hssf.record.CRNCountRecord; -import org.apache.poi.hssf.record.CRNRecord; -import org.apache.poi.hssf.record.CountryRecord; -import org.apache.poi.hssf.record.ExternSheetRecord; -import org.apache.poi.hssf.record.ExternalNameRecord; -import org.apache.poi.hssf.record.NameCommentRecord; -import org.apache.poi.hssf.record.NameRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SupBookRecord; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.ErrPtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * Link Table (OOO pdf reference: 4.10.3 )

    - * - * The main data of all types of references is stored in the Link Table inside the Workbook Globals - * Substream (4.2.5). The Link Table itself is optional and occurs only if there are any - * references in the document. - *

    - * - * In BIFF8 the Link Table consists of - *

      - *
    • zero or more EXTERNALBOOK Blocks

      - * each consisting of - *

        - *
      • exactly one EXTERNALBOOK (0x01AE) record
      • - *
      • zero or more EXTERNALNAME (0x0023) records
      • - *
      • zero or more CRN Blocks

        - * each consisting of - *

          - *
        • exactly one XCT (0x0059)record
        • - *
        • zero or more CRN (0x005A) records (documentation says one or more)
        • - *
        - *
      • - *
      - *
    • - *
    • zero or one EXTERNSHEET (0x0017) record
    • - *
    • zero or more DEFINEDNAME (0x0018) records
    • - *
    - */ -final class LinkTable { - - // TODO make this class into a record aggregate - private static final class CRNBlock { - - private final CRNCountRecord _countRecord; - private final CRNRecord[] _crns; - - public CRNBlock(RecordStream rs) { - _countRecord = (CRNCountRecord) rs.getNext(); - int nCRNs = _countRecord.getNumberOfCRNs(); - CRNRecord[] crns = new CRNRecord[nCRNs]; - for (int i = 0; i < crns.length; i++) { - crns[i] = (CRNRecord) rs.getNext(); - } - _crns = crns; - } - public CRNRecord[] getCrns() { - return _crns.clone(); - } - } - - private static final class ExternalBookBlock { - private final SupBookRecord _externalBookRecord; - private ExternalNameRecord[] _externalNameRecords; - private final CRNBlock[] _crnBlocks; - - public ExternalBookBlock(RecordStream rs) { - _externalBookRecord = (SupBookRecord) rs.getNext(); - List temp = new ArrayList(); - while(rs.peekNextClass() == ExternalNameRecord.class) { - temp.add(rs.getNext()); - } - _externalNameRecords = new ExternalNameRecord[temp.size()]; - temp.toArray(_externalNameRecords); - - temp.clear(); - - while(rs.peekNextClass() == CRNCountRecord.class) { - temp.add(new CRNBlock(rs)); - } - _crnBlocks = new CRNBlock[temp.size()]; - temp.toArray(_crnBlocks); - } - - /** - * Create a new block for external references. - */ - public ExternalBookBlock(String url, String[] sheetNames) { - _externalBookRecord = SupBookRecord.createExternalReferences(url, sheetNames); - _crnBlocks = new CRNBlock[0]; - } - - /** - * Create a new block for internal references. It is called when constructing a new LinkTable. - * - * @see org.apache.poi.hssf.model.LinkTable#LinkTable(int, WorkbookRecordList) - */ - public ExternalBookBlock(int numberOfSheets) { - _externalBookRecord = SupBookRecord.createInternalReferences((short)numberOfSheets); - _externalNameRecords = new ExternalNameRecord[0]; - _crnBlocks = new CRNBlock[0]; - } - - /** - * Create a new block for registering add-in functions - * - * @see org.apache.poi.hssf.model.LinkTable#addNameXPtg(String) - */ - public ExternalBookBlock() { - _externalBookRecord = SupBookRecord.createAddInFunctions(); - _externalNameRecords = new ExternalNameRecord[0]; - _crnBlocks = new CRNBlock[0]; - } - - public SupBookRecord getExternalBookRecord() { - return _externalBookRecord; - } - - public String getNameText(int definedNameIndex) { - return _externalNameRecords[definedNameIndex].getText(); - } - - public int getNameIx(int definedNameIndex) { - return _externalNameRecords[definedNameIndex].getIx(); - } - - /** - * Performs case-insensitive search - * @return -1 if not found - */ - public int getIndexOfName(String name) { - for (int i = 0; i < _externalNameRecords.length; i++) { - if(_externalNameRecords[i].getText().equalsIgnoreCase(name)) { - return i; - } - } - return -1; - } - - public int getNumberOfNames() { - return _externalNameRecords.length; - } - - public int addExternalName(ExternalNameRecord rec){ - ExternalNameRecord[] tmp = new ExternalNameRecord[_externalNameRecords.length + 1]; - System.arraycopy(_externalNameRecords, 0, tmp, 0, _externalNameRecords.length); - tmp[tmp.length - 1] = rec; - _externalNameRecords = tmp; - return _externalNameRecords.length - 1; - } - } - - private ExternalBookBlock[] _externalBookBlocks; - private final ExternSheetRecord _externSheetRecord; - private final List _definedNames; - private final int _recordCount; - private final WorkbookRecordList _workbookRecordList; // TODO - would be nice to remove this - - public LinkTable(List inputList, int startIndex, WorkbookRecordList workbookRecordList, Map commentRecords) { - - _workbookRecordList = workbookRecordList; - RecordStream rs = new RecordStream(inputList, startIndex); - - List temp = new ArrayList(); - while(rs.peekNextClass() == SupBookRecord.class) { - temp.add(new ExternalBookBlock(rs)); - } - - _externalBookBlocks = new ExternalBookBlock[temp.size()]; - temp.toArray(_externalBookBlocks); - temp.clear(); - - if (_externalBookBlocks.length > 0) { - // If any ExternalBookBlock present, there is always 1 of ExternSheetRecord - if (rs.peekNextClass() != ExternSheetRecord.class) { - // not quite - if written by google docs - _externSheetRecord = null; - } else { - _externSheetRecord = readExtSheetRecord(rs); - } - } else { - _externSheetRecord = null; - } - - _definedNames = new ArrayList(); - // collect zero or more DEFINEDNAMEs id=0x18, - // with their comments if present - while(true) { - Class nextClass = rs.peekNextClass(); - if (nextClass == NameRecord.class) { - NameRecord nr = (NameRecord)rs.getNext(); - _definedNames.add(nr); - } - else if (nextClass == NameCommentRecord.class) { - NameCommentRecord ncr = (NameCommentRecord)rs.getNext(); - commentRecords.put(ncr.getNameText(), ncr); - } - else { - break; - } - } - - _recordCount = rs.getCountRead(); - _workbookRecordList.getRecords().addAll(inputList.subList(startIndex, startIndex + _recordCount)); - } - - private static ExternSheetRecord readExtSheetRecord(RecordStream rs) { - List temp = new ArrayList(2); - while(rs.peekNextClass() == ExternSheetRecord.class) { - temp.add((ExternSheetRecord) rs.getNext()); - } - - int nItems = temp.size(); - if (nItems < 1) { - throw new RuntimeException("Expected an EXTERNSHEET record but got (" - + rs.peekNextClass().getName() + ")"); - } - if (nItems == 1) { - // this is the normal case. There should be just one ExternSheetRecord - return temp.get(0); - } - // Some apps generate multiple ExternSheetRecords (see bug 45698). - // It seems like the best thing to do might be to combine these into one - ExternSheetRecord[] esrs = new ExternSheetRecord[nItems]; - temp.toArray(esrs); - return ExternSheetRecord.combine(esrs); - } - - public LinkTable(int numberOfSheets, WorkbookRecordList workbookRecordList) { - _workbookRecordList = workbookRecordList; - _definedNames = new ArrayList(); - _externalBookBlocks = new ExternalBookBlock[] { - new ExternalBookBlock(numberOfSheets), - }; - _externSheetRecord = new ExternSheetRecord(); - _recordCount = 2; - - // tell _workbookRecordList about the 2 new records - - SupBookRecord supbook = _externalBookBlocks[0].getExternalBookRecord(); - - int idx = findFirstRecordLocBySid(CountryRecord.sid); - if(idx < 0) { - throw new RuntimeException("CountryRecord not found"); - } - _workbookRecordList.add(idx+1, _externSheetRecord); - _workbookRecordList.add(idx+1, supbook); - } - - /** - * TODO - would not be required if calling code used RecordStream or similar - */ - public int getRecordCount() { - return _recordCount; - } - - - /** - * @param builtInCode a BUILTIN_~ constant from {@link NameRecord} - * @param sheetNumber 1-based sheet number - */ - public NameRecord getSpecificBuiltinRecord(byte builtInCode, int sheetNumber) { - Iterator iterator = _definedNames.iterator(); - while (iterator.hasNext()) { - NameRecord record = iterator.next(); - - //print areas are one based - if (record.getBuiltInName() == builtInCode && record.getSheetNumber() == sheetNumber) { - return record; - } - } - - return null; - } - - public void removeBuiltinRecord(byte name, int sheetIndex) { - //the name array is smaller so searching through it should be faster than - //using the findFirstXXXX methods - NameRecord record = getSpecificBuiltinRecord(name, sheetIndex); - if (record != null) { - _definedNames.remove(record); - } - // TODO - do we need "Workbook.records.remove(...);" similar to that in Workbook.removeName(int namenum) {}? - } - - public int getNumNames() { - return _definedNames.size(); - } - - public NameRecord getNameRecord(int index) { - return _definedNames.get(index); - } - - public void addName(NameRecord name) { - _definedNames.add(name); - - // TODO - this is messy - // Not the most efficient way but the other way was causing too many bugs - int idx = findFirstRecordLocBySid(ExternSheetRecord.sid); - if (idx == -1) idx = findFirstRecordLocBySid(SupBookRecord.sid); - if (idx == -1) idx = findFirstRecordLocBySid(CountryRecord.sid); - int countNames = _definedNames.size(); - _workbookRecordList.add(idx+countNames, name); - } - - public void removeName(int namenum) { - _definedNames.remove(namenum); - } - - /** - * checks if the given name is already included in the linkTable - */ - public boolean nameAlreadyExists(NameRecord name) - { - // Check to ensure no other names have the same case-insensitive name - for ( int i = getNumNames()-1; i >=0; i-- ) { - NameRecord rec = getNameRecord(i); - if (rec != name) { - if (isDuplicatedNames(name, rec)) - return true; - } - } - return false; - } - - private static boolean isDuplicatedNames(NameRecord firstName, NameRecord lastName) { - return lastName.getNameText().equalsIgnoreCase(firstName.getNameText()) - && isSameSheetNames(firstName, lastName); - } - private static boolean isSameSheetNames(NameRecord firstName, NameRecord lastName) { - return lastName.getSheetNumber() == firstName.getSheetNumber(); - } - - public String[] getExternalBookAndSheetName(int extRefIndex) { - int ebIx = _externSheetRecord.getExtbookIndexFromRefIndex(extRefIndex); - SupBookRecord ebr = _externalBookBlocks[ebIx].getExternalBookRecord(); - if (!ebr.isExternalReferences()) { - return null; - } - // Sheet name only applies if not a global reference - int shIx1 = _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex); - int shIx2 = _externSheetRecord.getLastSheetIndexFromRefIndex(extRefIndex); - String firstSheetName = null; - String lastSheetName = null; - if(shIx1 >= 0) { - firstSheetName = ebr.getSheetNames()[shIx1]; - } - if (shIx2 >= 0) { - lastSheetName = ebr.getSheetNames()[shIx2]; - } - if (shIx1 == shIx2) { - return new String[] { - ebr.getURL(), - firstSheetName - }; - } else { - return new String[] { - ebr.getURL(), - firstSheetName, - lastSheetName - }; - } - } - - private int getExternalWorkbookIndex(String workbookName) { - for (int i=0; i<_externalBookBlocks.length; i++) { - SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord(); - if (!ebr.isExternalReferences()) { - continue; - } - if (workbookName.equals(ebr.getURL())) { // not sure if 'equals()' works when url has a directory - return i; - } - } - return -1; - } - - public int linkExternalWorkbook(String name, Workbook externalWorkbook) { - int extBookIndex = getExternalWorkbookIndex(name); - if (extBookIndex != -1) { - // Already linked! - return extBookIndex; - } - - // Create a new SupBookRecord - String[] sheetNames = new String[externalWorkbook.getNumberOfSheets()]; - for (int sn=0; sn= _externSheetRecord.getNumOfRefs() || extRefIndex < 0) { - return -1; - } - return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex); - } - /** - * @param extRefIndex as from a {@link Ref3DPtg} or {@link Area3DPtg} - * @return -1 if the reference is to an external book - */ - public int getLastInternalSheetIndexForExtIndex(int extRefIndex) { - if (extRefIndex >= _externSheetRecord.getNumOfRefs() || extRefIndex < 0) { - return -1; - } - return _externSheetRecord.getLastSheetIndexFromRefIndex(extRefIndex); - } - - public void removeSheet(int sheetIdx) { - _externSheetRecord.removeSheet(sheetIdx); - } - - public int checkExternSheet(int sheetIndex) { - return checkExternSheet(sheetIndex, sheetIndex); - } - public int checkExternSheet(int firstSheetIndex, int lastSheetIndex) { - int thisWbIndex = -1; // this is probably always zero - for (int i=0; i<_externalBookBlocks.length; i++) { - SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord(); - if (ebr.isInternalReferences()) { - thisWbIndex = i; - break; - } - } - if (thisWbIndex < 0) { - throw new RuntimeException("Could not find 'internal references' EXTERNALBOOK"); - } - - //Trying to find reference to this sheet - int i = _externSheetRecord.getRefIxForSheet(thisWbIndex, firstSheetIndex, lastSheetIndex); - if (i>=0) { - return i; - } - //We haven't found reference to this sheet - return _externSheetRecord.addRef(thisWbIndex, firstSheetIndex, lastSheetIndex); - } - - /** - * copied from Workbook - */ - private int findFirstRecordLocBySid(short sid) { - int index = 0; - for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); ) { - Record record = iterator.next(); - - if (record.getSid() == sid) { - return index; - } - index ++; - } - return -1; - } - - public String resolveNameXText(int refIndex, int definedNameIndex, InternalWorkbook workbook) { - int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex); - int firstTabIndex = _externSheetRecord.getFirstSheetIndexFromRefIndex(refIndex); - if (firstTabIndex == -1) { - // The referenced sheet could not be found - throw new RuntimeException("Referenced sheet could not be found"); - } - - // Does it exist via the external book block? - ExternalBookBlock externalBook = _externalBookBlocks[extBookIndex]; - if (externalBook._externalNameRecords.length > definedNameIndex) { - return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex); - } else if (firstTabIndex == -2) { - // Workbook scoped name, not actually external after all - NameRecord nr = getNameRecord(definedNameIndex); - int sheetNumber = nr.getSheetNumber(); - - StringBuffer text = new StringBuffer(); - if (sheetNumber > 0) { - String sheetName = workbook.getSheetName(sheetNumber-1); - SheetNameFormatter.appendFormat(text, sheetName); - text.append("!"); - } - text.append(nr.getNameText()); - return text.toString(); - } else { - throw new ArrayIndexOutOfBoundsException( - "Ext Book Index relative but beyond the supported length, was " + - extBookIndex + " but maximum is " + _externalBookBlocks.length - ); - } - } - public int resolveNameXIx(int refIndex, int definedNameIndex) { - int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex); - return _externalBookBlocks[extBookIndex].getNameIx(definedNameIndex); - } - - /** - * Finds the external name definition for the given name, - * optionally restricted by externsheet index, and returns - * (if found) as a NameXPtg. - * @param sheetRefIndex The Extern Sheet Index to look for, or -1 if any - */ - public NameXPtg getNameXPtg(String name, int sheetRefIndex) { - // first find any external book block that contains the name: - for (int i = 0; i < _externalBookBlocks.length; i++) { - int definedNameIndex = _externalBookBlocks[i].getIndexOfName(name); - if (definedNameIndex < 0) { - continue; - } - - // Found one - int thisSheetRefIndex = findRefIndexFromExtBookIndex(i); - if (thisSheetRefIndex >= 0) { - // Check for the sheet index match, if requested - if (sheetRefIndex == -1 || thisSheetRefIndex == sheetRefIndex) { - return new NameXPtg(thisSheetRefIndex, definedNameIndex); - } - } - } - return null; - } - - /** - * Register an external name in this workbook - * - * @param name the name to register - * @return a NameXPtg describing this name - */ - public NameXPtg addNameXPtg(String name) { - int extBlockIndex = -1; - ExternalBookBlock extBlock = null; - - // find ExternalBlock for Add-In functions and remember its index - for (int i = 0; i < _externalBookBlocks.length; i++) { - SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord(); - if (ebr.isAddInFunctions()) { - extBlock = _externalBookBlocks[i]; - extBlockIndex = i; - break; - } - } - // An ExternalBlock for Add-In functions was not found. Create a new one. - if (extBlock == null) { - extBlock = new ExternalBookBlock(); - extBlockIndex = extendExternalBookBlocks(extBlock); - - // add the created SupBookRecord before ExternSheetRecord - int idx = findFirstRecordLocBySid(ExternSheetRecord.sid); - _workbookRecordList.add(idx, extBlock.getExternalBookRecord()); - - // register the SupBookRecord in the ExternSheetRecord - // -2 means that the scope of this name is Workbook and the reference applies to the entire workbook. - _externSheetRecord.addRef(_externalBookBlocks.length - 1, -2, -2); - } - - // create a ExternalNameRecord that will describe this name - ExternalNameRecord extNameRecord = new ExternalNameRecord(); - extNameRecord.setText(name); - // The docs don't explain why Excel set the formula to #REF! - extNameRecord.setParsedExpression(new Ptg[]{ErrPtg.REF_INVALID}); - - int nameIndex = extBlock.addExternalName(extNameRecord); - int supLinkIndex = 0; - // find the posistion of the Add-In SupBookRecord in the workbook stream, - // the created ExternalNameRecord will be appended to it - for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) { - Record record = iterator.next(); - if (record instanceof SupBookRecord) { - if (((SupBookRecord) record).isAddInFunctions()) break; - } - } - int numberOfNames = extBlock.getNumberOfNames(); - // a new name is inserted in the end of the SupBookRecord, after the last name - _workbookRecordList.add(supLinkIndex + numberOfNames, extNameRecord); - int fakeSheetIdx = -2; /* the scope is workbook*/ - int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, fakeSheetIdx, fakeSheetIdx); - return new NameXPtg(ix, nameIndex); - } - private int extendExternalBookBlocks(ExternalBookBlock newBlock) { - ExternalBookBlock[] tmp = new ExternalBookBlock[_externalBookBlocks.length + 1]; - System.arraycopy(_externalBookBlocks, 0, tmp, 0, _externalBookBlocks.length); - tmp[tmp.length - 1] = newBlock; - _externalBookBlocks = tmp; - - return (_externalBookBlocks.length - 1); - } - - private int findRefIndexFromExtBookIndex(int extBookIndex) { - return _externSheetRecord.findRefIndexFromExtBookIndex(extBookIndex); - } - - /** - * Changes an external referenced file to another file. - * A formular in Excel which refers a cell in another file is saved in two parts: - * The referenced file is stored in an reference table. the row/cell information is saved separate. - * This method invokation will only change the reference in the lookup-table itself. - * @param oldUrl The old URL to search for and which is to be replaced - * @param newUrl The URL replacement - * @return true if the oldUrl was found and replaced with newUrl. Otherwise false - */ - public boolean changeExternalReference(String oldUrl, String newUrl) { - for(ExternalBookBlock ex : _externalBookBlocks) { - SupBookRecord externalRecord = ex.getExternalBookRecord(); - if (externalRecord.isExternalReferences() - && externalRecord.getURL().equals(oldUrl)) { - - externalRecord.setURL(newUrl); - return true; - } - } - return false; - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/RecordOrderer.java b/trunk/src/java/org/apache/poi/hssf/model/RecordOrderer.java deleted file mode 100644 index 9f1871cad..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/RecordOrderer.java +++ /dev/null @@ -1,458 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.util.List; - -import org.apache.poi.hssf.record.ArrayRecord; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.CalcCountRecord; -import org.apache.poi.hssf.record.CalcModeRecord; -import org.apache.poi.hssf.record.ColumnInfoRecord; -import org.apache.poi.hssf.record.DVALRecord; -import org.apache.poi.hssf.record.DateWindow1904Record; -import org.apache.poi.hssf.record.DefaultColWidthRecord; -import org.apache.poi.hssf.record.DefaultRowHeightRecord; -import org.apache.poi.hssf.record.DeltaRecord; -import org.apache.poi.hssf.record.DimensionsRecord; -import org.apache.poi.hssf.record.DrawingRecord; -import org.apache.poi.hssf.record.DrawingSelectionRecord; -import org.apache.poi.hssf.record.EOFRecord; -import org.apache.poi.hssf.record.FeatRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.GridsetRecord; -import org.apache.poi.hssf.record.GutsRecord; -import org.apache.poi.hssf.record.HyperlinkRecord; -import org.apache.poi.hssf.record.IndexRecord; -import org.apache.poi.hssf.record.IterationRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.ObjRecord; -import org.apache.poi.hssf.record.PaneRecord; -import org.apache.poi.hssf.record.PrecisionRecord; -import org.apache.poi.hssf.record.PrintGridlinesRecord; -import org.apache.poi.hssf.record.PrintHeadersRecord; -import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; -import org.apache.poi.hssf.record.RefModeRecord; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.SCLRecord; -import org.apache.poi.hssf.record.SaveRecalcRecord; -import org.apache.poi.hssf.record.SelectionRecord; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.TableRecord; -import org.apache.poi.hssf.record.TextObjectRecord; -import org.apache.poi.hssf.record.UncalcedRecord; -import org.apache.poi.hssf.record.UnknownRecord; -import org.apache.poi.hssf.record.WindowOneRecord; -import org.apache.poi.hssf.record.WindowTwoRecord; -import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; -import org.apache.poi.hssf.record.aggregates.DataValidityTable; -import org.apache.poi.hssf.record.aggregates.MergedCellsTable; -import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; -import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock; -import org.apache.poi.hssf.record.pivottable.ViewDefinitionRecord; - -/** - * Finds correct insert positions for records in workbook streams

    - * - * See OOO excelfileformat.pdf sec. 4.2.5 'Record Order in a BIFF8 Workbook Stream' - */ -final class RecordOrderer { - - // TODO - simplify logic using a generalised record ordering - - private RecordOrderer() { - // no instances of this class - } - /** - * Adds the specified new record in the correct place in sheet records list - */ - public static void addNewSheetRecord(List sheetRecords, RecordBase newRecord) { - int index = findSheetInsertPos(sheetRecords, newRecord.getClass()); - sheetRecords.add(index, newRecord); - } - - private static int findSheetInsertPos(List records, Class recClass) { - if (recClass == DataValidityTable.class) { - return findDataValidationTableInsertPos(records); - } - if (recClass == MergedCellsTable.class) { - return findInsertPosForNewMergedRecordTable(records); - } - if (recClass == ConditionalFormattingTable.class) { - return findInsertPosForNewCondFormatTable(records); - } - if (recClass == GutsRecord.class) { - return getGutsRecordInsertPos(records); - } - if (recClass == PageSettingsBlock.class) { - return getPageBreakRecordInsertPos(records); - } - if (recClass == WorksheetProtectionBlock.class) { - return getWorksheetProtectionBlockInsertPos(records); - } - throw new RuntimeException("Unexpected record class (" + recClass.getName() + ")"); - } - - /** - * Finds the index where the protection block should be inserted - * @param records the records for this sheet - *

    -	 * + BOF
    -	 * o INDEX
    -	 * o Calculation Settings Block
    -	 * o PRINTHEADERS
    -	 * o PRINTGRIDLINES
    -	 * o GRIDSET
    -	 * o GUTS
    -	 * o DEFAULTROWHEIGHT
    -	 * o SHEETPR
    -	 * o Page Settings Block
    -	 * o Worksheet Protection Block
    -	 * o DEFCOLWIDTH
    -	 * oo COLINFO
    -	 * o SORT
    -	 * + DIMENSION
    -	 * 
    - */ - private static int getWorksheetProtectionBlockInsertPos(List records) { - int i = getDimensionsIndex(records); - while (i > 0) { - i--; - Object rb = records.get(i); - if (!isProtectionSubsequentRecord(rb)) { - return i+1; - } - } - throw new IllegalStateException("did not find insert pos for protection block"); - } - - - /** - * These records may occur between the 'Worksheet Protection Block' and DIMENSION: - *
    -	 * o DEFCOLWIDTH
    -	 * oo COLINFO
    -	 * o SORT
    -	 * 
    - */ - private static boolean isProtectionSubsequentRecord(Object rb) { - if (rb instanceof ColumnInfoRecordsAggregate) { - return true; // oo COLINFO - } - if (rb instanceof Record) { - Record record = (Record) rb; - switch (record.getSid()) { - case DefaultColWidthRecord.sid: - case UnknownRecord.SORT_0090: - return true; - } - } - return false; - } - - private static int getPageBreakRecordInsertPos(List records) { - int dimensionsIndex = getDimensionsIndex(records); - int i = dimensionsIndex-1; - while (i > 0) { - i--; - Object rb = records.get(i); - if (isPageBreakPriorRecord(rb)) { - return i+1; - } - } - throw new RuntimeException("Did not find insert point for GUTS"); - } - private static boolean isPageBreakPriorRecord(Object rb) { - if (rb instanceof Record) { - Record record = (Record) rb; - switch (record.getSid()) { - case BOFRecord.sid: - case IndexRecord.sid: - // calc settings block - case UncalcedRecord.sid: - case CalcCountRecord.sid: - case CalcModeRecord.sid: - case PrecisionRecord.sid: - case RefModeRecord.sid: - case DeltaRecord.sid: - case IterationRecord.sid: - case DateWindow1904Record.sid: - case SaveRecalcRecord.sid: - // end calc settings - case PrintHeadersRecord.sid: - case PrintGridlinesRecord.sid: - case GridsetRecord.sid: - case DefaultRowHeightRecord.sid: - case UnknownRecord.SHEETPR_0081: - return true; - // next is the 'Worksheet Protection Block' - } - } - return false; - } - /** - * Find correct position to add new CFHeader record - */ - private static int findInsertPosForNewCondFormatTable(List records) { - - for (int i = records.size() - 2; i >= 0; i--) { // -2 to skip EOF record - Object rb = records.get(i); - if (rb instanceof MergedCellsTable) { - return i + 1; - } - if (rb instanceof DataValidityTable) { - continue; - } - - Record rec = (Record) rb; - switch (rec.getSid()) { - case WindowTwoRecord.sid: - case SCLRecord.sid: - case PaneRecord.sid: - case SelectionRecord.sid: - case UnknownRecord.STANDARDWIDTH_0099: - // MergedCellsTable usually here - case UnknownRecord.LABELRANGES_015F: - case UnknownRecord.PHONETICPR_00EF: - // ConditionalFormattingTable goes here - return i + 1; - // HyperlinkTable (not aggregated by POI yet) - // DataValidityTable - } - } - throw new RuntimeException("Did not find Window2 record"); - } - - private static int findInsertPosForNewMergedRecordTable(List records) { - for (int i = records.size() - 2; i >= 0; i--) { // -2 to skip EOF record - Object rb = records.get(i); - if (!(rb instanceof Record)) { - // DataValidityTable, ConditionalFormattingTable, - // even PageSettingsBlock (which doesn't normally appear after 'View Settings') - continue; - } - Record rec = (Record) rb; - switch (rec.getSid()) { - // 'View Settings' (4 records) - case WindowTwoRecord.sid: - case SCLRecord.sid: - case PaneRecord.sid: - case SelectionRecord.sid: - - case UnknownRecord.STANDARDWIDTH_0099: - return i + 1; - } - } - throw new RuntimeException("Did not find Window2 record"); - } - - - /** - * Finds the index where the sheet validations header record should be inserted - * @param records the records for this sheet - * - * + WINDOW2 - * o SCL - * o PANE - * oo SELECTION - * o STANDARDWIDTH - * oo MERGEDCELLS - * o LABELRANGES - * o PHONETICPR - * o Conditional Formatting Table - * o Hyperlink Table - * o Data Validity Table - * o SHEETLAYOUT - * o SHEETPROTECTION - * o RANGEPROTECTION - * + EOF - */ - private static int findDataValidationTableInsertPos(List records) { - int i = records.size() - 1; - if (!(records.get(i) instanceof EOFRecord)) { - throw new IllegalStateException("Last sheet record should be EOFRecord"); - } - while (i > 0) { - i--; - RecordBase rb = records.get(i); - if (isDVTPriorRecord(rb)) { - Record nextRec = (Record) records.get(i + 1); - if (!isDVTSubsequentRecord(nextRec.getSid())) { - throw new IllegalStateException("Unexpected (" + nextRec.getClass().getName() - + ") found after (" + rb.getClass().getName() + ")"); - } - return i+1; - } - Record rec = (Record) rb; - if (!isDVTSubsequentRecord(rec.getSid())) { - throw new IllegalStateException("Unexpected (" + rec.getClass().getName() - + ") while looking for DV Table insert pos"); - } - } - return 0; - } - - - private static boolean isDVTPriorRecord(RecordBase rb) { - if (rb instanceof MergedCellsTable || rb instanceof ConditionalFormattingTable) { - return true; - } - short sid = ((Record)rb).getSid(); - switch(sid) { - case WindowTwoRecord.sid: - case UnknownRecord.SCL_00A0: - case PaneRecord.sid: - case SelectionRecord.sid: - case UnknownRecord.STANDARDWIDTH_0099: - // MergedCellsTable - case UnknownRecord.LABELRANGES_015F: - case UnknownRecord.PHONETICPR_00EF: - // ConditionalFormattingTable - case HyperlinkRecord.sid: - case UnknownRecord.QUICKTIP_0800: - // name of a VBA module - case UnknownRecord.CODENAME_1BA: - return true; - } - return false; - } - - private static boolean isDVTSubsequentRecord(short sid) { - switch(sid) { - case UnknownRecord.SHEETEXT_0862: - case UnknownRecord.SHEETPROTECTION_0867: - case UnknownRecord.PLV_MAC: - case FeatRecord.sid: - case EOFRecord.sid: - return true; - } - return false; - } - /** - * DIMENSIONS record is always present - */ - private static int getDimensionsIndex(List records) { - int nRecs = records.size(); - for(int i=0; i records) { - int dimensionsIndex = getDimensionsIndex(records); - int i = dimensionsIndex-1; - while (i > 0) { - i--; - RecordBase rb = records.get(i); - if (isGutsPriorRecord(rb)) { - return i+1; - } - } - throw new RuntimeException("Did not find insert point for GUTS"); - } - - private static boolean isGutsPriorRecord(RecordBase rb) { - if (rb instanceof Record) { - Record record = (Record) rb; - switch (record.getSid()) { - case BOFRecord.sid: - case IndexRecord.sid: - // calc settings block - case UncalcedRecord.sid: - case CalcCountRecord.sid: - case CalcModeRecord.sid: - case PrecisionRecord.sid: - case RefModeRecord.sid: - case DeltaRecord.sid: - case IterationRecord.sid: - case DateWindow1904Record.sid: - case SaveRecalcRecord.sid: - // end calc settings - case PrintHeadersRecord.sid: - case PrintGridlinesRecord.sid: - case GridsetRecord.sid: - return true; - // DefaultRowHeightRecord.sid is next - } - } - return false; - } - /** - * @return true if the specified record ID terminates a sequence of Row block records - * It is assumed that at least one row or cell value record has been found prior to the current - * record - */ - public static boolean isEndOfRowBlock(int sid) { - switch(sid) { - case ViewDefinitionRecord.sid: - // should have been prefixed with DrawingRecord (0x00EC), but bug 46280 seems to allow this - case DrawingRecord.sid: - case DrawingSelectionRecord.sid: - case ObjRecord.sid: - case TextObjectRecord.sid: - case ColumnInfoRecord.sid: // See Bugzilla 53984 - case GutsRecord.sid: // see Bugzilla 50426 - case WindowOneRecord.sid: - // should really be part of workbook stream, but some apps seem to put this before WINDOW2 - case WindowTwoRecord.sid: - return true; - - case DVALRecord.sid: - return true; - case EOFRecord.sid: - // WINDOW2 should always be present, so shouldn't have got this far - throw new RuntimeException("Found EOFRecord before WindowTwoRecord was encountered"); - } - return PageSettingsBlock.isComponentRecord(sid); - } - - /** - * @return true if the specified record id normally appears in the row blocks section - * of the sheet records - */ - public static boolean isRowBlockRecord(int sid) { - switch (sid) { - case RowRecord.sid: - - case BlankRecord.sid: - case BoolErrRecord.sid: - case FormulaRecord.sid: - case LabelRecord.sid: - case LabelSSTRecord.sid: - case NumberRecord.sid: - case RKRecord.sid: - - case ArrayRecord.sid: - case SharedFormulaRecord.sid: - case TableRecord.sid: - return true; - } - return false; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java b/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java deleted file mode 100644 index 23c2d3d61..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.util.List; - -import org.apache.poi.hssf.record.Record; -/** - * Simplifies iteration over a sequence of Record objects. - */ -public final class RecordStream { - - private final List _list; - private int _nextIndex; - private int _countRead; - private final int _endIx; - - /** - * Creates a RecordStream bounded by startIndex and endIndex - * - * @param inputList the list to iterate over - * @param startIndex the start index within the list - * @param endIx the end index within the list, which is the index of the end element + 1 - */ - public RecordStream(List inputList, int startIndex, int endIx) { - _list = inputList; - _nextIndex = startIndex; - _endIx = endIx; - _countRead = 0; - } - - public RecordStream(List records, int startIx) { - this(records, startIx, records.size()); - } - - public boolean hasNext() { - return _nextIndex < _endIx; - } - - public Record getNext() { - if(!hasNext()) { - throw new RuntimeException("Attempt to read past end of record stream"); - } - _countRead ++; - return _list.get(_nextIndex++); - } - - /** - * @return the {@link Class} of the next Record. null if this stream is exhausted. - */ - public Class peekNextClass() { - if(!hasNext()) { - return null; - } - return _list.get(_nextIndex).getClass(); - } - - /** - * @return -1 if at end of records - */ - public int peekNextSid() { - if(!hasNext()) { - return -1; - } - return _list.get(_nextIndex).getSid(); - } - - public int getCountRead() { - return _countRead; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/RowBlocksReader.java b/trunk/src/java/org/apache/poi/hssf/model/RowBlocksReader.java deleted file mode 100644 index 0bc7e2919..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/RowBlocksReader.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.record.ArrayRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.TableRecord; -import org.apache.poi.hssf.record.aggregates.MergedCellsTable; -import org.apache.poi.hssf.record.aggregates.SharedValueManager; -import org.apache.poi.ss.util.CellReference; - -/** - * Segregates the 'Row Blocks' section of a single sheet into plain row/cell records and - * shared formula records. - */ -public final class RowBlocksReader { - - private final List _plainRecords; - private final SharedValueManager _sfm; - private final MergeCellsRecord[] _mergedCellsRecords; - - /** - * Also collects any loose MergeCellRecords and puts them in the supplied - * mergedCellsTable - * - * @param rs the record stream - */ - public RowBlocksReader(RecordStream rs) { - List plainRecords = new ArrayList(); - List shFrmRecords = new ArrayList(); - List firstCellRefs = new ArrayList(); - List arrayRecords = new ArrayList(); - List tableRecords = new ArrayList(); - List mergeCellRecords = new ArrayList(); - - Record prevRec = null; - while(!RecordOrderer.isEndOfRowBlock(rs.peekNextSid())) { - // End of row/cell records for the current sheet - // Note - It is important that this code does not inadvertently add any sheet - // records from a subsequent sheet. For example, if SharedFormulaRecords - // are taken from the wrong sheet, this could cause bug 44449. - if (!rs.hasNext()) { - throw new RuntimeException("Failed to find end of row/cell records"); - - } - Record rec = rs.getNext(); - List dest; - switch (rec.getSid()) { - case MergeCellsRecord.sid: dest = mergeCellRecords; break; - case SharedFormulaRecord.sid: dest = shFrmRecords; - if (!(prevRec instanceof FormulaRecord)) { - throw new RuntimeException("Shared formula record should follow a FormulaRecord"); - } - FormulaRecord fr = (FormulaRecord)prevRec; - firstCellRefs.add(new CellReference(fr.getRow(), fr.getColumn())); - break; - case ArrayRecord.sid: dest = arrayRecords; break; - case TableRecord.sid: dest = tableRecords; break; - default: dest = plainRecords; - } - dest.add(rec); - prevRec = rec; - } - SharedFormulaRecord[] sharedFormulaRecs = new SharedFormulaRecord[shFrmRecords.size()]; - CellReference[] firstCells = new CellReference[firstCellRefs.size()]; - ArrayRecord[] arrayRecs = new ArrayRecord[arrayRecords.size()]; - TableRecord[] tableRecs = new TableRecord[tableRecords.size()]; - shFrmRecords.toArray(sharedFormulaRecs); - firstCellRefs.toArray(firstCells); - arrayRecords.toArray(arrayRecs); - tableRecords.toArray(tableRecs); - - _plainRecords = plainRecords; - _sfm = SharedValueManager.create(sharedFormulaRecs, firstCells, arrayRecs, tableRecs); - _mergedCellsRecords = new MergeCellsRecord[mergeCellRecords.size()]; - mergeCellRecords.toArray(_mergedCellsRecords); - } - - /** - * Some unconventional apps place {@link MergeCellsRecord}s within the row block. They - * actually should be in the {@link MergedCellsTable} which is much later (see bug 45699). - * @return any loose MergeCellsRecords found - */ - public MergeCellsRecord[] getLooseMergedCells() { - return _mergedCellsRecords; - } - - public SharedValueManager getSharedFormulaManager() { - return _sfm; - } - /** - * @return a {@link RecordStream} containing all the non-{@link SharedFormulaRecord} - * non-{@link ArrayRecord} and non-{@link TableRecord} Records. - */ - public RecordStream getPlainRecordStream() { - return new RecordStream(_plainRecords, 0); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/WorkbookRecordList.java b/trunk/src/java/org/apache/poi/hssf/model/WorkbookRecordList.java deleted file mode 100644 index e02f8ba84..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/WorkbookRecordList.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hssf.record.Record; - -public final class WorkbookRecordList implements Iterable { - private List records = new ArrayList(); - - private int protpos = 0; // holds the position of the protect record. - private int bspos = 0; // holds the position of the last bound sheet. - private int tabpos = 0; // holds the position of the tabid record - private int fontpos = 0; // hold the position of the last font record - private int xfpos = 0; // hold the position of the last extended font record - private int backuppos = 0; // holds the position of the backup record. - private int namepos = 0; // holds the position of last name record - private int supbookpos = 0; // holds the position of sup book - private int externsheetPos = 0;// holds the position of the extern sheet - private int palettepos = -1; // hold the position of the palette, if applicable - - - public void setRecords(List records) { - this.records = records; - } - - public int size() { - return records.size(); - } - - public Record get(int i) { - return records.get(i); - } - - public void add(int pos, Record r) { - records.add(pos, r); - if (getProtpos() >= pos) setProtpos( protpos + 1 ); - if (getBspos() >= pos) setBspos( bspos + 1 ); - if (getTabpos() >= pos) setTabpos( tabpos + 1 ); - if (getFontpos() >= pos) setFontpos( fontpos + 1 ); - if (getXfpos() >= pos) setXfpos( xfpos + 1 ); - if (getBackuppos() >= pos) setBackuppos( backuppos + 1 ); - if (getNamepos() >= pos) setNamepos(namepos+1); - if (getSupbookpos() >= pos) setSupbookpos(supbookpos+1); - if ((getPalettepos() != -1) && (getPalettepos() >= pos)) setPalettepos( palettepos + 1 ); - if (getExternsheetPos() >= pos) setExternsheetPos(getExternsheetPos() + 1); - } - - public List getRecords() { - return records; - } - - public Iterator iterator() { - return records.iterator(); - } - - /** - * Find the given record in the record list by identity and removes it - * - * @param record the identical record to be searched for - */ - public void remove( Object record ) { - // can't use List.indexOf here because it checks the records for equality and not identity - int i = 0; - for (Record r : records) { - if (r == record) { - remove(i); - break; - } - i++; - } - } - - public void remove( int pos ) - { - records.remove(pos); - if (getProtpos() >= pos) setProtpos( protpos - 1 ); - if (getBspos() >= pos) setBspos( bspos - 1 ); - if (getTabpos() >= pos) setTabpos( tabpos - 1 ); - if (getFontpos() >= pos) setFontpos( fontpos - 1 ); - if (getXfpos() >= pos) setXfpos( xfpos - 1 ); - if (getBackuppos() >= pos) setBackuppos( backuppos - 1 ); - if (getNamepos() >= pos) setNamepos(getNamepos()-1); - if (getSupbookpos() >= pos) setSupbookpos(getSupbookpos()-1); - if ((getPalettepos() != -1) && (getPalettepos() >= pos)) setPalettepos( palettepos - 1 ); - if (getExternsheetPos() >= pos) setExternsheetPos( getExternsheetPos() -1); - } - - public int getProtpos() { - return protpos; - } - - public void setProtpos(int protpos) { - this.protpos = protpos; - } - - public int getBspos() { - return bspos; - } - - public void setBspos(int bspos) { - this.bspos = bspos; - } - - public int getTabpos() { - return tabpos; - } - - public void setTabpos(int tabpos) { - this.tabpos = tabpos; - } - - public int getFontpos() { - return fontpos; - } - - public void setFontpos(int fontpos) { - this.fontpos = fontpos; - } - - public int getXfpos() { - return xfpos; - } - - public void setXfpos(int xfpos) { - this.xfpos = xfpos; - } - - public int getBackuppos() { - return backuppos; - } - - public void setBackuppos(int backuppos) { - this.backuppos = backuppos; - } - - public int getPalettepos() { - return palettepos; - } - - public void setPalettepos(int palettepos) { - this.palettepos = palettepos; - } - - - /** - * Returns the namepos. - * @return int - */ - public int getNamepos() { - return namepos; - } - - /** - * Returns the supbookpos. - * @return int - */ - public int getSupbookpos() { - return supbookpos; - } - - /** - * Sets the namepos. - * @param namepos The namepos to set - */ - public void setNamepos(int namepos) { - this.namepos = namepos; - } - - /** - * Sets the supbookpos. - * @param supbookpos The supbookpos to set - */ - public void setSupbookpos(int supbookpos) { - this.supbookpos = supbookpos; - } - - /** - * Returns the externsheetPos. - * @return int - */ - public int getExternsheetPos() { - return externsheetPos; - } - - /** - * Sets the externsheetPos. - * @param externsheetPos The externsheetPos to set - */ - public void setExternsheetPos(int externsheetPos) { - this.externsheetPos = externsheetPos; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/model/package.html b/trunk/src/java/org/apache/poi/hssf/model/package.html deleted file mode 100644 index 2833d70a6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/model/package.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - -Provides low level API structures for reading, writing, modifying XLS files. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.hssf.usermodel - - - diff --git a/trunk/src/java/org/apache/poi/hssf/package.html b/trunk/src/java/org/apache/poi/hssf/package.html deleted file mode 100644 index b8d8b6132..000000000 --- a/trunk/src/java/org/apache/poi/hssf/package.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - -Horrible SpreadSheet Format API's for reading/writting Excel files using pure Java. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java b/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java deleted file mode 100644 index 1005b38f6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java +++ /dev/null @@ -1,264 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ddf.DefaultEscherRecordFactory; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherRecordFactory; -import org.apache.poi.ddf.NullEscherSerializationListener; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hssf.util.LazilyConcatenatedByteArray; - -/** - * The escher container record is used to hold escher records. It is abstract and - * must be subclassed for maximum benefit. - */ -public abstract class AbstractEscherHolderRecord extends Record implements Cloneable { - private static boolean DESERIALISE; - static { - try { - DESERIALISE = (System.getProperty("poi.deserialize.escher") != null); - } catch (SecurityException e) { - DESERIALISE = false; - } - } - - private final List escherRecords; - private final LazilyConcatenatedByteArray rawDataContainer = new LazilyConcatenatedByteArray(); - - public AbstractEscherHolderRecord() - { - escherRecords = new ArrayList(); - } - - public AbstractEscherHolderRecord(RecordInputStream in) - { - escherRecords = new ArrayList(); - if (! DESERIALISE ) { - rawDataContainer.concatenate(in.readRemainder()); - } else { - byte[] data = in.readAllContinuedRemainder(); - convertToEscherRecords( 0, data.length, data ); - } - } - - protected void convertRawBytesToEscherRecords() { - if (! DESERIALISE ) { - byte[] rawData = getRawData(); - convertToEscherRecords(0, rawData.length, rawData); - } - } - private void convertToEscherRecords( int offset, int size, byte[] data ) - { - escherRecords.clear(); - EscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); - int pos = offset; - while ( pos < offset + size ) - { - EscherRecord r = recordFactory.createRecord(data, pos); - int bytesRead = r.fillFields(data, pos, recordFactory ); - escherRecords.add(r); - pos += bytesRead; - } - } - - @Override - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - final String nl = System.getProperty("line.separator"); - buffer.append('[' + getRecordName() + ']' + nl); - if (escherRecords.size() == 0) - buffer.append("No Escher Records Decoded" + nl); - for (EscherRecord r : escherRecords) { - buffer.append(r.toString()); - } - buffer.append("[/" + getRecordName() + ']' + nl); - - return buffer.toString(); - } - - protected abstract String getRecordName(); - - @Override - public int serialize(int offset, byte[] data) - { - LittleEndian.putShort( data, 0 + offset, getSid() ); - LittleEndian.putShort( data, 2 + offset, (short) ( getRecordSize() - 4 ) ); - byte[] rawData = getRawData(); - if ( escherRecords.size() == 0 && rawData != null ) - { - LittleEndian.putShort(data, 0 + offset, getSid()); - LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4)); - System.arraycopy( rawData, 0, data, 4 + offset, rawData.length); - return rawData.length + 4; - } - LittleEndian.putShort(data, 0 + offset, getSid()); - LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4)); - - int pos = offset + 4; - for (EscherRecord r : escherRecords) { - pos += r.serialize( pos, data, new NullEscherSerializationListener() ); - } - return getRecordSize(); - } - - @Override - public int getRecordSize() { - byte[] rawData = getRawData(); - if (escherRecords.size() == 0 && rawData != null) { - // XXX: It should be possible to derive this without concatenating the array, too. - return rawData.length; - } - int size = 0; - for (EscherRecord r : escherRecords) { - size += r.getRecordSize(); - } - return size; - } - - - - @Override - public abstract short getSid(); - - @Override - public AbstractEscherHolderRecord clone() { - return (AbstractEscherHolderRecord)cloneViaReserialise(); - } - - public void addEscherRecord(int index, EscherRecord element) - { - escherRecords.add( index, element ); - } - - public boolean addEscherRecord(EscherRecord element) - { - return escherRecords.add( element ); - } - - public List getEscherRecords() - { - return escherRecords; - } - - public void clearEscherRecords() - { - escherRecords.clear(); - } - - /** - * If we have a EscherContainerRecord as one of our - * children (and most top level escher holders do), - * then return that. - * - * @return the EscherContainerRecord or {@code null} if no child is a container record - */ - public EscherContainerRecord getEscherContainer() { - for (EscherRecord er : escherRecords) { - if(er instanceof EscherContainerRecord) { - return (EscherContainerRecord)er; - } - } - return null; - } - - /** - * Descends into all our children, returning the - * first EscherRecord with the given id, or null - * if none found - * - * @param id the record to look for - * - * @return the record or {@code null} if it can't be found - */ - public EscherRecord findFirstWithId(short id) { - return findFirstWithId(id, getEscherRecords()); - } - - private EscherRecord findFirstWithId(short id, List records) { - // Check at our level - for (EscherRecord r : records) { - if(r.getRecordId() == id) { - return r; - } - } - - // Then check our children in turn - for (EscherRecord r : records) { - if(r.isContainerRecord()) { - EscherRecord found = findFirstWithId(id, r.getChildRecords()); - if(found != null) { - return found; - } - } - } - - // Not found in this lot - return null; - } - - - public EscherRecord getEscherRecord(int index) - { - return escherRecords.get(index); - } - - /** - * Big drawing group records are split but it's easier to deal with them - * as a whole group so we need to join them together. - * - * @param record the record data to concatenate to the end - */ - public void join( AbstractEscherHolderRecord record ) - { - rawDataContainer.concatenate(record.getRawData()); - } - - public void processContinueRecord( byte[] record ) - { - rawDataContainer.concatenate(record); - } - - public byte[] getRawData() - { - return rawDataContainer.toArray(); - } - - public void setRawData( byte[] rawData ) - { - rawDataContainer.clear(); - rawDataContainer.concatenate(rawData); - } - - /** - * Convert raw data to escher records. - */ - public void decode() - { - if (null == escherRecords || 0 == escherRecords.size()){ - byte[] rawData = getRawData(); - convertToEscherRecords(0, rawData.length, rawData ); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ArrayRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ArrayRecord.java deleted file mode 100644 index 0ff4eb04c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ArrayRecord.java +++ /dev/null @@ -1,107 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ARRAY (0x0221)

    - * - * Treated in a similar way to SharedFormulaRecord - */ -public final class ArrayRecord extends SharedValueRecordBase implements Cloneable { - - public final static short sid = 0x0221; - private static final int OPT_ALWAYS_RECALCULATE = 0x0001; - private static final int OPT_CALCULATE_ON_OPEN = 0x0002; - - private int _options; - private int _field3notUsed; - private Formula _formula; - - public ArrayRecord(RecordInputStream in) { - super(in); - _options = in.readUShort(); - _field3notUsed = in.readInt(); - int formulaTokenLen = in.readUShort(); - int totalFormulaLen = in.available(); - _formula = Formula.read(formulaTokenLen, in, totalFormulaLen); - } - - public ArrayRecord(Formula formula, CellRangeAddress8Bit range) { - super(range); - _options = 0; //YK: Excel 2007 leaves this field unset - _field3notUsed = 0; - _formula = formula; - } - - public boolean isAlwaysRecalculate() { - return (_options & OPT_ALWAYS_RECALCULATE) != 0; - } - public boolean isCalculateOnOpen() { - return (_options & OPT_CALCULATE_ON_OPEN) != 0; - } - - public Ptg[] getFormulaTokens() { - return _formula.getTokens(); - } - - protected int getExtraDataSize() { - return 2 + 4 + _formula.getEncodedSize(); - } - protected void serializeExtraData(LittleEndianOutput out) { - out.writeShort(_options); - out.writeInt(_field3notUsed); - _formula.serialize(out); - } - - public short getSid() { - return sid; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()).append(" [ARRAY]\n"); - sb.append(" range=").append(getRange().toString()).append("\n"); - sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n"); - sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n"); - sb.append(" formula:").append("\n"); - Ptg[] ptgs = _formula.getTokens(); - for (int i = 0; i < ptgs.length; i++) { - Ptg ptg = ptgs[i]; - sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n"); - } - sb.append("]"); - return sb.toString(); - } - - @Override - public ArrayRecord clone() { - ArrayRecord rec = new ArrayRecord(_formula.copy(), getRange()); - - // they both seem unused, but clone them nevertheless to have an exact copy - rec._options = _options; - rec._field3notUsed = _field3notUsed; - - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/AutoFilterInfoRecord.java b/trunk/src/java/org/apache/poi/hssf/record/AutoFilterInfoRecord.java deleted file mode 100644 index e514dc21b..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/AutoFilterInfoRecord.java +++ /dev/null @@ -1,99 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * The AutoFilterInfo record specifies the number of columns that have AutoFilter enabled - * and indicates the beginning of the collection of AutoFilter records. - * - * @author Yegor Kozlov - */ - -public final class AutoFilterInfoRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x9D; - /** - * Number of AutoFilter drop-down arrows on the sheet - */ - private short _cEntries; // = 0; - - public AutoFilterInfoRecord() - { - } - - public AutoFilterInfoRecord(RecordInputStream in) - { - _cEntries = in.readShort(); - } - - /** - * set the number of AutoFilter drop-down arrows on the sheet - * - * @param num the number of AutoFilter drop-down arrows on the sheet - */ - - public void setNumEntries(short num) - { - _cEntries = num; - } - - /** - * get the number of AutoFilter drop-down arrows on the sheet - * - * @return the number of AutoFilter drop-down arrows on the sheet - */ - - public short getNumEntries() - { - return _cEntries; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AUTOFILTERINFO]\n"); - buffer.append(" .numEntries = ") - .append(_cEntries).append("\n"); - buffer.append("[/AUTOFILTERINFO]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_cEntries); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public AutoFilterInfoRecord clone() - { - return (AutoFilterInfoRecord)cloneViaReserialise(); - } - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/BOFRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BOFRecord.java deleted file mode 100644 index aca680cf5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BOFRecord.java +++ /dev/null @@ -1,282 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Beginning Of File (0x0809)

    - * Description: Somewhat of a misnomer, its used for the beginning of a set of - * records that have a particular purpose or subject. - * Used in sheets and workbooks.

    - * REFERENCE: PG 289 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class BOFRecord extends StandardRecord implements Cloneable { - /** - * for BIFF8 files the BOF is 0x809. For earlier versions see - * {@link #biff2_sid} {@link #biff3_sid} {@link #biff4_sid} - * {@link #biff5_sid} - */ - public final static short sid = 0x809; - // SIDs from earlier BIFF versions - public final static short biff2_sid = 0x009; - public final static short biff3_sid = 0x209; - public final static short biff4_sid = 0x409; - public final static short biff5_sid = 0x809; - - /** suggested default (0x0600 - BIFF8) */ - public final static int VERSION = 0x0600; - /** suggested default 0x10d3 */ - public final static int BUILD = 0x10d3; - /** suggested default 0x07CC (1996) */ - public final static int BUILD_YEAR = 0x07CC; // 1996 - /** suggested default for a normal sheet (0x41) */ - public final static int HISTORY_MASK = 0x41; - - public final static int TYPE_WORKBOOK = 0x05; - public final static int TYPE_VB_MODULE = 0x06; - public final static int TYPE_WORKSHEET = 0x10; - public final static int TYPE_CHART = 0x20; - public final static int TYPE_EXCEL_4_MACRO = 0x40; - public final static int TYPE_WORKSPACE_FILE = 0x100; - - private int field_1_version; - private int field_2_type; - private int field_3_build; - private int field_4_year; - private int field_5_history; - private int field_6_rversion; - - /** - * Constructs an empty BOFRecord with no fields set. - */ - public BOFRecord() { - } - - private BOFRecord(int type) { - field_1_version = VERSION; - field_2_type = type; - field_3_build = BUILD; - field_4_year = BUILD_YEAR; - field_5_history = 0x01; - field_6_rversion = VERSION; - } - - public static BOFRecord createSheetBOF() { - return new BOFRecord(TYPE_WORKSHEET); - } - - public BOFRecord(RecordInputStream in) { - field_1_version = in.readShort(); - field_2_type = in.readShort(); - - // Some external tools don't generate all of - // the remaining fields - if (in.remaining() >= 2) { - field_3_build = in.readShort(); - } - if (in.remaining() >= 2) { - field_4_year = in.readShort(); - } - if (in.remaining() >= 4) { - field_5_history = in.readInt(); - } - if (in.remaining() >= 4) { - field_6_rversion = in.readInt(); - } - } - - /** - * Version number - for BIFF8 should be 0x06 - * @see #VERSION - * @param version version to be set - */ - public void setVersion(int version) { - field_1_version = version; - } - - /** - * type of object this marks - * @see #TYPE_WORKBOOK - * @see #TYPE_VB_MODULE - * @see #TYPE_WORKSHEET - * @see #TYPE_CHART - * @see #TYPE_EXCEL_4_MACRO - * @see #TYPE_WORKSPACE_FILE - * @param type type to be set - */ - public void setType(int type) { - field_2_type = type; - } - - /** - * build that wrote this file - * @see #BUILD - * @param build build number to set - */ - public void setBuild(int build) { - field_3_build = build; - } - - /** - * Year of the build that wrote this file - * @see #BUILD_YEAR - * @param year build year to set - */ - public void setBuildYear(int year) { - field_4_year = year; - } - - /** - * set the history bit mask (not very useful) - * @see #HISTORY_MASK - * @param bitmask bitmask to set for the history - */ - public void setHistoryBitMask(int bitmask) { - field_5_history = bitmask; - } - - /** - * set the minimum version required to read this file - * - * @see #VERSION - * @param version version to set - */ - public void setRequiredVersion(int version) { - field_6_rversion = version; - } - - /** - * Version number - for BIFF8 should be 0x06 - * @see #VERSION - * @return version number of the generator of this file - */ - public int getVersion() { - return field_1_version; - } - - /** - * type of object this marks - * @see #TYPE_WORKBOOK - * @see #TYPE_VB_MODULE - * @see #TYPE_WORKSHEET - * @see #TYPE_CHART - * @see #TYPE_EXCEL_4_MACRO - * @see #TYPE_WORKSPACE_FILE - * @return type of object - */ - public int getType() { - return field_2_type; - } - - /** - * get the build that wrote this file - * @see #BUILD - * @return short build number of the generator of this file - */ - public int getBuild() { - return field_3_build; - } - - /** - * Year of the build that wrote this file - * @see #BUILD_YEAR - * @return short build year of the generator of this file - */ - public int getBuildYear() { - return field_4_year; - } - - /** - * get the history bit mask (not very useful) - * @see #HISTORY_MASK - * @return int bitmask showing the history of the file (who cares!) - */ - public int getHistoryBitMask() { - return field_5_history; - } - - /** - * get the minimum version required to read this file - * - * @see #VERSION - * @return int least version that can read the file - */ - public int getRequiredVersion() { - return field_6_rversion; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BOF RECORD]\n"); - buffer.append(" .version = ").append(HexDump.shortToHex(getVersion())).append("\n"); - buffer.append(" .type = ").append(HexDump.shortToHex(getType())); - buffer.append(" (").append(getTypeName()).append(")").append("\n"); - buffer.append(" .build = ").append(HexDump.shortToHex(getBuild())).append("\n"); - buffer.append(" .buildyear= ").append(getBuildYear()).append("\n"); - buffer.append(" .history = ").append(HexDump.intToHex(getHistoryBitMask())).append("\n"); - buffer.append(" .reqver = ").append(HexDump.intToHex(getRequiredVersion())).append("\n"); - buffer.append("[/BOF RECORD]\n"); - return buffer.toString(); - } - - private String getTypeName() { - switch(field_2_type) { - case TYPE_CHART: return "chart"; - case TYPE_EXCEL_4_MACRO: return "excel 4 macro"; - case TYPE_VB_MODULE: return "vb module"; - case TYPE_WORKBOOK: return "workbook"; - case TYPE_WORKSHEET: return "worksheet"; - case TYPE_WORKSPACE_FILE: return "workspace file"; - } - return "#error unknown type#"; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getVersion()); - out.writeShort(getType()); - out.writeShort(getBuild()); - out.writeShort(getBuildYear()); - out.writeInt(getHistoryBitMask()); - out.writeInt(getRequiredVersion()); - } - - protected int getDataSize() { - return 16; - } - - public short getSid(){ - return sid; - } - - @Override - public BOFRecord clone() { - BOFRecord rec = new BOFRecord(); - rec.field_1_version = field_1_version; - rec.field_2_type = field_2_type; - rec.field_3_build = field_3_build; - rec.field_4_year = field_4_year; - rec.field_5_history = field_5_history; - rec.field_6_rversion = field_6_rversion; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/BackupRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BackupRecord.java deleted file mode 100644 index 0381b2277..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BackupRecord.java +++ /dev/null @@ -1,93 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Backup Record

    - * Description: Boolean specifying whether - * the GUI should store a backup of the file.

    - * REFERENCE: PG 287 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class BackupRecord - extends StandardRecord -{ - public final static short sid = 0x40; - private short field_1_backup; // = 0; - - public BackupRecord() - { - } - - public BackupRecord(RecordInputStream in) - { - field_1_backup = in.readShort(); - } - - /** - * set the backup flag (0,1) - * - * @param backup backup flag - */ - - public void setBackup(short backup) - { - field_1_backup = backup; - } - - /** - * get the backup flag - * - * @return short 0/1 (off/on) - */ - - public short getBackup() - { - return field_1_backup; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BACKUP]\n"); - buffer.append(" .backup = ") - .append(Integer.toHexString(getBackup())).append("\n"); - buffer.append("[/BACKUP]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getBackup()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/BiffHeaderInput.java b/trunk/src/java/org/apache/poi/hssf/record/BiffHeaderInput.java deleted file mode 100644 index 089dce675..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BiffHeaderInput.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.record; - -public interface BiffHeaderInput { - - /** - * Read an unsigned short from the stream without decrypting - * - * @return the record sid - */ - int readRecordSID(); - - /** - * Read an unsigned short from the stream without decrypting - * - * @return the data size - */ - int readDataSize(); - - /** - * @return the available bytes - */ - int available(); - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/BlankRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BlankRecord.java deleted file mode 100644 index d465ad3b4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BlankRecord.java +++ /dev/null @@ -1,148 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Blank cell record (0x0201)

    - * Description: Represents a column in a row with no value but with styling.

    - * REFERENCE: PG 287 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ -public final class BlankRecord extends StandardRecord implements CellValueRecordInterface, Cloneable { - public final static short sid = 0x0201; - private int field_1_row; - private short field_2_col; - private short field_3_xf; - - /** Creates a new instance of BlankRecord */ - public BlankRecord() - { - } - - public BlankRecord(RecordInputStream in) - { - field_1_row = in.readUShort(); - field_2_col = in.readShort(); - field_3_xf = in.readShort(); - } - - /** - * set the row this cell occurs on - * @param row the row this cell occurs within - */ - public void setRow(int row) - { - field_1_row = row; - } - - /** - * get the row this cell occurs on - * - * @return the row - */ - public int getRow() - { - return field_1_row; - } - - /** - * get the column this cell defines within the row - * - * @return the column - */ - public short getColumn() - { - return field_2_col; - } - - /** - * set the index of the extended format record to style this cell with - * - * @param xf - the 0-based index of the extended format - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - */ - public void setXFIndex(short xf) - { - field_3_xf = xf; - } - - /** - * get the index of the extended format record to style this cell with - * - * @return extended format index - */ - public short getXFIndex() - { - return field_3_xf; - } - - /** - * set the column this cell defines within the row - * - * @param col the column this cell defines - */ - - public void setColumn(short col) - { - field_2_col = col; - } - - /** - * return the non static version of the id for this record. - */ - public short getSid() - { - return sid; - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - - sb.append("[BLANK]\n"); - sb.append(" row= ").append(HexDump.shortToHex(getRow())).append("\n"); - sb.append(" col= ").append(HexDump.shortToHex(getColumn())).append("\n"); - sb.append(" xf = ").append(HexDump.shortToHex(getXFIndex())).append("\n"); - sb.append("[/BLANK]\n"); - return sb.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getRow()); - out.writeShort(getColumn()); - out.writeShort(getXFIndex()); - } - - protected int getDataSize() { - return 6; - } - - @Override - public BlankRecord clone() { - BlankRecord rec = new BlankRecord(); - rec.field_1_row = field_1_row; - rec.field_2_col = field_2_col; - rec.field_3_xf = field_3_xf; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/BookBoolRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BookBoolRecord.java deleted file mode 100644 index 652e2ec03..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BookBoolRecord.java +++ /dev/null @@ -1,93 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Save External Links record (BookBool)

    - * Description: Contains a flag specifying whether the Gui should save externally - * linked values from other workbooks.

    - * REFERENCE: PG 289 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class BookBoolRecord - extends StandardRecord -{ - public final static short sid = 0xDA; - private short field_1_save_link_values; - - public BookBoolRecord() - { - } - - public BookBoolRecord(RecordInputStream in) - { - field_1_save_link_values = in.readShort(); - } - - /** - * set the save ext links flag - * - * @param flag flag (0/1 -off/on) - */ - - public void setSaveLinkValues(short flag) - { - field_1_save_link_values = flag; - } - - /** - * get the save ext links flag - * - * @return short 0/1 (off/on) - */ - - public short getSaveLinkValues() - { - return field_1_save_link_values; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BOOKBOOL]\n"); - buffer.append(" .savelinkvalues = ") - .append(Integer.toHexString(getSaveLinkValues())).append("\n"); - buffer.append("[/BOOKBOOL]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_save_link_values); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/BoolErrRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BoolErrRecord.java deleted file mode 100644 index 3ff786ad9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BoolErrRecord.java +++ /dev/null @@ -1,192 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Creates new BoolErrRecord. (0x0205)

    - * REFERENCE: PG ??? Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Michael P. Harhen - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class BoolErrRecord extends CellRecord implements Cloneable { - public final static short sid = 0x0205; - private int _value; - /** - * If true, this record represents an error cell value, otherwise this record represents a boolean cell value - */ - private boolean _isError; - - /** Creates new BoolErrRecord */ - public BoolErrRecord() { - // fields uninitialised - } - - /** - * @param in the RecordInputstream to read the record from - */ - public BoolErrRecord(RecordInputStream in) { - super(in); - switch (in.remaining()) { - case 2: - _value = in.readByte(); - break; - case 3: - _value = in.readUShort(); - break; - default: - throw new RecordFormatException("Unexpected size (" - + in.remaining() + ") for BOOLERR record."); - } - int flag = in.readUByte(); - switch (flag) { - case 0: - _isError = false; - break; - case 1: - _isError = true; - break; - default: - throw new RecordFormatException("Unexpected isError flag (" - + flag + ") for BOOLERR record."); - } - } - - /** - * set the boolean value for the cell - * - * @param value representing the boolean value - */ - public void setValue(boolean value) { - _value = value ? 1 : 0; - _isError = false; - } - - /** - * set the error value for the cell. See {@link FormulaError} for valid codes. - * - * @param value error representing the error value - * this value can only be 0,7,15,23,29,36 or 42 - * see bugzilla bug 16560 for an explanation - */ - public void setValue(byte value) { - setValue(FormulaError.forInt(value)); - } - - /** - * set the error value for the cell - * - * @param value error representing the error value - * this value can only be 0,7,15,23,29,36 or 42 - * see bugzilla bug 16560 for an explanation - */ - public void setValue(FormulaError value) { - switch(value) { - case NULL: - case DIV0: - case VALUE: - case REF: - case NAME: - case NUM: - case NA: - _value = value.getCode(); - _isError = true; - return; - default: - throw new IllegalArgumentException("Error Value can only be 0,7,15,23,29,36 or 42. It cannot be "+value.getCode()+" ("+value+")"); - } - } - - /** - * get the value for the cell - * - * @return boolean representing the boolean value - */ - public boolean getBooleanValue() { - return _value != 0; - } - - /** - * get the error value for the cell - * - * @return byte representing the error value - */ - public byte getErrorValue() { - return (byte)_value; - } - - /** - * Indicates whether the call holds a boolean value - * - * @return boolean true if the cell holds a boolean value - */ - public boolean isBoolean() { - return !_isError; - } - - /** - * Indicates whether the call holds an error value - * - * @return boolean true if the cell holds an error value - */ - public boolean isError() { - return _isError; - } - - @Override - protected String getRecordName() { - return "BOOLERR"; - } - @Override - protected void appendValueText(StringBuilder sb) { - if (isBoolean()) { - sb.append(" .boolVal = "); - sb.append(getBooleanValue()); - } else { - sb.append(" .errCode = "); - sb.append(FormulaError.forInt(getErrorValue()).getString()); - sb.append(" (").append(HexDump.byteToHex(getErrorValue())).append(")"); - } - } - @Override - protected void serializeValue(LittleEndianOutput out) { - out.writeByte(_value); - out.writeByte(_isError ? 1 : 0); - } - - @Override - protected int getValueDataSize() { - return 2; - } - - public short getSid() { - return sid; - } - - @Override - public BoolErrRecord clone() { - BoolErrRecord rec = new BoolErrRecord(); - copyBaseFields(rec); - rec._value = _value; - rec._isError = _isError; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/BottomMarginRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BottomMarginRecord.java deleted file mode 100644 index 104d6a0f2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BottomMarginRecord.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - - -import org.apache.poi.util.LittleEndianOutput; - - -/** - * Record for the bottom margin. - */ -public final class BottomMarginRecord extends StandardRecord implements Margin, Cloneable { - public final static short sid = 0x29; - private double field_1_margin; - - public BottomMarginRecord() - { - - } - - public BottomMarginRecord( RecordInputStream in ) - { - field_1_margin = in.readDouble(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - buffer.append( "[BottomMargin]\n" ); - buffer.append( " .margin = " ) - .append( " (" ).append( getMargin() ).append( " )\n" ); - buffer.append( "[/BottomMargin]\n" ); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeDouble(field_1_margin); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() - { - return sid; - } - - /** - * Get the margin field for the BottomMargin record. - */ - public double getMargin() - { - return field_1_margin; - } - - /** - * Set the margin field for the BottomMargin record. - */ - public void setMargin( double field_1_margin ) - { - this.field_1_margin = field_1_margin; - } - - @Override - public BottomMarginRecord clone() { - BottomMarginRecord rec = new BottomMarginRecord(); - rec.field_1_margin = this.field_1_margin; - return rec; - } - -} // END OF \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java b/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java deleted file mode 100644 index 61b92831c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java +++ /dev/null @@ -1,216 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; -import org.apache.poi.ss.util.WorkbookUtil; - -/** - * Title: Bound Sheet Record (aka BundleSheet) (0x0085)

    - * Description: Defines a sheet within a workbook. Basically stores the sheet name - * and tells where the Beginning of file record is within the HSSF - * file.

    - * REFERENCE: PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class BoundSheetRecord extends StandardRecord { - public final static short sid = 0x0085; - - private static final BitField hiddenFlag = BitFieldFactory.getInstance(0x01); - private static final BitField veryHiddenFlag = BitFieldFactory.getInstance(0x02); - private int field_1_position_of_BOF; - private int field_2_option_flags; - private int field_4_isMultibyteUnicode; - private String field_5_sheetname; - - public BoundSheetRecord(String sheetname) { - field_2_option_flags = 0; - setSheetname(sheetname); - } - - /** - * UTF8: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 + - * 1 + 1 + len(str) - * - * UNICODE: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 + - * 1 + 1 + 2 * len(str) - * - * @param in the record stream to read from - */ - public BoundSheetRecord(RecordInputStream in) { - byte buf[] = new byte[LittleEndianConsts.INT_SIZE]; - in.readPlain(buf, 0, buf.length); - field_1_position_of_BOF = LittleEndian.getInt(buf); - field_2_option_flags = in.readUShort(); - int field_3_sheetname_length = in.readUByte(); - field_4_isMultibyteUnicode = in.readByte(); - - if (isMultibyte()) { - field_5_sheetname = in.readUnicodeLEString(field_3_sheetname_length); - } else { - field_5_sheetname = in.readCompressedUnicode(field_3_sheetname_length); - } - } - - /** - * set the offset in bytes of the Beginning of File Marker within the HSSF - * Stream part of the POIFS file - * - * @param pos offset in bytes - */ - public void setPositionOfBof(int pos) { - field_1_position_of_BOF = pos; - } - - /** - * Set the sheetname for this sheet. (this appears in the tabs at the bottom) - * @param sheetName the name of the sheet - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - * for a safe way to create valid names - * @throws IllegalArgumentException if sheet name will cause excel to crash. - */ - public void setSheetname(String sheetName) { - - WorkbookUtil.validateSheetName(sheetName); - field_5_sheetname = sheetName; - field_4_isMultibyteUnicode = StringUtil.hasMultibyte(sheetName) ? 1 : 0; - } - - /** - * get the offset in bytes of the Beginning of File Marker within the HSSF Stream part of the POIFS file - * - * @return offset in bytes - */ - public int getPositionOfBof() { - return field_1_position_of_BOF; - } - - private boolean isMultibyte() { - return (field_4_isMultibyteUnicode & 0x01) != 0; - } - - /** - * get the sheetname for this sheet. (this appears in the tabs at the bottom) - * @return sheetname the name of the sheet - */ - public String getSheetname() { - return field_5_sheetname; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BOUNDSHEET]\n"); - buffer.append(" .bof = ").append(HexDump.intToHex(getPositionOfBof())).append("\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(field_2_option_flags)).append("\n"); - buffer.append(" .unicodeflag= ").append(HexDump.byteToHex(field_4_isMultibyteUnicode)).append("\n"); - buffer.append(" .sheetname = ").append(field_5_sheetname).append("\n"); - buffer.append("[/BOUNDSHEET]\n"); - return buffer.toString(); - } - - protected int getDataSize() { - return 8 + field_5_sheetname.length() * (isMultibyte() ? 2 : 1); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(getPositionOfBof()); - out.writeShort(field_2_option_flags); - - String name = field_5_sheetname; - out.writeByte(name.length()); - out.writeByte(field_4_isMultibyteUnicode); - - if (isMultibyte()) { - StringUtil.putUnicodeLE(name, out); - } else { - StringUtil.putCompressedUnicode(name, out); - } - } - - public short getSid() { - return sid; - } - - /** - * Is the sheet hidden? Different from very hidden - * - * @return {@code true} if hidden - */ - public boolean isHidden() { - return hiddenFlag.isSet(field_2_option_flags); - } - - /** - * Is the sheet hidden? Different from very hidden - * - * @param hidden {@code true} if hidden - */ - public void setHidden(boolean hidden) { - field_2_option_flags = hiddenFlag.setBoolean(field_2_option_flags, hidden); - } - - /** - * Is the sheet very hidden? Different from (normal) hidden - * - * @return {@code true} if very hidden - */ - public boolean isVeryHidden() { - return veryHiddenFlag.isSet(field_2_option_flags); - } - - /** - * Is the sheet very hidden? Different from (normal) hidden - * - * @param veryHidden {@code true} if very hidden - */ - public void setVeryHidden(boolean veryHidden) { - field_2_option_flags = veryHiddenFlag.setBoolean(field_2_option_flags, veryHidden); - } - - /** - * Converts a List of {@link BoundSheetRecord}s to an array and sorts by the position of their - * BOFs. - * - * @param boundSheetRecords the boundSheetRecord list to arrayify - * - * @return the sorted boundSheetRecords - */ - public static BoundSheetRecord[] orderByBofPosition(List boundSheetRecords) { - BoundSheetRecord[] bsrs = new BoundSheetRecord[boundSheetRecords.size()]; - boundSheetRecords.toArray(bsrs); - Arrays.sort(bsrs, BOFComparator); - return bsrs; - } - - private static final Comparator BOFComparator = new Comparator() { - - public int compare(BoundSheetRecord bsr1, BoundSheetRecord bsr2) { - return bsr1.getPositionOfBof() - bsr2.getPositionOfBof(); - } - }; -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CFHeader12Record.java b/trunk/src/java/org/apache/poi/hssf/record/CFHeader12Record.java deleted file mode 100644 index 241faf139..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CFHeader12Record.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.common.FtrHeader; -import org.apache.poi.hssf.record.common.FutureRecord; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Conditional Formatting Header v12 record CFHEADER12 (0x0879), - * for conditional formattings introduced in Excel 2007 and newer. - */ -public final class CFHeader12Record extends CFHeaderBase implements FutureRecord, Cloneable { - public static final short sid = 0x0879; - - private FtrHeader futureHeader; - - /** Creates new CFHeaderRecord */ - public CFHeader12Record() { - createEmpty(); - futureHeader = new FtrHeader(); - futureHeader.setRecordType(sid); - } - public CFHeader12Record(CellRangeAddress[] regions, int nRules) { - super(regions, nRules); - futureHeader = new FtrHeader(); - futureHeader.setRecordType(sid); - } - public CFHeader12Record(RecordInputStream in) { - futureHeader = new FtrHeader(in); - read(in); - } - - @Override - protected String getRecordName() { - return "CFHEADER12"; - } - - protected int getDataSize() { - return FtrHeader.getDataSize() + super.getDataSize(); - } - - public void serialize(LittleEndianOutput out) { - // Sync the associated range - futureHeader.setAssociatedRange(getEnclosingCellRange()); - // Write the future header first - futureHeader.serialize(out); - // Then the rest of the CF Header details - super.serialize(out); - } - - public short getSid() { - return sid; - } - - public short getFutureRecordType() { - return futureHeader.getRecordType(); - } - public FtrHeader getFutureHeader() { - return futureHeader; - } - public CellRangeAddress getAssociatedRange() { - return futureHeader.getAssociatedRange(); - } - - @Override - public CFHeader12Record clone() { - CFHeader12Record result = new CFHeader12Record(); - result.futureHeader = (FtrHeader)futureHeader.clone(); - super.copyTo(result); - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CFHeaderBase.java b/trunk/src/java/org/apache/poi/hssf/record/CFHeaderBase.java deleted file mode 100644 index 378463865..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CFHeaderBase.java +++ /dev/null @@ -1,162 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.ss.util.CellRangeUtil; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Parent of Conditional Formatting Header records, - * {@link CFHeaderRecord} and {@link CFHeader12Record}. - */ -public abstract class CFHeaderBase extends StandardRecord implements Cloneable { - private int field_1_numcf; - private int field_2_need_recalculation_and_id; - private CellRangeAddress field_3_enclosing_cell_range; - private CellRangeAddressList field_4_cell_ranges; - - /** Creates new CFHeaderBase */ - protected CFHeaderBase() { - } - protected CFHeaderBase(CellRangeAddress[] regions, int nRules) { - CellRangeAddress[] unmergedRanges = regions; - CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges); - setCellRanges(mergeCellRanges); - field_1_numcf = nRules; - } - - protected void createEmpty() { - field_3_enclosing_cell_range = new CellRangeAddress(0, 0, 0, 0); - field_4_cell_ranges = new CellRangeAddressList(); - } - protected void read(RecordInputStream in) { - field_1_numcf = in.readShort(); - field_2_need_recalculation_and_id = in.readShort(); - field_3_enclosing_cell_range = new CellRangeAddress(in); - field_4_cell_ranges = new CellRangeAddressList(in); - } - - public int getNumberOfConditionalFormats() { - return field_1_numcf; - } - public void setNumberOfConditionalFormats(int n) { - field_1_numcf=n; - } - - public boolean getNeedRecalculation() { - // Held on the 1st bit - return (field_2_need_recalculation_and_id & 1) == 1; - } - public void setNeedRecalculation(boolean b) { - // held on the first bit - if (b == getNeedRecalculation()) { - return; - } else if (b) { - field_2_need_recalculation_and_id++; - } else { - field_2_need_recalculation_and_id--; - } - } - - public int getID() { - // Remaining 15 bits of field 2 - return field_2_need_recalculation_and_id>>1; - } - public void setID(int id) { - // Remaining 15 bits of field 2 - boolean needsRecalc = getNeedRecalculation(); - field_2_need_recalculation_and_id = (id<<1); - if (needsRecalc) { - field_2_need_recalculation_and_id++; - } - } - - public CellRangeAddress getEnclosingCellRange() { - return field_3_enclosing_cell_range; - } - public void setEnclosingCellRange(CellRangeAddress cr) { - field_3_enclosing_cell_range = cr; - } - - /** - * Set cell ranges list to a single cell range and - * modify the enclosing cell range accordingly. - * @param cellRanges - list of CellRange objects - */ - public void setCellRanges(CellRangeAddress[] cellRanges) { - if(cellRanges == null) { - throw new IllegalArgumentException("cellRanges must not be null"); - } - CellRangeAddressList cral = new CellRangeAddressList(); - CellRangeAddress enclosingRange = null; - for (int i = 0; i < cellRanges.length; i++) { - CellRangeAddress cr = cellRanges[i]; - enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange); - cral.addCellRangeAddress(cr); - } - field_3_enclosing_cell_range = enclosingRange; - field_4_cell_ranges = cral; - } - - public CellRangeAddress[] getCellRanges() { - return field_4_cell_ranges.getCellRangeAddresses(); - } - - protected abstract String getRecordName(); - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[").append(getRecordName()).append("]\n"); - buffer.append("\t.numCF = ").append(getNumberOfConditionalFormats()).append("\n"); - buffer.append("\t.needRecalc = ").append(getNeedRecalculation()).append("\n"); - buffer.append("\t.id = ").append(getID()).append("\n"); - buffer.append("\t.enclosingCellRange= ").append(getEnclosingCellRange()).append("\n"); - buffer.append("\t.cfranges=["); - for( int i=0; iThis is for newer-style Excel conditional formattings, - * from Excel 2007 onwards. - * - *

    {@link CFRuleRecord} is used where the condition type is - * {@link #CONDITION_TYPE_CELL_VALUE_IS} or {@link #CONDITION_TYPE_FORMULA}, - * this is only used for the other types - */ -public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cloneable { - public static final short sid = 0x087A; - - private FtrHeader futureHeader; - private int ext_formatting_length; - private byte[] ext_formatting_data; - private Formula formula_scale; - private byte ext_opts; - private int priority; - private int template_type; - private byte template_param_length; - private byte[] template_params; - - private DataBarFormatting data_bar; - private IconMultiStateFormatting multistate; - private ColorGradientFormatting color_gradient; - // TODO Parse this, see #58150 - private byte[] filter_data; - - /** Creates new CFRuleRecord */ - private CFRule12Record(byte conditionType, byte comparisonOperation) { - super(conditionType, comparisonOperation); - setDefaults(); - } - - private CFRule12Record(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2, Ptg[] formulaScale) { - super(conditionType, comparisonOperation, formula1, formula2); - setDefaults(); - this.formula_scale = Formula.create(formulaScale); - } - private void setDefaults() { - futureHeader = new FtrHeader(); - futureHeader.setRecordType(sid); - - ext_formatting_length = 0; - ext_formatting_data = new byte[4]; - - formula_scale = Formula.create(Ptg.EMPTY_PTG_ARRAY); - - ext_opts = 0; - priority = 0; - template_type = getConditionType(); - template_param_length = 16; - template_params = new byte[template_param_length]; - } - - /** - * Creates a new comparison operation rule - * - * @param sheet the sheet - * @param formulaText the first formula text - * - * @return a new comparison operation rule - */ - public static CFRule12Record create(HSSFSheet sheet, String formulaText) { - Ptg[] formula1 = parseFormula(formulaText, sheet); - return new CFRule12Record(CONDITION_TYPE_FORMULA, ComparisonOperator.NO_COMPARISON, - formula1, null, null); - } - - /** - * Creates a new comparison operation rule - * - * @param sheet the sheet - * @param comparisonOperation the comparison operation - * @param formulaText1 the first formula text - * @param formulaText2 the second formula text - * - * @return a new comparison operation rule - */ - public static CFRule12Record create(HSSFSheet sheet, byte comparisonOperation, - String formulaText1, String formulaText2) { - Ptg[] formula1 = parseFormula(formulaText1, sheet); - Ptg[] formula2 = parseFormula(formulaText2, sheet); - return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, - formula1, formula2, null); - } - - /** - * Creates a new comparison operation rule - * - * @param sheet the sheet - * @param comparisonOperation the comparison operation - * @param formulaText1 the first formula text - * @param formulaText2 the second formula text - * @param formulaTextScale the scale to apply for the comparison - * - * @return a new comparison operation rule - */ - public static CFRule12Record create(HSSFSheet sheet, byte comparisonOperation, - String formulaText1, String formulaText2, String formulaTextScale) { - Ptg[] formula1 = parseFormula(formulaText1, sheet); - Ptg[] formula2 = parseFormula(formulaText2, sheet); - Ptg[] formula3 = parseFormula(formulaTextScale, sheet); - return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, - formula1, formula2, formula3); - } - - /** - * Creates a new Data Bar formatting - * - * @param sheet the sheet - * @param color the data bar color - * - * @return a new Data Bar formatting - */ - public static CFRule12Record create(HSSFSheet sheet, ExtendedColor color) { - CFRule12Record r = new CFRule12Record(CONDITION_TYPE_DATA_BAR, - ComparisonOperator.NO_COMPARISON); - DataBarFormatting dbf = r.createDataBarFormatting(); - dbf.setColor(color); - dbf.setPercentMin((byte)0); - dbf.setPercentMax((byte)100); - - DataBarThreshold min = new DataBarThreshold(); - min.setType(RangeType.MIN.id); - dbf.setThresholdMin(min); - - DataBarThreshold max = new DataBarThreshold(); - max.setType(RangeType.MAX.id); - dbf.setThresholdMax(max); - - return r; - } - - /** - * Creates a new Icon Set / Multi-State formatting - * - * @param sheet the sheet - * @param iconSet the icon set - * - * @return a new Icon Set / Multi-State formatting - */ - public static CFRule12Record create(HSSFSheet sheet, IconSet iconSet) { - Threshold[] ts = new Threshold[iconSet.num]; - for (int i=0; iThis is for the older-style Excel conditional formattings, - * new-style (Excel 2007+) also make use of {@link CFRule12Record} - * for their rules.

    - */ -public abstract class CFRuleBase extends StandardRecord implements Cloneable { - // FIXME: Merge with org.apache.poi.ss.usermodel.ComparisonOperator and rewrite as an enum - public static final class ComparisonOperator { - public static final byte NO_COMPARISON = 0; - public static final byte BETWEEN = 1; - public static final byte NOT_BETWEEN = 2; - public static final byte EQUAL = 3; - public static final byte NOT_EQUAL = 4; - public static final byte GT = 5; - public static final byte LT = 6; - public static final byte GE = 7; - public static final byte LE = 8; - private static final byte max_operator = 8; - } - protected static final POILogger logger = POILogFactory.getLogger(CFRuleBase.class); - - private byte condition_type; - // The only kinds that CFRuleRecord handles - public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1; - public static final byte CONDITION_TYPE_FORMULA = 2; - // These are CFRule12Rule only - public static final byte CONDITION_TYPE_COLOR_SCALE = 3; - public static final byte CONDITION_TYPE_DATA_BAR = 4; - public static final byte CONDITION_TYPE_FILTER = 5; - public static final byte CONDITION_TYPE_ICON_SET = 6; - - private byte comparison_operator; - - public static final int TEMPLATE_CELL_VALUE = 0x0000; - public static final int TEMPLATE_FORMULA = 0x0001; - public static final int TEMPLATE_COLOR_SCALE_FORMATTING = 0x0002; - public static final int TEMPLATE_DATA_BAR_FORMATTING = 0x0003; - public static final int TEMPLATE_ICON_SET_FORMATTING = 0x0004; - public static final int TEMPLATE_FILTER = 0x0005; - public static final int TEMPLATE_UNIQUE_VALUES = 0x0007; - public static final int TEMPLATE_CONTAINS_TEXT = 0x0008; - public static final int TEMPLATE_CONTAINS_BLANKS = 0x0009; - public static final int TEMPLATE_CONTAINS_NO_BLANKS = 0x000A; - public static final int TEMPLATE_CONTAINS_ERRORS = 0x000B; - public static final int TEMPLATE_CONTAINS_NO_ERRORS = 0x000C; - public static final int TEMPLATE_TODAY = 0x000F; - public static final int TEMPLATE_TOMORROW = 0x0010; - public static final int TEMPLATE_YESTERDAY = 0x0011; - public static final int TEMPLATE_LAST_7_DAYS = 0x0012; - public static final int TEMPLATE_LAST_MONTH = 0x0013; - public static final int TEMPLATE_NEXT_MONTH = 0x0014; - public static final int TEMPLATE_THIS_WEEK = 0x0015; - public static final int TEMPLATE_NEXT_WEEK = 0x0016; - public static final int TEMPLATE_LAST_WEEK = 0x0017; - public static final int TEMPLATE_THIS_MONTH = 0x0018; - public static final int TEMPLATE_ABOVE_AVERAGE = 0x0019; - public static final int TEMPLATE_BELOW_AVERAGE = 0x001A; - public static final int TEMPLATE_DUPLICATE_VALUES = 0x001B; - public static final int TEMPLATE_ABOVE_OR_EQUAL_TO_AVERAGE = 0x001D; - public static final int TEMPLATE_BELOW_OR_EQUAL_TO_AVERAGE = 0x001E; - - static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot - static final BitField alignHor = bf(0x00000001); // 0 = Horizontal alignment modified - static final BitField alignVer = bf(0x00000002); // 0 = Vertical alignment modified - static final BitField alignWrap = bf(0x00000004); // 0 = Text wrapped flag modified - static final BitField alignRot = bf(0x00000008); // 0 = Text rotation modified - static final BitField alignJustLast = bf(0x00000010); // 0 = Justify last line flag modified - static final BitField alignIndent = bf(0x00000020); // 0 = Indentation modified - static final BitField alignShrin = bf(0x00000040); // 0 = Shrink to fit flag modified - static final BitField mergeCell = bf(0x00000080); // Normally 1, 0 = Merge Cell flag modified - static final BitField protLocked = bf(0x00000100); // 0 = Cell locked flag modified - static final BitField protHidden = bf(0x00000200); // 0 = Cell hidden flag modified - static final BitField bordLeft = bf(0x00000400); // 0 = Left border style and colour modified - static final BitField bordRight = bf(0x00000800); // 0 = Right border style and colour modified - static final BitField bordTop = bf(0x00001000); // 0 = Top border style and colour modified - static final BitField bordBot = bf(0x00002000); // 0 = Bottom border style and colour modified - static final BitField bordTlBr = bf(0x00004000); // 0 = Top-left to bottom-right border flag modified - static final BitField bordBlTr = bf(0x00008000); // 0 = Bottom-left to top-right border flag modified - static final BitField pattStyle = bf(0x00010000); // 0 = Pattern style modified - static final BitField pattCol = bf(0x00020000); // 0 = Pattern colour modified - static final BitField pattBgCol = bf(0x00040000); // 0 = Pattern background colour modified - static final BitField notUsed2 = bf(0x00380000); // Always 111 (ifmt / ifnt / 1) - static final BitField undocumented = bf(0x03C00000); // Undocumented bits - static final BitField fmtBlockBits = bf(0x7C000000); // Bits: font,align,bord,patt,prot - static final BitField font = bf(0x04000000); // 1 = Record contains font formatting block - static final BitField align = bf(0x08000000); // 1 = Record contains alignment formatting block - static final BitField bord = bf(0x10000000); // 1 = Record contains border formatting block - static final BitField patt = bf(0x20000000); // 1 = Record contains pattern formatting block - static final BitField prot = bf(0x40000000); // 1 = Record contains protection formatting block - static final BitField alignTextDir = bf(0x80000000); // 0 = Text direction modified - - private static BitField bf(int i) { - return BitFieldFactory.getInstance(i); - } - - protected int formatting_options; - protected short formatting_not_used; // TODO Decode this properly - - protected FontFormatting _fontFormatting; - protected BorderFormatting _borderFormatting; - protected PatternFormatting _patternFormatting; - - private Formula formula1; - private Formula formula2; - - /** - * Creates new CFRuleRecord - * - * @param conditionType the condition type - * @param comparisonOperation the comparison operation - */ - protected CFRuleBase(byte conditionType, byte comparisonOperation) { - setConditionType(conditionType); - setComparisonOperation(comparisonOperation); - formula1 = Formula.create(Ptg.EMPTY_PTG_ARRAY); - formula2 = Formula.create(Ptg.EMPTY_PTG_ARRAY); - } - protected CFRuleBase(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) { - this(conditionType, comparisonOperation); - this.formula1 = Formula.create(formula1); - this.formula2 = Formula.create(formula2); - } - protected CFRuleBase() {} - - protected int readFormatOptions(RecordInputStream in) { - formatting_options = in.readInt(); - formatting_not_used = in.readShort(); - - int len = 6; - - if (containsFontFormattingBlock()) { - _fontFormatting = new FontFormatting(in); - len += _fontFormatting.getDataLength(); - } - - if (containsBorderFormattingBlock()) { - _borderFormatting = new BorderFormatting(in); - len += _borderFormatting.getDataLength(); - } - - if (containsPatternFormattingBlock()) { - _patternFormatting = new PatternFormatting(in); - len += _patternFormatting.getDataLength(); - } - - return len; - } - - public byte getConditionType() { - return condition_type; - } - protected void setConditionType(byte condition_type) { - if ((this instanceof CFRuleRecord)) { - if (condition_type == CONDITION_TYPE_CELL_VALUE_IS || - condition_type == CONDITION_TYPE_FORMULA) { - // Good, valid combination - } else { - throw new IllegalArgumentException("CFRuleRecord only accepts Value-Is and Formula types"); - } - } - this.condition_type = condition_type; - } - - public void setComparisonOperation(byte operation) { - if (operation < 0 || operation > ComparisonOperator.max_operator) - throw new IllegalArgumentException( - "Valid operators are only in the range 0 to " +ComparisonOperator.max_operator); - - this.comparison_operator = operation; - } - public byte getComparisonOperation() { - return comparison_operator; - } - - public boolean containsFontFormattingBlock() { - return getOptionFlag(font); - } - public void setFontFormatting(FontFormatting fontFormatting) { - _fontFormatting = fontFormatting; - setOptionFlag(fontFormatting != null, font); - } - public FontFormatting getFontFormatting() { - if( containsFontFormattingBlock()) { - return _fontFormatting; - } - return null; - } - - public boolean containsAlignFormattingBlock() { - return getOptionFlag(align); - } - public void setAlignFormattingUnchanged() { - setOptionFlag(false,align); - } - - public boolean containsBorderFormattingBlock() { - return getOptionFlag(bord); - } - public void setBorderFormatting(BorderFormatting borderFormatting) { - _borderFormatting = borderFormatting; - setOptionFlag(borderFormatting != null, bord); - } - public BorderFormatting getBorderFormatting() { - if( containsBorderFormattingBlock()) { - return _borderFormatting; - } - return null; - } - - public boolean containsPatternFormattingBlock() { - return getOptionFlag(patt); - } - public void setPatternFormatting(PatternFormatting patternFormatting) { - _patternFormatting = patternFormatting; - setOptionFlag(patternFormatting!=null, patt); - } - public PatternFormatting getPatternFormatting() { - if( containsPatternFormattingBlock()) - { - return _patternFormatting; - } - return null; - } - - public boolean containsProtectionFormattingBlock() { - return getOptionFlag(prot); - } - public void setProtectionFormattingUnchanged() { - setOptionFlag(false,prot); - } - - /** - * get the option flags - * - * @return bit mask - */ - public int getOptions() { - return formatting_options; - } - - private boolean isModified(BitField field) { - return !field.isSet(formatting_options); - } - private void setModified(boolean modified, BitField field) { - formatting_options = field.setBoolean(formatting_options, !modified); - } - - public boolean isLeftBorderModified() { - return isModified(bordLeft); - } - public void setLeftBorderModified(boolean modified) { - setModified(modified,bordLeft); - } - - public boolean isRightBorderModified() { - return isModified(bordRight); - } - public void setRightBorderModified(boolean modified) - { - setModified(modified,bordRight); - } - - public boolean isTopBorderModified() { - return isModified(bordTop); - } - public void setTopBorderModified(boolean modified) { - setModified(modified,bordTop); - } - - public boolean isBottomBorderModified() { - return isModified(bordBot); - } - public void setBottomBorderModified(boolean modified) { - setModified(modified,bordBot); - } - - public boolean isTopLeftBottomRightBorderModified() { - return isModified(bordTlBr); - } - public void setTopLeftBottomRightBorderModified(boolean modified) { - setModified(modified,bordTlBr); - } - - public boolean isBottomLeftTopRightBorderModified() { - return isModified(bordBlTr); - } - public void setBottomLeftTopRightBorderModified(boolean modified) { - setModified(modified,bordBlTr); - } - - public boolean isPatternStyleModified() { - return isModified(pattStyle); - } - public void setPatternStyleModified(boolean modified) { - setModified(modified,pattStyle); - } - - public boolean isPatternColorModified() { - return isModified(pattCol); - } - public void setPatternColorModified(boolean modified) { - setModified(modified,pattCol); - } - - public boolean isPatternBackgroundColorModified() { - return isModified(pattBgCol); - } - public void setPatternBackgroundColorModified(boolean modified) { - setModified(modified,pattBgCol); - } - - private boolean getOptionFlag(BitField field) { - return field.isSet(formatting_options); - } - private void setOptionFlag(boolean flag, BitField field) { - formatting_options = field.setBoolean(formatting_options, flag); - } - - protected int getFormattingBlockSize() { - return 6 + - (containsFontFormattingBlock()?_fontFormatting.getRawRecord().length:0)+ - (containsBorderFormattingBlock()?8:0)+ - (containsPatternFormattingBlock()?4:0); - } - protected void serializeFormattingBlock(LittleEndianOutput out) { - out.writeInt(formatting_options); - out.writeShort(formatting_not_used); - - if (containsFontFormattingBlock()) { - byte[] fontFormattingRawRecord = _fontFormatting.getRawRecord(); - out.write(fontFormattingRawRecord); - } - - if (containsBorderFormattingBlock()) { - _borderFormatting.serialize(out); - } - - if (containsPatternFormattingBlock()) { - _patternFormatting.serialize(out); - } - } - - /** - * get the stack of the 1st expression as a list - * - * @return list of tokens (casts stack to a list and returns it!) - * this method can return null is we are unable to create Ptgs from - * existing excel file - * callers should check for null! - */ - public Ptg[] getParsedExpression1() { - return formula1.getTokens(); - } - public void setParsedExpression1(Ptg[] ptgs) { - formula1 = Formula.create(ptgs); - } - protected Formula getFormula1() { - return formula1; - } - protected void setFormula1(Formula formula1) { - this.formula1 = formula1; - } - - /** - * get the stack of the 2nd expression as a list - * - * @return array of {@link Ptg}s, possibly null - */ - public Ptg[] getParsedExpression2() { - return Formula.getTokens(formula2); - } - public void setParsedExpression2(Ptg[] ptgs) { - formula2 = Formula.create(ptgs); - } - protected Formula getFormula2() { - return formula2; - } - protected void setFormula2(Formula formula2) { - this.formula2 = formula2; - } - - /** - * @param formula must not be null - * @return encoded size of the formula tokens (does not include 2 bytes for ushort length) - */ - protected static int getFormulaSize(Formula formula) { - return formula.getEncodedTokenSize(); - } - - /** - * TODO - parse conditional format formulas properly i.e. produce tRefN and tAreaN instead of tRef and tArea - * this call will produce the wrong results if the formula contains any cell references - * One approach might be to apply the inverse of SharedFormulaRecord.convertSharedFormulas(Stack, int, int) - * Note - two extra parameters (rowIx & colIx) will be required. They probably come from one of the Region objects. - * - * @param formula The formula to parse, excluding the leading equals sign. - * @param sheet The sheet that the formula is on. - * @return null if formula was null. - */ - public static Ptg[] parseFormula(String formula, HSSFSheet sheet) { - if(formula == null) { - return null; - } - int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet); - return HSSFFormulaParser.parse(formula, sheet.getWorkbook(), FormulaType.CELL, sheetIndex); - } - - protected void copyTo(CFRuleBase rec) { - rec.condition_type = condition_type; - rec.comparison_operator = comparison_operator; - - rec.formatting_options = formatting_options; - rec.formatting_not_used = formatting_not_used; - if (containsFontFormattingBlock()) { - rec._fontFormatting = _fontFormatting.clone(); - } - if (containsBorderFormattingBlock()) { - rec._borderFormatting = _borderFormatting.clone(); - } - if (containsPatternFormattingBlock()) { - rec._patternFormatting = (PatternFormatting) _patternFormatting.clone(); - } - - rec.setFormula1(getFormula1().copy()); - rec.setFormula2(getFormula2().copy()); - } - - @Override - public abstract CFRuleBase clone(); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CFRuleRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CFRuleRecord.java deleted file mode 100644 index 83915ccc9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CFRuleRecord.java +++ /dev/null @@ -1,164 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Arrays; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Conditional Formatting Rule Record (0x01B1). - * - *

    This is for the older-style Excel conditional formattings, - * new-style (Excel 2007+) also make use of {@link CFRule12Record} - * for their rules.

    - */ -public final class CFRuleRecord extends CFRuleBase implements Cloneable { - public static final short sid = 0x01B1; - - /** Creates new CFRuleRecord */ - private CFRuleRecord(byte conditionType, byte comparisonOperation) { - super(conditionType, comparisonOperation); - setDefaults(); - } - - private CFRuleRecord(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) { - super(conditionType, comparisonOperation, formula1, formula2); - setDefaults(); - } - private void setDefaults() { - // Set modification flags to 1: by default options are not modified - formatting_options = modificationBits.setValue(formatting_options, -1); - // Set formatting block flags to 0 (no formatting blocks) - formatting_options = fmtBlockBits.setValue(formatting_options, 0); - formatting_options = undocumented.clear(formatting_options); - - formatting_not_used = (short)0x8002; // Excel seems to write this value, but it doesn't seem to care what it reads - _fontFormatting = null; - _borderFormatting = null; - _patternFormatting = null; - } - - /** - * Creates a new comparison operation rule - * - * @param sheet the sheet - * @param formulaText the formula text - * - * @return a new comparison operation rule - */ - public static CFRuleRecord create(HSSFSheet sheet, String formulaText) { - Ptg[] formula1 = parseFormula(formulaText, sheet); - return new CFRuleRecord(CONDITION_TYPE_FORMULA, ComparisonOperator.NO_COMPARISON, - formula1, null); - } - /** - * Creates a new comparison operation rule - * - * @param sheet the sheet - * @param comparisonOperation the comparison operation - * @param formulaText1 the first formula text - * @param formulaText2 the second formula text - * - * @return a new comparison operation rule - */ - public static CFRuleRecord create(HSSFSheet sheet, byte comparisonOperation, - String formulaText1, String formulaText2) { - Ptg[] formula1 = parseFormula(formulaText1, sheet); - Ptg[] formula2 = parseFormula(formulaText2, sheet); - return new CFRuleRecord(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, formula1, formula2); - } - - public CFRuleRecord(RecordInputStream in) { - setConditionType(in.readByte()); - setComparisonOperation(in.readByte()); - int field_3_formula1_len = in.readUShort(); - int field_4_formula2_len = in.readUShort(); - readFormatOptions(in); - - // "You may not use unions, intersections or array constants in Conditional Formatting criteria" - setFormula1(Formula.read(field_3_formula1_len, in)); - setFormula2(Formula.read(field_4_formula2_len, in)); - } - - @Override - public short getSid() { - return sid; - } - - /** - * called by the class that is responsible for writing this sucker. - * Subclasses should implement this so that their data is passed back in a - * byte array. - * - * @param out the stream to write to - */ - @Override - public void serialize(LittleEndianOutput out) { - int formula1Len=getFormulaSize(getFormula1()); - int formula2Len=getFormulaSize(getFormula2()); - - out.writeByte(getConditionType()); - out.writeByte(getComparisonOperation()); - out.writeShort(formula1Len); - out.writeShort(formula2Len); - - serializeFormattingBlock(out); - - getFormula1().serializeTokens(out); - getFormula2().serializeTokens(out); - } - - @Override - protected int getDataSize() { - return 6 + getFormattingBlockSize() + - getFormulaSize(getFormula1())+ - getFormulaSize(getFormula2()); - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[CFRULE]\n"); - buffer.append(" .condition_type =").append(getConditionType()).append("\n"); - buffer.append(" OPTION FLAGS=0x").append(Integer.toHexString(getOptions())).append("\n"); - if (containsFontFormattingBlock()) { - buffer.append(_fontFormatting.toString()).append("\n"); - } - if (containsBorderFormattingBlock()) { - buffer.append(_borderFormatting.toString()).append("\n"); - } - if (containsPatternFormattingBlock()) { - buffer.append(_patternFormatting.toString()).append("\n"); - } - buffer.append(" Formula 1 =").append(Arrays.toString(getFormula1().getTokens())).append("\n"); - buffer.append(" Formula 2 =").append(Arrays.toString(getFormula2().getTokens())).append("\n"); - buffer.append("[/CFRULE]\n"); - return buffer.toString(); - } - - @Override - public CFRuleRecord clone() { - CFRuleRecord rec = new CFRuleRecord(getConditionType(), getComparisonOperation()); - super.copyTo(rec); - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CRNCountRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CRNCountRecord.java deleted file mode 100644 index 88cebe270..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CRNCountRecord.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; -/** - * XCT - CRN Count

    - * - * REFERENCE: 5.114

    - * - * @author Josh Micich - */ -public final class CRNCountRecord extends StandardRecord { - public final static short sid = 0x59; - - private static final short DATA_SIZE = 4; - - - private int field_1_number_crn_records; - private int field_2_sheet_table_index; - - public CRNCountRecord() { - throw new RuntimeException("incomplete code"); - } - - public int getNumberOfCRNs() { - return field_1_number_crn_records; - } - - - public CRNCountRecord(RecordInputStream in) { - field_1_number_crn_records = in.readShort(); - if(field_1_number_crn_records < 0) { - // TODO - seems like the sign bit of this field might be used for some other purpose - // see example file for test case "TestBugs.test19599()" - field_1_number_crn_records = (short)-field_1_number_crn_records; - } - field_2_sheet_table_index = in.readShort(); - } - - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()).append(" [XCT"); - sb.append(" nCRNs=").append(field_1_number_crn_records); - sb.append(" sheetIx=").append(field_2_sheet_table_index); - sb.append("]"); - return sb.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort((short)field_1_number_crn_records); - out.writeShort((short)field_2_sheet_table_index); - } - protected int getDataSize() { - return DATA_SIZE; - } - - /** - * return the non static version of the id for this record. - */ - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CRNRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CRNRecord.java deleted file mode 100644 index 11921873d..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CRNRecord.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.formula.constant.ConstantValueParser; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: CRN(0x005A)

    - * Description: This record stores the contents of an external cell or cell range

    - * REFERENCE: OOO 5.23 - */ -public final class CRNRecord extends StandardRecord { - public final static short sid = 0x005A; - - private int field_1_last_column_index; - private int field_2_first_column_index; - private int field_3_row_index; - private Object[] field_4_constant_values; - - public CRNRecord() { - throw new RuntimeException("incomplete code"); - } - - public int getNumberOfCRNs() { - return field_1_last_column_index; - } - - - public CRNRecord(RecordInputStream in) { - field_1_last_column_index = in.readUByte(); - field_2_first_column_index = in.readUByte(); - field_3_row_index = in.readShort(); - int nValues = field_1_last_column_index - field_2_first_column_index + 1; - field_4_constant_values = ConstantValueParser.parse(in, nValues); - } - - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()).append(" [CRN"); - sb.append(" rowIx=").append(field_3_row_index); - sb.append(" firstColIx=").append(field_2_first_column_index); - sb.append(" lastColIx=").append(field_1_last_column_index); - sb.append("]"); - return sb.toString(); - } - protected int getDataSize() { - return 4 + ConstantValueParser.getEncodedSize(field_4_constant_values); - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(field_1_last_column_index); - out.writeByte(field_2_first_column_index); - out.writeShort(field_3_row_index); - ConstantValueParser.encode(out, field_4_constant_values); - } - - /** - * return the non static version of the id for this record. - */ - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CalcCountRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CalcCountRecord.java deleted file mode 100644 index f416def2f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CalcCountRecord.java +++ /dev/null @@ -1,99 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Calc Count Record - * Description: Specifies the maximum times the gui should perform a formula - * recalculation. For instance: in the case a formula includes - * cells that are themselves a result of a formula and a value - * changes. This is essentially a failsafe against an infinate - * loop in the event the formulas are not independant.

    - * REFERENCE: PG 292 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @version 2.0-pre - * @see org.apache.poi.hssf.record.CalcModeRecord - */ - -public final class CalcCountRecord extends StandardRecord implements Cloneable { - public final static short sid = 0xC; - private short field_1_iterations; - - public CalcCountRecord() - { - } - - public CalcCountRecord(RecordInputStream in) - { - field_1_iterations = in.readShort(); - } - - /** - * set the number of iterations to perform - * @param iterations to perform - */ - - public void setIterations(short iterations) - { - field_1_iterations = iterations; - } - - /** - * get the number of iterations to perform - * @return iterations - */ - - public short getIterations() - { - return field_1_iterations; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CALCCOUNT]\n"); - buffer.append(" .iterations = ") - .append(Integer.toHexString(getIterations())).append("\n"); - buffer.append("[/CALCCOUNT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getIterations()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public CalcCountRecord clone() { - CalcCountRecord rec = new CalcCountRecord(); - rec.field_1_iterations = field_1_iterations; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CalcModeRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CalcModeRecord.java deleted file mode 100644 index 9f74ecf71..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CalcModeRecord.java +++ /dev/null @@ -1,127 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Calc Mode Record

    - * Description: Tells the gui whether to calculate formulas - * automatically, manually or automatically - * except for tables.

    - * REFERENCE: PG 292 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - * @see org.apache.poi.hssf.record.CalcCountRecord - */ - -public final class CalcModeRecord extends StandardRecord implements Cloneable { - public final static short sid = 0xD; - - /** - * manually calculate formulas (0) - */ - - public final static short MANUAL = 0; - - /** - * automatically calculate formulas (1) - */ - - public final static short AUTOMATIC = 1; - - /** - * automatically calculate formulas except for tables (-1) - */ - - public final static short AUTOMATIC_EXCEPT_TABLES = -1; - private short field_1_calcmode; - - public CalcModeRecord() - { - } - - public CalcModeRecord(RecordInputStream in) - { - field_1_calcmode = in.readShort(); - } - - /** - * set the calc mode flag for formulas - * - * @see #MANUAL - * @see #AUTOMATIC - * @see #AUTOMATIC_EXCEPT_TABLES - * - * @param calcmode one of the three flags above - */ - - public void setCalcMode(short calcmode) - { - field_1_calcmode = calcmode; - } - - /** - * get the calc mode flag for formulas - * - * @see #MANUAL - * @see #AUTOMATIC - * @see #AUTOMATIC_EXCEPT_TABLES - * - * @return calcmode one of the three flags above - */ - - public short getCalcMode() - { - return field_1_calcmode; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CALCMODE]\n"); - buffer.append(" .calcmode = ") - .append(Integer.toHexString(getCalcMode())).append("\n"); - buffer.append("[/CALCMODE]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getCalcMode()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public CalcModeRecord clone() { - CalcModeRecord rec = new CalcModeRecord(); - rec.field_1_calcmode = field_1_calcmode; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CellRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CellRecord.java deleted file mode 100644 index 5ae7abebe..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CellRecord.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Base class for all cell value records (implementors of {@link CellValueRecordInterface}). - * Subclasses are expected to manage the cell data values (of various types). - */ -public abstract class CellRecord extends StandardRecord implements CellValueRecordInterface { - private int _rowIndex; - private int _columnIndex; - private int _formatIndex; - - protected CellRecord() { - // fields uninitialised - } - - protected CellRecord(RecordInputStream in) { - _rowIndex = in.readUShort(); - _columnIndex = in.readUShort(); - _formatIndex = in.readUShort(); - } - - @Override - public final void setRow(int row) { - _rowIndex = row; - } - - @Override - public final void setColumn(short col) { - _columnIndex = col; - } - - /** - * set the index to the ExtendedFormat - * - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @param xf index to the XF record - */ - @Override - public final void setXFIndex(short xf) { - _formatIndex = xf; - } - - @Override - public final int getRow() { - return _rowIndex; - } - - @Override - public final short getColumn() { - return (short) _columnIndex; - } - - /** - * get the index to the ExtendedFormat - * - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @return index to the XF record - */ - @Override - public final short getXFIndex() { - return (short) _formatIndex; - } - - @Override - public final String toString() { - StringBuilder sb = new StringBuilder(); - String recordName = getRecordName(); - - sb.append("[").append(recordName).append("]\n"); - sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n"); - sb.append(" .col = ").append(HexDump.shortToHex(getColumn())).append("\n"); - sb.append(" .xfindex= ").append(HexDump.shortToHex(getXFIndex())).append("\n"); - appendValueText(sb); - sb.append("\n"); - sb.append("[/").append(recordName).append("]\n"); - return sb.toString(); - } - - /** - * Append specific debug info (used by {@link #toString()} for the value - * contained in this record. Trailing new-line should not be appended - * (superclass does that). - * - * @param sb the StringBuilder to write to - */ - protected abstract void appendValueText(StringBuilder sb); - - /** - * Gets the debug info BIFF record type name (used by {@link #toString()}. - * - * @return the record type name - */ - protected abstract String getRecordName(); - - /** - * writes out the value data for this cell record - * - * @param out the output - */ - protected abstract void serializeValue(LittleEndianOutput out); - - /** - * @return the size (in bytes) of the value data for this cell record - */ - protected abstract int getValueDataSize(); - - @Override - public final void serialize(LittleEndianOutput out) { - out.writeShort(getRow()); - out.writeShort(getColumn()); - out.writeShort(getXFIndex()); - serializeValue(out); - } - - @Override - protected final int getDataSize() { - return 6 + getValueDataSize(); - } - - protected final void copyBaseFields(CellRecord rec) { - rec._rowIndex = _rowIndex; - rec._columnIndex = _columnIndex; - rec._formatIndex = _formatIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CellValueRecordInterface.java b/trunk/src/java/org/apache/poi/hssf/record/CellValueRecordInterface.java deleted file mode 100644 index c91a400d6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CellValueRecordInterface.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -/** - * The cell value record interface is implemented by all classes of type Record that - * contain cell values. It allows the containing sheet to move through them and compare - * them. - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * - * @see org.apache.poi.hssf.record.Record - * @see org.apache.poi.hssf.record.RecordFactory - */ -public interface CellValueRecordInterface { - - /** - * @return the row this cell occurs on - */ - int getRow(); - - /** - * @return the column this cell defines within the row - */ - short getColumn(); - - /** - * @param row the row this cell occurs within - */ - void setRow(int row); - - /** - * @param col the column this cell defines - */ - void setColumn(short col); - - void setXFIndex(short xf); - - short getXFIndex(); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CodepageRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CodepageRecord.java deleted file mode 100644 index 59f69af61..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CodepageRecord.java +++ /dev/null @@ -1,103 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Codepage Record - *

    Description: the default characterset. for the workbook

    - *

    REFERENCE: PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - *

    Use {@link CodePageUtil} to turn these values into Java code pages - * to encode/decode strings.

    - * @version 2.0-pre - */ - -public final class CodepageRecord - extends StandardRecord -{ - public final static short sid = 0x42; - private short field_1_codepage; // = 0; - - /** - * Excel 97+ (Biff 8) should always store strings as UTF-16LE or - * compressed versions of that. As such, this should always be - * 0x4b0 = UTF_16, except for files coming from older versions. - */ - public final static short CODEPAGE = ( short ) 0x4b0; - - public CodepageRecord() - { - } - - public CodepageRecord(RecordInputStream in) - { - field_1_codepage = in.readShort(); - } - - /** - * set the codepage for this workbook - * - * @see #CODEPAGE - * @param cp the codepage to set - */ - - public void setCodepage(short cp) - { - field_1_codepage = cp; - } - - /** - * get the codepage for this workbook - * - * @see #CODEPAGE - * @return codepage - the codepage to set - */ - - public short getCodepage() - { - return field_1_codepage; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CODEPAGE]\n"); - buffer.append(" .codepage = ") - .append(Integer.toHexString(getCodepage())).append("\n"); - buffer.append("[/CODEPAGE]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getCodepage()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ColumnInfoRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ColumnInfoRecord.java deleted file mode 100644 index 1f48458fd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ColumnInfoRecord.java +++ /dev/null @@ -1,259 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; - -/** - * Title: COLINFO Record (0x007D)

    - * Description: Defines with width and formatting for a range of columns

    - * REFERENCE: PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class ColumnInfoRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x007D; - - private int _firstCol; - private int _lastCol; - private int _colWidth; - private int _xfIndex; - private int _options; - private static final BitField hidden = BitFieldFactory.getInstance(0x01); - private static final BitField outlevel = BitFieldFactory.getInstance(0x0700); - private static final BitField collapsed = BitFieldFactory.getInstance(0x1000); - // Excel seems write values 2, 10, and 260, even though spec says "must be zero" - private int field_6_reserved; - - /** - * Creates a column info record with default width and format - */ - public ColumnInfoRecord() { - setColumnWidth(2275); - _options = 2; - _xfIndex = 0x0f; - field_6_reserved = 2; // seems to be the most common value - } - - public ColumnInfoRecord(RecordInputStream in) { - _firstCol = in.readUShort(); - _lastCol = in.readUShort(); - _colWidth = in.readUShort(); - _xfIndex = in.readUShort(); - _options = in.readUShort(); - switch(in.remaining()) { - case 2: // usual case - field_6_reserved = in.readUShort(); - break; - case 1: - // often COLINFO gets encoded 1 byte short - // shouldn't matter because this field is unused - field_6_reserved = in.readByte(); - break; - case 0: - // According to bugzilla 48332, - // "SoftArtisans OfficeWriter for Excel" totally skips field 6 - // Excel seems to be OK with this, and assumes zero. - field_6_reserved = 0; - break; - default: - throw new RuntimeException("Unusual record size remaining=(" + in.remaining() + ")"); - } - } - - /** - * set the first column this record defines formatting info for - * @param fc - the first column index (0-based) - */ - public void setFirstColumn(int fc) { - _firstCol = fc; - } - - /** - * set the last column this record defines formatting info for - * @param lc - the last column index (0-based) - */ - public void setLastColumn(int lc) { - _lastCol = lc; - } - - /** - * set the columns' width in 1/256 of a character width - * @param cw - column width - */ - public void setColumnWidth(int cw) { - _colWidth = cw; - } - - /** - * set the columns' default format info - * @param xfi - the extended format index - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - */ - public void setXFIndex(int xfi) { - _xfIndex = xfi; - } - - /** - * set whether or not these cells are hidden - * @param ishidden - whether the cells are hidden. - */ - public void setHidden(boolean ishidden) { - _options = hidden.setBoolean(_options, ishidden); - } - - /** - * set the outline level for the cells - * @param olevel -outline level for the cells - */ - public void setOutlineLevel(int olevel) { - _options = outlevel.setValue(_options, olevel); - } - - /** - * set whether the cells are collapsed - * @param isCollapsed - whether the cells are collapsed - */ - public void setCollapsed(boolean isCollapsed) { - _options = collapsed.setBoolean(_options, isCollapsed); - } - - /** - * get the first column this record defines formatting info for - * @return the first column index (0-based) - */ - public int getFirstColumn() { - return _firstCol; - } - - /** - * get the last column this record defines formatting info for - * @return the last column index (0-based) - */ - public int getLastColumn() { - return _lastCol; - } - - /** - * @return column width in units of 1/256 of a character width - */ - public int getColumnWidth() { - return _colWidth; - } - - /** - * get the columns' default format info - * @return the extended format index - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - */ - public int getXFIndex() { - return _xfIndex; - } - - /** - * @return whether the cells are hidden. - */ - public boolean getHidden() { - return hidden.isSet(_options); - } - - /** - * @return outline level for the cells - */ - public int getOutlineLevel() { - return outlevel.getValue(_options); - } - - /** - * @return whether the cells are collapsed - */ - public boolean getCollapsed() { - return collapsed.isSet(_options); - } - - public boolean containsColumn(int columnIndex) { - return _firstCol <= columnIndex && columnIndex <= _lastCol; - } - public boolean isAdjacentBefore(ColumnInfoRecord other) { - return _lastCol == other._firstCol - 1; - } - - /** - * @param other the format to match with - * - * @return {@code true} if the format, options and column width match - */ - public boolean formatMatches(ColumnInfoRecord other) { - if (_xfIndex != other._xfIndex) { - return false; - } - if (_options != other._options) { - return false; - } - if (_colWidth != other._colWidth) { - return false; - } - return true; - } - - public short getSid() { - return sid; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getFirstColumn()); - out.writeShort(getLastColumn()); - out.writeShort(getColumnWidth()); - out.writeShort(getXFIndex()); - out.writeShort(_options); - out.writeShort(field_6_reserved); - } - - protected int getDataSize() { - return 12; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("[COLINFO]\n"); - sb.append(" colfirst = ").append(getFirstColumn()).append("\n"); - sb.append(" collast = ").append(getLastColumn()).append("\n"); - sb.append(" colwidth = ").append(getColumnWidth()).append("\n"); - sb.append(" xfindex = ").append(getXFIndex()).append("\n"); - sb.append(" options = ").append(HexDump.shortToHex(_options)).append("\n"); - sb.append(" hidden = ").append(getHidden()).append("\n"); - sb.append(" olevel = ").append(getOutlineLevel()).append("\n"); - sb.append(" collapsed= ").append(getCollapsed()).append("\n"); - sb.append("[/COLINFO]\n"); - return sb.toString(); - } - - @Override - public ColumnInfoRecord clone() { - ColumnInfoRecord rec = new ColumnInfoRecord(); - rec._firstCol = _firstCol; - rec._lastCol = _lastCol; - rec._colWidth = _colWidth; - rec._xfIndex = _xfIndex; - rec._options = _options; - rec.field_6_reserved = field_6_reserved; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CommonObjectDataSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CommonObjectDataSubRecord.java deleted file mode 100644 index 18be70cc9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CommonObjectDataSubRecord.java +++ /dev/null @@ -1,436 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The common object data record is used to store all common preferences for an excel object. - */ -public final class CommonObjectDataSubRecord extends SubRecord implements Cloneable { - public final static short sid = 0x0015; - - private static final BitField locked = BitFieldFactory.getInstance(0x0001); - private static final BitField printable = BitFieldFactory.getInstance(0x0010); - private static final BitField autofill = BitFieldFactory.getInstance(0x2000); - private static final BitField autoline = BitFieldFactory.getInstance(0x4000); - - public final static short OBJECT_TYPE_GROUP = 0; - public final static short OBJECT_TYPE_LINE = 1; - public final static short OBJECT_TYPE_RECTANGLE = 2; - public final static short OBJECT_TYPE_OVAL = 3; - public final static short OBJECT_TYPE_ARC = 4; - public final static short OBJECT_TYPE_CHART = 5; - public final static short OBJECT_TYPE_TEXT = 6; - public final static short OBJECT_TYPE_BUTTON = 7; - public final static short OBJECT_TYPE_PICTURE = 8; - public final static short OBJECT_TYPE_POLYGON = 9; - public final static short OBJECT_TYPE_RESERVED1 = 10; - public final static short OBJECT_TYPE_CHECKBOX = 11; - public final static short OBJECT_TYPE_OPTION_BUTTON = 12; - public final static short OBJECT_TYPE_EDIT_BOX = 13; - public final static short OBJECT_TYPE_LABEL = 14; - public final static short OBJECT_TYPE_DIALOG_BOX = 15; - public final static short OBJECT_TYPE_SPINNER = 16; - public final static short OBJECT_TYPE_SCROLL_BAR = 17; - public final static short OBJECT_TYPE_LIST_BOX = 18; - public final static short OBJECT_TYPE_GROUP_BOX = 19; - public final static short OBJECT_TYPE_COMBO_BOX = 20; - public final static short OBJECT_TYPE_RESERVED2 = 21; - public final static short OBJECT_TYPE_RESERVED3 = 22; - public final static short OBJECT_TYPE_RESERVED4 = 23; - public final static short OBJECT_TYPE_RESERVED5 = 24; - public final static short OBJECT_TYPE_COMMENT = 25; - public final static short OBJECT_TYPE_RESERVED6 = 26; - public final static short OBJECT_TYPE_RESERVED7 = 27; - public final static short OBJECT_TYPE_RESERVED8 = 28; - public final static short OBJECT_TYPE_RESERVED9 = 29; - public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30; - - private short field_1_objectType; - private int field_2_objectId; - private short field_3_option; - private int field_4_reserved1; - private int field_5_reserved2; - private int field_6_reserved3; - - - public CommonObjectDataSubRecord() - { - - } - - public CommonObjectDataSubRecord(LittleEndianInput in, int size) { - if (size != 18) { - throw new RecordFormatException("Expected size 18 but got (" + size + ")"); - } - field_1_objectType = in.readShort(); - field_2_objectId = in.readUShort(); - field_3_option = in.readShort(); - field_4_reserved1 = in.readInt(); - field_5_reserved2 = in.readInt(); - field_6_reserved3 = in.readInt(); - } - - @Override - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ftCmo]\n"); - buffer.append(" .objectType = ") - .append("0x").append(HexDump.toHex( getObjectType ())) - .append(" (").append( getObjectType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .objectId = ") - .append("0x").append(HexDump.toHex( getObjectId ())) - .append(" (").append( getObjectId() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .option = ") - .append("0x").append(HexDump.toHex( getOption ())) - .append(" (").append( getOption() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .locked = ").append(isLocked()).append('\n'); - buffer.append(" .printable = ").append(isPrintable()).append('\n'); - buffer.append(" .autofill = ").append(isAutofill()).append('\n'); - buffer.append(" .autoline = ").append(isAutoline()).append('\n'); - buffer.append(" .reserved1 = ") - .append("0x").append(HexDump.toHex( getReserved1 ())) - .append(" (").append( getReserved1() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .reserved2 = ") - .append("0x").append(HexDump.toHex( getReserved2 ())) - .append(" (").append( getReserved2() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .reserved3 = ") - .append("0x").append(HexDump.toHex( getReserved3 ())) - .append(" (").append( getReserved3() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/ftCmo]\n"); - return buffer.toString(); - } - - @Override - public void serialize(LittleEndianOutput out) { - - out.writeShort(sid); - out.writeShort(getDataSize()); - - out.writeShort(field_1_objectType); - out.writeShort(field_2_objectId); - out.writeShort(field_3_option); - out.writeInt(field_4_reserved1); - out.writeInt(field_5_reserved2); - out.writeInt(field_6_reserved3); - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 4 + 4 + 4; - } - - /** - * @return the record sid - */ - public short getSid() - { - return sid; - } - - @Override - public CommonObjectDataSubRecord clone() { - CommonObjectDataSubRecord rec = new CommonObjectDataSubRecord(); - - rec.field_1_objectType = field_1_objectType; - rec.field_2_objectId = field_2_objectId; - rec.field_3_option = field_3_option; - rec.field_4_reserved1 = field_4_reserved1; - rec.field_5_reserved2 = field_5_reserved2; - rec.field_6_reserved3 = field_6_reserved3; - return rec; - } - - - /** - * Get the object type field for the CommonObjectData record. - * - * @return One of - * OBJECT_TYPE_GROUP - * OBJECT_TYPE_LINE - * OBJECT_TYPE_RECTANGLE - * OBJECT_TYPE_OVAL - * OBJECT_TYPE_ARC - * OBJECT_TYPE_CHART - * OBJECT_TYPE_TEXT - * OBJECT_TYPE_BUTTON - * OBJECT_TYPE_PICTURE - * OBJECT_TYPE_POLYGON - * OBJECT_TYPE_RESERVED1 - * OBJECT_TYPE_CHECKBOX - * OBJECT_TYPE_OPTION_BUTTON - * OBJECT_TYPE_EDIT_BOX - * OBJECT_TYPE_LABEL - * OBJECT_TYPE_DIALOG_BOX - * OBJECT_TYPE_SPINNER - * OBJECT_TYPE_SCROLL_BAR - * OBJECT_TYPE_LIST_BOX - * OBJECT_TYPE_GROUP_BOX - * OBJECT_TYPE_COMBO_BOX - * OBJECT_TYPE_RESERVED2 - * OBJECT_TYPE_RESERVED3 - * OBJECT_TYPE_RESERVED4 - * OBJECT_TYPE_RESERVED5 - * OBJECT_TYPE_COMMENT - * OBJECT_TYPE_RESERVED6 - * OBJECT_TYPE_RESERVED7 - * OBJECT_TYPE_RESERVED8 - * OBJECT_TYPE_RESERVED9 - * OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING - */ - public short getObjectType() - { - return field_1_objectType; - } - - /** - * Set the object type field for the CommonObjectData record. - * - * @param field_1_objectType - * One of - * OBJECT_TYPE_GROUP - * OBJECT_TYPE_LINE - * OBJECT_TYPE_RECTANGLE - * OBJECT_TYPE_OVAL - * OBJECT_TYPE_ARC - * OBJECT_TYPE_CHART - * OBJECT_TYPE_TEXT - * OBJECT_TYPE_BUTTON - * OBJECT_TYPE_PICTURE - * OBJECT_TYPE_POLYGON - * OBJECT_TYPE_RESERVED1 - * OBJECT_TYPE_CHECKBOX - * OBJECT_TYPE_OPTION_BUTTON - * OBJECT_TYPE_EDIT_BOX - * OBJECT_TYPE_LABEL - * OBJECT_TYPE_DIALOG_BOX - * OBJECT_TYPE_SPINNER - * OBJECT_TYPE_SCROLL_BAR - * OBJECT_TYPE_LIST_BOX - * OBJECT_TYPE_GROUP_BOX - * OBJECT_TYPE_COMBO_BOX - * OBJECT_TYPE_RESERVED2 - * OBJECT_TYPE_RESERVED3 - * OBJECT_TYPE_RESERVED4 - * OBJECT_TYPE_RESERVED5 - * OBJECT_TYPE_COMMENT - * OBJECT_TYPE_RESERVED6 - * OBJECT_TYPE_RESERVED7 - * OBJECT_TYPE_RESERVED8 - * OBJECT_TYPE_RESERVED9 - * OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING - */ - public void setObjectType(short field_1_objectType) - { - this.field_1_objectType = field_1_objectType; - } - - /** - * Get the object id field for the CommonObjectData record. - * - * @return the object id field - */ - public int getObjectId() - { - return field_2_objectId; - } - - /** - * Set the object id field for the CommonObjectData record. - * - * @param field_2_objectId the object id field - */ - public void setObjectId(int field_2_objectId) - { - this.field_2_objectId = field_2_objectId; - } - - /** - * Get the option field for the CommonObjectData record. - * - * @return the option field - */ - public short getOption() - { - return field_3_option; - } - - /** - * Set the option field for the CommonObjectData record. - * - * @param field_3_option the option field - */ - public void setOption(short field_3_option) - { - this.field_3_option = field_3_option; - } - - /** - * Get the reserved1 field for the CommonObjectData record. - * - * @return the reserved1 field - */ - public int getReserved1() - { - return field_4_reserved1; - } - - /** - * Set the reserved1 field for the CommonObjectData record. - * - * @param field_4_reserved1 the reserved1 field - */ - public void setReserved1(int field_4_reserved1) - { - this.field_4_reserved1 = field_4_reserved1; - } - - /** - * Get the reserved2 field for the CommonObjectData record. - * - * @return the reserved2 field - */ - public int getReserved2() - { - return field_5_reserved2; - } - - /** - * Set the reserved2 field for the CommonObjectData record. - * - * @param field_5_reserved2 the reserved2 field - */ - public void setReserved2(int field_5_reserved2) - { - this.field_5_reserved2 = field_5_reserved2; - } - - /** - * Get the reserved3 field for the CommonObjectData record. - * - * @return the reserved3 field - */ - public int getReserved3() - { - return field_6_reserved3; - } - - /** - * Set the reserved3 field for the CommonObjectData record. - * - * @param field_6_reserved3 the reserved3 field - */ - public void setReserved3(int field_6_reserved3) - { - this.field_6_reserved3 = field_6_reserved3; - } - - /** - * Sets the locked field value. - * true if object is locked when sheet has been protected - * - * @param value {@code true} if object is locked when sheet has been protected - */ - public void setLocked(boolean value) - { - field_3_option = locked.setShortBoolean(field_3_option, value); - } - - /** - * true if object is locked when sheet has been protected - * @return the locked field value. - */ - public boolean isLocked() - { - return locked.isSet(field_3_option); - } - - /** - * Sets the printable field value. - * object appears when printed - * - * @param value {@code true} if object appears when printed - */ - public void setPrintable(boolean value) - { - field_3_option = printable.setShortBoolean(field_3_option, value); - } - - /** - * object appears when printed - * @return the printable field value. - */ - public boolean isPrintable() - { - return printable.isSet(field_3_option); - } - - /** - * Sets the autofill field value. - * whether object uses an automatic fill style - * - * @param value {@code true} if object uses an automatic fill style - */ - public void setAutofill(boolean value) - { - field_3_option = autofill.setShortBoolean(field_3_option, value); - } - - /** - * whether object uses an automatic fill style - * @return the autofill field value. - */ - public boolean isAutofill() - { - return autofill.isSet(field_3_option); - } - - /** - * Sets the autoline field value. - * whether object uses an automatic line style - * - * @param value {@code true} if object uses an automatic line style - */ - public void setAutoline(boolean value) - { - field_3_option = autoline.setShortBoolean(field_3_option, value); - } - - /** - * whether object uses an automatic line style - * @return the autoline field value. - */ - public boolean isAutoline() - { - return autoline.isSet(field_3_option); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ContinueRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ContinueRecord.java deleted file mode 100644 index 17a0c5165..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ContinueRecord.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Continue Record(0x003C) - Helper class used primarily for SST Records

    - * Description: handles overflow for prior record in the input - * stream; content is tailored to that prior record

    - * @author Marc Johnson (mjohnson at apache dot org) - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Csaba Nagy (ncsaba at yahoo dot com) - */ -public final class ContinueRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x003C; - private byte[] _data; - - public ContinueRecord(byte[] data) { - _data = data; - } - - protected int getDataSize() { - return _data.length; - } - - public void serialize(LittleEndianOutput out) { - out.write(_data); - } - - /** - * get the data for continuation - * @return byte array containing all of the continued data - */ - public byte[] getData() { - return _data; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CONTINUE RECORD]\n"); - buffer.append(" .data = ").append(HexDump.toHex(_data)).append("\n"); - buffer.append("[/CONTINUE RECORD]\n"); - return buffer.toString(); - } - - public short getSid() { - return sid; - } - - public ContinueRecord(RecordInputStream in) { - _data = in.readRemainder(); - } - - @Override - public ContinueRecord clone() { - return new ContinueRecord(_data); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/CountryRecord.java b/trunk/src/java/org/apache/poi/hssf/record/CountryRecord.java deleted file mode 100644 index 44181aa3e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/CountryRecord.java +++ /dev/null @@ -1,123 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Country Record (aka WIN.INI country)

    - * Description: used for localization. Currently HSSF always sets this to 1 - * and it seems to work fine even in Germany. (es geht's auch fuer Deutschland)

    - * - * REFERENCE: PG 298 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class CountryRecord - extends StandardRecord -{ - public final static short sid = 0x8c; - - // 1 for US - private short field_1_default_country; - private short field_2_current_country; - - public CountryRecord() - { - } - - public CountryRecord(RecordInputStream in) - { - field_1_default_country = in.readShort(); - field_2_current_country = in.readShort(); - } - - /** - * sets the default country - * - * @param country ID to set (1 = US) - */ - - public void setDefaultCountry(short country) - { - field_1_default_country = country; - } - - /** - * sets the current country - * - * @param country ID to set (1 = US) - */ - - public void setCurrentCountry(short country) - { - field_2_current_country = country; - } - - /** - * gets the default country - * - * @return country ID (1 = US) - */ - - public short getDefaultCountry() - { - return field_1_default_country; - } - - /** - * gets the current country - * - * @return country ID (1 = US) - */ - - public short getCurrentCountry() - { - return field_2_current_country; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[COUNTRY]\n"); - buffer.append(" .defaultcountry = ") - .append(Integer.toHexString(getDefaultCountry())).append("\n"); - buffer.append(" .currentcountry = ") - .append(Integer.toHexString(getCurrentCountry())).append("\n"); - buffer.append("[/COUNTRY]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getDefaultCountry()); - out.writeShort(getCurrentCountry()); - } - - protected int getDataSize() { - return 4; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DBCellRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DBCellRecord.java deleted file mode 100644 index c4080f0ad..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DBCellRecord.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: DBCell Record (0x00D7)

    - * Description: Used by Excel and other MS apps to quickly find rows in the sheets.

    - * REFERENCE: PG 299/440 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class DBCellRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x00D7; - public final static int BLOCK_SIZE = 32; - - public static final class Builder { - private short[] _cellOffsets; - private int _nCellOffsets; - public Builder() { - _cellOffsets = new short[4]; - } - - public void addCellOffset(int cellRefOffset) { - if (_cellOffsets.length <= _nCellOffsets) { - short[] temp = new short[_nCellOffsets * 2]; - System.arraycopy(_cellOffsets, 0, temp, 0, _nCellOffsets); - _cellOffsets = temp; - } - _cellOffsets[_nCellOffsets] = (short) cellRefOffset; - _nCellOffsets++; - } - - public DBCellRecord build(int rowOffset) { - short[] cellOffsets = new short[_nCellOffsets]; - System.arraycopy(_cellOffsets, 0, cellOffsets, 0, _nCellOffsets); - return new DBCellRecord(rowOffset, cellOffsets); - } - } - /** - * offset from the start of this DBCellRecord to the start of the first cell in - * the next DBCell block. - */ - private final int field_1_row_offset; - private final short[] field_2_cell_offsets; - - DBCellRecord(int rowOffset, short[]cellOffsets) { - field_1_row_offset = rowOffset; - field_2_cell_offsets = cellOffsets; - } - - public DBCellRecord(RecordInputStream in) { - field_1_row_offset = in.readUShort(); - int size = in.remaining(); - field_2_cell_offsets = new short[ size / 2 ]; - - for (int i=0;iDBCellRecords needed to encode - * the specified number of blocks and rows - * - * @deprecated in POI 3.15-beta2, scheduled for removal in POI 3.17 - this method is not used within POI - */ - public static int calculateSizeOfRecords(int nBlocks, int nRows) { - // One DBCell per block. - // 8 bytes per DBCell (non variable section) - // 2 bytes per row reference - return nBlocks * 8 + nRows * 2; - } - - public short getSid() { - return sid; - } - - @Override - public DBCellRecord clone() { - // safe because immutable - return this; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java deleted file mode 100644 index 90bed261d..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.hssf.record; - -import java.util.Arrays; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * DConRef records specify a range in a workbook (internal or external) that serves as a data source - * for pivot tables or data consolidation. - * - * Represents a DConRef Structure - * [MS-XLS s. - * 2.4.86], and the contained DConFile structure - * - * [MS-XLS s. 2.5.69]. This in turn contains a XLUnicodeStringNoCch - * - * [MS-XLS s. 2.5.296]. - * - *

    - *         _______________________________
    - *        |          DConRef              |
    - *(bytes) +-+-+-+-+-+-+-+-+-+-+...+-+-+-+-+
    - *        |    ref    |cch|  stFile   | un|
    - *        +-+-+-+-+-+-+-+-+-+-+...+-+-+-+-+
    - *                              |
    - *                     _________|_____________________
    - *                    |DConFile / XLUnicodeStringNoCch|
    - *                    +-+-+-+-+-+-+-+-+-+-+-+...+-+-+-+
    - *             (bits) |h|   reserved  |      rgb      |
    - *                    +-+-+-+-+-+-+-+-+-+-+-+...+-+-+-+
    - * 
    - * Where - *
      - *
    • DConFile.h = 0x00 if the characters inrgb are single byte, and - * DConFile.h = 0x01 if they are double byte.

      - * If they are double byte, then - *

        - *
      • If it exists, the length of DConRef.un = 2. Otherwise it is 1. - *
      • The length of DConFile.rgb = (2 * DConRef.cch). Otherwise it is equal to - * DConRef.cch. - *
      - *
    • DConRef.rgb starts with 0x01 if it is an external reference, - * and with 0x02 if it is a self-reference. - *
    - * - * At the moment this class is read-only. - */ -public class DConRefRecord extends StandardRecord -{ - - /** - * The id of the record type, - * sid = {@value} - */ - public static final short sid = 0x0051; - /** - * A RefU structure specifying the range of cells if this record is part of an SXTBL. - * - * [MS XLS s.2.5.211] - */ - private int firstRow, lastRow, firstCol, lastCol; - /** - * the number of chars in the link - */ - private int charCount; - /** - * the type of characters (single or double byte) - */ - private int charType; - /** - * The link's path string. This is the rgb field of a - * XLUnicodeStringNoCch. Therefore it will contain at least one leading special - * character (0x01 or 0x02) and probably other ones.

    - * @see - * DConFile [MS-XLS s. 2.5.77] and - * - * VirtualPath [MS-XLS s. 2.5.69] - *

    - */ - private byte[] path; - /** - * unused bits at the end, must be set to 0. - */ - private byte[] _unused; - - /** - * Read constructor. - * - * @param data byte array containing a DConRef Record, including the header. - */ - public DConRefRecord(byte[] data) - { - int offset = 0; - if (!(LittleEndian.getShort(data, offset) == DConRefRecord.sid)) - throw new RecordFormatException("incompatible sid."); - offset += LittleEndian.SHORT_SIZE; - - //length = LittleEndian.getShort(data, offset); - offset += LittleEndian.SHORT_SIZE; - - firstRow = LittleEndian.getUShort(data, offset); - offset += LittleEndian.SHORT_SIZE; - lastRow = LittleEndian.getUShort(data, offset); - offset += LittleEndian.SHORT_SIZE; - firstCol = LittleEndian.getUByte(data, offset); - offset += LittleEndian.BYTE_SIZE; - lastCol = LittleEndian.getUByte(data, offset); - offset += LittleEndian.BYTE_SIZE; - charCount = LittleEndian.getUShort(data, offset); - offset += LittleEndian.SHORT_SIZE; - if (charCount < 2) - throw new org.apache.poi.hssf.record.RecordFormatException( - "Character count must be >= 2"); - - charType = LittleEndian.getUByte(data, offset); - offset += LittleEndian.BYTE_SIZE; //7 bits reserved + 1 bit type - - /* - * bytelength is the length of the string in bytes, which depends on whether the string is - * made of single- or double-byte chars. This is given by charType, which equals 0 if - * single-byte, 1 if double-byte. - */ - int byteLength = charCount * ((charType & 1) + 1); - - path = LittleEndian.getByteArray(data, offset, byteLength); - offset += byteLength; - - /* - * If it's a self reference, the last one or two bytes (depending on char type) are the - * unused field. Not sure If i need to bother with this... - */ - if (path[0] == 0x02) - _unused = LittleEndian.getByteArray(data, offset, (charType + 1)); - - } - - /** - * Read Constructor. - * - * @param inStream RecordInputStream containing a DConRefRecord structure. - */ - public DConRefRecord(RecordInputStream inStream) - { - if (inStream.getSid() != sid) - throw new RecordFormatException("Wrong sid: " + inStream.getSid()); - - firstRow = inStream.readUShort(); - lastRow = inStream.readUShort(); - firstCol = inStream.readUByte(); - lastCol = inStream.readUByte(); - - charCount = inStream.readUShort(); - charType = inStream.readUByte() & 0x01; //first bit only. - - // byteLength depends on whether we are using single- or double-byte chars. - int byteLength = charCount * (charType + 1); - - path = new byte[byteLength]; - inStream.readFully(path); - - if (path[0] == 0x02) - _unused = inStream.readRemainder(); - - } - - /* - * assuming this wants the number of bytes returned by {@link serialize(LittleEndianOutput)}, - * that is, (length - 4). - */ - @Override - protected int getDataSize() - { - int sz = 9 + path.length; - if (path[0] == 0x02) - sz += _unused.length; - return sz; - } - - @Override - protected void serialize(LittleEndianOutput out) - { - out.writeShort(firstRow); - out.writeShort(lastRow); - out.writeByte(firstCol); - out.writeByte(lastCol); - out.writeShort(charCount); - out.writeByte(charType); - out.write(path); - if (path[0] == 0x02) - out.write(_unused); - } - - @Override - public short getSid() - { - return sid; - } - - /** - * @return The first column of the range. - */ - public int getFirstColumn() - { - return firstCol; - } - - /** - * @return The first row of the range. - */ - public int getFirstRow() - { - return firstRow; - } - - /** - * @return The last column of the range. - */ - public int getLastColumn() - { - return lastCol; - } - - /** - * @return The last row of the range. - */ - public int getLastRow() - { - return lastRow; - } - - @Override - public String toString() - { - StringBuilder b = new StringBuilder(); - b.append("[DCONREF]\n"); - b.append(" .ref\n"); - b.append(" .firstrow = ").append(firstRow).append("\n"); - b.append(" .lastrow = ").append(lastRow).append("\n"); - b.append(" .firstcol = ").append(firstCol).append("\n"); - b.append(" .lastcol = ").append(lastCol).append("\n"); - b.append(" .cch = ").append(charCount).append("\n"); - b.append(" .stFile\n"); - b.append(" .h = ").append(charType).append("\n"); - b.append(" .rgb = ").append(getReadablePath()).append("\n"); - b.append("[/DCONREF]\n"); - - return b.toString(); - } - - /** - * - * @return raw path byte array. - */ - public byte[] getPath() - { - return Arrays.copyOf(path, path.length); - } - - /** - * @return the link's path, with the special characters stripped/replaced. May be null. - * See MS-XLS 2.5.277 (VirtualPath) - */ - public String getReadablePath() - { - if (path != null) - { - //all of the path strings start with either 0x02 or 0x01 followed by zero or - //more of 0x01..0x08 - int offset = 1; - while (path[offset] < 0x20 && offset < path.length) - { - offset++; - } - String out = new String(Arrays.copyOfRange(path, offset, path.length), StringUtil.UTF8); - //UNC paths have \u0003 chars as path separators. - out = out.replaceAll("\u0003", "/"); - return out; - } - return null; - } - - /** - * Checks if the data source in this reference record is external to this sheet or internal. - * - * @return true iff this is an external reference. - */ - public boolean isExternalRef() - { - if (path[0] == 0x01) - return true; - return false; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DSFRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DSFRecord.java deleted file mode 100644 index 8d28562ae..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DSFRecord.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Double Stream Flag Record (0x0161)

    - * Description: tells if this is a double stream file. (always no for HSSF generated files)

    - * Double Stream files contain both BIFF8 and BIFF7 workbooks.

    - * REFERENCE: PG 305 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class DSFRecord extends StandardRecord { - public final static short sid = 0x0161; - - private static final BitField biff5BookStreamFlag = BitFieldFactory.getInstance(0x0001); - - private int _options; - - private DSFRecord(int options) { - _options = options; - } - public DSFRecord(boolean isBiff5BookStreamPresent) { - this(0); - _options = biff5BookStreamFlag.setBoolean(0, isBiff5BookStreamPresent); - } - - public DSFRecord(RecordInputStream in) { - this(in.readShort()); - } - - public boolean isBiff5BookStreamPresent() { - return biff5BookStreamFlag.isSet(_options); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[DSF]\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(_options)).append("\n"); - buffer.append("[/DSF]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_options); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DVALRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DVALRecord.java deleted file mode 100644 index fd7163a52..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DVALRecord.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: DATAVALIDATIONS Record (0x01B2)

    - * Description: used in data validation ; - * This record is the list header of all data validation records (0x01BE) in the current sheet. - */ -public final class DVALRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x01B2; - - /** Options of the DVAL */ - private short field_1_options; - /** Horizontal position of the dialog */ - private int field_2_horiz_pos; - /** Vertical position of the dialog */ - private int field_3_vert_pos; - - /** Object ID of the drop down arrow object for list boxes ; - * in our case this will be always FFFF , until - * MSODrawingGroup and MSODrawing records are implemented */ - private int field_cbo_id; - - /** Number of following DV Records */ - private int field_5_dv_no; - - public DVALRecord() { - field_cbo_id = 0xFFFFFFFF; - field_5_dv_no = 0x00000000; - } - - public DVALRecord(RecordInputStream in) { - field_1_options = in.readShort(); - field_2_horiz_pos = in.readInt(); - field_3_vert_pos = in.readInt(); - field_cbo_id = in.readInt(); - field_5_dv_no = in.readInt(); - } - - /** - * @param options the options of the dialog - */ - public void setOptions(short options) { - field_1_options = options; - } - - /** - * @param horiz_pos the Horizontal position of the dialog - */ - public void setHorizontalPos(int horiz_pos) { - field_2_horiz_pos = horiz_pos; - } - - /** - * @param vert_pos the Vertical position of the dialog - */ - public void setVerticalPos(int vert_pos) { - field_3_vert_pos = vert_pos; - } - - /** - * set the object ID of the drop down arrow object for list boxes - * @param cboID - Object ID - */ - public void setObjectID(int cboID) { - field_cbo_id = cboID; - } - - /** - * Set the number of following DV records - * @param dvNo - the DV records number - */ - public void setDVRecNo(int dvNo) { - field_5_dv_no = dvNo; - } - - /** - * @return the field_1_options - */ - public short getOptions() { - return field_1_options; - } - - /** - * @return the Horizontal position of the dialog - */ - public int getHorizontalPos() { - return field_2_horiz_pos; - } - - /** - * @return the the Vertical position of the dialog - */ - public int getVerticalPos() { - return field_3_vert_pos; - } - - /** - * @return the Object ID of the drop down arrow object for list boxes - */ - public int getObjectID() { - return field_cbo_id; - } - - /** - * @return the number of following DV records - */ - public int getDVRecNo() { - return field_5_dv_no; - } - - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[DVAL]\n"); - buffer.append(" .options = ").append(getOptions()).append('\n'); - buffer.append(" .horizPos = ").append(getHorizontalPos()).append('\n'); - buffer.append(" .vertPos = ").append(getVerticalPos()).append('\n'); - buffer.append(" .comboObjectID = ").append(Integer.toHexString(getObjectID())).append("\n"); - buffer.append(" .DVRecordsNumber = ").append(Integer.toHexString(getDVRecNo())).append("\n"); - buffer.append("[/DVAL]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - - out.writeShort(getOptions()); - out.writeInt(getHorizontalPos()); - out.writeInt(getVerticalPos()); - out.writeInt(getObjectID()); - out.writeInt(getDVRecNo()); - } - - protected int getDataSize() { - return 18; - } - - public short getSid() { - return sid; - } - - @Override - public DVALRecord clone() { - DVALRecord rec = new DVALRecord(); - rec.field_1_options = field_1_options; - rec.field_2_horiz_pos = field_2_horiz_pos; - rec.field_3_vert_pos = field_3_vert_pos; - rec.field_cbo_id = field_cbo_id; - rec.field_5_dv_no = field_5_dv_no; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java deleted file mode 100644 index 68d560afd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java +++ /dev/null @@ -1,350 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.hssf.usermodel.HSSFDataValidation; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.util.BitField; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: DATAVALIDATION Record (0x01BE)

    - * Description: This record stores data validation settings and a list of cell ranges - * which contain these settings. The data validation settings of a sheet - * are stored in a sequential list of DV records. This list is followed by - * DVAL record(s) - */ -public final class DVRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x01BE; - - /** the unicode string used for error/prompt title/text when not present */ - private static final UnicodeString NULL_TEXT_STRING = new UnicodeString("\0"); - - /** Option flags */ - private int _option_flags; - /** Title of the prompt box */ - private UnicodeString _promptTitle; - /** Title of the error box */ - private UnicodeString _errorTitle; - /** Text of the prompt box */ - private UnicodeString _promptText; - /** Text of the error box */ - private UnicodeString _errorText; - /** Not used - Excel seems to always write 0x3FE0 */ - private short _not_used_1 = 0x3FE0; - /** Formula data for first condition (RPN token array without size field) */ - private Formula _formula1; - /** Not used - Excel seems to always write 0x0000 */ - private short _not_used_2 = 0x0000; - /** Formula data for second condition (RPN token array without size field) */ - private Formula _formula2; - /** Cell range address list with all affected ranges */ - private CellRangeAddressList _regions; - - /** - * Option flags field - * - * @see HSSFDataValidation utility class - */ - private static final BitField opt_data_type = new BitField(0x0000000F); - private static final BitField opt_error_style = new BitField(0x00000070); - private static final BitField opt_string_list_formula = new BitField(0x00000080); - private static final BitField opt_empty_cell_allowed = new BitField(0x00000100); - private static final BitField opt_suppress_dropdown_arrow = new BitField(0x00000200); - private static final BitField opt_show_prompt_on_cell_selected = new BitField(0x00040000); - private static final BitField opt_show_error_on_invalid_value = new BitField(0x00080000); - private static final BitField opt_condition_operator = new BitField(0x00700000); - - public DVRecord(int validationType, int operator, int errorStyle, boolean emptyCellAllowed, - boolean suppressDropDownArrow, boolean isExplicitList, - boolean showPromptBox, String promptTitle, String promptText, - boolean showErrorBox, String errorTitle, String errorText, - Ptg[] formula1, Ptg[] formula2, - CellRangeAddressList regions) { - - int flags = 0; - flags = opt_data_type.setValue(flags, validationType); - flags = opt_condition_operator.setValue(flags, operator); - flags = opt_error_style.setValue(flags, errorStyle); - flags = opt_empty_cell_allowed.setBoolean(flags, emptyCellAllowed); - flags = opt_suppress_dropdown_arrow.setBoolean(flags, suppressDropDownArrow); - flags = opt_string_list_formula.setBoolean(flags, isExplicitList); - flags = opt_show_prompt_on_cell_selected.setBoolean(flags, showPromptBox); - flags = opt_show_error_on_invalid_value.setBoolean(flags, showErrorBox); - _option_flags = flags; - _promptTitle = resolveTitleText(promptTitle); - _promptText = resolveTitleText(promptText); - _errorTitle = resolveTitleText(errorTitle); - _errorText = resolveTitleText(errorText); - _formula1 = Formula.create(formula1); - _formula2 = Formula.create(formula2); - _regions = regions; - } - - public DVRecord(RecordInputStream in) { - - _option_flags = in.readInt(); - - _promptTitle = readUnicodeString(in); - _errorTitle = readUnicodeString(in); - _promptText = readUnicodeString(in); - _errorText = readUnicodeString(in); - - int field_size_first_formula = in.readUShort(); - _not_used_1 = in.readShort(); - - // "You may not use unions, intersections or array constants in Data Validation criteria" - - // read first formula data condition - _formula1 = Formula.read(field_size_first_formula, in); - - int field_size_sec_formula = in.readUShort(); - _not_used_2 = in.readShort(); - - // read sec formula data condition - _formula2 = Formula.read(field_size_sec_formula, in); - - // read cell range address list with all affected ranges - _regions = new CellRangeAddressList(in); - } - - // --> start option flags - /** - * @return the condition data type - * @see org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType - */ - public int getDataType() { - return opt_data_type.getValue(_option_flags); - } - - /** - * @return the condition error style - * @see org.apache.poi.ss.usermodel.DataValidation.ErrorStyle - */ - public int getErrorStyle() { - return opt_error_style.getValue(_option_flags); - } - - /** - * @return true if in list validations the string list is explicitly given in the - * formula, false otherwise - */ - public boolean getListExplicitFormula() { - return (opt_string_list_formula.isSet(_option_flags)); - } - - /** - * @return true if empty values are allowed in cells, false otherwise - */ - public boolean getEmptyCellAllowed() { - return (opt_empty_cell_allowed.isSet(_option_flags)); - } - - - /** - * @return true if drop down arrow should be suppressed when list validation is - * used, false otherwise - */ - public boolean getSuppressDropdownArrow() { - return (opt_suppress_dropdown_arrow.isSet(_option_flags)); - } - - /** - * @return true if a prompt window should appear when cell is selected, false otherwise - */ - public boolean getShowPromptOnCellSelected() { - return (opt_show_prompt_on_cell_selected.isSet(_option_flags)); - } - - /** - * @return true if an error window should appear when an invalid value is entered - * in the cell, false otherwise - */ - public boolean getShowErrorOnInvalidValue() { - return (opt_show_error_on_invalid_value.isSet(_option_flags)); - } - - /** - * get the condition operator - * @return the condition operator - * @see HSSFDataValidation utility class - */ - public int getConditionOperator() { - return opt_condition_operator.getValue(_option_flags); - } - // <-- end option flags - - public String getPromptTitle() { - return resolveTitleString(_promptTitle); - } - - public String getErrorTitle() { - return resolveTitleString(_errorTitle); - } - - public String getPromptText() { - return resolveTitleString(_promptText); - } - - public String getErrorText() { - return resolveTitleString(_errorText); - } - - public Ptg[] getFormula1() { - return Formula.getTokens(_formula1); - } - - public Ptg[] getFormula2() { - return Formula.getTokens(_formula2); - } - - public CellRangeAddressList getCellRangeAddress() { - return this._regions; - } - - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("[DV]\n"); - sb.append(" options=").append(Integer.toHexString(_option_flags)); - sb.append(" title-prompt=").append(formatTextTitle(_promptTitle)); - sb.append(" title-error=").append(formatTextTitle(_errorTitle)); - sb.append(" text-prompt=").append(formatTextTitle(_promptText)); - sb.append(" text-error=").append(formatTextTitle(_errorText)); - sb.append("\n"); - appendFormula(sb, "Formula 1:", _formula1); - appendFormula(sb, "Formula 2:", _formula2); - sb.append("Regions: "); - int nRegions = _regions.countRanges(); - for(int i=0; i0) { - sb.append(", "); - } - CellRangeAddress addr = _regions.getCellRangeAddress(i); - sb.append('(').append(addr.getFirstRow()).append(',').append(addr.getLastRow()); - sb.append(',').append(addr.getFirstColumn()).append(',').append(addr.getLastColumn()).append(')'); - } - sb.append("\n"); - sb.append("[/DV]"); - - return sb.toString(); - } - - private static String formatTextTitle(UnicodeString us) { - String str = us.getString(); - if (str.length() == 1 && str.charAt(0) == '\0') { - return "'\\0'"; - } - return str; - } - - private static void appendFormula(StringBuffer sb, String label, Formula f) { - sb.append(label); - - if (f == null) { - sb.append("\n"); - return; - } - Ptg[] ptgs = f.getTokens(); - sb.append('\n'); - for (int i = 0; i < ptgs.length; i++) { - sb.append('\t').append(ptgs[i].toString()).append('\n'); - } - } - - public void serialize(LittleEndianOutput out) { - - out.writeInt(_option_flags); - - serializeUnicodeString(_promptTitle, out); - serializeUnicodeString(_errorTitle, out); - serializeUnicodeString(_promptText, out); - serializeUnicodeString(_errorText, out); - out.writeShort(_formula1.getEncodedTokenSize()); - out.writeShort(_not_used_1); - _formula1.serializeTokens(out); - - out.writeShort(_formula2.getEncodedTokenSize()); - out.writeShort(_not_used_2); - _formula2.serializeTokens(out); - - _regions.serialize(out); - } - - /** - * When entered via the UI, Excel translates empty string into "\0" - * While it is possible to encode the title/text as empty string (Excel doesn't exactly crash), - * the resulting tool-tip text / message box looks wrong. It is best to do the same as the - * Excel UI and encode 'not present' as "\0". - */ - private static UnicodeString resolveTitleText(String str) { - if (str == null || str.length() < 1) { - return NULL_TEXT_STRING; - } - return new UnicodeString(str); - } - - private static String resolveTitleString(UnicodeString us) { - if (us == null || us.equals(NULL_TEXT_STRING)) { - return null; - } - return us.getString(); - } - - private static UnicodeString readUnicodeString(RecordInputStream in) { - return new UnicodeString(in); - } - - private static void serializeUnicodeString(UnicodeString us, LittleEndianOutput out) { - StringUtil.writeUnicodeString(out, us.getString()); - } - private static int getUnicodeStringSize(UnicodeString us) { - String str = us.getString(); - return 3 + str.length() * (StringUtil.hasMultibyte(str) ? 2 : 1); - } - - protected int getDataSize() { - int size = 4+2+2+2+2;//options_field+first_formula_size+first_unused+sec_formula_size+sec+unused; - size += getUnicodeStringSize(_promptTitle); - size += getUnicodeStringSize(_errorTitle); - size += getUnicodeStringSize(_promptText); - size += getUnicodeStringSize(_errorText); - size += _formula1.getEncodedTokenSize(); - size += _formula2.getEncodedTokenSize(); - size += _regions.getSize(); - return size; - } - - public short getSid() { - return sid; - } - - /** - * Clones the object. Uses serialisation, as the - * contents are somewhat complex - */ - @Override - public DVRecord clone() { - return (DVRecord)cloneViaReserialise(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java b/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java deleted file mode 100644 index 39b47402c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java +++ /dev/null @@ -1,91 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Date Window 1904 Flag record

    - * Description: Flag specifying whether 1904 date windowing is used. - * (tick toc tick toc...BOOM!)

    - * REFERENCE: PG 280 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class DateWindow1904Record - extends StandardRecord -{ - public final static short sid = 0x22; - private short field_1_window; - - public DateWindow1904Record() - { - } - - public DateWindow1904Record(RecordInputStream in) - { - field_1_window = in.readShort(); - } - - /** - * sets whether or not to use 1904 date windowing (which means you'll be screwed in 2004) - * @param window flag - 0/1 (false,true) - */ - - public void setWindowing(short window) - { // I hate using numbers in method names so I wont! - field_1_window = window; - } - - /** - * gets whether or not to use 1904 date windowing (which means you'll be screwed in 2004) - * @return window flag - 0/1 (false,true) - */ - - public short getWindowing() - { - return field_1_window; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[1904]\n"); - buffer.append(" .is1904 = ") - .append(Integer.toHexString(getWindowing())).append("\n"); - buffer.append("[/1904]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getWindowing()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java deleted file mode 100644 index c2f37b8c4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Default Column Width Record (0x0055)

    - * Description: Specifies the default width for columns that have no specific - * width set.

    - * REFERENCE: PG 302 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ -public final class DefaultColWidthRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x0055; - private int field_1_col_width; - - /** - * The default column width is 8 characters - */ - public final static int DEFAULT_COLUMN_WIDTH = 0x0008; - - public DefaultColWidthRecord() - { - field_1_col_width = DEFAULT_COLUMN_WIDTH; - } - - public DefaultColWidthRecord(RecordInputStream in) - { - field_1_col_width = in.readUShort(); - } - - /** - * set the default column width - * @param width defaultwidth for columns - */ - - public void setColWidth(int width) - { - field_1_col_width = width; - } - - /** - * get the default column width - * @return defaultwidth for columns - */ - - public int getColWidth() - { - return field_1_col_width; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[DEFAULTCOLWIDTH]\n"); - buffer.append(" .colwidth = ") - .append(Integer.toHexString(getColWidth())).append("\n"); - buffer.append("[/DEFAULTCOLWIDTH]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getColWidth()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public DefaultColWidthRecord clone() { - DefaultColWidthRecord rec = new DefaultColWidthRecord(); - rec.field_1_col_width = field_1_col_width; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java deleted file mode 100644 index 850e895c9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java +++ /dev/null @@ -1,130 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Default Row Height Record - * Description: Row height for rows with undefined or not explicitly defined - * heights. - * REFERENCE: PG 301 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class DefaultRowHeightRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x225; - private short field_1_option_flags; - private short field_2_row_height; - - /** - * The default row height for empty rows is 255 twips (255 / 20 == 12.75 points) - */ - public static final short DEFAULT_ROW_HEIGHT = 0xFF; - - public DefaultRowHeightRecord() - { - field_1_option_flags = 0x0000; - field_2_row_height = DEFAULT_ROW_HEIGHT; - } - - public DefaultRowHeightRecord(RecordInputStream in) - { - field_1_option_flags = in.readShort(); - field_2_row_height = in.readShort(); - } - - /** - * set the (currently unimportant to HSSF) option flags - * @param flags the bitmask to set - */ - - public void setOptionFlags(short flags) - { - field_1_option_flags = flags; - } - - /** - * set the default row height - * @param height for undefined rows/rows w/undefined height - */ - - public void setRowHeight(short height) - { - field_2_row_height = height; - } - - /** - * get the (currently unimportant to HSSF) option flags - * @return flags - the current bitmask - */ - - public short getOptionFlags() - { - return field_1_option_flags; - } - - /** - * get the default row height - * @return rowheight for undefined rows/rows w/undefined height - */ - - public short getRowHeight() - { - return field_2_row_height; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[DEFAULTROWHEIGHT]\n"); - buffer.append(" .optionflags = ") - .append(Integer.toHexString(getOptionFlags())).append("\n"); - buffer.append(" .rowheight = ") - .append(Integer.toHexString(getRowHeight())).append("\n"); - buffer.append("[/DEFAULTROWHEIGHT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getOptionFlags()); - out.writeShort(getRowHeight()); - } - - protected int getDataSize() { - return 4; - } - - public short getSid() - { - return sid; - } - - @Override - public DefaultRowHeightRecord clone() { - DefaultRowHeightRecord rec = new DefaultRowHeightRecord(); - rec.field_1_option_flags = field_1_option_flags; - rec.field_2_row_height = field_2_row_height; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java deleted file mode 100644 index 9cc2c071a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Delta Record (0x0010)

    - * Description: controls the accuracy of the calculations

    - * REFERENCE: PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class DeltaRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x0010; - public final static double DEFAULT_VALUE = 0.0010; // should be .001 - - // a double is an IEEE 8-byte float...damn IEEE and their goofy standards an - // ambiguous numeric identifiers - private double field_1_max_change; - - public DeltaRecord(double maxChange) { - field_1_max_change = maxChange; - } - - public DeltaRecord(RecordInputStream in) { - field_1_max_change = in.readDouble(); - } - - /** - * get the maximum change - * @return maxChange - maximum rounding error - */ - public double getMaxChange() { - return field_1_max_change; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[DELTA]\n"); - buffer.append(" .maxchange = ").append(getMaxChange()).append("\n"); - buffer.append("[/DELTA]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeDouble(getMaxChange()); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() { - return sid; - } - - @Override - public DeltaRecord clone() { - // immutable - return this; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java deleted file mode 100644 index e326b5cb6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java +++ /dev/null @@ -1,181 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Dimensions Record

    - * Description: provides the minumum and maximum bounds - * of a sheet.

    - * REFERENCE: PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class DimensionsRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x200; - private int field_1_first_row; - private int field_2_last_row; // plus 1 - private short field_3_first_col; - private short field_4_last_col; - private short field_5_zero; // must be 0 (reserved) - - public DimensionsRecord() - { - } - - public DimensionsRecord(RecordInputStream in) - { - field_1_first_row = in.readInt(); - field_2_last_row = in.readInt(); - field_3_first_col = in.readShort(); - field_4_last_col = in.readShort(); - field_5_zero = in.readShort(); - } - - /** - * set the first row number for the sheet - * @param row - first row on the sheet - */ - - public void setFirstRow(int row) - { - field_1_first_row = row; - } - - /** - * set the last row number for the sheet - * @param row - last row on the sheet - */ - - public void setLastRow(int row) - { - field_2_last_row = row; - } - - /** - * set the first column number for the sheet - * @param col first column on the sheet - */ - - public void setFirstCol(short col) - { - field_3_first_col = col; - } - - /** - * set the last col number for the sheet - * @param col last column on the sheet - */ - - public void setLastCol(short col) - { - field_4_last_col = col; - } - - /** - * get the first row number for the sheet - * @return row - first row on the sheet - */ - - public int getFirstRow() - { - return field_1_first_row; - } - - /** - * get the last row number for the sheet - * @return row - last row on the sheet - */ - - public int getLastRow() - { - return field_2_last_row; - } - - /** - * get the first column number for the sheet - * @return column - first column on the sheet - */ - - public short getFirstCol() - { - return field_3_first_col; - } - - /** - * get the last col number for the sheet - * @return column - last column on the sheet - */ - - public short getLastCol() - { - return field_4_last_col; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[DIMENSIONS]\n"); - buffer.append(" .firstrow = ") - .append(Integer.toHexString(getFirstRow())).append("\n"); - buffer.append(" .lastrow = ") - .append(Integer.toHexString(getLastRow())).append("\n"); - buffer.append(" .firstcol = ") - .append(Integer.toHexString(getFirstCol())).append("\n"); - buffer.append(" .lastcol = ") - .append(Integer.toHexString(getLastCol())).append("\n"); - buffer.append(" .zero = ") - .append(Integer.toHexString(field_5_zero)).append("\n"); - buffer.append("[/DIMENSIONS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(getFirstRow()); - out.writeInt(getLastRow()); - out.writeShort(getFirstCol()); - out.writeShort(getLastCol()); - out.writeShort(( short ) 0); - } - - protected int getDataSize() { - return 14; - } - - public short getSid() - { - return sid; - } - - @Override - public DimensionsRecord clone() { - DimensionsRecord rec = new DimensionsRecord(); - rec.field_1_first_row = field_1_first_row; - rec.field_2_last_row = field_2_last_row; - rec.field_3_first_col = field_3_first_col; - rec.field_4_last_col = field_4_last_col; - rec.field_5_zero = field_5_zero; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java deleted file mode 100644 index 2304c0470..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java +++ /dev/null @@ -1,139 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.NullEscherSerializationListener; -import org.apache.poi.util.LittleEndian; - -import java.util.Iterator; -import java.util.List; - - -public final class DrawingGroupRecord extends AbstractEscherHolderRecord { - public static final short sid = 0xEB; - - static final int MAX_RECORD_SIZE = 8228; - private static final int MAX_DATA_SIZE = MAX_RECORD_SIZE - 4; - - public DrawingGroupRecord() - { - } - - public DrawingGroupRecord( RecordInputStream in ) - { - super( in ); - } - - protected String getRecordName() - { - return "MSODRAWINGGROUP"; - } - - public short getSid() - { - return sid; - } - - public int serialize(int offset, byte[] data) - { - byte[] rawData = getRawData(); - if (getEscherRecords().size() == 0 && rawData != null) - { - return writeData( offset, data, rawData ); - } - byte[] buffer = new byte[getRawDataSize()]; - int pos = 0; - for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); ) - { - EscherRecord r = iterator.next(); - pos += r.serialize(pos, buffer, new NullEscherSerializationListener() ); - } - - return writeData( offset, data, buffer ); - } - - /** - * Process the bytes into escher records. - * (Not done by default in case we break things, - * unless you set the "poi.deserialize.escher" - * system property) - */ - public void processChildRecords() { - convertRawBytesToEscherRecords(); - } - - public int getRecordSize() { - // TODO - convert this to a RecordAggregate - return grossSizeFromDataSize(getRawDataSize()); - } - - private int getRawDataSize() { - List escherRecords = getEscherRecords(); - byte[] rawData = getRawData(); - if (escherRecords.size() == 0 && rawData != null) - { - return rawData.length; - } - int size = 0; - for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); ) - { - EscherRecord r = iterator.next(); - size += r.getRecordSize(); - } - return size; - } - - static int grossSizeFromDataSize(int dataSize) - { - return dataSize + ( (dataSize - 1) / MAX_DATA_SIZE + 1 ) * 4; - } - - private int writeData( int offset, byte[] data, byte[] rawData ) - { - int writtenActualData = 0; - int writtenRawData = 0; - while (writtenRawData < rawData.length) - { - int segmentLength = Math.min( rawData.length - writtenRawData, MAX_DATA_SIZE); - if (writtenRawData / MAX_DATA_SIZE >= 2) - writeContinueHeader( data, offset, segmentLength ); - else - writeHeader( data, offset, segmentLength ); - writtenActualData += 4; - offset += 4; - System.arraycopy( rawData, writtenRawData, data, offset, segmentLength ); - offset += segmentLength; - writtenRawData += segmentLength; - writtenActualData += segmentLength; - } - return writtenActualData; - } - - private void writeHeader( byte[] data, int offset, int sizeExcludingHeader ) - { - LittleEndian.putShort(data, 0 + offset, getSid()); - LittleEndian.putShort(data, 2 + offset, (short) sizeExcludingHeader); - } - - private void writeContinueHeader( byte[] data, int offset, int sizeExcludingHeader ) - { - LittleEndian.putShort(data, 0 + offset, ContinueRecord.sid); - LittleEndian.putShort(data, 2 + offset, (short) sizeExcludingHeader); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java deleted file mode 100644 index c55cafa44..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; -/** - * DrawingRecord (0x00EC) - */ -public final class DrawingRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x00EC; - - private static final byte[] EMPTY_BYTE_ARRAY = {}; - - private byte[] recordData; - private byte[] contd; - - public DrawingRecord() { - recordData = EMPTY_BYTE_ARRAY; - } - - public DrawingRecord(RecordInputStream in) { - recordData = in.readRemainder(); - } - - /** - * @deprecated POI 3.9 - */ - @Deprecated - public void processContinueRecord(byte[] record) { - //don't merge continue record with the drawing record, it must be serialized separately - contd = record; - } - - public void serialize(LittleEndianOutput out) { - out.write(recordData); - } - - protected int getDataSize() { - return recordData.length; - } - - public short getSid() { - return sid; - } - - public byte[] getRecordData(){ - return recordData; - } - - public void setData(byte[] thedata) { - if (thedata == null) { - throw new IllegalArgumentException("data must not be null"); - } - recordData = thedata; - } - - /** - * Cloning of drawing records must be executed through HSSFPatriarch, because all id's must be changed - * @return cloned drawing records - */ - @Override - public DrawingRecord clone() { - DrawingRecord rec = new DrawingRecord(); - rec.recordData = recordData.clone(); - if (contd != null) { - // TODO - this code probably never executes - rec.contd = contd.clone(); - } - - return rec; - } - - @Override - public String toString() { - return "DrawingRecord["+recordData.length+"]"; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java b/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java deleted file mode 100644 index bbbe0b3ee..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayInputStream; - -/** - * This is purely for the biff viewer. During normal operations we don't want - * to be seeing this. - */ -public final class DrawingRecordForBiffViewer extends AbstractEscherHolderRecord { - public static final short sid = 0xEC; - - public DrawingRecordForBiffViewer() - { - } - - public DrawingRecordForBiffViewer( RecordInputStream in) - { - super(in); - } - - public DrawingRecordForBiffViewer(DrawingRecord r) - { - super(convertToInputStream(r)); - convertRawBytesToEscherRecords(); - } - private static RecordInputStream convertToInputStream(DrawingRecord r) - { - byte[] data = r.serialize(); - RecordInputStream rinp = new RecordInputStream( - new ByteArrayInputStream(data) - ); - rinp.nextRecord(); - return rinp; - } - - protected String getRecordName() - { - return "MSODRAWING"; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java b/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java deleted file mode 100644 index 1433bcbbd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * MsoDrawingSelection (0x00ED)

    - * Reference: - * [MS-OGRAPH].pdf sec 2.4.69 - */ -public final class DrawingSelectionRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x00ED; - - /** - * From [MS-ODRAW].pdf sec 2.2.1

    - * TODO - make EscherRecordHeader {@link LittleEndianInput} aware and refactor with this - */ - private static final class OfficeArtRecordHeader { - public static final int ENCODED_SIZE = 8; - /** - * lower 4 bits is 'version' usually 0x01 or 0x0F (for containers) - * upper 12 bits is 'instance' - */ - private final int _verAndInstance; - /** value should be between 0xF000 and 0xFFFF */ - private final int _type; - private final int _length; - - public OfficeArtRecordHeader(LittleEndianInput in) { - _verAndInstance = in.readUShort(); - _type = in.readUShort(); - _length = in.readInt(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_verAndInstance); - out.writeShort(_type); - out.writeInt(_length); - } - - public String debugFormatAsString() { - StringBuffer sb = new StringBuffer(32); - sb.append("ver+inst=").append(HexDump.shortToHex(_verAndInstance)); - sb.append(" type=").append(HexDump.shortToHex(_type)); - sb.append(" len=").append(HexDump.intToHex(_length)); - return sb.toString(); - } - } - - // [MS-OGRAPH].pdf says that the data of this record is an OfficeArtFDGSL structure - // as described in[MS-ODRAW].pdf sec 2.2.33 - private OfficeArtRecordHeader _header; - private int _cpsp; - /** a MSODGSLK enum value for the current selection mode */ - private int _dgslk; - private int _spidFocus; - /** selected shape IDs (e.g. from EscherSpRecord.ShapeId) */ - private int[] _shapeIds; - - public DrawingSelectionRecord(RecordInputStream in) { - _header = new OfficeArtRecordHeader(in); - _cpsp = in.readInt(); - _dgslk = in.readInt(); - _spidFocus = in.readInt(); - int nShapes = in.available() / 4; - int[] shapeIds = new int[nShapes]; - for (int i = 0; i < nShapes; i++) { - shapeIds[i] = in.readInt(); - } - _shapeIds = shapeIds; - } - - public short getSid() { - return sid; - } - - protected int getDataSize() { - return OfficeArtRecordHeader.ENCODED_SIZE - + 12 // 3 int fields - + _shapeIds.length * 4; - } - - public void serialize(LittleEndianOutput out) { - _header.serialize(out); - out.writeInt(_cpsp); - out.writeInt(_dgslk); - out.writeInt(_spidFocus); - for (int i = 0; i < _shapeIds.length; i++) { - out.writeInt(_shapeIds[i]); - } - } - - @Override - public DrawingSelectionRecord clone() { - // currently immutable - return this; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[MSODRAWINGSELECTION]\n"); - sb.append(" .rh =(").append(_header.debugFormatAsString()).append(")\n"); - sb.append(" .cpsp =").append(HexDump.intToHex(_cpsp)).append('\n'); - sb.append(" .dgslk =").append(HexDump.intToHex(_dgslk)).append('\n'); - sb.append(" .spidFocus=").append(HexDump.intToHex(_spidFocus)).append('\n'); - sb.append(" .shapeIds =("); - for (int i = 0; i < _shapeIds.length; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append(HexDump.intToHex(_shapeIds[i])); - } - sb.append(")\n"); - - sb.append("[/MSODRAWINGSELECTION]\n"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java b/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java deleted file mode 100644 index 02d734a99..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * End Of File record. - *

    - * Description: Marks the end of records belonging to a particular object in the - * HSSF File

    - * REFERENCE: PG 307 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ -public final class EOFRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x0A; - public static final int ENCODED_SIZE = 4; - - public static final EOFRecord instance = new EOFRecord(); - - private EOFRecord() { - // no data fields - } - - /** - * @param in unused (since this record has no data) - */ - public EOFRecord(RecordInputStream in) - { - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[EOF]\n"); - buffer.append("[/EOF]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - } - - protected int getDataSize() { - return ENCODED_SIZE - 4; - } - - public short getSid() - { - return sid; - } - - @Override - public EOFRecord clone() { - return instance; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java deleted file mode 100644 index 877ef8c91..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java +++ /dev/null @@ -1,349 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayInputStream; - -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.AreaPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.ptg.RefPtg; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianInputStream; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * ftPictFmla (0x0009)

    - * A sub-record within the OBJ record which stores a reference to an object - * stored in a separate entry within the OLE2 compound file. - */ -public final class EmbeddedObjectRefSubRecord extends SubRecord implements Cloneable { - private static POILogger logger = POILogFactory.getLogger(EmbeddedObjectRefSubRecord.class); - public static final short sid = 0x0009; - - private static final byte[] EMPTY_BYTE_ARRAY = { }; - - private int field_1_unknown_int; - /** either an area or a cell ref */ - private Ptg field_2_refPtg; - /** for when the 'formula' doesn't parse properly */ - private byte[] field_2_unknownFormulaData; - /** note- this byte is not present in the encoding if the string length is zero */ - private boolean field_3_unicode_flag; // Flags whether the string is Unicode. - private String field_4_ole_classname; // Classname of the embedded OLE document (e.g. Word.Document.8) - /** Formulas often have a single non-zero trailing byte. - * This is in a similar position to he pre-streamId padding - * It is unknown if the value is important (it seems to mirror a value a few bytes earlier) - * */ - private Byte field_4_unknownByte; - private Integer field_5_stream_id; // ID of the OLE stream containing the actual data. - private byte[] field_6_unknown; - - - // currently for testing only - needs review - public EmbeddedObjectRefSubRecord() { - field_2_unknownFormulaData = new byte[] { 0x02, 0x6C, 0x6A, 0x16, 0x01, }; // just some sample data. These values vary a lot - field_6_unknown = EMPTY_BYTE_ARRAY; - field_4_ole_classname = null; - } - - public short getSid() { - return sid; - } - - public EmbeddedObjectRefSubRecord(LittleEndianInput in, int size) { - - // Much guess-work going on here due to lack of any documentation. - // See similar source code in OOO: - // http://svn.services.openoffice.org/ooo/trunk/sc/source/filter/excel/xiescher.cxx - // 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize ) - - int streamIdOffset = in.readShort(); // OOO calls this 'nFmlaLen' - int remaining = size - LittleEndian.SHORT_SIZE; - - int dataLenAfterFormula = remaining - streamIdOffset; - int formulaSize = in.readUShort(); - remaining -= LittleEndian.SHORT_SIZE; - field_1_unknown_int = in.readInt(); - remaining -= LittleEndian.INT_SIZE; - byte[] formulaRawBytes = readRawData(in, formulaSize); - remaining -= formulaSize; - field_2_refPtg = readRefPtg(formulaRawBytes); - if (field_2_refPtg == null) { - // common case - // field_2_n16 seems to be 5 here - // The formula almost looks like tTbl but the row/column values seem like garbage. - field_2_unknownFormulaData = formulaRawBytes; - } else { - field_2_unknownFormulaData = null; - } - - int stringByteCount; - if (remaining >= dataLenAfterFormula + 3) { - int tag = in.readByte(); - stringByteCount = LittleEndian.BYTE_SIZE; - if (tag != 0x03) { - throw new RecordFormatException("Expected byte 0x03 here"); - } - int nChars = in.readUShort(); - stringByteCount += LittleEndian.SHORT_SIZE; - if (nChars > 0) { - // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if length 0 - field_3_unicode_flag = ( in.readByte() & 0x01 ) != 0; - stringByteCount += LittleEndian.BYTE_SIZE; - if (field_3_unicode_flag) { - field_4_ole_classname = StringUtil.readUnicodeLE(in, nChars); - stringByteCount += nChars * 2; - } else { - field_4_ole_classname = StringUtil.readCompressedUnicode(in, nChars); - stringByteCount += nChars; - } - } else { - field_4_ole_classname = ""; - } - } else { - field_4_ole_classname = null; - stringByteCount = 0; - } - remaining -= stringByteCount; - // Pad to next 2-byte boundary - if (((stringByteCount + formulaSize) % 2) != 0) { - int b = in.readByte(); - remaining -= LittleEndian.BYTE_SIZE; - if (field_2_refPtg != null && field_4_ole_classname == null) { - field_4_unknownByte = Byte.valueOf((byte)b); - } - } - int nUnexpectedPadding = remaining - dataLenAfterFormula; - - if (nUnexpectedPadding > 0) { - logger.log( POILogger.ERROR, "Discarding " + nUnexpectedPadding + " unexpected padding bytes "); - readRawData(in, nUnexpectedPadding); - remaining-=nUnexpectedPadding; - } - - // Fetch the stream ID - if (dataLenAfterFormula >= 4) { - field_5_stream_id = Integer.valueOf(in.readInt()); - remaining -= LittleEndian.INT_SIZE; - } else { - field_5_stream_id = null; - } - field_6_unknown = readRawData(in, remaining); - } - - private static Ptg readRefPtg(byte[] formulaRawBytes) { - LittleEndianInput in = new LittleEndianInputStream(new ByteArrayInputStream(formulaRawBytes)); - byte ptgSid = in.readByte(); - switch(ptgSid) { - case AreaPtg.sid: return new AreaPtg(in); - case Area3DPtg.sid: return new Area3DPtg(in); - case RefPtg.sid: return new RefPtg(in); - case Ref3DPtg.sid: return new Ref3DPtg(in); - } - return null; - } - - private static byte[] readRawData(LittleEndianInput in, int size) { - if (size < 0) { - throw new IllegalArgumentException("Negative size (" + size + ")"); - } - if (size == 0) { - return EMPTY_BYTE_ARRAY; - } - byte[] result = new byte[size]; - in.readFully(result); - return result; - } - - private int getStreamIDOffset(int formulaSize) { - int result = 2 + 4; // formulaSize + f2unknown_int - result += formulaSize; - - int stringLen; - if (field_4_ole_classname == null) { - // don't write 0x03, stringLen, flag, text - stringLen = 0; - } else { - result += 1 + 2; // 0x03, stringLen - stringLen = field_4_ole_classname.length(); - if (stringLen > 0) { - result += 1; // flag - if (field_3_unicode_flag) { - result += stringLen * 2; - } else { - result += stringLen; - } - } - } - // pad to next 2 byte boundary - if ((result % 2) != 0) { - result ++; - } - return result; - } - - private int getDataSize(int idOffset) { - - int result = 2 + idOffset; // 2 for idOffset short field itself - if (field_5_stream_id != null) { - result += 4; - } - return result + field_6_unknown.length; - } - protected int getDataSize() { - int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize(); - int idOffset = getStreamIDOffset(formulaSize); - return getDataSize(idOffset); - } - - public void serialize(LittleEndianOutput out) { - - int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize(); - int idOffset = getStreamIDOffset(formulaSize); - int dataSize = getDataSize(idOffset); - - - out.writeShort(sid); - out.writeShort(dataSize); - - out.writeShort(idOffset); - out.writeShort(formulaSize); - out.writeInt(field_1_unknown_int); - - int pos = 12; - - if (field_2_refPtg == null) { - out.write(field_2_unknownFormulaData); - } else { - field_2_refPtg.write(out); - } - pos += formulaSize; - - int stringLen; - if (field_4_ole_classname == null) { - // don't write 0x03, stringLen, flag, text - stringLen = 0; - } else { - out.writeByte(0x03); - pos+=1; - stringLen = field_4_ole_classname.length(); - out.writeShort(stringLen); - pos+=2; - if (stringLen > 0) { - out.writeByte(field_3_unicode_flag ? 0x01 : 0x00); - pos+=1; - - if (field_3_unicode_flag) { - StringUtil.putUnicodeLE(field_4_ole_classname, out); - pos += stringLen * 2; - } else { - StringUtil.putCompressedUnicode(field_4_ole_classname, out); - pos += stringLen; - } - } - } - - // pad to next 2-byte boundary (requires 0 or 1 bytes) - switch(idOffset - (pos - 6)) { // 6 for 3 shorts: sid, dataSize, idOffset - case 1: - out.writeByte(field_4_unknownByte == null ? 0x00 : field_4_unknownByte.intValue()); - pos++; - break; - case 0: - break; - default: - throw new IllegalStateException("Bad padding calculation (" + idOffset + ", " + pos + ")"); - } - - if (field_5_stream_id != null) { - out.writeInt(field_5_stream_id.intValue()); - pos += 4; - } - out.write(field_6_unknown); - } - - /** - * Gets the stream ID containing the actual data. The data itself - * can be found under a top-level directory entry in the OLE2 filesystem - * under the name "MBDxxxxxxxx" where xxxxxxxx is - * this ID converted into hex (in big endian order, funnily enough.) - * - * @return the data stream ID. Possibly null - */ - public Integer getStreamId() { - return field_5_stream_id; - } - - public String getOLEClassName() { - return field_4_ole_classname; - } - - public byte[] getObjectData() { - return field_6_unknown; - } - - @Override - public EmbeddedObjectRefSubRecord clone() { - return this; // TODO proper clone - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("[ftPictFmla]\n"); - sb.append(" .f2unknown = ").append(HexDump.intToHex(field_1_unknown_int)).append("\n"); - if (field_2_refPtg == null) { - sb.append(" .f3unknown = ").append(HexDump.toHex(field_2_unknownFormulaData)).append("\n"); - } else { - sb.append(" .formula = ").append(field_2_refPtg.toString()).append("\n"); - } - if (field_4_ole_classname != null) { - sb.append(" .unicodeFlag = ").append(field_3_unicode_flag).append("\n"); - sb.append(" .oleClassname = ").append(field_4_ole_classname).append("\n"); - } - if (field_4_unknownByte != null) { - sb.append(" .f4unknown = ").append(HexDump.byteToHex(field_4_unknownByte.intValue())).append("\n"); - } - if (field_5_stream_id != null) { - sb.append(" .streamId = ").append(HexDump.intToHex(field_5_stream_id.intValue())).append("\n"); - } - if (field_6_unknown.length > 0) { - sb.append(" .f7unknown = ").append(HexDump.toHex(field_6_unknown)).append("\n"); - } - sb.append("[/ftPictFmla]"); - return sb.toString(); - } - - public void setUnknownFormulaData(byte[] formularData) { - field_2_unknownFormulaData = formularData; - } - - public void setOleClassname(String oleClassname) { - field_4_ole_classname = oleClassname; - } - - public void setStorageId(int storageId) { - field_5_stream_id = storageId; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java deleted file mode 100644 index f0a676b18..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ftEnd (0x0000)

    - * - * The end data record is used to denote the end of the subrecords. - */ -public final class EndSubRecord extends SubRecord implements Cloneable { - // Note - zero sid is somewhat unusual (compared to plain Records) - public final static short sid = 0x0000; - private static final int ENCODED_SIZE = 0; - - public EndSubRecord() - { - - } - - /** - * @param in unused (since this record has no data) - * @param size must be 0 - */ - public EndSubRecord(LittleEndianInput in, int size) { - if ((size & 0xFF) != ENCODED_SIZE) { // mask out random crap in upper byte - throw new RecordFormatException("Unexpected size (" + size + ")"); - } - } - - @Override - public boolean isTerminating(){ - return true; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ftEnd]\n"); - - buffer.append("[/ftEnd]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(ENCODED_SIZE); - } - - protected int getDataSize() { - return ENCODED_SIZE; - } - - public short getSid() - { - return sid; - } - - @Override - public EndSubRecord clone() { - EndSubRecord rec = new EndSubRecord(); - - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java deleted file mode 100644 index 01e685c9c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java +++ /dev/null @@ -1,813 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.ddf.DefaultEscherRecordFactory; -import org.apache.poi.ddf.EscherClientDataRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherDgRecord; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherRecordFactory; -import org.apache.poi.ddf.EscherSerializationListener; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.ddf.EscherSpgrRecord; -import org.apache.poi.ddf.EscherTextboxRecord; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This class is used to aggregate the MSODRAWING and OBJ record - * combinations. This is necessary due to the bizare way in which - * these records are serialized. What happens is that you get a - * combination of MSODRAWING -> OBJ -> MSODRAWING -> OBJ records - * but the escher records are serialized _across_ the MSODRAWING - * records. - *

    - * It gets even worse when you start looking at TXO records. - *

    - * So what we do with this class is aggregate lazily. That is - * we don't aggregate the MSODRAWING -> OBJ records unless we - * need to modify them. - *

    - * At first document contains 4 types of records which belong to drawing layer. - * There are can be such sequence of record: - *

    - * DrawingRecord - * ContinueRecord - * ... - * ContinueRecord - * ObjRecord | TextObjectRecord - * ..... - * ContinueRecord - * ... - * ContinueRecord - * ObjRecord | TextObjectRecord - * NoteRecord - * ... - * NoteRecord - *

    - * To work with shapes we have to read data from Drawing and Continue records into single array of bytes and - * build escher(office art) records tree from this array. - * Each shape in drawing layer matches corresponding ObjRecord - * Each textbox matches corresponding TextObjectRecord - *

    - * ObjRecord contains information about shape. Thus each ObjRecord corresponds EscherContainerRecord(SPGR) - *

    - * EscherAggrefate contains also NoteRecords - * NoteRecords must be serial - */ - -public final class EscherAggregate extends AbstractEscherHolderRecord { - public static final short sid = 9876; // not a real sid - dummy value - private static POILogger log = POILogFactory.getLogger(EscherAggregate.class); - - public static final short ST_MIN = (short) 0; - public static final short ST_NOT_PRIMATIVE = ST_MIN; - public static final short ST_RECTANGLE = (short) 1; - public static final short ST_ROUNDRECTANGLE = (short) 2; - public static final short ST_ELLIPSE = (short) 3; - public static final short ST_DIAMOND = (short) 4; - public static final short ST_ISOCELESTRIANGLE = (short) 5; - public static final short ST_RIGHTTRIANGLE = (short) 6; - public static final short ST_PARALLELOGRAM = (short) 7; - public static final short ST_TRAPEZOID = (short) 8; - public static final short ST_HEXAGON = (short) 9; - public static final short ST_OCTAGON = (short) 10; - public static final short ST_PLUS = (short) 11; - public static final short ST_STAR = (short) 12; - public static final short ST_ARROW = (short) 13; - public static final short ST_THICKARROW = (short) 14; - public static final short ST_HOMEPLATE = (short) 15; - public static final short ST_CUBE = (short) 16; - public static final short ST_BALLOON = (short) 17; - public static final short ST_SEAL = (short) 18; - public static final short ST_ARC = (short) 19; - public static final short ST_LINE = (short) 20; - public static final short ST_PLAQUE = (short) 21; - public static final short ST_CAN = (short) 22; - public static final short ST_DONUT = (short) 23; - public static final short ST_TEXTSIMPLE = (short) 24; - public static final short ST_TEXTOCTAGON = (short) 25; - public static final short ST_TEXTHEXAGON = (short) 26; - public static final short ST_TEXTCURVE = (short) 27; - public static final short ST_TEXTWAVE = (short) 28; - public static final short ST_TEXTRING = (short) 29; - public static final short ST_TEXTONCURVE = (short) 30; - public static final short ST_TEXTONRING = (short) 31; - public static final short ST_STRAIGHTCONNECTOR1 = (short) 32; - public static final short ST_BENTCONNECTOR2 = (short) 33; - public static final short ST_BENTCONNECTOR3 = (short) 34; - public static final short ST_BENTCONNECTOR4 = (short) 35; - public static final short ST_BENTCONNECTOR5 = (short) 36; - public static final short ST_CURVEDCONNECTOR2 = (short) 37; - public static final short ST_CURVEDCONNECTOR3 = (short) 38; - public static final short ST_CURVEDCONNECTOR4 = (short) 39; - public static final short ST_CURVEDCONNECTOR5 = (short) 40; - public static final short ST_CALLOUT1 = (short) 41; - public static final short ST_CALLOUT2 = (short) 42; - public static final short ST_CALLOUT3 = (short) 43; - public static final short ST_ACCENTCALLOUT1 = (short) 44; - public static final short ST_ACCENTCALLOUT2 = (short) 45; - public static final short ST_ACCENTCALLOUT3 = (short) 46; - public static final short ST_BORDERCALLOUT1 = (short) 47; - public static final short ST_BORDERCALLOUT2 = (short) 48; - public static final short ST_BORDERCALLOUT3 = (short) 49; - public static final short ST_ACCENTBORDERCALLOUT1 = (short) 50; - public static final short ST_ACCENTBORDERCALLOUT2 = (short) 51; - public static final short ST_ACCENTBORDERCALLOUT3 = (short) 52; - public static final short ST_RIBBON = (short) 53; - public static final short ST_RIBBON2 = (short) 54; - public static final short ST_CHEVRON = (short) 55; - public static final short ST_PENTAGON = (short) 56; - public static final short ST_NOSMOKING = (short) 57; - public static final short ST_SEAL8 = (short) 58; - public static final short ST_SEAL16 = (short) 59; - public static final short ST_SEAL32 = (short) 60; - public static final short ST_WEDGERECTCALLOUT = (short) 61; - public static final short ST_WEDGERRECTCALLOUT = (short) 62; - public static final short ST_WEDGEELLIPSECALLOUT = (short) 63; - public static final short ST_WAVE = (short) 64; - public static final short ST_FOLDEDCORNER = (short) 65; - public static final short ST_LEFTARROW = (short) 66; - public static final short ST_DOWNARROW = (short) 67; - public static final short ST_UPARROW = (short) 68; - public static final short ST_LEFTRIGHTARROW = (short) 69; - public static final short ST_UPDOWNARROW = (short) 70; - public static final short ST_IRREGULARSEAL1 = (short) 71; - public static final short ST_IRREGULARSEAL2 = (short) 72; - public static final short ST_LIGHTNINGBOLT = (short) 73; - public static final short ST_HEART = (short) 74; - public static final short ST_PICTUREFRAME = (short) 75; - public static final short ST_QUADARROW = (short) 76; - public static final short ST_LEFTARROWCALLOUT = (short) 77; - public static final short ST_RIGHTARROWCALLOUT = (short) 78; - public static final short ST_UPARROWCALLOUT = (short) 79; - public static final short ST_DOWNARROWCALLOUT = (short) 80; - public static final short ST_LEFTRIGHTARROWCALLOUT = (short) 81; - public static final short ST_UPDOWNARROWCALLOUT = (short) 82; - public static final short ST_QUADARROWCALLOUT = (short) 83; - public static final short ST_BEVEL = (short) 84; - public static final short ST_LEFTBRACKET = (short) 85; - public static final short ST_RIGHTBRACKET = (short) 86; - public static final short ST_LEFTBRACE = (short) 87; - public static final short ST_RIGHTBRACE = (short) 88; - public static final short ST_LEFTUPARROW = (short) 89; - public static final short ST_BENTUPARROW = (short) 90; - public static final short ST_BENTARROW = (short) 91; - public static final short ST_SEAL24 = (short) 92; - public static final short ST_STRIPEDRIGHTARROW = (short) 93; - public static final short ST_NOTCHEDRIGHTARROW = (short) 94; - public static final short ST_BLOCKARC = (short) 95; - public static final short ST_SMILEYFACE = (short) 96; - public static final short ST_VERTICALSCROLL = (short) 97; - public static final short ST_HORIZONTALSCROLL = (short) 98; - public static final short ST_CIRCULARARROW = (short) 99; - public static final short ST_NOTCHEDCIRCULARARROW = (short) 100; - public static final short ST_UTURNARROW = (short) 101; - public static final short ST_CURVEDRIGHTARROW = (short) 102; - public static final short ST_CURVEDLEFTARROW = (short) 103; - public static final short ST_CURVEDUPARROW = (short) 104; - public static final short ST_CURVEDDOWNARROW = (short) 105; - public static final short ST_CLOUDCALLOUT = (short) 106; - public static final short ST_ELLIPSERIBBON = (short) 107; - public static final short ST_ELLIPSERIBBON2 = (short) 108; - public static final short ST_FLOWCHARTPROCESS = (short) 109; - public static final short ST_FLOWCHARTDECISION = (short) 110; - public static final short ST_FLOWCHARTINPUTOUTPUT = (short) 111; - public static final short ST_FLOWCHARTPREDEFINEDPROCESS = (short) 112; - public static final short ST_FLOWCHARTINTERNALSTORAGE = (short) 113; - public static final short ST_FLOWCHARTDOCUMENT = (short) 114; - public static final short ST_FLOWCHARTMULTIDOCUMENT = (short) 115; - public static final short ST_FLOWCHARTTERMINATOR = (short) 116; - public static final short ST_FLOWCHARTPREPARATION = (short) 117; - public static final short ST_FLOWCHARTMANUALINPUT = (short) 118; - public static final short ST_FLOWCHARTMANUALOPERATION = (short) 119; - public static final short ST_FLOWCHARTCONNECTOR = (short) 120; - public static final short ST_FLOWCHARTPUNCHEDCARD = (short) 121; - public static final short ST_FLOWCHARTPUNCHEDTAPE = (short) 122; - public static final short ST_FLOWCHARTSUMMINGJUNCTION = (short) 123; - public static final short ST_FLOWCHARTOR = (short) 124; - public static final short ST_FLOWCHARTCOLLATE = (short) 125; - public static final short ST_FLOWCHARTSORT = (short) 126; - public static final short ST_FLOWCHARTEXTRACT = (short) 127; - public static final short ST_FLOWCHARTMERGE = (short) 128; - public static final short ST_FLOWCHARTOFFLINESTORAGE = (short) 129; - public static final short ST_FLOWCHARTONLINESTORAGE = (short) 130; - public static final short ST_FLOWCHARTMAGNETICTAPE = (short) 131; - public static final short ST_FLOWCHARTMAGNETICDISK = (short) 132; - public static final short ST_FLOWCHARTMAGNETICDRUM = (short) 133; - public static final short ST_FLOWCHARTDISPLAY = (short) 134; - public static final short ST_FLOWCHARTDELAY = (short) 135; - public static final short ST_TEXTPLAINTEXT = (short) 136; - public static final short ST_TEXTSTOP = (short) 137; - public static final short ST_TEXTTRIANGLE = (short) 138; - public static final short ST_TEXTTRIANGLEINVERTED = (short) 139; - public static final short ST_TEXTCHEVRON = (short) 140; - public static final short ST_TEXTCHEVRONINVERTED = (short) 141; - public static final short ST_TEXTRINGINSIDE = (short) 142; - public static final short ST_TEXTRINGOUTSIDE = (short) 143; - public static final short ST_TEXTARCHUPCURVE = (short) 144; - public static final short ST_TEXTARCHDOWNCURVE = (short) 145; - public static final short ST_TEXTCIRCLECURVE = (short) 146; - public static final short ST_TEXTBUTTONCURVE = (short) 147; - public static final short ST_TEXTARCHUPPOUR = (short) 148; - public static final short ST_TEXTARCHDOWNPOUR = (short) 149; - public static final short ST_TEXTCIRCLEPOUR = (short) 150; - public static final short ST_TEXTBUTTONPOUR = (short) 151; - public static final short ST_TEXTCURVEUP = (short) 152; - public static final short ST_TEXTCURVEDOWN = (short) 153; - public static final short ST_TEXTCASCADEUP = (short) 154; - public static final short ST_TEXTCASCADEDOWN = (short) 155; - public static final short ST_TEXTWAVE1 = (short) 156; - public static final short ST_TEXTWAVE2 = (short) 157; - public static final short ST_TEXTWAVE3 = (short) 158; - public static final short ST_TEXTWAVE4 = (short) 159; - public static final short ST_TEXTINFLATE = (short) 160; - public static final short ST_TEXTDEFLATE = (short) 161; - public static final short ST_TEXTINFLATEBOTTOM = (short) 162; - public static final short ST_TEXTDEFLATEBOTTOM = (short) 163; - public static final short ST_TEXTINFLATETOP = (short) 164; - public static final short ST_TEXTDEFLATETOP = (short) 165; - public static final short ST_TEXTDEFLATEINFLATE = (short) 166; - public static final short ST_TEXTDEFLATEINFLATEDEFLATE = (short) 167; - public static final short ST_TEXTFADERIGHT = (short) 168; - public static final short ST_TEXTFADELEFT = (short) 169; - public static final short ST_TEXTFADEUP = (short) 170; - public static final short ST_TEXTFADEDOWN = (short) 171; - public static final short ST_TEXTSLANTUP = (short) 172; - public static final short ST_TEXTSLANTDOWN = (short) 173; - public static final short ST_TEXTCANUP = (short) 174; - public static final short ST_TEXTCANDOWN = (short) 175; - public static final short ST_FLOWCHARTALTERNATEPROCESS = (short) 176; - public static final short ST_FLOWCHARTOFFPAGECONNECTOR = (short) 177; - public static final short ST_CALLOUT90 = (short) 178; - public static final short ST_ACCENTCALLOUT90 = (short) 179; - public static final short ST_BORDERCALLOUT90 = (short) 180; - public static final short ST_ACCENTBORDERCALLOUT90 = (short) 181; - public static final short ST_LEFTRIGHTUPARROW = (short) 182; - public static final short ST_SUN = (short) 183; - public static final short ST_MOON = (short) 184; - public static final short ST_BRACKETPAIR = (short) 185; - public static final short ST_BRACEPAIR = (short) 186; - public static final short ST_SEAL4 = (short) 187; - public static final short ST_DOUBLEWAVE = (short) 188; - public static final short ST_ACTIONBUTTONBLANK = (short) 189; - public static final short ST_ACTIONBUTTONHOME = (short) 190; - public static final short ST_ACTIONBUTTONHELP = (short) 191; - public static final short ST_ACTIONBUTTONINFORMATION = (short) 192; - public static final short ST_ACTIONBUTTONFORWARDNEXT = (short) 193; - public static final short ST_ACTIONBUTTONBACKPREVIOUS = (short) 194; - public static final short ST_ACTIONBUTTONEND = (short) 195; - public static final short ST_ACTIONBUTTONBEGINNING = (short) 196; - public static final short ST_ACTIONBUTTONRETURN = (short) 197; - public static final short ST_ACTIONBUTTONDOCUMENT = (short) 198; - public static final short ST_ACTIONBUTTONSOUND = (short) 199; - public static final short ST_ACTIONBUTTONMOVIE = (short) 200; - public static final short ST_HOSTCONTROL = (short) 201; - public static final short ST_TEXTBOX = (short) 202; - public static final short ST_NIL = (short) 0x0FFF; - - /** - * Maps shape container objects to their {@link TextObjectRecord} or {@link ObjRecord} - */ - private final Map shapeToObj = new HashMap(); - - /** - * list of "tail" records that need to be serialized after all drawing group records - */ - private final Map tailRec = new LinkedHashMap(); - - /** - * create new EscherAggregate - * @param createDefaultTree if true creates base tree of the escher records, see EscherAggregate.buildBaseTree() - * else return empty escher aggregate - */ - public EscherAggregate(boolean createDefaultTree) { - if (createDefaultTree){ - buildBaseTree(); - } - } - - /** - * @return Returns the current sid. - */ - public short getSid() { - return sid; - } - - /** - * Calculates the string representation of this record. This is - * simply a dump of all the records. - */ - public String toString() { - String nl = System.getProperty("line.separtor"); - - StringBuilder result = new StringBuilder(); - result.append('[').append(getRecordName()).append(']').append(nl); - for (EscherRecord escherRecord : getEscherRecords()) { - result.append(escherRecord.toString()); - } - result.append("[/").append(getRecordName()).append(']').append(nl); - - return result.toString(); - } - - /** - * Calculates the xml representation of this record. This is - * simply a dump of all the records. - * @param tab - string which must be added before each line (used by default '\t') - * @return xml representation of the all aggregated records - */ - public String toXml(String tab) { - StringBuilder builder = new StringBuilder(); - builder.append(tab).append("<").append(getRecordName()).append(">\n"); - for (EscherRecord escherRecord : getEscherRecords()) { - builder.append(escherRecord.toXml(tab + "\t")); - } - builder.append(tab).append("\n"); - return builder.toString(); - } - - /** - * @param sid - record sid we want to check if it belongs to drawing layer - * @return true if record is instance of DrawingRecord or ContinueRecord or ObjRecord or TextObjRecord - */ - private static boolean isDrawingLayerRecord(final short sid) { - return sid == DrawingRecord.sid || - sid == ContinueRecord.sid || - sid == ObjRecord.sid || - sid == TextObjectRecord.sid; - } - - /** - * Collapses the drawing records into an aggregate. - * read Drawing, Obj, TxtObj, Note and Continue records into single byte array, - * create Escher tree from byte array, create map <EscherRecord, Record> - * - * @param records - list of all records inside sheet - * @param locFirstDrawingRecord - location of the first DrawingRecord inside sheet - * @return new EscherAggregate create from all aggregated records which belong to drawing layer - */ - public static EscherAggregate createAggregate(List records, int locFirstDrawingRecord) { - // Keep track of any shape records created so we can match them back to the object id's. - // Textbox objects are also treated as shape objects. - final List shapeRecords = new ArrayList(); - EscherRecordFactory recordFactory = new DefaultEscherRecordFactory() { - public EscherRecord createRecord(byte[] data, int offset) { - EscherRecord r = super.createRecord(data, offset); - if (r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID) { - shapeRecords.add(r); - } - return r; - } - }; - - // Create one big buffer - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - EscherAggregate agg = new EscherAggregate(false); - int loc = locFirstDrawingRecord; - while (loc + 1 < records.size() - && (isDrawingLayerRecord(sid(records, loc)))) { - try { - if (!(sid(records, loc) == DrawingRecord.sid || sid(records, loc) == ContinueRecord.sid)) { - loc++; - continue; - } - if (sid(records, loc) == DrawingRecord.sid) { - buffer.write(((DrawingRecord) records.get(loc)).getRecordData()); - } else { - buffer.write(((ContinueRecord) records.get(loc)).getData()); - } - } catch (IOException e) { - throw new RuntimeException("Couldn't get data from drawing/continue records", e); - } - loc++; - } - - // Decode the shapes - // agg.escherRecords = new ArrayList(); - int pos = 0; - while (pos < buffer.size()) { - EscherRecord r = recordFactory.createRecord(buffer.toByteArray(), pos); - int bytesRead = r.fillFields(buffer.toByteArray(), pos, recordFactory); - agg.addEscherRecord(r); - pos += bytesRead; - } - - // Associate the object records with the shapes - loc = locFirstDrawingRecord + 1; - int shapeIndex = 0; - while (loc < records.size() - && (isDrawingLayerRecord(sid(records, loc)))) { - if (!isObjectRecord(records, loc)) { - loc++; - continue; - } - Record objRecord = (Record) records.get(loc); - agg.shapeToObj.put(shapeRecords.get(shapeIndex++), objRecord); - loc++; - } - - // any NoteRecords that follow the drawing block must be aggregated and and saved in the tailRec collection - while (loc < records.size()) { - if (sid(records, loc) == NoteRecord.sid) { - NoteRecord r = (NoteRecord) records.get(loc); - agg.tailRec.put(r.getShapeId(), r); - } else { - break; - } - loc++; - } - - int locLastDrawingRecord = loc; - // replace drawing block with the created EscherAggregate - records.subList(locFirstDrawingRecord, locLastDrawingRecord).clear(); - records.add(locFirstDrawingRecord, agg); - return agg; - } - - /** - * Serializes this aggregate to a byte array. Since this is an aggregate - * record it will effectively serialize the aggregated records. - * - * @param offset The offset into the start of the array. - * @param data The byte array to serialize to. - * @return The number of bytes serialized. - */ - public int serialize(int offset, byte[] data) { - // Determine buffer size - List records = getEscherRecords(); - int size = getEscherRecordSize(records); - byte[] buffer = new byte[size]; - - // Serialize escher records into one big data structure and keep note of ending offsets. - final List spEndingOffsets = new ArrayList(); - final List shapes = new ArrayList(); - int pos = 0; - for (Object record : records) { - EscherRecord e = (EscherRecord) record; - pos += e.serialize(pos, buffer, new EscherSerializationListener() { - public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) { - } - - public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) { - if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) { - spEndingOffsets.add(offset); - shapes.add(record); - } - } - }); - } - shapes.add(0, null); - spEndingOffsets.add(0, 0); - - // Split escher records into separate MSODRAWING and OBJ, TXO records. (We don't break on - // the first one because it's the patriach). - pos = offset; - int writtenEscherBytes = 0; - int i; - for (i = 1; i < shapes.size(); i++) { - int endOffset = spEndingOffsets.get(i) - 1; - int startOffset; - if (i == 1) - startOffset = 0; - else - startOffset = spEndingOffsets.get(i - 1); - - byte[] drawingData = new byte[endOffset - startOffset + 1]; - System.arraycopy(buffer, startOffset, drawingData, 0, drawingData.length); - pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes, pos, data, i); - - writtenEscherBytes += drawingData.length; - - // Write the matching OBJ record - Record obj = shapeToObj.get(shapes.get(i)); - pos += obj.serialize(pos, data); - - if (i == shapes.size() - 1 && endOffset < buffer.length - 1) { - drawingData = new byte[buffer.length - endOffset - 1]; - System.arraycopy(buffer, endOffset + 1, drawingData, 0, drawingData.length); - pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes, pos, data, i); - } - } - if ((pos - offset) < buffer.length - 1) { - byte[] drawingData = new byte[buffer.length - (pos - offset)]; - System.arraycopy(buffer, (pos - offset), drawingData, 0, drawingData.length); - pos += writeDataIntoDrawingRecord(drawingData, writtenEscherBytes, pos, data, i); - } - - for (NoteRecord noteRecord : tailRec.values()) { - Record rec = (Record) noteRecord; - pos += rec.serialize(pos, data); - } - int bytesWritten = pos - offset; - if (bytesWritten != getRecordSize()) - throw new RecordFormatException(bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize()); - return bytesWritten; - } - - /** - * @param drawingData - escher records saved into single byte array - * @param writtenEscherBytes - count of bytes already saved into drawing records (we should know it to decide create - * drawing or continue record) - * @param pos current position of data array - * @param data - array of bytes where drawing records must be serialized - * @param i - number of shape, saved into data array - * @return offset of data array after serialization - */ - private int writeDataIntoDrawingRecord(byte[] drawingData, int writtenEscherBytes, int pos, byte[] data, int i) { - int temp = 0; - //First record in drawing layer MUST be DrawingRecord - if (writtenEscherBytes + drawingData.length > RecordInputStream.MAX_RECORD_DATA_SIZE && i != 1) { - for (int j = 0; j < drawingData.length; j += RecordInputStream.MAX_RECORD_DATA_SIZE) { - byte[] buf = new byte[Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)]; - System.arraycopy(drawingData, j, buf, 0, Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)); - ContinueRecord drawing = new ContinueRecord(buf); - temp += drawing.serialize(pos + temp, data); - } - } else { - for (int j = 0; j < drawingData.length; j += RecordInputStream.MAX_RECORD_DATA_SIZE) { - if (j == 0) { - DrawingRecord drawing = new DrawingRecord(); - byte[] buf = new byte[Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)]; - System.arraycopy(drawingData, j, buf, 0, Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)); - drawing.setData(buf); - temp += drawing.serialize(pos + temp, data); - } else { - byte[] buf = new byte[Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)]; - System.arraycopy(drawingData, j, buf, 0, Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)); - ContinueRecord drawing = new ContinueRecord(buf); - temp += drawing.serialize(pos + temp, data); - } - } - } - return temp; - } - - /** - * How many bytes do the raw escher records contain. - * - * @param records List of escher records - * @return the number of bytes - */ - private int getEscherRecordSize(List records) { - int size = 0; - for (EscherRecord record : records){ - size += record.getRecordSize(); - } - return size; - } - - /** - * @return record size, including header size of obj, text, note, drawing, continue records - */ - public int getRecordSize() { - // To determine size of aggregate record we have to know size of each DrawingRecord because if DrawingRecord - // is split into several continue records we have to add header size to total EscherAggregate size - int continueRecordsHeadersSize = 0; - // Determine buffer size - List records = getEscherRecords(); - int rawEscherSize = getEscherRecordSize(records); - byte[] buffer = new byte[rawEscherSize]; - final List spEndingOffsets = new ArrayList(); - int pos = 0; - for (EscherRecord e : records) { - pos += e.serialize(pos, buffer, new EscherSerializationListener() { - public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) { - } - - public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) { - if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) { - spEndingOffsets.add(offset); - } - } - }); - } - spEndingOffsets.add(0, 0); - - for (int i = 1; i < spEndingOffsets.size(); i++) { - if (i == spEndingOffsets.size() - 1 && spEndingOffsets.get(i) < pos) { - continueRecordsHeadersSize += 4; - } - if (spEndingOffsets.get(i) - spEndingOffsets.get(i - 1) <= RecordInputStream.MAX_RECORD_DATA_SIZE) { - continue; - } - continueRecordsHeadersSize += ((spEndingOffsets.get(i) - spEndingOffsets.get(i - 1)) / RecordInputStream.MAX_RECORD_DATA_SIZE) * 4; - } - - int drawingRecordSize = rawEscherSize + (shapeToObj.size()) * 4; - if (rawEscherSize != 0 && spEndingOffsets.size() == 1/**EMPTY**/) { - continueRecordsHeadersSize += 4; - } - int objRecordSize = 0; - for (Record r : shapeToObj.values()) { - objRecordSize += r.getRecordSize(); - } - int tailRecordSize = 0; - for (NoteRecord noteRecord : tailRec.values()) { - tailRecordSize += noteRecord.getRecordSize(); - } - return drawingRecordSize + objRecordSize + tailRecordSize + continueRecordsHeadersSize; - } - - /** - * Associates an escher record to an OBJ record or a TXO record. - * @param r - ClientData or Textbox record - * @param objRecord - Obj or TextObj record - */ - public void associateShapeToObjRecord(EscherRecord r, Record objRecord) { - shapeToObj.put(r, objRecord); - } - - /** - * Remove echerRecord and associated to it Obj or TextObj record - * @param rec - clientData or textbox record to be removed - */ - public void removeShapeToObjRecord(EscherRecord rec) { - shapeToObj.remove(rec); - } - - /** - * @return "ESCHERAGGREGATE" - */ - protected String getRecordName() { - return "ESCHERAGGREGATE"; - } - - // =============== Private methods ======================== - - /** - * - * @param records list of the record to look inside - * @param loc location of the checked record - * @return true if record is instance of ObjRecord or TextObjectRecord - */ - private static boolean isObjectRecord(List records, int loc) { - return sid(records, loc) == ObjRecord.sid || sid(records, loc) == TextObjectRecord.sid; - } - - /** - * create base tree with such structure: - * EscherDgContainer - * -EscherSpgrContainer - * --EscherSpContainer - * ---EscherSpRecord - * ---EscherSpgrRecord - * ---EscherSpRecord - * -EscherDgRecord - * - * id of DgRecord and SpRecord are empty and must be set later by HSSFPatriarch - */ - private void buildBaseTree() { - EscherContainerRecord dgContainer = new EscherContainerRecord(); - EscherContainerRecord spgrContainer = new EscherContainerRecord(); - EscherContainerRecord spContainer1 = new EscherContainerRecord(); - EscherSpgrRecord spgr = new EscherSpgrRecord(); - EscherSpRecord sp1 = new EscherSpRecord(); - dgContainer.setRecordId(EscherContainerRecord.DG_CONTAINER); - dgContainer.setOptions((short) 0x000F); - EscherDgRecord dg = new EscherDgRecord(); - dg.setRecordId(EscherDgRecord.RECORD_ID); - short dgId = 1; - dg.setOptions((short) (dgId << 4)); - dg.setNumShapes(0); - dg.setLastMSOSPID(1024); - spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); - spgrContainer.setOptions((short) 0x000F); - spContainer1.setRecordId(EscherContainerRecord.SP_CONTAINER); - spContainer1.setOptions((short) 0x000F); - spgr.setRecordId(EscherSpgrRecord.RECORD_ID); - spgr.setOptions((short) 0x0001); // version - spgr.setRectX1(0); - spgr.setRectY1(0); - spgr.setRectX2(1023); - spgr.setRectY2(255); - sp1.setRecordId(EscherSpRecord.RECORD_ID); - - sp1.setOptions((short) 0x0002); - sp1.setVersion((short) 0x2); - sp1.setShapeId(-1); - sp1.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH); - dgContainer.addChildRecord(dg); - dgContainer.addChildRecord(spgrContainer); - spgrContainer.addChildRecord(spContainer1); - spContainer1.addChildRecord(spgr); - spContainer1.addChildRecord(sp1); - addEscherRecord(dgContainer); - } - - /** - * EscherDgContainer - * -EscherSpgrContainer - * -EscherDgRecord - set id for this record - * set id for DgRecord of DgContainer - * @param dgId - id which must be set - */ - public void setDgId(short dgId) { - EscherContainerRecord dgContainer = getEscherContainer(); - EscherDgRecord dg = dgContainer.getChildById(EscherDgRecord.RECORD_ID); - dg.setOptions((short) (dgId << 4)); - } - - /** - * EscherDgContainer - * -EscherSpgrContainer - * --EscherSpContainer - * ---EscherSpRecord -set id for this record - * ---*** - * --*** - * -EscherDgRecord - * set id for the sp record of the first spContainer in main spgrConatiner - * @param shapeId - id which must be set - */ - public void setMainSpRecordId(int shapeId) { - EscherContainerRecord dgContainer = getEscherContainer(); - EscherContainerRecord spgrConatiner = (EscherContainerRecord) dgContainer.getChildById(EscherContainerRecord.SPGR_CONTAINER); - EscherContainerRecord spContainer = (EscherContainerRecord) spgrConatiner.getChild(0); - EscherSpRecord sp = (EscherSpRecord) spContainer.getChildById(EscherSpRecord.RECORD_ID); - sp.setShapeId(shapeId); - } - - /** - * @param records list of records to look into - * @param loc - location of the record which sid must be returned - * @return sid of the record with selected location - */ - private static short sid(List records, int loc) { - RecordBase record = records.get(loc); - if (record instanceof Record) { - return ((Record)record).getSid(); - } else { - // Aggregates don't have a sid - // We could step into them, but for these needs we don't care - return -1; - } - } - - /** - * @return unmodifiable copy of the mapping of {@link EscherClientDataRecord} and {@link EscherTextboxRecord} - * to their {@link TextObjectRecord} or {@link ObjRecord} . - *

    - * We need to access it outside of EscherAggregate when building shapes - */ - public Map getShapeToObjMapping() { - return Collections.unmodifiableMap(shapeToObj); - } - - /** - * @return unmodifiable copy of tail records. We need to access them when building shapes. - * Every HSSFComment shape has a link to a NoteRecord from the tailRec collection. - */ - public Map getTailRecords() { - return Collections.unmodifiableMap(tailRec); - } - - /** - * @param obj - ObjRecord with id == NoteRecord.id - * @return null if note record is not found else returns note record with id == obj.id - */ - public NoteRecord getNoteRecordByObj(ObjRecord obj) { - CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) obj.getSubRecords().get(0); - return tailRec.get(cod.getObjectId()); - } - - /** - * Add tail record to existing map - * @param note to be added - */ - public void addTailRecord(NoteRecord note) { - tailRec.put(note.getShapeId(), note); - } - - /** - * Remove tail record from the existing map - * @param note to be removed - */ - public void removeTailRecord(NoteRecord note) { - tailRec.remove(note.getShapeId()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java deleted file mode 100644 index 3732fd52a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java +++ /dev/null @@ -1,184 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.cont.ContinuableRecord; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.util.LittleEndianOutput; - -import java.util.ArrayList; - -/** - * Title: Extended Static String Table (0x00FF)

    - * Description: This record is used for a quick lookup into the SST record. This - * record breaks the SST table into a set of buckets. The offsets - * to these buckets within the SST record are kept as well as the - * position relative to the start of the SST record.

    - * REFERENCE: PG 313 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class ExtSSTRecord extends ContinuableRecord { - public final static short sid = 0x00FF; - public static final int DEFAULT_BUCKET_SIZE = 8; - //Can't seem to find this documented but from the biffviewer it is clear that - //Excel only records the indexes for the first 128 buckets. - public static final int MAX_BUCKETS = 128; - - - public static final class InfoSubRecord { - public static final int ENCODED_SIZE = 8; - private int field_1_stream_pos; // stream pointer to the SST record - private int field_2_bucket_sst_offset; // don't really understand this yet. - /** unused - supposed to be zero */ - private short field_3_zero; - - /** - * Creates new ExtSSTInfoSubRecord - * - * @param streamPos stream pointer to the SST record - * @param bucketSstOffset ... don't really understand this yet - */ - public InfoSubRecord(int streamPos, int bucketSstOffset) { - field_1_stream_pos = streamPos; - field_2_bucket_sst_offset = bucketSstOffset; - } - - public InfoSubRecord(RecordInputStream in) - { - field_1_stream_pos = in.readInt(); - field_2_bucket_sst_offset = in.readShort(); - field_3_zero = in.readShort(); - } - - public int getStreamPos() { - return field_1_stream_pos; - } - - public int getBucketSSTOffset() { - return field_2_bucket_sst_offset; - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(field_1_stream_pos); - out.writeShort(field_2_bucket_sst_offset); - out.writeShort(field_3_zero); - } - } - - - private short _stringsPerBucket; - private InfoSubRecord[] _sstInfos; - - - public ExtSSTRecord() { - _stringsPerBucket = DEFAULT_BUCKET_SIZE; - _sstInfos = new InfoSubRecord[0]; - } - - public ExtSSTRecord(RecordInputStream in) { - _stringsPerBucket = in.readShort(); - - int nInfos = in.remaining() / InfoSubRecord.ENCODED_SIZE; - ArrayList lst = new ArrayList(nInfos); - - while (in.available() > 0) { - InfoSubRecord info = new InfoSubRecord(in); - lst.add(info); - - if(in.available() == 0 && in.hasNextRecord() && in.getNextSid() == ContinueRecord.sid) { - in.nextRecord(); - } - } - _sstInfos = lst.toArray(new InfoSubRecord[lst.size()]); - } - - public void setNumStringsPerBucket(short numStrings) { - _stringsPerBucket = numStrings; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[EXTSST]\n"); - buffer.append(" .dsst = ") - .append(Integer.toHexString(_stringsPerBucket)) - .append("\n"); - buffer.append(" .numInfoRecords = ").append(_sstInfos.length) - .append("\n"); - for (int k = 0; k < _sstInfos.length; k++) - { - buffer.append(" .inforecord = ").append(k).append("\n"); - buffer.append(" .streampos = ") - .append(Integer - .toHexString(_sstInfos[k].getStreamPos())).append("\n"); - buffer.append(" .sstoffset = ") - .append(Integer - .toHexString(_sstInfos[k].getBucketSSTOffset())) - .append("\n"); - } - buffer.append("[/EXTSST]\n"); - return buffer.toString(); - } - - public void serialize(ContinuableRecordOutput out) { - out.writeShort(_stringsPerBucket); - for (int k = 0; k < _sstInfos.length; k++) { - _sstInfos[k].serialize(out); - } - } - protected int getDataSize() { - return 2 + InfoSubRecord.ENCODED_SIZE*_sstInfos.length; - } - - protected InfoSubRecord[] getInfoSubRecords() { - return _sstInfos; - } - - public static final int getNumberOfInfoRecsForStrings(int numStrings) { - int infoRecs = (numStrings / DEFAULT_BUCKET_SIZE); - if ((numStrings % DEFAULT_BUCKET_SIZE) != 0) - infoRecs ++; - //Excel seems to max out after 128 info records. - //This isn't really documented anywhere... - if (infoRecs > MAX_BUCKETS) - infoRecs = MAX_BUCKETS; - return infoRecs; - } - - /** - * Given a number of strings (in the sst), returns the size of the extsst record - * - * @param numStrings the number of strings - * - * @return the size of the extsst record - */ - public static final int getRecordSizeForStrings(int numStrings) { - return 4 + 2 + getNumberOfInfoRecsForStrings(numStrings) * 8; - } - - public short getSid() { - return sid; - } - - public void setBucketOffsets(int[] bucketAbsoluteOffsets, int[] bucketRelativeOffsets) { - // TODO - replace no-arg constructor with this logic - _sstInfos = new InfoSubRecord[bucketAbsoluteOffsets.length]; - for (int i = 0; i < bucketAbsoluteOffsets.length; i++) { - _sstInfos[i] = new InfoSubRecord(bucketAbsoluteOffsets[i], bucketRelativeOffsets[i]); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java deleted file mode 100644 index 3d043681b..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java +++ /dev/null @@ -1,1873 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Extended Format Record - * Description: Probably one of the more complex records. There are two breeds: - * Style and Cell. - *

    - * It should be noted that fields in the extended format record are - * somewhat arbitrary. Almost all of the fields are bit-level, but - * we name them as best as possible by functional group. In some - * places this is better than others. - *

    - * - * REFERENCE: PG 426 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - - * @since 2.0-pre - */ - -public final class ExtendedFormatRecord - extends StandardRecord -{ - public static final short sid = 0xE0; - - // null constant - public static final short NULL = (short)0xfff0; - - // xf type - public static final short XF_STYLE = 1; - public static final short XF_CELL = 0; - - // borders - public static final short NONE = 0x0; - public static final short THIN = 0x1; - public static final short MEDIUM = 0x2; - public static final short DASHED = 0x3; - public static final short DOTTED = 0x4; - public static final short THICK = 0x5; - public static final short DOUBLE = 0x6; - public static final short HAIR = 0x7; - public static final short MEDIUM_DASHED = 0x8; - public static final short DASH_DOT = 0x9; - public static final short MEDIUM_DASH_DOT = 0xA; - public static final short DASH_DOT_DOT = 0xB; - public static final short MEDIUM_DASH_DOT_DOT = 0xC; - public static final short SLANTED_DASH_DOT = 0xD; - - // alignment - public static final short GENERAL = 0x0; - public static final short LEFT = 0x1; - public static final short CENTER = 0x2; - public static final short RIGHT = 0x3; - public static final short FILL = 0x4; - public static final short JUSTIFY = 0x5; - public static final short CENTER_SELECTION = 0x6; - - // vertical alignment - public static final short VERTICAL_TOP = 0x0; - public static final short VERTICAL_CENTER = 0x1; - public static final short VERTICAL_BOTTOM = 0x2; - public static final short VERTICAL_JUSTIFY = 0x3; - - // fill - public static final short NO_FILL = 0 ; - public static final short SOLID_FILL = 1 ; - public static final short FINE_DOTS = 2 ; - public static final short ALT_BARS = 3 ; - public static final short SPARSE_DOTS = 4 ; - public static final short THICK_HORZ_BANDS = 5 ; - public static final short THICK_VERT_BANDS = 6 ; - public static final short THICK_BACKWARD_DIAG = 7 ; - public static final short THICK_FORWARD_DIAG = 8 ; - public static final short BIG_SPOTS = 9 ; - public static final short BRICKS = 10 ; - public static final short THIN_HORZ_BANDS = 11 ; - public static final short THIN_VERT_BANDS = 12 ; - public static final short THIN_BACKWARD_DIAG = 13 ; - public static final short THIN_FORWARD_DIAG = 14 ; - public static final short SQUARES = 15 ; - public static final short DIAMONDS = 16 ; - - // fields in BOTH style and Cell XF records - private short field_1_font_index; // not bit-mapped - private short field_2_format_index; // not bit-mapped - - // field_3_cell_options bit map - private static final BitField _locked = BitFieldFactory.getInstance(0x0001); - private static final BitField _hidden = BitFieldFactory.getInstance(0x0002); - private static final BitField _xf_type = BitFieldFactory.getInstance(0x0004); - private static final BitField _123_prefix = BitFieldFactory.getInstance(0x0008); - private static final BitField _parent_index = BitFieldFactory.getInstance(0xFFF0); - private short field_3_cell_options; - - // field_4_alignment_options bit map - private static final BitField _alignment = BitFieldFactory.getInstance(0x0007); - private static final BitField _wrap_text = BitFieldFactory.getInstance(0x0008); - private static final BitField _vertical_alignment = BitFieldFactory.getInstance(0x0070); - private static final BitField _justify_last = BitFieldFactory.getInstance(0x0080); - private static final BitField _rotation = BitFieldFactory.getInstance(0xFF00); - private short field_4_alignment_options; - - // field_5_indention_options - private static final BitField _indent = - BitFieldFactory.getInstance(0x000F); - private static final BitField _shrink_to_fit = - BitFieldFactory.getInstance(0x0010); - private static final BitField _merge_cells = - BitFieldFactory.getInstance(0x0020); - private static final BitField _reading_order = - BitFieldFactory.getInstance(0x00C0); - - // apparently bits 8 and 9 are unused - private static final BitField _indent_not_parent_format = - BitFieldFactory.getInstance(0x0400); - private static final BitField _indent_not_parent_font = - BitFieldFactory.getInstance(0x0800); - private static final BitField _indent_not_parent_alignment = - BitFieldFactory.getInstance(0x1000); - private static final BitField _indent_not_parent_border = - BitFieldFactory.getInstance(0x2000); - private static final BitField _indent_not_parent_pattern = - BitFieldFactory.getInstance(0x4000); - private static final BitField _indent_not_parent_cell_options = - BitFieldFactory.getInstance(0x8000); - private short field_5_indention_options; - - // field_6_border_options bit map - private static final BitField _border_left = BitFieldFactory.getInstance(0x000F); - private static final BitField _border_right = BitFieldFactory.getInstance(0x00F0); - private static final BitField _border_top = BitFieldFactory.getInstance(0x0F00); - private static final BitField _border_bottom = BitFieldFactory.getInstance(0xF000); - private short field_6_border_options; - - // all three of the following attributes are palette options - // field_7_palette_options bit map - private static final BitField _left_border_palette_idx = - BitFieldFactory.getInstance(0x007F); - private static final BitField _right_border_palette_idx = - BitFieldFactory.getInstance(0x3F80); - private static final BitField _diag = - BitFieldFactory.getInstance(0xC000); - private short field_7_palette_options; - - // field_8_adtl_palette_options bit map - private static final BitField _top_border_palette_idx = - BitFieldFactory.getInstance(0x0000007F); - private static final BitField _bottom_border_palette_idx = - BitFieldFactory.getInstance(0x00003F80); - private static final BitField _adtl_diag = - BitFieldFactory.getInstance(0x001fc000); - private static final BitField _adtl_diag_line_style = - BitFieldFactory.getInstance(0x01e00000); - - // apparently bit 25 is unused - private static final BitField _adtl_fill_pattern = - BitFieldFactory.getInstance(0xfc000000); - private int field_8_adtl_palette_options; // additional to avoid 2 - - // field_9_fill_palette_options bit map - private static final BitField _fill_foreground = BitFieldFactory.getInstance(0x007F); - private static final BitField _fill_background = BitFieldFactory.getInstance(0x3f80); - - // apparently bits 15 and 14 are unused - private short field_9_fill_palette_options; - - /** - * Constructor ExtendedFormatRecord - * - * - */ - - public ExtendedFormatRecord() - { - } - - public ExtendedFormatRecord(RecordInputStream in) - { - field_1_font_index = in.readShort(); - field_2_format_index = in.readShort(); - field_3_cell_options = in.readShort(); - field_4_alignment_options = in.readShort(); - field_5_indention_options = in.readShort(); - field_6_border_options = in.readShort(); - field_7_palette_options = in.readShort(); - field_8_adtl_palette_options = in.readInt(); - field_9_fill_palette_options = in.readShort(); - } - - /** - * set the index to the FONT record (which font to use 0 based) - * - * - * @param index to the font - * @see org.apache.poi.hssf.record.FontRecord - */ - - public void setFontIndex(short index) - { - field_1_font_index = index; - } - - /** - * set the index to the Format record (which FORMAT to use 0-based) - * - * - * @param index to the format record - * @see org.apache.poi.hssf.record.FormatRecord - */ - - public void setFormatIndex(short index) - { - field_2_format_index = index; - } - - /** - * sets the options bitmask - you can also use corresponding option bit setters - * (see other methods that reference this one) - * - * - * @param options bitmask to set - * - */ - - public void setCellOptions(short options) - { - field_3_cell_options = options; - } - - // These are the bit fields in cell options - - /** - * set whether the cell is locked or not - * - * - * @param locked - if the cell is locked - * @see #setCellOptions(short) - */ - - public void setLocked(boolean locked) - { - field_3_cell_options = _locked.setShortBoolean(field_3_cell_options, - locked); - } - - /** - * set whether the cell is hidden or not - * - * - * @param hidden - if the cell is hidden - * @see #setCellOptions(short) - */ - - public void setHidden(boolean hidden) - { - field_3_cell_options = _hidden.setShortBoolean(field_3_cell_options, - hidden); - } - - /** - * set whether the cell is a cell or style XFRecord - * - * - * @param type - cell or style (0/1) - * @see #XF_STYLE - * @see #XF_CELL - * @see #setCellOptions(short) - */ - - public void setXFType(short type) - { - field_3_cell_options = _xf_type.setShortValue(field_3_cell_options, - type); - } - - /** - * set some old holdover from lotus 123. Who cares, its all over for Lotus. - * RIP Lotus. - * - * @param prefix - the lotus thing to set. - * @see #setCellOptions(short) - */ - - public void set123Prefix(boolean prefix) - { - field_3_cell_options = - _123_prefix.setShortBoolean(field_3_cell_options, prefix); - } - - // present in both but NULL except in cell records - - /** - * for cell XF types this is the parent style (usually 0/normal). For - * style this should be NULL. - * - * @param parent index of parent XF - * @see #NULL - * @see #setCellOptions(short) - */ - - public void setParentIndex(short parent) - { - field_3_cell_options = - _parent_index.setShortValue(field_3_cell_options, parent); - } - - // end bitfields in cell options - - /** - * set the alignment options bitmask. See corresponding bitsetter methods - * that reference this one. - * - * - * @param options - the bitmask to set - */ - - public void setAlignmentOptions(short options) - { - field_4_alignment_options = options; - } - - /** - * set the horizontal alignment of the cell. - * - * - * @param align - how to align the cell (see constants) - * @see #GENERAL - * @see #LEFT - * @see #CENTER - * @see #RIGHT - * @see #FILL - * @see #JUSTIFY - * @see #CENTER_SELECTION - * @see #setAlignmentOptions(short) - */ - - public void setAlignment(short align) - { - field_4_alignment_options = - _alignment.setShortValue(field_4_alignment_options, align); - } - - /** - * set whether to wrap the text in the cell - * - * - * @param wrapped - whether or not to wrap the cell text - * @see #setAlignmentOptions(short) - */ - - public void setWrapText(boolean wrapped) - { - field_4_alignment_options = - _wrap_text.setShortBoolean(field_4_alignment_options, wrapped); - } - - /** - * set the vertical alignment of text in the cell - * - * - * @param align where to align the text - * @see #VERTICAL_TOP - * @see #VERTICAL_CENTER - * @see #VERTICAL_BOTTOM - * @see #VERTICAL_JUSTIFY - * - * @see #setAlignmentOptions(short) - */ - - public void setVerticalAlignment(short align) - { - field_4_alignment_options = - _vertical_alignment.setShortValue(field_4_alignment_options, - align); - } - - /** - * Dunno. Docs just say this is for far east versions.. (I'm guessing it - * justifies for right-to-left read languages) - * - * @param justify use 0 for US - * @see #setAlignmentOptions(short) - */ - - public void setJustifyLast(short justify) - { // for far east languages supported only for format always 0 for US - field_4_alignment_options = - _justify_last.setShortValue(field_4_alignment_options, justify); - } - - /** - * set the degree of rotation. - * - * - * @param rotation the degree of rotation - * @see #setAlignmentOptions(short) - */ - - public void setRotation(short rotation) - { - field_4_alignment_options = - _rotation.setShortValue(field_4_alignment_options, rotation); - } - - /** - * set the indent options bitmask (see corresponding bitmask setters that reference - * this field) - * - * - * @param options bitmask to set. - * - */ - - public void setIndentionOptions(short options) - { - field_5_indention_options = options; - } - - // set bitfields for indention options - - /** - * set indention (not sure of the units, think its spaces) - * - * @param indent - how far to indent the cell - * @see #setIndentionOptions(short) - */ - - public void setIndent(short indent) - { - field_5_indention_options = - _indent.setShortValue(field_5_indention_options, indent); - } - - /** - * set whether to shrink the text to fit - * - * - * @param shrink - shrink to fit or not - * @see #setIndentionOptions(short) - */ - - public void setShrinkToFit(boolean shrink) - { - field_5_indention_options = - _shrink_to_fit.setShortBoolean(field_5_indention_options, shrink); - } - - /** - * set whether to merge cells - * - * - * @param merge - merge cells or not - * @see #setIndentionOptions(short) - */ - - public void setMergeCells(boolean merge) - { - field_5_indention_options = - _merge_cells.setShortBoolean(field_5_indention_options, merge); - } - - /** - * set the reading order for far east versions (0 - Context, 1 - Left to right, - * 2 - right to left) - We could use some help with support for the far east. - * - * @param order - the reading order (0,1,2) - * @see #setIndentionOptions(short) - */ - - public void setReadingOrder(short order) - { // only for far east always 0 in US - field_5_indention_options = - _reading_order.setShortValue(field_5_indention_options, order); - } - - /** - * set whether or not to use the format in this XF instead of the parent XF. - * - * - * @param parent - true if this XF has a different format value than its parent, - * false otherwise. - * @see #setIndentionOptions(short) - */ - - public void setIndentNotParentFormat(boolean parent) - { - field_5_indention_options = - _indent_not_parent_format - .setShortBoolean(field_5_indention_options, parent); - } - - /** - * set whether or not to use the font in this XF instead of the parent XF. - * - * - * @param font - true if this XF has a different font value than its parent, - * false otherwise. - * @see #setIndentionOptions(short) - */ - - public void setIndentNotParentFont(boolean font) - { - field_5_indention_options = - _indent_not_parent_font.setShortBoolean(field_5_indention_options, - font); - } - - /** - * set whether or not to use the alignment in this XF instead of the parent XF. - * - * - * @param alignment true if this XF has a different alignment value than its parent, - * false otherwise. - * @see #setIndentionOptions(short) - */ - - public void setIndentNotParentAlignment(boolean alignment) - { - field_5_indention_options = - _indent_not_parent_alignment - .setShortBoolean(field_5_indention_options, alignment); - } - - /** - * set whether or not to use the border in this XF instead of the parent XF. - * - * - * @param border - true if this XF has a different border value than its parent, - * false otherwise. - * @see #setIndentionOptions(short) - */ - - public void setIndentNotParentBorder(boolean border) - { - field_5_indention_options = - _indent_not_parent_border - .setShortBoolean(field_5_indention_options, border); - } - - /** - *

    Sets whether or not to use the pattern in this XF instead of the - * parent XF (foreground/background).

    - * - * @param pattern {@code true} if this XF has a different pattern - * value than its parent, {@code false} otherwise. - * @see #setIndentionOptions(short) - */ - - public void setIndentNotParentPattern(boolean pattern) - { - field_5_indention_options = - _indent_not_parent_pattern - .setShortBoolean(field_5_indention_options, pattern); - } - - /** - * set whether or not to use the locking/hidden in this XF instead of the parent XF. - * - * - * @param options true if this XF has a different locking or hidden value than its parent, - * false otherwise. - * @see #setIndentionOptions(short) - */ - - public void setIndentNotParentCellOptions(boolean options) - { - field_5_indention_options = - _indent_not_parent_cell_options - .setShortBoolean(field_5_indention_options, options); - } - - // end indention options bitmask sets - - /** - * set the border options bitmask (see the corresponding bitsetter methods - * that reference back to this one) - * - * @param options - the bit mask to set - * - */ - - public void setBorderOptions(short options) - { - field_6_border_options = options; - } - - // border options bitfields - - /** - * set the borderline style for the left border - * - * - * @param border - type of border for the left side of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #setBorderOptions(short) - */ - - public void setBorderLeft(short border) - { - field_6_border_options = - _border_left.setShortValue(field_6_border_options, border); - } - - /** - * set the border line style for the right border - * - * - * @param border - type of border for the right side of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #setBorderOptions(short) - */ - - public void setBorderRight(short border) - { - field_6_border_options = - _border_right.setShortValue(field_6_border_options, border); - } - - /** - * set the border line style for the top border - * - * - * @param border - type of border for the top of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #setBorderOptions(short) - */ - - public void setBorderTop(short border) - { - field_6_border_options = - _border_top.setShortValue(field_6_border_options, border); - } - - /** - * set the border line style for the bottom border - * - * - * @param border - type of border for the bottom of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #setBorderOptions(short) - */ - - public void setBorderBottom(short border) - { - field_6_border_options = - _border_bottom.setShortValue(field_6_border_options, border); - } - - // end border option bitfields - - /** - * set the palette options bitmask (see the individual bitsetter methods that - * reference this one) - * - * - * @param options - the bitmask to set - * - */ - - public void setPaletteOptions(short options) - { - field_7_palette_options = options; - } - - // bitfields for palette options - - /** - * set the palette index for the left border color - * - * - * @param border - palette index - * @see #setPaletteOptions(short) - */ - - public void setLeftBorderPaletteIdx(short border) - { - field_7_palette_options = - _left_border_palette_idx.setShortValue(field_7_palette_options, - border); - } - - /** - * set the palette index for the right border color - * - * - * @param border - palette index - * @see #setPaletteOptions(short) - */ - - public void setRightBorderPaletteIdx(short border) - { - field_7_palette_options = - _right_border_palette_idx.setShortValue(field_7_palette_options, - border); - } - - // i've no idea.. possible values are 1 for down, 2 for up and 3 for both...0 for none.. - // maybe a diagnal line? - - /** - * Not sure what this is for (maybe fill lines?) 1 = down, 2 = up, 3 = both, 0 for none.. - * - * - * @param diag - set whatever it is that this is. - * @see #setPaletteOptions(short) - */ - - public void setDiag(short diag) - { - field_7_palette_options = _diag.setShortValue(field_7_palette_options, - diag); - } - - // end of palette options - - /** - * set the additional palette options bitmask (see individual bitsetter methods - * that reference this method) - * - * - * @param options - bitmask to set - * - */ - - public void setAdtlPaletteOptions(short options) - { - field_8_adtl_palette_options = options; - } - - // bitfields for additional palette options - - /** - * set the palette index for the top border - * - * - * @param border - palette index - * @see #setAdtlPaletteOptions(short) - */ - - public void setTopBorderPaletteIdx(short border) - { - field_8_adtl_palette_options = - _top_border_palette_idx.setValue(field_8_adtl_palette_options, - border); - } - - /** - * set the palette index for the bottom border - * - * - * @param border - palette index - * @see #setAdtlPaletteOptions(short) - */ - - public void setBottomBorderPaletteIdx(short border) - { - field_8_adtl_palette_options = - _bottom_border_palette_idx.setValue(field_8_adtl_palette_options, - border); - } - - /** - * set for diagonal borders? No idea (its a palette color for the other function - * we didn't know what was?) - * - * - * @param diag - the palette index? - * @see #setAdtlPaletteOptions(short) - */ - - public void setAdtlDiag(short diag) - { - field_8_adtl_palette_options = - _adtl_diag.setValue(field_8_adtl_palette_options, diag); - } - - /** - * set the diagonal border line style? Who the heck ever heard of a diagonal border? - * - * - * @param diag - the line style - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #setAdtlPaletteOptions(short) - */ - - public void setAdtlDiagLineStyle(short diag) - { - field_8_adtl_palette_options = - _adtl_diag_line_style.setValue(field_8_adtl_palette_options, - diag); - } - - /** - * set the fill pattern - * - * @see #NO_FILL - * @see #SOLID_FILL - * @see #FINE_DOTS - * @see #ALT_BARS - * @see #SPARSE_DOTS - * @see #THICK_HORZ_BANDS - * @see #THICK_VERT_BANDS - * @see #THICK_BACKWARD_DIAG - * @see #THICK_FORWARD_DIAG - * @see #BIG_SPOTS - * @see #BRICKS - * @see #THIN_HORZ_BANDS - * @see #THIN_VERT_BANDS - * @see #THIN_BACKWARD_DIAG - * @see #THIN_FORWARD_DIAG - * @see #SQUARES - * @see #DIAMONDS - * - * @param fill - fill pattern?? - * @see #setAdtlPaletteOptions(short) - */ - - public void setAdtlFillPattern(short fill) - { - field_8_adtl_palette_options = - _adtl_fill_pattern.setValue(field_8_adtl_palette_options, fill); - } - - /** - * set the fill palette options bitmask (see bitfields for additional palette options) - * - * @param options the palette options - */ - - public void setFillPaletteOptions(short options) - { - field_9_fill_palette_options = options; - } - - /** - * set the foreground palette color index - * - * - * @param color - palette index - * @see #setFillPaletteOptions(short) - */ - - public void setFillForeground(short color) - { - field_9_fill_palette_options = - _fill_foreground.setShortValue(field_9_fill_palette_options, - color); - } - - /** - * set the background palette color index - * - * - * @param color - palette index - * @see #setFillPaletteOptions(short) - */ - - public void setFillBackground(short color) - { - field_9_fill_palette_options = - _fill_background.setShortValue(field_9_fill_palette_options, - color); - } - - /** - * get the index to the FONT record (which font to use 0 based) - * - * - * @return index to the font - * @see org.apache.poi.hssf.record.FontRecord - */ - - public short getFontIndex() - { - return field_1_font_index; - } - - /** - * get the index to the Format record (which FORMAT to use 0-based) - * - * - * @return index to the format record - * @see org.apache.poi.hssf.record.FormatRecord - */ - - public short getFormatIndex() - { - return field_2_format_index; - } - - /** - * gets the options bitmask - you can also use corresponding option bit getters - * (see other methods that reference this one) - * - * - * @return options bitmask - * - */ - - public short getCellOptions() - { - return field_3_cell_options; - } - - // These are the bit fields in cell options - - /** - * get whether the cell is locked or not - * - * - * @return locked - if the cell is locked - * @see #getCellOptions() - */ - - public boolean isLocked() - { - return _locked.isSet(field_3_cell_options); - } - - /** - * get whether the cell is hidden or not - * - * - * @return hidden - if the cell is hidden - * @see #getCellOptions() - */ - - public boolean isHidden() - { - return _hidden.isSet(field_3_cell_options); - } - - /** - * get whether the cell is a cell or style XFRecord - * - * - * @return type - cell or style (0/1) - * @see #XF_STYLE - * @see #XF_CELL - * @see #getCellOptions() - */ - - public short getXFType() - { - return _xf_type.getShortValue(field_3_cell_options); - } - - /** - * get some old holdover from lotus 123. Who cares, its all over for Lotus. - * RIP Lotus. - * - * @return prefix - the lotus thing - * @see #getCellOptions() - */ - - public boolean get123Prefix() - { - return _123_prefix.isSet(field_3_cell_options); - } - - /** - * for cell XF types this is the parent style (usually 0/normal). For - * style this should be NULL. - * - * @return index of parent XF - * @see #NULL - * @see #getCellOptions() - */ - - public short getParentIndex() - { - return _parent_index.getShortValue(field_3_cell_options); - } - - // end bitfields in cell options - - /** - * get the alignment options bitmask. See corresponding bitgetter methods - * that reference this one. - * - * - * @return options - the bitmask - */ - - public short getAlignmentOptions() - { - return field_4_alignment_options; - } - - // bitfields in alignment options - - /** - * get the horizontal alignment of the cell. - * - * - * @return align - how to align the cell (see constants) - * @see #GENERAL - * @see #LEFT - * @see #CENTER - * @see #RIGHT - * @see #FILL - * @see #JUSTIFY - * @see #CENTER_SELECTION - * @see #getAlignmentOptions() - */ - - public short getAlignment() - { - return _alignment.getShortValue(field_4_alignment_options); - } - - /** - * get whether to wrap the text in the cell - * - * - * @return wrapped - whether or not to wrap the cell text - * @see #getAlignmentOptions() - */ - - public boolean getWrapText() - { - return _wrap_text.isSet(field_4_alignment_options); - } - - /** - * get the vertical alignment of text in the cell - * - * - * @return where to align the text - * @see #VERTICAL_TOP - * @see #VERTICAL_CENTER - * @see #VERTICAL_BOTTOM - * @see #VERTICAL_JUSTIFY - * - * @see #getAlignmentOptions() - */ - - public short getVerticalAlignment() - { - return _vertical_alignment.getShortValue(field_4_alignment_options); - } - - /** - * Dunno. Docs just say this is for far east versions.. (I'm guessing it - * justifies for right-to-left read languages) - * - * - * @return justify - * @see #getAlignmentOptions() - */ - - public short getJustifyLast() - { // for far east languages supported only for format always 0 for US - return _justify_last.getShortValue(field_4_alignment_options); - } - - /** - * get the degree of rotation. - * - * - * @return rotation - the degree of rotation - * @see #getAlignmentOptions() - */ - - public short getRotation() - { - return _rotation.getShortValue(field_4_alignment_options); - } - - // end alignment options bitfields - - /** - * get the indent options bitmask (see corresponding bit getters that reference - * this field) - * - * - * @return options bitmask - * - */ - - public short getIndentionOptions() - { - return field_5_indention_options; - } - - // bitfields for indention options - - /** - * get indention (not sure of the units, think its spaces) - * - * @return indent - how far to indent the cell - * @see #getIndentionOptions() - */ - - public short getIndent() - { - return _indent.getShortValue(field_5_indention_options); - } - - /** - * get whether to shrink the text to fit - * - * - * @return shrink - shrink to fit or not - * @see #getIndentionOptions() - */ - - public boolean getShrinkToFit() - { - return _shrink_to_fit.isSet(field_5_indention_options); - } - - /** - * get whether to merge cells - * - * - * @return merge - merge cells or not - * @see #getIndentionOptions() - */ - - public boolean getMergeCells() - { - return _merge_cells.isSet(field_5_indention_options); - } - - /** - * get the reading order for far east versions (0 - Context, 1 - Left to right, - * 2 - right to left) - We could use some help with support for the far east. - * - * @return order - the reading order (0,1,2) - * @see #getIndentionOptions() - */ - - public short getReadingOrder() - { // only for far east always 0 in US - return _reading_order.getShortValue(field_5_indention_options); - } - - /** - * get whether or not to use the format in this XF instead of the parent XF. - * - * - * @return parent - true if this XF has a different format value than its parent, - * false otherwise. - * @see #getIndentionOptions() - */ - - public boolean isIndentNotParentFormat() - { - return _indent_not_parent_format.isSet(field_5_indention_options); - } - - /** - * get whether or not to use the font in this XF instead of the parent XF. - * - * - * @return font - true if this XF has a different font value than its parent, - * false otherwise. - * @see #getIndentionOptions() - */ - - public boolean isIndentNotParentFont() - { - return _indent_not_parent_font.isSet(field_5_indention_options); - } - - /** - * get whether or not to use the alignment in this XF instead of the parent XF. - * - * - * @return alignment true if this XF has a different alignment value than its parent, - * false otherwise. - * @see #getIndentionOptions() - */ - - public boolean isIndentNotParentAlignment() - { - return _indent_not_parent_alignment.isSet(field_5_indention_options); - } - - /** - * get whether or not to use the border in this XF instead of the parent XF. - * - * - * @return border - true if this XF has a different border value than its parent, - * false otherwise. - * @see #getIndentionOptions() - */ - - public boolean isIndentNotParentBorder() - { - return _indent_not_parent_border.isSet(field_5_indention_options); - } - - /** - * get whether or not to use the pattern in this XF instead of the parent XF. - * (foregrount/background) - * - * @return pattern- true if this XF has a different pattern value than its parent, - * false otherwise. - * @see #getIndentionOptions() - */ - - public boolean isIndentNotParentPattern() - { - return _indent_not_parent_pattern.isSet(field_5_indention_options); - } - - /** - * get whether or not to use the locking/hidden in this XF instead of the parent XF. - * - * - * @return options- true if this XF has a different locking or hidden value than its parent, - * false otherwise. - * @see #getIndentionOptions() - */ - - public boolean isIndentNotParentCellOptions() - { - return _indent_not_parent_cell_options - .isSet(field_5_indention_options); - } - - // end of bitfields for indention options - // border options - - /** - * get the border options bitmask (see the corresponding bit getter methods - * that reference back to this one) - * - * @return options - the bit mask to set - * - */ - - public short getBorderOptions() - { - return field_6_border_options; - } - - // bitfields for border options - - /** - * get the borderline style for the left border - * - * - * @return border - type of border for the left side of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #getBorderOptions() - */ - - public short getBorderLeft() - { - return _border_left.getShortValue(field_6_border_options); - } - - /** - * get the borderline style for the right border - * - * - * @return border - type of border for the right side of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #getBorderOptions() - */ - - public short getBorderRight() - { - return _border_right.getShortValue(field_6_border_options); - } - - /** - * get the borderline style for the top border - * - * - * @return border - type of border for the top of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #getBorderOptions() - */ - - public short getBorderTop() - { - return _border_top.getShortValue(field_6_border_options); - } - - /** - * get the borderline style for the bottom border - * - * - * @return border - type of border for the bottom of the cell - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #getBorderOptions() - */ - - public short getBorderBottom() - { - return _border_bottom.getShortValue(field_6_border_options); - } - - // record types -- palette options - - /** - * get the palette options bitmask (see the individual bit getter methods that - * reference this one) - * - * - * @return options - the bitmask - * - */ - - public short getPaletteOptions() - { - return field_7_palette_options; - } - - // bitfields for palette options - - /** - * get the palette index for the left border color - * - * - * @return border - palette index - * @see #getPaletteOptions() - */ - - public short getLeftBorderPaletteIdx() - { - return _left_border_palette_idx - .getShortValue(field_7_palette_options); - } - - /** - * get the palette index for the right border color - * - * - * @return border - palette index - * @see #getPaletteOptions() - */ - - public short getRightBorderPaletteIdx() - { - return _right_border_palette_idx - .getShortValue(field_7_palette_options); - } - - // i've no idea.. possible values are 1 for down, 2 for up and 3 for both...0 for none.. - // maybe a diagnal line? - - /** - * Not sure what this is for (maybe fill lines?) 1 = down, 2 = up, 3 = both, 0 for none.. - * - * - * @return diag - whatever it is that this is. - * @see #getPaletteOptions() - */ - - public short getDiag() - { - return _diag.getShortValue(field_7_palette_options); - } - - // end of style palette options - // additional palette options - - /** - * get the additional palette options bitmask (see individual bit getter methods - * that reference this method) - * - * - * @return options - bitmask to set - * - */ - - public int getAdtlPaletteOptions() - { - return field_8_adtl_palette_options; - } - - // bitfields for additional palette options - - /** - * get the palette index for the top border - * - * - * @return border - palette index - * @see #getAdtlPaletteOptions() - */ - - public short getTopBorderPaletteIdx() - { - return ( short ) _top_border_palette_idx - .getValue(field_8_adtl_palette_options); - } - - /** - * get the palette index for the bottom border - * - * - * @return border - palette index - * @see #getAdtlPaletteOptions() - */ - - public short getBottomBorderPaletteIdx() - { - return ( short ) _bottom_border_palette_idx - .getValue(field_8_adtl_palette_options); - } - - /** - * get for diagonal borders? No idea (its a palette color for the other function - * we didn't know what was?) - * - * - * @return diag - the palette index? - * @see #getAdtlPaletteOptions() - */ - - public short getAdtlDiag() - { - return ( short ) _adtl_diag.getValue(field_8_adtl_palette_options); - } - - /** - * get the diagonal border line style? Who the heck ever heard of a diagonal border? - * - * - * @return diag - the line style - * @see #NONE - * @see #THIN - * @see #MEDIUM - * @see #DASHED - * @see #DOTTED - * @see #THICK - * @see #DOUBLE - * @see #HAIR - * @see #MEDIUM_DASHED - * @see #DASH_DOT - * @see #MEDIUM_DASH_DOT - * @see #DASH_DOT_DOT - * @see #MEDIUM_DASH_DOT_DOT - * @see #SLANTED_DASH_DOT - * @see #getAdtlPaletteOptions() - */ - - public short getAdtlDiagLineStyle() - { - return ( short ) _adtl_diag_line_style - .getValue(field_8_adtl_palette_options); - } - - /** - * get the additional fill pattern - * - * @see #NO_FILL - * @see #SOLID_FILL - * @see #FINE_DOTS - * @see #ALT_BARS - * @see #SPARSE_DOTS - * @see #THICK_HORZ_BANDS - * @see #THICK_VERT_BANDS - * @see #THICK_BACKWARD_DIAG - * @see #THICK_FORWARD_DIAG - * @see #BIG_SPOTS - * @see #BRICKS - * @see #THIN_HORZ_BANDS - * @see #THIN_VERT_BANDS - * @see #THIN_BACKWARD_DIAG - * @see #THIN_FORWARD_DIAG - * @see #SQUARES - * @see #DIAMONDS - * - * @return fill - fill pattern?? - * @see #getAdtlPaletteOptions() - */ - - public short getAdtlFillPattern() - { - return ( short ) _adtl_fill_pattern - .getValue(field_8_adtl_palette_options); - } - - // end bitfields for additional palette options - // fill palette options - - /** - * get the fill palette options bitmask (see indivdual bit getters that - * reference this method) - * - * @return options - * - */ - - public short getFillPaletteOptions() - { - return field_9_fill_palette_options; - } - - // bitfields for fill palette options - - /** - * get the foreground palette color index - * - * - * @return color - palette index - * @see #getFillPaletteOptions() - */ - - public short getFillForeground() - { - return _fill_foreground.getShortValue(field_9_fill_palette_options); - } - - /** - * get the background palette color index - * - * @return color palette index - * @see #getFillPaletteOptions() - */ - - public short getFillBackground() - { - return _fill_background.getShortValue(field_9_fill_palette_options); - } - - @Override - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[EXTENDEDFORMAT]\n"); - if (getXFType() == XF_STYLE) - { - buffer.append(" STYLE_RECORD_TYPE\n"); - } - else if (getXFType() == XF_CELL) - { - buffer.append(" CELL_RECORD_TYPE\n"); - } - buffer.append(" .fontindex = ") - .append(Integer.toHexString(getFontIndex())).append("\n"); - buffer.append(" .formatindex = ") - .append(Integer.toHexString(getFormatIndex())).append("\n"); - buffer.append(" .celloptions = ") - .append(Integer.toHexString(getCellOptions())).append("\n"); - buffer.append(" .islocked = ").append(isLocked()) - .append("\n"); - buffer.append(" .ishidden = ").append(isHidden()) - .append("\n"); - buffer.append(" .recordtype= ") - .append(Integer.toHexString(getXFType())).append("\n"); - buffer.append(" .parentidx = ") - .append(Integer.toHexString(getParentIndex())).append("\n"); - buffer.append(" .alignmentoptions= ") - .append(Integer.toHexString(getAlignmentOptions())).append("\n"); - buffer.append(" .alignment = ").append(getAlignment()) - .append("\n"); - buffer.append(" .wraptext = ").append(getWrapText()) - .append("\n"); - buffer.append(" .valignment= ") - .append(Integer.toHexString(getVerticalAlignment())).append("\n"); - buffer.append(" .justlast = ") - .append(Integer.toHexString(getJustifyLast())).append("\n"); - buffer.append(" .rotation = ") - .append(Integer.toHexString(getRotation())).append("\n"); - buffer.append(" .indentionoptions= ") - .append(Integer.toHexString(getIndentionOptions())).append("\n"); - buffer.append(" .indent = ") - .append(Integer.toHexString(getIndent())).append("\n"); - buffer.append(" .shrinktoft= ").append(getShrinkToFit()) - .append("\n"); - buffer.append(" .mergecells= ").append(getMergeCells()) - .append("\n"); - buffer.append(" .readngordr= ") - .append(Integer.toHexString(getReadingOrder())).append("\n"); - buffer.append(" .formatflag= ") - .append(isIndentNotParentFormat()).append("\n"); - buffer.append(" .fontflag = ") - .append(isIndentNotParentFont()).append("\n"); - buffer.append(" .prntalgnmt= ") - .append(isIndentNotParentAlignment()).append("\n"); - buffer.append(" .borderflag= ") - .append(isIndentNotParentBorder()).append("\n"); - buffer.append(" .paternflag= ") - .append(isIndentNotParentPattern()).append("\n"); - buffer.append(" .celloption= ") - .append(isIndentNotParentCellOptions()).append("\n"); - buffer.append(" .borderoptns = ") - .append(Integer.toHexString(getBorderOptions())).append("\n"); - buffer.append(" .lftln = ") - .append(Integer.toHexString(getBorderLeft())).append("\n"); - buffer.append(" .rgtln = ") - .append(Integer.toHexString(getBorderRight())).append("\n"); - buffer.append(" .topln = ") - .append(Integer.toHexString(getBorderTop())).append("\n"); - buffer.append(" .btmln = ") - .append(Integer.toHexString(getBorderBottom())).append("\n"); - buffer.append(" .paleteoptns = ") - .append(Integer.toHexString(getPaletteOptions())).append("\n"); - buffer.append(" .leftborder= ") - .append(Integer.toHexString(getLeftBorderPaletteIdx())) - .append("\n"); - buffer.append(" .rghtborder= ") - .append(Integer.toHexString(getRightBorderPaletteIdx())) - .append("\n"); - buffer.append(" .diag = ") - .append(Integer.toHexString(getDiag())).append("\n"); - buffer.append(" .paleteoptn2 = ") - .append(Integer.toHexString(getAdtlPaletteOptions())) - .append("\n"); - buffer.append(" .topborder = ") - .append(Integer.toHexString(getTopBorderPaletteIdx())) - .append("\n"); - buffer.append(" .botmborder= ") - .append(Integer.toHexString(getBottomBorderPaletteIdx())) - .append("\n"); - buffer.append(" .adtldiag = ") - .append(Integer.toHexString(getAdtlDiag())).append("\n"); - buffer.append(" .diaglnstyl= ") - .append(Integer.toHexString(getAdtlDiagLineStyle())).append("\n"); - buffer.append(" .fillpattrn= ") - .append(Integer.toHexString(getAdtlFillPattern())).append("\n"); - buffer.append(" .fillpaloptn = ") - .append(Integer.toHexString(getFillPaletteOptions())) - .append("\n"); - buffer.append(" .foreground= ") - .append(Integer.toHexString(getFillForeground())).append("\n"); - buffer.append(" .background= ") - .append(Integer.toHexString(getFillBackground())).append("\n"); - buffer.append("[/EXTENDEDFORMAT]\n"); - return buffer.toString(); - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(getFontIndex()); - out.writeShort(getFormatIndex()); - out.writeShort(getCellOptions()); - out.writeShort(getAlignmentOptions()); - out.writeShort(getIndentionOptions()); - out.writeShort(getBorderOptions()); - out.writeShort(getPaletteOptions()); - out.writeInt(getAdtlPaletteOptions()); - out.writeShort(getFillPaletteOptions()); - } - - @Override - protected int getDataSize() { - return 20; - } - - @Override - public short getSid() - { - return sid; - } - - /** - * Clones all the style information from another - * ExtendedFormatRecord, onto this one. This - * will then hold all the same style options. - * - * If The source ExtendedFormatRecord comes from - * a different Workbook, you will need to sort - * out the font and format indices yourself! - * - * @param source the ExtendedFormatRecord to copy from - */ - public void cloneStyleFrom(ExtendedFormatRecord source) { - field_1_font_index = source.field_1_font_index; - field_2_format_index = source.field_2_format_index; - field_3_cell_options = source.field_3_cell_options; - field_4_alignment_options = source.field_4_alignment_options; - field_5_indention_options = source.field_5_indention_options; - field_6_border_options = source.field_6_border_options; - field_7_palette_options = source.field_7_palette_options; - field_8_adtl_palette_options = source.field_8_adtl_palette_options; - field_9_fill_palette_options = source.field_9_fill_palette_options; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + field_1_font_index; - result = prime * result + field_2_format_index; - result = prime * result + field_3_cell_options; - result = prime * result + field_4_alignment_options; - result = prime * result + field_5_indention_options; - result = prime * result + field_6_border_options; - result = prime * result + field_7_palette_options; - result = prime * result + field_8_adtl_palette_options; - result = prime * result + field_9_fill_palette_options; - return result; - } - - /** - * Will consider two different records with the same - * contents as equals, as the various indexes - * that matter are embedded in the records - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (obj instanceof ExtendedFormatRecord) { - final ExtendedFormatRecord other = (ExtendedFormatRecord) obj; - if (field_1_font_index != other.field_1_font_index) - return false; - if (field_2_format_index != other.field_2_format_index) - return false; - if (field_3_cell_options != other.field_3_cell_options) - return false; - if (field_4_alignment_options != other.field_4_alignment_options) - return false; - if (field_5_indention_options != other.field_5_indention_options) - return false; - if (field_6_border_options != other.field_6_border_options) - return false; - if (field_7_palette_options != other.field_7_palette_options) - return false; - if (field_8_adtl_palette_options != other.field_8_adtl_palette_options) - return false; - if (field_9_fill_palette_options != other.field_9_fill_palette_options) - return false; - return true; - } - return false; - } - - public int[] stateSummary() { - return new int[] { field_1_font_index, field_2_format_index, field_3_cell_options, field_4_alignment_options, - field_5_indention_options, field_6_border_options, field_7_palette_options, field_8_adtl_palette_options, field_9_fill_palette_options }; - } - - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java deleted file mode 100644 index 343c1498e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java +++ /dev/null @@ -1,304 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * EXTERNSHEET (0x0017)

    - * A List of Indexes to EXTERNALBOOK (supplemental book) Records - */ -public class ExternSheetRecord extends StandardRecord { - - public final static short sid = 0x0017; - private final List _list; - - private static final class RefSubRecord { - public static final int ENCODED_SIZE = 6; - - /** index to External Book Block (which starts with a EXTERNALBOOK record) */ - private final int _extBookIndex; - private int _firstSheetIndex; // may be -1 (0xFFFF) - private int _lastSheetIndex; // may be -1 (0xFFFF) - - public void adjustIndex(int offset) { - _firstSheetIndex += offset; - _lastSheetIndex += offset; - } - - /** a Constructor for making new sub record - */ - public RefSubRecord(int extBookIndex, int firstSheetIndex, int lastSheetIndex) { - _extBookIndex = extBookIndex; - _firstSheetIndex = firstSheetIndex; - _lastSheetIndex = lastSheetIndex; - } - - /** - * @param in the RecordInputstream to read the record from - */ - public RefSubRecord(RecordInputStream in) { - this(in.readShort(), in.readShort(), in.readShort()); - } - public int getExtBookIndex(){ - return _extBookIndex; - } - public int getFirstSheetIndex(){ - return _firstSheetIndex; - } - public int getLastSheetIndex(){ - return _lastSheetIndex; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("extBook=").append(_extBookIndex); - buffer.append(" firstSheet=").append(_firstSheetIndex); - buffer.append(" lastSheet=").append(_lastSheetIndex); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_extBookIndex); - out.writeShort(_firstSheetIndex); - out.writeShort(_lastSheetIndex); - } - } - - - - public ExternSheetRecord() { - _list = new ArrayList(); - } - - public ExternSheetRecord(RecordInputStream in) { - _list = new ArrayList(); - - int nItems = in.readShort(); - - for (int i = 0 ; i < nItems ; ++i) { - RefSubRecord rec = new RefSubRecord(in); - _list.add(rec); - } - } - - - /** - * @return number of REF structures - */ - public int getNumOfRefs() { - return _list.size(); - } - - /** - * adds REF struct (ExternSheetSubRecord) - * @param rec REF struct - */ - public void addREFRecord(RefSubRecord rec) { - _list.add(rec); - } - - /** returns the number of REF Records, which is in model - * @return number of REF records - */ - public int getNumOfREFRecords() { - return _list.size(); - } - - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - int nItems = _list.size(); - sb.append("[EXTERNSHEET]\n"); - sb.append(" numOfRefs = ").append(nItems).append("\n"); - for (int i=0; i < nItems; i++) { - sb.append("refrec #").append(i).append(": "); - sb.append(getRef(i).toString()); - sb.append('\n'); - } - sb.append("[/EXTERNSHEET]\n"); - - - return sb.toString(); - } - - @Override - protected int getDataSize() { - return 2 + _list.size() * RefSubRecord.ENCODED_SIZE; - } - - @Override - public void serialize(LittleEndianOutput out) { - int nItems = _list.size(); - - out.writeShort(nItems); - - for (int i = 0; i < nItems; i++) { - getRef(i).serialize(out); - } - } - - private RefSubRecord getRef(int i) { - return _list.get(i); - } - - public void removeSheet(int sheetIdx) { - int nItems = _list.size(); - for (int i = 0; i < nItems; i++) { - RefSubRecord refSubRecord = _list.get(i); - if(refSubRecord.getFirstSheetIndex() == sheetIdx && - refSubRecord.getLastSheetIndex() == sheetIdx) { - // removing the entry would mess up the sheet index in Formula of NameRecord - _list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), -1, -1)); - } else if (refSubRecord.getFirstSheetIndex() > sheetIdx && - refSubRecord.getLastSheetIndex() > sheetIdx) { - _list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), refSubRecord.getFirstSheetIndex()-1, refSubRecord.getLastSheetIndex()-1)); - } - } - } - - /** - * return the non static version of the id for this record. - */ - @Override - public short getSid() { - return sid; - } - - /** - * @param refIndex specifies the n-th refIndex - * - * @return the index of the SupBookRecord for this index - */ - public int getExtbookIndexFromRefIndex(int refIndex) { - RefSubRecord refRec = getRef(refIndex); - return refRec.getExtBookIndex(); - } - - /** - * @param extBookIndex external sheet reference index - * - * @return -1 if not found - */ - public int findRefIndexFromExtBookIndex(int extBookIndex) { - int nItems = _list.size(); - for (int i = 0; i < nItems; i++) { - if (getRef(i).getExtBookIndex() == extBookIndex) { - return i; - } - } - return -1; - } - - /** - * Returns the first sheet that the reference applies to, or - * -1 if the referenced sheet can't be found, or -2 if the - * reference is workbook scoped. - * - * @param extRefIndex external sheet reference index - * - * @return the first sheet that the reference applies to, or - * -1 if the referenced sheet can't be found, or -2 if the - * reference is workbook scoped - */ - public int getFirstSheetIndexFromRefIndex(int extRefIndex) { - return getRef(extRefIndex).getFirstSheetIndex(); - } - - /** - * Returns the last sheet that the reference applies to, or - * -1 if the referenced sheet can't be found, or -2 if the - * reference is workbook scoped. - * For a single sheet reference, the first and last should be - * the same. - * - * @param extRefIndex external sheet reference index - * - * @return the last sheet that the reference applies to, or - * -1 if the referenced sheet can't be found, or -2 if the - * reference is workbook scoped. - */ - public int getLastSheetIndexFromRefIndex(int extRefIndex) { - return getRef(extRefIndex).getLastSheetIndex(); - } - - /** - * Add a zero-based reference to a {@link org.apache.poi.hssf.record.SupBookRecord}. - *

    - * If the type of the SupBook record is same-sheet referencing, Add-In referencing, - * DDE data source referencing, or OLE data source referencing, - * then no scope is specified and this value MUST be -2. Otherwise, - * the scope must be set as follows: - *

      - *
    1. -2 Workbook-level reference that applies to the entire workbook.
    2. - *
    3. -1 Sheet-level reference.
    4. - *
    5. >=0 Sheet-level reference. This specifies the first sheet in the reference. - *

      If the SupBook type is unused or external workbook referencing, - * then this value specifies the zero-based index of an external sheet name, - * see {@link org.apache.poi.hssf.record.SupBookRecord#getSheetNames()}. - * This referenced string specifies the name of the first sheet within the external workbook that is in scope. - * This sheet MUST be a worksheet or macro sheet.

      - * - *

      If the supporting link type is self-referencing, then this value specifies the zero-based index of a - * {@link org.apache.poi.hssf.record.BoundSheetRecord} record in the workbook stream that specifies - * the first sheet within the scope of this reference. This sheet MUST be a worksheet or a macro sheet. - *

      - *
    6. - *
    - * - * @param extBookIndex the external book block index - * @param firstSheetIndex the scope, must be -2 for add-in references - * @param lastSheetIndex the scope, must be -2 for add-in references - * @return index of newly added ref - */ - public int addRef(int extBookIndex, int firstSheetIndex, int lastSheetIndex) { - _list.add(new RefSubRecord(extBookIndex, firstSheetIndex, lastSheetIndex)); - return _list.size() - 1; - } - - public int getRefIxForSheet(int externalBookIndex, int firstSheetIndex, int lastSheetIndex) { - int nItems = _list.size(); - for (int i = 0; i < nItems; i++) { - RefSubRecord ref = getRef(i); - if (ref.getExtBookIndex() != externalBookIndex) { - continue; - } - if (ref.getFirstSheetIndex() == firstSheetIndex && - ref.getLastSheetIndex() == lastSheetIndex) { - return i; - } - } - return -1; - } - - public static ExternSheetRecord combine(ExternSheetRecord[] esrs) { - ExternSheetRecord result = new ExternSheetRecord(); - for (ExternSheetRecord esr : esrs) { - int nRefs = esr.getNumOfREFRecords(); - for (int j=0; j - * Logically this is a 2-D array, which has been flattened into 1-D array here. - */ - private Object[] _ddeValues; - /** - * (logical) number of columns in the {@link #_ddeValues} array - */ - private int _nColumns; - /** - * (logical) number of rows in the {@link #_ddeValues} array - */ - private int _nRows; - - /** - * @return {@code true} if the name is a built-in name - */ - public boolean isBuiltInName() { - return (field_1_option_flag & OPT_BUILTIN_NAME) != 0; - } - /** - * For OLE and DDE, links can be either 'automatic' or 'manual' - * - * @return {@code true} if this is a automatic link - */ - public boolean isAutomaticLink() { - return (field_1_option_flag & OPT_AUTOMATIC_LINK) != 0; - } - /** - * only for OLE and DDE - * - * @return {@code true} if this is a picture link - */ - public boolean isPicureLink() { - return (field_1_option_flag & OPT_PICTURE_LINK) != 0; - } - /** - * DDE links only. If true, this denotes the 'StdDocumentName' - * - * @return {@code true} if this denotes the 'StdDocumentName' - */ - public boolean isStdDocumentNameIdentifier() { - return (field_1_option_flag & OPT_STD_DOCUMENT_NAME) != 0; - } - public boolean isOLELink() { - return (field_1_option_flag & OPT_OLE_LINK) != 0; - } - public boolean isIconifiedPictureLink() { - return (field_1_option_flag & OPT_ICONIFIED_PICTURE_LINK) != 0; - } - /** - * @return the standard String representation of this name - */ - public String getText() { - return field_4_name; - } - - public void setText(String str) { - field_4_name = str; - } - - /** - * If this is a local name, then this is the (1 based) - * index of the name of the Sheet this refers to, as - * defined in the preceding {@link SupBookRecord}. - * If it isn't a local name, then it must be zero. - * - * @return the index of the name of the Sheet this refers to - */ - public short getIx() { - return field_2_ixals; - } - - public void setIx(short ix) { - field_2_ixals = ix; - } - - public Ptg[] getParsedExpression() { - return Formula.getTokens(field_5_name_definition); - } - public void setParsedExpression(Ptg[] ptgs) { - field_5_name_definition = Formula.create(ptgs); - } - - - @Override - protected int getDataSize(){ - int result = 2 + 4; // short and int - result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, not short - - if(!isOLELink() && !isStdDocumentNameIdentifier()){ - if(isAutomaticLink()){ - if(_ddeValues != null) { - result += 3; // byte, short - result += ConstantValueParser.getEncodedSize(_ddeValues); - } - } else { - result += field_5_name_definition.getEncodedSize(); - } - } - return result; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_option_flag); - out.writeShort(field_2_ixals); - out.writeShort(field_3_not_used); - - out.writeByte(field_4_name.length()); - StringUtil.writeUnicodeStringFlagAndData(out, field_4_name); - - if(!isOLELink() && !isStdDocumentNameIdentifier()){ - if(isAutomaticLink()){ - if(_ddeValues != null) { - out.writeByte(_nColumns-1); - out.writeShort(_nRows-1); - ConstantValueParser.encode(out, _ddeValues); - } - } else { - field_5_name_definition.serialize(out); - } - } - } - - public ExternalNameRecord() { - field_2_ixals = 0; - } - - public ExternalNameRecord(RecordInputStream in) { - field_1_option_flag = in.readShort(); - field_2_ixals = in.readShort(); - field_3_not_used = in.readShort(); - - int numChars = in.readUByte(); - field_4_name = StringUtil.readUnicodeString(in, numChars); - - // the record body can take different forms. - // The form is dictated by the values of 3-th and 4-th bits in field_1_option_flag - if(!isOLELink() && !isStdDocumentNameIdentifier()){ - // another switch: the fWantAdvise bit specifies whether the body describes - // an external defined name or a DDE data item - if(isAutomaticLink()){ - if(in.available() > 0) { - //body specifies DDE data item - int nColumns = in.readUByte() + 1; - int nRows = in.readShort() + 1; - - int totalCount = nRows * nColumns; - _ddeValues = ConstantValueParser.parse(in, totalCount); - _nColumns = nColumns; - _nRows = nRows; - } - } else { - //body specifies an external defined name - int formulaLen = in.readUShort(); - field_5_name_definition = Formula.read(formulaLen, in); - } - } - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("[EXTERNALNAME]\n"); - sb.append(" .options = ").append(field_1_option_flag).append("\n"); - sb.append(" .ix = ").append(field_2_ixals).append("\n"); - sb.append(" .name = ").append(field_4_name).append("\n"); - if(field_5_name_definition != null) { - Ptg[] ptgs = field_5_name_definition.getTokens(); - for (Ptg ptg : ptgs) { - sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n"); - } - } - sb.append("[/EXTERNALNAME]\n"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java deleted file mode 100644 index d12bc8b12..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.common.FtrHeader; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: FeatHdr (Feature Header) Record - *

    - * This record specifies common information for Shared Features, and - * specifies the beginning of a collection of records to define them. - * The collection of data (Globals Substream ABNF, macro sheet substream - * ABNF or worksheet substream ABNF) specifies Shared Feature data. - */ -public final class FeatHdrRecord extends StandardRecord implements Cloneable { - /** - * Specifies the enhanced protection type. Used to protect a - * shared workbook by restricting access to some areas of it - */ - public static final int SHAREDFEATURES_ISFPROTECTION = 0x02; - /** - * Specifies that formula errors should be ignored - */ - public static final int SHAREDFEATURES_ISFFEC2 = 0x03; - /** - * Specifies the smart tag type. Recognises certain - * types of entries (proper names, dates/times etc) and - * flags them for action - */ - public static final int SHAREDFEATURES_ISFFACTOID = 0x04; - /** - * Specifies the shared list type. Used for a table - * within a sheet - */ - public static final int SHAREDFEATURES_ISFLIST = 0x05; - - - public final static short sid = 0x0867; - - private FtrHeader futureHeader; - private int isf_sharedFeatureType; // See SHAREDFEATURES_ - private byte reserved; // Should always be one - /** - * 0x00000000 = rgbHdrData not present - * 0xffffffff = rgbHdrData present - */ - private long cbHdrData; - /** We need a BOFRecord to make sense of this... */ - private byte[] rgbHdrData; - - public FeatHdrRecord() { - futureHeader = new FtrHeader(); - futureHeader.setRecordType(sid); - } - - public short getSid() { - return sid; - } - - public FeatHdrRecord(RecordInputStream in) { - futureHeader = new FtrHeader(in); - - isf_sharedFeatureType = in.readShort(); - reserved = in.readByte(); - cbHdrData = in.readInt(); - // Don't process this just yet, need the BOFRecord - rgbHdrData = in.readRemainder(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[FEATURE HEADER]\n"); - - // TODO ... - - buffer.append("[/FEATURE HEADER]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - futureHeader.serialize(out); - - out.writeShort(isf_sharedFeatureType); - out.writeByte(reserved); - out.writeInt((int)cbHdrData); - out.write(rgbHdrData); - } - - protected int getDataSize() { - return 12 + 2+1+4+rgbHdrData.length; - } - - @Override - public FeatHdrRecord clone() { - //HACK: do a "cheat" clone, see Record.java for more information - return (FeatHdrRecord)cloneViaReserialise(); - } - - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java deleted file mode 100644 index 404fc24c5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java +++ /dev/null @@ -1,185 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.common.FeatFormulaErr2; -import org.apache.poi.hssf.record.common.FeatProtection; -import org.apache.poi.hssf.record.common.FeatSmartTag; -import org.apache.poi.hssf.record.common.FtrHeader; -import org.apache.poi.hssf.record.common.SharedFeature; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Title: Feat (Feature) Record - *

    - * This record specifies Shared Features data. It is normally paired - * up with a {@link FeatHdrRecord}. - */ -public final class FeatRecord extends StandardRecord implements Cloneable { - private static POILogger logger = POILogFactory.getLogger(FeatRecord.class); - public final static short sid = 0x0868; - // SIDs from newer versions - public final static short v11_sid = 0x0872; - public final static short v12_sid = 0x0878; - - private FtrHeader futureHeader; - - /** - * See SHAREDFEATURES_* on {@link FeatHdrRecord} - */ - private int isf_sharedFeatureType; - private byte reserved1; // Should always be zero - private long reserved2; // Should always be zero - /** Only matters if type is ISFFEC2 */ - private long cbFeatData; - private int reserved3; // Should always be zero - private CellRangeAddress[] cellRefs; - - /** - * Contents depends on isf_sharedFeatureType : - * ISFPROTECTION -> FeatProtection - * ISFFEC2 -> FeatFormulaErr2 - * ISFFACTOID -> FeatSmartTag - */ - private SharedFeature sharedFeature; - - public FeatRecord() { - futureHeader = new FtrHeader(); - futureHeader.setRecordType(sid); - } - - public short getSid() { - return sid; - } - - public FeatRecord(RecordInputStream in) { - futureHeader = new FtrHeader(in); - - isf_sharedFeatureType = in.readShort(); - reserved1 = in.readByte(); - reserved2 = in.readInt(); - int cref = in.readUShort(); - cbFeatData = in.readInt(); - reserved3 = in.readShort(); - - cellRefs = new CellRangeAddress[cref]; - for(int i=0; i - * - * Description: Indicates that the record after this record are encrypted. - */ -public final class FilePassRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x002F; - private static final int ENCRYPTION_XOR = 0; - private static final int ENCRYPTION_OTHER = 1; - - private final int encryptionType; - private EncryptionInfo encryptionInfo; - - private FilePassRecord(FilePassRecord other) { - encryptionType = other.encryptionType; - try { - encryptionInfo = other.encryptionInfo.clone(); - } catch (CloneNotSupportedException e) { - throw new EncryptedDocumentException(e); - } - } - - public FilePassRecord(EncryptionMode encryptionMode) { - encryptionType = (encryptionMode == EncryptionMode.xor) ? ENCRYPTION_XOR : ENCRYPTION_OTHER; - encryptionInfo = new EncryptionInfo(encryptionMode); - } - - public FilePassRecord(RecordInputStream in) { - encryptionType = in.readUShort(); - - EncryptionMode preferredMode; - switch (encryptionType) { - case ENCRYPTION_XOR: - preferredMode = EncryptionMode.xor; - break; - case ENCRYPTION_OTHER: - preferredMode = EncryptionMode.cryptoAPI; - break; - default: - throw new EncryptedDocumentException("invalid encryption type"); - } - - try { - encryptionInfo = new EncryptionInfo(in, preferredMode); - } catch (IOException e) { - throw new EncryptedDocumentException(e); - } - } - - @SuppressWarnings("resource") - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(encryptionType); - - byte data[] = new byte[1024]; - LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(data, 0); - - switch (encryptionInfo.getEncryptionMode()) { - case xor: - ((XOREncryptionHeader)encryptionInfo.getHeader()).write(bos); - ((XOREncryptionVerifier)encryptionInfo.getVerifier()).write(bos); - break; - case binaryRC4: - out.writeShort(encryptionInfo.getVersionMajor()); - out.writeShort(encryptionInfo.getVersionMinor()); - ((BinaryRC4EncryptionHeader)encryptionInfo.getHeader()).write(bos); - ((BinaryRC4EncryptionVerifier)encryptionInfo.getVerifier()).write(bos); - break; - case cryptoAPI: - out.writeShort(encryptionInfo.getVersionMajor()); - out.writeShort(encryptionInfo.getVersionMinor()); - out.writeInt(encryptionInfo.getEncryptionFlags()); - ((CryptoAPIEncryptionHeader)encryptionInfo.getHeader()).write(bos); - ((CryptoAPIEncryptionVerifier)encryptionInfo.getVerifier()).write(bos); - break; - default: - throw new EncryptedDocumentException("not supported"); - } - - out.write(data, 0, bos.getWriteIndex()); - } - - @Override - protected int getDataSize() { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - LittleEndianOutputStream leos = new LittleEndianOutputStream(bos); - serialize(leos); - return bos.size(); - } - - public EncryptionInfo getEncryptionInfo() { - return encryptionInfo; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public FilePassRecord clone() { - return new FilePassRecord(this); - } - - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(); - - buffer.append("[FILEPASS]\n"); - buffer.append(" .type = ").append(HexDump.shortToHex(encryptionType)).append('\n'); - String prefix = " ."+encryptionInfo.getEncryptionMode(); - buffer.append(prefix+".info = ").append(HexDump.shortToHex(encryptionInfo.getVersionMajor())).append('\n'); - buffer.append(prefix+".ver = ").append(HexDump.shortToHex(encryptionInfo.getVersionMinor())).append('\n'); - buffer.append(prefix+".salt = ").append(HexDump.toHex(encryptionInfo.getVerifier().getSalt())).append('\n'); - buffer.append(prefix+".verifier = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifier())).append('\n'); - buffer.append(prefix+".verifierHash = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifierHash())).append('\n'); - buffer.append("[/FILEPASS]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java deleted file mode 100644 index f2698a390..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java +++ /dev/null @@ -1,147 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: FILESHARING (0x005B)

    - * Description: stores the encrypted readonly for a workbook (write protect) - * This functionality is accessed from the options dialog box available when performing 'Save As'.

    - * REFERENCE: PG 314 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class FileSharingRecord extends StandardRecord implements Cloneable { - - public final static short sid = 0x005B; - private short field_1_readonly; - private short field_2_password; - private byte field_3_username_unicode_options; - private String field_3_username_value; - - public FileSharingRecord() {} - - public FileSharingRecord(RecordInputStream in) { - field_1_readonly = in.readShort(); - field_2_password = in.readShort(); - - int nameLen = in.readShort(); - - if(nameLen > 0) { - // TODO - Current examples(3) from junits only have zero length username. - field_3_username_unicode_options = in.readByte(); - field_3_username_value = in.readCompressedUnicode(nameLen); - } else { - field_3_username_value = ""; - } - } - - /** - * set the readonly flag - * - * @param readonly 1 for true, not 1 for false - */ - public void setReadOnly(short readonly) { - field_1_readonly = readonly; - } - - /** - * get the readonly - * - * @return short representing if this is read only (1 = true) - */ - public short getReadOnly() { - return field_1_readonly; - } - - /** - * @param password hashed password - */ - public void setPassword(short password) { - field_2_password = password; - } - - /** - * @return password hashed with hashPassword() (very lame) - */ - public short getPassword() { - return field_2_password; - } - - - /** - * @return username of the user that created the file - */ - public String getUsername() { - return field_3_username_value; - } - - /** - * @param username of the user that created the file - */ - public void setUsername(String username) { - field_3_username_value = username; - } - - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FILESHARING]\n"); - buffer.append(" .readonly = ") - .append(getReadOnly() == 1 ? "true" : "false").append("\n"); - buffer.append(" .password = ") - .append(Integer.toHexString(getPassword())).append("\n"); - buffer.append(" .username = ") - .append(getUsername()).append("\n"); - buffer.append("[/FILESHARING]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - // TODO - junit - out.writeShort(getReadOnly()); - out.writeShort(getPassword()); - out.writeShort(field_3_username_value.length()); - if(field_3_username_value.length() > 0) { - out.writeByte(field_3_username_unicode_options); - StringUtil.putCompressedUnicode(getUsername(), out); - } - } - - protected int getDataSize() { - int nameLen = field_3_username_value.length(); - if (nameLen < 1) { - return 6; - } - return 7+nameLen; - } - - public short getSid() { - return sid; - } - - @Override - public FileSharingRecord clone() { - FileSharingRecord clone = new FileSharingRecord(); - clone.setReadOnly(field_1_readonly); - clone.setPassword(field_2_password); - clone.setUsername(field_3_username_value); - return clone; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java deleted file mode 100644 index 5d70aeb7e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java +++ /dev/null @@ -1,99 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Function Group Count Record

    - * Description: Number of built in function groups in the current version of the - * Spreadsheet (probably only used on Windoze)

    - * REFERENCE: PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class FnGroupCountRecord - extends StandardRecord -{ - public final static short sid = 0x9c; - - /** - * suggested default (14 dec) - */ - - public final static short COUNT = 14; - private short field_1_count; - - public FnGroupCountRecord() - { - } - - public FnGroupCountRecord(RecordInputStream in) - { - field_1_count = in.readShort(); - } - - /** - * set the number of built-in functions - * - * @param count - number of functions - */ - - public void setCount(short count) - { - field_1_count = count; - } - - /** - * get the number of built-in functions - * - * @return number of built-in functions - */ - - public short getCount() - { - return field_1_count; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FNGROUPCOUNT]\n"); - buffer.append(" .count = ").append(getCount()) - .append("\n"); - buffer.append("[/FNGROUPCOUNT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getCount()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java deleted file mode 100644 index 03efd8403..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java +++ /dev/null @@ -1,494 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: Font Record (0x0031)

    - * - describes a font in the workbook (index = 0-3,5-infinity - skip 4)

    - * Description: An element in the Font Table

    - * REFERENCE: PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class FontRecord extends StandardRecord { - public final static short sid = 0x0031; // docs are wrong (0x231 Microsoft Support site article Q184647) - public final static short SS_NONE = 0; - public final static short SS_SUPER = 1; - public final static short SS_SUB = 2; - public final static byte U_NONE = 0; - public final static byte U_SINGLE = 1; - public final static byte U_DOUBLE = 2; - public final static byte U_SINGLE_ACCOUNTING = 0x21; - public final static byte U_DOUBLE_ACCOUNTING = 0x22; - private short field_1_font_height; // in units of .05 of a point - private short field_2_attributes; - - // 0 0x01 - Reserved bit must be 0 - private static final BitField italic = BitFieldFactory.getInstance(0x02); // is this font in italics - - // 2 0x04 - reserved bit must be 0 - private static final BitField strikeout =BitFieldFactory.getInstance(0x08); // is this font has a line through the center - private static final BitField macoutline = BitFieldFactory.getInstance(0x10); // some weird macintosh thing....but who understands those mac people anyhow - private static final BitField macshadow = BitFieldFactory.getInstance(0x20); // some weird macintosh thing....but who understands those mac people anyhow - - // 7-6 - reserved bits must be 0 - // the rest is unused - private short field_3_color_palette_index; - private short field_4_bold_weight; - private short field_5_super_sub_script; // 00none/01super/02sub - private byte field_6_underline; // 00none/01single/02double/21singleaccounting/22doubleaccounting - private byte field_7_family; // ?? defined by windows api logfont structure? - private byte field_8_charset; // ?? defined by windows api logfont structure? - private byte field_9_zero = 0; // must be 0 - /** possibly empty string never null */ - private String field_11_font_name; - - public FontRecord() { - } - - public FontRecord(RecordInputStream in) { - field_1_font_height = in.readShort(); - field_2_attributes = in.readShort(); - field_3_color_palette_index = in.readShort(); - field_4_bold_weight = in.readShort(); - field_5_super_sub_script = in.readShort(); - field_6_underline = in.readByte(); - field_7_family = in.readByte(); - field_8_charset = in.readByte(); - field_9_zero = in.readByte(); - int field_10_font_name_len = in.readUByte(); - int unicodeFlags = in.readUByte(); // options byte present always (even if no character data) - - if (field_10_font_name_len > 0) { - if (unicodeFlags == 0) { // is compressed unicode - field_11_font_name = in.readCompressedUnicode(field_10_font_name_len); - } else { // is not compressed unicode - field_11_font_name = in.readUnicodeLEString(field_10_font_name_len); - } - } else { - field_11_font_name = ""; - } - } - - /** - * sets the height of the font in 1/20th point units - * - * @param height fontheight (in points/20) - */ - public void setFontHeight(short height) { - field_1_font_height = height; - } - - /** - * set the font attributes (see individual bit setters that reference this method) - * - * @param attributes the bitmask to set - */ - public void setAttributes(short attributes) { - field_2_attributes = attributes; - } - - // attributes bitfields - - /** - * set the font to be italics or not - * - * @param italics - whether the font is italics or not - * @see #setAttributes(short) - */ - public void setItalic(boolean italics) { - field_2_attributes = italic.setShortBoolean(field_2_attributes, italics); - } - - /** - * set the font to be stricken out or not - * - * @param strike - whether the font is stricken out or not - * @see #setAttributes(short) - */ - public void setStrikeout(boolean strike) { - field_2_attributes = strikeout.setShortBoolean(field_2_attributes, strike); - } - - /** - * whether to use the mac outline font style thing (mac only) - Some mac person - * should comment this instead of me doing it (since I have no idea) - * - * @param mac - whether to do that mac font outline thing or not - * @see #setAttributes(short) - */ - public void setMacoutline(boolean mac) { - field_2_attributes = macoutline.setShortBoolean(field_2_attributes, mac); - } - - /** - * whether to use the mac shado font style thing (mac only) - Some mac person - * should comment this instead of me doing it (since I have no idea) - * - * @param mac - whether to do that mac font shadow thing or not - * @see #setAttributes(short) - */ - public void setMacshadow(boolean mac) { - field_2_attributes = macshadow.setShortBoolean(field_2_attributes, mac); - } - - /** - * set the font's color palette index - * - * @param cpi - font color index - */ - public void setColorPaletteIndex(short cpi) { - field_3_color_palette_index = cpi; - } - - /** - * set the bold weight for this font (100-1000dec or 0x64-0x3e8). Default is - * 0x190 for normal and 0x2bc for bold - * - * @param bw - a number between 100-1000 for the fonts "boldness" - */ - public void setBoldWeight(short bw) { - field_4_bold_weight = bw; - } - - /** - * set the type of super or subscript for the font - * - * @param sss super or subscript option - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - public void setSuperSubScript(short sss) { - field_5_super_sub_script = sss; - } - - /** - * set the type of underlining for the font - * - * @param u super or subscript option - * - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - public void setUnderline(byte u) { - field_6_underline = u; - } - - /** - * set the font family (TODO) - * - * @param f family - */ - public void setFamily(byte f) { - field_7_family = f; - } - - /** - * set the character set - * - * @param charset - character set - */ - public void setCharset(byte charset) { - field_8_charset = charset; - } - - - /** - * set the name of the font - * - * @param fn - name of the font (i.e. "Arial") - */ - public void setFontName(String fn) { - field_11_font_name = fn; - } - - /** - * gets the height of the font in 1/20th point units - * - * @return fontheight (in points/20) - */ - public short getFontHeight() { - return field_1_font_height; - } - - /** - * get the font attributes (see individual bit getters that reference this method) - * - * @return attribute - the bitmask - */ - public short getAttributes() { - return field_2_attributes; - } - - /** - * get whether the font is to be italics or not - * - * @return italics - whether the font is italics or not - * @see #getAttributes() - */ - public boolean isItalic() { - return italic.isSet(field_2_attributes); - } - - /** - * get whether the font is to be stricken out or not - * - * @return strike - whether the font is stricken out or not - * @see #getAttributes() - */ - public boolean isStruckout(){ - return strikeout.isSet(field_2_attributes); - } - - /** - * whether to use the mac outline font style thing (mac only) - Some mac person - * should comment this instead of me doing it (since I have no idea) - * - * @return mac - whether to do that mac font outline thing or not - * @see #getAttributes() - */ - public boolean isMacoutlined(){ - return macoutline.isSet(field_2_attributes); - } - - /** - * whether to use the mac shado font style thing (mac only) - Some mac person - * should comment this instead of me doing it (since I have no idea) - * - * @return mac - whether to do that mac font shadow thing or not - * @see #getAttributes() - */ - public boolean isMacshadowed(){ - return macshadow.isSet(field_2_attributes); - } - - /** - * get the font's color palette index - * - * @return cpi - font color index - */ - public short getColorPaletteIndex(){ - return field_3_color_palette_index; - } - - /** - * get the bold weight for this font (100-1000dec or 0x64-0x3e8). Default is - * 0x190 for normal and 0x2bc for bold - * - * @return bw - a number between 100-1000 for the fonts "boldness" - */ - public short getBoldWeight(){ - return field_4_bold_weight; - } - - /** - * get the type of super or subscript for the font - * - * @return super or subscript option - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - public short getSuperSubScript(){ - return field_5_super_sub_script; - } - - /** - * get the type of underlining for the font - * - * @return super or subscript option - * - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - public byte getUnderline() { - return field_6_underline; - } - - /** - * get the font family (TODO) - * - * @return family - */ - public byte getFamily() { - return field_7_family; - } - - /** - * get the character set - * - * @return charset - character set - */ - public byte getCharset() { - return field_8_charset; - } - - /** - * get the name of the font - * - * @return fn - name of the font (i.e. "Arial") - */ - public String getFontName() { - return field_11_font_name; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[FONT]\n"); - sb.append(" .fontheight = ").append(HexDump.shortToHex(getFontHeight())).append("\n"); - sb.append(" .attributes = ").append(HexDump.shortToHex(getAttributes())).append("\n"); - sb.append(" .italic = ").append(isItalic()).append("\n"); - sb.append(" .strikout = ").append(isStruckout()).append("\n"); - sb.append(" .macoutlined= ").append(isMacoutlined()).append("\n"); - sb.append(" .macshadowed= ").append(isMacshadowed()).append("\n"); - sb.append(" .colorpalette = ").append(HexDump.shortToHex(getColorPaletteIndex())).append("\n"); - sb.append(" .boldweight = ").append(HexDump.shortToHex(getBoldWeight())).append("\n"); - sb.append(" .supersubscript= ").append(HexDump.shortToHex(getSuperSubScript())).append("\n"); - sb.append(" .underline = ").append(HexDump.byteToHex(getUnderline())).append("\n"); - sb.append(" .family = ").append(HexDump.byteToHex(getFamily())).append("\n"); - sb.append(" .charset = ").append(HexDump.byteToHex(getCharset())).append("\n"); - sb.append(" .fontname = ").append(getFontName()).append("\n"); - sb.append("[/FONT]\n"); - return sb.toString(); - } - - public void serialize(LittleEndianOutput out) { - - out.writeShort(getFontHeight()); - out.writeShort(getAttributes()); - out.writeShort(getColorPaletteIndex()); - out.writeShort(getBoldWeight()); - out.writeShort(getSuperSubScript()); - out.writeByte(getUnderline()); - out.writeByte(getFamily()); - out.writeByte(getCharset()); - out.writeByte(field_9_zero); - int fontNameLen = field_11_font_name.length(); - out.writeByte(fontNameLen); - boolean hasMultibyte = StringUtil.hasMultibyte(field_11_font_name); - out.writeByte(hasMultibyte ? 0x01 : 0x00); - if (fontNameLen > 0) { - if (hasMultibyte) { - StringUtil.putUnicodeLE(field_11_font_name, out); - } else { - StringUtil.putCompressedUnicode(field_11_font_name, out); - } - } - } - protected int getDataSize() { - int size = 16; // 5 shorts + 6 bytes - int fontNameLen = field_11_font_name.length(); - if (fontNameLen < 1) { - return size; - } - - boolean hasMultibyte = StringUtil.hasMultibyte(field_11_font_name); - return size + fontNameLen * (hasMultibyte ? 2 : 1); - } - - public short getSid() { - return sid; - } - - /** - * Clones all the font style information from another - * FontRecord, onto this one. This - * will then hold all the same font style options. - * - * @param source the record to clone the properties from - */ - public void cloneStyleFrom(FontRecord source) { - field_1_font_height = source.field_1_font_height; - field_2_attributes = source.field_2_attributes; - field_3_color_palette_index = source.field_3_color_palette_index; - field_4_bold_weight = source.field_4_bold_weight; - field_5_super_sub_script = source.field_5_super_sub_script; - field_6_underline = source.field_6_underline; - field_7_family = source.field_7_family; - field_8_charset = source.field_8_charset; - field_9_zero = source.field_9_zero; - field_11_font_name = source.field_11_font_name; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime - * result - + ((field_11_font_name == null) ? 0 : field_11_font_name - .hashCode()); - result = prime * result + field_1_font_height; - result = prime * result + field_2_attributes; - result = prime * result + field_3_color_palette_index; - result = prime * result + field_4_bold_weight; - result = prime * result + field_5_super_sub_script; - result = prime * result + field_6_underline; - result = prime * result + field_7_family; - result = prime * result + field_8_charset; - result = prime * result + field_9_zero; - return result; - } - - /** - * Does this FontRecord have all the same font - * properties as the supplied FontRecord? - * Note that {@link #equals(Object)} will check - * for exact objects, while this will check - * for exact contents, because normally the - * font record's position makes a big - * difference too. - * - * @param other the record to compare with - * - * @return true, if the properties match - */ - public boolean sameProperties(FontRecord other) { - return - field_1_font_height == other.field_1_font_height && - field_2_attributes == other.field_2_attributes && - field_3_color_palette_index == other.field_3_color_palette_index && - field_4_bold_weight == other.field_4_bold_weight && - field_5_super_sub_script == other.field_5_super_sub_script && - field_6_underline == other.field_6_underline && - field_7_family == other.field_7_family && - field_8_charset == other.field_8_charset && - field_9_zero == other.field_9_zero && - stringEquals(this.field_11_font_name, other.field_11_font_name) - ; - } - - public boolean equals(Object o) { - return (o instanceof FontRecord) ? sameProperties((FontRecord)o) : false; - } - - private static boolean stringEquals(String s1, String s2) { - return (s1 == s2 || (s1 != null && s1.equals(s2))); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java deleted file mode 100644 index e5e98bb0b..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -/** - * Title: Footer Record (0x0015)

    - * Description: Specifies the footer for a sheet

    - * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class FooterRecord extends HeaderFooterBase implements Cloneable { - public final static short sid = 0x0015; - - public FooterRecord(String text) { - super(text); - } - - public FooterRecord(RecordInputStream in) { - super(in); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FOOTER]\n"); - buffer.append(" .footer = ").append(getText()).append("\n"); - buffer.append("[/FOOTER]\n"); - return buffer.toString(); - } - - public short getSid() { - return sid; - } - - @Override - public FooterRecord clone() { - return new FooterRecord(getText()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java deleted file mode 100644 index 955c52c22..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: Format Record (0x041E)

    - * Description: describes a number format -- those goofy strings like $(#,###)

    - * - * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class FormatRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x041E; - - private final int field_1_index_code; - private final boolean field_3_hasMultibyte; - private final String field_4_formatstring; - - private FormatRecord(FormatRecord other) { - field_1_index_code = other.field_1_index_code; - field_3_hasMultibyte = other.field_3_hasMultibyte; - field_4_formatstring = other.field_4_formatstring; - } - - public FormatRecord(int indexCode, String fs) { - field_1_index_code = indexCode; - field_4_formatstring = fs; - field_3_hasMultibyte = StringUtil.hasMultibyte(fs); - } - - public FormatRecord(RecordInputStream in) { - field_1_index_code = in.readShort(); - int field_3_unicode_len = in.readUShort(); - field_3_hasMultibyte = (in.readByte() & 0x01) != 0; - - if (field_3_hasMultibyte) { - field_4_formatstring = in.readUnicodeLEString(field_3_unicode_len); - } else { - field_4_formatstring = in.readCompressedUnicode(field_3_unicode_len); - } - } - - /** - * get the format index code (for built in formats) - * - * @return the format index code - * @see org.apache.poi.hssf.model.InternalWorkbook - */ - public int getIndexCode() { - return field_1_index_code; - } - - /** - * get the format string - * - * @return the format string - */ - public String getFormatString() { - return field_4_formatstring; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FORMAT]\n"); - buffer.append(" .indexcode = ").append(HexDump.shortToHex(getIndexCode())).append("\n"); - buffer.append(" .isUnicode = ").append(field_3_hasMultibyte ).append("\n"); - buffer.append(" .formatstring = ").append(getFormatString()).append("\n"); - buffer.append("[/FORMAT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - String formatString = getFormatString(); - out.writeShort(getIndexCode()); - out.writeShort(formatString.length()); - out.writeByte(field_3_hasMultibyte ? 0x01 : 0x00); - - if ( field_3_hasMultibyte ) { - StringUtil.putUnicodeLE( formatString, out); - } else { - StringUtil.putCompressedUnicode( formatString, out); - } - } - protected int getDataSize() { - return 5 // 2 shorts + 1 byte - + getFormatString().length() * (field_3_hasMultibyte ? 2 : 1); - } - - public short getSid() { - return sid; - } - - @Override - public FormatRecord clone() { - return new FormatRecord(this); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java deleted file mode 100644 index 4eae6ce5c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java +++ /dev/null @@ -1,391 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Formula Record (0x0006). - * REFERENCE: PG 317/444 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class FormulaRecord extends CellRecord implements Cloneable { - - public static final short sid = 0x0006; // docs say 406...because of a bug Microsoft support site article #Q184647) - private static int FIXED_SIZE = 14; // double + short + int - - private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001); - private static final BitField calcOnLoad = BitFieldFactory.getInstance(0x0002); - private static final BitField sharedFormula = BitFieldFactory.getInstance(0x0008); - - /** - * Manages the cached formula result values of other types besides numeric. - * Excel encodes the same 8 bytes that would be field_4_value with various NaN - * values that are decoded/encoded by this class. - */ - static final class SpecialCachedValue { - /** deliberately chosen by Excel in order to encode other values within Double NaNs */ - private static final long BIT_MARKER = 0xFFFF000000000000L; - private static final int VARIABLE_DATA_LENGTH = 6; - private static final int DATA_INDEX = 2; - - // FIXME: can these be merged with {@link CellType}? - // are the numbers specific to the HSSF formula record format or just a poor-man's enum? - public static final int STRING = 0; - public static final int BOOLEAN = 1; - public static final int ERROR_CODE = 2; - public static final int EMPTY = 3; - - private final byte[] _variableData; - - private SpecialCachedValue(byte[] data) { - _variableData = data; - } - public int getTypeCode() { - return _variableData[0]; - } - - /** - * @return null if the double value encoded by valueLongBits - * is a normal (non NaN) double value. - */ - public static SpecialCachedValue create(long valueLongBits) { - if ((BIT_MARKER & valueLongBits) != BIT_MARKER) { - return null; - } - - byte[] result = new byte[VARIABLE_DATA_LENGTH]; - long x = valueLongBits; - for (int i=0; i>= 8; - } - switch (result[0]) { - case STRING: - case BOOLEAN: - case ERROR_CODE: - case EMPTY: - break; - default: - throw new RecordFormatException("Bad special value code (" + result[0] + ")"); - } - return new SpecialCachedValue(result); - } - public void serialize(LittleEndianOutput out) { - out.write(_variableData); - out.writeShort(0xFFFF); - } - public String formatDebugString() { - return formatValue() + ' ' + HexDump.toHex(_variableData); - } - private String formatValue() { - int typeCode = getTypeCode(); - switch (typeCode) { - case STRING: return ""; - case BOOLEAN: return getDataValue() == 0 ? "FALSE" : "TRUE"; - case ERROR_CODE: return ErrorEval.getText(getDataValue()); - case EMPTY: return ""; - } - return "#error(type=" + typeCode + ")#"; - } - private int getDataValue() { - return _variableData[DATA_INDEX]; - } - public static SpecialCachedValue createCachedEmptyValue() { - return create(EMPTY, 0); - } - public static SpecialCachedValue createForString() { - return create(STRING, 0); - } - public static SpecialCachedValue createCachedBoolean(boolean b) { - return create(BOOLEAN, b ? 1 : 0); - } - public static SpecialCachedValue createCachedErrorCode(int errorCode) { - return create(ERROR_CODE, errorCode); - } - private static SpecialCachedValue create(int code, int data) { - byte[] vd = { - (byte) code, - 0, - (byte) data, - 0, - 0, - 0, - }; - return new SpecialCachedValue(vd); - } - @Override - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()); - sb.append('[').append(formatValue()).append(']'); - return sb.toString(); - } - public int getValueType() { - int typeCode = getTypeCode(); - switch (typeCode) { - case STRING: return CellType.STRING.getCode(); - case BOOLEAN: return CellType.BOOLEAN.getCode(); - case ERROR_CODE: return CellType.ERROR.getCode(); - case EMPTY: return CellType.STRING.getCode(); // is this correct? - } - throw new IllegalStateException("Unexpected type id (" + typeCode + ")"); - } - public boolean getBooleanValue() { - if (getTypeCode() != BOOLEAN) { - throw new IllegalStateException("Not a boolean cached value - " + formatValue()); - } - return getDataValue() != 0; - } - public int getErrorValue() { - if (getTypeCode() != ERROR_CODE) { - throw new IllegalStateException("Not an error cached value - " + formatValue()); - } - return getDataValue(); - } - } - - private double field_4_value; - private short field_5_options; - /** - * Unused field. As it turns out this field is often not zero.. - * According to Microsoft Excel Developer's Kit Page 318: - * when writing the chn field (offset 20), it's supposed to be 0 but ignored on read - */ - private int field_6_zero; - private Formula field_8_parsed_expr; - - /** - * Since the NaN support seems sketchy (different constants) we'll store and spit it out directly - */ - private SpecialCachedValue specialCachedValue; - - /** Creates new FormulaRecord */ - - public FormulaRecord() { - field_8_parsed_expr = Formula.create(Ptg.EMPTY_PTG_ARRAY); - } - - public FormulaRecord(RecordInputStream ris) { - super(ris); - LittleEndianInput in = ris; - long valueLongBits = in.readLong(); - field_5_options = in.readShort(); - specialCachedValue = SpecialCachedValue.create(valueLongBits); - if (specialCachedValue == null) { - field_4_value = Double.longBitsToDouble(valueLongBits); - } - - field_6_zero = in.readInt(); - - int field_7_expression_len = in.readShort(); // this length does not include any extra array data - int nBytesAvailable = in.available(); - field_8_parsed_expr = Formula.read(field_7_expression_len, in, nBytesAvailable); - } - - /** - * set the calculated value of the formula - * - * @param value calculated value - */ - public void setValue(double value) { - field_4_value = value; - specialCachedValue = null; - } - - public void setCachedResultTypeEmptyString() { - specialCachedValue = SpecialCachedValue.createCachedEmptyValue(); - } - public void setCachedResultTypeString() { - specialCachedValue = SpecialCachedValue.createForString(); - } - public void setCachedResultErrorCode(int errorCode) { - specialCachedValue = SpecialCachedValue.createCachedErrorCode(errorCode); - } - public void setCachedResultBoolean(boolean value) { - specialCachedValue = SpecialCachedValue.createCachedBoolean(value); - } - /** - * @return true if this {@link FormulaRecord} is followed by a - * {@link StringRecord} representing the cached text result of the formula - * evaluation. - */ - public boolean hasCachedResultString() { - if (specialCachedValue == null) { - return false; - } - return specialCachedValue.getTypeCode() == SpecialCachedValue.STRING; - } - - public int getCachedResultType() { - if (specialCachedValue == null) { - return CellType.NUMERIC.getCode(); - } - return specialCachedValue.getValueType(); - } - - public boolean getCachedBooleanValue() { - return specialCachedValue.getBooleanValue(); - } - public int getCachedErrorValue() { - return specialCachedValue.getErrorValue(); - } - - - /** - * set the option flags - * - * @param options bitmask - */ - public void setOptions(short options) { - field_5_options = options; - } - - /** - * get the calculated value of the formula - * - * @return calculated value - */ - public double getValue() { - return field_4_value; - } - - /** - * get the option flags - * - * @return bitmask - */ - public short getOptions() { - return field_5_options; - } - - public boolean isSharedFormula() { - return sharedFormula.isSet(field_5_options); - } - public void setSharedFormula(boolean flag) { - field_5_options = - sharedFormula.setShortBoolean(field_5_options, flag); - } - - public boolean isAlwaysCalc() { - return alwaysCalc.isSet(field_5_options); - } - public void setAlwaysCalc(boolean flag) { - field_5_options = - alwaysCalc.setShortBoolean(field_5_options, flag); - } - - public boolean isCalcOnLoad() { - return calcOnLoad.isSet(field_5_options); - } - public void setCalcOnLoad(boolean flag) { - field_5_options = - calcOnLoad.setShortBoolean(field_5_options, flag); - } - - /** - * @return the formula tokens. never null - */ - public Ptg[] getParsedExpression() { - return field_8_parsed_expr.getTokens(); - } - - public Formula getFormula() { - return field_8_parsed_expr; - } - - public void setParsedExpression(Ptg[] ptgs) { - field_8_parsed_expr = Formula.create(ptgs); - } - - @Override - public short getSid() { - return sid; - } - - @Override - protected int getValueDataSize() { - return FIXED_SIZE + field_8_parsed_expr.getEncodedSize(); - } - @Override - protected void serializeValue(LittleEndianOutput out) { - - if (specialCachedValue == null) { - out.writeDouble(field_4_value); - } else { - specialCachedValue.serialize(out); - } - - out.writeShort(getOptions()); - - out.writeInt(field_6_zero); // may as well write original data back so as to minimise differences from original - field_8_parsed_expr.serialize(out); - } - - @Override - protected String getRecordName() { - return "FORMULA"; - } - - @Override - protected void appendValueText(StringBuilder sb) { - sb.append(" .value = "); - if (specialCachedValue == null) { - sb.append(field_4_value).append("\n"); - } else { - sb.append(specialCachedValue.formatDebugString()).append("\n"); - } - sb.append(" .options = ").append(HexDump.shortToHex(getOptions())).append("\n"); - sb.append(" .alwaysCalc= ").append(isAlwaysCalc()).append("\n"); - sb.append(" .calcOnLoad= ").append(isCalcOnLoad()).append("\n"); - sb.append(" .shared = ").append(isSharedFormula()).append("\n"); - sb.append(" .zero = ").append(HexDump.intToHex(field_6_zero)).append("\n"); - - Ptg[] ptgs = field_8_parsed_expr.getTokens(); - for (int k = 0; k < ptgs.length; k++ ) { - if (k>0) { - sb.append("\n"); - } - sb.append(" Ptg[").append(k).append("]="); - Ptg ptg = ptgs[k]; - sb.append(ptg.toString()).append(ptg.getRVAType()); - } - } - - @Override - public FormulaRecord clone() { - FormulaRecord rec = new FormulaRecord(); - copyBaseFields(rec); - rec.field_4_value = field_4_value; - rec.field_5_options = field_5_options; - rec.field_6_zero = field_6_zero; - rec.field_8_parsed_expr = field_8_parsed_expr; - rec.specialCachedValue = specialCachedValue; - return rec; - } -} - diff --git a/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java deleted file mode 100644 index 14c0ddd15..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java +++ /dev/null @@ -1,102 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - - -/** - * This structure appears as part of an Obj record that represents a checkbox or radio button. - * - * @author Yegor Kozlov - */ -public final class FtCblsSubRecord extends SubRecord implements Cloneable { - public final static short sid = 0x0C; - private static final int ENCODED_SIZE = 20; - - private byte[] reserved; - - /** - * Construct a new FtCblsSubRecord and - * fill its data with the default values - */ - public FtCblsSubRecord() - { - reserved = new byte[ENCODED_SIZE]; - } - - public FtCblsSubRecord(LittleEndianInput in, int size) { - if (size != ENCODED_SIZE) { - throw new RecordFormatException("Unexpected size (" + size + ")"); - } - //just grab the raw data - byte[] buf = new byte[size]; - in.readFully(buf); - reserved = buf; - } - - /** - * Convert this record to string. - * Used by BiffViewer and other utilities. - */ - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FtCbls ]").append("\n"); - buffer.append(" size = ").append(getDataSize()).append("\n"); - buffer.append(" reserved = ").append(HexDump.toHex(reserved)).append("\n"); - buffer.append("[/FtCbls ]").append("\n"); - return buffer.toString(); - } - - /** - * Serialize the record data into the supplied array of bytes - * - * @param out the stream to serialize into - */ - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(reserved.length); - out.write(reserved); - } - - protected int getDataSize() { - return reserved.length; - } - - /** - * @return id of this record. - */ - public short getSid() - { - return sid; - } - - @Override - public FtCblsSubRecord clone() { - FtCblsSubRecord rec = new FtCblsSubRecord(); - byte[] recdata = new byte[reserved.length]; - System.arraycopy(reserved, 0, recdata, 0, recdata.length); - rec.reserved = recdata; - return rec; - } - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java deleted file mode 100644 index 08a661283..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - - -/** - * The FtCf structure specifies the clipboard format of the picture-type Obj record containing this FtCf. - */ -public final class FtCfSubRecord extends SubRecord implements Cloneable { - public final static short sid = 0x07; - public final static short length = 0x02; - - /** - * Specifies the format of the picture is an enhanced metafile. - */ - public static final short METAFILE_BIT = (short)0x0002; - - /** - * Specifies the format of the picture is a bitmap. - */ - public static final short BITMAP_BIT = (short)0x0009; - - /** - * Specifies the picture is in an unspecified format that is - * neither and enhanced metafile nor a bitmap. - */ - public static final short UNSPECIFIED_BIT = (short)0xFFFF; - - private short flags = 0; - - /** - * Construct a new FtPioGrbitSubRecord and - * fill its data with the default values - */ - public FtCfSubRecord() { - } - - public FtCfSubRecord(LittleEndianInput in, int size) { - if (size != length) { - throw new RecordFormatException("Unexpected size (" + size + ")"); - } - flags = in.readShort(); - } - - /** - * Convert this record to string. - * Used by BiffViewer and other utilities. - */ - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[FtCf ]\n"); - buffer.append(" size = ").append(length).append("\n"); - buffer.append(" flags = ").append(HexDump.toHex(flags)).append("\n"); - buffer.append("[/FtCf ]\n"); - return buffer.toString(); - } - - /** - * Serialize the record data into the supplied array of bytes - * - * @param out the stream to serialize into - */ - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(length); - out.writeShort(flags); - } - - protected int getDataSize() { - return length; - } - - /** - * @return id of this record. - */ - public short getSid() - { - return sid; - } - - @Override - public FtCfSubRecord clone() { - FtCfSubRecord rec = new FtCfSubRecord(); - rec.flags = this.flags; - return rec; - } - - public short getFlags() { - return flags; - } - - public void setFlags(short flags) { - this.flags = flags; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java deleted file mode 100644 index fa8c453af..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - - -/** - * This structure appears as part of an Obj record that represents image display properties. - */ -public final class FtPioGrbitSubRecord extends SubRecord implements Cloneable { - public final static short sid = 0x08; - public final static short length = 0x02; - - /** - * A bit that specifies whether the picture's aspect ratio is preserved when rendered in - * different views (Normal view, Page Break Preview view, Page Layout view and printing). - */ - public static final int AUTO_PICT_BIT = 1 << 0; - - /** - * A bit that specifies whether the pictFmla field of the Obj record that contains - * this FtPioGrbit specifies a DDE reference. - */ - public static final int DDE_BIT = 1 << 1; - - /** - * A bit that specifies whether this object is expected to be updated on print to - * reflect the values in the cell associated with the object. - */ - public static final int PRINT_CALC_BIT = 1 << 2; - - /** - * A bit that specifies whether the picture is displayed as an icon. - */ - public static final int ICON_BIT = 1 << 3; - - /** - * A bit that specifies whether this object is an ActiveX control. - * It MUST NOT be the case that both fCtl and fDde are equal to 1. - */ - public static final int CTL_BIT = 1 << 4; - - /** - * A bit that specifies whether the object data are stored in an - * embedding storage (= 0) or in the controls stream (ctls) (= 1). - */ - public static final int PRSTM_BIT = 1 << 5; - - /** - * A bit that specifies whether this is a camera picture. - */ - public static final int CAMERA_BIT = 1 << 7; - - /** - * A bit that specifies whether this picture's size has been explicitly set. - * 0 = picture size has been explicitly set, 1 = has not been set - */ - public static final int DEFAULT_SIZE_BIT = 1 << 8; - - /** - * A bit that specifies whether the OLE server for the object is called - * to load the object's data automatically when the parent workbook is opened. - */ - public static final int AUTO_LOAD_BIT = 1 << 9; - - - private short flags = 0; - - /** - * Construct a new FtPioGrbitSubRecord and - * fill its data with the default values - */ - public FtPioGrbitSubRecord() { - } - - public FtPioGrbitSubRecord(LittleEndianInput in, int size) { - if (size != length) { - throw new RecordFormatException("Unexpected size (" + size + ")"); - } - flags = in.readShort(); - } - - /** - * Use one of the bitmasks MANUAL_ADVANCE_BIT ... CURSOR_VISIBLE_BIT - * @param bitmask the bitmask to apply - * @param enabled if true, the bitmask will be or-ed, otherwise the bits set in the mask will be removed from the flags - */ - public void setFlagByBit(int bitmask, boolean enabled) { - if (enabled) { - flags |= bitmask; - } else { - flags &= (0xFFFF ^ bitmask); - } - } - - public boolean getFlagByBit(int bitmask) { - return ((flags & bitmask) != 0); - } - - /** - * Convert this record to string. - * Used by BiffViewer and other utilities. - */ - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[FtPioGrbit ]\n"); - buffer.append(" size = ").append(length).append("\n"); - buffer.append(" flags = ").append(HexDump.toHex(flags)).append("\n"); - buffer.append("[/FtPioGrbit ]\n"); - return buffer.toString(); - } - - /** - * Serialize the record data into the supplied array of bytes - * - * @param out the stream to serialize into - */ - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(length); - out.writeShort(flags); - } - - protected int getDataSize() { - return length; - } - - /** - * @return id of this record. - */ - public short getSid() - { - return sid; - } - - @Override - public FtPioGrbitSubRecord clone() { - FtPioGrbitSubRecord rec = new FtPioGrbitSubRecord(); - rec.flags = this.flags; - return rec; - } - - public short getFlags() { - return flags; - } - - public void setFlags(short flags) { - this.flags = flags; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java b/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java deleted file mode 100644 index 14f04ab2a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java +++ /dev/null @@ -1,109 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Gridset Record.

    - * Description: flag denoting whether the user specified that gridlines are used when - * printing.

    - * REFERENCE: PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Glen Stampoultzis (glens at apache.org) - * @author Jason Height (jheight at chariot dot net dot au) - * - * @version 2.0-pre - */ - -public final class GridsetRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x82; - public short field_1_gridset_flag; - - public GridsetRecord() - { - } - - public GridsetRecord(RecordInputStream in) - { - field_1_gridset_flag = in.readShort(); - } - - /** - * set whether gridlines are visible when printing - * - * @param gridset - true if no gridlines are print, false if gridlines are not print. - */ - - public void setGridset(boolean gridset) - { - if (gridset == true) - { - field_1_gridset_flag = 1; - } - else - { - field_1_gridset_flag = 0; - } - } - - /** - * get whether the gridlines are shown during printing. - * - * @return gridset - true if gridlines are NOT printed, false if they are. - */ - - public boolean getGridset() - { - return (field_1_gridset_flag == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[GRIDSET]\n"); - buffer.append(" .gridset = ").append(getGridset()) - .append("\n"); - buffer.append("[/GRIDSET]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_gridset_flag); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public GridsetRecord clone() { - GridsetRecord rec = new GridsetRecord(); - rec.field_1_gridset_flag = field_1_gridset_flag; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java deleted file mode 100644 index c7af79ee3..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ftGmo (0x0006)

    - * The group marker record is used as a position holder for groups. - */ -public final class GroupMarkerSubRecord extends SubRecord implements Cloneable { - public final static short sid = 0x0006; - - private static final byte[] EMPTY_BYTE_ARRAY = { }; - - // would really love to know what goes in here. - private byte[] reserved; - - public GroupMarkerSubRecord() { - reserved = EMPTY_BYTE_ARRAY; - } - - public GroupMarkerSubRecord(LittleEndianInput in, int size) { - byte[] buf = new byte[size]; - in.readFully(buf); - reserved = buf; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - String nl = System.getProperty("line.separator"); - buffer.append("[ftGmo]" + nl); - buffer.append(" reserved = ").append(HexDump.toHex(reserved)).append(nl); - buffer.append("[/ftGmo]" + nl); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(reserved.length); - out.write(reserved); - } - - protected int getDataSize() { - return reserved.length; - } - - public short getSid() - { - return sid; - } - - @Override - public GroupMarkerSubRecord clone() { - GroupMarkerSubRecord rec = new GroupMarkerSubRecord(); - rec.reserved = new byte[reserved.length]; - for ( int i = 0; i < reserved.length; i++ ) - rec.reserved[i] = reserved[i]; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java deleted file mode 100644 index 97cc0f7c7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java +++ /dev/null @@ -1,182 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Guts Record

    - * Description: Row/column gutter sizes

    - * REFERENCE: PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class GutsRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x80; - private short field_1_left_row_gutter; // size of the row gutter to the left of the rows - private short field_2_top_col_gutter; // size of the column gutter above the columns - private short field_3_row_level_max; // maximum outline level for row gutters - private short field_4_col_level_max; // maximum outline level for column gutters - - public GutsRecord() - { - } - - public GutsRecord(RecordInputStream in) - { - field_1_left_row_gutter = in.readShort(); - field_2_top_col_gutter = in.readShort(); - field_3_row_level_max = in.readShort(); - field_4_col_level_max = in.readShort(); - } - - /** - * set the size of the gutter that appears at the left of the rows - * - * @param gut gutter size in screen units - */ - - public void setLeftRowGutter(short gut) - { - field_1_left_row_gutter = gut; - } - - /** - * set the size of the gutter that appears at the above the columns - * - * @param gut gutter size in screen units - */ - - public void setTopColGutter(short gut) - { - field_2_top_col_gutter = gut; - } - - /** - * set the maximum outline level for the row gutter. - * - * @param max maximum outline level - */ - - public void setRowLevelMax(short max) - { - field_3_row_level_max = max; - } - - /** - * set the maximum outline level for the col gutter. - * - * @param max maximum outline level - */ - - public void setColLevelMax(short max) - { - field_4_col_level_max = max; - } - - /** - * get the size of the gutter that appears at the left of the rows - * - * @return gutter size in screen units - */ - - public short getLeftRowGutter() - { - return field_1_left_row_gutter; - } - - /** - * get the size of the gutter that appears at the above the columns - * - * @return gutter size in screen units - */ - - public short getTopColGutter() - { - return field_2_top_col_gutter; - } - - /** - * get the maximum outline level for the row gutter. - * - * @return maximum outline level - */ - - public short getRowLevelMax() - { - return field_3_row_level_max; - } - - /** - * get the maximum outline level for the col gutter. - * - * @return maximum outline level - */ - - public short getColLevelMax() - { - return field_4_col_level_max; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[GUTS]\n"); - buffer.append(" .leftgutter = ") - .append(Integer.toHexString(getLeftRowGutter())).append("\n"); - buffer.append(" .topgutter = ") - .append(Integer.toHexString(getTopColGutter())).append("\n"); - buffer.append(" .rowlevelmax = ") - .append(Integer.toHexString(getRowLevelMax())).append("\n"); - buffer.append(" .collevelmax = ") - .append(Integer.toHexString(getColLevelMax())).append("\n"); - buffer.append("[/GUTS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getLeftRowGutter()); - out.writeShort(getTopColGutter()); - out.writeShort(getRowLevelMax()); - out.writeShort(getColLevelMax()); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() - { - return sid; - } - - @Override - public GutsRecord clone() { - GutsRecord rec = new GutsRecord(); - rec.field_1_left_row_gutter = field_1_left_row_gutter; - rec.field_2_top_col_gutter = field_2_top_col_gutter; - rec.field_3_row_level_max = field_3_row_level_max; - rec.field_4_col_level_max = field_4_col_level_max; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java b/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java deleted file mode 100644 index 604ddeae2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: HCenter record (0x0083)

    - * Description: whether to center between horizontal margins

    - * REFERENCE: PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ -public final class HCenterRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x0083; - private short field_1_hcenter; - - public HCenterRecord() - { - } - - public HCenterRecord(RecordInputStream in) - { - field_1_hcenter = in.readShort(); - } - - /** - * set whether or not to horizonatally center this sheet. - * @param hc center - t/f - */ - - public void setHCenter(boolean hc) - { - if (hc == true) - { - field_1_hcenter = 1; - } - else - { - field_1_hcenter = 0; - } - } - - /** - * get whether or not to horizonatally center this sheet. - * @return center - t/f - */ - - public boolean getHCenter() - { - return (field_1_hcenter == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[HCENTER]\n"); - buffer.append(" .hcenter = ").append(getHCenter()) - .append("\n"); - buffer.append("[/HCENTER]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_hcenter); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public HCenterRecord clone() { - HCenterRecord rec = new HCenterRecord(); - rec.field_1_hcenter = field_1_hcenter; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java b/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java deleted file mode 100644 index 53d5f4692..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Common header/footer base class - * - * @author Josh Micich - */ -public abstract class HeaderFooterBase extends StandardRecord { - private boolean field_2_hasMultibyte; - private String field_3_text; - - protected HeaderFooterBase(String text) { - setText(text); - } - - protected HeaderFooterBase(RecordInputStream in) { - if (in.remaining() > 0) { - int field_1_footer_len = in.readShort(); - field_2_hasMultibyte = in.readByte() != 0x00; - - if (field_2_hasMultibyte) { - field_3_text = in.readUnicodeLEString(field_1_footer_len); - } else { - field_3_text = in.readCompressedUnicode(field_1_footer_len); - } - } else { - // Note - this is unusual for BIFF records in general, but normal for header / footer records: - // when the text is empty string, the whole record is empty (just the 4 byte BIFF header) - field_3_text = ""; - } - } - - /** - * set the footer string - * - * @param text string to display - */ - public final void setText(String text) { - if (text == null) { - throw new IllegalArgumentException("text must not be null"); - } - field_2_hasMultibyte = StringUtil.hasMultibyte(text); - field_3_text = text; - - // Check it'll fit into the space in the record - if (getDataSize() > RecordInputStream.MAX_RECORD_DATA_SIZE) { - throw new IllegalArgumentException("Header/Footer string too long (limit is " - + RecordInputStream.MAX_RECORD_DATA_SIZE + " bytes)"); - } - } - - /** - * get the length of the footer string - * - * @return length of the footer string - */ - private int getTextLength() { - return field_3_text.length(); - } - - public final String getText() { - return field_3_text; - } - - public final void serialize(LittleEndianOutput out) { - if (getTextLength() > 0) { - out.writeShort(getTextLength()); - out.writeByte(field_2_hasMultibyte ? 0x01 : 0x00); - if (field_2_hasMultibyte) { - StringUtil.putUnicodeLE(field_3_text, out); - } else { - StringUtil.putCompressedUnicode(field_3_text, out); - } - } - } - - protected final int getDataSize() { - if (getTextLength() < 1) { - return 0; - } - return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java b/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java deleted file mode 100644 index af4a38598..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -import java.util.Arrays; -import java.util.Locale; - -/** - * The HEADERFOOTER record stores information added in Office Excel 2007 for headers/footers. - * - * @author Yegor Kozlov - */ -public final class HeaderFooterRecord extends StandardRecord implements Cloneable { - - private static final byte[] BLANK_GUID = new byte[16]; - - public final static short sid = 0x089C; - private byte[] _rawData; - - public HeaderFooterRecord(byte[] data) { - _rawData = data; - } - - /** - * construct a HeaderFooterRecord record. No fields are interpreted and the record will - * be serialized in its original form more or less - * @param in the RecordInputstream to read the record from - */ - public HeaderFooterRecord(RecordInputStream in) { - _rawData = in.readRemainder(); - } - - /** - * spit the record out AS IS. no interpretation or identification - */ - public void serialize(LittleEndianOutput out) { - out.write(_rawData); - } - - protected int getDataSize() { - return _rawData.length; - } - - public short getSid() - { - return sid; - } - - /** - * If this header belongs to a specific sheet view , the sheet view?s GUID will be saved here. - *

    - * If it is zero, it means the current sheet. Otherwise, this field MUST match the guid field - * of the preceding {@link UserSViewBegin} record. - * - * @return the sheet view?s GUID - */ - public byte[] getGuid(){ - byte[] guid = new byte[16]; - System.arraycopy(_rawData, 12, guid, 0, guid.length); - return guid; - } - - /** - * @return whether this record belongs to the current sheet - */ - public boolean isCurrentSheet(){ - return Arrays.equals(getGuid(), BLANK_GUID); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[").append("HEADERFOOTER").append("] (0x"); - sb.append(Integer.toHexString(sid).toUpperCase(Locale.ROOT) + ")\n"); - sb.append(" rawData=").append(HexDump.toHex(_rawData)).append("\n"); - sb.append("[/").append("HEADERFOOTER").append("]\n"); - return sb.toString(); - } - - @Override - public HeaderFooterRecord clone() { - //HACK: do a "cheat" clone, see Record.java for more information - return (HeaderFooterRecord)cloneViaReserialise(); - } - - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java b/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java deleted file mode 100644 index ec6733c23..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -/** - * Title: Header Record

    - * Description: Specifies a header for a sheet

    - * REFERENCE: PG 321 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Shawn Laubach (slaubach at apache dot org) Modified 3/14/02 - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class HeaderRecord extends HeaderFooterBase implements Cloneable { - public final static short sid = 0x0014; - - public HeaderRecord(String text) { - super(text); - } - - public HeaderRecord(RecordInputStream in) { - super(in); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[HEADER]\n"); - buffer.append(" .header = ").append(getText()).append("\n"); - buffer.append("[/HEADER]\n"); - return buffer.toString(); - } - - public short getSid() { - return sid; - } - - @Override - public HeaderRecord clone() { - return new HeaderRecord(getText()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java b/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java deleted file mode 100644 index 9f4f1ca3c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java +++ /dev/null @@ -1,101 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Hide Object Record

    - * Description: flag defines whether to hide placeholders and object

    - * REFERENCE: PG 321 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class HideObjRecord - extends StandardRecord -{ - public final static short sid = 0x8d; - public final static short HIDE_ALL = 2; - public final static short SHOW_PLACEHOLDERS = 1; - public final static short SHOW_ALL = 0; - private short field_1_hide_obj; - - public HideObjRecord() - { - } - - public HideObjRecord(RecordInputStream in) - { - field_1_hide_obj = in.readShort(); - } - - /** - * set hide object options - * - * @param hide options - * @see #HIDE_ALL - * @see #SHOW_PLACEHOLDERS - * @see #SHOW_ALL - */ - - public void setHideObj(short hide) - { - field_1_hide_obj = hide; - } - - /** - * get hide object options - * - * @return hide options - * @see #HIDE_ALL - * @see #SHOW_PLACEHOLDERS - * @see #SHOW_ALL - */ - - public short getHideObj() - { - return field_1_hide_obj; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[HIDEOBJ]\n"); - buffer.append(" .hideobj = ") - .append(Integer.toHexString(getHideObj())).append("\n"); - buffer.append("[/HIDEOBJ]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getHideObj()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java b/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java deleted file mode 100644 index ff034ef55..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Iterator; - -/** - * HorizontalPageBreak (0x001B) record that stores page breaks at rows - * - * @see PageBreakRecord - */ -public final class HorizontalPageBreakRecord extends PageBreakRecord implements Cloneable { - - public static final short sid = 0x001B; - - /** - * Creates an empty horizontal page break record - */ - public HorizontalPageBreakRecord() { - } - - /** - * @param in the RecordInputstream to read the record from - */ - public HorizontalPageBreakRecord(RecordInputStream in) { - super(in); - } - - public short getSid() { - return sid; - } - - @Override - public PageBreakRecord clone() { - PageBreakRecord result = new HorizontalPageBreakRecord(); - Iterator iterator = getBreaksIterator(); - while (iterator.hasNext()) { - Break original = iterator.next(); - result.addBreak(original.main, original.subFrom, original.subTo); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java b/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java deleted file mode 100644 index 4048255f4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java +++ /dev/null @@ -1,786 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.HexRead; -import org.apache.poi.util.LittleEndianByteArrayInputStream; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * The HyperlinkRecord (0x01B8) wraps an HLINK-record - * from the Excel-97 format. - * Supports only external links for now (eg http://) - */ -public final class HyperlinkRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x01B8; - private static POILogger logger = POILogFactory.getLogger(HyperlinkRecord.class); - - static final class GUID { - /* - * this class is currently only used here, but could be moved to a - * common package if needed - */ - private static final int TEXT_FORMAT_LENGTH = 36; - - public static final int ENCODED_SIZE = 16; - - /** 4 bytes - little endian */ - private final int _d1; - /** 2 bytes - little endian */ - private final int _d2; - /** 2 bytes - little endian */ - private final int _d3; - /** - * 8 bytes - serialized as big endian, stored with inverted endianness here - */ - private final long _d4; - - public GUID(LittleEndianInput in) { - this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong()); - } - - public GUID(int d1, int d2, int d3, long d4) { - _d1 = d1; - _d2 = d2; - _d3 = d3; - _d4 = d4; - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(_d1); - out.writeShort(_d2); - out.writeShort(_d3); - out.writeLong(_d4); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof GUID)) { - return false; - } - GUID other = (GUID) obj; - return _d1 == other._d1 && _d2 == other._d2 - && _d3 == other._d3 && _d4 == other._d4; - } - - @Override - public int hashCode() { - assert false : "hashCode not designed"; - return 42; // any arbitrary constant will do - } - - public int getD1() { - return _d1; - } - - public int getD2() { - return _d2; - } - - public int getD3() { - return _d3; - } - - public long getD4() { - // - ByteArrayOutputStream baos = new ByteArrayOutputStream(8); - try { - new DataOutputStream(baos).writeLong(_d4); - } catch (IOException e) { - throw new RuntimeException(e); - } - byte[] buf = baos.toByteArray(); - return new LittleEndianByteArrayInputStream(buf).readLong(); - } - - public String formatAsString() { - - StringBuilder sb = new StringBuilder(36); - - int PREFIX_LEN = "0x".length(); - sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN)); - sb.append("-"); - sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN)); - sb.append("-"); - sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN)); - sb.append("-"); - String d4Chars = HexDump.longToHex(getD4()); - sb.append(d4Chars.substring(PREFIX_LEN, PREFIX_LEN+4)); - sb.append("-"); - sb.append(d4Chars.substring(PREFIX_LEN+4)); - return sb.toString(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - - /** - * Read a GUID in standard text form e.g.
    - * 13579BDF-0246-8ACE-0123-456789ABCDEF - *
    ->
    - * 0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF - */ - public static GUID parse(String rep) { - char[] cc = rep.toCharArray(); - if (cc.length != TEXT_FORMAT_LENGTH) { - throw new RecordFormatException("supplied text is the wrong length for a GUID"); - } - int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0); - int d1 = parseShort(cc, 9); - int d2 = parseShort(cc, 14); - for (int i = 23; i > 19; i--) { - cc[i] = cc[i - 1]; - } - long d3 = parseLELong(cc, 20); - - return new GUID(d0, d1, d2, d3); - } - - private static long parseLELong(char[] cc, int startIndex) { - long acc = 0; - for (int i = startIndex + 14; i >= startIndex; i -= 2) { - acc <<= 4; - acc += parseHexChar(cc[i + 0]); - acc <<= 4; - acc += parseHexChar(cc[i + 1]); - } - return acc; - } - - private static int parseShort(char[] cc, int startIndex) { - int acc = 0; - for (int i = 0; i < 4; i++) { - acc <<= 4; - acc += parseHexChar(cc[startIndex + i]); - } - return acc; - } - - private static int parseHexChar(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } - if (c >= 'A' && c <= 'F') { - return c - 'A' + 10; - } - if (c >= 'a' && c <= 'f') { - return c - 'a' + 10; - } - throw new RecordFormatException("Bad hex char '" + c + "'"); - } - } - - /** - * Link flags - */ - static final int HLINK_URL = 0x01; // File link or URL. - static final int HLINK_ABS = 0x02; // Absolute path. - static final int HLINK_LABEL = 0x14; // Has label/description. - /** Place in worksheet. If set, the {@link #_textMark} field will be present */ - static final int HLINK_PLACE = 0x08; - private static final int HLINK_TARGET_FRAME = 0x80; // has 'target frame' - private static final int HLINK_UNC_PATH = 0x100; // has UNC path - - final static GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B"); - final static GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B"); - final static GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046"); - /** expected Tail of a URL link */ - private final static byte[] URL_TAIL = HexRead.readFromString("79 58 81 F4 3B 1D 7F 48 AF 2C 82 5D C4 85 27 63 00 00 00 00 A5 AB 00 00"); - /** expected Tail of a file link */ - private final static byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); - - private static final int TAIL_SIZE = FILE_TAIL.length; - - /** cell range of this hyperlink */ - private CellRangeAddress _range; - - /** 16-byte GUID */ - private GUID _guid; - /** Some sort of options for file links. */ - private int _fileOpts; - /** Link options. Can include any of HLINK_* flags. */ - private int _linkOpts; - /** Test label */ - private String _label; - - private String _targetFrame; - /** Moniker. Makes sense only for URL and file links */ - private GUID _moniker; - /** in 8:3 DOS format No Unicode string header, - * always 8-bit characters, zero-terminated */ - private String _shortFilename; - /** Link */ - private String _address; - /** - * Text describing a place in document. In Excel UI, this is appended to the - * address, (after a '#' delimiter).
    - * This field is optional. If present, the {@link #HLINK_PLACE} must be set. - */ - private String _textMark; - - private byte[] _uninterpretedTail; - - /** - * Create a new hyperlink - */ - public HyperlinkRecord() - { - - } - - /** - * @return the 0-based column of the first cell that contains this hyperlink - */ - public int getFirstColumn() { - return _range.getFirstColumn(); - } - - /** - * Set the first column (zero-based) of the range that contains this hyperlink - * - * @param firstCol the first column (zero-based) - */ - public void setFirstColumn(int firstCol) { - _range.setFirstColumn(firstCol); - } - - /** - * @return the 0-based column of the last cell that contains this hyperlink - */ - public int getLastColumn() { - return _range.getLastColumn(); - } - - /** - * Set the last column (zero-based) of the range that contains this hyperlink - * - * @param lastCol the last column (zero-based) - */ - public void setLastColumn(int lastCol) { - _range.setLastColumn(lastCol); - } - - /** - * @return the 0-based row of the first cell that contains this hyperlink - */ - public int getFirstRow() { - return _range.getFirstRow(); - } - - /** - * Set the first row (zero-based) of the range that contains this hyperlink - * - * @param firstRow the first row (zero-based) - */ - public void setFirstRow(int firstRow) { - _range.setFirstRow(firstRow); - } - - /** - * @return the 0-based row of the last cell that contains this hyperlink - */ - public int getLastRow() { - return _range.getLastRow(); - } - - /** - * Set the last row (zero-based) of the range that contains this hyperlink - * - * @param lastRow the last row (zero-based) - */ - public void setLastRow(int lastRow) { - _range.setLastRow(lastRow); - } - - /** - * @return 16-byte guid identifier Seems to always equal {@link #STD_MONIKER} - */ - GUID getGuid() { - return _guid; - } - - /** - * @return 16-byte moniker - */ - GUID getMoniker() - { - return _moniker; - } - - private static String cleanString(String s) { - if (s == null) { - return null; - } - int idx = s.indexOf('\u0000'); - if (idx < 0) { - return s; - } - return s.substring(0, idx); - } - private static String appendNullTerm(String s) { - if (s == null) { - return null; - } - return s + '\u0000'; - } - - /** - * Return text label for this hyperlink - * - * @return text to display - */ - public String getLabel() { - return cleanString(_label); - } - - /** - * Sets text label for this hyperlink - * - * @param label text label for this hyperlink - */ - public void setLabel(String label) { - _label = appendNullTerm(label); - } - public String getTargetFrame() { - return cleanString(_targetFrame); - } - - /** - * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc. - * - * @return the address of this hyperlink - */ - public String getAddress() { - if ((_linkOpts & HLINK_URL) != 0 && FILE_MONIKER.equals(_moniker)) { - return cleanString(_address != null ? _address : _shortFilename); - } else if((_linkOpts & HLINK_PLACE) != 0) { - return cleanString(_textMark); - } else { - return cleanString(_address); - } - } - - /** - * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc. - * - * @param address the address of this hyperlink - */ - public void setAddress(String address) { - if ((_linkOpts & HLINK_URL) != 0 && FILE_MONIKER.equals(_moniker)) { - _shortFilename = appendNullTerm(address); - } else if((_linkOpts & HLINK_PLACE) != 0) { - _textMark = appendNullTerm(address); - } else { - _address = appendNullTerm(address); - } - } - - public String getShortFilename() { - return cleanString(_shortFilename); - } - - public void setShortFilename(String shortFilename) { - _shortFilename = appendNullTerm(shortFilename); - } - - public String getTextMark() { - return cleanString(_textMark); - } - public void setTextMark(String textMark) { - _textMark = appendNullTerm(textMark); - } - - - /** - * Link options. Must be a combination of HLINK_* constants. - * For testing only - * - * @return Link options - */ - int getLinkOptions(){ - return _linkOpts; - } - - /** - * @return Label options - */ - public int getLabelOptions(){ - return 2; // always 2 - } - - /** - * @return Options for a file link - */ - public int getFileOptions(){ - return _fileOpts; - } - - - public HyperlinkRecord(RecordInputStream in) { - _range = new CellRangeAddress(in); - - _guid = new GUID(in); - - /** - * streamVersion (4 bytes): An unsigned integer that specifies the version number - * of the serialization implementation used to save this structure. This value MUST equal 2. - */ - int streamVersion = in.readInt(); - if (streamVersion != 0x00000002) { - throw new RecordFormatException("Stream Version must be 0x2 but found " + streamVersion); - } - _linkOpts = in.readInt(); - - if ((_linkOpts & HLINK_LABEL) != 0){ - int label_len = in.readInt(); - _label = in.readUnicodeLEString(label_len); - } - - if ((_linkOpts & HLINK_TARGET_FRAME) != 0){ - int len = in.readInt(); - _targetFrame = in.readUnicodeLEString(len); - } - - if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) { - _moniker = null; - int nChars = in.readInt(); - _address = in.readUnicodeLEString(nChars); - } - - if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) { - _moniker = new GUID(in); - - if(URL_MONIKER.equals(_moniker)){ - int length = in.readInt(); - /** - * The value of length be either the byte size of the url field - * (including the terminating NULL character) or the byte size of the url field plus 24. - * If the value of this field is set to the byte size of the url field, - * then the tail bytes fields are not present. - */ - int remaining = in.remaining(); - if (length == remaining) { - int nChars = length/2; - _address = in.readUnicodeLEString(nChars); - } else { - int nChars = (length - TAIL_SIZE)/2; - _address = in.readUnicodeLEString(nChars); - /** - * TODO: make sense of the remaining bytes - * According to the spec they consist of: - * 1. 16-byte GUID: This field MUST equal - * {0xF4815879, 0x1D3B, 0x487F, 0xAF, 0x2C, 0x82, 0x5D, 0xC4, 0x85, 0x27, 0x63} - * 2. Serial version, this field MUST equal 0 if present. - * 3. URI Flags - */ - _uninterpretedTail = readTail(URL_TAIL, in); - } - } else if (FILE_MONIKER.equals(_moniker)) { - _fileOpts = in.readShort(); - - int len = in.readInt(); - _shortFilename = StringUtil.readCompressedUnicode(in, len); - _uninterpretedTail = readTail(FILE_TAIL, in); - int size = in.readInt(); - if (size > 0) { - int charDataSize = in.readInt(); - - //From the spec: An optional unsigned integer that MUST be 3 if present - // but some files has 4 - /*int usKeyValue = */ in.readUShort(); - - _address = StringUtil.readUnicodeLE(in, charDataSize/2); - } else { - _address = null; - } - } else if (STD_MONIKER.equals(_moniker)) { - _fileOpts = in.readShort(); - - int len = in.readInt(); - - byte[] path_bytes = new byte[len]; - in.readFully(path_bytes); - - _address = new String(path_bytes, StringUtil.UTF8); - } - } - - if((_linkOpts & HLINK_PLACE) != 0) { - - int len = in.readInt(); - _textMark = in.readUnicodeLEString(len); - } - - if (in.remaining() > 0) { - logger.log(POILogger.WARN, - "Hyperlink data remains: " + in.remaining() + - " : " +HexDump.toHex(in.readRemainder()) - ); - } - } - - @Override - public void serialize(LittleEndianOutput out) { - _range.serialize(out); - - _guid.serialize(out); - out.writeInt(0x00000002); // TODO const - out.writeInt(_linkOpts); - - if ((_linkOpts & HLINK_LABEL) != 0){ - out.writeInt(_label.length()); - StringUtil.putUnicodeLE(_label, out); - } - if ((_linkOpts & HLINK_TARGET_FRAME) != 0){ - out.writeInt(_targetFrame.length()); - StringUtil.putUnicodeLE(_targetFrame, out); - } - - if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) { - out.writeInt(_address.length()); - StringUtil.putUnicodeLE(_address, out); - } - - if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) { - _moniker.serialize(out); - if(URL_MONIKER.equals(_moniker)){ - if (_uninterpretedTail == null) { - out.writeInt(_address.length()*2); - StringUtil.putUnicodeLE(_address, out); - } else { - out.writeInt(_address.length()*2 + TAIL_SIZE); - StringUtil.putUnicodeLE(_address, out); - writeTail(_uninterpretedTail, out); - } - } else if (FILE_MONIKER.equals(_moniker)){ - out.writeShort(_fileOpts); - out.writeInt(_shortFilename.length()); - StringUtil.putCompressedUnicode(_shortFilename, out); - writeTail(_uninterpretedTail, out); - if (_address == null) { - out.writeInt(0); - } else { - int addrLen = _address.length() * 2; - out.writeInt(addrLen + 6); - out.writeInt(addrLen); - out.writeShort(0x0003); // TODO const - StringUtil.putUnicodeLE(_address, out); - } - } - } - if((_linkOpts & HLINK_PLACE) != 0){ - out.writeInt(_textMark.length()); - StringUtil.putUnicodeLE(_textMark, out); - } - } - - @Override - protected int getDataSize() { - int size = 0; - size += 2 + 2 + 2 + 2; //rwFirst, rwLast, colFirst, colLast - size += GUID.ENCODED_SIZE; - size += 4; //label_opts - size += 4; //link_opts - if ((_linkOpts & HLINK_LABEL) != 0){ - size += 4; //link length - size += _label.length()*2; - } - if ((_linkOpts & HLINK_TARGET_FRAME) != 0){ - size += 4; // int nChars - size += _targetFrame.length()*2; - } - if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) { - size += 4; // int nChars - size += _address.length()*2; - } - if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) { - size += GUID.ENCODED_SIZE; - if(URL_MONIKER.equals(_moniker)){ - size += 4; //address length - size += _address.length()*2; - if (_uninterpretedTail != null) { - size += TAIL_SIZE; - } - } else if (FILE_MONIKER.equals(_moniker)){ - size += 2; //file_opts - size += 4; //address length - size += _shortFilename.length(); - size += TAIL_SIZE; - size += 4; - if (_address != null) { - size += 6; - size += _address.length() * 2; - } - - } - } - if((_linkOpts & HLINK_PLACE) != 0){ - size += 4; //address length - size += _textMark.length()*2; - } - return size; - } - - - private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) { - byte[] result = new byte[TAIL_SIZE]; - in.readFully(result); -// if (false) { // Quite a few examples in the unit tests which don't have the exact expected tail -// for (int i = 0; i < expectedTail.length; i++) { -// if (expectedTail[i] != result[i]) { -// logger.log( POILogger.ERROR, "Mismatch in tail byte [" + i + "]" -// + "expected " + (expectedTail[i] & 0xFF) + " but got " + (result[i] & 0xFF)); -// } -// } -// } - return result; - } - private static void writeTail(byte[] tail, LittleEndianOutput out) { - out.write(tail); - } - - @Override - public short getSid() { - return HyperlinkRecord.sid; - } - - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[HYPERLINK RECORD]\n"); - buffer.append(" .range = ").append(_range.formatAsString()).append("\n"); - buffer.append(" .guid = ").append(_guid.formatAsString()).append("\n"); - buffer.append(" .linkOpts= ").append(HexDump.intToHex(_linkOpts)).append("\n"); - buffer.append(" .label = ").append(getLabel()).append("\n"); - if ((_linkOpts & HLINK_TARGET_FRAME) != 0) { - buffer.append(" .targetFrame= ").append(getTargetFrame()).append("\n"); - } - if((_linkOpts & HLINK_URL) != 0 && _moniker != null) { - buffer.append(" .moniker = ").append(_moniker.formatAsString()).append("\n"); - } - if ((_linkOpts & HLINK_PLACE) != 0) { - buffer.append(" .textMark= ").append(getTextMark()).append("\n"); - } - buffer.append(" .address = ").append(getAddress()).append("\n"); - buffer.append("[/HYPERLINK RECORD]\n"); - return buffer.toString(); - } - - /** - * Based on the link options, is this a url? - * - * @return true, if this is a url link - */ - public boolean isUrlLink() { - return (_linkOpts & HLINK_URL) > 0 - && (_linkOpts & HLINK_ABS) > 0; - } - /** - * Based on the link options, is this a file? - * - * @return true, if this is a file link - */ - public boolean isFileLink() { - return (_linkOpts & HLINK_URL) > 0 - && (_linkOpts & HLINK_ABS) == 0; - } - /** - * Based on the link options, is this a document? - * - * @return true, if this is a docment link - */ - public boolean isDocumentLink() { - return (_linkOpts & HLINK_PLACE) > 0; - } - - /** - * Initialize a new url link - */ - public void newUrlLink() { - _range = new CellRangeAddress(0, 0, 0, 0); - _guid = STD_MONIKER; - _linkOpts = HLINK_URL | HLINK_ABS | HLINK_LABEL; - setLabel(""); - _moniker = URL_MONIKER; - setAddress(""); - _uninterpretedTail = URL_TAIL; - } - - /** - * Initialize a new file link - */ - public void newFileLink() { - _range = new CellRangeAddress(0, 0, 0, 0); - _guid = STD_MONIKER; - _linkOpts = HLINK_URL | HLINK_LABEL; - _fileOpts = 0; - setLabel(""); - _moniker = FILE_MONIKER; - setAddress(null); - setShortFilename(""); - _uninterpretedTail = FILE_TAIL; - } - - /** - * Initialize a new document link - */ - public void newDocumentLink() { - _range = new CellRangeAddress(0, 0, 0, 0); - _guid = STD_MONIKER; - _linkOpts = HLINK_LABEL | HLINK_PLACE; - setLabel(""); - _moniker = FILE_MONIKER; - setAddress(""); - setTextMark(""); - } - - @Override - public HyperlinkRecord clone() { - HyperlinkRecord rec = new HyperlinkRecord(); - rec._range = _range.copy(); - rec._guid = _guid; - rec._linkOpts = _linkOpts; - rec._fileOpts = _fileOpts; - rec._label = _label; - rec._address = _address; - rec._moniker = _moniker; - rec._shortFilename = _shortFilename; - rec._targetFrame = _targetFrame; - rec._textMark = _textMark; - rec._uninterpretedTail = _uninterpretedTail; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java b/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java deleted file mode 100644 index 4eb000b55..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.IntList; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Index Record (0x020B)

    - * Description: Occurs right after BOF, tells you where the DBCELL records are for a sheet - * Important for locating cells

    - * - * REFERENCE: PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class IndexRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x020B; - private int field_2_first_row; // first row on the sheet - private int field_3_last_row_add1; // last row - private int field_4_zero; // supposed to be zero - private IntList field_5_dbcells; // array of offsets to DBCELL records - - public IndexRecord() - { - } - - public IndexRecord(RecordInputStream in) - { - int field_1_zero = in.readInt(); - if (field_1_zero != 0) { - throw new RecordFormatException("Expected zero for field 1 but got " + field_1_zero); - } - field_2_first_row = in.readInt(); - field_3_last_row_add1 = in.readInt(); - field_4_zero = in.readInt(); - - int nCells = in.remaining() / 4; - field_5_dbcells = new IntList(nCells); - for(int i=0; i - * Description: Shows where the Interface Records end (MMS) - * (has no fields)

    - * REFERENCE: PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - */ -public final class InterfaceEndRecord extends StandardRecord { - - public static final short sid = 0x00E2; - public static final InterfaceEndRecord instance = new InterfaceEndRecord(); - - private InterfaceEndRecord() { - // enforce singleton - } - - public static Record create(RecordInputStream in) { - switch (in.remaining()) { - case 0: - return instance; - case 2: - return new InterfaceHdrRecord(in); - } - throw new RecordFormatException("Invalid record data size: " + in.remaining()); - } - - public String toString() { - return "[INTERFACEEND/]\n"; - } - - public void serialize(LittleEndianOutput out) { - // no instance data - } - - protected int getDataSize() { - return 0; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java b/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java deleted file mode 100644 index afd770534..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Interface Header Record (0x00E1)

    - * Description: Defines the beginning of Interface records (MMS)

    - * REFERENCE: PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - */ -public final class InterfaceHdrRecord extends StandardRecord { - public final static short sid = 0x00E1; - private final int _codepage; - - /** - * suggested (and probably correct) default - */ - public final static int CODEPAGE = 0x04B0; - - public InterfaceHdrRecord(int codePage) { - _codepage = codePage; - } - - public InterfaceHdrRecord(RecordInputStream in) { - _codepage = in.readShort(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[INTERFACEHDR]\n"); - buffer.append(" .codepage = ").append(HexDump.shortToHex(_codepage)).append("\n"); - buffer.append("[/INTERFACEHDR]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_codepage); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java b/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java deleted file mode 100644 index 8a7595ce4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Iteration Record (0x0011)

    - * Description: Tells whether to iterate over formula calculations or not - * (if a formula is dependent upon another formula's result) - * (odd feature for something that can only have 32 elements in - * a formula!)

    - * REFERENCE: PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class IterationRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x0011; - - private static final BitField iterationOn = BitFieldFactory.getInstance(0x0001); - - private int _flags; - - public IterationRecord(boolean iterateOn) { - _flags = iterationOn.setBoolean(0, iterateOn); - } - - public IterationRecord(RecordInputStream in) - { - _flags = in.readShort(); - } - - /** - * set whether or not to iterate for calculations - * @param iterate or not - */ - public void setIteration(boolean iterate) { - _flags = iterationOn.setBoolean(_flags, iterate); - } - - /** - * get whether or not to iterate for calculations - * - * @return whether iterative calculations are turned off or on - */ - public boolean getIteration() { - return iterationOn.isSet(_flags); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ITERATION]\n"); - buffer.append(" .flags = ").append(HexDump.shortToHex(_flags)).append("\n"); - buffer.append("[/ITERATION]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_flags); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } - - @Override - public IterationRecord clone() { - return new IterationRecord(getIteration()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java b/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java deleted file mode 100644 index bac8ce2b8..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java +++ /dev/null @@ -1,194 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Label Record (0x0204) - read only support for strings stored directly in the cell... - * Don't use this (except to read), use LabelSST instead

    - * REFERENCE: PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - * - * @see org.apache.poi.hssf.record.LabelSSTRecord - */ -public final class LabelRecord extends Record implements CellValueRecordInterface, Cloneable { - private final static POILogger logger = POILogFactory.getLogger(LabelRecord.class); - - public final static short sid = 0x0204; - - private int field_1_row; - private short field_2_column; - private short field_3_xf_index; - private short field_4_string_len; - private byte field_5_unicode_flag; - private String field_6_value; - - /** Creates new LabelRecord */ - public LabelRecord() - { - } - - /** - * @param in the RecordInputstream to read the record from - */ - public LabelRecord(RecordInputStream in) - { - field_1_row = in.readUShort(); - field_2_column = in.readShort(); - field_3_xf_index = in.readShort(); - field_4_string_len = in.readShort(); - field_5_unicode_flag = in.readByte(); - if (field_4_string_len > 0) { - if (isUnCompressedUnicode()) { - field_6_value = in.readUnicodeLEString(field_4_string_len); - } else { - field_6_value = in.readCompressedUnicode(field_4_string_len); - } - } else { - field_6_value = ""; - } - - if (in.remaining() > 0) { - logger.log(POILogger.INFO, - "LabelRecord data remains: " + in.remaining() + - " : " + HexDump.toHex(in.readRemainder()) - ); - } - } - -/* - * READ ONLY ACCESS... THIS IS FOR COMPATIBILITY ONLY...USE LABELSST! public - */ - @Override - public int getRow() - { - return field_1_row; - } - - @Override - public short getColumn() - { - return field_2_column; - } - - @Override - public short getXFIndex() - { - return field_3_xf_index; - } - - /** - * get the number of characters this string contains - * @return number of characters - */ - public short getStringLength() - { - return field_4_string_len; - } - - /** - * is this uncompressed unicode (16bit)? Or just 8-bit compressed? - * @return isUnicode - True for 16bit- false for 8bit - */ - public boolean isUnCompressedUnicode() - { - return (field_5_unicode_flag & 0x01) != 0; - } - - /** - * get the value - * - * @return the text string - * @see #getStringLength() - */ - public String getValue() - { - return field_6_value; - } - - /** - * THROWS A RUNTIME EXCEPTION.. USE LABELSSTRecords. YOU HAVE NO REASON to use LABELRecord!! - */ - @Override - public int serialize(int offset, byte [] data) { - throw new RecordFormatException("Label Records are supported READ ONLY...convert to LabelSST"); - } - @Override - public int getRecordSize() { - throw new RecordFormatException("Label Records are supported READ ONLY...convert to LabelSST"); - } - - @Override - public short getSid() - { - return sid; - } - - @Override - public String toString() - { - StringBuffer sb = new StringBuffer(); - sb.append("[LABEL]\n"); - sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n"); - sb.append(" .column = ").append(HexDump.shortToHex(getColumn())).append("\n"); - sb.append(" .xfindex = ").append(HexDump.shortToHex(getXFIndex())).append("\n"); - sb.append(" .string_len= ").append(HexDump.shortToHex(field_4_string_len)).append("\n"); - sb.append(" .unicode_flag= ").append(HexDump.byteToHex(field_5_unicode_flag)).append("\n"); - sb.append(" .value = ").append(getValue()).append("\n"); - sb.append("[/LABEL]\n"); - return sb.toString(); - } - - /** - * NO-OP! - */ - @Override - public void setColumn(short col) - { - } - - /** - * NO-OP! - */ - @Override - public void setRow(int row) - { - } - - /** - * no op! - */ - @Override - public void setXFIndex(short xf) - { - } - - @Override - public LabelRecord clone() { - LabelRecord rec = new LabelRecord(); - rec.field_1_row = field_1_row; - rec.field_2_column = field_2_column; - rec.field_3_xf_index = field_3_xf_index; - rec.field_4_string_len = field_4_string_len; - rec.field_5_unicode_flag = field_5_unicode_flag; - rec.field_6_value = field_6_value; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java b/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java deleted file mode 100644 index 80bd99cfc..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Label SST Record

    - * Description: Refers to a string in the shared string table and is a column value.

    - * REFERENCE: PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class LabelSSTRecord extends CellRecord implements Cloneable { - public final static short sid = 0xfd; - private int field_4_sst_index; - - public LabelSSTRecord() { - // fields uninitialised - } - - public LabelSSTRecord(RecordInputStream in) { - super(in); - field_4_sst_index = in.readInt(); - } - - /** - * set the index to the string in the SSTRecord - * - * @param index - of string in the SST Table - * @see org.apache.poi.hssf.record.SSTRecord - */ - public void setSSTIndex(int index) { - field_4_sst_index = index; - } - - - /** - * get the index to the string in the SSTRecord - * - * @return index of string in the SST Table - * @see org.apache.poi.hssf.record.SSTRecord - */ - public int getSSTIndex() { - return field_4_sst_index; - } - - @Override - protected String getRecordName() { - return "LABELSST"; - } - - @Override - protected void appendValueText(StringBuilder sb) { - sb.append(" .sstIndex = "); - sb.append(HexDump.shortToHex(getSSTIndex())); - } - @Override - protected void serializeValue(LittleEndianOutput out) { - out.writeInt(getSSTIndex()); - } - - @Override - protected int getValueDataSize() { - return 4; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public LabelSSTRecord clone() { - LabelSSTRecord rec = new LabelSSTRecord(); - copyBaseFields(rec); - rec.field_4_sst_index = field_4_sst_index; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java deleted file mode 100644 index 2e98cba55..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java +++ /dev/null @@ -1,420 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * This structure specifies the properties of a list or drop-down list embedded object in a sheet. - */ -public class LbsDataSubRecord extends SubRecord { - - public static final int sid = 0x0013; - - /** - * From [MS-XLS].pdf 2.5.147 FtLbsData: - * - * An unsigned integer that indirectly specifies whether - * some of the data in this structure appear in a subsequent Continue record. - * If _cbFContinued is 0x00, all of the fields in this structure except sid and _cbFContinued - * MUST NOT exist. If this entire structure is contained within the same record, - * then _cbFContinued MUST be greater than or equal to the size, in bytes, - * of this structure, not including the four bytes for the ft and _cbFContinued fields - */ - private int _cbFContinued; - - /** - * a formula that specifies the range of cell values that are the items in this list. - */ - private int _unknownPreFormulaInt; - private Ptg _linkPtg; - private Byte _unknownPostFormulaByte; - - /** - * An unsigned integer that specifies the number of items in the list. - */ - private int _cLines; - - /** - * An unsigned integer that specifies the one-based index of the first selected item in this list. - * A value of 0x00 specifies there is no currently selected item. - */ - private int _iSel; - - /** - * flags that tell what data follows - */ - private int _flags; - - /** - * An ObjId that specifies the edit box associated with this list. - * A value of 0x00 specifies that there is no edit box associated with this list. - */ - private int _idEdit; - - /** - * An optional LbsDropData that specifies properties for this dropdown control. - * This field MUST exist if and only if the containing Obj?s cmo.ot is equal to 0x14. - */ - private LbsDropData _dropData; - - /** - * An optional array of strings where each string specifies an item in the list. - * The number of elements in this array, if it exists, MUST be {@link #_cLines} - */ - private String[] _rgLines; - - /** - * An optional array of booleans that specifies - * which items in the list are part of a multiple selection - */ - private boolean[] _bsels; - - /** - * @param in the stream to read data from - * @param cbFContinued the seconf short in the record header - * @param cmoOt the containing Obj's {@link CommonObjectDataSubRecord#field_1_objectType} - */ - public LbsDataSubRecord(LittleEndianInput in, int cbFContinued, int cmoOt) { - _cbFContinued = cbFContinued; - - int encodedTokenLen = in.readUShort(); - if (encodedTokenLen > 0) { - int formulaSize = in.readUShort(); - _unknownPreFormulaInt = in.readInt(); - - Ptg[] ptgs = Ptg.readTokens(formulaSize, in); - if (ptgs.length != 1) { - throw new RecordFormatException("Read " + ptgs.length - + " tokens but expected exactly 1"); - } - _linkPtg = ptgs[0]; - switch (encodedTokenLen - formulaSize - 6) { - case 1: - _unknownPostFormulaByte = in.readByte(); - break; - case 0: - _unknownPostFormulaByte = null; - break; - default: - throw new RecordFormatException("Unexpected leftover bytes"); - } - } - - _cLines = in.readUShort(); - _iSel = in.readUShort(); - _flags = in.readUShort(); - _idEdit = in.readUShort(); - - // From [MS-XLS].pdf 2.5.147 FtLbsData: - // This field MUST exist if and only if the containing Obj?s cmo.ot is equal to 0x14. - if(cmoOt == 0x14) { - _dropData = new LbsDropData(in); - } - - // From [MS-XLS].pdf 2.5.147 FtLbsData: - // This array MUST exist if and only if the fValidPlex flag (0x2) is set - if((_flags & 0x2) != 0) { - _rgLines = new String[_cLines]; - for(int i=0; i < _cLines; i++) { - _rgLines[i] = StringUtil.readUnicodeString(in); - } - } - - // bits 5-6 in the _flags specify the type - // of selection behavior this list control is expected to support - - // From [MS-XLS].pdf 2.5.147 FtLbsData: - // This array MUST exist if and only if the wListType field is not equal to 0. - if(((_flags >> 4) & 0x2) != 0) { - _bsels = new boolean[_cLines]; - for(int i=0; i < _cLines; i++) { - _bsels[i] = in.readByte() == 1; - } - } - - } - - LbsDataSubRecord(){ - - } - - /** - * - * @return a new instance of LbsDataSubRecord to construct auto-filters - * @see org.apache.poi.hssf.usermodel.HSSFCombobox - */ - public static LbsDataSubRecord newAutoFilterInstance(){ - LbsDataSubRecord lbs = new LbsDataSubRecord(); - lbs._cbFContinued = 0x1FEE; //autofilters seem to alway have this magic number - lbs._iSel = 0x000; - - lbs._flags = 0x0301; - lbs._dropData = new LbsDropData(); - lbs._dropData._wStyle = LbsDropData.STYLE_COMBO_SIMPLE_DROPDOWN; - - // the number of lines to be displayed in the dropdown - lbs._dropData._cLine = 8; - return lbs; - } - - /** - * @return true as LbsDataSubRecord is always the last sub-record - */ - @Override - public boolean isTerminating(){ - return true; - } - - @Override - protected int getDataSize() { - int result = 2; // 2 initial shorts - - // optional link formula - if (_linkPtg != null) { - result += 2; // encoded Ptg size - result += 4; // unknown int - result += _linkPtg.getSize(); - if (_unknownPostFormulaByte != null) { - result += 1; - } - } - - result += 4 * 2; // 4 shorts - if(_dropData != null) { - result += _dropData.getDataSize(); - } - if(_rgLines != null) { - for(String str : _rgLines){ - result += StringUtil.getEncodedSize(str); - } - } - if(_bsels != null) { - result += _bsels.length; - } - return result; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(_cbFContinued); - - if (_linkPtg == null) { - out.writeShort(0); - } else { - int formulaSize = _linkPtg.getSize(); - int linkSize = formulaSize + 6; - if (_unknownPostFormulaByte != null) { - linkSize++; - } - out.writeShort(linkSize); - out.writeShort(formulaSize); - out.writeInt(_unknownPreFormulaInt); - _linkPtg.write(out); - if (_unknownPostFormulaByte != null) { - out.writeByte(_unknownPostFormulaByte.intValue()); - } - } - - out.writeShort(_cLines); - out.writeShort(_iSel); - out.writeShort(_flags); - out.writeShort(_idEdit); - - if(_dropData != null) { - _dropData.serialize(out); - } - - if(_rgLines != null) { - for(String str : _rgLines){ - StringUtil.writeUnicodeString(out, str); - } - } - - if(_bsels != null) { - for(boolean val : _bsels){ - out.writeByte(val ? 1 : 0); - } - } - } - - @Override - public LbsDataSubRecord clone() { - // TODO: is immutable ??? - return this; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(256); - - sb.append("[ftLbsData]\n"); - sb.append(" .unknownShort1 =").append(HexDump.shortToHex(_cbFContinued)).append("\n"); - sb.append(" .formula = ").append('\n'); - if(_linkPtg != null) { - sb.append(_linkPtg.toString()).append(_linkPtg.getRVAType()).append('\n'); - } - sb.append(" .nEntryCount =").append(HexDump.shortToHex(_cLines)).append("\n"); - sb.append(" .selEntryIx =").append(HexDump.shortToHex(_iSel)).append("\n"); - sb.append(" .style =").append(HexDump.shortToHex(_flags)).append("\n"); - sb.append(" .unknownShort10=").append(HexDump.shortToHex(_idEdit)).append("\n"); - if(_dropData != null) { - sb.append('\n').append(_dropData.toString()); - } - sb.append("[/ftLbsData]\n"); - return sb.toString(); - } - - /** - * - * @return the formula that specifies the range of cell values that are the items in this list. - */ - public Ptg getFormula(){ - return _linkPtg; - } - - /** - * @return the number of items in the list - */ - public int getNumberOfItems(){ - return _cLines; - } - - /** - * This structure specifies properties of the dropdown list control - */ - public static class LbsDropData { - /** - * Combo dropdown control - */ - public static final int STYLE_COMBO_DROPDOWN = 0; - /** - * Combo Edit dropdown control - */ - public static final int STYLE_COMBO_EDIT_DROPDOWN = 1; - /** - * Simple dropdown control (just the dropdown button) - */ - public static final int STYLE_COMBO_SIMPLE_DROPDOWN = 2; - - /** - * An unsigned integer that specifies the style of this dropdown. - */ - private int _wStyle; - - /** - * An unsigned integer that specifies the number of lines to be displayed in the dropdown. - */ - private int _cLine; - - /** - * An unsigned integer that specifies the smallest width in pixels allowed for the dropdown window - */ - private int _dxMin; - - /** - * a string that specifies the current string value in the dropdown - */ - private final String _str; - - /** - * Optional, undefined and MUST be ignored. - * This field MUST exist if and only if the size of str in bytes is an odd number - */ - private Byte _unused; - - public LbsDropData(){ - _str = ""; - _unused = 0; - } - - public LbsDropData(LittleEndianInput in){ - _wStyle = in.readUShort(); - _cLine = in.readUShort(); - _dxMin = in.readUShort(); - _str = StringUtil.readUnicodeString(in); - if(StringUtil.getEncodedSize(_str) % 2 != 0){ - _unused = in.readByte(); - } - } - - /** - * Set the style of this dropdown.

    - * - * Possible values: - *

      - *
    • 0: Combo dropdown control
    • - *
    • 1: Combo Edit dropdown control
    • - *
    • 2: Simple dropdown control (just the dropdown button)
    • - *
    - * - * @param style the style - see possible values - */ - public void setStyle(int style){ - _wStyle = style; - } - - /** - * Set the number of lines to be displayed in the dropdown. - * - * @param num the number of lines to be displayed in the dropdown - */ - public void setNumLines(int num){ - _cLine = num; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_wStyle); - out.writeShort(_cLine); - out.writeShort(_dxMin); - StringUtil.writeUnicodeString(out, _str); - if(_unused != null) { - out.writeByte(_unused); - } - } - - public int getDataSize() { - int size = 6; - size += StringUtil.getEncodedSize(_str); - if(_unused != null) { - size++; - } - return size; - } - - @Override - public String toString(){ - StringBuffer sb = new StringBuffer(); - sb.append("[LbsDropData]\n"); - sb.append(" ._wStyle: ").append(_wStyle).append('\n'); - sb.append(" ._cLine: ").append(_cLine).append('\n'); - sb.append(" ._dxMin: ").append(_dxMin).append('\n'); - sb.append(" ._str: ").append(_str).append('\n'); - if(_unused != null) { - sb.append(" ._unused: ").append(_unused).append('\n'); - } - sb.append("[/LbsDropData]\n"); - - return sb.toString(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java b/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java deleted file mode 100644 index 6e8cb8fbb..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Record for the left margin. - */ -public final class LeftMarginRecord extends StandardRecord implements Margin, Cloneable { - public final static short sid = 0x0026; - private double field_1_margin; - - public LeftMarginRecord() { } - - public LeftMarginRecord(RecordInputStream in) - { - field_1_margin = in.readDouble(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - buffer.append( "[LeftMargin]\n" ); - buffer.append( " .margin = " ).append( " (" ).append( getMargin() ).append( " )\n" ); - buffer.append( "[/LeftMargin]\n" ); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeDouble(field_1_margin); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() { - return sid; - } - - /** - * Get the margin field for the LeftMargin record. - */ - public double getMargin() { - return field_1_margin; - } - - /** - * Set the margin field for the LeftMargin record. - */ - public void setMargin( double field_1_margin ) - { - this.field_1_margin = field_1_margin; - } - - @Override - public LeftMarginRecord clone() { - LeftMarginRecord rec = new LeftMarginRecord(); - rec.field_1_margin = this.field_1_margin; - return rec; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java b/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java deleted file mode 100644 index cc28f94d4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java +++ /dev/null @@ -1,120 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: MMS Record

    - * Description: defines how many add menu and del menu options are stored - * in the file. Should always be set to 0 for HSSF workbooks

    - * REFERENCE: PG 328 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ - -public final class MMSRecord - extends StandardRecord -{ - public final static short sid = 0xC1; - private byte field_1_addMenuCount; // = 0; - private byte field_2_delMenuCount; // = 0; - - public MMSRecord() - { - } - - public MMSRecord(RecordInputStream in) - { - if (in.remaining()==0) { - return; - } - - field_1_addMenuCount = in.readByte(); - field_2_delMenuCount = in.readByte(); - } - - /** - * set number of add menu options (set to 0) - * @param am number of add menu options - */ - - public void setAddMenuCount(byte am) - { - field_1_addMenuCount = am; - } - - /** - * set number of del menu options (set to 0) - * @param dm number of del menu options - */ - - public void setDelMenuCount(byte dm) - { - field_2_delMenuCount = dm; - } - - /** - * get number of add menu options (should be 0) - * @return number of add menu options - */ - - public byte getAddMenuCount() - { - return field_1_addMenuCount; - } - - /** - * get number of add del options (should be 0) - * @return number of add menu options - */ - - public byte getDelMenuCount() - { - return field_2_delMenuCount; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[MMS]\n"); - buffer.append(" .addMenu = ") - .append(Integer.toHexString(getAddMenuCount())).append("\n"); - buffer.append(" .delMenu = ") - .append(Integer.toHexString(getDelMenuCount())).append("\n"); - buffer.append("[/MMS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(getAddMenuCount()); - out.writeByte(getDelMenuCount()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/Margin.java b/trunk/src/java/org/apache/poi/hssf/record/Margin.java deleted file mode 100644 index 546db9838..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/Margin.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -/** - * The margin interface is a parent used to define left, right, top and bottom margins. - * This allows much of the code to be generic when it comes to handling margins. - */ -public interface Margin { - // TODO - introduce MarginBaseRecord - /** - * Get the margin field for the Margin. - * - * @return the margin - */ - public double getMargin(); - - /** - * Set the margin field for the Margin. - * - * @param field_1_margin the margin - */ - public void setMargin(double field_1_margin); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java deleted file mode 100644 index f9ebfd34a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Merged Cells Record (0x00E5)

    - * - * Description: Optional record defining a square area of cells to "merged" into one cell. - */ -public final class MergeCellsRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x00E5; - /** sometimes the regions array is shared with other MergedCellsRecords */ - private final CellRangeAddress[] _regions; - private final int _startIndex; - private final int _numberOfRegions; - - public MergeCellsRecord(CellRangeAddress[] regions, int startIndex, int numberOfRegions) { - _regions = regions; - _startIndex = startIndex; - _numberOfRegions = numberOfRegions; - } - /** - * Constructs a MergedCellsRecord and sets its fields appropriately - * @param in the RecordInputstream to read the record from - */ - public MergeCellsRecord(RecordInputStream in) { - int nRegions = in.readUShort(); - CellRangeAddress[] cras = new CellRangeAddress[nRegions]; - for (int i = 0; i < nRegions; i++) { - cras[i] = new CellRangeAddress(in); - } - _numberOfRegions = nRegions; - _startIndex = 0; - _regions = cras; - } - /** - * get the number of merged areas. If this drops down to 0 you should just go - * ahead and delete the record. - * @return number of areas - */ - public short getNumAreas() { - return (short)_numberOfRegions; - } - - /** - * @param index the n-th MergedRegion - * - * @return MergedRegion at the given index representing the area that is Merged (r1,c1 - r2,c2) - */ - public CellRangeAddress getAreaAt(int index) { - return _regions[_startIndex + index]; - } - - @Override - protected int getDataSize() { - return CellRangeAddressList.getEncodedSize(_numberOfRegions); - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - int nItems = _numberOfRegions; - out.writeShort(nItems); - for (int i = 0; i < _numberOfRegions; i++) { - _regions[_startIndex + i].serialize(out); - } - } - - @Override - public String toString() { - StringBuffer retval = new StringBuffer(); - - retval.append("[MERGEDCELLS]").append("\n"); - retval.append(" .numregions =").append(getNumAreas()).append("\n"); - for (int k = 0; k < _numberOfRegions; k++) { - CellRangeAddress r = _regions[_startIndex + k]; - - retval.append(" .rowfrom =").append(r.getFirstRow()).append("\n"); - retval.append(" .rowto =").append(r.getLastRow()).append("\n"); - retval.append(" .colfrom =").append(r.getFirstColumn()).append("\n"); - retval.append(" .colto =").append(r.getLastColumn()).append("\n"); - } - retval.append("[MERGEDCELLS]").append("\n"); - return retval.toString(); - } - - @Override - public MergeCellsRecord clone() { - int nRegions = _numberOfRegions; - CellRangeAddress[] clonedRegions = new CellRangeAddress[nRegions]; - for (int i = 0; i < clonedRegions.length; i++) { - clonedRegions[i] = _regions[_startIndex + i].copy(); - } - return new MergeCellsRecord(clonedRegions, 0, nRegions); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java b/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java deleted file mode 100644 index cbdcd2a93..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Multiple Blank cell record(0x00BE)

    - * Description: Represents a set of columns in a row with no value but with styling.

    - * - * REFERENCE: PG 329 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - * - * @see BlankRecord - */ -public final class MulBlankRecord extends StandardRecord { - public final static short sid = 0x00BE; - - private final int _row; - private final int _firstCol; - private final short[] _xfs; - private final int _lastCol; - - public MulBlankRecord(int row, int firstCol, short[] xfs) { - _row = row; - _firstCol = firstCol; - _xfs = xfs; - _lastCol = firstCol + xfs.length - 1; - } - - /** - * @return the row number of the cells this represents - */ - public int getRow() { - return _row; - } - - /** - * @return starting column (first cell this holds in the row). Zero based - */ - public int getFirstColumn() { - return _firstCol; - } - - /** - * @return ending column (last cell this holds in the row). Zero based - */ - public int getLastColumn() { - return _lastCol; - } - - /** - * get the number of columns this contains (last-first +1) - * @return number of columns (last - first +1) - */ - public int getNumColumns() { - return _lastCol - _firstCol + 1; - } - - /** - * returns the xf index for column (coffset = column - field_2_first_col) - * @param coffset the column (coffset = column - field_2_first_col) - * @return the XF index for the column - */ - public short getXFAt(int coffset) { - return _xfs[coffset]; - } - - /** - * @param in the RecordInputstream to read the record from - */ - public MulBlankRecord(RecordInputStream in) { - _row = in.readUShort(); - _firstCol = in.readShort(); - _xfs = parseXFs(in); - _lastCol = in.readShort(); - } - - private static short [] parseXFs(RecordInputStream in) { - short[] retval = new short[(in.remaining() - 2) / 2]; - - for (int idx = 0; idx < retval.length;idx++) { - retval[idx] = in.readShort(); - } - return retval; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[MULBLANK]\n"); - buffer.append("row = ").append(Integer.toHexString(getRow())).append("\n"); - buffer.append("firstcol = ").append(Integer.toHexString(getFirstColumn())).append("\n"); - buffer.append(" lastcol = ").append(Integer.toHexString(_lastCol)).append("\n"); - for (int k = 0; k < getNumColumns(); k++) { - buffer.append("xf").append(k).append(" = ").append( - Integer.toHexString(getXFAt(k))).append("\n"); - } - buffer.append("[/MULBLANK]\n"); - return buffer.toString(); - } - - public short getSid() { - return sid; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_row); - out.writeShort(_firstCol); - int nItems = _xfs.length; - for (int i = 0; i < nItems; i++) { - out.writeShort(_xfs[i]); - } - out.writeShort(_lastCol); - } - - protected int getDataSize() { - // 3 short fields + array of shorts - return 6 + _xfs.length * 2; - } - - @Override - public MulBlankRecord clone() { - // immutable - so OK to return this - return this; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java b/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java deleted file mode 100644 index 99420144c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java +++ /dev/null @@ -1,153 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.util.RKUtil; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * MULRK (0x00BD)

    - * - * Used to store multiple RK numbers on a row. 1 MulRk = Multiple Cell values. - * HSSF just converts this into multiple NUMBER records. READ-ONLY SUPPORT!

    - * REFERENCE: PG 330 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - * - * @since 2.0-pre - */ -public final class MulRKRecord extends StandardRecord { - public final static short sid = 0x00BD; - - private final int field_1_row; - private final short field_2_first_col; - private final RkRec[] field_3_rks; - private final short field_4_last_col; - - public int getRow() { - return field_1_row; - } - - /** - * starting column (first cell this holds in the row) - * @return first column number - */ - public short getFirstColumn() { - return field_2_first_col; - } - - /** - * ending column (last cell this holds in the row) - * @return first column number - */ - public short getLastColumn() { - return field_4_last_col; - } - - /** - * get the number of columns this contains (last-first +1) - * @return number of columns (last - first +1) - */ - public int getNumColumns() { - return field_4_last_col - field_2_first_col + 1; - } - - /** - * returns the xf index for column (coffset = column - field_2_first_col) - * - * @param coffset the coffset = column - field_2_first_col - * - * @return the XF index for the column - */ - public short getXFAt(int coffset) { - return field_3_rks[coffset].xf; - } - - /** - * returns the rk number for column (coffset = column - field_2_first_col) - * - * @param coffset the coffset = column - field_2_first_col - * - * @return the value (decoded into a double) - */ - public double getRKNumberAt(int coffset) { - return RKUtil.decodeNumber(field_3_rks[coffset].rk); - } - - /** - * @param in the RecordInputstream to read the record from - */ - public MulRKRecord(RecordInputStream in) { - field_1_row = in.readUShort(); - field_2_first_col = in.readShort(); - field_3_rks = RkRec.parseRKs(in); - field_4_last_col = in.readShort(); - } - - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[MULRK]\n"); - buffer.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n"); - buffer.append(" .firstcol= ").append(HexDump.shortToHex(getFirstColumn())).append("\n"); - buffer.append(" .lastcol = ").append(HexDump.shortToHex(getLastColumn())).append("\n"); - - for (int k = 0; k < getNumColumns(); k++) { - buffer.append(" xf[").append(k).append("] = ").append(HexDump.shortToHex(getXFAt(k))).append("\n"); - buffer.append(" rk[").append(k).append("] = ").append(getRKNumberAt(k)).append("\n"); - } - buffer.append("[/MULRK]\n"); - return buffer.toString(); - } - - @Override - public short getSid() - { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - throw new RecordFormatException( "Sorry, you can't serialize MulRK in this release"); - } - @Override - protected int getDataSize() { - throw new RecordFormatException( "Sorry, you can't serialize MulRK in this release"); - } - - private static final class RkRec { - public static final int ENCODED_SIZE = 6; - public final short xf; - public final int rk; - - private RkRec(RecordInputStream in) { - xf = in.readShort(); - rk = in.readInt(); - } - - public static RkRec[] parseRKs(RecordInputStream in) { - int nItems = (in.remaining()-2) / ENCODED_SIZE; - RkRec[] retval = new RkRec[nItems]; - for (int i=0; i - * - * Description: Defines a comment associated with a specified name. - */ -public final class NameCommentRecord extends StandardRecord { - public final static short sid = 0x0894; - - private final short field_1_record_type; - private final short field_2_frt_cell_ref_flag; - private final long field_3_reserved; - //private short field_4_name_length; - //private short field_5_comment_length; - private String field_6_name_text; - private String field_7_comment_text; - - public NameCommentRecord(final String name, final String comment) { - field_1_record_type = 0; - field_2_frt_cell_ref_flag = 0; - field_3_reserved = 0; - field_6_name_text = name; - field_7_comment_text = comment; - } - - @Override - public void serialize(final LittleEndianOutput out) { - final int field_4_name_length = field_6_name_text.length(); - final int field_5_comment_length = field_7_comment_text.length(); - - out.writeShort(field_1_record_type); - out.writeShort(field_2_frt_cell_ref_flag); - out.writeLong(field_3_reserved); - out.writeShort(field_4_name_length); - out.writeShort(field_5_comment_length); - - boolean isNameMultiByte = StringUtil.hasMultibyte(field_6_name_text); - out.writeByte(isNameMultiByte ? 1 : 0); - if (isNameMultiByte) { - StringUtil.putUnicodeLE(field_6_name_text, out); - } else { - StringUtil.putCompressedUnicode(field_6_name_text, out); - } - boolean isCommentMultiByte = StringUtil.hasMultibyte(field_7_comment_text); - out.writeByte(isCommentMultiByte ? 1 : 0); - if (isCommentMultiByte) { - StringUtil.putUnicodeLE(field_7_comment_text, out); - } else { - StringUtil.putCompressedUnicode(field_7_comment_text, out); - } - } - - @Override - protected int getDataSize() { - return 18 // 4 shorts + 1 long + 2 spurious 'nul's - + (StringUtil.hasMultibyte(field_6_name_text) ? field_6_name_text.length()*2 : field_6_name_text.length()) - + (StringUtil.hasMultibyte(field_7_comment_text) ? field_7_comment_text.length()*2 : field_7_comment_text.length()); - } - - /** - * @param ris the RecordInputstream to read the record from - */ - public NameCommentRecord(final RecordInputStream ris) { - final LittleEndianInput in = ris; - field_1_record_type = in.readShort(); - field_2_frt_cell_ref_flag = in.readShort(); - field_3_reserved = in.readLong(); - final int field_4_name_length = in.readShort(); - final int field_5_comment_length = in.readShort(); - - if (in.readByte() == 0) { - field_6_name_text = StringUtil.readCompressedUnicode(in, field_4_name_length); - } else { - field_6_name_text = StringUtil.readUnicodeLE(in, field_4_name_length); - } - if (in.readByte() == 0) { - field_7_comment_text = StringUtil.readCompressedUnicode(in, field_5_comment_length); - } else { - field_7_comment_text = StringUtil.readUnicodeLE(in, field_5_comment_length); - } - } - - /** - * return the non static version of the id for this record. - */ - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer(); - - sb.append("[NAMECMT]\n"); - sb.append(" .record type = ").append(HexDump.shortToHex(field_1_record_type)).append("\n"); - sb.append(" .frt cell ref flag = ").append(HexDump.byteToHex(field_2_frt_cell_ref_flag)).append("\n"); - sb.append(" .reserved = ").append(field_3_reserved).append("\n"); - sb.append(" .name length = ").append(field_6_name_text.length()).append("\n"); - sb.append(" .comment length = ").append(field_7_comment_text.length()).append("\n"); - sb.append(" .name = ").append(field_6_name_text).append("\n"); - sb.append(" .comment = ").append(field_7_comment_text).append("\n"); - sb.append("[/NAMECMT]\n"); - - return sb.toString(); - } - - /** - * @return the name of the NameRecord to which this comment applies. - */ - public String getNameText() { - return field_6_name_text; - } - - /** - * Updates the name we're associated with, normally used - * when renaming that Name - * - * @param newName the new name - */ - public void setNameText(String newName) { - field_6_name_text = newName; - } - - /** - * @return the text of the comment. - */ - public String getCommentText() { - return field_7_comment_text; - } - - public void setCommentText(String comment) { - field_7_comment_text = comment; - } - - public short getRecordType() { - return field_1_record_type; - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java b/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java deleted file mode 100644 index 613239bd5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java +++ /dev/null @@ -1,593 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.cont.ContinuableRecord; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.util.*; - -/** - * Title: DEFINEDNAME Record (0x0018)

    - * Description: Defines a named range within a workbook. - */ -public final class NameRecord extends ContinuableRecord { - public final static short sid = 0x0018; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_CONSOLIDATE_AREA = 1; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_AUTO_OPEN = 2; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_AUTO_CLOSE = 3; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_DATABASE = 4; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_CRITERIA = 5; - - public final static byte BUILTIN_PRINT_AREA = 6; - public final static byte BUILTIN_PRINT_TITLE = 7; - - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_RECORDER = 8; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_DATA_FORM = 9; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_AUTO_ACTIVATE = 10; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_AUTO_DEACTIVATE = 11; - /**Included for completeness sake, not implemented */ - public final static byte BUILTIN_SHEET_TITLE = 12; - - public final static byte BUILTIN_FILTER_DB = 13; - - private static final class Option { - public static final int OPT_HIDDEN_NAME = 0x0001; - public static final int OPT_FUNCTION_NAME = 0x0002; - public static final int OPT_COMMAND_NAME = 0x0004; - public static final int OPT_MACRO = 0x0008; - public static final int OPT_COMPLEX = 0x0010; - public static final int OPT_BUILTIN = 0x0020; - public static final int OPT_BINDATA = 0x1000; - public static final boolean isFormula(int optValue) { - return (optValue & 0x0F) == 0; - } - } - - private short field_1_option_flag; - private byte field_2_keyboard_shortcut; - /** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name */ - private short field_5_externSheetIndex_plus1; - /** the one based sheet number. */ - private int field_6_sheetNumber; - private boolean field_11_nameIsMultibyte; - private byte field_12_built_in_code; - private String field_12_name_text; - private Formula field_13_name_definition; - private String field_14_custom_menu_text; - private String field_15_description_text; - private String field_16_help_topic_text; - private String field_17_status_bar_text; - - - /** Creates new NameRecord */ - public NameRecord() { - field_13_name_definition = Formula.create(Ptg.EMPTY_PTG_ARRAY); - - field_12_name_text = ""; - field_14_custom_menu_text = ""; - field_15_description_text = ""; - field_16_help_topic_text = ""; - field_17_status_bar_text = ""; - } - - /** - * Constructor to create a built-in named region - * @param builtin Built-in byte representation for the name record, use the public constants - * @param sheetNumber the sheet which the name applies to - */ - public NameRecord(byte builtin, int sheetNumber) - { - this(); - field_12_built_in_code = builtin; - setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN)); - // the extern sheets are set through references - field_6_sheetNumber = sheetNumber; - } - - /** sets the option flag for the named range - * @param flag option flag - */ - public void setOptionFlag(short flag){ - field_1_option_flag = flag; - } - - - /** sets the keyboard shortcut - * @param shortcut keyboard shortcut - */ - public void setKeyboardShortcut(byte shortcut){ - field_2_keyboard_shortcut = shortcut; - } - - /** - * For named ranges, and built-in names - * @return the 1-based sheet number. - */ - public int getSheetNumber() - { - return field_6_sheetNumber; - } - - /** - * @return function group - * @see FnGroupCountRecord - */ - public byte getFnGroup() { - int masked = field_1_option_flag & 0x0fc0; - return (byte) (masked >> 4); - } - - - public void setSheetNumber(int value) - { - field_6_sheetNumber = value; - } - - - /** sets the name of the named range - * @param name named range name - */ - public void setNameText(String name){ - field_12_name_text = name; - field_11_nameIsMultibyte = StringUtil.hasMultibyte(name); - } - - /** sets the custom menu text - * @param text custom menu text - */ - public void setCustomMenuText(String text){ - field_14_custom_menu_text = text; - } - - /** sets the description text - * @param text the description text - */ - public void setDescriptionText(String text){ - field_15_description_text = text; - } - - /** sets the help topic text - * @param text help topix text - */ - public void setHelpTopicText(String text){ - field_16_help_topic_text = text; - } - - /** sets the status bar text - * @param text status bar text - */ - public void setStatusBarText(String text){ - field_17_status_bar_text = text; - } - - /** gets the option flag - * @return option flag - */ - public short getOptionFlag(){ - return field_1_option_flag; - } - - /** returns the keyboard shortcut - * @return keyboard shortcut - */ - public byte getKeyboardShortcut(){ - return field_2_keyboard_shortcut ; - } - - /** - * gets the name length, in characters - * @return name length - */ - private int getNameTextLength(){ - if (isBuiltInName()) { - return 1; - } - return field_12_name_text.length(); - } - - - /** - * @return true if name is hidden - */ - public boolean isHiddenName() { - return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0; - } - public void setHidden(boolean b) { - if (b) { - field_1_option_flag |= Option.OPT_HIDDEN_NAME; - } else { - field_1_option_flag &= (~Option.OPT_HIDDEN_NAME); - } - } - /** - * @return true if name is a function - */ - public boolean isFunctionName() { - return (field_1_option_flag & Option.OPT_FUNCTION_NAME) != 0; - } - - /** - * Indicates that the defined name refers to a user-defined function. - * This attribute is used when there is an add-in or other code project associated with the file. - * - * @param function true indicates the name refers to a function. - */ - public void setFunction(boolean function){ - if (function) { - field_1_option_flag |= Option.OPT_FUNCTION_NAME; - } else { - field_1_option_flag &= (~Option.OPT_FUNCTION_NAME); - } - } - - /** - * @return true if name has a formula (named range or defined value) - */ - public boolean hasFormula() { - return Option.isFormula(field_1_option_flag) && field_13_name_definition.getEncodedTokenSize() > 0; - } - - /** - * @return true if name is a command - */ - public boolean isCommandName() { - return (field_1_option_flag & Option.OPT_COMMAND_NAME) != 0; - } - /** - * @return true if function macro or command macro - */ - public boolean isMacro() { - return (field_1_option_flag & Option.OPT_MACRO) != 0; - } - /** - * @return true if array formula or user defined - */ - public boolean isComplexFunction() { - return (field_1_option_flag & Option.OPT_COMPLEX) != 0; - } - - /** - * Convenience Function to determine if the name is a built-in name - * - * @return true, if the name is a built-in name - */ - public boolean isBuiltInName() - { - return ((field_1_option_flag & Option.OPT_BUILTIN) != 0); - } - - - /** gets the name - * @return name - */ - public String getNameText(){ - - return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text; - } - - /** Gets the Built In Name - * @return the built in Name - */ - public byte getBuiltInName() - { - return field_12_built_in_code; - } - - - /** gets the definition, reference (Formula) - * @return the name formula. never null - */ - public Ptg[] getNameDefinition() { - return field_13_name_definition.getTokens(); - } - - public void setNameDefinition(Ptg[] ptgs) { - field_13_name_definition = Formula.create(ptgs); - } - - /** get the custom menu text - * @return custom menu text - */ - public String getCustomMenuText(){ - return field_14_custom_menu_text; - } - - /** gets the description text - * @return description text - */ - public String getDescriptionText(){ - return field_15_description_text; - } - - /** get the help topic text - * @return gelp topic text - */ - public String getHelpTopicText(){ - return field_16_help_topic_text; - } - - /** gets the status bar text - * @return status bar text - */ - public String getStatusBarText(){ - return field_17_status_bar_text; - } - - /** - * NameRecord can span into - * - * @param out a data output stream - */ - @Override - public void serialize(ContinuableRecordOutput out) { - - int field_7_length_custom_menu = field_14_custom_menu_text.length(); - int field_8_length_description_text = field_15_description_text.length(); - int field_9_length_help_topic_text = field_16_help_topic_text.length(); - int field_10_length_status_bar_text = field_17_status_bar_text.length(); - - // size defined below - out.writeShort(getOptionFlag()); - out.writeByte(getKeyboardShortcut()); - out.writeByte(getNameTextLength()); - // Note - formula size is not immediately before encoded formula, and does not include any array constant data - out.writeShort(field_13_name_definition.getEncodedTokenSize()); - out.writeShort(field_5_externSheetIndex_plus1); - out.writeShort(field_6_sheetNumber); - out.writeByte(field_7_length_custom_menu); - out.writeByte(field_8_length_description_text); - out.writeByte(field_9_length_help_topic_text); - out.writeByte(field_10_length_status_bar_text); - out.writeByte(field_11_nameIsMultibyte ? 1 : 0); - - if (isBuiltInName()) { - //can send the builtin name directly in - out.writeByte(field_12_built_in_code); - } else { - String nameText = field_12_name_text; - if (field_11_nameIsMultibyte) { - StringUtil.putUnicodeLE(nameText, out); - } else { - StringUtil.putCompressedUnicode(nameText, out); - } - } - field_13_name_definition.serializeTokens(out); - field_13_name_definition.serializeArrayConstantData(out); - - StringUtil.putCompressedUnicode( getCustomMenuText(), out); - StringUtil.putCompressedUnicode( getDescriptionText(), out); - StringUtil.putCompressedUnicode( getHelpTopicText(), out); - StringUtil.putCompressedUnicode( getStatusBarText(), out); - } - private int getNameRawSize() { - if (isBuiltInName()) { - return 1; - } - int nChars = field_12_name_text.length(); - if(field_11_nameIsMultibyte) { - return 2 * nChars; - } - return nChars; - } - - protected int getDataSize() { - return 13 // 3 shorts + 7 bytes - + getNameRawSize() - + field_14_custom_menu_text.length() - + field_15_description_text.length() - + field_16_help_topic_text.length() - + field_17_status_bar_text.length() - + field_13_name_definition.getEncodedSize(); - } - - /** gets the extern sheet number - * @return extern sheet index - */ - public int getExternSheetNumber(){ - Ptg[] tokens = field_13_name_definition.getTokens(); - if (tokens.length == 0) { - return 0; - } - - Ptg ptg = tokens[0]; - if (ptg.getClass() == Area3DPtg.class){ - return ((Area3DPtg) ptg).getExternSheetIndex(); - - } - if (ptg.getClass() == Ref3DPtg.class){ - return ((Ref3DPtg) ptg).getExternSheetIndex(); - } - return 0; - } - - /** - * called by the constructor, should set class level fields. Should throw - * runtime exception for bad/icomplete data. - * - * @param ris the RecordInputstream to read the record from - */ - public NameRecord(RecordInputStream ris) { - // YK: Formula data can span into continue records, for example, - // when containing a large array of strings. See Bugzilla 50244 - - // read all remaining bytes and wrap into a LittleEndianInput - byte[] remainder = ris.readAllContinuedRemainder(); - LittleEndianInput in = new LittleEndianByteArrayInputStream(remainder); - - field_1_option_flag = in.readShort(); - field_2_keyboard_shortcut = in.readByte(); - int field_3_length_name_text = in.readUByte(); - int field_4_length_name_definition = in.readShort(); - field_5_externSheetIndex_plus1 = in.readShort(); - field_6_sheetNumber = in.readUShort(); - int f7_customMenuLen = in.readUByte(); - int f8_descriptionTextLen = in.readUByte(); - int f9_helpTopicTextLen = in.readUByte(); - int f10_statusBarTextLen = in.readUByte(); - - //store the name in byte form if it's a built-in name - field_11_nameIsMultibyte = (in.readByte() != 0); - if (isBuiltInName()) { - field_12_built_in_code = in.readByte(); - } else { - if (field_11_nameIsMultibyte) { - field_12_name_text = StringUtil.readUnicodeLE(in, field_3_length_name_text); - } else { - field_12_name_text = StringUtil.readCompressedUnicode(in, field_3_length_name_text); - } - } - - int nBytesAvailable = in.available() - (f7_customMenuLen - + f8_descriptionTextLen + f9_helpTopicTextLen + f10_statusBarTextLen); - field_13_name_definition = Formula.read(field_4_length_name_definition, in, nBytesAvailable); - - //Who says that this can only ever be compressed unicode??? - field_14_custom_menu_text = StringUtil.readCompressedUnicode(in, f7_customMenuLen); - field_15_description_text = StringUtil.readCompressedUnicode(in, f8_descriptionTextLen); - field_16_help_topic_text = StringUtil.readCompressedUnicode(in, f9_helpTopicTextLen); - field_17_status_bar_text = StringUtil.readCompressedUnicode(in, f10_statusBarTextLen); - } - - /** - * return the non static version of the id for this record. - */ - @Override - public short getSid() { - return sid; - } - /* - 20 00 - 00 - 01 - 1A 00 // sz = 0x1A = 26 - 00 00 - 01 00 - 00 - 00 - 00 - 00 - 00 // unicode flag - 07 // name - - 29 17 00 3B 00 00 00 00 FF FF 00 00 02 00 3B 00 //{ 26 - 00 07 00 07 00 00 00 FF 00 10 // } - - - - 20 00 - 00 - 01 - 0B 00 // sz = 0xB = 11 - 00 00 - 01 00 - 00 - 00 - 00 - 00 - 00 // unicode flag - 07 // name - - 3B 00 00 07 00 07 00 00 00 FF 00 // { 11 } - */ - /* - 18, 00, - 1B, 00, - - 20, 00, - 00, - 01, - 0B, 00, - 00, - 00, - 00, - 00, - 00, - 07, - 3B 00 00 07 00 07 00 00 00 FF 00 ] - */ - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[NAME]\n"); - sb.append(" .option flags = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n"); - sb.append(" .keyboard shortcut = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n"); - sb.append(" .length of the name = ").append(getNameTextLength()).append("\n"); - sb.append(" .extSheetIx(1-based, 0=Global)= ").append( field_5_externSheetIndex_plus1 ).append("\n"); - sb.append(" .sheetTabIx = ").append(field_6_sheetNumber ).append("\n"); - sb.append(" .Menu text length = ").append(field_14_custom_menu_text.length()).append("\n"); - sb.append(" .Description text length= ").append(field_15_description_text.length()).append("\n"); - sb.append(" .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n"); - sb.append(" .Status bar text length = ").append(field_17_status_bar_text.length()).append("\n"); - sb.append(" .NameIsMultibyte = ").append(field_11_nameIsMultibyte).append("\n"); - sb.append(" .Name (Unicode text) = ").append( getNameText() ).append("\n"); - Ptg[] ptgs = field_13_name_definition.getTokens(); - sb.append(" .Formula (nTokens=").append(ptgs.length).append("):") .append("\n"); - for (Ptg ptg : ptgs) { - sb.append(" " + ptg.toString()).append(ptg.getRVAType()).append("\n"); - } - - sb.append(" .Menu text = ").append(field_14_custom_menu_text).append("\n"); - sb.append(" .Description text= ").append(field_15_description_text).append("\n"); - sb.append(" .Help topic text = ").append(field_16_help_topic_text).append("\n"); - sb.append(" .Status bar text = ").append(field_17_status_bar_text).append("\n"); - sb.append("[/NAME]\n"); - - return sb.toString(); - } - - /**Creates a human readable name for built in types - * @return Unknown if the built-in name cannot be translated - */ - private static String translateBuiltInName(byte name) - { - switch (name) - { - case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate"; - case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close"; - case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate"; - case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open"; - case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area"; - case NameRecord.BUILTIN_CRITERIA : return "Criteria"; - case NameRecord.BUILTIN_DATABASE : return "Database"; - case NameRecord.BUILTIN_DATA_FORM : return "Data_Form"; - case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area"; - case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles"; - case NameRecord.BUILTIN_RECORDER : return "Recorder"; - case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title"; - case NameRecord.BUILTIN_FILTER_DB : return "_FilterDatabase"; - - } - - return "Unknown"; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java b/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java deleted file mode 100644 index 1717444a7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java +++ /dev/null @@ -1,254 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * NOTE: Comment Associated with a Cell (0x001C) - */ -public final class NoteRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x001C; - - public static final NoteRecord[] EMPTY_ARRAY = { }; - - /** - * Flag indicating that the comment is hidden (default) - */ - public final static short NOTE_HIDDEN = 0x0; - - /** - * Flag indicating that the comment is visible - */ - public final static short NOTE_VISIBLE = 0x2; - - private static final Byte DEFAULT_PADDING = Byte.valueOf((byte)0); - - private int field_1_row; - private int field_2_col; - private short field_3_flags; - private int field_4_shapeid; - private boolean field_5_hasMultibyte; - private String field_6_author; - /** - * Saves padding byte value to reduce delta during round-trip serialization.
    - * - * The documentation is not clear about how padding should work. In any case - * Excel(2007) does something different. - */ - private Byte field_7_padding; - - /** - * Construct a new NoteRecord and - * fill its data with the default values - */ - public NoteRecord() { - field_6_author = ""; - field_3_flags = 0; - field_7_padding = DEFAULT_PADDING; // seems to be always present regardless of author text - } - - /** - * @return id of this record. - */ - public short getSid() { - return sid; - } - - /** - * Read the record data from the supplied RecordInputStream - * - * @param in the RecordInputStream to read from - */ - public NoteRecord(RecordInputStream in) { - field_1_row = in.readUShort(); - field_2_col = in.readShort(); - field_3_flags = in.readShort(); - field_4_shapeid = in.readUShort(); - int length = in.readShort(); - field_5_hasMultibyte = in.readByte() != 0x00; - if (field_5_hasMultibyte) { - field_6_author = StringUtil.readUnicodeLE(in, length); - } else { - field_6_author = StringUtil.readCompressedUnicode(in, length); - } - if (in.available() == 1) { - field_7_padding = Byte.valueOf(in.readByte()); - } else if (in.available() == 2 && length == 0) { - // If there's no author, may be double padded - field_7_padding = Byte.valueOf(in.readByte()); - in.readByte(); - } - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_row); - out.writeShort(field_2_col); - out.writeShort(field_3_flags); - out.writeShort(field_4_shapeid); - out.writeShort(field_6_author.length()); - out.writeByte(field_5_hasMultibyte ? 0x01 : 0x00); - if (field_5_hasMultibyte) { - StringUtil.putUnicodeLE(field_6_author, out); - } else { - StringUtil.putCompressedUnicode(field_6_author, out); - } - if (field_7_padding != null) { - out.writeByte(field_7_padding.intValue()); - } - } - - protected int getDataSize() { - return 11 // 5 shorts + 1 byte - + field_6_author.length() * (field_5_hasMultibyte ? 2 : 1) - + (field_7_padding == null ? 0 : 1); - } - - /** - * Convert this record to string. - * Used by BiffViewer and other utilities. - */ - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[NOTE]\n"); - buffer.append(" .row = ").append(field_1_row).append("\n"); - buffer.append(" .col = ").append(field_2_col).append("\n"); - buffer.append(" .flags = ").append(field_3_flags).append("\n"); - buffer.append(" .shapeid= ").append(field_4_shapeid).append("\n"); - buffer.append(" .author = ").append(field_6_author).append("\n"); - buffer.append("[/NOTE]\n"); - return buffer.toString(); - } - - /** - * Return the row that contains the comment - * - * @return the row that contains the comment - */ - public int getRow() { - return field_1_row; - } - - /** - * Specify the row that contains the comment - * - * @param row the row that contains the comment - */ - public void setRow(int row) { - field_1_row = row; - } - - /** - * Return the column that contains the comment - * - * @return the column that contains the comment - */ - public int getColumn() { - return field_2_col; - } - - /** - * Specify the column that contains the comment - * - * @param col the column that contains the comment - */ - public void setColumn(int col) { - field_2_col = col; - } - - /** - * Options flags. - * - * @return the options flag - * @see #NOTE_VISIBLE - * @see #NOTE_HIDDEN - */ - public short getFlags() { - return field_3_flags; - } - - /** - * Options flag - * - * @param flags the options flag - * @see #NOTE_VISIBLE - * @see #NOTE_HIDDEN - */ - public void setFlags(short flags) { - field_3_flags = flags; - } - - /** - * For unit testing only! - * - * @return true, if author element uses multi byte - */ - protected boolean authorIsMultibyte() { - return field_5_hasMultibyte; - } - - /** - * Object id for OBJ record that contains the comment - * - * @return the Object id for OBJ record that contains the comment - */ - public int getShapeId() { - return field_4_shapeid; - } - - /** - * Object id for OBJ record that contains the comment - * - * @param id the Object id for OBJ record that contains the comment - */ - public void setShapeId(int id) { - field_4_shapeid = id; - } - - /** - * Name of the original comment author - * - * @return the name of the original author of the comment - */ - public String getAuthor() { - return field_6_author; - } - - /** - * Name of the original comment author - * - * @param author the name of the original author of the comment - */ - public void setAuthor(String author) { - field_6_author = author; - field_5_hasMultibyte = StringUtil.hasMultibyte(author); - } - - @Override - public NoteRecord clone() { - NoteRecord rec = new NoteRecord(); - rec.field_1_row = field_1_row; - rec.field_2_col = field_2_col; - rec.field_3_flags = field_3_flags; - rec.field_4_shapeid = field_4_shapeid; - rec.field_6_author = field_6_author; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java deleted file mode 100644 index b2c18781e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ftNts (0x000D)

    - * Represents a NoteStructure sub record.

    - * - * The docs say nothing about it. The length of this record is always 26 bytes. - */ -public final class NoteStructureSubRecord extends SubRecord implements Cloneable { - public final static short sid = 0x0D; - private static final int ENCODED_SIZE = 22; - - private byte[] reserved; - - /** - * Construct a new NoteStructureSubRecord and - * fill its data with the default values - */ - public NoteStructureSubRecord() - { - //all we know is that the the length of NoteStructureSubRecord is always 22 bytes - reserved = new byte[ENCODED_SIZE]; - } - - /** - * Read the record data from the supplied RecordInputStream - * - * @param in the input to read from - * @param size the provided size - must be 22 - */ - public NoteStructureSubRecord(LittleEndianInput in, int size) { - if (size != ENCODED_SIZE) { - throw new RecordFormatException("Unexpected size (" + size + ")"); - } - //just grab the raw data - byte[] buf = new byte[size]; - in.readFully(buf); - reserved = buf; - } - - /** - * Convert this record to string. - * Used by BiffViewer and other utilities. - */ - @Override - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ftNts ]").append("\n"); - buffer.append(" size = ").append(getDataSize()).append("\n"); - buffer.append(" reserved = ").append(HexDump.toHex(reserved)).append("\n"); - buffer.append("[/ftNts ]").append("\n"); - return buffer.toString(); - } - - /** - * Serialize the record data into the supplied array of bytes - * - * @param out the stream to serialize into - */ - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); - out.writeShort(reserved.length); - out.write(reserved); - } - - @Override - protected int getDataSize() { - return reserved.length; - } - - /** - * @return id of this record. - */ - public short getSid() - { - return sid; - } - - @Override - public NoteStructureSubRecord clone() { - NoteStructureSubRecord rec = new NoteStructureSubRecord(); - byte[] recdata = new byte[reserved.length]; - System.arraycopy(reserved, 0, recdata, 0, recdata.length); - rec.reserved = recdata; - return rec; - } - -} - - diff --git a/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java b/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java deleted file mode 100644 index ebc6d9e3f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.util.NumberToTextConverter; -import org.apache.poi.util.LittleEndianOutput; - -/** - * NUMBER (0x0203) Contains a numeric cell value.

    - * REFERENCE: PG 334 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class NumberRecord extends CellRecord implements Cloneable { - public static final short sid = 0x0203; - private double field_4_value; - - /** Creates new NumberRecord */ - public NumberRecord() { - // fields uninitialised - } - - /** - * @param in the RecordInputstream to read the record from - */ - public NumberRecord(RecordInputStream in) { - super(in); - field_4_value = in.readDouble(); - } - - /** - * set the value for the cell - * - * @param value double representing the value - */ - public void setValue(double value){ - field_4_value = value; - } - - /** - * get the value for the cell - * - * @return double representing the value - */ - public double getValue(){ - return field_4_value; - } - - @Override - protected String getRecordName() { - return "NUMBER"; - } - - @Override - protected void appendValueText(StringBuilder sb) { - sb.append(" .value= ").append(NumberToTextConverter.toText(field_4_value)); - } - - @Override - protected void serializeValue(LittleEndianOutput out) { - out.writeDouble(getValue()); - } - - @Override - protected int getValueDataSize() { - return 8; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public NumberRecord clone() { - NumberRecord rec = new NumberRecord(); - copyBaseFields(rec); - rec.field_4_value = field_4_value; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java deleted file mode 100644 index 8eb4e03af..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java +++ /dev/null @@ -1,232 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayInputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianInputStream; - -/** - * OBJRECORD (0x005D)

    - * - * The obj record is used to hold various graphic objects and controls. - */ -public final class ObjRecord extends Record implements Cloneable { - public final static short sid = 0x005D; - - private static final int NORMAL_PAD_ALIGNMENT = 2; - private static int MAX_PAD_ALIGNMENT = 4; - - private List subrecords; - /** used when POI has no idea what is going on */ - private final byte[] _uninterpretedData; - /** - * Excel seems to tolerate padding to quad or double byte length - */ - private boolean _isPaddedToQuadByteMultiple; - - //00000000 15 00 12 00 01 00 01 00 11 60 00 00 00 00 00 0D .........`...... - //00000010 26 01 00 00 00 00 00 00 00 00 &......... - - - public ObjRecord() { - subrecords = new ArrayList(2); - // TODO - ensure 2 sub-records (ftCmo 15h, and ftEnd 00h) are always created - _uninterpretedData = null; - } - - public ObjRecord(RecordInputStream in) { - // TODO - problems with OBJ sub-records stream - // MS spec says first sub-record is always CommonObjectDataSubRecord, - // and last is - // always EndSubRecord. OOO spec does not mention ObjRecord(0x005D). - // Existing POI test data seems to violate that rule. Some test data - // seems to contain - // garbage, and a crash is only averted by stopping at what looks like - // the 'EndSubRecord' - - // Check if this can be continued, if so then the - // following wont work properly - byte[] subRecordData = in.readRemainder(); - if (LittleEndian.getUShort(subRecordData, 0) != CommonObjectDataSubRecord.sid) { - // seems to occur in just one junit on "OddStyleRecord.xls" (file created by CrystalReports) - // Excel tolerates the funny ObjRecord, and replaces it with a corrected version - // The exact logic/reasoning is not yet understood - _uninterpretedData = subRecordData; - subrecords = null; - return; - } - - //YK: files produced by OO violate the condition below - /* - if (subRecordData.length % 2 != 0) { - String msg = "Unexpected length of subRecordData : " + HexDump.toHex(subRecordData); - throw new RecordFormatException(msg); - } - */ - - subrecords = new ArrayList(); - ByteArrayInputStream bais = new ByteArrayInputStream(subRecordData); - LittleEndianInputStream subRecStream = new LittleEndianInputStream(bais); - CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)SubRecord.createSubRecord(subRecStream, 0); - subrecords.add(cmo); - while (true) { - SubRecord subRecord = SubRecord.createSubRecord(subRecStream, cmo.getObjectType()); - subrecords.add(subRecord); - if (subRecord.isTerminating()) { - break; - } - } - int nRemainingBytes = bais.available(); - if (nRemainingBytes > 0) { - // At present (Oct-2008), most unit test samples have (subRecordData.length % 2 == 0) - _isPaddedToQuadByteMultiple = subRecordData.length % MAX_PAD_ALIGNMENT == 0; - if (nRemainingBytes >= (_isPaddedToQuadByteMultiple ? MAX_PAD_ALIGNMENT : NORMAL_PAD_ALIGNMENT)) { - if (!canPaddingBeDiscarded(subRecordData, nRemainingBytes)) { - String msg = "Leftover " + nRemainingBytes - + " bytes in subrecord data " + HexDump.toHex(subRecordData); - throw new RecordFormatException(msg); - } - _isPaddedToQuadByteMultiple = false; - } - - } else { - _isPaddedToQuadByteMultiple = false; - } - _uninterpretedData = null; - } - - /** - * Some XLS files have ObjRecords with nearly 8Kb of excessive padding. These were probably - * written by a version of POI (around 3.1) which incorrectly interpreted the second short of - * the ftLbs subrecord (0x1FEE) as a length, and read that many bytes as padding (other bugs - * helped allow this to occur). - * - * Excel reads files with this excessive padding OK, truncating the over-sized ObjRecord back - * to the its proper size. POI does the same. - */ - private static boolean canPaddingBeDiscarded(byte[] data, int nRemainingBytes) { - // make sure none of the padding looks important - for(int i=data.length-nRemainingBytes; i=0; i--) { - SubRecord record = subrecords.get(i); - size += record.getDataSize()+4; - } - if (_isPaddedToQuadByteMultiple) { - while (size % MAX_PAD_ALIGNMENT != 0) { - size++; - } - } else { - while (size % NORMAL_PAD_ALIGNMENT != 0) { - size++; - } - } - return size + 4; - } - - @Override - public int serialize(int offset, byte[] data) { - int recSize = getRecordSize(); - int dataSize = recSize - 4; - LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize); - - out.writeShort(sid); - out.writeShort(dataSize); - - if (_uninterpretedData == null) { - - for (int i = 0; i < subrecords.size(); i++) { - SubRecord record = subrecords.get(i); - record.serialize(out); - } - int expectedEndIx = offset+dataSize; - // padding - while (out.getWriteIndex() < expectedEndIx) { - out.writeByte(0); - } - } else { - out.write(_uninterpretedData); - } - return recSize; - } - - @Override - public short getSid() { - return sid; - } - - public List getSubRecords() { - return subrecords; - } - - public void clearSubRecords() { - subrecords.clear(); - } - - public void addSubRecord(int index, SubRecord element) { - subrecords.add(index, element); - } - - public boolean addSubRecord(SubRecord o) { - return subrecords.add(o); - } - - @Override - public ObjRecord clone() { - ObjRecord rec = new ObjRecord(); - - for (int i = 0; i < subrecords.size(); i++) { - SubRecord record = subrecords.get(i); - rec.addSubRecord((SubRecord) record.clone()); - } - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java deleted file mode 100644 index 06aab4485..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java +++ /dev/null @@ -1,104 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Object Protect Record

    - * Description: Protect embedded object with the lamest "security" ever invented. - * This record tells "I want to protect my objects" with lame security. It - * appears in conjunction with the PASSWORD and PROTECT records as well as its - * scenario protect cousin.

    - * REFERENCE: PG 368 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - */ - -public final class ObjectProtectRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x63; - private short field_1_protect; - - public ObjectProtectRecord() - { - } - - public ObjectProtectRecord(RecordInputStream in) - { - field_1_protect = in.readShort(); - } - - /** - * set whether the sheet is protected or not - * @param protect whether to protect the sheet or not - */ - - public void setProtect(boolean protect) - { - if (protect) - { - field_1_protect = 1; - } - else - { - field_1_protect = 0; - } - } - - /** - * get whether the sheet is protected or not - * @return whether to protect the sheet or not - */ - - public boolean getProtect() - { - return (field_1_protect == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SCENARIOPROTECT]\n"); - buffer.append(" .protect = ").append(getProtect()) - .append("\n"); - buffer.append("[/SCENARIOPROTECT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_protect); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public ObjectProtectRecord clone() { - ObjectProtectRecord rec = new ObjectProtectRecord(); - rec.field_1_protect = field_1_protect; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/OldCellRecord.java b/trunk/src/java/org/apache/poi/hssf/record/OldCellRecord.java deleted file mode 100644 index 76f2dd300..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/OldCellRecord.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; - -/** - * Base class for all old (Biff 2 - Biff 4) cell value records - * (implementors of {@link CellValueRecordInterface}). - * Subclasses are expected to manage the cell data values (of various types). - */ -public abstract class OldCellRecord { - private final short sid; - private final boolean isBiff2; - private final int field_1_row; - private final short field_2_column; - private int field_3_cell_attrs; // Biff 2 - private short field_3_xf_index; // Biff 3+ - - protected OldCellRecord(RecordInputStream in, boolean isBiff2) { - this.sid = in.getSid(); - this.isBiff2 = isBiff2; - field_1_row = in.readUShort(); - field_2_column = in.readShort(); - - if (isBiff2) { - field_3_cell_attrs = in.readUShort() << 8; - field_3_cell_attrs += in.readUByte(); - } else { - field_3_xf_index = in.readShort(); - } - } - - public final int getRow() { - return field_1_row; - } - - public final short getColumn() { - return field_2_column; - } - - /** - * get the index to the ExtendedFormat, for non-Biff2 - * - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @return index to the XF record - */ - public final short getXFIndex() { - return field_3_xf_index; - } - - public int getCellAttrs() - { - return field_3_cell_attrs; - } - - /** - * Is this a Biff2 record, or newer? - * - * @return true, if this is a Biff2 record or newer - */ - public boolean isBiff2() { - return isBiff2; - } - - public short getSid() { - return sid; - } - - @Override - public final String toString() { - StringBuilder sb = new StringBuilder(); - String recordName = getRecordName(); - - sb.append("[").append(recordName).append("]\n"); - sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n"); - sb.append(" .col = ").append(HexDump.shortToHex(getColumn())).append("\n"); - if (isBiff2()) { - sb.append(" .cellattrs = ").append(HexDump.shortToHex(getCellAttrs())).append("\n"); - } else { - sb.append(" .xfindex = ").append(HexDump.shortToHex(getXFIndex())).append("\n"); - } - appendValueText(sb); - sb.append("\n"); - sb.append("[/").append(recordName).append("]\n"); - return sb.toString(); - } - - /** - * Append specific debug info (used by {@link #toString()} for the value - * contained in this record. Trailing new-line should not be appended - * (superclass does that). - * - * @param sb the StringBuilder to append to - */ - protected abstract void appendValueText(StringBuilder sb); - - /** - * Gets the debug info BIFF record type name (used by {@link #toString()}. - * - * @return the debug info BIFF record type name - */ - protected abstract String getRecordName(); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/OldFormulaRecord.java b/trunk/src/java/org/apache/poi/hssf/record/OldFormulaRecord.java deleted file mode 100644 index 365059f47..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/OldFormulaRecord.java +++ /dev/null @@ -1,113 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.FormulaRecord.SpecialCachedValue; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.CellType; - -/** - * Formula Record (0x0006 / 0x0206 / 0x0406) - holds a formula in - * encoded form, along with the value if a number - */ -public final class OldFormulaRecord extends OldCellRecord { - public final static short biff2_sid = 0x0006; - public final static short biff3_sid = 0x0206; - public final static short biff4_sid = 0x0406; - public final static short biff5_sid = 0x0006; - - private SpecialCachedValue specialCachedValue; - private double field_4_value; - private short field_5_options; - private Formula field_6_parsed_expr; - - public OldFormulaRecord(RecordInputStream ris) { - super(ris, ris.getSid() == biff2_sid); - - if (isBiff2()) { - field_4_value = ris.readDouble(); - } else { - long valueLongBits = ris.readLong(); - specialCachedValue = SpecialCachedValue.create(valueLongBits); - if (specialCachedValue == null) { - field_4_value = Double.longBitsToDouble(valueLongBits); - } - } - - if (isBiff2()) { - field_5_options = (short)ris.readUByte(); - } else { - field_5_options = ris.readShort(); - } - - int expression_len = ris.readShort(); - int nBytesAvailable = ris.available(); - field_6_parsed_expr = Formula.read(expression_len, ris, nBytesAvailable); - } - - public int getCachedResultType() { - if (specialCachedValue == null) { - return CellType.NUMERIC.getCode(); - } - return specialCachedValue.getValueType(); - } - - public boolean getCachedBooleanValue() { - return specialCachedValue.getBooleanValue(); - } - public int getCachedErrorValue() { - return specialCachedValue.getErrorValue(); - } - - /** - * get the calculated value of the formula - * - * @return calculated value - */ - public double getValue() { - return field_4_value; - } - - /** - * get the option flags - * - * @return bitmask - */ - public short getOptions() { - return field_5_options; - } - - /** - * @return the formula tokens. never null - */ - public Ptg[] getParsedExpression() { - return field_6_parsed_expr.getTokens(); - } - - public Formula getFormula() { - return field_6_parsed_expr; - } - - protected void appendValueText(StringBuilder sb) { - sb.append(" .value = ").append(getValue()).append("\n"); - } - protected String getRecordName() { - return "Old Formula"; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/OldLabelRecord.java b/trunk/src/java/org/apache/poi/hssf/record/OldLabelRecord.java deleted file mode 100644 index c12374933..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/OldLabelRecord.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Biff2 - Biff 4 Label Record (0x0004 / 0x0204) - read only support for - * strings stored directly in the cell, from the older file formats that - * didn't use {@link LabelSSTRecord} - */ -public final class OldLabelRecord extends OldCellRecord { - private final static POILogger logger = POILogFactory.getLogger(OldLabelRecord.class); - - public final static short biff2_sid = 0x0004; - public final static short biff345_sid = 0x0204; - - private short field_4_string_len; - private final byte[] field_5_bytes; - private CodepageRecord codepage; - - /** - * @param in the RecordInputstream to read the record from - */ - public OldLabelRecord(RecordInputStream in) - { - super(in, in.getSid() == biff2_sid); - - if (isBiff2()) { - field_4_string_len = (short)in.readUByte(); - } else { - field_4_string_len = in.readShort(); - } - - // Can only decode properly later when you know the codepage - field_5_bytes = new byte[field_4_string_len]; - in.read(field_5_bytes, 0, field_4_string_len); - - if (in.remaining() > 0) { - logger.log(POILogger.INFO, - "LabelRecord data remains: " + in.remaining() + - " : " + HexDump.toHex(in.readRemainder()) - ); - } - } - - public void setCodePage(CodepageRecord codepage) { - this.codepage = codepage; - } - - /** - * get the number of characters this string contains - * @return number of characters - */ - public short getStringLength() - { - return field_4_string_len; - } - - /** - * Get the String of the cell - * - * @return the String of the cell - */ - public String getValue() - { - return OldStringRecord.getString(field_5_bytes, codepage); - } - - /** - * Not supported - * - * @param offset not supported - * @param data not supported - * @return not supported - */ - public int serialize(int offset, byte [] data) { - throw new RecordFormatException("Old Label Records are supported READ ONLY"); - } - - public int getRecordSize() { - throw new RecordFormatException("Old Label Records are supported READ ONLY"); - } - - @Override - protected void appendValueText(StringBuilder sb) { - sb.append(" .string_len= ").append(HexDump.shortToHex(field_4_string_len)).append("\n"); - sb.append(" .value = ").append(getValue()).append("\n"); - } - - @Override - protected String getRecordName() { - return "OLD LABEL"; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/OldSheetRecord.java b/trunk/src/java/org/apache/poi/hssf/record/OldSheetRecord.java deleted file mode 100644 index 92ffcf923..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/OldSheetRecord.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; - -/** - * Title: Bound Sheet Record (aka BundleSheet) (0x0085) for BIFF 5

    - * Description: Defines a sheet within a workbook. Basically stores the sheet name - * and tells where the Beginning of file record is within the HSSF - * file. - */ -public final class OldSheetRecord { - public final static short sid = 0x0085; - - private int field_1_position_of_BOF; - private int field_2_visibility; - private int field_3_type; - private byte[] field_5_sheetname; - private CodepageRecord codepage; - - public OldSheetRecord(RecordInputStream in) { - field_1_position_of_BOF = in.readInt(); - field_2_visibility = in.readUByte(); - field_3_type = in.readUByte(); - int field_4_sheetname_length = in.readUByte(); - field_5_sheetname = new byte[field_4_sheetname_length]; - in.read(field_5_sheetname, 0, field_4_sheetname_length); - } - - public void setCodePage(CodepageRecord codepage) { - this.codepage = codepage; - } - - public short getSid() { - return sid; - } - - /** - * get the offset in bytes of the Beginning of File Marker within the HSSF Stream part of the POIFS file - * - * @return offset in bytes - */ - public int getPositionOfBof() { - return field_1_position_of_BOF; - } - - /** - * get the sheetname for this sheet. (this appears in the tabs at the bottom) - * @return sheetname the name of the sheet - */ - public String getSheetname() { - return OldStringRecord.getString(field_5_sheetname, codepage); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BOUNDSHEET]\n"); - buffer.append(" .bof = ").append(HexDump.intToHex(getPositionOfBof())).append("\n"); - buffer.append(" .visibility = ").append(HexDump.shortToHex(field_2_visibility)).append("\n"); - buffer.append(" .type = ").append(HexDump.byteToHex(field_3_type)).append("\n"); - buffer.append(" .sheetname = ").append(getSheetname()).append("\n"); - buffer.append("[/BOUNDSHEET]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/OldStringRecord.java b/trunk/src/java/org/apache/poi/hssf/record/OldStringRecord.java deleted file mode 100644 index 4964f8480..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/OldStringRecord.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.UnsupportedEncodingException; - -import org.apache.poi.util.CodePageUtil; - - -/** - * Biff2 - Biff 4 Label Record (0x0007 / 0x0207) - read only support for - * formula string results. - */ -public final class OldStringRecord { - public final static short biff2_sid = 0x0007; - public final static short biff345_sid = 0x0207; - - private short sid; - private short field_1_string_len; - private byte[] field_2_bytes; - private CodepageRecord codepage; - - /** - * @param in the RecordInputstream to read the record from - */ - public OldStringRecord(RecordInputStream in) { - sid = in.getSid(); - - if (in.getSid() == biff2_sid) { - field_1_string_len = (short)in.readUByte(); - } else { - field_1_string_len = in.readShort(); - } - - // Can only decode properly later when you know the codepage - field_2_bytes = new byte[field_1_string_len]; - in.read(field_2_bytes, 0, field_1_string_len); - } - - public boolean isBiff2() { - return sid == biff2_sid; - } - - public short getSid() { - return sid; - } - - public void setCodePage(CodepageRecord codepage) { - this.codepage = codepage; - } - - /** - * @return The string represented by this record. - */ - public String getString() - { - return getString(field_2_bytes, codepage); - } - - protected static String getString(byte[] data, CodepageRecord codepage) { - int cp = CodePageUtil.CP_ISO_8859_1; - if (codepage != null) { - cp = codepage.getCodepage() & 0xffff; - } - try { - return CodePageUtil.getStringFromCodePage(data, cp); - } catch (UnsupportedEncodingException uee) { - throw new IllegalArgumentException("Unsupported codepage requested", uee); - } - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[OLD STRING]\n"); - buffer.append(" .string = ") - .append(getString()).append("\n"); - buffer.append("[/OLD STRING]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PageBreakRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PageBreakRecord.java deleted file mode 100644 index fe182d05c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PageBreakRecord.java +++ /dev/null @@ -1,209 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.poi.util.LittleEndianOutput; - -/** - *

    Record that contains the functionality page breaks (horizontal and vertical)

    - * - *

    The other two classes just specifically set the SIDS for record creation.

    - * - *

    REFERENCE: Microsoft Excel SDK page 322 and 420

    - * - * @see HorizontalPageBreakRecord - * @see VerticalPageBreakRecord - * @author Danny Mui (dmui at apache dot org) - */ -public abstract class PageBreakRecord extends StandardRecord { - private static final int[] EMPTY_INT_ARRAY = { }; - - private List _breaks; - private Map _breakMap; - - /** - * Since both records store 2byte integers (short), no point in - * differentiating it in the records. - *

    - * The subs (rows or columns, don't seem to be able to set but excel sets - * them automatically) - */ - public static final class Break { - - public static final int ENCODED_SIZE = 6; - public int main; - public int subFrom; - public int subTo; - - public Break(int main, int subFrom, int subTo) - { - this.main = main; - this.subFrom = subFrom; - this.subTo = subTo; - } - - public Break(RecordInputStream in) { - main = in.readUShort() - 1; - subFrom = in.readUShort(); - subTo = in.readUShort(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(main + 1); - out.writeShort(subFrom); - out.writeShort(subTo); - } - } - - protected PageBreakRecord() { - _breaks = new ArrayList(); - _breakMap = new HashMap(); - } - - public PageBreakRecord(RecordInputStream in) - { - int nBreaks = in.readShort(); - _breaks = new ArrayList(nBreaks + 2); - _breakMap = new HashMap(); - - for(int k = 0; k < nBreaks; k++) { - Break br = new Break(in); - _breaks.add(br); - _breakMap.put(Integer.valueOf(br.main), br); - } - - } - - public boolean isEmpty() { - return _breaks.isEmpty(); - } - protected int getDataSize() { - return 2 + _breaks.size() * Break.ENCODED_SIZE; - } - - public final void serialize(LittleEndianOutput out) { - int nBreaks = _breaks.size(); - out.writeShort(nBreaks); - for (int i=0; i getBreaksIterator() { - return _breaks.iterator(); - } - - public String toString() { - StringBuffer retval = new StringBuffer(); - - String label; - String mainLabel; - String subLabel; - - if (getSid() == HorizontalPageBreakRecord.sid) { - label = "HORIZONTALPAGEBREAK"; - mainLabel = "row"; - subLabel = "col"; - } else { - label = "VERTICALPAGEBREAK"; - mainLabel = "column"; - subLabel = "row"; - } - - retval.append("["+label+"]").append("\n"); - retval.append(" .sid =").append(getSid()).append("\n"); - retval.append(" .numbreaks =").append(getNumBreaks()).append("\n"); - Iterator iterator = getBreaksIterator(); - for(int k = 0; k < getNumBreaks(); k++) - { - Break region = iterator.next(); - - retval.append(" .").append(mainLabel).append(" (zero-based) =").append(region.main).append("\n"); - retval.append(" .").append(subLabel).append("From =").append(region.subFrom).append("\n"); - retval.append(" .").append(subLabel).append("To =").append(region.subTo).append("\n"); - } - - retval.append("["+label+"]").append("\n"); - return retval.toString(); - } - - /** - * Adds the page break at the specified parameters - * @param main Depending on sid, will determine row or column to put page break (zero-based) - * @param subFrom No user-interface to set (defaults to minimum, 0) - * @param subTo No user-interface to set - */ - public void addBreak(int main, int subFrom, int subTo) { - - Integer key = Integer.valueOf(main); - Break region = _breakMap.get(key); - if(region == null) { - region = new Break(main, subFrom, subTo); - _breakMap.put(key, region); - _breaks.add(region); - } else { - region.main = main; - region.subFrom = subFrom; - region.subTo = subTo; - } - } - - /** - * Removes the break indicated by the parameter - * @param main (zero-based) - */ - public final void removeBreak(int main) { - Integer rowKey = Integer.valueOf(main); - Break region = _breakMap.get(rowKey); - _breaks.remove(region); - _breakMap.remove(rowKey); - } - - /** - * Retrieves the region at the row/column indicated - * @param main FIXME: Document this! - * @return The Break or null if no break exists at the row/col specified. - */ - public final Break getBreak(int main) { - Integer rowKey = Integer.valueOf(main); - return _breakMap.get(rowKey); - } - - public final int[] getBreaks() { - int count = getNumBreaks(); - if (count < 1) { - return EMPTY_INT_ARRAY; - } - int[] result = new int[count]; - for (int i=0; i _colors; - - public PaletteRecord() { - PColor[] defaultPalette = createDefaultPalette(); - _colors = new ArrayList(defaultPalette.length); - for (PColor element : defaultPalette) { - _colors.add(element); - } - } - - public PaletteRecord(RecordInputStream in) { - int field_1_numcolors = in.readShort(); - _colors = new ArrayList(field_1_numcolors); - for (int k = 0; k < field_1_numcolors; k++) { - _colors.add(new PColor(in)); - } - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PALETTE]\n"); - buffer.append(" numcolors = ").append(_colors.size()).append('\n'); - for (int i = 0; i < _colors.size(); i++) { - PColor c = _colors.get(i); - buffer.append("* colornum = ").append(i).append('\n'); - buffer.append(c.toString()); - buffer.append("/*colornum = ").append(i).append('\n'); - } - buffer.append("[/PALETTE]\n"); - return buffer.toString(); - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(_colors.size()); - for (int i = 0; i < _colors.size(); i++) { - _colors.get(i).serialize(out); - } - } - - @Override - protected int getDataSize() { - return 2 + _colors.size() * PColor.ENCODED_SIZE; - } - - @Override - public short getSid() { - return sid; - } - - /** - * Returns the color value at a given index - * - * @param byteIndex palette index, must be >= 0x8 - * - * @return the RGB triplet for the color, or null if the specified index - * does not exist - */ - public byte[] getColor(int byteIndex) { - int i = byteIndex - FIRST_COLOR_INDEX; - if (i < 0 || i >= _colors.size()) { - return null; - } - return _colors.get(i).getTriplet(); - } - - /** - * Sets the color value at a given index - * - * If the given index is greater than the current last color index, - * then black is inserted at every index required to make the palette continuous. - * - * @param byteIndex the index to set; if this index is less than 0x8 or greater than - * 0x40, then no modification is made - * @param red the red color part - * @param green the green color part - * @param blue the blue color part - */ - public void setColor(short byteIndex, byte red, byte green, byte blue) - { - int i = byteIndex - FIRST_COLOR_INDEX; - if (i < 0 || i >= STANDARD_PALETTE_SIZE) - { - return; - } - // may need to grow - fill intervening palette entries with black - while (_colors.size() <= i) { - _colors.add(new PColor(0, 0, 0)); - } - PColor custColor = new PColor(red, green, blue); - _colors.set(i, custColor); - } - - /** - * Creates the default palette as PaletteRecord binary data - */ - private static PColor[] createDefaultPalette() - { - return new PColor[] { - pc(0, 0, 0), - pc(255, 255, 255), - pc(255, 0, 0), - pc(0, 255, 0), - pc(0, 0, 255), - pc(255, 255, 0), - pc(255, 0, 255), - pc(0, 255, 255), - pc(128, 0, 0), - pc(0, 128, 0), - pc(0, 0, 128), - pc(128, 128, 0), - pc(128, 0, 128), - pc(0, 128, 128), - pc(192, 192, 192), - pc(128, 128, 128), - pc(153, 153, 255), - pc(153, 51, 102), - pc(255, 255, 204), - pc(204, 255, 255), - pc(102, 0, 102), - pc(255, 128, 128), - pc(0, 102, 204), - pc(204, 204, 255), - pc(0, 0, 128), - pc(255, 0, 255), - pc(255, 255, 0), - pc(0, 255, 255), - pc(128, 0, 128), - pc(128, 0, 0), - pc(0, 128, 128), - pc(0, 0, 255), - pc(0, 204, 255), - pc(204, 255, 255), - pc(204, 255, 204), - pc(255, 255, 153), - pc(153, 204, 255), - pc(255, 153, 204), - pc(204, 153, 255), - pc(255, 204, 153), - pc(51, 102, 255), - pc(51, 204, 204), - pc(153, 204, 0), - pc(255, 204, 0), - pc(255, 153, 0), - pc(255, 102, 0), - pc(102, 102, 153), - pc(150, 150, 150), - pc(0, 51, 102), - pc(51, 153, 102), - pc(0, 51, 0), - pc(51, 51, 0), - pc(153, 51, 0), - pc(153, 51, 102), - pc(51, 51, 153), - pc(51, 51, 51), - }; - } - - private static PColor pc(int r, int g, int b) { - return new PColor(r, g, b); - } - - /** - * PColor - element in the list of colors - */ - private static final class PColor { - public static final short ENCODED_SIZE = 4; - private final int _red; - private final int _green; - private final int _blue; - - public PColor(int red, int green, int blue) { - _red = red; - _green = green; - _blue = blue; - } - - public byte[] getTriplet() { - return new byte[] { (byte) _red, (byte) _green, (byte) _blue }; - } - - public PColor(RecordInputStream in) { - _red = in.readByte(); - _green = in.readByte(); - _blue = in.readByte(); - in.readByte(); // unused - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(_red); - out.writeByte(_green); - out.writeByte(_blue); - out.writeByte(0); - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" red = ").append(_red & 0xff).append('\n'); - buffer.append(" green = ").append(_green & 0xff).append('\n'); - buffer.append(" blue = ").append(_blue & 0xff).append('\n'); - return buffer.toString(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PaneRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PaneRecord.java deleted file mode 100644 index 69b94feb1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PaneRecord.java +++ /dev/null @@ -1,225 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Describes the frozen and unfrozen panes. - */ -public final class PaneRecord extends StandardRecord { - public final static short sid = 0x41; - private short field_1_x; - private short field_2_y; - private short field_3_topRow; - private short field_4_leftColumn; - private short field_5_activePane; - public final static short ACTIVE_PANE_LOWER_RIGHT = 0; - public final static short ACTIVE_PANE_UPPER_RIGHT = 1; - public final static short ACTIVE_PANE_LOWER_LEFT = 2; - public final static short ACTIVE_PANE_UPPER_LEFT = 3; - - - public PaneRecord() - { - - } - - public PaneRecord(RecordInputStream in) - { - field_1_x = in.readShort(); - field_2_y = in.readShort(); - field_3_topRow = in.readShort(); - field_4_leftColumn = in.readShort(); - field_5_activePane = in.readShort(); - } - - @Override - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PANE]\n"); - buffer.append(" .x = ") - .append("0x").append(HexDump.toHex( getX ())) - .append(" (").append( getX() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .y = ") - .append("0x").append(HexDump.toHex( getY ())) - .append(" (").append( getY() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .topRow = ") - .append("0x").append(HexDump.toHex( getTopRow ())) - .append(" (").append( getTopRow() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .leftColumn = ") - .append("0x").append(HexDump.toHex( getLeftColumn ())) - .append(" (").append( getLeftColumn() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .activePane = ") - .append("0x").append(HexDump.toHex( getActivePane ())) - .append(" (").append( getActivePane() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/PANE]\n"); - return buffer.toString(); - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_x); - out.writeShort(field_2_y); - out.writeShort(field_3_topRow); - out.writeShort(field_4_leftColumn); - out.writeShort(field_5_activePane); - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2; - } - - @Override - public short getSid() - { - return sid; - } - - @Override - public Object clone() { - PaneRecord rec = new PaneRecord(); - - rec.field_1_x = field_1_x; - rec.field_2_y = field_2_y; - rec.field_3_topRow = field_3_topRow; - rec.field_4_leftColumn = field_4_leftColumn; - rec.field_5_activePane = field_5_activePane; - return rec; - } - - /** - * Get the x field for the Pane record. - * - * @return the x value - */ - public short getX() - { - return field_1_x; - } - - /** - * Set the x field for the Pane record. - * - * @param field_1_x the x value - */ - public void setX(short field_1_x) - { - this.field_1_x = field_1_x; - } - - /** - * Get the y field for the Pane record. - * - * @return the y value - */ - public short getY() - { - return field_2_y; - } - - /** - * Set the y field for the Pane record. - * - * @param field_2_y the y value - */ - public void setY(short field_2_y) - { - this.field_2_y = field_2_y; - } - - /** - * Get the top row field for the Pane record. - * - * @return the top row - */ - public short getTopRow() - { - return field_3_topRow; - } - - /** - * Set the top row field for the Pane record. - * - * @param field_3_topRow the top row - */ - public void setTopRow(short field_3_topRow) - { - this.field_3_topRow = field_3_topRow; - } - - /** - * Get the left column field for the Pane record. - * - * @return the left column - */ - public short getLeftColumn() - { - return field_4_leftColumn; - } - - /** - * Set the left column field for the Pane record. - * - * @param field_4_leftColumn the left column - */ - public void setLeftColumn(short field_4_leftColumn) - { - this.field_4_leftColumn = field_4_leftColumn; - } - - /** - * Get the active pane field for the Pane record. - * - * @return One of - * ACTIVE_PANE_LOWER_RIGHT - * ACTIVE_PANE_UPPER_RIGHT - * ACTIVE_PANE_LOWER_LEFT - * ACTIVE_PANE_UPPER_LEFT - */ - public short getActivePane() - { - return field_5_activePane; - } - - /** - * Set the active pane field for the Pane record. - * - * @param field_5_activePane - * One of - * ACTIVE_PANE_LOWER_RIGHT - * ACTIVE_PANE_UPPER_RIGHT - * ACTIVE_PANE_LOWER_LEFT - * ACTIVE_PANE_UPPER_LEFT - */ - public void setActivePane(short field_5_activePane) - { - this.field_5_activePane = field_5_activePane; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PasswordRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PasswordRecord.java deleted file mode 100644 index c80e8c82c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PasswordRecord.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Password Record (0x0013)

    - * Description: stores the encrypted password for a sheet or workbook (HSSF doesn't support encryption) - * REFERENCE: PG 371 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class PasswordRecord extends StandardRecord { - public final static short sid = 0x0013; - private int field_1_password; // not sure why this is only 2 bytes, but it is... go figure - - public PasswordRecord(int password) { - field_1_password = password; - } - - public PasswordRecord(RecordInputStream in) { - field_1_password = in.readShort(); - } - - /** - * set the password - * - * @param password representing the password - */ - - public void setPassword(int password) { - field_1_password = password; - } - - /** - * get the password - * - * @return short representing the password - */ - public int getPassword() { - return field_1_password; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PASSWORD]\n"); - buffer.append(" .password = ").append(HexDump.shortToHex(field_1_password)).append("\n"); - buffer.append("[/PASSWORD]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_password); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } - - /** - * Clone this record. - */ - public Object clone() { - return new PasswordRecord(field_1_password); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PasswordRev4Record.java b/trunk/src/java/org/apache/poi/hssf/record/PasswordRev4Record.java deleted file mode 100644 index 16ef49a6f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PasswordRev4Record.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Protection Revision 4 password Record (0x01BC)

    - * Description: Stores the (2 byte??!!) encrypted password for a shared workbook

    - * REFERENCE: PG 374 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class PasswordRev4Record extends StandardRecord { - public final static short sid = 0x01BC; - private int field_1_password; - - public PasswordRev4Record(int pw) { - field_1_password = pw; - } - - public PasswordRev4Record(RecordInputStream in) { - field_1_password = in.readShort(); - } - - /** - * set the password - * - * @param pw representing the password - */ - public void setPassword(short pw) { - field_1_password = pw; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PROT4REVPASSWORD]\n"); - buffer.append(" .password = ").append(HexDump.shortToHex(field_1_password)).append("\n"); - buffer.append("[/PROT4REVPASSWORD]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_password); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PrecisionRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PrecisionRecord.java deleted file mode 100644 index 0dede1837..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PrecisionRecord.java +++ /dev/null @@ -1,99 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Precision Record

    - * Description: defines whether to store with full precision or what's displayed by the gui - * (meaning have really screwed up and skewed figures or only think you do!)

    - * REFERENCE: PG 372 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @version 2.0-pre - */ - -public final class PrecisionRecord - extends StandardRecord -{ - public final static short sid = 0xE; - public short field_1_precision; - - public PrecisionRecord() - { - } - - public PrecisionRecord(RecordInputStream in) - { - field_1_precision = in.readShort(); - } - - /** - * set whether to use full precision or just skew all you figures all to hell. - * - * @param fullprecision - or not - */ - - public void setFullPrecision(boolean fullprecision) - { - if (fullprecision == true) - { - field_1_precision = 1; - } - else - { - field_1_precision = 0; - } - } - - /** - * get whether to use full precision or just skew all you figures all to hell. - * - * @return fullprecision - or not - */ - - public boolean getFullPrecision() - { - return (field_1_precision == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PRECISION]\n"); - buffer.append(" .precision = ").append(getFullPrecision()) - .append("\n"); - buffer.append("[/PRECISION]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_precision); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PrintGridlinesRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PrintGridlinesRecord.java deleted file mode 100644 index b22e24485..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PrintGridlinesRecord.java +++ /dev/null @@ -1,106 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Print Gridlines Record

    - * Description: whether to print the gridlines when you enjoy you spreadsheet on paper.

    - * REFERENCE: PG 373 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class PrintGridlinesRecord - extends StandardRecord -{ - public final static short sid = 0x2b; - private short field_1_print_gridlines; - - public PrintGridlinesRecord() - { - } - - public PrintGridlinesRecord(RecordInputStream in) - { - field_1_print_gridlines = in.readShort(); - } - - /** - * set whether or not to print the gridlines (and make your spreadsheet ugly) - * - * @param pg make spreadsheet ugly - Y/N - */ - - public void setPrintGridlines(boolean pg) - { - if (pg == true) - { - field_1_print_gridlines = 1; - } - else - { - field_1_print_gridlines = 0; - } - } - - /** - * get whether or not to print the gridlines (and make your spreadsheet ugly) - * - * @return make spreadsheet ugly - Y/N - */ - - public boolean getPrintGridlines() - { - return (field_1_print_gridlines == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PRINTGRIDLINES]\n"); - buffer.append(" .printgridlines = ").append(getPrintGridlines()) - .append("\n"); - buffer.append("[/PRINTGRIDLINES]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_print_gridlines); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - PrintGridlinesRecord rec = new PrintGridlinesRecord(); - rec.field_1_print_gridlines = field_1_print_gridlines; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PrintHeadersRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PrintHeadersRecord.java deleted file mode 100644 index f2287ee6f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PrintHeadersRecord.java +++ /dev/null @@ -1,105 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Print Headers Record

    - * Description: Whether or not to print the row/column headers when you - * enjoy your spreadsheet in the physical form.

    - * REFERENCE: PG 373 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class PrintHeadersRecord - extends StandardRecord -{ - public final static short sid = 0x2a; - private short field_1_print_headers; - - public PrintHeadersRecord() - { - } - - public PrintHeadersRecord(RecordInputStream in) - { - field_1_print_headers = in.readShort(); - } - - /** - * set to print the headers - y/n - * @param p printheaders or not - */ - - public void setPrintHeaders(boolean p) - { - if (p == true) - { - field_1_print_headers = 1; - } - else - { - field_1_print_headers = 0; - } - } - - /** - * get whether to print the headers - y/n - * @return printheaders or not - */ - - public boolean getPrintHeaders() - { - return (field_1_print_headers == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PRINTHEADERS]\n"); - buffer.append(" .printheaders = ").append(getPrintHeaders()) - .append("\n"); - buffer.append("[/PRINTHEADERS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_print_headers); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - PrintHeadersRecord rec = new PrintHeadersRecord(); - rec.field_1_print_headers = field_1_print_headers; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java b/trunk/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java deleted file mode 100644 index 9ab4fe1a6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java +++ /dev/null @@ -1,365 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.usermodel.PrintSetup; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; - -/** - * Title: PAGESETUP (0x00A1)

    - * Description: Stores print setup options -- bogus for HSSF (and marked as such)

    - * REFERENCE: PG 385 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * REFERENCE: PG 412 Microsoft Excel Binary File Format Structure v20091214 - * - * @since 2.0-pre - */ -public final class PrintSetupRecord extends StandardRecord { - public final static short sid = 0x00A1; - /** Constants for this are held in {@link PrintSetup} */ - private short field_1_paper_size; - private short field_2_scale; - private short field_3_page_start; - private short field_4_fit_width; - private short field_5_fit_height; - private short field_6_options; - static final private BitField lefttoright = - BitFieldFactory.getInstance(0x01); // print over then down - static final private BitField landscape = - BitFieldFactory.getInstance(0x02); // landscape mode - static final private BitField validsettings = BitFieldFactory.getInstance( - 0x04); // if papersize, scale, resolution, copies, landscape - - // weren't obtained from the print consider them - // mere bunk - static final private BitField nocolor = - BitFieldFactory.getInstance(0x08); // print mono/b&w, colorless - static final private BitField draft = - BitFieldFactory.getInstance(0x10); // print draft quality - static final private BitField notes = - BitFieldFactory.getInstance(0x20); // print the notes - static final private BitField noOrientation = - BitFieldFactory.getInstance(0x40); // the orientation is not set - static final private BitField usepage = - BitFieldFactory.getInstance(0x80); // use a user set page no, instead of auto - private short field_7_hresolution; - private short field_8_vresolution; - private double field_9_headermargin; - private double field_10_footermargin; - private short field_11_copies; - - public PrintSetupRecord() - { - } - - public PrintSetupRecord(RecordInputStream in) - { - field_1_paper_size = in.readShort(); - field_2_scale = in.readShort(); - field_3_page_start = in.readShort(); - field_4_fit_width = in.readShort(); - field_5_fit_height = in.readShort(); - field_6_options = in.readShort(); - field_7_hresolution = in.readShort(); - field_8_vresolution = in.readShort(); - field_9_headermargin = in.readDouble(); - field_10_footermargin = in.readDouble(); - field_11_copies = in.readShort(); - } - - public void setPaperSize(short size) - { - field_1_paper_size = size; - } - - public void setScale(short scale) - { - field_2_scale = scale; - } - - public void setPageStart(short start) - { - field_3_page_start = start; - } - - public void setFitWidth(short width) - { - field_4_fit_width = width; - } - - public void setFitHeight(short height) - { - field_5_fit_height = height; - } - - public void setOptions(short options) - { - field_6_options = options; - } - - // option bitfields - public void setLeftToRight(boolean ltor) - { - field_6_options = lefttoright.setShortBoolean(field_6_options, ltor); - } - - public void setLandscape(boolean ls) - { - field_6_options = landscape.setShortBoolean(field_6_options, ls); - } - - public void setValidSettings(boolean valid) - { - field_6_options = validsettings.setShortBoolean(field_6_options, valid); - } - - public void setNoColor(boolean mono) - { - field_6_options = nocolor.setShortBoolean(field_6_options, mono); - } - - public void setDraft(boolean d) - { - field_6_options = draft.setShortBoolean(field_6_options, d); - } - - public void setNotes(boolean printnotes) - { - field_6_options = notes.setShortBoolean(field_6_options, printnotes); - } - - public void setNoOrientation(boolean orientation) - { - field_6_options = noOrientation.setShortBoolean(field_6_options, orientation); - } - - public void setUsePage(boolean page) - { - field_6_options = usepage.setShortBoolean(field_6_options, page); - } - - // end option bitfields - public void setHResolution(short resolution) - { - field_7_hresolution = resolution; - } - - public void setVResolution(short resolution) - { - field_8_vresolution = resolution; - } - - public void setHeaderMargin(double headermargin) - { - field_9_headermargin = headermargin; - } - - public void setFooterMargin(double footermargin) - { - field_10_footermargin = footermargin; - } - - public void setCopies(short copies) - { - field_11_copies = copies; - } - - public short getPaperSize() - { - return field_1_paper_size; - } - - public short getScale() - { - return field_2_scale; - } - - public short getPageStart() - { - return field_3_page_start; - } - - public short getFitWidth() - { - return field_4_fit_width; - } - - public short getFitHeight() - { - return field_5_fit_height; - } - - public short getOptions() - { - return field_6_options; - } - - // option bitfields - public boolean getLeftToRight() - { - return lefttoright.isSet(field_6_options); - } - - public boolean getLandscape() - { - return landscape.isSet(field_6_options); - } - - public boolean getValidSettings() - { - return validsettings.isSet(field_6_options); - } - - public boolean getNoColor() - { - return nocolor.isSet(field_6_options); - } - - public boolean getDraft() - { - return draft.isSet(field_6_options); - } - - public boolean getNotes() - { - return notes.isSet(field_6_options); - } - - public boolean getNoOrientation() - { - return noOrientation.isSet(field_6_options); - } - - public boolean getUsePage() - { - return usepage.isSet(field_6_options); - } - - // end option bitfields - public short getHResolution() - { - return field_7_hresolution; - } - - public short getVResolution() - { - return field_8_vresolution; - } - - public double getHeaderMargin() - { - return field_9_headermargin; - } - - public double getFooterMargin() - { - return field_10_footermargin; - } - - public short getCopies() - { - return field_11_copies; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PRINTSETUP]\n"); - buffer.append(" .papersize = ").append(getPaperSize()) - .append("\n"); - buffer.append(" .scale = ").append(getScale()) - .append("\n"); - buffer.append(" .pagestart = ").append(getPageStart()) - .append("\n"); - buffer.append(" .fitwidth = ").append(getFitWidth()) - .append("\n"); - buffer.append(" .fitheight = ").append(getFitHeight()) - .append("\n"); - buffer.append(" .options = ").append(getOptions()) - .append("\n"); - buffer.append(" .ltor = ").append(getLeftToRight()) - .append("\n"); - buffer.append(" .landscape = ").append(getLandscape()) - .append("\n"); - buffer.append(" .valid = ").append(getValidSettings()) - .append("\n"); - buffer.append(" .mono = ").append(getNoColor()) - .append("\n"); - buffer.append(" .draft = ").append(getDraft()) - .append("\n"); - buffer.append(" .notes = ").append(getNotes()) - .append("\n"); - buffer.append(" .noOrientat = ").append(getNoOrientation()) - .append("\n"); - buffer.append(" .usepage = ").append(getUsePage()) - .append("\n"); - buffer.append(" .hresolution = ").append(getHResolution()) - .append("\n"); - buffer.append(" .vresolution = ").append(getVResolution()) - .append("\n"); - buffer.append(" .headermargin = ").append(getHeaderMargin()) - .append("\n"); - buffer.append(" .footermargin = ").append(getFooterMargin()) - .append("\n"); - buffer.append(" .copies = ").append(getCopies()) - .append("\n"); - buffer.append("[/PRINTSETUP]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getPaperSize()); - out.writeShort(getScale()); - out.writeShort(getPageStart()); - out.writeShort(getFitWidth()); - out.writeShort(getFitHeight()); - out.writeShort(getOptions()); - out.writeShort(getHResolution()); - out.writeShort(getVResolution()); - out.writeDouble(getHeaderMargin()); - out.writeDouble(getFooterMargin()); - out.writeShort(getCopies()); - } - - protected int getDataSize() { - return 34; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - PrintSetupRecord rec = new PrintSetupRecord(); - rec.field_1_paper_size = field_1_paper_size; - rec.field_2_scale = field_2_scale; - rec.field_3_page_start = field_3_page_start; - rec.field_4_fit_width = field_4_fit_width; - rec.field_5_fit_height = field_5_fit_height; - rec.field_6_options = field_6_options; - rec.field_7_hresolution = field_7_hresolution; - rec.field_8_vresolution = field_8_vresolution; - rec.field_9_headermargin = field_9_headermargin; - rec.field_10_footermargin = field_10_footermargin; - rec.field_11_copies = field_11_copies; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ProtectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ProtectRecord.java deleted file mode 100644 index dca418e07..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ProtectRecord.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Protect Record (0x0012)

    - * Description: defines whether a sheet or workbook is protected (HSSF DOES NOT SUPPORT ENCRYPTION)

    - * HSSF now supports the simple "protected" sheets (where they are not encrypted and open office et al - * ignore the password record entirely). - * REFERENCE: PG 373 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class ProtectRecord extends StandardRecord { - public final static short sid = 0x0012; - - private static final BitField protectFlag = BitFieldFactory.getInstance(0x0001); - - private int _options; - - private ProtectRecord(int options) { - _options = options; - } - - public ProtectRecord(boolean isProtected) { - this(0); - setProtect(isProtected); - } - - public ProtectRecord(RecordInputStream in) { - this(in.readShort()); - } - - /** - * set whether the sheet is protected or not - * @param protect whether to protect the sheet or not - */ - public void setProtect(boolean protect) { - _options = protectFlag.setBoolean(_options, protect); - } - - /** - * get whether the sheet is protected or not - * @return whether to protect the sheet or not - */ - public boolean getProtect() { - return protectFlag.isSet(_options); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PROTECT]\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(_options)).append("\n"); - buffer.append("[/PROTECT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_options); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } - - public Object clone() { - return new ProtectRecord(_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ProtectionRev4Record.java b/trunk/src/java/org/apache/poi/hssf/record/ProtectionRev4Record.java deleted file mode 100644 index 6a9ca300f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ProtectionRev4Record.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Protection Revision 4 Record (0x01AF)

    - * Description: describes whether this is a protected shared/tracked workbook

    - * REFERENCE: PG 373 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class ProtectionRev4Record extends StandardRecord { - public final static short sid = 0x01AF; - - private static final BitField protectedFlag = BitFieldFactory.getInstance(0x0001); - - private int _options; - - private ProtectionRev4Record(int options) { - _options = options; - } - - public ProtectionRev4Record(boolean protect) { - this(0); - setProtect(protect); - } - - public ProtectionRev4Record(RecordInputStream in) { - this(in.readUShort()); - } - - /** - * set whether the this is protected shared/tracked workbook or not - * @param protect whether to protect the workbook or not - */ - public void setProtect(boolean protect) { - _options = protectedFlag.setBoolean(_options, protect); - } - - /** - * get whether the this is protected shared/tracked workbook or not - * @return whether to protect the workbook or not - */ - public boolean getProtect() { - return protectedFlag.isSet(_options); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PROT4REV]\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(_options)).append("\n"); - buffer.append("[/PROT4REV]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_options); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RKRecord.java b/trunk/src/java/org/apache/poi/hssf/record/RKRecord.java deleted file mode 100644 index 3aac08d69..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RKRecord.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.util.RKUtil; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: RK Record (0x027E)

    - * Description: An internal 32 bit number with the two most significant bits - * storing the type. This is part of a bizarre scheme to save disk - * space and memory (gee look at all the other whole records that - * are in the file just "cause"..,far better to waste processor - * cycles on this then leave on of those "valuable" records out).

    - * We support this in READ-ONLY mode. HSSF converts these to NUMBER records

    - * - * REFERENCE: PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - * - * @see org.apache.poi.hssf.record.NumberRecord - */ -public final class RKRecord extends CellRecord { - public final static short sid = 0x027E; - public final static short RK_IEEE_NUMBER = 0; - public final static short RK_IEEE_NUMBER_TIMES_100 = 1; - public final static short RK_INTEGER = 2; - public final static short RK_INTEGER_TIMES_100 = 3; - private int field_4_rk_number; - - private RKRecord() { - // fields uninitialised - } - - public RKRecord(RecordInputStream in) { - super(in); - field_4_rk_number = in.readInt(); - } - - /** - * Extract the value of the number - *

    - * The mechanism for determining the value is dependent on the two - * low order bits of the raw number. If bit 1 is set, the number - * is an integer and can be cast directly as a double, otherwise, - * it's apparently the exponent and mantissa of a double (and the - * remaining low-order bits of the double's mantissa are 0's). - *

    - * If bit 0 is set, the result of the conversion to a double is - * divided by 100; otherwise, the value is left alone. - *

    - * [insert picture of Screwy Squirrel in full Napoleonic regalia] - * - * @return the value as a proper double (hey, it could - * happen) - */ - public double getRKNumber() { - return RKUtil.decodeNumber(field_4_rk_number); - } - - @Override - protected String getRecordName() { - return "RK"; - } - - @Override - protected void appendValueText(StringBuilder sb) { - sb.append(" .value= ").append(getRKNumber()); - } - - @Override - protected void serializeValue(LittleEndianOutput out) { - out.writeInt(field_4_rk_number); - } - - @Override - protected int getValueDataSize() { - return 4; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public Object clone() { - RKRecord rec = new RKRecord(); - copyBaseFields(rec); - rec.field_4_rk_number = field_4_rk_number; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecalcIdRecord.java b/trunk/src/java/org/apache/poi/hssf/record/RecalcIdRecord.java deleted file mode 100644 index e890b43f9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecalcIdRecord.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Recalc Id Record (0x01C1)

    - * Description: This record contains an ID that marks when a worksheet was last - * recalculated. It's an optimization Excel uses to determine if it - * needs to recalculate the spreadsheet when it's opened. So far, only - * the two engine ids {@code 0x80 0x38 0x01 0x00} - * and {@code 0x60 0x69 0x01 0x00} have been seen. - * A value of {@code 0x00} will cause Excel to recalculate - * all formulas on the next load.

    - * REFERENCE: http://chicago.sourceforge.net/devel/docs/excel/biff8.html - */ -public final class RecalcIdRecord extends StandardRecord { - public final static short sid = 0x01C1; - private final int _reserved0; - - /** - * An unsigned integer that specifies the recalculation engine identifier - * of the recalculation engine that performed the last recalculation. - * If the value is less than the recalculation engine identifier associated with the application, - * the application will recalculate the results of all formulas on - * this workbook immediately after loading the file - */ - private int _engineId; - - public RecalcIdRecord() { - _reserved0 = 0; - _engineId = 0; - } - - public RecalcIdRecord(RecordInputStream in) { - in.readUShort(); // field 'rt' should have value 0x01C1, but Excel doesn't care during reading - _reserved0 = in.readUShort(); - _engineId = in.readInt(); - } - - public boolean isNeeded() { - return true; - } - - public void setEngineId(int val) { - _engineId = val; - } - - public int getEngineId() { - return _engineId; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[RECALCID]\n"); - buffer.append(" .reserved = ").append(HexDump.shortToHex(_reserved0)).append("\n"); - buffer.append(" .engineId = ").append(HexDump.intToHex(_engineId)).append("\n"); - buffer.append("[/RECALCID]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(sid); // always write 'rt' field as 0x01C1 - out.writeShort(_reserved0); - out.writeInt(_engineId); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/Record.java b/trunk/src/java/org/apache/poi/hssf/record/Record.java deleted file mode 100644 index 60ba7cd5d..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/Record.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayInputStream; - -/** - * All HSSF Records inherit from this class. - */ -public abstract class Record extends RecordBase { - - protected Record() { - // no fields to initialise - } - - /** - * called by the class that is responsible for writing this sucker. - * Subclasses should implement this so that their data is passed back in a - * byte array. - * - * @return byte array containing instance data - */ - public final byte[] serialize() { - byte[] retval = new byte[ getRecordSize() ]; - - serialize(0, retval); - return retval; - } - - /** - * get a string representation of the record (for biffview/debugging) - */ - @Override - public String toString() { - return super.toString(); - } - - /** - * return the non static version of the id for this record. - * - * @return he id for this record - */ - public abstract short getSid(); - - @Override - public Object clone() throws CloneNotSupportedException { - throw new CloneNotSupportedException("The class "+getClass().getName()+" needs to define a clone method"); - } - - /** - * Clone the current record, via a call to serialize - * it, and another to create a new record from the - * bytes. - * May only be used for classes which don't have - * internal counts / ids in them. For those which - * do, a full model-aware cloning is needed, which - * allocates new ids / counts as needed. - * - * @return the cloned current record - */ - public Record cloneViaReserialise() { - // Do it via a re-serialization - // It's a cheat, but it works... - byte[] b = serialize(); - RecordInputStream rinp = new RecordInputStream(new ByteArrayInputStream(b)); - rinp.nextRecord(); - - Record[] r = RecordFactory.createRecord(rinp); - if(r.length != 1) { - throw new IllegalStateException("Re-serialised a record to clone it, but got " + r.length + " records back!"); - } - return r[0]; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecordBase.java b/trunk/src/java/org/apache/poi/hssf/record/RecordBase.java deleted file mode 100644 index d19d2718d..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecordBase.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -/** - * Common base class of {@link Record} and {@link org.apache.poi.hssf.record.aggregates.RecordAggregate} - */ -public abstract class RecordBase { - /** - * called by the class that is responsible for writing this sucker. - * Subclasses should implement this so that their data is passed back in a - * byte array. - * - * @param offset to begin writing at - * @param data byte array containing instance data - * @return number of bytes written - */ - public abstract int serialize(int offset, byte[] data); - - /** - * gives the current serialized size of the record. Should include the sid - * and reclength (4 bytes). - * - * @return the record size - */ - public abstract int getRecordSize(); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java b/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java deleted file mode 100644 index 2336999b1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java +++ /dev/null @@ -1,500 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.hssf.record.chart.BeginRecord; -import org.apache.poi.hssf.record.chart.CatLabRecord; -import org.apache.poi.hssf.record.chart.ChartEndBlockRecord; -import org.apache.poi.hssf.record.chart.ChartEndObjectRecord; -import org.apache.poi.hssf.record.chart.ChartFRTInfoRecord; -import org.apache.poi.hssf.record.chart.ChartRecord; -import org.apache.poi.hssf.record.chart.ChartStartBlockRecord; -import org.apache.poi.hssf.record.chart.ChartStartObjectRecord; -import org.apache.poi.hssf.record.chart.ChartTitleFormatRecord; -import org.apache.poi.hssf.record.chart.DataFormatRecord; -import org.apache.poi.hssf.record.chart.EndRecord; -import org.apache.poi.hssf.record.chart.LegendRecord; -import org.apache.poi.hssf.record.chart.LinkedDataRecord; -import org.apache.poi.hssf.record.chart.SeriesRecord; -import org.apache.poi.hssf.record.chart.SeriesTextRecord; -import org.apache.poi.hssf.record.chart.SeriesToChartGroupRecord; -import org.apache.poi.hssf.record.chart.ValueRangeRecord; -import org.apache.poi.hssf.record.pivottable.DataItemRecord; -import org.apache.poi.hssf.record.pivottable.ExtendedPivotTableViewFieldsRecord; -import org.apache.poi.hssf.record.pivottable.PageItemRecord; -import org.apache.poi.hssf.record.pivottable.StreamIDRecord; -import org.apache.poi.hssf.record.pivottable.ViewDefinitionRecord; -import org.apache.poi.hssf.record.pivottable.ViewFieldsRecord; -import org.apache.poi.hssf.record.pivottable.ViewSourceRecord; - -/** - * Title: Record Factory

    - * Description: Takes a stream and outputs an array of Record objects. - * - * @see org.apache.poi.hssf.eventmodel.EventRecordFactory - */ -public final class RecordFactory { - private static final int NUM_RECORDS = 512; - - private interface I_RecordCreator { - Record create(RecordInputStream in); - - Class getRecordClass(); - } - private static final class ReflectionConstructorRecordCreator implements I_RecordCreator { - - private final Constructor _c; - public ReflectionConstructorRecordCreator(Constructor c) { - _c = c; - } - @Override - public Record create(RecordInputStream in) { - Object[] args = { in, }; - try { - return _c.newInstance(args); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof org.apache.poi.util.RecordFormatException) { - throw (org.apache.poi.util.RecordFormatException)t; - } else if (t instanceof EncryptedDocumentException) { - throw (EncryptedDocumentException)t; - } else { - throw new org.apache.poi.util.RecordFormatException("Unable to construct record instance" , t); - } - } - } - @Override - public Class getRecordClass() { - return _c.getDeclaringClass(); - } - } - /** - * A "create" method is used instead of the usual constructor if the created record might - * be of a different class to the declaring class. - */ - private static final class ReflectionMethodRecordCreator implements I_RecordCreator { - private final Method _m; - public ReflectionMethodRecordCreator(Method m) { - _m = m; - } - @Override - public Record create(RecordInputStream in) { - Object[] args = { in, }; - try { - return (Record) _m.invoke(null, args); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new org.apache.poi.util.RecordFormatException("Unable to construct record instance" , e.getTargetException()); - } - } - @Override - @SuppressWarnings("unchecked") - public Class getRecordClass() { - return (Class) _m.getDeclaringClass(); - } - } - - private static final Class[] CONSTRUCTOR_ARGS = { RecordInputStream.class, }; - - /** - * contains the classes for all the records we want to parse.
    - * Note - this most but not *every* subclass of Record. - */ - @SuppressWarnings("unchecked") - private static final Class[] recordClasses = new Class[] { - ArrayRecord.class, - AutoFilterInfoRecord.class, - BackupRecord.class, - BlankRecord.class, - BOFRecord.class, - BookBoolRecord.class, - BoolErrRecord.class, - BottomMarginRecord.class, - BoundSheetRecord.class, - CalcCountRecord.class, - CalcModeRecord.class, - CFHeaderRecord.class, - CFHeader12Record.class, - CFRuleRecord.class, - CFRule12Record.class, - ChartRecord.class, - ChartTitleFormatRecord.class, - CodepageRecord.class, - ColumnInfoRecord.class, - ContinueRecord.class, - CountryRecord.class, - CRNCountRecord.class, - CRNRecord.class, - DateWindow1904Record.class, - DBCellRecord.class, - DConRefRecord.class, - DefaultColWidthRecord.class, - DefaultRowHeightRecord.class, - DeltaRecord.class, - DimensionsRecord.class, - DrawingGroupRecord.class, - DrawingRecord.class, - DrawingSelectionRecord.class, - DSFRecord.class, - DVALRecord.class, - DVRecord.class, - EOFRecord.class, - ExtendedFormatRecord.class, - ExternalNameRecord.class, - ExternSheetRecord.class, - ExtSSTRecord.class, - FeatRecord.class, - FeatHdrRecord.class, - FilePassRecord.class, - FileSharingRecord.class, - FnGroupCountRecord.class, - FontRecord.class, - FooterRecord.class, - FormatRecord.class, - FormulaRecord.class, - GridsetRecord.class, - GutsRecord.class, - HCenterRecord.class, - HeaderRecord.class, - HeaderFooterRecord.class, - HideObjRecord.class, - HorizontalPageBreakRecord.class, - HyperlinkRecord.class, - IndexRecord.class, - InterfaceEndRecord.class, - InterfaceHdrRecord.class, - IterationRecord.class, - LabelRecord.class, - LabelSSTRecord.class, - LeftMarginRecord.class, - LegendRecord.class, - MergeCellsRecord.class, - MMSRecord.class, - MulBlankRecord.class, - MulRKRecord.class, - NameRecord.class, - NameCommentRecord.class, - NoteRecord.class, - NumberRecord.class, - ObjectProtectRecord.class, - ObjRecord.class, - PaletteRecord.class, - PaneRecord.class, - PasswordRecord.class, - PasswordRev4Record.class, - PrecisionRecord.class, - PrintGridlinesRecord.class, - PrintHeadersRecord.class, - PrintSetupRecord.class, - ProtectionRev4Record.class, - ProtectRecord.class, - RecalcIdRecord.class, - RefModeRecord.class, - RefreshAllRecord.class, - RightMarginRecord.class, - RKRecord.class, - RowRecord.class, - SaveRecalcRecord.class, - ScenarioProtectRecord.class, - SelectionRecord.class, - SeriesRecord.class, - SeriesTextRecord.class, - SharedFormulaRecord.class, - SSTRecord.class, - StringRecord.class, - StyleRecord.class, - SupBookRecord.class, - TabIdRecord.class, - TableRecord.class, - TableStylesRecord.class, - TextObjectRecord.class, - TopMarginRecord.class, - UncalcedRecord.class, - UseSelFSRecord.class, - UserSViewBegin.class, - UserSViewEnd.class, - ValueRangeRecord.class, - VCenterRecord.class, - VerticalPageBreakRecord.class, - WindowOneRecord.class, - WindowProtectRecord.class, - WindowTwoRecord.class, - WriteAccessRecord.class, - WriteProtectRecord.class, - WSBoolRecord.class, - - // chart records - BeginRecord.class, - ChartFRTInfoRecord.class, - ChartStartBlockRecord.class, - ChartEndBlockRecord.class, - // TODO ChartFormatRecord.class, - ChartStartObjectRecord.class, - ChartEndObjectRecord.class, - CatLabRecord.class, - DataFormatRecord.class, - EndRecord.class, - LinkedDataRecord.class, - SeriesToChartGroupRecord.class, - - // pivot table records - DataItemRecord.class, - ExtendedPivotTableViewFieldsRecord.class, - PageItemRecord.class, - StreamIDRecord.class, - ViewDefinitionRecord.class, - ViewFieldsRecord.class, - ViewSourceRecord.class, - }; - - /** - * cache of the recordsToMap(); - */ - private static final Map _recordCreatorsById = recordsToMap(recordClasses); - - private static short[] _allKnownRecordSIDs; - - /** - * Debug / diagnosis method

    - * - * Gets the POI implementation class for a given {@code sid}. Only a subset of the BIFF - * records are actually interpreted by POI. A few others are known but not interpreted - * (see {@link UnknownRecord#getBiffName(int)}). - * - * @param sid the record sid - * - * @return the POI implementation class for the specified record {@code sid}. - * {@code null} if the specified record is not interpreted by POI. - */ - public static Class getRecordClass(int sid) { - I_RecordCreator rc = _recordCreatorsById.get(Integer.valueOf(sid)); - if (rc == null) { - return null; - } - return rc.getRecordClass(); - } - - /** - * create a record, if there are MUL records than multiple records - * are returned digested into the non-mul form. - * - * @param in the RecordInputStream to read from - * @return the extracted records - */ - public static Record [] createRecord(RecordInputStream in) { - Record record = createSingleRecord(in); - if (record instanceof DBCellRecord) { - // Not needed by POI. Regenerated from scratch by POI when spreadsheet is written - return new Record[] { null, }; - } - if (record instanceof RKRecord) { - return new Record[] { convertToNumberRecord((RKRecord) record), }; - } - if (record instanceof MulRKRecord) { - return convertRKRecords((MulRKRecord)record); - } - return new Record[] { record, }; - } - - public static Record createSingleRecord(RecordInputStream in) { - I_RecordCreator constructor = _recordCreatorsById.get(Integer.valueOf(in.getSid())); - - if (constructor == null) { - return new UnknownRecord(in); - } - - return constructor.create(in); - } - - /** - * RK record is a slightly smaller alternative to NumberRecord - * POI likes NumberRecord better - * - * @param rk the RK record to convert - * @return the NumberRecord - */ - public static NumberRecord convertToNumberRecord(RKRecord rk) { - NumberRecord num = new NumberRecord(); - - num.setColumn(rk.getColumn()); - num.setRow(rk.getRow()); - num.setXFIndex(rk.getXFIndex()); - num.setValue(rk.getRKNumber()); - return num; - } - - /** - * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord NumberRecords} - * - * @param mrk the MulRKRecord to convert - * @return the equivalent array of {@link NumberRecord NumberRecords} - */ - public static NumberRecord[] convertRKRecords(MulRKRecord mrk) { - NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()]; - for (int k = 0; k < mrk.getNumColumns(); k++) { - NumberRecord nr = new NumberRecord(); - - nr.setColumn((short) (k + mrk.getFirstColumn())); - nr.setRow(mrk.getRow()); - nr.setXFIndex(mrk.getXFAt(k)); - nr.setValue(mrk.getRKNumberAt(k)); - mulRecs[k] = nr; - } - return mulRecs; - } - - /** - * Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord BlankRecords} - * - * @param mbk the MulBlankRecord to convert - * @return the equivalent array of {@link BlankRecord BlankRecords} - */ - public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) { - BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()]; - for (int k = 0; k < mbk.getNumColumns(); k++) { - BlankRecord br = new BlankRecord(); - - br.setColumn((short) (k + mbk.getFirstColumn())); - br.setRow(mbk.getRow()); - br.setXFIndex(mbk.getXFAt(k)); - mulRecs[k] = br; - } - return mulRecs; - } - - /** - * @return an array of all the SIDS for all known records - */ - public static short[] getAllKnownRecordSIDs() { - if (_allKnownRecordSIDs == null) { - short[] results = new short[ _recordCreatorsById.size() ]; - int i = 0; - - for (Integer sid : _recordCreatorsById.keySet()) { - results[i++] = sid.shortValue(); - } - Arrays.sort(results); - _allKnownRecordSIDs = results; - } - - return _allKnownRecordSIDs.clone(); - } - - /** - * gets the record constructors and sticks them in the map by SID - * @return map of SIDs to short,short,byte[] constructors for Record classes - * most of org.apache.poi.hssf.record.* - */ - private static Map recordsToMap(Class [] records) { - Map result = new HashMap(); - Set> uniqueRecClasses = new HashSet>(records.length * 3 / 2); - - for (Class recClass : records) { - if(!Record.class.isAssignableFrom(recClass)) { - throw new RuntimeException("Invalid record sub-class (" + recClass.getName() + ")"); - } - if(Modifier.isAbstract(recClass.getModifiers())) { - throw new RuntimeException("Invalid record class (" + recClass.getName() + ") - must not be abstract"); - } - if(!uniqueRecClasses.add(recClass)) { - throw new RuntimeException("duplicate record class (" + recClass.getName() + ")"); - } - - int sid; - try { - sid = recClass.getField("sid").getShort(null); - } catch (Exception illegalArgumentException) { - throw new org.apache.poi.util.RecordFormatException( - "Unable to determine record types"); - } - Integer key = Integer.valueOf(sid); - if (result.containsKey(key)) { - Class prevClass = result.get(key).getRecordClass(); - throw new RuntimeException("duplicate record sid 0x" + - Integer.toHexString(sid).toUpperCase(Locale.ROOT) - + " for classes (" + recClass.getName() + ") and (" - + prevClass.getName() + ")"); - } - result.put(key, getRecordCreator(recClass)); - } - // result.put(Integer.valueOf(0x0406), result.get(Integer.valueOf(0x06))); - return result; - } - - private static I_RecordCreator getRecordCreator(Class recClass) { - try { - Constructor constructor; - constructor = recClass.getConstructor(CONSTRUCTOR_ARGS); - return new ReflectionConstructorRecordCreator(constructor); - } catch (NoSuchMethodException e) { - // fall through and look for other construction methods - } - try { - Method m = recClass.getDeclaredMethod("create", CONSTRUCTOR_ARGS); - return new ReflectionMethodRecordCreator(m); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Failed to find constructor or create method for (" + recClass.getName() + ")."); - } - } - /** - * Create an array of records from an input stream - * - * @param in the InputStream from which the records will be obtained - * - * @return an array of Records created from the InputStream - * - * @exception org.apache.poi.util.RecordFormatException on error processing the InputStream - */ - public static List createRecords(InputStream in) throws org.apache.poi.util.RecordFormatException { - - List records = new ArrayList(NUM_RECORDS); - - RecordFactoryInputStream recStream = new RecordFactoryInputStream(in, true); - - Record record; - while ((record = recStream.nextRecord())!=null) { - records.add(record); - } - - return records; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java b/trunk/src/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java deleted file mode 100644 index 2c5ba94c0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecordFactoryInputStream.java +++ /dev/null @@ -1,368 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.record; - -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; -import org.apache.poi.hssf.eventusermodel.HSSFListener; -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; - -/** - * A stream based way to get at complete records, with - * as low a memory footprint as possible. - * This handles reading from a RecordInputStream, turning - * the data into full records, processing continue records - * etc. - * Most users should use {@link HSSFEventFactory} / - * {@link HSSFListener} and have new records pushed to - * them, but this does allow for a "pull" style of coding. - */ -public final class RecordFactoryInputStream { - - /** - * Keeps track of the sizes of the initial records up to and including {@link FilePassRecord} - * Needed for protected files because each byte is encrypted with respect to its absolute - * position from the start of the stream. - */ - private static final class StreamEncryptionInfo { - private final int _initialRecordsSize; - private final FilePassRecord _filePassRec; - private final Record _lastRecord; - private final boolean _hasBOFRecord; - - public StreamEncryptionInfo(RecordInputStream rs, List outputRecs) { - Record rec; - rs.nextRecord(); - int recSize = 4 + rs.remaining(); - rec = RecordFactory.createSingleRecord(rs); - outputRecs.add(rec); - FilePassRecord fpr = null; - if (rec instanceof BOFRecord) { - _hasBOFRecord = true; - - // Fetch the next record, and see if it indicates whether - // the document is encrypted or not - if (rs.hasNextRecord()) { - rs.nextRecord(); - rec = RecordFactory.createSingleRecord(rs); - recSize += rec.getRecordSize(); - outputRecs.add(rec); - - // Encrypted is normally BOF then FILEPASS - // May sometimes be BOF, WRITEPROTECT, FILEPASS - if (rec instanceof WriteProtectRecord && rs.hasNextRecord()) { - rs.nextRecord(); - rec = RecordFactory.createSingleRecord(rs); - recSize += rec.getRecordSize(); - outputRecs.add(rec); - } - - // If it's a FILEPASS, track it specifically - if (rec instanceof FilePassRecord) { - fpr = (FilePassRecord) rec; - } - - // workbook not encrypted (typical case) - if (rec instanceof EOFRecord) { - // A workbook stream is never empty, so crash instead - // of trying to keep track of nesting level - throw new IllegalStateException("Nothing between BOF and EOF"); - } - } - } else { - // Invalid in a normal workbook stream. - // However, some test cases work on sub-sections of - // the workbook stream that do not begin with BOF - _hasBOFRecord = false; - } - _initialRecordsSize = recSize; - _filePassRec = fpr; - _lastRecord = rec; - } - - public RecordInputStream createDecryptingStream(InputStream original) { - FilePassRecord fpr = _filePassRec; - String userPassword = Biff8EncryptionKey.getCurrentUserPassword(); - if (userPassword == null) { - userPassword = Decryptor.DEFAULT_PASSWORD; - } - - EncryptionInfo info = fpr.getEncryptionInfo(); - try { - if (!info.getDecryptor().verifyPassword(userPassword)) { - throw new EncryptedDocumentException( - (Decryptor.DEFAULT_PASSWORD.equals(userPassword) ? "Default" : "Supplied") - + " password is invalid for salt/verifier/verifierHash"); - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e); - } - - return new RecordInputStream(original, info, _initialRecordsSize); - } - - public boolean hasEncryption() { - return _filePassRec != null; - } - - /** - * @return last record scanned while looking for encryption info. - * This will typically be the first or second record read. Possibly null - * if stream was empty - */ - public Record getLastRecord() { - return _lastRecord; - } - - /** - * false in some test cases - */ - public boolean hasBOFRecord() { - return _hasBOFRecord; - } - } - - - private final RecordInputStream _recStream; - private final boolean _shouldIncludeContinueRecords; - - /** - * Temporarily stores a group of {@link Record}s, for future return by {@link #nextRecord()}. - * This is used at the start of the workbook stream, and also when the most recently read - * underlying record is a {@link MulRKRecord} - */ - private Record[] _unreadRecordBuffer; - - /** - * used to help iterating over the unread records - */ - private int _unreadRecordIndex = -1; - - /** - * The most recent record that we gave to the user - */ - private Record _lastRecord = null; - /** - * The most recent DrawingRecord seen - */ - private DrawingRecord _lastDrawingRecord = new DrawingRecord(); - - private int _bofDepth; - - private boolean _lastRecordWasEOFLevelZero; - - - /** - * @param in the InputStream to read from - * - * @param shouldIncludeContinueRecords caller can pass false if loose - * {@link ContinueRecord}s should be skipped (this is sometimes useful in event based - * processing). - */ - public RecordFactoryInputStream(InputStream in, boolean shouldIncludeContinueRecords) { - RecordInputStream rs = new RecordInputStream(in); - List records = new ArrayList(); - StreamEncryptionInfo sei = new StreamEncryptionInfo(rs, records); - if (sei.hasEncryption()) { - rs = sei.createDecryptingStream(in); - } else { - // typical case - non-encrypted stream - } - - if (!records.isEmpty()) { - _unreadRecordBuffer = new Record[records.size()]; - records.toArray(_unreadRecordBuffer); - _unreadRecordIndex =0; - } - _recStream = rs; - _shouldIncludeContinueRecords = shouldIncludeContinueRecords; - _lastRecord = sei.getLastRecord(); - - /* - * How to recognise end of stream? - * In the best case, the underlying input stream (in) ends just after the last EOF record - * Usually however, the stream is padded with an arbitrary byte count. Excel and most apps - * reliably use zeros for padding and if this were always the case, this code could just - * skip all the (zero sized) records with sid==0. However, bug 46987 shows a file with - * non-zero padding that is read OK by Excel (Excel also fixes the padding). - * - * So to properly detect the workbook end of stream, this code has to identify the last - * EOF record. This is not so easy because the worbook bof+eof pair do not bracket the - * whole stream. The worksheets follow the workbook, but it is not easy to tell how many - * sheet sub-streams should be present. Hence we are looking for an EOF record that is not - * immediately followed by a BOF record. One extra complication is that bof+eof sub- - * streams can be nested within worksheet streams and it's not clear in these cases what - * record might follow any EOF record. So we also need to keep track of the bof/eof - * nesting level. - */ - _bofDepth = sei.hasBOFRecord() ? 1 : 0; - _lastRecordWasEOFLevelZero = false; - } - - /** - * @return the next (complete) record from the stream, or null if there are no more. - */ - public Record nextRecord() { - Record r; - r = getNextUnreadRecord(); - if (r != null) { - // found an unread record - return r; - } - while (true) { - if (!_recStream.hasNextRecord()) { - // recStream is exhausted; - return null; - } - - if (_lastRecordWasEOFLevelZero) { - // Potential place for ending the workbook stream - // Check that the next record is not BOFRecord(0x0809) - // Normally the input stream contains only zero padding after the last EOFRecord, - // but bug 46987 and 48068 suggests that the padding may be garbage. - // This code relies on the padding bytes not starting with BOFRecord.sid - if (_recStream.getNextSid() != BOFRecord.sid) { - return null; - } - // else - another sheet substream starting here - } - - // step underlying RecordInputStream to the next record - _recStream.nextRecord(); - - r = readNextRecord(); - if (r == null) { - // some record types may get skipped (e.g. DBCellRecord and ContinueRecord) - continue; - } - return r; - } - } - - /** - * @return the next {@link Record} from the multiple record group as expanded from - * a recently read {@link MulRKRecord}. null if not present. - */ - private Record getNextUnreadRecord() { - if (_unreadRecordBuffer != null) { - int ix = _unreadRecordIndex; - if (ix < _unreadRecordBuffer.length) { - Record result = _unreadRecordBuffer[ix]; - _unreadRecordIndex = ix + 1; - return result; - } - _unreadRecordIndex = -1; - _unreadRecordBuffer = null; - } - return null; - } - - /** - * @return the next available record, or null if - * this pass didn't return a record that's - * suitable for returning (eg was a continue record). - */ - private Record readNextRecord() { - - Record record = RecordFactory.createSingleRecord(_recStream); - _lastRecordWasEOFLevelZero = false; - - if (record instanceof BOFRecord) { - _bofDepth++; - return record; - } - - if (record instanceof EOFRecord) { - _bofDepth--; - if (_bofDepth < 1) { - _lastRecordWasEOFLevelZero = true; - } - - return record; - } - - if (record instanceof DBCellRecord) { - // Not needed by POI. Regenerated from scratch by POI when spreadsheet is written - return null; - } - - if (record instanceof RKRecord) { - return RecordFactory.convertToNumberRecord((RKRecord) record); - } - - if (record instanceof MulRKRecord) { - Record[] records = RecordFactory.convertRKRecords((MulRKRecord) record); - - _unreadRecordBuffer = records; - _unreadRecordIndex = 1; - return records[0]; - } - - if (record.getSid() == DrawingGroupRecord.sid - && _lastRecord instanceof DrawingGroupRecord) { - DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) _lastRecord; - lastDGRecord.join((AbstractEscherHolderRecord) record); - return null; - } - if (record.getSid() == ContinueRecord.sid) { - ContinueRecord contRec = (ContinueRecord) record; - - if (_lastRecord instanceof ObjRecord || _lastRecord instanceof TextObjectRecord) { - // Drawing records have a very strange continue behaviour. - //There can actually be OBJ records mixed between the continues. - _lastDrawingRecord.processContinueRecord(contRec.getData()); - //we must remember the position of the continue record. - //in the serialization procedure the original structure of records must be preserved - if (_shouldIncludeContinueRecords) { - return record; - } - return null; - } - if (_lastRecord instanceof DrawingGroupRecord) { - ((DrawingGroupRecord) _lastRecord).processContinueRecord(contRec.getData()); - return null; - } - if (_lastRecord instanceof DrawingRecord) { -// ((DrawingRecord) _lastRecord).appendContinueRecord(contRec.getData()); - return contRec; - } - if (_lastRecord instanceof UnknownRecord) { - //Gracefully handle records that we don't know about, - //that happen to be continued - return record; - } - if (_lastRecord instanceof EOFRecord) { - // This is really odd, but excel still sometimes - // outputs a file like this all the same - return record; - } - throw new RecordFormatException("Unhandled Continue Record followining " + _lastRecord.getClass()); - } - _lastRecord = record; - if (record instanceof DrawingRecord) { - _lastDrawingRecord = (DrawingRecord) record; - } - return record; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecordFormatException.java b/trunk/src/java/org/apache/poi/hssf/record/RecordFormatException.java deleted file mode 100644 index 63d05aa70..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecordFormatException.java +++ /dev/null @@ -1,44 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -/** - * Used by records to indicate invalid format/data.

    - * - * @deprecated as of 3.15-beta1, scheduled for removal in 3.17 - * use the class with the same name from the utils-package - */ - -public class RecordFormatException - extends org.apache.poi.util.RecordFormatException -{ - public RecordFormatException(String exception) - { - super(exception); - } - - public RecordFormatException(String exception, Throwable thr) { - super(exception, thr); - } - - public RecordFormatException(Throwable thr) { - super(thr); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java b/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java deleted file mode 100644 index 8fd042393..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java +++ /dev/null @@ -1,537 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Locale; - -import org.apache.poi.hssf.dev.BiffViewer; -import org.apache.poi.hssf.record.crypto.Biff8DecryptingStream; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianInputStream; - -/** - * Title: Record Input Stream

    - * Description: Wraps a stream and provides helper methods for the construction of records.

    - */ -public final class RecordInputStream implements LittleEndianInput { - /** Maximum size of a single record (minus the 4 byte header) without a continue*/ - public final static short MAX_RECORD_DATA_SIZE = 8224; - private static final int INVALID_SID_VALUE = -1; - /** - * When {@link #_currentDataLength} has this value, it means that the previous BIFF record is - * finished, the next sid has been properly read, but the data size field has not been read yet. - */ - private static final int DATA_LEN_NEEDS_TO_BE_READ = -1; - private static final byte[] EMPTY_BYTE_ARRAY = { }; - - /** - * For use in {@link BiffViewer} which may construct {@link Record}s that don't completely - * read all available data. This exception should never be thrown otherwise. - */ - @SuppressWarnings("serial") - public static final class LeftoverDataException extends RuntimeException { - public LeftoverDataException(int sid, int remainingByteCount) { - super("Initialisation of record 0x" + Integer.toHexString(sid).toUpperCase(Locale.ROOT) - + "(" + getRecordName(sid) + ") left " + remainingByteCount - + " bytes remaining still to be read."); - } - - private static String getRecordName(int sid) { - Class recordClass = RecordFactory.getRecordClass(sid); - if(recordClass == null) { - return null; - } - return recordClass.getSimpleName(); - } - } - - /** Header {@link LittleEndianInput} facet of the wrapped {@link InputStream} */ - private final BiffHeaderInput _bhi; - /** Data {@link LittleEndianInput} facet of the wrapped {@link InputStream} */ - private final LittleEndianInput _dataInput; - /** the record identifier of the BIFF record currently being read */ - private int _currentSid; - /** - * Length of the data section of the current BIFF record (always 4 less than the total record size). - * When uninitialised, this field is set to {@link #DATA_LEN_NEEDS_TO_BE_READ}. - */ - private int _currentDataLength; - /** - * The BIFF record identifier for the next record is read when just as the current record - * is finished. - * This field is only really valid during the time that ({@link #_currentDataLength} == - * {@link #DATA_LEN_NEEDS_TO_BE_READ}). At most other times its value is not really the - * 'sid of the next record'. Wwhile mid-record, this field coincidentally holds the sid - * of the current record. - */ - private int _nextSid; - /** - * index within the data section of the current BIFF record - */ - private int _currentDataOffset; - /** - * index within the data section when mark() was called - */ - private int _markedDataOffset; - - private static final class SimpleHeaderInput implements BiffHeaderInput { - - private final LittleEndianInput _lei; - - public SimpleHeaderInput(InputStream in) { - _lei = getLEI(in); - } - @Override - public int available() { - return _lei.available(); - } - @Override - public int readDataSize() { - return _lei.readUShort(); - } - @Override - public int readRecordSID() { - return _lei.readUShort(); - } - } - - public RecordInputStream(InputStream in) throws RecordFormatException { - this (in, null, 0); - } - - public RecordInputStream(InputStream in, EncryptionInfo key, int initialOffset) throws RecordFormatException { - if (key == null) { - _dataInput = getLEI(in); - _bhi = new SimpleHeaderInput(in); - } else { - Biff8DecryptingStream bds = new Biff8DecryptingStream(in, initialOffset, key); - _dataInput = bds; - _bhi = bds; - } - _nextSid = readNextSid(); - } - - static LittleEndianInput getLEI(InputStream is) { - if (is instanceof LittleEndianInput) { - // accessing directly is an optimisation - return (LittleEndianInput) is; - } - // less optimal, but should work OK just the same. Often occurs in junit tests. - return new LittleEndianInputStream(is); - } - - /** - * @return the number of bytes available in the current BIFF record - * @see #remaining() - */ - @Override - public int available() { - return remaining(); - } - - public int read(byte[] b, int off, int len) { - int limit = Math.min(len, remaining()); - if (limit == 0) { - return 0; - } - readFully(b, off,limit); - return limit; - } - - public short getSid() { - return (short) _currentSid; - } - - /** - * Note - this method is expected to be called only when completed reading the current BIFF - * record. - * - * @return true, if there's another record in the stream - * - * @throws LeftoverDataException if this method is called before reaching the end of the - * current record. - */ - public boolean hasNextRecord() throws LeftoverDataException { - if (_currentDataLength != -1 && _currentDataLength != _currentDataOffset) { - throw new LeftoverDataException(_currentSid, remaining()); - } - if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) { - _nextSid = readNextSid(); - } - return _nextSid != INVALID_SID_VALUE; - } - - /** - * @return the sid of the next record or {@link #INVALID_SID_VALUE} if at end of stream - */ - private int readNextSid() { - int nAvailable = _bhi.available(); - if (nAvailable < EOFRecord.ENCODED_SIZE) { - if (nAvailable > 0) { - // some scrap left over? - // ex45582-22397.xls has one extra byte after the last record - // Excel reads that file OK - } - return INVALID_SID_VALUE; - } - int result = _bhi.readRecordSID(); - if (result == INVALID_SID_VALUE) { - throw new RecordFormatException("Found invalid sid (" + result + ")"); - } - _currentDataLength = DATA_LEN_NEEDS_TO_BE_READ; - return result; - } - - /** Moves to the next record in the stream. - * - * Note: The auto continue flag is reset to true - */ - public void nextRecord() throws RecordFormatException { - if (_nextSid == INVALID_SID_VALUE) { - throw new IllegalStateException("EOF - next record not available"); - } - if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) { - throw new IllegalStateException("Cannot call nextRecord() without checking hasNextRecord() first"); - } - _currentSid = _nextSid; - _currentDataOffset = 0; - _currentDataLength = _bhi.readDataSize(); - if (_currentDataLength > MAX_RECORD_DATA_SIZE) { - throw new RecordFormatException("The content of an excel record cannot exceed " - + MAX_RECORD_DATA_SIZE + " bytes"); - } - } - - private void checkRecordPosition(int requiredByteCount) { - - int nAvailable = remaining(); - if (nAvailable >= requiredByteCount) { - // all OK - return; - } - if (nAvailable == 0 && isContinueNext()) { - nextRecord(); - return; - } - throw new RecordFormatException("Not enough data (" + nAvailable - + ") to read requested (" + requiredByteCount +") bytes"); - } - - /** - * Reads an 8 bit, signed value - */ - @Override - public byte readByte() { - checkRecordPosition(LittleEndianConsts.BYTE_SIZE); - _currentDataOffset += LittleEndianConsts.BYTE_SIZE; - return _dataInput.readByte(); - } - - /** - * Reads a 16 bit, signed value - */ - @Override - public short readShort() { - checkRecordPosition(LittleEndianConsts.SHORT_SIZE); - _currentDataOffset += LittleEndianConsts.SHORT_SIZE; - return _dataInput.readShort(); - } - - /** - * Reads a 32 bit, signed value - */ - @Override - public int readInt() { - checkRecordPosition(LittleEndianConsts.INT_SIZE); - _currentDataOffset += LittleEndianConsts.INT_SIZE; - return _dataInput.readInt(); - } - - /** - * Reads a 64 bit, signed value - */ - @Override - public long readLong() { - checkRecordPosition(LittleEndianConsts.LONG_SIZE); - _currentDataOffset += LittleEndianConsts.LONG_SIZE; - return _dataInput.readLong(); - } - - /** - * Reads an 8 bit, unsigned value - */ - @Override - public int readUByte() { - return readByte() & 0x00FF; - } - - /** - * Reads a 16 bit, unsigned value. - */ - @Override - public int readUShort() { - checkRecordPosition(LittleEndianConsts.SHORT_SIZE); - _currentDataOffset += LittleEndianConsts.SHORT_SIZE; - return _dataInput.readUShort(); - } - - @Override - public double readDouble() { - long valueLongBits = readLong(); - double result = Double.longBitsToDouble(valueLongBits); - if (Double.isNaN(result)) { - // YK: Excel doesn't write NaN but instead converts the cell type into {@link CellType#ERROR}. - // HSSF prior to version 3.7 had a bug: it could write Double.NaN but could not read such a file back. - // This behavior was fixed in POI-3.7. - //throw new RuntimeException("Did not expect to read NaN"); // (Because Excel typically doesn't write NaN) - } - return result; - } - - public void readPlain(byte[] buf, int off, int len) { - readFully(buf, 0, buf.length, true); - } - - @Override - public void readFully(byte[] buf) { - readFully(buf, 0, buf.length, false); - } - - @Override - public void readFully(byte[] buf, int off, int len) { - readFully(buf, off, len, false); - } - - protected void readFully(byte[] buf, int off, int len, boolean isPlain) { - int origLen = len; - if (buf == null) { - throw new NullPointerException(); - } else if (off < 0 || len < 0 || len > buf.length - off) { - throw new IndexOutOfBoundsException(); - } - - while (len > 0) { - int nextChunk = Math.min(available(),len); - if (nextChunk == 0) { - if (!hasNextRecord()) { - throw new RecordFormatException("Can't read the remaining "+len+" bytes of the requested "+origLen+" bytes. No further record exists."); - } else { - nextRecord(); - nextChunk = Math.min(available(),len); - assert(nextChunk > 0); - } - } - checkRecordPosition(nextChunk); - if (isPlain) { - _dataInput.readPlain(buf, off, nextChunk); - } else { - _dataInput.readFully(buf, off, nextChunk); - } - _currentDataOffset+=nextChunk; - off += nextChunk; - len -= nextChunk; - } - } - - public String readString() { - int requestedLength = readUShort(); - byte compressFlag = readByte(); - return readStringCommon(requestedLength, compressFlag == 0); - } - /** - * given a byte array of 16-bit unicode characters, compress to 8-bit and - * return a string - * - * { 0x16, 0x00 } -0x16 - * - * @param requestedLength the length of the final string - * @return the converted string - * @exception IllegalArgumentException if len is too large (i.e., - * there is not enough data in string to create a String of that - * length) - */ - public String readUnicodeLEString(int requestedLength) { - return readStringCommon(requestedLength, false); - } - - public String readCompressedUnicode(int requestedLength) { - return readStringCommon(requestedLength, true); - } - - private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) { - // Sanity check to detect garbage string lengths - if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars? - throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")"); - } - char[] buf = new char[requestedLength]; - boolean isCompressedEncoding = pIsCompressedEncoding; - int curLen = 0; - while(true) { - int availableChars =isCompressedEncoding ? remaining() : remaining() / LittleEndianConsts.SHORT_SIZE; - if (requestedLength - curLen <= availableChars) { - // enough space in current record, so just read it out - while(curLen < requestedLength) { - char ch; - if (isCompressedEncoding) { - ch = (char)readUByte(); - } else { - ch = (char)readShort(); - } - buf[curLen] = ch; - curLen++; - } - return new String(buf); - } - // else string has been spilled into next continue record - // so read what's left of the current record - while(availableChars > 0) { - char ch; - if (isCompressedEncoding) { - ch = (char)readUByte(); - } else { - ch = (char)readShort(); - } - buf[curLen] = ch; - curLen++; - availableChars--; - } - if (!isContinueNext()) { - throw new RecordFormatException("Expected to find a ContinueRecord in order to read remaining " - + (requestedLength-curLen) + " of " + requestedLength + " chars"); - } - if(remaining() != 0) { - throw new RecordFormatException("Odd number of bytes(" + remaining() + ") left behind"); - } - nextRecord(); - // note - the compressed flag may change on the fly - byte compressFlag = readByte(); - assert(compressFlag == 0 || compressFlag == 1); - isCompressedEncoding = (compressFlag == 0); - } - } - - /** Returns the remaining bytes for the current record. - * - * @return The remaining bytes of the current record. - */ - public byte[] readRemainder() { - int size = remaining(); - if (size ==0) { - return EMPTY_BYTE_ARRAY; - } - byte[] result = new byte[size]; - readFully(result); - return result; - } - - /** - * Reads all byte data for the current record, including any that overlaps - * into any following continue records. - * - * @return all byte data for the current record - * - * @deprecated POI 2.0 Best to write a input stream that wraps this one - * where there is special sub record that may overlap continue - * records. - */ - @Deprecated - public byte[] readAllContinuedRemainder() { - ByteArrayOutputStream out = new ByteArrayOutputStream(2 * MAX_RECORD_DATA_SIZE); - - while (true) { - byte[] b = readRemainder(); - out.write(b, 0, b.length); - if (!isContinueNext()) { - break; - } - nextRecord(); - } - return out.toByteArray(); - } - - /** The remaining number of bytes in the current record. - * - * @return The number of bytes remaining in the current record - */ - public int remaining() { - if (_currentDataLength == DATA_LEN_NEEDS_TO_BE_READ) { - // already read sid of next record. so current one is finished - return 0; - } - return _currentDataLength - _currentDataOffset; - } - - /** - * - * @return true when a {@link ContinueRecord} is next. - */ - private boolean isContinueNext() { - if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && _currentDataOffset != _currentDataLength) { - throw new IllegalStateException("Should never be called before end of current record"); - } - if (!hasNextRecord()) { - return false; - } - // At what point are records continued? - // - Often from within the char data of long strings (caller is within readStringCommon()). - // - From UnicodeString construction (many different points - call via checkRecordPosition) - // - During TextObjectRecord construction (just before the text, perhaps within the text, - // and before the formatting run data) - return _nextSid == ContinueRecord.sid; - } - - /** - @return sid of next record. Can be called after hasNextRecord() - */ - public int getNextSid() { - return _nextSid; - } - - /** - * Mark the stream position - experimental function - * - * @param readlimit the read ahead limit - * - * @see InputStream#mark(int) - */ - @Internal - public void mark(int readlimit) { - ((InputStream)_dataInput).mark(readlimit); - _markedDataOffset = _currentDataOffset; - } - - /** - * Resets the stream position to the previously marked position. - * Experimental function - this only works, when nextRecord() wasn't called in the meantime. - * - * @throws IOException if marking is not supported - * - * @see InputStream#reset() - */ - @Internal - public void reset() throws IOException { - ((InputStream)_dataInput).reset(); - _currentDataOffset = _markedDataOffset; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RecordProcessor.java b/trunk/src/java/org/apache/poi/hssf/record/RecordProcessor.java deleted file mode 100644 index 715cb84d1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RecordProcessor.java +++ /dev/null @@ -1,33 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - - -/** - * Process a single record. That is, an SST record or a continue record. - * Refactored from code originally in SSTRecord. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -class RecordProcessor -{ - //This class is not required anymore -} - diff --git a/trunk/src/java/org/apache/poi/hssf/record/RefModeRecord.java b/trunk/src/java/org/apache/poi/hssf/record/RefModeRecord.java deleted file mode 100644 index ef1316e48..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RefModeRecord.java +++ /dev/null @@ -1,104 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: RefMode Record

    - * Description: Describes which reference mode to use

    - * REFERENCE: PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class RefModeRecord - extends StandardRecord -{ - public final static short sid = 0xf; - public final static short USE_A1_MODE = 1; - public final static short USE_R1C1_MODE = 0; - private short field_1_mode; - - public RefModeRecord() - { - } - - public RefModeRecord(RecordInputStream in) - { - field_1_mode = in.readShort(); - } - - /** - * set the reference mode to use (HSSF uses/assumes A1) - * @param mode the mode to use - * @see #USE_A1_MODE - * @see #USE_R1C1_MODE - * - */ - - public void setMode(short mode) - { - field_1_mode = mode; - } - - /** - * get the reference mode to use (HSSF uses/assumes A1) - * @return mode to use - * @see #USE_A1_MODE - * @see #USE_R1C1_MODE - */ - - public short getMode() - { - return field_1_mode; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[REFMODE]\n"); - buffer.append(" .mode = ") - .append(Integer.toHexString(getMode())).append("\n"); - buffer.append("[/REFMODE]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getMode()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - RefModeRecord rec = new RefModeRecord(); - rec.field_1_mode = field_1_mode; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RefreshAllRecord.java b/trunk/src/java/org/apache/poi/hssf/record/RefreshAllRecord.java deleted file mode 100644 index a6e547fea..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RefreshAllRecord.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Refresh All Record (0x01B7)

    - * Description: Flag whether to refresh all external data when loading a sheet. - * (which hssf doesn't support anyhow so who really cares?)

    - * REFERENCE: PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class RefreshAllRecord extends StandardRecord { - public final static short sid = 0x01B7; - - private static final BitField refreshFlag = BitFieldFactory.getInstance(0x0001); - - private int _options; - - private RefreshAllRecord(int options) { - _options = options; - } - - public RefreshAllRecord(RecordInputStream in) { - this(in.readUShort()); - } - - public RefreshAllRecord(boolean refreshAll) { - this(0); - setRefreshAll(refreshAll); - } - - /** - * set whether to refresh all external data when loading a sheet - * @param refreshAll or not - */ - public void setRefreshAll(boolean refreshAll) { - _options = refreshFlag.setBoolean(_options, refreshAll); - } - - /** - * get whether to refresh all external data when loading a sheet - * @return refreshall or not - */ - public boolean getRefreshAll() { - return refreshFlag.isSet(_options); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[REFRESHALL]\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(_options)).append("\n"); - buffer.append("[/REFRESHALL]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_options); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } - @Override - public Object clone() { - return new RefreshAllRecord(_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/RightMarginRecord.java b/trunk/src/java/org/apache/poi/hssf/record/RightMarginRecord.java deleted file mode 100644 index 09b1d9684..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RightMarginRecord.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Record for the right margin. - */ -public final class RightMarginRecord extends StandardRecord implements Margin { - public final static short sid = 0x27; - private double field_1_margin; - - public RightMarginRecord() { } - - public RightMarginRecord( RecordInputStream in ) - { - field_1_margin = in.readDouble(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - buffer.append( "[RightMargin]\n" ); - buffer.append( " .margin = " ).append( " (" ).append( getMargin() ).append( " )\n" ); - buffer.append( "[/RightMargin]\n" ); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeDouble(field_1_margin); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() { return sid; } - - /** - * Get the margin field for the RightMargin record. - */ - public double getMargin() { return field_1_margin; } - - /** - * Set the margin field for the RightMargin record. - */ - public void setMargin( double field_1_margin ) - { this.field_1_margin = field_1_margin; } - - public Object clone() - { - RightMarginRecord rec = new RightMarginRecord(); - rec.field_1_margin = this.field_1_margin; - return rec; - } -} // END OF \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/RowRecord.java b/trunk/src/java/org/apache/poi/hssf/record/RowRecord.java deleted file mode 100644 index 20951cb9f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/RowRecord.java +++ /dev/null @@ -1,424 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Row Record (0x0208)

    - * Description: stores the row information for the sheet.

    - * REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - * - * @since 2.0-pre - */ -public final class RowRecord extends StandardRecord { - public final static short sid = 0x0208; - - public static final int ENCODED_SIZE = 20; - - private static final int OPTION_BITS_ALWAYS_SET = 0x0100; - //private static final int DEFAULT_HEIGHT_BIT = 0x8000; - - private int field_1_row_number; - private int field_2_first_col; - private int field_3_last_col; // plus 1 - private short field_4_height; - private short field_5_optimize; // hint field for gui, can/should be set to zero - - // for generated sheets. - private short field_6_reserved; - /** 16 bit options flags */ - private int field_7_option_flags; - private static final BitField outlineLevel = BitFieldFactory.getInstance(0x07); - // bit 3 reserved - private static final BitField colapsed = BitFieldFactory.getInstance(0x10); - private static final BitField zeroHeight = BitFieldFactory.getInstance(0x20); - private static final BitField badFontHeight = BitFieldFactory.getInstance(0x40); - private static final BitField formatted = BitFieldFactory.getInstance(0x80); - - /** 16 bit options flags */ - private int field_8_option_flags; // only if isFormatted - private static final BitField xfIndex = BitFieldFactory.getInstance(0xFFF); - private static final BitField topBorder = BitFieldFactory.getInstance(0x1000); - private static final BitField bottomBorder = BitFieldFactory.getInstance(0x2000); - private static final BitField phoeneticGuide = BitFieldFactory.getInstance(0x4000); - // bit 15 is unused - - public RowRecord(int rowNumber) { - if(rowNumber < 0) { - throw new IllegalArgumentException("Invalid row number (" + rowNumber + ")"); - } - field_1_row_number = rowNumber; - field_4_height = (short)0xFF; - field_5_optimize = ( short ) 0; - field_6_reserved = ( short ) 0; - field_7_option_flags = OPTION_BITS_ALWAYS_SET; // seems necessary for outlining - - field_8_option_flags = ( short ) 0xf; - setEmpty(); - } - - public RowRecord(RecordInputStream in) { - field_1_row_number = in.readUShort(); - if(field_1_row_number < 0) { - throw new IllegalArgumentException("Invalid row number " + field_1_row_number + " found in InputStream"); - } - field_2_first_col = in.readShort(); - field_3_last_col = in.readShort(); - field_4_height = in.readShort(); - field_5_optimize = in.readShort(); - field_6_reserved = in.readShort(); - field_7_option_flags = in.readShort(); - field_8_option_flags = in.readShort(); - } - - /** - * Updates the firstCol and lastCol fields to the reserved value (-1) - * to signify that this row is empty - */ - public void setEmpty() { - field_2_first_col = 0; - field_3_last_col = 0; - } - public boolean isEmpty() { - return (field_2_first_col | field_3_last_col) == 0; - } - - /** - * set the logical row number for this row (0 based index) - * @param row - the row number - */ - public void setRowNumber(int row) { - field_1_row_number = row; - } - - /** - * set the logical col number for the first cell this row (0 based index) - * @param col - the col number - */ - public void setFirstCol(int col) { - field_2_first_col = col; - } - - /** - * @param col - one past the zero-based index to the last cell in this row - */ - public void setLastCol(int col) { - field_3_last_col = col; - } - - /** - * set the height of the row - * @param height of the row - */ - public void setHeight(short height) { - field_4_height = height; - } - - /** - * set whether to optimize or not (set to 0) - * @param optimize (set to 0) - */ - public void setOptimize(short optimize) { - field_5_optimize = optimize; - } - - // option bitfields - - /** - * set the outline level of this row - * @param ol - the outline level - */ - public void setOutlineLevel(short ol) { - field_7_option_flags = outlineLevel.setValue(field_7_option_flags, ol); - } - - /** - * set whether or not to collapse this row - * @param c - collapse or not - */ - public void setColapsed(boolean c) { - field_7_option_flags = colapsed.setBoolean(field_7_option_flags, c); - } - - /** - * set whether or not to display this row with 0 height - * @param z height is zero or not. - */ - public void setZeroHeight(boolean z) { - field_7_option_flags = zeroHeight.setBoolean(field_7_option_flags, z); - } - - /** - * set whether the font and row height are not compatible - * @param f true if they aren't compatible (damn not logic) - */ - public void setBadFontHeight(boolean f) { - field_7_option_flags = badFontHeight.setBoolean(field_7_option_flags, f); - } - - /** - * set whether the row has been formatted (even if its got all blank cells) - * @param f formatted or not - */ - public void setFormatted(boolean f) { - field_7_option_flags = formatted.setBoolean(field_7_option_flags, f); - } - - // end bitfields - - /** - * if the row is formatted then this is the index to the extended format record - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @param index to the XF record - */ - public void setXFIndex(short index) { - field_8_option_flags = xfIndex.setValue(field_8_option_flags, index); - } - - /** - * bit that specifies whether any cell in the row has a thick top border, or any - * cell in the row directly above the current row has a thick bottom border. - * @param f has thick top border - */ - public void setTopBorder(boolean f) { - field_8_option_flags = topBorder.setBoolean(field_8_option_flags, f); - } - - /** - * A bit that specifies whether any cell in the row has a medium or thick - * bottom border, or any cell in the row directly below the current row has - * a medium or thick top border. - * @param f has thick bottom border - */ - public void setBottomBorder(boolean f) { - field_8_option_flags = bottomBorder.setBoolean(field_8_option_flags, f); - } - - /** - * A bit that specifies whether the phonetic guide feature is enabled for - * any cell in this row. - * @param f use phoenetic guide - */ - public void setPhoeneticGuide(boolean f) { - field_8_option_flags = phoeneticGuide.setBoolean(field_8_option_flags, f); - } - - /** - * get the logical row number for this row (0 based index) - * @return row - the row number - */ - public int getRowNumber() { - return field_1_row_number; - } - - /** - * get the logical col number for the first cell this row (0 based index) - * @return col - the col number - */ - public int getFirstCol() { - return field_2_first_col; - } - - /** - * get the logical col number for the last cell this row (0 based index), plus one - * @return col - the last col index + 1 - */ - public int getLastCol() { - return field_3_last_col; - } - - /** - * get the height of the row - * @return height of the row - */ - public short getHeight() { - return field_4_height; - } - - /** - * get whether to optimize or not (set to 0) - * @return optimize (set to 0) - */ - public short getOptimize() { - return field_5_optimize; - } - - /** - * gets the option bitmask. (use the individual bit setters that refer to this - * method) - * @return options - the bitmask - */ - public short getOptionFlags() { - return (short)field_7_option_flags; - } - - // option bitfields - - /** - * get the outline level of this row - * @return ol - the outline level - * @see #getOptionFlags() - */ - public short getOutlineLevel() { - return (short)outlineLevel.getValue(field_7_option_flags); - } - - /** - * get whether or not to colapse this row - * @return c - colapse or not - * @see #getOptionFlags() - */ - public boolean getColapsed() { - return (colapsed.isSet(field_7_option_flags)); - } - - /** - * get whether or not to display this row with 0 height - * @return - z height is zero or not. - * @see #getOptionFlags() - */ - public boolean getZeroHeight() { - return zeroHeight.isSet(field_7_option_flags); - } - - /** - * get whether the font and row height are not compatible - * @return - f -true if they aren't compatible (damn not logic) - * @see #getOptionFlags() - */ - public boolean getBadFontHeight() { - return badFontHeight.isSet(field_7_option_flags); - } - - /** - * get whether the row has been formatted (even if its got all blank cells) - * @return formatted or not - * @see #getOptionFlags() - */ - public boolean getFormatted() { - return formatted.isSet(field_7_option_flags); - } - - // end bitfields - - /** - * gets the 2nd option bitmask. (use the individual bit setters that refer to this - * method) - * @return options - the bitmask - */ - public short getOptionFlags2() { - return (short)field_8_option_flags; - } - - /** - * if the row is formatted then this is the index to the extended format record - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @return index to the XF record or bogus value (undefined) if isn't formatted - */ - public short getXFIndex() { - return xfIndex.getShortValue((short)field_8_option_flags); - } - - /** - * A bit that specifies whether any cell in the row has a thick top border, or any - * cell in the row directly above the current row has a thick bottom border. - * @return has cells with a thick top border - */ - public boolean getTopBorder() { - return topBorder.isSet(field_8_option_flags); - } - - /** - * A bit that specifies whether any cell in the row has a medium or thick bottom border, - * or any cell in the row directly below the current row has a medium or thick top border. - * @return has cells with a thick bottom border - */ - public boolean getBottomBorder() { - return bottomBorder.isSet(field_8_option_flags); - } - - /** - * A bit that specifies whether the phonetic guide feature is enabled for - * any cell in this row. - * @return has phoentic guide - */ - public boolean getPhoeneticGuide() { - return phoeneticGuide.isSet(field_8_option_flags); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[ROW]\n"); - sb.append(" .rownumber = ").append(Integer.toHexString(getRowNumber())) - .append("\n"); - sb.append(" .firstcol = ").append(HexDump.shortToHex(getFirstCol())).append("\n"); - sb.append(" .lastcol = ").append(HexDump.shortToHex(getLastCol())).append("\n"); - sb.append(" .height = ").append(HexDump.shortToHex(getHeight())).append("\n"); - sb.append(" .optimize = ").append(HexDump.shortToHex(getOptimize())).append("\n"); - sb.append(" .reserved = ").append(HexDump.shortToHex(field_6_reserved)).append("\n"); - sb.append(" .optionflags = ").append(HexDump.shortToHex(getOptionFlags())).append("\n"); - sb.append(" .outlinelvl = ").append(Integer.toHexString(getOutlineLevel())).append("\n"); - sb.append(" .colapsed = ").append(getColapsed()).append("\n"); - sb.append(" .zeroheight = ").append(getZeroHeight()).append("\n"); - sb.append(" .badfontheig= ").append(getBadFontHeight()).append("\n"); - sb.append(" .formatted = ").append(getFormatted()).append("\n"); - sb.append(" .optionsflags2 = ").append(HexDump.shortToHex(getOptionFlags2())).append("\n"); - sb.append(" .xfindex = ").append(Integer.toHexString(getXFIndex())).append("\n"); - sb.append(" .topBorder = ").append(getTopBorder()).append("\n"); - sb.append(" .bottomBorder = ").append(getBottomBorder()).append("\n"); - sb.append(" .phoeneticGuide= ").append(getPhoeneticGuide()).append("\n"); - sb.append("[/ROW]\n"); - return sb.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getRowNumber()); - out.writeShort(getFirstCol() == -1 ? (short)0 : getFirstCol()); - out.writeShort(getLastCol() == -1 ? (short)0 : getLastCol()); - out.writeShort(getHeight()); - out.writeShort(getOptimize()); - out.writeShort(field_6_reserved); - out.writeShort(getOptionFlags()); - out.writeShort(getOptionFlags2()); - } - - protected int getDataSize() { - return ENCODED_SIZE - 4; - } - - public short getSid() { - return sid; - } - - public Object clone() { - RowRecord rec = new RowRecord(field_1_row_number); - rec.field_2_first_col = field_2_first_col; - rec.field_3_last_col = field_3_last_col; - rec.field_4_height = field_4_height; - rec.field_5_optimize = field_5_optimize; - rec.field_6_reserved = field_6_reserved; - rec.field_7_option_flags = field_7_option_flags; - rec.field_8_option_flags = field_8_option_flags; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SCLRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SCLRecord.java deleted file mode 100644 index 5b360937f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SCLRecord.java +++ /dev/null @@ -1,128 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Specifies the window's zoom magnification.

    - * If this record isn't present then the windows zoom is 100%. see p384 Excel Dev Kit - */ -public final class SCLRecord extends StandardRecord { - public final static short sid = 0x00A0; - private short field_1_numerator; - private short field_2_denominator; - - - public SCLRecord() - { - - } - - public SCLRecord(RecordInputStream in) - { - field_1_numerator = in.readShort(); - field_2_denominator = in.readShort(); - } - - @Override - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SCL]\n"); - buffer.append(" .numerator = ") - .append("0x").append(HexDump.toHex( getNumerator ())) - .append(" (").append( getNumerator() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .denominator = ") - .append("0x").append(HexDump.toHex( getDenominator ())) - .append(" (").append( getDenominator() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/SCL]\n"); - return buffer.toString(); - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_numerator); - out.writeShort(field_2_denominator); - } - - @Override - protected int getDataSize() { - return 2 + 2; - } - - @Override - public short getSid() - { - return sid; - } - - @Override - public Object clone() { - SCLRecord rec = new SCLRecord(); - - rec.field_1_numerator = field_1_numerator; - rec.field_2_denominator = field_2_denominator; - return rec; - } - - /** - * Get the numerator field for the SCL record. - * - * @return the numerator - */ - public short getNumerator() - { - return field_1_numerator; - } - - /** - * Set the numerator field for the SCL record. - * - * @param field_1_numerator the numerator - */ - public void setNumerator(short field_1_numerator) - { - this.field_1_numerator = field_1_numerator; - } - - /** - * Get the denominator field for the SCL record. - * - * @return the denominator - */ - public short getDenominator() - { - return field_2_denominator; - } - - /** - * Set the denominator field for the SCL record. - * - * @param field_2_denominator the denominator - */ - public void setDenominator(short field_2_denominator) - { - this.field_2_denominator = field_2_denominator; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SSTDeserializer.java b/trunk/src/java/org/apache/poi/hssf/record/SSTDeserializer.java deleted file mode 100644 index 181616185..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SSTDeserializer.java +++ /dev/null @@ -1,67 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.util.IntMapper; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Handles the task of deserializing a SST string. The two main entry points are - * - * @author Glen Stampoultzis (glens at apache.org) - * @author Jason Height (jheight at apache.org) - */ -class SSTDeserializer -{ - private static POILogger logger = POILogFactory.getLogger(SSTDeserializer.class); - private IntMapper strings; - - public SSTDeserializer( IntMapper strings ) - { - this.strings = strings; - } - - /** - * This is the starting point where strings are constructed. Note that - * strings may span across multiple continuations. Read the SST record - * carefully before beginning to hack. - */ - public void manufactureStrings( int stringCount, RecordInputStream in ) - { - for (int i=0;i strings, UnicodeString string ) - { - strings.add(string); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SSTRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SSTRecord.java deleted file mode 100644 index 43f42defd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SSTRecord.java +++ /dev/null @@ -1,321 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Iterator; - -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.hssf.record.cont.ContinuableRecord; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.util.IntMapper; -import org.apache.poi.util.LittleEndianConsts; - -/** - * Title: Static String Table Record (0x00FC)

    - * - * Description: This holds all the strings for LabelSSTRecords.

    - * - * REFERENCE: PG 389 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - * - * @see org.apache.poi.hssf.record.LabelSSTRecord - * @see org.apache.poi.hssf.record.ContinueRecord - */ -public final class SSTRecord extends ContinuableRecord { - public static final short sid = 0x00FC; - - private static final UnicodeString EMPTY_STRING = new UnicodeString(""); - - // TODO - move these constants to test class (the only consumer) - /** standard record overhead: two shorts (record id plus data space size)*/ - static final int STD_RECORD_OVERHEAD = 2 * LittleEndianConsts.SHORT_SIZE; - - /** SST overhead: the standard record overhead, plus the number of strings and the number of unique strings -- two ints */ - static final int SST_RECORD_OVERHEAD = STD_RECORD_OVERHEAD + 2 * LittleEndianConsts.INT_SIZE; - - /** how much data can we stuff into an SST record? That would be _max minus the standard SST record overhead */ - static final int MAX_DATA_SPACE = RecordInputStream.MAX_RECORD_DATA_SIZE - 8; - - /** union of strings in the SST and EXTSST */ - private int field_1_num_strings; - - /** according to docs ONLY SST */ - private int field_2_num_unique_strings; - private IntMapper field_3_strings; - - private SSTDeserializer deserializer; - - /** Offsets from the beginning of the SST record (even across continuations) */ - int[] bucketAbsoluteOffsets; - /** Offsets relative the start of the current SST or continue record */ - int[] bucketRelativeOffsets; - - public SSTRecord() - { - field_1_num_strings = 0; - field_2_num_unique_strings = 0; - field_3_strings = new IntMapper(); - deserializer = new SSTDeserializer(field_3_strings); - } - - /** - * Add a string. - * - * @param string string to be added - * - * @return the index of that string in the table - */ - public int addString(UnicodeString string) - { - field_1_num_strings++; - UnicodeString ucs = ( string == null ) ? EMPTY_STRING - : string; - int rval; - int index = field_3_strings.getIndex(ucs); - - if ( index != -1 ) { - rval = index; - } else { - // This is a new string -- we didn't see it among the - // strings we've already collected - rval = field_3_strings.size(); - field_2_num_unique_strings++; - SSTDeserializer.addToStringTable( field_3_strings, ucs ); - } - return rval; - } - - /** - * @return number of strings - */ - public int getNumStrings() - { - return field_1_num_strings; - } - - /** - * @return number of unique strings - */ - public int getNumUniqueStrings() - { - return field_2_num_unique_strings; - } - - - /** - * Get a particular string by its index - * - * @param id index into the array of strings - * - * @return the desired string - */ - public UnicodeString getString(int id ) - { - return field_3_strings.get( id ); - } - - - /** - * Return a debugging string representation - * - * @return string representation - */ - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append( "[SST]\n" ); - buffer.append( " .numstrings = " ) - .append( Integer.toHexString( getNumStrings() ) ).append( "\n" ); - buffer.append( " .uniquestrings = " ) - .append( Integer.toHexString( getNumUniqueStrings() ) ).append( "\n" ); - for ( int k = 0; k < field_3_strings.size(); k++ ) - { - UnicodeString s = field_3_strings.get( k ); - buffer.append( " .string_" + k + " = " ) - .append( s.getDebugInfo() ).append( "\n" ); - } - buffer.append( "[/SST]\n" ); - return buffer.toString(); - } - - public short getSid() { - return sid; - } - - /** - * Fill the fields from the data - *

    - * The data consists of sets of string data. This string data is - * arranged as follows: - *

    - *

    -     * short  string_length;   // length of string data
    -     * byte   string_flag;     // flag specifying special string
    -     *                         // handling
    -     * short  run_count;       // optional count of formatting runs
    -     * int    extend_length;   // optional extension length
    -     * char[] string_data;     // string data, can be byte[] or
    -     *                         // short[] (length of array is
    -     *                         // string_length)
    -     * int[]  formatting_runs; // optional formatting runs (length of
    -     *                         // array is run_count)
    -     * byte[] extension;       // optional extension (length of array
    -     *                         // is extend_length)
    -     * 
    - *

    - * The string_flag is bit mapped as follows: - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Bit numberMeaning if 0Meaning if 1
    0string_data is byte[]string_data is short[]
    1Should always be 0string_flag is defective
    2extension is not includedextension is included
    3formatting run data is not includedformatting run data is included
    4Should always be 0string_flag is defective
    5Should always be 0string_flag is defective
    6Should always be 0string_flag is defective
    7Should always be 0string_flag is defective
    - *

    - * We can handle eating the overhead associated with bits 2 or 3 - * (or both) being set, but we have no idea what to do with the - * associated data. The UnicodeString class can handle the byte[] - * vs short[] nature of the actual string data - * - * @param in the RecordInputstream to read the record from - */ - public SSTRecord(RecordInputStream in) { - // this method is ALWAYS called after construction -- using - // the nontrivial constructor, of course -- so this is where - // we initialize our fields - field_1_num_strings = in.readInt(); - field_2_num_unique_strings = in.readInt(); - field_3_strings = new IntMapper(); - - deserializer = new SSTDeserializer(field_3_strings); - // Bug 57456: some Excel Sheets send 0 as field=1, but have some random number in field_2, - // we should not try to read the strings in this case. - if(field_1_num_strings == 0) { - field_2_num_unique_strings = 0; - return; - } - deserializer.manufactureStrings( field_2_num_unique_strings, in ); - } - - - /** - * @return an iterator of the strings we hold. All instances are - * UnicodeStrings - */ - Iterator getStrings() - { - return field_3_strings.iterator(); - } - - /** - * @return count of the strings we hold. - */ - int countStrings() { - return field_3_strings.size(); - } - - protected void serialize(ContinuableRecordOutput out) { - SSTSerializer serializer = new SSTSerializer(field_3_strings, getNumStrings(), getNumUniqueStrings() ); - serializer.serialize(out); - bucketAbsoluteOffsets = serializer.getBucketAbsoluteOffsets(); - bucketRelativeOffsets = serializer.getBucketRelativeOffsets(); - } - - SSTDeserializer getDeserializer() { - return deserializer; - } - - /** - * Creates an extended string record based on the current contents of - * the current SST record. The offset within the stream to the SST record - * is required because the extended string record points directly to the - * strings in the SST record. - *

    - * NOTE: THIS FUNCTION MUST ONLY BE CALLED AFTER THE SST RECORD HAS BEEN - * SERIALIZED. - * - * @param sstOffset The offset in the stream to the start of the - * SST record. - * @return The new SST record. - */ - public ExtSSTRecord createExtSSTRecord(int sstOffset) { - if (bucketAbsoluteOffsets == null || bucketRelativeOffsets == null) { - throw new IllegalStateException("SST record has not yet been serialized."); - } - - ExtSSTRecord extSST = new ExtSSTRecord(); - extSST.setNumStringsPerBucket((short)8); - int[] absoluteOffsets = bucketAbsoluteOffsets.clone(); - int[] relativeOffsets = bucketRelativeOffsets.clone(); - for ( int i = 0; i < absoluteOffsets.length; i++ ) { - absoluteOffsets[i] += sstOffset; - } - extSST.setBucketOffsets(absoluteOffsets, relativeOffsets); - return extSST; - } - - /** - * Calculates the size in bytes of the EXTSST record as it would be if the - * record was serialized. - * - * @return The size of the ExtSST record in bytes. - */ - public int calcExtSSTRecordSize() { - return ExtSSTRecord.getRecordSizeForStrings(field_3_strings.size()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SSTSerializer.java b/trunk/src/java/org/apache/poi/hssf/record/SSTSerializer.java deleted file mode 100644 index c15c7ad1f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SSTSerializer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.util.IntMapper; - -/** - * This class handles serialization of SST records. It utilizes the record processor - * class write individual records. This has been refactored from the SSTRecord class. - * - * @author Glen Stampoultzis (glens at apache.org) - */ -final class SSTSerializer { - - private final int _numStrings; - private final int _numUniqueStrings; - - private final IntMapper strings; - - /** Offsets from the beginning of the SST record (even across continuations) */ - private final int[] bucketAbsoluteOffsets; - /** Offsets relative the start of the current SST or continue record */ - private final int[] bucketRelativeOffsets; - - public SSTSerializer( IntMapper strings, int numStrings, int numUniqueStrings ) - { - this.strings = strings; - _numStrings = numStrings; - _numUniqueStrings = numUniqueStrings; - - int infoRecs = ExtSSTRecord.getNumberOfInfoRecsForStrings(strings.size()); - this.bucketAbsoluteOffsets = new int[infoRecs]; - this.bucketRelativeOffsets = new int[infoRecs]; - } - - public void serialize(ContinuableRecordOutput out) { - out.writeInt(_numStrings); - out.writeInt(_numUniqueStrings); - - for ( int k = 0; k < strings.size(); k++ ) - { - if (k % ExtSSTRecord.DEFAULT_BUCKET_SIZE == 0) - { - int rOff = out.getTotalSize(); - int index = k/ExtSSTRecord.DEFAULT_BUCKET_SIZE; - if (index < ExtSSTRecord.MAX_BUCKETS) { - //Excel only indexes the first 128 buckets. - bucketAbsoluteOffsets[index] = rOff; - bucketRelativeOffsets[index] = rOff; - } - } - UnicodeString s = getUnicodeString(k); - s.serialize(out); - } - } - - - private UnicodeString getUnicodeString( int index ) - { - return getUnicodeString(strings, index); - } - - private static UnicodeString getUnicodeString( IntMapper strings, int index ) - { - return ( strings.get( index ) ); - } - - public int[] getBucketAbsoluteOffsets() - { - return bucketAbsoluteOffsets; - } - - public int[] getBucketRelativeOffsets() - { - return bucketRelativeOffsets; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SaveRecalcRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SaveRecalcRecord.java deleted file mode 100644 index 96cfde27c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SaveRecalcRecord.java +++ /dev/null @@ -1,98 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Save Recalc Record

    - * Description: defines whether to recalculate before saving (set to true)

    - * REFERENCE: PG 381 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class SaveRecalcRecord - extends StandardRecord -{ - public final static short sid = 0x5f; - private short field_1_recalc; - - public SaveRecalcRecord() - { - } - - public SaveRecalcRecord(RecordInputStream in) - { - field_1_recalc = in.readShort(); - } - - /** - * set whether to recalculate formulas/etc before saving or not - * @param recalc - whether to recalculate or not - */ - - public void setRecalc(boolean recalc) - { - field_1_recalc = ( short ) ((recalc == true) ? 1 - : 0); - } - - /** - * get whether to recalculate formulas/etc before saving or not - * @return recalc - whether to recalculate or not - */ - - public boolean getRecalc() - { - return (field_1_recalc == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SAVERECALC]\n"); - buffer.append(" .recalc = ").append(getRecalc()) - .append("\n"); - buffer.append("[/SAVERECALC]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_recalc); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - SaveRecalcRecord rec = new SaveRecalcRecord(); - rec.field_1_recalc = field_1_recalc; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/ScenarioProtectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/ScenarioProtectRecord.java deleted file mode 100644 index 37605c699..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/ScenarioProtectRecord.java +++ /dev/null @@ -1,106 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Scenario Protect Record

    - * Description: I have no idea what a Scenario is or why on would want to - * protect it with the lamest "security" ever invented. However this record tells - * excel "I want to protect my scenarios" (0xAF) with lame security. It appears - * in conjunction with the PASSWORD and PROTECT records as well as its object - * protect cousin.

    - * REFERENCE: PG 383 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - */ - -public final class ScenarioProtectRecord - extends StandardRecord -{ - public final static short sid = 0xdd; - private short field_1_protect; - - public ScenarioProtectRecord() - { - } - - public ScenarioProtectRecord(RecordInputStream in) - { - field_1_protect = in.readShort(); - } - - /** - * set whether the sheet is protected or not - * @param protect whether to protect the sheet or not - */ - - public void setProtect(boolean protect) - { - if (protect) - { - field_1_protect = 1; - } - else - { - field_1_protect = 0; - } - } - - /** - * get whether the sheet is protected or not - * @return whether to protect the sheet or not - */ - - public boolean getProtect() - { - return (field_1_protect == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SCENARIOPROTECT]\n"); - buffer.append(" .protect = ").append(getProtect()) - .append("\n"); - buffer.append("[/SCENARIOPROTECT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_protect); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - ScenarioProtectRecord rec = new ScenarioProtectRecord(); - rec.field_1_protect = field_1_protect; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SelectionRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SelectionRecord.java deleted file mode 100644 index 12928b95f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SelectionRecord.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Selection Record (0x001D)

    - * Description: shows the user's selection on the sheet - * for write set num refs to 0

    - * - * REFERENCE: PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class SelectionRecord extends StandardRecord { - public final static short sid = 0x001D; - private byte field_1_pane; - private int field_2_row_active_cell; - private int field_3_col_active_cell; - private int field_4_active_cell_ref_index; - private CellRangeAddress8Bit[] field_6_refs; - - /** - * Creates a default selection record (cell A1, in pane ID 3) - * - * @param activeCellRow the active cells row index - * @param activeCellCol the active cells column index - */ - public SelectionRecord(int activeCellRow, int activeCellCol) { - field_1_pane = 3; // pane id 3 is always present. see OOO sec 5.75 'PANE' - field_2_row_active_cell = activeCellRow; - field_3_col_active_cell = activeCellCol; - field_4_active_cell_ref_index = 0; - field_6_refs = new CellRangeAddress8Bit[] { - new CellRangeAddress8Bit(activeCellRow, activeCellRow, activeCellCol, activeCellCol), - }; - } - - public SelectionRecord(RecordInputStream in) { - field_1_pane = in.readByte(); - field_2_row_active_cell = in.readUShort(); - field_3_col_active_cell = in.readShort(); - field_4_active_cell_ref_index = in.readShort(); - int field_5_num_refs = in.readUShort(); - - field_6_refs = new CellRangeAddress8Bit[field_5_num_refs]; - for (int i = 0; i < field_6_refs.length; i++) { - field_6_refs[i] = new CellRangeAddress8Bit(in); - } - } - - /** - * set which window pane this is for - * @param pane the window pane - */ - public void setPane(byte pane) { - field_1_pane = pane; - } - - /** - * set the active cell's row - * @param row number of active cell - */ - public void setActiveCellRow(int row) { - field_2_row_active_cell = row; - } - - /** - * set the active cell's col - * @param col number of active cell - */ - public void setActiveCellCol(short col) { - field_3_col_active_cell = col; - } - - /** - * set the active cell's reference number - * @param ref number of active cell - */ - public void setActiveCellRef(short ref) { - field_4_active_cell_ref_index = ref; - } - - /** - * @return the pane ID which window pane this is for - */ - public byte getPane() { - return field_1_pane; - } - - /** - * get the active cell's row - * @return row number of active cell - */ - public int getActiveCellRow() { - return field_2_row_active_cell; - } - - /** - * get the active cell's col - * @return col number of active cell - */ - public int getActiveCellCol() { - return field_3_col_active_cell; - } - - /** - * get the active cell's reference number - * @return ref number of active cell - */ - public int getActiveCellRef() { - return field_4_active_cell_ref_index; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[SELECTION]\n"); - sb.append(" .pane = ").append(HexDump.byteToHex(getPane())).append("\n"); - sb.append(" .activecellrow = ").append(HexDump.shortToHex(getActiveCellRow())).append("\n"); - sb.append(" .activecellcol = ").append(HexDump.shortToHex(getActiveCellCol())).append("\n"); - sb.append(" .activecellref = ").append(HexDump.shortToHex(getActiveCellRef())).append("\n"); - sb.append(" .numrefs = ").append(HexDump.shortToHex(field_6_refs.length)).append("\n"); - sb.append("[/SELECTION]\n"); - return sb.toString(); - } - @Override - protected int getDataSize() { - return 9 // 1 byte + 4 shorts - + CellRangeAddress8Bit.getEncodedSize(field_6_refs.length); - } - @Override - public void serialize(LittleEndianOutput out) { - out.writeByte(getPane()); - out.writeShort(getActiveCellRow()); - out.writeShort(getActiveCellCol()); - out.writeShort(getActiveCellRef()); - int nRefs = field_6_refs.length; - out.writeShort(nRefs); - for (CellRangeAddress8Bit field_6_ref : field_6_refs) { - field_6_ref.serialize(out); - } - } - - @Override - public short getSid() { - return sid; - } - - @Override - public Object clone() { - SelectionRecord rec = new SelectionRecord(field_2_row_active_cell, field_3_col_active_cell); - rec.field_1_pane = field_1_pane; - rec.field_4_active_cell_ref_index = field_4_active_cell_ref_index; - rec.field_6_refs = field_6_refs; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java deleted file mode 100644 index 9acf82c80..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.formula.ptg.*; -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.SharedFormula; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: SHAREDFMLA (0x04BC) SharedFormulaRecord - * Description: Primarily used as an excel optimization so that multiple similar formulas - * are not written out too many times. We should recognize this record and - * serialize as is since this is used when reading templates. - *

    - * Note: the documentation says that the SID is BC where biffviewer reports 4BC. The hex dump shows - * that the two byte sid representation to be 'BC 04' that is consistent with the other high byte - * record types. - * @author Danny Mui at apache dot org - */ -public final class SharedFormulaRecord extends SharedValueRecordBase { - public final static short sid = 0x04BC; - - private int field_5_reserved; - private Formula field_7_parsed_expr; - - // for testing only - public SharedFormulaRecord() { - this(new CellRangeAddress8Bit(0,0,0,0)); - } - private SharedFormulaRecord(CellRangeAddress8Bit range) { - super(range); - field_7_parsed_expr = Formula.create(Ptg.EMPTY_PTG_ARRAY); - } - - /** - * @param in the RecordInputstream to read the record from - */ - public SharedFormulaRecord(RecordInputStream in) { - super(in); - field_5_reserved = in.readShort(); - int field_6_expression_len = in.readShort(); - int nAvailableBytes = in.available(); - field_7_parsed_expr = Formula.read(field_6_expression_len, in, nAvailableBytes); - } - - protected void serializeExtraData(LittleEndianOutput out) { - out.writeShort(field_5_reserved); - field_7_parsed_expr.serialize(out); - } - - protected int getExtraDataSize() { - return 2 + field_7_parsed_expr.getEncodedSize(); - } - - /** - * print a sort of string representation ([SHARED FORMULA RECORD] id = x [/SHARED FORMULA RECORD]) - */ - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SHARED FORMULA (").append(HexDump.intToHex(sid)).append("]\n"); - buffer.append(" .range = ").append(getRange().toString()).append("\n"); - buffer.append(" .reserved = ").append(HexDump.shortToHex(field_5_reserved)).append("\n"); - - Ptg[] ptgs = field_7_parsed_expr.getTokens(); - for (int k = 0; k < ptgs.length; k++ ) { - buffer.append("Formula[").append(k).append("]"); - Ptg ptg = ptgs[k]; - buffer.append(ptg.toString()).append(ptg.getRVAType()).append("\n"); - } - - buffer.append("[/SHARED FORMULA]\n"); - return buffer.toString(); - } - - public short getSid() { - return sid; - } - - /** - * @return the equivalent {@link Ptg} array that the formula would have, were it not shared. - */ - public Ptg[] getFormulaTokens(FormulaRecord formula) { - int formulaRow = formula.getRow(); - int formulaColumn = formula.getColumn(); - //Sanity checks - if (!isInRange(formulaRow, formulaColumn)) { - throw new RuntimeException("Shared Formula Conversion: Coding Error"); - } - - SharedFormula sf = new SharedFormula(SpreadsheetVersion.EXCEL97); - return sf.convertSharedFormulas(field_7_parsed_expr.getTokens(), formulaRow, formulaColumn); - } - - public Object clone() { - SharedFormulaRecord result = new SharedFormulaRecord(getRange()); - result.field_5_reserved = field_5_reserved; - result.field_7_parsed_expr = field_7_parsed_expr.copy(); - return result; - } - public boolean isFormulaSame(SharedFormulaRecord other) { - return field_7_parsed_expr.isSame(other.field_7_parsed_expr); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java b/trunk/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java deleted file mode 100644 index a5035303a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Common base class for {@link SharedFormulaRecord}, {@link ArrayRecord} and - * {@link TableRecord} which are have similarities. - */ -public abstract class SharedValueRecordBase extends StandardRecord { - - private CellRangeAddress8Bit _range; - - protected SharedValueRecordBase(CellRangeAddress8Bit range) { - if (range == null) { - throw new IllegalArgumentException("range must be supplied."); - } - _range = range; - } - - protected SharedValueRecordBase() { - this(new CellRangeAddress8Bit(0, 0, 0, 0)); - } - - /** - * reads only the range (1 {@link CellRangeAddress8Bit}) from the stream - */ - public SharedValueRecordBase(LittleEndianInput in) { - _range = new CellRangeAddress8Bit(in); - } - - /** - * @return the range of cells that this record is shared across. Never null. - */ - public final CellRangeAddress8Bit getRange() { - return _range; - } - - public final int getFirstRow() { - return _range.getFirstRow(); - } - - public final int getLastRow() { - return _range.getLastRow(); - } - - public final int getFirstColumn() { - return (short) _range.getFirstColumn(); - } - - public final int getLastColumn() { - return (short) _range.getLastColumn(); - } - - protected int getDataSize() { - return CellRangeAddress8Bit.ENCODED_SIZE + getExtraDataSize(); - } - - protected abstract int getExtraDataSize(); - - protected abstract void serializeExtraData(LittleEndianOutput out); - - public void serialize(LittleEndianOutput out) { - _range.serialize(out); - serializeExtraData(out); - } - - /** - * @param rowIx the row index - * @param colIx the column index - * - * @return {@code true} if (rowIx, colIx) is within the range of this shared value object. - * - * @see #getRange() - */ - public final boolean isInRange(int rowIx, int colIx) { - CellRangeAddress8Bit r = _range; - return r.getFirstRow() <= rowIx - && r.getLastRow() >= rowIx - && r.getFirstColumn() <= colIx - && r.getLastColumn() >= colIx; - } - /** - * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value - * object's range - * - * @param rowIx the row index - * @param colIx the column index - * - * @return {@code true} if its the first cell in this shared value object range - * - * @see #getRange() - */ - public final boolean isFirstCell(int rowIx, int colIx) { - CellRangeAddress8Bit r = getRange(); - return r.getFirstRow() == rowIx && r.getFirstColumn() == colIx; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java b/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java deleted file mode 100644 index 54886d7e2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Subclasses of this class (the majority of BIFF records) are non-continuable. This allows for - * some simplification of serialization logic - */ -public abstract class StandardRecord extends Record { - protected abstract int getDataSize(); - public final int getRecordSize() { - return 4 + getDataSize(); - } - - /** - * Write the data content of this BIFF record including the sid and record length. - *

    - * The subclass must write the exact number of bytes as reported by - * {@link org.apache.poi.hssf.record.Record#getRecordSize()}} - */ - @Override - public final int serialize(int offset, byte[] data) { - int dataSize = getDataSize(); - int recSize = 4 + dataSize; - LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize); - out.writeShort(getSid()); - out.writeShort(dataSize); - serialize(out); - if (out.getWriteIndex() - offset != recSize) { - throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): " - + "Incorrect number of bytes written - expected " - + recSize + " but got " + (out.getWriteIndex() - offset)); - } - return recSize; - } - - /** - * Write the data content of this BIFF record. The 'ushort sid' and 'ushort size' header fields - * have already been written by the superclass. - *

    - * The number of bytes written must equal the record size reported by - * {@link org.apache.poi.hssf.record.Record#getRecordSize()}} minus four - * ( record header consisting of a 'ushort sid' and 'ushort reclength' has already been written - * by their superclass). - * - * @param out the output object - */ - protected abstract void serialize(LittleEndianOutput out); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/StringRecord.java b/trunk/src/java/org/apache/poi/hssf/record/StringRecord.java deleted file mode 100644 index d2113df06..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/StringRecord.java +++ /dev/null @@ -1,101 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.cont.ContinuableRecord; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.util.StringUtil; - -/** - * STRING (0x0207)

    - * - * Stores the cached result of a text formula - */ -public final class StringRecord extends ContinuableRecord { - - public final static short sid = 0x0207; - - private boolean _is16bitUnicode; - private String _text; - - - public StringRecord() - { - } - - /** - * @param in the RecordInputstream to read the record from - */ - public StringRecord( RecordInputStream in) { - int field_1_string_length = in.readUShort(); - _is16bitUnicode = in.readByte() != 0x00; - - if (_is16bitUnicode){ - _text = in.readUnicodeLEString(field_1_string_length); - } else { - _text = in.readCompressedUnicode(field_1_string_length); - } - } - - - protected void serialize(ContinuableRecordOutput out) { - out.writeShort(_text.length()); - out.writeStringData(_text); - } - - - public short getSid() - { - return sid; - } - - /** - * @return The string represented by this record. - */ - public String getString() - { - return _text; - } - - - /** - * Sets the string represented by this record. - */ - public void setString(String string) { - _text = string; - _is16bitUnicode = StringUtil.hasMultibyte(string); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[STRING]\n"); - buffer.append(" .string = ") - .append(_text).append("\n"); - buffer.append("[/STRING]\n"); - return buffer.toString(); - } - - public Object clone() { - StringRecord rec = new StringRecord(); - rec._is16bitUnicode= _is16bitUnicode; - rec._text = _text; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/StyleRecord.java b/trunk/src/java/org/apache/poi/hssf/record/StyleRecord.java deleted file mode 100644 index 4d60217a2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/StyleRecord.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: Style Record (0x0293)

    - * Description: Describes a builtin to the gui or user defined style

    - * REFERENCE: PG 390 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class StyleRecord extends StandardRecord { - public final static short sid = 0x0293; - - private static final BitField styleIndexMask = BitFieldFactory.getInstance(0x0FFF); - private static final BitField isBuiltinFlag = BitFieldFactory.getInstance(0x8000); - - /** shared by both user defined and built-in styles */ - private int field_1_xf_index; - - // only for built in styles - private int field_2_builtin_style; - private int field_3_outline_style_level; - - // only for user defined styles - private boolean field_3_stringHasMultibyte; - private String field_4_name; - - /** - * creates a new style record, initially set to 'built-in' - */ - public StyleRecord() { - field_1_xf_index = isBuiltinFlag.set(0); - } - - public StyleRecord(RecordInputStream in) { - field_1_xf_index = in.readShort(); - if (isBuiltin()) { - field_2_builtin_style = in.readByte(); - field_3_outline_style_level = in.readByte(); - } else { - int field_2_name_length = in.readShort(); - - if(in.remaining() < 1) { - // Some files from Crystal Reports lack the is16BitUnicode byte - // the remaining fields, which is naughty - if (field_2_name_length != 0) { - throw new RecordFormatException("Ran out of data reading style record"); - } - // guess this is OK if the string length is zero - field_4_name = ""; - } else { - - field_3_stringHasMultibyte = in.readByte() != 0x00; - if (field_3_stringHasMultibyte) { - field_4_name = StringUtil.readUnicodeLE(in, field_2_name_length); - } else { - field_4_name = StringUtil.readCompressedUnicode(in, field_2_name_length); - } - } - } - } - - /** - * set the actual index of the style extended format record - * @param xfIndex of the xf record - */ - public void setXFIndex(int xfIndex) { - field_1_xf_index = styleIndexMask.setValue(field_1_xf_index, xfIndex); - } - - /** - * get the actual index of the style extended format record - * @see #getXFIndex() - * @return index of the xf record - */ - public int getXFIndex() { - return styleIndexMask.getValue(field_1_xf_index); - } - - /** - * set the style's name - * @param name of the style - */ - public void setName(String name) { - field_4_name = name; - field_3_stringHasMultibyte = StringUtil.hasMultibyte(name); - field_1_xf_index = isBuiltinFlag.clear(field_1_xf_index); - } - - /** - * if this is a builtin style set the number of the built in style - * @param builtinStyleId style number (0-7) - * - */ - public void setBuiltinStyle(int builtinStyleId) { - field_1_xf_index = isBuiltinFlag.set(field_1_xf_index); - field_2_builtin_style = builtinStyleId; - } - - /** - * set the row or column level of the style (if builtin 1||2) - */ - public void setOutlineStyleLevel(int level) { - field_3_outline_style_level = level & 0x00FF; - } - - public boolean isBuiltin(){ - return isBuiltinFlag.isSet(field_1_xf_index); - } - - /** - * get the style's name - * @return name of the style - */ - public String getName() { - return field_4_name; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("[STYLE]\n"); - sb.append(" .xf_index_raw =").append(HexDump.shortToHex(field_1_xf_index)).append("\n"); - sb.append(" .type =").append(isBuiltin() ? "built-in" : "user-defined").append("\n"); - sb.append(" .xf_index =").append(HexDump.shortToHex(getXFIndex())).append("\n"); - if (isBuiltin()){ - sb.append(" .builtin_style=").append(HexDump.byteToHex(field_2_builtin_style)).append("\n"); - sb.append(" .outline_level=").append(HexDump.byteToHex(field_3_outline_style_level)).append("\n"); - } else { - sb.append(" .name =").append(getName()).append("\n"); - } - sb.append("[/STYLE]\n"); - return sb.toString(); - } - - - @Override - protected int getDataSize() { - if (isBuiltin()) { - return 4; // short, byte, byte - } - return 2 // short xf index - + 3 // str len + flag - + field_4_name.length() * (field_3_stringHasMultibyte ? 2 : 1); - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_xf_index); - if (isBuiltin()) { - out.writeByte(field_2_builtin_style); - out.writeByte(field_3_outline_style_level); - } else { - out.writeShort(field_4_name.length()); - out.writeByte(field_3_stringHasMultibyte ? 0x01 : 0x00); - if (field_3_stringHasMultibyte) { - StringUtil.putUnicodeLE(getName(), out); - } else { - StringUtil.putCompressedUnicode(getName(), out); - } - } - } - - @Override - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SubRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SubRecord.java deleted file mode 100644 index 35b62c36c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SubRecord.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.LittleEndianOutputStream; - -import java.io.ByteArrayOutputStream; - -/** - * Subrecords are part of the OBJ class. - */ -public abstract class SubRecord { - protected SubRecord() { - // no fields to initialise - } - - /** - * read a sub-record from the supplied stream - * - * @param in the stream to read from - * @param cmoOt the objectType field of the containing CommonObjectDataSubRecord, - * we need it to propagate to next sub-records as it defines what data follows - * @return the created sub-record - */ - public static SubRecord createSubRecord(LittleEndianInput in, int cmoOt) { - int sid = in.readUShort(); - int secondUShort = in.readUShort(); // Often (but not always) the datasize for the sub-record - - switch (sid) { - case CommonObjectDataSubRecord.sid: - return new CommonObjectDataSubRecord(in, secondUShort); - case EmbeddedObjectRefSubRecord.sid: - return new EmbeddedObjectRefSubRecord(in, secondUShort); - case GroupMarkerSubRecord.sid: - return new GroupMarkerSubRecord(in, secondUShort); - case EndSubRecord.sid: - return new EndSubRecord(in, secondUShort); - case NoteStructureSubRecord.sid: - return new NoteStructureSubRecord(in, secondUShort); - case LbsDataSubRecord.sid: - return new LbsDataSubRecord(in, secondUShort, cmoOt); - case FtCblsSubRecord.sid: - return new FtCblsSubRecord(in, secondUShort); - case FtPioGrbitSubRecord.sid: - return new FtPioGrbitSubRecord(in, secondUShort); - case FtCfSubRecord.sid: - return new FtCfSubRecord(in, secondUShort); - } - return new UnknownSubRecord(in, sid, secondUShort); - } - - /** - * @return the size of the data for this record (which is always 4 bytes less than the total - * record size). Note however, that ushort encoded after the record sid is usually but not - * always the data size. - */ - protected abstract int getDataSize(); - public byte[] serialize() { - int size = getDataSize() + 4; - ByteArrayOutputStream baos = new ByteArrayOutputStream(size); - serialize(new LittleEndianOutputStream(baos)); - if (baos.size() != size) { - throw new RuntimeException("write size mismatch"); - } - return baos.toByteArray(); - } - - public abstract void serialize(LittleEndianOutput out); - public abstract Object clone(); - - /** - * Wether this record terminates the sub-record stream. - * There are two cases when this method must be overridden and return true - * - EndSubRecord (sid = 0x00) - * - LbsDataSubRecord (sid = 0x12) - * - * @return whether this record is the last in the sub-record stream - */ - public boolean isTerminating(){ - return false; - } - - private static final class UnknownSubRecord extends SubRecord { - - private final int _sid; - private final byte[] _data; - - public UnknownSubRecord(LittleEndianInput in, int sid, int size) { - _sid = sid; - byte[] buf = new byte[size]; - in.readFully(buf); - _data = buf; - } - protected int getDataSize() { - return _data.length; - } - public void serialize(LittleEndianOutput out) { - out.writeShort(_sid); - out.writeShort(_data.length); - out.write(_data); - } - public Object clone() { - return this; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append("sid=").append(HexDump.shortToHex(_sid)); - sb.append(" size=").append(_data.length); - sb.append(" : ").append(HexDump.toHex(_data)); - sb.append("]\n"); - return sb.toString(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java b/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java deleted file mode 100644 index 9067c24cc..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java +++ /dev/null @@ -1,256 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * Title: Sup Book - EXTERNALBOOK (0x01AE)

    - * Description: A External Workbook Description (Supplemental Book) - * Its only a dummy record for making new ExternSheet Record

    - * REFERENCE: 5.38 - */ -public final class SupBookRecord extends StandardRecord { - - private final static POILogger logger = POILogFactory.getLogger(SupBookRecord.class); - - public final static short sid = 0x01AE; - - private static final short SMALL_RECORD_SIZE = 4; - private static final short TAG_INTERNAL_REFERENCES = 0x0401; - private static final short TAG_ADD_IN_FUNCTIONS = 0x3A01; - - private short field_1_number_of_sheets; - private String field_2_encoded_url; - private String[] field_3_sheet_names; - private boolean _isAddInFunctions; - - protected static final char CH_VOLUME = 1; - protected static final char CH_SAME_VOLUME = 2; - protected static final char CH_DOWN_DIR = 3; - protected static final char CH_UP_DIR = 4; - protected static final char CH_LONG_VOLUME = 5; - protected static final char CH_STARTUP_DIR = 6; - protected static final char CH_ALT_STARTUP_DIR = 7; - protected static final char CH_LIB_DIR = 8; - protected static final String PATH_SEPERATOR = System.getProperty("file.separator"); - - public static SupBookRecord createInternalReferences(short numberOfSheets) { - return new SupBookRecord(false, numberOfSheets); - } - public static SupBookRecord createAddInFunctions() { - return new SupBookRecord(true, (short)1 /* this field MUST be 0x0001 for add-in referencing */); - } - public static SupBookRecord createExternalReferences(String url, String[] sheetNames) { - return new SupBookRecord(url, sheetNames); - } - private SupBookRecord(boolean isAddInFuncs, short numberOfSheets) { - // else not 'External References' - field_1_number_of_sheets = numberOfSheets; - field_2_encoded_url = null; - field_3_sheet_names = null; - _isAddInFunctions = isAddInFuncs; - } - public SupBookRecord(String url, String[] sheetNames) { - field_1_number_of_sheets = (short) sheetNames.length; - field_2_encoded_url = url; - field_3_sheet_names = sheetNames; - _isAddInFunctions = false; - } - - public boolean isExternalReferences() { - return field_3_sheet_names != null; - } - public boolean isInternalReferences() { - return field_3_sheet_names == null && !_isAddInFunctions; - } - public boolean isAddInFunctions() { - return field_3_sheet_names == null && _isAddInFunctions; - } - /** - * called by the constructor, should set class level fields. Should throw - * runtime exception for bad/incomplete data. - * - * @param in the stream to read from - */ - public SupBookRecord(RecordInputStream in) { - int recLen = in.remaining(); - - field_1_number_of_sheets = in.readShort(); - - if(recLen > SMALL_RECORD_SIZE) { - // 5.38.1 External References - _isAddInFunctions = false; - - field_2_encoded_url = in.readString(); - String[] sheetNames = new String[field_1_number_of_sheets]; - for (int i = 0; i < sheetNames.length; i++) { - sheetNames[i] = in.readString(); - } - field_3_sheet_names = sheetNames; - return; - } - // else not 'External References' - field_2_encoded_url = null; - field_3_sheet_names = null; - - short nextShort = in.readShort(); - if(nextShort == TAG_INTERNAL_REFERENCES) { - // 5.38.2 'Internal References' - _isAddInFunctions = false; - } else if(nextShort == TAG_ADD_IN_FUNCTIONS) { - // 5.38.3 'Add-In Functions' - _isAddInFunctions = true; - if(field_1_number_of_sheets != 1) { - throw new RuntimeException("Expected 0x0001 for number of sheets field in 'Add-In Functions' but got (" - + field_1_number_of_sheets + ")"); - } - } else { - throw new RuntimeException("invalid EXTERNALBOOK code (" - + Integer.toHexString(nextShort) + ")"); - } - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("[SUPBOOK "); - - if(isExternalReferences()) { - sb.append("External References]\n"); - sb.append(" .url = ").append(field_2_encoded_url).append("\n"); - sb.append(" .nSheets = ").append(field_1_number_of_sheets).append("\n"); - for (String sheetname : field_3_sheet_names) { - sb.append(" .name = ").append(sheetname).append("\n"); - } - sb.append("[/SUPBOOK"); - } else if(_isAddInFunctions) { - sb.append("Add-In Functions"); - } else { - sb.append("Internal References"); - sb.append(" nSheets=").append(field_1_number_of_sheets); - } - sb.append("]"); - return sb.toString(); - } - protected int getDataSize() { - if(!isExternalReferences()) { - return SMALL_RECORD_SIZE; - } - int sum = 2; // u16 number of sheets - - sum += StringUtil.getEncodedSize(field_2_encoded_url); - - for(int i=0; i - * Description: Contains an array of sheet id's. Sheets always keep their ID - * regardless of what their name is.

    - * REFERENCE: PG 412 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class TabIdRecord extends StandardRecord { - public final static short sid = 0x013D; - private static final short[] EMPTY_SHORT_ARRAY = { }; - - public short[] _tabids; - - public TabIdRecord() { - _tabids = EMPTY_SHORT_ARRAY; - } - - public TabIdRecord(RecordInputStream in) { - int nTabs = in.remaining() / 2; - _tabids = new short[nTabs]; - for (int i = 0; i < _tabids.length; i++) { - _tabids[i] = in.readShort(); - } - } - - /** - * set the tab array. (0,1,2). - * @param array of tab id's {0,1,2} - */ - public void setTabIdArray(short[] array) { - _tabids = array.clone(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[TABID]\n"); - buffer.append(" .elements = ").append(_tabids.length).append("\n"); - for (int i = 0; i < _tabids.length; i++) { - buffer.append(" .element_").append(i).append(" = ").append(_tabids[i]).append("\n"); - } - buffer.append("[/TABID]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - short[] tabids = _tabids; - - for (int i = 0; i < tabids.length; i++) { - out.writeShort(tabids[i]); - } - } - - protected int getDataSize() { - return _tabids.length * 2; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/TableRecord.java b/trunk/src/java/org/apache/poi/hssf/record/TableRecord.java deleted file mode 100644 index 7c42db206..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/TableRecord.java +++ /dev/null @@ -1,179 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.ss.formula.ptg.TblPtg; -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.hssf.util.CellReference; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -/** - * DATATABLE (0x0236)

    - * - * TableRecord - The record specifies a data table. - * This record is preceded by a single Formula record that - * defines the first cell in the data table, which should - * only contain a single Ptg, {@link TblPtg}. - * - * See p536 of the June 08 binary docs - */ -public final class TableRecord extends SharedValueRecordBase { - public static final short sid = 0x0236; - - private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001); - private static final BitField calcOnOpen = BitFieldFactory.getInstance(0x0002); - private static final BitField rowOrColInpCell = BitFieldFactory.getInstance(0x0004); - private static final BitField oneOrTwoVar = BitFieldFactory.getInstance(0x0008); - private static final BitField rowDeleted = BitFieldFactory.getInstance(0x0010); - private static final BitField colDeleted = BitFieldFactory.getInstance(0x0020); - - private int field_5_flags; - private int field_6_res; - private int field_7_rowInputRow; - private int field_8_colInputRow; - private int field_9_rowInputCol; - private int field_10_colInputCol; - - public TableRecord(RecordInputStream in) { - super(in); - field_5_flags = in.readByte(); - field_6_res = in.readByte(); - field_7_rowInputRow = in.readShort(); - field_8_colInputRow = in.readShort(); - field_9_rowInputCol = in.readShort(); - field_10_colInputCol = in.readShort(); - } - - public TableRecord(CellRangeAddress8Bit range) { - super(range); - field_6_res = 0; - } - - public int getFlags() { - return field_5_flags; - } - public void setFlags(int flags) { - field_5_flags = flags; - } - - public int getRowInputRow() { - return field_7_rowInputRow; - } - public void setRowInputRow(int rowInputRow) { - field_7_rowInputRow = rowInputRow; - } - - public int getColInputRow() { - return field_8_colInputRow; - } - public void setColInputRow(int colInputRow) { - field_8_colInputRow = colInputRow; - } - - public int getRowInputCol() { - return field_9_rowInputCol; - } - public void setRowInputCol(int rowInputCol) { - field_9_rowInputCol = rowInputCol; - } - - public int getColInputCol() { - return field_10_colInputCol; - } - public void setColInputCol(int colInputCol) { - field_10_colInputCol = colInputCol; - } - - - public boolean isAlwaysCalc() { - return alwaysCalc.isSet(field_5_flags); - } - public void setAlwaysCalc(boolean flag) { - field_5_flags = alwaysCalc.setBoolean(field_5_flags, flag); - } - - public boolean isRowOrColInpCell() { - return rowOrColInpCell.isSet(field_5_flags); - } - public void setRowOrColInpCell(boolean flag) { - field_5_flags = rowOrColInpCell.setBoolean(field_5_flags, flag); - } - - public boolean isOneNotTwoVar() { - return oneOrTwoVar.isSet(field_5_flags); - } - public void setOneNotTwoVar(boolean flag) { - field_5_flags = oneOrTwoVar.setBoolean(field_5_flags, flag); - } - - public boolean isColDeleted() { - return colDeleted.isSet(field_5_flags); - } - public void setColDeleted(boolean flag) { - field_5_flags = colDeleted.setBoolean(field_5_flags, flag); - } - - public boolean isRowDeleted() { - return rowDeleted.isSet(field_5_flags); - } - public void setRowDeleted(boolean flag) { - field_5_flags = rowDeleted.setBoolean(field_5_flags, flag); - } - - - public short getSid() { - return sid; - } - protected int getExtraDataSize() { - return - 2 // 2 byte fields - + 8; // 4 short fields - } - protected void serializeExtraData(LittleEndianOutput out) { - out.writeByte(field_5_flags); - out.writeByte(field_6_res); - out.writeShort(field_7_rowInputRow); - out.writeShort(field_8_colInputRow); - out.writeShort(field_9_rowInputCol); - out.writeShort(field_10_colInputCol); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[TABLE]\n"); - buffer.append(" .range = ").append(getRange().toString()).append("\n"); - buffer.append(" .flags = ") .append(HexDump.byteToHex(field_5_flags)).append("\n"); - buffer.append(" .alwaysClc= ").append(isAlwaysCalc()).append("\n"); - buffer.append(" .reserved = ").append(HexDump.intToHex(field_6_res)).append("\n"); - CellReference crRowInput = cr(field_7_rowInputRow, field_8_colInputRow); - CellReference crColInput = cr(field_9_rowInputCol, field_10_colInputCol); - buffer.append(" .rowInput = ").append(crRowInput.formatAsString()).append("\n"); - buffer.append(" .colInput = ").append(crColInput.formatAsString()).append("\n"); - buffer.append("[/TABLE]\n"); - return buffer.toString(); - } - - private static CellReference cr(int rowIx, int colIxAndFlags) { - int colIx = colIxAndFlags & 0x00FF; - boolean isRowAbs = (colIxAndFlags & 0x8000) == 0; - boolean isColAbs = (colIxAndFlags & 0x4000) == 0; - return new CellReference(rowIx, colIx, isRowAbs, isColAbs); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/TableStylesRecord.java b/trunk/src/java/org/apache/poi/hssf/record/TableStylesRecord.java deleted file mode 100644 index 27bd8a71f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/TableStylesRecord.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * TABLESTYLES (0x088E) - */ -public final class TableStylesRecord extends StandardRecord { - public static final short sid = 0x088E; - - private int rt; - private int grbitFrt; - private byte[] unused = new byte[8]; - private int cts; - - private String rgchDefListStyle; - private String rgchDefPivotStyle; - - - public TableStylesRecord(RecordInputStream in) { - rt = in.readUShort(); - grbitFrt = in.readUShort(); - in.readFully(unused); - cts = in.readInt(); - int cchDefListStyle = in.readUShort(); - int cchDefPivotStyle = in.readUShort(); - - rgchDefListStyle = in.readUnicodeLEString(cchDefListStyle); - rgchDefPivotStyle = in.readUnicodeLEString(cchDefPivotStyle); - } - - @Override - protected void serialize(LittleEndianOutput out) { - out.writeShort(rt); - out.writeShort(grbitFrt); - out.write(unused); - out.writeInt(cts); - - out.writeShort(rgchDefListStyle.length()); - out.writeShort(rgchDefPivotStyle.length()); - - StringUtil.putUnicodeLE(rgchDefListStyle, out); - StringUtil.putUnicodeLE(rgchDefPivotStyle, out); - } - - @Override - protected int getDataSize() { - return 2 + 2 + 8 + 4 + 2 + 2 - + (2*rgchDefListStyle.length()) + (2*rgchDefPivotStyle.length()); - } - - @Override - public short getSid() { - return sid; - } - - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[TABLESTYLES]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt=").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .unused =").append(HexDump.toHex(unused)).append('\n'); - buffer.append(" .cts=").append(HexDump.intToHex(cts)).append('\n'); - buffer.append(" .rgchDefListStyle=").append(rgchDefListStyle).append('\n'); - buffer.append(" .rgchDefPivotStyle=").append(rgchDefPivotStyle).append('\n'); - - buffer.append("[/TABLESTYLES]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/TextObjectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/TextObjectRecord.java deleted file mode 100644 index 148bee315..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/TextObjectRecord.java +++ /dev/null @@ -1,342 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.hssf.record.cont.ContinuableRecord; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.ss.formula.ptg.OperandPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.hssf.usermodel.HSSFRichTextString; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; - -/** - * The TXO record (0x01B6) is used to define the properties of a text box. It is - * followed by two or more continue records unless there is no actual text. The - * first continue records contain the text data and the last continue record - * contains the formatting runs. - */ -public final class TextObjectRecord extends ContinuableRecord { - public final static short sid = 0x01B6; - - private static final int FORMAT_RUN_ENCODED_SIZE = 8; // 2 shorts and 4 bytes reserved - - private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E); - private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070); - private static final BitField textLocked = BitFieldFactory.getInstance(0x0200); - - public final static short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1; - public final static short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2; - public final static short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3; - public final static short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4; - public final static short VERTICAL_TEXT_ALIGNMENT_TOP = 1; - public final static short VERTICAL_TEXT_ALIGNMENT_CENTER = 2; - public final static short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3; - public final static short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4; - - public final static short TEXT_ORIENTATION_NONE = 0; - public final static short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1; - public final static short TEXT_ORIENTATION_ROT_RIGHT = 2; - public final static short TEXT_ORIENTATION_ROT_LEFT = 3; - - private int field_1_options; - private int field_2_textOrientation; - private int field_3_reserved4; - private int field_4_reserved5; - private int field_5_reserved6; - private int field_8_reserved7; - - private HSSFRichTextString _text; - - /* - * Note - the next three fields are very similar to those on - * EmbededObjectRefSubRecord(ftPictFmla 0x0009) - * - * some observed values for the 4 bytes preceding the formula: C0 5E 86 03 - * C0 11 AC 02 80 F1 8A 03 D4 F0 8A 03 - */ - private int _unknownPreFormulaInt; - /** expect tRef, tRef3D, tArea, tArea3D or tName */ - private OperandPtg _linkRefPtg; - /** - * Not clear if needed . Excel seems to be OK if this byte is not present. - * Value is often the same as the earlier firstColumn byte. */ - private Byte _unknownPostFormulaByte; - - public TextObjectRecord() { - // - } - - public TextObjectRecord(RecordInputStream in) { - field_1_options = in.readUShort(); - field_2_textOrientation = in.readUShort(); - field_3_reserved4 = in.readUShort(); - field_4_reserved5 = in.readUShort(); - field_5_reserved6 = in.readUShort(); - int field_6_textLength = in.readUShort(); - int field_7_formattingDataLength = in.readUShort(); - field_8_reserved7 = in.readInt(); - - if (in.remaining() > 0) { - // Text Objects can have simple reference formulas - // (This bit not mentioned in the MS document) - if (in.remaining() < 11) { - throw new RecordFormatException("Not enough remaining data for a link formula"); - } - int formulaSize = in.readUShort(); - _unknownPreFormulaInt = in.readInt(); - Ptg[] ptgs = Ptg.readTokens(formulaSize, in); - if (ptgs.length != 1) { - throw new RecordFormatException("Read " + ptgs.length - + " tokens but expected exactly 1"); - } - _linkRefPtg = (OperandPtg) ptgs[0]; - if (in.remaining() > 0) { - _unknownPostFormulaByte = Byte.valueOf(in.readByte()); - } else { - _unknownPostFormulaByte = null; - } - } else { - _linkRefPtg = null; - } - if (in.remaining() > 0) { - throw new RecordFormatException("Unused " + in.remaining() + " bytes at end of record"); - } - - String text; - if (field_6_textLength > 0) { - text = readRawString(in, field_6_textLength); - } else { - text = ""; - } - _text = new HSSFRichTextString(text); - - if (field_7_formattingDataLength > 0) { - processFontRuns(in, _text, field_7_formattingDataLength); - } - } - - private static String readRawString(RecordInputStream in, int textLength) { - byte compressByte = in.readByte(); - boolean isCompressed = (compressByte & 0x01) == 0; - if (isCompressed) { - return in.readCompressedUnicode(textLength); - } - return in.readUnicodeLEString(textLength); - } - - private static void processFontRuns(RecordInputStream in, HSSFRichTextString str, - int formattingRunDataLength) { - if (formattingRunDataLength % FORMAT_RUN_ENCODED_SIZE != 0) { - throw new RecordFormatException("Bad format run data length " + formattingRunDataLength - + ")"); - } - int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE; - for (int i = 0; i < nRuns; i++) { - short index = in.readShort(); - short iFont = in.readShort(); - in.readInt(); // skip reserved. - str.applyFont(index, str.length(), iFont); - } - } - - public short getSid() { - return sid; - } - - private void serializeTXORecord(ContinuableRecordOutput out) { - - out.writeShort(field_1_options); - out.writeShort(field_2_textOrientation); - out.writeShort(field_3_reserved4); - out.writeShort(field_4_reserved5); - out.writeShort(field_5_reserved6); - out.writeShort(_text.length()); - out.writeShort(getFormattingDataLength()); - out.writeInt(field_8_reserved7); - - if (_linkRefPtg != null) { - int formulaSize = _linkRefPtg.getSize(); - out.writeShort(formulaSize); - out.writeInt(_unknownPreFormulaInt); - _linkRefPtg.write(out); - if (_unknownPostFormulaByte != null) { - out.writeByte(_unknownPostFormulaByte.byteValue()); - } - } - } - - private void serializeTrailingRecords(ContinuableRecordOutput out) { - out.writeContinue(); - out.writeStringData(_text.getString()); - out.writeContinue(); - writeFormatData(out, _text); - } - - protected void serialize(ContinuableRecordOutput out) { - - serializeTXORecord(out); - if (_text.getString().length() > 0) { - serializeTrailingRecords(out); - } - } - - private int getFormattingDataLength() { - if (_text.length() < 1) { - // important - no formatting data if text is empty - return 0; - } - return (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE; - } - - private static void writeFormatData(ContinuableRecordOutput out , HSSFRichTextString str) { - int nRuns = str.numFormattingRuns(); - for (int i = 0; i < nRuns; i++) { - out.writeShort(str.getIndexOfFormattingRun(i)); - int fontIndex = str.getFontOfFormattingRun(i); - out.writeShort(fontIndex == HSSFRichTextString.NO_FONT ? 0 : fontIndex); - out.writeInt(0); // skip reserved - } - out.writeShort(str.length()); - out.writeShort(0); - out.writeInt(0); // skip reserved - } - - /** - * Sets the Horizontal text alignment field value. - */ - public void setHorizontalTextAlignment(int value) { - field_1_options = HorizontalTextAlignment.setValue(field_1_options, value); - } - - /** - * @return the Horizontal text alignment field value. - */ - public int getHorizontalTextAlignment() { - return HorizontalTextAlignment.getValue(field_1_options); - } - - /** - * Sets the Vertical text alignment field value. - */ - public void setVerticalTextAlignment(int value) { - field_1_options = VerticalTextAlignment.setValue(field_1_options, value); - } - - /** - * @return the Vertical text alignment field value. - */ - public int getVerticalTextAlignment() { - return VerticalTextAlignment.getValue(field_1_options); - } - - /** - * Sets the text locked field value. - */ - public void setTextLocked(boolean value) { - field_1_options = textLocked.setBoolean(field_1_options, value); - } - - /** - * @return the text locked field value. - */ - public boolean isTextLocked() { - return textLocked.isSet(field_1_options); - } - - /** - * Get the text orientation field for the TextObjectBase record. - * - * @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM - * TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT - */ - public int getTextOrientation() { - return field_2_textOrientation; - } - - /** - * Set the text orientation field for the TextObjectBase record. - * - * @param textOrientation - * One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM - * TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT - */ - public void setTextOrientation(int textOrientation) { - this.field_2_textOrientation = textOrientation; - } - - public HSSFRichTextString getStr() { - return _text; - } - - public void setStr(HSSFRichTextString str) { - _text = str; - } - - public Ptg getLinkRefPtg() { - return _linkRefPtg; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[TXO]\n"); - sb.append(" .options = ").append(HexDump.shortToHex(field_1_options)).append("\n"); - sb.append(" .isHorizontal = ").append(getHorizontalTextAlignment()).append('\n'); - sb.append(" .isVertical = ").append(getVerticalTextAlignment()).append('\n'); - sb.append(" .textLocked = ").append(isTextLocked()).append('\n'); - sb.append(" .textOrientation= ").append(HexDump.shortToHex(getTextOrientation())).append("\n"); - sb.append(" .reserved4 = ").append(HexDump.shortToHex(field_3_reserved4)).append("\n"); - sb.append(" .reserved5 = ").append(HexDump.shortToHex(field_4_reserved5)).append("\n"); - sb.append(" .reserved6 = ").append(HexDump.shortToHex(field_5_reserved6)).append("\n"); - sb.append(" .textLength = ").append(HexDump.shortToHex(_text.length())).append("\n"); - sb.append(" .reserved7 = ").append(HexDump.intToHex(field_8_reserved7)).append("\n"); - - sb.append(" .string = ").append(_text).append('\n'); - - for (int i = 0; i < _text.numFormattingRuns(); i++) { - sb.append(" .textrun = ").append(_text.getFontOfFormattingRun(i)).append('\n'); - - } - sb.append("[/TXO]\n"); - return sb.toString(); - } - - public Object clone() { - - TextObjectRecord rec = new TextObjectRecord(); - rec._text = _text; - - rec.field_1_options = field_1_options; - rec.field_2_textOrientation = field_2_textOrientation; - rec.field_3_reserved4 = field_3_reserved4; - rec.field_4_reserved5 = field_4_reserved5; - rec.field_5_reserved6 = field_5_reserved6; - rec.field_8_reserved7 = field_8_reserved7; - - rec._text = _text; // clone needed? - - if (_linkRefPtg != null) { - rec._unknownPreFormulaInt = _unknownPreFormulaInt; - rec._linkRefPtg = _linkRefPtg.copy(); - rec._unknownPostFormulaByte = _unknownPostFormulaByte; - } - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/TopMarginRecord.java b/trunk/src/java/org/apache/poi/hssf/record/TopMarginRecord.java deleted file mode 100644 index 2dfa32b46..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/TopMarginRecord.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.*; - -/** - * Record for the top margin. - */ -public final class TopMarginRecord extends StandardRecord implements Margin { - public final static short sid = 0x28; - private double field_1_margin; - - public TopMarginRecord() { } - - /** - * @param in the RecordInputstream to read the record from - */ - public TopMarginRecord( RecordInputStream in ) - { - field_1_margin = in.readDouble(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - buffer.append( "[TopMargin]\n" ); - buffer.append( " .margin = " ).append( " (" ).append( getMargin() ).append( " )\n" ); - buffer.append( "[/TopMargin]\n" ); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeDouble(field_1_margin); - } - - protected int getDataSize() { - return 8; - } - - public short getSid() { return sid; } - - /** - * Get the margin field for the TopMargin record. - */ - public double getMargin() { return field_1_margin; } - - /** - * Set the margin field for the TopMargin record. - */ - public void setMargin( double field_1_margin ) - { this.field_1_margin = field_1_margin; } - - public Object clone() - { - TopMarginRecord rec = new TopMarginRecord(); - rec.field_1_margin = this.field_1_margin; - return rec; - } -} // END OF \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java b/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java deleted file mode 100644 index 2ae3e03e7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Uncalced Record - *

    - * If this record occurs in the Worksheet Substream, it indicates that the formulas have not - * been recalculated before the document was saved. - * - * @author Olivier Leprince - */ -public final class UncalcedRecord extends StandardRecord { - public final static short sid = 0x005E; - - private short _reserved; - - public UncalcedRecord() { - _reserved = 0; - } - - public short getSid() { - return sid; - } - - public UncalcedRecord(RecordInputStream in) { - _reserved = in.readShort(); // unused - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[UNCALCED]\n"); - buffer.append(" _reserved: ").append(_reserved).append('\n'); - buffer.append("[/UNCALCED]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_reserved); - } - - protected int getDataSize() { - return 2; - } - - public static int getStaticRecordSize() { - return 6; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/UnknownRecord.java b/trunk/src/java/org/apache/poi/hssf/record/UnknownRecord.java deleted file mode 100644 index 59bab98f2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/UnknownRecord.java +++ /dev/null @@ -1,294 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Locale; - -import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Unknown Record (for debugging)

    - * Description: Unknown record just tells you the sid so you can figure out - * what records you are missing. Also helps us read/modify sheets we - * don't know all the records to. (HSSF leaves these alone!)

    - * Company: SuperLink Software, Inc. - */ -public final class UnknownRecord extends StandardRecord { - - /* - * Some Record IDs used by POI as 'milestones' in the record stream - */ - /** - * seems to be part of the {@link PageSettingsBlock}. Not interpreted by POI. - * The name 'PRINTSIZE' was taken from OOO source.

    - * The few POI test samples with this record have data { 0x03, 0x00 }. - */ - public static final int PRINTSIZE_0033 = 0x0033; - /** - * Environment-Specific Print Record - */ - public static final int PLS_004D = 0x004D; - public static final int SHEETPR_0081 = 0x0081; - public static final int SORT_0090 = 0x0090; - public static final int STANDARDWIDTH_0099 = 0x0099; - public static final int SCL_00A0 = 0x00A0; - public static final int BITMAP_00E9 = 0x00E9; - public static final int PHONETICPR_00EF = 0x00EF; - public static final int LABELRANGES_015F = 0x015F; - public static final int QUICKTIP_0800 = 0x0800; - public static final int SHEETEXT_0862 = 0x0862; // OOO calls this SHEETLAYOUT - public static final int SHEETPROTECTION_0867 = 0x0867; - public static final int HEADER_FOOTER_089C = 0x089C; - public static final int CODENAME_1BA = 0x01BA; - public static final int PLV_MAC = 0x08C8; - - private int _sid; - private byte[] _rawData; - - /** - * @param id id of the record -not validated, just stored for serialization - * @param data the data - */ - public UnknownRecord(int id, byte[] data) { - _sid = id & 0xFFFF; - _rawData = data; - } - - - /** - * construct an unknown record. No fields are interpreted and the record will - * be serialized in its original form more or less - * @param in the RecordInputstream to read the record from - */ - public UnknownRecord(RecordInputStream in) { - _sid = in.getSid(); - _rawData = in.readRemainder(); -// if (false && getBiffName(_sid) == null) { -// // unknown sids in the range 0x0004-0x0013 are probably 'sub-records' of ObjectRecord -// // those sids are in a different number space. -// // TODO - put unknown OBJ sub-records in a different class -// System.out.println("Unknown record 0x" + -// Integer.toHexString(_sid).toUpperCase(Locale.ROOT)); -// } - } - - /** - * spit the record out AS IS. no interpretation or identification - */ - @Override - public void serialize(LittleEndianOutput out) { - out.write(_rawData); - } - - @Override - protected int getDataSize() { - return _rawData.length; - } - - /** - * print a sort of string representation ([UNKNOWN RECORD] id = x [/UNKNOWN RECORD]) - */ - @Override - public String toString() { - String biffName = getBiffName(_sid); - if (biffName == null) { - biffName = "UNKNOWNRECORD"; - } - StringBuffer sb = new StringBuffer(); - - sb.append("[").append(biffName).append("] (0x"); - sb.append(Integer.toHexString(_sid).toUpperCase(Locale.ROOT) + ")\n"); - if (_rawData.length > 0) { - sb.append(" rawData=").append(HexDump.toHex(_rawData)).append("\n"); - } - sb.append("[/").append(biffName).append("]\n"); - return sb.toString(); - } - - @Override - public short getSid() { - return (short) _sid; - } - - /** - * These BIFF record types are known but still uninterpreted by POI - * - * @return the documented name of this BIFF record type, null if unknown to POI - */ - public static String getBiffName(int sid) { - // Note to POI developers: - // Make sure you delete the corresponding entry from - // this method any time a new Record subclass is created. - switch (sid) { - case PRINTSIZE_0033: return "PRINTSIZE"; - case PLS_004D: return "PLS"; - case 0x0050: return "DCON"; // Data Consolidation Information - case 0x007F: return "IMDATA"; - case SHEETPR_0081: return "SHEETPR"; - case SORT_0090: return "SORT"; // Sorting Options - case 0x0094: return "LHRECORD"; // .WK? File Conversion Information - case STANDARDWIDTH_0099: return "STANDARDWIDTH"; //Standard Column Width - case SCL_00A0: return "SCL"; // Window Zoom Magnification - case 0x00AE: return "SCENMAN"; // Scenario Output Data - - case 0x00B2: return "SXVI"; // (pivot table) View Item - case 0x00B4: return "SXIVD"; // (pivot table) Row/Column Field IDs - case 0x00B5: return "SXLI"; // (pivot table) Line Item Array - - case 0x00D3: return "OBPROJ"; - case 0x00DC: return "PARAMQRY"; - case 0x00DE: return "OLESIZE"; - case BITMAP_00E9: return "BITMAP"; - case PHONETICPR_00EF: return "PHONETICPR"; - case 0x00F1: return "SXEX"; // PivotTable View Extended Information - - case LABELRANGES_015F: return "LABELRANGES"; - case 0x01BA: return "CODENAME"; - case 0x01A9: return "USERBVIEW"; - case 0x01AD: return "QSI"; - - case 0x01C0: return "EXCEL9FILE"; - - case 0x0802: return "QSISXTAG"; // Pivot Table and Query Table Extensions - case 0x0803: return "DBQUERYEXT"; - case 0x0805: return "TXTQUERY"; - case 0x0810: return "SXVIEWEX9"; // Pivot Table Extensions - - case 0x0812: return "CONTINUEFRT"; - case QUICKTIP_0800: return "QUICKTIP"; - case SHEETEXT_0862: return "SHEETEXT"; - case 0x0863: return "BOOKEXT"; - case 0x0864: return "SXADDL"; // Pivot Table Additional Info - case SHEETPROTECTION_0867: return "SHEETPROTECTION"; - case 0x086B: return "DATALABEXTCONTENTS"; - case 0x086C: return "CELLWATCH"; - case FeatRecord.v11_sid: return "SHARED FEATURE v11"; - case 0x0874: return "DROPDOWNOBJIDS"; - case 0x0876: return "DCONN"; - case FeatRecord.v12_sid: return "SHARED FEATURE v12"; - case 0x087B: return "CFEX"; - case 0x087C: return "XFCRC"; - case 0x087D: return "XFEXT"; - case 0x087F: return "CONTINUEFRT12"; - case 0x088B: return "PLV"; - case 0x088C: return "COMPAT12"; - case 0x088D: return "DXF"; - case 0x0892: return "STYLEEXT"; - case 0x0896: return "THEME"; - case 0x0897: return "GUIDTYPELIB"; - case 0x089A: return "MTRSETTINGS"; - case 0x089B: return "COMPRESSPICTURES"; - case HEADER_FOOTER_089C: return "HEADERFOOTER"; - case 0x089D: return "CRTLAYOUT12"; - case 0x089E: return "CRTMLFRT"; - case 0x089F: return "CRTMLFRTCONTINUE"; - case 0x08A1: return "SHAPEPROPSSTREAM"; - case 0x08A3: return "FORCEFULLCALCULATION"; - case 0x08A4: return "SHAPEPROPSSTREAM"; - case 0x08A5: return "TEXTPROPSSTREAM"; - case 0x08A6: return "RICHTEXTSTREAM"; - case 0x08A7: return "CRTLAYOUT12A"; - - case 0x08C8: return "PLV{Mac Excel}"; - - case 0x1001: return "UNITS"; - case 0x1006: return "CHARTDATAFORMAT"; - case 0x1007: return "CHARTLINEFORMAT"; - } - if (isObservedButUnknown(sid)) { - return "UNKNOWN-" + Integer.toHexString(sid).toUpperCase(Locale.ROOT); - } - - return null; - } - - /** - * @return true if the unknown record id has been observed in POI unit tests - */ - private static boolean isObservedButUnknown(int sid) { - // TODO Look up more of these in the latest [MS-XLS] doc and move to getBiffName - switch (sid) { - case 0x0033: - // contains 2 bytes of data: 0x0001 or 0x0003 - case 0x0034: - // Seems to be written by MSAccess - // contains text "[Microsoft JET Created Table]0021010" - // appears after last cell value record and before WINDOW2 - case 0x01BD: - case 0x01C2: - // Written by Excel 2007 - // rawData is multiple of 12 bytes long - // appears after last cell value record and before WINDOW2 or drawing records - - case 0x1009: - case 0x100A: - case 0x100B: - case 0x100C: - case 0x1014: - case 0x1017: - case 0x1018: - case 0x1019: - case 0x101A: - case 0x101B: - case 0x101D: - case 0x101E: - case 0x101F: - case 0x1020: - case 0x1021: - case 0x1022: - case 0x1024: - case 0x1025: - case 0x1026: - case 0x1027: - case 0x1032: - case 0x1033: - case 0x1034: - case 0x1035: - case 0x103A: - case 0x1041: - case 0x1043: - case 0x1044: - case 0x1045: - case 0x1046: - case 0x104A: - case 0x104B: - case 0x104E: - case 0x104F: - case 0x1051: - case 0x105C: - case 0x105D: - case 0x105F: - case 0x1060: - case 0x1062: - case 0x1063: - case 0x1064: - case 0x1065: - case 0x1066: - return true; - } - return false; - } - - @Override - public Object clone() { - // immutable - OK to return this - return this; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/UseSelFSRecord.java b/trunk/src/java/org/apache/poi/hssf/record/UseSelFSRecord.java deleted file mode 100644 index 19fdf35f0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/UseSelFSRecord.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: USESELFS (0x0160) - Use Natural Language Formulas Flag

    - * Description: Tells the GUI if this was written by something that can use - * "natural language" formulas. HSSF can't.

    - * REFERENCE: PG 420 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class UseSelFSRecord extends StandardRecord { - public final static short sid = 0x0160; - - private static final BitField useNaturalLanguageFormulasFlag = BitFieldFactory.getInstance(0x0001); - - private int _options; - - private UseSelFSRecord(int options) { - _options = options; - } - - public UseSelFSRecord(RecordInputStream in) { - this(in.readUShort()); - } - - public UseSelFSRecord(boolean b) { - this(0); - _options = useNaturalLanguageFormulasFlag.setBoolean(_options, b); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[USESELFS]\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(_options)).append("\n"); - buffer.append("[/USESELFS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_options); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() { - return sid; - } - - @Override - public Object clone() { - return new UseSelFSRecord(_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/UserSViewBegin.java b/trunk/src/java/org/apache/poi/hssf/record/UserSViewBegin.java deleted file mode 100644 index 1c4895a53..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/UserSViewBegin.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Locale; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The UserSViewBegin record specifies settings for a custom view associated with the sheet. - * This record also marks the start of custom view records, which save custom view settings. - * Records between {@link UserSViewBegin} and {@link UserSViewEnd} contain settings for the custom view, - * not settings for the sheet itself. - * - * @author Yegor Kozlov - */ -public final class UserSViewBegin extends StandardRecord { - - public final static short sid = 0x01AA; - private byte[] _rawData; - - public UserSViewBegin(byte[] data) { - _rawData = data; - } - - /** - * construct an UserSViewBegin record. No fields are interpreted and the record will - * be serialized in its original form more or less - * @param in the RecordInputstream to read the record from - */ - public UserSViewBegin(RecordInputStream in) { - _rawData = in.readRemainder(); - } - - /** - * spit the record out AS IS. no interpretation or identification - */ - public void serialize(LittleEndianOutput out) { - out.write(_rawData); - } - - protected int getDataSize() { - return _rawData.length; - } - - public short getSid() - { - return sid; - } - - /** - * @return Globally unique identifier for the custom view - */ - public byte[] getGuid(){ - byte[] guid = new byte[16]; - System.arraycopy(_rawData, 0, guid, 0, guid.length); - return guid; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[").append("USERSVIEWBEGIN").append("] (0x"); - sb.append(Integer.toHexString(sid).toUpperCase(Locale.ROOT) + ")\n"); - sb.append(" rawData=").append(HexDump.toHex(_rawData)).append("\n"); - sb.append("[/").append("USERSVIEWBEGIN").append("]\n"); - return sb.toString(); - } - - //HACK: do a "cheat" clone, see Record.java for more information - public Object clone() { - return cloneViaReserialise(); - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/UserSViewEnd.java b/trunk/src/java/org/apache/poi/hssf/record/UserSViewEnd.java deleted file mode 100644 index aa72eacd5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/UserSViewEnd.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Locale; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The UserSViewEnd record marks the end of the settings for a custom view associated with the sheet - */ -public final class UserSViewEnd extends StandardRecord { - - public final static short sid = 0x01AB; - private byte[] _rawData; - - public UserSViewEnd(byte[] data) { - _rawData = data; - } - - /** - * construct an UserSViewEnd record. No fields are interpreted and the record will - * be serialized in its original form more or less - * @param in the RecordInputstream to read the record from - */ - public UserSViewEnd(RecordInputStream in) { - _rawData = in.readRemainder(); - } - - /** - * spit the record out AS IS. no interpretation or identification - */ - public void serialize(LittleEndianOutput out) { - out.write(_rawData); - } - - protected int getDataSize() { - return _rawData.length; - } - - public short getSid() - { - return sid; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[").append("USERSVIEWEND").append("] (0x"); - sb.append(Integer.toHexString(sid).toUpperCase(Locale.ROOT) + ")\n"); - sb.append(" rawData=").append(HexDump.toHex(_rawData)).append("\n"); - sb.append("[/").append("USERSVIEWEND").append("]\n"); - return sb.toString(); - } - - //HACK: do a "cheat" clone, see Record.java for more information - public Object clone() { - return cloneViaReserialise(); - } - - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/VCenterRecord.java b/trunk/src/java/org/apache/poi/hssf/record/VCenterRecord.java deleted file mode 100644 index f14845c7e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/VCenterRecord.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: VCenter record

    - * Description: tells whether to center the sheet between vertical margins

    - * REFERENCE: PG 420 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ - -public final class VCenterRecord extends StandardRecord { - public final static short sid = 0x84; - private int field_1_vcenter; - - public VCenterRecord() - { - } - - public VCenterRecord(RecordInputStream in) - { - field_1_vcenter = in.readShort(); - } - - /** - * set whether to center vertically or not - * @param hc vcenter or not - */ - - public void setVCenter(boolean hc) - { - field_1_vcenter = hc ? 1 : 0; - } - - /** - * get whether to center vertically or not - * @return vcenter or not - */ - - public boolean getVCenter() - { - return (field_1_vcenter == 1); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[VCENTER]\n"); - buffer.append(" .vcenter = ").append(getVCenter()) - .append("\n"); - buffer.append("[/VCENTER]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_vcenter); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - VCenterRecord rec = new VCenterRecord(); - rec.field_1_vcenter = field_1_vcenter; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java b/trunk/src/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java deleted file mode 100644 index f15baf6ff..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Iterator; - -/** - * VerticalPageBreak (0x001A) record that stores page breaks at columns - * - * @see PageBreakRecord - */ -public final class VerticalPageBreakRecord extends PageBreakRecord { - - public static final short sid = 0x001A; - - /** - * Creates an empty vertical page break record - */ - public VerticalPageBreakRecord() { - - } - - /** - * @param in the RecordInputstream to read the record from - */ - public VerticalPageBreakRecord(RecordInputStream in) { - super(in); - } - - public short getSid() { - return sid; - } - - public Object clone() { - PageBreakRecord result = new VerticalPageBreakRecord(); - Iterator iterator = getBreaksIterator(); - while (iterator.hasNext()) { - Break original = iterator.next(); - result.addBreak(original.main, original.subFrom, original.subTo); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/WSBoolRecord.java b/trunk/src/java/org/apache/poi/hssf/record/WSBoolRecord.java deleted file mode 100644 index 78185c1df..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/WSBoolRecord.java +++ /dev/null @@ -1,335 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: WSBOOL (0x0081) (called SHEETPR in OOO doc)

    - * Description: stores workbook settings (aka its a big "everything we didn't - * put somewhere else")

    - * REFERENCE: PG 425 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class WSBoolRecord extends StandardRecord { - public final static short sid = 0x0081; - private byte field_1_wsbool; // crappy names are because this is really one big short field (2byte) - private byte field_2_wsbool; // but the docs inconsistently use it as 2 separate bytes - - // I decided to be consistent in this way. - private static final BitField autobreaks = BitFieldFactory.getInstance(0x01); // are automatic page breaks visible - - // bits 1 to 3 unused - private static final BitField dialog = BitFieldFactory.getInstance(0x10); // is sheet dialog sheet - private static final BitField applystyles = BitFieldFactory.getInstance(0x20); // whether to apply automatic styles to outlines - private static final BitField rowsumsbelow = BitFieldFactory.getInstance(0x40); // whether summary rows will appear below detail in outlines - private static final BitField rowsumsright = BitFieldFactory.getInstance(0x80); // whether summary rows will appear right of the detail in outlines - private static final BitField fittopage = BitFieldFactory.getInstance(0x01); // whether to fit stuff to the page - - // bit 2 reserved - private static final BitField displayguts = BitFieldFactory.getInstance(0x06); // whether to display outline symbols (in the gutters) - - // bits 4-5 reserved - private static final BitField alternateexpression = BitFieldFactory.getInstance(0x40); // whether to use alternate expression eval - private static final BitField alternateformula = BitFieldFactory.getInstance(0x80); // whether to use alternate formula entry - - public WSBoolRecord() - { - } - - public WSBoolRecord(RecordInputStream in) - { - byte data[] = in.readRemainder(); - field_1_wsbool = - data[ 1 ]; // backwards because theoretically this is one short field - field_2_wsbool = - data[ 0 ]; // but it was easier to implement it this way to avoid confusion - } // because the dev kit shows the masks for it as 2 byte fields - - // why? Why ask why? But don't drink bud dry as its a really - // crappy beer, try the czech "Budvar" beer (which is the real - // budweiser though its ironically good...its sold in the USs - // as czechvar --- odd that they had the name first but can't - // use it)... - - /** - * set first byte (see bit setters) - */ - - public void setWSBool1(byte bool1) - { - field_1_wsbool = bool1; - } - - // bool1 bitfields - - /** - * show automatic page breaks or not - * @param ab whether to show auto page breaks - */ - - public void setAutobreaks(boolean ab) - { - field_1_wsbool = autobreaks.setByteBoolean(field_1_wsbool, ab); - } - - /** - * set whether sheet is a dialog sheet or not - * @param isDialog or not - */ - - public void setDialog(boolean isDialog) - { - field_1_wsbool = dialog.setByteBoolean(field_1_wsbool, isDialog); - } - - /** - * set if row summaries appear below detail in the outline - * @param below or not - */ - - public void setRowSumsBelow(boolean below) - { - field_1_wsbool = rowsumsbelow.setByteBoolean(field_1_wsbool, below); - } - - /** - * set if col summaries appear right of the detail in the outline - * @param right or not - */ - - public void setRowSumsRight(boolean right) - { - field_1_wsbool = rowsumsright.setByteBoolean(field_1_wsbool, right); - } - - // end bitfields - - /** - * set the second byte (see bit setters) - */ - - public void setWSBool2(byte bool2) - { - field_2_wsbool = bool2; - } - - // bool2 bitfields - - /** - * fit to page option is on - * @param fit2page fit or not - */ - - public void setFitToPage(boolean fit2page) - { - field_2_wsbool = fittopage.setByteBoolean(field_2_wsbool, fit2page); - } - - /** - * set whether to display the guts or not - * - * @param guts or no guts (or glory) - */ - - public void setDisplayGuts(boolean guts) - { - field_2_wsbool = displayguts.setByteBoolean(field_2_wsbool, guts); - } - - /** - * whether alternate expression evaluation is on - * @param altexp alternative expression evaluation or not - */ - - public void setAlternateExpression(boolean altexp) - { - field_2_wsbool = alternateexpression.setByteBoolean(field_2_wsbool, - altexp); - } - - /** - * whether alternative formula entry is on - * @param formula alternative formulas or not - */ - - public void setAlternateFormula(boolean formula) - { - field_2_wsbool = alternateformula.setByteBoolean(field_2_wsbool, - formula); - } - - // end bitfields - - /** - * get first byte (see bit getters) - */ - - public byte getWSBool1() - { - return field_1_wsbool; - } - - // bool1 bitfields - - /** - * show automatic page breaks or not - * @return whether to show auto page breaks - */ - - public boolean getAutobreaks() - { - return autobreaks.isSet(field_1_wsbool); - } - - /** - * get whether sheet is a dialog sheet or not - * @return isDialog or not - */ - - public boolean getDialog() - { - return dialog.isSet(field_1_wsbool); - } - - /** - * get if row summaries appear below detail in the outline - * @return below or not - */ - - public boolean getRowSumsBelow() - { - return rowsumsbelow.isSet(field_1_wsbool); - } - - /** - * get if col summaries appear right of the detail in the outline - * @return right or not - */ - - public boolean getRowSumsRight() - { - return rowsumsright.isSet(field_1_wsbool); - } - - // end bitfields - - /** - * get the second byte (see bit getters) - */ - - public byte getWSBool2() - { - return field_2_wsbool; - } - - // bool2 bitfields - - /** - * fit to page option is on - * @return fit or not - */ - - public boolean getFitToPage() - { - return fittopage.isSet(field_2_wsbool); - } - - /** - * get whether to display the guts or not - * - * @return guts or no guts (or glory) - */ - - public boolean getDisplayGuts() - { - return displayguts.isSet(field_2_wsbool); - } - - /** - * whether alternate expression evaluation is on - * @return alternative expression evaluation or not - */ - - public boolean getAlternateExpression() - { - return alternateexpression.isSet(field_2_wsbool); - } - - /** - * whether alternative formula entry is on - * @return alternative formulas or not - */ - - public boolean getAlternateFormula() - { - return alternateformula.isSet(field_2_wsbool); - } - - // end bitfields - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[WSBOOL]\n"); - buffer.append(" .wsbool1 = ") - .append(Integer.toHexString(getWSBool1())).append("\n"); - buffer.append(" .autobreaks = ").append(getAutobreaks()) - .append("\n"); - buffer.append(" .dialog = ").append(getDialog()) - .append("\n"); - buffer.append(" .rowsumsbelw= ").append(getRowSumsBelow()) - .append("\n"); - buffer.append(" .rowsumsrigt= ").append(getRowSumsRight()) - .append("\n"); - buffer.append(" .wsbool2 = ") - .append(Integer.toHexString(getWSBool2())).append("\n"); - buffer.append(" .fittopage = ").append(getFitToPage()) - .append("\n"); - buffer.append(" .displayguts= ").append(getDisplayGuts()) - .append("\n"); - buffer.append(" .alternateex= ") - .append(getAlternateExpression()).append("\n"); - buffer.append(" .alternatefo= ").append(getAlternateFormula()) - .append("\n"); - buffer.append("[/WSBOOL]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(getWSBool2()); - out.writeByte(getWSBool1()); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - WSBoolRecord rec = new WSBoolRecord(); - rec.field_1_wsbool = field_1_wsbool; - rec.field_2_wsbool = field_2_wsbool; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/WindowOneRecord.java b/trunk/src/java/org/apache/poi/hssf/record/WindowOneRecord.java deleted file mode 100644 index 440348e37..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/WindowOneRecord.java +++ /dev/null @@ -1,410 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Window1 Record

    - * Description: Stores the attributes of the workbook window. This is basically - * so the gui knows how big to make the window holding the spreadsheet - * document.

    - * REFERENCE: PG 421 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @version 2.0-pre - */ -public final class WindowOneRecord extends StandardRecord { - public final static short sid = 0x3d; - - // our variable names stolen from old TV sets. - private short field_1_h_hold; // horizontal position - private short field_2_v_hold; // vertical position - private short field_3_width; - private short field_4_height; - private short field_5_options; - static final private BitField hidden = - BitFieldFactory.getInstance(0x01); // is this window is hidden - static final private BitField iconic = - BitFieldFactory.getInstance(0x02); // is this window is an icon - @SuppressWarnings("unused") - static final private BitField reserved = BitFieldFactory.getInstance(0x04); // reserved - static final private BitField hscroll = - BitFieldFactory.getInstance(0x08); // display horizontal scrollbar - static final private BitField vscroll = - BitFieldFactory.getInstance(0x10); // display vertical scrollbar - static final private BitField tabs = - BitFieldFactory.getInstance(0x20); // display tabs at the bottom - - // all the rest are "reserved" - private int field_6_active_sheet; - private int field_7_first_visible_tab; - private short field_8_num_selected_tabs; - private short field_9_tab_width_ratio; - - public WindowOneRecord() - { - } - - public WindowOneRecord(RecordInputStream in) - { - field_1_h_hold = in.readShort(); - field_2_v_hold = in.readShort(); - field_3_width = in.readShort(); - field_4_height = in.readShort(); - field_5_options = in.readShort(); - field_6_active_sheet = in.readShort(); - field_7_first_visible_tab = in.readShort(); - field_8_num_selected_tabs = in.readShort(); - field_9_tab_width_ratio = in.readShort(); - } - - /** - * set the horizontal position of the window (in 1/20ths of a point) - * @param h - horizontal location - */ - - public void setHorizontalHold(short h) - { - field_1_h_hold = h; - } - - /** - * set the vertical position of the window (in 1/20ths of a point) - * @param v - vertical location - */ - - public void setVerticalHold(short v) - { - field_2_v_hold = v; - } - - /** - * set the width of the window - * @param w width - */ - - public void setWidth(short w) - { - field_3_width = w; - } - - /** - * set teh height of the window - * @param h height - */ - - public void setHeight(short h) - { - field_4_height = h; - } - - /** - * set the options bitmask (see bit setters) - * - * @param o - the bitmask - */ - - public void setOptions(short o) - { - field_5_options = o; - } - - // bitfields for options - - /** - * set whether the window is hidden or not - * @param ishidden or not - */ - - public void setHidden(boolean ishidden) - { - field_5_options = hidden.setShortBoolean(field_5_options, ishidden); - } - - /** - * set whether the window has been iconized or not - * @param isiconic iconize or not - */ - - public void setIconic(boolean isiconic) - { - field_5_options = iconic.setShortBoolean(field_5_options, isiconic); - } - - /** - * set whether to display the horizontal scrollbar or not - * @param scroll display or not - */ - - public void setDisplayHorizonalScrollbar(boolean scroll) - { - field_5_options = hscroll.setShortBoolean(field_5_options, scroll); - } - - /** - * set whether to display the vertical scrollbar or not - * @param scroll display or not - */ - - public void setDisplayVerticalScrollbar(boolean scroll) - { - field_5_options = vscroll.setShortBoolean(field_5_options, scroll); - } - - /** - * set whether to display the tabs or not - * @param disptabs display or not - */ - - public void setDisplayTabs(boolean disptabs) - { - field_5_options = tabs.setShortBoolean(field_5_options, disptabs); - } - - // end bitfields - - public void setActiveSheetIndex(int index) { - field_6_active_sheet = index; - } - - /** - * Sets the first visible sheet in the worksheet tab-bar. This method does not - * hide, select or focus sheets. It just sets the scroll position in the tab-bar. - * @param t the sheet index of the tab that will become the first in the tab-bar - */ - public void setFirstVisibleTab(int t) { - field_7_first_visible_tab = t; - } - - /** - * set the number of selected tabs - * @param n number of tabs - */ - - public void setNumSelectedTabs(short n) - { - field_8_num_selected_tabs = n; - } - - /** - * ratio of the width of the tabs to the horizontal scrollbar - * @param r ratio - */ - - public void setTabWidthRatio(short r) - { - field_9_tab_width_ratio = r; - } - - /** - * get the horizontal position of the window (in 1/20ths of a point) - * @return h - horizontal location - */ - - public short getHorizontalHold() - { - return field_1_h_hold; - } - - /** - * get the vertical position of the window (in 1/20ths of a point) - * @return v - vertical location - */ - - public short getVerticalHold() - { - return field_2_v_hold; - } - - /** - * get the width of the window - * @return width - */ - - public short getWidth() - { - return field_3_width; - } - - /** - * get the height of the window - * @return height - */ - - public short getHeight() - { - return field_4_height; - } - - /** - * get the options bitmask (see bit setters) - * - * @return o - the bitmask - */ - - public short getOptions() - { - return field_5_options; - } - - // bitfields for options - - /** - * get whether the window is hidden or not - * @return ishidden or not - */ - - public boolean getHidden() - { - return hidden.isSet(field_5_options); - } - - /** - * get whether the window has been iconized or not - * @return iconize or not - */ - - public boolean getIconic() - { - return iconic.isSet(field_5_options); - } - - /** - * get whether to display the horizontal scrollbar or not - * @return display or not - */ - - public boolean getDisplayHorizontalScrollbar() - { - return hscroll.isSet(field_5_options); - } - - /** - * get whether to display the vertical scrollbar or not - * @return display or not - */ - - public boolean getDisplayVerticalScrollbar() - { - return vscroll.isSet(field_5_options); - } - - /** - * get whether to display the tabs or not - * @return display or not - */ - - public boolean getDisplayTabs() - { - return tabs.isSet(field_5_options); - } - - // end options bitfields - - - /** - * @return the index of the currently displayed sheet - */ - public int getActiveSheetIndex() { - return field_6_active_sheet; - } - - /** - * @return the first visible sheet in the worksheet tab-bar. - * I.E. the scroll position of the tab-bar. - */ - public int getFirstVisibleTab() { - return field_7_first_visible_tab; - } - - /** - * get the number of selected tabs - * @return number of tabs - */ - - public short getNumSelectedTabs() - { - return field_8_num_selected_tabs; - } - - /** - * ratio of the width of the tabs to the horizontal scrollbar - * @return ratio - */ - - public short getTabWidthRatio() - { - return field_9_tab_width_ratio; - } - - public String toString() { - return "[WINDOW1]\n" + - " .h_hold = " + - Integer.toHexString(getHorizontalHold()) + "\n" + - " .v_hold = " + - Integer.toHexString(getVerticalHold()) + "\n" + - " .width = " + - Integer.toHexString(getWidth()) + "\n" + - " .height = " + - Integer.toHexString(getHeight()) + "\n" + - " .options = " + - Integer.toHexString(getOptions()) + "\n" + - " .hidden = " + getHidden() + - "\n" + - " .iconic = " + getIconic() + - "\n" + - " .hscroll = " + - getDisplayHorizontalScrollbar() + "\n" + - " .vscroll = " + - getDisplayVerticalScrollbar() + "\n" + - " .tabs = " + getDisplayTabs() + - "\n" + - " .activeSheet = " + - Integer.toHexString(getActiveSheetIndex()) + "\n" + - " .firstVisibleTab = " + - Integer.toHexString(getFirstVisibleTab()) + "\n" + - " .numselectedtabs = " + - Integer.toHexString(getNumSelectedTabs()) + "\n" + - " .tabwidthratio = " + - Integer.toHexString(getTabWidthRatio()) + "\n" + - "[/WINDOW1]\n"; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getHorizontalHold()); - out.writeShort(getVerticalHold()); - out.writeShort(getWidth()); - out.writeShort(getHeight()); - out.writeShort(getOptions()); - out.writeShort(getActiveSheetIndex()); - out.writeShort(getFirstVisibleTab()); - out.writeShort(getNumSelectedTabs()); - out.writeShort(getTabWidthRatio()); - } - - protected int getDataSize() { - return 18; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/WindowProtectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/WindowProtectRecord.java deleted file mode 100644 index a360bc4b0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/WindowProtectRecord.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Window Protect Record (0x0019)

    - * Description: flags whether workbook windows are protected

    - * REFERENCE: PG 424 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class WindowProtectRecord extends StandardRecord { - public final static short sid = 0x0019; - - private static final BitField settingsProtectedFlag = BitFieldFactory.getInstance(0x0001); - - private int _options; - - public WindowProtectRecord(int options) { - _options = options; - } - - public WindowProtectRecord(RecordInputStream in) { - this(in.readUShort()); - } - - public WindowProtectRecord(boolean protect) { - this(0); - setProtect(protect); - } - - /** - * set whether this window should be protected or not - * @param protect or not - */ - public void setProtect(boolean protect) { - _options = settingsProtectedFlag.setBoolean(_options, protect); - } - - /** - * is this window protected or not - * - * @return protected or not - */ - public boolean getProtect() { - return settingsProtectedFlag.isSet(_options); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[WINDOWPROTECT]\n"); - buffer.append(" .options = ").append(HexDump.shortToHex(_options)).append("\n"); - buffer.append("[/WINDOWPROTECT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_options); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - @Override - public Object clone() { - return new WindowProtectRecord(_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java b/trunk/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java deleted file mode 100644 index d7f0ec477..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java +++ /dev/null @@ -1,543 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Window Two Record

    - * Description: sheet window settings

    - * REFERENCE: PG 422 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - * @version 2.0-pre - */ -public final class WindowTwoRecord extends StandardRecord { - public final static short sid = 0x023E; - - // bitfields - private static final BitField displayFormulas = BitFieldFactory.getInstance(0x01); - private static final BitField displayGridlines = BitFieldFactory.getInstance(0x02); - private static final BitField displayRowColHeadings = BitFieldFactory.getInstance(0x04); - private static final BitField freezePanes = BitFieldFactory.getInstance(0x08); - private static final BitField displayZeros = BitFieldFactory.getInstance(0x10); - /** if false use color in field 4 if true use default foreground for headers */ - private static final BitField defaultHeader = BitFieldFactory.getInstance(0x20); - private static final BitField arabic = BitFieldFactory.getInstance(0x040); - private static final BitField displayGuts = BitFieldFactory.getInstance(0x080); - private static final BitField freezePanesNoSplit = BitFieldFactory.getInstance(0x100); - private static final BitField selected = BitFieldFactory.getInstance(0x200); - private static final BitField active = BitFieldFactory.getInstance(0x400); - private static final BitField savedInPageBreakPreview = BitFieldFactory.getInstance(0x800); - // 4-7 reserved - // end bitfields - - private short field_1_options; - private short field_2_top_row; - private short field_3_left_col; - private int field_4_header_color; - private short field_5_page_break_zoom; - private short field_6_normal_zoom; - private int field_7_reserved; - - public WindowTwoRecord() - { - } - - public WindowTwoRecord(RecordInputStream in) - { - int size = in.remaining(); - field_1_options = in.readShort(); - field_2_top_row = in.readShort(); - field_3_left_col = in.readShort(); - field_4_header_color = in.readInt(); - if (size > 10) - { - field_5_page_break_zoom = in.readShort(); - field_6_normal_zoom = in.readShort(); - } - if (size > 14) - { // there is a special case of this record that has only 14 bytes...undocumented! - field_7_reserved = in.readInt(); - } - } - - /** - * set the options bitmask or just use the bit setters. - * @param options - */ - - public void setOptions(short options) - { - field_1_options = options; - } - - // option bitfields - - /** - * set whether the window should display formulas - * @param formulas or not - */ - - public void setDisplayFormulas(boolean formulas) - { - field_1_options = displayFormulas.setShortBoolean(field_1_options, formulas); - } - - /** - * set whether the window should display gridlines - * @param gridlines or not - */ - - public void setDisplayGridlines(boolean gridlines) - { - field_1_options = displayGridlines.setShortBoolean(field_1_options, gridlines); - } - - /** - * set whether the window should display row and column headings - * @param headings or not - */ - - public void setDisplayRowColHeadings(boolean headings) - { - field_1_options = displayRowColHeadings.setShortBoolean(field_1_options, headings); - } - - /** - * set whether the window should freeze panes - * @param freezepanes freeze panes or not - */ - - public void setFreezePanes(boolean freezepanes) - { - field_1_options = freezePanes.setShortBoolean(field_1_options, freezepanes); - } - - /** - * set whether the window should display zero values - * @param zeros or not - */ - - public void setDisplayZeros(boolean zeros) - { - field_1_options = displayZeros.setShortBoolean(field_1_options, zeros); - } - - /** - * set whether the window should display a default header - * @param header or not - */ - - public void setDefaultHeader(boolean header) - { - field_1_options = defaultHeader.setShortBoolean(field_1_options, header); - } - - /** - * is this arabic? - * @param isarabic arabic or not - */ - - public void setArabic(boolean isarabic) - { - field_1_options = arabic.setShortBoolean(field_1_options, isarabic); - } - - /** - * set whether the outline symbols are displaed - * @param guts symbols or not - */ - - public void setDisplayGuts(boolean guts) - { - field_1_options = displayGuts.setShortBoolean(field_1_options, guts); - } - - /** - * freeze unsplit panes or not - * @param freeze or not - */ - - public void setFreezePanesNoSplit(boolean freeze) - { - field_1_options = freezePanesNoSplit.setShortBoolean(field_1_options, freeze); - } - - /** - * sheet tab is selected - * @param sel selected or not - */ - - public void setSelected(boolean sel) - { - field_1_options = selected.setShortBoolean(field_1_options, sel); - } - - /** - * is the sheet currently displayed in the window - * @param p displayed or not - */ - public void setActive(boolean p) { - field_1_options = active.setShortBoolean(field_1_options, p); - } - - /** - * was the sheet saved in page break view - * @param p pagebreaksaved or not - */ - - public void setSavedInPageBreakPreview(boolean p) - { - field_1_options = savedInPageBreakPreview.setShortBoolean(field_1_options, p); - } - - // end of bitfields. - - /** - * set the top row visible in the window - * @param topRow top row visible - */ - - public void setTopRow(short topRow) - { - field_2_top_row = topRow; - } - - /** - * set the leftmost column displayed in the window - * @param leftCol leftmost column - */ - - public void setLeftCol(short leftCol) - { - field_3_left_col = leftCol; - } - - /** - * set the palette index for the header color - * @param color - */ - - public void setHeaderColor(int color) - { - field_4_header_color = color; - } - - /** - * zoom magification in page break view - * @param zoom - */ - - public void setPageBreakZoom(short zoom) - { - field_5_page_break_zoom = zoom; - } - - /** - * set the zoom magnification in normal view - * @param zoom - */ - - public void setNormalZoom(short zoom) - { - field_6_normal_zoom = zoom; - } - - /** - * set the reserved (don't do this) value - */ - - public void setReserved(int reserved) - { - field_7_reserved = reserved; - } - - /** - * get the options bitmask or just use the bit setters. - * @return options - */ - - public short getOptions() - { - return field_1_options; - } - - // option bitfields - - /** - * get whether the window should display formulas - * @return formulas or not - */ - - public boolean getDisplayFormulas() - { - return displayFormulas.isSet(field_1_options); - } - - /** - * get whether the window should display gridlines - * @return gridlines or not - */ - - public boolean getDisplayGridlines() - { - return displayGridlines.isSet(field_1_options); - } - - /** - * get whether the window should display row and column headings - * @return headings or not - */ - - public boolean getDisplayRowColHeadings() - { - return displayRowColHeadings.isSet(field_1_options); - } - - /** - * get whether the window should freeze panes - * @return freeze panes or not - */ - - public boolean getFreezePanes() - { - return freezePanes.isSet(field_1_options); - } - - /** - * get whether the window should display zero values - * @return zeros or not - */ - - public boolean getDisplayZeros() - { - return displayZeros.isSet(field_1_options); - } - - /** - * get whether the window should display a default header - * @return header or not - */ - - public boolean getDefaultHeader() - { - return defaultHeader.isSet(field_1_options); - } - - /** - * is this arabic? - * @return arabic or not - */ - - public boolean getArabic() - { - return arabic.isSet(field_1_options); - } - - /** - * get whether the outline symbols are displaed - * @return symbols or not - */ - - public boolean getDisplayGuts() - { - return displayGuts.isSet(field_1_options); - } - - /** - * freeze unsplit panes or not - * @return freeze or not - */ - - public boolean getFreezePanesNoSplit() - { - return freezePanesNoSplit.isSet(field_1_options); - } - - /** - * sheet tab is selected - * @return selected or not - */ - - public boolean getSelected() - { - return selected.isSet(field_1_options); - } - - /** - * is the sheet currently displayed in the window - * @return displayed or not - */ - - public boolean isActive() { - return active.isSet(field_1_options); - } - - /** - * was the sheet saved in page break view - * @return pagebreaksaved or not - */ - - public boolean getSavedInPageBreakPreview() - { - return savedInPageBreakPreview.isSet(field_1_options); - } - - // end of bitfields. - - /** - * get the top row visible in the window - * @return toprow - */ - - public short getTopRow() - { - return field_2_top_row; - } - - /** - * get the leftmost column displayed in the window - * @return leftmost - */ - - public short getLeftCol() - { - return field_3_left_col; - } - - /** - * get the palette index for the header color - * @return color - */ - - public int getHeaderColor() - { - return field_4_header_color; - } - - /** - * zoom magification in page break view - * @return zoom - */ - - public short getPageBreakZoom() - { - return field_5_page_break_zoom; - } - - /** - * get the zoom magnification in normal view - * @return zoom - */ - - public short getNormalZoom() - { - return field_6_normal_zoom; - } - - /** - * get the reserved bits - why would you do this? - * @return reserved stuff -probably garbage - */ - - public int getReserved() - { - return field_7_reserved; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[WINDOW2]\n"); - buffer.append(" .options = ") - .append(Integer.toHexString(getOptions())).append("\n"); - buffer.append(" .dispformulas= ").append(getDisplayFormulas()) - .append("\n"); - buffer.append(" .dispgridlins= ").append(getDisplayGridlines()) - .append("\n"); - buffer.append(" .disprcheadin= ") - .append(getDisplayRowColHeadings()).append("\n"); - buffer.append(" .freezepanes = ").append(getFreezePanes()) - .append("\n"); - buffer.append(" .displayzeros= ").append(getDisplayZeros()) - .append("\n"); - buffer.append(" .defaultheadr= ").append(getDefaultHeader()) - .append("\n"); - buffer.append(" .arabic = ").append(getArabic()) - .append("\n"); - buffer.append(" .displayguts = ").append(getDisplayGuts()) - .append("\n"); - buffer.append(" .frzpnsnosplt= ") - .append(getFreezePanesNoSplit()).append("\n"); - buffer.append(" .selected = ").append(getSelected()) - .append("\n"); - buffer.append(" .active = ").append(isActive()) - .append("\n"); - buffer.append(" .svdinpgbrkpv= ") - .append(getSavedInPageBreakPreview()).append("\n"); - buffer.append(" .toprow = ") - .append(Integer.toHexString(getTopRow())).append("\n"); - buffer.append(" .leftcol = ") - .append(Integer.toHexString(getLeftCol())).append("\n"); - buffer.append(" .headercolor = ") - .append(Integer.toHexString(getHeaderColor())).append("\n"); - buffer.append(" .pagebreakzoom = ") - .append(Integer.toHexString(getPageBreakZoom())).append("\n"); - buffer.append(" .normalzoom = ") - .append(Integer.toHexString(getNormalZoom())).append("\n"); - buffer.append(" .reserved = ") - .append(Integer.toHexString(getReserved())).append("\n"); - buffer.append("[/WINDOW2]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getOptions()); - out.writeShort(getTopRow()); - out.writeShort(getLeftCol()); - out.writeInt(getHeaderColor()); - out.writeShort(getPageBreakZoom()); - out.writeShort(getNormalZoom()); - out.writeInt(getReserved()); - } - - protected int getDataSize() { - return 18; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - WindowTwoRecord rec = new WindowTwoRecord(); - rec.field_1_options = field_1_options; - rec.field_2_top_row = field_2_top_row; - rec.field_3_left_col = field_3_left_col; - rec.field_4_header_color = field_4_header_color; - rec.field_5_page_break_zoom = field_5_page_break_zoom; - rec.field_6_normal_zoom = field_6_normal_zoom; - rec.field_7_reserved = field_7_reserved; - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java b/trunk/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java deleted file mode 100644 index e8c4a6f92..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import java.util.Arrays; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: Write Access Record (0x005C)

    - * - * Description: Stores the username of that who owns the spreadsheet generator (on unix the user's - * login, on Windoze its the name you typed when you installed the thing)

    - * - * REFERENCE: PG 424 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) - */ -public final class WriteAccessRecord extends StandardRecord { - public final static short sid = 0x005C; - - private static final byte PAD_CHAR = (byte) ' '; - private static final int DATA_SIZE = 112; - private String field_1_username; - /** this record is always padded to a constant length */ - private static final byte[] PADDING = new byte[DATA_SIZE]; - static { - Arrays.fill(PADDING, PAD_CHAR); - } - - public WriteAccessRecord() { - setUsername(""); - } - - public WriteAccessRecord(RecordInputStream in) { - if (in.remaining() > DATA_SIZE) { - throw new RecordFormatException("Expected data size (" + DATA_SIZE + ") but got (" - + in.remaining() + ")"); - } - // The string is always 112 characters (padded with spaces), therefore - // this record can not be continued. - - int nChars = in.readUShort(); - int is16BitFlag = in.readUByte(); - if (nChars > DATA_SIZE || (is16BitFlag & 0xFE) != 0) { - // String header looks wrong (probably missing) - // OOO doc says this is optional anyway. - // reconstruct data - byte[] data = new byte[3 + in.remaining()]; - LittleEndian.putUShort(data, 0, nChars); - LittleEndian.putByte(data, 2, is16BitFlag); - in.readFully(data, 3, data.length-3); - String rawValue = new String(data, StringUtil.UTF8); - setUsername(rawValue.trim()); - return; - } - - String rawText; - if ((is16BitFlag & 0x01) == 0x00) { - rawText = StringUtil.readCompressedUnicode(in, nChars); - } else { - rawText = StringUtil.readUnicodeLE(in, nChars); - } - field_1_username = rawText.trim(); - - // consume padding - int padSize = in.remaining(); - while (padSize > 0) { - // in some cases this seems to be garbage (non spaces) - in.readUByte(); - padSize--; - } - } - - /** - * set the username for the user that created the report. HSSF uses the - * logged in user. - * - * @param username of the user who is logged in (probably "tomcat" or "apache") - */ - public void setUsername(String username) { - boolean is16bit = StringUtil.hasMultibyte(username); - int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1); - int paddingSize = DATA_SIZE - encodedByteCount; - if (paddingSize < 0) { - throw new IllegalArgumentException("Name is too long: " + username); - } - - field_1_username = username; - } - - /** - * get the username for the user that created the report. HSSF uses the - * logged in user. On natively created M$ Excel sheet this would be the name - * you typed in when you installed it in most cases. - * - * @return username of the user who is logged in (probably "tomcat" or "apache") - */ - public String getUsername() { - return field_1_username; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[WRITEACCESS]\n"); - buffer.append(" .name = ").append(field_1_username).append("\n"); - buffer.append("[/WRITEACCESS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - String username = getUsername(); - boolean is16bit = StringUtil.hasMultibyte(username); - - out.writeShort(username.length()); - out.writeByte(is16bit ? 0x01 : 0x00); - if (is16bit) { - StringUtil.putUnicodeLE(username, out); - } else { - StringUtil.putCompressedUnicode(username, out); - } - int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1); - int paddingSize = DATA_SIZE - encodedByteCount; - out.write(PADDING, 0, paddingSize); - } - - protected int getDataSize() { - return DATA_SIZE; - } - - public short getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java deleted file mode 100644 index 14afeedc3..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Write Protect Record

    - * Description: Indicated that the sheet/workbook is write protected. - * REFERENCE: PG 425 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * @version 3.0-pre - */ -public final class WriteProtectRecord extends StandardRecord { - public final static short sid = 0x86; - - public WriteProtectRecord() - { - } - - /** - * @param in unused (since this record has no data) - */ - public WriteProtectRecord(RecordInputStream in) - { - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[WRITEPROTECT]\n"); - buffer.append("[/WRITEPROTECT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - } - - protected int getDataSize() { - return 0; - } - - public short getSid() - { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java deleted file mode 100644 index 40fd28865..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java +++ /dev/null @@ -1,286 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.CFHeader12Record; -import org.apache.poi.hssf.record.CFHeaderBase; -import org.apache.poi.hssf.record.CFHeaderRecord; -import org.apache.poi.hssf.record.CFRule12Record; -import org.apache.poi.hssf.record.CFRuleBase; -import org.apache.poi.hssf.record.CFRuleRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.ptg.AreaErrPtg; -import org.apache.poi.ss.formula.ptg.AreaPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.RecordFormatException; - -/** - *

    CFRecordsAggregate - aggregates Conditional Formatting records CFHeaderRecord - * and number of up CFRuleRecord records together to simplify access to them.

    - *

    Note that Excel versions before 2007 can only cope with a maximum of 3 - * Conditional Formatting rules per sheet. Excel 2007 or newer can cope with - * unlimited numbers, as can Apache OpenOffice. This is an Excel limitation, - * not a file format one.

    - */ -public final class CFRecordsAggregate extends RecordAggregate { - /** Excel 97-2003 allows up to 3 conditional formating rules */ - private static final int MAX_97_2003_CONDTIONAL_FORMAT_RULES = 3; - private static final POILogger logger = POILogFactory.getLogger(CFRecordsAggregate.class); - - private final CFHeaderBase header; - - /** List of CFRuleRecord objects */ - private final List rules; - - private CFRecordsAggregate(CFHeaderBase pHeader, CFRuleBase[] pRules) { - if(pHeader == null) { - throw new IllegalArgumentException("header must not be null"); - } - if(pRules == null) { - throw new IllegalArgumentException("rules must not be null"); - } - if(pRules.length > MAX_97_2003_CONDTIONAL_FORMAT_RULES) { - logger.log(POILogger.WARN, "Excel versions before 2007 require that " - + "No more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES - + " rules may be specified, " + pRules.length + " were found," - + " this file will cause problems with old Excel versions"); - } - if (pRules.length != pHeader.getNumberOfConditionalFormats()) { - throw new RecordFormatException("Mismatch number of rules"); - } - header = pHeader; - rules = new ArrayList(pRules.length); - for (CFRuleBase pRule : pRules) { - checkRuleType(pRule); - rules.add(pRule); - } - } - - public CFRecordsAggregate(CellRangeAddress[] regions, CFRuleBase[] rules) { - this(createHeader(regions, rules), rules); - } - private static CFHeaderBase createHeader(CellRangeAddress[] regions, CFRuleBase[] rules) { - final CFHeaderBase header; - if (rules.length == 0 || rules[0] instanceof CFRuleRecord) { - header = new CFHeaderRecord(regions, rules.length); - } else { - header = new CFHeader12Record(regions, rules.length); - } - - // set the "needs recalculate" by default to avoid Excel handling conditional formatting incorrectly - // see bug 52122 for details - header.setNeedRecalculation(true); - - return header; - } - - /** - * Create CFRecordsAggregate from a list of CF Records - * @param rs - the stream to read from - * @return CFRecordsAggregate object - */ - public static CFRecordsAggregate createCFAggregate(RecordStream rs) { - Record rec = rs.getNext(); - if (rec.getSid() != CFHeaderRecord.sid && - rec.getSid() != CFHeader12Record.sid) { - throw new IllegalStateException("next record sid was " + rec.getSid() - + " instead of " + CFHeaderRecord.sid + " or " + - CFHeader12Record.sid + " as expected"); - } - - CFHeaderBase header = (CFHeaderBase)rec; - int nRules = header.getNumberOfConditionalFormats(); - - CFRuleBase[] rules = new CFRuleBase[nRules]; - for (int i = 0; i < rules.length; i++) { - rules[i] = (CFRuleBase) rs.getNext(); - } - - return new CFRecordsAggregate(header, rules); - } - - /** - * Create a deep clone of the record - */ - public CFRecordsAggregate cloneCFAggregate() { - CFRuleBase[] newRecs = new CFRuleBase[rules.size()]; - for (int i = 0; i < newRecs.length; i++) { - newRecs[i] = getRule(i).clone(); - } - return new CFRecordsAggregate(header.clone(), newRecs); - } - - /** - * @return the header. Never null. - */ - public CFHeaderBase getHeader() { - return header; - } - - private void checkRuleIndex(int idx) { - if(idx < 0 || idx >= rules.size()) { - throw new IllegalArgumentException("Bad rule record index (" + idx - + ") nRules=" + rules.size()); - } - } - private void checkRuleType(CFRuleBase r) { - if (header instanceof CFHeaderRecord && - r instanceof CFRuleRecord) { - return; - } - if (header instanceof CFHeader12Record && - r instanceof CFRule12Record) { - return; - } - throw new IllegalArgumentException("Header and Rule must both be CF or both be CF12, can't mix"); - } - - public CFRuleBase getRule(int idx) { - checkRuleIndex(idx); - return rules.get(idx); - } - public void setRule(int idx, CFRuleBase r) { - if (r == null) { - throw new IllegalArgumentException("r must not be null"); - } - checkRuleIndex(idx); - checkRuleType(r); - rules.set(idx, r); - } - public void addRule(CFRuleBase r) { - if (r == null) { - throw new IllegalArgumentException("r must not be null"); - } - if(rules.size() >= MAX_97_2003_CONDTIONAL_FORMAT_RULES) { - logger.log(POILogger.WARN, "Excel versions before 2007 cannot cope with" - + " any more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES - + " - this file will cause problems with old Excel versions"); - } - checkRuleType(r); - rules.add(r); - header.setNumberOfConditionalFormats(rules.size()); - } - public int getNumberOfRules() { - return rules.size(); - } - - /** - * String representation of CFRecordsAggregate - */ - public String toString() { - StringBuilder buffer = new StringBuilder(); - String type = "CF"; - if (header instanceof CFHeader12Record) { - type = "CF12"; - } - - buffer.append("[").append(type).append("]\n"); - if( header != null ) { - buffer.append(header.toString()); - } - for (CFRuleBase cfRule : rules) { - buffer.append(cfRule.toString()); - } - buffer.append("[/").append(type).append("]\n"); - return buffer.toString(); - } - - public void visitContainedRecords(RecordVisitor rv) { - rv.visitRecord(header); - for (CFRuleBase rule : rules) { - rv.visitRecord(rule); - } - } - - /** - * @return false if this whole {@link CFHeaderRecord} / {@link CFRuleRecord}s should be deleted - */ - public boolean updateFormulasAfterCellShift(FormulaShifter shifter, int currentExternSheetIx) { - CellRangeAddress[] cellRanges = header.getCellRanges(); - boolean changed = false; - List temp = new ArrayList(); - for (CellRangeAddress craOld : cellRanges) { - CellRangeAddress craNew = shiftRange(shifter, craOld, currentExternSheetIx); - if (craNew == null) { - changed = true; - continue; - } - temp.add(craNew); - if (craNew != craOld) { - changed = true; - } - } - - if (changed) { - int nRanges = temp.size(); - if (nRanges == 0) { - return false; - } - CellRangeAddress[] newRanges = new CellRangeAddress[nRanges]; - temp.toArray(newRanges); - header.setCellRanges(newRanges); - } - - for (CFRuleBase rule : rules) { - Ptg[] ptgs; - ptgs = rule.getParsedExpression1(); - if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) { - rule.setParsedExpression1(ptgs); - } - ptgs = rule.getParsedExpression2(); - if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) { - rule.setParsedExpression2(ptgs); - } - if (rule instanceof CFRule12Record) { - CFRule12Record rule12 = (CFRule12Record)rule; - ptgs = rule12.getParsedExpressionScale(); - if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) { - rule12.setParsedExpressionScale(ptgs); - } - } - } - return true; - } - - private static CellRangeAddress shiftRange(FormulaShifter shifter, CellRangeAddress cra, int currentExternSheetIx) { - // FormulaShifter works well in terms of Ptgs - so convert CellRangeAddress to AreaPtg (and back) here - AreaPtg aptg = new AreaPtg(cra.getFirstRow(), cra.getLastRow(), cra.getFirstColumn(), cra.getLastColumn(), false, false, false, false); - Ptg[] ptgs = { aptg, }; - - if (!shifter.adjustFormula(ptgs, currentExternSheetIx)) { - return cra; - } - Ptg ptg0 = ptgs[0]; - if (ptg0 instanceof AreaPtg) { - AreaPtg bptg = (AreaPtg) ptg0; - return new CellRangeAddress(bptg.getFirstRow(), bptg.getLastRow(), bptg.getFirstColumn(), bptg.getLastColumn()); - } - if (ptg0 instanceof AreaErrPtg) { - return null; - } - throw new IllegalStateException("Unexpected shifted ptg class (" + ptg0.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java deleted file mode 100644 index 5df1993e4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.*; - -/** - * Manages the all the records associated with a chart sub-stream.

    - * Includes the initial {@link BOFRecord} and final {@link EOFRecord}. - */ -public final class ChartSubstreamRecordAggregate extends RecordAggregate { - - private final BOFRecord _bofRec; - /** - * All the records between BOF and EOF - */ - private final List _recs; - private PageSettingsBlock _psBlock; - - public ChartSubstreamRecordAggregate(RecordStream rs) { - _bofRec = (BOFRecord) rs.getNext(); - List temp = new ArrayList(); - while (rs.peekNextClass() != EOFRecord.class) { - if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) { - if (_psBlock != null) { - if (rs.peekNextSid() == HeaderFooterRecord.sid) { - // test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls - _psBlock.addLateHeaderFooter((HeaderFooterRecord)rs.getNext()); - continue; - } - throw new IllegalStateException( - "Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid()); - } - _psBlock = new PageSettingsBlock(rs); - temp.add(_psBlock); - continue; - } - temp.add(rs.getNext()); - } - _recs = temp; - Record eof = rs.getNext(); // no need to save EOF in field - if (!(eof instanceof EOFRecord)) { - throw new IllegalStateException("Bad chart EOF"); - } - } - - public void visitContainedRecords(RecordVisitor rv) { - if (_recs.isEmpty()) { - return; - } - rv.visitRecord(_bofRec); - for (int i = 0; i < _recs.size(); i++) { - RecordBase rb = _recs.get(i); - if (rb instanceof RecordAggregate) { - ((RecordAggregate) rb).visitContainedRecords(rv); - } else { - rv.visitRecord((Record) rb); - } - } - rv.visitRecord(EOFRecord.instance); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java deleted file mode 100644 index 7c02b8bb1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java +++ /dev/null @@ -1,528 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.ColumnInfoRecord; - -/** - * @author Glen Stampoultzis - */ -public final class ColumnInfoRecordsAggregate extends RecordAggregate implements Cloneable { - /** - * List of {@link ColumnInfoRecord}s assumed to be in order - */ - private final List records; - - - private static final class CIRComparator implements Comparator { - public static final Comparator instance = new CIRComparator(); - private CIRComparator() { - // enforce singleton - } - public int compare(ColumnInfoRecord a, ColumnInfoRecord b) { - return compareColInfos(a, b); - } - public static int compareColInfos(ColumnInfoRecord a, ColumnInfoRecord b) { - return a.getFirstColumn()-b.getFirstColumn(); - } - } - - /** - * Creates an empty aggregate - */ - public ColumnInfoRecordsAggregate() { - records = new ArrayList(); - } - public ColumnInfoRecordsAggregate(RecordStream rs) { - this(); - - boolean isInOrder = true; - ColumnInfoRecord cirPrev = null; - while(rs.peekNextClass() == ColumnInfoRecord.class) { - ColumnInfoRecord cir = (ColumnInfoRecord) rs.getNext(); - records.add(cir); - if (cirPrev != null && CIRComparator.compareColInfos(cirPrev, cir) > 0) { - isInOrder = false; - } - cirPrev = cir; - } - if (records.size() < 1) { - throw new RuntimeException("No column info records found"); - } - if (!isInOrder) { - Collections.sort(records, CIRComparator.instance); - } - } - - @Override - public ColumnInfoRecordsAggregate clone() { - ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate(); - for (ColumnInfoRecord ci : records) { - rec.records.add(ci.clone()); - } - return rec; - } - - /** - * Inserts a column into the aggregate (at the end of the list). - */ - public void insertColumn(ColumnInfoRecord col) { - records.add(col); - Collections.sort(records, CIRComparator.instance); - } - - /** - * Inserts a column into the aggregate (at the position specified by - * idx. - */ - private void insertColumn(int idx, ColumnInfoRecord col) { - records.add(idx, col); - } - - /* package */ int getNumColumns() { - return records.size(); - } - - public void visitContainedRecords(RecordVisitor rv) { - int nItems = records.size(); - if (nItems < 1) { - return; - } - ColumnInfoRecord cirPrev = null; - for(int i=0; i 0) { - // Excel probably wouldn't mind, but there is much logic in this class - // that assumes the column info records are kept in order - throw new RuntimeException("Column info records are out of order"); - } - cirPrev = cir; - } - } - - private int findStartOfColumnOutlineGroup(int pIdx) { - // Find the start of the group. - ColumnInfoRecord columnInfo = records.get(pIdx); - int level = columnInfo.getOutlineLevel(); - int idx = pIdx; - while (idx != 0) { - ColumnInfoRecord prevColumnInfo = records.get(idx - 1); - if (!prevColumnInfo.isAdjacentBefore(columnInfo)) { - break; - } - if (prevColumnInfo.getOutlineLevel() < level) { - break; - } - idx--; - columnInfo = prevColumnInfo; - } - - return idx; - } - - private int findEndOfColumnOutlineGroup(int colInfoIndex) { - // Find the end of the group. - ColumnInfoRecord columnInfo = records.get(colInfoIndex); - int level = columnInfo.getOutlineLevel(); - int idx = colInfoIndex; - while (idx < records.size() - 1) { - ColumnInfoRecord nextColumnInfo = records.get(idx + 1); - if (!columnInfo.isAdjacentBefore(nextColumnInfo)) { - break; - } - if (nextColumnInfo.getOutlineLevel() < level) { - break; - } - idx++; - columnInfo = nextColumnInfo; - } - return idx; - } - - private ColumnInfoRecord getColInfo(int idx) { - return records.get( idx ); - } - - /** - * 'Collapsed' state is stored in a single column col info record immediately after the outline group - * @param idx - * @return true, if the column is collapsed, false otherwise. - */ - private boolean isColumnGroupCollapsed(int idx) { - int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx); - int nextColInfoIx = endOfOutlineGroupIdx+1; - if (nextColInfoIx >= records.size()) { - return false; - } - ColumnInfoRecord nextColInfo = getColInfo(nextColInfoIx); - if (!getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextColInfo)) { - return false; - } - return nextColInfo.getCollapsed(); - } - - - private boolean isColumnGroupHiddenByParent(int idx) { - // Look out outline details of end - int endLevel = 0; - boolean endHidden = false; - int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); - if (endOfOutlineGroupIdx < records.size()) { - ColumnInfoRecord nextInfo = getColInfo(endOfOutlineGroupIdx + 1); - if (getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextInfo)) { - endLevel = nextInfo.getOutlineLevel(); - endHidden = nextInfo.getHidden(); - } - } - // Look out outline details of start - int startLevel = 0; - boolean startHidden = false; - int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx ); - if (startOfOutlineGroupIdx > 0) { - ColumnInfoRecord prevInfo = getColInfo(startOfOutlineGroupIdx - 1); - if (prevInfo.isAdjacentBefore(getColInfo(startOfOutlineGroupIdx))) { - startLevel = prevInfo.getOutlineLevel(); - startHidden = prevInfo.getHidden(); - } - } - if (endLevel > startLevel) { - return endHidden; - } - return startHidden; - } - - public void collapseColumn(int columnIndex) { - int colInfoIx = findColInfoIdx(columnIndex, 0); - if (colInfoIx == -1) { - return; - } - - // Find the start of the group. - int groupStartColInfoIx = findStartOfColumnOutlineGroup(colInfoIx); - ColumnInfoRecord columnInfo = getColInfo(groupStartColInfoIx); - - // Hide all the columns until the end of the group - int lastColIx = setGroupHidden(groupStartColInfoIx, columnInfo.getOutlineLevel(), true); - - // Write collapse field - setColumn(lastColIx + 1, null, null, null, null, Boolean.TRUE); - } - /** - * Sets all adjacent columns of the same outline level to the specified hidden status. - * @param pIdx the col info index of the start of the outline group - * @return the column index of the last column in the outline group - */ - private int setGroupHidden(int pIdx, int level, boolean hidden) { - int idx = pIdx; - ColumnInfoRecord columnInfo = getColInfo(idx); - while (idx < records.size()) { - columnInfo.setHidden(hidden); - if (idx + 1 < records.size()) { - ColumnInfoRecord nextColumnInfo = getColInfo(idx + 1); - if (!columnInfo.isAdjacentBefore(nextColumnInfo)) { - break; - } - if (nextColumnInfo.getOutlineLevel() < level) { - break; - } - columnInfo = nextColumnInfo; - } - idx++; - } - return columnInfo.getLastColumn(); - } - - - public void expandColumn(int columnIndex) { - int idx = findColInfoIdx(columnIndex, 0); - if (idx == -1) { - return; - } - - // If it is already expanded do nothing. - if (!isColumnGroupCollapsed(idx)) { - return; - } - - // Find the start/end of the group. - int startIdx = findStartOfColumnOutlineGroup(idx); - int endIdx = findEndOfColumnOutlineGroup(idx); - - // expand: - // colapsed bit must be unset - // hidden bit gets unset _if_ surrounding groups are expanded you can determine - // this by looking at the hidden bit of the enclosing group. You will have - // to look at the start and the end of the current group to determine which - // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups - ColumnInfoRecord columnInfo = getColInfo(endIdx); - if (!isColumnGroupHiddenByParent(idx)) { - int outlineLevel = columnInfo.getOutlineLevel(); - for (int i = startIdx; i <= endIdx; i++) { - ColumnInfoRecord ci = getColInfo(i); - if (outlineLevel == ci.getOutlineLevel()) - ci.setHidden(false); - } - } - - // Write collapse flag (stored in a single col info record after this outline group) - setColumn(columnInfo.getLastColumn() + 1, null, null, null, null, Boolean.FALSE); - } - - private static ColumnInfoRecord copyColInfo(ColumnInfoRecord ci) { - return ci.clone(); - } - - - public void setColumn(int targetColumnIx, Short xfIndex, Integer width, - Integer level, Boolean hidden, Boolean collapsed) { - ColumnInfoRecord ci = null; - int k = 0; - - for (k = 0; k < records.size(); k++) { - ColumnInfoRecord tci = records.get(k); - if (tci.containsColumn(targetColumnIx)) { - ci = tci; - break; - } - if (tci.getFirstColumn() > targetColumnIx) { - // call column infos after k are for later columns - break; // exit now so k will be the correct insert pos - } - } - - if (ci == null) { - // okay so there ISN'T a column info record that covers this column so lets create one! - ColumnInfoRecord nci = new ColumnInfoRecord(); - - nci.setFirstColumn(targetColumnIx); - nci.setLastColumn(targetColumnIx); - setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed ); - insertColumn(k, nci); - attemptMergeColInfoRecords(k); - return; - } - - boolean styleChanged = xfIndex != null && ci.getXFIndex() != xfIndex.shortValue(); - boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue(); - boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue(); - boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue(); - boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue(); - - boolean columnChanged = styleChanged || widthChanged || levelChanged || hiddenChanged || collapsedChanged; - if (!columnChanged) { - // do nothing...nothing changed. - return; - } - - if (ci.getFirstColumn() == targetColumnIx && ci.getLastColumn() == targetColumnIx) { - // ColumnInfo ci for a single column, the target column - setColumnInfoFields(ci, xfIndex, width, level, hidden, collapsed); - attemptMergeColInfoRecords(k); - return; - } - - if (ci.getFirstColumn() == targetColumnIx || ci.getLastColumn() == targetColumnIx) { - // The target column is at either end of the multi-column ColumnInfo ci - // we'll just divide the info and create a new one - if (ci.getFirstColumn() == targetColumnIx) { - ci.setFirstColumn(targetColumnIx + 1); - } else { - ci.setLastColumn(targetColumnIx - 1); - k++; // adjust insert pos to insert after - } - ColumnInfoRecord nci = copyColInfo(ci); - - nci.setFirstColumn(targetColumnIx); - nci.setLastColumn(targetColumnIx); - setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed ); - - insertColumn(k, nci); - attemptMergeColInfoRecords(k); - } else { - //split to 3 records - ColumnInfoRecord ciStart = ci; - ColumnInfoRecord ciMid = copyColInfo(ci); - ColumnInfoRecord ciEnd = copyColInfo(ci); - int lastcolumn = ci.getLastColumn(); - - ciStart.setLastColumn(targetColumnIx - 1); - - ciMid.setFirstColumn(targetColumnIx); - ciMid.setLastColumn(targetColumnIx); - setColumnInfoFields(ciMid, xfIndex, width, level, hidden, collapsed); - insertColumn(++k, ciMid); - - ciEnd.setFirstColumn(targetColumnIx+1); - ciEnd.setLastColumn(lastcolumn); - insertColumn(++k, ciEnd); - // no need to attemptMergeColInfoRecords because we - // know both on each side are different - } - } - - /** - * Sets all non null fields into the ci parameter. - */ - private static void setColumnInfoFields(ColumnInfoRecord ci, Short xfStyle, Integer width, - Integer level, Boolean hidden, Boolean collapsed) { - if (xfStyle != null) { - ci.setXFIndex(xfStyle.shortValue()); - } - if (width != null) { - ci.setColumnWidth(width.intValue()); - } - if (level != null) { - ci.setOutlineLevel( level.shortValue() ); - } - if (hidden != null) { - ci.setHidden( hidden.booleanValue() ); - } - if (collapsed != null) { - ci.setCollapsed( collapsed.booleanValue() ); - } - } - - private int findColInfoIdx(int columnIx, int fromColInfoIdx) { - if (columnIx < 0) { - throw new IllegalArgumentException( "column parameter out of range: " + columnIx ); - } - if (fromColInfoIdx < 0) { - throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromColInfoIdx ); - } - - for (int k = fromColInfoIdx; k < records.size(); k++) { - ColumnInfoRecord ci = getColInfo(k); - if (ci.containsColumn(columnIx)) { - return k; - } - if (ci.getFirstColumn() > columnIx) { - break; - } - } - return -1; - } - - /** - * Attempts to merge the col info record at the specified index - * with either or both of its neighbours - */ - private void attemptMergeColInfoRecords(int colInfoIx) { - int nRecords = records.size(); - if (colInfoIx < 0 || colInfoIx >= nRecords) { - throw new IllegalArgumentException("colInfoIx " + colInfoIx - + " is out of range (0.." + (nRecords-1) + ")"); - } - ColumnInfoRecord currentCol = getColInfo(colInfoIx); - int nextIx = colInfoIx+1; - if (nextIx < nRecords) { - if (mergeColInfoRecords(currentCol, getColInfo(nextIx))) { - records.remove(nextIx); - } - } - if (colInfoIx > 0) { - if (mergeColInfoRecords(getColInfo(colInfoIx - 1), currentCol)) { - records.remove(colInfoIx); - } - } - } - /** - * merges two column info records (if they are adjacent and have the same formatting, etc) - * @return false if the two column records could not be merged - */ - private static boolean mergeColInfoRecords(ColumnInfoRecord ciA, ColumnInfoRecord ciB) { - if (ciA.isAdjacentBefore(ciB) && ciA.formatMatches(ciB)) { - ciA.setLastColumn(ciB.getLastColumn()); - return true; - } - return false; - } - /** - * Creates an outline group for the specified columns, by setting the level - * field for each col info record in the range. {@link ColumnInfoRecord}s - * may be created, split or merged as a result of this operation. - * - * @param fromColumnIx - * group from this column (inclusive) - * @param toColumnIx - * group to this column (inclusive) - * @param indent - * if true the group will be indented by one - * level, if false indenting will be decreased by - * one level. - */ - public void groupColumnRange(int fromColumnIx, int toColumnIx, boolean indent) { - - int colInfoSearchStartIdx = 0; // optimization to speed up the search for col infos - for (int i = fromColumnIx; i <= toColumnIx; i++) { - int level = 1; - int colInfoIdx = findColInfoIdx(i, colInfoSearchStartIdx); - if (colInfoIdx != -1) { - level = getColInfo(colInfoIdx).getOutlineLevel(); - if (indent) { - level++; - } else { - level--; - } - level = Math.max(0, level); - level = Math.min(7, level); - colInfoSearchStartIdx = Math.max(0, colInfoIdx - 1); // -1 just in case this column is collapsed later. - } - setColumn(i, null, null, Integer.valueOf(level), null, null); - } - } - /** - * Finds the ColumnInfoRecord which contains the specified columnIndex - * @param columnIndex index of the column (not the index of the ColumnInfoRecord) - * @return null if no column info found for the specified column - */ - public ColumnInfoRecord findColumnInfo(int columnIndex) { - int nInfos = records.size(); - for(int i=0; i< nInfos; i++) { - ColumnInfoRecord ci = getColInfo(i); - if (ci.containsColumn(columnIndex)) { - return ci; - } - } - return null; - } - public int getMaxOutlineLevel() { - int result = 0; - int count=records.size(); - for (int i=0; i - * - * See OOO exelfileformat.pdf sec 4.12 'Conditional Formatting Table' - */ -public final class ConditionalFormattingTable extends RecordAggregate { - private final List _cfHeaders; - - /** - * Creates an empty ConditionalFormattingTable - */ - public ConditionalFormattingTable() { - _cfHeaders = new ArrayList(); - } - - public ConditionalFormattingTable(RecordStream rs) { - - List temp = new ArrayList(); - while (rs.peekNextClass() == CFHeaderRecord.class || - rs.peekNextClass() == CFHeader12Record.class) { - temp.add(CFRecordsAggregate.createCFAggregate(rs)); - } - _cfHeaders = temp; - } - - public void visitContainedRecords(RecordVisitor rv) { - for (CFRecordsAggregate subAgg : _cfHeaders) { - subAgg.visitContainedRecords(rv); - } - } - - /** - * @return index of the newly added CF header aggregate - */ - public int add(CFRecordsAggregate cfAggregate) { - cfAggregate.getHeader().setID(_cfHeaders.size()); - _cfHeaders.add(cfAggregate); - return _cfHeaders.size() - 1; - } - - public int size() { - return _cfHeaders.size(); - } - - public CFRecordsAggregate get(int index) { - checkIndex(index); - return _cfHeaders.get(index); - } - - public void remove(int index) { - checkIndex(index); - _cfHeaders.remove(index); - } - - private void checkIndex(int index) { - if (index < 0 || index >= _cfHeaders.size()) { - throw new IllegalArgumentException("Specified CF index " + index - + " is outside the allowable range (0.." + (_cfHeaders.size() - 1) + ")"); - } - } - - public void updateFormulasAfterCellShift(FormulaShifter shifter, int externSheetIndex) { - for (int i = 0; i < _cfHeaders.size(); i++) { - CFRecordsAggregate subAgg = _cfHeaders.get(i); - boolean shouldKeep = subAgg.updateFormulasAfterCellShift(shifter, externSheetIndex); - if (!shouldKeep) { - _cfHeaders.remove(i); - i--; - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java deleted file mode 100644 index 7018eec63..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.*; - -/** - * Manages the all the records associated with a 'Custom View Settings' sub-stream.

    - * Includes the initial USERSVIEWBEGIN(0x01AA) and final USERSVIEWEND(0x01AB). - */ -public final class CustomViewSettingsRecordAggregate extends RecordAggregate { - - private final Record _begin; - private final Record _end; - /** - * All the records between BOF and EOF - */ - private final List _recs; - private PageSettingsBlock _psBlock; - - public CustomViewSettingsRecordAggregate(RecordStream rs) { - _begin = rs.getNext(); - if (_begin.getSid() != UserSViewBegin.sid) { - throw new IllegalStateException("Bad begin record"); - } - List temp = new ArrayList(); - while (rs.peekNextSid() != UserSViewEnd.sid) { - if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) { - if (_psBlock != null) { - if (rs.peekNextSid() == HeaderFooterRecord.sid) { - // test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls - _psBlock.addLateHeaderFooter((HeaderFooterRecord)rs.getNext()); - continue; - } - throw new IllegalStateException( - "Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid()); - } - _psBlock = new PageSettingsBlock(rs); - temp.add(_psBlock); - continue; - } - temp.add(rs.getNext()); - } - _recs = temp; - _end = rs.getNext(); // no need to save EOF in field - if (_end.getSid() != UserSViewEnd.sid) { - throw new IllegalStateException("Bad custom view settings end record"); - } - } - - public void visitContainedRecords(RecordVisitor rv) { - if (_recs.isEmpty()) { - return; - } - rv.visitRecord(_begin); - for (int i = 0; i < _recs.size(); i++) { - RecordBase rb = _recs.get(i); - if (rb instanceof RecordAggregate) { - ((RecordAggregate) rb).visitContainedRecords(rv); - } else { - rv.visitRecord((Record) rb); - } - } - rv.visitRecord(_end); - } - - public static boolean isBeginRecord(int sid) { - return sid == UserSViewBegin.sid; - } - - public void append(RecordBase r){ - _recs.add(r); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java deleted file mode 100644 index a4bb38ada..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.DVALRecord; -import org.apache.poi.hssf.record.DVRecord; - -/** - * Manages the DVALRecord and DVRecords for a single sheet

    - * See OOO excelfileformat.pdf section 4.14 - */ -public final class DataValidityTable extends RecordAggregate { - - private final DVALRecord _headerRec; - /** - * The list of data validations for the current sheet. - * Note - this may be empty (contrary to OOO documentation) - */ - private final List _validationList; - - public DataValidityTable(RecordStream rs) { - _headerRec = (DVALRecord) rs.getNext(); - List temp = new ArrayList(); - while (rs.peekNextClass() == DVRecord.class) { - temp.add((DVRecord) rs.getNext()); - } - _validationList = temp; - } - - public DataValidityTable() { - _headerRec = new DVALRecord(); - _validationList = new ArrayList(); - } - - public void visitContainedRecords(RecordVisitor rv) { - if (_validationList.isEmpty()) { - return; - } - rv.visitRecord(_headerRec); - for (int i = 0; i < _validationList.size(); i++) { - rv.visitRecord(_validationList.get(i)); - } - } - - public void addDataValidation(DVRecord dvRecord) { - _validationList.add(dvRecord); - _headerRec.setDVRecNo(_validationList.size()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java deleted file mode 100644 index 4382d99c4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java +++ /dev/null @@ -1,273 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import org.apache.poi.hssf.record.ArrayRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.ss.formula.ptg.ExpPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; - -/** - * The formula record aggregate is used to join together the formula record and it's - * (optional) string record and (optional) Shared Formula Record (template reads, excel optimization). - * - * @author Glen Stampoultzis (glens at apache.org) - * @author Vladimirs Abramovs(Vladimirs.Abramovs at exigenservices.com) - Array Formula support - */ -public final class FormulaRecordAggregate extends RecordAggregate implements CellValueRecordInterface { - - private final FormulaRecord _formulaRecord; - private SharedValueManager _sharedValueManager; - /** caches the calculated result of the formula */ - private StringRecord _stringRecord; - private SharedFormulaRecord _sharedFormulaRecord; - - /** - * @param stringRec may be null if this formula does not have a cached text - * value. - * @param svm the {@link SharedValueManager} for the current sheet - */ - public FormulaRecordAggregate(FormulaRecord formulaRec, StringRecord stringRec, SharedValueManager svm) { - if (svm == null) { - throw new IllegalArgumentException("sfm must not be null"); - } - if (formulaRec.hasCachedResultString()) { - if (stringRec == null) { - throw new RecordFormatException("Formula record flag is set but String record was not found"); - } - _stringRecord = stringRec; - } else { - // Usually stringRec is null here (in agreement with what the formula rec says). - // In the case where an extra StringRecord is erroneously present, Excel (2007) - // ignores it (see bug 46213). - _stringRecord = null; - } - - _formulaRecord = formulaRec; - _sharedValueManager = svm; - if (formulaRec.isSharedFormula()) { - CellReference firstCell = formulaRec.getFormula().getExpReference(); - if (firstCell == null) { - handleMissingSharedFormulaRecord(formulaRec); - } else { - _sharedFormulaRecord = svm.linkSharedFormulaRecord(firstCell, this); - } - } - } - /** - * Sometimes the shared formula flag "seems" to be erroneously set (because the corresponding - * {@link SharedFormulaRecord} does not exist). Normally this would leave no way of determining - * the {@link Ptg} tokens for the formula. However as it turns out in these - * cases, Excel encodes the unshared {@link Ptg} tokens in the right place (inside the {@link - * FormulaRecord}). So the the only thing that needs to be done is to ignore the erroneous - * shared formula flag.
    - * - * This method may also be used for setting breakpoints to help diagnose issues regarding the - * abnormally-set 'shared formula' flags. - * (see TestValueRecordsAggregate.testSpuriousSharedFormulaFlag()).

    - */ - private static void handleMissingSharedFormulaRecord(FormulaRecord formula) { - // make sure 'unshared' formula is actually available - Ptg firstToken = formula.getParsedExpression()[0]; - if (firstToken instanceof ExpPtg) { - throw new RecordFormatException( - "SharedFormulaRecord not found for FormulaRecord with (isSharedFormula=true)"); - } - // could log an info message here since this is a fairly unusual occurrence. - formula.setSharedFormula(false); // no point leaving the flag erroneously set - } - - public FormulaRecord getFormulaRecord() { - return _formulaRecord; - } - - /** - * debug only - * TODO - encapsulate - */ - public StringRecord getStringRecord() { - return _stringRecord; - } - - public short getXFIndex() { - return _formulaRecord.getXFIndex(); - } - - public void setXFIndex(short xf) { - _formulaRecord.setXFIndex(xf); - } - - public void setColumn(short col) { - _formulaRecord.setColumn(col); - } - - public void setRow(int row) { - _formulaRecord.setRow(row); - } - - public short getColumn() { - return _formulaRecord.getColumn(); - } - - public int getRow() { - return _formulaRecord.getRow(); - } - - public String toString() { - return _formulaRecord.toString(); - } - - public void visitContainedRecords(RecordVisitor rv) { - rv.visitRecord(_formulaRecord); - Record sharedFormulaRecord = _sharedValueManager.getRecordForFirstCell(this); - if (sharedFormulaRecord != null) { - rv.visitRecord(sharedFormulaRecord); - } - if (_formulaRecord.hasCachedResultString() && _stringRecord != null) { - rv.visitRecord(_stringRecord); - } - } - - public String getStringValue() { - if(_stringRecord==null) { - return null; - } - return _stringRecord.getString(); - } - - public void setCachedStringResult(String value) { - - // Save the string into a String Record, creating one if required - if(_stringRecord == null) { - _stringRecord = new StringRecord(); - } - _stringRecord.setString(value); - if (value.length() < 1) { - _formulaRecord.setCachedResultTypeEmptyString(); - } else { - _formulaRecord.setCachedResultTypeString(); - } - } - public void setCachedBooleanResult(boolean value) { - _stringRecord = null; - _formulaRecord.setCachedResultBoolean(value); - } - public void setCachedErrorResult(int errorCode) { - _stringRecord = null; - _formulaRecord.setCachedResultErrorCode(errorCode); - } - public void setCachedErrorResult(FormulaError error) { - setCachedErrorResult(error.getCode()); - } - public void setCachedDoubleResult(double value) { - _stringRecord = null; - _formulaRecord.setValue(value); - } - - public Ptg[] getFormulaTokens() { - if (_sharedFormulaRecord != null) { - return _sharedFormulaRecord.getFormulaTokens(_formulaRecord); - } - CellReference expRef = _formulaRecord.getFormula().getExpReference(); - if (expRef != null) { - ArrayRecord arec = _sharedValueManager.getArrayRecord(expRef.getRow(), expRef.getCol()); - return arec.getFormulaTokens(); - } - return _formulaRecord.getParsedExpression(); - } - - /** - * Also checks for a related shared formula and unlinks it if found - */ - public void setParsedExpression(Ptg[] ptgs) { - notifyFormulaChanging(); - _formulaRecord.setParsedExpression(ptgs); - } - - public void unlinkSharedFormula() { - SharedFormulaRecord sfr = _sharedFormulaRecord; - if (sfr == null) { - throw new IllegalStateException("Formula not linked to shared formula"); - } - Ptg[] ptgs = sfr.getFormulaTokens(_formulaRecord); - _formulaRecord.setParsedExpression(ptgs); - //Now its not shared! - _formulaRecord.setSharedFormula(false); - _sharedFormulaRecord = null; - } - /** - * Should be called by any code which is either deleting this formula cell, or changing - * its type. This method gives the aggregate a chance to unlink any shared formula - * that may be involved with this cell formula. - */ - public void notifyFormulaChanging() { - if (_sharedFormulaRecord != null) { - _sharedValueManager.unlink(_sharedFormulaRecord); - } - } - public boolean isPartOfArrayFormula() { - if (_sharedFormulaRecord != null) { - return false; - } - CellReference expRef = _formulaRecord.getFormula().getExpReference(); - ArrayRecord arec = expRef == null ? null : _sharedValueManager.getArrayRecord(expRef.getRow(), expRef.getCol()); - return arec != null; - } - - public CellRangeAddress getArrayFormulaRange() { - if (_sharedFormulaRecord != null) { - throw new IllegalStateException("not an array formula cell."); - } - CellReference expRef = _formulaRecord.getFormula().getExpReference(); - if (expRef == null) { - throw new IllegalStateException("not an array formula cell."); - } - ArrayRecord arec = _sharedValueManager.getArrayRecord(expRef.getRow(), expRef.getCol()); - if (arec == null) { - throw new IllegalStateException("ArrayRecord was not found for the locator " + expRef.formatAsString()); - } - CellRangeAddress8Bit a = arec.getRange(); - return new CellRangeAddress(a.getFirstRow(), a.getLastRow(), a.getFirstColumn(),a.getLastColumn()); - } - - public void setArrayFormula(CellRangeAddress r, Ptg[] ptgs) { - - ArrayRecord arr = new ArrayRecord(Formula.create(ptgs), new CellRangeAddress8Bit(r.getFirstRow(), r.getLastRow(), r.getFirstColumn(), r.getLastColumn())); - _sharedValueManager.addArrayRecord(arr); - } - /** - * Removes an array formula - * @return the range of the array formula containing the specified cell. Never null - */ - public CellRangeAddress removeArrayFormula(int rowIndex, int columnIndex) { - CellRangeAddress8Bit a = _sharedValueManager.removeArrayFormula(rowIndex, columnIndex); - // at this point FormulaRecordAggregate#isPartOfArrayFormula() should return false - _formulaRecord.setParsedExpression(null); - return new CellRangeAddress(a.getFirstRow(), a.getLastRow(), a.getFirstColumn(), a.getLastColumn()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java deleted file mode 100644 index cc59338a5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; - -/** - * - * @author Josh Micich - */ -public final class MergedCellsTable extends RecordAggregate { - private static int MAX_MERGED_REGIONS = 1027; // enforced by the 8224 byte limit - - private final List _mergedRegions; - - /** - * Creates an empty aggregate - */ - public MergedCellsTable() { - _mergedRegions = new ArrayList(); - } - - /** - * reads zero or more consecutive {@link MergeCellsRecord}s - * @param rs - */ - public void read(RecordStream rs) { - List temp = _mergedRegions; - while (rs.peekNextClass() == MergeCellsRecord.class) { - MergeCellsRecord mcr = (MergeCellsRecord) rs.getNext(); - int nRegions = mcr.getNumAreas(); - for (int i = 0; i < nRegions; i++) { - CellRangeAddress cra = mcr.getAreaAt(i); - temp.add(cra); - } - } - } - - public int getRecordSize() { - // a bit cheaper than the default impl - int nRegions = _mergedRegions.size(); - if (nRegions < 1) { - // no need to write a single empty MergeCellsRecord - return 0; - } - int nMergedCellsRecords = nRegions / MAX_MERGED_REGIONS; - int nLeftoverMergedRegions = nRegions % MAX_MERGED_REGIONS; - - int result = nMergedCellsRecords - * (4 + CellRangeAddressList.getEncodedSize(MAX_MERGED_REGIONS)) + 4 - + CellRangeAddressList.getEncodedSize(nLeftoverMergedRegions); - return result; - } - - public void visitContainedRecords(RecordVisitor rv) { - int nRegions = _mergedRegions.size(); - if (nRegions < 1) { - // no need to write a single empty MergeCellsRecord - return; - } - - int nFullMergedCellsRecords = nRegions / MAX_MERGED_REGIONS; - int nLeftoverMergedRegions = nRegions % MAX_MERGED_REGIONS; - CellRangeAddress[] cras = new CellRangeAddress[nRegions]; - _mergedRegions.toArray(cras); - - for (int i = 0; i < nFullMergedCellsRecords; i++) { - int startIx = i * MAX_MERGED_REGIONS; - rv.visitRecord(new MergeCellsRecord(cras, startIx, MAX_MERGED_REGIONS)); - } - if (nLeftoverMergedRegions > 0) { - int startIx = nFullMergedCellsRecords * MAX_MERGED_REGIONS; - rv.visitRecord(new MergeCellsRecord(cras, startIx, nLeftoverMergedRegions)); - } - } - public void addRecords(MergeCellsRecord[] mcrs) { - for (int i = 0; i < mcrs.length; i++) { - addMergeCellsRecord(mcrs[i]); - } - } - - private void addMergeCellsRecord(MergeCellsRecord mcr) { - int nRegions = mcr.getNumAreas(); - for (int i = 0; i < nRegions; i++) { - CellRangeAddress cra = mcr.getAreaAt(i); - _mergedRegions.add(cra); - } - } - - public CellRangeAddress get(int index) { - checkIndex(index); - return _mergedRegions.get(index); - } - - public void remove(int index) { - checkIndex(index); - _mergedRegions.remove(index); - } - - private void checkIndex(int index) { - if (index < 0 || index >= _mergedRegions.size()) { - throw new IllegalArgumentException("Specified CF index " + index - + " is outside the allowable range (0.." + (_mergedRegions.size() - 1) + ")"); - } - } - - public void addArea(int rowFrom, int colFrom, int rowTo, int colTo) { - _mergedRegions.add(new CellRangeAddress(rowFrom, rowTo, colFrom, colTo)); - } - - public int getNumberOfMergedRegions() { - return _mergedRegions.size(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java deleted file mode 100644 index b42f09b47..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java +++ /dev/null @@ -1,705 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.model.InternalSheet; -import org.apache.poi.hssf.record.*; -import org.apache.poi.util.HexDump; - -/** - * Groups the page settings records for a worksheet.

    - * - * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block' - */ -public final class PageSettingsBlock extends RecordAggregate { - - /** - * PLS is potentially a continued record, but is currently uninterpreted by POI - */ - private static final class PLSAggregate extends RecordAggregate { - private static final ContinueRecord[] EMPTY_CONTINUE_RECORD_ARRAY = { }; - private final Record _pls; - /** - * holds any continue records found after the PLS record.
    - * This would not be required if PLS was properly interpreted. - * Currently, PLS is an {@link UnknownRecord} and does not automatically - * include any trailing {@link ContinueRecord}s. - */ - private ContinueRecord[] _plsContinues; - - public PLSAggregate(RecordStream rs) { - _pls = rs.getNext(); - if (rs.peekNextSid()==ContinueRecord.sid) { - List temp = new ArrayList(); - while (rs.peekNextSid()==ContinueRecord.sid) { - temp.add((ContinueRecord)rs.getNext()); - } - _plsContinues = new ContinueRecord[temp.size()]; - temp.toArray(_plsContinues); - } else { - _plsContinues = EMPTY_CONTINUE_RECORD_ARRAY; - } - } - - @Override - public void visitContainedRecords(RecordVisitor rv) { - rv.visitRecord(_pls); - for (ContinueRecord _plsContinue : _plsContinues) { - rv.visitRecord(_plsContinue); - } - } - } - - // Every one of these component records is optional - // (The whole PageSettingsBlock may not be present) - private PageBreakRecord _rowBreaksRecord; - private PageBreakRecord _columnBreaksRecord; - private HeaderRecord _header; - private FooterRecord _footer; - private HCenterRecord _hCenter; - private VCenterRecord _vCenter; - private LeftMarginRecord _leftMargin; - private RightMarginRecord _rightMargin; - private TopMarginRecord _topMargin; - private BottomMarginRecord _bottomMargin; - private final List _plsRecords; - private PrintSetupRecord _printSetup; - private Record _bitmap; - private HeaderFooterRecord _headerFooter; - /** - * HeaderFooterRecord records belonging to preceding CustomViewSettingsRecordAggregates. - * The indicator of such records is a non-zero GUID, - * see {@link org.apache.poi.hssf.record.HeaderFooterRecord#getGuid()} - */ - private final List _sviewHeaderFooters = new ArrayList(); - private Record _printSize; - - public PageSettingsBlock(RecordStream rs) { - _plsRecords = new ArrayList(); - while(true) { - if (!readARecord(rs)) { - break; - } - } - } - - /** - * Creates a PageSettingsBlock with default settings - */ - public PageSettingsBlock() { - _plsRecords = new ArrayList(); - _rowBreaksRecord = new HorizontalPageBreakRecord(); - _columnBreaksRecord = new VerticalPageBreakRecord(); - _header = new HeaderRecord(""); - _footer = new FooterRecord(""); - _hCenter = createHCenter(); - _vCenter = createVCenter(); - _printSetup = createPrintSetup(); - } - - /** - * @param sid the record sid - * - * @return true if the specified Record sid is one belonging to the - * 'Page Settings Block'. - */ - public static boolean isComponentRecord(int sid) { - switch (sid) { - case HorizontalPageBreakRecord.sid: - case VerticalPageBreakRecord.sid: - case HeaderRecord.sid: - case FooterRecord.sid: - case HCenterRecord.sid: - case VCenterRecord.sid: - case LeftMarginRecord.sid: - case RightMarginRecord.sid: - case TopMarginRecord.sid: - case BottomMarginRecord.sid: - case UnknownRecord.PLS_004D: - case PrintSetupRecord.sid: - case UnknownRecord.BITMAP_00E9: - case UnknownRecord.PRINTSIZE_0033: - case HeaderFooterRecord.sid: // extra header/footer settings supported by Excel 2007 - return true; - } - return false; - } - - private boolean readARecord(RecordStream rs) { - switch (rs.peekNextSid()) { - case HorizontalPageBreakRecord.sid: - checkNotPresent(_rowBreaksRecord); - _rowBreaksRecord = (PageBreakRecord) rs.getNext(); - break; - case VerticalPageBreakRecord.sid: - checkNotPresent(_columnBreaksRecord); - _columnBreaksRecord = (PageBreakRecord) rs.getNext(); - break; - case HeaderRecord.sid: - checkNotPresent(_header); - _header = (HeaderRecord) rs.getNext(); - break; - case FooterRecord.sid: - checkNotPresent(_footer); - _footer = (FooterRecord) rs.getNext(); - break; - case HCenterRecord.sid: - checkNotPresent(_hCenter); - _hCenter = (HCenterRecord) rs.getNext(); - break; - case VCenterRecord.sid: - checkNotPresent(_vCenter); - _vCenter = (VCenterRecord) rs.getNext(); - break; - case LeftMarginRecord.sid: - checkNotPresent(_leftMargin); - _leftMargin = (LeftMarginRecord) rs.getNext(); - break; - case RightMarginRecord.sid: - checkNotPresent(_rightMargin); - _rightMargin = (RightMarginRecord) rs.getNext(); - break; - case TopMarginRecord.sid: - checkNotPresent(_topMargin); - _topMargin = (TopMarginRecord) rs.getNext(); - break; - case BottomMarginRecord.sid: - checkNotPresent(_bottomMargin); - _bottomMargin = (BottomMarginRecord) rs.getNext(); - break; - case UnknownRecord.PLS_004D: - _plsRecords.add(new PLSAggregate(rs)); - break; - case PrintSetupRecord.sid: - checkNotPresent(_printSetup); - _printSetup = (PrintSetupRecord)rs.getNext(); - break; - case UnknownRecord.BITMAP_00E9: - checkNotPresent(_bitmap); - _bitmap = rs.getNext(); - break; - case UnknownRecord.PRINTSIZE_0033: - checkNotPresent(_printSize); - _printSize = rs.getNext(); - break; - case HeaderFooterRecord.sid: - //there can be multiple HeaderFooterRecord records belonging to different sheet views - HeaderFooterRecord hf = (HeaderFooterRecord)rs.getNext(); - if(hf.isCurrentSheet()) { - _headerFooter = hf; - } else { - _sviewHeaderFooters.add(hf); - } - break; - default: - // all other record types are not part of the PageSettingsBlock - return false; - } - return true; - } - - private void checkNotPresent(Record rec) { - if (rec != null) { - throw new RecordFormatException("Duplicate PageSettingsBlock record (sid=0x" - + Integer.toHexString(rec.getSid()) + ")"); - } - } - - private PageBreakRecord getRowBreaksRecord() { - if (_rowBreaksRecord == null) { - _rowBreaksRecord = new HorizontalPageBreakRecord(); - } - return _rowBreaksRecord; - } - - private PageBreakRecord getColumnBreaksRecord() { - if (_columnBreaksRecord == null) { - _columnBreaksRecord = new VerticalPageBreakRecord(); - } - return _columnBreaksRecord; - } - - - /** - * Sets a page break at the indicated column - * - * @param column the column to add page breaks to - * @param fromRow the starting row - * @param toRow the ending row - */ - public void setColumnBreak(short column, short fromRow, short toRow) { - getColumnBreaksRecord().addBreak(column, fromRow, toRow); - } - - /** - * Removes a page break at the indicated column - * - * @param column the column to check for page breaks - */ - public void removeColumnBreak(int column) { - getColumnBreaksRecord().removeBreak(column); - } - - - - - @Override - public void visitContainedRecords(RecordVisitor rv) { - // Replicates record order from Excel 2007, though this is not critical - - visitIfPresent(_rowBreaksRecord, rv); - visitIfPresent(_columnBreaksRecord, rv); - // Write out empty header / footer records if these are missing - if (_header == null) { - rv.visitRecord(new HeaderRecord("")); - } else { - rv.visitRecord(_header); - } - if (_footer == null) { - rv.visitRecord(new FooterRecord("")); - } else { - rv.visitRecord(_footer); - } - visitIfPresent(_hCenter, rv); - visitIfPresent(_vCenter, rv); - visitIfPresent(_leftMargin, rv); - visitIfPresent(_rightMargin, rv); - visitIfPresent(_topMargin, rv); - visitIfPresent(_bottomMargin, rv); - for (RecordAggregate pls : _plsRecords) { - pls.visitContainedRecords(rv); - } - visitIfPresent(_printSetup, rv); - visitIfPresent(_printSize, rv); - visitIfPresent(_headerFooter, rv); - visitIfPresent(_bitmap, rv); - } - private static void visitIfPresent(Record r, RecordVisitor rv) { - if (r != null) { - rv.visitRecord(r); - } - } - private static void visitIfPresent(PageBreakRecord r, RecordVisitor rv) { - if (r != null) { - if (r.isEmpty()) { - // its OK to not serialize empty page break records - return; - } - rv.visitRecord(r); - } - } - - /** - * creates the HCenter Record and sets it to false (don't horizontally center) - */ - private static HCenterRecord createHCenter() { - HCenterRecord retval = new HCenterRecord(); - - retval.setHCenter(false); - return retval; - } - - /** - * creates the VCenter Record and sets it to false (don't horizontally center) - */ - private static VCenterRecord createVCenter() { - VCenterRecord retval = new VCenterRecord(); - - retval.setVCenter(false); - return retval; - } - - /** - * creates the PrintSetup Record and sets it to defaults and marks it invalid - * @see org.apache.poi.hssf.record.PrintSetupRecord - * @see org.apache.poi.hssf.record.Record - * @return record containing a PrintSetupRecord - */ - private static PrintSetupRecord createPrintSetup() { - PrintSetupRecord retval = new PrintSetupRecord(); - - retval.setPaperSize(( short ) 1); - retval.setScale(( short ) 100); - retval.setPageStart(( short ) 1); - retval.setFitWidth(( short ) 1); - retval.setFitHeight(( short ) 1); - retval.setOptions(( short ) 2); - retval.setHResolution(( short ) 300); - retval.setVResolution(( short ) 300); - retval.setHeaderMargin( 0.5); - retval.setFooterMargin( 0.5); - retval.setCopies(( short ) 1); - return retval; - } - - - /** - * Returns the HeaderRecord. - * @return HeaderRecord for the sheet. - */ - public HeaderRecord getHeader () - { - return _header; - } - - /** - * Sets the HeaderRecord. - * @param newHeader The new HeaderRecord for the sheet. - */ - public void setHeader (HeaderRecord newHeader) - { - _header = newHeader; - } - - /** - * Returns the FooterRecord. - * @return FooterRecord for the sheet. - */ - public FooterRecord getFooter () - { - return _footer; - } - - /** - * Sets the FooterRecord. - * @param newFooter The new FooterRecord for the sheet. - */ - public void setFooter (FooterRecord newFooter) - { - _footer = newFooter; - } - - /** - * Returns the PrintSetupRecord. - * @return PrintSetupRecord for the sheet. - */ - public PrintSetupRecord getPrintSetup () - { - return _printSetup; - } - - /** - * Sets the PrintSetupRecord. - * @param newPrintSetup The new PrintSetupRecord for the sheet. - */ - public void setPrintSetup (PrintSetupRecord newPrintSetup) - { - _printSetup = newPrintSetup; - } - - - private Margin getMarginRec(int marginIndex) { - switch (marginIndex) { - case InternalSheet.LeftMargin: return _leftMargin; - case InternalSheet.RightMargin: return _rightMargin; - case InternalSheet.TopMargin: return _topMargin; - case InternalSheet.BottomMargin: return _bottomMargin; - } - throw new IllegalArgumentException( "Unknown margin constant: " + marginIndex ); - } - - - /** - * Gets the size of the margin in inches. - * @param margin which margin to get - * @return the size of the margin - */ - public double getMargin(short margin) { - Margin m = getMarginRec(margin); - if (m != null) { - return m.getMargin(); - } - switch (margin) { - case InternalSheet.LeftMargin: return .75; - case InternalSheet.RightMargin: return .75; - case InternalSheet.TopMargin: return 1.0; - case InternalSheet.BottomMargin: return 1.0; - } - throw new IllegalArgumentException( "Unknown margin constant: " + margin ); - } - - /** - * Sets the size of the margin in inches. - * @param margin which margin to get - * @param size the size of the margin - */ - public void setMargin(short margin, double size) { - Margin m = getMarginRec(margin); - if (m == null) { - switch (margin) { - case InternalSheet.LeftMargin: - _leftMargin = new LeftMarginRecord(); - m = _leftMargin; - break; - case InternalSheet.RightMargin: - _rightMargin = new RightMarginRecord(); - m = _rightMargin; - break; - case InternalSheet.TopMargin: - _topMargin = new TopMarginRecord(); - m = _topMargin; - break; - case InternalSheet.BottomMargin: - _bottomMargin = new BottomMarginRecord(); - m = _bottomMargin; - break; - default : - throw new IllegalArgumentException( "Unknown margin constant: " + margin ); - } - } - m.setMargin( size ); - } - - /** - * Shifts all the page breaks in the range "count" number of rows/columns - * @param breaks The page record to be shifted - * @param start Starting "main" value to shift breaks - * @param stop Ending "main" value to shift breaks - * @param count number of units (rows/columns) to shift by - */ - private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) { - - Iterator iterator = breaks.getBreaksIterator(); - List shiftedBreak = new ArrayList(); - while(iterator.hasNext()) - { - PageBreakRecord.Break breakItem = iterator.next(); - int breakLocation = breakItem.main; - boolean inStart = (breakLocation >= start); - boolean inEnd = (breakLocation <= stop); - if(inStart && inEnd) { - shiftedBreak.add(breakItem); - } - } - - iterator = shiftedBreak.iterator(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = iterator.next(); - breaks.removeBreak(breakItem.main); - breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); - } - } - - - /** - * Sets a page break at the indicated row - * @param row the row - * @param fromCol the starting column - * @param toCol the ending column - */ - public void setRowBreak(int row, short fromCol, short toCol) { - getRowBreaksRecord().addBreak((short)row, fromCol, toCol); - } - - /** - * Removes a page break at the indicated row - * @param row the row - */ - public void removeRowBreak(int row) { - if (getRowBreaksRecord().getBreaks().length < 1) { - throw new IllegalArgumentException("Sheet does not define any row breaks"); - } - getRowBreaksRecord().removeBreak((short)row); - } - - /** - * Queries if the specified row has a page break - * - * @param row the row to check for - * - * @return true if the specified row has a page break - */ - public boolean isRowBroken(int row) { - return getRowBreaksRecord().getBreak(row) != null; - } - - - /** - * Queries if the specified column has a page break - * - * @param column the column to check for - * - * @return true if the specified column has a page break - */ - public boolean isColumnBroken(int column) { - return getColumnBreaksRecord().getBreak(column) != null; - } - - /** - * Shifts the horizontal page breaks for the indicated count - * @param startingRow the starting row - * @param endingRow the ending row - * @param count the number of rows to shift by - */ - public void shiftRowBreaks(int startingRow, int endingRow, int count) { - shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count); - } - - /** - * Shifts the vertical page breaks for the indicated count - * @param startingCol the starting column - * @param endingCol the ending column - * @param count the number of columns to shift by - */ - public void shiftColumnBreaks(short startingCol, short endingCol, short count) { - shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count); - } - - /** - * @return all the horizontal page breaks, never null - */ - public int[] getRowBreaks() { - return getRowBreaksRecord().getBreaks(); - } - - /** - * @return the number of row page breaks - */ - public int getNumRowBreaks(){ - return getRowBreaksRecord().getNumBreaks(); - } - - /** - * @return all the column page breaks, never null - */ - public int[] getColumnBreaks(){ - return getColumnBreaksRecord().getBreaks(); - } - - /** - * @return the number of column page breaks - */ - public int getNumColumnBreaks(){ - return getColumnBreaksRecord().getNumBreaks(); - } - - public VCenterRecord getVCenter() { - return _vCenter; - } - - public HCenterRecord getHCenter() { - return _hCenter; - } - - /** - * HEADERFOOTER is new in 2007. Some apps seem to have scattered this record long after - * the {@link PageSettingsBlock} where it belongs. - * - * @param rec the HeaderFooterRecord to set - */ - public void addLateHeaderFooter(HeaderFooterRecord rec) { - if (_headerFooter != null) { - throw new IllegalStateException("This page settings block already has a header/footer record"); - } - if (rec.getSid() != HeaderFooterRecord.sid) { - throw new RecordFormatException("Unexpected header-footer record sid: 0x" + Integer.toHexString(rec.getSid())); - } - _headerFooter = rec; - } - - /** - * This method reads PageSettingsBlock records from the supplied RecordStream until the first - * non-PageSettingsBlock record is encountered. As each record is read, it is incorporated - * into this PageSettingsBlock.

    - * - * The latest Excel version seems to write the PageSettingsBlock uninterrupted. However there - * are several examples (that Excel reads OK) where these records are not written together: - * - *

      - *
    • HEADER_FOOTER(0x089C) after WINDOW2 - This record is new in 2007. Some apps - * seem to have scattered this record long after the PageSettingsBlock where it belongs - * test samples: SharedFormulaTest.xls, ex44921-21902.xls, ex42570-20305.xls
    • - *
    • PLS, WSBOOL, PageSettingsBlock - WSBOOL is not a PSB record. - * This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"
    • - *
    • Margins after DIMENSION - All of PSB should be before DIMENSION. (Bug-47199)
    • - *
    - * - * These were probably written by other applications (or earlier versions of Excel). It was - * decided to not write specific code for detecting each of these cases. POI now tolerates - * PageSettingsBlock records scattered all over the sheet record stream, and in any order, but - * does not allow duplicates of any of those records.

    - * - * Note - when POI writes out this PageSettingsBlock, the records will always be written - * in one consolidated block (in the standard ordering) regardless of how scattered the records - * were when they were originally read. - * - * @param rs the RecordStream to read from - * - * @throws RecordFormatException if any PSB record encountered has the same type (sid) as - * a record that is already part of this PageSettingsBlock - */ - public void addLateRecords(RecordStream rs) { - while(true) { - if (!readARecord(rs)) { - break; - } - } - } - - /** - * Some apps can define multiple HeaderFooterRecord records for a sheet. - * When saving such a file Excel 2007 re-positions them according to the following rules: - * - take a HeaderFooterRecord and read 16-byte GUID at offset 12. If it is zero, - * it means the current sheet and the given HeaderFooterRecord belongs to this PageSettingsBlock - * - If GUID is not zero then search in preceding CustomViewSettingsRecordAggregates. - * Compare first 16 bytes of UserSViewBegin with the HeaderFooterRecord's GUID. If match, - * then append the HeaderFooterRecord to this CustomViewSettingsRecordAggregates - * - * @param sheetRecords the list of sheet records read so far - */ - public void positionRecords(List sheetRecords) { - // Take a copy to loop over, so we can update the real one - // without concurrency issues - List hfRecordsToIterate = new ArrayList(_sviewHeaderFooters); - - final Map hfGuidMap = new HashMap(); - - for(final HeaderFooterRecord hf : hfRecordsToIterate) { - hfGuidMap.put(HexDump.toHex(hf.getGuid()), hf); - } - - // loop through HeaderFooterRecord records having not-empty GUID and match them with - // CustomViewSettingsRecordAggregate blocks having UserSViewBegin with the same GUID - for (RecordBase rb : sheetRecords) { - if (rb instanceof CustomViewSettingsRecordAggregate) { - final CustomViewSettingsRecordAggregate cv = (CustomViewSettingsRecordAggregate) rb; - cv.visitContainedRecords(new RecordVisitor() { - @Override - public void visitRecord(Record r) { - if (r.getSid() == UserSViewBegin.sid) { - String guid = HexDump.toHex(((UserSViewBegin) r).getGuid()); - HeaderFooterRecord hf = hfGuidMap.get(guid); - - if (hf != null) { - cv.append(hf); - _sviewHeaderFooters.remove(hf); - } - } - } - }); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java deleted file mode 100644 index fd458df96..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java +++ /dev/null @@ -1,115 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; - -/** - * RecordAggregates are groups of of BIFF Records that are typically stored - * together and/or updated together. Workbook / Sheet records are typically stored in a sequential - * list, which does not provide much structure to coordinate updates. - * - * @author Josh Micich - */ -public abstract class RecordAggregate extends RecordBase { - - /** - * Visit each of the atomic BIFF records contained in this {@link RecordAggregate} in the order - * that they should be written to file. Implementors may or may not return the actual - * {@link Record}s being used to manage POI's internal implementation. Callers should not - * assume either way, and therefore only attempt to modify those {@link Record}s after cloning - */ - public abstract void visitContainedRecords(RecordVisitor rv); - - public final int serialize(int offset, byte[] data) { - SerializingRecordVisitor srv = new SerializingRecordVisitor(data, offset); - visitContainedRecords(srv); - return srv.countBytesWritten(); - } - public int getRecordSize() { - RecordSizingVisitor rsv = new RecordSizingVisitor(); - visitContainedRecords(rsv); - return rsv.getTotalSize(); - } - - public interface RecordVisitor { - /** - * Implementors may call non-mutating methods on Record r. - * @param r must not be null - */ - void visitRecord(Record r); - } - - private static final class SerializingRecordVisitor implements RecordVisitor { - - private final byte[] _data; - private final int _startOffset; - private int _countBytesWritten; - - public SerializingRecordVisitor(byte[] data, int startOffset) { - _data = data; - _startOffset = startOffset; - _countBytesWritten = 0; - } - public int countBytesWritten() { - return _countBytesWritten; - } - public void visitRecord(Record r) { - int currentOffset = _startOffset + _countBytesWritten; - _countBytesWritten += r.serialize(currentOffset, _data); - } - } - private static final class RecordSizingVisitor implements RecordVisitor { - - private int _totalSize; - - public RecordSizingVisitor() { - _totalSize = 0; - } - public int getTotalSize() { - return _totalSize; - } - public void visitRecord(Record r) { - _totalSize += r.getRecordSize(); - } - } - /** - * A wrapper for {@link RecordVisitor} which accumulates the sizes of all - * records visited. - */ - public static final class PositionTrackingVisitor implements RecordVisitor { - private final RecordVisitor _rv; - private int _position; - - public PositionTrackingVisitor(RecordVisitor rv, int initialPosition) { - _rv = rv; - _position = initialPosition; - } - public void visitRecord(Record r) { - _position += r.getRecordSize(); - _rv.visitRecord(r); - } - public void setPosition(int position) { - _position = position; - } - public int getPosition() { - return _position; - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java deleted file mode 100644 index 5551639b4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java +++ /dev/null @@ -1,505 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.*; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaShifter; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class RowRecordsAggregate extends RecordAggregate { - private int _firstrow = -1; - private int _lastrow = -1; - private final Map _rowRecords; - private final ValueRecordsAggregate _valuesAgg; - private final List _unknownRecords; - private final SharedValueManager _sharedValueManager; - - // Cache values to speed up performance of - // getStartRowNumberForBlock / getEndRowNumberForBlock, see Bugzilla 47405 - private RowRecord[] _rowRecordValues = null; - - /** Creates a new instance of ValueRecordsAggregate */ - public RowRecordsAggregate() { - this(SharedValueManager.createEmpty()); - } - private RowRecordsAggregate(SharedValueManager svm) { - if (svm == null) { - throw new IllegalArgumentException("SharedValueManager must be provided."); - } - _rowRecords = new TreeMap(); - _valuesAgg = new ValueRecordsAggregate(); - _unknownRecords = new ArrayList(); - _sharedValueManager = svm; - } - - /** - * @param rs record stream with all {@link SharedFormulaRecord} - * {@link ArrayRecord}, {@link TableRecord} {@link MergeCellsRecord} Records removed - * @param svm an initialised {@link SharedValueManager} (from the shared formula, array - * and table records of the current sheet). Never null. - */ - public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) { - this(svm); - while(rs.hasNext()) { - Record rec = rs.getNext(); - switch (rec.getSid()) { - case RowRecord.sid: - insertRow((RowRecord) rec); - continue; - case DConRefRecord.sid: - addUnknownRecord(rec); - continue; - case DBCellRecord.sid: - // end of 'Row Block'. Should only occur after cell records - // ignore DBCELL records because POI generates them upon re-serialization - continue; - } - if (rec instanceof UnknownRecord) { - // might need to keep track of where exactly these belong - addUnknownRecord(rec); - while (rs.peekNextSid() == ContinueRecord.sid) { - addUnknownRecord(rs.getNext()); - } - continue; - } - if (rec instanceof MulBlankRecord) { - _valuesAgg.addMultipleBlanks((MulBlankRecord) rec); - continue; - } - if (!(rec instanceof CellValueRecordInterface)) { - throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")"); - } - _valuesAgg.construct((CellValueRecordInterface)rec, rs, svm); - } - } - /** - * Handles UnknownRecords which appear within the row/cell records - */ - private void addUnknownRecord(Record rec) { - // ony a few distinct record IDs are encountered by the existing POI test cases: - // 0x1065 // many - // 0x01C2 // several - // 0x0034 // few - // No documentation could be found for these - - // keep the unknown records for re-serialization - _unknownRecords.add(rec); - } - public void insertRow(RowRecord row) { - // Integer integer = Integer.valueOf(row.getRowNumber()); - _rowRecords.put(Integer.valueOf(row.getRowNumber()), row); - // Clear the cached values - _rowRecordValues = null; - if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) { - _firstrow = row.getRowNumber(); - } - if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) { - _lastrow = row.getRowNumber(); - } - } - - public void removeRow(RowRecord row) { - int rowIndex = row.getRowNumber(); - _valuesAgg.removeAllCellsValuesForRow(rowIndex); - Integer key = Integer.valueOf(rowIndex); - RowRecord rr = _rowRecords.remove(key); - if (rr == null) { - throw new RuntimeException("Invalid row index (" + key.intValue() + ")"); - } - if (row != rr) { - _rowRecords.put(key, rr); - throw new RuntimeException("Attempt to remove row that does not belong to this sheet"); - } - - // Clear the cached values - _rowRecordValues = null; - } - - public RowRecord getRow(int rowIndex) { - int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex(); - if (rowIndex < 0 || rowIndex > maxrow) { - throw new IllegalArgumentException("The row number must be between 0 and " + maxrow + ", but had: " + rowIndex); - } - return _rowRecords.get(Integer.valueOf(rowIndex)); - } - - public int getPhysicalNumberOfRows() - { - return _rowRecords.size(); - } - - public int getFirstRowNum() - { - return _firstrow; - } - - public int getLastRowNum() - { - return _lastrow; - } - - /** Returns the number of row blocks. - *

    The row blocks are goupings of rows that contain the DBCell record - * after them - */ - public int getRowBlockCount() { - int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE; - if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0) - size++; - return size; - } - - private int getRowBlockSize(int block) { - return RowRecord.ENCODED_SIZE * getRowCountForBlock(block); - } - - /** Returns the number of physical rows within a block*/ - public int getRowCountForBlock(int block) { - int startIndex = block * DBCellRecord.BLOCK_SIZE; - int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1; - if (endIndex >= _rowRecords.size()) - endIndex = _rowRecords.size()-1; - - return endIndex-startIndex+1; - } - - /** Returns the physical row number of the first row in a block*/ - private int getStartRowNumberForBlock(int block) { - int startIndex = block * DBCellRecord.BLOCK_SIZE; - - if (_rowRecordValues == null) { - _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]); - } - - try { - return _rowRecordValues[startIndex].getRowNumber(); - } catch(ArrayIndexOutOfBoundsException e) { - throw new RuntimeException("Did not find start row for block " + block); - } - } - - /** Returns the physical row number of the end row in a block*/ - private int getEndRowNumberForBlock(int block) { - int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1; - if (endIndex >= _rowRecords.size()) - endIndex = _rowRecords.size()-1; - - if (_rowRecordValues == null){ - _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]); - } - - try { - return _rowRecordValues[endIndex].getRowNumber(); - } catch(ArrayIndexOutOfBoundsException e) { - throw new RuntimeException("Did not find end row for block " + block); - } - } - - private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) { - final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE; - final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; - - Iterator rowIterator = _rowRecords.values().iterator(); - - //Given that we basically iterate through the rows in order, - //For a performance improvement, it would be better to return an instance of - //an iterator and use that instance throughout, rather than recreating one and - //having to move it to the right position. - int i=0; - for (;i getIterator() { - return _rowRecords.values().iterator(); - } - - public int findStartOfRowOutlineGroup(int row) { - // Find the start of the group. - RowRecord rowRecord = this.getRow( row ); - int level = rowRecord.getOutlineLevel(); - int currentRow = row; - while (currentRow >= 0 && this.getRow( currentRow ) != null) { - rowRecord = this.getRow( currentRow ); - if (rowRecord.getOutlineLevel() < level) { - return currentRow + 1; - } - currentRow--; - } - - return currentRow + 1; - } - - public int findEndOfRowOutlineGroup(int row) { - int level = getRow( row ).getOutlineLevel(); - int currentRow; - for (currentRow = row; currentRow < getLastRowNum(); currentRow++) { - if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) { - break; - } - } - - return currentRow-1; - } - - /** - * Hide all rows at or below the current outline level - * @return index of the next row after the last row that gets hidden - */ - private int writeHidden(RowRecord pRowRecord, int row) { - int rowIx = row; - RowRecord rowRecord = pRowRecord; - int level = rowRecord.getOutlineLevel(); - while (rowRecord != null && getRow(rowIx).getOutlineLevel() >= level) { - rowRecord.setZeroHeight(true); - rowIx++; - rowRecord = getRow(rowIx); - } - return rowIx; - } - - public void collapseRow(int rowNumber) { - - // Find the start of the group. - int startRow = findStartOfRowOutlineGroup(rowNumber); - RowRecord rowRecord = getRow(startRow); - - // Hide all the columns until the end of the group - int nextRowIx = writeHidden(rowRecord, startRow); - - RowRecord row = getRow(nextRowIx); - if (row == null) { - row = createRow(nextRowIx); - insertRow(row); - } - // Write collapse field - row.setColapsed(true); - } - - /** - * Create a row record. - * - * @param rowNumber row number - * @return RowRecord created for the passed in row number - * @see org.apache.poi.hssf.record.RowRecord - */ - public static RowRecord createRow(int rowNumber) { - return new RowRecord(rowNumber); - } - - public boolean isRowGroupCollapsed(int row) { - int collapseRow = findEndOfRowOutlineGroup(row) + 1; - - return getRow(collapseRow) != null && getRow(collapseRow).getColapsed(); - } - - public void expandRow(int rowNumber) { - if (rowNumber == -1) - return; - - // If it is already expanded do nothing. - if (!isRowGroupCollapsed(rowNumber)) { - return; - } - - // Find the start of the group. - int startIdx = findStartOfRowOutlineGroup(rowNumber); - RowRecord row = getRow(startIdx); - - // Find the end of the group. - int endIdx = findEndOfRowOutlineGroup(rowNumber); - - // expand: - // collapsed bit must be unset - // hidden bit gets unset _if_ surrounding groups are expanded you can determine - // this by looking at the hidden bit of the enclosing group. You will have - // to look at the start and the end of the current group to determine which - // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't un-collapse contained groups - if (!isRowGroupHiddenByParent(rowNumber)) { - for (int i = startIdx; i <= endIdx; i++) { - RowRecord otherRow = getRow(i); - if (row.getOutlineLevel() == otherRow.getOutlineLevel() || !isRowGroupCollapsed(i)) { - otherRow.setZeroHeight(false); - } - } - } - - // Write collapse field - getRow(endIdx + 1).setColapsed(false); - } - - public boolean isRowGroupHiddenByParent(int row) { - // Look out outline details of end - int endLevel; - boolean endHidden; - int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row); - if (getRow(endOfOutlineGroupIdx + 1) == null) { - endLevel = 0; - endHidden = false; - } else { - endLevel = getRow(endOfOutlineGroupIdx + 1).getOutlineLevel(); - endHidden = getRow(endOfOutlineGroupIdx + 1).getZeroHeight(); - } - - // Look out outline details of start - int startLevel; - boolean startHidden; - int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row ); - if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) { - startLevel = 0; - startHidden = false; - } else { - startLevel = getRow(startOfOutlineGroupIdx - 1).getOutlineLevel(); - startHidden = getRow(startOfOutlineGroupIdx - 1).getZeroHeight(); - } - - if (endLevel > startLevel) { - return endHidden; - } - - return startHidden; - } - - /** - * Returns an iterator for the cell values - */ - public Iterator getCellValueIterator() { - return _valuesAgg.iterator(); - } - - public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) { - IndexRecord result = new IndexRecord(); - result.setFirstRow(_firstrow); - result.setLastRowAdd1(_lastrow + 1); - // Calculate the size of the records from the end of the BOF - // and up to the RowRecordsAggregate... - - // Add the references to the DBCells in the IndexRecord (one for each block) - // Note: The offsets are relative to the Workbook BOF. Assume that this is - // 0 for now..... - - int blockCount = getRowBlockCount(); - // Calculate the size of this IndexRecord - int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount); - - int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords; - - for (int block = 0; block < blockCount; block++) { - // each row-block has a DBCELL record. - // The offset of each DBCELL record needs to be updated in the INDEX record - - // account for row records in this row-block - currentOffset += getRowBlockSize(block); - // account for cell value records after those - currentOffset += _valuesAgg.getRowCellBlockSize( - getStartRowNumberForBlock(block), getEndRowNumberForBlock(block)); - - // currentOffset is now the location of the DBCELL record for this row-block - result.addDbcell(currentOffset); - // Add space required to write the DBCELL record (whose reference was just added). - currentOffset += (8 + (getRowCountForBlock(block) * 2)); - } - return result; - } - public void insertCell(CellValueRecordInterface cvRec) { - _valuesAgg.insertCell(cvRec); - } - public void removeCell(CellValueRecordInterface cvRec) { - if (cvRec instanceof FormulaRecordAggregate) { - ((FormulaRecordAggregate)cvRec).notifyFormulaChanging(); - } - _valuesAgg.removeCell(cvRec); - } - public FormulaRecordAggregate createFormula(int row, int col) { - FormulaRecord fr = new FormulaRecord(); - fr.setRow(row); - fr.setColumn((short) col); - return new FormulaRecordAggregate(fr, null, _sharedValueManager); - } - public void updateFormulasAfterRowShift(FormulaShifter formulaShifter, int currentExternSheetIndex) { - _valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex); - } - public DimensionsRecord createDimensions() { - DimensionsRecord result = new DimensionsRecord(); - result.setFirstRow(_firstrow); - result.setLastRow(_lastrow); - result.setFirstCol((short) _valuesAgg.getFirstCellNum()); - result.setLastCol((short) _valuesAgg.getLastCellNum()); - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java deleted file mode 100644 index f2ccc71e4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java +++ /dev/null @@ -1,286 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.hssf.record.ArrayRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.SharedValueRecordBase; -import org.apache.poi.hssf.record.TableRecord; -import org.apache.poi.ss.formula.ptg.ExpPtg; -import org.apache.poi.hssf.util.CellRangeAddress8Bit; -import org.apache.poi.ss.util.CellReference; - -/** - * Manages various auxiliary records while constructing a - * {@link RowRecordsAggregate}: - *

      - *
    • {@link SharedFormulaRecord}s
    • - *
    • {@link ArrayRecord}s
    • - *
    • {@link TableRecord}s
    • - *
    - * - * @author Josh Micich - * @author Vladimirs Abramovs(Vladimirs.Abramovs at exigenservices.com) - handling of ArrayRecords - */ -public final class SharedValueManager { - - private static final class SharedFormulaGroup { - private final SharedFormulaRecord _sfr; - private final FormulaRecordAggregate[] _frAggs; - private int _numberOfFormulas; - /** - * Coordinates of the first cell having a formula that uses this shared formula. - * This is often but not always the top left cell in the range covered by - * {@link #_sfr} - */ - private final CellReference _firstCell; - - public SharedFormulaGroup(SharedFormulaRecord sfr, CellReference firstCell) { - if (!sfr.isInRange(firstCell.getRow(), firstCell.getCol())) { - throw new IllegalArgumentException("First formula cell " + firstCell.formatAsString() - + " is not shared formula range " + sfr.getRange().toString() + "."); - } - _sfr = sfr; - _firstCell = firstCell; - int width = sfr.getLastColumn() - sfr.getFirstColumn() + 1; - int height = sfr.getLastRow() - sfr.getFirstRow() + 1; - _frAggs = new FormulaRecordAggregate[width * height]; - _numberOfFormulas = 0; - } - - public void add(FormulaRecordAggregate agg) { - if (_numberOfFormulas == 0) { - if (_firstCell.getRow() != agg.getRow() || _firstCell.getCol() != agg.getColumn()) { - throw new IllegalStateException("shared formula coding error: "+_firstCell.getCol()+'/'+_firstCell.getRow()+" != "+agg.getColumn()+'/'+agg.getRow()); - } - } - if (_numberOfFormulas >= _frAggs.length) { - throw new RuntimeException("Too many formula records for shared formula group"); - } - _frAggs[_numberOfFormulas++] = agg; - } - - public void unlinkSharedFormulas() { - for (int i = 0; i < _numberOfFormulas; i++) { - _frAggs[i].unlinkSharedFormula(); - } - } - - public SharedFormulaRecord getSFR() { - return _sfr; - } - - public final String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_sfr.getRange().toString()); - sb.append("]"); - return sb.toString(); - } - } - - /** - * @return a new empty {@link SharedValueManager}. - */ - public static SharedValueManager createEmpty() { - // Note - must create distinct instances because they are assumed to be mutable. - return new SharedValueManager( - new SharedFormulaRecord[0], new CellReference[0], new ArrayRecord[0], new TableRecord[0]); - } - private final List _arrayRecords; - private final TableRecord[] _tableRecords; - private final Map _groupsBySharedFormulaRecord; - /** cached for optimization purposes */ - private Map _groupsCache; - - private SharedValueManager(SharedFormulaRecord[] sharedFormulaRecords, - CellReference[] firstCells, ArrayRecord[] arrayRecords, TableRecord[] tableRecords) { - int nShF = sharedFormulaRecords.length; - if (nShF != firstCells.length) { - throw new IllegalArgumentException("array sizes don't match: " + nShF + "!=" + firstCells.length + "."); - } - _arrayRecords = toList(arrayRecords); - _tableRecords = tableRecords; - Map m = new HashMap(nShF * 3 / 2); - for (int i = 0; i < nShF; i++) { - SharedFormulaRecord sfr = sharedFormulaRecords[i]; - m.put(sfr, new SharedFormulaGroup(sfr, firstCells[i])); - } - _groupsBySharedFormulaRecord = m; - } - - /** - * @return a modifiable list, independent of the supplied array - */ - private static List toList(Z[] zz) { - List result = new ArrayList(zz.length); - for (int i = 0; i < zz.length; i++) { - result.add(zz[i]); - } - return result; - } - - /** - */ - public static SharedValueManager create(SharedFormulaRecord[] sharedFormulaRecords, - CellReference[] firstCells, ArrayRecord[] arrayRecords, TableRecord[] tableRecords) { - if (sharedFormulaRecords.length + firstCells.length + arrayRecords.length + tableRecords.length < 1) { - return createEmpty(); - } - return new SharedValueManager(sharedFormulaRecords, firstCells, arrayRecords, tableRecords); - } - - - /** - * @param firstCell as extracted from the {@link ExpPtg} from the cell's formula. - * @return never null - */ - public SharedFormulaRecord linkSharedFormulaRecord(CellReference firstCell, FormulaRecordAggregate agg) { - SharedFormulaGroup result = findFormulaGroupForCell(firstCell); - if(null == result) { - throw new RuntimeException("Failed to find a matching shared formula record"); - } - result.add(agg); - return result.getSFR(); - } - - private SharedFormulaGroup findFormulaGroupForCell(final CellReference cellRef) { - if(null == _groupsCache) { - _groupsCache = new HashMap(_groupsBySharedFormulaRecord.size()); - for(SharedFormulaGroup group: _groupsBySharedFormulaRecord.values()) { - _groupsCache.put(getKeyForCache(group._firstCell),group); - } - } - SharedFormulaGroup sfg = _groupsCache.get(getKeyForCache(cellRef)); - return sfg; - } - - private Integer getKeyForCache(final CellReference cellRef) { - // The HSSF has a max of 2^16 rows and 2^8 cols - return ((cellRef.getCol()+1)<<16 | cellRef.getRow()); - } - - /** - * Gets the {@link SharedValueRecordBase} record if it should be encoded immediately after the - * formula record contained in the specified {@link FormulaRecordAggregate} agg. Note - the - * shared value record always appears after the first formula record in the group. For arrays - * and tables the first formula is always the in the top left cell. However, since shared - * formula groups can be sparse and/or overlap, the first formula may not actually be in the - * top left cell. - * - * @return the SHRFMLA, TABLE or ARRAY record for the formula cell, if it is the first cell of - * a table or array region. null if the formula cell is not shared/array/table, - * or if the specified formula is not the the first in the group. - */ - public SharedValueRecordBase getRecordForFirstCell(FormulaRecordAggregate agg) { - CellReference firstCell = agg.getFormulaRecord().getFormula().getExpReference(); - // perhaps this could be optimised by consulting the (somewhat unreliable) isShared flag - // and/or distinguishing between tExp and tTbl. - if (firstCell == null) { - // not a shared/array/table formula - return null; - } - - - int row = firstCell.getRow(); - int column = firstCell.getCol(); - if (agg.getRow() != row || agg.getColumn() != column) { - // not the first formula cell in the group - return null; - } - - if(!_groupsBySharedFormulaRecord.isEmpty()) { - SharedFormulaGroup sfg = findFormulaGroupForCell(firstCell); - if(null != sfg) { - return sfg.getSFR(); - } - } - - // Since arrays and tables cannot be sparse (all cells in range participate) - // The first cell will be the top left in the range. So we can match the - // ARRAY/TABLE record directly. - - for (TableRecord tr : _tableRecords) { - if (tr.isFirstCell(row, column)) { - return tr; - } - } - for (ArrayRecord ar : _arrayRecords) { - if (ar.isFirstCell(row, column)) { - return ar; - } - } - return null; - } - - /** - * Converts all {@link FormulaRecord}s handled by sharedFormulaRecord - * to plain unshared formulas - */ - public void unlink(SharedFormulaRecord sharedFormulaRecord) { - SharedFormulaGroup svg = _groupsBySharedFormulaRecord.remove(sharedFormulaRecord); - if (svg == null) { - throw new IllegalStateException("Failed to find formulas for shared formula"); - } - _groupsCache = null; // be sure to reset cached value - svg.unlinkSharedFormulas(); - } - - /** - * Add specified Array Record. - */ - public void addArrayRecord(ArrayRecord ar) { - // could do a check here to make sure none of the ranges overlap - _arrayRecords.add(ar); - } - - /** - * Removes the {@link ArrayRecord} for the cell group containing the specified cell. - * The caller should clear (set blank) all cells in the returned range. - * @return the range of the array formula which was just removed. Never null. - */ - public CellRangeAddress8Bit removeArrayFormula(int rowIndex, int columnIndex) { - for (ArrayRecord ar : _arrayRecords) { - if (ar.isInRange(rowIndex, columnIndex)) { - _arrayRecords.remove(ar); - return ar.getRange(); - } - } - String ref = new CellReference(rowIndex, columnIndex, false, false).formatAsString(); - throw new IllegalArgumentException("Specified cell " + ref - + " is not part of an array formula."); - } - - /** - * @return the shared ArrayRecord identified by (firstRow, firstColumn). never null. - */ - public ArrayRecord getArrayRecord(int firstRow, int firstColumn) { - for(ArrayRecord ar : _arrayRecords) { - if(ar.isFirstCell(firstRow, firstColumn)) { - return ar; - } - } - return null; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java deleted file mode 100644 index 106da8b99..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java +++ /dev/null @@ -1,363 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import java.util.Iterator; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.MulBlankRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; -import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.ptg.Ptg; - -/** - * - * Aggregate value records together. Things are easier to handle that way. - * - * @author andy - * @author Glen Stampoultzis (glens at apache.org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class ValueRecordsAggregate implements Iterable { - private static final int MAX_ROW_INDEX = 0XFFFF; - private static final int INDEX_NOT_SET = -1; - private int firstcell = INDEX_NOT_SET; - private int lastcell = INDEX_NOT_SET; - private CellValueRecordInterface[][] records; - - /** Creates a new instance of ValueRecordsAggregate */ - - public ValueRecordsAggregate() { - this(INDEX_NOT_SET, INDEX_NOT_SET, new CellValueRecordInterface[30][]); // We start with 30 Rows. - } - private ValueRecordsAggregate(int firstCellIx, int lastCellIx, CellValueRecordInterface[][] pRecords) { - firstcell = firstCellIx; - lastcell = lastCellIx; - records = pRecords; - } - - public void insertCell(CellValueRecordInterface cell) { - short column = cell.getColumn(); - int row = cell.getRow(); - if (row >= records.length) { - CellValueRecordInterface[][] oldRecords = records; - int newSize = oldRecords.length * 2; - if (newSize < row + 1) - newSize = row + 1; - records = new CellValueRecordInterface[newSize][]; - System.arraycopy(oldRecords, 0, records, 0, oldRecords.length); - } - CellValueRecordInterface[] rowCells = records[row]; - if (rowCells == null) { - int newSize = column + 1; - if (newSize < 10) - newSize = 10; - rowCells = new CellValueRecordInterface[newSize]; - records[row] = rowCells; - } - if (column >= rowCells.length) { - CellValueRecordInterface[] oldRowCells = rowCells; - int newSize = oldRowCells.length * 2; - if (newSize < column + 1) - newSize = column + 1; - // if(newSize>257) newSize=257; // activate? - rowCells = new CellValueRecordInterface[newSize]; - System.arraycopy(oldRowCells, 0, rowCells, 0, oldRowCells.length); - records[row] = rowCells; - } - rowCells[column] = cell; - - if (column < firstcell || firstcell == INDEX_NOT_SET) { - firstcell = column; - } - if (column > lastcell || lastcell == INDEX_NOT_SET) { - lastcell = column; - } - } - - public void removeCell(CellValueRecordInterface cell) { - if (cell == null) { - throw new IllegalArgumentException("cell must not be null"); - } - int row = cell.getRow(); - if (row >= records.length) { - throw new RuntimeException("cell row is out of range"); - } - CellValueRecordInterface[] rowCells = records[row]; - if (rowCells == null) { - throw new RuntimeException("cell row is already empty"); - } - short column = cell.getColumn(); - if (column >= rowCells.length) { - throw new RuntimeException("cell column is out of range"); - } - rowCells[column] = null; - } - - public void removeAllCellsValuesForRow(int rowIndex) { - if (rowIndex < 0 || rowIndex > MAX_ROW_INDEX) { - throw new IllegalArgumentException("Specified rowIndex " + rowIndex - + " is outside the allowable range (0.." +MAX_ROW_INDEX + ")"); - } - if (rowIndex >= records.length) { - // this can happen when the client code has created a row, - // and then removes/replaces it before adding any cells. (see bug 46312) - return; - } - - records[rowIndex] = null; - } - - - public int getPhysicalNumberOfCells() { - int count = 0; - for (int r = 0; r < records.length; r++) { - CellValueRecordInterface[] rowCells = records[r]; - if (rowCells != null) { - for (int c = 0; c < rowCells.length; c++) { - if (rowCells[c] != null) - count++; - } - } - } - return count; - } - - public int getFirstCellNum() { - return firstcell; - } - - public int getLastCellNum() { - return lastcell; - } - - public void addMultipleBlanks(MulBlankRecord mbr) { - for (int j = 0; j < mbr.getNumColumns(); j++) { - BlankRecord br = new BlankRecord(); - - br.setColumn(( short ) (j + mbr.getFirstColumn())); - br.setRow(mbr.getRow()); - br.setXFIndex(mbr.getXFAt(j)); - insertCell(br); - } - } - - /** - * Processes a single cell value record - * @param sfh used to resolve any shared-formulas/arrays/tables for the current sheet - */ - public void construct(CellValueRecordInterface rec, RecordStream rs, SharedValueManager sfh) { - if (rec instanceof FormulaRecord) { - FormulaRecord formulaRec = (FormulaRecord)rec; - // read optional cached text value - StringRecord cachedText; - Class nextClass = rs.peekNextClass(); - if (nextClass == StringRecord.class) { - cachedText = (StringRecord) rs.getNext(); - } else { - cachedText = null; - } - insertCell(new FormulaRecordAggregate(formulaRec, cachedText, sfh)); - } else { - insertCell(rec); - } - } - - /** Tallies a count of the size of the cell records - * that are attached to the rows in the range specified. - */ - public int getRowCellBlockSize(int startRow, int endRow) { - int result = 0; - for(int rowIx=startRow; rowIx<=endRow && rowIx= records.length) { - return false; - } - CellValueRecordInterface[] rowCells=records[row]; - if(rowCells==null) return false; - for(int col=0;col 1) { - result += (10 + 2*nBlank); - i+=nBlank-1; - } else { - result += cvr.getRecordSize(); - } - } - return result; - } - - public void visitCellsForRow(int rowIndex, RecordVisitor rv) { - - CellValueRecordInterface[] rowCells = records[rowIndex]; - if(rowCells == null) { - throw new IllegalArgumentException("Row [" + rowIndex + "] is empty"); - } - - - for (int i = 0; i < rowCells.length; i++) { - RecordBase cvr = (RecordBase) rowCells[i]; - if(cvr == null) { - continue; - } - int nBlank = countBlanks(rowCells, i); - if (nBlank > 1) { - rv.visitRecord(createMBR(rowCells, i, nBlank)); - i+=nBlank-1; - } else if (cvr instanceof RecordAggregate) { - RecordAggregate agg = (RecordAggregate) cvr; - agg.visitContainedRecords(rv); - } else { - rv.visitRecord((Record) cvr); - } - } - } - - /** - * @return the number of consecutive {@link BlankRecord}s in the specified row - * starting from startIx. - */ - private static int countBlanks(CellValueRecordInterface[] rowCellValues, int startIx) { - int i = startIx; - while(i < rowCellValues.length) { - CellValueRecordInterface cvr = rowCellValues[i]; - if (!(cvr instanceof BlankRecord)) { - break; - } - i++; - } - return i - startIx; - } - - private MulBlankRecord createMBR(CellValueRecordInterface[] cellValues, int startIx, int nBlank) { - - short[] xfs = new short[nBlank]; - for (int i = 0; i < xfs.length; i++) { - xfs[i] = ((BlankRecord)cellValues[startIx + i]).getXFIndex(); - } - int rowIx = cellValues[startIx].getRow(); - return new MulBlankRecord(rowIx, startIx, xfs); - } - - public void updateFormulasAfterRowShift(FormulaShifter shifter, int currentExternSheetIndex) { - for (int i = 0; i < records.length; i++) { - CellValueRecordInterface[] rowCells = records[i]; - if (rowCells == null) { - continue; - } - for (int j = 0; j < rowCells.length; j++) { - CellValueRecordInterface cell = rowCells[j]; - if (cell instanceof FormulaRecordAggregate) { - FormulaRecordAggregate fra = (FormulaRecordAggregate)cell; - Ptg[] ptgs = fra.getFormulaTokens(); // needs clone() inside this getter? - Ptg[] ptgs2 = ((FormulaRecordAggregate)cell).getFormulaRecord().getParsedExpression(); // needs clone() inside this getter? - - if (shifter.adjustFormula(ptgs, currentExternSheetIndex)) { - fra.setParsedExpression(ptgs); - } - } - } - } - } - - /** - * iterator for CellValueRecordInterface - */ - class ValueIterator implements Iterator { - - int curRowIndex = 0, curColIndex = -1; - int nextRowIndex = 0, nextColIndex = -1; - - public ValueIterator() { - getNextPos(); - } - - void getNextPos() { - if (nextRowIndex >= records.length) - return; // no next already - - while (nextRowIndex < records.length) { - ++nextColIndex; - if (records[nextRowIndex] == null || nextColIndex >= records[nextRowIndex].length) { - ++nextRowIndex; - nextColIndex = -1; - continue; - } - - if (records[nextRowIndex][nextColIndex] != null) - return; // next cell found - } - // no next found - } - - public boolean hasNext() { - return nextRowIndex < records.length; - } - - public CellValueRecordInterface next() { - if (!hasNext()) - throw new IndexOutOfBoundsException("iterator has no next"); - - curRowIndex = nextRowIndex; - curColIndex = nextColIndex; - final CellValueRecordInterface ret = records[curRowIndex][curColIndex]; - getNextPos(); - return ret; - } - - public void remove() { - records[curRowIndex][curColIndex] = null; - } - } - - /** value iterator */ - public Iterator iterator() { - return new ValueIterator(); - } - - public Object clone() { - throw new RuntimeException("clone() should not be called. ValueRecordsAggregate should be copied via Sheet.cloneSheet()"); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/WorksheetProtectionBlock.java b/trunk/src/java/org/apache/poi/hssf/record/aggregates/WorksheetProtectionBlock.java deleted file mode 100644 index 275fbf123..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/WorksheetProtectionBlock.java +++ /dev/null @@ -1,246 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.aggregates; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.ObjectProtectRecord; -import org.apache.poi.hssf.record.PasswordRecord; -import org.apache.poi.hssf.record.ProtectRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.hssf.record.ScenarioProtectRecord; -import org.apache.poi.poifs.crypt.CryptoFunctions; - -/** - * Groups the sheet protection records for a worksheet. - *

    - * - * See OOO excelfileformat.pdf sec 4.18.2 'Sheet Protection in a Workbook - * (BIFF5-BIFF8)' - * - * @author Josh Micich - */ -public final class WorksheetProtectionBlock extends RecordAggregate { - // Every one of these component records is optional - // (The whole WorksheetProtectionBlock may not be present) - private ProtectRecord _protectRecord; - private ObjectProtectRecord _objectProtectRecord; - private ScenarioProtectRecord _scenarioProtectRecord; - private PasswordRecord _passwordRecord; - - /** - * Creates an empty WorksheetProtectionBlock - */ - public WorksheetProtectionBlock() { - // all fields empty - } - - /** - * @return true if the specified Record sid is one belonging to - * the 'Page Settings Block'. - */ - public static boolean isComponentRecord(int sid) { - switch (sid) { - case ProtectRecord.sid: - case ObjectProtectRecord.sid: - case ScenarioProtectRecord.sid: - case PasswordRecord.sid: - return true; - } - return false; - } - - private boolean readARecord(RecordStream rs) { - switch (rs.peekNextSid()) { - case ProtectRecord.sid: - checkNotPresent(_protectRecord); - _protectRecord = (ProtectRecord) rs.getNext(); - break; - case ObjectProtectRecord.sid: - checkNotPresent(_objectProtectRecord); - _objectProtectRecord = (ObjectProtectRecord) rs.getNext(); - break; - case ScenarioProtectRecord.sid: - checkNotPresent(_scenarioProtectRecord); - _scenarioProtectRecord = (ScenarioProtectRecord) rs.getNext(); - break; - case PasswordRecord.sid: - checkNotPresent(_passwordRecord); - _passwordRecord = (PasswordRecord) rs.getNext(); - break; - default: - // all other record types are not part of the PageSettingsBlock - return false; - } - return true; - } - - private void checkNotPresent(Record rec) { - if (rec != null) { - throw new RecordFormatException("Duplicate PageSettingsBlock record (sid=0x" - + Integer.toHexString(rec.getSid()) + ")"); - } - } - - public void visitContainedRecords(RecordVisitor rv) { - // Replicates record order from Excel 2007, though this is not critical - - visitIfPresent(_protectRecord, rv); - visitIfPresent(_objectProtectRecord, rv); - visitIfPresent(_scenarioProtectRecord, rv); - visitIfPresent(_passwordRecord, rv); - } - - private static void visitIfPresent(Record r, RecordVisitor rv) { - if (r != null) { - rv.visitRecord(r); - } - } - - public PasswordRecord getPasswordRecord() { - return _passwordRecord; - } - - public ScenarioProtectRecord getHCenter() { - return _scenarioProtectRecord; - } - - /** - * This method reads {@link WorksheetProtectionBlock} records from the supplied RecordStream - * until the first non-WorksheetProtectionBlock record is encountered. As each record is read, - * it is incorporated into this WorksheetProtectionBlock. - *

    - * As per the OOO documentation, the protection block records can be expected to be written - * together (with no intervening records), but earlier versions of POI (prior to Jun 2009) - * didn't do this. Workbooks with sheet protection created by those earlier POI versions - * seemed to be valid (Excel opens them OK). So PO allows continues to support reading of files - * with non continuous worksheet protection blocks. - * - *

    - * Note - when POI writes out this WorksheetProtectionBlock, the records will always be - * written in one consolidated block (in the standard ordering) regardless of how scattered the - * records were when they were originally read. - */ - public void addRecords(RecordStream rs) { - while (true) { - if (!readARecord(rs)) { - break; - } - } - } - - /** - * @return the ProtectRecord. If one is not contained in the sheet, then one - * is created. - */ - private ProtectRecord getProtect() { - if (_protectRecord == null) { - _protectRecord = new ProtectRecord(false); - } - return _protectRecord; - } - - /** - * @return the PasswordRecord. If one is not contained in the sheet, then - * one is created. - */ - private PasswordRecord getPassword() { - if (_passwordRecord == null) { - _passwordRecord = createPassword(); - } - return _passwordRecord; - } - - /** - * protect a spreadsheet with a password (not encrypted, just sets protect - * flags and the password. - * - * @param password to set. Pass null to remove all protection - * @param shouldProtectObjects are protected - * @param shouldProtectScenarios are protected - */ - public void protectSheet(String password, boolean shouldProtectObjects, - boolean shouldProtectScenarios) { - if (password == null) { - _passwordRecord = null; - _protectRecord = null; - _objectProtectRecord = null; - _scenarioProtectRecord = null; - return; - } - - ProtectRecord prec = getProtect(); - PasswordRecord pass = getPassword(); - prec.setProtect(true); - pass.setPassword((short)CryptoFunctions.createXorVerifier1(password)); - if (_objectProtectRecord == null && shouldProtectObjects) { - ObjectProtectRecord rec = createObjectProtect(); - rec.setProtect(true); - _objectProtectRecord = rec; - } - if (_scenarioProtectRecord == null && shouldProtectScenarios) { - ScenarioProtectRecord srec = createScenarioProtect(); - srec.setProtect(true); - _scenarioProtectRecord = srec; - } - } - - public boolean isSheetProtected() { - return _protectRecord != null && _protectRecord.getProtect(); - } - - public boolean isObjectProtected() { - return _objectProtectRecord != null && _objectProtectRecord.getProtect(); - } - - public boolean isScenarioProtected() { - return _scenarioProtectRecord != null && _scenarioProtectRecord.getProtect(); - } - - /** - * creates an ObjectProtect record with protect set to false. - */ - private static ObjectProtectRecord createObjectProtect() { - ObjectProtectRecord retval = new ObjectProtectRecord(); - retval.setProtect(false); - return retval; - } - - /** - * creates a ScenarioProtect record with protect set to false. - */ - private static ScenarioProtectRecord createScenarioProtect() { - ScenarioProtectRecord retval = new ScenarioProtectRecord(); - retval.setProtect(false); - return retval; - } - - /** - * creates a Password record with password set to 0x0000. - */ - private static PasswordRecord createPassword() { - return new PasswordRecord(0x0000); - } - - public int getPasswordHash() { - if (_passwordRecord == null) { - return 0; - } - return _passwordRecord.getPassword(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/aggregates/package.html b/trunk/src/java/org/apache/poi/hssf/record/aggregates/package.html deleted file mode 100644 index ccf7a6097..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/aggregates/package.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - -record aggregates are not real "records" but collections of records that act as a single record. -This is an optimization basically. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.hssf.record -@see org.apache.poi.hssf.eventmodel -@see org.apache.poi.hssf.record.RecordFactory - - diff --git a/trunk/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java b/trunk/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java deleted file mode 100644 index 41f465357..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java +++ /dev/null @@ -1,466 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cf; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Border Formatting Block of the Conditional Formatting Rule Record. - */ -public final class BorderFormatting implements Cloneable { - /** No border */ - public final static short BORDER_NONE = 0x0; - /** Thin border */ - public final static short BORDER_THIN = 0x1; - /** Medium border */ - public final static short BORDER_MEDIUM = 0x2; - /** dash border */ - public final static short BORDER_DASHED = 0x3; - /** dot border */ - public final static short BORDER_HAIR = 0x4; - /** Thick border */ - public final static short BORDER_THICK = 0x5; - /** double-line border */ - public final static short BORDER_DOUBLE = 0x6; - /** hair-line border */ - public final static short BORDER_DOTTED = 0x7; - /** Medium dashed border */ - public final static short BORDER_MEDIUM_DASHED = 0x8; - /** dash-dot border */ - public final static short BORDER_DASH_DOT = 0x9; - /** medium dash-dot border */ - public final static short BORDER_MEDIUM_DASH_DOT = 0xA; - /** dash-dot-dot border */ - public final static short BORDER_DASH_DOT_DOT = 0xB; - /** medium dash-dot-dot border */ - public final static short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; - /** slanted dash-dot border */ - public final static short BORDER_SLANTED_DASH_DOT = 0xD; - - // BORDER FORMATTING BLOCK - // For Border Line Style codes see HSSFCellStyle.BORDER_XXXXXX - private int field_13_border_styles1; - private static final BitField bordLeftLineStyle = BitFieldFactory.getInstance(0x0000000F); - private static final BitField bordRightLineStyle = BitFieldFactory.getInstance(0x000000F0); - private static final BitField bordTopLineStyle = BitFieldFactory.getInstance(0x00000F00); - private static final BitField bordBottomLineStyle= BitFieldFactory.getInstance(0x0000F000); - private static final BitField bordLeftLineColor = BitFieldFactory.getInstance(0x007F0000); - private static final BitField bordRightLineColor = BitFieldFactory.getInstance(0x3F800000); - private static final BitField bordTlBrLineOnOff = BitFieldFactory.getInstance(0x40000000); - private static final BitField bordBlTrtLineOnOff = BitFieldFactory.getInstance(0x80000000); - - private int field_14_border_styles2; - private static final BitField bordTopLineColor = BitFieldFactory.getInstance(0x0000007F); - private static final BitField bordBottomLineColor= BitFieldFactory.getInstance(0x00003f80); - private static final BitField bordDiagLineColor = BitFieldFactory.getInstance(0x001FC000); - private static final BitField bordDiagLineStyle = BitFieldFactory.getInstance(0x01E00000); - - - public BorderFormatting() { - field_13_border_styles1 = 0; - field_14_border_styles2 = 0; - } - - /** Creates new FontFormatting */ - public BorderFormatting(LittleEndianInput in) { - field_13_border_styles1 = in.readInt(); - field_14_border_styles2 = in.readInt(); - } - - public int getDataLength() { - return 8; - } - - /** - * set the type of border to use for the left border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public void setBorderLeft(int border) { - field_13_border_styles1 = bordLeftLineStyle.setValue(field_13_border_styles1, border); - } - - /** - * get the type of border to use for the left border of the cell - * @return border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public int getBorderLeft() { - return bordLeftLineStyle.getValue(field_13_border_styles1); - } - - /** - * set the type of border to use for the right border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public void setBorderRight(int border) { - field_13_border_styles1 = bordRightLineStyle.setValue(field_13_border_styles1, border); - } - - /** - * get the type of border to use for the right border of the cell - * @return border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public int getBorderRight() { - return bordRightLineStyle.getValue(field_13_border_styles1); - } - - /** - * set the type of border to use for the top border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public void setBorderTop(int border) { - field_13_border_styles1 = bordTopLineStyle.setValue(field_13_border_styles1, border); - } - - /** - * get the type of border to use for the top border of the cell - * @return border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public int getBorderTop() { - return bordTopLineStyle.getValue(field_13_border_styles1); - } - - /** - * set the type of border to use for the bottom border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public void setBorderBottom(int border) { - field_13_border_styles1 = bordBottomLineStyle.setValue(field_13_border_styles1, border); - } - - /** - * get the type of border to use for the bottom border of the cell - * @return border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public int getBorderBottom() { - return bordBottomLineStyle.getValue(field_13_border_styles1); - } - - /** - * set the type of border to use for the diagonal border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public void setBorderDiagonal(int border) { - field_14_border_styles2 = bordDiagLineStyle.setValue(field_14_border_styles2, border); - } - - /** - * get the type of border to use for the diagonal border of the cell - * @return border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - */ - public int getBorderDiagonal() { - return bordDiagLineStyle.getValue(field_14_border_styles2); - } - - /** - * set the color to use for the left border - * @param color The index of the color definition - */ - public void setLeftBorderColor(int color) { - field_13_border_styles1 = bordLeftLineColor.setValue(field_13_border_styles1, color); - } - - /** - * get the color to use for the left border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - public int getLeftBorderColor() { - return bordLeftLineColor.getValue(field_13_border_styles1); - } - - /** - * set the color to use for the right border - * @param color The index of the color definition - */ - public void setRightBorderColor(int color) { - field_13_border_styles1 = bordRightLineColor.setValue(field_13_border_styles1, color); - } - - /** - * get the color to use for the right border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - public int getRightBorderColor() { - return bordRightLineColor.getValue(field_13_border_styles1); - } - - /** - * set the color to use for the top border - * @param color The index of the color definition - */ - public void setTopBorderColor(int color) { - field_14_border_styles2 = bordTopLineColor.setValue(field_14_border_styles2, color); - } - - /** - * get the color to use for the top border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - public int getTopBorderColor() { - return bordTopLineColor.getValue(field_14_border_styles2); - } - - /** - * set the color to use for the bottom border - * @param color The index of the color definition - */ - public void setBottomBorderColor(int color) - { - field_14_border_styles2 = bordBottomLineColor.setValue(field_14_border_styles2, color); - } - - /** - * get the color to use for the bottom border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - public int getBottomBorderColor() { - return bordBottomLineColor.getValue(field_14_border_styles2); - } - - /** - * set the color to use for the diagonal borders - * @param color The index of the color definition - */ - public void setDiagonalBorderColor(int color) { - field_14_border_styles2 = bordDiagLineColor.setValue(field_14_border_styles2, color); - } - - /** - * get the color to use for the diagonal border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - public int getDiagonalBorderColor() { - return bordDiagLineColor.getValue(field_14_border_styles2); - } - - /** - * Of/off bottom left to top right line - * - * @param on - if true - on, otherwise off - */ - public void setForwardDiagonalOn(boolean on) { - field_13_border_styles1 = bordBlTrtLineOnOff.setBoolean(field_13_border_styles1, on); - } - - /** - * Of/off top left to bottom right line - * - * @param on - if true - on, otherwise off - */ - public void setBackwardDiagonalOn(boolean on) { - field_13_border_styles1 = bordTlBrLineOnOff.setBoolean(field_13_border_styles1, on); - } - - /** - * @return true if forward diagonal is on - */ - public boolean isForwardDiagonalOn() { - return bordBlTrtLineOnOff.isSet(field_13_border_styles1); - } - - /** - * @return true if backward diagonal is on - */ - public boolean isBackwardDiagonalOn() { - return bordTlBrLineOnOff.isSet(field_13_border_styles1); - } - - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [Border Formatting]\n"); - buffer.append(" .lftln = ").append(Integer.toHexString(getBorderLeft())).append("\n"); - buffer.append(" .rgtln = ").append(Integer.toHexString(getBorderRight())).append("\n"); - buffer.append(" .topln = ").append(Integer.toHexString(getBorderTop())).append("\n"); - buffer.append(" .btmln = ").append(Integer.toHexString(getBorderBottom())).append("\n"); - buffer.append(" .leftborder= ").append(Integer.toHexString(getLeftBorderColor())).append("\n"); - buffer.append(" .rghtborder= ").append(Integer.toHexString(getRightBorderColor())).append("\n"); - buffer.append(" .topborder= ").append(Integer.toHexString(getTopBorderColor())).append("\n"); - buffer.append(" .bottomborder= ").append(Integer.toHexString(getBottomBorderColor())).append("\n"); - buffer.append(" .fwdiag= ").append(isForwardDiagonalOn()).append("\n"); - buffer.append(" .bwdiag= ").append(isBackwardDiagonalOn()).append("\n"); - buffer.append(" [/Border Formatting]\n"); - return buffer.toString(); - } - - @Override - public BorderFormatting clone() { - BorderFormatting rec = new BorderFormatting(); - rec.field_13_border_styles1 = field_13_border_styles1; - rec.field_14_border_styles2 = field_14_border_styles2; - return rec; - } - - public int serialize(int offset, byte [] data) { - LittleEndian.putInt(data, offset+0, field_13_border_styles1); - LittleEndian.putInt(data, offset+4, field_14_border_styles2); - return 8; - } - public void serialize(LittleEndianOutput out) { - out.writeInt(field_13_border_styles1); - out.writeInt(field_14_border_styles2); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cf/ColorGradientFormatting.java b/trunk/src/java/org/apache/poi/hssf/record/cf/ColorGradientFormatting.java deleted file mode 100644 index 0bc179a57..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cf/ColorGradientFormatting.java +++ /dev/null @@ -1,177 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cf; - -import org.apache.poi.hssf.record.common.ExtendedColor; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Color Gradient / Color Scale Conditional Formatting Rule Record. - * (Called Color Gradient in the file format docs, but more commonly - * Color Scale in the UI) - */ -public final class ColorGradientFormatting implements Cloneable { - private static POILogger log = POILogFactory.getLogger(ColorGradientFormatting.class); - - private byte options = 0; - private ColorGradientThreshold[] thresholds; - private ExtendedColor[] colors; - - private static BitField clamp = BitFieldFactory.getInstance(0x01); - private static BitField background = BitFieldFactory.getInstance(0x02); - - public ColorGradientFormatting() { - options = 3; - thresholds = new ColorGradientThreshold[3]; - colors = new ExtendedColor[3]; - } - public ColorGradientFormatting(LittleEndianInput in) { - in.readShort(); // Ignored - in.readByte(); // Reserved - int numI = in.readByte(); - int numG = in.readByte(); - if (numI != numG) { - log.log(POILogger.WARN, "Inconsistent Color Gradient defintion, found " + numI + " vs " + numG + " entries"); - } - options = in.readByte(); - - thresholds = new ColorGradientThreshold[numI]; - for (int i=0; i 100) - log.log(POILogger.WARN, "Inconsistent Minimum Percentage found " + percentMin); - if (percentMax < 0 || percentMax > 100) - log.log(POILogger.WARN, "Inconsistent Minimum Percentage found " + percentMin); - - color = new ExtendedColor(in); - thresholdMin = new DataBarThreshold(in); - thresholdMax = new DataBarThreshold(in); - } - - public boolean isIconOnly() { - return getOptionFlag(iconOnly); - } - public void setIconOnly(boolean only) { - setOptionFlag(only, iconOnly); - } - - public boolean isReversed() { - return getOptionFlag(reversed); - } - public void setReversed(boolean rev) { - setOptionFlag(rev, reversed); - } - - private boolean getOptionFlag(BitField field) { - int value = field.getValue(options); - return value==0 ? false : true; - } - private void setOptionFlag(boolean option, BitField field) { - options = field.setByteBoolean(options, option); - } - - public byte getPercentMin() { - return percentMin; - } - public void setPercentMin(byte percentMin) { - this.percentMin = percentMin; - } - - public byte getPercentMax() { - return percentMax; - } - public void setPercentMax(byte percentMax) { - this.percentMax = percentMax; - } - - public ExtendedColor getColor() { - return color; - } - public void setColor(ExtendedColor color) { - this.color = color; - } - - public DataBarThreshold getThresholdMin() { - return thresholdMin; - } - public void setThresholdMin(DataBarThreshold thresholdMin) { - this.thresholdMin = thresholdMin; - } - - public DataBarThreshold getThresholdMax() { - return thresholdMax; - } - public void setThresholdMax(DataBarThreshold thresholdMax) { - this.thresholdMax = thresholdMax; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [Data Bar Formatting]\n"); - buffer.append(" .icon_only= ").append(isIconOnly()).append("\n"); - buffer.append(" .reversed = ").append(isReversed()).append("\n"); - buffer.append(color); - buffer.append(thresholdMin); - buffer.append(thresholdMax); - buffer.append(" [/Data Bar Formatting]\n"); - return buffer.toString(); - } - - public Object clone() { - DataBarFormatting rec = new DataBarFormatting(); - rec.options = options; - rec.percentMin = percentMin; - rec.percentMax = percentMax; - rec.color = color.clone(); - rec.thresholdMin = thresholdMin.clone(); - rec.thresholdMax = thresholdMax.clone(); - return rec; - } - - public int getDataLength() { - return 6 + color.getDataLength() + - thresholdMin.getDataLength() + - thresholdMax.getDataLength(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(0); - out.writeByte(0); - out.writeByte(options); - out.writeByte(percentMin); - out.writeByte(percentMax); - color.serialize(out); - thresholdMin.serialize(out); - thresholdMax.serialize(out); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cf/DataBarThreshold.java b/trunk/src/java/org/apache/poi/hssf/record/cf/DataBarThreshold.java deleted file mode 100644 index 63c7f6b36..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cf/DataBarThreshold.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cf; - -import org.apache.poi.util.LittleEndianInput; - -/** - * Data Bar specific Threshold / value (CFVO), - * for changes in Conditional Formatting - */ -public final class DataBarThreshold extends Threshold implements Cloneable { - public DataBarThreshold() { - super(); - } - - /** Creates new Data Bar Threshold */ - public DataBarThreshold(LittleEndianInput in) { - super(in); - } - - @Override - public DataBarThreshold clone() { - DataBarThreshold rec = new DataBarThreshold(); - super.copyTo(rec); - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java b/trunk/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java deleted file mode 100644 index 807d67afd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java +++ /dev/null @@ -1,540 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cf; - -import java.util.Locale; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndian; - -/** - * Font Formatting Block of the Conditional Formatting Rule Record. - */ -public final class FontFormatting implements Cloneable { - private final byte[] _rawData = new byte[RAW_DATA_SIZE]; - - private static final int OFFSET_FONT_NAME = 0; - private static final int OFFSET_FONT_HEIGHT = 64; - private static final int OFFSET_FONT_OPTIONS = 68; - private static final int OFFSET_FONT_WEIGHT = 72; - private static final int OFFSET_ESCAPEMENT_TYPE = 74; - private static final int OFFSET_UNDERLINE_TYPE = 76; - private static final int OFFSET_FONT_COLOR_INDEX = 80; - private static final int OFFSET_OPTION_FLAGS = 88; - private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92; - private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96; - private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100; - private static final int OFFSET_NOT_USED1 = 104; - private static final int OFFSET_NOT_USED2 = 108; - private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes 0x7FFFFFFF at this offset - private static final int OFFSET_FONT_FORMATING_END = 116; - private static final int RAW_DATA_SIZE = 118; - - - public final static int FONT_CELL_HEIGHT_PRESERVED = 0xFFFFFFFF; - - // FONT OPTIONS MASKS - private static final BitField posture = BitFieldFactory.getInstance(0x00000002); - private static final BitField outline = BitFieldFactory.getInstance(0x00000008); - private static final BitField shadow = BitFieldFactory.getInstance(0x00000010); - private static final BitField cancellation = BitFieldFactory.getInstance(0x00000080); - - // OPTION FLAGS MASKS - - private static final BitField styleModified = BitFieldFactory.getInstance(0x00000002); - private static final BitField outlineModified = BitFieldFactory.getInstance(0x00000008); - private static final BitField shadowModified = BitFieldFactory.getInstance(0x00000010); - private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080); - - /** Escapement type - None */ - public static final short SS_NONE = 0; - /** Escapement type - Superscript */ - public static final short SS_SUPER = 1; - /** Escapement type - Subscript */ - public static final short SS_SUB = 2; - /** Underline type - None */ - public static final byte U_NONE = 0; - /** Underline type - Single */ - public static final byte U_SINGLE = 1; - /** Underline type - Double */ - public static final byte U_DOUBLE = 2; - /** Underline type - Single Accounting */ - public static final byte U_SINGLE_ACCOUNTING = 0x21; - /** Underline type - Double Accounting */ - public static final byte U_DOUBLE_ACCOUNTING = 0x22; - /** Normal boldness (not bold) */ - private static final short FONT_WEIGHT_NORMAL = 0x190; - - /** - * Bold boldness (bold) - */ - private static final short FONT_WEIGHT_BOLD = 0x2bc; - - public FontFormatting() { - setFontHeight(-1); - setItalic(false); - setFontWieghtModified(false); - setOutline(false); - setShadow(false); - setStrikeout(false); - setEscapementType((short)0); - setUnderlineType((byte)0); - setFontColorIndex((short)-1); - - setFontStyleModified(false); - setFontOutlineModified(false); - setFontShadowModified(false); - setFontCancellationModified(false); - - setEscapementTypeModified(false); - setUnderlineTypeModified(false); - - setShort(OFFSET_FONT_NAME, 0); - setInt(OFFSET_NOT_USED1, 0x00000001); - setInt(OFFSET_NOT_USED2, 0x00000000); - setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes 0x7FFFFFFF at this offset - setShort(OFFSET_FONT_FORMATING_END, 0x0001); - } - - /** Creates new FontFormatting */ - public FontFormatting(RecordInputStream in) { - for (int i = 0; i < _rawData.length; i++) { - _rawData[i] = in.readByte(); - } - } - - private short getShort(int offset) { - return LittleEndian.getShort( _rawData, offset); - } - private void setShort(int offset, int value) { - LittleEndian.putShort( _rawData, offset, (short)value); - } - private int getInt(int offset) { - return LittleEndian.getInt( _rawData, offset); - } - private void setInt(int offset, int value) { - LittleEndian.putInt( _rawData, offset, value); - } - - public byte[] getRawRecord() - { - return _rawData; - } - - public int getDataLength() { - return RAW_DATA_SIZE; - } - - /** - * sets the height of the font in 1/20th point units - * - * - * @param height fontheight (in points/20); or -1 to preserve the cell font height - */ - - public void setFontHeight(int height) - { - setInt(OFFSET_FONT_HEIGHT, height); - } - - /** - * gets the height of the font in 1/20th point units - * - * @return fontheight (in points/20); or -1 if not modified - */ - public int getFontHeight() - { - return getInt(OFFSET_FONT_HEIGHT); - } - - private void setFontOption(boolean option, BitField field) - { - int options = getInt(OFFSET_FONT_OPTIONS); - options = field.setBoolean(options, option); - setInt(OFFSET_FONT_OPTIONS, options); - } - - private boolean getFontOption(BitField field) - { - int options = getInt(OFFSET_FONT_OPTIONS); - return field.isSet(options); - } - - /** - * set the font to be italics or not - * - * @param italic - whether the font is italics or not - * @see #setFontOption(boolean, org.apache.poi.util.BitField) - */ - - public void setItalic(boolean italic) - { - setFontOption(italic, posture); - } - - /** - * get whether the font is to be italics or not - * - * @return italics - whether the font is italics or not - * @see #getFontOption(org.apache.poi.util.BitField) - */ - - public boolean isItalic() - { - return getFontOption(posture); - } - - public void setOutline(boolean on) - { - setFontOption(on, outline); - } - - public boolean isOutlineOn() - { - return getFontOption(outline); - } - - public void setShadow(boolean on) - { - setFontOption(on, shadow); - } - - public boolean isShadowOn() - { - return getFontOption(shadow); - } - - /** - * set the font to be stricken out or not - * - * @param strike - whether the font is stricken out or not - */ - public void setStrikeout(boolean strike) - { - setFontOption(strike, cancellation); - } - - /** - * get whether the font is to be stricken out or not - * - * @return strike - whether the font is stricken out or not - * @see #getFontOption(org.apache.poi.util.BitField) - */ - public boolean isStruckout() - { - return getFontOption(cancellation); - } - - /** - * set the font weight (100-1000dec or 0x64-0x3e8). Default is - * 0x190 for normal and 0x2bc for bold - * - * @param bw - a number between 100-1000 for the fonts "boldness" - */ - - private void setFontWeight(short pbw) - { - short bw = pbw; - if( bw<100) { bw=100; } - if( bw>1000){ bw=1000; } - setShort(OFFSET_FONT_WEIGHT, bw); - } - - /** - * set the font weight to bold (weight=700) or to normal(weight=400) boldness. - * - * @param bold - set font weight to bold if true; to normal otherwise - */ - public void setBold(boolean bold) - { - setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL); - } - - /** - * get the font weight for this font (100-1000dec or 0x64-0x3e8). Default is - * 0x190 for normal and 0x2bc for bold - * - * @return bw - a number between 100-1000 for the fonts "boldness" - */ - - public short getFontWeight() - { - return getShort(OFFSET_FONT_WEIGHT); - } - - /** - * get whether the font weight is set to bold or not - * - * @return bold - whether the font is bold or not - */ - - public boolean isBold() - { - return getFontWeight()==FONT_WEIGHT_BOLD; - } - - /** - * get the type of super or subscript for the font - * - * @return super or subscript option - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB - */ - public short getEscapementType() - { - return getShort(OFFSET_ESCAPEMENT_TYPE); - } - - /** - * set the escapement type for the font - * - * @param escapementType super or subscript option - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB - */ - public void setEscapementType( short escapementType) - { - setShort(OFFSET_ESCAPEMENT_TYPE, escapementType); - } - - /** - * get the type of underlining for the font - * - * @return font underlining type - * - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING - */ - public short getUnderlineType() - { - return getShort(OFFSET_UNDERLINE_TYPE); - } - - /** - * set the type of underlining type for the font - * - * @param underlineType underline option - * - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING - * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING - */ - public void setUnderlineType( short underlineType) - { - setShort(OFFSET_UNDERLINE_TYPE, underlineType); - } - - - public short getFontColorIndex() - { - return (short)getInt(OFFSET_FONT_COLOR_INDEX); - } - - public void setFontColorIndex(short fci ) - { - setInt(OFFSET_FONT_COLOR_INDEX,fci); - } - - private boolean getOptionFlag(BitField field) { - int optionFlags = getInt(OFFSET_OPTION_FLAGS); - int value = field.getValue(optionFlags); - return value==0? true : false ; - } - - private void setOptionFlag(boolean modified, BitField field) - { - int value = modified? 0 : 1; - int optionFlags = getInt(OFFSET_OPTION_FLAGS); - optionFlags = field.setValue(optionFlags, value); - setInt(OFFSET_OPTION_FLAGS, optionFlags); - } - - - public boolean isFontStyleModified() - { - return getOptionFlag(styleModified); - } - - - public void setFontStyleModified(boolean modified) - { - setOptionFlag(modified, styleModified); - } - - public boolean isFontOutlineModified() - { - return getOptionFlag(outlineModified); - } - - public void setFontOutlineModified(boolean modified) - { - setOptionFlag(modified, outlineModified); - } - - public boolean isFontShadowModified() - { - return getOptionFlag(shadowModified); - } - - public void setFontShadowModified(boolean modified) - { - setOptionFlag(modified, shadowModified); - } - public void setFontCancellationModified(boolean modified) - { - setOptionFlag(modified, cancellationModified); - } - - public boolean isFontCancellationModified() - { - return getOptionFlag(cancellationModified); - } - - public void setEscapementTypeModified(boolean modified) - { - int value = modified? 0 : 1; - setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value); - } - public boolean isEscapementTypeModified() - { - int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED); - return escapementModified == 0; - } - - public void setUnderlineTypeModified(boolean modified) - { - int value = modified? 0 : 1; - setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value); - } - - public boolean isUnderlineTypeModified() - { - int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED); - return underlineModified == 0; - } - - public void setFontWieghtModified(boolean modified) - { - int value = modified? 0 : 1; - setInt(OFFSET_FONT_WEIGHT_MODIFIED, value); - } - - public boolean isFontWeightModified() - { - int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED); - return fontStyleModified == 0; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [Font Formatting]\n"); - - buffer.append(" .font height = ").append(getFontHeight()).append(" twips\n"); - - if( isFontStyleModified() ) - { - buffer.append(" .font posture = ").append(isItalic()?"Italic":"Normal").append("\n"); - } - else - { - buffer.append(" .font posture = ]not modified]").append("\n"); - } - - if( isFontOutlineModified() ) - { - buffer.append(" .font outline = ").append(isOutlineOn()).append("\n"); - } - else - { - buffer.append(" .font outline is not modified\n"); - } - - if( isFontShadowModified() ) - { - buffer.append(" .font shadow = ").append(isShadowOn()).append("\n"); - } - else - { - buffer.append(" .font shadow is not modified\n"); - } - - if( isFontCancellationModified() ) - { - buffer.append(" .font strikeout = ").append(isStruckout()).append("\n"); - } - else - { - buffer.append(" .font strikeout is not modified\n"); - } - - if( isFontStyleModified() ) - { - buffer.append(" .font weight = "). - append(getFontWeight()). - append( - getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)" - : getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" - : "0x"+Integer.toHexString(getFontWeight())). - append("\n"); - } - else - { - buffer.append(" .font weight = ]not modified]").append("\n"); - } - - if( isEscapementTypeModified() ) - { - buffer.append(" .escapement type = ").append(getEscapementType()).append("\n"); - } - else - { - buffer.append(" .escapement type is not modified\n"); - } - - if( isUnderlineTypeModified() ) - { - buffer.append(" .underline type = ").append(getUnderlineType()).append("\n"); - } - else - { - buffer.append(" .underline type is not modified\n"); - } - buffer.append(" .color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase(Locale.ROOT)).append("\n"); - - buffer.append(" [/Font Formatting]\n"); - return buffer.toString(); - } - - @Override - public FontFormatting clone() { - FontFormatting other = new FontFormatting(); - System.arraycopy(_rawData, 0, other._rawData, 0, _rawData.length); - return other; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java b/trunk/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java deleted file mode 100644 index 6c984b278..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java +++ /dev/null @@ -1,139 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cf; - -import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Icon / Multi-State Conditional Formatting Rule Record. - */ -public final class IconMultiStateFormatting implements Cloneable { - private static POILogger log = POILogFactory.getLogger(IconMultiStateFormatting.class); - - private IconSet iconSet; - private byte options; - private Threshold[] thresholds; - - private static BitField iconOnly = BitFieldFactory.getInstance(0x01); - private static BitField reversed = BitFieldFactory.getInstance(0x04); - - public IconMultiStateFormatting() { - iconSet = IconSet.GYR_3_TRAFFIC_LIGHTS; - options = 0; - thresholds = new Threshold[iconSet.num]; - } - public IconMultiStateFormatting(LittleEndianInput in) { - in.readShort(); // Ignored - in.readByte(); // Reserved - int num = in.readByte(); - int set = in.readByte(); - iconSet = IconSet.byId(set); - if (iconSet.num != num) { - log.log(POILogger.WARN, "Inconsistent Icon Set defintion, found " + iconSet + " but defined as " + num + " entries"); - } - options = in.readByte(); - - thresholds = new Threshold[iconSet.num]; - for (int i=0; i 0) { - formula = Formula.read(formulaLen, in); - } else { - formula = Formula.create(null); - } - // Value is only there for non-formula, non min/max thresholds - if (formulaLen == 0 && type != RangeType.MIN.id && - type != RangeType.MAX.id) { - value = in.readDouble(); - } - } - - public byte getType() { - return type; - } - public void setType(byte type) { - this.type = type; - - // Ensure the value presence / absence is consistent for the new type - if (type == RangeType.MIN.id || type == RangeType.MAX.id || - type == RangeType.FORMULA.id) { - this.value = null; - } else if (value == null) { - this.value = 0d; - } - } - public void setType(int type) { - this.type = (byte)type; - } - - protected Formula getFormula() { - return formula; - } - public Ptg[] getParsedExpression() { - return formula.getTokens(); - } - public void setParsedExpression(Ptg[] ptgs) { - formula = Formula.create(ptgs); - if (ptgs.length > 0) { - this.value = null; - } - } - - public Double getValue() { - return value; - } - public void setValue(Double value) { - this.value = value; - } - - public int getDataLength() { - int len = 1 + formula.getEncodedSize(); - if (value != null) { - len += 8; - } - return len; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [CF Threshold]\n"); - buffer.append(" .type = ").append(Integer.toHexString(type)).append("\n"); - buffer.append(" .formula = ").append(Arrays.toString(formula.getTokens())).append("\n"); - buffer.append(" .value = ").append(value).append("\n"); - buffer.append(" [/CF Threshold]\n"); - return buffer.toString(); - } - - public void copyTo(Threshold rec) { - rec.type = type; - rec.formula = formula; - rec.value = value; - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(type); - if (formula.getTokens().length == 0) { - out.writeShort(0); - } else { - formula.serialize(out); - } - if (value != null) { - out.writeDouble(value); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AreaFormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AreaFormatRecord.java deleted file mode 100644 index 229743ebd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AreaFormatRecord.java +++ /dev/null @@ -1,263 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The area format record is used to define the colours and patterns for an area.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class AreaFormatRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x100A; - - private static final BitField automatic = BitFieldFactory.getInstance(0x1); - private static final BitField invert = BitFieldFactory.getInstance(0x2); - - private int field_1_foregroundColor; - private int field_2_backgroundColor; - private short field_3_pattern; - private short field_4_formatFlags; - private short field_5_forecolorIndex; - private short field_6_backcolorIndex; - - - public AreaFormatRecord() - { - - } - - public AreaFormatRecord(RecordInputStream in) - { - field_1_foregroundColor = in.readInt(); - field_2_backgroundColor = in.readInt(); - field_3_pattern = in.readShort(); - field_4_formatFlags = in.readShort(); - field_5_forecolorIndex = in.readShort(); - field_6_backcolorIndex = in.readShort(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AREAFORMAT]\n"); - buffer.append(" .foregroundColor = ") - .append("0x").append(HexDump.toHex( getForegroundColor ())) - .append(" (").append( getForegroundColor() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .backgroundColor = ") - .append("0x").append(HexDump.toHex( getBackgroundColor ())) - .append(" (").append( getBackgroundColor() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .pattern = ") - .append("0x").append(HexDump.toHex( getPattern ())) - .append(" (").append( getPattern() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .formatFlags = ") - .append("0x").append(HexDump.toHex( getFormatFlags ())) - .append(" (").append( getFormatFlags() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .automatic = ").append(isAutomatic()).append('\n'); - buffer.append(" .invert = ").append(isInvert()).append('\n'); - buffer.append(" .forecolorIndex = ") - .append("0x").append(HexDump.toHex( getForecolorIndex ())) - .append(" (").append( getForecolorIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .backcolorIndex = ") - .append("0x").append(HexDump.toHex( getBackcolorIndex ())) - .append(" (").append( getBackcolorIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/AREAFORMAT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(field_1_foregroundColor); - out.writeInt(field_2_backgroundColor); - out.writeShort(field_3_pattern); - out.writeShort(field_4_formatFlags); - out.writeShort(field_5_forecolorIndex); - out.writeShort(field_6_backcolorIndex); - } - - protected int getDataSize() { - return 4 + 4 + 2 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public AreaFormatRecord clone() { - AreaFormatRecord rec = new AreaFormatRecord(); - - rec.field_1_foregroundColor = field_1_foregroundColor; - rec.field_2_backgroundColor = field_2_backgroundColor; - rec.field_3_pattern = field_3_pattern; - rec.field_4_formatFlags = field_4_formatFlags; - rec.field_5_forecolorIndex = field_5_forecolorIndex; - rec.field_6_backcolorIndex = field_6_backcolorIndex; - return rec; - } - - - - - /** - * Get the foreground color field for the AreaFormat record. - */ - public int getForegroundColor() - { - return field_1_foregroundColor; - } - - /** - * Set the foreground color field for the AreaFormat record. - */ - public void setForegroundColor(int field_1_foregroundColor) - { - this.field_1_foregroundColor = field_1_foregroundColor; - } - - /** - * Get the background color field for the AreaFormat record. - */ - public int getBackgroundColor() - { - return field_2_backgroundColor; - } - - /** - * Set the background color field for the AreaFormat record. - */ - public void setBackgroundColor(int field_2_backgroundColor) - { - this.field_2_backgroundColor = field_2_backgroundColor; - } - - /** - * Get the pattern field for the AreaFormat record. - */ - public short getPattern() - { - return field_3_pattern; - } - - /** - * Set the pattern field for the AreaFormat record. - */ - public void setPattern(short field_3_pattern) - { - this.field_3_pattern = field_3_pattern; - } - - /** - * Get the format flags field for the AreaFormat record. - */ - public short getFormatFlags() - { - return field_4_formatFlags; - } - - /** - * Set the format flags field for the AreaFormat record. - */ - public void setFormatFlags(short field_4_formatFlags) - { - this.field_4_formatFlags = field_4_formatFlags; - } - - /** - * Get the forecolor index field for the AreaFormat record. - */ - public short getForecolorIndex() - { - return field_5_forecolorIndex; - } - - /** - * Set the forecolor index field for the AreaFormat record. - */ - public void setForecolorIndex(short field_5_forecolorIndex) - { - this.field_5_forecolorIndex = field_5_forecolorIndex; - } - - /** - * Get the backcolor index field for the AreaFormat record. - */ - public short getBackcolorIndex() - { - return field_6_backcolorIndex; - } - - /** - * Set the backcolor index field for the AreaFormat record. - */ - public void setBackcolorIndex(short field_6_backcolorIndex) - { - this.field_6_backcolorIndex = field_6_backcolorIndex; - } - - /** - * Sets the automatic field value. - * automatic formatting - */ - public void setAutomatic(boolean value) - { - field_4_formatFlags = automatic.setShortBoolean(field_4_formatFlags, value); - } - - /** - * automatic formatting - * @return the automatic field value. - */ - public boolean isAutomatic() - { - return automatic.isSet(field_4_formatFlags); - } - - /** - * Sets the invert field value. - * swap foreground and background colours when data is negative - */ - public void setInvert(boolean value) - { - field_4_formatFlags = invert.setShortBoolean(field_4_formatFlags, value); - } - - /** - * swap foreground and background colours when data is negative - * @return the invert field value. - */ - public boolean isInvert() - { - return invert.isSet(field_4_formatFlags); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AreaRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AreaRecord.java deleted file mode 100644 index 0bc901d0c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AreaRecord.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The area record is used to define a area chart.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class AreaRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x101A; - private short field_1_formatFlags; - private static final BitField stacked = BitFieldFactory.getInstance(0x1); - private static final BitField displayAsPercentage = BitFieldFactory.getInstance(0x2); - private static final BitField shadow = BitFieldFactory.getInstance(0x4); - - - public AreaRecord() - { - - } - - public AreaRecord(RecordInputStream in) - { - - field_1_formatFlags = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AREA]\n"); - buffer.append(" .formatFlags = ") - .append("0x").append(HexDump.toHex( getFormatFlags ())) - .append(" (").append( getFormatFlags() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .stacked = ").append(isStacked()).append('\n'); - buffer.append(" .displayAsPercentage = ").append(isDisplayAsPercentage()).append('\n'); - buffer.append(" .shadow = ").append(isShadow()).append('\n'); - - buffer.append("[/AREA]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_formatFlags); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public AreaRecord clone() { - AreaRecord rec = new AreaRecord(); - - rec.field_1_formatFlags = field_1_formatFlags; - return rec; - } - - - - - /** - * Get the format flags field for the Area record. - */ - public short getFormatFlags() - { - return field_1_formatFlags; - } - - /** - * Set the format flags field for the Area record. - */ - public void setFormatFlags(short field_1_formatFlags) - { - this.field_1_formatFlags = field_1_formatFlags; - } - - /** - * Sets the stacked field value. - * series is stacked - */ - public void setStacked(boolean value) - { - field_1_formatFlags = stacked.setShortBoolean(field_1_formatFlags, value); - } - - /** - * series is stacked - * @return the stacked field value. - */ - public boolean isStacked() - { - return stacked.isSet(field_1_formatFlags); - } - - /** - * Sets the display as percentage field value. - * results displayed as percentages - */ - public void setDisplayAsPercentage(boolean value) - { - field_1_formatFlags = displayAsPercentage.setShortBoolean(field_1_formatFlags, value); - } - - /** - * results displayed as percentages - * @return the display as percentage field value. - */ - public boolean isDisplayAsPercentage() - { - return displayAsPercentage.isSet(field_1_formatFlags); - } - - /** - * Sets the shadow field value. - * display a shadow for the chart - */ - public void setShadow(boolean value) - { - field_1_formatFlags = shadow.setShortBoolean(field_1_formatFlags, value); - } - - /** - * display a shadow for the chart - * @return the shadow field value. - */ - public boolean isShadow() - { - return shadow.isSet(field_1_formatFlags); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisLineFormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AxisLineFormatRecord.java deleted file mode 100644 index 92b0b6af2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisLineFormatRecord.java +++ /dev/null @@ -1,115 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The axis line format record defines the axis type details.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class AxisLineFormatRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1021; - private short field_1_axisType; - public final static short AXIS_TYPE_AXIS_LINE = 0; - public final static short AXIS_TYPE_MAJOR_GRID_LINE = 1; - public final static short AXIS_TYPE_MINOR_GRID_LINE = 2; - public final static short AXIS_TYPE_WALLS_OR_FLOOR = 3; - - - public AxisLineFormatRecord() - { - - } - - public AxisLineFormatRecord(RecordInputStream in) - { - field_1_axisType = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AXISLINEFORMAT]\n"); - buffer.append(" .axisType = ") - .append("0x").append(HexDump.toHex( getAxisType ())) - .append(" (").append( getAxisType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/AXISLINEFORMAT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_axisType); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public AxisLineFormatRecord clone() { - AxisLineFormatRecord rec = new AxisLineFormatRecord(); - - rec.field_1_axisType = field_1_axisType; - return rec; - } - - - - - /** - * Get the axis type field for the AxisLineFormat record. - * - * @return One of - * AXIS_TYPE_AXIS_LINE - * AXIS_TYPE_MAJOR_GRID_LINE - * AXIS_TYPE_MINOR_GRID_LINE - * AXIS_TYPE_WALLS_OR_FLOOR - */ - public short getAxisType() - { - return field_1_axisType; - } - - /** - * Set the axis type field for the AxisLineFormat record. - * - * @param field_1_axisType - * One of - * AXIS_TYPE_AXIS_LINE - * AXIS_TYPE_MAJOR_GRID_LINE - * AXIS_TYPE_MINOR_GRID_LINE - * AXIS_TYPE_WALLS_OR_FLOOR - */ - public void setAxisType(short field_1_axisType) - { - this.field_1_axisType = field_1_axisType; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisOptionsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AxisOptionsRecord.java deleted file mode 100644 index e6c4768c8..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisOptionsRecord.java +++ /dev/null @@ -1,454 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The axis options record provides unit information and other various tidbits about the axis.

    - * - * @author Andrew C. Oliver(acoliver at apache.org) - */ -public final class AxisOptionsRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1062; - - private static final BitField defaultMinimum = BitFieldFactory.getInstance(0x01); - private static final BitField defaultMaximum = BitFieldFactory.getInstance(0x02); - private static final BitField defaultMajor = BitFieldFactory.getInstance(0x04); - private static final BitField defaultMinorUnit = BitFieldFactory.getInstance(0x08); - private static final BitField isDate = BitFieldFactory.getInstance(0x10); - private static final BitField defaultBase = BitFieldFactory.getInstance(0x20); - private static final BitField defaultCross = BitFieldFactory.getInstance(0x40); - private static final BitField defaultDateSettings = BitFieldFactory.getInstance(0x80); - - private short field_1_minimumCategory; - private short field_2_maximumCategory; - private short field_3_majorUnitValue; - private short field_4_majorUnit; - private short field_5_minorUnitValue; - private short field_6_minorUnit; - private short field_7_baseUnit; - private short field_8_crossingPoint; - private short field_9_options; - - - public AxisOptionsRecord() - { - - } - - public AxisOptionsRecord(RecordInputStream in) - { - field_1_minimumCategory = in.readShort(); - field_2_maximumCategory = in.readShort(); - field_3_majorUnitValue = in.readShort(); - field_4_majorUnit = in.readShort(); - field_5_minorUnitValue = in.readShort(); - field_6_minorUnit = in.readShort(); - field_7_baseUnit = in.readShort(); - field_8_crossingPoint = in.readShort(); - field_9_options = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AXCEXT]\n"); - buffer.append(" .minimumCategory = ") - .append("0x").append(HexDump.toHex( getMinimumCategory ())) - .append(" (").append( getMinimumCategory() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .maximumCategory = ") - .append("0x").append(HexDump.toHex( getMaximumCategory ())) - .append(" (").append( getMaximumCategory() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .majorUnitValue = ") - .append("0x").append(HexDump.toHex( getMajorUnitValue ())) - .append(" (").append( getMajorUnitValue() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .majorUnit = ") - .append("0x").append(HexDump.toHex( getMajorUnit ())) - .append(" (").append( getMajorUnit() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .minorUnitValue = ") - .append("0x").append(HexDump.toHex( getMinorUnitValue ())) - .append(" (").append( getMinorUnitValue() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .minorUnit = ") - .append("0x").append(HexDump.toHex( getMinorUnit ())) - .append(" (").append( getMinorUnit() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .baseUnit = ") - .append("0x").append(HexDump.toHex( getBaseUnit ())) - .append(" (").append( getBaseUnit() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .crossingPoint = ") - .append("0x").append(HexDump.toHex( getCrossingPoint ())) - .append(" (").append( getCrossingPoint() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options = ") - .append("0x").append(HexDump.toHex( getOptions ())) - .append(" (").append( getOptions() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .defaultMinimum = ").append(isDefaultMinimum()).append('\n'); - buffer.append(" .defaultMaximum = ").append(isDefaultMaximum()).append('\n'); - buffer.append(" .defaultMajor = ").append(isDefaultMajor()).append('\n'); - buffer.append(" .defaultMinorUnit = ").append(isDefaultMinorUnit()).append('\n'); - buffer.append(" .isDate = ").append(isIsDate()).append('\n'); - buffer.append(" .defaultBase = ").append(isDefaultBase()).append('\n'); - buffer.append(" .defaultCross = ").append(isDefaultCross()).append('\n'); - buffer.append(" .defaultDateSettings = ").append(isDefaultDateSettings()).append('\n'); - - buffer.append("[/AXCEXT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_minimumCategory); - out.writeShort(field_2_maximumCategory); - out.writeShort(field_3_majorUnitValue); - out.writeShort(field_4_majorUnit); - out.writeShort(field_5_minorUnitValue); - out.writeShort(field_6_minorUnit); - out.writeShort(field_7_baseUnit); - out.writeShort(field_8_crossingPoint); - out.writeShort(field_9_options); - } - - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public AxisOptionsRecord clone() { - AxisOptionsRecord rec = new AxisOptionsRecord(); - - rec.field_1_minimumCategory = field_1_minimumCategory; - rec.field_2_maximumCategory = field_2_maximumCategory; - rec.field_3_majorUnitValue = field_3_majorUnitValue; - rec.field_4_majorUnit = field_4_majorUnit; - rec.field_5_minorUnitValue = field_5_minorUnitValue; - rec.field_6_minorUnit = field_6_minorUnit; - rec.field_7_baseUnit = field_7_baseUnit; - rec.field_8_crossingPoint = field_8_crossingPoint; - rec.field_9_options = field_9_options; - return rec; - } - - - - - /** - * Get the minimum category field for the AxisOptions record. - */ - public short getMinimumCategory() - { - return field_1_minimumCategory; - } - - /** - * Set the minimum category field for the AxisOptions record. - */ - public void setMinimumCategory(short field_1_minimumCategory) - { - this.field_1_minimumCategory = field_1_minimumCategory; - } - - /** - * Get the maximum category field for the AxisOptions record. - */ - public short getMaximumCategory() - { - return field_2_maximumCategory; - } - - /** - * Set the maximum category field for the AxisOptions record. - */ - public void setMaximumCategory(short field_2_maximumCategory) - { - this.field_2_maximumCategory = field_2_maximumCategory; - } - - /** - * Get the major unit value field for the AxisOptions record. - */ - public short getMajorUnitValue() - { - return field_3_majorUnitValue; - } - - /** - * Set the major unit value field for the AxisOptions record. - */ - public void setMajorUnitValue(short field_3_majorUnitValue) - { - this.field_3_majorUnitValue = field_3_majorUnitValue; - } - - /** - * Get the major unit field for the AxisOptions record. - */ - public short getMajorUnit() - { - return field_4_majorUnit; - } - - /** - * Set the major unit field for the AxisOptions record. - */ - public void setMajorUnit(short field_4_majorUnit) - { - this.field_4_majorUnit = field_4_majorUnit; - } - - /** - * Get the minor unit value field for the AxisOptions record. - */ - public short getMinorUnitValue() - { - return field_5_minorUnitValue; - } - - /** - * Set the minor unit value field for the AxisOptions record. - */ - public void setMinorUnitValue(short field_5_minorUnitValue) - { - this.field_5_minorUnitValue = field_5_minorUnitValue; - } - - /** - * Get the minor unit field for the AxisOptions record. - */ - public short getMinorUnit() - { - return field_6_minorUnit; - } - - /** - * Set the minor unit field for the AxisOptions record. - */ - public void setMinorUnit(short field_6_minorUnit) - { - this.field_6_minorUnit = field_6_minorUnit; - } - - /** - * Get the base unit field for the AxisOptions record. - */ - public short getBaseUnit() - { - return field_7_baseUnit; - } - - /** - * Set the base unit field for the AxisOptions record. - */ - public void setBaseUnit(short field_7_baseUnit) - { - this.field_7_baseUnit = field_7_baseUnit; - } - - /** - * Get the crossing point field for the AxisOptions record. - */ - public short getCrossingPoint() - { - return field_8_crossingPoint; - } - - /** - * Set the crossing point field for the AxisOptions record. - */ - public void setCrossingPoint(short field_8_crossingPoint) - { - this.field_8_crossingPoint = field_8_crossingPoint; - } - - /** - * Get the options field for the AxisOptions record. - */ - public short getOptions() - { - return field_9_options; - } - - /** - * Set the options field for the AxisOptions record. - */ - public void setOptions(short field_9_options) - { - this.field_9_options = field_9_options; - } - - /** - * Sets the default minimum field value. - * use the default minimum category - */ - public void setDefaultMinimum(boolean value) - { - field_9_options = defaultMinimum.setShortBoolean(field_9_options, value); - } - - /** - * use the default minimum category - * @return the default minimum field value. - */ - public boolean isDefaultMinimum() - { - return defaultMinimum.isSet(field_9_options); - } - - /** - * Sets the default maximum field value. - * use the default maximum category - */ - public void setDefaultMaximum(boolean value) - { - field_9_options = defaultMaximum.setShortBoolean(field_9_options, value); - } - - /** - * use the default maximum category - * @return the default maximum field value. - */ - public boolean isDefaultMaximum() - { - return defaultMaximum.isSet(field_9_options); - } - - /** - * Sets the default major field value. - * use the default major unit - */ - public void setDefaultMajor(boolean value) - { - field_9_options = defaultMajor.setShortBoolean(field_9_options, value); - } - - /** - * use the default major unit - * @return the default major field value. - */ - public boolean isDefaultMajor() - { - return defaultMajor.isSet(field_9_options); - } - - /** - * Sets the default minor unit field value. - * use the default minor unit - */ - public void setDefaultMinorUnit(boolean value) - { - field_9_options = defaultMinorUnit.setShortBoolean(field_9_options, value); - } - - /** - * use the default minor unit - * @return the default minor unit field value. - */ - public boolean isDefaultMinorUnit() - { - return defaultMinorUnit.isSet(field_9_options); - } - - /** - * Sets the isDate field value. - * this is a date axis - */ - public void setIsDate(boolean value) - { - field_9_options = isDate.setShortBoolean(field_9_options, value); - } - - /** - * this is a date axis - * @return the isDate field value. - */ - public boolean isIsDate() - { - return isDate.isSet(field_9_options); - } - - /** - * Sets the default base field value. - * use the default base unit - */ - public void setDefaultBase(boolean value) - { - field_9_options = defaultBase.setShortBoolean(field_9_options, value); - } - - /** - * use the default base unit - * @return the default base field value. - */ - public boolean isDefaultBase() - { - return defaultBase.isSet(field_9_options); - } - - /** - * Sets the default cross field value. - * use the default crossing point - */ - public void setDefaultCross(boolean value) - { - field_9_options = defaultCross.setShortBoolean(field_9_options, value); - } - - /** - * use the default crossing point - * @return the default cross field value. - */ - public boolean isDefaultCross() - { - return defaultCross.isSet(field_9_options); - } - - /** - * Sets the default date settings field value. - * use default date setttings for this axis - */ - public void setDefaultDateSettings(boolean value) - { - field_9_options = defaultDateSettings.setShortBoolean(field_9_options, value); - } - - /** - * use default date setttings for this axis - * @return the default date settings field value. - */ - public boolean isDefaultDateSettings() - { - return defaultDateSettings.isSet(field_9_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisParentRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AxisParentRecord.java deleted file mode 100644 index 8cf8fdb09..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisParentRecord.java +++ /dev/null @@ -1,205 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The axis size and location

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class AxisParentRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1041; - private short field_1_axisType; - public final static short AXIS_TYPE_MAIN = 0; - public final static short AXIS_TYPE_SECONDARY = 1; - private int field_2_x; - private int field_3_y; - private int field_4_width; - private int field_5_height; - - - public AxisParentRecord() - { - - } - - public AxisParentRecord(RecordInputStream in) - { - field_1_axisType = in.readShort(); - field_2_x = in.readInt(); - field_3_y = in.readInt(); - field_4_width = in.readInt(); - field_5_height = in.readInt(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AXISPARENT]\n"); - buffer.append(" .axisType = ") - .append("0x").append(HexDump.toHex( getAxisType ())) - .append(" (").append( getAxisType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .x = ") - .append("0x").append(HexDump.toHex( getX ())) - .append(" (").append( getX() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .y = ") - .append("0x").append(HexDump.toHex( getY ())) - .append(" (").append( getY() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .width = ") - .append("0x").append(HexDump.toHex( getWidth ())) - .append(" (").append( getWidth() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .height = ") - .append("0x").append(HexDump.toHex( getHeight ())) - .append(" (").append( getHeight() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/AXISPARENT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_axisType); - out.writeInt(field_2_x); - out.writeInt(field_3_y); - out.writeInt(field_4_width); - out.writeInt(field_5_height); - } - - protected int getDataSize() { - return 2 + 4 + 4 + 4 + 4; - } - - public short getSid() - { - return sid; - } - - @Override - public AxisParentRecord clone() { - AxisParentRecord rec = new AxisParentRecord(); - - rec.field_1_axisType = field_1_axisType; - rec.field_2_x = field_2_x; - rec.field_3_y = field_3_y; - rec.field_4_width = field_4_width; - rec.field_5_height = field_5_height; - return rec; - } - - - - - /** - * Get the axis type field for the AxisParent record. - * - * @return One of - * AXIS_TYPE_MAIN - * AXIS_TYPE_SECONDARY - */ - public short getAxisType() - { - return field_1_axisType; - } - - /** - * Set the axis type field for the AxisParent record. - * - * @param field_1_axisType - * One of - * AXIS_TYPE_MAIN - * AXIS_TYPE_SECONDARY - */ - public void setAxisType(short field_1_axisType) - { - this.field_1_axisType = field_1_axisType; - } - - /** - * Get the x field for the AxisParent record. - */ - public int getX() - { - return field_2_x; - } - - /** - * Set the x field for the AxisParent record. - */ - public void setX(int field_2_x) - { - this.field_2_x = field_2_x; - } - - /** - * Get the y field for the AxisParent record. - */ - public int getY() - { - return field_3_y; - } - - /** - * Set the y field for the AxisParent record. - */ - public void setY(int field_3_y) - { - this.field_3_y = field_3_y; - } - - /** - * Get the width field for the AxisParent record. - */ - public int getWidth() - { - return field_4_width; - } - - /** - * Set the width field for the AxisParent record. - */ - public void setWidth(int field_4_width) - { - this.field_4_width = field_4_width; - } - - /** - * Get the height field for the AxisParent record. - */ - public int getHeight() - { - return field_5_height; - } - - /** - * Set the height field for the AxisParent record. - */ - public void setHeight(int field_5_height) - { - this.field_5_height = field_5_height; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AxisRecord.java deleted file mode 100644 index 42aefb4a8..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisRecord.java +++ /dev/null @@ -1,208 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The axis record defines the type of an axis.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class AxisRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x101d; - private short field_1_axisType; - public final static short AXIS_TYPE_CATEGORY_OR_X_AXIS = 0; - public final static short AXIS_TYPE_VALUE_AXIS = 1; - public final static short AXIS_TYPE_SERIES_AXIS = 2; - private int field_2_reserved1; - private int field_3_reserved2; - private int field_4_reserved3; - private int field_5_reserved4; - - - public AxisRecord() - { - - } - - public AxisRecord(RecordInputStream in) - { - field_1_axisType = in.readShort(); - field_2_reserved1 = in.readInt(); - field_3_reserved2 = in.readInt(); - field_4_reserved3 = in.readInt(); - field_5_reserved4 = in.readInt(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AXIS]\n"); - buffer.append(" .axisType = ") - .append("0x").append(HexDump.toHex( getAxisType ())) - .append(" (").append( getAxisType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .reserved1 = ") - .append("0x").append(HexDump.toHex( getReserved1 ())) - .append(" (").append( getReserved1() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .reserved2 = ") - .append("0x").append(HexDump.toHex( getReserved2 ())) - .append(" (").append( getReserved2() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .reserved3 = ") - .append("0x").append(HexDump.toHex( getReserved3 ())) - .append(" (").append( getReserved3() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .reserved4 = ") - .append("0x").append(HexDump.toHex( getReserved4 ())) - .append(" (").append( getReserved4() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/AXIS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_axisType); - out.writeInt(field_2_reserved1); - out.writeInt(field_3_reserved2); - out.writeInt(field_4_reserved3); - out.writeInt(field_5_reserved4); - } - - protected int getDataSize() { - return 2 + 4 + 4 + 4 + 4; - } - - public short getSid() - { - return sid; - } - - @Override - public AxisRecord clone() { - AxisRecord rec = new AxisRecord(); - - rec.field_1_axisType = field_1_axisType; - rec.field_2_reserved1 = field_2_reserved1; - rec.field_3_reserved2 = field_3_reserved2; - rec.field_4_reserved3 = field_4_reserved3; - rec.field_5_reserved4 = field_5_reserved4; - return rec; - } - - - - - /** - * Get the axis type field for the Axis record. - * - * @return One of - * AXIS_TYPE_CATEGORY_OR_X_AXIS - * AXIS_TYPE_VALUE_AXIS - * AXIS_TYPE_SERIES_AXIS - */ - public short getAxisType() - { - return field_1_axisType; - } - - /** - * Set the axis type field for the Axis record. - * - * @param field_1_axisType - * One of - * AXIS_TYPE_CATEGORY_OR_X_AXIS - * AXIS_TYPE_VALUE_AXIS - * AXIS_TYPE_SERIES_AXIS - */ - public void setAxisType(short field_1_axisType) - { - this.field_1_axisType = field_1_axisType; - } - - /** - * Get the reserved1 field for the Axis record. - */ - public int getReserved1() - { - return field_2_reserved1; - } - - /** - * Set the reserved1 field for the Axis record. - */ - public void setReserved1(int field_2_reserved1) - { - this.field_2_reserved1 = field_2_reserved1; - } - - /** - * Get the reserved2 field for the Axis record. - */ - public int getReserved2() - { - return field_3_reserved2; - } - - /** - * Set the reserved2 field for the Axis record. - */ - public void setReserved2(int field_3_reserved2) - { - this.field_3_reserved2 = field_3_reserved2; - } - - /** - * Get the reserved3 field for the Axis record. - */ - public int getReserved3() - { - return field_4_reserved3; - } - - /** - * Set the reserved3 field for the Axis record. - */ - public void setReserved3(int field_4_reserved3) - { - this.field_4_reserved3 = field_4_reserved3; - } - - /** - * Get the reserved4 field for the Axis record. - */ - public int getReserved4() - { - return field_5_reserved4; - } - - /** - * Set the reserved4 field for the Axis record. - */ - public void setReserved4(int field_5_reserved4) - { - this.field_5_reserved4 = field_5_reserved4; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisUsedRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/AxisUsedRecord.java deleted file mode 100644 index baca15b57..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/AxisUsedRecord.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The number of axes used on a chart.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class AxisUsedRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1046; - private short field_1_numAxis; - - - public AxisUsedRecord() - { - - } - - public AxisUsedRecord(RecordInputStream in) - { - field_1_numAxis = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AXISUSED]\n"); - buffer.append(" .numAxis = ") - .append("0x").append(HexDump.toHex( getNumAxis ())) - .append(" (").append( getNumAxis() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/AXISUSED]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_numAxis); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public AxisUsedRecord clone() { - AxisUsedRecord rec = new AxisUsedRecord(); - - rec.field_1_numAxis = field_1_numAxis; - return rec; - } - - - - - /** - * Get the num axis field for the AxisUsed record. - */ - public short getNumAxis() - { - return field_1_numAxis; - } - - /** - * Set the num axis field for the AxisUsed record. - */ - public void setNumAxis(short field_1_numAxis) - { - this.field_1_numAxis = field_1_numAxis; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/BarRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/BarRecord.java deleted file mode 100644 index 72d418cb7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/BarRecord.java +++ /dev/null @@ -1,230 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The bar record is used to define a bar chart.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class BarRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1017; - - private static final BitField horizontal = BitFieldFactory.getInstance(0x1); - private static final BitField stacked = BitFieldFactory.getInstance(0x2); - private static final BitField displayAsPercentage = BitFieldFactory.getInstance(0x4); - private static final BitField shadow = BitFieldFactory.getInstance(0x8); - - private short field_1_barSpace; - private short field_2_categorySpace; - private short field_3_formatFlags; - - - public BarRecord() - { - - } - - public BarRecord(RecordInputStream in) - { - field_1_barSpace = in.readShort(); - field_2_categorySpace = in.readShort(); - field_3_formatFlags = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BAR]\n"); - buffer.append(" .barSpace = ") - .append("0x").append(HexDump.toHex( getBarSpace ())) - .append(" (").append( getBarSpace() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .categorySpace = ") - .append("0x").append(HexDump.toHex( getCategorySpace ())) - .append(" (").append( getCategorySpace() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .formatFlags = ") - .append("0x").append(HexDump.toHex( getFormatFlags ())) - .append(" (").append( getFormatFlags() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .horizontal = ").append(isHorizontal()).append('\n'); - buffer.append(" .stacked = ").append(isStacked()).append('\n'); - buffer.append(" .displayAsPercentage = ").append(isDisplayAsPercentage()).append('\n'); - buffer.append(" .shadow = ").append(isShadow()).append('\n'); - - buffer.append("[/BAR]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_barSpace); - out.writeShort(field_2_categorySpace); - out.writeShort(field_3_formatFlags); - } - - protected int getDataSize() { - return 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public BarRecord clone() { - BarRecord rec = new BarRecord(); - - rec.field_1_barSpace = field_1_barSpace; - rec.field_2_categorySpace = field_2_categorySpace; - rec.field_3_formatFlags = field_3_formatFlags; - return rec; - } - - - - - /** - * Get the bar space field for the Bar record. - */ - public short getBarSpace() - { - return field_1_barSpace; - } - - /** - * Set the bar space field for the Bar record. - */ - public void setBarSpace(short field_1_barSpace) - { - this.field_1_barSpace = field_1_barSpace; - } - - /** - * Get the category space field for the Bar record. - */ - public short getCategorySpace() - { - return field_2_categorySpace; - } - - /** - * Set the category space field for the Bar record. - */ - public void setCategorySpace(short field_2_categorySpace) - { - this.field_2_categorySpace = field_2_categorySpace; - } - - /** - * Get the format flags field for the Bar record. - */ - public short getFormatFlags() - { - return field_3_formatFlags; - } - - /** - * Set the format flags field for the Bar record. - */ - public void setFormatFlags(short field_3_formatFlags) - { - this.field_3_formatFlags = field_3_formatFlags; - } - - /** - * Sets the horizontal field value. - * true to display horizontal bar charts, false for vertical - */ - public void setHorizontal(boolean value) - { - field_3_formatFlags = horizontal.setShortBoolean(field_3_formatFlags, value); - } - - /** - * true to display horizontal bar charts, false for vertical - * @return the horizontal field value. - */ - public boolean isHorizontal() - { - return horizontal.isSet(field_3_formatFlags); - } - - /** - * Sets the stacked field value. - * stack displayed values - */ - public void setStacked(boolean value) - { - field_3_formatFlags = stacked.setShortBoolean(field_3_formatFlags, value); - } - - /** - * stack displayed values - * @return the stacked field value. - */ - public boolean isStacked() - { - return stacked.isSet(field_3_formatFlags); - } - - /** - * Sets the display as percentage field value. - * display chart values as a percentage - */ - public void setDisplayAsPercentage(boolean value) - { - field_3_formatFlags = displayAsPercentage.setShortBoolean(field_3_formatFlags, value); - } - - /** - * display chart values as a percentage - * @return the display as percentage field value. - */ - public boolean isDisplayAsPercentage() - { - return displayAsPercentage.isSet(field_3_formatFlags); - } - - /** - * Sets the shadow field value. - * display a shadow for the chart - */ - public void setShadow(boolean value) - { - field_3_formatFlags = shadow.setShortBoolean(field_3_formatFlags, value); - } - - /** - * display a shadow for the chart - * @return the shadow field value. - */ - public boolean isShadow() - { - return shadow.isSet(field_3_formatFlags); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/BeginRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/BeginRecord.java deleted file mode 100644 index 88a7efcf2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/BeginRecord.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The begin record defines the start of a block of records for a (grpahing - * data object. This record is matched with a corresponding EndRecord. - * - * @see EndRecord - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class BeginRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x1033; - - public BeginRecord() - { - } - - /** - * @param in unused (since this record has no data) - */ - public BeginRecord(RecordInputStream in) - { - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[BEGIN]\n"); - buffer.append("[/BEGIN]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - } - - protected int getDataSize() { - return 0; - } - - public short getSid() - { - return sid; - } - - @Override - public BeginRecord clone() { - BeginRecord br = new BeginRecord(); - // No data so nothing to copy - return br; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/CatLabRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/CatLabRecord.java deleted file mode 100644 index 92f3b555e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/CatLabRecord.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * CATLAB - Category Labels (0x0856)
    - * - * @author Patrick Cheng - */ -public final class CatLabRecord extends StandardRecord { - public static final short sid = 0x0856; - - private short rt; - private short grbitFrt; - private short wOffset; - private short at; - private short grbit; - private Short unused; - - public CatLabRecord(RecordInputStream in) { - rt = in.readShort(); - grbitFrt = in.readShort(); - wOffset = in.readShort(); - at = in.readShort(); - grbit = in.readShort(); - - // Often, but not always has an unused short at the end - if(in.available() == 0) { - unused = null; - } else { - unused = in.readShort(); - } - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2 + (unused==null? 0:2); - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(rt); - out.writeShort(grbitFrt); - out.writeShort(wOffset); - out.writeShort(at); - out.writeShort(grbit); - if(unused != null) - out.writeShort(unused); - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CATLAB]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt=").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .wOffset =").append(HexDump.shortToHex(wOffset)).append('\n'); - buffer.append(" .at =").append(HexDump.shortToHex(at)).append('\n'); - buffer.append(" .grbit =").append(HexDump.shortToHex(grbit)).append('\n'); - if(unused != null) - buffer.append(" .unused =").append(HexDump.shortToHex(unused)).append('\n'); - - buffer.append("[/CATLAB]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/CategorySeriesAxisRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/CategorySeriesAxisRecord.java deleted file mode 100644 index 6e8216a13..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/CategorySeriesAxisRecord.java +++ /dev/null @@ -1,234 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * This record refers to a category or series axis and is used to specify label/tickmark frequency.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class CategorySeriesAxisRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1020; - - private static final BitField valueAxisCrossing = BitFieldFactory.getInstance(0x1); - private static final BitField crossesFarRight = BitFieldFactory.getInstance(0x2); - private static final BitField reversed = BitFieldFactory.getInstance(0x4); - - private short field_1_crossingPoint; - private short field_2_labelFrequency; - private short field_3_tickMarkFrequency; - private short field_4_options; - - - public CategorySeriesAxisRecord() - { - - } - - public CategorySeriesAxisRecord(RecordInputStream in) - { - field_1_crossingPoint = in.readShort(); - field_2_labelFrequency = in.readShort(); - field_3_tickMarkFrequency = in.readShort(); - field_4_options = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CATSERRANGE]\n"); - buffer.append(" .crossingPoint = ") - .append("0x").append(HexDump.toHex( getCrossingPoint ())) - .append(" (").append( getCrossingPoint() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .labelFrequency = ") - .append("0x").append(HexDump.toHex( getLabelFrequency ())) - .append(" (").append( getLabelFrequency() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .tickMarkFrequency = ") - .append("0x").append(HexDump.toHex( getTickMarkFrequency ())) - .append(" (").append( getTickMarkFrequency() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options = ") - .append("0x").append(HexDump.toHex( getOptions ())) - .append(" (").append( getOptions() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .valueAxisCrossing = ").append(isValueAxisCrossing()).append('\n'); - buffer.append(" .crossesFarRight = ").append(isCrossesFarRight()).append('\n'); - buffer.append(" .reversed = ").append(isReversed()).append('\n'); - - buffer.append("[/CATSERRANGE]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_crossingPoint); - out.writeShort(field_2_labelFrequency); - out.writeShort(field_3_tickMarkFrequency); - out.writeShort(field_4_options); - } - - protected int getDataSize() { - return 2 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public CategorySeriesAxisRecord clone() { - CategorySeriesAxisRecord rec = new CategorySeriesAxisRecord(); - - rec.field_1_crossingPoint = field_1_crossingPoint; - rec.field_2_labelFrequency = field_2_labelFrequency; - rec.field_3_tickMarkFrequency = field_3_tickMarkFrequency; - rec.field_4_options = field_4_options; - return rec; - } - - - - - /** - * Get the crossing point field for the CategorySeriesAxis record. - */ - public short getCrossingPoint() - { - return field_1_crossingPoint; - } - - /** - * Set the crossing point field for the CategorySeriesAxis record. - */ - public void setCrossingPoint(short field_1_crossingPoint) - { - this.field_1_crossingPoint = field_1_crossingPoint; - } - - /** - * Get the label frequency field for the CategorySeriesAxis record. - */ - public short getLabelFrequency() - { - return field_2_labelFrequency; - } - - /** - * Set the label frequency field for the CategorySeriesAxis record. - */ - public void setLabelFrequency(short field_2_labelFrequency) - { - this.field_2_labelFrequency = field_2_labelFrequency; - } - - /** - * Get the tick mark frequency field for the CategorySeriesAxis record. - */ - public short getTickMarkFrequency() - { - return field_3_tickMarkFrequency; - } - - /** - * Set the tick mark frequency field for the CategorySeriesAxis record. - */ - public void setTickMarkFrequency(short field_3_tickMarkFrequency) - { - this.field_3_tickMarkFrequency = field_3_tickMarkFrequency; - } - - /** - * Get the options field for the CategorySeriesAxis record. - */ - public short getOptions() - { - return field_4_options; - } - - /** - * Set the options field for the CategorySeriesAxis record. - */ - public void setOptions(short field_4_options) - { - this.field_4_options = field_4_options; - } - - /** - * Sets the value axis crossing field value. - * set true to indicate axis crosses between categories and false to cross axis midway - */ - public void setValueAxisCrossing(boolean value) - { - field_4_options = valueAxisCrossing.setShortBoolean(field_4_options, value); - } - - /** - * set true to indicate axis crosses between categories and false to cross axis midway - * @return the value axis crossing field value. - */ - public boolean isValueAxisCrossing() - { - return valueAxisCrossing.isSet(field_4_options); - } - - /** - * Sets the crosses far right field value. - * axis crosses at the far right - */ - public void setCrossesFarRight(boolean value) - { - field_4_options = crossesFarRight.setShortBoolean(field_4_options, value); - } - - /** - * axis crosses at the far right - * @return the crosses far right field value. - */ - public boolean isCrossesFarRight() - { - return crossesFarRight.isSet(field_4_options); - } - - /** - * Sets the reversed field value. - * categories are displayed in reverse order - */ - public void setReversed(boolean value) - { - field_4_options = reversed.setShortBoolean(field_4_options, value); - } - - /** - * categories are displayed in reverse order - * @return the reversed field value. - */ - public boolean isReversed() - { - return reversed.isSet(field_4_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartEndBlockRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartEndBlockRecord.java deleted file mode 100644 index 4354b01c5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartEndBlockRecord.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ENDBLOCK - Chart Future Record Type End Block (0x0853)
    - * - * @author Patrick Cheng - */ -public final class ChartEndBlockRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x0853; - - private short rt; - private short grbitFrt; - private short iObjectKind; - private byte[] unused; - - public ChartEndBlockRecord() { - } - - public ChartEndBlockRecord(RecordInputStream in) { - rt = in.readShort(); - grbitFrt = in.readShort(); - iObjectKind = in.readShort(); - - // Often, but not always has 6 unused bytes at the end - if(in.available() == 0) { - unused = new byte[0]; - } else { - unused = new byte[6]; - in.readFully(unused); - } - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + unused.length; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(rt); - out.writeShort(grbitFrt); - out.writeShort(iObjectKind); - // 6 bytes unused - out.write(unused); - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ENDBLOCK]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .iObjectKind=").append(HexDump.shortToHex(iObjectKind)).append('\n'); - buffer.append(" .unused =").append(HexDump.toHex(unused)).append('\n'); - buffer.append("[/ENDBLOCK]\n"); - return buffer.toString(); - } - - @Override - public ChartEndBlockRecord clone() { - ChartEndBlockRecord record = new ChartEndBlockRecord(); - - record.rt = rt ; - record.grbitFrt = grbitFrt ; - record.iObjectKind = iObjectKind ; - record.unused = unused.clone() ; - - return record; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartEndObjectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartEndObjectRecord.java deleted file mode 100644 index 49de2394f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartEndObjectRecord.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ENDOBJECT - Chart Future Record Type End Object (0x0855) - */ -public final class ChartEndObjectRecord extends StandardRecord { - public static final short sid = 0x0855; - - private short rt; - private short grbitFrt; - private short iObjectKind; - private byte[] reserved; - - public ChartEndObjectRecord(RecordInputStream in) { - rt = in.readShort(); - grbitFrt = in.readShort(); - iObjectKind = in.readShort(); - - // The spec says that there should be 6 bytes at the - // end, which must be there and must be zero - // However, sometimes Excel forgets them... - reserved = new byte[6]; - if(in.available() == 0) { - // They've gone missing... - } else { - // Read the reserved bytes - in.readFully(reserved); - } - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 6; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(rt); - out.writeShort(grbitFrt); - out.writeShort(iObjectKind); - // 6 bytes unused - out.write(reserved); - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ENDOBJECT]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .iObjectKind=").append(HexDump.shortToHex(iObjectKind)).append('\n'); - buffer.append(" .reserved =").append(HexDump.toHex(reserved)).append('\n'); - buffer.append("[/ENDOBJECT]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartFRTInfoRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartFRTInfoRecord.java deleted file mode 100644 index 83b135c3c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartFRTInfoRecord.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * CHARTFRTINFO - Chart Future Record Type Info (0x0850) - */ -public final class ChartFRTInfoRecord extends StandardRecord { - public static final short sid = 0x850; - - private short rt; - private short grbitFrt; - private byte verOriginator; - private byte verWriter; - private CFRTID[] rgCFRTID; - - private static final class CFRTID { - public static final int ENCODED_SIZE = 4; - private int rtFirst; - private int rtLast; - - public CFRTID(LittleEndianInput in) { - rtFirst = in.readShort(); - rtLast = in.readShort(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(rtFirst); - out.writeShort(rtLast); - } - } - - public ChartFRTInfoRecord(RecordInputStream in) { - rt = in.readShort(); - grbitFrt = in.readShort(); - verOriginator = in.readByte(); - verWriter = in.readByte(); - int cCFRTID = in.readShort(); - - rgCFRTID = new CFRTID[cCFRTID]; - for (int i = 0; i < cCFRTID; i++) { - rgCFRTID[i] = new CFRTID(in); - } - } - - @Override - protected int getDataSize() { - return 2 + 2 + 1 + 1 + 2 + rgCFRTID.length * CFRTID.ENCODED_SIZE; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - - out.writeShort(rt); - out.writeShort(grbitFrt); - out.writeByte(verOriginator); - out.writeByte(verWriter); - int nCFRTIDs = rgCFRTID.length; - out.writeShort(nCFRTIDs); - - for (int i = 0; i < nCFRTIDs; i++) { - rgCFRTID[i].serialize(out); - } - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CHARTFRTINFO]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .verOriginator=").append(HexDump.byteToHex(verOriginator)).append('\n'); - buffer.append(" .verWriter =").append(HexDump.byteToHex(verOriginator)).append('\n'); - buffer.append(" .nCFRTIDs =").append(HexDump.shortToHex(rgCFRTID.length)).append('\n'); - buffer.append("[/CHARTFRTINFO]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java deleted file mode 100644 index 326e4053d..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java +++ /dev/null @@ -1,128 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Class ChartFormatRecord (0x1014)

    - * - * (As with all chart related records, documentation is lacking. - * See {@link ChartRecord} for more details) - */ -public final class ChartFormatRecord extends StandardRecord { - public static final short sid = 0x1014; - - private static final BitField varyDisplayPattern = BitFieldFactory.getInstance(0x01); - - // ignored? - private int field1_x_position; // lower left - private int field2_y_position; // lower left - private int field3_width; - private int field4_height; - private int field5_grbit; - private int field6_unknown; - - public ChartFormatRecord() { - // fields uninitialised - } - - public ChartFormatRecord(RecordInputStream in) { - field1_x_position = in.readInt(); - field2_y_position = in.readInt(); - field3_width = in.readInt(); - field4_height = in.readInt(); - field5_grbit = in.readUShort(); - field6_unknown = in.readUShort(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[CHARTFORMAT]\n"); - buffer.append(" .xPosition = ").append(getXPosition()).append("\n"); - buffer.append(" .yPosition = ").append(getYPosition()).append("\n"); - buffer.append(" .width = ").append(getWidth()).append("\n"); - buffer.append(" .height = ").append(getHeight()).append("\n"); - buffer.append(" .grBit = ").append(HexDump.intToHex(field5_grbit)).append("\n"); - buffer.append("[/CHARTFORMAT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(getXPosition()); - out.writeInt(getYPosition()); - out.writeInt(getWidth()); - out.writeInt(getHeight()); - out.writeShort(field5_grbit); - out.writeShort(field6_unknown); - } - - protected int getDataSize() { - return 20; // 4 ints and 2 shorts - } - - public short getSid() { - return sid; - } - - public int getXPosition() { - return field1_x_position; - } - - public void setXPosition(int xPosition) { - field1_x_position = xPosition; - } - - public int getYPosition() { - return field2_y_position; - } - - public void setYPosition(int yPosition) { - field2_y_position = yPosition; - } - - public int getWidth() { - return field3_width; - } - - public void setWidth(int width) { - field3_width = width; - } - - public int getHeight() { - return field4_height; - } - - public void setHeight(int height) { - field4_height = height; - } - - public boolean getVaryDisplayPattern() { - return varyDisplayPattern.isSet(field5_grbit); - } - - public void setVaryDisplayPattern(boolean value) { - field5_grbit = varyDisplayPattern.setBoolean(field5_grbit, value); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java deleted file mode 100644 index 8a4deeb8b..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.LittleEndianOutput; - -/** - * CHART (0x1002)

    - * - * The chart record is used to define the location and size of a chart.

    - * - * Chart related records don't seem to be covered in either the - * OOO - * or the - * MS - * documentation. - * - * The book "Microsoft Excel 97 Developer's Kit" ISBN: (1-57231-498-2) seems to have an entire - * chapter (10) devoted to Chart records. One - * blog - * suggests that some documentation for these records is available in "MSDN Library, Feb 1998", - * but no later. - */ -public final class ChartRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1002; - private int field_1_x; - private int field_2_y; - private int field_3_width; - private int field_4_height; - - - public ChartRecord() { - // fields uninitialised - } - - public ChartRecord(RecordInputStream in) { - field_1_x = in.readInt(); - field_2_y = in.readInt(); - field_3_width = in.readInt(); - field_4_height = in.readInt(); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[CHART]\n"); - sb.append(" .x = ").append(getX()).append('\n'); - sb.append(" .y = ").append(getY()).append('\n'); - sb.append(" .width = ").append(getWidth()).append('\n'); - sb.append(" .height= ").append(getHeight()).append('\n'); - sb.append("[/CHART]\n"); - return sb.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(field_1_x); - out.writeInt(field_2_y); - out.writeInt(field_3_width); - out.writeInt(field_4_height); - } - - protected int getDataSize() { - return 4 + 4 + 4 + 4; - } - - public short getSid() - { - return sid; - } - - @Override - public ChartRecord clone() { - ChartRecord rec = new ChartRecord(); - - rec.field_1_x = field_1_x; - rec.field_2_y = field_2_y; - rec.field_3_width = field_3_width; - rec.field_4_height = field_4_height; - return rec; - } - - - - - /** - * Get the x field for the Chart record. - */ - public int getX() { - return field_1_x; - } - - /** - * Set the x field for the Chart record. - */ - public void setX(int x) { - field_1_x = x; - } - - /** - * Get the y field for the Chart record. - */ - public int getY() { - return field_2_y; - } - - /** - * Set the y field for the Chart record. - */ - public void setY(int y) { - field_2_y = y; - } - - /** - * Get the width field for the Chart record. - */ - public int getWidth() { - return field_3_width; - } - - /** - * Set the width field for the Chart record. - */ - public void setWidth(int width) { - field_3_width = width; - } - - /** - * Get the height field for the Chart record. - */ - public int getHeight() { - return field_4_height; - } - - /** - * Set the height field for the Chart record. - */ - public void setHeight(int height) { - field_4_height = height; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartStartBlockRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartStartBlockRecord.java deleted file mode 100644 index 80ef48181..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartStartBlockRecord.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * STARTBLOCK - Chart Future Record Type Start Block (0x0852) - */ -public final class ChartStartBlockRecord extends StandardRecord implements Cloneable { - public static final short sid = 0x0852; - - private short rt; - private short grbitFrt; - private short iObjectKind; - private short iObjectContext; - private short iObjectInstance1; - private short iObjectInstance2; - - public ChartStartBlockRecord() { - } - - public ChartStartBlockRecord(RecordInputStream in) { - rt = in.readShort(); - grbitFrt = in.readShort(); - iObjectKind = in.readShort(); - iObjectContext = in.readShort(); - iObjectInstance1 = in.readShort(); - iObjectInstance2 = in.readShort(); - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2 + 2; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(rt); - out.writeShort(grbitFrt); - out.writeShort(iObjectKind); - out.writeShort(iObjectContext); - out.writeShort(iObjectInstance1); - out.writeShort(iObjectInstance2); - } - - public String toString() { - - StringBuffer buffer = new StringBuffer(); - - buffer.append("[STARTBLOCK]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .iObjectKind =").append(HexDump.shortToHex(iObjectKind)).append('\n'); - buffer.append(" .iObjectContext =").append(HexDump.shortToHex(iObjectContext)).append('\n'); - buffer.append(" .iObjectInstance1=").append(HexDump.shortToHex(iObjectInstance1)).append('\n'); - buffer.append(" .iObjectInstance2=").append(HexDump.shortToHex(iObjectInstance2)).append('\n'); - buffer.append("[/STARTBLOCK]\n"); - return buffer.toString(); - } - - @Override - public ChartStartBlockRecord clone() { - ChartStartBlockRecord record = new ChartStartBlockRecord(); - - record.rt = rt; - record.grbitFrt = grbitFrt; - record.iObjectKind = iObjectKind; - record.iObjectContext = iObjectContext; - record.iObjectInstance1 = iObjectInstance1; - record.iObjectInstance2 = iObjectInstance2; - - return record; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartStartObjectRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartStartObjectRecord.java deleted file mode 100644 index aa2ed5f4f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartStartObjectRecord.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * STARTOBJECT - Chart Future Record Type Start Object (0x0854) - */ -public final class ChartStartObjectRecord extends StandardRecord { - public static final short sid = 0x0854; - - private short rt; - private short grbitFrt; - private short iObjectKind; - private short iObjectContext; - private short iObjectInstance1; - private short iObjectInstance2; - - public ChartStartObjectRecord(RecordInputStream in) { - rt = in.readShort(); - grbitFrt = in.readShort(); - iObjectKind = in.readShort(); - iObjectContext = in.readShort(); - iObjectInstance1 = in.readShort(); - iObjectInstance2 = in.readShort(); - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2 + 2; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public void serialize(LittleEndianOutput out) { - out.writeShort(rt); - out.writeShort(grbitFrt); - out.writeShort(iObjectKind); - out.writeShort(iObjectContext); - out.writeShort(iObjectInstance1); - out.writeShort(iObjectInstance2); - } - - public String toString() { - - StringBuffer buffer = new StringBuffer(); - - buffer.append("[STARTOBJECT]\n"); - buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n'); - buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n'); - buffer.append(" .iObjectKind =").append(HexDump.shortToHex(iObjectKind)).append('\n'); - buffer.append(" .iObjectContext =").append(HexDump.shortToHex(iObjectContext)).append('\n'); - buffer.append(" .iObjectInstance1=").append(HexDump.shortToHex(iObjectInstance1)).append('\n'); - buffer.append(" .iObjectInstance2=").append(HexDump.shortToHex(iObjectInstance2)).append('\n'); - buffer.append("[/STARTOBJECT]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartTitleFormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ChartTitleFormatRecord.java deleted file mode 100644 index f98891db0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ChartTitleFormatRecord.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* - * HSSF Chart Title Format Record Type - */ -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.LittleEndianOutput; - -/** - * CHARTTITLEFORMAT (0x1050)

    - * Describes the formatting runs associated with a chart title. - */ -public class ChartTitleFormatRecord extends StandardRecord { - public static final short sid = 0x1050; - - private CTFormat[] _formats; - - private static final class CTFormat { - public static final int ENCODED_SIZE=4; - private int _offset; - private int _fontIndex; - - public CTFormat(RecordInputStream in) { - _offset = in.readShort(); - _fontIndex = in.readShort(); - } - - public int getOffset(){ - return _offset; - } - public void setOffset(int newOff){ - _offset = newOff; - } - public int getFontIndex() { - return _fontIndex; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_offset); - out.writeShort(_fontIndex); - } - } - - - public ChartTitleFormatRecord(RecordInputStream in) { - int nRecs = in.readUShort(); - _formats = new CTFormat[nRecs]; - - for(int i=0;i - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class FontIndexRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1026; - private short field_1_fontIndex; - - - public FontIndexRecord() - { - - } - - public FontIndexRecord(RecordInputStream in) - { - field_1_fontIndex = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FONTX]\n"); - buffer.append(" .fontIndex = ") - .append("0x").append(HexDump.toHex( getFontIndex ())) - .append(" (").append( getFontIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/FONTX]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_fontIndex); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public FontIndexRecord clone() { - FontIndexRecord rec = new FontIndexRecord(); - - rec.field_1_fontIndex = field_1_fontIndex; - return rec; - } - - - - - /** - * Get the font index field for the FontIndex record. - */ - public short getFontIndex() - { - return field_1_fontIndex; - } - - /** - * Set the font index field for the FontIndex record. - */ - public void setFontIndex(short field_1_fontIndex) - { - this.field_1_fontIndex = field_1_fontIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/FrameRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/FrameRecord.java deleted file mode 100644 index 6515d4a7e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/FrameRecord.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The frame record indicates whether there is a border around the displayed text of a chart. - */ -public final class FrameRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1032; - - private static final BitField autoSize = BitFieldFactory.getInstance(0x1); - private static final BitField autoPosition = BitFieldFactory.getInstance(0x2); - - private short field_1_borderType; - public final static short BORDER_TYPE_REGULAR = 0; - public final static short BORDER_TYPE_SHADOW = 1; - private short field_2_options; - - - public FrameRecord() - { - - } - - public FrameRecord(RecordInputStream in) - { - field_1_borderType = in.readShort(); - field_2_options = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FRAME]\n"); - buffer.append(" .borderType = ") - .append("0x").append(HexDump.toHex( getBorderType ())) - .append(" (").append( getBorderType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options = ") - .append("0x").append(HexDump.toHex( getOptions ())) - .append(" (").append( getOptions() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .autoSize = ").append(isAutoSize()).append('\n'); - buffer.append(" .autoPosition = ").append(isAutoPosition()).append('\n'); - - buffer.append("[/FRAME]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_borderType); - out.writeShort(field_2_options); - } - - protected int getDataSize() { - return 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public FrameRecord clone() { - FrameRecord rec = new FrameRecord(); - - rec.field_1_borderType = field_1_borderType; - rec.field_2_options = field_2_options; - return rec; - } - - - - - /** - * Get the border type field for the Frame record. - * - * @return One of - * BORDER_TYPE_REGULAR - * BORDER_TYPE_SHADOW - */ - public short getBorderType() - { - return field_1_borderType; - } - - /** - * Set the border type field for the Frame record. - * - * @param field_1_borderType - * One of - * BORDER_TYPE_REGULAR - * BORDER_TYPE_SHADOW - */ - public void setBorderType(short field_1_borderType) - { - this.field_1_borderType = field_1_borderType; - } - - /** - * Get the options field for the Frame record. - */ - public short getOptions() - { - return field_2_options; - } - - /** - * Set the options field for the Frame record. - */ - public void setOptions(short field_2_options) - { - this.field_2_options = field_2_options; - } - - /** - * Sets the auto size field value. - * excel calculates the size automatically if true - */ - public void setAutoSize(boolean value) - { - field_2_options = autoSize.setShortBoolean(field_2_options, value); - } - - /** - * excel calculates the size automatically if true - * @return the auto size field value. - */ - public boolean isAutoSize() - { - return autoSize.isSet(field_2_options); - } - - /** - * Sets the auto position field value. - * excel calculates the position automatically - */ - public void setAutoPosition(boolean value) - { - field_2_options = autoPosition.setShortBoolean(field_2_options, value); - } - - /** - * excel calculates the position automatically - * @return the auto position field value. - */ - public boolean isAutoPosition() - { - return autoPosition.isSet(field_2_options); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/LegendRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/LegendRecord.java deleted file mode 100644 index 04e3de1e4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/LegendRecord.java +++ /dev/null @@ -1,401 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Defines a legend for a chart. - */ -public final class LegendRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1015; - - private static final BitField autoPosition = BitFieldFactory.getInstance(0x01); - private static final BitField autoSeries = BitFieldFactory.getInstance(0x02); - private static final BitField autoXPositioning = BitFieldFactory.getInstance(0x04); - private static final BitField autoYPositioning = BitFieldFactory.getInstance(0x08); - private static final BitField vertical = BitFieldFactory.getInstance(0x10); - private static final BitField dataTable = BitFieldFactory.getInstance(0x20); - - private int field_1_xAxisUpperLeft; - private int field_2_yAxisUpperLeft; - private int field_3_xSize; - private int field_4_ySize; - private byte field_5_type; - public final static byte TYPE_BOTTOM = 0; - public final static byte TYPE_CORNER = 1; - public final static byte TYPE_TOP = 2; - public final static byte TYPE_RIGHT = 3; - public final static byte TYPE_LEFT = 4; - public final static byte TYPE_UNDOCKED = 7; - private byte field_6_spacing; - public final static byte SPACING_CLOSE = 0; - public final static byte SPACING_MEDIUM = 1; - public final static byte SPACING_OPEN = 2; - private short field_7_options; - - - public LegendRecord() - { - - } - - public LegendRecord(RecordInputStream in) - { - field_1_xAxisUpperLeft = in.readInt(); - field_2_yAxisUpperLeft = in.readInt(); - field_3_xSize = in.readInt(); - field_4_ySize = in.readInt(); - field_5_type = in.readByte(); - field_6_spacing = in.readByte(); - field_7_options = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[LEGEND]\n"); - buffer.append(" .xAxisUpperLeft = ") - .append("0x").append(HexDump.toHex( getXAxisUpperLeft ())) - .append(" (").append( getXAxisUpperLeft() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .yAxisUpperLeft = ") - .append("0x").append(HexDump.toHex( getYAxisUpperLeft ())) - .append(" (").append( getYAxisUpperLeft() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .xSize = ") - .append("0x").append(HexDump.toHex( getXSize ())) - .append(" (").append( getXSize() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .ySize = ") - .append("0x").append(HexDump.toHex( getYSize ())) - .append(" (").append( getYSize() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .type = ") - .append("0x").append(HexDump.toHex( getType ())) - .append(" (").append( getType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .spacing = ") - .append("0x").append(HexDump.toHex( getSpacing ())) - .append(" (").append( getSpacing() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options = ") - .append("0x").append(HexDump.toHex( getOptions ())) - .append(" (").append( getOptions() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .autoPosition = ").append(isAutoPosition()).append('\n'); - buffer.append(" .autoSeries = ").append(isAutoSeries()).append('\n'); - buffer.append(" .autoXPositioning = ").append(isAutoXPositioning()).append('\n'); - buffer.append(" .autoYPositioning = ").append(isAutoYPositioning()).append('\n'); - buffer.append(" .vertical = ").append(isVertical()).append('\n'); - buffer.append(" .dataTable = ").append(isDataTable()).append('\n'); - - buffer.append("[/LEGEND]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(field_1_xAxisUpperLeft); - out.writeInt(field_2_yAxisUpperLeft); - out.writeInt(field_3_xSize); - out.writeInt(field_4_ySize); - out.writeByte(field_5_type); - out.writeByte(field_6_spacing); - out.writeShort(field_7_options); - } - - protected int getDataSize() { - return 4 + 4 + 4 + 4 + 1 + 1 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public LegendRecord clone() { - LegendRecord rec = new LegendRecord(); - - rec.field_1_xAxisUpperLeft = field_1_xAxisUpperLeft; - rec.field_2_yAxisUpperLeft = field_2_yAxisUpperLeft; - rec.field_3_xSize = field_3_xSize; - rec.field_4_ySize = field_4_ySize; - rec.field_5_type = field_5_type; - rec.field_6_spacing = field_6_spacing; - rec.field_7_options = field_7_options; - return rec; - } - - - - - /** - * Get the x axis upper left field for the Legend record. - */ - public int getXAxisUpperLeft() - { - return field_1_xAxisUpperLeft; - } - - /** - * Set the x axis upper left field for the Legend record. - */ - public void setXAxisUpperLeft(int field_1_xAxisUpperLeft) - { - this.field_1_xAxisUpperLeft = field_1_xAxisUpperLeft; - } - - /** - * Get the y axis upper left field for the Legend record. - */ - public int getYAxisUpperLeft() - { - return field_2_yAxisUpperLeft; - } - - /** - * Set the y axis upper left field for the Legend record. - */ - public void setYAxisUpperLeft(int field_2_yAxisUpperLeft) - { - this.field_2_yAxisUpperLeft = field_2_yAxisUpperLeft; - } - - /** - * Get the x size field for the Legend record. - */ - public int getXSize() - { - return field_3_xSize; - } - - /** - * Set the x size field for the Legend record. - */ - public void setXSize(int field_3_xSize) - { - this.field_3_xSize = field_3_xSize; - } - - /** - * Get the y size field for the Legend record. - */ - public int getYSize() - { - return field_4_ySize; - } - - /** - * Set the y size field for the Legend record. - */ - public void setYSize(int field_4_ySize) - { - this.field_4_ySize = field_4_ySize; - } - - /** - * Get the type field for the Legend record. - * - * @return One of - * TYPE_BOTTOM - * TYPE_CORNER - * TYPE_TOP - * TYPE_RIGHT - * TYPE_LEFT - * TYPE_UNDOCKED - */ - public byte getType() - { - return field_5_type; - } - - /** - * Set the type field for the Legend record. - * - * @param field_5_type - * One of - * TYPE_BOTTOM - * TYPE_CORNER - * TYPE_TOP - * TYPE_RIGHT - * TYPE_LEFT - * TYPE_UNDOCKED - */ - public void setType(byte field_5_type) - { - this.field_5_type = field_5_type; - } - - /** - * Get the spacing field for the Legend record. - * - * @return One of - * SPACING_CLOSE - * SPACING_MEDIUM - * SPACING_OPEN - */ - public byte getSpacing() - { - return field_6_spacing; - } - - /** - * Set the spacing field for the Legend record. - * - * @param field_6_spacing - * One of - * SPACING_CLOSE - * SPACING_MEDIUM - * SPACING_OPEN - */ - public void setSpacing(byte field_6_spacing) - { - this.field_6_spacing = field_6_spacing; - } - - /** - * Get the options field for the Legend record. - */ - public short getOptions() - { - return field_7_options; - } - - /** - * Set the options field for the Legend record. - */ - public void setOptions(short field_7_options) - { - this.field_7_options = field_7_options; - } - - /** - * Sets the auto position field value. - * automatic positioning (1=docked) - */ - public void setAutoPosition(boolean value) - { - field_7_options = autoPosition.setShortBoolean(field_7_options, value); - } - - /** - * automatic positioning (1=docked) - * @return the auto position field value. - */ - public boolean isAutoPosition() - { - return autoPosition.isSet(field_7_options); - } - - /** - * Sets the auto series field value. - * excel 5 only (true) - */ - public void setAutoSeries(boolean value) - { - field_7_options = autoSeries.setShortBoolean(field_7_options, value); - } - - /** - * excel 5 only (true) - * @return the auto series field value. - */ - public boolean isAutoSeries() - { - return autoSeries.isSet(field_7_options); - } - - /** - * Sets the auto x positioning field value. - * position of legend on the x axis is automatic - */ - public void setAutoXPositioning(boolean value) - { - field_7_options = autoXPositioning.setShortBoolean(field_7_options, value); - } - - /** - * position of legend on the x axis is automatic - * @return the auto x positioning field value. - */ - public boolean isAutoXPositioning() - { - return autoXPositioning.isSet(field_7_options); - } - - /** - * Sets the auto y positioning field value. - * position of legend on the y axis is automatic - */ - public void setAutoYPositioning(boolean value) - { - field_7_options = autoYPositioning.setShortBoolean(field_7_options, value); - } - - /** - * position of legend on the y axis is automatic - * @return the auto y positioning field value. - */ - public boolean isAutoYPositioning() - { - return autoYPositioning.isSet(field_7_options); - } - - /** - * Sets the vertical field value. - * vertical or horizontal legend (1 or 0 respectively). Always 0 if not automatic. - */ - public void setVertical(boolean value) - { - field_7_options = vertical.setShortBoolean(field_7_options, value); - } - - /** - * vertical or horizontal legend (1 or 0 respectively). Always 0 if not automatic. - * @return the vertical field value. - */ - public boolean isVertical() - { - return vertical.isSet(field_7_options); - } - - /** - * Sets the data table field value. - * 1 if chart contains data table - */ - public void setDataTable(boolean value) - { - field_7_options = dataTable.setShortBoolean(field_7_options, value); - } - - /** - * 1 if chart contains data table - * @return the data table field value. - */ - public boolean isDataTable() - { - return dataTable.isSet(field_7_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/LineFormatRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/LineFormatRecord.java deleted file mode 100644 index d21a564b2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/LineFormatRecord.java +++ /dev/null @@ -1,306 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Describes a line format record. The line format record controls how a line on a chart appears. - */ -public final class LineFormatRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1007; - - private static final BitField auto = BitFieldFactory.getInstance(0x1); - private static final BitField drawTicks = BitFieldFactory.getInstance(0x4); - private static final BitField unknown = BitFieldFactory.getInstance(0x4); - - private int field_1_lineColor; - private short field_2_linePattern; - public final static short LINE_PATTERN_SOLID = 0; - public final static short LINE_PATTERN_DASH = 1; - public final static short LINE_PATTERN_DOT = 2; - public final static short LINE_PATTERN_DASH_DOT = 3; - public final static short LINE_PATTERN_DASH_DOT_DOT = 4; - public final static short LINE_PATTERN_NONE = 5; - public final static short LINE_PATTERN_DARK_GRAY_PATTERN = 6; - public final static short LINE_PATTERN_MEDIUM_GRAY_PATTERN = 7; - public final static short LINE_PATTERN_LIGHT_GRAY_PATTERN = 8; - private short field_3_weight; - public final static short WEIGHT_HAIRLINE = -1; - public final static short WEIGHT_NARROW = 0; - public final static short WEIGHT_MEDIUM = 1; - public final static short WEIGHT_WIDE = 2; - private short field_4_format; - private short field_5_colourPaletteIndex; - - - public LineFormatRecord() - { - - } - - public LineFormatRecord(RecordInputStream in) - { - field_1_lineColor = in.readInt(); - field_2_linePattern = in.readShort(); - field_3_weight = in.readShort(); - field_4_format = in.readShort(); - field_5_colourPaletteIndex = in.readShort(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[LINEFORMAT]\n"); - buffer.append(" .lineColor = ") - .append("0x").append(HexDump.toHex( getLineColor ())) - .append(" (").append( getLineColor() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .linePattern = ") - .append("0x").append(HexDump.toHex( getLinePattern ())) - .append(" (").append( getLinePattern() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .weight = ") - .append("0x").append(HexDump.toHex( getWeight ())) - .append(" (").append( getWeight() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .format = ") - .append("0x").append(HexDump.toHex( getFormat ())) - .append(" (").append( getFormat() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .auto = ").append(isAuto()).append('\n'); - buffer.append(" .drawTicks = ").append(isDrawTicks()).append('\n'); - buffer.append(" .unknown = ").append(isUnknown()).append('\n'); - buffer.append(" .colourPaletteIndex = ") - .append("0x").append(HexDump.toHex( getColourPaletteIndex ())) - .append(" (").append( getColourPaletteIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/LINEFORMAT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(field_1_lineColor); - out.writeShort(field_2_linePattern); - out.writeShort(field_3_weight); - out.writeShort(field_4_format); - out.writeShort(field_5_colourPaletteIndex); - } - - protected int getDataSize() { - return 4 + 2 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public LineFormatRecord clone() { - LineFormatRecord rec = new LineFormatRecord(); - - rec.field_1_lineColor = field_1_lineColor; - rec.field_2_linePattern = field_2_linePattern; - rec.field_3_weight = field_3_weight; - rec.field_4_format = field_4_format; - rec.field_5_colourPaletteIndex = field_5_colourPaletteIndex; - return rec; - } - - - - - /** - * Get the line color field for the LineFormat record. - */ - public int getLineColor() - { - return field_1_lineColor; - } - - /** - * Set the line color field for the LineFormat record. - */ - public void setLineColor(int field_1_lineColor) - { - this.field_1_lineColor = field_1_lineColor; - } - - /** - * Get the line pattern field for the LineFormat record. - * - * @return One of - * LINE_PATTERN_SOLID - * LINE_PATTERN_DASH - * LINE_PATTERN_DOT - * LINE_PATTERN_DASH_DOT - * LINE_PATTERN_DASH_DOT_DOT - * LINE_PATTERN_NONE - * LINE_PATTERN_DARK_GRAY_PATTERN - * LINE_PATTERN_MEDIUM_GRAY_PATTERN - * LINE_PATTERN_LIGHT_GRAY_PATTERN - */ - public short getLinePattern() - { - return field_2_linePattern; - } - - /** - * Set the line pattern field for the LineFormat record. - * - * @param field_2_linePattern - * One of - * LINE_PATTERN_SOLID - * LINE_PATTERN_DASH - * LINE_PATTERN_DOT - * LINE_PATTERN_DASH_DOT - * LINE_PATTERN_DASH_DOT_DOT - * LINE_PATTERN_NONE - * LINE_PATTERN_DARK_GRAY_PATTERN - * LINE_PATTERN_MEDIUM_GRAY_PATTERN - * LINE_PATTERN_LIGHT_GRAY_PATTERN - */ - public void setLinePattern(short field_2_linePattern) - { - this.field_2_linePattern = field_2_linePattern; - } - - /** - * Get the weight field for the LineFormat record. - * - * @return One of - * WEIGHT_HAIRLINE - * WEIGHT_NARROW - * WEIGHT_MEDIUM - * WEIGHT_WIDE - */ - public short getWeight() - { - return field_3_weight; - } - - /** - * Set the weight field for the LineFormat record. - * - * @param field_3_weight - * One of - * WEIGHT_HAIRLINE - * WEIGHT_NARROW - * WEIGHT_MEDIUM - * WEIGHT_WIDE - */ - public void setWeight(short field_3_weight) - { - this.field_3_weight = field_3_weight; - } - - /** - * Get the format field for the LineFormat record. - */ - public short getFormat() - { - return field_4_format; - } - - /** - * Set the format field for the LineFormat record. - */ - public void setFormat(short field_4_format) - { - this.field_4_format = field_4_format; - } - - /** - * Get the colour palette index field for the LineFormat record. - */ - public short getColourPaletteIndex() - { - return field_5_colourPaletteIndex; - } - - /** - * Set the colour palette index field for the LineFormat record. - */ - public void setColourPaletteIndex(short field_5_colourPaletteIndex) - { - this.field_5_colourPaletteIndex = field_5_colourPaletteIndex; - } - - /** - * Sets the auto field value. - * automatic format - */ - public void setAuto(boolean value) - { - field_4_format = auto.setShortBoolean(field_4_format, value); - } - - /** - * automatic format - * @return the auto field value. - */ - public boolean isAuto() - { - return auto.isSet(field_4_format); - } - - /** - * Sets the draw ticks field value. - * draw tick marks - */ - public void setDrawTicks(boolean value) - { - field_4_format = drawTicks.setShortBoolean(field_4_format, value); - } - - /** - * draw tick marks - * @return the draw ticks field value. - */ - public boolean isDrawTicks() - { - return drawTicks.isSet(field_4_format); - } - - /** - * Sets the unknown field value. - * book marks this as reserved = 0 but it seems to do something - */ - public void setUnknown(boolean value) - { - field_4_format = unknown.setShortBoolean(field_4_format, value); - } - - /** - * book marks this as reserved = 0 but it seems to do something - * @return the unknown field value. - */ - public boolean isUnknown() - { - return unknown.isSet(field_4_format); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/LinkedDataRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/LinkedDataRecord.java deleted file mode 100644 index 772327077..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/LinkedDataRecord.java +++ /dev/null @@ -1,243 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Describes a linked data record. This record refers to the series data or text. - */ -public final class LinkedDataRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1051; - - private static final BitField customNumberFormat= BitFieldFactory.getInstance(0x1); - - private byte field_1_linkType; - public final static byte LINK_TYPE_TITLE_OR_TEXT = 0; - public final static byte LINK_TYPE_VALUES = 1; - public final static byte LINK_TYPE_CATEGORIES = 2; - public final static byte LINK_TYPE_SECONDARY_CATEGORIES = 3; - private byte field_2_referenceType; - public final static byte REFERENCE_TYPE_DEFAULT_CATEGORIES = 0; - public final static byte REFERENCE_TYPE_DIRECT = 1; - public final static byte REFERENCE_TYPE_WORKSHEET = 2; - public final static byte REFERENCE_TYPE_NOT_USED = 3; - public final static byte REFERENCE_TYPE_ERROR_REPORTED = 4; - private short field_3_options; - private short field_4_indexNumberFmtRecord; - private Formula field_5_formulaOfLink; - - - public LinkedDataRecord() - { - - } - - public LinkedDataRecord(RecordInputStream in) - { - field_1_linkType = in.readByte(); - field_2_referenceType = in.readByte(); - field_3_options = in.readShort(); - field_4_indexNumberFmtRecord = in.readShort(); - int encodedTokenLen = in.readUShort(); - field_5_formulaOfLink = Formula.read(encodedTokenLen, in); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[AI]\n"); - buffer.append(" .linkType = ").append(HexDump.byteToHex(getLinkType())).append('\n'); - buffer.append(" .referenceType = ").append(HexDump.byteToHex(getReferenceType())).append('\n'); - buffer.append(" .options = ").append(HexDump.shortToHex(getOptions())).append('\n'); - buffer.append(" .customNumberFormat = ").append(isCustomNumberFormat()).append('\n'); - buffer.append(" .indexNumberFmtRecord = ").append(HexDump.shortToHex(getIndexNumberFmtRecord())).append('\n'); - buffer.append(" .formulaOfLink = ").append('\n'); - Ptg[] ptgs = field_5_formulaOfLink.getTokens(); - for (int i = 0; i < ptgs.length; i++) { - Ptg ptg = ptgs[i]; - buffer.append(ptg.toString()).append(ptg.getRVAType()).append('\n'); - } - - buffer.append("[/AI]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(field_1_linkType); - out.writeByte(field_2_referenceType); - out.writeShort(field_3_options); - out.writeShort(field_4_indexNumberFmtRecord); - field_5_formulaOfLink.serialize(out); - } - - protected int getDataSize() { - return 1 + 1 + 2 + 2 + field_5_formulaOfLink.getEncodedSize(); - } - - public short getSid() { - return sid; - } - - @Override - public LinkedDataRecord clone() { - LinkedDataRecord rec = new LinkedDataRecord(); - - rec.field_1_linkType = field_1_linkType; - rec.field_2_referenceType = field_2_referenceType; - rec.field_3_options = field_3_options; - rec.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord; - rec.field_5_formulaOfLink = field_5_formulaOfLink.copy(); - return rec; - } - - - - - /** - * Get the link type field for the LinkedData record. - * - * @return One of - * {@link #LINK_TYPE_TITLE_OR_TEXT}, - * {@link #LINK_TYPE_VALUES}, - * {@link #LINK_TYPE_CATEGORIES}, or - * {@link #LINK_TYPE_SECONDARY_CATEGORIES} - */ - public byte getLinkType() - { - return field_1_linkType; - } - - /** - * Set the link type field for the LinkedData record. - * - * @param field_1_linkType - * One of - * {@link #LINK_TYPE_TITLE_OR_TEXT}, - * {@link #LINK_TYPE_VALUES}, - * {@link #LINK_TYPE_CATEGORIES}, or - * {@link #LINK_TYPE_SECONDARY_CATEGORIES} - */ - public void setLinkType(byte field_1_linkType) - { - this.field_1_linkType = field_1_linkType; - } - - /** - * Get the reference type field for the LinkedData record. - * - * @return One of - * {@link #REFERENCE_TYPE_DEFAULT_CATEGORIES} - * {@link #REFERENCE_TYPE_DIRECT} - * {@link #REFERENCE_TYPE_WORKSHEET} - * {@link #REFERENCE_TYPE_NOT_USED} - * {@link #REFERENCE_TYPE_ERROR_REPORTED} - */ - public byte getReferenceType() - { - return field_2_referenceType; - } - - /** - * Set the reference type field for the LinkedData record. - * - * @param field_2_referenceType - * One of - * {@link #REFERENCE_TYPE_DEFAULT_CATEGORIES} - * {@link #REFERENCE_TYPE_DIRECT} - * {@link #REFERENCE_TYPE_WORKSHEET} - * {@link #REFERENCE_TYPE_NOT_USED} - * {@link #REFERENCE_TYPE_ERROR_REPORTED} - */ - public void setReferenceType(byte field_2_referenceType) - { - this.field_2_referenceType = field_2_referenceType; - } - - /** - * Get the options field for the LinkedData record. - */ - public short getOptions() - { - return field_3_options; - } - - /** - * Set the options field for the LinkedData record. - */ - public void setOptions(short field_3_options) - { - this.field_3_options = field_3_options; - } - - /** - * Get the index number fmt record field for the LinkedData record. - */ - public short getIndexNumberFmtRecord() - { - return field_4_indexNumberFmtRecord; - } - - /** - * Set the index number fmt record field for the LinkedData record. - */ - public void setIndexNumberFmtRecord(short field_4_indexNumberFmtRecord) - { - this.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord; - } - - /** - * Get the formula of link field for the LinkedData record. - */ - public Ptg[] getFormulaOfLink() { - return field_5_formulaOfLink.getTokens(); - } - - /** - * Set the formula of link field for the LinkedData record. - */ - public void setFormulaOfLink(Ptg[] ptgs) - { - this.field_5_formulaOfLink = Formula.create(ptgs); - } - - /** - * Sets the custom number format field value. - * true if this object has a custom number format - */ - public void setCustomNumberFormat(boolean value) - { - field_3_options = customNumberFormat.setShortBoolean(field_3_options, value); - } - - /** - * true if this object has a custom number format - * @return the custom number format field value. - */ - public boolean isCustomNumberFormat() - { - return customNumberFormat.isSet(field_3_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/NumberFormatIndexRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/NumberFormatIndexRecord.java deleted file mode 100644 index 99f609f54..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/NumberFormatIndexRecord.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The number format index record indexes format table. This applies to an axis. - */ -public final class NumberFormatIndexRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x104E; - private short field_1_formatIndex; - - - public NumberFormatIndexRecord() - { - - } - - public NumberFormatIndexRecord(RecordInputStream in) - { - field_1_formatIndex = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[IFMT]\n"); - buffer.append(" .formatIndex = ") - .append("0x").append(HexDump.toHex( getFormatIndex ())) - .append(" (").append( getFormatIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/IFMT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_formatIndex); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - @Override - public NumberFormatIndexRecord clone() { - NumberFormatIndexRecord rec = new NumberFormatIndexRecord(); - - rec.field_1_formatIndex = field_1_formatIndex; - return rec; - } - - - - - /** - * Get the format index field for the NumberFormatIndex record. - */ - public short getFormatIndex() - { - return field_1_formatIndex; - } - - /** - * Set the format index field for the NumberFormatIndex record. - */ - public void setFormatIndex(short field_1_formatIndex) - { - this.field_1_formatIndex = field_1_formatIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ObjectLinkRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ObjectLinkRecord.java deleted file mode 100644 index d21387c95..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ObjectLinkRecord.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Links text to an object on the chart or identifies it as the title. - */ -public final class ObjectLinkRecord extends StandardRecord implements Cloneable { - public final static short sid = 0x1027; - private short field_1_anchorId; - public final static short ANCHOR_ID_CHART_TITLE = 1; - public final static short ANCHOR_ID_Y_AXIS = 2; - public final static short ANCHOR_ID_X_AXIS = 3; - public final static short ANCHOR_ID_SERIES_OR_POINT = 4; - public final static short ANCHOR_ID_Z_AXIS = 7; - private short field_2_link1; - private short field_3_link2; - - - public ObjectLinkRecord() - { - - } - - public ObjectLinkRecord(RecordInputStream in) - { - field_1_anchorId = in.readShort(); - field_2_link1 = in.readShort(); - field_3_link2 = in.readShort(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[OBJECTLINK]\n"); - buffer.append(" .anchorId = ") - .append("0x").append(HexDump.toHex( getAnchorId ())) - .append(" (").append( getAnchorId() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .link1 = ") - .append("0x").append(HexDump.toHex( getLink1 ())) - .append(" (").append( getLink1() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .link2 = ") - .append("0x").append(HexDump.toHex( getLink2 ())) - .append(" (").append( getLink2() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/OBJECTLINK]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_anchorId); - out.writeShort(field_2_link1); - out.writeShort(field_3_link2); - } - - protected int getDataSize() { - return 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - @Override - public ObjectLinkRecord clone() { - ObjectLinkRecord rec = new ObjectLinkRecord(); - - rec.field_1_anchorId = field_1_anchorId; - rec.field_2_link1 = field_2_link1; - rec.field_3_link2 = field_3_link2; - return rec; - } - - - - - /** - * Get the anchor id field for the ObjectLink record. - * - * @return One of - * ANCHOR_ID_CHART_TITLE - * ANCHOR_ID_Y_AXIS - * ANCHOR_ID_X_AXIS - * ANCHOR_ID_SERIES_OR_POINT - * ANCHOR_ID_Z_AXIS - */ - public short getAnchorId() - { - return field_1_anchorId; - } - - /** - * Set the anchor id field for the ObjectLink record. - * - * @param field_1_anchorId - * One of - * ANCHOR_ID_CHART_TITLE - * ANCHOR_ID_Y_AXIS - * ANCHOR_ID_X_AXIS - * ANCHOR_ID_SERIES_OR_POINT - * ANCHOR_ID_Z_AXIS - */ - public void setAnchorId(short field_1_anchorId) - { - this.field_1_anchorId = field_1_anchorId; - } - - /** - * Get the link 1 field for the ObjectLink record. - */ - public short getLink1() - { - return field_2_link1; - } - - /** - * Set the link 1 field for the ObjectLink record. - */ - public void setLink1(short field_2_link1) - { - this.field_2_link1 = field_2_link1; - } - - /** - * Get the link 2 field for the ObjectLink record. - */ - public short getLink2() - { - return field_3_link2; - } - - /** - * Set the link 2 field for the ObjectLink record. - */ - public void setLink2(short field_3_link2) - { - this.field_3_link2 = field_3_link2; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/PlotAreaRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/PlotAreaRecord.java deleted file mode 100644 index 775354cd1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/PlotAreaRecord.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.LittleEndianOutput; - -/** - * preceeds and identifies a frame as belonging to the plot area. - */ -public final class PlotAreaRecord extends StandardRecord { - public final static short sid = 0x1035; - - - public PlotAreaRecord() - { - - } - - /** - * @param in unused (since this record has no data) - */ - public PlotAreaRecord(RecordInputStream in) - { - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PLOTAREA]\n"); - - buffer.append("[/PLOTAREA]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - } - - protected int getDataSize() { - return 0; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - PlotAreaRecord rec = new PlotAreaRecord(); - - return rec; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/PlotGrowthRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/PlotGrowthRecord.java deleted file mode 100644 index aa326aca0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/PlotGrowthRecord.java +++ /dev/null @@ -1,120 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The plot growth record specifies the scaling factors used when a font is scaled. - */ -public final class PlotGrowthRecord extends StandardRecord { - public final static short sid = 0x1064; - private int field_1_horizontalScale; - private int field_2_verticalScale; - - - public PlotGrowthRecord() - { - - } - - public PlotGrowthRecord(RecordInputStream in) - { - field_1_horizontalScale = in.readInt(); - field_2_verticalScale = in.readInt(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[PLOTGROWTH]\n"); - buffer.append(" .horizontalScale = ") - .append("0x").append(HexDump.toHex( getHorizontalScale ())) - .append(" (").append( getHorizontalScale() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .verticalScale = ") - .append("0x").append(HexDump.toHex( getVerticalScale ())) - .append(" (").append( getVerticalScale() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/PLOTGROWTH]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(field_1_horizontalScale); - out.writeInt(field_2_verticalScale); - } - - protected int getDataSize() { - return 4 + 4; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - PlotGrowthRecord rec = new PlotGrowthRecord(); - - rec.field_1_horizontalScale = field_1_horizontalScale; - rec.field_2_verticalScale = field_2_verticalScale; - return rec; - } - - - - - /** - * Get the horizontalScale field for the PlotGrowth record. - */ - public int getHorizontalScale() - { - return field_1_horizontalScale; - } - - /** - * Set the horizontalScale field for the PlotGrowth record. - */ - public void setHorizontalScale(int field_1_horizontalScale) - { - this.field_1_horizontalScale = field_1_horizontalScale; - } - - /** - * Get the verticalScale field for the PlotGrowth record. - */ - public int getVerticalScale() - { - return field_2_verticalScale; - } - - /** - * Set the verticalScale field for the PlotGrowth record. - */ - public void setVerticalScale(int field_2_verticalScale) - { - this.field_2_verticalScale = field_2_verticalScale; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesChartGroupIndexRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesChartGroupIndexRecord.java deleted file mode 100644 index 18f428ab5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesChartGroupIndexRecord.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The series chart group index record stores the index to the CHARTFORMAT record (0 based). - */ -public final class SeriesChartGroupIndexRecord extends StandardRecord { - public final static short sid = 0x1045; - private short field_1_chartGroupIndex; - - - public SeriesChartGroupIndexRecord() - { - - } - - public SeriesChartGroupIndexRecord(RecordInputStream in) - { - field_1_chartGroupIndex = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SERTOCRT]\n"); - buffer.append(" .chartGroupIndex = ") - .append("0x").append(HexDump.toHex( getChartGroupIndex ())) - .append(" (").append( getChartGroupIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/SERTOCRT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_chartGroupIndex); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - SeriesChartGroupIndexRecord rec = new SeriesChartGroupIndexRecord(); - - rec.field_1_chartGroupIndex = field_1_chartGroupIndex; - return rec; - } - - - - - /** - * Get the chart group index field for the SeriesChartGroupIndex record. - */ - public short getChartGroupIndex() - { - return field_1_chartGroupIndex; - } - - /** - * Set the chart group index field for the SeriesChartGroupIndex record. - */ - public void setChartGroupIndex(short field_1_chartGroupIndex) - { - this.field_1_chartGroupIndex = field_1_chartGroupIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesIndexRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesIndexRecord.java deleted file mode 100644 index 08efc7fa9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesIndexRecord.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * links a series to its position in the series list. - */ -public final class SeriesIndexRecord extends StandardRecord { - public final static short sid = 0x1065; - private short field_1_index; - - - public SeriesIndexRecord() - { - - } - - public SeriesIndexRecord(RecordInputStream in) - { - field_1_index = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SINDEX]\n"); - buffer.append(" .index = ") - .append("0x").append(HexDump.toHex( getIndex ())) - .append(" (").append( getIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/SINDEX]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_index); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - SeriesIndexRecord rec = new SeriesIndexRecord(); - - rec.field_1_index = field_1_index; - return rec; - } - - - - - /** - * Get the index field for the SeriesIndex record. - */ - public short getIndex() - { - return field_1_index; - } - - /** - * Set the index field for the SeriesIndex record. - */ - public void setIndex(short field_1_index) - { - this.field_1_index = field_1_index; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesLabelsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesLabelsRecord.java deleted file mode 100644 index 9fff21af9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesLabelsRecord.java +++ /dev/null @@ -1,220 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The series label record defines the type of label associated with the data format record.

    - * - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class SeriesLabelsRecord extends StandardRecord { - public final static short sid = 0x100c; - - private static final BitField showActual = BitFieldFactory.getInstance(0x01); - private static final BitField showPercent = BitFieldFactory.getInstance(0x02); - private static final BitField labelAsPercentage = BitFieldFactory.getInstance(0x04); - private static final BitField smoothedLine = BitFieldFactory.getInstance(0x08); - private static final BitField showLabel = BitFieldFactory.getInstance(0x10); - private static final BitField showBubbleSizes = BitFieldFactory.getInstance(0x20); - - private short field_1_formatFlags; - - public SeriesLabelsRecord() - { - - } - - public SeriesLabelsRecord(RecordInputStream in) - { - field_1_formatFlags = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[ATTACHEDLABEL]\n"); - buffer.append(" .formatFlags = ") - .append("0x").append(HexDump.toHex( getFormatFlags ())) - .append(" (").append( getFormatFlags() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .showActual = ").append(isShowActual()).append('\n'); - buffer.append(" .showPercent = ").append(isShowPercent()).append('\n'); - buffer.append(" .labelAsPercentage = ").append(isLabelAsPercentage()).append('\n'); - buffer.append(" .smoothedLine = ").append(isSmoothedLine()).append('\n'); - buffer.append(" .showLabel = ").append(isShowLabel()).append('\n'); - buffer.append(" .showBubbleSizes = ").append(isShowBubbleSizes()).append('\n'); - - buffer.append("[/ATTACHEDLABEL]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_formatFlags); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - SeriesLabelsRecord rec = new SeriesLabelsRecord(); - - rec.field_1_formatFlags = field_1_formatFlags; - return rec; - } - - - - - /** - * Get the format flags field for the SeriesLabels record. - */ - public short getFormatFlags() - { - return field_1_formatFlags; - } - - /** - * Set the format flags field for the SeriesLabels record. - */ - public void setFormatFlags(short field_1_formatFlags) - { - this.field_1_formatFlags = field_1_formatFlags; - } - - /** - * Sets the show actual field value. - * show actual value of the data point - */ - public void setShowActual(boolean value) - { - field_1_formatFlags = showActual.setShortBoolean(field_1_formatFlags, value); - } - - /** - * show actual value of the data point - * @return the show actual field value. - */ - public boolean isShowActual() - { - return showActual.isSet(field_1_formatFlags); - } - - /** - * Sets the show percent field value. - * show value as percentage of total (pie charts only) - */ - public void setShowPercent(boolean value) - { - field_1_formatFlags = showPercent.setShortBoolean(field_1_formatFlags, value); - } - - /** - * show value as percentage of total (pie charts only) - * @return the show percent field value. - */ - public boolean isShowPercent() - { - return showPercent.isSet(field_1_formatFlags); - } - - /** - * Sets the label as percentage field value. - * show category label/value as percentage (pie charts only) - */ - public void setLabelAsPercentage(boolean value) - { - field_1_formatFlags = labelAsPercentage.setShortBoolean(field_1_formatFlags, value); - } - - /** - * show category label/value as percentage (pie charts only) - * @return the label as percentage field value. - */ - public boolean isLabelAsPercentage() - { - return labelAsPercentage.isSet(field_1_formatFlags); - } - - /** - * Sets the smoothed line field value. - * show smooth line - */ - public void setSmoothedLine(boolean value) - { - field_1_formatFlags = smoothedLine.setShortBoolean(field_1_formatFlags, value); - } - - /** - * show smooth line - * @return the smoothed line field value. - */ - public boolean isSmoothedLine() - { - return smoothedLine.isSet(field_1_formatFlags); - } - - /** - * Sets the show label field value. - * display category label - */ - public void setShowLabel(boolean value) - { - field_1_formatFlags = showLabel.setShortBoolean(field_1_formatFlags, value); - } - - /** - * display category label - * @return the show label field value. - */ - public boolean isShowLabel() - { - return showLabel.isSet(field_1_formatFlags); - } - - /** - * Sets the show bubble sizes field value. - * ?? - */ - public void setShowBubbleSizes(boolean value) - { - field_1_formatFlags = showBubbleSizes.setShortBoolean(field_1_formatFlags, value); - } - - /** - * ?? - * @return the show bubble sizes field value. - */ - public boolean isShowBubbleSizes() - { - return showBubbleSizes.isSet(field_1_formatFlags); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java deleted file mode 100644 index 5d101f903..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import java.util.Arrays; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.LittleEndianOutput; - -/** - * SERIESLIST (0x1016)

    - * - * The series list record defines the series displayed as an overlay to the main chart record.

    - * - * (As with all chart related records, documentation is lacking. - * See {@link ChartRecord} for more details) - */ -public final class SeriesListRecord extends StandardRecord { - public final static short sid = 0x1016; - private short[] field_1_seriesNumbers; - - public SeriesListRecord(short[] seriesNumbers) { - field_1_seriesNumbers = (seriesNumbers == null) ? null : seriesNumbers.clone(); - } - - public SeriesListRecord(RecordInputStream in) { - int nItems = in.readUShort(); - short[] ss = new short[nItems]; - for (int i = 0; i < nItems; i++) { - ss[i] = in.readShort(); - - } - field_1_seriesNumbers = ss; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SERIESLIST]\n"); - buffer.append(" .seriesNumbers= ").append(" (").append( Arrays.toString(getSeriesNumbers()) ).append(" )"); - buffer.append("\n"); - - buffer.append("[/SERIESLIST]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - - int nItems = field_1_seriesNumbers.length; - out.writeShort(nItems); - for (int i = 0; i < nItems; i++) { - out.writeShort(field_1_seriesNumbers[i]); - } - } - - protected int getDataSize() { - return field_1_seriesNumbers.length * 2 + 2; - } - - public short getSid() { - return sid; - } - - public Object clone() { - return new SeriesListRecord(field_1_seriesNumbers); - } - - /** - * Get the series numbers field for the SeriesList record. - */ - public short[] getSeriesNumbers() { - return field_1_seriesNumbers; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesRecord.java deleted file mode 100644 index 0ff5564ac..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesRecord.java +++ /dev/null @@ -1,267 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The series record describes the overall data for a series. - */ -public final class SeriesRecord extends StandardRecord { - public final static short sid = 0x1003; - private short field_1_categoryDataType; - public final static short CATEGORY_DATA_TYPE_DATES = 0; - public final static short CATEGORY_DATA_TYPE_NUMERIC = 1; - public final static short CATEGORY_DATA_TYPE_SEQUENCE = 2; - public final static short CATEGORY_DATA_TYPE_TEXT = 3; - private short field_2_valuesDataType; - public final static short VALUES_DATA_TYPE_DATES = 0; - public final static short VALUES_DATA_TYPE_NUMERIC = 1; - public final static short VALUES_DATA_TYPE_SEQUENCE = 2; - public final static short VALUES_DATA_TYPE_TEXT = 3; - private short field_3_numCategories; - private short field_4_numValues; - private short field_5_bubbleSeriesType; - public final static short BUBBLE_SERIES_TYPE_DATES = 0; - public final static short BUBBLE_SERIES_TYPE_NUMERIC = 1; - public final static short BUBBLE_SERIES_TYPE_SEQUENCE = 2; - public final static short BUBBLE_SERIES_TYPE_TEXT = 3; - private short field_6_numBubbleValues; - - - public SeriesRecord() - { - - } - - public SeriesRecord(RecordInputStream in) - { - field_1_categoryDataType = in.readShort(); - field_2_valuesDataType = in.readShort(); - field_3_numCategories = in.readShort(); - field_4_numValues = in.readShort(); - field_5_bubbleSeriesType = in.readShort(); - field_6_numBubbleValues = in.readShort(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SERIES]\n"); - buffer.append(" .categoryDataType = ") - .append("0x").append(HexDump.toHex( getCategoryDataType ())) - .append(" (").append( getCategoryDataType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .valuesDataType = ") - .append("0x").append(HexDump.toHex( getValuesDataType ())) - .append(" (").append( getValuesDataType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .numCategories = ") - .append("0x").append(HexDump.toHex( getNumCategories ())) - .append(" (").append( getNumCategories() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .numValues = ") - .append("0x").append(HexDump.toHex( getNumValues ())) - .append(" (").append( getNumValues() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .bubbleSeriesType = ") - .append("0x").append(HexDump.toHex( getBubbleSeriesType ())) - .append(" (").append( getBubbleSeriesType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .numBubbleValues = ") - .append("0x").append(HexDump.toHex( getNumBubbleValues ())) - .append(" (").append( getNumBubbleValues() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/SERIES]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_categoryDataType); - out.writeShort(field_2_valuesDataType); - out.writeShort(field_3_numCategories); - out.writeShort(field_4_numValues); - out.writeShort(field_5_bubbleSeriesType); - out.writeShort(field_6_numBubbleValues); - } - - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - SeriesRecord rec = new SeriesRecord(); - - rec.field_1_categoryDataType = field_1_categoryDataType; - rec.field_2_valuesDataType = field_2_valuesDataType; - rec.field_3_numCategories = field_3_numCategories; - rec.field_4_numValues = field_4_numValues; - rec.field_5_bubbleSeriesType = field_5_bubbleSeriesType; - rec.field_6_numBubbleValues = field_6_numBubbleValues; - return rec; - } - - - - - /** - * Get the category data type field for the Series record. - * - * @return One of - * CATEGORY_DATA_TYPE_DATES - * CATEGORY_DATA_TYPE_NUMERIC - * CATEGORY_DATA_TYPE_SEQUENCE - * CATEGORY_DATA_TYPE_TEXT - */ - public short getCategoryDataType() - { - return field_1_categoryDataType; - } - - /** - * Set the category data type field for the Series record. - * - * @param field_1_categoryDataType - * One of - * CATEGORY_DATA_TYPE_DATES - * CATEGORY_DATA_TYPE_NUMERIC - * CATEGORY_DATA_TYPE_SEQUENCE - * CATEGORY_DATA_TYPE_TEXT - */ - public void setCategoryDataType(short field_1_categoryDataType) - { - this.field_1_categoryDataType = field_1_categoryDataType; - } - - /** - * Get the values data type field for the Series record. - * - * @return One of - * VALUES_DATA_TYPE_DATES - * VALUES_DATA_TYPE_NUMERIC - * VALUES_DATA_TYPE_SEQUENCE - * VALUES_DATA_TYPE_TEXT - */ - public short getValuesDataType() - { - return field_2_valuesDataType; - } - - /** - * Set the values data type field for the Series record. - * - * @param field_2_valuesDataType - * One of - * VALUES_DATA_TYPE_DATES - * VALUES_DATA_TYPE_NUMERIC - * VALUES_DATA_TYPE_SEQUENCE - * VALUES_DATA_TYPE_TEXT - */ - public void setValuesDataType(short field_2_valuesDataType) - { - this.field_2_valuesDataType = field_2_valuesDataType; - } - - /** - * Get the num categories field for the Series record. - */ - public short getNumCategories() - { - return field_3_numCategories; - } - - /** - * Set the num categories field for the Series record. - */ - public void setNumCategories(short field_3_numCategories) - { - this.field_3_numCategories = field_3_numCategories; - } - - /** - * Get the num values field for the Series record. - */ - public short getNumValues() - { - return field_4_numValues; - } - - /** - * Set the num values field for the Series record. - */ - public void setNumValues(short field_4_numValues) - { - this.field_4_numValues = field_4_numValues; - } - - /** - * Get the bubble series type field for the Series record. - * - * @return One of - * BUBBLE_SERIES_TYPE_DATES - * BUBBLE_SERIES_TYPE_NUMERIC - * BUBBLE_SERIES_TYPE_SEQUENCE - * BUBBLE_SERIES_TYPE_TEXT - */ - public short getBubbleSeriesType() - { - return field_5_bubbleSeriesType; - } - - /** - * Set the bubble series type field for the Series record. - * - * @param field_5_bubbleSeriesType - * One of - * BUBBLE_SERIES_TYPE_DATES - * BUBBLE_SERIES_TYPE_NUMERIC - * BUBBLE_SERIES_TYPE_SEQUENCE - * BUBBLE_SERIES_TYPE_TEXT - */ - public void setBubbleSeriesType(short field_5_bubbleSeriesType) - { - this.field_5_bubbleSeriesType = field_5_bubbleSeriesType; - } - - /** - * Get the num bubble values field for the Series record. - */ - public short getNumBubbleValues() - { - return field_6_numBubbleValues; - } - - /** - * Set the num bubble values field for the Series record. - */ - public void setNumBubbleValues(short field_6_numBubbleValues) - { - this.field_6_numBubbleValues = field_6_numBubbleValues; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesTextRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesTextRecord.java deleted file mode 100644 index 7e349895a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesTextRecord.java +++ /dev/null @@ -1,131 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * SERIESTEXT (0x100D)

    - * Defines a series name - */ -public final class SeriesTextRecord extends StandardRecord { - public final static short sid = 0x100D; - - /** the actual text cannot be longer than 255 characters */ - private static final int MAX_LEN = 0xFF; - private int field_1_id; - private boolean is16bit; - private String field_4_text; - - public SeriesTextRecord() { - field_4_text = ""; - is16bit = false; - } - - public SeriesTextRecord(RecordInputStream in) { - field_1_id = in.readUShort(); - int field_2_textLength = in.readUByte(); - is16bit = (in.readUByte() & 0x01) != 0; - if (is16bit) { - field_4_text = in.readUnicodeLEString(field_2_textLength); - } else { - field_4_text = in.readCompressedUnicode(field_2_textLength); - } - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[SERIESTEXT]\n"); - sb.append(" .id =").append(HexDump.shortToHex(getId())).append('\n'); - sb.append(" .textLen=").append(field_4_text.length()).append('\n'); - sb.append(" .is16bit=").append(is16bit).append('\n'); - sb.append(" .text =").append(" (").append(getText()).append(" )").append('\n'); - sb.append("[/SERIESTEXT]\n"); - return sb.toString(); - } - - public void serialize(LittleEndianOutput out) { - - out.writeShort(field_1_id); - out.writeByte(field_4_text.length()); - if (is16bit) { - // Excel (2007) seems to choose 16bit regardless of whether it is needed - out.writeByte(0x01); - StringUtil.putUnicodeLE(field_4_text, out); - } else { - // Excel can read this OK - out.writeByte(0x00); - StringUtil.putCompressedUnicode(field_4_text, out); - } - } - - protected int getDataSize() { - return 2 + 1 + 1 + field_4_text.length() * (is16bit ? 2 : 1); - } - - public short getSid() { - return sid; - } - - public Object clone() { - SeriesTextRecord rec = new SeriesTextRecord(); - - rec.field_1_id = field_1_id; - rec.is16bit = is16bit; - rec.field_4_text = field_4_text; - return rec; - } - - /** - * Get the id field for the SeriesText record. - */ - public int getId() { - return field_1_id; - } - - /** - * Set the id field for the SeriesText record. - */ - public void setId(int id) { - field_1_id = id; - } - - /** - * Get the text field for the SeriesText record. - */ - public String getText() { - return field_4_text; - } - - /** - * Set the text field for the SeriesText record. - */ - public void setText(String text) { - if (text.length() > MAX_LEN) { - throw new IllegalArgumentException("Text is too long (" - + text.length() + ">" + MAX_LEN + ")"); - } - field_4_text = text; - is16bit = StringUtil.hasMultibyte(text); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesToChartGroupRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesToChartGroupRecord.java deleted file mode 100644 index fcb73e84f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SeriesToChartGroupRecord.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Indicates the chart-group index for a series. The order probably defines the mapping. - * So the 0th record probably means the 0th series. The only field in this of course defines which chart - * group the 0th series (for instance) would map to. Confusing? Well thats because it is. (p 522 BCG) - */ -public final class SeriesToChartGroupRecord extends StandardRecord { - public final static short sid = 0x1045; - private short field_1_chartGroupIndex; - - - public SeriesToChartGroupRecord() - { - - } - - public SeriesToChartGroupRecord(RecordInputStream in) - { - field_1_chartGroupIndex = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SeriesToChartGroup]\n"); - buffer.append(" .chartGroupIndex = ") - .append("0x").append(HexDump.toHex( getChartGroupIndex ())) - .append(" (").append( getChartGroupIndex() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/SeriesToChartGroup]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_chartGroupIndex); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - SeriesToChartGroupRecord rec = new SeriesToChartGroupRecord(); - - rec.field_1_chartGroupIndex = field_1_chartGroupIndex; - return rec; - } - - - - - /** - * Get the chart group index field for the SeriesToChartGroup record. - */ - public short getChartGroupIndex() - { - return field_1_chartGroupIndex; - } - - /** - * Set the chart group index field for the SeriesToChartGroup record. - */ - public void setChartGroupIndex(short field_1_chartGroupIndex) - { - this.field_1_chartGroupIndex = field_1_chartGroupIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java deleted file mode 100644 index d264459f8..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java +++ /dev/null @@ -1,206 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Describes a chart sheet properties record. SHTPROPS (0x1044)

    - * - * (As with all chart related records, documentation is lacking. - * See {@link ChartRecord} for more details) - */ -public final class SheetPropertiesRecord extends StandardRecord { - public final static short sid = 0x1044; - - private static final BitField chartTypeManuallyFormatted = BitFieldFactory.getInstance(0x01); - private static final BitField plotVisibleOnly = BitFieldFactory.getInstance(0x02); - private static final BitField doNotSizeWithWindow = BitFieldFactory.getInstance(0x04); - private static final BitField defaultPlotDimensions = BitFieldFactory.getInstance(0x08); - private static final BitField autoPlotArea = BitFieldFactory.getInstance(0x10); - - private int field_1_flags; - private int field_2_empty; - public final static byte EMPTY_NOT_PLOTTED = 0; - public final static byte EMPTY_ZERO = 1; - public final static byte EMPTY_INTERPOLATED = 2; - - - public SheetPropertiesRecord() { - // fields uninitialised - } - - public SheetPropertiesRecord(RecordInputStream in) { - field_1_flags = in.readUShort(); - field_2_empty = in.readUShort(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SHTPROPS]\n"); - buffer.append(" .flags = ").append(HexDump.shortToHex(field_1_flags)).append('\n'); - buffer.append(" .chartTypeManuallyFormatted= ").append(isChartTypeManuallyFormatted()).append('\n'); - buffer.append(" .plotVisibleOnly = ").append(isPlotVisibleOnly()).append('\n'); - buffer.append(" .doNotSizeWithWindow = ").append(isDoNotSizeWithWindow()).append('\n'); - buffer.append(" .defaultPlotDimensions = ").append(isDefaultPlotDimensions()).append('\n'); - buffer.append(" .autoPlotArea = ").append(isAutoPlotArea()).append('\n'); - buffer.append(" .empty = ").append(HexDump.shortToHex(field_2_empty)).append('\n'); - - buffer.append("[/SHTPROPS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_flags); - out.writeShort(field_2_empty); - } - - protected int getDataSize() { - return 2 + 2; - } - - public short getSid() { - return sid; - } - - public Object clone() { - SheetPropertiesRecord rec = new SheetPropertiesRecord(); - - rec.field_1_flags = field_1_flags; - rec.field_2_empty = field_2_empty; - return rec; - } - - /** - * Get the flags field for the SheetProperties record. - */ - public int getFlags() { - return field_1_flags; - } - - /** - * Get the empty field for the SheetProperties record. - * - * @return One of - * EMPTY_NOT_PLOTTED - * EMPTY_ZERO - * EMPTY_INTERPOLATED - */ - public int getEmpty() { - return field_2_empty; - } - - /** - * Set the empty field for the SheetProperties record. - * - * @param empty - * One of - * EMPTY_NOT_PLOTTED - * EMPTY_ZERO - * EMPTY_INTERPOLATED - */ - public void setEmpty(byte empty) { - this.field_2_empty = empty; - } - - /** - * Sets the chart type manually formatted field value. - * Has the chart type been manually formatted? - */ - public void setChartTypeManuallyFormatted(boolean value) { - field_1_flags = chartTypeManuallyFormatted.setBoolean(field_1_flags, value); - } - - /** - * Has the chart type been manually formatted? - * @return the chart type manually formatted field value. - */ - public boolean isChartTypeManuallyFormatted() { - return chartTypeManuallyFormatted.isSet(field_1_flags); - } - - /** - * Sets the plot visible only field value. - * Only show visible cells on the chart. - */ - public void setPlotVisibleOnly(boolean value) { - field_1_flags = plotVisibleOnly.setBoolean(field_1_flags, value); - } - - /** - * Only show visible cells on the chart. - * @return the plot visible only field value. - */ - public boolean isPlotVisibleOnly() { - return plotVisibleOnly.isSet(field_1_flags); - } - - /** - * Sets the do not size with window field value. - * Do not size the chart when the window changes size - */ - public void setDoNotSizeWithWindow(boolean value) { - field_1_flags = doNotSizeWithWindow.setBoolean(field_1_flags, value); - } - - /** - * Do not size the chart when the window changes size - * @return the do not size with window field value. - */ - public boolean isDoNotSizeWithWindow() { - return doNotSizeWithWindow.isSet(field_1_flags); - } - - /** - * Sets the default plot dimensions field value. - * Indicates that the default area dimensions should be used. - */ - public void setDefaultPlotDimensions(boolean value) { - field_1_flags = defaultPlotDimensions.setBoolean(field_1_flags, value); - } - - /** - * Indicates that the default area dimensions should be used. - * @return the default plot dimensions field value. - */ - public boolean isDefaultPlotDimensions() { - return defaultPlotDimensions.isSet(field_1_flags); - } - - /** - * Sets the auto plot area field value. - * ?? - */ - public void setAutoPlotArea(boolean value) { - field_1_flags = autoPlotArea.setBoolean(field_1_flags, value); - } - - /** - * ?? - * @return the auto plot area field value. - */ - public boolean isAutoPlotArea() { - return autoPlotArea.isSet(field_1_flags); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/TextRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/TextRecord.java deleted file mode 100644 index 28fb65318..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/TextRecord.java +++ /dev/null @@ -1,705 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The text record is used to define text stored on a chart. - */ -public final class TextRecord extends StandardRecord { - public final static short sid = 0x1025; - - private static final BitField dataLabelPlacement = BitFieldFactory.getInstance(0x000F); - private static final BitField autoColor = BitFieldFactory.getInstance(0x0001); - private static final BitField showKey = BitFieldFactory.getInstance(0x0002); - private static final BitField showValue = BitFieldFactory.getInstance(0x0004); - private static final BitField vertical = BitFieldFactory.getInstance(0x0008); - private static final BitField autoGeneratedText = BitFieldFactory.getInstance(0x0010); - private static final BitField generated = BitFieldFactory.getInstance(0x0020); - private static final BitField autoLabelDeleted = BitFieldFactory.getInstance(0x0040); - private static final BitField autoBackground = BitFieldFactory.getInstance(0x0080); - private static final BitField rotation = BitFieldFactory.getInstance(0x0700); - - private static final BitField showCategoryLabelAsPercentage = BitFieldFactory.getInstance(0x0800); - private static final BitField showValueAsPercentage = BitFieldFactory.getInstance(0x1000); - private static final BitField showBubbleSizes = BitFieldFactory.getInstance(0x2000); - private static final BitField showLabel = BitFieldFactory.getInstance(0x4000); - - - private byte field_1_horizontalAlignment; - public final static byte HORIZONTAL_ALIGNMENT_LEFT = 1; - public final static byte HORIZONTAL_ALIGNMENT_CENTER = 2; - public final static byte HORIZONTAL_ALIGNMENT_BOTTOM = 3; - public final static byte HORIZONTAL_ALIGNMENT_JUSTIFY = 4; - private byte field_2_verticalAlignment; - public final static byte VERTICAL_ALIGNMENT_TOP = 1; - public final static byte VERTICAL_ALIGNMENT_CENTER = 2; - public final static byte VERTICAL_ALIGNMENT_BOTTOM = 3; - public final static byte VERTICAL_ALIGNMENT_JUSTIFY = 4; - private short field_3_displayMode; - public final static short DISPLAY_MODE_TRANSPARENT = 1; - public final static short DISPLAY_MODE_OPAQUE = 2; - private int field_4_rgbColor; - private int field_5_x; - private int field_6_y; - private int field_7_width; - private int field_8_height; - private short field_9_options1; - public final static short ROTATION_NONE = 0; - public final static short ROTATION_TOP_TO_BOTTOM = 1; - public final static short ROTATION_ROTATED_90_DEGREES = 2; - public final static short ROTATION_ROTATED_90_DEGREES_CLOCKWISE = 3; - private short field_10_indexOfColorValue; - private short field_11_options2; - public final static short DATA_LABEL_PLACEMENT_CHART_DEPENDENT = 0; - public final static short DATA_LABEL_PLACEMENT_OUTSIDE = 1; - public final static short DATA_LABEL_PLACEMENT_INSIDE = 2; - public final static short DATA_LABEL_PLACEMENT_CENTER = 3; - public final static short DATA_LABEL_PLACEMENT_AXIS = 4; - public final static short DATA_LABEL_PLACEMENT_ABOVE = 5; - public final static short DATA_LABEL_PLACEMENT_BELOW = 6; - public final static short DATA_LABEL_PLACEMENT_LEFT = 7; - public final static short DATA_LABEL_PLACEMENT_RIGHT = 8; - public final static short DATA_LABEL_PLACEMENT_AUTO = 9; - public final static short DATA_LABEL_PLACEMENT_USER_MOVED = 10; - private short field_12_textRotation; - - - public TextRecord() - { - - } - - public TextRecord(RecordInputStream in) - { - field_1_horizontalAlignment = in.readByte(); - field_2_verticalAlignment = in.readByte(); - field_3_displayMode = in.readShort(); - field_4_rgbColor = in.readInt(); - field_5_x = in.readInt(); - field_6_y = in.readInt(); - field_7_width = in.readInt(); - field_8_height = in.readInt(); - field_9_options1 = in.readShort(); - field_10_indexOfColorValue = in.readShort(); - field_11_options2 = in.readShort(); - field_12_textRotation = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[TEXT]\n"); - buffer.append(" .horizontalAlignment = ") - .append("0x").append(HexDump.toHex( getHorizontalAlignment ())) - .append(" (").append( getHorizontalAlignment() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .verticalAlignment = ") - .append("0x").append(HexDump.toHex( getVerticalAlignment ())) - .append(" (").append( getVerticalAlignment() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .displayMode = ") - .append("0x").append(HexDump.toHex( getDisplayMode ())) - .append(" (").append( getDisplayMode() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .rgbColor = ") - .append("0x").append(HexDump.toHex( getRgbColor ())) - .append(" (").append( getRgbColor() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .x = ") - .append("0x").append(HexDump.toHex( getX ())) - .append(" (").append( getX() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .y = ") - .append("0x").append(HexDump.toHex( getY ())) - .append(" (").append( getY() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .width = ") - .append("0x").append(HexDump.toHex( getWidth ())) - .append(" (").append( getWidth() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .height = ") - .append("0x").append(HexDump.toHex( getHeight ())) - .append(" (").append( getHeight() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options1 = ") - .append("0x").append(HexDump.toHex( getOptions1 ())) - .append(" (").append( getOptions1() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .autoColor = ").append(isAutoColor()).append('\n'); - buffer.append(" .showKey = ").append(isShowKey()).append('\n'); - buffer.append(" .showValue = ").append(isShowValue()).append('\n'); - buffer.append(" .vertical = ").append(isVertical()).append('\n'); - buffer.append(" .autoGeneratedText = ").append(isAutoGeneratedText()).append('\n'); - buffer.append(" .generated = ").append(isGenerated()).append('\n'); - buffer.append(" .autoLabelDeleted = ").append(isAutoLabelDeleted()).append('\n'); - buffer.append(" .autoBackground = ").append(isAutoBackground()).append('\n'); - buffer.append(" .rotation = ").append(getRotation()).append('\n'); - buffer.append(" .showCategoryLabelAsPercentage = ").append(isShowCategoryLabelAsPercentage()).append('\n'); - buffer.append(" .showValueAsPercentage = ").append(isShowValueAsPercentage()).append('\n'); - buffer.append(" .showBubbleSizes = ").append(isShowBubbleSizes()).append('\n'); - buffer.append(" .showLabel = ").append(isShowLabel()).append('\n'); - buffer.append(" .indexOfColorValue = ") - .append("0x").append(HexDump.toHex( getIndexOfColorValue ())) - .append(" (").append( getIndexOfColorValue() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options2 = ") - .append("0x").append(HexDump.toHex( getOptions2 ())) - .append(" (").append( getOptions2() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .dataLabelPlacement = ").append(getDataLabelPlacement()).append('\n'); - buffer.append(" .textRotation = ") - .append("0x").append(HexDump.toHex( getTextRotation ())) - .append(" (").append( getTextRotation() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/TEXT]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(field_1_horizontalAlignment); - out.writeByte(field_2_verticalAlignment); - out.writeShort(field_3_displayMode); - out.writeInt(field_4_rgbColor); - out.writeInt(field_5_x); - out.writeInt(field_6_y); - out.writeInt(field_7_width); - out.writeInt(field_8_height); - out.writeShort(field_9_options1); - out.writeShort(field_10_indexOfColorValue); - out.writeShort(field_11_options2); - out.writeShort(field_12_textRotation); - } - - protected int getDataSize() { - return 1 + 1 + 2 + 4 + 4 + 4 + 4 + 4 + 2 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - TextRecord rec = new TextRecord(); - - rec.field_1_horizontalAlignment = field_1_horizontalAlignment; - rec.field_2_verticalAlignment = field_2_verticalAlignment; - rec.field_3_displayMode = field_3_displayMode; - rec.field_4_rgbColor = field_4_rgbColor; - rec.field_5_x = field_5_x; - rec.field_6_y = field_6_y; - rec.field_7_width = field_7_width; - rec.field_8_height = field_8_height; - rec.field_9_options1 = field_9_options1; - rec.field_10_indexOfColorValue = field_10_indexOfColorValue; - rec.field_11_options2 = field_11_options2; - rec.field_12_textRotation = field_12_textRotation; - return rec; - } - - - - - /** - * Get the horizontal alignment field for the Text record. - * - * @return One of - * HORIZONTAL_ALIGNMENT_LEFT - * HORIZONTAL_ALIGNMENT_CENTER - * HORIZONTAL_ALIGNMENT_BOTTOM - * HORIZONTAL_ALIGNMENT_JUSTIFY - */ - public byte getHorizontalAlignment() - { - return field_1_horizontalAlignment; - } - - /** - * Set the horizontal alignment field for the Text record. - * - * @param field_1_horizontalAlignment - * One of - * HORIZONTAL_ALIGNMENT_LEFT - * HORIZONTAL_ALIGNMENT_CENTER - * HORIZONTAL_ALIGNMENT_BOTTOM - * HORIZONTAL_ALIGNMENT_JUSTIFY - */ - public void setHorizontalAlignment(byte field_1_horizontalAlignment) - { - this.field_1_horizontalAlignment = field_1_horizontalAlignment; - } - - /** - * Get the vertical alignment field for the Text record. - * - * @return One of - * VERTICAL_ALIGNMENT_TOP - * VERTICAL_ALIGNMENT_CENTER - * VERTICAL_ALIGNMENT_BOTTOM - * VERTICAL_ALIGNMENT_JUSTIFY - */ - public byte getVerticalAlignment() - { - return field_2_verticalAlignment; - } - - /** - * Set the vertical alignment field for the Text record. - * - * @param field_2_verticalAlignment - * One of - * VERTICAL_ALIGNMENT_TOP - * VERTICAL_ALIGNMENT_CENTER - * VERTICAL_ALIGNMENT_BOTTOM - * VERTICAL_ALIGNMENT_JUSTIFY - */ - public void setVerticalAlignment(byte field_2_verticalAlignment) - { - this.field_2_verticalAlignment = field_2_verticalAlignment; - } - - /** - * Get the display mode field for the Text record. - * - * @return One of - * DISPLAY_MODE_TRANSPARENT - * DISPLAY_MODE_OPAQUE - */ - public short getDisplayMode() - { - return field_3_displayMode; - } - - /** - * Set the display mode field for the Text record. - * - * @param field_3_displayMode - * One of - * DISPLAY_MODE_TRANSPARENT - * DISPLAY_MODE_OPAQUE - */ - public void setDisplayMode(short field_3_displayMode) - { - this.field_3_displayMode = field_3_displayMode; - } - - /** - * Get the rgbColor field for the Text record. - */ - public int getRgbColor() - { - return field_4_rgbColor; - } - - /** - * Set the rgbColor field for the Text record. - */ - public void setRgbColor(int field_4_rgbColor) - { - this.field_4_rgbColor = field_4_rgbColor; - } - - /** - * Get the x field for the Text record. - */ - public int getX() - { - return field_5_x; - } - - /** - * Set the x field for the Text record. - */ - public void setX(int field_5_x) - { - this.field_5_x = field_5_x; - } - - /** - * Get the y field for the Text record. - */ - public int getY() - { - return field_6_y; - } - - /** - * Set the y field for the Text record. - */ - public void setY(int field_6_y) - { - this.field_6_y = field_6_y; - } - - /** - * Get the width field for the Text record. - */ - public int getWidth() - { - return field_7_width; - } - - /** - * Set the width field for the Text record. - */ - public void setWidth(int field_7_width) - { - this.field_7_width = field_7_width; - } - - /** - * Get the height field for the Text record. - */ - public int getHeight() - { - return field_8_height; - } - - /** - * Set the height field for the Text record. - */ - public void setHeight(int field_8_height) - { - this.field_8_height = field_8_height; - } - - /** - * Get the options1 field for the Text record. - */ - public short getOptions1() - { - return field_9_options1; - } - - /** - * Set the options1 field for the Text record. - */ - public void setOptions1(short field_9_options1) - { - this.field_9_options1 = field_9_options1; - } - - /** - * Get the index of color value field for the Text record. - */ - public short getIndexOfColorValue() - { - return field_10_indexOfColorValue; - } - - /** - * Set the index of color value field for the Text record. - */ - public void setIndexOfColorValue(short field_10_indexOfColorValue) - { - this.field_10_indexOfColorValue = field_10_indexOfColorValue; - } - - /** - * Get the options2 field for the Text record. - */ - public short getOptions2() - { - return field_11_options2; - } - - /** - * Set the options2 field for the Text record. - */ - public void setOptions2(short field_11_options2) - { - this.field_11_options2 = field_11_options2; - } - - /** - * Get the text rotation field for the Text record. - */ - public short getTextRotation() - { - return field_12_textRotation; - } - - /** - * Set the text rotation field for the Text record. - */ - public void setTextRotation(short field_12_textRotation) - { - this.field_12_textRotation = field_12_textRotation; - } - - /** - * Sets the auto color field value. - * true = automaticly selected colour, false = user-selected - */ - public void setAutoColor(boolean value) - { - field_9_options1 = autoColor.setShortBoolean(field_9_options1, value); - } - - /** - * true = automaticly selected colour, false = user-selected - * @return the auto color field value. - */ - public boolean isAutoColor() - { - return autoColor.isSet(field_9_options1); - } - - /** - * Sets the show key field value. - * true = draw legend - */ - public void setShowKey(boolean value) - { - field_9_options1 = showKey.setShortBoolean(field_9_options1, value); - } - - /** - * true = draw legend - * @return the show key field value. - */ - public boolean isShowKey() - { - return showKey.isSet(field_9_options1); - } - - /** - * Sets the show value field value. - * false = text is category label - */ - public void setShowValue(boolean value) - { - field_9_options1 = showValue.setShortBoolean(field_9_options1, value); - } - - /** - * false = text is category label - * @return the show value field value. - */ - public boolean isShowValue() - { - return showValue.isSet(field_9_options1); - } - - /** - * Sets the vertical field value. - * true = text is vertical - */ - public void setVertical(boolean value) - { - field_9_options1 = vertical.setShortBoolean(field_9_options1, value); - } - - /** - * true = text is vertical - * @return the vertical field value. - */ - public boolean isVertical() - { - return vertical.isSet(field_9_options1); - } - - /** - * Sets the auto generated text field value. - * - */ - public void setAutoGeneratedText(boolean value) - { - field_9_options1 = autoGeneratedText.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the auto generated text field value. - */ - public boolean isAutoGeneratedText() - { - return autoGeneratedText.isSet(field_9_options1); - } - - /** - * Sets the generated field value. - * - */ - public void setGenerated(boolean value) - { - field_9_options1 = generated.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the generated field value. - */ - public boolean isGenerated() - { - return generated.isSet(field_9_options1); - } - - /** - * Sets the auto label deleted field value. - * - */ - public void setAutoLabelDeleted(boolean value) - { - field_9_options1 = autoLabelDeleted.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the auto label deleted field value. - */ - public boolean isAutoLabelDeleted() - { - return autoLabelDeleted.isSet(field_9_options1); - } - - /** - * Sets the auto background field value. - * - */ - public void setAutoBackground(boolean value) - { - field_9_options1 = autoBackground.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the auto background field value. - */ - public boolean isAutoBackground() - { - return autoBackground.isSet(field_9_options1); - } - - /** - * Sets the rotation field value. - * - */ - public void setRotation(short value) - { - field_9_options1 = rotation.setShortValue(field_9_options1, value); - } - - /** - * - * @return the rotation field value. - */ - public short getRotation() - { - return rotation.getShortValue(field_9_options1); - } - - /** - * Sets the show category label as percentage field value. - * - */ - public void setShowCategoryLabelAsPercentage(boolean value) - { - field_9_options1 = showCategoryLabelAsPercentage.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the show category label as percentage field value. - */ - public boolean isShowCategoryLabelAsPercentage() - { - return showCategoryLabelAsPercentage.isSet(field_9_options1); - } - - /** - * Sets the show value as percentage field value. - * - */ - public void setShowValueAsPercentage(boolean value) - { - field_9_options1 = showValueAsPercentage.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the show value as percentage field value. - */ - public boolean isShowValueAsPercentage() - { - return showValueAsPercentage.isSet(field_9_options1); - } - - /** - * Sets the show bubble sizes field value. - * - */ - public void setShowBubbleSizes(boolean value) - { - field_9_options1 = showBubbleSizes.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the show bubble sizes field value. - */ - public boolean isShowBubbleSizes() - { - return showBubbleSizes.isSet(field_9_options1); - } - - /** - * Sets the show label field value. - * - */ - public void setShowLabel(boolean value) - { - field_9_options1 = showLabel.setShortBoolean(field_9_options1, value); - } - - /** - * - * @return the show label field value. - */ - public boolean isShowLabel() - { - return showLabel.isSet(field_9_options1); - } - - /** - * Sets the data label placement field value. - * - */ - public void setDataLabelPlacement(short value) - { - field_11_options2 = dataLabelPlacement.setShortValue(field_11_options2, value); - } - - /** - * - * @return the data label placement field value. - */ - public short getDataLabelPlacement() - { - return dataLabelPlacement.getShortValue(field_11_options2); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/TickRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/TickRecord.java deleted file mode 100644 index 993f5705c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/TickRecord.java +++ /dev/null @@ -1,407 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The Tick record defines how tick marks and label positioning/formatting

    - * - * @author Andrew C. Oliver(acoliver at apache.org) - */ -public final class TickRecord extends StandardRecord { - public final static short sid = 0x101E; - - private static final BitField autoTextColor = BitFieldFactory.getInstance(0x1); - private static final BitField autoTextBackground = BitFieldFactory.getInstance(0x2); - private static final BitField rotation = BitFieldFactory.getInstance(0x1c); - private static final BitField autorotate = BitFieldFactory.getInstance(0x20); - - private byte field_1_majorTickType; - private byte field_2_minorTickType; - private byte field_3_labelPosition; - private byte field_4_background; - private int field_5_labelColorRgb; - private int field_6_zero1; - private int field_7_zero2; - private int field_8_zero3; - private int field_9_zero4; - private short field_10_options; - private short field_11_tickColor; - private short field_12_zero5; - - - public TickRecord() - { - - } - - public TickRecord(RecordInputStream in) - { - - field_1_majorTickType = in.readByte(); - field_2_minorTickType = in.readByte(); - field_3_labelPosition = in.readByte(); - field_4_background = in.readByte(); - field_5_labelColorRgb = in.readInt(); - field_6_zero1 = in.readInt(); - field_7_zero2 = in.readInt(); - field_8_zero3 = in.readInt(); - field_9_zero4 = in.readInt(); - - field_10_options = in.readShort(); - field_11_tickColor = in.readShort(); - field_12_zero5 = in.readShort(); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[TICK]\n"); - buffer.append(" .majorTickType = ") - .append("0x").append(HexDump.toHex( getMajorTickType ())) - .append(" (").append( getMajorTickType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .minorTickType = ") - .append("0x").append(HexDump.toHex( getMinorTickType ())) - .append(" (").append( getMinorTickType() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .labelPosition = ") - .append("0x").append(HexDump.toHex( getLabelPosition ())) - .append(" (").append( getLabelPosition() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .background = ") - .append("0x").append(HexDump.toHex( getBackground ())) - .append(" (").append( getBackground() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .labelColorRgb = ") - .append("0x").append(HexDump.toHex( getLabelColorRgb ())) - .append(" (").append( getLabelColorRgb() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .zero1 = ") - .append("0x").append(HexDump.toHex( getZero1 ())) - .append(" (").append( getZero1() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .zero2 = ") - .append("0x").append(HexDump.toHex( getZero2 ())) - .append(" (").append( getZero2() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options = ") - .append("0x").append(HexDump.toHex( getOptions ())) - .append(" (").append( getOptions() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .autoTextColor = ").append(isAutoTextColor()).append('\n'); - buffer.append(" .autoTextBackground = ").append(isAutoTextBackground()).append('\n'); - buffer.append(" .rotation = ").append(getRotation()).append('\n'); - buffer.append(" .autorotate = ").append(isAutorotate()).append('\n'); - buffer.append(" .tickColor = ") - .append("0x").append(HexDump.toHex( getTickColor ())) - .append(" (").append( getTickColor() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .zero3 = ") - .append("0x").append(HexDump.toHex( getZero3 ())) - .append(" (").append( getZero3() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/TICK]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeByte(field_1_majorTickType); - out.writeByte(field_2_minorTickType); - out.writeByte(field_3_labelPosition); - out.writeByte(field_4_background); - out.writeInt(field_5_labelColorRgb); - out.writeInt(field_6_zero1); - out.writeInt(field_7_zero2); - out.writeInt(field_8_zero3); - out.writeInt(field_9_zero4); - out.writeShort(field_10_options); - out.writeShort(field_11_tickColor); - out.writeShort(field_12_zero5); - } - - protected int getDataSize() { - return 1 + 1 + 1 + 1 + 4 + 8 + 8 + 2 + 2 + 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - TickRecord rec = new TickRecord(); - - rec.field_1_majorTickType = field_1_majorTickType; - rec.field_2_minorTickType = field_2_minorTickType; - rec.field_3_labelPosition = field_3_labelPosition; - rec.field_4_background = field_4_background; - rec.field_5_labelColorRgb = field_5_labelColorRgb; - rec.field_6_zero1 = field_6_zero1; - rec.field_7_zero2 = field_7_zero2; - rec.field_8_zero3 = field_8_zero3; - rec.field_9_zero4 = field_9_zero4; - rec.field_10_options = field_10_options; - rec.field_11_tickColor = field_11_tickColor; - rec.field_12_zero5 = field_12_zero5; - return rec; - } - - - - - /** - * Get the major tick type field for the Tick record. - */ - public byte getMajorTickType() - { - return field_1_majorTickType; - } - - /** - * Set the major tick type field for the Tick record. - */ - public void setMajorTickType(byte field_1_majorTickType) - { - this.field_1_majorTickType = field_1_majorTickType; - } - - /** - * Get the minor tick type field for the Tick record. - */ - public byte getMinorTickType() - { - return field_2_minorTickType; - } - - /** - * Set the minor tick type field for the Tick record. - */ - public void setMinorTickType(byte field_2_minorTickType) - { - this.field_2_minorTickType = field_2_minorTickType; - } - - /** - * Get the label position field for the Tick record. - */ - public byte getLabelPosition() - { - return field_3_labelPosition; - } - - /** - * Set the label position field for the Tick record. - */ - public void setLabelPosition(byte field_3_labelPosition) - { - this.field_3_labelPosition = field_3_labelPosition; - } - - /** - * Get the background field for the Tick record. - */ - public byte getBackground() - { - return field_4_background; - } - - /** - * Set the background field for the Tick record. - */ - public void setBackground(byte field_4_background) - { - this.field_4_background = field_4_background; - } - - /** - * Get the label color rgb field for the Tick record. - */ - public int getLabelColorRgb() - { - return field_5_labelColorRgb; - } - - /** - * Set the label color rgb field for the Tick record. - */ - public void setLabelColorRgb(int field_5_labelColorRgb) - { - this.field_5_labelColorRgb = field_5_labelColorRgb; - } - - /** - * Get the zero 1 field for the Tick record. - */ - public int getZero1() - { - return field_6_zero1; - } - - /** - * Set the zero 1 field for the Tick record. - */ - public void setZero1(int field_6_zero1) - { - this.field_6_zero1 = field_6_zero1; - } - - /** - * Get the zero 2 field for the Tick record. - */ - public int getZero2() - { - return field_7_zero2; - } - - /** - * Set the zero 2 field for the Tick record. - */ - public void setZero2(int field_7_zero2) - { - this.field_7_zero2 = field_7_zero2; - } - - /** - * Get the options field for the Tick record. - */ - public short getOptions() - { - return field_10_options; - } - - /** - * Set the options field for the Tick record. - */ - public void setOptions(short field_10_options) - { - this.field_10_options = field_10_options; - } - - /** - * Get the tick color field for the Tick record. - */ - public short getTickColor() - { - return field_11_tickColor; - } - - /** - * Set the tick color field for the Tick record. - */ - public void setTickColor(short field_11_tickColor) - { - this.field_11_tickColor = field_11_tickColor; - } - - /** - * Get the zero 3 field for the Tick record. - */ - public short getZero3() - { - return field_12_zero5; - } - - /** - * Set the zero 3 field for the Tick record. - */ - public void setZero3(short field_12_zero3) - { - this.field_12_zero5 = field_12_zero3; - } - - /** - * Sets the auto text color field value. - * use the quote unquote automatic color for text - */ - public void setAutoTextColor(boolean value) - { - field_10_options = autoTextColor.setShortBoolean(field_10_options, value); - } - - /** - * use the quote unquote automatic color for text - * @return the auto text color field value. - */ - public boolean isAutoTextColor() - { - return autoTextColor.isSet(field_10_options); - } - - /** - * Sets the auto text background field value. - * use the quote unquote automatic color for text background - */ - public void setAutoTextBackground(boolean value) - { - field_10_options = autoTextBackground.setShortBoolean(field_10_options, value); - } - - /** - * use the quote unquote automatic color for text background - * @return the auto text background field value. - */ - public boolean isAutoTextBackground() - { - return autoTextBackground.isSet(field_10_options); - } - - /** - * Sets the rotation field value. - * rotate text (0=none, 1=normal, 2=90 degrees counterclockwise, 3=90 degrees clockwise) - */ - public void setRotation(short value) - { - field_10_options = rotation.setShortValue(field_10_options, value); - } - - /** - * rotate text (0=none, 1=normal, 2=90 degrees counterclockwise, 3=90 degrees clockwise) - * @return the rotation field value. - */ - public short getRotation() - { - return rotation.getShortValue(field_10_options); - } - - /** - * Sets the autorotate field value. - * automatically rotate the text - */ - public void setAutorotate(boolean value) - { - field_10_options = autorotate.setShortBoolean(field_10_options, value); - } - - /** - * automatically rotate the text - * @return the autorotate field value. - */ - public boolean isAutorotate() - { - return autorotate.isSet(field_10_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java deleted file mode 100644 index cab88c077..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The units record describes units. - */ -public final class UnitsRecord extends StandardRecord { - public final static short sid = 0x1001; - private short field_1_units; - - - public UnitsRecord() - { - - } - - public UnitsRecord(RecordInputStream in) - { - field_1_units = in.readShort(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[UNITS]\n"); - buffer.append(" .units = ") - .append("0x").append(HexDump.toHex( getUnits ())) - .append(" (").append( getUnits() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - - buffer.append("[/UNITS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(field_1_units); - } - - protected int getDataSize() { - return 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - UnitsRecord rec = new UnitsRecord(); - - rec.field_1_units = field_1_units; - return rec; - } - - - - - /** - * Get the units field for the Units record. - */ - public short getUnits() - { - return field_1_units; - } - - /** - * Set the units field for the Units record. - */ - public void setUnits(short field_1_units) - { - this.field_1_units = field_1_units; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java b/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java deleted file mode 100644 index e098011a6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java +++ /dev/null @@ -1,395 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.chart; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * The value range record defines the range of the value axis. - */ -public final class ValueRangeRecord extends StandardRecord { - public final static short sid = 0x101f; - - private static final BitField automaticMinimum = BitFieldFactory.getInstance(0x0001); - private static final BitField automaticMaximum = BitFieldFactory.getInstance(0x0002); - private static final BitField automaticMajor = BitFieldFactory.getInstance(0x0004); - private static final BitField automaticMinor = BitFieldFactory.getInstance(0x0008); - private static final BitField automaticCategoryCrossing = BitFieldFactory.getInstance(0x0010); - private static final BitField logarithmicScale = BitFieldFactory.getInstance(0x0020); - private static final BitField valuesInReverse = BitFieldFactory.getInstance(0x0040); - private static final BitField crossCategoryAxisAtMaximum = BitFieldFactory.getInstance(0x0080); - private static final BitField reserved = BitFieldFactory.getInstance(0x0100); - - private double field_1_minimumAxisValue; - private double field_2_maximumAxisValue; - private double field_3_majorIncrement; - private double field_4_minorIncrement; - private double field_5_categoryAxisCross; - private short field_6_options; - - - public ValueRangeRecord() - { - - } - - public ValueRangeRecord(RecordInputStream in) - { - field_1_minimumAxisValue = in.readDouble(); - field_2_maximumAxisValue = in.readDouble(); - field_3_majorIncrement = in.readDouble(); - field_4_minorIncrement = in.readDouble(); - field_5_categoryAxisCross = in.readDouble(); - field_6_options = in.readShort(); - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[VALUERANGE]\n"); - buffer.append(" .minimumAxisValue = ") - .append(" (").append( getMinimumAxisValue() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .maximumAxisValue = ") - .append(" (").append( getMaximumAxisValue() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .majorIncrement = ") - .append(" (").append( getMajorIncrement() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .minorIncrement = ") - .append(" (").append( getMinorIncrement() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .categoryAxisCross = ") - .append(" (").append( getCategoryAxisCross() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .options = ") - .append("0x").append(HexDump.toHex( getOptions ())) - .append(" (").append( getOptions() ).append(" )"); - buffer.append(System.getProperty("line.separator")); - buffer.append(" .automaticMinimum = ").append(isAutomaticMinimum()).append('\n'); - buffer.append(" .automaticMaximum = ").append(isAutomaticMaximum()).append('\n'); - buffer.append(" .automaticMajor = ").append(isAutomaticMajor()).append('\n'); - buffer.append(" .automaticMinor = ").append(isAutomaticMinor()).append('\n'); - buffer.append(" .automaticCategoryCrossing = ").append(isAutomaticCategoryCrossing()).append('\n'); - buffer.append(" .logarithmicScale = ").append(isLogarithmicScale()).append('\n'); - buffer.append(" .valuesInReverse = ").append(isValuesInReverse()).append('\n'); - buffer.append(" .crossCategoryAxisAtMaximum = ").append(isCrossCategoryAxisAtMaximum()).append('\n'); - buffer.append(" .reserved = ").append(isReserved()).append('\n'); - - buffer.append("[/VALUERANGE]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeDouble(field_1_minimumAxisValue); - out.writeDouble(field_2_maximumAxisValue); - out.writeDouble(field_3_majorIncrement); - out.writeDouble(field_4_minorIncrement); - out.writeDouble(field_5_categoryAxisCross); - out.writeShort(field_6_options); - } - - protected int getDataSize() { - return 8 + 8 + 8 + 8 + 8 + 2; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - ValueRangeRecord rec = new ValueRangeRecord(); - - rec.field_1_minimumAxisValue = field_1_minimumAxisValue; - rec.field_2_maximumAxisValue = field_2_maximumAxisValue; - rec.field_3_majorIncrement = field_3_majorIncrement; - rec.field_4_minorIncrement = field_4_minorIncrement; - rec.field_5_categoryAxisCross = field_5_categoryAxisCross; - rec.field_6_options = field_6_options; - return rec; - } - - - - - /** - * Get the minimum axis value field for the ValueRange record. - */ - public double getMinimumAxisValue() - { - return field_1_minimumAxisValue; - } - - /** - * Set the minimum axis value field for the ValueRange record. - */ - public void setMinimumAxisValue(double field_1_minimumAxisValue) - { - this.field_1_minimumAxisValue = field_1_minimumAxisValue; - } - - /** - * Get the maximum axis value field for the ValueRange record. - */ - public double getMaximumAxisValue() - { - return field_2_maximumAxisValue; - } - - /** - * Set the maximum axis value field for the ValueRange record. - */ - public void setMaximumAxisValue(double field_2_maximumAxisValue) - { - this.field_2_maximumAxisValue = field_2_maximumAxisValue; - } - - /** - * Get the major increment field for the ValueRange record. - */ - public double getMajorIncrement() - { - return field_3_majorIncrement; - } - - /** - * Set the major increment field for the ValueRange record. - */ - public void setMajorIncrement(double field_3_majorIncrement) - { - this.field_3_majorIncrement = field_3_majorIncrement; - } - - /** - * Get the minor increment field for the ValueRange record. - */ - public double getMinorIncrement() - { - return field_4_minorIncrement; - } - - /** - * Set the minor increment field for the ValueRange record. - */ - public void setMinorIncrement(double field_4_minorIncrement) - { - this.field_4_minorIncrement = field_4_minorIncrement; - } - - /** - * Get the category axis cross field for the ValueRange record. - */ - public double getCategoryAxisCross() - { - return field_5_categoryAxisCross; - } - - /** - * Set the category axis cross field for the ValueRange record. - */ - public void setCategoryAxisCross(double field_5_categoryAxisCross) - { - this.field_5_categoryAxisCross = field_5_categoryAxisCross; - } - - /** - * Get the options field for the ValueRange record. - */ - public short getOptions() - { - return field_6_options; - } - - /** - * Set the options field for the ValueRange record. - */ - public void setOptions(short field_6_options) - { - this.field_6_options = field_6_options; - } - - /** - * Sets the automatic minimum field value. - * automatic minimum value selected - */ - public void setAutomaticMinimum(boolean value) - { - field_6_options = automaticMinimum.setShortBoolean(field_6_options, value); - } - - /** - * automatic minimum value selected - * @return the automatic minimum field value. - */ - public boolean isAutomaticMinimum() - { - return automaticMinimum.isSet(field_6_options); - } - - /** - * Sets the automatic maximum field value. - * automatic maximum value selected - */ - public void setAutomaticMaximum(boolean value) - { - field_6_options = automaticMaximum.setShortBoolean(field_6_options, value); - } - - /** - * automatic maximum value selected - * @return the automatic maximum field value. - */ - public boolean isAutomaticMaximum() - { - return automaticMaximum.isSet(field_6_options); - } - - /** - * Sets the automatic major field value. - * automatic major unit selected - */ - public void setAutomaticMajor(boolean value) - { - field_6_options = automaticMajor.setShortBoolean(field_6_options, value); - } - - /** - * automatic major unit selected - * @return the automatic major field value. - */ - public boolean isAutomaticMajor() - { - return automaticMajor.isSet(field_6_options); - } - - /** - * Sets the automatic minor field value. - * automatic minor unit selected - */ - public void setAutomaticMinor(boolean value) - { - field_6_options = automaticMinor.setShortBoolean(field_6_options, value); - } - - /** - * automatic minor unit selected - * @return the automatic minor field value. - */ - public boolean isAutomaticMinor() - { - return automaticMinor.isSet(field_6_options); - } - - /** - * Sets the automatic category crossing field value. - * category crossing point is automatically selected - */ - public void setAutomaticCategoryCrossing(boolean value) - { - field_6_options = automaticCategoryCrossing.setShortBoolean(field_6_options, value); - } - - /** - * category crossing point is automatically selected - * @return the automatic category crossing field value. - */ - public boolean isAutomaticCategoryCrossing() - { - return automaticCategoryCrossing.isSet(field_6_options); - } - - /** - * Sets the logarithmic scale field value. - * use logarithmic scale - */ - public void setLogarithmicScale(boolean value) - { - field_6_options = logarithmicScale.setShortBoolean(field_6_options, value); - } - - /** - * use logarithmic scale - * @return the logarithmic scale field value. - */ - public boolean isLogarithmicScale() - { - return logarithmicScale.isSet(field_6_options); - } - - /** - * Sets the values in reverse field value. - * values are reverses in graph - */ - public void setValuesInReverse(boolean value) - { - field_6_options = valuesInReverse.setShortBoolean(field_6_options, value); - } - - /** - * values are reverses in graph - * @return the values in reverse field value. - */ - public boolean isValuesInReverse() - { - return valuesInReverse.isSet(field_6_options); - } - - /** - * Sets the cross category axis at maximum field value. - * category axis to cross at maximum value - */ - public void setCrossCategoryAxisAtMaximum(boolean value) - { - field_6_options = crossCategoryAxisAtMaximum.setShortBoolean(field_6_options, value); - } - - /** - * category axis to cross at maximum value - * @return the cross category axis at maximum field value. - */ - public boolean isCrossCategoryAxisAtMaximum() - { - return crossCategoryAxisAtMaximum.isSet(field_6_options); - } - - /** - * Sets the reserved field value. - * reserved, must equal 1 (excel dev. guide says otherwise) - */ - public void setReserved(boolean value) - { - field_6_options = reserved.setShortBoolean(field_6_options, value); - } - - /** - * reserved, must equal 1 (excel dev. guide says otherwise) - * @return the reserved field value. - */ - public boolean isReserved() - { - return reserved.isSet(field_6_options); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/ExtendedColor.java b/trunk/src/java/org/apache/poi/hssf/record/common/ExtendedColor.java deleted file mode 100644 index a4defe8dd..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/ExtendedColor.java +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - - -/** - * Title: CTColor (Extended Color) record part - *

    - * The HSSF file format normally stores Color information in the - * Palette (see PaletteRecord), but for a few cases (eg Conditional - * Formatting, Sheet Extensions), this XSSF-style color record - * can be used. - */ -public final class ExtendedColor implements Cloneable { - public static final int TYPE_AUTO = 0; - public static final int TYPE_INDEXED = 1; - public static final int TYPE_RGB = 2; - public static final int TYPE_THEMED = 3; - public static final int TYPE_UNSET = 4; - - public static final int THEME_DARK_1 = 0; - public static final int THEME_LIGHT_1 = 1; - public static final int THEME_DARK_2 = 2; - public static final int THEME_LIGHT_2 = 3; - public static final int THEME_ACCENT_1 = 4; - public static final int THEME_ACCENT_2 = 5; - public static final int THEME_ACCENT_3 = 6; - public static final int THEME_ACCENT_4 = 7; - public static final int THEME_ACCENT_5 = 8; - public static final int THEME_ACCENT_6 = 9; - public static final int THEME_HYPERLINK = 10; - // This one is SheetEx only, not allowed in CFs - public static final int THEME_FOLLOWED_HYPERLINK = 11; - - private int type; - - // Type = Indexed - private int colorIndex; - // Type = RGB - private byte[] rgba; - // Type = Theme - private int themeIndex; - - private double tint; - - public ExtendedColor() { - this.type = TYPE_INDEXED; - this.colorIndex = 0; - this.tint = 0d; - } - public ExtendedColor(LittleEndianInput in) { - type = in.readInt(); - if (type == TYPE_INDEXED) { - colorIndex = in.readInt(); - } else if (type == TYPE_RGB) { - rgba = new byte[4]; - in.readFully(rgba); - } else if (type == TYPE_THEMED) { - themeIndex = in.readInt(); - } else { - // Ignored - in.readInt(); - } - tint = in.readDouble(); - } - - public int getType() { - return type; - } - public void setType(int type) { - this.type = type; - } - - /** - * @return Palette color index, if type is {@link #TYPE_INDEXED} - */ - public int getColorIndex() { - return colorIndex; - } - public void setColorIndex(int colorIndex) { - this.colorIndex = colorIndex; - } - - /** - * @return Red Green Blue Alpha, if type is {@link #TYPE_RGB} - */ - public byte[] getRGBA() { - return rgba; - } - public void setRGBA(byte[] rgba) { - this.rgba = (rgba == null) ? null : rgba.clone(); - } - - /** - * @return Theme color type index, eg {@link #THEME_DARK_1}, if type is {@link #TYPE_THEMED} - */ - public int getThemeIndex() { - return themeIndex; - } - public void setThemeIndex(int themeIndex) { - this.themeIndex = themeIndex; - } - /** - * @return Tint and Shade value, between -1 and +1 - */ - public double getTint() { - return tint; - } - /** - * @param tint Tint and Shade value, between -1 and +1 - */ - public void setTint(double tint) { - if (tint < -1 || tint > 1) { - throw new IllegalArgumentException("Tint/Shade must be between -1 and +1"); - } - this.tint = tint; - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [Extended Color]\n"); - buffer.append(" .type = ").append(type).append("\n"); - buffer.append(" .tint = ").append(tint).append("\n"); - buffer.append(" .c_idx = ").append(colorIndex).append("\n"); - buffer.append(" .rgba = ").append(HexDump.toHex(rgba)).append("\n"); - buffer.append(" .t_idx = ").append(themeIndex).append("\n"); - buffer.append(" [/Extended Color]\n"); - return buffer.toString(); - } - - @Override - public ExtendedColor clone() { - ExtendedColor exc = new ExtendedColor(); - exc.type = type; - exc.tint = tint; - if (type == TYPE_INDEXED) { - exc.colorIndex = colorIndex; - } else if (type == TYPE_RGB) { - exc.rgba = new byte[4]; - System.arraycopy(rgba, 0, exc.rgba, 0, 4); - } else if (type == TYPE_THEMED) { - exc.themeIndex = themeIndex; - } - return exc; - } - - public int getDataLength() { - return 4+4+8; - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(type); - if (type == TYPE_INDEXED) { - out.writeInt(colorIndex); - } else if (type == TYPE_RGB) { - out.write(rgba); - } else if (type == TYPE_THEMED) { - out.writeInt(themeIndex); - } else { - out.writeInt(0); - } - out.writeDouble(tint); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java b/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java deleted file mode 100644 index 8ab993632..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java +++ /dev/null @@ -1,142 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.hssf.record.FeatRecord; -//import org.apache.poi.hssf.record.Feat11Record; -//import org.apache.poi.hssf.record.Feat12Record; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: FeatFormulaErr2 (Formula Evaluation Shared Feature) common record part - *

    - * This record part specifies Formula Evaluation & Error Ignoring data - * for a sheet, stored as part of a Shared Feature. It can be found in - * records such as {@link FeatRecord}. - * For the full meanings of the flags, see pages 669 and 670 - * of the Excel binary file format documentation and/or - * https://msdn.microsoft.com/en-us/library/dd924991%28v=office.12%29.aspx - */ -public final class FeatFormulaErr2 implements SharedFeature { - private static final BitField CHECK_CALCULATION_ERRORS = BitFieldFactory.getInstance(0x01); - private static final BitField CHECK_EMPTY_CELL_REF = BitFieldFactory.getInstance(0x02); - private static final BitField CHECK_NUMBERS_AS_TEXT = BitFieldFactory.getInstance(0x04); - private static final BitField CHECK_INCONSISTENT_RANGES = BitFieldFactory.getInstance(0x08); - private static final BitField CHECK_INCONSISTENT_FORMULAS = BitFieldFactory.getInstance(0x10); - private static final BitField CHECK_DATETIME_FORMATS = BitFieldFactory.getInstance(0x20); - private static final BitField CHECK_UNPROTECTED_FORMULAS = BitFieldFactory.getInstance(0x40); - private static final BitField PERFORM_DATA_VALIDATION = BitFieldFactory.getInstance(0x80); - - /** - * What errors we should ignore - */ - private int errorCheck; - - - public FeatFormulaErr2() {} - - public FeatFormulaErr2(RecordInputStream in) { - errorCheck = in.readInt(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [FEATURE FORMULA ERRORS]\n"); - buffer.append(" checkCalculationErrors = "); - buffer.append(" checkEmptyCellRef = "); - buffer.append(" checkNumbersAsText = "); - buffer.append(" checkInconsistentRanges = "); - buffer.append(" checkInconsistentFormulas = "); - buffer.append(" checkDateTimeFormats = "); - buffer.append(" checkUnprotectedFormulas = "); - buffer.append(" performDataValidation = "); - buffer.append(" [/FEATURE FORMULA ERRORS]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(errorCheck); - } - - public int getDataSize() { - return 4; - } - - public int _getRawErrorCheckValue() { - return errorCheck; - } - - public boolean getCheckCalculationErrors() { - return CHECK_CALCULATION_ERRORS.isSet(errorCheck); - } - public void setCheckCalculationErrors(boolean checkCalculationErrors) { - errorCheck = CHECK_CALCULATION_ERRORS.setBoolean(errorCheck, checkCalculationErrors); - } - - public boolean getCheckEmptyCellRef() { - return CHECK_EMPTY_CELL_REF.isSet(errorCheck); - } - public void setCheckEmptyCellRef(boolean checkEmptyCellRef) { - errorCheck = CHECK_EMPTY_CELL_REF.setBoolean(errorCheck, checkEmptyCellRef); - } - - public boolean getCheckNumbersAsText() { - return CHECK_NUMBERS_AS_TEXT.isSet(errorCheck); - } - public void setCheckNumbersAsText(boolean checkNumbersAsText) { - errorCheck = CHECK_NUMBERS_AS_TEXT.setBoolean(errorCheck, checkNumbersAsText); - } - - public boolean getCheckInconsistentRanges() { - return CHECK_INCONSISTENT_RANGES.isSet(errorCheck); - } - public void setCheckInconsistentRanges(boolean checkInconsistentRanges) { - errorCheck = CHECK_INCONSISTENT_RANGES.setBoolean(errorCheck, checkInconsistentRanges); - } - - public boolean getCheckInconsistentFormulas() { - return CHECK_INCONSISTENT_FORMULAS.isSet(errorCheck); - } - public void setCheckInconsistentFormulas(boolean checkInconsistentFormulas) { - errorCheck = CHECK_INCONSISTENT_FORMULAS.setBoolean(errorCheck, checkInconsistentFormulas); - } - - public boolean getCheckDateTimeFormats() { - return CHECK_DATETIME_FORMATS.isSet(errorCheck); - } - public void setCheckDateTimeFormats(boolean checkDateTimeFormats) { - errorCheck = CHECK_DATETIME_FORMATS.setBoolean(errorCheck, checkDateTimeFormats); - } - - public boolean getCheckUnprotectedFormulas() { - return CHECK_UNPROTECTED_FORMULAS.isSet(errorCheck); - } - public void setCheckUnprotectedFormulas(boolean checkUnprotectedFormulas) { - errorCheck = CHECK_UNPROTECTED_FORMULAS.setBoolean(errorCheck, checkUnprotectedFormulas); - } - - public boolean getPerformDataValidation() { - return PERFORM_DATA_VALIDATION.isSet(errorCheck); - } - public void setPerformDataValidation(boolean performDataValidation) { - errorCheck = PERFORM_DATA_VALIDATION.setBoolean(errorCheck, performDataValidation); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java b/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java deleted file mode 100644 index a10d7119c..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.hssf.record.FeatRecord; -import org.apache.poi.hssf.record.PasswordRecord; -import org.apache.poi.hssf.record.PasswordRev4Record; -//import org.apache.poi.hssf.record.Feat11Record; -//import org.apache.poi.hssf.record.Feat12Record; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Title: FeatProtection (Protection Shared Feature) common record part - *

    - * This record part specifies Protection data for a sheet, stored - * as part of a Shared Feature. It can be found in records such - * as {@link FeatRecord} - */ -public final class FeatProtection implements SharedFeature { - public static long NO_SELF_RELATIVE_SECURITY_FEATURE = 0; - public static long HAS_SELF_RELATIVE_SECURITY_FEATURE = 1; - - private int fSD; - - /** - * 0 means no password. Otherwise indicates the - * password verifier algorithm (same kind as - * {@link PasswordRecord} and - * {@link PasswordRev4Record}) - */ - private int passwordVerifier; - - private String title; - private byte[] securityDescriptor; - - public FeatProtection() { - securityDescriptor = new byte[0]; - } - - public FeatProtection(RecordInputStream in) { - fSD = in.readInt(); - passwordVerifier = in.readInt(); - - title = StringUtil.readUnicodeString(in); - - securityDescriptor = in.readRemainder(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [FEATURE PROTECTION]\n"); - buffer.append(" Self Relative = " + fSD); - buffer.append(" Password Verifier = " + passwordVerifier); - buffer.append(" Title = " + title); - buffer.append(" Security Descriptor Size = " + securityDescriptor.length); - buffer.append(" [/FEATURE PROTECTION]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeInt(fSD); - out.writeInt(passwordVerifier); - StringUtil.writeUnicodeString(out, title); - out.write(securityDescriptor); - } - - public int getDataSize() { - return 4 + 4 + StringUtil.getEncodedSize(title) + securityDescriptor.length; - } - - public int getPasswordVerifier() { - return passwordVerifier; - } - public void setPasswordVerifier(int passwordVerifier) { - this.passwordVerifier = passwordVerifier; - } - - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } - - public int getFSD() { - return fSD; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java b/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java deleted file mode 100644 index f2e9cc69f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.hssf.record.FeatRecord; -//import org.apache.poi.hssf.record.Feat11Record; -//import org.apache.poi.hssf.record.Feat12Record; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: FeatSmartTag (Smart Tag Shared Feature) common record part - *

    - * This record part specifies Smart Tag data for a sheet, stored as part - * of a Shared Feature. It can be found in records such as {@link FeatRecord}. - * It is made up of a hash, and a set of Factoid Data that makes up - * the smart tags. - * For more details, see page 669 of the Excel binary file - * format documentation. - */ -public final class FeatSmartTag implements SharedFeature { - // TODO - process - private byte[] data; - - public FeatSmartTag() { - data = new byte[0]; - } - - public FeatSmartTag(RecordInputStream in) { - data = in.readRemainder(); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [FEATURE SMART TAGS]\n"); - buffer.append(" [/FEATURE SMART TAGS]\n"); - return buffer.toString(); - } - - public int getDataSize() { - return data.length; - } - - public void serialize(LittleEndianOutput out) { - out.write(data); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java b/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java deleted file mode 100644 index eecc541ca..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: FtrHeader (Future Record Header) common record part - *

    - * This record part specifies a header for a Ftr (Future) - * style record, which includes extra attributes above and - * beyond those of a traditional record. - */ -public final class FtrHeader implements Cloneable { - /** This MUST match the type on the containing record */ - private short recordType; - /** This is a FrtFlags */ - private short grbitFrt; - /** The range of cells the parent record applies to, or 0 if N/A */ - private CellRangeAddress associatedRange; - - public FtrHeader() { - associatedRange = new CellRangeAddress(0, 0, 0, 0); - } - - public FtrHeader(RecordInputStream in) { - recordType = in.readShort(); - grbitFrt = in.readShort(); - - associatedRange = new CellRangeAddress(in); - } - - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [FUTURE HEADER]\n"); - buffer.append(" Type " + recordType); - buffer.append(" Flags " + grbitFrt); - buffer.append(" [/FUTURE HEADER]\n"); - return buffer.toString(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(recordType); - out.writeShort(grbitFrt); - associatedRange.serialize(out); - } - - public static int getDataSize() { - return 12; - } - - public short getRecordType() { - return recordType; - } - public void setRecordType(short recordType) { - this.recordType = recordType; - } - - public short getGrbitFrt() { - return grbitFrt; - } - public void setGrbitFrt(short grbitFrt) { - this.grbitFrt = grbitFrt; - } - - public CellRangeAddress getAssociatedRange() { - return associatedRange; - } - public void setAssociatedRange(CellRangeAddress associatedRange) { - this.associatedRange = associatedRange; - } - - public Object clone() { - FtrHeader result = new FtrHeader(); - result.recordType = recordType; - result.grbitFrt = grbitFrt; - result.associatedRange = associatedRange.copy(); - return result; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/FutureRecord.java b/trunk/src/java/org/apache/poi/hssf/record/common/FutureRecord.java deleted file mode 100644 index 65a26cca7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/FutureRecord.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * Title: Future Record, a newer (largely Excel 2007+) record - * which contains a Future Record Header ({@link FtrHeader}) - */ -public interface FutureRecord { - public short getFutureRecordType(); - public FtrHeader getFutureHeader(); - public CellRangeAddress getAssociatedRange(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java b/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java deleted file mode 100644 index 1ce8bce1f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Common Interface for all Shared Features - */ -public interface SharedFeature { - public String toString(); - public void serialize(LittleEndianOutput out); - public int getDataSize(); -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java b/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java deleted file mode 100644 index 4cefdee10..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java +++ /dev/null @@ -1,826 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.common; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.cont.ContinuableRecordInput; -import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * Title: Unicode String

    - * Description: Unicode String - just standard fields that are in several records. - * It is considered more desirable then repeating it in all of them.

    - * This is often called a XLUnicodeRichExtendedString in MS documentation.

    - * REFERENCE: PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

    - * REFERENCE: PG 951 Excel Binary File Format (.xls) Structure Specification v20091214 - */ -public class UnicodeString implements Comparable { - // TODO - make this final when the compatibility version is removed - private static POILogger _logger = POILogFactory.getLogger(UnicodeString.class); - - private short field_1_charCount; - private byte field_2_optionflags; - private String field_3_string; - private List field_4_format_runs; - private ExtRst field_5_ext_rst; - private static final BitField highByte = BitFieldFactory.getInstance(0x1); - // 0x2 is reserved - private static final BitField extBit = BitFieldFactory.getInstance(0x4); - private static final BitField richText = BitFieldFactory.getInstance(0x8); - - public static class FormatRun implements Comparable { - final short _character; - short _fontIndex; - - public FormatRun(short character, short fontIndex) { - this._character = character; - this._fontIndex = fontIndex; - } - - public FormatRun(LittleEndianInput in) { - this(in.readShort(), in.readShort()); - } - - public short getCharacterPos() { - return _character; - } - - public short getFontIndex() { - return _fontIndex; - } - - public boolean equals(Object o) { - if (!(o instanceof FormatRun)) { - return false; - } - FormatRun other = ( FormatRun ) o; - - return _character == other._character && _fontIndex == other._fontIndex; - } - - public int compareTo(FormatRun r) { - if (_character == r._character && _fontIndex == r._fontIndex) { - return 0; - } - if (_character == r._character) { - return _fontIndex - r._fontIndex; - } - return _character - r._character; - } - - @Override - public int hashCode() { - assert false : "hashCode not designed"; - return 42; // any arbitrary constant will do - } - - public String toString() { - return "character="+_character+",fontIndex="+_fontIndex; - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(_character); - out.writeShort(_fontIndex); - } - } - - // See page 681 - public static class ExtRst implements Comparable { - private short reserved; - - // This is a Phs (see page 881) - private short formattingFontIndex; - private short formattingOptions; - - // This is a RPHSSub (see page 894) - private int numberOfRuns; - private String phoneticText; - - // This is an array of PhRuns (see page 881) - private PhRun[] phRuns; - // Sometimes there's some cruft at the end - private byte[] extraData; - - private void populateEmpty() { - reserved = 1; - phoneticText = ""; - phRuns = new PhRun[0]; - extraData = new byte[0]; - } - - protected ExtRst() { - populateEmpty(); - } - protected ExtRst(LittleEndianInput in, int expectedLength) { - reserved = in.readShort(); - - // Old style detection (Reserved = 0xFF) - if(reserved == -1) { - populateEmpty(); - return; - } - - // Spot corrupt records - if(reserved != 1) { - _logger.log(POILogger.WARN, "Warning - ExtRst has wrong magic marker, expecting 1 but found " + reserved + " - ignoring"); - // Grab all the remaining data, and ignore it - for(int i=0; i 0) { - length2 = 0; - } - if(length1 != length2) { - throw new IllegalStateException( - "The two length fields of the Phonetic Text don't agree! " + - length1 + " vs " + length2 - ); - } - phoneticText = StringUtil.readUnicodeLE(in, length1); - - int runData = stringDataSize - 4 - 6 - (2*phoneticText.length()); - int numRuns = (runData / 6); - phRuns = new PhRun[numRuns]; - for(int i=0; i 0)) { - field_4_format_runs = new ArrayList(runCount); - for (int i=0;i 0)) { - field_5_ext_rst = new ExtRst(new ContinuableRecordInput(in), extensionLength); - if(field_5_ext_rst.getDataSize()+4 != extensionLength) { - _logger.log(POILogger.WARN, "ExtRst was supposed to be " + extensionLength + " bytes long, but seems to actually be " + (field_5_ext_rst.getDataSize() + 4)); - } - } - } - - - - /** - * get the number of characters in the string, - * as an un-wrapped int - * - * @return number of characters - */ - public int getCharCount() { - if(field_1_charCount < 0) { - return field_1_charCount + 65536; - } - return field_1_charCount; - } - - /** - * get the number of characters in the string, - * wrapped as needed to fit within a short - * - * @return number of characters - */ - public short getCharCountShort() { - return field_1_charCount; - } - - /** - * set the number of characters in the string - * @param cc - number of characters - */ - - public void setCharCount(short cc) - { - field_1_charCount = cc; - } - - /** - * get the option flags which among other things return if this is a 16-bit or - * 8 bit string - * - * @return optionflags bitmask - * - */ - - public byte getOptionFlags() - { - return field_2_optionflags; - } - - /** - * set the option flags which among other things return if this is a 16-bit or - * 8 bit string - * - * @param of optionflags bitmask - * - */ - - public void setOptionFlags(byte of) - { - field_2_optionflags = of; - } - - /** - * @return the actual string this contains as a java String object - */ - public String getString() - { - return field_3_string; - } - - /** - * set the actual string this contains - * @param string the text - */ - - public void setString(String string) - { - field_3_string = string; - setCharCount((short)field_3_string.length()); - // scan for characters greater than 255 ... if any are - // present, we have to use 16-bit encoding. Otherwise, we - // can use 8-bit encoding - boolean useUTF16 = false; - int strlen = string.length(); - - for ( int j = 0; j < strlen; j++ ) { - if ( string.charAt( j ) > 255 ) { - useUTF16 = true; - break; - } - } - if (useUTF16) { - //Set the uncompressed bit - field_2_optionflags = highByte.setByte(field_2_optionflags); - } else { - field_2_optionflags = highByte.clearByte(field_2_optionflags); - } - } - - public int getFormatRunCount() { - return (field_4_format_runs == null) ? 0 : field_4_format_runs.size(); - } - - public FormatRun getFormatRun(int index) { - if (field_4_format_runs == null) { - return null; - } - if (index < 0 || index >= field_4_format_runs.size()) { - return null; - } - return field_4_format_runs.get(index); - } - - private int findFormatRunAt(int characterPos) { - int size = field_4_format_runs.size(); - for (int i=0;i characterPos) { - return -1; - } - } - return -1; - } - - /** Adds a font run to the formatted string. - * - * If a font run exists at the current charcter location, then it is - * replaced with the font run to be added. - */ - public void addFormatRun(FormatRun r) { - if (field_4_format_runs == null) { - field_4_format_runs = new ArrayList(); - } - - int index = findFormatRunAt(r._character); - if (index != -1) { - field_4_format_runs.remove(index); - } - - field_4_format_runs.add(r); - //Need to sort the font runs to ensure that the font runs appear in - //character order - Collections.sort(field_4_format_runs); - - //Make sure that we now say that we are a rich string - field_2_optionflags = richText.setByte(field_2_optionflags); - } - - public Iterator formatIterator() { - if (field_4_format_runs != null) { - return field_4_format_runs.iterator(); - } - return null; - } - - public void removeFormatRun(FormatRun r) { - field_4_format_runs.remove(r); - if (field_4_format_runs.size() == 0) { - field_4_format_runs = null; - field_2_optionflags = richText.clearByte(field_2_optionflags); - } - } - - public void clearFormatting() { - field_4_format_runs = null; - field_2_optionflags = richText.clearByte(field_2_optionflags); - } - - - public ExtRst getExtendedRst() { - return this.field_5_ext_rst; - } - void setExtendedRst(ExtRst ext_rst) { - if (ext_rst != null) { - field_2_optionflags = extBit.setByte(field_2_optionflags); - } else { - field_2_optionflags = extBit.clearByte(field_2_optionflags); - } - this.field_5_ext_rst = ext_rst; - } - - - /** - * Swaps all use in the string of one font index - * for use of a different font index. - * Normally only called when fonts have been - * removed / re-ordered - */ - public void swapFontUse(short oldFontIndex, short newFontIndex) { - for (FormatRun run : field_4_format_runs) { - if(run._fontIndex == oldFontIndex) { - run._fontIndex = newFontIndex; - } - } - } - - /** - * unlike the real records we return the same as "getString()" rather than debug info - * @see #getDebugInfo() - * @return String value of the record - */ - - public String toString() - { - return getString(); - } - - /** - * return a character representation of the fields of this record - * - * - * @return String of output for biffviewer etc. - * - */ - public String getDebugInfo() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[UNICODESTRING]\n"); - buffer.append(" .charcount = ") - .append(Integer.toHexString(getCharCount())).append("\n"); - buffer.append(" .optionflags = ") - .append(Integer.toHexString(getOptionFlags())).append("\n"); - buffer.append(" .string = ").append(getString()).append("\n"); - if (field_4_format_runs != null) { - for (int i = 0; i < field_4_format_runs.size();i++) { - FormatRun r = field_4_format_runs.get(i); - buffer.append(" .format_run"+i+" = ").append(r.toString()).append("\n"); - } - } - if (field_5_ext_rst != null) { - buffer.append(" .field_5_ext_rst = ").append("\n"); - buffer.append( field_5_ext_rst.toString() ).append("\n"); - } - buffer.append("[/UNICODESTRING]\n"); - return buffer.toString(); - } - - /** - * Serialises out the String. There are special rules - * about where we can and can't split onto - * Continue records. - */ - public void serialize(ContinuableRecordOutput out) { - int numberOfRichTextRuns = 0; - int extendedDataSize = 0; - if (isRichText() && field_4_format_runs != null) { - numberOfRichTextRuns = field_4_format_runs.size(); - } - if (isExtendedText() && field_5_ext_rst != null) { - extendedDataSize = 4 + field_5_ext_rst.getDataSize(); - } - - // Serialise the bulk of the String - // The writeString handles tricky continue stuff for us - out.writeString(field_3_string, numberOfRichTextRuns, extendedDataSize); - - if (numberOfRichTextRuns > 0) { - - //This will ensure that a run does not split a continue - for (int i=0;i 0) { - field_5_ext_rst.serialize(out); - } - } - - public int compareTo(UnicodeString str) { - - int result = getString().compareTo(str.getString()); - - //As per the equals method lets do this in stages - if (result != 0) { - return result; - } - - //OK string appears to be equal but now lets compare formatting runs - if (field_4_format_runs == null) { - //Strings are equal, and there are no formatting runs. -> 0 - //Strings are equal, but one or the other has formatting runs -> 1 - return (str.field_4_format_runs == null) ? 0 : 1; - } else if (str.field_4_format_runs == null) { - //Strings are equal, but one or the other has formatting runs - return -1; - } - - //Strings are equal, so now compare formatting runs. - int size = field_4_format_runs.size(); - if (size != str.field_4_format_runs.size()) { - return size - str.field_4_format_runs.size(); - } - - for (int i=0;i(); - for (FormatRun r : field_4_format_runs) { - str.field_4_format_runs.add(new FormatRun(r._character, r._fontIndex)); - } - } - if (field_5_ext_rst != null) { - str.field_5_ext_rst = field_5_ext_rst.clone(); - } - - return str; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java b/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java deleted file mode 100644 index 88399074a..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cont; - -import org.apache.poi.hssf.record.ContinueRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Common superclass of all records that can produce {@link ContinueRecord}s while being serialized. - */ -public abstract class ContinuableRecord extends Record { - - protected ContinuableRecord() { - // no fields to initialise - } - /** - * Serializes this record's content to the supplied data output.

    - * The standard BIFF header (ushort sid, ushort size) has been handled by the superclass, so - * only BIFF data should be written by this method. Simple data types can be written with the - * standard {@link LittleEndianOutput} methods. Methods from {@link ContinuableRecordOutput} - * can be used to serialize strings (with {@link ContinueRecord}s being written as required). - * If necessary, implementors can explicitly start {@link ContinueRecord}s (regardless of the - * amount of remaining space). - * - * @param out a data output stream - */ - protected abstract void serialize(ContinuableRecordOutput out); - - - /** - * @return the total length of the encoded record(s) - * (Note - if any {@link ContinueRecord} is required, this result includes the - * size of those too) - */ - public final int getRecordSize() { - ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly(); - serialize(out); - out.terminate(); - return out.getTotalSize(); - } - - public final int serialize(int offset, byte[] data) { - - LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset); - ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid()); - serialize(out); - out.terminate(); - return out.getTotalSize(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordInput.java b/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordInput.java deleted file mode 100644 index ecd8d4b59..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordInput.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.hssf.record.cont; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.ContinueRecord; -import org.apache.poi.util.LittleEndianInput; - -/** - * A decorated {@link RecordInputStream} that can read primitive data types - * (short, int, long, etc.) spanned across a {@link ContinueRecord } boundary. - * - *

    - * Most records construct themselves from {@link RecordInputStream}. - * This class assumes that a {@link ContinueRecord} record break always occurs at the type boundary, - * however, it is not always so. - *

    - * Two attachments to Bugzilla 50779 - * demonstrate that a CONTINUE break can appear right in between two bytes of a unicode character - * or between two bytes of a short. The problematic portion of the data is - * in a Asian Phonetic Settings Block (ExtRst) of a UnicodeString. - *

    - * {@link RecordInputStream} greedily requests the bytes to be read and stumbles on such files with a - * "Not enough data (1) to read requested (2) bytes" exception. The ContinuableRecordInput - * class circumvents this "type boundary" rule and reads data byte-by-byte rolling over CONTINUE if necessary. - *

    - * - *

    - * YK: For now (March 2011) this class is only used to read - * @link org.apache.poi.hssf.record.common.UnicodeString.ExtRst} blocks of a UnicodeString. - * - *

    - */ -public class ContinuableRecordInput implements LittleEndianInput { - private final RecordInputStream _in; - - public ContinuableRecordInput(RecordInputStream in){ - _in = in; - } - @Override - public int available(){ - return _in.available(); - } - - @Override - public byte readByte(){ - return _in.readByte(); - } - - @Override - public int readUByte(){ - return _in.readUByte(); - } - - @Override - public short readShort(){ - return _in.readShort(); - } - - @Override - public int readUShort(){ - int ch1 = readUByte(); - int ch2 = readUByte(); - return (ch2 << 8) + (ch1 << 0); - } - - @Override - public int readInt(){ - int ch1 = _in.readUByte(); - int ch2 = _in.readUByte(); - int ch3 = _in.readUByte(); - int ch4 = _in.readUByte(); - return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); - } - - @Override - public long readLong(){ - int b0 = _in.readUByte(); - int b1 = _in.readUByte(); - int b2 = _in.readUByte(); - int b3 = _in.readUByte(); - int b4 = _in.readUByte(); - int b5 = _in.readUByte(); - int b6 = _in.readUByte(); - int b7 = _in.readUByte(); - return (((long)b7 << 56) + - ((long)b6 << 48) + - ((long)b5 << 40) + - ((long)b4 << 32) + - ((long)b3 << 24) + - (b2 << 16) + - (b1 << 8) + - (b0 << 0)); - } - - @Override - public double readDouble(){ - return _in.readDouble(); - } - - @Override - public void readFully(byte[] buf){ - _in.readFully(buf); - } - - @Override - public void readFully(byte[] buf, int off, int len){ - _in.readFully(buf, off, len); - } - - @Override - public void readPlain(byte[] buf, int off, int len) { - readFully(buf, off, len); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java b/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java deleted file mode 100644 index a39f1393e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java +++ /dev/null @@ -1,272 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cont; - -import org.apache.poi.hssf.record.ContinueRecord; -import org.apache.poi.util.DelayableLittleEndianOutput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s. - * This class keeps track of how much remaining space is available in the current BIFF record and - * can start new {@link ContinueRecord}s as required. - */ -public final class ContinuableRecordOutput implements LittleEndianOutput { - - private final LittleEndianOutput _out; - private UnknownLengthRecordOutput _ulrOutput; - private int _totalPreviousRecordsSize; - - public ContinuableRecordOutput(LittleEndianOutput out, int sid) { - _ulrOutput = new UnknownLengthRecordOutput(out, sid); - _out = out; - _totalPreviousRecordsSize = 0; - } - - public static ContinuableRecordOutput createForCountingOnly() { - return new ContinuableRecordOutput(NOPOutput, -777); // fake sid - } - - /** - * @return total number of bytes written so far (including all BIFF headers) - */ - public int getTotalSize() { - return _totalPreviousRecordsSize + _ulrOutput.getTotalSize(); - } - /** - * Terminates the last record (also updates its 'ushort size' field) - */ - void terminate() { - _ulrOutput.terminate(); - } - /** - * @return number of remaining bytes of space in current record - */ - public int getAvailableSpace() { - return _ulrOutput.getAvailableSpace(); - } - - /** - * Terminates the current record and starts a new {@link ContinueRecord} (regardless - * of how much space is still available in the current record). - */ - public void writeContinue() { - _ulrOutput.terminate(); - _totalPreviousRecordsSize += _ulrOutput.getTotalSize(); - _ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid); - } - /** - * Will terminate the current record and start a new {@link ContinueRecord} - * if there isn't space for the requested number of bytes - * @param requiredContinuousSize The number of bytes that need to be written - */ - public void writeContinueIfRequired(int requiredContinuousSize) { - if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) { - writeContinue(); - } - } - - /** - * Writes the 'optionFlags' byte and encoded character data of a unicode string. This includes: - *
      - *
    • byte optionFlags
    • - *
    • encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)
    • - *
    - * - * Notes: - *
      - *
    • The value of the 'is16bitEncoded' flag is determined by the actual character data - * of text
    • - *
    • The string options flag is never separated (by a {@link ContinueRecord}) from the - * first chunk of character data it refers to.
    • - *
    • The 'ushort length' field is assumed to have been explicitly written earlier. Hence, - * there may be an intervening {@link ContinueRecord}
    • - *
    - */ - public void writeStringData(String text) { - boolean is16bitEncoded = StringUtil.hasMultibyte(text); - // calculate total size of the header and first encoded char - int keepTogetherSize = 1 + 1; // ushort len, at least one character byte - int optionFlags = 0x00; - if (is16bitEncoded) { - optionFlags |= 0x01; - keepTogetherSize += 1; // one extra byte for first char - } - writeContinueIfRequired(keepTogetherSize); - writeByte(optionFlags); - writeCharacterData(text, is16bitEncoded); - } - /** - * Writes a unicode string complete with header and character data. This includes: - *
      - *
    • ushort length
    • - *
    • byte optionFlags
    • - *
    • ushort numberOfRichTextRuns (optional)
    • - *
    • ushort extendedDataSize (optional)
    • - *
    • encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)
    • - *
    - * - * The following bits of the 'optionFlags' byte will be set as appropriate: - * - * - * - * - * - *
    MaskDescription
    0x01is16bitEncoded
    0x04hasExtendedData
    0x08isRichText
    - * Notes: - *
      - *
    • The value of the 'is16bitEncoded' flag is determined by the actual character data - * of text
    • - *
    • The string header fields are never separated (by a {@link ContinueRecord}) from the - * first chunk of character data (i.e. the first character is always encoded in the same - * record as the string header).
    • - *
    - */ - public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) { - boolean is16bitEncoded = StringUtil.hasMultibyte(text); - // calculate total size of the header and first encoded char - int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte - int optionFlags = 0x00; - if (is16bitEncoded) { - optionFlags |= 0x01; - keepTogetherSize += 1; // one extra byte for first char - } - if (numberOfRichTextRuns > 0) { - optionFlags |= 0x08; - keepTogetherSize += 2; - } - if (extendedDataSize > 0) { - optionFlags |= 0x04; - keepTogetherSize += 4; - } - writeContinueIfRequired(keepTogetherSize); - writeShort(text.length()); - writeByte(optionFlags); - if (numberOfRichTextRuns > 0) { - writeShort(numberOfRichTextRuns); - } - if (extendedDataSize > 0) { - writeInt(extendedDataSize); - } - writeCharacterData(text, is16bitEncoded); - } - - - private void writeCharacterData(String text, boolean is16bitEncoded) { - int nChars = text.length(); - int i=0; - if (is16bitEncoded) { - while(true) { - int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2); - for ( ; nWritableChars > 0; nWritableChars--) { - _ulrOutput.writeShort(text.charAt(i++)); - } - if (i >= nChars) { - break; - } - writeContinue(); - writeByte(0x01); - } - } else { - while(true) { - int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1); - for ( ; nWritableChars > 0; nWritableChars--) { - _ulrOutput.writeByte(text.charAt(i++)); - } - if (i >= nChars) { - break; - } - writeContinue(); - writeByte(0x00); - } - } - } - - public void write(byte[] b) { - writeContinueIfRequired(b.length); - _ulrOutput.write(b); - } - - public void write(byte[] b, int offset, int len) { - - int i=0; - while(true) { - int nWritableChars = Math.min(len - i, _ulrOutput.getAvailableSpace() / 1); - for ( ; nWritableChars > 0; nWritableChars--) { - _ulrOutput.writeByte(b[offset + i++]); - } - if (i >= len) { - break; - } - writeContinue(); - } - } - - public void writeByte(int v) { - writeContinueIfRequired(1); - _ulrOutput.writeByte(v); - } - public void writeDouble(double v) { - writeContinueIfRequired(8); - _ulrOutput.writeDouble(v); - } - public void writeInt(int v) { - writeContinueIfRequired(4); - _ulrOutput.writeInt(v); - } - public void writeLong(long v) { - writeContinueIfRequired(8); - _ulrOutput.writeLong(v); - } - public void writeShort(int v) { - writeContinueIfRequired(2); - _ulrOutput.writeShort(v); - } - - /** - * Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only. - */ - private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() { - - public LittleEndianOutput createDelayedOutput(int size) { - return this; - } - public void write(byte[] b) { - // does nothing - } - public void write(byte[] b, int offset, int len) { - // does nothing - } - public void writeByte(int v) { - // does nothing - } - public void writeDouble(double v) { - // does nothing - } - public void writeInt(int v) { - // does nothing - } - public void writeLong(long v) { - // does nothing - } - public void writeShort(int v) { - // does nothing - } - }; -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java b/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java deleted file mode 100644 index 5e5206ff1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.cont; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.DelayableLittleEndianOutput; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianOutput; -/** - * Allows the writing of BIFF records when the 'ushort size' header field is not known in advance. - * When the client is finished writing data, it calls {@link #terminate()}, at which point this - * class updates the 'ushort size' with its final value. - */ -final class UnknownLengthRecordOutput implements LittleEndianOutput { - private static final int MAX_DATA_SIZE = RecordInputStream.MAX_RECORD_DATA_SIZE; - - private final LittleEndianOutput _originalOut; - /** for writing the 'ushort size' field once its value is known */ - private final LittleEndianOutput _dataSizeOutput; - private final byte[] _byteBuffer; - private LittleEndianOutput _out; - private int _size; - - public UnknownLengthRecordOutput(LittleEndianOutput out, int sid) { - _originalOut = out; - out.writeShort(sid); - if (out instanceof DelayableLittleEndianOutput) { - // optimisation - DelayableLittleEndianOutput dleo = (DelayableLittleEndianOutput) out; - _dataSizeOutput = dleo.createDelayedOutput(2); - _byteBuffer = null; - _out = out; - } else { - // otherwise temporarily write all subsequent data to a buffer - _dataSizeOutput = out; - _byteBuffer = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE]; - _out = new LittleEndianByteArrayOutputStream(_byteBuffer, 0); - } - } - /** - * includes 4 byte header - */ - public int getTotalSize() { - return 4 + _size; - } - public int getAvailableSpace() { - if (_out == null) { - throw new IllegalStateException("Record already terminated"); - } - return MAX_DATA_SIZE - _size; - } - /** - * Finishes writing the current record and updates 'ushort size' field.
    - * After this method is called, only {@link #getTotalSize()} may be called. - */ - public void terminate() { - if (_out == null) { - throw new IllegalStateException("Record already terminated"); - } - _dataSizeOutput.writeShort(_size); - if (_byteBuffer != null) { - _originalOut.write(_byteBuffer, 0, _size); - _out = null; - return; - } - _out = null; - } - - public void write(byte[] b) { - _out.write(b); - _size += b.length; - } - public void write(byte[] b, int offset, int len) { - _out.write(b, offset, len); - _size += len; - } - public void writeByte(int v) { - _out.writeByte(v); - _size += 1; - } - public void writeDouble(double v) { - _out.writeDouble(v); - _size += 8; - } - public void writeInt(int v) { - _out.writeInt(v); - _size += 4; - } - public void writeLong(long v) { - _out.writeLong(v); - _size += 8; - } - public void writeShort(int v) { - _out.writeShort(v); - _size += 2; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java b/trunk/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java deleted file mode 100644 index cef3102ff..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.crypto; - -import java.io.InputStream; -import java.io.PushbackInputStream; - -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BiffHeaderInput; -import org.apache.poi.hssf.record.FilePassRecord; -import org.apache.poi.hssf.record.InterfaceHdrRecord; -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.LittleEndianInput; - -public final class Biff8DecryptingStream implements BiffHeaderInput, LittleEndianInput { - - public static final int RC4_REKEYING_INTERVAL = 1024; - - private final EncryptionInfo info; - private ChunkedCipherInputStream ccis; - private final byte buffer[] = new byte[LittleEndianConsts.LONG_SIZE]; - private boolean shouldSkipEncryptionOnCurrentRecord = false; - - public Biff8DecryptingStream(InputStream in, int initialOffset, EncryptionInfo info) throws RecordFormatException { - try { - byte initialBuf[] = new byte[initialOffset]; - InputStream stream; - if (initialOffset == 0) { - stream = in; - } else { - stream = new PushbackInputStream(in, initialOffset); - ((PushbackInputStream)stream).unread(initialBuf); - } - - this.info = info; - Decryptor dec = this.info.getDecryptor(); - dec.setChunkSize(RC4_REKEYING_INTERVAL); - ccis = (ChunkedCipherInputStream)dec.getDataStream(stream, Integer.MAX_VALUE, 0); - - if (initialOffset > 0) { - ccis.readFully(initialBuf); - } - } catch (Exception e) { - throw new RecordFormatException(e); - } - } - - @Override - public int available() { - return ccis.available(); - } - - /** - * Reads an unsigned short value without decrypting - */ - @Override - public int readRecordSID() { - readPlain(buffer, 0, LittleEndianConsts.SHORT_SIZE); - int sid = LittleEndian.getUShort(buffer, 0); - shouldSkipEncryptionOnCurrentRecord = isNeverEncryptedRecord(sid); - return sid; - } - - /** - * Reads an unsigned short value without decrypting - */ - @Override - public int readDataSize() { - readPlain(buffer, 0, LittleEndianConsts.SHORT_SIZE); - int dataSize = LittleEndian.getUShort(buffer, 0); - ccis.setNextRecordSize(dataSize); - return dataSize; - } - - @Override - public double readDouble() { - long valueLongBits = readLong(); - double result = Double.longBitsToDouble(valueLongBits); - if (Double.isNaN(result)) { - // (Because Excel typically doesn't write NaN - throw new RuntimeException("Did not expect to read NaN"); - } - return result; - } - - @Override - public void readFully(byte[] buf) { - readFully(buf, 0, buf.length); - } - - @Override - public void readFully(byte[] buf, int off, int len) { - if (shouldSkipEncryptionOnCurrentRecord) { - readPlain(buf, off, buf.length); - } else { - ccis.readFully(buf, off, len); - } - } - - @Override - public int readUByte() { - return readByte() & 0xFF; - } - - @Override - public byte readByte() { - if (shouldSkipEncryptionOnCurrentRecord) { - readPlain(buffer, 0, LittleEndianConsts.BYTE_SIZE); - return buffer[0]; - } else { - return ccis.readByte(); - } - } - - @Override - public int readUShort() { - return readShort() & 0xFFFF; - } - - @Override - public short readShort() { - if (shouldSkipEncryptionOnCurrentRecord) { - readPlain(buffer, 0, LittleEndianConsts.SHORT_SIZE); - return LittleEndian.getShort(buffer); - } else { - return ccis.readShort(); - } - } - - @Override - public int readInt() { - if (shouldSkipEncryptionOnCurrentRecord) { - readPlain(buffer, 0, LittleEndianConsts.INT_SIZE); - return LittleEndian.getInt(buffer); - } else { - return ccis.readInt(); - } - } - - @Override - public long readLong() { - if (shouldSkipEncryptionOnCurrentRecord) { - readPlain(buffer, 0, LittleEndianConsts.LONG_SIZE); - return LittleEndian.getLong(buffer); - } else { - return ccis.readLong(); - } - } - - /** - * @return the absolute position in the stream - */ - public long getPosition() { - return ccis.getPos(); - } - - /** - * TODO: Additionally, the lbPlyPos (position_of_BOF) field of the BoundSheet8 record MUST NOT be encrypted. - * - * @return true if record type specified by sid is never encrypted - */ - public static boolean isNeverEncryptedRecord(int sid) { - switch (sid) { - case BOFRecord.sid: - // sheet BOFs for sure - // TODO - find out about chart BOFs - - case InterfaceHdrRecord.sid: - // don't know why this record doesn't seem to get encrypted - - case FilePassRecord.sid: - // this only really counts when writing because FILEPASS is read early - - // UsrExcl(0x0194) - // FileLock - // RRDInfo(0x0196) - // RRDHead(0x0138) - - return true; - - default: - return false; - } - } - - @Override - public void readPlain(byte b[], int off, int len) { - ccis.readPlain(b, off, len); - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java b/trunk/src/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java deleted file mode 100644 index 382ae2f13..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/crypto/Biff8EncryptionKey.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.record.crypto; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -public final class Biff8EncryptionKey { - /** - * Stores the BIFF8 encryption/decryption password for the current thread. This has been done - * using a {@link ThreadLocal} in order to avoid further overloading the various public APIs - * (e.g. {@link HSSFWorkbook}) that need this functionality. - */ - private static final ThreadLocal _userPasswordTLS = new ThreadLocal(); - - /** - * Sets the BIFF8 encryption/decryption password for the current thread. - * - * @param password pass null to clear user password (and use default) - */ - public static void setCurrentUserPassword(String password) { - _userPasswordTLS.set(password); - } - - /** - * @return the BIFF8 encryption/decryption password for the current thread. - * null if it is currently unset. - */ - public static String getCurrentUserPassword() { - return _userPasswordTLS.get(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/package.html b/trunk/src/java/org/apache/poi/hssf/record/package.html deleted file mode 100644 index 446535891..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/package.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - -Record package contains class representations for XLS binary strutures. Its very -low level. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.hssf.eventmodel -@see org.apache.poi.hssf.record.RecordFactory - - diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java deleted file mode 100644 index 05cf6a675..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * SXDI - Data Item (0x00C5)
    - * - * @author Patrick Cheng - */ -public final class DataItemRecord extends StandardRecord { - public static final short sid = 0x00C5; - - private int isxvdData; - private int iiftab; - private int df; - private int isxvd; - private int isxvi; - private int ifmt; - private String name; - - public DataItemRecord(RecordInputStream in) { - isxvdData = in.readUShort(); - iiftab = in.readUShort(); - df = in.readUShort(); - isxvd = in.readUShort(); - isxvi = in.readUShort(); - ifmt = in.readUShort(); - - name = in.readString(); - } - - @Override - protected void serialize(LittleEndianOutput out) { - - out.writeShort(isxvdData); - out.writeShort(iiftab); - out.writeShort(df); - out.writeShort(isxvd); - out.writeShort(isxvi); - out.writeShort(ifmt); - - StringUtil.writeUnicodeString(out, name); - } - - @Override - protected int getDataSize() { - return 2 + 2 + 2 + 2 + 2 + 2 + StringUtil.getEncodedSize(name); - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SXDI]\n"); - buffer.append(" .isxvdData = ").append(HexDump.shortToHex(isxvdData)).append("\n"); - buffer.append(" .iiftab = ").append(HexDump.shortToHex(iiftab)).append("\n"); - buffer.append(" .df = ").append(HexDump.shortToHex(df)).append("\n"); - buffer.append(" .isxvd = ").append(HexDump.shortToHex(isxvd)).append("\n"); - buffer.append(" .isxvi = ").append(HexDump.shortToHex(isxvi)).append("\n"); - buffer.append(" .ifmt = ").append(HexDump.shortToHex(ifmt)).append("\n"); - buffer.append("[/SXDI]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java deleted file mode 100644 index 70c9ebcc1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * SXVDEX - Extended PivotTable View Fields (0x0100)
    - * - * @author Patrick Cheng - */ -public final class ExtendedPivotTableViewFieldsRecord extends StandardRecord { - public static final short sid = 0x0100; - - /** the value of the subname length when the {@link #_subtotalName} is not present */ - private static final int STRING_NOT_PRESENT_LEN = 0xFFFF; - - private int _grbit1; - private int _grbit2; - private int _citmShow; - private int _isxdiSort; - private int _isxdiShow; - private int _reserved1; - private int _reserved2; - /** custom sub-total name */ - private String _subtotalName; - - public ExtendedPivotTableViewFieldsRecord(RecordInputStream in) { - - _grbit1 = in.readInt(); - _grbit2 = in.readUByte(); - _citmShow = in.readUByte(); - _isxdiSort = in.readUShort(); - _isxdiShow = in.readUShort(); - // This record seems to have different valid encodings - switch (in.remaining()) { - case 0: - // as per "Microsoft Excel Developer's Kit" book - // older version of SXVDEX - doesn't seem to have a sub-total name - _reserved1 = 0; - _reserved2 = 0; - _subtotalName = null; - return; - case 10: - // as per "MICROSOFT OFFICE EXCEL 97-2007 BINARY FILE FORMAT SPECIFICATION" pdf - break; - default: - throw new RecordFormatException("Unexpected remaining size (" + in.remaining() + ")"); - } - int cchSubName = in.readUShort(); - _reserved1 = in.readInt(); - _reserved2 = in.readInt(); - if (cchSubName != STRING_NOT_PRESENT_LEN) { - _subtotalName = in.readUnicodeLEString(cchSubName); - } - } - - @Override - protected void serialize(LittleEndianOutput out) { - - out.writeInt(_grbit1); - out.writeByte(_grbit2); - out.writeByte(_citmShow); - out.writeShort(_isxdiSort); - out.writeShort(_isxdiShow); - - if (_subtotalName == null) { - out.writeShort(STRING_NOT_PRESENT_LEN); - } else { - out.writeShort(_subtotalName.length()); - } - - out.writeInt(_reserved1); - out.writeInt(_reserved2); - if (_subtotalName != null) { - StringUtil.putUnicodeLE(_subtotalName, out); - } - } - - @Override - protected int getDataSize() { - - return 4 + 1 + 1 + 2 + 2 + 2 + 4 + 4 + - (_subtotalName == null ? 0 : (2*_subtotalName.length())); // in unicode - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SXVDEX]\n"); - - buffer.append(" .grbit1 =").append(HexDump.intToHex(_grbit1)).append("\n"); - buffer.append(" .grbit2 =").append(HexDump.byteToHex(_grbit2)).append("\n"); - buffer.append(" .citmShow =").append(HexDump.byteToHex(_citmShow)).append("\n"); - buffer.append(" .isxdiSort =").append(HexDump.shortToHex(_isxdiSort)).append("\n"); - buffer.append(" .isxdiShow =").append(HexDump.shortToHex(_isxdiShow)).append("\n"); - buffer.append(" .subtotalName =").append(_subtotalName).append("\n"); - buffer.append("[/SXVDEX]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java deleted file mode 100644 index ebcb843cc..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * SXPI - Page Item (0x00B6)
    - * - * @author Patrick Cheng - */ -public final class PageItemRecord extends StandardRecord { - public static final short sid = 0x00B6; - - private static final class FieldInfo { - public static final int ENCODED_SIZE = 6; - /** Index to the View Item SXVI(0x00B2) record */ - private int _isxvi; - /** Index to the {@link ViewFieldsRecord} SXVD(0x00B1) record */ - private int _isxvd; - /** Object ID for the drop-down arrow */ - private int _idObj; - - public FieldInfo(RecordInputStream in) { - _isxvi = in.readShort(); - _isxvd = in.readShort(); - _idObj = in.readShort(); - } - - protected void serialize(LittleEndianOutput out) { - out.writeShort(_isxvi); - out.writeShort(_isxvd); - out.writeShort(_idObj); - } - - public void appendDebugInfo(StringBuffer sb) { - sb.append('('); - sb.append( "isxvi=").append(HexDump.shortToHex(_isxvi)); - sb.append(" isxvd=").append(HexDump.shortToHex(_isxvd)); - sb.append(" idObj=").append(HexDump.shortToHex(_idObj)); - sb.append(')'); - } - } - - private final FieldInfo[] _fieldInfos; - - public PageItemRecord(RecordInputStream in) { - int dataSize = in.remaining(); - if (dataSize % FieldInfo.ENCODED_SIZE != 0) { - throw new RecordFormatException("Bad data size " + dataSize); - } - - int nItems = dataSize / FieldInfo.ENCODED_SIZE; - - FieldInfo[] fis = new FieldInfo[nItems]; - for (int i = 0; i < fis.length; i++) { - fis[i] = new FieldInfo(in); - } - _fieldInfos = fis; - } - - @Override - protected void serialize(LittleEndianOutput out) { - for (int i = 0; i < _fieldInfos.length; i++) { - _fieldInfos[i].serialize(out); - } - } - - @Override - protected int getDataSize() { - return _fieldInfos.length * FieldInfo.ENCODED_SIZE; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("[SXPI]\n"); - for (int i = 0; i < _fieldInfos.length; i++) { - sb.append(" item[").append(i).append("]="); - _fieldInfos[i].appendDebugInfo(sb); - sb.append('\n'); - } - sb.append("[/SXPI]\n"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java deleted file mode 100644 index bd7290078..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * SXIDSTM - Stream ID (0x00D5)
    - * - * @author Patrick Cheng - */ -public final class StreamIDRecord extends StandardRecord { - public static final short sid = 0x00D5; - - private int idstm; - - public StreamIDRecord(RecordInputStream in) { - idstm = in.readShort(); - } - - @Override - protected void serialize(LittleEndianOutput out) { - out.writeShort(idstm); - } - - @Override - protected int getDataSize() { - return 2; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SXIDSTM]\n"); - buffer.append(" .idstm =").append(HexDump.shortToHex(idstm)).append('\n'); - - buffer.append("[/SXIDSTM]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java deleted file mode 100644 index 3c37924f9..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java +++ /dev/null @@ -1,160 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * SXVIEW - View Definition (0x00B0)
    - */ -public final class ViewDefinitionRecord extends StandardRecord { - public static final short sid = 0x00B0; - - private int rwFirst; - private int rwLast; - private int colFirst; - private int colLast; - private int rwFirstHead; - private int rwFirstData; - private int colFirstData; - private int iCache; - private int reserved; - - private int sxaxis4Data; - private int ipos4Data; - private int cDim; - - private int cDimRw; - - private int cDimCol; - private int cDimPg; - - private int cDimData; - private int cRw; - private int cCol; - private int grbit; - private int itblAutoFmt; - - private String dataField; - private String name; - - - public ViewDefinitionRecord(RecordInputStream in) { - rwFirst = in.readUShort(); - rwLast = in.readUShort(); - colFirst = in.readUShort(); - colLast = in.readUShort(); - rwFirstHead = in.readUShort(); - rwFirstData = in.readUShort(); - colFirstData = in.readUShort(); - iCache = in.readUShort(); - reserved = in.readUShort(); - sxaxis4Data = in.readUShort(); - ipos4Data = in.readUShort(); - cDim = in.readUShort(); - cDimRw = in.readUShort(); - cDimCol = in.readUShort(); - cDimPg = in.readUShort(); - cDimData = in.readUShort(); - cRw = in.readUShort(); - cCol = in.readUShort(); - grbit = in.readUShort(); - itblAutoFmt = in.readUShort(); - int cchName = in.readUShort(); - int cchData = in.readUShort(); - - name = StringUtil.readUnicodeString(in, cchName); - dataField = StringUtil.readUnicodeString(in, cchData); - } - - @Override - protected void serialize(LittleEndianOutput out) { - out.writeShort(rwFirst); - out.writeShort(rwLast); - out.writeShort(colFirst); - out.writeShort(colLast); - out.writeShort(rwFirstHead); - out.writeShort(rwFirstData); - out.writeShort(colFirstData); - out.writeShort(iCache); - out.writeShort(reserved); - out.writeShort(sxaxis4Data); - out.writeShort(ipos4Data); - out.writeShort(cDim); - out.writeShort(cDimRw); - out.writeShort(cDimCol); - out.writeShort(cDimPg); - out.writeShort(cDimData); - out.writeShort(cRw); - out.writeShort(cCol); - out.writeShort(grbit); - out.writeShort(itblAutoFmt); - out.writeShort(name.length()); - out.writeShort(dataField.length()); - - StringUtil.writeUnicodeStringFlagAndData(out, name); - StringUtil.writeUnicodeStringFlagAndData(out, dataField); - } - - @Override - protected int getDataSize() { - return 40 + // 20 short fields (rwFirst ... itblAutoFmt) - StringUtil.getEncodedSize(name) + StringUtil.getEncodedSize(dataField) ; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SXVIEW]\n"); - buffer.append(" .rwFirst =").append(HexDump.shortToHex(rwFirst)).append('\n'); - buffer.append(" .rwLast =").append(HexDump.shortToHex(rwLast)).append('\n'); - buffer.append(" .colFirst =").append(HexDump.shortToHex(colFirst)).append('\n'); - buffer.append(" .colLast =").append(HexDump.shortToHex(colLast)).append('\n'); - buffer.append(" .rwFirstHead =").append(HexDump.shortToHex(rwFirstHead)).append('\n'); - buffer.append(" .rwFirstData =").append(HexDump.shortToHex(rwFirstData)).append('\n'); - buffer.append(" .colFirstData =").append(HexDump.shortToHex(colFirstData)).append('\n'); - buffer.append(" .iCache =").append(HexDump.shortToHex(iCache)).append('\n'); - buffer.append(" .reserved =").append(HexDump.shortToHex(reserved)).append('\n'); - buffer.append(" .sxaxis4Data =").append(HexDump.shortToHex(sxaxis4Data)).append('\n'); - buffer.append(" .ipos4Data =").append(HexDump.shortToHex(ipos4Data)).append('\n'); - buffer.append(" .cDim =").append(HexDump.shortToHex(cDim)).append('\n'); - buffer.append(" .cDimRw =").append(HexDump.shortToHex(cDimRw)).append('\n'); - buffer.append(" .cDimCol =").append(HexDump.shortToHex(cDimCol)).append('\n'); - buffer.append(" .cDimPg =").append(HexDump.shortToHex(cDimPg)).append('\n'); - buffer.append(" .cDimData =").append(HexDump.shortToHex(cDimData)).append('\n'); - buffer.append(" .cRw =").append(HexDump.shortToHex(cRw)).append('\n'); - buffer.append(" .cCol =").append(HexDump.shortToHex(cCol)).append('\n'); - buffer.append(" .grbit =").append(HexDump.shortToHex(grbit)).append('\n'); - buffer.append(" .itblAutoFmt =").append(HexDump.shortToHex(itblAutoFmt)).append('\n'); - buffer.append(" .name =").append(name).append('\n'); - buffer.append(" .dataField =").append(dataField).append('\n'); - - buffer.append("[/SXVIEW]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java deleted file mode 100644 index de73f8447..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * SXVD - View Fields (0x00B1)
    - * - * @author Patrick Cheng - */ -public final class ViewFieldsRecord extends StandardRecord { - public static final short sid = 0x00B1; - - /** the value of the cchName field when the {@link #_name} is not present */ - private static final int STRING_NOT_PRESENT_LEN = 0xFFFF; - /** 5 shorts */ - private static final int BASE_SIZE = 10; - - private int _sxaxis; - private int _cSub; - private int _grbitSub; - private int _cItm; - - private String _name; - - /** - * values for the {@link ViewFieldsRecord#_sxaxis} field - */ - private static final class Axis { - public static final int NO_AXIS = 0; - public static final int ROW = 1; - public static final int COLUMN = 2; - public static final int PAGE = 4; - public static final int DATA = 8; - } - - public ViewFieldsRecord(RecordInputStream in) { - _sxaxis = in.readShort(); - _cSub = in.readShort(); - _grbitSub = in.readShort(); - _cItm = in.readShort(); - - int cchName = in.readUShort(); - if (cchName != STRING_NOT_PRESENT_LEN) { - int flag = in.readByte(); - if ((flag & 0x01) != 0) { - _name = in.readUnicodeLEString(cchName); - } else { - _name = in.readCompressedUnicode(cchName); - } - } - } - - @Override - protected void serialize(LittleEndianOutput out) { - - out.writeShort(_sxaxis); - out.writeShort(_cSub); - out.writeShort(_grbitSub); - out.writeShort(_cItm); - - if (_name != null) { - StringUtil.writeUnicodeString(out, _name); - } else { - out.writeShort(STRING_NOT_PRESENT_LEN); - } - } - - @Override - protected int getDataSize() { - if (_name == null) { - return BASE_SIZE; - } - return BASE_SIZE - + 1 // unicode flag - + _name.length() * (StringUtil.hasMultibyte(_name) ? 2 : 1); - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("[SXVD]\n"); - buffer.append(" .sxaxis = ").append(HexDump.shortToHex(_sxaxis)).append('\n'); - buffer.append(" .cSub = ").append(HexDump.shortToHex(_cSub)).append('\n'); - buffer.append(" .grbitSub = ").append(HexDump.shortToHex(_grbitSub)).append('\n'); - buffer.append(" .cItm = ").append(HexDump.shortToHex(_cItm)).append('\n'); - buffer.append(" .name = ").append(_name).append('\n'); - - buffer.append("[/SXVD]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java b/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java deleted file mode 100644 index daee00732..000000000 --- a/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.pivottable; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.StandardRecord; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * SXVS - View Source (0x00E3)
    - * - * @author Patrick Cheng - */ -public final class ViewSourceRecord extends StandardRecord { - public static final short sid = 0x00E3; - - private int vs; - - public ViewSourceRecord(RecordInputStream in) { - vs = in.readShort(); - } - - @Override - protected void serialize(LittleEndianOutput out) { - out.writeShort(vs); - } - - @Override - protected int getDataSize() { - return 2; - } - - @Override - public short getSid() { - return sid; - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[SXVS]\n"); - buffer.append(" .vs =").append(HexDump.shortToHex(vs)).append('\n'); - - buffer.append("[/SXVS]\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java b/trunk/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java deleted file mode 100644 index bf0ca4c47..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java +++ /dev/null @@ -1,513 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.regex.Pattern; - -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.DVRecord; -import org.apache.poi.ss.formula.FormulaRenderer; -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.NumberPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.StringPtg; -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.util.LocaleUtil; - -/** - * Data Validation Constraint - */ -public class DVConstraint implements DataValidationConstraint { - /* package */ static final class FormulaPair { - - private final Ptg[] _formula1; - private final Ptg[] _formula2; - - FormulaPair(Ptg[] formula1, Ptg[] formula2) { - _formula1 = (formula1 == null) ? null : formula1.clone(); - _formula2 = (formula2 == null) ? null : formula2.clone(); - } - public Ptg[] getFormula1() { - return _formula1; - } - public Ptg[] getFormula2() { - return _formula2; - } - - } - - private final int _validationType; - private int _operator; - private String[] _explicitListValues; - - private String _formula1; - private String _formula2; - private Double _value1; - private Double _value2; - - - private DVConstraint(int validationType, int comparisonOperator, String formulaA, - String formulaB, Double value1, Double value2, String[] excplicitListValues) { - _validationType = validationType; - _operator = comparisonOperator; - _formula1 = formulaA; - _formula2 = formulaB; - _value1 = value1; - _value2 = value2; - _explicitListValues = (excplicitListValues == null) ? null : excplicitListValues.clone(); - } - - - /** - * Creates a list constraint - */ - private DVConstraint(String listFormula, String[] excplicitListValues) { - this(ValidationType.LIST, OperatorType.IGNORED, - listFormula, null, null, null, excplicitListValues); - } - - /** - * Creates a number based data validation constraint. The text values entered for expr1 and expr2 - * can be either standard Excel formulas or formatted number values. If the expression starts - * with '=' it is parsed as a formula, otherwise it is parsed as a formatted number. - * - * @param validationType one of {@link org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType#ANY}, - * {@link org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType#DECIMAL}, - * {@link org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType#INTEGER}, - * {@link org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType#TEXT_LENGTH} - * @param comparisonOperator any constant from {@link org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType} enum - * @param expr1 date formula (when first char is '=') or formatted number value - * @param expr2 date formula (when first char is '=') or formatted number value - */ - public static DVConstraint createNumericConstraint(int validationType, int comparisonOperator, - String expr1, String expr2) { - switch (validationType) { - case ValidationType.ANY: - if (expr1 != null || expr2 != null) { - throw new IllegalArgumentException("expr1 and expr2 must be null for validation type 'any'"); - } - break; - case ValidationType.DECIMAL: - case ValidationType.INTEGER: - case ValidationType.TEXT_LENGTH: - if (expr1 == null) { - throw new IllegalArgumentException("expr1 must be supplied"); - } - OperatorType.validateSecondArg(comparisonOperator, expr2); - break; - default: - throw new IllegalArgumentException("Validation Type (" - + validationType + ") not supported with this method"); - } - // formula1 and value1 are mutually exclusive - String formula1 = getFormulaFromTextExpression(expr1); - Double value1 = formula1 == null ? convertNumber(expr1) : null; - // formula2 and value2 are mutually exclusive - String formula2 = getFormulaFromTextExpression(expr2); - Double value2 = formula2 == null ? convertNumber(expr2) : null; - return new DVConstraint(validationType, comparisonOperator, formula1, formula2, value1, value2, null); - } - - public static DVConstraint createFormulaListConstraint(String listFormula) { - return new DVConstraint(listFormula, null); - } - public static DVConstraint createExplicitListConstraint(String[] explicitListValues) { - return new DVConstraint(null, explicitListValues); - } - - - /** - * Creates a time based data validation constraint. The text values entered for expr1 and expr2 - * can be either standard Excel formulas or formatted time values. If the expression starts - * with '=' it is parsed as a formula, otherwise it is parsed as a formatted time. To parse - * formatted times, two formats are supported: "HH:MM" or "HH:MM:SS". This is contrary to - * Excel which uses the default time format from the OS. - * - * @param comparisonOperator constant from {@link org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType} enum - * @param expr1 date formula (when first char is '=') or formatted time value - * @param expr2 date formula (when first char is '=') or formatted time value - */ - public static DVConstraint createTimeConstraint(int comparisonOperator, String expr1, String expr2) { - if (expr1 == null) { - throw new IllegalArgumentException("expr1 must be supplied"); - } - OperatorType.validateSecondArg(comparisonOperator, expr1); - - // formula1 and value1 are mutually exclusive - String formula1 = getFormulaFromTextExpression(expr1); - Double value1 = formula1 == null ? convertTime(expr1) : null; - // formula2 and value2 are mutually exclusive - String formula2 = getFormulaFromTextExpression(expr2); - Double value2 = formula2 == null ? convertTime(expr2) : null; - return new DVConstraint(ValidationType.TIME, comparisonOperator, formula1, formula2, value1, value2, null); - } - - /** - * Creates a date based data validation constraint. The text values entered for expr1 and expr2 - * can be either standard Excel formulas or formatted date values. If the expression starts - * with '=' it is parsed as a formula, otherwise it is parsed as a formatted date (Excel uses - * the same convention). To parse formatted dates, a date format needs to be specified. This - * is contrary to Excel which uses the default short date format from the OS. - * - * @param comparisonOperator constant from {@link org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType} enum - * @param expr1 date formula (when first char is '=') or formatted date value - * @param expr2 date formula (when first char is '=') or formatted date value - * @param dateFormat ignored if both expr1 and expr2 are formulas. Default value is "YYYY/MM/DD" - * otherwise any other valid argument for SimpleDateFormat can be used - * @see SimpleDateFormat - */ - public static DVConstraint createDateConstraint(int comparisonOperator, String expr1, String expr2, String dateFormat) { - if (expr1 == null) { - throw new IllegalArgumentException("expr1 must be supplied"); - } - OperatorType.validateSecondArg(comparisonOperator, expr2); - SimpleDateFormat df = null; - if (dateFormat != null) { - df = new SimpleDateFormat(dateFormat, LocaleUtil.getUserLocale()); - df.setTimeZone(LocaleUtil.getUserTimeZone()); - } - - // formula1 and value1 are mutually exclusive - String formula1 = getFormulaFromTextExpression(expr1); - Double value1 = formula1 == null ? convertDate(expr1, df) : null; - // formula2 and value2 are mutually exclusive - String formula2 = getFormulaFromTextExpression(expr2); - Double value2 = formula2 == null ? convertDate(expr2, df) : null; - return new DVConstraint(ValidationType.DATE, comparisonOperator, formula1, formula2, value1, value2, null); - } - - /** - * Distinguishes formula expressions from simple value expressions. This logic is only - * required by a few factory methods in this class that create data validation constraints - * from more or less the same parameters that would have been entered in the Excel UI. The - * data validation dialog box uses the convention that formulas begin with '='. Other methods - * in this class follow the POI convention (formulas and values are distinct), so the '=' - * convention is not used there. - * - * @param textExpr a formula or value expression - * @return all text after '=' if textExpr begins with '='. Otherwise null if textExpr does not begin with '=' - */ - private static String getFormulaFromTextExpression(String textExpr) { - if (textExpr == null) { - return null; - } - if (textExpr.length() < 1) { - throw new IllegalArgumentException("Empty string is not a valid formula/value expression"); - } - if (textExpr.charAt(0) == '=') { - return textExpr.substring(1); - } - return null; - } - - - /** - * @return null if numberStr is null - */ - private static Double convertNumber(String numberStr) { - if (numberStr == null) { - return null; - } - try { - return new Double(numberStr); - } catch (NumberFormatException e) { - throw new RuntimeException("The supplied text '" + numberStr - + "' could not be parsed as a number"); - } - } - - /** - * @return null if timeStr is null - */ - private static Double convertTime(String timeStr) { - if (timeStr == null) { - return null; - } - return new Double(HSSFDateUtil.convertTime(timeStr)); - } - /** - * @param dateFormat pass null for default YYYYMMDD - * @return null if timeStr is null - */ - private static Double convertDate(String dateStr, SimpleDateFormat dateFormat) { - if (dateStr == null) { - return null; - } - Date dateVal; - if (dateFormat == null) { - dateVal = HSSFDateUtil.parseYYYYMMDDDate(dateStr); - } else { - try { - dateVal = dateFormat.parse(dateStr); - } catch (ParseException e) { - throw new RuntimeException("Failed to parse date '" + dateStr - + "' using specified format '" + dateFormat + "'", e); - } - } - return new Double(HSSFDateUtil.getExcelDate(dateVal)); - } - - public static DVConstraint createCustomFormulaConstraint(String formula) { - if (formula == null) { - throw new IllegalArgumentException("formula must be supplied"); - } - return new DVConstraint(ValidationType.FORMULA, OperatorType.IGNORED, formula, null, null, null, null); - } - - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getValidationType() - */ - public int getValidationType() { - return _validationType; - } - /** - * Convenience method - * @return true if this constraint is a 'list' validation - */ - public boolean isListValidationType() { - return _validationType == ValidationType.LIST; - } - /** - * Convenience method - * @return true if this constraint is a 'list' validation with explicit values - */ - public boolean isExplicitList() { - return _validationType == ValidationType.LIST && _explicitListValues != null; - } - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getOperator() - */ - public int getOperator() { - return _operator; - } - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setOperator(int) - */ - public void setOperator(int operator) { - _operator = operator; - } - - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getExplicitListValues() - */ - public String[] getExplicitListValues() { - return _explicitListValues; - } - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setExplicitListValues(java.lang.String[]) - */ - public void setExplicitListValues(String[] explicitListValues) { - if (_validationType != ValidationType.LIST) { - throw new RuntimeException("Cannot setExplicitListValues on non-list constraint"); - } - _formula1 = null; - _explicitListValues = explicitListValues; - } - - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getFormula1() - */ - public String getFormula1() { - return _formula1; - } - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setFormula1(java.lang.String) - */ - public void setFormula1(String formula1) { - _value1 = null; - _explicitListValues = null; - _formula1 = formula1; - } - - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getFormula2() - */ - public String getFormula2() { - return _formula2; - } - /* (non-Javadoc) - * @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setFormula2(java.lang.String) - */ - public void setFormula2(String formula2) { - _value2 = null; - _formula2 = formula2; - } - - /** - * @return the numeric value for expression 1. May be null - */ - public Double getValue1() { - return _value1; - } - /** - * Sets a numeric value for expression 1. - */ - public void setValue1(double value1) { - _formula1 = null; - _value1 = new Double(value1); - } - - /** - * @return the numeric value for expression 2. May be null - */ - public Double getValue2() { - return _value2; - } - /** - * Sets a numeric value for expression 2. - */ - public void setValue2(double value2) { - _formula2 = null; - _value2 = new Double(value2); - } - - /** - * @return both parsed formulas (for expression 1 and 2). - */ - /* package */ FormulaPair createFormulas(HSSFSheet sheet) { - Ptg[] formula1; - Ptg[] formula2; - if (isListValidationType()) { - formula1 = createListFormula(sheet); - formula2 = Ptg.EMPTY_PTG_ARRAY; - } else { - formula1 = convertDoubleFormula(_formula1, _value1, sheet); - formula2 = convertDoubleFormula(_formula2, _value2, sheet); - } - return new FormulaPair(formula1, formula2); - } - - @SuppressWarnings("resource") - private Ptg[] createListFormula(HSSFSheet sheet) { - - if (_explicitListValues == null) { - HSSFWorkbook wb = sheet.getWorkbook(); - // formula is parsed with slightly different RVA rules: (root node type must be 'reference') - return HSSFFormulaParser.parse(_formula1, wb, FormulaType.DATAVALIDATION_LIST, wb.getSheetIndex(sheet)); - // To do: Excel places restrictions on the available operations within a list formula. - // Some things like union and intersection are not allowed. - } - // explicit list was provided - StringBuffer sb = new StringBuffer(_explicitListValues.length * 16); - for (int i = 0; i < _explicitListValues.length; i++) { - if (i > 0) { - sb.append('\0'); // list delimiter is the nul char - } - sb.append(_explicitListValues[i]); - - } - return new Ptg[] { new StringPtg(sb.toString()), }; - } - - /** - * @return The parsed token array representing the formula or value specified. - * Empty array if both formula and value are null - */ - @SuppressWarnings("resource") - private static Ptg[] convertDoubleFormula(String formula, Double value, HSSFSheet sheet) { - if (formula == null) { - if (value == null) { - return Ptg.EMPTY_PTG_ARRAY; - } - return new Ptg[] { new NumberPtg(value.doubleValue()), }; - } - if (value != null) { - throw new IllegalStateException("Both formula and value cannot be present"); - } - HSSFWorkbook wb = sheet.getWorkbook(); - return HSSFFormulaParser.parse(formula, wb, FormulaType.CELL, wb.getSheetIndex(sheet)); - } - - static DVConstraint createDVConstraint(DVRecord dvRecord, FormulaRenderingWorkbook book) { - switch (dvRecord.getDataType()) { - case ValidationType.ANY: - return new DVConstraint(ValidationType.ANY, dvRecord.getConditionOperator(), null, null, null, null, null); - case ValidationType.INTEGER: - case ValidationType.DECIMAL: - case ValidationType.DATE: - case ValidationType.TIME: - case ValidationType.TEXT_LENGTH: - FormulaValuePair pair1 = toFormulaString(dvRecord.getFormula1(), book); - FormulaValuePair pair2 = toFormulaString(dvRecord.getFormula2(), book); - return new DVConstraint(dvRecord.getDataType(), dvRecord.getConditionOperator(), pair1.formula(), - pair2.formula(), pair1.value(), pair2.value(), null); - case ValidationType.LIST: - if (dvRecord.getListExplicitFormula()) { - String values = toFormulaString(dvRecord.getFormula1(), book).string(); - if (values.startsWith("\"")) { - values = values.substring(1); - } - if (values.endsWith("\"")) { - values = values.substring(0, values.length() - 1); - } - String[] explicitListValues = values.split(Pattern.quote("\0")); - return createExplicitListConstraint(explicitListValues); - } else { - String listFormula = toFormulaString(dvRecord.getFormula1(), book).string(); - return createFormulaListConstraint(listFormula); - } - case ValidationType.FORMULA: - return createCustomFormulaConstraint(toFormulaString(dvRecord.getFormula1(), book).string()); - default: - throw new UnsupportedOperationException("validationType="+dvRecord.getDataType()); - } - } - - private static class FormulaValuePair { - private String _formula; - private String _value; - - public String formula() { - return _formula; - } - - public Double value() { - if (_value == null) { - return null; - } - return new Double(_value); - } - - public String string() { - if (_formula != null) { - return _formula; - } - if (_value != null) { - return _value; - } - return null; - } - } - - private static FormulaValuePair toFormulaString(Ptg[] ptgs, FormulaRenderingWorkbook book) { - FormulaValuePair pair = new FormulaValuePair(); - if (ptgs != null && ptgs.length > 0) { - String string = FormulaRenderer.toFormulaString(book, ptgs); - if (ptgs.length == 1 && ptgs[0].getClass() == NumberPtg.class) { - pair._value = string; - } else { - pair._formula = string; - } - } - return pair; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java b/trunk/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java deleted file mode 100644 index 31cd919ed..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java +++ /dev/null @@ -1,832 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.io.PrintStream; -import java.text.AttributedCharacterIterator; -import java.util.Arrays; -import java.util.Map; - -import org.apache.poi.util.Internal; - -public class DummyGraphics2d extends Graphics2D { - private BufferedImage bufimg; - private final Graphics2D g2D; - private final PrintStream log; - - public DummyGraphics2d() { - this(System.out); - } - - public DummyGraphics2d(PrintStream log) { - bufimg = new BufferedImage(1000, 1000, 2); - g2D = (Graphics2D)bufimg.getGraphics(); - this.log = log; - } - - public DummyGraphics2d(PrintStream log, Graphics2D g2D) { - this.g2D = g2D; - this.log = log; - } - - public void addRenderingHints(Map hints) { - String l = - "addRenderingHinds(Map):" + - "\n hints = " + hints; - log.println( l ); - g2D.addRenderingHints( hints ); - } - - public void clip(Shape s) { - String l = - "clip(Shape):" + - "\n s = " + s; - log.println( l ); - g2D.clip( s ); - } - - public void draw(Shape s) { - String l = - "draw(Shape):" + - "\n s = " + s; - log.println( l ); - g2D.draw( s ); - } - - public void drawGlyphVector(GlyphVector g, float x, float y) { - String l = - "drawGlyphVector(GlyphVector, float, float):" + - "\n g = " + g + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawGlyphVector( g, x, y ); - } - - public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { - String l = - "drawImage(BufferedImage, BufferedImageOp, x, y):" + - "\n img = " + img + - "\n op = " + op + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawImage( img, op, x, y ); - } - - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - String l = - "drawImage(Image,AfflineTransform,ImageObserver):" + - "\n img = " + img + - "\n xform = " + xform + - "\n obs = " + obs; - log.println( l ); - return g2D.drawImage( img, xform, obs ); - } - - public void drawRenderableImage(RenderableImage img, AffineTransform xform) { - String l = - "drawRenderableImage(RenderableImage, AfflineTransform):" + - "\n img = " + img + - "\n xform = " + xform; - log.println( l ); - g2D.drawRenderableImage( img, xform ); - } - - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - String l = - "drawRenderedImage(RenderedImage, AffineTransform):" + - "\n img = " + img + - "\n xform = " + xform; - log.println( l ); - g2D.drawRenderedImage( img, xform ); - } - - public void drawString(AttributedCharacterIterator iterator, float x, float y) { - String l = - "drawString(AttributedCharacterIterator):" + - "\n iterator = " + iterator + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawString( iterator, x, y ); - } - - public void drawString(String s, float x, float y) { - String l = - "drawString(s,x,y):" + - "\n s = " + s + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawString( s, x, y ); - } - - public void fill(Shape s) { - String l = - "fill(Shape):" + - "\n s = " + s; - log.println( l ); - g2D.fill( s ); - } - - public Color getBackground() { - log.println( "getBackground():" ); - return g2D.getBackground(); - } - - public Composite getComposite() { - log.println( "getComposite():" ); - return g2D.getComposite(); - } - - public GraphicsConfiguration getDeviceConfiguration() { - log.println( "getDeviceConfiguration():" ); - return g2D.getDeviceConfiguration(); - } - - public FontRenderContext getFontRenderContext() { - log.println( "getFontRenderContext():" ); - return g2D.getFontRenderContext(); - } - - public Paint getPaint() { - log.println( "getPaint():" ); - return g2D.getPaint(); - } - - public Object getRenderingHint(RenderingHints.Key hintKey) { - String l = - "getRenderingHint(RenderingHints.Key):" + - "\n hintKey = " + hintKey; - log.println( l ); - return g2D.getRenderingHint( hintKey ); - } - - public RenderingHints getRenderingHints() { - log.println( "getRenderingHints():" ); - return g2D.getRenderingHints(); - } - - public Stroke getStroke() { - log.println( "getStroke():" ); - return g2D.getStroke(); - } - - public AffineTransform getTransform() { - log.println( "getTransform():" ); - return g2D.getTransform(); - } - - public boolean hit(Rectangle rect, Shape s, boolean onStroke) { - String l = - "hit(Rectangle, Shape, onStroke):" + - "\n rect = " + rect + - "\n s = " + s + - "\n onStroke = " + onStroke; - log.println( l ); - return g2D.hit( rect, s, onStroke ); - } - - public void rotate(double theta) { - String l = - "rotate(theta):" + - "\n theta = " + theta; - log.println( l ); - g2D.rotate( theta ); - } - - public void rotate(double theta, double x, double y) { - String l = - "rotate(double,double,double):" + - "\n theta = " + theta + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.rotate( theta, x, y ); - } - - public void scale(double sx, double sy) { - String l = - "scale(double,double):" + - "\n sx = " + sx + - "\n sy"; - log.println( l ); - g2D.scale( sx, sy ); - } - - public void setBackground(Color color) { - String l = - "setBackground(Color):" + - "\n color = " + color; - log.println( l ); - g2D.setBackground( color ); - } - - public void setComposite(Composite comp) { - String l = - "setComposite(Composite):" + - "\n comp = " + comp; - log.println( l ); - g2D.setComposite( comp ); - } - - public void setPaint( Paint paint ) { - String l = - "setPaint(Paint):" + - "\n paint = " + paint; - log.println( l ); - g2D.setPaint( paint ); - } - - public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { - String l = - "setRenderingHint(RenderingHints.Key, Object):" + - "\n hintKey = " + hintKey + - "\n hintValue = " + hintValue; - log.println( l ); - g2D.setRenderingHint( hintKey, hintValue ); - } - - public void setRenderingHints(Map hints) { - String l = - "setRenderingHints(Map):" + - "\n hints = " + hints; - log.println( l ); - g2D.setRenderingHints( hints ); - } - - public void setStroke(Stroke s) { - String l; - if (s instanceof BasicStroke) { - BasicStroke bs = (BasicStroke)s; - l = "setStroke(Stoke):" + - "\n s = BasicStroke(" + - "\n dash[]: "+Arrays.toString(bs.getDashArray()) + - "\n dashPhase: "+bs.getDashPhase() + - "\n endCap: "+bs.getEndCap() + - "\n lineJoin: "+bs.getLineJoin() + - "\n width: "+bs.getLineWidth() + - "\n miterLimit: "+bs.getMiterLimit() + - "\n )"; - } else { - l = "setStroke(Stoke):" + - "\n s = " + s; - } - log.println( l ); - g2D.setStroke( s ); - } - - public void setTransform(AffineTransform Tx) { - String l = - "setTransform():" + - "\n Tx = " + Tx; - log.println( l ); - g2D.setTransform( Tx ); - } - - public void shear(double shx, double shy) { - String l = - "shear(shx, dhy):" + - "\n shx = " + shx + - "\n shy = " + shy; - log.println( l ); - g2D.shear( shx, shy ); - } - - public void transform(AffineTransform Tx) { - String l = - "transform(AffineTransform):" + - "\n Tx = " + Tx; - log.println( l ); - g2D.transform( Tx ); - } - - public void translate(double tx, double ty) { - String l = - "translate(double, double):" + - "\n tx = " + tx + - "\n ty = " + ty; - log.println( l ); - g2D.translate( tx, ty ); - } - - public void clearRect(int x, int y, int width, int height) { - String l = - "clearRect(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.clearRect( x, y, width, height ); - } - - public void clipRect(int x, int y, int width, int height) { - String l = - "clipRect(int, int, int, int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "height = " + height; - log.println( l ); - g2D.clipRect( x, y, width, height ); - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - String l = - "copyArea(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.copyArea( x, y, width, height, dx, dy ); - } - - public Graphics create() { - log.println( "create():" ); - return g2D.create(); - } - - public Graphics create(int x, int y, int width, int height) { - String l = - "create(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - return g2D.create( x, y, width, height ); - } - - public void dispose() { - log.println( "dispose():" ); - g2D.dispose(); - } - - public void draw3DRect(int x, int y, int width, int height, boolean raised) { - String l = - "draw3DRect(int,int,int,int,boolean):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n raised = " + raised; - log.println( l ); - g2D.draw3DRect( x, y, width, height, raised ); - } - - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - String l = - "drawArc(int,int,int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n startAngle = " + startAngle + - "\n arcAngle = " + arcAngle; - log.println( l ); - g2D.drawArc( x, y, width, height, startAngle, arcAngle ); - } - - public void drawBytes(byte data[], int offset, int length, int x, int y) { - String l = - "drawBytes(byte[],int,int,int,int):" + - "\n data = " + Arrays.toString(data) + - "\n offset = " + offset + - "\n length = " + length + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawBytes( data, offset, length, x, y ); - } - - public void drawChars(char data[], int offset, int length, int x, int y) { - String l = - "drawChars(data,int,int,int,int):" + - "\n data = " + Arrays.toString(data) + - "\n offset = " + offset + - "\n length = " + length + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawChars( data, offset, length, x, y ); - } - - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { - String l = - "drawImage(Image,int,int,int,int,int,int,int,int,ImageObserver):" + - "\n img = " + img + - "\n dx1 = " + dx1 + - "\n dy1 = " + dy1 + - "\n dx2 = " + dx2 + - "\n dy2 = " + dy2 + - "\n sx1 = " + sx1 + - "\n sy1 = " + sy1 + - "\n sx2 = " + sx2 + - "\n sy2 = " + sy2 + - "\n observer = " + observer; - log.println( l ); - return g2D.drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer ); - } - - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { - String l = - "drawImage(Image,int,int,int,int,int,int,int,int,Color,ImageObserver):" + - "\n img = " + img + - "\n dx1 = " + dx1 + - "\n dy1 = " + dy1 + - "\n dx2 = " + dx2 + - "\n dy2 = " + dy2 + - "\n sx1 = " + sx1 + - "\n sy1 = " + sy1 + - "\n sx2 = " + sx2 + - "\n sy2 = " + sy2 + - "\n bgcolor = " + bgcolor + - "\n observer = " + observer; - log.println( l ); - return g2D.drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer ); - } - - public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { - String l = - "drawImage(Image,int,int,Color,ImageObserver):" + - "\n img = " + img + - "\n x = " + x + - "\n y = " + y + - "\n bgcolor = " + bgcolor + - "\n observer = " + observer; - log.println( l ); - return g2D.drawImage( img, x, y, bgcolor, observer ); - } - - public boolean drawImage(Image img, int x, int y, ImageObserver observer) { - String l = - "drawImage(Image,int,int,observer):" + - "\n img = " + img + - "\n x = " + x + - "\n y = " + y + - "\n observer = " + observer; - log.println( l ); - return g2D.drawImage( img, x, y, observer ); - } - - public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { - String l = - "drawImage(Image,int,int,int,int,Color,ImageObserver):" + - "\n img = " + img + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n bgcolor = " + bgcolor + - "\n observer = " + observer; - log.println( l ); - return g2D.drawImage( img, x, y, width, height, bgcolor, observer ); - } - - public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { - String l = - "drawImage(Image,int,int,width,height,observer):" + - "\n img = " + img + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n observer = " + observer; - log.println( l ); - return g2D.drawImage( img, x, y, width, height, observer ); - } - - public void drawLine(int x1, int y1, int x2, int y2) { - String l = - "drawLine(int,int,int,int):" + - "\n x1 = " + x1 + - "\n y1 = " + y1 + - "\n x2 = " + x2 + - "\n y2 = " + y2; - log.println( l ); - g2D.drawLine( x1, y1, x2, y2 ); - } - - public void drawOval(int x, int y, int width, int height) { - String l = - "drawOval(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.drawOval( x, y, width, height ); - } - - public void drawPolygon(Polygon p) { - String l = - "drawPolygon(Polygon):" + - "\n p = " + p; - log.println( l ); - g2D.drawPolygon( p ); - } - - public void drawPolygon(int xPoints[], int yPoints[], int nPoints) { - String l = - "drawPolygon(int[],int[],int):" + - "\n xPoints = " + Arrays.toString(xPoints) + - "\n yPoints = " + Arrays.toString(yPoints) + - "\n nPoints = " + nPoints; - log.println( l ); - g2D.drawPolygon( xPoints, yPoints, nPoints ); - } - - public void drawPolyline(int xPoints[], int yPoints[], int nPoints) { - String l = - "drawPolyline(int[],int[],int):" + - "\n xPoints = " + Arrays.toString(xPoints) + - "\n yPoints = " + Arrays.toString(yPoints) + - "\n nPoints = " + nPoints; - log.println( l ); - g2D.drawPolyline( xPoints, yPoints, nPoints ); - } - - public void drawRect(int x, int y, int width, int height) { - String l = - "drawRect(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.drawRect( x, y, width, height ); - } - - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { - String l = - "drawRoundRect(int,int,int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n arcWidth = " + arcWidth + - "\n arcHeight = " + arcHeight; - log.println( l ); - g2D.drawRoundRect( x, y, width, height, arcWidth, arcHeight ); - } - - public void drawString(AttributedCharacterIterator iterator, int x, int y) { - String l = - "drawString(AttributedCharacterIterator,int,int):" + - "\n iterator = " + iterator + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawString( iterator, x, y ); - } - - public void drawString(String str, int x, int y) { - String l = - "drawString(str,int,int):" + - "\n str = " + str + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.drawString( str, x, y ); - } - - public void fill3DRect(int x, int y, int width, int height, boolean raised) { - String l = - "fill3DRect(int,int,int,int,boolean):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n raised = " + raised; - log.println( l ); - g2D.fill3DRect( x, y, width, height, raised ); - } - - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - String l = - "fillArc(int,int,int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height + - "\n startAngle = " + startAngle + - "\n arcAngle = " + arcAngle; - log.println( l ); - g2D.fillArc( x, y, width, height, startAngle, arcAngle ); - } - - public void fillOval(int x, int y, int width, int height) { - String l = - "fillOval(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.fillOval( x, y, width, height ); - } - - public void fillPolygon(Polygon p) { - String l = - "fillPolygon(Polygon):" + - "\n p = " + p; - log.println( l ); - g2D.fillPolygon( p ); - } - - public void fillPolygon(int xPoints[], int yPoints[], int nPoints) { - String l = - "fillPolygon(int[],int[],int):" + - "\n xPoints = " + Arrays.toString(xPoints) + - "\n yPoints = " + Arrays.toString(yPoints) + - "\n nPoints = " + nPoints; - log.println( l ); - g2D.fillPolygon( xPoints, yPoints, nPoints ); - } - - public void fillRect(int x, int y, int width, int height) { - String l = - "fillRect(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.fillRect( x, y, width, height ); - } - - public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { - String l = - "fillRoundRect(int,int,int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.fillRoundRect( x, y, width, height, arcWidth, arcHeight ); - } - - // FIXME: should be protected - // FindBugs, category MALICIOUS_CODE, FI_PUBLIC_SHOULD_BE_PROTECTED - // A class's finalize() method should have protected access, not public - @Internal - @Override - public final void finalize() { - log.println( "finalize():" ); - g2D.finalize(); // NOSOLAR - super.finalize(); - } - - public Shape getClip() { - log.println( "getClip():" ); - return g2D.getClip(); - } - - public Rectangle getClipBounds() { - log.println( "getClipBounds():" ); - return g2D.getClipBounds(); - } - - public Rectangle getClipBounds(Rectangle r) { - String l = - "getClipBounds(Rectangle):" + - "\n r = " + r; - log.println( l ); - return g2D.getClipBounds( r ); - } - - public Color getColor() { - log.println( "getColor():" ); - return g2D.getColor(); - } - - public Font getFont() { - log.println( "getFont():" ); - return g2D.getFont(); - } - - public FontMetrics getFontMetrics() { - log.println( "getFontMetrics():" ); - return g2D.getFontMetrics(); - } - - public FontMetrics getFontMetrics(Font f) { - log.println( "getFontMetrics():" ); - return g2D.getFontMetrics( f ); - } - - public boolean hitClip(int x, int y, int width, int height) { - String l = - "hitClip(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - return g2D.hitClip( x, y, width, height ); - } - - public void setClip(Shape clip) { - String l = - "setClip(Shape):" + - "\n clip = " + clip; - log.println( l ); - g2D.setClip( clip ); - } - - public void setClip(int x, int y, int width, int height) { - String l = - "setClip(int,int,int,int):" + - "\n x = " + x + - "\n y = " + y + - "\n width = " + width + - "\n height = " + height; - log.println( l ); - g2D.setClip( x, y, width, height ); - } - - public void setColor(Color c) { - String l = - "setColor():" + - "\n c = " + c; - log.println( l ); - g2D.setColor( c ); - } - - public void setFont(Font font) { - String l = - "setFont(Font):" + - "\n font = " + font; - log.println( l ); - g2D.setFont( font ); - } - - public void setPaintMode() { - log.println( "setPaintMode():" ); - g2D.setPaintMode(); - } - - public void setXORMode(Color c1) { - String l = - "setXORMode(Color):" + - "\n c1 = " + c1; - log.println( l ); - g2D.setXORMode( c1 ); - } - - public String toString() { - log.println( "toString():" ); - return g2D.toString(); - } - - public void translate(int x, int y) { - String l = - "translate(int,int):" + - "\n x = " + x + - "\n y = " + y; - log.println( l ); - g2D.translate( x, y ); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java b/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java deleted file mode 100644 index 5cdb2a357..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java +++ /dev/null @@ -1,554 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.SuppressForbidden; - -import java.awt.*; -import java.awt.image.ImageObserver; -import java.text.AttributedCharacterIterator; - -/** - * Translates Graphics calls into escher calls. The translation is lossy so - * many features are not supported and some just aren't implemented yet. If - * in doubt test the specific calls you wish to make. Graphics calls are - * always performed into an EscherGroup so one will need to be created. - *

    - * Important: - *

    - * One important concept worth considering is that of font size. One of the - * difficulties in converting Graphics calls into escher drawing calls is that - * Excel does not have the concept of absolute pixel positions. It measures - * it's cell widths in 'characters' and the cell heights in points. - * Unfortunately it's not defined exactly what a type of character it's - * measuring. Presumably this is due to the fact that the Excel will be - * using different fonts on different platforms or even within the same - * platform. - *

    - * Because of this constraint we've had to calculate the - * verticalPointsPerPixel. This the amount the font should be scaled by when - * you issue commands such as drawString(). A good way to calculate this - * is to use the follow formula: - *

    - *

    - *      multipler = groupHeightInPoints / heightOfGroup
    - * 
    - *

    - * The height of the group is calculated fairly simply by calculating the - * difference between the y coordinates of the bounding box of the shape. The - * height of the group can be calculated by using a convenience called - * HSSFClientAnchor.getAnchorHeightInPoints(). - *

    - */ -public class EscherGraphics extends Graphics -{ - private final HSSFShapeGroup escherGroup; - private final HSSFWorkbook workbook; - private float verticalPointsPerPixel = 1.0f; - private final float verticalPixelsPerPoint; - private Color foreground; - private Color background = Color.white; - private Font font; - private static final POILogger logger = POILogFactory.getLogger(EscherGraphics.class); - - /** - * Construct an escher graphics object. - * - * @param escherGroup The escher group to write the graphics calls into. - * @param workbook The workbook we are using. - * @param forecolor The foreground color to use as default. - * @param verticalPointsPerPixel The font multiplier. (See class description for information on how this works.). - */ - public EscherGraphics(HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor, float verticalPointsPerPixel ) - { - this.escherGroup = escherGroup; - this.workbook = workbook; - this.verticalPointsPerPixel = verticalPointsPerPixel; - this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel; - this.font = new Font("Arial", 0, 10); - this.foreground = forecolor; -// background = backcolor; - } - - /** - * Constructs an escher graphics object. - * - * @param escherGroup The escher group to write the graphics calls into. - * @param workbook The workbook we are using. - * @param foreground The foreground color to use as default. - * @param verticalPointsPerPixel The font multiplier. (See class description for information on how this works.). - * @param font The font to use. - */ - EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color foreground, Font font, float verticalPointsPerPixel ) - { - this.escherGroup = escherGroup; - this.workbook = workbook; - this.foreground = foreground; -// this.background = background; - this.font = font; - this.verticalPointsPerPixel = verticalPointsPerPixel; - this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel; - } - -// /** -// * Constructs an escher graphics object. -// * -// * @param escherGroup The escher group to write the graphics calls into. -// * @param workbook The workbook we are using. -// * @param forecolor The default foreground color. -// */ -// public EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor) -// { -// this(escherGroup, workbook, forecolor, 1.0f); -// } - - - @Override - @NotImplemented - public void clearRect(int x, int y, int width, int height) - { - Color color = foreground; - setColor(background); - fillRect(x,y,width,height); - setColor(color); - } - - @Override - @NotImplemented - public void clipRect(int x, int y, int width, int height) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"clipRect not supported"); - } - - @Override - @NotImplemented - public void copyArea(int x, int y, int width, int height, int dx, int dy) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"copyArea not supported"); - } - - @Override - public Graphics create() - { - EscherGraphics g = new EscherGraphics(escherGroup, workbook, - foreground, font, verticalPointsPerPixel ); - return g; - } - - @Override - public void dispose() - { - } - - @Override - @NotImplemented - public void drawArc(int x, int y, int width, int height, - int startAngle, int arcAngle) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawArc not supported"); - } - - @Override - @NotImplemented - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - Color bgcolor, - ImageObserver observer) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawImage not supported"); - - return true; - } - - @Override - @NotImplemented - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - ImageObserver observer) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawImage not supported"); - return true; - } - - @Override - public boolean drawImage(Image image, int i, int j, int k, int l, Color color, ImageObserver imageobserver) - { - return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver); - } - - @Override - public boolean drawImage(Image image, int i, int j, int k, int l, ImageObserver imageobserver) - { - return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver); - } - - @Override - public boolean drawImage(Image image, int i, int j, Color color, ImageObserver imageobserver) - { - return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver); - } - - @Override - public boolean drawImage(Image image, int i, int j, ImageObserver imageobserver) - { - return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver); - } - - @Override - public void drawLine(int x1, int y1, int x2, int y2) - { - drawLine(x1,y1,x2,y2,0); - } - - public void drawLine(int x1, int y1, int x2, int y2, int width) - { - HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x1, y1, x2, y2) ); - shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); - shape.setLineWidth(width); - shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - } - - @Override - public void drawOval(int x, int y, int width, int height) - { - HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x,y,x+width,y+height) ); - shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL); - shape.setLineWidth(0); - shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - shape.setNoFill(true); - } - - @Override - public void drawPolygon(int xPoints[], int yPoints[], - int nPoints) - { - int right = findBiggest(xPoints); - int bottom = findBiggest(yPoints); - int left = findSmallest(xPoints); - int top = findSmallest(yPoints); - HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) ); - shape.setPolygonDrawArea(right - left, bottom - top); - shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top)); - shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - shape.setLineWidth(0); - shape.setNoFill(true); - } - - private int[] addToAll( int[] values, int amount ) - { - int[] result = new int[values.length]; - for ( int i = 0; i < values.length; i++ ) - result[i] = values[i] + amount; - return result; - } - - @Override - @NotImplemented - public void drawPolyline(int xPoints[], int yPoints[], - int nPoints) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawPolyline not supported"); - } - - @Override - @NotImplemented - public void drawRect(int x, int y, int width, int height) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawRect not supported"); - } - - @Override - @NotImplemented - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawRoundRect not supported"); - } - - @Override - public void drawString(String str, int x, int y) - { - if (str == null || str.equals("")) - return; - - Font excelFont = font; - if ( font.getName().equals( "SansSerif" ) ) - { - excelFont = new Font( "Arial", font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ) ); - } - else - { - excelFont = new Font( font.getName(), font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint )); - } - FontDetails d = StaticFontMetrics.getFontDetails( excelFont ); - int width = d.getStringWidth( str ) * 8 + 12; - int height = (int) ( ( font.getSize() / verticalPixelsPerPoint ) + 6 ) * 2; - y -= ( font.getSize() / verticalPixelsPerPoint ) + 2 * verticalPixelsPerPoint; // we want to draw the shape from the top-left - HSSFTextbox textbox = escherGroup.createTextbox( new HSSFChildAnchor( x, y, x + width, y + height ) ); - textbox.setNoFill( true ); - textbox.setLineStyle( HSSFShape.LINESTYLE_NONE ); - HSSFRichTextString s = new HSSFRichTextString( str ); - HSSFFont hssfFont = matchFont( excelFont ); - s.applyFont( hssfFont ); - textbox.setString( s ); - } - - private HSSFFont matchFont( Font matchFont ) - { - HSSFColor hssfColor = workbook.getCustomPalette() - .findColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue()); - if (hssfColor == null) - hssfColor = workbook.getCustomPalette().findSimilarColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue()); - boolean bold = (matchFont.getStyle() & Font.BOLD) != 0; - boolean italic = (matchFont.getStyle() & Font.ITALIC) != 0; - HSSFFont hssfFont = workbook.findFont(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0, - hssfColor.getIndex(), - (short)(matchFont.getSize() * 20), - matchFont.getName(), - italic, - false, - (short)0, - (byte)0); - if (hssfFont == null) - { - hssfFont = workbook.createFont(); - hssfFont.setBoldweight(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0); - hssfFont.setColor(hssfColor.getIndex()); - hssfFont.setFontHeight((short)(matchFont.getSize() * 20)); - hssfFont.setFontName(matchFont.getName()); - hssfFont.setItalic(italic); - hssfFont.setStrikeout(false); - hssfFont.setTypeOffset((short) 0); - hssfFont.setUnderline((byte) 0); - } - - return hssfFont; - } - - - @Override - public void drawString(AttributedCharacterIterator iterator, - int x, int y) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawString not supported"); - } - - @Override - public void fillArc(int x, int y, int width, int height, - int startAngle, int arcAngle) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"fillArc not supported"); - } - - @Override - public void fillOval(int x, int y, int width, int height) - { - HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) ); - shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL); - shape.setLineStyle(HSSFShape.LINESTYLE_NONE); - shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - shape.setNoFill(false); - } - - /** - * Fills a (closed) polygon, as defined by a pair of arrays, which - * hold the x and y coordinates. - *

    - * This draws the polygon, with nPoint line segments. - * The first nPoint - 1 line segments are - * drawn between sequential points - * (xPoints[i],yPoints[i],xPoints[i+1],yPoints[i+1]). - * The final line segment is a closing one, from the last point to - * the first (assuming they are different). - *

    - * The area inside of the polygon is defined by using an - * even-odd fill rule (also known as the alternating rule), and - * the area inside of it is filled. - * @param xPoints array of the x coordinates. - * @param yPoints array of the y coordinates. - * @param nPoints the total number of points in the polygon. - * @see java.awt.Graphics#drawPolygon(int[], int[], int) - */ - @Override - public void fillPolygon(int xPoints[], int yPoints[], - int nPoints) - { - int right = findBiggest(xPoints); - int bottom = findBiggest(yPoints); - int left = findSmallest(xPoints); - int top = findSmallest(yPoints); - HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) ); - shape.setPolygonDrawArea(right - left, bottom - top); - shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top)); - shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - } - - private int findBiggest( int[] values ) - { - int result = Integer.MIN_VALUE; - for ( int i = 0; i < values.length; i++ ) - { - if (values[i] > result) - result = values[i]; - } - return result; - } - - private int findSmallest( int[] values ) - { - int result = Integer.MAX_VALUE; - for ( int i = 0; i < values.length; i++ ) - { - if (values[i] < result) - result = values[i]; - } - return result; - } - - @Override - public void fillRect(int x, int y, int width, int height) - { - HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) ); - shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE); - shape.setLineStyle(HSSFShape.LINESTYLE_NONE); - shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue()); - } - - @Override - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"fillRoundRect not supported"); - } - - @Override - public Shape getClip() - { - return getClipBounds(); - } - - @Override - public Rectangle getClipBounds() - { - return null; - } - - @Override - public Color getColor() - { - return foreground; - } - - @Override - public Font getFont() - { - return font; - } - - @Override - @SuppressWarnings("deprecation") - @SuppressForbidden - public FontMetrics getFontMetrics(Font f) - { - return Toolkit.getDefaultToolkit().getFontMetrics(f); - } - - @Override - public void setClip(int x, int y, int width, int height) - { - setClip(new Rectangle(x,y,width,height)); - } - - @Override - @NotImplemented - public void setClip(Shape shape) - { - // ignore... not implemented - } - - @Override - public void setColor(Color color) - { - foreground = color; - } - - @Override - public void setFont(Font f) - { - font = f; - } - - @Override - @NotImplemented - public void setPaintMode() - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"setPaintMode not supported"); - } - - @Override - @NotImplemented - public void setXORMode(Color color) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"setXORMode not supported"); - } - @Override - @NotImplemented - public void translate(int x, int y) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"translate not supported"); - } - - public Color getBackground() - { - return background; - } - - public void setBackground( Color background ) - { - this.background = background; - } - - HSSFShapeGroup getEscherGraphics() - { - return escherGroup; - } -} - diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java b/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java deleted file mode 100644 index 949168aac..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java +++ /dev/null @@ -1,609 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -import java.awt.*; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Area; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.text.AttributedCharacterIterator; -import java.util.Map; - -/** - * Translates Graphics2d calls into escher calls. The translation is lossy so - * many features are not supported and some just aren't implemented yet. If - * in doubt test the specific calls you wish to make. Graphics calls are - * always drawn into an EscherGroup so one will need to be created. - *

    - * Important: - *

    - * One important concept worth considering is that of font size. One of the - * difficulties in converting Graphics calls into escher drawing calls is that - * Excel does not have the concept of absolute pixel positions. It measures - * it's cell widths in 'characters' and the cell heights in points. - * Unfortunately it's not defined exactly what a type of character it's - * measuring. Presumably this is due to the fact that the Excel will be - * using different fonts on different platforms or even within the same - * platform. - *

    - * Because of this constraint you have to calculate the verticalPointsPerPixel. - * This the amount the font should be scaled by when - * you issue commands such as drawString(). A good way to calculate this - * is to use the follow formula: - *

    - *

    - *      multipler = groupHeightInPoints / heightOfGroup
    - * 
    - *

    - * The height of the group is calculated fairly simply by calculating the - * difference between the y coordinates of the bounding box of the shape. The - * height of the group can be calculated by using a convenience called - * HSSFClientAnchor.getAnchorHeightInPoints(). - *

    - */ -public final class EscherGraphics2d extends Graphics2D { - private EscherGraphics _escherGraphics; - private BufferedImage _img; - private AffineTransform _trans; - private Stroke _stroke; - private Paint _paint; - private Shape _deviceclip; - private POILogger logger = POILogFactory.getLogger(getClass()); - - /** - * Constructs one escher graphics object from an escher graphics object. - * - * @param escherGraphics the original EscherGraphics2d object to copy - */ - public EscherGraphics2d(EscherGraphics escherGraphics) - { - this._escherGraphics = escherGraphics; - setImg( new BufferedImage(1, 1, 2) ); - setColor(Color.black); - } - - public void addRenderingHints(Map map) - { - getG2D().addRenderingHints(map); - } - - public void clearRect(int i, int j, int k, int l) - { - Paint paint1 = getPaint(); - setColor(getBackground()); - fillRect(i, j, k, l); - setPaint(paint1); - } - - public void clip(Shape shape) - { - if(getDeviceclip() != null) - { - Area area = new Area(getClip()); - if(shape != null) - area.intersect(new Area(shape)); - shape = area; - } - setClip(shape); - } - - public void clipRect(int x, int y, int width, int height) - { - clip(new Rectangle(x,y,width,height)); - } - - public void copyArea(int x, int y, int width, int height, - int dx, int dy) - { - getG2D().copyArea(x,y,width,height,dx,dy); - } - - public Graphics create() - { - EscherGraphics2d g2d = new EscherGraphics2d(_escherGraphics); - return g2d; - } - - public void dispose() - { - getEscherGraphics().dispose(); - getG2D().dispose(); - getImg().flush(); - } - - public void draw(Shape shape) - { - if (shape instanceof Line2D) - { - Line2D shape2d = (Line2D) shape; - - int width = 0; - if (_stroke != null && _stroke instanceof BasicStroke) { - width = (int) ((BasicStroke)_stroke).getLineWidth() * 12700; - } - - drawLine((int)shape2d.getX1(), (int)shape2d.getY1(), (int)shape2d.getX2(), (int)shape2d.getY2(), width); - } - else - { - if (logger.check(POILogger.WARN)) - logger.log(POILogger.WARN, "draw not fully supported"); - } - } - - public void drawArc(int x, int y, int width, int height, - int startAngle, int arcAngle) - { - draw(new java.awt.geom.Arc2D.Float(x, y, width, height, startAngle, arcAngle, 0)); - } - - public void drawGlyphVector(GlyphVector g, float x, float y) - { - fill(g.getOutline(x, y)); - } - - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, - int sx2, int sy2, Color bgColor, ImageObserver imageobserver) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawImage() not supported"); - return true; - } - - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, - int sx2, int sy2, ImageObserver imageobserver) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawImage() not supported"); - return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, imageobserver); - } - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, Color bgColor, ImageObserver imageobserver) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"drawImage() not supported"); - return true; - } - - public boolean drawImage(Image img, int x, int y, - int width, int height, - ImageObserver observer) - { - return drawImage(img, x,y,width,height, null, observer); - } - - public boolean drawImage(Image image, int x, int y, Color bgColor, ImageObserver imageobserver) - { - return drawImage(image, x, y, image.getWidth(imageobserver), image.getHeight(imageobserver), bgColor, imageobserver); - } - - public boolean drawImage(Image image, int x, int y, ImageObserver imageobserver) - { - return drawImage(image, x, y, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver); - } - - public boolean drawImage(Image image, AffineTransform affinetransform, ImageObserver imageobserver) - { - AffineTransform affinetransform1 = (AffineTransform)getTrans().clone(); - getTrans().concatenate(affinetransform); - drawImage(image, 0, 0, imageobserver); - setTrans( affinetransform1 ); - return true; - } - - public void drawImage(BufferedImage bufferedimage, BufferedImageOp op, int x, int y) - { - BufferedImage img = op.filter(bufferedimage, null); - drawImage(img, new AffineTransform(1.0F, 0.0F, 0.0F, 1.0F, x, y), null); - } - - public void drawLine(int x1, int y1, int x2, int y2, int width) - { - getEscherGraphics().drawLine(x1,y1,x2,y2, width); - } - - public void drawLine(int x1, int y1, int x2, int y2) - { - int width = 0; - if (_stroke != null && _stroke instanceof BasicStroke) { - width = (int) ((BasicStroke)_stroke).getLineWidth() * 12700; - } - getEscherGraphics().drawLine(x1,y1,x2,y2, width); -// draw(new GeneralPath(new java.awt.geom.Line2D.Float(x1, y1, x2, y2))); - } - - public void drawOval(int x, int y, int width, int height) - { - getEscherGraphics().drawOval(x,y,width,height); -// draw(new java.awt.geom.Ellipse2D.Float(x, y, width, height)); - } - - public void drawPolygon(int xPoints[], int yPoints[], - int nPoints) - { - getEscherGraphics().drawPolygon(xPoints, yPoints, nPoints); - } - - public void drawPolyline(int xPoints[], int yPoints[], int nPoints) - { - if(nPoints > 0) - { - GeneralPath generalpath = new GeneralPath(); - generalpath.moveTo(xPoints[0], yPoints[0]); - for(int j = 1; j < nPoints; j++) - generalpath.lineTo(xPoints[j], yPoints[j]); - - draw(generalpath); - } - } - - public void drawRect(int x, int y, int width, int height) - { - _escherGraphics.drawRect(x,y,width,height); - } - - public void drawRenderableImage(RenderableImage renderableimage, AffineTransform affinetransform) - { - drawRenderedImage(renderableimage.createDefaultRendering(), affinetransform); - } - - public void drawRenderedImage(RenderedImage renderedimage, AffineTransform affinetransform) - { - BufferedImage bufferedimage = new BufferedImage(renderedimage.getColorModel(), renderedimage.getData().createCompatibleWritableRaster(), false, null); - bufferedimage.setData(renderedimage.getData()); - drawImage(bufferedimage, affinetransform, null); - } - - public void drawRoundRect(int i, int j, int k, int l, int i1, int j1) - { - draw(new java.awt.geom.RoundRectangle2D.Float(i, j, k, l, i1, j1)); - } - - public void drawString(String string, float x, float y) - { - getEscherGraphics().drawString(string, (int)x, (int)y); - } - - public void drawString(String string, int x, int y) - { - getEscherGraphics().drawString(string, x, y); - } - - public void drawString(AttributedCharacterIterator attributedcharacteriterator, float x, float y) - { - TextLayout textlayout = new TextLayout(attributedcharacteriterator, getFontRenderContext()); - Paint paint1 = getPaint(); - setColor(getColor()); - fill(textlayout.getOutline(AffineTransform.getTranslateInstance(x, y))); - setPaint(paint1); - } - - public void drawString(AttributedCharacterIterator attributedcharacteriterator, int x, int y) - { - getEscherGraphics().drawString(attributedcharacteriterator, x, y); - } - - public void fill(Shape shape) - { - if (logger.check( POILogger.WARN )) - logger.log(POILogger.WARN,"fill(Shape) not supported"); - } - - public void fillArc(int i, int j, int k, int l, int i1, int j1) - { - fill(new java.awt.geom.Arc2D.Float(i, j, k, l, i1, j1, 2)); - } - - public void fillOval(int x, int y, int width, int height) - { - _escherGraphics.fillOval(x,y,width,height); - } - - /** - * Fills a (closed) polygon, as defined by a pair of arrays, which - * hold the x and y coordinates. - *

    - * This draws the polygon, with nPoint line segments. - * The first nPoint - 1 line segments are - * drawn between sequential points - * (xPoints[i],yPoints[i],xPoints[i+1],yPoints[i+1]). - * The final line segment is a closing one, from the last point to - * the first (assuming they are different). - *

    - * The area inside of the polygon is defined by using an - * even-odd fill rule (also known as the alternating rule), and - * the area inside of it is filled. - * @param xPoints array of the x coordinates. - * @param yPoints array of the y coordinates. - * @param nPoints the total number of points in the polygon. - * @see java.awt.Graphics#drawPolygon(int[], int[], int) - */ - public void fillPolygon(int xPoints[], int yPoints[], int nPoints) - { - _escherGraphics.fillPolygon(xPoints, yPoints, nPoints); - } - - public void fillRect(int x, int y, int width, int height) - { - getEscherGraphics().fillRect(x,y,width,height); - } - - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) - { - fill(new java.awt.geom.RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight)); - } - - public Color getBackground() - { - return getEscherGraphics().getBackground(); - } - - public Shape getClip() - { - try - { - return getTrans().createInverse().createTransformedShape(getDeviceclip()); - } - catch(Exception _ex) - { - return null; - } - } - - public Rectangle getClipBounds() - { - if(getDeviceclip() != null) { - return getClip().getBounds(); - } - return null; - } - - public Color getColor() - { - return _escherGraphics.getColor(); - } - - public Composite getComposite() - { - return getG2D().getComposite(); - } - - public GraphicsConfiguration getDeviceConfiguration() - { - return getG2D().getDeviceConfiguration(); - } - - public Font getFont() - { - return getEscherGraphics().getFont(); - } - - public FontMetrics getFontMetrics(Font font) - { - return getEscherGraphics().getFontMetrics(font); - } - - public FontRenderContext getFontRenderContext() - { - getG2D().setTransform(getTrans()); - return getG2D().getFontRenderContext(); - } - - public Paint getPaint() - { - return _paint; - } - - public Object getRenderingHint(java.awt.RenderingHints.Key key) - { - return getG2D().getRenderingHint(key); - } - - public RenderingHints getRenderingHints() - { - return getG2D().getRenderingHints(); - } - - public Stroke getStroke() - { - return _stroke; - } - - public AffineTransform getTransform() - { - return (AffineTransform)getTrans().clone(); - } - - public boolean hit(Rectangle rectangle, Shape shape, boolean flag) - { - getG2D().setTransform(getTrans()); - getG2D().setStroke(getStroke()); - getG2D().setClip(getClip()); - return getG2D().hit(rectangle, shape, flag); - } - - public void rotate(double d) - { - getTrans().rotate(d); - } - - public void rotate(double d, double d1, double d2) - { - getTrans().rotate(d, d1, d2); - } - - public void scale(double d, double d1) - { - getTrans().scale(d, d1); - } - - public void setBackground(Color c) - { - getEscherGraphics().setBackground(c); - } - - public void setClip(int i, int j, int k, int l) - { - setClip(new Rectangle(i, j, k, l)); - } - - public void setClip(Shape shape) - { - setDeviceclip( getTrans().createTransformedShape(shape) ); - } - - public void setColor(Color c) - { - _escherGraphics.setColor(c); - } - - public void setComposite(Composite composite) - { - getG2D().setComposite(composite); - } - - public void setFont(Font font) - { - getEscherGraphics().setFont(font); - } - - public void setPaint(Paint paint1) - { - if(paint1 != null) - { - _paint = paint1; - if(paint1 instanceof Color) - setColor( (Color)paint1 ); - } - } - - public void setPaintMode() - { - getEscherGraphics().setPaintMode(); - } - - public void setRenderingHint(java.awt.RenderingHints.Key key, Object obj) - { - getG2D().setRenderingHint(key, obj); - } - - public void setRenderingHints(Map map) - { - getG2D().setRenderingHints(map); - } - - public void setStroke(Stroke s) - { - _stroke = s; - } - - public void setTransform(AffineTransform affinetransform) - { - setTrans( (AffineTransform)affinetransform.clone() ); - } - - public void setXORMode(Color color1) - { - getEscherGraphics().setXORMode(color1); - } - - public void shear(double d, double d1) - { - getTrans().shear(d, d1); - } - - public void transform(AffineTransform affinetransform) - { - getTrans().concatenate(affinetransform); - } - -// Image transformImage(Image image, Rectangle rectangle, Rectangle rectangle1, ImageObserver imageobserver, Color color1) -// { -// logger.log(POILogger.WARN,"transformImage() not supported"); -// return null; -// } -// -// Image transformImage(Image image, int ai[], Rectangle rectangle, ImageObserver imageobserver, Color color1) -// { -// logger.log(POILogger.WARN,"transformImage() not supported"); -// return null; -// } - - public void translate(double d, double d1) - { - getTrans().translate(d, d1); - } - - public void translate(int i, int j) - { - getTrans().translate(i, j); - } - - private EscherGraphics getEscherGraphics() - { - return _escherGraphics; - } - - private BufferedImage getImg() - { - return _img; - } - - private void setImg( BufferedImage img ) - { - this._img = img; - } - - private Graphics2D getG2D() - { - return (Graphics2D) _img.getGraphics(); - } - - private AffineTransform getTrans() - { - return _trans; - } - - private void setTrans( AffineTransform trans ) - { - this._trans = trans; - } - - private Shape getDeviceclip() - { - return _deviceclip; - } - - private void setDeviceclip( Shape deviceclip ) - { - this._deviceclip = deviceclip; - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/FontDetails.java b/trunk/src/java/org/apache/poi/hssf/usermodel/FontDetails.java deleted file mode 100644 index 29bcf5ac4..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/FontDetails.java +++ /dev/null @@ -1,174 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.StringTokenizer; - -/** - * Stores width and height details about a font. - */ -public class FontDetails -{ - private String _fontName; - private int _height; - private final Map charWidths = new HashMap(); - - /** - * Construct the font details with the given name and height. - * - * @param fontName The font name. - * @param height The height of the font. - */ - public FontDetails( String fontName, int height ) - { - _fontName = fontName; - _height = height; - } - - public String getFontName() - { - return _fontName; - } - - public int getHeight() - { - return _height; - } - - public void addChar( char c, int width ) - { - charWidths.put(Character.valueOf(c), Integer.valueOf(width)); - } - - /** - * Retrieves the width of the specified character. If the metrics for - * a particular character are not available it defaults to returning the - * width for the 'W' character. - */ - public int getCharWidth( char c ) - { - Integer widthInteger = charWidths.get(Character.valueOf(c)); - if (widthInteger == null) { - return 'W' == c ? 0 : getCharWidth('W'); - } - return widthInteger; - } - - public void addChars( char[] characters, int[] widths ) - { - for ( int i = 0; i < characters.length; i++ ) - { - charWidths.put( Character.valueOf(characters[i]), Integer.valueOf(widths[i])); - } - } - - protected static String buildFontHeightProperty(String fontName) { - return "font." + fontName + ".height"; - } - protected static String buildFontWidthsProperty(String fontName) { - return "font." + fontName + ".widths"; - } - protected static String buildFontCharactersProperty(String fontName) { - return "font." + fontName + ".characters"; - } - - /** - * Create an instance of FontDetails by loading them from the - * provided property object. - * @param fontName the font name - * @param fontMetricsProps the property object holding the details of this - * particular font. - * @return a new FontDetails instance. - */ - public static FontDetails create( String fontName, Properties fontMetricsProps ) - { - String heightStr = fontMetricsProps.getProperty( buildFontHeightProperty(fontName) ); - String widthsStr = fontMetricsProps.getProperty( buildFontWidthsProperty(fontName) ); - String charactersStr = fontMetricsProps.getProperty( buildFontCharactersProperty(fontName) ); - - // Ensure that this is a font we know about - if(heightStr == null || widthsStr == null || charactersStr == null) { - // We don't know all we need to about this font - // Since we don't know its sizes, we can't work with it - throw new IllegalArgumentException("The supplied FontMetrics doesn't know about the font '" + fontName + "', so we can't use it. Please add it to your font metrics file (see StaticFontMetrics.getFontDetails"); - } - - int height = Integer.parseInt(heightStr); - FontDetails d = new FontDetails(fontName, height); - String[] charactersStrArray = split(charactersStr, ",", -1); - String[] widthsStrArray = split(widthsStr, ",", -1); - if (charactersStrArray.length != widthsStrArray.length) - throw new RuntimeException("Number of characters does not number of widths for font " + fontName); - for ( int i = 0; i < widthsStrArray.length; i++ ) - { - if (charactersStrArray[i].length() != 0) - d.addChar(charactersStrArray[i].charAt(0), Integer.parseInt(widthsStrArray[i])); - } - return d; - } - - /** - * Gets the width of all characters in a string. - * - * @param str The string to measure. - * @return The width of the string for a 10 point font. - */ - public int getStringWidth(String str) - { - int width = 0; - for (int i = 0; i < str.length(); i++) - { - width += getCharWidth(str.charAt(i)); - } - return width; - } - - /** - * Split the given string into an array of strings using the given - * delimiter. - */ - private static String[] split(String text, String separator, int max) - { - StringTokenizer tok = new StringTokenizer(text, separator); - int listSize = tok.countTokens(); - if(max != -1 && listSize > max) - listSize = max; - String list[] = new String[listSize]; - for(int i = 0; tok.hasMoreTokens(); i++) - { - if(max != -1 && i == listSize - 1) - { - StringBuffer buf = new StringBuffer((text.length() * (listSize - i)) / listSize); - while(tok.hasMoreTokens()) - { - buf.append(tok.nextToken()); - if(tok.hasMoreTokens()) - buf.append(separator); - } - list[i] = buf.toString().trim(); - break; - } - list[i] = tok.nextToken().trim(); - } - - return list; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java deleted file mode 100644 index 3ba57373f..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - - -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherRecord; - -/** - * An anchor is what specifics the position of a shape within a client object - * or within another containing shape. - */ -public abstract class HSSFAnchor { - - protected boolean _isHorizontallyFlipped = false; - protected boolean _isVerticallyFlipped = false; - - public HSSFAnchor() { - createEscherAnchor(); - } - - public HSSFAnchor(int dx1, int dy1, int dx2, int dy2) { - createEscherAnchor(); - setDx1(dx1); - setDy1(dy1); - setDx2(dx2); - setDy2(dy2); - } - - public static HSSFAnchor createAnchorFromEscher(EscherContainerRecord container){ - if (null != container.getChildById(EscherChildAnchorRecord.RECORD_ID)){ - return new HSSFChildAnchor((EscherChildAnchorRecord) container.getChildById(EscherChildAnchorRecord.RECORD_ID)); - } else { - if (null != container.getChildById(EscherClientAnchorRecord.RECORD_ID)){ - return new HSSFClientAnchor((EscherClientAnchorRecord) container.getChildById(EscherClientAnchorRecord.RECORD_ID)); - } - return null; - } - } - - /** - * @return x coordinate of the left up corner - */ - public abstract int getDx1(); - - /** - * @param dx1 x coordinate of the left up corner - */ - public abstract void setDx1(int dx1); - - /** - * @return y coordinate of the left up corner - */ - public abstract int getDy1(); - - /** - * @param dy1 y coordinate of the left up corner - */ - public abstract void setDy1(int dy1); - - /** - * @return y coordinate of the right down corner - */ - public abstract int getDy2(); - - /** - * @param dy2 y coordinate of the right down corner - */ - public abstract void setDy2(int dy2); - - /** - * @return x coordinate of the right down corner - */ - public abstract int getDx2(); - - /** - * @param dx2 x coordinate of the right down corner - */ - public abstract void setDx2(int dx2); - - /** - * @return whether this shape is horizontally flipped - */ - public abstract boolean isHorizontallyFlipped(); - - /** - * @return whether this shape is vertically flipped - */ - public abstract boolean isVerticallyFlipped(); - - protected abstract EscherRecord getEscherAnchor(); - - protected abstract void createEscherAnchor(); -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFAutoFilter.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFAutoFilter.java deleted file mode 100644 index 533dffee3..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFAutoFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; -import org.apache.poi.ss.usermodel.AutoFilter; - -/** - * Represents autofiltering for the specified worksheet. - */ -public final class HSSFAutoFilter implements AutoFilter { - private HSSFSheet _sheet; - - HSSFAutoFilter(HSSFSheet sheet){ - _sheet = sheet; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java deleted file mode 100644 index c4113b615..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java +++ /dev/null @@ -1,367 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.hssf.record.CFRuleBase; -import org.apache.poi.hssf.record.cf.BorderFormatting; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Color; - -/** - * High level representation for Border Formatting component - * of Conditional Formatting settings - */ -public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.BorderFormatting { - private final HSSFWorkbook workbook; - private final CFRuleBase cfRuleRecord; - private final BorderFormatting borderFormatting; - - protected HSSFBorderFormatting(CFRuleBase cfRuleRecord, HSSFWorkbook workbook) { - this.workbook = workbook; - this.cfRuleRecord = cfRuleRecord; - this.borderFormatting = cfRuleRecord.getBorderFormatting(); - } - - protected BorderFormatting getBorderFormattingBlock() { - return borderFormatting; - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderBottom() { - return (short)borderFormatting.getBorderBottom(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderBottomEnum() { - return BorderStyle.valueOf((short)borderFormatting.getBorderBottom()); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderDiagonalEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderDiagonal() { - return (short)borderFormatting.getBorderDiagonal(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderDiagonalEnum() { - return BorderStyle.valueOf((short)borderFormatting.getBorderDiagonal()); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderLeft() { - return (short)borderFormatting.getBorderLeft(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderLeftEnum() { - return BorderStyle.valueOf((short)borderFormatting.getBorderLeft()); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderRightEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderRight() { - return (short)borderFormatting.getBorderRight(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderRightEnum() { - return BorderStyle.valueOf((short)borderFormatting.getBorderRight()); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderTopEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderTop() { - return (short)borderFormatting.getBorderTop(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderTopEnum() { - return BorderStyle.valueOf((short)borderFormatting.getBorderTop()); - } - - @Override - public short getBottomBorderColor() { - return (short)borderFormatting.getBottomBorderColor(); - } - @Override - public HSSFColor getBottomBorderColorColor() { - return workbook.getCustomPalette().getColor( - borderFormatting.getBottomBorderColor() - ); - } - - @Override - public short getDiagonalBorderColor() { - return (short)borderFormatting.getDiagonalBorderColor(); - } - @Override - public HSSFColor getDiagonalBorderColorColor() { - return workbook.getCustomPalette().getColor( - borderFormatting.getDiagonalBorderColor() - ); - } - - @Override - public short getLeftBorderColor() { - return (short)borderFormatting.getLeftBorderColor(); - } - @Override - public HSSFColor getLeftBorderColorColor() { - return workbook.getCustomPalette().getColor( - borderFormatting.getLeftBorderColor() - ); - } - - @Override - public short getRightBorderColor() { - return (short)borderFormatting.getRightBorderColor(); - } - @Override - public HSSFColor getRightBorderColorColor() { - return workbook.getCustomPalette().getColor( - borderFormatting.getRightBorderColor() - ); - } - - @Override - public short getTopBorderColor() { - return (short)borderFormatting.getTopBorderColor(); - } - @Override - public HSSFColor getTopBorderColorColor() { - return workbook.getCustomPalette().getColor( - borderFormatting.getTopBorderColor() - ); - } - - public boolean isBackwardDiagonalOn() { - return borderFormatting.isBackwardDiagonalOn(); - } - public boolean isForwardDiagonalOn() { - return borderFormatting.isForwardDiagonalOn(); - } - - public void setBackwardDiagonalOn(boolean on) { - borderFormatting.setBackwardDiagonalOn(on); - if (on) { - cfRuleRecord.setTopLeftBottomRightBorderModified(on); - } - } - public void setForwardDiagonalOn(boolean on) { - borderFormatting.setForwardDiagonalOn(on); - if (on) { - cfRuleRecord.setBottomLeftTopRightBorderModified(on); - } - } - - @Override - public void setBorderBottom(short border) { - borderFormatting.setBorderBottom(border); - if (border != 0) { - cfRuleRecord.setBottomBorderModified(true); - } else { - cfRuleRecord.setBottomBorderModified(false); - } - } - @Override - public void setBorderBottom(BorderStyle border) { - setBorderBottom(border.getCode()); - } - - @Override - public void setBorderDiagonal(short border) { - borderFormatting.setBorderDiagonal(border); - if (border != 0) { - cfRuleRecord.setBottomLeftTopRightBorderModified(true); - cfRuleRecord.setTopLeftBottomRightBorderModified(true); - } else { - cfRuleRecord.setBottomLeftTopRightBorderModified(false); - cfRuleRecord.setTopLeftBottomRightBorderModified(false); - } - } - @Override - public void setBorderDiagonal(BorderStyle border) { - setBorderDiagonal(border.getCode()); - } - - @Override - public void setBorderLeft(short border) { - borderFormatting.setBorderLeft(border); - if (border != 0) { - cfRuleRecord.setLeftBorderModified(true); - } else { - cfRuleRecord.setLeftBorderModified(false); - } - } - @Override - public void setBorderLeft(BorderStyle border) { - setBorderLeft(border.getCode()); - } - - @Override - public void setBorderRight(short border) { - borderFormatting.setBorderRight(border); - if (border != 0) { - cfRuleRecord.setRightBorderModified(true); - } else { - cfRuleRecord.setRightBorderModified(false); - } - } - @Override - public void setBorderRight(BorderStyle border) { - setBorderRight(border.getCode()); - } - - @Override - public void setBorderTop(short border) { - borderFormatting.setBorderTop(border); - if (border != 0) { - cfRuleRecord.setTopBorderModified(true); - } else { - cfRuleRecord.setTopBorderModified(false); - } - } - @Override - public void setBorderTop(BorderStyle border) { - setBorderTop(border.getCode()); - } - - @Override - public void setBottomBorderColor(short color) { - borderFormatting.setBottomBorderColor(color); - if (color != 0) { - cfRuleRecord.setBottomBorderModified(true); - } else { - cfRuleRecord.setBottomBorderModified(false); - } - } - public void setBottomBorderColor(Color color) { - HSSFColor hcolor = HSSFColor.toHSSFColor(color); - if (hcolor == null) { - setBottomBorderColor((short)0); - } else { - setBottomBorderColor(hcolor.getIndex()); - } - } - - @Override - public void setDiagonalBorderColor(short color) { - borderFormatting.setDiagonalBorderColor(color); - if (color != 0) { - cfRuleRecord.setBottomLeftTopRightBorderModified(true); - cfRuleRecord.setTopLeftBottomRightBorderModified(true); - } else { - cfRuleRecord.setBottomLeftTopRightBorderModified(false); - cfRuleRecord.setTopLeftBottomRightBorderModified(false); - } - } - @Override - public void setDiagonalBorderColor(Color color) { - HSSFColor hcolor = HSSFColor.toHSSFColor(color); - if (hcolor == null) { - setDiagonalBorderColor((short)0); - } else { - setDiagonalBorderColor(hcolor.getIndex()); - } - } - - @Override - public void setLeftBorderColor(short color) { - borderFormatting.setLeftBorderColor(color); - if (color != 0) { - cfRuleRecord.setLeftBorderModified(true); - } else { - cfRuleRecord.setLeftBorderModified(false); - } - } - @Override - public void setLeftBorderColor(Color color) { - HSSFColor hcolor = HSSFColor.toHSSFColor(color); - if (hcolor == null) { - setLeftBorderColor((short)0); - } else { - setLeftBorderColor(hcolor.getIndex()); - } - } - - @Override - public void setRightBorderColor(short color) { - borderFormatting.setRightBorderColor(color); - if (color != 0) { - cfRuleRecord.setRightBorderModified(true); - } else { - cfRuleRecord.setRightBorderModified(false); - } - } - @Override - public void setRightBorderColor(Color color) { - HSSFColor hcolor = HSSFColor.toHSSFColor(color); - if (hcolor == null) { - setRightBorderColor((short)0); - } else { - setRightBorderColor(hcolor.getIndex()); - } - } - - @Override - public void setTopBorderColor(short color) { - borderFormatting.setTopBorderColor(color); - if (color != 0) { - cfRuleRecord.setTopBorderModified(true); - } else { - cfRuleRecord.setTopBorderModified(false); - } - } - @Override - public void setTopBorderColor(Color color) { - HSSFColor hcolor = HSSFColor.toHSSFColor(color); - if (hcolor == null) { - setTopBorderColor((short)0); - } else { - setTopBorderColor(hcolor.getIndex()); - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java deleted file mode 100644 index 981cbd482..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ /dev/null @@ -1,1288 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.model.InternalWorkbook; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.HyperlinkRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; -import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.ptg.ExpPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.NumberToTextConverter; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; - -/** - * High level representation of a cell in a row of a spreadsheet. - * Cells can be numeric, formula-based or string-based (text). The cell type - * specifies this. String cells cannot contain numbers and numeric cells cannot - * contain strings (at least according to our model). Client apps should do the - * conversions themselves. Formula cells have the formula string, as well as - * the formula result, which can be numeric or string. - *

    - * Cells should have their number (0 based) before being added to a row. Only - * cells that have values should be added. - *

    - */ -public class HSSFCell implements Cell { - private static final String FILE_FORMAT_NAME = "BIFF8"; - /** - * The maximum number of columns in BIFF8 - */ - public static final int LAST_COLUMN_NUMBER = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); // 2^8 - 1 - private static final String LAST_COLUMN_NAME = SpreadsheetVersion.EXCEL97.getLastColumnName(); - - public final static short ENCODING_UNCHANGED = -1; - public final static short ENCODING_COMPRESSED_UNICODE = 0; - public final static short ENCODING_UTF_16 = 1; - - private final HSSFWorkbook _book; - private final HSSFSheet _sheet; - private CellType _cellType; - private HSSFRichTextString _stringValue; - private CellValueRecordInterface _record; - private HSSFComment _comment; - - /** - * Creates new Cell - Should only be called by HSSFRow. This creates a cell - * from scratch. - *

    - * When the cell is initially created it is set to {@link CellType#BLANK}. Cell types - * can be changed/overwritten by calling setCellValue with the appropriate - * type as a parameter although conversions from one type to another may be - * prohibited. - * - * @param book - Workbook record of the workbook containing this cell - * @param sheet - Sheet record of the sheet containing this cell - * @param row - the row of this cell - * @param col - the column for this cell - * - * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(int) - */ - protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, int row, short col) - { - checkBounds(col); - _stringValue = null; - _book = book; - _sheet = sheet; - - // Relying on the fact that by default the cellType is set to 0 which - // is different to {@link CellType#BLANK} hence the following method call correctly - // creates a new blank cell. - short xfindex = sheet.getSheet().getXFIndexForColAt(col); - setCellType(CellType.BLANK, false, row, col,xfindex); - } - - /** - * Returns the HSSFSheet this cell belongs to - * - * @return the HSSFSheet that owns this cell - */ - public HSSFSheet getSheet() { - return _sheet; - } - - /** - * Returns the HSSFRow this cell belongs to - * - * @return the HSSFRow that owns this cell - */ - public HSSFRow getRow() { - int rowIndex = getRowIndex(); - return _sheet.getRow(rowIndex); - } - - /** - * Creates new Cell - Should only be called by HSSFRow. This creates a cell - * from scratch. - * - * @param book - Workbook record of the workbook containing this cell - * @param sheet - Sheet record of the sheet containing this cell - * @param row - the row of this cell - * @param col - the column for this cell - * @param type - Type of cell - * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(int,int) - */ - protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, int row, short col, - CellType type) - { - checkBounds(col); - _cellType = CellType._NONE; // Force 'setCellType' to create a first Record - _stringValue = null; - _book = book; - _sheet = sheet; - - short xfindex = sheet.getSheet().getXFIndexForColAt(col); - setCellType(type,false,row,col,xfindex); - } - - /** - * Creates an HSSFCell from a CellValueRecordInterface. HSSFSheet uses this when - * reading in cells from an existing sheet. - * - * @param book - Workbook record of the workbook containing this cell - * @param sheet - Sheet record of the sheet containing this cell - * @param cval - the Cell Value Record we wish to represent - */ - protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, CellValueRecordInterface cval) { - _record = cval; - _cellType = determineType(cval); - _stringValue = null; - _book = book; - _sheet = sheet; - switch (_cellType) - { - case STRING : - _stringValue = new HSSFRichTextString(book.getWorkbook(), (LabelSSTRecord ) cval); - break; - - case BLANK : - break; - - case FORMULA : - _stringValue=new HSSFRichTextString(((FormulaRecordAggregate) cval).getStringValue()); - break; - - default : - break; - } - } - - - /** - * used internally -- given a cell value record, figure out its type - */ - private static CellType determineType(CellValueRecordInterface cval) { - if (cval instanceof FormulaRecordAggregate) { - return CellType.FORMULA; - } - // all others are plain BIFF records - Record record = ( Record ) cval; - switch (record.getSid()) { - - case NumberRecord.sid : return CellType.NUMERIC; - case BlankRecord.sid : return CellType.BLANK; - case LabelSSTRecord.sid : return CellType.STRING; - case BoolErrRecord.sid : - BoolErrRecord boolErrRecord = ( BoolErrRecord ) record; - - return boolErrRecord.isBoolean() - ? CellType.BOOLEAN - : CellType.ERROR; - } - throw new RuntimeException("Bad cell value rec (" + cval.getClass().getName() + ")"); - } - - /** - * Returns the Workbook that this Cell is bound to - */ - protected InternalWorkbook getBoundWorkbook() { - return _book.getWorkbook(); - } - - /** - * @return the (zero based) index of the row containing this cell - */ - @Override - public int getRowIndex() { - return _record.getRow(); - } - - /** - * Updates the cell record's idea of what - * column it belongs in (0 based) - * @param num the new cell number - */ - protected void updateCellNum(short num) - { - _record.setColumn(num); - } - - @Override - public int getColumnIndex() { - return _record.getColumn() & 0xFFFF; - } - - /** - * {@inheritDoc} - */ - @Override - public CellAddress getAddress() { - return new CellAddress(this); - } - - /** - * Set the cells type (numeric, formula or string). - * If the cell currently contains a value, the value will - * be converted to match the new type, if possible. - * @see CellType#NUMERIC - * @see CellType#STRING - * @see CellType#FORMULA - * @see CellType#BLANK - * @see CellType#BOOLEAN - * @see CellType#ERROR - * @deprecated POI 3.15 beta 3. Use {@link #setCellType(CellType)} instead. - */ - @Override - public void setCellType(int cellType) { - setCellType(CellType.forInt(cellType)); - } - /** - * Set the cells type (numeric, formula or string). - * If the cell currently contains a value, the value will - * be converted to match the new type, if possible. - */ - @Override - public void setCellType(CellType cellType) { - notifyFormulaChanging(); - if(isPartOfArrayFormulaGroup()){ - notifyArrayFormulaChanging(); - } - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - setCellType(cellType, true, row, col, styleIndex); - } - - /** - * sets the cell type. The setValue flag indicates whether to bother about - * trying to preserve the current value in the new record if one is created. - *

    - * The @see #setCellValue method will call this method with false in setValue - * since it will overwrite the cell value later - * - */ - - private void setCellType(CellType cellType, boolean setValue, int row,short col, short styleIndex) - { - switch (cellType) - { - - case FORMULA : - FormulaRecordAggregate frec; - - if (cellType != _cellType) { - frec = _sheet.getSheet().getRowsAggregate().createFormula(row, col); - } else { - frec = (FormulaRecordAggregate) _record; - frec.setRow(row); - frec.setColumn(col); - } - if (setValue) - { - frec.getFormulaRecord().setValue(getNumericCellValue()); - } - frec.setXFIndex(styleIndex); - _record = frec; - break; - - case NUMERIC : - NumberRecord nrec = null; - - if (cellType != _cellType) - { - nrec = new NumberRecord(); - } - else - { - nrec = ( NumberRecord ) _record; - } - nrec.setColumn(col); - if (setValue) - { - nrec.setValue(getNumericCellValue()); - } - nrec.setXFIndex(styleIndex); - nrec.setRow(row); - _record = nrec; - break; - - case STRING : - LabelSSTRecord lrec; - - if (cellType == _cellType) { - lrec = (LabelSSTRecord) _record; - } else { - lrec = new LabelSSTRecord(); - lrec.setColumn(col); - lrec.setRow(row); - lrec.setXFIndex(styleIndex); - } - if (setValue) { - String str = convertCellValueToString(); - if(str == null) { - // bug 55668: don't try to store null-string when formula - // results in empty/null value - setCellType(CellType.BLANK, false, row, col, styleIndex); - return; - } else { - int sstIndex = _book.getWorkbook().addSSTString(new UnicodeString(str)); - lrec.setSSTIndex(sstIndex); - UnicodeString us = _book.getWorkbook().getSSTString(sstIndex); - _stringValue = new HSSFRichTextString(); - _stringValue.setUnicodeString(us); - } - } - _record = lrec; - break; - - case BLANK : - BlankRecord brec = null; - - if (cellType != _cellType) - { - brec = new BlankRecord(); - } - else - { - brec = ( BlankRecord ) _record; - } - brec.setColumn(col); - - // During construction the cellStyle may be null for a Blank cell. - brec.setXFIndex(styleIndex); - brec.setRow(row); - _record = brec; - break; - - case BOOLEAN : - BoolErrRecord boolRec = null; - - if (cellType != _cellType) - { - boolRec = new BoolErrRecord(); - } - else - { - boolRec = ( BoolErrRecord ) _record; - } - boolRec.setColumn(col); - if (setValue) - { - boolRec.setValue(convertCellValueToBoolean()); - } - boolRec.setXFIndex(styleIndex); - boolRec.setRow(row); - _record = boolRec; - break; - - case ERROR : - BoolErrRecord errRec = null; - - if (cellType != _cellType) - { - errRec = new BoolErrRecord(); - } - else - { - errRec = ( BoolErrRecord ) _record; - } - errRec.setColumn(col); - if (setValue) - { - errRec.setValue(FormulaError.VALUE.getCode()); - } - errRec.setXFIndex(styleIndex); - errRec.setRow(row); - _record = errRec; - break; - default : - throw new IllegalStateException("Invalid cell type: " + cellType); - } - if (cellType != _cellType && - _cellType != CellType._NONE ) // Special Value to indicate an uninitialized Cell - { - _sheet.getSheet().replaceValueRecord(_record); - } - _cellType = cellType; - } - - /** - * get the cells type (numeric, formula or string) - * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * @deprecated 3.15. Will be return a {@link CellType} enum in the future. - */ - @Override - public int getCellType() - { - return getCellTypeEnum().getCode(); - } - - /** - * get the cells type (numeric, formula or string) - * @since POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCellTypeEnum() - { - return _cellType; - } - - /** - * set a numeric value for the cell - * - * @param value the numeric value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numeric cell and set its value. - */ - @SuppressWarnings("fallthrough") - @Override - public void setCellValue(double value) { - if(Double.isInfinite(value)) { - // Excel does not support positive/negative infinities, - // rather, it gives a #DIV/0! error in these cases. - setCellErrorValue(FormulaError.DIV0.getCode()); - } else if (Double.isNaN(value)){ - // Excel does not support Not-a-Number (NaN), - // instead it immediately generates a #NUM! error. - setCellErrorValue(FormulaError.NUM.getCode()); - } else { - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - - switch (_cellType) { - default: - setCellType(CellType.NUMERIC, false, row, col, styleIndex); - // fall through - case NUMERIC: - (( NumberRecord ) _record).setValue(value); - break; - case FORMULA: - ((FormulaRecordAggregate)_record).setCachedDoubleResult(value); - break; - } - } - - } - - /** - * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as - * a date. - * - * @param value the date value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numeric cell and set its value. - */ - public void setCellValue(Date value) - { - setCellValue(HSSFDateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing())); - } - - /** - * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as - * a date. - * - * This will set the cell value based on the Calendar's timezone. As Excel - * does not support timezones this means that both 20:00+03:00 and - * 20:00-03:00 will be reported as the same value (20:00) even that there - * are 6 hours difference between the two times. This difference can be - * preserved by using setCellValue(value.getTime()) which will - * automatically shift the times to the default timezone. - * - * @param value the date value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For othertypes we - * will change the cell to a numeric cell and set its value. - */ - public void setCellValue(Calendar value) - { - setCellValue( HSSFDateUtil.getExcelDate(value, _book.getWorkbook().isUsing1904DateWindowing()) ); - } - - /** - * set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * cached string result, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - public void setCellValue(String value) { - HSSFRichTextString str = value == null ? null : new HSSFRichTextString(value); - setCellValue(str); - } - - /** - * Set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - - public void setCellValue(RichTextString value) - { - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - if (value == null) - { - notifyFormulaChanging(); - setCellType(CellType.BLANK, false, row, col, styleIndex); - return; - } - - if(value.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){ - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - - if (_cellType == CellType.FORMULA) { - // Set the 'pre-evaluated result' for the formula - // note - formulas do not preserve text formatting. - FormulaRecordAggregate fr = (FormulaRecordAggregate) _record; - fr.setCachedStringResult(value.getString()); - // Update our local cache to the un-formatted version - _stringValue = new HSSFRichTextString(value.getString()); - - // All done - return; - } - - // If we get here, we're not dealing with a formula, - // so handle things as a normal rich text cell - - if (_cellType != CellType.STRING) { - setCellType(CellType.STRING, false, row, col, styleIndex); - } - int index = 0; - - HSSFRichTextString hvalue = (HSSFRichTextString) value; - UnicodeString str = hvalue.getUnicodeString(); - index = _book.getWorkbook().addSSTString(str); - (( LabelSSTRecord ) _record).setSSTIndex(index); - _stringValue = hvalue; - _stringValue.setWorkbookReferences(_book.getWorkbook(), (( LabelSSTRecord ) _record)); - _stringValue.setUnicodeString(_book.getWorkbook().getSSTString(index)); - } - - public void setCellFormula(String formula) { - if(isPartOfArrayFormulaGroup()){ - notifyArrayFormulaChanging(); - } - - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - - if (formula==null) { - notifyFormulaChanging(); - setCellType(CellType.BLANK, false, row, col, styleIndex); - return; - } - int sheetIndex = _book.getSheetIndex(_sheet); - Ptg[] ptgs = HSSFFormulaParser.parse(formula, _book, FormulaType.CELL, sheetIndex); - setCellType(CellType.FORMULA, false, row, col, styleIndex); - FormulaRecordAggregate agg = (FormulaRecordAggregate) _record; - FormulaRecord frec = agg.getFormulaRecord(); - frec.setOptions((short) 2); - frec.setValue(0); - - //only set to default if there is no extended format index already set - if (agg.getXFIndex() == (short)0) { - agg.setXFIndex((short) 0x0f); - } - agg.setParsedExpression(ptgs); - } - /** - * Should be called any time that a formula could potentially be deleted. - * Does nothing if this cell currently does not hold a formula - */ - private void notifyFormulaChanging() { - if (_record instanceof FormulaRecordAggregate) { - ((FormulaRecordAggregate)_record).notifyFormulaChanging(); - } - } - - public String getCellFormula() { - if (!(_record instanceof FormulaRecordAggregate)) { - throw typeMismatch(CellType.FORMULA, _cellType, true); - } - return HSSFFormulaParser.toFormulaString(_book, ((FormulaRecordAggregate)_record).getFormulaTokens()); - } - - private static RuntimeException typeMismatch(CellType expectedTypeCode, CellType actualTypeCode, boolean isFormulaCell) { - String msg = "Cannot get a " + expectedTypeCode + " value from a " + actualTypeCode - + " " + (isFormulaCell ? "formula " : "") + "cell"; - return new IllegalStateException(msg); - } - private static void checkFormulaCachedValueType(CellType expectedTypeCode, FormulaRecord fr) { - CellType cachedValueType = CellType.forInt(fr.getCachedResultType()); - if (cachedValueType != expectedTypeCode) { - throw typeMismatch(expectedTypeCode, cachedValueType, true); - } - } - - /** - * Get the value of the cell as a number. - * For strings we throw an exception. - * For blank cells we return a 0. - * See {@link HSSFDataFormatter} for turning this - * number into a string similar to that which - * Excel would render this number as. - */ - public double getNumericCellValue() { - - switch(_cellType) { - case BLANK: - return 0.0; - case NUMERIC: - return ((NumberRecord)_record).getValue(); - default: - throw typeMismatch(CellType.NUMERIC, _cellType, false); - case FORMULA: - break; - } - FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord(); - checkFormulaCachedValueType(CellType.NUMERIC, fr); - return fr.getValue(); - } - - /** - * Get the value of the cell as a date. - * For strings we throw an exception. - * For blank cells we return a null. - * See {@link HSSFDataFormatter} for formatting - * this date into a string similar to how excel does. - */ - public Date getDateCellValue() { - - if (_cellType == CellType.BLANK) { - return null; - } - double value = getNumericCellValue(); - if (_book.getWorkbook().isUsing1904DateWindowing()) { - return HSSFDateUtil.getJavaDate(value, true); - } - return HSSFDateUtil.getJavaDate(value, false); - } - - /** - * get the value of the cell as a string - for numeric cells we throw an exception. - * For blank cells we return an empty string. - * For formulaCells that are not string Formulas, we throw an exception - */ - public String getStringCellValue() - { - HSSFRichTextString str = getRichStringCellValue(); - return str.getString(); - } - - /** - * get the value of the cell as a string - for numeric cells we throw an exception. - * For blank cells we return an empty string. - * For formulaCells that are not string Formulas, we throw an exception - */ - public HSSFRichTextString getRichStringCellValue() { - - switch(_cellType) { - case BLANK: - return new HSSFRichTextString(""); - case STRING: - return _stringValue; - default: - throw typeMismatch(CellType.STRING, _cellType, false); - case FORMULA: - break; - } - FormulaRecordAggregate fra = ((FormulaRecordAggregate)_record); - checkFormulaCachedValueType(CellType.STRING, fra.getFormulaRecord()); - String strVal = fra.getStringValue(); - return new HSSFRichTextString(strVal == null ? "" : strVal); - } - - /** - * set a boolean value for the cell - * - * @param value the boolean value to set this cell to. For formulas we'll set the - * precalculated value, for booleans we'll set its value. For other types we - * will change the cell to a boolean cell and set its value. - */ - @SuppressWarnings("fallthrough") - public void setCellValue(boolean value) { - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - - switch (_cellType) { - default: - setCellType(CellType.BOOLEAN, false, row, col, styleIndex); - // fall through - case BOOLEAN: - (( BoolErrRecord ) _record).setValue(value); - break; - case FORMULA: - ((FormulaRecordAggregate)_record).setCachedBooleanResult(value); - break; - } - } - - /** - * set a error value for the cell - * - * @param errorCode the error value to set this cell to. For formulas we'll set the - * precalculated value , for errors we'll set - * its value. For other types we will change the cell to an error - * cell and set its value. - * For error code byte, see {@link FormulaError}. - * @deprecated 3.15 beta 2. Use {@link #setCellErrorValue(FormulaError)} instead. - */ - public void setCellErrorValue(byte errorCode) { - FormulaError error = FormulaError.forInt(errorCode); - setCellErrorValue(error); - } - /** - * set a error value for the cell - * - * @param error the error value to set this cell to. For formulas we'll set the - * precalculated value , for errors we'll set - * its value. For other types we will change the cell to an error - * cell and set its value. - */ - @SuppressWarnings("fallthrough") - public void setCellErrorValue(FormulaError error) { - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - switch (_cellType) { - default: - setCellType(CellType.ERROR, false, row, col, styleIndex); - // fall through - case ERROR: - (( BoolErrRecord ) _record).setValue(error); - break; - case FORMULA: - ((FormulaRecordAggregate)_record).setCachedErrorResult(error.getCode()); - break; - } - } - - - /** - * Chooses a new boolean value for the cell when its type is changing.

    - * - * Usually the caller is calling setCellType() with the intention of calling - * setCellValue(boolean) straight afterwards. This method only exists to give - * the cell a somewhat reasonable value until the setCellValue() call (if at all). - * TODO - perhaps a method like setCellTypeAndValue(int, Object) should be introduced to avoid this - */ - private boolean convertCellValueToBoolean() { - - switch (_cellType) { - case BOOLEAN: - return (( BoolErrRecord ) _record).getBooleanValue(); - case STRING: - int sstIndex = ((LabelSSTRecord)_record).getSSTIndex(); - String text = _book.getWorkbook().getSSTString(sstIndex).getString(); - return Boolean.valueOf(text).booleanValue(); - case NUMERIC: - return ((NumberRecord)_record).getValue() != 0; - - case FORMULA: - // use cached formula result if it's the right type: - FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord(); - checkFormulaCachedValueType(CellType.BOOLEAN, fr); - return fr.getCachedBooleanValue(); - // Other cases convert to false - // These choices are not well justified. - case ERROR: - case BLANK: - return false; - } - throw new RuntimeException("Unexpected cell type (" + _cellType + ")"); - } - private String convertCellValueToString() { - - switch (_cellType) { - case BLANK: - return ""; - case BOOLEAN: - return ((BoolErrRecord) _record).getBooleanValue() ? "TRUE" : "FALSE"; - case STRING: - int sstIndex = ((LabelSSTRecord)_record).getSSTIndex(); - return _book.getWorkbook().getSSTString(sstIndex).getString(); - case NUMERIC: - return NumberToTextConverter.toText(((NumberRecord)_record).getValue()); - case ERROR: - return FormulaError.forInt(((BoolErrRecord)_record).getErrorValue()).getString(); - case FORMULA: - // should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator - // just use cached formula result instead - break; - default: - throw new IllegalStateException("Unexpected cell type (" + _cellType + ")"); - } - FormulaRecordAggregate fra = ((FormulaRecordAggregate)_record); - FormulaRecord fr = fra.getFormulaRecord(); - switch (CellType.forInt(fr.getCachedResultType())) { - case BOOLEAN: - return fr.getCachedBooleanValue() ? "TRUE" : "FALSE"; - case STRING: - return fra.getStringValue(); - case NUMERIC: - return NumberToTextConverter.toText(fr.getValue()); - case ERROR: - return FormulaError.forInt(fr.getCachedErrorValue()).getString(); - default: - throw new IllegalStateException("Unexpected formula result type (" + _cellType + ")"); - } - - } - - /** - * get the value of the cell as a boolean. For strings, numbers, and errors, we throw an exception. - * For blank cells we return a false. - */ - @Override - public boolean getBooleanCellValue() { - - switch(_cellType) { - case BLANK: - return false; - case BOOLEAN: - return (( BoolErrRecord ) _record).getBooleanValue(); - case FORMULA: - break; - default: - throw typeMismatch(CellType.BOOLEAN, _cellType, false); - } - FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord(); - checkFormulaCachedValueType(CellType.BOOLEAN, fr); - return fr.getCachedBooleanValue(); - } - - /** - * get the value of the cell as an error code. For strings, numbers, and booleans, we throw an exception. - * For blank cells we return a 0. - */ - @Override - public byte getErrorCellValue() { - switch(_cellType) { - case ERROR: - return (( BoolErrRecord ) _record).getErrorValue(); - case FORMULA: - break; - default: - throw typeMismatch(CellType.ERROR, _cellType, false); - } - FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord(); - checkFormulaCachedValueType(CellType.ERROR, fr); - return (byte) fr.getCachedErrorValue(); - } - - /** - *

    Set the style for the cell. The style should be an HSSFCellStyle created/retreived from - * the HSSFWorkbook.

    - * - *

    To change the style of a cell without affecting other cells that use the same style, - * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(org.apache.poi.ss.usermodel.Cell, java.util.Map)}

    - * - * @param style reference contained in the workbook - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle() - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(int) - */ - public void setCellStyle(CellStyle style) { - setCellStyle( (HSSFCellStyle)style ); - } - public void setCellStyle(HSSFCellStyle style) { - // A style of null means resetting back to the default style - if (style == null) { - _record.setXFIndex((short)0xf); - return; - } - - // Verify the style really does belong to our workbook - style.verifyBelongsToWorkbook(_book); - - short styleIndex; - if(style.getUserStyleName() != null) { - styleIndex = applyUserCellStyle(style); - } else { - styleIndex = style.getIndex(); - } - - // Change our cell record to use this style - _record.setXFIndex(styleIndex); - } - - /** - * get the style for the cell. This is a reference to a cell style contained in the workbook - * object. - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(int) - */ - public HSSFCellStyle getCellStyle() - { - short styleIndex=_record.getXFIndex(); - ExtendedFormatRecord xf = _book.getWorkbook().getExFormatAt(styleIndex); - return new HSSFCellStyle(styleIndex, xf, _book); - } - - /** - * Should only be used by HSSFSheet and friends. Returns the low level CellValueRecordInterface record - * - * @return CellValueRecordInterface representing the cell via the low level api. - */ - - protected CellValueRecordInterface getCellValueRecord() - { - return _record; - } - - /** - * @throws RuntimeException if the bounds are exceeded. - */ - private static void checkBounds(int cellIndex) { - if (cellIndex < 0 || cellIndex > LAST_COLUMN_NUMBER) { - throw new IllegalArgumentException("Invalid column index (" + cellIndex - + "). Allowable column range for " + FILE_FORMAT_NAME + " is (0.." - + LAST_COLUMN_NUMBER + ") or ('A'..'" + LAST_COLUMN_NAME + "')"); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setAsActiveCell() - { - int row=_record.getRow(); - short col=_record.getColumn(); - _sheet.getSheet().setActiveCellRow(row); - _sheet.getSheet().setActiveCellCol(col); - } - - /** - * Returns a string representation of the cell - * - * This method returns a simple representation, - * anything more complex should be in user code, with - * knowledge of the semantics of the sheet being processed. - * - * Formula cells return the formula string, - * rather than the formula result. - * Dates are displayed in dd-MMM-yyyy format - * Errors are displayed as #ERR<errIdx> - */ - public String toString() { - switch (getCellTypeEnum()) { - case BLANK: - return ""; - case BOOLEAN: - return getBooleanCellValue()?"TRUE":"FALSE"; - case ERROR: - return ErrorEval.getText((( BoolErrRecord ) _record).getErrorValue()); - case FORMULA: - return getCellFormula(); - case NUMERIC: - //TODO apply the dataformat for this cell - if (HSSFDateUtil.isCellDateFormatted(this)) { - SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale()); - sdf.setTimeZone(LocaleUtil.getUserTimeZone()); - return sdf.format(getDateCellValue()); - } - return String.valueOf(getNumericCellValue()); - case STRING: - return getStringCellValue(); - default: - return "Unknown Cell Type: " + getCellTypeEnum(); - } - } - - /** - * Assign a comment to this cell. If the supplied - * comment is null, the comment for this cell - * will be removed. - * - * @param comment comment associated with this cell - */ - public void setCellComment(Comment comment){ - if(comment == null) { - removeCellComment(); - return; - } - - comment.setRow(_record.getRow()); - comment.setColumn(_record.getColumn()); - _comment = (HSSFComment)comment; - } - - /** - * Returns comment associated with this cell - * - * @return comment associated with this cell - */ - public HSSFComment getCellComment(){ - if (_comment == null) { - _comment = _sheet.findCellComment(_record.getRow(), _record.getColumn()); - } - return _comment; - } - - /** - * Removes the comment for this cell, if - * there is one. - * WARNING - some versions of excel will loose - * all comments after performing this action! - */ - public void removeCellComment() { - HSSFComment comment = _sheet.findCellComment(_record.getRow(), _record.getColumn()); - _comment = null; - if (null == comment){ - return; - } - _sheet.getDrawingPatriarch().removeShape(comment); - } - - /** - * @return hyperlink associated with this cell or null if not found - */ - @Override - public HSSFHyperlink getHyperlink(){ - return _sheet.getHyperlink(_record.getRow(), _record.getColumn()); - } - - /** - * Assign a hyperlink to this cell. If the supplied hyperlink is null, the - * hyperlink for this cell will be removed. - * - * @param hyperlink hyperlink associated with this cell - */ - @Override - public void setHyperlink(Hyperlink hyperlink){ - if (hyperlink == null) { - removeHyperlink(); - return; - } - - HSSFHyperlink link = (HSSFHyperlink)hyperlink; - - link.setFirstRow(_record.getRow()); - link.setLastRow(_record.getRow()); - link.setFirstColumn(_record.getColumn()); - link.setLastColumn(_record.getColumn()); - - switch(link.getTypeEnum()){ - case EMAIL: - case URL: - link.setLabel("url"); - break; - case FILE: - link.setLabel("file"); - break; - case DOCUMENT: - link.setLabel("place"); - break; - default: - break; - } - - List records = _sheet.getSheet().getRecords(); - int eofLoc = records.size() - 1; - records.add( eofLoc, link.record ); - } - - /** - * Removes the hyperlink for this cell, if there is one. - */ - public void removeHyperlink() { - for (Iterator it = _sheet.getSheet().getRecords().iterator(); it.hasNext();) { - RecordBase rec = it.next(); - if (rec instanceof HyperlinkRecord) { - HyperlinkRecord link = (HyperlinkRecord) rec; - if (link.getFirstColumn() == _record.getColumn() && link.getFirstRow() == _record.getRow()) { - it.remove(); - return; - } - } - } - } - - /** - * Only valid for formula cells - * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCachedFormulaResultType() { - return getCachedFormulaResultTypeEnum().getCode(); - } - - /** - * Only valid for formula cells - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @since POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCachedFormulaResultTypeEnum() { - if (_cellType != CellType.FORMULA) { - throw new IllegalStateException("Only formula cells have cached results"); - } - int code = ((FormulaRecordAggregate)_record).getFormulaRecord().getCachedResultType(); - return CellType.forInt(code); - } - - void setCellArrayFormula(CellRangeAddress range) { - int row = _record.getRow(); - short col = _record.getColumn(); - short styleIndex = _record.getXFIndex(); - setCellType(CellType.FORMULA, false, row, col, styleIndex); - - // Billet for formula in rec - Ptg[] ptgsForCell = {new ExpPtg(range.getFirstRow(), range.getFirstColumn())}; - FormulaRecordAggregate agg = (FormulaRecordAggregate) _record; - agg.setParsedExpression(ptgsForCell); - } - - public CellRangeAddress getArrayFormulaRange() { - if (_cellType != CellType.FORMULA) { - String ref = new CellReference(this).formatAsString(); - throw new IllegalStateException("Cell " + ref - + " is not part of an array formula."); - } - return ((FormulaRecordAggregate)_record).getArrayFormulaRange(); - } - - public boolean isPartOfArrayFormulaGroup() { - if (_cellType != CellType.FORMULA) { - return false; - } - return ((FormulaRecordAggregate)_record).isPartOfArrayFormula(); - } - - /** - * The purpose of this method is to validate the cell state prior to modification - * - * @see #notifyArrayFormulaChanging() - */ - void notifyArrayFormulaChanging(String msg){ - CellRangeAddress cra = getArrayFormulaRange(); - if(cra.getNumberOfCells() > 1) { - throw new IllegalStateException(msg); - } - //un-register the single-cell array formula from the parent XSSFSheet - getRow().getSheet().removeArrayFormula(this); - } - - /** - * Called when this cell is modified. - *

    - * The purpose of this method is to validate the cell state prior to modification. - *

    - * - * @see #setCellType(int) - * @see #setCellFormula(String) - * @see HSSFRow#removeCell(org.apache.poi.ss.usermodel.Cell) - * @see org.apache.poi.hssf.usermodel.HSSFSheet#removeRow(org.apache.poi.ss.usermodel.Row) - * @see org.apache.poi.hssf.usermodel.HSSFSheet#shiftRows(int, int, int) - * @see org.apache.poi.hssf.usermodel.HSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress) - * @throws IllegalStateException if modification is not allowed - */ - void notifyArrayFormulaChanging(){ - CellReference ref = new CellReference(this); - String msg = "Cell "+ref.formatAsString()+" is part of a multi-cell array formula. " + - "You cannot change part of an array."; - notifyArrayFormulaChanging(msg); - } - - /** - * Applying a user-defined style (UDS) is special. Excel does not directly reference user-defined styles, but - * instead create a 'proxy' ExtendedFormatRecord referencing the UDS as parent. - * - * The proceudre to apply a UDS is as follows: - * - * 1. search for a ExtendedFormatRecord with parentIndex == style.getIndex() - * and xfType == ExtendedFormatRecord.XF_CELL. - * 2. if not found then create a new ExtendedFormatRecord and copy all attributes from the user-defined style - * and set the parentIndex to be style.getIndex() - * 3. return the index of the ExtendedFormatRecord, this will be assigned to the parent cell record - * - * @param style the user style to apply - * - * @return the index of a ExtendedFormatRecord record that will be referenced by the cell - */ - private short applyUserCellStyle(HSSFCellStyle style){ - if(style.getUserStyleName() == null) { - throw new IllegalArgumentException("Expected user-defined style"); - } - - InternalWorkbook iwb = _book.getWorkbook(); - short userXf = -1; - int numfmt = iwb.getNumExFormats(); - for(short i = 0; i < numfmt; i++){ - ExtendedFormatRecord xf = iwb.getExFormatAt(i); - if(xf.getXFType() == ExtendedFormatRecord.XF_CELL && xf.getParentIndex() == style.getIndex() ){ - userXf = i; - break; - } - } - short styleIndex; - if (userXf == -1){ - ExtendedFormatRecord xfr = iwb.createCellXF(); - xfr.cloneStyleFrom(iwb.getExFormatAt(style.getIndex())); - xfr.setIndentionOptions((short)0); - xfr.setXFType(ExtendedFormatRecord.XF_CELL); - xfr.setParentIndex(style.getIndex()); - styleIndex = (short)numfmt; - } else { - styleIndex = userXf; - } - - return styleIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java deleted file mode 100644 index 542ee2210..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java +++ /dev/null @@ -1,1136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.usermodel; - -import java.util.List; - -import org.apache.poi.hssf.model.InternalWorkbook; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.FontRecord; -import org.apache.poi.hssf.record.FormatRecord; -import org.apache.poi.hssf.record.StyleRecord; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.util.Removal; - -/** - * High level representation of the style of a cell in a sheet of a workbook. - * - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle() - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(int) - * @see org.apache.poi.hssf.usermodel.HSSFCell#setCellStyle(HSSFCellStyle) - */ -public final class HSSFCellStyle implements CellStyle { - private final ExtendedFormatRecord _format; - private final short _index; - private final InternalWorkbook _workbook; - - - /** Creates new HSSFCellStyle why would you want to do this?? */ - protected HSSFCellStyle(short index, ExtendedFormatRecord rec, HSSFWorkbook workbook) - { - this(index, rec, workbook.getWorkbook()); - } - protected HSSFCellStyle(short index, ExtendedFormatRecord rec, InternalWorkbook workbook) - { - _workbook = workbook; - _index = index; - _format = rec; - } - - /** - * get the index within the HSSFWorkbook (sequence within the collection of ExtnededFormat objects) - * @return unique index number of the underlying record this style represents (probably you don't care - * unless you're comparing which one is which) - */ - @Override - public short getIndex() - { - return _index; - } - - /** - * Return the parent style for this cell style. - * In most cases this will be null, but in a few - * cases there'll be a fully defined parent. - */ - public HSSFCellStyle getParentStyle() { - short parentIndex = _format.getParentIndex(); - // parentIndex equal 0xFFF indicates no inheritance from a cell style XF (See 2.4.353 XF) - if(parentIndex == 0 || parentIndex == 0xFFF) { - return null; - } - return new HSSFCellStyle( - parentIndex, - _workbook.getExFormatAt(parentIndex), - _workbook - ); - } - - /** - * set the data format (must be a valid format) - * @see org.apache.poi.hssf.usermodel.HSSFDataFormat - */ - @Override - public void setDataFormat(short fmt) - { - _format.setFormatIndex(fmt); - } - - /** - * get the index of the format - * @see org.apache.poi.hssf.usermodel.HSSFDataFormat - */ - @Override - public short getDataFormat() - { - return _format.getFormatIndex(); - } - - // we keep the cached data in ThreadLocal members in order to - // avoid multi-threading issues when different workbooks are accessed in - // multiple threads at the same time - private static final ThreadLocal lastDateFormat = new ThreadLocal() { - protected Short initialValue() { - return Short.MIN_VALUE; - } - }; - private static final ThreadLocal> lastFormats = new ThreadLocal>(); - private static final ThreadLocal getDataFormatStringCache = new ThreadLocal(); - - /** - * Get the contents of the format string, by looking up - * the DataFormat against the bound workbook - * @see org.apache.poi.hssf.usermodel.HSSFDataFormat - * @return the format string or "General" if not found - */ - @Override - public String getDataFormatString() { - if (getDataFormatStringCache.get() != null) { - if (lastDateFormat.get() == getDataFormat() && _workbook.getFormats().equals(lastFormats.get())) { - return getDataFormatStringCache.get(); - } - } - - lastFormats.set(_workbook.getFormats()); - lastDateFormat.set(getDataFormat()); - - getDataFormatStringCache.set(getDataFormatString(_workbook)); - - return getDataFormatStringCache.get(); - } - - /** - * Get the contents of the format string, by looking up - * the DataFormat against the supplied workbook - * @see org.apache.poi.hssf.usermodel.HSSFDataFormat - * - * @return the format string or "General" if not found - */ - public String getDataFormatString(org.apache.poi.ss.usermodel.Workbook workbook) { - HSSFDataFormat format = new HSSFDataFormat( ((HSSFWorkbook)workbook).getWorkbook() ); - - int idx = getDataFormat(); - return idx == -1 ? "General" : format.getFormat(getDataFormat()); - } - /** - * Get the contents of the format string, by looking up - * the DataFormat against the supplied low level workbook - * @see org.apache.poi.hssf.usermodel.HSSFDataFormat - */ - public String getDataFormatString(org.apache.poi.hssf.model.InternalWorkbook workbook) { - HSSFDataFormat format = new HSSFDataFormat( workbook ); - - return format.getFormat(getDataFormat()); - } - - /** - * set the font for this style - * @param font a font object created or retreived from the HSSFWorkbook object - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createFont() - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(short) - */ - @Override - public void setFont(Font font) { - setFont((HSSFFont)font); - } - public void setFont(HSSFFont font) { - _format.setIndentNotParentFont(true); - short fontindex = font.getIndex(); - _format.setFontIndex(fontindex); - } - - /** - * gets the index of the font for this style - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(short) - */ - @Override - public short getFontIndex() - { - return _format.getFontIndex(); - } - - /** - * gets the font for this style - * @param parentWorkbook The HSSFWorkbook that this style belongs to - * @see org.apache.poi.hssf.usermodel.HSSFCellStyle#getFontIndex() - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(short) - */ - public HSSFFont getFont(org.apache.poi.ss.usermodel.Workbook parentWorkbook) { - return ((HSSFWorkbook) parentWorkbook).getFontAt(getFontIndex()); - } - - /** - * set the cell's using this style to be hidden - * @param hidden - whether the cell using this style should be hidden - */ - @Override - public void setHidden(boolean hidden) - { - _format.setIndentNotParentCellOptions(true); - _format.setHidden(hidden); - } - - /** - * get whether the cell's using this style are to be hidden - * @return hidden - whether the cell using this style should be hidden - */ - @Override - public boolean getHidden() - { - return _format.isHidden(); - } - - /** - * set the cell's using this style to be locked - * @param locked - whether the cell using this style should be locked - */ - @Override - public void setLocked(boolean locked) - { - _format.setIndentNotParentCellOptions(true); - _format.setLocked(locked); - } - - /** - * get whether the cell's using this style are to be locked - * @return hidden - whether the cell using this style should be locked - */ - @Override - public boolean getLocked() - { - return _format.isLocked(); - } - - /** - * Turn on or off "Quote Prefix" or "123 Prefix" for the style, - * which is used to tell Excel that the thing which looks like - * a number or a formula shouldn't be treated as on. - */ - @Override - public void setQuotePrefixed(boolean quotePrefix) { - _format.set123Prefix(quotePrefix); - } - - /** - * Is "Quote Prefix" or "123 Prefix" enabled for the cell? - */ - @Override - public boolean getQuotePrefixed() { - return _format.get123Prefix(); - } - - /** - * set the type of horizontal alignment for the cell - * @param align - the type of alignment - * @see #ALIGN_GENERAL - * @see #ALIGN_LEFT - * @see #ALIGN_CENTER - * @see #ALIGN_RIGHT - * @see #ALIGN_FILL - * @see #ALIGN_JUSTIFY - * @see #ALIGN_CENTER_SELECTION - * @deprecated POI 3.15 beta 3. Use {@link #setAlignment(HorizontalAlignment)} instead. - */ - @Removal(version="3.17") - @Override - public void setAlignment(short align) - { - _format.setIndentNotParentAlignment(true); - _format.setAlignment(align); - } - /** - * set the type of horizontal alignment for the cell - * @param align - the type of alignment - */ - @Override - public void setAlignment(HorizontalAlignment align) - { - _format.setIndentNotParentAlignment(true); - _format.setAlignment(align.getCode()); - } - - /** - * get the type of horizontal alignment for the cell - * @return align - the type of alignment - * @see #ALIGN_GENERAL - * @see #ALIGN_LEFT - * @see #ALIGN_CENTER - * @see #ALIGN_RIGHT - * @see #ALIGN_FILL - * @see #ALIGN_JUSTIFY - * @see #ALIGN_CENTER_SELECTION - * @deprecated POI 3.15 beta 3. Use {@link #getAlignmentEnum()} instead. - */ - @Override - public short getAlignment() - { - return _format.getAlignment(); - } - /** - * get the type of horizontal alignment for the cell - * @return align - the type of alignment - */ - @Override - public HorizontalAlignment getAlignmentEnum() - { - return HorizontalAlignment.forInt(_format.getAlignment()); - } - - /** - * set whether the text should be wrapped - * @param wrapped wrap text or not - */ - @Override - public void setWrapText(boolean wrapped) - { - _format.setIndentNotParentAlignment(true); - _format.setWrapText(wrapped); - } - - /** - * get whether the text should be wrapped - * @return wrap text or not - */ - @Override - public boolean getWrapText() - { - return _format.getWrapText(); - } - - /** - * set the type of vertical alignment for the cell - * @param align the type of alignment - * @see #VERTICAL_TOP - * @see #VERTICAL_CENTER - * @see #VERTICAL_BOTTOM - * @see #VERTICAL_JUSTIFY - * @see VerticalAlignment - * @deprecated POI 3.15 beta 3. Use {@link #setVerticalAlignment(VerticalAlignment)} instead. - */ - @Removal(version="3.17") - @Override - public void setVerticalAlignment(short align) - { - _format.setVerticalAlignment(align); - } - /** - * set the type of vertical alignment for the cell - * @param align the type of alignment - */ - @Override - public void setVerticalAlignment(VerticalAlignment align) - { - _format.setVerticalAlignment(align.getCode()); - } - - /** - * get the type of vertical alignment for the cell - * @return align the type of alignment - * @see #VERTICAL_TOP - * @see #VERTICAL_CENTER - * @see #VERTICAL_BOTTOM - * @see #VERTICAL_JUSTIFY - * @see VerticalAlignment - * @deprecated POI 3.15 beta 3. Use {@link #getVerticalAlignmentEnum()} instead. - */ - @Override - public short getVerticalAlignment() - { - return _format.getVerticalAlignment(); - } - /** - * get the type of vertical alignment for the cell - * @return align the type of alignment - */ - @Override - public VerticalAlignment getVerticalAlignmentEnum() - { - return VerticalAlignment.forInt(_format.getVerticalAlignment()); - } - - /** - * set the degree of rotation for the text in the cell - * - * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF - * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges - * accordingly, however the corresponding getter is returning values in the range mandated by the current type - * of Excel file-format that this CellStyle is applied to. - * - * @param rotation degrees (between -90 and 90 degrees, of 0xff for vertical) - */ - @Override - public void setRotation(short rotation) - { - if (rotation == 0xff) { - // Special cases for vertically aligned text - } - else if ((rotation < 0)&&(rotation >= -90)) { - //Take care of the funny 4th quadrant issue - //The 4th quadrant (-1 to -90) is stored as (91 to 180) - rotation = (short)(90 - rotation); - } - else if (rotation > 90 && rotation <= 180) { - // stay compatible with the range used by XSSF, map from ]90..180] to ]0..-90] - // we actually don't need to do anything here as the internal value is stored in [0-180] anyway! - } - else if ((rotation < -90) || (rotation > 90)) { - //Do not allow an incorrect rotation to be set - throw new IllegalArgumentException("The rotation must be between -90 and 90 degrees, or 0xff"); - } - _format.setRotation(rotation); - } - - /** - * get the degree of rotation for the text in the cell - * @return rotation degrees (between -90 and 90 degrees, or 0xff for vertical) - */ - @Override - public short getRotation() - { - short rotation = _format.getRotation(); - if (rotation == 0xff) { - // Vertical aligned special case - return rotation; - } - if (rotation > 90) { - //This is actually the 4th quadrant - rotation = (short)(90-rotation); - } - return rotation; - } - - /** - * set the number of spaces to indent the text in the cell - * @param indent - number of spaces - */ - @Override - public void setIndention(short indent) - { - _format.setIndent(indent); - } - - /** - * get the number of spaces to indent the text in the cell - * @return indent - number of spaces - */ - @Override - public short getIndention() - { - return _format.getIndent(); - } - - /** - * set the type of border to use for the left border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderLeft(BorderStyle)} instead. - */ - @Removal(version="3.17") - @Override - public void setBorderLeft(short border) - { - _format.setIndentNotParentBorder(true); - _format.setBorderLeft(border); - } - - /** - * set the type of border to use for the left border of the cell - * @param border type - * @since POI 3.15 - */ - @Override - public void setBorderLeft(BorderStyle border) - { - setBorderLeft(border.getCode()); - } - - /** - * get the type of border to use for the left border of the cell - * @return border type - * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderLeftEnum()}. - */ - @Override - public short getBorderLeft() - { - return _format.getBorderLeft(); - } - /** - * get the type of border to use for the left border of the cell - * @return border type - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderLeftEnum() - { - return BorderStyle.valueOf(_format.getBorderLeft()); - } - - /** - * set the type of border to use for the right border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderRight(BorderStyle)} instead. - */ - @Removal(version="3.17") - @Override - public void setBorderRight(short border) - { - _format.setIndentNotParentBorder(true); - _format.setBorderRight(border); - } - - /** - * set the type of border to use for the right border of the cell - * @param border type - * @since POI 3.15 - */ - @Override - public void setBorderRight(BorderStyle border) - { - setBorderRight(border.getCode()); - } - - /** - * get the type of border to use for the right border of the cell - * @return border type - * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderRightEnum()}. - */ - @Override - public short getBorderRight() - { - return _format.getBorderRight(); - } - /** - * get the type of border to use for the right border of the cell - * @return border type - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderRightEnum() - { - return BorderStyle.valueOf(_format.getBorderRight()); - } - - /** - * set the type of border to use for the top border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderTop(BorderStyle)} instead. - */ - @Removal(version="3.17") - @Override - public void setBorderTop(short border) - { - _format.setIndentNotParentBorder(true); - _format.setBorderTop(border); - } - - /** - * set the type of border to use for the top border of the cell - * @param border type - * @since POI 3.15 - */ - @Override - public void setBorderTop(BorderStyle border) - { - setBorderTop(border.getCode()); - } - - /** - * get the type of border to use for the top border of the cell - * @return border type - * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderTopEnum()}. - */ - @Override - public short getBorderTop() - { - return _format.getBorderTop(); - } - /** - * get the type of border to use for the top border of the cell - * @return border type - * @since 3.15 - */ - @Override - public BorderStyle getBorderTopEnum() - { - return BorderStyle.valueOf(_format.getBorderTop()); - } - - /** - * set the type of border to use for the bottom border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderBottom(BorderStyle)} instead. - */ - @Removal(version="3.17") - @Override - public void setBorderBottom(short border) - { - _format.setIndentNotParentBorder(true); - _format.setBorderBottom(border); - } - - /** - * set the type of border to use for the bottom border of the cell - * @param border type - * @since 3.15 beta 2 - */ - @Override - public void setBorderBottom(BorderStyle border) - { - setBorderBottom(border.getCode()); - } - - /** - * get the type of border to use for the bottom border of the cell - * @return border type - * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderBottomEnum()}. - */ - @Override - public short getBorderBottom() - { - return _format.getBorderBottom(); - } - /** - * get the type of border to use for the bottom border of the cell - * @return border type - * @since 3.15 - */ - @Override - public BorderStyle getBorderBottomEnum() - { - return BorderStyle.valueOf(_format.getBorderBottom()); - } - - /** - * set the color to use for the left border - * @param color The index of the color definition - */ - @Override - public void setLeftBorderColor(short color) - { - _format.setLeftBorderPaletteIdx(color); - } - - /** - * get the color to use for the left border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - @Override - public short getLeftBorderColor() - { - return _format.getLeftBorderPaletteIdx(); - } - - /** - * set the color to use for the right border - * @param color The index of the color definition - */ - @Override - public void setRightBorderColor(short color) - { - _format.setRightBorderPaletteIdx(color); - } - - /** - * get the color to use for the left border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - @Override - public short getRightBorderColor() - { - return _format.getRightBorderPaletteIdx(); - } - - /** - * set the color to use for the top border - * @param color The index of the color definition - */ - @Override - public void setTopBorderColor(short color) - { - _format.setTopBorderPaletteIdx(color); - } - - /** - * get the color to use for the top border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - @Override - public short getTopBorderColor() - { - return _format.getTopBorderPaletteIdx(); - } - - /** - * set the color to use for the bottom border - * @param color The index of the color definition - */ - @Override - public void setBottomBorderColor(short color) - { - _format.setBottomBorderPaletteIdx(color); - } - - /** - * get the color to use for the left border - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return The index of the color definition - */ - @Override - public short getBottomBorderColor() - { - return _format.getBottomBorderPaletteIdx(); - } - - /** - * setting to one fills the cell with the foreground color... No idea about - * other values - * - * @see #NO_FILL - * @see #SOLID_FOREGROUND - * @see #FINE_DOTS - * @see #ALT_BARS - * @see #SPARSE_DOTS - * @see #THICK_HORZ_BANDS - * @see #THICK_VERT_BANDS - * @see #THICK_BACKWARD_DIAG - * @see #THICK_FORWARD_DIAG - * @see #BIG_SPOTS - * @see #BRICKS - * @see #THIN_HORZ_BANDS - * @see #THIN_VERT_BANDS - * @see #THIN_BACKWARD_DIAG - * @see #THIN_FORWARD_DIAG - * @see #SQUARES - * @see #DIAMONDS - * - * @param fp fill pattern (set to 1 to fill w/foreground color) - * @deprecated POI 3.15 beta 3. Use {@link #setFillPattern(FillPatternType)} instead. - */ - @Removal(version="3.17") - @Override - public void setFillPattern(short fp) - { - setFillPattern(FillPatternType.forInt(fp)); - } - - /** - * setting to one fills the cell with the foreground color... No idea about - * other values - * - * @param fp fill pattern (set to {@link FillPatternType#SOLID_FOREGROUND} to fill w/foreground color) - */ - @Override - public void setFillPattern(FillPatternType fp) - { - _format.setAdtlFillPattern(fp.getCode()); - } - - /** - * get the fill pattern - * @return fill pattern - * @deprecated POI 3.15 beta 3. This method will return {@link FillPatternType} in the future. Use {@link #setFillPattern(FillPatternType)} instead. - */ - @Override - public short getFillPattern() - { - return getFillPatternEnum().getCode(); - } - - /** - * get the fill pattern - * @return fill pattern - */ - @Override - public FillPatternType getFillPatternEnum() - { - return FillPatternType.forInt(_format.getAdtlFillPattern()); - } - - /** - * Checks if the background and foreground fills are set correctly when one - * or the other is set to the default color. - *

    Works like the logic table below:

    - *

    BACKGROUND FOREGROUND

    - *

    NONE AUTOMATIC

    - *

    0x41 0x40

    - *

    NONE RED/ANYTHING

    - *

    0x40 0xSOMETHING

    - */ - private void checkDefaultBackgroundFills() { - if (_format.getFillForeground() == org.apache.poi.hssf.util.HSSFColor.AUTOMATIC.index) { - //JMH: Why +1, hell why not. I guess it made some sense to someone at the time. Doesnt - //to me now.... But experience has shown that when the fore is set to AUTOMATIC then the - //background needs to be incremented...... - if (_format.getFillBackground() != (org.apache.poi.hssf.util.HSSFColor.AUTOMATIC.index+1)) - setFillBackgroundColor((short)(org.apache.poi.hssf.util.HSSFColor.AUTOMATIC.index+1)); - } else if (_format.getFillBackground() == org.apache.poi.hssf.util.HSSFColor.AUTOMATIC.index+1) - //Now if the forground changes to a non-AUTOMATIC color the background resets itself!!! - if (_format.getFillForeground() != org.apache.poi.hssf.util.HSSFColor.AUTOMATIC.index) - setFillBackgroundColor(org.apache.poi.hssf.util.HSSFColor.AUTOMATIC.index); - } - - /** - * set the background fill color. - *

    - * For example: - *

    -     * cs.setFillPattern(HSSFCellStyle.FINE_DOTS );
    -     * cs.setFillBackgroundColor(new HSSFColor.RED().getIndex());
    -     * 
    - * optionally a Foreground and background fill can be applied: - * Note: Ensure Foreground color is set prior to background - *
    -     * cs.setFillPattern(HSSFCellStyle.FINE_DOTS );
    -     * cs.setFillForegroundColor(new HSSFColor.BLUE().getIndex());
    -     * cs.setFillBackgroundColor(new HSSFColor.RED().getIndex());
    -     * 
    - * or, for the special case of SOLID_FILL: - *
    -     * cs.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND );
    -     * cs.setFillForegroundColor(new HSSFColor.RED().getIndex());
    -     * 
    - * It is necessary to set the fill style in order - * for the color to be shown in the cell. - * - * @param bg color - */ - @Override - public void setFillBackgroundColor(short bg) - { - _format.setFillBackground(bg); - checkDefaultBackgroundFills(); - } - - /** - * Get the background fill color. - * Note - many cells are actually filled with a foreground - * fill, not a background fill - see {@link #getFillForegroundColor()} - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return fill color - */ - @Override - public short getFillBackgroundColor() - { - short result = _format.getFillBackground(); - //JMH: Do this ridiculous conversion, and let HSSFCellStyle - //internally migrate back and forth - if (result == (HSSFColor.AUTOMATIC.index+1)) { - return HSSFColor.AUTOMATIC.index; - } - return result; - } - - @Override - public HSSFColor getFillBackgroundColorColor() { - HSSFPalette pallette = new HSSFPalette( - _workbook.getCustomPalette() - ); - return pallette.getColor( - getFillBackgroundColor() - ); - } - - /** - * set the foreground fill color - * Note: Ensure Foreground color is set prior to background color. - * @param bg color - */ - @Override - public void setFillForegroundColor(short bg) - { - _format.setFillForeground(bg); - checkDefaultBackgroundFills(); - } - - /** - * Get the foreground fill color. - * Many cells are filled with this, instead of a - * background color ({@link #getFillBackgroundColor()}) - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - * @return fill color - */ - @Override - public short getFillForegroundColor() - { - return _format.getFillForeground(); - } - - @Override - public HSSFColor getFillForegroundColorColor() { - HSSFPalette pallette = new HSSFPalette( - _workbook.getCustomPalette() - ); - return pallette.getColor( - getFillForegroundColor() - ); - } - - /** - * Gets the name of the user defined style. - * Returns null for built in styles, and - * styles where no name has been defined - */ - public String getUserStyleName() { - StyleRecord sr = _workbook.getStyleRecord(_index); - if(sr == null) { - return null; - } - if(sr.isBuiltin()) { - return null; - } - return sr.getName(); - } - - /** - * Sets the name of the user defined style. - * Will complain if you try this on a built in style. - */ - public void setUserStyleName(String styleName) { - StyleRecord sr = _workbook.getStyleRecord(_index); - if(sr == null) { - sr = _workbook.createStyleRecord(_index); - } - // All Style records start as "builtin", but generally - // only 20 and below really need to be - if(sr.isBuiltin() && _index <= 20) { - throw new IllegalArgumentException("Unable to set user specified style names for built in styles!"); - } - sr.setName(styleName); - } - - /** - * Controls if the Cell should be auto-sized - * to shrink to fit if the text is too long - */ - @Override - public void setShrinkToFit(boolean shrinkToFit) { - _format.setShrinkToFit(shrinkToFit); - } - /** - * Should the Cell be auto-sized by Excel to shrink - * it to fit if this text is too long? - */ - @Override - public boolean getShrinkToFit() { - return _format.getShrinkToFit(); - } - - /** - * Get the reading order, for RTL/LTR ordering of - * the text. - *

    0 means Context (Default), 1 means Left To Right, - * and 2 means Right to Left

    - * - * @return order - the reading order (0,1,2) - */ - public short getReadingOrder() { - return _format.getReadingOrder(); - } - /** - * Sets the reading order, for RTL/LTR ordering of - * the text. - *

    0 means Context (Default), 1 means Left To Right, - * and 2 means Right to Left

    - * - * @param order - the reading order (0,1,2) - */ - public void setReadingOrder(short order) { - _format.setReadingOrder(order); - } - - /** - * Verifies that this style belongs to the supplied Workbook. - * Will throw an exception if it belongs to a different one. - * This is normally called when trying to assign a style to a - * cell, to ensure the cell and the style are from the same - * workbook (if they're not, it won't work) - * @throws IllegalArgumentException if there's a workbook mis-match - */ - public void verifyBelongsToWorkbook(HSSFWorkbook wb) { - if(wb.getWorkbook() != _workbook) { - throw new IllegalArgumentException("This Style does not belong to the supplied Workbook. Are you trying to assign a style from one workbook to the cell of a differnt workbook?"); - } - } - - /** - * Clones all the style information from another - * HSSFCellStyle, onto this one. This - * HSSFCellStyle will then have all the same - * properties as the source, but the two may - * be edited independently. - * Any stylings on this HSSFCellStyle will be lost! - * - * The source HSSFCellStyle could be from another - * HSSFWorkbook if you like. This allows you to - * copy styles from one HSSFWorkbook to another. - */ - @Override - public void cloneStyleFrom(CellStyle source) { - if(source instanceof HSSFCellStyle) { - this.cloneStyleFrom((HSSFCellStyle)source); - } else { - throw new IllegalArgumentException("Can only clone from one HSSFCellStyle to another, not between HSSFCellStyle and XSSFCellStyle"); - } - } - public void cloneStyleFrom(HSSFCellStyle source) { - // First we need to clone the extended format - // record - _format.cloneStyleFrom(source._format); - - // Handle matching things if we cross workbooks - if(_workbook != source._workbook) { - - lastDateFormat.set(Short.MIN_VALUE); - lastFormats.set(null); - getDataFormatStringCache.set(null); - - // Then we need to clone the format string, - // and update the format record for this - short fmt = (short)_workbook.createFormat(source.getDataFormatString() ); - setDataFormat(fmt); - - // Finally we need to clone the font, - // and update the format record for this - FontRecord fr = _workbook.createNewFont(); - fr.cloneStyleFrom( - source._workbook.getFontRecordAt( - source.getFontIndex() - ) - ); - - HSSFFont font = new HSSFFont( - (short)_workbook.getFontIndex(fr), fr - ); - setFont(font); - } - } - - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((_format == null) ? 0 : _format.hashCode()); - result = prime * result + _index; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (obj instanceof HSSFCellStyle) { - final HSSFCellStyle other = (HSSFCellStyle) obj; - if (_format == null) { - if (other._format != null) - return false; - } else if (!_format.equals(other._format)) - return false; - if (_index != other._index) - return false; - return true; - } - return false; - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java deleted file mode 100644 index a7a88c6b6..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - - -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherRecord; - -public final class HSSFChildAnchor extends HSSFAnchor { - - private EscherChildAnchorRecord _escherChildAnchor; - - /** - * create anchor from existing file - * @param escherChildAnchorRecord - */ - public HSSFChildAnchor(EscherChildAnchorRecord escherChildAnchorRecord) { - this._escherChildAnchor = escherChildAnchorRecord; - } - - public HSSFChildAnchor() { - _escherChildAnchor = new EscherChildAnchorRecord(); - } - - /** - * create anchor from scratch - * @param dx1 x coordinate of the left up corner - * @param dy1 y coordinate of the left up corner - * @param dx2 x coordinate of the right down corner - * @param dy2 y coordinate of the right down corner - */ - public HSSFChildAnchor(int dx1, int dy1, int dx2, int dy2) { - super(Math.min(dx1, dx2), Math.min(dy1, dy2), Math.max(dx1, dx2), Math.max(dy1, dy2)); - if (dx1 > dx2){ - _isHorizontallyFlipped = true; - } - if (dy1 > dy2){ - _isVerticallyFlipped = true; - } - } - - @Override - public int getDx1() { - return _escherChildAnchor.getDx1(); - } - - @Override - public void setDx1(int dx1) { - _escherChildAnchor.setDx1(dx1); - } - - @Override - public int getDy1() { - return _escherChildAnchor.getDy1(); - } - - @Override - public void setDy1(int dy1) { - _escherChildAnchor.setDy1(dy1); - } - - @Override - public int getDy2() { - return _escherChildAnchor.getDy2(); - } - - @Override - public void setDy2(int dy2) { - _escherChildAnchor.setDy2(dy2); - } - - @Override - public int getDx2() { - return _escherChildAnchor.getDx2(); - } - - @Override - public void setDx2(int dx2) { - _escherChildAnchor.setDx2(dx2); - } - - /** - * @param dx1 x coordinate of the left up corner - * @param dy1 y coordinate of the left up corner - * @param dx2 x coordinate of the right down corner - * @param dy2 y coordinate of the right down corner - */ - public void setAnchor(int dx1, int dy1, int dx2, int dy2) { - setDx1(Math.min(dx1, dx2)); - setDy1(Math.min(dy1, dy2)); - setDx2(Math.max(dx1, dx2)); - setDy2(Math.max(dy1, dy2)); - } - - - public boolean isHorizontallyFlipped() { - return _isHorizontallyFlipped; - } - - - public boolean isVerticallyFlipped() { - return _isVerticallyFlipped; - } - - @Override - protected EscherRecord getEscherAnchor() { - return _escherChildAnchor; - } - - @Override - protected void createEscherAnchor() { - _escherChildAnchor = new EscherChildAnchorRecord(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (obj == this) - return true; - if (obj.getClass() != getClass()) - return false; - HSSFChildAnchor anchor = (HSSFChildAnchor) obj; - - return anchor.getDx1() == getDx1() && anchor.getDx2() == getDx2() && anchor.getDy1() == getDy1() - && anchor.getDy2() == getDy2(); - } - - @Override - public int hashCode() { - assert false : "hashCode not designed"; - return 42; // any arbitrary constant will do - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java deleted file mode 100644 index d4c8c6d68..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java +++ /dev/null @@ -1,357 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.util.Removal; - -/** - * A client anchor is attached to an excel worksheet. It anchors against a - * top-left and buttom-right cell. - */ -public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor { - - public static final int MAX_COL = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); - public static final int MAX_ROW = SpreadsheetVersion.EXCEL97.getLastRowIndex(); - - private EscherClientAnchorRecord _escherClientAnchor; - - public HSSFClientAnchor(EscherClientAnchorRecord escherClientAnchorRecord) { - this._escherClientAnchor = escherClientAnchorRecord; - } - - /** - * Creates a new client anchor and defaults all the anchor positions to 0. - */ - public HSSFClientAnchor() { - } - - /** - * Creates a new client anchor and sets the top-left and bottom-right - * coordinates of the anchor. - * - * Note: Microsoft Excel seems to sometimes disallow - * higher y1 than y2 or higher x1 than x2, you might need to - * reverse them and draw shapes vertically or horizontally flipped! - * - * @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 HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2) { - super(dx1, dy1, dx2, dy2); - - checkRange(dx1, 0, 1023, "dx1"); - checkRange(dx2, 0, 1023, "dx2"); - checkRange(dy1, 0, 255, "dy1"); - checkRange(dy2, 0, 255, "dy2"); - checkRange(col1, 0, MAX_COL, "col1"); - checkRange(col2, 0, MAX_COL, "col2"); - checkRange(row1, 0, MAX_ROW, "row1"); - checkRange(row2, 0, MAX_ROW, "row2"); - - setCol1((short) Math.min(col1, col2)); - setCol2((short) Math.max(col1, col2)); - setRow1(Math.min(row1, row2)); - setRow2(Math.max(row1, row2)); - - if (col1 > col2){ - _isHorizontallyFlipped = true; - } - if (row1 > row2){ - _isVerticallyFlipped = true; - } - } - - /** - * Calculates the height of a client anchor in points. - * - * @param sheet the sheet the anchor will be attached to - * @return the shape height. - */ - public float getAnchorHeightInPoints(HSSFSheet sheet) { - int y1 = getDy1(); - int y2 = getDy2(); - int row1 = Math.min(getRow1(), getRow2()); - int row2 = Math.max(getRow1(), getRow2()); - - float points = 0; - if (row1 == row2) { - points = ((y2 - y1) / 256.0f) * getRowHeightInPoints(sheet, row2); - } else { - points += ((256.0f - y1) / 256.0f) * getRowHeightInPoints(sheet, row1); - for (int i = row1 + 1; i < row2; i++) { - points += getRowHeightInPoints(sheet, i); - } - points += (y2 / 256.0f) * getRowHeightInPoints(sheet, row2); - } - - return points; - } - - private float getRowHeightInPoints(HSSFSheet sheet, int rowNum) { - HSSFRow row = sheet.getRow(rowNum); - if (row == null) { - return sheet.getDefaultRowHeightInPoints(); - } - return row.getHeightInPoints(); - } - - /** - * @return the column(0 based) of the first cell. - */ - public short getCol1() { - return _escherClientAnchor.getCol1(); - } - - /** - * @param col1 the column(0 based) of the first cell. - */ - public void setCol1(short col1) { - checkRange(col1, 0, MAX_COL, "col1"); - _escherClientAnchor.setCol1(col1); - } - - /** - * @param col1 0-based column of the first cell. - */ - public void setCol1(int col1) { - setCol1((short) col1); - } - - /** - * @return the column(0 based) of the first cell. - */ - public short getCol2() { - return _escherClientAnchor.getCol2(); - } - - /** - * @param col2 the column(0 based) of the second cell. - */ - public void setCol2(short col2) { - checkRange(col2, 0, MAX_COL, "col2"); - _escherClientAnchor.setCol2(col2); - } - - /** - * @param col2 the column(0 based) of the second cell. - */ - public void setCol2(int col2) { - setCol2((short) col2); - } - - /** - * @return the row(0 based) of the first cell. - */ - public int getRow1() { - return unsignedValue(_escherClientAnchor.getRow1()); - } - - /** - * @param row1 0-based row of the first cell. - */ - public void setRow1(int row1) { - checkRange(row1, 0, MAX_ROW, "row1"); - _escherClientAnchor.setRow1(Integer.valueOf(row1).shortValue()); - } - - /** - * @return the row(0 based) of the second cell. - */ - public int getRow2() { - return unsignedValue(_escherClientAnchor.getRow2()); - } - - /** - * @param row2 the row(0 based) of the second cell. - */ - public void setRow2(int row2) { - checkRange(row2, 0, MAX_ROW, "row2"); - _escherClientAnchor.setRow2(Integer.valueOf(row2).shortValue()); - } - - /** - * Sets the top-left and bottom-right coordinates of - * the anchor. - * - * Note: Microsoft Excel seems to sometimes disallow - * higher y1 than y2 or higher x1 than x2, you might need to - * reverse them and draw shapes vertically or horizontally flipped! - * - * @param x1 the x coordinate within the first cell. - * @param y1 the y coordinate within the first cell. - * @param x2 the x coordinate within the second cell. - * @param y2 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 void setAnchor(short col1, int row1, int x1, int y1, short col2, int row2, int x2, int y2) { - checkRange(getDx1(), 0, 1023, "dx1"); - checkRange(getDx2(), 0, 1023, "dx2"); - checkRange(getDy1(), 0, 255, "dy1"); - checkRange(getDy2(), 0, 255, "dy2"); - checkRange(getCol1(), 0, MAX_COL, "col1"); - checkRange(getCol2(), 0, MAX_COL, "col2"); - checkRange(getRow1(), 0, MAX_ROW, "row1"); - checkRange(getRow2(), 0, MAX_ROW, "row2"); - - setCol1(col1); - setRow1(row1); - setDx1(x1); - setDy1(y1); - setCol2(col2); - setRow2(row2); - setDx2(x2); - setDy2(y2); - } - - public boolean isHorizontallyFlipped() { - return _isHorizontallyFlipped; - } - - public boolean isVerticallyFlipped() { - return _isVerticallyFlipped; - } - - @Override - protected EscherRecord getEscherAnchor() { - return _escherClientAnchor; - } - - @Override - protected void createEscherAnchor() { - _escherClientAnchor = new EscherClientAnchorRecord(); - } - - /** - * Gets the anchor type - * Changed from returning an int to an enum in POI 3.14 beta 1. - * @return the anchor type - */ - @Override - public AnchorType getAnchorType() { - return AnchorType.byId(_escherClientAnchor.getFlag()); - } - - /** - * Sets the anchor type - * @param anchorType the anchor type to set - * @since POI 3.14 - */ - @Override - public void setAnchorType(AnchorType anchorType) { - _escherClientAnchor.setFlag(anchorType.value); - } - /** - * Sets the anchor type - * @param anchorType the anchor type to set - * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead. - */ - @Removal(version="3.17") - @Override - public void setAnchorType(int anchorType) { - _escherClientAnchor.setFlag((short) anchorType); - } - - private void checkRange(int value, int minRange, int maxRange, String varName) { - if (value < minRange || value > maxRange) - throw new IllegalArgumentException(varName + " must be between " + minRange + " and " + maxRange + ", but was: " + value); - } - - /** - * Given a 16-bit unsigned integer stored in a short, return the unsigned value. - * - * @param s A 16-bit value intended to be interpreted as an unsigned integer. - * @return The value represented by s. - */ - private static int unsignedValue(final short s) { - return (s < 0 ? 0x10000 + s : s); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (obj == this) - return true; - if (obj.getClass() != getClass()) - return false; - HSSFClientAnchor anchor = (HSSFClientAnchor) obj; - - return anchor.getCol1() == getCol1() && anchor.getCol2() == getCol2() && anchor.getDx1() == getDx1() - && anchor.getDx2() == getDx2() && anchor.getDy1() == getDy1() && anchor.getDy2() == getDy2() - && anchor.getRow1() == getRow1() && anchor.getRow2() == getRow2() && anchor.getAnchorType() == getAnchorType(); - } - - @Override - public int hashCode() { - assert false : "hashCode not designed"; - return 42; // any arbitrary constant will do - } - - @Override - public int getDx1() { - return _escherClientAnchor.getDx1(); - } - - @Override - public void setDx1(int dx1) { - _escherClientAnchor.setDx1(Integer.valueOf(dx1).shortValue()); - } - - @Override - public int getDy1() { - return _escherClientAnchor.getDy1(); - } - - @Override - public void setDy1(int dy1) { - _escherClientAnchor.setDy1(Integer.valueOf(dy1).shortValue()); - } - - @Override - public int getDy2() { - return _escherClientAnchor.getDy2(); - } - - @Override - public void setDy2(int dy2) { - _escherClientAnchor.setDy2(Integer.valueOf(dy2).shortValue()); - } - - @Override - public int getDx2() { - return _escherClientAnchor.getDx2(); - } - - @Override - public void setDx2(int dx2) { - _escherClientAnchor.setDx2(Integer.valueOf(dx2).shortValue()); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFColorScaleFormatting.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFColorScaleFormatting.java deleted file mode 100644 index 36c5a53e0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFColorScaleFormatting.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.hssf.record.CFRule12Record; -import org.apache.poi.hssf.record.cf.ColorGradientFormatting; -import org.apache.poi.hssf.record.cf.ColorGradientThreshold; -import org.apache.poi.hssf.record.cf.Threshold; -import org.apache.poi.hssf.record.common.ExtendedColor; -import org.apache.poi.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold; - -/** - * High level representation for Color Scale / Color Gradient - * Formatting component of Conditional Formatting settings - */ -public final class HSSFColorScaleFormatting implements org.apache.poi.ss.usermodel.ColorScaleFormatting { - private final HSSFSheet sheet; - private final CFRule12Record cfRule12Record; - private final ColorGradientFormatting colorFormatting; - - protected HSSFColorScaleFormatting(CFRule12Record cfRule12Record, HSSFSheet sheet) { - this.sheet = sheet; - this.cfRule12Record = cfRule12Record; - this.colorFormatting = this.cfRule12Record.getColorGradientFormatting(); - } - - public int getNumControlPoints() { - return colorFormatting.getNumControlPoints(); - } - public void setNumControlPoints(int num) { - colorFormatting.setNumControlPoints(num); - } - - public HSSFExtendedColor[] getColors() { - ExtendedColor[] colors = colorFormatting.getColors(); - HSSFExtendedColor[] hcolors = new HSSFExtendedColor[colors.length]; - for (int i=0; i
    objects. Two rows are equal if they belong to the same worksheet and - * their row indexes are equal. - * - * @param other the HSSFRow to be compared. - * @return
      - *
    • - * the value 0 if the row number of this HSSFRow is - * equal to the row number of the argument HSSFRow - *
    • - *
    • - * a value less than 0 if the row number of this this HSSFRow is - * numerically less than the row number of the argument HSSFRow - *
    • - *
    • - * a value greater than 0 if the row number of this this HSSFRow is - * numerically greater than the row number of the argument HSSFRow - *
    • - *
    - * @throws IllegalArgumentException if the argument row belongs to a different worksheet - */ - @Override - public int compareTo(HSSFRow other) - { - if (this.getSheet() != other.getSheet()) { - throw new IllegalArgumentException("The compared rows must belong to the same sheet"); - } - - Integer thisRow = this.getRowNum(); - Integer otherRow = other.getRowNum(); - return thisRow.compareTo(otherRow); - } - - @Override - public boolean equals(Object obj) - { - if (!(obj instanceof HSSFRow)) - { - return false; - } - HSSFRow other = (HSSFRow) obj; - - return (this.getRowNum() == other.getRowNum()) && - (this.getSheet() == other.getSheet()); - } - - @Override - public int hashCode() { - return row.hashCode(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java deleted file mode 100644 index dc31858fe..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java +++ /dev/null @@ -1,420 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.apache.poi.ddf.EscherBoolProperty; -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherProperty; -import org.apache.poi.ddf.EscherRGBProperty; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.hssf.record.CommonObjectDataSubRecord; -import org.apache.poi.hssf.record.ObjRecord; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * An abstract shape. - * - * Note: Microsoft Excel seems to sometimes disallow - * higher y1 than y2 or higher x1 than x2 in the anchor, you might need to - * reverse them and draw shapes vertically or horizontally flipped via - * setFlipVertical() or setFlipHorizontally(). - */ -public abstract class HSSFShape { - private static final POILogger LOG = POILogFactory.getLogger(HSSFShape.class); - - public static final int LINEWIDTH_ONE_PT = 12700; - public static final int LINEWIDTH_DEFAULT = 9525; - public static final int LINESTYLE__COLOR_DEFAULT = 0x08000040; - public static final int FILL__FILLCOLOR_DEFAULT = 0x08000009; - public static final boolean NO_FILL_DEFAULT = true; - - public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen - public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style - public static final int LINESTYLE_DOTSYS = 2; // PS_DOT system dash style - public static final int LINESTYLE_DASHDOTSYS = 3; // PS_DASHDOT system dash style - public static final int LINESTYLE_DASHDOTDOTSYS = 4; // PS_DASHDOTDOT system dash style - public static final int LINESTYLE_DOTGEL = 5; // square dot style - public static final int LINESTYLE_DASHGEL = 6; // dash style - public static final int LINESTYLE_LONGDASHGEL = 7; // long dash style - public static final int LINESTYLE_DASHDOTGEL = 8; // dash short dash - public static final int LINESTYLE_LONGDASHDOTGEL = 9; // long dash short dash - public static final int LINESTYLE_LONGDASHDOTDOTGEL = 10; // long dash short dash short dash - public static final int LINESTYLE_NONE = -1; - - public static final int LINESTYLE_DEFAULT = LINESTYLE_NONE; - - // TODO - make all these fields private - private HSSFShape parent; - HSSFAnchor anchor; - private HSSFPatriarch _patriarch; - - private final EscherContainerRecord _escherContainer; - private final ObjRecord _objRecord; - private final EscherOptRecord _optRecord; - - public final static int NO_FILLHITTEST_TRUE = 0x00110000; - public final static int NO_FILLHITTEST_FALSE = 0x00010000; - - /** - * creates shapes from existing file - * @param spContainer - * @param objRecord - */ - public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord) { - this._escherContainer = spContainer; - this._objRecord = objRecord; - this._optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID); - this.anchor = HSSFAnchor.createAnchorFromEscher(spContainer); - } - - /** - * Create a new shape with the specified parent and anchor. - */ - public HSSFShape(HSSFShape parent, HSSFAnchor anchor) { - this.parent = parent; - this.anchor = anchor; - this._escherContainer = createSpContainer(); - _optRecord = _escherContainer.getChildById(EscherOptRecord.RECORD_ID); - _objRecord = createObjRecord(); - - } - - protected abstract EscherContainerRecord createSpContainer(); - - protected abstract ObjRecord createObjRecord(); - - /** - * remove escher container from the patriarch.escherAggregate - * remove obj, textObj and note records if it's necessary - * in case of ShapeGroup remove all contained shapes - * @param patriarch - */ - protected abstract void afterRemove(HSSFPatriarch patriarch); - - /** - * @param shapeId - global shapeId which must be set to EscherSpRecord - */ - void setShapeId(int shapeId){ - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setShapeId(shapeId); - CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0); - cod.setObjectId((short) (shapeId%1024)); - } - - /** - * @return global shapeId(from EscherSpRecord) - */ - int getShapeId(){ - return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId(); - } - - abstract void afterInsert(HSSFPatriarch patriarch); - - protected EscherContainerRecord getEscherContainer() { - return _escherContainer; - } - - protected ObjRecord getObjRecord() { - return _objRecord; - } - - /** - * Return the low-level EscherOptRecord to read/modify not yet wrapped escher properties - * - * @return the low-level EscherOptRecord - */ - public EscherOptRecord getOptRecord() { - return _optRecord; - } - - /** - * Gets the parent shape. - */ - public HSSFShape getParent() { - return parent; - } - - /** - * @return the anchor that is used by this shape. - */ - public HSSFAnchor getAnchor() { - return anchor; - } - - /** - * Sets a particular anchor. A top-level shape must have an anchor of - * HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor - * - * @param anchor the anchor to use. - * @throws IllegalArgumentException when the wrong anchor is used for - * this particular shape. - * @see HSSFChildAnchor - * @see HSSFClientAnchor - */ - public void setAnchor(HSSFAnchor anchor) { - int i = 0; - int recordId = -1; - if (parent == null) { - if (anchor instanceof HSSFChildAnchor) - throw new IllegalArgumentException("Must use client anchors for shapes directly attached to sheet."); - EscherClientAnchorRecord anch = _escherContainer.getChildById(EscherClientAnchorRecord.RECORD_ID); - if (null != anch) { - for (i=0; i< _escherContainer.getChildRecords().size(); i++){ - if (_escherContainer.getChild(i).getRecordId() == EscherClientAnchorRecord.RECORD_ID){ - if (i != _escherContainer.getChildRecords().size() -1){ - recordId = _escherContainer.getChild(i+1).getRecordId(); - } - } - } - _escherContainer.removeChildRecord(anch); - } - } else { - if (anchor instanceof HSSFClientAnchor) - throw new IllegalArgumentException("Must use child anchors for shapes attached to groups."); - EscherChildAnchorRecord anch = _escherContainer.getChildById(EscherChildAnchorRecord.RECORD_ID); - if (null != anch) { - for (i=0; i< _escherContainer.getChildRecords().size(); i++){ - if (_escherContainer.getChild(i).getRecordId() == EscherChildAnchorRecord.RECORD_ID){ - if (i != _escherContainer.getChildRecords().size() -1){ - recordId = _escherContainer.getChild(i+1).getRecordId(); - } - } - } - _escherContainer.removeChildRecord(anch); - } - } - if (-1 == recordId){ - _escherContainer.addChildRecord(anchor.getEscherAnchor()); - } else { - _escherContainer.addChildBefore(anchor.getEscherAnchor(), recordId); - } - this.anchor = anchor; - } - - /** - * The color applied to the lines of this shape. - */ - public int getLineStyleColor() { - EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR); - return rgbProperty == null ? LINESTYLE__COLOR_DEFAULT : rgbProperty.getRgbColor(); - } - - /** - * The color applied to the lines of this shape. - */ - public void setLineStyleColor(int lineStyleColor) { - setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor)); - } - - /** - * The color applied to the lines of this shape. - */ - public void setLineStyleColor(int red, int green, int blue) { - int lineStyleColor = ((blue) << 16) | ((green) << 8) | red; - setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor)); - } - - /** - * The color used to fill this shape. - */ - public int getFillColor() { - EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR); - return rgbProperty == null ? FILL__FILLCOLOR_DEFAULT : rgbProperty.getRgbColor(); - } - - /** - * The color used to fill this shape. - */ - public void setFillColor(int fillColor) { - setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor)); - } - - /** - * The color used to fill this shape. - */ - public void setFillColor(int red, int green, int blue) { - int fillColor = ((blue) << 16) | ((green) << 8) | red; - setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor)); - } - - /** - * @return returns with width of the line in EMUs. 12700 = 1 pt. - */ - public int getLineWidth() { - EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH); - return property == null ? LINEWIDTH_DEFAULT: property.getPropertyValue(); - } - - /** - * Sets the width of the line. 12700 = 1 pt. - * - * @param lineWidth width in EMU's. 12700EMU's = 1 pt - * @see HSSFShape#LINEWIDTH_ONE_PT - */ - public void setLineWidth(int lineWidth) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth)); - } - - /** - * @return One of the constants in LINESTYLE_* - */ - public int getLineStyle() { - EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING); - if (null == property){ - return LINESTYLE_DEFAULT; - } - return property.getPropertyValue(); - } - - /** - * Sets the line style. - * - * @param lineStyle One of the constants in LINESTYLE_* - */ - public void setLineStyle(int lineStyle) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle)); - if (getLineStyle() != HSSFShape.LINESTYLE_SOLID) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDCAPSTYLE, 0)); - if (getLineStyle() == HSSFShape.LINESTYLE_NONE){ - setPropertyValue(new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080000)); - } else { - setPropertyValue( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008)); - } - } - } - - /** - * @return true if this shape is not filled with a color. - */ - public boolean isNoFill() { - EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST); - return property == null ? NO_FILL_DEFAULT : property.getPropertyValue() == NO_FILLHITTEST_TRUE; - } - - /** - * @param noFill sets whether this shape is filled or transparent. - */ - public void setNoFill(boolean noFill) { - setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? NO_FILLHITTEST_TRUE : NO_FILLHITTEST_FALSE)); - } - - protected void setPropertyValue(EscherProperty property){ - _optRecord.setEscherProperty(property); - } - - /** - * @param value specifies whether this shape is vertically flipped. - */ - public void setFlipVertical(boolean value){ - EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); - if (value){ - sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT); - } else { - sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPVERT)); - } - } - - /** - * @param value specifies whether this shape is horizontally flipped. - */ - public void setFlipHorizontal(boolean value){ - EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); - if (value){ - sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ); - } else { - sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPHORIZ)); - } - } - - /** - * @return whether this shape is vertically flipped. - */ - public boolean isFlipVertical(){ - EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); - return (sp.getFlags() & EscherSpRecord.FLAG_FLIPVERT) != 0; - } - - /** - * @return whether this shape is horizontally flipped. - */ - public boolean isFlipHorizontal(){ - EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); - return (sp.getFlags() & EscherSpRecord.FLAG_FLIPHORIZ) != 0; - } - - /** - * @return the rotation, in degrees, that is applied to a shape. - */ - public int getRotationDegree(){ - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TRANSFORM__ROTATION); - if (null == property){ - return 0; - } - try { - LittleEndian.putInt(property.getPropertyValue(), bos); - return LittleEndian.getShort(bos.toByteArray(), 2); - } catch (IOException e) { - LOG.log(POILogger.ERROR, "can't determine rotation degree", e); - return 0; - } - } - - /** - * specifies the rotation, in degrees, that is applied to a shape. - * Positive values specify rotation in the clockwise direction. - * Negative values specify rotation in the counterclockwise direction. - * Rotation occurs around the center of the shape. - * The default value for this property is 0x00000000 - * @param value - */ - public void setRotationDegree(short value){ - setPropertyValue(new EscherSimpleProperty(EscherProperties.TRANSFORM__ROTATION , (value << 16))); - } - - /** - * Count of all children and their children's children. - */ - public int countOfAllChildren() { - return 1; - } - - protected abstract HSSFShape cloneShape(); - - protected void setPatriarch(HSSFPatriarch _patriarch) { - this._patriarch = _patriarch; - } - - public HSSFPatriarch getPatriarch() { - return _patriarch; - } - - protected void setParent(HSSFShape parent) { - this.parent = parent; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java deleted file mode 100644 index 31ce24fa0..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.util.List; - -/** - * An interface that indicates whether a class can contain children. - */ -public interface HSSFShapeContainer extends Iterable -{ - /** - * @return Any children contained by this shape. - */ - List getChildren(); - - /** - * add shape to the list of child records - * @param shape - */ - public void addShape(HSSFShape shape); - - /** - * set coordinates of this group relative to the parent - */ - void setCoordinates( int x1, int y1, int x2, int y2 ); - - void clear(); - - /** - *@return The top left x coordinate of this group. - */ - public int getX1(); - - /** - *@return The top left y coordinate of this group. - */ - public int getY1(); - - /** - *@return The bottom right x coordinate of this group. - */ - public int getX2(); - - /** - * @return The bottom right y coordinate of this group. - */ - public int getY2(); - - /** - * remove first level shapes - * @param shape to be removed - * @return true if shape is removed else return false - */ - public boolean removeShape(HSSFShape shape); -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java deleted file mode 100644 index 772ee5821..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.ddf.*; -import org.apache.poi.hssf.record.*; -import org.apache.poi.poifs.filesystem.DirectoryNode; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * Factory class for producing Excel Shapes from Escher records - */ -public class HSSFShapeFactory { - /** - * build shape tree from escher container - * @param container root escher container from which escher records must be taken - * @param agg - EscherAggregate - * @param out - shape container to which shapes must be added - * @param root - node to create HSSFObjectData shapes - */ - public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out, DirectoryNode root) { - if (container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) { - ObjRecord obj = null; - EscherClientDataRecord clientData = ((EscherContainerRecord) container.getChild(0)).getChildById(EscherClientDataRecord.RECORD_ID); - if (null != clientData) { - obj = (ObjRecord) agg.getShapeToObjMapping().get(clientData); - } - HSSFShapeGroup group = new HSSFShapeGroup(container, obj); - List children = container.getChildContainers(); - // skip the first child record, it is group descriptor - for (int i = 0; i < children.size(); i++) { - EscherContainerRecord spContainer = children.get(i); - if (i != 0) { - createShapeTree(spContainer, agg, group, root); - } - } - out.addShape(group); - } else if (container.getRecordId() == EscherContainerRecord.SP_CONTAINER) { - Map shapeToObj = agg.getShapeToObjMapping(); - ObjRecord objRecord = null; - TextObjectRecord txtRecord = null; - - for (EscherRecord record : container.getChildRecords()) { - switch (record.getRecordId()) { - case EscherClientDataRecord.RECORD_ID: - objRecord = (ObjRecord) shapeToObj.get(record); - break; - case EscherTextboxRecord.RECORD_ID: - txtRecord = (TextObjectRecord) shapeToObj.get(record); - break; - default: - break; - } - } - if (isEmbeddedObject(objRecord)) { - HSSFObjectData objectData = new HSSFObjectData(container, objRecord, root); - out.addShape(objectData); - return; - } - CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0); - final HSSFShape shape; - switch (cmo.getObjectType()) { - case CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE: - shape = new HSSFPicture(container, objRecord); - break; - case CommonObjectDataSubRecord.OBJECT_TYPE_RECTANGLE: - shape = new HSSFSimpleShape(container, objRecord, txtRecord); - break; - case CommonObjectDataSubRecord.OBJECT_TYPE_LINE: - shape = new HSSFSimpleShape(container, objRecord); - break; - case CommonObjectDataSubRecord.OBJECT_TYPE_COMBO_BOX: - shape = new HSSFCombobox(container, objRecord); - break; - case CommonObjectDataSubRecord.OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING: - EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID); - if(optRecord == null) { - shape = new HSSFSimpleShape(container, objRecord, txtRecord); - } else { - EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES); - if (null != property) { - shape = new HSSFPolygon(container, objRecord, txtRecord); - } else { - shape = new HSSFSimpleShape(container, objRecord, txtRecord); - } - } - break; - case CommonObjectDataSubRecord.OBJECT_TYPE_TEXT: - shape = new HSSFTextbox(container, objRecord, txtRecord); - break; - case CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT: - shape = new HSSFComment(container, objRecord, txtRecord, agg.getNoteRecordByObj(objRecord)); - break; - default: - shape = new HSSFSimpleShape(container, objRecord, txtRecord); - } - out.addShape(shape); - } - } - - private static boolean isEmbeddedObject(ObjRecord obj) { - Iterator subRecordIter = obj.getSubRecords().iterator(); - while (subRecordIter.hasNext()) { - SubRecord sub = subRecordIter.next(); - if (sub instanceof EmbeddedObjectRefSubRecord) { - return true; - } - } - return false; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java deleted file mode 100644 index 9e339c7c1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java +++ /dev/null @@ -1,387 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.ddf.*; -import org.apache.poi.hssf.record.*; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Iterator; - -/** - * A shape group may contain other shapes. It was no actual form on the - * sheet. - */ -public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer { - private final List shapes = new ArrayList(); - private EscherSpgrRecord _spgrRecord; - - public HSSFShapeGroup(EscherContainerRecord spgrContainer, ObjRecord objRecord) { - super(spgrContainer, objRecord); - - // read internal and external coordinates from spgrContainer - EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0); - _spgrRecord = (EscherSpgrRecord) spContainer.getChild(0); - for (EscherRecord ch : spContainer.getChildRecords()) { - switch (ch.getRecordId()) { - case EscherSpgrRecord.RECORD_ID: - break; - case EscherClientAnchorRecord.RECORD_ID: - anchor = new HSSFClientAnchor((EscherClientAnchorRecord) ch); - break; - case EscherChildAnchorRecord.RECORD_ID: - anchor = new HSSFChildAnchor((EscherChildAnchorRecord) ch); - break; - default: - break; - } - } - } - - public HSSFShapeGroup(HSSFShape parent, HSSFAnchor anchor) { - super(parent, anchor); - _spgrRecord = ((EscherContainerRecord)getEscherContainer().getChild(0)).getChildById(EscherSpgrRecord.RECORD_ID); - } - - @Override - protected EscherContainerRecord createSpContainer() { - EscherContainerRecord spgrContainer = new EscherContainerRecord(); - EscherContainerRecord spContainer = new EscherContainerRecord(); - EscherSpgrRecord spgr = new EscherSpgrRecord(); - EscherSpRecord sp = new EscherSpRecord(); - EscherOptRecord opt = new EscherOptRecord(); - EscherRecord anchor; - EscherClientDataRecord clientData = new EscherClientDataRecord(); - - spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); - spgrContainer.setOptions((short) 0x000F); - spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER); - spContainer.setOptions((short) 0x000F); - spgr.setRecordId(EscherSpgrRecord.RECORD_ID); - spgr.setOptions((short) 0x0001); - spgr.setRectX1(0); - spgr.setRectY1(0); - spgr.setRectX2(1023); - spgr.setRectY2(255); - sp.setRecordId(EscherSpRecord.RECORD_ID); - sp.setOptions((short) 0x0002); - if (getAnchor() instanceof HSSFClientAnchor) { - sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR); - } else { - sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD); - } - opt.setRecordId(EscherOptRecord.RECORD_ID); - opt.setOptions((short) 0x0023); - opt.addEscherProperty(new EscherBoolProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004)); - opt.addEscherProperty(new EscherBoolProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000)); - - anchor = getAnchor().getEscherAnchor(); - clientData.setRecordId(EscherClientDataRecord.RECORD_ID); - clientData.setOptions((short) 0x0000); - - spgrContainer.addChildRecord(spContainer); - spContainer.addChildRecord(spgr); - spContainer.addChildRecord(sp); - spContainer.addChildRecord(opt); - spContainer.addChildRecord(anchor); - spContainer.addChildRecord(clientData); - return spgrContainer; - } - - @Override - protected ObjRecord createObjRecord() { - ObjRecord obj = new ObjRecord(); - CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord(); - cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP); - cmo.setLocked(true); - cmo.setPrintable(true); - cmo.setAutofill(true); - cmo.setAutoline(true); - GroupMarkerSubRecord gmo = new GroupMarkerSubRecord(); - EndSubRecord end = new EndSubRecord(); - obj.addSubRecord(cmo); - obj.addSubRecord(gmo); - obj.addSubRecord(end); - return obj; - } - - @Override - protected void afterRemove(HSSFPatriarch patriarch) { - patriarch.getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildContainers().get(0) - .getChildById(EscherClientDataRecord.RECORD_ID)); - for ( int i=0; i getChildren() { - return Collections.unmodifiableList(shapes); - } - - /** - * 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) { - _spgrRecord.setRectX1(x1); - _spgrRecord.setRectX2(x2); - _spgrRecord.setRectY1(y1); - _spgrRecord.setRectY2(y2); - } - - public void clear() { - ArrayList copy = new ArrayList(shapes); - for (HSSFShape shape: copy){ - removeShape(shape); - } - } - - /** - * The top left x coordinate of this group. - */ - public int getX1() { - return _spgrRecord.getRectX1(); - } - - /** - * The top left y coordinate of this group. - */ - public int getY1() { - return _spgrRecord.getRectY1(); - } - - /** - * The bottom right x coordinate of this group. - */ - public int getX2() { - return _spgrRecord.getRectX2(); - } - - /** - * The bottom right y coordinate of this group. - */ - public int getY2() { - return _spgrRecord.getRectY2(); - } - - /** - * Count of all children and their childrens children. - */ - public int countOfAllChildren() { - int count = shapes.size(); - for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) { - HSSFShape shape = iterator.next(); - count += shape.countOfAllChildren(); - } - return count; - } - - @Override - void afterInsert(HSSFPatriarch patriarch){ - EscherAggregate agg = patriarch.getBoundAggregate(); - EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); - agg.associateShapeToObjRecord(containerRecord.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord()); - } - - @Override - void setShapeId(int shapeId){ - EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); - EscherSpRecord spRecord = containerRecord.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setShapeId(shapeId); - CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0); - cod.setObjectId((short) (shapeId % 1024)); - } - - @Override - int getShapeId(){ - EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); - return ((EscherSpRecord)containerRecord.getChildById(EscherSpRecord.RECORD_ID)).getShapeId(); - } - - @Override - protected HSSFShape cloneShape() { - throw new IllegalStateException("Use method cloneShape(HSSFPatriarch patriarch)"); - } - - protected HSSFShape cloneShape(HSSFPatriarch patriarch) { - EscherContainerRecord spgrContainer = new EscherContainerRecord(); - spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); - spgrContainer.setOptions((short) 0x000F); - EscherContainerRecord spContainer = new EscherContainerRecord(); - EscherContainerRecord cont = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); - byte [] inSp = cont.serialize(); - spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory()); - - spgrContainer.addChildRecord(spContainer); - ObjRecord obj = null; - if (null != getObjRecord()){ - obj = (ObjRecord) getObjRecord().cloneViaReserialise(); - } - - HSSFShapeGroup group = new HSSFShapeGroup(spgrContainer, obj); - group.setPatriarch(patriarch); - - for (HSSFShape shape: getChildren()){ - HSSFShape newShape; - if (shape instanceof HSSFShapeGroup){ - newShape = ((HSSFShapeGroup)shape).cloneShape(patriarch); - } else { - newShape = shape.cloneShape(); - } - group.addShape(newShape); - group.onCreate(newShape); - } - return group; - } - - public boolean removeShape(HSSFShape shape) { - boolean isRemoved = getEscherContainer().removeChildRecord(shape.getEscherContainer()); - if (isRemoved){ - shape.afterRemove(this.getPatriarch()); - shapes.remove(shape); - } - return isRemoved; - } - - public Iterator iterator() { - return shapes.iterator(); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeTypes.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeTypes.java deleted file mode 100644 index d72b4003d..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeTypes.java +++ /dev/null @@ -1,224 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -public interface HSSFShapeTypes { - public static final int NotPrimitive = 0; - public static final int Rectangle = 1; - public static final int RoundRectangle = 2; - public static final int Ellipse = 3; - public static final int Diamond = 4; - public static final int IsocelesTriangle = 5; - public static final int RightTriangle = 6; - public static final int Parallelogram = 7; - public static final int Trapezoid = 8; - public static final int Hexagon = 9; - public static final int Octagon = 10; - public static final int Plus = 11; - public static final int Star = 12; - public static final int Arrow = 13; - public static final int ThickArrow = 14; - public static final int HomePlate = 15; - public static final int Cube = 16; - public static final int Balloon = 17; - public static final int Seal = 18; - public static final int Arc = 19; - public static final int Line = 20; - public static final int Plaque = 21; - public static final int Can = 22; - public static final int Donut = 23; - public static final int TextSimple = 24; - public static final int TextOctagon = 25; - public static final int TextHexagon = 26; - public static final int TextCurve = 27; - public static final int TextWave = 28; - public static final int TextRing = 29; - public static final int TextOnCurve = 30; - public static final int TextOnRing = 31; - public static final int StraightConnector1 = 32; - public static final int BentConnector2 = 33; - public static final int BentConnector3 = 34; - public static final int BentConnector4 = 35; - public static final int BentConnector5 = 36; - public static final int CurvedConnector2 = 37; - public static final int CurvedConnector3 = 38; - public static final int CurvedConnector4 = 39; - public static final int CurvedConnector5 = 40; - public static final int Callout1 = 41; - public static final int Callout2 = 42; - public static final int Callout3 = 43; - public static final int AccentCallout1 = 44; - public static final int AccentCallout2 = 45; - public static final int AccentCallout3 = 46; - public static final int BorderCallout1 = 47; - public static final int BorderCallout2 = 48; - public static final int BorderCallout3 = 49; - public static final int AccentBorderCallout1 = 50; - public static final int AccentBorderCallout2 = 51; - public static final int AccentBorderCallout3 = 52; - public static final int Ribbon = 53; - public static final int Ribbon2 = 54; - public static final int Chevron = 55; - public static final int Pentagon = 56; - public static final int NoSmoking = 57; - public static final int Star8 = 58; - public static final int Star16 = 59; - public static final int Star32 = 60; - public static final int WedgeRectCallout = 61; - public static final int WedgeRRectCallout = 62; - public static final int WedgeEllipseCallout = 63; - public static final int Wave = 64; - public static final int FoldedCorner = 65; - public static final int LeftArrow = 66; - public static final int DownArrow = 67; - public static final int UpArrow = 68; - public static final int LeftRightArrow = 69; - public static final int UpDownArrow = 70; - public static final int IrregularSeal1 = 71; - public static final int IrregularSeal2 = 72; - public static final int LightningBolt = 73; - public static final int Heart = 74; - public static final int PictureFrame = 75; - public static final int QuadArrow = 76; - public static final int LeftArrowCallout = 77; - public static final int RightArrowCallout = 78; - public static final int UpArrowCallout = 79; - public static final int DownArrowCallout = 80; - public static final int LeftRightArrowCallout = 81; - public static final int UpDownArrowCallout = 82; - public static final int QuadArrowCallout = 83; - public static final int Bevel = 84; - public static final int LeftBracket = 85; - public static final int RightBracket = 86; - public static final int LeftBrace = 87; - public static final int RightBrace = 88; - public static final int LeftUpArrow = 89; - public static final int BentUpArrow = 90; - public static final int BentArrow = 91; - public static final int Star24 = 92; - public static final int StripedRightArrow = 93; - public static final int NotchedRightArrow = 94; - public static final int BlockArc = 95; - public static final int SmileyFace = 96; - public static final int VerticalScroll = 97; - public static final int HorizontalScroll = 98; - public static final int CircularArrow = 99; - public static final int NotchedCircularArrow = 100; - public static final int UturnArrow = 101; - public static final int CurvedRightArrow = 102; - public static final int CurvedLeftArrow = 103; - public static final int CurvedUpArrow = 104; - public static final int CurvedDownArrow = 105; - public static final int CloudCallout = 106; - public static final int EllipseRibbon = 107; - public static final int EllipseRibbon2 = 108; - public static final int FlowChartProcess = 109; - public static final int FlowChartDecision = 110; - public static final int FlowChartInputOutput = 111; - public static final int FlowChartPredefinedProcess = 112; - public static final int FlowChartInternalStorage = 113; - public static final int FlowChartDocument = 114; - public static final int FlowChartMultidocument = 115; - public static final int FlowChartTerminator = 116; - public static final int FlowChartPreparation = 117; - public static final int FlowChartManualInput = 118; - public static final int FlowChartManualOperation = 119; - public static final int FlowChartConnector = 120; - public static final int FlowChartPunchedCard = 121; - public static final int FlowChartPunchedTape = 122; - public static final int FlowChartSummingJunction = 123; - public static final int FlowChartOr = 124; - public static final int FlowChartCollate = 125; - public static final int FlowChartSort = 126; - public static final int FlowChartExtract = 127; - public static final int FlowChartMerge = 128; - public static final int FlowChartOfflineStorage = 129; - public static final int FlowChartOnlineStorage = 130; - public static final int FlowChartMagneticTape = 131; - public static final int FlowChartMagneticDisk = 132; - public static final int FlowChartMagneticDrum = 133; - public static final int FlowChartDisplay = 134; - public static final int FlowChartDelay = 135; - public static final int TextPlainText = 136; - public static final int TextStop = 137; - public static final int TextTriangle = 138; - public static final int TextTriangleInverted = 139; - public static final int TextChevron = 140; - public static final int TextChevronInverted = 141; - public static final int TextRingInside = 142; - public static final int TextRingOutside = 143; - public static final int TextArchUpCurve = 144; - public static final int TextArchDownCurve = 145; - public static final int TextCircleCurve = 146; - public static final int TextButtonCurve = 147; - public static final int TextArchUpPour = 148; - public static final int TextArchDownPour = 149; - public static final int TextCirclePour = 150; - public static final int TextButtonPour = 151; - public static final int TextCurveUp = 152; - public static final int TextCurveDown = 153; - public static final int TextCascadeUp = 154; - public static final int TextCascadeDown = 155; - public static final int TextWave1 = 156; - public static final int TextWave2 = 157; - public static final int TextWave3 = 158; - public static final int TextWave4 = 159; - public static final int TextInflate = 160; - public static final int TextDeflate = 161; - public static final int TextInflateBottom = 162; - public static final int TextDeflateBottom = 163; - public static final int TextInflateTop = 164; - public static final int TextDeflateTop = 165; - public static final int TextDeflateInflate = 166; - public static final int TextDeflateInflateDeflate = 167; - public static final int TextFadeRight = 168; - public static final int TextFadeLeft = 169; - public static final int TextFadeUp = 170; - public static final int TextFadeDown = 171; - public static final int TextSlantUp = 172; - public static final int TextSlantDown = 173; - public static final int TextCanUp = 174; - public static final int TextCanDown = 175; - public static final int FlowChartAlternateProcess = 176; - public static final int FlowChartOffpageConnector = 177; - public static final int Callout90 = 178; - public static final int AccentCallout90 = 179; - public static final int BorderCallout90 = 180; - public static final int AccentBorderCallout90 = 181; - public static final int LeftRightUpArrow = 182; - public static final int Sun = 183; - public static final int Moon = 184; - public static final int BracketPair = 185; - public static final int BracePair = 186; - public static final int Star4 = 187; - public static final int DoubleWave = 188; - public static final int ActionButtonBlank = 189; - public static final int ActionButtonHome = 190; - public static final int ActionButtonHelp = 191; - public static final int ActionButtonInformation = 192; - public static final int ActionButtonForwardNext = 193; - public static final int ActionButtonBackPrevious = 194; - public static final int ActionButtonEnd = 195; - public static final int ActionButtonBeginning = 196; - public static final int ActionButtonReturn = 197; - public static final int ActionButtonDocument = 198; - public static final int ActionButtonSound = 199; - public static final int ActionButtonMovie = 200; - public static final int HostControl = 201; - public static final int TextBox = 202; -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java deleted file mode 100644 index 5360fe600..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ /dev/null @@ -1,2654 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.hssf.model.DrawingManager2; -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.model.InternalSheet; -import org.apache.poi.hssf.model.InternalWorkbook; -import org.apache.poi.hssf.record.AutoFilterInfoRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.DVRecord; -import org.apache.poi.hssf.record.DimensionsRecord; -import org.apache.poi.hssf.record.DrawingRecord; -import org.apache.poi.hssf.record.EscherAggregate; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.HyperlinkRecord; -import org.apache.poi.hssf.record.NameRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.SCLRecord; -import org.apache.poi.hssf.record.WSBoolRecord; -import org.apache.poi.hssf.record.WindowTwoRecord; -import org.apache.poi.hssf.record.aggregates.DataValidityTable; -import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; -import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; -import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock; -import org.apache.poi.hssf.usermodel.helpers.HSSFRowShifter; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.MemFuncPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.UnionPtg; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellRange; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.helpers.RowShifter; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.PaneInformation; -import org.apache.poi.ss.util.SSCellRange; -import org.apache.poi.ss.util.SheetUtil; -import org.apache.poi.util.Configurator; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * High level representation of a worksheet. - */ -public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { - private static final POILogger log = POILogFactory.getLogger(HSSFSheet.class); - private static final int DEBUG = POILogger.DEBUG; - - /** - * width of 1px in columns with default width in units of 1/256 of a character width - */ - private static final float PX_DEFAULT = 32.00f; - /** - * width of 1px in columns with overridden width in units of 1/256 of a character width - */ - private static final float PX_MODIFIED = 36.56f; - - - /** - * Used for compile-time optimization. This is the initial size for the collection of - * rows. It is currently set to 20. If you generate larger sheets you may benefit - * by setting this to a higher number and recompiling a custom edition of HSSFSheet. - */ - public final static int INITIAL_CAPACITY = Configurator.getIntValue("HSSFSheet.RowInitialCapacity", 20); - - /** - * reference to the low level {@link InternalSheet} object - */ - private final InternalSheet _sheet; - /** - * stores rows by zero-based row number - */ - private final TreeMap _rows; - protected final InternalWorkbook _book; - protected final HSSFWorkbook _workbook; - private HSSFPatriarch _patriarch; - private int _firstrow; - private int _lastrow; - - /** - * Creates new HSSFSheet - called by HSSFWorkbook to create a sheet from - * scratch. You should not be calling this from application code (its protected anyhow). - * - * @param workbook - The HSSF Workbook object associated with the sheet. - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createSheet() - */ - protected HSSFSheet(HSSFWorkbook workbook) { - _sheet = InternalSheet.createSheet(); - _rows = new TreeMap(); - this._workbook = workbook; - this._book = workbook.getWorkbook(); - } - - /** - * Creates an HSSFSheet representing the given Sheet object. Should only be - * called by HSSFWorkbook when reading in an exisiting file. - * - * @param workbook - The HSSF Workbook object associated with the sheet. - * @param sheet - lowlevel Sheet object this sheet will represent - * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createSheet() - */ - protected HSSFSheet(HSSFWorkbook workbook, InternalSheet sheet) { - this._sheet = sheet; - _rows = new TreeMap(); - this._workbook = workbook; - this._book = workbook.getWorkbook(); - setPropertiesFromSheet(sheet); - } - - HSSFSheet cloneSheet(HSSFWorkbook workbook) { - this.getDrawingPatriarch();/**Aggregate drawing records**/ - HSSFSheet sheet = new HSSFSheet(workbook, _sheet.cloneSheet()); - int pos = sheet._sheet.findFirstRecordLocBySid(DrawingRecord.sid); - DrawingRecord dr = (DrawingRecord) sheet._sheet.findFirstRecordBySid(DrawingRecord.sid); - if (null != dr) { - sheet._sheet.getRecords().remove(dr); - } - if (getDrawingPatriarch() != null) { - HSSFPatriarch patr = HSSFPatriarch.createPatriarch(this.getDrawingPatriarch(), sheet); - sheet._sheet.getRecords().add(pos, patr.getBoundAggregate()); - sheet._patriarch = patr; - } - return sheet; - } - - /** - * check whether the data of sheet can be serialized - */ - protected void preSerialize(){ - if (_patriarch != null){ - _patriarch.preSerialize(); - } - } - - /** - * Return the parent workbook - * - * @return the parent workbook - */ - @Override - public HSSFWorkbook getWorkbook() { - return _workbook; - } - - /** - * used internally to set the properties given a Sheet object - */ - private void setPropertiesFromSheet(InternalSheet sheet) { - RowRecord row = sheet.getNextRow(); - - while (row != null) { - createRowFromRecord(row); - - row = sheet.getNextRow(); - } - - Iterator iter = sheet.getCellValueIterator(); - long timestart = System.currentTimeMillis(); - - if (log.check( POILogger.DEBUG )) { - log.log(DEBUG, "Time at start of cell creating in HSSF sheet = ", - Long.valueOf(timestart)); - } - HSSFRow lastrow = null; - - // Add every cell to its row - while (iter.hasNext()) { - CellValueRecordInterface cval = iter.next(); - - long cellstart = System.currentTimeMillis(); - HSSFRow hrow = lastrow; - - if (hrow == null || hrow.getRowNum() != cval.getRow()) { - hrow = getRow(cval.getRow()); - lastrow = hrow; - if (hrow == null) { - /* we removed this check, see bug 47245 for the discussion around this - // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords - // Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too. - if (rowRecordsAlreadyPresent) { - // if at least one row record is present, all should be present. - throw new RuntimeException("Unexpected missing row when some rows already present"); - }*/ - - // create the row record on the fly now. - RowRecord rowRec = new RowRecord(cval.getRow()); - sheet.addRow(rowRec); - hrow = createRowFromRecord(rowRec); - } - } - if (log.check( POILogger.DEBUG )) { - if (cval instanceof Record) { - log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) ); - } else { - log.log( DEBUG, "record = " + cval ); - } - } - hrow.createCellFromRecord( cval ); - if (log.check( POILogger.DEBUG )) { - log.log( DEBUG, "record took ", - Long.valueOf( System.currentTimeMillis() - cellstart ) ); - } - - } - if (log.check( POILogger.DEBUG )) { - log.log(DEBUG, "total sheet cell creation took ", - Long.valueOf(System.currentTimeMillis() - timestart)); - } - } - - /** - * Create a new row within the sheet and return the high level representation - * - * @param rownum row number - * @return High level HSSFRow object representing a row in the sheet - * @see org.apache.poi.hssf.usermodel.HSSFRow - * @see #removeRow(org.apache.poi.ss.usermodel.Row) - */ - @Override - public HSSFRow createRow(int rownum) { - HSSFRow row = new HSSFRow(_workbook, this, rownum); - // new rows inherit default height from the sheet - row.setHeight(getDefaultRowHeight()); - row.getRowRecord().setBadFontHeight(false); - - addRow(row, true); - return row; - } - - /** - * Used internally to create a high level Row object from a low level row object. - * USed when reading an existing file - * - * @param row low level record to represent as a high level Row and add to sheet - * @return HSSFRow high level representation - */ - - private HSSFRow createRowFromRecord(RowRecord row) { - HSSFRow hrow = new HSSFRow(_workbook, this, row); - - addRow(hrow, false); - return hrow; - } - - /** - * Remove a row from this sheet. All cells contained in the row are removed as well - * - * @param row representing a row to remove. - */ - @Override - public void removeRow(Row row) { - HSSFRow hrow = (HSSFRow) row; - if (row.getSheet() != this) { - throw new IllegalArgumentException("Specified row does not belong to this sheet"); - } - for (Cell cell : row) { - HSSFCell xcell = (HSSFCell) cell; - if (xcell.isPartOfArrayFormulaGroup()) { - String msg = "Row[rownum=" + row.getRowNum() + "] contains cell(s) included in a multi-cell array formula. You cannot change part of an array."; - xcell.notifyArrayFormulaChanging(msg); - } - } - - if (_rows.size() > 0) { - Integer key = Integer.valueOf(row.getRowNum()); - HSSFRow removedRow = _rows.remove(key); - if (removedRow != row) { - //should not happen if the input argument is valid - throw new IllegalArgumentException("Specified row does not belong to this sheet"); - } - if (hrow.getRowNum() == getLastRowNum()) { - _lastrow = findLastRow(_lastrow); - } - if (hrow.getRowNum() == getFirstRowNum()) { - _firstrow = findFirstRow(_firstrow); - } - _sheet.removeRow(hrow.getRowRecord()); - } - } - - /** - * used internally to refresh the "last row" when the last row is removed. - */ - private int findLastRow(int lastrow) { - if (lastrow < 1) { - return 0; - } - int rownum = lastrow - 1; - HSSFRow r = getRow(rownum); - - while (r == null && rownum > 0) { - r = getRow(--rownum); - } - if (r == null) { - return 0; - } - return rownum; - } - - /** - * used internally to refresh the "first row" when the first row is removed. - */ - - private int findFirstRow(int firstrow) { - int rownum = firstrow + 1; - HSSFRow r = getRow(rownum); - - while (r == null && rownum <= getLastRowNum()) { - r = getRow(++rownum); - } - - if (rownum > getLastRowNum()) - return 0; - - return rownum; - } - - /** - * add a row to the sheet - * - * @param addLow whether to add the row to the low level model - false if its already there - */ - - private void addRow(HSSFRow row, boolean addLow) { - _rows.put(Integer.valueOf(row.getRowNum()), row); - if (addLow) { - _sheet.addRow(row.getRowRecord()); - } - boolean firstRow = _rows.size() == 1; - if (row.getRowNum() > getLastRowNum() || firstRow) { - _lastrow = row.getRowNum(); - } - if (row.getRowNum() < getFirstRowNum() || firstRow) { - _firstrow = row.getRowNum(); - } - } - - /** - * Returns the logical row (not physical) 0-based. If you ask for a row that is not - * defined you get a null. This is to say row 4 represents the fifth row on a sheet. - * - * @param rowIndex row to get - * @return HSSFRow representing the row number or null if its not defined on the sheet - */ - @Override - public HSSFRow getRow(int rowIndex) { - return _rows.get(Integer.valueOf(rowIndex)); - } - - /** - * Returns the number of physically defined rows (NOT the number of rows in the sheet) - */ - @Override - public int getPhysicalNumberOfRows() { - return _rows.size(); - } - - /** - * Gets the first row on the sheet - * - * @return the number of the first logical row on the sheet, zero based - */ - @Override - public int getFirstRowNum() { - return _firstrow; - } - - /** - * Gets the number last row on the sheet. - * Owing to idiosyncrasies in the excel file - * format, if the result of calling this method - * is zero, you can't tell if that means there - * are zero rows on the sheet, or one at - * position zero. For that case, additionally - * call {@link #getPhysicalNumberOfRows()} to - * tell if there is a row at position zero - * or not. - * - * @return the number of the last row contained in this sheet, zero based. - */ - @Override - public int getLastRowNum() { - return _lastrow; - } - - @Override - public List getDataValidations() { - DataValidityTable dvt = _sheet.getOrCreateDataValidityTable(); - final List hssfValidations = new ArrayList(); - RecordVisitor visitor = new RecordVisitor() { - private HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(getWorkbook()); - - @Override - public void visitRecord(Record r) { - if (!(r instanceof DVRecord)) { - return; - } - DVRecord dvRecord = (DVRecord) r; - CellRangeAddressList regions = dvRecord.getCellRangeAddress().copy(); - DVConstraint constraint = DVConstraint.createDVConstraint(dvRecord, book); - HSSFDataValidation hssfDataValidation = new HSSFDataValidation(regions, constraint); - hssfDataValidation.setErrorStyle(dvRecord.getErrorStyle()); - hssfDataValidation.setEmptyCellAllowed(dvRecord.getEmptyCellAllowed()); - hssfDataValidation.setSuppressDropDownArrow(dvRecord.getSuppressDropdownArrow()); - hssfDataValidation.createPromptBox(dvRecord.getPromptTitle(), dvRecord.getPromptText()); - hssfDataValidation.setShowPromptBox(dvRecord.getShowPromptOnCellSelected()); - hssfDataValidation.createErrorBox(dvRecord.getErrorTitle(), dvRecord.getErrorText()); - hssfDataValidation.setShowErrorBox(dvRecord.getShowErrorOnInvalidValue()); - hssfValidations.add(hssfDataValidation); - } - }; - dvt.visitContainedRecords(visitor); - return hssfValidations; - } - - /** - * Creates a data validation object - * - * @param dataValidation The Data validation object settings - */ - @Override - public void addValidationData(DataValidation dataValidation) { - if (dataValidation == null) { - throw new IllegalArgumentException("objValidation must not be null"); - } - HSSFDataValidation hssfDataValidation = (HSSFDataValidation) dataValidation; - DataValidityTable dvt = _sheet.getOrCreateDataValidityTable(); - - DVRecord dvRecord = hssfDataValidation.createDVRecord(this); - dvt.addDataValidation(dvRecord); - } - - /** - * Get the visibility state for a given column. - * - * @param columnIndex - the column to get (0-based) - * @param hidden - the visiblity state of the column - */ - @Override - public void setColumnHidden(int columnIndex, boolean hidden) { - _sheet.setColumnHidden(columnIndex, hidden); - } - - /** - * Get the hidden state for a given column. - * - * @param columnIndex - the column to set (0-based) - * @return hidden - false if the column is visible - */ - @Override - public boolean isColumnHidden(int columnIndex) { - return _sheet.isColumnHidden(columnIndex); - } - - /** - * Set the width (in units of 1/256th of a character width)

    - * - * The maximum column width for an individual cell is 255 characters. - * This value represents the number of characters that can be displayed - * in a cell that is formatted with the standard font (first font in the workbook).

    - * - * Character width is defined as the maximum digit width - * of the numbers 0, 1, 2, ... 9 as rendered - * using the default font (first font in the workbook).

    - * - * Unless you are using a very special font, the default character is '0' (zero), - * this is true for Arial (default font font in HSSF) and Calibri (default font in XSSF)

    - * - * Please note, that the width set by this method includes 4 pixels of margin padding (two on each side), - * plus 1 pixel padding for the gridlines (Section 3.3.1.12 of the OOXML spec). - * This results is a slightly less value of visible characters than passed to this method (approx. 1/2 of a character).

    - * - * To compute the actual number of visible characters, - * Excel uses the following formula (Section 3.3.1.12 of the OOXML spec):

    - * - * - * width = Truncate([{Number of Visible Characters} * - * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256 - * - *

    Using the Calibri font as an example, the maximum digit width of 11 point font size is 7 pixels (at 96 dpi). - * If you set a column width to be eight characters wide, e.g. setColumnWidth(columnIndex, 8*256), - * then the actual value of visible characters (the value shown in Excel) is derived from the following equation: - * - * Truncate([numChars*7+5]/7*256)/256 = 8; - * - *

    - * which gives 7.29. - * - * @param columnIndex - the column to set (0-based) - * @param width - the width in units of 1/256th of a character width - * @throws IllegalArgumentException if width > 255*256 (the maximum column width in Excel is 255 characters) - */ - @Override - public void setColumnWidth(int columnIndex, int width) { - _sheet.setColumnWidth(columnIndex, width); - } - - /** - * get the width (in units of 1/256th of a character width ) - * - * @param columnIndex - the column to set (0-based) - * @return width - the width in units of 1/256th of a character width - */ - @Override - public int getColumnWidth(int columnIndex) { - return _sheet.getColumnWidth(columnIndex); - } - - @Override - public float getColumnWidthInPixels(int column){ - int cw = getColumnWidth(column); - int def = getDefaultColumnWidth()*256; - float px = (cw == def ? PX_DEFAULT : PX_MODIFIED); - - return cw/px; - } - - /** - * get the default column width for the sheet (if the columns do not define their own width) in - * characters - * - * @return default column width - */ - @Override - public int getDefaultColumnWidth() { - return _sheet.getDefaultColumnWidth(); - } - - /** - * set the default column width for the sheet (if the columns do not define their own width) in - * characters - * - * @param width default column width - */ - @Override - public void setDefaultColumnWidth(int width) { - _sheet.setDefaultColumnWidth(width); - } - - - /** - * get the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @return default row height - */ - @Override - public short getDefaultRowHeight() { - return _sheet.getDefaultRowHeight(); - } - - /** - * get the default row height for the sheet (if the rows do not define their own height) in - * points. - * - * @return default row height in points - */ - @Override - public float getDefaultRowHeightInPoints() { - return ((float) _sheet.getDefaultRowHeight() / 20); - } - - /** - * set the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @param height default row height - */ - @Override - public void setDefaultRowHeight(short height) { - _sheet.setDefaultRowHeight(height); - } - - /** - * set the default row height for the sheet (if the rows do not define their own height) in - * points - * - * @param height default row height - */ - @Override - public void setDefaultRowHeightInPoints(float height) { - _sheet.setDefaultRowHeight((short) (height * 20)); - } - - /** - * Returns the HSSFCellStyle that applies to the given - * (0 based) column, or null if no style has been - * set for that column - */ - @Override - public HSSFCellStyle getColumnStyle(int column) { - short styleIndex = _sheet.getXFIndexForColAt((short) column); - - if (styleIndex == 0xf) { - // None set - return null; - } - - ExtendedFormatRecord xf = _book.getExFormatAt(styleIndex); - return new HSSFCellStyle(styleIndex, xf, _book); - } - - /** - * get whether gridlines are printed. - * - * @return true if printed - */ - public boolean isGridsPrinted() { - return _sheet.isGridsPrinted(); - } - - /** - * set whether gridlines printed. - * - * @param value false if not printed. - */ - public void setGridsPrinted(boolean value) { - _sheet.setGridsPrinted(value); - } - - /** - * Adds a merged region of cells on a sheet. - * - * @param region to merge - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if region intersects with an existing region on this sheet - */ - @Override - public int addMergedRegion(CellRangeAddress region) { - return addMergedRegion(region, true); - } - - /** - * Adds a merged region of cells (hence those cells form one). - * Skips validation. It is possible to create overlapping merged regions - * or create a merged region that intersects a multi-cell array formula - * with this formula, which may result in a corrupt workbook. - * - * To check for merged regions overlapping array formulas or other merged regions - * after addMergedRegionUnsafe has been called, call {@link #validateMergedRegions()}, which runs in O(n^2) time. - * - * @param region to merge - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells - */ - @Override - public int addMergedRegionUnsafe(CellRangeAddress region) { - return addMergedRegion(region, false); - } - - /** - * Verify that merged regions do not intersect multi-cell array formulas and - * no merged regions intersect another merged region in this sheet. - * - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if at least one region intersects with another merged region in this sheet - */ - @Override - public void validateMergedRegions() { - checkForMergedRegionsIntersectingArrayFormulas(); - checkForIntersectingMergedRegions(); - } - - /** - * adds a merged region of cells (hence those cells form one) - * - * @param region (rowfrom/colfrom-rowto/colto) to merge - * @param validate whether to validate merged region - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells - * @throws IllegalStateException if region intersects with an existing merged region - * or multi-cell array formula on this sheet - */ - private int addMergedRegion(CellRangeAddress region, boolean validate) { - if (region.getNumberOfCells() < 2) { - throw new IllegalArgumentException("Merged region " + region.formatAsString() + " must contain 2 or more cells"); - } - region.validate(SpreadsheetVersion.EXCEL97); - - if (validate) { - // throw IllegalStateException if the argument CellRangeAddress intersects with - // a multi-cell array formula defined in this sheet - validateArrayFormulas(region); - - // Throw IllegalStateException if the argument CellRangeAddress intersects with - // a merged region already in this sheet - validateMergedRegions(region); - } - - return _sheet.addMergedRegion(region.getFirstRow(), - region.getFirstColumn(), - region.getLastRow(), - region.getLastColumn()); - } - - private void validateArrayFormulas(CellRangeAddress region) { - // FIXME: this may be faster if it looped over array formulas directly rather than looping over each cell in - // the region and searching if that cell belongs to an array formula - int firstRow = region.getFirstRow(); - int firstColumn = region.getFirstColumn(); - int lastRow = region.getLastRow(); - int lastColumn = region.getLastColumn(); - for (int rowIn = firstRow; rowIn <= lastRow; rowIn++) { - HSSFRow row = getRow(rowIn); - if (row == null) continue; - - for (int colIn = firstColumn; colIn <= lastColumn; colIn++) { - HSSFCell cell = row.getCell(colIn); - if (cell == null) continue; - - if (cell.isPartOfArrayFormulaGroup()) { - CellRangeAddress arrayRange = cell.getArrayFormulaRange(); - if (arrayRange.getNumberOfCells() > 1 && region.intersects(arrayRange)) { - String msg = "The range " + region.formatAsString() + " intersects with a multi-cell array formula. " + - "You cannot merge cells of an array."; - throw new IllegalStateException(msg); - } - } - } - } - - } - - /** - * Verify that none of the merged regions intersect a multi-cell array formula in this sheet - * - * @throws IllegalStateException if candidate region intersects an existing array formula in this sheet - */ - private void checkForMergedRegionsIntersectingArrayFormulas() { - for (CellRangeAddress region : getMergedRegions()) { - validateArrayFormulas(region); - } - } - - private void validateMergedRegions(CellRangeAddress candidateRegion) { - for (final CellRangeAddress existingRegion : getMergedRegions()) { - if (existingRegion.intersects(candidateRegion)) { - throw new IllegalStateException("Cannot add merged region " + candidateRegion.formatAsString() + - " to sheet because it overlaps with an existing merged region (" + existingRegion.formatAsString() + ")."); - } - } - } - - /** - * Verify that no merged regions intersect another merged region in this sheet. - * - * @throws IllegalStateException if at least one region intersects with another merged region in this sheet - */ - private void checkForIntersectingMergedRegions() { - final List regions = getMergedRegions(); - final int size = regions.size(); - for (int i=0; i < size; i++) { - final CellRangeAddress region = regions.get(i); - for (final CellRangeAddress other : regions.subList(i+1, regions.size())) { - if (region.intersects(other)) { - String msg = "The range " + region.formatAsString() + - " intersects with another merged region " + - other.formatAsString() + " in this sheet"; - throw new IllegalStateException(msg); - } - } - } - } - - /** - * Control if Excel should be asked to recalculate all formulas on this sheet - * when the workbook is opened.

    - * - * Calculating the formula values with {@link org.apache.poi.ss.usermodel.FormulaEvaluator} is the - * recommended solution, but this may be used for certain cases where - * evaluation in POI is not possible.

    - * - * It is recommended to force recalcuation of formulas on workbook level using - * {@link org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean)} - * to ensure that all cross-worksheet formuals and external dependencies are updated. - * - * @param value true if the application will perform a full recalculation of - * this worksheet values when the workbook is opened - * @see org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean) - */ - @Override - public void setForceFormulaRecalculation(boolean value) { - _sheet.setUncalced(value); - } - - /** - * Whether a record must be inserted or not at generation to indicate that - * formula must be recalculated when workbook is opened. - * - * @return true if an uncalced record must be inserted or not at generation - */ - @Override - public boolean getForceFormulaRecalculation() { - return _sheet.getUncalced(); - } - - - /** - * determines whether the output is vertically centered on the page. - * - * @param value true to vertically center, false otherwise. - */ - @Override - public void setVerticallyCenter(boolean value) { - _sheet.getPageSettings().getVCenter().setVCenter(value); - } - - /** - * Determine whether printed output for this sheet will be vertically centered. - */ - @Override - public boolean getVerticallyCenter() { - return _sheet.getPageSettings().getVCenter().getVCenter(); - } - - /** - * determines whether the output is horizontally centered on the page. - * - * @param value true to horizontally center, false otherwise. - */ - @Override - public void setHorizontallyCenter(boolean value) { - _sheet.getPageSettings().getHCenter().setHCenter(value); - } - - /** - * Determine whether printed output for this sheet will be horizontally centered. - */ - @Override - public boolean getHorizontallyCenter() { - return _sheet.getPageSettings().getHCenter().getHCenter(); - } - - /** - * Sets whether the worksheet is displayed from right to left instead of from left to right. - * - * @param value true for right to left, false otherwise. - */ - @Override - public void setRightToLeft(boolean value) { - _sheet.getWindowTwo().setArabic(value); - } - - /** - * Whether the text is displayed in right-to-left mode in the window - * - * @return whether the text is displayed in right-to-left mode in the window - */ - @Override - public boolean isRightToLeft() { - return _sheet.getWindowTwo().getArabic(); - } - - /** - * removes a merged region of cells (hence letting them free) - * - * @param index of the region to unmerge - */ - @Override - public void removeMergedRegion(int index) { - _sheet.removeMergedRegion(index); - } - - /** - * Removes a number of merged regions of cells (hence letting them free) - * - * @param indices A set of the regions to unmerge - */ - @Override - public void removeMergedRegions(Collection indices) { - for (int i : (new TreeSet(indices)).descendingSet()) { - _sheet.removeMergedRegion(i); - } - } - - /** - * returns the number of merged regions - * - * @return number of merged regions - */ - @Override - public int getNumMergedRegions() { - return _sheet.getNumMergedRegions(); - } - - /** - * @return the merged region at the specified index - */ - @Override - public CellRangeAddress getMergedRegion(int index) { - return _sheet.getMergedRegionAt(index); - } - - /** - * @return the list of merged regions - */ - @Override - public List getMergedRegions() { - List addresses = new ArrayList(); - int count = _sheet.getNumMergedRegions(); - for (int i=0; i < count; i++) { - addresses.add(_sheet.getMergedRegionAt(i)); - } - return addresses; - } - - /** - * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not - * be the third row if say for instance the second row is undefined. - * Call getRowNum() on each row if you care which one it is. - */ - @Override - public Iterator rowIterator() { - @SuppressWarnings("unchecked") // can this clumsy generic syntax be improved? - Iterator result = (Iterator) (Iterator) _rows.values().iterator(); - return result; - } - - /** - * Alias for {@link #rowIterator()} to allow - * foreach loops - */ - @Override - public Iterator iterator() { - return rowIterator(); - } - - - /** - * used internally in the API to get the low level Sheet record represented by this - * Object. - * - * @return Sheet - low level representation of this HSSFSheet. - */ - /*package*/ InternalSheet getSheet() { - return _sheet; - } - - /** - * whether alternate expression evaluation is on - * - * @param b alternative expression evaluation or not - */ - public void setAlternativeExpression(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setAlternateExpression(b); - } - - /** - * whether alternative formula entry is on - * - * @param b alternative formulas or not - */ - public void setAlternativeFormula(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setAlternateFormula(b); - } - - /** - * show automatic page breaks or not - * - * @param b whether to show auto page breaks - */ - @Override - public void setAutobreaks(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setAutobreaks(b); - } - - /** - * set whether sheet is a dialog sheet or not - * - * @param b isDialog or not - */ - public void setDialog(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setDialog(b); - } - - /** - * set whether to display the guts or not - * - * @param b guts or no guts (or glory) - */ - @Override - public void setDisplayGuts(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setDisplayGuts(b); - } - - /** - * fit to page option is on - * - * @param b fit or not - */ - @Override - public void setFitToPage(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setFitToPage(b); - } - - /** - * set if row summaries appear below detail in the outline - * - * @param b below or not - */ - @Override - public void setRowSumsBelow(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setRowSumsBelow(b); - //setAlternateExpression must be set in conjuction with setRowSumsBelow - record.setAlternateExpression(b); - } - - /** - * set if col summaries appear right of the detail in the outline - * - * @param b right or not - */ - @Override - public void setRowSumsRight(boolean b) { - WSBoolRecord record = - (WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid); - - record.setRowSumsRight(b); - } - - /** - * whether alternate expression evaluation is on - * - * @return alternative expression evaluation or not - */ - public boolean getAlternateExpression() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getAlternateExpression(); - } - - /** - * whether alternative formula entry is on - * - * @return alternative formulas or not - */ - public boolean getAlternateFormula() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getAlternateFormula(); - } - - /** - * show automatic page breaks or not - * - * @return whether to show auto page breaks - */ - @Override - public boolean getAutobreaks() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getAutobreaks(); - } - - /** - * get whether sheet is a dialog sheet or not - * - * @return isDialog or not - */ - public boolean getDialog() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getDialog(); - } - - /** - * get whether to display the guts or not - * - * @return guts or no guts (or glory) - */ - @Override - public boolean getDisplayGuts() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getDisplayGuts(); - } - - - /** - * Gets the flag indicating whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - *

    - * In Excel 2003 this option can be changed in the Options dialog on the View tab. - *

    - * - * @return whether all zero values on the worksheet are displayed - */ - @Override - public boolean isDisplayZeros() { - return _sheet.getWindowTwo().getDisplayZeros(); - } - - /** - * Set whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - *

    - * In Excel 2003 this option can be set in the Options dialog on the View tab. - *

    - * - * @param value whether to display or hide all zero values on the worksheet - */ - @Override - public void setDisplayZeros(boolean value) { - _sheet.getWindowTwo().setDisplayZeros(value); - } - - /** - * fit to page option is on - * - * @return fit or not - */ - @Override - public boolean getFitToPage() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getFitToPage(); - } - - /** - * get if row summaries appear below detail in the outline - * - * @return below or not - */ - @Override - public boolean getRowSumsBelow() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getRowSumsBelow(); - } - - /** - * get if col summaries appear right of the detail in the outline - * - * @return right or not - */ - @Override - public boolean getRowSumsRight() { - return ((WSBoolRecord) _sheet.findFirstRecordBySid(WSBoolRecord.sid)) - .getRowSumsRight(); - } - - /** - * Returns whether gridlines are printed. - * - * @return Gridlines are printed - */ - @Override - public boolean isPrintGridlines() { - return getSheet().getPrintGridlines().getPrintGridlines(); - } - - /** - * Turns on or off the printing of gridlines. - * - * @param show boolean to turn on or off the printing of - * gridlines - */ - @Override - public void setPrintGridlines(boolean show) { - getSheet().getPrintGridlines().setPrintGridlines(show); - } - - /** - * Returns whether row and column headings are printed. - * - * @return row and column headings are printed - */ - @Override - public boolean isPrintRowAndColumnHeadings() { - return getSheet().getPrintHeaders().getPrintHeaders(); - } - - /** - * Turns on or off the printing of row and column headings. - * - * @param show boolean to turn on or off the printing of - * row and column headings - */ - @Override - public void setPrintRowAndColumnHeadings(boolean show) { - getSheet().getPrintHeaders().setPrintHeaders(show); - } - - /** - * Gets the print setup object. - * - * @return The user model for the print setup object. - */ - @Override - public HSSFPrintSetup getPrintSetup() { - return new HSSFPrintSetup(_sheet.getPageSettings().getPrintSetup()); - } - - @Override - public HSSFHeader getHeader() { - return new HSSFHeader(_sheet.getPageSettings()); - } - - @Override - public HSSFFooter getFooter() { - return new HSSFFooter(_sheet.getPageSettings()); - } - - /** - * Note - this is not the same as whether the sheet is focused (isActive) - * - * @return true if this sheet is currently selected - */ - @Override - public boolean isSelected() { - return getSheet().getWindowTwo().getSelected(); - } - - /** - * Sets whether sheet is selected. - * - * @param sel Whether to select the sheet or deselect the sheet. - */ - @Override - public void setSelected(boolean sel) { - getSheet().getWindowTwo().setSelected(sel); - } - - /** - * @return true if this sheet is currently focused - */ - public boolean isActive() { - return getSheet().getWindowTwo().isActive(); - } - - /** - * Sets whether sheet is selected. - * - * @param sel Whether to select the sheet or deselect the sheet. - */ - public void setActive(boolean sel) { - getSheet().getWindowTwo().setActive(sel); - } - - /** - * Gets the size of the margin in inches. - * - * @param margin which margin to get - * @return the size of the margin - */ - @Override - public double getMargin(short margin) { - switch (margin) { - case FooterMargin: - return _sheet.getPageSettings().getPrintSetup().getFooterMargin(); - case HeaderMargin: - return _sheet.getPageSettings().getPrintSetup().getHeaderMargin(); - default: - return _sheet.getPageSettings().getMargin(margin); - } - } - - /** - * Sets the size of the margin in inches. - * - * @param margin which margin to get - * @param size the size of the margin - */ - @Override - public void setMargin(short margin, double size) { - switch (margin) { - case FooterMargin: - _sheet.getPageSettings().getPrintSetup().setFooterMargin(size); - break; - case HeaderMargin: - _sheet.getPageSettings().getPrintSetup().setHeaderMargin(size); - break; - default: - _sheet.getPageSettings().setMargin(margin, size); - } - } - - private WorksheetProtectionBlock getProtectionBlock() { - return _sheet.getProtectionBlock(); - } - - /** - * Answer whether protection is enabled or disabled - * - * @return true => protection enabled; false => protection disabled - */ - @Override - public boolean getProtect() { - return getProtectionBlock().isSheetProtected(); - } - - /** - * @return hashed password - */ - public short getPassword() { - return (short) getProtectionBlock().getPasswordHash(); - } - - /** - * Answer whether object protection is enabled or disabled - * - * @return true => protection enabled; false => protection disabled - */ - public boolean getObjectProtect() { - return getProtectionBlock().isObjectProtected(); - } - - /** - * Answer whether scenario protection is enabled or disabled - * - * @return true => protection enabled; false => protection disabled - */ - @Override - public boolean getScenarioProtect() { - return getProtectionBlock().isScenarioProtected(); - } - - /** - * Sets the protection enabled as well as the password - * - * @param password to set for protection. Pass null to remove protection - */ - @Override - public void protectSheet(String password) { - getProtectionBlock().protectSheet(password, true, true); //protect objs&scenarios(normal) - } - - /** - * Sets the zoom magnification for the sheet. The zoom is expressed as a - * fraction. For example to express a zoom of 75% use 3 for the numerator - * and 4 for the denominator. - * - * @param numerator The numerator for the zoom magnification. - * @param denominator The denominator for the zoom magnification. - * @see #setZoom(int) - */ - public void setZoom(int numerator, int denominator) { - if (numerator < 1 || numerator > 65535) - throw new IllegalArgumentException("Numerator must be greater than 0 and less than 65536"); - if (denominator < 1 || denominator > 65535) - throw new IllegalArgumentException("Denominator must be greater than 0 and less than 65536"); - - SCLRecord sclRecord = new SCLRecord(); - sclRecord.setNumerator((short) numerator); - sclRecord.setDenominator((short) denominator); - getSheet().setSCLRecord(sclRecord); - } - - /** - * Window zoom magnification for current view representing percent values. - * Valid values range from 10 to 400. Horizontal & Vertical scale together. - * - * For example: - *
    -     * 10 - 10%
    -     * 20 - 20%
    -     * ...
    -     * 100 - 100%
    -     * ...
    -     * 400 - 400%
    -     * 
    - * - * @param scale window zoom magnification - * @throws IllegalArgumentException if scale is invalid - */ - @Override - public void setZoom(int scale) { - setZoom(scale, 100); - } - - /** - * The top row in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return short indicating the rownum (0 based) of the top row - */ - @Override - public short getTopRow() { - return _sheet.getTopRow(); - } - - /** - * The left col in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return short indicating the rownum (0 based) of the top row - */ - @Override - public short getLeftCol() { - return _sheet.getLeftCol(); - } - - /** - * Sets desktop window pane display area, when the - * file is first opened in a viewer. - * - * @param toprow the top row to show in desktop window pane - * @param leftcol the left column to show in desktop window pane - */ - @Override - public void showInPane(int toprow, int leftcol) { - int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex(); - if (toprow > maxrow) throw new IllegalArgumentException("Maximum row number is " + maxrow); - - showInPane((short)toprow, (short)leftcol); - } - /** - * Sets desktop window pane display area, when the - * file is first opened in a viewer. - * - * @param toprow the top row to show in desktop window pane - * @param leftcol the left column to show in desktop window pane - */ - private void showInPane(short toprow, short leftcol) { - _sheet.setTopRow(toprow); - _sheet.setLeftCol(leftcol); - } - - /** - * Shifts, grows, or shrinks the merged regions due to a row shift - * - * @param startRow the start-index of the rows to shift, zero-based - * @param endRow the end-index of the rows to shift, zero-based - * @param n how far to shift, negative to shift up - * @param isRow unused, kept for backwards compatibility - * @deprecated POI 3.15 beta 2. Use {@link HSSFRowShifter#shiftMergedRegions(int, int, int)}. - */ - protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) { - RowShifter rowShifter = new HSSFRowShifter(this); - rowShifter.shiftMergedRegions(startRow, endRow, n); - } - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around.

    - * - * Calls {@code shiftRows(startRow, endRow, n, false, false);}

    - * - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). - * - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - */ - @Override - public void shiftRows(int startRow, int endRow, int n) { - shiftRows(startRow, endRow, n, false, false); - } - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around

    - * - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). All merged regions that are - * completely overlaid by shifting will be deleted.

    - * - * TODO Might want to add bounds checking here - * - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - * @param copyRowHeight whether to copy the row height during the shift - * @param resetOriginalRowHeight whether to set the original row's height to the default - */ - @Override - public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) { - shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true); - } - - /** - * bound a row number between 0 and last row index (65535) - * - * @param row the row number - */ - private static int clip(int row) { - return Math.min( - Math.max(0, row), - SpreadsheetVersion.EXCEL97.getLastRowIndex()); - } - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around

    - * - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted).

    - * - * TODO Might want to add bounds checking here - * - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - * @param copyRowHeight whether to copy the row height during the shift - * @param resetOriginalRowHeight whether to set the original row's height to the default - * @param moveComments whether to move comments at the same time as the cells they are attached to - */ - public void shiftRows(int startRow, int endRow, int n, - boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments) { - int s, inc; - if (endRow < startRow) { - throw new IllegalArgumentException("startRow must be less than or equal to endRow. To shift rows up, use n<0."); - } - if (n < 0) { - s = startRow; - inc = 1; - } else if (n > 0) { - s = endRow; - inc = -1; - } else { - // Nothing to do - return; - } - - final RowShifter rowShifter = new HSSFRowShifter(this); - - // Move comments from the source row to the - // destination row. Note that comments can - // exist for cells which are null - // If the row shift would shift the comments off the sheet - // (above the first row or below the last row), this code will shift the - // comments to the first or last row, rather than moving them out of - // bounds or deleting them - if (moveComments) { - final HSSFPatriarch patriarch = createDrawingPatriarch(); - for (final HSSFShape shape : patriarch.getChildren()) { - if (!(shape instanceof HSSFComment)) { - continue; - } - final HSSFComment comment = (HSSFComment) shape; - final int r = comment.getRow(); - if (startRow <= r && r <= endRow) { - comment.setRow(clip(r + n)); - } - } - } - - // Shift Merged Regions - rowShifter.shiftMergedRegions(startRow, endRow, n); - - // Shift Row Breaks - _sheet.getPageSettings().shiftRowBreaks(startRow, endRow, n); - - // Delete overwritten hyperlinks - final int firstOverwrittenRow = startRow + n; - final int lastOverwrittenRow = endRow + n; - for (HSSFHyperlink link : getHyperlinkList()) { - // If hyperlink is fully contained in the rows that will be overwritten, delete the hyperlink - final int firstRow = link.getFirstRow(); - final int lastRow = link.getLastRow(); - if (firstOverwrittenRow <= firstRow && firstRow <= lastOverwrittenRow && - lastOverwrittenRow <= lastRow && lastRow <= lastOverwrittenRow) { - removeHyperlink(link); - } - } - - for (int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc) { - HSSFRow row = getRow(rowNum); - // notify all cells in this row that we are going to shift them, - // it can throw IllegalStateException if the operation is not allowed, for example, - // if the row contains cells included in a multi-cell array formula - if (row != null) notifyRowShifting(row); - - HSSFRow row2Replace = getRow(rowNum + n); - if (row2Replace == null) - row2Replace = createRow(rowNum + n); - - - // Remove all the old cells from the row we'll - // be writing to, before we start overwriting - // any cells. This avoids issues with cells - // changing type, and records not being correctly - // overwritten - row2Replace.removeAllCells(); - - // If this row doesn't exist, nothing needs to - // be done for the now empty destination row - if (row == null) continue; // Nothing to do for this row - - // Fix up row heights if required - if (copyRowHeight) { - row2Replace.setHeight(row.getHeight()); - } - if (resetOriginalRowHeight) { - row.setHeight((short) 0xff); - } - - // Copy each cell from the source row to - // the destination row - for (Iterator cells = row.cellIterator(); cells.hasNext(); ) { - HSSFCell cell = (HSSFCell) cells.next(); - HSSFHyperlink link = cell.getHyperlink(); - row.removeCell(cell); - CellValueRecordInterface cellRecord = cell.getCellValueRecord(); - cellRecord.setRow(rowNum + n); - row2Replace.createCellFromRecord(cellRecord); - _sheet.addValueRecord(rowNum + n, cellRecord); - - if (link != null) { - link.setFirstRow(link.getFirstRow() + n); - link.setLastRow(link.getLastRow() + n); - } - } - // Now zap all the cells in the source row - row.removeAllCells(); - } - - // Re-compute the first and last rows of the sheet as needed - if (n > 0) { - // Rows are moving down - if (startRow == _firstrow) { - // Need to walk forward to find the first non-blank row - _firstrow = Math.max(startRow + n, 0); - for (int i = startRow + 1; i < startRow + n; i++) { - if (getRow(i) != null) { - _firstrow = i; - break; - } - } - } - if (endRow + n > _lastrow) { - _lastrow = Math.min(endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex()); - } - } else { - // Rows are moving up - if (startRow + n < _firstrow) { - _firstrow = Math.max(startRow + n, 0); - } - if (endRow == _lastrow) { - // Need to walk backward to find the last non-blank row - _lastrow = Math.min(endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex()); - for (int i = endRow - 1; i > endRow + n; i++) { - if (getRow(i) != null) { - _lastrow = i; - break; - } - } - } - } - - // Update any formulas on this sheet that point to - // rows which have been moved - int sheetIndex = _workbook.getSheetIndex(this); - String sheetName = _workbook.getSheetName(sheetIndex); - short externSheetIndex = _book.checkExternSheet(sheetIndex); - FormulaShifter shifter = FormulaShifter.createForRowShift( - externSheetIndex, sheetName, startRow, endRow, n, SpreadsheetVersion.EXCEL97); - _sheet.updateFormulasAfterCellShift(shifter, externSheetIndex); - - int nSheets = _workbook.getNumberOfSheets(); - for (int i = 0; i < nSheets; i++) { - InternalSheet otherSheet = _workbook.getSheetAt(i).getSheet(); - if (otherSheet == this._sheet) { - continue; - } - short otherExtSheetIx = _book.checkExternSheet(i); - otherSheet.updateFormulasAfterCellShift(shifter, otherExtSheetIx); - } - _workbook.getWorkbook().updateNamesAfterCellShift(shifter); - } - - protected void insertChartRecords(List records) { - int window2Loc = _sheet.findFirstRecordLocBySid(WindowTwoRecord.sid); - _sheet.getRecords().addAll(window2Loc, records); - } - - private void notifyRowShifting(HSSFRow row) { - String msg = "Row[rownum=" + row.getRowNum() + "] contains cell(s) included in a multi-cell array formula. " + - "You cannot change part of an array."; - for (Cell cell : row) { - HSSFCell hcell = (HSSFCell) cell; - if (hcell.isPartOfArrayFormulaGroup()) { - hcell.notifyArrayFormulaChanging(msg); - } - } - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.

    - * - * If both colSplit and rowSplit are zero then the existing freeze pane is removed - * - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - * @param leftmostColumn Left column visible in right pane. - * @param topRow Top row visible in bottom pane - */ - @Override - public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) { - validateColumn(colSplit); - validateRow(rowSplit); - if (leftmostColumn < colSplit) - throw new IllegalArgumentException("leftmostColumn parameter must not be less than colSplit parameter"); - if (topRow < rowSplit) - throw new IllegalArgumentException("topRow parameter must not be less than leftmostColumn parameter"); - getSheet().createFreezePane(colSplit, rowSplit, topRow, leftmostColumn); - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.

    - * - * If both colSplit and rowSplit are zero then the existing freeze pane is removed - * - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - */ - @Override - public void createFreezePane(int colSplit, int rowSplit) { - createFreezePane(colSplit, rowSplit, colSplit, rowSplit); - } - - /** - * Creates a split pane. Any existing freezepane or split pane is overwritten. - * - * @param xSplitPos Horizonatal position of split (in 1/20th of a point). - * @param ySplitPos Vertical position of split (in 1/20th of a point). - * @param topRow Top row visible in bottom pane - * @param leftmostColumn Left column visible in right pane. - * @param activePane Active pane. One of: PANE_LOWER_RIGHT, - * PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT - * @see #PANE_LOWER_LEFT - * @see #PANE_LOWER_RIGHT - * @see #PANE_UPPER_LEFT - * @see #PANE_UPPER_RIGHT - */ - @Override - public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) { - getSheet().createSplitPane(xSplitPos, ySplitPos, topRow, leftmostColumn, activePane); - } - - /** - * Returns the information regarding the currently configured pane (split or freeze). - * - * @return null if no pane configured, or the pane information. - */ - @Override - public PaneInformation getPaneInformation() { - return getSheet().getPaneInformation(); - } - - /** - * Sets whether the gridlines are shown in a viewer. - * - * @param show whether to show gridlines or not - */ - @Override - public void setDisplayGridlines(boolean show) { - _sheet.setDisplayGridlines(show); - } - - /** - * Returns if gridlines are displayed. - * - * @return whether gridlines are displayed - */ - @Override - public boolean isDisplayGridlines() { - return _sheet.isDisplayGridlines(); - } - - /** - * Sets whether the formulas are shown in a viewer. - * - * @param show whether to show formulas or not - */ - @Override - public void setDisplayFormulas(boolean show) { - _sheet.setDisplayFormulas(show); - } - - /** - * Returns if formulas are displayed. - * - * @return whether formulas are displayed - */ - @Override - public boolean isDisplayFormulas() { - return _sheet.isDisplayFormulas(); - } - - /** - * Sets whether the RowColHeadings are shown in a viewer. - * - * @param show whether to show RowColHeadings or not - */ - @Override - public void setDisplayRowColHeadings(boolean show) { - _sheet.setDisplayRowColHeadings(show); - } - - /** - * Returns if RowColHeadings are displayed. - * - * @return whether RowColHeadings are displayed - */ - @Override - public boolean isDisplayRowColHeadings() { - return _sheet.isDisplayRowColHeadings(); - } - - /** - * Sets a page break at the indicated row - * Breaks occur above the specified row and left of the specified column inclusive.

    - * - * For example, sheet.setColumnBreak(2); breaks the sheet into two parts - * with columns A,B,C in the first and D,E,... in the second. Simuilar, sheet.setRowBreak(2); - * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part - * and rows starting with rownum=4 in the second. - * - * @param row the row to break, inclusive - */ - @Override - public void setRowBreak(int row) { - validateRow(row); - _sheet.getPageSettings().setRowBreak(row, (short) 0, (short) 255); - } - - /** - * @return true if there is a page break at the indicated row - */ - @Override - public boolean isRowBroken(int row) { - return _sheet.getPageSettings().isRowBroken(row); - } - - /** - * Removes the page break at the indicated row - */ - @Override - public void removeRowBreak(int row) { - _sheet.getPageSettings().removeRowBreak(row); - } - - /** - * @return row indexes of all the horizontal page breaks, never null - */ - @Override - public int[] getRowBreaks() { - //we can probably cache this information, but this should be a sparsely used function - return _sheet.getPageSettings().getRowBreaks(); - } - - /** - * @return column indexes of all the vertical page breaks, never null - */ - @Override - public int[] getColumnBreaks() { - //we can probably cache this information, but this should be a sparsely used function - return _sheet.getPageSettings().getColumnBreaks(); - } - - - /** - * Sets a page break at the indicated column. - * Breaks occur above the specified row and left of the specified column inclusive.

    - * - * For example, sheet.setColumnBreak(2); breaks the sheet into two parts - * with columns A,B,C in the first and D,E,... in the second. Simuilar, {@code sheet.setRowBreak(2);} - * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part - * and rows starting with rownum=4 in the second. - * - * @param column the column to break, inclusive - */ - @Override - public void setColumnBreak(int column) { - validateColumn((short) column); - _sheet.getPageSettings().setColumnBreak((short) column, (short) 0, (short) SpreadsheetVersion.EXCEL97.getLastRowIndex()); - } - - /** - * Determines if there is a page break at the indicated column - * - * @param column FIXME: Document this! - * @return FIXME: Document this! - */ - @Override - public boolean isColumnBroken(int column) { - return _sheet.getPageSettings().isColumnBroken(column); - } - - /** - * Removes a page break at the indicated column - * - * @param column The index of the column for which to remove a page-break, zero-based - */ - @Override - public void removeColumnBreak(int column) { - _sheet.getPageSettings().removeColumnBreak(column); - } - - /** - * Runs a bounds check for row numbers - * - * @param row the index of the row to validate, zero-based - */ - protected void validateRow(int row) { - int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex(); - if (row > maxrow) throw new IllegalArgumentException("Maximum row number is " + maxrow); - if (row < 0) throw new IllegalArgumentException("Minumum row number is 0"); - } - - /** - * Runs a bounds check for column numbers - * - * @param column the index of the column to validate, zero-based - */ - protected void validateColumn(int column) { - int maxcol = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); - if (column > maxcol) throw new IllegalArgumentException("Maximum column number is " + maxcol); - if (column < 0) throw new IllegalArgumentException("Minimum column number is 0"); - } - - /** - * Aggregates the drawing records and dumps the escher record hierarchy - * to the standard output. - */ - public void dumpDrawingRecords(boolean fat, PrintWriter pw) { - _sheet.aggregateDrawingRecords(_book.getDrawingManager(), false); - - EscherAggregate r = (EscherAggregate) getSheet().findFirstRecordBySid(EscherAggregate.sid); - List escherRecords = r.getEscherRecords(); - for (EscherRecord escherRecord : escherRecords) { - if (fat) { - pw.println(escherRecord.toString()); - } else { - escherRecord.display(pw, 0); - } - } - pw.flush(); - } - - /** - * Returns the agregate escher records for this sheet, - * it there is one. - */ - public EscherAggregate getDrawingEscherAggregate() { - _book.findDrawingGroup(); - - // If there's now no drawing manager, then there's - // no drawing escher records on the workbook - if (_book.getDrawingManager() == null) { - return null; - } - - int found = _sheet.aggregateDrawingRecords( - _book.getDrawingManager(), false - ); - if (found == -1) { - // Workbook has drawing stuff, but this sheet doesn't - return null; - } - - // Grab our aggregate record, and wire it up - return (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid); - } - - /** - * This will hold any graphics or charts for the sheet. - * - * @return the top-level drawing patriarch, if there is one, else returns null - */ - @Override - public HSSFPatriarch getDrawingPatriarch() { - _patriarch = getPatriarch(false); - return _patriarch; - } - - /** - * Creates the top-level drawing patriarch. - *

    This may then be used to add graphics or charts.

    - *

    Note that this will normally have the effect of removing - * any existing drawings on this sheet.

    - * - * @return The new patriarch. - */ - @Override - public HSSFPatriarch createDrawingPatriarch() { - _patriarch = getPatriarch(true); - return _patriarch; - } - - private HSSFPatriarch getPatriarch(boolean createIfMissing) { - if (_patriarch != null) { - return _patriarch; - } - DrawingManager2 dm = _book.findDrawingGroup(); - if (null == dm) { - if (!createIfMissing) { - return null; - } else { - _book.createDrawingGroup(); - dm = _book.getDrawingManager(); - } - } - EscherAggregate agg = (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid); - if (null == agg) { - int pos = _sheet.aggregateDrawingRecords(dm, false); - if (-1 == pos) { - if (createIfMissing) { - pos = _sheet.aggregateDrawingRecords(dm, true); - agg = (EscherAggregate) _sheet.getRecords().get(pos); - HSSFPatriarch patriarch = new HSSFPatriarch(this, agg); - patriarch.afterCreate(); - return patriarch; - } else { - return null; - } - } - agg = (EscherAggregate) _sheet.getRecords().get(pos); - } - return new HSSFPatriarch(this, agg); - } - - /** - * Expands or collapses a column group. - * - * @param columnNumber One of the columns in the group. - * @param collapsed true = collapse group, false = expand group. - */ - @Override - public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) { - _sheet.setColumnGroupCollapsed(columnNumber, collapsed); - } - - /** - * Create an outline for the provided column range. - * - * @param fromColumn beginning of the column range. - * @param toColumn end of the column range. - */ - @Override - public void groupColumn(int fromColumn, int toColumn) { - _sheet.groupColumnRange(fromColumn, toColumn, true); - } - - @Override - public void ungroupColumn(int fromColumn, int toColumn) { - _sheet.groupColumnRange(fromColumn, toColumn, false); - } - - /** - * Tie a range of cell together so that they can be collapsed or expanded - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - @Override - public void groupRow(int fromRow, int toRow) { - _sheet.groupRowRange(fromRow, toRow, true); - } - - @Override - public void ungroupRow(int fromRow, int toRow) { - _sheet.groupRowRange(fromRow, toRow, false); - } - - @Override - public void setRowGroupCollapsed(int rowIndex, boolean collapse) { - if (collapse) { - _sheet.getRowsAggregate().collapseRow(rowIndex); - } else { - _sheet.getRowsAggregate().expandRow(rowIndex); - } - } - - /** - * Sets the default column style for a given column. POI will only apply this style to new cells added to the sheet. - * - * @param column the column index - * @param style the style to set - */ - @Override - public void setDefaultColumnStyle(int column, CellStyle style) { - _sheet.setDefaultColumnStyle(column, ((HSSFCellStyle) style).getIndex()); - } - - /** - * Adjusts the column width to fit the contents.

    - * - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - * - * @param column the column index - */ - @Override - public void autoSizeColumn(int column) { - autoSizeColumn(column, false); - } - - /** - * Adjusts the column width to fit the contents.

    - * - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing.

    - * - * You can specify whether the content of merged cells should be considered or ignored. - * Default is to ignore merged cells. - * - * @param column the column index - * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column - */ - @Override - public void autoSizeColumn(int column, boolean useMergedCells) { - double width = SheetUtil.getColumnWidth(this, column, useMergedCells); - - if (width != -1) { - width *= 256; - int maxColumnWidth = 255 * 256; // The maximum column width for an individual cell is 255 characters - if (width > maxColumnWidth) { - width = maxColumnWidth; - } - setColumnWidth(column, (int) (width)); - } - - } - - /** - * Returns cell comment for the specified row and column - * - * @return cell comment or null if not found - * @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellAddress)} instead. - */ - @Override - public HSSFComment getCellComment(int row, int column) { - return findCellComment(row, column); - } - - /** - * Returns cell comment for the specified row and column - * - * @return cell comment or null if not found - */ - @Override - public HSSFComment getCellComment(CellAddress ref) { - return findCellComment(ref.getRow(), ref.getColumn()); - } - - /** - * Get a Hyperlink in this sheet anchored at row, column - * - * @param row The index of the row of the hyperlink, zero-based - * @param column the index of the column of the hyperlink, zero-based - * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null - */ - @Override - public HSSFHyperlink getHyperlink(int row, int column) { - for (RecordBase rec : _sheet.getRecords()) { - if (rec instanceof HyperlinkRecord) { - HyperlinkRecord link = (HyperlinkRecord) rec; - if (link.getFirstColumn() == column && link.getFirstRow() == row) { - return new HSSFHyperlink(link); - } - } - } - return null; - } - - /** - * Get a Hyperlink in this sheet located in a cell specified by {code addr} - * - * @param addr The address of the cell containing the hyperlink - * @return hyperlink if there is a hyperlink anchored at {@code addr}; otherwise returns {@code null} - * @since POI 3.15 beta 3 - */ - @Override - public HSSFHyperlink getHyperlink(CellAddress addr) { - return getHyperlink(addr.getRow(), addr.getColumn()); - } - - /** - * Get a list of Hyperlinks in this sheet - * - * @return Hyperlinks for the sheet - */ - @Override - public List getHyperlinkList() { - final List hyperlinkList = new ArrayList(); - for (RecordBase rec : _sheet.getRecords()) { - if (rec instanceof HyperlinkRecord) { - HyperlinkRecord link = (HyperlinkRecord) rec; - hyperlinkList.add(new HSSFHyperlink(link)); - } - } - return hyperlinkList; - } - - /** - * Remove the underlying HyperlinkRecord from this sheet. - * If multiple HSSFHyperlinks refer to the same HyperlinkRecord, all HSSFHyperlinks will be removed. - * - * @param link the HSSFHyperlink wrapper around the HyperlinkRecord to remove - */ - protected void removeHyperlink(HSSFHyperlink link) { - removeHyperlink(link.record); - } - - /** - * Remove the underlying HyperlinkRecord from this sheet - * - * @param link the underlying HyperlinkRecord to remove from this sheet - */ - protected void removeHyperlink(HyperlinkRecord link) { - for (Iterator it = _sheet.getRecords().iterator(); it.hasNext();) { - RecordBase rec = it.next(); - if (rec instanceof HyperlinkRecord) { - HyperlinkRecord recLink = (HyperlinkRecord) rec; - if (link == recLink) { - it.remove(); - // if multiple HSSFHyperlinks refer to the same record - return; - } - } - } - } - - @Override - public HSSFSheetConditionalFormatting getSheetConditionalFormatting() { - return new HSSFSheetConditionalFormatting(this); - } - - /** - * Returns the name of this sheet - * - * @return the name of this sheet - */ - @SuppressWarnings("resource") - @Override - public String getSheetName() { - HSSFWorkbook wb = getWorkbook(); - int idx = wb.getSheetIndex(this); - return wb.getSheetName(idx); - } - - /** - * Also creates cells if they don't exist - */ - private CellRange getCellRange(CellRangeAddress range) { - int firstRow = range.getFirstRow(); - int firstColumn = range.getFirstColumn(); - int lastRow = range.getLastRow(); - int lastColumn = range.getLastColumn(); - int height = lastRow - firstRow + 1; - int width = lastColumn - firstColumn + 1; - List temp = new ArrayList(height * width); - for (int rowIn = firstRow; rowIn <= lastRow; rowIn++) { - for (int colIn = firstColumn; colIn <= lastColumn; colIn++) { - HSSFRow row = getRow(rowIn); - if (row == null) { - row = createRow(rowIn); - } - HSSFCell cell = row.getCell(colIn); - if (cell == null) { - cell = row.createCell(colIn); - } - temp.add(cell); - } - } - return SSCellRange.create(firstRow, firstColumn, height, width, temp, HSSFCell.class); - } - - @Override - public CellRange setArrayFormula(String formula, CellRangeAddress range) { - // make sure the formula parses OK first - int sheetIndex = _workbook.getSheetIndex(this); - Ptg[] ptgs = HSSFFormulaParser.parse(formula, _workbook, FormulaType.ARRAY, sheetIndex); - CellRange cells = getCellRange(range); - - for (HSSFCell c : cells) { - c.setCellArrayFormula(range); - } - HSSFCell mainArrayFormulaCell = cells.getTopLeftCell(); - FormulaRecordAggregate agg = (FormulaRecordAggregate) mainArrayFormulaCell.getCellValueRecord(); - agg.setArrayFormula(range, ptgs); - return cells; - } - - @Override - public CellRange removeArrayFormula(Cell cell) { - if (cell.getSheet() != this) { - throw new IllegalArgumentException("Specified cell does not belong to this sheet."); - } - CellValueRecordInterface rec = ((HSSFCell) cell).getCellValueRecord(); - if (!(rec instanceof FormulaRecordAggregate)) { - String ref = new CellReference(cell).formatAsString(); - throw new IllegalArgumentException("Cell " + ref + " is not part of an array formula."); - } - FormulaRecordAggregate fra = (FormulaRecordAggregate) rec; - CellRangeAddress range = fra.removeArrayFormula(cell.getRowIndex(), cell.getColumnIndex()); - - CellRange result = getCellRange(range); - // clear all cells in the range - for (Cell c : result) { - c.setCellType(CellType.BLANK); - } - return result; - } - - @Override - public DataValidationHelper getDataValidationHelper() { - return new HSSFDataValidationHelper(this); - } - - @Override - public HSSFAutoFilter setAutoFilter(CellRangeAddress range) { - InternalWorkbook workbook = _workbook.getWorkbook(); - int sheetIndex = _workbook.getSheetIndex(this); - - NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_FILTER_DB, sheetIndex + 1); - - if (name == null) { - name = workbook.createBuiltInName(NameRecord.BUILTIN_FILTER_DB, sheetIndex + 1); - } - - int firstRow = range.getFirstRow(); - - // if row was not given when constructing the range... - if(firstRow == -1) { - firstRow = 0; - } - - // The built-in name must consist of a single Area3d Ptg. - Area3DPtg ptg = new Area3DPtg(firstRow, range.getLastRow(), - range.getFirstColumn(), range.getLastColumn(), - false, false, false, false, sheetIndex); - name.setNameDefinition(new Ptg[]{ptg}); - - AutoFilterInfoRecord r = new AutoFilterInfoRecord(); - // the number of columns that have AutoFilter enabled. - int numcols = 1 + range.getLastColumn() - range.getFirstColumn(); - r.setNumEntries((short) numcols); - int idx = _sheet.findFirstRecordLocBySid(DimensionsRecord.sid); - _sheet.getRecords().add(idx, r); - - //create a combobox control for each column - HSSFPatriarch p = createDrawingPatriarch(); - final int firstColumn = range.getFirstColumn(); - final int lastColumn = range.getLastColumn(); - for (int col = firstColumn; col <= lastColumn; col++) { - p.createComboBox(new HSSFClientAnchor(0, 0, 0, 0, - (short) col, firstRow, (short) (col + 1), firstRow + 1)); - } - - return new HSSFAutoFilter(this); - } - - protected HSSFComment findCellComment(int row, int column) { - HSSFPatriarch patriarch = getDrawingPatriarch(); - if (null == patriarch) { - patriarch = createDrawingPatriarch(); - } - return lookForComment(patriarch, row, column); - } - - private HSSFComment lookForComment(HSSFShapeContainer container, int row, int column) { - for (Object object : container.getChildren()) { - HSSFShape shape = (HSSFShape) object; - if (shape instanceof HSSFShapeGroup) { - HSSFShape res = lookForComment((HSSFShapeContainer) shape, row, column); - if (null != res) { - return (HSSFComment) res; - } - continue; - } - if (shape instanceof HSSFComment) { - HSSFComment comment = (HSSFComment) shape; - if (comment.hasPosition() && comment.getColumn() == column && comment.getRow() == row) { - return comment; - } - } - } - return null; - } - - /** - * Returns all cell comments on this sheet. - * @return A map of each Comment in the sheet, keyed on the cell address where - * the comment is located. - */ - @Override - public Map getCellComments() { - HSSFPatriarch patriarch = getDrawingPatriarch(); - if (null == patriarch) { - patriarch = createDrawingPatriarch(); - } - - Map locations = new TreeMap(); - findCellCommentLocations(patriarch, locations); - return locations; - } - /** - * Finds all cell comments in this sheet and adds them to the specified locations map - * - * @param container a container that may contain HSSFComments - * @param locations the map to store the HSSFComments in - */ - private void findCellCommentLocations(HSSFShapeContainer container, Map locations) { - for (Object object : container.getChildren()) { - HSSFShape shape = (HSSFShape) object; - if (shape instanceof HSSFShapeGroup) { - findCellCommentLocations((HSSFShapeGroup) shape, locations); - continue; - } - if (shape instanceof HSSFComment) { - HSSFComment comment = (HSSFComment) shape; - if (comment.hasPosition()) { - locations.put(new CellAddress(comment.getRow(), comment.getColumn()), comment); - } - } - } - } - - @Override - public CellRangeAddress getRepeatingRows() { - return getRepeatingRowsOrColums(true); - } - - @Override - public CellRangeAddress getRepeatingColumns() { - return getRepeatingRowsOrColums(false); - } - - @Override - public void setRepeatingRows(CellRangeAddress rowRangeRef) { - CellRangeAddress columnRangeRef = getRepeatingColumns(); - setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef); - } - - @Override - public void setRepeatingColumns(CellRangeAddress columnRangeRef) { - CellRangeAddress rowRangeRef = getRepeatingRows(); - setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef); - } - - - private void setRepeatingRowsAndColumns( - CellRangeAddress rowDef, CellRangeAddress colDef) { - int sheetIndex = _workbook.getSheetIndex(this); - int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex(); - int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); - - int col1 = -1; - int col2 = -1; - int row1 = -1; - int row2 = -1; - - if (rowDef != null) { - row1 = rowDef.getFirstRow(); - row2 = rowDef.getLastRow(); - if ((row1 == -1 && row2 != -1) || (row1 > row2) - || (row1 < 0 || row1 > maxRowIndex) - || (row2 < 0 || row2 > maxRowIndex)) { - throw new IllegalArgumentException("Invalid row range specification"); - } - } - if (colDef != null) { - col1 = colDef.getFirstColumn(); - col2 = colDef.getLastColumn(); - if ((col1 == -1 && col2 != -1) || (col1 > col2) - || (col1 < 0 || col1 > maxColIndex) - || (col2 < 0 || col2 > maxColIndex)) { - throw new IllegalArgumentException("Invalid column range specification"); - } - } - - short externSheetIndex = - _workbook.getWorkbook().checkExternSheet(sheetIndex); - - boolean setBoth = rowDef != null && colDef != null; - boolean removeAll = rowDef == null && colDef == null; - - HSSFName name = _workbook.getBuiltInName( - NameRecord.BUILTIN_PRINT_TITLE, sheetIndex); - if (removeAll) { - if (name != null) { - _workbook.removeName(name); - } - return; - } - if (name == null) { - name = _workbook.createBuiltInName( - NameRecord.BUILTIN_PRINT_TITLE, sheetIndex); - } - - List ptgList = new ArrayList(); - if (setBoth) { - final int exprsSize = 2 * 11 + 1; // 2 * Area3DPtg.SIZE + UnionPtg.SIZE - ptgList.add(new MemFuncPtg(exprsSize)); - } - if (colDef != null) { - Area3DPtg colArea = new Area3DPtg(0, maxRowIndex, col1, col2, - false, false, false, false, externSheetIndex); - ptgList.add(colArea); - } - if (rowDef != null) { - Area3DPtg rowArea = new Area3DPtg(row1, row2, 0, maxColIndex, - false, false, false, false, externSheetIndex); - ptgList.add(rowArea); - } - if (setBoth) { - ptgList.add(UnionPtg.instance); - } - - Ptg[] ptgs = new Ptg[ptgList.size()]; - ptgList.toArray(ptgs); - name.setNameDefinition(ptgs); - - HSSFPrintSetup printSetup = getPrintSetup(); - printSetup.setValidSettings(false); - setActive(true); - } - - - private CellRangeAddress getRepeatingRowsOrColums(boolean rows) { - NameRecord rec = getBuiltinNameRecord(NameRecord.BUILTIN_PRINT_TITLE); - if (rec == null) { - return null; - } - - Ptg[] nameDefinition = rec.getNameDefinition(); - if (nameDefinition == null) { - return null; - } - - int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex(); - int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); - - for (Ptg ptg : nameDefinition) { - - if (ptg instanceof Area3DPtg) { - Area3DPtg areaPtg = (Area3DPtg) ptg; - - if (areaPtg.getFirstColumn() == 0 - && areaPtg.getLastColumn() == maxColIndex) { - if (rows) { - return new CellRangeAddress( - areaPtg.getFirstRow(), areaPtg.getLastRow(), -1, -1); - } - } else if (areaPtg.getFirstRow() == 0 - && areaPtg.getLastRow() == maxRowIndex) { - if (!rows) { - return new CellRangeAddress(-1, -1, - areaPtg.getFirstColumn(), areaPtg.getLastColumn()); - } - } - - } - - } - - return null; - } - - - private NameRecord getBuiltinNameRecord(byte builtinCode) { - int sheetIndex = _workbook.getSheetIndex(this); - int recIndex = - _workbook.findExistingBuiltinNameRecordIdx(sheetIndex, builtinCode); - if (recIndex == -1) { - return null; - } - return _workbook.getNameRecord(recIndex); - } - - /** - * Returns the column outline level. Increased as you - * put it into more groups (outlines), reduced as - * you take it out of them. - */ - @Override - public int getColumnOutlineLevel(int columnIndex) { - return _sheet.getColumnOutlineLevel(columnIndex); - } - - /** - * {@inheritDoc} - */ - @Override - public CellAddress getActiveCell() { - int row = _sheet.getActiveCellRow(); - int col = _sheet.getActiveCellCol(); - return new CellAddress(row, col); - } - - /** - * {@inheritDoc} - */ - @Override - public void setActiveCell(CellAddress address) { - int row = address.getRow(); - short col = (short) address.getColumn(); - _sheet.setActiveCellRow(row); - _sheet.setActiveCellCol(col); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java deleted file mode 100644 index d3aba5ba2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java +++ /dev/null @@ -1,264 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.hssf.record.CFRule12Record; -import org.apache.poi.hssf.record.CFRuleBase; -import org.apache.poi.hssf.record.CFRuleRecord; -import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.ConditionalFormatting; -import org.apache.poi.ss.usermodel.ConditionalFormattingRule; -import org.apache.poi.ss.usermodel.ExtendedColor; -import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet; -import org.apache.poi.ss.usermodel.SheetConditionalFormatting; -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * The 'Conditional Formatting' facet of HSSFSheet - */ -public final class HSSFSheetConditionalFormatting implements SheetConditionalFormatting { - private final HSSFSheet _sheet; - private final ConditionalFormattingTable _conditionalFormattingTable; - - /* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) { - _sheet = sheet; - _conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable(); - } - - /** - * A factory method allowing to create a conditional formatting rule - * with a cell comparison operator

    - * TODO - formulas containing cell references are currently not parsed properly - * - * @param comparisonOperation - a constant value from - * {@link org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator}:

    - *

      - *
    • BETWEEN
    • - *
    • NOT_BETWEEN
    • - *
    • EQUAL
    • - *
    • NOT_EQUAL
    • - *
    • GT
    • - *
    • LT
    • - *
    • GE
    • - *
    • LE
    • - *
    - *

    - * @param formula1 - formula for the valued, compared with the cell - * @param formula2 - second formula (only used with - * {@link org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator#BETWEEN}) and - * {@link org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator#NOT_BETWEEN} operations) - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula1, - String formula2) { - CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2); - return new HSSFConditionalFormattingRule(_sheet, rr); - } - - public HSSFConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula1) { - CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, null); - return new HSSFConditionalFormattingRule(_sheet, rr); - } - - /** - * A factory method allowing to create a conditional formatting rule with a formula.
    - * - * The formatting rules are applied by Excel when the value of the formula not equal to 0.

    - * TODO - formulas containing cell references are currently not parsed properly - * @param formula - formula for the valued, compared with the cell - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) { - CFRuleRecord rr = CFRuleRecord.create(_sheet, formula); - return new HSSFConditionalFormattingRule(_sheet, rr); - } - - /** - * A factory method allowing the creation of conditional formatting - * rules using an Icon Set / Multi-State formatting. - * The thresholds for it will be created, but will be empty - * and require configuring with - * {@link HSSFConditionalFormattingRule#getMultiStateFormatting()} - * then - * {@link HSSFIconMultiStateFormatting#getThresholds()} - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule( - IconSet iconSet) { - CFRule12Record rr = CFRule12Record.create(_sheet, iconSet); - return new HSSFConditionalFormattingRule(_sheet, rr); - } - - /** - * Create a Databar conditional formatting rule. - *

    The thresholds and colour for it will be created, but will be - * empty and require configuring with - * {@link HSSFConditionalFormattingRule#getDataBarFormatting()} - * then - * {@link HSSFDataBarFormatting#getMinThreshold()} - * and - * {@link HSSFDataBarFormatting#getMaxThreshold()} - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule(HSSFExtendedColor color) { - CFRule12Record rr = CFRule12Record.create(_sheet, color.getExtendedColor()); - return new HSSFConditionalFormattingRule(_sheet, rr); - } - public HSSFConditionalFormattingRule createConditionalFormattingRule(ExtendedColor color) { - return createConditionalFormattingRule((HSSFExtendedColor)color); - } - - /** - * Create a Color Scale / Color Gradient conditional formatting rule. - *

    The thresholds and colours for it will be created, but will be - * empty and require configuring with - * {@link HSSFConditionalFormattingRule#getColorScaleFormatting()} - * then - * {@link HSSFColorScaleFormatting#getThresholds()} - * and - * {@link HSSFColorScaleFormatting#getColors()} - */ - public HSSFConditionalFormattingRule createConditionalFormattingColorScaleRule() { - CFRule12Record rr = CFRule12Record.createColorScale(_sheet); - return new HSSFConditionalFormattingRule(_sheet, rr); - } - - /** - * Adds a copy of HSSFConditionalFormatting object to the sheet - *

    This method could be used to copy HSSFConditionalFormatting object - * from one sheet to another. For example: - *

    -     * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
    -     * newSheet.addConditionalFormatting(cf);
    -     * 
    - * - * @param cf HSSFConditionalFormatting object - * @return index of the new Conditional Formatting object - */ - public int addConditionalFormatting( HSSFConditionalFormatting cf ) { - CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); - - return _conditionalFormattingTable.add(cfraClone); - } - - public int addConditionalFormatting( ConditionalFormatting cf ) { - return addConditionalFormatting((HSSFConditionalFormatting)cf); - } - - /** - * Allows to add a new Conditional Formatting set to the sheet. - * - * @param regions - list of rectangular regions to apply conditional formatting rules - * @param cfRules - set of up to three conditional formatting rules - * - * @return index of the newly created Conditional Formatting object - */ - public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) { - if (regions == null) { - throw new IllegalArgumentException("regions must not be null"); - } - for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97); - - if (cfRules == null) { - throw new IllegalArgumentException("cfRules must not be null"); - } - if (cfRules.length == 0) { - throw new IllegalArgumentException("cfRules must not be empty"); - } - if (cfRules.length > 3) { - throw new IllegalArgumentException("Number of rules must not exceed 3"); - } - - CFRuleBase[] rules = new CFRuleBase[cfRules.length]; - for (int i = 0; i != cfRules.length; i++) { - rules[i] = cfRules[i].getCfRuleRecord(); - } - CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules); - return _conditionalFormattingTable.add(cfra); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) { - HSSFConditionalFormattingRule[] hfRules; - if(cfRules instanceof HSSFConditionalFormattingRule[]) hfRules = (HSSFConditionalFormattingRule[])cfRules; - else { - hfRules = new HSSFConditionalFormattingRule[cfRules.length]; - System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length); - } - return addConditionalFormatting(regions, hfRules); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - HSSFConditionalFormattingRule rule1) { - return addConditionalFormatting(regions, rule1 == null ? - null : new HSSFConditionalFormattingRule[] { rule1 } - ); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - ConditionalFormattingRule rule1) { - return addConditionalFormatting(regions, (HSSFConditionalFormattingRule)rule1); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - HSSFConditionalFormattingRule rule1, - HSSFConditionalFormattingRule rule2) { - return addConditionalFormatting(regions, - new HSSFConditionalFormattingRule[] { rule1, rule2 }); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - ConditionalFormattingRule rule1, - ConditionalFormattingRule rule2) { - return addConditionalFormatting(regions, - (HSSFConditionalFormattingRule)rule1, - (HSSFConditionalFormattingRule)rule2 - ); - } - - /** - * gets Conditional Formatting object at a particular index - * - * @param index - * of the Conditional Formatting object to fetch - * @return Conditional Formatting object - */ - public HSSFConditionalFormatting getConditionalFormattingAt(int index) { - CFRecordsAggregate cf = _conditionalFormattingTable.get(index); - if (cf == null) { - return null; - } - return new HSSFConditionalFormatting(_sheet, cf); - } - - /** - * @return number of Conditional Formatting objects of the sheet - */ - public int getNumConditionalFormattings() { - return _conditionalFormattingTable.size(); - } - - /** - * removes a Conditional Formatting object by index - * @param index of a Conditional Formatting object to remove - */ - public void removeConditionalFormatting(int index) { - _conditionalFormattingTable.remove(index); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java deleted file mode 100644 index ec5293bbe..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java +++ /dev/null @@ -1,251 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.ddf.*; -import org.apache.poi.hssf.record.*; -import org.apache.poi.ss.usermodel.RichTextString; - -/** - * Represents a simple shape such as a line, rectangle or oval. - */ -public class HSSFSimpleShape extends HSSFShape -{ - // The commented out ones haven't been tested yet or aren't supported - // by HSSFSimpleShape. - - public final static short OBJECT_TYPE_LINE = HSSFShapeTypes.Line; - public final static short OBJECT_TYPE_RECTANGLE = HSSFShapeTypes.Rectangle; - public final static short OBJECT_TYPE_OVAL = HSSFShapeTypes.Ellipse; - public final static short OBJECT_TYPE_ARC = HSSFShapeTypes.Arc; - // public final static short OBJECT_TYPE_CHART = 5; -// public final static short OBJECT_TYPE_TEXT = 6; -// public final static short OBJECT_TYPE_BUTTON = 7; - public final static short OBJECT_TYPE_PICTURE = HSSFShapeTypes.PictureFrame; - -// public final static short OBJECT_TYPE_POLYGON = 9; -// public final static short OBJECT_TYPE_CHECKBOX = 11; -// public final static short OBJECT_TYPE_OPTION_BUTTON = 12; -// public final static short OBJECT_TYPE_EDIT_BOX = 13; -// public final static short OBJECT_TYPE_LABEL = 14; -// public final static short OBJECT_TYPE_DIALOG_BOX = 15; -// public final static short OBJECT_TYPE_SPINNER = 16; -// public final static short OBJECT_TYPE_SCROLL_BAR = 17; -// public final static short OBJECT_TYPE_LIST_BOX = 18; -// public final static short OBJECT_TYPE_GROUP_BOX = 19; - public final static short OBJECT_TYPE_COMBO_BOX = HSSFShapeTypes.HostControl; - public final static short OBJECT_TYPE_COMMENT = HSSFShapeTypes.TextBox; - public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30; - - public final static int WRAP_SQUARE = 0; - public final static int WRAP_BY_POINTS = 1; - public final static int WRAP_NONE = 2; - - private TextObjectRecord _textObjectRecord; - - public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) { - super(spContainer, objRecord); - this._textObjectRecord = textObjectRecord; - } - - public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) { - super(spContainer, objRecord); - } - - public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor) - { - super( parent, anchor ); - _textObjectRecord = createTextObjRecord(); - } - - protected TextObjectRecord getTextObjectRecord() { - return _textObjectRecord; - } - - protected TextObjectRecord createTextObjRecord(){ - TextObjectRecord obj = new TextObjectRecord(); - obj.setHorizontalTextAlignment(2); - obj.setVerticalTextAlignment(2); - obj.setTextLocked(true); - obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE); - obj.setStr(new HSSFRichTextString("")); - return obj; - } - - @Override - protected EscherContainerRecord createSpContainer() { - EscherContainerRecord spContainer = new EscherContainerRecord(); - spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); - spContainer.setOptions( (short) 0x000F ); - - EscherSpRecord sp = new EscherSpRecord(); - sp.setRecordId( EscherSpRecord.RECORD_ID ); - sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE ); - sp.setVersion((short) 0x2); - - EscherClientDataRecord clientData = new EscherClientDataRecord(); - clientData.setRecordId( EscherClientDataRecord.RECORD_ID ); - clientData.setOptions( (short) (0x0000) ); - - EscherOptRecord optRecord = new EscherOptRecord(); - optRecord.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID)); - optRecord.setEscherProperty( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008)); -// optRecord.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT)); - optRecord.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT)); - optRecord.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT)); - optRecord.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, NO_FILLHITTEST_FALSE)); - optRecord.setEscherProperty( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008)); - - optRecord.setEscherProperty( new EscherShapePathProperty( EscherProperties.GEOMETRY__SHAPEPATH, EscherShapePathProperty.COMPLEX ) ); - optRecord.setEscherProperty(new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x080000)); - optRecord.setRecordId( EscherOptRecord.RECORD_ID ); - - EscherTextboxRecord escherTextbox = new EscherTextboxRecord(); - escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID); - escherTextbox.setOptions((short) 0x0000); - - spContainer.addChildRecord(sp); - spContainer.addChildRecord(optRecord); - spContainer.addChildRecord(getAnchor().getEscherAnchor()); - spContainer.addChildRecord(clientData); - spContainer.addChildRecord(escherTextbox); - return spContainer; - } - - @Override - protected ObjRecord createObjRecord() { - ObjRecord obj = new ObjRecord(); - CommonObjectDataSubRecord c = new CommonObjectDataSubRecord(); - c.setLocked(true); - c.setPrintable(true); - c.setAutofill(true); - c.setAutoline(true); - EndSubRecord e = new EndSubRecord(); - - obj.addSubRecord(c); - obj.addSubRecord(e); - return obj; - } - - @Override - protected void afterRemove(HSSFPatriarch patriarch) { - patriarch.getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID)); - if (null != getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID)){ - patriarch.getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID)); - } - } - - /** - * @return the rich text string for this textbox. - */ - public HSSFRichTextString getString() { - return _textObjectRecord.getStr(); - } - - /** - * @param string Sets the rich text string used by this object. - */ - public void setString(RichTextString string) { - //TODO add other shape types which can not contain text - if (getShapeType() == 0 || getShapeType() == OBJECT_TYPE_LINE){ - throw new IllegalStateException("Cannot set text for shape type: "+getShapeType()); - } - HSSFRichTextString rtr = (HSSFRichTextString) string; - // If font is not set we must set the default one - if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0); - TextObjectRecord txo = getOrCreateTextObjRecord(); - txo.setStr(rtr); - if (string.getString() != null){ - setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTID, string.getString().hashCode())); - } - } - - @Override - void afterInsert(HSSFPatriarch patriarch){ - EscherAggregate agg = patriarch.getBoundAggregate(); - agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord()); - - if (null != getTextObjectRecord()){ - agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord()); - } - } - - @Override - protected HSSFShape cloneShape() { - TextObjectRecord txo = null; - EscherContainerRecord spContainer = new EscherContainerRecord(); - byte [] inSp = getEscherContainer().serialize(); - spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory()); - ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise(); - if (getTextObjectRecord() != null && getString() != null && null != getString().getString()){ - txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise(); - } - return new HSSFSimpleShape(spContainer, obj, txo); - } - - - /** - * Gets the shape type. - * @return One of the OBJECT_TYPE_* constants. - * - * @see #OBJECT_TYPE_LINE - * @see #OBJECT_TYPE_OVAL - * @see #OBJECT_TYPE_RECTANGLE - * @see #OBJECT_TYPE_PICTURE - * @see #OBJECT_TYPE_COMMENT - */ - public int getShapeType() { - EscherSpRecord spRecord = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); - return spRecord.getShapeType(); - } - - public int getWrapText(){ - EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__WRAPTEXT); - return null == property ? WRAP_SQUARE : property.getPropertyValue(); - } - - public void setWrapText(int value){ - setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__WRAPTEXT, false, false, value)); - } - - /** - * @see HSSFShapeTypes - * @param value - shapeType - */ - public void setShapeType(int value){ - CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0); - cod.setObjectType(OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING); - EscherSpRecord spRecord = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); - spRecord.setShapeType((short) value); - } - - private TextObjectRecord getOrCreateTextObjRecord(){ - if (getTextObjectRecord() == null){ - _textObjectRecord = createTextObjRecord(); - } - EscherTextboxRecord escherTextbox = getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID); - if (null == escherTextbox){ - escherTextbox = new EscherTextboxRecord(); - escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID); - escherTextbox.setOptions((short) 0x0000); - getEscherContainer().addChildRecord(escherTextbox); - getPatriarch().getBoundAggregate().associateShapeToObjRecord(escherTextbox, _textObjectRecord); - } - return _textObjectRecord; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java deleted file mode 100644 index d1e8b9ffa..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java +++ /dev/null @@ -1,247 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.ddf.*; -import org.apache.poi.hssf.record.*; - -/** - * A textbox is a shape that may hold a rich text string. - */ -public class HSSFTextbox extends HSSFSimpleShape { - public final static short OBJECT_TYPE_TEXT = 6; - - /** - * How to align text horizontally - */ - public final static short HORIZONTAL_ALIGNMENT_LEFT = 1; - public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2; - public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3; - public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4; - public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7; - - /** - * How to align text vertically - */ - public final static short VERTICAL_ALIGNMENT_TOP = 1; - public final static short VERTICAL_ALIGNMENT_CENTER = 2; - public final static short VERTICAL_ALIGNMENT_BOTTOM = 3; - public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4; - public final static short VERTICAL_ALIGNMENT_DISTRIBUTED = 7; - - public HSSFTextbox(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) { - super(spContainer, objRecord, textObjectRecord); - } - - // Findbugs: URF_UNREAD_FIELD. Do not delete without understanding how this class works. - //HSSFRichTextString string = new HSSFRichTextString(""); - - /** - * Construct a new textbox with the given parent and anchor. - * - * @param parent - * @param anchor One of HSSFClientAnchor or HSSFChildAnchor - */ - public HSSFTextbox(HSSFShape parent, HSSFAnchor anchor) { - super(parent, anchor); - setHorizontalAlignment(HORIZONTAL_ALIGNMENT_LEFT); - setVerticalAlignment(VERTICAL_ALIGNMENT_TOP); - setString(new HSSFRichTextString("")); - } - - @Override - protected ObjRecord createObjRecord() { - ObjRecord obj = new ObjRecord(); - CommonObjectDataSubRecord c = new CommonObjectDataSubRecord(); - c.setObjectType(HSSFTextbox.OBJECT_TYPE_TEXT); - c.setLocked(true); - c.setPrintable(true); - c.setAutofill(true); - c.setAutoline(true); - EndSubRecord e = new EndSubRecord(); - obj.addSubRecord(c); - obj.addSubRecord(e); - return obj; - } - - @Override - protected EscherContainerRecord createSpContainer() { - EscherContainerRecord spContainer = new EscherContainerRecord(); - EscherSpRecord sp = new EscherSpRecord(); - EscherOptRecord opt = new EscherOptRecord(); - EscherClientDataRecord clientData = new EscherClientDataRecord(); - EscherTextboxRecord escherTextbox = new EscherTextboxRecord(); - - spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER); - spContainer.setOptions((short) 0x000F); - sp.setRecordId(EscherSpRecord.RECORD_ID); - sp.setOptions((short) ((EscherAggregate.ST_TEXTBOX << 4) | 0x2)); - - sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE); - opt.setRecordId(EscherOptRecord.RECORD_ID); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTID, 0)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__WRAPTEXT, 0)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__ANCHORTEXT, 0)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000)); - - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, 0)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, 0)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, 0)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, 0)); - - opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID)); - opt.setEscherProperty(new EscherBoolProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008)); - opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT)); - opt.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT)); - opt.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT)); - opt.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, NO_FILLHITTEST_FALSE)); - opt.setEscherProperty(new EscherBoolProperty(EscherProperties.GROUPSHAPE__PRINT, 0x080000)); - - EscherRecord anchor = getAnchor().getEscherAnchor(); - clientData.setRecordId(EscherClientDataRecord.RECORD_ID); - clientData.setOptions((short) 0x0000); - escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID); - escherTextbox.setOptions((short) 0x0000); - - spContainer.addChildRecord(sp); - spContainer.addChildRecord(opt); - spContainer.addChildRecord(anchor); - spContainer.addChildRecord(clientData); - spContainer.addChildRecord(escherTextbox); - - return spContainer; - } - - @Override - void afterInsert(HSSFPatriarch patriarch) { - EscherAggregate agg = patriarch.getBoundAggregate(); - agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord()); - if (getTextObjectRecord() != null){ - agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord()); - } - } - - /** - * @return Returns the left margin within the textbox. - */ - public int getMarginLeft() { - EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTLEFT); - return property == null ? 0 : property.getPropertyValue(); - } - - /** - * Sets the left margin within the textbox. - */ - public void setMarginLeft(int marginLeft) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, marginLeft)); - } - - /** - * @return returns the right margin within the textbox. - */ - public int getMarginRight() { - EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTRIGHT); - return property == null ? 0 : property.getPropertyValue(); - } - - /** - * Sets the right margin within the textbox. - */ - public void setMarginRight(int marginRight) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, marginRight)); - } - - /** - * @return returns the top margin within the textbox. - */ - public int getMarginTop() { - EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTTOP); - return property == null ? 0 : property.getPropertyValue(); - } - - /** - * Sets the top margin within the textbox. - */ - public void setMarginTop(int marginTop) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, marginTop)); - } - - /** - * Gets the bottom margin within the textbox. - */ - public int getMarginBottom() { - EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTBOTTOM); - return property == null ? 0 : property.getPropertyValue(); - } - - /** - * Sets the bottom margin within the textbox. - */ - public void setMarginBottom(int marginBottom) { - setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, marginBottom)); - } - - /** - * Gets the horizontal alignment. - */ - public short getHorizontalAlignment() { - return (short) getTextObjectRecord().getHorizontalTextAlignment(); - } - - /** - * Sets the horizontal alignment. - */ - public void setHorizontalAlignment(short align) { - getTextObjectRecord().setHorizontalTextAlignment(align); - } - - /** - * Gets the vertical alignment. - */ - public short getVerticalAlignment() { - return (short) getTextObjectRecord().getVerticalTextAlignment(); - } - - /** - * Sets the vertical alignment. - */ - public void setVerticalAlignment(short align) { - getTextObjectRecord().setVerticalTextAlignment(align); - } - - @Override - public void setShapeType(int shapeType) { - throw new IllegalStateException("Shape type can not be changed in " + this.getClass().getSimpleName()); - } - - @Override - protected HSSFShape cloneShape() { - TextObjectRecord txo = getTextObjectRecord() == null ? null : (TextObjectRecord) getTextObjectRecord().cloneViaReserialise(); - EscherContainerRecord spContainer = new EscherContainerRecord(); - byte[] inSp = getEscherContainer().serialize(); - spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory()); - ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise(); - return new HSSFTextbox(spContainer, obj, txo); - } - - @Override - protected void afterRemove(HSSFPatriarch patriarch) { - patriarch.getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID)); - patriarch.getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID)); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java deleted file mode 100644 index 89b36c0d8..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ /dev/null @@ -1,2264 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import static org.apache.poi.hssf.model.InternalWorkbook.OLD_WORKBOOK_DIR_ENTRY_NAME; -import static org.apache.poi.hssf.model.InternalWorkbook.WORKBOOK_DIR_ENTRY_NAMES; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.regex.Pattern; - -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.POIDocument; -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherBitmapBlip; -import org.apache.poi.ddf.EscherBlipRecord; -import org.apache.poi.ddf.EscherMetafileBlip; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.hpsf.ClassID; -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.hssf.model.DrawingManager2; -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.model.InternalSheet; -import org.apache.poi.hssf.model.InternalSheet.UnsupportedBOFType; -import org.apache.poi.hssf.model.InternalWorkbook; -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.AbstractEscherHolderRecord; -import org.apache.poi.hssf.record.BackupRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.DrawingGroupRecord; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.FilePassRecord; -import org.apache.poi.hssf.record.FontRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NameRecord; -import org.apache.poi.hssf.record.RecalcIdRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordFactory; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.UnknownRecord; -import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; -import org.apache.poi.hssf.record.common.UnicodeString; -import org.apache.poi.hssf.record.crypto.Biff8DecryptingStream; -import org.apache.poi.hssf.util.CellReference; -import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.EntryUtils; -import org.apache.poi.poifs.filesystem.FilteringDirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSDocument; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.Ole10Native; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.formula.udf.AggregatingUDFFinder; -import org.apache.poi.ss.formula.udf.IndexedUDFFinder; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.WorkbookUtil; -import org.apache.poi.util.Configurator; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayInputStream; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * High level representation of a workbook. This is the first object most users - * will construct whether they are reading or writing a workbook. It is also the - * top level object for creating new sheets/etc. - * - * @see org.apache.poi.hssf.model.InternalWorkbook - * @see org.apache.poi.hssf.usermodel.HSSFSheet - */ -public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook { - private static final Pattern COMMA_PATTERN = Pattern.compile(","); - - /** - * The maximum number of cell styles in a .xls workbook. - * The 'official' limit is 4,000, but POI allows a slightly larger number. - * This extra delta takes into account built-in styles that are automatically - * - * See http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP005199291.aspx - */ - private static final int MAX_STYLES = 4030; - - private static final int DEBUG = POILogger.DEBUG; - - /** - * used for compile-time performance/memory optimization. This determines the - * initial capacity for the sheet collection. Its currently set to 3. - * Changing it in this release will decrease performance - * since you're never allowed to have more or less than three sheets! - */ - - public final static int INITIAL_CAPACITY = Configurator.getIntValue("HSSFWorkbook.SheetInitialCapacity",3); - - /** - * this is the reference to the low level Workbook object - */ - - private InternalWorkbook workbook; - - /** - * this holds the HSSFSheet objects attached to this workbook - */ - - protected List _sheets; - - /** - * this holds the HSSFName objects attached to this workbook - */ - - private ArrayList names; - - /** - * this holds the HSSFFont objects attached to this workbook. - * We only create these from the low level records as required. - */ - private Map fonts; - - /** - * holds whether or not to preserve other nodes in the POIFS. Used - * for macros and embedded objects. - */ - private boolean preserveNodes; - - /** - * Used to keep track of the data formatter so that all - * createDataFormatter calls return the same one for a given - * book. This ensures that updates from one places is visible - * someplace else. - */ - private HSSFDataFormat formatter; - - /** - * The policy to apply in the event of missing or - * blank cells when fetching from a row. - * See {@link MissingCellPolicy} - */ - private MissingCellPolicy missingCellPolicy = MissingCellPolicy.RETURN_NULL_AND_BLANK; - - private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class); - - /** - * The locator of user-defined functions. - * By default includes functions from the Excel Analysis Toolpack - */ - private UDFFinder _udfFinder = new IndexedUDFFinder(AggregatingUDFFinder.DEFAULT); - - public static HSSFWorkbook create(InternalWorkbook book) { - return new HSSFWorkbook(book); - } - /** - * Creates new HSSFWorkbook from scratch (start here!) - * - */ - public HSSFWorkbook() { - this(InternalWorkbook.createWorkbook()); - } - - private HSSFWorkbook(InternalWorkbook book) { - super((DirectoryNode)null); - workbook = book; - _sheets = new ArrayList(INITIAL_CAPACITY); - names = new ArrayList(INITIAL_CAPACITY); - } - - /** - * Given a POI POIFSFileSystem object, read in its Workbook along - * with all related nodes, and populate the high and low level models. - *

    This calls {@link #HSSFWorkbook(POIFSFileSystem, boolean)} with - * preserve nodes set to true. - * - * @see #HSSFWorkbook(POIFSFileSystem, boolean) - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @exception IOException if the stream cannot be read - */ - public HSSFWorkbook(POIFSFileSystem fs) throws IOException { - this(fs,true); - } - /** - * Given a POI POIFSFileSystem object, read in its Workbook along - * with all related nodes, and populate the high and low level models. - *

    This calls {@link #HSSFWorkbook(POIFSFileSystem, boolean)} with - * preserve nodes set to true. - * - * @see #HSSFWorkbook(POIFSFileSystem, boolean) - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @exception IOException if the stream cannot be read - */ - public HSSFWorkbook(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot(),true); - } - - /** - * Given a POI POIFSFileSystem object, read in its Workbook and populate - * the high and low level models. If you're reading in a workbook... start here! - * - * @param fs the POI filesystem that contains the Workbook stream. - * @param preserveNodes whether to preserve other nodes, such as - * macros. This takes more memory, so only say yes if you - * need to. If set, will store all of the POIFSFileSystem - * in memory - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @exception IOException if the stream cannot be read - */ - public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes) - throws IOException { - this(fs.getRoot(), fs, preserveNodes); - } - - public static String getWorkbookDirEntryName(DirectoryNode directory) { - - for (String wbName : WORKBOOK_DIR_ENTRY_NAMES) { - try { - directory.getEntry(wbName); - return wbName; - } catch (FileNotFoundException e) { - // continue - to try other options - } - } - - // check for an encrypted .xlsx file - they get OLE2 wrapped - try { - directory.getEntry(Decryptor.DEFAULT_POIFS_ENTRY); - throw new EncryptedDocumentException("The supplied spreadsheet seems to be an Encrypted .xlsx file. " + - "It must be decrypted before use by XSSF, it cannot be used by HSSF"); - } catch (FileNotFoundException e) { - // fall through - } - - // check for previous version of file format - try { - directory.getEntry(OLD_WORKBOOK_DIR_ENTRY_NAME); - throw new OldExcelFormatException("The supplied spreadsheet seems to be Excel 5.0/7.0 (BIFF5) format. " - + "POI only supports BIFF8 format (from Excel versions 97/2000/XP/2003)"); - } catch (FileNotFoundException e) { - // fall through - } - - throw new IllegalArgumentException("The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. " - + "Is it really an excel file?"); - } - - /** - * given a POI POIFSFileSystem object, and a specific directory - * within it, read in its Workbook and populate the high and - * low level models. If you're reading in a workbook...start here. - * - * @param directory the POI filesystem directory to process from - * @param fs the POI filesystem that contains the Workbook stream. - * @param preserveNodes whether to preserve other nodes, such as - * macros. This takes more memory, so only say yes if you - * need to. If set, will store all of the POIFSFileSystem - * in memory - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @exception IOException if the stream cannot be read - */ - public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserveNodes) - throws IOException - { - this(directory, preserveNodes); - } - - /** - * given a POI POIFSFileSystem object, and a specific directory - * within it, read in its Workbook and populate the high and - * low level models. If you're reading in a workbook...start here. - * - * @param directory the POI filesystem directory to process from - * @param preserveNodes whether to preserve other nodes, such as - * macros. This takes more memory, so only say yes if you - * need to. If set, will store all of the POIFSFileSystem - * in memory - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @exception IOException if the stream cannot be read - */ - public HSSFWorkbook(DirectoryNode directory, boolean preserveNodes) - throws IOException - { - super(directory); - String workbookName = getWorkbookDirEntryName(directory); - - this.preserveNodes = preserveNodes; - - // If we're not preserving nodes, don't track the - // POIFS any more - if(! preserveNodes) { - this.directory = null; - } - - _sheets = new ArrayList(INITIAL_CAPACITY); - names = new ArrayList(INITIAL_CAPACITY); - - // Grab the data from the workbook stream, however - // it happens to be spelled. - InputStream stream = directory.createDocumentInputStream(workbookName); - - List records = RecordFactory.createRecords(stream); - - workbook = InternalWorkbook.createWorkbook(records); - setPropertiesFromWorkbook(workbook); - int recOffset = workbook.getNumRecords(); - - // convert all LabelRecord records to LabelSSTRecord - convertLabelRecords(records, recOffset); - RecordStream rs = new RecordStream(records, recOffset); - while (rs.hasNext()) { - try { - InternalSheet sheet = InternalSheet.createSheet(rs); - _sheets.add(new HSSFSheet(this, sheet)); - } catch (UnsupportedBOFType eb) { - // Hopefully there's a supported one after this! - log.log(POILogger.WARN, "Unsupported BOF found of type " + eb.getType()); - } - } - - for (int i = 0 ; i < workbook.getNumNames() ; ++i){ - NameRecord nameRecord = workbook.getNameRecord(i); - HSSFName name = new HSSFName(this, nameRecord, workbook.getNameCommentRecord(nameRecord)); - names.add(name); - } - } - - /** - * Companion to HSSFWorkbook(POIFSFileSystem), this constructs the - * POI filesystem around your {@link InputStream}, including all nodes. - *

    - * Note that Excel allows sheet names up to 31 chars in length but other applications - * (such as OpenOffice) allow more. Some versions of Excel crash with names longer than 31 chars, - * others - truncate such names to 31 character. - *

    - *

    - * POI's SpreadsheetAPI silently truncates the input argument to 31 characters. - * Example: - * - *

    
    -     *     Sheet sheet = workbook.createSheet("My very long sheet name which is longer than 31 chars"); // will be truncated
    -     *     assert 31 == sheet.getSheetName().length();
    -     *     assert "My very long sheet name which i" == sheet.getSheetName();
    -     *     
    - *

    - * - * Except the 31-character constraint, Excel applies some other rules: - *

    - * Sheet name MUST be unique in the workbook and MUST NOT contain the any of the following characters: - *

      - *
    • 0x0000
    • - *
    • 0x0003
    • - *
    • colon (:)
    • - *
    • backslash (\)
    • - *
    • asterisk (*)
    • - *
    • question mark (?)
    • - *
    • forward slash (/)
    • - *
    • opening square bracket ([)
    • - *
    • closing square bracket (])
    • - *
    - * The string MUST NOT begin or end with the single quote (') character. - *

    - * - * @param sheetname sheetname to set for the sheet. - * @return Sheet representing the new sheet. - * @throws IllegalArgumentException if the name is null or invalid - * or workbook already contains a sheet with this name - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - */ - @Override - public HSSFSheet createSheet(String sheetname) - { - if (sheetname == null) { - throw new IllegalArgumentException("sheetName must not be null"); - } - - if (workbook.doesContainsSheetName( sheetname, _sheets.size() )) - throw new IllegalArgumentException("The workbook already contains a sheet named '" + sheetname + "'"); - - HSSFSheet sheet = new HSSFSheet(this); - - workbook.setSheetName(_sheets.size(), sheetname); - _sheets.add(sheet); - boolean isOnlySheet = _sheets.size() == 1; - sheet.setSelected(isOnlySheet); - sheet.setActive(isOnlySheet); - return sheet; - } - - /** - * Returns an iterator of the sheets in the workbook - * in sheet order. Includes hidden and very hidden sheets. - * - * @return an iterator of the sheets. - */ - @Override - public Iterator sheetIterator() { - return new SheetIterator(); - } - - /** - * Alias for {@link #sheetIterator()} to allow - * foreach loops - */ - @Override - public Iterator iterator() { - return sheetIterator(); - } - - private final class SheetIterator implements Iterator { - final private Iterator it; - private T cursor = null; - @SuppressWarnings("unchecked") - public SheetIterator() { - it = (Iterator) _sheets.iterator(); - } - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - public T next() throws NoSuchElementException { - cursor = it.next(); - return cursor; - } - /** - * Unexpected behavior may occur if sheets are reordered after iterator - * has been created. Support for the remove method may be added in the future - * if someone can figure out a reliable implementation. - */ - @Override - public void remove() throws IllegalStateException { - throw new UnsupportedOperationException("remove method not supported on HSSFWorkbook.iterator(). "+ - "Use Sheet.removeSheetAt(int) instead."); - } - } - - /** - * get the number of spreadsheets in the workbook (this will be three after serialization) - * @return number of sheets - */ - @Override - public int getNumberOfSheets() - { - return _sheets.size(); - } - - private HSSFSheet[] getSheets() { - HSSFSheet[] result = new HSSFSheet[_sheets.size()]; - _sheets.toArray(result); - return result; - } - - /** - * Get the HSSFSheet object at the given index. - * @param index of the sheet number (0-based physical & logical) - * @return HSSFSheet at the provided index - * @throws IllegalArgumentException if the index is out of range (index - * < 0 || index >= getNumberOfSheets()). - */ - @Override - public HSSFSheet getSheetAt(int index) - { - validateSheetIndex(index); - return _sheets.get(index); - } - - /** - * Get sheet with the given name (case insensitive match) - * @param name of the sheet - * @return HSSFSheet with the name provided or null if it does not exist - */ - - @Override - public HSSFSheet getSheet(String name) - { - HSSFSheet retval = null; - - for (int k = 0; k < _sheets.size(); k++) - { - String sheetname = workbook.getSheetName(k); - - if (sheetname.equalsIgnoreCase(name)) - { - retval = _sheets.get(k); - } - } - return retval; - } - - /** - * Removes sheet at the given index.

    - * - * Care must be taken if the removed sheet is the currently active or only selected sheet in - * the workbook. There are a few situations when Excel must have a selection and/or active - * sheet. (For example when printing - see Bug 40414).
    - * - * This method makes sure that if the removed sheet was active, another sheet will become - * active in its place. Furthermore, if the removed sheet was the only selected sheet, another - * sheet will become selected. The newly active/selected sheet will have the same index, or - * one less if the removed sheet was the last in the workbook. - * - * @param index of the sheet (0-based) - */ - @Override - public void removeSheetAt(int index) { - validateSheetIndex(index); - boolean wasSelected = getSheetAt(index).isSelected(); - - _sheets.remove(index); - workbook.removeSheet(index); - - // set the remaining active/selected sheet - int nSheets = _sheets.size(); - if (nSheets < 1) { - // nothing more to do if there are no sheets left - return; - } - // the index of the closest remaining sheet to the one just deleted - int newSheetIndex = index; - if (newSheetIndex >= nSheets) { - newSheetIndex = nSheets-1; - } - - if (wasSelected) { - boolean someOtherSheetIsStillSelected = false; - for (int i =0; i < nSheets; i++) { - if (getSheetAt(i).isSelected()) { - someOtherSheetIsStillSelected = true; - break; - } - } - if (!someOtherSheetIsStillSelected) { - setSelectedTab(newSheetIndex); - } - } - - // adjust active sheet - int active = getActiveSheetIndex(); - if(active == index) { - // removed sheet was the active one, reset active sheet if there is still one left now - setActiveSheet(newSheetIndex); - } else if (active > index) { - // removed sheet was below the active one => active is one less now - setActiveSheet(active-1); - } - } - - /** - * determine whether the Excel GUI will backup the workbook when saving. - * - * @param backupValue true to indicate a backup will be performed. - */ - - public void setBackupFlag(boolean backupValue) - { - BackupRecord backupRecord = workbook.getBackupRecord(); - - backupRecord.setBackup(backupValue ? (short) 1 - : (short) 0); - } - - /** - * determine whether the Excel GUI will backup the workbook when saving. - * - * @return the current setting for backups. - */ - - public boolean getBackupFlag() - { - BackupRecord backupRecord = workbook.getBackupRecord(); - - return backupRecord.getBackup() != 0; - } - - int findExistingBuiltinNameRecordIdx(int sheetIndex, byte builtinCode) { - for(int defNameIndex =0; defNameIndex 3) - { - fontindex++; // THERE IS NO FOUR!! - } - if(fontindex == Short.MAX_VALUE){ - throw new IllegalArgumentException("Maximum number of fonts was exceeded"); - } - - // Ask getFontAt() to build it for us, - // so it gets properly cached - return getFontAt(fontindex); - } - - /** - * Finds a font that matches the one with the supplied attributes - * @deprecated 3.15 beta 2. Use {@link #findFont(boolean, short, short, String, boolean, boolean, short, byte)} instead. - */ - @Deprecated - @Override - public HSSFFont findFont(short boldWeight, short color, short fontHeight, - String name, boolean italic, boolean strikeout, - short typeOffset, byte underline) - { - short numberOfFonts = getNumberOfFonts(); - for (short i=0; i<=numberOfFonts; i++) { - // Remember - there is no 4! - if(i == 4) continue; - - HSSFFont hssfFont = getFontAt(i); - if (hssfFont.getBoldweight() == boldWeight - && hssfFont.getColor() == color - && hssfFont.getFontHeight() == fontHeight - && hssfFont.getFontName().equals(name) - && hssfFont.getItalic() == italic - && hssfFont.getStrikeout() == strikeout - && hssfFont.getTypeOffset() == typeOffset - && hssfFont.getUnderline() == underline) - { - return hssfFont; - } - } - - return null; - } - /** - * Finds a font that matches the one with the supplied attributes - */ - @Override - public HSSFFont findFont(boolean bold, short color, short fontHeight, - String name, boolean italic, boolean strikeout, - short typeOffset, byte underline) - { - short numberOfFonts = getNumberOfFonts(); - for (short i=0; i<=numberOfFonts; i++) { - // Remember - there is no 4! - if(i == 4) continue; - - HSSFFont hssfFont = getFontAt(i); - if (hssfFont.getBold() == bold - && hssfFont.getColor() == color - && hssfFont.getFontHeight() == fontHeight - && hssfFont.getFontName().equals(name) - && hssfFont.getItalic() == italic - && hssfFont.getStrikeout() == strikeout - && hssfFont.getTypeOffset() == typeOffset - && hssfFont.getUnderline() == underline) - { - return hssfFont; - } - } - - return null; - } - - /** - * get the number of fonts in the font table - * @return number of fonts - */ - - @Override - public short getNumberOfFonts() - { - return (short) workbook.getNumberOfFontRecords(); - } - - /** - * Get the font at the given index number - * @param idx index number - * @return HSSFFont at the index - */ - @Override - public HSSFFont getFontAt(short idx) { - if(fonts == null) fonts = new HashMap(); - - // So we don't confuse users, give them back - // the same object every time, but create - // them lazily - Short sIdx = Short.valueOf(idx); - if(fonts.containsKey(sIdx)) { - return fonts.get(sIdx); - } - - FontRecord font = workbook.getFontRecordAt(idx); - HSSFFont retval = new HSSFFont(idx, font); - fonts.put(sIdx, retval); - - return retval; - } - - /** - * Reset the fonts cache, causing all new calls - * to getFontAt() to create new objects. - * Should only be called after deleting fonts, - * and that's not something you should normally do - */ - protected void resetFontCache() { - fonts = new HashMap(); - } - - /** - * Create a new Cell style and add it to the workbook's style table. - * You can define up to 4000 unique styles in a .xls workbook. - * - * @return the new Cell Style object - * @throws IllegalStateException if the number of cell styles exceeded the limit for this type of Workbook. - */ - @Override - public HSSFCellStyle createCellStyle() - { - if(workbook.getNumExFormats() == MAX_STYLES) { - throw new IllegalStateException("The maximum number of cell styles was exceeded. " + - "You can define up to 4000 styles in a .xls workbook"); - } - ExtendedFormatRecord xfr = workbook.createCellXF(); - short index = (short) (getNumCellStyles() - 1); - return new HSSFCellStyle(index, xfr, this); - } - - /** - * get the number of styles the workbook contains - * @return count of cell styles - */ - @Override - public int getNumCellStyles() - { - return workbook.getNumExFormats(); - } - - /** - * get the cell style object at the given index - * @param idx index within the set of styles - * @return HSSFCellStyle object at the index - */ - @Override - public HSSFCellStyle getCellStyleAt(int idx) - { - ExtendedFormatRecord xfr = workbook.getExFormatAt(idx); - return new HSSFCellStyle((short)idx, xfr, this); - } - - /** - * Closes the underlying {@link NPOIFSFileSystem} from which - * the Workbook was read, if any. - * - *

    Once this has been called, no further - * operations, updates or reads should be performed on the - * Workbook. - */ - @Override - public void close() throws IOException { - super.close(); - } - - /** - * Write out this workbook to the currently open {@link File} via the - * writeable {@link POIFSFileSystem} it was opened as. - * - *

    This will fail (with an {@link IllegalStateException} if the - * Workbook was opened read-only, opened from an {@link InputStream} - * instead of a File, or if this is not the root document. For those cases, - * you must use {@link #write(OutputStream)} or {@link #write(File)} to - * write to a brand new document. - */ - @Override - public void write() throws IOException { - validateInPlaceWritePossible(); - - // Update the Workbook stream in the file - DocumentNode workbookNode = (DocumentNode)directory.getEntry( - getWorkbookDirEntryName(directory)); - NPOIFSDocument workbookDoc = new NPOIFSDocument(workbookNode); - workbookDoc.replaceContents(new ByteArrayInputStream(getBytes())); - - // Update the properties streams in the file - writeProperties(); - - // Sync with the File on disk - directory.getFileSystem().writeFilesystem(); - } - - /** - * Method write - write out this workbook to a new {@link File}. Constructs - * a new POI POIFSFileSystem, passes in the workbook binary representation and - * writes it out. If the file exists, it will be replaced, otherwise a new one - * will be created. - * - * Note that you cannot write to the currently open File using this method. - * If you opened your Workbook from a File, you must use the {@link #write()} - * method instead! - * - * @param newFile The new File you wish to write the XLS to - * - * @exception IOException if anything can't be written. - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - */ - @Override - public void write(File newFile) throws IOException { - POIFSFileSystem fs = POIFSFileSystem.create(newFile); - try { - write(fs); - fs.writeFilesystem(); - } finally { - fs.close(); - } - } - - /** - * Method write - write out this workbook to an {@link OutputStream}. Constructs - * a new POI POIFSFileSystem, passes in the workbook binary representation and - * writes it out. - * - * If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive - * or has a high cost/latency associated with each written byte, - * consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream} - * to improve write performance. - * - * @param stream - the java OutputStream you wish to write the XLS to - * - * @exception IOException if anything can't be written. - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - */ - @Override - public void write(OutputStream stream) throws IOException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(); - try { - write(fs); - fs.writeFilesystem(stream); - } finally { - fs.close(); - } - } - - /** Writes the workbook out to a brand new, empty POIFS */ - private void write(NPOIFSFileSystem fs) throws IOException { - // For tracking what we've written out, used if we're - // going to be preserving nodes - List excepts = new ArrayList(1); - - // Write out the Workbook stream - fs.createDocument(new ByteArrayInputStream(getBytes()), "Workbook"); - - // Write out our HPFS properties, if we have them - writeProperties(fs, excepts); - - if (preserveNodes) { - // Don't write out the old Workbook, we'll be doing our new one - // If the file had an "incorrect" name for the workbook stream, - // don't write the old one as we'll use the correct name shortly - excepts.addAll(Arrays.asList(WORKBOOK_DIR_ENTRY_NAMES)); - - // Copy over all the other nodes to our new poifs - EntryUtils.copyNodes( - new FilteringDirectoryNode(this.directory, excepts) - , new FilteringDirectoryNode(fs.getRoot(), excepts) - ); - - // YK: preserve StorageClsid, it is important for embedded workbooks, - // see Bugzilla 47920 - fs.getRoot().setStorageClsid(this.directory.getStorageClsid()); - } - } - - /** - * Totals the sizes of all sheet records and eventually serializes them - */ - private static final class SheetRecordCollector implements RecordVisitor { - - private List _list; - private int _totalSize; - - public SheetRecordCollector() { - _totalSize = 0; - _list = new ArrayList(128); - } - public int getTotalSize() { - return _totalSize; - } - @Override - public void visitRecord(Record r) { - _list.add(r); - _totalSize+=r.getRecordSize(); - - } - public int serialize(int offset, byte[] data) { - int result = 0; - for (Record rec : _list) { - result += rec.serialize(offset + result, data); - } - return result; - } - } - - - /** - * Method getBytes - get the bytes of just the HSSF portions of the XLS file. - * Use this to construct a POI POIFSFileSystem yourself. - * - * - * @return byte[] array containing the binary representation of this workbook and all contained - * sheets, rows, cells, etc. - */ - public byte[] getBytes() { - if (log.check( POILogger.DEBUG )) { - log.log(DEBUG, "HSSFWorkbook.getBytes()"); - } - - HSSFSheet[] sheets = getSheets(); - int nSheets = sheets.length; - - - // before getting the workbook size we must tell the sheets that - // serialization is about to occur. - workbook.preSerialize(); - for (HSSFSheet sheet : sheets) { - sheet.getSheet().preSerialize(); - sheet.preSerialize(); - } - - int totalsize = workbook.getSize(); - - // pre-calculate all the sheet sizes and set BOF indexes - SheetRecordCollector[] srCollectors = new SheetRecordCollector[nSheets]; - for (int k = 0; k < nSheets; k++) { - workbook.setSheetBof(k, totalsize); - SheetRecordCollector src = new SheetRecordCollector(); - sheets[k].getSheet().visitContainedRecords(src, totalsize); - totalsize += src.getTotalSize(); - srCollectors[k] = src; - } - - byte[] retval = new byte[totalsize]; - int pos = workbook.serialize(0, retval); - - for (int k = 0; k < nSheets; k++) { - SheetRecordCollector src = srCollectors[k]; - int serializedSize = src.serialize(pos, retval); - if (serializedSize != src.getTotalSize()) { - // Wrong offset values have been passed in the call to setSheetBof() above. - // For books with more than one sheet, this discrepancy would cause excel - // to report errors and loose data while reading the workbook - throw new IllegalStateException("Actual serialized sheet size (" + serializedSize - + ") differs from pre-calculated size (" + src.getTotalSize() - + ") for sheet (" + k + ")"); - // TODO - add similar sanity check to ensure that Sheet.serializeIndexRecord() does not write mis-aligned offsets either - } - pos += serializedSize; - } - - encryptBytes(retval); - - return retval; - } - - @SuppressWarnings("resource") - protected void encryptBytes(byte buf[]) { - int initialOffset = 0; - FilePassRecord fpr = null; - for (Record r : workbook.getRecords()) { - initialOffset += r.getRecordSize(); - if (r instanceof FilePassRecord) { - fpr = (FilePassRecord)r; - break; - } - } - if (fpr == null) { - return; - } - - LittleEndianByteArrayInputStream plain = new LittleEndianByteArrayInputStream(buf, 0); - LittleEndianByteArrayOutputStream leos = new LittleEndianByteArrayOutputStream(buf, 0); - Encryptor enc = fpr.getEncryptionInfo().getEncryptor(); - enc.setChunkSize(Biff8DecryptingStream.RC4_REKEYING_INTERVAL); - byte tmp[] = new byte[1024]; - try { - ChunkedCipherOutputStream os = enc.getDataStream(leos, initialOffset); - int totalBytes = 0; - while (totalBytes < buf.length) { - plain.read(tmp, 0, 4); - final int sid = LittleEndian.getUShort(tmp, 0); - final int len = LittleEndian.getUShort(tmp, 2); - boolean isPlain = Biff8DecryptingStream.isNeverEncryptedRecord(sid); - os.setNextRecordSize(len, isPlain); - os.writePlain(tmp, 0, 4); - if (sid == BoundSheetRecord.sid) { - // special case for the field_1_position_of_BOF (=lbPlyPos) field of - // the BoundSheet8 record which must be unencrypted - byte bsrBuf[] = new byte[len]; - plain.readFully(bsrBuf); - os.writePlain(bsrBuf, 0, 4); - os.write(bsrBuf, 4, len-4); - } else { - int todo = len; - while (todo > 0) { - int nextLen = Math.min(todo, tmp.length); - plain.readFully(tmp, 0, nextLen); - if (isPlain) { - os.writePlain(tmp, 0, nextLen); - } else { - os.write(tmp, 0, nextLen); - } - todo -= nextLen; - } - } - totalBytes += 4 + len; - } - os.close(); - } catch (Exception e) { - throw new EncryptedDocumentException(e); - } - } - - /*package*/ InternalWorkbook getWorkbook() { - return workbook; - } - - @Override - public int getNumberOfNames(){ - return names.size(); - } - - @Override - public HSSFName getName(String name) { - int nameIndex = getNameIndex(name); - if (nameIndex < 0) { - return null; - } - return names.get(nameIndex); - } - - @Override - public List getNames(String name) { - List nameList = new ArrayList(); - for(HSSFName nr : names) { - if(nr.getNameName().equals(name)) { - nameList.add(nr); - } - } - - return Collections.unmodifiableList(nameList); - } - - @Override - public HSSFName getNameAt(int nameIndex) { - int nNames = names.size(); - if (nNames < 1) { - throw new IllegalStateException("There are no defined names in this workbook"); - } - if (nameIndex < 0 || nameIndex > nNames) { - throw new IllegalArgumentException("Specified name index " + nameIndex - + " is outside the allowable range (0.." + (nNames-1) + ")."); - } - return names.get(nameIndex); - } - - @Override - public List getAllNames() { - return Collections.unmodifiableList(names); - } - - public NameRecord getNameRecord(int nameIndex) { - return getWorkbook().getNameRecord(nameIndex); - } - - /** gets the named range name - * @param index the named range index (0 based) - * @return named range name - */ - public String getNameName(int index){ - return getNameAt(index).getNameName(); - } - - /** - * Sets the printarea for the sheet provided - *

    - * i.e. Reference = $A$1:$B$2 - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @param reference Valid name Reference for the Print Area - */ - @Override - public void setPrintArea(int sheetIndex, String reference) - { - NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1); - - - if (name == null) { - name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1); - // adding one here because 0 indicates a global named region; doesn't make sense for print areas - } - String[] parts = COMMA_PATTERN.split(reference); - StringBuffer sb = new StringBuffer(32); - for (int i = 0; i < parts.length; i++) { - if(i>0) { - sb.append(","); - } - SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex)); - sb.append("!"); - sb.append(parts[i]); - } - name.setNameDefinition(HSSFFormulaParser.parse(sb.toString(), this, FormulaType.NAMEDRANGE, sheetIndex)); - } - - /** - * For the Convenience of Java Programmers maintaining pointers. - * @see #setPrintArea(int, String) - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - * @param startColumn Column to begin printarea - * @param endColumn Column to end the printarea - * @param startRow Row to begin the printarea - * @param endRow Row to end the printarea - */ - @Override - public void setPrintArea(int sheetIndex, int startColumn, int endColumn, - int startRow, int endRow) { - - //using absolute references because they don't get copied and pasted anyway - CellReference cell = new CellReference(startRow, startColumn, true, true); - String reference = cell.formatAsString(); - - cell = new CellReference(endRow, endColumn, true, true); - reference = reference+":"+cell.formatAsString(); - - setPrintArea(sheetIndex, reference); - } - - - /** - * Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified. - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @return String Null if no print area has been defined - */ - @Override - public String getPrintArea(int sheetIndex) { - NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1); - //adding one here because 0 indicates a global named region; doesn't make sense for print areas - if (name == null) { - return null; - } - - return HSSFFormulaParser.toFormulaString(this, name.getNameDefinition()); - } - - /** - * Delete the printarea for the sheet specified - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - */ - @Override - public void removePrintArea(int sheetIndex) { - getWorkbook().removeBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1); - } - - /** creates a new named range and add it to the model - * @return named range high level - */ - @Override - public HSSFName createName(){ - NameRecord nameRecord = workbook.createName(); - - HSSFName newName = new HSSFName(this, nameRecord); - - names.add(newName); - - return newName; - } - - @Override - public int getNameIndex(String name) { - - for (int k = 0; k < names.size(); k++) { - String nameName = getNameName(k); - - if (nameName.equalsIgnoreCase(name)) { - return k; - } - } - return -1; - } - - - /** - * As {@link #getNameIndex(String)} is not necessarily unique - * (name + sheet index is unique), this method is more accurate. - * - * @param name the name whose index in the list of names of this workbook - * should be looked up. - * @return an index value >= 0 if the name was found; -1, if the name was - * not found - */ - int getNameIndex(HSSFName name) { - for (int k = 0; k < names.size(); k++) { - if (name == names.get(k)) { - return k; - } - } - return -1; - } - - - @Override - public void removeName(int index){ - names.remove(index); - workbook.removeName(index); - } - - /** - * Returns the instance of HSSFDataFormat for this workbook. - * @return the HSSFDataFormat object - * @see org.apache.poi.hssf.record.FormatRecord - * @see org.apache.poi.hssf.record.Record - */ - @Override - public HSSFDataFormat createDataFormat() { - if (formatter == null) - formatter = new HSSFDataFormat(workbook); - return formatter; - } - - - @Override - public void removeName(String name) { - int index = getNameIndex(name); - removeName(index); - } - - - /** - * As {@link #removeName(String)} is not necessarily unique - * (name + sheet index is unique), this method is more accurate. - * - * @param name the name to remove. - */ - @Override - public void removeName(Name name) { - int index = getNameIndex((HSSFName) name); - removeName(index); - } - - public HSSFPalette getCustomPalette() - { - return new HSSFPalette(workbook.getCustomPalette()); - } - - /** Test only. Do not use */ - public void insertChartRecord() - { - int loc = workbook.findFirstRecordLocBySid(SSTRecord.sid); - byte[] data = { - (byte)0x0F, (byte)0x00, (byte)0x00, (byte)0xF0, (byte)0x52, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, - (byte)0x06, (byte)0xF0, (byte)0x18, (byte)0x00, (byte)0x00, - (byte)0x00, (byte)0x01, (byte)0x08, (byte)0x00, (byte)0x00, - (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, - (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, - (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00, - (byte)0x33, (byte)0x00, (byte)0x0B, (byte)0xF0, (byte)0x12, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xBF, (byte)0x00, - (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x81, - (byte)0x01, (byte)0x09, (byte)0x00, (byte)0x00, (byte)0x08, - (byte)0xC0, (byte)0x01, (byte)0x40, (byte)0x00, (byte)0x00, - (byte)0x08, (byte)0x40, (byte)0x00, (byte)0x1E, (byte)0xF1, - (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0D, - (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x0C, (byte)0x00, - (byte)0x00, (byte)0x08, (byte)0x17, (byte)0x00, (byte)0x00, - (byte)0x08, (byte)0xF7, (byte)0x00, (byte)0x00, (byte)0x10, - }; - UnknownRecord r = new UnknownRecord((short)0x00EB, data); - workbook.getRecords().add(loc, r); - } - - /** - * Spits out a list of all the drawing records in the workbook. - */ - public void dumpDrawingGroupRecords(boolean fat) - { - DrawingGroupRecord r = (DrawingGroupRecord) workbook.findFirstRecordBySid( DrawingGroupRecord.sid ); - r.decode(); - List escherRecords = r.getEscherRecords(); - PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out, Charset.defaultCharset())); - for (EscherRecord escherRecord : escherRecords) { - if (fat) - System.out.println(escherRecord.toString()); - else - escherRecord.display(w, 0); - } - w.flush(); - } - - void initDrawings(){ - DrawingManager2 mgr = workbook.findDrawingGroup(); - if(mgr != null) { - for(HSSFSheet sh : _sheets) { - sh.getDrawingPatriarch(); - } - } else { - workbook.createDrawingGroup(); - } - } - - /** - * Adds a picture to the workbook. - * - * @param pictureData The bytes of the picture - * @param format The format of the picture. One of PICTURE_TYPE_* - * - * @return the index to this picture (1 based). - * @see #PICTURE_TYPE_WMF - * @see #PICTURE_TYPE_EMF - * @see #PICTURE_TYPE_PICT - * @see #PICTURE_TYPE_PNG - * @see #PICTURE_TYPE_JPEG - * @see #PICTURE_TYPE_DIB - */ - @SuppressWarnings("fallthrough") - @Override - public int addPicture(byte[] pictureData, int format) - { - initDrawings(); - - byte[] uid = DigestUtils.md5(pictureData); - EscherBlipRecord blipRecord; - int blipSize; - short escherTag; - switch (format) { - case PICTURE_TYPE_WMF: - // remove first 22 bytes if file starts with magic bytes D7-CD-C6-9A - // see also http://de.wikipedia.org/wiki/Windows_Metafile#Hinweise_zur_WMF-Spezifikation - if (LittleEndian.getInt(pictureData) == 0x9AC6CDD7) { - byte picDataNoHeader[] = new byte[pictureData.length-22]; - System.arraycopy(pictureData, 22, picDataNoHeader, 0, pictureData.length-22); - pictureData = picDataNoHeader; - } - // fall through - case PICTURE_TYPE_EMF: - EscherMetafileBlip blipRecordMeta = new EscherMetafileBlip(); - blipRecord = blipRecordMeta; - blipRecordMeta.setUID(uid); - blipRecordMeta.setPictureData(pictureData); - // taken from libre office export, it won't open, if this is left to 0 - blipRecordMeta.setFilter((byte)-2); - blipSize = blipRecordMeta.getCompressedSize() + 58; - escherTag = 0; - break; - default: - EscherBitmapBlip blipRecordBitmap = new EscherBitmapBlip(); - blipRecord = blipRecordBitmap; - blipRecordBitmap.setUID( uid ); - blipRecordBitmap.setMarker( (byte) 0xFF ); - blipRecordBitmap.setPictureData( pictureData ); - blipSize = pictureData.length + 25; - escherTag = (short) 0xFF; - break; - } - - blipRecord.setRecordId((short) (EscherBlipRecord.RECORD_ID_START + format)); - switch (format) - { - case PICTURE_TYPE_EMF: - blipRecord.setOptions(HSSFPictureData.MSOBI_EMF); - break; - case PICTURE_TYPE_WMF: - blipRecord.setOptions(HSSFPictureData.MSOBI_WMF); - break; - case PICTURE_TYPE_PICT: - blipRecord.setOptions(HSSFPictureData.MSOBI_PICT); - break; - case PICTURE_TYPE_PNG: - blipRecord.setOptions(HSSFPictureData.MSOBI_PNG); - break; - case PICTURE_TYPE_JPEG: - blipRecord.setOptions(HSSFPictureData.MSOBI_JPEG); - break; - case PICTURE_TYPE_DIB: - blipRecord.setOptions(HSSFPictureData.MSOBI_DIB); - break; - default: - throw new IllegalStateException("Unexpected picture format: " + format); - } - - EscherBSERecord r = new EscherBSERecord(); - r.setRecordId( EscherBSERecord.RECORD_ID ); - r.setOptions( (short) ( 0x0002 | ( format << 4 ) ) ); - r.setBlipTypeMacOS( (byte) format ); - r.setBlipTypeWin32( (byte) format ); - r.setUid( uid ); - r.setTag( escherTag ); - r.setSize( blipSize ); - r.setRef( 0 ); - r.setOffset( 0 ); - r.setBlipRecord( blipRecord ); - - return workbook.addBSERecord( r ); - } - - /** - * Gets all pictures from the Workbook. - * - * @return the list of pictures (a list of {@link HSSFPictureData} objects.) - */ - @Override - public List getAllPictures() - { - // The drawing group record always exists at the top level, so we won't need to do this recursively. - List pictures = new ArrayList(); - for (Record r : workbook.getRecords()) { - if (r instanceof AbstractEscherHolderRecord) { - ((AbstractEscherHolderRecord) r).decode(); - List escherRecords = ((AbstractEscherHolderRecord) r).getEscherRecords(); - searchForPictures(escherRecords, pictures); - } - } - return Collections.unmodifiableList(pictures); - } - - /** - * Performs a recursive search for pictures in the given list of escher records. - * - * @param escherRecords the escher records. - * @param pictures the list to populate with the pictures. - */ - private void searchForPictures(List escherRecords, List pictures) - { - for(EscherRecord escherRecord : escherRecords) { - - if (escherRecord instanceof EscherBSERecord) - { - EscherBlipRecord blip = ((EscherBSERecord) escherRecord).getBlipRecord(); - if (blip != null) - { - // TODO: Some kind of structure. - HSSFPictureData picture = new HSSFPictureData(blip); - pictures.add(picture); - } - - - } - - // Recursive call. - searchForPictures(escherRecord.getChildRecords(), pictures); - } - - } - - protected static Map getOleMap() { - Map olemap = new HashMap(); - olemap.put("PowerPoint Document", ClassID.PPT_SHOW); - for (String str : WORKBOOK_DIR_ENTRY_NAMES) { - olemap.put(str, ClassID.XLS_WORKBOOK); - } - // ... to be continued - return olemap; - } - - public int addOlePackage(POIFSFileSystem poiData, String label, String fileName, String command) - throws IOException { - DirectoryNode root = poiData.getRoot(); - Map olemap = getOleMap(); - for (Map.Entry entry : olemap.entrySet()) { - if (root.hasEntry(entry.getKey())) { - root.setStorageClsid(entry.getValue()); - break; - } - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - poiData.writeFilesystem(bos); - return addOlePackage(bos.toByteArray(), label, fileName, command); - } - - public int addOlePackage(byte[] oleData, String label, String fileName, String command) - throws IOException { - // check if we were created by POIFS otherwise create a new dummy POIFS for storing the package data - if (directory == null) { - directory = new NPOIFSFileSystem().getRoot(); - preserveNodes = true; - } - - // get free MBD-Node - int storageId = 0; - DirectoryEntry oleDir = null; - do { - String storageStr = "MBD"+ HexDump.toHex(++storageId); - if (!directory.hasEntry(storageStr)) { - oleDir = directory.createDirectory(storageStr); - oleDir.setStorageClsid(ClassID.OLE10_PACKAGE); - } - } while (oleDir == null); - - // the following data was taken from an example libre office document - // beside this "\u0001Ole" record there were several other records, e.g. CompObj, - // OlePresXXX, but it seems, that they aren't neccessary - byte oleBytes[] = { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - oleDir.createDocument("\u0001Ole", new ByteArrayInputStream(oleBytes)); - - Ole10Native oleNative = new Ole10Native(label, fileName, command, oleData); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - oleNative.writeOut(bos); - oleDir.createDocument(Ole10Native.OLE10_NATIVE, new ByteArrayInputStream(bos.toByteArray())); - - return storageId; - } - - /** - * Adds the LinkTable records required to allow formulas referencing - * the specified external workbook to be added to this one. Allows - * formulas such as "[MyOtherWorkbook]Sheet3!$A$5" to be added to the - * file, for workbooks not already referenced. - * - * @param name The name the workbook will be referenced as in formulas - * @param workbook The open workbook to fetch the link required information from - */ - @Override - public int linkExternalWorkbook(String name, Workbook workbook) { - return this.workbook.linkExternalWorkbook(name, workbook); - } - - /** - * Is the workbook protected with a password (not encrypted)? - */ - public boolean isWriteProtected() { - return this.workbook.isWriteProtected(); - } - - /** - * protect a workbook with a password (not encypted, just sets writeprotect - * flags and the password. - * @param password to set - */ - public void writeProtectWorkbook( String password, String username ) { - this.workbook.writeProtectWorkbook(password, username); - } - - /** - * removes the write protect flag - */ - public void unwriteProtectWorkbook() { - this.workbook.unwriteProtectWorkbook(); - } - - /** - * Gets all embedded OLE2 objects from the Workbook. - * - * @return the list of embedded objects (a list of {@link HSSFObjectData} objects.) - */ - public List getAllEmbeddedObjects() - { - List objects = new ArrayList(); - for (HSSFSheet sheet : _sheets) - { - getAllEmbeddedObjects(sheet, objects); - } - return Collections.unmodifiableList(objects); - } - - /** - * Gets all embedded OLE2 objects from the Workbook. - * - * @param sheet embedded object attached to - * @param objects the list of embedded objects to populate. - */ - private void getAllEmbeddedObjects(HSSFSheet sheet, List objects) - { - HSSFPatriarch patriarch = sheet.getDrawingPatriarch(); - if (null == patriarch){ - return; - } - getAllEmbeddedObjects(patriarch, objects); - } - /** - * Recursively iterates a shape container to get all embedded objects. - * - * @param parent the parent. - * @param objects the list of embedded objects to populate. - */ - private void getAllEmbeddedObjects(HSSFShapeContainer parent, List objects) - { - for (HSSFShape shape : parent.getChildren()) { - if (shape instanceof HSSFObjectData) { - objects.add((HSSFObjectData) shape); - } else if (shape instanceof HSSFShapeContainer) { - getAllEmbeddedObjects((HSSFShapeContainer) shape, objects); - } - } - } - @Override - public HSSFCreationHelper getCreationHelper() { - return new HSSFCreationHelper(this); - } - - /** - * - * Returns the locator of user-defined functions. - * The default instance extends the built-in functions with the Analysis Tool Pack - * - * @return the locator of user-defined functions - */ - /*package*/ UDFFinder getUDFFinder(){ - return _udfFinder; - } - - /** - * Register a new toolpack in this workbook. - * - * @param toopack the toolpack to register - */ - @Override - public void addToolPack(UDFFinder toopack){ - AggregatingUDFFinder udfs = (AggregatingUDFFinder)_udfFinder; - udfs.add(toopack); - } - - /** - * Whether the application shall perform a full recalculation when the workbook is opened. - *

    - * Typically you want to force formula recalculation when you modify cell formulas or values - * of a workbook previously created by Excel. When set to true, this flag will tell Excel - * that it needs to recalculate all formulas in the workbook the next time the file is opened. - *

    - *

    - * Note, that recalculation updates cached formula results and, thus, modifies the workbook. - * Depending on the version, Excel may prompt you with "Do you want to save the changes in filename?" - * on close. - *

    - * - * @param value true if the application will perform a full recalculation of - * workbook values when the workbook is opened - * @since 3.8 - */ - @Override - public void setForceFormulaRecalculation(boolean value){ - InternalWorkbook iwb = getWorkbook(); - RecalcIdRecord recalc = iwb.getRecalcId(); - recalc.setEngineId(0); - } - - /** - * Whether Excel will be asked to recalculate all formulas when the workbook is opened. - * - * @since 3.8 - */ - @Override - public boolean getForceFormulaRecalculation(){ - InternalWorkbook iwb = getWorkbook(); - RecalcIdRecord recalc = (RecalcIdRecord)iwb.findFirstRecordBySid(RecalcIdRecord.sid); - return recalc != null && recalc.getEngineId() != 0; - } - - /** - * Changes an external referenced file to another file. - * A formula in Excel which references a cell in another file is saved in two parts: - * The referenced file is stored in an reference table. the row/cell information is saved separate. - * This method invocation will only change the reference in the lookup-table itself. - * @param oldUrl The old URL to search for and which is to be replaced - * @param newUrl The URL replacement - * @return true if the oldUrl was found and replaced with newUrl. Otherwise false - */ - public boolean changeExternalReference(String oldUrl, String newUrl) { - return workbook.changeExternalReference(oldUrl, newUrl); - } - - public DirectoryNode getRootDirectory(){ - return directory; - } - - @Internal - public InternalWorkbook getInternalWorkbook() { - return workbook; - } - - /** - * Returns the spreadsheet version (EXCLE97) of this workbook - * - * @return EXCEL97 SpreadsheetVersion enum - * @since 3.14 beta 2 - */ - @Override - public SpreadsheetVersion getSpreadsheetVersion() { - return SpreadsheetVersion.EXCEL97; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/HeaderFooter.java b/trunk/src/java/org/apache/poi/hssf/usermodel/HeaderFooter.java deleted file mode 100644 index 94a4e3b31..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/HeaderFooter.java +++ /dev/null @@ -1,346 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - - -/** - * Common class for {@link HSSFHeader} and {@link HSSFFooter}. - */ -public abstract class HeaderFooter implements org.apache.poi.ss.usermodel.HeaderFooter { - - protected HeaderFooter() { - // - } - - /** - * @return the internal text representation (combining center, left and right parts). - * Possibly empty string if no header or footer is set. Never null. - */ - protected abstract String getRawText(); - - private String[] splitParts() { - String text = getRawText(); - // default values - String _left = ""; - String _center = ""; - String _right = ""; - -outer: - while (text.length() > 1) { - if (text.charAt(0) != '&') { - // Mimics the behaviour of Excel, which would put it in the center. - _center = text; - break; - } - int pos = text.length(); - switch (text.charAt(1)) { - case 'L': - if (text.indexOf("&C") >= 0) { - pos = Math.min(pos, text.indexOf("&C")); - } - if (text.indexOf("&R") >= 0) { - pos = Math.min(pos, text.indexOf("&R")); - } - _left = text.substring(2, pos); - text = text.substring(pos); - break; - case 'C': - if (text.indexOf("&L") >= 0) { - pos = Math.min(pos, text.indexOf("&L")); - } - if (text.indexOf("&R") >= 0) { - pos = Math.min(pos, text.indexOf("&R")); - } - _center = text.substring(2, pos); - text = text.substring(pos); - break; - case 'R': - if (text.indexOf("&C") >= 0) { - pos = Math.min(pos, text.indexOf("&C")); - } - if (text.indexOf("&L") >= 0) { - pos = Math.min(pos, text.indexOf("&L")); - } - _right = text.substring(2, pos); - text = text.substring(pos); - break; - default: - // Mimics the behaviour of Excel, which would put it in the center. - _center = text; - break outer; - } - } - return new String[] { _left, _center, _right, }; - } - - /** - * @return the left side of the header or footer. - */ - public final String getLeft() { - return splitParts()[0]; - } - - /** - * @param newLeft The string to set as the left side. - */ - public final void setLeft(String newLeft) { - updatePart(0, newLeft); - } - - /** - * @return the center of the header or footer. - */ - public final String getCenter() { - return splitParts()[1]; - } - - /** - * @param newCenter The string to set as the center. - */ - public final void setCenter(String newCenter) { - updatePart(1, newCenter); - } - - /** - * @return The right side of the header or footer. - */ - public final String getRight() { - return splitParts()[2]; - } - - /** - * @param newRight The string to set as the right side. - */ - public final void setRight(String newRight) { - updatePart(2, newRight); - } - - private void updatePart(int partIndex, String newValue) { - String[] parts = splitParts(); - parts[partIndex] = newValue == null ? "" : newValue; - updateHeaderFooterText(parts); - } - /** - * Creates the complete footer string based on the left, center, and middle - * strings. - */ - private void updateHeaderFooterText(String[] parts) { - String _left = parts[0]; - String _center = parts[1]; - String _right = parts[2]; - - if (_center.length() < 1 && _left.length() < 1 && _right.length() < 1) { - setHeaderFooterText(""); - return; - } - StringBuilder sb = new StringBuilder(64); - sb.append("&C"); - sb.append(_center); - sb.append("&L"); - sb.append(_left); - sb.append("&R"); - sb.append(_right); - String text = sb.toString(); - setHeaderFooterText(text); - } - - /** - * @param text the new header footer text (contains mark-up tags). Possibly - * empty string never null - */ - protected abstract void setHeaderFooterText(String text); - - /** - * @param size - * the new font size - * @return The mark-up tag representing a new font size - */ - public static String fontSize(short size) { - return "&" + size; - } - - /** - * @param font - * the new font - * @param style - * the fonts style, one of regular, italic, bold, italic bold or - * bold italic - * @return The mark-up tag representing a new font size - */ - public static String font(String font, String style) { - return "&\"" + font + "," + style + "\""; - } - - /** - * @return The mark-up tag representing the current page number - */ - public static String page() { - return MarkupTag.PAGE_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag representing the number of pages - */ - public static String numPages() { - return MarkupTag.NUM_PAGES_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag representing the current date date - */ - public static String date() { - return MarkupTag.DATE_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag representing current time - */ - public static String time() { - return MarkupTag.TIME_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag representing the current file name - */ - public static String file() { - return MarkupTag.FILE_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag representing the current tab (sheet) name - */ - public static String tab() { - return MarkupTag.SHEET_NAME_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag for start bold - */ - public static String startBold() { - return MarkupTag.BOLD_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag for end bold - */ - public static String endBold() { - return MarkupTag.BOLD_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag for start underline - */ - public static String startUnderline() { - return MarkupTag.UNDERLINE_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag for end underline - */ - public static String endUnderline() { - return MarkupTag.UNDERLINE_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag for start double underline - */ - public static String startDoubleUnderline() { - return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation(); - } - - /** - * @return The mark-up tag for end double underline - */ - public static String endDoubleUnderline() { - return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation(); - } - - /** - * Removes any fields (eg macros, page markers etc) from the string. - * Normally used to make some text suitable for showing to humans, and the - * resultant text should not normally be saved back into the document! - */ - public static String stripFields(String pText) { - int pos; - - // Check we really got something to work on - if (pText == null || pText.length() == 0) { - return pText; - } - - String text = pText; - - // Firstly, do the easy ones which are static - for (MarkupTag mt : MarkupTag.values()) { - String seq = mt.getRepresentation(); - while ((pos = text.indexOf(seq)) > -1) { - text = text.substring(0, pos) + text.substring(pos + seq.length()); - } - } - - // Now do the tricky, dynamic ones - // These are things like font sizes and font names - text = text.replaceAll("\\&\\d+", ""); - text = text.replaceAll("\\&\".*?,.*?\"", ""); - - // All done - return text; - } - - private enum MarkupTag { - SHEET_NAME_FIELD ("&A", false), - DATE_FIELD ("&D", false), - FILE_FIELD ("&F", false), - FULL_FILE_FIELD ("&Z", false), - PAGE_FIELD ("&P", false), - TIME_FIELD ("&T", false), - NUM_PAGES_FIELD ("&N", false), - - PICTURE_FIELD ("&G", false), - - BOLD_FIELD ("&B", true), - ITALIC_FIELD ("&I", true), - STRIKETHROUGH_FIELD ("&S", true), - SUBSCRIPT_FIELD ("&Y", true), - SUPERSCRIPT_FIELD ("&X", true), - UNDERLINE_FIELD ("&U", true), - DOUBLE_UNDERLINE_FIELD ("&E", true), - ; - - private final String _representation; - private final boolean _occursInPairs; - private MarkupTag(String sequence, boolean occursInPairs) { - _representation = sequence; - _occursInPairs = occursInPairs; - } - /** - * @return The character sequence that marks this field - */ - public String getRepresentation() { - return _representation; - } - - /** - * @return true if this markup tag normally comes in a pair, eg turn on - * underline / turn off underline - */ - public boolean occursPairs() { - return _occursInPairs; - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/StaticFontMetrics.java b/trunk/src/java/org/apache/poi/hssf/usermodel/StaticFontMetrics.java deleted file mode 100644 index fcfd23f17..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/StaticFontMetrics.java +++ /dev/null @@ -1,142 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel; - -import java.awt.Font; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Allows the user to lookup the font metrics for a particular font without - * actually having the font on the system. The font details are loaded as a - * resource from the POI jar file (or classpath) and should be contained in path - * "/font_metrics.properties". The font widths are for a 10 point version of the - * font. Use a multiplier for other sizes. - */ -final class StaticFontMetrics { - private static final POILogger LOGGER = POILogFactory.getLogger(StaticFontMetrics.class); - /** The font metrics property file we're using */ - private static Properties fontMetricsProps; - /** Our cache of font details we've already looked up */ - private static final Map fontDetailsMap = new HashMap(); - - private StaticFontMetrics() {} - - /** - * Retrieves the fake font details for a given font. - * - * @param font - * the font to lookup. - * @return the fake font. - */ - public static synchronized FontDetails getFontDetails(Font font) { - // If we haven't already identified out font metrics file, - // figure out which one to use and load it - if (fontMetricsProps == null) { - try { - fontMetricsProps = loadMetrics(); - } catch (IOException e) { - throw new RuntimeException("Could not load font metrics", e); - } - } - - // Grab the base name of the font they've asked about - String fontName = font.getName(); - - // Some fonts support plain/bold/italic/bolditalic variants - // Others have different font instances for bold etc - // (eg font.dialog.plain.* vs font.Californian FB Bold.*) - String fontStyle = ""; - if (font.isPlain()) { - fontStyle += "plain"; - } - if (font.isBold()) { - fontStyle += "bold"; - } - if (font.isItalic()) { - fontStyle += "italic"; - } - - // Do we have a definition for this font with just the name? - // If not, check with the font style added - String fontHeight = FontDetails.buildFontHeightProperty(fontName); - String styleHeight = FontDetails.buildFontHeightProperty(fontName + "." + fontStyle); - - if (fontMetricsProps.get(fontHeight) == null - && fontMetricsProps.get(styleHeight) != null) { - // Need to add on the style to the font name - fontName += "." + fontStyle; - } - - // Get the details on this font - FontDetails fontDetails = fontDetailsMap.get(fontName); - if (fontDetails == null) { - fontDetails = FontDetails.create(fontName, fontMetricsProps); - fontDetailsMap.put(fontName, fontDetails); - } - return fontDetails; - } - - private static Properties loadMetrics() throws IOException { - // Check to see if the font metric file was specified - // as a system property - File propFile = null; - try { - String propFileName = System.getProperty("font.metrics.filename"); - if (propFileName != null) { - propFile = new File(propFileName); - if (!propFile.exists()) { - LOGGER.log(POILogger.WARN, "font_metrics.properties not found at path "+propFile.getAbsolutePath()); - propFile = null; - } - } - } catch (SecurityException e) { - LOGGER.log(POILogger.WARN, "Can't access font.metrics.filename system property", e); - } - - InputStream metricsIn = null; - try { - if (propFile != null) { - metricsIn = new FileInputStream(propFile); - } else { - // Use the built-in font metrics file off the classpath - metricsIn = FontDetails.class.getResourceAsStream("/font_metrics.properties"); - if (metricsIn == null) { - String err = "font_metrics.properties not found in classpath"; - throw new IOException(err); - } - } - - Properties props = new Properties(); - props.load(metricsIn); - return props; - } finally { - if (metricsIn != null) { - metricsIn.close(); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/helpers/HSSFRowShifter.java b/trunk/src/java/org/apache/poi/hssf/usermodel/helpers/HSSFRowShifter.java deleted file mode 100644 index 88a6f9b73..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/helpers/HSSFRowShifter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.usermodel.helpers; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.eval.NotImplementedException; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.helpers.RowShifter; -import org.apache.poi.util.Internal; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Helper for shifting rows up or down - * - * When possible, code should be implemented in the RowShifter abstract class to avoid duplication with {@link org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter} - */ -public final class HSSFRowShifter extends RowShifter { - private static final POILogger logger = POILogFactory.getLogger(HSSFRowShifter.class); - - public HSSFRowShifter(HSSFSheet sh) { - super(sh); - } - - @NotImplemented - public void updateNamedRanges(FormulaShifter shifter) { - throw new NotImplementedException("HSSFRowShifter.updateNamedRanges"); - } - - @NotImplemented - public void updateFormulas(FormulaShifter shifter) { - throw new NotImplementedException("updateFormulas"); - } - - @Internal - @NotImplemented - public void updateRowFormulas(Row row, FormulaShifter shifter) { - throw new NotImplementedException("updateRowFormulas"); - } - - @NotImplemented - public void updateConditionalFormatting(FormulaShifter shifter) { - throw new NotImplementedException("updateConditionalFormatting"); - } - - @NotImplemented - public void updateHyperlinks(FormulaShifter shifter) { - throw new NotImplementedException("updateHyperlinks"); - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/usermodel/package.html b/trunk/src/java/org/apache/poi/hssf/usermodel/package.html deleted file mode 100644 index 5779057bf..000000000 --- a/trunk/src/java/org/apache/poi/hssf/usermodel/package.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - -usermodel package maps HSSF low level strutures to familiar workbook/sheet model - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/hssf/util/AreaReference.java b/trunk/src/java/org/apache/poi/hssf/util/AreaReference.java deleted file mode 100644 index 3474abff7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/AreaReference.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -/** - * @deprecated POI 3.15 beta 3. Use {@link org.apache.poi.ss.util.AreaReference} instead. - */ -@Deprecated -public final class AreaReference extends org.apache.poi.ss.util.AreaReference { - /** - * Create an area ref from a string representation. Sheet names containing special characters should be - * delimited and escaped as per normal syntax rules for formulas.
    - * The area reference must be contiguous (i.e. represent a single rectangle, not a union of rectangles) - */ - public AreaReference(String reference) { - super(reference); - } - - /** - * Creates an area ref from a pair of Cell References. - * Also normalises such that the top-left - */ - public AreaReference(CellReference topLeft, CellReference botRight) { - super(topLeft, botRight); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java b/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java deleted file mode 100644 index 9c866f9b5..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -import org.apache.poi.ss.util.CellRangeAddressBase; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

    - * - * Implements a CellRangeAddress with 8-but column fields. - */ -public final class CellRangeAddress8Bit extends CellRangeAddressBase { - - public static final int ENCODED_SIZE = 6; - - public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) { - super(firstRow, lastRow, firstCol, lastCol); - } - - public CellRangeAddress8Bit(LittleEndianInput in) { - super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte()); - } - - private static int readUShortAndCheck(LittleEndianInput in) { - if (in.available() < ENCODED_SIZE) { - // Ran out of data - throw new RuntimeException("Ran out of data reading CellRangeAddress"); - } - return in.readUShort(); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getFirstRow()); - out.writeShort(getLastRow()); - out.writeByte(getFirstColumn()); - out.writeByte(getLastColumn()); - } - - public CellRangeAddress8Bit copy() { - return new CellRangeAddress8Bit(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn()); - } - - public static int getEncodedSize(int numberOfItems) { - return numberOfItems * ENCODED_SIZE; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/CellReference.java b/trunk/src/java/org/apache/poi/hssf/util/CellReference.java deleted file mode 100644 index ac3e5f388..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/CellReference.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -/** - * Common conversion functions between Excel style A1, C27 style - * cell references, and POI usermodel style row=0, column=0 - * style references. - */ -public final class CellReference extends org.apache.poi.ss.util.CellReference { - /** - * Create an cell ref from a string representation. Sheet names containing special characters should be - * delimited and escaped as per normal syntax rules for formulas. - */ - public CellReference(String cellRef) { - super(cellRef); - } - - public CellReference(int pRow, int pCol) { - super(pRow, pCol, true, true); - } - - public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) { - super(null, pRow, pCol, pAbsRow, pAbsCol); - } - - public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) { - super(pSheetName, pRow, pCol, pAbsRow, pAbsCol); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/HSSFCellUtil.java b/trunk/src/java/org/apache/poi/hssf/util/HSSFCellUtil.java deleted file mode 100644 index ae46a5a2e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/HSSFCellUtil.java +++ /dev/null @@ -1,169 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.util.CellUtil; -import org.apache.poi.util.Removal; - -/** - * Various utility functions that make working with a cells and rows easier. The various - * methods that deal with style's allow you to create your HSSFCellStyles as you need them. - * When you apply a style change to a cell, the code will attempt to see if a style already - * exists that meets your needs. If not, then it will create a new style. This is to prevent - * creating too many styles. there is an upper limit in Excel on the number of styles that - * can be supported. - * - * @deprecated 3.15 beta2. Use {@link org.apache.poi.ss.util.CellUtil} instead. - */ -@Deprecated -@Removal(version="3.17") -public final class HSSFCellUtil { - - private HSSFCellUtil() { - // no instances of this class - } - - /** - * Get a row from the spreadsheet, and create it if it doesn't exist. - * - * @param rowIndex The 0 based row number - * @param sheet The sheet that the row is part of. - * @return The row indicated by the rowCounter - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#getRow} instead. - */ - public static HSSFRow getRow(int rowIndex, HSSFSheet sheet) { - return (HSSFRow) CellUtil.getRow(rowIndex, sheet); - } - - /** - * Get a specific cell from a row. If the cell doesn't exist, - * then create it. - * - * @param row The row that the cell is part of - * @param columnIndex The column index that the cell is in. - * @return The cell indicated by the column. - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#getCell} instead. - */ - public static HSSFCell getCell(HSSFRow row, int columnIndex) { - return (HSSFCell) CellUtil.getCell(row, columnIndex); - } - - /** - * Creates a cell, gives it a value, and applies a style if provided - * - * @param row the row to create the cell in - * @param column the column index to create the cell in - * @param value The value of the cell - * @param style If the style is not null, then set - * @return A new HSSFCell - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#createCell} instead. - */ - public static HSSFCell createCell(HSSFRow row, int column, String value, HSSFCellStyle style) { - return (HSSFCell) CellUtil.createCell(row, column, value, style); - } - - /** - * Create a cell, and give it a value. - * - * @param row the row to create the cell in - * @param column the column index to create the cell in - * @param value The value of the cell - * @return A new HSSFCell. - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#createCell} instead. - */ - public static HSSFCell createCell(HSSFRow row, int column, String value) { - return createCell( row, column, value, null ); - } - - /** - * Take a cell, and align it. - * - * @param cell the cell to set the alignment for - * @param workbook The workbook that is being worked with. - * @param align the column alignment to use. - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#setAlignment} instead. - * - * @see HSSFCellStyle for alignment options - */ - public static void setAlignment(HSSFCell cell, HSSFWorkbook workbook, short align) { - setAlignment(cell, HorizontalAlignment.forInt(align)); - } - /** - * Take a cell, and align it. - * - * @param cell the cell to set the alignment for - * @param align the column alignment to use. - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#setAlignment} instead. - * - * @see HSSFCellStyle for alignment options - */ - public static void setAlignment(HSSFCell cell, HorizontalAlignment align) { - CellUtil.setAlignment(cell, align); - } - - /** - * Take a cell, and apply a font to it - * - * @param cell the cell to set the alignment for - * @param workbook The workbook that is being worked with. - * @param font The HSSFFont that you want to set. - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#setFont} instead. - */ - public static void setFont(HSSFCell cell, HSSFWorkbook workbook, HSSFFont font) { - CellUtil.setFont(cell, font); - } - - /** - * This method attempt to find an already existing HSSFCellStyle that matches - * what you want the style to be. If it does not find the style, then it - * creates a new one. If it does create a new one, then it applies the - * propertyName and propertyValue to the style. This is necessary because - * Excel has an upper limit on the number of Styles that it supports. - * - * @param workbook The workbook that is being worked with. - * @param propertyName The name of the property that is to be changed. - * @param propertyValue The value of the property that is to be changed. - * @param cell The cell that needs it's style changes - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperty} instead. - */ - public static void setCellStyleProperty(HSSFCell cell, HSSFWorkbook workbook, - String propertyName, Object propertyValue) { - CellUtil.setCellStyleProperty(cell, propertyName, propertyValue); - } - - /** - * Looks for text in the cell that should be unicode, like α and provides the - * unicode version of it. - * - * @param cell The cell to check for unicode values - * @return translated to unicode (the cell is modified in-place and returned) - * - * @deprecated 3.15 beta2. Removed in 3.17. Use {@link org.apache.poi.ss.util.CellUtil#translateUnicodeValues} instead. - */ - public static HSSFCell translateUnicodeValues(HSSFCell cell){ - CellUtil.translateUnicodeValues(cell); - return cell; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/HSSFColor.java b/trunk/src/java/org/apache/poi/hssf/util/HSSFColor.java deleted file mode 100644 index 55ff46bf1..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/HSSFColor.java +++ /dev/null @@ -1,1717 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -import java.lang.reflect.Field; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.usermodel.Color; - - -/** - * Intends to provide support for the very evil index to triplet issue and - * will likely replace the color constants interface for HSSF 2.0. - * This class contains static inner class members for representing colors. - * Each color has an index (for the standard palette in Excel (tm) ), - * native (RGB) triplet and string triplet. The string triplet is as the - * color would be represented by Gnumeric. Having (string) this here is a bit of a - * collusion of function between HSSF and the HSSFSerializer but I think its - * a reasonable one in this case. - */ -public class HSSFColor implements Color { - private static Map indexHash; - - /** Creates a new instance of HSSFColor */ - public HSSFColor() - { - } - - /** - * This function returns all the colours in an unmodifiable Map. - * The map is cached on first use. - * - * @return a Map containing all colours keyed by Integer excel-style palette indexes - */ - public final static Map getIndexHash() { - if(indexHash == null) { - indexHash = Collections.unmodifiableMap( createColorsByIndexMap() ); - } - - return indexHash; - } - /** - * This function returns all the Colours, stored in a Map that - * can be edited. No caching is performed. If you don't need to edit - * the table, then call {@link #getIndexHash()} which returns a - * statically cached imuatable map of colours. - */ - public final static Map getMutableIndexHash() { - return createColorsByIndexMap(); - } - - private static Map createColorsByIndexMap() { - HSSFColor[] colors = getAllColors(); - Map result = new HashMap(colors.length * 3 / 2); - - for (int i = 0; i < colors.length; i++) { - HSSFColor color = colors[i]; - - Integer index1 = Integer.valueOf(color.getIndex()); - if (result.containsKey(index1)) { - HSSFColor prevColor = result.get(index1); - throw new RuntimeException("Dup color index (" + index1 - + ") for colors (" + prevColor.getClass().getName() - + "),(" + color.getClass().getName() + ")"); - } - result.put(index1, color); - } - - for (int i = 0; i < colors.length; i++) { - HSSFColor color = colors[i]; - Integer index2 = getIndex2(color); - if (index2 == null) { - // most colors don't have a second index - continue; - } -// if (result.containsKey(index2)) { -// if (false) { // Many of the second indexes clash -// HSSFColor prevColor = (HSSFColor)result.get(index2); -// throw new RuntimeException("Dup color index (" + index2 -// + ") for colors (" + prevColor.getClass().getName() -// + "),(" + color.getClass().getName() + ")"); -// } -// } - result.put(index2, color); - } - return result; - } - - private static Integer getIndex2(HSSFColor color) { - - Field f; - try { - f = color.getClass().getDeclaredField("index2"); - } catch (NoSuchFieldException e) { - // can happen because not all colors have a second index - return null; - } - - Short s; - try { - s = (Short) f.get(color); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - return Integer.valueOf(s.intValue()); - } - - private static HSSFColor[] getAllColors() { - - return new HSSFColor[] { - new BLACK(), new BROWN(), new OLIVE_GREEN(), new DARK_GREEN(), - new DARK_TEAL(), new DARK_BLUE(), new INDIGO(), new GREY_80_PERCENT(), - new ORANGE(), new DARK_YELLOW(), new GREEN(), new TEAL(), new BLUE(), - new BLUE_GREY(), new GREY_50_PERCENT(), new RED(), new LIGHT_ORANGE(), new LIME(), - new SEA_GREEN(), new AQUA(), new LIGHT_BLUE(), new VIOLET(), new GREY_40_PERCENT(), - new PINK(), new GOLD(), new YELLOW(), new BRIGHT_GREEN(), new TURQUOISE(), - new DARK_RED(), new SKY_BLUE(), new PLUM(), new GREY_25_PERCENT(), new ROSE(), - new LIGHT_YELLOW(), new LIGHT_GREEN(), new LIGHT_TURQUOISE(), new PALE_BLUE(), - new LAVENDER(), new WHITE(), new CORNFLOWER_BLUE(), new LEMON_CHIFFON(), - new MAROON(), new ORCHID(), new CORAL(), new ROYAL_BLUE(), - new LIGHT_CORNFLOWER_BLUE(), new TAN(), - }; - } - - /** - * this function returns all colors in a hastable. Its not implemented as a - * static member/staticly initialized because that would be dirty in a - * server environment as it is intended. This means you'll eat the time - * it takes to create it once per request but you will not hold onto it - * if you have none of those requests. - * - * @return a Map containing all colors keyed by String gnumeric-like triplets - */ - public final static Map getTripletHash() - { - return createColorsByHexStringMap(); - } - - private static Map createColorsByHexStringMap() { - HSSFColor[] colors = getAllColors(); - Map result = new HashMap(colors.length * 3 / 2); - - for (int i = 0; i < colors.length; i++) { - HSSFColor color = colors[i]; - - String hexString = color.getHexString(); - if (result.containsKey(hexString)) { - HSSFColor other = result.get(hexString); - throw new RuntimeException( - "Dup color hexString (" + hexString - + ") for color (" + color.getClass().getName() + ") - " - + " already taken by (" + other.getClass().getName() + ")" - ); - } - result.put(hexString, color); - } - return result; - } - - /** - * returns color standard palette index (0x08) - * @return index to the standard palette - */ - - public short getIndex() - { - // this will be overridden by the specific color subclass - return BLACK.index; - } - - /** - * returns RGB triplet (0, 0, 0) - * @return triplet representation like that in Excel - */ - - public short [] getTriplet() - { - // this will be overridden by the specific color subclass - return BLACK.triplet; - } - - /** - * returns colon-delimited hex string "0:0:0" - * @return a hex string exactly like a gnumeric triplet - */ - - public String getHexString() - { - // this will be overridden by the specific color subclass - return BLACK.hexString; - } - - /** - * Checked type cast color to an HSSFColor. - * - * @param color the color to type cast - * @return the type casted color - * @throws IllegalArgumentException if color is null or is not an instance of HSSFColor - */ - public static HSSFColor toHSSFColor(Color color) { - // FIXME: this method would be more useful if it could convert any Color to an HSSFColor - // Currently the only benefit of this method is to throw an IllegalArgumentException - // instead of a ClassCastException. - if (color != null && !(color instanceof HSSFColor)) { - throw new IllegalArgumentException("Only HSSFColor objects are supported"); - } - return (HSSFColor)color; - } - - /** - * Class BLACK - * - */ - - public final static class BLACK - extends HSSFColor - { - public final static short index = 0x8; - public final static short[] triplet = - { - 0, 0, 0 - }; - public final static String hexString = "0:0:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class BROWN - * - */ - - public final static class BROWN - extends HSSFColor - { - public final static short index = 0x3c; - public final static short[] triplet = - { - 153, 51, 0 - }; - public final static String hexString = "9999:3333:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class OLIVE_GREEN - * - */ - - public static class OLIVE_GREEN - extends HSSFColor - { - public final static short index = 0x3b; - public final static short[] triplet = - { - 51, 51, 0 - }; - public final static String hexString = "3333:3333:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class DARK_GREEN - * - */ - - public final static class DARK_GREEN - extends HSSFColor - { - public final static short index = 0x3a; - public final static short[] triplet = - { - 0, 51, 0 - }; - public final static String hexString = "0:3333:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class DARK_TEAL - * - */ - - public final static class DARK_TEAL - extends HSSFColor - { - public final static short index = 0x38; - public final static short[] triplet = - { - 0, 51, 102 - }; - public final static String hexString = "0:3333:6666"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class DARK_BLUE - * - */ - - public final static class DARK_BLUE - extends HSSFColor - { - public final static short index = 0x12; - public final static short index2 = 0x20; - public final static short[] triplet = - { - 0, 0, 128 - }; - public final static String hexString = "0:0:8080"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class INDIGO - * - */ - - public final static class INDIGO - extends HSSFColor - { - public final static short index = 0x3e; - public final static short[] triplet = - { - 51, 51, 153 - }; - public final static String hexString = "3333:3333:9999"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class GREY_80_PERCENT - * - */ - - public final static class GREY_80_PERCENT - extends HSSFColor - { - public final static short index = 0x3f; - public final static short[] triplet = - { - 51, 51, 51 - }; - public final static String hexString = "3333:3333:3333"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class DARK_RED - * - */ - - public final static class DARK_RED - extends HSSFColor - { - public final static short index = 0x10; - public final static short index2 = 0x25; - public final static short[] triplet = - { - 128, 0, 0 - }; - public final static String hexString = "8080:0:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class ORANGE - * - */ - - public final static class ORANGE - extends HSSFColor - { - public final static short index = 0x35; - public final static short[] triplet = - { - 255, 102, 0 - }; - public final static String hexString = "FFFF:6666:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class DARK_YELLOW - * - */ - - public final static class DARK_YELLOW - extends HSSFColor - { - public final static short index = 0x13; - public final static short[] triplet = - { - 128, 128, 0 - }; - public final static String hexString = "8080:8080:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class GREEN - * - */ - - public final static class GREEN - extends HSSFColor - { - public final static short index = 0x11; - public final static short[] triplet = - { - 0, 128, 0 - }; - public final static String hexString = "0:8080:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class TEAL - * - */ - - public final static class TEAL - extends HSSFColor - { - public final static short index = 0x15; - public final static short index2 = 0x26; - public final static short[] triplet = - { - 0, 128, 128 - }; - public final static String hexString = "0:8080:8080"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class BLUE - * - */ - - public final static class BLUE - extends HSSFColor - { - public final static short index = 0xc; - public final static short index2 = 0x27; - public final static short[] triplet = - { - 0, 0, 255 - }; - public final static String hexString = "0:0:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class BLUE_GREY - * - */ - - public final static class BLUE_GREY - extends HSSFColor - { - public final static short index = 0x36; - public final static short[] triplet = - { - 102, 102, 153 - }; - public final static String hexString = "6666:6666:9999"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class GREY_50_PERCENT - * - */ - - public final static class GREY_50_PERCENT - extends HSSFColor - { - public final static short index = 0x17; - public final static short[] triplet = - { - 128, 128, 128 - }; - public final static String hexString = "8080:8080:8080"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class RED - * - */ - - public final static class RED - extends HSSFColor - { - public final static short index = 0xa; - public final static short[] triplet = - { - 255, 0, 0 - }; - public final static String hexString = "FFFF:0:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIGHT_ORANGE - * - */ - - public final static class LIGHT_ORANGE - extends HSSFColor - { - public final static short index = 0x34; - public final static short[] triplet = - { - 255, 153, 0 - }; - public final static String hexString = "FFFF:9999:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIME - * - */ - - public final static class LIME - extends HSSFColor - { - public final static short index = 0x32; - public final static short[] triplet = - { - 153, 204, 0 - }; - public final static String hexString = "9999:CCCC:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class SEA_GREEN - * - */ - - public final static class SEA_GREEN - extends HSSFColor - { - public final static short index = 0x39; - public final static short[] triplet = - { - 51, 153, 102 - }; - public final static String hexString = "3333:9999:6666"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class AQUA - * - */ - - public final static class AQUA - extends HSSFColor - { - public final static short index = 0x31; - public final static short[] triplet = - { - 51, 204, 204 - }; - public final static String hexString = "3333:CCCC:CCCC"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIGHT_BLUE - * - */ - - public final static class LIGHT_BLUE - extends HSSFColor - { - public final static short index = 0x30; - public final static short[] triplet = - { - 51, 102, 255 - }; - public final static String hexString = "3333:6666:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class VIOLET - * - */ - - public final static class VIOLET - extends HSSFColor - { - public final static short index = 0x14; - public final static short index2 = 0x24; - public final static short[] triplet = - { - 128, 0, 128 - }; - public final static String hexString = "8080:0:8080"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class GREY_40_PERCENT - * - */ - - public final static class GREY_40_PERCENT - extends HSSFColor - { - public final static short index = 0x37; - public final static short[] triplet = - { - 150, 150, 150 - }; - public final static String hexString = "9696:9696:9696"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class PINK - * - */ - - public final static class PINK - extends HSSFColor - { - public final static short index = 0xe; - public final static short index2 = 0x21; - public final static short[] triplet = - { - 255, 0, 255 - }; - public final static String hexString = "FFFF:0:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class GOLD - * - */ - - public final static class GOLD - extends HSSFColor - { - public final static short index = 0x33; - public final static short[] triplet = - { - 255, 204, 0 - }; - public final static String hexString = "FFFF:CCCC:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class YELLOW - * - */ - - public final static class YELLOW - extends HSSFColor - { - public final static short index = 0xd; - public final static short index2 = 0x22; - public final static short[] triplet = - { - 255, 255, 0 - }; - public final static String hexString = "FFFF:FFFF:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class BRIGHT_GREEN - * - */ - - public final static class BRIGHT_GREEN - extends HSSFColor - { - public final static short index = 0xb; - public final static short index2 = 0x23; - public final static short[] triplet = - { - 0, 255, 0 - }; - public final static String hexString = "0:FFFF:0"; - - public short getIndex() - { - return index; - } - - public String getHexString() - { - return hexString; - } - - public short [] getTriplet() - { - return triplet; - } - } - - /** - * Class TURQUOISE - * - */ - - public final static class TURQUOISE - extends HSSFColor - { - public final static short index = 0xf; - public final static short index2 = 0x23; - public final static short[] triplet = - { - 0, 255, 255 - }; - public final static String hexString = "0:FFFF:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class SKY_BLUE - * - */ - - public final static class SKY_BLUE - extends HSSFColor - { - public final static short index = 0x28; - public final static short[] triplet = - { - 0, 204, 255 - }; - public final static String hexString = "0:CCCC:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class PLUM - * - */ - - public final static class PLUM - extends HSSFColor - { - public final static short index = 0x3d; - public final static short index2 = 0x19; - public final static short[] triplet = - { - 153, 51, 102 - }; - public final static String hexString = "9999:3333:6666"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class GREY_25_PERCENT - * - */ - - public final static class GREY_25_PERCENT - extends HSSFColor - { - public final static short index = 0x16; - public final static short[] triplet = - { - 192, 192, 192 - }; - public final static String hexString = "C0C0:C0C0:C0C0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class ROSE - * - */ - - public final static class ROSE - extends HSSFColor - { - public final static short index = 0x2d; - public final static short[] triplet = - { - 255, 153, 204 - }; - public final static String hexString = "FFFF:9999:CCCC"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class TAN - * - */ - - public final static class TAN - extends HSSFColor - { - public final static short index = 0x2f; - public final static short[] triplet = - { - 255, 204, 153 - }; - public final static String hexString = "FFFF:CCCC:9999"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIGHT_YELLOW - * - */ - - public final static class LIGHT_YELLOW - extends HSSFColor - { - public final static short index = 0x2b; - public final static short[] triplet = - { - 255, 255, 153 - }; - public final static String hexString = "FFFF:FFFF:9999"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIGHT_GREEN - * - */ - - public final static class LIGHT_GREEN - extends HSSFColor - { - public final static short index = 0x2a; - public final static short[] triplet = - { - 204, 255, 204 - }; - public final static String hexString = "CCCC:FFFF:CCCC"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIGHT_TURQUOISE - * - */ - - public final static class LIGHT_TURQUOISE - extends HSSFColor - { - public final static short index = 0x29; - public final static short index2 = 0x1b; - public final static short[] triplet = - { - 204, 255, 255 - }; - public final static String hexString = "CCCC:FFFF:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class PALE_BLUE - * - */ - - public final static class PALE_BLUE - extends HSSFColor - { - public final static short index = 0x2c; - public final static short[] triplet = - { - 153, 204, 255 - }; - public final static String hexString = "9999:CCCC:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LAVENDER - * - */ - - public final static class LAVENDER - extends HSSFColor - { - public final static short index = 0x2e; - public final static short[] triplet = - { - 204, 153, 255 - }; - public final static String hexString = "CCCC:9999:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class WHITE - * - */ - - public final static class WHITE - extends HSSFColor - { - public final static short index = 0x9; - public final static short[] triplet = - { - 255, 255, 255 - }; - public final static String hexString = "FFFF:FFFF:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class CORNFLOWER_BLUE - */ - public final static class CORNFLOWER_BLUE - extends HSSFColor - { - public final static short index = 0x18; - public final static short[] triplet = - { - 153, 153, 255 - }; - public final static String hexString = "9999:9999:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - - /** - * Class LEMON_CHIFFON - */ - public final static class LEMON_CHIFFON - extends HSSFColor - { - public final static short index = 0x1a; - public final static short[] triplet = - { - 255, 255, 204 - }; - public final static String hexString = "FFFF:FFFF:CCCC"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class MAROON - */ - public final static class MAROON - extends HSSFColor - { - public final static short index = 0x19; - public final static short[] triplet = - { - 127, 0, 0 - }; - public final static String hexString = "8000:0:0"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class ORCHID - */ - public final static class ORCHID - extends HSSFColor - { - public final static short index = 0x1c; - public final static short[] triplet = - { - 102, 0, 102 - }; - public final static String hexString = "6666:0:6666"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class CORAL - */ - public final static class CORAL - extends HSSFColor - { - public final static short index = 0x1d; - public final static short[] triplet = - { - 255, 128, 128 - }; - public final static String hexString = "FFFF:8080:8080"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class ROYAL_BLUE - */ - public final static class ROYAL_BLUE - extends HSSFColor - { - public final static short index = 0x1e; - public final static short[] triplet = - { - 0, 102, 204 - }; - public final static String hexString = "0:6666:CCCC"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Class LIGHT_CORNFLOWER_BLUE - */ - public final static class LIGHT_CORNFLOWER_BLUE - extends HSSFColor - { - public final static short index = 0x1f; - public final static short[] triplet = - { - 204, 204, 255 - }; - public final static String hexString = "CCCC:CCCC:FFFF"; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return triplet; - } - - public String getHexString() - { - return hexString; - } - } - - /** - * Special Default/Normal/Automatic color. - *

    Note: This class is NOT in the default Map returned by HSSFColor. - * The index is a special case which is interpreted in the various setXXXColor calls. - * - * @author Jason - * - */ - public final static class AUTOMATIC extends HSSFColor - { - private static HSSFColor instance = new AUTOMATIC(); - - public final static short index = 0x40; - - public short getIndex() - { - return index; - } - - public short [] getTriplet() - { - return BLACK.triplet; - } - - public String getHexString() - { - return BLACK.hexString; - } - - public static HSSFColor getInstance() { - return instance; - } - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/HSSFRegionUtil.java b/trunk/src/java/org/apache/poi/hssf/util/HSSFRegionUtil.java deleted file mode 100644 index 826875a74..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/HSSFRegionUtil.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.util.RegionUtil; -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * Various utility functions that make working with a region of cells easier. - */ -public final class HSSFRegionUtil { - - private HSSFRegionUtil() { - // no instances of this class - } - - /** - * Sets the left border for a region of cells by manipulating the cell style - * of the individual cells on the left - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setBorderLeft(int border, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setBorderLeft(border, region, sheet, workbook); - } - - /** - * Sets the leftBorderColor attribute of the HSSFRegionUtil object - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setLeftBorderColor(int color, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setLeftBorderColor(color, region, sheet, workbook); - } - - /** - * Sets the borderRight attribute of the HSSFRegionUtil object - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setBorderRight(int border, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setBorderRight(border, region, sheet, workbook); - } - - /** - * Sets the rightBorderColor attribute of the HSSFRegionUtil object - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setRightBorderColor(int color, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setRightBorderColor(color, region, sheet, workbook); - } - - /** - * Sets the borderBottom attribute of the HSSFRegionUtil object - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setBorderBottom(int border, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setBorderBottom(border, region, sheet, workbook); - } - - /** - * Sets the bottomBorderColor attribute of the HSSFRegionUtil object - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setBottomBorderColor(int color, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setBottomBorderColor(color, region, sheet, workbook); - } - - /** - * Sets the borderBottom attribute of the HSSFRegionUtil object - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setBorderTop(int border, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setBorderTop(border, region, sheet, workbook); - } - - /** - * Sets the topBorderColor attribute of the HSSFRegionUtil object - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - */ - public static void setTopBorderColor(int color, CellRangeAddress region, HSSFSheet sheet, - HSSFWorkbook workbook) { - RegionUtil.setTopBorderColor(color, region, sheet, workbook); - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/LazilyConcatenatedByteArray.java b/trunk/src/java/org/apache/poi/hssf/util/LazilyConcatenatedByteArray.java deleted file mode 100644 index e7ca949e7..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/LazilyConcatenatedByteArray.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -import java.util.ArrayList; -import java.util.List; - -/** - * Utility for delaying the concatenation of multiple byte arrays. Doing this up-front - * causes significantly more copying, which for a large number of byte arrays can cost - * a large amount of time. - */ -public class LazilyConcatenatedByteArray { - private final List arrays = new ArrayList(1); - - /** - * Clears the array (sets the concatenated length back to zero. - */ - public void clear() { - arrays.clear(); - } - - /** - * Concatenates an array onto the end of our array. - * This is a relatively fast operation. - * - * @param array the array to concatenate. - * @throws IllegalArgumentException if {@code array} is {@code null}. - */ - public void concatenate(byte[] array) { - if (array == null) { - throw new IllegalArgumentException("array cannot be null"); - } - arrays.add(array); - } - - /** - * Gets the concatenated contents as a single byte array. - * - * This is a slower operation, but the concatenated array is stored off as a single - * array again so that subsequent calls will not perform additional copying. - * - * @return the byte array. Returns {@code null} if no data has been placed into it. - */ - public byte[] toArray() { - if (arrays.isEmpty()) { - return null; - } else if (arrays.size() > 1) { - int totalLength = 0; - for (byte[] array : arrays) { - totalLength += array.length; - } - - byte[] concatenated = new byte[totalLength]; - int destPos = 0; - for (byte[] array : arrays) { - System.arraycopy(array, 0, concatenated, destPos, array.length); - destPos += array.length; - } - - arrays.clear(); - arrays.add(concatenated); - } - - return arrays.get(0); - } -} - diff --git a/trunk/src/java/org/apache/poi/hssf/util/PaneInformation.java b/trunk/src/java/org/apache/poi/hssf/util/PaneInformation.java deleted file mode 100644 index d0382961e..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/PaneInformation.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -/** - * Holds information regarding a split plane or freeze plane for a sheet. - * @deprecated POI 3.15 beta 3. Use {@link org.apache.poi.ss.util.PaneInformation} instead. - */ -public class PaneInformation extends org.apache.poi.ss.util.PaneInformation -{ - public PaneInformation(short x, short y, short top, short left, byte active, boolean frozen) { - super(x, y, top, left, active, frozen); - } - -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/RKUtil.java b/trunk/src/java/org/apache/poi/hssf/util/RKUtil.java deleted file mode 100644 index 42cdd379b..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/RKUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -/** - * Utility class for helping convert RK numbers. - * - * @see org.apache.poi.hssf.record.MulRKRecord - * @see org.apache.poi.hssf.record.RKRecord - */ -public final class RKUtil { - private RKUtil() { - // no instances of this class - } - - /** - * Do the dirty work of decoding; made a private static method to - * facilitate testing the algorithm - */ - public static double decodeNumber(int number) { - long raw_number = number; - - // mask off the two low-order bits, 'cause they're not part of - // the number - raw_number = raw_number >> 2; - double rvalue = 0; - - if ((number & 0x02) == 0x02) - { - // ok, it's just a plain ol' int; we can handle this - // trivially by casting - rvalue = raw_number; - } - else - { - - // also trivial, but not as obvious ... left shift the - // bits high and use that clever static method in Double - // to convert the resulting bit image to a double - rvalue = Double.longBitsToDouble(raw_number << 34); - } - if ((number & 0x01) == 0x01) - { - - // low-order bit says divide by 100, and so we do. Why? - // 'cause that's what the algorithm says. Can't fight city - // hall, especially if it's the city of Redmond - rvalue /= 100; - } - - return rvalue; - } -} diff --git a/trunk/src/java/org/apache/poi/hssf/util/package.html b/trunk/src/java/org/apache/poi/hssf/util/package.html deleted file mode 100644 index 7936e88f2..000000000 --- a/trunk/src/java/org/apache/poi/hssf/util/package.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - -util package contains tools needed for writing HSSF files that are not necesarily "real" -HSSF concepts. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java b/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java deleted file mode 100644 index 1e8b1b113..000000000 --- a/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java +++ /dev/null @@ -1,64 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.common; - -import org.apache.poi.util.LittleEndianConsts; - -/** - *

    A class describing attributes of the Big Block Size

    - */ -public final class POIFSBigBlockSize -{ - private int bigBlockSize; - private short headerValue; - - protected POIFSBigBlockSize(int bigBlockSize, short headerValue) { - this.bigBlockSize = bigBlockSize; - this.headerValue = headerValue; - } - - public int getBigBlockSize() { - return bigBlockSize; - } - - /** - * Returns the value that gets written into the - * header. - * Is the power of two that corresponds to the - * size of the block, eg 512 => 9 - */ - public short getHeaderValue() { - return headerValue; - } - - public int getPropertiesPerBlock() { - return bigBlockSize / POIFSConstants.PROPERTY_SIZE; - } - - public int getBATEntriesPerBlock() { - return bigBlockSize / LittleEndianConsts.INT_SIZE; - } - public int getXBATEntriesPerBlock() { - return getBATEntriesPerBlock() - 1; - } - public int getNextXBATChainOffset() { - return getXBATEntriesPerBlock() * LittleEndianConsts.INT_SIZE; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java b/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java deleted file mode 100644 index 1cc5d038d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java +++ /dev/null @@ -1,67 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.common; - -/** - *

    A repository for constants shared by POI classes.

    - */ -public interface POIFSConstants -{ - /** Most files use 512 bytes as their big block size */ - public static final int SMALLER_BIG_BLOCK_SIZE = 0x0200; - public static final POIFSBigBlockSize SMALLER_BIG_BLOCK_SIZE_DETAILS = - new POIFSBigBlockSize(SMALLER_BIG_BLOCK_SIZE, (short)9); - /** Some use 4096 bytes */ - public static final int LARGER_BIG_BLOCK_SIZE = 0x1000; - public static final POIFSBigBlockSize LARGER_BIG_BLOCK_SIZE_DETAILS = - new POIFSBigBlockSize(LARGER_BIG_BLOCK_SIZE, (short)12); - - /** How big a block in the small block stream is. Fixed size */ - public static final int SMALL_BLOCK_SIZE = 0x0040; - - /** How big a single property is */ - public static final int PROPERTY_SIZE = 0x0080; - - /** - * The minimum size of a document before it's stored using - * Big Blocks (normal streams). Smaller documents go in the - * Mini Stream (SBAT / Small Blocks) - */ - public static final int BIG_BLOCK_MINIMUM_DOCUMENT_SIZE = 0x1000; - - /** The highest sector number you're allowed, 0xFFFFFFFA */ - public static final int LARGEST_REGULAR_SECTOR_NUMBER = -5; - - /** Indicates the sector holds a DIFAT block (0xFFFFFFFC) */ - public static final int DIFAT_SECTOR_BLOCK = -4; - /** Indicates the sector holds a FAT block (0xFFFFFFFD) */ - public static final int FAT_SECTOR_BLOCK = -3; - /** Indicates the sector is the end of a chain (0xFFFFFFFE) */ - public static final int END_OF_CHAIN = -2; - /** Indicates the sector is not used (0xFFFFFFFF) */ - public static final int UNUSED_BLOCK = -1; - - /** The first 4 bytes of an OOXML file, used in detection */ - public static final byte[] OOXML_FILE_HEADER = - new byte[] { 0x50, 0x4b, 0x03, 0x04 }; - /** The first 5 bytes of a raw XML file, used in detection */ - public static final byte[] RAW_XML_FILE_HEADER = - new byte[] { 0x3c, 0x3f, 0x78, 0x6d, 0x6c }; -} // end public interface POIFSConstants; diff --git a/trunk/src/java/org/apache/poi/poifs/common/package.html b/trunk/src/java/org/apache/poi/poifs/common/package.html deleted file mode 100644 index da2edf195..000000000 --- a/trunk/src/java/org/apache/poi/poifs/common/package.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - -common package contains constants and other classes shared across all POIFS subpackages - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java b/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java deleted file mode 100644 index 7fccccfb2..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/ChainingMode.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -public enum ChainingMode { - // ecb - only for standard encryption - ecb("ECB", 1), - cbc("CBC", 2), - /* Cipher feedback chaining (CFB), with an 8-bit window */ - cfb("CFB8", 3); - - public final String jceId; - public final int ecmaId; - ChainingMode(String jceId, int ecmaId) { - this.jceId = jceId; - this.ecmaId = ecmaId; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java b/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java deleted file mode 100644 index db3d724e4..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java +++ /dev/null @@ -1,277 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.ShortBufferException; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndianInputStream; - -@Internal -public abstract class ChunkedCipherInputStream extends LittleEndianInputStream { - private final int chunkSize; - private final int chunkBits; - - private final long size; - private final byte[] chunk, plain; - private final Cipher cipher; - - private int lastIndex; - private long pos; - private boolean chunkIsValid = false; - - public ChunkedCipherInputStream(InputStream stream, long size, int chunkSize) - throws GeneralSecurityException { - this(stream, size, chunkSize, 0); - } - - public ChunkedCipherInputStream(InputStream stream, long size, int chunkSize, int initialPos) - throws GeneralSecurityException { - super(stream); - this.size = size; - this.pos = initialPos; - this.chunkSize = chunkSize; - int cs = chunkSize == -1 ? 4096 : chunkSize; - this.chunk = new byte[cs]; - this.plain = new byte[cs]; - this.chunkBits = Integer.bitCount(chunk.length-1); - this.lastIndex = (int)(pos >> chunkBits); - this.cipher = initCipherForBlock(null, lastIndex); - } - - public final Cipher initCipherForBlock(int block) throws IOException, GeneralSecurityException { - if (chunkSize != -1) { - throw new GeneralSecurityException("the cipher block can only be set for streaming encryption, e.g. CryptoAPI..."); - } - - chunkIsValid = false; - return initCipherForBlock(cipher, block); - } - - protected abstract Cipher initCipherForBlock(Cipher existing, int block) - throws GeneralSecurityException; - - @Override - public int read() throws IOException { - byte[] b = new byte[1]; - if (read(b) == 1) { - return b[0]; - } - return -1; - } - - // do not implement! -> recursion - // public int read(byte[] b) throws IOException; - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return read(b, off, len, false); - } - - private int read(byte[] b, int off, int len, boolean readPlain) throws IOException { - int total = 0; - - if (available() <= 0) { - return -1; - } - - final int chunkMask = getChunkMask(); - while (len > 0) { - if (!chunkIsValid) { - try { - nextChunk(); - chunkIsValid = true; - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e.getMessage(), e); - } - } - int count = (int)(chunk.length - (pos & chunkMask)); - int avail = available(); - if (avail == 0) { - return total; - } - count = Math.min(avail, Math.min(count, len)); - - System.arraycopy(readPlain ? plain : chunk, (int)(pos & chunkMask), b, off, count); - - off += count; - len -= count; - pos += count; - if ((pos & chunkMask) == 0) { - chunkIsValid = false; - } - total += count; - } - - return total; - } - - @Override - public long skip(final long n) throws IOException { - long start = pos; - long skip = Math.min(remainingBytes(), n); - - if ((((pos + skip) ^ start) & ~getChunkMask()) != 0) { - chunkIsValid = false; - } - pos += skip; - return skip; - } - - @Override - public int available() { - return remainingBytes(); - } - - /** - * Helper method for forbidden available call - we know the size beforehand, so it's ok ... - * - * @return the remaining byte until EOF - */ - private int remainingBytes() { - return (int)(size - pos); - } - - @Override - public boolean markSupported() { - return false; - } - - @Override - public synchronized void mark(int readlimit) { - throw new UnsupportedOperationException(); - } - - @Override - public synchronized void reset() throws IOException { - throw new UnsupportedOperationException(); - } - - protected int getChunkMask() { - return chunk.length-1; - } - - private void nextChunk() throws GeneralSecurityException, IOException { - if (chunkSize != -1) { - int index = (int)(pos >> chunkBits); - initCipherForBlock(cipher, index); - - if (lastIndex != index) { - super.skip((index - lastIndex) << chunkBits); - } - - lastIndex = index + 1; - } - - final int todo = (int)Math.min(size, chunk.length); - int readBytes = 0, totalBytes = 0; - do { - readBytes = super.read(plain, totalBytes, todo-totalBytes); - totalBytes += Math.max(0, readBytes); - } while (readBytes != -1 && totalBytes < todo); - - if (readBytes == -1 && pos+totalBytes < size && size < Integer.MAX_VALUE) { - throw new EOFException("buffer underrun"); - } - - System.arraycopy(plain, 0, chunk, 0, totalBytes); - - invokeCipher(totalBytes, totalBytes == chunkSize); - } - - /** - * Helper function for overriding the cipher invocation, i.e. XOR doesn't use a cipher - * and uses it's own implementation - * - * @throws BadPaddingException - * @throws IllegalBlockSizeException - * @throws ShortBufferException - */ - protected int invokeCipher(int totalBytes, boolean doFinal) throws GeneralSecurityException { - if (doFinal) { - return cipher.doFinal(chunk, 0, totalBytes, chunk); - } else { - return cipher.update(chunk, 0, totalBytes, chunk); - } - } - - /** - * Used when BIFF header fields (sid, size) are being read. The internal - * {@link Cipher} instance must step even when unencrypted bytes are read - * - */ - @Override - public void readPlain(byte b[], int off, int len) { - if (len <= 0) { - return; - } - - try { - int readBytes, total = 0; - do { - readBytes = read(b, off, len, true); - total += Math.max(0, readBytes); - } while (readBytes > -1 && total < len); - - if (total < len) { - throw new EOFException("buffer underrun"); - } - } catch (IOException e) { - // need to wrap checked exception, because of LittleEndianInput interface :( - throw new RuntimeException(e); - } - } - - /** - * Some ciphers (actually just XOR) are based on the record size, - * which needs to be set before decryption - * - * @param recordSize the size of the next record - */ - public void setNextRecordSize(int recordSize) { - } - - /** - * @return the chunk bytes - */ - protected byte[] getChunk() { - return chunk; - } - - /** - * @return the plain bytes - */ - protected byte[] getPlain() { - return plain; - } - - /** - * @return the absolute position in the stream - */ - public long getPos() { - return pos; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java b/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java deleted file mode 100644 index a8e920dc1..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java +++ /dev/null @@ -1,297 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.apache.poi.poifs.crypt.Decryptor.DEFAULT_POIFS_ENTRY; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.util.BitSet; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.ShortBufferException; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.POIFSWriterEvent; -import org.apache.poi.poifs.filesystem.POIFSWriterListener; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; - -@Internal -public abstract class ChunkedCipherOutputStream extends FilterOutputStream { - private static final POILogger LOG = POILogFactory.getLogger(ChunkedCipherOutputStream.class); - private static final int STREAMING = -1; - - private final int chunkSize; - private final int chunkBits; - - private final byte[] chunk; - private final BitSet plainByteFlags; - private final File fileOut; - private final DirectoryNode dir; - - private long pos = 0; - private long totalPos = 0; - private long written = 0; - - // the cipher can't be final, because for the last chunk we change the padding - // and therefore need to change the cipher too - private Cipher cipher; - - public ChunkedCipherOutputStream(DirectoryNode dir, int chunkSize) throws IOException, GeneralSecurityException { - super(null); - this.chunkSize = chunkSize; - int cs = chunkSize == STREAMING ? 4096 : chunkSize; - this.chunk = new byte[cs]; - this.plainByteFlags = new BitSet(cs); - this.chunkBits = Integer.bitCount(cs-1); - this.fileOut = TempFile.createTempFile("encrypted_package", "crypt"); - this.fileOut.deleteOnExit(); - this.out = new FileOutputStream(fileOut); - this.dir = dir; - this.cipher = initCipherForBlock(null, 0, false); - } - - public ChunkedCipherOutputStream(OutputStream stream, int chunkSize) throws IOException, GeneralSecurityException { - super(stream); - this.chunkSize = chunkSize; - int cs = chunkSize == STREAMING ? 4096 : chunkSize; - this.chunk = new byte[cs]; - this.plainByteFlags = new BitSet(cs); - this.chunkBits = Integer.bitCount(cs-1); - this.fileOut = null; - this.dir = null; - this.cipher = initCipherForBlock(null, 0, false); - } - - public final Cipher initCipherForBlock(int block, boolean lastChunk) throws IOException, GeneralSecurityException { - return initCipherForBlock(cipher, block, lastChunk); - } - - protected abstract Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk) - throws IOException, GeneralSecurityException; - - protected abstract void calculateChecksum(File fileOut, int oleStreamSize) - throws GeneralSecurityException, IOException; - - protected abstract void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) - throws IOException, GeneralSecurityException; - - @Override - public void write(int b) throws IOException { - write(new byte[]{(byte)b}); - } - - @Override - public void write(byte[] b) throws IOException { - write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - write(b, off, len, false); - } - - public void writePlain(byte[] b, int off, int len) throws IOException { - write(b, off, len, true); - } - - protected void write(byte[] b, int off, int len, boolean writePlain) throws IOException { - if (len == 0) { - return; - } - - if (len < 0 || b.length < off+len) { - throw new IOException("not enough bytes in your input buffer"); - } - - final int chunkMask = getChunkMask(); - while (len > 0) { - int posInChunk = (int)(pos & chunkMask); - int nextLen = Math.min(chunk.length-posInChunk, len); - System.arraycopy(b, off, chunk, posInChunk, nextLen); - if (writePlain) { - plainByteFlags.set(posInChunk, posInChunk+nextLen); - } - pos += nextLen; - totalPos += nextLen; - off += nextLen; - len -= nextLen; - if ((pos & chunkMask) == 0) { - writeChunk(len > 0); - } - } - } - - protected int getChunkMask() { - return chunk.length-1; - } - - protected void writeChunk(boolean continued) throws IOException { - if (pos == 0 || totalPos == written) { - return; - } - - int posInChunk = (int)(pos & getChunkMask()); - - // normally posInChunk is 0, i.e. on the next chunk (-> index-1) - // but if called on close(), posInChunk is somewhere within the chunk data - int index = (int)(pos >> chunkBits); - boolean lastChunk; - if (posInChunk==0) { - index--; - posInChunk = chunk.length; - lastChunk = false; - } else { - // pad the last chunk - lastChunk = true; - } - - int ciLen; - try { - boolean doFinal = true; - long oldPos = pos; - // reset stream (not only) in case we were interrupted by plain stream parts - // this also needs to be set to prevent an endless loop - pos = 0; - if (chunkSize == STREAMING) { - if (continued) { - doFinal = false; - } - } else { - cipher = initCipherForBlock(cipher, index, lastChunk); - // restore pos - only streaming chunks will be reset - pos = oldPos; - } - ciLen = invokeCipher(posInChunk, doFinal); - } catch (GeneralSecurityException e) { - throw new IOException("can't re-/initialize cipher", e); - } - - out.write(chunk, 0, ciLen); - plainByteFlags.clear(); - written += ciLen; - } - - /** - * Helper function for overriding the cipher invocation, i.e. XOR doesn't use a cipher - * and uses it's own implementation - * - * @throws BadPaddingException - * @throws IllegalBlockSizeException - * @throws ShortBufferException - */ - protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException { - byte plain[] = (plainByteFlags.isEmpty()) ? null : chunk.clone(); - - int ciLen = (doFinal) - ? cipher.doFinal(chunk, 0, posInChunk, chunk) - : cipher.update(chunk, 0, posInChunk, chunk); - - for (int i = plainByteFlags.nextSetBit(0); i >= 0 && i < posInChunk; i = plainByteFlags.nextSetBit(i+1)) { - chunk[i] = plain[i]; - } - - return ciLen; - } - - @Override - public void close() throws IOException { - try { - writeChunk(false); - - super.close(); - - if (fileOut != null) { - int oleStreamSize = (int)(fileOut.length()+LittleEndianConsts.LONG_SIZE); - calculateChecksum(fileOut, (int)pos); - dir.createDocument(DEFAULT_POIFS_ENTRY, oleStreamSize, new EncryptedPackageWriter()); - createEncryptionInfoEntry(dir, fileOut); - } - } catch (GeneralSecurityException e) { - throw new IOException(e); - } - } - - protected byte[] getChunk() { - return chunk; - } - - protected BitSet getPlainByteFlags() { - return plainByteFlags; - } - - protected long getPos() { - return pos; - } - - protected long getTotalPos() { - return totalPos; - } - - /** - * Some ciphers (actually just XOR) are based on the record size, - * which needs to be set before encryption - * - * @param recordSize the size of the next record - * @param isPlain {@code true} if the record is unencrypted - */ - public void setNextRecordSize(int recordSize, boolean isPlain) { - } - - private class EncryptedPackageWriter implements POIFSWriterListener { - @Override - public void processPOIFSWriterEvent(POIFSWriterEvent event) { - try { - OutputStream os = event.getStream(); - - // StreamSize (8 bytes): An unsigned integer that specifies the number of bytes used by data - // encrypted within the EncryptedData field, not including the size of the StreamSize field. - // Note that the actual size of the \EncryptedPackage stream (1) can be larger than this - // value, depending on the block size of the chosen encryption algorithm - byte buf[] = new byte[LittleEndianConsts.LONG_SIZE]; - LittleEndian.putLong(buf, 0, pos); - os.write(buf); - - FileInputStream fis = new FileInputStream(fileOut); - IOUtils.copy(fis, os); - fis.close(); - - os.close(); - - if (!fileOut.delete()) { - LOG.log(POILogger.ERROR, "Can't delete temporary encryption file: "+fileOut); - } - } catch (IOException e) { - throw new EncryptedDocumentException(e); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/CipherAlgorithm.java b/trunk/src/java/org/apache/poi/poifs/crypt/CipherAlgorithm.java deleted file mode 100644 index c5887354d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/CipherAlgorithm.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import org.apache.poi.EncryptedDocumentException; - -public enum CipherAlgorithm { - // key size for rc4: 0x00000028 - 0x00000080 (inclusive) with 8-bit increments - // no block size, because its a streaming cipher - rc4(CipherProvider.rc4, "RC4", 0x6801, 0x40, new int[]{0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80}, -1, 20, "RC4", false), - // aes has always a block size of 128 - only its keysize may vary - aes128(CipherProvider.aes, "AES", 0x660E, 128, new int[]{128}, 16, 32, "AES", false), - aes192(CipherProvider.aes, "AES", 0x660F, 192, new int[]{192}, 16, 32, "AES", false), - aes256(CipherProvider.aes, "AES", 0x6610, 256, new int[]{256}, 16, 32, "AES", false), - rc2(null, "RC2", -1, 0x80, new int[]{0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80}, 8, 20, "RC2", false), - des(null, "DES", -1, 64, new int[]{64}, 8/*for 56-bit*/, 32, "DES", false), - // desx is not supported. Not sure, if it can be simulated by des3 somehow - des3(null, "DESede", -1, 192, new int[]{192}, 8, 32, "3DES", false), - // need bouncycastle provider for this one ... - // see http://stackoverflow.com/questions/4436397/3des-des-encryption-using-the-jce-generating-an-acceptable-key - des3_112(null, "DESede", -1, 128, new int[]{128}, 8, 32, "3DES_112", true), - // only for digital signatures - rsa(null, "RSA", -1, 1024, new int[]{1024, 2048, 3072, 4096}, -1, -1, "", false); - - public final CipherProvider provider; - public final String jceId; - public final int ecmaId; - public final int defaultKeySize; - public final int allowedKeySize[]; - public final int blockSize; - public final int encryptedVerifierHashLength; - public final String xmlId; - public final boolean needsBouncyCastle; - - CipherAlgorithm(CipherProvider provider, String jceId, int ecmaId, int defaultKeySize, int allowedKeySize[], int blockSize, int encryptedVerifierHashLength, String xmlId, boolean needsBouncyCastle) { - this.provider = provider; - this.jceId = jceId; - this.ecmaId = ecmaId; - this.defaultKeySize = defaultKeySize; - this.allowedKeySize = allowedKeySize.clone(); - this.blockSize = blockSize; - this.encryptedVerifierHashLength = encryptedVerifierHashLength; - this.xmlId = xmlId; - this.needsBouncyCastle = needsBouncyCastle; - } - - public static CipherAlgorithm fromEcmaId(int ecmaId) { - for (CipherAlgorithm ca : CipherAlgorithm.values()) { - if (ca.ecmaId == ecmaId) return ca; - } - throw new EncryptedDocumentException("cipher algorithm " + ecmaId + " not found"); - } - - public static CipherAlgorithm fromXmlId(String xmlId, int keySize) { - for (CipherAlgorithm ca : CipherAlgorithm.values()) { - if (!ca.xmlId.equals(xmlId)) continue; - for (int ks : ca.allowedKeySize) { - if (ks == keySize) return ca; - } - } - throw new EncryptedDocumentException("cipher algorithm " + xmlId + "/" + keySize + " not found"); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/CipherProvider.java b/trunk/src/java/org/apache/poi/poifs/crypt/CipherProvider.java deleted file mode 100644 index 5ffe1d33a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/CipherProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import org.apache.poi.EncryptedDocumentException; - -public enum CipherProvider { - rc4("RC4", 1, "Microsoft Base Cryptographic Provider v1.0"), - aes("AES", 0x18, "Microsoft Enhanced RSA and AES Cryptographic Provider"); - - public static CipherProvider fromEcmaId(int ecmaId) { - for (CipherProvider cp : CipherProvider.values()) { - if (cp.ecmaId == ecmaId) return cp; - } - throw new EncryptedDocumentException("cipher provider not found"); - } - - public final String jceId; - public final int ecmaId; - public final String cipherProviderName; - CipherProvider(String jceId, int ecmaId, String cipherProviderName) { - this.jceId = jceId; - this.ecmaId = ecmaId; - this.cipherProviderName = cipherProviderName; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java b/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java deleted file mode 100644 index b35d2c59c..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java +++ /dev/null @@ -1,576 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import java.nio.charset.Charset; -import java.security.DigestException; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.MessageDigest; -import java.security.Provider; -import java.security.Security; -import java.security.spec.AlgorithmParameterSpec; -import java.util.Arrays; -import java.util.Locale; - -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.RC2ParameterSpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.StringUtil; - -/** - * Helper functions used for standard and agile encryption - */ -@Internal -public class CryptoFunctions { - /** - *

    2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)
    - * 2.3.4.11 Encryption Key Generation (Agile Encryption)

    - * - *

    The encryption key for ECMA-376 document encryption [ECMA-376] using agile - * encryption MUST be generated by using the following method, which is derived from PKCS #5: - * Password-Based Cryptography Version 2.0 [RFC2898].

    - * - *

    Let H() be a hashing algorithm as determined by the PasswordKeyEncryptor.hashAlgorithm - * element, H_n be the hash data of the n-th iteration, and a plus sign (+) represent concatenation. - * The password MUST be provided as an array of Unicode characters. Limitations on the length of the - * password and the characters used by the password are implementation-dependent. - * The initial password hash is generated as follows:

    - * - * - *
    H_0 = H(salt + password)
    - * - *

    The salt used MUST be generated randomly. The salt MUST be stored in the - * PasswordKeyEncryptor.saltValue element contained within the \EncryptionInfo stream as - * specified in section 2.3.4.10. The hash is then iterated by using the following approach:

    - * - *
    H_n = H(iterator + H_n-1)
    - * - *

    where iterator is an unsigned 32-bit value that is initially set to 0x00000000 and then incremented - * monotonically on each iteration until PasswordKey.spinCount iterations have been performed. - * The value of iterator on the last iteration MUST be one less than PasswordKey.spinCount.

    - * - *

    For POI, H_final will be calculated by {@link #generateKey(byte[],HashAlgorithm,byte[],int)}

    - * - * @param password - * @param hashAlgorithm - * @param salt - * @param spinCount - * @return the hashed password - */ - public static byte[] hashPassword(String password, HashAlgorithm hashAlgorithm, byte salt[], int spinCount) { - return hashPassword(password, hashAlgorithm, salt, spinCount, true); - } - - /** - * Generalized method for read and write protection hash generation. - * The difference is, read protection uses the order iterator then hash in the hash loop, whereas write protection - * uses first the last hash value and then the current iterator value - * - * @param password - * @param hashAlgorithm - * @param salt - * @param spinCount - * @param iteratorFirst if true, the iterator is hashed before the n-1 hash value, - * if false the n-1 hash value is applied first - * @return the hashed password - */ - public static byte[] hashPassword(String password, HashAlgorithm hashAlgorithm, byte salt[], int spinCount, boolean iteratorFirst) { - // If no password was given, use the default - if (password == null) { - password = Decryptor.DEFAULT_PASSWORD; - } - - MessageDigest hashAlg = getMessageDigest(hashAlgorithm); - - hashAlg.update(salt); - byte[] hash = hashAlg.digest(StringUtil.getToUnicodeLE(password)); - byte[] iterator = new byte[LittleEndianConsts.INT_SIZE]; - - byte[] first = (iteratorFirst ? iterator : hash); - byte[] second = (iteratorFirst ? hash : iterator); - - try { - for (int i = 0; i < spinCount; i++) { - LittleEndian.putInt(iterator, 0, i); - hashAlg.reset(); - hashAlg.update(first); - hashAlg.update(second); - hashAlg.digest(hash, 0, hash.length); // don't create hash buffer everytime new - } - } catch (DigestException e) { - throw new EncryptedDocumentException("error in password hashing"); - } - - return hash; - } - - /** - *

    2.3.4.12 Initialization Vector Generation (Agile Encryption)

    - * - *

    Initialization vectors are used in all cases for agile encryption. An initialization vector MUST be - * generated by using the following method, where H() is a hash function that MUST be the same as - * specified in section 2.3.4.11 and a plus sign (+) represents concatenation:

    - *
      - *
    • If a blockKey is provided, let IV be a hash of the KeySalt and the following value:
      - * {@code blockKey: IV = H(KeySalt + blockKey)}
    • - *
    • If a blockKey is not provided, let IV be equal to the following value:
      - * {@code KeySalt:IV = KeySalt}
    • - *
    • If the number of bytes in the value of IV is less than the the value of the blockSize attribute - * corresponding to the cipherAlgorithm attribute, pad the array of bytes by appending 0x36 until - * the array is blockSize bytes. If the array of bytes is larger than blockSize bytes, truncate the - * array to blockSize bytes.
    • - *
    - **/ - public static byte[] generateIv(HashAlgorithm hashAlgorithm, byte[] salt, byte[] blockKey, int blockSize) { - byte iv[] = salt; - if (blockKey != null) { - MessageDigest hashAlgo = getMessageDigest(hashAlgorithm); - hashAlgo.update(salt); - iv = hashAlgo.digest(blockKey); - } - return getBlock36(iv, blockSize); - } - - /** - *

    2.3.4.11 Encryption Key Generation (Agile Encryption)

    - * - *

    The final hash data that is used for an encryption key is then generated by using the following - * method:

    - * - *
    H_final = H(H_n + blockKey)
    - * - *

    where blockKey represents an array of bytes used to prevent two different blocks from encrypting - * to the same cipher text.

    - * - *

    If the size of the resulting H_final is smaller than that of PasswordKeyEncryptor.keyBits, the key - * MUST be padded by appending bytes with a value of 0x36. If the hash value is larger in size than - * PasswordKeyEncryptor.keyBits, the key is obtained by truncating the hash value.

    - * - * @param passwordHash - * @param hashAlgorithm - * @param blockKey - * @param keySize - * @return intermediate key - */ - public static byte[] generateKey(byte[] passwordHash, HashAlgorithm hashAlgorithm, byte[] blockKey, int keySize) { - MessageDigest hashAlgo = getMessageDigest(hashAlgorithm); - hashAlgo.update(passwordHash); - byte[] key = hashAlgo.digest(blockKey); - return getBlock36(key, keySize); - } - - /** - * Initialize a new cipher object with the given cipher properties and no padding - * If the given algorithm is not implemented in the JCE, it will try to load it from the bouncy castle - * provider. - * - * @param key the secrect key - * @param cipherAlgorithm the cipher algorithm - * @param chain the chaining mode - * @param vec the initialization vector (IV), can be null - * @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE - * @return the requested cipher - * @throws GeneralSecurityException - * @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified, - * which depends on a missing bouncy castle provider - */ - public static Cipher getCipher(SecretKey key, CipherAlgorithm cipherAlgorithm, ChainingMode chain, byte[] vec, int cipherMode) { - return getCipher(key, cipherAlgorithm, chain, vec, cipherMode, null); - } - - /** - * Initialize a new cipher object with the given cipher properties - * If the given algorithm is not implemented in the JCE, it will try to load it from the bouncy castle - * provider. - * - * @param key the secrect key - * @param cipherAlgorithm the cipher algorithm - * @param chain the chaining mode - * @param vec the initialization vector (IV), can be null - * @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE - * @param padding the padding (null = NOPADDING, ANSIX923Padding, PKCS5Padding, PKCS7Padding, ISO10126Padding, ...) - * @return the requested cipher - * @throws GeneralSecurityException - * @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified, - * which depends on a missing bouncy castle provider - */ - public static Cipher getCipher(Key key, CipherAlgorithm cipherAlgorithm, ChainingMode chain, byte[] vec, int cipherMode, String padding) { - int keySizeInBytes = key.getEncoded().length; - if (padding == null) padding = "NoPadding"; - - try { - // Ensure the JCE policies files allow for this sized key - if (Cipher.getMaxAllowedKeyLength(cipherAlgorithm.jceId) < keySizeInBytes*8) { - throw new EncryptedDocumentException("Export Restrictions in place - please install JCE Unlimited Strength Jurisdiction Policy files"); - } - - Cipher cipher; - if (cipherAlgorithm == CipherAlgorithm.rc4) { - cipher = Cipher.getInstance(cipherAlgorithm.jceId); - } else if (cipherAlgorithm.needsBouncyCastle) { - registerBouncyCastle(); - cipher = Cipher.getInstance(cipherAlgorithm.jceId + "/" + chain.jceId + "/" + padding, "BC"); - } else { - cipher = Cipher.getInstance(cipherAlgorithm.jceId + "/" + chain.jceId + "/" + padding); - } - - if (vec == null) { - cipher.init(cipherMode, key); - } else { - AlgorithmParameterSpec aps; - if (cipherAlgorithm == CipherAlgorithm.rc2) { - aps = new RC2ParameterSpec(key.getEncoded().length*8, vec); - } else { - aps = new IvParameterSpec(vec); - } - cipher.init(cipherMode, key, aps); - } - return cipher; - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e); - } - } - - /** - * Returns a new byte array with a truncated to the given size. - * If the hash has less then size bytes, it will be filled with 0x36-bytes - * - * @param hash the to be truncated/filled hash byte array - * @param size the size of the returned byte array - * @return the padded hash - */ - private static byte[] getBlock36(byte[] hash, int size) { - return getBlockX(hash, size, (byte)0x36); - } - - /** - * Returns a new byte array with a truncated to the given size. - * If the hash has less then size bytes, it will be filled with 0-bytes - * - * @param hash the to be truncated/filled hash byte array - * @param size the size of the returned byte array - * @return the padded hash - */ - public static byte[] getBlock0(byte[] hash, int size) { - return getBlockX(hash, size, (byte)0); - } - - private static byte[] getBlockX(byte[] hash, int size, byte fill) { - if (hash.length == size) return hash; - - byte[] result = new byte[size]; - Arrays.fill(result, fill); - System.arraycopy(hash, 0, result, 0, Math.min(result.length, hash.length)); - return result; - } - - public static MessageDigest getMessageDigest(HashAlgorithm hashAlgorithm) { - try { - if (hashAlgorithm.needsBouncyCastle) { - registerBouncyCastle(); - return MessageDigest.getInstance(hashAlgorithm.jceId, "BC"); - } else { - return MessageDigest.getInstance(hashAlgorithm.jceId); - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException("hash algo not supported", e); - } - } - - public static Mac getMac(HashAlgorithm hashAlgorithm) { - try { - if (hashAlgorithm.needsBouncyCastle) { - registerBouncyCastle(); - return Mac.getInstance(hashAlgorithm.jceHmacId, "BC"); - } else { - return Mac.getInstance(hashAlgorithm.jceHmacId); - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException("hmac algo not supported", e); - } - } - - @SuppressWarnings("unchecked") - public static void registerBouncyCastle() { - if (Security.getProvider("BC") != null) { - return; - } - - try { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - String bcProviderName = "org.bouncycastle.jce.provider.BouncyCastleProvider"; - Class clazz = (Class)cl.loadClass(bcProviderName); - Security.addProvider(clazz.newInstance()); - } catch (Exception e) { - throw new EncryptedDocumentException("Only the BouncyCastle provider supports your encryption settings - please add it to the classpath.", e); - } - } - - private static final int INITIAL_CODE_ARRAY[] = { - 0xE1F0, 0x1D0F, 0xCC9C, 0x84C0, 0x110C, 0x0E10, 0xF1CE, - 0x313E, 0x1872, 0xE139, 0xD40F, 0x84F9, 0x280C, 0xA96A, - 0x4EC3 - }; - - private static final byte PAD_ARRAY[] = { - (byte)0xBB, (byte)0xFF, (byte)0xFF, (byte)0xBA, (byte)0xFF, - (byte)0xFF, (byte)0xB9, (byte)0x80, (byte)0x00, (byte)0xBE, - (byte)0x0F, (byte)0x00, (byte)0xBF, (byte)0x0F, (byte)0x00 - }; - - private static final int ENCRYPTION_MATRIX[][] = { - /* char 1 */ {0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09}, - /* char 2 */ {0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF}, - /* char 3 */ {0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0}, - /* char 4 */ {0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40}, - /* char 5 */ {0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5}, - /* char 6 */ {0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A}, - /* char 7 */ {0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9}, - /* char 8 */ {0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0}, - /* char 9 */ {0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC}, - /* char 10 */ {0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10}, - /* char 11 */ {0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168}, - /* char 12 */ {0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C}, - /* char 13 */ {0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD}, - /* char 14 */ {0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC}, - /* char 15 */ {0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4} - }; - - /** - * Create the verifier for xor obfuscation (method 1) - * - * @see 2.3.7.1 Binary Document Password Verifier Derivation Method 1 - * @see 2.3.7.4 Binary Document Password Verifier Derivation Method 2 - * @see Part 4 - Markup Language Reference - Ecma International - 3.2.12 fileSharing - * - * @param password the password - * @return the verifier (actually a short value) - */ - public static int createXorVerifier1(String password) { - byte[] arrByteChars = toAnsiPassword(password); - - // SET Verifier TO 0x0000 - short verifier = 0; - - if (!"".equals(password)) { - // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER - for (int i = arrByteChars.length-1; i >= 0; i--) { - // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte - verifier = rotateLeftBase15Bit(verifier); - verifier ^= arrByteChars[i]; - } - - // as we haven't prepended the password length into the input array - // we need to do it now separately ... - verifier = rotateLeftBase15Bit(verifier); - verifier ^= arrByteChars.length; - - // RETURN Verifier BITWISE XOR 0xCE4B - verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K') - } - - return verifier & 0xFFFF; - } - - /** - * This method generates the xor verifier for word documents < 2007 (method 2). - * Its output will be used as password input for the newer word generations which - * utilize a real hashing algorithm like sha1. - * - * @param password the password - * @return the hashed password - * - * @see 2.3.7.4 Binary Document Password Verifier Derivation Method 2 - * @see How to set the editing restrictions in Word using Open XML SDK 2.0 - * @see Funny: How the new powerful cryptography implemented in Word 2007 turns it into a perfect tool for document password removal. - */ - public static int createXorVerifier2(String password) { - //Array to hold Key Values - byte[] generatedKey = new byte[4]; - - //Maximum length of the password is 15 chars. - final int maxPasswordLength = 15; - - if (!"".equals(password)) { - // Truncate the password to 15 characters - password = password.substring(0, Math.min(password.length(), maxPasswordLength)); - - byte[] arrByteChars = toAnsiPassword(password); - - // Compute the high-order word of the new key: - - // --> Initialize from the initial code array (see below), depending on the passwords length. - int highOrderWord = INITIAL_CODE_ARRAY[arrByteChars.length - 1]; - - // --> For each character in the password: - // --> For every bit in the character, starting with the least significant and progressing to (but excluding) - // the most significant, if the bit is set, XOR the keys high-order word with the corresponding word from - // the Encryption Matrix - for (int i = 0; i < arrByteChars.length; i++) { - int tmp = maxPasswordLength - arrByteChars.length + i; - for (int intBit = 0; intBit < 7; intBit++) { - if ((arrByteChars[i] & (0x0001 << intBit)) != 0) { - highOrderWord ^= ENCRYPTION_MATRIX[tmp][intBit]; - } - } - } - - // Compute the low-order word of the new key: - int verifier = createXorVerifier1(password); - - // The byte order of the result shall be reversed [password "Example": 0x64CEED7E becomes 7EEDCE64], - // and that value shall be hashed as defined by the attribute values. - - LittleEndian.putShort(generatedKey, 0, (short)verifier); - LittleEndian.putShort(generatedKey, 2, (short)highOrderWord); - } - - return LittleEndian.getInt(generatedKey); - } - - /** - * This method generates the xored-hashed password for word documents < 2007. - */ - public static String xorHashPassword(String password) { - int hashedPassword = createXorVerifier2(password); - return String.format(Locale.ROOT, "%1$08X", hashedPassword); - } - - /** - * Convenience function which returns the reversed xored-hashed password for further - * processing in word documents 2007 and newer, which utilize a real hashing algorithm like sha1. - */ - public static String xorHashPasswordReversed(String password) { - int hashedPassword = createXorVerifier2(password); - - return String.format(Locale.ROOT, "%1$02X%2$02X%3$02X%4$02X" - , ( hashedPassword >>> 0 ) & 0xFF - , ( hashedPassword >>> 8 ) & 0xFF - , ( hashedPassword >>> 16 ) & 0xFF - , ( hashedPassword >>> 24 ) & 0xFF - ); - } - - /** - * Create the xor key for xor obfuscation, which is used to create the xor array (method 1) - * - * @see 2.3.7.2 Binary Document XOR Array Initialization Method 1 - * @see 2.3.7.4 Binary Document Password Verifier Derivation Method 2 - * - * @param password the password - * @return the xor key - */ - public static int createXorKey1(String password) { - // the xor key for method 1 is part of the verifier for method 2 - // so we simply chop it from there - return createXorVerifier2(password) >>> 16; - } - - /** - * Creates an byte array for xor obfuscation (method 1) - * - * @see 2.3.7.2 Binary Document XOR Array Initialization Method 1 - * @see Libre Office implementation - * - * @param password the password - * @return the byte array for xor obfuscation - */ - public static byte[] createXorArray1(String password) { - if (password.length() > 15) { - password = password.substring(0, 15); - } - byte passBytes[] = password.getBytes(Charset.forName("ASCII")); - - // this code is based on the libre office implementation. - // The MS-OFFCRYPTO misses some infos about the various rotation sizes - byte obfuscationArray[] = new byte[16]; - System.arraycopy(passBytes, 0, obfuscationArray, 0, passBytes.length); - System.arraycopy(PAD_ARRAY, 0, obfuscationArray, passBytes.length, PAD_ARRAY.length-passBytes.length+1); - - int xorKey = createXorKey1(password); - - // rotation of key values is application dependent - Excel = 2 / Word = 7 - int nRotateSize = 2; - - byte baseKeyLE[] = { (byte)(xorKey & 0xFF), (byte)((xorKey >>> 8) & 0xFF) }; - for (int i=0; iPart 4 - Markup Language Reference - Ecma International - section 3.2.29 (workbookProtection) - */ - private static byte[] toAnsiPassword(String password) { - // TODO: charset conversion (see ecma spec) - - // Get the single-byte values by iterating through the Unicode characters. - // For each character, if the low byte is not equal to 0, take it. - // Otherwise, take the high byte. - byte[] arrByteChars = new byte[password.length()]; - - for (int i = 0; i < password.length(); i++) { - int intTemp = password.charAt(i); - byte lowByte = (byte)(intTemp & 0xFF); - byte highByte = (byte)((intTemp >>> 8) & 0xFF); - arrByteChars[i] = (lowByte != 0 ? lowByte : highByte); - } - - return arrByteChars; - } - - private static byte rotateLeft(byte bits, int shift) { - return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (8 - shift))); - } - - private static short rotateLeftBase15Bit(short verifier) { - /* - * IF (Verifier BITWISE AND 0x4000) is 0x0000 - * SET Intermediate1 TO 0 - * ELSE - * SET Intermediate1 TO 1 - * ENDIF - */ - short intermediate1 = (short)(((verifier & 0x4000) == 0) ? 0 : 1); - /* - * SET Intermediate2 TO Verifier MULTIPLED BY 2 - * SET most significant bit of Intermediate2 TO 0 - */ - short intermediate2 = (short)((verifier<<1) & 0x7FFF); - /* - * SET Intermediate3 TO Intermediate1 BITWISE OR Intermediate2 - */ - short intermediate3 = (short)(intermediate1 | intermediate2); - return intermediate3; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java b/trunk/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java deleted file mode 100644 index 923d7075f..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java +++ /dev/null @@ -1,370 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import java.io.IOException; -import java.nio.charset.Charset; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentEntry; -import org.apache.poi.poifs.filesystem.POIFSWriterEvent; -import org.apache.poi.poifs.filesystem.POIFSWriterListener; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -public class DataSpaceMapUtils { - public static void addDefaultDataSpace(DirectoryEntry dir) throws IOException { - DataSpaceMapEntry dsme = new DataSpaceMapEntry( - new int[]{ 0 } - , new String[]{ Decryptor.DEFAULT_POIFS_ENTRY } - , "StrongEncryptionDataSpace" - ); - DataSpaceMap dsm = new DataSpaceMap(new DataSpaceMapEntry[]{dsme}); - createEncryptionEntry(dir, "\u0006DataSpaces/DataSpaceMap", dsm); - - DataSpaceDefinition dsd = new DataSpaceDefinition(new String[]{ "StrongEncryptionTransform" }); - createEncryptionEntry(dir, "\u0006DataSpaces/DataSpaceInfo/StrongEncryptionDataSpace", dsd); - - TransformInfoHeader tih = new TransformInfoHeader( - 1 - , "{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}" - , "Microsoft.Container.EncryptionTransform" - , 1, 0, 1, 0, 1, 0 - ); - IRMDSTransformInfo irm = new IRMDSTransformInfo(tih, 0, null); - createEncryptionEntry(dir, "\u0006DataSpaces/TransformInfo/StrongEncryptionTransform/\u0006Primary", irm); - - DataSpaceVersionInfo dsvi = new DataSpaceVersionInfo("Microsoft.Container.DataSpaces", 1, 0, 1, 0, 1, 0); - createEncryptionEntry(dir, "\u0006DataSpaces/Version", dsvi); - } - - public static DocumentEntry createEncryptionEntry(DirectoryEntry dir, String path, EncryptionRecord out) throws IOException { - String parts[] = path.split("/"); - for (int i=0; i 0) { - for (int i=0; i<(4-scratchedBytes); i++) { - is.readByte(); - } - } - - return new String(data, 0, data.length, Charset.forName("UTF-8")); - } - - public static void writeUtf8LPP4(LittleEndianOutput os, String str) { - if (str == null || "".equals(str)) { - os.writeInt(str == null ? 0 : 4); - os.writeInt(0); - } else { - byte buf[] = str.getBytes(Charset.forName("UTF-8")); - os.writeInt(buf.length); - os.write(buf); - int scratchBytes = buf.length%4; - if (scratchBytes > 0) { - for (int i=0; i<(4-scratchBytes); i++) { - os.writeByte(0); - } - } - } - } - -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java deleted file mode 100644 index da746d896..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java +++ /dev/null @@ -1,196 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -public abstract class Decryptor implements Cloneable { - public static final String DEFAULT_PASSWORD="VelvetSweatshop"; - public static final String DEFAULT_POIFS_ENTRY="EncryptedPackage"; - - protected EncryptionInfo encryptionInfo; - private SecretKey secretKey; - private byte[] verifier, integrityHmacKey, integrityHmacValue; - - protected Decryptor() { - } - - /** - * Return a stream with decrypted data. - *

    - * Use {@link #getLength()} to get the size of that data that can be safely read from the stream. - * Just reading to the end of the input stream is not sufficient because there are - * normally padding bytes that must be discarded - *

    - * - * @param dir the node to read from - * @return decrypted stream - */ - public abstract InputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException; - - /** - * Wraps a stream for decryption

    - * - * As we are handling streams and don't know the total length beforehand, - * it's the callers duty to care for the length of the entries. - * - * @param stream the stream to be wrapped - * @param initialPos initial/current byte position within the stream - * @return decrypted stream - */ - public InputStream getDataStream(InputStream stream, int size, int initialPos) - throws IOException, GeneralSecurityException { - throw new EncryptedDocumentException("this decryptor doesn't support reading from a stream"); - } - - /** - * Sets the chunk size of the data stream. - * Needs to be set before the data stream is requested. - * When not set, the implementation uses method specific default values - * - * @param chunkSize the chunk size, i.e. the block size with the same encryption key - */ - public void setChunkSize(int chunkSize) { - throw new EncryptedDocumentException("this decryptor doesn't support changing the chunk size"); - } - - /** - * Initializes a cipher object for a given block index for encryption - * - * @param cipher may be null, otherwise the given instance is reset to the new block index - * @param block the block index, e.g. the persist/slide id (hslf) - * @return a new cipher object, if cipher was null, otherwise the reinitialized cipher - * @throws GeneralSecurityException - */ - public Cipher initCipherForBlock(Cipher cipher, int block) - throws GeneralSecurityException { - throw new EncryptedDocumentException("this decryptor doesn't support initCipherForBlock"); - } - - public abstract boolean verifyPassword(String password) - throws GeneralSecurityException; - - /** - * Returns the length of the encrypted data that can be safely read with - * {@link #getDataStream(org.apache.poi.poifs.filesystem.DirectoryNode)}. - * Just reading to the end of the input stream is not sufficient because there are - * normally padding bytes that must be discarded - * - *

    - * The length variable is initialized in {@link #getDataStream(org.apache.poi.poifs.filesystem.DirectoryNode)}, - * an attempt to call getLength() prior to getDataStream() will result in IllegalStateException. - *

    - * - * @return length of the encrypted data - * @throws IllegalStateException if {@link #getDataStream(org.apache.poi.poifs.filesystem.DirectoryNode)} - * was not called - */ - public abstract long getLength(); - - public static Decryptor getInstance(EncryptionInfo info) { - Decryptor d = info.getDecryptor(); - if (d == null) { - throw new EncryptedDocumentException("Unsupported version"); - } - return d; - } - - public InputStream getDataStream(NPOIFSFileSystem fs) throws IOException, GeneralSecurityException { - return getDataStream(fs.getRoot()); - } - - public InputStream getDataStream(OPOIFSFileSystem fs) throws IOException, GeneralSecurityException { - return getDataStream(fs.getRoot()); - } - - public InputStream getDataStream(POIFSFileSystem fs) throws IOException, GeneralSecurityException { - return getDataStream(fs.getRoot()); - } - - // for tests - public byte[] getVerifier() { - return verifier; - } - - public SecretKey getSecretKey() { - return secretKey; - } - - public byte[] getIntegrityHmacKey() { - return integrityHmacKey; - } - - public byte[] getIntegrityHmacValue() { - return integrityHmacValue; - } - - protected void setSecretKey(SecretKey secretKey) { - this.secretKey = secretKey; - } - - protected void setVerifier(byte[] verifier) { - this.verifier = (verifier == null) ? null : verifier.clone(); - } - - protected void setIntegrityHmacKey(byte[] integrityHmacKey) { - this.integrityHmacKey = (integrityHmacKey == null) ? null : integrityHmacKey.clone(); - } - - protected void setIntegrityHmacValue(byte[] integrityHmacValue) { - this.integrityHmacValue = (integrityHmacValue == null) ? null : integrityHmacValue.clone(); - } - - protected int getBlockSizeInBytes() { - return encryptionInfo.getHeader().getBlockSize(); - } - - protected int getKeySizeInBytes() { - return encryptionInfo.getHeader().getKeySize()/8; - } - - public EncryptionInfo getEncryptionInfo() { - return encryptionInfo; - } - - public void setEncryptionInfo(EncryptionInfo encryptionInfo) { - this.encryptionInfo = encryptionInfo; - } - - @Override - public Decryptor clone() throws CloneNotSupportedException { - Decryptor other = (Decryptor)super.clone(); - other.integrityHmacKey = integrityHmacKey.clone(); - other.integrityHmacValue = integrityHmacValue.clone(); - other.verifier = verifier.clone(); - other.secretKey = new SecretKeySpec(secretKey.getEncoded(), secretKey.getAlgorithm()); - // encryptionInfo is set from outside - return other; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java b/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java deleted file mode 100644 index f13c116e0..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.util.Removal; - -/** - * Reads and processes OOXML Encryption Headers - * The constants are largely based on ZIP constants. - */ -public abstract class EncryptionHeader implements Cloneable { - public static final int ALGORITHM_RC4 = CipherAlgorithm.rc4.ecmaId; - public static final int ALGORITHM_AES_128 = CipherAlgorithm.aes128.ecmaId; - public static final int ALGORITHM_AES_192 = CipherAlgorithm.aes192.ecmaId; - public static final int ALGORITHM_AES_256 = CipherAlgorithm.aes256.ecmaId; - - public static final int HASH_NONE = HashAlgorithm.none.ecmaId; - public static final int HASH_SHA1 = HashAlgorithm.sha1.ecmaId; - public static final int HASH_SHA256 = HashAlgorithm.sha256.ecmaId; - public static final int HASH_SHA384 = HashAlgorithm.sha384.ecmaId; - public static final int HASH_SHA512 = HashAlgorithm.sha512.ecmaId; - - public static final int PROVIDER_RC4 = CipherProvider.rc4.ecmaId; - public static final int PROVIDER_AES = CipherProvider.aes.ecmaId; - - public static final int MODE_ECB = ChainingMode.ecb.ecmaId; - public static final int MODE_CBC = ChainingMode.cbc.ecmaId; - public static final int MODE_CFB = ChainingMode.cfb.ecmaId; - - private int flags; - private int sizeExtra; - private CipherAlgorithm cipherAlgorithm; - private HashAlgorithm hashAlgorithm; - private int keyBits; - private int blockSize; - private CipherProvider providerType; - private ChainingMode chainingMode; - private byte[] keySalt; - private String cspName; - - protected EncryptionHeader() {} - - public ChainingMode getChainingMode() { - return chainingMode; - } - - protected void setChainingMode(ChainingMode chainingMode) { - this.chainingMode = chainingMode; - } - - public int getFlags() { - return flags; - } - - protected void setFlags(int flags) { - this.flags = flags; - } - - public int getSizeExtra() { - return sizeExtra; - } - - protected void setSizeExtra(int sizeExtra) { - this.sizeExtra = sizeExtra; - } - - public CipherAlgorithm getCipherAlgorithm() { - return cipherAlgorithm; - } - - protected void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) { - this.cipherAlgorithm = cipherAlgorithm; - if (cipherAlgorithm.allowedKeySize.length == 1) { - setKeySize(cipherAlgorithm.defaultKeySize); - } - } - - public HashAlgorithm getHashAlgorithm() { - return hashAlgorithm; - } - - /** - * @deprecated POI 3.16 beta 1. use {@link #getHashAlgorithm()} - */ - @Removal(version="3.18") - public HashAlgorithm getHashAlgorithmEx() { - return hashAlgorithm; - } - - protected void setHashAlgorithm(HashAlgorithm hashAlgorithm) { - this.hashAlgorithm = hashAlgorithm; - } - - public int getKeySize() { - return keyBits; - } - - /** - * Sets the keySize (in bits). Before calling this method, make sure - * to set the cipherAlgorithm, as the amount of keyBits gets validated against - * the list of allowed keyBits of the corresponding cipherAlgorithm - * - * @param keyBits - */ - protected void setKeySize(int keyBits) { - this.keyBits = keyBits; - for (int allowedBits : getCipherAlgorithm().allowedKeySize) { - if (allowedBits == keyBits) { - return; - } - } - throw new EncryptedDocumentException("KeySize "+keyBits+" not allowed for cipher "+getCipherAlgorithm()); - } - - public int getBlockSize() { - return blockSize; - } - - protected void setBlockSize(int blockSize) { - this.blockSize = blockSize; - } - - public byte[] getKeySalt() { - return keySalt; - } - - protected void setKeySalt(byte salt[]) { - this.keySalt = (salt == null) ? null : salt.clone(); - } - - public CipherProvider getCipherProvider() { - return providerType; - } - - protected void setCipherProvider(CipherProvider providerType) { - this.providerType = providerType; - } - - public String getCspName() { - return cspName; - } - - protected void setCspName(String cspName) { - this.cspName = cspName; - } - - @Override - public EncryptionHeader clone() throws CloneNotSupportedException { - EncryptionHeader other = (EncryptionHeader)super.clone(); - other.keySalt = (keySalt == null) ? null : keySalt.clone(); - return other; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java b/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java deleted file mode 100644 index e8895c1ab..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java +++ /dev/null @@ -1,282 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.apache.poi.poifs.crypt.EncryptionMode.agile; -import static org.apache.poi.poifs.crypt.EncryptionMode.binaryRC4; -import static org.apache.poi.poifs.crypt.EncryptionMode.cryptoAPI; -import static org.apache.poi.poifs.crypt.EncryptionMode.standard; -import static org.apache.poi.poifs.crypt.EncryptionMode.xor; - -import java.io.IOException; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianInput; - -/** - * This class may require {@code poi-ooxml} to be on the classpath to load - * some {@link EncryptionMode}s. - * @see #getBuilder(EncryptionMode) - */ -public class EncryptionInfo implements Cloneable { - private final EncryptionMode encryptionMode; - private final int versionMajor; - private final int versionMinor; - private final int encryptionFlags; - - private EncryptionHeader header; - private EncryptionVerifier verifier; - private Decryptor decryptor; - private Encryptor encryptor; - - /** - * A flag that specifies whether CryptoAPI RC4 or ECMA-376 encryption - * ECMA-376 is used. It MUST be 1 unless flagExternal is 1. If flagExternal is 1, it MUST be 0. - */ - public static final BitField flagCryptoAPI = BitFieldFactory.getInstance(0x04); - - /** - * A value that MUST be 0 if document properties are encrypted. - * The encryption of document properties is specified in section 2.3.5.4. - */ - public static final BitField flagDocProps = BitFieldFactory.getInstance(0x08); - - /** - * A value that MUST be 1 if extensible encryption is used. If this value is 1, - * the value of every other field in this structure MUST be 0. - */ - public static final BitField flagExternal = BitFieldFactory.getInstance(0x10); - - /** - * A value that MUST be 1 if the protected content is an ECMA-376 document - * ECMA-376. If the fAES bit is 1, the fCryptoAPI bit MUST also be 1. - */ - public static final BitField flagAES = BitFieldFactory.getInstance(0x20); - - - /** - * Opens for decryption - */ - public EncryptionInfo(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - - /** - * Opens for decryption - */ - public EncryptionInfo(OPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - - /** - * Opens for decryption - */ - public EncryptionInfo(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - - /** - * Opens for decryption - */ - public EncryptionInfo(DirectoryNode dir) throws IOException { - this(dir.createDocumentInputStream("EncryptionInfo"), null); - } - - public EncryptionInfo(LittleEndianInput dis, EncryptionMode preferredEncryptionMode) throws IOException { - if (preferredEncryptionMode == xor) { - versionMajor = xor.versionMajor; - versionMinor = xor.versionMinor; - } else { - versionMajor = dis.readUShort(); - versionMinor = dis.readUShort(); - } - - if ( versionMajor == xor.versionMajor - && versionMinor == xor.versionMinor) { - encryptionMode = xor; - encryptionFlags = -1; - } else if ( versionMajor == binaryRC4.versionMajor - && versionMinor == binaryRC4.versionMinor) { - encryptionMode = binaryRC4; - encryptionFlags = -1; - } else if ( - 2 <= versionMajor && versionMajor <= 4 - && versionMinor == 2) { - encryptionMode = (preferredEncryptionMode == cryptoAPI) ? cryptoAPI : standard; - encryptionFlags = dis.readInt(); - } else if ( - versionMajor == agile.versionMajor - && versionMinor == agile.versionMinor){ - encryptionMode = agile; - encryptionFlags = dis.readInt(); - } else { - encryptionFlags = dis.readInt(); - throw new EncryptedDocumentException( - "Unknown encryption: version major: "+versionMajor+ - " / version minor: "+versionMinor+ - " / fCrypto: "+flagCryptoAPI.isSet(encryptionFlags)+ - " / fExternal: "+flagExternal.isSet(encryptionFlags)+ - " / fDocProps: "+flagDocProps.isSet(encryptionFlags)+ - " / fAES: "+flagAES.isSet(encryptionFlags)); - } - - EncryptionInfoBuilder eib; - try { - eib = getBuilder(encryptionMode); - } catch (Exception e) { - throw new IOException(e); - } - - eib.initialize(this, dis); - } - - /** - * Prepares for encryption, using the given Encryption Mode, and - * all other parameters as default. - * @see #EncryptionInfo(EncryptionMode, CipherAlgorithm, HashAlgorithm, int, int, ChainingMode) - */ - public EncryptionInfo(EncryptionMode encryptionMode) { - this(encryptionMode, null, null, -1, -1, null); - } - - /** - * Constructs an EncryptionInfo from scratch - * - * @param encryptionMode see {@link EncryptionMode} for values, {@link EncryptionMode#cryptoAPI} is for - * internal use only, as it's record based - * @param cipherAlgorithm - * @param hashAlgorithm - * @param keyBits - * @param blockSize - * @param chainingMode - * - * @throws EncryptedDocumentException if the given parameters mismatch, e.g. only certain combinations - * of keyBits, blockSize are allowed for a given {@link CipherAlgorithm} - */ - public EncryptionInfo( - EncryptionMode encryptionMode - , CipherAlgorithm cipherAlgorithm - , HashAlgorithm hashAlgorithm - , int keyBits - , int blockSize - , ChainingMode chainingMode - ) { - this.encryptionMode = encryptionMode; - versionMajor = encryptionMode.versionMajor; - versionMinor = encryptionMode.versionMinor; - encryptionFlags = encryptionMode.encryptionFlags; - - EncryptionInfoBuilder eib; - try { - eib = getBuilder(encryptionMode); - } catch (Exception e) { - throw new EncryptedDocumentException(e); - } - - eib.initialize(this, cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode); - } - - /** - * This method loads the builder class with reflection, which may generate - * a {@code ClassNotFoundException} if the class is not on the classpath. - * For example, {@link org.apache.poi.poifs.crypt.agile.AgileEncryptionInfoBuilder} - * is contained in the {@code poi-ooxml} package since the class makes use of some OOXML - * classes rather than using the {@code poi} package and plain XML DOM calls. - * As such, you may need to include {@code poi-ooxml} and {@code poi-ooxml-schemas} to load - * some encryption mode builders. See bug #60021 for more information. - * https://bz.apache.org/bugzilla/show_bug.cgi?id=60021 - * - * @param encryptionMode the encryption mode - * @return an encryption info builder - * @throws ClassNotFoundException - * @throws IllegalAccessException - * @throws InstantiationException - */ - protected static EncryptionInfoBuilder getBuilder(EncryptionMode encryptionMode) - throws ClassNotFoundException, IllegalAccessException, InstantiationException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - EncryptionInfoBuilder eib; - eib = (EncryptionInfoBuilder)cl.loadClass(encryptionMode.builder).newInstance(); - return eib; - } - - public int getVersionMajor() { - return versionMajor; - } - - public int getVersionMinor() { - return versionMinor; - } - - public int getEncryptionFlags() { - return encryptionFlags; - } - - public EncryptionHeader getHeader() { - return header; - } - - public EncryptionVerifier getVerifier() { - return verifier; - } - - public Decryptor getDecryptor() { - return decryptor; - } - - public Encryptor getEncryptor() { - return encryptor; - } - - public void setHeader(EncryptionHeader header) { - this.header = header; - } - - public void setVerifier(EncryptionVerifier verifier) { - this.verifier = verifier; - } - - public void setDecryptor(Decryptor decryptor) { - this.decryptor = decryptor; - } - - public void setEncryptor(Encryptor encryptor) { - this.encryptor = encryptor; - } - - public EncryptionMode getEncryptionMode() { - return encryptionMode; - } - - @Override - public EncryptionInfo clone() throws CloneNotSupportedException { - EncryptionInfo other = (EncryptionInfo)super.clone(); - other.header = header.clone(); - other.verifier = verifier.clone(); - other.decryptor = decryptor.clone(); - other.decryptor.setEncryptionInfo(other); - other.encryptor = encryptor.clone(); - other.encryptor.setEncryptionInfo(other); - return other; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfoBuilder.java b/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfoBuilder.java deleted file mode 100644 index 24371dfdd..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionInfoBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import java.io.IOException; - -import org.apache.poi.util.LittleEndianInput; - -public interface EncryptionInfoBuilder { - /** - * initialize the builder from a stream - */ - void initialize(EncryptionInfo ei, LittleEndianInput dis) throws IOException; - - /** - * initialize the builder from scratch - */ - void initialize(EncryptionInfo ei, CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode); -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionMode.java b/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionMode.java deleted file mode 100644 index 50064b5a6..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionMode.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; - -/** - * Office supports various encryption modes. - * The encryption is either based on the whole container ({@link #agile}, {@link #standard} or {@link #binaryRC4}) - * or record based ({@link #cryptoAPI}). The record based encryption can't be accessed directly, but will be - * invoked by using the {@link Biff8EncryptionKey#setCurrentUserPassword(String)} before saving the document. - */ -public enum EncryptionMode { - /* @see 2.3.6 Office Binary Document RC4 Encryption */ - binaryRC4("org.apache.poi.poifs.crypt.binaryrc4.BinaryRC4EncryptionInfoBuilder", 1, 1, 0x0), - /* @see 2.3.5 Office Binary Document RC4 CryptoAPI Encryption */ - cryptoAPI("org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptionInfoBuilder", 4, 2, 0x04), - /* @see 2.3.4.5 \EncryptionInfo Stream (Standard Encryption) */ - standard("org.apache.poi.poifs.crypt.standard.StandardEncryptionInfoBuilder", 4, 2, 0x24), - /* @see 2.3.4.10 \EncryptionInfo Stream (Agile Encryption) */ - agile("org.apache.poi.poifs.crypt.agile.AgileEncryptionInfoBuilder", 4, 4, 0x40), - /* @see XOR Obfuscation */ - xor("org.apache.poi.poifs.crypt.xor.XOREncryptionInfoBuilder", 0, 0, 0) - ; - - public final String builder; - public final int versionMajor; - public final int versionMinor; - public final int encryptionFlags; - - EncryptionMode(String builder, int versionMajor, int versionMinor, int encryptionFlags) { - this.builder = builder; - this.versionMajor = versionMajor; - this.versionMinor = versionMinor; - this.encryptionFlags = encryptionFlags; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java b/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java deleted file mode 100644 index df216c071..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/EncryptionVerifier.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import org.apache.poi.util.Removal; - -/** - * Used when checking if a key is valid for a document - */ -public abstract class EncryptionVerifier implements Cloneable { - private byte[] salt; - private byte[] encryptedVerifier; - private byte[] encryptedVerifierHash; - private byte[] encryptedKey; - // protected int verifierHashSize; - private int spinCount; - private CipherAlgorithm cipherAlgorithm; - private ChainingMode chainingMode; - private HashAlgorithm hashAlgorithm; - - protected EncryptionVerifier() {} - - public byte[] getSalt() { - return salt; - } - - public byte[] getEncryptedVerifier() { - return encryptedVerifier; - } - - public byte[] getEncryptedVerifierHash() { - return encryptedVerifierHash; - } - - public int getSpinCount() { - return spinCount; - } - - /** - * @deprecated POI 3.16 beta 1. use {@link #getChainingMode()} - */ - @Removal(version="3.18") - public int getCipherMode() { - return chainingMode.ecmaId; - } - - /** - * @deprecated POI 3.16 beta 1. use {@link #getCipherAlgorithm()} - */ - public int getAlgorithm() { - return cipherAlgorithm.ecmaId; - } - - public byte[] getEncryptedKey() { - return encryptedKey; - } - - public CipherAlgorithm getCipherAlgorithm() { - return cipherAlgorithm; - } - - public HashAlgorithm getHashAlgorithm() { - return hashAlgorithm; - } - - public ChainingMode getChainingMode() { - return chainingMode; - } - - protected void setSalt(byte[] salt) { - this.salt = (salt == null) ? null : salt.clone(); - } - - protected void setEncryptedVerifier(byte[] encryptedVerifier) { - this.encryptedVerifier = (encryptedVerifier == null) ? null : encryptedVerifier.clone(); - } - - protected void setEncryptedVerifierHash(byte[] encryptedVerifierHash) { - this.encryptedVerifierHash = (encryptedVerifierHash == null) ? null : encryptedVerifierHash.clone(); - } - - protected void setEncryptedKey(byte[] encryptedKey) { - this.encryptedKey = (encryptedKey == null) ? null : encryptedKey.clone(); - } - - protected void setSpinCount(int spinCount) { - this.spinCount = spinCount; - } - - protected void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) { - this.cipherAlgorithm = cipherAlgorithm; - } - - protected void setChainingMode(ChainingMode chainingMode) { - this.chainingMode = chainingMode; - } - - protected void setHashAlgorithm(HashAlgorithm hashAlgorithm) { - this.hashAlgorithm = hashAlgorithm; - } - - @Override - public EncryptionVerifier clone() throws CloneNotSupportedException { - EncryptionVerifier other = (EncryptionVerifier)super.clone(); - other.salt = (salt == null) ? null : salt.clone(); - other.encryptedVerifier = (encryptedVerifier == null) ? null : encryptedVerifier.clone(); - other.encryptedVerifierHash = (encryptedVerifierHash == null) ? null : encryptedVerifierHash.clone(); - other.encryptedKey = (encryptedKey == null) ? null : encryptedKey.clone(); - return other; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java deleted file mode 100644 index f4c0c1639..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java +++ /dev/null @@ -1,104 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; - -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -public abstract class Encryptor implements Cloneable { - protected static final String DEFAULT_POIFS_ENTRY = Decryptor.DEFAULT_POIFS_ENTRY; - private EncryptionInfo encryptionInfo; - private SecretKey secretKey; - - /** - * Return a output stream for encrypted data. - * - * @param dir the node to write to - * @return encrypted stream - */ - public abstract OutputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException; - - // for tests - public abstract void confirmPassword(String password, byte keySpec[], byte keySalt[], byte verifier[], byte verifierSalt[], byte integritySalt[]); - - public abstract void confirmPassword(String password); - - public static Encryptor getInstance(EncryptionInfo info) { - return info.getEncryptor(); - } - - public OutputStream getDataStream(NPOIFSFileSystem fs) throws IOException, GeneralSecurityException { - return getDataStream(fs.getRoot()); - } - public OutputStream getDataStream(OPOIFSFileSystem fs) throws IOException, GeneralSecurityException { - return getDataStream(fs.getRoot()); - } - public OutputStream getDataStream(POIFSFileSystem fs) throws IOException, GeneralSecurityException { - return getDataStream(fs.getRoot()); - } - - public ChunkedCipherOutputStream getDataStream(OutputStream stream, int initialOffset) - throws IOException, GeneralSecurityException { - throw new EncryptedDocumentException("this decryptor doesn't support writing directly to a stream"); - } - - public SecretKey getSecretKey() { - return secretKey; - } - - public void setSecretKey(SecretKey secretKey) { - this.secretKey = secretKey; - } - - public EncryptionInfo getEncryptionInfo() { - return encryptionInfo; - } - - public void setEncryptionInfo(EncryptionInfo encryptionInfo) { - this.encryptionInfo = encryptionInfo; - } - - /** - * Sets the chunk size of the data stream. - * Needs to be set before the data stream is requested. - * When not set, the implementation uses method specific default values - * - * @param chunkSize the chunk size, i.e. the block size with the same encryption key - */ - public void setChunkSize(int chunkSize) { - throw new EncryptedDocumentException("this decryptor doesn't support changing the chunk size"); - } - - @Override - public Encryptor clone() throws CloneNotSupportedException { - Encryptor other = (Encryptor)super.clone(); - other.secretKey = new SecretKeySpec(secretKey.getEncoded(), secretKey.getAlgorithm()); - // encryptionInfo is set from outside - return other; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/HashAlgorithm.java b/trunk/src/java/org/apache/poi/poifs/crypt/HashAlgorithm.java deleted file mode 100644 index 24c43325d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/HashAlgorithm.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import org.apache.poi.EncryptedDocumentException; - -public enum HashAlgorithm { - none ( "", 0x0000, "", 0, "", false), - sha1 ( "SHA-1", 0x8004, "SHA1", 20, "HmacSHA1", false), - sha256 ( "SHA-256", 0x800C, "SHA256", 32, "HmacSHA256", false), - sha384 ( "SHA-384", 0x800D, "SHA384", 48, "HmacSHA384", false), - sha512 ( "SHA-512", 0x800E, "SHA512", 64, "HmacSHA512", false), - /* only for agile encryption */ - md5 ( "MD5", -1, "MD5", 16, "HmacMD5", false), - // although sunjc2 supports md2, hmac-md2 is only supported by bouncycastle - md2 ( "MD2", -1, "MD2", 16, "Hmac-MD2", true), - md4 ( "MD4", -1, "MD4", 16, "Hmac-MD4", true), - ripemd128("RipeMD128", -1, "RIPEMD-128", 16, "HMac-RipeMD128", true), - ripemd160("RipeMD160", -1, "RIPEMD-160", 20, "HMac-RipeMD160", true), - whirlpool("Whirlpool", -1, "WHIRLPOOL", 64, "HMac-Whirlpool", true), - // only for xml signing - sha224 ( "SHA-224", -1, "SHA224", 28, "HmacSHA224", true); - - public final String jceId; - public final int ecmaId; - public final String ecmaString; - public final int hashSize; - public final String jceHmacId; - public final boolean needsBouncyCastle; - - HashAlgorithm(String jceId, int ecmaId, String ecmaString, int hashSize, String jceHmacId, boolean needsBouncyCastle) { - this.jceId = jceId; - this.ecmaId = ecmaId; - this.ecmaString = ecmaString; - this.hashSize = hashSize; - this.jceHmacId = jceHmacId; - this.needsBouncyCastle = needsBouncyCastle; - } - - public static HashAlgorithm fromEcmaId(int ecmaId) { - for (HashAlgorithm ha : values()) { - if (ha.ecmaId == ecmaId) return ha; - } - throw new EncryptedDocumentException("hash algorithm not found"); - } - - public static HashAlgorithm fromEcmaId(String ecmaString) { - for (HashAlgorithm ha : values()) { - if (ha.ecmaString.equals(ecmaString)) return ha; - } - throw new EncryptedDocumentException("hash algorithm not found"); - } - - public static HashAlgorithm fromString(String string) { - for (HashAlgorithm ha : values()) { - if (ha.ecmaString.equalsIgnoreCase(string) || ha.jceId.equalsIgnoreCase(string)) return ha; - } - throw new EncryptedDocumentException("hash algorithm not found"); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java deleted file mode 100644 index e02273407..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java +++ /dev/null @@ -1,166 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.binaryrc4; - -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.util.Arrays; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.*; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - -public class BinaryRC4Decryptor extends Decryptor implements Cloneable { - private long length = -1L; - private int chunkSize = 512; - - private class BinaryRC4CipherInputStream extends ChunkedCipherInputStream { - - @Override - protected Cipher initCipherForBlock(Cipher existing, int block) - throws GeneralSecurityException { - return BinaryRC4Decryptor.this.initCipherForBlock(existing, block); - } - - public BinaryRC4CipherInputStream(DocumentInputStream stream, long size) - throws GeneralSecurityException { - super(stream, size, chunkSize); - } - - public BinaryRC4CipherInputStream(InputStream stream) - throws GeneralSecurityException { - super(stream, Integer.MAX_VALUE, chunkSize); - } - } - - protected BinaryRC4Decryptor() { - } - - @Override - public boolean verifyPassword(String password) { - EncryptionVerifier ver = getEncryptionInfo().getVerifier(); - SecretKey skey = generateSecretKey(password, ver); - try { - Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE); - byte encryptedVerifier[] = ver.getEncryptedVerifier(); - byte verifier[] = new byte[encryptedVerifier.length]; - cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier); - setVerifier(verifier); - byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); - byte verifierHash[] = cipher.doFinal(encryptedVerifierHash); - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - byte calcVerifierHash[] = hashAlg.digest(verifier); - if (Arrays.equals(calcVerifierHash, verifierHash)) { - setSecretKey(skey); - return true; - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e); - } - return false; - } - - @Override - public Cipher initCipherForBlock(Cipher cipher, int block) - throws GeneralSecurityException { - return initCipherForBlock(cipher, block, getEncryptionInfo(), getSecretKey(), Cipher.DECRYPT_MODE); - } - - protected static Cipher initCipherForBlock(Cipher cipher, int block, - EncryptionInfo encryptionInfo, SecretKey skey, int encryptMode) - throws GeneralSecurityException { - EncryptionVerifier ver = encryptionInfo.getVerifier(); - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - byte blockKey[] = new byte[4]; - LittleEndian.putUInt(blockKey, 0, block); - byte encKey[] = CryptoFunctions.generateKey(skey.getEncoded(), hashAlgo, blockKey, 16); - SecretKey key = new SecretKeySpec(encKey, skey.getAlgorithm()); - if (cipher == null) { - EncryptionHeader em = encryptionInfo.getHeader(); - cipher = CryptoFunctions.getCipher(key, em.getCipherAlgorithm(), null, null, encryptMode); - } else { - cipher.init(encryptMode, key); - } - return cipher; - } - - protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { - if (password.length() > 255) { - password = password.substring(0, 255); - } - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); - byte salt[] = ver.getSalt(); - hashAlg.reset(); - for (int i = 0; i < 16; i++) { - hashAlg.update(hash, 0, 5); - hashAlg.update(salt); - } - - hash = new byte[5]; - System.arraycopy(hashAlg.digest(), 0, hash, 0, 5); - SecretKey skey = new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); - return skey; - } - - @Override - @SuppressWarnings("resource") - public ChunkedCipherInputStream getDataStream(DirectoryNode dir) throws IOException, - GeneralSecurityException { - DocumentInputStream dis = dir.createDocumentInputStream(DEFAULT_POIFS_ENTRY); - length = dis.readLong(); - return new BinaryRC4CipherInputStream(dis, length); - } - - @Override - public InputStream getDataStream(InputStream stream, int size, int initialPos) - throws IOException, GeneralSecurityException { - return new BinaryRC4CipherInputStream(stream); - } - - - @Override - public long getLength() { - if (length == -1L) { - throw new IllegalStateException("Decryptor.getDataStream() was not called"); - } - - return length; - } - - @Override - public void setChunkSize(int chunkSize) { - this.chunkSize = chunkSize; - } - - @Override - public BinaryRC4Decryptor clone() throws CloneNotSupportedException { - return (BinaryRC4Decryptor)super.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionHeader.java b/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionHeader.java deleted file mode 100644 index b9022017b..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionHeader.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.binaryrc4; - -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CipherProvider; -import org.apache.poi.poifs.crypt.EncryptionHeader; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; - -public class BinaryRC4EncryptionHeader extends EncryptionHeader implements EncryptionRecord, Cloneable { - - protected BinaryRC4EncryptionHeader() { - setCipherAlgorithm(CipherAlgorithm.rc4); - setKeySize(40); - setBlockSize(-1); - setCipherProvider(CipherProvider.rc4); - setHashAlgorithm(HashAlgorithm.md5); - setSizeExtra(0); - setFlags(0); - setCspName(""); - setChainingMode(null); - } - - @Override - public void write(LittleEndianByteArrayOutputStream littleendianbytearrayoutputstream) { - } - - @Override - public BinaryRC4EncryptionHeader clone() throws CloneNotSupportedException { - return (BinaryRC4EncryptionHeader)super.clone(); - } - - -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionInfoBuilder.java b/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionInfoBuilder.java deleted file mode 100644 index 94ddde72a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionInfoBuilder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.binaryrc4; - -import java.io.IOException; -import org.apache.poi.poifs.crypt.*; -import org.apache.poi.util.LittleEndianInput; - -public class BinaryRC4EncryptionInfoBuilder implements EncryptionInfoBuilder { - - public BinaryRC4EncryptionInfoBuilder() { - } - - @Override - public void initialize(EncryptionInfo info, LittleEndianInput dis) - throws IOException { - int vMajor = info.getVersionMajor(); - int vMinor = info.getVersionMinor(); - assert (vMajor == 1 && vMinor == 1); - - info.setHeader(new BinaryRC4EncryptionHeader()); - info.setVerifier(new BinaryRC4EncryptionVerifier(dis)); - Decryptor dec = new BinaryRC4Decryptor(); - dec.setEncryptionInfo(info); - info.setDecryptor(dec); - Encryptor enc = new BinaryRC4Encryptor(); - enc.setEncryptionInfo(info); - info.setEncryptor(enc); - } - - @Override - public void initialize(EncryptionInfo info, - CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, - int keyBits, int blockSize, ChainingMode chainingMode) { - info.setHeader(new BinaryRC4EncryptionHeader()); - info.setVerifier(new BinaryRC4EncryptionVerifier()); - Decryptor dec = new BinaryRC4Decryptor(); - dec.setEncryptionInfo(info); - info.setDecryptor(dec); - Encryptor enc = new BinaryRC4Encryptor(); - enc.setEncryptionInfo(info); - info.setEncryptor(enc); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionVerifier.java b/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionVerifier.java deleted file mode 100644 index 654b64a3e..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4EncryptionVerifier.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.binaryrc4; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.*; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianInput; - -public class BinaryRC4EncryptionVerifier extends EncryptionVerifier implements EncryptionRecord, Cloneable { - - protected BinaryRC4EncryptionVerifier() { - setSpinCount(-1); - setCipherAlgorithm(CipherAlgorithm.rc4); - setChainingMode(null); - setEncryptedKey(null); - setHashAlgorithm(HashAlgorithm.md5); - } - - protected BinaryRC4EncryptionVerifier(LittleEndianInput is) { - byte salt[] = new byte[16]; - is.readFully(salt); - setSalt(salt); - byte encryptedVerifier[] = new byte[16]; - is.readFully(encryptedVerifier); - setEncryptedVerifier(encryptedVerifier); - byte encryptedVerifierHash[] = new byte[16]; - is.readFully(encryptedVerifierHash); - setEncryptedVerifierHash(encryptedVerifierHash); - setSpinCount(-1); - setCipherAlgorithm(CipherAlgorithm.rc4); - setChainingMode(null); - setEncryptedKey(null); - setHashAlgorithm(HashAlgorithm.md5); - } - - @Override - protected void setSalt(byte salt[]) { - if (salt == null || salt.length != 16) { - throw new EncryptedDocumentException("invalid verifier salt"); - } - - super.setSalt(salt); - } - - @Override - protected void setEncryptedVerifier(byte encryptedVerifier[]) { - super.setEncryptedVerifier(encryptedVerifier); - } - - @Override - protected void setEncryptedVerifierHash(byte encryptedVerifierHash[]) { - super.setEncryptedVerifierHash(encryptedVerifierHash); - } - - @Override - public void write(LittleEndianByteArrayOutputStream bos) { - byte salt[] = getSalt(); - assert (salt.length == 16); - bos.write(salt); - byte encryptedVerifier[] = getEncryptedVerifier(); - assert (encryptedVerifier.length == 16); - bos.write(encryptedVerifier); - byte encryptedVerifierHash[] = getEncryptedVerifierHash(); - assert (encryptedVerifierHash.length == 16); - bos.write(encryptedVerifierHash); - } - - @Override - public BinaryRC4EncryptionVerifier clone() throws CloneNotSupportedException { - return (BinaryRC4EncryptionVerifier)super.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Encryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Encryptor.java deleted file mode 100644 index 15bb476ea..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Encryptor.java +++ /dev/null @@ -1,160 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.binaryrc4; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.util.Random; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.DataSpaceMapUtils; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; - -public class BinaryRC4Encryptor extends Encryptor implements Cloneable { - - private int chunkSize = 512; - - protected BinaryRC4Encryptor() { - } - - @Override - public void confirmPassword(String password) { - Random r = new SecureRandom(); - byte salt[] = new byte[16]; - byte verifier[] = new byte[16]; - r.nextBytes(salt); - r.nextBytes(verifier); - confirmPassword(password, null, null, verifier, salt, null); - } - - @Override - public void confirmPassword(String password, byte keySpec[], - byte keySalt[], byte verifier[], byte verifierSalt[], - byte integritySalt[]) { - BinaryRC4EncryptionVerifier ver = (BinaryRC4EncryptionVerifier)getEncryptionInfo().getVerifier(); - ver.setSalt(verifierSalt); - SecretKey skey = BinaryRC4Decryptor.generateSecretKey(password, ver); - setSecretKey(skey); - try { - Cipher cipher = BinaryRC4Decryptor.initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.ENCRYPT_MODE); - byte encryptedVerifier[] = new byte[16]; - cipher.update(verifier, 0, 16, encryptedVerifier); - ver.setEncryptedVerifier(encryptedVerifier); - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - byte calcVerifierHash[] = hashAlg.digest(verifier); - byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash); - ver.setEncryptedVerifierHash(encryptedVerifierHash); - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException("Password confirmation failed", e); - } - } - - @Override - public OutputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException { - OutputStream countStream = new BinaryRC4CipherOutputStream(dir); - return countStream; - } - - @Override - public BinaryRC4CipherOutputStream getDataStream(OutputStream stream, int initialOffset) - throws IOException, GeneralSecurityException { - return new BinaryRC4CipherOutputStream(stream); - } - - protected int getKeySizeInBytes() { - return getEncryptionInfo().getHeader().getKeySize() / 8; - } - - protected void createEncryptionInfoEntry(DirectoryNode dir) throws IOException { - DataSpaceMapUtils.addDefaultDataSpace(dir); - final EncryptionInfo info = getEncryptionInfo(); - final BinaryRC4EncryptionHeader header = (BinaryRC4EncryptionHeader)info.getHeader(); - final BinaryRC4EncryptionVerifier verifier = (BinaryRC4EncryptionVerifier)info.getVerifier(); - EncryptionRecord er = new EncryptionRecord() { - @Override - public void write(LittleEndianByteArrayOutputStream bos) { - bos.writeShort(info.getVersionMajor()); - bos.writeShort(info.getVersionMinor()); - header.write(bos); - verifier.write(bos); - } - }; - DataSpaceMapUtils.createEncryptionEntry(dir, "EncryptionInfo", er); - } - - @Override - public void setChunkSize(int chunkSize) { - this.chunkSize = chunkSize; - } - - @Override - public BinaryRC4Encryptor clone() throws CloneNotSupportedException { - return (BinaryRC4Encryptor)super.clone(); - } - - protected class BinaryRC4CipherOutputStream extends ChunkedCipherOutputStream { - - public BinaryRC4CipherOutputStream(OutputStream stream) - throws IOException, GeneralSecurityException { - super(stream, BinaryRC4Encryptor.this.chunkSize); - } - - public BinaryRC4CipherOutputStream(DirectoryNode dir) - throws IOException, GeneralSecurityException { - super(dir, BinaryRC4Encryptor.this.chunkSize); - } - - @Override - protected Cipher initCipherForBlock(Cipher cipher, int block, boolean lastChunk) - throws GeneralSecurityException { - return BinaryRC4Decryptor.initCipherForBlock(cipher, block, getEncryptionInfo(), getSecretKey(), Cipher.ENCRYPT_MODE); - } - - @Override - protected void calculateChecksum(File file, int i) { - } - - @Override - protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) - throws IOException, GeneralSecurityException { - BinaryRC4Encryptor.this.createEncryptionInfoEntry(dir); - } - - @Override - public void flush() throws IOException { - writeChunk(false); - super.flush(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java deleted file mode 100644 index e781c9d89..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java +++ /dev/null @@ -1,239 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.cryptoapi; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.util.Arrays; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionHeader; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionVerifier; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.BoundedInputStream; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianInputStream; -import org.apache.poi.util.StringUtil; - -public class CryptoAPIDecryptor extends Decryptor implements Cloneable { - - private long length = -1L; - private int chunkSize = -1; - - static class StreamDescriptorEntry { - static BitField flagStream = BitFieldFactory.getInstance(1); - - int streamOffset; - int streamSize; - int block; - int flags; - int reserved2; - String streamName; - } - - protected CryptoAPIDecryptor() { - } - - @Override - public boolean verifyPassword(String password) { - EncryptionVerifier ver = getEncryptionInfo().getVerifier(); - SecretKey skey = generateSecretKey(password, ver); - try { - Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE); - byte encryptedVerifier[] = ver.getEncryptedVerifier(); - byte verifier[] = new byte[encryptedVerifier.length]; - cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier); - setVerifier(verifier); - byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); - byte verifierHash[] = cipher.doFinal(encryptedVerifierHash); - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - byte calcVerifierHash[] = hashAlg.digest(verifier); - if (Arrays.equals(calcVerifierHash, verifierHash)) { - setSecretKey(skey); - return true; - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e); - } - return false; - } - - @Override - public Cipher initCipherForBlock(Cipher cipher, int block) - throws GeneralSecurityException { - EncryptionInfo ei = getEncryptionInfo(); - SecretKey sk = getSecretKey(); - return initCipherForBlock(cipher, block, ei, sk, Cipher.DECRYPT_MODE); - } - - protected static Cipher initCipherForBlock(Cipher cipher, int block, - EncryptionInfo encryptionInfo, SecretKey skey, int encryptMode) - throws GeneralSecurityException { - EncryptionVerifier ver = encryptionInfo.getVerifier(); - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - byte blockKey[] = new byte[4]; - LittleEndian.putUInt(blockKey, 0, block); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - hashAlg.update(skey.getEncoded()); - byte encKey[] = hashAlg.digest(blockKey); - EncryptionHeader header = encryptionInfo.getHeader(); - int keyBits = header.getKeySize(); - encKey = CryptoFunctions.getBlock0(encKey, keyBits / 8); - if (keyBits == 40) { - encKey = CryptoFunctions.getBlock0(encKey, 16); - } - SecretKey key = new SecretKeySpec(encKey, skey.getAlgorithm()); - if (cipher == null) { - cipher = CryptoFunctions.getCipher(key, header.getCipherAlgorithm(), null, null, encryptMode); - } else { - cipher.init(encryptMode, key); - } - return cipher; - } - - protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { - if (password.length() > 255) { - password = password.substring(0, 255); - } - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - hashAlg.update(ver.getSalt()); - byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); - SecretKey skey = new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); - return skey; - } - - @Override - public ChunkedCipherInputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException { - throw new IOException("not supported"); - } - - @Override - public ChunkedCipherInputStream getDataStream(InputStream stream, int size, int initialPos) - throws IOException, GeneralSecurityException { - return new CryptoAPICipherInputStream(stream, size, initialPos); - } - - /** - * Decrypt the Document-/SummaryInformation and other optionally streams. - * Opposed to other crypto modes, cryptoapi is record based and can't be used - * to stream-decrypt a whole file - * - * @see 2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream - */ - public POIFSFileSystem getSummaryEntries(DirectoryNode root, String encryptedStream) - throws IOException, GeneralSecurityException { - POIFSFileSystem fsOut = new POIFSFileSystem(); - // HSLF: encryptedStream - // HSSF: encryption - DocumentNode es = (DocumentNode) root.getEntry(encryptedStream); - DocumentInputStream dis = root.createDocumentInputStream(es); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(dis, bos); - dis.close(); - CryptoAPIDocumentInputStream sbis = new CryptoAPIDocumentInputStream(this, bos.toByteArray()); - LittleEndianInputStream leis = new LittleEndianInputStream(sbis); - int streamDescriptorArrayOffset = (int) leis.readUInt(); - /* int streamDescriptorArraySize = (int) */ leis.readUInt(); - sbis.skip(streamDescriptorArrayOffset - 8); - sbis.setBlock(0); - int encryptedStreamDescriptorCount = (int) leis.readUInt(); - StreamDescriptorEntry entries[] = new StreamDescriptorEntry[encryptedStreamDescriptorCount]; - for (int i = 0; i < encryptedStreamDescriptorCount; i++) { - StreamDescriptorEntry entry = new StreamDescriptorEntry(); - entries[i] = entry; - entry.streamOffset = (int) leis.readUInt(); - entry.streamSize = (int) leis.readUInt(); - entry.block = leis.readUShort(); - int nameSize = leis.readUByte(); - entry.flags = leis.readUByte(); - // boolean isStream = StreamDescriptorEntry.flagStream.isSet(entry.flags); - entry.reserved2 = leis.readInt(); - entry.streamName = StringUtil.readUnicodeLE(leis, nameSize); - leis.readShort(); - assert(entry.streamName.length() == nameSize); - } - - for (StreamDescriptorEntry entry : entries) { - sbis.seek(entry.streamOffset); - sbis.setBlock(entry.block); - InputStream is = new BoundedInputStream(sbis, entry.streamSize); - fsOut.createDocument(is, entry.streamName); - is.close(); - } - - leis.close(); - sbis.close(); - sbis = null; - return fsOut; - } - - /** - * @return the length of the stream returned by {@link #getDataStream(DirectoryNode)} - */ - @Override - public long getLength() { - if (length == -1L) { - throw new IllegalStateException("Decryptor.getDataStream() was not called"); - } - return length; - } - - public void setChunkSize(int chunkSize) { - this.chunkSize = chunkSize; - } - - @Override - public CryptoAPIDecryptor clone() throws CloneNotSupportedException { - return (CryptoAPIDecryptor)super.clone(); - } - - private class CryptoAPICipherInputStream extends ChunkedCipherInputStream { - - @Override - protected Cipher initCipherForBlock(Cipher existing, int block) - throws GeneralSecurityException { - return CryptoAPIDecryptor.this.initCipherForBlock(existing, block); - } - - public CryptoAPICipherInputStream(InputStream stream, long size, int initialPos) - throws GeneralSecurityException { - super(stream, size, chunkSize, initialPos); - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java deleted file mode 100644 index 573664932..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt.cryptoapi; - -import java.io.ByteArrayInputStream; -import java.security.GeneralSecurityException; - -import javax.crypto.Cipher; -import javax.crypto.ShortBufferException; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.util.Internal; - -/** - * A seekable InputStream, which is used to decrypt/extract the document entries - * within the encrypted stream - */ -@Internal -/* package */ class CryptoAPIDocumentInputStream extends ByteArrayInputStream { - private Cipher cipher; - private final CryptoAPIDecryptor decryptor; - private byte oneByte[] = { 0 }; - - public void seek(int newpos) { - if (newpos > count) { - throw new ArrayIndexOutOfBoundsException(newpos); - } - - this.pos = newpos; - mark = newpos; - } - - public void setBlock(int block) throws GeneralSecurityException { - cipher = decryptor.initCipherForBlock(cipher, block); - } - - @Override - public synchronized int read() { - int ch = super.read(); - if (ch == -1) { - return -1; - } - oneByte[0] = (byte) ch; - try { - cipher.update(oneByte, 0, 1, oneByte); - } catch (ShortBufferException e) { - throw new EncryptedDocumentException(e); - } - return oneByte[0]; - } - - @Override - public synchronized int read(byte b[], int off, int len) { - int readLen = super.read(b, off, len); - if (readLen ==-1) { - return -1; - } - try { - cipher.update(b, off, readLen, b, off); - } catch (ShortBufferException e) { - throw new EncryptedDocumentException(e); - } - return readLen; - } - - public CryptoAPIDocumentInputStream(CryptoAPIDecryptor decryptor, byte buf[]) - throws GeneralSecurityException { - super(buf); - this.decryptor = decryptor; - cipher = decryptor.initCipherForBlock(null, 0); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java deleted file mode 100644 index 5fa9564a4..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt.cryptoapi; - -import java.io.ByteArrayOutputStream; -import java.security.GeneralSecurityException; - -import javax.crypto.Cipher; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.util.Internal; - -/** - * An OutputStream for the document entries within the encrypted stream - */ -@Internal -/* package */ class CryptoAPIDocumentOutputStream extends ByteArrayOutputStream { - private final Cipher cipher; - private final CryptoAPIEncryptor encryptor; - private final byte oneByte[] = { 0 }; - - public CryptoAPIDocumentOutputStream(CryptoAPIEncryptor encryptor) throws GeneralSecurityException { - this.encryptor = encryptor; - cipher = encryptor.initCipherForBlock(null, 0); - } - - public byte[] getBuf() { - return buf; - } - - public void setSize(int count) { - this.count = count; - } - - public void setBlock(int block) throws GeneralSecurityException { - encryptor.initCipherForBlock(cipher, block); - } - - @Override - public void write(int b) { - try { - oneByte[0] = (byte)b; - cipher.update(oneByte, 0, 1, oneByte, 0); - super.write(oneByte); - } catch (Exception e) { - throw new EncryptedDocumentException(e); - } - } - - @Override - public void write(byte[] b, int off, int len) { - try { - cipher.update(b, off, len, b, off); - super.write(b, off, len); - } catch (Exception e) { - throw new EncryptedDocumentException(e); - } - } - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionHeader.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionHeader.java deleted file mode 100644 index b54dc2f0d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionHeader.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.cryptoapi; - -import java.io.IOException; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CipherProvider; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.standard.StandardEncryptionHeader; -import org.apache.poi.util.LittleEndianInput; - -public class CryptoAPIEncryptionHeader extends StandardEncryptionHeader implements Cloneable { - - public CryptoAPIEncryptionHeader(LittleEndianInput is) throws IOException { - super(is); - } - - protected CryptoAPIEncryptionHeader(CipherAlgorithm cipherAlgorithm, - HashAlgorithm hashAlgorithm, int keyBits, int blockSize, - ChainingMode chainingMode) { - super(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode); - } - - @Override - public void setKeySize(int keyBits) { - // Microsoft Base Cryptographic Provider is limited up to 40 bits - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375599(v=vs.85).aspx - boolean found = false; - for (int size : getCipherAlgorithm().allowedKeySize) { - if (size == keyBits) { - found = true; - break; - } - } - if (!found) { - throw new EncryptedDocumentException("invalid keysize "+keyBits+" for cipher algorithm "+getCipherAlgorithm()); - } - super.setKeySize(keyBits); - if (keyBits > 40) { - setCspName("Microsoft Enhanced Cryptographic Provider v1.0"); - } else { - setCspName(CipherProvider.rc4.cipherProviderName); - } - } - - @Override - public CryptoAPIEncryptionHeader clone() throws CloneNotSupportedException { - return (CryptoAPIEncryptionHeader)super.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionInfoBuilder.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionInfoBuilder.java deleted file mode 100644 index fef4dde16..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionInfoBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.cryptoapi; - -import java.io.IOException; - -import org.apache.poi.poifs.crypt.*; -import org.apache.poi.util.LittleEndianInput; - -public class CryptoAPIEncryptionInfoBuilder implements EncryptionInfoBuilder { - public CryptoAPIEncryptionInfoBuilder() { - } - - /** - * initialize the builder from a stream - */ - @Override - public void initialize(EncryptionInfo info, LittleEndianInput dis) - throws IOException { - /* int hSize = */ dis.readInt(); - CryptoAPIEncryptionHeader header = new CryptoAPIEncryptionHeader(dis); - info.setHeader(header); - info.setVerifier(new CryptoAPIEncryptionVerifier(dis, header)); - CryptoAPIDecryptor dec = new CryptoAPIDecryptor(); - dec.setEncryptionInfo(info); - info.setDecryptor(dec); - CryptoAPIEncryptor enc = new CryptoAPIEncryptor(); - enc.setEncryptionInfo(info); - info.setEncryptor(enc); - } - - /** - * initialize the builder from scratch - */ - @Override - public void initialize(EncryptionInfo info, - CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, - int keyBits, int blockSize, ChainingMode chainingMode) { - if (cipherAlgorithm == null) { - cipherAlgorithm = CipherAlgorithm.rc4; - } - if (hashAlgorithm == null) { - hashAlgorithm = HashAlgorithm.sha1; - } - if (keyBits == -1) { - keyBits = 0x28; - } - assert(cipherAlgorithm == CipherAlgorithm.rc4 && hashAlgorithm == HashAlgorithm.sha1); - - info.setHeader(new CryptoAPIEncryptionHeader(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode)); - info.setVerifier(new CryptoAPIEncryptionVerifier(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode)); - CryptoAPIDecryptor dec = new CryptoAPIDecryptor(); - dec.setEncryptionInfo(info); - info.setDecryptor(dec); - CryptoAPIEncryptor enc = new CryptoAPIEncryptor(); - enc.setEncryptionInfo(info); - info.setEncryptor(enc); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionVerifier.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionVerifier.java deleted file mode 100644 index d2c87b7ab..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptionVerifier.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.cryptoapi; - -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.standard.StandardEncryptionVerifier; -import org.apache.poi.util.LittleEndianInput; - -public class CryptoAPIEncryptionVerifier extends StandardEncryptionVerifier implements Cloneable { - - protected CryptoAPIEncryptionVerifier(LittleEndianInput is, - CryptoAPIEncryptionHeader header) { - super(is, header); - } - - protected CryptoAPIEncryptionVerifier(CipherAlgorithm cipherAlgorithm, - HashAlgorithm hashAlgorithm, int keyBits, int blockSize, - ChainingMode chainingMode) { - super(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode); - } - - @Override - protected void setSalt(byte salt[]) { - super.setSalt(salt); - } - - @Override - protected void setEncryptedVerifier(byte encryptedVerifier[]) { - super.setEncryptedVerifier(encryptedVerifier); - } - - @Override - protected void setEncryptedVerifierHash(byte encryptedVerifierHash[]) { - super.setEncryptedVerifierHash(encryptedVerifierHash); - } - - @Override - public CryptoAPIEncryptionVerifier clone() throws CloneNotSupportedException { - return (CryptoAPIEncryptionVerifier)super.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java deleted file mode 100644 index d04096c39..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java +++ /dev/null @@ -1,277 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.cryptoapi; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.WritingNotSupportedException; -import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.DataSpaceMapUtils; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIDecryptor.StreamDescriptorEntry; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.StringUtil; - -public class CryptoAPIEncryptor extends Encryptor implements Cloneable { - - private int chunkSize = 512; - - protected CryptoAPIEncryptor() { - } - - @Override - public void confirmPassword(String password) { - Random r = new SecureRandom(); - byte salt[] = new byte[16]; - byte verifier[] = new byte[16]; - r.nextBytes(salt); - r.nextBytes(verifier); - confirmPassword(password, null, null, verifier, salt, null); - } - - @Override - public void confirmPassword(String password, byte keySpec[], - byte keySalt[], byte verifier[], byte verifierSalt[], - byte integritySalt[]) { - assert(verifier != null && verifierSalt != null); - CryptoAPIEncryptionVerifier ver = (CryptoAPIEncryptionVerifier)getEncryptionInfo().getVerifier(); - ver.setSalt(verifierSalt); - SecretKey skey = CryptoAPIDecryptor.generateSecretKey(password, ver); - setSecretKey(skey); - try { - Cipher cipher = initCipherForBlock(null, 0); - byte encryptedVerifier[] = new byte[verifier.length]; - cipher.update(verifier, 0, verifier.length, encryptedVerifier); - ver.setEncryptedVerifier(encryptedVerifier); - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); - byte calcVerifierHash[] = hashAlg.digest(verifier); - byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash); - ver.setEncryptedVerifierHash(encryptedVerifierHash); - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException("Password confirmation failed", e); - } - } - - /** - * Initializes a cipher object for a given block index for encryption - * - * @param cipher may be null, otherwise the given instance is reset to the new block index - * @param block the block index, e.g. the persist/slide id (hslf) - * @return a new cipher object, if cipher was null, otherwise the reinitialized cipher - * @throws GeneralSecurityException - */ - public Cipher initCipherForBlock(Cipher cipher, int block) - throws GeneralSecurityException { - return CryptoAPIDecryptor.initCipherForBlock(cipher, block, getEncryptionInfo(), getSecretKey(), Cipher.ENCRYPT_MODE); - } - - @Override - public ChunkedCipherOutputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException { - throw new IOException("not supported"); - } - - @Override - public CryptoAPICipherOutputStream getDataStream(OutputStream stream, int initialOffset) - throws IOException, GeneralSecurityException { - return new CryptoAPICipherOutputStream(stream); - } - - /** - * Encrypt the Document-/SummaryInformation and other optionally streams. - * Opposed to other crypto modes, cryptoapi is record based and can't be used - * to stream-encrypt a whole file - * - * @see 2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream - */ - public OutputStream getSummaryEntries(DirectoryNode dir) - throws IOException, GeneralSecurityException { - CryptoAPIDocumentOutputStream bos = new CryptoAPIDocumentOutputStream(this); - byte buf[] = new byte[8]; - - bos.write(buf, 0, 8); // skip header - String entryNames[] = { - SummaryInformation.DEFAULT_STREAM_NAME, - DocumentSummaryInformation.DEFAULT_STREAM_NAME - }; - - List descList = new ArrayList(); - - int block = 0; - for (String entryName : entryNames) { - if (!dir.hasEntry(entryName)) { - continue; - } - StreamDescriptorEntry descEntry = new StreamDescriptorEntry(); - descEntry.block = block; - descEntry.streamOffset = bos.size(); - descEntry.streamName = entryName; - descEntry.flags = StreamDescriptorEntry.flagStream.setValue(0, 1); - descEntry.reserved2 = 0; - - bos.setBlock(block); - DocumentInputStream dis = dir.createDocumentInputStream(entryName); - IOUtils.copy(dis, bos); - dis.close(); - - descEntry.streamSize = bos.size() - descEntry.streamOffset; - descList.add(descEntry); - - dir.getEntry(entryName).delete(); - - block++; - } - - int streamDescriptorArrayOffset = bos.size(); - - bos.setBlock(0); - LittleEndian.putUInt(buf, 0, descList.size()); - bos.write(buf, 0, 4); - - for (StreamDescriptorEntry sde : descList) { - LittleEndian.putUInt(buf, 0, sde.streamOffset); - bos.write(buf, 0, 4); - LittleEndian.putUInt(buf, 0, sde.streamSize); - bos.write(buf, 0, 4); - LittleEndian.putUShort(buf, 0, sde.block); - bos.write(buf, 0, 2); - LittleEndian.putUByte(buf, 0, (short)sde.streamName.length()); - bos.write(buf, 0, 1); - LittleEndian.putUByte(buf, 0, (short)sde.flags); - bos.write(buf, 0, 1); - LittleEndian.putUInt(buf, 0, sde.reserved2); - bos.write(buf, 0, 4); - byte nameBytes[] = StringUtil.getToUnicodeLE(sde.streamName); - bos.write(nameBytes, 0, nameBytes.length); - LittleEndian.putShort(buf, 0, (short)0); // null-termination - bos.write(buf, 0, 2); - } - - int savedSize = bos.size(); - int streamDescriptorArraySize = savedSize - streamDescriptorArrayOffset; - LittleEndian.putUInt(buf, 0, streamDescriptorArrayOffset); - LittleEndian.putUInt(buf, 4, streamDescriptorArraySize); - - bos.reset(); - bos.setBlock(0); - bos.write(buf, 0, 8); - bos.setSize(savedSize); - - dir.createDocument("EncryptedSummary", new ByteArrayInputStream(bos.getBuf(), 0, savedSize)); - DocumentSummaryInformation dsi = PropertySetFactory.newDocumentSummaryInformation(); - - try { - dsi.write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME); - } catch (WritingNotSupportedException e) { - throw new IOException(e); - } - - return bos; - } - - protected int getKeySizeInBytes() { - return getEncryptionInfo().getHeader().getKeySize() / 8; - } - - @Override - public void setChunkSize(int chunkSize) { - this.chunkSize = chunkSize; - } - - protected void createEncryptionInfoEntry(DirectoryNode dir) throws IOException { - DataSpaceMapUtils.addDefaultDataSpace(dir); - final EncryptionInfo info = getEncryptionInfo(); - final CryptoAPIEncryptionHeader header = (CryptoAPIEncryptionHeader)getEncryptionInfo().getHeader(); - final CryptoAPIEncryptionVerifier verifier = (CryptoAPIEncryptionVerifier)getEncryptionInfo().getVerifier(); - EncryptionRecord er = new EncryptionRecord() { - @Override - public void write(LittleEndianByteArrayOutputStream bos) { - bos.writeShort(info.getVersionMajor()); - bos.writeShort(info.getVersionMinor()); - header.write(bos); - verifier.write(bos); - } - }; - DataSpaceMapUtils.createEncryptionEntry(dir, "EncryptionInfo", er); - } - - - @Override - public CryptoAPIEncryptor clone() throws CloneNotSupportedException { - return (CryptoAPIEncryptor)super.clone(); - } - - protected class CryptoAPICipherOutputStream extends ChunkedCipherOutputStream { - - @Override - protected Cipher initCipherForBlock(Cipher cipher, int block, boolean lastChunk) - throws IOException, GeneralSecurityException { - flush(); - EncryptionInfo ei = getEncryptionInfo(); - SecretKey sk = getSecretKey(); - return CryptoAPIDecryptor.initCipherForBlock(cipher, block, ei, sk, Cipher.ENCRYPT_MODE); - } - - @Override - protected void calculateChecksum(File file, int i) { - } - - @Override - protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) - throws IOException, GeneralSecurityException { - throw new EncryptedDocumentException("createEncryptionInfoEntry not supported"); - } - - public CryptoAPICipherOutputStream(OutputStream stream) - throws IOException, GeneralSecurityException { - super(stream, CryptoAPIEncryptor.this.chunkSize); - } - - @Override - public void flush() throws IOException { - writeChunk(false); - super.flush(); - } - } - -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/package.html b/trunk/src/java/org/apache/poi/poifs/crypt/package.html deleted file mode 100644 index 977cf8b5a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/package.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - -

    Implementation of the ECMA-376 Document Encryption

    -

    The implementation is split into three packages:

    -
      -
    • This package contains common functions for both current implemented cipher modes.
    • -
    • the {@link org.apache.poi.poifs.crypt.standard standard} package is part of the base poi jar and contains classes for the standard encryption ...
    • -
    • the {@link org.apache.poi.poifs.crypt.agile agile} package is part of the poi ooxml jar and the provides agile encryption support.
    • -
    - -

    Related Documentation

    - -Some implementations informations can be found under: - - - -@see org.apache.poi.poifs.crypt.standard -@see org.apache.poi.poifs.crypt.agile - - diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/standard/EncryptionRecord.java b/trunk/src/java/org/apache/poi/poifs/crypt/standard/EncryptionRecord.java deleted file mode 100644 index bf65fbe79..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/standard/EncryptionRecord.java +++ /dev/null @@ -1,23 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt.standard; - -import org.apache.poi.util.LittleEndianByteArrayOutputStream; - -public interface EncryptionRecord { - void write(LittleEndianByteArrayOutputStream os); -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java deleted file mode 100644 index d06f9a373..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java +++ /dev/null @@ -1,160 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt.standard; - -import static org.apache.poi.poifs.crypt.CryptoFunctions.hashPassword; - -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.util.Arrays; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionHeader; -import org.apache.poi.poifs.crypt.EncryptionVerifier; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.util.BoundedInputStream; -import org.apache.poi.util.LittleEndian; - -/** - */ -public class StandardDecryptor extends Decryptor implements Cloneable { - private long _length = -1; - - protected StandardDecryptor() { - } - - @Override - public boolean verifyPassword(String password) { - EncryptionVerifier ver = getEncryptionInfo().getVerifier(); - SecretKey skey = generateSecretKey(password, ver, getKeySizeInBytes()); - Cipher cipher = getCipher(skey); - - try { - byte encryptedVerifier[] = ver.getEncryptedVerifier(); - byte verifier[] = cipher.doFinal(encryptedVerifier); - setVerifier(verifier); - MessageDigest sha1 = CryptoFunctions.getMessageDigest(ver.getHashAlgorithm()); - byte[] calcVerifierHash = sha1.digest(verifier); - byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); - byte decryptedVerifierHash[] = cipher.doFinal(encryptedVerifierHash); - - // see 2.3.4.9 Password Verification (Standard Encryption) - // ... The number of bytes used by the encrypted Verifier hash MUST be 32 ... - // TODO: check and trim/pad the hashes to 32 - byte[] verifierHash = Arrays.copyOf(decryptedVerifierHash, calcVerifierHash.length); - - if (Arrays.equals(calcVerifierHash, verifierHash)) { - setSecretKey(skey); - return true; - } else { - return false; - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e); - } - } - - protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver, int keySize) { - HashAlgorithm hashAlgo = ver.getHashAlgorithm(); - - byte pwHash[] = hashPassword(password, hashAlgo, ver.getSalt(), ver.getSpinCount()); - - byte[] blockKey = new byte[4]; - LittleEndian.putInt(blockKey, 0, 0); - - byte[] finalHash = CryptoFunctions.generateKey(pwHash, hashAlgo, blockKey, hashAlgo.hashSize); - byte x1[] = fillAndXor(finalHash, (byte) 0x36); - byte x2[] = fillAndXor(finalHash, (byte) 0x5c); - - byte[] x3 = new byte[x1.length + x2.length]; - System.arraycopy(x1, 0, x3, 0, x1.length); - System.arraycopy(x2, 0, x3, x1.length, x2.length); - - byte[] key = Arrays.copyOf(x3, keySize); - - SecretKey skey = new SecretKeySpec(key, ver.getCipherAlgorithm().jceId); - return skey; - } - - protected static byte[] fillAndXor(byte hash[], byte fillByte) { - byte[] buff = new byte[64]; - Arrays.fill(buff, fillByte); - - for (int i=0; i>> (8 - shift))); - } - - - /** - * Decrypts a xor obfuscated byte array. - * The data is decrypted in-place - * - * @see 2.3.7.3 Binary Document XOR Data Transformation Method 1 - */ - @Override - public void setNextRecordSize(int recordSize) { - final int pos = (int)getPos(); - final byte chunk[] = getChunk(); - final int chunkMask = getChunkMask(); - recordStart = pos; - recordEnd = recordStart+recordSize; - int nextBytes = Math.min(recordSize, chunk.length-(pos & chunkMask)); - invokeCipher(nextBytes, true); - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionHeader.java b/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionHeader.java deleted file mode 100644 index 873c1abde..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionHeader.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.xor; - -import org.apache.poi.poifs.crypt.EncryptionHeader; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; - -public class XOREncryptionHeader extends EncryptionHeader implements EncryptionRecord, Cloneable { - - protected XOREncryptionHeader() { - } - - @Override - public void write(LittleEndianByteArrayOutputStream leos) { - } - - @Override - public XOREncryptionHeader clone() throws CloneNotSupportedException { - return (XOREncryptionHeader)super.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionInfoBuilder.java b/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionInfoBuilder.java deleted file mode 100644 index 9fcaf8b35..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionInfoBuilder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.xor; - -import java.io.IOException; - -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionInfoBuilder; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.util.LittleEndianInput; - -public class XOREncryptionInfoBuilder implements EncryptionInfoBuilder { - - public XOREncryptionInfoBuilder() { - } - - @Override - public void initialize(EncryptionInfo info, LittleEndianInput dis) - throws IOException { - info.setHeader(new XOREncryptionHeader()); - info.setVerifier(new XOREncryptionVerifier(dis)); - Decryptor dec = new XORDecryptor(); - dec.setEncryptionInfo(info); - info.setDecryptor(dec); - Encryptor enc = new XOREncryptor(); - enc.setEncryptionInfo(info); - info.setEncryptor(enc); - } - - @Override - public void initialize(EncryptionInfo info, - CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, - int keyBits, int blockSize, ChainingMode chainingMode) { - info.setHeader(new XOREncryptionHeader()); - info.setVerifier(new XOREncryptionVerifier()); - Decryptor dec = new XORDecryptor(); - dec.setEncryptionInfo(info); - info.setDecryptor(dec); - Encryptor enc = new XOREncryptor(); - enc.setEncryptionInfo(info); - info.setEncryptor(enc); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionVerifier.java b/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionVerifier.java deleted file mode 100644 index ba0645cb7..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionVerifier.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.xor; - -import org.apache.poi.poifs.crypt.EncryptionVerifier; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianInput; - -public class XOREncryptionVerifier extends EncryptionVerifier implements EncryptionRecord, Cloneable { - - protected XOREncryptionVerifier() { - setEncryptedKey(new byte[2]); - setEncryptedVerifier(new byte[2]); - } - - protected XOREncryptionVerifier(LittleEndianInput is) { - /** - * key (2 bytes): An unsigned integer that specifies the obfuscation key. - * See [MS-OFFCRYPTO], 2.3.6.2 section, the first step of initializing XOR - * array where it describes the generation of 16-bit XorKey value. - */ - byte key[] = new byte[2]; - is.readFully(key); - setEncryptedKey(key); - - /** - * verificationBytes (2 bytes): An unsigned integer that specifies - * the password verification identifier. - */ - byte verifier[] = new byte[2]; - is.readFully(verifier); - setEncryptedVerifier(verifier); - } - - @Override - public void write(LittleEndianByteArrayOutputStream bos) { - bos.write(getEncryptedKey()); - bos.write(getEncryptedVerifier()); - } - - @Override - public XOREncryptionVerifier clone() throws CloneNotSupportedException { - return (XOREncryptionVerifier)super.clone(); - } - - @Override - protected final void setEncryptedVerifier(byte[] encryptedVerifier) { - super.setEncryptedVerifier(encryptedVerifier); - } - - @Override - protected final void setEncryptedKey(byte[] encryptedKey) { - super.setEncryptedKey(encryptedKey); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java b/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java deleted file mode 100644 index 1c0834c8c..000000000 --- a/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java +++ /dev/null @@ -1,180 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.xor; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.util.BitSet; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.util.LittleEndian; - -public class XOREncryptor extends Encryptor implements Cloneable { - protected XOREncryptor() { - } - - @Override - public void confirmPassword(String password) { - int keyComp = CryptoFunctions.createXorKey1(password); - int verifierComp = CryptoFunctions.createXorVerifier1(password); - byte xorArray[] = CryptoFunctions.createXorArray1(password); - - byte shortBuf[] = new byte[2]; - XOREncryptionVerifier ver = (XOREncryptionVerifier)getEncryptionInfo().getVerifier(); - LittleEndian.putUShort(shortBuf, 0, keyComp); - ver.setEncryptedKey(shortBuf); - LittleEndian.putUShort(shortBuf, 0, verifierComp); - ver.setEncryptedVerifier(shortBuf); - setSecretKey(new SecretKeySpec(xorArray, "XOR")); - } - - @Override - public void confirmPassword(String password, byte keySpec[], - byte keySalt[], byte verifier[], byte verifierSalt[], - byte integritySalt[]) { - confirmPassword(password); - } - - @Override - public OutputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException { - return new XORCipherOutputStream(dir); - } - - @Override - public XORCipherOutputStream getDataStream(OutputStream stream, int initialOffset) - throws IOException, GeneralSecurityException { - return new XORCipherOutputStream(stream, initialOffset); - } - - protected int getKeySizeInBytes() { - return -1; - } - - @Override - public void setChunkSize(int chunkSize) { - // chunkSize is irrelevant - } - - protected void createEncryptionInfoEntry(DirectoryNode dir) throws IOException { - } - - @Override - public XOREncryptor clone() throws CloneNotSupportedException { - return (XOREncryptor)super.clone(); - } - - private class XORCipherOutputStream extends ChunkedCipherOutputStream { - private int recordStart = 0; - private int recordEnd = 0; - - public XORCipherOutputStream(OutputStream stream, int initialPos) throws IOException, GeneralSecurityException { - super(stream, -1); - } - - public XORCipherOutputStream(DirectoryNode dir) throws IOException, GeneralSecurityException { - super(dir, -1); - } - - @Override - protected Cipher initCipherForBlock(Cipher cipher, int block, boolean lastChunk) - throws GeneralSecurityException { - return XORDecryptor.initCipherForBlock(cipher, block, getEncryptionInfo(), getSecretKey(), Cipher.ENCRYPT_MODE); - } - - @Override - protected void calculateChecksum(File file, int i) { - } - - @Override - protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) - throws IOException, GeneralSecurityException { - XOREncryptor.this.createEncryptionInfoEntry(dir); - } - - @Override - public void setNextRecordSize(int recordSize, boolean isPlain) { - if (recordEnd > 0 && !isPlain) { - // encrypt last record - invokeCipher((int)getPos(), true); - } - recordStart = (int)getTotalPos()+4; - recordEnd = recordStart+recordSize; - } - - @Override - public void flush() throws IOException { - setNextRecordSize(0, true); - super.flush(); - } - - @Override - protected int invokeCipher(int posInChunk, boolean doFinal) { - if (posInChunk == 0) { - return 0; - } - - final int start = Math.max(posInChunk-(recordEnd-recordStart), 0); - - final BitSet plainBytes = getPlainByteFlags(); - final byte xorArray[] = getEncryptionInfo().getEncryptor().getSecretKey().getEncoded(); - final byte chunk[] = getChunk(); - final byte plain[] = (plainBytes.isEmpty()) ? null : chunk.clone(); - - /* - * From: http://social.msdn.microsoft.com/Forums/en-US/3dadbed3-0e68-4f11-8b43-3a2328d9ebd5 - * - * The initial value for XorArrayIndex is as follows: - * XorArrayIndex = (FileOffset + Data.Length) % 16 - * - * The FileOffset variable in this context is the stream offset into the Workbook stream at - * the time we are about to write each of the bytes of the record data. - * This (the value) is then incremented after each byte is written. - */ - // ... also need to handle invocation in case of a filled chunk - int xorArrayIndex = recordEnd+(start-recordStart); - - for (int i=start; i < posInChunk; i++) { - byte value = chunk[i]; - value ^= xorArray[(xorArrayIndex++) & 0x0F]; - value = rotateLeft(value, 8-3); - chunk[i] = value; - } - - for (int i = plainBytes.nextSetBit(start); i >= 0 && i < posInChunk; i = plainBytes.nextSetBit(i+1)) { - chunk[i] = plain[i]; - } - - return posInChunk; - } - - private byte rotateLeft(byte bits, int shift) { - return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (8 - shift))); - } - - - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/dev/POIFSDump.java b/trunk/src/java/org/apache/poi/poifs/dev/POIFSDump.java deleted file mode 100644 index ad3e6176e..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/POIFSDump.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.dev; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.Iterator; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.NPOIFSStream; -import org.apache.poi.poifs.property.NPropertyTable; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.util.IOUtils; - -/** - * Dump internal structure of a OLE2 file into file system - */ -public class POIFSDump { - public static void main(String[] args) throws IOException { - if (args.length == 0) { - System.err.println("Must specify at least one file to dump"); - System.exit(1); - } - - boolean dumpProps = false, dumpMini = false; - for (String filename : args) { - if (filename.equalsIgnoreCase("-dumprops") || - filename.equalsIgnoreCase("-dump-props") || - filename.equalsIgnoreCase("-dump-properties")) { - dumpProps = true; - continue; - } - if (filename.equalsIgnoreCase("-dumpmini") || - filename.equalsIgnoreCase("-dump-mini") || - filename.equalsIgnoreCase("-dump-ministream") || - filename.equalsIgnoreCase("-dump-mini-stream")) { - dumpMini = true; - continue; - } - - System.out.println("Dumping " + filename); - FileInputStream is = new FileInputStream(filename); - NPOIFSFileSystem fs; - try { - fs = new NPOIFSFileSystem(is); - } finally { - is.close(); - } - try { - DirectoryEntry root = fs.getRoot(); - String filenameWithoutPath = new File(filename).getName(); - File dumpDir = new File(filenameWithoutPath + "_dump"); - File file = new File(dumpDir, root.getName()); - if (!file.exists() && !file.mkdirs()) { - throw new IOException("Could not create directory " + file); - } - - dump(root, file); - - if (dumpProps) { - HeaderBlock header = fs.getHeaderBlock(); - dump(fs, header.getPropertyStart(), "properties", file); - } - if (dumpMini) { - NPropertyTable props = fs.getPropertyTable(); - int startBlock = props.getRoot().getStartBlock(); - if (startBlock == POIFSConstants.END_OF_CHAIN) { - System.err.println("No Mini Stream in file"); - } else { - dump(fs, startBlock, "mini-stream", file); - } - } - } finally { - fs.close(); - } - } - } - - public static void dump(DirectoryEntry root, File parent) throws IOException { - for(Iterator it = root.getEntries(); it.hasNext();){ - Entry entry = it.next(); - if(entry instanceof DocumentNode){ - DocumentNode node = (DocumentNode)entry; - DocumentInputStream is = new DocumentInputStream(node); - byte[] bytes = IOUtils.toByteArray(is); - is.close(); - - OutputStream out = new FileOutputStream(new File(parent, node.getName().trim())); - try { - out.write(bytes); - } finally { - out.close(); - } - } else if (entry instanceof DirectoryEntry){ - DirectoryEntry dir = (DirectoryEntry)entry; - File file = new File(parent, entry.getName()); - if(!file.exists() && !file.mkdirs()) { - throw new IOException("Could not create directory " + file); - } - dump(dir, file); - } else { - System.err.println("Skipping unsupported POIFS entry: " + entry); - } - } - } - public static void dump(NPOIFSFileSystem fs, int startBlock, String name, File parent) throws IOException { - File file = new File(parent, name); - FileOutputStream out = new FileOutputStream(file); - try { - NPOIFSStream stream = new NPOIFSStream(fs, startBlock); - - byte[] b = new byte[fs.getBigBlockSize()]; - for (ByteBuffer bb : stream) { - int len = bb.remaining(); - bb.get(b); - out.write(b, 0, len); - } - } finally { - out.close(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java b/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java deleted file mode 100644 index 642ffa0f9..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java +++ /dev/null @@ -1,181 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.dev; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.Property; -import org.apache.poi.poifs.property.PropertyTable; -import org.apache.poi.poifs.storage.BlockAllocationTableReader; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.poifs.storage.ListManagedBlock; -import org.apache.poi.poifs.storage.RawDataBlockList; -import org.apache.poi.poifs.storage.SmallBlockTableReader; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.IntList; - -/** - * A very low level debugging tool, for printing out core - * information on the headers and FAT blocks. - * You probably only want to use this if you're trying - * to understand POIFS, or if you're trying to track - * down the source of corruption in a file. - */ -public class POIFSHeaderDumper { - /** - * Display the entries of multiple POIFS files - * - * @param args the names of the files to be displayed - */ - public static void main(final String args[]) throws Exception { - if (args.length == 0) { - System.err.println("Must specify at least one file to view"); - System.exit(1); - } - - for (int j = 0; j < args.length; j++) { - viewFile(args[j]); - } - } - - public static void viewFile(final String filename) throws Exception { - System.out.println("Dumping headers from: " + filename); - InputStream inp = new FileInputStream(filename); - - // Header - HeaderBlock header_block = new HeaderBlock(inp); - displayHeader(header_block); - - // Raw blocks - POIFSBigBlockSize bigBlockSize = header_block.getBigBlockSize(); - RawDataBlockList data_blocks = new RawDataBlockList(inp, bigBlockSize); - displayRawBlocksSummary(data_blocks); - - // Main FAT Table - BlockAllocationTableReader batReader = - new BlockAllocationTableReader( - header_block.getBigBlockSize(), - header_block.getBATCount(), - header_block.getBATArray(), - header_block.getXBATCount(), - header_block.getXBATIndex(), - data_blocks); - displayBATReader("Big Blocks", batReader); - - // Properties Table - PropertyTable properties = - new PropertyTable(header_block, data_blocks); - - // Mini Fat - BlockAllocationTableReader sbatReader = - SmallBlockTableReader._getSmallDocumentBlockReader( - bigBlockSize, data_blocks, properties.getRoot(), - header_block.getSBATStart() - ); - displayBATReader("Small Blocks", sbatReader); - - // Summary of the properties - displayPropertiesSummary(properties); - } - - public static void displayHeader(HeaderBlock header_block) throws Exception { - System.out.println("Header Details:"); - System.out.println(" Block size: " + header_block.getBigBlockSize().getBigBlockSize()); - System.out.println(" BAT (FAT) header blocks: " + header_block.getBATArray().length); - System.out.println(" BAT (FAT) block count: " + header_block.getBATCount()); - if (header_block.getBATCount() > 0) - System.out.println(" BAT (FAT) block 1 at: " + header_block.getBATArray()[0]); - System.out.println(" XBAT (FAT) block count: " + header_block.getXBATCount()); - System.out.println(" XBAT (FAT) block 1 at: " + header_block.getXBATIndex()); - System.out.println(" SBAT (MiniFAT) block count: " + header_block.getSBATCount()); - System.out.println(" SBAT (MiniFAT) block 1 at: " + header_block.getSBATStart()); - System.out.println(" Property table at: " + header_block.getPropertyStart()); - System.out.println(""); - } - - public static void displayRawBlocksSummary(RawDataBlockList data_blocks) throws Exception { - System.out.println("Raw Blocks Details:"); - System.out.println(" Number of blocks: " + data_blocks.blockCount()); - - for(int i=0; i " + bnS); - } - - System.out.println(""); - } - - public static void displayPropertiesSummary(PropertyTable properties) { - System.out.println("Mini Stream starts at " + properties.getRoot().getStartBlock()); - System.out.println("Mini Stream length is " + properties.getRoot().getSize()); - System.out.println(); - - System.out.println("Properties and their block start:"); - displayProperties(properties.getRoot(), ""); - System.out.println(""); - } - public static void displayProperties(DirectoryProperty prop, String indent) { - String nextIndent = indent + " "; - System.out.println(indent + "-> " + prop.getName()); - for (Property cp : prop) { - if (cp instanceof DirectoryProperty) { - displayProperties((DirectoryProperty)cp, nextIndent); - } else { - System.out.println(nextIndent + "=> " + cp.getName()); - System.out.print(nextIndent + " " + cp.getSize() + " bytes in "); - if (cp.shouldUseSmallBlocks()) { - System.out.print("mini"); - } else { - System.out.print("main"); - } - System.out.println(" stream, starts at " + cp.getStartBlock()); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/dev/POIFSLister.java b/trunk/src/java/org/apache/poi/poifs/dev/POIFSLister.java deleted file mode 100644 index 357773a63..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/POIFSLister.java +++ /dev/null @@ -1,104 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.dev; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Iterator; - -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * A lister of the entries in POIFS files. - * - * Much simpler than {@link POIFSViewer} - */ -public class POIFSLister { - /** - * Display the entries of multiple POIFS files - * - * @param args the names of the files to be displayed - */ - public static void main(final String args[]) throws IOException { - if (args.length == 0) { - System.err.println("Must specify at least one file to view"); - System.exit(1); - } - - boolean withSizes = false; - boolean newPOIFS = true; - for (int j = 0; j < args.length; j++) { - if (args[j].equalsIgnoreCase("-size") || args[j].equalsIgnoreCase("-sizes")) { - withSizes = true; - } else if (args[j].equalsIgnoreCase("-old") || args[j].equalsIgnoreCase("-old-poifs")) { - newPOIFS = false; - } else { - if(newPOIFS) { - viewFile(args[j], withSizes); - } else { - viewFileOld(args[j], withSizes); - } - } - } - } - - public static void viewFile(final String filename, boolean withSizes) throws IOException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(filename)); - displayDirectory(fs.getRoot(), "", withSizes); - } - - public static void viewFileOld(final String filename, boolean withSizes) throws IOException { - POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(filename)); - displayDirectory(fs.getRoot(), "", withSizes); - } - - public static void displayDirectory(DirectoryNode dir, String indent, boolean withSizes) { - System.out.println(indent + dir.getName() + " -"); - String newIndent = indent + " "; - - boolean hadChildren = false; - for(Iterator it = dir.getEntries(); it.hasNext();) { - hadChildren = true; - Entry entry = it.next(); - if (entry instanceof DirectoryNode) { - displayDirectory((DirectoryNode) entry, newIndent, withSizes); - } else { - DocumentNode doc = (DocumentNode) entry; - String name = doc.getName(); - String size = ""; - if (name.charAt(0) < 10) { - String altname = "(0x0" + (int) name.charAt(0) + ")" + name.substring(1); - name = name.substring(1) + " <" + altname + ">"; - } - if (withSizes) { - size = " [" + doc.getSize() + " / 0x" + - Integer.toHexString(doc.getSize()) + "]"; - } - System.out.println(newIndent + name + size); - } - } - if (!hadChildren) { - System.out.println(newIndent + "(no children)"); - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewEngine.java b/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewEngine.java deleted file mode 100644 index 84f2a5463..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewEngine.java +++ /dev/null @@ -1,132 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.dev; - -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * This class contains methods used to inspect POIFSViewable objects - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public class POIFSViewEngine -{ - private static final String _EOL = System.getProperty("line.separator"); - - /** - * Inspect an object that may be viewable, and drill down if told - * to - * - * @param viewable the object to be viewed - * @param drilldown if true, and the object implements - * POIFSViewable, inspect the objects' contents - * (recursively) - * @param indentLevel how far in to indent each string - * @param indentString string to use for indenting - * - * @return a List of Strings holding the content - */ - - public static List inspectViewable(final Object viewable, - final boolean drilldown, - final int indentLevel, - final String indentString) - { - List objects = new ArrayList(); - - if (viewable instanceof POIFSViewable) - { - POIFSViewable inspected = ( POIFSViewable ) viewable; - - objects.add(indent(indentLevel, indentString, - inspected.getShortDescription())); - if (drilldown) - { - if (inspected.preferArray()) - { - Object[] data = inspected.getViewableArray(); - - for (int j = 0; j < data.length; j++) - { - objects.addAll(inspectViewable(data[ j ], drilldown, - indentLevel + 1, - indentString)); - } - } - else - { - Iterator iter = inspected.getViewableIterator(); - - while (iter.hasNext()) - { - objects.addAll(inspectViewable(iter.next(), - drilldown, - indentLevel + 1, - indentString)); - } - } - } - } - else - { - objects.add(indent(indentLevel, indentString, - viewable.toString())); - } - return objects; - } - - private static String indent(final int indentLevel, - final String indentString, final String data) - { - StringBuffer finalBuffer = new StringBuffer(); - StringBuffer indentPrefix = new StringBuffer(); - - for (int j = 0; j < indentLevel; j++) - { - indentPrefix.append(indentString); - } - LineNumberReader reader = - new LineNumberReader(new StringReader(data)); - - try - { - String line = reader.readLine(); - - while (line != null) - { - finalBuffer.append(indentPrefix).append(line).append(_EOL); - line = reader.readLine(); - } - } - catch (IOException e) - { - finalBuffer.append(indentPrefix).append(e.getMessage()) - .append(_EOL); - } - return finalBuffer.toString(); - } -} // end public class POIFSViewEngine - diff --git a/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewable.java b/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewable.java deleted file mode 100644 index 8349e6697..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewable.java +++ /dev/null @@ -1,78 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.dev; - -import java.util.Iterator; - -/** - * Interface for a drill-down viewable object. Such an object has - * content that may or may not be displayed, at the discretion of the - * viewer. The content is returned to the viewer as an array or as an - * Iterator, and the object provides a clue as to which technique the - * viewer should use to get its content. - * - * A POIFSViewable object is also expected to provide a short - * description of itself, that can be used by a viewer when the - * viewable object is collapsed. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface POIFSViewable -{ - - /** - * Get an array of objects, some of which may implement - * POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - - public Object [] getViewableArray(); - - /** - * Get an Iterator of objects, some of which may implement - * POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty - * back end store - */ - public Iterator getViewableIterator(); - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, false if - * a viewer should call getViewableIterator - */ - - public boolean preferArray(); - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - - public String getShortDescription(); -} // end public interface POIFSViewable - diff --git a/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewer.java b/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewer.java deleted file mode 100644 index cf98c0147..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/POIFSViewer.java +++ /dev/null @@ -1,81 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.dev; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; - -/** - * A simple viewer for POIFS files - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public class POIFSViewer -{ - - /** - * Display the contents of multiple POIFS files - * - * @param args the names of the files to be displayed - */ - - public static void main(final String args[]) { - if (args.length == 0) { - System.err.println("Must specify at least one file to view"); - System.exit(1); - } - boolean printNames = (args.length > 1); - - for (int j = 0; j < args.length; j++) - { - viewFile(args[ j ], printNames); - } - } - - private static void viewFile(String filename, boolean printName) { - if (printName) { - StringBuffer flowerbox = new StringBuffer(); - - flowerbox.append("."); - for (int j = 0; j < filename.length(); j++) { - flowerbox.append("-"); - } - flowerbox.append("."); - System.out.println(flowerbox); - System.out.println("|" + filename + "|"); - System.out.println(flowerbox); - } - try { - NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(filename)); - List strings = POIFSViewEngine.inspectViewable(fs, true, 0, " "); - for (String s : strings) { - System.out.print(s); - } - fs.close(); - } catch (IOException e) { - System.out.println(e.getMessage()); - } - } -} // end public class POIFSViewer - diff --git a/trunk/src/java/org/apache/poi/poifs/dev/package.html b/trunk/src/java/org/apache/poi/poifs/dev/package.html deleted file mode 100644 index e4e60cece..000000000 --- a/trunk/src/java/org/apache/poi/poifs/dev/package.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - -DEV package serves two purposes. 1. Examples for how to use POIFS and 2. tools for developing -and validating POIFS. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java b/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java deleted file mode 100644 index 80151146a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java +++ /dev/null @@ -1,330 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.eventfilesystem; - -import java.io.*; - -import java.util.*; - -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.OPOIFSDocument; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; -import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.Property; -import org.apache.poi.poifs.property.PropertyTable; -import org.apache.poi.poifs.storage.BlockAllocationTableReader; -import org.apache.poi.poifs.storage.BlockList; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.poifs.storage.RawDataBlockList; -import org.apache.poi.poifs.storage.SmallBlockTableReader; - -/** - * An event-driven reader for POIFS file systems. Users of this class - * first create an instance of it, then use the registerListener - * methods to register POIFSReaderListener instances for specific - * documents. Once all the listeners have been registered, the read() - * method is called, which results in the listeners being notified as - * their documents are read. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public class POIFSReader -{ - private final POIFSReaderRegistry registry; - private boolean registryClosed; - - /** - * Create a POIFSReader - */ - - public POIFSReader() - { - registry = new POIFSReaderRegistry(); - registryClosed = false; - } - - /** - * Read from an InputStream and process the documents we get - * - * @param stream the InputStream from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - - public void read(final InputStream stream) - throws IOException - { - registryClosed = true; - - // read the header block from the stream - HeaderBlock header_block = new HeaderBlock(stream); - - // read the rest of the stream into blocks - RawDataBlockList data_blocks = new RawDataBlockList(stream, header_block.getBigBlockSize()); - - // set up the block allocation table (necessary for the - // data_blocks to be manageable - new BlockAllocationTableReader(header_block.getBigBlockSize(), - header_block.getBATCount(), - header_block.getBATArray(), - header_block.getXBATCount(), - header_block.getXBATIndex(), - data_blocks); - - // get property table from the document - PropertyTable properties = - new PropertyTable(header_block, data_blocks); - - // process documents - processProperties(SmallBlockTableReader - .getSmallDocumentBlocks( - header_block.getBigBlockSize(), - data_blocks, properties.getRoot(), - header_block.getSBATStart()), - data_blocks, properties.getRoot() - .getChildren(), new POIFSDocumentPath()); - } - - /** - * Register a POIFSReaderListener for all documents - * - * @param listener the listener to be registered - * - * @exception NullPointerException if listener is null - * @exception IllegalStateException if read() has already been - * called - */ - - public void registerListener(final POIFSReaderListener listener) - { - if (listener == null) - { - throw new NullPointerException(); - } - if (registryClosed) - { - throw new IllegalStateException(); - } - registry.registerListener(listener); - } - - /** - * Register a POIFSReaderListener for a document in the root - * directory - * - * @param listener the listener to be registered - * @param name the document name - * - * @exception NullPointerException if listener is null or name is - * null or empty - * @exception IllegalStateException if read() has already been - * called - */ - - public void registerListener(final POIFSReaderListener listener, - final String name) - { - registerListener(listener, null, name); - } - - /** - * Register a POIFSReaderListener for a document in the specified - * directory - * - * @param listener the listener to be registered - * @param path the document path; if null, the root directory is - * assumed - * @param name the document name - * - * @exception NullPointerException if listener is null or name is - * null or empty - * @exception IllegalStateException if read() has already been - * called - */ - - public void registerListener(final POIFSReaderListener listener, - final POIFSDocumentPath path, - final String name) - { - if ((listener == null) || (name == null) || (name.length() == 0)) - { - throw new NullPointerException(); - } - if (registryClosed) - { - throw new IllegalStateException(); - } - registry.registerListener(listener, - (path == null) ? new POIFSDocumentPath() - : path, name); - } - - /** - * read in files - * - * @param args names of the files - * - * @exception IOException - */ - - public static void main(String args[]) - throws IOException - { - if (args.length == 0) - { - System.err - .println("at least one argument required: input filename(s)"); - System.exit(1); - } - - // register for all - for (int j = 0; j < args.length; j++) - { - POIFSReader reader = new POIFSReader(); - POIFSReaderListener listener = new SampleListener(); - - reader.registerListener(listener); - System.out.println("reading " + args[ j ]); - FileInputStream istream = new FileInputStream(args[ j ]); - - reader.read(istream); - istream.close(); - } - } - - private void processProperties(final BlockList small_blocks, - final BlockList big_blocks, - final Iterator properties, - final POIFSDocumentPath path) - throws IOException - { - while (properties.hasNext()) - { - Property property = properties.next(); - String name = property.getName(); - - if (property.isDirectory()) - { - POIFSDocumentPath new_path = new POIFSDocumentPath(path, - new String[] - { - name - }); - - processProperties( - small_blocks, big_blocks, - (( DirectoryProperty ) property).getChildren(), new_path); - } - else - { - int startBlock = property.getStartBlock(); - Iterator listeners = registry.getListeners(path, name); - - if (listeners.hasNext()) - { - int size = property.getSize(); - OPOIFSDocument document = null; - - if (property.shouldUseSmallBlocks()) - { - document = - new OPOIFSDocument(name, small_blocks - .fetchBlocks(startBlock, -1), size); - } - else - { - document = - new OPOIFSDocument(name, big_blocks - .fetchBlocks(startBlock, -1), size); - } - while (listeners.hasNext()) - { - POIFSReaderListener listener = listeners.next(); - - listener.processPOIFSReaderEvent( - new POIFSReaderEvent( - new DocumentInputStream(document), path, - name)); - } - } - else - { - - // consume the document's data and discard it - if (property.shouldUseSmallBlocks()) - { - small_blocks.fetchBlocks(startBlock, -1); - } - else - { - big_blocks.fetchBlocks(startBlock, -1); - } - } - } - } - } - - private static class SampleListener - implements POIFSReaderListener - { - - /** - * Constructor SampleListener - */ - - SampleListener() - { - } - - /** - * Method processPOIFSReaderEvent - * - * @param event - */ - - public void processPOIFSReaderEvent(final POIFSReaderEvent event) - { - @SuppressWarnings("resource") - DocumentInputStream istream = event.getStream(); - POIFSDocumentPath path = event.getPath(); - String name = event.getName(); - - try - { - byte[] data = new byte[ istream.available() ]; - - istream.read(data); - int pathLength = path.length(); - - for (int k = 0; k < pathLength; k++) - { - System.out.print("/" + path.getComponent(k)); - } - System.out.println("/" + name + ": " + data.length - + " bytes read"); - } - catch (IOException ignored) - { - } - } - } // end private class SampleListener -} // end public class POIFSReader - diff --git a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderEvent.java b/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderEvent.java deleted file mode 100644 index 4d9d93fa2..000000000 --- a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderEvent.java +++ /dev/null @@ -1,81 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.eventfilesystem; - -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; - -/** - * Class POIFSReaderEvent - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -public class POIFSReaderEvent -{ - private final DocumentInputStream stream; - private final POIFSDocumentPath path; - private final String documentName; - - /** - * package scoped constructor - * - * @param stream the DocumentInputStream, freshly opened - * @param path the path of the document - * @param documentName the name of the document - */ - - POIFSReaderEvent(final DocumentInputStream stream, - final POIFSDocumentPath path, final String documentName) - { - this.stream = stream; - this.path = path; - this.documentName = documentName; - } - - /** - * @return the DocumentInputStream, freshly opened - */ - - public DocumentInputStream getStream() - { - return stream; - } - - /** - * @return the document's path - */ - - public POIFSDocumentPath getPath() - { - return path; - } - - /** - * @return the document's name - */ - - public String getName() - { - return documentName; - } -} // end public class POIFSReaderEvent - diff --git a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderListener.java b/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderListener.java deleted file mode 100644 index 56a3b7847..000000000 --- a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderListener.java +++ /dev/null @@ -1,41 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.eventfilesystem; - -/** - * Interface POIFSReaderListener - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -public interface POIFSReaderListener -{ - - /** - * Process a POIFSReaderEvent that this listener had registered - * for - * - * @param event the POIFSReaderEvent - */ - - public void processPOIFSReaderEvent(POIFSReaderEvent event); -} // end public interface POIFSReaderListener - diff --git a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderRegistry.java b/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderRegistry.java deleted file mode 100644 index 1ea85f7c8..000000000 --- a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReaderRegistry.java +++ /dev/null @@ -1,184 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.eventfilesystem; - -import java.util.*; - -import org.apache.poi.poifs.filesystem.DocumentDescriptor; -import org.apache.poi.poifs.filesystem.POIFSDocumentPath; - -/** - * A registry for POIFSReaderListeners and the DocumentDescriptors of - * the documents those listeners are interested in - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -class POIFSReaderRegistry -{ - - // the POIFSReaderListeners who listen to all POIFSReaderEvents - private Set omnivorousListeners; - - // Each mapping in this Map has a key consisting of a - // POIFSReaderListener and a value cosisting of a Set of - // DocumentDescriptors for the documents that POIFSReaderListener - // is interested in; used to efficiently manage the registry - private Map> selectiveListeners; - - // Each mapping in this Map has a key consisting of a - // DocumentDescriptor and a value consisting of a Set of - // POIFSReaderListeners for the document matching that - // DocumentDescriptor; used when a document is found, to quickly - // get the listeners interested in that document - private Map> chosenDocumentDescriptors; - - /** - * Construct the registry - */ - - POIFSReaderRegistry() - { - omnivorousListeners = new HashSet(); - selectiveListeners = new HashMap>(); - chosenDocumentDescriptors = new HashMap>(); - } - - /** - * register a POIFSReaderListener for a particular document - * - * @param listener the listener - * @param path the path of the document of interest - * @param documentName the name of the document of interest - */ - - void registerListener(final POIFSReaderListener listener, - final POIFSDocumentPath path, - final String documentName) - { - if (!omnivorousListeners.contains(listener)) - { - - // not an omnivorous listener (if it was, this method is a - // no-op) - Set descriptors = selectiveListeners.get(listener); - - if (descriptors == null) - { - - // this listener has not registered before - descriptors = new HashSet(); - selectiveListeners.put(listener, descriptors); - } - DocumentDescriptor descriptor = new DocumentDescriptor(path, - documentName); - - if (descriptors.add(descriptor)) - { - - // this listener wasn't already listening for this - // document -- add the listener to the set of - // listeners for this document - Set listeners = - chosenDocumentDescriptors.get(descriptor); - - if (listeners == null) - { - - // nobody was listening for this document before - listeners = new HashSet(); - chosenDocumentDescriptors.put(descriptor, listeners); - } - listeners.add(listener); - } - } - } - - /** - * register for all documents - * - * @param listener the listener who wants to get all documents - */ - - void registerListener(final POIFSReaderListener listener) - { - if (!omnivorousListeners.contains(listener)) - { - - // wasn't already listening for everything, so drop - // anything listener might have been listening for and - // then add the listener to the set of omnivorous - // listeners - removeSelectiveListener(listener); - omnivorousListeners.add(listener); - } - } - - /** - * get am iterator of listeners for a particular document - * - * @param path the document path - * @param name the name of the document - * - * @return an Iterator POIFSReaderListeners; may be empty - */ - - Iterator getListeners(final POIFSDocumentPath path, final String name) - { - Set rval = new HashSet(omnivorousListeners); - Set selectiveListenersInner = - chosenDocumentDescriptors.get(new DocumentDescriptor(path, name)); - - if (selectiveListenersInner != null) - { - rval.addAll(selectiveListenersInner); - } - return rval.iterator(); - } - - private void removeSelectiveListener(final POIFSReaderListener listener) - { - Set selectedDescriptors = selectiveListeners.remove(listener); - - if (selectedDescriptors != null) - { - Iterator iter = selectedDescriptors.iterator(); - - while (iter.hasNext()) - { - dropDocument(listener, iter.next()); - } - } - } - - private void dropDocument(final POIFSReaderListener listener, - final DocumentDescriptor descriptor) - { - Set listeners = chosenDocumentDescriptors.get(descriptor); - - listeners.remove(listener); - if (listeners.size() == 0) - { - chosenDocumentDescriptors.remove(descriptor); - } - } -} // end package scope class POIFSReaderRegistry - diff --git a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/package.html b/trunk/src/java/org/apache/poi/poifs/eventfilesystem/package.html deleted file mode 100644 index 472a0d93e..000000000 --- a/trunk/src/java/org/apache/poi/poifs/eventfilesystem/package.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - -The eventfilesystem is an efficient method for reading OLE 2 CDF files. It is to OLE 2 CDF what SAX is to XML. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.poifs.filesystem - - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/BATManaged.java b/trunk/src/java/org/apache/poi/poifs/filesystem/BATManaged.java deleted file mode 100644 index fcd3bde64..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/BATManaged.java +++ /dev/null @@ -1,49 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -/** - * This interface defines behaviors for objects managed by the Block - * Allocation Table (BAT). - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface BATManaged -{ - - /** - * Return the number of BigBlock's this instance uses - * - * @return count of BigBlock instances - */ - - int countBlocks(); - - /** - * Set the start block for this instance - * - * @param index index into the array of BigBlock instances making - * up the the filesystem - */ - - void setStartBlock(final int index); -} // end public interface BATManaged - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/BlockStore.java b/trunk/src/java/org/apache/poi/poifs/filesystem/BlockStore.java deleted file mode 100644 index a56d111f3..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/BlockStore.java +++ /dev/null @@ -1,109 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex; - -/** - * This abstract class describes a way to read, store, chain - * and free a series of blocks (be they Big or Small ones) - */ -public abstract class BlockStore { - /** - * Returns the size of the blocks managed through the block store. - */ - protected abstract int getBlockStoreBlockSize(); - - /** - * Load the block at the given offset. - */ - protected abstract ByteBuffer getBlockAt(final int offset) throws IOException; - - /** - * Extends the file if required to hold blocks up to - * the specified offset, and return the block from there. - */ - protected abstract ByteBuffer createBlockIfNeeded(final int offset) throws IOException; - - /** - * Returns the BATBlock that handles the specified offset, - * and the relative index within it - */ - protected abstract BATBlockAndIndex getBATBlockAndIndex(final int offset); - - /** - * Works out what block follows the specified one. - */ - protected abstract int getNextBlock(final int offset); - - /** - * Changes the record of what block follows the specified one. - */ - protected abstract void setNextBlock(final int offset, final int nextBlock); - - /** - * Finds a free block, and returns its offset. - * This method will extend the file/stream if needed, and if doing - * so, allocate new FAT blocks to address the extra space. - */ - protected abstract int getFreeBlock() throws IOException; - - /** - * Creates a Detector for loops in the chain - */ - protected abstract ChainLoopDetector getChainLoopDetector() throws IOException; - - /** - * Used to detect if a chain has a loop in it, so - * we can bail out with an error rather than - * spinning away for ever... - */ - protected class ChainLoopDetector { - private boolean[] used_blocks; - protected ChainLoopDetector(long rawSize) { - int blkSize = getBlockStoreBlockSize(); - int numBlocks = (int)(rawSize / blkSize); - if ((rawSize % blkSize) != 0) { - numBlocks++; - } - used_blocks = new boolean[numBlocks]; - } - protected void claim(int offset) { - if(offset >= used_blocks.length) { - // They're writing, and have had new blocks requested - // for the write to proceed. That means they're into - // blocks we've allocated for them, so are safe - return; - } - - // Claiming an existing block, ensure there's no loop - if(used_blocks[offset]) { - throw new IllegalStateException( - "Potential loop detected - Block " + offset + - " was already claimed but was just requested again" - ); - } - used_blocks[offset] = true; - } - } -} - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DirectoryEntry.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DirectoryEntry.java deleted file mode 100644 index 7148fda3c..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DirectoryEntry.java +++ /dev/null @@ -1,164 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; -import java.util.Set; - -import org.apache.poi.hpsf.ClassID; - -/** - * This interface defines methods specific to Directory objects - * managed by a Filesystem instance. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface DirectoryEntry - extends Entry, Iterable -{ - - /** - * get an iterator of the Entry instances contained directly in - * this instance (in other words, children only; no grandchildren - * etc.) - * - * @return iterator; never null, but hasNext() may return false - * immediately (i.e., this DirectoryEntry is empty). All - * objects retrieved by next() are guaranteed to be - * implementations of Entry. - */ - - public Iterator getEntries(); - - /** - * get the names of all the Entries contained directly in this - * instance (in other words, names of children only; no grandchildren - * etc). - * - * @return the names of all the entries that may be retrieved with - * getEntry(String), which may be empty (if this - * DirectoryEntry is empty) - */ - public Set getEntryNames(); - - /** - * is this DirectoryEntry empty? - * - * @return true if this instance contains no Entry instances - */ - - public boolean isEmpty(); - - /** - * find out how many Entry instances are contained directly within - * this DirectoryEntry - * - * @return number of immediately (no grandchildren etc.) contained - * Entry instances - */ - - public int getEntryCount(); - - /** - * Checks if entry with specified name present - */ - - public boolean hasEntry( final String name ); - - /** - * get a specified Entry by name - * - * @param name the name of the Entry to obtain. - * - * @return the specified Entry, if it is directly contained in - * this DirectoryEntry - * - * @exception FileNotFoundException if no Entry with the specified - * name exists in this DirectoryEntry - */ - - public Entry getEntry(final String name) - throws FileNotFoundException; - - /** - * create a new DocumentEntry - * - * @param name the name of the new DocumentEntry - * @param stream the InputStream from which to create the new - * DocumentEntry - * - * @return the new DocumentEntry - * - * @exception IOException - */ - - public DocumentEntry createDocument(final String name, - final InputStream stream) - throws IOException; - - /** - * create a new DocumentEntry; the data will be provided later - * - * @param name the name of the new DocumentEntry - * @param size the size of the new DocumentEntry - * @param writer the writer of the new DocumentEntry - * - * @return the new DocumentEntry - * - * @exception IOException - */ - - public DocumentEntry createDocument(final String name, final int size, - final POIFSWriterListener writer) - throws IOException; - - /** - * create a new DirectoryEntry - * - * @param name the name of the new DirectoryEntry - * - * @return the new DirectoryEntry - * - * @exception IOException - */ - - public DirectoryEntry createDirectory(final String name) - throws IOException; - - /** - * Gets the storage clsid of the directory entry - * - * @return storage Class ID - */ - public ClassID getStorageClsid(); - - /** - * Sets the storage clsid for the directory entry - * - * @param clsidStorage storage Class ID - */ - public void setStorageClsid(ClassID clsidStorage); - -} // end public interface DirectoryEntry - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java deleted file mode 100644 index ccb008507..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java +++ /dev/null @@ -1,636 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hpsf.ClassID; -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.DocumentProperty; -import org.apache.poi.poifs.property.Property; - -/** - * Simple implementation of DirectoryEntry - */ -public class DirectoryNode - extends EntryNode - implements DirectoryEntry, POIFSViewable, Iterable -{ - - // Map of Entry instances, keyed by their names - private Map _byname; - // Our list of entries, kept sorted to preserve order - private ArrayList _entries; - - // Only one of these two will exist - // the OPOIFSFileSystem we belong to - private OPOIFSFileSystem _ofilesystem; - // the NPOIFSFileSytem we belong to - private NPOIFSFileSystem _nfilesystem; - - // the path described by this document - private POIFSDocumentPath _path; - - /** - * create a DirectoryNode. This method is not public by design; it - * is intended strictly for the internal use of this package - * - * @param property the DirectoryProperty for this DirectoryEntry - * @param filesystem the OPOIFSFileSystem we belong to - * @param parent the parent of this entry - */ - DirectoryNode(final DirectoryProperty property, - final OPOIFSFileSystem filesystem, - final DirectoryNode parent) - { - this(property, parent, filesystem, (NPOIFSFileSystem)null); - } - - /** - * create a DirectoryNode. This method is not public by design; it - * is intended strictly for the internal use of this package - * - * @param property the DirectoryProperty for this DirectoryEntry - * @param nfilesystem the NPOIFSFileSystem we belong to - * @param parent the parent of this entry - */ - DirectoryNode(final DirectoryProperty property, - final NPOIFSFileSystem nfilesystem, - final DirectoryNode parent) - { - this(property, parent, (OPOIFSFileSystem)null, nfilesystem); - } - - private DirectoryNode(final DirectoryProperty property, - final DirectoryNode parent, - final OPOIFSFileSystem ofilesystem, - final NPOIFSFileSystem nfilesystem) - { - super(property, parent); - this._ofilesystem = ofilesystem; - this._nfilesystem = nfilesystem; - - if (parent == null) - { - _path = new POIFSDocumentPath(); - } - else - { - _path = new POIFSDocumentPath(parent._path, new String[] - { - property.getName() - }); - } - _byname = new HashMap(); - _entries = new ArrayList(); - Iterator iter = property.getChildren(); - - while (iter.hasNext()) - { - Property child = iter.next(); - Entry childNode = null; - - if (child.isDirectory()) - { - DirectoryProperty childDir = (DirectoryProperty) child; - if(_ofilesystem != null) { - childNode = new DirectoryNode(childDir, _ofilesystem, this); - } else { - childNode = new DirectoryNode(childDir, _nfilesystem, this); - } - } - else - { - childNode = new DocumentNode((DocumentProperty) child, this); - } - _entries.add(childNode); - _byname.put(childNode.getName(), childNode); - } - } - - /** - * @return this directory's path representation - */ - - public POIFSDocumentPath getPath() - { - return _path; - } - - /** - * @return the filesystem that this belongs to - */ - public NPOIFSFileSystem getFileSystem() - { - return _nfilesystem; - } - - /** - * If this is OPOIFS based, return the NPOIFSFileSystem - * that this belong to, otherwise Null if NPOIFS based - * @return the filesystem that this belongs to - */ - public OPOIFSFileSystem getOFileSystem() - { - return _ofilesystem; - } - - /** - * If this is NPOIFS based, return the NPOIFSFileSystem - * that this belong to, otherwise Null if OPOIFS based - * @return the filesystem that this belongs to - */ - public NPOIFSFileSystem getNFileSystem() - { - return _nfilesystem; - } - - /** - * open a document in the directory's entry's list of entries - * - * @param documentName the name of the document to be opened - * - * @return a newly opened DocumentInputStream - * - * @exception IOException if the document does not exist or the - * name is that of a DirectoryEntry - */ - public DocumentInputStream createDocumentInputStream( - final String documentName) - throws IOException - { - return createDocumentInputStream(getEntry(documentName)); - } - - /** - * open a document in the directory's entry's list of entries - * - * @param document the document to be opened - * - * @return a newly opened DocumentInputStream or NDocumentInputStream - * - * @exception IOException if the document does not exist or the - * name is that of a DirectoryEntry - */ - public DocumentInputStream createDocumentInputStream( - final Entry document) - throws IOException - { - if (!document.isDocumentEntry()) { - throw new IOException("Entry '" + document.getName() - + "' is not a DocumentEntry"); - } - - DocumentEntry entry = (DocumentEntry)document; - return new DocumentInputStream(entry); - } - - /** - * create a new DocumentEntry - * - * @param document the new document - * - * @return the new DocumentEntry - * - * @exception IOException - */ - DocumentEntry createDocument(final OPOIFSDocument document) - throws IOException - { - DocumentProperty property = document.getDocumentProperty(); - DocumentNode rval = new DocumentNode(property, this); - - (( DirectoryProperty ) getProperty()).addChild(property); - _ofilesystem.addDocument(document); - - _entries.add(rval); - _byname.put(property.getName(), rval); - return rval; - } - - /** - * create a new DocumentEntry - * - * @param document the new document - * - * @return the new DocumentEntry - * - * @exception IOException - */ - DocumentEntry createDocument(final NPOIFSDocument document) - throws IOException - { - DocumentProperty property = document.getDocumentProperty(); - DocumentNode rval = new DocumentNode(property, this); - - (( DirectoryProperty ) getProperty()).addChild(property); - _nfilesystem.addDocument(document); - - _entries.add(rval); - _byname.put(property.getName(), rval); - return rval; - } - - /** - * Change a contained Entry's name - * - * @param oldName the original name - * @param newName the new name - * - * @return true if the operation succeeded, else false - */ - boolean changeName(final String oldName, final String newName) - { - boolean rval = false; - EntryNode child = ( EntryNode ) _byname.get(oldName); - - if (child != null) - { - rval = (( DirectoryProperty ) getProperty()) - .changeName(child.getProperty(), newName); - if (rval) - { - _byname.remove(oldName); - _byname.put(child.getProperty().getName(), child); - } - } - return rval; - } - - /** - * Delete an entry - * - * @param entry the EntryNode to be deleted - * - * @return true if the entry was deleted, else false - */ - - boolean deleteEntry(final EntryNode entry) - { - boolean rval = - (( DirectoryProperty ) getProperty()) - .deleteChild(entry.getProperty()); - - if (rval) - { - _entries.remove(entry); - _byname.remove(entry.getName()); - - if(_ofilesystem != null) { - _ofilesystem.remove(entry); - } else { - try { - _nfilesystem.remove(entry); - } catch (IOException e) { - // TODO Work out how to report this, given we can't change the method signature... - } - } - } - return rval; - } - - /* ********** START implementation of DirectoryEntry ********** */ - - /** - * get an iterator of the Entry instances contained directly in - * this instance (in other words, children only; no grandchildren - * etc.) - * - * @return iterator; never null, but hasNext() may return false - * immediately (i.e., this DirectoryEntry is empty). All - * objects retrieved by next() are guaranteed to be - * implementations of Entry. - */ - - public Iterator getEntries() - { - return _entries.iterator(); - } - - /** - * get the names of all the Entries contained directly in this - * instance (in other words, names of children only; no grandchildren - * etc). - * - * @return the names of all the entries that may be retrieved with - * getEntry(String), which may be empty (if this - * DirectoryEntry is empty) - */ - public Set getEntryNames() - { - return _byname.keySet(); - } - - /** - * is this DirectoryEntry empty? - * - * @return true if this instance contains no Entry instances - */ - - public boolean isEmpty() - { - return _entries.isEmpty(); - } - - /** - * find out how many Entry instances are contained directly within - * this DirectoryEntry - * - * @return number of immediately (no grandchildren etc.) contained - * Entry instances - */ - - public int getEntryCount() - { - return _entries.size(); - } - - public boolean hasEntry( String name ) - { - return name != null && _byname.containsKey( name ); - } - - /** - * get a specified Entry by name - * - * @param name the name of the Entry to obtain. - * - * @return the specified Entry, if it is directly contained in - * this DirectoryEntry - * - * @exception FileNotFoundException if no Entry with the specified - * name exists in this DirectoryEntry - */ - - public Entry getEntry(final String name) throws FileNotFoundException { - Entry rval = null; - - if (name != null) { - rval = _byname.get(name); - } - if (rval == null) { - // either a null name was given, or there is no such name - throw new FileNotFoundException("no such entry: \"" + name - + "\", had: " + _byname.keySet()); - } - return rval; - } - - /** - * create a new DocumentEntry - * - * @param name the name of the new DocumentEntry - * @param stream the InputStream from which to create the new - * DocumentEntry - * - * @return the new DocumentEntry - * - * @exception IOException - */ - - public DocumentEntry createDocument(final String name, - final InputStream stream) - throws IOException - { - if(_nfilesystem != null) { - return createDocument(new NPOIFSDocument(name, _nfilesystem, stream)); - } else { - return createDocument(new OPOIFSDocument(name, stream)); - } - } - - /** - * create a new DocumentEntry; the data will be provided later - * - * @param name the name of the new DocumentEntry - * @param size the size of the new DocumentEntry - * @param writer the writer of the new DocumentEntry - * - * @return the new DocumentEntry - * - * @exception IOException - */ - - public DocumentEntry createDocument(final String name, final int size, - final POIFSWriterListener writer) - throws IOException - { - if(_nfilesystem != null) { - return createDocument(new NPOIFSDocument(name, size, _nfilesystem, writer)); - } else { - return createDocument(new OPOIFSDocument(name, size, _path, writer)); - } - } - - /** - * create a new DirectoryEntry - * - * @param name the name of the new DirectoryEntry - * - * @return the new DirectoryEntry - * - * @exception IOException - */ - - public DirectoryEntry createDirectory(final String name) - throws IOException - { - DirectoryNode rval; - DirectoryProperty property = new DirectoryProperty(name); - - if(_ofilesystem != null) { - rval = new DirectoryNode(property, _ofilesystem, this); - _ofilesystem.addDirectory(property); - } else { - rval = new DirectoryNode(property, _nfilesystem, this); - _nfilesystem.addDirectory(property); - } - - (( DirectoryProperty ) getProperty()).addChild(property); - _entries.add(rval); - _byname.put(name, rval); - return rval; - } - - /** - * Set the contents of a document, creating if needed, - * otherwise updating. Returns the created / updated DocumentEntry - * - * @param name the name of the new or existing DocumentEntry - * @param stream the InputStream from which to populate the DocumentEntry - * - * @return the new or updated DocumentEntry - * - * @exception IOException - */ - - public DocumentEntry createOrUpdateDocument(final String name, - final InputStream stream) - throws IOException - { - if (! hasEntry(name)) { - return createDocument(name, stream); - } else { - DocumentNode existing = (DocumentNode)getEntry(name); - if (_nfilesystem != null) { - NPOIFSDocument nDoc = new NPOIFSDocument(existing); - nDoc.replaceContents(stream); - return existing; - } else { - // Do it the hard way for Old POIFS... - deleteEntry(existing); - return createDocument(name, stream); - } - } - } - - /** - * Gets the storage clsid of the directory entry - * - * @return storage Class ID - */ - public ClassID getStorageClsid() - { - return getProperty().getStorageClsid(); - } - - /** - * Sets the storage clsid for the directory entry - * - * @param clsidStorage storage Class ID - */ - public void setStorageClsid(ClassID clsidStorage) - { - getProperty().setStorageClsid(clsidStorage); - } - - /* ********** END implementation of DirectoryEntry ********** */ - /* ********** START implementation of Entry ********** */ - - /** - * is this a DirectoryEntry? - * - * @return true if the Entry is a DirectoryEntry, else false - */ - - @Override - public boolean isDirectoryEntry() - { - return true; - } - - /* ********** END implementation of Entry ********** */ - /* ********** START extension of Entry ********** */ - - /** - * extensions use this method to verify internal rules regarding - * deletion of the underlying store. - * - * @return true if it's ok to delete the underlying store, else - * false - */ - - @Override - protected boolean isDeleteOK() - { - - // if this directory is empty, we can delete it - return isEmpty(); - } - - /* ********** END extension of Entry ********** */ - /* ********** START begin implementation of POIFSViewable ********** */ - - /** - * Get an array of objects, some of which may implement - * POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - - public Object [] getViewableArray() - { - return new Object[ 0 ]; - } - - /** - * Get an Iterator of objects, some of which may implement - * POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty - * back end store - */ - public Iterator getViewableIterator() - { - List components = new ArrayList(); - - components.add(getProperty()); - Iterator iter = _entries.iterator(); - while (iter.hasNext()) - { - components.add(iter.next()); - } - return components.iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, false if - * a viewer should call getViewableIterator - */ - - public boolean preferArray() - { - return false; - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - - public String getShortDescription() - { - return getName(); - } - - /** - * Returns an Iterator over all the entries - */ - public Iterator iterator() { - return getEntries(); - } - - /* ********** END begin implementation of POIFSViewable ********** */ -} // end public class DirectoryNode - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentDescriptor.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentDescriptor.java deleted file mode 100644 index cc9d7eb5e..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentDescriptor.java +++ /dev/null @@ -1,117 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -/** - * Class DocumentDescriptor - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -public class DocumentDescriptor -{ - private POIFSDocumentPath path; - private String name; - private int hashcode = 0; - - /** - * Trivial constructor - * - * @param path the Document path - * @param name the Document name - */ - - public DocumentDescriptor(final POIFSDocumentPath path, final String name) - { - if (path == null) - { - throw new NullPointerException("path must not be null"); - } - if (name == null) - { - throw new NullPointerException("name must not be null"); - } - if (name.length() == 0) - { - throw new IllegalArgumentException("name cannot be empty"); - } - this.path = path; - this.name = name; - } - - /** - * equality. Two DocumentDescriptor instances are equal if they - * have equal paths and names - * - * @param o the object we're checking equality for - * - * @return true if the object is equal to this object - */ - - public boolean equals(final Object o) - { - boolean rval = false; - - if ((o != null) && (o.getClass() == this.getClass())) - { - if (this == o) - { - rval = true; - } - else - { - DocumentDescriptor descriptor = ( DocumentDescriptor ) o; - - rval = this.path.equals(descriptor.path) - && this.name.equals(descriptor.name); - } - } - return rval; - } - - /** - * calculate and return the hashcode - * - * @return hashcode - */ - - public int hashCode() - { - if (hashcode == 0) - { - hashcode = path.hashCode() ^ name.hashCode(); - } - return hashcode; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(40 * (path.length() + 1)); - - for (int j = 0; j < path.length(); j++) - { - buffer.append(path.getComponent(j)).append("/"); - } - buffer.append(name); - return buffer.toString(); - } -} // end public class DocumentDescriptor - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentEntry.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentEntry.java deleted file mode 100644 index 29f4b8afb..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentEntry.java +++ /dev/null @@ -1,41 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -/** - * This interface defines methods specific to Document objects - * managed by a Filesystem instance. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface DocumentEntry - extends Entry -{ - - /** - * get the zize of the document, in bytes - * - * @return size in bytes - */ - - public int getSize(); -} // end public interface DocumentEntry - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java deleted file mode 100644 index 58658fac7..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.util.IOUtils; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.security.GeneralSecurityException; - -/** - * A small base class for the various factories, e.g. WorkbookFactory, - * SlideShowFactory to combine common code here. - */ -public class DocumentFactoryHelper { - /** - * Wrap the OLE2 data in the NPOIFSFileSystem into a decrypted stream by using - * the given password. - * - * @param fs The OLE2 stream for the document - * @param password The password, null if the default password should be used - * @return A stream for reading the decrypted data - * @throws IOException If an error occurs while decrypting or if the password does not match - */ - public static InputStream getDecryptedStream(final NPOIFSFileSystem fs, String password) - throws IOException { - EncryptionInfo info = new EncryptionInfo(fs); - Decryptor d = Decryptor.getInstance(info); - - try { - boolean passwordCorrect = false; - if (password != null && d.verifyPassword(password)) { - passwordCorrect = true; - } - if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) { - passwordCorrect = true; - } - - if (passwordCorrect) { - // wrap the stream in a FilterInputStream to close the NPOIFSFileSystem - // as well when the resulting OPCPackage is closed - return new FilterInputStream(d.getDataStream(fs.getRoot())) { - @Override - public void close() throws IOException { - fs.close(); - - super.close(); - } - }; - } else { - if (password != null) - throw new EncryptedDocumentException("Password incorrect"); - else - throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied"); - } - } catch (GeneralSecurityException e) { - throw new IOException(e); - } - } - - /** - * Checks that the supplied InputStream (which MUST - * support mark and reset, or be a PushbackInputStream) - * has a OOXML (zip) header at the start of it. - * If your InputStream does not support mark / reset, - * then wrap it in a PushBackInputStream, then be - * sure to always use that, and not the original! - * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream - */ - public static boolean hasOOXMLHeader(InputStream inp) throws IOException { - // We want to peek at the first 4 bytes - inp.mark(4); - - byte[] header = new byte[4]; - int bytesRead = IOUtils.readFully(inp, header); - - // Wind back those 4 bytes - if(inp instanceof PushbackInputStream) { - PushbackInputStream pin = (PushbackInputStream)inp; - pin.unread(header, 0, bytesRead); - } else { - inp.reset(); - } - - // Did it match the ooxml zip signature? - return ( - bytesRead == 4 && - header[0] == POIFSConstants.OOXML_FILE_HEADER[0] && - header[1] == POIFSConstants.OOXML_FILE_HEADER[1] && - header[2] == POIFSConstants.OOXML_FILE_HEADER[2] && - header[3] == POIFSConstants.OOXML_FILE_HEADER[3] - ); - } - -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java deleted file mode 100644 index ffd6a1a85..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.util.LittleEndianInput; - -/** - * This class provides methods to read a DocumentEntry managed by a - * {@link POIFSFileSystem} or {@link NPOIFSFileSystem} instance. - * It creates the appropriate one, and delegates, allowing us to - * work transparently with the two. - */ -public class DocumentInputStream extends InputStream implements LittleEndianInput { - /** returned by read operations if we're at end of document */ - protected static final int EOF = -1; - - protected static final int SIZE_SHORT = 2; - protected static final int SIZE_INT = 4; - protected static final int SIZE_LONG = 8; - - private DocumentInputStream delegate; - - /** For use by downstream implementations */ - protected DocumentInputStream() {} - - /** - * Create an InputStream from the specified DocumentEntry - * - * @param document the DocumentEntry to be read - * - * @exception IOException if the DocumentEntry cannot be opened (like, maybe it has - * been deleted?) - */ - public DocumentInputStream(DocumentEntry document) throws IOException { - if (!(document instanceof DocumentNode)) { - throw new IOException("Cannot open internal document storage"); - } - DocumentNode documentNode = (DocumentNode)document; - DirectoryNode parentNode = (DirectoryNode)document.getParent(); - - if(documentNode.getDocument() != null) { - delegate = new ODocumentInputStream(document); - } else if(parentNode.getOFileSystem() != null) { - delegate = new ODocumentInputStream(document); - } else if(parentNode.getNFileSystem() != null) { - delegate = new NDocumentInputStream(document); - } else { - throw new IOException("No FileSystem bound on the parent, can't read contents"); - } - } - - /** - * Create an InputStream from the specified Document - * - * @param document the Document to be read - */ - public DocumentInputStream(OPOIFSDocument document) { - delegate = new ODocumentInputStream(document); - } - - /** - * Create an InputStream from the specified Document - * - * @param document the Document to be read - */ - public DocumentInputStream(NPOIFSDocument document) { - delegate = new NDocumentInputStream(document); - } - - @Override - public int available() { - return delegate.available(); - } - - @Override - public void close() { - delegate.close(); - } - - @Override - public void mark(int ignoredReadlimit) { - delegate.mark(ignoredReadlimit); - } - - /** - * Tests if this input stream supports the mark and reset methods. - * - * @return true always - */ - @Override - public boolean markSupported() { - return true; - } - - @Override - public int read() throws IOException { - return delegate.read(); - } - - @Override - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return delegate.read(b, off, len); - } - - /** - * Repositions this stream to the position at the time the mark() method was - * last called on this input stream. If mark() has not been called this - * method repositions the stream to its beginning. - */ - @Override - public void reset() { - delegate.reset(); - } - - @Override - public long skip(long n) throws IOException { - return delegate.skip(n); - } - - @Override - public byte readByte() { - return delegate.readByte(); - } - - @Override - public double readDouble() { - return delegate.readDouble(); - } - - @Override - public short readShort() { - return (short) readUShort(); - } - - @Override - public void readFully(byte[] buf) { - readFully(buf, 0, buf.length); - } - - @Override - public void readFully(byte[] buf, int off, int len) { - delegate.readFully(buf, off, len); - } - - @Override - public long readLong() { - return delegate.readLong(); - } - - @Override - public int readInt() { - return delegate.readInt(); - } - - @Override - public int readUShort() { - return delegate.readUShort(); - } - - @Override - public int readUByte() { - return delegate.readUByte(); - } - - public long readUInt() { - int i = readInt(); - return i & 0xFFFFFFFFL; - } - - @Override - public void readPlain(byte[] buf, int off, int len) { - readFully(buf, off, len); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java deleted file mode 100644 index 7a5bf6900..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java +++ /dev/null @@ -1,168 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.poifs.property.DocumentProperty; - -/** - * Simple implementation of DocumentEntry for OPOIFS - */ -public class DocumentNode - extends EntryNode - implements DocumentEntry, POIFSViewable -{ - - // underlying POIFSDocument instance - private OPOIFSDocument _document; - - /** - * create a DocumentNode. This method is not public by design; it - * is intended strictly for the internal use of this package - * - * @param property the DocumentProperty for this DocumentEntry - * @param parent the parent of this entry - */ - - DocumentNode(final DocumentProperty property, final DirectoryNode parent) - { - super(property, parent); - _document = property.getDocument(); - } - - /** - * get the POIFSDocument - * - * @return the internal POIFSDocument - */ - OPOIFSDocument getDocument() - { - return _document; - } - - /* ********** START implementation of DocumentEntry ********** */ - - /** - * get the zize of the document, in bytes - * - * @return size in bytes - */ - - public int getSize() - { - return getProperty().getSize(); - } - - /* ********** END implementation of DocumentEntry ********** */ - /* ********** START implementation of Entry ********** */ - - /** - * is this a DocumentEntry? - * - * @return true if the Entry is a DocumentEntry, else false - */ - - @Override - public boolean isDocumentEntry() - { - return true; - } - - /* ********** END implementation of Entry ********** */ - /* ********** START extension of Entry ********** */ - - /** - * extensions use this method to verify internal rules regarding - * deletion of the underlying store. - * - * @return true if it's ok to delete the underlying store, else - * false - */ - - @Override - protected boolean isDeleteOK() - { - return true; - } - - /* ********** END extension of Entry ********** */ - /* ********** START begin implementation of POIFSViewable ********** */ - - /** - * Get an array of objects, some of which may implement - * POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - - public Object [] getViewableArray() - { - return new Object[ 0 ]; - } - - /** - * Get an Iterator of objects, some of which may implement - * POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty - * back end store - */ - - public Iterator getViewableIterator() - { - List components = new ArrayList(); - - components.add(getProperty()); - components.add(_document); - return components.iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, false if - * a viewer should call getViewableIterator - */ - - public boolean preferArray() - { - return false; - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - - public String getShortDescription() - { - return getName(); - } - - /* ********** END begin implementation of POIFSViewable ********** */ -} // end public class DocumentNode - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentOutputStream.java b/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentOutputStream.java deleted file mode 100644 index fd1ffa9a5..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentOutputStream.java +++ /dev/null @@ -1,163 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.*; - -import java.util.*; - -/** - * This class provides a wrapper over an OutputStream so that Document - * writers can't accidently go over their size limits - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public final class DocumentOutputStream extends OutputStream { - private final OutputStream _stream; - private final int _limit; - private int _written; - - /** - * Create a DocumentOutputStream - * - * @param stream the OutputStream to which the data is actually - * read - * @param limit the maximum number of bytes that can be written - */ - DocumentOutputStream(OutputStream stream, int limit) { - _stream = stream; - _limit = limit; - _written = 0; - } - - /** - * Writes the specified byte to this output stream. The general - * contract for write is that one byte is written to the output - * stream. The byte to be written is the eight low-order bits of - * the argument b. The 24 high-order bits of b are ignored. - * - * @param b the byte. - * @exception IOException if an I/O error occurs. In particular, - * an IOException may be thrown if the - * output stream has been closed, or if the - * writer tries to write too much data. - */ - public void write(int b) - throws IOException - { - limitCheck(1); - _stream.write(b); - } - - /** - * Writes b.length bytes from the specified byte array - * to this output stream. - * - * @param b the data. - * @exception IOException if an I/O error occurs. - */ - public void write(byte b[]) - throws IOException - { - write(b, 0, b.length); - } - - /** - * Writes len bytes from the specified byte array starting at - * offset off to this output stream. The general contract for - * write(b, off, len) is that some of the bytes in the array b are - * written to the output stream in order; element b[off] is the - * first byte written and b[off+len-1] is the last byte written by - * this operation.

    - * If b is null, a NullPointerException is thrown.

    - * If off is negative, or len is negative, or off+len is greater - * than the length of the array b, then an - * IndexOutOfBoundsException is thrown. - * - * @param b the data. - * @param off the start offset in the data. - * @param len the number of bytes to write. - * @exception IOException if an I/O error occurs. In particular, - * an IOException is thrown if the - * output stream is closed or if the writer - * tries to write too many bytes. - */ - public void write(byte b[], int off, int len) - throws IOException - { - limitCheck(len); - _stream.write(b, off, len); - } - - /** - * Flushes this output stream and forces any buffered output bytes - * to be written out. - * - * @exception IOException if an I/O error occurs. - */ - public void flush() - throws IOException - { - _stream.flush(); - } - - /** - * Closes this output stream and releases any system resources - * associated with this stream. The general contract of close is - * that it closes the output stream. A closed stream cannot - * perform output operations and cannot be reopened. - * - * @exception IOException if an I/O error occurs. - */ - public void close() { - - // ignore this call - } - - /** - * write the rest of the document's data (fill in at the end) - * - * @param totalLimit the actual number of bytes the corresponding - * document must fill - * @param fill the byte to fill remaining space with - * - * @exception IOException on I/O error - */ - void writeFiller(int totalLimit, byte fill) - throws IOException - { - if (totalLimit > _written) - { - byte[] filler = new byte[ totalLimit - _written ]; - - Arrays.fill(filler, fill); - _stream.write(filler); - } - } - - private void limitCheck(int toBeWritten) - throws IOException - { - if ((_written + toBeWritten) > _limit) - { - throw new IOException("tried to write too much data"); - } - _written += toBeWritten; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/Entry.java b/trunk/src/java/org/apache/poi/poifs/filesystem/Entry.java deleted file mode 100644 index 2a8ea16aa..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/Entry.java +++ /dev/null @@ -1,97 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -/** - * This interface provides access to an object managed by a Filesystem - * instance. Entry objects are further divided into DocumentEntry and - * DirectoryEntry instances. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface Entry -{ - - /** - * get the name of the Entry - * - * @return name - */ - - public String getName(); - - /** - * is this a DirectoryEntry? - * - * @return true if the Entry is a DirectoryEntry, else false - */ - - public boolean isDirectoryEntry(); - - /** - * is this a DocumentEntry? - * - * @return true if the Entry is a DocumentEntry, else false - */ - - public boolean isDocumentEntry(); - - /** - * get this Entry's parent (the DirectoryEntry that owns this - * Entry). All Entry objects, except the root Entry, has a parent. - * - * @return this Entry's parent; null iff this is the root Entry - */ - - public DirectoryEntry getParent(); - - /** - * Delete this Entry. This operation should succeed, but there are - * special circumstances when it will not: - * - * If this Entry is the root of the Entry tree, it cannot be - * deleted, as there is no way to create another one. - * - * If this Entry is a directory, it cannot be deleted unless it is - * empty. - * - * @return true if the Entry was successfully deleted, else false - */ - - public boolean delete(); - - /** - * Rename this Entry. This operation will fail if: - * - * There is a sibling Entry (i.e., an Entry whose parent is the - * same as this Entry's parent) with the same name. - * - * This Entry is the root of the Entry tree. Its name is dictated - * by the Filesystem and many not be changed. - * - * @param newName the new name for this Entry - * - * @return true if the operation succeeded, else false - */ - - public boolean renameTo(final String newName); -} // end public interface Entry - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/EntryNode.java b/trunk/src/java/org/apache/poi/poifs/filesystem/EntryNode.java deleted file mode 100644 index a48d8e4f9..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/EntryNode.java +++ /dev/null @@ -1,191 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import org.apache.poi.poifs.property.Property; - -/** - * Abstract implementation of Entry - * - * Extending classes should override isDocument() or isDirectory(), as - * appropriate - * - * Extending classes must override isDeleteOK() - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public abstract class EntryNode - implements Entry -{ - - // the DocumentProperty backing this object - private Property _property; - - // this object's parent Entry - private DirectoryNode _parent; - - /** - * create a DocumentNode. This method is not public by design; it - * is intended strictly for the internal use of extending classes - * - * @param property the Property for this Entry - * @param parent the parent of this entry - */ - - protected EntryNode(final Property property, final DirectoryNode parent) - { - _property = property; - _parent = parent; - } - - /** - * grant access to the property - * - * @return the property backing this entry - */ - - protected Property getProperty() - { - return _property; - } - - /** - * is this the root of the tree? - * - * @return true if so, else false - */ - - protected boolean isRoot() - { - - // only the root Entry has no parent ... - return (_parent == null); - } - - /** - * extensions use this method to verify internal rules regarding - * deletion of the underlying store. - * - * @return true if it's ok to delete the underlying store, else - * false - */ - - protected abstract boolean isDeleteOK(); - - /* ********** START implementation of Entry ********** */ - - /** - * get the name of the Entry - * - * @return name - */ - - public String getName() - { - return _property.getName(); - } - - /** - * is this a DirectoryEntry? - * - * @return true if the Entry is a DirectoryEntry, else false - */ - - public boolean isDirectoryEntry() - { - return false; - } - - /** - * is this a DocumentEntry? - * - * @return true if the Entry is a DocumentEntry, else false - */ - - public boolean isDocumentEntry() - { - return false; - } - - /** - * get this Entry's parent (the DocumentEntry that owns this - * Entry). All Entry objects, except the root Entry, has a parent. - * - * @return this Entry's parent; null iff this is the root Entry - */ - - public DirectoryEntry getParent() - { - return _parent; - } - - /** - * Delete this Entry. This operation should succeed, but there are - * special circumstances when it will not: - * - * If this Entry is the root of the Entry tree, it cannot be - * deleted, as there is no way to create another one. - * - * If this Entry is a directory, it cannot be deleted unless it is - * empty. - * - * @return true if the Entry was successfully deleted, else false - */ - - public boolean delete() - { - boolean rval = false; - - if ((!isRoot()) && isDeleteOK()) - { - rval = _parent.deleteEntry(this); - } - return rval; - } - - /** - * Rename this Entry. This operation will fail if: - * - * There is a sibling Entry (i.e., an Entry whose parent is the - * same as this Entry's parent) with the same name. - * - * This Entry is the root of the Entry tree. Its name is dictated - * by the Filesystem and many not be changed. - * - * @param newName the new name for this Entry - * - * @return true if the operation succeeded, else false - */ - - public boolean renameTo(final String newName) - { - boolean rval = false; - - if (!isRoot()) - { - rval = _parent.changeName(getName(), newName); - } - return rval; - } - - /* ********** END implementation of Entry ********** */ -} // end public class EntryNode - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java b/trunk/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java deleted file mode 100644 index 18140d9df..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java +++ /dev/null @@ -1,276 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.filesystem; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.poi.util.Internal; - -@Internal -public class EntryUtils -{ - - /** - * Copies an Entry into a target POIFS directory, recursively - */ - @Internal - public static void copyNodeRecursively( Entry entry, DirectoryEntry target ) - throws IOException - { - // logger.log( POILogger.ERROR, "copyNodeRecursively called with "+entry.getName()+ - // ","+target.getName()); - DirectoryEntry newTarget = null; - if ( entry.isDirectoryEntry() ) - { - DirectoryEntry dirEntry = (DirectoryEntry)entry; - newTarget = target.createDirectory( entry.getName() ); - newTarget.setStorageClsid( dirEntry.getStorageClsid() ); - Iterator entries = dirEntry.getEntries(); - - while ( entries.hasNext() ) - { - copyNodeRecursively( entries.next(), newTarget ); - } - } - else - { - DocumentEntry dentry = (DocumentEntry) entry; - DocumentInputStream dstream = new DocumentInputStream( dentry ); - target.createDocument( dentry.getName(), dstream ); - dstream.close(); - } - } - - /** - * Copies all the nodes from one POIFS Directory to another - * - * @param sourceRoot - * is the source Directory to copy from - * @param targetRoot - * is the target Directory to copy to - */ - public static void copyNodes(DirectoryEntry sourceRoot, - DirectoryEntry targetRoot) throws IOException - { - for (Entry entry : sourceRoot) { - copyNodeRecursively( entry, targetRoot ); - } - } - - /** - * Copies nodes from one Directory to the other minus the excepts - * - * @param filteredSource The filtering source Directory to copy from - * @param filteredTarget The filtering target Directory to copy to - */ - public static void copyNodes( FilteringDirectoryNode filteredSource, - FilteringDirectoryNode filteredTarget ) throws IOException - { - // Nothing special here, just overloaded types to make the - // recommended new way to handle this clearer - copyNodes( (DirectoryEntry)filteredSource, (DirectoryEntry)filteredTarget ); - } - - /** - * Copies all nodes from one POIFS to the other - * - * @param source - * is the source POIFS to copy from - * @param target - * is the target POIFS to copy to - */ - public static void copyNodes( OPOIFSFileSystem source, - OPOIFSFileSystem target ) throws IOException - { - copyNodes( source.getRoot(), target.getRoot() ); - } - /** - * Copies all nodes from one POIFS to the other - * - * @param source - * is the source POIFS to copy from - * @param target - * is the target POIFS to copy to - */ - public static void copyNodes( NPOIFSFileSystem source, - NPOIFSFileSystem target ) throws IOException - { - copyNodes( source.getRoot(), target.getRoot() ); - } - - /** - * Copies nodes from one POIFS to the other, minus the excepts. - * This delegates the filtering work to {@link FilteringDirectoryNode}, - * so excepts can be of the form "NodeToExclude" or - * "FilteringDirectory/ExcludedChildNode" - * - * @param source is the source POIFS to copy from - * @param target is the target POIFS to copy to - * @param excepts is a list of Entry Names to be excluded from the copy - */ - public static void copyNodes( OPOIFSFileSystem source, - OPOIFSFileSystem target, List excepts ) throws IOException - { - copyNodes( - new FilteringDirectoryNode(source.getRoot(), excepts), - new FilteringDirectoryNode(target.getRoot(), excepts) - ); - } - /** - * Copies nodes from one POIFS to the other, minus the excepts. - * This delegates the filtering work to {@link FilteringDirectoryNode}, - * so excepts can be of the form "NodeToExclude" or - * "FilteringDirectory/ExcludedChildNode" - * - * @param source is the source POIFS to copy from - * @param target is the target POIFS to copy to - * @param excepts is a list of Entry Names to be excluded from the copy - */ - public static void copyNodes( NPOIFSFileSystem source, - NPOIFSFileSystem target, List excepts ) throws IOException - { - copyNodes( - new FilteringDirectoryNode(source.getRoot(), excepts), - new FilteringDirectoryNode(target.getRoot(), excepts) - ); - } - - /** - * Checks to see if the two Directories hold the same contents. - * For this to be true, they must have entries with the same names, - * no entries in one but not the other, and the size+contents - * of each entry must match, and they must share names. - * To exclude certain parts of the Directory from being checked, - * use a {@link FilteringDirectoryNode} - */ - public static boolean areDirectoriesIdentical(DirectoryEntry dirA, DirectoryEntry dirB) { - // First, check names - if (! dirA.getName().equals(dirB.getName())) { - return false; - } - - // Next up, check they have the same number of children - if (dirA.getEntryCount() != dirB.getEntryCount()) { - return false; - } - - // Next, check entries and their types/sizes - Map aSizes = new HashMap(); - final int isDirectory = -12345; - for (Entry a : dirA) { - String aName = a.getName(); - if (a.isDirectoryEntry()) { - aSizes.put(aName, isDirectory); - } else { - aSizes.put(aName, ((DocumentNode)a).getSize()); - } - } - for (Entry b : dirB) { - String bName = b.getName(); - if (! aSizes.containsKey(bName)) { - // In B but not A - return false; - } - - int size; - if (b.isDirectoryEntry()) { - size = isDirectory; - } else { - size = ((DocumentNode)b).getSize(); - } - if (size != aSizes.get(bName)) { - // Either the wrong type, or they're different sizes - return false; - } - - // Track it as checked - aSizes.remove(bName); - } - if (!aSizes.isEmpty()) { - // Nodes were in A but not B - return false; - } - - // If that passed, check entry contents - for (Entry a : dirA) { - try { - Entry b = dirB.getEntry(a.getName()); - boolean match; - if (a.isDirectoryEntry()) { - match = areDirectoriesIdentical( - (DirectoryEntry)a, (DirectoryEntry)b); - } else { - match = areDocumentsIdentical( - (DocumentEntry)a, (DocumentEntry)b); - } - if (!match) return false; - } catch(FileNotFoundException e) { - // Shouldn't really happen... - return false; - } catch(IOException e) { - // Something's messed up with one document, not a match - return false; - } - } - - // If we get here, they match! - return true; - } - - /** - * Checks to see if two Documents have the same name - * and the same contents. (Their parent directories are - * not checked) - */ - public static boolean areDocumentsIdentical(DocumentEntry docA, DocumentEntry docB) throws IOException { - if (! docA.getName().equals(docB.getName())) { - // Names don't match, not the same - return false; - } - if (docA.getSize() != docB.getSize()) { - // Wrong sizes, can't have the same contents - return false; - } - - boolean matches = true; - DocumentInputStream inpA = null, inpB = null; - try { - inpA = new DocumentInputStream(docA); - inpB = new DocumentInputStream(docB); - - int readA, readB; - do { - readA = inpA.read(); - readB = inpB.read(); - if (readA != readB) { - matches = false; - break; - } - } while(readA != -1 && readB != -1); - } finally { - if (inpA != null) inpA.close(); - if (inpB != null) inpB.close(); - } - - return matches; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java b/trunk/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java deleted file mode 100644 index 3296ddb88..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java +++ /dev/null @@ -1,221 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hpsf.ClassID; - -/** - * A DirectoryEntry filter, which exposes another - * DirectoryEntry less certain parts. - * This is typically used when copying or comparing - * Filesystems. - */ -public class FilteringDirectoryNode implements DirectoryEntry -{ - /** - * The names of our entries to exclude - */ - private Set excludes; - /** - * Excludes of our child directories - */ - private Map> childExcludes; - - private DirectoryEntry directory; - - /** - * Creates a filter round the specified directory, which - * will exclude entries such as "MyNode" and "MyDir/IgnoreNode". - * The excludes can stretch into children, if they contain a /. - * - * @param directory The Directory to filter - * @param excludes The Entries to exclude - */ - public FilteringDirectoryNode(DirectoryEntry directory, Collection excludes) { - this.directory = directory; - - // Process the excludes - this.excludes = new HashSet(); - this.childExcludes = new HashMap>(); - for (String excl : excludes) { - int splitAt = excl.indexOf('/'); - if (splitAt == -1) { - // Applies to us - this.excludes.add(excl); - } else { - // Applies to a child - String child = excl.substring(0, splitAt); - String childExcl = excl.substring(splitAt+1); - if (! this.childExcludes.containsKey(child)) { - this.childExcludes.put(child, new ArrayList()); - } - this.childExcludes.get(child).add(childExcl); - } - } - } - - public DirectoryEntry createDirectory(String name) throws IOException { - return directory.createDirectory(name); - } - - public DocumentEntry createDocument(String name, InputStream stream) - throws IOException { - return directory.createDocument(name, stream); - } - - public DocumentEntry createDocument(String name, int size, - POIFSWriterListener writer) throws IOException { - return directory.createDocument(name, size, writer); - } - - public Iterator getEntries() { - return new FilteringIterator(); - } - - public Iterator iterator() { - return getEntries(); - } - - public int getEntryCount() { - int size = directory.getEntryCount(); - for (String excl : excludes) { - if (directory.hasEntry(excl)) { - size--; - } - } - return size; - } - - public Set getEntryNames() { - Set names = new HashSet(); - for (String name : directory.getEntryNames()) { - if (!excludes.contains(name)) { - names.add(name); - } - } - return names; - } - - public boolean isEmpty() { - return (getEntryCount() == 0); - } - - public boolean hasEntry(String name) { - if (excludes.contains(name)) { - return false; - } - return directory.hasEntry(name); - } - - public Entry getEntry(String name) throws FileNotFoundException { - if (excludes.contains(name)) { - throw new FileNotFoundException(name); - } - - Entry entry = directory.getEntry(name); - return wrapEntry(entry); - } - private Entry wrapEntry(Entry entry) { - String name = entry.getName(); - if (childExcludes.containsKey(name) && entry instanceof DirectoryEntry) { - return new FilteringDirectoryNode( - (DirectoryEntry)entry, childExcludes.get(name)); - } - return entry; - } - - public ClassID getStorageClsid() { - return directory.getStorageClsid(); - } - - public void setStorageClsid(ClassID clsidStorage) { - directory.setStorageClsid(clsidStorage); - } - - public boolean delete() { - return directory.delete(); - } - - public boolean renameTo(String newName) { - return directory.renameTo(newName); - } - - public String getName() { - return directory.getName(); - } - - public DirectoryEntry getParent() { - return directory.getParent(); - } - - public boolean isDirectoryEntry() { - return true; - } - - public boolean isDocumentEntry() { - return false; - } - - private class FilteringIterator implements Iterator { - private Iterator parent; - private Entry next; - - private FilteringIterator() { - parent = directory.getEntries(); - locateNext(); - } - private void locateNext() { - next = null; - Entry e; - while (parent.hasNext() && next == null) { - e = parent.next(); - if (! excludes.contains(e.getName())) { - next = wrapEntry(e); - } - } - } - - public boolean hasNext() { - return (next != null); - } - - public Entry next() { - Entry e = next; - locateNext(); - return e; - } - - public void remove() { - throw new UnsupportedOperationException("Remove not supported"); - } - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java deleted file mode 100644 index 0d09c4714..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java +++ /dev/null @@ -1,309 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Iterator; - -import org.apache.poi.poifs.property.DocumentProperty; -import org.apache.poi.util.LittleEndian; - -/** - * This class provides methods to read a DocumentEntry managed by a - * {@link NPOIFSFileSystem} instance. - */ -public final class NDocumentInputStream extends DocumentInputStream { - /** current offset into the Document */ - private int _current_offset; - /** current block count */ - private int _current_block_count; - - /** current marked offset into the Document (used by mark and reset) */ - private int _marked_offset; - /** and the block count for it */ - private int _marked_offset_count; - - /** the Document's size */ - private int _document_size; - - /** have we been closed? */ - private boolean _closed; - - /** the actual Document */ - private NPOIFSDocument _document; - - private Iterator _data; - private ByteBuffer _buffer; - - /** - * Create an InputStream from the specified DocumentEntry - * - * @param document the DocumentEntry to be read - * - * @exception IOException if the DocumentEntry cannot be opened (like, maybe it has - * been deleted?) - */ - public NDocumentInputStream(DocumentEntry document) throws IOException { - if (!(document instanceof DocumentNode)) { - throw new IOException("Cannot open internal document storage, " + document + " not a Document Node"); - } - _current_offset = 0; - _current_block_count = 0; - _marked_offset = 0; - _marked_offset_count = 0; - _document_size = document.getSize(); - _closed = false; - - DocumentNode doc = (DocumentNode)document; - DocumentProperty property = (DocumentProperty)doc.getProperty(); - _document = new NPOIFSDocument( - property, - ((DirectoryNode)doc.getParent()).getNFileSystem() - ); - _data = _document.getBlockIterator(); - } - - /** - * Create an InputStream from the specified Document - * - * @param document the Document to be read - */ - public NDocumentInputStream(NPOIFSDocument document) { - _current_offset = 0; - _current_block_count = 0; - _marked_offset = 0; - _marked_offset_count = 0; - _document_size = document.getSize(); - _closed = false; - _document = document; - _data = _document.getBlockIterator(); - } - - @Override - public int available() { - if (_closed) { - throw new IllegalStateException("cannot perform requested operation on a closed stream"); - } - return _document_size - _current_offset; - } - - @Override - public void close() { - _closed = true; - } - - @Override - public void mark(int ignoredReadlimit) { - _marked_offset = _current_offset; - _marked_offset_count = Math.max(0, _current_block_count - 1); - } - - @Override - public int read() throws IOException { - dieIfClosed(); - if (atEOD()) { - return EOF; - } - byte[] b = new byte[1]; - int result = read(b, 0, 1); - if(result >= 0) { - if(b[0] < 0) { - return b[0]+256; - } - return b[0]; - } - return result; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - dieIfClosed(); - if (b == null) { - throw new IllegalArgumentException("buffer must not be null"); - } - if (off < 0 || len < 0 || b.length < off + len) { - throw new IndexOutOfBoundsException("can't read past buffer boundaries"); - } - if (len == 0) { - return 0; - } - if (atEOD()) { - return EOF; - } - int limit = Math.min(available(), len); - readFully(b, off, limit); - return limit; - } - - /** - * Repositions this stream to the position at the time the mark() method was - * last called on this input stream. If mark() has not been called this - * method repositions the stream to its beginning. - */ - @Override - public void reset() { - // Special case for reset to the start - if(_marked_offset == 0 && _marked_offset_count == 0) { - _current_block_count = _marked_offset_count; - _current_offset = _marked_offset; - _data = _document.getBlockIterator(); - _buffer = null; - return; - } - - // Start again, then wind on to the required block - _data = _document.getBlockIterator(); - _current_offset = 0; - for(int i=0; i<_marked_offset_count; i++) { - _buffer = _data.next(); - _current_offset += _buffer.remaining(); - } - - _current_block_count = _marked_offset_count; - - // Do we need to position within it? - if(_current_offset != _marked_offset) { - // Grab the right block - _buffer = _data.next(); - _current_block_count++; - - // Skip to the right place in it - // (It should be positioned already at the start of the block, - // we need to move further inside the block) - int skipBy = _marked_offset - _current_offset; - _buffer.position(_buffer.position() + skipBy); - } - - // All done - _current_offset = _marked_offset; - } - - @Override - public long skip(long n) throws IOException { - dieIfClosed(); - if (n < 0) { - return 0; - } - int new_offset = _current_offset + (int) n; - - if (new_offset < _current_offset) { - // wrap around in converting a VERY large long to an int - new_offset = _document_size; - } else if (new_offset > _document_size) { - new_offset = _document_size; - } - - long rval = new_offset - _current_offset; - - // TODO Do this better - byte[] skip = new byte[(int)rval]; - readFully(skip); - return rval; - } - - private void dieIfClosed() throws IOException { - if (_closed) { - throw new IOException("cannot perform requested operation on a closed stream"); - } - } - - private boolean atEOD() { - return _current_offset == _document_size; - } - - private void checkAvaliable(int requestedSize) { - if (_closed) { - throw new IllegalStateException("cannot perform requested operation on a closed stream"); - } - if (requestedSize > _document_size - _current_offset) { - throw new RuntimeException("Buffer underrun - requested " + requestedSize - + " bytes but " + (_document_size - _current_offset) + " was available"); - } - } - - @Override - public void readFully(byte[] buf, int off, int len) { - checkAvaliable(len); - - int read = 0; - while(read < len) { - if(_buffer == null || _buffer.remaining() == 0) { - _current_block_count++; - _buffer = _data.next(); - } - - int limit = Math.min(len-read, _buffer.remaining()); - _buffer.get(buf, off+read, limit); - _current_offset += limit; - read += limit; - } - } - - @Override - public byte readByte() { - return (byte) readUByte(); - } - - @Override - public double readDouble() { - return Double.longBitsToDouble(readLong()); - } - - @Override - public long readLong() { - checkAvaliable(SIZE_LONG); - byte[] data = new byte[SIZE_LONG]; - readFully(data, 0, SIZE_LONG); - return LittleEndian.getLong(data, 0); - } - - @Override - public short readShort() { - checkAvaliable(SIZE_SHORT); - byte[] data = new byte[SIZE_SHORT]; - readFully(data, 0, SIZE_SHORT); - return LittleEndian.getShort(data); - } - - @Override - public int readInt() { - checkAvaliable(SIZE_INT); - byte[] data = new byte[SIZE_INT]; - readFully(data, 0, SIZE_INT); - return LittleEndian.getInt(data); - } - - @Override - public int readUShort() { - checkAvaliable(SIZE_SHORT); - byte[] data = new byte[SIZE_SHORT]; - readFully(data, 0, SIZE_SHORT); - return LittleEndian.getUShort(data); - } - - @Override - public int readUByte() { - checkAvaliable(1); - byte[] data = new byte[1]; - readFully(data, 0, 1); - if(data[0] >= 0) - return data[0]; - return data[0] + 256; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java deleted file mode 100644 index 6d4d13d5d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java +++ /dev/null @@ -1,163 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.property.DocumentProperty; - -/** - * This class provides methods to write a DocumentEntry managed by a - * {@link NPOIFSFileSystem} instance. - */ -public final class NDocumentOutputStream extends OutputStream { - /** the Document's size */ - private int _document_size; - - /** have we been closed? */ - private boolean _closed; - - /** the actual Document */ - private NPOIFSDocument _document; - /** and its Property */ - private DocumentProperty _property; - - /** our buffer, when null we're into normal blocks */ - private ByteArrayOutputStream _buffer = - new ByteArrayOutputStream(POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE); - - /** our main block stream, when we're into normal blocks */ - private NPOIFSStream _stream; - private OutputStream _stream_output; - - /** - * Create an OutputStream from the specified DocumentEntry. - * The specified entry will be emptied. - * - * @param document the DocumentEntry to be written - */ - public NDocumentOutputStream(DocumentEntry document) throws IOException { - if (!(document instanceof DocumentNode)) { - throw new IOException("Cannot open internal document storage, " + document + " not a Document Node"); - } - _document_size = 0; - _closed = false; - - _property = (DocumentProperty)((DocumentNode)document).getProperty(); - - _document = new NPOIFSDocument((DocumentNode)document); - _document.free(); - } - - /** - * Create an OutputStream to create the specified new Entry - * - * @param parent Where to create the Entry - * @param name Name of the new entry - */ - public NDocumentOutputStream(DirectoryEntry parent, String name) throws IOException { - if (!(parent instanceof DirectoryNode)) { - throw new IOException("Cannot open internal directory storage, " + parent + " not a Directory Node"); - } - _document_size = 0; - _closed = false; - - // Have an empty one created for now - DocumentEntry doc = parent.createDocument(name, new ByteArrayInputStream(new byte[0])); - _property = (DocumentProperty)((DocumentNode)doc).getProperty(); - _document = new NPOIFSDocument((DocumentNode)doc); - } - - private void dieIfClosed() throws IOException { - if (_closed) { - throw new IOException("cannot perform requested operation on a closed stream"); - } - } - - private void checkBufferSize() throws IOException { - // Have we gone over the mini stream limit yet? - if (_buffer.size() > POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) { - // Will need to be in the main stream - byte[] data = _buffer.toByteArray(); - _buffer = null; - write(data, 0, data.length); - } else { - // So far, mini stream will work, keep going - } - } - - public void write(int b) throws IOException { - dieIfClosed(); - - if (_buffer != null) { - _buffer.write(b); - checkBufferSize(); - } else { - write(new byte[] { (byte)b }); - } - } - - public void write(byte[] b) throws IOException { - dieIfClosed(); - - if (_buffer != null) { - _buffer.write(b); - checkBufferSize(); - } else { - write(b, 0, b.length); - } - } - - public void write(byte[] b, int off, int len) throws IOException { - dieIfClosed(); - - if (_buffer != null) { - _buffer.write(b, off, len); - checkBufferSize(); - } else { - if (_stream == null) { - _stream = new NPOIFSStream(_document.getFileSystem()); - _stream_output = _stream.getOutputStream(); - } - _stream_output.write(b, off, len); - _document_size += len; - } - } - - public void close() throws IOException { - // Do we have a pending buffer for the mini stream? - if (_buffer != null) { - // It's not much data, so ask NPOIFSDocument to do it for us - _document.replaceContents(new ByteArrayInputStream(_buffer.toByteArray())); - } - else { - // We've been writing to the stream as we've gone along - // Update the details on the property now - _stream_output.close(); - _property.updateSize(_document_size); - _property.setStartBlock(_stream.getStartBlock()); - } - - // No more! - _closed = true; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java deleted file mode 100644 index 7e7ca0780..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java +++ /dev/null @@ -1,265 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.poifs.property.DocumentProperty; -import org.apache.poi.util.HexDump; - -/** - * This class manages a document in the NIO POIFS filesystem. - * This is the {@link NPOIFSFileSystem} version. - */ -public final class NPOIFSDocument implements POIFSViewable { - private DocumentProperty _property; - - private NPOIFSFileSystem _filesystem; - private NPOIFSStream _stream; - private int _block_size; - - /** - * Constructor for an existing Document - */ - public NPOIFSDocument(DocumentNode document) throws IOException { - this((DocumentProperty)document.getProperty(), - ((DirectoryNode)document.getParent()).getNFileSystem()); - } - - /** - * Constructor for an existing Document - */ - public NPOIFSDocument(DocumentProperty property, NPOIFSFileSystem filesystem) - throws IOException - { - this._property = property; - this._filesystem = filesystem; - - if(property.getSize() < POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) { - _stream = new NPOIFSStream(_filesystem.getMiniStore(), property.getStartBlock()); - _block_size = _filesystem.getMiniStore().getBlockStoreBlockSize(); - } else { - _stream = new NPOIFSStream(_filesystem, property.getStartBlock()); - _block_size = _filesystem.getBlockStoreBlockSize(); - } - } - - /** - * Constructor for a new Document - * - * @param name the name of the POIFSDocument - * @param stream the InputStream we read data from - */ - public NPOIFSDocument(String name, NPOIFSFileSystem filesystem, InputStream stream) - throws IOException - { - this._filesystem = filesystem; - - // Store it - int length = store(stream); - - // Build the property for it - this._property = new DocumentProperty(name, length); - _property.setStartBlock(_stream.getStartBlock()); - } - - public NPOIFSDocument(String name, int size, NPOIFSFileSystem filesystem, POIFSWriterListener writer) - throws IOException - { - this._filesystem = filesystem; - - if (size < POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) { - _stream = new NPOIFSStream(filesystem.getMiniStore()); - _block_size = _filesystem.getMiniStore().getBlockStoreBlockSize(); - } else { - _stream = new NPOIFSStream(filesystem); - _block_size = _filesystem.getBlockStoreBlockSize(); - } - - OutputStream innerOs = _stream.getOutputStream(); - DocumentOutputStream os = new DocumentOutputStream(innerOs, size); - POIFSDocumentPath path = new POIFSDocumentPath(name.split("\\\\")); - String docName = path.getComponent(path.length()-1); - POIFSWriterEvent event = new POIFSWriterEvent(os, path, docName, size); - writer.processPOIFSWriterEvent(event); - innerOs.close(); - - // And build the property for it - this._property = new DocumentProperty(name, size); - _property.setStartBlock(_stream.getStartBlock()); - } - - /** - * Stores the given data for this Document - */ - private int store(InputStream stream) throws IOException { - final int bigBlockSize = POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE; - BufferedInputStream bis = new BufferedInputStream(stream, bigBlockSize+1); - bis.mark(bigBlockSize); - - // Do we need to store as a mini stream or a full one? - if(bis.skip(bigBlockSize) < bigBlockSize) { - _stream = new NPOIFSStream(_filesystem.getMiniStore()); - _block_size = _filesystem.getMiniStore().getBlockStoreBlockSize(); - } else { - _stream = new NPOIFSStream(_filesystem); - _block_size = _filesystem.getBlockStoreBlockSize(); - } - - // start from the beginning - bis.reset(); - - // Store it - OutputStream os = _stream.getOutputStream(); - byte buf[] = new byte[1024]; - int length = 0; - - for (int readBytes; (readBytes = bis.read(buf)) != -1; length += readBytes) { - os.write(buf, 0, readBytes); - } - - // Pad to the end of the block with -1s - int usedInBlock = length % _block_size; - if (usedInBlock != 0 && usedInBlock != _block_size) { - int toBlockEnd = _block_size - usedInBlock; - byte[] padding = new byte[toBlockEnd]; - Arrays.fill(padding, (byte)0xFF); - os.write(padding); - } - - // Tidy and return the length - os.close(); - return length; - } - - /** - * Frees the underlying stream and property - */ - void free() throws IOException { - _stream.free(); - _property.setStartBlock(POIFSConstants.END_OF_CHAIN); - } - - NPOIFSFileSystem getFileSystem() - { - return _filesystem; - } - - int getDocumentBlockSize() { - return _block_size; - } - - Iterator getBlockIterator() { - if(getSize() > 0) { - return _stream.getBlockIterator(); - } else { - List empty = Collections.emptyList(); - return empty.iterator(); - } - } - - /** - * @return size of the document - */ - public int getSize() { - return _property.getSize(); - } - - public void replaceContents(InputStream stream) throws IOException { - free(); - int size = store(stream); - _property.setStartBlock(_stream.getStartBlock()); - _property.updateSize(size); - } - - /** - * @return the instance's DocumentProperty - */ - DocumentProperty getDocumentProperty() { - return _property; - } - - /** - * Get an array of objects, some of which may implement POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - public Object[] getViewableArray() { - String result = ""; - - if(getSize() > 0) { - // Get all the data into a single array - byte[] data = new byte[getSize()]; - int offset = 0; - for(ByteBuffer buffer : _stream) { - int length = Math.min(_block_size, data.length-offset); - buffer.get(data, offset, length); - offset += length; - } - - result = HexDump.dump(data, 0, 0); - } - - return new String[]{ result }; - } - - /** - * Get an Iterator of objects, some of which may implement POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty back end - * store - */ - public Iterator getViewableIterator() { - return Collections.emptyList().iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, - * false if a viewer should call getViewableIterator - */ - public boolean preferArray() { - return true; - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - public String getShortDescription() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("Document: \"").append(_property.getName()).append("\""); - buffer.append(" size = ").append(getSize()); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java deleted file mode 100644 index f987c43b3..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java +++ /dev/null @@ -1,1023 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PushbackInputStream; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.EmptyFileException; -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.poifs.nio.ByteArrayBackedDataSource; -import org.apache.poi.poifs.nio.DataSource; -import org.apache.poi.poifs.nio.FileBackedDataSource; -import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.DocumentProperty; -import org.apache.poi.poifs.property.NPropertyTable; -import org.apache.poi.poifs.storage.BATBlock; -import org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex; -import org.apache.poi.poifs.storage.BlockAllocationTableReader; -import org.apache.poi.poifs.storage.BlockAllocationTableWriter; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.poifs.storage.HeaderBlockConstants; -import org.apache.poi.poifs.storage.HeaderBlockWriter; -import org.apache.poi.util.CloseIgnoringInputStream; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LongField; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - *

    This is the main class of the POIFS system; it manages the entire - * life cycle of the filesystem.

    - *

    This is the new NIO version, which uses less memory

    - */ - -public class NPOIFSFileSystem extends BlockStore - implements POIFSViewable, Closeable -{ - private static final POILogger LOG = POILogFactory.getLogger(NPOIFSFileSystem.class); - - /** - * Convenience method for clients that want to avoid the auto-close behaviour of the constructor. - */ - public static InputStream createNonClosingInputStream(InputStream is) { - return new CloseIgnoringInputStream(is); - } - - private NPOIFSMiniStore _mini_store; - private NPropertyTable _property_table; - private List _xbat_blocks; - private List _bat_blocks; - private HeaderBlock _header; - private DirectoryNode _root; - - private DataSource _data; - - /** - * What big block size the file uses. Most files - * use 512 bytes, but a few use 4096 - */ - private POIFSBigBlockSize bigBlockSize = - POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; - - private NPOIFSFileSystem(boolean newFS) - { - _header = new HeaderBlock(bigBlockSize); - _property_table = new NPropertyTable(_header); - _mini_store = new NPOIFSMiniStore(this, _property_table.getRoot(), new ArrayList(), _header); - _xbat_blocks = new ArrayList(); - _bat_blocks = new ArrayList(); - _root = null; - - if(newFS) { - // Data needs to initially hold just the header block, - // a single bat block, and an empty properties section - _data = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()*3]); - } - } - - /** - * Constructor, intended for writing - */ - public NPOIFSFileSystem() - { - this(true); - - // Reserve block 0 for the start of the Properties Table - // Create a single empty BAT, at pop that at offset 1 - _header.setBATCount(1); - _header.setBATArray(new int[] { 1 }); - BATBlock bb = BATBlock.createEmptyBATBlock(bigBlockSize, false); - bb.setOurBlockIndex(1); - _bat_blocks.add(bb); - - setNextBlock(0, POIFSConstants.END_OF_CHAIN); - setNextBlock(1, POIFSConstants.FAT_SECTOR_BLOCK); - - _property_table.setStartBlock(0); - } - - /** - *

    Creates a POIFSFileSystem from a File. This uses less memory than - * creating from an InputStream. The File will be opened read-only

    - * - *

    Note that with this constructor, you will need to call {@link #close()} - * when you're done to have the underlying file closed, as the file is - * kept open during normal operation to read the data out.

    - * - * @param file the File from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - public NPOIFSFileSystem(File file) - throws IOException - { - this(file, true); - } - - /** - *

    Creates a POIFSFileSystem from a File. This uses less memory than - * creating from an InputStream.

    - * - *

    Note that with this constructor, you will need to call {@link #close()} - * when you're done to have the underlying file closed, as the file is - * kept open during normal operation to read the data out.

    - * - * @param file the File from which to read or read/write the data - * @param readOnly whether the POIFileSystem will only be used in read-only mode - * - * @exception IOException on errors reading, or on invalid data - */ - public NPOIFSFileSystem(File file, boolean readOnly) - throws IOException - { - this(null, file, readOnly, true); - } - - /** - *

    Creates a POIFSFileSystem from an open FileChannel. This uses - * less memory than creating from an InputStream. The stream will - * be used in read-only mode.

    - * - *

    Note that with this constructor, you will need to call {@link #close()} - * when you're done to have the underlying Channel closed, as the channel is - * kept open during normal operation to read the data out.

    - * - * @param channel the FileChannel from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - public NPOIFSFileSystem(FileChannel channel) - throws IOException - { - this(channel, true); - } - - /** - *

    Creates a POIFSFileSystem from an open FileChannel. This uses - * less memory than creating from an InputStream.

    - * - *

    Note that with this constructor, you will need to call {@link #close()} - * when you're done to have the underlying Channel closed, as the channel is - * kept open during normal operation to read the data out.

    - * - * @param channel the FileChannel from which to read or read/write the data - * @param readOnly whether the POIFileSystem will only be used in read-only mode - * - * @exception IOException on errors reading, or on invalid data - */ - public NPOIFSFileSystem(FileChannel channel, boolean readOnly) - throws IOException - { - this(channel, null, readOnly, false); - } - - private NPOIFSFileSystem(FileChannel channel, File srcFile, boolean readOnly, boolean closeChannelOnError) - throws IOException - { - this(false); - - try { - // Initialize the datasource - if (srcFile != null) { - if (srcFile.length() == 0) - throw new EmptyFileException(); - - FileBackedDataSource d = new FileBackedDataSource(srcFile, readOnly); - channel = d.getChannel(); - _data = d; - } else { - _data = new FileBackedDataSource(channel, readOnly); - } - - // Get the header - ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE); - IOUtils.readFully(channel, headerBuffer); - - // Have the header processed - _header = new HeaderBlock(headerBuffer); - - // Now process the various entries - readCoreContents(); - } catch(IOException e) { - // Until we upgrade to Java 7, and can do a MultiCatch, we - // need to keep these two catch blocks in sync on their cleanup - if (closeChannelOnError && channel != null) { - channel.close(); - channel = null; - } - throw e; - } catch(RuntimeException e) { - // Comes from Iterators etc. - // TODO Decide if we can handle these better whilst - // still sticking to the iterator contract - if (closeChannelOnError && channel != null) { - channel.close(); - channel = null; - } - throw e; - } - } - - /** - * Create a POIFSFileSystem from an InputStream. Normally the stream is read until - * EOF. The stream is always closed.

    - * - * Some streams are usable after reaching EOF (typically those that return true - * for markSupported()). In the unlikely case that the caller has such a stream - * and needs to use it after this constructor completes, a work around is to wrap the - * stream in order to trap the close() call. A convenience method ( - * createNonClosingInputStream()) has been provided for this purpose: - *

    -     * InputStream wrappedStream = POIFSFileSystem.createNonClosingInputStream(is);
    -     * HSSFWorkbook wb = new HSSFWorkbook(wrappedStream);
    -     * is.reset();
    -     * doSomethingElse(is);
    -     * 
    - * Note also the special case of ByteArrayInputStream for which the close() - * method does nothing. - *
    -     * ByteArrayInputStream bais = ...
    -     * HSSFWorkbook wb = new HSSFWorkbook(bais); // calls bais.close() !
    -     * bais.reset(); // no problem
    -     * doSomethingElse(bais);
    -     * 
    - * - * @param stream the InputStream from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - - public NPOIFSFileSystem(InputStream stream) - throws IOException - { - this(false); - - ReadableByteChannel channel = null; - boolean success = false; - - try { - // Turn our InputStream into something NIO based - channel = Channels.newChannel(stream); - - // Get the header - ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE); - IOUtils.readFully(channel, headerBuffer); - - // Have the header processed - _header = new HeaderBlock(headerBuffer); - - // Sanity check the block count - BlockAllocationTableReader.sanityCheckBlockCount(_header.getBATCount()); - - // We need to buffer the whole file into memory when - // working with an InputStream. - // The max possible size is when each BAT block entry is used - long maxSize = BATBlock.calculateMaximumSize(_header); - if (maxSize > Integer.MAX_VALUE) { - throw new IllegalArgumentException("Unable read a >2gb file via an InputStream"); - } - ByteBuffer data = ByteBuffer.allocate((int)maxSize); - - // Copy in the header - headerBuffer.position(0); - data.put(headerBuffer); - data.position(headerBuffer.capacity()); - - // Now read the rest of the stream - IOUtils.readFully(channel, data); - success = true; - - // Turn it into a DataSource - _data = new ByteArrayBackedDataSource(data.array(), data.position()); - } finally { - // As per the constructor contract, always close the stream - if(channel != null) - channel.close(); - closeInputStream(stream, success); - } - - // Now process the various entries - readCoreContents(); - } - /** - * @param stream the stream to be closed - * @param success false if an exception is currently being thrown in the calling method - */ - private void closeInputStream(InputStream stream, boolean success) { - try { - stream.close(); - } catch (IOException e) { - if(success) { - throw new RuntimeException(e); - } - // else not success? Try block did not complete normally - // just print stack trace and leave original ex to be thrown - LOG.log(POILogger.ERROR, "can't close input stream", e); - } - } - - /** - * Checks that the supplied InputStream (which MUST - * support mark and reset, or be a PushbackInputStream) - * has a POIFS (OLE2) header at the start of it. - * If your InputStream does not support mark / reset, - * then wrap it in a PushBackInputStream, then be - * sure to always use that and not the original! - * - * After the method call, the InputStream is at the - * same position as of the time of entering the method. - * - * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream - */ - public static boolean hasPOIFSHeader(InputStream inp) throws IOException { - // We want to peek at the first 8 bytes - inp.mark(8); - - byte[] header = new byte[8]; - int bytesRead = IOUtils.readFully(inp, header); - LongField signature = new LongField(HeaderBlockConstants._signature_offset, header); - - // Wind back those 8 bytes - if(inp instanceof PushbackInputStream) { - PushbackInputStream pin = (PushbackInputStream)inp; - pin.unread(header, 0, bytesRead); - } else { - inp.reset(); - } - - // Did it match the signature? - return (signature.get() == HeaderBlockConstants._signature); - } - - /** - * Checks if the supplied first 8 bytes of a stream / file - * has a POIFS (OLE2) header. - */ - public static boolean hasPOIFSHeader(byte[] header8Bytes) { - LongField signature = new LongField(HeaderBlockConstants._signature_offset, header8Bytes); - return (signature.get() == HeaderBlockConstants._signature); - } - - /** - * Read and process the PropertiesTable and the - * FAT / XFAT blocks, so that we're ready to - * work with the file - */ - private void readCoreContents() throws IOException { - // Grab the block size - bigBlockSize = _header.getBigBlockSize(); - - // Each block should only ever be used by one of the - // FAT, XFAT or Property Table. Ensure it does - ChainLoopDetector loopDetector = getChainLoopDetector(); - - // Read the FAT blocks - for(int fatAt : _header.getBATArray()) { - readBAT(fatAt, loopDetector); - } - - // Work out how many FAT blocks remain in the XFATs - int remainingFATs = _header.getBATCount() - _header.getBATArray().length; - - // Now read the XFAT blocks, and the FATs within them - BATBlock xfat; - int nextAt = _header.getXBATIndex(); - for(int i=0; i<_header.getXBATCount(); i++) { - loopDetector.claim(nextAt); - ByteBuffer fatData = getBlockAt(nextAt); - xfat = BATBlock.createBATBlock(bigBlockSize, fatData); - xfat.setOurBlockIndex(nextAt); - nextAt = xfat.getValueAt(bigBlockSize.getXBATEntriesPerBlock()); - _xbat_blocks.add(xfat); - - // Process all the (used) FATs from this XFAT - int xbatFATs = Math.min(remainingFATs, bigBlockSize.getXBATEntriesPerBlock()); - for(int j=0; j sbats = new ArrayList(); - _mini_store = new NPOIFSMiniStore(this, _property_table.getRoot(), sbats, _header); - nextAt = _header.getSBATStart(); - for(int i=0; i<_header.getSBATCount() && nextAt != POIFSConstants.END_OF_CHAIN; i++) { - loopDetector.claim(nextAt); - ByteBuffer fatData = getBlockAt(nextAt); - sfat = BATBlock.createBATBlock(bigBlockSize, fatData); - sfat.setOurBlockIndex(nextAt); - sbats.add(sfat); - nextAt = getNextBlock(nextAt); - } - } - private void readBAT(int batAt, ChainLoopDetector loopDetector) throws IOException { - loopDetector.claim(batAt); - ByteBuffer fatData = getBlockAt(batAt); - BATBlock bat = BATBlock.createBATBlock(bigBlockSize, fatData); - bat.setOurBlockIndex(batAt); - _bat_blocks.add(bat); - } - private BATBlock createBAT(int offset, boolean isBAT) throws IOException { - // Create a new BATBlock - BATBlock newBAT = BATBlock.createEmptyBATBlock(bigBlockSize, !isBAT); - newBAT.setOurBlockIndex(offset); - // Ensure there's a spot in the file for it - ByteBuffer buffer = ByteBuffer.allocate(bigBlockSize.getBigBlockSize()); - int writeTo = (1+offset) * bigBlockSize.getBigBlockSize(); // Header isn't in BATs - _data.write(buffer, writeTo); - // All done - return newBAT; - } - - /** - * Load the block at the given offset. - */ - @Override - protected ByteBuffer getBlockAt(final int offset) throws IOException { - // The header block doesn't count, so add one - long blockWanted = offset + 1; - long startAt = blockWanted * bigBlockSize.getBigBlockSize(); - try { - return _data.read(bigBlockSize.getBigBlockSize(), startAt); - } catch (IndexOutOfBoundsException e) { - IndexOutOfBoundsException wrapped = new IndexOutOfBoundsException("Block " + offset + " not found"); - wrapped.initCause(e); - throw wrapped; - } - } - - /** - * Load the block at the given offset, - * extending the file if needed - */ - @Override - protected ByteBuffer createBlockIfNeeded(final int offset) throws IOException { - try { - return getBlockAt(offset); - } catch(IndexOutOfBoundsException e) { - // The header block doesn't count, so add one - long startAt = (offset+1) * bigBlockSize.getBigBlockSize(); - // Allocate and write - ByteBuffer buffer = ByteBuffer.allocate(getBigBlockSize()); - _data.write(buffer, startAt); - // Retrieve the properly backed block - return getBlockAt(offset); - } - } - - /** - * Returns the BATBlock that handles the specified offset, - * and the relative index within it - */ - @Override - protected BATBlockAndIndex getBATBlockAndIndex(final int offset) { - return BATBlock.getBATBlockAndIndex( - offset, _header, _bat_blocks - ); - } - - /** - * Works out what block follows the specified one. - */ - @Override - protected int getNextBlock(final int offset) { - BATBlockAndIndex bai = getBATBlockAndIndex(offset); - return bai.getBlock().getValueAt( bai.getIndex() ); - } - - /** - * Changes the record of what block follows the specified one. - */ - @Override - protected void setNextBlock(final int offset, final int nextBlock) { - BATBlockAndIndex bai = getBATBlockAndIndex(offset); - bai.getBlock().setValueAt( - bai.getIndex(), nextBlock - ); - } - - /** - * Finds a free block, and returns its offset. - * This method will extend the file if needed, and if doing - * so, allocate new FAT blocks to address the extra space. - */ - @Override - protected int getFreeBlock() throws IOException { - int numSectors = bigBlockSize.getBATEntriesPerBlock(); - - // First up, do we have any spare ones? - int offset = 0; - for (BATBlock bat : _bat_blocks) { - if(bat.hasFreeSectors()) { - // Claim one of them and return it - for(int j=0; j= 109) { - // Needs to come from an XBAT - BATBlock xbat = null; - for(BATBlock x : _xbat_blocks) { - if(x.hasFreeSectors()) { - xbat = x; - break; - } - } - if(xbat == null) { - // Oh joy, we need a new XBAT too... - xbat = createBAT(offset+1, false); - // Allocate our new BAT as the first block in the XBAT - xbat.setValueAt(0, offset); - // And allocate the XBAT in the BAT - bat.setValueAt(1, POIFSConstants.DIFAT_SECTOR_BLOCK); - - // Will go one place higher as XBAT added in - offset++; - - // Chain it - if(_xbat_blocks.size() == 0) { - _header.setXBATStart(offset); - } else { - _xbat_blocks.get(_xbat_blocks.size()-1).setValueAt( - bigBlockSize.getXBATEntriesPerBlock(), offset - ); - } - _xbat_blocks.add(xbat); - _header.setXBATCount(_xbat_blocks.size()); - } else { - // Allocate our BAT in the existing XBAT with space - for(int i=0; i getViewableIterator() - { - if (!preferArray()) - { - return (( POIFSViewable ) getRoot()).getViewableIterator(); - } - return Collections.emptyList().iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, false if - * a viewer should call getViewableIterator - */ - - public boolean preferArray() - { - return (( POIFSViewable ) getRoot()).preferArray(); - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - - public String getShortDescription() - { - return "POIFS FileSystem"; - } - - /* ********** END begin implementation of POIFSViewable ********** */ - - /** - * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes - */ - public int getBigBlockSize() { - return bigBlockSize.getBigBlockSize(); - } - - /** - * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes - */ - public POIFSBigBlockSize getBigBlockSizeDetails() { - return bigBlockSize; - } - - @Override - protected int getBlockStoreBlockSize() { - return getBigBlockSize(); - } - - @Internal - public NPropertyTable getPropertyTable() { - return _property_table; - } - - @Internal - public HeaderBlock getHeaderBlock() { - return _header; - } -} - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java deleted file mode 100644 index b784058bc..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java +++ /dev/null @@ -1,265 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.property.RootProperty; -import org.apache.poi.poifs.storage.BATBlock; -import org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex; -import org.apache.poi.poifs.storage.BlockAllocationTableWriter; -import org.apache.poi.poifs.storage.HeaderBlock; - -/** - * This class handles the MiniStream (small block store) - * in the NIO case for {@link NPOIFSFileSystem} - */ -public class NPOIFSMiniStore extends BlockStore -{ - private NPOIFSFileSystem _filesystem; - private NPOIFSStream _mini_stream; - private List _sbat_blocks; - private HeaderBlock _header; - private RootProperty _root; - - protected NPOIFSMiniStore(NPOIFSFileSystem filesystem, RootProperty root, - List sbats, HeaderBlock header) - { - this._filesystem = filesystem; - this._sbat_blocks = sbats; - this._header = header; - this._root = root; - - this._mini_stream = new NPOIFSStream(filesystem, root.getStartBlock()); - } - - /** - * Load the block at the given offset. - */ - protected ByteBuffer getBlockAt(final int offset) throws IOException { - // Which big block is this? - int byteOffset = offset * POIFSConstants.SMALL_BLOCK_SIZE; - int bigBlockNumber = byteOffset / _filesystem.getBigBlockSize(); - int bigBlockOffset = byteOffset % _filesystem.getBigBlockSize(); - - // Now locate the data block for it - Iterator it = _mini_stream.getBlockIterator(); - for(int i=0; i bytes conversion for us - _filesystem._get_property_table().getRoot().setSize(blocksUsed); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java deleted file mode 100644 index da24fc383..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java +++ /dev/null @@ -1,266 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.Iterator; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.filesystem.BlockStore.ChainLoopDetector; -import org.apache.poi.poifs.property.Property; -import org.apache.poi.poifs.storage.HeaderBlock; - -/** - * This handles reading and writing a stream within a - * {@link NPOIFSFileSystem}. It can supply an iterator - * to read blocks, and way to write out to existing and - * new blocks. - * Most users will want a higher level version of this, - * which deals with properties to track which stream - * this is. - * This only works on big block streams, it doesn't - * handle small block ones. - * This uses the new NIO code - * - * TODO Implement a streaming write method, and append - */ - -public class NPOIFSStream implements Iterable -{ - private BlockStore blockStore; - private int startBlock; - private OutputStream outStream; - - /** - * Constructor for an existing stream. It's up to you - * to know how to get the start block (eg from a - * {@link HeaderBlock} or a {@link Property}) - */ - public NPOIFSStream(BlockStore blockStore, int startBlock) { - this.blockStore = blockStore; - this.startBlock = startBlock; - } - - /** - * Constructor for a new stream. A start block won't - * be allocated until you begin writing to it. - */ - public NPOIFSStream(BlockStore blockStore) { - this.blockStore = blockStore; - this.startBlock = POIFSConstants.END_OF_CHAIN; - } - - /** - * What block does this stream start at? - * Will be {@link POIFSConstants#END_OF_CHAIN} for a - * new stream that hasn't been written to yet. - */ - public int getStartBlock() { - return startBlock; - } - - /** - * Returns an iterator that'll supply one {@link ByteBuffer} - * per block in the stream. - */ - public Iterator iterator() { - return getBlockIterator(); - } - - public Iterator getBlockIterator() { - if(startBlock == POIFSConstants.END_OF_CHAIN) { - throw new IllegalStateException( - "Can't read from a new stream before it has been written to" - ); - } - return new StreamBlockByteBufferIterator(startBlock); - } - - /** - * Updates the contents of the stream to the new - * set of bytes. - * Note - if this is property based, you'll still - * need to update the size in the property yourself - */ - public void updateContents(byte[] contents) throws IOException { - OutputStream os = getOutputStream(); - os.write(contents); - os.close(); - } - - public OutputStream getOutputStream() throws IOException { - if (outStream == null) { - outStream = new StreamBlockByteBuffer(); - } - return outStream; - } - - // TODO Streaming write support - // TODO then convert fixed sized write to use streaming internally - // TODO Append write support (probably streaming) - - /** - * Frees all blocks in the stream - */ - public void free() throws IOException { - ChainLoopDetector loopDetector = blockStore.getChainLoopDetector(); - free(loopDetector); - } - private void free(ChainLoopDetector loopDetector) { - int nextBlock = startBlock; - while(nextBlock != POIFSConstants.END_OF_CHAIN) { - int thisBlock = nextBlock; - loopDetector.claim(thisBlock); - nextBlock = blockStore.getNextBlock(thisBlock); - blockStore.setNextBlock(thisBlock, POIFSConstants.UNUSED_BLOCK); - } - this.startBlock = POIFSConstants.END_OF_CHAIN; - } - - /** - * Class that handles a streaming read of one stream - */ - protected class StreamBlockByteBufferIterator implements Iterator { - private ChainLoopDetector loopDetector; - private int nextBlock; - - protected StreamBlockByteBufferIterator(int firstBlock) { - this.nextBlock = firstBlock; - try { - this.loopDetector = blockStore.getChainLoopDetector(); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - - public boolean hasNext() { - if(nextBlock == POIFSConstants.END_OF_CHAIN) { - return false; - } - return true; - } - - public ByteBuffer next() { - if(nextBlock == POIFSConstants.END_OF_CHAIN) { - throw new IndexOutOfBoundsException("Can't read past the end of the stream"); - } - - try { - loopDetector.claim(nextBlock); - ByteBuffer data = blockStore.getBlockAt(nextBlock); - nextBlock = blockStore.getNextBlock(nextBlock); - return data; - } catch(IOException e) { - throw new RuntimeException(e); - } - } - - public void remove() { - throw new UnsupportedOperationException(); - } - } - - protected class StreamBlockByteBuffer extends OutputStream { - byte oneByte[] = new byte[1]; - ByteBuffer buffer; - // Make sure we don't encounter a loop whilst overwriting - // the existing blocks - ChainLoopDetector loopDetector; - int prevBlock, nextBlock; - - protected StreamBlockByteBuffer() throws IOException { - loopDetector = blockStore.getChainLoopDetector(); - prevBlock = POIFSConstants.END_OF_CHAIN; - nextBlock = startBlock; - } - - protected void createBlockIfNeeded() throws IOException { - if (buffer != null && buffer.hasRemaining()) return; - - int thisBlock = nextBlock; - - // Allocate a block if needed, otherwise figure - // out what the next block will be - if(thisBlock == POIFSConstants.END_OF_CHAIN) { - thisBlock = blockStore.getFreeBlock(); - loopDetector.claim(thisBlock); - - // We're on the end of the chain - nextBlock = POIFSConstants.END_OF_CHAIN; - - // Mark the previous block as carrying on to us if needed - if(prevBlock != POIFSConstants.END_OF_CHAIN) { - blockStore.setNextBlock(prevBlock, thisBlock); - } - blockStore.setNextBlock(thisBlock, POIFSConstants.END_OF_CHAIN); - - // If we've just written the first block on a - // new stream, save the start block offset - if(startBlock == POIFSConstants.END_OF_CHAIN) { - startBlock = thisBlock; - } - } else { - loopDetector.claim(thisBlock); - nextBlock = blockStore.getNextBlock(thisBlock); - } - - buffer = blockStore.createBlockIfNeeded(thisBlock); - - // Update pointers - prevBlock = thisBlock; - } - - public void write(int b) throws IOException { - oneByte[0] = (byte)(b & 0xFF); - write(oneByte); - } - - public void write(byte[] b, int off, int len) throws IOException { - if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - - do { - createBlockIfNeeded(); - int writeBytes = Math.min(buffer.remaining(), len); - buffer.put(b, off, writeBytes); - off += writeBytes; - len -= writeBytes; - } while (len > 0); - } - - public void close() throws IOException { - // If we're overwriting, free any remaining blocks - NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock); - toFree.free(loopDetector); - - // Mark the end of the stream, if we have any data - if (prevBlock != POIFSConstants.END_OF_CHAIN) { - blockStore.setNextBlock(prevBlock, POIFSConstants.END_OF_CHAIN); - } - } - } -} - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/NotOLE2FileException.java b/trunk/src/java/org/apache/poi/poifs/filesystem/NotOLE2FileException.java deleted file mode 100644 index 18387cfb7..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/NotOLE2FileException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; - -/** - * This exception is thrown when we try to open a file that doesn't - * seem to actually be an OLE2 file after all - */ -public class NotOLE2FileException extends IOException { - public NotOLE2FileException(String s) { - super(s); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java b/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java deleted file mode 100644 index 858e2d9d9..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java +++ /dev/null @@ -1,319 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.IOException; - -import org.apache.poi.poifs.storage.DataInputBlock; - -/** - * This class provides methods to read a DocumentEntry managed by a - * {@link OPOIFSFileSystem} instance. - */ -public final class ODocumentInputStream extends DocumentInputStream { - /** current offset into the Document */ - private int _current_offset; - - /** current marked offset into the Document (used by mark and reset) */ - private int _marked_offset; - - /** the Document's size */ - private int _document_size; - - /** have we been closed? */ - private boolean _closed; - - /** the actual Document */ - private OPOIFSDocument _document; - - /** the data block containing the current stream pointer */ - private DataInputBlock _currentBlock; - - /** - * Create an InputStream from the specified DocumentEntry - * - * @param document the DocumentEntry to be read - * - * @exception IOException if the DocumentEntry cannot be opened (like, maybe it has - * been deleted?) - */ - public ODocumentInputStream(DocumentEntry document) throws IOException { - if (!(document instanceof DocumentNode)) { - throw new IOException("Cannot open internal document storage"); - } - DocumentNode documentNode = (DocumentNode)document; - if (documentNode.getDocument() == null) { - throw new IOException("Cannot open internal document storage"); - } - - _current_offset = 0; - _marked_offset = 0; - _document_size = document.getSize(); - _closed = false; - _document = documentNode.getDocument(); - _currentBlock = getDataInputBlock(0); - } - - /** - * Create an InputStream from the specified Document - * - * @param document the Document to be read - */ - public ODocumentInputStream(OPOIFSDocument document) { - _current_offset = 0; - _marked_offset = 0; - _document_size = document.getSize(); - _closed = false; - _document = document; - _currentBlock = getDataInputBlock(0); - } - - @Override - public int available() { - if (_closed) { - throw new IllegalStateException("cannot perform requested operation on a closed stream"); - } - return _document_size - _current_offset; - } - - @Override - public void close() { - _closed = true; - } - - @Override - public void mark(int ignoredReadlimit) { - _marked_offset = _current_offset; - } - - private DataInputBlock getDataInputBlock(int offset) { - return _document.getDataInputBlock(offset); - } - - @Override - public int read() throws IOException { - dieIfClosed(); - if (atEOD()) { - return EOF; - } - int result = _currentBlock.readUByte(); - _current_offset++; - if (_currentBlock.available() < 1) { - _currentBlock = getDataInputBlock(_current_offset); - } - return result; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - dieIfClosed(); - if (b == null) { - throw new IllegalArgumentException("buffer must not be null"); - } - if (off < 0 || len < 0 || b.length < off + len) { - throw new IndexOutOfBoundsException("can't read past buffer boundaries"); - } - if (len == 0) { - return 0; - } - if (atEOD()) { - return EOF; - } - int limit = Math.min(available(), len); - readFully(b, off, limit); - return limit; - } - - /** - * Repositions this stream to the position at the time the mark() method was - * last called on this input stream. If mark() has not been called this - * method repositions the stream to its beginning. - */ - @Override - public void reset() { - _current_offset = _marked_offset; - _currentBlock = getDataInputBlock(_current_offset); - } - - @Override - public long skip(long n) throws IOException { - dieIfClosed(); - if (n < 0) { - return 0; - } - int new_offset = _current_offset + (int) n; - - if (new_offset < _current_offset) { - - // wrap around in converting a VERY large long to an int - new_offset = _document_size; - } else if (new_offset > _document_size) { - new_offset = _document_size; - } - long rval = new_offset - _current_offset; - - _current_offset = new_offset; - _currentBlock = getDataInputBlock(_current_offset); - return rval; - } - - private void dieIfClosed() throws IOException { - if (_closed) { - throw new IOException("cannot perform requested operation on a closed stream"); - } - } - - private boolean atEOD() { - return _current_offset == _document_size; - } - - private void checkAvaliable(int requestedSize) { - if (_closed) { - throw new IllegalStateException("cannot perform requested operation on a closed stream"); - } - if (requestedSize > _document_size - _current_offset) { - throw new RuntimeException("Buffer underrun - requested " + requestedSize - + " bytes but " + (_document_size - _current_offset) + " was available"); - } - } - - @Override - public byte readByte() { - return (byte) readUByte(); - } - - @Override - public double readDouble() { - return Double.longBitsToDouble(readLong()); - } - - @Override - public short readShort() { - return (short) readUShort(); - } - - @Override - public void readFully(byte[] buf, int off, int len) { - checkAvaliable(len); - int blockAvailable = _currentBlock.available(); - if (blockAvailable > len) { - _currentBlock.readFully(buf, off, len); - _current_offset += len; - return; - } - // else read big amount in chunks - int remaining = len; - int writePos = off; - while (remaining > 0) { - boolean blockIsExpiring = remaining >= blockAvailable; - int reqSize; - if (blockIsExpiring) { - reqSize = blockAvailable; - } else { - reqSize = remaining; - } - _currentBlock.readFully(buf, writePos, reqSize); - remaining -= reqSize; - writePos += reqSize; - _current_offset += reqSize; - if (blockIsExpiring) { - if (_current_offset == _document_size) { - if (remaining > 0) { - throw new IllegalStateException( - "reached end of document stream unexpectedly"); - } - _currentBlock = null; - break; - } - _currentBlock = getDataInputBlock(_current_offset); - blockAvailable = _currentBlock.available(); - } - } - } - - @Override - public long readLong() { - checkAvaliable(SIZE_LONG); - int blockAvailable = _currentBlock.available(); - long result; - if (blockAvailable > SIZE_LONG) { - result = _currentBlock.readLongLE(); - } else { - DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable); - if (blockAvailable == SIZE_LONG) { - result = _currentBlock.readLongLE(); - } else { - result = nextBlock.readLongLE(_currentBlock, blockAvailable); - } - _currentBlock = nextBlock; - } - _current_offset += SIZE_LONG; - return result; - } - - @Override - public int readInt() { - checkAvaliable(SIZE_INT); - int blockAvailable = _currentBlock.available(); - int result; - if (blockAvailable > SIZE_INT) { - result = _currentBlock.readIntLE(); - } else { - DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable); - if (blockAvailable == SIZE_INT) { - result = _currentBlock.readIntLE(); - } else { - result = nextBlock.readIntLE(_currentBlock, blockAvailable); - } - _currentBlock = nextBlock; - } - _current_offset += SIZE_INT; - return result; - } - - @Override - public int readUShort() { - checkAvaliable(SIZE_SHORT); - int blockAvailable = _currentBlock.available(); - int result; - if (blockAvailable > SIZE_SHORT) { - result = _currentBlock.readUShortLE(); - } else { - DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable); - if (blockAvailable == SIZE_SHORT) { - result = _currentBlock.readUShortLE(); - } else { - result = nextBlock.readUShortLE(_currentBlock); - } - _currentBlock = nextBlock; - } - _current_offset += SIZE_SHORT; - return result; - } - - @Override - public int readUByte() { - checkAvaliable(1); - int result = _currentBlock.readUByte(); - _current_offset++; - if (_currentBlock.available() < 1) { - _currentBlock = getDataInputBlock(_current_offset); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java b/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java deleted file mode 100644 index a7479f319..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java +++ /dev/null @@ -1,554 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.poifs.property.DocumentProperty; -import org.apache.poi.poifs.property.Property; -import org.apache.poi.poifs.storage.BlockWritable; -import org.apache.poi.poifs.storage.DataInputBlock; -import org.apache.poi.poifs.storage.DocumentBlock; -import org.apache.poi.poifs.storage.ListManagedBlock; -import org.apache.poi.poifs.storage.RawDataBlock; -import org.apache.poi.poifs.storage.SmallDocumentBlock; -import org.apache.poi.util.HexDump; - -/** - * This class manages a document in a old-style - * OPOIFS filesystem. - */ -public final class OPOIFSDocument implements BATManaged, BlockWritable, POIFSViewable { - private static final DocumentBlock[] EMPTY_BIG_BLOCK_ARRAY = { }; - private static final SmallDocumentBlock[] EMPTY_SMALL_BLOCK_ARRAY = { }; - private DocumentProperty _property; - private int _size; - - private final POIFSBigBlockSize _bigBigBlockSize; - - // one of these stores will be valid - private SmallBlockStore _small_store; - private BigBlockStore _big_store; - - /** - * Constructor from large blocks - * - * @param name the name of the POIFSDocument - * @param blocks the big blocks making up the POIFSDocument - * @param length the actual length of the POIFSDocument - */ - public OPOIFSDocument(String name, RawDataBlock[] blocks, int length) throws IOException { - _size = length; - if(blocks.length == 0) { - _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; - } else { - _bigBigBlockSize = (blocks[0].getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ? - POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS : - POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS - ); - } - - _big_store = new BigBlockStore(_bigBigBlockSize, convertRawBlocksToBigBlocks(blocks)); - _property = new DocumentProperty(name, _size); - _small_store = new SmallBlockStore(_bigBigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); - _property.setDocument(this); - } - - // TODO - awkward typing going on here - private static DocumentBlock[] convertRawBlocksToBigBlocks(ListManagedBlock[] blocks) throws IOException { - DocumentBlock[] result = new DocumentBlock[blocks.length]; - for (int i = 0; i < result.length; i++) { - result[i] = new DocumentBlock((RawDataBlock)blocks[i]); - } - return result; - } - private static SmallDocumentBlock[] convertRawBlocksToSmallBlocks(ListManagedBlock[] blocks) { - if (blocks instanceof SmallDocumentBlock[]) { - return (SmallDocumentBlock[]) blocks; - } - SmallDocumentBlock[] result = new SmallDocumentBlock[blocks.length]; - System.arraycopy(blocks, 0, result, 0, blocks.length); - return result; - } - - /** - * Constructor from small blocks - * - * @param name the name of the POIFSDocument - * @param blocks the small blocks making up the POIFSDocument - * @param length the actual length of the POIFSDocument - */ - public OPOIFSDocument(String name, SmallDocumentBlock[] blocks, int length) { - _size = length; - - if(blocks.length == 0) { - _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; - } else { - _bigBigBlockSize = blocks[0].getBigBlockSize(); - } - - _big_store = new BigBlockStore(_bigBigBlockSize, EMPTY_BIG_BLOCK_ARRAY); - _property = new DocumentProperty(name, _size); - _small_store = new SmallBlockStore(_bigBigBlockSize, blocks); - _property.setDocument(this); - } - - /** - * Constructor from small blocks - * - * @param name the name of the POIFSDocument - * @param blocks the small blocks making up the POIFSDocument - * @param length the actual length of the POIFSDocument - */ - public OPOIFSDocument(String name, POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, int length) throws IOException { - _size = length; - _bigBigBlockSize = bigBlockSize; - _property = new DocumentProperty(name, _size); - _property.setDocument(this); - if (Property.isSmall(_size)) { - _big_store = new BigBlockStore(bigBlockSize,EMPTY_BIG_BLOCK_ARRAY); - _small_store = new SmallBlockStore(bigBlockSize,convertRawBlocksToSmallBlocks(blocks)); - } else { - _big_store = new BigBlockStore(bigBlockSize,convertRawBlocksToBigBlocks(blocks)); - _small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY); - } - } - public OPOIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException { - this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, blocks, length); - } - - /** - * Constructor - * - * @param name the name of the POIFSDocument - * @param stream the InputStream we read data from - */ - public OPOIFSDocument(String name, POIFSBigBlockSize bigBlockSize, InputStream stream) throws IOException { - List blocks = new ArrayList(); - - _size = 0; - _bigBigBlockSize = bigBlockSize; - while (true) { - DocumentBlock block = new DocumentBlock(stream, bigBlockSize); - int blockSize = block.size(); - - if (blockSize > 0) { - blocks.add(block); - _size += blockSize; - } - if (block.partiallyRead()) { - break; - } - } - DocumentBlock[] bigBlocks = blocks.toArray(new DocumentBlock[blocks.size()]); - - _big_store = new BigBlockStore(bigBlockSize,bigBlocks); - _property = new DocumentProperty(name, _size); - _property.setDocument(this); - if (_property.shouldUseSmallBlocks()) { - _small_store = new SmallBlockStore(bigBlockSize,SmallDocumentBlock.convert(bigBlockSize,bigBlocks, _size)); - _big_store = new BigBlockStore(bigBlockSize,new DocumentBlock[0]); - } else { - _small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY); - } - } - public OPOIFSDocument(String name, InputStream stream) throws IOException { - this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, stream); - } - - /** - * Constructor - * - * @param name the name of the POIFSDocument - * @param size the length of the POIFSDocument - * @param path the path of the POIFSDocument - * @param writer the writer who will eventually write the document contents - */ - public OPOIFSDocument(String name, int size, POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, POIFSWriterListener writer) { - _size = size; - _bigBigBlockSize = bigBlockSize; - _property = new DocumentProperty(name, _size); - _property.setDocument(this); - if (_property.shouldUseSmallBlocks()) { - _small_store = new SmallBlockStore(_bigBigBlockSize, path, name, size, writer); - _big_store = new BigBlockStore(_bigBigBlockSize, EMPTY_BIG_BLOCK_ARRAY); - } else { - _small_store = new SmallBlockStore(_bigBigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); - _big_store = new BigBlockStore(_bigBigBlockSize, path, name, size, writer); - } - } - public OPOIFSDocument(String name, int size, POIFSDocumentPath path, POIFSWriterListener writer) { - this(name, size, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, path, writer); - } - - /** - * @return array of SmallDocumentBlocks; may be empty, cannot be null - */ - public SmallDocumentBlock[] getSmallBlocks() { - return _small_store.getBlocks(); - } - - /** - * @return size of the document - */ - public int getSize() { - return _size; - } - - /** - * read data from the internal stores - * - * @param buffer the buffer to write to - * @param offset the offset into our storage to read from - * This method is currently (Oct 2008) only used by test code. Perhaps it can be deleted - */ - void read(byte[] buffer, int offset) { - int len = buffer.length; - - DataInputBlock currentBlock = getDataInputBlock(offset); - - int blockAvailable = currentBlock.available(); - if (blockAvailable > len) { - currentBlock.readFully(buffer, 0, len); - return; - } - // else read big amount in chunks - int remaining = len; - int writePos = 0; - int currentOffset = offset; - while (remaining > 0) { - boolean blockIsExpiring = remaining >= blockAvailable; - int reqSize; - if (blockIsExpiring) { - reqSize = blockAvailable; - } else { - reqSize = remaining; - } - currentBlock.readFully(buffer, writePos, reqSize); - remaining-=reqSize; - writePos+=reqSize; - currentOffset += reqSize; - if (blockIsExpiring) { - if (currentOffset == _size) { - if (remaining > 0) { - throw new IllegalStateException("reached end of document stream unexpectedly"); - } - currentBlock = null; - break; - } - currentBlock = getDataInputBlock(currentOffset); - blockAvailable = currentBlock.available(); - } - } - } - - /** - * @return null if offset points to the end of the document stream - */ - DataInputBlock getDataInputBlock(int offset) { - if (offset >= _size) { - if (offset > _size) { - throw new RuntimeException("Request for Offset " + offset + " doc size is " + _size); - } - return null; - } - if (_property.shouldUseSmallBlocks()) { - return SmallDocumentBlock.getDataInputBlock(_small_store.getBlocks(), offset); - } - return DocumentBlock.getDataInputBlock(_big_store.getBlocks(), offset); - } - - /** - * @return the instance's DocumentProperty - */ - - DocumentProperty getDocumentProperty() { - return _property; - } - - /* ********** START implementation of BlockWritable ********** */ - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should be written - */ - public void writeBlocks(OutputStream stream) throws IOException { - _big_store.writeBlocks(stream); - } - - /* ********** END implementation of BlockWritable ********** */ - /* ********** START implementation of BATManaged ********** */ - - /** - * Return the number of BigBlock's this instance uses - * - * @return count of BigBlock instances - */ - public int countBlocks() { - return _big_store.countBlocks(); - } - - /** - * Set the start block for this instance - * - * @param index index into the array of blocks making up the filesystem - */ - public void setStartBlock(int index) { - _property.setStartBlock(index); - } - - /* ********** END implementation of BATManaged ********** */ - /* ********** START begin implementation of POIFSViewable ********** */ - - /** - * Get an array of objects, some of which may implement POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - public Object[] getViewableArray() { - String result = ""; - - try { - BlockWritable[] blocks = null; - - if (_big_store.isValid()) { - blocks = _big_store.getBlocks(); - } else if (_small_store.isValid()) { - blocks = _small_store.getBlocks(); - } - if (blocks != null) { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - for (BlockWritable bw : blocks) { - bw.writeBlocks(output); - } - int length = Math.min(output.size(), _property.getSize()); - result = HexDump.dump(output.toByteArray(), 0, 0, length); - } - } catch (IOException e) { - result = e.getMessage(); - } - return new String[]{ result }; - } - - /** - * Get an Iterator of objects, some of which may implement POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty back end - * store - */ - public Iterator getViewableIterator() { - return Collections.emptyList().iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, - * false if a viewer should call getViewableIterator - */ - public boolean preferArray() { - return true; - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - public String getShortDescription() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("Document: \"").append(_property.getName()).append("\""); - buffer.append(" size = ").append(getSize()); - return buffer.toString(); - } - - /* ********** END begin implementation of POIFSViewable ********** */ - private static final class SmallBlockStore { - private SmallDocumentBlock[] _smallBlocks; - private final POIFSDocumentPath _path; - private final String _name; - private final int _size; - private final POIFSWriterListener _writer; - private final POIFSBigBlockSize _bigBlockSize; - - /** - * Constructor - * - * @param blocks blocks to construct the store from - */ - SmallBlockStore(POIFSBigBlockSize bigBlockSize, SmallDocumentBlock[] blocks) { - _bigBlockSize = bigBlockSize; - _smallBlocks = blocks.clone(); - this._path = null; - this._name = null; - this._size = -1; - this._writer = null; - } - - /** - * Constructor for a small block store that will be written later - * - * @param path path of the document - * @param name name of the document - * @param size length of the document - * @param writer the object that will eventually write the document - */ - SmallBlockStore(POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, - String name, int size, POIFSWriterListener writer) { - _bigBlockSize = bigBlockSize; - _smallBlocks = new SmallDocumentBlock[0]; - this._path = path; - this._name = name; - this._size = size; - this._writer = writer; - } - - /** - * @return true if this store is a valid source of data - */ - boolean isValid() { - return _smallBlocks.length > 0 || _writer != null; - } - - /** - * @return the SmallDocumentBlocks - */ - SmallDocumentBlock[] getBlocks() { - if (isValid() && _writer != null) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(_size); - DocumentOutputStream dstream = new DocumentOutputStream(stream, _size); - - _writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, _path, _name, _size)); - _smallBlocks = SmallDocumentBlock.convert(_bigBlockSize, stream.toByteArray(), _size); - } - return _smallBlocks; - } - } // end private class SmallBlockStore - - private static final class BigBlockStore { - private DocumentBlock[] bigBlocks; - private final POIFSDocumentPath _path; - private final String _name; - private final int _size; - private final POIFSWriterListener _writer; - private final POIFSBigBlockSize _bigBlockSize; - - /** - * Constructor - * - * @param blocks the blocks making up the store - */ - BigBlockStore(POIFSBigBlockSize bigBlockSize, DocumentBlock[] blocks) { - _bigBlockSize = bigBlockSize; - bigBlocks = blocks.clone(); - _path = null; - _name = null; - _size = -1; - _writer = null; - } - - /** - * Constructor for a big block store that will be written later - * - * @param path path of the document - * @param name name of the document - * @param size length of the document - * @param writer the object that will eventually write the document - */ - BigBlockStore(POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, - String name, int size, POIFSWriterListener writer) { - _bigBlockSize = bigBlockSize; - bigBlocks = new DocumentBlock[0]; - _path = path; - _name = name; - _size = size; - _writer = writer; - } - - /** - * @return true if this store is a valid source of data - */ - boolean isValid() { - return bigBlocks.length > 0 || _writer != null; - } - - /** - * @return the DocumentBlocks - */ - DocumentBlock[] getBlocks() { - if (isValid() && _writer != null) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(_size); - DocumentOutputStream dstream = new DocumentOutputStream(stream, _size); - - _writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, _path, _name, _size)); - bigBlocks = DocumentBlock.convert(_bigBlockSize, stream.toByteArray(), _size); - } - return bigBlocks; - } - - /** - * write the blocks to a stream - * - * @param stream the stream to which the data is to be written - */ - void writeBlocks(OutputStream stream) throws IOException { - if (isValid()) { - if (_writer != null) { - DocumentOutputStream dstream = new DocumentOutputStream(stream, _size); - - _writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, _path, _name, _size)); - dstream.writeFiller(countBlocks() * _bigBlockSize.getBigBlockSize(), - DocumentBlock.getFillByte()); - } else { - for (int k = 0; k < bigBlocks.length; k++) { - bigBlocks[k].writeBlocks(stream); - } - } - } - } - - /** - * @return number of big blocks making up this document - */ - int countBlocks() { - - if (isValid()) { - if (_writer == null) { - return bigBlocks.length; - } - return (_size + _bigBlockSize.getBigBlockSize() - 1) - / _bigBlockSize.getBigBlockSize(); - } - return 0; - } - } // end private class BigBlockStore -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSFileSystem.java b/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSFileSystem.java deleted file mode 100644 index b0afaa333..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSFileSystem.java +++ /dev/null @@ -1,607 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.Property; -import org.apache.poi.poifs.property.PropertyTable; -import org.apache.poi.poifs.storage.BATBlock; -import org.apache.poi.poifs.storage.BlockAllocationTableReader; -import org.apache.poi.poifs.storage.BlockAllocationTableWriter; -import org.apache.poi.poifs.storage.BlockList; -import org.apache.poi.poifs.storage.BlockWritable; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.poifs.storage.HeaderBlockConstants; -import org.apache.poi.poifs.storage.HeaderBlockWriter; -import org.apache.poi.poifs.storage.RawDataBlockList; -import org.apache.poi.poifs.storage.SmallBlockTableReader; -import org.apache.poi.poifs.storage.SmallBlockTableWriter; -import org.apache.poi.util.CloseIgnoringInputStream; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LongField; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - *

    This is the main class of the POIFS system; it manages the entire - * life cycle of the filesystem.

    - *

    This is the older version, which uses more memory, and doesn't - * support in-place writes.

    - */ -public class OPOIFSFileSystem - implements POIFSViewable -{ - private static final POILogger _logger = - POILogFactory.getLogger(OPOIFSFileSystem.class); - - /** - * Convenience method for clients that want to avoid the auto-close behaviour of the constructor. - */ - public static InputStream createNonClosingInputStream(InputStream is) { - return new CloseIgnoringInputStream(is); - } - - private PropertyTable _property_table; - private List _documents; - private DirectoryNode _root; - - /** - * What big block size the file uses. Most files - * use 512 bytes, but a few use 4096 - */ - private POIFSBigBlockSize bigBlockSize = - POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; - - /** - * Constructor, intended for writing - */ - public OPOIFSFileSystem() - { - HeaderBlock header_block = new HeaderBlock(bigBlockSize); - _property_table = new PropertyTable(header_block); - _documents = new ArrayList(); - _root = null; - } - - /** - * Create a OPOIFSFileSystem from an InputStream. Normally the stream is read until - * EOF. The stream is always closed.

    - * - * Some streams are usable after reaching EOF (typically those that return true - * for markSupported()). In the unlikely case that the caller has such a stream - * and needs to use it after this constructor completes, a work around is to wrap the - * stream in order to trap the close() call. A convenience method ( - * createNonClosingInputStream()) has been provided for this purpose: - *

    -     * InputStream wrappedStream = OPOIFSFileSystem.createNonClosingInputStream(is);
    -     * HSSFWorkbook wb = new HSSFWorkbook(wrappedStream);
    -     * is.reset();
    -     * doSomethingElse(is);
    -     * 
    - * Note also the special case of ByteArrayInputStream for which the close() - * method does nothing. - *
    -     * ByteArrayInputStream bais = ...
    -     * HSSFWorkbook wb = new HSSFWorkbook(bais); // calls bais.close() !
    -     * bais.reset(); // no problem
    -     * doSomethingElse(bais);
    -     * 
    - * - * @param stream the InputStream from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - - public OPOIFSFileSystem(InputStream stream) - throws IOException - { - this(); - boolean success = false; - - HeaderBlock header_block; - RawDataBlockList data_blocks; - try { - // read the header block from the stream - header_block = new HeaderBlock(stream); - bigBlockSize = header_block.getBigBlockSize(); - - // read the rest of the stream into blocks - data_blocks = new RawDataBlockList(stream, bigBlockSize); - success = true; - } finally { - closeInputStream(stream, success); - } - - - // set up the block allocation table (necessary for the - // data_blocks to be manageable - new BlockAllocationTableReader(header_block.getBigBlockSize(), - header_block.getBATCount(), - header_block.getBATArray(), - header_block.getXBATCount(), - header_block.getXBATIndex(), - data_blocks); - - // get property table from the document - PropertyTable properties = - new PropertyTable(header_block, data_blocks); - - // init documents - processProperties( - SmallBlockTableReader.getSmallDocumentBlocks( - bigBlockSize, data_blocks, properties.getRoot(), - header_block.getSBATStart() - ), - data_blocks, - properties.getRoot().getChildren(), - null, - header_block.getPropertyStart() - ); - - // For whatever reason CLSID of root is always 0. - getRoot().setStorageClsid(properties.getRoot().getStorageClsid()); - } - /** - * @param stream the stream to be closed - * @param success false if an exception is currently being thrown in the calling method - */ - protected void closeInputStream(InputStream stream, boolean success) { - - if(stream.markSupported() && !(stream instanceof ByteArrayInputStream)) { - String msg = "POIFS is closing the supplied input stream of type (" - + stream.getClass().getName() + ") which supports mark/reset. " - + "This will be a problem for the caller if the stream will still be used. " - + "If that is the case the caller should wrap the input stream to avoid this close logic. " - + "This warning is only temporary and will not be present in future versions of POI."; - _logger.log(POILogger.WARN, msg); - } - try { - stream.close(); - } catch (IOException e) { - if(success) { - throw new RuntimeException(e); - } - // else not success? Try block did not complete normally - // just print stack trace and leave original ex to be thrown - _logger.log(POILogger.ERROR, "can't close input stream", e); - } - } - - /** - * Checks that the supplied InputStream (which MUST - * support mark and reset, or be a PushbackInputStream) - * has a POIFS (OLE2) header at the start of it. - * If your InputStream does not support mark / reset, - * then wrap it in a PushBackInputStream, then be - * sure to always use that, and not the original! - * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream - */ - public static boolean hasPOIFSHeader(InputStream inp) throws IOException { - // We want to peek at the first 8 bytes - byte[] header = IOUtils.peekFirst8Bytes(inp); - return hasPOIFSHeader(header); - } - /** - * Checks if the supplied first 8 bytes of a stream / file - * has a POIFS (OLE2) header. - */ - public static boolean hasPOIFSHeader(byte[] header8Bytes) { - LongField signature = new LongField(HeaderBlockConstants._signature_offset, header8Bytes); - - // Did it match the signature? - return (signature.get() == HeaderBlockConstants._signature); - } - - /** - * Create a new document to be added to the root directory - * - * @param stream the InputStream from which the document's data - * will be obtained - * @param name the name of the new POIFSDocument - * - * @return the new DocumentEntry - * - * @exception IOException on error creating the new POIFSDocument - */ - - public DocumentEntry createDocument(final InputStream stream, - final String name) - throws IOException - { - return getRoot().createDocument(name, stream); - } - - /** - * create a new DocumentEntry in the root entry; the data will be - * provided later - * - * @param name the name of the new DocumentEntry - * @param size the size of the new DocumentEntry - * @param writer the writer of the new DocumentEntry - * - * @return the new DocumentEntry - * - * @exception IOException - */ - - public DocumentEntry createDocument(final String name, final int size, - final POIFSWriterListener writer) - throws IOException - { - return getRoot().createDocument(name, size, writer); - } - - /** - * create a new DirectoryEntry in the root directory - * - * @param name the name of the new DirectoryEntry - * - * @return the new DirectoryEntry - * - * @exception IOException on name duplication - */ - - public DirectoryEntry createDirectory(final String name) - throws IOException - { - return getRoot().createDirectory(name); - } - - /** - * Write the filesystem out - * - * @param stream the OutputStream to which the filesystem will be - * written - * - * @exception IOException thrown on errors writing to the stream - */ - - public void writeFilesystem(final OutputStream stream) - throws IOException - { - - // get the property table ready - _property_table.preWrite(); - - // create the small block store, and the SBAT - SmallBlockTableWriter sbtw = - new SmallBlockTableWriter(bigBlockSize, _documents, _property_table.getRoot()); - - // create the block allocation table - BlockAllocationTableWriter bat = - new BlockAllocationTableWriter(bigBlockSize); - - // create a list of BATManaged objects: the documents plus the - // property table and the small block table - List bm_objects = new ArrayList(); - - bm_objects.addAll(_documents); - bm_objects.add(_property_table); - bm_objects.add(sbtw); - bm_objects.add(sbtw.getSBAT()); - - // walk the list, allocating space for each and assigning each - // a starting block number - Iterator iter = bm_objects.iterator(); - - while (iter.hasNext()) - { - BATManaged bmo = ( BATManaged ) iter.next(); - int block_count = bmo.countBlocks(); - - if (block_count != 0) - { - bmo.setStartBlock(bat.allocateSpace(block_count)); - } - else - { - - // Either the BATManaged object is empty or its data - // is composed of SmallBlocks; in either case, - // allocating space in the BAT is inappropriate - } - } - - // allocate space for the block allocation table and take its - // starting block - int batStartBlock = bat.createBlocks(); - - // get the extended block allocation table blocks - HeaderBlockWriter header_block_writer = new HeaderBlockWriter(bigBlockSize); - BATBlock[] xbat_blocks = - header_block_writer.setBATBlocks(bat.countBlocks(), - batStartBlock); - - // set the property table start block - header_block_writer.setPropertyStart(_property_table.getStartBlock()); - - // set the small block allocation table start block - header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock()); - - // set the small block allocation table block count - header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount()); - - // the header is now properly initialized. Make a list of - // writers (the header block, followed by the documents, the - // property table, the small block store, the small block - // allocation table, the block allocation table, and the - // extended block allocation table blocks) - List writers = new ArrayList(); - - writers.add(header_block_writer); - writers.addAll(_documents); - writers.add(_property_table); - writers.add(sbtw); - writers.add(sbtw.getSBAT()); - writers.add(bat); - for (int j = 0; j < xbat_blocks.length; j++) - { - writers.add(xbat_blocks[ j ]); - } - - // now, write everything out - iter = writers.iterator(); - while (iter.hasNext()) - { - BlockWritable writer = ( BlockWritable ) iter.next(); - - writer.writeBlocks(stream); - } - } - - /** - * read in a file and write it back out again - * - * @param args names of the files; arg[ 0 ] is the input file, - * arg[ 1 ] is the output file - * - * @exception IOException - */ - - public static void main(String args[]) - throws IOException - { - if (args.length != 2) - { - System.err.println( - "two arguments required: input filename and output filename"); - System.exit(1); - } - FileInputStream istream = new FileInputStream(args[ 0 ]); - FileOutputStream ostream = new FileOutputStream(args[ 1 ]); - - new OPOIFSFileSystem(istream).writeFilesystem(ostream); - istream.close(); - ostream.close(); - } - - /** - * get the root entry - * - * @return the root entry - */ - - public DirectoryNode getRoot() - { - if (_root == null) - { - _root = new DirectoryNode(_property_table.getRoot(), this, null); - } - return _root; - } - - /** - * open a document in the root entry's list of entries - * - * @param documentName the name of the document to be opened - * - * @return a newly opened DocumentInputStream - * - * @exception IOException if the document does not exist or the - * name is that of a DirectoryEntry - */ - - public DocumentInputStream createDocumentInputStream( - final String documentName) - throws IOException - { - return getRoot().createDocumentInputStream(documentName); - } - - /** - * add a new POIFSDocument - * - * @param document the POIFSDocument being added - */ - - void addDocument(final OPOIFSDocument document) - { - _documents.add(document); - _property_table.addProperty(document.getDocumentProperty()); - } - - /** - * add a new DirectoryProperty - * - * @param directory the DirectoryProperty being added - */ - - void addDirectory(final DirectoryProperty directory) - { - _property_table.addProperty(directory); - } - - /** - * remove an entry - * - * @param entry to be removed - */ - - void remove(EntryNode entry) - { - _property_table.removeProperty(entry.getProperty()); - if (entry.isDocumentEntry()) - { - _documents.remove((( DocumentNode ) entry).getDocument()); - } - } - - private void processProperties(final BlockList small_blocks, - final BlockList big_blocks, - final Iterator properties, - final DirectoryNode dir, - final int headerPropertiesStartAt) - throws IOException - { - while (properties.hasNext()) - { - Property property = properties.next(); - String name = property.getName(); - DirectoryNode parent = (dir == null) - ? (( DirectoryNode ) getRoot()) - : dir; - - if (property.isDirectory()) - { - DirectoryNode new_dir = - ( DirectoryNode ) parent.createDirectory(name); - - new_dir.setStorageClsid( property.getStorageClsid() ); - - processProperties( - small_blocks, big_blocks, - (( DirectoryProperty ) property).getChildren(), - new_dir, headerPropertiesStartAt); - } - else - { - int startBlock = property.getStartBlock(); - int size = property.getSize(); - OPOIFSDocument document = null; - - if (property.shouldUseSmallBlocks()) - { - document = - new OPOIFSDocument(name, - small_blocks.fetchBlocks(startBlock, headerPropertiesStartAt), - size); - } - else - { - document = - new OPOIFSDocument(name, - big_blocks.fetchBlocks(startBlock, headerPropertiesStartAt), - size); - } - parent.createDocument(document); - } - } - } - - /* ********** START begin implementation of POIFSViewable ********** */ - - /** - * Get an array of objects, some of which may implement - * POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - - public Object [] getViewableArray() - { - if (preferArray()) - { - return (( POIFSViewable ) getRoot()).getViewableArray(); - } - return new Object[ 0 ]; - } - - /** - * Get an Iterator of objects, some of which may implement - * POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty - * back end store - */ - - public Iterator getViewableIterator() - { - if (!preferArray()) - { - return (( POIFSViewable ) getRoot()).getViewableIterator(); - } - return Collections.emptyList().iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, false if - * a viewer should call getViewableIterator - */ - - public boolean preferArray() - { - return (( POIFSViewable ) getRoot()).preferArray(); - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - - public String getShortDescription() - { - return "POIFS FileSystem"; - } - - /** - * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes - */ - public int getBigBlockSize() { - return bigBlockSize.getBigBlockSize(); - } - /** - * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes - */ - public POIFSBigBlockSize getBigBlockSizeDetails() { - return bigBlockSize; - } - - /* ********** END begin implementation of POIFSViewable ********** */ -} // end public class OPOIFSFileSystem - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java b/trunk/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java deleted file mode 100644 index ac2404b72..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import org.apache.poi.UnsupportedFileFormatException; - -/** - * This exception is thrown when we try to open a file that's actually - * an Office 2007+ XML file, rather than an OLE2 file (which is what - * POIFS works with) - */ -public class OfficeXmlFileException extends UnsupportedFileFormatException { - public OfficeXmlFileException(String s) { - super(s); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java b/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java deleted file mode 100644 index d11841dd5..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java +++ /dev/null @@ -1,401 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.LittleEndianOutputStream; -import org.apache.poi.util.StringUtil; - -/** - * Represents an Ole10Native record which is wrapped around certain binary - * files being embedded in OLE2 documents. - * - * @author Rainer Schwarze - */ -public class Ole10Native { - - public static final String OLE10_NATIVE = "\u0001Ole10Native"; - protected static final String ISO1 = "ISO-8859-1"; - - // (the fields as they appear in the raw record:) - private int totalSize; // 4 bytes, total size of record not including this field - private short flags1 = 2; // 2 bytes, unknown, mostly [02 00] - private String label; // ASCIIZ, stored in this field without the terminating zero - private String fileName; // ASCIIZ, stored in this field without the terminating zero - private short flags2 = 0; // 2 bytes, unknown, mostly [00 00] - private short unknown1 = 3; // see below - private String command; // ASCIIZ, stored in this field without the terminating zero - private byte[] dataBuffer; // varying size, the actual native data - private short flags3 = 0; // some final flags? or zero terminators?, sometimes not there - - /** - * the field encoding mode - merely a try-and-error guess ... - **/ - private enum EncodingMode { - /** - * the data is stored in parsed format - including label, command, etc. - */ - parsed, - /** - * the data is stored raw after the length field - */ - unparsed, - /** - * the data is stored raw after the length field and the flags1 field - */ - compact - } - - private EncodingMode mode; - - - - /** - * Creates an instance of this class from an embedded OLE Object. The OLE Object is expected - * to include a stream "{01}Ole10Native" which contains the actual - * data relevant for this class. - * - * @param poifs POI Filesystem object - * @return Returns an instance of this class - * @throws IOException on IO error - * @throws Ole10NativeException on invalid or unexcepted data format - */ - public static Ole10Native createFromEmbeddedOleObject(POIFSFileSystem poifs) throws IOException, Ole10NativeException { - return createFromEmbeddedOleObject(poifs.getRoot()); - } - - /** - * Creates an instance of this class from an embedded OLE Object. The OLE Object is expected - * to include a stream "{01}Ole10Native" which contains the actual - * data relevant for this class. - * - * @param directory POI Filesystem object - * @return Returns an instance of this class - * @throws IOException on IO error - * @throws Ole10NativeException on invalid or unexcepted data format - */ - public static Ole10Native createFromEmbeddedOleObject(DirectoryNode directory) throws IOException, Ole10NativeException { - DocumentEntry nativeEntry = - (DocumentEntry)directory.getEntry(OLE10_NATIVE); - byte[] data = new byte[nativeEntry.getSize()]; - int readBytes = directory.createDocumentInputStream(nativeEntry).read(data); - assert(readBytes == data.length); - - return new Ole10Native(data, 0); - } - - /** - * Creates an instance and fills the fields based on ... the fields - */ - public Ole10Native(String label, String filename, String command, byte[] data) { - setLabel(label); - setFileName(filename); - setCommand(command); - setDataBuffer(data); - mode = EncodingMode.parsed; - } - - /** - * Creates an instance and fills the fields based on the data in the given buffer. - * - * @param data The buffer containing the Ole10Native record - * @param offset The start offset of the record in the buffer - * @throws Ole10NativeException on invalid or unexcepted data format - */ - public Ole10Native(byte[] data, int offset) throws Ole10NativeException { - int ofs = offset; // current offset, initialized to start - - if (data.length < offset + 2) { - throw new Ole10NativeException("data is too small"); - } - - totalSize = LittleEndian.getInt(data, ofs); - ofs += LittleEndianConsts.INT_SIZE; - - mode = EncodingMode.unparsed; - if (LittleEndian.getShort(data, ofs) == 2) { - // some files like equations don't have a valid filename, - // but somehow encode the formula right away in the ole10 header - if (Character.isISOControl(data[ofs+LittleEndianConsts.SHORT_SIZE])) { - mode = EncodingMode.compact; - } else { - mode = EncodingMode.parsed; - } - } - - int dataSize; - switch (mode) { - case parsed: { - flags1 = LittleEndian.getShort(data, ofs); - - // structured format - ofs += LittleEndianConsts.SHORT_SIZE; - - int len = getStringLength(data, ofs); - label = StringUtil.getFromCompressedUnicode(data, ofs, len - 1); - ofs += len; - - len = getStringLength(data, ofs); - fileName = StringUtil.getFromCompressedUnicode(data, ofs, len - 1); - ofs += len; - - flags2 = LittleEndian.getShort(data, ofs); - ofs += LittleEndianConsts.SHORT_SIZE; - - unknown1 = LittleEndian.getShort(data, ofs); - ofs += LittleEndianConsts.SHORT_SIZE; - - len = LittleEndian.getInt(data, ofs); - ofs += LittleEndianConsts.INT_SIZE; - command = StringUtil.getFromCompressedUnicode(data, ofs, len - 1); - ofs += len; - - if (totalSize < ofs) { - throw new Ole10NativeException("Invalid Ole10Native"); - } - - dataSize = LittleEndian.getInt(data, ofs); - ofs += LittleEndianConsts.INT_SIZE; - - if (dataSize < 0 || totalSize - (ofs - LittleEndianConsts.INT_SIZE) < dataSize) { - throw new Ole10NativeException("Invalid Ole10Native"); - } - break; - } - case compact: - flags1 = LittleEndian.getShort(data, ofs); - ofs += LittleEndianConsts.SHORT_SIZE; - dataSize = totalSize - LittleEndianConsts.SHORT_SIZE; - break; - default: - case unparsed: - dataSize = totalSize; - break; - } - - if ((long)dataSize + (long)ofs > (long)data.length) { //cast to avoid overflow - throw new Ole10NativeException("Invalid Ole10Native: declared data length > available data"); - } - dataBuffer = new byte[dataSize]; - System.arraycopy(data, ofs, dataBuffer, 0, dataSize); - ofs += dataSize; - } - - /* - * Helper - determine length of zero terminated string (ASCIIZ). - */ - private static int getStringLength(byte[] data, int ofs) { - int len = 0; - while (len + ofs < data.length && data[ofs + len] != 0) { - len++; - } - len++; - return len; - } - - /** - * Returns the value of the totalSize field - the total length of the - * structure is totalSize + 4 (value of this field + size of this field). - * - * @return the totalSize - */ - public int getTotalSize() { - return totalSize; - } - - /** - * Returns flags1 - currently unknown - usually 0x0002. - * - * @return the flags1 - */ - public short getFlags1() { - return flags1; - } - - /** - * Returns the label field - usually the name of the file (without - * directory) but probably may be any name specified during - * packaging/embedding the data. - * - * @return the label - */ - public String getLabel() { - return label; - } - - /** - * Returns the fileName field - usually the name of the file being embedded - * including the full path. - * - * @return the fileName - */ - public String getFileName() { - return fileName; - } - - /** - * Returns flags2 - currently unknown - mostly 0x0000. - * - * @return the flags2 - */ - public short getFlags2() { - return flags2; - } - - /** - * Returns unknown1 field - currently unknown. - * - * @return the unknown1 - */ - public short getUnknown1() { - return unknown1; - } - - /** - * Returns the command field - usually the name of the file being embedded - * including the full path, may be a command specified during embedding the - * file. - * - * @return the command - */ - public String getCommand() { - return command; - } - - /** - * Returns the size of the embedded file. If the size is 0 (zero), no data - * has been embedded. To be sure, that no data has been embedded, check - * whether {@link #getDataBuffer()} returns null. - * - * @return the dataSize - */ - public int getDataSize() { - return dataBuffer.length; - } - - /** - * Returns the buffer containing the embedded file's data, or - * null if no data was embedded. Note that an embedding may - * provide information about the data, but the actual data is not included. - * (So label, filename etc. are available, but this method returns - * null.) - * - * @return the dataBuffer - */ - public byte[] getDataBuffer() { - return dataBuffer; - } - - /** - * Returns the flags3 - currently unknown. - * - * @return the flags3 - */ - public short getFlags3() { - return flags3; - } - - /** - * Have the contents printer out into an OutputStream, used when writing a - * file back out to disk (Normally, atom classes will keep their bytes - * around, but non atom classes will just request the bytes from their - * children, then chuck on their header and return) - */ - public void writeOut(OutputStream out) throws IOException { - // byte intbuf[] = new byte[LittleEndianConsts.INT_SIZE]; - // byte shortbuf[] = new byte[LittleEndianConsts.SHORT_SIZE]; - - @SuppressWarnings("resource") - LittleEndianOutputStream leosOut = new LittleEndianOutputStream(out); - - switch (mode) { - case parsed: { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - LittleEndianOutputStream leos = new LittleEndianOutputStream(bos); - // total size, will be determined later .. - - leos.writeShort(getFlags1()); - leos.write(getLabel().getBytes(ISO1)); - leos.write(0); - leos.write(getFileName().getBytes(ISO1)); - leos.write(0); - leos.writeShort(getFlags2()); - leos.writeShort(getUnknown1()); - leos.writeInt(getCommand().length() + 1); - leos.write(getCommand().getBytes(ISO1)); - leos.write(0); - leos.writeInt(getDataSize()); - leos.write(getDataBuffer()); - leos.writeShort(getFlags3()); - leos.close(); // satisfy compiler ... - - leosOut.writeInt(bos.size()); // total size - bos.writeTo(out); - break; - } - case compact: - leosOut.writeInt(getDataSize()+LittleEndianConsts.SHORT_SIZE); - leosOut.writeShort(getFlags1()); - out.write(getDataBuffer()); - break; - default: - case unparsed: - leosOut.writeInt(getDataSize()); - out.write(getDataBuffer()); - break; - } - - } - - public void setFlags1(short flags1) { - this.flags1 = flags1; - } - - public void setFlags2(short flags2) { - this.flags2 = flags2; - } - - public void setFlags3(short flags3) { - this.flags3 = flags3; - } - - public void setLabel(String label) { - this.label = label; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - - public void setCommand(String command) { - this.command = command; - } - - public void setUnknown1(short unknown1) { - this.unknown1 = unknown1; - } - - public void setDataBuffer(byte dataBuffer[]) { - this.dataBuffer = dataBuffer.clone(); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java b/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java deleted file mode 100644 index a186990ca..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.filesystem; - -public class Ole10NativeException extends Exception { - public Ole10NativeException(String message) { - super(message); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java b/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java deleted file mode 100644 index 5b6441cdc..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java +++ /dev/null @@ -1,307 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.File; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Class POIFSDocumentPath - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -public class POIFSDocumentPath -{ - private static final POILogger log = POILogFactory.getLogger(POIFSDocumentPath.class); - - private final String[] components; - private int hashcode = 0; //lazy-compute hashCode - - /** - * constructor for the path of a document that is not in the root - * of the POIFSFileSystem - * - * @param components the Strings making up the path to a document. - * The Strings must be ordered as they appear in - * the directory hierarchy of the the document - * -- the first string must be the name of a - * directory in the root of the POIFSFileSystem, - * and every Nth (for N > 1) string thereafter - * must be the name of a directory in the - * directory identified by the (N-1)th string. - *

    - * If the components parameter is null or has - * zero length, the POIFSDocumentPath is - * appropriate for a document that is in the - * root of a POIFSFileSystem - * - * @exception IllegalArgumentException if any of the elements in - * the components parameter - * are null or have zero - * length - */ - - public POIFSDocumentPath(final String [] components) - throws IllegalArgumentException - { - if (components == null) - { - this.components = new String[ 0 ]; - } - else - { - this.components = new String[ components.length ]; - for (int j = 0; j < components.length; j++) - { - if ((components[ j ] == null) - || (components[ j ].length() == 0)) - { - throw new IllegalArgumentException( - "components cannot contain null or empty strings"); - } - this.components[ j ] = components[ j ]; - } - } - } - - /** - * simple constructor for the path of a document that is in the - * root of the POIFSFileSystem. The constructor that takes an - * array of Strings can also be used to create such a - * POIFSDocumentPath by passing it a null or empty String array - */ - - public POIFSDocumentPath() - { - this.components = new String[ 0 ]; - } - - /** - * constructor that adds additional subdirectories to an existing - * path - * - * @param path the existing path - * @param components the additional subdirectory names to be added - * - * @exception IllegalArgumentException if any of the Strings in - * components is null or zero - * length - */ - - public POIFSDocumentPath(final POIFSDocumentPath path, - final String [] components) - throws IllegalArgumentException - { - if (components == null) - { - this.components = new String[ path.components.length ]; - } - else - { - this.components = - new String[ path.components.length + components.length ]; - } - for (int j = 0; j < path.components.length; j++) - { - this.components[ j ] = path.components[ j ]; - } - if (components != null) - { - for (int j = 0; j < components.length; j++) - { - if (components[ j ] == null) - { - throw new IllegalArgumentException( - "components cannot contain null"); - } - if (components[ j ].length() == 0) - { - log.log(POILogger.WARN, "Directory under " + path + " has an empty name, " + - "not all OLE2 readers will handle this file correctly!"); - } - - this.components[ j + path.components.length ] = - components[ j ]; - } - } - } - - /** - * equality. Two POIFSDocumentPath instances are equal if they - * have the same number of component Strings, and if each - * component String is equal to its coresponding component String - * - * @param o the object we're checking equality for - * - * @return true if the object is equal to this object - */ - - public boolean equals(final Object o) - { - boolean rval = false; - - if ((o != null) && (o.getClass() == this.getClass())) - { - if (this == o) - { - rval = true; - } - else - { - POIFSDocumentPath path = ( POIFSDocumentPath ) o; - - if (path.components.length == this.components.length) - { - rval = true; - for (int j = 0; j < this.components.length; j++) - { - if (!path.components[ j ] - .equals(this.components[ j ])) - { - rval = false; - break; - } - } - } - } - } - return rval; - } - - /** - * calculate and return the hashcode - * - * @return hashcode - */ - - public int hashCode() - { - if (hashcode == 0) - { - hashcode = computeHashCode(); - } - return hashcode; - } - - private int computeHashCode() { - int code = 0; - for (int j = 0; j < components.length; j++) - { - code += components[ j ].hashCode(); - } - return code; - } - - /** - * @return the number of components - */ - - public int length() - { - return components.length; - } - - /** - * get the specified component - * - * @param n which component (0 ... length() - 1) - * - * @return the nth component; - * - * @exception ArrayIndexOutOfBoundsException if n < 0 or n >= - * length() - */ - - public String getComponent(int n) - throws ArrayIndexOutOfBoundsException - { - return components[ n ]; - } - - /** - *

    Returns the path's parent or null if this path - * is the root path.

    - * - * @since 2002-01-24 - * @return path of parent, or null if this path is the root path - */ - - public POIFSDocumentPath getParent() - { - final int length = components.length - 1; - - if (length < 0) - { - return null; - } - String[] parentComponents = new String[ length ]; - System.arraycopy(components, 0, parentComponents, 0, length); - POIFSDocumentPath parent = new POIFSDocumentPath(parentComponents); - - return parent; - } - - /** - *

    Returns the last name in the document path's name sequence. - * If the document path's name sequence is empty, then the empty string is returned.

    - * - * @since 2016-04-09 - * @return The last name in the document path's name sequence, or empty string if this is the root path - */ - - public String getName() - { - if (components.length == 0) { - return ""; - } - return components[components.length - 1]; - } - - /** - *

    Returns a string representation of the path. Components are - * separated by the platform-specific file separator {@link File#separatorChar}

    - * - * @return string representation - * - * @since 2002-01-24 - */ - - public String toString() - { - final StringBuffer b = new StringBuffer(); - final int l = length(); - - b.append(File.separatorChar); - for (int i = 0; i < l; i++) - { - b.append(getComponent(i)); - if (i < l - 1) - { - b.append(File.separatorChar); - } - } - return b.toString(); - } -} // end public class POIFSDocumentPath - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java b/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java deleted file mode 100644 index cc482536b..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java +++ /dev/null @@ -1,179 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.util.CloseIgnoringInputStream; - -/** - * Transition class for the move from {@link POIFSFileSystem} to - * {@link OPOIFSFileSystem}, and from {@link NPOIFSFileSystem} to - * {@link POIFSFileSystem}. Currently, this is OPOIFS-powered - */ - -public class POIFSFileSystem - extends NPOIFSFileSystem // TODO Temporary workaround during #56791 - implements POIFSViewable -{ - /** - * Convenience method for clients that want to avoid the auto-close behaviour of the constructor. - */ - public static InputStream createNonClosingInputStream(InputStream is) { - return new CloseIgnoringInputStream(is); - } - - /** - * Constructor, intended for writing - */ - public POIFSFileSystem() - { - super(); - } - - /** - * Create a POIFSFileSystem from an InputStream. Normally the stream is read until - * EOF. The stream is always closed.

    - * - * Some streams are usable after reaching EOF (typically those that return true - * for markSupported()). In the unlikely case that the caller has such a stream - * and needs to use it after this constructor completes, a work around is to wrap the - * stream in order to trap the close() call. A convenience method ( - * createNonClosingInputStream()) has been provided for this purpose: - *

    -     * InputStream wrappedStream = POIFSFileSystem.createNonClosingInputStream(is);
    -     * HSSFWorkbook wb = new HSSFWorkbook(wrappedStream);
    -     * is.reset();
    -     * doSomethingElse(is);
    -     * 
    - * Note also the special case of ByteArrayInputStream for which the close() - * method does nothing. - *
    -     * ByteArrayInputStream bais = ...
    -     * HSSFWorkbook wb = new HSSFWorkbook(bais); // calls bais.close() !
    -     * bais.reset(); // no problem
    -     * doSomethingElse(bais);
    -     * 
    - * - * @param stream the InputStream from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - - public POIFSFileSystem(InputStream stream) - throws IOException - { - super(stream); - } - - /** - *

    Creates a POIFSFileSystem from a File. This uses less memory than - * creating from an InputStream.

    - * - *

    Note that with this constructor, you will need to call {@link #close()} - * when you're done to have the underlying file closed, as the file is - * kept open during normal operation to read the data out.

    - * @param readOnly whether the POIFileSystem will only be used in read-only mode - * - * @param file the File from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - public POIFSFileSystem(File file, boolean readOnly) throws IOException { - super(file, readOnly); - } - - /** - *

    Creates a POIFSFileSystem from a File. This uses less memory than - * creating from an InputStream. The File will be opened read-only

    - * - *

    Note that with this constructor, you will need to call {@link #close()} - * when you're done to have the underlying file closed, as the file is - * kept open during normal operation to read the data out.

    - * - * @param file the File from which to read the data - * - * @exception IOException on errors reading, or on invalid data - */ - public POIFSFileSystem(File file) throws IOException { - super(file); - } - - /** - * Checks that the supplied InputStream (which MUST - * support mark and reset, or be a PushbackInputStream) - * has a POIFS (OLE2) header at the start of it. - * If your InputStream does not support mark / reset, - * then wrap it in a PushBackInputStream, then be - * sure to always use that, and not the original! - * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream - */ - public static boolean hasPOIFSHeader(InputStream inp) throws IOException { - return NPOIFSFileSystem.hasPOIFSHeader(inp); - } - /** - * Checks if the supplied first 8 bytes of a stream / file - * has a POIFS (OLE2) header. - */ - public static boolean hasPOIFSHeader(byte[] header8Bytes) { - return NPOIFSFileSystem.hasPOIFSHeader(header8Bytes); - } - - /** - * Creates a new {@link POIFSFileSystem} in a new {@link File}. - * Use {@link #POIFSFileSystem(File)} to open an existing File, - * this should only be used to create a new empty filesystem. - * - * @param file The file to create and open - * @return The created and opened {@link POIFSFileSystem} - */ - public static POIFSFileSystem create(File file) throws IOException { - // TODO Make this nicer! - // Create a new empty POIFS in the file - POIFSFileSystem tmp = new POIFSFileSystem(); - FileOutputStream fout = new FileOutputStream(file); - tmp.writeFilesystem(fout); - fout.close(); - tmp.close(); - - // Open it up again backed by the file - return new POIFSFileSystem(file, false); - } - - /** - * read in a file and write it back out again - * - * @param args names of the files; arg[ 0 ] is the input file, - * arg[ 1 ] is the output file - * - * @exception IOException - */ - - public static void main(String args[]) - throws IOException - { - OPOIFSFileSystem.main(args); - } -} - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSWriterEvent.java b/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSWriterEvent.java deleted file mode 100644 index a3954c372..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSWriterEvent.java +++ /dev/null @@ -1,92 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -/** - * Class POIFSWriterEvent - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -public class POIFSWriterEvent -{ - private DocumentOutputStream stream; - private POIFSDocumentPath path; - private String documentName; - private int limit; - - /** - * package scoped constructor - * - * @param stream the DocumentOutputStream, freshly opened - * @param path the path of the document - * @param documentName the name of the document - * @param limit the limit, in bytes, that can be written to the - * stream - */ - - POIFSWriterEvent(final DocumentOutputStream stream, - final POIFSDocumentPath path, final String documentName, - final int limit) - { - this.stream = stream; - this.path = path; - this.documentName = documentName; - this.limit = limit; - } - - /** - * @return the DocumentOutputStream, freshly opened - */ - - public DocumentOutputStream getStream() - { - return stream; - } - - /** - * @return the document's path - */ - - public POIFSDocumentPath getPath() - { - return path; - } - - /** - * @return the document's name - */ - - public String getName() - { - return documentName; - } - - /** - * @return the limit on writing, in bytes - */ - - public int getLimit() - { - return limit; - } -} // end public class POIFSWriterEvent - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSWriterListener.java b/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSWriterListener.java deleted file mode 100644 index 9f9e396a1..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSWriterListener.java +++ /dev/null @@ -1,41 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.filesystem; - -/** - * Interface POIFSWriterListener - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% - */ - -public interface POIFSWriterListener -{ - - /** - * Process a POIFSWriterEvent that this listener had registered - * for - * - * @param event the POIFSWriterEvent - */ - - public void processPOIFSWriterEvent(POIFSWriterEvent event); -} // end public interface POIFSWriterListener - diff --git a/trunk/src/java/org/apache/poi/poifs/filesystem/package.html b/trunk/src/java/org/apache/poi/poifs/filesystem/package.html deleted file mode 100644 index d673ed593..000000000 --- a/trunk/src/java/org/apache/poi/poifs/filesystem/package.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - -filesystem package maps OLE 2 Compound document files to a more familiar filesystem interface. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.poifs.eventfilesystem - - diff --git a/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroExtractor.java b/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroExtractor.java deleted file mode 100644 index c5c84aff9..000000000 --- a/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroExtractor.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.macros; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.poi.util.StringUtil; - -/** - * This tool extracts out the source of all VBA Modules of an office file, - * both OOXML (eg XLSM) and OLE2/POIFS (eg DOC), to STDOUT or a directory. - * - * @since 3.15-beta2 - */ -public class VBAMacroExtractor { - public static void main(String args[]) throws IOException { - if (args.length == 0) { - System.err.println("Use:"); - System.err.println(" VBAMacroExtractor [output]"); - System.err.println(""); - System.err.println("If an output directory is given, macros are written there"); - System.err.println("Otherwise they are output to the screen"); - System.exit(1); - } - - File input = new File(args[0]); - File output = null; - if (args.length > 1) { - output = new File(args[1]); - } - - VBAMacroExtractor extractor = new VBAMacroExtractor(); - extractor.extract(input, output); - } - - /** - * Extracts the VBA modules from a macro-enabled office file and writes them - * to files in outputDir. - * - * Creates the outputDir, directory, including any necessary but - * nonexistent parent directories, if outputDir does not exist. - * If outputDir is null, writes the contents to standard out instead. - * - * @param input the macro-enabled office file. - * @param outputDir the directory to write the extracted VBA modules to. - * @param extension file extension of the extracted VBA modules - * @since 3.15-beta2 - */ - public void extract(File input, File outputDir, String extension) throws IOException { - if (! input.exists()) throw new FileNotFoundException(input.toString()); - System.err.print("Extracting VBA Macros from " + input + " to "); - if (outputDir != null) { - if (!outputDir.exists() && !outputDir.mkdirs()) { - throw new IOException("Output directory " + outputDir + " could not be created"); - } - System.err.println(outputDir); - } else { - System.err.println("STDOUT"); - } - - VBAMacroReader reader = new VBAMacroReader(input); - Map macros = reader.readMacros(); - reader.close(); - - final String divider = "---------------------------------------"; - for (Entry entry : macros.entrySet()) { - String moduleName = entry.getKey(); - String moduleCode = entry.getValue(); - if (outputDir == null) { - System.out.println(divider); - System.out.println(moduleName); - System.out.println(""); - System.out.println(moduleCode); - } else { - File out = new File(outputDir, moduleName + extension); - FileOutputStream fout = new FileOutputStream(out); - OutputStreamWriter fwriter = new OutputStreamWriter(fout, StringUtil.UTF8); - fwriter.write(moduleCode); - fwriter.close(); - fout.close(); - System.out.println("Extracted " + out); - } - } - if (outputDir == null) { - System.out.println(divider); - } - } - - /** - * Extracts the VBA modules from a macro-enabled office file and writes them - * to .vba files in outputDir. - * - * Creates the outputDir, directory, including any necessary but - * nonexistent parent directories, if outputDir does not exist. - * If outputDir is null, writes the contents to standard out instead. - * - * @param input the macro-enabled office file. - * @param outputDir the directory to write the extracted VBA modules to. - * @since 3.15-beta2 - */ - public void extract(File input, File outputDir) throws IOException { - extract(input, outputDir, ".vba"); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java b/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java deleted file mode 100644 index 83eb7295c..000000000 --- a/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java +++ /dev/null @@ -1,369 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.macros; - -import static org.apache.poi.util.StringUtil.startsWithIgnoreCase; -import static org.apache.poi.util.StringUtil.endsWithIgnoreCase; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OfficeXmlFileException; -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.RLEDecompressingInputStream; - -/** - *

    Finds all VBA Macros in an office file (OLE2/POIFS and OOXML/OPC), - * and returns them. - *

    - *

    - * NOTE: This does not read macros from .ppt files. - * See org.apache.poi.hslf.usermodel.TestBugs.getMacrosFromHSLF() in the scratchpad - * module for an example of how to do this. Patches that make macro - * extraction from .ppt more elegant are welcomed! - *

    - * - * @since 3.15-beta2 - */ -public class VBAMacroReader implements Closeable { - protected static final String VBA_PROJECT_OOXML = "vbaProject.bin"; - protected static final String VBA_PROJECT_POIFS = "VBA"; - // FIXME: When minimum supported version is Java 7, replace with java.nio.charset.StandardCharsets.UTF_16LE - private static final Charset UTF_16LE = Charset.forName("UTF-16LE"); - - private NPOIFSFileSystem fs; - - public VBAMacroReader(InputStream rstream) throws IOException { - PushbackInputStream stream = new PushbackInputStream(rstream, 8); - byte[] header8 = IOUtils.peekFirst8Bytes(stream); - - if (NPOIFSFileSystem.hasPOIFSHeader(header8)) { - fs = new NPOIFSFileSystem(stream); - } else { - openOOXML(stream); - } - } - - public VBAMacroReader(File file) throws IOException { - try { - this.fs = new NPOIFSFileSystem(file); - } catch (OfficeXmlFileException e) { - openOOXML(new FileInputStream(file)); - } - } - public VBAMacroReader(NPOIFSFileSystem fs) { - this.fs = fs; - } - - private void openOOXML(InputStream zipFile) throws IOException { - ZipInputStream zis = new ZipInputStream(zipFile); - ZipEntry zipEntry; - while ((zipEntry = zis.getNextEntry()) != null) { - if (endsWithIgnoreCase(zipEntry.getName(), VBA_PROJECT_OOXML)) { - try { - // Make a NPOIFS from the contents, and close the stream - this.fs = new NPOIFSFileSystem(zis); - return; - } catch (IOException e) { - // Tidy up - zis.close(); - - // Pass on - throw e; - } - } - } - zis.close(); - throw new IllegalArgumentException("No VBA project found"); - } - - public void close() throws IOException { - fs.close(); - fs = null; - } - - /** - * Reads all macros from all modules of the opened office file. - * @return All the macros and their contents - * - * @since 3.15-beta2 - */ - public Map readMacros() throws IOException { - final ModuleMap modules = new ModuleMap(); - findMacros(fs.getRoot(), modules); - - Map moduleSources = new HashMap(); - for (Map.Entry entry : modules.entrySet()) { - Module module = entry.getValue(); - if (module.buf != null && module.buf.length > 0) { // Skip empty modules - moduleSources.put(entry.getKey(), new String(module.buf, modules.charset)); - } - } - return moduleSources; - } - - protected static class Module { - Integer offset; - byte[] buf; - void read(InputStream in) throws IOException { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copy(in, out); - out.close(); - buf = out.toByteArray(); - } - } - protected static class ModuleMap extends HashMap { - Charset charset = Charset.forName("Cp1252"); // default charset - } - - /** - * Recursively traverses directory structure rooted at dir. - * For each macro module that is found, the module's name and code are - * added to modules. - * - * @param dir The directory of entries to look at - * @param modules The resulting map of modules - * @throws IOException If reading the VBA module fails - * @since 3.15-beta2 - */ - protected void findMacros(DirectoryNode dir, ModuleMap modules) throws IOException { - if (VBA_PROJECT_POIFS.equalsIgnoreCase(dir.getName())) { - // VBA project directory, process - readMacros(dir, modules); - } else { - // Check children - for (Entry child : dir) { - if (child instanceof DirectoryNode) { - findMacros((DirectoryNode)child, modules); - } - } - } - } - - /** - * Read length bytes of MBCS (multi-byte character set) characters from the stream - * - * @param stream the inputstream to read from - * @param length number of bytes to read from stream - * @param charset the character set encoding of the bytes in the stream - * @return a java String in the supplied character set - * @throws IOException If reading from the stream fails - */ - private static String readString(InputStream stream, int length, Charset charset) throws IOException { - byte[] buffer = new byte[length]; - int count = stream.read(buffer); - return new String(buffer, 0, count, charset); - } - - /** - * reads module from DIR node in input stream and adds it to the modules map for decompression later - * on the second pass through this function, the module will be decompressed - * - * Side-effects: adds a new module to the module map or sets the buf field on the module - * to the decompressed stream contents (the VBA code for one module) - * - * @param in the run-length encoded input stream to read from - * @param streamName the stream name of the module - * @param modules a map to store the modules - * @throws IOException If reading data from the stream or from modules fails - */ - private static void readModule(RLEDecompressingInputStream in, String streamName, ModuleMap modules) throws IOException { - int moduleOffset = in.readInt(); - Module module = modules.get(streamName); - if (module == null) { - // First time we've seen the module. Add it to the ModuleMap and decompress it later - module = new Module(); - module.offset = moduleOffset; - modules.put(streamName, module); - // Would adding module.read(in) here be correct? - } else { - // Decompress a previously found module and store the decompressed result into module.buf - InputStream stream = new RLEDecompressingInputStream( - new ByteArrayInputStream(module.buf, moduleOffset, module.buf.length - moduleOffset) - ); - module.read(stream); - stream.close(); - } - } - - private static void readModule(DocumentInputStream dis, String name, ModuleMap modules) throws IOException { - Module module = modules.get(name); - // TODO Refactor this to fetch dir then do the rest - if (module == null) { - // no DIR stream with offsets yet, so store the compressed bytes for later - module = new Module(); - modules.put(name, module); - module.read(dis); - } else if (module.buf == null) { //if we haven't already read the bytes for the module keyed off this name... - if (module.offset == null) { - //This should not happen. bug 59858 - throw new IOException("Module offset for '" + name + "' was never read."); - } - // we know the offset already, so decompress immediately on-the-fly - long skippedBytes = dis.skip(module.offset); - if (skippedBytes != module.offset) { - throw new IOException("tried to skip " + module.offset + " bytes, but actually skipped " + skippedBytes + " bytes"); - } - InputStream stream = new RLEDecompressingInputStream(dis); - module.read(stream); - stream.close(); - } - - } - - /** - * Skips n bytes in an input stream, throwing IOException if the - * number of bytes skipped is different than requested. - * @throws IOException If skipping would exceed the available data or skipping did not work. - */ - private static void trySkip(InputStream in, long n) throws IOException { - long skippedBytes = in.skip(n); - if (skippedBytes != n) { - if (skippedBytes < 0) { - throw new IOException( - "Tried skipping " + n + " bytes, but no bytes were skipped. " - + "The end of the stream has been reached or the stream is closed."); - } else { - throw new IOException( - "Tried skipping " + n + " bytes, but only " + skippedBytes + " bytes were skipped. " - + "This should never happen."); - } - } - } - - // Constants from MS-OVBA: https://msdn.microsoft.com/en-us/library/office/cc313094(v=office.12).aspx - private static final int EOF = -1; - private static final int VERSION_INDEPENDENT_TERMINATOR = 0x0010; - @SuppressWarnings("unused") - private static final int VERSION_DEPENDENT_TERMINATOR = 0x002B; - private static final int PROJECTVERSION = 0x0009; - private static final int PROJECTCODEPAGE = 0x0003; - private static final int STREAMNAME = 0x001A; - private static final int MODULEOFFSET = 0x0031; - @SuppressWarnings("unused") - private static final int MODULETYPE_PROCEDURAL = 0x0021; - @SuppressWarnings("unused") - private static final int MODULETYPE_DOCUMENT_CLASS_OR_DESIGNER = 0x0022; - @SuppressWarnings("unused") - private static final int PROJECTLCID = 0x0002; - @SuppressWarnings("unused") - private static final int MODULE_NAME = 0x0019; - @SuppressWarnings("unused") - private static final int MODULE_NAME_UNICODE = 0x0047; - @SuppressWarnings("unused") - private static final int MODULE_DOC_STRING = 0x001c; - private static final int STREAMNAME_RESERVED = 0x0032; - - /** - * Reads VBA Project modules from a VBA Project directory located at - * macroDir into modules. - * - * @since 3.15-beta2 - */ - protected void readMacros(DirectoryNode macroDir, ModuleMap modules) throws IOException { - for (Entry entry : macroDir) { - if (! (entry instanceof DocumentNode)) { continue; } - - String name = entry.getName(); - DocumentNode document = (DocumentNode)entry; - DocumentInputStream dis = new DocumentInputStream(document); - try { - if ("dir".equalsIgnoreCase(name)) { - // process DIR - RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis); - String streamName = null; - int recordId = 0; - try { - while (true) { - recordId = in.readShort(); - if (EOF == recordId - || VERSION_INDEPENDENT_TERMINATOR == recordId) { - break; - } - int recordLength = in.readInt(); - switch (recordId) { - case PROJECTVERSION: - trySkip(in, 6); - break; - case PROJECTCODEPAGE: - int codepage = in.readShort(); - modules.charset = Charset.forName(CodePageUtil.codepageToEncoding(codepage, true)); - break; - case STREAMNAME: - streamName = readString(in, recordLength, modules.charset); - int reserved = in.readShort(); - if (reserved != STREAMNAME_RESERVED) { - throw new IOException("Expected x0032 after stream name before Unicode stream name, but found: "+ - Integer.toHexString(reserved)); - } - int unicodeNameRecordLength = in.readInt(); - readUnicodeString(in, unicodeNameRecordLength); - // do something with this at some point - break; - case MODULEOFFSET: - readModule(in, streamName, modules); - break; - default: - trySkip(in, recordLength); - break; - } - } - } catch (final IOException e) { - throw new IOException( - "Error occurred while reading macros at section id " - + recordId + " (" + HexDump.shortToHex(recordId) + ")", e); - } - finally { - in.close(); - } - } else if (!startsWithIgnoreCase(name, "__SRP") - && !startsWithIgnoreCase(name, "_VBA_PROJECT")) { - // process module, skip __SRP and _VBA_PROJECT since these do not contain macros - readModule(dis, name, modules); - } - } - finally { - dis.close(); - } - } - } - - private String readUnicodeString(RLEDecompressingInputStream in, int unicodeNameRecordLength) throws IOException { - byte[] buffer = new byte[unicodeNameRecordLength]; - IOUtils.readFully(in, buffer); - return new String(buffer, UTF_16LE); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java b/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java deleted file mode 100644 index 88ee7da7f..000000000 --- a/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.nio; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -/** - * A POIFS {@link DataSource} backed by a byte array. - */ -public class ByteArrayBackedDataSource extends DataSource { - private byte[] buffer; - private long size; - - public ByteArrayBackedDataSource(byte[] data, int size) { // NOSONAR - this.buffer = data; - this.size = size; - } - public ByteArrayBackedDataSource(byte[] data) { - this(data, data.length); - } - - @Override - public ByteBuffer read(int length, long position) { - if(position >= size) { - throw new IndexOutOfBoundsException( - "Unable to read " + length + " bytes from " + - position + " in stream of length " + size - ); - } - - int toRead = (int)Math.min(length, size - position); - return ByteBuffer.wrap(buffer, (int)position, toRead); - } - - @Override - public void write(ByteBuffer src, long position) { - // Extend if needed - long endPosition = position + src.capacity(); - if(endPosition > buffer.length) { - extend(endPosition); - } - - // Now copy - src.get(buffer, (int)position, src.capacity()); - - // Update size if needed - if(endPosition > size) { - size = endPosition; - } - } - - private void extend(long length) { - // Consider extending by a bit more than requested - long difference = length - buffer.length; - if(difference < buffer.length*0.25) { - difference = (long)(buffer.length*0.25); - } - if(difference < 4096) { - difference = 4096; - } - - byte[] nb = new byte[(int)(difference+buffer.length)]; - System.arraycopy(buffer, 0, nb, 0, (int)size); - buffer = nb; - } - - @Override - public void copyTo(OutputStream stream) throws IOException { - stream.write(buffer, 0, (int)size); - } - - @Override - public long size() { - return size; - } - - @Override - public void close() { - buffer = null; - size = -1; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java b/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java deleted file mode 100644 index f43667626..000000000 --- a/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.nio; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -/** - * Common definition of how we read and write bytes - */ -public abstract class DataSource { - public abstract ByteBuffer read(int length, long position) throws IOException; - public abstract void write(ByteBuffer src, long position) throws IOException; - public abstract long size() throws IOException; - /** Close the underlying stream */ - public abstract void close() throws IOException; - /** Copies the contents to the specified OutputStream */ - public abstract void copyTo(OutputStream stream) throws IOException; -} diff --git a/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java b/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java deleted file mode 100644 index 32a8701fb..000000000 --- a/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.nio; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.WritableByteChannel; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.SuppressForbidden; - -/** - * A POIFS {@link DataSource} backed by a File - */ -public class FileBackedDataSource extends DataSource { - private final static POILogger logger = POILogFactory.getLogger( FileBackedDataSource.class ); - - private FileChannel channel; - private boolean writable; - // remember file base, which needs to be closed too - private RandomAccessFile srcFile; - - // Buffers which map to a file-portion are not closed automatically when the Channel is closed - // therefore we need to keep the list of mapped buffers and do some ugly reflection to try to - // clean the buffer during close(). - // See https://bz.apache.org/bugzilla/show_bug.cgi?id=58480, - // http://stackoverflow.com/questions/3602783/file-access-synchronized-on-java-object and - // http://bugs.java.com/view_bug.do?bug_id=4724038 for related discussions - private List buffersToClean = new ArrayList(); - - public FileBackedDataSource(File file) throws FileNotFoundException { - this(newSrcFile(file, "r"), true); - } - - public FileBackedDataSource(File file, boolean readOnly) throws FileNotFoundException { - this(newSrcFile(file, readOnly ? "r" : "rw"), readOnly); - } - - public FileBackedDataSource(RandomAccessFile srcFile, boolean readOnly) { - this(srcFile.getChannel(), readOnly); - this.srcFile = srcFile; - } - - public FileBackedDataSource(FileChannel channel, boolean readOnly) { - this.channel = channel; - this.writable = !readOnly; - } - - public boolean isWriteable() { - return this.writable; - } - - public FileChannel getChannel() { - return this.channel; - } - - @Override - public ByteBuffer read(int length, long position) throws IOException { - if(position >= size()) { - throw new IndexOutOfBoundsException("Position " + position + " past the end of the file"); - } - - // Do we read or map (for read/write)? - ByteBuffer dst; - if (writable) { - dst = channel.map(FileChannel.MapMode.READ_WRITE, position, length); - - // remember this buffer for cleanup - buffersToClean.add(dst); - } else { - // allocate the buffer on the heap if we cannot map the data in directly - channel.position(position); - dst = ByteBuffer.allocate(length); - - // Read the contents and check that we could read some data - int worked = IOUtils.readFully(channel, dst); - if(worked == -1) { - throw new IndexOutOfBoundsException("Position " + position + " past the end of the file"); - } - } - - // make it ready for reading - dst.position(0); - - // All done - return dst; - } - - @Override - public void write(ByteBuffer src, long position) throws IOException { - channel.write(src, position); - } - - @Override - public void copyTo(OutputStream stream) throws IOException { - // Wrap the OutputSteam as a channel - WritableByteChannel out = Channels.newChannel(stream); - // Now do the transfer - channel.transferTo(0, channel.size(), out); - } - - @Override - public long size() throws IOException { - return channel.size(); - } - - @Override - public void close() throws IOException { - // also ensure that all buffers are unmapped so we do not keep files locked on Windows - // We consider it a bug if a Buffer is still in use now! - for(ByteBuffer buffer : buffersToClean) { - unmap(buffer); - } - buffersToClean.clear(); - - if (srcFile != null) { - // see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4796385 - srcFile.close(); - } else { - channel.close(); - } - } - - private static RandomAccessFile newSrcFile(File file, String mode) throws FileNotFoundException { - if(!file.exists()) { - throw new FileNotFoundException(file.toString()); - } - return new RandomAccessFile(file, mode); - } - - // need to use reflection to avoid depending on the sun.nio internal API - // unfortunately this might break silently with newer/other Java implementations, - // but we at least have unit-tests which will indicate this when run on Windows - private static void unmap(final ByteBuffer buffer) { - // not necessary for HeapByteBuffer, avoid lots of log-output on this class - if(buffer.getClass().getName().endsWith("HeapByteBuffer")) { - return; - } - - AccessController.doPrivileged(new PrivilegedAction() { - @Override - @SuppressForbidden("Java 9 Jigsaw whitelists access to sun.misc.Cleaner, so setAccessible works") - public Void run() { - try { - final Method getCleanerMethod = buffer.getClass().getMethod("cleaner"); - getCleanerMethod.setAccessible(true); - final Object cleaner = getCleanerMethod.invoke(buffer); - if (cleaner != null) { - cleaner.getClass().getMethod("clean").invoke(cleaner); - } - } catch (Exception e) { - logger.log(POILogger.WARN, "Unable to unmap memory mapped ByteBuffer.", e); - } - return null; // Void - } - }); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/package.html b/trunk/src/java/org/apache/poi/poifs/package.html deleted file mode 100644 index f86821c8a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/package.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - -Poor Obfuscation Implementation FileSystem APIs implement the OLE 2 Compound Document format in -pure Java. All POI subprojects are based upon this API. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.hssf -@see org.apache.poi.hpsf - - diff --git a/trunk/src/java/org/apache/poi/poifs/property/Child.java b/trunk/src/java/org/apache/poi/poifs/property/Child.java deleted file mode 100644 index 604745214..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/Child.java +++ /dev/null @@ -1,63 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.property; - -/** - * This interface defines methods for finding and setting sibling - * Property instances - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface Child { - /** - * Get the next Child, if any - * - * @return the next Child; may return null - */ - - public Child getNextChild(); - - /** - * Get the previous Child, if any - * - * @return the previous Child; may return null - */ - - public Child getPreviousChild(); - - /** - * Set the next Child - * - * @param child the new 'next' child; may be null, which has the - * effect of saying there is no 'next' child - */ - - public void setNextChild(final Child child); - - /** - * Set the previous Child - * - * @param child the new 'previous' child; may be null, which has - * the effect of saying there is no 'previous' child - */ - - public void setPreviousChild(final Child child); -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/DirectoryProperty.java b/trunk/src/java/org/apache/poi/poifs/property/DirectoryProperty.java deleted file mode 100644 index ef4ff3499..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/DirectoryProperty.java +++ /dev/null @@ -1,271 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -/** - * Directory property - */ -public class DirectoryProperty extends Property implements Parent, Iterable { // TODO - fix instantiable superclass - - /** List of Property instances */ - private List _children; - - /** set of children's names */ - private Set _children_names; - - /** - * Default constructor - * - * @param name the name of the directory - */ - public DirectoryProperty(String name) - { - super(); - _children = new ArrayList(); - _children_names = new HashSet(); - setName(name); - setSize(0); - setPropertyType(PropertyConstants.DIRECTORY_TYPE); - setStartBlock(0); - setNodeColor(_NODE_BLACK); // simplification - } - - /** - * reader constructor - * - * @param index index number - * @param array byte data - * @param offset offset into byte data - */ - protected DirectoryProperty(final int index, final byte [] array, - final int offset) - { - super(index, array, offset); - _children = new ArrayList(); - _children_names = new HashSet(); - } - - /** - * Change a Property's name - * - * @param property the Property whose name is being changed - * @param newName the new name for the Property - * - * @return true if the name change could be made, else false - */ - public boolean changeName(Property property, String newName) - { - boolean result; - String oldName = property.getName(); - - property.setName(newName); - String cleanNewName = property.getName(); - - if (_children_names.contains(cleanNewName)) - { - - // revert the change - property.setName(oldName); - result = false; - } - else - { - _children_names.add(cleanNewName); - _children_names.remove(oldName); - result = true; - } - return result; - } - - /** - * Delete a Property - * - * @param property the Property being deleted - * - * @return true if the Property could be deleted, else false - */ - public boolean deleteChild(Property property) - { - boolean result = _children.remove(property); - - if (result) - { - _children_names.remove(property.getName()); - } - return result; - } - - public static class PropertyComparator implements Comparator, Serializable { - - /** - * compare method. Assumes both parameters are non-null - * instances of Property. One property is less than another if - * its name is shorter than the other property's name. If the - * names are the same length, the property whose name comes - * before the other property's name, alphabetically, is less - * than the other property. - * - * @param o1 first object to compare, better be a Property - * @param o2 second object to compare, better be a Property - * - * @return negative value if o1 < o2, - * zero if o1 == o2, - * positive value if o1 > o2. - */ - public int compare(Property o1, Property o2) - { - String VBA_PROJECT = "_VBA_PROJECT"; - String name1 = o1.getName(); - String name2 = o2.getName(); - int result = name1.length() - name2.length(); - - if (result == 0) - { - // _VBA_PROJECT, it seems, will always come last - if (name1.compareTo(VBA_PROJECT) == 0) - result = 1; - else if (name2.compareTo(VBA_PROJECT) == 0) - result = -1; - else - { - if (name1.startsWith("__") && name2.startsWith("__")) - { - // Betweeen __SRP_0 and __SRP_1 just sort as normal - result = name1.compareToIgnoreCase(name2); - } - else if (name1.startsWith("__")) - { - // If only name1 is __XXX then this will be placed after name2 - result = 1; - } - else if (name2.startsWith("__")) - { - // If only name2 is __XXX then this will be placed after name1 - result = -1; - } - else - // result = name1.compareTo(name2); - // The default case is to sort names ignoring case - result = name1.compareToIgnoreCase(name2); - } - } - return result; - } - } - - /** - * @return true if a directory type Property - */ - public boolean isDirectory() - { - return true; - } - - /** - * Perform whatever activities need to be performed prior to - * writing - */ - protected void preWrite() - { - if (_children.size() > 0) - { - Property[] children = _children.toArray(new Property[ 0 ]); - - Arrays.sort(children, new PropertyComparator()); - int midpoint = children.length / 2; - - setChildProperty(children[ midpoint ].getIndex()); - children[ 0 ].setPreviousChild(null); - children[ 0 ].setNextChild(null); - for (int j = 1; j < midpoint; j++) - { - children[ j ].setPreviousChild(children[ j - 1 ]); - children[ j ].setNextChild(null); - } - if (midpoint != 0) - { - children[ midpoint ] - .setPreviousChild(children[ midpoint - 1 ]); - } - if (midpoint != (children.length - 1)) - { - children[ midpoint ].setNextChild(children[ midpoint + 1 ]); - for (int j = midpoint + 1; j < children.length - 1; j++) - { - children[ j ].setPreviousChild(null); - children[ j ].setNextChild(children[ j + 1 ]); - } - children[ children.length - 1 ].setPreviousChild(null); - children[ children.length - 1 ].setNextChild(null); - } - else - { - children[ midpoint ].setNextChild(null); - } - } - } - - /** - * Get an iterator over the children of this Parent; all elements - * are instances of Property. - * - * @return Iterator of children; may refer to an empty collection - */ - public Iterator getChildren() - { - return _children.iterator(); - } - /** - * Get an iterator over the children of this Parent, alias for - * {@link #getChildren()} which supports foreach use - */ - public Iterator iterator() { - return getChildren(); - } - - /** - * Add a new child to the collection of children - * - * @param property the new child to be added; must not be null - * - * @exception IOException if we already have a child with the same - * name - */ - public void addChild(final Property property) - throws IOException - { - String name = property.getName(); - - if (_children_names.contains(name)) - { - throw new IOException("Duplicate name \"" + name + "\""); - } - _children_names.add(name); - _children.add(property); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java b/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java deleted file mode 100644 index ea693d887..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java +++ /dev/null @@ -1,121 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.property; - -import org.apache.poi.poifs.filesystem.OPOIFSDocument; - -/** - * Trivial extension of Property for POIFSDocuments - */ -public class DocumentProperty extends Property { - // the POIFSDocument this property is associated with - private OPOIFSDocument _document; - - /** - * Constructor - * - * @param name POIFSDocument name - * @param size POIFSDocument size - */ - - public DocumentProperty(final String name, final int size) - { - super(); - _document = null; - setName(name); - setSize(size); - setNodeColor(_NODE_BLACK); // simplification - setPropertyType(PropertyConstants.DOCUMENT_TYPE); - } - - /** - * reader constructor - * - * @param index index number - * @param array byte data - * @param offset offset into byte data - */ - protected DocumentProperty(final int index, final byte [] array, - final int offset) - { - super(index, array, offset); - _document = null; - } - - /** - * set the POIFSDocument - * - * @param doc the associated POIFSDocument - */ - public void setDocument(OPOIFSDocument doc) - { - _document = doc; - } - - /** - * get the POIFSDocument - * - * @return the associated document - */ - public OPOIFSDocument getDocument() - { - return _document; - } - - /* ********** START extension of Property ********** */ - - /** - * give method more visibility - * - * @return true if this property should use small blocks - */ - public boolean shouldUseSmallBlocks() - { - return super.shouldUseSmallBlocks(); - } - - /** - * @return true if a directory type Property - */ - public boolean isDirectory() - { - return false; - } - - /** - * Perform whatever activities need to be performed prior to - * writing - */ - protected void preWrite() - { - - // do nothing - } - - /** - * Update the size of the property's data - */ - public void updateSize(int size) - { - setSize(size); - } - - /* ********** END extension of Property ********** */ -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/NPropertyTable.java b/trunk/src/java/org/apache/poi/poifs/property/NPropertyTable.java deleted file mode 100644 index 7117bc2e0..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/NPropertyTable.java +++ /dev/null @@ -1,160 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.NPOIFSStream; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This class embodies the Property Table for a {@link NPOIFSFileSystem}; - * this is basically the directory for all of the documents in the - * filesystem. - */ -public final class NPropertyTable extends PropertyTableBase { - private static final POILogger _logger = - POILogFactory.getLogger(NPropertyTable.class); - private POIFSBigBlockSize _bigBigBlockSize; - - public NPropertyTable(HeaderBlock headerBlock) - { - super(headerBlock); - _bigBigBlockSize = headerBlock.getBigBlockSize(); - } - - /** - * reading constructor (used when we've read in a file and we want - * to extract the property table from it). Populates the - * properties thoroughly - * - * @param headerBlock the header block of the file - * @param filesystem the filesystem to read from - * - * @exception IOException if anything goes wrong (which should be - * a result of the input being NFG) - */ - public NPropertyTable(final HeaderBlock headerBlock, - final NPOIFSFileSystem filesystem) - throws IOException - { - super( - headerBlock, - buildProperties( - (new NPOIFSStream(filesystem, headerBlock.getPropertyStart())).iterator(), - headerBlock.getBigBlockSize() - ) - ); - _bigBigBlockSize = headerBlock.getBigBlockSize(); - } - - private static List buildProperties(final Iterator dataSource, - final POIFSBigBlockSize bigBlockSize) throws IOException - { - List properties = new ArrayList(); - while(dataSource.hasNext()) { - ByteBuffer bb = dataSource.next(); - - // Turn it into an array - byte[] data; - if(bb.hasArray() && bb.arrayOffset() == 0 && - bb.array().length == bigBlockSize.getBigBlockSize()) { - data = bb.array(); - } else { - data = new byte[bigBlockSize.getBigBlockSize()]; - - int toRead = data.length; - if (bb.remaining() < bigBlockSize.getBigBlockSize()) { - // Looks to be a truncated block - // This isn't allowed, but some third party created files - // sometimes do this, and we can normally read anyway - _logger.log(POILogger.WARN, "Short Property Block, ", bb.remaining(), - " bytes instead of the expected " + bigBlockSize.getBigBlockSize()); - toRead = bb.remaining(); - } - - bb.get(data, 0, toRead); - } - - PropertyFactory.convertToProperties(data, properties); - } - return properties; - } - - /** - * Return the number of BigBlock's this instance uses - * - * @return count of BigBlock instances - */ - public int countBlocks() - { - long rawSize = _properties.size() * POIFSConstants.PROPERTY_SIZE; - int blkSize = _bigBigBlockSize.getBigBlockSize(); - int numBlocks = (int)(rawSize / blkSize); - if ((rawSize % blkSize) != 0) { - numBlocks++; - } - return numBlocks; - } - - /** - * Prepare to be written - */ - public void preWrite() { - List pList = new ArrayList(); - // give each property its index - int i=0; - for (Property p : _properties) { - // only handle non-null properties - if (p == null) continue; - p.setIndex(i++); - pList.add(p); - } - - // prepare each property for writing - for (Property p : pList) p.preWrite(); - } - - /** - * Writes the properties out into the given low-level stream - */ - public void write(NPOIFSStream stream) throws IOException { - OutputStream os = stream.getOutputStream(); - for(Property property : _properties) { - if(property != null) { - property.writeData(os); - } - } - os.close(); - - // Update the start position if needed - if(getStartBlock() != stream.getStartBlock()) { - setStartBlock(stream.getStartBlock()); - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/Parent.java b/trunk/src/java/org/apache/poi/poifs/property/Parent.java deleted file mode 100644 index 79c286c44..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/Parent.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import java.util.Iterator; - -import java.io.IOException; - -/** - * Behavior for parent (directory) properties - * - * @author Marc Johnson27591@hotmail.com - */ -public interface Parent - extends Child -{ - - /** - * Get an iterator over the children of this Parent; all elements - * are instances of Property. - * - * @return Iterator of children; may refer to an empty collection - */ - - public Iterator getChildren(); - - /** - * Add a new child to the collection of children - * - * @param property the new child to be added; must not be null - * - * @exception IOException if the Parent already has a child with - * the same name - */ - - public void addChild(final Property property) - throws IOException; - - /** - * Set the previous Child - * - * @param child the new 'previous' child; may be null, which has - * the effect of saying there is no 'previous' child - */ - - public void setPreviousChild(final Child child); - - /** - * Set the next Child - * - * @param child the new 'next' child; may be null, which has the - * effect of saying there is no 'next' child - */ - - public void setNextChild(final Child child); -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/Property.java b/trunk/src/java/org/apache/poi/poifs/property/Property.java deleted file mode 100644 index bccac354d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/Property.java +++ /dev/null @@ -1,526 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; - -import org.apache.poi.hpsf.ClassID; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.dev.POIFSViewable; -import org.apache.poi.util.ByteField; -import org.apache.poi.util.IntegerField; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.ShortField; - -/** - * This abstract base class is the ancestor of all classes - * implementing POIFS Property behavior. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public abstract class Property implements Child, POIFSViewable { - static final private byte _default_fill = ( byte ) 0x00; - static final private int _name_size_offset = 0x40; - static final private int _max_name_length = - (_name_size_offset / LittleEndianConsts.SHORT_SIZE) - 1; - static final protected int _NO_INDEX = -1; - - // useful offsets - static final private int _node_color_offset = 0x43; - static final private int _previous_property_offset = 0x44; - static final private int _next_property_offset = 0x48; - static final private int _child_property_offset = 0x4C; - static final private int _storage_clsid_offset = 0x50; - static final private int _user_flags_offset = 0x60; - static final private int _seconds_1_offset = 0x64; - static final private int _days_1_offset = 0x68; - static final private int _seconds_2_offset = 0x6C; - static final private int _days_2_offset = 0x70; - static final private int _start_block_offset = 0x74; - static final private int _size_offset = 0x78; - - // node colors - static final protected byte _NODE_BLACK = 1; - static final protected byte _NODE_RED = 0; - - // documents must be at least this size to be stored in big blocks - static final private int _big_block_minimum_bytes = POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE; - private String _name; - private ShortField _name_size; - private ByteField _property_type; - private ByteField _node_color; - private IntegerField _previous_property; - private IntegerField _next_property; - private IntegerField _child_property; - private ClassID _storage_clsid; - private IntegerField _user_flags; - private IntegerField _seconds_1; - private IntegerField _days_1; - private IntegerField _seconds_2; - private IntegerField _days_2; - private IntegerField _start_block; - private IntegerField _size; - private byte[] _raw_data; - private int _index; - private Child _next_child; - private Child _previous_child; - - protected Property() - { - _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ]; - Arrays.fill(_raw_data, _default_fill); - _name_size = new ShortField(_name_size_offset); - _property_type = - new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET); - _node_color = new ByteField(_node_color_offset); - _previous_property = new IntegerField(_previous_property_offset, - _NO_INDEX, _raw_data); - _next_property = new IntegerField(_next_property_offset, - _NO_INDEX, _raw_data); - _child_property = new IntegerField(_child_property_offset, - _NO_INDEX, _raw_data); - _storage_clsid = new ClassID(_raw_data,_storage_clsid_offset); - _user_flags = new IntegerField(_user_flags_offset, 0, _raw_data); - _seconds_1 = new IntegerField(_seconds_1_offset, 0, - _raw_data); - _days_1 = new IntegerField(_days_1_offset, 0, _raw_data); - _seconds_2 = new IntegerField(_seconds_2_offset, 0, - _raw_data); - _days_2 = new IntegerField(_days_2_offset, 0, _raw_data); - _start_block = new IntegerField(_start_block_offset); - _size = new IntegerField(_size_offset, 0, _raw_data); - _index = _NO_INDEX; - setName(""); - setNextChild(null); - setPreviousChild(null); - } - - /** - * Constructor from byte data - * - * @param index index number - * @param array byte data - * @param offset offset into byte data - */ - protected Property(int index, byte [] array, int offset) - { - _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ]; - System.arraycopy(array, offset, _raw_data, 0, - POIFSConstants.PROPERTY_SIZE); - _name_size = new ShortField(_name_size_offset, _raw_data); - _property_type = - new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data); - _node_color = new ByteField(_node_color_offset, _raw_data); - _previous_property = new IntegerField(_previous_property_offset, - _raw_data); - _next_property = new IntegerField(_next_property_offset, - _raw_data); - _child_property = new IntegerField(_child_property_offset, - _raw_data); - _storage_clsid = new ClassID(_raw_data,_storage_clsid_offset); - _user_flags = new IntegerField(_user_flags_offset, 0, _raw_data); - _seconds_1 = new IntegerField(_seconds_1_offset, _raw_data); - _days_1 = new IntegerField(_days_1_offset, _raw_data); - _seconds_2 = new IntegerField(_seconds_2_offset, _raw_data); - _days_2 = new IntegerField(_days_2_offset, _raw_data); - _start_block = new IntegerField(_start_block_offset, _raw_data); - _size = new IntegerField(_size_offset, _raw_data); - _index = index; - int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE) - - 1; - - if (name_length < 1) - { - _name = ""; - } - else - { - char[] char_array = new char[ name_length ]; - int name_offset = 0; - - for (int j = 0; j < name_length; j++) - { - char_array[ j ] = ( char ) new ShortField(name_offset, - _raw_data).get(); - name_offset += LittleEndianConsts.SHORT_SIZE; - } - _name = new String(char_array, 0, name_length); - } - _next_child = null; - _previous_child = null; - } - - /** - * Write the raw data to an OutputStream. - * - * @param stream the OutputStream to which the data should be - * written. - * - * @exception IOException on problems writing to the specified - * stream. - */ - public void writeData(OutputStream stream) - throws IOException - { - stream.write(_raw_data); - } - - /** - * Set the start block for the document referred to by this - * Property. - * - * @param startBlock the start block index - */ - public void setStartBlock(int startBlock) - { - _start_block.set(startBlock, _raw_data); - } - - /** - * @return the start block - */ - public int getStartBlock() - { - return _start_block.get(); - } - - /** - * find out the document size - * - * @return size in bytes - */ - public int getSize() - { - return _size.get(); - } - - /** - * Based on the currently defined size, should this property use - * small blocks? - * - * @return true if the size is less than _big_block_minimum_bytes - */ - public boolean shouldUseSmallBlocks() - { - return Property.isSmall(_size.get()); - } - - /** - * does the length indicate a small document? - * - * @param length length in bytes - * - * @return true if the length is less than - * _big_block_minimum_bytes - */ - public static boolean isSmall(int length) - { - return length < _big_block_minimum_bytes; - } - - /** - * Get the name of this property - * - * @return property name as String - */ - public String getName() - { - return _name; - } - - /** - * @return true if a directory type Property - */ - abstract public boolean isDirectory(); - - /** - * Sets the storage clsid, which is the Class ID of a COM object which - * reads and writes this stream - * @return storage Class ID for this property stream - */ - public ClassID getStorageClsid() - { - return _storage_clsid; - } - - /** - * Set the name; silently truncates the name if it's too long. - * - * @param name the new name - */ - protected void setName(String name) - { - char[] char_array = name.toCharArray(); - int limit = Math.min(char_array.length, _max_name_length); - - _name = new String(char_array, 0, limit); - short offset = 0; - int j = 0; - - for (; j < limit; j++) - { - new ShortField(offset, ( short ) char_array[ j ], _raw_data); - offset += LittleEndianConsts.SHORT_SIZE; - } - for (; j < _max_name_length + 1; j++) - { - new ShortField(offset, ( short ) 0, _raw_data); - offset += LittleEndianConsts.SHORT_SIZE; - } - - // double the count, and include the null at the end - _name_size - .set(( short ) ((limit + 1) - * LittleEndianConsts.SHORT_SIZE), _raw_data); - } - - /** - * Sets the storage class ID for this property stream. This is the Class ID - * of the COM object which can read and write this property stream - * @param clsidStorage Storage Class ID - */ - public void setStorageClsid( ClassID clsidStorage) - { - _storage_clsid = clsidStorage; - if( clsidStorage == null) { - Arrays.fill( _raw_data, _storage_clsid_offset, _storage_clsid_offset + ClassID.LENGTH, (byte) 0); - } else { - clsidStorage.write( _raw_data, _storage_clsid_offset); - } - } - /** - * Set the property type. Makes no attempt to validate the value. - * - * @param propertyType the property type (root, file, directory) - */ - protected void setPropertyType(byte propertyType) - { - _property_type.set(propertyType, _raw_data); - } - - /** - * Set the node color. - * - * @param nodeColor the node color (red or black) - */ - protected void setNodeColor(byte nodeColor) - { - _node_color.set(nodeColor, _raw_data); - } - - /** - * Set the child property. - * - * @param child the child property's index in the Property Table - */ - protected void setChildProperty(int child) - { - _child_property.set(child, _raw_data); - } - - /** - * Get the child property (its index in the Property Table) - * - * @return child property index - */ - protected int getChildIndex() - { - return _child_property.get(); - } - - /** - * Set the size of the document associated with this Property - * - * @param size the size of the document, in bytes - */ - protected void setSize(int size) - { - _size.set(size, _raw_data); - } - - /** - * Set the index for this Property - * - * @param index this Property's index within its containing - * Property Table - */ - protected void setIndex(int index) - { - _index = index; - } - - /** - * get the index for this Property - * - * @return the index of this Property within its Property Table - */ - protected int getIndex() - { - return _index; - } - - /** - * Perform whatever activities need to be performed prior to - * writing - */ - abstract protected void preWrite(); - - /** - * get the next sibling - * - * @return index of next sibling - */ - int getNextChildIndex() - { - return _next_property.get(); - } - - /** - * get the previous sibling - * - * @return index of previous sibling - */ - int getPreviousChildIndex() - { - return _previous_property.get(); - } - - /** - * determine whether the specified index is valid - * - * @param index value to be checked - * - * @return true if the index is valid - */ - static boolean isValidIndex(int index) - { - return index != _NO_INDEX; - } - - /** - * Get the next Child, if any - * - * @return the next Child; may return null - */ - public Child getNextChild() - { - return _next_child; - } - - /** - * Get the previous Child, if any - * - * @return the previous Child; may return null - */ - public Child getPreviousChild() - { - return _previous_child; - } - - /** - * Set the next Child - * - * @param child the new 'next' child; may be null, which has the - * effect of saying there is no 'next' child - */ - public void setNextChild(Child child) - { - _next_child = child; - _next_property.set((child == null) ? _NO_INDEX - : (( Property ) child) - .getIndex(), _raw_data); - } - - /** - * Set the previous Child - * - * @param child the new 'previous' child; may be null, which has - * the effect of saying there is no 'previous' child - */ - public void setPreviousChild(Child child) - { - _previous_child = child; - _previous_property.set((child == null) ? _NO_INDEX - : (( Property ) child) - .getIndex(), _raw_data); - } - - /** - * Get an array of objects, some of which may implement - * POIFSViewable - * - * @return an array of Object; may not be null, but may be empty - */ - public Object [] getViewableArray() - { - Object[] results = new Object[ 5 ]; - - results[ 0 ] = "Name = \"" + getName() + "\""; - results[ 1 ] = "Property Type = " + _property_type.get(); - results[ 2 ] = "Node Color = " + _node_color.get(); - long time = _days_1.get(); - - time <<= 32; - time += _seconds_1.get() & 0x0000FFFFL; - results[ 3 ] = "Time 1 = " + time; - time = _days_2.get(); - time <<= 32; - time += _seconds_2.get() & 0x0000FFFFL; - results[ 4 ] = "Time 2 = " + time; - return results; - } - - /** - * Get an Iterator of objects, some of which may implement - * POIFSViewable - * - * @return an Iterator; may not be null, but may have an empty - * back end store - */ - public Iterator getViewableIterator() - { - return Collections.emptyList().iterator(); - } - - /** - * Give viewers a hint as to whether to call getViewableArray or - * getViewableIterator - * - * @return true if a viewer should call getViewableArray, false if - * a viewer should call getViewableIterator - */ - public boolean preferArray() - { - return true; - } - - /** - * Provides a short description of the object, to be used when a - * POIFSViewable object has not provided its contents. - * - * @return short description - */ - public String getShortDescription() { - return "Property: \"" + getName() + "\""; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/PropertyConstants.java b/trunk/src/java/org/apache/poi/poifs/property/PropertyConstants.java deleted file mode 100644 index cf89f4085..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/PropertyConstants.java +++ /dev/null @@ -1,34 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.property; - -/** - * Interface PropertyConstants - */ - -public interface PropertyConstants -{ - public static final int PROPERTY_TYPE_OFFSET = 0x42; - - // the property types - public static final byte DIRECTORY_TYPE = 1; - public static final byte DOCUMENT_TYPE = 2; - public static final byte ROOT_TYPE = 5; -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/PropertyFactory.java b/trunk/src/java/org/apache/poi/poifs/property/PropertyFactory.java deleted file mode 100644 index df3dcba29..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/PropertyFactory.java +++ /dev/null @@ -1,103 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.property; - -import java.io.IOException; - -import java.util.*; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.storage.ListManagedBlock; - -/** - * Factory for turning an array of RawDataBlock instances containing - * Property data into an array of proper Property objects. - * - * The array produced may be sparse, in that any portion of data that - * should correspond to a Property, but which does not map to a proper - * Property (i.e., a DirectoryProperty, DocumentProperty, or - * RootProperty) will get mapped to a null Property in the array. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -class PropertyFactory { - // no need for an accessible constructor - private PropertyFactory() - { - } - - /** - * Convert raw data blocks to an array of Property's - * - * @param blocks to be converted - * - * @return the converted List of Property objects. May contain - * nulls, but will not be null - * - * @exception IOException if any of the blocks are empty - */ - static List convertToProperties(ListManagedBlock [] blocks) - throws IOException - { - List properties = new ArrayList(); - - for (ListManagedBlock block : blocks) { - byte[] data = block.getData(); - convertToProperties(data, properties); - } - return properties; - } - - static void convertToProperties(byte[] data, List properties) - throws IOException - { - int property_count = data.length / POIFSConstants.PROPERTY_SIZE; - int offset = 0; - - for (int k = 0; k < property_count; k++) { - switch (data[ offset + PropertyConstants.PROPERTY_TYPE_OFFSET ]) { - case PropertyConstants.DIRECTORY_TYPE : - properties.add( - new DirectoryProperty(properties.size(), data, offset) - ); - break; - - case PropertyConstants.DOCUMENT_TYPE : - properties.add( - new DocumentProperty(properties.size(), data, offset) - ); - break; - - case PropertyConstants.ROOT_TYPE : - properties.add( - new RootProperty(properties.size(), data, offset) - ); - break; - - default : - properties.add(null); - break; - } - - offset += POIFSConstants.PROPERTY_SIZE; - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java b/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java deleted file mode 100644 index e2b5772d7..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.storage.BlockWritable; -import org.apache.poi.poifs.storage.HeaderBlock; -import org.apache.poi.poifs.storage.PropertyBlock; -import org.apache.poi.poifs.storage.RawDataBlockList; - -/** - * This class embodies the Property Table for the {@link org.apache.poi.poifs.filesystem.POIFSFileSystem}; - * this is basically the directory for all of the documents in the - * filesystem. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ -public final class PropertyTable extends PropertyTableBase implements BlockWritable { - private POIFSBigBlockSize _bigBigBlockSize; - private BlockWritable[] _blocks; - - public PropertyTable(HeaderBlock headerBlock) - { - super(headerBlock); - _bigBigBlockSize = headerBlock.getBigBlockSize(); - _blocks = null; - } - - /** - * reading constructor (used when we've read in a file and we want - * to extract the property table from it). Populates the - * properties thoroughly - * - * @param headerBlock the header block of the file - * @param blockList the list of blocks - * - * @exception IOException if anything goes wrong (which should be - * a result of the input being NFG) - */ - public PropertyTable(final HeaderBlock headerBlock, - final RawDataBlockList blockList) - throws IOException - { - super( - headerBlock, - PropertyFactory.convertToProperties( - blockList.fetchBlocks(headerBlock.getPropertyStart(), -1) - ) - ); - _bigBigBlockSize = headerBlock.getBigBlockSize(); - _blocks = null; - } - - /** - * Prepare to be written - */ - public void preWrite() - { - Property[] properties = _properties.toArray(new Property[_properties.size()]); - - // give each property its index - for (int k = 0; k < properties.length; k++) - { - properties[ k ].setIndex(k); - } - - // allocate the blocks for the property table - _blocks = PropertyBlock.createPropertyBlockArray(_bigBigBlockSize, _properties); - - // prepare each property for writing - for (Property property : properties) { - property.preWrite(); - } - } - - /** - * Return the number of BigBlock's this instance uses - * - * @return count of BigBlock instances - */ - public int countBlocks() - { - return (_blocks == null) ? 0 - : _blocks.length; - } - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - public void writeBlocks(final OutputStream stream) - throws IOException - { - if (_blocks != null) - { - for (BlockWritable _block : _blocks) { - _block.writeBlocks(stream); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/PropertyTableBase.java b/trunk/src/java/org/apache/poi/poifs/property/PropertyTableBase.java deleted file mode 100644 index 477cf036d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/PropertyTableBase.java +++ /dev/null @@ -1,158 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -import org.apache.poi.poifs.filesystem.BATManaged; -import org.apache.poi.poifs.storage.HeaderBlock; - -/** - * This class embodies the Property Table for the filesystem, - * which looks up entries in the filesystem to their - * chain of blocks. - * This is the core support, there are implementations - * for the different block schemes as needed. - */ -public abstract class PropertyTableBase implements BATManaged { - private final HeaderBlock _header_block; - protected final List _properties; - - public PropertyTableBase(final HeaderBlock header_block) - { - _header_block = header_block; - _properties = new ArrayList(); - addProperty(new RootProperty()); - } - - /** - * Reading constructor (used when we've read in a file and we want - * to extract the property table from it). Populates the - * properties thoroughly - * - * @param header_block the first block to read from - * @param properties the list to populate - * - * @exception IOException if anything goes wrong (which should be - * a result of the input being NFG) - */ - public PropertyTableBase(final HeaderBlock header_block, - final List properties) - throws IOException - { - _header_block = header_block; - _properties = properties; - populatePropertyTree( (DirectoryProperty)_properties.get(0)); - } - - /** - * Add a property to the list of properties we manage - * - * @param property the new Property to manage - */ - public void addProperty(Property property) - { - _properties.add(property); - } - - /** - * Remove a property from the list of properties we manage - * - * @param property the Property to be removed - */ - public void removeProperty(final Property property) - { - _properties.remove(property); - } - - /** - * Get the root property - * - * @return the root property - */ - public RootProperty getRoot() - { - // it's always the first element in the List - return ( RootProperty ) _properties.get(0); - } - - private void populatePropertyTree(DirectoryProperty root) - throws IOException - { - int index = root.getChildIndex(); - - if (!Property.isValidIndex(index)) - { - - // property has no children - return; - } - Stack children = new Stack(); - - children.push(_properties.get(index)); - while (!children.empty()) - { - Property property = children.pop(); - if (property == null) - { - // unknown / unsupported / corrupted property, skip - continue; - } - - root.addChild(property); - if (property.isDirectory()) - { - populatePropertyTree(( DirectoryProperty ) property); - } - index = property.getPreviousChildIndex(); - if (Property.isValidIndex(index)) - { - children.push(_properties.get(index)); - } - index = property.getNextChildIndex(); - if (Property.isValidIndex(index)) - { - children.push(_properties.get(index)); - } - } - } - - /** - * Get the start block for the property table - * - * @return start block index - */ - public int getStartBlock() - { - return _header_block.getPropertyStart(); - } - - /** - * Set the start block for this instance - * - * @param index index into the array of BigBlock instances making - * up the the filesystem - */ - public void setStartBlock(final int index) - { - _header_block.setPropertyStart(index); - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/RootProperty.java b/trunk/src/java/org/apache/poi/poifs/property/RootProperty.java deleted file mode 100644 index 5a8f3d52e..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/RootProperty.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.property; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.storage.SmallDocumentBlock; - -/** - * Root property - */ -public final class RootProperty extends DirectoryProperty { - private static final String NAME = "Root Entry"; - - RootProperty() - { - super(NAME); - - // overrides - setNodeColor(_NODE_BLACK); - setPropertyType(PropertyConstants.ROOT_TYPE); - setStartBlock(POIFSConstants.END_OF_CHAIN); - } - - /** - * reader constructor - * - * @param index index number - * @param array byte data - * @param offset offset into byte data - */ - protected RootProperty(final int index, final byte [] array, - final int offset) - { - super(index, array, offset); - } - - /** - * set size - * - * @param size size in terms of small blocks - */ - public void setSize(int size) - { - super.setSize(SmallDocumentBlock.calcSize(size)); - } - - /** - * Returns the fixed name "Root Entry", as the - * raw property doesn't have a real name set - */ - @Override - public String getName() { - return NAME; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/property/package.html b/trunk/src/java/org/apache/poi/poifs/property/package.html deleted file mode 100644 index ff11a205a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/property/package.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - -property package contains high and low level Property structures for POIFS. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.poifs.filesystem - - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java deleted file mode 100644 index 2aef116d6..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java +++ /dev/null @@ -1,416 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.util.LittleEndian; - -/** - * A block of block allocation table entries. BATBlocks are created - * only through a static factory method: createBATBlocks. - */ -public final class BATBlock extends BigBlock { - /** - * For a regular fat block, these are 128 / 1024 - * next sector values. - * For a XFat (DIFat) block, these are 127 / 1023 - * next sector values, then a chaining value. - */ - private int[] _values; - - /** - * Does this BATBlock have any free sectors in it? - */ - private boolean _has_free_sectors; - - /** - * Where in the file are we? - */ - private int ourBlockIndex; - - /** - * Create a single instance initialized with default values - */ - private BATBlock(POIFSBigBlockSize bigBlockSize) - { - super(bigBlockSize); - - int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); - _values = new int[_entries_per_block]; - _has_free_sectors = true; - - Arrays.fill(_values, POIFSConstants.UNUSED_BLOCK); - } - - /** - * Create a single instance initialized (perhaps partially) with entries - * - * @param entries the array of block allocation table entries - * @param start_index the index of the first entry to be written - * to the block - * @param end_index the index, plus one, of the last entry to be - * written to the block (writing is for all index - * k, start_index <= k < end_index) - */ - - private BATBlock(POIFSBigBlockSize bigBlockSize, final int [] entries, - final int start_index, final int end_index) - { - this(bigBlockSize); - for (int k = start_index; k < end_index; k++) { - _values[k - start_index] = entries[k]; - } - - // Do we have any free sectors? - if(end_index - start_index == _values.length) { - recomputeFree(); - } - } - - private void recomputeFree() { - boolean hasFree = false; - for(int k=0; k<_values.length; k++) { - if(_values[k] == POIFSConstants.UNUSED_BLOCK) { - hasFree = true; - break; - } - } - _has_free_sectors = hasFree; - } - - /** - * Create a single BATBlock from the byte buffer, which must hold at least - * one big block of data to be read. - */ - public static BATBlock createBATBlock(final POIFSBigBlockSize bigBlockSize, ByteBuffer data) - { - // Create an empty block - BATBlock block = new BATBlock(bigBlockSize); - - // Fill it - byte[] buffer = new byte[LittleEndian.INT_SIZE]; - for(int i=0; i _entries_per_block) - ? j + _entries_per_block - : entries.length); - remaining -= _entries_per_block; - } - return blocks; - } - - /** - * Create an array of XBATBlocks from an array of int block - * allocation table entries - * - * @param entries the array of int entries - * @param startBlock the start block of the array of XBAT blocks - * - * @return the newly created array of BATBlocks - */ - - public static BATBlock [] createXBATBlocks(final POIFSBigBlockSize bigBlockSize, - final int [] entries, - final int startBlock) - { - int block_count = - calculateXBATStorageRequirements(bigBlockSize, entries.length); - BATBlock[] blocks = new BATBlock[ block_count ]; - int index = 0; - int remaining = entries.length; - - int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); - if (block_count != 0) - { - for (int j = 0; j < entries.length; j += _entries_per_xbat_block) - { - blocks[ index++ ] = - new BATBlock(bigBlockSize, entries, j, - (remaining > _entries_per_xbat_block) - ? j + _entries_per_xbat_block - : entries.length); - remaining -= _entries_per_xbat_block; - } - for (index = 0; index < blocks.length - 1; index++) - { - blocks[ index ].setXBATChain(bigBlockSize, startBlock + index + 1); - } - blocks[ index ].setXBATChain(bigBlockSize, POIFSConstants.END_OF_CHAIN); - } - return blocks; - } - - /** - * Calculate how many BATBlocks are needed to hold a specified - * number of BAT entries. - * - * @param entryCount the number of entries - * - * @return the number of BATBlocks needed - */ - public static int calculateStorageRequirements(final POIFSBigBlockSize bigBlockSize, final int entryCount) - { - int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); - return (entryCount + _entries_per_block - 1) / _entries_per_block; - } - - /** - * Calculate how many XBATBlocks are needed to hold a specified - * number of BAT entries. - * - * @param entryCount the number of entries - * - * @return the number of XBATBlocks needed - */ - public static int calculateXBATStorageRequirements(final POIFSBigBlockSize bigBlockSize, final int entryCount) - { - int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); - return (entryCount + _entries_per_xbat_block - 1) - / _entries_per_xbat_block; - } - - /** - * Calculates the maximum size of a file which is addressable given the - * number of FAT (BAT) sectors specified. (We don't care if those BAT - * blocks come from the 109 in the header, or from header + XBATS, it - * won't affect the calculation) - * - * The actual file size will be between [size of fatCount-1 blocks] and - * [size of fatCount blocks]. - * For 512 byte block sizes, this means we may over-estimate by up to 65kb. - * For 4096 byte block sizes, this means we may over-estimate by up to 4mb - */ - public static long calculateMaximumSize(final POIFSBigBlockSize bigBlockSize, - final int numBATs) { - // Header isn't FAT addressed - long size = 1; - - // The header has up to 109 BATs, and extra ones are referenced - // from XBATs - // However, all BATs can contain 128/1024 blocks - size += (((long)numBATs) * bigBlockSize.getBATEntriesPerBlock()); - - // So far we've been in sector counts, turn into bytes - return size * bigBlockSize.getBigBlockSize(); - } - public static long calculateMaximumSize(final HeaderBlock header) - { - return calculateMaximumSize(header.getBigBlockSize(), header.getBATCount()); - } - - /** - * Returns the BATBlock that handles the specified offset, - * and the relative index within it. - * The List of BATBlocks must be in sequential order - */ - public static BATBlockAndIndex getBATBlockAndIndex(final int offset, - final HeaderBlock header, final List bats) { - POIFSBigBlockSize bigBlockSize = header.getBigBlockSize(); - int entriesPerBlock = bigBlockSize.getBATEntriesPerBlock(); - - int whichBAT = offset / entriesPerBlock; - int index = offset % entriesPerBlock; - return new BATBlockAndIndex( index, bats.get(whichBAT) ); - } - - /** - * Returns the BATBlock that handles the specified offset, - * and the relative index within it, for the mini stream. - * The List of BATBlocks must be in sequential order - */ - public static BATBlockAndIndex getSBATBlockAndIndex(final int offset, - final HeaderBlock header, final List sbats) { - POIFSBigBlockSize bigBlockSize = header.getBigBlockSize(); - int entriesPerBlock = bigBlockSize.getBATEntriesPerBlock(); - - // SBATs are so much easier, as they're chained streams - int whichSBAT = offset / entriesPerBlock; - int index = offset % entriesPerBlock; - return new BATBlockAndIndex( index, sbats.get(whichSBAT) ); - } - - private void setXBATChain(final POIFSBigBlockSize bigBlockSize, int chainIndex) - { - int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); - _values[ _entries_per_xbat_block ] = chainIndex; - } - - /** - * Does this BATBlock have any free sectors in it, or - * is it full? - */ - public boolean hasFreeSectors() { - return _has_free_sectors; - } - /** - * How many sectors in this block are taken? - * Note that calling {@link #hasFreeSectors()} is much quicker - */ - public int getUsedSectors(boolean isAnXBAT) { - int usedSectors = 0; - int toCheck = _values.length; - if (isAnXBAT) toCheck--; // Last is a chain location - for(int k=0; k= _values.length) { - throw new ArrayIndexOutOfBoundsException( - "Unable to fetch offset " + relativeOffset + " as the " + - "BAT only contains " + _values.length + " entries" - ); - } - return _values[relativeOffset]; - } - public void setValueAt(int relativeOffset, int value) { - int oldValue = _values[relativeOffset]; - _values[relativeOffset] = value; - - // Do we need to re-compute the free? - if(value == POIFSConstants.UNUSED_BLOCK) { - _has_free_sectors = true; - return; - } - if(oldValue == POIFSConstants.UNUSED_BLOCK) { - recomputeFree(); - } - } - - /** - * Record where in the file we live - */ - public void setOurBlockIndex(int index) { - this.ourBlockIndex = index; - } - /** - * Retrieve where in the file we live - */ - public int getOurBlockIndex() { - return ourBlockIndex; - } - - - /* ********** START extension of BigBlock ********** */ - - /** - * Write the block's data to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - void writeData(final OutputStream stream) - throws IOException - { - // Save it out - stream.write( serialize() ); - } - - void writeData(final ByteBuffer block) - throws IOException - { - // Save it out - block.put( serialize() ); - } - - private byte[] serialize() { - // Create the empty array - byte[] data = new byte[ bigBlockSize.getBigBlockSize() ]; - - // Fill in the values - int offset = 0; - for(int i=0; i<_values.length; i++) { - LittleEndian.putInt(data, offset, _values[i]); - offset += LittleEndian.INT_SIZE; - } - - // Done - return data; - } - - /* ********** END extension of BigBlock ********** */ - - - public static class BATBlockAndIndex { - private final int index; - private final BATBlock block; - private BATBlockAndIndex(int index, BATBlock block) { - this.index = index; - this.block = block; - } - public int getIndex() { - return index; - } - public BATBlock getBlock() { - return block; - } - } -} - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java deleted file mode 100644 index a3fa3f9e6..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java +++ /dev/null @@ -1,103 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -/** - * Abstract base class of all POIFS block storage classes. All - * extensions of BigBlock should write 512 or 4096 bytes of data when - * requested to write their data (as per their BigBlockSize). - * - * This class has package scope, as there is no reason at this time to - * make the class public. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; - -abstract class BigBlock - implements BlockWritable -{ - /** - * Either 512 bytes ({@link POIFSConstants#SMALLER_BIG_BLOCK_SIZE}) - * or 4096 bytes ({@link POIFSConstants#LARGER_BIG_BLOCK_SIZE}) - */ - protected POIFSBigBlockSize bigBlockSize; - - protected BigBlock(POIFSBigBlockSize bigBlockSize) { - this.bigBlockSize = bigBlockSize; - } - - /** - * Default implementation of write for extending classes that - * contain their data in a simple array of bytes. - * - * @param stream the OutputStream to which the data should be - * written. - * @param data the byte array of to be written. - * - * @exception IOException on problems writing to the specified - * stream. - */ - - protected void doWriteData(final OutputStream stream, final byte [] data) - throws IOException - { - stream.write(data); - } - - /** - * Write the block's data to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - - abstract void writeData(final OutputStream stream) - throws IOException; - - /* ********** START implementation of BlockWritable ********** */ - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - - public void writeBlocks(final OutputStream stream) - throws IOException - { - writeData(stream); - } - - /* ********** END implementation of BlockWritable ********** */ -} // end abstract class BigBlock - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java b/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java deleted file mode 100644 index df872b3a7..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java +++ /dev/null @@ -1,320 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; - -import java.util.*; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.util.*; - -/** - * This class manages and creates the Block Allocation Table, which is - * basically a set of linked lists of block indices. - *

    - * Each block of the filesystem has an index. The first block, the - * header, is skipped; the first block after the header is index 0, - * the next is index 1, and so on. - *

    - * A block's index is also its index into the Block Allocation - * Table. The entry that it finds in the Block Allocation Table is the - * index of the next block in the linked list of blocks making up a - * file, or it is set to -2: end of list. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ -public final class BlockAllocationTableReader { - private static final POILogger _logger = POILogFactory.getLogger(BlockAllocationTableReader.class); - - /** - * Maximum number size (in blocks) of the allocation table as supported by - * POI.
    - * - * This constant has been chosen to help POI identify corrupted data in the - * header block (rather than crash immediately with {@link OutOfMemoryError} - * ). It's not clear if the compound document format actually specifies any - * upper limits. For files with 512 byte blocks, having an allocation table - * of 65,335 blocks would correspond to a total file size of 4GB. Needless - * to say, POI probably cannot handle files anywhere near that size. - */ - private static final int MAX_BLOCK_COUNT = 65535; - private final IntList _entries; - private POIFSBigBlockSize bigBlockSize; - - /** - * create a BlockAllocationTableReader for an existing filesystem. Side - * effect: when this method finishes, the BAT blocks will have - * been removed from the raw block list, and any blocks labeled as - * 'unused' in the block allocation table will also have been - * removed from the raw block list. - * - * @param block_count the number of BAT blocks making up the block - * allocation table - * @param block_array the array of BAT block indices from the - * filesystem's header - * @param xbat_count the number of XBAT blocks - * @param xbat_index the index of the first XBAT block - * @param raw_block_list the list of RawDataBlocks - * - * @exception IOException if, in trying to create the table, we - * encounter logic errors - */ - public BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, int block_count, int [] block_array, - int xbat_count, int xbat_index, BlockList raw_block_list) throws IOException { - this(bigBlockSize); - - sanityCheckBlockCount(block_count); - - // We want to get the whole of the FAT table - // To do this: - // * Work through raw_block_list, which points to the - // first (up to) 109 BAT blocks - // * Jump to the XBAT offset, and read in XBATs which - // point to more BAT blocks - int limit = Math.min(block_count, block_array.length); - int block_index; - - // This will hold all of the BAT blocks in order - RawDataBlock blocks[] = new RawDataBlock[ block_count ]; - - // Process the first (up to) 109 BAT blocks - for (block_index = 0; block_index < limit; block_index++) - { - // Check that the sector number of the BAT block is a valid one - int nextOffset = block_array[ block_index ]; - if(nextOffset > raw_block_list.blockCount()) { - throw new IOException("Your file contains " + raw_block_list.blockCount() + - " sectors, but the initial DIFAT array at index " + block_index + - " referenced block # " + nextOffset + ". This isn't allowed and " + - " your file is corrupt"); - } - // Record the sector number of this BAT block - blocks[ block_index ] = - ( RawDataBlock ) raw_block_list.remove(nextOffset); - } - - // Process additional BAT blocks via the XBATs - if (block_index < block_count) - { - - // must have extended blocks - if (xbat_index < 0) - { - throw new IOException( - "BAT count exceeds limit, yet XBAT index indicates no valid entries"); - } - int chain_index = xbat_index; - int max_entries_per_block = bigBlockSize.getXBATEntriesPerBlock(); - int chain_index_offset = bigBlockSize.getNextXBATChainOffset(); - - // Each XBAT block contains either: - // (maximum number of sector indexes) + index of next XBAT - // some sector indexes + FREE sectors to max # + EndOfChain - for (int j = 0; j < xbat_count; j++) - { - limit = Math.min(block_count - block_index, - max_entries_per_block); - byte[] data = raw_block_list.remove(chain_index).getData(); - int offset = 0; - - for (int k = 0; k < limit; k++) - { - blocks[ block_index++ ] = - ( RawDataBlock ) raw_block_list - .remove(LittleEndian.getInt(data, offset)); - offset += LittleEndianConsts.INT_SIZE; - } - chain_index = LittleEndian.getInt(data, chain_index_offset); - if (chain_index == POIFSConstants.END_OF_CHAIN) - { - break; - } - } - } - if (block_index != block_count) - { - throw new IOException("Could not find all blocks"); - } - - // Now that we have all of the raw data blocks which make - // up the FAT, go through and create the indices - setEntries(blocks, raw_block_list); - } - - /** - * create a BlockAllocationTableReader from an array of raw data blocks - * - * @param blocks the raw data - * @param raw_block_list the list holding the managed blocks - * - * @exception IOException - */ - BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, BlockList raw_block_list) - throws IOException { - this(bigBlockSize); - setEntries(blocks, raw_block_list); - } - - BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize) { - this.bigBlockSize = bigBlockSize; - _entries = new IntList(); - } - - public static void sanityCheckBlockCount(int block_count) throws IOException { - if (block_count <= 0) { - throw new IOException( - "Illegal block count; minimum count is 1, got " + - block_count + " instead" - ); - } - if (block_count > MAX_BLOCK_COUNT) { - throw new IOException( - "Block count " + block_count + - " is too high. POI maximum is " + MAX_BLOCK_COUNT + "." - ); - } - } - - /** - * walk the entries from a specified point and return the - * associated blocks. The associated blocks are removed from the - * block list - * - * @param startBlock the first block in the chain - * @param blockList the raw data block list - * - * @return array of ListManagedBlocks, in their correct order - * - * @exception IOException if there is a problem acquiring the blocks - */ - ListManagedBlock[] fetchBlocks(int startBlock, int headerPropertiesStartBlock, - BlockList blockList) throws IOException { - List blocks = new ArrayList(); - int currentBlock = startBlock; - boolean firstPass = true; - ListManagedBlock dataBlock = null; - - // Process the chain from the start to the end - // Normally we have header, data, end - // Sometimes we have data, header, end - // For those cases, stop at the header, not the end - while (currentBlock != POIFSConstants.END_OF_CHAIN) { - try { - // Grab the data at the current block offset - dataBlock = blockList.remove(currentBlock); - blocks.add(dataBlock); - // Now figure out which block we go to next - currentBlock = _entries.get(currentBlock); - firstPass = false; - } catch(IOException e) { - if(currentBlock == headerPropertiesStartBlock) { - // Special case where things are in the wrong order - _logger.log(POILogger.WARN, "Warning, header block comes after data blocks in POIFS block listing"); - currentBlock = POIFSConstants.END_OF_CHAIN; - } else if(currentBlock == 0 && firstPass) { - // Special case where the termination isn't done right - // on an empty set - _logger.log(POILogger.WARN, "Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)"); - currentBlock = POIFSConstants.END_OF_CHAIN; - } else { - // Ripple up - throw e; - } - } - } - - return blocks.toArray(new ListManagedBlock[blocks.size()]); - } - - // methods for debugging reader - - /** - * determine whether the block specified by index is used or not - * - * @param index index of block in question - * - * @return true if the specific block is used, else false - */ - boolean isUsed(int index) { - - try { - return _entries.get(index) != -1; - } catch (IndexOutOfBoundsException e) { - // ignored - return false; - } - } - - /** - * return the next block index - * - * @param index of the current block - * - * @return index of the next block (may be - * POIFSConstants.END_OF_CHAIN, indicating end of chain - * (duh)) - * - * @exception IOException if the current block is unused - */ - int getNextBlockIndex(int index) throws IOException { - if (isUsed(index)) { - return _entries.get(index); - } - throw new IOException("index " + index + " is unused"); - } - - /** - * Convert an array of blocks into a set of integer indices - * - * @param blocks the array of blocks containing the indices - * @param raw_blocks the list of blocks being managed. Unused - * blocks will be eliminated from the list - */ - private void setEntries(ListManagedBlock[] blocks, BlockList raw_blocks) throws IOException { - int limit = bigBlockSize.getBATEntriesPerBlock(); - - for (int block_index = 0; block_index < blocks.length; block_index++) - { - byte[] data = blocks[ block_index ].getData(); - int offset = 0; - - for (int k = 0; k < limit; k++) - { - int entry = LittleEndian.getInt(data, offset); - - if (entry == POIFSConstants.UNUSED_BLOCK) - { - raw_blocks.zap(_entries.size()); - } - _entries.add(entry); - offset += LittleEndianConsts.INT_SIZE; - } - - // discard block - blocks[ block_index ] = null; - } - raw_blocks.setBAT(this); - } - - @Internal - public IntList getEntries() { - return _entries; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java b/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java deleted file mode 100644 index e037b892d..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.filesystem.BATManaged; -import org.apache.poi.util.IntList; - -/** - * This class manages and creates the Block Allocation Table, which is - * basically a set of linked lists of block indices. - *

    - * Each block of the filesystem has an index. The first block, the - * header, is skipped; the first block after the header is index 0, - * the next is index 1, and so on. - *

    - * A block's index is also its index into the Block Allocation - * Table. The entry that it finds in the Block Allocation Table is the - * index of the next block in the linked list of blocks making up a - * file, or it is set to -2: end of list. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ -public final class BlockAllocationTableWriter implements BlockWritable, BATManaged { - private IntList _entries; - private BATBlock[] _blocks; - private int _start_block; - private POIFSBigBlockSize _bigBlockSize; - - /** - * create a BlockAllocationTableWriter - */ - public BlockAllocationTableWriter(POIFSBigBlockSize bigBlockSize) - { - _bigBlockSize = bigBlockSize; - _start_block = POIFSConstants.END_OF_CHAIN; - _entries = new IntList(); - _blocks = new BATBlock[ 0 ]; - } - - /** - * Create the BATBlocks we need - * - * @return start block index of BAT blocks - */ - public int createBlocks() - { - int xbat_blocks = 0; - int bat_blocks = 0; - - while (true) - { - int calculated_bat_blocks = - BATBlock.calculateStorageRequirements(_bigBlockSize, - bat_blocks - + xbat_blocks - + _entries.size()); - int calculated_xbat_blocks = - HeaderBlockWriter.calculateXBATStorageRequirements( - _bigBlockSize, calculated_bat_blocks); - - if ((bat_blocks == calculated_bat_blocks) - && (xbat_blocks == calculated_xbat_blocks)) - { - - // stable ... we're OK - break; - } - bat_blocks = calculated_bat_blocks; - xbat_blocks = calculated_xbat_blocks; - } - int startBlock = allocateSpace(bat_blocks); - - allocateSpace(xbat_blocks); - simpleCreateBlocks(); - return startBlock; - } - - /** - * Allocate space for a block of indices - * - * @param blockCount the number of blocks to allocate space for - * - * @return the starting index of the blocks - */ - public int allocateSpace(final int blockCount) - { - int startBlock = _entries.size(); - - if (blockCount > 0) - { - int limit = blockCount - 1; - int index = startBlock + 1; - - for (int k = 0; k < limit; k++) - { - _entries.add(index++); - } - _entries.add(POIFSConstants.END_OF_CHAIN); - } - return startBlock; - } - - /** - * get the starting block - * - * @return the starting block index - */ - public int getStartBlock() - { - return _start_block; - } - - /** - * create the BATBlocks - */ - void simpleCreateBlocks() - { - _blocks = BATBlock.createBATBlocks(_bigBlockSize, _entries.toArray()); - } - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - public void writeBlocks(final OutputStream stream) - throws IOException - { - for (int j = 0; j < _blocks.length; j++) - { - _blocks[ j ].writeBlocks(stream); - } - } - - /** - * Write the BAT into its associated block - */ - public static void writeBlock(final BATBlock bat, final ByteBuffer block) - throws IOException - { - bat.writeData(block); - } - - /** - * Return the number of BigBlock's this instance uses - * - * @return count of BigBlock instances - */ - public int countBlocks() - { - return _blocks.length; - } - - /** - * Set the start block for this instance - */ - public void setStartBlock(int start_block) - { - _start_block = start_block; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java b/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java deleted file mode 100644 index dfbd69c2a..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java +++ /dev/null @@ -1,83 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import java.io.IOException; - -/** - * Interface for lists of blocks that are mapped by block allocation - * tables - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public interface BlockList -{ - - /** - * remove the specified block from the list - * - * @param index the index of the specified block; if the index is - * out of range, that's ok - */ - - void zap(final int index); - - /** - * remove and return the specified block from the list - * - * @param index the index of the specified block - * - * @return the specified block - * - * @exception IOException if the index is out of range or has - * already been removed - */ - - ListManagedBlock remove(final int index) throws IOException; - - /** - * get the blocks making up a particular stream in the list. The - * blocks are removed from the list. - * - * @param startBlock the index of the first block in the stream - * @param headerPropertiesStartBlock the index of the first header block in the stream - * - * @return the stream as an array of correctly ordered blocks - * - * @exception IOException if blocks are missing - */ - - ListManagedBlock [] fetchBlocks(final int startBlock, final int headerPropertiesStartBlock) - throws IOException; - - /** - * set the associated BlockAllocationTable - * - * @param bat the associated BlockAllocationTable - * - * @exception IOException - */ - - void setBAT(final BlockAllocationTableReader bat) throws IOException; - - int blockCount(); -} // end public interface BlockList - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java b/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java deleted file mode 100644 index f3d459e38..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; - -import org.apache.poi.util.Internal; - -/** - * A simple implementation of BlockList - * - * @author Marc Johnson (mjohnson at apache dot org - */ -abstract class BlockListImpl implements BlockList { - private ListManagedBlock[] _blocks; - private BlockAllocationTableReader _bat; - - protected BlockListImpl() - { - _blocks = new ListManagedBlock[ 0 ]; - _bat = null; - } - - /** - * provide blocks to manage - * - * @param blocks blocks to be managed - */ - protected void setBlocks(final ListManagedBlock [] blocks) - { - _blocks = blocks.clone(); - } - - /** - * remove the specified block from the list - * - * @param index the index of the specified block; if the index is - * out of range, that's ok - */ - public void zap(final int index) - { - if ((index >= 0) && (index < _blocks.length)) - { - _blocks[ index ] = null; - } - } - - /** - * Internal method. Gets, without sanity checks or - * removing. - */ - @Internal - public ListManagedBlock get(final int index) { - return _blocks[index]; - } - - /** - * remove and return the specified block from the list - * - * @param index the index of the specified block - * - * @return the specified block - * - * @exception IOException if the index is out of range or has - * already been removed - */ - public ListManagedBlock remove(final int index) - throws IOException - { - ListManagedBlock result = null; - - try - { - result = _blocks[ index ]; - if (result == null) - { - throw new IOException( - "block[ " + index + " ] already removed - " + - "does your POIFS have circular or duplicate block references?" - ); - } - _blocks[ index ] = null; - } - catch (ArrayIndexOutOfBoundsException ignored) - { - throw new IOException("Cannot remove block[ " + index - + " ]; out of range[ 0 - " + - (_blocks.length-1) + " ]"); - } - return result; - } - - /** - * get the blocks making up a particular stream in the list. The - * blocks are removed from the list. - * - * @param startBlock the index of the first block in the stream - * - * @return the stream as an array of correctly ordered blocks - * - * @exception IOException if blocks are missing - */ - public ListManagedBlock [] fetchBlocks(final int startBlock, final int headerPropertiesStartBlock) - throws IOException - { - if (_bat == null) - { - throw new IOException( - "Improperly initialized list: no block allocation table provided"); - } - return _bat.fetchBlocks(startBlock, headerPropertiesStartBlock, this); - } - - /** - * set the associated BlockAllocationTable - * - * @param bat the associated BlockAllocationTable - */ - public void setBAT(final BlockAllocationTableReader bat) - throws IOException - { - if (_bat != null) - { - throw new IOException( - "Attempt to replace existing BlockAllocationTable"); - } - _bat = bat; - } - - /** - * Returns the count of the number of blocks - */ - public int blockCount() { - return _blocks.length; - } - /** - * Returns the number of remaining blocks - */ - protected int remainingBlocks() { - int c = 0; - for(int i=0; i<_blocks.length; i++) { - if(_blocks[i] != null) c++; - } - return c; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/BlockWritable.java b/trunk/src/java/org/apache/poi/poifs/storage/BlockWritable.java deleted file mode 100644 index 3bf833ec1..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/BlockWritable.java +++ /dev/null @@ -1,46 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An interface for persisting block storage of POIFS components. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public interface BlockWritable -{ - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - - void writeBlocks(final OutputStream stream) throws IOException; -} // end public interface BlockWritable - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/DataInputBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/DataInputBlock.java deleted file mode 100644 index 0710b4ee7..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/DataInputBlock.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -/** - * Wraps a byte array and provides simple data input access. - * Internally, this class maintains a buffer read index, so that for the most part, primitive - * data can be read in a data-input-stream-like manner.

    - * - * Note - the calling class should call the {@link #available()} method to detect end-of-buffer - * and move to the next data block when the current is exhausted. - * For optimisation reasons, no error handling is performed in this class. Thus, mistakes in - * calling code ran may raise ugly exceptions here, like {@link ArrayIndexOutOfBoundsException}, - * etc .

    - * - * The multi-byte primitive input methods ({@link #readUShortLE()}, {@link #readIntLE()} and - * {@link #readLongLE()}) have corresponding 'spanning read' methods which (when required) perform - * a read across the block boundary. These spanning read methods take the previous - * {@link DataInputBlock} as a parameter. - * Reads of larger amounts of data (into byte array buffers) must be managed by the caller - * since these could conceivably involve more than two blocks. - * - * @author Josh Micich - */ -public final class DataInputBlock { - - /** - * Possibly any size (usually 512K or 64K). Assumed to be at least 8 bytes for all blocks - * before the end of the stream. The last block in the stream can be any size except zero. - */ - private final byte[] _buf; - private int _readIndex; - private int _maxIndex; - - DataInputBlock(byte[] data, int startOffset) { // NOSONAR - _buf = data; - _readIndex = startOffset; - _maxIndex = _buf.length; - } - public int available() { - return _maxIndex-_readIndex; - } - - public int readUByte() { - return _buf[_readIndex++] & 0xFF; - } - - /** - * Reads a short which was encoded in little endian format. - */ - public int readUShortLE() { - int i = _readIndex; - - int b0 = _buf[i++] & 0xFF; - int b1 = _buf[i++] & 0xFF; - _readIndex = i; - return (b1 << 8) + (b0 << 0); - } - - /** - * Reads a short which spans the end of prevBlock and the start of this block. - */ - public int readUShortLE(DataInputBlock prevBlock) { - // simple case - will always be one byte in each block - int i = prevBlock._buf.length-1; - - int b0 = prevBlock._buf[i] & 0xFF; - int b1 = _buf[_readIndex++] & 0xFF; - return (b1 << 8) + (b0 << 0); - } - - /** - * Reads an int which was encoded in little endian format. - */ - public int readIntLE() { - int i = _readIndex; - - int b0 = _buf[i++] & 0xFF; - int b1 = _buf[i++] & 0xFF; - int b2 = _buf[i++] & 0xFF; - int b3 = _buf[i++] & 0xFF; - _readIndex = i; - return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0); - } - - /** - * Reads an int which spans the end of prevBlock and the start of this block. - */ - public int readIntLE(DataInputBlock prevBlock, int prevBlockAvailable) { - byte[] buf = new byte[4]; - - readSpanning(prevBlock, prevBlockAvailable, buf); - int b0 = buf[0] & 0xFF; - int b1 = buf[1] & 0xFF; - int b2 = buf[2] & 0xFF; - int b3 = buf[3] & 0xFF; - return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0); - } - - /** - * Reads a long which was encoded in little endian format. - */ - public long readLongLE() { - int i = _readIndex; - - int b0 = _buf[i++] & 0xFF; - int b1 = _buf[i++] & 0xFF; - int b2 = _buf[i++] & 0xFF; - int b3 = _buf[i++] & 0xFF; - int b4 = _buf[i++] & 0xFF; - int b5 = _buf[i++] & 0xFF; - int b6 = _buf[i++] & 0xFF; - int b7 = _buf[i++] & 0xFF; - _readIndex = i; - return (((long)b7 << 56) + - ((long)b6 << 48) + - ((long)b5 << 40) + - ((long)b4 << 32) + - ((long)b3 << 24) + - (b2 << 16) + - (b1 << 8) + - (b0 << 0)); - } - - /** - * Reads a long which spans the end of prevBlock and the start of this block. - */ - public long readLongLE(DataInputBlock prevBlock, int prevBlockAvailable) { - byte[] buf = new byte[8]; - - readSpanning(prevBlock, prevBlockAvailable, buf); - - int b0 = buf[0] & 0xFF; - int b1 = buf[1] & 0xFF; - int b2 = buf[2] & 0xFF; - int b3 = buf[3] & 0xFF; - int b4 = buf[4] & 0xFF; - int b5 = buf[5] & 0xFF; - int b6 = buf[6] & 0xFF; - int b7 = buf[7] & 0xFF; - return (((long)b7 << 56) + - ((long)b6 << 48) + - ((long)b5 << 40) + - ((long)b4 << 32) + - ((long)b3 << 24) + - (b2 << 16) + - (b1 << 8) + - (b0 << 0)); - } - - /** - * Reads a small amount of data from across the boundary between two blocks. - * The {@link #_readIndex} of this (the second) block is updated accordingly. - * Note- this method (and other code) assumes that the second {@link DataInputBlock} - * always is big enough to complete the read without being exhausted. - */ - private void readSpanning(DataInputBlock prevBlock, int prevBlockAvailable, byte[] buf) { - System.arraycopy(prevBlock._buf, prevBlock._readIndex, buf, 0, prevBlockAvailable); - int secondReadLen = buf.length-prevBlockAvailable; - System.arraycopy(_buf, 0, buf, prevBlockAvailable, secondReadLen); - _readIndex = secondReadLen; - } - - /** - * Reads len bytes from this block into the supplied buffer. - */ - public void readFully(byte[] buf, int off, int len) { - System.arraycopy(_buf, _readIndex, buf, off, len); - _readIndex += len; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java deleted file mode 100644 index a7c568625..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java +++ /dev/null @@ -1,200 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.util.IOUtils; - -/** - * A block of document data. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ -public final class DocumentBlock extends BigBlock { - private static final byte _default_value = ( byte ) 0xFF; - private byte[] _data; - private int _bytes_read; - - /** - * create a document block from a raw data block - * - * @param block the raw data block - * - * @exception IOException - */ - - public DocumentBlock(final RawDataBlock block) - throws IOException - { - super( - block.getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ? - POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS : - POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS - ); - _data = block.getData(); - _bytes_read = _data.length; - } - - /** - * Create a single instance initialized with data. - * - * @param stream the InputStream delivering the data. - * - * @exception IOException - */ - - public DocumentBlock(final InputStream stream, POIFSBigBlockSize bigBlockSize) - throws IOException - { - this(bigBlockSize); - int count = IOUtils.readFully(stream, _data); - - _bytes_read = (count == -1) ? 0 - : count; - } - - /** - * Create a single instance initialized with default values - */ - - private DocumentBlock(POIFSBigBlockSize bigBlockSize) - { - super(bigBlockSize); - _data = new byte[ bigBlockSize.getBigBlockSize() ]; - Arrays.fill(_data, _default_value); - } - - /** - * Get the number of bytes read for this block - * - * @return bytes read into the block - */ - - public int size() - { - return _bytes_read; - } - - /** - * Was this a partially read block? - * - * @return true if the block was only partially filled with data - */ - - public boolean partiallyRead() - { - return _bytes_read != bigBlockSize.getBigBlockSize(); - } - - /** - * @return the fill byte used - */ - - public static byte getFillByte() - { - return _default_value; - } - - /** - * convert a single long array into an array of DocumentBlock - * instances - * - * @param array the byte array to be converted - * @param size the intended size of the array (which may be smaller) - * - * @return an array of DocumentBlock instances, filled from the - * input array - */ - - public static DocumentBlock [] convert(final POIFSBigBlockSize bigBlockSize, - final byte [] array, - final int size) - { - DocumentBlock[] rval = - new DocumentBlock[ (size + bigBlockSize.getBigBlockSize() - 1) / bigBlockSize.getBigBlockSize() ]; - int offset = 0; - - for (int k = 0; k < rval.length; k++) - { - rval[ k ] = new DocumentBlock(bigBlockSize); - if (offset < array.length) - { - int length = Math.min(bigBlockSize.getBigBlockSize(), - array.length - offset); - - System.arraycopy(array, offset, rval[ k ]._data, 0, length); - if (length != bigBlockSize.getBigBlockSize()) - { - Arrays.fill(rval[ k ]._data, length, - bigBlockSize.getBigBlockSize(), - _default_value); - } - } - else - { - Arrays.fill(rval[ k ]._data, _default_value); - } - offset += bigBlockSize.getBigBlockSize(); - } - return rval; - } - - public static DataInputBlock getDataInputBlock(DocumentBlock[] blocks, int offset) { - if(blocks == null || blocks.length == 0) { - return null; - } - - // Key things about the size of the block - POIFSBigBlockSize bigBlockSize = blocks[0].bigBlockSize; - int BLOCK_SHIFT = bigBlockSize.getHeaderValue(); - int BLOCK_SIZE = bigBlockSize.getBigBlockSize(); - int BLOCK_MASK = BLOCK_SIZE - 1; - - // Now do the offset lookup - int firstBlockIndex = offset >> BLOCK_SHIFT; - int firstBlockOffset= offset & BLOCK_MASK; - return new DataInputBlock(blocks[firstBlockIndex]._data, firstBlockOffset); - } - - /* ********** START extension of BigBlock ********** */ - - /** - * Write the block's data to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - - void writeData(final OutputStream stream) - throws IOException - { - doWriteData(stream, _data); - } - - /* ********** END extension of BigBlock ********** */ -} // end public class DocumentBlock - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlock.java deleted file mode 100644 index aced76bbe..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlock.java +++ /dev/null @@ -1,435 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; - -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.filesystem.NotOLE2FileException; -import org.apache.poi.poifs.filesystem.OfficeXmlFileException; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.IntegerField; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.LongField; -import org.apache.poi.util.ShortField; - -/** - * The block containing the archive header - */ -public final class HeaderBlock implements HeaderBlockConstants { - private static final byte[] MAGIC_BIFF2 = { - 0x09, 0x00, // sid=0x0009 - 0x04, 0x00, // size=0x0004 - 0x00, 0x00, // unused - 0x70, 0x00 // 0x70 = multiple values - }; - - private static final byte[] MAGIC_BIFF3 = { - 0x09, 0x02, // sid=0x0209 - 0x06, 0x00, // size=0x0006 - 0x00, 0x00, // unused - 0x70, 0x00 // 0x70 = multiple values - }; - - private static final byte[] MAGIC_BIFF4a = { - 0x09, 0x04, // sid=0x0409 - 0x06, 0x00, // size=0x0006 - 0x00, 0x00, // unused - 0x70, 0x00 // 0x70 = multiple values - }; - - private static final byte[] MAGIC_BIFF4b = { - 0x09, 0x04, // sid=0x0409 - 0x06, 0x00, // size=0x0006 - 0x00, 0x00, // unused - 0x00, 0x01 - }; - - private static final byte _default_value = ( byte ) 0xFF; - - /** - * What big block size the file uses. Most files - * use 512 bytes, but a few use 4096 - */ - private final POIFSBigBlockSize bigBlockSize; - - /** - * Number of big block allocation table blocks (int). - * (Number of FAT Sectors in Microsoft parlance). - */ - private int _bat_count; - - /** - * Start of the property set block (int index of the property set - * chain's first big block). - */ - private int _property_start; - - /** - * start of the small block allocation table (int index of small - * block allocation table's first big block) - */ - private int _sbat_start; - /** - * Number of small block allocation table blocks (int) - * (Number of MiniFAT Sectors in Microsoft parlance) - */ - private int _sbat_count; - - /** - * Big block index for extension to the big block allocation table - */ - private int _xbat_start; - /** - * Number of big block allocation table blocks (int) - * (Number of DIFAT Sectors in Microsoft parlance) - */ - private int _xbat_count; - - /** - * The data. Only ever 512 bytes, because 4096 byte - * files use zeros for the extra header space. - */ - private final byte[] _data; - - /** - * create a new HeaderBlockReader from an InputStream - * - * @param stream the source InputStream - * - * @exception IOException on errors or bad data - */ - public HeaderBlock(InputStream stream) throws IOException { - // Grab the first 512 bytes - // (For 4096 sized blocks, the remaining 3584 bytes are zero) - // Then, process the contents - this(readFirst512(stream)); - - // Fetch the rest of the block if needed - if(bigBlockSize.getBigBlockSize() != 512) { - int rest = bigBlockSize.getBigBlockSize() - 512; - byte[] tmp = new byte[rest]; - IOUtils.readFully(stream, tmp); - } - } - - public HeaderBlock(ByteBuffer buffer) throws IOException { - this(IOUtils.toByteArray(buffer, POIFSConstants.SMALLER_BIG_BLOCK_SIZE)); - } - - private HeaderBlock(byte[] data) throws IOException { - this._data = data.clone(); - - // verify signature - long signature = LittleEndian.getLong(_data, _signature_offset); - - if (signature != _signature) { - // Is it one of the usual suspects? - if (cmp(POIFSConstants.OOXML_FILE_HEADER, data)) { - throw new OfficeXmlFileException("The supplied data appears to be in the Office 2007+ XML. " - + "You are calling the part of POI that deals with OLE2 Office Documents. " - + "You need to call a different part of POI to process this data (eg XSSF instead of HSSF)"); - } - - if (cmp(POIFSConstants.RAW_XML_FILE_HEADER, data)) { - throw new NotOLE2FileException("The supplied data appears to be a raw XML file. " - + "Formats such as Office 2003 XML are not supported"); - } - - // BIFF2 raw stream - if (cmp(MAGIC_BIFF2, data)) { - throw new OldExcelFormatException("The supplied data appears to be in BIFF2 format. " - + "HSSF only supports the BIFF8 format, try OldExcelExtractor"); - } - - // BIFF3 raw stream - if (cmp(MAGIC_BIFF3, data)) { - throw new OldExcelFormatException("The supplied data appears to be in BIFF3 format. " - + "HSSF only supports the BIFF8 format, try OldExcelExtractor"); - } - - // BIFF4 raw stream - if (cmp(MAGIC_BIFF4a, data) || cmp(MAGIC_BIFF4b, data)) { - throw new OldExcelFormatException("The supplied data appears to be in BIFF4 format. " - + "HSSF only supports the BIFF8 format, try OldExcelExtractor"); - } - - // Give a generic error if the OLE2 signature isn't found - throw new NotOLE2FileException("Invalid header signature; read " - + HexDump.longToHex(signature) + ", expected " - + HexDump.longToHex(_signature) + " - Your file appears " - + "not to be a valid OLE2 document"); - } - - - // Figure out our block size - if (_data[30] == 12) { - this.bigBlockSize = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS; - } else if(_data[30] == 9) { - this.bigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; - } else { - throw new IOException("Unsupported blocksize (2^"+ _data[30] + "). Expected 2^9 or 2^12."); - } - - // Setup the fields to read and write the counts and starts - _bat_count = new IntegerField(_bat_count_offset, data).get(); - _property_start = new IntegerField(_property_start_offset,_data).get(); - _sbat_start = new IntegerField(_sbat_start_offset, _data).get(); - _sbat_count = new IntegerField(_sbat_block_count_offset, _data).get(); - _xbat_start = new IntegerField(_xbat_start_offset, _data).get(); - _xbat_count = new IntegerField(_xbat_count_offset, _data).get(); - } - - /** - * Create a single instance initialized with default values - */ - public HeaderBlock(POIFSBigBlockSize bigBlockSize) - { - this.bigBlockSize = bigBlockSize; - - // Our data is always 512 big no matter what - _data = new byte[ POIFSConstants.SMALLER_BIG_BLOCK_SIZE ]; - Arrays.fill(_data, _default_value); - - // Set all the default values - new LongField(_signature_offset, _signature, _data); - new IntegerField(0x08, 0, _data); - new IntegerField(0x0c, 0, _data); - new IntegerField(0x10, 0, _data); - new IntegerField(0x14, 0, _data); - new ShortField(0x18, ( short ) 0x3b, _data); - new ShortField(0x1a, ( short ) 0x3, _data); - new ShortField(0x1c, ( short ) -2, _data); - - new ShortField(0x1e, bigBlockSize.getHeaderValue(), _data); - new IntegerField(0x20, 0x6, _data); - new IntegerField(0x24, 0, _data); - new IntegerField(0x28, 0, _data); - new IntegerField(0x34, 0, _data); - new IntegerField(0x38, 0x1000, _data); - - // Initialize the variables - _bat_count = 0; - _sbat_count = 0; - _xbat_count = 0; - _property_start = POIFSConstants.END_OF_CHAIN; - _sbat_start = POIFSConstants.END_OF_CHAIN; - _xbat_start = POIFSConstants.END_OF_CHAIN; - } - - private static byte[] readFirst512(InputStream stream) throws IOException { - // Grab the first 512 bytes - // (For 4096 sized blocks, the remaining 3584 bytes are zero) - byte[] data = new byte[512]; - int bsCount = IOUtils.readFully(stream, data); - if(bsCount != 512) { - throw alertShortRead(bsCount, 512); - } - return data; - } - - private static IOException alertShortRead(int pRead, int expectedReadSize) { - int read; - if (pRead < 0) { - //Can't have -1 bytes read in the error message! - read = 0; - } else { - read = pRead; - } - String type = " byte" + (read == 1 ? (""): ("s")); - - return new IOException("Unable to read entire header; " - + read + type + " read; expected " - + expectedReadSize + " bytes"); - } - - /** - * get start of Property Table - * - * @return the index of the first block of the Property Table - */ - public int getPropertyStart() { - return _property_start; - } - /** - * Set start of Property Table - * - * @param startBlock the index of the first block of the Property Table - */ - public void setPropertyStart(final int startBlock) { - _property_start = startBlock; - } - - /** - * @return start of small block (MiniFAT) allocation table - */ - public int getSBATStart() { - return _sbat_start; - } - public int getSBATCount() { - return _sbat_count; - } - - /** - * Set start of small block allocation table - * - * @param startBlock the index of the first big block of the small - * block allocation table - */ - public void setSBATStart(final int startBlock) { - _sbat_start = startBlock; - } - /** - * Set count of SBAT blocks - * - * @param count the number of SBAT blocks - */ - public void setSBATBlockCount(final int count) - { - _sbat_count = count; - } - - /** - * @return number of BAT blocks - */ - public int getBATCount() { - return _bat_count; - } - /** - * Sets the number of BAT blocks that are used. - * This is the number used in both the BAT and XBAT. - */ - public void setBATCount(final int count) { - _bat_count = count; - } - - /** - * Returns the offsets to the first (up to) 109 - * BAT sectors. - * Any additional BAT sectors are held in the XBAT (DIFAT) - * sectors in a chain. - * @return BAT offset array - */ - public int[] getBATArray() { - // Read them in - int[] result = new int[ Math.min(_bat_count,_max_bats_in_header) ]; - int offset = _bat_array_offset; - for (int j = 0; j < result.length; j++) { - result[ j ] = LittleEndian.getInt(_data, offset); - offset += LittleEndianConsts.INT_SIZE; - } - return result; - } - /** - * Sets the offsets of the first (up to) 109 - * BAT sectors. - */ - public void setBATArray(int[] bat_array) { - int count = Math.min(bat_array.length, _max_bats_in_header); - int blank = _max_bats_in_header - count; - - int offset = _bat_array_offset; - for(int i=0; i _max_bats_in_header) - { - int excess_blocks = blockCount - _max_bats_in_header; - int[] excess_block_array = new int[ excess_blocks ]; - - for (int j = 0; j < excess_blocks; j++) - { - excess_block_array[ j ] = startBlock + j - + _max_bats_in_header; - } - rvalue = BATBlock.createXBATBlocks(bigBlockSize, excess_block_array, - startBlock + blockCount); - _header_block.setXBATStart(startBlock + blockCount); - } - else - { - rvalue = BATBlock.createXBATBlocks(bigBlockSize, new int[ 0 ], 0); - _header_block.setXBATStart(POIFSConstants.END_OF_CHAIN); - } - _header_block.setXBATCount(rvalue.length); - return rvalue; - } - - /** - * Set start of Property Table - * - * @param startBlock the index of the first block of the Property - * Table - */ - public void setPropertyStart(final int startBlock) - { - _header_block.setPropertyStart(startBlock); - } - - /** - * Set start of small block allocation table - * - * @param startBlock the index of the first big block of the small - * block allocation table - */ - public void setSBATStart(final int startBlock) - { - _header_block.setSBATStart(startBlock); - } - - /** - * Set count of SBAT blocks - * - * @param count the number of SBAT blocks - */ - public void setSBATBlockCount(final int count) - { - _header_block.setSBATBlockCount(count); - } - - /** - * For a given number of BAT blocks, calculate how many XBAT - * blocks will be needed - * - * @param blockCount number of BAT blocks - * - * @return number of XBAT blocks needed - */ - - static int calculateXBATStorageRequirements(POIFSBigBlockSize bigBlockSize, final int blockCount) - { - return (blockCount > _max_bats_in_header) - ? BATBlock.calculateXBATStorageRequirements( - bigBlockSize, blockCount - _max_bats_in_header) - : 0; - } - - /* ********** START extension of BigBlock ********** */ - - /** - * Write the block's data to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - public void writeBlocks(final OutputStream stream) - throws IOException - { - _header_block.writeData(stream); - } - - /** - * Write the block's data to an existing block - * - * @param block the ByteBuffer of the block to which the - * stored data should be written - * - * @exception IOException on problems writing to the block - */ - public void writeBlock(ByteBuffer block) - throws IOException - { - ByteArrayOutputStream baos = new ByteArrayOutputStream( - _header_block.getBigBlockSize().getBigBlockSize() - ); - _header_block.writeData(baos); - - block.put(baos.toByteArray()); - } - - /* ********** END extension of BigBlock ********** */ -} // end public class HeaderBlockWriter - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/ListManagedBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/ListManagedBlock.java deleted file mode 100644 index 3d582d262..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/ListManagedBlock.java +++ /dev/null @@ -1,45 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import java.io.IOException; - -/** - * An interface for blocks managed by a list that works with a - * BlockAllocationTable to keep block sequences straight - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public interface ListManagedBlock -{ - - /** - * Get the data from the block - * - * @return the block's data as a byte array - * - * @exception IOException if there is no data - */ - - public byte [] getData() - throws IOException; -} // end public interface ListManagedBlock - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java deleted file mode 100644 index c824166bf..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.property.Property; - -/** - * A block of Property instances - * - * @author Marc Johnson (mjohnson at apache dot org) - */ -public final class PropertyBlock extends BigBlock { - private Property[] _properties; - - /** - * Create a single instance initialized with default values - * - * @param properties the properties to be inserted - * @param offset the offset into the properties array - */ - - private PropertyBlock(final POIFSBigBlockSize bigBlockSize, final Property [] properties, final int offset) - { - super(bigBlockSize); - - _properties = new Property[ bigBlockSize.getPropertiesPerBlock() ]; - for (int j = 0; j < _properties.length; j++) - { - _properties[ j ] = properties[ j + offset ]; - } - } - - /** - * Create an array of PropertyBlocks from an array of Property - * instances, creating empty Property instances to make up any - * shortfall - * - * @param properties the Property instances to be converted into - * PropertyBlocks, in a java List - * - * @return the array of newly created PropertyBlock instances - */ - - public static BlockWritable [] createPropertyBlockArray( - final POIFSBigBlockSize bigBlockSize, final List properties) - { - int _properties_per_block = bigBlockSize.getPropertiesPerBlock(); - int block_count = - (properties.size() + _properties_per_block - 1) - / _properties_per_block; - Property[] to_be_written = - new Property[ block_count * _properties_per_block ]; - - System.arraycopy(properties.toArray(new Property[ 0 ]), 0, - to_be_written, 0, properties.size()); - for (int j = properties.size(); j < to_be_written.length; j++) - { - - // create an instance of an anonymous inner class that - // extends Property - to_be_written[ j ] = new Property() - { - protected void preWrite() - { - } - - public boolean isDirectory() - { - return false; - } - }; - } - BlockWritable[] rvalue = new BlockWritable[ block_count ]; - - for (int j = 0; j < block_count; j++) - { - rvalue[ j ] = new PropertyBlock(bigBlockSize, to_be_written, - j * _properties_per_block); - } - return rvalue; - } - - /* ********** START extension of BigBlock ********** */ - - /** - * Write the block's data to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - - void writeData(final OutputStream stream) - throws IOException - { - int _properties_per_block = bigBlockSize.getPropertiesPerBlock(); - for (int j = 0; j < _properties_per_block; j++) - { - _properties[ j ].writeData(stream); - } - } - - /* ********** END extension of BigBlock ********** */ -} // end public class PropertyBlock - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java deleted file mode 100644 index 923e76fac..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java +++ /dev/null @@ -1,148 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -import java.io.*; - -/** - * A big block created from an InputStream, holding the raw data - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public class RawDataBlock - implements ListManagedBlock -{ - private byte[] _data; - private boolean _eof; - private boolean _hasData; - static POILogger log = POILogFactory.getLogger(RawDataBlock.class); - - /** - * Constructor RawDataBlock - * - * @param stream the InputStream from which the data will be read - * - * @exception IOException on I/O errors, and if an insufficient - * amount of data is read (the InputStream must - * be an exact multiple of the block size) - */ - public RawDataBlock(final InputStream stream) - throws IOException { - this(stream, POIFSConstants.SMALLER_BIG_BLOCK_SIZE); - } - /** - * Constructor RawDataBlock - * - * @param stream the InputStream from which the data will be read - * @param blockSize the size of the POIFS blocks, normally 512 bytes - * {@link org.apache.poi.poifs.common.POIFSConstants#SMALLER_BIG_BLOCK_SIZE} - * - * @exception IOException on I/O errors, and if an insufficient - * amount of data is read (the InputStream must - * be an exact multiple of the block size) - */ - public RawDataBlock(final InputStream stream, int blockSize) - throws IOException { - _data = new byte[ blockSize ]; - int count = IOUtils.readFully(stream, _data); - _hasData = (count > 0); - - if (count == -1) { - _eof = true; - } - else if (count != blockSize) { - // IOUtils.readFully will always read the - // requested number of bytes, unless it hits - // an EOF - _eof = true; - String type = " byte" + ((count == 1) ? ("") - : ("s")); - - log.log(POILogger.ERROR, - "Unable to read entire block; " + count - + type + " read before EOF; expected " - + blockSize + " bytes. Your document " - + "was either written by software that " - + "ignores the spec, or has been truncated!" - ); - } - else { - _eof = false; - } - } - - /** - * When we read the data, did we hit end of file? - * - * @return true if the EoF was hit during this block, or - * false if not. If you have a dodgy short last block, then - * it's possible to both have data, and also hit EoF... - */ - public boolean eof() { - return _eof; - } - /** - * Did we actually find any data to read? It's possible, - * in the event of a short last block, to both have hit - * the EoF, but also to have data - */ - public boolean hasData() { - return _hasData; - } - - public String toString() { - return "RawDataBlock of size " + _data.length; - } - - /* ********** START implementation of ListManagedBlock ********** */ - - /** - * Get the data from the block - * - * @return the block's data as a byte array - * - * @exception IOException if there is no data - */ - public byte [] getData() - throws IOException - { - if (! hasData()) - { - throw new IOException("Cannot return empty data"); - } - return _data; - } - - /** - * What's the big block size? - */ - public int getBigBlockSize() { - return _data.length; - } - - /* ********** END implementation of ListManagedBlock ********** */ -} // end public class RawDataBlock - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java b/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java deleted file mode 100644 index eb8bcc085..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java +++ /dev/null @@ -1,70 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import java.io.*; - -import java.util.*; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; - -/** - * A list of RawDataBlocks instances, and methods to manage the list - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public class RawDataBlockList - extends BlockListImpl -{ - - /** - * Constructor RawDataBlockList - * - * @param stream the InputStream from which the data will be read - * @param bigBlockSize The big block size, either 512 bytes or 4096 bytes - * - * @exception IOException on I/O errors, and if an incomplete - * block is read - */ - - public RawDataBlockList(final InputStream stream, POIFSBigBlockSize bigBlockSize) - throws IOException - { - List blocks = new ArrayList(); - - while (true) - { - RawDataBlock block = new RawDataBlock(stream, bigBlockSize.getBigBlockSize()); - - // If there was data, add the block to the list - if(block.hasData()) { - blocks.add(block); - } - - // If the stream is now at the End Of File, we're done - if (block.eof()) { - break; - } - } - setBlocks( blocks.toArray(new RawDataBlock[ blocks.size() ]) ); - } -} // end public class RawDataBlockList - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java b/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java deleted file mode 100644 index 2f9528318..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.IOException; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.property.RootProperty; - -/** - * This class implements reading the small document block list from an - * existing file - */ -public final class SmallBlockTableReader { - private static BlockList prepareSmallDocumentBlocks( - final POIFSBigBlockSize bigBlockSize, - final RawDataBlockList blockList, final RootProperty root, - final int sbatStart) - throws IOException - { - // Fetch the blocks which hold the Small Blocks stream - ListManagedBlock [] smallBlockBlocks = - blockList.fetchBlocks(root.getStartBlock(), -1); - - // Turn that into a list - BlockList list =new SmallDocumentBlockList( - SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks)); - - return list; - } - private static BlockAllocationTableReader prepareReader( - final POIFSBigBlockSize bigBlockSize, - final RawDataBlockList blockList, final BlockList list, - final RootProperty root, final int sbatStart) - throws IOException - { - // Process the SBAT and blocks - return new BlockAllocationTableReader(bigBlockSize, - blockList.fetchBlocks(sbatStart, -1), - list); - } - - /** - * Fetch the small document block reader from an existing file, normally - * needed for debugging and low level dumping. You should typically call - * {@link #getSmallDocumentBlocks(POIFSBigBlockSize, RawDataBlockList, RootProperty, int)} - * instead. - * - * @param blockList the raw data from which the small block table - * will be extracted - * @param root the root property (which contains the start block - * and small block table size) - * @param sbatStart the start block of the SBAT - * - * @return the small document block reader - * - * @exception IOException - */ - public static BlockAllocationTableReader _getSmallDocumentBlockReader( - final POIFSBigBlockSize bigBlockSize, - final RawDataBlockList blockList, final RootProperty root, - final int sbatStart) - throws IOException - { - BlockList list = prepareSmallDocumentBlocks( - bigBlockSize, blockList, root, sbatStart); - return prepareReader( - bigBlockSize, blockList, list, root, sbatStart); - } - - /** - * Fetch the small document block list from an existing file - * - * @param blockList the raw data from which the small block table - * will be extracted - * @param root the root property (which contains the start block - * and small block table size) - * @param sbatStart the start block of the SBAT - * - * @return the small document block list - * - * @exception IOException - */ - public static BlockList getSmallDocumentBlocks( - final POIFSBigBlockSize bigBlockSize, - final RawDataBlockList blockList, final RootProperty root, - final int sbatStart) - throws IOException - { - BlockList list = prepareSmallDocumentBlocks( - bigBlockSize, blockList, root, sbatStart); - prepareReader(bigBlockSize, blockList, list, root, sbatStart); - return list; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java b/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java deleted file mode 100644 index 9c98bb459..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java +++ /dev/null @@ -1,149 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.filesystem.BATManaged; -import org.apache.poi.poifs.filesystem.OPOIFSDocument; -import org.apache.poi.poifs.property.RootProperty; - -import java.util.*; - -import java.io.*; - -/** - * This class implements storage for writing the small blocks used by - * small documents. - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - -public class SmallBlockTableWriter - implements BlockWritable, BATManaged -{ - private BlockAllocationTableWriter _sbat; - private List _small_blocks; - private int _big_block_count; - private RootProperty _root; - - /** - * Creates new SmallBlockTable - * - * @param documents a List of POIFSDocument instances - * @param root the Filesystem's root property - */ - public SmallBlockTableWriter(final POIFSBigBlockSize bigBlockSize, - final List documents, - final RootProperty root) - { - _sbat = new BlockAllocationTableWriter(bigBlockSize); - _small_blocks = new ArrayList(); - _root = root; - - for (OPOIFSDocument doc : documents) - { - SmallDocumentBlock[] blocks = doc.getSmallBlocks(); - - if (blocks.length != 0) - { - doc.setStartBlock(_sbat.allocateSpace(blocks.length)); - for (int j = 0; j < blocks.length; j++) - { - _small_blocks.add(blocks[ j ]); - } - } else { - doc.setStartBlock(POIFSConstants.END_OF_CHAIN); - } - } - _sbat.simpleCreateBlocks(); - _root.setSize(_small_blocks.size()); - _big_block_count = SmallDocumentBlock.fill(bigBlockSize,_small_blocks); - } - - /** - * Get the number of SBAT blocks - * - * @return number of SBAT big blocks - */ - - public int getSBATBlockCount() - { - return (_big_block_count + 15) / 16; - } - - /** - * Get the SBAT - * - * @return the Small Block Allocation Table - */ - - public BlockAllocationTableWriter getSBAT() - { - return _sbat; - } - - /* ********** START implementation of BATManaged ********** */ - - /** - * Return the number of BigBlock's this instance uses - * - * @return count of BigBlock instances - */ - - public int countBlocks() - { - return _big_block_count; - } - - /** - * Set the start block for this instance - * - * @param start_block - */ - - public void setStartBlock(int start_block) - { - _root.setStartBlock(start_block); - } - - /* ********** END implementation of BATManaged ********** */ - /* ********** START implementation of BlockWritable ********** */ - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - - public void writeBlocks(final OutputStream stream) - throws IOException - { - for (BlockWritable block : _small_blocks) { - block.writeBlocks(stream); - } - } - - /* ********** END implementation of BlockWritable ********** */ -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java b/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java deleted file mode 100644 index d09bf9ecf..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java +++ /dev/null @@ -1,253 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.storage; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.apache.poi.poifs.common.POIFSBigBlockSize; - -/** - * Storage for documents that are too small to use regular - * DocumentBlocks for their data - */ -public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock { - private static final int BLOCK_SHIFT = 6; - - private byte[] _data; - private static final byte _default_fill = ( byte ) 0xff; - private static final int _block_size = 1 << BLOCK_SHIFT; - private static final int BLOCK_MASK = _block_size-1; - - private final int _blocks_per_big_block; - private final POIFSBigBlockSize _bigBlockSize; - - private SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize, final byte [] data, final int index) - { - this(bigBlockSize); - System.arraycopy(data, index * _block_size, _data, 0, _block_size); - } - - protected SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize) - { - _bigBlockSize = bigBlockSize; - _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize); - _data = new byte[ _block_size ]; - } - - private static int getBlocksPerBigBlock(final POIFSBigBlockSize bigBlockSize) - { - return bigBlockSize.getBigBlockSize() / _block_size; - } - - /** - * convert a single long array into an array of SmallDocumentBlock - * instances - * - * @param array the byte array to be converted - * @param size the intended size of the array (which may be smaller) - * - * @return an array of SmallDocumentBlock instances, filled from - * the array - */ - public static SmallDocumentBlock [] convert(POIFSBigBlockSize bigBlockSize, - byte [] array, - int size) - { - SmallDocumentBlock[] rval = - new SmallDocumentBlock[ (size + _block_size - 1) / _block_size ]; - int offset = 0; - - for (int k = 0; k < rval.length; k++) - { - rval[ k ] = new SmallDocumentBlock(bigBlockSize); - if (offset < array.length) - { - int length = Math.min(_block_size, array.length - offset); - - System.arraycopy(array, offset, rval[ k ]._data, 0, length); - if (length != _block_size) - { - Arrays.fill(rval[ k ]._data, length, _block_size, - _default_fill); - } - } - else - { - Arrays.fill(rval[ k ]._data, _default_fill); - } - offset += _block_size; - } - return rval; - } - - /** - * fill out a List of SmallDocumentBlocks so that it fully occupies - * a set of big blocks - * - * @param blocks the List to be filled out - * - * @return number of big blocks the list encompasses - */ - public static int fill(POIFSBigBlockSize bigBlockSize, List blocks) - { - int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize); - - int count = blocks.size(); - int big_block_count = (count + _blocks_per_big_block - 1) - / _blocks_per_big_block; - int full_count = big_block_count * _blocks_per_big_block; - - for (; count < full_count; count++) - { - blocks.add(makeEmptySmallDocumentBlock(bigBlockSize)); - } - return big_block_count; - } - - /** - * Factory for creating SmallDocumentBlocks from DocumentBlocks - * - * @param store the original DocumentBlocks - * @param size the total document size - * - * @return an array of new SmallDocumentBlocks instances - * - * @exception IOException on errors reading from the DocumentBlocks - * @exception ArrayIndexOutOfBoundsException if, somehow, the store - * contains less data than size indicates - */ - public static SmallDocumentBlock [] convert(POIFSBigBlockSize bigBlockSize, - BlockWritable [] store, - int size) - throws IOException, ArrayIndexOutOfBoundsException - { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - - for (int j = 0; j < store.length; j++) - { - store[ j ].writeBlocks(stream); - } - byte[] data = stream.toByteArray(); - SmallDocumentBlock[] rval = - new SmallDocumentBlock[ convertToBlockCount(size) ]; - - for (int index = 0; index < rval.length; index++) - { - rval[ index ] = new SmallDocumentBlock(bigBlockSize, data, index); - } - return rval; - } - - /** - * create a list of SmallDocumentBlock's from raw data - * - * @param blocks the raw data containing the SmallDocumentBlock - * data - * - * @return a List of SmallDocumentBlock's extracted from the input - */ - public static List extract(POIFSBigBlockSize bigBlockSize, ListManagedBlock [] blocks) - throws IOException - { - int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize); - - List sdbs = new ArrayList(); - - for (int j = 0; j < blocks.length; j++) - { - byte[] data = blocks[ j ].getData(); - - for (int k = 0; k < _blocks_per_big_block; k++) - { - sdbs.add(new SmallDocumentBlock(bigBlockSize, data, k)); - } - } - return sdbs; - } - - public static DataInputBlock getDataInputBlock(SmallDocumentBlock[] blocks, int offset) { - int firstBlockIndex = offset >> BLOCK_SHIFT; - int firstBlockOffset= offset & BLOCK_MASK; - return new DataInputBlock(blocks[firstBlockIndex]._data, firstBlockOffset); - } - - /** - * Calculate the storage size of a set of SmallDocumentBlocks - * - * @param size number of SmallDocumentBlocks - * - * @return total size - */ - public static int calcSize(int size) - { - return size * _block_size; - } - - protected int getSmallBlocksPerBigBlock() - { - return _blocks_per_big_block; - } - - private static SmallDocumentBlock makeEmptySmallDocumentBlock(POIFSBigBlockSize bigBlockSize) - { - SmallDocumentBlock block = new SmallDocumentBlock(bigBlockSize); - - Arrays.fill(block._data, _default_fill); - return block; - } - - private static int convertToBlockCount(int size) - { - return (size + _block_size - 1) / _block_size; - } - - /** - * Write the storage to an OutputStream - * - * @param stream the OutputStream to which the stored data should - * be written - * - * @exception IOException on problems writing to the specified - * stream - */ - public void writeBlocks(OutputStream stream) - throws IOException - { - stream.write(_data); - } - - /** - * Get the data from the block - * - * @return the block's data as a byte array - * - * @exception IOException if there is no data - */ - public byte [] getData() { - return _data; - } - - public POIFSBigBlockSize getBigBlockSize() { - return _bigBlockSize; - } -} diff --git a/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java b/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java deleted file mode 100644 index cc6bb7c17..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java +++ /dev/null @@ -1,41 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.poifs.storage; - -import java.util.*; - -/** - * A list of SmallDocumentBlocks instances, and methods to manage the list - */ -public class SmallDocumentBlockList - extends BlockListImpl -{ - /** - * Constructor SmallDocumentBlockList - * - * @param blocks a list of SmallDocumentBlock instances - */ - - public SmallDocumentBlockList(final List blocks) - { - setBlocks(blocks.toArray(new SmallDocumentBlock[blocks.size()])); - } -} - diff --git a/trunk/src/java/org/apache/poi/poifs/storage/package.html b/trunk/src/java/org/apache/poi/poifs/storage/package.html deleted file mode 100644 index b098350c2..000000000 --- a/trunk/src/java/org/apache/poi/poifs/storage/package.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - -storage package contains low level binary structures for POIFS's implementation of the OLE 2 -Compound Document Format. - -

    Related Documentation

    - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java b/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java deleted file mode 100644 index 818b10b10..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java +++ /dev/null @@ -1,306 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.AlphaComposite; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.AffineTransformOp; -import java.awt.image.BufferedImage; -import java.awt.image.RescaleOp; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReadParam; -import javax.imageio.ImageReader; -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.stream.ImageInputStream; -import javax.imageio.stream.MemoryCacheImageInputStream; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * For now this class renders only images supported by the javax.imageio.ImageIO framework. - **/ -public class BitmapImageRenderer implements ImageRenderer { - private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class); - - protected BufferedImage img; - - @Override - public void loadImage(InputStream data, String contentType) throws IOException { - img = readImage(data, contentType); - } - - @Override - public void loadImage(byte data[], String contentType) throws IOException { - img = readImage(new ByteArrayInputStream(data), contentType); - } - - /** - * Read the image data via ImageIO and optionally try to workaround metadata errors. - * The resulting image is of image type {@link BufferedImage#TYPE_INT_ARGB} - * - * @param data the data stream - * @param contentType the content type - * @return the bufferedImage or null, if there was no image reader for this content type - * @throws IOException thrown if there was an error while processing the image - */ - private static BufferedImage readImage(InputStream data, String contentType) throws IOException { - IOException lastException = null; - BufferedImage img = null; - if (data.markSupported()) { - data.mark(data.available()); - } - - // currently don't use FileCacheImageInputStream, - // because of the risk of filling the file handles (see #59166) - ImageInputStream iis = new MemoryCacheImageInputStream(data); - try { - iis = new MemoryCacheImageInputStream(data); - iis.mark(); - - Iterator iter = ImageIO.getImageReaders(iis); - while (img==null && iter.hasNext()) { - ImageReader reader = iter.next(); - ImageReadParam param = reader.getDefaultReadParam(); - // 0:default mode, 1:fallback mode - for (int mode=0; img==null && mode<3; mode++) { - lastException = null; - try { - iis.reset(); - } catch (IOException e) { - if (data.markSupported()) { - data.reset(); - data.mark(data.available()); - iis.close(); - iis = new MemoryCacheImageInputStream(data); - } else { - // can't restore the input stream, so we need to stop processing here - lastException = e; - break; - } - } - iis.mark(); - - try { - - switch (mode) { - case 0: - reader.setInput(iis, false, true); - img = reader.read(0, param); - break; - case 1: { - // try to load picture in gray scale mode - // fallback mode for invalid image band metadata - // see http://stackoverflow.com/questions/10416378 - Iterator imageTypes = reader.getImageTypes(0); - while (imageTypes.hasNext()) { - ImageTypeSpecifier imageTypeSpecifier = imageTypes.next(); - int bufferedImageType = imageTypeSpecifier.getBufferedImageType(); - if (bufferedImageType == BufferedImage.TYPE_BYTE_GRAY) { - param.setDestinationType(imageTypeSpecifier); - break; - } - } - reader.setInput(iis, false, true); - img = reader.read(0, param); - break; - } - case 2: { - // try to load truncated pictures by supplying a BufferedImage - // and use the processed data up till the point of error - reader.setInput(iis, false, true); - int height = reader.getHeight(0); - int width = reader.getWidth(0); - - Iterator imageTypes = reader.getImageTypes(0); - if (imageTypes.hasNext()) { - ImageTypeSpecifier imageTypeSpecifier = imageTypes.next(); - img = imageTypeSpecifier.createBufferedImage(width, height); - param.setDestination(img); - } else { - lastException = new IOException("unable to load even a truncated version of the image."); - break; - } - - try { - reader.read(0, param); - } finally { - if (img.getType() != BufferedImage.TYPE_INT_ARGB) { - int y = findTruncatedBlackBox(img, width, height); - if (y < height) { - BufferedImage argbImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics2D g = argbImg.createGraphics(); - g.clipRect(0, 0, width, y); - g.drawImage(img, 0, 0, null); - g.dispose(); - img.flush(); - img = argbImg; - } - } - } - break; - } - } - - } catch (IOException e) { - if (mode < 2) { - lastException = e; - } - } catch (RuntimeException e) { - if (mode < 2) { - lastException = new IOException("ImageIO runtime exception - "+(mode==0 ? "normal" : "fallback"), e); - } - } - } - reader.dispose(); - } - } finally { - iis.close(); - } - - // If you don't have an image at the end of all readers - if (img == null) { - if (lastException != null) { - // rethrow exception - be aware that the exception source can be in - // multiple locations above ... - throw lastException; - } - LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored."); - return null; - } - - // add alpha channel - if (img.getType() != BufferedImage.TYPE_INT_ARGB) { - BufferedImage argbImg = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics g = argbImg.getGraphics(); - g.drawImage(img, 0, 0, null); - g.dispose(); - return argbImg; - } - - return img; - } - - private static int findTruncatedBlackBox(BufferedImage img, int width, int height) { - // scan through the image to find the black box after the truncated data - int h = height-1; - for (; h > 0; h--) { - for (int w = width-1; w > 0; w-=width/10) { - int p = img.getRGB(w, h); - if (p != 0xff000000) { - return h+1; - } - } - } - return 0; - } - - - @Override - public BufferedImage getImage() { - return img; - } - - @Override - public BufferedImage getImage(Dimension dim) { - double w_old = img.getWidth(); - double h_old = img.getHeight(); - BufferedImage scaled = new BufferedImage((int)w_old, (int)h_old, BufferedImage.TYPE_INT_ARGB); - double w_new = dim.getWidth(); - double h_new = dim.getHeight(); - AffineTransform at = new AffineTransform(); - at.scale(w_new/w_old, h_new/h_old); - AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); - scaleOp.filter(img, scaled); - return scaled; - } - - @Override - public Dimension getDimension() { - return (img == null) - ? new Dimension(0,0) - : new Dimension(img.getWidth(),img.getHeight()); - } - - @Override - public void setAlpha(double alpha) { - if (img == null) return; - - Dimension dim = getDimension(); - BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D g = newImg.createGraphics(); - RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null); - g.drawImage(img, op, 0, 0); - g.dispose(); - - img = newImg; - } - - - @Override - public boolean drawImage( - Graphics2D graphics, - Rectangle2D anchor) { - return drawImage(graphics, anchor, null); - } - - @Override - public boolean drawImage( - Graphics2D graphics, - Rectangle2D anchor, - Insets clip) { - if (img == null) return false; - - boolean isClipped = true; - if (clip == null) { - isClipped = false; - clip = new Insets(0,0,0,0); - } - - int iw = img.getWidth(); - int ih = img.getHeight(); - - - double cw = (100000-clip.left-clip.right) / 100000.0; - double ch = (100000-clip.top-clip.bottom) / 100000.0; - double sx = anchor.getWidth()/(iw*cw); - double sy = anchor.getHeight()/(ih*ch); - double tx = anchor.getX()-(iw*sx*clip.left/100000.0); - double ty = anchor.getY()-(ih*sy*clip.top/100000.0); - - AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ; - - Shape clipOld = graphics.getClip(); - if (isClipped) graphics.clip(anchor.getBounds2D()); - graphics.drawRenderedImage(img, at); - graphics.setClip(clipOld); - - return true; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawAutoShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawAutoShape.java deleted file mode 100644 index 9cda7a32a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawAutoShape.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import org.apache.poi.sl.usermodel.*; - - -public class DrawAutoShape extends DrawTextShape { - public DrawAutoShape(AutoShape shape) { - super(shape); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java b/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java deleted file mode 100644 index aa12b470c..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.sl.usermodel.Background; -import org.apache.poi.sl.usermodel.PlaceableShape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.Sheet; - - -public class DrawBackground extends DrawShape { - public DrawBackground(Background shape) { - super(shape); - } - - @SuppressWarnings("rawtypes") - public void draw(Graphics2D graphics) { - Dimension pg = shape.getSheet().getSlideShow().getPageSize(); - final Rectangle2D anchor = new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); - - PlaceableShape ps = new PlaceableShape(){ - public ShapeContainer getParent() { return null; } - public Rectangle2D getAnchor() { return anchor; } - public void setAnchor(Rectangle2D newAnchor) {} - public double getRotation() { return 0; } - public void setRotation(double theta) {} - public void setFlipHorizontal(boolean flip) {} - public void setFlipVertical(boolean flip) {} - public boolean getFlipHorizontal() { return false; } - public boolean getFlipVertical() { return false; } - public Sheet getSheet() { return shape.getSheet(); } - }; - - DrawFactory drawFact = DrawFactory.getInstance(graphics); - DrawPaint dp = drawFact.getPaint(ps); - Paint fill = dp.getPaint(graphics, getShape().getFillStyle().getPaint()); - Rectangle2D anchor2 = getAnchor(graphics, anchor); - - if(fill != null) { - graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, anchor); - graphics.setPaint(fill); - graphics.fill(anchor2); - } - } - - protected Background getShape() { - return (Background)shape; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawConnectorShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawConnectorShape.java deleted file mode 100644 index 00bcd1b58..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawConnectorShape.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import org.apache.poi.sl.usermodel.ConnectorShape; - -public class DrawConnectorShape extends DrawSimpleShape { - public DrawConnectorShape(ConnectorShape shape) { - super(shape); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java b/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java deleted file mode 100644 index f06ccdc1b..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java +++ /dev/null @@ -1,239 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.text.AttributedString; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.sl.usermodel.Background; -import org.apache.poi.sl.usermodel.ConnectorShape; -import org.apache.poi.sl.usermodel.FreeformShape; -import org.apache.poi.sl.usermodel.GraphicalFrame; -import org.apache.poi.sl.usermodel.GroupShape; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.sl.usermodel.PictureShape; -import org.apache.poi.sl.usermodel.PlaceableShape; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.Sheet; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.TableShape; -import org.apache.poi.sl.usermodel.TextBox; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.sl.usermodel.TextShape; -import org.apache.poi.util.JvmBugs; - -public class DrawFactory { - protected static final ThreadLocal defaultFactory = new ThreadLocal(); - - /** - * Set a custom draw factory for the current thread. - * This is a fallback, for operations where usercode can't set a graphics context. - * Preferably use the rendering hint {@link Drawable#DRAW_FACTORY} to set the factory. - * - * @param factory - */ - public static void setDefaultFactory(DrawFactory factory) { - defaultFactory.set(factory); - } - - /** - * Returns the DrawFactory, preferably via a graphics instance. - * If graphics is null, the current thread local is checked or - * if it is not set, a new factory is created. - * - * @param graphics the current graphics context or null - * @return the draw factory - */ - public static DrawFactory getInstance(Graphics2D graphics) { - // first try to find the factory over the rendering hint - DrawFactory factory = null; - boolean isHint = false; - if (graphics != null) { - factory = (DrawFactory)graphics.getRenderingHint(Drawable.DRAW_FACTORY); - isHint = (factory != null); - } - // secondly try the thread local default - if (factory == null) { - factory = defaultFactory.get(); - } - // and at last, use the default factory - if (factory == null) { - factory = new DrawFactory(); - } - if (graphics != null && !isHint) { - graphics.setRenderingHint(Drawable.DRAW_FACTORY, factory); - } - return factory; - } - - public Drawable getDrawable(Shape shape) { - if (shape instanceof TextBox) { - return getDrawable((TextBox)shape); - } else if (shape instanceof FreeformShape) { - return getDrawable((FreeformShape)shape); - } else if (shape instanceof TextShape) { - return getDrawable((TextShape)shape); - } else if (shape instanceof TableShape) { - return getDrawable((TableShape)shape); - } else if (shape instanceof GroupShape) { - return getDrawable((GroupShape)shape); - } else if (shape instanceof PictureShape) { - return getDrawable((PictureShape)shape); - } else if (shape instanceof GraphicalFrame) { - return getDrawable((GraphicalFrame)shape); - } else if (shape instanceof Background) { - return getDrawable((Background)shape); - } else if (shape instanceof ConnectorShape) { - return getDrawable((ConnectorShape)shape); - } else if (shape instanceof Slide) { - return getDrawable((Slide)shape); - } else if (shape instanceof MasterSheet) { - return getDrawable((MasterSheet)shape); - } else if (shape instanceof Sheet) { - return getDrawable((Sheet)shape); - } else if (shape.getClass().isAnnotationPresent(DrawNotImplemented.class)) { - return new DrawNothing(shape); - } - - throw new IllegalArgumentException("Unsupported shape type: "+shape.getClass()); - } - - public DrawSlide getDrawable(Slide sheet) { - return new DrawSlide(sheet); - } - - public DrawSheet getDrawable(Sheet sheet) { - return new DrawSheet(sheet); - } - - public DrawMasterSheet getDrawable(MasterSheet sheet) { - return new DrawMasterSheet(sheet); - } - - public DrawTextBox getDrawable(TextBox shape) { - return new DrawTextBox(shape); - } - - public DrawFreeformShape getDrawable(FreeformShape shape) { - return new DrawFreeformShape(shape); - } - - public DrawConnectorShape getDrawable(ConnectorShape shape) { - return new DrawConnectorShape(shape); - } - - public DrawTableShape getDrawable(TableShape shape) { - return new DrawTableShape(shape); - } - - public DrawTextShape getDrawable(TextShape shape) { - return new DrawTextShape(shape); - } - - public DrawGroupShape getDrawable(GroupShape shape) { - return new DrawGroupShape(shape); - } - - public DrawPictureShape getDrawable(PictureShape shape) { - return new DrawPictureShape(shape); - } - - public DrawGraphicalFrame getDrawable(GraphicalFrame shape) { - return new DrawGraphicalFrame(shape); - } - - public DrawTextParagraph getDrawable(TextParagraph paragraph) { - return new DrawTextParagraph(paragraph); - } - - public DrawBackground getDrawable(Background shape) { - return new DrawBackground(shape); - } - - public DrawTextFragment getTextFragment(TextLayout layout, AttributedString str) { - return new DrawTextFragment(layout, str); - } - - public DrawPaint getPaint(PlaceableShape shape) { - return new DrawPaint(shape); - } - - /** - * Convenience method for drawing single shapes. - * For drawing whole slides, use {@link Slide#draw(Graphics2D)} - * - * @param graphics the graphics context to draw to - * @param shape the shape - * @param bounds the bounds within the graphics context to draw to - */ - public void drawShape(Graphics2D graphics, Shape shape, Rectangle2D bounds) { - Rectangle2D shapeBounds = shape.getAnchor(); - if (shapeBounds.isEmpty() || (bounds != null && bounds.isEmpty())) { - return; - } - - AffineTransform txg = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); - AffineTransform tx = new AffineTransform(); - try { - if (bounds != null) { - double scaleX = bounds.getWidth()/shapeBounds.getWidth(); - double scaleY = bounds.getHeight()/shapeBounds.getHeight(); - tx.translate(bounds.getCenterX(), bounds.getCenterY()); - tx.scale(scaleX, scaleY); - tx.translate(-shapeBounds.getCenterX(), -shapeBounds.getCenterY()); - } - graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx); - - Drawable d = getDrawable(shape); - d.applyTransform(graphics); - d.draw(graphics); - } finally { - graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, txg); - } - } - - - /** - * Replace font families for Windows JVM 6, which contains a font rendering error. - * This is likely to be removed, when POI upgrades to JDK 7 - * - * @param graphics the graphics context which will contain the font mapping - */ - public void fixFonts(Graphics2D graphics) { - if (!JvmBugs.hasLineBreakMeasurerBug()) return; - @SuppressWarnings("unchecked") - Map fontMap = (Map)graphics.getRenderingHint(Drawable.FONT_MAP); - if (fontMap == null) { - fontMap = new HashMap(); - graphics.setRenderingHint(Drawable.FONT_MAP, fontMap); - } - - String fonts[][] = { { "Calibri", "Lucida Sans" }, { "Cambria", "Lucida Bright" } }; - - for (String f[] : fonts) { - if (!fontMap.containsKey(f[0])) { - fontMap.put(f[0], f[1]); - } - } - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawFontManager.java b/trunk/src/java/org/apache/poi/sl/draw/DrawFontManager.java deleted file mode 100644 index 9c49489ff..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawFontManager.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw; - -/** - * Manages fonts when rendering slides. - * - * Use this class to handle unknown / missing fonts or to substitute fonts - */ -public interface DrawFontManager { - - /** - * select a font to be used to paint text - * - * @param typeface the font family as defined in the .pptx file. - * This can be unknown or missing in the graphic environment. - * - * @return the font to be used to paint text - */ - String getRendererableFont(String typeface, int pitchFamily); -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java deleted file mode 100644 index d8f986881..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.apache.poi.sl.draw.geom.Outline; -import org.apache.poi.sl.draw.geom.Path; -import org.apache.poi.sl.usermodel.FillStyle; -import org.apache.poi.sl.usermodel.FreeformShape; -import org.apache.poi.sl.usermodel.StrokeStyle; - -public class DrawFreeformShape extends DrawAutoShape { - public DrawFreeformShape(FreeformShape shape) { - super(shape); - } - - protected Collection computeOutlines(Graphics2D graphics) { - List lst = new ArrayList(); - FreeformShape fsh = getShape(); - Path2D sh = fsh.getPath(); - - AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); - if (tx == null) { - tx = new AffineTransform(); - } - - java.awt.Shape canvasShape = tx.createTransformedShape(sh); - - FillStyle fs = fsh.getFillStyle(); - StrokeStyle ss = fsh.getStrokeStyle(); - Path path = new Path(fs != null, ss != null); - lst.add(new Outline(canvasShape, path)); - return lst; - } - - @Override - protected FreeformShape getShape() { - return (FreeformShape)shape; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java b/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java deleted file mode 100644 index c4b75f19d..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; - -import org.apache.poi.sl.usermodel.GraphicalFrame; -import org.apache.poi.sl.usermodel.PictureShape; - - -public class DrawGraphicalFrame extends DrawShape { - - public DrawGraphicalFrame(GraphicalFrame shape) { - super(shape); - } - - public void draw(Graphics2D context) { - PictureShape ps = ((GraphicalFrame)getShape()).getFallbackPicture(); - if (ps == null) { - return; - } - DrawPictureShape dps = DrawFactory.getInstance(context).getDrawable(ps); - dps.draw(context); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawGroupShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawGroupShape.java deleted file mode 100644 index 999e34c54..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawGroupShape.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.sl.usermodel.*; - - -public class DrawGroupShape extends DrawShape { - - public DrawGroupShape(GroupShape shape) { - super(shape); - } - - public void draw(Graphics2D graphics) { - - // the coordinate system of this group of shape - Rectangle2D interior = getShape().getInteriorAnchor(); - // anchor of this group relative to the parent shape - Rectangle2D exterior = getShape().getAnchor(); - - AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); - AffineTransform tx0 = new AffineTransform(tx); - - double scaleX = interior.getWidth() == 0. ? 1.0 : exterior.getWidth() / interior.getWidth(); - double scaleY = interior.getHeight() == 0. ? 1.0 : exterior.getHeight() / interior.getHeight(); - - tx.translate(exterior.getX(), exterior.getY()); - tx.scale(scaleX, scaleY); - tx.translate(-interior.getX(), -interior.getY()); - - DrawFactory drawFact = DrawFactory.getInstance(graphics); - AffineTransform at2 = graphics.getTransform(); - - for (Shape child : getShape()) { - // remember the initial transform and restore it after we are done with the drawing - AffineTransform at = graphics.getTransform(); - graphics.setRenderingHint(Drawable.GSAVE, true); - - Drawable draw = drawFact.getDrawable(child); - draw.applyTransform(graphics); - draw.draw(graphics); - - // restore the coordinate system - graphics.setTransform(at); - graphics.setRenderingHint(Drawable.GRESTORE, true); - } - - graphics.setTransform(at2); - graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx0); - } - - @Override - protected GroupShape getShape() { - return (GroupShape)shape; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java b/trunk/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java deleted file mode 100644 index 3bcedbe85..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import org.apache.poi.sl.usermodel.*; - - -public class DrawMasterSheet extends DrawSheet { - - public DrawMasterSheet(MasterSheet sheet) { - super(sheet); - } - - /** - * Checks if this sheet displays the specified shape. - * - * Subclasses can override it and skip certain shapes from drawings, - * for instance, slide masters and layouts don't display placeholders - */ - @Override - protected boolean canDraw(Shape shape) { - if (shape instanceof SimpleShape) { - Placeholder ph = ((SimpleShape)shape).getPlaceholder(); - return ph == null; - } else { - return true; - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawNotImplemented.java b/trunk/src/java/org/apache/poi/sl/draw/DrawNotImplemented.java deleted file mode 100644 index 45b80eaaa..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawNotImplemented.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import org.apache.poi.util.Internal; - - -/** - * This is a marker annotation for classes which don't have a defined - * draw implementation. - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Internal -public @interface DrawNotImplemented { -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawNothing.java b/trunk/src/java/org/apache/poi/sl/draw/DrawNothing.java deleted file mode 100644 index d1710b235..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawNothing.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; - -import org.apache.poi.sl.usermodel.Shape; - - -public class DrawNothing implements Drawable { - - protected final Shape shape; - - public DrawNothing(Shape shape) { - this.shape = shape; - } - - /** - * Apply 2-D transforms before drawing this shape. This includes rotation and flipping. - * - * @param graphics the graphics whos transform matrix will be modified - */ - public void applyTransform(Graphics2D graphics) { - } - - - public void draw(Graphics2D graphics) { - } - - public void drawContent(Graphics2D context) { - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java b/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java deleted file mode 100644 index 4bfbe4300..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java +++ /dev/null @@ -1,524 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.LinearGradientPaint; -import java.awt.MultipleGradientPaint.ColorSpaceType; -import java.awt.MultipleGradientPaint.CycleMethod; -import java.awt.Paint; -import java.awt.RadialGradientPaint; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.sl.usermodel.ColorStyle; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; -import org.apache.poi.sl.usermodel.PlaceableShape; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - - -/** - * This class handles color transformations. - * - * @see HSL code taken from Java Tips Weblog - */ -public class DrawPaint { - // HSL code is public domain - see https://tips4java.wordpress.com/contact-us/ - - private static final POILogger LOG = POILogFactory.getLogger(DrawPaint.class); - - private static final Color TRANSPARENT = new Color(1f,1f,1f,0f); - - protected PlaceableShape shape; - - public DrawPaint(PlaceableShape shape) { - this.shape = shape; - } - - private static class SimpleSolidPaint implements SolidPaint { - private final ColorStyle solidColor; - - SimpleSolidPaint(final Color color) { - if (color == null) { - throw new NullPointerException("Color needs to be specified"); - } - this.solidColor = new ColorStyle(){ - public Color getColor() { - return new Color(color.getRed(), color.getGreen(), color.getBlue()); - } - public int getAlpha() { return (int)Math.round(color.getAlpha()*100000./255.); } - public int getHueOff() { return -1; } - public int getHueMod() { return -1; } - public int getSatOff() { return -1; } - public int getSatMod() { return -1; } - public int getLumOff() { return -1; } - public int getLumMod() { return -1; } - public int getShade() { return -1; } - public int getTint() { return -1; } - }; - } - - SimpleSolidPaint(ColorStyle color) { - if (color == null) { - throw new NullPointerException("Color needs to be specified"); - } - this.solidColor = color; - } - - public ColorStyle getSolidColor() { - return solidColor; - } - } - - public static SolidPaint createSolidPaint(final Color color) { - return (color == null) ? null : new SimpleSolidPaint(color); - } - - public static SolidPaint createSolidPaint(final ColorStyle color) { - return (color == null) ? null : new SimpleSolidPaint(color); - } - - public Paint getPaint(Graphics2D graphics, PaintStyle paint) { - if (paint instanceof SolidPaint) { - return getSolidPaint((SolidPaint)paint, graphics); - } else if (paint instanceof GradientPaint) { - return getGradientPaint((GradientPaint)paint, graphics); - } else if (paint instanceof TexturePaint) { - return getTexturePaint((TexturePaint)paint, graphics); - } - return null; - } - - protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics) { - return applyColorTransform(fill.getSolidColor()); - } - - protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) { - switch (fill.getGradientType()) { - case linear: - return createLinearGradientPaint(fill, graphics); - case circular: - return createRadialGradientPaint(fill, graphics); - case shape: - return createPathGradientPaint(fill, graphics); - default: - throw new UnsupportedOperationException("gradient fill of type "+fill+" not supported."); - } - } - - protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) { - InputStream is = fill.getImageData(); - if (is == null) return null; - assert(graphics != null); - - ImageRenderer renderer = DrawPictureShape.getImageRenderer(graphics, fill.getContentType()); - - try { - try { - renderer.loadImage(is, fill.getContentType()); - } finally { - is.close(); - } - } catch (IOException e) { - LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e); - return null; - } - - int alpha = fill.getAlpha(); - if (0 <= alpha && alpha < 100000) { - renderer.setAlpha(alpha/100000.f); - } - - Rectangle2D textAnchor = shape.getAnchor(); - BufferedImage image; - if ("image/x-wmf".equals(fill.getContentType())) { - // don't rely on wmf dimensions, use dimension of anchor - // TODO: check pixels vs. points for image dimension - image = renderer.getImage(new Dimension((int)textAnchor.getWidth(), (int)textAnchor.getHeight())); - } else { - image = renderer.getImage(); - } - - if(image == null) { - LOG.log(POILogger.ERROR, "Can't load image data"); - return null; - } - Paint paint = new java.awt.TexturePaint(image, textAnchor); - - return paint; - } - - /** - * Convert color transformations in {@link ColorStyle} to a {@link Color} instance - * - * @see Using Office Open XML to Customize Document Formatting in the 2007 Office System - * @see saturation modulation (satMod) - * @see Office Open XML satMod results in more than 100% saturation - */ - public static Color applyColorTransform(ColorStyle color){ - // TODO: The colors don't match 100% the results of Powerpoint, maybe because we still - // operate in sRGB and not scRGB ... work in progress ... - if (color == null || color.getColor() == null) { - return TRANSPARENT; - } - - Color result = color.getColor(); - - double alpha = getAlpha(result, color); - double hsl[] = RGB2HSL(result); // values are in the range [0..100] (usually ...) - applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff()); - applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff()); - applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff()); - applyShade(hsl, color); - applyTint(hsl, color); - - result = HSL2RGB(hsl[0], hsl[1], hsl[2], alpha); - - return result; - } - - private static double getAlpha(Color c, ColorStyle fc) { - double alpha = c.getAlpha()/255d; - int fcAlpha = fc.getAlpha(); - if (fcAlpha != -1) { - alpha *= fcAlpha/100000d; - } - return Math.min(1, Math.max(0, alpha)); - } - - /** - * Apply the modulation and offset adjustments to the given HSL part - * - * Example for lumMod/lumOff: - * The lumMod value is the percent luminance. A lumMod value of "60000", - * is 60% of the luminance of the original color. - * When the color is a shade of the original theme color, the lumMod - * attribute is the only one of the tags shown here that appears. - * The tag appears after the tag when the color is a - * tint of the original. The lumOff value always equals 1-lumMod, which is used in the tint calculation - * - * Despite having different ways to display the tint and shade percentages, - * all of the programs use the same method to calculate the resulting color. - * Convert the original RGB value to HSL ... and then adjust the luminance (L) - * with one of the following equations before converting the HSL value back to RGB. - * (The % tint in the following equations refers to the tint, themetint, themeshade, - * or lumMod values, as applicable.) - * - * @param hsl the hsl values - * @param hslPart the hsl part to modify [0..2] - * @param mod the modulation adjustment - * @param off the offset adjustment - * @return the modified hsl value - * - */ - private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) { - if (mod == -1) mod = 100000; - if (off == -1) off = 0; - if (!(mod == 100000 && off == 0)) { - double fOff = off / 1000d; - double fMod = mod / 100000d; - hsl[hslPart] = hsl[hslPart]*fMod+fOff; - } - } - - /** - * Apply the shade - * - * For a shade, the equation is luminance * %tint. - */ - private static void applyShade(double hsl[], ColorStyle fc) { - int shade = fc.getShade(); - if (shade == -1) return; - - double fshade = shade / 100000.d; - - hsl[2] *= fshade; - } - - /** - * Apply the tint - * - * For a tint, the equation is luminance * %tint + (1-%tint). - * (Note that 1-%tint is equal to the lumOff value in DrawingML.) - */ - private static void applyTint(double hsl[], ColorStyle fc) { - int tint = fc.getTint(); - if (tint == -1) return; - - double ftint = tint / 100000.f; - - hsl[2] = hsl[2] * ftint + (100 - ftint*100.); - } - - - protected Paint createLinearGradientPaint(GradientPaint fill, Graphics2D graphics) { - double angle = fill.getGradientAngle(); - Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); - - AffineTransform at = AffineTransform.getRotateInstance( - Math.toRadians(angle), - anchor.getX() + anchor.getWidth() / 2, - anchor.getY() + anchor.getHeight() / 2); - - double diagonal = Math.sqrt(anchor.getHeight() * anchor.getHeight() + anchor.getWidth() * anchor.getWidth()); - Point2D p1 = new Point2D.Double(anchor.getX() + anchor.getWidth() / 2 - diagonal / 2, - anchor.getY() + anchor.getHeight() / 2); - p1 = at.transform(p1, null); - - Point2D p2 = new Point2D.Double(anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight() / 2); - p2 = at.transform(p2, null); - - snapToAnchor(p1, anchor); - snapToAnchor(p2, anchor); - - if (p1.equals(p2)) { - // gradient paint on the same point throws an exception ... and doesn't make sense - return null; - } - - float[] fractions = fill.getGradientFractions(); - Color[] colors = new Color[fractions.length]; - - int i = 0; - for (ColorStyle fc : fill.getGradientColors()) { - // if fc is null, use transparent color to get color of background - colors[i++] = (fc == null) ? TRANSPARENT : applyColorTransform(fc); - } - - AffineTransform grAt = new AffineTransform(); - if(fill.isRotatedWithShape()) { - double rotation = shape.getRotation(); - if (rotation != 0.) { - double centerX = anchor.getX() + anchor.getWidth() / 2; - double centerY = anchor.getY() + anchor.getHeight() / 2; - - grAt.translate(centerX, centerY); - grAt.rotate(Math.toRadians(-rotation)); - grAt.translate(-centerX, -centerY); - } - } - - return new LinearGradientPaint - (p1, p2, fractions, colors, CycleMethod.NO_CYCLE, ColorSpaceType.SRGB, grAt); - } - - protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) { - Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); - - Point2D pCenter = new Point2D.Double(anchor.getX() + anchor.getWidth()/2, - anchor.getY() + anchor.getHeight()/2); - - float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight()); - - float[] fractions = fill.getGradientFractions(); - Color[] colors = new Color[fractions.length]; - - int i=0; - for (ColorStyle fc : fill.getGradientColors()) { - colors[i++] = applyColorTransform(fc); - } - - return new RadialGradientPaint(pCenter, radius, fractions, colors); - } - - protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) { - // currently we ignore an eventually center setting - - float[] fractions = fill.getGradientFractions(); - Color[] colors = new Color[fractions.length]; - - int i=0; - for (ColorStyle fc : fill.getGradientColors()) { - colors[i++] = applyColorTransform(fc); - } - - return new PathGradientPaint(colors, fractions); - } - - protected void snapToAnchor(Point2D p, Rectangle2D anchor) { - if (p.getX() < anchor.getX()) { - p.setLocation(anchor.getX(), p.getY()); - } else if (p.getX() > (anchor.getX() + anchor.getWidth())) { - p.setLocation(anchor.getX() + anchor.getWidth(), p.getY()); - } - - if (p.getY() < anchor.getY()) { - p.setLocation(p.getX(), anchor.getY()); - } else if (p.getY() > (anchor.getY() + anchor.getHeight())) { - p.setLocation(p.getX(), anchor.getY() + anchor.getHeight()); - } - } - - /** - * Convert HSL values to a RGB Color. - * - * @param h Hue is specified as degrees in the range 0 - 360. - * @param s Saturation is specified as a percentage in the range 1 - 100. - * @param l Luminance is specified as a percentage in the range 1 - 100. - * @param alpha the alpha value between 0 - 1 - * - * @return the RGB Color object - */ - public static Color HSL2RGB(double h, double s, double l, double alpha) { - // we clamp the values, as it possible to come up with more than 100% sat/lum - // (see links in applyColorTransform() for more info) - s = Math.max(0, Math.min(100, s)); - l = Math.max(0, Math.min(100, l)); - - if (alpha <0.0f || alpha > 1.0f) { - String message = "Color parameter outside of expected range - Alpha: " + alpha; - throw new IllegalArgumentException( message ); - } - - // Formula needs all values between 0 - 1. - - h = h % 360.0f; - h /= 360f; - s /= 100f; - l /= 100f; - - double q = (l < 0.5d) - ? l * (1d + s) - : (l + s) - (s * l); - - double p = 2d * l - q; - - double r = Math.max(0, HUE2RGB(p, q, h + (1.0d / 3.0d))); - double g = Math.max(0, HUE2RGB(p, q, h)); - double b = Math.max(0, HUE2RGB(p, q, h - (1.0d / 3.0d))); - - r = Math.min(r, 1.0d); - g = Math.min(g, 1.0d); - b = Math.min(b, 1.0d); - - return new Color((float)r, (float)g, (float)b, (float)alpha); - } - - private static double HUE2RGB(double p, double q, double h) { - if (h < 0d) h += 1d; - - if (h > 1d) h -= 1d; - - if (6d * h < 1d) { - return p + ((q - p) * 6d * h); - } - - if (2d * h < 1d) { - return q; - } - - if (3d * h < 2d) { - return p + ( (q - p) * 6d * ((2.0d / 3.0d) - h) ); - } - - return p; - } - - - /** - * Convert a RGB Color to it corresponding HSL values. - * - * @return an array containing the 3 HSL values. - */ - private static double[] RGB2HSL(Color color) - { - // Get RGB values in the range 0 - 1 - - float[] rgb = color.getRGBColorComponents( null ); - double r = rgb[0]; - double g = rgb[1]; - double b = rgb[2]; - - // Minimum and Maximum RGB values are used in the HSL calculations - - double min = Math.min(r, Math.min(g, b)); - double max = Math.max(r, Math.max(g, b)); - - // Calculate the Hue - - double h = 0; - - if (max == min) { - h = 0; - } else if (max == r) { - h = ((60d * (g - b) / (max - min)) + 360d) % 360d; - } else if (max == g) { - h = (60d * (b - r) / (max - min)) + 120d; - } else if (max == b) { - h = (60d * (r - g) / (max - min)) + 240d; - } - - // Calculate the Luminance - - double l = (max + min) / 2d; - - // Calculate the Saturation - - double s = 0; - - if (max == min) { - s = 0; - } else if (l <= .5d) { - s = (max - min) / (max + min); - } else { - s = (max - min) / (2d - max - min); - } - - return new double[] {h, s * 100, l * 100}; - } - - /** - * Convert sRGB float component [0..1] from sRGB to linear RGB [0..100000] - * - * @see Color#getRGBColorComponents(float[]) - */ - public static int srgb2lin(float sRGB) { - // scRGB has a linear gamma of 1.0, scale the AWT-Color which is in sRGB to linear RGB - // see https://en.wikipedia.org/wiki/SRGB (the reverse transformation) - if (sRGB <= 0.04045d) { - return (int)Math.rint(100000d * sRGB / 12.92d); - } else { - return (int)Math.rint(100000d * Math.pow((sRGB + 0.055d) / 1.055d, 2.4d)); - } - } - - /** - * Convert linear RGB [0..100000] to sRGB float component [0..1] - * - * @see Color#getRGBColorComponents(float[]) - */ - public static float lin2srgb(int linRGB) { - // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color - // see https://en.wikipedia.org/wiki/SRGB (The forward transformation) - if (linRGB <= 0.0031308d) { - return (float)(linRGB / 100000d * 12.92d); - } else { - return (float)(1.055d * Math.pow(linRGB / 100000d, 1.0d/2.4d) - 0.055d); - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java deleted file mode 100644 index bdc5ab68c..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java +++ /dev/null @@ -1,204 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.sl.usermodel.PictureShape; -import org.apache.poi.sl.usermodel.RectAlign; - - -public class DrawPictureShape extends DrawSimpleShape { - private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class); - private static final String WMF_IMAGE_RENDERER = "org.apache.poi.hwmf.draw.HwmfSLImageRenderer"; - - public DrawPictureShape(PictureShape shape) { - super(shape); - } - - @Override - public void drawContent(Graphics2D graphics) { - PictureData data = getShape().getPictureData(); - if(data == null) return; - - Rectangle2D anchor = getAnchor(graphics, getShape()); - Insets insets = getShape().getClipping(); - - try { - ImageRenderer renderer = getImageRenderer(graphics, data.getContentType()); - renderer.loadImage(data.getData(), data.getContentType()); - renderer.drawImage(graphics, anchor, insets); - } catch (IOException e) { - LOG.log(POILogger.ERROR, "image can't be loaded/rendered.", e); - } - } - - /** - * Returns an ImageRenderer for the PictureData - * - * @param graphics - * @return the image renderer - */ - public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) { - ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER); - if (renderer != null) { - return renderer; - } - - if (PictureType.WMF.contentType.equals(contentType)) { - try { - @SuppressWarnings("unchecked") - Class irc = (Class) - Thread.currentThread().getContextClassLoader().loadClass(WMF_IMAGE_RENDERER); - return irc.newInstance(); - } catch (Exception e) { - // WMF image renderer is not on the classpath, continuing with BitmapRenderer - // although this doesn't make much sense ... - LOG.log(POILogger.ERROR, "WMF image renderer is not on the classpath - include poi-scratchpad jar!", e); - } - } - - return new BitmapImageRenderer(); - } - - @Override - protected PictureShape getShape() { - return (PictureShape)shape; - } - - /** - * Resize this picture to the default size. - * - * For PNG and JPEG resizes the image to 100%, - * for other types, if the size can't be determined it will be 200x200 pixels. - */ - public void resize() { - PictureShape ps = getShape(); - Dimension dim = ps.getPictureData().getImageDimension(); - - Rectangle2D origRect = ps.getAnchor(); - double x = origRect.getX(); - double y = origRect.getY(); - double w = dim.getWidth(); - double h = dim.getHeight(); - ps.setAnchor(new Rectangle2D.Double(x, y, w, h)); - } - - - /** - * Fit picture shape into the target rectangle, maintaining the aspect ratio - * and repositioning within the target rectangle with a centered alignment. - * - * @param target The target rectangle - */ - public void resize(Rectangle2D target) { - resize(target, RectAlign.CENTER); - } - - - /** - * Fit picture shape into the target rectangle, maintaining the aspect ratio - * and repositioning within the target rectangle based on the specified - * alignment (gravity). - * - * @param target The target rectangle - * @param align - * The alignment within the target rectangle when resizing. - * A null value corresponds to RectAlign.CENTER - */ - public void resize(Rectangle2D target, RectAlign align) { - PictureShape ps = getShape(); - Dimension dim = ps.getPictureData().getImageDimension(); - if (dim.width <= 0 || dim.height <= 0) { - // nothing useful to be done for this case - ps.setAnchor(target); - return; - } - - double w = target.getWidth(); - double h = target.getHeight(); - - // scaling - double sx = w / dim.width; - double sy = h / dim.height; - - // position adjustments - double dx = 0, dy = 0; - - if (sx > sy) { - // use y-scaling for both, reposition x accordingly - w = sy * dim.width; - dx = target.getWidth() - w; - } else if (sy > sx) { - // use x-scaling for both, reposition y accordingly - h = sx * dim.height; - dy = target.getHeight() - h; - } else { - // uniform scaling, can use target values directly - ps.setAnchor(target); - return; - } - - // the positioning - double x = target.getX(); - double y = target.getY(); - switch (align) { - case TOP: // X=balance, Y=ok - x += dx/2; - break; - case TOP_RIGHT: // X=shift, Y=ok - x += dx; - break; - case RIGHT: // X=shift, Y=balance - x += dx; - y += dy/2; - break; - case BOTTOM_RIGHT: // X=shift, Y=shift - x += dx; - y += dy; - break; - case BOTTOM: // X=balance, Y=shift - x += dx/2; - y += dy; - break; - case BOTTOM_LEFT: // X=ok, Y=shift - y += dy; - break; - case LEFT: // X=ok, Y=balance - y += dy/2; - break; - case TOP_LEFT: // X=ok, Y=ok - /* no-op */ - break; - default: // CENTER: X=balance, Y=balance - x += dx/2; - y += dy/2; - break; - } - - ps.setAnchor(new Rectangle2D.Double(x, y, w, h)); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java deleted file mode 100644 index 1d0eca000..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java +++ /dev/null @@ -1,216 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.BasicStroke; -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.util.Locale; - -import org.apache.poi.sl.usermodel.PlaceableShape; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; - - -public class DrawShape implements Drawable { - - protected final Shape shape; - - public DrawShape(Shape shape) { - this.shape = shape; - } - - /** - * Apply 2-D transforms before drawing this shape. This includes rotation and flipping. - * - * @param graphics the graphics whos transform matrix will be modified - */ - public void applyTransform(Graphics2D graphics) { - if (!(shape instanceof PlaceableShape)) return; - - PlaceableShape ps = (PlaceableShape)shape; - final boolean isHSLF = ps.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf"); - AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); - if (tx == null) tx = new AffineTransform(); - final Rectangle2D anchor = tx.createTransformedShape(ps.getAnchor()).getBounds2D(); - - char cmds[] = isHSLF ? new char[]{ 'h','v','r' } : new char[]{ 'r','h','v' }; - for (char ch : cmds) { - switch (ch) { - case 'h': - //flip horizontal - if (ps.getFlipHorizontal()) { - graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY()); - graphics.scale(-1, 1); - graphics.translate(-anchor.getX(), -anchor.getY()); - } - break; - case 'v': - //flip vertical - if (ps.getFlipVertical()) { - graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight()); - graphics.scale(1, -1); - graphics.translate(-anchor.getX(), -anchor.getY()); - } - break; - case 'r': - // rotation - double rotation = ps.getRotation(); - if (rotation != 0.) { - // PowerPoint rotates shapes relative to the geometric center - double centerX = anchor.getCenterX(); - double centerY = anchor.getCenterY(); - - // normalize rotation - rotation %= 360.; - if (rotation < 0) rotation += 360.; - - int quadrant = (((int)rotation+45)/90)%4; - double scaleX = 1.0, scaleY = 1.0; - - // scale to bounding box (bug #53176) - if (quadrant == 1 || quadrant == 3) { - // In quadrant 1 and 3, which is basically a shape in a more or less portrait orientation - // (45-135 degrees and 225-315 degrees), we need to first rotate the shape by a multiple - // of 90 degrees and then resize the bounding box to its original bbox. After that we can - // rotate the shape to the exact rotation amount. - // It's strange that you'll need to rotate the shape back and forth again, but you can - // think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might - // be already (differently) scaled, so you can paint the shape in its default orientation - // and later on, turn it around again to compare it with its original size ... - - AffineTransform txs; - if (isHSLF) { - txs = new AffineTransform(tx); - } else { - // this handling is only based on try and error ... not sure why xslf is handled differently. - txs = new AffineTransform(); - txs.translate(centerX, centerY); - txs.rotate(Math.PI/2.); // actually doesn't matter if +/- 90 degrees - txs.translate(-centerX, -centerY); - txs.concatenate(tx); - } - - txs.translate(centerX, centerY); - txs.rotate(Math.PI/2.); - txs.translate(-centerX, -centerY); - - Rectangle2D anchor2 = txs.createTransformedShape(ps.getAnchor()).getBounds2D(); - - scaleX = safeScale(anchor.getWidth(), anchor2.getWidth()); - scaleY = safeScale(anchor.getHeight(), anchor2.getHeight()); - } else { - quadrant = 0; - } - - // transformation is applied reversed ... - graphics.translate(centerX, centerY); - double rot = Math.toRadians(rotation-quadrant*90.); - if (rot != 0) { - graphics.rotate(rot); - } - graphics.scale(scaleX, scaleY); - rot = Math.toRadians(quadrant*90); - if (rot != 0) { - graphics.rotate(rot); - } - graphics.translate(-centerX, -centerY); - } - break; - default: - throw new RuntimeException("unexpected transform code " + ch); - } - } - } - - private static double safeScale(double dim1, double dim2) { - if (dim1 == 0.) { - return 1; - } - return (dim2 == 0.) ? 1 : dim1/dim2; - } - - public void draw(Graphics2D graphics) { - } - - public void drawContent(Graphics2D graphics) { - } - - public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape shape) { - return getAnchor(graphics, shape.getAnchor()); - } - - public static Rectangle2D getAnchor(Graphics2D graphics, Rectangle2D anchor) { - if(graphics == null) { - return anchor; - } - - AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); - if(tx != null) { - anchor = tx.createTransformedShape(anchor).getBounds2D(); - } - return anchor; - } - - protected Shape getShape() { - return shape; - } - - protected static BasicStroke getStroke(StrokeStyle strokeStyle) { - float lineWidth = (float) strokeStyle.getLineWidth(); - if (lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt - - LineDash lineDash = strokeStyle.getLineDash(); - if (lineDash == null) { - lineDash = LineDash.SOLID; - } - - int dashPatI[] = lineDash.pattern; - final float dash_phase = 0; - float[] dashPatF = null; - if (dashPatI != null) { - dashPatF = new float[dashPatI.length]; - for (int i=0; i sheet; - - public DrawSheet(Sheet sheet) { - this.sheet = sheet; - } - - public void draw(Graphics2D graphics) { - Dimension dim = sheet.getSlideShow().getPageSize(); - Color whiteTrans = new Color(1f,1f,1f,0f); - graphics.setColor(whiteTrans); - graphics.fillRect(0, 0, (int)dim.getWidth(), (int)dim.getHeight()); - - DrawFactory drawFact = DrawFactory.getInstance(graphics); - MasterSheet master = sheet.getMasterSheet(); - - if(sheet.getFollowMasterGraphics() && master != null) { - Drawable drawer = drawFact.getDrawable(master); - drawer.draw(graphics); - } - - graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, new AffineTransform()); - - for (Shape shape : sheet.getShapes()) { - if(!canDraw(shape)) continue; - - // remember the initial transform and restore it after we are done with drawing - AffineTransform at = graphics.getTransform(); - - // concrete implementations can make sense of this hint, - // for example PSGraphics2D or PDFGraphics2D would call gsave() / grestore - graphics.setRenderingHint(Drawable.GSAVE, true); - - // apply rotation and flipping - Drawable drawer = drawFact.getDrawable(shape); - drawer.applyTransform(graphics); - // draw stuff - drawer.draw(graphics); - - // restore the coordinate system - graphics.setTransform(at); - - graphics.setRenderingHint(Drawable.GRESTORE, true); - } - } - - public void applyTransform(Graphics2D context) { - } - - public void drawContent(Graphics2D context) { - } - - /** - * Checks if this sheet displays the specified shape. - * - * Subclasses can override it and skip certain shapes from drawings, - * for instance, slide masters and layouts don't display placeholders - */ - protected boolean canDraw(Shape shape){ - return true; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java deleted file mode 100644 index 103275069..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java +++ /dev/null @@ -1,439 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.geom.AffineTransform; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Path2D; -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.Unmarshaller; -import javax.xml.stream.EventFilter; -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; - -import org.apache.poi.sl.draw.binding.CTCustomGeometry2D; -import org.apache.poi.sl.draw.geom.Context; -import org.apache.poi.sl.draw.geom.CustomGeometry; -import org.apache.poi.sl.draw.geom.Outline; -import org.apache.poi.sl.draw.geom.Path; -import org.apache.poi.sl.usermodel.LineDecoration; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.Shadow; -import org.apache.poi.sl.usermodel.SimpleShape; -import org.apache.poi.util.Units; - - -public class DrawSimpleShape extends DrawShape { - - private static final double DECO_SIZE_POW = 1.5d; - - public DrawSimpleShape(SimpleShape shape) { - super(shape); - } - - @Override - public void draw(Graphics2D graphics) { - DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape()); - Paint fill = drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint()); - Paint line = drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint()); - BasicStroke stroke = getStroke(); // the stroke applies both to the shadow and the shape - graphics.setStroke(stroke); - - Collection elems = computeOutlines(graphics); - - // first paint the shadow - drawShadow(graphics, elems, fill, line); - - // then fill the shape interior - if (fill != null) { - graphics.setPaint(fill); - for (Outline o : elems) { - if (o.getPath().isFilled()){ - java.awt.Shape s = o.getOutline(); - graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s); - graphics.fill(s); - } - } - } - - // then draw any content within this shape (text, image, etc.) - drawContent(graphics); - - // then stroke the shape outline - if(line != null) { - graphics.setPaint(line); - graphics.setStroke(stroke); - for(Outline o : elems){ - if(o.getPath().isStroked()){ - java.awt.Shape s = o.getOutline(); - graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s); - graphics.draw(s); - } - } - } - - // draw line decorations - drawDecoration(graphics, line, stroke); - } - - protected void drawDecoration(Graphics2D graphics, Paint line, BasicStroke stroke) { - if(line == null) return; - graphics.setPaint(line); - - List lst = new ArrayList(); - LineDecoration deco = getShape().getLineDecoration(); - Outline head = getHeadDecoration(graphics, deco, stroke); - if (head != null) lst.add(head); - Outline tail = getTailDecoration(graphics, deco, stroke); - if (tail != null) lst.add(tail); - - - for(Outline o : lst){ - java.awt.Shape s = o.getOutline(); - Path p = o.getPath(); - graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s); - - if(p.isFilled()) graphics.fill(s); - if(p.isStroked()) graphics.draw(s); - } - } - - protected Outline getTailDecoration(Graphics2D graphics, LineDecoration deco, BasicStroke stroke) { - if (deco == null || stroke == null) { - return null; - } - DecorationSize tailLength = deco.getTailLength(); - if (tailLength == null) { - tailLength = DecorationSize.MEDIUM; - } - DecorationSize tailWidth = deco.getTailWidth(); - if (tailWidth == null) { - tailWidth = DecorationSize.MEDIUM; - } - - double lineWidth = Math.max(2.5, stroke.getLineWidth()); - - Rectangle2D anchor = getAnchor(graphics, getShape()); - double x2 = anchor.getX() + anchor.getWidth(), - y2 = anchor.getY() + anchor.getHeight(); - - double alpha = Math.atan(anchor.getHeight() / anchor.getWidth()); - - AffineTransform at = new AffineTransform(); - java.awt.Shape tailShape = null; - Path p = null; - Rectangle2D bounds; - final double scaleY = Math.pow(DECO_SIZE_POW, tailWidth.ordinal()+1); - final double scaleX = Math.pow(DECO_SIZE_POW, tailLength.ordinal()+1); - - DecorationShape tailShapeEnum = deco.getTailShape(); - - if (tailShapeEnum == null) { - return null; - } - - switch (tailShapeEnum) { - case OVAL: - p = new Path(); - tailShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); - bounds = tailShape.getBounds2D(); - at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2); - at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2); - break; - case STEALTH: - case ARROW: - p = new Path(false, true); - Path2D.Double arrow = new Path2D.Double(); - arrow.moveTo((-lineWidth * scaleX), (-lineWidth * scaleY / 2)); - arrow.lineTo(0, 0); - arrow.lineTo((-lineWidth * scaleX), (lineWidth * scaleY / 2)); - tailShape = arrow; - at.translate(x2, y2); - at.rotate(alpha); - break; - case TRIANGLE: - p = new Path(); - Path2D.Double triangle = new Path2D.Double(); - triangle.moveTo((-lineWidth * scaleX), (-lineWidth * scaleY / 2)); - triangle.lineTo(0, 0); - triangle.lineTo((-lineWidth * scaleX), (lineWidth * scaleY / 2)); - triangle.closePath(); - tailShape = triangle; - at.translate(x2, y2); - at.rotate(alpha); - break; - default: - break; - } - - if (tailShape != null) { - tailShape = at.createTransformedShape(tailShape); - } - return tailShape == null ? null : new Outline(tailShape, p); - } - - protected Outline getHeadDecoration(Graphics2D graphics, LineDecoration deco, BasicStroke stroke) { - if (deco == null || stroke == null) { - return null; - } - DecorationSize headLength = deco.getHeadLength(); - if (headLength == null) { - headLength = DecorationSize.MEDIUM; - } - DecorationSize headWidth = deco.getHeadWidth(); - if (headWidth == null) { - headWidth = DecorationSize.MEDIUM; - } - - double lineWidth = Math.max(2.5, stroke.getLineWidth()); - - Rectangle2D anchor = getAnchor(graphics, getShape()); - double x1 = anchor.getX(), - y1 = anchor.getY(); - - double alpha = Math.atan(anchor.getHeight() / anchor.getWidth()); - - AffineTransform at = new AffineTransform(); - java.awt.Shape headShape = null; - Path p = null; - Rectangle2D bounds; - final double scaleY = Math.pow(DECO_SIZE_POW, headWidth.ordinal()+1); - final double scaleX = Math.pow(DECO_SIZE_POW, headLength.ordinal()+1); - DecorationShape headShapeEnum = deco.getHeadShape(); - - if (headShapeEnum == null) { - return null; - } - - switch (headShapeEnum) { - case OVAL: - p = new Path(); - headShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); - bounds = headShape.getBounds2D(); - at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2); - at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2); - break; - case STEALTH: - case ARROW: - p = new Path(false, true); - Path2D.Double arrow = new Path2D.Double(); - arrow.moveTo((lineWidth * scaleX), (-lineWidth * scaleY / 2)); - arrow.lineTo(0, 0); - arrow.lineTo((lineWidth * scaleX), (lineWidth * scaleY / 2)); - headShape = arrow; - at.translate(x1, y1); - at.rotate(alpha); - break; - case TRIANGLE: - p = new Path(); - Path2D.Double triangle = new Path2D.Double(); - triangle.moveTo((lineWidth * scaleX), (-lineWidth * scaleY / 2)); - triangle.lineTo(0, 0); - triangle.lineTo((lineWidth * scaleX), (lineWidth * scaleY / 2)); - triangle.closePath(); - headShape = triangle; - at.translate(x1, y1); - at.rotate(alpha); - break; - default: - break; - } - - if (headShape != null) { - headShape = at.createTransformedShape(headShape); - } - return headShape == null ? null : new Outline(headShape, p); - } - - public BasicStroke getStroke() { - return getStroke(getShape().getStrokeStyle()); - } - - protected void drawShadow( - Graphics2D graphics - , Collection outlines - , Paint fill - , Paint line - ) { - Shadow shadow = getShape().getShadow(); - if (shadow == null || (fill == null && line == null)) return; - - SolidPaint shadowPaint = shadow.getFillStyle(); - Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor()); - - double shapeRotation = getShape().getRotation(); - if(getShape().getFlipVertical()) { - shapeRotation += 180; - } - double angle = shadow.getAngle() - shapeRotation; - double dist = shadow.getDistance(); - double dx = dist * Math.cos(Math.toRadians(angle)); - double dy = dist * Math.sin(Math.toRadians(angle)); - - graphics.translate(dx, dy); - - for(Outline o : outlines){ - java.awt.Shape s = o.getOutline(); - Path p = o.getPath(); - graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s); - graphics.setPaint(shadowColor); - - if(fill != null && p.isFilled()){ - graphics.fill(s); - } else if (line != null && p.isStroked()) { - graphics.draw(s); - } - } - - graphics.translate(-dx, -dy); - } - - protected static CustomGeometry getCustomGeometry(String name) { - return getCustomGeometry(name, null); - } - - protected static CustomGeometry getCustomGeometry(String name, Graphics2D graphics) { - @SuppressWarnings("unchecked") - Map presets = (graphics == null) - ? null - : (Map)graphics.getRenderingHint(Drawable.PRESET_GEOMETRY_CACHE); - - if (presets == null) { - presets = new HashMap(); - if (graphics != null) { - graphics.setRenderingHint(Drawable.PRESET_GEOMETRY_CACHE, presets); - } - - String packageName = "org.apache.poi.sl.draw.binding"; - InputStream presetIS = Drawable.class.getResourceAsStream("presetShapeDefinitions.xml"); - - // StAX: - EventFilter startElementFilter = new EventFilter() { - @Override - public boolean accept(XMLEvent event) { - return event.isStartElement(); - } - }; - - try { - XMLInputFactory staxFactory = XMLInputFactory.newInstance(); - XMLEventReader staxReader = staxFactory.createXMLEventReader(presetIS); - XMLEventReader staxFiltRd = staxFactory.createFilteredReader(staxReader, startElementFilter); - // Ignore StartElement: - staxFiltRd.nextEvent(); - // JAXB: - JAXBContext jaxbContext = JAXBContext.newInstance(packageName); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - - while (staxFiltRd.peek() != null) { - StartElement evRoot = (StartElement)staxFiltRd.peek(); - String cusName = evRoot.getName().getLocalPart(); - // XMLEvent ev = staxReader.nextEvent(); - JAXBElement el = unmarshaller.unmarshal(staxReader, CTCustomGeometry2D.class); - CTCustomGeometry2D cusGeom = el.getValue(); - - presets.put(cusName, new CustomGeometry(cusGeom)); - } - - staxFiltRd.close(); - staxReader.close(); - } catch (Exception e) { - throw new RuntimeException("Unable to load preset geometries.", e); - } finally { - try { - presetIS.close(); - } catch (IOException e) { - throw new RuntimeException("Unable to load preset geometries.", e); - } - } - } - - return presets.get(name); - } - - protected Collection computeOutlines(Graphics2D graphics) { - - List lst = new ArrayList(); - CustomGeometry geom = getShape().getGeometry(); - if(geom == null) { - return lst; - } - - Rectangle2D anchor = getAnchor(graphics, getShape()); - for (Path p : geom) { - - double w = p.getW() == -1 ? anchor.getWidth() * Units.EMU_PER_POINT : p.getW(); - double h = p.getH() == -1 ? anchor.getHeight() * Units.EMU_PER_POINT : p.getH(); - - // the guides in the shape definitions are all defined relative to each other, - // so we build the path starting from (0,0). - final Rectangle2D pathAnchor = new Rectangle2D.Double(0,0,w,h); - - Context ctx = new Context(geom, pathAnchor, getShape()); - - java.awt.Shape gp = p.getPath(ctx); - - // translate the result to the canvas coordinates in points - AffineTransform at = new AffineTransform(); - at.translate(anchor.getX(), anchor.getY()); - - double scaleX, scaleY; - if (p.getW() != -1) { - scaleX = anchor.getWidth() / p.getW(); - } else { - scaleX = 1.0 / Units.EMU_PER_POINT; - } - if (p.getH() != -1) { - scaleY = anchor.getHeight() / p.getH(); - } else { - scaleY = 1.0 / Units.EMU_PER_POINT; - } - - at.scale(scaleX, scaleY); - - java.awt.Shape canvasShape = at.createTransformedShape(gp); - - lst.add(new Outline(canvasShape, p)); - } - - return lst; - } - - @Override - protected SimpleShape getShape() { - return (SimpleShape)shape; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawSlide.java b/trunk/src/java/org/apache/poi/sl/draw/DrawSlide.java deleted file mode 100644 index ae4baa27f..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawSlide.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; - -import org.apache.poi.sl.usermodel.*; - - -public class DrawSlide extends DrawSheet { - - public DrawSlide(Slide slide) { - super(slide); - } - - public void draw(Graphics2D graphics) { - Background bg = sheet.getBackground(); - if(bg != null) { - DrawFactory drawFact = DrawFactory.getInstance(graphics); - Drawable db = drawFact.getDrawable(bg); - db.draw(graphics); - } - - super.draw(graphics); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawTableShape.java b/trunk/src/java/org/apache/poi/sl/draw/DrawTableShape.java deleted file mode 100644 index 970c9b4e0..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawTableShape.java +++ /dev/null @@ -1,252 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.sl.usermodel.GroupShape; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; -import org.apache.poi.sl.usermodel.TableCell; -import org.apache.poi.sl.usermodel.TableCell.BorderEdge; -import org.apache.poi.util.Internal; -import org.apache.poi.sl.usermodel.TableShape; - -public class DrawTableShape extends DrawShape { - /** - * Additional spacing between cells - */ - @Internal - public static final int borderSize = 2; - - public DrawTableShape(TableShape shape) { - super(shape); - } - - protected Drawable getGroupShape(Graphics2D graphics) { - if (shape instanceof GroupShape) { - DrawFactory df = DrawFactory.getInstance(graphics); - return df.getDrawable((GroupShape)shape); - } - return null; - } - - public void applyTransform(Graphics2D graphics) { - Drawable d = getGroupShape(graphics); - if (d != null) { - d.applyTransform(graphics); - } else { - super.applyTransform(graphics); - } - } - - public void draw(Graphics2D graphics) { - Drawable d = getGroupShape(graphics); - if (d != null) { - d.draw(graphics); - return; - } - - TableShape ts = getShape(); - DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(ts); - final int rows = ts.getNumberOfRows(); - final int cols = ts.getNumberOfColumns(); - - // draw background boxes - for (int row=0; row tc = ts.getCell(row, col); - if (tc == null || tc.isMerged()) { - continue; - } - - Paint fillPaint = drawPaint.getPaint(graphics, tc.getFillStyle().getPaint()); - graphics.setPaint(fillPaint); - Rectangle2D cellAnc = tc.getAnchor(); - graphics.fill(cellAnc); - - for (BorderEdge edge : BorderEdge.values()) { - StrokeStyle stroke = tc.getBorderStyle(edge); - if (stroke == null) { - continue; - } - graphics.setStroke(getStroke(stroke)); - Paint linePaint = drawPaint.getPaint(graphics, stroke.getPaint()); - graphics.setPaint(linePaint); - - double x=cellAnc.getX(), y=cellAnc.getY(), w=cellAnc.getWidth(), h=cellAnc.getHeight(); - Line2D line; - switch (edge) { - default: - case bottom: - line = new Line2D.Double(x-borderSize, y+h, x+w+borderSize, y+h); - break; - case left: - line = new Line2D.Double(x, y, x, y+h+borderSize); - break; - case right: - line = new Line2D.Double(x+w, y, x+w, y+h+borderSize); - break; - case top: - line = new Line2D.Double(x-borderSize, y, x+w+borderSize, y); - break; - } - - graphics.draw(line); - } - } - } - - // draw text - drawContent(graphics); - } - - public void drawContent(Graphics2D graphics) { - Drawable d = getGroupShape(graphics); - if (d != null) { - d.drawContent(graphics); - return; - } - - TableShape ts = getShape(); - DrawFactory df = DrawFactory.getInstance(graphics); - - final int rows = ts.getNumberOfRows(); - final int cols = ts.getNumberOfColumns(); - - for (int row=0; row tc = ts.getCell(row, col); - DrawTextShape dts = df.getDrawable(tc); - dts.drawContent(graphics); - } - } - } - - @Override - protected TableShape getShape() { - return (TableShape)shape; - } - - /** - * Format the table and apply the specified Line to all cell boundaries, - * both outside and inside. - * An empty args parameter removes the affected border. - * - * @param args a varargs array possible containing {@link Double} (width), - * {@link LineCompound}, {@link Color}, {@link LineDash} - */ - public void setAllBorders(Object... args) { - TableShape table = getShape(); - final int rows = table.getNumberOfRows(); - final int cols = table.getNumberOfColumns(); - - BorderEdge edges[] = { BorderEdge.top, BorderEdge.left, null, null }; - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { - edges[2] = (col == cols - 1) ? BorderEdge.right : null; - edges[3] = (row == rows - 1) ? BorderEdge.bottom : null; - setEdges(table.getCell(row, col), edges, args); - } - } - } - - /** - * Format the outside border using the specified Line object - * An empty args parameter removes the affected border. - * - * @param args a varargs array possible containing {@link Double} (width), - * {@link LineCompound}, {@link Color}, {@link LineDash} - */ - public void setOutsideBorders(Object... args){ - if (args.length == 0) return; - - TableShape table = getShape(); - final int rows = table.getNumberOfRows(); - final int cols = table.getNumberOfColumns(); - - BorderEdge edges[] = new BorderEdge[4]; - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { - edges[0] = (col == 0) ? BorderEdge.left : null; - edges[1] = (col == cols - 1) ? BorderEdge.right : null; - edges[2] = (row == 0) ? BorderEdge.top : null; - edges[3] = (row == rows - 1) ? BorderEdge.bottom : null; - setEdges(table.getCell(row, col), edges, args); - } - } - } - - /** - * Format the inside border using the specified Line object - * An empty args parameter removes the affected border. - * - * @param args a varargs array possible containing {@link Double} (width), - * {@link LineCompound}, {@link Color}, {@link LineDash} - */ - public void setInsideBorders(Object... args) { - if (args.length == 0) return; - - TableShape table = getShape(); - final int rows = table.getNumberOfRows(); - final int cols = table.getNumberOfColumns(); - - BorderEdge edges[] = new BorderEdge[2]; - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { - edges[0] = (col > 0 && col < cols - 1) ? BorderEdge.right : null; - edges[1] = (row > 0 && row < rows - 1) ? BorderEdge.bottom : null; - setEdges(table.getCell(row, col), edges, args); - } - } - } - - /** - * Apply the border attributes (args) to the given cell and edges - * - * @param cell the cell - * @param edges the border edges - * @param args the border attributes - */ - private static void setEdges(TableCell cell, BorderEdge edges[], Object... args) { - for (BorderEdge be : edges) { - if (be != null) { - if (args.length == 0) { - cell.removeBorder(be); - } else { - for (Object o : args) { - if (o instanceof Double) { - cell.setBorderWidth(be, (Double)o); - } else if (o instanceof Color) { - cell.setBorderColor(be, (Color)o); - } else if (o instanceof LineDash) { - cell.setBorderDash(be, (LineDash)o); - } else if (o instanceof LineCompound) { - cell.setBorderCompound(be, (LineCompound)o); - } - } - } - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawTextBox.java b/trunk/src/java/org/apache/poi/sl/draw/DrawTextBox.java deleted file mode 100644 index d44d10807..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawTextBox.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import org.apache.poi.sl.usermodel.*; - -public class DrawTextBox extends DrawAutoShape { - public DrawTextBox(TextBox shape) { - super(shape); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawTextFragment.java b/trunk/src/java/org/apache/poi/sl/draw/DrawTextFragment.java deleted file mode 100644 index acb6b4c76..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawTextFragment.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; -import java.awt.font.TextLayout; -import java.text.*; - -public class DrawTextFragment implements Drawable { - final TextLayout layout; - final AttributedString str; - double x, y; - - public DrawTextFragment(TextLayout layout, AttributedString str) { - this.layout = layout; - this.str = str; - } - - public void setPosition(double x, double y) { - // TODO: replace it, by applyTransform???? - this.x = x; - this.y = y; - } - - public void draw(Graphics2D graphics){ - if(str == null) { - return; - } - - double yBaseline = y + layout.getAscent(); - - Integer textMode = (Integer)graphics.getRenderingHint(Drawable.TEXT_RENDERING_MODE); - if(textMode != null && textMode == Drawable.TEXT_AS_SHAPES){ - layout.draw(graphics, (float)x, (float)yBaseline); - } else { - graphics.drawString(str.getIterator(), (float)x, (float)yBaseline ); - } - } - - public void applyTransform(Graphics2D graphics) { - } - - public void drawContent(Graphics2D graphics) { - } - - public TextLayout getLayout() { - return layout; - } - - public AttributedString getAttributedString() { - return str; - } - - /** - * @return full height of this text run which is sum of ascent, descent and leading - */ - public float getHeight(){ - double h = Math.ceil(layout.getAscent()) + Math.ceil(layout.getDescent()) + layout.getLeading(); - return (float)h; - } - - /** - * - * @return width if this text run - */ - public float getWidth(){ - return layout.getAdvance(); - } - - /** - * - * @return the string to be painted - */ - public String getString(){ - if (str == null) return ""; - - AttributedCharacterIterator it = str.getIterator(); - StringBuilder buf = new StringBuilder(); - for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { - buf.append(c); - } - return buf.toString(); - } - - @Override - public String toString(){ - return "[" + getClass().getSimpleName() + "] " + getString(); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java b/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java deleted file mode 100644 index efdd7f4da..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java +++ /dev/null @@ -1,617 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.font.FontRenderContext; -import java.awt.font.LineBreakMeasurer; -import java.awt.font.TextAttribute; -import java.awt.font.TextLayout; -import java.awt.geom.Rectangle2D; -import java.io.InvalidObjectException; -import java.text.AttributedCharacterIterator; -import java.text.AttributedCharacterIterator.Attribute; -import java.text.AttributedString; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.poi.sl.usermodel.AutoNumberingScheme; -import org.apache.poi.sl.usermodel.Hyperlink; -import org.apache.poi.sl.usermodel.Insets2D; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PlaceableShape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.Sheet; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle; -import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; -import org.apache.poi.sl.usermodel.TextRun; -import org.apache.poi.sl.usermodel.TextRun.TextCap; -import org.apache.poi.sl.usermodel.TextShape; -import org.apache.poi.sl.usermodel.TextShape.TextDirection; -import org.apache.poi.util.StringUtil; -import org.apache.poi.util.Units; - - -public class DrawTextParagraph implements Drawable { - /** Keys for passing hyperlinks to the graphics context */ - public static final XlinkAttribute HYPERLINK_HREF = new XlinkAttribute("href"); - public static final XlinkAttribute HYPERLINK_LABEL = new XlinkAttribute("label"); - - protected TextParagraph paragraph; - double x, y; - protected List lines = new ArrayList(); - protected String rawText; - protected DrawTextFragment bullet; - protected int autoNbrIdx = 0; - - /** - * the highest line in this paragraph. Used for line spacing. - */ - protected double maxLineHeight; - - /** - * Defines an attribute used for storing the hyperlink associated with - * some renderable text. - */ - private static class XlinkAttribute extends Attribute { - - XlinkAttribute(String name) { - super(name); - } - - /** - * Resolves instances being deserialized to the predefined constants. - */ - protected Object readResolve() throws InvalidObjectException { - if (HYPERLINK_HREF.getName().equals(getName())) { - return HYPERLINK_HREF; - } - if (HYPERLINK_LABEL.getName().equals(getName())) { - return HYPERLINK_LABEL; - } - throw new InvalidObjectException("unknown attribute name"); - } - } - - - public DrawTextParagraph(TextParagraph paragraph) { - this.paragraph = paragraph; - } - - public void setPosition(double x, double y) { - // TODO: replace it, by applyTransform???? - this.x = x; - this.y = y; - } - - public double getY() { - return y; - } - - /** - * Sets the auto numbering index of the handled paragraph - * @param index the auto numbering index - */ - public void setAutoNumberingIdx(int index) { - autoNbrIdx = index; - } - - public void draw(Graphics2D graphics){ - if (lines.isEmpty()) return; - - double penY = y; - - boolean firstLine = true; - int indentLevel = paragraph.getIndentLevel(); - Double leftMargin = paragraph.getLeftMargin(); - if (leftMargin == null) { - // if the marL attribute is omitted, then a value of 347663 is implied - leftMargin = Units.toPoints(347663L*indentLevel); - } - Double indent = paragraph.getIndent(); - if (indent == null) { - indent = Units.toPoints(347663L*indentLevel); - } - if (isHSLF()) { - // special handling for HSLF - indent -= leftMargin; - } - -// Double rightMargin = paragraph.getRightMargin(); -// if (rightMargin == null) { -// rightMargin = 0d; -// } - - //The vertical line spacing - Double spacing = paragraph.getLineSpacing(); - if (spacing == null) spacing = 100d; - - for(DrawTextFragment line : lines){ - double penX; - - if(firstLine) { - if (!isEmptyParagraph()) { - // TODO: find out character style for empty, but bulleted/numbered lines - bullet = getBullet(graphics, line.getAttributedString().getIterator()); - } - - if (bullet != null){ - bullet.setPosition(x+leftMargin+indent, penY); - bullet.draw(graphics); - // don't let text overlay the bullet and advance by the bullet width - double bulletWidth = bullet.getLayout().getAdvance() + 1; - penX = x + Math.max(leftMargin, leftMargin+indent+bulletWidth); - } else { - penX = x + leftMargin; - } - } else { - penX = x + leftMargin; - } - - Rectangle2D anchor = DrawShape.getAnchor(graphics, paragraph.getParentShape()); - // Insets are already applied on DrawTextShape.drawContent - // but (outer) anchor need to be adjusted - Insets2D insets = paragraph.getParentShape().getInsets(); - double leftInset = insets.left; - double rightInset = insets.right; - - TextAlign ta = paragraph.getTextAlign(); - if (ta == null) ta = TextAlign.LEFT; - switch (ta) { - case CENTER: - penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2; - break; - case RIGHT: - penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset); - break; - default: - break; - } - - line.setPosition(penX, penY); - line.draw(graphics); - - if(spacing > 0) { - // If linespacing >= 0, then linespacing is a percentage of normal line height. - penY += spacing*0.01* line.getHeight(); - } else { - // negative value means absolute spacing in points - penY += -spacing; - } - - firstLine = false; - } - - y = penY - y; - } - - public float getFirstLineHeight() { - return (lines.isEmpty()) ? 0 : lines.get(0).getHeight(); - } - - public float getLastLineHeight() { - return (lines.isEmpty()) ? 0 : lines.get(lines.size()-1).getHeight(); - } - - public boolean isEmptyParagraph() { - return (lines.isEmpty() || rawText.trim().isEmpty()); - } - - public void applyTransform(Graphics2D graphics) { - } - - public void drawContent(Graphics2D graphics) { - } - - /** - * break text into lines, each representing a line of text that fits in the wrapping width - * - * @param graphics - */ - protected void breakText(Graphics2D graphics){ - lines.clear(); - - DrawFactory fact = DrawFactory.getInstance(graphics); - StringBuilder text = new StringBuilder(); - AttributedString at = getAttributedString(graphics, text); - boolean emptyParagraph = ("".equals(text.toString().trim())); - - AttributedCharacterIterator it = at.getIterator(); - LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext()); - for (;;) { - int startIndex = measurer.getPosition(); - - double wrappingWidth = getWrappingWidth(lines.size() == 0, graphics) + 1; // add a pixel to compensate rounding errors - // shape width can be smaller that the sum of insets (this was proved by a test file) - if(wrappingWidth < 0) wrappingWidth = 1; - - int nextBreak = text.indexOf("\n", startIndex + 1); - if (nextBreak == -1) nextBreak = it.getEndIndex(); - - TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true); - if (layout == null) { - // layout can be null if the entire word at the current position - // does not fit within the wrapping width. Try with requireNextWord=false. - layout = measurer.nextLayout((float)wrappingWidth, nextBreak, false); - } - - if(layout == null) { - // exit if can't break any more - break; - } - - int endIndex = measurer.getPosition(); - // skip over new line breaks (we paint 'clear' text runs not starting or ending with \n) - if(endIndex < it.getEndIndex() && text.charAt(endIndex) == '\n'){ - measurer.setPosition(endIndex + 1); - } - - TextAlign hAlign = paragraph.getTextAlign(); - if(hAlign == TextAlign.JUSTIFY || hAlign == TextAlign.JUSTIFY_LOW) { - layout = layout.getJustifiedLayout((float)wrappingWidth); - } - - AttributedString str = (emptyParagraph) - ? null // we will not paint empty paragraphs - : new AttributedString(it, startIndex, endIndex); - DrawTextFragment line = fact.getTextFragment(layout, str); - lines.add(line); - - maxLineHeight = Math.max(maxLineHeight, line.getHeight()); - - if(endIndex == it.getEndIndex()) break; - } - - rawText = text.toString(); - } - - protected DrawTextFragment getBullet(Graphics2D graphics, AttributedCharacterIterator firstLineAttr) { - BulletStyle bulletStyle = paragraph.getBulletStyle(); - if (bulletStyle == null) return null; - - String buCharacter; - AutoNumberingScheme ans = bulletStyle.getAutoNumberingScheme(); - if (ans != null) { - buCharacter = ans.format(autoNbrIdx); - } else { - buCharacter = bulletStyle.getBulletCharacter(); - } - if (buCharacter == null) return null; - - String buFont = bulletStyle.getBulletFont(); - if (buFont == null) buFont = paragraph.getDefaultFontFamily(); - assert(buFont != null); - - PlaceableShape ps = getParagraphShape(); - PaintStyle fgPaintStyle = bulletStyle.getBulletFontColor(); - Paint fgPaint; - if (fgPaintStyle == null) { - fgPaint = (Paint)firstLineAttr.getAttribute(TextAttribute.FOREGROUND); - } else { - fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle); - } - - float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE); - Double buSz = bulletStyle.getBulletFontSize(); - if (buSz == null) buSz = 100d; - if (buSz > 0) fontSize *= buSz* 0.01; - else fontSize = (float)-buSz; - - - AttributedString str = new AttributedString(mapFontCharset(buCharacter,buFont)); - str.addAttribute(TextAttribute.FOREGROUND, fgPaint); - str.addAttribute(TextAttribute.FAMILY, buFont); - str.addAttribute(TextAttribute.SIZE, fontSize); - - TextLayout layout = new TextLayout(str.getIterator(), graphics.getFontRenderContext()); - DrawFactory fact = DrawFactory.getInstance(graphics); - return fact.getTextFragment(layout, str); - } - - protected String getRenderableText(TextRun tr) { - StringBuilder buf = new StringBuilder(); - TextCap cap = tr.getTextCap(); - String tabs = null; - for (char c : tr.getRawText().toCharArray()) { - switch (c) { - case '\t': - if (tabs == null) { - tabs = tab2space(tr); - } - buf.append(tabs); - break; - case '\u000b': - buf.append('\n'); - break; - default: - switch (cap) { - case ALL: c = Character.toUpperCase(c); break; - case SMALL: c = Character.toLowerCase(c); break; - case NONE: break; - } - - buf.append(c); - break; - } - } - - return buf.toString(); - } - - /** - * Replace a tab with the effective number of white spaces. - */ - private String tab2space(TextRun tr) { - AttributedString string = new AttributedString(" "); - String fontFamily = tr.getFontFamily(); - if (fontFamily == null) fontFamily = "Lucida Sans"; - string.addAttribute(TextAttribute.FAMILY, fontFamily); - - Double fs = tr.getFontSize(); - if (fs == null) fs = 12d; - string.addAttribute(TextAttribute.SIZE, fs.floatValue()); - - TextLayout l = new TextLayout(string.getIterator(), new FontRenderContext(null, true, true)); - double wspace = l.getAdvance(); - - Double tabSz = paragraph.getDefaultTabSize(); - if (tabSz == null) tabSz = wspace*4; - - int numSpaces = (int)Math.ceil(tabSz / wspace); - StringBuilder buf = new StringBuilder(); - for(int i = 0; i < numSpaces; i++) { - buf.append(' '); - } - return buf.toString(); - } - - - /** - * Returns wrapping width to break lines in this paragraph - * - * @param firstLine whether the first line is breaking - * - * @return wrapping width in points - */ - protected double getWrappingWidth(boolean firstLine, Graphics2D graphics){ - TextShape ts = paragraph.getParentShape(); - - // internal margins for the text box - Insets2D insets = ts.getInsets(); - double leftInset = insets.left; - double rightInset = insets.right; - - int indentLevel = paragraph.getIndentLevel(); - if (indentLevel == -1) { - // default to 0, if indentLevel is not set - indentLevel = 0; - } - Double leftMargin = paragraph.getLeftMargin(); - if (leftMargin == null) { - // if the marL attribute is omitted, then a value of 347663 is implied - leftMargin = Units.toPoints(347663L*(indentLevel+1)); - } - Double indent = paragraph.getIndent(); - if (indent == null) { - indent = Units.toPoints(347663L*indentLevel); - } - Double rightMargin = paragraph.getRightMargin(); - if (rightMargin == null) { - rightMargin = 0d; - } - - Rectangle2D anchor = DrawShape.getAnchor(graphics, ts); - TextDirection textDir = ts.getTextDirection(); - double width; - if (!ts.getWordWrap()) { - Dimension pageDim = ts.getSheet().getSlideShow().getPageSize(); - // if wordWrap == false then we return the advance to the (right) border of the sheet - switch (textDir) { - default: - width = pageDim.getWidth() - anchor.getX(); - break; - case VERTICAL: - width = pageDim.getHeight() - anchor.getX(); - break; - case VERTICAL_270: - width = anchor.getX(); - break; - } - } else { - switch (textDir) { - default: - width = anchor.getWidth() - leftInset - rightInset - leftMargin - rightMargin; - break; - case VERTICAL: - case VERTICAL_270: - width = anchor.getHeight() - leftInset - rightInset - leftMargin - rightMargin; - break; - } - if (firstLine && !isHSLF()) { - if (bullet != null){ - if (indent > 0) width -= indent; - } else { - if (indent > 0) width -= indent; // first line indentation - else if (indent < 0) { // hanging indentation: the first line start at the left margin - width += leftMargin; - } - } - } - } - - return width; - } - - private static class AttributedStringData { - Attribute attribute; - Object value; - int beginIndex, endIndex; - AttributedStringData(Attribute attribute, Object value, int beginIndex, int endIndex) { - this.attribute = attribute; - this.value = value; - this.beginIndex = beginIndex; - this.endIndex = endIndex; - } - } - - /** - * Helper method for paint style relative to bounds, e.g. gradient paint - */ - @SuppressWarnings("rawtypes") - private PlaceableShape getParagraphShape() { - PlaceableShape ps = new PlaceableShape(){ - public ShapeContainer getParent() { return null; } - public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); } - public void setAnchor(Rectangle2D anchor) {} - public double getRotation() { return 0; } - public void setRotation(double theta) {} - public void setFlipHorizontal(boolean flip) {} - public void setFlipVertical(boolean flip) {} - public boolean getFlipHorizontal() { return false; } - public boolean getFlipVertical() { return false; } - public Sheet getSheet() { return paragraph.getParentShape().getSheet(); } - }; - return ps; - } - - protected AttributedString getAttributedString(Graphics2D graphics, StringBuilder text){ - List attList = new ArrayList(); - if (text == null) text = new StringBuilder(); - - PlaceableShape ps = getParagraphShape(); - - DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER); - - for (TextRun run : paragraph){ - String runText = getRenderableText(run); - // skip empty runs - if (runText.isEmpty()) continue; - - // user can pass an custom object to convert fonts - String fontFamily = run.getFontFamily(); - @SuppressWarnings("unchecked") - Map fontMap = (Map)graphics.getRenderingHint(Drawable.FONT_MAP); - if (fontMap != null && fontMap.containsKey(fontFamily)) { - fontFamily = fontMap.get(fontFamily); - } - if(fontHandler != null) { - fontFamily = fontHandler.getRendererableFont(fontFamily, run.getPitchAndFamily()); - } - if (fontFamily == null) { - fontFamily = paragraph.getDefaultFontFamily(); - } - - int beginIndex = text.length(); - text.append(mapFontCharset(runText,fontFamily)); - int endIndex = text.length(); - - attList.add(new AttributedStringData(TextAttribute.FAMILY, fontFamily, beginIndex, endIndex)); - - PaintStyle fgPaintStyle = run.getFontColor(); - Paint fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle); - attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgPaint, beginIndex, endIndex)); - - Double fontSz = run.getFontSize(); - if (fontSz == null) fontSz = paragraph.getDefaultFontSize(); - attList.add(new AttributedStringData(TextAttribute.SIZE, fontSz.floatValue(), beginIndex, endIndex)); - - if(run.isBold()) { - attList.add(new AttributedStringData(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, beginIndex, endIndex)); - } - if(run.isItalic()) { - attList.add(new AttributedStringData(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, beginIndex, endIndex)); - } - if(run.isUnderlined()) { - attList.add(new AttributedStringData(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, beginIndex, endIndex)); - attList.add(new AttributedStringData(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL, beginIndex, endIndex)); - } - if(run.isStrikethrough()) { - attList.add(new AttributedStringData(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, beginIndex, endIndex)); - } - if(run.isSubscript()) { - attList.add(new AttributedStringData(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB, beginIndex, endIndex)); - } - if(run.isSuperscript()) { - attList.add(new AttributedStringData(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, beginIndex, endIndex)); - } - - Hyperlink hl = run.getHyperlink(); - if (hl != null) { - attList.add(new AttributedStringData(HYPERLINK_HREF, hl.getAddress(), beginIndex, endIndex)); - attList.add(new AttributedStringData(HYPERLINK_LABEL, hl.getLabel(), beginIndex, endIndex)); - } - } - - // ensure that the paragraph contains at least one character - // We need this trick to correctly measure text - if (text.length() == 0) { - Double fontSz = paragraph.getDefaultFontSize(); - text.append(" "); - attList.add(new AttributedStringData(TextAttribute.SIZE, fontSz.floatValue(), 0, 1)); - } - - AttributedString string = new AttributedString(text.toString()); - for (AttributedStringData asd : attList) { - string.addAttribute(asd.attribute, asd.value, asd.beginIndex, asd.endIndex); - } - - return string; - } - - protected boolean isHSLF() { - return paragraph.getClass().getName().contains("HSLF"); - } - - /** - * Map text charset depending on font family. - * Currently this only maps for wingdings font (into unicode private use area) - * - * @param text the raw text - * @param fontFamily the font family - * @return AttributedString with mapped codepoints - * - * @see Drawing exotic fonts in a java applet - * @see StringUtil#mapMsCodepointString(String) - */ - protected String mapFontCharset(String text, String fontFamily) { - // TODO: find a real charset mapping solution instead of hard coding for Wingdings - String attStr = text; - if ("Wingdings".equalsIgnoreCase(fontFamily)) { - // wingdings doesn't contain high-surrogates, so chars are ok - boolean changed = false; - char chrs[] = attStr.toCharArray(); - for (int i=0; i shape) { - super(shape); - } - - @Override - public void drawContent(Graphics2D graphics) { - DrawFactory.getInstance(graphics).fixFonts(graphics); - - TextShape s = getShape(); - - Rectangle2D anchor = DrawShape.getAnchor(graphics, s); - Insets2D insets = s.getInsets(); - double x = anchor.getX() + insets.left; - double y = anchor.getY(); - - // remember the initial transform - AffineTransform tx = graphics.getTransform(); - - // Transform of text in flipped shapes is special. - // At this point the flip and rotation transform is already applied - // (see DrawShape#applyTransform ), but we need to restore it to avoid painting "upside down". - // See Bugzilla 54210. - - boolean vertFlip = s.getFlipVertical(); - boolean horzFlip = s.getFlipHorizontal(); - ShapeContainer sc = s.getParent(); - while (sc instanceof PlaceableShape) { - PlaceableShape ps = (PlaceableShape)sc; - vertFlip ^= ps.getFlipVertical(); - horzFlip ^= ps.getFlipHorizontal(); - sc = ps.getParent(); - } - - // Horizontal flipping applies only to shape outline and not to the text in the shape. - // Applying flip second time restores the original not-flipped transform - if (horzFlip ^ vertFlip) { - final double ax = anchor.getX(); - final double ay = anchor.getY(); - graphics.translate(ax + anchor.getWidth(), ay); - graphics.scale(-1, 1); - graphics.translate(-ax, -ay); - } - - Double textRot = s.getTextRotation(); - if (textRot != null && textRot != 0) { - final double cx = anchor.getCenterX(); - final double cy = anchor.getCenterY(); - graphics.translate(cx, cy); - graphics.rotate(Math.toRadians(textRot)); - graphics.translate(-cx, -cy); - } - - // first dry-run to calculate the total height of the text - double textHeight; - - switch (s.getVerticalAlignment()){ - default: - case TOP: - y += insets.top; - break; - case BOTTOM: - textHeight = getTextHeight(graphics); - y += anchor.getHeight() - textHeight - insets.bottom; - break; - case MIDDLE: - textHeight = getTextHeight(graphics); - double delta = anchor.getHeight() - textHeight - insets.top - insets.bottom; - y += insets.top + delta/2; - break; - } - - TextDirection textDir = s.getTextDirection(); - if (textDir == TextDirection.VERTICAL || textDir == TextDirection.VERTICAL_270) { - final double deg = (textDir == TextDirection.VERTICAL) ? 90 : 270; - final double cx = anchor.getCenterX(); - final double cy = anchor.getCenterY(); - graphics.translate(cx, cy); - graphics.rotate(Math.toRadians(deg)); - graphics.translate(-cx, -cy); - - // old top/left edge is now bottom/left or top/right - as we operate on the already - // rotated drawing context, both verticals can be moved in the same direction - final double w = anchor.getWidth(); - final double h = anchor.getHeight(); - final double dx = (w-h)/2d; - graphics.translate(dx,-dx); - } - - drawParagraphs(graphics, x, y); - - // restore the transform - graphics.setTransform(tx); - } - - /** - * paint the paragraphs starting from top left (x,y) - * - * @return the vertical advance, i.e. the cumulative space occupied by the text - */ - public double drawParagraphs(Graphics2D graphics, double x, double y) { - DrawFactory fact = DrawFactory.getInstance(graphics); - - double y0 = y; - //noinspection RedundantCast - Iterator> paragraphs = - (Iterator>) getShape().iterator(); - - boolean isFirstLine = true; - for (int autoNbrIdx=0; paragraphs.hasNext(); autoNbrIdx++){ - TextParagraph p = paragraphs.next(); - DrawTextParagraph dp = fact.getDrawable(p); - BulletStyle bs = p.getBulletStyle(); - if (bs == null || bs.getAutoNumberingScheme() == null) { - autoNbrIdx = -1; - } else { - Integer startAt = bs.getAutoNumberingStartAt(); - if (startAt == null) startAt = 1; - // TODO: handle reset auto number indexes - if (startAt > autoNbrIdx) autoNbrIdx = startAt; - } - dp.setAutoNumberingIdx(autoNbrIdx); - dp.breakText(graphics); - - if (!isFirstLine) { - // the amount of vertical white space before the paragraph - Double spaceBefore = p.getSpaceBefore(); - if (spaceBefore == null) spaceBefore = 0d; - if(spaceBefore > 0) { - // positive value means percentage spacing of the height of the first line, e.g. - // the higher the first line, the bigger the space before the paragraph - y += spaceBefore*0.01*dp.getFirstLineHeight(); - } else { - // negative value means the absolute spacing in points - y += -spaceBefore; - } - } - isFirstLine = false; - - dp.setPosition(x, y); - dp.draw(graphics); - y += dp.getY(); - - if (paragraphs.hasNext()) { - Double spaceAfter = p.getSpaceAfter(); - if (spaceAfter == null) spaceAfter = 0d; - if(spaceAfter > 0) { - // positive value means percentage spacing of the height of the last line, e.g. - // the higher the last line, the bigger the space after the paragraph - y += spaceAfter*0.01*dp.getLastLineHeight(); - } else { - // negative value means the absolute spacing in points - y += -spaceAfter; - } - } - } - return y - y0; - } - - /** - * Compute the cumulative height occupied by the text - * - * @return the height in points - */ - public double getTextHeight() { - return getTextHeight(null); - } - - /** - * Compute the cumulative height occupied by the text - * - * @param oldGraphics the graphics context, which properties are to be copied, may be null - * @return the height in points - */ - protected double getTextHeight(Graphics2D oldGraphics) { - // dry-run in a 1x1 image and return the vertical advance - BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); - Graphics2D graphics = img.createGraphics(); - if (oldGraphics != null) { - graphics.addRenderingHints(oldGraphics.getRenderingHints()); - graphics.setTransform(oldGraphics.getTransform()); - } - DrawFactory.getInstance(graphics).fixFonts(graphics); - return drawParagraphs(graphics, 0, 0); - } - - @Override - protected TextShape getShape() { - return (TextShape)shape; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/Drawable.java b/trunk/src/java/org/apache/poi/sl/draw/Drawable.java deleted file mode 100644 index 54128b82c..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/Drawable.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.Graphics2D; -import java.awt.RenderingHints; - -import org.apache.poi.util.Internal; - - -public interface Drawable { - class DrawableHint extends RenderingHints.Key { - protected DrawableHint(int id) { - super(id); - } - - public boolean isCompatibleValue(Object val) { - return true; - } - - public String toString() { - switch (intKey()) { - case 1: return "DRAW_FACTORY"; - case 2: return "GROUP_TRANSFORM"; - case 3: return "IMAGE_RENDERER"; - case 4: return "TEXT_RENDERING_MODE"; - case 5: return "GRADIENT_SHAPE"; - case 6: return "PRESET_GEOMETRY_CACHE"; - case 7: return "FONT_HANDLER"; - case 8: return "FONT_FALLBACK"; - case 9: return "FONT_MAP"; - case 10: return "GSAVE"; - case 11: return "GRESTORE"; - default: return "UNKNOWN_ID "+intKey(); - } - } - } - - /** - * {@link DrawFactory} which will be used to draw objects into this graphics context - */ - DrawableHint DRAW_FACTORY = new DrawableHint(1); - - /** - * Key will be internally used to store affine transformation temporarily within group shapes - */ - @Internal - DrawableHint GROUP_TRANSFORM = new DrawableHint(2); - - /** - * Use a custom image renderer of an instance of {@link ImageRenderer} - */ - DrawableHint IMAGE_RENDERER = new DrawableHint(3); - - /** - * how to render text: - * - * {@link #TEXT_AS_CHARACTERS} (default) means to draw via - * {@link java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float)}. - * This mode draws text as characters. Use it if the target graphics writes the actual - * character codes instead of glyph outlines (PDFGraphics2D, SVGGraphics2D, etc.) - * - * {@link #TEXT_AS_SHAPES} means to render via - * {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)}. - * This mode draws glyphs as shapes and provides some advanced capabilities such as - * justification and font substitution. Use it if the target graphics is an image. - * - */ - DrawableHint TEXT_RENDERING_MODE = new DrawableHint(4); - - /** - * PathGradientPaint needs the shape to be set. - * It will be achieved through setting it in the rendering hints - */ - DrawableHint GRADIENT_SHAPE = new DrawableHint(5); - - - /** - * Internal key for caching the preset geometries - */ - DrawableHint PRESET_GEOMETRY_CACHE = new DrawableHint(6); - - /** - * draw text via {@link java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float)} - */ - int TEXT_AS_CHARACTERS = 1; - - /** - * draw text via {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)} - */ - int TEXT_AS_SHAPES = 2; - - /** - * Use this object to resolve unknown / missing fonts when rendering slides - */ - DrawableHint FONT_HANDLER = new DrawableHint(7); - DrawableHint FONT_FALLBACK = new DrawableHint(8); - DrawableHint FONT_MAP = new DrawableHint(9); - - DrawableHint GSAVE = new DrawableHint(10); - DrawableHint GRESTORE = new DrawableHint(11); - - - - /** - * Apply 2-D transforms before drawing this shape. This includes rotation and flipping. - * - * @param graphics the graphics whos transform matrix will be modified - */ - void applyTransform(Graphics2D graphics); - - /** - * Draw this shape into the supplied canvas - * - * @param graphics the graphics to draw into - */ - void draw(Graphics2D graphics); - - /** - * draw any content within this shape (image, text, etc.). - * - * @param graphics the graphics to draw into - */ - void drawContent(Graphics2D graphics); -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java b/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java deleted file mode 100644 index 6b8c49a14..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.sl.draw; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; - -/** - * Classes can implement this interfaces to support other formats, for - * example, use Apache Batik to render WMF, PICT can be rendered using Apple QuickTime API for Java: - * - *
    - * 
    - * public class MyImageRendener implements ImageRendener {
    - *     InputStream data;
    - *
    - *     public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {
    - *         // draw image
    - *       DataInputStream is = new DataInputStream(data);
    - *       org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore wmfStore =
    - *               new org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore();
    - *       try {
    - *           wmfStore.read(is);
    - *       } catch (IOException e){
    - *           return;
    - *       }
    - *
    - *       float scale = (float)anchor.width/wmfStore.getWidthPixels();
    - *
    - *       org.apache.batik.transcoder.wmf.tosvg.WMFPainter painter =
    - *               new org.apache.batik.transcoder.wmf.tosvg.WMFPainter(wmfStore, 0, 0, scale);
    - *       graphics.translate(anchor.x, anchor.y);
    - *       painter.paint(graphics);
    - *     }
    - *
    - *     public void loadImage(InputStream data, String contentType) throws IOException {
    - *         if ("image/wmf".equals(contentType)) {
    - *             this.data = data;
    - *             // use Apache Batik to handle WMF
    - *         } else {
    - *             super.loadImage(data,contentType);
    - *         }
    - *     }
    - * }
    - * 
    - * 
    - * - * and then pass this class to your instance of java.awt.Graphics2D: - * - *
    - * 
    - * graphics.setRenderingHint(Drawable.IMAGE_RENDERER, new MyImageRendener());
    - * 
    - * 
    - */ -public interface ImageRenderer { - /** - * Load and buffer the image - * - * @param data the raw image stream - * @param contentType the content type - */ - void loadImage(InputStream data, String contentType) throws IOException; - - /** - * Load and buffer the image - * - * @param data the raw image bytes - * @param contentType the content type - */ - void loadImage(byte data[], String contentType) throws IOException; - - /** - * @return the dimension of the buffered image - */ - Dimension getDimension(); - - /** - * @param alpha the alpha [0..1] to be added to the image (possibly already containing an alpha channel) - */ - void setAlpha(double alpha); - - /** - * @return the image as buffered image - */ - BufferedImage getImage(); - - /** - * @param dim the dimension in pixels of the returned image - * @return the image as buffered image - * - * @since POI 3.15-beta2 - */ - BufferedImage getImage(Dimension dim); - - /** - * Render picture data into the supplied graphics - * - * @return true if the picture data was successfully rendered - */ - boolean drawImage(Graphics2D graphics, Rectangle2D anchor); - - /** - * Render picture data into the supplied graphics - * - * @return true if the picture data was successfully rendered - */ - boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java b/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java deleted file mode 100644 index 63cae11e9..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java +++ /dev/null @@ -1,188 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - -import java.awt.*; -import java.awt.MultipleGradientPaint.ColorSpaceType; -import java.awt.MultipleGradientPaint.CycleMethod; -import java.awt.geom.*; -import java.awt.image.*; - -class PathGradientPaint implements Paint { - - // http://asserttrue.blogspot.de/2010/01/how-to-iimplement-custom-paint-in-50.html - protected final Color colors[]; - protected final float fractions[]; - protected final int capStyle; - protected final int joinStyle; - protected final int transparency; - - - public PathGradientPaint(Color colors[], float fractions[]) { - this(colors,fractions,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); - } - - public PathGradientPaint(Color colors[], float fractions[], int capStyle, int joinStyle) { - this.colors = colors.clone(); - this.fractions = fractions.clone(); - this.capStyle = capStyle; - this.joinStyle = joinStyle; - - // determine transparency - boolean opaque = true; - for (Color c : colors) { - if (c != null) { - opaque = opaque && (c.getAlpha() == 0xff); - } - } - this.transparency = opaque ? OPAQUE : TRANSLUCENT; - } - - public PaintContext createContext(ColorModel cm, - Rectangle deviceBounds, - Rectangle2D userBounds, - AffineTransform transform, - RenderingHints hints) { - return new PathGradientContext(cm, deviceBounds, userBounds, transform, hints); - } - - public int getTransparency() { - return transparency; - } - - class PathGradientContext implements PaintContext { - protected final Rectangle deviceBounds; - protected final Rectangle2D userBounds; - protected final AffineTransform xform; - protected final RenderingHints hints; - - /** - * for POI: the shape will be only known when the subclasses determines the concrete implementation - * in the draw/-content method, so we need to postpone the setting/creation as long as possible - **/ - protected final Shape shape; - protected final PaintContext pCtx; - protected final int gradientSteps; - WritableRaster raster; - - public PathGradientContext( - ColorModel cm - , Rectangle deviceBounds - , Rectangle2D userBounds - , AffineTransform xform - , RenderingHints hints - ) { - shape = (Shape)hints.get(Drawable.GRADIENT_SHAPE); - if (shape == null) { - throw new IllegalPathStateException("PathGradientPaint needs a shape to be set via the rendering hint Drawable.GRADIANT_SHAPE."); - } - - this.deviceBounds = deviceBounds; - this.userBounds = userBounds; - this.xform = xform; - this.hints = hints; - - gradientSteps = getGradientSteps(shape); - - Point2D start = new Point2D.Double(0, 0); - Point2D end = new Point2D.Double(gradientSteps, 0); - LinearGradientPaint gradientPaint = new LinearGradientPaint(start, end, fractions, colors, CycleMethod.NO_CYCLE, ColorSpaceType.SRGB, new AffineTransform()); - - Rectangle bounds = new Rectangle(0, 0, gradientSteps, 1); - pCtx = gradientPaint.createContext(cm, bounds, bounds, new AffineTransform(), hints); - } - - public void dispose() {} - - public ColorModel getColorModel() { - return pCtx.getColorModel(); - } - - public Raster getRaster(int xOffset, int yOffset, int w, int h) { - ColorModel cm = getColorModel(); - if (raster == null) createRaster(); - - // TODO: eventually use caching here - WritableRaster childRaster = cm.createCompatibleWritableRaster(w, h); - Rectangle2D childRect = new Rectangle2D.Double(xOffset, yOffset, w, h); - if (!childRect.intersects(deviceBounds)) { - // usually doesn't happen ... - return childRaster; - } - - Rectangle2D destRect = new Rectangle2D.Double(); - Rectangle2D.intersect(childRect, deviceBounds, destRect); - int dx = (int)(destRect.getX()-deviceBounds.getX()); - int dy = (int)(destRect.getY()-deviceBounds.getY()); - int dw = (int)destRect.getWidth(); - int dh = (int)destRect.getHeight(); - Object data = raster.getDataElements(dx, dy, dw, dh, null); - dx = (int)(destRect.getX()-childRect.getX()); - dy = (int)(destRect.getY()-childRect.getY()); - childRaster.setDataElements(dx, dy, dw, dh, data); - - return childRaster; - } - - protected int getGradientSteps(Shape gradientShape) { - Rectangle rect = gradientShape.getBounds(); - int lower = 1; - int upper = (int)(Math.max(rect.getWidth(),rect.getHeight())/2.0); - while (lower < upper-1) { - int mid = lower + (upper - lower) / 2; - BasicStroke bs = new BasicStroke(mid, capStyle, joinStyle); - Area area = new Area(bs.createStrokedShape(gradientShape)); - if (area.isSingular()) { - upper = mid; - } else { - lower = mid; - } - } - return upper; - } - - - - protected void createRaster() { - ColorModel cm = getColorModel(); - raster = cm.createCompatibleWritableRaster((int)deviceBounds.getWidth(), (int)deviceBounds.getHeight()); - BufferedImage img = new BufferedImage(cm, raster, false, null); - Graphics2D graphics = img.createGraphics(); - graphics.setRenderingHints(hints); - graphics.translate(-deviceBounds.getX(), -deviceBounds.getY()); - graphics.transform(xform); - - Raster img2 = pCtx.getRaster(0, 0, gradientSteps, 1); - int rgb[] = new int[cm.getNumComponents()]; - - for (int i = gradientSteps-1; i>=0; i--) { - img2.getPixel(i, 0, rgb); - Color c = new Color(rgb[0],rgb[1],rgb[2]); - if (rgb.length == 4) { - // it doesn't work to use just a color with transparency ... - graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, rgb[3]/255.0f)); - } - graphics.setStroke(new BasicStroke(i+1, capStyle, joinStyle)); - graphics.setColor(c); - graphics.draw(shape); - } - - graphics.dispose(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java b/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java deleted file mode 100644 index 47dba6288..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java +++ /dev/null @@ -1,1846 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw; - - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.Toolkit; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Path2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.text.AttributedCharacterIterator; -import java.util.Map; - -import org.apache.poi.sl.usermodel.FreeformShape; -import org.apache.poi.sl.usermodel.GroupShape; -import org.apache.poi.sl.usermodel.Insets2D; -import org.apache.poi.sl.usermodel.SimpleShape; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.TextBox; -import org.apache.poi.sl.usermodel.TextRun; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.SuppressForbidden; - -/** - * Translates Graphics2D calls into PowerPoint. - * - * @author Yegor Kozlov - */ -public final class SLGraphics extends Graphics2D implements Cloneable { - - protected POILogger log = POILogFactory.getLogger(this.getClass()); - - //The ppt object to write into. - private GroupShape _group; - - private AffineTransform _transform; - private Stroke _stroke; - private Paint _paint; - private Font _font; - private Color _foreground; - private Color _background; - private RenderingHints _hints; - - /** - * Construct Java Graphics object which translates graphic calls in ppt drawing layer. - * - * @param group The shape group to write the graphics calls into. - */ - public SLGraphics(GroupShape group){ - this._group = group; - - _transform = new AffineTransform(); - _stroke = new BasicStroke(); - _paint = Color.black; - _font = new Font("Arial", Font.PLAIN, 12); - _background = Color.black; - _foreground = Color.white; - _hints = new RenderingHints(null); - } - - /** - * @return the shape group being used for drawing - */ - public GroupShape getShapeGroup(){ - return _group; - } - - /** - * Gets the current font. - * @return this graphics context's current font. - * @see java.awt.Font - * @see java.awt.Graphics#setFont(Font) - */ - public Font getFont(){ - return _font; - } - - /** - * Sets this graphics context's font to the specified font. - * All subsequent text operations using this graphics context - * use this font. - * @param font the font. - * @see java.awt.Graphics#getFont - * @see java.awt.Graphics#drawString(java.lang.String, int, int) - * @see java.awt.Graphics#drawBytes(byte[], int, int, int, int) - * @see java.awt.Graphics#drawChars(char[], int, int, int, int) - */ - public void setFont(Font font){ - this._font = font; - } - - /** - * Gets this graphics context's current color. - * @return this graphics context's current color. - * @see java.awt.Color - * @see java.awt.Graphics#setColor - */ - public Color getColor(){ - return _foreground; - } - - /** - * Sets this graphics context's current color to the specified - * color. All subsequent graphics operations using this graphics - * context use this specified color. - * @param c the new rendering color. - * @see java.awt.Color - * @see java.awt.Graphics#getColor - */ - public void setColor(Color c) { - setPaint(c); - } - - /** - * Returns the current Stroke in the - * Graphics2D context. - * @return the current Graphics2D Stroke, - * which defines the line style. - * @see #setStroke - */ - public Stroke getStroke(){ - return _stroke; - } - - /** - * Sets the Stroke for the Graphics2D context. - * @param s the Stroke object to be used to stroke a - * Shape during the rendering process - */ - public void setStroke(Stroke s){ - this._stroke = s; - } - - /** - * Returns the current Paint of the - * Graphics2D context. - * @return the current Graphics2D Paint, - * which defines a color or pattern. - * @see #setPaint - * @see java.awt.Graphics#setColor - */ - public Paint getPaint(){ - return _paint; - } - - /** - * Sets the Paint attribute for the - * Graphics2D context. Calling this method - * with a null Paint object does - * not have any effect on the current Paint attribute - * of this Graphics2D. - * @param paint the Paint object to be used to generate - * color during the rendering process, or null - * @see java.awt.Graphics#setColor - */ - public void setPaint(Paint paint){ - if(paint == null) return; - - this._paint = paint; - if (paint instanceof Color) _foreground = (Color)paint; - } - - /** - * Returns a copy of the current Transform in the - * Graphics2D context. - * @return the current AffineTransform in the - * Graphics2D context. - * @see #_transform - * @see #setTransform - */ - public AffineTransform getTransform(){ - return new AffineTransform(_transform); - } - - /** - * Sets the Transform in the Graphics2D - * context. - * @param Tx the AffineTransform object to be used in the - * rendering process - * @see #_transform - * @see AffineTransform - */ - public void setTransform(AffineTransform Tx) { - _transform = new AffineTransform(Tx); - } - - /** - * Strokes the outline of a Shape using the settings of the - * current Graphics2D context. The rendering attributes - * applied include the Clip, Transform, - * Paint, Composite and - * Stroke attributes. - * @param shape the Shape to be rendered - * @see #setStroke - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #_transform - * @see #setTransform - * @see #clip - * @see #setClip - * @see #setComposite - */ - public void draw(Shape shape){ - Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape)); - FreeformShape p = _group.createFreeform(); - p.setPath(path); - p.setFillColor(null); - applyStroke(p); - if (_paint instanceof Color) { - p.setStrokeStyle((Color)_paint); - } - } - - /** - * Renders the text specified by the specified String, - * using the current text attribute state in the Graphics2D context. - * The baseline of the first character is at position - * (xy) in the User Space. - * The rendering attributes applied include the Clip, - * Transform, Paint, Font and - * Composite attributes. For characters in script systems - * such as Hebrew and Arabic, the glyphs can be rendered from right to - * left, in which case the coordinate supplied is the location of the - * leftmost character on the baseline. - * @param s the String to be rendered - * @param x the x coordinate of the location where the - * String should be rendered - * @param y the y coordinate of the location where the - * String should be rendered - * @throws NullPointerException if str is - * null - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see java.awt.Graphics#setFont - * @see #setTransform - * @see #setComposite - * @see #setClip - */ - public void drawString(String s, float x, float y) { - TextBox txt = _group.createTextBox(); - - TextRun rt = txt.getTextParagraphs().get(0).getTextRuns().get(0); - rt.setFontSize((double)_font.getSize()); - rt.setFontFamily(_font.getFamily()); - - if (getColor() != null) rt.setFontColor(DrawPaint.createSolidPaint(getColor())); - if (_font.isBold()) rt.setBold(true); - if (_font.isItalic()) rt.setItalic(true); - - txt.setText(s); - - txt.setInsets(new Insets2D(0,0,0,0)); - txt.setWordWrap(false); - txt.setHorizontalCentered(false); - txt.setVerticalAlignment(VerticalAlignment.MIDDLE); - - - TextLayout layout = new TextLayout(s, _font, getFontRenderContext()); - float ascent = layout.getAscent(); - - float width = (float) Math.floor(layout.getAdvance()); - /** - * Even if top and bottom margins are set to 0 PowerPoint - * always sets extra space between the text and its bounding box. - * - * The approximation height = ascent*2 works good enough in most cases - */ - float height = ascent * 2; - - /* - In powerpoint anchor of a shape is its top left corner. - Java graphics sets string coordinates by the baseline of the first character - so we need to shift up by the height of the textbox - */ - y -= height / 2 + ascent / 2; - - /* - In powerpoint anchor of a shape is its top left corner. - Java graphics sets string coordinates by the baseline of the first character - so we need to shift down by the height of the textbox - */ - txt.setAnchor(new Rectangle((int)x, (int)y, (int)width, (int)height)); - } - - /** - * Fills the interior of a Shape using the settings of the - * Graphics2D context. The rendering attributes applied - * include the Clip, Transform, - * Paint, and Composite. - * @param shape the Shape to be filled - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - */ - public void fill(Shape shape){ - Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape)); - FreeformShape p = _group.createFreeform(); - p.setPath(path); - applyPaint(p); - p.setStrokeStyle(); //Fills must be "No Line" - } - - /** - * Translates the origin of the graphics context to the point - * (xy) in the current coordinate system. - * Modifies this graphics context so that its new origin corresponds - * to the point (xy) in this graphics context's - * original coordinate system. All coordinates used in subsequent - * rendering operations on this graphics context will be relative - * to this new origin. - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void translate(int x, int y){ - _transform.translate(x, y); - } - - /** - * Intersects the current Clip with the interior of the - * specified Shape and sets the Clip to the - * resulting intersection. The specified Shape is - * transformed with the current Graphics2D - * Transform before being intersected with the current - * Clip. This method is used to make the current - * Clip smaller. - * To make the Clip larger, use setClip. - * The user clip modified by this method is independent of the - * clipping associated with device bounds and visibility. If no clip has - * previously been set, or if the clip has been cleared using - * {@link java.awt.Graphics#setClip(Shape) setClip} with a - * null argument, the specified Shape becomes - * the new user clip. - * @param s the Shape to be intersected with the current - * Clip. If s is null, - * this method clears the current Clip. - */ - @NotImplemented - public void clip(Shape s){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Gets the current clipping area. - * This method returns the user clip, which is independent of the - * clipping associated with device bounds and window visibility. - * If no clip has previously been set, or if the clip has been - * cleared using setClip(null), this method returns - * null. - * @return a Shape object representing the - * current clipping area, or null if - * no clip is set. - * @see java.awt.Graphics#getClipBounds() - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(int, int, int, int) - * @see java.awt.Graphics#setClip(Shape) - * @since JDK1.1 - */ - @NotImplemented - public Shape getClip(){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return null; - } - - /** - * Concatenates the current Graphics2D - * Transform with a scaling transformation - * Subsequent rendering is resized according to the specified scaling - * factors relative to the previous scaling. - * This is equivalent to calling transform(S), where S is an - * AffineTransform represented by the following matrix: - *
    -     *          [   sx   0    0   ]
    -     *          [   0    sy   0   ]
    -     *          [   0    0    1   ]
    -     * 
    - * @param sx the amount by which X coordinates in subsequent - * rendering operations are multiplied relative to previous - * rendering operations. - * @param sy the amount by which Y coordinates in subsequent - * rendering operations are multiplied relative to previous - * rendering operations. - */ - public void scale(double sx, double sy){ - _transform.scale(sx, sy); - } - - /** - * Draws an outlined round-cornered rectangle using this graphics - * context's current color. The left and right edges of the rectangle - * are at x and x + width, - * respectively. The top and bottom edges of the rectangle are at - * y and y + height. - * @param x the x coordinate of the rectangle to be drawn. - * @param y the y coordinate of the rectangle to be drawn. - * @param width the width of the rectangle to be drawn. - * @param height the height of the rectangle to be drawn. - * @param arcWidth the horizontal diameter of the arc - * at the four corners. - * @param arcHeight the vertical diameter of the arc - * at the four corners. - * @see java.awt.Graphics#fillRoundRect - */ - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight){ - RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight); - draw(rect); - } - - /** - * Draws the text given by the specified string, using this - * graphics context's current font and color. The baseline of the - * first character is at position (xy) in this - * graphics context's coordinate system. - * @param str the string to be drawn. - * @param x the x coordinate. - * @param y the y coordinate. - * @see java.awt.Graphics#drawBytes - * @see java.awt.Graphics#drawChars - */ - public void drawString(String str, int x, int y){ - drawString(str, (float)x, (float)y); - } - - /** - * Fills an oval bounded by the specified rectangle with the - * current color. - * @param x the x coordinate of the upper left corner - * of the oval to be filled. - * @param y the y coordinate of the upper left corner - * of the oval to be filled. - * @param width the width of the oval to be filled. - * @param height the height of the oval to be filled. - * @see java.awt.Graphics#drawOval - */ - public void fillOval(int x, int y, int width, int height){ - Ellipse2D oval = new Ellipse2D.Double(x, y, width, height); - fill(oval); - } - - /** - * Fills the specified rounded corner rectangle with the current color. - * The left and right edges of the rectangle - * are at x and x + width - 1, - * respectively. The top and bottom edges of the rectangle are at - * y and y + height - 1. - * @param x the x coordinate of the rectangle to be filled. - * @param y the y coordinate of the rectangle to be filled. - * @param width the width of the rectangle to be filled. - * @param height the height of the rectangle to be filled. - * @param arcWidth the horizontal diameter - * of the arc at the four corners. - * @param arcHeight the vertical diameter - * of the arc at the four corners. - * @see java.awt.Graphics#drawRoundRect - */ - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight){ - - RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight); - fill(rect); - } - - /** - * Fills a circular or elliptical arc covering the specified rectangle. - *

    - * The resulting arc begins at startAngle and extends - * for arcAngle degrees. - * Angles are interpreted such that 0 degrees - * is at the 3 o'clock position. - * A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - *

    - * The center of the arc is the center of the rectangle whose origin - * is (xy) and whose size is specified by the - * width and height arguments. - *

    - * The resulting arc covers an area - * width + 1 pixels wide - * by height + 1 pixels tall. - *

    - * The angles are specified relative to the non-square extents of - * the bounding rectangle such that 45 degrees always falls on the - * line from the center of the ellipse to the upper right corner of - * the bounding rectangle. As a result, if the bounding rectangle is - * noticeably longer in one axis than the other, the angles to the - * start and end of the arc segment will be skewed farther along the - * longer axis of the bounds. - * @param x the x coordinate of the - * upper-left corner of the arc to be filled. - * @param y the y coordinate of the - * upper-left corner of the arc to be filled. - * @param width the width of the arc to be filled. - * @param height the height of the arc to be filled. - * @param startAngle the beginning angle. - * @param arcAngle the angular extent of the arc, - * relative to the start angle. - * @see java.awt.Graphics#drawArc - */ - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle){ - Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE); - fill(arc); - } - - /** - * Draws the outline of a circular or elliptical arc - * covering the specified rectangle. - *

    - * The resulting arc begins at startAngle and extends - * for arcAngle degrees, using the current color. - * Angles are interpreted such that 0 degrees - * is at the 3 o'clock position. - * A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - *

    - * The center of the arc is the center of the rectangle whose origin - * is (xy) and whose size is specified by the - * width and height arguments. - *

    - * The resulting arc covers an area - * width + 1 pixels wide - * by height + 1 pixels tall. - *

    - * The angles are specified relative to the non-square extents of - * the bounding rectangle such that 45 degrees always falls on the - * line from the center of the ellipse to the upper right corner of - * the bounding rectangle. As a result, if the bounding rectangle is - * noticeably longer in one axis than the other, the angles to the - * start and end of the arc segment will be skewed farther along the - * longer axis of the bounds. - * @param x the x coordinate of the - * upper-left corner of the arc to be drawn. - * @param y the y coordinate of the - * upper-left corner of the arc to be drawn. - * @param width the width of the arc to be drawn. - * @param height the height of the arc to be drawn. - * @param startAngle the beginning angle. - * @param arcAngle the angular extent of the arc, - * relative to the start angle. - * @see java.awt.Graphics#fillArc - */ - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN); - draw(arc); - } - - - /** - * Draws a sequence of connected lines defined by - * arrays of x and y coordinates. - * Each pair of (xy) coordinates defines a point. - * The figure is not closed if the first point - * differs from the last point. - * @param xPoints an array of x points - * @param yPoints an array of y points - * @param nPoints the total number of points - * @see java.awt.Graphics#drawPolygon(int[], int[], int) - * @since JDK1.1 - */ - public void drawPolyline(int[] xPoints, int[] yPoints, - int nPoints){ - if(nPoints > 0){ - GeneralPath path = new GeneralPath(); - path.moveTo(xPoints[0], yPoints[0]); - for(int i=1; ix, y, - * width, and height arguments. - *

    - * The oval covers an area that is - * width + 1 pixels wide - * and height + 1 pixels tall. - * @param x the x coordinate of the upper left - * corner of the oval to be drawn. - * @param y the y coordinate of the upper left - * corner of the oval to be drawn. - * @param width the width of the oval to be drawn. - * @param height the height of the oval to be drawn. - * @see java.awt.Graphics#fillOval - */ - public void drawOval(int x, int y, int width, int height){ - Ellipse2D oval = new Ellipse2D.Double(x, y, width, height); - draw(oval); - } - - /** - * Draws as much of the specified image as is currently available. - * The image is drawn with its top-left corner at - * (xy) in this graphics context's coordinate - * space. Transparent pixels are drawn in the specified - * background color. - *

    - * This operation is equivalent to filling a rectangle of the - * width and height of the specified image with the given color and then - * drawing the image on top of it, but possibly more efficient. - *

    - * This method returns immediately in all cases, even if the - * complete image has not yet been loaded, and it has not been dithered - * and converted for the current output device. - *

    - * If the image has not yet been completely loaded, then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - * @param img the specified image to be drawn. - * @param x the x coordinate. - * @param y the y coordinate. - * @param bgcolor the background color to paint under the - * non-opaque portions of the image. - * @param observer object to be notified as more of - * the image is converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - Color bgcolor, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - - return false; - } - - /** - * Draws as much of the specified image as has already been scaled - * to fit inside the specified rectangle. - *

    - * The image is drawn inside the specified rectangle of this - * graphics context's coordinate space, and is scaled if - * necessary. Transparent pixels are drawn in the specified - * background color. - * This operation is equivalent to filling a rectangle of the - * width and height of the specified image with the given color and then - * drawing the image on top of it, but possibly more efficient. - *

    - * This method returns immediately in all cases, even if the - * entire image has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - *

    - * A scaled version of an image will not necessarily be - * available immediately just because an unscaled version of the - * image has been constructed for this output device. Each size of - * the image may be cached separately and generated from the original - * data in a separate image production sequence. - * @param img the specified image to be drawn. - * @param x the x coordinate. - * @param y the y coordinate. - * @param width the width of the rectangle. - * @param height the height of the rectangle. - * @param bgcolor the background color to paint under the - * non-opaque portions of the image. - * @param observer object to be notified as more of - * the image is converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - int width, int height, - Color bgcolor, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - - return false; - } - - - /** - * Draws as much of the specified area of the specified image as is - * currently available, scaling it on the fly to fit inside the - * specified area of the destination drawable surface. Transparent pixels - * do not affect whatever pixels are already there. - *

    - * This method returns immediately in all cases, even if the - * image area to be drawn has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - *

    - * This method always uses the unscaled version of the image - * to render the scaled rectangle and performs the required - * scaling on the fly. It does not use a cached, scaled version - * of the image for this operation. Scaling of the image from source - * to destination is performed such that the first coordinate - * of the source rectangle is mapped to the first coordinate of - * the destination rectangle, and the second source coordinate is - * mapped to the second destination coordinate. The subimage is - * scaled and flipped as needed to preserve those mappings. - * @param img the specified image to be drawn - * @param dx1 the x coordinate of the first corner of the - * destination rectangle. - * @param dy1 the y coordinate of the first corner of the - * destination rectangle. - * @param dx2 the x coordinate of the second corner of the - * destination rectangle. - * @param dy2 the y coordinate of the second corner of the - * destination rectangle. - * @param sx1 the x coordinate of the first corner of the - * source rectangle. - * @param sy1 the y coordinate of the first corner of the - * source rectangle. - * @param sx2 the x coordinate of the second corner of the - * source rectangle. - * @param sy2 the y coordinate of the second corner of the - * source rectangle. - * @param observer object to be notified as more of the image is - * scaled and converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - * @since JDK1.1 - */ - @NotImplemented - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Draws as much of the specified area of the specified image as is - * currently available, scaling it on the fly to fit inside the - * specified area of the destination drawable surface. - *

    - * Transparent pixels are drawn in the specified background color. - * This operation is equivalent to filling a rectangle of the - * width and height of the specified image with the given color and then - * drawing the image on top of it, but possibly more efficient. - *

    - * This method returns immediately in all cases, even if the - * image area to be drawn has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - *

    - * This method always uses the unscaled version of the image - * to render the scaled rectangle and performs the required - * scaling on the fly. It does not use a cached, scaled version - * of the image for this operation. Scaling of the image from source - * to destination is performed such that the first coordinate - * of the source rectangle is mapped to the first coordinate of - * the destination rectangle, and the second source coordinate is - * mapped to the second destination coordinate. The subimage is - * scaled and flipped as needed to preserve those mappings. - * @param img the specified image to be drawn - * @param dx1 the x coordinate of the first corner of the - * destination rectangle. - * @param dy1 the y coordinate of the first corner of the - * destination rectangle. - * @param dx2 the x coordinate of the second corner of the - * destination rectangle. - * @param dy2 the y coordinate of the second corner of the - * destination rectangle. - * @param sx1 the x coordinate of the first corner of the - * source rectangle. - * @param sy1 the y coordinate of the first corner of the - * source rectangle. - * @param sx2 the x coordinate of the second corner of the - * source rectangle. - * @param sy2 the y coordinate of the second corner of the - * source rectangle. - * @param bgcolor the background color to paint under the - * non-opaque portions of the image. - * @param observer object to be notified as more of the image is - * scaled and converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - * @since JDK1.1 - */ - @NotImplemented - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - Color bgcolor, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Draws as much of the specified image as is currently available. - * The image is drawn with its top-left corner at - * (xy) in this graphics context's coordinate - * space. Transparent pixels in the image do not affect whatever - * pixels are already there. - *

    - * This method returns immediately in all cases, even if the - * complete image has not yet been loaded, and it has not been dithered - * and converted for the current output device. - *

    - * If the image has completely loaded and its pixels are - * no longer being changed, then - * drawImage returns true. - * Otherwise, drawImage returns false - * and as more of - * the image becomes available - * or it is time to draw another frame of animation, - * the process that loads the image notifies - * the specified image observer. - * @param img the specified image to be drawn. This method does - * nothing if img is null. - * @param x the x coordinate. - * @param y the y coordinate. - * @param observer object to be notified as more of - * the image is converted. - * @return false if the image pixels are still changing; - * true otherwise. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - ImageObserver observer) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Disposes of this graphics context and releases - * any system resources that it is using. - * A Graphics object cannot be used after - * disposehas been called. - *

    - * When a Java program runs, a large number of Graphics - * objects can be created within a short time frame. - * Although the finalization process of the garbage collector - * also disposes of the same system resources, it is preferable - * to manually free the associated resources by calling this - * method rather than to rely on a finalization process which - * may not run to completion for a long period of time. - *

    - * Graphics objects which are provided as arguments to the - * paint and update methods - * of components are automatically released by the system when - * those methods return. For efficiency, programmers should - * call dispose when finished using - * a Graphics object only if it was created - * directly from a component or another Graphics object. - * @see java.awt.Graphics#finalize - * @see java.awt.Component#paint - * @see java.awt.Component#update - * @see java.awt.Component#getGraphics - * @see java.awt.Graphics#create - */ - public void dispose() { - } - - /** - * Draws a line, using the current color, between the points - * (x1, y1) and (x2, y2) - * in this graphics context's coordinate system. - * @param x1 the first point's x coordinate. - * @param y1 the first point's y coordinate. - * @param x2 the second point's x coordinate. - * @param y2 the second point's y coordinate. - */ - public void drawLine(int x1, int y1, int x2, int y2){ - Line2D line = new Line2D.Double(x1, y1, x2, y2); - draw(line); - } - - /** - * Fills a closed polygon defined by - * arrays of x and y coordinates. - *

    - * This method draws the polygon defined by nPoint line - * segments, where the first nPoint - 1 - * line segments are line segments from - * (xPoints[i - 1], yPoints[i - 1]) - * to (xPoints[i], yPoints[i]), for - * 1 ≤ i ≤ nPoints. - * The figure is automatically closed by drawing a line connecting - * the final point to the first point, if those points are different. - *

    - * The area inside the polygon is defined using an - * even-odd fill rule, also known as the alternating rule. - * @param xPoints a an array of x coordinates. - * @param yPoints a an array of y coordinates. - * @param nPoints a the total number of points. - * @see java.awt.Graphics#drawPolygon(int[], int[], int) - */ - public void fillPolygon(int[] xPoints, int[] yPoints, - int nPoints){ - java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints); - fill(polygon); - } - - /** - * Fills the specified rectangle. - * The left and right edges of the rectangle are at - * x and x + width - 1. - * The top and bottom edges are at - * y and y + height - 1. - * The resulting rectangle covers an area - * width pixels wide by - * height pixels tall. - * The rectangle is filled using the graphics context's current color. - * @param x the x coordinate - * of the rectangle to be filled. - * @param y the y coordinate - * of the rectangle to be filled. - * @param width the width of the rectangle to be filled. - * @param height the height of the rectangle to be filled. - * @see java.awt.Graphics#clearRect - * @see java.awt.Graphics#drawRect - */ - public void fillRect(int x, int y, int width, int height){ - Rectangle rect = new Rectangle(x, y, width, height); - fill(rect); - } - - /** - * Draws the outline of the specified rectangle. - * The left and right edges of the rectangle are at - * x and x + width. - * The top and bottom edges are at - * y and y + height. - * The rectangle is drawn using the graphics context's current color. - * @param x the x coordinate - * of the rectangle to be drawn. - * @param y the y coordinate - * of the rectangle to be drawn. - * @param width the width of the rectangle to be drawn. - * @param height the height of the rectangle to be drawn. - * @see java.awt.Graphics#fillRect - * @see java.awt.Graphics#clearRect - */ - public void drawRect(int x, int y, int width, int height) { - Rectangle rect = new Rectangle(x, y, width, height); - draw(rect); - } - - /** - * Draws a closed polygon defined by - * arrays of x and y coordinates. - * Each pair of (xy) coordinates defines a point. - *

    - * This method draws the polygon defined by nPoint line - * segments, where the first nPoint - 1 - * line segments are line segments from - * (xPoints[i - 1], yPoints[i - 1]) - * to (xPoints[i], yPoints[i]), for - * 1 ≤ i ≤ nPoints. - * The figure is automatically closed by drawing a line connecting - * the final point to the first point, if those points are different. - * @param xPoints a an array of x coordinates. - * @param yPoints a an array of y coordinates. - * @param nPoints a the total number of points. - * @see java.awt.Graphics#fillPolygon(int[],int[],int) - * @see java.awt.Graphics#drawPolyline - */ - public void drawPolygon(int[] xPoints, int[] yPoints, - int nPoints){ - java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints); - draw(polygon); - } - - /** - * Intersects the current clip with the specified rectangle. - * The resulting clipping area is the intersection of the current - * clipping area and the specified rectangle. If there is no - * current clipping area, either because the clip has never been - * set, or the clip has been cleared using setClip(null), - * the specified rectangle becomes the new clip. - * This method sets the user clip, which is independent of the - * clipping associated with device bounds and window visibility. - * This method can only be used to make the current clip smaller. - * To set the current clip larger, use any of the setClip methods. - * Rendering operations have no effect outside of the clipping area. - * @param x the x coordinate of the rectangle to intersect the clip with - * @param y the y coordinate of the rectangle to intersect the clip with - * @param width the width of the rectangle to intersect the clip with - * @param height the height of the rectangle to intersect the clip with - * @see #setClip(int, int, int, int) - * @see #setClip(Shape) - */ - public void clipRect(int x, int y, int width, int height){ - clip(new Rectangle(x, y, width, height)); - } - - /** - * Sets the current clipping area to an arbitrary clip shape. - * Not all objects that implement the Shape - * interface can be used to set the clip. The only - * Shape objects that are guaranteed to be - * supported are Shape objects that are - * obtained via the getClip method and via - * Rectangle objects. This method sets the - * user clip, which is independent of the clipping associated - * with device bounds and window visibility. - * @param clip the Shape to use to set the clip - * @see java.awt.Graphics#getClip() - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(int, int, int, int) - * @since JDK1.1 - */ - @NotImplemented - public void setClip(Shape clip) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Returns the bounding rectangle of the current clipping area. - * This method refers to the user clip, which is independent of the - * clipping associated with device bounds and window visibility. - * If no clip has previously been set, or if the clip has been - * cleared using setClip(null), this method returns - * null. - * The coordinates in the rectangle are relative to the coordinate - * system origin of this graphics context. - * @return the bounding rectangle of the current clipping area, - * or null if no clip is set. - * @see java.awt.Graphics#getClip - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(int, int, int, int) - * @see java.awt.Graphics#setClip(Shape) - * @since JDK1.1 - */ - public Rectangle getClipBounds(){ - Shape c = getClip(); - if (c==null) { - return null; - } - return c.getBounds(); - } - - /** - * Draws the text given by the specified iterator, using this - * graphics context's current color. The iterator has to specify a font - * for each character. The baseline of the - * first character is at position (xy) in this - * graphics context's coordinate system. - * @param iterator the iterator whose text is to be drawn - * @param x the x coordinate. - * @param y the y coordinate. - * @see java.awt.Graphics#drawBytes - * @see java.awt.Graphics#drawChars - */ - public void drawString(AttributedCharacterIterator iterator, - int x, int y){ - drawString(iterator, (float)x, (float)y); - } - - /** - * Clears the specified rectangle by filling it with the background - * color of the current drawing surface. This operation does not - * use the current paint mode. - *

    - * Beginning with Java 1.1, the background color - * of offscreen images may be system dependent. Applications should - * use setColor followed by fillRect to - * ensure that an offscreen image is cleared to a specific color. - * @param x the x coordinate of the rectangle to clear. - * @param y the y coordinate of the rectangle to clear. - * @param width the width of the rectangle to clear. - * @param height the height of the rectangle to clear. - * @see java.awt.Graphics#fillRect(int, int, int, int) - * @see java.awt.Graphics#drawRect - * @see java.awt.Graphics#setColor(java.awt.Color) - * @see java.awt.Graphics#setPaintMode - * @see java.awt.Graphics#setXORMode(java.awt.Color) - */ - public void clearRect(int x, int y, int width, int height) { - Paint paint = getPaint(); - setColor(getBackground()); - fillRect(x, y, width, height); - setPaint(paint); - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - } - - /** - * Sets the current clip to the rectangle specified by the given - * coordinates. This method sets the user clip, which is - * independent of the clipping associated with device bounds - * and window visibility. - * Rendering operations have no effect outside of the clipping area. - * @param x the x coordinate of the new clip rectangle. - * @param y the y coordinate of the new clip rectangle. - * @param width the width of the new clip rectangle. - * @param height the height of the new clip rectangle. - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(Shape) - * @since JDK1.1 - */ - public void setClip(int x, int y, int width, int height){ - setClip(new Rectangle(x, y, width, height)); - } - - /** - * Concatenates the current Graphics2D - * Transform with a rotation transform. - * Subsequent rendering is rotated by the specified radians relative - * to the previous origin. - * This is equivalent to calling transform(R), where R is an - * AffineTransform represented by the following matrix: - *

    -     *          [   cos(theta)    -sin(theta)    0   ]
    -     *          [   sin(theta)     cos(theta)    0   ]
    -     *          [       0              0         1   ]
    -     * 
    - * Rotating with a positive angle theta rotates points on the positive - * x axis toward the positive y axis. - * @param theta the angle of rotation in radians - */ - public void rotate(double theta){ - _transform.rotate(theta); - } - - /** - * Concatenates the current Graphics2D - * Transform with a translated rotation - * transform. Subsequent rendering is transformed by a transform - * which is constructed by translating to the specified location, - * rotating by the specified radians, and translating back by the same - * amount as the original translation. This is equivalent to the - * following sequence of calls: - *
    -     *          translate(x, y);
    -     *          rotate(theta);
    -     *          translate(-x, -y);
    -     * 
    - * Rotating with a positive angle theta rotates points on the positive - * x axis toward the positive y axis. - * @param theta the angle of rotation in radians - * @param x x coordinate of the origin of the rotation - * @param y y coordinate of the origin of the rotation - */ - public void rotate(double theta, double x, double y){ - _transform.rotate(theta, x, y); - } - - /** - * Concatenates the current Graphics2D - * Transform with a shearing transform. - * Subsequent renderings are sheared by the specified - * multiplier relative to the previous position. - * This is equivalent to calling transform(SH), where SH - * is an AffineTransform represented by the following - * matrix: - *
    -     *          [   1   shx   0   ]
    -     *          [  shy   1    0   ]
    -     *          [   0    0    1   ]
    -     * 
    - * @param shx the multiplier by which coordinates are shifted in - * the positive X axis direction as a function of their Y coordinate - * @param shy the multiplier by which coordinates are shifted in - * the positive Y axis direction as a function of their X coordinate - */ - public void shear(double shx, double shy){ - _transform.shear(shx, shy); - } - - /** - * Get the rendering context of the Font within this - * Graphics2D context. - * The {@link FontRenderContext} - * encapsulates application hints such as anti-aliasing and - * fractional metrics, as well as target device specific information - * such as dots-per-inch. This information should be provided by the - * application when using objects that perform typographical - * formatting, such as Font and - * TextLayout. This information should also be provided - * by applications that perform their own layout and need accurate - * measurements of various characteristics of glyphs such as advance - * and line height when various rendering hints have been applied to - * the text rendering. - * - * @return a reference to an instance of FontRenderContext. - * @see java.awt.font.FontRenderContext - * @see java.awt.Font#createGlyphVector(FontRenderContext,char[]) - * @see java.awt.font.TextLayout - * @since JDK1.2 - */ - public FontRenderContext getFontRenderContext() { - boolean isAntiAliased = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals( - getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING)); - boolean usesFractionalMetrics = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals( - getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS)); - - - return new FontRenderContext(new AffineTransform(), isAntiAliased, usesFractionalMetrics); - } - - /** - * Composes an AffineTransform object with the - * Transform in this Graphics2D according - * to the rule last-specified-first-applied. If the current - * Transform is Cx, the result of composition - * with Tx is a new Transform Cx'. Cx' becomes the - * current Transform for this Graphics2D. - * Transforming a point p by the updated Transform Cx' is - * equivalent to first transforming p by Tx and then transforming - * the result by the original Transform Cx. In other - * words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary, - * so further modifications to Tx do not affect rendering. - * @param Tx the AffineTransform object to be composed with - * the current Transform - * @see #setTransform - * @see AffineTransform - */ - public void transform(AffineTransform Tx) { - _transform.concatenate(Tx); - } - - /** - * Renders a BufferedImage that is - * filtered with a - * {@link BufferedImageOp}. - * The rendering attributes applied include the Clip, - * Transform - * and Composite attributes. This is equivalent to: - *
    -     * img1 = op.filter(img, null);
    -     * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
    -     * 
    - * @param img the BufferedImage to be rendered - * @param op the filter to be applied to the image before rendering - * @param x the x coordinate in user space where the image is rendered - * @param y the y coordinate in user space where the image is rendered - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip(Shape) - */ - public void drawImage(BufferedImage img, - BufferedImageOp op, - int x, - int y){ - img = op.filter(img, null); - drawImage(img, x, y, null); - } - - /** - * Sets the background color for the Graphics2D context. - * The background color is used for clearing a region. - * When a Graphics2D is constructed for a - * Component, the background color is - * inherited from the Component. Setting the background color - * in the Graphics2D context only affects the subsequent - * clearRect calls and not the background color of the - * Component. To change the background - * of the Component, use appropriate methods of - * the Component. - * @param color the background color that isused in - * subsequent calls to clearRect - * @see #getBackground - * @see java.awt.Graphics#clearRect - */ - public void setBackground(Color color) { - if(color == null) - return; - - _background = color; - } - - /** - * Returns the background color used for clearing a region. - * @return the current Graphics2D Color, - * which defines the background color. - * @see #setBackground - */ - public Color getBackground(){ - return _background; - } - - /** - * Sets the Composite for the Graphics2D context. - * The Composite is used in all drawing methods such as - * drawImage, drawString, draw, - * and fill. It specifies how new pixels are to be combined - * with the existing pixels on the graphics device during the rendering - * process. - *

    If this Graphics2D context is drawing to a - * Component on the display screen and the - * Composite is a custom object rather than an - * instance of the AlphaComposite class, and if - * there is a security manager, its checkPermission - * method is called with an AWTPermission("readDisplayPixels") - * permission. - * - * @param comp the Composite object to be used for rendering - * @throws SecurityException - * if a custom Composite object is being - * used to render to the screen and a security manager - * is set and its checkPermission method - * does not allow the operation. - * @see java.awt.Graphics#setXORMode - * @see java.awt.Graphics#setPaintMode - * @see java.awt.AlphaComposite - */ - @NotImplemented - public void setComposite(Composite comp){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Returns the current Composite in the - * Graphics2D context. - * @return the current Graphics2D Composite, - * which defines a compositing style. - * @see #setComposite - */ - @NotImplemented - public Composite getComposite(){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return null; - } - - /** - * Returns the value of a single preference for the rendering algorithms. - * Hint categories include controls for rendering quality and overall - * time/quality trade-off in the rendering process. Refer to the - * RenderingHints class for definitions of some common - * keys and values. - * @param hintKey the key corresponding to the hint to get. - * @return an object representing the value for the specified hint key. - * Some of the keys and their associated values are defined in the - * RenderingHints class. - * @see RenderingHints - */ - public Object getRenderingHint(RenderingHints.Key hintKey){ - return _hints.get(hintKey); - } - - /** - * Sets the value of a single preference for the rendering algorithms. - * Hint categories include controls for rendering quality and overall - * time/quality trade-off in the rendering process. Refer to the - * RenderingHints class for definitions of some common - * keys and values. - * @param hintKey the key of the hint to be set. - * @param hintValue the value indicating preferences for the specified - * hint category. - * @see RenderingHints - */ - public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue){ - _hints.put(hintKey, hintValue); - } - - - /** - * Renders the text of the specified - * {@link GlyphVector} using - * the Graphics2D context's rendering attributes. - * The rendering attributes applied include the Clip, - * Transform, Paint, and - * Composite attributes. The GlyphVector - * specifies individual glyphs from a {@link Font}. - * The GlyphVector can also contain the glyph positions. - * This is the fastest way to render a set of characters to the - * screen. - * - * @param g the GlyphVector to be rendered - * @param x the x position in user space where the glyphs should be - * rendered - * @param y the y position in user space where the glyphs should be - * rendered - * - * @see java.awt.Font#createGlyphVector(FontRenderContext, char[]) - * @see java.awt.font.GlyphVector - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #setTransform - * @see #setComposite - * @see #setClip(Shape) - */ - public void drawGlyphVector(GlyphVector g, float x, float y) { - Shape glyphOutline = g.getOutline(x, y); - fill(glyphOutline); - } - - /** - * Returns the device configuration associated with this - * Graphics2D. - * @return the device configuration - */ - public GraphicsConfiguration getDeviceConfiguration() { - return GraphicsEnvironment.getLocalGraphicsEnvironment(). - getDefaultScreenDevice().getDefaultConfiguration(); - } - - /** - * Sets the values of an arbitrary number of preferences for the - * rendering algorithms. - * Only values for the rendering hints that are present in the - * specified Map object are modified. - * All other preferences not present in the specified - * object are left unmodified. - * Hint categories include controls for rendering quality and - * overall time/quality trade-off in the rendering process. - * Refer to the RenderingHints class for definitions of - * some common keys and values. - * @param hints the rendering hints to be set - * @see RenderingHints - */ - public void addRenderingHints(Map hints){ - this._hints.putAll(hints); - } - - /** - * Concatenates the current - * Graphics2D Transform - * with a translation transform. - * Subsequent rendering is translated by the specified - * distance relative to the previous position. - * This is equivalent to calling transform(T), where T is an - * AffineTransform represented by the following matrix: - *

    -     *          [   1    0    tx  ]
    -     *          [   0    1    ty  ]
    -     *          [   0    0    1   ]
    -     * 
    - * @param tx the distance to translate along the x-axis - * @param ty the distance to translate along the y-axis - */ - public void translate(double tx, double ty){ - _transform.translate(tx, ty); - } - - /** - * Renders the text of the specified iterator, using the - * Graphics2D context's current Paint. The - * iterator must specify a font - * for each character. The baseline of the - * first character is at position (xy) in the - * User Space. - * The rendering attributes applied include the Clip, - * Transform, Paint, and - * Composite attributes. - * For characters in script systems such as Hebrew and Arabic, - * the glyphs can be rendered from right to left, in which case the - * coordinate supplied is the location of the leftmost character - * on the baseline. - * @param iterator the iterator whose text is to be rendered - * @param x the x coordinate where the iterator's text is to be - * rendered - * @param y the y coordinate where the iterator's text is to be - * rendered - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #setTransform - * @see #setComposite - * @see #setClip - */ - @NotImplemented - public void drawString(AttributedCharacterIterator iterator, float x, float y) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Checks whether or not the specified Shape intersects - * the specified {@link Rectangle}, which is in device - * space. If onStroke is false, this method checks - * whether or not the interior of the specified Shape - * intersects the specified Rectangle. If - * onStroke is true, this method checks - * whether or not the Stroke of the specified - * Shape outline intersects the specified - * Rectangle. - * The rendering attributes taken into account include the - * Clip, Transform, and Stroke - * attributes. - * @param rect the area in device space to check for a hit - * @param s the Shape to check for a hit - * @param onStroke flag used to choose between testing the - * stroked or the filled shape. If the flag is true, the - * Stroke oultine is tested. If the flag is - * false, the filled Shape is tested. - * @return true if there is a hit; false - * otherwise. - * @see #setStroke - * @see #fill(Shape) - * @see #draw(Shape) - * @see #_transform - * @see #setTransform - * @see #clip - * @see #setClip(Shape) - */ - public boolean hit(Rectangle rect, - Shape s, - boolean onStroke){ - if (onStroke) { - s = getStroke().createStrokedShape(s); - } - - s = getTransform().createTransformedShape(s); - - return s.intersects(rect); - } - - /** - * Gets the preferences for the rendering algorithms. Hint categories - * include controls for rendering quality and overall time/quality - * trade-off in the rendering process. - * Returns all of the hint key/value pairs that were ever specified in - * one operation. Refer to the - * RenderingHints class for definitions of some common - * keys and values. - * @return a reference to an instance of RenderingHints - * that contains the current preferences. - * @see RenderingHints - */ - public RenderingHints getRenderingHints(){ - return _hints; - } - - /** - * Replaces the values of all preferences for the rendering - * algorithms with the specified hints. - * The existing values for all rendering hints are discarded and - * the new set of known hints and values are initialized from the - * specified {@link Map} object. - * Hint categories include controls for rendering quality and - * overall time/quality trade-off in the rendering process. - * Refer to the RenderingHints class for definitions of - * some common keys and values. - * @param hints the rendering hints to be set - * @see RenderingHints - */ - public void setRenderingHints(Map hints){ - this._hints = new RenderingHints(null); - this._hints.putAll(hints); - } - - /** - * Renders an image, applying a transform from image space into user space - * before drawing. - * The transformation from user space into device space is done with - * the current Transform in the Graphics2D. - * The specified transformation is applied to the image before the - * transform attribute in the Graphics2D context is applied. - * The rendering attributes applied include the Clip, - * Transform, and Composite attributes. - * Note that no rendering is done if the specified transform is - * noninvertible. - * @param img the Image to be rendered - * @param xform the transformation from image space into user space - * @param obs the {@link ImageObserver} - * to be notified as more of the Image - * is converted - * @return true if the Image is - * fully loaded and completely rendered; - * false if the Image is still being loaded. - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip(Shape) - */ - @NotImplemented - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Draws as much of the specified image as has already been scaled - * to fit inside the specified rectangle. - *

    - * The image is drawn inside the specified rectangle of this - * graphics context's coordinate space, and is scaled if - * necessary. Transparent pixels do not affect whatever pixels - * are already there. - *

    - * This method returns immediately in all cases, even if the - * entire image has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete, then - * drawImage returns false. As more of - * the image becomes available, the process that loads the image notifies - * the image observer by calling its imageUpdate method. - *

    - * A scaled version of an image will not necessarily be - * available immediately just because an unscaled version of the - * image has been constructed for this output device. Each size of - * the image may be cached separately and generated from the original - * data in a separate image production sequence. - * @param img the specified image to be drawn. This method does - * nothing if img is null. - * @param x the x coordinate. - * @param y the y coordinate. - * @param width the width of the rectangle. - * @param height the height of the rectangle. - * @param observer object to be notified as more of - * the image is converted. - * @return false if the image pixels are still changing; - * true otherwise. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - int width, int height, - ImageObserver observer) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Creates a new Graphics object that is - * a copy of this Graphics object. - * @return a new graphics context that is a copy of - * this graphics context. - */ - public Graphics create() { - try { - return (Graphics)clone(); - } catch (CloneNotSupportedException e){ - throw new RuntimeException(e); - } - } - - /** - * Gets the font metrics for the specified font. - * @return the font metrics for the specified font. - * @param f the specified font - * @see java.awt.Graphics#getFont - * @see java.awt.FontMetrics - * @see java.awt.Graphics#getFontMetrics() - */ - @SuppressWarnings("deprecation") - @SuppressForbidden - public FontMetrics getFontMetrics(Font f) { - return Toolkit.getDefaultToolkit().getFontMetrics(f); - } - - /** - * Sets the paint mode of this graphics context to alternate between - * this graphics context's current color and the new specified color. - * This specifies that logical pixel operations are performed in the - * XOR mode, which alternates pixels between the current color and - * a specified XOR color. - *

    - * When drawing operations are performed, pixels which are the - * current color are changed to the specified color, and vice versa. - *

    - * Pixels that are of colors other than those two colors are changed - * in an unpredictable but reversible manner; if the same figure is - * drawn twice, then all pixels are restored to their original values. - * @param c1 the XOR alternation color - */ - @NotImplemented - public void setXORMode(Color c1) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Sets the paint mode of this graphics context to overwrite the - * destination with this graphics context's current color. - * This sets the logical pixel operation function to the paint or - * overwrite mode. All subsequent rendering operations will - * overwrite the destination with the current color. - */ - @NotImplemented - public void setPaintMode() { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Renders a - * {@link RenderableImage}, - * applying a transform from image space into user space before drawing. - * The transformation from user space into device space is done with - * the current Transform in the Graphics2D. - * The specified transformation is applied to the image before the - * transform attribute in the Graphics2D context is applied. - * The rendering attributes applied include the Clip, - * Transform, and Composite attributes. Note - * that no rendering is done if the specified transform is - * noninvertible. - *

    - * Rendering hints set on the Graphics2D object might - * be used in rendering the RenderableImage. - * If explicit control is required over specific hints recognized by a - * specific RenderableImage, or if knowledge of which hints - * are used is required, then a RenderedImage should be - * obtained directly from the RenderableImage - * and rendered using - *{@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. - * @param img the image to be rendered. This method does - * nothing if img is null. - * @param xform the transformation from image space into user space - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - * @see #drawRenderedImage - */ - @NotImplemented - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Renders a {@link RenderedImage}, - * applying a transform from image - * space into user space before drawing. - * The transformation from user space into device space is done with - * the current Transform in the Graphics2D. - * The specified transformation is applied to the image before the - * transform attribute in the Graphics2D context is applied. - * The rendering attributes applied include the Clip, - * Transform, and Composite attributes. Note - * that no rendering is done if the specified transform is - * noninvertible. - * @param img the image to be rendered. This method does - * nothing if img is null. - * @param xform the transformation from image space into user space - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - */ - @NotImplemented - public void drawRenderableImage(RenderableImage img, AffineTransform xform) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - protected void applyStroke(SimpleShape shape) { - if (_stroke instanceof BasicStroke){ - BasicStroke bs = (BasicStroke)_stroke; - shape.setStrokeStyle((double)bs.getLineWidth()); - float[] dash = bs.getDashArray(); - if (dash != null) { - //TODO: implement more dashing styles - shape.setStrokeStyle(StrokeStyle.LineDash.DASH); - } - } - } - - protected void applyPaint(SimpleShape shape) { - if (_paint instanceof Color) { - shape.setFillColor((Color)_paint); - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java deleted file mode 100644 index 32ee2a03b..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_AdjPoint2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_AdjPoint2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="x" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="y" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_AdjPoint2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTAdjPoint2D { - - @XmlAttribute(required = true) - protected String x; - @XmlAttribute(required = true) - protected String y; - - /** - * Gets the value of the x property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getX() { - return x; - } - - /** - * Sets the value of the x property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setX(String value) { - this.x = value; - } - - public boolean isSetX() { - return (this.x!= null); - } - - /** - * Gets the value of the y property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getY() { - return y; - } - - /** - * Sets the value of the y property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setY(String value) { - this.y = value; - } - - public boolean isSetY() { - return (this.y!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java deleted file mode 100644 index d684cccb7..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_AdjustHandleList complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_AdjustHandleList">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <choice maxOccurs="unbounded" minOccurs="0">
    - *         <element name="ahXY" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_XYAdjustHandle"/>
    - *         <element name="ahPolar" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_PolarAdjustHandle"/>
    - *       </choice>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_AdjustHandleList", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "ahXYOrAhPolar" -}) -public class CTAdjustHandleList { - - @XmlElements({ - @XmlElement(name = "ahXY", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTXYAdjustHandle.class), - @XmlElement(name = "ahPolar", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPolarAdjustHandle.class) - }) - protected List ahXYOrAhPolar; - - /** - * Gets the value of the ahXYOrAhPolar property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the ahXYOrAhPolar property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getAhXYOrAhPolar().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTXYAdjustHandle } - * {@link CTPolarAdjustHandle } - * - * - */ - public List getAhXYOrAhPolar() { - if (ahXYOrAhPolar == null) { - ahXYOrAhPolar = new ArrayList(); - } - return this.ahXYOrAhPolar; - } - - public boolean isSetAhXYOrAhPolar() { - return ((this.ahXYOrAhPolar!= null)&&(!this.ahXYOrAhPolar.isEmpty())); - } - - public void unsetAhXYOrAhPolar() { - this.ahXYOrAhPolar = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTAngle.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTAngle.java deleted file mode 100644 index 2e39602da..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTAngle.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Angle complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Angle">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Angle" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Angle", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTAngle { - - @XmlAttribute(required = true) - protected int val; - - /** - * Gets the value of the val property. - * - */ - public int getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - */ - public void setVal(int value) { - this.val = value; - } - - public boolean isSetVal() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTColor.java deleted file mode 100644 index dd3cca360..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTColor.java +++ /dev/null @@ -1,237 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Color complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Color">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorChoice"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Color", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "scrgbClr", - "srgbClr", - "hslClr", - "sysClr", - "schemeClr", - "prstClr" -}) -public class CTColor { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTScRgbColor scrgbClr; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTSRgbColor srgbClr; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTHslColor hslClr; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTSystemColor sysClr; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTSchemeColor schemeClr; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPresetColor prstClr; - - /** - * Gets the value of the scrgbClr property. - * - * @return - * possible object is - * {@link CTScRgbColor } - * - */ - public CTScRgbColor getScrgbClr() { - return scrgbClr; - } - - /** - * Sets the value of the scrgbClr property. - * - * @param value - * allowed object is - * {@link CTScRgbColor } - * - */ - public void setScrgbClr(CTScRgbColor value) { - this.scrgbClr = value; - } - - public boolean isSetScrgbClr() { - return (this.scrgbClr!= null); - } - - /** - * Gets the value of the srgbClr property. - * - * @return - * possible object is - * {@link CTSRgbColor } - * - */ - public CTSRgbColor getSrgbClr() { - return srgbClr; - } - - /** - * Sets the value of the srgbClr property. - * - * @param value - * allowed object is - * {@link CTSRgbColor } - * - */ - public void setSrgbClr(CTSRgbColor value) { - this.srgbClr = value; - } - - public boolean isSetSrgbClr() { - return (this.srgbClr!= null); - } - - /** - * Gets the value of the hslClr property. - * - * @return - * possible object is - * {@link CTHslColor } - * - */ - public CTHslColor getHslClr() { - return hslClr; - } - - /** - * Sets the value of the hslClr property. - * - * @param value - * allowed object is - * {@link CTHslColor } - * - */ - public void setHslClr(CTHslColor value) { - this.hslClr = value; - } - - public boolean isSetHslClr() { - return (this.hslClr!= null); - } - - /** - * Gets the value of the sysClr property. - * - * @return - * possible object is - * {@link CTSystemColor } - * - */ - public CTSystemColor getSysClr() { - return sysClr; - } - - /** - * Sets the value of the sysClr property. - * - * @param value - * allowed object is - * {@link CTSystemColor } - * - */ - public void setSysClr(CTSystemColor value) { - this.sysClr = value; - } - - public boolean isSetSysClr() { - return (this.sysClr!= null); - } - - /** - * Gets the value of the schemeClr property. - * - * @return - * possible object is - * {@link CTSchemeColor } - * - */ - public CTSchemeColor getSchemeClr() { - return schemeClr; - } - - /** - * Sets the value of the schemeClr property. - * - * @param value - * allowed object is - * {@link CTSchemeColor } - * - */ - public void setSchemeClr(CTSchemeColor value) { - this.schemeClr = value; - } - - public boolean isSetSchemeClr() { - return (this.schemeClr!= null); - } - - /** - * Gets the value of the prstClr property. - * - * @return - * possible object is - * {@link CTPresetColor } - * - */ - public CTPresetColor getPrstClr() { - return prstClr; - } - - /** - * Sets the value of the prstClr property. - * - * @param value - * allowed object is - * {@link CTPresetColor } - * - */ - public void setPrstClr(CTPresetColor value) { - this.prstClr = value; - } - - public boolean isSetPrstClr() { - return (this.prstClr!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTColorMRU.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTColorMRU.java deleted file mode 100644 index 973603de4..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTColorMRU.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_ColorMRU complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_ColorMRU">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorChoice" maxOccurs="10" minOccurs="0"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_ColorMRU", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorChoice" -}) -public class CTColorMRU { - - @XmlElements({ - @XmlElement(name = "prstClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPresetColor.class), - @XmlElement(name = "sysClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSystemColor.class), - @XmlElement(name = "hslClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTHslColor.class), - @XmlElement(name = "srgbClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSRgbColor.class), - @XmlElement(name = "scrgbClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTScRgbColor.class), - @XmlElement(name = "schemeClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSchemeColor.class) - }) - protected List egColorChoice; - - /** - * Gets the value of the egColorChoice property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorChoice property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorChoice().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTPresetColor } - * {@link CTSystemColor } - * {@link CTHslColor } - * {@link CTSRgbColor } - * {@link CTScRgbColor } - * {@link CTSchemeColor } - * - * - */ - public List getEGColorChoice() { - if (egColorChoice == null) { - egColorChoice = new ArrayList(); - } - return this.egColorChoice; - } - - public boolean isSetEGColorChoice() { - return ((this.egColorChoice!= null)&&(!this.egColorChoice.isEmpty())); - } - - public void unsetEGColorChoice() { - this.egColorChoice = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTComplementTransform.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTComplementTransform.java deleted file mode 100644 index dd1a56c0b..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTComplementTransform.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_ComplementTransform complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_ComplementTransform">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_ComplementTransform", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTComplementTransform { - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnection.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnection.java deleted file mode 100644 index 4af3fac71..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnection.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Connection complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Connection">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="id" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_DrawingElementId" />
    - *       <attribute name="idx" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedInt" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Connection", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTConnection { - - @XmlAttribute(required = true) - protected long id; - @XmlAttribute(required = true) - @XmlSchemaType(name = "unsignedInt") - protected long idx; - - /** - * Gets the value of the id property. - * - */ - public long getId() { - return id; - } - - /** - * Sets the value of the id property. - * - */ - public void setId(long value) { - this.id = value; - } - - public boolean isSetId() { - return true; - } - - /** - * Gets the value of the idx property. - * - */ - public long getIdx() { - return idx; - } - - /** - * Sets the value of the idx property. - * - */ - public void setIdx(long value) { - this.idx = value; - } - - public boolean isSetIdx() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnectionSite.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnectionSite.java deleted file mode 100644 index 7ec62972d..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnectionSite.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_ConnectionSite complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_ConnectionSite">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pos" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D"/>
    - *       </sequence>
    - *       <attribute name="ang" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjAngle" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_ConnectionSite", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pos" -}) -public class CTConnectionSite { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTAdjPoint2D pos; - @XmlAttribute(required = true) - protected String ang; - - /** - * Gets the value of the pos property. - * - * @return - * possible object is - * {@link CTAdjPoint2D } - * - */ - public CTAdjPoint2D getPos() { - return pos; - } - - /** - * Sets the value of the pos property. - * - * @param value - * allowed object is - * {@link CTAdjPoint2D } - * - */ - public void setPos(CTAdjPoint2D value) { - this.pos = value; - } - - public boolean isSetPos() { - return (this.pos!= null); - } - - /** - * Gets the value of the ang property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAng() { - return ang; - } - - /** - * Sets the value of the ang property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAng(String value) { - this.ang = value; - } - - public boolean isSetAng() { - return (this.ang!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java deleted file mode 100644 index a3c98898c..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_ConnectionSiteList complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_ConnectionSiteList">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="cxn" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_ConnectionSite" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_ConnectionSiteList", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "cxn" -}) -public class CTConnectionSiteList { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected List cxn; - - /** - * Gets the value of the cxn property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the cxn property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getCxn().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTConnectionSite } - * - * - */ - public List getCxn() { - if (cxn == null) { - cxn = new ArrayList(); - } - return this.cxn; - } - - public boolean isSetCxn() { - return ((this.cxn!= null)&&(!this.cxn.isEmpty())); - } - - public void unsetCxn() { - this.cxn = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java deleted file mode 100644 index d6856ee63..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java +++ /dev/null @@ -1,242 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_CustomGeometry2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_CustomGeometry2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="avLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_GeomGuideList" minOccurs="0"/>
    - *         <element name="gdLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_GeomGuideList" minOccurs="0"/>
    - *         <element name="ahLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjustHandleList" minOccurs="0"/>
    - *         <element name="cxnLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_ConnectionSiteList" minOccurs="0"/>
    - *         <element name="rect" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_GeomRect" minOccurs="0"/>
    - *         <element name="pathLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DList"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_CustomGeometry2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "avLst", - "gdLst", - "ahLst", - "cxnLst", - "rect", - "pathLst" -}) -public class CTCustomGeometry2D { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTGeomGuideList avLst; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTGeomGuideList gdLst; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTAdjustHandleList ahLst; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTConnectionSiteList cxnLst; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTGeomRect rect; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTPath2DList pathLst; - - /** - * Gets the value of the avLst property. - * - * @return - * possible object is - * {@link CTGeomGuideList } - * - */ - public CTGeomGuideList getAvLst() { - return avLst; - } - - /** - * Sets the value of the avLst property. - * - * @param value - * allowed object is - * {@link CTGeomGuideList } - * - */ - public void setAvLst(CTGeomGuideList value) { - this.avLst = value; - } - - public boolean isSetAvLst() { - return (this.avLst!= null); - } - - /** - * Gets the value of the gdLst property. - * - * @return - * possible object is - * {@link CTGeomGuideList } - * - */ - public CTGeomGuideList getGdLst() { - return gdLst; - } - - /** - * Sets the value of the gdLst property. - * - * @param value - * allowed object is - * {@link CTGeomGuideList } - * - */ - public void setGdLst(CTGeomGuideList value) { - this.gdLst = value; - } - - public boolean isSetGdLst() { - return (this.gdLst!= null); - } - - /** - * Gets the value of the ahLst property. - * - * @return - * possible object is - * {@link CTAdjustHandleList } - * - */ - public CTAdjustHandleList getAhLst() { - return ahLst; - } - - /** - * Sets the value of the ahLst property. - * - * @param value - * allowed object is - * {@link CTAdjustHandleList } - * - */ - public void setAhLst(CTAdjustHandleList value) { - this.ahLst = value; - } - - public boolean isSetAhLst() { - return (this.ahLst!= null); - } - - /** - * Gets the value of the cxnLst property. - * - * @return - * possible object is - * {@link CTConnectionSiteList } - * - */ - public CTConnectionSiteList getCxnLst() { - return cxnLst; - } - - /** - * Sets the value of the cxnLst property. - * - * @param value - * allowed object is - * {@link CTConnectionSiteList } - * - */ - public void setCxnLst(CTConnectionSiteList value) { - this.cxnLst = value; - } - - public boolean isSetCxnLst() { - return (this.cxnLst!= null); - } - - /** - * Gets the value of the rect property. - * - * @return - * possible object is - * {@link CTGeomRect } - * - */ - public CTGeomRect getRect() { - return rect; - } - - /** - * Sets the value of the rect property. - * - * @param value - * allowed object is - * {@link CTGeomRect } - * - */ - public void setRect(CTGeomRect value) { - this.rect = value; - } - - public boolean isSetRect() { - return (this.rect!= null); - } - - /** - * Gets the value of the pathLst property. - * - * @return - * possible object is - * {@link CTPath2DList } - * - */ - public CTPath2DList getPathLst() { - return pathLst; - } - - /** - * Sets the value of the pathLst property. - * - * @param value - * allowed object is - * {@link CTPath2DList } - * - */ - public void setPathLst(CTPath2DList value) { - this.pathLst = value; - } - - public boolean isSetPathLst() { - return (this.pathLst!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java deleted file mode 100644 index 94d44ece2..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java +++ /dev/null @@ -1,152 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_EmbeddedWAVAudioFile complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_EmbeddedWAVAudioFile">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute ref="{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed use="required""/>
    - *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" default="" />
    - *       <attribute name="builtIn" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_EmbeddedWAVAudioFile", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTEmbeddedWAVAudioFile { - - @XmlAttribute(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", required = true) - protected String embed; - @XmlAttribute - protected String name; - @XmlAttribute - protected Boolean builtIn; - - /** - * Embedded Audio File Relationship ID - * - * @return - * possible object is - * {@link String } - * - */ - public String getEmbed() { - return embed; - } - - /** - * Sets the value of the embed property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setEmbed(String value) { - this.embed = value; - } - - public boolean isSetEmbed() { - return (this.embed!= null); - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - if (name == null) { - return ""; - } else { - return name; - } - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - public boolean isSetName() { - return (this.name!= null); - } - - /** - * Gets the value of the builtIn property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isBuiltIn() { - if (builtIn == null) { - return false; - } else { - return builtIn; - } - } - - /** - * Sets the value of the builtIn property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setBuiltIn(boolean value) { - this.builtIn = value; - } - - public boolean isSetBuiltIn() { - return (this.builtIn!= null); - } - - public void unsetBuiltIn() { - this.builtIn = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTFixedPercentage.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTFixedPercentage.java deleted file mode 100644 index 92f41aee8..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTFixedPercentage.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_FixedPercentage complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_FixedPercentage">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_FixedPercentage" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_FixedPercentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTFixedPercentage { - - @XmlAttribute(required = true) - protected int val; - - /** - * Gets the value of the val property. - * - */ - public int getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - */ - public void setVal(int value) { - this.val = value; - } - - public boolean isSetVal() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGammaTransform.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTGammaTransform.java deleted file mode 100644 index 7cf6cb195..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGammaTransform.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_GammaTransform complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_GammaTransform">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_GammaTransform", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTGammaTransform { - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomGuide.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomGuide.java deleted file mode 100644 index 3df22093c..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomGuide.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

    Java class for CT_GeomGuide complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_GeomGuide">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="name" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_GeomGuideName" />
    - *       <attribute name="fmla" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_GeomGuideFormula" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_GeomGuide", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTGeomGuide { - - @XmlAttribute(required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - protected String name; - @XmlAttribute(required = true) - protected String fmla; - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - public boolean isSetName() { - return (this.name!= null); - } - - /** - * Gets the value of the fmla property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getFmla() { - return fmla; - } - - /** - * Sets the value of the fmla property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFmla(String value) { - this.fmla = value; - } - - public boolean isSetFmla() { - return (this.fmla!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomGuideList.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomGuideList.java deleted file mode 100644 index 4490933b4..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomGuideList.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_GeomGuideList complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_GeomGuideList">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="gd" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_GeomGuide" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_GeomGuideList", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "gd" -}) -public class CTGeomGuideList { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected List gd; - - /** - * Gets the value of the gd property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the gd property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getGd().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTGeomGuide } - * - * - */ - public List getGd() { - if (gd == null) { - gd = new ArrayList(); - } - return this.gd; - } - - public boolean isSetGd() { - return ((this.gd!= null)&&(!this.gd.isEmpty())); - } - - public void unsetGd() { - this.gd = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomRect.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomRect.java deleted file mode 100644 index b1368be29..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGeomRect.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_GeomRect complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_GeomRect">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="l" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="t" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="r" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="b" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_GeomRect", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTGeomRect { - - @XmlAttribute(required = true) - protected String l; - @XmlAttribute(required = true) - protected String t; - @XmlAttribute(required = true) - protected String r; - @XmlAttribute(required = true) - protected String b; - - /** - * Gets the value of the l property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getL() { - return l; - } - - /** - * Sets the value of the l property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setL(String value) { - this.l = value; - } - - public boolean isSetL() { - return (this.l!= null); - } - - /** - * Gets the value of the t property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getT() { - return t; - } - - /** - * Sets the value of the t property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setT(String value) { - this.t = value; - } - - public boolean isSetT() { - return (this.t!= null); - } - - /** - * Gets the value of the r property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getR() { - return r; - } - - /** - * Sets the value of the r property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setR(String value) { - this.r = value; - } - - public boolean isSetR() { - return (this.r!= null); - } - - /** - * Gets the value of the b property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getB() { - return b; - } - - /** - * Sets the value of the b property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setB(String value) { - this.b = value; - } - - public boolean isSetB() { - return (this.b!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java deleted file mode 100644 index 643db025a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_GrayscaleTransform complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_GrayscaleTransform">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_GrayscaleTransform", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTGrayscaleTransform { - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java deleted file mode 100644 index 6508613b1..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java +++ /dev/null @@ -1,296 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_GroupTransform2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_GroupTransform2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="off" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Point2D" minOccurs="0"/>
    - *         <element name="ext" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_PositiveSize2D" minOccurs="0"/>
    - *         <element name="chOff" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Point2D" minOccurs="0"/>
    - *         <element name="chExt" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_PositiveSize2D" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="rot" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Angle" default="0" />
    - *       <attribute name="flipH" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *       <attribute name="flipV" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_GroupTransform2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "off", - "ext", - "chOff", - "chExt" -}) -public class CTGroupTransform2D { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPoint2D off; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPositiveSize2D ext; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPoint2D chOff; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPositiveSize2D chExt; - @XmlAttribute - protected Integer rot; - @XmlAttribute - protected Boolean flipH; - @XmlAttribute - protected Boolean flipV; - - /** - * Gets the value of the off property. - * - * @return - * possible object is - * {@link CTPoint2D } - * - */ - public CTPoint2D getOff() { - return off; - } - - /** - * Sets the value of the off property. - * - * @param value - * allowed object is - * {@link CTPoint2D } - * - */ - public void setOff(CTPoint2D value) { - this.off = value; - } - - public boolean isSetOff() { - return (this.off!= null); - } - - /** - * Gets the value of the ext property. - * - * @return - * possible object is - * {@link CTPositiveSize2D } - * - */ - public CTPositiveSize2D getExt() { - return ext; - } - - /** - * Sets the value of the ext property. - * - * @param value - * allowed object is - * {@link CTPositiveSize2D } - * - */ - public void setExt(CTPositiveSize2D value) { - this.ext = value; - } - - public boolean isSetExt() { - return (this.ext!= null); - } - - /** - * Gets the value of the chOff property. - * - * @return - * possible object is - * {@link CTPoint2D } - * - */ - public CTPoint2D getChOff() { - return chOff; - } - - /** - * Sets the value of the chOff property. - * - * @param value - * allowed object is - * {@link CTPoint2D } - * - */ - public void setChOff(CTPoint2D value) { - this.chOff = value; - } - - public boolean isSetChOff() { - return (this.chOff!= null); - } - - /** - * Gets the value of the chExt property. - * - * @return - * possible object is - * {@link CTPositiveSize2D } - * - */ - public CTPositiveSize2D getChExt() { - return chExt; - } - - /** - * Sets the value of the chExt property. - * - * @param value - * allowed object is - * {@link CTPositiveSize2D } - * - */ - public void setChExt(CTPositiveSize2D value) { - this.chExt = value; - } - - public boolean isSetChExt() { - return (this.chExt!= null); - } - - /** - * Gets the value of the rot property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public int getRot() { - if (rot == null) { - return 0; - } else { - return rot; - } - } - - /** - * Sets the value of the rot property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setRot(int value) { - this.rot = value; - } - - public boolean isSetRot() { - return (this.rot!= null); - } - - public void unsetRot() { - this.rot = null; - } - - /** - * Gets the value of the flipH property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isFlipH() { - if (flipH == null) { - return false; - } else { - return flipH; - } - } - - /** - * Sets the value of the flipH property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setFlipH(boolean value) { - this.flipH = value; - } - - public boolean isSetFlipH() { - return (this.flipH!= null); - } - - public void unsetFlipH() { - this.flipH = null; - } - - /** - * Gets the value of the flipV property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isFlipV() { - if (flipV == null) { - return false; - } else { - return flipV; - } - } - - /** - * Sets the value of the flipV property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setFlipV(boolean value) { - this.flipV = value; - } - - public boolean isSetFlipV() { - return (this.flipV!= null); - } - - public void unsetFlipV() { - this.flipV = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTHslColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTHslColor.java deleted file mode 100644 index 53ced8d65..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTHslColor.java +++ /dev/null @@ -1,221 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_HslColor complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_HslColor">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorTransform" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="hue" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveFixedAngle" />
    - *       <attribute name="sat" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" />
    - *       <attribute name="lum" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_HslColor", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorTransform" -}) -public class CTHslColor { - - @XmlElementRefs({ - @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class) - }) - protected List> egColorTransform; - @XmlAttribute(required = true) - protected int hue; - @XmlAttribute(required = true) - protected int sat; - @XmlAttribute(required = true) - protected int lum; - - /** - * Gets the value of the egColorTransform property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorTransform property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorTransform().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * - * - */ - public List> getEGColorTransform() { - if (egColorTransform == null) { - egColorTransform = new ArrayList>(); - } - return this.egColorTransform; - } - - public boolean isSetEGColorTransform() { - return ((this.egColorTransform!= null)&&(!this.egColorTransform.isEmpty())); - } - - public void unsetEGColorTransform() { - this.egColorTransform = null; - } - - /** - * Gets the value of the hue property. - * - */ - public int getHue() { - return hue; - } - - /** - * Sets the value of the hue property. - * - */ - public void setHue(int value) { - this.hue = value; - } - - public boolean isSetHue() { - return true; - } - - /** - * Gets the value of the sat property. - * - */ - public int getSat() { - return sat; - } - - /** - * Sets the value of the sat property. - * - */ - public void setSat(int value) { - this.sat = value; - } - - public boolean isSetSat() { - return true; - } - - /** - * Gets the value of the lum property. - * - */ - public int getLum() { - return lum; - } - - /** - * Sets the value of the lum property. - * - */ - public void setLum(int value) { - this.lum = value; - } - - public boolean isSetLum() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTHyperlink.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTHyperlink.java deleted file mode 100644 index 03e486af5..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTHyperlink.java +++ /dev/null @@ -1,403 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Hyperlink complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Hyperlink">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="snd" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_EmbeddedWAVAudioFile" minOccurs="0"/>
    - *         <element name="extLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_OfficeArtExtensionList" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute ref="{http://schemas.openxmlformats.org/officeDocument/2006/relationships}id"/>
    - *       <attribute name="invalidUrl" type="{http://www.w3.org/2001/XMLSchema}string" default="" />
    - *       <attribute name="action" type="{http://www.w3.org/2001/XMLSchema}string" default="" />
    - *       <attribute name="tgtFrame" type="{http://www.w3.org/2001/XMLSchema}string" default="" />
    - *       <attribute name="tooltip" type="{http://www.w3.org/2001/XMLSchema}string" default="" />
    - *       <attribute name="history" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
    - *       <attribute name="highlightClick" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *       <attribute name="endSnd" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Hyperlink", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "snd", - "extLst" -}) -public class CTHyperlink { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTEmbeddedWAVAudioFile snd; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTOfficeArtExtensionList extLst; - @XmlAttribute(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships") - protected String id; - @XmlAttribute - protected String invalidUrl; - @XmlAttribute - protected String action; - @XmlAttribute - protected String tgtFrame; - @XmlAttribute - protected String tooltip; - @XmlAttribute - protected Boolean history; - @XmlAttribute - protected Boolean highlightClick; - @XmlAttribute - protected Boolean endSnd; - - /** - * Gets the value of the snd property. - * - * @return - * possible object is - * {@link CTEmbeddedWAVAudioFile } - * - */ - public CTEmbeddedWAVAudioFile getSnd() { - return snd; - } - - /** - * Sets the value of the snd property. - * - * @param value - * allowed object is - * {@link CTEmbeddedWAVAudioFile } - * - */ - public void setSnd(CTEmbeddedWAVAudioFile value) { - this.snd = value; - } - - public boolean isSetSnd() { - return (this.snd!= null); - } - - /** - * Gets the value of the extLst property. - * - * @return - * possible object is - * {@link CTOfficeArtExtensionList } - * - */ - public CTOfficeArtExtensionList getExtLst() { - return extLst; - } - - /** - * Sets the value of the extLst property. - * - * @param value - * allowed object is - * {@link CTOfficeArtExtensionList } - * - */ - public void setExtLst(CTOfficeArtExtensionList value) { - this.extLst = value; - } - - public boolean isSetExtLst() { - return (this.extLst!= null); - } - - /** - * Drawing Object Hyperlink Target - * - * @return - * possible object is - * {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - public boolean isSetId() { - return (this.id!= null); - } - - /** - * Gets the value of the invalidUrl property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getInvalidUrl() { - if (invalidUrl == null) { - return ""; - } else { - return invalidUrl; - } - } - - /** - * Sets the value of the invalidUrl property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setInvalidUrl(String value) { - this.invalidUrl = value; - } - - public boolean isSetInvalidUrl() { - return (this.invalidUrl!= null); - } - - /** - * Gets the value of the action property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAction() { - if (action == null) { - return ""; - } else { - return action; - } - } - - /** - * Sets the value of the action property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAction(String value) { - this.action = value; - } - - public boolean isSetAction() { - return (this.action!= null); - } - - /** - * Gets the value of the tgtFrame property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTgtFrame() { - if (tgtFrame == null) { - return ""; - } else { - return tgtFrame; - } - } - - /** - * Sets the value of the tgtFrame property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTgtFrame(String value) { - this.tgtFrame = value; - } - - public boolean isSetTgtFrame() { - return (this.tgtFrame!= null); - } - - /** - * Gets the value of the tooltip property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTooltip() { - if (tooltip == null) { - return ""; - } else { - return tooltip; - } - } - - /** - * Sets the value of the tooltip property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTooltip(String value) { - this.tooltip = value; - } - - public boolean isSetTooltip() { - return (this.tooltip!= null); - } - - /** - * Gets the value of the history property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isHistory() { - if (history == null) { - return true; - } else { - return history; - } - } - - /** - * Sets the value of the history property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setHistory(boolean value) { - this.history = value; - } - - public boolean isSetHistory() { - return (this.history!= null); - } - - public void unsetHistory() { - this.history = null; - } - - /** - * Gets the value of the highlightClick property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isHighlightClick() { - if (highlightClick == null) { - return false; - } else { - return highlightClick; - } - } - - /** - * Sets the value of the highlightClick property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setHighlightClick(boolean value) { - this.highlightClick = value; - } - - public boolean isSetHighlightClick() { - return (this.highlightClick!= null); - } - - public void unsetHighlightClick() { - this.highlightClick = null; - } - - /** - * Gets the value of the endSnd property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isEndSnd() { - if (endSnd == null) { - return false; - } else { - return endSnd; - } - } - - /** - * Sets the value of the endSnd property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setEndSnd(boolean value) { - this.endSnd = value; - } - - public boolean isSetEndSnd() { - return (this.endSnd!= null); - } - - public void unsetEndSnd() { - this.endSnd = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java deleted file mode 100644 index eaff064d7..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_InverseGammaTransform complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_InverseGammaTransform">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_InverseGammaTransform", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTInverseGammaTransform { - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTInverseTransform.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTInverseTransform.java deleted file mode 100644 index 84af62533..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTInverseTransform.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_InverseTransform complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_InverseTransform">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_InverseTransform", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTInverseTransform { - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java deleted file mode 100644 index 62edc57b9..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java +++ /dev/null @@ -1,122 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAnyElement; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.w3c.dom.Element; - - -/** - *

    Java class for CT_OfficeArtExtension complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_OfficeArtExtension">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <any processContents='lax'/>
    - *       </sequence>
    - *       <attribute name="uri" type="{http://www.w3.org/2001/XMLSchema}token" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_OfficeArtExtension", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "any" -}) -public class CTOfficeArtExtension { - - @XmlAnyElement(lax = true) - protected Object any; - @XmlAttribute - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "token") - protected String uri; - - /** - * Gets the value of the any property. - * - * @return - * possible object is - * {@link Object } - * {@link Element } - * - */ - public Object getAny() { - return any; - } - - /** - * Sets the value of the any property. - * - * @param value - * allowed object is - * {@link Object } - * {@link Element } - * - */ - public void setAny(Object value) { - this.any = value; - } - - public boolean isSetAny() { - return (this.any!= null); - } - - /** - * Gets the value of the uri property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUri() { - return uri; - } - - /** - * Sets the value of the uri property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUri(String value) { - this.uri = value; - } - - public boolean isSetUri() { - return (this.uri!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java deleted file mode 100644 index f0b54cb18..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_OfficeArtExtensionList complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_OfficeArtExtensionList">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_OfficeArtExtensionList"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_OfficeArtExtensionList", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "ext" -}) -public class CTOfficeArtExtensionList { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected List ext; - - /** - * Gets the value of the ext property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the ext property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getExt().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTOfficeArtExtension } - * - * - */ - public List getExt() { - if (ext == null) { - ext = new ArrayList(); - } - return this.ext; - } - - public boolean isSetExt() { - return ((this.ext!= null)&&(!this.ext.isEmpty())); - } - - public void unsetExt() { - this.ext = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2D.java deleted file mode 100644 index 25fcd4923..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2D.java +++ /dev/null @@ -1,303 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <choice maxOccurs="unbounded" minOccurs="0">
    - *         <element name="close" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DClose"/>
    - *         <element name="moveTo" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DMoveTo"/>
    - *         <element name="lnTo" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DLineTo"/>
    - *         <element name="arcTo" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DArcTo"/>
    - *         <element name="quadBezTo" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DQuadBezierTo"/>
    - *         <element name="cubicBezTo" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2DCubicBezierTo"/>
    - *       </choice>
    - *       <attribute name="w" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveCoordinate" default="0" />
    - *       <attribute name="h" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveCoordinate" default="0" />
    - *       <attribute name="fill" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PathFillMode" default="norm" />
    - *       <attribute name="stroke" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
    - *       <attribute name="extrusionOk" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "closeOrMoveToOrLnTo" -}) -public class CTPath2D { - - @XmlElements({ - @XmlElement(name = "lnTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DLineTo.class), - @XmlElement(name = "close", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DClose.class), - @XmlElement(name = "cubicBezTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DCubicBezierTo.class), - @XmlElement(name = "quadBezTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DQuadBezierTo.class), - @XmlElement(name = "arcTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DArcTo.class), - @XmlElement(name = "moveTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DMoveTo.class) - }) - protected List closeOrMoveToOrLnTo; - @XmlAttribute - protected Long w; - @XmlAttribute - protected Long h; - @XmlAttribute - protected STPathFillMode fill; - @XmlAttribute - protected Boolean stroke; - @XmlAttribute - protected Boolean extrusionOk; - - /** - * Gets the value of the closeOrMoveToOrLnTo property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the closeOrMoveToOrLnTo property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getCloseOrMoveToOrLnTo().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTPath2DLineTo } - * {@link CTPath2DClose } - * {@link CTPath2DCubicBezierTo } - * {@link CTPath2DQuadBezierTo } - * {@link CTPath2DArcTo } - * {@link CTPath2DMoveTo } - * - * - */ - public List getCloseOrMoveToOrLnTo() { - if (closeOrMoveToOrLnTo == null) { - closeOrMoveToOrLnTo = new ArrayList(); - } - return this.closeOrMoveToOrLnTo; - } - - public boolean isSetCloseOrMoveToOrLnTo() { - return ((this.closeOrMoveToOrLnTo!= null)&&(!this.closeOrMoveToOrLnTo.isEmpty())); - } - - public void unsetCloseOrMoveToOrLnTo() { - this.closeOrMoveToOrLnTo = null; - } - - /** - * Gets the value of the w property. - * - * @return - * possible object is - * {@link Long } - * - */ - public long getW() { - if (w == null) { - return 0L; - } else { - return w; - } - } - - /** - * Sets the value of the w property. - * - * @param value - * allowed object is - * {@link Long } - * - */ - public void setW(long value) { - this.w = value; - } - - public boolean isSetW() { - return (this.w!= null); - } - - public void unsetW() { - this.w = null; - } - - /** - * Gets the value of the h property. - * - * @return - * possible object is - * {@link Long } - * - */ - public long getH() { - if (h == null) { - return 0L; - } else { - return h; - } - } - - /** - * Sets the value of the h property. - * - * @param value - * allowed object is - * {@link Long } - * - */ - public void setH(long value) { - this.h = value; - } - - public boolean isSetH() { - return (this.h!= null); - } - - public void unsetH() { - this.h = null; - } - - /** - * Gets the value of the fill property. - * - * @return - * possible object is - * {@link STPathFillMode } - * - */ - public STPathFillMode getFill() { - if (fill == null) { - return STPathFillMode.NORM; - } else { - return fill; - } - } - - /** - * Sets the value of the fill property. - * - * @param value - * allowed object is - * {@link STPathFillMode } - * - */ - public void setFill(STPathFillMode value) { - this.fill = value; - } - - public boolean isSetFill() { - return (this.fill!= null); - } - - /** - * Gets the value of the stroke property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isStroke() { - if (stroke == null) { - return true; - } else { - return stroke; - } - } - - /** - * Sets the value of the stroke property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setStroke(boolean value) { - this.stroke = value; - } - - public boolean isSetStroke() { - return (this.stroke!= null); - } - - public void unsetStroke() { - this.stroke = null; - } - - /** - * Gets the value of the extrusionOk property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isExtrusionOk() { - if (extrusionOk == null) { - return true; - } else { - return extrusionOk; - } - } - - /** - * Sets the value of the extrusionOk property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setExtrusionOk(boolean value) { - this.extrusionOk = value; - } - - public boolean isSetExtrusionOk() { - return (this.extrusionOk!= null); - } - - public void unsetExtrusionOk() { - this.extrusionOk = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java deleted file mode 100644 index a4c325aa1..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DArcTo complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DArcTo">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="wR" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="hR" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="stAng" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjAngle" />
    - *       <attribute name="swAng" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjAngle" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DArcTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPath2DArcTo { - - @XmlAttribute(name = "wR", required = true) - protected String wr; - @XmlAttribute(name = "hR", required = true) - protected String hr; - @XmlAttribute(required = true) - protected String stAng; - @XmlAttribute(required = true) - protected String swAng; - - /** - * Gets the value of the wr property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getWR() { - return wr; - } - - /** - * Sets the value of the wr property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setWR(String value) { - this.wr = value; - } - - public boolean isSetWR() { - return (this.wr!= null); - } - - /** - * Gets the value of the hr property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getHR() { - return hr; - } - - /** - * Sets the value of the hr property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setHR(String value) { - this.hr = value; - } - - public boolean isSetHR() { - return (this.hr!= null); - } - - /** - * Gets the value of the stAng property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStAng() { - return stAng; - } - - /** - * Sets the value of the stAng property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStAng(String value) { - this.stAng = value; - } - - public boolean isSetStAng() { - return (this.stAng!= null); - } - - /** - * Gets the value of the swAng property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSwAng() { - return swAng; - } - - /** - * Sets the value of the swAng property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSwAng(String value) { - this.swAng = value; - } - - public boolean isSetSwAng() { - return (this.swAng!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DClose.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DClose.java deleted file mode 100644 index a60f98bb6..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DClose.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DClose complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DClose">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DClose", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPath2DClose { - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java deleted file mode 100644 index e1818fa5d..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DCubicBezierTo complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DCubicBezierTo">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pt" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D" maxOccurs="3" minOccurs="3"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DCubicBezierTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pt" -}) -public class CTPath2DCubicBezierTo { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected List pt; - - /** - * Gets the value of the pt property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the pt property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getPt().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTAdjPoint2D } - * - * - */ - public List getPt() { - if (pt == null) { - pt = new ArrayList(); - } - return this.pt; - } - - public boolean isSetPt() { - return ((this.pt!= null)&&(!this.pt.isEmpty())); - } - - public void unsetPt() { - this.pt = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java deleted file mode 100644 index 9c6d1b39a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DLineTo complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DLineTo">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pt" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DLineTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pt" -}) -public class CTPath2DLineTo { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTAdjPoint2D pt; - - /** - * Gets the value of the pt property. - * - * @return - * possible object is - * {@link CTAdjPoint2D } - * - */ - public CTAdjPoint2D getPt() { - return pt; - } - - /** - * Sets the value of the pt property. - * - * @param value - * allowed object is - * {@link CTAdjPoint2D } - * - */ - public void setPt(CTAdjPoint2D value) { - this.pt = value; - } - - public boolean isSetPt() { - return (this.pt!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DList.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DList.java deleted file mode 100644 index cd31a0ba5..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DList.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DList complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DList">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="path" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Path2D" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DList", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "path" -}) -public class CTPath2DList { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected List path; - - /** - * Gets the value of the path property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the path property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getPath().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTPath2D } - * - * - */ - public List getPath() { - if (path == null) { - path = new ArrayList(); - } - return this.path; - } - - public boolean isSetPath() { - return ((this.path!= null)&&(!this.path.isEmpty())); - } - - public void unsetPath() { - this.path = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java deleted file mode 100644 index f5e210f76..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DMoveTo complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DMoveTo">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pt" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DMoveTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pt" -}) -public class CTPath2DMoveTo { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTAdjPoint2D pt; - - /** - * Gets the value of the pt property. - * - * @return - * possible object is - * {@link CTAdjPoint2D } - * - */ - public CTAdjPoint2D getPt() { - return pt; - } - - /** - * Sets the value of the pt property. - * - * @param value - * allowed object is - * {@link CTAdjPoint2D } - * - */ - public void setPt(CTAdjPoint2D value) { - this.pt = value; - } - - public boolean isSetPt() { - return (this.pt!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java deleted file mode 100644 index b58877524..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Path2DQuadBezierTo complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Path2DQuadBezierTo">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pt" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D" maxOccurs="2" minOccurs="2"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Path2DQuadBezierTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pt" -}) -public class CTPath2DQuadBezierTo { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected List pt; - - /** - * Gets the value of the pt property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the pt property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getPt().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link CTAdjPoint2D } - * - * - */ - public List getPt() { - if (pt == null) { - pt = new ArrayList(); - } - return this.pt; - } - - public boolean isSetPt() { - return ((this.pt!= null)&&(!this.pt.isEmpty())); - } - - public void unsetPt() { - this.pt = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPercentage.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPercentage.java deleted file mode 100644 index 7ca8c1fec..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPercentage.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Percentage complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Percentage">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Percentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPercentage { - - @XmlAttribute(required = true) - protected int val; - - /** - * Gets the value of the val property. - * - */ - public int getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - */ - public void setVal(int value) { - this.val = value; - } - - public boolean isSetVal() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPoint2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPoint2D.java deleted file mode 100644 index ae8798603..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPoint2D.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Point2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Point2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="x" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *       <attribute name="y" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Point2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPoint2D { - - @XmlAttribute(required = true) - protected long x; - @XmlAttribute(required = true) - protected long y; - - /** - * Gets the value of the x property. - * - */ - public long getX() { - return x; - } - - /** - * Sets the value of the x property. - * - */ - public void setX(long value) { - this.x = value; - } - - public boolean isSetX() { - return true; - } - - /** - * Gets the value of the y property. - * - */ - public long getY() { - return y; - } - - /** - * Sets the value of the y property. - * - */ - public void setY(long value) { - this.y = value; - } - - public boolean isSetY() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPoint3D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPoint3D.java deleted file mode 100644 index e14c6ba4f..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPoint3D.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Point3D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Point3D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="x" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *       <attribute name="y" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *       <attribute name="z" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Point3D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPoint3D { - - @XmlAttribute(required = true) - protected long x; - @XmlAttribute(required = true) - protected long y; - @XmlAttribute(required = true) - protected long z; - - /** - * Gets the value of the x property. - * - */ - public long getX() { - return x; - } - - /** - * Sets the value of the x property. - * - */ - public void setX(long value) { - this.x = value; - } - - public boolean isSetX() { - return true; - } - - /** - * Gets the value of the y property. - * - */ - public long getY() { - return y; - } - - /** - * Sets the value of the y property. - * - */ - public void setY(long value) { - this.y = value; - } - - public boolean isSetY() { - return true; - } - - /** - * Gets the value of the z property. - * - */ - public long getZ() { - return z; - } - - /** - * Sets the value of the z property. - * - */ - public void setZ(long value) { - this.z = value; - } - - public boolean isSetZ() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java deleted file mode 100644 index 9547ca988..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java +++ /dev/null @@ -1,273 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

    Java class for CT_PolarAdjustHandle complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PolarAdjustHandle">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pos" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D"/>
    - *       </sequence>
    - *       <attribute name="gdRefR" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_GeomGuideName" />
    - *       <attribute name="minR" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="maxR" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="gdRefAng" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_GeomGuideName" />
    - *       <attribute name="minAng" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjAngle" />
    - *       <attribute name="maxAng" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjAngle" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PolarAdjustHandle", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pos" -}) -public class CTPolarAdjustHandle { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTAdjPoint2D pos; - @XmlAttribute - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - protected String gdRefR; - @XmlAttribute - protected String minR; - @XmlAttribute - protected String maxR; - @XmlAttribute - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - protected String gdRefAng; - @XmlAttribute - protected String minAng; - @XmlAttribute - protected String maxAng; - - /** - * Gets the value of the pos property. - * - * @return - * possible object is - * {@link CTAdjPoint2D } - * - */ - public CTAdjPoint2D getPos() { - return pos; - } - - /** - * Sets the value of the pos property. - * - * @param value - * allowed object is - * {@link CTAdjPoint2D } - * - */ - public void setPos(CTAdjPoint2D value) { - this.pos = value; - } - - public boolean isSetPos() { - return (this.pos!= null); - } - - /** - * Gets the value of the gdRefR property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getGdRefR() { - return gdRefR; - } - - /** - * Sets the value of the gdRefR property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setGdRefR(String value) { - this.gdRefR = value; - } - - public boolean isSetGdRefR() { - return (this.gdRefR!= null); - } - - /** - * Gets the value of the minR property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMinR() { - return minR; - } - - /** - * Sets the value of the minR property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMinR(String value) { - this.minR = value; - } - - public boolean isSetMinR() { - return (this.minR!= null); - } - - /** - * Gets the value of the maxR property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMaxR() { - return maxR; - } - - /** - * Sets the value of the maxR property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMaxR(String value) { - this.maxR = value; - } - - public boolean isSetMaxR() { - return (this.maxR!= null); - } - - /** - * Gets the value of the gdRefAng property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getGdRefAng() { - return gdRefAng; - } - - /** - * Sets the value of the gdRefAng property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setGdRefAng(String value) { - this.gdRefAng = value; - } - - public boolean isSetGdRefAng() { - return (this.gdRefAng!= null); - } - - /** - * Gets the value of the minAng property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMinAng() { - return minAng; - } - - /** - * Sets the value of the minAng property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMinAng(String value) { - this.minAng = value; - } - - public boolean isSetMinAng() { - return (this.minAng!= null); - } - - /** - * Gets the value of the maxAng property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMaxAng() { - return maxAng; - } - - /** - * Sets the value of the maxAng property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMaxAng(String value) { - this.maxAng = value; - } - - public boolean isSetMaxAng() { - return (this.maxAng!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java deleted file mode 100644 index 94348d9bf..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PositiveFixedAngle complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PositiveFixedAngle">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveFixedAngle" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PositiveFixedAngle", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPositiveFixedAngle { - - @XmlAttribute(required = true) - protected int val; - - /** - * Gets the value of the val property. - * - */ - public int getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - */ - public void setVal(int value) { - this.val = value; - } - - public boolean isSetVal() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java deleted file mode 100644 index de659159e..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PositiveFixedPercentage complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PositiveFixedPercentage">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveFixedPercentage" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PositiveFixedPercentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPositiveFixedPercentage { - - @XmlAttribute(required = true) - protected int val; - - /** - * Gets the value of the val property. - * - */ - public int getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - */ - public void setVal(int value) { - this.val = value; - } - - public boolean isSetVal() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositivePercentage.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositivePercentage.java deleted file mode 100644 index 7b377e144..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositivePercentage.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PositivePercentage complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PositivePercentage">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositivePercentage" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PositivePercentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPositivePercentage { - - @XmlAttribute(required = true) - protected int val; - - /** - * Gets the value of the val property. - * - */ - public int getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - */ - public void setVal(int value) { - this.val = value; - } - - public boolean isSetVal() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java deleted file mode 100644 index 210fd925a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PositiveSize2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PositiveSize2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="cx" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveCoordinate" />
    - *       <attribute name="cy" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveCoordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PositiveSize2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTPositiveSize2D { - - @XmlAttribute(required = true) - protected long cx; - @XmlAttribute(required = true) - protected long cy; - - /** - * Gets the value of the cx property. - * - */ - public long getCx() { - return cx; - } - - /** - * Sets the value of the cx property. - * - */ - public void setCx(long value) { - this.cx = value; - } - - public boolean isSetCx() { - return true; - } - - /** - * Gets the value of the cy property. - * - */ - public long getCy() { - return cy; - } - - /** - * Sets the value of the cy property. - * - */ - public void setCy(long value) { - this.cy = value; - } - - public boolean isSetCy() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetColor.java deleted file mode 100644 index 595d1c596..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetColor.java +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PresetColor complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PresetColor">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorTransform" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="val" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PresetColorVal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PresetColor", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorTransform" -}) -public class CTPresetColor { - - @XmlElementRefs({ - @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class) - }) - protected List> egColorTransform; - @XmlAttribute - protected STPresetColorVal val; - - /** - * Gets the value of the egColorTransform property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorTransform property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorTransform().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * - * - */ - public List> getEGColorTransform() { - if (egColorTransform == null) { - egColorTransform = new ArrayList>(); - } - return this.egColorTransform; - } - - public boolean isSetEGColorTransform() { - return ((this.egColorTransform!= null)&&(!this.egColorTransform.isEmpty())); - } - - public void unsetEGColorTransform() { - this.egColorTransform = null; - } - - /** - * Gets the value of the val property. - * - * @return - * possible object is - * {@link STPresetColorVal } - * - */ - public STPresetColorVal getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - * @param value - * allowed object is - * {@link STPresetColorVal } - * - */ - public void setVal(STPresetColorVal value) { - this.val = value; - } - - public boolean isSetVal() { - return (this.val!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java deleted file mode 100644 index 234bbd95f..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PresetGeometry2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PresetGeometry2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="avLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_GeomGuideList" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="prst" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_ShapeType" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PresetGeometry2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "avLst" -}) -public class CTPresetGeometry2D { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTGeomGuideList avLst; - @XmlAttribute(required = true) - protected STShapeType prst; - - /** - * Gets the value of the avLst property. - * - * @return - * possible object is - * {@link CTGeomGuideList } - * - */ - public CTGeomGuideList getAvLst() { - return avLst; - } - - /** - * Sets the value of the avLst property. - * - * @param value - * allowed object is - * {@link CTGeomGuideList } - * - */ - public void setAvLst(CTGeomGuideList value) { - this.avLst = value; - } - - public boolean isSetAvLst() { - return (this.avLst!= null); - } - - /** - * Gets the value of the prst property. - * - * @return - * possible object is - * {@link STShapeType } - * - */ - public STShapeType getPrst() { - return prst; - } - - /** - * Sets the value of the prst property. - * - * @param value - * allowed object is - * {@link STShapeType } - * - */ - public void setPrst(STShapeType value) { - this.prst = value; - } - - public boolean isSetPrst() { - return (this.prst!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetTextShape.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetTextShape.java deleted file mode 100644 index 0a6135fc9..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTPresetTextShape.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_PresetTextShape complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_PresetTextShape">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="avLst" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_GeomGuideList" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="prst" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_TextShapeType" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_PresetTextShape", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "avLst" -}) -public class CTPresetTextShape { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTGeomGuideList avLst; - @XmlAttribute(required = true) - protected STTextShapeType prst; - - /** - * Gets the value of the avLst property. - * - * @return - * possible object is - * {@link CTGeomGuideList } - * - */ - public CTGeomGuideList getAvLst() { - return avLst; - } - - /** - * Sets the value of the avLst property. - * - * @param value - * allowed object is - * {@link CTGeomGuideList } - * - */ - public void setAvLst(CTGeomGuideList value) { - this.avLst = value; - } - - public boolean isSetAvLst() { - return (this.avLst!= null); - } - - /** - * Gets the value of the prst property. - * - * @return - * possible object is - * {@link STTextShapeType } - * - */ - public STTextShapeType getPrst() { - return prst; - } - - /** - * Sets the value of the prst property. - * - * @param value - * allowed object is - * {@link STTextShapeType } - * - */ - public void setPrst(STTextShapeType value) { - this.prst = value; - } - - public boolean isSetPrst() { - return (this.prst!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTRatio.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTRatio.java deleted file mode 100644 index 4a61b88cb..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTRatio.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Ratio complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Ratio">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="n" use="required" type="{http://www.w3.org/2001/XMLSchema}long" />
    - *       <attribute name="d" use="required" type="{http://www.w3.org/2001/XMLSchema}long" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Ratio", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTRatio { - - @XmlAttribute(required = true) - protected long n; - @XmlAttribute(required = true) - protected long d; - - /** - * Gets the value of the n property. - * - */ - public long getN() { - return n; - } - - /** - * Sets the value of the n property. - * - */ - public void setN(long value) { - this.n = value; - } - - public boolean isSetN() { - return true; - } - - /** - * Gets the value of the d property. - * - */ - public long getD() { - return d; - } - - /** - * Sets the value of the d property. - * - */ - public void setD(long value) { - this.d = value; - } - - public boolean isSetD() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTRelativeRect.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTRelativeRect.java deleted file mode 100644 index a8b82c474..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTRelativeRect.java +++ /dev/null @@ -1,203 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_RelativeRect complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_RelativeRect">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="l" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" default="0" />
    - *       <attribute name="t" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" default="0" />
    - *       <attribute name="r" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" default="0" />
    - *       <attribute name="b" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" default="0" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_RelativeRect", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTRelativeRect { - - @XmlAttribute - protected Integer l; - @XmlAttribute - protected Integer t; - @XmlAttribute - protected Integer r; - @XmlAttribute - protected Integer b; - - /** - * Gets the value of the l property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public int getL() { - if (l == null) { - return 0; - } else { - return l; - } - } - - /** - * Sets the value of the l property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setL(int value) { - this.l = value; - } - - public boolean isSetL() { - return (this.l!= null); - } - - public void unsetL() { - this.l = null; - } - - /** - * Gets the value of the t property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public int getT() { - if (t == null) { - return 0; - } else { - return t; - } - } - - /** - * Sets the value of the t property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setT(int value) { - this.t = value; - } - - public boolean isSetT() { - return (this.t!= null); - } - - public void unsetT() { - this.t = null; - } - - /** - * Gets the value of the r property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public int getR() { - if (r == null) { - return 0; - } else { - return r; - } - } - - /** - * Sets the value of the r property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setR(int value) { - this.r = value; - } - - public boolean isSetR() { - return (this.r!= null); - } - - public void unsetR() { - this.r = null; - } - - /** - * Gets the value of the b property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public int getB() { - if (b == null) { - return 0; - } else { - return b; - } - } - - /** - * Sets the value of the b property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setB(int value) { - this.b = value; - } - - public boolean isSetB() { - return (this.b!= null); - } - - public void unsetB() { - this.b = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSRgbColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTSRgbColor.java deleted file mode 100644 index 36cefe532..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSRgbColor.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

    Java class for CT_SRgbColor complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_SRgbColor">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorTransform" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_HexBinary3" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_SRgbColor", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorTransform" -}) -public class CTSRgbColor { - - @XmlElementRefs({ - @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class) - }) - protected List> egColorTransform; - @XmlAttribute(required = true) - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - protected byte[] val; - - /** - * Gets the value of the egColorTransform property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorTransform property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorTransform().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * - * - */ - public List> getEGColorTransform() { - if (egColorTransform == null) { - egColorTransform = new ArrayList>(); - } - return this.egColorTransform; - } - - public boolean isSetEGColorTransform() { - return ((this.egColorTransform!= null)&&(!this.egColorTransform.isEmpty())); - } - - public void unsetEGColorTransform() { - this.egColorTransform = null; - } - - /** - * Gets the value of the val property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setVal(byte[] value) { - this.val = (value != null) ? value.clone() : null; - } - - public boolean isSetVal() { - return (this.val!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTScRgbColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTScRgbColor.java deleted file mode 100644 index 2cb3986eb..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTScRgbColor.java +++ /dev/null @@ -1,221 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_ScRgbColor complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_ScRgbColor">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorTransform" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="r" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" />
    - *       <attribute name="g" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" />
    - *       <attribute name="b" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Percentage" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_ScRgbColor", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorTransform" -}) -public class CTScRgbColor { - - @XmlElementRefs({ - @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class) - }) - protected List> egColorTransform; - @XmlAttribute(required = true) - protected int r; - @XmlAttribute(required = true) - protected int g; - @XmlAttribute(required = true) - protected int b; - - /** - * Gets the value of the egColorTransform property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorTransform property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorTransform().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * - * - */ - public List> getEGColorTransform() { - if (egColorTransform == null) { - egColorTransform = new ArrayList>(); - } - return this.egColorTransform; - } - - public boolean isSetEGColorTransform() { - return ((this.egColorTransform!= null)&&(!this.egColorTransform.isEmpty())); - } - - public void unsetEGColorTransform() { - this.egColorTransform = null; - } - - /** - * Gets the value of the r property. - * - */ - public int getR() { - return r; - } - - /** - * Sets the value of the r property. - * - */ - public void setR(int value) { - this.r = value; - } - - public boolean isSetR() { - return true; - } - - /** - * Gets the value of the g property. - * - */ - public int getG() { - return g; - } - - /** - * Sets the value of the g property. - * - */ - public void setG(int value) { - this.g = value; - } - - public boolean isSetG() { - return true; - } - - /** - * Gets the value of the b property. - * - */ - public int getB() { - return b; - } - - /** - * Sets the value of the b property. - * - */ - public void setB(int value) { - this.b = value; - } - - public boolean isSetB() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTScale2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTScale2D.java deleted file mode 100644 index 2e8eba194..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTScale2D.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Scale2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Scale2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="sx" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Ratio"/>
    - *         <element name="sy" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Ratio"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Scale2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "sx", - "sy" -}) -public class CTScale2D { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTRatio sx; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTRatio sy; - - /** - * Gets the value of the sx property. - * - * @return - * possible object is - * {@link CTRatio } - * - */ - public CTRatio getSx() { - return sx; - } - - /** - * Sets the value of the sx property. - * - * @param value - * allowed object is - * {@link CTRatio } - * - */ - public void setSx(CTRatio value) { - this.sx = value; - } - - public boolean isSetSx() { - return (this.sx!= null); - } - - /** - * Gets the value of the sy property. - * - * @return - * possible object is - * {@link CTRatio } - * - */ - public CTRatio getSy() { - return sy; - } - - /** - * Sets the value of the sy property. - * - * @param value - * allowed object is - * {@link CTRatio } - * - */ - public void setSy(CTRatio value) { - this.sy = value; - } - - public boolean isSetSy() { - return (this.sy!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSchemeColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTSchemeColor.java deleted file mode 100644 index ac8fb5c27..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSchemeColor.java +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_SchemeColor complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_SchemeColor">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorTransform" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_SchemeColorVal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_SchemeColor", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorTransform" -}) -public class CTSchemeColor { - - @XmlElementRefs({ - @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class) - }) - protected List> egColorTransform; - @XmlAttribute(required = true) - protected STSchemeColorVal val; - - /** - * Gets the value of the egColorTransform property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorTransform property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorTransform().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * - * - */ - public List> getEGColorTransform() { - if (egColorTransform == null) { - egColorTransform = new ArrayList>(); - } - return this.egColorTransform; - } - - public boolean isSetEGColorTransform() { - return ((this.egColorTransform!= null)&&(!this.egColorTransform.isEmpty())); - } - - public void unsetEGColorTransform() { - this.egColorTransform = null; - } - - /** - * Gets the value of the val property. - * - * @return - * possible object is - * {@link STSchemeColorVal } - * - */ - public STSchemeColorVal getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - * @param value - * allowed object is - * {@link STSchemeColorVal } - * - */ - public void setVal(STSchemeColorVal value) { - this.val = value; - } - - public boolean isSetVal() { - return (this.val!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSphereCoords.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTSphereCoords.java deleted file mode 100644 index 7f03d0dac..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSphereCoords.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_SphereCoords complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_SphereCoords">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="lat" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveFixedAngle" />
    - *       <attribute name="lon" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveFixedAngle" />
    - *       <attribute name="rev" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_PositiveFixedAngle" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_SphereCoords", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTSphereCoords { - - @XmlAttribute(required = true) - protected int lat; - @XmlAttribute(required = true) - protected int lon; - @XmlAttribute(required = true) - protected int rev; - - /** - * Gets the value of the lat property. - * - */ - public int getLat() { - return lat; - } - - /** - * Sets the value of the lat property. - * - */ - public void setLat(int value) { - this.lat = value; - } - - public boolean isSetLat() { - return true; - } - - /** - * Gets the value of the lon property. - * - */ - public int getLon() { - return lon; - } - - /** - * Sets the value of the lon property. - * - */ - public void setLon(int value) { - this.lon = value; - } - - public boolean isSetLon() { - return true; - } - - /** - * Gets the value of the rev property. - * - */ - public int getRev() { - return rev; - } - - /** - * Sets the value of the rev property. - * - */ - public void setRev(int value) { - this.rev = value; - } - - public boolean isSetRev() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSystemColor.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTSystemColor.java deleted file mode 100644 index 1300f87f5..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTSystemColor.java +++ /dev/null @@ -1,219 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElementRef; -import javax.xml.bind.annotation.XmlElementRefs; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

    Java class for CT_SystemColor complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_SystemColor">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <group ref="{http://schemas.openxmlformats.org/drawingml/2006/main}EG_ColorTransform" maxOccurs="unbounded" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="val" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_SystemColorVal" />
    - *       <attribute name="lastClr" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_HexBinary3" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_SystemColor", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "egColorTransform" -}) -public class CTSystemColor { - - @XmlElementRefs({ - @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class), - @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class) - }) - protected List> egColorTransform; - @XmlAttribute(required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - protected String val; - @XmlAttribute - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - protected byte[] lastClr; - - /** - * Gets the value of the egColorTransform property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the egColorTransform property. - * - *

    - * For example, to add a new item, do as follows: - *

    -     *    getEGColorTransform().add(newItem);
    -     * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTAngle }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >} - * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >} - * - * - */ - public List> getEGColorTransform() { - if (egColorTransform == null) { - egColorTransform = new ArrayList>(); - } - return this.egColorTransform; - } - - public boolean isSetEGColorTransform() { - return ((this.egColorTransform!= null)&&(!this.egColorTransform.isEmpty())); - } - - public void unsetEGColorTransform() { - this.egColorTransform = null; - } - - /** - * Gets the value of the val property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getVal() { - return val; - } - - /** - * Sets the value of the val property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setVal(String value) { - this.val = value; - } - - public boolean isSetVal() { - return (this.val!= null); - } - - /** - * Gets the value of the lastClr property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getLastClr() { - return lastClr; - } - - /** - * Sets the value of the lastClr property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setLastClr(byte[] value) { - this.lastClr = (value != null) ? value.clone() : null; - } - - public boolean isSetLastClr() { - return (this.lastClr!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTTransform2D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTTransform2D.java deleted file mode 100644 index dd1dcb501..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTTransform2D.java +++ /dev/null @@ -1,232 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Transform2D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Transform2D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="off" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_Point2D" minOccurs="0"/>
    - *         <element name="ext" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_PositiveSize2D" minOccurs="0"/>
    - *       </sequence>
    - *       <attribute name="rot" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Angle" default="0" />
    - *       <attribute name="flipH" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *       <attribute name="flipV" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Transform2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "off", - "ext" -}) -public class CTTransform2D { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPoint2D off; - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") - protected CTPositiveSize2D ext; - @XmlAttribute - protected Integer rot; - @XmlAttribute - protected Boolean flipH; - @XmlAttribute - protected Boolean flipV; - - /** - * Gets the value of the off property. - * - * @return - * possible object is - * {@link CTPoint2D } - * - */ - public CTPoint2D getOff() { - return off; - } - - /** - * Sets the value of the off property. - * - * @param value - * allowed object is - * {@link CTPoint2D } - * - */ - public void setOff(CTPoint2D value) { - this.off = value; - } - - public boolean isSetOff() { - return (this.off!= null); - } - - /** - * Gets the value of the ext property. - * - * @return - * possible object is - * {@link CTPositiveSize2D } - * - */ - public CTPositiveSize2D getExt() { - return ext; - } - - /** - * Sets the value of the ext property. - * - * @param value - * allowed object is - * {@link CTPositiveSize2D } - * - */ - public void setExt(CTPositiveSize2D value) { - this.ext = value; - } - - public boolean isSetExt() { - return (this.ext!= null); - } - - /** - * Gets the value of the rot property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public int getRot() { - if (rot == null) { - return 0; - } else { - return rot; - } - } - - /** - * Sets the value of the rot property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setRot(int value) { - this.rot = value; - } - - public boolean isSetRot() { - return (this.rot!= null); - } - - public void unsetRot() { - this.rot = null; - } - - /** - * Gets the value of the flipH property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isFlipH() { - if (flipH == null) { - return false; - } else { - return flipH; - } - } - - /** - * Sets the value of the flipH property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setFlipH(boolean value) { - this.flipH = value; - } - - public boolean isSetFlipH() { - return (this.flipH!= null); - } - - public void unsetFlipH() { - this.flipH = null; - } - - /** - * Gets the value of the flipV property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isFlipV() { - if (flipV == null) { - return false; - } else { - return flipV; - } - } - - /** - * Sets the value of the flipV property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setFlipV(boolean value) { - this.flipV = value; - } - - public boolean isSetFlipV() { - return (this.flipV!= null); - } - - public void unsetFlipV() { - this.flipV = null; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTVector3D.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTVector3D.java deleted file mode 100644 index d7f744ba6..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTVector3D.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for CT_Vector3D complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_Vector3D">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="dx" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *       <attribute name="dy" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *       <attribute name="dz" use="required" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_Coordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_Vector3D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -public class CTVector3D { - - @XmlAttribute(required = true) - protected long dx; - @XmlAttribute(required = true) - protected long dy; - @XmlAttribute(required = true) - protected long dz; - - /** - * Gets the value of the dx property. - * - */ - public long getDx() { - return dx; - } - - /** - * Sets the value of the dx property. - * - */ - public void setDx(long value) { - this.dx = value; - } - - public boolean isSetDx() { - return true; - } - - /** - * Gets the value of the dy property. - * - */ - public long getDy() { - return dy; - } - - /** - * Sets the value of the dy property. - * - */ - public void setDy(long value) { - this.dy = value; - } - - public boolean isSetDy() { - return true; - } - - /** - * Gets the value of the dz property. - * - */ - public long getDz() { - return dz; - } - - /** - * Sets the value of the dz property. - * - */ - public void setDz(long value) { - this.dz = value; - } - - public boolean isSetDz() { - return true; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java b/trunk/src/java/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java deleted file mode 100644 index 2b22a5881..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java +++ /dev/null @@ -1,273 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

    Java class for CT_XYAdjustHandle complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType name="CT_XYAdjustHandle">
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element name="pos" type="{http://schemas.openxmlformats.org/drawingml/2006/main}CT_AdjPoint2D"/>
    - *       </sequence>
    - *       <attribute name="gdRefX" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_GeomGuideName" />
    - *       <attribute name="minX" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="maxX" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="gdRefY" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_GeomGuideName" />
    - *       <attribute name="minY" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *       <attribute name="maxY" type="{http://schemas.openxmlformats.org/drawingml/2006/main}ST_AdjCoordinate" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CT_XYAdjustHandle", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", propOrder = { - "pos" -}) -public class CTXYAdjustHandle { - - @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true) - protected CTAdjPoint2D pos; - @XmlAttribute - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - protected String gdRefX; - @XmlAttribute - protected String minX; - @XmlAttribute - protected String maxX; - @XmlAttribute - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - protected String gdRefY; - @XmlAttribute - protected String minY; - @XmlAttribute - protected String maxY; - - /** - * Gets the value of the pos property. - * - * @return - * possible object is - * {@link CTAdjPoint2D } - * - */ - public CTAdjPoint2D getPos() { - return pos; - } - - /** - * Sets the value of the pos property. - * - * @param value - * allowed object is - * {@link CTAdjPoint2D } - * - */ - public void setPos(CTAdjPoint2D value) { - this.pos = value; - } - - public boolean isSetPos() { - return (this.pos!= null); - } - - /** - * Gets the value of the gdRefX property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getGdRefX() { - return gdRefX; - } - - /** - * Sets the value of the gdRefX property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setGdRefX(String value) { - this.gdRefX = value; - } - - public boolean isSetGdRefX() { - return (this.gdRefX!= null); - } - - /** - * Gets the value of the minX property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMinX() { - return minX; - } - - /** - * Sets the value of the minX property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMinX(String value) { - this.minX = value; - } - - public boolean isSetMinX() { - return (this.minX!= null); - } - - /** - * Gets the value of the maxX property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMaxX() { - return maxX; - } - - /** - * Sets the value of the maxX property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMaxX(String value) { - this.maxX = value; - } - - public boolean isSetMaxX() { - return (this.maxX!= null); - } - - /** - * Gets the value of the gdRefY property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getGdRefY() { - return gdRefY; - } - - /** - * Sets the value of the gdRefY property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setGdRefY(String value) { - this.gdRefY = value; - } - - public boolean isSetGdRefY() { - return (this.gdRefY!= null); - } - - /** - * Gets the value of the minY property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMinY() { - return minY; - } - - /** - * Sets the value of the minY property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMinY(String value) { - this.minY = value; - } - - public boolean isSetMinY() { - return (this.minY!= null); - } - - /** - * Gets the value of the maxY property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMaxY() { - return maxY; - } - - /** - * Sets the value of the maxY property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMaxY(String value) { - this.maxY = value; - } - - public boolean isSetMaxY() { - return (this.maxY!= null); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/ObjectFactory.java b/trunk/src/java/org/apache/poi/sl/draw/binding/ObjectFactory.java deleted file mode 100644 index 896fb2476..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/ObjectFactory.java +++ /dev/null @@ -1,2023 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the org.apache.poi.sl.draw.binding package. - *

    An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _CTSRgbColorAlpha_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alpha"); - private final static QName _CTSRgbColorLum_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lum"); - private final static QName _CTSRgbColorGamma_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "gamma"); - private final static QName _CTSRgbColorInvGamma_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "invGamma"); - private final static QName _CTSRgbColorRedOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "redOff"); - private final static QName _CTSRgbColorAlphaMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alphaMod"); - private final static QName _CTSRgbColorAlphaOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alphaOff"); - private final static QName _CTSRgbColorGreenOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "greenOff"); - private final static QName _CTSRgbColorRedMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "redMod"); - private final static QName _CTSRgbColorHue_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hue"); - private final static QName _CTSRgbColorSatOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "satOff"); - private final static QName _CTSRgbColorGreenMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "greenMod"); - private final static QName _CTSRgbColorSat_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "sat"); - private final static QName _CTSRgbColorBlue_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blue"); - private final static QName _CTSRgbColorRed_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "red"); - private final static QName _CTSRgbColorSatMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "satMod"); - private final static QName _CTSRgbColorHueOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hueOff"); - private final static QName _CTSRgbColorBlueMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blueMod"); - private final static QName _CTSRgbColorShade_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "shade"); - private final static QName _CTSRgbColorLumMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lumMod"); - private final static QName _CTSRgbColorInv_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "inv"); - private final static QName _CTSRgbColorLumOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lumOff"); - private final static QName _CTSRgbColorTint_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tint"); - private final static QName _CTSRgbColorGreen_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "green"); - private final static QName _CTSRgbColorComp_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "comp"); - private final static QName _CTSRgbColorBlueOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blueOff"); - private final static QName _CTSRgbColorHueMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hueMod"); - private final static QName _CTSRgbColorGray_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "gray"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.poi.sl.draw.binding - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link CTPositiveSize2D } - * - */ - public CTPositiveSize2D createCTPositiveSize2D() { - return new CTPositiveSize2D(); - } - - /** - * Create an instance of {@link CTSphereCoords } - * - */ - public CTSphereCoords createCTSphereCoords() { - return new CTSphereCoords(); - } - - /** - * Create an instance of {@link CTPositivePercentage } - * - */ - public CTPositivePercentage createCTPositivePercentage() { - return new CTPositivePercentage(); - } - - /** - * Create an instance of {@link CTAdjPoint2D } - * - */ - public CTAdjPoint2D createCTAdjPoint2D() { - return new CTAdjPoint2D(); - } - - /** - * Create an instance of {@link CTPath2DCubicBezierTo } - * - */ - public CTPath2DCubicBezierTo createCTPath2DCubicBezierTo() { - return new CTPath2DCubicBezierTo(); - } - - /** - * Create an instance of {@link CTEmbeddedWAVAudioFile } - * - */ - public CTEmbeddedWAVAudioFile createCTEmbeddedWAVAudioFile() { - return new CTEmbeddedWAVAudioFile(); - } - - /** - * Create an instance of {@link CTPresetGeometry2D } - * - */ - public CTPresetGeometry2D createCTPresetGeometry2D() { - return new CTPresetGeometry2D(); - } - - /** - * Create an instance of {@link CTSchemeColor } - * - */ - public CTSchemeColor createCTSchemeColor() { - return new CTSchemeColor(); - } - - /** - * Create an instance of {@link CTInverseTransform } - * - */ - public CTInverseTransform createCTInverseTransform() { - return new CTInverseTransform(); - } - - /** - * Create an instance of {@link CTScRgbColor } - * - */ - public CTScRgbColor createCTScRgbColor() { - return new CTScRgbColor(); - } - - /** - * Create an instance of {@link CTPositiveFixedAngle } - * - */ - public CTPositiveFixedAngle createCTPositiveFixedAngle() { - return new CTPositiveFixedAngle(); - } - - /** - * Create an instance of {@link CTInverseGammaTransform } - * - */ - public CTInverseGammaTransform createCTInverseGammaTransform() { - return new CTInverseGammaTransform(); - } - - /** - * Create an instance of {@link CTColorMRU } - * - */ - public CTColorMRU createCTColorMRU() { - return new CTColorMRU(); - } - - /** - * Create an instance of {@link CTPath2DArcTo } - * - */ - public CTPath2DArcTo createCTPath2DArcTo() { - return new CTPath2DArcTo(); - } - - /** - * Create an instance of {@link CTSystemColor } - * - */ - public CTSystemColor createCTSystemColor() { - return new CTSystemColor(); - } - - /** - * Create an instance of {@link CTGroupTransform2D } - * - */ - public CTGroupTransform2D createCTGroupTransform2D() { - return new CTGroupTransform2D(); - } - - /** - * Create an instance of {@link CTPoint2D } - * - */ - public CTPoint2D createCTPoint2D() { - return new CTPoint2D(); - } - - /** - * Create an instance of {@link CTGeomRect } - * - */ - public CTGeomRect createCTGeomRect() { - return new CTGeomRect(); - } - - /** - * Create an instance of {@link CTScale2D } - * - */ - public CTScale2D createCTScale2D() { - return new CTScale2D(); - } - - /** - * Create an instance of {@link CTGeomGuide } - * - */ - public CTGeomGuide createCTGeomGuide() { - return new CTGeomGuide(); - } - - /** - * Create an instance of {@link CTXYAdjustHandle } - * - */ - public CTXYAdjustHandle createCTXYAdjustHandle() { - return new CTXYAdjustHandle(); - } - - /** - * Create an instance of {@link CTCustomGeometry2D } - * - */ - public CTCustomGeometry2D createCTCustomGeometry2D() { - return new CTCustomGeometry2D(); - } - - /** - * Create an instance of {@link CTOfficeArtExtension } - * - */ - public CTOfficeArtExtension createCTOfficeArtExtension() { - return new CTOfficeArtExtension(); - } - - /** - * Create an instance of {@link CTGrayscaleTransform } - * - */ - public CTGrayscaleTransform createCTGrayscaleTransform() { - return new CTGrayscaleTransform(); - } - - /** - * Create an instance of {@link CTPath2DClose } - * - */ - public CTPath2DClose createCTPath2DClose() { - return new CTPath2DClose(); - } - - /** - * Create an instance of {@link CTComplementTransform } - * - */ - public CTComplementTransform createCTComplementTransform() { - return new CTComplementTransform(); - } - - /** - * Create an instance of {@link CTPoint3D } - * - */ - public CTPoint3D createCTPoint3D() { - return new CTPoint3D(); - } - - /** - * Create an instance of {@link CTPositiveFixedPercentage } - * - */ - public CTPositiveFixedPercentage createCTPositiveFixedPercentage() { - return new CTPositiveFixedPercentage(); - } - - /** - * Create an instance of {@link CTPath2D } - * - */ - public CTPath2D createCTPath2D() { - return new CTPath2D(); - } - - /** - * Create an instance of {@link CTAdjustHandleList } - * - */ - public CTAdjustHandleList createCTAdjustHandleList() { - return new CTAdjustHandleList(); - } - - /** - * Create an instance of {@link CTConnectionSiteList } - * - */ - public CTConnectionSiteList createCTConnectionSiteList() { - return new CTConnectionSiteList(); - } - - /** - * Create an instance of {@link CTPresetTextShape } - * - */ - public CTPresetTextShape createCTPresetTextShape() { - return new CTPresetTextShape(); - } - - /** - * Create an instance of {@link CTSRgbColor } - * - */ - public CTSRgbColor createCTSRgbColor() { - return new CTSRgbColor(); - } - - /** - * Create an instance of {@link CTPath2DMoveTo } - * - */ - public CTPath2DMoveTo createCTPath2DMoveTo() { - return new CTPath2DMoveTo(); - } - - /** - * Create an instance of {@link CTRelativeRect } - * - */ - public CTRelativeRect createCTRelativeRect() { - return new CTRelativeRect(); - } - - /** - * Create an instance of {@link CTPath2DList } - * - */ - public CTPath2DList createCTPath2DList() { - return new CTPath2DList(); - } - - /** - * Create an instance of {@link CTPolarAdjustHandle } - * - */ - public CTPolarAdjustHandle createCTPolarAdjustHandle() { - return new CTPolarAdjustHandle(); - } - - /** - * Create an instance of {@link CTPercentage } - * - */ - public CTPercentage createCTPercentage() { - return new CTPercentage(); - } - - /** - * Create an instance of {@link CTHslColor } - * - */ - public CTHslColor createCTHslColor() { - return new CTHslColor(); - } - - /** - * Create an instance of {@link CTRatio } - * - */ - public CTRatio createCTRatio() { - return new CTRatio(); - } - - /** - * Create an instance of {@link CTGeomGuideList } - * - */ - public CTGeomGuideList createCTGeomGuideList() { - return new CTGeomGuideList(); - } - - /** - * Create an instance of {@link CTTransform2D } - * - */ - public CTTransform2D createCTTransform2D() { - return new CTTransform2D(); - } - - /** - * Create an instance of {@link CTGammaTransform } - * - */ - public CTGammaTransform createCTGammaTransform() { - return new CTGammaTransform(); - } - - /** - * Create an instance of {@link CTPath2DQuadBezierTo } - * - */ - public CTPath2DQuadBezierTo createCTPath2DQuadBezierTo() { - return new CTPath2DQuadBezierTo(); - } - - /** - * Create an instance of {@link CTAngle } - * - */ - public CTAngle createCTAngle() { - return new CTAngle(); - } - - /** - * Create an instance of {@link CTConnectionSite } - * - */ - public CTConnectionSite createCTConnectionSite() { - return new CTConnectionSite(); - } - - /** - * Create an instance of {@link CTHyperlink } - * - */ - public CTHyperlink createCTHyperlink() { - return new CTHyperlink(); - } - - /** - * Create an instance of {@link CTFixedPercentage } - * - */ - public CTFixedPercentage createCTFixedPercentage() { - return new CTFixedPercentage(); - } - - /** - * Create an instance of {@link CTPath2DLineTo } - * - */ - public CTPath2DLineTo createCTPath2DLineTo() { - return new CTPath2DLineTo(); - } - - /** - * Create an instance of {@link CTColor } - * - */ - public CTColor createCTColor() { - return new CTColor(); - } - - /** - * Create an instance of {@link CTPresetColor } - * - */ - public CTPresetColor createCTPresetColor() { - return new CTPresetColor(); - } - - /** - * Create an instance of {@link CTVector3D } - * - */ - public CTVector3D createCTVector3D() { - return new CTVector3D(); - } - - /** - * Create an instance of {@link CTOfficeArtExtensionList } - * - */ - public CTOfficeArtExtensionList createCTOfficeArtExtensionList() { - return new CTOfficeArtExtensionList(); - } - - /** - * Create an instance of {@link CTConnection } - * - */ - public CTConnection createCTConnection() { - return new CTConnection(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorAlpha(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorLum(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLum_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorGamma(CTGammaTransform value) { - return new JAXBElement(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorInvGamma(CTInverseGammaTransform value) { - return new JAXBElement(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorRedOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorAlphaMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorAlphaOff(CTFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorGreenOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorRedMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorHue(CTPositiveFixedAngle value) { - return new JAXBElement(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorSatOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorGreenMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorSat(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSat_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorBlue(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorRed(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRed_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorSatMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorHueOff(CTAngle value) { - return new JAXBElement(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorBlueMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorShade(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorLumMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorInv(CTInverseTransform value) { - return new JAXBElement(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorLumOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorTint(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorGreen(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorComp(CTComplementTransform value) { - return new JAXBElement(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorBlueOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorHueMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSRgbColor.class) - public JAXBElement createCTSRgbColorGray(CTGrayscaleTransform value) { - return new JAXBElement(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorLum(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLum_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorAlpha(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorGamma(CTGammaTransform value) { - return new JAXBElement(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorInvGamma(CTInverseGammaTransform value) { - return new JAXBElement(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorAlphaMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorRedOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorAlphaOff(CTFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorGreenOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorRedMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorHue(CTPositiveFixedAngle value) { - return new JAXBElement(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorSatOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorGreenMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorBlue(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorSat(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSat_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorRed(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRed_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorSatMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorBlueMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorHueOff(CTAngle value) { - return new JAXBElement(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorShade(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorLumMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorInv(CTInverseTransform value) { - return new JAXBElement(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorLumOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorTint(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorGreen(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorComp(CTComplementTransform value) { - return new JAXBElement(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorBlueOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorHueMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSystemColor.class) - public JAXBElement createCTSystemColorGray(CTGrayscaleTransform value) { - return new JAXBElement(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSystemColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorLum(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLum_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorAlpha(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorGamma(CTGammaTransform value) { - return new JAXBElement(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorInvGamma(CTInverseGammaTransform value) { - return new JAXBElement(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorRedOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorAlphaMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorAlphaOff(CTFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorGreenOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorHue(CTPositiveFixedAngle value) { - return new JAXBElement(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorRedMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorSatOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorGreenMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorBlue(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorSat(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSat_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorRed(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRed_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorSatMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorHueOff(CTAngle value) { - return new JAXBElement(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorBlueMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorShade(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorLumMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorInv(CTInverseTransform value) { - return new JAXBElement(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorLumOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorTint(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorGreen(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorComp(CTComplementTransform value) { - return new JAXBElement(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorBlueOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorHueMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSchemeColor.class) - public JAXBElement createCTSchemeColorGray(CTGrayscaleTransform value) { - return new JAXBElement(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSchemeColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorLum(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLum_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorAlpha(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorGamma(CTGammaTransform value) { - return new JAXBElement(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorInvGamma(CTInverseGammaTransform value) { - return new JAXBElement(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorRedOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorAlphaMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorAlphaOff(CTFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorGreenOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorHue(CTPositiveFixedAngle value) { - return new JAXBElement(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorRedMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorSatOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorGreenMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorSat(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSat_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorBlue(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorRed(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRed_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorSatMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorHueOff(CTAngle value) { - return new JAXBElement(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorBlueMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorShade(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorLumMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorInv(CTInverseTransform value) { - return new JAXBElement(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorLumOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorTint(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorGreen(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorComp(CTComplementTransform value) { - return new JAXBElement(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorBlueOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorHueMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTScRgbColor.class) - public JAXBElement createCTScRgbColorGray(CTGrayscaleTransform value) { - return new JAXBElement(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTScRgbColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTHslColor.class) - public JAXBElement createCTHslColorAlpha(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTHslColor.class) - public JAXBElement createCTHslColorLum(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLum_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTHslColor.class) - public JAXBElement createCTHslColorGamma(CTGammaTransform value) { - return new JAXBElement(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTHslColor.class) - public JAXBElement createCTHslColorInvGamma(CTInverseGammaTransform value) { - return new JAXBElement(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorAlphaMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorRedOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorAlphaOff(CTFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorGreenOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTHslColor.class) - public JAXBElement createCTHslColorHue(CTPositiveFixedAngle value) { - return new JAXBElement(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorRedMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorSatOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorGreenMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTHslColor.class) - public JAXBElement createCTHslColorBlue(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTHslColor.class) - public JAXBElement createCTHslColorSat(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSat_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTHslColor.class) - public JAXBElement createCTHslColorRed(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRed_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorSatMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorBlueMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorHueOff(CTAngle value) { - return new JAXBElement(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTHslColor.class) - public JAXBElement createCTHslColorShade(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorLumMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTHslColor.class) - public JAXBElement createCTHslColorInv(CTInverseTransform value) { - return new JAXBElement(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorLumOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTHslColor.class) - public JAXBElement createCTHslColorTint(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTHslColor.class) - public JAXBElement createCTHslColorGreen(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTHslColor.class) - public JAXBElement createCTHslColorComp(CTComplementTransform value) { - return new JAXBElement(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTHslColor.class) - public JAXBElement createCTHslColorBlueOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTHslColor.class) - public JAXBElement createCTHslColorHueMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTHslColor.class) - public JAXBElement createCTHslColorGray(CTGrayscaleTransform value) { - return new JAXBElement(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTHslColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorLum(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLum_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorAlpha(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorGamma(CTGammaTransform value) { - return new JAXBElement(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorInvGamma(CTInverseGammaTransform value) { - return new JAXBElement(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorRedOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorAlphaMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorAlphaOff(CTFixedPercentage value) { - return new JAXBElement(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorGreenOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorHue(CTPositiveFixedAngle value) { - return new JAXBElement(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorRedMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorSatOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorGreenMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorBlue(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorSat(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSat_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorRed(CTPercentage value) { - return new JAXBElement(_CTSRgbColorRed_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorSatMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorBlueMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorHueOff(CTAngle value) { - return new JAXBElement(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorShade(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorLumMod(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorInv(CTInverseTransform value) { - return new JAXBElement(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorLumOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorTint(CTPositiveFixedPercentage value) { - return new JAXBElement(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorGreen(CTPercentage value) { - return new JAXBElement(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorComp(CTComplementTransform value) { - return new JAXBElement(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorBlueOff(CTPercentage value) { - return new JAXBElement(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorHueMod(CTPositivePercentage value) { - return new JAXBElement(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTPresetColor.class, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTPresetColor.class) - public JAXBElement createCTPresetColorGray(CTGrayscaleTransform value) { - return new JAXBElement(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTPresetColor.class, value); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java deleted file mode 100644 index 27262d606..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_BlackWhiteMode. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_BlackWhiteMode">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="clr"/>
    - *     <enumeration value="auto"/>
    - *     <enumeration value="gray"/>
    - *     <enumeration value="ltGray"/>
    - *     <enumeration value="invGray"/>
    - *     <enumeration value="grayWhite"/>
    - *     <enumeration value="blackGray"/>
    - *     <enumeration value="blackWhite"/>
    - *     <enumeration value="black"/>
    - *     <enumeration value="white"/>
    - *     <enumeration value="hidden"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_BlackWhiteMode", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STBlackWhiteMode { - - - /** - * Color - * - */ - @XmlEnumValue("clr") - CLR("clr"), - - /** - * Automatic - * - */ - @XmlEnumValue("auto") - AUTO("auto"), - - /** - * Gray - * - */ - @XmlEnumValue("gray") - GRAY("gray"), - - /** - * Light Gray - * - */ - @XmlEnumValue("ltGray") - LT_GRAY("ltGray"), - - /** - * Inverse Gray - * - */ - @XmlEnumValue("invGray") - INV_GRAY("invGray"), - - /** - * Gray and White - * - */ - @XmlEnumValue("grayWhite") - GRAY_WHITE("grayWhite"), - - /** - * Black and Gray - * - */ - @XmlEnumValue("blackGray") - BLACK_GRAY("blackGray"), - - /** - * Black and White - * - */ - @XmlEnumValue("blackWhite") - BLACK_WHITE("blackWhite"), - - /** - * Black - * - */ - @XmlEnumValue("black") - BLACK("black"), - - /** - * White - * - */ - @XmlEnumValue("white") - WHITE("white"), - - /** - * Hidden - * - */ - @XmlEnumValue("hidden") - HIDDEN("hidden"); - private final String value; - - STBlackWhiteMode(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STBlackWhiteMode fromValue(String v) { - for (STBlackWhiteMode c: STBlackWhiteMode.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STPathFillMode.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STPathFillMode.java deleted file mode 100644 index 8a26458f0..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STPathFillMode.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_PathFillMode. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_PathFillMode">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="none"/>
    - *     <enumeration value="norm"/>
    - *     <enumeration value="lighten"/>
    - *     <enumeration value="lightenLess"/>
    - *     <enumeration value="darken"/>
    - *     <enumeration value="darkenLess"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_PathFillMode", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STPathFillMode { - - - /** - * No Path Fill - * - */ - @XmlEnumValue("none") - NONE("none"), - - /** - * Normal Path Fill - * - */ - @XmlEnumValue("norm") - NORM("norm"), - - /** - * Lighten Path Fill - * - */ - @XmlEnumValue("lighten") - LIGHTEN("lighten"), - - /** - * Lighten Path Fill Less - * - */ - @XmlEnumValue("lightenLess") - LIGHTEN_LESS("lightenLess"), - - /** - * Darken Path Fill - * - */ - @XmlEnumValue("darken") - DARKEN("darken"), - - /** - * Darken Path Fill Less - * - */ - @XmlEnumValue("darkenLess") - DARKEN_LESS("darkenLess"); - private final String value; - - STPathFillMode(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STPathFillMode fromValue(String v) { - for (STPathFillMode c: STPathFillMode.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STPresetColorVal.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STPresetColorVal.java deleted file mode 100644 index 7450ac656..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STPresetColorVal.java +++ /dev/null @@ -1,1181 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_PresetColorVal. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_PresetColorVal">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="aliceBlue"/>
    - *     <enumeration value="antiqueWhite"/>
    - *     <enumeration value="aqua"/>
    - *     <enumeration value="aquamarine"/>
    - *     <enumeration value="azure"/>
    - *     <enumeration value="beige"/>
    - *     <enumeration value="bisque"/>
    - *     <enumeration value="black"/>
    - *     <enumeration value="blanchedAlmond"/>
    - *     <enumeration value="blue"/>
    - *     <enumeration value="blueViolet"/>
    - *     <enumeration value="brown"/>
    - *     <enumeration value="burlyWood"/>
    - *     <enumeration value="cadetBlue"/>
    - *     <enumeration value="chartreuse"/>
    - *     <enumeration value="chocolate"/>
    - *     <enumeration value="coral"/>
    - *     <enumeration value="cornflowerBlue"/>
    - *     <enumeration value="cornsilk"/>
    - *     <enumeration value="crimson"/>
    - *     <enumeration value="cyan"/>
    - *     <enumeration value="dkBlue"/>
    - *     <enumeration value="dkCyan"/>
    - *     <enumeration value="dkGoldenrod"/>
    - *     <enumeration value="dkGray"/>
    - *     <enumeration value="dkGreen"/>
    - *     <enumeration value="dkKhaki"/>
    - *     <enumeration value="dkMagenta"/>
    - *     <enumeration value="dkOliveGreen"/>
    - *     <enumeration value="dkOrange"/>
    - *     <enumeration value="dkOrchid"/>
    - *     <enumeration value="dkRed"/>
    - *     <enumeration value="dkSalmon"/>
    - *     <enumeration value="dkSeaGreen"/>
    - *     <enumeration value="dkSlateBlue"/>
    - *     <enumeration value="dkSlateGray"/>
    - *     <enumeration value="dkTurquoise"/>
    - *     <enumeration value="dkViolet"/>
    - *     <enumeration value="deepPink"/>
    - *     <enumeration value="deepSkyBlue"/>
    - *     <enumeration value="dimGray"/>
    - *     <enumeration value="dodgerBlue"/>
    - *     <enumeration value="firebrick"/>
    - *     <enumeration value="floralWhite"/>
    - *     <enumeration value="forestGreen"/>
    - *     <enumeration value="fuchsia"/>
    - *     <enumeration value="gainsboro"/>
    - *     <enumeration value="ghostWhite"/>
    - *     <enumeration value="gold"/>
    - *     <enumeration value="goldenrod"/>
    - *     <enumeration value="gray"/>
    - *     <enumeration value="green"/>
    - *     <enumeration value="greenYellow"/>
    - *     <enumeration value="honeydew"/>
    - *     <enumeration value="hotPink"/>
    - *     <enumeration value="indianRed"/>
    - *     <enumeration value="indigo"/>
    - *     <enumeration value="ivory"/>
    - *     <enumeration value="khaki"/>
    - *     <enumeration value="lavender"/>
    - *     <enumeration value="lavenderBlush"/>
    - *     <enumeration value="lawnGreen"/>
    - *     <enumeration value="lemonChiffon"/>
    - *     <enumeration value="ltBlue"/>
    - *     <enumeration value="ltCoral"/>
    - *     <enumeration value="ltCyan"/>
    - *     <enumeration value="ltGoldenrodYellow"/>
    - *     <enumeration value="ltGray"/>
    - *     <enumeration value="ltGreen"/>
    - *     <enumeration value="ltPink"/>
    - *     <enumeration value="ltSalmon"/>
    - *     <enumeration value="ltSeaGreen"/>
    - *     <enumeration value="ltSkyBlue"/>
    - *     <enumeration value="ltSlateGray"/>
    - *     <enumeration value="ltSteelBlue"/>
    - *     <enumeration value="ltYellow"/>
    - *     <enumeration value="lime"/>
    - *     <enumeration value="limeGreen"/>
    - *     <enumeration value="linen"/>
    - *     <enumeration value="magenta"/>
    - *     <enumeration value="maroon"/>
    - *     <enumeration value="medAquamarine"/>
    - *     <enumeration value="medBlue"/>
    - *     <enumeration value="medOrchid"/>
    - *     <enumeration value="medPurple"/>
    - *     <enumeration value="medSeaGreen"/>
    - *     <enumeration value="medSlateBlue"/>
    - *     <enumeration value="medSpringGreen"/>
    - *     <enumeration value="medTurquoise"/>
    - *     <enumeration value="medVioletRed"/>
    - *     <enumeration value="midnightBlue"/>
    - *     <enumeration value="mintCream"/>
    - *     <enumeration value="mistyRose"/>
    - *     <enumeration value="moccasin"/>
    - *     <enumeration value="navajoWhite"/>
    - *     <enumeration value="navy"/>
    - *     <enumeration value="oldLace"/>
    - *     <enumeration value="olive"/>
    - *     <enumeration value="oliveDrab"/>
    - *     <enumeration value="orange"/>
    - *     <enumeration value="orangeRed"/>
    - *     <enumeration value="orchid"/>
    - *     <enumeration value="paleGoldenrod"/>
    - *     <enumeration value="paleGreen"/>
    - *     <enumeration value="paleTurquoise"/>
    - *     <enumeration value="paleVioletRed"/>
    - *     <enumeration value="papayaWhip"/>
    - *     <enumeration value="peachPuff"/>
    - *     <enumeration value="peru"/>
    - *     <enumeration value="pink"/>
    - *     <enumeration value="plum"/>
    - *     <enumeration value="powderBlue"/>
    - *     <enumeration value="purple"/>
    - *     <enumeration value="red"/>
    - *     <enumeration value="rosyBrown"/>
    - *     <enumeration value="royalBlue"/>
    - *     <enumeration value="saddleBrown"/>
    - *     <enumeration value="salmon"/>
    - *     <enumeration value="sandyBrown"/>
    - *     <enumeration value="seaGreen"/>
    - *     <enumeration value="seaShell"/>
    - *     <enumeration value="sienna"/>
    - *     <enumeration value="silver"/>
    - *     <enumeration value="skyBlue"/>
    - *     <enumeration value="slateBlue"/>
    - *     <enumeration value="slateGray"/>
    - *     <enumeration value="snow"/>
    - *     <enumeration value="springGreen"/>
    - *     <enumeration value="steelBlue"/>
    - *     <enumeration value="tan"/>
    - *     <enumeration value="teal"/>
    - *     <enumeration value="thistle"/>
    - *     <enumeration value="tomato"/>
    - *     <enumeration value="turquoise"/>
    - *     <enumeration value="violet"/>
    - *     <enumeration value="wheat"/>
    - *     <enumeration value="white"/>
    - *     <enumeration value="whiteSmoke"/>
    - *     <enumeration value="yellow"/>
    - *     <enumeration value="yellowGreen"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_PresetColorVal", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STPresetColorVal { - - - /** - * Alice Blue Preset Color - * - */ - @XmlEnumValue("aliceBlue") - ALICE_BLUE("aliceBlue"), - - /** - * Antique White Preset Color - * - */ - @XmlEnumValue("antiqueWhite") - ANTIQUE_WHITE("antiqueWhite"), - - /** - * Aqua Preset Color - * - */ - @XmlEnumValue("aqua") - AQUA("aqua"), - - /** - * Aquamarine Preset Color - * - */ - @XmlEnumValue("aquamarine") - AQUAMARINE("aquamarine"), - - /** - * Azure Preset Color - * - */ - @XmlEnumValue("azure") - AZURE("azure"), - - /** - * Beige Preset Color - * - */ - @XmlEnumValue("beige") - BEIGE("beige"), - - /** - * Bisque Preset Color - * - */ - @XmlEnumValue("bisque") - BISQUE("bisque"), - - /** - * Black Preset Color - * - */ - @XmlEnumValue("black") - BLACK("black"), - - /** - * Blanched Almond Preset Color - * - */ - @XmlEnumValue("blanchedAlmond") - BLANCHED_ALMOND("blanchedAlmond"), - - /** - * Blue Preset Color - * - */ - @XmlEnumValue("blue") - BLUE("blue"), - - /** - * Blue Violet Preset Color - * - */ - @XmlEnumValue("blueViolet") - BLUE_VIOLET("blueViolet"), - - /** - * Brown Preset Color - * - */ - @XmlEnumValue("brown") - BROWN("brown"), - - /** - * Burly Wood Preset Color - * - */ - @XmlEnumValue("burlyWood") - BURLY_WOOD("burlyWood"), - - /** - * Cadet Blue Preset Color - * - */ - @XmlEnumValue("cadetBlue") - CADET_BLUE("cadetBlue"), - - /** - * Chartreuse Preset Color - * - */ - @XmlEnumValue("chartreuse") - CHARTREUSE("chartreuse"), - - /** - * Chocolate Preset Color - * - */ - @XmlEnumValue("chocolate") - CHOCOLATE("chocolate"), - - /** - * Coral Preset Color - * - */ - @XmlEnumValue("coral") - CORAL("coral"), - - /** - * Cornflower Blue Preset Color - * - */ - @XmlEnumValue("cornflowerBlue") - CORNFLOWER_BLUE("cornflowerBlue"), - - /** - * Cornsilk Preset Color - * - */ - @XmlEnumValue("cornsilk") - CORNSILK("cornsilk"), - - /** - * Crimson Preset Color - * - */ - @XmlEnumValue("crimson") - CRIMSON("crimson"), - - /** - * Cyan Preset Color - * - */ - @XmlEnumValue("cyan") - CYAN("cyan"), - - /** - * Dark Blue Preset Color - * - */ - @XmlEnumValue("dkBlue") - DK_BLUE("dkBlue"), - - /** - * Dark Cyan Preset Color - * - */ - @XmlEnumValue("dkCyan") - DK_CYAN("dkCyan"), - - /** - * Dark Goldenrod Preset Color - * - */ - @XmlEnumValue("dkGoldenrod") - DK_GOLDENROD("dkGoldenrod"), - - /** - * Dark Gray Preset Color - * - */ - @XmlEnumValue("dkGray") - DK_GRAY("dkGray"), - - /** - * Dark Green Preset Color - * - */ - @XmlEnumValue("dkGreen") - DK_GREEN("dkGreen"), - - /** - * Dark Khaki Preset Color - * - */ - @XmlEnumValue("dkKhaki") - DK_KHAKI("dkKhaki"), - - /** - * Dark Magenta Preset Color - * - */ - @XmlEnumValue("dkMagenta") - DK_MAGENTA("dkMagenta"), - - /** - * Dark Olive Green Preset Color - * - */ - @XmlEnumValue("dkOliveGreen") - DK_OLIVE_GREEN("dkOliveGreen"), - - /** - * Dark Orange Preset Color - * - */ - @XmlEnumValue("dkOrange") - DK_ORANGE("dkOrange"), - - /** - * Dark Orchid Preset Color - * - */ - @XmlEnumValue("dkOrchid") - DK_ORCHID("dkOrchid"), - - /** - * Dark Red Preset Color - * - */ - @XmlEnumValue("dkRed") - DK_RED("dkRed"), - - /** - * Dark Salmon Preset Color - * - */ - @XmlEnumValue("dkSalmon") - DK_SALMON("dkSalmon"), - - /** - * Dark Sea Green Preset Color - * - */ - @XmlEnumValue("dkSeaGreen") - DK_SEA_GREEN("dkSeaGreen"), - - /** - * Dark Slate Blue Preset Color - * - */ - @XmlEnumValue("dkSlateBlue") - DK_SLATE_BLUE("dkSlateBlue"), - - /** - * Dark Slate Gray Preset Color - * - */ - @XmlEnumValue("dkSlateGray") - DK_SLATE_GRAY("dkSlateGray"), - - /** - * Dark Turquoise Preset Color - * - */ - @XmlEnumValue("dkTurquoise") - DK_TURQUOISE("dkTurquoise"), - - /** - * Dark Violet Preset Color - * - */ - @XmlEnumValue("dkViolet") - DK_VIOLET("dkViolet"), - - /** - * Deep Pink Preset Color - * - */ - @XmlEnumValue("deepPink") - DEEP_PINK("deepPink"), - - /** - * Deep Sky Blue Preset Color - * - */ - @XmlEnumValue("deepSkyBlue") - DEEP_SKY_BLUE("deepSkyBlue"), - - /** - * Dim Gray Preset Color - * - */ - @XmlEnumValue("dimGray") - DIM_GRAY("dimGray"), - - /** - * Dodger Blue Preset Color - * - */ - @XmlEnumValue("dodgerBlue") - DODGER_BLUE("dodgerBlue"), - - /** - * Firebrick Preset Color - * - */ - @XmlEnumValue("firebrick") - FIREBRICK("firebrick"), - - /** - * Floral White Preset Color - * - */ - @XmlEnumValue("floralWhite") - FLORAL_WHITE("floralWhite"), - - /** - * Forest Green Preset Color - * - */ - @XmlEnumValue("forestGreen") - FOREST_GREEN("forestGreen"), - - /** - * Fuchsia Preset Color - * - */ - @XmlEnumValue("fuchsia") - FUCHSIA("fuchsia"), - - /** - * Gainsboro Preset Color - * - */ - @XmlEnumValue("gainsboro") - GAINSBORO("gainsboro"), - - /** - * Ghost White Preset Color - * - */ - @XmlEnumValue("ghostWhite") - GHOST_WHITE("ghostWhite"), - - /** - * Gold Preset Color - * - */ - @XmlEnumValue("gold") - GOLD("gold"), - - /** - * Goldenrod Preset Color - * - */ - @XmlEnumValue("goldenrod") - GOLDENROD("goldenrod"), - - /** - * Gray Preset Color - * - */ - @XmlEnumValue("gray") - GRAY("gray"), - - /** - * Green Preset Color - * - */ - @XmlEnumValue("green") - GREEN("green"), - - /** - * Green Yellow Preset Color - * - */ - @XmlEnumValue("greenYellow") - GREEN_YELLOW("greenYellow"), - - /** - * Honeydew Preset Color - * - */ - @XmlEnumValue("honeydew") - HONEYDEW("honeydew"), - - /** - * Hot Pink Preset Color - * - */ - @XmlEnumValue("hotPink") - HOT_PINK("hotPink"), - - /** - * Indian Red Preset Color - * - */ - @XmlEnumValue("indianRed") - INDIAN_RED("indianRed"), - - /** - * Indigo Preset Color - * - */ - @XmlEnumValue("indigo") - INDIGO("indigo"), - - /** - * Ivory Preset Color - * - */ - @XmlEnumValue("ivory") - IVORY("ivory"), - - /** - * Khaki Preset Color - * - */ - @XmlEnumValue("khaki") - KHAKI("khaki"), - - /** - * Lavender Preset Color - * - */ - @XmlEnumValue("lavender") - LAVENDER("lavender"), - - /** - * Lavender Blush Preset Color - * - */ - @XmlEnumValue("lavenderBlush") - LAVENDER_BLUSH("lavenderBlush"), - - /** - * Lawn Green Preset Color - * - */ - @XmlEnumValue("lawnGreen") - LAWN_GREEN("lawnGreen"), - - /** - * Lemon Chiffon Preset Color - * - */ - @XmlEnumValue("lemonChiffon") - LEMON_CHIFFON("lemonChiffon"), - - /** - * Light Blue Preset Color - * - */ - @XmlEnumValue("ltBlue") - LT_BLUE("ltBlue"), - - /** - * Light Coral Preset Color - * - */ - @XmlEnumValue("ltCoral") - LT_CORAL("ltCoral"), - - /** - * Light Cyan Preset Color - * - */ - @XmlEnumValue("ltCyan") - LT_CYAN("ltCyan"), - - /** - * Light Goldenrod Yellow Preset Color - * - */ - @XmlEnumValue("ltGoldenrodYellow") - LT_GOLDENROD_YELLOW("ltGoldenrodYellow"), - - /** - * Light Gray Preset Color - * - */ - @XmlEnumValue("ltGray") - LT_GRAY("ltGray"), - - /** - * Light Green Preset Color - * - */ - @XmlEnumValue("ltGreen") - LT_GREEN("ltGreen"), - - /** - * Light Pink Preset Color - * - */ - @XmlEnumValue("ltPink") - LT_PINK("ltPink"), - - /** - * Light Salmon Preset Color - * - */ - @XmlEnumValue("ltSalmon") - LT_SALMON("ltSalmon"), - - /** - * Light Sea Green Preset Color - * - */ - @XmlEnumValue("ltSeaGreen") - LT_SEA_GREEN("ltSeaGreen"), - - /** - * Light Sky Blue Preset Color - * - */ - @XmlEnumValue("ltSkyBlue") - LT_SKY_BLUE("ltSkyBlue"), - - /** - * Light Slate Gray Preset Color - * - */ - @XmlEnumValue("ltSlateGray") - LT_SLATE_GRAY("ltSlateGray"), - - /** - * Light Steel Blue Preset Color - * - */ - @XmlEnumValue("ltSteelBlue") - LT_STEEL_BLUE("ltSteelBlue"), - - /** - * Light Yellow Preset Color - * - */ - @XmlEnumValue("ltYellow") - LT_YELLOW("ltYellow"), - - /** - * Lime Preset Color - * - */ - @XmlEnumValue("lime") - LIME("lime"), - - /** - * Lime Green Preset Color - * - */ - @XmlEnumValue("limeGreen") - LIME_GREEN("limeGreen"), - - /** - * Linen Preset Color - * - */ - @XmlEnumValue("linen") - LINEN("linen"), - - /** - * Magenta Preset Color - * - */ - @XmlEnumValue("magenta") - MAGENTA("magenta"), - - /** - * Maroon Preset Color - * - */ - @XmlEnumValue("maroon") - MAROON("maroon"), - - /** - * Medium Aquamarine Preset Color - * - */ - @XmlEnumValue("medAquamarine") - MED_AQUAMARINE("medAquamarine"), - - /** - * Medium Blue Preset Color - * - */ - @XmlEnumValue("medBlue") - MED_BLUE("medBlue"), - - /** - * Medium Orchid Preset Color - * - */ - @XmlEnumValue("medOrchid") - MED_ORCHID("medOrchid"), - - /** - * Medium Purple Preset Color - * - */ - @XmlEnumValue("medPurple") - MED_PURPLE("medPurple"), - - /** - * Medium Sea Green Preset Color - * - */ - @XmlEnumValue("medSeaGreen") - MED_SEA_GREEN("medSeaGreen"), - - /** - * Medium Slate Blue Preset Color - * - */ - @XmlEnumValue("medSlateBlue") - MED_SLATE_BLUE("medSlateBlue"), - - /** - * Medium Spring Green Preset Color - * - */ - @XmlEnumValue("medSpringGreen") - MED_SPRING_GREEN("medSpringGreen"), - - /** - * Medium Turquoise Preset Color - * - */ - @XmlEnumValue("medTurquoise") - MED_TURQUOISE("medTurquoise"), - - /** - * Medium Violet Red Preset Color - * - */ - @XmlEnumValue("medVioletRed") - MED_VIOLET_RED("medVioletRed"), - - /** - * Midnight Blue Preset Color - * - */ - @XmlEnumValue("midnightBlue") - MIDNIGHT_BLUE("midnightBlue"), - - /** - * Mint Cream Preset Color - * - */ - @XmlEnumValue("mintCream") - MINT_CREAM("mintCream"), - - /** - * Misty Rose Preset Color - * - */ - @XmlEnumValue("mistyRose") - MISTY_ROSE("mistyRose"), - - /** - * Moccasin Preset Color - * - */ - @XmlEnumValue("moccasin") - MOCCASIN("moccasin"), - - /** - * Navajo White Preset Color - * - */ - @XmlEnumValue("navajoWhite") - NAVAJO_WHITE("navajoWhite"), - - /** - * Navy Preset Color - * - */ - @XmlEnumValue("navy") - NAVY("navy"), - - /** - * Old Lace Preset Color - * - */ - @XmlEnumValue("oldLace") - OLD_LACE("oldLace"), - - /** - * Olive Preset Color - * - */ - @XmlEnumValue("olive") - OLIVE("olive"), - - /** - * Olive Drab Preset Color - * - */ - @XmlEnumValue("oliveDrab") - OLIVE_DRAB("oliveDrab"), - - /** - * Orange Preset Color - * - */ - @XmlEnumValue("orange") - ORANGE("orange"), - - /** - * Orange Red Preset Color - * - */ - @XmlEnumValue("orangeRed") - ORANGE_RED("orangeRed"), - - /** - * Orchid Preset Color - * - */ - @XmlEnumValue("orchid") - ORCHID("orchid"), - - /** - * Pale Goldenrod Preset Color - * - */ - @XmlEnumValue("paleGoldenrod") - PALE_GOLDENROD("paleGoldenrod"), - - /** - * Pale Green Preset Color - * - */ - @XmlEnumValue("paleGreen") - PALE_GREEN("paleGreen"), - - /** - * Pale Turquoise Preset Color - * - */ - @XmlEnumValue("paleTurquoise") - PALE_TURQUOISE("paleTurquoise"), - - /** - * Pale Violet Red Preset Color - * - */ - @XmlEnumValue("paleVioletRed") - PALE_VIOLET_RED("paleVioletRed"), - - /** - * Papaya Whip Preset Color - * - */ - @XmlEnumValue("papayaWhip") - PAPAYA_WHIP("papayaWhip"), - - /** - * Peach Puff Preset Color - * - */ - @XmlEnumValue("peachPuff") - PEACH_PUFF("peachPuff"), - - /** - * Peru Preset Color - * - */ - @XmlEnumValue("peru") - PERU("peru"), - - /** - * Pink Preset Color - * - */ - @XmlEnumValue("pink") - PINK("pink"), - - /** - * Plum Preset Color - * - */ - @XmlEnumValue("plum") - PLUM("plum"), - - /** - * Powder Blue Preset Color - * - */ - @XmlEnumValue("powderBlue") - POWDER_BLUE("powderBlue"), - - /** - * Purple Preset Color - * - */ - @XmlEnumValue("purple") - PURPLE("purple"), - - /** - * Red Preset Color - * - */ - @XmlEnumValue("red") - RED("red"), - - /** - * Rosy Brown Preset Color - * - */ - @XmlEnumValue("rosyBrown") - ROSY_BROWN("rosyBrown"), - - /** - * Royal Blue Preset Color - * - */ - @XmlEnumValue("royalBlue") - ROYAL_BLUE("royalBlue"), - - /** - * Saddle Brown Preset Color - * - */ - @XmlEnumValue("saddleBrown") - SADDLE_BROWN("saddleBrown"), - - /** - * Salmon Preset Color - * - */ - @XmlEnumValue("salmon") - SALMON("salmon"), - - /** - * Sandy Brown Preset Color - * - */ - @XmlEnumValue("sandyBrown") - SANDY_BROWN("sandyBrown"), - - /** - * Sea Green Preset Color - * - */ - @XmlEnumValue("seaGreen") - SEA_GREEN("seaGreen"), - - /** - * Sea Shell Preset Color - * - */ - @XmlEnumValue("seaShell") - SEA_SHELL("seaShell"), - - /** - * Sienna Preset Color - * - */ - @XmlEnumValue("sienna") - SIENNA("sienna"), - - /** - * Silver Preset Color - * - */ - @XmlEnumValue("silver") - SILVER("silver"), - - /** - * Sky Blue Preset Color - * - */ - @XmlEnumValue("skyBlue") - SKY_BLUE("skyBlue"), - - /** - * Slate Blue Preset Color - * - */ - @XmlEnumValue("slateBlue") - SLATE_BLUE("slateBlue"), - - /** - * Slate Gray Preset Color - * - */ - @XmlEnumValue("slateGray") - SLATE_GRAY("slateGray"), - - /** - * Snow Preset Color - * - */ - @XmlEnumValue("snow") - SNOW("snow"), - - /** - * Spring Green Preset Color - * - */ - @XmlEnumValue("springGreen") - SPRING_GREEN("springGreen"), - - /** - * Steel Blue Preset Color - * - */ - @XmlEnumValue("steelBlue") - STEEL_BLUE("steelBlue"), - - /** - * Tan Preset Color - * - */ - @XmlEnumValue("tan") - TAN("tan"), - - /** - * Teal Preset Color - * - */ - @XmlEnumValue("teal") - TEAL("teal"), - - /** - * Thistle Preset Color - * - */ - @XmlEnumValue("thistle") - THISTLE("thistle"), - - /** - * Tomato Preset Color - * - */ - @XmlEnumValue("tomato") - TOMATO("tomato"), - - /** - * Turquoise Preset Color - * - */ - @XmlEnumValue("turquoise") - TURQUOISE("turquoise"), - - /** - * Violet Preset Color - * - */ - @XmlEnumValue("violet") - VIOLET("violet"), - - /** - * Wheat Preset Color - * - */ - @XmlEnumValue("wheat") - WHEAT("wheat"), - - /** - * White Preset Color - * - */ - @XmlEnumValue("white") - WHITE("white"), - - /** - * White Smoke Preset Color - * - */ - @XmlEnumValue("whiteSmoke") - WHITE_SMOKE("whiteSmoke"), - - /** - * Yellow Preset Color - * - */ - @XmlEnumValue("yellow") - YELLOW("yellow"), - - /** - * Yellow Green Preset Color - * - */ - @XmlEnumValue("yellowGreen") - YELLOW_GREEN("yellowGreen"); - private final String value; - - STPresetColorVal(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STPresetColorVal fromValue(String v) { - for (STPresetColorVal c: STPresetColorVal.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STRectAlignment.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STRectAlignment.java deleted file mode 100644 index 688a166ba..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STRectAlignment.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_RectAlignment. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_RectAlignment">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="tl"/>
    - *     <enumeration value="t"/>
    - *     <enumeration value="tr"/>
    - *     <enumeration value="l"/>
    - *     <enumeration value="ctr"/>
    - *     <enumeration value="r"/>
    - *     <enumeration value="bl"/>
    - *     <enumeration value="b"/>
    - *     <enumeration value="br"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_RectAlignment", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STRectAlignment { - - - /** - * Rectangle Alignment Enum ( Top Left ) - * - */ - @XmlEnumValue("tl") - TL("tl"), - - /** - * Rectangle Alignment Enum ( Top ) - * - */ - @XmlEnumValue("t") - T("t"), - - /** - * Rectangle Alignment Enum ( Top Right ) - * - */ - @XmlEnumValue("tr") - TR("tr"), - - /** - * Rectangle Alignment Enum ( Left ) - * - */ - @XmlEnumValue("l") - L("l"), - - /** - * Rectangle Alignment Enum ( Center ) - * - */ - @XmlEnumValue("ctr") - CTR("ctr"), - - /** - * Rectangle Alignment Enum ( Right ) - * - */ - @XmlEnumValue("r") - R("r"), - - /** - * Rectangle Alignment Enum ( Bottom Left ) - * - */ - @XmlEnumValue("bl") - BL("bl"), - - /** - * Rectangle Alignment Enum ( Bottom ) - * - */ - @XmlEnumValue("b") - B("b"), - - /** - * Rectangle Alignment Enum ( Bottom Right ) - * - */ - @XmlEnumValue("br") - BR("br"); - private final String value; - - STRectAlignment(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STRectAlignment fromValue(String v) { - for (STRectAlignment c: STRectAlignment.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STSchemeColorVal.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STSchemeColorVal.java deleted file mode 100644 index 84b88075f..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STSchemeColorVal.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_SchemeColorVal. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_SchemeColorVal">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="bg1"/>
    - *     <enumeration value="tx1"/>
    - *     <enumeration value="bg2"/>
    - *     <enumeration value="tx2"/>
    - *     <enumeration value="accent1"/>
    - *     <enumeration value="accent2"/>
    - *     <enumeration value="accent3"/>
    - *     <enumeration value="accent4"/>
    - *     <enumeration value="accent5"/>
    - *     <enumeration value="accent6"/>
    - *     <enumeration value="hlink"/>
    - *     <enumeration value="folHlink"/>
    - *     <enumeration value="phClr"/>
    - *     <enumeration value="dk1"/>
    - *     <enumeration value="lt1"/>
    - *     <enumeration value="dk2"/>
    - *     <enumeration value="lt2"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_SchemeColorVal", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STSchemeColorVal { - - - /** - * Background Color 1 - * - */ - @XmlEnumValue("bg1") - BG_1("bg1"), - - /** - * Text Color 1 - * - */ - @XmlEnumValue("tx1") - TX_1("tx1"), - - /** - * Background Color 2 - * - */ - @XmlEnumValue("bg2") - BG_2("bg2"), - - /** - * Text Color 2 - * - */ - @XmlEnumValue("tx2") - TX_2("tx2"), - - /** - * Accent Color 1 - * - */ - @XmlEnumValue("accent1") - ACCENT_1("accent1"), - - /** - * Accent Color 2 - * - */ - @XmlEnumValue("accent2") - ACCENT_2("accent2"), - - /** - * Accent Color 3 - * - */ - @XmlEnumValue("accent3") - ACCENT_3("accent3"), - - /** - * Accent Color 4 - * - */ - @XmlEnumValue("accent4") - ACCENT_4("accent4"), - - /** - * Accent Color 5 - * - */ - @XmlEnumValue("accent5") - ACCENT_5("accent5"), - - /** - * Accent Color 6 - * - */ - @XmlEnumValue("accent6") - ACCENT_6("accent6"), - - /** - * Hyperlink Color - * - */ - @XmlEnumValue("hlink") - HLINK("hlink"), - - /** - * Followed Hyperlink Color - * - */ - @XmlEnumValue("folHlink") - FOL_HLINK("folHlink"), - - /** - * Style Color - * - */ - @XmlEnumValue("phClr") - PH_CLR("phClr"), - - /** - * Dark Color 1 - * - */ - @XmlEnumValue("dk1") - DK_1("dk1"), - - /** - * Light Color 1 - * - */ - @XmlEnumValue("lt1") - LT_1("lt1"), - - /** - * Dark Color 2 - * - */ - @XmlEnumValue("dk2") - DK_2("dk2"), - - /** - * Light Color 2 - * - */ - @XmlEnumValue("lt2") - LT_2("lt2"); - private final String value; - - STSchemeColorVal(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STSchemeColorVal fromValue(String v) { - for (STSchemeColorVal c: STSchemeColorVal.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STShapeType.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STShapeType.java deleted file mode 100644 index 559b0a159..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STShapeType.java +++ /dev/null @@ -1,1557 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_ShapeType. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_ShapeType">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="line"/>
    - *     <enumeration value="lineInv"/>
    - *     <enumeration value="triangle"/>
    - *     <enumeration value="rtTriangle"/>
    - *     <enumeration value="rect"/>
    - *     <enumeration value="diamond"/>
    - *     <enumeration value="parallelogram"/>
    - *     <enumeration value="trapezoid"/>
    - *     <enumeration value="nonIsoscelesTrapezoid"/>
    - *     <enumeration value="pentagon"/>
    - *     <enumeration value="hexagon"/>
    - *     <enumeration value="heptagon"/>
    - *     <enumeration value="octagon"/>
    - *     <enumeration value="decagon"/>
    - *     <enumeration value="dodecagon"/>
    - *     <enumeration value="star4"/>
    - *     <enumeration value="star5"/>
    - *     <enumeration value="star6"/>
    - *     <enumeration value="star7"/>
    - *     <enumeration value="star8"/>
    - *     <enumeration value="star10"/>
    - *     <enumeration value="star12"/>
    - *     <enumeration value="star16"/>
    - *     <enumeration value="star24"/>
    - *     <enumeration value="star32"/>
    - *     <enumeration value="roundRect"/>
    - *     <enumeration value="round1Rect"/>
    - *     <enumeration value="round2SameRect"/>
    - *     <enumeration value="round2DiagRect"/>
    - *     <enumeration value="snipRoundRect"/>
    - *     <enumeration value="snip1Rect"/>
    - *     <enumeration value="snip2SameRect"/>
    - *     <enumeration value="snip2DiagRect"/>
    - *     <enumeration value="plaque"/>
    - *     <enumeration value="ellipse"/>
    - *     <enumeration value="teardrop"/>
    - *     <enumeration value="homePlate"/>
    - *     <enumeration value="chevron"/>
    - *     <enumeration value="pieWedge"/>
    - *     <enumeration value="pie"/>
    - *     <enumeration value="blockArc"/>
    - *     <enumeration value="donut"/>
    - *     <enumeration value="noSmoking"/>
    - *     <enumeration value="rightArrow"/>
    - *     <enumeration value="leftArrow"/>
    - *     <enumeration value="upArrow"/>
    - *     <enumeration value="downArrow"/>
    - *     <enumeration value="stripedRightArrow"/>
    - *     <enumeration value="notchedRightArrow"/>
    - *     <enumeration value="bentUpArrow"/>
    - *     <enumeration value="leftRightArrow"/>
    - *     <enumeration value="upDownArrow"/>
    - *     <enumeration value="leftUpArrow"/>
    - *     <enumeration value="leftRightUpArrow"/>
    - *     <enumeration value="quadArrow"/>
    - *     <enumeration value="leftArrowCallout"/>
    - *     <enumeration value="rightArrowCallout"/>
    - *     <enumeration value="upArrowCallout"/>
    - *     <enumeration value="downArrowCallout"/>
    - *     <enumeration value="leftRightArrowCallout"/>
    - *     <enumeration value="upDownArrowCallout"/>
    - *     <enumeration value="quadArrowCallout"/>
    - *     <enumeration value="bentArrow"/>
    - *     <enumeration value="uturnArrow"/>
    - *     <enumeration value="circularArrow"/>
    - *     <enumeration value="leftCircularArrow"/>
    - *     <enumeration value="leftRightCircularArrow"/>
    - *     <enumeration value="curvedRightArrow"/>
    - *     <enumeration value="curvedLeftArrow"/>
    - *     <enumeration value="curvedUpArrow"/>
    - *     <enumeration value="curvedDownArrow"/>
    - *     <enumeration value="swooshArrow"/>
    - *     <enumeration value="cube"/>
    - *     <enumeration value="can"/>
    - *     <enumeration value="lightningBolt"/>
    - *     <enumeration value="heart"/>
    - *     <enumeration value="sun"/>
    - *     <enumeration value="moon"/>
    - *     <enumeration value="smileyFace"/>
    - *     <enumeration value="irregularSeal1"/>
    - *     <enumeration value="irregularSeal2"/>
    - *     <enumeration value="foldedCorner"/>
    - *     <enumeration value="bevel"/>
    - *     <enumeration value="frame"/>
    - *     <enumeration value="halfFrame"/>
    - *     <enumeration value="corner"/>
    - *     <enumeration value="diagStripe"/>
    - *     <enumeration value="chord"/>
    - *     <enumeration value="arc"/>
    - *     <enumeration value="leftBracket"/>
    - *     <enumeration value="rightBracket"/>
    - *     <enumeration value="leftBrace"/>
    - *     <enumeration value="rightBrace"/>
    - *     <enumeration value="bracketPair"/>
    - *     <enumeration value="bracePair"/>
    - *     <enumeration value="straightConnector1"/>
    - *     <enumeration value="bentConnector2"/>
    - *     <enumeration value="bentConnector3"/>
    - *     <enumeration value="bentConnector4"/>
    - *     <enumeration value="bentConnector5"/>
    - *     <enumeration value="curvedConnector2"/>
    - *     <enumeration value="curvedConnector3"/>
    - *     <enumeration value="curvedConnector4"/>
    - *     <enumeration value="curvedConnector5"/>
    - *     <enumeration value="callout1"/>
    - *     <enumeration value="callout2"/>
    - *     <enumeration value="callout3"/>
    - *     <enumeration value="accentCallout1"/>
    - *     <enumeration value="accentCallout2"/>
    - *     <enumeration value="accentCallout3"/>
    - *     <enumeration value="borderCallout1"/>
    - *     <enumeration value="borderCallout2"/>
    - *     <enumeration value="borderCallout3"/>
    - *     <enumeration value="accentBorderCallout1"/>
    - *     <enumeration value="accentBorderCallout2"/>
    - *     <enumeration value="accentBorderCallout3"/>
    - *     <enumeration value="wedgeRectCallout"/>
    - *     <enumeration value="wedgeRoundRectCallout"/>
    - *     <enumeration value="wedgeEllipseCallout"/>
    - *     <enumeration value="cloudCallout"/>
    - *     <enumeration value="cloud"/>
    - *     <enumeration value="ribbon"/>
    - *     <enumeration value="ribbon2"/>
    - *     <enumeration value="ellipseRibbon"/>
    - *     <enumeration value="ellipseRibbon2"/>
    - *     <enumeration value="leftRightRibbon"/>
    - *     <enumeration value="verticalScroll"/>
    - *     <enumeration value="horizontalScroll"/>
    - *     <enumeration value="wave"/>
    - *     <enumeration value="doubleWave"/>
    - *     <enumeration value="plus"/>
    - *     <enumeration value="flowChartProcess"/>
    - *     <enumeration value="flowChartDecision"/>
    - *     <enumeration value="flowChartInputOutput"/>
    - *     <enumeration value="flowChartPredefinedProcess"/>
    - *     <enumeration value="flowChartInternalStorage"/>
    - *     <enumeration value="flowChartDocument"/>
    - *     <enumeration value="flowChartMultidocument"/>
    - *     <enumeration value="flowChartTerminator"/>
    - *     <enumeration value="flowChartPreparation"/>
    - *     <enumeration value="flowChartManualInput"/>
    - *     <enumeration value="flowChartManualOperation"/>
    - *     <enumeration value="flowChartConnector"/>
    - *     <enumeration value="flowChartPunchedCard"/>
    - *     <enumeration value="flowChartPunchedTape"/>
    - *     <enumeration value="flowChartSummingJunction"/>
    - *     <enumeration value="flowChartOr"/>
    - *     <enumeration value="flowChartCollate"/>
    - *     <enumeration value="flowChartSort"/>
    - *     <enumeration value="flowChartExtract"/>
    - *     <enumeration value="flowChartMerge"/>
    - *     <enumeration value="flowChartOfflineStorage"/>
    - *     <enumeration value="flowChartOnlineStorage"/>
    - *     <enumeration value="flowChartMagneticTape"/>
    - *     <enumeration value="flowChartMagneticDisk"/>
    - *     <enumeration value="flowChartMagneticDrum"/>
    - *     <enumeration value="flowChartDisplay"/>
    - *     <enumeration value="flowChartDelay"/>
    - *     <enumeration value="flowChartAlternateProcess"/>
    - *     <enumeration value="flowChartOffpageConnector"/>
    - *     <enumeration value="actionButtonBlank"/>
    - *     <enumeration value="actionButtonHome"/>
    - *     <enumeration value="actionButtonHelp"/>
    - *     <enumeration value="actionButtonInformation"/>
    - *     <enumeration value="actionButtonForwardNext"/>
    - *     <enumeration value="actionButtonBackPrevious"/>
    - *     <enumeration value="actionButtonEnd"/>
    - *     <enumeration value="actionButtonBeginning"/>
    - *     <enumeration value="actionButtonReturn"/>
    - *     <enumeration value="actionButtonDocument"/>
    - *     <enumeration value="actionButtonSound"/>
    - *     <enumeration value="actionButtonMovie"/>
    - *     <enumeration value="gear6"/>
    - *     <enumeration value="gear9"/>
    - *     <enumeration value="funnel"/>
    - *     <enumeration value="mathPlus"/>
    - *     <enumeration value="mathMinus"/>
    - *     <enumeration value="mathMultiply"/>
    - *     <enumeration value="mathDivide"/>
    - *     <enumeration value="mathEqual"/>
    - *     <enumeration value="mathNotEqual"/>
    - *     <enumeration value="cornerTabs"/>
    - *     <enumeration value="squareTabs"/>
    - *     <enumeration value="plaqueTabs"/>
    - *     <enumeration value="chartX"/>
    - *     <enumeration value="chartStar"/>
    - *     <enumeration value="chartPlus"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_ShapeType", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STShapeType { - - - /** - * Line Shape - * - */ - @XmlEnumValue("line") - LINE("line"), - - /** - * Line Inverse Shape - * - */ - @XmlEnumValue("lineInv") - LINE_INV("lineInv"), - - /** - * Triangle Shape - * - */ - @XmlEnumValue("triangle") - TRIANGLE("triangle"), - - /** - * Right Triangle Shape - * - */ - @XmlEnumValue("rtTriangle") - RT_TRIANGLE("rtTriangle"), - - /** - * Rectangle Shape - * - */ - @XmlEnumValue("rect") - RECT("rect"), - - /** - * Diamond Shape - * - */ - @XmlEnumValue("diamond") - DIAMOND("diamond"), - - /** - * Parallelogram Shape - * - */ - @XmlEnumValue("parallelogram") - PARALLELOGRAM("parallelogram"), - - /** - * Trapezoid Shape - * - */ - @XmlEnumValue("trapezoid") - TRAPEZOID("trapezoid"), - - /** - * Non-Isosceles Trapezoid Shape - * - */ - @XmlEnumValue("nonIsoscelesTrapezoid") - NON_ISOSCELES_TRAPEZOID("nonIsoscelesTrapezoid"), - - /** - * Pentagon Shape - * - */ - @XmlEnumValue("pentagon") - PENTAGON("pentagon"), - - /** - * Hexagon Shape - * - */ - @XmlEnumValue("hexagon") - HEXAGON("hexagon"), - - /** - * Heptagon Shape - * - */ - @XmlEnumValue("heptagon") - HEPTAGON("heptagon"), - - /** - * Octagon Shape - * - */ - @XmlEnumValue("octagon") - OCTAGON("octagon"), - - /** - * Decagon Shape - * - */ - @XmlEnumValue("decagon") - DECAGON("decagon"), - - /** - * Dodecagon Shape - * - */ - @XmlEnumValue("dodecagon") - DODECAGON("dodecagon"), - - /** - * Four Pointed Star Shape - * - */ - @XmlEnumValue("star4") - STAR_4("star4"), - - /** - * Five Pointed Star Shape - * - */ - @XmlEnumValue("star5") - STAR_5("star5"), - - /** - * Six Pointed Star Shape - * - */ - @XmlEnumValue("star6") - STAR_6("star6"), - - /** - * Seven Pointed Star Shape - * - */ - @XmlEnumValue("star7") - STAR_7("star7"), - - /** - * Eight Pointed Star Shape - * - */ - @XmlEnumValue("star8") - STAR_8("star8"), - - /** - * Ten Pointed Star Shape - * - */ - @XmlEnumValue("star10") - STAR_10("star10"), - - /** - * Twelve Pointed Star Shape - * - */ - @XmlEnumValue("star12") - STAR_12("star12"), - - /** - * Sixteen Pointed Star Shape - * - */ - @XmlEnumValue("star16") - STAR_16("star16"), - - /** - * Twenty Four Pointed Star Shape - * - */ - @XmlEnumValue("star24") - STAR_24("star24"), - - /** - * Thirty Two Pointed Star Shape - * - */ - @XmlEnumValue("star32") - STAR_32("star32"), - - /** - * Round Corner Rectangle Shape - * - */ - @XmlEnumValue("roundRect") - ROUND_RECT("roundRect"), - - /** - * One Round Corner Rectangle Shape - * - */ - @XmlEnumValue("round1Rect") - ROUND_1_RECT("round1Rect"), - - /** - * Two Same-side Round Corner Rectangle Shape - * - */ - @XmlEnumValue("round2SameRect") - ROUND_2_SAME_RECT("round2SameRect"), - - /** - * Two Diagonal Round Corner Rectangle Shape - * - */ - @XmlEnumValue("round2DiagRect") - ROUND_2_DIAG_RECT("round2DiagRect"), - - /** - * One Snip One Round Corner Rectangle Shape - * - */ - @XmlEnumValue("snipRoundRect") - SNIP_ROUND_RECT("snipRoundRect"), - - /** - * One Snip Corner Rectangle Shape - * - */ - @XmlEnumValue("snip1Rect") - SNIP_1_RECT("snip1Rect"), - - /** - * Two Same-side Snip Corner Rectangle Shape - * - */ - @XmlEnumValue("snip2SameRect") - SNIP_2_SAME_RECT("snip2SameRect"), - - /** - * Two Diagonal Snip Corner Rectangle Shape - * - */ - @XmlEnumValue("snip2DiagRect") - SNIP_2_DIAG_RECT("snip2DiagRect"), - - /** - * Plaque Shape - * - */ - @XmlEnumValue("plaque") - PLAQUE("plaque"), - - /** - * Ellipse Shape - * - */ - @XmlEnumValue("ellipse") - ELLIPSE("ellipse"), - - /** - * Teardrop Shape - * - */ - @XmlEnumValue("teardrop") - TEARDROP("teardrop"), - - /** - * Home Plate Shape - * - */ - @XmlEnumValue("homePlate") - HOME_PLATE("homePlate"), - - /** - * Chevron Shape - * - */ - @XmlEnumValue("chevron") - CHEVRON("chevron"), - - /** - * Pie Wedge Shape - * - */ - @XmlEnumValue("pieWedge") - PIE_WEDGE("pieWedge"), - - /** - * Pie Shape - * - */ - @XmlEnumValue("pie") - PIE("pie"), - - /** - * Block Arc Shape - * - */ - @XmlEnumValue("blockArc") - BLOCK_ARC("blockArc"), - - /** - * Donut Shape - * - */ - @XmlEnumValue("donut") - DONUT("donut"), - - /** - * No Smoking Shape - * - */ - @XmlEnumValue("noSmoking") - NO_SMOKING("noSmoking"), - - /** - * Right Arrow Shape - * - */ - @XmlEnumValue("rightArrow") - RIGHT_ARROW("rightArrow"), - - /** - * Left Arrow Shape - * - */ - @XmlEnumValue("leftArrow") - LEFT_ARROW("leftArrow"), - - /** - * Up Arrow Shape - * - */ - @XmlEnumValue("upArrow") - UP_ARROW("upArrow"), - - /** - * Down Arrow Shape - * - */ - @XmlEnumValue("downArrow") - DOWN_ARROW("downArrow"), - - /** - * Striped Right Arrow Shape - * - */ - @XmlEnumValue("stripedRightArrow") - STRIPED_RIGHT_ARROW("stripedRightArrow"), - - /** - * Notched Right Arrow Shape - * - */ - @XmlEnumValue("notchedRightArrow") - NOTCHED_RIGHT_ARROW("notchedRightArrow"), - - /** - * Bent Up Arrow Shape - * - */ - @XmlEnumValue("bentUpArrow") - BENT_UP_ARROW("bentUpArrow"), - - /** - * Left Right Arrow Shape - * - */ - @XmlEnumValue("leftRightArrow") - LEFT_RIGHT_ARROW("leftRightArrow"), - - /** - * Up Down Arrow Shape - * - */ - @XmlEnumValue("upDownArrow") - UP_DOWN_ARROW("upDownArrow"), - - /** - * Left Up Arrow Shape - * - */ - @XmlEnumValue("leftUpArrow") - LEFT_UP_ARROW("leftUpArrow"), - - /** - * Left Right Up Arrow Shape - * - */ - @XmlEnumValue("leftRightUpArrow") - LEFT_RIGHT_UP_ARROW("leftRightUpArrow"), - - /** - * Quad-Arrow Shape - * - */ - @XmlEnumValue("quadArrow") - QUAD_ARROW("quadArrow"), - - /** - * Callout Left Arrow Shape - * - */ - @XmlEnumValue("leftArrowCallout") - LEFT_ARROW_CALLOUT("leftArrowCallout"), - - /** - * Callout Right Arrow Shape - * - */ - @XmlEnumValue("rightArrowCallout") - RIGHT_ARROW_CALLOUT("rightArrowCallout"), - - /** - * Callout Up Arrow Shape - * - */ - @XmlEnumValue("upArrowCallout") - UP_ARROW_CALLOUT("upArrowCallout"), - - /** - * Callout Down Arrow Shape - * - */ - @XmlEnumValue("downArrowCallout") - DOWN_ARROW_CALLOUT("downArrowCallout"), - - /** - * Callout Left Right Arrow Shape - * - */ - @XmlEnumValue("leftRightArrowCallout") - LEFT_RIGHT_ARROW_CALLOUT("leftRightArrowCallout"), - - /** - * Callout Up Down Arrow Shape - * - */ - @XmlEnumValue("upDownArrowCallout") - UP_DOWN_ARROW_CALLOUT("upDownArrowCallout"), - - /** - * Callout Quad-Arrow Shape - * - */ - @XmlEnumValue("quadArrowCallout") - QUAD_ARROW_CALLOUT("quadArrowCallout"), - - /** - * Bent Arrow Shape - * - */ - @XmlEnumValue("bentArrow") - BENT_ARROW("bentArrow"), - - /** - * U-Turn Arrow Shape - * - */ - @XmlEnumValue("uturnArrow") - UTURN_ARROW("uturnArrow"), - - /** - * Circular Arrow Shape - * - */ - @XmlEnumValue("circularArrow") - CIRCULAR_ARROW("circularArrow"), - - /** - * Left Circular Arrow Shape - * - */ - @XmlEnumValue("leftCircularArrow") - LEFT_CIRCULAR_ARROW("leftCircularArrow"), - - /** - * Left Right Circular Arrow Shape - * - */ - @XmlEnumValue("leftRightCircularArrow") - LEFT_RIGHT_CIRCULAR_ARROW("leftRightCircularArrow"), - - /** - * Curved Right Arrow Shape - * - */ - @XmlEnumValue("curvedRightArrow") - CURVED_RIGHT_ARROW("curvedRightArrow"), - - /** - * Curved Left Arrow Shape - * - */ - @XmlEnumValue("curvedLeftArrow") - CURVED_LEFT_ARROW("curvedLeftArrow"), - - /** - * Curved Up Arrow Shape - * - */ - @XmlEnumValue("curvedUpArrow") - CURVED_UP_ARROW("curvedUpArrow"), - - /** - * Curved Down Arrow Shape - * - */ - @XmlEnumValue("curvedDownArrow") - CURVED_DOWN_ARROW("curvedDownArrow"), - - /** - * Swoosh Arrow Shape - * - */ - @XmlEnumValue("swooshArrow") - SWOOSH_ARROW("swooshArrow"), - - /** - * Cube Shape - * - */ - @XmlEnumValue("cube") - CUBE("cube"), - - /** - * Can Shape - * - */ - @XmlEnumValue("can") - CAN("can"), - - /** - * Lightning Bolt Shape - * - */ - @XmlEnumValue("lightningBolt") - LIGHTNING_BOLT("lightningBolt"), - - /** - * Heart Shape - * - */ - @XmlEnumValue("heart") - HEART("heart"), - - /** - * Sun Shape - * - */ - @XmlEnumValue("sun") - SUN("sun"), - - /** - * Moon Shape - * - */ - @XmlEnumValue("moon") - MOON("moon"), - - /** - * Smiley Face Shape - * - */ - @XmlEnumValue("smileyFace") - SMILEY_FACE("smileyFace"), - - /** - * Irregular Seal 1 Shape - * - */ - @XmlEnumValue("irregularSeal1") - IRREGULAR_SEAL_1("irregularSeal1"), - - /** - * Irregular Seal 2 Shape - * - */ - @XmlEnumValue("irregularSeal2") - IRREGULAR_SEAL_2("irregularSeal2"), - - /** - * Folded Corner Shape - * - */ - @XmlEnumValue("foldedCorner") - FOLDED_CORNER("foldedCorner"), - - /** - * Bevel Shape - * - */ - @XmlEnumValue("bevel") - BEVEL("bevel"), - - /** - * Frame Shape - * - */ - @XmlEnumValue("frame") - FRAME("frame"), - - /** - * Half Frame Shape - * - */ - @XmlEnumValue("halfFrame") - HALF_FRAME("halfFrame"), - - /** - * Corner Shape - * - */ - @XmlEnumValue("corner") - CORNER("corner"), - - /** - * Diagonal Stripe Shape - * - */ - @XmlEnumValue("diagStripe") - DIAG_STRIPE("diagStripe"), - - /** - * Chord Shape - * - */ - @XmlEnumValue("chord") - CHORD("chord"), - - /** - * Curved Arc Shape - * - */ - @XmlEnumValue("arc") - ARC("arc"), - - /** - * Left Bracket Shape - * - */ - @XmlEnumValue("leftBracket") - LEFT_BRACKET("leftBracket"), - - /** - * Right Bracket Shape - * - */ - @XmlEnumValue("rightBracket") - RIGHT_BRACKET("rightBracket"), - - /** - * Left Brace Shape - * - */ - @XmlEnumValue("leftBrace") - LEFT_BRACE("leftBrace"), - - /** - * Right Brace Shape - * - */ - @XmlEnumValue("rightBrace") - RIGHT_BRACE("rightBrace"), - - /** - * Bracket Pair Shape - * - */ - @XmlEnumValue("bracketPair") - BRACKET_PAIR("bracketPair"), - - /** - * Brace Pair Shape - * - */ - @XmlEnumValue("bracePair") - BRACE_PAIR("bracePair"), - - /** - * Straight Connector 1 Shape - * - */ - @XmlEnumValue("straightConnector1") - STRAIGHT_CONNECTOR_1("straightConnector1"), - - /** - * Bent Connector 2 Shape - * - */ - @XmlEnumValue("bentConnector2") - BENT_CONNECTOR_2("bentConnector2"), - - /** - * Bent Connector 3 Shape - * - */ - @XmlEnumValue("bentConnector3") - BENT_CONNECTOR_3("bentConnector3"), - - /** - * Bent Connector 4 Shape - * - */ - @XmlEnumValue("bentConnector4") - BENT_CONNECTOR_4("bentConnector4"), - - /** - * Bent Connector 5 Shape - * - */ - @XmlEnumValue("bentConnector5") - BENT_CONNECTOR_5("bentConnector5"), - - /** - * Curved Connector 2 Shape - * - */ - @XmlEnumValue("curvedConnector2") - CURVED_CONNECTOR_2("curvedConnector2"), - - /** - * Curved Connector 3 Shape - * - */ - @XmlEnumValue("curvedConnector3") - CURVED_CONNECTOR_3("curvedConnector3"), - - /** - * Curved Connector 4 Shape - * - */ - @XmlEnumValue("curvedConnector4") - CURVED_CONNECTOR_4("curvedConnector4"), - - /** - * Curved Connector 5 Shape - * - */ - @XmlEnumValue("curvedConnector5") - CURVED_CONNECTOR_5("curvedConnector5"), - - /** - * Callout 1 Shape - * - */ - @XmlEnumValue("callout1") - CALLOUT_1("callout1"), - - /** - * Callout 2 Shape - * - */ - @XmlEnumValue("callout2") - CALLOUT_2("callout2"), - - /** - * Callout 3 Shape - * - */ - @XmlEnumValue("callout3") - CALLOUT_3("callout3"), - - /** - * Callout 1 Shape - * - */ - @XmlEnumValue("accentCallout1") - ACCENT_CALLOUT_1("accentCallout1"), - - /** - * Callout 2 Shape - * - */ - @XmlEnumValue("accentCallout2") - ACCENT_CALLOUT_2("accentCallout2"), - - /** - * Callout 3 Shape - * - */ - @XmlEnumValue("accentCallout3") - ACCENT_CALLOUT_3("accentCallout3"), - - /** - * Callout 1 with Border Shape - * - */ - @XmlEnumValue("borderCallout1") - BORDER_CALLOUT_1("borderCallout1"), - - /** - * Callout 2 with Border Shape - * - */ - @XmlEnumValue("borderCallout2") - BORDER_CALLOUT_2("borderCallout2"), - - /** - * Callout 3 with Border Shape - * - */ - @XmlEnumValue("borderCallout3") - BORDER_CALLOUT_3("borderCallout3"), - - /** - * Callout 1 with Border and Accent Shape - * - */ - @XmlEnumValue("accentBorderCallout1") - ACCENT_BORDER_CALLOUT_1("accentBorderCallout1"), - - /** - * Callout 2 with Border and Accent Shape - * - */ - @XmlEnumValue("accentBorderCallout2") - ACCENT_BORDER_CALLOUT_2("accentBorderCallout2"), - - /** - * Callout 3 with Border and Accent Shape - * - */ - @XmlEnumValue("accentBorderCallout3") - ACCENT_BORDER_CALLOUT_3("accentBorderCallout3"), - - /** - * Callout Wedge Rectangle Shape - * - */ - @XmlEnumValue("wedgeRectCallout") - WEDGE_RECT_CALLOUT("wedgeRectCallout"), - - /** - * Callout Wedge Round Rectangle Shape - * - */ - @XmlEnumValue("wedgeRoundRectCallout") - WEDGE_ROUND_RECT_CALLOUT("wedgeRoundRectCallout"), - - /** - * Callout Wedge Ellipse Shape - * - */ - @XmlEnumValue("wedgeEllipseCallout") - WEDGE_ELLIPSE_CALLOUT("wedgeEllipseCallout"), - - /** - * Callout Cloud Shape - * - */ - @XmlEnumValue("cloudCallout") - CLOUD_CALLOUT("cloudCallout"), - - /** - * Cloud Shape - * - */ - @XmlEnumValue("cloud") - CLOUD("cloud"), - - /** - * Ribbon Shape - * - */ - @XmlEnumValue("ribbon") - RIBBON("ribbon"), - - /** - * Ribbon 2 Shape - * - */ - @XmlEnumValue("ribbon2") - RIBBON_2("ribbon2"), - - /** - * Ellipse Ribbon Shape - * - */ - @XmlEnumValue("ellipseRibbon") - ELLIPSE_RIBBON("ellipseRibbon"), - - /** - * Ellipse Ribbon 2 Shape - * - */ - @XmlEnumValue("ellipseRibbon2") - ELLIPSE_RIBBON_2("ellipseRibbon2"), - - /** - * Left Right Ribbon Shape - * - */ - @XmlEnumValue("leftRightRibbon") - LEFT_RIGHT_RIBBON("leftRightRibbon"), - - /** - * Vertical Scroll Shape - * - */ - @XmlEnumValue("verticalScroll") - VERTICAL_SCROLL("verticalScroll"), - - /** - * Horizontal Scroll Shape - * - */ - @XmlEnumValue("horizontalScroll") - HORIZONTAL_SCROLL("horizontalScroll"), - - /** - * Wave Shape - * - */ - @XmlEnumValue("wave") - WAVE("wave"), - - /** - * Double Wave Shape - * - */ - @XmlEnumValue("doubleWave") - DOUBLE_WAVE("doubleWave"), - - /** - * Plus Shape - * - */ - @XmlEnumValue("plus") - PLUS("plus"), - - /** - * Process Flow Shape - * - */ - @XmlEnumValue("flowChartProcess") - FLOW_CHART_PROCESS("flowChartProcess"), - - /** - * Decision Flow Shape - * - */ - @XmlEnumValue("flowChartDecision") - FLOW_CHART_DECISION("flowChartDecision"), - - /** - * Input Output Flow Shape - * - */ - @XmlEnumValue("flowChartInputOutput") - FLOW_CHART_INPUT_OUTPUT("flowChartInputOutput"), - - /** - * Predefined Process Flow Shape - * - */ - @XmlEnumValue("flowChartPredefinedProcess") - FLOW_CHART_PREDEFINED_PROCESS("flowChartPredefinedProcess"), - - /** - * Internal Storage Flow Shape - * - */ - @XmlEnumValue("flowChartInternalStorage") - FLOW_CHART_INTERNAL_STORAGE("flowChartInternalStorage"), - - /** - * Document Flow Shape - * - */ - @XmlEnumValue("flowChartDocument") - FLOW_CHART_DOCUMENT("flowChartDocument"), - - /** - * Multi-Document Flow Shape - * - */ - @XmlEnumValue("flowChartMultidocument") - FLOW_CHART_MULTIDOCUMENT("flowChartMultidocument"), - - /** - * Terminator Flow Shape - * - */ - @XmlEnumValue("flowChartTerminator") - FLOW_CHART_TERMINATOR("flowChartTerminator"), - - /** - * Preparation Flow Shape - * - */ - @XmlEnumValue("flowChartPreparation") - FLOW_CHART_PREPARATION("flowChartPreparation"), - - /** - * Manual Input Flow Shape - * - */ - @XmlEnumValue("flowChartManualInput") - FLOW_CHART_MANUAL_INPUT("flowChartManualInput"), - - /** - * Manual Operation Flow Shape - * - */ - @XmlEnumValue("flowChartManualOperation") - FLOW_CHART_MANUAL_OPERATION("flowChartManualOperation"), - - /** - * Connector Flow Shape - * - */ - @XmlEnumValue("flowChartConnector") - FLOW_CHART_CONNECTOR("flowChartConnector"), - - /** - * Punched Card Flow Shape - * - */ - @XmlEnumValue("flowChartPunchedCard") - FLOW_CHART_PUNCHED_CARD("flowChartPunchedCard"), - - /** - * Punched Tape Flow Shape - * - */ - @XmlEnumValue("flowChartPunchedTape") - FLOW_CHART_PUNCHED_TAPE("flowChartPunchedTape"), - - /** - * Summing Junction Flow Shape - * - */ - @XmlEnumValue("flowChartSummingJunction") - FLOW_CHART_SUMMING_JUNCTION("flowChartSummingJunction"), - - /** - * Or Flow Shape - * - */ - @XmlEnumValue("flowChartOr") - FLOW_CHART_OR("flowChartOr"), - - /** - * Collate Flow Shape - * - */ - @XmlEnumValue("flowChartCollate") - FLOW_CHART_COLLATE("flowChartCollate"), - - /** - * Sort Flow Shape - * - */ - @XmlEnumValue("flowChartSort") - FLOW_CHART_SORT("flowChartSort"), - - /** - * Extract Flow Shape - * - */ - @XmlEnumValue("flowChartExtract") - FLOW_CHART_EXTRACT("flowChartExtract"), - - /** - * Merge Flow Shape - * - */ - @XmlEnumValue("flowChartMerge") - FLOW_CHART_MERGE("flowChartMerge"), - - /** - * Offline Storage Flow Shape - * - */ - @XmlEnumValue("flowChartOfflineStorage") - FLOW_CHART_OFFLINE_STORAGE("flowChartOfflineStorage"), - - /** - * Online Storage Flow Shape - * - */ - @XmlEnumValue("flowChartOnlineStorage") - FLOW_CHART_ONLINE_STORAGE("flowChartOnlineStorage"), - - /** - * Magnetic Tape Flow Shape - * - */ - @XmlEnumValue("flowChartMagneticTape") - FLOW_CHART_MAGNETIC_TAPE("flowChartMagneticTape"), - - /** - * Magnetic Disk Flow Shape - * - */ - @XmlEnumValue("flowChartMagneticDisk") - FLOW_CHART_MAGNETIC_DISK("flowChartMagneticDisk"), - - /** - * Magnetic Drum Flow Shape - * - */ - @XmlEnumValue("flowChartMagneticDrum") - FLOW_CHART_MAGNETIC_DRUM("flowChartMagneticDrum"), - - /** - * Display Flow Shape - * - */ - @XmlEnumValue("flowChartDisplay") - FLOW_CHART_DISPLAY("flowChartDisplay"), - - /** - * Delay Flow Shape - * - */ - @XmlEnumValue("flowChartDelay") - FLOW_CHART_DELAY("flowChartDelay"), - - /** - * Alternate Process Flow Shape - * - */ - @XmlEnumValue("flowChartAlternateProcess") - FLOW_CHART_ALTERNATE_PROCESS("flowChartAlternateProcess"), - - /** - * Off-Page Connector Flow Shape - * - */ - @XmlEnumValue("flowChartOffpageConnector") - FLOW_CHART_OFFPAGE_CONNECTOR("flowChartOffpageConnector"), - - /** - * Blank Button Shape - * - */ - @XmlEnumValue("actionButtonBlank") - ACTION_BUTTON_BLANK("actionButtonBlank"), - - /** - * Home Button Shape - * - */ - @XmlEnumValue("actionButtonHome") - ACTION_BUTTON_HOME("actionButtonHome"), - - /** - * Help Button Shape - * - */ - @XmlEnumValue("actionButtonHelp") - ACTION_BUTTON_HELP("actionButtonHelp"), - - /** - * Information Button Shape - * - */ - @XmlEnumValue("actionButtonInformation") - ACTION_BUTTON_INFORMATION("actionButtonInformation"), - - /** - * Forward or Next Button Shape - * - */ - @XmlEnumValue("actionButtonForwardNext") - ACTION_BUTTON_FORWARD_NEXT("actionButtonForwardNext"), - - /** - * Back or Previous Button Shape - * - */ - @XmlEnumValue("actionButtonBackPrevious") - ACTION_BUTTON_BACK_PREVIOUS("actionButtonBackPrevious"), - - /** - * End Button Shape - * - */ - @XmlEnumValue("actionButtonEnd") - ACTION_BUTTON_END("actionButtonEnd"), - - /** - * Beginning Button Shape - * - */ - @XmlEnumValue("actionButtonBeginning") - ACTION_BUTTON_BEGINNING("actionButtonBeginning"), - - /** - * Return Button Shape - * - */ - @XmlEnumValue("actionButtonReturn") - ACTION_BUTTON_RETURN("actionButtonReturn"), - - /** - * Document Button Shape - * - */ - @XmlEnumValue("actionButtonDocument") - ACTION_BUTTON_DOCUMENT("actionButtonDocument"), - - /** - * Sound Button Shape - * - */ - @XmlEnumValue("actionButtonSound") - ACTION_BUTTON_SOUND("actionButtonSound"), - - /** - * Movie Button Shape - * - */ - @XmlEnumValue("actionButtonMovie") - ACTION_BUTTON_MOVIE("actionButtonMovie"), - - /** - * Gear 6 Shape - * - */ - @XmlEnumValue("gear6") - GEAR_6("gear6"), - - /** - * Gear 9 Shape - * - */ - @XmlEnumValue("gear9") - GEAR_9("gear9"), - - /** - * Funnel Shape - * - */ - @XmlEnumValue("funnel") - FUNNEL("funnel"), - - /** - * Plus Math Shape - * - */ - @XmlEnumValue("mathPlus") - MATH_PLUS("mathPlus"), - - /** - * Minus Math Shape - * - */ - @XmlEnumValue("mathMinus") - MATH_MINUS("mathMinus"), - - /** - * Multiply Math Shape - * - */ - @XmlEnumValue("mathMultiply") - MATH_MULTIPLY("mathMultiply"), - - /** - * Divide Math Shape - * - */ - @XmlEnumValue("mathDivide") - MATH_DIVIDE("mathDivide"), - - /** - * Equal Math Shape - * - */ - @XmlEnumValue("mathEqual") - MATH_EQUAL("mathEqual"), - - /** - * Not Equal Math Shape - * - */ - @XmlEnumValue("mathNotEqual") - MATH_NOT_EQUAL("mathNotEqual"), - - /** - * Corner Tabs Shape - * - */ - @XmlEnumValue("cornerTabs") - CORNER_TABS("cornerTabs"), - - /** - * Square Tabs Shape - * - */ - @XmlEnumValue("squareTabs") - SQUARE_TABS("squareTabs"), - - /** - * Plaque Tabs Shape - * - */ - @XmlEnumValue("plaqueTabs") - PLAQUE_TABS("plaqueTabs"), - - /** - * Chart X Shape - * - */ - @XmlEnumValue("chartX") - CHART_X("chartX"), - - /** - * Chart Star Shape - * - */ - @XmlEnumValue("chartStar") - CHART_STAR("chartStar"), - - /** - * Chart Plus Shape - * - */ - @XmlEnumValue("chartPlus") - CHART_PLUS("chartPlus"); - private final String value; - - STShapeType(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STShapeType fromValue(String v) { - for (STShapeType c: STShapeType.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/binding/STTextShapeType.java b/trunk/src/java/org/apache/poi/sl/draw/binding/STTextShapeType.java deleted file mode 100644 index f3ed4b0cf..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/binding/STTextShapeType.java +++ /dev/null @@ -1,389 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.draw.binding; - -import javax.xml.bind.annotation.XmlEnum; -import javax.xml.bind.annotation.XmlEnumValue; -import javax.xml.bind.annotation.XmlType; - - -/** - *

    Java class for ST_TextShapeType. - * - *

    The following schema fragment specifies the expected content contained within this class. - *

    - *

    - * <simpleType name="ST_TextShapeType">
    - *   <restriction base="{http://www.w3.org/2001/XMLSchema}token">
    - *     <enumeration value="textNoShape"/>
    - *     <enumeration value="textPlain"/>
    - *     <enumeration value="textStop"/>
    - *     <enumeration value="textTriangle"/>
    - *     <enumeration value="textTriangleInverted"/>
    - *     <enumeration value="textChevron"/>
    - *     <enumeration value="textChevronInverted"/>
    - *     <enumeration value="textRingInside"/>
    - *     <enumeration value="textRingOutside"/>
    - *     <enumeration value="textArchUp"/>
    - *     <enumeration value="textArchDown"/>
    - *     <enumeration value="textCircle"/>
    - *     <enumeration value="textButton"/>
    - *     <enumeration value="textArchUpPour"/>
    - *     <enumeration value="textArchDownPour"/>
    - *     <enumeration value="textCirclePour"/>
    - *     <enumeration value="textButtonPour"/>
    - *     <enumeration value="textCurveUp"/>
    - *     <enumeration value="textCurveDown"/>
    - *     <enumeration value="textCanUp"/>
    - *     <enumeration value="textCanDown"/>
    - *     <enumeration value="textWave1"/>
    - *     <enumeration value="textWave2"/>
    - *     <enumeration value="textDoubleWave1"/>
    - *     <enumeration value="textWave4"/>
    - *     <enumeration value="textInflate"/>
    - *     <enumeration value="textDeflate"/>
    - *     <enumeration value="textInflateBottom"/>
    - *     <enumeration value="textDeflateBottom"/>
    - *     <enumeration value="textInflateTop"/>
    - *     <enumeration value="textDeflateTop"/>
    - *     <enumeration value="textDeflateInflate"/>
    - *     <enumeration value="textDeflateInflateDeflate"/>
    - *     <enumeration value="textFadeRight"/>
    - *     <enumeration value="textFadeLeft"/>
    - *     <enumeration value="textFadeUp"/>
    - *     <enumeration value="textFadeDown"/>
    - *     <enumeration value="textSlantUp"/>
    - *     <enumeration value="textSlantDown"/>
    - *     <enumeration value="textCascadeUp"/>
    - *     <enumeration value="textCascadeDown"/>
    - *   </restriction>
    - * </simpleType>
    - * 
    - * - */ -@XmlType(name = "ST_TextShapeType", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main") -@XmlEnum -public enum STTextShapeType { - - - /** - * No Text Shape - * - */ - @XmlEnumValue("textNoShape") - TEXT_NO_SHAPE("textNoShape"), - - /** - * Plain Text Shape - * - */ - @XmlEnumValue("textPlain") - TEXT_PLAIN("textPlain"), - - /** - * Stop Sign Text Shape - * - */ - @XmlEnumValue("textStop") - TEXT_STOP("textStop"), - - /** - * Triangle Text Shape - * - */ - @XmlEnumValue("textTriangle") - TEXT_TRIANGLE("textTriangle"), - - /** - * Inverted Triangle Text Shape - * - */ - @XmlEnumValue("textTriangleInverted") - TEXT_TRIANGLE_INVERTED("textTriangleInverted"), - - /** - * Chevron Text Shape - * - */ - @XmlEnumValue("textChevron") - TEXT_CHEVRON("textChevron"), - - /** - * Inverted Chevron Text Shape - * - */ - @XmlEnumValue("textChevronInverted") - TEXT_CHEVRON_INVERTED("textChevronInverted"), - - /** - * Inside Ring Text Shape - * - */ - @XmlEnumValue("textRingInside") - TEXT_RING_INSIDE("textRingInside"), - - /** - * Outside Ring Text Shape - * - */ - @XmlEnumValue("textRingOutside") - TEXT_RING_OUTSIDE("textRingOutside"), - - /** - * Upward Arch Text Shape - * - */ - @XmlEnumValue("textArchUp") - TEXT_ARCH_UP("textArchUp"), - - /** - * Downward Arch Text Shape - * - */ - @XmlEnumValue("textArchDown") - TEXT_ARCH_DOWN("textArchDown"), - - /** - * Circle Text Shape - * - */ - @XmlEnumValue("textCircle") - TEXT_CIRCLE("textCircle"), - - /** - * Button Text Shape - * - */ - @XmlEnumValue("textButton") - TEXT_BUTTON("textButton"), - - /** - * Upward Pour Arch Text Shape - * - */ - @XmlEnumValue("textArchUpPour") - TEXT_ARCH_UP_POUR("textArchUpPour"), - - /** - * Downward Pour Arch Text Shape - * - */ - @XmlEnumValue("textArchDownPour") - TEXT_ARCH_DOWN_POUR("textArchDownPour"), - - /** - * Circle Pour Text Shape - * - */ - @XmlEnumValue("textCirclePour") - TEXT_CIRCLE_POUR("textCirclePour"), - - /** - * Button Pour Text Shape - * - */ - @XmlEnumValue("textButtonPour") - TEXT_BUTTON_POUR("textButtonPour"), - - /** - * Upward Curve Text Shape - * - */ - @XmlEnumValue("textCurveUp") - TEXT_CURVE_UP("textCurveUp"), - - /** - * Downward Curve Text Shape - * - */ - @XmlEnumValue("textCurveDown") - TEXT_CURVE_DOWN("textCurveDown"), - - /** - * Upward Can Text Shape - * - */ - @XmlEnumValue("textCanUp") - TEXT_CAN_UP("textCanUp"), - - /** - * Downward Can Text Shape - * - */ - @XmlEnumValue("textCanDown") - TEXT_CAN_DOWN("textCanDown"), - - /** - * Wave 1 Text Shape - * - */ - @XmlEnumValue("textWave1") - TEXT_WAVE_1("textWave1"), - - /** - * Wave 2 Text Shape - * - */ - @XmlEnumValue("textWave2") - TEXT_WAVE_2("textWave2"), - - /** - * Double Wave 1 Text Shape - * - */ - @XmlEnumValue("textDoubleWave1") - TEXT_DOUBLE_WAVE_1("textDoubleWave1"), - - /** - * Wave 4 Text Shape - * - */ - @XmlEnumValue("textWave4") - TEXT_WAVE_4("textWave4"), - - /** - * Inflate Text Shape - * - */ - @XmlEnumValue("textInflate") - TEXT_INFLATE("textInflate"), - - /** - * Deflate Text Shape - * - */ - @XmlEnumValue("textDeflate") - TEXT_DEFLATE("textDeflate"), - - /** - * Bottom Inflate Text Shape - * - */ - @XmlEnumValue("textInflateBottom") - TEXT_INFLATE_BOTTOM("textInflateBottom"), - - /** - * Bottom Deflate Text Shape - * - */ - @XmlEnumValue("textDeflateBottom") - TEXT_DEFLATE_BOTTOM("textDeflateBottom"), - - /** - * Top Inflate Text Shape - * - */ - @XmlEnumValue("textInflateTop") - TEXT_INFLATE_TOP("textInflateTop"), - - /** - * Top Deflate Text Shape - * - */ - @XmlEnumValue("textDeflateTop") - TEXT_DEFLATE_TOP("textDeflateTop"), - - /** - * Deflate-Inflate Text Shape - * - */ - @XmlEnumValue("textDeflateInflate") - TEXT_DEFLATE_INFLATE("textDeflateInflate"), - - /** - * Deflate-Inflate-Deflate Text Shape - * - */ - @XmlEnumValue("textDeflateInflateDeflate") - TEXT_DEFLATE_INFLATE_DEFLATE("textDeflateInflateDeflate"), - - /** - * Right Fade Text Shape - * - */ - @XmlEnumValue("textFadeRight") - TEXT_FADE_RIGHT("textFadeRight"), - - /** - * Left Fade Text Shape - * - */ - @XmlEnumValue("textFadeLeft") - TEXT_FADE_LEFT("textFadeLeft"), - - /** - * Upward Fade Text Shape - * - */ - @XmlEnumValue("textFadeUp") - TEXT_FADE_UP("textFadeUp"), - - /** - * Downward Fade Text Shape - * - */ - @XmlEnumValue("textFadeDown") - TEXT_FADE_DOWN("textFadeDown"), - - /** - * Upward Slant Text Shape - * - */ - @XmlEnumValue("textSlantUp") - TEXT_SLANT_UP("textSlantUp"), - - /** - * Downward Slant Text Shape - * - */ - @XmlEnumValue("textSlantDown") - TEXT_SLANT_DOWN("textSlantDown"), - - /** - * Upward Cascade Text Shape - * - */ - @XmlEnumValue("textCascadeUp") - TEXT_CASCADE_UP("textCascadeUp"), - - /** - * Downward Cascade Text Shape - * - */ - @XmlEnumValue("textCascadeDown") - TEXT_CASCADE_DOWN("textCascadeDown"); - private final String value; - - STTextShapeType(String v) { - value = v; - } - - public String value() { - return value; - } - - public static STTextShapeType fromValue(String v) { - for (STTextShapeType c: STTextShapeType.values()) { - if (c.value.equals(v)) { - return c; - } - } - throw new IllegalArgumentException(v); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/AbsExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/AbsExpression.java deleted file mode 100644 index 0f94e14b6..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/AbsExpression.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Absolute Value Formula - * - * @author Yegor Kozlov - */ -public class AbsExpression implements Expression { - private String arg; - - AbsExpression(Matcher m){ - arg = m.group(1); - } - - public double evaluate(Context ctx){ - double val = ctx.getValue(arg); - return Math.abs(val); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/AddDivideExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/AddDivideExpression.java deleted file mode 100644 index 2a01de449..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/AddDivideExpression.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Add Divide Formula - * - * @author Yegor Kozlov - */ -public class AddDivideExpression implements Expression { - private String arg1, arg2, arg3; - - AddDivideExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return (x + y ) / z; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/AddSubtractExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/AddSubtractExpression.java deleted file mode 100644 index 5d5f1e635..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/AddSubtractExpression.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Add Subtract Formula - * - * @author Yegor Kozlov - */ -public class AddSubtractExpression implements Expression { - private String arg1, arg2, arg3; - - AddSubtractExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return (x + y ) - z; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/AdjustValue.java b/trunk/src/java/org/apache/poi/sl/draw/geom/AdjustValue.java deleted file mode 100644 index 8a2f0a456..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/AdjustValue.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import org.apache.poi.sl.draw.binding.CTGeomGuide; - -/** - * Represents a shape adjust values (see section 20.1.9.5 in the spec) - * - * @author Yegor Kozlov - */ -public class AdjustValue extends Guide { - - public AdjustValue(CTGeomGuide gd) { - super(gd.getName(), gd.getFmla()); - } - - @Override - public double evaluate(Context ctx){ - String name = getName(); - Guide adj = ctx.getAdjustValue(name); - if(adj != null) { - return adj.evaluate(ctx); - } - return super.evaluate(ctx); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/ArcTanExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/ArcTanExpression.java deleted file mode 100644 index 9044e8ad3..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/ArcTanExpression.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class ArcTanExpression implements Expression { - private String arg1, arg2; - - ArcTanExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - return Math.atan(y / x); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java deleted file mode 100644 index 18531d7ed..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Arc2D; -import java.awt.geom.Path2D; -import java.awt.geom.Point2D; - -import org.apache.poi.sl.draw.binding.CTPath2DArcTo; - -/** - * ArcTo command within a shape path in DrawingML: - * - * - * - * Where wr and wh are the height and width radiuses - * of the supposed circle being used to draw the arc. This gives the circle - * a total height of (2 * hR) and a total width of (2 * wR) - * - * stAng is the start angle and swAng is the swing angle - * - * @author Yegor Kozlov - */ -public class ArcToCommand implements PathCommand { - private String hr, wr, stAng, swAng; - - ArcToCommand(CTPath2DArcTo arc){ - hr = arc.getHR().toString(); - wr = arc.getWR().toString(); - stAng = arc.getStAng().toString(); - swAng = arc.getSwAng().toString(); - } - - public void execute(Path2D.Double path, Context ctx){ - double rx = ctx.getValue(wr); - double ry = ctx.getValue(hr); - double start = ctx.getValue(stAng) / 60000; - double extent = ctx.getValue(swAng) / 60000; - Point2D pt = path.getCurrentPoint(); - double x0 = pt.getX() - rx - rx * Math.cos(Math.toRadians(start)); - double y0 = pt.getY() - ry - ry * Math.sin(Math.toRadians(start)); - - Arc2D arc = new Arc2D.Double( - x0, - y0, - 2 * rx, 2 * ry, - -start, -extent, - Arc2D.OPEN); - path.append(arc, true); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java deleted file mode 100644 index 66b35ed58..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; - -/** - * Date: 10/25/11 - * - * @author Yegor Kozlov - */ -public class ClosePathCommand implements PathCommand { - - ClosePathCommand(){ - } - - public void execute(Path2D.Double path, Context ctx){ - path.closePath(); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/Context.java b/trunk/src/java/org/apache/poi/sl/draw/geom/Context.java deleted file mode 100644 index 8fd5147ed..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/Context.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Rectangle2D; -import java.util.HashMap; -import java.util.Map; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class Context { - final Map _ctx = new HashMap(); - final IAdjustableShape _props; - final Rectangle2D _anchor; - - public Context(CustomGeometry geom, Rectangle2D anchor, IAdjustableShape props){ - _props = props; - _anchor = anchor; - for(Guide gd : geom.adjusts) evaluate(gd); - for(Guide gd : geom.guides) evaluate(gd); - } - - public Rectangle2D getShapeAnchor(){ - return _anchor; - } - - public Guide getAdjustValue(String name){ - return _props.getAdjustValue(name); - } - - public double getValue(String key){ - if(key.matches("(\\+|-)?\\d+")){ - return Double.parseDouble(key); - } - - Formula builtIn = Formula.builtInFormulas.get(key); - if(builtIn != null){ - return builtIn.evaluate(this); - } - - if(!_ctx.containsKey(key)) { - throw new RuntimeException("undefined variable: " + key); - } - - return _ctx.get(key); - } - - public double evaluate(Formula fmla){ - double result = fmla.evaluate(this); - String key = fmla.getName(); - if(key != null) _ctx.put(key, result); - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/CosExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/CosExpression.java deleted file mode 100644 index 56373d919..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/CosExpression.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class CosExpression implements Expression { - private String arg1, arg2; - - CosExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2)/ 60000; - return x * Math.cos(Math.toRadians(y)); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java deleted file mode 100644 index 4bed9b72d..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class CosineArcTanExpression implements Expression { - private String arg1, arg2, arg3; - - CosineArcTanExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return x*Math.cos(Math.atan(z / y)); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java deleted file mode 100644 index 6c6361aed..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; - -import org.apache.poi.sl.draw.binding.CTAdjPoint2D; - -/** - * Date: 10/25/11 - * - * @author Yegor Kozlov - */ -public class CurveToCommand implements PathCommand { - private String arg1, arg2, arg3, arg4, arg5, arg6; - - CurveToCommand(CTAdjPoint2D pt1, CTAdjPoint2D pt2, CTAdjPoint2D pt3){ - arg1 = pt1.getX().toString(); - arg2 = pt1.getY().toString(); - arg3 = pt2.getX().toString(); - arg4 = pt2.getY().toString(); - arg5 = pt3.getX().toString(); - arg6 = pt3.getY().toString(); - } - - public void execute(Path2D.Double path, Context ctx){ - double x1 = ctx.getValue(arg1); - double y1 = ctx.getValue(arg2); - double x2 = ctx.getValue(arg3); - double y2 = ctx.getValue(arg4); - double x3 = ctx.getValue(arg5); - double y3 = ctx.getValue(arg6); - path.curveTo(x1, y1, x2, y2, x3, y3); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/CustomGeometry.java b/trunk/src/java/org/apache/poi/sl/draw/geom/CustomGeometry.java deleted file mode 100644 index ce1b26c49..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/CustomGeometry.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.*; - -import org.apache.poi.sl.draw.binding.*; - -/** - * Definition of a custom geometric shape - * - * @author Yegor Kozlov - */ -public class CustomGeometry implements Iterable{ - List adjusts = new ArrayList(); - List guides = new ArrayList(); - List paths = new ArrayList(); - Path textBounds; - - public CustomGeometry(CTCustomGeometry2D geom) { - CTGeomGuideList avLst = geom.getAvLst(); - if(avLst != null) { - for(CTGeomGuide gd : avLst.getGd()){ - adjusts.add(new AdjustValue(gd)); - } - } - - CTGeomGuideList gdLst = geom.getGdLst(); - if(gdLst != null) { - for(CTGeomGuide gd : gdLst.getGd()){ - guides.add(new Guide(gd)); - } - } - - CTPath2DList pathLst = geom.getPathLst(); - if(pathLst != null) { - for(CTPath2D spPath : pathLst.getPath()){ - paths.add(new Path(spPath)); - } - } - - CTGeomRect rect = geom.getRect(); - if(rect != null) { - textBounds = new Path(); - textBounds.addCommand( - new MoveToCommand(rect.getL().toString(), rect.getT().toString())); - textBounds.addCommand( - new LineToCommand(rect.getR().toString(), rect.getT().toString())); - textBounds.addCommand( - new LineToCommand(rect.getR().toString(), rect.getB().toString())); - textBounds.addCommand( - new LineToCommand(rect.getL().toString(), rect.getB().toString())); - textBounds.addCommand( - new ClosePathCommand()); - } - } - - public Iterator iterator() { - return paths.iterator(); - } - - public Path getTextBounds(){ - return textBounds; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/Expression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/Expression.java deleted file mode 100644 index 2403c85a0..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/Expression.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public interface Expression { - - double evaluate(Context ctx); - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/ExpressionParser.java b/trunk/src/java/org/apache/poi/sl/draw/geom/ExpressionParser.java deleted file mode 100644 index 61ab98b8a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/ExpressionParser.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.lang.reflect.Constructor; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A simple regexp-based parser of shape guide formulas in DrawingML - */ -public class ExpressionParser { - private static final Map impls = - new HashMap(); - - private static class ExpressionEntry { - final Pattern regex; - final Constructor con; - ExpressionEntry(String regex, Class cls) - throws SecurityException, NoSuchMethodException { - this.regex = Pattern.compile(regex); - this.con = cls.getDeclaredConstructor(Matcher.class); - impls.put(op(regex), this); - } - } - - static { - try { - new ExpressionEntry("\\*/ +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", MultiplyDivideExpression.class); - new ExpressionEntry("\\+- +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)( 0)?", AddSubtractExpression.class); - new ExpressionEntry("\\+/ +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", AddDivideExpression.class); - new ExpressionEntry("\\?: +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", IfElseExpression.class); - new ExpressionEntry("val +([\\-\\w]+)", LiteralValueExpression.class); - new ExpressionEntry("abs +([\\-\\w]+)", AbsExpression.class); - new ExpressionEntry("sqrt +([\\-\\w]+)", SqrtExpression.class); - new ExpressionEntry("max +([\\-\\w]+) +([\\-\\w]+)", MaxExpression.class); - new ExpressionEntry("min +([\\-\\w]+) +([\\-\\w]+)", MinExpression.class); - new ExpressionEntry("at2 +([\\-\\w]+) +([\\-\\w]+)", ArcTanExpression.class); - new ExpressionEntry("sin +([\\-\\w]+) +([\\-\\w]+)", SinExpression.class); - new ExpressionEntry("cos +([\\-\\w]+) +([\\-\\w]+)", CosExpression.class); - new ExpressionEntry("tan +([\\-\\w]+) +([\\-\\w]+)", TanExpression.class); - new ExpressionEntry("cat2 +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", CosineArcTanExpression.class); - new ExpressionEntry("sat2 +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", SinArcTanExpression.class); - new ExpressionEntry("pin +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", PinExpression.class); - new ExpressionEntry("mod +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", ModExpression.class); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static String op(String str) { - return (str == null || !str.contains(" ")) - ? "" : str.substring(0, str.indexOf(" ")).replace("\\", ""); - } - - public static Expression parse(String str) { - ExpressionEntry ee = impls.get(op(str)); - Matcher m = (ee == null) ? null : ee.regex.matcher(str); - if (m == null || !m.matches()) { - throw new RuntimeException("Unsupported formula: " + str); - } - - try { - return ee.con.newInstance(m); - } catch (Exception e) { - throw new RuntimeException("Unsupported formula: " + str, e); - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/Formula.java b/trunk/src/java/org/apache/poi/sl/draw/geom/Formula.java deleted file mode 100644 index 47453475a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/Formula.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Rectangle2D; -import java.util.HashMap; -import java.util.Map; - -/** - * A guide formula in DrawingML. - * This is a base class for adjust values, geometric guides and bilt-in guides - * - * @author Yegor Kozlov - */ -public abstract class Formula { - - String getName(){ - return null; - } - - abstract double evaluate(Context ctx); - - static Map builtInFormulas = new HashMap(); - static { - // 3 x 360 / 4 = 270 - builtInFormulas.put("3cd4", new Formula(){ - @Override - double evaluate(Context ctx){ - return 270 * 60000; - } - - }); - - // 3 x 360 / 8 = 135 - builtInFormulas.put("3cd8", new Formula(){ - @Override - double evaluate(Context ctx){ - return 135 * 60000; - } - - }); - - // 5 x 360 / 8 = 225 - builtInFormulas.put("5cd8", new Formula(){ - @Override - double evaluate(Context ctx){ - return 270 * 60000; - } - - }); - - // 7 x 360 / 8 = 315 - builtInFormulas.put("7cd8", new Formula(){ - @Override - double evaluate(Context ctx){ - return 270 * 60000; - } - - }); - - // bottom - builtInFormulas.put("b", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getY() + anchor.getHeight(); - } - - }); - - // 360 / 2 = 180 - builtInFormulas.put("cd2", new Formula(){ - @Override - double evaluate(Context ctx){ - return 180 * 60000; - } - - }); - - // 360 / 4 = 90 - builtInFormulas.put("cd4", new Formula(){ - @Override - double evaluate(Context ctx){ - return 90 * 60000; - } - - }); - - // 360 / 8 = 45 - builtInFormulas.put("cd8", new Formula(){ - @Override - double evaluate(Context ctx){ - return 45 * 60000; - } - - }); - - // horizontal center - builtInFormulas.put("hc", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getX() + anchor.getWidth()/2; - } - - }); - - // height - builtInFormulas.put("h", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight(); - } - - }); - - // height / 2 - builtInFormulas.put("hd2", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight()/2; - } - - }); - - // height / 3 - builtInFormulas.put("hd3", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight()/3; - } - - }); - - // height / 4 - builtInFormulas.put("hd4", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight()/4; - } - - }); - - // height / 5 - builtInFormulas.put("hd5", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight()/5; - } - - }); - - // height / 6 - builtInFormulas.put("hd6", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight()/6; - } - - }); - - // height / 8 - builtInFormulas.put("hd8", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getHeight()/8; - } - - }); - - // left - builtInFormulas.put("l", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getX(); - } - - }); - - // long side - builtInFormulas.put("ls", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return Math.max(anchor.getWidth(), anchor.getHeight()); - } - - }); - - // right - builtInFormulas.put("r", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getX() + anchor.getWidth(); - } - - }); - - // short side - builtInFormulas.put("ss", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return Math.min(anchor.getWidth(), anchor.getHeight()); - } - - }); - - // short side / 2 - builtInFormulas.put("ssd2", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - double ss = Math.min(anchor.getWidth(), anchor.getHeight()); - return ss / 2; - } - }); - - // short side / 4 - builtInFormulas.put("ssd4", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - double ss = Math.min(anchor.getWidth(), anchor.getHeight()); - return ss / 4; - } - }); - - // short side / 6 - builtInFormulas.put("ssd6", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - double ss = Math.min(anchor.getWidth(), anchor.getHeight()); - return ss / 6; - } - }); - - // short side / 8 - builtInFormulas.put("ssd8", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - double ss = Math.min(anchor.getWidth(), anchor.getHeight()); - return ss / 8; - } - }); - - // short side / 16 - builtInFormulas.put("ssd16", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - double ss = Math.min(anchor.getWidth(), anchor.getHeight()); - return ss / 16; - } - }); - - // short side / 32 - builtInFormulas.put("ssd32", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - double ss = Math.min(anchor.getWidth(), anchor.getHeight()); - return ss / 32; - } - }); - - // top - builtInFormulas.put("t", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getY(); - } - }); - - // vertical center - builtInFormulas.put("vc", new Formula(){ - @Override - double evaluate(Context ctx){ - Rectangle2D anchor = ctx.getShapeAnchor(); - return anchor.getY() + anchor.getHeight()/2; - } - }); - - // width - builtInFormulas.put("w", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth(); - } - }); - - // width / 2 - builtInFormulas.put("wd2", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/2; - } - }); - - // width / 3 - builtInFormulas.put("wd3", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/3; - } - }); - - // width / 4 - builtInFormulas.put("wd4", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/4; - } - }); - - // width / 5 - builtInFormulas.put("wd5", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/5; - } - }); - - // width / 6 - builtInFormulas.put("wd6", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/6; - } - }); - - // width / 8 - builtInFormulas.put("wd8", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/8; - } - }); - - // width / 10 - builtInFormulas.put("wd10", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/10; - } - }); - - // width / 32 - builtInFormulas.put("wd32", new Formula(){ - @Override - double evaluate(Context ctx){ - return ctx.getShapeAnchor().getWidth()/32; - } - }); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/Guide.java b/trunk/src/java/org/apache/poi/sl/draw/geom/Guide.java deleted file mode 100644 index f14213244..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/Guide.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import org.apache.poi.sl.draw.binding.CTGeomGuide; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class Guide extends Formula { - private String name, fmla; - private Expression expr; - - public Guide(CTGeomGuide gd) { - this(gd.getName(), gd.getFmla()); - } - - public Guide(String nm, String fm){ - name = nm; - fmla = fm; - expr = ExpressionParser.parse(fm); - } - - - String getName(){ - return name; - } - - String getFormula(){ - return fmla; - } - - @Override - public double evaluate(Context ctx){ - return expr.evaluate(ctx); - } - - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/IAdjustableShape.java b/trunk/src/java/org/apache/poi/sl/draw/geom/IAdjustableShape.java deleted file mode 100644 index 920acb82d..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/IAdjustableShape.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - - -/** - * A bridge to the consumer application. - * - * To get a shape geometry one needs to pass shape bounds and adjust values. - * - * @author Yegor Kozlov - */ -public interface IAdjustableShape { - /** - * - * @param name name of a adjust value, e.g. adj1 - * @return adjust guide defined in the shape or null - */ - Guide getAdjustValue(String name); -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/IfElseExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/IfElseExpression.java deleted file mode 100644 index 443115a78..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/IfElseExpression.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * If Else Formula: - *

    - * Arguments: 3 (fmla="?: x y z") - * Usage: "?: x y z" = if (x > 0), then y = value of this guide, - * else z = value of this guide - *

    - * - * @author Yegor Kozlov - */ -public class IfElseExpression implements Expression { - private String arg1, arg2, arg3; - - IfElseExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return x > 0 ? y : z; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java deleted file mode 100644 index 7f6e13c54..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; - -import org.apache.poi.sl.draw.binding.CTAdjPoint2D; - -/** - * Date: 10/25/11 - * - * @author Yegor Kozlov - */ -public class LineToCommand implements PathCommand { - private String arg1, arg2; - - LineToCommand(CTAdjPoint2D pt){ - arg1 = pt.getX().toString(); - arg2 = pt.getY().toString(); - } - - LineToCommand(String s1, String s2){ - arg1 = s1; - arg2 = s2; - } - - public void execute(Path2D.Double path, Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - path.lineTo(x, y); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/LiteralValueExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/LiteralValueExpression.java deleted file mode 100644 index ab3abc7fd..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/LiteralValueExpression.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class LiteralValueExpression implements Expression { - private String arg; - - LiteralValueExpression(Matcher m){ - arg = m.group(1); - } - - public double evaluate(Context ctx){ - return ctx.getValue(arg); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/MaxExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/MaxExpression.java deleted file mode 100644 index 88a9c6047..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/MaxExpression.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Maximum Value Formula - * - * @author Yegor Kozlov - */ -public class MaxExpression implements Expression { - private String arg1, arg2; - - MaxExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - return Math.max(x, y); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/MinExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/MinExpression.java deleted file mode 100644 index 8c1864c5a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/MinExpression.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Minimum Value Formula - * - * @author Yegor Kozlov - */ -public class MinExpression implements Expression { - private String arg1, arg2; - - MinExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - return Math.min(x, y); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/ModExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/ModExpression.java deleted file mode 100644 index ff20fc20f..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/ModExpression.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Modulo Formula: - *

    - * Arguments: 3 (fmla="mod x y z") - * Usage: "mod x y z" = sqrt(x^2 + b^2 + c^2) = value of this guide - *

    - * - * @author Yegor Kozlov - */ -public class ModExpression implements Expression { - private String arg1, arg2, arg3; - - ModExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return Math.sqrt(x*x + y*y + z*z); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java deleted file mode 100644 index 59c7a8adf..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; - -import org.apache.poi.sl.draw.binding.CTAdjPoint2D; - -/** - * Date: 10/25/11 - * - * @author Yegor Kozlov - */ -public class MoveToCommand implements PathCommand { - private String arg1, arg2; - - MoveToCommand(CTAdjPoint2D pt){ - arg1 = pt.getX().toString(); - arg2 = pt.getY().toString(); - } - - MoveToCommand(String s1, String s2){ - arg1 = s1; - arg2 = s2; - } - - public void execute(Path2D.Double path, Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - path.moveTo(x, y); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java deleted file mode 100644 index 5af0ff12c..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Multiply Divide Formula - * - * @author Yegor Kozlov - */ -public class MultiplyDivideExpression implements Expression { - private String arg1, arg2, arg3; - - MultiplyDivideExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return (x * y ) / z; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/Outline.java b/trunk/src/java/org/apache/poi/sl/draw/geom/Outline.java deleted file mode 100644 index b4ffc4257..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/Outline.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.Shape; - -/** -* Date: 11/6/11 -* -* @author Yegor Kozlov -*/ -public class Outline { - private Shape shape; - private Path path; - - public Outline(Shape shape, Path path){ - this.shape = shape; - this.path = path; - } - - public Path getPath(){ - return path; - } - - public Shape getOutline(){ - return shape; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java b/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java deleted file mode 100644 index 78590faf0..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.sl.draw.binding.CTAdjPoint2D; -import org.apache.poi.sl.draw.binding.CTPath2D; -import org.apache.poi.sl.draw.binding.CTPath2DArcTo; -import org.apache.poi.sl.draw.binding.CTPath2DClose; -import org.apache.poi.sl.draw.binding.CTPath2DCubicBezierTo; -import org.apache.poi.sl.draw.binding.CTPath2DLineTo; -import org.apache.poi.sl.draw.binding.CTPath2DMoveTo; -import org.apache.poi.sl.draw.binding.CTPath2DQuadBezierTo; -import org.apache.poi.sl.draw.binding.STPathFillMode; - -/** - * Specifies a creation path consisting of a series of moves, lines and curves - * that when combined forms a geometric shape - * - * @author Yegor Kozlov - */ -public class Path { - private final List commands; - boolean _fill, _stroke; - long _w, _h; - - public Path(){ - this(true, true); - } - - public Path(boolean fill, boolean stroke){ - commands = new ArrayList(); - _w = -1; - _h = -1; - _fill = fill; - _stroke = stroke; - } - - public Path(CTPath2D spPath){ - _fill = spPath.getFill() != STPathFillMode.NONE; - _stroke = spPath.isStroke(); - _w = spPath.isSetW() ? spPath.getW() : -1; - _h = spPath.isSetH() ? spPath.getH() : -1; - - commands = new ArrayList(); - - for(Object ch : spPath.getCloseOrMoveToOrLnTo()){ - if(ch instanceof CTPath2DMoveTo){ - CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt(); - commands.add(new MoveToCommand(pt)); - } else if (ch instanceof CTPath2DLineTo){ - CTAdjPoint2D pt = ((CTPath2DLineTo)ch).getPt(); - commands.add(new LineToCommand(pt)); - } else if (ch instanceof CTPath2DArcTo){ - CTPath2DArcTo arc = (CTPath2DArcTo)ch; - commands.add(new ArcToCommand(arc)); - } else if (ch instanceof CTPath2DQuadBezierTo){ - CTPath2DQuadBezierTo bez = ((CTPath2DQuadBezierTo)ch); - CTAdjPoint2D pt1 = bez.getPt().get(0); - CTAdjPoint2D pt2 = bez.getPt().get(1); - commands.add(new QuadToCommand(pt1, pt2)); - } else if (ch instanceof CTPath2DCubicBezierTo){ - CTPath2DCubicBezierTo bez = ((CTPath2DCubicBezierTo)ch); - CTAdjPoint2D pt1 = bez.getPt().get(0); - CTAdjPoint2D pt2 = bez.getPt().get(1); - CTAdjPoint2D pt3 = bez.getPt().get(2); - commands.add(new CurveToCommand(pt1, pt2, pt3)); - } else if (ch instanceof CTPath2DClose){ - commands.add(new ClosePathCommand()); - } else { - throw new IllegalStateException("Unsupported path segment: " + ch); - } - } - } - - public void addCommand(PathCommand cmd){ - commands.add(cmd); - } - - /** - * Convert the internal represenation to java.awt.geom.Path2D - */ - public Path2D.Double getPath(Context ctx) { - Path2D.Double path = new Path2D.Double(); - for(PathCommand cmd : commands) - cmd.execute(path, ctx); - return path; - } - - public boolean isStroked(){ - return _stroke; - } - - public boolean isFilled(){ - return _fill; - } - - public long getW(){ - return _w; - } - - public long getH(){ - return _h; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java deleted file mode 100644 index 41fa21a54..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; - -/** - * A path command in DrawingML. One of: - * - * - arcTo - * - moveTo - * - lineTo - * - cubicBezTo - * - quadBezTo - * - close - * - * - * @author Yegor Kozlov - */ -public interface PathCommand { - /** - * Execute the command an append a segment to the specified path - * - * @param path the path to append the result to - * @param ctx the context to lookup variables - */ - void execute(Path2D.Double path, Context ctx); -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/PinExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/PinExpression.java deleted file mode 100644 index ee0d4e510..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/PinExpression.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Pin To Formula: - * - * - *

    - * Usage: "pin x y z" = if (y < x), then x = value of this guide - * else if (y > z), then z = value of this guide - * else y = value of this guide - *

    - * - * @author Yegor Kozlov - */ -public class PinExpression implements Expression { - private String arg1, arg2, arg3; - - PinExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - if(y < x) return x; - else if (y > z) return z; - else return y; - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java b/trunk/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java deleted file mode 100644 index ad2553fbe..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.io.InputStream; -import java.util.LinkedHashMap; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import javax.xml.stream.EventFilter; -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; - -import org.apache.poi.sl.draw.binding.CTCustomGeometry2D; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * - */ -public class PresetGeometries extends LinkedHashMap { - private final static POILogger LOG = POILogFactory.getLogger(PresetGeometries.class); - protected final static String BINDING_PACKAGE = "org.apache.poi.sl.draw.binding"; - - protected static PresetGeometries _inst; - - protected PresetGeometries(){} - - @SuppressWarnings("unused") - public void init(InputStream is) throws XMLStreamException, JAXBException { - // StAX: - EventFilter startElementFilter = new EventFilter() { - @Override - public boolean accept(XMLEvent event) { - return event.isStartElement(); - } - }; - - XMLInputFactory staxFactory = XMLInputFactory.newFactory(); - XMLEventReader staxReader = staxFactory.createXMLEventReader(is); - XMLEventReader staxFiltRd = staxFactory.createFilteredReader(staxReader, startElementFilter); - // ignore StartElement: - /* XMLEvent evDoc = */ staxFiltRd.nextEvent(); - // JAXB: - JAXBContext jaxbContext = JAXBContext.newInstance(BINDING_PACKAGE); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - - long cntElem = 0; - while (staxFiltRd.peek() != null) { - StartElement evRoot = (StartElement)staxFiltRd.peek(); - String name = evRoot.getName().getLocalPart(); - JAXBElement el = unmarshaller.unmarshal(staxReader, CTCustomGeometry2D.class); - CTCustomGeometry2D cus = el.getValue(); - cntElem++; - - if(containsKey(name)) { - LOG.log(POILogger.WARN, "Duplicate definition of " + name); - } - put(name, new CustomGeometry(cus)); - } - } - - /** - * Convert a single CustomGeometry object, i.e. from xmlbeans - */ - public static CustomGeometry convertCustomGeometry(XMLStreamReader staxReader) { - try { - JAXBContext jaxbContext = JAXBContext.newInstance(BINDING_PACKAGE); - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - JAXBElement el = unmarshaller.unmarshal(staxReader, CTCustomGeometry2D.class); - return new CustomGeometry(el.getValue()); - } catch (JAXBException e) { - LOG.log(POILogger.ERROR, "Unable to parse single custom geometry", e); - return null; - } - } - - public static synchronized PresetGeometries getInstance(){ - if(_inst == null) { - // use a local object first to not assign a partly constructed object - // in case of failure - PresetGeometries lInst = new PresetGeometries(); - try { - InputStream is = PresetGeometries.class. - getResourceAsStream("presetShapeDefinitions.xml"); - try { - lInst.init(is); - } finally { - is.close(); - } - } catch (Exception e){ - throw new RuntimeException(e); - } - _inst = lInst; - } - - return _inst; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java b/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java deleted file mode 100644 index d5e848b5a..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.awt.geom.Path2D; - -import org.apache.poi.sl.draw.binding.CTAdjPoint2D; - -/** - * Date: 10/25/11 - * - * @author Yegor Kozlov - */ -public class QuadToCommand implements PathCommand { - private String arg1, arg2, arg3, arg4; - - QuadToCommand(CTAdjPoint2D pt1, CTAdjPoint2D pt2){ - arg1 = pt1.getX().toString(); - arg2 = pt1.getY().toString(); - arg3 = pt2.getX().toString(); - arg4 = pt2.getY().toString(); - } - - public void execute(Path2D.Double path, Context ctx){ - double x1 = ctx.getValue(arg1); - double y1 = ctx.getValue(arg2); - double x2 = ctx.getValue(arg3); - double y2 = ctx.getValue(arg4); - path.quadTo(x1, y1, x2, y2); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/SinArcTanExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/SinArcTanExpression.java deleted file mode 100644 index e14acb9e6..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/SinArcTanExpression.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Sine ArcTan Formula: - * - * - *

    - * Arguments: 3 (fmla="sat2 x y z") - * Usage: "sat2 x y z" = (x*sin(arctan(z / y))) = value of this guide - *

    - * - * @author Yegor Kozlov - */ -public class SinArcTanExpression implements Expression { - private String arg1, arg2, arg3; - - SinArcTanExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - arg3 = m.group(3); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - double z = ctx.getValue(arg3); - return x*Math.sin(Math.atan(z / y)); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/SinExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/SinExpression.java deleted file mode 100644 index ca0c110ce..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/SinExpression.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Sine Formula: - * - * - *

    - * Arguments: 2 (fmla="sin x y") - * Usage: "sin x y" = (x * sin( y )) = value of this guide - *

    - * - * @author Yegor Kozlov - */ -public class SinExpression implements Expression { - private String arg1, arg2; - - SinExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2) / 60000; - return x * Math.sin(Math.toRadians(y)); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/SqrtExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/SqrtExpression.java deleted file mode 100644 index 5cdd67cc5..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/SqrtExpression.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Square Root Formula: - * - * - *

    - * Arguments: 1 (fmla="sqrt x") - * Usage: "sqrt x" = sqrt(x) = value of this guide - *

    - * @author Yegor Kozlov - */ -public class SqrtExpression implements Expression { - private String arg; - - SqrtExpression(Matcher m){ - arg =m.group(1); - } - - public double evaluate(Context ctx){ - double val = ctx.getValue(arg); - return Math.sqrt(val); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/draw/geom/TanExpression.java b/trunk/src/java/org/apache/poi/sl/draw/geom/TanExpression.java deleted file mode 100644 index 7eebdcedf..000000000 --- a/trunk/src/java/org/apache/poi/sl/draw/geom/TanExpression.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.draw.geom; - -import java.util.regex.Matcher; - -/** - * Tangent Formula: - * - * - * - *

    - * Arguments: 2 (fmla="tan x y") - * Usage: "tan x y" = (x * tan( y )) = value of this guide - *

    - * - * @author Yegor Kozlov - */ -public class TanExpression implements Expression { - private String arg1, arg2; - - TanExpression(Matcher m){ - arg1 = m.group(1); - arg2 = m.group(2); - } - - public double evaluate(Context ctx){ - double x = ctx.getValue(arg1); - double y = ctx.getValue(arg2); - return x * Math.tan(Math.toRadians(y / 60000)); - } - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/AutoNumberingScheme.java b/trunk/src/java/org/apache/poi/sl/usermodel/AutoNumberingScheme.java deleted file mode 100644 index 1ba4f13e2..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/AutoNumberingScheme.java +++ /dev/null @@ -1,289 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.util.Locale; - -public enum AutoNumberingScheme { - /** Lowercase alphabetic character enclosed in parentheses. Example: (a), (b), (c), ... */ - alphaLcParenBoth(0x0008, 1), - /** Uppercase alphabetic character enclosed in parentheses. Example: (A), (B), (C), ... */ - alphaUcParenBoth(0x000A, 2), - /** Lowercase alphabetic character followed by a closing parenthesis. Example: a), b), c), ... */ - alphaLcParenRight(0x0009, 3), - /** Uppercase alphabetic character followed by a closing parenthesis. Example: A), B), C), ... */ - alphaUcParenRight(0x000B, 4), - /** Lowercase Latin character followed by a period. Example: a., b., c., ... */ - alphaLcPeriod(0x0000, 5), - /** Uppercase Latin character followed by a period. Example: A., B., C., ... */ - alphaUcPeriod(0x0001, 6), - /** Arabic numeral enclosed in parentheses. Example: (1), (2), (3), ... */ - arabicParenBoth(0x000C, 7), - /** Arabic numeral followed by a closing parenthesis. Example: 1), 2), 3), ... */ - arabicParenRight(0x0002, 8), - /** Arabic numeral followed by a period. Example: 1., 2., 3., ... */ - arabicPeriod(0x0003, 9), - /** Arabic numeral. Example: 1, 2, 3, ... */ - arabicPlain(0x000D, 10), - /** Lowercase Roman numeral enclosed in parentheses. Example: (i), (ii), (iii), ... */ - romanLcParenBoth(0x0004, 11), - /** Uppercase Roman numeral enclosed in parentheses. Example: (I), (II), (III), ... */ - romanUcParenBoth(0x000E, 12), - /** Lowercase Roman numeral followed by a closing parenthesis. Example: i), ii), iii), ... */ - romanLcParenRight(0x0005, 13), - /** Uppercase Roman numeral followed by a closing parenthesis. Example: I), II), III), .... */ - romanUcParenRight(0x000F, 14), - /** Lowercase Roman numeral followed by a period. Example: i., ii., iii., ... */ - romanLcPeriod(0x0006, 15), - /** Uppercase Roman numeral followed by a period. Example: I., II., III., ... */ - romanUcPeriod(0x0007, 16), - /** Double byte circle numbers. */ - circleNumDbPlain(0x0012, 17), - /** Wingdings black circle numbers. */ - circleNumWdBlackPlain(0x0014, 18), - /** Wingdings white circle numbers. */ - circleNumWdWhitePlain(0x0013, 19), - /** Double-byte Arabic numbers with double-byte period. */ - arabicDbPeriod(0x001D, 20), - /** Double-byte Arabic numbers. */ - arabicDbPlain(0x001C, 21), - /** Simplified Chinese with single-byte period. */ - ea1ChsPeriod(0x0011, 22), - /** Simplified Chinese. */ - ea1ChsPlain(0x0010, 23), - /** Traditional Chinese with single-byte period. */ - ea1ChtPeriod(0x0015, 24), - /** Traditional Chinese. */ - ea1ChtPlain(0x0014, 25), - /** Japanese with double-byte period. */ - ea1JpnChsDbPeriod(0x0026, 26), - /** Japanese/Korean. */ - ea1JpnKorPlain(0x001A, 27), - /** Japanese/Korean with single-byte period. */ - ea1JpnKorPeriod(0x001B, 28), - /** Bidi Arabic 1 (AraAlpha) with ANSI minus symbol. */ - arabic1Minus(0x0017, 29), - /** Bidi Arabic 2 (AraAbjad) with ANSI minus symbol. */ - arabic2Minus(0x0018, 30), - /** Bidi Hebrew 2 with ANSI minus symbol. */ - hebrew2Minus(0x0019, 31), - /** Thai alphabetic character followed by a period. */ - thaiAlphaPeriod(0x001E, 32), - /** Thai alphabetic character followed by a closing parenthesis. */ - thaiAlphaParenRight(0x001F, 33), - /** Thai alphabetic character enclosed by parentheses. */ - thaiAlphaParenBoth(0x0020, 34), - /** Thai numeral followed by a period. */ - thaiNumPeriod(0x0021, 35), - /** Thai numeral followed by a closing parenthesis. */ - thaiNumParenRight(0x0022, 36), - /** Thai numeral enclosed in parentheses. */ - thaiNumParenBoth(0x0023, 37), - /** Hindi alphabetic character followed by a period. */ - hindiAlphaPeriod(0x0024, 38), - /** Hindi numeric character followed by a period. */ - hindiNumPeriod(0x0025, 39), - /** Hindi numeric character followed by a closing parenthesis. */ - hindiNumParenRight(0x0027, 40), - /** Hindi alphabetic character followed by a period. */ - hindiAlpha1Period(0x0027, 41); - - public final int nativeId, ooxmlId; - - AutoNumberingScheme(int nativeId, int ooxmlId) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - } - - public static AutoNumberingScheme forNativeID(int nativeId) { - for (AutoNumberingScheme ans : values()) { - if (ans.nativeId == nativeId) return ans; - } - return null; - } - - public static AutoNumberingScheme forOoxmlID(int ooxmlId) { - for (AutoNumberingScheme ans : values()) { - if (ans.ooxmlId == ooxmlId) return ans; - } - return null; - } - - public String getDescription() { - switch (this) { - case alphaLcPeriod : return "Lowercase Latin character followed by a period. Example: a., b., c., ..."; - case alphaUcPeriod : return "Uppercase Latin character followed by a period. Example: A., B., C., ..."; - case arabicParenRight : return "Arabic numeral followed by a closing parenthesis. Example: 1), 2), 3), ..."; - case arabicPeriod : return "Arabic numeral followed by a period. Example: 1., 2., 3., ..."; - case romanLcParenBoth : return "Lowercase Roman numeral enclosed in parentheses. Example: (i), (ii), (iii), ..."; - case romanLcParenRight : return "Lowercase Roman numeral followed by a closing parenthesis. Example: i), ii), iii), ..."; - case romanLcPeriod : return "Lowercase Roman numeral followed by a period. Example: i., ii., iii., ..."; - case romanUcPeriod : return "Uppercase Roman numeral followed by a period. Example: I., II., III., ..."; - case alphaLcParenBoth : return "Lowercase alphabetic character enclosed in parentheses. Example: (a), (b), (c), ..."; - case alphaLcParenRight : return "Lowercase alphabetic character followed by a closing parenthesis. Example: a), b), c), ..."; - case alphaUcParenBoth : return "Uppercase alphabetic character enclosed in parentheses. Example: (A), (B), (C), ..."; - case alphaUcParenRight : return "Uppercase alphabetic character followed by a closing parenthesis. Example: A), B), C), ..."; - case arabicParenBoth : return "Arabic numeral enclosed in parentheses. Example: (1), (2), (3), ..."; - case arabicPlain : return "Arabic numeral. Example: 1, 2, 3, ..."; - case romanUcParenBoth : return "Uppercase Roman numeral enclosed in parentheses. Example: (I), (II), (III), ..."; - case romanUcParenRight : return "Uppercase Roman numeral followed by a closing parenthesis. Example: I), II), III), ..."; - case ea1ChsPlain : return "Simplified Chinese."; - case ea1ChsPeriod : return "Simplified Chinese with single-byte period."; - case circleNumDbPlain : return "Double byte circle numbers."; - case circleNumWdWhitePlain : return "Wingdings white circle numbers."; - case circleNumWdBlackPlain : return "Wingdings black circle numbers."; - case ea1ChtPlain : return "Traditional Chinese."; - case ea1ChtPeriod : return "Traditional Chinese with single-byte period."; - case arabic1Minus : return "Bidi Arabic 1 (AraAlpha) with ANSI minus symbol."; - case arabic2Minus : return "Bidi Arabic 2 (AraAbjad) with ANSI minus symbol."; - case hebrew2Minus : return "Bidi Hebrew 2 with ANSI minus symbol."; - case ea1JpnKorPlain : return "Japanese/Korean."; - case ea1JpnKorPeriod : return "Japanese/Korean with single-byte period."; - case arabicDbPlain : return "Double-byte Arabic numbers."; - case arabicDbPeriod : return "Double-byte Arabic numbers with double-byte period."; - case thaiAlphaPeriod : return "Thai alphabetic character followed by a period."; - case thaiAlphaParenRight : return "Thai alphabetic character followed by a closing parenthesis."; - case thaiAlphaParenBoth : return "Thai alphabetic character enclosed by parentheses."; - case thaiNumPeriod : return "Thai numeral followed by a period."; - case thaiNumParenRight : return "Thai numeral followed by a closing parenthesis."; - case thaiNumParenBoth : return "Thai numeral enclosed in parentheses."; - case hindiAlphaPeriod : return "Hindi alphabetic character followed by a period."; - case hindiNumPeriod : return "Hindi numeric character followed by a period."; - case ea1JpnChsDbPeriod : return "Japanese with double-byte period."; - case hindiNumParenRight : return "Hindi numeric character followed by a closing parenthesis."; - case hindiAlpha1Period : return "Hindi alphabetic character followed by a period."; - default : return "Unknown Numbered Scheme"; - } - } - - public String format(int value) { - String index = formatIndex(value); - String cased = formatCase(index); - String seperated = formatSeperator(cased); - return seperated; - } - - private String formatSeperator(String cased) { - String name = name().toLowerCase(Locale.ROOT); - if (name.contains("plain")) return cased; - if (name.contains("parenright")) return cased+")"; - if (name.contains("parenboth")) return "("+cased+")"; - if (name.contains("period")) return cased+"."; - if (name.contains("minus")) return cased+"-"; // ??? - return cased; - } - - private String formatCase(String index) { - String name = name().toLowerCase(Locale.ROOT); - if (name.contains("lc")) return index.toLowerCase(Locale.ROOT); - if (name.contains("uc")) return index.toUpperCase(Locale.ROOT); - return index; - } - - private static final String ARABIC_LIST = "0123456789"; - private static final String ALPHA_LIST = "abcdefghijklmnopqrstuvwxyz"; - private static final String WINGDINGS_WHITE_LIST = - "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089"; - private static final String WINGDINGS_BLACK_LIST = - "\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094"; - private static final String CIRCLE_DB_LIST = - "\u2776\u2777\u2778\u2779\u277A\u277B\u277C\u277D\u277E"; - - private String formatIndex(int value) { - String name = name().toLowerCase(Locale.ROOT); - if (name.startsWith("roman")) { - return formatRomanIndex(value); - } else if (name.startsWith("arabic") && !name.contains("db")) { - return getIndexedList(value, ARABIC_LIST, false); - } else if (name.startsWith("alpha")) { - return getIndexedList(value, ALPHA_LIST, true); - } else if (name.contains("WdWhite")) { - return (value == 10) ? "\u008A" - : getIndexedList(value, WINGDINGS_WHITE_LIST, false); - } else if (name.contains("WdBlack")) { - return (value == 10) ? "\u0095" - : getIndexedList(value, WINGDINGS_BLACK_LIST, false); - } else if (name.contains("NumDb")) { - return (value == 10) ? "\u277F" - : getIndexedList(value, CIRCLE_DB_LIST, true); - } else { - return "?"; - } - } - - private static String getIndexedList(int val, String list, boolean oneBased) { - StringBuilder sb = new StringBuilder(); - addIndexedChar(val, list, oneBased, sb); - return sb.toString(); - } - - private static void addIndexedChar(int val, String list, boolean oneBased, StringBuilder sb) { - if (oneBased) val -= 1; - final int len = list.length(); - if (val >= len) { - addIndexedChar(val/len, list, oneBased, sb); - } - sb.append(list.charAt(val%len)); - } - - - private String formatRomanIndex(int value) { - //M (1000), CM (900), D (500), CD (400), C (100), XC (90), L (50), XL (40), X (10), IX (9), V (5), IV (4) and I (1). - final int[] VALUES = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; - final String[] ROMAN = new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; - final String conciseList[][] = { - {"XLV", "VL"}, //45 - {"XCV", "VC"}, //95 - {"CDL", "LD"}, //450 - {"CML", "LM"}, //950 - {"CMVC", "LMVL"}, //995 - {"CDXC", "LDXL"}, //490 - {"CDVC", "LDVL"}, //495 - {"CMXC", "LMXL"}, //990 - {"XCIX", "VCIV"}, //99 - {"XLIX", "VLIV"}, //49 - {"XLIX", "IL"}, //49 - {"XCIX", "IC"}, //99 - {"CDXC", "XD"}, //490 - {"CDVC", "XDV"}, //495 - {"CDIC", "XDIX"}, //499 - {"LMVL", "XMV"}, //995 - {"CMIC", "XMIX"}, //999 - {"CMXC", "XM"}, // 990 - {"XDV", "VD"}, //495 - {"XDIX", "VDIV"}, //499 - {"XMV", "VM"}, // 995 - {"XMIX", "VMIV"}, //999 - {"VDIV", "ID"}, //499 - {"VMIV", "IM"} //999 - }; - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 13; i++) { - while (value >= VALUES[i]) { - value -= VALUES[i]; - sb.append(ROMAN[i]); - } - } - String result = sb.toString(); - for (String cc[] : conciseList) { - result = result.replace(cc[0], cc[1]); - } - return result; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/AutoShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/AutoShape.java deleted file mode 100644 index 5a77bdae4..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/AutoShape.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface AutoShape< - S extends Shape, - P extends TextParagraph -> extends TextShape { -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Background.java b/trunk/src/java/org/apache/poi/sl/usermodel/Background.java deleted file mode 100644 index 64f3b36a5..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Background.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface Background< - S extends Shape, - P extends TextParagraph -> extends Shape { - FillStyle getFillStyle(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java b/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java deleted file mode 100644 index fba7f5eae..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Color; - - -public interface ColorStyle { - Color getColor(); - - /** - * the opacity as expressed by a percentage value - * - * @return opacity in percents in the range [0..100000] - * or -1 if the value is not set - */ - int getAlpha(); - - /** - * the hue shift as expressed by a percentage relative to the input color. - * Be aware that OOXML also returns values greater than 100% - * - * @return hue shift in percents in the range [0..100000] (usually ...) - * or -1 if the value is not set - */ - int getHueOff(); - - /** - * the hue as expressed by a percentage relative to the input color. - * Be aware that OOXML also returns values greater than 100% - * - * @return hue in percents in the range [0..100000] (usually ...) - * or -1 if the value is not set - */ - int getHueMod(); - - /** - * the saturation shift as expressed by a percentage relative to the input color. - * Be aware that OOXML also returns values greater than 100% - * - * @return saturation shift in percents in the range [0..100000] (usually ...) - * or -1 if the value is not set - */ - int getSatOff(); - - /** - * the saturation as expressed by a percentage relative to the input color. - * Be aware that OOXML also returns values greater than 100% - * - * @return saturation in percents in the range [0..100000] (usually ...) - * or -1 if the value is not set - */ - int getSatMod(); - - /** - * the luminance shift as expressed by a percentage relative to the input color. - * Be aware that OOXML also returns values greater than 100% - * - * @return luminance shift in percents in the range [0..100000] (usually ...) - * or -1 if the value is not set - */ - int getLumOff(); - - /** - * the luminance as expressed by a percentage relative to the input color. - * Be aware that OOXML also returns values greater than 100%. - * - * @return luminance in percents in the range [0..100000] (usually ...) - * or -1 if the value is not set - */ - int getLumMod(); - - /** - * specifies a darker version of its input color. - * A 10% shade is 10% of the input color combined with 90% black. - * Be aware that OOXML also returns values greater than 100%. - * - * @return the value of the shade specified as percents in the range [0..100000] (usually ...) - * with 0% indicating minimal shade and 100% indicating maximum - * or -1 if the value is not set - */ - int getShade(); - - /** - * specifies a lighter version of its input color. - * A 10% tint is 10% of the input color combined with 90% white. - * Be aware that OOXML also returns values greater than 100% - * - * @return the value of the tint specified as percents in the range [0..100000] (usually ...) - * with 0% indicating minimal tint and 100% indicating maximum - * or -1 if the value is not set - */ - int getTint(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/ConnectorShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/ConnectorShape.java deleted file mode 100644 index 39e34d29e..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/ConnectorShape.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface ConnectorShape< - S extends Shape, - P extends TextParagraph -> extends SimpleShape { - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/FillStyle.java b/trunk/src/java/org/apache/poi/sl/usermodel/FillStyle.java deleted file mode 100644 index 8414000b8..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/FillStyle.java +++ /dev/null @@ -1,22 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface FillStyle { - PaintStyle getPaint(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/FontCollection.java b/trunk/src/java/org/apache/poi/sl/usermodel/FontCollection.java deleted file mode 100644 index 61278f461..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/FontCollection.java +++ /dev/null @@ -1,22 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface FontCollection { - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java deleted file mode 100644 index 9536065ef..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.geom.Path2D; - -public interface FreeformShape< - S extends Shape, - P extends TextParagraph -> extends AutoShape { - /** - * Gets the shape path. - *

    - * The path is translated in the shape's coordinate system, i.e. - * freeform.getPath().getBounds2D() equals to freeform.getAnchor() - * (small discrepancies are possible due to rounding errors) - *

    - * - * @return the path - */ - Path2D.Double getPath(); - - /** - * Set the shape path - * - * @param path shape outline - * @return the number of points written - */ - int setPath(Path2D.Double path); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java b/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java deleted file mode 100644 index 20621efed..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface GraphicalFrame< - S extends Shape, - P extends TextParagraph -> extends Shape, PlaceableShape { - - /** - * @return a fallback representation as picture shape - */ - PictureShape getFallbackPicture(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/GroupShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/GroupShape.java deleted file mode 100644 index a7545a4d4..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/GroupShape.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.geom.Rectangle2D; - -public interface GroupShape< - S extends Shape, - P extends TextParagraph -> extends Shape, ShapeContainer, PlaceableShape { - - /** - * Gets the coordinate space of this group. All children are constrained - * to these coordinates. - * - * @return the coordinate space of this group - */ - Rectangle2D getInteriorAnchor(); - - /** - * Sets the coordinate space of this group. All children are constrained - * to these coordinates. - * - * @param anchor the coordinate space of this group - */ - void setInteriorAnchor(Rectangle2D anchor); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Hyperlink.java b/trunk/src/java/org/apache/poi/sl/usermodel/Hyperlink.java deleted file mode 100644 index 3c2a9fc28..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Hyperlink.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -/** - * A PowerPoint hyperlink - * @since POI 3.14 beta 2 - */ -public interface Hyperlink< - S extends Shape, - P extends TextParagraph -> extends org.apache.poi.common.usermodel.Hyperlink { - /** - * Link to an email - * - * @param emailAddress the email address - * @since POI 3.14-Beta2 - */ - void linkToEmail(String emailAddress); - - /** - * Link to a web page / URL - * - * @param url the url - * @since POI 3.14-Beta2 - */ - void linkToUrl(String url); - - /** - * Link to a slide in this slideshow - * - * @param slide the linked slide - * @since POI 3.14-Beta2 - */ - void linkToSlide(Slide slide); - - /** - * Link to the next slide (relative from the current) - * - * @since POI 3.14-Beta2 - */ - void linkToNextSlide(); - - /** - * Link to the previous slide (relative from the current) - * - * @since POI 3.14-Beta2 - */ - void linkToPreviousSlide(); - - /** - * Link to the first slide in this slideshow - * - * @since POI 3.14-Beta2 - */ - void linkToFirstSlide(); - - /** - * Link to the last slide in this slideshow - * - * @since POI 3.14-Beta2 - */ - void linkToLastSlide(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Insets2D.java b/trunk/src/java/org/apache/poi/sl/usermodel/Insets2D.java deleted file mode 100644 index c7e59c27f..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Insets2D.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -/** - * This is a replacement for {@link java.awt.Insets} which works on doubles - * instead of ints - */ -public final class Insets2D implements Cloneable { - - /** - * The inset from the top. - * This value is added to the Top of the rectangle - * to yield a new location for the Top. - */ - public double top; - - /** - * The inset from the left. - * This value is added to the Left of the rectangle - * to yield a new location for the Left edge. - */ - public double left; - - /** - * The inset from the bottom. - * This value is subtracted from the Bottom of the rectangle - * to yield a new location for the Bottom. - */ - public double bottom; - - /** - * The inset from the right. - * This value is subtracted from the Right of the rectangle - * to yield a new location for the Right edge. - */ - public double right; - - /** - * Creates and initializes a new Insets object with the - * specified top, left, bottom, and right insets. - * @param top the inset from the top. - * @param left the inset from the left. - * @param bottom the inset from the bottom. - * @param right the inset from the right. - */ - public Insets2D(double top, double left, double bottom, double right) { - this.top = top; - this.left = left; - this.bottom = bottom; - this.right = right; - } - - /** - * Set top, left, bottom, and right to the specified values - * - * @param top the inset from the top. - * @param left the inset from the left. - * @param bottom the inset from the bottom. - * @param right the inset from the right. - * @since 1.5 - */ - public void set(double top, double left, double bottom, double right) { - this.top = top; - this.left = left; - this.bottom = bottom; - this.right = right; - } - - /** - * Checks whether two insets objects are equal. Two instances - * of Insets are equal if the four integer values - * of the fields top, left, - * bottom, and right are all equal. - * @return true if the two insets are equal; - * otherwise false. - * @since JDK1.1 - */ - public boolean equals(Object obj) { - if (obj instanceof Insets2D) { - Insets2D insets = (Insets2D)obj; - return ((top == insets.top) && (left == insets.left) && - (bottom == insets.bottom) && (right == insets.right)); - } - return false; - } - - /** - * Returns the hash code for this Insets. - * - * @return a hash code for this Insets. - */ - public int hashCode() { - double sum1 = left + bottom; - double sum2 = right + top; - double val1 = sum1 * (sum1 + 1)/2 + left; - double val2 = sum2 * (sum2 + 1)/2 + top; - double sum3 = val1 + val2; - return (int)(sum3 * (sum3 + 1)/2 + val2); - } - - /** - * Returns a string representation of this Insets object. - * This method is intended to be used only for debugging purposes, and - * the content and format of the returned string may vary between - * implementations. The returned string may be empty but may not be - * null. - * - * @return a string representation of this Insets object. - */ - public String toString() { - return getClass().getName() + "[top=" + top + ",left=" + left + ",bottom=" + bottom + ",right=" + right + "]"; - } - - /** - * Create a copy of this object. - * @return a copy of this Insets2D object. - */ - @Override - public Insets2D clone() { - return new Insets2D(top, left, bottom, right); - } - - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Line.java b/trunk/src/java/org/apache/poi/sl/usermodel/Line.java deleted file mode 100644 index e9325c55b..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Line.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import org.apache.poi.util.Internal; - -/** - * Interface for Lines ... this will be eventually removed, - * so don't depend on it in user classes, but use AutoShape instead! - */ - -@Internal -public interface Line< - S extends Shape, - P extends TextParagraph -> extends AutoShape { - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/LineDecoration.java b/trunk/src/java/org/apache/poi/sl/usermodel/LineDecoration.java deleted file mode 100644 index ad61e413c..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/LineDecoration.java +++ /dev/null @@ -1,113 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface LineDecoration { - /** - * Represents the shape decoration that appears at the ends of lines. - */ - enum DecorationShape { - NONE(0,1), - TRIANGLE(1,2), - STEALTH(2,3), - DIAMOND(3,4), - OVAL(4,5), - ARROW(5,6); - - public final int nativeId; - public final int ooxmlId; - - DecorationShape(int nativeId, int ooxmlId) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - } - - public static DecorationShape fromNativeId(int nativeId) { - for (DecorationShape ld : values()) { - if (ld.nativeId == nativeId) return ld; - } - return null; - } - - public static DecorationShape fromOoxmlId(int ooxmlId) { - for (DecorationShape ds : values()) { - if (ds.ooxmlId == ooxmlId) return ds; - } - return null; - } - } - - enum DecorationSize { - SMALL(0, 1), - MEDIUM(1, 2), - LARGE(2, 3); - - public final int nativeId; - public final int ooxmlId; - - DecorationSize(int nativeId, int ooxmlId) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - } - - public static DecorationSize fromNativeId(int nativeId) { - for (DecorationSize ld : values()) { - if (ld.nativeId == nativeId) return ld; - } - return null; - } - - public static DecorationSize fromOoxmlId(int ooxmlId) { - for (DecorationSize ds : values()) { - if (ds.ooxmlId == ooxmlId) return ds; - } - return null; - } - } - - /** - * @return the line start shape - */ - DecorationShape getHeadShape(); - - /** - * @return the width of the start shape - */ - DecorationSize getHeadWidth(); - - /** - * @return the length of the start shape - */ - DecorationSize getHeadLength(); - - /** - * @return the line end shape - */ - DecorationShape getTailShape(); - - /** - * @return the width of the end shape - */ - DecorationSize getTailWidth(); - - /** - * @return the length of the end shape - */ - DecorationSize getTailLength(); - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/MasterSheet.java b/trunk/src/java/org/apache/poi/sl/usermodel/MasterSheet.java deleted file mode 100644 index fdfcf4380..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/MasterSheet.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface MasterSheet< - S extends Shape, - P extends TextParagraph -> extends Sheet { - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Notes.java b/trunk/src/java/org/apache/poi/sl/usermodel/Notes.java deleted file mode 100644 index d156e98a7..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Notes.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.util.List; - -public interface Notes< - S extends Shape, - P extends TextParagraph -> extends Sheet { - List> getTextParagraphs(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java b/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java deleted file mode 100644 index 25651043b..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.io.InputStream; - - - -public interface PaintStyle { - - public interface SolidPaint extends PaintStyle { - ColorStyle getSolidColor(); - } - - public interface GradientPaint extends PaintStyle { - enum GradientType { linear, circular, shape } - - /** - * @return the angle of the gradient - */ - double getGradientAngle(); - ColorStyle[] getGradientColors(); - float[] getGradientFractions(); - boolean isRotatedWithShape(); - GradientType getGradientType(); - } - - public interface TexturePaint extends PaintStyle { - /** - * @return the raw image stream - */ - InputStream getImageData(); - - /** - * @return the content type of the image data - */ - String getContentType(); - - /** - * @return the alpha mask in percents [0..100000] - */ - int getAlpha(); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/PictureData.java b/trunk/src/java/org/apache/poi/sl/usermodel/PictureData.java deleted file mode 100644 index 60e6266b7..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/PictureData.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Dimension; -import java.io.IOException; - -public interface PictureData { - - enum PictureType { - /** Extended windows meta file */ - EMF(2,2,"image/x-emf",".emf"), - /** Windows Meta File */ - WMF(3,3,"image/x-wmf",".wmf"), - /** Mac PICT format */ - PICT(4,4,"image/pict",".pict"), // or image/x-pict (for HSLF) ??? - /** JPEG format */ - JPEG(5,5,"image/jpeg",".jpg"), - /** PNG format */ - PNG(6,6,"image/png",".png"), - /** Device independent bitmap */ - DIB(7,7,"image/dib",".dib"), - /** GIF image format */ - GIF(-1,8,"image/gif",".gif"), - /** Tag Image File (.tiff) */ - TIFF(-1,9,"image/tiff",".tif"), - /** Encapsulated Postscript (.eps) */ - EPS(-1,10,"image/x-eps",".eps"), - /** Windows Bitmap (.bmp) */ - BMP(-1,11,"image/x-ms-bmp",".bmp"), - /** WordPerfect graphics (.wpg) */ - WPG(-1,12,"image/x-wpg",".wpg"), - /** Microsoft Windows Media Photo image (.wdp) */ - WDP(-1,13,"image/vnd.ms-photo",".wdp"); - - public final int nativeId, ooxmlId; - public final String contentType,extension; - - PictureType(int nativeId, int ooxmlId,String contentType,String extension) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - this.contentType = contentType; - this.extension = extension; - } - - public static PictureType forNativeID(int nativeId) { - for (PictureType ans : values()) { - if (ans.nativeId == nativeId) return ans; - } - return null; - } - - public static PictureType forOoxmlID(int ooxmlId) { - for (PictureType ans : values()) { - if (ans.ooxmlId == ooxmlId) return ans; - } - return null; - } - } - - - /** - * Returns content type (mime type) of this picture. - * - * @return content type of this picture. - */ - String getContentType(); - - /** - * @return the picture type - */ - PictureType getType(); - - /** - * Returns the binary data of this Picture - * @return picture data - */ - byte[] getData(); - - /** - * Sets the binary picture data - * @param data picture data - */ - void setData(byte[] data) throws IOException; - - /** - * Gets the checksum - the checksum can be of various length - - * mostly it's 8 (XSLF) or 16 (HSLF) bytes long. - * @return the checksum - */ - byte[] getChecksum(); - - /** - * Return the original image dimensions in points - * (for formats supported by BufferedImage). - * - * Will return a Dimension with a default width of 200x200 if the format unsupported. - */ - Dimension getImageDimension(); - - /** - * Return the original image dimensions in pixels - * @see PictureData#getImageDimension() - */ - Dimension getImageDimensionInPixels(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/PictureShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/PictureShape.java deleted file mode 100644 index 671a43946..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/PictureShape.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Insets; - -public interface PictureShape< - S extends Shape, - P extends TextParagraph -> extends SimpleShape { - /** - * Returns the picture data for this picture. - * - * @return the picture data for this picture. - */ - PictureData getPictureData(); - - /** - * Returns the clipping values as percent ratio relatively to the image size. - * The clipping are returned as insets converted/scaled to 100000 (=100%). - * - * @return the clipping rectangle, which is given in percent in relation to the image width/height - */ - Insets getClipping(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java deleted file mode 100644 index 9fdcf91f6..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.geom.Rectangle2D; - -public interface PlaceableShape< - S extends Shape, - P extends TextParagraph -> { - ShapeContainer getParent(); - - /** - * @return the sheet this shape belongs to - */ - Sheet getSheet(); - - /** - * @return the position of this shape within the drawing canvas. - * The coordinates are expressed in points - */ - Rectangle2D getAnchor(); - - /** - * @param anchor the position of this shape within the drawing canvas. - * The coordinates are expressed in points - */ - void setAnchor(Rectangle2D anchor); - - /** - * Rotation angle in degrees - *

    - * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

    - * - * @return rotation angle in degrees - */ - double getRotation(); - - /** - * Rotate this shape. - *

    - * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

    - * - * @param theta the rotation angle in degrees. - */ - void setRotation(double theta); - - /** - * @param flip whether the shape is horizontally flipped - */ - void setFlipHorizontal(boolean flip); - - /** - * Whether the shape is vertically flipped - * - * @param flip whether the shape is vertically flipped - */ - void setFlipVertical(boolean flip); - - /** - * Whether the shape is horizontally flipped - * - * @return whether the shape is horizontally flipped - */ - boolean getFlipHorizontal(); - - /** - * Whether the shape is vertically flipped - * - * @return whether the shape is vertically flipped - */ - boolean getFlipVertical(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Placeholder.java b/trunk/src/java/org/apache/poi/sl/usermodel/Placeholder.java deleted file mode 100644 index a3bc9c7c8..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Placeholder.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public enum Placeholder { - /** - * No placeholder shape. - */ - NONE(0,0,0,0,0), - /** - * Title text placeholder shape. - */ - TITLE(13,1,1,1,1), - /** - * Body text placeholder shape. - */ - BODY(14,2,12,6,2), - /** - * Center title text placeholder shape. - */ - CENTERED_TITLE(15,3,3,3,3), - /** - * Sub-title text placeholder shape. - */ - SUBTITLE(16,4,4,4,4), - /** - * Date placeholder shape. - */ - DATETIME(7,7,7,7,5), - /** - * Slide number placeholder shape. - */ - SLIDE_NUMBER(8,8,8,8,6), - /** - * Footer placeholder shape. - */ - FOOTER(9,9,9,9,7), - /** - * Header placeholder shape. - */ - HEADER(10,10,10,10,8), - /** - * Object placeholder shape. - */ - CONTENT(19,19,19,19,9), - /** - * Graph object placeholder shape. - */ - CHART(20,20,20,20,10), - /** - * Table object placeholder shape. - */ - TABLE(21,21,21,21,11), - /** - * Clipart object placeholder shape. - */ - CLIP_ART(22,22,22,22,12), - /** - * Organization chart object placeholder shape. - */ - DGM(23,23,23,23,13), - /** - * Media object placeholder shape. - */ - MEDIA(24,24,24,24,14), - /** - * Slide image placeholder shape. - */ - SLIDE_IMAGE(11,11,11,5,15), - /** - * Picture object placeholder shape. - */ - PICTURE(26,26,26,26,16), - /** - * Vertical object placeholder shape. - */ - VERTICAL_OBJECT(25,25,25,25,-2), - /** - * Vertical title text placeholder shape. - */ - VERTICAL_TEXT_TITLE(17,17,17,17,-2), - /** - * Vertical body text placeholder shape. - */ - VERTICAL_TEXT_BODY(18,18,18,18,-2) - ; - - public final int nativeSlideId; - public final int nativeSlideMasterId; - public final int nativeNotesId; - public final int nativeNotesMasterId; - public final int ooxmlId; - - Placeholder(int nativeSlideId, int nativeSlideMasterId, int nativeNotesId, int nativeNotesMasterId, int ooxmlId) { - this.nativeSlideId = nativeSlideId; - this.nativeSlideMasterId = nativeSlideMasterId; - this.nativeNotesId = nativeNotesId; - this.nativeNotesMasterId = nativeNotesMasterId; - this.ooxmlId = ooxmlId; - } - - public static Placeholder lookupNative(int nativeId) { - for (Placeholder ph : values()) { - if (ph.nativeSlideId == nativeId || - ph.nativeSlideMasterId == nativeId || - ph.nativeNotesId == nativeId || - ph.nativeNotesMasterId == nativeId - ) { - return ph; - } - } - return null; - } - - public static Placeholder lookupOoxml(int ooxmlId) { - for (Placeholder ph : values()) { - if (ph.ooxmlId == ooxmlId) { - return ph; - } - } - return null; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/PresetColor.java b/trunk/src/java/org/apache/poi/sl/usermodel/PresetColor.java deleted file mode 100644 index f78dbca40..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/PresetColor.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Color; -import java.util.HashMap; -import java.util.Map; - -/** - * Preset colors defined in DrawingML aka known/system colors - * - * @see KnownColor Enumeration - * @see Colors Class - */ -public enum PresetColor { - // the order of this enum can be found in the definition of .net System.Drawing.KnownColor enumeration - // or by running the the program in the linked documentation - - // default colors for theme-depending colors taken from ... (last post): - // https://social.technet.microsoft.com/Forums/windows/en-US/ac76cc56-6ff2-4778-b260-8141d7170a3b/windows-7-highlight-text-color-or-selected-text-color-in-aero - - // see ST_SystemColorVal for system color names - - /** The system-defined color of the active window's border. */ - ActiveBorder (0xffb4b4b4, 1, "activeBorder"), - /** The system-defined color of the background of the active window's title bar. */ - ActiveCaption (0xff99b4d1, 2, "activeCaption"), - /** The system-defined color of the text in the active window's title bar. */ - ActiveCaptionText (0xff000000, 3, "captionText"), - /** The application workspace is the area in a multiple-document view that is not being occupied by documents. */ - AppWorkspace (0xffababab, 4, "appWorkspace"), - /** The system-defined face color of a 3-D element. */ - Control (0xfff0f0f0, 5, "btnFace"), - /** The system-defined shadow color of a 3-D element. The shadow color is applied to parts of a 3-D element that face away from the light source. */ - ControlDark (0xff696969, 6, "btnShadow"), - /** The system-defined color that is the dark shadow color of a 3-D element. The dark shadow color is applied to the parts of a 3-D element that are the darkest color. */ - ControlDarkDark (0xff000000, 7, "3dDkShadow"), - /** The system-defined color that is the light color of a 3-D element. The light color is applied to parts of a 3-D element that face the light source. */ - ControlLight (0xffe3e3e3, 8, "btnHighlight"), - /** The system-defined highlight color of a 3-D element. The highlight color is applied to the parts of a 3-D element that are the lightest color. */ - ControlLightLight (0xffe3e3e3, 9, "3dLight"), - /** The system-defined color of text in a 3-D element. */ - ControlText (0xff000000, 10, "btnText"), - /** The system-defined color of the desktop. */ - Desktop (0xff000000, 11, "background"), - /** The system-defined color of dimmed text. Items in a list that are disabled are displayed in dimmed text. */ - GrayText (0xff6d6d6d, 12, "grayText"), - /** The system-defined color of the background of selected items. This includes selected menu items as well as selected text. */ - Highlight (0xff3399ff, 13, "highlight"), - /** The system-defined color of the text of selected items. */ - HighlightText (0xffffffff, 14, "highlightText"), - /** The system-defined color used to designate a hot-tracked item. Single-clicking a hot-tracked item executes the item. */ - HotTrack (0xff0066cc, 15, "hotLight"), - /** The system-defined color of an inactive window's border. */ - InactiveBorder (0xfff4f7fc, 16, "inactiveBorder"), - /** The system-defined color of the background of an inactive window's title bar. */ - InactiveCaption (0xffbfcddb, 17, "inactiveCaption"), - /** The system-defined color of the text in an inactive window's title bar. */ - InactiveCaptionText (0xff000000, 18, "inactiveCaptionText"), - /** The system-defined color of the background of a ToolTip. */ - Info (0xffffffe1, 19, "infoBk"), - /** The system-defined color of the text of a ToolTip. */ - InfoText (0xff000000, 20, "infoText"), - /** The system-defined color of a menu's background. */ - Menu (0xfff0f0f0, 21, "menu"), - /** The system-defined color of a menu's text. */ - MenuText (0xff000000, 22, "menuText"), - /** The system-defined color of the background of a scroll bar. */ - ScrollBar (0xffc8c8c8, 23, "scrollBar"), - /** The system-defined color of the background in the client area of a window. */ - Window (0xffffffff, 24, "window"), - /** The system-defined color of a window frame. */ - WindowFrame (0xff646464, 25, "windowFrame"), - /** The system-defined color of the text in the client area of a window. */ - WindowText (0xff000000, 26, "windowText"), - Transparent (0x00ffffff, 27, null), - AliceBlue (0xfff0f8ff, 28, "aliceBlue"), - AntiqueWhite (0xfffaebd7, 29, "antiqueWhite"), - Aqua (0xff00ffff, 30, "aqua"), - Aquamarine (0xff7fffd4, 31, "aquamarine"), - Azure (0xfff0ffff, 32, "azure"), - Beige (0xfff5f5dc, 33, "beige"), - Bisque (0xffffe4c4, 34, "bisque"), - Black (0xff000000, 35, "black"), - BlanchedAlmond (0xffffebcd, 36, "blanchedAlmond"), - Blue (0xff0000ff, 37, "blue"), - BlueViolet (0xff8a2be2, 38, "blueViolet"), - Brown (0xffa52a2a, 39, "brown"), - BurlyWood (0xffdeb887, 40, "burlyWood"), - CadetBlue (0xff5f9ea0, 41, "cadetBlue"), - Chartreuse (0xff7fff00, 42, "chartreuse"), - Chocolate (0xffd2691e, 43, "chocolate"), - Coral (0xffff7f50, 44, "coral"), - CornflowerBlue (0xff6495ed, 45, "cornflowerBlue"), - Cornsilk (0xfffff8dc, 46, "cornsilk"), - Crimson (0xffdc143c, 47, "crimson"), - Cyan (0xff00ffff, 48, "cyan"), - DarkBlue (0xff00008b, 49, "dkBlue"), - DarkCyan (0xff008b8b, 50, "dkCyan"), - DarkGoldenrod (0xffb8860b, 51, "dkGoldenrod"), - DarkGray (0xffa9a9a9, 52, "dkGray"), - DarkGreen (0xff006400, 53, "dkGreen"), - DarkKhaki (0xffbdb76b, 54, "dkKhaki"), - DarkMagenta (0xff8b008b, 55, "dkMagenta"), - DarkOliveGreen (0xff556b2f, 56, "dkOliveGreen"), - DarkOrange (0xffff8c00, 57, "dkOrange"), - DarkOrchid (0xff9932cc, 58, "dkOrchid"), - DarkRed (0xff8b0000, 59, "dkRed"), - DarkSalmon (0xffe9967a, 60, "dkSalmon"), - DarkSeaGreen (0xff8fbc8b, 61, "dkSeaGreen"), - DarkSlateBlue (0xff483d8b, 62, "dkSlateBlue"), - DarkSlateGray (0xff2f4f4f, 63, "dkSlateGray"), - DarkTurquoise (0xff00ced1, 64, "dkTurquoise"), - DarkViolet (0xff9400d3, 65, "dkViolet"), - DeepPink (0xffff1493, 66, "deepPink"), - DeepSkyBlue (0xff00bfff, 67, "deepSkyBlue"), - DimGray (0xff696969, 68, "dimGray"), - DodgerBlue (0xff1e90ff, 69, "dodgerBlue"), - Firebrick (0xffb22222, 70, "firebrick"), - FloralWhite (0xfffffaf0, 71, "floralWhite"), - ForestGreen (0xff228b22, 72, "forestGreen"), - Fuchsia (0xffff00ff, 73, "fuchsia"), - Gainsboro (0xffdcdcdc, 74, "gainsboro"), - GhostWhite (0xfff8f8ff, 75, "ghostWhite"), - Gold (0xffffd700, 76, "gold"), - Goldenrod (0xffdaa520, 77, "goldenrod"), - Gray (0xff808080, 78, "gray"), - Green (0xff008000, 79, "green"), - GreenYellow (0xffadff2f, 80, "greenYellow"), - Honeydew (0xfff0fff0, 81, "honeydew"), - HotPink (0xffff69b4, 82, "hotPink"), - IndianRed (0xffcd5c5c, 83, "indianRed"), - Indigo (0xff4b0082, 84, "indigo"), - Ivory (0xfffffff0, 85, "ivory"), - Khaki (0xfff0e68c, 86, "khaki"), - Lavender (0xffe6e6fa, 87, "lavender"), - LavenderBlush (0xfffff0f5, 88, "lavenderBlush"), - LawnGreen (0xff7cfc00, 89, "lawnGreen"), - LemonChiffon (0xfffffacd, 90, "lemonChiffon"), - LightBlue (0xffadd8e6, 91, "ltBlue"), - LightCoral (0xfff08080, 92, "ltCoral"), - LightCyan (0xffe0ffff, 93, "ltCyan"), - LightGoldenrodYellow (0xfffafa78, 94, "ltGoldenrodYellow"), - LightGray (0xffd3d3d3, 95, "ltGray"), - LightGreen (0xff90ee90, 96, "ltGreen"), - LightPink (0xffffb6c1, 97, "ltPink"), - LightSalmon (0xffffa07a, 98, "ltSalmon"), - LightSeaGreen (0xff20b2aa, 99, "ltSeaGreen"), - LightSkyBlue (0xff87cefa, 100, "ltSkyBlue"), - LightSlateGray (0xff778899, 101, "ltSlateGray"), - LightSteelBlue (0xffb0c4de, 102, "ltSteelBlue"), - LightYellow (0xffffffe0, 103, "ltYellow"), - Lime (0xff00ff00, 104, "lime"), - LimeGreen (0xff32cd32, 105, "limeGreen"), - Linen (0xfffaf0e6, 106, "linen"), - Magenta (0xffff00ff, 107, "magenta"), - Maroon (0xff800000, 108, "maroon"), - MediumAquamarine (0xff66cdaa, 109, "medAquamarine"), - MediumBlue (0xff0000cd, 110, "medBlue"), - MediumOrchid (0xffba55d3, 111, "medOrchid"), - MediumPurple (0xff9370db, 112, "medPurple"), - MediumSeaGreen (0xff3cb371, 113, "medSeaGreen"), - MediumSlateBlue (0xff7b68ee, 114, "medSlateBlue"), - MediumSpringGreen (0xff00fa9a, 115, "medSpringGreen"), - MediumTurquoise (0xff48d1cc, 116, "medTurquoise"), - MediumVioletRed (0xffc71585, 117, "medVioletRed"), - MidnightBlue (0xff191970, 118, "midnightBlue"), - MintCream (0xfff5fffa, 119, "mintCream"), - MistyRose (0xffffe4e1, 120, "mistyRose"), - Moccasin (0xffffe4b5, 121, "moccasin"), - NavajoWhite (0xffffdead, 122, "navajoWhite"), - Navy (0xff000080, 123, "navy"), - OldLace (0xfffdf5e6, 124, "oldLace"), - Olive (0xff808000, 125, "olive"), - OliveDrab (0xff6b8e23, 126, "oliveDrab"), - Orange (0xffffa500, 127, "orange"), - OrangeRed (0xffff4500, 128, "orangeRed"), - Orchid (0xffda70d6, 129, "orchid"), - PaleGoldenrod (0xffeee8aa, 130, "paleGoldenrod"), - PaleGreen (0xff98fb98, 131, "paleGreen"), - PaleTurquoise (0xffafeeee, 132, "paleTurquoise"), - PaleVioletRed (0xffdb7093, 133, "paleVioletRed"), - PapayaWhip (0xffffefd5, 134, "papayaWhip"), - PeachPuff (0xffffdab9, 135, "peachPuff"), - Peru (0xffcd853f, 136, "peru"), - Pink (0xffffc0cb, 137, "pink"), - Plum (0xffdda0dd, 138, "plum"), - PowderBlue (0xffb0e0e6, 139, "powderBlue"), - Purple (0xff800080, 140, "purple"), - Red (0xffff0000, 141, "red"), - RosyBrown (0xffbc8f8f, 142, "rosyBrown"), - RoyalBlue (0xff4169e1, 143, "royalBlue"), - SaddleBrown (0xff8b4513, 144, "saddleBrown"), - Salmon (0xfffa8072, 145, "salmon"), - SandyBrown (0xfff4a460, 146, "sandyBrown"), - SeaGreen (0xff2e8b57, 147, "seaGreen"), - SeaShell (0xfffff5ee, 148, "seaShell"), - Sienna (0xffa0522d, 149, "sienna"), - Silver (0xffc0c0c0, 150, "silver"), - SkyBlue (0xff87ceeb, 151, "skyBlue"), - SlateBlue (0xff6a5acd, 152, "slateBlue"), - SlateGray (0xff708090, 153, "slateGray"), - Snow (0xfffffafa, 154, "snow"), - SpringGreen (0xff00ff7f, 155, "springGreen"), - SteelBlue (0xff4682b4, 156, "steelBlue"), - Tan (0xffd2b48c, 157, "tan"), - Teal (0xff008080, 158, "teal"), - Thistle (0xffd8bfd8, 159, "thistle"), - Tomato (0xffff6347, 160, "tomato"), - Turquoise (0xff40e0d0, 161, "turquoise"), - Violet (0xffee82ee, 162, "violet"), - Wheat (0xfff5deb3, 163, "wheat"), - White (0xffffffff, 164, "white"), - WhiteSmoke (0xfff5f5f5, 165, "whiteSmoke"), - Yellow (0xffffff00, 166, "yellow"), - YellowGreen (0xff9acd32, 167, "yellowGreen"), - /** The system-defined face color of a 3-D element. */ - ButtonFace (0xfff0f0f0, 168, null), - /** The system-defined color that is the highlight color of a 3-D element. This color is applied to parts of a 3-D element that face the light source. */ - ButtonHighlight (0xffffffff, 169, null), - /** The system-defined color that is the shadow color of a 3-D element. This color is applied to parts of a 3-D element that face away from the light source. */ - ButtonShadow (0xffa0a0a0, 170, null), - /** The system-defined color of the lightest color in the color gradient of an active window's title bar. */ - GradientActiveCaption (0xffb9d1ea, 171, "gradientActiveCaption"), - /** The system-defined color of the lightest color in the color gradient of an inactive window's title bar. */ - GradientInactiveCaption (0xffd7e4f2, 172, "gradientInactiveCaption"), - /** The system-defined color of the background of a menu bar. */ - MenuBar (0xfff0f0f0, 173, "menuBar"), - /** The system-defined color used to highlight menu items when the menu appears as a flat menu. */ - MenuHighlight (0xff3399ff, 174, "menuHighlight") - ; - - public final Color color; - public final int nativeId; - public final String ooxmlId; - - PresetColor(Integer rgb, int nativeId, String ooxmlId) { - this.color = (rgb == null) ? null : new Color(rgb, true); - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - } - - private static final Map lookupOoxmlId; - - static { - lookupOoxmlId = new HashMap(); - for(PresetColor pc : PresetColor.values()) { - if (pc.ooxmlId != null) { - lookupOoxmlId.put(pc.ooxmlId, pc); - } - } - } - - public static PresetColor valueOfOoxmlId(String ooxmlId) { - return lookupOoxmlId.get(ooxmlId); - } - - public static PresetColor valueOfNativeId(int nativeId) { - PresetColor vals[] = values(); - return (0 < nativeId && nativeId <= vals.length) ? vals[nativeId-1] : null; - } -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/RectAlign.java b/trunk/src/java/org/apache/poi/sl/usermodel/RectAlign.java deleted file mode 100644 index 471043f41..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/RectAlign.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.sl.usermodel; - -/** - * Specifies possible rectangle alignment types. - * See org.openxmlformats.schemas.drawingml.x2006.main.STRectAlignment - * - * @see org.apache.poi.sl.draw.binding.STRectAlignment - */ -public enum RectAlign { - /** Top-Left rectangle alignment */ - TOP_LEFT("tl"), - - /** Top rectangle alignment */ - TOP("t"), - - /** Top-Right rectangle alignment */ - TOP_RIGHT("tr"), - - /** Left rectangle alignment */ - LEFT("l"), - - /** Center rectangle alignment */ - CENTER("ctr"), - - /** Right rectangle alignment */ - RIGHT("r"), - - /** Bottom-Left rectangle alignment */ - BOTTOM_LEFT("bl"), - - /** Bottom rectangle alignment */ - BOTTOM("b"), - - /** Bottom-Right rectangle alignment */ - BOTTOM_RIGHT("br"); - - /** The corresponding xml enum value */ - private final String dir; - - private RectAlign(String dir) { - this.dir = dir; - } - - - /** - * The string representation, - * which corresponds to the internal XML enum value - */ - @Override - public String toString() { - return dir; - } - -} - -/* ************************************************************************** */ diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Resources.java b/trunk/src/java/org/apache/poi/sl/usermodel/Resources.java deleted file mode 100644 index 96170e50b..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Resources.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -/** - * Common SlideShow resources, such as fonts, pictures - * and multimedia data - */ -public interface Resources { - public FontCollection getFontCollection(); - - public PictureData[] getPictureData(); - public int addPictureData(PictureData pict); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Shadow.java b/trunk/src/java/org/apache/poi/sl/usermodel/Shadow.java deleted file mode 100644 index 9afc4e64e..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Shadow.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; - - - -public interface Shadow< -S extends Shape, -P extends TextParagraph -> { - SimpleShape getShadowParent(); - - /** - * @return the offset of this shadow in points - */ - double getDistance(); - - /** - * - * @return the direction to offset the shadow in angles - */ - double getAngle(); - - /** - * - * @return the blur radius of the shadow - * TODO: figure out how to make sense of this property when rendering shadows - */ - double getBlur(); - - /** - * @return the color of this shadow. - * Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow - */ - SolidPaint getFillStyle(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java b/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java deleted file mode 100644 index 0115f8b9a..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; - -public interface Shape< - S extends Shape, - P extends TextParagraph -> { - ShapeContainer getParent(); - - /** - * @return the sheet this shape belongs to - */ - Sheet getSheet(); - - /** - * Returns the anchor (the bounding box rectangle) of this shape. - * All coordinates are expressed in points (72 dpi). - * - * @return the anchor of this shape - */ - Rectangle2D getAnchor(); - - /** - * Convenience method to draw a single shape - * - * @param graphics the graphics context - * @param bounds the rectangle to fit the shape to. - * if null, the bounds of the shape are used. - */ - void draw(Graphics2D graphics, Rectangle2D bounds); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/ShapeContainer.java b/trunk/src/java/org/apache/poi/sl/usermodel/ShapeContainer.java deleted file mode 100644 index 086501b4c..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/ShapeContainer.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.util.List; - - -public interface ShapeContainer< - S extends Shape, - P extends TextParagraph -> extends Iterable { - /** - * Returns an list containing all of the elements in this container in proper - * sequence (from first to last element). - * - * @return an list containing all of the elements in this container in proper - * sequence - */ - List getShapes(); - - void addShape(S shape); - - /** - * Removes the specified shape from this sheet, if it is present - * (optional operation). If this sheet does not contain the element, - * it is unchanged. - * - * @param shape the shape to be removed from this sheet, if present - * @return true if this sheet contained the specified element - * @throws IllegalArgumentException if the type of the specified shape - * is incompatible with this sheet (optional) - */ - boolean removeShape(S shape); - - /** - * create a new shape with a predefined geometry and add it to this shape container - */ - AutoShape createAutoShape(); - - /** - * create a new shape with a custom geometry - */ - FreeformShape createFreeform(); - - /** - * create a text box - */ - TextBox createTextBox(); - - /** - * create a connector - */ - ConnectorShape createConnector(); - - /** - * create a group of shapes belonging to this container - */ - GroupShape createGroup(); - - /** - * create a picture belonging to this container - */ - PictureShape createPicture(PictureData pictureData); - - /** - * Create a new Table of the given number of rows and columns - * - * @param numRows the number of rows - * @param numCols the number of columns - */ - TableShape createTable(int numRows, int numCols); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/ShapeType.java b/trunk/src/java/org/apache/poi/sl/usermodel/ShapeType.java deleted file mode 100644 index b2cb73b0f..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/ShapeType.java +++ /dev/null @@ -1,321 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -/** - * known preset shape geometries in PresentationML - */ -public enum ShapeType { - NOT_PRIMITIVE(-1, 0, "NotPrimitive"), - LINE(1, 20, "Line"), - LINE_INV(2, -1, null), - TRIANGLE(3, 5, "IsocelesTriangle"), - RT_TRIANGLE(4, 6, "RightTriangle"), - RECT(5, 1, "Rectangle"), - DIAMOND(6, 4, "Diamond"), - PARALLELOGRAM(7, 7, "Parallelogram"), - TRAPEZOID(8, 8, "Trapezoid"), - NON_ISOSCELES_TRAPEZOID(9, -1, null), - PENTAGON(10, 56, "Pentagon"), - HEXAGON(11, 9, "Hexagon"), - HEPTAGON(12, -1, null), - OCTAGON(13, 10, "Octagon"), - DECAGON(14, -1, null), - DODECAGON(15, -1, null), - STAR_4(16, 187, "Star4"), - STAR_5(17, 12, "Star"), // aka star in native - STAR_6(18, -1, null), - STAR_7(19, -1, null), - STAR_8(20, 58, "Star8"), - STAR_10(21, -1, null), - STAR_12(22, -1, null), - STAR_16(23, 59, "Star16"), - SEAL(23, 18, "Seal"), // same as star_16, but twice in native - STAR_24(24, 92, "Star24"), - STAR_32(25, 60, "Star32"), - ROUND_RECT(26, 2, "RoundRectangle"), - ROUND_1_RECT(27, -1, null), - ROUND_2_SAME_RECT(28, -1, null), - ROUND_2_DIAG_RECT(29, -1, null), - SNIP_ROUND_RECT(30, -1, null), - SNIP_1_RECT(31, -1, null), - SNIP_2_SAME_RECT(32, -1, null), - SNIP_2_DIAG_RECT(33, -1, null), - PLAQUE(34, 21, "Plaque"), - ELLIPSE(35, 3, "Ellipse"), - TEARDROP(36, -1, null), - HOME_PLATE(37, 15, "HomePlate"), - CHEVRON(38, 55, "Chevron"), - PIE_WEDGE(39, -1, null), - PIE(40, -1, null), - BLOCK_ARC(41, 95, "BlockArc"), - DONUT(42, 23, "Donut"), - NO_SMOKING(43, 57, "NoSmoking"), - RIGHT_ARROW(44, 13, "Arrow"), // aka arrow in native - LEFT_ARROW(45, 66, "LeftArrow"), - UP_ARROW(46, 68, "UpArrow"), - DOWN_ARROW(47, 67, "DownArrow"), - STRIPED_RIGHT_ARROW(48, 93, "StripedRightArrow"), - NOTCHED_RIGHT_ARROW(49, 94, "NotchedRightArrow"), - BENT_UP_ARROW(50, 90, "BentUpArrow"), - LEFT_RIGHT_ARROW(51, 69, "LeftRightArrow"), - UP_DOWN_ARROW(52, 70, "UpDownArrow"), - LEFT_UP_ARROW(53, 89, "LeftUpArrow"), - LEFT_RIGHT_UP_ARROW(54, 182, "LeftRightUpArrow"), - QUAD_ARROW(55, 76, "QuadArrow"), - LEFT_ARROW_CALLOUT(56, 77, "LeftArrowCallout"), - RIGHT_ARROW_CALLOUT(57, 78, "RightArrowCallout"), - UP_ARROW_CALLOUT(58, 79, "UpArrowCallout"), - DOWN_ARROW_CALLOUT(59, 80, "DownArrowCallout"), - LEFT_RIGHT_ARROW_CALLOUT(60, 81, "LeftRightArrowCallout"), - UP_DOWN_ARROW_CALLOUT(61, 82, "UpDownArrowCallout"), - QUAD_ARROW_CALLOUT(62, 83, "QuadArrowCallout"), - BENT_ARROW(63, 91, "BentArrow"), - UTURN_ARROW(64, 101, "UturnArrow"), - CIRCULAR_ARROW(65, 99, "CircularArrow"), - LEFT_CIRCULAR_ARROW(66, -1, null), - LEFT_RIGHT_CIRCULAR_ARROW(67, -1, null), - CURVED_RIGHT_ARROW(68, 102, "CurvedRightArrow"), - CURVED_LEFT_ARROW(69, 103, "CurvedLeftArrow"), - CURVED_UP_ARROW(70, 104, "CurvedUpArrow"), - CURVED_DOWN_ARROW(71, 105, "CurvedDownArrow"), - SWOOSH_ARROW(72, -1, null), - CUBE(73, 16, "Cube"), - CAN(74, 22, "Can"), - LIGHTNING_BOLT(75, 73, "LightningBolt"), - HEART(76, 74, "Heart"), - SUN(77, 183, "Sun"), - MOON(78, 184, "Moon"), - SMILEY_FACE(79, 96, "SmileyFace"), - IRREGULAR_SEAL_1(80, 71, "IrregularSeal1"), - IRREGULAR_SEAL_2(81, 72, "IrregularSeal2"), - FOLDED_CORNER(82, 65, "FoldedCorner"), - BEVEL(83, 84, "Bevel"), - FRAME(84, 75, "PictureFrame"), - HALF_FRAME(85, -1, null), - CORNER(86, -1, null), - DIAG_STRIPE(87, -1, null), - CHORD(88, -1, null), - ARC(89, 19, "Arc"), - LEFT_BRACKET(90, 85, "LeftBracket"), - RIGHT_BRACKET(91, 86, "RightBracket"), - LEFT_BRACE(92, 87, "LeftBrace"), - RIGHT_BRACE(93, 88, "RightBrace"), - BRACKET_PAIR(94, 185, "BracketPair"), - BRACE_PAIR(95, 186, "BracePair"), - STRAIGHT_CONNECTOR_1(96, 32, "StraightConnector1"), - BENT_CONNECTOR_2(97, 33, "BentConnector2"), - BENT_CONNECTOR_3(98, 34, "BentConnector3"), - BENT_CONNECTOR_4(99, 35, "BentConnector4"), - BENT_CONNECTOR_5(100, 36, "BentConnector5"), - CURVED_CONNECTOR_2(101, 37, "CurvedConnector2"), - CURVED_CONNECTOR_3(102, 38, "CurvedConnector3"), - CURVED_CONNECTOR_4(103, 39, "CurvedConnector4"), - CURVED_CONNECTOR_5(104, 40, "CurvedConnector5"), - CALLOUT_1(105, 41, "Callout1"), - CALLOUT_2(106, 42, "Callout2"), - CALLOUT_3(107, 43, "Callout3"), - ACCENT_CALLOUT_1(108, 44, "AccentCallout1"), - ACCENT_CALLOUT_2(109, 45, "AccentCallout2"), - ACCENT_CALLOUT_3(110, 46, "AccentCallout3"), - BORDER_CALLOUT_1(111, 47, "BorderCallout1"), - BORDER_CALLOUT_2(112, 48, "BorderCallout2"), - BORDER_CALLOUT_3(113, 49, "BorderCallout3"), - ACCENT_BORDER_CALLOUT_1(114, 50, "AccentBorderCallout1"), - ACCENT_BORDER_CALLOUT_2(115, 51, "AccentBorderCallout2"), - ACCENT_BORDER_CALLOUT_3(116, 52, "AccentBorderCallout3"), - WEDGE_RECT_CALLOUT(117, 61, "WedgeRectCallout"), - WEDGE_ROUND_RECT_CALLOUT(118, 62, "WedgeRRectCallout"), - WEDGE_ELLIPSE_CALLOUT(119, 63, "WedgeEllipseCallout"), - CLOUD_CALLOUT(120, 106, "CloudCallout"), - CLOUD(121, -1, null), - RIBBON(122, 53, "Ribbon"), - RIBBON_2(123, 54, "Ribbon2"), - ELLIPSE_RIBBON(124, 107, "EllipseRibbon"), - ELLIPSE_RIBBON_2(125, 108, "EllipseRibbon2"), - LEFT_RIGHT_RIBBON(126, -1, null), - VERTICAL_SCROLL(127, 97, "VerticalScroll"), - HORIZONTAL_SCROLL(128, 98, "HorizontalScroll"), - WAVE(129, 64, "Wave"), - DOUBLE_WAVE(130, 188, "DoubleWave"), - PLUS(131, 11, "Plus"), - FLOW_CHART_PROCESS(132, 109, "FlowChartProcess"), - FLOW_CHART_DECISION(133, 110, "FlowChartDecision"), - FLOW_CHART_INPUT_OUTPUT(134, 111, "FlowChartInputOutput"), - FLOW_CHART_PREDEFINED_PROCESS(135, 112, "FlowChartPredefinedProcess"), - FLOW_CHART_INTERNAL_STORAGE(136, 113, "FlowChartInternalStorage"), - FLOW_CHART_DOCUMENT(137, 114, "FlowChartDocument"), - FLOW_CHART_MULTIDOCUMENT(138, 115, "FlowChartMultidocument"), - FLOW_CHART_TERMINATOR(139, 116, "FlowChartTerminator"), - FLOW_CHART_PREPARATION(140, 117, "FlowChartPreparation"), - FLOW_CHART_MANUAL_INPUT(141, 118, "FlowChartManualInput"), - FLOW_CHART_MANUAL_OPERATION(142, 119, "FlowChartManualOperation"), - FLOW_CHART_CONNECTOR(143, 120, "FlowChartConnector"), - FLOW_CHART_PUNCHED_CARD(144, 121, "FlowChartPunchedCard"), - FLOW_CHART_PUNCHED_TAPE(145, 122, "FlowChartPunchedTape"), - FLOW_CHART_SUMMING_JUNCTION(146, 123, "FlowChartSummingJunction"), - FLOW_CHART_OR(147, 124, "FlowChartOr"), - FLOW_CHART_COLLATE(148, 125, "FlowChartCollate"), - FLOW_CHART_SORT(149, 126, "FlowChartSort"), - FLOW_CHART_EXTRACT(150, 127, "FlowChartExtract"), - FLOW_CHART_MERGE(151, 128, "FlowChartMerge"), - FLOW_CHART_OFFLINE_STORAGE(152, 129, "FlowChartOfflineStorage"), - FLOW_CHART_ONLINE_STORAGE(153, 130, "FlowChartOnlineStorage"), - FLOW_CHART_MAGNETIC_TAPE(154, 131, "FlowChartMagneticTape"), - FLOW_CHART_MAGNETIC_DISK(155, 132, "FlowChartMagneticDisk"), - FLOW_CHART_MAGNETIC_DRUM(156, 133, "FlowChartMagneticDrum"), - FLOW_CHART_DISPLAY(157, 134, "FlowChartDisplay"), - FLOW_CHART_DELAY(158, 135, "FlowChartDelay"), - FLOW_CHART_ALTERNATE_PROCESS(159, 176, "FlowChartAlternateProcess"), - FLOW_CHART_OFFPAGE_CONNECTOR(160, 177, "FlowChartOffpageConnector"), - ACTION_BUTTON_BLANK(161, 189, "ActionButtonBlank"), - ACTION_BUTTON_HOME(162, 190, "ActionButtonHome"), - ACTION_BUTTON_HELP(163, 191, "ActionButtonHelp"), - ACTION_BUTTON_INFORMATION(164, 192, "ActionButtonInformation"), - ACTION_BUTTON_FORWARD_NEXT(165, 193, "ActionButtonForwardNext"), - ACTION_BUTTON_BACK_PREVIOUS(166, 194, "ActionButtonBackPrevious"), - ACTION_BUTTON_END(167, 195, "ActionButtonEnd"), - ACTION_BUTTON_BEGINNING(168, 196, "ActionButtonBeginning"), - ACTION_BUTTON_RETURN(169, 197, "ActionButtonReturn"), - ACTION_BUTTON_DOCUMENT(170, 198, "ActionButtonDocument"), - ACTION_BUTTON_SOUND(171, 199, "ActionButtonSound"), - ACTION_BUTTON_MOVIE(172, 200, "ActionButtonMovie"), - GEAR_6(173, -1, null), - GEAR_9(174, -1, null), - FUNNEL(175, -1, null), - MATH_PLUS(176, -1, null), - MATH_MINUS(177, -1, null), - MATH_MULTIPLY(178, -1, null), - MATH_DIVIDE(179, -1, null), - MATH_EQUAL(180, -1, null), - MATH_NOT_EQUAL(181, -1, null), - CORNER_TABS(182, -1, null), - SQUARE_TABS(183, -1, null), - PLAQUE_TABS(184, -1, null), - CHART_X(185, -1, null), - CHART_STAR(186, -1, null), - CHART_PLUS(187, -1, null), - // below are shape types only found in native - NOTCHED_CIRCULAR_ARROW(-1, 100, "NotchedCircularArrow"), - THICK_ARROW(-1, 14, "ThickArrow"), - BALLOON(-1, 17, "Balloon"), - TEXT_SIMPLE(-1, 24, "TextSimple"), - TEXT_OCTAGON(-1, 25, "TextOctagon"), - TEXT_HEXAGON(-1, 26, "TextHexagon"), - TEXT_CURVE(-1, 27, "TextCurve"), - TEXT_WAVE(-1, 28, "TextWave"), - TEXT_RING(-1, 29, "TextRing"), - TEXT_ON_CURVE(-1, 30, "TextOnCurve"), - TEXT_ON_RING(-1, 31, "TextOnRing"), - TEXT_PLAIN_TEXT(-1, 136, "TextPlainText"), - TEXT_STOP(-1, 137, "TextStop"), - TEXT_TRIANGLE(-1, 138, "TextTriangle"), - TEXT_TRIANGLE_INVERTED(-1, 139, "TextTriangleInverted"), - TEXT_CHEVRON(-1, 140, "TextChevron"), - TEXT_CHEVRON_INVERTED(-1, 141, "TextChevronInverted"), - TEXT_RING_INSIDE(-1, 142, "TextRingInside"), - TEXT_RING_OUTSIDE(-1, 143, "TextRingOutside"), - TEXT_ARCH_UP_CURVE(-1, 144, "TextArchUpCurve"), - TEXT_ARCH_DOWN_CURVE(-1, 145, "TextArchDownCurve"), - TEXT_CIRCLE_CURVE(-1, 146, "TextCircleCurve"), - TEXT_BUTTON_CURVE(-1, 147, "TextButtonCurve"), - TEXT_ARCH_UP_POUR(-1, 148, "TextArchUpPour"), - TEXT_ARCH_DOWN_POUR(-1, 149, "TextArchDownPour"), - TEXT_CIRCLE_POUR(-1, 150, "TextCirclePour"), - TEXT_BUTTON_POUR(-1, 151, "TextButtonPour"), - TEXT_CURVE_UP(-1, 152, "TextCurveUp"), - TEXT_CURVE_DOWN(-1, 153, "TextCurveDown"), - TEXT_CASCADE_UP(-1, 154, "TextCascadeUp"), - TEXT_CASCADE_DOWN(-1, 155, "TextCascadeDown"), - TEXT_WAVE_1(-1, 156, "TextWave1"), - TEXT_WAVE_2(-1, 157, "TextWave2"), - TEXT_WAVE_3(-1, 158, "TextWave3"), - TEXT_WAVE_4(-1, 159, "TextWave4"), - TEXT_INFLATE(-1, 160, "TextInflate"), - TEXT_DEFLATE(-1, 161, "TextDeflate"), - TEXT_INFLATE_BOTTOM(-1, 162, "TextInflateBottom"), - TEXT_DEFLATE_BOTTOM(-1, 163, "TextDeflateBottom"), - TEXT_INFLATE_TOP(-1, 164, "TextInflateTop"), - TEXT_DEFLATE_TOP(-1, 165, "TextDeflateTop"), - TEXT_DEFLATE_INFLATE(-1, 166, "TextDeflateInflate"), - TEXT_DEFLATE_INFLATE_DEFLATE(-1, 167, "TextDeflateInflateDeflate"), - TEXT_FADE_RIGHT(-1, 168, "TextFadeRight"), - TEXT_FADE_LEFT(-1, 169, "TextFadeLeft"), - TEXT_FADE_UP(-1, 170, "TextFadeUp"), - TEXT_FADE_DOWN(-1, 171, "TextFadeDown"), - TEXT_SLANT_UP(-1, 172, "TextSlantUp"), - TEXT_SLANT_DOWN(-1, 173, "TextSlantDown"), - TEXT_CAN_UP(-1, 174, "TextCanUp"), - TEXT_CAN_DOWN(-1, 175, "TextCanDown"), - CALLOUT_90(-1, 178, "Callout90"), - ACCENT_CALLOUT_90(-1, 179, "AccentCallout90"), - BORDER_CALLOUT_90(-1, 180, "BorderCallout90"), - ACCENT_BORDER_CALLOUT_90(-1, 181, "AccentBorderCallout90"), - HOST_CONTROL(-1, 201, "HostControl"), - TEXT_BOX(-1, 202, "TextBox") - ; - - /** Preset-ID for XML-based shapes */ - public final int ooxmlId; - - /** Preset-ID for binary-based shapes */ - public final int nativeId; - - /** POI-specific name for the binary-based type */ - public final String nativeName; - - ShapeType(int ooxmlId, int nativeId, String nativeName){ - this.ooxmlId = ooxmlId; - this.nativeId = nativeId; - this.nativeName = nativeName; - } - - /** name of the presetShapeDefinit(i)on entry */ - public String getOoxmlName() { - if (this == SEAL) return STAR_16.getOoxmlName(); - if (ooxmlId == -1) { - return (name().startsWith("TEXT")) ? RECT.getOoxmlName() : null; - } - - StringBuilder sb = new StringBuilder(); - boolean toLower = true; - for (char ch : name().toCharArray()) { - if (ch == '_') { - toLower = false; - continue; - } - sb.append(toLower ? Character.toLowerCase(ch) : Character.toUpperCase(ch)); - toLower = true; - } - - return sb.toString(); - } - - public static ShapeType forId(int id, boolean isOoxmlId){ - // exemption for #60294 - if (!isOoxmlId && id == 0x0FFF) { - return NOT_PRIMITIVE; - } - - for(ShapeType t : values()){ - if((isOoxmlId && t.ooxmlId == id) || - (!isOoxmlId && t.nativeId == id)) return t; - } - throw new IllegalArgumentException("Unknown shape type: " + id); - } -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Sheet.java b/trunk/src/java/org/apache/poi/sl/usermodel/Sheet.java deleted file mode 100644 index cd2a6f18c..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Sheet.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Graphics2D; - - -/** - * Common parent of Slides, Notes and Masters - */ -public interface Sheet< - S extends Shape, - P extends TextParagraph -> extends ShapeContainer { - SlideShow getSlideShow(); - - /** - * @return whether shapes on the master sheet should be shown. By default master graphics is turned off. - * Sheets that support the notion of master (slide, slideLayout) should override it and - * check this setting in the sheet XML - */ - boolean getFollowMasterGraphics(); - - MasterSheet getMasterSheet(); - - Background getBackground(); - - /** - * Convenience method to draw a sheet to a graphics context - * - * @param graphics - */ - void draw(Graphics2D graphics); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java deleted file mode 100644 index aee69fb73..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/SimpleShape.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Color; - -import org.apache.poi.sl.draw.geom.CustomGeometry; -import org.apache.poi.sl.draw.geom.IAdjustableShape; - - -public interface SimpleShape< - S extends Shape, - P extends TextParagraph -> extends Shape, IAdjustableShape, PlaceableShape { - - FillStyle getFillStyle(); - - LineDecoration getLineDecoration(); - - StrokeStyle getStrokeStyle(); - - /** - * Sets the line attributes. - * Possible attributes are Double (width), LineCap, LineDash, LineCompound, Color - * (implementations of PaintStyle aren't yet supported ...) - * - * If no styles are given, the line will be hidden - * - * @param styles the line attributes - */ - void setStrokeStyle(Object... styles); - - CustomGeometry getGeometry(); - - ShapeType getShapeType(); - void setShapeType(ShapeType type); - - /** - * @return the placeholder or null if none is assigned - * @see #setPlaceholder(Placeholder) - */ - Placeholder getPlaceholder(); - - /** - * Specifies that the corresponding shape should be represented by the generating application - * as a placeholder. When a shape is considered a placeholder by the generating application - * it can have special properties to alert the user that they may enter content into the shape. - * - * @param placeholder the placeholder or null to remove the reference to the placeholder - */ - void setPlaceholder(Placeholder placeholder); - - Shadow getShadow(); - - /** - * Returns the solid color fill. - * - * @return solid fill color of null if not set or fill color - * is not solid (pattern or gradient) - */ - Color getFillColor(); - - /** - * Specifies a solid color fill. The shape is filled entirely with the - * specified color. - * - * @param color the solid color fill. The value of null unsets - * the solid fill attribute from the underlying implementation - */ - void setFillColor(Color color); - - /** - * Returns the hyperlink assigned to this shape - * - * @return the hyperlink assigned to this shape - * or null if not found. - * - * @since POI 3.14-Beta1 - */ - Hyperlink getHyperlink(); - - /** - * Creates a hyperlink and asigns it to this shape. - * If the shape has already a hyperlink assigned, return it instead - * - * @return the hyperlink assigned to this shape - * - * @since POI 3.14-Beta1 - */ - Hyperlink createHyperlink(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java b/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java deleted file mode 100644 index dae2f42e6..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface Slide< - S extends Shape, - P extends TextParagraph -> extends Sheet { - Notes getNotes(); - void setNotes(Notes notes); - - boolean getFollowMasterBackground(); - void setFollowMasterBackground(boolean follow); - - boolean getFollowMasterColourScheme(); - void setFollowMasterColourScheme(boolean follow); - - boolean getFollowMasterObjects(); - void setFollowMasterObjects(boolean follow); - - /** - * @return the 1-based slide no. - */ - int getSlideNumber(); - - /** - * @return title of this slide or null if title is not set - */ - String getTitle(); - -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java b/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java deleted file mode 100644 index 228925d1c..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Dimension; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; - -import org.apache.poi.sl.usermodel.PictureData.PictureType; - -public interface SlideShow< - S extends Shape, - P extends TextParagraph -> extends Closeable { - Slide createSlide() throws IOException; - - List> getSlides(); - - MasterSheet createMasterSheet() throws IOException; - - /** - * Returns all slide masters. - * This doesn't include notes master and other arbitrary masters. - */ - List> getSlideMasters(); - - Resources getResources(); - - /** - * Returns the current page size - * - * @return the page size - */ - Dimension getPageSize(); - - /** - * Change the current page size - * - * @param pgsize page size (in points) - */ - void setPageSize(Dimension pgsize); - - /** - * Returns all Pictures of this slideshow. - * The returned {@link List} is unmodifiable. - * @return a {@link List} of {@link PictureData}. - */ - List getPictureData(); - - /** - * Adds a picture to the presentation. - * - * @param pictureData The bytes of the picture - * @param format The format of the picture. - * - * @return the picture data reference. - */ - PictureData addPicture(byte[] pictureData, PictureType format) throws IOException; - - /** - * Adds a picture to the presentation. - * - * @param is The stream to read the image from - * @param format The format of the picture. - * - * @return the picture data reference. - * @since 3.15 beta 1 - */ - PictureData addPicture(InputStream is, PictureType format) throws IOException; - - /** - * Adds a picture to the presentation. - * - * @param pict The file containing the image to add - * @param format The format of the picture. - * - * @return the picture data reference - * @since 3.15 beta 1 - */ - PictureData addPicture(File pict, PictureType format) throws IOException; - - /** - * check if a picture with this picture data already exists in this presentation - * - * @param pictureData The picture data to find in the SlideShow - * @return {@code null} if picture data is not found in this slideshow - * @since 3.15 beta 3 - */ - PictureData findPictureData(byte[] pictureData); - - /** - * Writes out the slideshow file the is represented by an instance of this - * class - * - * @param out - * The OutputStream to write to. - * @throws IOException - * If there is an unexpected IOException from the passed in - * OutputStream - */ - void write(OutputStream out) throws IOException; -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java b/trunk/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java deleted file mode 100644 index db23e1de0..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java +++ /dev/null @@ -1,265 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.sl.usermodel; - -import java.io.*; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.OldFileFormatException; -import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OfficeXmlFileException; -import org.apache.poi.util.IOUtils; - -public class SlideShowFactory { - /** - * Creates a SlideShow from the given NPOIFSFileSystem. - * - * @param fs The {@link NPOIFSFileSystem} to read the document from - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - */ - public static SlideShow create(NPOIFSFileSystem fs) throws IOException { - return create(fs, null); - } - - /** - * Creates a SlideShow from the given NPOIFSFileSystem, which may - * be password protected - * - * @param fs The {@link NPOIFSFileSystem} to read the document from - * @param password The password that should be used or null if no password is necessary. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - */ - public static SlideShow create(final NPOIFSFileSystem fs, String password) throws IOException { - DirectoryNode root = fs.getRoot(); - - // Encrypted OOXML files go inside OLE2 containers, is this one? - if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { - InputStream stream = null; - try { - stream = DocumentFactoryHelper.getDecryptedStream(fs, password); - - return createXSLFSlideShow(stream); - } finally { - if (stream != null) stream.close(); - } - } - - // If we get here, it isn't an encrypted PPTX file - // So, treat it as a regular HSLF PPT one - if (password != null) { - Biff8EncryptionKey.setCurrentUserPassword(password); - } - try { - return createHSLFSlideShow(fs); - } finally { - Biff8EncryptionKey.setCurrentUserPassword(null); - } - } - - /** - * Creates the appropriate HSLFSlideShow / XMLSlideShow from - * the given InputStream. - * - *

    Your input stream MUST either support mark/reset, or - * be wrapped as a {@link PushbackInputStream}! Note that - * using an {@link InputStream} has a higher memory footprint - * than using a {@link File}.

    - * - *

    Note that in order to properly release resources the - * SlideShow should be closed after use. Note also that loading - * from an InputStream requires more memory than loading - * from a File, so prefer {@link #create(File)} where possible. - * - * @param inp The {@link InputStream} to read data from. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws EncryptedDocumentException If the SlideShow given is password protected - */ - public static SlideShow create(InputStream inp) throws IOException, EncryptedDocumentException { - return create(inp, null); - } - - /** - * Creates the appropriate HSLFSlideShow / XMLSlideShow from - * the given InputStream, which may be password protected. - *

    Your input stream MUST either support mark/reset, or - * be wrapped as a {@link PushbackInputStream}! Note that - * using an {@link InputStream} has a higher memory footprint - * than using a {@link File}.

    - * - *

    Note that in order to properly release resources the - * SlideShow should be closed after use. Note also that loading - * from an InputStream requires more memory than loading - * from a File, so prefer {@link #create(File)} where possible.

    - * - * @param inp The {@link InputStream} to read data from. - * @param password The password that should be used or null if no password is necessary. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws EncryptedDocumentException If the wrong password is given for a protected file - */ - public static SlideShow create(InputStream inp, String password) throws IOException, EncryptedDocumentException { - // If clearly doesn't do mark/reset, wrap up - if (! inp.markSupported()) { - inp = new PushbackInputStream(inp, 8); - } - - // Ensure that there is at least some data there - byte[] header8 = IOUtils.peekFirst8Bytes(inp); - - // Try to create - if (NPOIFSFileSystem.hasPOIFSHeader(header8)) { - NPOIFSFileSystem fs = new NPOIFSFileSystem(inp); - return create(fs, password); - } - if (DocumentFactoryHelper.hasOOXMLHeader(inp)) { - return createXSLFSlideShow(inp); - } - throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream"); - } - - /** - * Creates the appropriate HSLFSlideShow / XMLSlideShow from - * the given File, which must exist and be readable. - *

    Note that in order to properly release resources the - * SlideShow should be closed after use. - * - * @param file The file to read data from. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws EncryptedDocumentException If the SlideShow given is password protected - */ - public static SlideShow create(File file) throws IOException, EncryptedDocumentException { - return create(file, null); - } - - /** - * Creates the appropriate HSLFSlideShow / XMLSlideShow from - * the given File, which must exist and be readable, and - * may be password protected - *

    Note that in order to properly release resources the - * SlideShow should be closed after use. - * - * @param file The file to read data from. - * @param password The password that should be used or null if no password is necessary. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws EncryptedDocumentException If the wrong password is given for a protected file - */ - public static SlideShow create(File file, String password) throws IOException, EncryptedDocumentException { - return create(file, password, false); - } - - /** - * Creates the appropriate HSLFSlideShow / XMLSlideShow from - * the given File, which must exist and be readable, and - * may be password protected - *

    Note that in order to properly release resources the - * SlideShow should be closed after use. - * - * @param file The file to read data from. - * @param password The password that should be used or null if no password is necessary. - * @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back - * changes when the document is closed. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws EncryptedDocumentException If the wrong password is given for a protected file - */ - public static SlideShow create(File file, String password, boolean readOnly) throws IOException, EncryptedDocumentException { - if (!file.exists()) { - throw new FileNotFoundException(file.toString()); - } - - NPOIFSFileSystem fs = null; - try { - fs = new NPOIFSFileSystem(file, readOnly); - return create(fs, password); - } catch(OfficeXmlFileException e) { - if(fs != null) { - fs.close(); - } - return createXSLFSlideShow(file, readOnly); - } catch(RuntimeException e) { - if(fs != null) { - fs.close(); - } - throw e; - } - } - - protected static SlideShow createHSLFSlideShow(Object... args) throws IOException, EncryptedDocumentException { - return createSlideShow("org.apache.poi.hslf.usermodel.HSLFSlideShowFactory", args); - } - - protected static SlideShow createXSLFSlideShow(Object... args) throws IOException, EncryptedDocumentException { - return createSlideShow("org.apache.poi.xslf.usermodel.XSLFSlideShowFactory", args); - } - - protected static SlideShow createSlideShow(String factoryClass, Object args[]) throws IOException, EncryptedDocumentException { - try { - Class clazz = Thread.currentThread().getContextClassLoader().loadClass(factoryClass); - Class argsClz[] = new Class[args.length]; - int i=0; - for (Object o : args) { - Class c = o.getClass(); - if (Boolean.class.isAssignableFrom(c)) { - c = boolean.class; - } else if (InputStream.class.isAssignableFrom(c)) { - c = InputStream.class; - } - argsClz[i++] = c; - } - Method m = clazz.getMethod("createSlideShow", argsClz); - return (SlideShow)m.invoke(null, args); - } catch (InvocationTargetException e) { - Throwable t = e.getCause(); - if (t instanceof IOException) { - throw (IOException)t; - } else if (t instanceof EncryptedDocumentException) { - throw (EncryptedDocumentException)t; - } else if (t instanceof OldFileFormatException) { - throw (OldFileFormatException)t; - } else { - throw new IOException(t); - } - } catch (Exception e) { - throw new IOException(e); - } - } -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java b/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java deleted file mode 100644 index be93a994d..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java +++ /dev/null @@ -1,147 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface StrokeStyle { - enum LineCap { - /** Rounded ends */ - ROUND(0,1), - /** Square protrudes by half line width */ - SQUARE(1,2), - /** Line ends at end point*/ - FLAT(2,3); - - public final int nativeId; - public final int ooxmlId; - - LineCap(int nativeId, int ooxmlId) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - } - - public static LineCap fromNativeId(int nativeId) { - for (LineCap ld : values()) { - if (ld.nativeId == nativeId) return ld; - } - return null; - } - - public static LineCap fromOoxmlId(int ooxmlId) { - for (LineCap lc : values()) { - if (lc.ooxmlId == ooxmlId) return lc; - } - return null; - } - } - - /** - * The line dash with pattern. - * The pattern is derived empirically on PowerPoint 2010 and needs to be multiplied - * with actual line width - */ - enum LineDash { - /** Solid (continuous) pen - native 1 */ - SOLID(1, 1, null), - /** square dot style - native 6 */ - DOT(6, 2, 1,1), - /** dash style - native 7 */ - DASH(7, 3, 3,4), - /** dash short dash - native 9*/ - DASH_DOT(9, 5, 4,3,1,3), - /** long dash style - native 8 */ - LG_DASH(8, 4, 8,3), - /** long dash short dash - native 10 */ - LG_DASH_DOT(10, 6, 8,3,1,3), - /** long dash short dash short dash - native 11 */ - LG_DASH_DOT_DOT(11, 7, 8,3,1,3,1,3), - /** PS_DASH system dash style - native 2 */ - SYS_DASH(2, 8, 2,2), - /** PS_DOT system dash style - native 3 */ - SYS_DOT(3, 9, 1,1), - /** PS_DASHDOT system dash style - native 4 */ - SYS_DASH_DOT(4, 10, 2,2,1,1), - /** PS_DASHDOTDOT system dash style / native 5 */ - SYS_DASH_DOT_DOT(5, 11, 2,2,1,1,1,1); - - public final int pattern[]; - public final int nativeId; - public final int ooxmlId; - - LineDash(int nativeId, int ooxmlId, int... pattern) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - this.pattern = (pattern == null || pattern.length == 0) ? null : pattern; - } - - public static LineDash fromNativeId(int nativeId) { - for (LineDash ld : values()) { - if (ld.nativeId == nativeId) return ld; - } - return null; - } - - public static LineDash fromOoxmlId(int ooxmlId) { - for (LineDash ld : values()) { - if (ld.ooxmlId == ooxmlId) return ld; - } - return null; - } - } - - enum LineCompound { - /** Single line (of width lineWidth) - native 0 / ooxml default */ - SINGLE(0, 1), - /** Double lines of equal width - native 1 / ooxml "dbl" */ - DOUBLE(1, 2), - /** Double lines, one thick, one thin - native 2 / ooxml "thickThin" */ - THICK_THIN(2, 3), - /** Double lines, reverse order - native 3 / ooxml "thinThick" */ - THIN_THICK(3, 4), - /** Three lines, thin, thick, thin - native 4 / ooxml "tri" */ - TRIPLE(4, 5); - - public final int nativeId; - public final int ooxmlId; - - LineCompound(int nativeId, int ooxmlId) { - this.nativeId = nativeId; - this.ooxmlId = ooxmlId; - } - - public static LineCompound fromNativeId(int nativeId) { - for (LineCompound lc : values()) { - if (lc.nativeId == nativeId) return lc; - } - return null; - } - - public static LineCompound fromOoxmlId(int ooxmlId) { - for (LineCompound lc : values()) { - if (lc.ooxmlId == ooxmlId) return lc; - } - return null; - } - } - - - PaintStyle getPaint(); - LineCap getLineCap(); - LineDash getLineDash(); - LineCompound getLineCompound(); - double getLineWidth(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/TableCell.java b/trunk/src/java/org/apache/poi/sl/usermodel/TableCell.java deleted file mode 100644 index 9516196de..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/TableCell.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Color; - -import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; - -public interface TableCell< - S extends Shape, - P extends TextParagraph -> extends TextShape { - enum BorderEdge { bottom, left, top, right } - - /** - * Return line style of given edge or {@code null} if border is not defined - * - * @param edge the border edge - * @return line style of given edge or {@code null} if border is not defined - */ - StrokeStyle getBorderStyle(BorderEdge edge); - - /** - * Sets the {@link StrokeStyle} of the given border edge. - * A {@code null} property of the style is ignored. - * - * @param edge border edge - * @param style the new stroke style - */ - void setBorderStyle(BorderEdge edge, StrokeStyle style); - - /** - * Convenience method for setting the border width. - * - * @param edge border edge - * @param width the new border width - */ - void setBorderWidth(BorderEdge edge, double width); - - /** - * Convenience method for setting the border color. - * - * @param edge border edge - * @param color the new border color - */ - void setBorderColor(BorderEdge edge, Color color); - - /** - * Convenience method for setting the border line compound. - * - * @param edge border edge - * @param compound the new border line compound - */ - void setBorderCompound(BorderEdge edge, LineCompound compound); - - /** - * Convenience method for setting the border line dash. - * - * @param edge border edge - * @param dash the new border line dash - */ - void setBorderDash(BorderEdge edge, LineDash dash); - - /** - * Remove all line attributes of the given border edge - * - * @param edge the border edge to be cleared - */ - void removeBorder(BorderEdge edge); - - /** - * Get the number of columns to be spanned/merged - * - * @return the grid span - * - * @since POI 3.15-beta2 - */ - int getGridSpan(); - - /** - * Get the number of rows to be spanned/merged - * - * @return the row span - * - * @since POI 3.15-beta2 - */ - int getRowSpan(); - - /** - * Return if this cell is part of a merged cell. The top/left cell of a merged region is not regarded as merged - - * its grid and/or row span is greater than one. - * - * @return true if this a merged cell - * - * @since POI 3.15-beta2 - */ - boolean isMerged(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/TableShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/TableShape.java deleted file mode 100644 index 13c5d0dc5..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/TableShape.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -public interface TableShape< - S extends Shape, - P extends TextParagraph -> extends Shape, PlaceableShape { - /** - * Return the maximum number of columns. - * If the table contains merged cells, the number of columns might be less than the maximum. - * - * @return the maximum number of column - */ - int getNumberOfColumns(); - - /** - * Return the number of rows - * - * @return the row count - */ - int getNumberOfRows(); - - /** - * Gets a cell - * - * @param row the row index (0-based) - * @param col the column index (0-based) - * @return the cell or null if the cell doesn't exists, e.g. when accessing - * a merged cell or if the index is out of bounds - */ - TableCell getCell(int row, int col); - - /** - * Gets the width (in points) of the n-th column - * - * @param idx the column index (0-based) - * @return the width (in points) - */ - double getColumnWidth(int idx); - - /** - * Sets the width (in points) of the n-th column - * - * @param idx the column index (0-based) - * @param width the width (in points) - */ - void setColumnWidth(int idx, double width); - - /** - * Gets the row height - * - * @param row the row index (0-based) - * @return the height (in points) - */ - double getRowHeight(int row); - - /** - * Sets the row height. - * - * @param row the row index (0-based) - * @param height the height to set (in points) - */ - void setRowHeight(int row, double height); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/TextBox.java b/trunk/src/java/org/apache/poi/sl/usermodel/TextBox.java deleted file mode 100644 index bc6951103..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/TextBox.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -/** - * Represents a TextFrame shape in PowerPoint. - *

    - * Contains the text in a text frame as well as the properties and methods - * that control alignment and anchoring of the text. - *

    - */ -public interface TextBox< - S extends Shape, - P extends TextParagraph -> extends AutoShape { -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java b/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java deleted file mode 100644 index 881a71da9..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java +++ /dev/null @@ -1,377 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Color; -import java.util.List; - - - -public interface TextParagraph< - S extends Shape, - P extends TextParagraph, - T extends TextRun -> extends Iterable { - - /** - * Specifies a list of text alignment types - */ - public enum TextAlign { - /** - * For horizontal text, left aligned. - * For vertical text, top aligned. - */ - LEFT, - - /** - * For horizontal text, centered. - * For vertical text, middle aligned. - */ - CENTER, - - /** - * For horizontal text, right aligned. - * For vertical text, bottom aligned. - */ - RIGHT, - - /** - * Align text so that it is justified across the whole line. It - * is smart in the sense that it will not justify sentences - * which are short - * - * For horizontal text, flush left and right. - * For vertical text, flush top and bottom. - */ - JUSTIFY, - - /** - * Kashida justify low. - */ - JUSTIFY_LOW, - - /** - * Distribute space between characters. - */ - DIST, - - /** - * Thai distribution justification. - */ - THAI_DIST - } - - /** - * - */ - public enum FontAlign { - AUTO, - - /** - * Characters hang from top of line height. - * Also known as "Hanging" - */ - TOP, - - /** - * Characters centered within line height. - */ - CENTER, - - /** - * Place characters on font baseline. - * Also known as "Roman" - */ - BASELINE, - - /** - * Characters are anchored to the very bottom of a single line. - * This is different than BASELINE because of letters such as "g", "q", and "y". - * Also known as "UpholdFixed" - */ - BOTTOM - } - - public interface BulletStyle { - String getBulletCharacter(); - String getBulletFont(); - - /** - * The bullet point font size - * If bulletFontSize >= 0, then space is a percentage of normal line height. - * If bulletFontSize < 0, the absolute value in points - * - * @return the bullet point font size - */ - Double getBulletFontSize(); - - /** - * Convenience function to set a solid color - */ - void setBulletFontColor(Color color); - - void setBulletFontColor(PaintStyle color); - - /** - * - * @return the color of bullet characters within a given paragraph. - * A {@code null} value means to use the text font color. - */ - PaintStyle getBulletFontColor(); - - AutoNumberingScheme getAutoNumberingScheme(); - /** - * Index (1-based) of the first auto number value, or null if auto numbering scheme - * wasn't assigned. - */ - Integer getAutoNumberingStartAt(); - } - - /** - * The amount of vertical white space before the paragraph - * This may be specified in two different ways, percentage spacing and font point spacing: - *

    - * If spaceBefore >= 0, then space is a percentage of normal line height. - * If spaceBefore < 0, the absolute value in points - *

    - * - * @return the vertical white space before the paragraph, or null if unset - */ - Double getSpaceBefore(); - - /** - * Set the amount of vertical white space that will be present before the paragraph. - * This space is specified in either percentage or points: - *

    - * If spaceBefore >= 0, then space is a percentage of normal line height. - * If spaceBefore < 0, the absolute value of linespacing is the spacing in points - *

    - * Examples: - *
    
    -     *      // The paragraph will be formatted to have a spacing before the paragraph text.
    -     *      // The spacing will be 200% of the size of the largest text on each line
    -     *      paragraph.setSpaceBefore(200);
    -     *
    -     *      // The spacing will be a size of 48 points
    -     *      paragraph.setSpaceBefore(-48.0);
    -     * 
    - * - * @param spaceBefore the vertical white space before the paragraph, null to unset - */ - void setSpaceBefore(Double spaceBefore); - - /** - * The amount of vertical white space after the paragraph - * This may be specified in two different ways, percentage spacing and font point spacing: - *

    - * If spaceBefore >= 0, then space is a percentage of normal line height. - * If spaceBefore < 0, the absolute value of linespacing is the spacing in points - *

    - * - * @return the vertical white space after the paragraph or null, if unset - */ - Double getSpaceAfter(); - - /** - * Set the amount of vertical white space that will be present after the paragraph. - * This space is specified in either percentage or points: - *

    - * If spaceAfter >= 0, then space is a percentage of normal line height. - * If spaceAfter < 0, the absolute value of linespacing is the spacing in points - *

    - * Examples: - *
    
    -     *      // The paragraph will be formatted to have a spacing after the paragraph text.
    -     *      // The spacing will be 200% of the size of the largest text on each line
    -     *      paragraph.setSpaceAfter(200);
    -     *
    -     *      // The spacing will be a size of 48 points
    -     *      paragraph.setSpaceAfter(-48.0);
    -     * 
    - * - * @param spaceAfter the vertical white space after the paragraph, null to unset - */ - public void setSpaceAfter(Double spaceAfter); - - /** - * @return the left margin (in points) of the paragraph or null, if unset - */ - Double getLeftMargin(); - - /** - * Specifies the left margin of the paragraph. This is specified in addition to the text body - * inset and applies only to this text paragraph. That is the text body Inset and the LeftMargin - * attributes are additive with respect to the text position. - * - * @param leftMargin the left margin (in points) or null to unset - */ - void setLeftMargin(Double leftMargin); - - - /** - * Specifies the right margin of the paragraph. This is specified in addition to the text body - * inset and applies only to this text paragraph. That is the text body Inset and the RightMargin - * attributes are additive with respect to the text position. - * - * The right margin is not support and therefore ignored by the HSLF implementation. - * - * @return the right margin (in points) of the paragraph or null, if unset - */ - Double getRightMargin(); - - /** - * @param rightMargin the right margin (in points) of the paragraph - */ - void setRightMargin(Double rightMargin); - - /** - * @return the indent (in points) applied to the first line of text in the paragraph. - * or null, if unset - */ - Double getIndent(); - - /** - * Specifies the indent size that will be applied to the first line of text in the paragraph. - * - * @param indent the indent (in points) applied to the first line of text in the paragraph - */ - void setIndent(Double indent); - - - /** - * @return the text level of this paragraph (0-based). Default is 0. - */ - int getIndentLevel(); - - /** - * Specifies the particular level text properties that this paragraph will follow. - * The value for this attribute formats the text according to the corresponding level - * paragraph properties defined in the SlideMaster. - * - * @param level the level (0 ... 4) - */ - void setIndentLevel(int level); - - /** - * Returns the vertical line spacing that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

    - * If linespacing >= 0, then linespacing is a percentage of normal line height. - * If linespacing < 0, the absolute value of linespacing is the spacing in points - *

    - * - * @return the vertical line spacing or null, if unset - */ - Double getLineSpacing(); - - /** - * This element specifies the vertical line spacing that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

    - * If linespacing >= 0, then linespacing is a percentage of normal line height - * If linespacing < 0, the absolute value of linespacing is the spacing in points - *

    - * Examples: - *
    
    -     *      // spacing will be 120% of the size of the largest text on each line
    -     *      paragraph.setLineSpacing(120);
    -     *
    -     *      // spacing will be 200% of the size of the largest text on each line
    -     *      paragraph.setLineSpacing(200);
    -     *
    -     *      // spacing will be 48 points
    -     *      paragraph.setLineSpacing(-48.0);
    -     * 
    - * - * @param lineSpacing the vertical line spacing - */ - void setLineSpacing(Double lineSpacing); - - String getDefaultFontFamily(); - - /** - * @return the default font size, in case its not set in the textrun or null, if unset - */ - Double getDefaultFontSize(); - - /** - * Returns the alignment that is applied to the paragraph. - * - * If this attribute is omitted, then null is returned. - * User code can imply the value {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign#LEFT} then. - * - * @return alignment that is applied to the paragraph - */ - TextAlign getTextAlign(); - - /** - * Specifies the alignment that is to be applied to the paragraph. - * Possible values for this include left, right, centered, justified and distributed, - * see {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign}. - * - * @param align text align - */ - void setTextAlign(TextAlign align); - - /** - * Returns the font alignment that is applied to the paragraph. - * - * If this attribute is omitted, then null is return, - * user code can imply the a value of {@link FontAlign#AUTO} - * - * @return alignment that is applied to the paragraph - */ - FontAlign getFontAlign(); - - /** - * @return the bullet style of the paragraph, if {@code null} then no bullets are used - */ - BulletStyle getBulletStyle(); - - /** - * Sets the bullet styles. If no styles are given, the bullets are omitted. - * Possible attributes are integer/double (bullet size), Color (bullet color), - * character (bullet character), string (bullet font), AutoNumberingScheme - * - * @param styles - */ - void setBulletStyle(Object... styles); - - /** - * @return the default size for a tab character within this paragraph in points, null if unset - */ - Double getDefaultTabSize(); - - - TextShape getParentShape(); - - /** - * Fetch the text runs that are contained within this block of text - */ - List getTextRuns(); - - /** - * Convenience method to determine if this text paragraph is part of - * the slide header or footer - * - * @return true if this paragraph is part of a header or footer placeholder - * - * @since POI 3.15-beta2 - */ - boolean isHeaderOrFooter(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java b/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java deleted file mode 100644 index 014d3036b..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java +++ /dev/null @@ -1,179 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.awt.Color; - -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; - -/** - * Some text. - */ -public interface TextRun { - enum TextCap { - NONE, - SMALL, - ALL - } - - String getRawText(); - void setText(String text); - - TextCap getTextCap(); - - /** - * Returns the font color. - * This usually returns a {@link SolidPaint}, but but also other classes are possible - * - * @return the font color/paint - * - * @see org.apache.poi.sl.draw.DrawPaint#getPaint(java.awt.Graphics2D, PaintStyle) - * @see SolidPaint#getSolidColor() - * @see org.apache.poi.sl.draw.DrawPaint#applyColorTransform(ColorStyle) - */ - PaintStyle getFontColor(); - - /** - * Sets the (solid) font color - convenience function - * - * @param color the color - */ - void setFontColor(Color color); - - /** - * Sets the font color - * - * @param color the color - * - * @see org.apache.poi.sl.draw.DrawPaint#createSolidPaint(Color) - */ - void setFontColor(PaintStyle color); - - - /** - * Returns the font size which is either set directly on this text run or - * given from the slide layout - * - * @return font size in points or null if font size is not set. - */ - Double getFontSize(); - - /** - * Sets the font size directly on this text run, if null is given, the - * font size defaults to the values given from the slide layout - * - * @param fontSize font size in points, if null the underlying fontsize will be unset - */ - void setFontSize(Double fontSize); - - /** - * @return font family or null if not set - */ - String getFontFamily(); - - /** - * Specifies the typeface, or name of the font that is to be used for this text run. - * - * @param typeface the font to apply to this text run. - * The value of null unsets the Typeface attrubute from the underlying xml. - */ - void setFontFamily(String typeface); - - /** - * @return true, if text is bold - */ - boolean isBold(); - - /** - * Sets the bold state - * - * @param bold set to true for bold text, false for normal weight - */ - void setBold(boolean bold); - - /** - * @return true, if text is italic - */ - boolean isItalic(); - - /** - * Sets the italic state - * - * @param italic set to true for italic text, false for non-italics - */ - void setItalic(boolean italic); - - /** - * @return true, if text is underlined - */ - boolean isUnderlined(); - - /** - * Sets the underlined state - * - * @param underlined set to true for underlined text, false for no underlining - */ - void setUnderlined(boolean underlined); - - /** - * @return true, if text is stroked - */ - boolean isStrikethrough(); - - /** - * Sets the strikethrough state - * - * @param stroked set to true for stroked text, false for no stroking - */ - void setStrikethrough(boolean stroked); - - /** - * @return true, if text is sub scripted - */ - boolean isSubscript(); - - /** - * @return true, if text is super scripted - */ - boolean isSuperscript(); - - /** - * @return the pitch and family id or -1 if not applicable - */ - byte getPitchAndFamily(); - - /** - * Return the associated hyperlink - * - * @return the associated hyperlink or null if no hyperlink was set - * - * @since POI 3.14-Beta2 - */ - Hyperlink getHyperlink(); - - - /** - * Creates a new hyperlink and assigns it to this text run. - * If the text run has already a hyperlink assigned, return it instead - * - * @return the associated hyperlink - * - * @since POI 3.14-Beta2 - */ - Hyperlink createHyperlink(); -} diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/TextShape.java b/trunk/src/java/org/apache/poi/sl/usermodel/TextShape.java deleted file mode 100644 index 45bd63e0d..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/TextShape.java +++ /dev/null @@ -1,258 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.util.List; - -public interface TextShape< - S extends Shape, - P extends TextParagraph -> extends SimpleShape, Iterable

    { - /** - * Vertical Text Types - */ - enum TextDirection { - /** - * Horizontal text. This should be default. - */ - HORIZONTAL, - /** - * Vertical orientation. - * (each line is 90 degrees rotated clockwise, so it goes - * from top to bottom; each next line is to the left from - * the previous one). - */ - VERTICAL, - /** - * Vertical orientation. - * (each line is 270 degrees rotated clockwise, so it goes - * from bottom to top; each next line is to the right from - * the previous one). - * For HSLF: always interpreted by Powerpoint as HORIZONTAL. - */ - VERTICAL_270, - /** - * Determines if all of the text is vertical - * ("one letter on top of another"). - * For HSLF: not supported - */ - STACKED - } - - /** - * Specifies alist of auto-fit types. - *

    - * Autofit specofies that a shape should be auto-fit to fully contain the text described within it. - * Auto-fitting is when text within a shape is scaled in order to contain all the text inside - *

    - */ - enum TextAutofit { - /** - * Specifies that text within the text body should not be auto-fit to the bounding box. - * Auto-fitting is when text within a text box is scaled in order to remain inside - * the text box. - */ - NONE, - /** - * Specifies that text within the text body should be normally auto-fit to the bounding box. - * Autofitting is when text within a text box is scaled in order to remain inside the text box. - * - *

    - * Example: Consider the situation where a user is building a diagram and needs - * to have the text for each shape that they are using stay within the bounds of the shape. - * An easy way this might be done is by using NORMAL autofit - *

    - */ - NORMAL, - /** - * Specifies that a shape should be auto-fit to fully contain the text described within it. - * Auto-fitting is when text within a shape is scaled in order to contain all the text inside. - * - *

    - * Example: Consider the situation where a user is building a diagram and needs to have - * the text for each shape that they are using stay within the bounds of the shape. - * An easy way this might be done is by using SHAPE autofit - *

    - */ - SHAPE - } - - /** - * This enum represents a compromise for the handling of - * HSLF run types (see org.apache.poi.hslf.record.TextHeaderAtom) and - * XSLF placeholders (see org.apache.poi.xslf.usermodel.Placeholder). - * When a shape is considered a placeholder by the generating application - * it can have special properties to alert the user that they may enter content into the shape. - * - * This enum and the handling around it may change significantly in future releases - */ - enum TextPlaceholder { - /** Title placeholder shape text */ - TITLE, - /** Body placeholder shape text */ - BODY, - /** Center title placeholder shape text */ - CENTER_TITLE, - /** Center body placeholder shape text */ - CENTER_BODY, - /** Half-sized body placeholder shape text */ - HALF_BODY, - /** Quarter-sized body placeholder shape text */ - QUARTER_BODY, - /** Notes placeholder shape text */ - NOTES, - /** Any other text */ - OTHER - } - - /** - * Returns the text contained in this text frame, which has been made safe - * for printing and other use. - * - * @return the text string for this textbox. - * - * @since POI 3.14-Beta2 - */ - String getText(); - - /** - * Sets (overwrites) the current text. - * Uses the properties of the first paragraph / textrun. - * Text paragraphs are split by \\r or \\n. - * New lines within text run are split by \\u000b - * - * @param text the text string used by this object. - * - * @return the last text run of the - potential split - text - */ - TextRun setText(String text); - - /** - * Adds the supplied text onto the end of the TextParagraphs, - * creating a new RichTextRun for it to sit in. - * - * @param text the text string to be appended. - * @param newParagraph if true, a new paragraph will be added, - * which will contain the added text - * - * @since POI 3.14-Beta1 - */ - TextRun appendText(String text, boolean newParagraph); - - /** - * @return the TextParagraphs for this text box - */ - List> getTextParagraphs(); - - /** - * @return text shape margin - */ - Insets2D getInsets(); - - /** - * Sets the shape margins - * - * @param insets the new shape margins - */ - void setInsets(Insets2D insets); - - /** - * Compute the cumulative height occupied by the text - */ - double getTextHeight(); - - /** - * Returns the type of vertical alignment for the text. - * - * @return the type of vertical alignment - */ - VerticalAlignment getVerticalAlignment(); - - /** - * Sets the type of vertical alignment for the text. - * - * @param vAlign - the type of alignment. - * A {@code null} values unsets this property. - */ - void setVerticalAlignment(VerticalAlignment vAlign); - - /** - * Returns if the text is centered. - * If true and if the individual paragraph settings allow it, - * the whole text block will be displayed centered, i.e. its left and right - * margin will be maximized while still keeping the alignment of the paragraphs - * - * @return true, if the text anchor is horizontal centered - */ - boolean isHorizontalCentered(); - - /** - * Sets if the paragraphs are horizontal centered - * - * @param isCentered true, if the paragraphs are horizontal centered - * A {@code null} values unsets this property. - */ - void setHorizontalCentered(Boolean isCentered); - - /** - * @return whether to wrap words within the bounding rectangle - */ - boolean getWordWrap(); - - /** - * @param wrap whether to wrap words within the bounding rectangle - */ - void setWordWrap(boolean wrap); - - /** - * @return vertical orientation of the text - */ - TextDirection getTextDirection(); - - /** - * sets the vertical orientation - * @param orientation vertical orientation of the text - */ - void setTextDirection(TextDirection orientation); - - /** - * The text rotation can be independent specified from the shape rotation. - * For XSLF this can be an arbitrary degree, for HSLF the degree is given in steps of 90 degrees - * - * @return text rotation in degrees, returns null if no rotation is given - */ - Double getTextRotation(); - - /** - * Sets the text rotation. - * For XSLF this can ben an arbitrary degree, for HSLF the rotation is rounded to next 90 degree step - * - * @param rotation the text rotation, or null to unset the rotation - */ - void setTextRotation(Double rotation); - - /** - * Sets the text placeholder - */ - void setTextPlaceholder(TextPlaceholder placeholder); - - /** - * @return the text placeholder - */ - TextPlaceholder getTextPlaceholder(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/sl/usermodel/VerticalAlignment.java b/trunk/src/java/org/apache/poi/sl/usermodel/VerticalAlignment.java deleted file mode 100644 index a38da00bf..000000000 --- a/trunk/src/java/org/apache/poi/sl/usermodel/VerticalAlignment.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.sl.usermodel; - -/** - * Specifies a list of available anchoring types for text - * - * - * - * @author Yegor Kozlov - */ -public enum VerticalAlignment { - /** - * Anchor the text at the top of the bounding rectangle - */ - TOP, - - /** - * Anchor the text at the middle of the bounding rectangle - */ - MIDDLE, - - /** - * Anchor the text at the bottom of the bounding rectangle. - */ - BOTTOM, - - /** - * Anchor the text so that it is justified vertically. - *

    - * When text is horizontal, this spaces out the actual lines of - * text and is almost always identical in behavior to - * {@link #DISTRIBUTED} (special case: if only 1 line, then anchored at top). - *

    - *

    - * When text is vertical, then it justifies the letters - * vertically. This is different than {@link #DISTRIBUTED}, - * because in some cases such as very little text in a line, - * it will not justify. - *

    - */ - JUSTIFIED, - - /** - * Anchor the text so that it is distributed vertically. - *

    - * When text is horizontal, this spaces out the actual lines - * of text and is almost always identical in behavior to - * {@link #JUSTIFIED} (special case: if only 1 line, then anchored in middle). - *

    - *

    - * When text is vertical, then it distributes the letters vertically. - * This is different than {@link #JUSTIFIED}, because it always forces distribution - * of the words, even if there are only one or two words in a line. - */ - DISTRIBUTED -} diff --git a/trunk/src/java/org/apache/poi/ss/SpreadsheetVersion.java b/trunk/src/java/org/apache/poi/ss/SpreadsheetVersion.java deleted file mode 100644 index 200175d04..000000000 --- a/trunk/src/java/org/apache/poi/ss/SpreadsheetVersion.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss; - -import org.apache.poi.ss.util.CellReference; - -/** - * This enum allows spreadsheets from multiple Excel versions to be handled by the common code. - *

    Properties of this enum correspond to attributes of the spreadsheet that are easily - * discernable to the user. It is not intended to deal with low-level issues like file formats. - */ -public enum SpreadsheetVersion { - /** - * Excel97 format aka BIFF8 - *

      - *
    • The total number of available rows is 64k (2^16)
    • - *
    • The total number of available columns is 256 (2^8)
    • - *
    • The maximum number of arguments to a function is 30
    • - *
    • Number of conditional format conditions on a cell is 3
    • - *
    • Number of cell styles is 4000
    • - *
    • Length of text cell contents is 32767
    • - *
    - */ - EXCEL97(0x10000, 0x0100, 30, 3, 4000, 32767), - - /** - * Excel2007 - * - *
      - *
    • The total number of available rows is 1M (2^20)
    • - *
    • The total number of available columns is 16K (2^14)
    • - *
    • The maximum number of arguments to a function is 255
    • - *
    • Number of conditional format conditions on a cell is unlimited - * (actually limited by available memory in Excel)
    • - *
    • Number of cell styles is 64000
    • - *
    • Length of text cell contents is 32767
    • - *
        - */ - EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 64000, 32767); - - private final int _maxRows; - private final int _maxColumns; - private final int _maxFunctionArgs; - private final int _maxCondFormats; - private final int _maxCellStyles; - private final int _maxTextLength; - - private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats, int maxCellStyles, int maxText) { - _maxRows = maxRows; - _maxColumns = maxColumns; - _maxFunctionArgs = maxFunctionArgs; - _maxCondFormats = maxCondFormats; - _maxCellStyles = maxCellStyles; - _maxTextLength = maxText; - } - - /** - * @return the maximum number of usable rows in each spreadsheet - */ - public int getMaxRows() { - return _maxRows; - } - - /** - * @return the last (maximum) valid row index, equals to getMaxRows() - 1 - */ - public int getLastRowIndex() { - return _maxRows - 1; - } - - /** - * @return the maximum number of usable columns in each spreadsheet - */ - public int getMaxColumns() { - return _maxColumns; - } - - /** - * @return the last (maximum) valid column index, equals to getMaxColumns() - 1 - */ - public int getLastColumnIndex() { - return _maxColumns - 1; - } - - /** - * @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF) - */ - public int getMaxFunctionArgs() { - return _maxFunctionArgs; - } - - /** - * @return the maximum number of conditional format conditions on a cell - */ - public int getMaxConditionalFormats() { - return _maxCondFormats; - } - - /** - * @return the maximum number of cell styles per spreadsheet - */ - public int getMaxCellStyles() { - return _maxCellStyles; - } - - /** - * - * @return the last valid column index in a ALPHA-26 representation - * (IV or XFD). - */ - public String getLastColumnName() { - return CellReference.convertNumToColString(getLastColumnIndex()); - } - - /** - * @return the maximum length of a text cell - */ - public int getMaxTextLength() { - return _maxTextLength; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/extractor/ExcelExtractor.java b/trunk/src/java/org/apache/poi/ss/extractor/ExcelExtractor.java deleted file mode 100644 index 82a31592b..000000000 --- a/trunk/src/java/org/apache/poi/ss/extractor/ExcelExtractor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.extractor; - -/** - * Common interface for Excel text extractors, covering - * HSSF and XSSF - */ -public interface ExcelExtractor { - /** - * Should sheet names be included? - * Default is true - * - * @param includeSheetNames {@code true} if the sheet names should be included - */ - public void setIncludeSheetNames(boolean includeSheetNames); - - /** - * Should we return the formula itself, and not the result it produces? - * Default is false - * - * @param formulasNotResults {@code true} if the formula itself is returned - */ - public void setFormulasNotResults(boolean formulasNotResults); - - /** - * Should headers and footers be included in the output? - * Default is true - * - * @param includeHeadersFooters {@code true} if headers and footers should be included - */ - public void setIncludeHeadersFooters(boolean includeHeadersFooters); - - /** - * Should cell comments be included? - * Default is false - * - * @param includeCellComments {@code true} if cell comments should be included - */ - public void setIncludeCellComments(boolean includeCellComments); - - /** - * Retrieves the text contents of the file - * - * @return the text contents of the file - */ - public String getText(); -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellDateFormatter.java b/trunk/src/java/org/apache/poi/ss/format/CellDateFormatter.java deleted file mode 100644 index 11c567c4c..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellDateFormatter.java +++ /dev/null @@ -1,226 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.text.AttributedCharacterIterator; -import java.text.CharacterIterator; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Formatter; -import java.util.Locale; -import java.util.regex.Matcher; - -import org.apache.poi.util.LocaleUtil; - -/** - * Formats a date value. - */ -public class CellDateFormatter extends CellFormatter { - private boolean amPmUpper; - private boolean showM; - private boolean showAmPm; - private final DateFormat dateFmt; - private String sFmt; - - private final Calendar EXCEL_EPOCH_CAL = - LocaleUtil.getLocaleCalendar(1904, 0, 1); - - private static /* final */ CellDateFormatter SIMPLE_DATE = null; - - private class DatePartHandler implements CellFormatPart.PartHandler { - private int mStart = -1; - private int mLen; - private int hStart = -1; - private int hLen; - - public String handlePart(Matcher m, String part, CellFormatType type, - StringBuffer desc) { - - int pos = desc.length(); - char firstCh = part.charAt(0); - switch (firstCh) { - case 's': - case 'S': - if (mStart >= 0) { - for (int i = 0; i < mLen; i++) - desc.setCharAt(mStart + i, 'm'); - mStart = -1; - } - return part.toLowerCase(Locale.ROOT); - - case 'h': - case 'H': - mStart = -1; - hStart = pos; - hLen = part.length(); - return part.toLowerCase(Locale.ROOT); - - case 'd': - case 'D': - mStart = -1; - if (part.length() <= 2) - return part.toLowerCase(Locale.ROOT); - else - return part.toLowerCase(Locale.ROOT).replace('d', 'E'); - - case 'm': - case 'M': - mStart = pos; - mLen = part.length(); - // For 'm' after 'h', output minutes ('m') not month ('M') - if (hStart >= 0) - return part.toLowerCase(Locale.ROOT); - else - return part.toUpperCase(Locale.ROOT); - - case 'y': - case 'Y': - mStart = -1; - if (part.length() == 3) - part = "yyyy"; - return part.toLowerCase(Locale.ROOT); - - case '0': - mStart = -1; - int sLen = part.length(); - sFmt = "%0" + (sLen + 2) + "." + sLen + "f"; - return part.replace('0', 'S'); - - case 'a': - case 'A': - case 'p': - case 'P': - if (part.length() > 1) { - // am/pm marker - mStart = -1; - showAmPm = true; - showM = Character.toLowerCase(part.charAt(1)) == 'm'; - // For some reason "am/pm" becomes AM or PM, but "a/p" becomes a or p - amPmUpper = showM || Character.isUpperCase(part.charAt(0)); - - return "a"; - } - //noinspection fallthrough - - default: - return null; - } - } - - public void finish(StringBuffer toAppendTo) { - if (hStart >= 0 && !showAmPm) { - for (int i = 0; i < hLen; i++) { - toAppendTo.setCharAt(hStart + i, 'H'); - } - } - } - } - - /** - * Creates a new date formatter with the given specification. - * - * @param format The format. - */ - public CellDateFormatter(String format) { - super(format); - DatePartHandler partHandler = new DatePartHandler(); - StringBuffer descBuf = CellFormatPart.parseFormat(format, - CellFormatType.DATE, partHandler); - partHandler.finish(descBuf); - // tweak the format pattern to pass tests on JDK 1.7, - // See https://issues.apache.org/bugzilla/show_bug.cgi?id=53369 - String ptrn = descBuf.toString().replaceAll("((y)(?!y))(? - * For a date, this is "mm/d/y". - */ - public void simpleValue(StringBuffer toAppendTo, Object value) { - synchronized (CellDateFormatter.class) { - if (SIMPLE_DATE == null || !SIMPLE_DATE.EXCEL_EPOCH_CAL.equals(EXCEL_EPOCH_CAL)) { - SIMPLE_DATE = new CellDateFormatter("mm/d/y"); - } - } - SIMPLE_DATE.formatValue(toAppendTo, value); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellElapsedFormatter.java b/trunk/src/java/org/apache/poi/ss/format/CellElapsedFormatter.java deleted file mode 100644 index 9a90e8a9e..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellElapsedFormatter.java +++ /dev/null @@ -1,220 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.util.ArrayList; -import java.util.Formatter; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * This class implements printing out an elapsed time format. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class CellElapsedFormatter extends CellFormatter { - private final List specs; - private TimeSpec topmost; - private final String printfFmt; - - private static final Pattern PERCENTS = Pattern.compile("%"); - - private static final double HOUR__FACTOR = 1.0 / 24.0; - private static final double MIN__FACTOR = HOUR__FACTOR / 60.0; - private static final double SEC__FACTOR = MIN__FACTOR / 60.0; - - private static class TimeSpec { - final char type; - final int pos; - final int len; - final double factor; - double modBy; - - public TimeSpec(char type, int pos, int len, double factor) { - this.type = type; - this.pos = pos; - this.len = len; - this.factor = factor; - modBy = 0; - } - - public long valueFor(double elapsed) { - double val; - if (modBy == 0) - val = elapsed / factor; - else - val = elapsed / factor % modBy; - if (type == '0') - return Math.round(val); - else - return (long) val; - } - } - - private class ElapsedPartHandler implements CellFormatPart.PartHandler { - // This is the one class that's directly using printf, so it can't use - // the default handling for quoted strings and special characters. The - // only special character for this is '%', so we have to handle all the - // quoting in this method ourselves. - - public String handlePart(Matcher m, String part, CellFormatType type, - StringBuffer desc) { - - int pos = desc.length(); - char firstCh = part.charAt(0); - switch (firstCh) { - case '[': - if (part.length() < 3) - break; - if (topmost != null) - throw new IllegalArgumentException( - "Duplicate '[' times in format"); - part = part.toLowerCase(Locale.ROOT); - int specLen = part.length() - 2; - topmost = assignSpec(part.charAt(1), pos, specLen); - return part.substring(1, 1 + specLen); - - case 'h': - case 'm': - case 's': - case '0': - part = part.toLowerCase(Locale.ROOT); - assignSpec(part.charAt(0), pos, part.length()); - return part; - - case '\n': - return "%n"; - - case '\"': - part = part.substring(1, part.length() - 1); - break; - - case '\\': - part = part.substring(1); - break; - - case '*': - if (part.length() > 1) - part = CellFormatPart.expandChar(part); - break; - - // An escape we can let it handle because it can't have a '%' - case '_': - return null; - } - // Replace ever "%" with a "%%" so we can use printf - return PERCENTS.matcher(part).replaceAll("%%"); - } - } - - /** - * Creates a elapsed time formatter. - * - * @param pattern The pattern to parse. - */ - public CellElapsedFormatter(String pattern) { - super(pattern); - - specs = new ArrayList(); - - StringBuffer desc = CellFormatPart.parseFormat(pattern, - CellFormatType.ELAPSED, new ElapsedPartHandler()); - - ListIterator it = specs.listIterator(specs.size()); - while (it.hasPrevious()) { - TimeSpec spec = it.previous(); - desc.replace(spec.pos, spec.pos + spec.len, "%0" + spec.len + "d"); - if (spec.type != topmost.type) { - spec.modBy = modFor(spec.type, spec.len); - } - } - - printfFmt = desc.toString(); - } - - private TimeSpec assignSpec(char type, int pos, int len) { - TimeSpec spec = new TimeSpec(type, pos, len, factorFor(type, len)); - specs.add(spec); - return spec; - } - - private static double factorFor(char type, int len) { - switch (type) { - case 'h': - return HOUR__FACTOR; - case 'm': - return MIN__FACTOR; - case 's': - return SEC__FACTOR; - case '0': - return SEC__FACTOR / Math.pow(10, len); - default: - throw new IllegalArgumentException( - "Uknown elapsed time spec: " + type); - } - } - - private static double modFor(char type, int len) { - switch (type) { - case 'h': - return 24; - case 'm': - return 60; - case 's': - return 60; - case '0': - return Math.pow(10, len); - default: - throw new IllegalArgumentException( - "Uknown elapsed time spec: " + type); - } - } - - /** {@inheritDoc} */ - public void formatValue(StringBuffer toAppendTo, Object value) { - double elapsed = ((Number) value).doubleValue(); - - if (elapsed < 0) { - toAppendTo.append('-'); - elapsed = -elapsed; - } - - Object[] parts = new Long[specs.size()]; - for (int i = 0; i < specs.size(); i++) { - parts[i] = specs.get(i).valueFor(elapsed); - } - - Formatter formatter = new Formatter(toAppendTo, Locale.ROOT); - try { - formatter.format(printfFmt, parts); - } finally { - formatter.close(); - } - } - - /** - * {@inheritDoc} - *

        - * For a date, this is "mm/d/y". - */ - public void simpleValue(StringBuffer toAppendTo, Object value) { - formatValue(toAppendTo, value); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellFormat.java b/trunk/src/java/org/apache/poi/ss/format/CellFormat.java deleted file mode 100644 index bad849712..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellFormat.java +++ /dev/null @@ -1,485 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.format; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.logging.Level; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.swing.JLabel; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.ConditionalFormatting; -import org.apache.poi.ss.usermodel.ConditionalFormattingRule; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.util.DateFormatConverter; - -/** - * Format a value according to the standard Excel behavior. This "standard" is - * not explicitly documented by Microsoft, so the behavior is determined by - * experimentation; see the tests. - *

        - * An Excel format has up to four parts, separated by semicolons. Each part - * specifies what to do with particular kinds of values, depending on the number - * of parts given: - *

        - *
        One part (example: [Green]#.##)
        - *
        If the value is a number, display according to this one part (example: green text, - * with up to two decimal points). If the value is text, display it as is.
        - * - *
        Two parts (example: [Green]#.##;[Red]#.##)
        - *
        If the value is a positive number or zero, display according to the first part (example: green - * text, with up to two decimal points); if it is a negative number, display - * according to the second part (example: red text, with up to two decimal - * points). If the value is text, display it as is.
        - * - *
        Three parts (example: [Green]#.##;[Black]#.##;[Red]#.##)
        - *
        If the value is a positive - * number, display according to the first part (example: green text, with up to - * two decimal points); if it is zero, display according to the second part - * (example: black text, with up to two decimal points); if it is a negative - * number, display according to the third part (example: red text, with up to - * two decimal points). If the value is text, display it as is.
        - * - *
        Four parts (example: [Green]#.##;[Black]#.##;[Red]#.##;[@])
        - *
        If the value is a positive number, display according to the first part (example: green text, - * with up to two decimal points); if it is zero, display according to the - * second part (example: black text, with up to two decimal points); if it is a - * negative number, display according to the third part (example: red text, with - * up to two decimal points). If the value is text, display according to the - * fourth part (example: text in the cell's usual color, with the text value - * surround by brackets).
        - *
        - *

        - * A given format part may specify a given Locale, by including something - * like [$$-409] or [$£-809] or [$-40C]. These - * are (currently) largely ignored. You can use {@link DateFormatConverter} - * to look these up into Java Locales if desired. - *

        - * In addition to these, there is a general format that is used when no format - * is specified. This formatting is presented by the {@link #GENERAL_FORMAT} - * object. - * - * TODO Merge this with {@link DataFormatter} so we only have one set of - * code for formatting numbers. - * TODO Re-use parts of this logic with {@link ConditionalFormatting} / - * {@link ConditionalFormattingRule} for reporting stylings which do/don't apply - * TODO Support the full set of modifiers, including alternate calendars and - * native character numbers, as documented at https://help.libreoffice.org/Common/Number_Format_Codes - */ -public class CellFormat { - private final String format; - private final CellFormatPart posNumFmt; - private final CellFormatPart zeroNumFmt; - private final CellFormatPart negNumFmt; - private final CellFormatPart textFmt; - private final int formatPartCount; - - private static final Pattern ONE_PART = Pattern.compile( - CellFormatPart.FORMAT_PAT.pattern() + "(;|$)", - Pattern.COMMENTS | Pattern.CASE_INSENSITIVE); - - private static final CellFormatPart DEFAULT_TEXT_FORMAT = - new CellFormatPart("@"); - - /* - * Cells that cannot be formatted, e.g. cells that have a date or time - * format and have an invalid date or time value, are displayed as 255 - * pound signs ("#"). - */ - private static final String INVALID_VALUE_FOR_FORMAT = - "###################################################" + - "###################################################" + - "###################################################" + - "###################################################" + - "###################################################"; - - private static String QUOTE = "\""; - - /** - * Format a value as it would be were no format specified. This is also - * used when the format specified is General. - */ - public static final CellFormat GENERAL_FORMAT = new CellFormat("General") { - @Override - public CellFormatResult apply(Object value) { - String text = (new CellGeneralFormatter()).format(value); - return new CellFormatResult(true, text, null); - } - }; - - /** Maps a format string to its parsed version for efficiencies sake. */ - private static final Map formatCache = - new WeakHashMap(); - - /** - * Returns a {@link CellFormat} that applies the given format. Two calls - * with the same format may or may not return the same object. - * - * @param format The format. - * - * @return A {@link CellFormat} that applies the given format. - */ - public static CellFormat getInstance(String format) { - CellFormat fmt = formatCache.get(format); - if (fmt == null) { - if (format.equals("General") || format.equals("@")) - fmt = GENERAL_FORMAT; - else - fmt = new CellFormat(format); - formatCache.put(format, fmt); - } - return fmt; - } - - /** - * Creates a new object. - * - * @param format The format. - */ - private CellFormat(String format) { - this.format = format; - Matcher m = ONE_PART.matcher(format); - List parts = new ArrayList(); - - while (m.find()) { - try { - String valueDesc = m.group(); - - // Strip out the semicolon if it's there - if (valueDesc.endsWith(";")) - valueDesc = valueDesc.substring(0, valueDesc.length() - 1); - - parts.add(new CellFormatPart(valueDesc)); - } catch (RuntimeException e) { - CellFormatter.logger.log(Level.WARNING, - "Invalid format: " + CellFormatter.quote(m.group()), e); - parts.add(null); - } - } - - formatPartCount = parts.size(); - - switch (formatPartCount) { - case 1: - posNumFmt = parts.get(0); - negNumFmt = null; - zeroNumFmt = null; - textFmt = DEFAULT_TEXT_FORMAT; - break; - case 2: - posNumFmt = parts.get(0); - negNumFmt = parts.get(1); - zeroNumFmt = null; - textFmt = DEFAULT_TEXT_FORMAT; - break; - case 3: - posNumFmt = parts.get(0); - negNumFmt = parts.get(1); - zeroNumFmt = parts.get(2); - textFmt = DEFAULT_TEXT_FORMAT; - break; - case 4: - default: - posNumFmt = parts.get(0); - negNumFmt = parts.get(1); - zeroNumFmt = parts.get(2); - textFmt = parts.get(3); - break; - } - } - - /** - * Returns the result of applying the format to the given value. If the - * value is a number (a type of {@link Number} object), the correct number - * format type is chosen; otherwise it is considered a text object. - * - * @param value The value - * - * @return The result, in a {@link CellFormatResult}. - */ - public CellFormatResult apply(Object value) { - if (value instanceof Number) { - Number num = (Number) value; - double val = num.doubleValue(); - if (val < 0 && - ((formatPartCount == 2 - && !posNumFmt.hasCondition() && !negNumFmt.hasCondition()) - || (formatPartCount == 3 && !negNumFmt.hasCondition()) - || (formatPartCount == 4 && !negNumFmt.hasCondition()))) { - // The negative number format has the negative formatting required, - // e.g. minus sign or brackets, so pass a positive value so that - // the default leading minus sign is not also output - return negNumFmt.apply(-val); - } else { - return getApplicableFormatPart(val).apply(val); - } - } else if (value instanceof java.util.Date) { - // Don't know (and can't get) the workbook date windowing (1900 or 1904) - // so assume 1900 date windowing - Double numericValue = DateUtil.getExcelDate((Date) value); - if (DateUtil.isValidExcelDate(numericValue)) { - return getApplicableFormatPart(numericValue).apply(value); - } else { - throw new IllegalArgumentException("value " + numericValue + " of date " + value + " is not a valid Excel date"); - } - } else { - return textFmt.apply(value); - } - } - - /** - * Returns the result of applying the format to the given date. - * - * @param date The date. - * @param numericValue The numeric value for the date. - * - * @return The result, in a {@link CellFormatResult}. - */ - private CellFormatResult apply(Date date, double numericValue) { - return getApplicableFormatPart(numericValue).apply(date); - } - - /** - * Fetches the appropriate value from the cell, and returns the result of - * applying it to the appropriate format. For formula cells, the computed - * value is what is used. - * - * @param c The cell. - * - * @return The result, in a {@link CellFormatResult}. - */ - public CellFormatResult apply(Cell c) { - switch (ultimateTypeEnum(c)) { - case BLANK: - return apply(""); - case BOOLEAN: - return apply(c.getBooleanCellValue()); - case NUMERIC: - Double value = c.getNumericCellValue(); - if (getApplicableFormatPart(value).getCellFormatType() == CellFormatType.DATE) { - if (DateUtil.isValidExcelDate(value)) { - return apply(c.getDateCellValue(), value); - } else { - return apply(INVALID_VALUE_FOR_FORMAT); - } - } else { - return apply(value); - } - case STRING: - return apply(c.getStringCellValue()); - default: - return apply("?"); - } - } - - /** - * Uses the result of applying this format to the value, setting the text - * and color of a label before returning the result. - * - * @param label The label to apply to. - * @param value The value to process. - * - * @return The result, in a {@link CellFormatResult}. - */ - public CellFormatResult apply(JLabel label, Object value) { - CellFormatResult result = apply(value); - label.setText(result.text); - if (result.textColor != null) { - label.setForeground(result.textColor); - } - return result; - } - - /** - * Uses the result of applying this format to the given date, setting the text - * and color of a label before returning the result. - * - * @param label The label to apply to. - * @param date The date. - * @param numericValue The numeric value for the date. - * - * @return The result, in a {@link CellFormatResult}. - */ - private CellFormatResult apply(JLabel label, Date date, double numericValue) { - CellFormatResult result = apply(date, numericValue); - label.setText(result.text); - if (result.textColor != null) { - label.setForeground(result.textColor); - } - return result; - } - - /** - * Fetches the appropriate value from the cell, and uses the result, setting - * the text and color of a label before returning the result. - * - * @param label The label to apply to. - * @param c The cell. - * - * @return The result, in a {@link CellFormatResult}. - */ - public CellFormatResult apply(JLabel label, Cell c) { - switch (ultimateTypeEnum(c)) { - case BLANK: - return apply(label, ""); - case BOOLEAN: - return apply(label, c.getBooleanCellValue()); - case NUMERIC: - Double value = c.getNumericCellValue(); - if (getApplicableFormatPart(value).getCellFormatType() == CellFormatType.DATE) { - if (DateUtil.isValidExcelDate(value)) { - return apply(label, c.getDateCellValue(), value); - } else { - return apply(label, INVALID_VALUE_FOR_FORMAT); - } - } else { - return apply(label, value); - } - case STRING: - return apply(label, c.getStringCellValue()); - default: - return apply(label, "?"); - } - } - - /** - * Returns the {@link CellFormatPart} that applies to the value. Result - * depends on how many parts the cell format has, the cell value and any - * conditions. The value must be a {@link Number}. - * - * @param value The value. - * @return The {@link CellFormatPart} that applies to the value. - */ - private CellFormatPart getApplicableFormatPart(Object value) { - - if (value instanceof Number) { - - double val = ((Number) value).doubleValue(); - - if (formatPartCount == 1) { - if (!posNumFmt.hasCondition() - || (posNumFmt.hasCondition() && posNumFmt.applies(val))) { - return posNumFmt; - } else { - return new CellFormatPart("General"); - } - } else if (formatPartCount == 2) { - if ((!posNumFmt.hasCondition() && val >= 0) - || (posNumFmt.hasCondition() && posNumFmt.applies(val))) { - return posNumFmt; - } else if (!negNumFmt.hasCondition() - || (negNumFmt.hasCondition() && negNumFmt.applies(val))) { - return negNumFmt; - } else { - // Return ###...### (255 #s) to match Excel 2007 behaviour - return new CellFormatPart(QUOTE + INVALID_VALUE_FOR_FORMAT + QUOTE); - } - } else { - if ((!posNumFmt.hasCondition() && val > 0) - || (posNumFmt.hasCondition() && posNumFmt.applies(val))) { - return posNumFmt; - } else if ((!negNumFmt.hasCondition() && val < 0) - || (negNumFmt.hasCondition() && negNumFmt.applies(val))) { - return negNumFmt; - // Only the first two format parts can have conditions - } else { - return zeroNumFmt; - } - } - } else { - throw new IllegalArgumentException("value must be a Number"); - } - - } - - /** - * Returns the ultimate cell type, following the results of formulas. If - * the cell is a {@link CellType#FORMULA}, this returns the result of - * {@link Cell#getCachedFormulaResultTypeEnum()}. Otherwise this returns the - * result of {@link Cell#getCellTypeEnum()}. - * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @param cell The cell. - * - * @return The ultimate type of this cell. - * @deprecated POI 3.15. This will return a CellType enum in the future - */ - public static int ultimateType(Cell cell) { - return ultimateTypeEnum(cell).getCode(); - } - - /** - * Returns the ultimate cell type, following the results of formulas. If - * the cell is a {@link CellType#FORMULA}, this returns the result of - * {@link Cell#getCachedFormulaResultTypeEnum()}. Otherwise this returns the - * result of {@link Cell#getCellTypeEnum()}. - * - * @param cell The cell. - * - * @return The ultimate type of this cell. - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - public static CellType ultimateTypeEnum(Cell cell) { - CellType type = cell.getCellTypeEnum(); - if (type == CellType.FORMULA) - return cell.getCachedFormulaResultTypeEnum(); - else - return type; - } - - /** - * Returns true if the other object is a {@link CellFormat} object - * with the same format. - * - * @param obj The other object. - * - * @return true if the two objects are equal. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj instanceof CellFormat) { - CellFormat that = (CellFormat) obj; - return format.equals(that.format); - } - return false; - } - - /** - * Returns a hash code for the format. - * - * @return A hash code for the format. - */ - @Override - public int hashCode() { - return format.hashCode(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellFormatCondition.java b/trunk/src/java/org/apache/poi/ss/format/CellFormatCondition.java deleted file mode 100644 index 23fd2f2e7..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellFormatCondition.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.util.HashMap; -import java.util.Map; - -/** - * This object represents a condition in a cell format. - * - * @author Ken Arnold, Industrious Media LLC - */ -public abstract class CellFormatCondition { - private static final int LT = 0; - private static final int LE = 1; - private static final int GT = 2; - private static final int GE = 3; - private static final int EQ = 4; - private static final int NE = 5; - - private static final Map TESTS; - - static { - TESTS = new HashMap(); - TESTS.put("<", LT); - TESTS.put("<=", LE); - TESTS.put(">", GT); - TESTS.put(">=", GE); - TESTS.put("=", EQ); - TESTS.put("==", EQ); - TESTS.put("!=", NE); - TESTS.put("<>", NE); - } - - /** - * Returns an instance of a condition object. - * - * @param opString The operator as a string. One of "<", - * "<=", ">", ">=", - * "=", "==", "!=", or - * "<>". - * @param constStr The constant (such as "12"). - * - * @return A condition object for the given condition. - */ - public static CellFormatCondition getInstance(String opString, - String constStr) { - - if (!TESTS.containsKey(opString)) - throw new IllegalArgumentException("Unknown test: " + opString); - int test = TESTS.get(opString); - - final double c = Double.parseDouble(constStr); - - switch (test) { - case LT: - return new CellFormatCondition() { - public boolean pass(double value) { - return value < c; - } - }; - case LE: - return new CellFormatCondition() { - public boolean pass(double value) { - return value <= c; - } - }; - case GT: - return new CellFormatCondition() { - public boolean pass(double value) { - return value > c; - } - }; - case GE: - return new CellFormatCondition() { - public boolean pass(double value) { - return value >= c; - } - }; - case EQ: - return new CellFormatCondition() { - public boolean pass(double value) { - return value == c; - } - }; - case NE: - return new CellFormatCondition() { - public boolean pass(double value) { - return value != c; - } - }; - default: - throw new IllegalArgumentException( - "Cannot create for test number " + test + "(\"" + opString + - "\")"); - } - } - - /** - * Returns true if the given value passes the constraint's test. - * - * @param value The value to compare against. - * - * @return true if the given value passes the constraint's test. - */ - public abstract boolean pass(double value); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java b/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java deleted file mode 100644 index b4b508fb3..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellFormatPart.java +++ /dev/null @@ -1,573 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import org.apache.poi.hssf.util.HSSFColor; - -import javax.swing.*; - -import java.awt.*; -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.apache.poi.ss.format.CellFormatter.logger; -import static org.apache.poi.ss.format.CellFormatter.quote; - -/** - * Objects of this class represent a single part of a cell format expression. - * Each cell can have up to four of these for positive, zero, negative, and text - * values. - *

        - * Each format part can contain a color, a condition, and will always contain a - * format specification. For example "[Red][>=10]#" has a color - * ([Red]), a condition (>=10) and a format specification - * (#). - *

        - * This class also contains patterns for matching the subparts of format - * specification. These are used internally, but are made public in case other - * code has use for them. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class CellFormatPart { - private final Color color; - private CellFormatCondition condition; - private final CellFormatter format; - private final CellFormatType type; - - private static final Map NAMED_COLORS; - - static { - NAMED_COLORS = new TreeMap( - String.CASE_INSENSITIVE_ORDER); - - Map colors = HSSFColor.getIndexHash(); - for (HSSFColor color : colors.values()) { - Class type = color.getClass(); - String name = type.getSimpleName(); - if (name.equals(name.toUpperCase(Locale.ROOT))) { - short[] rgb = color.getTriplet(); - Color c = new Color(rgb[0], rgb[1], rgb[2]); - NAMED_COLORS.put(name, c); - if (name.indexOf('_') > 0) - NAMED_COLORS.put(name.replace('_', ' '), c); - if (name.indexOf("_PERCENT") > 0) - NAMED_COLORS.put(name.replace("_PERCENT", "%").replace('_', - ' '), c); - } - } - } - - /** Pattern for the color part of a cell format part. */ - public static final Pattern COLOR_PAT; - /** Pattern for the condition part of a cell format part. */ - public static final Pattern CONDITION_PAT; - /** Pattern for the format specification part of a cell format part. */ - public static final Pattern SPECIFICATION_PAT; - /** Pattern for the currency symbol part of a cell format part */ - public static final Pattern CURRENCY_PAT; - /** Pattern for an entire cell single part. */ - public static final Pattern FORMAT_PAT; - - /** Within {@link #FORMAT_PAT}, the group number for the matched color. */ - public static final int COLOR_GROUP; - /** - * Within {@link #FORMAT_PAT}, the group number for the operator in the - * condition. - */ - public static final int CONDITION_OPERATOR_GROUP; - /** - * Within {@link #FORMAT_PAT}, the group number for the value in the - * condition. - */ - public static final int CONDITION_VALUE_GROUP; - /** - * Within {@link #FORMAT_PAT}, the group number for the format - * specification. - */ - public static final int SPECIFICATION_GROUP; - - static { - // A condition specification - String condition = "([<>=]=?|!=|<>) # The operator\n" + - " \\s*([0-9]+(?:\\.[0-9]*)?)\\s* # The constant to test against\n"; - - // A currency symbol / string, in a specific locale - String currency = "(\\[\\$.{0,3}-[0-9a-f]{3}\\])"; - - String color = - "\\[(black|blue|cyan|green|magenta|red|white|yellow|color [0-9]+)\\]"; - - // A number specification - // Note: careful that in something like ##, that the trailing comma is not caught up in the integer part - - // A part of a specification - String part = "\\\\. # Quoted single character\n" + - "|\"([^\\\\\"]|\\\\.)*\" # Quoted string of characters (handles escaped quotes like \\\") \n" + - "|"+currency+" # Currency symbol in a given locale\n" + - "|_. # Space as wide as a given character\n" + - "|\\*. # Repeating fill character\n" + - "|@ # Text: cell text\n" + - "|([0?\\#](?:[0?\\#,]*)) # Number: digit + other digits and commas\n" + - "|e[-+] # Number: Scientific: Exponent\n" + - "|m{1,5} # Date: month or minute spec\n" + - "|d{1,4} # Date: day/date spec\n" + - "|y{2,4} # Date: year spec\n" + - "|h{1,2} # Date: hour spec\n" + - "|s{1,2} # Date: second spec\n" + - "|am?/pm? # Date: am/pm spec\n" + - "|\\[h{1,2}\\] # Elapsed time: hour spec\n" + - "|\\[m{1,2}\\] # Elapsed time: minute spec\n" + - "|\\[s{1,2}\\] # Elapsed time: second spec\n" + - "|[^;] # A character\n" + ""; - - String format = "(?:" + color + ")? # Text color\n" + - "(?:\\[" + condition + "\\])? # Condition\n" + - // see https://msdn.microsoft.com/en-ca/goglobal/bb964664.aspx and https://bz.apache.org/ooo/show_bug.cgi?id=70003 - // we ignore these for now though - "(?:\\[\\$-[0-9a-fA-F]+\\])? # Optional locale id, ignored currently\n" + - "((?:" + part + ")+) # Format spec\n"; - - int flags = Pattern.COMMENTS | Pattern.CASE_INSENSITIVE; - COLOR_PAT = Pattern.compile(color, flags); - CONDITION_PAT = Pattern.compile(condition, flags); - SPECIFICATION_PAT = Pattern.compile(part, flags); - CURRENCY_PAT = Pattern.compile(currency, flags); - FORMAT_PAT = Pattern.compile(format, flags); - - // Calculate the group numbers of important groups. (They shift around - // when the pattern is changed; this way we figure out the numbers by - // experimentation.) - - COLOR_GROUP = findGroup(FORMAT_PAT, "[Blue]@", "Blue"); - CONDITION_OPERATOR_GROUP = findGroup(FORMAT_PAT, "[>=1]@", ">="); - CONDITION_VALUE_GROUP = findGroup(FORMAT_PAT, "[>=1]@", "1"); - SPECIFICATION_GROUP = findGroup(FORMAT_PAT, "[Blue][>1]\\a ?", "\\a ?"); - } - - interface PartHandler { - String handlePart(Matcher m, String part, CellFormatType type, - StringBuffer desc); - } - - /** - * Create an object to represent a format part. - * - * @param desc The string to parse. - */ - public CellFormatPart(String desc) { - Matcher m = FORMAT_PAT.matcher(desc); - if (!m.matches()) { - throw new IllegalArgumentException("Unrecognized format: " + quote( - desc)); - } - color = getColor(m); - condition = getCondition(m); - type = getCellFormatType(m); - format = getFormatter(m); - } - - /** - * Returns true if this format part applies to the given value. If - * the value is a number and this is part has a condition, returns - * true only if the number passes the condition. Otherwise, this - * always return true. - * - * @param valueObject The value to evaluate. - * - * @return true if this format part applies to the given value. - */ - public boolean applies(Object valueObject) { - if (condition == null || !(valueObject instanceof Number)) { - if (valueObject == null) - throw new NullPointerException("valueObject"); - return true; - } else { - Number num = (Number) valueObject; - return condition.pass(num.doubleValue()); - } - } - - /** - * Returns the number of the first group that is the same as the marker - * string. Starts from group 1. - * - * @param pat The pattern to use. - * @param str The string to match against the pattern. - * @param marker The marker value to find the group of. - * - * @return The matching group number. - * - * @throws IllegalArgumentException No group matches the marker. - */ - private static int findGroup(Pattern pat, String str, String marker) { - Matcher m = pat.matcher(str); - if (!m.find()) - throw new IllegalArgumentException( - "Pattern \"" + pat.pattern() + "\" doesn't match \"" + str + - "\""); - for (int i = 1; i <= m.groupCount(); i++) { - String grp = m.group(i); - if (grp != null && grp.equals(marker)) - return i; - } - throw new IllegalArgumentException( - "\"" + marker + "\" not found in \"" + pat.pattern() + "\""); - } - - /** - * Returns the color specification from the matcher, or null if - * there is none. - * - * @param m The matcher for the format part. - * - * @return The color specification or null. - */ - private static Color getColor(Matcher m) { - String cdesc = m.group(COLOR_GROUP); - if (cdesc == null || cdesc.length() == 0) - return null; - Color c = NAMED_COLORS.get(cdesc); - if (c == null) - logger.warning("Unknown color: " + quote(cdesc)); - return c; - } - - /** - * Returns the condition specification from the matcher, or null if - * there is none. - * - * @param m The matcher for the format part. - * - * @return The condition specification or null. - */ - private CellFormatCondition getCondition(Matcher m) { - String mdesc = m.group(CONDITION_OPERATOR_GROUP); - if (mdesc == null || mdesc.length() == 0) - return null; - return CellFormatCondition.getInstance(m.group( - CONDITION_OPERATOR_GROUP), m.group(CONDITION_VALUE_GROUP)); - } - - /** - * Returns the CellFormatType object implied by the format specification for - * the format part. - * - * @param matcher The matcher for the format part. - * - * @return The CellFormatType. - */ - private CellFormatType getCellFormatType(Matcher matcher) { - String fdesc = matcher.group(SPECIFICATION_GROUP); - return formatType(fdesc); - } - - /** - * Returns the formatter object implied by the format specification for the - * format part. - * - * @param matcher The matcher for the format part. - * - * @return The formatter. - */ - private CellFormatter getFormatter(Matcher matcher) { - String fdesc = matcher.group(SPECIFICATION_GROUP); - - // For now, we don't support localised currencies, so simplify if there - Matcher currencyM = CURRENCY_PAT.matcher(fdesc); - if (currencyM.find()) { - String currencyPart = currencyM.group(1); - String currencyRepl; - if (currencyPart.startsWith("[$-")) { - // Default $ in a different locale - currencyRepl = "$"; - } else { - currencyRepl = currencyPart.substring(2, currencyPart.lastIndexOf('-')); - } - fdesc = fdesc.replace(currencyPart, currencyRepl); - } - - // Build a formatter for this simplified string - return type.formatter(fdesc); - } - - /** - * Returns the type of format. - * - * @param fdesc The format specification - * - * @return The type of format. - */ - private CellFormatType formatType(String fdesc) { - fdesc = fdesc.trim(); - if (fdesc.equals("") || fdesc.equalsIgnoreCase("General")) - return CellFormatType.GENERAL; - - Matcher m = SPECIFICATION_PAT.matcher(fdesc); - boolean couldBeDate = false; - boolean seenZero = false; - while (m.find()) { - String repl = m.group(0); - - if (repl.length() > 0) { - char c1 = repl.charAt(0); - char c2 = 0; - if (repl.length() > 1) - c2 = Character.toLowerCase(repl.charAt(1)); - - switch (c1) { - case '@': - return CellFormatType.TEXT; - case 'd': - case 'D': - case 'y': - case 'Y': - return CellFormatType.DATE; - case 'h': - case 'H': - case 'm': - case 'M': - case 's': - case 'S': - // These can be part of date, or elapsed - couldBeDate = true; - break; - case '0': - // This can be part of date, elapsed, or number - seenZero = true; - break; - case '[': - if (c2 == 'h' || c2 == 'm' || c2 == 's') { - return CellFormatType.ELAPSED; - } - if (c2 == '$') { - // Localised currency - return CellFormatType.NUMBER; - } - // Something else inside [] which isn't supported! - throw new IllegalArgumentException("Unsupported [] format block '" + - repl + "' in '" + fdesc + "' with c2: " + c2); - case '#': - case '?': - return CellFormatType.NUMBER; - } - } - } - - // Nothing definitive was found, so we figure out it deductively - if (couldBeDate) - return CellFormatType.DATE; - if (seenZero) - return CellFormatType.NUMBER; - return CellFormatType.TEXT; - } - - /** - * Returns a version of the original string that has any special characters - * quoted (or escaped) as appropriate for the cell format type. The format - * type object is queried to see what is special. - * - * @param repl The original string. - * @param type The format type representation object. - * - * @return A version of the string with any special characters replaced. - * - * @see CellFormatType#isSpecial(char) - */ - static String quoteSpecial(String repl, CellFormatType type) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < repl.length(); i++) { - char ch = repl.charAt(i); - if (ch == '\'' && type.isSpecial('\'')) { - sb.append('\u0000'); - continue; - } - - boolean special = type.isSpecial(ch); - if (special) - sb.append("'"); - sb.append(ch); - if (special) - sb.append("'"); - } - return sb.toString(); - } - - /** - * Apply this format part to the given value. This returns a {@link - * CellFormatResult} object with the results. - * - * @param value The value to apply this format part to. - * - * @return A {@link CellFormatResult} object containing the results of - * applying the format to the value. - */ - public CellFormatResult apply(Object value) { - boolean applies = applies(value); - String text; - Color textColor; - if (applies) { - text = format.format(value); - textColor = color; - } else { - text = format.simpleFormat(value); - textColor = null; - } - return new CellFormatResult(applies, text, textColor); - } - - /** - * Apply this format part to the given value, applying the result to the - * given label. - * - * @param label The label - * @param value The value to apply this format part to. - * - * @return true if the - */ - public CellFormatResult apply(JLabel label, Object value) { - CellFormatResult result = apply(value); - label.setText(result.text); - if (result.textColor != null) { - label.setForeground(result.textColor); - } - return result; - } - - /** - * Returns the CellFormatType object implied by the format specification for - * the format part. - * - * @return The CellFormatType. - */ - CellFormatType getCellFormatType() { - return type; - } - - /** - * Returns true if this format part has a condition. - * - * @return true if this format part has a condition. - */ - boolean hasCondition() { - return condition != null; - } - - public static StringBuffer parseFormat(String fdesc, CellFormatType type, - PartHandler partHandler) { - - // Quoting is very awkward. In the Java classes, quoting is done - // between ' chars, with '' meaning a single ' char. The problem is that - // in Excel, it is legal to have two adjacent escaped strings. For - // example, consider the Excel format "\a\b#". The naive (and easy) - // translation into Java DecimalFormat is "'a''b'#". For the number 17, - // in Excel you would get "ab17", but in Java it would be "a'b17" -- the - // '' is in the middle of the quoted string in Java. So the trick we - // use is this: When we encounter a ' char in the Excel format, we - // output a \u0000 char into the string. Now we know that any '' in the - // output is the result of two adjacent escaped strings. So after the - // main loop, we have to do two passes: One to eliminate any '' - // sequences, to make "'a''b'" become "'ab'", and another to replace any - // \u0000 with '' to mean a quote char. Oy. - // - // For formats that don't use "'" we don't do any of this - Matcher m = SPECIFICATION_PAT.matcher(fdesc); - StringBuffer fmt = new StringBuffer(); - while (m.find()) { - String part = group(m, 0); - if (part.length() > 0) { - String repl = partHandler.handlePart(m, part, type, fmt); - if (repl == null) { - switch (part.charAt(0)) { - case '\"': - repl = quoteSpecial(part.substring(1, - part.length() - 1), type); - break; - case '\\': - repl = quoteSpecial(part.substring(1), type); - break; - case '_': - repl = " "; - break; - case '*': //!! We don't do this for real, we just put in 3 of them - repl = expandChar(part); - break; - default: - repl = part; - break; - } - } - m.appendReplacement(fmt, Matcher.quoteReplacement(repl)); - } - } - m.appendTail(fmt); - - if (type.isSpecial('\'')) { - // Now the next pass for quoted characters: Remove '' chars, making "'a''b'" into "'ab'" - int pos = 0; - while ((pos = fmt.indexOf("''", pos)) >= 0) { - fmt.delete(pos, pos + 2); - } - - // Now the final pass for quoted chars: Replace any \u0000 with '' - pos = 0; - while ((pos = fmt.indexOf("\u0000", pos)) >= 0) { - fmt.replace(pos, pos + 1, "''"); - } - } - - return fmt; - } - - /** - * Expands a character. This is only partly done, because we don't have the - * correct info. In Excel, this would be expanded to fill the rest of the - * cell, but we don't know, in general, what the "rest of the cell" is. - * - * @param part The character to be repeated is the second character in this - * string. - * - * @return The character repeated three times. - */ - static String expandChar(String part) { - String repl; - char ch = part.charAt(1); - repl = "" + ch + ch + ch; - return repl; - } - - /** - * Returns the string from the group, or "" if the group is - * null. - * - * @param m The matcher. - * @param g The group number. - * - * @return The group or "". - */ - public static String group(Matcher m, int g) { - String str = m.group(g); - return (str == null ? "" : str); - } - - public String toString() { - return format.format; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellFormatResult.java b/trunk/src/java/org/apache/poi/ss/format/CellFormatResult.java deleted file mode 100644 index a22f77c27..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellFormatResult.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.awt.Color; - -/** - * This object contains the result of applying a cell format or cell format part - * to a value. - * - * @author Ken Arnold, Industrious Media LLC - * @see CellFormatPart#apply(Object) - * @see CellFormat#apply(Object) - */ -public class CellFormatResult { - /** - * This is true if no condition was given that applied to the - * value, or if the condition is satisfied. If a condition is relevant, and - * when applied the value fails the test, this is false. - */ - public final boolean applies; - - /** The resulting text. This will never be null. */ - public final String text; - - /** - * The color the format sets, or null if the format sets no color. - * This will always be null if {@link #applies} is false. - */ - public final Color textColor; - - /** - * Creates a new format result object. - * - * @param applies The value for {@link #applies}. - * @param text The value for {@link #text}. - * @param textColor The value for {@link #textColor}. - */ - public CellFormatResult(boolean applies, String text, Color textColor) throws IllegalArgumentException { - this.applies = applies; - if (text == null) - throw new IllegalArgumentException("CellFormatResult text may not be null"); - this.text = text; - this.textColor = (applies ? textColor : null); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/format/CellFormatType.java b/trunk/src/java/org/apache/poi/ss/format/CellFormatType.java deleted file mode 100644 index e1f436bdc..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellFormatType.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.format; - -/** - * The different kinds of formats that the formatter understands. - * - * @author Ken Arnold, Industrious Media LLC - */ -public enum CellFormatType { - - /** The general (default) format; also used for "General". */ - GENERAL { - CellFormatter formatter(String pattern) { - return new CellGeneralFormatter(); - } - boolean isSpecial(char ch) { - return false; - } - }, - /** A numeric format. */ - NUMBER { - boolean isSpecial(char ch) { - return false; - } - CellFormatter formatter(String pattern) { - return new CellNumberFormatter(pattern); - } - }, - /** A date format. */ - DATE { - boolean isSpecial(char ch) { - return ch == '\'' || (ch <= '\u007f' && Character.isLetter(ch)); - } - CellFormatter formatter(String pattern) { - return new CellDateFormatter(pattern); - } - }, - /** An elapsed time format. */ - ELAPSED { - boolean isSpecial(char ch) { - return false; - } - CellFormatter formatter(String pattern) { - return new CellElapsedFormatter(pattern); - } - }, - /** A text format. */ - TEXT { - boolean isSpecial(char ch) { - return false; - } - CellFormatter formatter(String pattern) { - return new CellTextFormatter(pattern); - } - }; - - /** - * Returns true if the format is special and needs to be quoted. - * - * @param ch The character to test. - * - * @return true if the format is special and needs to be quoted. - */ - abstract boolean isSpecial(char ch); - - /** - * Returns a new formatter of the appropriate type, for the given pattern. - * The pattern must be appropriate for the type. - * - * @param pattern The pattern to use. - * - * @return A new formatter of the appropriate type, for the given pattern. - */ - abstract CellFormatter formatter(String pattern); -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellFormatter.java b/trunk/src/java/org/apache/poi/ss/format/CellFormatter.java deleted file mode 100644 index e529a90f1..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellFormatter.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.util.logging.Logger; - -/** - * This is the abstract supertype for the various cell formatters. - * - * @author Ken Arnold, Industrious Media LLC - */ -public abstract class CellFormatter { - /** The original specified format. */ - protected final String format; - - /** - * Creates a new formatter object, storing the format in {@link #format}. - * - * @param format The format. - */ - public CellFormatter(String format) { - this.format = format; - } - - /** The logger to use in the formatting code. */ - static final Logger logger = Logger.getLogger( - CellFormatter.class.getName()); - - /** - * Format a value according the format string. - * - * @param toAppendTo The buffer to append to. - * @param value The value to format. - */ - public abstract void formatValue(StringBuffer toAppendTo, Object value); - - /** - * Format a value according to the type, in the most basic way. - * - * @param toAppendTo The buffer to append to. - * @param value The value to format. - */ - public abstract void simpleValue(StringBuffer toAppendTo, Object value); - - /** - * Formats the value, returning the resulting string. - * - * @param value The value to format. - * - * @return The value, formatted. - */ - public String format(Object value) { - StringBuffer sb = new StringBuffer(); - formatValue(sb, value); - return sb.toString(); - } - - /** - * Formats the value in the most basic way, returning the resulting string. - * - * @param value The value to format. - * - * @return The value, formatted. - */ - public String simpleFormat(Object value) { - StringBuffer sb = new StringBuffer(); - simpleValue(sb, value); - return sb.toString(); - } - - /** - * Returns the input string, surrounded by quotes. - * - * @param str The string to quote. - * - * @return The input string, surrounded by quotes. - */ - static String quote(String str) { - return '"' + str + '"'; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java b/trunk/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java deleted file mode 100644 index b890e0217..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.util.Formatter; -import java.util.Locale; - -import org.apache.poi.util.LocaleUtil; - -/** - * A formatter for the default "General" cell format. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class CellGeneralFormatter extends CellFormatter { - /** Creates a new general formatter. */ - public CellGeneralFormatter() { - super("General"); - } - - /** - * The general style is not quite the same as any other, or any combination - * of others. - * - * @param toAppendTo The buffer to append to. - * @param value The value to format. - */ - public void formatValue(StringBuffer toAppendTo, Object value) { - if (value instanceof Number) { - double val = ((Number) value).doubleValue(); - if (val == 0) { - toAppendTo.append('0'); - return; - } - - String fmt; - double exp = Math.log10(Math.abs(val)); - boolean stripZeros = true; - if (exp > 10 || exp < -9) - fmt = "%1.5E"; - else if ((long) val != val) - fmt = "%1.9f"; - else { - fmt = "%1.0f"; - stripZeros = false; - } - - Formatter formatter = new Formatter(toAppendTo, LocaleUtil.getUserLocale()); - try { - formatter.format(LocaleUtil.getUserLocale(), fmt, value); - } finally { - formatter.close(); - } - if (stripZeros) { - // strip off trailing zeros - int removeFrom; - if (fmt.endsWith("E")) - removeFrom = toAppendTo.lastIndexOf("E") - 1; - else - removeFrom = toAppendTo.length() - 1; - while (toAppendTo.charAt(removeFrom) == '0') { - toAppendTo.deleteCharAt(removeFrom--); - } - if (toAppendTo.charAt(removeFrom) == '.') { - toAppendTo.deleteCharAt(removeFrom--); - } - } - } else if (value instanceof Boolean) { - toAppendTo.append(value.toString().toUpperCase(Locale.ROOT)); - } else { - toAppendTo.append(value.toString()); - } - } - - /** Equivalent to {@link #formatValue(StringBuffer,Object)}. {@inheritDoc}. */ - public void simpleValue(StringBuffer toAppendTo, Object value) { - formatValue(toAppendTo, value); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellNumberFormatter.java b/trunk/src/java/org/apache/poi/ss/format/CellNumberFormatter.java deleted file mode 100644 index 668149f85..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellNumberFormatter.java +++ /dev/null @@ -1,819 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.FieldPosition; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.Formatter; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Set; -import java.util.TreeSet; - -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This class implements printing out a value using a number format. - */ -public class CellNumberFormatter extends CellFormatter { - private static final POILogger LOG = POILogFactory.getLogger(CellNumberFormatter.class); - - private final String desc; - private final String printfFmt; - private final double scale; - private final Special decimalPoint; - private final Special slash; - private final Special exponent; - private final Special numerator; - private final Special afterInteger; - private final Special afterFractional; - private final boolean integerCommas; - private final List specials = new ArrayList(); - private final List integerSpecials = new ArrayList(); - private final List fractionalSpecials = new ArrayList(); - private final List numeratorSpecials = new ArrayList(); - private final List denominatorSpecials = new ArrayList(); - private final List exponentSpecials = new ArrayList(); - private final List exponentDigitSpecials = new ArrayList(); - private final int maxDenominator; - private final String numeratorFmt; - private final String denominatorFmt; - private final boolean improperFraction; - private final DecimalFormat decimalFmt; - - // The CellNumberFormatter.simpleValue() method uses the SIMPLE_NUMBER - // CellFormatter defined here. The CellFormat.GENERAL_FORMAT CellFormat - // no longer uses the SIMPLE_NUMBER CellFormatter. - // Note that the simpleValue()/SIMPLE_NUMBER CellFormatter format - // ("#" for integer values, and "#.#" for floating-point values) is - // different from the 'General' format for numbers ("#" for integer - // values and "#.#########" for floating-point values). - private static final CellFormatter SIMPLE_NUMBER = new GeneralNumberFormatter(); - private static final CellFormatter SIMPLE_INT = new CellNumberFormatter("#"); - private static final CellFormatter SIMPLE_FLOAT = new CellNumberFormatter("#.#"); - - private static class GeneralNumberFormatter extends CellFormatter { - private GeneralNumberFormatter() { - super("General"); - } - - public void formatValue(StringBuffer toAppendTo, Object value) { - if (value == null) { - return; - } - - CellFormatter cf; - if (value instanceof Number) { - Number num = (Number) value; - cf = (num.doubleValue() % 1.0 == 0) ? SIMPLE_INT : SIMPLE_FLOAT; - } else { - cf = CellTextFormatter.SIMPLE_TEXT; - } - cf.formatValue(toAppendTo, value); - } - - public void simpleValue(StringBuffer toAppendTo, Object value) { - formatValue(toAppendTo, value); - } - } - - - /** - * This class is used to mark where the special characters in the format - * are, as opposed to the other characters that are simply printed. - */ - /* package */ static class Special { - final char ch; - int pos; - - Special(char ch, int pos) { - this.ch = ch; - this.pos = pos; - } - - @Override - public String toString() { - return "'" + ch + "' @ " + pos; - } - } - - /** - * Creates a new cell number formatter. - * - * @param format The format to parse. - */ - public CellNumberFormatter(String format) { - super(format); - - CellNumberPartHandler ph = new CellNumberPartHandler(); - StringBuffer descBuf = CellFormatPart.parseFormat(format, CellFormatType.NUMBER, ph); - - exponent = ph.getExponent(); - specials.addAll(ph.getSpecials()); - improperFraction = ph.isImproperFraction(); - - // These are inconsistent settings, so ditch 'em - if ((ph.getDecimalPoint() != null || ph.getExponent() != null) && ph.getSlash() != null) { - slash = null; - numerator = null; - } else { - slash = ph.getSlash(); - numerator = ph.getNumerator(); - } - - final int precision = interpretPrecision(ph.getDecimalPoint(), specials); - int fractionPartWidth = 0; - if (ph.getDecimalPoint() != null) { - fractionPartWidth = 1 + precision; - if (precision == 0) { - // This means the format has a ".", but that output should have no decimals after it. - // We just stop treating it specially - specials.remove(ph.getDecimalPoint()); - decimalPoint = null; - } else { - decimalPoint = ph.getDecimalPoint(); - } - } else { - decimalPoint = null; - } - - if (decimalPoint != null) { - afterInteger = decimalPoint; - } else if (exponent != null) { - afterInteger = exponent; - } else if (numerator != null) { - afterInteger = numerator; - } else { - afterInteger = null; - } - - if (exponent != null) { - afterFractional = exponent; - } else if (numerator != null) { - afterFractional = numerator; - } else { - afterFractional = null; - } - - double scaleByRef[] = { ph.getScale() }; - integerCommas = interpretIntegerCommas(descBuf, specials, decimalPoint, integerEnd(), fractionalEnd(), scaleByRef); - if (exponent == null) { - scale = scaleByRef[0]; - } else { - // in "e" formats,% and trailing commas have no scaling effect - scale = 1; - } - - if (precision != 0) { - // TODO: if decimalPoint is null (-> index == -1), return the whole list? - fractionalSpecials.addAll(specials.subList(specials.indexOf(decimalPoint) + 1, fractionalEnd())); - } - - if (exponent != null) { - int exponentPos = specials.indexOf(exponent); - exponentSpecials.addAll(specialsFor(exponentPos, 2)); - exponentDigitSpecials.addAll(specialsFor(exponentPos + 2)); - } - - if (slash != null) { - if (numerator != null) { - numeratorSpecials.addAll(specialsFor(specials.indexOf(numerator))); - } - - denominatorSpecials.addAll(specialsFor(specials.indexOf(slash) + 1)); - if (denominatorSpecials.isEmpty()) { - // no denominator follows the slash, drop the fraction idea - numeratorSpecials.clear(); - maxDenominator = 1; - numeratorFmt = null; - denominatorFmt = null; - } else { - maxDenominator = maxValue(denominatorSpecials); - numeratorFmt = singleNumberFormat(numeratorSpecials); - denominatorFmt = singleNumberFormat(denominatorSpecials); - } - } else { - maxDenominator = 1; - numeratorFmt = null; - denominatorFmt = null; - } - - integerSpecials.addAll(specials.subList(0, integerEnd())); - - if (exponent == null) { - StringBuffer fmtBuf = new StringBuffer("%"); - - int integerPartWidth = calculateIntegerPartWidth(); - int totalWidth = integerPartWidth + fractionPartWidth; - - fmtBuf.append('0').append(totalWidth).append('.').append(precision); - - fmtBuf.append("f"); - printfFmt = fmtBuf.toString(); - decimalFmt = null; - } else { - StringBuffer fmtBuf = new StringBuffer(); - boolean first = true; - List specialList = integerSpecials; - if (integerSpecials.size() == 1) { - // If we don't do this, we get ".6e5" instead of "6e4" - fmtBuf.append("0"); - first = false; - } else - for (Special s : specialList) { - if (isDigitFmt(s)) { - fmtBuf.append(first ? '#' : '0'); - first = false; - } - } - if (fractionalSpecials.size() > 0) { - fmtBuf.append('.'); - for (Special s : fractionalSpecials) { - if (isDigitFmt(s)) { - if (!first) - fmtBuf.append('0'); - first = false; - } - } - } - fmtBuf.append('E'); - placeZeros(fmtBuf, exponentSpecials.subList(2, exponentSpecials.size())); - DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(LocaleUtil.getUserLocale()); - decimalFmt = new DecimalFormat(fmtBuf.toString(), dfs); - printfFmt = null; - } - - desc = descBuf.toString(); - } - - private static void placeZeros(StringBuffer sb, List specials) { - for (Special s : specials) { - if (isDigitFmt(s)) { - sb.append('0'); - } - } - } - - private static CellNumberStringMod insertMod(Special special, CharSequence toAdd, int where) { - return new CellNumberStringMod(special, toAdd, where); - } - - private static CellNumberStringMod deleteMod(Special start, boolean startInclusive, Special end, boolean endInclusive) { - return new CellNumberStringMod(start, startInclusive, end, endInclusive); - } - - private static CellNumberStringMod replaceMod(Special start, boolean startInclusive, Special end, boolean endInclusive, char withChar) { - return new CellNumberStringMod(start, startInclusive, end, endInclusive, withChar); - } - - private static String singleNumberFormat(List numSpecials) { - return "%0" + numSpecials.size() + "d"; - } - - private static int maxValue(List s) { - return (int) Math.round(Math.pow(10, s.size()) - 1); - } - - private List specialsFor(int pos, int takeFirst) { - if (pos >= specials.size()) { - return Collections.emptyList(); - } - ListIterator it = specials.listIterator(pos + takeFirst); - Special last = it.next(); - int end = pos + takeFirst; - while (it.hasNext()) { - Special s = it.next(); - if (!isDigitFmt(s) || s.pos - last.pos > 1) - break; - end++; - last = s; - } - return specials.subList(pos, end + 1); - } - - private List specialsFor(int pos) { - return specialsFor(pos, 0); - } - - private static boolean isDigitFmt(Special s) { - return s.ch == '0' || s.ch == '?' || s.ch == '#'; - } - - private int calculateIntegerPartWidth() { - int digitCount = 0; - for (Special s : specials) { - //!! Handle fractions: The previous set of digits before that is the numerator, so we should stop short of that - if (s == afterInteger) { - break; - } else if (isDigitFmt(s)) { - digitCount++; - } - } - return digitCount; - } - - private static int interpretPrecision(Special decimalPoint, List specials) { - int idx = specials.indexOf(decimalPoint); - int precision = 0; - if (idx != -1) { - // skip over the decimal point itself - ListIterator it = specials.listIterator(idx+1); - while (it.hasNext()) { - Special s = it.next(); - if (!isDigitFmt(s)) { - break; - } - precision++; - } - } - return precision; - } - - private static boolean interpretIntegerCommas - (StringBuffer sb, List specials, Special decimalPoint, int integerEnd, int fractionalEnd, double[] scale) { - // In the integer part, commas at the end are scaling commas; other commas mean to show thousand-grouping commas - ListIterator it = specials.listIterator(integerEnd); - - boolean stillScaling = true; - boolean integerCommas = false; - while (it.hasPrevious()) { - Special s = it.previous(); - if (s.ch != ',') { - stillScaling = false; - } else { - if (stillScaling) { - scale[0] /= 1000; - } else { - integerCommas = true; - } - } - } - - if (decimalPoint != null) { - it = specials.listIterator(fractionalEnd); - while (it.hasPrevious()) { - Special s = it.previous(); - if (s.ch != ',') { - break; - } else { - scale[0] /= 1000; - } - } - } - - // Now strip them out -- we only need their interpretation, not their presence - it = specials.listIterator(); - int removed = 0; - while (it.hasNext()) { - Special s = it.next(); - s.pos -= removed; - if (s.ch == ',') { - removed++; - it.remove(); - sb.deleteCharAt(s.pos); - } - } - - return integerCommas; - } - - private int integerEnd() { - return (afterInteger == null) ? specials.size() : specials.indexOf(afterInteger); - } - - private int fractionalEnd() { - return (afterFractional == null) ? specials.size() : specials.indexOf(afterFractional); - } - - /** {@inheritDoc} */ - public void formatValue(StringBuffer toAppendTo, Object valueObject) { - double value = ((Number) valueObject).doubleValue(); - value *= scale; - - // For negative numbers: - // - If the cell format has a negative number format, this method - // is called with a positive value and the number format has - // the negative formatting required, e.g. minus sign or brackets. - // - If the cell format does not have a negative number format, - // this method is called with a negative value and the number is - // formatted with a minus sign at the start. - boolean negative = value < 0; - if (negative) - value = -value; - - // Split out the fractional part if we need to print a fraction - double fractional = 0; - if (slash != null) { - if (improperFraction) { - fractional = value; - value = 0; - } else { - fractional = value % 1.0; - //noinspection SillyAssignment - value = (long) value; - } - } - - Set mods = new TreeSet(); - StringBuffer output = new StringBuffer(desc); - - if (exponent != null) { - writeScientific(value, output, mods); - } else if (improperFraction) { - writeFraction(value, null, fractional, output, mods); - } else { - StringBuffer result = new StringBuffer(); - Formatter f = new Formatter(result, LocaleUtil.getUserLocale()); - try { - f.format(LocaleUtil.getUserLocale(), printfFmt, value); - } finally { - f.close(); - } - - if (numerator == null) { - writeFractional(result, output); - writeInteger(result, output, integerSpecials, mods, integerCommas); - } else { - writeFraction(value, result, fractional, output, mods); - } - } - - // Now strip out any remaining '#'s and add any pending text ... - Iterator changes = mods.iterator(); - CellNumberStringMod nextChange = (changes.hasNext() ? changes.next() : null); - // records chars already deleted - BitSet deletedChars = new BitSet(); - int adjust = 0; - for (Special s : specials) { - int adjustedPos = s.pos + adjust; - if (!deletedChars.get(s.pos) && output.charAt(adjustedPos) == '#') { - output.deleteCharAt(adjustedPos); - adjust--; - deletedChars.set(s.pos); - } - while (nextChange != null && s == nextChange.getSpecial()) { - int lenBefore = output.length(); - int modPos = s.pos + adjust; - switch (nextChange.getOp()) { - case CellNumberStringMod.AFTER: - // ignore adding a comma after a deleted char (which was a '#') - if (nextChange.getToAdd().equals(",") && deletedChars.get(s.pos)) { - break; - } - output.insert(modPos + 1, nextChange.getToAdd()); - break; - case CellNumberStringMod.BEFORE: - output.insert(modPos, nextChange.getToAdd()); - break; - - case CellNumberStringMod.REPLACE: - // delete starting pos in original coordinates - int delPos = s.pos; - if (!nextChange.isStartInclusive()) { - delPos++; - modPos++; - } - - // Skip over anything already deleted - while (deletedChars.get(delPos)) { - delPos++; - modPos++; - } - - // delete end point in original - int delEndPos = nextChange.getEnd().pos; - if (nextChange.isEndInclusive()) { - delEndPos++; - } - - // delete end point in current - int modEndPos = delEndPos + adjust; - - if (modPos < modEndPos) { - if ("".equals(nextChange.getToAdd())) { - output.delete(modPos, modEndPos); - } - else { - char fillCh = nextChange.getToAdd().charAt(0); - for (int i = modPos; i < modEndPos; i++) { - output.setCharAt(i, fillCh); - } - } - deletedChars.set(delPos, delEndPos); - } - break; - - default: - throw new IllegalStateException("Unknown op: " + nextChange.getOp()); - } - adjust += output.length() - lenBefore; - - nextChange = (changes.hasNext()) ? changes.next() : null; - } - } - - // Finally, add it to the string - if (negative) { - toAppendTo.append('-'); - } - toAppendTo.append(output); - } - - private void writeScientific(double value, StringBuffer output, Set mods) { - - StringBuffer result = new StringBuffer(); - FieldPosition fractionPos = new FieldPosition(DecimalFormat.FRACTION_FIELD); - decimalFmt.format(value, result, fractionPos); - writeInteger(result, output, integerSpecials, mods, integerCommas); - writeFractional(result, output); - - /* - * Exponent sign handling is complex. - * - * In DecimalFormat, you never put the sign in the format, and the sign only - * comes out of the format if it is negative. - * - * In Excel, you always say whether to always show the sign ("e+") or only - * show negative signs ("e-"). - * - * Also in Excel, where you put the sign in the format is NOT where it comes - * out in the result. In the format, the sign goes with the "e"; in the - * output it goes with the exponent value. That is, if you say "#e-|#" you - * get "1e|-5", not "1e-|5". This makes sense I suppose, but it complicates - * things. - * - * Finally, everything else in this formatting code assumes that the base of - * the result is the original format, and that starting from that situation, - * the indexes of the original special characters can be used to place the new - * characters. As just described, this is not true for the exponent's sign. - *

        - * So here is how we handle it: - * - * (1) When parsing the format, remove the sign from after the 'e' and put it - * before the first digit of the exponent (where it will be shown). - * - * (2) Determine the result's sign. - * - * (3) If it's missing, put the sign into the output to keep the result - * lined up with the output. (In the result, "after the 'e'" and "before the - * first digit" are the same because the result has no extra chars to be in - * the way.) - * - * (4) In the output, remove the sign if it should not be shown ("e-" was used - * and the sign is negative) or set it to the correct value. - */ - - // (2) Determine the result's sign. - int ePos = fractionPos.getEndIndex(); - int signPos = ePos + 1; - char expSignRes = result.charAt(signPos); - if (expSignRes != '-') { - // not a sign, so it's a digit, and therefore a positive exponent - expSignRes = '+'; - // (3) If it's missing, put the sign into the output to keep the result - // lined up with the output. - result.insert(signPos, '+'); - } - - // Now the result lines up like it is supposed to with the specials' indexes - ListIterator it = exponentSpecials.listIterator(1); - Special expSign = it.next(); - char expSignFmt = expSign.ch; - - // (4) In the output, remove the sign if it should not be shown or set it to - // the correct value. - if (expSignRes == '-' || expSignFmt == '+') { - mods.add(replaceMod(expSign, true, expSign, true, expSignRes)); - } else { - mods.add(deleteMod(expSign, true, expSign, true)); - } - - StringBuffer exponentNum = new StringBuffer(result.substring(signPos + 1)); - writeInteger(exponentNum, output, exponentDigitSpecials, mods, false); - } - - @SuppressWarnings("unchecked") - private void writeFraction(double value, StringBuffer result, - double fractional, StringBuffer output, Set mods) { - - // Figure out if we are to suppress either the integer or fractional part. - // With # the suppressed part is removed; with ? it is replaced with spaces. - if (!improperFraction) { - // If fractional part is zero, and numerator doesn't have '0', write out - // only the integer part and strip the rest. - if (fractional == 0 && !hasChar('0', numeratorSpecials)) { - writeInteger(result, output, integerSpecials, mods, false); - - Special start = lastSpecial(integerSpecials); - Special end = lastSpecial(denominatorSpecials); - if (hasChar('?', integerSpecials, numeratorSpecials, denominatorSpecials)) { - //if any format has '?', then replace the fraction with spaces - mods.add(replaceMod(start, false, end, true, ' ')); - } else { - // otherwise, remove the fraction - mods.add(deleteMod(start, false, end, true)); - } - - // That's all, just return - return; - } else { - // New we check to see if we should remove the integer part - boolean numNoZero = !hasChar('0', numeratorSpecials); - boolean intNoZero = !hasChar('0', integerSpecials); - boolean intOnlyHash = integerSpecials.isEmpty() || (integerSpecials.size() == 1 && hasChar('#', integerSpecials)); - - boolean removeBecauseZero = fractional == 0 && (intOnlyHash || numNoZero); - boolean removeBecauseFraction = fractional != 0 && intNoZero; - - if (value == 0 && (removeBecauseZero || removeBecauseFraction)) { - Special start = lastSpecial(integerSpecials); - boolean hasPlaceHolder = hasChar('?', integerSpecials, numeratorSpecials); - CellNumberStringMod sm = hasPlaceHolder - ? replaceMod(start, true, numerator, false, ' ') - : deleteMod(start, true, numerator, false); - mods.add(sm); - } else { - // Not removing the integer part -- print it out - writeInteger(result, output, integerSpecials, mods, false); - } - } - } - - // Calculate and print the actual fraction (improper or otherwise) - try { - int n; - int d; - // the "fractional % 1" captures integer values in improper fractions - if (fractional == 0 || (improperFraction && fractional % 1 == 0)) { - // 0 as a fraction is reported by excel as 0/1 - n = (int) Math.round(fractional); - d = 1; - } else { - SimpleFraction frac = SimpleFraction.buildFractionMaxDenominator(fractional, maxDenominator); - n = frac.getNumerator(); - d = frac.getDenominator(); - } - if (improperFraction) { - n += Math.round(value * d); - } - writeSingleInteger(numeratorFmt, n, output, numeratorSpecials, mods); - writeSingleInteger(denominatorFmt, d, output, denominatorSpecials, mods); - } catch (RuntimeException ignored) { - LOG.log(POILogger.ERROR, "error while fraction evaluation", ignored); - } - } - - private static boolean hasChar(char ch, List... numSpecials) { - for (List specials : numSpecials) { - for (Special s : specials) { - if (s.ch == ch) { - return true; - } - } - } - return false; - } - - private void writeSingleInteger(String fmt, int num, StringBuffer output, List numSpecials, Set mods) { - - StringBuffer sb = new StringBuffer(); - Formatter formatter = new Formatter(sb, LocaleUtil.getUserLocale()); - try { - formatter.format(LocaleUtil.getUserLocale(), fmt, num); - } finally { - formatter.close(); - } - writeInteger(sb, output, numSpecials, mods, false); - } - - private void writeInteger(StringBuffer result, StringBuffer output, - List numSpecials, Set mods, - boolean showCommas) { - - int pos = result.indexOf(".") - 1; - if (pos < 0) { - if (exponent != null && numSpecials == integerSpecials) { - pos = result.indexOf("E") - 1; - } else { - pos = result.length() - 1; - } - } - - int strip; - for (strip = 0; strip < pos; strip++) { - char resultCh = result.charAt(strip); - if (resultCh != '0' && resultCh != ',') { - break; - } - } - - ListIterator it = numSpecials.listIterator(numSpecials.size()); - boolean followWithComma = false; - Special lastOutputIntegerDigit = null; - int digit = 0; - while (it.hasPrevious()) { - char resultCh; - if (pos >= 0) { - resultCh = result.charAt(pos); - } else { - // If result is shorter than field, pretend there are leading zeros - resultCh = '0'; - } - Special s = it.previous(); - followWithComma = showCommas && digit > 0 && digit % 3 == 0; - boolean zeroStrip = false; - if (resultCh != '0' || s.ch == '0' || s.ch == '?' || pos >= strip) { - zeroStrip = s.ch == '?' && pos < strip; - output.setCharAt(s.pos, (zeroStrip ? ' ' : resultCh)); - lastOutputIntegerDigit = s; - } - if (followWithComma) { - mods.add(insertMod(s, zeroStrip ? " " : ",", CellNumberStringMod.AFTER)); - followWithComma = false; - } - digit++; - --pos; - } - StringBuffer extraLeadingDigits = new StringBuffer(); - if (pos >= 0) { - // We ran out of places to put digits before we ran out of digits; put this aside so we can add it later - // pos was decremented at the end of the loop above when the iterator was at its end - ++pos; - extraLeadingDigits = new StringBuffer(result.substring(0, pos)); - if (showCommas) { - while (pos > 0) { - if (digit > 0 && digit % 3 == 0) { - extraLeadingDigits.insert(pos, ','); - } - digit++; - --pos; - } - } - mods.add(insertMod(lastOutputIntegerDigit, extraLeadingDigits, CellNumberStringMod.BEFORE)); - } - } - - private void writeFractional(StringBuffer result, StringBuffer output) { - int digit; - int strip; - if (fractionalSpecials.size() > 0) { - digit = result.indexOf(".") + 1; - if (exponent != null) { - strip = result.indexOf("e") - 1; - } else { - strip = result.length() - 1; - } - - while (strip > digit && result.charAt(strip) == '0') { - strip--; - } - - for (Special s : fractionalSpecials) { - char resultCh = result.charAt(digit); - if (resultCh != '0' || s.ch == '0' || digit < strip) { - output.setCharAt(s.pos, resultCh); - } else if (s.ch == '?') { - // This is when we're in trailing zeros, and the format is '?'. - // We still strip out remaining '#'s later - output.setCharAt(s.pos, ' '); - } - digit++; - } - } - } - - /** - * {@inheritDoc} - *

        - * For a number, this is "#" for integer values, and "#.#" - * for floating-point values. - */ - public void simpleValue(StringBuffer toAppendTo, Object value) { - SIMPLE_NUMBER.formatValue(toAppendTo, value); - } - - private static Special lastSpecial(List s) { - return s.get(s.size() - 1); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellNumberPartHandler.java b/trunk/src/java/org/apache/poi/ss/format/CellNumberPartHandler.java deleted file mode 100644 index f563db249..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellNumberPartHandler.java +++ /dev/null @@ -1,164 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.regex.Matcher; - -import org.apache.poi.ss.format.CellFormatPart.PartHandler; -import org.apache.poi.ss.format.CellNumberFormatter.Special; -import org.apache.poi.util.Internal; - -/** - * Internal helper class for CellNumberFormatter - */ -@Internal -public class CellNumberPartHandler implements PartHandler { - private char insertSignForExponent; - private double scale = 1; - private Special decimalPoint; - private Special slash; - private Special exponent; - private Special numerator; - private final List specials = new LinkedList(); - private boolean improperFraction; - - public String handlePart(Matcher m, String part, CellFormatType type, StringBuffer descBuf) { - int pos = descBuf.length(); - char firstCh = part.charAt(0); - switch (firstCh) { - case 'e': - case 'E': - // See comment in writeScientific -- exponent handling is complex. - // (1) When parsing the format, remove the sign from after the 'e' and - // put it before the first digit of the exponent. - if (exponent == null && specials.size() > 0) { - exponent = new Special('.', pos); - specials.add(exponent); - insertSignForExponent = part.charAt(1); - return part.substring(0, 1); - } - break; - - case '0': - case '?': - case '#': - if (insertSignForExponent != '\0') { - specials.add(new Special(insertSignForExponent, pos)); - descBuf.append(insertSignForExponent); - insertSignForExponent = '\0'; - pos++; - } - for (int i = 0; i < part.length(); i++) { - char ch = part.charAt(i); - specials.add(new Special(ch, pos + i)); - } - break; - - case '.': - if (decimalPoint == null && specials.size() > 0) { - decimalPoint = new Special('.', pos); - specials.add(decimalPoint); - } - break; - - case '/': - //!! This assumes there is a numerator and a denominator, but these are actually optional - if (slash == null && specials.size() > 0) { - numerator = previousNumber(); - // If the first number in the whole format is the numerator, the - // entire number should be printed as an improper fraction - improperFraction |= (numerator == firstDigit(specials)); - slash = new Special('.', pos); - specials.add(slash); - } - break; - - case '%': - // don't need to remember because we don't need to do anything with these - scale *= 100; - break; - - default: - return null; - } - return part; - } - - public double getScale() { - return scale; - } - - public Special getDecimalPoint() { - return decimalPoint; - } - - public Special getSlash() { - return slash; - } - - public Special getExponent() { - return exponent; - } - - public Special getNumerator() { - return numerator; - } - - public List getSpecials() { - return specials; - } - - public boolean isImproperFraction() { - return improperFraction; - } - - private Special previousNumber() { - ListIterator it = specials.listIterator(specials.size()); - while (it.hasPrevious()) { - Special s = it.previous(); - if (isDigitFmt(s)) { - Special last = s; - while (it.hasPrevious()) { - s = it.previous(); - // it has to be continuous digits - if (last.pos - s.pos > 1 || !isDigitFmt(s)) { - break; - } - last = s; - } - return last; - } - } - return null; - } - - private static boolean isDigitFmt(Special s) { - return s.ch == '0' || s.ch == '?' || s.ch == '#'; - } - - private static Special firstDigit(List specials) { - for (Special s : specials) { - if (isDigitFmt(s)) { - return s; - } - } - return null; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellNumberStringMod.java b/trunk/src/java/org/apache/poi/ss/format/CellNumberStringMod.java deleted file mode 100644 index a053206a8..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellNumberStringMod.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import org.apache.poi.ss.format.CellNumberFormatter.Special; -import org.apache.poi.util.Internal; - -/** - * Internal helper class for CellNumberFormatter - * - * This class represents a single modification to a result string. The way - * this works is complicated, but so is numeric formatting. In general, for - * most formats, we use a DecimalFormat object that will put the string out - * in a known format, usually with all possible leading and trailing zeros. - * We then walk through the result and the original format, and note any - * modifications that need to be made. Finally, we go through and apply - * them all, dealing with overlapping modifications. - */ -@Internal -public class CellNumberStringMod implements Comparable { - public static final int BEFORE = 1; - public static final int AFTER = 2; - public static final int REPLACE = 3; - - private final Special special; - private final int op; - private CharSequence toAdd; - private Special end; - private boolean startInclusive; - private boolean endInclusive; - - public CellNumberStringMod(Special special, CharSequence toAdd, int op) { - this.special = special; - this.toAdd = toAdd; - this.op = op; - } - - public CellNumberStringMod(Special start, boolean startInclusive, Special end, boolean endInclusive, char toAdd) { - this(start, startInclusive, end, endInclusive); - this.toAdd = toAdd + ""; - } - - public CellNumberStringMod(Special start, boolean startInclusive, Special end, boolean endInclusive) { - special = start; - this.startInclusive = startInclusive; - this.end = end; - this.endInclusive = endInclusive; - op = REPLACE; - toAdd = ""; - } - - public int compareTo(CellNumberStringMod that) { - int diff = special.pos - that.special.pos; - return (diff != 0) ? diff : (op - that.op); - } - - @Override - public boolean equals(Object that) { - try { - return compareTo((CellNumberStringMod) that) == 0; - } catch (RuntimeException ignored) { - // NullPointerException or CastException - return false; - } - } - - @Override - public int hashCode() { - return special.hashCode() + op; - } - - public Special getSpecial() { - return special; - } - - public int getOp() { - return op; - } - - public CharSequence getToAdd() { - return toAdd; - } - - public Special getEnd() { - return end; - } - - public boolean isStartInclusive() { - return startInclusive; - } - - public boolean isEndInclusive() { - return endInclusive; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/CellTextFormatter.java b/trunk/src/java/org/apache/poi/ss/format/CellTextFormatter.java deleted file mode 100644 index bde29e2ea..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/CellTextFormatter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import org.apache.poi.ss.format.CellFormatPart.PartHandler; - -import java.util.Locale; -import java.util.regex.Matcher; - -/** - * This class implements printing out text. - * - * @author Ken Arnold, Industrious Media LLC - */ -public class CellTextFormatter extends CellFormatter { - private final int[] textPos; - private final String desc; - - static final CellFormatter SIMPLE_TEXT = new CellTextFormatter("@"); - - public CellTextFormatter(String format) { - super(format); - - final int[] numPlaces = new int[1]; - - desc = CellFormatPart.parseFormat(format, CellFormatType.TEXT, - new PartHandler() { - public String handlePart(Matcher m, String part, - CellFormatType type, StringBuffer desc) { - if (part.equals("@")) { - numPlaces[0]++; - return "\u0000"; - } - return null; - } - }).toString(); - - // Remember the "@" positions in last-to-first order (to make insertion easier) - textPos = new int[numPlaces[0]]; - int pos = desc.length() - 1; - for (int i = 0; i < textPos.length; i++) { - textPos[i] = desc.lastIndexOf("\u0000", pos); - pos = textPos[i] - 1; - } - } - - /** {@inheritDoc} */ - public void formatValue(StringBuffer toAppendTo, Object obj) { - int start = toAppendTo.length(); - String text = obj.toString(); - if (obj instanceof Boolean) { - text = text.toUpperCase(Locale.ROOT); - } - toAppendTo.append(desc); - for (int i = 0; i < textPos.length; i++) { - int pos = start + textPos[i]; - toAppendTo.replace(pos, pos + 1, text); - } - } - - /** - * {@inheritDoc} - *

        - * For text, this is just printing the text. - */ - public void simpleValue(StringBuffer toAppendTo, Object value) { - SIMPLE_TEXT.formatValue(toAppendTo, value); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/format/SimpleFraction.java b/trunk/src/java/org/apache/poi/ss/format/SimpleFraction.java deleted file mode 100644 index dec5a275f..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/SimpleFraction.java +++ /dev/null @@ -1,170 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -package org.apache.poi.ss.format; - -public class SimpleFraction { - - - /** The denominator. */ - private final int denominator; - - /** The numerator. */ - private final int numerator; - /** - * Create a fraction given a double value and a denominator. - * - * @param val double value of fraction - * @param exactDenom the exact denominator - * @return a SimpleFraction with the given values set. - */ - public static SimpleFraction buildFractionExactDenominator(double val, int exactDenom){ - int num = (int)Math.round(val*exactDenom); - return new SimpleFraction(num,exactDenom); - } - - /** - * Create a fraction given the double value and either the maximum error - * allowed or the maximum number of denominator digits. - * - * @param value the double value to convert to a fraction. - * @param maxDenominator maximum denominator value allowed. - * - * @throws RuntimeException if the continued fraction failed to - * converge. - * @throws IllegalArgumentException if value > Integer.MAX_VALUE - */ - public static SimpleFraction buildFractionMaxDenominator(double value, int maxDenominator){ - return buildFractionMaxDenominator(value, 0, maxDenominator, 100); - } - /** - * Create a fraction given the double value and either the maximum error - * allowed or the maximum number of denominator digits. - *

        - * References: - *

        - *

        - * - * Based on org.apache.commons.math.fraction.Fraction from Apache Commons-Math. - * YK: The only reason of having this class is to avoid dependency on the Commons-Math jar. - * - * @param value the double value to convert to a fraction. - * @param epsilon maximum error allowed. The resulting fraction is within - * epsilon of value, in absolute terms. - * @param maxDenominator maximum denominator value allowed. - * @param maxIterations maximum number of convergents - * @throws RuntimeException if the continued fraction failed to - * converge. - * @throws IllegalArgumentException if value > Integer.MAX_VALUE - */ - private static SimpleFraction buildFractionMaxDenominator(double value, double epsilon, int maxDenominator, int maxIterations) - { - long overflow = Integer.MAX_VALUE; - double r0 = value; - long a0 = (long)Math.floor(r0); - if (a0 > overflow) { - throw new IllegalArgumentException("Overflow trying to convert "+value+" to fraction ("+a0+"/"+1l+")"); - } - - // check for (almost) integer arguments, which should not go - // to iterations. - if (Math.abs(a0 - value) < epsilon) { - return new SimpleFraction((int)a0, 1); - } - - long p0 = 1; - long q0 = 0; - long p1 = a0; - long q1 = 1; - - long p2; - long q2; - - int n = 0; - boolean stop = false; - do { - ++n; - double r1 = 1.0 / (r0 - a0); - long a1 = (long)Math.floor(r1); - p2 = (a1 * p1) + p0; - q2 = (a1 * q1) + q0; - //MATH-996/POI-55419 - if (epsilon == 0.0f && maxDenominator > 0 && Math.abs(q2) > maxDenominator && - Math.abs(q1) < maxDenominator){ - - return new SimpleFraction((int)p1, (int)q1); - } - if ((p2 > overflow) || (q2 > overflow)) { - throw new RuntimeException("Overflow trying to convert "+value+" to fraction ("+p2+"/"+q2+")"); - } - - double convergent = (double)p2 / (double)q2; - if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) { - p0 = p1; - p1 = p2; - q0 = q1; - q1 = q2; - a0 = a1; - r0 = r1; - } else { - stop = true; - } - } while (!stop); - - if (n >= maxIterations) { - throw new RuntimeException("Unable to convert "+value+" to fraction after "+maxIterations+" iterations"); - } - - if (q2 < maxDenominator) { - return new SimpleFraction((int) p2, (int)q2); - } else { - return new SimpleFraction((int)p1, (int)q1); - } - - } - - /** - * Create a fraction given a numerator and denominator. - * @param numerator - * @param denominator maxDenominator The maximum allowed value for denominator - */ - public SimpleFraction(int numerator, int denominator) - { - this.numerator = numerator; - this.denominator = denominator; - } - - /** - * Access the denominator. - * @return the denominator. - */ - public int getDenominator() { - return denominator; - } - - /** - * Access the numerator. - * @return the numerator. - */ - public int getNumerator() { - return numerator; - } - -} - diff --git a/trunk/src/java/org/apache/poi/ss/format/package.html b/trunk/src/java/org/apache/poi/ss/format/package.html deleted file mode 100644 index 4c0096d3c..000000000 --- a/trunk/src/java/org/apache/poi/ss/format/package.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -This package contains classes that implement cell formatting - - diff --git a/trunk/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java b/trunk/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java deleted file mode 100644 index 74872de75..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java +++ /dev/null @@ -1,285 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Map; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * Common functionality across file formats for evaluating formula cells.

        - */ -public abstract class BaseFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider { - protected final WorkbookEvaluator _bookEvaluator; - - protected BaseFormulaEvaluator(WorkbookEvaluator bookEvaluator) { - this._bookEvaluator = bookEvaluator; - } - - /** - * Coordinates several formula evaluators together so that formulas that involve external - * references can be evaluated. - * @param workbookNames the simple file names used to identify the workbooks in formulas - * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1") - * @param evaluators all evaluators for the full set of workbooks required by the formulas. - */ - public static void setupEnvironment(String[] workbookNames, BaseFormulaEvaluator[] evaluators) { - WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length]; - for (int i = 0; i < wbEvals.length; i++) { - wbEvals[i] = evaluators[i]._bookEvaluator; - } - CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals); - } - - @Override - public void setupReferencedWorkbooks(Map evaluators) { - CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators); - } - - @Override - public WorkbookEvaluator _getWorkbookEvaluator() { - return _bookEvaluator; - } - - /** - * Should be called whenever there are major changes (e.g. moving sheets) to input cells - * in the evaluated workbook. If performance is not critical, a single call to this method - * may be used instead of many specific calls to the notify~ methods. - * - * Failure to call this method after changing cell values will cause incorrect behaviour - * of the evaluate~ methods of this class - */ - @Override - public void clearAllCachedResultValues() { - _bookEvaluator.clearAllCachedResultValues(); - } - - /** - * If cell contains a formula, the formula is evaluated and returned, - * else the CellValue simply copies the appropriate cell value from - * the cell and also its cell type. This method should be preferred over - * evaluateInCell() when the call should not modify the contents of the - * original cell. - * - * @param cell may be null signifying that the cell is not present (or blank) - * @return null if the supplied cell is null or blank - */ - @Override - public CellValue evaluate(Cell cell) { - if (cell == null) { - return null; - } - - switch (cell.getCellTypeEnum()) { - case BOOLEAN: - return CellValue.valueOf(cell.getBooleanCellValue()); - case ERROR: - return CellValue.getError(cell.getErrorCellValue()); - case FORMULA: - return evaluateFormulaCellValue(cell); - case NUMERIC: - return new CellValue(cell.getNumericCellValue()); - case STRING: - return new CellValue(cell.getRichStringCellValue().getString()); - case BLANK: - return null; - default: - throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")"); - } - } - - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of HSSFCell is returned to - * allow chained calls like: - *

        -     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
        -     * 
        - * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}} - * @param cell - * @return the {@code cell} that was passed in, allowing for chained calls - */ - @Override - public Cell evaluateInCell(Cell cell) { - if (cell == null) { - return null; - } - Cell result = cell; - if (cell.getCellTypeEnum() == CellType.FORMULA) { - CellValue cv = evaluateFormulaCellValue(cell); - setCellValue(cell, cv); - setCellType(cell, cv); // cell will no longer be a formula cell - } - return result; - } - - protected abstract CellValue evaluateFormulaCellValue(Cell cell); - - /** - * If cell contains formula, it evaluates the formula, and saves the result of the formula. The - * cell remains as a formula cell. If the cell does not contain formula, this method returns -1 - * and leaves the cell unchanged. - * - * Note that the type of the formula result is returned, so you know what kind of - * cached formula result is also stored with the formula. - *
        -     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
        -     * 
        - * Be aware that your cell will hold both the formula, and the result. If you want the cell - * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} - * @param cell The cell to evaluate - * @return -1 for non-formula cells, or the type of the formula result - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int evaluateFormulaCell(Cell cell) { - return evaluateFormulaCellEnum(cell).getCode(); - } - - /** - * If cell contains formula, it evaluates the formula, - * and saves the result of the formula. The cell - * remains as a formula cell. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the type of the formula result is returned, - * so you know what kind of value is also stored with - * the formula. - *
        -     * CellType evaluatedCellType = evaluator.evaluateFormulaCellEnum(cell);
        -     * 
        - * Be aware that your cell will hold both the formula, - * and the result. If you want the cell replaced with - * the result of the formula, use {@link #evaluate(org.apache.poi.ss.usermodel.Cell)} } - * @param cell The cell to evaluate - * @return The type of the formula result (the cell's type remains as CellType.FORMULA however) - * If cell is not a formula cell, returns {@link CellType#_NONE} rather than throwing an exception. - * @since POI 3.15 beta 3 - */ - @Override - public CellType evaluateFormulaCellEnum(Cell cell) { - if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) { - return CellType._NONE; - } - CellValue cv = evaluateFormulaCellValue(cell); - // cell remains a formula cell, but the cached value is changed - setCellValue(cell, cv); - return cv.getCellTypeEnum(); - } - - protected static void setCellType(Cell cell, CellValue cv) { - CellType cellType = cv.getCellTypeEnum(); - switch (cellType) { - case BOOLEAN: - case ERROR: - case NUMERIC: - case STRING: - cell.setCellType(cellType); - return; - case BLANK: - // never happens - blanks eventually get translated to zero - throw new IllegalArgumentException("This should never happen. Blanks eventually get translated to zero."); - case FORMULA: - // this will never happen, we have already evaluated the formula - throw new IllegalArgumentException("This should never happen. Formulas should have already been evaluated."); - default: - throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); - } - } - - protected abstract RichTextString createRichTextString(String str); - - protected void setCellValue(Cell cell, CellValue cv) { - CellType cellType = cv.getCellTypeEnum(); - switch (cellType) { - case BOOLEAN: - cell.setCellValue(cv.getBooleanValue()); - break; - case ERROR: - cell.setCellErrorValue(cv.getErrorValue()); - break; - case NUMERIC: - cell.setCellValue(cv.getNumberValue()); - break; - case STRING: - cell.setCellValue(createRichTextString(cv.getStringValue())); - break; - case BLANK: - // never happens - blanks eventually get translated to zero - case FORMULA: - // this will never happen, we have already evaluated the formula - default: - throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); - } - } - - - /** - * Loops over all cells in all sheets of the supplied - * workbook. - * For cells that contain formulas, their formulas are - * evaluated, and the results are saved. These cells - * remain as formula cells. - * For cells that do not contain formulas, no changes - * are made. - * This is a helpful wrapper around looping over all - * cells, and calling evaluateFormulaCell on each one. - */ - public static void evaluateAllFormulaCells(Workbook wb) { - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - evaluateAllFormulaCells(wb, evaluator); - } - protected static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) { - for(int i=0; i - */ -abstract class CellCacheEntry implements ICacheEntry { - public static final CellCacheEntry[] EMPTY_ARRAY = { }; - - private final FormulaCellCacheEntrySet _consumingCells; - private ValueEval _value; - - - protected CellCacheEntry() { - _consumingCells = new FormulaCellCacheEntrySet(); - } - protected final void clearValue() { - _value = null; - } - - public final boolean updateValue(ValueEval value) { - if (value == null) { - throw new IllegalArgumentException("Did not expect to update to null"); - } - boolean result = !areValuesEqual(_value, value); - _value = value; - return result; - } - public final ValueEval getValue() { - return _value; - } - - private static boolean areValuesEqual(ValueEval a, ValueEval b) { - if (a == null) { - return false; - } - Class cls = a.getClass(); - if (cls != b.getClass()) { - // value type is changing - return false; - } - if (a == BlankEval.instance) { - return b == a; - } - if (cls == NumberEval.class) { - return ((NumberEval)a).getNumberValue() == ((NumberEval)b).getNumberValue(); - } - if (cls == StringEval.class) { - return ((StringEval)a).getStringValue().equals(((StringEval)b).getStringValue()); - } - if (cls == BoolEval.class) { - return ((BoolEval)a).getBooleanValue() == ((BoolEval)b).getBooleanValue(); - } - if (cls == ErrorEval.class) { - return ((ErrorEval)a).getErrorCode() == ((ErrorEval)b).getErrorCode(); - } - throw new IllegalStateException("Unexpected value class (" + cls.getName() + ")"); - } - - public final void addConsumingCell(FormulaCellCacheEntry cellLoc) { - _consumingCells.add(cellLoc); - - } - public final FormulaCellCacheEntry[] getConsumingCells() { - return _consumingCells.toArray(); - } - - public final void clearConsumingCell(FormulaCellCacheEntry cce) { - if(!_consumingCells.remove(cce)) { - throw new IllegalStateException("Specified formula cell is not consumed by this cell"); - } - } - public final void recurseClearCachedFormulaResults(IEvaluationListener listener) { - if (listener == null) { - recurseClearCachedFormulaResults(); - } else { - listener.onClearCachedValue(this); - recurseClearCachedFormulaResults(listener, 1); - } - } - - /** - * Calls formulaCell.setFormulaResult(null, null) recursively all the way up the tree of - * dependencies. Calls usedCell.clearConsumingCell(fc) for each child of a cell that is - * cleared along the way. - * @param formulaCells - */ - protected final void recurseClearCachedFormulaResults() { - FormulaCellCacheEntry[] formulaCells = getConsumingCells(); - - for (int i = 0; i < formulaCells.length; i++) { - FormulaCellCacheEntry fc = formulaCells[i]; - fc.clearFormulaEntry(); - fc.recurseClearCachedFormulaResults(); - } - } - - /** - * Identical to {@link #recurseClearCachedFormulaResults()} except for the listener call-backs - */ - protected final void recurseClearCachedFormulaResults(IEvaluationListener listener, int depth) { - FormulaCellCacheEntry[] formulaCells = getConsumingCells(); - - listener.sortDependentCachedValues(formulaCells); - for (int i = 0; i < formulaCells.length; i++) { - FormulaCellCacheEntry fc = formulaCells[i]; - listener.onClearDependentCachedValue(fc, depth); - fc.clearFormulaEntry(); - fc.recurseClearCachedFormulaResults(listener, depth+1); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java b/trunk/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java deleted file mode 100644 index 2f9c9521f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.HashSet; -import java.util.Set; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Stores details about the current evaluation of a cell.
        - */ -final class CellEvaluationFrame { - - private final FormulaCellCacheEntry _cce; - private final Set _sensitiveInputCells; - private FormulaUsedBlankCellSet _usedBlankCellGroup; - - public CellEvaluationFrame(FormulaCellCacheEntry cce) { - _cce = cce; - _sensitiveInputCells = new HashSet(); - } - public CellCacheEntry getCCE() { - return _cce; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append("]"); - return sb.toString(); - } - /** - * @param inputCell a cell directly used by the formula of this evaluation frame - */ - public void addSensitiveInputCell(CellCacheEntry inputCell) { - _sensitiveInputCells.add(inputCell); - } - /** - * @return never null, (possibly empty) array of all cells directly used while - * evaluating the formula of this frame. - */ - private CellCacheEntry[] getSensitiveInputCells() { - int nItems = _sensitiveInputCells.size(); - if (nItems < 1) { - return CellCacheEntry.EMPTY_ARRAY; - } - CellCacheEntry[] result = new CellCacheEntry[nItems]; - _sensitiveInputCells.toArray(result); - return result; - } - public void addUsedBlankCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) { - if (_usedBlankCellGroup == null) { - _usedBlankCellGroup = new FormulaUsedBlankCellSet(); - } - _usedBlankCellGroup.addCell(bookIndex, sheetIndex, rowIndex, columnIndex); - } - - public void updateFormulaResult(ValueEval result) { - _cce.updateFormulaResult(result, getSensitiveInputCells(), _usedBlankCellGroup); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java b/trunk/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java deleted file mode 100644 index 58ce3d929..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java +++ /dev/null @@ -1,198 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.util.Internal; - -/** - * Manages a collection of {@link WorkbookEvaluator}s, in order to support - * evaluation of formulas across spreadsheets. - * - *

        For POI internal use only - use

        - */ -@Internal -public final class CollaboratingWorkbooksEnvironment { - - public static final class WorkbookNotFoundException extends Exception { - private static final long serialVersionUID = 8787784539811167941L; - - WorkbookNotFoundException(String msg) { - super(msg); - } - } - - public static final CollaboratingWorkbooksEnvironment EMPTY = new CollaboratingWorkbooksEnvironment(); - - private final Map _evaluatorsByName; - private final WorkbookEvaluator[] _evaluators; - - private boolean _unhooked; - private CollaboratingWorkbooksEnvironment() { - _evaluatorsByName = Collections.emptyMap(); - _evaluators = new WorkbookEvaluator[0]; - } - - public static void setup(String[] workbookNames, WorkbookEvaluator[] evaluators) { - int nItems = workbookNames.length; - if (evaluators.length != nItems) { - throw new IllegalArgumentException("Number of workbook names is " + nItems - + " but number of evaluators is " + evaluators.length); - } - if (nItems < 1) { - throw new IllegalArgumentException("Must provide at least one collaborating worbook"); - } - new CollaboratingWorkbooksEnvironment(workbookNames, evaluators, nItems); - } - public static void setup(Map evaluatorsByName) { - if (evaluatorsByName.size() < 1) { - throw new IllegalArgumentException("Must provide at least one collaborating worbook"); - } - WorkbookEvaluator[] evaluators = - evaluatorsByName.values().toArray(new WorkbookEvaluator[evaluatorsByName.size()]); - new CollaboratingWorkbooksEnvironment(evaluatorsByName, evaluators); - } - public static void setupFormulaEvaluator(Map evaluators) { - Map evaluatorsByName = new HashMap(evaluators.size()); - for (Map.Entry swb : evaluators.entrySet()) { - String wbName = swb.getKey(); - FormulaEvaluator eval = swb.getValue(); - if (eval instanceof WorkbookEvaluatorProvider) { - evaluatorsByName.put(wbName, ((WorkbookEvaluatorProvider)eval)._getWorkbookEvaluator()); - } else { - throw new IllegalArgumentException("Formula Evaluator " + eval + - " provides no WorkbookEvaluator access"); - } - } - setup(evaluatorsByName); - } - - private CollaboratingWorkbooksEnvironment(String[] workbookNames, WorkbookEvaluator[] evaluators, int nItems) { - this(toUniqueMap(workbookNames, evaluators, nItems), evaluators); - } - private static Map toUniqueMap(String[] workbookNames, WorkbookEvaluator[] evaluators, int nItems) { - Map evaluatorsByName = new HashMap(nItems * 3 / 2); - for(int i=0; i evaluatorsByName, WorkbookEvaluator[] evaluators) { - IdentityHashMap uniqueEvals = new IdentityHashMap(evaluators.length); - for (Map.Entry me : evaluatorsByName.entrySet()) { - String uniEval = uniqueEvals.put(me.getValue(), me.getKey()); - if (uniEval != null) { - String msg = "Attempted to register same workbook under names '" + - uniEval + "' and '" + me.getKey() + "'"; - throw new IllegalArgumentException(msg); - } - } - unhookOldEnvironments(evaluators); - hookNewEnvironment(evaluators, this); - _unhooked = false; - _evaluators = evaluators.clone(); - _evaluatorsByName = evaluatorsByName; - } - - private static void hookNewEnvironment(WorkbookEvaluator[] evaluators, CollaboratingWorkbooksEnvironment env) { - // All evaluators will need to share the same cache. - // but the cache takes an optional evaluation listener. - int nItems = evaluators.length; - IEvaluationListener evalListener = evaluators[0].getEvaluationListener(); - // make sure that all evaluators have the same listener - for(int i=0; i oldEnvs = new HashSet(); - for(int i=0; i i = _evaluatorsByName.keySet().iterator(); - int count=0; - while(i.hasNext()) { - if (count++>0) { - sb.append(", "); - } - sb.append("'").append(i.next()).append("'"); - } - sb.append(")"); - } - throw new WorkbookNotFoundException(sb.toString()); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/EvaluationCache.java b/trunk/src/java/org/apache/poi/ss/formula/EvaluationCache.java deleted file mode 100644 index cd68db397..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/EvaluationCache.java +++ /dev/null @@ -1,219 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.FormulaCellCache.IEntryOperation; -import org.apache.poi.ss.formula.FormulaUsedBlankCellSet.BookSheetKey; -import org.apache.poi.ss.formula.PlainCellCache.Loc; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.CellType; - -/** - * Performance optimisation for {@link org.apache.poi.ss.usermodel.FormulaEvaluator}. - * This class stores previously calculated values of already visited cells, - * to avoid unnecessary re-calculation when the same cells are referenced multiple times - * - * @author Josh Micich - */ -final class EvaluationCache { - - private final PlainCellCache _plainCellCache; - private final FormulaCellCache _formulaCellCache; - /** only used for testing. null otherwise */ - final IEvaluationListener _evaluationListener; - - /* package */EvaluationCache(IEvaluationListener evaluationListener) { - _evaluationListener = evaluationListener; - _plainCellCache = new PlainCellCache(); - _formulaCellCache = new FormulaCellCache(); - } - - public void notifyUpdateCell(int bookIndex, int sheetIndex, EvaluationCell cell) { - FormulaCellCacheEntry fcce = _formulaCellCache.get(cell); - - int rowIndex = cell.getRowIndex(); - int columnIndex = cell.getColumnIndex(); - Loc loc = new Loc(bookIndex, sheetIndex, rowIndex, columnIndex); - PlainValueCellCacheEntry pcce = _plainCellCache.get(loc); - - if (cell.getCellTypeEnum() == CellType.FORMULA) { - if (fcce == null) { - fcce = new FormulaCellCacheEntry(); - if (pcce == null) { - if (_evaluationListener != null) { - _evaluationListener.onChangeFromBlankValue(sheetIndex, rowIndex, - columnIndex, cell, fcce); - } - updateAnyBlankReferencingFormulas(bookIndex, sheetIndex, rowIndex, - columnIndex); - } - _formulaCellCache.put(cell, fcce); - } else { - fcce.recurseClearCachedFormulaResults(_evaluationListener); - fcce.clearFormulaEntry(); - } - if (pcce == null) { - // was formula cell before - no change of type - } else { - // changing from plain cell to formula cell - pcce.recurseClearCachedFormulaResults(_evaluationListener); - _plainCellCache.remove(loc); - } - } else { - ValueEval value = WorkbookEvaluator.getValueFromNonFormulaCell(cell); - if (pcce == null) { - if (value != BlankEval.instance) { - // only cache non-blank values in the plain cell cache - // (dependencies on blank cells are managed by - // FormulaCellCacheEntry._usedBlankCellGroup) - pcce = new PlainValueCellCacheEntry(value); - if (fcce == null) { - if (_evaluationListener != null) { - _evaluationListener.onChangeFromBlankValue(sheetIndex, rowIndex, columnIndex, cell, pcce); - } - updateAnyBlankReferencingFormulas(bookIndex, sheetIndex, - rowIndex, columnIndex); - } - _plainCellCache.put(loc, pcce); - } - } else { - if (pcce.updateValue(value)) { - pcce.recurseClearCachedFormulaResults(_evaluationListener); - } - if (value == BlankEval.instance) { - _plainCellCache.remove(loc); - } - } - if (fcce == null) { - // was plain cell before - no change of type - } else { - // was formula cell before - now a plain value - _formulaCellCache.remove(cell); - fcce.setSensitiveInputCells(null); - fcce.recurseClearCachedFormulaResults(_evaluationListener); - } - } - } - - private void updateAnyBlankReferencingFormulas(int bookIndex, int sheetIndex, - final int rowIndex, final int columnIndex) { - final BookSheetKey bsk = new BookSheetKey(bookIndex, sheetIndex); - _formulaCellCache.applyOperation(new IEntryOperation() { - - public void processEntry(FormulaCellCacheEntry entry) { - entry.notifyUpdatedBlankCell(bsk, rowIndex, columnIndex, _evaluationListener); - } - }); - } - - public PlainValueCellCacheEntry getPlainValueEntry(int bookIndex, int sheetIndex, - int rowIndex, int columnIndex, ValueEval value) { - - Loc loc = new Loc(bookIndex, sheetIndex, rowIndex, columnIndex); - PlainValueCellCacheEntry result = _plainCellCache.get(loc); - if (result == null) { - result = new PlainValueCellCacheEntry(value); - _plainCellCache.put(loc, result); - if (_evaluationListener != null) { - _evaluationListener.onReadPlainValue(sheetIndex, rowIndex, columnIndex, result); - } - } else { - // TODO - if we are confident that this sanity check is not required, we can remove 'value' from plain value cache entry - if (!areValuesEqual(result.getValue(), value)) { - throw new IllegalStateException("value changed"); - } - if (_evaluationListener != null) { - _evaluationListener.onCacheHit(sheetIndex, rowIndex, columnIndex, value); - } - } - return result; - } - private boolean areValuesEqual(ValueEval a, ValueEval b) { - if (a == null) { - return false; - } - Class cls = a.getClass(); - if (cls != b.getClass()) { - // value type is changing - return false; - } - if (a == BlankEval.instance) { - return b == a; - } - if (cls == NumberEval.class) { - return ((NumberEval)a).getNumberValue() == ((NumberEval)b).getNumberValue(); - } - if (cls == StringEval.class) { - return ((StringEval)a).getStringValue().equals(((StringEval)b).getStringValue()); - } - if (cls == BoolEval.class) { - return ((BoolEval)a).getBooleanValue() == ((BoolEval)b).getBooleanValue(); - } - if (cls == ErrorEval.class) { - return ((ErrorEval)a).getErrorCode() == ((ErrorEval)b).getErrorCode(); - } - throw new IllegalStateException("Unexpected value class (" + cls.getName() + ")"); - } - - public FormulaCellCacheEntry getOrCreateFormulaCellEntry(EvaluationCell cell) { - FormulaCellCacheEntry result = _formulaCellCache.get(cell); - if (result == null) { - - result = new FormulaCellCacheEntry(); - _formulaCellCache.put(cell, result); - } - return result; - } - - /** - * Should be called whenever there are changes to input cells in the evaluated workbook. - */ - public void clear() { - if(_evaluationListener != null) { - _evaluationListener.onClearWholeCache(); - } - _plainCellCache.clear(); - _formulaCellCache.clear(); - } - public void notifyDeleteCell(int bookIndex, int sheetIndex, EvaluationCell cell) { - - if (cell.getCellTypeEnum() == CellType.FORMULA) { - FormulaCellCacheEntry fcce = _formulaCellCache.remove(cell); - if (fcce == null) { - // formula cell has not been evaluated yet - } else { - fcce.setSensitiveInputCells(null); - fcce.recurseClearCachedFormulaResults(_evaluationListener); - } - } else { - Loc loc = new Loc(bookIndex, sheetIndex, cell.getRowIndex(), cell.getColumnIndex()); - PlainValueCellCacheEntry pcce = _plainCellCache.get(loc); - - if (pcce == null) { - // cache entry doesn't exist. nothing to do - } else { - pcce.recurseClearCachedFormulaResults(_evaluationListener); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/EvaluationCell.java b/trunk/src/java/org/apache/poi/ss/formula/EvaluationCell.java deleted file mode 100644 index a7e855c44..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/EvaluationCell.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.usermodel.CellType; - -/** - * Abstracts a cell for the purpose of formula evaluation. This interface represents both formula - * and non-formula cells.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface EvaluationCell { - /** - * @return an Object that identifies the underlying cell, - * suitable for use as a key in a {@link java.util.HashMap} - */ - Object getIdentityKey(); - - EvaluationSheet getSheet(); - int getRowIndex(); - int getColumnIndex(); - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - int getCellType(); - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - CellType getCellTypeEnum(); - - double getNumericCellValue(); - String getStringCellValue(); - boolean getBooleanCellValue(); - int getErrorCellValue(); - - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type of cached formula result - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - int getCachedFormulaResultType(); - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - CellType getCachedFormulaResultTypeEnum(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/EvaluationName.java b/trunk/src/java/org/apache/poi/ss/formula/EvaluationName.java deleted file mode 100644 index 2d1fbf5e2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/EvaluationName.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.Ptg; -/** - * Abstracts a name record for formula evaluation.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface EvaluationName { - - String getNameText(); - - boolean isFunctionName(); - - boolean hasFormula(); - - Ptg[] getNameDefinition(); - - boolean isRange(); - NamePtg createPtg(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/EvaluationSheet.java b/trunk/src/java/org/apache/poi/ss/formula/EvaluationSheet.java deleted file mode 100644 index 1d5b0655a..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/EvaluationSheet.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.util.Internal; - -/** - * Abstracts a sheet for the purpose of formula evaluation.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -@Internal -public interface EvaluationSheet { - - /** - * @return null if there is no cell at the specified coordinates - */ - EvaluationCell getCell(int rowIndex, int columnIndex); - - /** - * Propagated from {@link EvaluationWorkbook#clearAllCachedResultValues()} to clear locally cached data. - * - * @see WorkbookEvaluator#clearAllCachedResultValues() - * @see EvaluationWorkbook#clearAllCachedResultValues() - * @since POI 3.15 beta 3 - */ - public void clearAllCachedResultValues(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/EvaluationTracker.java b/trunk/src/java/org/apache/poi/ss/formula/EvaluationTracker.java deleted file mode 100644 index ef7cb1187..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/EvaluationTracker.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Instances of this class keep track of multiple dependent cell evaluations due - * to recursive calls to {@link WorkbookEvaluator#evaluate(EvaluationCell)}} - * The main purpose of this class is to detect an attempt to evaluate a cell - * that is already being evaluated. In other words, it detects circular - * references in spreadsheet formulas. - * - * @author Josh Micich - */ -final class EvaluationTracker { - // TODO - consider deleting this class and letting CellEvaluationFrame take care of itself - private final List _evaluationFrames; - private final Set _currentlyEvaluatingCells; - private final EvaluationCache _cache; - - public EvaluationTracker(EvaluationCache cache) { - _cache = cache; - _evaluationFrames = new ArrayList(); - _currentlyEvaluatingCells = new HashSet(); - } - - /** - * Notifies this evaluation tracker that evaluation of the specified cell is - * about to start.
        - * - * In the case of a true return code, the caller should - * continue evaluation of the specified cell, and also be sure to call - * endEvaluate() when complete.
        - * - * In the case of a null return code, the caller should - * return an evaluation result of - * ErrorEval.CIRCULAR_REF_ERROR, and not call endEvaluate(). - *
        - * @return false if the specified cell is already being evaluated - */ - public boolean startEvaluate(FormulaCellCacheEntry cce) { - if (cce == null) { - throw new IllegalArgumentException("cellLoc must not be null"); - } - if (_currentlyEvaluatingCells.contains(cce)) { - return false; - } - _currentlyEvaluatingCells.add(cce); - _evaluationFrames.add(new CellEvaluationFrame(cce)); - return true; - } - - public void updateCacheResult(ValueEval result) { - - int nFrames = _evaluationFrames.size(); - if (nFrames < 1) { - throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate"); - } - CellEvaluationFrame frame = _evaluationFrames.get(nFrames-1); - if (result == ErrorEval.CIRCULAR_REF_ERROR && nFrames > 1) { - // Don't cache a circular ref error result if this cell is not the top evaluated cell. - // A true circular ref error will propagate all the way around the loop. However, it's - // possible to have parts of the formula tree (/ parts of the loop) to evaluate to - // CIRCULAR_REF_ERROR, and that value not get used in the final cell result (see the - // unit tests for a simple example). Thus, the only CIRCULAR_REF_ERROR result that can - // safely be cached is that of the top evaluated cell. - return; - } - - frame.updateFormulaResult(result); - } - - /** - * Notifies this evaluation tracker that the evaluation of the specified cell is complete.

        - * - * Every successful call to startEvaluate must be followed by a call to endEvaluate (recommended in a finally block) to enable - * proper tracking of which cells are being evaluated at any point in time.

        - * - * Assuming a well behaved client, parameters to this method would not be - * required. However, they have been included to assert correct behaviour, - * and form more meaningful error messages. - */ - public void endEvaluate(CellCacheEntry cce) { - - int nFrames = _evaluationFrames.size(); - if (nFrames < 1) { - throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate"); - } - - nFrames--; - CellEvaluationFrame frame = _evaluationFrames.get(nFrames); - if (cce != frame.getCCE()) { - throw new IllegalStateException("Wrong cell specified. "); - } - // else - no problems so pop current frame - _evaluationFrames.remove(nFrames); - _currentlyEvaluatingCells.remove(cce); - } - - public void acceptFormulaDependency(CellCacheEntry cce) { - // Tell the currently evaluating cell frame that it has a dependency on the specified - int prevFrameIndex = _evaluationFrames.size()-1; - if (prevFrameIndex < 0) { - // Top level frame, there is no 'cell' above this frame that is using the current cell - } else { - CellEvaluationFrame consumingFrame = _evaluationFrames.get(prevFrameIndex); - consumingFrame.addSensitiveInputCell(cce); - } - } - - public void acceptPlainValueDependency(int bookIndex, int sheetIndex, - int rowIndex, int columnIndex, ValueEval value) { - // Tell the currently evaluating cell frame that it has a dependency on the specified - int prevFrameIndex = _evaluationFrames.size() - 1; - if (prevFrameIndex < 0) { - // Top level frame, there is no 'cell' above this frame that is using the current cell - } else { - CellEvaluationFrame consumingFrame = _evaluationFrames.get(prevFrameIndex); - if (value == BlankEval.instance) { - consumingFrame.addUsedBlankCell(bookIndex, sheetIndex, rowIndex, columnIndex); - } else { - PlainValueCellCacheEntry cce = _cache.getPlainValueEntry(bookIndex, sheetIndex, - rowIndex, columnIndex, value); - consumingFrame.addSensitiveInputCell(cce); - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java b/trunk/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java deleted file mode 100644 index 6c4c17eb3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.util.Internal; - -/** - * Abstracts a workbook for the purpose of formula evaluation.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -@Internal -public interface EvaluationWorkbook { - String getSheetName(int sheetIndex); - /** - * @return -1 if the specified sheet is from a different book - */ - int getSheetIndex(EvaluationSheet sheet); - /** - * Finds a sheet index by case insensitive name. - * @return the index of the sheet matching the specified name. -1 if not found - */ - int getSheetIndex(String sheetName); - - EvaluationSheet getSheet(int sheetIndex); - - /** - * HSSF Only - fetch the external-style sheet details - *

        Return will have no workbook set if it's actually in our own workbook

        - */ - ExternalSheet getExternalSheet(int externSheetIndex); - /** - * XSSF Only - fetch the external-style sheet details - *

        Return will have no workbook set if it's actually in our own workbook

        - */ - ExternalSheet getExternalSheet(String firstSheetName, String lastSheetName, int externalWorkbookNumber); - /** - * HSSF Only - convert an external sheet index to an internal sheet index, - * for an external-style reference to one of this workbook's own sheets - */ - int convertFromExternSheetIndex(int externSheetIndex); - - /** - * HSSF Only - fetch the external-style name details - */ - ExternalName getExternalName(int externSheetIndex, int externNameIndex); - /** - * XSSF Only - fetch the external-style name details - */ - ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber); - - EvaluationName getName(NamePtg namePtg); - EvaluationName getName(String name, int sheetIndex); - String resolveNameXText(NameXPtg ptg); - Ptg[] getFormulaTokens(EvaluationCell cell); - UDFFinder getUDFFinder(); - - /** - * Propagated from {@link WorkbookEvaluator#clearAllCachedResultValues()} to clear locally cached data. - * Implementations must call the same method on all referenced {@link EvaluationSheet} instances, as well as clearing local caches. - * @see WorkbookEvaluator#clearAllCachedResultValues() - * - * @since POI 3.15 beta 3 - */ - public void clearAllCachedResultValues(); - - class ExternalSheet { - private final String _workbookName; - private final String _sheetName; - - public ExternalSheet(String workbookName, String sheetName) { - _workbookName = workbookName; - _sheetName = sheetName; - } - public String getWorkbookName() { - return _workbookName; - } - public String getSheetName() { - return _sheetName; - } - } - class ExternalSheetRange extends ExternalSheet { - private final String _lastSheetName; - public ExternalSheetRange(String workbookName, String firstSheetName, String lastSheetName) { - super(workbookName, firstSheetName); - this._lastSheetName = lastSheetName; - } - - public String getFirstSheetName() { - return getSheetName(); - } - public String getLastSheetName() { - return _lastSheetName; - } - } - class ExternalName { - private final String _nameName; - private final int _nameNumber; - private final int _ix; - - public ExternalName(String nameName, int nameNumber, int ix) { - _nameName = nameName; - _nameNumber = nameNumber; - _ix = ix; - } - public String getName() { - return _nameName; - } - public int getNumber() { - return _nameNumber; - } - public int getIx() { - return _ix; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java b/trunk/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java deleted file mode 100644 index ce67dadc1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -/** - * Should be implemented by any {@link org.apache.poi.ss.formula.ptg.Ptg} subclass that needs has an extern sheet index
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface ExternSheetReferenceToken { - int getExternSheetIndex(); - /** - * @return formula text for this reference token without the qualifying sheet name - */ - String format2DRefAsString(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/Formula.java b/trunk/src/java/org/apache/poi/ss/formula/Formula.java deleted file mode 100644 index 9f4f25e90..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/Formula.java +++ /dev/null @@ -1,195 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Arrays; - -import org.apache.poi.ss.formula.ptg.ExpPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.TblPtg; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayInputStream; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Encapsulates an encoded formula token array. - * - * @author Josh Micich - */ -public class Formula { - - private static final Formula EMPTY = new Formula(new byte[0], 0); - - /** immutable */ - private final byte[] _byteEncoding; - private final int _encodedTokenLen; - - private Formula(byte[] byteEncoding, int encodedTokenLen) { - _byteEncoding = byteEncoding.clone(); - _encodedTokenLen = encodedTokenLen; -// if (false) { // set to true to eagerly check Ptg decoding -// LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding); -// Ptg.readTokens(encodedTokenLen, in); -// int nUnusedBytes = _byteEncoding.length - in.getReadIndex(); -// if (nUnusedBytes > 0) { -// // TODO - this seems to occur when IntersectionPtg is present -// // This example file "IntersectionPtg.xls" -// // used by test: TestIntersectionPtg.testReading() -// // has 10 bytes unused at the end of the formula -// // 10 extra bytes are just 0x01 and 0x00 -// System.out.println(nUnusedBytes + " unused bytes at end of formula"); -// } -// } - } - /** - * Convenience method for {@link #read(int, LittleEndianInput, int)} - */ - public static Formula read(int encodedTokenLen, LittleEndianInput in) { - return read(encodedTokenLen, in, encodedTokenLen); - } - /** - * When there are no array constants present, encodedTokenLen==totalEncodedLen - * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens - * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding - * for array constants, but does not include 2 bytes for initial ushort encodedTokenLen field. - * @return A new formula object as read from the stream. Possibly empty, never null. - */ - public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) { - byte[] byteEncoding = new byte[totalEncodedLen]; - in.readFully(byteEncoding); - return new Formula(byteEncoding, encodedTokenLen); - } - - public Ptg[] getTokens() { - LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding); - return Ptg.readTokens(_encodedTokenLen, in); - } - /** - * Writes The formula encoding is includes: - *
          - *
        • ushort tokenDataLen
        • - *
        • tokenData
        • - *
        • arrayConstantData (if present)
        • - *
        - */ - public void serialize(LittleEndianOutput out) { - out.writeShort(_encodedTokenLen); - out.write(_byteEncoding); - } - - public void serializeTokens(LittleEndianOutput out) { - out.write(_byteEncoding, 0, _encodedTokenLen); - } - public void serializeArrayConstantData(LittleEndianOutput out) { - int len = _byteEncoding.length-_encodedTokenLen; - out.write(_byteEncoding, _encodedTokenLen, len); - } - - - /** - * @return total formula encoding length. The formula encoding includes: - *
          - *
        • ushort tokenDataLen
        • - *
        • tokenData
        • - *
        • arrayConstantData (optional)
        • - *
        - * Note - this value is different to tokenDataLength - */ - public int getEncodedSize() { - return 2 + _byteEncoding.length; - } - /** - * This method is often used when the formula length does not appear immediately before - * the encoded token data. - * - * @return the encoded length of the plain formula tokens. This does not include - * the leading ushort field, nor any trailing array constant data. - */ - public int getEncodedTokenSize() { - return _encodedTokenLen; - } - - /** - * Creates a {@link Formula} object from a supplied {@link Ptg} array. - * Handles nulls OK. - * @param ptgs may be null - * @return Never null (Possibly empty if the supplied ptgs is null) - */ - public static Formula create(Ptg[] ptgs) { - if (ptgs == null || ptgs.length < 1) { - return EMPTY; - } - int totalSize = Ptg.getEncodedSize(ptgs); - byte[] encodedData = new byte[totalSize]; - Ptg.serializePtgs(ptgs, encodedData, 0); - int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs); - return new Formula(encodedData, encodedTokenLen); - } - /** - * Gets the {@link Ptg} array from the supplied {@link Formula}. - * Handles nulls OK. - * - * @param formula may be null - * @return possibly null (if the supplied formula is null) - */ - public static Ptg[] getTokens(Formula formula) { - if (formula == null) { - return null; - } - return formula.getTokens(); - } - - public Formula copy() { - // OK to return this because immutable - return this; - } - - /** - * Gets the locator for the corresponding {@link org.apache.poi.hssf.record.SharedFormulaRecord}, - * {@link org.apache.poi.hssf.record.ArrayRecord} or {@link org.apache.poi.hssf.record.TableRecord} - * if this formula belongs to such a grouping. The {@link CellReference} - * returned by this method will match the top left corner of the range of that grouping. - * The return value is usually not the same as the location of the cell containing this formula. - * - * @return the firstRow & firstColumn of an array formula or shared formula that this formula - * belongs to. null if this formula is not part of an array or shared formula. - */ - public CellReference getExpReference() { - byte[] data = _byteEncoding; - if (data.length != 5) { - // tExp and tTbl are always 5 bytes long, and the only ptg in the formula - return null; - } - switch (data[0]) { - case ExpPtg.sid: - break; - case TblPtg.sid: - break; - default: - return null; - } - int firstRow = LittleEndian.getUShort(data, 1); - int firstColumn = LittleEndian.getUShort(data, 3); - return new CellReference(firstRow, firstColumn); - } - public boolean isSame(Formula other) { - return Arrays.equals(_byteEncoding, other._byteEncoding); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCache.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCache.java deleted file mode 100644 index 63a1da166..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCache.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * - * @author Josh Micich - */ -final class FormulaCellCache { - - static interface IEntryOperation { - void processEntry(FormulaCellCacheEntry entry); - } - - private final Map _formulaEntriesByCell; - - public FormulaCellCache() { - // assumes the object returned by EvaluationCell.getIdentityKey() has a well behaved hashCode+equals - _formulaEntriesByCell = new HashMap(); - } - - public CellCacheEntry[] getCacheEntries() { - - FormulaCellCacheEntry[] result = new FormulaCellCacheEntry[_formulaEntriesByCell.size()]; - _formulaEntriesByCell.values().toArray(result); - return result; - } - - public void clear() { - _formulaEntriesByCell.clear(); - } - - /** - * @return null if not found - */ - public FormulaCellCacheEntry get(EvaluationCell cell) { - return _formulaEntriesByCell.get(cell.getIdentityKey()); - } - - public void put(EvaluationCell cell, FormulaCellCacheEntry entry) { - _formulaEntriesByCell.put(cell.getIdentityKey(), entry); - } - - public FormulaCellCacheEntry remove(EvaluationCell cell) { - return _formulaEntriesByCell.remove(cell.getIdentityKey()); - } - - public void applyOperation(IEntryOperation operation) { - Iterator i = _formulaEntriesByCell.values().iterator(); - while (i.hasNext()) { - operation.processEntry(i.next()); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCacheEntry.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCacheEntry.java deleted file mode 100644 index 056195618..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCacheEntry.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.FormulaUsedBlankCellSet.BookSheetKey; - - -/** - * Stores the cached result of a formula evaluation, along with the set of sensitive input cells - */ -final class FormulaCellCacheEntry extends CellCacheEntry { - - /** - * Cells 'used' in the current evaluation of the formula corresponding to this cache entry - * - * If any of the following cells change, this cache entry needs to be cleared - */ - private CellCacheEntry[] _sensitiveInputCells; - - private FormulaUsedBlankCellSet _usedBlankCellGroup; - - public FormulaCellCacheEntry() { - // leave fields un-set - } - - public boolean isInputSensitive() { - if (_sensitiveInputCells != null) { - if (_sensitiveInputCells.length > 0 ) { - return true; - } - } - return _usedBlankCellGroup == null ? false : !_usedBlankCellGroup.isEmpty(); - } - - public void setSensitiveInputCells(CellCacheEntry[] sensitiveInputCells) { - // need to tell all cells that were previously used, but no longer are, - // that they are not consumed by this cell any more - if (sensitiveInputCells == null) { - _sensitiveInputCells = null; - changeConsumingCells(CellCacheEntry.EMPTY_ARRAY); - } else { - _sensitiveInputCells = sensitiveInputCells.clone(); - changeConsumingCells(_sensitiveInputCells); - } - } - - public void clearFormulaEntry() { - CellCacheEntry[] usedCells = _sensitiveInputCells; - if (usedCells != null) { - for (int i = usedCells.length-1; i>=0; i--) { - usedCells[i].clearConsumingCell(this); - } - } - _sensitiveInputCells = null; - clearValue(); - } - - private void changeConsumingCells(CellCacheEntry[] usedCells) { - - CellCacheEntry[] prevUsedCells = _sensitiveInputCells; - int nUsed = usedCells.length; - for (int i = 0; i < nUsed; i++) { - usedCells[i].addConsumingCell(this); - } - if (prevUsedCells == null) { - return; - } - int nPrevUsed = prevUsedCells.length; - if (nPrevUsed < 1) { - return; - } - Set usedSet; - if (nUsed < 1) { - usedSet = Collections.emptySet(); - } else { - usedSet = new HashSet(nUsed * 3 / 2); - for (int i = 0; i < nUsed; i++) { - usedSet.add(usedCells[i]); - } - } - for (int i = 0; i < nPrevUsed; i++) { - CellCacheEntry prevUsed = prevUsedCells[i]; - if (!usedSet.contains(prevUsed)) { - // previously was used by cellLoc, but not anymore - prevUsed.clearConsumingCell(this); - } - } - } - - public void updateFormulaResult(ValueEval result, CellCacheEntry[] sensitiveInputCells, FormulaUsedBlankCellSet usedBlankAreas) { - updateValue(result); - setSensitiveInputCells(sensitiveInputCells); - _usedBlankCellGroup = usedBlankAreas; - } - - public void notifyUpdatedBlankCell(BookSheetKey bsk, int rowIndex, int columnIndex, IEvaluationListener evaluationListener) { - if (_usedBlankCellGroup != null) { - if (_usedBlankCellGroup.containsCell(bsk, rowIndex, columnIndex)) { - clearFormulaEntry(); - recurseClearCachedFormulaResults(evaluationListener); - } - } - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCacheEntrySet.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCacheEntrySet.java deleted file mode 100644 index 9a40cbc95..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaCellCacheEntrySet.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -/** - * A custom implementation of {@link java.util.HashSet} in order to reduce memory consumption. - * - * Profiling tests (Oct 2008) have shown that each element {@link FormulaCellCacheEntry} takes - * around 32 bytes to store in a HashSet, but around 6 bytes to store here. For Spreadsheets with - * thousands of formula cells with multiple interdependencies, the savings can be very significant. - * - * @author Josh Micich - */ -final class FormulaCellCacheEntrySet { - private static final FormulaCellCacheEntry[] EMPTY_ARRAY = { }; - - private int _size; - private FormulaCellCacheEntry[] _arr; - - public FormulaCellCacheEntrySet() { - _arr = EMPTY_ARRAY; - } - - public FormulaCellCacheEntry[] toArray() { - int nItems = _size; - if (nItems < 1) { - return EMPTY_ARRAY; - } - FormulaCellCacheEntry[] result = new FormulaCellCacheEntry[nItems]; - int j=0; - for(int i=0; i<_arr.length; i++) { - FormulaCellCacheEntry cce = _arr[i]; - if (cce != null) { - result[j++] = cce; - } - } - if (j!= nItems) { - throw new IllegalStateException("size mismatch"); - } - return result; - } - - - public void add(CellCacheEntry cce) { - if (_size * 3 >= _arr.length * 2) { - // re-hash - FormulaCellCacheEntry[] prevArr = _arr; - FormulaCellCacheEntry[] newArr = new FormulaCellCacheEntry[4 + _arr.length * 3 / 2]; // grow 50% - for(int i=0; i 8) { - // re-hash - boolean found = false; - FormulaCellCacheEntry[] prevArr = _arr; - FormulaCellCacheEntry[] newArr = new FormulaCellCacheEntry[_arr.length / 2]; // shrink 50% - for(int i=0; i ::= [ ]* - * ::= [ ]* - * ::= | () | | - * ::= ([expression [, expression]*]) - *

        - * For POI internal use only - *

        - */ -@Internal -public final class FormulaParser { - private final static POILogger log = POILogFactory.getLogger(FormulaParser.class); - private final String _formulaString; - private final int _formulaLength; - /** points at the next character to be read (after the {@link #look} char) */ - private int _pointer; - - private ParseNode _rootNode; - - private final static char TAB = '\t'; // HSSF + XSSF - private final static char CR = '\r'; // Normally just XSSF - private final static char LF = '\n'; // Normally just XSSF - - /** - * Lookahead Character. - * gets value '\0' when the input string is exhausted - */ - private char look; - - /** - * Tracks whether the run of whitespace preceding "look" could be an - * intersection operator. See GetChar. - */ - private boolean _inIntersection = false; - - private final FormulaParsingWorkbook _book; - private final SpreadsheetVersion _ssVersion; - - private final int _sheetIndex; - private final int _rowIndex; // 0-based - - - /** - * Create the formula parser, with the string that is to be - * parsed against the supplied workbook. - * A later call the parse() method to return ptg list in - * rpn order, then call the getRPNPtg() to retrieve the - * parse results. - * This class is recommended only for single threaded use. - * - * If you have a {@link org.apache.poi.hssf.usermodel.HSSFWorkbook}, and not a - * {@link org.apache.poi.hssf.model.Workbook}, then use the convenience method on - * {@link org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator} - */ - private FormulaParser(String formula, FormulaParsingWorkbook book, int sheetIndex, int rowIndex) { - _formulaString = formula; - _pointer=0; - _book = book; - _ssVersion = book == null ? SpreadsheetVersion.EXCEL97 : book.getSpreadsheetVersion(); - _formulaLength = _formulaString.length(); - _sheetIndex = sheetIndex; - _rowIndex = rowIndex; - } - - /** - * Parse a formula into an array of tokens - * Side effect: creates name ({@link org.apache.poi.ss.usermodel.Workbook#createName}) - * if formula contains unrecognized names (names are likely UDFs) - * - * @param formula the formula to parse - * @param workbook the parent workbook - * @param formulaType the type of the formula - * @param sheetIndex the 0-based index of the sheet this formula belongs to. - * The sheet index is required to resolve sheet-level names. -1 means that - * the scope of the name will be ignored and the parser will match names only by name - * @param rowIndex - the related cell's row index in 0-based form (-1 if the formula is not cell related) - * used to handle structured references that have the "#This Row" quantifier. - * Use rowIndex=-1 or {@link #parseStructuredReference(String, FormulaParsingWorkbook, int)} if formula - * does not contain structured references. - * - * @return array of parsed tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, FormulaType formulaType, int sheetIndex, int rowIndex) { - FormulaParser fp = new FormulaParser(formula, workbook, sheetIndex, rowIndex); - fp.parse(); - return fp.getRPNPtg(formulaType); - } - - /** - * Parse a formula into an array of tokens - * Side effect: creates name ({@link org.apache.poi.ss.usermodel.Workbook#createName}) - * if formula contains unrecognized names (names are likely UDFs) - * - * @param formula the formula to parse - * @param workbook the parent workbook - * @param formulaType the type of the formula - * @param sheetIndex the 0-based index of the sheet this formula belongs to. - * The sheet index is required to resolve sheet-level names. -1 means that - * the scope of the name will be ignored and the parser will match names only by name - * - * @return array of parsed tokens - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, FormulaType formulaType, int sheetIndex) { - return parse(formula, workbook, formulaType, sheetIndex, -1); - } - - /** - * Parse a structured reference. Converts the structured - * reference to the area that represent it. - * - * @param tableText - The structured reference text - * @param workbook - the parent workbook - * @param rowIndex - the 0-based cell's row index ( used to handle "#This Row" quantifiers ) - * @return the area that being represented by the structured reference. - */ - public static Area3DPxg parseStructuredReference(String tableText, FormulaParsingWorkbook workbook, int rowIndex) { - final int sheetIndex = -1; //don't care? - Ptg[] arr = FormulaParser.parse(tableText, workbook, FormulaType.CELL, sheetIndex, rowIndex); - if (arr.length != 1 || !(arr[0] instanceof Area3DPxg) ) { - throw new IllegalStateException("Illegal structured reference"); - } - return (Area3DPxg) arr[0]; - } - - /** Read New Character From Input Stream */ - private void GetChar() { - // The intersection operator is a space. We track whether the run of - // whitespace preceeding "look" counts as an intersection operator. - if (IsWhite(look)) { - if (look == ' ') { - _inIntersection = true; - } - } - else { - _inIntersection = false; - } - - // Check to see if we've walked off the end of the string. - if (_pointer > _formulaLength) { - throw new RuntimeException("too far"); - } - if (_pointer < _formulaLength) { - look=_formulaString.charAt(_pointer); - } else { - // Just return if so and reset 'look' to something to keep - // SkipWhitespace from spinning - look = (char)0; - _inIntersection = false; - } - _pointer++; - //System.out.println("Got char: "+ look); - } - private void resetPointer(int ptr) { - _pointer = ptr; - if (_pointer <= _formulaLength) { - look=_formulaString.charAt(_pointer-1); - } else { - // Just return if so and reset 'look' to something to keep - // SkipWhitespace from spinning - look = (char)0; - } - } - - /** Report What Was Expected */ - private RuntimeException expected(String s) { - String msg; - - if (look == '=' && _formulaString.substring(0, _pointer-1).trim().length() < 1) { - msg = "The specified formula '" + _formulaString - + "' starts with an equals sign which is not allowed."; - } else { - msg = "Parse error near char " + (_pointer-1) + " '" + look + "'" - + " in specified formula '" + _formulaString + "'. Expected " - + s; - } - return new FormulaParseException(msg); - } - - /** Recognize an Alpha Character */ - private static boolean IsAlpha(char c) { - return Character.isLetter(c) || c == '$' || c=='_'; - } - - /** Recognize a Decimal Digit */ - private static boolean IsDigit(char c) { - return Character.isDigit(c); - } - - /** Recognize White Space */ - private static boolean IsWhite( char c) { - return c ==' ' || c== TAB || c == CR || c == LF; - } - - /** Skip Over Leading White Space */ - private void SkipWhite() { - while (IsWhite(look)) { - GetChar(); - } - } - - /** - * Consumes the next input character if it is equal to the one specified otherwise throws an - * unchecked exception. This method does not consume whitespace (before or after the - * matched character). - */ - private void Match(char x) { - if (look != x) { - throw expected("'" + x + "'"); - } - GetChar(); - } - - /** Get a Number */ - private String GetNum() { - StringBuffer value = new StringBuffer(); - - while (IsDigit(this.look)){ - value.append(this.look); - GetChar(); - } - return value.length() == 0 ? null : value.toString(); - } - - private ParseNode parseRangeExpression() { - ParseNode result = parseRangeable(); - boolean hasRange = false; - while (look == ':') { - int pos = _pointer; - GetChar(); - ParseNode nextPart = parseRangeable(); - // Note - no range simplification here. An expr like "A1:B2:C3:D4:E5" should be - // grouped into area ref pairs like: "(A1:B2):(C3:D4):E5" - // Furthermore, Excel doesn't seem to simplify - // expressions like "Sheet1!A1:Sheet1:B2" into "Sheet1!A1:B2" - - checkValidRangeOperand("LHS", pos, result); - checkValidRangeOperand("RHS", pos, nextPart); - - ParseNode[] children = { result, nextPart, }; - result = new ParseNode(RangePtg.instance, children); - hasRange = true; - } - if (hasRange) { - return augmentWithMemPtg(result); - } - return result; - } - - private static ParseNode augmentWithMemPtg(ParseNode root) { - Ptg memPtg; - if (needsMemFunc(root)) { - memPtg = new MemFuncPtg(root.getEncodedSize()); - } else { - memPtg = new MemAreaPtg(root.getEncodedSize()); - } - return new ParseNode(memPtg, root); - } - /** - * From OOO doc: "Whenever one operand of the reference subexpression is a function, - * a defined name, a 3D reference, or an external reference (and no error occurs), - * a tMemFunc token is used" - * - */ - private static boolean needsMemFunc(ParseNode root) { - Ptg token = root.getToken(); - if (token instanceof AbstractFunctionPtg) { - return true; - } - if (token instanceof ExternSheetReferenceToken) { // 3D refs - return true; - } - if (token instanceof NamePtg || token instanceof NameXPtg) { // 3D refs - return true; - } - - if (token instanceof OperationPtg || token instanceof ParenthesisPtg) { - // expect RangePtg, but perhaps also UnionPtg, IntersectionPtg etc - for(ParseNode child : root.getChildren()) { - if (needsMemFunc(child)) { - return true; - } - } - return false; - } - if (token instanceof OperandPtg) { - return false; - } - if (token instanceof OperationPtg) { - return true; - } - - return false; - } - - /** - * @param currentParsePosition used to format a potential error message - */ - private static void checkValidRangeOperand(String sideName, int currentParsePosition, ParseNode pn) { - if (!isValidRangeOperand(pn)) { - throw new FormulaParseException("The " + sideName - + " of the range operator ':' at position " - + currentParsePosition + " is not a proper reference."); - } - } - - /** - * @return false if sub-expression represented the specified ParseNode definitely - * cannot appear on either side of the range (':') operator - */ - private static boolean isValidRangeOperand(ParseNode a) { - Ptg tkn = a.getToken(); - // Note - order is important for these instance-of checks - if (tkn instanceof OperandPtg) { - // notably cell refs and area refs - return true; - } - - // next 2 are special cases of OperationPtg - if (tkn instanceof AbstractFunctionPtg) { - AbstractFunctionPtg afp = (AbstractFunctionPtg) tkn; - byte returnClass = afp.getDefaultOperandClass(); - return Ptg.CLASS_REF == returnClass; - } - if (tkn instanceof ValueOperatorPtg) { - return false; - } - if (tkn instanceof OperationPtg) { - return true; - } - - // one special case of ControlPtg - if (tkn instanceof ParenthesisPtg) { - // parenthesis Ptg should have only one child - return isValidRangeOperand(a.getChildren()[0]); - } - - // one special case of ScalarConstantPtg - if (tkn == ErrPtg.REF_INVALID) { - return true; - } - - // All other ControlPtgs and ScalarConstantPtgs cannot be used with ':' - return false; - } - - /** - * Parses area refs (things which could be the operand of ':') and simple factors - * Examples - *

        -     *   A$1
        -     *   $A$1 :  $B1
        -     *   A1 .......    C2
        -     *   Sheet1 !$A1
        -     *   a..b!A1
        -     *   'my sheet'!A1
        -     *   .my.sheet!A1
        -     *   'my sheet':'my alt sheet'!A1
        -     *   .my.sheet1:.my.sheet2!$B$2
        -     *   my.named..range.
        -     *   'my sheet'!my.named.range
        -     *   .my.sheet!my.named.range
        -     *   foo.bar(123.456, "abc")
        -     *   123.456
        -     *   "abc"
        -     *   true
        -     *   [Foo.xls]!$A$1
        -     *   [Foo.xls]'my sheet'!$A$1
        -     *   [Foo.xls]!my.named.range
        -     * 
        - * - */ - private ParseNode parseRangeable() { - SkipWhite(); - int savePointer = _pointer; - SheetIdentifier sheetIden = parseSheetName(); - - if (sheetIden == null) { - resetPointer(savePointer); - } else { - SkipWhite(); - savePointer = _pointer; - } - - SimpleRangePart part1 = parseSimpleRangePart(); - if (part1 == null) { - if (sheetIden != null) { - if(look == '#'){ // error ref like MySheet!#REF! - return new ParseNode(ErrPtg.valueOf(parseErrorLiteral())); - } else { - // Is it a named range? - String name = parseAsName(); - if (name.length() == 0) { - throw new FormulaParseException("Cell reference or Named Range " - + "expected after sheet name at index " + _pointer + "."); - } - Ptg nameXPtg = _book.getNameXPtg(name, sheetIden); - if (nameXPtg == null) { - throw new FormulaParseException("Specified name '" + name + - "' for sheet " + sheetIden.asFormulaString() + " not found"); - } - return new ParseNode(nameXPtg); - } - } - return parseNonRange(savePointer); - } - boolean whiteAfterPart1 = IsWhite(look); - if (whiteAfterPart1) { - SkipWhite(); - } - - if (look == ':') { - int colonPos = _pointer; - GetChar(); - SkipWhite(); - SimpleRangePart part2 = parseSimpleRangePart(); - if (part2 != null && !part1.isCompatibleForArea(part2)) { - // second part is not compatible with an area ref e.g. S!A1:S!B2 - // where S might be a sheet name (that looks like a column name) - - part2 = null; - } - if (part2 == null) { - // second part is not compatible with an area ref e.g. A1:OFFSET(B2, 1, 2) - // reset and let caller use explicit range operator - resetPointer(colonPos); - if (!part1.isCell()) { - String prefix = ""; - if (sheetIden != null) { - prefix = "'" + sheetIden.getSheetIdentifier().getName() + '!'; - } - throw new FormulaParseException(prefix + part1.getRep() + "' is not a proper reference."); - } - } - return createAreaRefParseNode(sheetIden, part1, part2); - } - - if (look == '.') { - GetChar(); - int dotCount = 1; - while (look =='.') { - dotCount ++; - GetChar(); - } - boolean whiteBeforePart2 = IsWhite(look); - - SkipWhite(); - SimpleRangePart part2 = parseSimpleRangePart(); - String part1And2 = _formulaString.substring(savePointer-1, _pointer-1); - if (part2 == null) { - if (sheetIden != null) { - throw new FormulaParseException("Complete area reference expected after sheet name at index " - + _pointer + "."); - } - return parseNonRange(savePointer); - } - - - if (whiteAfterPart1 || whiteBeforePart2) { - if (part1.isRowOrColumn() || part2.isRowOrColumn()) { - // "A .. B" not valid syntax for "A:B" - // and there's no other valid expression that fits this grammar - throw new FormulaParseException("Dotted range (full row or column) expression '" - + part1And2 + "' must not contain whitespace."); - } - return createAreaRefParseNode(sheetIden, part1, part2); - } - - if (dotCount == 1 && part1.isRow() && part2.isRow()) { - // actually, this is looking more like a number - return parseNonRange(savePointer); - } - - if (part1.isRowOrColumn() || part2.isRowOrColumn()) { - if (dotCount != 2) { - throw new FormulaParseException("Dotted range (full row or column) expression '" + part1And2 - + "' must have exactly 2 dots."); - } - } - return createAreaRefParseNode(sheetIden, part1, part2); - } - if (part1.isCell() && isValidCellReference(part1.getRep())) { - return createAreaRefParseNode(sheetIden, part1, null); - } - if (sheetIden != null) { - throw new FormulaParseException("Second part of cell reference expected after sheet name at index " - + _pointer + "."); - } - - return parseNonRange(savePointer); - } - - - - private final static String specHeaders = "Headers"; - private final static String specAll = "All"; - private final static String specData = "Data"; - private final static String specTotals = "Totals"; - private final static String specThisRow = "This Row"; - - /** - * Parses a structured reference, returns it as area reference. - * Examples: - *
        -     * Table1[col]
        -     * Table1[[#Totals],[col]]
        -     * Table1[#Totals]
        -     * Table1[#All]
        -     * Table1[#Data]
        -     * Table1[#Headers]
        -     * Table1[#Totals]
        -     * Table1[#This Row]
        -     * Table1[[#All],[col]]
        -     * Table1[[#Headers],[col]]
        -     * Table1[[#Totals],[col]]
        -     * Table1[[#All],[col1]:[col2]]
        -     * Table1[[#Data],[col1]:[col2]]
        -     * Table1[[#Headers],[col1]:[col2]]
        -     * Table1[[#Totals],[col1]:[col2]]
        -     * Table1[[#Headers],[#Data],[col2]]
        -     * Table1[[#This Row], [col1]]
        -     * Table1[ [col1]:[col2] ]
        -     * 
        - * @param tableName - * @return Area Reference for the given table - */ - private ParseNode parseStructuredReference(String tableName) { - - if ( ! (_ssVersion.equals(SpreadsheetVersion.EXCEL2007)) ) { - throw new FormulaParseException("Structured references work only on XSSF (Excel 2007+)!"); - } - Table tbl = _book.getTable(tableName); - if (tbl == null) { - throw new FormulaParseException("Illegal table name: '" + tableName + "'"); - } - String sheetName = tbl.getSheetName(); - - int startCol = tbl.getStartColIndex(); - int endCol = tbl.getEndColIndex(); - int startRow = tbl.getStartRowIndex(); - int endRow = tbl.getEndRowIndex(); - - // Do NOT return before done reading all the structured reference tokens from the input stream. - // Throwing exceptions is okay. - int savePtr0 = _pointer; - GetChar(); - - boolean isTotalsSpec = false; - boolean isThisRowSpec = false; - boolean isDataSpec = false; - boolean isHeadersSpec = false; - boolean isAllSpec = false; - int nSpecQuantifiers = 0; // The number of special quantifiers - while (true) { - int savePtr1 = _pointer; - String specName = parseAsSpecialQuantifier(); - if (specName == null) { - resetPointer(savePtr1); - break; - } - if (specName.equals(specAll)) { - isAllSpec = true; - } else if (specName.equals(specData)) { - isDataSpec = true; - } else if (specName.equals(specHeaders)) { - isHeadersSpec = true; - } else if (specName.equals(specThisRow)) { - isThisRowSpec = true; - } else if (specName.equals(specTotals)) { - isTotalsSpec = true; - } else { - throw new FormulaParseException("Unknown special quantifier "+ specName); - } - nSpecQuantifiers++; - if (look == ','){ - GetChar(); - } else { - break; - } - } - boolean isThisRow = false; - SkipWhite(); - if (look == '@') { - isThisRow = true; - GetChar(); - } - // parse column quantifier - String startColumnName = null; - String endColumnName = null; - int nColQuantifiers = 0; - int savePtr1 = _pointer; - startColumnName = parseAsColumnQuantifier(); - if (startColumnName == null) { - resetPointer(savePtr1); - } else { - nColQuantifiers++; - if (look == ','){ - throw new FormulaParseException("The formula "+ _formulaString + "is illegal: you should not use ',' with column quantifiers"); - } else if (look == ':') { - GetChar(); - endColumnName = parseAsColumnQuantifier(); - nColQuantifiers++; - if (endColumnName == null) { - throw new FormulaParseException("The formula "+ _formulaString + "is illegal: the string after ':' must be column quantifier"); - } - } - } - - if(nColQuantifiers == 0 && nSpecQuantifiers == 0){ - resetPointer(savePtr0); - savePtr0 = _pointer; - startColumnName = parseAsColumnQuantifier(); - if (startColumnName != null) { - nColQuantifiers++; - } else { - resetPointer(savePtr0); - String name = parseAsSpecialQuantifier(); - if (name!=null) { - if (name.equals(specAll)) { - isAllSpec = true; - } else if (name.equals(specData)) { - isDataSpec = true; - } else if (name.equals(specHeaders)) { - isHeadersSpec = true; - } else if (name.equals(specThisRow)) { - isThisRowSpec = true; - } else if (name.equals(specTotals)) { - isTotalsSpec = true; - } else { - throw new FormulaParseException("Unknown special quantifier "+ name); - } - nSpecQuantifiers++; - } else { - throw new FormulaParseException("The formula "+ _formulaString + " is illegal"); - } - } - } else { - Match(']'); - } - // Done reading from input stream - // Ok to return now - - if (isTotalsSpec && !tbl.isHasTotalsRow()) { - return new ParseNode(ErrPtg.REF_INVALID); - } - if ((isThisRow || isThisRowSpec) && (_rowIndex < startRow || endRow < _rowIndex)) { - // structured reference is trying to reference a row above or below the table with [#This Row] or [@] - if (_rowIndex >= 0) { - return new ParseNode(ErrPtg.VALUE_INVALID); - } else { - throw new FormulaParseException( - "Formula contained [#This Row] or [@] structured reference but this row < 0. " + - "Row index must be specified for row-referencing structured references."); - } - } - - int actualStartRow = startRow; - int actualEndRow = endRow; - int actualStartCol = startCol; - int actualEndCol = endCol; - if (nSpecQuantifiers > 0) { - //Selecting rows - if (nSpecQuantifiers == 1 && isAllSpec) { - //do nothing - } else if (isDataSpec && isHeadersSpec) { - if (tbl.isHasTotalsRow()) { - actualEndRow = endRow - 1; - } - } else if (isDataSpec && isTotalsSpec) { - actualStartRow = startRow + 1; - } else if (nSpecQuantifiers == 1 && isDataSpec) { - actualStartRow = startRow + 1; - if (tbl.isHasTotalsRow()) { - actualEndRow = endRow - 1; - } - } else if (nSpecQuantifiers == 1 && isHeadersSpec) { - actualEndRow = actualStartRow; - } else if (nSpecQuantifiers == 1 && isTotalsSpec) { - actualStartRow = actualEndRow; - } else if ((nSpecQuantifiers == 1 && isThisRowSpec) || isThisRow) { - actualStartRow = _rowIndex; //The rowNum is 0 based - actualEndRow = _rowIndex; - } else { - throw new FormulaParseException("The formula "+ _formulaString + " is illegal"); - } - } else { - if (isThisRow) { // there is a @ - actualStartRow = _rowIndex; //The rowNum is 0 based - actualEndRow = _rowIndex; - } else { // Really no special quantifiers - actualStartRow++; - } - } - - //Selecting cols - - if (nColQuantifiers == 2) { - if (startColumnName == null || endColumnName == null) { - throw new IllegalStateException("Fatal error"); - } - int startIdx = tbl.findColumnIndex(startColumnName); - int endIdx = tbl.findColumnIndex(endColumnName); - if (startIdx == -1 || endIdx == -1) { - throw new FormulaParseException("One of the columns "+ startColumnName +", "+ endColumnName +" doesn't exist in table "+ tbl.getName()); - } - actualStartCol = startCol+ startIdx; - actualEndCol = startCol + endIdx; - - } else if (nColQuantifiers == 1 && !isThisRow) { - if (startColumnName == null) { - throw new IllegalStateException("Fatal error"); - } - int idx = tbl.findColumnIndex(startColumnName); - if (idx == -1) { - throw new FormulaParseException("The column "+ startColumnName + " doesn't exist in table "+ tbl.getName()); - } - actualStartCol = startCol + idx; - actualEndCol = actualStartCol; - } - CellReference topLeft = new CellReference(actualStartRow, actualStartCol); - CellReference bottomRight = new CellReference(actualEndRow, actualEndCol); - SheetIdentifier sheetIden = new SheetIdentifier( null, new NameIdentifier(sheetName, true)); - Ptg ptg = _book.get3DReferencePtg(new AreaReference(topLeft, bottomRight), sheetIden); - return new ParseNode(ptg); - } - - /** - * Tries to parse the next as column - can contain whitespace - * Caller should save pointer. - */ - private String parseAsColumnQuantifier() { - if ( look != '[') { - return null; - } - GetChar(); - if (look == '#') { - return null; - } - if (look == '@') { - GetChar(); - } - StringBuilder name = new StringBuilder(); - while (look!=']') { - name.append(look); - GetChar(); - } - Match(']'); - return name.toString(); - } - /** - * Tries to parse the next as special quantifier - * Caller should save pointer. - */ - private String parseAsSpecialQuantifier(){ - if ( look != '[') { - return null; - } - GetChar(); - if( look != '#') { - return null; - } - GetChar(); - String name = parseAsName(); - if ( name.equals("This")) { - name = name + ' ' + parseAsName(); - } - Match(']'); - return name; - } - - - /** - * Parses simple factors that are not primitive ranges or range components - * i.e. '!', ':'(and equiv '...') do not appear - * Examples - *
        -     *   my.named...range.
        -     *   foo.bar(123.456, "abc")
        -     *   123.456
        -     *   "abc"
        -     *   true
        -     * 
        - */ - private ParseNode parseNonRange(int savePointer) { - resetPointer(savePointer); - - if (Character.isDigit(look)) { - return new ParseNode(parseNumber()); - } - if (look == '"') { - return new ParseNode(new StringPtg(parseStringLiteral())); - } - - // from now on we can only be dealing with non-quoted identifiers - // which will either be named ranges or functions - String name = parseAsName(); - - if (look == '(') { - return function(name); - } - if(look == '['){ - return parseStructuredReference(name); - } - if (name.equalsIgnoreCase("TRUE") || name.equalsIgnoreCase("FALSE")) { - return new ParseNode(BoolPtg.valueOf(name.equalsIgnoreCase("TRUE"))); - } - if (_book == null) { - // Only test cases omit the book (expecting it not to be needed) - throw new IllegalStateException("Need book to evaluate name '" + name + "'"); - } - EvaluationName evalName = _book.getName(name, _sheetIndex); - if (evalName == null) { - throw new FormulaParseException("Specified named range '" - + name + "' does not exist in the current workbook."); - } - if (evalName.isRange()) { - return new ParseNode(evalName.createPtg()); - } - // TODO - what about NameX ? - throw new FormulaParseException("Specified name '" - + name + "' is not a range as expected."); - } - - private String parseAsName() { - StringBuilder sb = new StringBuilder(); - - // defined names may begin with a letter or underscore or backslash - if (!Character.isLetter(look) && look != '_' && look != '\\') { - throw expected("number, string, defined name, or data table"); - } - while (isValidDefinedNameChar(look)) { - sb.append(look); - GetChar(); - } - SkipWhite(); - - return sb.toString(); - } - - /** - * - * @return true if the specified character may be used in a defined name - */ - private static boolean isValidDefinedNameChar(char ch) { - if (Character.isLetterOrDigit(ch)) { - return true; - } - switch (ch) { - case '.': - case '_': - case '?': - case '\\': // of all things - return true; - } - return false; - } - - /** - * - * @param sheetIden may be null - * @param part1 - * @param part2 may be null - */ - private ParseNode createAreaRefParseNode(SheetIdentifier sheetIden, SimpleRangePart part1, - SimpleRangePart part2) throws FormulaParseException { - Ptg ptg; - if (part2 == null) { - CellReference cr = part1.getCellReference(); - if (sheetIden == null) { - ptg = new RefPtg(cr); - } else { - ptg = _book.get3DReferencePtg(cr, sheetIden); - } - } else { - AreaReference areaRef = createAreaRef(part1, part2); - - if (sheetIden == null) { - ptg = new AreaPtg(areaRef); - } else { - ptg = _book.get3DReferencePtg(areaRef, sheetIden); - } - } - return new ParseNode(ptg); - } - - private AreaReference createAreaRef(SimpleRangePart part1, SimpleRangePart part2) { - if (!part1.isCompatibleForArea(part2)) { - throw new FormulaParseException("has incompatible parts: '" - + part1.getRep() + "' and '" + part2.getRep() + "'."); - } - if (part1.isRow()) { - return AreaReference.getWholeRow(_ssVersion, part1.getRep(), part2.getRep()); - } - if (part1.isColumn()) { - return AreaReference.getWholeColumn(_ssVersion, part1.getRep(), part2.getRep()); - } - return new AreaReference(part1.getCellReference(), part2.getCellReference()); - } - - /** - * Matches a zero or one letter-runs followed by zero or one digit-runs. - * Either or both runs man optionally be prefixed with a single '$'. - * (copied+modified from {@link org.apache.poi.ss.util.CellReference#CELL_REF_PATTERN}) - */ - private static final Pattern CELL_REF_PATTERN = Pattern.compile("(\\$?[A-Za-z]+)?(\\$?[0-9]+)?"); - - /** - * Parses out a potential LHS or RHS of a ':' intended to produce a plain AreaRef. Normally these are - * proper cell references but they could also be row or column refs like "$AC" or "10" - * @return null (and leaves {@link #_pointer} unchanged if a proper range part does not parse out - */ - private SimpleRangePart parseSimpleRangePart() { - int ptr = _pointer-1; // TODO avoid StringIndexOutOfBounds - boolean hasDigits = false; - boolean hasLetters = false; - while (ptr < _formulaLength) { - char ch = _formulaString.charAt(ptr); - if (Character.isDigit(ch)) { - hasDigits = true; - } else if (Character.isLetter(ch)) { - hasLetters = true; - } else if (ch =='$' || ch =='_') { - // - } else { - break; - } - ptr++; - } - if (ptr <= _pointer-1) { - return null; - } - String rep = _formulaString.substring(_pointer-1, ptr); - if (!CELL_REF_PATTERN.matcher(rep).matches()) { - return null; - } - // Check range bounds against grid max - if (hasLetters && hasDigits) { - if (!isValidCellReference(rep)) { - return null; - } - } else if (hasLetters) { - if (!CellReference.isColumnWithinRange(rep.replace("$", ""), _ssVersion)) { - return null; - } - } else if (hasDigits) { - int i; - try { - i = Integer.parseInt(rep.replace("$", "")); - } catch (NumberFormatException e) { - return null; - } - if (i<1 || i>_ssVersion.getMaxRows()) { - return null; - } - } else { - // just dollars ? can this happen? - return null; - } - - - resetPointer(ptr+1); // stepping forward - return new SimpleRangePart(rep, hasLetters, hasDigits); - } - - - /** - * A1, $A1, A$1, $A$1, A, 1 - */ - private static final class SimpleRangePart { - private enum Type { - CELL, ROW, COLUMN; - - public static Type get(boolean hasLetters, boolean hasDigits) { - if (hasLetters) { - return hasDigits ? CELL : COLUMN; - } - if (!hasDigits) { - throw new IllegalArgumentException("must have either letters or numbers"); - } - return ROW; - } - } - - private final Type _type; - private final String _rep; - - public SimpleRangePart(String rep, boolean hasLetters, boolean hasNumbers) { - _rep = rep; - _type = Type.get(hasLetters, hasNumbers); - } - - public boolean isCell() { - return _type == Type.CELL; - } - - public boolean isRowOrColumn() { - return _type != Type.CELL; - } - - public CellReference getCellReference() { - if (_type != Type.CELL) { - throw new IllegalStateException("Not applicable to this type"); - } - return new CellReference(_rep); - } - - public boolean isColumn() { - return _type == Type.COLUMN; - } - - public boolean isRow() { - return _type == Type.ROW; - } - - public String getRep() { - return _rep; - } - - /** - * @return true if the two range parts can be combined in an - * {@link AreaPtg} ( Note - the explicit range operator (:) may still be valid - * when this method returns false ) - */ - public boolean isCompatibleForArea(SimpleRangePart part2) { - return _type == part2._type; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_rep); - sb.append("]"); - return sb.toString(); - } - } - - /** - * Note - caller should reset {@link #_pointer} upon null result - * @return The sheet name as an identifier null if '!' is not found in the right place - */ - private SheetIdentifier parseSheetName() { - String bookName; - if (look == '[') { - StringBuilder sb = new StringBuilder(); - GetChar(); - while (look != ']') { - sb.append(look); - GetChar(); - } - GetChar(); - bookName = sb.toString(); - } else { - bookName = null; - } - - if (look == '\'') { - StringBuffer sb = new StringBuffer(); - - Match('\''); - boolean done = look == '\''; - while(!done) { - sb.append(look); - GetChar(); - if(look == '\'') - { - Match('\''); - done = look != '\''; - } - } - - NameIdentifier iden = new NameIdentifier(sb.toString(), true); - // quoted identifier - can't concatenate anything more - SkipWhite(); - if (look == '!') { - GetChar(); - return new SheetIdentifier(bookName, iden); - } - // See if it's a multi-sheet range, eg Sheet1:Sheet3!A1 - if (look == ':') { - return parseSheetRange(bookName, iden); - } - return null; - } - - // unquoted sheet names must start with underscore or a letter - if (look =='_' || Character.isLetter(look)) { - StringBuilder sb = new StringBuilder(); - // can concatenate idens with dots - while (isUnquotedSheetNameChar(look)) { - sb.append(look); - GetChar(); - } - NameIdentifier iden = new NameIdentifier(sb.toString(), false); - SkipWhite(); - if (look == '!') { - GetChar(); - return new SheetIdentifier(bookName, iden); - } - // See if it's a multi-sheet range, eg Sheet1:Sheet3!A1 - if (look == ':') { - return parseSheetRange(bookName, iden); - } - return null; - } - if (look == '!' && bookName != null) { - // Raw book reference, without a sheet - GetChar(); - return new SheetIdentifier(bookName, null); - } - return null; - } - - /** - * If we have something that looks like [book]Sheet1: or - * Sheet1, see if it's actually a range eg Sheet1:Sheet2! - */ - private SheetIdentifier parseSheetRange(String bookname, NameIdentifier sheet1Name) { - GetChar(); - SheetIdentifier sheet2 = parseSheetName(); - if (sheet2 != null) { - return new SheetRangeIdentifier(bookname, sheet1Name, sheet2.getSheetIdentifier()); - } - return null; - } - - /** - * very similar to {@link SheetNameFormatter#isSpecialChar(char)} - */ - private static boolean isUnquotedSheetNameChar(char ch) { - if(Character.isLetterOrDigit(ch)) { - return true; - } - switch(ch) { - case '.': // dot is OK - case '_': // underscore is OK - return true; - } - return false; - } - - /** - * @return true if the specified name is a valid cell reference - */ - private boolean isValidCellReference(String str) { - //check range bounds against grid max - boolean result = CellReference.classifyCellReference(str, _ssVersion) == NameType.CELL; - - if(result){ - /** - * Check if the argument is a function. Certain names can be either a cell reference or a function name - * depending on the contenxt. Compare the following examples in Excel 2007: - * (a) LOG10(100) + 1 - * (b) LOG10 + 1 - * In (a) LOG10 is a name of a built-in function. In (b) LOG10 is a cell reference - */ - boolean isFunc = FunctionMetadataRegistry.getFunctionByName(str.toUpperCase(Locale.ROOT)) != null; - if(isFunc){ - int savePointer = _pointer; - resetPointer(_pointer + str.length()); - SkipWhite(); - // open bracket indicates that the argument is a function, - // the returning value should be false, i.e. "not a valid cell reference" - result = look != '('; - resetPointer(savePointer); - } - } - return result; - } - - - /** - * Note - Excel function names are 'case aware but not case sensitive'. This method may end - * up creating a defined name record in the workbook if the specified name is not an internal - * Excel function, and has not been encountered before. - * - * Side effect: creates workbook name if name is not recognized (name is probably a UDF) - * - * @param name case preserved function name (as it was entered/appeared in the formula). - */ - private ParseNode function(String name) { - Ptg nameToken = null; - if(!AbstractFunctionPtg.isBuiltInFunctionName(name)) { - // user defined function - // in the token tree, the name is more or less the first argument - - if (_book == null) { - // Only test cases omit the book (expecting it not to be needed) - throw new IllegalStateException("Need book to evaluate name '" + name + "'"); - } - // Check to see if name is a named range in the workbook - EvaluationName hName = _book.getName(name, _sheetIndex); - if (hName != null) { - if (!hName.isFunctionName()) { - throw new FormulaParseException("Attempt to use name '" + name - + "' as a function, but defined name in workbook does not refer to a function"); - } - - // calls to user-defined functions within the workbook - // get a Name token which points to a defined name record - nameToken = hName.createPtg(); - } else { - // Check if name is an external names table - nameToken = _book.getNameXPtg(name, null); - if (nameToken == null) { - // name is not an internal or external name - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, - "FormulaParser.function: Name '" + name + "' is completely unknown in the current workbook."); - } - // name is probably the name of an unregistered User-Defined Function - switch (_book.getSpreadsheetVersion()) { - case EXCEL97: - // HSSFWorkbooks require a name to be added to Workbook defined names table - addName(name); - hName = _book.getName(name, _sheetIndex); - nameToken = hName.createPtg(); - break; - case EXCEL2007: - // XSSFWorkbooks store formula names as strings. - nameToken = new NameXPxg(name); - break; - default: - throw new IllegalStateException("Unexpected spreadsheet version: " + _book.getSpreadsheetVersion().name()); - } - } - } - } - - Match('('); - ParseNode[] args = Arguments(); - Match(')'); - - return getFunction(name, nameToken, args); - } - - /** - * Adds a name (named range or user defined function) to underlying workbook's names table - * @param functionName - */ - private final void addName(String functionName) { - final Name name = _book.createName(); - name.setFunction(true); - name.setNameName(functionName); - name.setSheetIndex(_sheetIndex); - } - - /** - * Generates the variable function ptg for the formula. - *

        - * For IF Formulas, additional PTGs are added to the tokens - * @param name a {@link NamePtg} or {@link NameXPtg} or null - * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this function - */ - private ParseNode getFunction(String name, Ptg namePtg, ParseNode[] args) { - - FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase(Locale.ROOT)); - int numArgs = args.length; - if(fm == null) { - if (namePtg == null) { - throw new IllegalStateException("NamePtg must be supplied for external functions"); - } - // must be external function - ParseNode[] allArgs = new ParseNode[numArgs+1]; - allArgs[0] = new ParseNode(namePtg); - System.arraycopy(args, 0, allArgs, 1, numArgs); - return new ParseNode(FuncVarPtg.create(name, numArgs+1), allArgs); - } - - if (namePtg != null) { - throw new IllegalStateException("NamePtg no applicable to internal functions"); - } - boolean isVarArgs = !fm.hasFixedArgsLength(); - int funcIx = fm.getIndex(); - if (funcIx == FunctionMetadataRegistry.FUNCTION_INDEX_SUM && args.length == 1) { - // Excel encodes the sum of a single argument as tAttrSum - // POI does the same for consistency, but this is not critical - return new ParseNode(AttrPtg.getSumSingle(), args); - // The code below would encode tFuncVar(SUM) which seems to do no harm - } - validateNumArgs(args.length, fm); - - AbstractFunctionPtg retval; - if(isVarArgs) { - retval = FuncVarPtg.create(name, numArgs); - } else { - retval = FuncPtg.create(funcIx); - } - return new ParseNode(retval, args); - } - - private void validateNumArgs(int numArgs, FunctionMetadata fm) { - if(numArgs < fm.getMinParams()) { - String msg = "Too few arguments to function '" + fm.getName() + "'. "; - if(fm.hasFixedArgsLength()) { - msg += "Expected " + fm.getMinParams(); - } else { - msg += "At least " + fm.getMinParams() + " were expected"; - } - msg += " but got " + numArgs + "."; - throw new FormulaParseException(msg); - } - //the maximum number of arguments depends on the Excel version - int maxArgs; - if (fm.hasUnlimitedVarags()) { - if(_book != null) { - maxArgs = _book.getSpreadsheetVersion().getMaxFunctionArgs(); - } else { - //_book can be omitted by test cases - maxArgs = fm.getMaxParams(); // just use BIFF8 - } - } else { - maxArgs = fm.getMaxParams(); - } - - if(numArgs > maxArgs) { - String msg = "Too many arguments to function '" + fm.getName() + "'. "; - if(fm.hasFixedArgsLength()) { - msg += "Expected " + maxArgs; - } else { - msg += "At most " + maxArgs + " were expected"; - } - msg += " but got " + numArgs + "."; - throw new FormulaParseException(msg); - } - } - - private static boolean isArgumentDelimiter(char ch) { - return ch == ',' || ch == ')'; - } - - /** get arguments to a function */ - private ParseNode[] Arguments() { - //average 2 args per function - List temp = new ArrayList(2); - SkipWhite(); - if(look == ')') { - return ParseNode.EMPTY_ARRAY; - } - - boolean missedPrevArg = true; - while (true) { - SkipWhite(); - if (isArgumentDelimiter(look)) { - if (missedPrevArg) { - temp.add(new ParseNode(MissingArgPtg.instance)); - } - if (look == ')') { - break; - } - Match(','); - missedPrevArg = true; - continue; - } - temp.add(comparisonExpression()); - missedPrevArg = false; - SkipWhite(); - if (!isArgumentDelimiter(look)) { - throw expected("',' or ')'"); - } - } - ParseNode[] result = new ParseNode[temp.size()]; - temp.toArray(result); - return result; - } - - /** Parse and Translate a Math Factor */ - private ParseNode powerFactor() { - ParseNode result = percentFactor(); - while(true) { - SkipWhite(); - if(look != '^') { - return result; - } - Match('^'); - ParseNode other = percentFactor(); - result = new ParseNode(PowerPtg.instance, result, other); - } - } - - private ParseNode percentFactor() { - ParseNode result = parseSimpleFactor(); - while(true) { - SkipWhite(); - if(look != '%') { - return result; - } - Match('%'); - result = new ParseNode(PercentPtg.instance, result); - } - } - - - /** - * factors (without ^ or % ) - */ - private ParseNode parseSimpleFactor() { - SkipWhite(); - switch(look) { - case '#': - return new ParseNode(ErrPtg.valueOf(parseErrorLiteral())); - case '-': - Match('-'); - return parseUnary(false); - case '+': - Match('+'); - return parseUnary(true); - case '(': - Match('('); - ParseNode inside = unionExpression(); - Match(')'); - return new ParseNode(ParenthesisPtg.instance, inside); - case '"': - return new ParseNode(new StringPtg(parseStringLiteral())); - case '{': - Match('{'); - ParseNode arrayNode = parseArray(); - Match('}'); - return arrayNode; - } - // named ranges and tables can start with underscore or backslash - // see https://support.office.com/en-us/article/Define-and-use-names-in-formulas-4d0f13ac-53b7-422e-afd2-abd7ff379c64?ui=en-US&rs=en-US&ad=US#bmsyntax_rules_for_names - if (IsAlpha(look) || Character.isDigit(look) || look == '\'' || look == '[' || look == '_' || look == '\\' ) { - return parseRangeExpression(); - } - if (look == '.') { - return new ParseNode(parseNumber()); - } - throw expected("cell ref or constant literal"); - } - - - private ParseNode parseUnary(boolean isPlus) { - - boolean numberFollows = IsDigit(look) || look=='.'; - ParseNode factor = powerFactor(); - - if (numberFollows) { - // + or - directly next to a number is parsed with the number - - Ptg token = factor.getToken(); - if (token instanceof NumberPtg) { - if (isPlus) { - return factor; - } - token = new NumberPtg(-((NumberPtg)token).getValue()); - return new ParseNode(token); - } - if (token instanceof IntPtg) { - if (isPlus) { - return factor; - } - int intVal = ((IntPtg)token).getValue(); - // note - cannot use IntPtg for negatives - token = new NumberPtg(-intVal); - return new ParseNode(token); - } - } - return new ParseNode(isPlus ? UnaryPlusPtg.instance : UnaryMinusPtg.instance, factor); - } - - private ParseNode parseArray() { - List rowsData = new ArrayList(); - while(true) { - Object[] singleRowData = parseArrayRow(); - rowsData.add(singleRowData); - if (look == '}') { - break; - } - if (look != ';') { - throw expected("'}' or ';'"); - } - Match(';'); - } - int nRows = rowsData.size(); - Object[][] values2d = new Object[nRows][]; - rowsData.toArray(values2d); - int nColumns = values2d[0].length; - checkRowLengths(values2d, nColumns); - - return new ParseNode(new ArrayPtg(values2d)); - } - private void checkRowLengths(Object[][] values2d, int nColumns) { - for (int i = 0; i < values2d.length; i++) { - int rowLen = values2d[i].length; - if (rowLen != nColumns) { - throw new FormulaParseException("Array row " + i + " has length " + rowLen - + " but row 0 has length " + nColumns); - } - } - } - - private Object[] parseArrayRow() { - List temp = new ArrayList(); - while (true) { - temp.add(parseArrayItem()); - SkipWhite(); - switch(look) { - case '}': - case ';': - break; - case ',': - Match(','); - continue; - default: - throw expected("'}' or ','"); - - } - break; - } - - Object[] result = new Object[temp.size()]; - temp.toArray(result); - return result; - } - - private Object parseArrayItem() { - SkipWhite(); - switch(look) { - case '"': return parseStringLiteral(); - case '#': return ErrorConstant.valueOf(parseErrorLiteral()); - case 'F': case 'f': - case 'T': case 't': - return parseBooleanLiteral(); - case '-': - Match('-'); - SkipWhite(); - return convertArrayNumber(parseNumber(), false); - } - // else assume number - return convertArrayNumber(parseNumber(), true); - } - - private Boolean parseBooleanLiteral() { - String iden = parseUnquotedIdentifier(); - if ("TRUE".equalsIgnoreCase(iden)) { - return Boolean.TRUE; - } - if ("FALSE".equalsIgnoreCase(iden)) { - return Boolean.FALSE; - } - throw expected("'TRUE' or 'FALSE'"); - } - - private static Double convertArrayNumber(Ptg ptg, boolean isPositive) { - double value; - if (ptg instanceof IntPtg) { - value = ((IntPtg)ptg).getValue(); - } else if (ptg instanceof NumberPtg) { - value = ((NumberPtg)ptg).getValue(); - } else { - throw new RuntimeException("Unexpected ptg (" + ptg.getClass().getName() + ")"); - } - if (!isPositive) { - value = -value; - } - return new Double(value); - } - - private Ptg parseNumber() { - String number2 = null; - String exponent = null; - String number1 = GetNum(); - - if (look == '.') { - GetChar(); - number2 = GetNum(); - } - - if (look == 'E') { - GetChar(); - - String sign = ""; - if (look == '+') { - GetChar(); - } else if (look == '-') { - GetChar(); - sign = "-"; - } - - String number = GetNum(); - if (number == null) { - throw expected("Integer"); - } - exponent = sign + number; - } - - if (number1 == null && number2 == null) { - throw expected("Integer"); - } - - return getNumberPtgFromString(number1, number2, exponent); - } - - - private int parseErrorLiteral() { - Match('#'); - String part1 = parseUnquotedIdentifier().toUpperCase(Locale.ROOT); - if (part1 == null) { - throw expected("remainder of error constant literal"); - } - - switch(part1.charAt(0)) { - case 'V': { - FormulaError fe = FormulaError.VALUE; - if(part1.equals(fe.name())) { - Match('!'); - return fe.getCode(); - } - throw expected(fe.getString()); - } - case 'R': { - FormulaError fe = FormulaError.REF; - if(part1.equals(fe.name())) { - Match('!'); - return fe.getCode(); - } - throw expected(fe.getString()); - } - case 'D': { - FormulaError fe = FormulaError.DIV0; - if(part1.equals("DIV")) { - Match('/'); - Match('0'); - Match('!'); - return fe.getCode(); - } - throw expected(fe.getString()); - } - case 'N': { - FormulaError fe = FormulaError.NAME; - if(part1.equals(fe.name())) { - // only one that ends in '?' - Match('?'); - return fe.getCode(); - } - fe = FormulaError.NUM; - if(part1.equals(fe.name())) { - Match('!'); - return fe.getCode(); - } - fe = FormulaError.NULL; - if(part1.equals(fe.name())) { - Match('!'); - return fe.getCode(); - } - fe = FormulaError.NA; - if(part1.equals("N")) { - Match('/'); - if(look != 'A' && look != 'a') { - throw expected(fe.getString()); - } - Match(look); - // Note - no '!' or '?' suffix - return fe.getCode(); - } - throw expected("#NAME?, #NUM!, #NULL! or #N/A"); - } - } - throw expected("#VALUE!, #REF!, #DIV/0!, #NAME?, #NUM!, #NULL! or #N/A"); - } - - private String parseUnquotedIdentifier() { - if (look == '\'') { - throw expected("unquoted identifier"); - } - StringBuilder sb = new StringBuilder(); - while (Character.isLetterOrDigit(look) || look == '.') { - sb.append(look); - GetChar(); - } - if (sb.length() < 1) { - return null; - } - - return sb.toString(); - } - - /** - * Get a PTG for an integer from its string representation. - * return Int or Number Ptg based on size of input - */ - private static Ptg getNumberPtgFromString(String number1, String number2, String exponent) { - StringBuffer number = new StringBuffer(); - - if (number2 == null) { - number.append(number1); - - if (exponent != null) { - number.append('E'); - number.append(exponent); - } - - String numberStr = number.toString(); - int intVal; - try { - intVal = Integer.parseInt(numberStr); - } catch (NumberFormatException e) { - return new NumberPtg(numberStr); - } - if (IntPtg.isInRange(intVal)) { - return new IntPtg(intVal); - } - return new NumberPtg(numberStr); - } - - if (number1 != null) { - number.append(number1); - } - - number.append('.'); - number.append(number2); - - if (exponent != null) { - number.append('E'); - number.append(exponent); - } - - return new NumberPtg(number.toString()); - } - - - private String parseStringLiteral() { - Match('"'); - - StringBuffer token = new StringBuffer(); - while (true) { - if (look == '"') { - GetChar(); - if (look != '"') { - break; - } - } - token.append(look); - GetChar(); - } - return token.toString(); - } - - /** Parse and Translate a Math Term */ - private ParseNode Term() { - ParseNode result = powerFactor(); - while(true) { - SkipWhite(); - Ptg operator; - switch(look) { - case '*': - Match('*'); - operator = MultiplyPtg.instance; - break; - case '/': - Match('/'); - operator = DividePtg.instance; - break; - default: - return result; // finished with Term - } - ParseNode other = powerFactor(); - result = new ParseNode(operator, result, other); - } - } - - private ParseNode unionExpression() { - ParseNode result = intersectionExpression(); - boolean hasUnions = false; - while (true) { - SkipWhite(); - switch(look) { - case ',': - GetChar(); - hasUnions = true; - ParseNode other = intersectionExpression(); - result = new ParseNode(UnionPtg.instance, result, other); - continue; - } - if (hasUnions) { - return augmentWithMemPtg(result); - } - return result; - } - } - - private ParseNode intersectionExpression() { - ParseNode result = comparisonExpression(); - boolean hasIntersections = false; - while (true) { - SkipWhite(); - if (_inIntersection) { - int savePointer = _pointer; - - // Don't getChar() as the space has already been eaten and recorded by SkipWhite(). - try { - ParseNode other = comparisonExpression(); - result = new ParseNode(IntersectionPtg.instance, result, other); - hasIntersections = true; - continue; - } catch (FormulaParseException e) { - // if parsing for intersection fails we assume that we actually had an arbitrary - // whitespace and thus should simply skip this whitespace - resetPointer(savePointer); - } - } - if (hasIntersections) { - return augmentWithMemPtg(result); - } - return result; - } - } - - private ParseNode comparisonExpression() { - ParseNode result = concatExpression(); - while (true) { - SkipWhite(); - switch(look) { - case '=': - case '>': - case '<': - Ptg comparisonToken = getComparisonToken(); - ParseNode other = concatExpression(); - result = new ParseNode(comparisonToken, result, other); - continue; - } - return result; // finished with predicate expression - } - } - - private Ptg getComparisonToken() { - if(look == '=') { - Match(look); - return EqualPtg.instance; - } - boolean isGreater = look == '>'; - Match(look); - if(isGreater) { - if(look == '=') { - Match('='); - return GreaterEqualPtg.instance; - } - return GreaterThanPtg.instance; - } - switch(look) { - case '=': - Match('='); - return LessEqualPtg.instance; - case '>': - Match('>'); - return NotEqualPtg.instance; - } - return LessThanPtg.instance; - } - - - private ParseNode concatExpression() { - ParseNode result = additiveExpression(); - while (true) { - SkipWhite(); - if(look != '&') { - break; // finished with concat expression - } - Match('&'); - ParseNode other = additiveExpression(); - result = new ParseNode(ConcatPtg.instance, result, other); - } - return result; - } - - - /** Parse and Translate an Expression */ - private ParseNode additiveExpression() { - ParseNode result = Term(); - while (true) { - SkipWhite(); - Ptg operator; - switch(look) { - case '+': - Match('+'); - operator = AddPtg.instance; - break; - case '-': - Match('-'); - operator = SubtractPtg.instance; - break; - default: - return result; // finished with additive expression - } - ParseNode other = Term(); - result = new ParseNode(operator, result, other); - } - } - - //{--------------------------------------------------------------} - //{ Parse and Translate an Assignment Statement } - /** -procedure Assignment; -var Name: string[8]; -begin - Name := GetName; - Match('='); - Expression; - -end; - **/ - - - /** - * API call to execute the parsing of the formula - * - */ - private void parse() { - _pointer=0; - GetChar(); - _rootNode = unionExpression(); - - if(_pointer <= _formulaLength) { - String msg = "Unused input [" + _formulaString.substring(_pointer-1) - + "] after attempting to parse the formula [" + _formulaString + "]"; - throw new FormulaParseException(msg); - } - } - - private Ptg[] getRPNPtg(FormulaType formulaType) { - OperandClassTransformer oct = new OperandClassTransformer(formulaType); - // RVA is for 'operand class': 'reference', 'value', 'array' - oct.transformFormula(_rootNode); - return ParseNode.toTokenArray(_rootNode); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java deleted file mode 100644 index 7ddcc944c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.Table; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; - -/** - * Abstracts a workbook for the purpose of formula parsing.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface FormulaParsingWorkbook { - /** - * named range name matching is case insensitive - */ - EvaluationName getName(String name, int sheetIndex); - - /** - * Return the underlying workbook - */ - Name createName(); - - /** - * XSSF Only - gets a table that exists in the worksheet - */ - Table getTable(String name); - - /** - * Return an external name (named range, function, user-defined function) Ptg - */ - Ptg getNameXPtg(String name, SheetIdentifier sheet); - - /** - * Produce the appropriate Ptg for a 3d cell reference - */ - Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet); - - /** - * Produce the appropriate Ptg for a 3d area reference - */ - Ptg get3DReferencePtg(AreaReference area, SheetIdentifier sheet); - - /** - * gets the externSheet index for a sheet from this workbook - */ - int getExternalSheetIndex(String sheetName); - /** - * gets the externSheet index for a sheet from an external workbook - * @param workbookName e.g. "Budget.xls" - * @param sheetName a name of a sheet in that workbook - */ - int getExternalSheetIndex(String workbookName, String sheetName); - - /** - * Returns an enum holding spreadhseet properties specific to an Excel version ( - * max column and row numbers, max arguments to a function, etc.) - */ - SpreadsheetVersion getSpreadsheetVersion(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaRenderer.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaRenderer.java deleted file mode 100644 index 78eb16ddb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaRenderer.java +++ /dev/null @@ -1,130 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Stack; - -import org.apache.poi.ss.formula.ptg.AttrPtg; -import org.apache.poi.ss.formula.ptg.MemAreaPtg; -import org.apache.poi.ss.formula.ptg.MemErrPtg; -import org.apache.poi.ss.formula.ptg.MemFuncPtg; -import org.apache.poi.ss.formula.ptg.OperationPtg; -import org.apache.poi.ss.formula.ptg.ParenthesisPtg; -import org.apache.poi.ss.formula.ptg.Ptg; - -/** - * Common logic for rendering formulas.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public class FormulaRenderer { - - /** - * Static method to convert an array of {@link Ptg}s in RPN order - * to a human readable string format in infix mode. - * @param book used for defined names and 3D references - * @param ptgs must not be null - * @return a human readable String - */ - public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) { - if (ptgs == null || ptgs.length == 0) { - throw new IllegalArgumentException("ptgs must not be null"); - } - Stack stack = new Stack(); - - for (Ptg ptg : ptgs) { - // TODO - what about MemNoMemPtg? - if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) { - // marks the start of a list of area expressions which will be naturally combined - // by their trailing operators (e.g. UnionPtg) - // TODO - put comment and throw exception in toFormulaString() of these classes - continue; - } - if (ptg instanceof ParenthesisPtg) { - String contents = stack.pop(); - stack.push ("(" + contents + ")"); - continue; - } - if (ptg instanceof AttrPtg) { - AttrPtg attrPtg = ((AttrPtg) ptg); - if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isSkip()) { - continue; - } - if (attrPtg.isSpace()) { - // POI currently doesn't render spaces in formulas - continue; - // but if it ever did, care must be taken: - // tAttrSpace comes *before* the operand it applies to, which may be consistent - // with how the formula text appears but is against the RPN ordering assumed here - } - if (attrPtg.isSemiVolatile()) { - // similar to tAttrSpace - RPN is violated - continue; - } - if (attrPtg.isSum()) { - String[] operands = getOperands(stack, attrPtg.getNumberOfOperands()); - stack.push(attrPtg.toFormulaString(operands)); - continue; - } - throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString()); - } - - if (ptg instanceof WorkbookDependentFormula) { - WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg; - stack.push(optg.toFormulaString(book)); - continue; - } - if (! (ptg instanceof OperationPtg)) { - stack.push(ptg.toFormulaString()); - continue; - } - - OperationPtg o = (OperationPtg) ptg; - String[] operands = getOperands(stack, o.getNumberOfOperands()); - stack.push(o.toFormulaString(operands)); - } - if(stack.isEmpty()) { - // inspection of the code above reveals that every stack.pop() is followed by a - // stack.push(). So this is either an internal error or impossible. - throw new IllegalStateException("Stack underflow"); - } - String result = stack.pop(); - if(!stack.isEmpty()) { - // Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't - // put anything on the stack - throw new IllegalStateException("too much stuff left on the stack"); - } - return result; - } - - private static String[] getOperands(Stack stack, int nOperands) { - String[] operands = new String[nOperands]; - - for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order - if(stack.isEmpty()) { - String msg = "Too few arguments supplied to operation. Expected (" + nOperands - + ") operands but got (" + (nOperands - j - 1) + ")"; - throw new IllegalStateException(msg); - } - operands[j] = stack.pop(); - } - return operands; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java deleted file mode 100644 index f918be4eb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; - -/** - * Abstracts a workbook for the purpose of converting formula to text.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface FormulaRenderingWorkbook { - /** - * @return null if externSheetIndex refers to a sheet inside the current workbook - */ - ExternalSheet getExternalSheet(int externSheetIndex); - - /** - * @return the name of the (first) sheet referred to by the given external sheet index - */ - String getSheetFirstNameByExternSheet(int externSheetIndex); - /** - * @return the name of the (last) sheet referred to by the given external sheet index - */ - String getSheetLastNameByExternSheet(int externSheetIndex); - - String resolveNameXText(NameXPtg nameXPtg); - String getNameText(NamePtg namePtg); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaShifter.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaShifter.java deleted file mode 100644 index 44e477f23..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaShifter.java +++ /dev/null @@ -1,544 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.ptg.Area2DPtgBase; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.Area3DPxg; -import org.apache.poi.ss.formula.ptg.AreaErrPtg; -import org.apache.poi.ss.formula.ptg.AreaPtg; -import org.apache.poi.ss.formula.ptg.AreaPtgBase; -import org.apache.poi.ss.formula.ptg.Deleted3DPxg; -import org.apache.poi.ss.formula.ptg.DeletedArea3DPtg; -import org.apache.poi.ss.formula.ptg.DeletedRef3DPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.ptg.Ref3DPxg; -import org.apache.poi.ss.formula.ptg.RefErrorPtg; -import org.apache.poi.ss.formula.ptg.RefPtg; -import org.apache.poi.ss.formula.ptg.RefPtgBase; - - -/** - * Updates Formulas as rows or sheets are shifted - */ -public final class FormulaShifter { - - private static enum ShiftMode { - RowMove, - RowCopy, - SheetMove, - } - - /** - * Extern sheet index of sheet where moving is occurring, - * used for updating HSSF style 3D references - */ - private final int _externSheetIndex; - /** - * Sheet name of the sheet where moving is occurring, - * used for updating XSSF style 3D references on row shifts. - */ - private final String _sheetName; - - private final int _firstMovedIndex; - private final int _lastMovedIndex; - private final int _amountToMove; - - private final int _srcSheetIndex; - private final int _dstSheetIndex; - private final SpreadsheetVersion _version; - - private final ShiftMode _mode; - - /** - * Create an instance for shifting row. - * - * For example, this will be called on {@link org.apache.poi.hssf.usermodel.HSSFSheet#shiftRows(int, int, int)} } - */ - private FormulaShifter(int externSheetIndex, String sheetName, int firstMovedIndex, int lastMovedIndex, int amountToMove, - ShiftMode mode, SpreadsheetVersion version) { - if (amountToMove == 0) { - throw new IllegalArgumentException("amountToMove must not be zero"); - } - if (firstMovedIndex > lastMovedIndex) { - throw new IllegalArgumentException("firstMovedIndex, lastMovedIndex out of order"); - } - _externSheetIndex = externSheetIndex; - _sheetName = sheetName; - _firstMovedIndex = firstMovedIndex; - _lastMovedIndex = lastMovedIndex; - _amountToMove = amountToMove; - _mode = mode; - _version = version; - - _srcSheetIndex = _dstSheetIndex = -1; - } - - /** - * Create an instance for shifting sheets. - * - * For example, this will be called on {@link org.apache.poi.hssf.usermodel.HSSFWorkbook#setSheetOrder(String, int)} - */ - private FormulaShifter(int srcSheetIndex, int dstSheetIndex) { - _externSheetIndex = _firstMovedIndex = _lastMovedIndex = _amountToMove = -1; - _sheetName = null; - _version = null; - - _srcSheetIndex = srcSheetIndex; - _dstSheetIndex = dstSheetIndex; - _mode = ShiftMode.SheetMove; - } - - public static FormulaShifter createForRowShift(int externSheetIndex, String sheetName, int firstMovedRowIndex, int lastMovedRowIndex, int numberOfRowsToMove, - SpreadsheetVersion version) { - return new FormulaShifter(externSheetIndex, sheetName, firstMovedRowIndex, lastMovedRowIndex, numberOfRowsToMove, ShiftMode.RowMove, version); - } - - public static FormulaShifter createForRowCopy(int externSheetIndex, String sheetName, int firstMovedRowIndex, int lastMovedRowIndex, int numberOfRowsToMove, - SpreadsheetVersion version) { - return new FormulaShifter(externSheetIndex, sheetName, firstMovedRowIndex, lastMovedRowIndex, numberOfRowsToMove, ShiftMode.RowCopy, version); - } - - public static FormulaShifter createForSheetShift(int srcSheetIndex, int dstSheetIndex) { - return new FormulaShifter(srcSheetIndex, dstSheetIndex); - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - - sb.append(getClass().getName()); - sb.append(" ["); - sb.append(_firstMovedIndex); - sb.append(_lastMovedIndex); - sb.append(_amountToMove); - return sb.toString(); - } - - /** - * @param ptgs - if necessary, will get modified by this method - * @param currentExternSheetIx - the extern sheet index of the sheet that contains the formula being adjusted - * @return true if a change was made to the formula tokens - */ - public boolean adjustFormula(Ptg[] ptgs, int currentExternSheetIx) { - boolean refsWereChanged = false; - for(int i=0; i 0 || - ! _sheetName.equals(rpxg.getSheetName())) { - // only move 3D refs that refer to the sheet with cells being moved - return null; - } - return rowMoveRefPtg(rpxg); - } - if(ptg instanceof Area2DPtgBase) { - if (currentExternSheetIx != _externSheetIndex) { - // local refs on other sheets are unaffected - return ptg; - } - return rowMoveAreaPtg((Area2DPtgBase)ptg); - } - if(ptg instanceof Area3DPtg) { - Area3DPtg aptg = (Area3DPtg)ptg; - if (_externSheetIndex != aptg.getExternSheetIndex()) { - // only move 3D refs that refer to the sheet with cells being moved - // (currentExternSheetIx is irrelevant) - return null; - } - return rowMoveAreaPtg(aptg); - } - if(ptg instanceof Area3DPxg) { - Area3DPxg apxg = (Area3DPxg)ptg; - if (apxg.getExternalWorkbookNumber() > 0 || - ! _sheetName.equals(apxg.getSheetName())) { - // only move 3D refs that refer to the sheet with cells being moved - return null; - } - return rowMoveAreaPtg(apxg); - } - return null; - } - - /** - * Call this on any ptg reference contained in a row of cells that was copied. - * If the ptg reference is relative, the references will be shifted by the distance - * that the rows were copied. - * In the future similar functions could be written due to column copying or - * individual cell copying. Just make sure to only call adjustPtgDueToRowCopy on - * formula cells that are copied (unless row shifting, where references outside - * of the shifted region need to be updated to reflect the shift, a copy is self-contained). - * - * @param ptg the ptg to shift - * @return deleted ref ptg, in-place modified ptg, or null - * If Ptg would be shifted off the first or last row of a sheet, return deleted ref - * If Ptg needs to be changed, modifies Ptg in-place - * If Ptg doesn't need to be changed, returns null - */ - private Ptg adjustPtgDueToRowCopy(Ptg ptg) { - if(ptg instanceof RefPtg) { - RefPtg rptg = (RefPtg)ptg; - return rowCopyRefPtg(rptg); - } - if(ptg instanceof Ref3DPtg) { - Ref3DPtg rptg = (Ref3DPtg)ptg; - return rowCopyRefPtg(rptg); - } - if(ptg instanceof Ref3DPxg) { - Ref3DPxg rpxg = (Ref3DPxg)ptg; - return rowCopyRefPtg(rpxg); - } - if(ptg instanceof Area2DPtgBase) { - return rowCopyAreaPtg((Area2DPtgBase)ptg); - } - if(ptg instanceof Area3DPtg) { - Area3DPtg aptg = (Area3DPtg)ptg; - return rowCopyAreaPtg(aptg); - } - if(ptg instanceof Area3DPxg) { - Area3DPxg apxg = (Area3DPxg)ptg; - return rowCopyAreaPtg(apxg); - } - return null; - } - - - private Ptg adjustPtgDueToSheetMove(Ptg ptg) { - if(ptg instanceof Ref3DPtg) { - Ref3DPtg ref = (Ref3DPtg)ptg; - int oldSheetIndex = ref.getExternSheetIndex(); - - // we have to handle a few cases here - - // 1. sheet is outside moved sheets, no change necessary - if(oldSheetIndex < _srcSheetIndex && - oldSheetIndex < _dstSheetIndex) { - return null; - } - if(oldSheetIndex > _srcSheetIndex && - oldSheetIndex > _dstSheetIndex) { - return null; - } - - // 2. ptg refers to the moved sheet - if(oldSheetIndex == _srcSheetIndex) { - ref.setExternSheetIndex(_dstSheetIndex); - return ref; - } - - // 3. new index is lower than old one => sheets get moved up - if (_dstSheetIndex < _srcSheetIndex) { - ref.setExternSheetIndex(oldSheetIndex+1); - return ref; - } - - // 4. new index is higher than old one => sheets get moved down - if (_dstSheetIndex > _srcSheetIndex) { - ref.setExternSheetIndex(oldSheetIndex-1); - return ref; - } - } - - return null; - } - - private Ptg rowMoveRefPtg(RefPtgBase rptg) { - int refRow = rptg.getRow(); - if (_firstMovedIndex <= refRow && refRow <= _lastMovedIndex) { - // Rows being moved completely enclose the ref. - // - move the area ref along with the rows regardless of destination - rptg.setRow(refRow + _amountToMove); - return rptg; - } - // else rules for adjusting area may also depend on the destination of the moved rows - - int destFirstRowIndex = _firstMovedIndex + _amountToMove; - int destLastRowIndex = _lastMovedIndex + _amountToMove; - - // ref is outside source rows - // check for clashes with destination - - if (destLastRowIndex < refRow || refRow < destFirstRowIndex) { - // destination rows are completely outside ref - return null; - } - - if (destFirstRowIndex <= refRow && refRow <= destLastRowIndex) { - // destination rows enclose the area (possibly exactly) - return createDeletedRef(rptg); - } - throw new IllegalStateException("Situation not covered: (" + _firstMovedIndex + ", " + - _lastMovedIndex + ", " + _amountToMove + ", " + refRow + ", " + refRow + ")"); - } - - private Ptg rowMoveAreaPtg(AreaPtgBase aptg) { - int aFirstRow = aptg.getFirstRow(); - int aLastRow = aptg.getLastRow(); - if (_firstMovedIndex <= aFirstRow && aLastRow <= _lastMovedIndex) { - // Rows being moved completely enclose the area ref. - // - move the area ref along with the rows regardless of destination - aptg.setFirstRow(aFirstRow + _amountToMove); - aptg.setLastRow(aLastRow + _amountToMove); - return aptg; - } - // else rules for adjusting area may also depend on the destination of the moved rows - - int destFirstRowIndex = _firstMovedIndex + _amountToMove; - int destLastRowIndex = _lastMovedIndex + _amountToMove; - - if (aFirstRow < _firstMovedIndex && _lastMovedIndex < aLastRow) { - // Rows moved were originally *completely* within the area ref - - // If the destination of the rows overlaps either the top - // or bottom of the area ref there will be a change - if (destFirstRowIndex < aFirstRow && aFirstRow <= destLastRowIndex) { - // truncate the top of the area by the moved rows - aptg.setFirstRow(destLastRowIndex+1); - return aptg; - } else if (destFirstRowIndex <= aLastRow && aLastRow < destLastRowIndex) { - // truncate the bottom of the area by the moved rows - aptg.setLastRow(destFirstRowIndex-1); - return aptg; - } - // else - rows have moved completely outside the area ref, - // or still remain completely within the area ref - return null; // - no change to the area - } - if (_firstMovedIndex <= aFirstRow && aFirstRow <= _lastMovedIndex) { - // Rows moved include the first row of the area ref, but not the last row - // btw: (aLastRow > _lastMovedIndex) - if (_amountToMove < 0) { - // simple case - expand area by shifting top upward - aptg.setFirstRow(aFirstRow + _amountToMove); - return aptg; - } - if (destFirstRowIndex > aLastRow) { - // in this case, excel ignores the row move - return null; - } - int newFirstRowIx = aFirstRow + _amountToMove; - if (destLastRowIndex < aLastRow) { - // end of area is preserved (will remain exact same row) - // the top area row is moved simply - aptg.setFirstRow(newFirstRowIx); - return aptg; - } - // else - bottom area row has been replaced - both area top and bottom may move now - int areaRemainingTopRowIx = _lastMovedIndex + 1; - if (destFirstRowIndex > areaRemainingTopRowIx) { - // old top row of area has moved deep within the area, and exposed a new top row - newFirstRowIx = areaRemainingTopRowIx; - } - aptg.setFirstRow(newFirstRowIx); - aptg.setLastRow(Math.max(aLastRow, destLastRowIndex)); - return aptg; - } - if (_firstMovedIndex <= aLastRow && aLastRow <= _lastMovedIndex) { - // Rows moved include the last row of the area ref, but not the first - // btw: (aFirstRow < _firstMovedIndex) - if (_amountToMove > 0) { - // simple case - expand area by shifting bottom downward - aptg.setLastRow(aLastRow + _amountToMove); - return aptg; - } - if (destLastRowIndex < aFirstRow) { - // in this case, excel ignores the row move - return null; - } - int newLastRowIx = aLastRow + _amountToMove; - if (destFirstRowIndex > aFirstRow) { - // top of area is preserved (will remain exact same row) - // the bottom area row is moved simply - aptg.setLastRow(newLastRowIx); - return aptg; - } - // else - top area row has been replaced - both area top and bottom may move now - int areaRemainingBottomRowIx = _firstMovedIndex - 1; - if (destLastRowIndex < areaRemainingBottomRowIx) { - // old bottom row of area has moved up deep within the area, and exposed a new bottom row - newLastRowIx = areaRemainingBottomRowIx; - } - aptg.setFirstRow(Math.min(aFirstRow, destFirstRowIndex)); - aptg.setLastRow(newLastRowIx); - return aptg; - } - // else source rows include none of the rows of the area ref - // check for clashes with destination - - if (destLastRowIndex < aFirstRow || aLastRow < destFirstRowIndex) { - // destination rows are completely outside area ref - return null; - } - - if (destFirstRowIndex <= aFirstRow && aLastRow <= destLastRowIndex) { - // destination rows enclose the area (possibly exactly) - return createDeletedRef(aptg); - } - - if (aFirstRow <= destFirstRowIndex && destLastRowIndex <= aLastRow) { - // destination rows are within area ref (possibly exact on top or bottom, but not both) - return null; // - no change to area - } - - if (destFirstRowIndex < aFirstRow && aFirstRow <= destLastRowIndex) { - // dest rows overlap top of area - // - truncate the top - aptg.setFirstRow(destLastRowIndex+1); - return aptg; - } - if (destFirstRowIndex <= aLastRow && aLastRow < destLastRowIndex) { - // dest rows overlap bottom of area - // - truncate the bottom - aptg.setLastRow(destFirstRowIndex-1); - return aptg; - } - throw new IllegalStateException("Situation not covered: (" + _firstMovedIndex + ", " + - _lastMovedIndex + ", " + _amountToMove + ", " + aFirstRow + ", " + aLastRow + ")"); - } - - /** - * Modifies rptg in-place and return a reference to rptg if the cell reference - * would move due to a row copy operation - * Returns null or {@link #RefErrorPtg} if no change was made - * - * @param aptg - * @return The Ptg reference if the cell would move due to copy, otherwise null - */ - private Ptg rowCopyRefPtg(RefPtgBase rptg) { - final int refRow = rptg.getRow(); - if (rptg.isRowRelative()) { - final int destRowIndex = _firstMovedIndex + _amountToMove; - if (destRowIndex < 0 || _version.getLastRowIndex() < destRowIndex) - return createDeletedRef(rptg); - rptg.setRow(refRow + _amountToMove); - return rptg; - } - return null; - } - - /** - * Modifies aptg in-place and return a reference to aptg if the first or last row of - * of the Area reference would move due to a row copy operation - * Returns null or {@link #AreaErrPtg} if no change was made - * - * @param aptg - * @return null, AreaErrPtg, or modified aptg - */ - private Ptg rowCopyAreaPtg(AreaPtgBase aptg) { - boolean changed = false; - - final int aFirstRow = aptg.getFirstRow(); - final int aLastRow = aptg.getLastRow(); - - if (aptg.isFirstRowRelative()) { - final int destFirstRowIndex = aFirstRow + _amountToMove; - if (destFirstRowIndex < 0 || _version.getLastRowIndex() < destFirstRowIndex) - return createDeletedRef(aptg); - aptg.setFirstRow(destFirstRowIndex); - changed = true; - } - if (aptg.isLastRowRelative()) { - final int destLastRowIndex = aLastRow + _amountToMove; - if (destLastRowIndex < 0 || _version.getLastRowIndex() < destLastRowIndex) - return createDeletedRef(aptg); - aptg.setLastRow(destLastRowIndex); - changed = true; - } - if (changed) { - aptg.sortTopLeftToBottomRight(); - } - - return changed ? aptg : null; - } - - private static Ptg createDeletedRef(Ptg ptg) { - if (ptg instanceof RefPtg) { - return new RefErrorPtg(); - } - if (ptg instanceof Ref3DPtg) { - Ref3DPtg rptg = (Ref3DPtg) ptg; - return new DeletedRef3DPtg(rptg.getExternSheetIndex()); - } - if (ptg instanceof AreaPtg) { - return new AreaErrPtg(); - } - if (ptg instanceof Area3DPtg) { - Area3DPtg area3DPtg = (Area3DPtg) ptg; - return new DeletedArea3DPtg(area3DPtg.getExternSheetIndex()); - } - if (ptg instanceof Ref3DPxg) { - Ref3DPxg pxg = (Ref3DPxg)ptg; - return new Deleted3DPxg(pxg.getExternalWorkbookNumber(), pxg.getSheetName()); - } - if (ptg instanceof Area3DPxg) { - Area3DPxg pxg = (Area3DPxg)ptg; - return new Deleted3DPxg(pxg.getExternalWorkbookNumber(), pxg.getSheetName()); - } - - throw new IllegalArgumentException("Unexpected ref ptg class (" + ptg.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaType.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaType.java deleted file mode 100644 index 45d26ae88..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaType.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.util.Internal; - -/** - * Enumeration of various formula types. - * - * See Sections 3 and 4.8 of https://www.openoffice.org/sc/excelfileformat.pdf - */ -@Internal -public enum FormulaType { - /** Regular cell formula */ - CELL(0), - - /** - * A Shared Formula ("{=SUM(A1:E1*{1,2,3,4,5}}") - * - * Similar to an array formula, but stored in a SHAREDFMLA instead of ARRAY record as a file size optimization. - * See Section 4.8 of https://www.openoffice.org/sc/excelfileformat.pdf - */ - SHARED(1), - - /** - * An Array formula ("{=SUM(A1:E1*{1,2,3,4,5}}") - * https://support.office.com/en-us/article/Guidelines-and-examples-of-array-formulas-7D94A64E-3FF3-4686-9372-ECFD5CAA57C7 - */ - ARRAY(2), - - /** Conditional formatting */ - CONDFORMAT(3), - - /** Named range */ - NAMEDRANGE(4), - - /** - * This constant is currently very specific. The exact differences from general data - * validation formulas or conditional format formulas is not known yet - */ - DATAVALIDATION_LIST(5); - - /** @deprecated POI 3.15 beta 3. */ - private final int code; - /** - * @since POI 3.15 beta 3. - * @deprecated POI 3.15 beta 3. - * Formula type code doesn't mean anything. Only in this class for transitioning from a class with int constants to a true enum. - * Remove hard-coded numbers from the enums above. */ - private FormulaType(int code) { - this.code = code; - } - - /** - * @since POI 3.15 beta 3. - * @deprecated POI 3.15 beta 3. Used to transition code from ints to FormulaTypes. - */ - public static FormulaType forInt(int code) { - for (FormulaType type : values()) { - if (type.code == code) { - return type; - } - } - throw new IllegalArgumentException("Invalid FormulaType code: " + code); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java b/trunk/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java deleted file mode 100644 index e054f125d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java +++ /dev/null @@ -1,194 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.ss.util.CellReference; - -/** - * Optimisation - compacts many blank cell references used by a single formula. - * - * @author Josh Micich - */ -final class FormulaUsedBlankCellSet { - public static final class BookSheetKey { - - private final int _bookIndex; - private final int _sheetIndex; - - public BookSheetKey(int bookIndex, int sheetIndex) { - _bookIndex = bookIndex; - _sheetIndex = sheetIndex; - } - public int hashCode() { - return _bookIndex * 17 + _sheetIndex; - } - public boolean equals(Object obj) { - assert obj instanceof BookSheetKey : "these private cache key instances are only compared to themselves"; - BookSheetKey other = (BookSheetKey) obj; - return _bookIndex == other._bookIndex && _sheetIndex == other._sheetIndex; - } - } - - private static final class BlankCellSheetGroup { - private final List _rectangleGroups; - private int _currentRowIndex; - private int _firstColumnIndex; - private int _lastColumnIndex; - private BlankCellRectangleGroup _currentRectangleGroup; - - public BlankCellSheetGroup() { - _rectangleGroups = new ArrayList(); - _currentRowIndex = -1; - } - - public void addCell(int rowIndex, int columnIndex) { - if (_currentRowIndex == -1) { - _currentRowIndex = rowIndex; - _firstColumnIndex = columnIndex; - _lastColumnIndex = columnIndex; - } else { - if (_currentRowIndex == rowIndex && _lastColumnIndex+1 == columnIndex) { - _lastColumnIndex = columnIndex; - } else { - // cell does not fit on end of current row - if (_currentRectangleGroup == null) { - _currentRectangleGroup = new BlankCellRectangleGroup(_currentRowIndex, _firstColumnIndex, _lastColumnIndex); - } else { - if (!_currentRectangleGroup.acceptRow(_currentRowIndex, _firstColumnIndex, _lastColumnIndex)) { - _rectangleGroups.add(_currentRectangleGroup); - _currentRectangleGroup = new BlankCellRectangleGroup(_currentRowIndex, _firstColumnIndex, _lastColumnIndex); - } - } - _currentRowIndex = rowIndex; - _firstColumnIndex = columnIndex; - _lastColumnIndex = columnIndex; - } - } - } - - public boolean containsCell(int rowIndex, int columnIndex) { - for (int i=_rectangleGroups.size()-1; i>=0; i--) { - BlankCellRectangleGroup bcrg = _rectangleGroups.get(i); - if (bcrg.containsCell(rowIndex, columnIndex)) { - return true; - } - } - if(_currentRectangleGroup != null && _currentRectangleGroup.containsCell(rowIndex, columnIndex)) { - return true; - } - if (_currentRowIndex != -1 && _currentRowIndex == rowIndex) { - if (_firstColumnIndex <= columnIndex && columnIndex <= _lastColumnIndex) { - return true; - } - } - return false; - } - } - - private static final class BlankCellRectangleGroup { - - private final int _firstRowIndex; - private final int _firstColumnIndex; - private final int _lastColumnIndex; - private int _lastRowIndex; - - public BlankCellRectangleGroup(int firstRowIndex, int firstColumnIndex, int lastColumnIndex) { - _firstRowIndex = firstRowIndex; - _firstColumnIndex = firstColumnIndex; - _lastColumnIndex = lastColumnIndex; - _lastRowIndex = firstRowIndex; - } - - public boolean containsCell(int rowIndex, int columnIndex) { - if (columnIndex < _firstColumnIndex) { - return false; - } - if (columnIndex > _lastColumnIndex) { - return false; - } - if (rowIndex < _firstRowIndex) { - return false; - } - if (rowIndex > _lastRowIndex) { - return false; - } - return true; - } - - public boolean acceptRow(int rowIndex, int firstColumnIndex, int lastColumnIndex) { - if (firstColumnIndex != _firstColumnIndex) { - return false; - } - if (lastColumnIndex != _lastColumnIndex) { - return false; - } - if (rowIndex != _lastRowIndex+1) { - return false; - } - _lastRowIndex = rowIndex; - return true; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - CellReference crA = new CellReference(_firstRowIndex, _firstColumnIndex, false, false); - CellReference crB = new CellReference(_lastRowIndex, _lastColumnIndex, false, false); - sb.append(getClass().getName()); - sb.append(" [").append(crA.formatAsString()).append(':').append(crB.formatAsString()).append("]"); - return sb.toString(); - } - } - - private final Map _sheetGroupsByBookSheet; - - public FormulaUsedBlankCellSet() { - _sheetGroupsByBookSheet = new HashMap(); - } - - public void addCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) { - BlankCellSheetGroup sbcg = getSheetGroup(bookIndex, sheetIndex); - sbcg.addCell(rowIndex, columnIndex); - } - - private BlankCellSheetGroup getSheetGroup(int bookIndex, int sheetIndex) { - BookSheetKey key = new BookSheetKey(bookIndex, sheetIndex); - - BlankCellSheetGroup result = _sheetGroupsByBookSheet.get(key); - if (result == null) { - result = new BlankCellSheetGroup(); - _sheetGroupsByBookSheet.put(key, result); - } - return result; - } - - public boolean containsCell(BookSheetKey key, int rowIndex, int columnIndex) { - BlankCellSheetGroup bcsg = _sheetGroupsByBookSheet.get(key); - if (bcsg == null) { - return false; - } - return bcsg.containsCell(rowIndex, columnIndex); - } - - public boolean isEmpty() { - return _sheetGroupsByBookSheet.isEmpty(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/IEvaluationListener.java b/trunk/src/java/org/apache/poi/ss/formula/IEvaluationListener.java deleted file mode 100644 index bab3ba325..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/IEvaluationListener.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Tests can implement this class to track the internal working of the {@link WorkbookEvaluator}.
        - * - * For POI internal testing use only - * - * @author Josh Micich - */ -interface IEvaluationListener { - /** - * A (mostly) opaque interface to allow test clients to trace cache values - * Each spreadsheet cell gets one unique cache entry instance. These objects - * are safe to use as keys in {@link java.util.HashMap}s - */ - interface ICacheEntry { - ValueEval getValue(); - } - - void onCacheHit(int sheetIndex, int rowIndex, int columnIndex, ValueEval result); - void onReadPlainValue(int sheetIndex, int rowIndex, int columnIndex, ICacheEntry entry); - void onStartEvaluate(EvaluationCell cell, ICacheEntry entry); - void onEndEvaluate(ICacheEntry entry, ValueEval result); - void onClearWholeCache(); - void onClearCachedValue(ICacheEntry entry); - /** - * Internally, formula {@link ICacheEntry}s are stored in sets which may change ordering due - * to seemingly trivial changes. This method is provided to make the order of call-backs to - * {@link #onClearDependentCachedValue(ICacheEntry, int)} more deterministic. - */ - void sortDependentCachedValues(ICacheEntry[] formulaCells); - void onClearDependentCachedValue(ICacheEntry formulaCell, int depth); - void onChangeFromBlankValue(int sheetIndex, int rowIndex, int columnIndex, - EvaluationCell cell, ICacheEntry entry); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/IStabilityClassifier.java b/trunk/src/java/org/apache/poi/ss/formula/IStabilityClassifier.java deleted file mode 100644 index 089469bc6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/IStabilityClassifier.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -/** - * Used to help optimise cell evaluation result caching by allowing applications to specify which - * parts of a workbook are final.
        - * The term final is introduced here to denote immutability or 'having constant definition'. - * This classification refers to potential actions (on the evaluated workbook) by the evaluating - * application. It does not refer to operations performed by the evaluator ({@link - * WorkbookEvaluator}).
        - *
        - * General guidelines: - *
          - *
        • a plain value cell can be marked as 'final' if it will not be changed after the first call - * to {@link WorkbookEvaluator#evaluate(EvaluationCell)}. - *
        • - *
        • a formula cell can be marked as 'final' if its formula will not be changed after the first - * call to {@link WorkbookEvaluator#evaluate(EvaluationCell)}. This remains true even if changes - * in dependent values may cause the evaluated value to change.
        • - *
        • plain value cells should be marked as 'not final' if their plain value value may change. - *
        • - *
        • formula cells should be marked as 'not final' if their formula definition may change.
        • - *
        • cells which may switch between plain value and formula should also be marked as 'not final'. - *
        • - *
        - * Notes: - *
          - *
        • If none of the spreadsheet cells is expected to have its definition changed after evaluation - * begins, every cell can be marked as 'final'. This is the most efficient / least resource - * intensive option.
        • - *
        • To retain freedom to change any cell definition at any time, an application may classify all - * cells as 'not final'. This freedom comes at the expense of greater memory consumption.
        • - *
        • For the purpose of these classifications, setting the cached formula result of a cell (for - * example in {@link org.apache.poi.ss.usermodel.FormulaEvaluator#evaluateFormulaCellEnum(org.apache.poi.ss.usermodel.Cell)}) - * does not constitute changing the definition of the cell.
        • - *
        • Updating cells which have been classified as 'final' will cause the evaluator to behave - * unpredictably (typically ignoring the update).
        • - *
        - * - * @author Josh Micich - */ -public interface IStabilityClassifier { - - /** - * Convenience implementation for situations where all cell definitions remain fixed after - * evaluation begins. - */ - IStabilityClassifier TOTALLY_IMMUTABLE = new IStabilityClassifier() { - public boolean isCellFinal(int sheetIndex, int rowIndex, int columnIndex) { - return true; - } - }; - - /** - * Checks if a cell's value(/formula) is fixed - in other words - not expected to be modified - * between calls to the evaluator. (Note - this is an independent concept from whether a - * formula cell's evaluated value may change during successive calls to the evaluator). - * - * @param sheetIndex zero based index into workbook sheet list - * @param rowIndex zero based row index of cell - * @param columnIndex zero based column index of cell - * @return false if the evaluating application may need to modify the specified - * cell between calls to the evaluator. - */ - boolean isCellFinal(int sheetIndex, int rowIndex, int columnIndex); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/LazyAreaEval.java b/trunk/src/java/org/apache/poi/ss/formula/LazyAreaEval.java deleted file mode 100644 index 4bfbf41d3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/LazyAreaEval.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.AreaEvalBase; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.ptg.AreaI; -import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; -import org.apache.poi.ss.util.CellReference; - -/** - * Provides Lazy Evaluation to 3D Ranges - */ -final class LazyAreaEval extends AreaEvalBase { - private final SheetRangeEvaluator _evaluator; - - LazyAreaEval(AreaI ptg, SheetRangeEvaluator evaluator) { - super(ptg, evaluator); - _evaluator = evaluator; - } - - public LazyAreaEval(int firstRowIndex, int firstColumnIndex, int lastRowIndex, - int lastColumnIndex, SheetRangeEvaluator evaluator) { - super(evaluator, firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex); - _evaluator = evaluator; - } - - public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) { - return getRelativeValue(getFirstSheetIndex(), relativeRowIndex, relativeColumnIndex); - } - public ValueEval getRelativeValue(int sheetIndex, int relativeRowIndex, int relativeColumnIndex) { - int rowIx = (relativeRowIndex + getFirstRow() ) ; - int colIx = (relativeColumnIndex + getFirstColumn() ) ; - - return _evaluator.getEvalForCell(sheetIndex, rowIx, colIx); - } - - public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { - AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(), - relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx); - - return new LazyAreaEval(area, _evaluator); - } - public LazyAreaEval getRow(int rowIndex) { - if (rowIndex >= getHeight()) { - throw new IllegalArgumentException("Invalid rowIndex " + rowIndex - + ". Allowable range is (0.." + getHeight() + ")."); - } - int absRowIx = getFirstRow() + rowIndex; - return new LazyAreaEval(absRowIx, getFirstColumn(), absRowIx, getLastColumn(), _evaluator); - } - public LazyAreaEval getColumn(int columnIndex) { - if (columnIndex >= getWidth()) { - throw new IllegalArgumentException("Invalid columnIndex " + columnIndex - + ". Allowable range is (0.." + getWidth() + ")."); - } - int absColIx = getFirstColumn() + columnIndex; - return new LazyAreaEval(getFirstRow(), absColIx, getLastRow(), absColIx, _evaluator); - } - - public String toString() { - CellReference crA = new CellReference(getFirstRow(), getFirstColumn()); - CellReference crB = new CellReference(getLastRow(), getLastColumn()); - return getClass().getName() + "[" + - _evaluator.getSheetNameRange() + - '!' + - crA.formatAsString() + - ':' + - crB.formatAsString() + - "]"; - } - - /** - * @return whether cell at rowIndex and columnIndex is a subtotal - */ - public boolean isSubTotal(int rowIndex, int columnIndex){ - // delegate the query to the sheet evaluator which has access to internal ptgs - SheetRefEvaluator _sre = _evaluator.getSheetEvaluator(_evaluator.getFirstSheetIndex()); - return _sre.isSubTotal(getFirstRow() + rowIndex, getFirstColumn() + columnIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/LazyRefEval.java b/trunk/src/java/org/apache/poi/ss/formula/LazyRefEval.java deleted file mode 100644 index c71b0e977..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/LazyRefEval.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.RefEvalBase; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.ptg.AreaI; -import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; -import org.apache.poi.ss.util.CellReference; - -/** - * Provides Lazy Evaluation to a 3D Reference - */ -public final class LazyRefEval extends RefEvalBase { - private final SheetRangeEvaluator _evaluator; - - public LazyRefEval(int rowIndex, int columnIndex, SheetRangeEvaluator sre) { - super(sre, rowIndex, columnIndex); - _evaluator = sre; - } - - public ValueEval getInnerValueEval(int sheetIndex) { - return _evaluator.getEvalForCell(sheetIndex, getRow(), getColumn()); - } - - public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { - - AreaI area = new OffsetArea(getRow(), getColumn(), - relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx); - - return new LazyAreaEval(area, _evaluator); - } - - public boolean isSubTotal() { - SheetRefEvaluator sheetEvaluator = _evaluator.getSheetEvaluator(getFirstSheetIndex()); - return sheetEvaluator.isSubTotal(getRow(), getColumn()); - } - - public String toString() { - CellReference cr = new CellReference(getRow(), getColumn()); - return getClass().getName() + "[" + - _evaluator.getSheetNameRange() + - '!' + - cr.formatAsString() + - "]"; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/NameIdentifier.java b/trunk/src/java/org/apache/poi/ss/formula/NameIdentifier.java deleted file mode 100644 index 341a9605d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/NameIdentifier.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -public class NameIdentifier { - private final String _name; - private final boolean _isQuoted; - - public NameIdentifier(String name, boolean isQuoted) { - _name = name; - _isQuoted = isQuoted; - } - public String getName() { - return _name; - } - public boolean isQuoted() { - return _isQuoted; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()); - sb.append(" ["); - if (_isQuoted) { - sb.append("'").append(_name).append("'"); - } else { - sb.append(_name); - } - sb.append("]"); - return sb.toString(); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java b/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java deleted file mode 100644 index 8e438c966..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java +++ /dev/null @@ -1,301 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg; -import org.apache.poi.ss.formula.ptg.AttrPtg; -import org.apache.poi.ss.formula.ptg.ControlPtg; -import org.apache.poi.ss.formula.ptg.FuncVarPtg; -import org.apache.poi.ss.formula.ptg.IntersectionPtg; -import org.apache.poi.ss.formula.ptg.MemAreaPtg; -import org.apache.poi.ss.formula.ptg.MemFuncPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.RangePtg; -import org.apache.poi.ss.formula.ptg.UnionPtg; -import org.apache.poi.ss.formula.ptg.ValueOperatorPtg; -import org.apache.poi.util.Removal; - -/** - * This class performs 'operand class' transformation. Non-base tokens are classified into three - * operand classes: - *
          - *
        • reference
        • - *
        • value
        • - *
        • array
        • - *
        - *

        - * - * The final operand class chosen for each token depends on the formula type and the token's place - * in the formula. If POI gets the operand class wrong, Excel may interpret the formula - * incorrectly. This condition is typically manifested as a formula cell that displays as '#VALUE!', - * but resolves correctly when the user presses F2, enter.

        - * - * The logic implemented here was partially inspired by the description in - * "OpenOffice.org's Documentation of the Microsoft Excel File Format". The model presented there - * seems to be inconsistent with observed Excel behaviour (These differences have not been fully - * investigated). The implementation in this class has been heavily modified in order to satisfy - * concrete examples of how Excel performs the same logic (see TestRVA).

        - * - * Hopefully, as additional important test cases are identified and added to the test suite, - * patterns might become more obvious in this code and allow for simplification. - * - * @author Josh Micich - */ -final class OperandClassTransformer { - - private final FormulaType _formulaType; - - /** - * @deprecated POI 3.15 beta 3. Use {@code OperandClassTransformer(FormulaType)} instead. - */ - @Removal(version="3.17") - public OperandClassTransformer(int formulaType) { - this(FormulaType.forInt(formulaType)); - } - public OperandClassTransformer(FormulaType formulaType) { - _formulaType = formulaType; - } - - /** - * Traverses the supplied formula parse tree, calling Ptg.setClass() for each non-base - * token to set its operand class. - */ - public void transformFormula(ParseNode rootNode) { - byte rootNodeOperandClass; - switch (_formulaType) { - case CELL: - rootNodeOperandClass = Ptg.CLASS_VALUE; - break; - case ARRAY: - rootNodeOperandClass = Ptg.CLASS_ARRAY; - break; - case NAMEDRANGE: - case DATAVALIDATION_LIST: - rootNodeOperandClass = Ptg.CLASS_REF; - break; - default: - throw new RuntimeException("Incomplete code - formula type (" - + _formulaType + ") not supported yet"); - - } - transformNode(rootNode, rootNodeOperandClass, false); - } - - /** - * @param callerForceArrayFlag true if one of the current node's parents is a - * function Ptg which has been changed from default 'V' to 'A' type (due to requirements on - * the function return value). - */ - private void transformNode(ParseNode node, byte desiredOperandClass, - boolean callerForceArrayFlag) { - Ptg token = node.getToken(); - ParseNode[] children = node.getChildren(); - boolean isSimpleValueFunc = isSimpleValueFunction(token); - - if (isSimpleValueFunc) { - boolean localForceArray = desiredOperandClass == Ptg.CLASS_ARRAY; - for (int i = 0; i < children.length; i++) { - transformNode(children[i], desiredOperandClass, localForceArray); - } - setSimpleValueFuncClass((AbstractFunctionPtg) token, desiredOperandClass, callerForceArrayFlag); - return; - } - - if (isSingleArgSum(token)) { - // Need to process the argument of SUM with transformFunctionNode below - // so make a dummy FuncVarPtg for that call. - token = FuncVarPtg.SUM; - // Note - the tAttrSum token (node.getToken()) is a base - // token so does not need to have its operand class set - } - if (token instanceof ValueOperatorPtg || token instanceof ControlPtg - || token instanceof MemFuncPtg - || token instanceof MemAreaPtg - || token instanceof UnionPtg - || token instanceof IntersectionPtg) { - // Value Operator Ptgs and Control are base tokens, so token will be unchanged - // but any child nodes are processed according to desiredOperandClass and callerForceArrayFlag - - // As per OOO documentation Sec 3.2.4 "Token Class Transformation", "Step 1" - // All direct operands of value operators that are initially 'R' type will - // be converted to 'V' type. - byte localDesiredOperandClass = desiredOperandClass == Ptg.CLASS_REF ? Ptg.CLASS_VALUE : desiredOperandClass; - for (int i = 0; i < children.length; i++) { - transformNode(children[i], localDesiredOperandClass, callerForceArrayFlag); - } - return; - } - if (token instanceof AbstractFunctionPtg) { - transformFunctionNode((AbstractFunctionPtg) token, children, desiredOperandClass, callerForceArrayFlag); - return; - } - if (children.length > 0) { - if (token == RangePtg.instance) { - // TODO is any token transformation required under the various ref operators? - return; - } - throw new IllegalStateException("Node should not have any children"); - } - - if (token.isBaseToken()) { - // nothing to do - return; - } - token.setClass(transformClass(token.getPtgClass(), desiredOperandClass, callerForceArrayFlag)); - } - - private static boolean isSingleArgSum(Ptg token) { - if (token instanceof AttrPtg) { - AttrPtg attrPtg = (AttrPtg) token; - return attrPtg.isSum(); - } - return false; - } - - private static boolean isSimpleValueFunction(Ptg token) { - if (token instanceof AbstractFunctionPtg) { - AbstractFunctionPtg aptg = (AbstractFunctionPtg) token; - if (aptg.getDefaultOperandClass() != Ptg.CLASS_VALUE) { - return false; - } - int numberOfOperands = aptg.getNumberOfOperands(); - for (int i=numberOfOperands-1; i>=0; i--) { - if (aptg.getParameterClass(i) != Ptg.CLASS_VALUE) { - return false; - } - } - return true; - } - return false; - } - - private byte transformClass(byte currentOperandClass, byte desiredOperandClass, - boolean callerForceArrayFlag) { - switch (desiredOperandClass) { - case Ptg.CLASS_VALUE: - if (!callerForceArrayFlag) { - return Ptg.CLASS_VALUE; - } - // else fall through - case Ptg.CLASS_ARRAY: - return Ptg.CLASS_ARRAY; - case Ptg.CLASS_REF: - if (!callerForceArrayFlag) { - return currentOperandClass; - } - return Ptg.CLASS_REF; - } - throw new IllegalStateException("Unexpected operand class (" + desiredOperandClass + ")"); - } - - private void transformFunctionNode(AbstractFunctionPtg afp, ParseNode[] children, - byte desiredOperandClass, boolean callerForceArrayFlag) { - - boolean localForceArrayFlag; - byte defaultReturnOperandClass = afp.getDefaultOperandClass(); - - if (callerForceArrayFlag) { - switch (defaultReturnOperandClass) { - case Ptg.CLASS_REF: - if (desiredOperandClass == Ptg.CLASS_REF) { - afp.setClass(Ptg.CLASS_REF); - } else { - afp.setClass(Ptg.CLASS_ARRAY); - } - localForceArrayFlag = false; - break; - case Ptg.CLASS_ARRAY: - afp.setClass(Ptg.CLASS_ARRAY); - localForceArrayFlag = false; - break; - case Ptg.CLASS_VALUE: - afp.setClass(Ptg.CLASS_ARRAY); - localForceArrayFlag = true; - break; - default: - throw new IllegalStateException("Unexpected operand class (" - + defaultReturnOperandClass + ")"); - } - } else { - if (defaultReturnOperandClass == desiredOperandClass) { - localForceArrayFlag = false; - // an alternative would have been to for non-base Ptgs to set their operand class - // from their default, but this would require the call in many subclasses because - // the default OC is not known until the end of the constructor - afp.setClass(defaultReturnOperandClass); - } else { - switch (desiredOperandClass) { - case Ptg.CLASS_VALUE: - // always OK to set functions to return 'value' - afp.setClass(Ptg.CLASS_VALUE); - localForceArrayFlag = false; - break; - case Ptg.CLASS_ARRAY: - switch (defaultReturnOperandClass) { - case Ptg.CLASS_REF: - afp.setClass(Ptg.CLASS_REF); -// afp.setClass(Ptg.CLASS_ARRAY); - break; - case Ptg.CLASS_VALUE: - afp.setClass(Ptg.CLASS_ARRAY); - break; - default: - throw new IllegalStateException("Unexpected operand class (" - + defaultReturnOperandClass + ")"); - } - localForceArrayFlag = (defaultReturnOperandClass == Ptg.CLASS_VALUE); - break; - case Ptg.CLASS_REF: - switch (defaultReturnOperandClass) { - case Ptg.CLASS_ARRAY: - afp.setClass(Ptg.CLASS_ARRAY); - break; - case Ptg.CLASS_VALUE: - afp.setClass(Ptg.CLASS_VALUE); - break; - default: - throw new IllegalStateException("Unexpected operand class (" - + defaultReturnOperandClass + ")"); - } - localForceArrayFlag = false; - break; - default: - throw new IllegalStateException("Unexpected operand class (" - + desiredOperandClass + ")"); - } - - } - } - - for (int i = 0; i < children.length; i++) { - ParseNode child = children[i]; - byte paramOperandClass = afp.getParameterClass(i); - transformNode(child, paramOperandClass, localForceArrayFlag); - } - } - - private void setSimpleValueFuncClass(AbstractFunctionPtg afp, - byte desiredOperandClass, boolean callerForceArrayFlag) { - - if (callerForceArrayFlag || desiredOperandClass == Ptg.CLASS_ARRAY) { - afp.setClass(Ptg.CLASS_ARRAY); - } else { - afp.setClass(Ptg.CLASS_VALUE); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java b/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java deleted file mode 100644 index d7345f7cb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java +++ /dev/null @@ -1,448 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheetRange; -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ExternalNameEval; -import org.apache.poi.ss.formula.eval.FunctionNameEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.Area3DPxg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.NameXPxg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.ptg.Ref3DPxg; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.CellReference.NameType; - -/** - * Contains all the contextual information required to evaluate an operation - * within a formula - * - * For POI internal use only - */ -public final class OperationEvaluationContext { - public static final FreeRefFunction UDF = UserDefinedFunction.instance; - private final EvaluationWorkbook _workbook; - private final int _sheetIndex; - private final int _rowIndex; - private final int _columnIndex; - private final EvaluationTracker _tracker; - private final WorkbookEvaluator _bookEvaluator; - - public OperationEvaluationContext(WorkbookEvaluator bookEvaluator, EvaluationWorkbook workbook, int sheetIndex, int srcRowNum, - int srcColNum, EvaluationTracker tracker) { - _bookEvaluator = bookEvaluator; - _workbook = workbook; - _sheetIndex = sheetIndex; - _rowIndex = srcRowNum; - _columnIndex = srcColNum; - _tracker = tracker; - } - - public EvaluationWorkbook getWorkbook() { - return _workbook; - } - - public int getRowIndex() { - return _rowIndex; - } - - public int getColumnIndex() { - return _columnIndex; - } - - SheetRangeEvaluator createExternSheetRefEvaluator(ExternSheetReferenceToken ptg) { - return createExternSheetRefEvaluator(ptg.getExternSheetIndex()); - } - SheetRangeEvaluator createExternSheetRefEvaluator(String firstSheetName, String lastSheetName, int externalWorkbookNumber) { - ExternalSheet externalSheet = _workbook.getExternalSheet(firstSheetName, lastSheetName, externalWorkbookNumber); - return createExternSheetRefEvaluator(externalSheet); - } - SheetRangeEvaluator createExternSheetRefEvaluator(int externSheetIndex) { - ExternalSheet externalSheet = _workbook.getExternalSheet(externSheetIndex); - return createExternSheetRefEvaluator(externalSheet); - } - SheetRangeEvaluator createExternSheetRefEvaluator(ExternalSheet externalSheet) { - WorkbookEvaluator targetEvaluator; - int otherFirstSheetIndex; - int otherLastSheetIndex = -1; - if (externalSheet == null || externalSheet.getWorkbookName() == null) { - // sheet is in same workbook - targetEvaluator = _bookEvaluator; - if(externalSheet == null) { - otherFirstSheetIndex = 0; - } else { - otherFirstSheetIndex = _workbook.getSheetIndex(externalSheet.getSheetName()); - } - - if (externalSheet instanceof ExternalSheetRange) { - String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName(); - otherLastSheetIndex = _workbook.getSheetIndex(lastSheetName); - } - } else { - // look up sheet by name from external workbook - String workbookName = externalSheet.getWorkbookName(); - try { - targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName); - } catch (WorkbookNotFoundException e) { - throw new RuntimeException(e.getMessage(), e); - } - - otherFirstSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName()); - if (externalSheet instanceof ExternalSheetRange) { - String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName(); - otherLastSheetIndex = targetEvaluator.getSheetIndex(lastSheetName); - } - - if (otherFirstSheetIndex < 0) { - throw new RuntimeException("Invalid sheet name '" + externalSheet.getSheetName() - + "' in bool '" + workbookName + "'."); - } - } - - if (otherLastSheetIndex == -1) { - // Reference to just one sheet - otherLastSheetIndex = otherFirstSheetIndex; - } - - SheetRefEvaluator[] evals = new SheetRefEvaluator[otherLastSheetIndex-otherFirstSheetIndex+1]; - for (int i=0; inull if either workbook or sheet is not found - */ - private SheetRefEvaluator createExternSheetRefEvaluator(String workbookName, String sheetName) { - WorkbookEvaluator targetEvaluator; - if (workbookName == null) { - targetEvaluator = _bookEvaluator; - } else { - if (sheetName == null) { - throw new IllegalArgumentException("sheetName must not be null if workbookName is provided"); - } - try { - targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName); - } catch (WorkbookNotFoundException e) { - return null; - } - } - int otherSheetIndex = sheetName == null ? _sheetIndex : targetEvaluator.getSheetIndex(sheetName); - if (otherSheetIndex < 0) { - return null; - } - return new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex); - } - - public SheetRangeEvaluator getRefEvaluatorForCurrentSheet() { - SheetRefEvaluator sre = new SheetRefEvaluator(_bookEvaluator, _tracker, _sheetIndex); - return new SheetRangeEvaluator(_sheetIndex, sre); - } - - - - /** - * Resolves a cell or area reference dynamically. - * @param workbookName the name of the workbook containing the reference. If null - * the current workbook is assumed. Note - to evaluate formulas which use multiple workbooks, - * a {@link CollaboratingWorkbooksEnvironment} must be set up. - * @param sheetName the name of the sheet containing the reference. May be null - * (when workbookName is also null) in which case the current workbook and sheet is - * assumed. - * @param refStrPart1 the single cell reference or first part of the area reference. Must not - * be null. - * @param refStrPart2 the second part of the area reference. For single cell references this - * parameter must be null - * @param isA1Style specifies the format for refStrPart1 and refStrPart2. - * Pass true for 'A1' style and false for 'R1C1' style. - * TODO - currently POI only supports 'A1' reference style - * @return a {@link RefEval} or {@link AreaEval} - */ - public ValueEval getDynamicReference(String workbookName, String sheetName, String refStrPart1, - String refStrPart2, boolean isA1Style) { - if (!isA1Style) { - throw new RuntimeException("R1C1 style not supported yet"); - } - SheetRefEvaluator se = createExternSheetRefEvaluator(workbookName, sheetName); - if (se == null) { - return ErrorEval.REF_INVALID; - } - SheetRangeEvaluator sre = new SheetRangeEvaluator(_sheetIndex, se); - - // ugly typecast - TODO - make spreadsheet version more easily accessible - SpreadsheetVersion ssVersion = ((FormulaParsingWorkbook)_workbook).getSpreadsheetVersion(); - - NameType part1refType = classifyCellReference(refStrPart1, ssVersion); - switch (part1refType) { - case BAD_CELL_OR_NAMED_RANGE: - return ErrorEval.REF_INVALID; - case NAMED_RANGE: - EvaluationName nm = ((FormulaParsingWorkbook)_workbook).getName(refStrPart1, _sheetIndex); - if(!nm.isRange()){ - throw new RuntimeException("Specified name '" + refStrPart1 + "' is not a range as expected."); - } - return _bookEvaluator.evaluateNameFormula(nm.getNameDefinition(), this); - } - if (refStrPart2 == null) { - // no ':' - switch (part1refType) { - case COLUMN: - case ROW: - return ErrorEval.REF_INVALID; - case CELL: - CellReference cr = new CellReference(refStrPart1); - return new LazyRefEval(cr.getRow(), cr.getCol(), sre); - } - throw new IllegalStateException("Unexpected reference classification of '" + refStrPart1 + "'."); - } - NameType part2refType = classifyCellReference(refStrPart1, ssVersion); - switch (part2refType) { - case BAD_CELL_OR_NAMED_RANGE: - return ErrorEval.REF_INVALID; - case NAMED_RANGE: - throw new RuntimeException("Cannot evaluate '" + refStrPart1 - + "'. Indirect evaluation of defined names not supported yet"); - } - - if (part2refType != part1refType) { - // LHS and RHS of ':' must be compatible - return ErrorEval.REF_INVALID; - } - int firstRow, firstCol, lastRow, lastCol; - switch (part1refType) { - case COLUMN: - firstRow =0; - if (part2refType.equals(NameType.COLUMN)) - { - lastRow = ssVersion.getLastRowIndex(); - firstCol = parseRowRef(refStrPart1); - lastCol = parseRowRef(refStrPart2); - } - else { - lastRow = ssVersion.getLastRowIndex(); - firstCol = parseColRef(refStrPart1); - lastCol = parseColRef(refStrPart2); - } - break; - case ROW: - // support of cell range in the form of integer:integer - firstCol = 0; - if (part2refType.equals(NameType.ROW)) - { - firstRow = parseColRef(refStrPart1); - lastRow = parseColRef(refStrPart2); - lastCol = ssVersion.getLastColumnIndex(); - } else { - lastCol = ssVersion.getLastColumnIndex(); - firstRow = parseRowRef(refStrPart1); - lastRow = parseRowRef(refStrPart2); - } - break; - case CELL: - CellReference cr; - cr = new CellReference(refStrPart1); - firstRow = cr.getRow(); - firstCol = cr.getCol(); - cr = new CellReference(refStrPart2); - lastRow = cr.getRow(); - lastCol = cr.getCol(); - break; - default: - throw new IllegalStateException("Unexpected reference classification of '" + refStrPart1 + "'."); - } - return new LazyAreaEval(firstRow, firstCol, lastRow, lastCol, sre); - } - - private static int parseRowRef(String refStrPart) { - return CellReference.convertColStringToIndex(refStrPart); - } - - private static int parseColRef(String refStrPart) { - return Integer.parseInt(refStrPart) - 1; - } - - private static NameType classifyCellReference(String str, SpreadsheetVersion ssVersion) { - int len = str.length(); - if (len < 1) { - return CellReference.NameType.BAD_CELL_OR_NAMED_RANGE; - } - return CellReference.classifyCellReference(str, ssVersion); - } - - public FreeRefFunction findUserDefinedFunction(String functionName) { - return _bookEvaluator.findUserDefinedFunction(functionName); - } - - public ValueEval getRefEval(int rowIndex, int columnIndex) { - SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet(); - return new LazyRefEval(rowIndex, columnIndex, sre); - } - public ValueEval getRef3DEval(Ref3DPtg rptg) { - SheetRangeEvaluator sre = createExternSheetRefEvaluator(rptg.getExternSheetIndex()); - return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre); - } - public ValueEval getRef3DEval(Ref3DPxg rptg) { - SheetRangeEvaluator sre = createExternSheetRefEvaluator( - rptg.getSheetName(), rptg.getLastSheetName(), rptg.getExternalWorkbookNumber()); - return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre); - } - - public ValueEval getAreaEval(int firstRowIndex, int firstColumnIndex, - int lastRowIndex, int lastColumnIndex) { - SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet(); - return new LazyAreaEval(firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex, sre); - } - public ValueEval getArea3DEval(Area3DPtg aptg) { - SheetRangeEvaluator sre = createExternSheetRefEvaluator(aptg.getExternSheetIndex()); - return new LazyAreaEval(aptg.getFirstRow(), aptg.getFirstColumn(), - aptg.getLastRow(), aptg.getLastColumn(), sre); - } - public ValueEval getArea3DEval(Area3DPxg aptg) { - SheetRangeEvaluator sre = createExternSheetRefEvaluator( - aptg.getSheetName(), aptg.getLastSheetName(), aptg.getExternalWorkbookNumber()); - return new LazyAreaEval(aptg.getFirstRow(), aptg.getFirstColumn(), - aptg.getLastRow(), aptg.getLastColumn(), sre); - } - - public ValueEval getNameXEval(NameXPtg nameXPtg) { - // Is the name actually on our workbook? - ExternalSheet externSheet = _workbook.getExternalSheet(nameXPtg.getSheetRefIndex()); - if(externSheet == null || externSheet.getWorkbookName() == null) { - // External reference to our own workbook's name - return getLocalNameXEval(nameXPtg); - } - - // Look it up for the external workbook - String workbookName = externSheet.getWorkbookName(); - ExternalName externName = _workbook.getExternalName( - nameXPtg.getSheetRefIndex(), - nameXPtg.getNameIndex() - ); - return getExternalNameXEval(externName, workbookName); - } - public ValueEval getNameXEval(NameXPxg nameXPxg) { - ExternalSheet externSheet = _workbook.getExternalSheet(nameXPxg.getSheetName(), null, nameXPxg.getExternalWorkbookNumber()); - if(externSheet == null || externSheet.getWorkbookName() == null) { - // External reference to our own workbook's name - return getLocalNameXEval(nameXPxg); - } - - // Look it up for the external workbook - String workbookName = externSheet.getWorkbookName(); - ExternalName externName = _workbook.getExternalName( - nameXPxg.getNameName(), - nameXPxg.getSheetName(), - nameXPxg.getExternalWorkbookNumber() - ); - return getExternalNameXEval(externName, workbookName); - } - - private ValueEval getLocalNameXEval(NameXPxg nameXPxg) { - // Look up the sheet, if present - int sIdx = -1; - if (nameXPxg.getSheetName() != null) { - sIdx = _workbook.getSheetIndex(nameXPxg.getSheetName()); - } - - // Is it a name or a function? - String name = nameXPxg.getNameName(); - EvaluationName evalName = _workbook.getName(name, sIdx); - if (evalName != null) { - // Process it as a name - return new ExternalNameEval(evalName); - } else { - // Must be an external function - return new FunctionNameEval(name); - } - } - private ValueEval getLocalNameXEval(NameXPtg nameXPtg) { - String name = _workbook.resolveNameXText(nameXPtg); - - // Try to parse it as a name - int sheetNameAt = name.indexOf('!'); - EvaluationName evalName = null; - if (sheetNameAt > -1) { - // Sheet based name - String sheetName = name.substring(0, sheetNameAt); - String nameName = name.substring(sheetNameAt+1); - evalName = _workbook.getName(nameName, _workbook.getSheetIndex(sheetName)); - } else { - // Workbook based name - evalName = _workbook.getName(name, -1); - } - - if (evalName != null) { - // Process it as a name - return new ExternalNameEval(evalName); - } else { - // Must be an external function - return new FunctionNameEval(name); - } - } - public int getSheetIndex() { - return _sheetIndex; - } - - private ValueEval getExternalNameXEval(ExternalName externName, String workbookName) { - try { - // Fetch the workbook this refers to, and the name as defined with that - WorkbookEvaluator refWorkbookEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName); - EvaluationName evaluationName = refWorkbookEvaluator.getName(externName.getName(),externName.getIx()-1); - if (evaluationName != null && evaluationName.hasFormula()){ - if (evaluationName.getNameDefinition().length > 1) { - throw new RuntimeException("Complex name formulas not supported yet"); - } - - // Need to evaluate the reference in the context of the other book - OperationEvaluationContext refWorkbookContext = new OperationEvaluationContext( - refWorkbookEvaluator, refWorkbookEvaluator.getWorkbook(), -1, -1, -1, _tracker); - - Ptg ptg = evaluationName.getNameDefinition()[0]; - if (ptg instanceof Ref3DPtg){ - Ref3DPtg ref3D = (Ref3DPtg)ptg; - return refWorkbookContext.getRef3DEval(ref3D); - } else if (ptg instanceof Ref3DPxg){ - Ref3DPxg ref3D = (Ref3DPxg)ptg; - return refWorkbookContext.getRef3DEval(ref3D); - } else if(ptg instanceof Area3DPtg){ - Area3DPtg area3D = (Area3DPtg)ptg; - return refWorkbookContext.getArea3DEval(area3D); - } else if(ptg instanceof Area3DPxg){ - Area3DPxg area3D = (Area3DPxg)ptg; - return refWorkbookContext.getArea3DEval(area3D); - } - } - return ErrorEval.REF_INVALID; - } catch(WorkbookNotFoundException wnfe){ - return ErrorEval.REF_INVALID; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java b/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java deleted file mode 100644 index 31b86b1fd..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg; -import org.apache.poi.ss.formula.ptg.AddPtg; -import org.apache.poi.ss.formula.ptg.ConcatPtg; -import org.apache.poi.ss.formula.ptg.DividePtg; -import org.apache.poi.ss.formula.ptg.EqualPtg; -import org.apache.poi.ss.formula.ptg.GreaterEqualPtg; -import org.apache.poi.ss.formula.ptg.GreaterThanPtg; -import org.apache.poi.ss.formula.ptg.IntersectionPtg; -import org.apache.poi.ss.formula.ptg.LessEqualPtg; -import org.apache.poi.ss.formula.ptg.LessThanPtg; -import org.apache.poi.ss.formula.ptg.MultiplyPtg; -import org.apache.poi.ss.formula.ptg.NotEqualPtg; -import org.apache.poi.ss.formula.ptg.OperationPtg; -import org.apache.poi.ss.formula.ptg.PercentPtg; -import org.apache.poi.ss.formula.ptg.PowerPtg; -import org.apache.poi.ss.formula.ptg.RangePtg; -import org.apache.poi.ss.formula.ptg.SubtractPtg; -import org.apache.poi.ss.formula.ptg.UnaryMinusPtg; -import org.apache.poi.ss.formula.ptg.UnaryPlusPtg; -import org.apache.poi.ss.formula.eval.ConcatEval; -import org.apache.poi.ss.formula.eval.FunctionEval; -import org.apache.poi.ss.formula.eval.IntersectionEval; -import org.apache.poi.ss.formula.eval.PercentEval; -import org.apache.poi.ss.formula.eval.RangeEval; -import org.apache.poi.ss.formula.eval.RelationalOperationEval; -import org.apache.poi.ss.formula.eval.TwoOperandNumericOperation; -import org.apache.poi.ss.formula.eval.UnaryMinusEval; -import org.apache.poi.ss.formula.eval.UnaryPlusEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -import org.apache.poi.ss.formula.functions.Function; -import org.apache.poi.ss.formula.functions.Indirect; - -/** - * This class creates OperationEval instances to help evaluate OperationPtg - * formula tokens. - * - * @author Josh Micich - */ -final class OperationEvaluatorFactory { - - private static final Map _instancesByPtgClass = initialiseInstancesMap(); - - private OperationEvaluatorFactory() { - // no instances of this class - } - - private static Map initialiseInstancesMap() { - Map m = new HashMap(32); - - put(m, EqualPtg.instance, RelationalOperationEval.EqualEval); - put(m, GreaterEqualPtg.instance, RelationalOperationEval.GreaterEqualEval); - put(m, GreaterThanPtg.instance, RelationalOperationEval.GreaterThanEval); - put(m, LessEqualPtg.instance, RelationalOperationEval.LessEqualEval); - put(m, LessThanPtg.instance, RelationalOperationEval.LessThanEval); - put(m, NotEqualPtg.instance, RelationalOperationEval.NotEqualEval); - - put(m, ConcatPtg.instance, ConcatEval.instance); - put(m, AddPtg.instance, TwoOperandNumericOperation.AddEval); - put(m, DividePtg.instance, TwoOperandNumericOperation.DivideEval); - put(m, MultiplyPtg.instance, TwoOperandNumericOperation.MultiplyEval); - put(m, PercentPtg.instance, PercentEval.instance); - put(m, PowerPtg.instance, TwoOperandNumericOperation.PowerEval); - put(m, SubtractPtg.instance, TwoOperandNumericOperation.SubtractEval); - put(m, UnaryMinusPtg.instance, UnaryMinusEval.instance); - put(m, UnaryPlusPtg.instance, UnaryPlusEval.instance); - put(m, RangePtg.instance, RangeEval.instance); - put(m, IntersectionPtg.instance, IntersectionEval.instance); - return m; - } - - private static void put(Map m, OperationPtg ptgKey, - Function instance) { - // make sure ptg has single private constructor because map lookups assume singleton keys - Constructor[] cc = ptgKey.getClass().getDeclaredConstructors(); - if (cc.length > 1 || !Modifier.isPrivate(cc[0].getModifiers())) { - throw new RuntimeException("Failed to verify instance (" - + ptgKey.getClass().getName() + ") is a singleton."); - } - m.put(ptgKey, instance); - } - - /** - * returns the OperationEval concrete impl instance corresponding - * to the supplied operationPtg - */ - public static ValueEval evaluate(OperationPtg ptg, ValueEval[] args, - OperationEvaluationContext ec) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - Function result = _instancesByPtgClass.get(ptg); - - if (result != null) { - return result.evaluate(args, ec.getRowIndex(), (short) ec.getColumnIndex()); - } - - if (ptg instanceof AbstractFunctionPtg) { - AbstractFunctionPtg fptg = (AbstractFunctionPtg)ptg; - int functionIndex = fptg.getFunctionIndex(); - switch (functionIndex) { - case FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT: - return Indirect.instance.evaluate(args, ec); - case FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL: - return UserDefinedFunction.instance.evaluate(args, ec); - } - - return FunctionEval.getBasicFunction(functionIndex).evaluate(args, ec.getRowIndex(), (short) ec.getColumnIndex()); - } - throw new RuntimeException("Unexpected operation ptg class (" + ptg.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ParseNode.java b/trunk/src/java/org/apache/poi/ss/formula/ParseNode.java deleted file mode 100644 index a41ec2634..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ParseNode.java +++ /dev/null @@ -1,209 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.ptg.ArrayPtg; -import org.apache.poi.ss.formula.ptg.AttrPtg; -import org.apache.poi.ss.formula.ptg.FuncVarPtg; -import org.apache.poi.ss.formula.ptg.MemAreaPtg; -import org.apache.poi.ss.formula.ptg.MemFuncPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -/** - * Represents a syntactic element from a formula by encapsulating the corresponding Ptg - * token. Each ParseNode may have child ParseNodes in the case when the wrapped - * Ptg is non-atomic. - */ -final class ParseNode { - - public static final ParseNode[] EMPTY_ARRAY = { }; - private final Ptg _token; - private final ParseNode[] _children; - private boolean _isIf; - private final int _tokenCount; - - public ParseNode(Ptg token, ParseNode[] children) { - if (token == null) { - throw new IllegalArgumentException("token must not be null"); - } - _token = token; - _children = children.clone(); - _isIf = isIf(token); - int tokenCount = 1; - for (int i = 0; i < children.length; i++) { - tokenCount += children[i].getTokenCount(); - } - if (_isIf) { - // there will be 2 or 3 extra tAttr tokens according to whether the false param is present - tokenCount += children.length; - } - _tokenCount = tokenCount; - } - public ParseNode(Ptg token) { - this(token, EMPTY_ARRAY); - } - public ParseNode(Ptg token, ParseNode child0) { - this(token, new ParseNode[] { child0, }); - } - public ParseNode(Ptg token, ParseNode child0, ParseNode child1) { - this(token, new ParseNode[] { child0, child1, }); - } - private int getTokenCount() { - return _tokenCount; - } - public int getEncodedSize() { - int result = _token instanceof ArrayPtg ? ArrayPtg.PLAIN_TOKEN_SIZE : _token.getSize(); - for (int i = 0; i < _children.length; i++) { - result += _children[i].getEncodedSize(); - } - return result; - } - - /** - * Collects the array of Ptg tokens for the specified tree. - */ - public static Ptg[] toTokenArray(ParseNode rootNode) { - TokenCollector temp = new TokenCollector(rootNode.getTokenCount()); - rootNode.collectPtgs(temp); - return temp.getResult(); - } - private void collectPtgs(TokenCollector temp) { - if (isIf(_token)) { - collectIfPtgs(temp); - return; - } - boolean isPreFixOperator = _token instanceof MemFuncPtg || _token instanceof MemAreaPtg; - if (isPreFixOperator) { - temp.add(_token); - } - for (int i=0; i< getChildren().length; i++) { - getChildren()[i].collectPtgs(temp); - } - if (!isPreFixOperator) { - temp.add(_token); - } - } - /** - * The IF() function gets marked up with two or three tAttr tokens. - * Similar logic will be required for CHOOSE() when it is supported - * - * See excelfileformat.pdf sec 3.10.5 "tAttr (19H) - */ - private void collectIfPtgs(TokenCollector temp) { - - // condition goes first - getChildren()[0].collectPtgs(temp); - - // placeholder for tAttrIf - int ifAttrIndex = temp.createPlaceholder(); - - // true parameter - getChildren()[1].collectPtgs(temp); - - // placeholder for first skip attr - int skipAfterTrueParamIndex = temp.createPlaceholder(); - int trueParamSize = temp.sumTokenSizes(ifAttrIndex+1, skipAfterTrueParamIndex); - - AttrPtg attrIf = AttrPtg.createIf(trueParamSize + 4); // distance to start of false parameter/tFuncVar. +4 for tAttrSkip after true - - if (getChildren().length > 2) { - // false param present - - // false parameter - getChildren()[2].collectPtgs(temp); - - int skipAfterFalseParamIndex = temp.createPlaceholder(); - - int falseParamSize = temp.sumTokenSizes(skipAfterTrueParamIndex+1, skipAfterFalseParamIndex); - - AttrPtg attrSkipAfterTrue = AttrPtg.createSkip(falseParamSize + 4 + 4 - 1); // 1 less than distance to end of if FuncVar(size=4). +4 for attr skip before - AttrPtg attrSkipAfterFalse = AttrPtg.createSkip(4 - 1); // 1 less than distance to end of if FuncVar(size=4). - - temp.setPlaceholder(ifAttrIndex, attrIf); - temp.setPlaceholder(skipAfterTrueParamIndex, attrSkipAfterTrue); - temp.setPlaceholder(skipAfterFalseParamIndex, attrSkipAfterFalse); - } else { - // false parameter not present - AttrPtg attrSkipAfterTrue = AttrPtg.createSkip(4 - 1); // 1 less than distance to end of if FuncVar(size=4). - - temp.setPlaceholder(ifAttrIndex, attrIf); - temp.setPlaceholder(skipAfterTrueParamIndex, attrSkipAfterTrue); - } - temp.add(_token); - } - - private static boolean isIf(Ptg token) { - if (token instanceof FuncVarPtg) { - FuncVarPtg func = (FuncVarPtg) token; - if (FunctionMetadataRegistry.FUNCTION_NAME_IF.equals(func.getName())) { - return true; - } - } - return false; - } - - public Ptg getToken() { - return _token; - } - - public ParseNode[] getChildren() { - return _children; - } - - private static final class TokenCollector { - - private final Ptg[] _ptgs; - private int _offset; - - public TokenCollector(int tokenCount) { - _ptgs = new Ptg[tokenCount]; - _offset = 0; - } - - public int sumTokenSizes(int fromIx, int toIx) { - int result = 0; - for (int i=fromIx; i>> 32)) + 17 * _rowIndex; - } - - public boolean equals(Object obj) { - assert obj instanceof Loc : "these package-private cache key instances are only compared to themselves"; - Loc other = (Loc) obj; - return _bookSheetColumn == other._bookSheetColumn && _rowIndex == other._rowIndex; - } - - public int getRowIndex() { - return _rowIndex; - } - - public int getColumnIndex() { - return (int)(_bookSheetColumn & 0x000FFFF); - } - - public int getSheetIndex() { - return (int)((_bookSheetColumn >> 32) & 0xFFFF); - } - - public int getBookIndex() { - return (int)((_bookSheetColumn >> 48) & 0xFFFF); - } - } - - private Map _plainValueEntriesByLoc; - - public PlainCellCache() { - _plainValueEntriesByLoc = new HashMap(); - } - public void put(Loc key, PlainValueCellCacheEntry cce) { - _plainValueEntriesByLoc.put(key, cce); - } - public void clear() { - _plainValueEntriesByLoc.clear(); - } - public PlainValueCellCacheEntry get(Loc key) { - return _plainValueEntriesByLoc.get(key); - } - public void remove(Loc key) { - _plainValueEntriesByLoc.remove(key); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/PlainValueCellCacheEntry.java b/trunk/src/java/org/apache/poi/ss/formula/PlainValueCellCacheEntry.java deleted file mode 100644 index 171b12e17..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/PlainValueCellCacheEntry.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Used for non-formula cells, primarily to keep track of the referencing (formula) cells. - * - * @author Josh Micich - */ -final class PlainValueCellCacheEntry extends CellCacheEntry { - public PlainValueCellCacheEntry(ValueEval value) { - updateValue(value); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/SharedFormula.java b/trunk/src/java/org/apache/poi/ss/formula/SharedFormula.java deleted file mode 100644 index 0cf492e9c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SharedFormula.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.ptg.*; -import org.apache.poi.ss.SpreadsheetVersion; - -/** - * Encapsulates logic to convert shared formulaa into non shared equivalent - */ -public class SharedFormula { - - private final int _columnWrappingMask; - private final int _rowWrappingMask; - - public SharedFormula(SpreadsheetVersion ssVersion){ - _columnWrappingMask = ssVersion.getLastColumnIndex(); //"IV" for .xls and "XFD" for .xlsx - _rowWrappingMask = ssVersion.getLastRowIndex(); - } - - /** - * Creates a non shared formula from the shared formula counterpart, i.e. - * Converts the shared formula into the equivalent {@link org.apache.poi.ss.formula.ptg.Ptg} array that it would have, - * were it not shared. - * - * @param ptgs parsed tokens of the shared formula - * @param formulaRow - * @param formulaColumn - */ - public Ptg[] convertSharedFormulas(Ptg[] ptgs, int formulaRow, int formulaColumn) { - - Ptg[] newPtgStack = new Ptg[ptgs.length]; - - for (int k = 0; k < ptgs.length; k++) { - Ptg ptg = ptgs[k]; - byte originalOperandClass = -1; - if (!ptg.isBaseToken()) { - originalOperandClass = ptg.getPtgClass(); - } - if (ptg instanceof RefPtgBase) { - RefPtgBase refNPtg = (RefPtgBase)ptg; - ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()), - fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()), - refNPtg.isRowRelative(), - refNPtg.isColRelative()); - ptg.setClass(originalOperandClass); - } else if (ptg instanceof AreaPtgBase) { - AreaPtgBase areaNPtg = (AreaPtgBase)ptg; - ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()), - fixupRelativeRow(formulaRow,areaNPtg.getLastRow(),areaNPtg.isLastRowRelative()), - fixupRelativeColumn(formulaColumn,areaNPtg.getFirstColumn(),areaNPtg.isFirstColRelative()), - fixupRelativeColumn(formulaColumn,areaNPtg.getLastColumn(),areaNPtg.isLastColRelative()), - areaNPtg.isFirstRowRelative(), - areaNPtg.isLastRowRelative(), - areaNPtg.isFirstColRelative(), - areaNPtg.isLastColRelative()); - ptg.setClass(originalOperandClass); - } else if (ptg instanceof OperandPtg) { - // Any subclass of OperandPtg is mutable, so it's safest to not share these instances. - ptg = ((OperandPtg) ptg).copy(); - } else { - // all other Ptgs are immutable and can be shared - } - newPtgStack[k] = ptg; - } - return newPtgStack; - } - - private int fixupRelativeColumn(int currentcolumn, int column, boolean relative) { - if(relative) { - // mask out upper bits to produce 'wrapping' at the maximum column ("IV" for .xls and "XFD" for .xlsx) - return (column + currentcolumn) & _columnWrappingMask; - } - return column; - } - - private int fixupRelativeRow(int currentrow, int row, boolean relative) { - if(relative) { - return (row+currentrow) & _rowWrappingMask; - } - return row; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/SheetIdentifier.java b/trunk/src/java/org/apache/poi/ss/formula/SheetIdentifier.java deleted file mode 100644 index 71c7cd0f0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SheetIdentifier.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -public class SheetIdentifier { - public String _bookName; - public NameIdentifier _sheetIdentifier; - - public SheetIdentifier(String bookName, NameIdentifier sheetIdentifier) { - _bookName = bookName; - _sheetIdentifier = sheetIdentifier; - } - public String getBookName() { - return _bookName; - } - public NameIdentifier getSheetIdentifier() { - return _sheetIdentifier; - } - protected void asFormulaString(StringBuffer sb) { - if (_bookName != null) { - sb.append(" [").append(_sheetIdentifier.getName()).append("]"); - } - if (_sheetIdentifier.isQuoted()) { - sb.append("'").append(_sheetIdentifier.getName()).append("'"); - } else { - sb.append(_sheetIdentifier.getName()); - } - } - public String asFormulaString() { - StringBuffer sb = new StringBuffer(32); - asFormulaString(sb); - return sb.toString(); - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()); - sb.append(" ["); - asFormulaString(sb); - sb.append("]"); - return sb.toString(); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java b/trunk/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java deleted file mode 100644 index 479704887..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java +++ /dev/null @@ -1,223 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.SpreadsheetVersion; - -/** - * Formats sheet names for use in formula expressions. - * - * @author Josh Micich - */ -public final class SheetNameFormatter { - - private static final char DELIMITER = '\''; - - /** - * Matches a single cell ref with no absolute ('$') markers - */ - private static final Pattern CELL_REF_PATTERN = Pattern.compile("([A-Za-z]+)([0-9]+)"); - - private SheetNameFormatter() { - // no instances of this class - } - /** - * Used to format sheet names as they would appear in cell formula expressions. - * @return the sheet name unchanged if there is no need for delimiting. Otherwise the sheet - * name is enclosed in single quotes ('). Any single quotes which were already present in the - * sheet name will be converted to double single quotes (''). - */ - public static String format(String rawSheetName) { - StringBuffer sb = new StringBuffer(rawSheetName.length() + 2); - appendFormat(sb, rawSheetName); - return sb.toString(); - } - - /** - * Convenience method for ({@link #format(String)}) when a StringBuffer is already available. - * - * @param out - sheet name will be appended here possibly with delimiting quotes - */ - public static void appendFormat(StringBuffer out, String rawSheetName) { - boolean needsQuotes = needsDelimiting(rawSheetName); - if(needsQuotes) { - out.append(DELIMITER); - appendAndEscape(out, rawSheetName); - out.append(DELIMITER); - } else { - out.append(rawSheetName); - } - } - public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) { - boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName); - if(needsQuotes) { - out.append(DELIMITER); - out.append('['); - appendAndEscape(out, workbookName.replace('[', '(').replace(']', ')')); - out.append(']'); - appendAndEscape(out, rawSheetName); - out.append(DELIMITER); - } else { - out.append('['); - out.append(workbookName); - out.append(']'); - out.append(rawSheetName); - } - } - - private static void appendAndEscape(StringBuffer sb, String rawSheetName) { - int len = rawSheetName.length(); - for(int i=0; itrue if the presence of the specified character in a sheet name would - * require the sheet name to be delimited in formulas. This includes every non-alphanumeric - * character besides underscore '_' and dot '.'. - */ - /* package */ static boolean isSpecialChar(char ch) { - // note - Character.isJavaIdentifierPart() would allow dollars '$' - if(Character.isLetterOrDigit(ch)) { - return false; - } - switch(ch) { - case '.': // dot is OK - case '_': // underscore is OK - return false; - case '\n': - case '\r': - case '\t': - throw new RuntimeException("Illegal character (0x" - + Integer.toHexString(ch) + ") found in sheet name"); - } - return true; - } - - - /** - * Used to decide whether sheet names like 'AB123' need delimiting due to the fact that they - * look like cell references. - *

        - * This code is currently being used for translating formulas represented with Ptg - * tokens into human readable text form. In formula expressions, a sheet name always has a - * trailing '!' so there is little chance for ambiguity. It doesn't matter too much what this - * method returns but it is worth noting the likely consumers of these formula text strings: - *

          - *
        1. POI's own formula parser
        2. - *
        3. Visual reading by human
        4. - *
        5. VBA automation entry into Excel cell contents e.g. ActiveCell.Formula = "=c64!A1"
        6. - *
        7. Manual entry into Excel cell contents
        8. - *
        9. Some third party formula parser
        10. - *
        - * - * At the time of writing, POI's formula parser tolerates cell-like sheet names in formulas - * with or without delimiters. The same goes for Excel(2007), both manual and automated entry. - *

        - * For better or worse this implementation attempts to replicate Excel's formula renderer. - * Excel uses range checking on the apparent 'row' and 'column' components. Note however that - * the maximum sheet size varies across versions. - * @see org.apache.poi.ss.util.CellReference - */ - /* package */ static boolean cellReferenceIsWithinRange(String lettersPrefix, String numbersSuffix) { - return CellReference.cellReferenceIsWithinRange(lettersPrefix, numbersSuffix, SpreadsheetVersion.EXCEL97); - } - - /** - * Note - this method assumes the specified rawSheetName has only letters and digits. It - * cannot be used to match absolute or range references (using the dollar or colon char). - *

        - * Some notable cases: - *

        - * - * - * - * - * - * - * - * - * - * - *
        Input Result Comments
        "A1"  true 
        "a111"  true 
        "AA"  false 
        "aa1"  true 
        "A1A"  false 
        "A1A1"  false 
        "A$1:$C$20"  falseNot a plain cell reference
        "SALES20080101"  trueStill needs delimiting even though well out of range
        - * - * @return true if there is any possible ambiguity that the specified rawSheetName - * could be interpreted as a valid cell name. - */ - /* package */ static boolean nameLooksLikePlainCellReference(String rawSheetName) { - Matcher matcher = CELL_REF_PATTERN.matcher(rawSheetName); - if(!matcher.matches()) { - return false; - } - - // rawSheetName == "Sheet1" gets this far. - String lettersPrefix = matcher.group(1); - String numbersSuffix = matcher.group(2); - return cellReferenceIsWithinRange(lettersPrefix, numbersSuffix); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/SheetRange.java b/trunk/src/java/org/apache/poi/ss/formula/SheetRange.java deleted file mode 100644 index ab7ccab83..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SheetRange.java +++ /dev/null @@ -1,23 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -public interface SheetRange { - public int getFirstSheetIndex(); - public int getLastSheetIndex(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java b/trunk/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java deleted file mode 100644 index 68dbb9be3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Evaluator for returning cells or sheets for a range of sheets - */ -final class SheetRangeEvaluator implements SheetRange { - private final int _firstSheetIndex; - private final int _lastSheetIndex; - private SheetRefEvaluator[] _sheetEvaluators; - - public SheetRangeEvaluator(int firstSheetIndex, int lastSheetIndex, SheetRefEvaluator[] sheetEvaluators) { - if (firstSheetIndex < 0) { - throw new IllegalArgumentException("Invalid firstSheetIndex: " + firstSheetIndex + "."); - } - if (lastSheetIndex < firstSheetIndex) { - throw new IllegalArgumentException("Invalid lastSheetIndex: " + lastSheetIndex + " for firstSheetIndex: " + firstSheetIndex + "."); - } - _firstSheetIndex = firstSheetIndex; - _lastSheetIndex = lastSheetIndex; - _sheetEvaluators = sheetEvaluators.clone(); - } - public SheetRangeEvaluator(int onlySheetIndex, SheetRefEvaluator sheetEvaluator) { - this(onlySheetIndex, onlySheetIndex, new SheetRefEvaluator[] {sheetEvaluator}); - } - - public SheetRefEvaluator getSheetEvaluator(int sheetIndex) { - if (sheetIndex < _firstSheetIndex || sheetIndex > _lastSheetIndex) { - throw new IllegalArgumentException("Invalid SheetIndex: " + sheetIndex + - " - Outside range " + _firstSheetIndex + " : " + _lastSheetIndex); - } - return _sheetEvaluators[sheetIndex-_firstSheetIndex]; - } - - public int getFirstSheetIndex() { - return _firstSheetIndex; - } - public int getLastSheetIndex() { - return _lastSheetIndex; - } - - public String getSheetName(int sheetIndex) { - return getSheetEvaluator(sheetIndex).getSheetName(); - } - public String getSheetNameRange() { - StringBuilder sb = new StringBuilder(); - sb.append(getSheetName(_firstSheetIndex)); - if (_firstSheetIndex != _lastSheetIndex) { - sb.append(':'); - sb.append(getSheetName(_lastSheetIndex)); - } - return sb.toString(); - } - - public ValueEval getEvalForCell(int sheetIndex, int rowIndex, int columnIndex) { - return getSheetEvaluator(sheetIndex).getEvalForCell(rowIndex, columnIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/SheetRangeIdentifier.java b/trunk/src/java/org/apache/poi/ss/formula/SheetRangeIdentifier.java deleted file mode 100644 index c0b851ed5..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SheetRangeIdentifier.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -public class SheetRangeIdentifier extends SheetIdentifier { - public NameIdentifier _lastSheetIdentifier; - - public SheetRangeIdentifier(String bookName, NameIdentifier firstSheetIdentifier, NameIdentifier lastSheetIdentifier) { - super(bookName, firstSheetIdentifier); - _lastSheetIdentifier = lastSheetIdentifier; - } - public NameIdentifier getFirstSheetIdentifier() { - return super.getSheetIdentifier(); - } - public NameIdentifier getLastSheetIdentifier() { - return _lastSheetIdentifier; - } - protected void asFormulaString(StringBuffer sb) { - super.asFormulaString(sb); - sb.append(':'); - if (_lastSheetIdentifier.isQuoted()) { - sb.append("'").append(_lastSheetIdentifier.getName()).append("'"); - } else { - sb.append(_lastSheetIdentifier.getName()); - } - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java b/trunk/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java deleted file mode 100644 index cc27e66c4..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.ptg.FuncVarPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.CellType; - -/** - * Evaluator for cells within a specific Sheet - */ -final class SheetRefEvaluator { - private final WorkbookEvaluator _bookEvaluator; - private final EvaluationTracker _tracker; - private final int _sheetIndex; - private EvaluationSheet _sheet; - - public SheetRefEvaluator(WorkbookEvaluator bookEvaluator, EvaluationTracker tracker, int sheetIndex) { - if (sheetIndex < 0) { - throw new IllegalArgumentException("Invalid sheetIndex: " + sheetIndex + "."); - } - _bookEvaluator = bookEvaluator; - _tracker = tracker; - _sheetIndex = sheetIndex; - } - - public String getSheetName() { - return _bookEvaluator.getSheetName(_sheetIndex); - } - - public ValueEval getEvalForCell(int rowIndex, int columnIndex) { - return _bookEvaluator.evaluateReference(getSheet(), _sheetIndex, rowIndex, columnIndex, _tracker); - } - - private EvaluationSheet getSheet() { - if (_sheet == null) { - _sheet = _bookEvaluator.getSheet(_sheetIndex); - } - return _sheet; - } - - /** - * @return whether cell at rowIndex and columnIndex is a subtotal - * @see org.apache.poi.ss.formula.functions.Subtotal - */ - public boolean isSubTotal(int rowIndex, int columnIndex){ - boolean subtotal = false; - EvaluationCell cell = getSheet().getCell(rowIndex, columnIndex); - if(cell != null && cell.getCellTypeEnum() == CellType.FORMULA){ - EvaluationWorkbook wb = _bookEvaluator.getWorkbook(); - for(Ptg ptg : wb.getFormulaTokens(cell)){ - if(ptg instanceof FuncVarPtg){ - FuncVarPtg f = (FuncVarPtg)ptg; - if("SUBTOTAL".equals(f.getName())) { - subtotal = true; - break; - } - } - } - } - return subtotal; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ThreeDEval.java b/trunk/src/java/org/apache/poi/ss/formula/ThreeDEval.java deleted file mode 100644 index 0bda63749..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ThreeDEval.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Optional Extension to the likes of {@link AreaEval} and - * {@link org.apache.poi.ss.formula.eval.AreaEvalBase}, - * which allows for looking up 3D (sheet+row+column) evaluations - */ -public interface ThreeDEval extends TwoDEval, SheetRange { - /** - * @param sheetIndex sheet index (zero based) - * @param rowIndex relative row index (zero based) - * @param columnIndex relative column index (zero based) - * @return element at the specified row and column position - */ - ValueEval getValue(int sheetIndex, int rowIndex, int columnIndex); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/TwoDEval.java b/trunk/src/java/org/apache/poi/ss/formula/TwoDEval.java deleted file mode 100644 index c52d0f3ef..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/TwoDEval.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Common interface of {@link AreaEval} and {@link org.apache.poi.ss.formula.eval.AreaEvalBase}, - * for 2D (row+column) evaluations - */ -public interface TwoDEval extends ValueEval { - - /** - * @param rowIndex relative row index (zero based) - * @param columnIndex relative column index (zero based) - * @return element at the specified row and column position - */ - ValueEval getValue(int rowIndex, int columnIndex); - - int getWidth(); - int getHeight(); - - /** - * @return true if the area has just a single row, this also includes - * the trivial case when the area has just a single cell. - */ - boolean isRow(); - - /** - * @return true if the area has just a single column, this also includes - * the trivial case when the area has just a single cell. - */ - boolean isColumn(); - - /** - * @param rowIndex relative row index (zero based) - * @return a single row {@link TwoDEval} - */ - TwoDEval getRow(int rowIndex); - /** - * @param columnIndex relative column index (zero based) - * @return a single column {@link TwoDEval} - */ - TwoDEval getColumn(int columnIndex); - - - /** - * @return true if the cell at row and col is a subtotal - */ - boolean isSubTotal(int rowIndex, int columnIndex); - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/UserDefinedFunction.java b/trunk/src/java/org/apache/poi/ss/formula/UserDefinedFunction.java deleted file mode 100644 index c52613755..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/UserDefinedFunction.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.ss.formula.eval.FunctionNameEval; -import org.apache.poi.ss.formula.eval.NotImplementedFunctionException; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -/** - * - * Common entry point for all user-defined (non-built-in) functions (where - * AbstractFunctionPtg.field_2_fnc_index == 255) - * - * @author Josh Micich - * @author Petr Udalau - Improved resolving of UDFs through the ToolPacks. - */ -final class UserDefinedFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new UserDefinedFunction(); - - private UserDefinedFunction() { - // enforce singleton - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - int nIncomingArgs = args.length; - if(nIncomingArgs < 1) { - throw new RuntimeException("function name argument missing"); - } - - ValueEval nameArg = args[0]; - String functionName; - if (nameArg instanceof FunctionNameEval) { - functionName = ((FunctionNameEval) nameArg).getFunctionName(); - } else { - throw new RuntimeException("First argument should be a NameEval, but got (" - + nameArg.getClass().getName() + ")"); - } - FreeRefFunction targetFunc = ec.findUserDefinedFunction(functionName); - if (targetFunc == null) { - throw new NotImplementedFunctionException(functionName); - } - int nOutGoingArgs = nIncomingArgs -1; - ValueEval[] outGoingArgs = new ValueEval[nOutGoingArgs]; - System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs); - return targetFunc.evaluate(outGoingArgs, ec); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java b/trunk/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java deleted file mode 100644 index 47dc952f7..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -/** - * Should be implemented by any {@link org.apache.poi.ss.formula.ptg.Ptg} subclass that needs a workbook to render its formula. - *
        - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface WorkbookDependentFormula { - String toFormulaString(FormulaRenderingWorkbook book); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java b/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java deleted file mode 100644 index 3fad35edc..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java +++ /dev/null @@ -1,833 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Stack; -import java.util.TreeSet; - -import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException; -import org.apache.poi.ss.formula.atp.AnalysisToolPak; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.ExternalNameEval; -import org.apache.poi.ss.formula.eval.FunctionEval; -import org.apache.poi.ss.formula.eval.FunctionNameEval; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.NotImplementedException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -import org.apache.poi.ss.formula.functions.Choose; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.functions.Function; -import org.apache.poi.ss.formula.functions.IfFunc; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.Area3DPxg; -import org.apache.poi.ss.formula.ptg.AreaErrPtg; -import org.apache.poi.ss.formula.ptg.AreaPtg; -import org.apache.poi.ss.formula.ptg.AttrPtg; -import org.apache.poi.ss.formula.ptg.BoolPtg; -import org.apache.poi.ss.formula.ptg.ControlPtg; -import org.apache.poi.ss.formula.ptg.DeletedArea3DPtg; -import org.apache.poi.ss.formula.ptg.DeletedRef3DPtg; -import org.apache.poi.ss.formula.ptg.ErrPtg; -import org.apache.poi.ss.formula.ptg.ExpPtg; -import org.apache.poi.ss.formula.ptg.FuncVarPtg; -import org.apache.poi.ss.formula.ptg.IntPtg; -import org.apache.poi.ss.formula.ptg.MemAreaPtg; -import org.apache.poi.ss.formula.ptg.MemErrPtg; -import org.apache.poi.ss.formula.ptg.MemFuncPtg; -import org.apache.poi.ss.formula.ptg.MissingArgPtg; -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.NameXPxg; -import org.apache.poi.ss.formula.ptg.NumberPtg; -import org.apache.poi.ss.formula.ptg.OperationPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.ptg.Ref3DPxg; -import org.apache.poi.ss.formula.ptg.RefErrorPtg; -import org.apache.poi.ss.formula.ptg.RefPtg; -import org.apache.poi.ss.formula.ptg.StringPtg; -import org.apache.poi.ss.formula.ptg.UnionPtg; -import org.apache.poi.ss.formula.ptg.UnknownPtg; -import org.apache.poi.ss.formula.udf.AggregatingUDFFinder; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -/** - * Evaluates formula cells.

        - * - * For performance reasons, this class keeps a cache of all previously calculated intermediate - * cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between - * calls to evaluate~ methods on this class.
        - * - * For POI internal use only - * - * @author Josh Micich - * @author Thies Wellpott (debug output enhancements) - */ -@Internal -public final class WorkbookEvaluator { - - private static final POILogger LOG = POILogFactory.getLogger(WorkbookEvaluator.class); - - private final EvaluationWorkbook _workbook; - private EvaluationCache _cache; - /** part of cache entry key (useful when evaluating multiple workbooks) */ - private int _workbookIx; - - private final IEvaluationListener _evaluationListener; - private final Map _sheetIndexesBySheet; - private final Map _sheetIndexesByName; - private CollaboratingWorkbooksEnvironment _collaboratingWorkbookEnvironment; - private final IStabilityClassifier _stabilityClassifier; - private final AggregatingUDFFinder _udfFinder; - - private boolean _ignoreMissingWorkbooks = false; - - /** - * whether print detailed messages about the next formula evaluation - */ - private boolean dbgEvaluationOutputForNextEval = false; - - // special logger for formula evaluation output (because of possibly very large output) - private final POILogger EVAL_LOG = POILogFactory.getLogger("POI.FormulaEval"); - // current indent level for evalution; negative value for no output - private int dbgEvaluationOutputIndent = -1; - - /** - * @param udfFinder pass null for default (AnalysisToolPak only) - */ - public WorkbookEvaluator(EvaluationWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - this (workbook, null, stabilityClassifier, udfFinder); - } - /* package */ WorkbookEvaluator(EvaluationWorkbook workbook, IEvaluationListener evaluationListener, - IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - _workbook = workbook; - _evaluationListener = evaluationListener; - _cache = new EvaluationCache(evaluationListener); - _sheetIndexesBySheet = new IdentityHashMap(); - _sheetIndexesByName = new IdentityHashMap(); - _collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY; - _workbookIx = 0; - _stabilityClassifier = stabilityClassifier; - - AggregatingUDFFinder defaultToolkit = // workbook can be null in unit tests - workbook == null ? null : (AggregatingUDFFinder)workbook.getUDFFinder(); - if(defaultToolkit != null && udfFinder != null) { - defaultToolkit.add(udfFinder); - } - _udfFinder = defaultToolkit; - } - - /** - * also for debug use. Used in toString methods - */ - /* package */ String getSheetName(int sheetIndex) { - return _workbook.getSheetName(sheetIndex); - } - - /* package */ EvaluationSheet getSheet(int sheetIndex) { - return _workbook.getSheet(sheetIndex); - } - - /* package */ EvaluationWorkbook getWorkbook() { - return _workbook; - } - - /* package */ EvaluationName getName(String name, int sheetIndex) { - EvaluationName evalName = _workbook.getName(name, sheetIndex); - return evalName; - } - - private static boolean isDebugLogEnabled() { - return LOG.check(POILogger.DEBUG); - } - private static boolean isInfoLogEnabled() { - return LOG.check(POILogger.INFO); - } - private static void logDebug(String s) { - if (isDebugLogEnabled()) { - LOG.log(POILogger.DEBUG, s); - } - } - private static void logInfo(String s) { - if (isInfoLogEnabled()) { - LOG.log(POILogger.INFO, s); - } - } - /* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache, int workbookIx) { - _collaboratingWorkbookEnvironment = collaboratingWorkbooksEnvironment; - _cache = cache; - _workbookIx = workbookIx; - } - /* package */ CollaboratingWorkbooksEnvironment getEnvironment() { - return _collaboratingWorkbookEnvironment; - } - - /** - * Discards the current workbook environment and attaches to the default 'empty' environment. - * Also resets evaluation cache. - */ - /* package */ void detachFromEnvironment() { - _collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY; - _cache = new EvaluationCache(_evaluationListener); - _workbookIx = 0; - } - /** - * @return the evaluator for another workbook which is part of the same {@link CollaboratingWorkbooksEnvironment} - */ - /* package */ WorkbookEvaluator getOtherWorkbookEvaluator(String workbookName) throws WorkbookNotFoundException { - return _collaboratingWorkbookEnvironment.getWorkbookEvaluator(workbookName); - } - - /* package */ IEvaluationListener getEvaluationListener() { - return _evaluationListener; - } - - /** - * Should be called whenever there are changes to input cells in the evaluated workbook. - * Failure to call this method after changing cell values will cause incorrect behaviour - * of the evaluate~ methods of this class - */ - public void clearAllCachedResultValues() { - _cache.clear(); - _sheetIndexesBySheet.clear(); - _workbook.clearAllCachedResultValues(); - } - - /** - * Should be called to tell the cell value cache that the specified (value or formula) cell - * has changed. - */ - public void notifyUpdateCell(EvaluationCell cell) { - int sheetIndex = getSheetIndex(cell.getSheet()); - _cache.notifyUpdateCell(_workbookIx, sheetIndex, cell); - } - /** - * Should be called to tell the cell value cache that the specified cell has just been - * deleted. - */ - public void notifyDeleteCell(EvaluationCell cell) { - int sheetIndex = getSheetIndex(cell.getSheet()); - _cache.notifyDeleteCell(_workbookIx, sheetIndex, cell); - } - - private int getSheetIndex(EvaluationSheet sheet) { - Integer result = _sheetIndexesBySheet.get(sheet); - if (result == null) { - int sheetIndex = _workbook.getSheetIndex(sheet); - if (sheetIndex < 0) { - throw new RuntimeException("Specified sheet from a different book"); - } - result = Integer.valueOf(sheetIndex); - _sheetIndexesBySheet.put(sheet, result); - } - return result.intValue(); - } - - public ValueEval evaluate(EvaluationCell srcCell) { - int sheetIndex = getSheetIndex(srcCell.getSheet()); - return evaluateAny(srcCell, sheetIndex, srcCell.getRowIndex(), srcCell.getColumnIndex(), new EvaluationTracker(_cache)); - } - - /** - * Case-insensitive. - * @return -1 if sheet with specified name does not exist - */ - /* package */ int getSheetIndex(String sheetName) { - Integer result = _sheetIndexesByName.get(sheetName); - if (result == null) { - int sheetIndex = _workbook.getSheetIndex(sheetName); - if (sheetIndex < 0) { - return -1; - } - result = Integer.valueOf(sheetIndex); - _sheetIndexesByName.put(sheetName, result); - } - return result.intValue(); - } - - /* package */ int getSheetIndexByExternIndex(int externSheetIndex) { - return _workbook.convertFromExternSheetIndex(externSheetIndex); - } - - - /** - * @return never null, never {@link BlankEval} - */ - private ValueEval evaluateAny(EvaluationCell srcCell, int sheetIndex, - int rowIndex, int columnIndex, EvaluationTracker tracker) { - - // avoid tracking dependencies to cells that have constant definition - boolean shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true - : !_stabilityClassifier.isCellFinal(sheetIndex, rowIndex, columnIndex); - if (srcCell == null || srcCell.getCellTypeEnum() != CellType.FORMULA) { - ValueEval result = getValueFromNonFormulaCell(srcCell); - if (shouldCellDependencyBeRecorded) { - tracker.acceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result); - } - return result; - } - - FormulaCellCacheEntry cce = _cache.getOrCreateFormulaCellEntry(srcCell); - if (shouldCellDependencyBeRecorded || cce.isInputSensitive()) { - tracker.acceptFormulaDependency(cce); - } - IEvaluationListener evalListener = _evaluationListener; - ValueEval result; - if (cce.getValue() == null) { - if (!tracker.startEvaluate(cce)) { - return ErrorEval.CIRCULAR_REF_ERROR; - } - OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker); - - try { - - Ptg[] ptgs = _workbook.getFormulaTokens(srcCell); - if (evalListener == null) { - result = evaluateFormula(ec, ptgs); - } else { - evalListener.onStartEvaluate(srcCell, cce); - result = evaluateFormula(ec, ptgs); - evalListener.onEndEvaluate(cce, result); - } - - tracker.updateCacheResult(result); - } - catch (NotImplementedException e) { - throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex); - } catch (RuntimeException re) { - if (re.getCause() instanceof WorkbookNotFoundException && _ignoreMissingWorkbooks) { - logInfo(re.getCause().getMessage() + " - Continuing with cached value!"); - switch(srcCell.getCachedFormulaResultTypeEnum()) { - case NUMERIC: - result = new NumberEval(srcCell.getNumericCellValue()); - break; - case STRING: - result = new StringEval(srcCell.getStringCellValue()); - break; - case BLANK: - result = BlankEval.instance; - break; - case BOOLEAN: - result = BoolEval.valueOf(srcCell.getBooleanCellValue()); - break; - case ERROR: - result = ErrorEval.valueOf(srcCell.getErrorCellValue()); - break; - case FORMULA: - default: - throw new RuntimeException("Unexpected cell type '" + srcCell.getCellTypeEnum()+"' found!"); - } - } else { - throw re; - } - } finally { - tracker.endEvaluate(cce); - } - } else { - if(evalListener != null) { - evalListener.onCacheHit(sheetIndex, rowIndex, columnIndex, cce.getValue()); - } - return cce.getValue(); - } - if (isDebugLogEnabled()) { - String sheetName = getSheetName(sheetIndex); - CellReference cr = new CellReference(rowIndex, columnIndex); - logDebug("Evaluated " + sheetName + "!" + cr.formatAsString() + " to " + result.toString()); - } - // Usually (result === cce.getValue()) - // But sometimes: (result==ErrorEval.CIRCULAR_REF_ERROR, cce.getValue()==null) - // When circular references are detected, the cache entry is only updated for - // the top evaluation frame - return result; - } - - /** - * Adds the current cell reference to the exception for easier debugging. - * Would be nice to get the formula text as well, but that seems to require - * too much digging around and casting to get the FormulaRenderingWorkbook. - */ - private NotImplementedException addExceptionInfo(NotImplementedException inner, int sheetIndex, int rowIndex, int columnIndex) { - - try { - String sheetName = _workbook.getSheetName(sheetIndex); - CellReference cr = new CellReference(sheetName, rowIndex, columnIndex, false, false); - String msg = "Error evaluating cell " + cr.formatAsString(); - return new NotImplementedException(msg, inner); - } catch (Exception e) { - // avoid bombing out during exception handling - LOG.log(POILogger.ERROR, "Can't add exception info", e); - return inner; // preserve original exception - } - } - /** - * Gets the value from a non-formula cell. - * @param cell may be null - * @return {@link BlankEval} if cell is null or blank, never null - */ - /* package */ static ValueEval getValueFromNonFormulaCell(EvaluationCell cell) { - if (cell == null) { - return BlankEval.instance; - } - CellType cellType = cell.getCellTypeEnum(); - switch (cellType) { - case NUMERIC: - return new NumberEval(cell.getNumericCellValue()); - case STRING: - return new StringEval(cell.getStringCellValue()); - case BOOLEAN: - return BoolEval.valueOf(cell.getBooleanCellValue()); - case BLANK: - return BlankEval.instance; - case ERROR: - return ErrorEval.valueOf(cell.getErrorCellValue()); - default: - throw new RuntimeException("Unexpected cell type (" + cellType + ")"); - } - - } - - - // visibility raised for testing - @Internal - /* package */ ValueEval evaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs) { - - String dbgIndentStr = ""; // always init. to non-null just for defensive avoiding NPE - if (dbgEvaluationOutputForNextEval) { - // first evaluation call when ouput is desired, so iit. this evaluator instance - dbgEvaluationOutputIndent = 1; - dbgEvaluationOutputForNextEval = false; - } - if (dbgEvaluationOutputIndent > 0) { - // init. indent string to needed spaces (create as substring vom very long space-only string; - // limit indendation for deep recursions) - dbgIndentStr = " "; - dbgIndentStr = dbgIndentStr.substring(0, Math.min(dbgIndentStr.length(), dbgEvaluationOutputIndent*2)); - EVAL_LOG.log(POILogger.WARN, dbgIndentStr - + "- evaluateFormula('" + ec.getRefEvaluatorForCurrentSheet().getSheetNameRange() - + "'/" + new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString() - + "): " + Arrays.toString(ptgs).replaceAll("\\Qorg.apache.poi.ss.formula.ptg.\\E", "")); - dbgEvaluationOutputIndent++; - } - - Stack stack = new Stack(); - for (int i = 0, iSize = ptgs.length; i < iSize; i++) { - - // since we don't know how to handle these yet :( - Ptg ptg = ptgs[i]; - if (dbgEvaluationOutputIndent > 0) { - EVAL_LOG.log(POILogger.INFO, dbgIndentStr + " * ptg " + i + ": " + ptg); - } - if (ptg instanceof AttrPtg) { - AttrPtg attrPtg = (AttrPtg) ptg; - if (attrPtg.isSum()) { - // Excel prefers to encode 'SUM()' as a tAttr token, but this evaluator - // expects the equivalent function token - ptg = FuncVarPtg.SUM; - } - if (attrPtg.isOptimizedChoose()) { - ValueEval arg0 = stack.pop(); - int[] jumpTable = attrPtg.getJumpTable(); - int dist; - int nChoices = jumpTable.length; - try { - int switchIndex = Choose.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex()); - if (switchIndex<1 || switchIndex > nChoices) { - stack.push(ErrorEval.VALUE_INVALID); - dist = attrPtg.getChooseFuncOffset() + 4; // +4 for tFuncFar(CHOOSE) - } else { - dist = jumpTable[switchIndex-1]; - } - } catch (EvaluationException e) { - stack.push(e.getErrorEval()); - dist = attrPtg.getChooseFuncOffset() + 4; // +4 for tFuncFar(CHOOSE) - } - // Encoded dist for tAttrChoose includes size of jump table, but - // countTokensToBeSkipped() does not (it counts whole tokens). - dist -= nChoices*2+2; // subtract jump table size - i+= countTokensToBeSkipped(ptgs, i, dist); - continue; - } - if (attrPtg.isOptimizedIf()) { - ValueEval arg0 = stack.pop(); - boolean evaluatedPredicate; - try { - evaluatedPredicate = IfFunc.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex()); - } catch (EvaluationException e) { - stack.push(e.getErrorEval()); - int dist = attrPtg.getData(); - i+= countTokensToBeSkipped(ptgs, i, dist); - attrPtg = (AttrPtg) ptgs[i]; - dist = attrPtg.getData()+1; - i+= countTokensToBeSkipped(ptgs, i, dist); - continue; - } - if (evaluatedPredicate) { - // nothing to skip - true param follows - } else { - int dist = attrPtg.getData(); - i+= countTokensToBeSkipped(ptgs, i, dist); - Ptg nextPtg = ptgs[i+1]; - if (ptgs[i] instanceof AttrPtg && nextPtg instanceof FuncVarPtg && - // in order to verify that there is no third param, we need to check - // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()! - ((FuncVarPtg)nextPtg).getFunctionIndex() == FunctionMetadataRegistry.FUNCTION_INDEX_IF) { - // this is an if statement without a false param (as opposed to MissingArgPtg as the false param) - i++; - stack.push(BoolEval.FALSE); - } - } - continue; - } - if (attrPtg.isSkip()) { - int dist = attrPtg.getData()+1; - i+= countTokensToBeSkipped(ptgs, i, dist); - if (stack.peek() == MissingArgEval.instance) { - stack.pop(); - stack.push(BlankEval.instance); - } - continue; - } - } - if (ptg instanceof ControlPtg) { - // skip Parentheses, Attr, etc - continue; - } - if (ptg instanceof MemFuncPtg || ptg instanceof MemAreaPtg) { - // can ignore, rest of tokens for this expression are in OK RPN order - continue; - } - if (ptg instanceof MemErrPtg) { - continue; - } - - ValueEval opResult; - if (ptg instanceof OperationPtg) { - OperationPtg optg = (OperationPtg) ptg; - - if (optg instanceof UnionPtg) { continue; } - - - int numops = optg.getNumberOfOperands(); - ValueEval[] ops = new ValueEval[numops]; - - // storing the ops in reverse order since they are popping - for (int j = numops - 1; j >= 0; j--) { - ValueEval p = stack.pop(); - ops[j] = p; - } -// logDebug("invoke " + operation + " (nAgs=" + numops + ")"); - opResult = OperationEvaluatorFactory.evaluate(optg, ops, ec); - } else { - opResult = getEvalForPtg(ptg, ec); - } - if (opResult == null) { - throw new RuntimeException("Evaluation result must not be null"); - } -// logDebug("push " + opResult); - stack.push(opResult); - if (dbgEvaluationOutputIndent > 0) { - EVAL_LOG.log(POILogger.INFO, dbgIndentStr + " = " + opResult); - } - } - - ValueEval value = stack.pop(); - if (!stack.isEmpty()) { - throw new IllegalStateException("evaluation stack not empty"); - } - ValueEval result = dereferenceResult(value, ec.getRowIndex(), ec.getColumnIndex()); - if (dbgEvaluationOutputIndent > 0) { - EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "finshed eval of " - + new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString() - + ": " + result); - dbgEvaluationOutputIndent--; - if (dbgEvaluationOutputIndent == 1) { - // this evaluation is done, reset indent to stop logging - dbgEvaluationOutputIndent = -1; - } - } // if - return result; - - } - - /** - * Calculates the number of tokens that the evaluator should skip upon reaching a tAttrSkip. - * - * @return the number of tokens (starting from startIndex+1) that need to be skipped - * to achieve the specified distInBytes skip distance. - */ - private static int countTokensToBeSkipped(Ptg[] ptgs, int startIndex, int distInBytes) { - int remBytes = distInBytes; - int index = startIndex; - while (remBytes != 0) { - index++; - remBytes -= ptgs[index].getSize(); - if (remBytes < 0) { - throw new RuntimeException("Bad skip distance (wrong token size calculation)."); - } - if (index >= ptgs.length) { - throw new RuntimeException("Skip distance too far (ran out of formula tokens)."); - } - } - return index-startIndex; - } - - /** - * Dereferences a single value from any AreaEval or RefEval evaluation - * result. If the supplied evaluationResult is just a plain value, it is - * returned as-is. - * - * @return a {@link NumberEval}, {@link StringEval}, {@link BoolEval}, or - * {@link ErrorEval}. Never null. {@link BlankEval} is - * converted to {@link NumberEval#ZERO} - */ - public static ValueEval dereferenceResult(ValueEval evaluationResult, int srcRowNum, int srcColNum) { - ValueEval value; - try { - value = OperandResolver.getSingleValue(evaluationResult, srcRowNum, srcColNum); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (value == BlankEval.instance) { - // Note Excel behaviour here. A blank final final value is converted to zero. - return NumberEval.ZERO; - // Formulas _never_ evaluate to blank. If a formula appears to have evaluated to - // blank, the actual value is empty string. This can be verified with ISBLANK(). - } - return value; - } - - - /** - * returns an appropriate Eval impl instance for the Ptg. The Ptg must be - * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg, - * StringPtg, BoolPtg
        special Note: OperationPtg subtypes cannot be - * passed here! - */ - private ValueEval getEvalForPtg(Ptg ptg, OperationEvaluationContext ec) { - // consider converting all these (ptg instanceof XxxPtg) expressions to (ptg.getClass() == XxxPtg.class) - - if (ptg instanceof NamePtg) { - // Named ranges, macro functions - NamePtg namePtg = (NamePtg) ptg; - EvaluationName nameRecord = _workbook.getName(namePtg); - return getEvalForNameRecord(nameRecord, ec); - } - if (ptg instanceof NameXPtg) { - // Externally defined named ranges or macro functions - return processNameEval(ec.getNameXEval((NameXPtg)ptg), ec); - } - if (ptg instanceof NameXPxg) { - // Externally defined named ranges or macro functions - return processNameEval(ec.getNameXEval((NameXPxg)ptg), ec); - } - - if (ptg instanceof IntPtg) { - return new NumberEval(((IntPtg)ptg).getValue()); - } - if (ptg instanceof NumberPtg) { - return new NumberEval(((NumberPtg)ptg).getValue()); - } - if (ptg instanceof StringPtg) { - return new StringEval(((StringPtg) ptg).getValue()); - } - if (ptg instanceof BoolPtg) { - return BoolEval.valueOf(((BoolPtg) ptg).getValue()); - } - if (ptg instanceof ErrPtg) { - return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode()); - } - if (ptg instanceof MissingArgPtg) { - return MissingArgEval.instance; - } - if (ptg instanceof AreaErrPtg ||ptg instanceof RefErrorPtg - || ptg instanceof DeletedArea3DPtg || ptg instanceof DeletedRef3DPtg) { - return ErrorEval.REF_INVALID; - } - if (ptg instanceof Ref3DPtg) { - return ec.getRef3DEval((Ref3DPtg)ptg); - } - if (ptg instanceof Ref3DPxg) { - return ec.getRef3DEval((Ref3DPxg)ptg); - } - if (ptg instanceof Area3DPtg) { - return ec.getArea3DEval((Area3DPtg)ptg); - } - if (ptg instanceof Area3DPxg) { - return ec.getArea3DEval((Area3DPxg)ptg); - } - if (ptg instanceof RefPtg) { - RefPtg rptg = (RefPtg) ptg; - return ec.getRefEval(rptg.getRow(), rptg.getColumn()); - } - if (ptg instanceof AreaPtg) { - AreaPtg aptg = (AreaPtg) ptg; - return ec.getAreaEval(aptg.getFirstRow(), aptg.getFirstColumn(), aptg.getLastRow(), aptg.getLastColumn()); - } - - if (ptg instanceof UnknownPtg) { - // POI uses UnknownPtg when the encoded Ptg array seems to be corrupted. - // This seems to occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790) - // In any case, formulas are re-parsed before execution, so UnknownPtg should not get here - throw new RuntimeException("UnknownPtg not allowed"); - } - if (ptg instanceof ExpPtg) { - // ExpPtg is used for array formulas and shared formulas. - // it is currently unsupported, and may not even get implemented here - throw new RuntimeException("ExpPtg currently not supported"); - } - - throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")"); - } - - private ValueEval processNameEval(ValueEval eval, OperationEvaluationContext ec) { - if (eval instanceof ExternalNameEval) { - EvaluationName name = ((ExternalNameEval)eval).getName(); - return getEvalForNameRecord(name, ec); - } - return eval; - } - - private ValueEval getEvalForNameRecord(EvaluationName nameRecord, OperationEvaluationContext ec) { - if (nameRecord.isFunctionName()) { - return new FunctionNameEval(nameRecord.getNameText()); - } - if (nameRecord.hasFormula()) { - return evaluateNameFormula(nameRecord.getNameDefinition(), ec); - } - - throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'"); - } - - /** - * YK: Used by OperationEvaluationContext to resolve indirect names. - */ - /*package*/ ValueEval evaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec) { - if (ptgs.length == 1) { - return getEvalForPtg(ptgs[0], ec); - } - return evaluateFormula(ec, ptgs); - } - - /** - * Used by the lazy ref evals whenever they need to get the value of a contained cell. - */ - /* package */ ValueEval evaluateReference( - EvaluationSheet sheet, int sheetIndex, int rowIndex, - int columnIndex, EvaluationTracker tracker) { - - EvaluationCell cell = sheet.getCell(rowIndex, columnIndex); - return evaluateAny(cell, sheetIndex, rowIndex, columnIndex, tracker); - } - public FreeRefFunction findUserDefinedFunction(String functionName) { - return _udfFinder.findFunction(functionName); - } - - /** - * Whether to ignore missing references to external workbooks and - * use cached formula results in the main workbook instead. - *

        - * In some cases exetrnal workbooks referenced by formulas in the main workbook are not avaiable. - * With this method you can control how POI handles such missing references: - *

          - *
        • by default ignoreMissingWorkbooks=false and POI throws {@link WorkbookNotFoundException} - * if an external reference cannot be resolved
        • - *
        • if ignoreMissingWorkbooks=true then POI uses cached formula result - * that already exists in the main workbook
        • - *
        - * - * @param ignore whether to ignore missing references to external workbooks - * @see Bug 52575 for details - */ - public void setIgnoreMissingWorkbooks(boolean ignore){ - _ignoreMissingWorkbooks = ignore; - } - public boolean isIgnoreMissingWorkbooks(){ - return _ignoreMissingWorkbooks; - } - - /** - * Return a collection of functions that POI can evaluate - * - * @return names of functions supported by POI - */ - public static Collection getSupportedFunctionNames(){ - Collection lst = new TreeSet(); - lst.addAll(FunctionEval.getSupportedFunctionNames()); - lst.addAll(AnalysisToolPak.getSupportedFunctionNames()); - return Collections.unmodifiableCollection(lst); - } - - /** - * Return a collection of functions that POI does not support - * - * @return names of functions NOT supported by POI - */ - public static Collection getNotSupportedFunctionNames(){ - Collection lst = new TreeSet(); - lst.addAll(FunctionEval.getNotSupportedFunctionNames()); - lst.addAll(AnalysisToolPak.getNotSupportedFunctionNames()); - return Collections.unmodifiableCollection(lst); - } - - /** - * Register a ATP function in runtime. - * - * @param name the function name - * @param func the functoin to register - * @throws IllegalArgumentException if the function is unknown or already registered. - * @since 3.8 beta6 - */ - public static void registerFunction(String name, FreeRefFunction func){ - AnalysisToolPak.registerFunction(name, func); - } - - /** - * Register a function in runtime. - * - * @param name the function name - * @param func the functoin to register - * @throws IllegalArgumentException if the function is unknown or already registered. - * @since 3.8 beta6 - */ - public static void registerFunction(String name, Function func){ - FunctionEval.registerFunction(name, func); - } - - public void setDebugEvaluationOutputForNextEval(boolean value){ - dbgEvaluationOutputForNextEval = value; - } - public boolean isDebugEvaluationOutputForNextEval(){ - return dbgEvaluationOutputForNextEval; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluatorProvider.java b/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluatorProvider.java deleted file mode 100644 index dd6f09bd1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluatorProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.util.Internal; - -/** - * Provides access to a {@link WorkbookEvaluator}, eg for use with - * {@link CollaboratingWorkbooksEnvironment} - * - *

        For POI internal use only - */ -@Internal -public interface WorkbookEvaluatorProvider { - /** - * Provide the underlying WorkbookEvaluator - */ - WorkbookEvaluator _getWorkbookEvaluator(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java b/trunk/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java deleted file mode 100644 index a0da336d7..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or - * agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.atp; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.TreeSet; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.NotImplementedFunctionException; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.function.FunctionMetadata; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -import org.apache.poi.ss.formula.functions.Bin2Dec; -import org.apache.poi.ss.formula.functions.Complex; -import org.apache.poi.ss.formula.functions.Countifs; -import org.apache.poi.ss.formula.functions.Dec2Bin; -import org.apache.poi.ss.formula.functions.Dec2Hex; -import org.apache.poi.ss.formula.functions.Delta; -import org.apache.poi.ss.formula.functions.EDate; -import org.apache.poi.ss.formula.functions.EOMonth; -import org.apache.poi.ss.formula.functions.FactDouble; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.functions.Hex2Dec; -import org.apache.poi.ss.formula.functions.ImReal; -import org.apache.poi.ss.formula.functions.Imaginary; -import org.apache.poi.ss.formula.functions.Oct2Dec; -import org.apache.poi.ss.formula.functions.Quotient; -import org.apache.poi.ss.formula.functions.Sumifs; -import org.apache.poi.ss.formula.functions.WeekNum; -import org.apache.poi.ss.formula.udf.UDFFinder; - -/** - * Analysis Toolpack Function Definitions - */ -public final class AnalysisToolPak implements UDFFinder { - - public static final UDFFinder instance = new AnalysisToolPak(); - - private static final class NotImplemented implements FreeRefFunction { - private final String _functionName; - - public NotImplemented(String functionName) { - _functionName = functionName; - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - throw new NotImplementedFunctionException(_functionName); - } - } - - private final Map _functionsByName = createFunctionsMap(); - - private AnalysisToolPak() { - // enforce singleton - } - - public FreeRefFunction findFunction(String name) { - // functions that are available in Excel 2007+ have a prefix _xlfn. - // if you save such a .xlsx workbook as .xls - if(name.startsWith("_xlfn.")) name = name.substring(6); - - // FIXME: inconsistent case-sensitivity - return _functionsByName.get(name.toUpperCase(Locale.ROOT)); - } - - private Map createFunctionsMap() { - Map m = new HashMap(108); - - r(m, "ACCRINT", null); - r(m, "ACCRINTM", null); - r(m, "AMORDEGRC", null); - r(m, "AMORLINC", null); - r(m, "AVERAGEIF", null); - r(m, "AVERAGEIFS", null); - r(m, "BAHTTEXT", null); - r(m, "BESSELI", null); - r(m, "BESSELJ", null); - r(m, "BESSELK", null); - r(m, "BESSELY", null); - r(m, "BIN2DEC", Bin2Dec.instance); - r(m, "BIN2HEX", null); - r(m, "BIN2OCT", null); - r(m, "COMPLEX", Complex.instance); - r(m, "CONVERT", null); - r(m, "COUNTIFS", null); - r(m, "COUPDAYBS", null); - r(m, "COUPDAYS", null); - r(m, "COUPDAYSNC", null); - r(m, "COUPNCD", null); - r(m, "COUPNUM", null); - r(m, "COUPPCD", null); - r(m, "CUBEKPIMEMBER", null); - r(m, "CUBEMEMBER", null); - r(m, "CUBEMEMBERPROPERTY", null); - r(m, "CUBERANKEDMEMBER", null); - r(m, "CUBESET", null); - r(m, "CUBESETCOUNT", null); - r(m, "CUBEVALUE", null); - r(m, "CUMIPMT", null); - r(m, "CUMPRINC", null); - r(m, "DEC2BIN", Dec2Bin.instance); - r(m, "DEC2HEX", Dec2Hex.instance); - r(m, "DEC2OCT", null); - r(m, "DELTA", Delta.instance); - r(m, "DISC", null); - r(m, "DOLLARDE", null); - r(m, "DOLLARFR", null); - r(m, "DURATION", null); - r(m, "EDATE", EDate.instance); - r(m, "EFFECT", null); - r(m, "EOMONTH", EOMonth.instance); - r(m, "ERF", null); - r(m, "ERFC", null); - r(m, "FACTDOUBLE", FactDouble.instance); - r(m, "FVSCHEDULE", null); - r(m, "GCD", null); - r(m, "GESTEP", null); - r(m, "HEX2BIN", null); - r(m, "HEX2DEC", Hex2Dec.instance); - r(m, "HEX2OCT", null); - r(m, "IFERROR", IfError.instance); - r(m, "IMABS", null); - r(m, "IMAGINARY", Imaginary.instance); - r(m, "IMARGUMENT", null); - r(m, "IMCONJUGATE", null); - r(m, "IMCOS", null); - r(m, "IMDIV", null); - r(m, "IMEXP", null); - r(m, "IMLN", null); - r(m, "IMLOG10", null); - r(m, "IMLOG2", null); - r(m, "IMPOWER", null); - r(m, "IMPRODUCT", null); - r(m, "IMREAL", ImReal.instance); - r(m, "IMSIN", null); - r(m, "IMSQRT", null); - r(m, "IMSUB", null); - r(m, "IMSUM", null); - r(m, "INTRATE", null); - r(m, "ISEVEN", ParityFunction.IS_EVEN); - r(m, "ISODD", ParityFunction.IS_ODD); - r(m, "JIS", null); - r(m, "LCM", null); - r(m, "MDURATION", null); - r(m, "MROUND", MRound.instance); - r(m, "MULTINOMIAL", null); - r(m, "NETWORKDAYS", NetworkdaysFunction.instance); - r(m, "NOMINAL", null); - r(m, "OCT2BIN", null); - r(m, "OCT2DEC", Oct2Dec.instance); - r(m, "OCT2HEX", null); - r(m, "ODDFPRICE", null); - r(m, "ODDFYIELD", null); - r(m, "ODDLPRICE", null); - r(m, "ODDLYIELD", null); - r(m, "PRICE", null); - r(m, "PRICEDISC", null); - r(m, "PRICEMAT", null); - r(m, "QUOTIENT", Quotient.instance); - r(m, "RANDBETWEEN", RandBetween.instance); - r(m, "RECEIVED", null); - r(m, "RTD", null); - r(m, "SERIESSUM", null); - r(m, "SQRTPI", null); - r(m, "SUMIFS", Sumifs.instance); - r(m, "TBILLEQ", null); - r(m, "TBILLPRICE", null); - r(m, "TBILLYIELD", null); - r(m, "WEEKNUM", WeekNum.instance); - r(m, "WORKDAY", WorkdayFunction.instance); - r(m, "XIRR", null); - r(m, "XNPV", null); - r(m, "YEARFRAC", YearFrac.instance); - r(m, "YIELD", null); - r(m, "YIELDDISC", null); - r(m, "YIELDMAT", null); - r(m, "COUNTIFS", Countifs.instance); - - return m; - } - - private static void r(Map m, String functionName, FreeRefFunction pFunc) { - FreeRefFunction func = pFunc == null ? new NotImplemented(functionName) : pFunc; - m.put(functionName, func); - } - - public static boolean isATPFunction(String name){ - AnalysisToolPak inst = (AnalysisToolPak)instance; - // FIXME: inconsistent case-sensitivity - return inst._functionsByName.containsKey(name); - } - - /** - * Returns a collection of ATP function names implemented by POI. - * - * @return an array of supported functions - * @since 3.8 beta6 - */ - public static Collection getSupportedFunctionNames(){ - AnalysisToolPak inst = (AnalysisToolPak)instance; - Collection lst = new TreeSet(); - for(Map.Entry me : inst._functionsByName.entrySet()){ - FreeRefFunction func = me.getValue(); - if(func != null && !(func instanceof NotImplemented)){ - lst.add(me.getKey()); - } - } - return Collections.unmodifiableCollection(lst); - } - - /** - * Returns a collection of ATP function names NOT implemented by POI. - * - * @return an array of not supported functions - * @since 3.8 beta6 - */ - public static Collection getNotSupportedFunctionNames(){ - AnalysisToolPak inst = (AnalysisToolPak)instance; - Collection lst = new TreeSet(); - for(Map.Entry me : inst._functionsByName.entrySet()){ - FreeRefFunction func = me.getValue(); - if (func instanceof NotImplemented) { - lst.add(me.getKey()); - } - } - return Collections.unmodifiableCollection(lst); - } - - /** - * Register a ATP function in runtime. - * - * @param name the function name - * @param func the functoin to register - * @throws IllegalArgumentException if the function is unknown or already registered. - * @since 3.8 beta6 - */ - public static void registerFunction(String name, FreeRefFunction func){ - AnalysisToolPak inst = (AnalysisToolPak)instance; - if(!isATPFunction(name)) { - FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByName(name); - if(metaData != null) { - throw new IllegalArgumentException(name + " is a built-in Excel function. " + - "Use FunctoinEval.registerFunction(String name, Function func) instead."); - } - - throw new IllegalArgumentException(name + " is not a function from the Excel Analysis Toolpack."); - } - FreeRefFunction f = inst.findFunction(name); - if(f != null && !(f instanceof NotImplemented)) { - throw new IllegalArgumentException("POI already implememts " + name + - ". You cannot override POI's implementations of Excel functions"); - } - - // FIXME: inconsistent case-sensitivity - inst._functionsByName.put(name, func); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/ArgumentsEvaluator.java b/trunk/src/java/org/apache/poi/ss/formula/atp/ArgumentsEvaluator.java deleted file mode 100644 index fa5d50aee..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/ArgumentsEvaluator.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; - -import org.apache.poi.ss.formula.eval.AreaEvalBase; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; - -/** - * Evaluator for formula arguments. - * - * @author jfaenomoto@gmail.com - */ -final class ArgumentsEvaluator { - - public static final ArgumentsEvaluator instance = new ArgumentsEvaluator(); - - private ArgumentsEvaluator() { - // enforces singleton - } - - /** - * Evaluate a generic {@link ValueEval} argument to a double value that represents a date in POI. - * - * @param arg {@link ValueEval} an argument. - * @param srcCellRow number cell row. - * @param srcCellCol number cell column. - * @return a double representing a date in POI. - * @throws EvaluationException exception upon argument evaluation. - */ - public double evaluateDateArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol); - - if (ve instanceof StringEval) { - String strVal = ((StringEval) ve).getStringValue(); - Double dVal = OperandResolver.parseDouble(strVal); - if (dVal != null) { - return dVal.doubleValue(); - } - Calendar date = DateParser.parseDate(strVal); - return DateUtil.getExcelDate(date, false); - } - return OperandResolver.coerceValueToDouble(ve); - } - - /** - * Evaluate a generic {@link ValueEval} argument to an array of double values that represents dates in POI. - * - * @param arg {@link ValueEval} an argument. - * @param srcCellRow number cell row. - * @param srcCellCol number cell column. - * @return an array of doubles representing dates in POI. - * @throws EvaluationException exception upon argument evaluation. - */ - public double[] evaluateDatesArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - if (arg == null) { - return new double[0]; - } - - if (arg instanceof StringEval) { - return new double[]{ evaluateDateArg(arg, srcCellRow, srcCellCol) }; - } else if (arg instanceof AreaEvalBase) { - List valuesList = new ArrayList(); - AreaEvalBase area = (AreaEvalBase) arg; - for (int i = area.getFirstRow(); i <= area.getLastRow(); i++) { - for (int j = area.getFirstColumn(); j <= area.getLastColumn(); j++) { - // getValue() is replaced with getAbsoluteValue() because loop variables i, j are - // absolute indexes values, but getValue() works with relative indexes values - valuesList.add(evaluateDateArg(area.getAbsoluteValue(i, j), i, j)); - } - } - double[] values = new double[valuesList.size()]; - for (int i = 0; i < valuesList.size(); i++) { - values[i] = valuesList.get(i).doubleValue(); - } - return values; - } - return new double[]{ OperandResolver.coerceValueToDouble(arg) }; - } - - /** - * Evaluate a generic {@link ValueEval} argument to a double value. - * - * @param arg {@link ValueEval} an argument. - * @param srcCellRow number cell row. - * @param srcCellCol number cell column. - * @return a double value. - * @throws EvaluationException exception upon argument evaluation. - */ - public double evaluateNumberArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - if (arg == null) { - return 0f; - } - - return OperandResolver.coerceValueToDouble(arg); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/DateParser.java b/trunk/src/java/org/apache/poi/ss/formula/atp/DateParser.java deleted file mode 100644 index 1cb25527b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/DateParser.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import java.util.Calendar; -import java.util.regex.Pattern; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.util.LocaleUtil; - -/** - * Parser for java dates. - */ -public class DateParser { - private DateParser() { - // enforcing singleton - } - - /** - * Parses a date from a string. - * - * @param strVal a string with a date pattern. - * @return a date parsed from argument. - * @throws EvaluationException exception upon parsing. - */ - public static Calendar parseDate(String strVal) throws EvaluationException { - String[] parts = Pattern.compile("/").split(strVal); - if (parts.length != 3) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - String part2 = parts[2]; - int spacePos = part2.indexOf(' '); - if (spacePos > 0) { - // drop time portion if present - part2 = part2.substring(0, spacePos); - } - int f0; - int f1; - int f2; - try { - f0 = Integer.parseInt(parts[0]); - f1 = Integer.parseInt(parts[1]); - f2 = Integer.parseInt(part2); - } catch (NumberFormatException e) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - if (f0 < 0 || f1 < 0 || f2 < 0 || (f0 > 12 && f1 > 12 && f2 > 12)) { - // easy to see this cannot be a valid date - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - - if (f0 >= 1900 && f0 < 9999) { - // when 4 digit value appears first, the format is YYYY/MM/DD, regardless of OS settings - return makeDate(f0, f1, f2); - } - // otherwise the format seems to depend on OS settings (default date format) -// if (false) { -// // MM/DD/YYYY is probably a good guess, if the in the US -// return makeDate(f2, f0, f1); -// } - // TODO - find a way to choose the correct date format - throw new RuntimeException("Unable to determine date format for text '" + strVal + "'"); - } - - /** - * @param month 1-based - */ - private static Calendar makeDate(int year, int month, int day) throws EvaluationException { - if (month < 1 || month > 12) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - Calendar cal = LocaleUtil.getLocaleCalendar(year, month - 1, 1, 0, 0, 0); - if (day < 1 || day > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - cal.set(Calendar.DAY_OF_MONTH, day); - return cal; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/IfError.java b/trunk/src/java/org/apache/poi/ss/formula/atp/IfError.java deleted file mode 100644 index d3a22661b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/IfError.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -/** - * Implementation of 'Analysis Toolpak' Excel function IFERROR()
        - * - * Returns an error text if there is an error in the evaluation

        - * - * Syntax
        - * IFERROR(expression, string) - * - * @author Johan Karlsteen - */ -final class IfError implements FreeRefFunction { - - public static final FreeRefFunction instance = new IfError(); - - private IfError() { - // enforce singleton - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - ValueEval val; - try { - val = evaluateInternal(args[0], args[1], ec.getRowIndex(), ec.getColumnIndex()); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return val; - } - - private static ValueEval evaluateInternal(ValueEval arg, ValueEval iferror, int srcCellRow, int srcCellCol) throws EvaluationException { - arg = WorkbookEvaluator.dereferenceResult(arg, srcCellRow, srcCellCol); - if(arg instanceof ErrorEval) { - return iferror; - } else { - return arg; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/MRound.java b/trunk/src/java/org/apache/poi/ss/formula/atp/MRound.java deleted file mode 100644 index 8ca8796ca..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/MRound.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.functions.NumericFunction; - -/** - * Implementation of Excel 'Analysis ToolPak' function MROUND()
        - * - * Returns a number rounded to the desired multiple.

        - * - * Syntax
        - * MROUND(number, multiple) - * - *

        - * - * @author Yegor Kozlov - */ -final class MRound implements FreeRefFunction { - - public static final FreeRefFunction instance = new MRound(); - - private MRound() { - // enforce singleton - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - double number, multiple, result; - - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - try { - number = OperandResolver.coerceValueToDouble(OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec.getColumnIndex())); - multiple = OperandResolver.coerceValueToDouble(OperandResolver.getSingleValue(args[1], ec.getRowIndex(), ec.getColumnIndex())); - - if( multiple == 0.0 ) { - result = 0.0; - } else { - if(number*multiple < 0) { - // Returns #NUM! because the number and the multiple have different signs - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - result = multiple * Math.round( number / multiple ); - } - NumericFunction.checkValue(result); - return new NumberEval(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/NetworkdaysFunction.java b/trunk/src/java/org/apache/poi/ss/formula/atp/NetworkdaysFunction.java deleted file mode 100644 index 95e054864..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/NetworkdaysFunction.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.ss.formula.atp; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; - -/** - * Implementation of Excel 'Analysis ToolPak' function NETWORKDAYS()
        - * Returns the number of workdays given a starting and an ending date, considering an interval of holidays. A workday is any non - * saturday/sunday date. - *

        - * Syntax
        - * NETWORKDAYS(startDate, endDate, holidays) - *

        - * - * @author jfaenomoto@gmail.com - */ -final class NetworkdaysFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new NetworkdaysFunction(ArgumentsEvaluator.instance); - - private ArgumentsEvaluator evaluator; - - /** - * Constructor. - * - * @param anEvaluator an injected {@link ArgumentsEvaluator}. - */ - private NetworkdaysFunction(ArgumentsEvaluator anEvaluator) { - // enforces singleton - this.evaluator = anEvaluator; - } - - /** - * Evaluate for NETWORKDAYS. Given two dates and a optional date or interval of holidays, determines how many working days are there - * between those dates. - * - * @return {@link ValueEval} for the number of days between two dates. - */ - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { // NOSONAR - if (args.length < 2 || args.length > 3) { - return ErrorEval.VALUE_INVALID; - } - - int srcCellRow = ec.getRowIndex(); - int srcCellCol = ec.getColumnIndex(); - - double start, end; - double[] holidays; - try { - start = this.evaluator.evaluateDateArg(args[0], srcCellRow, srcCellCol); - end = this.evaluator.evaluateDateArg(args[1], srcCellRow, srcCellCol); - if (start > end) { - return ErrorEval.NAME_INVALID; - } - ValueEval holidaysCell = args.length == 3 ? args[2] : null; - holidays = this.evaluator.evaluateDatesArg(holidaysCell, srcCellRow, srcCellCol); - return new NumberEval(WorkdayCalculator.instance.calculateWorkdays(start, end, holidays)); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/ParityFunction.java b/trunk/src/java/org/apache/poi/ss/formula/atp/ParityFunction.java deleted file mode 100644 index 04b5e9223..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/ParityFunction.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.OperationEvaluationContext; -/** - * Implementation of Excel 'Analysis ToolPak' function ISEVEN() ISODD()
        - * - * @author Josh Micich - */ -final class ParityFunction implements FreeRefFunction { - - public static final FreeRefFunction IS_EVEN = new ParityFunction(0); - public static final FreeRefFunction IS_ODD = new ParityFunction(1); - private final int _desiredParity; - - private ParityFunction(int desiredParity) { - _desiredParity = desiredParity; - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - - int val; - try { - val = evaluateArgParity(args[0], ec.getRowIndex(), ec.getColumnIndex()); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return BoolEval.valueOf(val == _desiredParity); - } - - private static int evaluateArgParity(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short)srcCellCol); - - double d = OperandResolver.coerceValueToDouble(ve); - if (d < 0) { - d = -d; - } - long v = (long) Math.floor(d); - return (int) (v & 0x0001); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/RandBetween.java b/trunk/src/java/org/apache/poi/ss/formula/atp/RandBetween.java deleted file mode 100644 index 4da7a53ef..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/RandBetween.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.atp; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.OperationEvaluationContext; - -/** - * Implementation of Excel 'Analysis ToolPak' function RANDBETWEEN()
        - * - * Returns a random integer number between the numbers you specify.

        - * - * Syntax
        - * RANDBETWEEN(bottom, top)

        - * - * bottom is the smallest integer RANDBETWEEN will return.
        - * top is the largest integer RANDBETWEEN will return.
        - - * @author Brendan Nolan - */ -final class RandBetween implements FreeRefFunction{ - - public static final FreeRefFunction instance = new RandBetween(); - - private RandBetween() { - //enforces singleton - } - - /** - * Evaluate for RANDBETWEEN(). Must be given two arguments. Bottom must be greater than top. - * Bottom is rounded up and top value is rounded down. After rounding top has to be set greater - * than top. - * - * @see org.apache.poi.ss.formula.functions.FreeRefFunction#evaluate(org.apache.poi.ss.formula.eval.ValueEval[], org.apache.poi.ss.formula.OperationEvaluationContext) - */ - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - - double bottom, top; - - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - try { - bottom = OperandResolver.coerceValueToDouble(OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec.getColumnIndex())); - top = OperandResolver.coerceValueToDouble(OperandResolver.getSingleValue(args[1], ec.getRowIndex(), ec.getColumnIndex())); - if(bottom > top) { - return ErrorEval.NUM_ERROR; - } - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - bottom = Math.ceil(bottom); - top = Math.floor(top); - - if(bottom > top) { - top = bottom; - } - - return new NumberEval((bottom + (int)(Math.random() * ((top - bottom) + 1)))); - - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java b/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java deleted file mode 100644 index 29b29feaa..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java +++ /dev/null @@ -1,166 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - -/** - * A calculator for workdays, considering dates as excel representations. - */ -public class WorkdayCalculator { - public static final WorkdayCalculator instance = new WorkdayCalculator(); - - /** - * Constructor. - */ - private WorkdayCalculator() { - // enforcing singleton - } - - /** - * Calculate how many workdays are there between a start and an end date, as excel representations, considering a range of holidays. - * - * @param start start date. - * @param end end date. - * @param holidays an array of holidays. - * @return number of workdays between start and end dates, including both dates. - */ - public int calculateWorkdays(double start, double end, double[] holidays) { - int saturdaysPast = this.pastDaysOfWeek(start, end, Calendar.SATURDAY); - int sundaysPast = this.pastDaysOfWeek(start, end, Calendar.SUNDAY); - int nonWeekendHolidays = this.calculateNonWeekendHolidays(start, end, holidays); - return (int) (end - start + 1) - saturdaysPast - sundaysPast - nonWeekendHolidays; - } - - /** - * Calculate the workday past x workdays from a starting date, considering a range of holidays. - * - * @param start start date. - * @param workdays number of workdays to be past from starting date. - * @param holidays an array of holidays. - * @return date past x workdays. - */ - public Date calculateWorkdays(double start, int workdays, double[] holidays) { - Date startDate = DateUtil.getJavaDate(start); - int direction = workdays < 0 ? -1 : 1; - Calendar endDate = LocaleUtil.getLocaleCalendar(); - endDate.setTime(startDate); - double excelEndDate = DateUtil.getExcelDate(endDate.getTime()); - while (workdays != 0) { - endDate.add(Calendar.DAY_OF_YEAR, direction); - excelEndDate += direction; - if (endDate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY - && endDate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY - && !isHoliday(excelEndDate, holidays)) { - workdays -= direction; - } - } - return endDate.getTime(); - } - - /** - * Calculates how many days of week past between a start and an end date. - * - * @param start start date. - * @param end end date. - * @param dayOfWeek a day of week as represented by {@link Calendar} constants. - * @return how many days of week past in this interval. - */ - protected int pastDaysOfWeek(double start, double end, int dayOfWeek) { - int pastDaysOfWeek = 0; - int startDay = (int) Math.floor(start < end ? start : end); - int endDay = (int) Math.floor(end > start ? end : start); - for (; startDay <= endDay; startDay++) { - Calendar today = LocaleUtil.getLocaleCalendar(); - today.setTime(DateUtil.getJavaDate(startDay)); - if (today.get(Calendar.DAY_OF_WEEK) == dayOfWeek) { - pastDaysOfWeek++; - } - } - return start < end ? pastDaysOfWeek : -pastDaysOfWeek; - } - - /** - * Calculates how many holidays in a list are workdays, considering an interval of dates. - * - * @param start start date. - * @param end end date. - * @param holidays an array of holidays. - * @return number of holidays that occur in workdays, between start and end dates. - */ - protected int calculateNonWeekendHolidays(double start, double end, double[] holidays) { - int nonWeekendHolidays = 0; - double startDay = start < end ? start : end; - double endDay = end > start ? end : start; - for (int i = 0; i < holidays.length; i++) { - if (isInARange(startDay, endDay, holidays[i])) { - if (!isWeekend(holidays[i])) { - nonWeekendHolidays++; - } - } - } - return start < end ? nonWeekendHolidays : -nonWeekendHolidays; - } - - /** - * @param aDate a given date. - * @return true if date is weekend, false otherwise. - */ - protected boolean isWeekend(double aDate) { - Calendar date = LocaleUtil.getLocaleCalendar(); - date.setTime(DateUtil.getJavaDate(aDate)); - return date.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || date.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY; - } - - /** - * @param aDate a given date. - * @param holidays an array of holidays. - * @return true if date is a holiday, false otherwise. - */ - protected boolean isHoliday(double aDate, double[] holidays) { - for (int i = 0; i < holidays.length; i++) { - if (Math.round(holidays[i]) == Math.round(aDate)) { - return true; - } - } - return false; - } - - /** - * @param aDate a given date. - * @param holidays an array of holidays. - * @return 1 is not a workday, 0 otherwise. - */ - protected int isNonWorkday(double aDate, double[] holidays) { - return isWeekend(aDate) || isHoliday(aDate, holidays) ? 1 : 0; - } - - /** - * @param start start date. - * @param end end date. - * @param aDate a date to be analyzed. - * @return true if aDate is between start and end dates, false otherwise. - */ - protected boolean isInARange(double start, double end, double aDate) { - return aDate >= start && aDate <= end; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java b/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java deleted file mode 100644 index e746bd139..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.usermodel.DateUtil; - -/** - * Implementation of Excel 'Analysis ToolPak' function WORKDAY()
        - * Returns the date past a number of workdays beginning at a start date, considering an interval of holidays. A workday is any non - * saturday/sunday date. - *

        - * Syntax
        - * WORKDAY(startDate, days, holidays) - *

        - * - * @author jfaenomoto@gmail.com - */ -final class WorkdayFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new WorkdayFunction(ArgumentsEvaluator.instance); - - private ArgumentsEvaluator evaluator; - - private WorkdayFunction(ArgumentsEvaluator anEvaluator) { - // enforces singleton - this.evaluator = anEvaluator; - } - - /** - * Evaluate for WORKDAY. Given a date, a number of days and a optional date or interval of holidays, determines which date it is past - * number of parametrized workdays. - * - * @return {@link ValueEval} with date as its value. - */ - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length < 2 || args.length > 3) { - return ErrorEval.VALUE_INVALID; - } - - int srcCellRow = ec.getRowIndex(); - int srcCellCol = ec.getColumnIndex(); - - double start; - int days; - double[] holidays; - try { - start = this.evaluator.evaluateDateArg(args[0], srcCellRow, srcCellCol); - days = (int) Math.floor(this.evaluator.evaluateNumberArg(args[1], srcCellRow, srcCellCol)); - ValueEval holidaysCell = args.length == 3 ? args[2] : null; - holidays = this.evaluator.evaluateDatesArg(holidaysCell, srcCellRow, srcCellCol); - return new NumberEval(DateUtil.getExcelDate(WorkdayCalculator.instance.calculateWorkdays(start, days, holidays))); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/YearFrac.java b/trunk/src/java/org/apache/poi/ss/formula/atp/YearFrac.java deleted file mode 100644 index a44645f61..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/YearFrac.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.usermodel.DateUtil; -/** - * Implementation of Excel 'Analysis ToolPak' function YEARFRAC()
        - * - * Returns the fraction of the year spanned by two dates.

        - * - * Syntax
        - * YEARFRAC(startDate, endDate, basis)

        - * - * The basis optionally specifies the behaviour of YEARFRAC as follows: - * - * - * - * - * - * - * - * - *
        ValueDays per MonthDays per Year
        0 (default)30360
        1actualactual
        2actual360
        3actual365
        430360
        - * - */ -final class YearFrac implements FreeRefFunction { - - public static final FreeRefFunction instance = new YearFrac(); - - private YearFrac() { - // enforce singleton - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - int srcCellRow = ec.getRowIndex(); - int srcCellCol = ec.getColumnIndex(); - double result; - try { - int basis = 0; // default - switch(args.length) { - case 3: - basis = evaluateIntArg(args[2], srcCellRow, srcCellCol); - // fall through - case 2: - break; - default: - return ErrorEval.VALUE_INVALID; - } - double startDateVal = evaluateDateArg(args[0], srcCellRow, srcCellCol); - double endDateVal = evaluateDateArg(args[1], srcCellRow, srcCellCol); - result = YearFracCalculator.calculate(startDateVal, endDateVal, basis); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return new NumberEval(result); - } - - private static double evaluateDateArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol); - - if (ve instanceof StringEval) { - String strVal = ((StringEval) ve).getStringValue(); - Double dVal = OperandResolver.parseDouble(strVal); - if (dVal != null) { - return dVal.doubleValue(); - } - Calendar date = DateParser.parseDate(strVal); - return DateUtil.getExcelDate(date, false); - } - return OperandResolver.coerceValueToDouble(ve); - } - - private static int evaluateIntArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol); - return OperandResolver.coerceValueToInt(ve); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java b/trunk/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java deleted file mode 100644 index 42bd9aed1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java +++ /dev/null @@ -1,342 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.atp; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - - -/** - * Internal calculation methods for Excel 'Analysis ToolPak' function YEARFRAC()
        - * - * Algorithm inspired by www.dwheeler.com/yearfrac - * - * @author Josh Micich - */ -final class YearFracCalculator { - private static final int MS_PER_HOUR = 60 * 60 * 1000; - private static final int MS_PER_DAY = 24 * MS_PER_HOUR; - private static final int DAYS_PER_NORMAL_YEAR = 365; - private static final int DAYS_PER_LEAP_YEAR = DAYS_PER_NORMAL_YEAR + 1; - - /** the length of normal long months i.e. 31 */ - private static final int LONG_MONTH_LEN = 31; - /** the length of normal short months i.e. 30 */ - private static final int SHORT_MONTH_LEN = 30; - private static final int SHORT_FEB_LEN = 28; - private static final int LONG_FEB_LEN = SHORT_FEB_LEN + 1; - - private YearFracCalculator() { - // no instances of this class - } - - - public static double calculate(double pStartDateVal, double pEndDateVal, int basis) throws EvaluationException { - - if (basis < 0 || basis >= 5) { - // if basis is invalid the result is #NUM! - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - - // common logic for all bases - - // truncate day values - int startDateVal = (int) Math.floor(pStartDateVal); - int endDateVal = (int) Math.floor(pEndDateVal); - if (startDateVal == endDateVal) { - // when dates are equal, result is zero - return 0; - } - // swap start and end if out of order - if (startDateVal > endDateVal) { - int temp = startDateVal; - startDateVal = endDateVal; - endDateVal = temp; - } - - switch (basis) { - case 0: return basis0(startDateVal, endDateVal); - case 1: return basis1(startDateVal, endDateVal); - case 2: return basis2(startDateVal, endDateVal); - case 3: return basis3(startDateVal, endDateVal); - case 4: return basis4(startDateVal, endDateVal); - } - throw new IllegalStateException("cannot happen"); - } - - - /** - * @param startDateVal assumed to be less than or equal to endDateVal - * @param endDateVal assumed to be greater than or equal to startDateVal - */ - public static double basis0(int startDateVal, int endDateVal) { - SimpleDate startDate = createDate(startDateVal); - SimpleDate endDate = createDate(endDateVal); - int date1day = startDate.day; - int date2day = endDate.day; - - // basis zero has funny adjustments to the day-of-month fields when at end-of-month - if (date1day == LONG_MONTH_LEN && date2day == LONG_MONTH_LEN) { - date1day = SHORT_MONTH_LEN; - date2day = SHORT_MONTH_LEN; - } else if (date1day == LONG_MONTH_LEN) { - date1day = SHORT_MONTH_LEN; - } else if (date1day == SHORT_MONTH_LEN && date2day == LONG_MONTH_LEN) { - date2day = SHORT_MONTH_LEN; - // Note: If date2day==31, it STAYS 31 if date1day < 30. - // Special fixes for February: - } else if (startDate.month == 2 && isLastDayOfMonth(startDate)) { - // Note - these assignments deliberately set Feb 30 date. - date1day = SHORT_MONTH_LEN; - if (endDate.month == 2 && isLastDayOfMonth(endDate)) { - // only adjusted when first date is last day in Feb - date2day = SHORT_MONTH_LEN; - } - } - return calculateAdjusted(startDate, endDate, date1day, date2day); - } - /** - * @param startDateVal assumed to be less than or equal to endDateVal - * @param endDateVal assumed to be greater than or equal to startDateVal - */ - public static double basis1(int startDateVal, int endDateVal) { - SimpleDate startDate = createDate(startDateVal); - SimpleDate endDate = createDate(endDateVal); - double yearLength; - if (isGreaterThanOneYear(startDate, endDate)) { - yearLength = averageYearLength(startDate.year, endDate.year); - } else if (shouldCountFeb29(startDate, endDate)) { - yearLength = DAYS_PER_LEAP_YEAR; - } else { - yearLength = DAYS_PER_NORMAL_YEAR; - } - return dateDiff(startDate.tsMilliseconds, endDate.tsMilliseconds) / yearLength; - } - - /** - * @param startDateVal assumed to be less than or equal to endDateVal - * @param endDateVal assumed to be greater than or equal to startDateVal - */ - public static double basis2(int startDateVal, int endDateVal) { - return (endDateVal - startDateVal) / 360.0; - } - /** - * @param startDateVal assumed to be less than or equal to endDateVal - * @param endDateVal assumed to be greater than or equal to startDateVal - */ - public static double basis3(double startDateVal, double endDateVal) { - return (endDateVal - startDateVal) / 365.0; - } - /** - * @param startDateVal assumed to be less than or equal to endDateVal - * @param endDateVal assumed to be greater than or equal to startDateVal - */ - public static double basis4(int startDateVal, int endDateVal) { - SimpleDate startDate = createDate(startDateVal); - SimpleDate endDate = createDate(endDateVal); - int date1day = startDate.day; - int date2day = endDate.day; - - - // basis four has funny adjustments to the day-of-month fields when at end-of-month - if (date1day == LONG_MONTH_LEN) { - date1day = SHORT_MONTH_LEN; - } - if (date2day == LONG_MONTH_LEN) { - date2day = SHORT_MONTH_LEN; - } - // Note - no adjustments for end of Feb - return calculateAdjusted(startDate, endDate, date1day, date2day); - } - - - private static double calculateAdjusted(SimpleDate startDate, SimpleDate endDate, int date1day, - int date2day) { - double dayCount - = (endDate.year - startDate.year) * 360 - + (endDate.month - startDate.month) * SHORT_MONTH_LEN - + (date2day - date1day) * 1; - return dayCount / 360; - } - - private static boolean isLastDayOfMonth(SimpleDate date) { - if (date.day < SHORT_FEB_LEN) { - return false; - } - return date.day == getLastDayOfMonth(date); - } - - private static int getLastDayOfMonth(SimpleDate date) { - switch (date.month) { - case 1: - case 3: - case 5: - case 7: - case 8: - case 10: - case 12: - return LONG_MONTH_LEN; - case 4: - case 6: - case 9: - case 11: - return SHORT_MONTH_LEN; - } - if (isLeapYear(date.year)) { - return LONG_FEB_LEN; - } - return SHORT_FEB_LEN; - } - - /** - * Assumes dates are no more than 1 year apart. - * @return true if dates both within a leap year, or span a period including Feb 29 - */ - private static boolean shouldCountFeb29(SimpleDate start, SimpleDate end) { - boolean startIsLeapYear = isLeapYear(start.year); - if (startIsLeapYear && start.year == end.year) { - // note - dates may not actually span Feb-29, but it gets counted anyway in this case - return true; - } - - boolean endIsLeapYear = isLeapYear(end.year); - if (!startIsLeapYear && !endIsLeapYear) { - return false; - } - if (startIsLeapYear) { - switch (start.month) { - case SimpleDate.JANUARY: - case SimpleDate.FEBRUARY: - return true; - } - return false; - } - if (endIsLeapYear) { - switch (end.month) { - case SimpleDate.JANUARY: - return false; - case SimpleDate.FEBRUARY: - break; - default: - return true; - } - return end.day == LONG_FEB_LEN; - } - return false; - } - - /** - * @return the whole number of days between the two time-stamps. Both time-stamps are - * assumed to represent 12:00 midnight on the respective day. - */ - private static int dateDiff(long startDateMS, long endDateMS) { - long msDiff = endDateMS - startDateMS; - - // some extra checks to make sure we don't hide some other bug with the rounding - int remainderHours = (int) ((msDiff % MS_PER_DAY) / MS_PER_HOUR); - switch (remainderHours) { - case 0: // normal case - break; - case 1: // transition from normal time to daylight savings adjusted - case 23: // transition from daylight savings adjusted to normal time - // Unexpected since we are using UTC_TIME_ZONE - default: - throw new RuntimeException("Unexpected date diff between " + startDateMS + " and " + endDateMS); - - } - return (int) (0.5 + ((double)msDiff / MS_PER_DAY)); - } - - private static double averageYearLength(int startYear, int endYear) { - int dayCount = 0; - for (int i=startYear; i<=endYear; i++) { - dayCount += DAYS_PER_NORMAL_YEAR; - if (isLeapYear(i)) { - dayCount++; - } - } - double numberOfYears = endYear-startYear+1; - return dayCount / numberOfYears; - } - - private static boolean isLeapYear(int i) { - // leap years are always divisible by 4 - if (i % 4 != 0) { - return false; - } - // each 4th century is a leap year - if (i % 400 == 0) { - return true; - } - // all other centuries are *not* leap years - if (i % 100 == 0) { - return false; - } - return true; - } - - private static boolean isGreaterThanOneYear(SimpleDate start, SimpleDate end) { - if (start.year == end.year) { - return false; - } - if (start.year + 1 != end.year) { - return true; - } - - if (start.month > end.month) { - return false; - } - if (start.month < end.month) { - return true; - } - - return start.day < end.day; - } - - private static SimpleDate createDate(int dayCount) { - /** use UTC time-zone to avoid daylight savings issues */ - Calendar cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); - DateUtil.setCalendar(cal, dayCount, 0, false, false); - return new SimpleDate(cal); - } - - private static final class SimpleDate { - - public static final int JANUARY = 1; - public static final int FEBRUARY = 2; - - public final int year; - /** 1-based month */ - public final int month; - /** day of month */ - public final int day; - /** milliseconds since 1970 */ - public long tsMilliseconds; - - public SimpleDate(Calendar cal) { - year = cal.get(Calendar.YEAR); - month = cal.get(Calendar.MONTH) + 1; - day = cal.get(Calendar.DAY_OF_MONTH); - tsMilliseconds = cal.getTimeInMillis(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java b/trunk/src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java deleted file mode 100644 index aa5016bc2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.constant; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * To support Constant Values (2.5.7) as required by the CRN record. - * This class is also used for two dimensional arrays which are encoded by - * EXTERNALNAME (5.39) records and Array tokens.

        - * - * @author Josh Micich - */ -public final class ConstantValueParser { - // note - these (non-combinable) enum values are sparse. - private static final int TYPE_EMPTY = 0; - private static final int TYPE_NUMBER = 1; - private static final int TYPE_STRING = 2; - private static final int TYPE_BOOLEAN = 4; - private static final int TYPE_ERROR_CODE = 16; // TODO - update OOO document to include this value - - private static final int TRUE_ENCODING = 1; - private static final int FALSE_ENCODING = 0; - - // TODO - is this the best way to represent 'EMPTY'? - private static final Object EMPTY_REPRESENTATION = null; - - private ConstantValueParser() { - // no instances of this class - } - - public static Object[] parse(LittleEndianInput in, int nValues) { - Object[] result = new Object[nValues]; - for (int i = 0; i < result.length; i++) { - result[i] = readAConstantValue(in); - } - return result; - } - - private static Object readAConstantValue(LittleEndianInput in) { - byte grbit = in.readByte(); - switch(grbit) { - case TYPE_EMPTY: - in.readLong(); // 8 byte 'not used' field - return EMPTY_REPRESENTATION; - case TYPE_NUMBER: - return new Double(in.readDouble()); - case TYPE_STRING: - return StringUtil.readUnicodeString(in); - case TYPE_BOOLEAN: - return readBoolean(in); - case TYPE_ERROR_CODE: - int errCode = in.readUShort(); - // next 6 bytes are unused - in.readUShort(); - in.readInt(); - return ErrorConstant.valueOf(errCode); - } - throw new RuntimeException("Unknown grbit value (" + grbit + ")"); - } - - private static Object readBoolean(LittleEndianInput in) { - byte val = (byte)in.readLong(); // 7 bytes 'not used' - switch(val) { - case FALSE_ENCODING: - return Boolean.FALSE; - case TRUE_ENCODING: - return Boolean.TRUE; - } - // Don't tolerate unusual boolean encoded values (unless it becomes evident that they occur) - throw new RuntimeException("unexpected boolean encoding (" + val + ")"); - } - - public static int getEncodedSize(Object[] values) { - // start with one byte 'type' code for each value - int result = values.length * 1; - for (int i = 0; i < values.length; i++) { - result += getEncodedSize(values[i]); - } - return result; - } - - /** - * @return encoded size without the 'type' code byte - */ - private static int getEncodedSize(Object object) { - if(object == EMPTY_REPRESENTATION) { - return 8; - } - Class cls = object.getClass(); - - if(cls == Boolean.class || cls == Double.class || cls == ErrorConstant.class) { - return 8; - } - String strVal = (String)object; - return StringUtil.getEncodedSize(strVal); - } - - public static void encode(LittleEndianOutput out, Object[] values) { - for (int i = 0; i < values.length; i++) { - encodeSingleValue(out, values[i]); - } - } - - private static void encodeSingleValue(LittleEndianOutput out, Object value) { - if (value == EMPTY_REPRESENTATION) { - out.writeByte(TYPE_EMPTY); - out.writeLong(0L); - return; - } - if (value instanceof Boolean) { - Boolean bVal = ((Boolean)value); - out.writeByte(TYPE_BOOLEAN); - long longVal = bVal.booleanValue() ? 1L : 0L; - out.writeLong(longVal); - return; - } - if (value instanceof Double) { - Double dVal = (Double) value; - out.writeByte(TYPE_NUMBER); - out.writeDouble(dVal.doubleValue()); - return; - } - if (value instanceof String) { - String val = (String) value; - out.writeByte(TYPE_STRING); - StringUtil.writeUnicodeString(out, val); - return; - } - if (value instanceof ErrorConstant) { - ErrorConstant ecVal = (ErrorConstant) value; - out.writeByte(TYPE_ERROR_CODE); - long longVal = ecVal.getErrorCode(); - out.writeLong(longVal); - return; - } - - throw new IllegalStateException("Unexpected value type (" + value.getClass().getName() + "'"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java b/trunk/src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java deleted file mode 100644 index 9d3c898b3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.constant; - -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -/** - * Represents a constant error code value as encoded in a constant values array.

        - * - * This class is a type-safe wrapper for a 16-bit int value performing a similar job to - * ErrorEval. - */ -public class ErrorConstant { - private static final POILogger logger = POILogFactory.getLogger(ErrorConstant.class); - private static final ErrorConstant NULL = new ErrorConstant(FormulaError.NULL.getCode()); - private static final ErrorConstant DIV_0 = new ErrorConstant(FormulaError.DIV0.getCode()); - private static final ErrorConstant VALUE = new ErrorConstant(FormulaError.VALUE.getCode()); - private static final ErrorConstant REF = new ErrorConstant(FormulaError.REF.getCode()); - private static final ErrorConstant NAME = new ErrorConstant(FormulaError.NAME.getCode()); - private static final ErrorConstant NUM = new ErrorConstant(FormulaError.NUM.getCode()); - private static final ErrorConstant NA = new ErrorConstant(FormulaError.NA.getCode()); - - private final int _errorCode; - - private ErrorConstant(int errorCode) { - _errorCode = errorCode; - } - - public int getErrorCode() { - return _errorCode; - } - - public String getText() { - if(FormulaError.isValidCode(_errorCode)) { - return FormulaError.forInt(_errorCode).getString(); - } - return "unknown error code (" + _errorCode + ")"; - } - - public static ErrorConstant valueOf(int errorCode) { - if (FormulaError.isValidCode(errorCode)) { - switch (FormulaError.forInt(errorCode)) { - case NULL: return NULL; - case DIV0: return DIV_0; - case VALUE: return VALUE; - case REF: return REF; - case NAME: return NAME; - case NUM: return NUM; - case NA: return NA; - default: break; - } - } - logger.log( POILogger.WARN, "Warning - unexpected error code (" + errorCode + ")"); - return new ErrorConstant(errorCode); - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(getText()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/AreaEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/AreaEval.java deleted file mode 100644 index c2ce41168..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/AreaEval.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.ThreeDEval; -import org.apache.poi.ss.formula.TwoDEval; -/** - * Evaluation of 2D (Row+Column) and 3D (Sheet+Row+Column) areas - */ -public interface AreaEval extends TwoDEval, ThreeDEval { - - /** - * returns the 0-based index of the first row in - * this area. - */ - int getFirstRow(); - - /** - * returns the 0-based index of the last row in - * this area. - */ - int getLastRow(); - - /** - * returns the 0-based index of the first col in - * this area. - */ - int getFirstColumn(); - - /** - * returns the 0-based index of the last col in - * this area. - */ - int getLastColumn(); - - /** - * @return the ValueEval from within this area at the specified row and col index. Never - * null (possibly {@link BlankEval}). The specified indexes should be absolute - * indexes in the sheet and not relative indexes within the area. - */ - ValueEval getAbsoluteValue(int row, int col); - - /** - * returns true if the cell at row and col specified - * as absolute indexes in the sheet is contained in - * this area. - * @param row - * @param col - */ - boolean contains(int row, int col); - - /** - * returns true if the specified col is in range - * @param col - */ - boolean containsColumn(int col); - - /** - * returns true if the specified row is in range - * @param row - */ - boolean containsRow(int row); - - int getWidth(); - int getHeight(); - /** - * @return the ValueEval from within this area at the specified relativeRowIndex and - * relativeColumnIndex. Never null (possibly {@link BlankEval}). The - * specified indexes should relative to the top left corner of this area. - */ - ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex); - - /** - * Creates an {@link AreaEval} offset by a relative amount from from the upper left cell - * of this area - */ - AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java b/trunk/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java deleted file mode 100644 index edb8af7a1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.SheetRange; -import org.apache.poi.ss.formula.ptg.AreaI; - -/** - * @author Josh Micich - */ -public abstract class AreaEvalBase implements AreaEval { - - private final int _firstSheet; - private final int _firstColumn; - private final int _firstRow; - private final int _lastSheet; - private final int _lastColumn; - private final int _lastRow; - private final int _nColumns; - private final int _nRows; - - protected AreaEvalBase(SheetRange sheets, int firstRow, int firstColumn, int lastRow, int lastColumn) { - _firstColumn = firstColumn; - _firstRow = firstRow; - _lastColumn = lastColumn; - _lastRow = lastRow; - - _nColumns = _lastColumn - _firstColumn + 1; - _nRows = _lastRow - _firstRow + 1; - - if (sheets != null) { - _firstSheet = sheets.getFirstSheetIndex(); - _lastSheet = sheets.getLastSheetIndex(); - } else { - _firstSheet = -1; - _lastSheet = -1; - } - } - protected AreaEvalBase(int firstRow, int firstColumn, int lastRow, int lastColumn) { - this(null, firstRow, firstColumn, lastRow, lastColumn); - } - - protected AreaEvalBase(AreaI ptg) { - this(ptg, null); - } - protected AreaEvalBase(AreaI ptg, SheetRange sheets) { - this(sheets, ptg.getFirstRow(), ptg.getFirstColumn(), ptg.getLastRow(), ptg.getLastColumn()); - } - - public final int getFirstColumn() { - return _firstColumn; - } - - public final int getFirstRow() { - return _firstRow; - } - - public final int getLastColumn() { - return _lastColumn; - } - - public final int getLastRow() { - return _lastRow; - } - - public int getFirstSheetIndex() { - return _firstSheet; - } - public int getLastSheetIndex() { - return _lastSheet; - } - - public final ValueEval getAbsoluteValue(int row, int col) { - int rowOffsetIx = row - _firstRow; - int colOffsetIx = col - _firstColumn; - - if(rowOffsetIx < 0 || rowOffsetIx >= _nRows) { - throw new IllegalArgumentException("Specified row index (" + row - + ") is outside the allowed range (" + _firstRow + ".." + _lastRow + ")"); - } - if(colOffsetIx < 0 || colOffsetIx >= _nColumns) { - throw new IllegalArgumentException("Specified column index (" + col - + ") is outside the allowed range (" + _firstColumn + ".." + col + ")"); - } - return getRelativeValue(rowOffsetIx, colOffsetIx); - } - - public final boolean contains(int row, int col) { - return _firstRow <= row && _lastRow >= row - && _firstColumn <= col && _lastColumn >= col; - } - - public final boolean containsRow(int row) { - return _firstRow <= row && _lastRow >= row; - } - - public final boolean containsColumn(int col) { - return _firstColumn <= col && _lastColumn >= col; - } - - public final boolean isColumn() { - return _firstColumn == _lastColumn; - } - - public final boolean isRow() { - return _firstRow == _lastRow; - } - public int getHeight() { - return _lastRow-_firstRow+1; - } - - public final ValueEval getValue(int row, int col) { - return getRelativeValue(row, col); - } - public final ValueEval getValue(int sheetIndex, int row, int col) { - return getRelativeValue(sheetIndex, row, col); - } - - public abstract ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex); - public abstract ValueEval getRelativeValue(int sheetIndex, int relativeRowIndex, int relativeColumnIndex); - - public int getWidth() { - return _lastColumn-_firstColumn+1; - } - - /** - * @return whether cell at rowIndex and columnIndex is a subtotal. - * By default return false which means 'don't care about subtotals' - */ - public boolean isSubTotal(int rowIndex, int columnIndex) { - return false; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/BlankEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/BlankEval.java deleted file mode 100644 index 845e7deaa..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/BlankEval.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > This class is a - * marker class. It is a special value for empty cells. - */ -public final class BlankEval implements ValueEval { - - public static final BlankEval instance = new BlankEval(); - - private BlankEval() { - // enforce singleton - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/BoolEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/BoolEval.java deleted file mode 100644 index cab4105d0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/BoolEval.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class BoolEval implements NumericValueEval, StringValueEval { - - private boolean _value; - - public static final BoolEval FALSE = new BoolEval(false); - - public static final BoolEval TRUE = new BoolEval(true); - - /** - * Convenience method for the following:
        - * (b ? BoolEval.TRUE : BoolEval.FALSE) - * - * @return the BoolEval instance representing b. - */ - public static final BoolEval valueOf(boolean b) { - return b ? TRUE : FALSE; - } - - private BoolEval(boolean value) { - _value = value; - } - - public boolean getBooleanValue() { - return _value; - } - - public double getNumberValue() { - return _value ? 1 : 0; - } - - public String getStringValue() { - return _value ? "TRUE" : "FALSE"; - } - - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(getClass().getName()).append(" ["); - sb.append(getStringValue()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/ConcatEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/ConcatEval.java deleted file mode 100644 index 5622be870..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/ConcatEval.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed2ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class ConcatEval extends Fixed2ArgFunction { - - public static final Function instance = new ConcatEval(); - - private ConcatEval() { - // enforce singleton - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - ValueEval ve0; - ValueEval ve1; - try { - ve0 = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - StringBuilder sb = new StringBuilder(); - sb.append(getText(ve0)); - sb.append(getText(ve1)); - return new StringEval(sb.toString()); - } - - private Object getText(ValueEval ve) { - if (ve instanceof StringValueEval) { - StringValueEval sve = (StringValueEval) ve; - return sve.getStringValue(); - } - if (ve == BlankEval.instance) { - return ""; - } - throw new IllegalAccessError("Unexpected value type (" - + ve.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java deleted file mode 100644 index 8e119ea03..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java +++ /dev/null @@ -1,98 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.poi.ss.formula.eval; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.usermodel.FormulaError; - -/** - * Evaluations for formula errors - */ -public final class ErrorEval implements ValueEval { - private static final Map evals = new HashMap(); - - /** #NULL! - Intersection of two cell ranges is empty */ - public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL); - /** #DIV/0! - Division by zero */ - public static final ErrorEval DIV_ZERO = new ErrorEval(FormulaError.DIV0); - /** #VALUE! - Wrong type of operand */ - public static final ErrorEval VALUE_INVALID = new ErrorEval(FormulaError.VALUE); - /** #REF! - Illegal or deleted cell reference */ - public static final ErrorEval REF_INVALID = new ErrorEval(FormulaError.REF); - /** #NAME? - Wrong function or range name */ - public static final ErrorEval NAME_INVALID = new ErrorEval(FormulaError.NAME); - /** #NUM! - Value range overflow */ - public static final ErrorEval NUM_ERROR = new ErrorEval(FormulaError.NUM); - /** #N/A - Argument or function not available */ - public static final ErrorEval NA = new ErrorEval(FormulaError.NA); - - // POI internal error codes - public static final ErrorEval FUNCTION_NOT_IMPLEMENTED = new ErrorEval(FormulaError.FUNCTION_NOT_IMPLEMENTED); - - // Note - Excel does not seem to represent this condition with an error code - public static final ErrorEval CIRCULAR_REF_ERROR = new ErrorEval(FormulaError.CIRCULAR_REF); - - /** - * Translates an Excel internal error code into the corresponding POI ErrorEval instance - * @param errorCode - */ - public static ErrorEval valueOf(int errorCode) { - FormulaError error = FormulaError.forInt(errorCode); - ErrorEval eval = evals.get(error); - if (eval != null) { - return eval; - } else { - throw new RuntimeException("Unhandled error type for code " + errorCode); - } - } - - /** - * Converts error codes to text. Handles non-standard error codes OK. - * For debug/test purposes (and for formatting error messages). - * @return the String representation of the specified Excel error code. - */ - public static String getText(int errorCode) { - if(FormulaError.isValidCode(errorCode)) { - return FormulaError.forInt(errorCode).getString(); - } - // Give a special string, based on ~, to make clear this isn't a standard Excel error - return "~non~std~err(" + errorCode + ")~"; - } - - private FormulaError _error; - private ErrorEval(FormulaError error) { - _error = error; - evals.put(error, this); - } - - public int getErrorCode() { - return _error.getLongCode(); - } - public String getErrorString() { - return _error.getString(); - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_error.getString()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/EvaluationException.java b/trunk/src/java/org/apache/poi/ss/formula/eval/EvaluationException.java deleted file mode 100644 index bb9d9574b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/EvaluationException.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -/** - * This class is used to simplify error handling logic within operator and function - * implementations. Note - OperationEval.evaluate() and Function.evaluate() - * method signatures do not throw this exception so it cannot propagate outside.

        - * - * Here is an example coded without EvaluationException, to show how it can help: - *

        - * public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
        - *	// ...
        - *	Eval arg0 = args[0];
        - *	if(arg0 instanceof ErrorEval) {
        - *		return arg0;
        - *	}
        - *	if(!(arg0 instanceof AreaEval)) {
        - *		return ErrorEval.VALUE_INVALID;
        - *	}
        - *	double temp = 0;
        - *	AreaEval area = (AreaEval)arg0;
        - *	ValueEval[] values = area.getValues();
        - *	for (int i = 0; i < values.length; i++) {
        - *		ValueEval ve = values[i];
        - *		if(ve instanceof ErrorEval) {
        - *			return ve;
        - *		}
        - *		if(!(ve instanceof NumericValueEval)) {
        - *			return ErrorEval.VALUE_INVALID;
        - *		}
        - *		temp += ((NumericValueEval)ve).getNumberValue();
        - *	}
        - *	// ...
        - * }	 
        - * 
        - * In this example, if any error is encountered while processing the arguments, an error is - * returned immediately. This code is difficult to refactor due to all the points where errors - * are returned.
        - * Using EvaluationException allows the error returning code to be consolidated to one - * place.

        - *

        - * public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
        - *	try {
        - *		// ...
        - *		AreaEval area = getAreaArg(args[0]);
        - *		double temp = sumValues(area.getValues());
        - *		// ...
        - *	} catch (EvaluationException e) {
        - *		return e.getErrorEval();
        - *	}
        - *}
        - *
        - *private static AreaEval getAreaArg(Eval arg0) throws EvaluationException {
        - *	if (arg0 instanceof ErrorEval) {
        - *		throw new EvaluationException((ErrorEval) arg0);
        - *	}
        - *	if (arg0 instanceof AreaEval) {
        - *		return (AreaEval) arg0;
        - *	}
        - *	throw EvaluationException.invalidValue();
        - *}
        - *
        - *private double sumValues(ValueEval[] values) throws EvaluationException {
        - *	double temp = 0;
        - *	for (int i = 0; i < values.length; i++) {
        - *		ValueEval ve = values[i];
        - *		if (ve instanceof ErrorEval) {
        - *			throw new EvaluationException((ErrorEval) ve);
        - *		}
        - *		if (!(ve instanceof NumericValueEval)) {
        - *			throw EvaluationException.invalidValue();
        - *		}
        - *		temp += ((NumericValueEval) ve).getNumberValue();
        - *	}
        - *	return temp;
        - *}
        - * 
        - * It is not mandatory to use EvaluationException, doing so might give the following advantages:
        - * - Methods can more easily be extracted, allowing for re-use.
        - * - Type management (typecasting etc) is simpler because error conditions have been separated from - * intermediate calculation values.
        - * - Fewer local variables are required. Local variables can have stronger types.
        - * - It is easier to mimic common Excel error handling behaviour (exit upon encountering first - * error), because exceptions conveniently propagate up the call stack regardless of execution - * points or the number of levels of nested calls.

        - * - * Note - Only standard evaluation errors are represented by EvaluationException ( - * i.e. conditions expected to be encountered when evaluating arbitrary Excel formulas). Conditions - * that could never occur in an Excel spreadsheet should result in runtime exceptions. Care should - * be taken to not translate any POI internal error into an Excel evaluation error code. - * - * @author Josh Micich - */ -public final class EvaluationException extends Exception { - private final ErrorEval _errorEval; - - public EvaluationException(ErrorEval errorEval) { - _errorEval = errorEval; - } - // some convenience factory methods - - /** #VALUE! - Wrong type of operand */ - public static EvaluationException invalidValue() { - return new EvaluationException(ErrorEval.VALUE_INVALID); - } - /** #REF! - Illegal or deleted cell reference */ - public static EvaluationException invalidRef() { - return new EvaluationException(ErrorEval.REF_INVALID); - } - /** #NUM! - Value range overflow */ - public static EvaluationException numberError() { - return new EvaluationException(ErrorEval.NUM_ERROR); - } - - public ErrorEval getErrorEval() { - return _errorEval; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/ExternalNameEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/ExternalNameEval.java deleted file mode 100644 index f65a3f83d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/ExternalNameEval.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.EvaluationName; - -/** - * Evaluation of a Name defined in a Sheet or Workbook scope - */ -public final class ExternalNameEval implements ValueEval { - private final EvaluationName _name; - - public ExternalNameEval(EvaluationName name) { - _name = name; - } - - public EvaluationName getName() { - return _name; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_name.getNameText()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java deleted file mode 100644 index d2a4d39ba..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java +++ /dev/null @@ -1,423 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import java.util.Collection; -import java.util.Collections; -import java.util.TreeSet; - -import org.apache.poi.ss.formula.atp.AnalysisToolPak; -import org.apache.poi.ss.formula.function.FunctionMetadata; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -import org.apache.poi.ss.formula.functions.*; - -/** - * Mappings from the Excel functions to our evaluation implementations - * (where available) - */ -public final class FunctionEval { - private FunctionEval() { - // no instances of this class - } - - /** - * Some function IDs that require special treatment - */ - private static final class FunctionID { - /** 1 */ - public static final int IF = FunctionMetadataRegistry.FUNCTION_INDEX_IF; - /** 4 */ - public static final int SUM = FunctionMetadataRegistry.FUNCTION_INDEX_SUM; - /** 78 */ - public static final int OFFSET = 78; - /** 100 */ - public static final int CHOOSE = FunctionMetadataRegistry.FUNCTION_INDEX_CHOOSE; - /** 148 */ - public static final int INDIRECT = FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT; - /** 255 */ - public static final int EXTERNAL_FUNC = FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL; - } - - /** - * Array elements corresponding to unimplemented functions are null - */ - protected static final Function[] functions = produceFunctions(); - - /** - * See Apache Open Office Excel File Format, - * Section 3.11 Built-In Sheet Functions - */ - private static Function[] produceFunctions() { - Function[] retval = new Function[368]; - - retval[0] = new Count(); - retval[FunctionID.IF] = new IfFunc(); //nominally 1 - retval[2] = LogicalFunction.ISNA; - retval[3] = LogicalFunction.ISERROR; - retval[FunctionID.SUM] = AggregateFunction.SUM; //nominally 4 - retval[5] = AggregateFunction.AVERAGE; - retval[6] = AggregateFunction.MIN; - retval[7] = AggregateFunction.MAX; - retval[8] = new RowFunc(); // ROW - retval[9] = new Column(); - retval[10] = new Na(); - retval[11] = new Npv(); - retval[12] = AggregateFunction.STDEV; - retval[13] = NumericFunction.DOLLAR; - retval[14] = new Fixed(); - retval[15] = NumericFunction.SIN; - retval[16] = NumericFunction.COS; - retval[17] = NumericFunction.TAN; - retval[18] = NumericFunction.ATAN; - retval[19] = NumericFunction.PI; - retval[20] = NumericFunction.SQRT; - retval[21] = NumericFunction.EXP; - retval[22] = NumericFunction.LN; - retval[23] = NumericFunction.LOG10; - retval[24] = NumericFunction.ABS; - retval[25] = NumericFunction.INT; - retval[26] = NumericFunction.SIGN; - retval[27] = NumericFunction.ROUND; - retval[28] = new Lookup(); - retval[29] = new Index(); - retval[30] = new Rept(); - retval[31] = TextFunction.MID; - retval[32] = TextFunction.LEN; - retval[33] = new Value(); - retval[34] = BooleanFunction.TRUE; - retval[35] = BooleanFunction.FALSE; - retval[36] = BooleanFunction.AND; - retval[37] = BooleanFunction.OR; - retval[38] = BooleanFunction.NOT; - retval[39] = NumericFunction.MOD; - // 40: DCOUNT - // 41: DSUM - // 42: DAVERAGE - retval[43] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DMIN); - // 44: DMAX - // 45: DSTDEV - retval[46] = AggregateFunction.VAR; - // 47: DVAR - retval[48] = TextFunction.TEXT; - // 49: LINEST - // 50: TREND - // 51: LOGEST - // 52: GROWTH - - retval[56] = FinanceFunction.PV; - retval[57] = FinanceFunction.FV; - retval[58] = FinanceFunction.NPER; - retval[59] = FinanceFunction.PMT; - retval[60] = new Rate(); - retval[61] = new Mirr(); - retval[62] = new Irr(); - retval[63] = NumericFunction.RAND; - retval[64] = new Match(); - retval[65] = DateFunc.instance; - retval[66] = new TimeFunc(); - retval[67] = CalendarFieldFunction.DAY; - retval[68] = CalendarFieldFunction.MONTH; - retval[69] = CalendarFieldFunction.YEAR; - retval[70] = WeekdayFunc.instance; - retval[71] = CalendarFieldFunction.HOUR; - retval[72] = CalendarFieldFunction.MINUTE; - retval[73] = CalendarFieldFunction.SECOND; - retval[74] = new Now(); - // 75: AREAS - retval[76] = new Rows(); - retval[77] = new Columns(); - retval[FunctionID.OFFSET] = new Offset(); //nominally 78 - - retval[82] = TextFunction.SEARCH; - // 83: TRANSPOSE - - // 86: TYPE - - retval[97] = NumericFunction.ATAN2; - retval[98] = NumericFunction.ASIN; - retval[99] = NumericFunction.ACOS; - retval[FunctionID.CHOOSE] = new Choose(); //nominally 100 - retval[101] = new Hlookup(); - retval[102] = new Vlookup(); - - retval[105] = LogicalFunction.ISREF; - - retval[109] = NumericFunction.LOG; - - retval[111] = TextFunction.CHAR; - retval[112] = TextFunction.LOWER; - retval[113] = TextFunction.UPPER; - retval[114] = TextFunction.PROPER; - retval[115] = TextFunction.LEFT; - retval[116] = TextFunction.RIGHT; - retval[117] = TextFunction.EXACT; - retval[118] = TextFunction.TRIM; - retval[119] = new Replace(); - retval[120] = new Substitute(); - retval[121] = new Code(); - - retval[124] = TextFunction.FIND; - - retval[126] = LogicalFunction.ISERR; - retval[127] = LogicalFunction.ISTEXT; - retval[128] = LogicalFunction.ISNUMBER; - retval[129] = LogicalFunction.ISBLANK; - retval[130] = new T(); - - retval[FunctionID.INDIRECT] = null; // Indirect.evaluate has different signature - - retval[162] = TextFunction.CLEAN; - - retval[167] = new IPMT(); - retval[168] = new PPMT(); - retval[169] = new Counta(); - - retval[183] = AggregateFunction.PRODUCT; - retval[184] = NumericFunction.FACT; - - retval[190] = LogicalFunction.ISNONTEXT; - - retval[194] = AggregateFunction.VARP; - - retval[197] = NumericFunction.TRUNC; - retval[198] = LogicalFunction.ISLOGICAL; - - //204: USDOLLAR (YEN in BIFF3) - //205: FINDB - //206: SEARCHB - //207: REPLACEB - //208: LEFTB - //209: RIGHTB - //210: MIDB - //211: LENB - retval[212] = NumericFunction.ROUNDUP; - retval[213] = NumericFunction.ROUNDDOWN; - //214: ASC - //215: DBCS (JIS in BIFF3) - retval[216] = new Rank(); - retval[219] = new Address(); - retval[220] = new Days360(); - retval[221] = new Today(); - //222: VBD - - retval[227] = AggregateFunction.MEDIAN; - retval[228] = new Sumproduct(); - retval[229] = NumericFunction.SINH; - retval[230] = NumericFunction.COSH; - retval[231] = NumericFunction.TANH; - retval[232] = NumericFunction.ASINH; - retval[233] = NumericFunction.ACOSH; - retval[234] = NumericFunction.ATANH; - retval[235] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DGET); - - // 244: INFO - - // 247: DB - - retval[FunctionID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeRefFunction, nominally 255 - - retval[261] = new Errortype(); - - retval[269] = AggregateFunction.AVEDEV; - // 270: BETADIST - // 271: GAMMALN - // 272: BETAINV - // 273: BINOMDIST - // 274: CHIDIST - // 275: CHIINV - retval[276] = NumericFunction.COMBIN; - // 277: CONFIDENCE - // 278:CRITBINOM - retval[279] = new Even(); - // 280: EXPONDIST - // 281: FDIST - // 282: FINV - // 283: FISHER - // 284: FISHERINV - retval[285] = NumericFunction.FLOOR; - // 286: GAMMADIST - // 287: GAMMAINV - retval[288] = NumericFunction.CEILING; - // 289: HYPGEOMDIST - // 290: LOGNORMDIST - // 291: LOGINV - // 292: NEGBINOMDIST - // 293: NORMDIST - // 294: NORMSDIST - // 295: NORMINV - // 296: NORMSINV - // 297: STANDARDIZE - retval[298] = new Odd(); - // 299: PERMUT - retval[300] = NumericFunction.POISSON; - // 301: TDIST - // 302: WEIBULL - retval[303] = new Sumxmy2(); - retval[304] = new Sumx2my2(); - retval[305] = new Sumx2py2(); - // 306: CHITEST - // 307: CORREL - // 308: COVAR - // 309: FORECAST - // 310: FTEST - retval[311] = new Intercept(); - // 312: PEARSON - // 313: RSQ - // 314: STEYX - retval[315] = new Slope(); - // 316: TTEST - // 317: PROB - retval[318] = AggregateFunction.DEVSQ; - // 319: GEOMEAN - // 320: HARMEAN - retval[321] = AggregateFunction.SUMSQ; - // 322: KURT - // 323: SKEW - // 324: ZTEST - retval[325] = AggregateFunction.LARGE; - retval[326] = AggregateFunction.SMALL; - // 327: QUARTILE - retval[328] = AggregateFunction.PERCENTILE; - // 329: PERCENTRANK - retval[330] = new Mode(); - // 331: TRIMMEAN - // 332: TINV - - retval[336] = TextFunction.CONCATENATE; - retval[337] = NumericFunction.POWER; - - retval[342] = NumericFunction.RADIANS; - retval[343] = NumericFunction.DEGREES; - retval[344] = new Subtotal(); - retval[345] = new Sumif(); - retval[346] = new Countif(); - retval[347] = new Countblank(); - - // 350: ISPMT - // 351: DATEDIF - // 352: DATESTRING - // 353: NUMBERSTRING - retval[354] = new Roman(); - - // 358: GETPIVOTDATA - retval[359] = new Hyperlink(); - // 360: PHONETIC - // 361: AVERAGEA - retval[362] = MinaMaxa.MAXA; - retval[363] = MinaMaxa.MINA; - // 364: STDEVPA - // 365: VARPA - // 366: STDEVA - // 367: VARA - - for (int i = 0; i < retval.length; i++) { - Function f = retval[i]; - if (f == null) { - FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(i); - if (fm == null) { - continue; - } - retval[i] = new NotImplementedFunction(fm.getName()); - } - } - return retval; - } - /** - * @return null if the specified functionIndex is for INDIRECT() or any external (add-in) function. - */ - public static Function getBasicFunction(int functionIndex) { - // check for 'free ref' functions first - switch (functionIndex) { - case FunctionID.INDIRECT: - case FunctionID.EXTERNAL_FUNC: - return null; - } - // else - must be plain function - Function result = functions[functionIndex]; - if (result == null) { - throw new NotImplementedException("FuncIx=" + functionIndex); - } - return result; - } - - /** - * Register a new function in runtime. - * - * @param name the function name - * @param func the functoin to register - * @throws IllegalArgumentException if the function is unknown or already registered. - * @since 3.8 beta6 - */ - public static void registerFunction(String name, Function func){ - FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByName(name); - if(metaData == null) { - if(AnalysisToolPak.isATPFunction(name)) { - throw new IllegalArgumentException(name + " is a function from the Excel Analysis Toolpack. " + - "Use AnalysisToolpack.registerFunction(String name, FreeRefFunction func) instead."); - } - - throw new IllegalArgumentException("Unknown function: " + name); - } - - int idx = metaData.getIndex(); - if(functions[idx] instanceof NotImplementedFunction) { - functions[idx] = func; - } else { - throw new IllegalArgumentException("POI already implememts " + name + - ". You cannot override POI's implementations of Excel functions"); - } - } - - /** - * Returns a collection of function names implemented by POI. - * - * @return an array of supported functions - * @since 3.8 beta6 - */ - public static Collection getSupportedFunctionNames() { - Collection lst = new TreeSet(); - for (int i = 0; i < functions.length; i++) { - Function func = functions[i]; - FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByIndex(i); - if (func != null && !(func instanceof NotImplementedFunction)) { - lst.add(metaData.getName()); - } - } - lst.add("INDIRECT"); // INDIRECT is a special case - return Collections.unmodifiableCollection(lst); - } - - /** - * Returns an array of function names NOT implemented by POI. - * - * @return an array of not supported functions - * @since 3.8 beta6 - */ - public static Collection getNotSupportedFunctionNames() { - Collection lst = new TreeSet(); - for (int i = 0; i < functions.length; i++) { - Function func = functions[i]; - if (func != null && (func instanceof NotImplementedFunction)) { - FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByIndex(i); - lst.add(metaData.getName()); - } - } - lst.remove("INDIRECT"); // INDIRECT is a special case - return Collections.unmodifiableCollection(lst); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/FunctionNameEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/FunctionNameEval.java deleted file mode 100644 index 8a9e48042..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/FunctionNameEval.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -/** - * @author Josh Micich - */ -public final class FunctionNameEval implements ValueEval { - - private final String _functionName; - - /** - * Creates a NameEval representing a function name - */ - public FunctionNameEval(String functionName) { - _functionName = functionName; - } - - - public String getFunctionName() { - return _functionName; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_functionName); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/IntersectionEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/IntersectionEval.java deleted file mode 100644 index 4063790c7..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/IntersectionEval.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed2ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - -/** - * @author Josh Micich - */ -public final class IntersectionEval extends Fixed2ArgFunction { - - public static final Function instance = new IntersectionEval(); - - private IntersectionEval() { - // enforces singleton - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - - try { - AreaEval reA = evaluateRef(arg0); - AreaEval reB = evaluateRef(arg1); - AreaEval result = resolveRange(reA, reB); - if (result == null) { - return ErrorEval.NULL_INTERSECTION; - } - return result; - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - /** - * @return simple rectangular {@link AreaEval} which represents the intersection of areas - * aeA and aeB. If the two areas do not intersect, the result is null. - */ - private static AreaEval resolveRange(AreaEval aeA, AreaEval aeB) { - - int aeAfr = aeA.getFirstRow(); - int aeAfc = aeA.getFirstColumn(); - int aeBlc = aeB.getLastColumn(); - if (aeAfc > aeBlc) { - return null; - } - int aeBfc = aeB.getFirstColumn(); - if (aeBfc > aeA.getLastColumn()) { - return null; - } - int aeBlr = aeB.getLastRow(); - if (aeAfr > aeBlr) { - return null; - } - int aeBfr = aeB.getFirstRow(); - int aeAlr = aeA.getLastRow(); - if (aeBfr > aeAlr) { - return null; - } - - - int top = Math.max(aeAfr, aeBfr); - int bottom = Math.min(aeAlr, aeBlr); - int left = Math.max(aeAfc, aeBfc); - int right = Math.min(aeA.getLastColumn(), aeBlc); - - return aeA.offset(top-aeAfr, bottom-aeAfr, left-aeAfc, right-aeAfc); - } - - private static AreaEval evaluateRef(ValueEval arg) throws EvaluationException { - if (arg instanceof AreaEval) { - return (AreaEval) arg; - } - if (arg instanceof RefEval) { - return ((RefEval) arg).offset(0, 0, 0, 0); - } - if (arg instanceof ErrorEval) { - throw new EvaluationException((ErrorEval)arg); - } - throw new IllegalArgumentException("Unexpected ref arg class (" + arg.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/MissingArgEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/MissingArgEval.java deleted file mode 100644 index 70d25040f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/MissingArgEval.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -/** - * Represents the (intermediate) evaluated result of a missing function argument. In most cases - * this can be translated into {@link BlankEval} but there are some notable exceptions. Functions - * COUNT and COUNTA do count their missing args. Note - the differences between - * {@link MissingArgEval} and {@link BlankEval} have not been investigated fully, so the POI - * evaluator may need to be updated to account for these as they are found. - * - * @author Josh Micich - */ -public final class MissingArgEval implements ValueEval { - - public static final MissingArgEval instance = new MissingArgEval(); - - private MissingArgEval() { - // enforce singleton - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java b/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java deleted file mode 100644 index 9d81f8ce3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.usermodel.FormulaEvaluator; - -/** - * An exception thrown by implementors of {@link FormulaEvaluator}, - * when attempting to evaluate a formula which requires features - * that POI does not (yet) support. - * - *

        Where possible, a subclass of this should be thrown, to provide - * more detail of what part of the formula couldn't be processed due - * to a missing implementation - */ -public class NotImplementedException extends RuntimeException { - private static final long serialVersionUID = -5840703336495141301L; - - public NotImplementedException(String message) { - super(message); - } - public NotImplementedException(String message, NotImplementedException cause) { - super(message, cause); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedFunctionException.java b/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedFunctionException.java deleted file mode 100644 index 182e53b15..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/NotImplementedFunctionException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.usermodel.FormulaEvaluator; - -/** - * An exception thrown by implementors of {@link FormulaEvaluator} when - * attempting to evaluate a formula which requires a function that POI - * does not (yet) support. - */ -public final class NotImplementedFunctionException extends NotImplementedException { - private static final long serialVersionUID = 1208119411557559057L; - - private String functionName; - - public NotImplementedFunctionException(String functionName) { - super(functionName); - this.functionName = functionName; - } - public NotImplementedFunctionException(String functionName, NotImplementedException cause) { - super(functionName, cause); - this.functionName = functionName; - } - - public String getFunctionName() { - return functionName; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/NumberEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/NumberEval.java deleted file mode 100644 index 87d425356..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/NumberEval.java +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.ptg.IntPtg; -import org.apache.poi.ss.formula.ptg.NumberPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.util.NumberToTextConverter; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class NumberEval implements NumericValueEval, StringValueEval { - - public static final NumberEval ZERO = new NumberEval(0); - - private final double _value; - private String _stringValue; - - public NumberEval(Ptg ptg) { - if (ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if (ptg instanceof IntPtg) { - _value = ((IntPtg) ptg).getValue(); - } else if (ptg instanceof NumberPtg) { - _value = ((NumberPtg) ptg).getValue(); - } else { - throw new IllegalArgumentException("bad argument type (" + ptg.getClass().getName() + ")"); - } - } - - public NumberEval(double value) { - _value = value; - } - - public double getNumberValue() { - return _value; - } - - public String getStringValue() { - if (_stringValue == null) { - _stringValue = NumberToTextConverter.toText(_value); - } - return _stringValue; - } - public final String toString() { - return getClass().getName() + " [" + - getStringValue() + - "]"; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java deleted file mode 100644 index 056f21cdf..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java +++ /dev/null @@ -1,30 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.ss.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public interface NumericValueEval extends ValueEval { - - public abstract double getNumberValue(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java b/trunk/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java deleted file mode 100644 index d2b899da5..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java +++ /dev/null @@ -1,328 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import java.util.regex.Pattern; - -/** - * Provides functionality for evaluating arguments to functions and operators. - * - * @author Josh Micich - * @author Brendan Nolan - */ -public final class OperandResolver { - - // Based on regular expression defined in JavaDoc at {@link java.lang.Double#valueOf} - // modified to remove support for NaN, Infinity, Hexadecimal support and floating type suffixes - private static final String Digits = "(\\p{Digit}+)"; - private static final String Exp = "[eE][+-]?"+Digits; - private static final String fpRegex = - ("[\\x00-\\x20]*" + - "[+-]?(" + - "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ - "(\\.("+Digits+")("+Exp+")?))))"+ - "[\\x00-\\x20]*"); - - - private OperandResolver() { - // no instances of this class - } - - /** - * Retrieves a single value from a variety of different argument types according to standard - * Excel rules. Does not perform any type conversion. - * @param arg the evaluated argument as passed to the function or operator. - * @param srcCellRow used when arg is a single column AreaRef - * @param srcCellCol used when arg is a single row AreaRef - * @return a NumberEval, StringEval, BoolEval or BlankEval. - * Never null or ErrorEval. - * @throws EvaluationException(#VALUE!) if srcCellRow or srcCellCol do not properly index into - * an AreaEval. If the actual value retrieved is an ErrorEval, a corresponding - * EvaluationException is thrown. - */ - public static ValueEval getSingleValue(ValueEval arg, int srcCellRow, int srcCellCol) - throws EvaluationException { - final ValueEval result; - if (arg instanceof RefEval) { - result = chooseSingleElementFromRef((RefEval) arg); - } else if (arg instanceof AreaEval) { - result = chooseSingleElementFromArea((AreaEval) arg, srcCellRow, srcCellCol); - } else { - result = arg; - } - if (result instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) result); - } - return result; - } - - /** - * Implements (some perhaps not well known) Excel functionality to select a single cell from an - * area depending on the coordinates of the calling cell. Here is an example demonstrating - * both selection from a single row area and a single column area in the same formula. - * - * - * - * - * - * - * - *
          A  B  C  D 
        1152025 
        2   200
        3   300
        3   400
        - * - * If the formula "=1000+A1:B1+D2:D3" is put into the 9 cells from A2 to C4, the spreadsheet - * will look like this: - * - * - * - * - * - * - * - *
          A  B  C  D 
        1152025 
        212151220#VALUE!200
        313151320#VALUE!300
        4#VALUE!#VALUE!#VALUE!400
        - * - * Note that the row area (A1:B1) does not include column C and the column area (D2:D3) does - * not include row 4, so the values in C1(=25) and D4(=400) are not accessible to the formula - * as written, but in the 4 cells A2:B3, the row and column selection works ok.

        - * - * The same concept is extended to references across sheets, such that even multi-row, - * multi-column areas can be useful.

        - * - * Of course with carefully (or carelessly) chosen parameters, cyclic references can occur and - * hence this method can throw a 'circular reference' EvaluationException. Note that - * this method does not attempt to detect cycles. Every cell in the specified Area ae - * has already been evaluated prior to this method call. Any cell (or cells) part of - * ae that would incur a cyclic reference error if selected by this method, will - * already have the value ErrorEval.CIRCULAR_REF_ERROR upon entry to this method. It - * is assumed logic exists elsewhere to produce this behaviour. - * - * @return whatever the selected cell's evaluated value is. Never null. Never - * ErrorEval. - * @throws EvaluationException if there is a problem with indexing into the area, or if the - * evaluated cell has an error. - */ - public static ValueEval chooseSingleElementFromArea(AreaEval ae, - int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval result = chooseSingleElementFromAreaInternal(ae, srcCellRow, srcCellCol); - if (result instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) result); - } - return result; - } - - /** - * @return possibly ErrorEval, and null - */ - private static ValueEval chooseSingleElementFromAreaInternal(AreaEval ae, - int srcCellRow, int srcCellCol) throws EvaluationException { - -// if(false) { -// // this is too simplistic -// if(ae.containsRow(srcCellRow) && ae.containsColumn(srcCellCol)) { -// throw new EvaluationException(ErrorEval.CIRCULAR_REF_ERROR); -// } -// /* -// Circular references are not dealt with directly here, but it is worth noting some issues. -// -// ANY one of the return statements in this method could return a cell that is identical -// to the one immediately being evaluated. The evaluating cell is identified by srcCellRow, -// srcCellRow AND sheet. The sheet is not available in any nearby calling method, so that's -// one reason why circular references are not easy to detect here. (The sheet of the returned -// cell can be obtained from ae if it is an Area3DEval.) -// -// Another reason there's little value in attempting to detect circular references here is -// that only direct circular references could be detected. If the cycle involved two or more -// cells this method could not detect it. -// -// Logic to detect evaluation cycles of all kinds has been coded in EvaluationCycleDetector -// (and FormulaEvaluator). -// */ -// } - - if (ae.isColumn()) { - if(ae.isRow()) { - return ae.getRelativeValue(0, 0); - } - if(!ae.containsRow(srcCellRow)) { - throw EvaluationException.invalidValue(); - } - return ae.getAbsoluteValue(srcCellRow, ae.getFirstColumn()); - } - if(!ae.isRow()) { - // multi-column, multi-row area - if(ae.containsRow(srcCellRow) && ae.containsColumn(srcCellCol)) { - return ae.getAbsoluteValue(ae.getFirstRow(), ae.getFirstColumn()); - } - throw EvaluationException.invalidValue(); - } - if(!ae.containsColumn(srcCellCol)) { - throw EvaluationException.invalidValue(); - } - return ae.getAbsoluteValue(ae.getFirstRow(), srcCellCol); - } - - private static ValueEval chooseSingleElementFromRef(RefEval ref) { - return ref.getInnerValueEval( ref.getFirstSheetIndex() ); - } - - /** - * Applies some conversion rules if the supplied value is not already an integer.
        - * Value is first coerced to a double ( See coerceValueToDouble() ). - * Note - BlankEval is converted to 0.

        - * - * Excel typically converts doubles to integers by truncating toward negative infinity.
        - * The equivalent java code is:
        - *   return (int)Math.floor(d);
        - * not:
        - *   return (int)d; // wrong - rounds toward zero - * - */ - public static int coerceValueToInt(ValueEval ev) throws EvaluationException { - if (ev == BlankEval.instance) { - return 0; - } - double d = coerceValueToDouble(ev); - // Note - the standard java type conversion from double to int truncates toward zero. - // but Math.floor() truncates toward negative infinity - return (int)Math.floor(d); - } - - /** - * Applies some conversion rules if the supplied value is not already a number. - * Note - BlankEval is converted to {@link NumberEval#ZERO}. - * @param ev must be a {@link NumberEval}, {@link StringEval}, {@link BoolEval} or - * {@link BlankEval} - * @return actual, parsed or interpreted double value (respectively). - * @throws EvaluationException(#VALUE!) only if a StringEval is supplied and cannot be parsed - * as a double (See parseDouble() for allowable formats). - * @throws RuntimeException if the supplied parameter is not {@link NumberEval}, - * {@link StringEval}, {@link BoolEval} or {@link BlankEval} - */ - public static double coerceValueToDouble(ValueEval ev) throws EvaluationException { - - if (ev == BlankEval.instance) { - return 0.0; - } - if (ev instanceof NumericValueEval) { - // this also handles booleans - return ((NumericValueEval)ev).getNumberValue(); - } - if (ev instanceof StringEval) { - Double dd = parseDouble(((StringEval) ev).getStringValue()); - if (dd == null) { - throw EvaluationException.invalidValue(); - } - return dd.doubleValue(); - } - throw new RuntimeException("Unexpected arg eval type (" + ev.getClass().getName() + ")"); - } - - /** - * Converts a string to a double using standard rules that Excel would use.
        - * Tolerates leading and trailing spaces,

        - * - * Doesn't support currency prefixes, commas, percentage signs or arithmetic operations strings. - * - * Some examples:
        - * " 123 " -> 123.0
        - * ".123" -> 0.123
        - * "1E4" -> 1000
        - * "-123" -> -123.0
        - * These not supported yet:
        - * " $ 1,000.00 " -> 1000.0
        - * "$1.25E4" -> 12500.0
        - * "5**2" -> 500
        - * "250%" -> 2.5
        - * - * @return null if the specified text cannot be parsed as a number - */ - public static Double parseDouble(String pText) { - - if (Pattern.matches(fpRegex, pText)) - try { - return Double.parseDouble(pText); - } catch (NumberFormatException e) { - return null; - } - else { - return null; - } - - } - - /** - * @param ve must be a NumberEval, StringEval, BoolEval, or BlankEval - * @return the converted string value. never null - */ - public static String coerceValueToString(ValueEval ve) { - if (ve instanceof StringValueEval) { - StringValueEval sve = (StringValueEval) ve; - return sve.getStringValue(); - } - if (ve == BlankEval.instance) { - return ""; - } - throw new IllegalArgumentException("Unexpected eval class (" + ve.getClass().getName() + ")"); - } - - /** - * @return null to represent blank values - * @throws EvaluationException if ve is an ErrorEval, or if a string value cannot be converted - */ - public static Boolean coerceValueToBoolean(ValueEval ve, boolean stringsAreBlanks) throws EvaluationException { - - if (ve == null || ve == BlankEval.instance) { - // TODO - remove 've == null' condition once AreaEval is fixed - return null; - } - if (ve instanceof BoolEval) { - return Boolean.valueOf(((BoolEval) ve).getBooleanValue()); - } - - if (ve == BlankEval.instance) { - return null; - } - - if (ve instanceof StringEval) { - if (stringsAreBlanks) { - return null; - } - String str = ((StringEval) ve).getStringValue(); - if (str.equalsIgnoreCase("true")) { - return Boolean.TRUE; - } - if (str.equalsIgnoreCase("false")) { - return Boolean.FALSE; - } - // else - string cannot be converted to boolean - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - double d = ne.getNumberValue(); - if (Double.isNaN(d)) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - return Boolean.valueOf(d != 0); - } - if (ve instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) ve); - } - throw new RuntimeException("Unexpected eval (" + ve.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/PercentEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/PercentEval.java deleted file mode 100644 index 263574a40..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/PercentEval.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed1ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - - -/** - * Implementation of Excel formula token '%'.

        - * @author Josh Micich - */ -public final class PercentEval extends Fixed1ArgFunction { - - public static final Function instance = new PercentEval(); - - private PercentEval() { - // enforce singleton - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - double d; - try { - ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - d = OperandResolver.coerceValueToDouble(ve); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (d == 0.0) { // this '==' matches +0.0 and -0.0 - return NumberEval.ZERO; - } - return new NumberEval(d / 100); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/RangeEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/RangeEval.java deleted file mode 100644 index 617d20a76..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/RangeEval.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed2ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - - -/** - * - * @author Josh Micich - */ -public final class RangeEval extends Fixed2ArgFunction { - - public static final Function instance = new RangeEval(); - - private RangeEval() { - // enforces singleton - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - - try { - AreaEval reA = evaluateRef(arg0); - AreaEval reB = evaluateRef(arg1); - return resolveRange(reA, reB); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - /** - * @return simple rectangular {@link AreaEval} which fully encloses both areas - * aeA and aeB - */ - private static AreaEval resolveRange(AreaEval aeA, AreaEval aeB) { - int aeAfr = aeA.getFirstRow(); - int aeAfc = aeA.getFirstColumn(); - - int top = Math.min(aeAfr, aeB.getFirstRow()); - int bottom = Math.max(aeA.getLastRow(), aeB.getLastRow()); - int left = Math.min(aeAfc, aeB.getFirstColumn()); - int right = Math.max(aeA.getLastColumn(), aeB.getLastColumn()); - - return aeA.offset(top-aeAfr, bottom-aeAfr, left-aeAfc, right-aeAfc); - } - - private static AreaEval evaluateRef(ValueEval arg) throws EvaluationException { - if (arg instanceof AreaEval) { - return (AreaEval) arg; - } - if (arg instanceof RefEval) { - return ((RefEval) arg).offset(0, 0, 0, 0); - } - if (arg instanceof ErrorEval) { - throw new EvaluationException((ErrorEval)arg); - } - throw new IllegalArgumentException("Unexpected ref arg class (" + arg.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/RefEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/RefEval.java deleted file mode 100644 index 46aa96c04..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/RefEval.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.SheetRange; -import org.apache.poi.ss.usermodel.CellType; - -/** - * RefEval is the super interface for Ref2D and Ref3DEval. Basically a RefEval - * impl should contain reference to the original ReferencePtg or Ref3DPtg as - * well as the final "value" resulting from the evaluation of the cell - * reference. Thus if the Cell has type {@link CellType#NUMERIC}, the contained - * value object should be of type NumberEval; if cell type is {@link CellType#STRING}, - * contained value object should be of type StringEval - */ -public interface RefEval extends ValueEval, SheetRange { - /** - * @return the evaluated value of the cell referred to by this RefEval on the given sheet - */ - ValueEval getInnerValueEval(int sheetIndex); - - /** - * returns the zero based column index. - */ - int getColumn(); - - /** - * returns the zero based row index. - */ - int getRow(); - - /** - * returns the first sheet index this applies to - */ - int getFirstSheetIndex(); - - /** - * returns the last sheet index this applies to, which - * will be the same as the first for a 2D and many 3D references - */ - int getLastSheetIndex(); - - /** - * returns the number of sheets this applies to - */ - int getNumberOfSheets(); - - /** - * Creates an {@link AreaEval} offset by a relative amount from this RefEval - */ - AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java b/trunk/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java deleted file mode 100644 index bd96c4eb8..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.SheetRange; - -/** - * Common base class for implementors of {@link RefEval} - */ -public abstract class RefEvalBase implements RefEval { - private final int _firstSheetIndex; - private final int _lastSheetIndex; - private final int _rowIndex; - private final int _columnIndex; - - protected RefEvalBase(SheetRange sheetRange, int rowIndex, int columnIndex) { - if (sheetRange == null) { - throw new IllegalArgumentException("sheetRange must not be null"); - } - _firstSheetIndex = sheetRange.getFirstSheetIndex(); - _lastSheetIndex = sheetRange.getLastSheetIndex(); - _rowIndex = rowIndex; - _columnIndex = columnIndex; - } - protected RefEvalBase(int firstSheetIndex, int lastSheetIndex, int rowIndex, int columnIndex) { - _firstSheetIndex = firstSheetIndex; - _lastSheetIndex = lastSheetIndex; - _rowIndex = rowIndex; - _columnIndex = columnIndex; - } - protected RefEvalBase(int onlySheetIndex, int rowIndex, int columnIndex) { - this(onlySheetIndex, onlySheetIndex, rowIndex, columnIndex); - } - - public int getNumberOfSheets() { - return _lastSheetIndex-_firstSheetIndex+1; - } - public int getFirstSheetIndex() { - return _firstSheetIndex; - } - public int getLastSheetIndex() { - return _lastSheetIndex; - } - public final int getRow() { - return _rowIndex; - } - public final int getColumn() { - return _columnIndex; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java deleted file mode 100644 index 8b3be1919..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed2ArgFunction; -import org.apache.poi.ss.formula.functions.Function; -import org.apache.poi.ss.util.NumberComparer; - -/** - * Base class for all comparison operator evaluators - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public abstract class RelationalOperationEval extends Fixed2ArgFunction { - - /** - * Converts a standard compare result (-1, 0, 1) to true or false - * according to subclass' comparison type. - */ - protected abstract boolean convertComparisonResult(int cmpResult); - - /** - * This is a description of how the relational operators apply in MS Excel. - * Use this as a guideline when testing/implementing the evaluate methods - * for the relational operators Evals. - * - *

        -	 * Bool.TRUE > any number.
        -	 * Bool > any string. ALWAYS
        -	 * Bool.TRUE > Bool.FALSE
        -	 * Bool.FALSE == Blank
        -	 *
        -	 * Strings are never converted to numbers or booleans
        -	 * String > any number. ALWAYS
        -	 * Non-empty String > Blank
        -	 * Empty String == Blank
        -	 * String are sorted dictionary wise
        -	 *
        -	 * Blank > Negative numbers
        -	 * Blank == 0
        -	 * Blank < Positive numbers
        -	 * 
        - */ - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - - ValueEval vA; - ValueEval vB; - try { - vA = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - vB = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - int cmpResult = doCompare(vA, vB); - boolean result = convertComparisonResult(cmpResult); - return BoolEval.valueOf(result); - } - - private static int doCompare(ValueEval va, ValueEval vb) { - // special cases when one operand is blank - if (va == BlankEval.instance) { - return compareBlank(vb); - } - if (vb == BlankEval.instance) { - return -compareBlank(va); - } - - if (va instanceof BoolEval) { - if (vb instanceof BoolEval) { - BoolEval bA = (BoolEval) va; - BoolEval bB = (BoolEval) vb; - if (bA.getBooleanValue() == bB.getBooleanValue()) { - return 0; - } - return bA.getBooleanValue() ? 1 : -1; - } - return 1; - } - if (vb instanceof BoolEval) { - return -1; - } - if (va instanceof StringEval) { - if (vb instanceof StringEval) { - StringEval sA = (StringEval) va; - StringEval sB = (StringEval) vb; - return sA.getStringValue().compareToIgnoreCase(sB.getStringValue()); - } - return 1; - } - if (vb instanceof StringEval) { - return -1; - } - if (va instanceof NumberEval) { - if (vb instanceof NumberEval) { - NumberEval nA = (NumberEval) va; - NumberEval nB = (NumberEval) vb; - return NumberComparer.compare(nA.getNumberValue(), nB.getNumberValue()); - } - } - throw new IllegalArgumentException("Bad operand types (" + va.getClass().getName() + "), (" - + vb.getClass().getName() + ")"); - } - - private static int compareBlank(ValueEval v) { - if (v == BlankEval.instance) { - return 0; - } - if (v instanceof BoolEval) { - BoolEval boolEval = (BoolEval) v; - return boolEval.getBooleanValue() ? -1 : 0; - } - if (v instanceof NumberEval) { - NumberEval ne = (NumberEval) v; - return NumberComparer.compare(0.0, ne.getNumberValue()); - } - if (v instanceof StringEval) { - StringEval se = (StringEval) v; - return se.getStringValue().length() < 1 ? 0 : -1; - } - throw new IllegalArgumentException("bad value class (" + v.getClass().getName() + ")"); - } - - public static final Function EqualEval = new RelationalOperationEval() { - protected boolean convertComparisonResult(int cmpResult) { - return cmpResult == 0; - } - }; - public static final Function GreaterEqualEval = new RelationalOperationEval() { - protected boolean convertComparisonResult(int cmpResult) { - return cmpResult >= 0; - } - }; - public static final Function GreaterThanEval = new RelationalOperationEval() { - protected boolean convertComparisonResult(int cmpResult) { - return cmpResult > 0; - } - }; - public static final Function LessEqualEval = new RelationalOperationEval() { - protected boolean convertComparisonResult(int cmpResult) { - return cmpResult <= 0; - } - }; - public static final Function LessThanEval = new RelationalOperationEval() { - protected boolean convertComparisonResult(int cmpResult) { - return cmpResult < 0; - } - }; - public static final Function NotEqualEval = new RelationalOperationEval() { - protected boolean convertComparisonResult(int cmpResult) { - return cmpResult != 0; - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/StringEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/StringEval.java deleted file mode 100644 index 5d3976137..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/StringEval.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.StringPtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class StringEval implements StringValueEval { - - public static final StringEval EMPTY_INSTANCE = new StringEval(""); - - private final String _value; - - public StringEval(Ptg ptg) { - this(((StringPtg) ptg).getValue()); - } - - public StringEval(String value) { - if (value == null) { - throw new IllegalArgumentException("value must not be null"); - } - _value = value; - } - - public String getStringValue() { - return _value; - } - - public String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_value); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/StringValueEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/StringValueEval.java deleted file mode 100644 index 4e1b712fb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/StringValueEval.java +++ /dev/null @@ -1,30 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.poi.ss.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public interface StringValueEval extends ValueEval { - - /** - * @return never null, possibly empty string. - */ - String getStringValue(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java b/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java deleted file mode 100644 index a4c05d96f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed2ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - -/** - * @author Josh Micich - */ -public abstract class TwoOperandNumericOperation extends Fixed2ArgFunction { - - protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - return OperandResolver.coerceValueToDouble(ve); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - double result; - try { - double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - result = evaluate(d0, d1); - if (result == 0.0) { // this '==' matches +0.0 and -0.0 - // Excel converts -0.0 to +0.0 for '*', '/', '%', '+' and '^' - if (!(this instanceof SubtractEvalClass)) { - return NumberEval.ZERO; - } - } - if (Double.isNaN(result) || Double.isInfinite(result)) { - return ErrorEval.NUM_ERROR; - } - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - - protected abstract double evaluate(double d0, double d1) throws EvaluationException; - - public static final Function AddEval = new TwoOperandNumericOperation() { - protected double evaluate(double d0, double d1) { - return d0+d1; - } - }; - public static final Function DivideEval = new TwoOperandNumericOperation() { - protected double evaluate(double d0, double d1) throws EvaluationException { - if (d1 == 0.0) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return d0/d1; - } - }; - public static final Function MultiplyEval = new TwoOperandNumericOperation() { - protected double evaluate(double d0, double d1) { - return d0*d1; - } - }; - public static final Function PowerEval = new TwoOperandNumericOperation() { - protected double evaluate(double d0, double d1) { - return Math.pow(d0, d1); - } - }; - private static final class SubtractEvalClass extends TwoOperandNumericOperation { - public SubtractEvalClass() { - // - } - protected double evaluate(double d0, double d1) { - return d0-d1; - } - } - public static final Function SubtractEval = new SubtractEvalClass(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java deleted file mode 100644 index 02d6d5e12..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed1ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class UnaryMinusEval extends Fixed1ArgFunction { - - public static final Function instance = new UnaryMinusEval(); - - private UnaryMinusEval() { - // enforce singleton - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - double d; - try { - ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - d = OperandResolver.coerceValueToDouble(ve); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (d == 0.0) { // this '==' matches +0.0 and -0.0 - return NumberEval.ZERO; - } - return new NumberEval(-d); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java deleted file mode 100644 index 9b10f2b10..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.formula.functions.Fixed1ArgFunction; -import org.apache.poi.ss.formula.functions.Function; - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class UnaryPlusEval extends Fixed1ArgFunction { - - public static final Function instance = new UnaryPlusEval(); - - private UnaryPlusEval() { - // enforce singleton - } - - public ValueEval evaluate(int srcCellRow, int srcCellCol, ValueEval arg0) { - double d; - try { - ValueEval ve = OperandResolver.getSingleValue(arg0, srcCellRow, srcCellCol); - if(ve instanceof StringEval) { - // Note - asymmetric with UnaryMinus - // -"hello" evaluates to #VALUE! - // but +"hello" evaluates to "hello" - return ve; - } - d = OperandResolver.coerceValueToDouble(ve); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(+d); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/ValueEval.java b/trunk/src/java/org/apache/poi/ss/formula/eval/ValueEval.java deleted file mode 100644 index c1309a7df..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/ValueEval.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public interface ValueEval { - // no methods -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java b/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java deleted file mode 100644 index db01b0640..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java +++ /dev/null @@ -1,179 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.util.Internal; - -/** - * Represents a cell being used for forked evaluation that has had a value set different from the - * corresponding cell in the shared master workbook. - * - * @author Josh Micich - */ -final class ForkedEvaluationCell implements EvaluationCell { - - private final EvaluationSheet _sheet; - /** corresponding cell from master workbook */ - private final EvaluationCell _masterCell; - private boolean _booleanValue; - private CellType _cellType; - private int _errorValue; - private double _numberValue; - private String _stringValue; - - public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) { - _sheet = sheet; - _masterCell = masterCell; - // start with value blank, but expect construction to be immediately - setValue(BlankEval.instance); // followed by a proper call to setValue() - } - - @Override - public Object getIdentityKey() { - return _masterCell.getIdentityKey(); - } - - public void setValue(ValueEval value) { - Class cls = value.getClass(); - - if (cls == NumberEval.class) { - _cellType = CellType.NUMERIC; - _numberValue = ((NumberEval)value).getNumberValue(); - return; - } - if (cls == StringEval.class) { - _cellType = CellType.STRING; - _stringValue = ((StringEval)value).getStringValue(); - return; - } - if (cls == BoolEval.class) { - _cellType = CellType.BOOLEAN; - _booleanValue = ((BoolEval)value).getBooleanValue(); - return; - } - if (cls == ErrorEval.class) { - _cellType = CellType.ERROR; - _errorValue = ((ErrorEval)value).getErrorCode(); - return; - } - if (cls == BlankEval.class) { - _cellType = CellType.BLANK; - return; - } - throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")"); - } - public void copyValue(Cell destCell) { - switch (_cellType) { - case BLANK: destCell.setCellType(CellType.BLANK); return; - case NUMERIC: destCell.setCellValue(_numberValue); return; - case BOOLEAN: destCell.setCellValue(_booleanValue); return; - case STRING: destCell.setCellValue(_stringValue); return; - case ERROR: destCell.setCellErrorValue((byte)_errorValue); return; - default: throw new IllegalStateException("Unexpected data type (" + _cellType + ")"); - } - } - - private void checkCellType(CellType expectedCellType) { - if (_cellType != expectedCellType) { - throw new RuntimeException("Wrong data type (" + _cellType + ")"); - } - } - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCellType() { - return _cellType.getCode(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCellTypeEnum() { - return _cellType; - } - @Override - public boolean getBooleanCellValue() { - checkCellType(CellType.BOOLEAN); - return _booleanValue; - } - @Override - public int getErrorCellValue() { - checkCellType(CellType.ERROR); - return _errorValue; - } - @Override - public double getNumericCellValue() { - checkCellType(CellType.NUMERIC); - return _numberValue; - } - @Override - public String getStringCellValue() { - checkCellType(CellType.STRING); - return _stringValue; - } - @Override - public EvaluationSheet getSheet() { - return _sheet; - } - @Override - public int getRowIndex() { - return _masterCell.getRowIndex(); - } - @Override - public int getColumnIndex() { - return _masterCell.getColumnIndex(); - } - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type of cached formula result - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCachedFormulaResultType() { - return _masterCell.getCachedFormulaResultType(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCachedFormulaResultTypeEnum() { - return _masterCell.getCachedFormulaResultTypeEnum(); - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java b/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java deleted file mode 100644 index 072a777e1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java +++ /dev/null @@ -1,153 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Internal; - -/** - * Represents a sheet being used for forked evaluation. Initially, objects of this class contain - * only the cells from the master workbook. By calling {@link #getOrCreateUpdatableCell(int, int)}, - * the master cell object is logically replaced with a {@link ForkedEvaluationCell} instance, which - * will be used in all subsequent evaluations.
        - * - * For POI internal use only - * - * @author Josh Micich - */ -@Internal -final class ForkedEvaluationSheet implements EvaluationSheet { - - private final EvaluationSheet _masterSheet; - /** - * Only cells which have been split are put in this map. (This has been done to conserve memory). - */ - private final Map _sharedCellsByRowCol; - - public ForkedEvaluationSheet(EvaluationSheet masterSheet) { - _masterSheet = masterSheet; - _sharedCellsByRowCol = new HashMap(); - } - - @Override - public EvaluationCell getCell(int rowIndex, int columnIndex) { - RowColKey key = new RowColKey(rowIndex, columnIndex); - - ForkedEvaluationCell result = _sharedCellsByRowCol.get(key); - if (result == null) { - return _masterSheet.getCell(rowIndex, columnIndex); - } - return result; - } - - public ForkedEvaluationCell getOrCreateUpdatableCell(int rowIndex, int columnIndex) { - RowColKey key = new RowColKey(rowIndex, columnIndex); - - ForkedEvaluationCell result = _sharedCellsByRowCol.get(key); - if (result == null) { - EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex); - if (mcell == null) { - CellReference cr = new CellReference(rowIndex, columnIndex); - throw new UnsupportedOperationException("Underlying cell '" - + cr.formatAsString() + "' is missing in master sheet."); - } - result = new ForkedEvaluationCell(this, mcell); - _sharedCellsByRowCol.put(key, result); - } - return result; - } - - public void copyUpdatedCells(Sheet sheet) { - RowColKey[] keys = new RowColKey[_sharedCellsByRowCol.size()]; - _sharedCellsByRowCol.keySet().toArray(keys); - Arrays.sort(keys); - for (int i = 0; i < keys.length; i++) { - RowColKey key = keys[i]; - Row row = sheet.getRow(key.getRowIndex()); - if (row == null) { - row = sheet.createRow(key.getRowIndex()); - } - Cell destCell = row.getCell(key.getColumnIndex()); - if (destCell == null) { - destCell = row.createCell(key.getColumnIndex()); - } - - ForkedEvaluationCell srcCell = _sharedCellsByRowCol.get(key); - srcCell.copyValue(destCell); - } - } - - public int getSheetIndex(EvaluationWorkbook mewb) { - return mewb.getSheetIndex(_masterSheet); - } - - /* (non-Javadoc) - * leave the map alone, if it needs resetting, reusing this class is probably a bad idea. - * @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues() - * - * @since POI 3.15 beta 3 - */ - @Override - public void clearAllCachedResultValues() { - _masterSheet.clearAllCachedResultValues(); - } - - // FIXME: serves same purpose as org.apache.poi.xssf.usermodel.XSSFEvaluationSheet$CellKey - private static final class RowColKey implements Comparable{ - private final int _rowIndex; - private final int _columnIndex; - - public RowColKey(int rowIndex, int columnIndex) { - _rowIndex = rowIndex; - _columnIndex = columnIndex; - } - @Override - public boolean equals(Object obj) { - assert obj instanceof RowColKey : "these private cache key instances are only compared to themselves"; - RowColKey other = (RowColKey) obj; - return _rowIndex == other._rowIndex && _columnIndex == other._columnIndex; - } - @Override - public int hashCode() { - return _rowIndex ^ _columnIndex; - } - public int compareTo(RowColKey o) { - int cmp = _rowIndex - o._rowIndex; - if (cmp != 0) { - return cmp; - } - return _columnIndex - o._columnIndex; - } - public int getRowIndex() { - return _rowIndex; - } - public int getColumnIndex() { - return _columnIndex; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java b/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java deleted file mode 100644 index adc3e4f07..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationName; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.Internal; - -/** - * Represents a workbook being used for forked evaluation. Most operations are delegated to the - * shared master workbook, except those that potentially involve cell values that may have been - * updated after a call to {@link #getOrCreateUpdatableCell(String, int, int)}.
        - * - * For POI internal use only - */ -@Internal -final class ForkedEvaluationWorkbook implements EvaluationWorkbook { - - private final EvaluationWorkbook _masterBook; - private final Map _sharedSheetsByName; - - public ForkedEvaluationWorkbook(EvaluationWorkbook master) { - _masterBook = master; - _sharedSheetsByName = new HashMap(); - } - - public ForkedEvaluationCell getOrCreateUpdatableCell(String sheetName, int rowIndex, - int columnIndex) { - ForkedEvaluationSheet sheet = getSharedSheet(sheetName); - return sheet.getOrCreateUpdatableCell(rowIndex, columnIndex); - } - - public EvaluationCell getEvaluationCell(String sheetName, int rowIndex, int columnIndex) { - ForkedEvaluationSheet sheet = getSharedSheet(sheetName); - return sheet.getCell(rowIndex, columnIndex); - } - - private ForkedEvaluationSheet getSharedSheet(String sheetName) { - ForkedEvaluationSheet result = _sharedSheetsByName.get(sheetName); - if (result == null) { - result = new ForkedEvaluationSheet(_masterBook.getSheet(_masterBook - .getSheetIndex(sheetName))); - _sharedSheetsByName.put(sheetName, result); - } - return result; - } - - public void copyUpdatedCells(Workbook workbook) { - String[] sheetNames = new String[_sharedSheetsByName.size()]; - _sharedSheetsByName.keySet().toArray(sheetNames); - for (String sheetName : sheetNames) { - ForkedEvaluationSheet sheet = _sharedSheetsByName.get(sheetName); - sheet.copyUpdatedCells(workbook.getSheet(sheetName)); - } - } - - @Override - public int convertFromExternSheetIndex(int externSheetIndex) { - return _masterBook.convertFromExternSheetIndex(externSheetIndex); - } - - @Override - public ExternalSheet getExternalSheet(int externSheetIndex) { - return _masterBook.getExternalSheet(externSheetIndex); - } - @Override - public ExternalSheet getExternalSheet(String firstSheetName, String lastSheetName, int externalWorkbookNumber) { - return _masterBook.getExternalSheet(firstSheetName, lastSheetName, externalWorkbookNumber); - } - - @Override - public Ptg[] getFormulaTokens(EvaluationCell cell) { - if (cell instanceof ForkedEvaluationCell) { - // doesn't happen yet because formulas cannot be modified from the master workbook - throw new RuntimeException("Updated formulas not supported yet"); - } - return _masterBook.getFormulaTokens(cell); - } - - @Override - public EvaluationName getName(NamePtg namePtg) { - return _masterBook.getName(namePtg); - } - - @Override - public EvaluationName getName(String name, int sheetIndex){ - return _masterBook.getName(name, sheetIndex); - } - - @Override - public EvaluationSheet getSheet(int sheetIndex) { - return getSharedSheet(getSheetName(sheetIndex)); - } - - @Override - public ExternalName getExternalName(int externSheetIndex, int externNameIndex) { - return _masterBook.getExternalName(externSheetIndex, externNameIndex); - } - @Override - public ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber) { - return _masterBook.getExternalName(nameName, sheetName, externalWorkbookNumber); - } - - @Override - public int getSheetIndex(EvaluationSheet sheet) { - if (sheet instanceof ForkedEvaluationSheet) { - ForkedEvaluationSheet mes = (ForkedEvaluationSheet) sheet; - return mes.getSheetIndex(_masterBook); - } - return _masterBook.getSheetIndex(sheet); - } - - @Override - public int getSheetIndex(String sheetName) { - return _masterBook.getSheetIndex(sheetName); - } - - @Override - public String getSheetName(int sheetIndex) { - return _masterBook.getSheetName(sheetIndex); - } - - @Override - public String resolveNameXText(NameXPtg ptg) { - return _masterBook.resolveNameXText(ptg); - } - - @Override - public UDFFinder getUDFFinder() { - return _masterBook.getUDFFinder(); - } - - /* (non-Javadoc) - * leave the map alone, if it needs resetting, reusing this class is probably a bad idea. - * @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues() - * - * @since POI 3.15 beta 3 - */ - @Override - public void clearAllCachedResultValues() { - _masterBook.clearAllCachedResultValues(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java b/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java deleted file mode 100644 index c8beb37d1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.udf.UDFFinder; - -import java.lang.reflect.Method; - -import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment; -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.formula.IStabilityClassifier; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * An alternative workbook evaluator that saves memory in situations where a single workbook is - * concurrently and independently evaluated many times. With standard formula evaluation, around - * 90% of memory consumption is due to loading of the {@link HSSFWorkbook} or {@link org.apache.poi.xssf.usermodel.XSSFWorkbook}. - * This class enables a 'master workbook' to be loaded just once and shared between many evaluation - * clients. Each evaluation client creates its own {@link ForkedEvaluator} and can set cell values - * that will be used for local evaluations (and don't disturb evaluations on other evaluators). - */ -public final class ForkedEvaluator { - - private WorkbookEvaluator _evaluator; - private ForkedEvaluationWorkbook _sewb; - - private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - _sewb = new ForkedEvaluationWorkbook(masterWorkbook); - _evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier, udfFinder); - } - private static EvaluationWorkbook createEvaluationWorkbook(Workbook wb) { - if (wb instanceof HSSFWorkbook) { - return HSSFEvaluationWorkbook.create((HSSFWorkbook) wb); - } else { - try { - // TODO: check if this is Java 9 compatible ... - Class evalWB = Class.forName("org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook"); - Class xssfWB = Class.forName("org.apache.poi.xssf.usermodel.XSSFWorkbook"); - Method createM = evalWB.getDeclaredMethod("create", xssfWB); - return (EvaluationWorkbook)createM.invoke(null, wb); - } catch (Exception e) { - throw new IllegalArgumentException("Unexpected workbook type (" + wb.getClass().getName() + ") - check for poi-ooxml and poi-ooxml schemas jar in the classpath", e); - } - } - } - - /** - * @param udfFinder pass null for default (AnalysisToolPak only) - */ - public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - return new ForkedEvaluator(createEvaluationWorkbook(wb), stabilityClassifier, udfFinder); - } - - /** - * Sets the specified cell to the supplied value - * @param sheetName the name of the sheet containing the cell - * @param rowIndex zero based - * @param columnIndex zero based - */ - public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) { - - ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex); - cell.setValue(value); - _evaluator.notifyUpdateCell(cell); - } - /** - * Copies the values of all updated cells (modified by calls to {@link - * #updateCell(String, int, int, ValueEval)}) to the supplied workbook.
        - * Typically, the supplied workbook is a writable copy of the 'master workbook', - * but at the very least it must contain sheets with the same names. - */ - public void copyUpdatedCells(Workbook workbook) { - _sewb.copyUpdatedCells(workbook); - } - - /** - * If cell contains a formula, the formula is evaluated and returned, - * else the CellValue simply copies the appropriate cell value from - * the cell and also its cell type. This method should be preferred over - * evaluateInCell() when the call should not modify the contents of the - * original cell. - * - * @param sheetName the name of the sheet containing the cell - * @param rowIndex zero based - * @param columnIndex zero based - * @return null if the supplied cell is null or blank - */ - public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) { - EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex); - - switch (cell.getCellTypeEnum()) { - case BOOLEAN: - return BoolEval.valueOf(cell.getBooleanCellValue()); - case ERROR: - return ErrorEval.valueOf(cell.getErrorCellValue()); - case FORMULA: - return _evaluator.evaluate(cell); - case NUMERIC: - return new NumberEval(cell.getNumericCellValue()); - case STRING: - return new StringEval(cell.getStringCellValue()); - case BLANK: - return null; - default: - throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")"); - } - } - /** - * Coordinates several formula evaluators together so that formulas that involve external - * references can be evaluated. - * @param workbookNames the simple file names used to identify the workbooks in formulas - * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1") - * @param evaluators all evaluators for the full set of workbooks required by the formulas. - */ - public static void setupEnvironment(String[] workbookNames, ForkedEvaluator[] evaluators) { - WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length]; - for (int i = 0; i < wbEvals.length; i++) { - wbEvals[i] = evaluators[i]._evaluator; - } - CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java b/trunk/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java deleted file mode 100644 index b44a03ef3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.function; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Temporarily collects FunctionMetadata instances for creation of a - * FunctionMetadataRegistry. - * - * @author Josh Micich - */ -final class FunctionDataBuilder { - private int _maxFunctionIndex; - private final Map _functionDataByName; - private final Map _functionDataByIndex; - /** stores indexes of all functions with footnotes (i.e. whose definitions might change) */ - private final Set _mutatingFunctionIndexes; - - public FunctionDataBuilder(int sizeEstimate) { - _maxFunctionIndex = -1; - _functionDataByName = new HashMap(sizeEstimate * 3 / 2); - _functionDataByIndex = new HashMap(sizeEstimate * 3 / 2); - _mutatingFunctionIndexes = new HashSet(); - } - - public void add(int functionIndex, String functionName, int minParams, int maxParams, - byte returnClassCode, byte[] parameterClassCodes, boolean hasFootnote) { - FunctionMetadata fm = new FunctionMetadata(functionIndex, functionName, minParams, maxParams, - returnClassCode, parameterClassCodes); - - Integer indexKey = Integer.valueOf(functionIndex); - - - if(functionIndex > _maxFunctionIndex) { - _maxFunctionIndex = functionIndex; - } - // allow function definitions to change only if both previous and the new items have footnotes - FunctionMetadata prevFM; - prevFM = _functionDataByName.get(functionName); - if(prevFM != null) { - if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) { - throw new RuntimeException("Multiple entries for function name '" + functionName + "'"); - } - _functionDataByIndex.remove(Integer.valueOf(prevFM.getIndex())); - } - prevFM = _functionDataByIndex.get(indexKey); - if(prevFM != null) { - if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) { - throw new RuntimeException("Multiple entries for function index (" + functionIndex + ")"); - } - _functionDataByName.remove(prevFM.getName()); - } - if(hasFootnote) { - _mutatingFunctionIndexes.add(indexKey); - } - _functionDataByIndex.put(indexKey, fm); - _functionDataByName.put(functionName, fm); - } - - public FunctionMetadataRegistry build() { - - FunctionMetadata[] jumbledArray = new FunctionMetadata[_functionDataByName.size()]; - _functionDataByName.values().toArray(jumbledArray); - FunctionMetadata[] fdIndexArray = new FunctionMetadata[_maxFunctionIndex+1]; - for (int i = 0; i < jumbledArray.length; i++) { - FunctionMetadata fd = jumbledArray[i]; - fdIndexArray[fd.getIndex()] = fd; - } - - return new FunctionMetadataRegistry(fdIndexArray, _functionDataByName); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadata.java b/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadata.java deleted file mode 100644 index 6ab06f0ad..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadata.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.function; - -/** - * Holds information about Excel built-in functions. - * - * @author Josh Micich - */ -public final class FunctionMetadata { - /** - * maxParams=30 in functionMetadata.txt means the maximum number arguments supported - * by the given version of Excel. Validation routines should take the actual limit (Excel 97 or 2007) - * from the SpreadsheetVersion enum. - * Perhaps a value like 'M' should be used instead of '30' in functionMetadata.txt - * to make that file more version neutral. - * @see org.apache.poi.ss.formula.FormulaParser#validateNumArgs(int, FunctionMetadata) - */ - private static final short FUNCTION_MAX_PARAMS = 30; - - private final int _index; - private final String _name; - private final int _minParams; - private final int _maxParams; - private final byte _returnClassCode; - private final byte[] _parameterClassCodes; - - /* package */ FunctionMetadata(int index, String name, int minParams, int maxParams, - byte returnClassCode, byte[] parameterClassCodes) { - _index = index; - _name = name; - _minParams = minParams; - _maxParams = maxParams; - _returnClassCode = returnClassCode; - _parameterClassCodes = (parameterClassCodes == null) ? null : parameterClassCodes.clone(); - } - public int getIndex() { - return _index; - } - public String getName() { - return _name; - } - public int getMinParams() { - return _minParams; - } - public int getMaxParams() { - return _maxParams; - } - public boolean hasFixedArgsLength() { - return _minParams == _maxParams; - } - public byte getReturnClassCode() { - return _returnClassCode; - } - public byte[] getParameterClassCodes() { - return _parameterClassCodes.clone(); - } - /** - * Some varags functions (like VLOOKUP) have a specific limit to the number of arguments that - * can be passed. Other functions (like SUM) don't have such a limit. For those functions, - * the spreadsheet version determines the maximum number of arguments that can be passed. - * @return true if this function can the maximum number of arguments allowable by - * the {@link org.apache.poi.ss.SpreadsheetVersion} - */ - public boolean hasUnlimitedVarags() { - return FUNCTION_MAX_PARAMS == _maxParams; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_index).append(" ").append(_name); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java b/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java deleted file mode 100644 index 02a9267df..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java +++ /dev/null @@ -1,203 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.function; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Pattern; - -import org.apache.poi.ss.formula.ptg.Ptg; - -/** - * Converts the text meta-data file into a FunctionMetadataRegistry - * - * @author Josh Micich - */ -final class FunctionMetadataReader { - - private static final String METADATA_FILE_NAME = "functionMetadata.txt"; - - /** plain ASCII text metadata file uses three dots for ellipsis */ - private static final String ELLIPSIS = "..."; - - private static final Pattern TAB_DELIM_PATTERN = Pattern.compile("\t"); - private static final Pattern SPACE_DELIM_PATTERN = Pattern.compile(" "); - private static final byte[] EMPTY_BYTE_ARRAY = { }; - - private static final String[] DIGIT_ENDING_FUNCTION_NAMES = { - // Digits at the end of a function might be due to a left-over footnote marker. - // except in these cases - "LOG10", "ATAN2", "DAYS360", "SUMXMY2", "SUMX2MY2", "SUMX2PY2", - }; - private static final Set DIGIT_ENDING_FUNCTION_NAMES_SET = new HashSet(Arrays.asList(DIGIT_ENDING_FUNCTION_NAMES)); - - public static FunctionMetadataRegistry createRegistry() { - try { - InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME); - if (is == null) { - throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found"); - } - - try { - BufferedReader br; - try { - br = new BufferedReader(new InputStreamReader(is,"UTF-8")); - } catch(UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - - try { - FunctionDataBuilder fdb = new FunctionDataBuilder(400); - - while (true) { - String line = br.readLine(); - if (line == null) { - break; - } - if (line.length() < 1 || line.charAt(0) == '#') { - continue; - } - String trimLine = line.trim(); - if (trimLine.length() < 1) { - continue; - } - processLine(fdb, line); - } - - return fdb.build(); - } finally { - br.close(); - } - } finally { - is.close(); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static void processLine(FunctionDataBuilder fdb, String line) { - - String[] parts = TAB_DELIM_PATTERN.split(line, -2); - if(parts.length != 8) { - throw new RuntimeException("Bad line format '" + line + "' - expected 8 data fields"); - } - int functionIndex = parseInt(parts[0]); - String functionName = parts[1]; - int minParams = parseInt(parts[2]); - int maxParams = parseInt(parts[3]); - byte returnClassCode = parseReturnTypeCode(parts[4]); - byte[] parameterClassCodes = parseOperandTypeCodes(parts[5]); - // 6 isVolatile - boolean hasNote = parts[7].length() > 0; - - validateFunctionName(functionName); - // TODO - make POI use isVolatile - fdb.add(functionIndex, functionName, minParams, maxParams, - returnClassCode, parameterClassCodes, hasNote); - } - - - private static byte parseReturnTypeCode(String code) { - if(code.length() == 0) { - return Ptg.CLASS_REF; // happens for GETPIVOTDATA - } - return parseOperandTypeCode(code); - } - - private static byte[] parseOperandTypeCodes(String codes) { - if(codes.length() < 1) { - return EMPTY_BYTE_ARRAY; // happens for GETPIVOTDATA - } - if(isDash(codes)) { - // '-' means empty: - return EMPTY_BYTE_ARRAY; - } - String[] array = SPACE_DELIM_PATTERN.split(codes); - int nItems = array.length; - if(ELLIPSIS.equals(array[nItems-1])) { - // final ellipsis is optional, and ignored - // (all unspecified params are assumed to be the same as the last) - nItems --; - } - byte[] result = new byte[nItems]; - for (int i = 0; i < nItems; i++) { - result[i] = parseOperandTypeCode(array[i]); - } - return result; - } - - private static boolean isDash(String codes) { - if(codes.length() == 1) { - switch (codes.charAt(0)) { - case '-': - return true; - } - } - return false; - } - - private static byte parseOperandTypeCode(String code) { - if(code.length() != 1) { - throw new RuntimeException("Bad operand type code format '" + code + "' expected single char"); - } - switch(code.charAt(0)) { - case 'V': return Ptg.CLASS_VALUE; - case 'R': return Ptg.CLASS_REF; - case 'A': return Ptg.CLASS_ARRAY; - } - throw new IllegalArgumentException("Unexpected operand type code '" + code + "' (" + (int)code.charAt(0) + ")"); - } - - /** - * Makes sure that footnote digits from the original OOO document have not been accidentally - * left behind - */ - private static void validateFunctionName(String functionName) { - int len = functionName.length(); - int ix = len - 1; - if (!Character.isDigit(functionName.charAt(ix))) { - return; - } - while(ix >= 0) { - if (!Character.isDigit(functionName.charAt(ix))) { - break; - } - ix--; - } - if(DIGIT_ENDING_FUNCTION_NAMES_SET.contains(functionName)) { - return; - } - throw new RuntimeException("Invalid function name '" + functionName - + "' (is footnote number incorrectly appended)"); - } - - private static int parseInt(String valStr) { - try { - return Integer.parseInt(valStr); - } catch (NumberFormatException e) { - throw new RuntimeException("Value '" + valStr + "' could not be parsed as an integer"); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java b/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java deleted file mode 100644 index 34317fe6d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.function; - -import java.util.Map; -import java.util.Set; -/** - * Allows clients to get {@link FunctionMetadata} instances for any built-in function of Excel. - * - * @author Josh Micich - */ -public final class FunctionMetadataRegistry { - /** - * The name of the IF function (i.e. "IF"). Extracted as a constant for clarity. - */ - public static final String FUNCTION_NAME_IF = "IF"; - - public static final int FUNCTION_INDEX_IF = 1; - public static final short FUNCTION_INDEX_SUM = 4; - public static final int FUNCTION_INDEX_CHOOSE = 100; - public static final short FUNCTION_INDEX_INDIRECT = 148; - public static final short FUNCTION_INDEX_EXTERNAL = 255; - - private static FunctionMetadataRegistry _instance; - - private final FunctionMetadata[] _functionDataByIndex; - private final Map _functionDataByName; - - private static FunctionMetadataRegistry getInstance() { - if (_instance == null) { - _instance = FunctionMetadataReader.createRegistry(); - } - return _instance; - } - - /* package */ FunctionMetadataRegistry(FunctionMetadata[] functionDataByIndex, Map functionDataByName) { - _functionDataByIndex = (functionDataByIndex == null) ? null : functionDataByIndex.clone(); - _functionDataByName = functionDataByName; - } - - /* package */ Set getAllFunctionNames() { - return _functionDataByName.keySet(); - } - - - public static FunctionMetadata getFunctionByIndex(int index) { - return getInstance().getFunctionByIndexInternal(index); - } - - private FunctionMetadata getFunctionByIndexInternal(int index) { - return _functionDataByIndex[index]; - } - /** - * Resolves a built-in function index. - * @param name uppercase function name - * @return a negative value if the function name is not found. - * This typically occurs for external functions. - */ - public static short lookupIndexByName(String name) { - FunctionMetadata fd = getInstance().getFunctionByNameInternal(name); - if (fd == null) { - return -1; - } - return (short) fd.getIndex(); - } - - private FunctionMetadata getFunctionByNameInternal(String name) { - return _functionDataByName.get(name); - } - - - public static FunctionMetadata getFunctionByName(String name) { - return getInstance().getFunctionByNameInternal(name); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Address.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Address.java deleted file mode 100644 index e0680dff6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Address.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.formula.eval.*; -import org.apache.poi.ss.util.CellReference; - -/** - * Creates a text reference as text, given specified row and column numbers. - * - * @author Aniket Banerjee (banerjee@google.com) - */ -public class Address implements Function { - public static final int REF_ABSOLUTE = 1; - public static final int REF_ROW_ABSOLUTE_COLUMN_RELATIVE = 2; - public static final int REF_ROW_RELATIVE_RELATIVE_ABSOLUTE = 3; - public static final int REF_RELATIVE = 4; - - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, - int srcColumnIndex) { - if(args.length < 2 || args.length > 5) { - return ErrorEval.VALUE_INVALID; - } - try { - boolean pAbsRow, pAbsCol; - - int row = (int)NumericFunction.singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex); - int col = (int)NumericFunction.singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex); - - int refType; - if (args.length > 2 && args[2] != MissingArgEval.instance) { - refType = (int)NumericFunction.singleOperandEvaluate(args[2], srcRowIndex, srcColumnIndex); - } else { - refType = REF_ABSOLUTE; // this is also the default if parameter is not given - } - switch (refType){ - case REF_ABSOLUTE: - pAbsRow = true; - pAbsCol = true; - break; - case REF_ROW_ABSOLUTE_COLUMN_RELATIVE: - pAbsRow = true; - pAbsCol = false; - break; - case REF_ROW_RELATIVE_RELATIVE_ABSOLUTE: - pAbsRow = false; - pAbsCol = true; - break; - case REF_RELATIVE: - pAbsRow = false; - pAbsCol = false; - break; - default: - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - -// boolean a1; -// if(args.length > 3){ -// ValueEval ve = OperandResolver.getSingleValue(args[3], srcRowIndex, srcColumnIndex); -// // TODO R1C1 style is not yet supported -// a1 = ve == MissingArgEval.instance ? true : OperandResolver.coerceValueToBoolean(ve, false); -// } else { -// a1 = true; -// } - - String sheetName; - if(args.length == 5){ - ValueEval ve = OperandResolver.getSingleValue(args[4], srcRowIndex, srcColumnIndex); - sheetName = ve == MissingArgEval.instance ? null : OperandResolver.coerceValueToString(ve); - } else { - sheetName = null; - } - - CellReference ref = new CellReference(row - 1, col - 1, pAbsRow, pAbsCol); - StringBuffer sb = new StringBuffer(32); - if(sheetName != null) { - SheetNameFormatter.appendFormat(sb, sheetName); - sb.append('!'); - } - sb.append(ref.formatAsString()); - - return new StringEval(sb.toString()); - - } catch (EvaluationException e){ - return e.getErrorEval(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/AggregateFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/AggregateFunction.java deleted file mode 100644 index 644086d31..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/AggregateFunction.java +++ /dev/null @@ -1,260 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public abstract class AggregateFunction extends MultiOperandNumericFunction { - - private static final class LargeSmall extends Fixed2ArgFunction { - private final boolean _isLarge; - protected LargeSmall(boolean isLarge) { - _isLarge = isLarge; - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1) { - double dn; - try { - ValueEval ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex); - dn = OperandResolver.coerceValueToDouble(ve1); - } catch (EvaluationException e1) { - // all errors in the second arg translate to #VALUE! - return ErrorEval.VALUE_INVALID; - } - // weird Excel behaviour on second arg - if (dn < 1.0) { - // values between 0.0 and 1.0 result in #NUM! - return ErrorEval.NUM_ERROR; - } - // all other values are rounded up to the next integer - int k = (int) Math.ceil(dn); - - double result; - try { - double[] ds = ValueCollector.collectValues(arg0); - if (k > ds.length) { - return ErrorEval.NUM_ERROR; - } - result = _isLarge ? StatsLib.kthLargest(ds, k) : StatsLib.kthSmallest(ds, k); - NumericFunction.checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return new NumberEval(result); - } - } - - /** - * Returns the k-th percentile of values in a range. You can use this function to establish a threshold of - * acceptance. For example, you can decide to examine candidates who score above the 90th percentile. - * - * PERCENTILE(array,k) - * Array is the array or range of data that defines relative standing. - * K is the percentile value in the range 0..1, inclusive. - * - * Remarks - *
          - *
        • if array is empty or contains more than 8,191 data points, PERCENTILE returns the #NUM! error value.
        • - *
        • If k is nonnumeric, PERCENTILE returns the #VALUE! error value.
        • - *
        • If k is < 0 or if k > 1, PERCENTILE returns the #NUM! error value.
        • - *
        • If k is not a multiple of 1/(n - 1), PERCENTILE interpolates to determine the value at the k-th percentile.
        • - *
        - */ - private static final class Percentile extends Fixed2ArgFunction { - - protected Percentile() { - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1) { - double dn; - try { - ValueEval ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex); - dn = OperandResolver.coerceValueToDouble(ve1); - } catch (EvaluationException e1) { - // all errors in the second arg translate to #VALUE! - return ErrorEval.VALUE_INVALID; - } - if (dn < 0 || dn > 1) { // has to be percentage - return ErrorEval.NUM_ERROR; - } - - double result; - try { - double[] ds = ValueCollector.collectValues(arg0); - int N = ds.length; - - if (N == 0 || N > 8191) { - return ErrorEval.NUM_ERROR; - } - - double n = (N - 1) * dn + 1; - if (n == 1d) { - result = StatsLib.kthSmallest(ds, 1); - } else if (Double.compare(n, N) == 0) { - result = StatsLib.kthLargest(ds, 1); - } else { - int k = (int) n; - double d = n - k; - result = StatsLib.kthSmallest(ds, k) + d - * (StatsLib.kthSmallest(ds, k + 1) - StatsLib.kthSmallest(ds, k)); - } - - NumericFunction.checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return new NumberEval(result); - } - } - - static final class ValueCollector extends MultiOperandNumericFunction { - private static final ValueCollector instance = new ValueCollector(); - public ValueCollector() { - super(false, false); - } - public static double[] collectValues(ValueEval...operands) throws EvaluationException { - return instance.getNumberArray(operands); - } - protected double evaluate(double[] values) { - throw new IllegalStateException("should not be called"); - } - } - - protected AggregateFunction() { - super(false, false); - } - - /** - * Create an instance to use in the {@link Subtotal} function. - * - *

        - * If there are other subtotals within argument refs (or nested subtotals), - * these nested subtotals are ignored to avoid double counting. - *

        - * - * @param func the function to wrap - * @return wrapped instance. The actual math is delegated to the argument function. - */ - /*package*/ static Function subtotalInstance(Function func) { - final AggregateFunction arg = (AggregateFunction)func; - return new AggregateFunction() { - @Override - protected double evaluate(double[] values) throws EvaluationException { - return arg.evaluate(values); - } - - /** - * ignore nested subtotals. - */ - @Override - public boolean isSubtotalCounted(){ - return false; - } - - }; - } - - public static final Function AVEDEV = new AggregateFunction() { - protected double evaluate(double[] values) { - return StatsLib.avedev(values); - } - }; - public static final Function AVERAGE = new AggregateFunction() { - protected double evaluate(double[] values) throws EvaluationException { - if (values.length < 1) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return MathX.average(values); - } - }; - public static final Function DEVSQ = new AggregateFunction() { - protected double evaluate(double[] values) { - return StatsLib.devsq(values); - } - }; - public static final Function LARGE = new LargeSmall(true); - public static final Function MAX = new AggregateFunction() { - protected double evaluate(double[] values) { - return values.length > 0 ? MathX.max(values) : 0; - } - }; - public static final Function MEDIAN = new AggregateFunction() { - protected double evaluate(double[] values) { - return StatsLib.median(values); - } - }; - public static final Function MIN = new AggregateFunction() { - protected double evaluate(double[] values) { - return values.length > 0 ? MathX.min(values) : 0; - } - }; - - public static final Function PERCENTILE = new Percentile(); - - public static final Function PRODUCT = new AggregateFunction() { - protected double evaluate(double[] values) { - return MathX.product(values); - } - }; - public static final Function SMALL = new LargeSmall(false); - public static final Function STDEV = new AggregateFunction() { - protected double evaluate(double[] values) throws EvaluationException { - if (values.length < 1) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return StatsLib.stdev(values); - } - }; - public static final Function SUM = new AggregateFunction() { - protected double evaluate(double[] values) { - return MathX.sum(values); - } - }; - public static final Function SUMSQ = new AggregateFunction() { - protected double evaluate(double[] values) { - return MathX.sumsq(values); - } - }; - public static final Function VAR = new AggregateFunction() { - protected double evaluate(double[] values) throws EvaluationException { - if (values.length < 1) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return StatsLib.var(values); - } - }; - public static final Function VARP = new AggregateFunction() { - protected double evaluate(double[] values) throws EvaluationException { - if (values.length < 1) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return StatsLib.varp(values); - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/BaseNumberUtils.java b/trunk/src/java/org/apache/poi/ss/formula/functions/BaseNumberUtils.java deleted file mode 100644 index 6130311d6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/BaseNumberUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.functions; - -/** - *

        Some utils for converting from and to any base

        - * - * @author cedric dot walter @ gmail dot com - */ -public class BaseNumberUtils { - - - public static double convertToDecimal(String value, int base, int maxNumberOfPlaces) throws IllegalArgumentException { - if (value == null || value.length() == 0) { - return 0.0; - } - - long stringLength = value.length(); - if (stringLength > maxNumberOfPlaces) { - throw new IllegalArgumentException(); - } - - double decimalValue = 0.0; - - long signedDigit = 0; - boolean hasSignedDigit = true; - char[] characters = value.toCharArray(); - for (char character : characters) { - long digit; - - if ('0' <= character && character <= '9') { - digit = character - '0'; - } else if ('A' <= character && character <= 'Z') { - digit = 10 + (character - 'A'); - } else if ('a' <= character && character <= 'z') { - digit = 10 + (character - 'a'); - } else { - digit = base; - } - - if (digit < base) { - if (hasSignedDigit) { - hasSignedDigit = false; - signedDigit = digit; - } - decimalValue = decimalValue * base + digit; - } else { - throw new IllegalArgumentException("character not allowed"); - } - } - - boolean isNegative = (!hasSignedDigit && stringLength == maxNumberOfPlaces && (signedDigit >= base / 2)); - if (isNegative) { - decimalValue = getTwoComplement(base, maxNumberOfPlaces, decimalValue); - decimalValue = decimalValue * -1.0; - } - - return decimalValue; - } - - private static double getTwoComplement(double base, double maxNumberOfPlaces, double decimalValue) { - return (Math.pow(base, maxNumberOfPlaces) - decimalValue); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java deleted file mode 100644 index cb206051c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel Bin2Dec() function.

        - *

        - * Syntax:
        Bin2Dec (number)
        - *

        - * Converts a binary number to decimal. - *

        - * Number is the binary number you want to convert. Number cannot contain more than 10 characters (10 bits). - * The most significant bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - *

        - * Remark - * If number is not a valid binary number, or if number contains more than 10 characters (10 bits), - * BIN2DEC returns the #NUM! error value. - * - * @author cedric dot walter @ gmail dot com - */ -public class Bin2Dec extends Fixed1ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Bin2Dec(); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE) { - final String number; - if (numberVE instanceof RefEval) { - RefEval re = (RefEval) numberVE; - number = OperandResolver.coerceValueToString(re.getInnerValueEval(re.getFirstSheetIndex())); - } else { - number = OperandResolver.coerceValueToString(numberVE); - } - if (number.length() > 10) { - return ErrorEval.NUM_ERROR; - } - - String unsigned; - - //If the leftmost bit is 0 -- number is positive. - boolean isPositive; - if (number.length() < 10) { - unsigned = number; - isPositive = true; - } else { - unsigned = number.substring(1); - isPositive = number.startsWith("0"); - } - - String value; - try { - if (isPositive) { - //bit9*2^8 + bit8*2^7 + bit7*2^6 + bit6*2^5 + bit5*2^4+ bit3*2^2+ bit2*2^1+ bit1*2^0 - int sum = getDecimalValue(unsigned); - value = String.valueOf(sum); - } else { - //The leftmost bit is 1 -- this is negative number - //Inverse bits [1-9] - String inverted = toggleBits(unsigned); - // Calculate decimal number - int sum = getDecimalValue(inverted); - - //Add 1 to obtained number - sum++; - - value = "-" + sum; - } - } catch (NumberFormatException e) { - return ErrorEval.NUM_ERROR; - } - - return new NumberEval(Long.parseLong(value)); - } - - private int getDecimalValue(String unsigned) { - int sum = 0; - int numBits = unsigned.length(); - int power = numBits - 1; - - for (int i = 0; i < numBits; i++) { - int bit = Integer.parseInt(unsigned.substring(i, i + 1)); - int term = (int) (bit * Math.pow(2, power)); - sum += term; - power--; - } - return sum; - } - - private static String toggleBits(String s) { - long i = Long.parseLong(s, 2); - long i2 = i ^ ((1L << s.length()) - 1); - String s2 = Long.toBinaryString(i2); - while (s2.length() < s.length()) s2 = '0' + s2; - return s2; - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java deleted file mode 100644 index 5d011e3b2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java +++ /dev/null @@ -1,159 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Here are the general rules concerning Boolean functions: - *

          - *
        1. Blanks are ignored (not either true or false)
        2. - *
        3. Strings are ignored if part of an area ref or cell ref, otherwise they must be 'true' or 'false'
        4. - *
        5. Numbers: 0 is false. Any other number is TRUE
        6. - *
        7. Areas: *all* cells in area are evaluated according to the above rules
        8. - *
        - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public abstract class BooleanFunction implements Function { - - public final ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) { - if (args.length < 1) { - return ErrorEval.VALUE_INVALID; - } - boolean boolResult; - try { - boolResult = calculate(args); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return BoolEval.valueOf(boolResult); - } - - private boolean calculate(ValueEval[] args) throws EvaluationException { - - boolean result = getInitialResultValue(); - boolean atleastOneNonBlank = false; - - /* - * Note: no short-circuit boolean loop exit because any ErrorEvals will override the result - */ - for (final ValueEval arg : args) { - Boolean tempVe; - if (arg instanceof TwoDEval) { - TwoDEval ae = (TwoDEval) arg; - int height = ae.getHeight(); - int width = ae.getWidth(); - for (int rrIx=0; rrIx= args.length) { - return ErrorEval.VALUE_INVALID; - } - ValueEval result = OperandResolver.getSingleValue(args[ix], srcRowIndex, srcColumnIndex); - if (result == MissingArgEval.instance) { - return BlankEval.instance; - } - return result; - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - public static int evaluateFirstArg(ValueEval arg0, int srcRowIndex, int srcColumnIndex) - throws EvaluationException { - ValueEval ev = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - return OperandResolver.coerceValueToInt(ev); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Code.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Code.java deleted file mode 100644 index ee1622f58..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Code.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.*; - -/** - * Implementation for Excel CODE () function.

        - *

        - * Syntax:
        CODE (text )
        - *

        - * Returns a numeric code for the first character in a text string. The returned code corresponds to the character set used by your computer. - *

        - * text The text for which you want the code of the first character. - * - * @author cedric dot walter @ gmail dot com - */ -public class Code extends Fixed1ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval textArg) { - - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(textArg, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String text = OperandResolver.coerceValueToString(veText1); - - if (text.length() == 0) { - return ErrorEval.VALUE_INVALID; - } - - int code = text.charAt(0); - - return new StringEval(String.valueOf(code)); - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Column.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Column.java deleted file mode 100644 index 06e629db0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Column.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -public final class Column implements Function0Arg, Function1Arg { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) { - return new NumberEval(srcColumnIndex+1); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - int rnum; - - if (arg0 instanceof AreaEval) { - rnum = ((AreaEval) arg0).getFirstColumn(); - } else if (arg0 instanceof RefEval) { - rnum = ((RefEval) arg0).getColumn(); - } else { - // anything else is not valid argument - return ErrorEval.VALUE_INVALID; - } - - return new NumberEval(rnum + 1); - } - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 1: - return evaluate(srcRowIndex, srcColumnIndex, args[0]); - case 0: - return new NumberEval(srcColumnIndex+1); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Columns.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Columns.java deleted file mode 100644 index 3c1fdc54a..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Columns.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.TwoDEval; - -/** - * Implementation for Excel COLUMNS function. - * - * @author Josh Micich - */ -public final class Columns extends Fixed1ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - - int result; - if (arg0 instanceof TwoDEval) { - result = ((TwoDEval) arg0).getWidth(); - } else if (arg0 instanceof RefEval) { - result = 1; - } else { // anything else is not valid argument - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(result); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Complex.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Complex.java deleted file mode 100644 index 628a2670f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Complex.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Locale; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel COMPLEX () function.

        - *

        - * Syntax:
        COMPLEX (real_num,i_num,suffix )
        - *

        - * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj. - *

        - *

        - * All complex number functions accept "i" and "j" for suffix, but neither "I" nor "J". - * Using uppercase results in the #VALUE! error value. All functions that accept two - * or more complex numbers require that all suffixes match. - *

        - * real_num The real coefficient of the complex number. - * If this argument is nonnumeric, this function returns the #VALUE! error value. - *

        - *

        - * i_num The imaginary coefficient of the complex number. - * If this argument is nonnumeric, this function returns the #VALUE! error value. - *

        - *

        - * suffix The suffix for the imaginary component of the complex number. - *

          - *
        • If omitted, suffix is assumed to be "i".
        • - *
        • If suffix is neither "i" nor "j", COMPLEX returns the #VALUE! error value.
        • - *
        - * - * @author cedric dot walter @ gmail dot com - */ -public class Complex extends Var2or3ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Complex(); - - public static final String DEFAULT_SUFFIX = "i"; - public static final String SUPPORTED_SUFFIX = "j"; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval real_num, ValueEval i_num) { - return this.evaluate(srcRowIndex, srcColumnIndex, real_num, i_num, new StringEval(DEFAULT_SUFFIX)); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval real_num, ValueEval i_num, ValueEval suffix) { - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(real_num, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - double realNum = 0; - try { - realNum = OperandResolver.coerceValueToDouble(veText1); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - ValueEval veINum; - try { - veINum = OperandResolver.getSingleValue(i_num, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - double realINum = 0; - try { - realINum = OperandResolver.coerceValueToDouble(veINum); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - String suffixValue = OperandResolver.coerceValueToString(suffix); - if (suffixValue.length() == 0) { - suffixValue = DEFAULT_SUFFIX; - } - if (suffixValue.equals(DEFAULT_SUFFIX.toUpperCase(Locale.ROOT)) || - suffixValue.equals(SUPPORTED_SUFFIX.toUpperCase(Locale.ROOT))) { - return ErrorEval.VALUE_INVALID; - } - if (!(suffixValue.equals(DEFAULT_SUFFIX) || suffixValue.equals(SUPPORTED_SUFFIX))) { - return ErrorEval.VALUE_INVALID; - } - - StringBuffer strb = new StringBuffer(""); - if (realNum != 0) { - if (isDoubleAnInt(realNum)) { - strb.append((int)realNum); - } else { - strb.append(realNum); - } - } - if (realINum != 0) { - if (strb.length() != 0) { - if (realINum > 0) { - strb.append("+"); - } - } - - if (realINum != 1 && realINum != -1) { - if (isDoubleAnInt(realINum)) { - strb.append((int)realINum); - } else { - strb.append(realINum); - } - } - - strb.append(suffixValue); - } - - return new StringEval(strb.toString()); - } - - private boolean isDoubleAnInt(double number) { - return (number == Math.floor(number)) && !Double.isInfinite(number); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length == 2) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]); - } - if (args.length == 3) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1], args[2]); - } - - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Count.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Count.java deleted file mode 100644 index b8de432ed..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Count.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate; -import org.apache.poi.ss.formula.functions.CountUtils.I_MatchAreaPredicate; - -/** - * Counts the number of cells that contain numeric data within - * the list of arguments. - * - * Excel Syntax - * COUNT(value1,value2,...) - * Value1, value2, ... are 1 to 30 arguments representing the values or ranges to be counted. - * - * TODO: Check this properly matches excel on edge cases - * like formula cells, error cells etc - */ -public final class Count implements Function { - private final I_MatchPredicate _predicate; - - public Count(){ - _predicate = defaultPredicate; - } - - private Count(I_MatchPredicate criteriaPredicate){ - _predicate = criteriaPredicate; - } - - public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - int nArgs = args.length; - if (nArgs < 1) { - // too few arguments - return ErrorEval.VALUE_INVALID; - } - - if (nArgs > 30) { - // too many arguments - return ErrorEval.VALUE_INVALID; - } - - int temp = 0; - - for(int i=0; i - * If there are other subtotals within argument refs (or nested subtotals), - * these nested subtotals are ignored to avoid double counting. - *

        - * - * @see Subtotal - */ - public static Count subtotalInstance() { - return new Count(subtotalPredicate ); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/CountUtils.java b/trunk/src/java/org/apache/poi/ss/formula/functions/CountUtils.java deleted file mode 100644 index 5dae60f94..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/CountUtils.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.ThreeDEval; -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Common logic for COUNT, COUNTA and COUNTIF - * - * @author Josh Micich - */ -final class CountUtils { - - private CountUtils() { - // no instances of this class - } - - /** - * Common interface for the matching criteria. - */ - public interface I_MatchPredicate { - boolean matches(ValueEval x); - } - public interface I_MatchAreaPredicate extends I_MatchPredicate { - boolean matches(TwoDEval x, int rowIndex, int columnIndex); - } - - /** - * @return the number of evaluated cells in the range that match the specified criteria - */ - public static int countMatchingCellsInArea(ThreeDEval areaEval, I_MatchPredicate criteriaPredicate) { - int result = 0; - - final int firstSheetIndex = areaEval.getFirstSheetIndex(); - final int lastSheetIndex = areaEval.getLastSheetIndex(); - for (int sIx = firstSheetIndex; sIx <= lastSheetIndex; sIx++) { - int height = areaEval.getHeight(); - int width = areaEval.getWidth(); - for (int rrIx=0; rrIx 30) { - // too many arguments - return ErrorEval.VALUE_INVALID; - } - - int temp = 0; - - for(int i=0; i - * Syntax: COUNTBLANK ( range ) - * - * - *
        range   is the range of cells to count blanks
        - *

        - * - * @author Mads Mohr Christensen - */ -public final class Countblank extends Fixed1ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - - double result; - if (arg0 instanceof RefEval) { - result = CountUtils.countMatchingCellsInRef((RefEval) arg0, predicate); - } else if (arg0 instanceof ThreeDEval) { - result = CountUtils.countMatchingCellsInArea((ThreeDEval) arg0, predicate); - } else { - throw new IllegalArgumentException("Bad range arg type (" + arg0.getClass().getName() + ")"); - } - return new NumberEval(result); - } - - private static final I_MatchPredicate predicate = new I_MatchPredicate() { - - public boolean matches(ValueEval valueEval) { - // Note - only BlankEval counts - return valueEval == BlankEval.instance || - // see https://support.office.com/en-us/article/COUNTBLANK-function-6a92d772-675c-4bee-b346-24af6bd3ac22 - // "Cells with formulas that return "" (empty text) are also counted." - (valueEval instanceof StringEval && "".equals(((StringEval)valueEval).getStringValue())); - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Countif.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Countif.java deleted file mode 100644 index f2a7ebe3a..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Countif.java +++ /dev/null @@ -1,562 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.regex.Pattern; - -import org.apache.poi.ss.formula.ThreeDEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate; -import org.apache.poi.ss.usermodel.FormulaError; - -/** - * Implementation for the function COUNTIF - *

        - * Syntax: COUNTIF ( range, criteria ) - * - * - * - *
        range   is the range of cells to be counted based on the criteria
        criteriais used to determine which cells to count
        - *

        - */ -public final class Countif extends Fixed2ArgFunction { - - private static final class CmpOp { - public static final int NONE = 0; - public static final int EQ = 1; - public static final int NE = 2; - public static final int LE = 3; - public static final int LT = 4; - public static final int GT = 5; - public static final int GE = 6; - - public static final CmpOp OP_NONE = op("", NONE); - public static final CmpOp OP_EQ = op("=", EQ); - public static final CmpOp OP_NE = op("<>", NE); - public static final CmpOp OP_LE = op("<=", LE); - public static final CmpOp OP_LT = op("<", LT); - public static final CmpOp OP_GT = op(">", GT); - public static final CmpOp OP_GE = op(">=", GE); - private final String _representation; - private final int _code; - - private static CmpOp op(String rep, int code) { - return new CmpOp(rep, code); - } - private CmpOp(String representation, int code) { - _representation = representation; - _code = code; - } - /** - * @return number of characters used to represent this operator - */ - public int getLength() { - return _representation.length(); - } - public int getCode() { - return _code; - } - public static CmpOp getOperator(String value) { - int len = value.length(); - if (len < 1) { - return OP_NONE; - } - - char firstChar = value.charAt(0); - - switch(firstChar) { - case '=': - return OP_EQ; - case '>': - if (len > 1) { - switch(value.charAt(1)) { - case '=': - return OP_GE; - } - } - return OP_GT; - case '<': - if (len > 1) { - switch(value.charAt(1)) { - case '=': - return OP_LE; - case '>': - return OP_NE; - } - } - return OP_LT; - } - return OP_NONE; - } - public boolean evaluate(boolean cmpResult) { - switch (_code) { - case NONE: - case EQ: - return cmpResult; - case NE: - return !cmpResult; - } - throw new RuntimeException("Cannot call boolean evaluate on non-equality operator '" - + _representation + "'"); - } - public boolean evaluate(int cmpResult) { - switch (_code) { - case NONE: - case EQ: - return cmpResult == 0; - case NE: return cmpResult != 0; - case LT: return cmpResult < 0; - case LE: return cmpResult <= 0; - case GT: return cmpResult > 0; - case GE: return cmpResult >= 0; - } - throw new RuntimeException("Cannot call boolean evaluate on non-equality operator '" - + _representation + "'"); - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()); - sb.append(" [").append(_representation).append("]"); - return sb.toString(); - } - public String getRepresentation() { - return _representation; - } - } - - private static abstract class MatcherBase implements I_MatchPredicate { - private final CmpOp _operator; - - MatcherBase(CmpOp operator) { - _operator = operator; - } - protected final int getCode() { - return _operator.getCode(); - } - protected final boolean evaluate(int cmpResult) { - return _operator.evaluate(cmpResult); - } - protected final boolean evaluate(boolean cmpResult) { - return _operator.evaluate(cmpResult); - } - @Override - public final String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_operator.getRepresentation()); - sb.append(getValueText()); - sb.append("]"); - return sb.toString(); - } - protected abstract String getValueText(); - } - - private static final class NumberMatcher extends MatcherBase { - - private final double _value; - - public NumberMatcher(double value, CmpOp operator) { - super(operator); - _value = value; - } - @Override - protected String getValueText() { - return String.valueOf(_value); - } - - public boolean matches(ValueEval x) { - double testValue; - if(x instanceof StringEval) { - // if the target(x) is a string, but parses as a number - // it may still count as a match, only for the equality operator - switch (getCode()) { - case CmpOp.EQ: - case CmpOp.NONE: - break; - case CmpOp.NE: - // Always matches (inconsistent with above two cases). - // for example '<>123' matches '123', '4', 'abc', etc - return true; - default: - // never matches (also inconsistent with above three cases). - // for example '>5' does not match '6', - return false; - } - StringEval se = (StringEval)x; - Double val = OperandResolver.parseDouble(se.getStringValue()); - if(val == null) { - // x is text that is not a number - return false; - } - return _value == val.doubleValue(); - } else if((x instanceof NumberEval)) { - NumberEval ne = (NumberEval) x; - testValue = ne.getNumberValue(); - } else if((x instanceof BlankEval)) { - switch (getCode()) { - case CmpOp.NE: - // Excel counts blank values in range as not equal to any value. See Bugzilla 51498 - return true; - default: - return false; - } - } else { - return false; - } - return evaluate(Double.compare(testValue, _value)); - } - } - private static final class BooleanMatcher extends MatcherBase { - - private final int _value; - - public BooleanMatcher(boolean value, CmpOp operator) { - super(operator); - _value = boolToInt(value); - } - @Override - protected String getValueText() { - return _value == 1 ? "TRUE" : "FALSE"; - } - - private static int boolToInt(boolean value) { - return value ? 1 : 0; - } - - public boolean matches(ValueEval x) { - int testValue; - if(x instanceof StringEval) { - if (true) { // change to false to observe more intuitive behaviour - // Note - Unlike with numbers, it seems that COUNTIF never matches - // boolean values when the target(x) is a string - return false; - } - @SuppressWarnings("unused") - StringEval se = (StringEval)x; - Boolean val = parseBoolean(se.getStringValue()); - if(val == null) { - // x is text that is not a boolean - return false; - } - testValue = boolToInt(val.booleanValue()); - } else if((x instanceof BoolEval)) { - BoolEval be = (BoolEval) x; - testValue = boolToInt(be.getBooleanValue()); - } else if((x instanceof BlankEval)) { - switch (getCode()) { - case CmpOp.NE: - // Excel counts blank values in range as not equal to any value. See Bugzilla 51498 - return true; - default: - return false; - } - } else if((x instanceof NumberEval)) { - switch (getCode()) { - case CmpOp.NE: - // not-equals comparison of a number to boolean always returnes false - return true; - default: - return false; - } - } else { - return false; - } - return evaluate(testValue - _value); - } - } - public static final class ErrorMatcher extends MatcherBase { - - private final int _value; - - public ErrorMatcher(int errorCode, CmpOp operator) { - super(operator); - _value = errorCode; - } - @Override - protected String getValueText() { - return FormulaError.forInt(_value).getString(); - } - - public boolean matches(ValueEval x) { - if(x instanceof ErrorEval) { - int testValue = ((ErrorEval)x).getErrorCode(); - return evaluate(testValue - _value); - } - return false; - } - - public int getValue() { - return _value; - } - } - public static final class StringMatcher extends MatcherBase { - - private final String _value; - private final Pattern _pattern; - - public StringMatcher(String value, CmpOp operator) { - super(operator); - _value = value; - switch(operator.getCode()) { - case CmpOp.NONE: - case CmpOp.EQ: - case CmpOp.NE: - _pattern = getWildCardPattern(value); - break; - default: - // pattern matching is never used for < > <= => - _pattern = null; - } - } - @Override - protected String getValueText() { - if (_pattern == null) { - return _value; - } - return _pattern.pattern(); - } - - public boolean matches(ValueEval x) { - if (x instanceof BlankEval) { - switch(getCode()) { - case CmpOp.NONE: - case CmpOp.EQ: - return _value.length() == 0; - case CmpOp.NE: - // pred '<>' matches empty string but not blank cell - // pred '<>ABC' matches blank and 'not ABC' - return _value.length() != 0; - } - // no other criteria matches a blank cell - return false; - } - if(!(x instanceof StringEval)) { - // must always be string - // even if match str is wild, but contains only digits - // e.g. '4*7', NumberEval(4567) does not match - return false; - } - String testedValue = ((StringEval) x).getStringValue(); - if (testedValue.length() < 1 && _value.length() < 1) { - // odd case: criteria '=' behaves differently to criteria '' - - switch(getCode()) { - case CmpOp.NONE: return true; - case CmpOp.EQ: return false; - case CmpOp.NE: return true; - } - return false; - } - if (_pattern != null) { - return evaluate(_pattern.matcher(testedValue).matches()); - } - // String criteria in COUNTIF are case insensitive: - // for example, the string "apples" and the string "APPLES" will match the same cells. - return evaluate(testedValue.compareToIgnoreCase(_value)); - } - /** - * Translates Excel countif wildcard strings into java regex strings - * @return null if the specified value contains no special wildcard characters. - */ - public static Pattern getWildCardPattern(String value) { - int len = value.length(); - StringBuffer sb = new StringBuffer(len); - boolean hasWildCard = false; - for(int i=0; inull if the arg evaluates to blank. - */ - /* package */ static I_MatchPredicate createCriteriaPredicate(ValueEval arg, int srcRowIndex, int srcColumnIndex) { - - ValueEval evaluatedCriteriaArg = evaluateCriteriaArg(arg, srcRowIndex, srcColumnIndex); - - if(evaluatedCriteriaArg instanceof NumberEval) { - return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue(), CmpOp.OP_NONE); - } - if(evaluatedCriteriaArg instanceof BoolEval) { - return new BooleanMatcher(((BoolEval)evaluatedCriteriaArg).getBooleanValue(), CmpOp.OP_NONE); - } - - if(evaluatedCriteriaArg instanceof StringEval) { - return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg); - } - if(evaluatedCriteriaArg instanceof ErrorEval) { - return new ErrorMatcher(((ErrorEval)evaluatedCriteriaArg).getErrorCode(), CmpOp.OP_NONE); - } - if(evaluatedCriteriaArg == BlankEval.instance) { - return null; - } - throw new RuntimeException("Unexpected type for criteria (" - + evaluatedCriteriaArg.getClass().getName() + ")"); - } - - /** - * - * @return the de-referenced criteria arg (possibly {@link ErrorEval}) - */ - private static ValueEval evaluateCriteriaArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) { - try { - return OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - /** - * When the second argument is a string, many things are possible - */ - private static I_MatchPredicate createGeneralMatchPredicate(StringEval stringEval) { - String value = stringEval.getStringValue(); - CmpOp operator = CmpOp.getOperator(value); - value = value.substring(operator.getLength()); - - Boolean booleanVal = parseBoolean(value); - if(booleanVal != null) { - return new BooleanMatcher(booleanVal.booleanValue(), operator); - } - - Double doubleVal = OperandResolver.parseDouble(value); - if(doubleVal != null) { - return new NumberMatcher(doubleVal.doubleValue(), operator); - } - ErrorEval ee = parseError(value); - if (ee != null) { - return new ErrorMatcher(ee.getErrorCode(), operator); - } - - //else - just a plain string with no interpretation. - return new StringMatcher(value, operator); - } - private static ErrorEval parseError(String value) { - if (value.length() < 4 || value.charAt(0) != '#') { - return null; - } - if (value.equals("#NULL!")) return ErrorEval.NULL_INTERSECTION; - if (value.equals("#DIV/0!")) return ErrorEval.DIV_ZERO; - if (value.equals("#VALUE!")) return ErrorEval.VALUE_INVALID; - if (value.equals("#REF!")) return ErrorEval.REF_INVALID; - if (value.equals("#NAME?")) return ErrorEval.NAME_INVALID; - if (value.equals("#NUM!")) return ErrorEval.NUM_ERROR; - if (value.equals("#N/A")) return ErrorEval.NA; - - return null; - } - /** - * Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers. - * @return null to represent blank values - */ - /* package */ static Boolean parseBoolean(String strRep) { - if (strRep.length() < 1) { - return null; - } - switch(strRep.charAt(0)) { - case 't': - case 'T': - if("TRUE".equalsIgnoreCase(strRep)) { - return Boolean.TRUE; - } - break; - case 'f': - case 'F': - if("FALSE".equalsIgnoreCase(strRep)) { - return Boolean.FALSE; - } - break; - } - return null; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Countifs.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Countifs.java deleted file mode 100644 index 15e6a1521..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Countifs.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for the function COUNTIFS - *

        - * Syntax: COUNTIFS(criteria_range1, criteria1, [criteria_range2, criteria2]) - *

        - */ - -public class Countifs implements FreeRefFunction { - public static final FreeRefFunction instance = new Countifs(); - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - // https://support.office.com/en-us/article/COUNTIFS-function-dda3dc6e-f74e-4aee-88bc-aa8c2a866842?ui=en-US&rs=en-US&ad=US - // COUNTIFS(criteria_range1, criteria1, [criteria_range2, criteria2]...) - // need at least 2 arguments and need to have an even number of arguments (criteria_range1, criteria1 plus x*(criteria_range, criteria)) - if (args.length < 2 || args.length % 2 != 0) { - return ErrorEval.VALUE_INVALID; - } - - Double result = null; - // for each (criteria_range, criteria) pair - for (int i = 0; i < args.length; i += 2) { - ValueEval firstArg = args[i]; - ValueEval secondArg = args[i + 1]; - NumberEval evaluate = (NumberEval) new Countif().evaluate( - new ValueEval[] {firstArg, secondArg}, - ec.getRowIndex(), - ec.getColumnIndex()); - if (result == null) { - result = evaluate.getNumberValue(); - } else if (evaluate.getNumberValue() < result) { - result = evaluate.getNumberValue(); - } - } - return new NumberEval(result == null ? 0 : result); - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/DGet.java b/trunk/src/java/org/apache/poi/ss/formula/functions/DGet.java deleted file mode 100644 index 0bf9cc262..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/DGet.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation of the DGet function: - * Finds the value of a column in an area with given conditions. - */ -public final class DGet implements IDStarAlgorithm { - private ValueEval result; - - @Override - public boolean processMatch(ValueEval eval) { - if(result == null) // First match, just set the value. - { - result = eval; - } - else // There was a previous match, since there is only exactly one allowed, bail out. - { - result = ErrorEval.NUM_ERROR; - return false; - } - - return true; - } - - @Override - public ValueEval getResult() { - if(result == null) { - return ErrorEval.VALUE_INVALID; - } else if(result instanceof BlankEval) { - return ErrorEval.VALUE_INVALID; - } else - try { - if(OperandResolver.coerceValueToString(OperandResolver.getSingleValue(result, 0, 0)).equals("")) { - return ErrorEval.VALUE_INVALID; - } - else { - return result; - } - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/DMin.java b/trunk/src/java/org/apache/poi/ss/formula/functions/DMin.java deleted file mode 100644 index 61b75768c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/DMin.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.NumericValueEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation of the DMin function: - * Finds the minimum value of a column in an area with given conditions. - * - * TODO: - * - wildcards ? and * in string conditions - * - functions as conditions - */ -public final class DMin implements IDStarAlgorithm { - private ValueEval minimumValue; - - @Override - public boolean processMatch(ValueEval eval) { - if(eval instanceof NumericValueEval) { - if(minimumValue == null) { // First match, just set the value. - minimumValue = eval; - } else { // There was a previous match, find the new minimum. - double currentValue = ((NumericValueEval)eval).getNumberValue(); - double oldValue = ((NumericValueEval)minimumValue).getNumberValue(); - if(currentValue < oldValue) { - minimumValue = eval; - } - } - } - - return true; - } - - @Override - public ValueEval getResult() { - if(minimumValue == null) { - return NumberEval.ZERO; - } else { - return minimumValue; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java b/trunk/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java deleted file mode 100644 index 8418c4f74..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java +++ /dev/null @@ -1,403 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NotImplementedException; -import org.apache.poi.ss.formula.eval.NumericValueEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.StringValueEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.util.NumberComparer; - -/** - * This class performs a D* calculation. It takes an {@link IDStarAlgorithm} object and - * uses it for calculating the result value. Iterating a database and checking the - * entries against the set of conditions is done here. - * - * TODO: - * - wildcards ? and * in string conditions - * - functions as conditions - */ -public final class DStarRunner implements Function3Arg { - public enum DStarAlgorithmEnum { - DGET, - DMIN, - // DMAX, // DMAX is not yet implemented - } - private final DStarAlgorithmEnum algoType; - - public DStarRunner(DStarAlgorithmEnum algorithm) { - this.algoType = algorithm; - } - - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if(args.length == 3) { - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]); - } - else { - return ErrorEval.VALUE_INVALID; - } - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, - ValueEval database, ValueEval filterColumn, ValueEval conditionDatabase) { - // Input processing and error checks. - if(!(database instanceof AreaEval) || !(conditionDatabase instanceof AreaEval)) { - return ErrorEval.VALUE_INVALID; - } - AreaEval db = (AreaEval)database; - AreaEval cdb = (AreaEval)conditionDatabase; - - try { - filterColumn = OperandResolver.getSingleValue(filterColumn, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - int fc; - try { - fc = getColumnForName(filterColumn, db); - } - catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - if(fc == -1) { // column not found - return ErrorEval.VALUE_INVALID; - } - - // Create an algorithm runner. - IDStarAlgorithm algorithm = null; - switch(algoType) { - case DGET: algorithm = new DGet(); break; - case DMIN: algorithm = new DMin(); break; - default: - throw new IllegalStateException("Unexpected algorithm type " + algoType + " encountered."); - } - - // Iterate over all DB entries. - final int height = db.getHeight(); - for(int row = 1; row < height; ++row) { - boolean matches = true; - try { - matches = fullfillsConditions(db, row, cdb); - } - catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - // Filter each entry. - if(matches) { - ValueEval currentValueEval = resolveReference(db, row, fc); - // Pass the match to the algorithm and conditionally abort the search. - boolean shouldContinue = algorithm.processMatch(currentValueEval); - if(! shouldContinue) { - break; - } - } - } - - // Return the result of the algorithm. - return algorithm.getResult(); - } - - private enum operator { - largerThan, - largerEqualThan, - smallerThan, - smallerEqualThan, - equal - } - - /** - * - * - * @param nameValueEval Must not be a RefEval or AreaEval. Thus make sure resolveReference() is called on the value first! - * @param db Database - * @return Corresponding column number. - * @throws EvaluationException - */ - private static int getColumnForName(ValueEval nameValueEval, AreaEval db) - throws EvaluationException { - String name = OperandResolver.coerceValueToString(nameValueEval); - return getColumnForString(db, name); - } - - /** - * For a given database returns the column number for a column heading. - * - * @param db Database. - * @param name Column heading. - * @return Corresponding column number. - * @throws EvaluationException If it's not possible to turn all headings into strings. - */ - private static int getColumnForString(AreaEval db,String name) - throws EvaluationException { - int resultColumn = -1; - final int width = db.getWidth(); - for(int column = 0; column < width; ++column) { - ValueEval columnNameValueEval = resolveReference(db, 0, column); - if(columnNameValueEval instanceof BlankEval) { - continue; - } - if(columnNameValueEval instanceof ErrorEval) { - continue; - } - String columnName = OperandResolver.coerceValueToString(columnNameValueEval); - if(name.equals(columnName)) { - resultColumn = column; - break; - } - } - return resultColumn; - } - - /** - * Checks a row in a database against a condition database. - * - * @param db Database. - * @param row The row in the database to check. - * @param cdb The condition database to use for checking. - * @return Whether the row matches the conditions. - * @throws EvaluationException If references could not be resolved or comparison - * operators and operands didn't match. - */ - private static boolean fullfillsConditions(AreaEval db, int row, AreaEval cdb) - throws EvaluationException { - // Only one row must match to accept the input, so rows are ORed. - // Each row is made up of cells where each cell is a condition, - // all have to match, so they are ANDed. - final int height = cdb.getHeight(); - for(int conditionRow = 1; conditionRow < height; ++conditionRow) { - boolean matches = true; - final int width = cdb.getWidth(); - for(int column = 0; column < width; ++column) { // columns are ANDed - // Whether the condition column matches a database column, if not it's a - // special column that accepts formulas. - boolean columnCondition = true; - ValueEval condition = null; - - // The condition to apply. - condition = resolveReference(cdb, conditionRow, column); - - // If the condition is empty it matches. - if(condition instanceof BlankEval) - continue; - // The column in the DB to apply the condition to. - ValueEval targetHeader = resolveReference(cdb, 0, column); - - if(!(targetHeader instanceof StringValueEval)) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - - if (getColumnForName(targetHeader, db) == -1) - // No column found, it's again a special column that accepts formulas. - columnCondition = false; - - if(columnCondition == true) { // normal column condition - // Should not throw, checked above. - ValueEval value = resolveReference(db, row, getColumnForName(targetHeader, db)); - if(!testNormalCondition(value, condition)) { - matches = false; - break; - } - } else { // It's a special formula condition. - // TODO: Check whether the condition cell contains a formula and return #VALUE! if it doesn't. - if(OperandResolver.coerceValueToString(condition).isEmpty()) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - throw new NotImplementedException( - "D* function with formula conditions"); - } - } - if (matches == true) { - return true; - } - } - return false; - } - - /** - * Test a value against a simple (< > <= >= = starts-with) condition string. - * - * @param value The value to check. - * @param condition The condition to check for. - * @return Whether the condition holds. - * @throws EvaluationException If comparison operator and operands don't match. - */ - private static boolean testNormalCondition(ValueEval value, ValueEval condition) - throws EvaluationException { - if(condition instanceof StringEval) { - String conditionString = ((StringEval)condition).getStringValue(); - - if(conditionString.startsWith("<")) { // It's a ")) { // It's a >/>= condition. - String number = conditionString.substring(1); - if(number.startsWith("=")) { - number = number.substring(1); - return testNumericCondition(value, operator.largerEqualThan, number); - } else { - return testNumericCondition(value, operator.largerThan, number); - } - } - else if(conditionString.startsWith("=")) { // It's a = condition. - String stringOrNumber = conditionString.substring(1); - - if(stringOrNumber.isEmpty()) { - return value instanceof BlankEval; - } - // Distinguish between string and number. - boolean itsANumber = false; - try { - Integer.parseInt(stringOrNumber); - itsANumber = true; - } catch (NumberFormatException e) { // It's not an int. - try { - Double.parseDouble(stringOrNumber); - itsANumber = true; - } catch (NumberFormatException e2) { // It's a string. - itsANumber = false; - } - } - if(itsANumber) { - return testNumericCondition(value, operator.equal, stringOrNumber); - } else { // It's a string. - String valueString = value instanceof BlankEval ? "" : OperandResolver.coerceValueToString(value); - return stringOrNumber.equals(valueString); - } - } else { // It's a text starts-with condition. - if(conditionString.isEmpty()) { - return value instanceof StringEval; - } - else { - String valueString = value instanceof BlankEval ? "" : OperandResolver.coerceValueToString(value); - return valueString.startsWith(conditionString); - } - } - } - else if(condition instanceof NumericValueEval) { - double conditionNumber = ((NumericValueEval)condition).getNumberValue(); - Double valueNumber = getNumberFromValueEval(value); - if(valueNumber == null) { - return false; - } - - return conditionNumber == valueNumber; - } - else if(condition instanceof ErrorEval) { - if(value instanceof ErrorEval) { - return ((ErrorEval)condition).getErrorCode() == ((ErrorEval)value).getErrorCode(); - } - else { - return false; - } - } - else { - return false; - } - } - - /** - * Test whether a value matches a numeric condition. - * @param valueEval Value to check. - * @param op Comparator to use. - * @param condition Value to check against. - * @return whether the condition holds. - * @throws EvaluationException If it's impossible to turn the condition into a number. - */ - private static boolean testNumericCondition( - ValueEval valueEval, operator op, String condition) - throws EvaluationException { - // Construct double from ValueEval. - if(!(valueEval instanceof NumericValueEval)) - return false; - double value = ((NumericValueEval)valueEval).getNumberValue(); - - // Construct double from condition. - double conditionValue = 0.0; - try { - int intValue = Integer.parseInt(condition); - conditionValue = intValue; - } catch (NumberFormatException e) { // It's not an int. - try { - conditionValue = Double.parseDouble(condition); - } catch (NumberFormatException e2) { // It's not a double. - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - } - - int result = NumberComparer.compare(value, conditionValue); - switch(op) { - case largerThan: - return result > 0; - case largerEqualThan: - return result >= 0; - case smallerThan: - return result < 0; - case smallerEqualThan: - return result <= 0; - case equal: - return result == 0; - } - return false; // Can not be reached. - } - - private static Double getNumberFromValueEval(ValueEval value) { - if(value instanceof NumericValueEval) { - return ((NumericValueEval)value).getNumberValue(); - } - else if(value instanceof StringValueEval) { - String stringValue = ((StringValueEval)value).getStringValue(); - try { - return Double.parseDouble(stringValue); - } catch (NumberFormatException e2) { - return null; - } - } - else { - return null; - } - } - - /** - * Resolve a ValueEval that's in an AreaEval. - * - * @param db AreaEval from which the cell to resolve is retrieved. - * @param dbRow Relative row in the AreaEval. - * @param dbCol Relative column in the AreaEval. - * @return A ValueEval that is a NumberEval, StringEval, BoolEval, BlankEval or ErrorEval. - */ - private static ValueEval resolveReference(AreaEval db, int dbRow, int dbCol) { - try { - return OperandResolver.getSingleValue(db.getValue(dbRow, dbCol), db.getFirstRow()+dbRow, db.getFirstColumn()+dbCol); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/DateFunc.java b/trunk/src/java/org/apache/poi/ss/formula/functions/DateFunc.java deleted file mode 100644 index 7068bea93..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/DateFunc.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - - -/** - * Implementation for the Excel function DATE - */ -public final class DateFunc extends Fixed3ArgFunction { - public static final Function instance = new DateFunc(); - - private DateFunc() { - // no fields to initialise - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - double result; - try { - double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - double d2 = NumericFunction.singleOperandEvaluate(arg2, srcRowIndex, srcColumnIndex); - result = evaluate(getYear(d0), (int) (d1 - 1), (int) d2); - NumericFunction.checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - - /** - * Note - works with Java Calendar months, not Excel months - */ - private static double evaluate(int year, int month, int pDay) throws EvaluationException { - // We don't support negative years yet - if (year < 0) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - // Negative months are fairly easy - while (month < 0) { - year--; - month += 12; - } - // Negative days are handled by the Java Calendar - - // Excel has bugs around leap years in 1900, handle them - // Special case for the non-existant 1900 leap year - if (year == 1900 && month == Calendar.FEBRUARY && pDay == 29) { - return 60.0; - } - - // If they give a date in 1900 in Jan/Feb, with the days - // putting it past the leap year, adjust - int day = pDay; - if (year == 1900) { - if ((month == Calendar.JANUARY && day >= 60) || - (month == Calendar.FEBRUARY && day >= 30)) { - day--; - } - } - - // Turn this into a Java date - Calendar c = LocaleUtil.getLocaleCalendar(year, month, day); - - // Handle negative days of the week, that pull us across - // the 29th of Feb 1900 - if (pDay < 0 && c.get(Calendar.YEAR) == 1900 && - month > Calendar.FEBRUARY && - c.get(Calendar.MONTH) < Calendar.MARCH) { - c.add(Calendar.DATE, 1); - } - - // TODO Identify if we're doing 1900 or 1904 date windowing - boolean use1904windowing = false; - - // Have this Java date turned back into an Excel one - return DateUtil.getExcelDate(c.getTime(), use1904windowing); - } - - private static int getYear(double d) { - int year = (int)d; - - if (year < 0) { - return -1; - } - - return year < 1900 ? 1900 + year : year; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Days360.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Days360.java deleted file mode 100644 index 087e16b42..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Days360.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - -/** - *

        Calculates the number of days between two dates based on a 360-day year - * (twelve 30-day months), which is used in some accounting calculations. Use - * this function to help compute payments if your accounting system is based on - * twelve 30-day months.

        - * - * {@code DAYS360(start_date,end_date,[method])} - * - *

          - *
        • Start_date, end_date (required):
          - * The two dates between which you want to know the number of days.
          - * If start_date occurs after end_date, the DAYS360 function returns a negative number.
        • - * - *
        • Method (optional):
          - * A logical value that specifies whether to use the U.S. or European method in the calculation
        • - * - *
        • Method set to false or omitted:
          - * the DAYS360 function uses the U.S. (NASD) method. If the starting date is the 31st of a month, - * it becomes equal to the 30th of the same month. If the ending date is the 31st of a month and - * the starting date is earlier than the 30th of a month, the ending date becomes equal to the - * 1st of the next month, otherwise the ending date becomes equal to the 30th of the same month. - * The month February and leap years are handled in the following way:
          - * On a non-leap year the function {@code =DAYS360("2/28/93", "3/1/93", FALSE)} returns 1 day - * because the DAYS360 function ignores the extra days added to February.
          - * On a leap year the function {@code =DAYS360("2/29/96","3/1/96", FALSE)} returns 1 day for - * the same reason.
        • - * - *
        • Method Set to true:
          - * When you set the method parameter to TRUE, the DAYS360 function uses the European method. - * Starting dates or ending dates that occur on the 31st of a month become equal to the 30th of - * the same month. The month February and leap years are handled in the following way:
          - * On a non-leap year the function {@code =DAYS360("2/28/93", "3/1/93", TRUE)} returns - * 3 days because the DAYS360 function is counting the extra days added to February to give - * February 30 days.
          - * On a leap year the function {@code =DAYS360("2/29/96", "3/1/96", TRUE)} returns - * 2 days for the same reason.
        • - *
        - * - * @see DAYS360 Function Produces Different Values Depending on the Version of Excel - */ -public class Days360 extends Var2or3ArgFunction { - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - try { - double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - return new NumberEval(evaluate(d0, d1, false)); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - try { - double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - ValueEval ve = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex); - Boolean method = OperandResolver.coerceValueToBoolean(ve, false); - return new NumberEval(evaluate(d0, d1, method != null && method.booleanValue())); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private static double evaluate(double d0, double d1, boolean method) { - Calendar realStart = getDate(d0); - Calendar realEnd = getDate(d1); - int startingDate[] = getStartingDate(realStart, method); - int endingDate[] = getEndingDate(realEnd, startingDate, method); - return - (endingDate[0]*360+endingDate[1]*30+endingDate[2])- - (startingDate[0]*360+startingDate[1]*30+startingDate[2]); - } - - private static Calendar getDate(double date) { - Calendar processedDate = LocaleUtil.getLocaleCalendar(); - processedDate.setTime(DateUtil.getJavaDate(date, false)); - return processedDate; - } - - private static int[] getStartingDate(Calendar realStart, boolean method) { - int yyyy = realStart.get(Calendar.YEAR); - int mm = realStart.get(Calendar.MONTH); - int dd = Math.min(30, realStart.get(Calendar.DAY_OF_MONTH)); - - if (!method && isLastDayOfMonth(realStart)) dd = 30; - - return new int[]{yyyy,mm,dd}; - } - - private static int[] getEndingDate(Calendar realEnd, int startingDate[], boolean method) { - int yyyy = realEnd.get(Calendar.YEAR); - int mm = realEnd.get(Calendar.MONTH); - int dd = Math.min(30, realEnd.get(Calendar.DAY_OF_MONTH)); - - if (!method && realEnd.get(Calendar.DAY_OF_MONTH) == 31) { - if (startingDate[2] < 30) { - realEnd.set(Calendar.DAY_OF_MONTH, 1); - realEnd.add(Calendar.MONTH, 1); - yyyy = realEnd.get(Calendar.YEAR); - mm = realEnd.get(Calendar.MONTH); - dd = 1; - } else { - dd = 30; - } - } - - return new int[]{yyyy,mm,dd}; - } - - private static boolean isLastDayOfMonth(Calendar date) { - int dayOfMonth = date.get(Calendar.DAY_OF_MONTH); - int lastDayOfMonth = date.getActualMaximum(Calendar.DAY_OF_MONTH); - return (dayOfMonth == lastDayOfMonth); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Bin.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Bin.java deleted file mode 100644 index 21d8bcfaf..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Bin.java +++ /dev/null @@ -1,131 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel Bin2Dec() function.

        - *

        - * Syntax:
        Bin2Dec (number,[places] )
        - *

        - * Converts a decimal number to binary. - *

        - * The DEC2BIN function syntax has the following arguments: - *

          - *
        • Number Required. The decimal integer you want to convert. If number is negative, valid place values are ignored and DEC2BIN returns a 10-character (10-bit) binary number in which the most significant bit is the sign bit. The remaining 9 bits are magnitude bits. Negative numbers are represented using two's-complement notation.
        • - *
        • Places Optional. The number of characters to use. If places is omitted, DEC2BIN uses the minimum number of characters necessary. Places is useful for padding the return value with leading 0s (zeros).
        • - *
        - *

        - * Remarks - *

          - *
        • If number < -512 or if number > 511, DEC2BIN returns the #NUM! error value.
        • - *
        • If number is nonnumeric, DEC2BIN returns the #VALUE! error value.
        • - *
        • If DEC2BIN requires more than places characters, it returns the #NUM! error value.
        • - *
        • If places is not an integer, it is truncated.
        • - *
        • If places is nonnumeric, DEC2BIN returns the #VALUE! error value.
        • - *
        • If places is zero or negative, DEC2BIN returns the #NUM! error value.
        • - *
        - * - * @author cedric dot walter @ gmail dot com - */ -public class Dec2Bin extends Var1or2ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Dec2Bin(); - - private final static long MIN_VALUE = -512; - private final static long MAX_VALUE = 511; - private final static int DEFAULT_PLACES_VALUE = 10; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE, ValueEval placesVE) { - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(numberVE, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String strText1 = OperandResolver.coerceValueToString(veText1); - Double number = OperandResolver.parseDouble(strText1); - - //If this number argument is non numeric, this function returns the #VALUE! error value. - if (number == null) { - return ErrorEval.VALUE_INVALID; - } - - //If number < -512 or if number > 512, this function returns the #NUM! error value. - if (number.longValue() < MIN_VALUE || number.longValue() > MAX_VALUE) { - return ErrorEval.NUM_ERROR; - } - - int placesNumber; - if (number < 0 || placesVE == null) { - placesNumber = DEFAULT_PLACES_VALUE; - } else { - ValueEval placesValueEval; - try { - placesValueEval = OperandResolver.getSingleValue(placesVE, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String placesStr = OperandResolver.coerceValueToString(placesValueEval); - Double placesNumberDouble = OperandResolver.parseDouble(placesStr); - - //non numeric value - if (placesNumberDouble == null) { - return ErrorEval.VALUE_INVALID; - } - - //If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point. - placesNumber = placesNumberDouble.intValue(); - - if (placesNumber < 0 || placesNumber == 0) { - return ErrorEval.NUM_ERROR; - } - } - String binary = Integer.toBinaryString(number.intValue()); - - if (binary.length() > DEFAULT_PLACES_VALUE) { - binary = binary.substring(binary.length() - DEFAULT_PLACES_VALUE, binary.length()); - } - //If DEC2BIN requires more than places characters, it returns the #NUM! error value. - if (binary.length() > placesNumber) { - return ErrorEval.NUM_ERROR; - } - - return new StringEval(binary); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE) { - return this.evaluate(srcRowIndex, srcColumnIndex, numberVE, null); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length == 1) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } - if (args.length == 2) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]); - } - - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java deleted file mode 100644 index 6318f9846..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Locale; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; - -/** - * Implementation for Excel DELTA() function.

        - *

        - * Syntax:
        DEC2HEX (number,places )
        - *

        - * Converts a decimal number to hexadecimal. - * - * The decimal integer you want to convert. If number is negative, places is ignored - * and this function returns a 10-character (40-bit) hexadecimal number in which the - * most significant bit is the sign bit. The remaining 39 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * - *

          - *
        • If number < -549,755,813,888 or if number > 549,755,813,887, this function returns the #NUM! error value.
        • - *
        • If number is nonnumeric, this function returns the #VALUE! error value.
        • - *
        - * - *

        places

        - * - * The number of characters to use. The places argument is useful for padding the - * return value with leading 0s (zeros). - * - *
          - *
        • If this argument is omitted, this function uses the minimum number of characters necessary.
        • - *
        • If this function requires more than places characters, it returns the #NUM! error value.
        • - *
        • If this argument is non numeric, this function returns the #VALUE! error value.
        • - *
        • If this argument is negative, this function returns the #NUM! error value.
        • - *
        • If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point.
        • - *
        - */ -public final class Dec2Hex extends Var1or2ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Dec2Hex(); - - private final static long MIN_VALUE = Long.parseLong("-549755813888"); - private final static long MAX_VALUE = Long.parseLong("549755813887"); - private final static int DEFAULT_PLACES_VALUE = 10; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval number, ValueEval places) { - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(number, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String strText1 = OperandResolver.coerceValueToString(veText1); - Double number1 = OperandResolver.parseDouble(strText1); - - //If this number argument is non numeric, this function returns the #VALUE! error value. - if (number1 == null) { - return ErrorEval.VALUE_INVALID; - } - - //If number < -549,755,813,888 or if number > 549,755,813,887, this function returns the #NUM! error value. - if (number1.longValue() < MIN_VALUE || number1.longValue() > MAX_VALUE) { - return ErrorEval.NUM_ERROR; - } - - int placesNumber = 0; - if (number1 < 0) { - placesNumber = DEFAULT_PLACES_VALUE; - } - else if (places != null) { - ValueEval placesValueEval; - try { - placesValueEval = OperandResolver.getSingleValue(places, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String placesStr = OperandResolver.coerceValueToString(placesValueEval); - Double placesNumberDouble = OperandResolver.parseDouble(placesStr); - - //non numeric value - if (placesNumberDouble == null) { - return ErrorEval.VALUE_INVALID; - } - - //If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point. - placesNumber = placesNumberDouble.intValue(); - - if (placesNumber < 0) { - return ErrorEval.NUM_ERROR; - } - } - - String hex; - if (placesNumber != 0) { - hex = String.format(Locale.ROOT, "%0"+placesNumber+"X", number1.intValue()); - } - else { - hex = Long.toHexString(number1.longValue()); - } - - if (number1 < 0) { - hex = "FF"+ hex.substring(2); - } - - return new StringEval(hex.toUpperCase(Locale.ROOT)); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - return this.evaluate(srcRowIndex, srcColumnIndex, arg0, null); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length == 1) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } - if (args.length == 2) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java deleted file mode 100644 index 2f1bd88df..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; - -import java.math.BigDecimal; - -/** - * Implementation for Excel DELTA() function.

        - *

        - * Syntax:
        DELTA (number1,number2 )
        - *

        - * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. - * Use this function to filter a set of values. For example, by summing several DELTA functions - * you calculate the count of equal pairs. This function is also known as the Kronecker Delta function. - * - *

          - *
        • If number1 is nonnumeric, DELTA returns the #VALUE! error value.
        • - *
        • If number2 is nonnumeric, DELTA returns the #VALUE! error value.
        • - *
        - * - * @author cedric dot walter @ gmail dot com - */ -public final class Delta extends Fixed2ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Delta(); - - private final static NumberEval ONE = new NumberEval(1); - private final static NumberEval ZERO = new NumberEval(0); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2) { - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String strText1 = OperandResolver.coerceValueToString(veText1); - Double number1 = OperandResolver.parseDouble(strText1); - if (number1 == null) { - return ErrorEval.VALUE_INVALID; - } - - ValueEval veText2; - try { - veText2 = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - String strText2 = OperandResolver.coerceValueToString(veText2); - Double number2 = OperandResolver.parseDouble(strText2); - if (number2 == null) { - return ErrorEval.VALUE_INVALID; - } - - int result = new BigDecimal(number1.doubleValue()).compareTo(new BigDecimal(number2.doubleValue())); - return result == 0 ? ONE : ZERO; - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length == 2) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]); - } - - return ErrorEval.VALUE_INVALID; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/EDate.java b/trunk/src/java/org/apache/poi/ss/formula/functions/EDate.java deleted file mode 100644 index d4998b84b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/EDate.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - -/** - * Implementation for Excel EDATE () function. - */ -public class EDate implements FreeRefFunction { - public static final FreeRefFunction instance = new EDate(); - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - try { - double startDateAsNumber = getValue(args[0]); - int offsetInMonthAsNumber = (int) getValue(args[1]); - - Date startDate = DateUtil.getJavaDate(startDateAsNumber); - Calendar calendar = LocaleUtil.getLocaleCalendar(); - calendar.setTime(startDate); - calendar.add(Calendar.MONTH, offsetInMonthAsNumber); - return new NumberEval(DateUtil.getExcelDate(calendar.getTime())); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private double getValue(ValueEval arg) throws EvaluationException { - if (arg instanceof NumberEval) { - return ((NumberEval) arg).getNumberValue(); - } - if(arg instanceof BlankEval) { - return 0; - } - if (arg instanceof RefEval) { - RefEval refEval = (RefEval)arg; - if (refEval.getNumberOfSheets() > 1) { - // Multi-Sheet references are not supported - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - - ValueEval innerValueEval = refEval.getInnerValueEval(refEval.getFirstSheetIndex()); - if(innerValueEval instanceof NumberEval) { - return ((NumberEval) innerValueEval).getNumberValue(); - } - if(innerValueEval instanceof BlankEval) { - return 0; - } - } - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/EOMonth.java b/trunk/src/java/org/apache/poi/ss/formula/functions/EOMonth.java deleted file mode 100644 index 63836e591..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/EOMonth.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - -/** - * Implementation for the Excel EOMONTH() function.

        - *

        - * EOMONTH() returns the date of the last day of a month..

        - *

        - * Syntax:
        - * EOMONTH(start_date,months)

        - *

        - * start_date is the starting date of the calculation - * months is the number of months to be added to start_date, - * to give a new date. For this new date, EOMONTH returns the date of - * the last day of the month. months may be positive (in the future), - * zero or negative (in the past). - */ -public class EOMonth implements FreeRefFunction { - public static final FreeRefFunction instance = new EOMonth(); - - @Override - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - try { - double startDateAsNumber = NumericFunction.singleOperandEvaluate(args[0], ec.getRowIndex(), ec.getColumnIndex()); - int months = (int) NumericFunction.singleOperandEvaluate(args[1], ec.getRowIndex(), ec.getColumnIndex()); - - // Excel treats date 0 as 1900-01-00; EOMONTH results in 1900-01-31 - if (startDateAsNumber >= 0.0 && startDateAsNumber < 1.0) { - startDateAsNumber = 1.0; - } - - Date startDate = DateUtil.getJavaDate(startDateAsNumber, false); - - Calendar cal = LocaleUtil.getLocaleCalendar(); - cal.setTime(startDate); - cal.clear(Calendar.HOUR); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.clear(Calendar.MINUTE); - cal.clear(Calendar.SECOND); - cal.clear(Calendar.MILLISECOND); - - cal.add(Calendar.MONTH, months + 1); - cal.set(Calendar.DAY_OF_MONTH, 1); - cal.add(Calendar.DAY_OF_MONTH, -1); - - return new NumberEval(DateUtil.getExcelDate(cal.getTime())); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Errortype.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Errortype.java deleted file mode 100644 index 5dea7a3a0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Errortype.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.FormulaError; - -/** - * Implementation for the ERROR.TYPE() Excel function. - *

        - * Syntax:
        - * ERROR.TYPE(errorValue)

        - *

        - * Returns a number corresponding to the error type of the supplied argument.

        - *

        - * - * - * - * - * - * - * - * - * - * - *
        errorValueReturn Value
        #NULL!1
        #DIV/0!2
        #VALUE!3
        #REF!4
        #NAME?5
        #NUM!6
        #N/A!7
        everything else#N/A!
        - * - * Note - the results of ERROR.TYPE() are different to the constants defined in - * ErrorConstants. - *

        - * - * @author Josh Micich - */ -public final class Errortype extends Fixed1ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - - try { - OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - return ErrorEval.NA; - } catch (EvaluationException e) { - int result = translateErrorCodeToErrorTypeValue(e.getErrorEval().getErrorCode()); - return new NumberEval(result); - } - } - - private int translateErrorCodeToErrorTypeValue(int errorCode) { - switch (FormulaError.forInt(errorCode)) { - case NULL: return 1; - case DIV0: return 2; - case VALUE: return 3; - case REF: return 4; - case NAME: return 5; - case NUM: return 6; - case NA: return 7; - default: - throw new IllegalArgumentException("Invalid error code (" + errorCode + ")"); - } - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Even.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Even.java deleted file mode 100644 index f69126532..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Even.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Even extends NumericFunction.OneArg { - - private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL; - - protected double evaluate(double d) { - if (d==0) { - return 0; - } - long result; - if (d>0) { - result = calcEven(d); - } else { - result = -calcEven(-d); - } - return result; - } - - private static long calcEven(double d) { - long x = ((long) d) & PARITY_MASK; - if (x == d) { - return x; - } - return x + 2; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/FactDouble.java b/trunk/src/java/org/apache/poi/ss/formula/functions/FactDouble.java deleted file mode 100644 index 28c217186..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/FactDouble.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; - -import java.math.BigInteger; -import java.util.HashMap; - -/** - * Implementation for Excel FACTDOUBLE() function.

        - *

        - * Syntax:
        FACTDOUBLE (number)
        - *

        - * Returns the double factorial of a number. - *

        - * Number is the value for which to return the double factorial. If number is not an integer, it is truncated. - *

        - * Remarks - *

          - *
        • If number is nonnumeric, FACTDOUBLE returns the #VALUE! error value.
        • - *
        • If number is negative, FACTDOUBLE returns the #NUM! error value.
        • - *
        - * Use a cache for more speed of previously calculated factorial - * - * @author cedric dot walter @ gmail dot com - */ -public class FactDouble extends Fixed1ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new FactDouble(); - - //Caching of previously calculated factorial for speed - static HashMap cache = new HashMap(); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE) { - int number; - try { - number = OperandResolver.coerceValueToInt(numberVE); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - if (number < 0) { - return ErrorEval.NUM_ERROR; - } - - return new NumberEval(factorial(number).longValue()); - } - - public static BigInteger factorial(int n) { - if (n == 0 || n < 0) { - return BigInteger.ONE; - } - - if (cache.containsKey(n)) { - return cache.get(n); - } - - BigInteger result = BigInteger.valueOf(n).multiply(factorial(n - 2)); - cache.put(n, result); - return result; - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Finance.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Finance.java deleted file mode 100644 index 367438bfc..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Finance.java +++ /dev/null @@ -1,169 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -/** - * Implementation of the financial functions pmt, fv, ppmt, ipmt. - */ -public class Finance { - - /** - * Emulates Excel/Calc's PMT(interest_rate, number_payments, PV, FV, Type) - * function, which calculates the payments for a loan or the future value of an investment - * - * @param r - * - periodic interest rate represented as a decimal. - * @param nper - * - number of total payments / periods. - * @param pv - * - present value -- borrowed or invested principal. - * @param fv - * - future value of loan or annuity. - * @param type - * - when payment is made: beginning of period is 1; end, 0. - * @return double representing periodic payment amount. - */ - // http://arachnoid.com/lutusp/finance.html - static public double pmt(double r, int nper, double pv, double fv, int type) { - double pmt = -r * (pv * Math.pow(1 + r, nper) + fv) / ((1 + r*type) * (Math.pow(1 + r, nper) - 1)); - return pmt; - } - - - /** - * Overloaded pmt() call omitting type, which defaults to 0. - * - * @see #pmt(double, int, double, double, int) - */ - static public double pmt(double r, int nper, double pv, double fv) { - return pmt(r, nper, pv, fv, 0); - } - - /** - * Overloaded pmt() call omitting fv and type, which both default to 0. - * - * @see #pmt(double, int, double, double, int) - */ - static public double pmt(double r, int nper, double pv) { - return pmt(r, nper, pv, 0); - } - - - /** - * Emulates Excel/Calc's IPMT(interest_rate, period, number_payments, PV, - * FV, Type) function, which calculates the portion of the payment at a - * given period that is the interest on previous balance. - * - * @param r - * - periodic interest rate represented as a decimal. - * @param per - * - period (payment number) to check value at. - * @param nper - * - number of total payments / periods. - * @param pv - * - present value -- borrowed or invested principal. - * @param fv - * - future value of loan or annuity. - * @param type - * - when payment is made: beginning of period is 1; end, 0. - * @return double representing interest portion of payment. - * - * @see #pmt(double, int, double, double, int) - * @see #fv(double, int, double, double, int) - */ - // http://doc.optadata.com/en/dokumentation/application/expression/functions/financial.html - static public double ipmt(double r, int per, int nper, double pv, double fv, int type) { - double ipmt = fv(r, per - 1, pmt(r, nper, pv, fv, type), pv, type) * r; - if (type==1) ipmt /= (1 + r); - return ipmt; - } - - static public double ipmt(double r, int per, int nper, double pv, double fv) { - return ipmt(r, per, nper, pv, fv, 0); - } - - static public double ipmt(double r, int per, int nper, double pv) { - return ipmt(r, per, nper, pv, 0); - } - - /** - * Emulates Excel/Calc's PPMT(interest_rate, period, number_payments, PV, - * FV, Type) function, which calculates the portion of the payment at a - * given period that will apply to principal. - * - * @param r - * - periodic interest rate represented as a decimal. - * @param per - * - period (payment number) to check value at. - * @param nper - * - number of total payments / periods. - * @param pv - * - present value -- borrowed or invested principal. - * @param fv - * - future value of loan or annuity. - * @param type - * - when payment is made: beginning of period is 1; end, 0. - * @return double representing principal portion of payment. - * - * @see #pmt(double, int, double, double, int) - * @see #ipmt(double, int, int, double, double, int) - */ - static public double ppmt(double r, int per, int nper, double pv, double fv, int type) { - return pmt(r, nper, pv, fv, type) - ipmt(r, per, nper, pv, fv, type); - } - - static public double ppmt(double r, int per, int nper, double pv, double fv) { - return pmt(r, nper, pv, fv) - ipmt(r, per, nper, pv, fv); - } - - static public double ppmt(double r, int per, int nper, double pv) { - return pmt(r, nper, pv) - ipmt(r, per, nper, pv); - } - - /** - * Emulates Excel/Calc's FV(interest_rate, number_payments, payment, PV, - * Type) function, which calculates future value or principal at period N. - * - * @param r - * - periodic interest rate represented as a decimal. - * @param nper - * - number of total payments / periods. - * @param pmt - * - periodic payment amount. - * @param pv - * - present value -- borrowed or invested principal. - * @param type - * - when payment is made: beginning of period is 1; end, 0. - * @return double representing future principal value. - */ - //http://en.wikipedia.org/wiki/Future_value - static public double fv(double r, int nper, double pmt, double pv, int type) { - double fv = -(pv * Math.pow(1 + r, nper) + pmt * (1+r*type) * (Math.pow(1 + r, nper) - 1) / r); - return fv; - } - - /** - * Overloaded fv() call omitting type, which defaults to 0. - * - * @see #fv(double, int, double, double, int) - */ - static public double fv(double r, int nper, double c, double pv) { - return fv(r, nper, c, pv, 0); - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/FinanceFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/FinanceFunction.java deleted file mode 100644 index 988007386..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/FinanceFunction.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public abstract class FinanceFunction implements Function3Arg, Function4Arg { - private static final ValueEval DEFAULT_ARG3 = NumberEval.ZERO; - private static final ValueEval DEFAULT_ARG4 = BoolEval.FALSE; - - - protected FinanceFunction() { - // no instance fields - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, arg1, arg2, DEFAULT_ARG3); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2, ValueEval arg3) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, arg1, arg2, arg3, DEFAULT_ARG4); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2, ValueEval arg3, ValueEval arg4) { - double result; - try { - double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - double d2 = NumericFunction.singleOperandEvaluate(arg2, srcRowIndex, srcColumnIndex); - double d3 = NumericFunction.singleOperandEvaluate(arg3, srcRowIndex, srcColumnIndex); - double d4 = NumericFunction.singleOperandEvaluate(arg4, srcRowIndex, srcColumnIndex); - result = evaluate(d0, d1, d2, d3, d4 != 0.0); - NumericFunction.checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 3: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], DEFAULT_ARG3, DEFAULT_ARG4); - case 4: { - ValueEval arg3 = args[3]; - if(arg3 == MissingArgEval.instance) { - arg3 = DEFAULT_ARG3; - } - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], arg3, DEFAULT_ARG4); - } - case 5: { - ValueEval arg3 = args[3]; - if(arg3 == MissingArgEval.instance) { - arg3 = DEFAULT_ARG3; - } - ValueEval arg4 = args[4]; - if(arg4 == MissingArgEval.instance) { - arg4 = DEFAULT_ARG4; - } - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], arg3, arg4); - } - default: - return ErrorEval.VALUE_INVALID; - } - } - - @SuppressWarnings("fallthrough") - protected double evaluate(double[] ds) throws EvaluationException { - // All finance functions have 3 to 5 args, first 4 are numbers, last is boolean - // default for last 2 args are 0.0 and false - // Text boolean literals are not valid for the last arg - - double arg3 = 0.0; - double arg4 = 0.0; - - switch(ds.length) { - case 5: - arg4 = ds[4]; - // fall through - case 4: - arg3 = ds[3]; - // fall through - case 3: - break; - default: - throw new IllegalStateException("Wrong number of arguments"); - } - return evaluate(ds[0], ds[1], ds[2], arg3, arg4!=0.0); - } - - protected abstract double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) throws EvaluationException ; - - - public static final Function FV = new FinanceFunction() { - protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) { - return FinanceLib.fv(rate, arg1, arg2, arg3, type); - } - }; - public static final Function NPER = new FinanceFunction() { - protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) { - return FinanceLib.nper(rate, arg1, arg2, arg3, type); - } - }; - public static final Function PMT = new FinanceFunction() { - protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) { - return FinanceLib.pmt(rate, arg1, arg2, arg3, type); - } - }; - public static final Function PV = new FinanceFunction() { - protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) { - return FinanceLib.pv(rate, arg1, arg2, arg3, type); - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/FinanceLib.java b/trunk/src/java/org/apache/poi/ss/formula/functions/FinanceLib.java deleted file mode 100644 index 2a10fc9c3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/FinanceLib.java +++ /dev/null @@ -1,185 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - * - * This class is a functon library for common fiscal functions. - * Glossary of terms/abbreviations: - *
        - *
          - *
        • FV: Future Value
        • - *
        • PV: Present Value
        • - *
        • NPV: Net Present Value
        • - *
        • PMT: (Periodic) Payment
        • - * - *
        - * For more info on the terms/abbreviations please use the references below - * (hyperlinks are subject to change): - *
        Online References: - *
          - *
        1. GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html
        2. - *
        3. Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y
        4. - *
        5. MS Excel function reference: http://office.microsoft.com/en-us/assistance/CH062528251033.aspx
        6. - *
        - *

        Implementation Notes:

        - * Symbols used in the formulae that follow:
        - *
          - *
        • p: present value
        • - *
        • f: future value
        • - *
        • n: number of periods
        • - *
        • y: payment (in each period)
        • - *
        • r: rate
        • - *
        • ^: the power operator (NOT the java bitwise XOR operator!)
        • - *
        - * [From MS Excel function reference] Following are some of the key formulas - * that are used in this implementation: - *
        - * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0   ...{when r!=0}
        - * ny + p + f=0                            ...{when r=0}
        - * 
        - */ -public final class FinanceLib { - - private FinanceLib() { - // no instances of this class - } - - /** - * Future value of an amount given the number of payments, rate, amount - * of individual payment, present value and boolean value indicating whether - * payments are due at the beginning of period - * (false => payments are due at end of period) - * @param r rate - * @param n num of periods - * @param y pmt per period - * @param p future value - * @param t type (true=pmt at end of period, false=pmt at begining of period) - */ - public static double fv(double r, double n, double y, double p, boolean t) { - double retval = 0; - if (r == 0) { - retval = -1*(p+(n*y)); - } - else { - double r1 = r + 1; - retval =((1-Math.pow(r1, n)) * (t ? r1 : 1) * y ) / r - - - p*Math.pow(r1, n); - } - return retval; - } - - /** - * Present value of an amount given the number of future payments, rate, amount - * of individual payment, future value and boolean value indicating whether - * payments are due at the beginning of period - * (false => payments are due at end of period) - * @param r - * @param n - * @param y - * @param f - * @param t - */ - public static double pv(double r, double n, double y, double f, boolean t) { - double retval = 0; - if (r == 0) { - retval = -1*((n*y)+f); - } - else { - double r1 = r + 1; - retval =(( ( 1 - Math.pow(r1, n) ) / r ) * (t ? r1 : 1) * y - f) - / - Math.pow(r1, n); - } - return retval; - } - - /** - * calculates the Net Present Value of a principal amount - * given the discount rate and a sequence of cash flows - * (supplied as an array). If the amounts are income the value should - * be positive, else if they are payments and not income, the - * value should be negative. - * @param r - * @param cfs cashflow amounts - */ - public static double npv(double r, double[] cfs) { - double npv = 0; - double r1 = r + 1; - double trate = r1; - for (int i=0, iSize=cfs.length; i= 0 ? places : 0); - formatter.setMaximumFractionDigits(places >= 0 ? places : 0); - String numberString = formatter.format(number.doubleValue()); - - // Return the result as a StringEval. - return new StringEval(numberString); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed0ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed0ArgFunction.java deleted file mode 100644 index dbb1695ba..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed0ArgFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for functions that only take zero arguments. - * - * @author Josh Micich - */ -public abstract class Fixed0ArgFunction implements Function0Arg { - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length != 0) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(srcRowIndex, srcColumnIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed1ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed1ArgFunction.java deleted file mode 100644 index 0b3317d5b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed1ArgFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for functions that must take exactly one argument. - * - * @author Josh Micich - */ -public abstract class Fixed1ArgFunction implements Function1Arg { - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(srcRowIndex, srcColumnIndex, args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed2ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed2ArgFunction.java deleted file mode 100644 index 0ba3d40de..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed2ArgFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for functions that must take exactly two arguments. - * - * @author Josh Micich - */ -public abstract class Fixed2ArgFunction implements Function2Arg { - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed3ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed3ArgFunction.java deleted file mode 100644 index 421a39802..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed3ArgFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for functions that must take exactly three arguments. - * - * @author Josh Micich - */ -public abstract class Fixed3ArgFunction implements Function3Arg { - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length != 3) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed4ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed4ArgFunction.java deleted file mode 100644 index e3f8ace41..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed4ArgFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for functions that must take exactly four arguments. - * - * @author Josh Micich - */ -public abstract class Fixed4ArgFunction implements Function4Arg { - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length != 4) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], args[3]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/FreeRefFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/FreeRefFunction.java deleted file mode 100644 index 1c0fe1a6d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/FreeRefFunction.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.OperationEvaluationContext; - - -/** - * For most Excel functions, involving references ((cell, area), (2d, 3d)), the references are - * passed in as arguments, and the exact location remains fixed. However, a select few Excel - * functions have the ability to access cells that were not part of any reference passed as an - * argument.
        - * Two important functions with this feature are INDIRECT and OFFSET

        - * - * When POI evaluates formulas, each reference argument is capable of evaluating any cell inside - * its range. Actually, even cells outside the reference range but on the same sheet can be - * evaluated. This allows OFFSET to be implemented like most other functions - taking only - * the arguments, and source cell coordinates. - * - * For the moment this interface only exists to serve the INDIRECT which can decode - * arbitrary text into cell references, and evaluate them.. - * - * @author Josh Micich - */ -public interface FreeRefFunction { - /** - * @param args the pre-evaluated arguments for this function. args is never null, - * nor are any of its elements. - * @param ec primarily used to identify the source cell containing the formula being evaluated. - * may also be used to dynamically create reference evals. - * @return never null. Possibly an instance of ErrorEval in the case of - * a specified Excel error (Exceptions are never thrown to represent Excel errors). - */ - ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Function.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Function.java deleted file mode 100644 index 5f97b81a2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Function.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Common interface for all implementations of Excel built-in functions. - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public interface Function { - - /** - * @param args the evaluated function arguments. Empty values are represented with - * {@link BlankEval} or {@link MissingArgEval}, never null. - * @param srcRowIndex row index of the cell containing the formula under evaluation - * @param srcColumnIndex column index of the cell containing the formula under evaluation - * @return The evaluated result, possibly an {@link ErrorEval}, never null. - * Note - Excel uses the error code #NUM! instead of IEEE NaN, so when - * numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link - * ErrorEval#NUM_ERROR}. - */ - ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Function0Arg.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Function0Arg.java deleted file mode 100644 index 749053ea1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Function0Arg.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implemented by all functions that can be called with zero arguments - * - * @author Josh Micich - */ -public interface Function0Arg extends Function { - /** - * see {@link Function#evaluate(ValueEval[], int, int)} - */ - ValueEval evaluate(int srcRowIndex, int srcColumnIndex); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Function1Arg.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Function1Arg.java deleted file mode 100644 index ec214f4f0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Function1Arg.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implemented by all functions that can be called with one argument - * - * @author Josh Micich - */ -public interface Function1Arg extends Function { - /** - * see {@link Function#evaluate(ValueEval[], int, int)} - */ - ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Function2Arg.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Function2Arg.java deleted file mode 100644 index bd395cc51..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Function2Arg.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implemented by all functions that can be called with two arguments - * - * @author Josh Micich - */ -public interface Function2Arg extends Function { - /** - * see {@link Function#evaluate(ValueEval[], int, int)} - */ - ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Function3Arg.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Function3Arg.java deleted file mode 100644 index ad5eee158..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Function3Arg.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implemented by all functions that can be called with three arguments - * - * @author Josh Micich - */ -public interface Function3Arg extends Function { - /** - * see {@link Function#evaluate(ValueEval[], int, int)} - */ - ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Function4Arg.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Function4Arg.java deleted file mode 100644 index f0eee5224..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Function4Arg.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implemented by all functions that can be called with four arguments - * - * @author Josh Micich - */ -public interface Function4Arg extends Function { - /** - * see {@link Function#evaluate(ValueEval[], int, int)} - */ - ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2, ValueEval arg3); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Hex2Dec.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Hex2Dec.java deleted file mode 100644 index 907b62916..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Hex2Dec.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; - -/** - * Implementation for Excel HEX2DEC() function.

        - *

        - * Syntax:
        HEX2DEC (number)
        - *

        - * Converts a hexadecimal number to decimal. - *

        - * Number is the hexadecimal number you want to convert. Number cannot contain more than 10 characters (40 bits). - * The most significant bit of number is the sign bit. - * The remaining 39 bits are magnitude bits. Negative numbers are represented using two's-complement notation. - * Remark - * If number is not a valid hexadecimal number, HEX2DEC returns the #NUM! error value. - * - * @author cedric dot walter @ gmail dot com - */ -public class Hex2Dec extends Fixed1ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Hex2Dec(); - - static final int HEXADECIMAL_BASE = 16; - static final int MAX_NUMBER_OF_PLACES = 10; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE) { - final String hex; - if (numberVE instanceof RefEval) { - RefEval re = (RefEval) numberVE; - hex = OperandResolver.coerceValueToString(re.getInnerValueEval(re.getFirstSheetIndex())); - } else { - hex = OperandResolver.coerceValueToString(numberVE); - } - try { - return new NumberEval(BaseNumberUtils.convertToDecimal(hex, HEXADECIMAL_BASE, MAX_NUMBER_OF_PLACES)); - } catch (IllegalArgumentException e) { - return ErrorEval.NUM_ERROR; - } - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Hlookup.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Hlookup.java deleted file mode 100644 index c6190dcba..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Hlookup.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; -import org.apache.poi.ss.formula.TwoDEval; -/** - * Implementation of the HLOOKUP() function.

        - * - * HLOOKUP finds a column in a lookup table by the first row value and returns the value from another row.
        - * - * Syntax:
        - * HLOOKUP(lookup_value, table_array, row_index_num, range_lookup)

        - * - * lookup_value The value to be found in the first column of the table array.
        - * table_array An area reference for the lookup data.
        - * row_index_num a 1 based index specifying which row value of the lookup data will be returned.
        - * range_lookup If TRUE (default), HLOOKUP finds the largest value less than or equal to - * the lookup_value. If FALSE, only exact matches will be considered
        - * - * @author Josh Micich - */ -public final class Hlookup extends Var3or4ArgFunction { - private static final ValueEval DEFAULT_ARG3 = BoolEval.TRUE; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, arg1, arg2, DEFAULT_ARG3); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2, ValueEval arg3) { - try { - // Evaluation order: - // arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 row_index, fetch result - ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - TwoDEval tableArray = LookupUtils.resolveTableArrayArg(arg1); - boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcRowIndex, srcColumnIndex); - int colIndex = LookupUtils.lookupIndexOfValue(lookupValue, LookupUtils.createRowVector(tableArray, 0), isRangeLookup); - int rowIndex = LookupUtils.resolveRowOrColIndexArg(arg2, srcRowIndex, srcColumnIndex); - ValueVector resultCol = createResultColumnVector(tableArray, rowIndex); - return resultCol.getItem(colIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - /** - * Returns one column from an AreaEval - * - * @param rowIndex assumed to be non-negative - * - * @throws EvaluationException (#REF!) if colIndex is too high - */ - private ValueVector createResultColumnVector(TwoDEval tableArray, int rowIndex) throws EvaluationException { - if(rowIndex >= tableArray.getHeight()) { - throw EvaluationException.invalidRef(); - } - return LookupUtils.createRowVector(tableArray, rowIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Hyperlink.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Hyperlink.java deleted file mode 100644 index a43b04014..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Hyperlink.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation of Excel HYPERLINK function.

        - * - * In Excel this function has special behaviour - it causes the displayed cell value to behave like - * a hyperlink in the GUI. From an evaluation perspective however, it is very simple.

        - * - * Syntax:
        - * HYPERLINK(link_location, friendly_name)

        - * - * link_location The URL of the hyperlink
        - * friendly_name (optional) the value to display

        - * - * Returns last argument. Leaves type unchanged (does not convert to {@link org.apache.poi.ss.formula.eval.StringEval}). - * - * @author Wayne Clingingsmith - */ -public final class Hyperlink extends Var1or2ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - return arg0; - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - // note - if last arg is MissingArgEval, result will be NumberEval.ZERO, - // but WorkbookEvaluator does that translation - return arg1; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java b/trunk/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java deleted file mode 100644 index 111964a4c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/IDStarAlgorithm.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Interface specifying how an algorithm to be used by {@link DStarRunner} should look like. - * Each implementing class should correspond to one of the D* functions. - */ -public interface IDStarAlgorithm { - /** - * Process a match that is found during a run through a database. - * @param eval ValueEval of the cell in the matching row. References will already be resolved. - * @return Whether we should continue iterating through the database. - */ - boolean processMatch(ValueEval eval); - /** - * Return a result ValueEval that will be the result of the calculation. - * This is always called at the end of a run through the database. - * @return a ValueEval - */ - ValueEval getResult(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/IPMT.java b/trunk/src/java/org/apache/poi/ss/formula/functions/IPMT.java deleted file mode 100644 index 35dca8a2f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/IPMT.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -public class IPMT extends NumericFunction { - - @Override - public double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException { - - if(args.length != 4) - throw new EvaluationException(ErrorEval.VALUE_INVALID); - - double result; - - ValueEval v1 = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - ValueEval v2 = OperandResolver.getSingleValue(args[1], srcCellRow, srcCellCol); - ValueEval v3 = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol); - ValueEval v4 = OperandResolver.getSingleValue(args[3], srcCellRow, srcCellCol); - - double interestRate = OperandResolver.coerceValueToDouble(v1); - int period = OperandResolver.coerceValueToInt(v2); - int numberPayments = OperandResolver.coerceValueToInt(v3); - double PV = OperandResolver.coerceValueToDouble(v4); - - result = Finance.ipmt(interestRate, period, numberPayments, PV) ; - - checkValue(result); - - return result; - } - - - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java b/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java deleted file mode 100644 index d410350b7..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.RefPtg; - -/** - * Implementation for the Excel function IF - *

        - * Note that Excel is a bit picky about the arguments to this function, - * when serialised into {@link Ptg}s in a HSSF file. While most cases are - * pretty chilled about the R vs V state of {@link RefPtg} arguments, - * for IF special care is needed to avoid Excel showing #VALUE. - * See bug numbers #55324 and #55747 for the full details on this. - * TODO Fix this... - */ -public final class IfFunc extends Var2or3ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - boolean b; - try { - b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (b) { - if (arg1 == MissingArgEval.instance) { - return BlankEval.instance; - } - return arg1; - } - return BoolEval.FALSE; - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - boolean b; - try { - b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (b) { - if (arg1 == MissingArgEval.instance) { - return BlankEval.instance; - } - return arg1; - } - if (arg2 == MissingArgEval.instance) { - return BlankEval.instance; - } - return arg2; - } - - public static boolean evaluateFirstArg(ValueEval arg, int srcCellRow, int srcCellCol) - throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - Boolean b = OperandResolver.coerceValueToBoolean(ve, false); - if (b == null) { - return false; - } - return b.booleanValue(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/ImReal.java b/trunk/src/java/org/apache/poi/ss/formula/functions/ImReal.java deleted file mode 100644 index f7c17adef..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/ImReal.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.regex.Matcher; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel ImReal() function.

        - *

        - * Syntax:
        ImReal (Inumber)
        - *

        - * Returns the real coefficient of a complex number in x + yi or x + yj text format. - *

        - * Inumber A complex number for which you want the real coefficient. - *

        - * Remarks - *

          - *
        • If inumber is not in the form x + yi or x + yj, this function returns the #NUM! error value.
        • - *
        • Use COMPLEX to convert real and imaginary coefficients into a complex number.
        • - *
        - * - * @author cedric dot walter @ gmail dot com - */ -public class ImReal extends Fixed1ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new ImReal(); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval inumberVE) { - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(inumberVE, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String iNumber = OperandResolver.coerceValueToString(veText1); - - Matcher m = Imaginary.COMPLEX_NUMBER_PATTERN.matcher(iNumber); - boolean result = m.matches(); - - String real = ""; - if (result == true) { - String realGroup = m.group(2); - boolean hasRealPart = realGroup.length() != 0; - - if (realGroup.length() == 0) { - return new StringEval(String.valueOf(0)); - } - - if (hasRealPart) { - String sign = ""; - String realSign = m.group(Imaginary.GROUP1_REAL_SIGN); - if (realSign.length() != 0 && !(realSign.equals("+"))) { - sign = realSign; - } - - String groupRealNumber = m.group(Imaginary.GROUP2_IMAGINARY_INTEGER_OR_DOUBLE); - if (groupRealNumber.length() != 0) { - real = sign + groupRealNumber; - } else { - real = sign + "1"; - } - } - } else { - return ErrorEval.NUM_ERROR; - } - - return new StringEval(real); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Imaginary.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Imaginary.java deleted file mode 100644 index 2b1309310..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Imaginary.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Implementation for Excel IMAGINARY() function.

        - *

        - * Syntax:
        IMAGINARY (Inumber)
        - *

        - * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. - *

        - * Inumber is a complex number for which you want the imaginary coefficient. - *

        - * Remarks - *

          - *
        • Use COMPLEX to convert real and imaginary coefficients into a complex number.
        • - *
        - * - * @author cedric dot walter @ gmail dot com - */ -public class Imaginary extends Fixed1ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Imaginary(); - - public static final String GROUP1_REAL_SIGN_REGEX = "([+-]?)"; - public static final String GROUP2_REAL_INTEGER_OR_DOUBLE_REGEX = "([0-9]+\\.[0-9]+|[0-9]*)"; - public static final String GROUP3_IMAGINARY_SIGN_REGEX = "([+-]?)"; - public static final String GROUP4_IMAGINARY_INTEGER_OR_DOUBLE_REGEX = "([0-9]+\\.[0-9]+|[0-9]*)"; - public static final String GROUP5_IMAGINARY_GROUP_REGEX = "([ij]?)"; - - public static final Pattern COMPLEX_NUMBER_PATTERN - = Pattern.compile(GROUP1_REAL_SIGN_REGEX + GROUP2_REAL_INTEGER_OR_DOUBLE_REGEX + - GROUP3_IMAGINARY_SIGN_REGEX + GROUP4_IMAGINARY_INTEGER_OR_DOUBLE_REGEX + GROUP5_IMAGINARY_GROUP_REGEX); - - public static final int GROUP1_REAL_SIGN = 1; - public static final int GROUP2_IMAGINARY_INTEGER_OR_DOUBLE = 2; - public static final int GROUP3_IMAGINARY_SIGN = 3; - public static final int GROUP4_IMAGINARY_INTEGER_OR_DOUBLE = 4; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval inumberVE) { - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(inumberVE, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String iNumber = OperandResolver.coerceValueToString(veText1); - - Matcher m = COMPLEX_NUMBER_PATTERN.matcher(iNumber); - boolean result = m.matches(); - - String imaginary = ""; - if (result == true) { - String imaginaryGroup = m.group(5); - boolean hasImaginaryPart = imaginaryGroup.equals("i") || imaginaryGroup.equals("j"); - - if (imaginaryGroup.length() == 0) { - return new StringEval(String.valueOf(0)); - } - - if (hasImaginaryPart) { - String sign = ""; - String imaginarySign = m.group(GROUP3_IMAGINARY_SIGN); - if (imaginarySign.length() != 0 && !(imaginarySign.equals("+"))) { - sign = imaginarySign; - } - - String groupImaginaryNumber = m.group(GROUP4_IMAGINARY_INTEGER_OR_DOUBLE); - if (groupImaginaryNumber.length() != 0) { - imaginary = sign + groupImaginaryNumber; - } else { - imaginary = sign + "1"; - } - } - } else { - return ErrorEval.NUM_ERROR; - } - - return new StringEval(imaginary); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Index.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Index.java deleted file mode 100644 index e4884b206..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Index.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.TwoDEval; - -/** - * Implementation for the Excel function INDEX - *

        - * - * Syntax :
        - * INDEX ( reference, row_num[, column_num [, area_num]])
        - * INDEX ( array, row_num[, column_num]) - * - * - * - * - * - * - *
        referencetypically an area reference, possibly a union of areas
        arraya literal array value (currently not supported)
        row_numselects the row within the array or area reference
        column_numselects column within the array or area reference. default is 1
        area_numused when reference is a union of areas
        - *

        - * - * @author Josh Micich - */ -public final class Index implements Function2Arg, Function3Arg, Function4Arg { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - TwoDEval reference = convertFirstArg(arg0); - - int columnIx = 0; - try { - int rowIx = resolveIndexArg(arg1, srcRowIndex, srcColumnIndex); - - if (!reference.isColumn()) { - if (!reference.isRow()) { - // always an error with 2-D area refs - // Note - the type of error changes if the pRowArg is negative - return ErrorEval.REF_INVALID; - } - // When the two-arg version of INDEX() has been invoked and the reference - // is a single column ref, the row arg seems to get used as the column index - columnIx = rowIx; - rowIx = 0; - } - - return getValueFromArea(reference, rowIx, columnIx); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - TwoDEval reference = convertFirstArg(arg0); - - try { - int columnIx = resolveIndexArg(arg2, srcRowIndex, srcColumnIndex); - int rowIx = resolveIndexArg(arg1, srcRowIndex, srcColumnIndex); - return getValueFromArea(reference, rowIx, columnIx); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2, ValueEval arg3) { - throw new RuntimeException("Incomplete code" - + " - don't know how to support the 'area_num' parameter yet)"); - // Excel expression might look like this "INDEX( (A1:B4, C3:D6, D2:E5 ), 1, 2, 3) - // In this example, the 3rd area would be used i.e. D2:E5, and the overall result would be E2 - // Token array might be encoded like this: MemAreaPtg, AreaPtg, AreaPtg, UnionPtg, UnionPtg, ParenthesesPtg - // The formula parser doesn't seem to support this yet. Not sure if the evaluator does either - } - - private static TwoDEval convertFirstArg(ValueEval arg0) { - ValueEval firstArg = arg0; - if (firstArg instanceof RefEval) { - // convert to area ref for simpler code in getValueFromArea() - return ((RefEval)firstArg).offset(0, 0, 0, 0); - } - if((firstArg instanceof TwoDEval)) { - return (TwoDEval) firstArg; - } - // else the other variation of this function takes an array as the first argument - // it seems like interface 'ArrayEval' does not even exist yet - throw new RuntimeException("Incomplete code - cannot handle first arg of type (" - + firstArg.getClass().getName() + ")"); - - } - - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 2: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]); - case 3: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]); - case 4: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], args[3]); - } - return ErrorEval.VALUE_INVALID; - } - - private static ValueEval getValueFromArea(TwoDEval ae, int pRowIx, int pColumnIx) - throws EvaluationException { - assert pRowIx >= 0; - assert pColumnIx >= 0; - - TwoDEval result = ae; - - if (pRowIx != 0) { - // Slightly irregular logic for bounds checking errors - if (pRowIx > ae.getHeight()) { - // high bounds check fail gives #REF! if arg was explicitly passed - throw new EvaluationException(ErrorEval.REF_INVALID); - } - result = result.getRow(pRowIx-1); - } - - if (pColumnIx != 0) { - // Slightly irregular logic for bounds checking errors - if (pColumnIx > ae.getWidth()) { - // high bounds check fail gives #REF! if arg was explicitly passed - throw new EvaluationException(ErrorEval.REF_INVALID); - } - result = result.getColumn(pColumnIx-1); - } - return result; - } - - - /** - * @param arg a 1-based index. - * @return the resolved 1-based index. Zero if the arg was missing or blank - * @throws EvaluationException if the arg is an error value evaluates to a negative numeric value - */ - private static int resolveIndexArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - - ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - if (ev == MissingArgEval.instance) { - return 0; - } - if (ev == BlankEval.instance) { - return 0; - } - int result = OperandResolver.coerceValueToInt(ev); - if (result < 0) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Indirect.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Indirect.java deleted file mode 100644 index 1ea3dcd38..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Indirect.java +++ /dev/null @@ -1,256 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.FormulaParseException; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaParsingWorkbook; -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.ptg.Area3DPxg; -import org.apache.poi.ss.usermodel.Table; - -/** - * Implementation for Excel function INDIRECT

        - * - * INDIRECT() returns the cell or area reference denoted by the text argument.

        - * - * Syntax:
        - * INDIRECT(ref_text,isA1Style)

        - * - * ref_text a string representation of the desired reference as it would - * normally be written in a cell formula.
        - * isA1Style (default TRUE) specifies whether the ref_text should be - * interpreted as A1-style or R1C1-style. - * - * @author Josh Micich - */ -public final class Indirect implements FreeRefFunction { - - public static final FreeRefFunction instance = new Indirect(); - - private Indirect() { - // enforce singleton - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length < 1) { - return ErrorEval.VALUE_INVALID; - } - - boolean isA1style; - String text; - try { - ValueEval ve = OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec - .getColumnIndex()); - text = OperandResolver.coerceValueToString(ve); - switch (args.length) { - case 1: - isA1style = true; - break; - case 2: - isA1style = evaluateBooleanArg(args[1], ec); - break; - default: - return ErrorEval.VALUE_INVALID; - } - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return evaluateIndirect(ec, text, isA1style); - } - - private static boolean evaluateBooleanArg(ValueEval arg, OperationEvaluationContext ec) - throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, ec.getRowIndex(), ec.getColumnIndex()); - - if (ve == BlankEval.instance || ve == MissingArgEval.instance) { - return false; - } - // numeric quantities follow standard boolean conversion rules - // for strings, only "TRUE" and "FALSE" (case insensitive) are valid - return OperandResolver.coerceValueToBoolean(ve, false).booleanValue(); - } - - private static ValueEval evaluateIndirect(final OperationEvaluationContext ec, String text, - boolean isA1style) { - - // Search backwards for '!' because sheet names can contain '!' - int plingPos = text.lastIndexOf('!'); - - String workbookName; - String sheetName; - String refText; // whitespace around this gets trimmed OK - if (plingPos < 0) { - workbookName = null; - sheetName = null; - refText = text; - } else { - String[] parts = parseWorkbookAndSheetName(text.subSequence(0, plingPos)); - if (parts == null) { - return ErrorEval.REF_INVALID; - } - workbookName = parts[0]; - sheetName = parts[1]; - refText = text.substring(plingPos + 1); - } - - if (Table.isStructuredReference.matcher(refText).matches()) { - // The argument is structured reference - Area3DPxg areaPtg = null; - try { - areaPtg = FormulaParser.parseStructuredReference(refText, (FormulaParsingWorkbook) ec.getWorkbook(), ec.getRowIndex()); - } catch (FormulaParseException e) { - return ErrorEval.REF_INVALID; - } - return ec.getArea3DEval(areaPtg); - } else { - // The argument is regular reference - String refStrPart1; - String refStrPart2; - int colonPos = refText.indexOf(':'); - if (colonPos < 0) { - refStrPart1 = refText.trim(); - refStrPart2 = null; - } else { - refStrPart1 = refText.substring(0, colonPos).trim(); - refStrPart2 = refText.substring(colonPos + 1).trim(); - } - return ec.getDynamicReference(workbookName, sheetName, refStrPart1, refStrPart2, isA1style); - } - } - - /** - * @return array of length 2: {workbookName, sheetName,}. Second element will always be - * present. First element may be null if sheetName is unqualified. - * Returns null if text cannot be parsed. - */ - private static String[] parseWorkbookAndSheetName(CharSequence text) { - int lastIx = text.length() - 1; - if (lastIx < 0) { - return null; - } - if (canTrim(text)) { - return null; - } - char firstChar = text.charAt(0); - if (Character.isWhitespace(firstChar)) { - return null; - } - if (firstChar == '\'') { - // workbookName or sheetName needs quoting - // quotes go around both - if (text.charAt(lastIx) != '\'') { - return null; - } - firstChar = text.charAt(1); - if (Character.isWhitespace(firstChar)) { - return null; - } - String wbName; - int sheetStartPos; - if (firstChar == '[') { - int rbPos = text.toString().lastIndexOf(']'); - if (rbPos < 0) { - return null; - } - wbName = unescapeString(text.subSequence(2, rbPos)); - if (wbName == null || canTrim(wbName)) { - return null; - } - sheetStartPos = rbPos + 1; - } else { - wbName = null; - sheetStartPos = 1; - } - - // else - just sheet name - String sheetName = unescapeString(text.subSequence(sheetStartPos, lastIx)); - if (sheetName == null) { // note - when quoted, sheetName can - // start/end with whitespace - return null; - } - return new String[] { wbName, sheetName, }; - } - - if (firstChar == '[') { - int rbPos = text.toString().lastIndexOf(']'); - if (rbPos < 0) { - return null; - } - CharSequence wbName = text.subSequence(1, rbPos); - if (canTrim(wbName)) { - return null; - } - CharSequence sheetName = text.subSequence(rbPos + 1, text.length()); - if (canTrim(sheetName)) { - return null; - } - return new String[] { wbName.toString(), sheetName.toString(), }; - } - // else - just sheet name - return new String[] { null, text.toString(), }; - } - - /** - * @return null if there is a syntax error in any escape sequence - * (the typical syntax error is a single quote character not followed by another). - */ - private static String unescapeString(CharSequence text) { - int len = text.length(); - StringBuilder sb = new StringBuilder(len); - int i = 0; - while (i < len) { - char ch = text.charAt(i); - if (ch == '\'') { - // every quote must be followed by another - i++; - if (i >= len) { - return null; - } - ch = text.charAt(i); - if (ch != '\'') { - return null; - } - } - sb.append(ch); - i++; - } - return sb.toString(); - } - - private static boolean canTrim(CharSequence text) { - int lastIx = text.length() - 1; - if (lastIx < 0) { - return false; - } - if (Character.isWhitespace(text.charAt(0))) { - return true; - } - if (Character.isWhitespace(text.charAt(lastIx))) { - return true; - } - return false; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Intercept.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Intercept.java deleted file mode 100644 index f7a142a3b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Intercept.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LinearRegressionFunction.FUNCTION; - -/** - * Implementation of Excel function INTERCEPT()

        - * - * Calculates the INTERCEPT of the linear regression line that is used to predict y values from x values
        - * (http://introcs.cs.princeton.edu/java/97data/LinearRegression.java.html) - * Syntax:
        - * INTERCEPT(arrayX, arrayY)

        - * - * - * @author Johan Karlsteen - */ -public final class Intercept extends Fixed2ArgFunction { - - private final LinearRegressionFunction func; - public Intercept() { - func = new LinearRegressionFunction(FUNCTION.INTERCEPT); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, - ValueEval arg0, ValueEval arg1) { - return func.evaluate(srcRowIndex, srcColumnIndex, arg0, arg1); - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java deleted file mode 100644 index a2faf181c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java +++ /dev/null @@ -1,122 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.*; - -/** - * Calculates the internal rate of return. - * - * Syntax is IRR(values) or IRR(values,guess) - * - * @author Marcel May - * @author Yegor Kozlov - * - * @see Wikipedia on IRR - * @see Excel IRR - */ -public final class Irr implements Function { - - - public ValueEval evaluate(final ValueEval[] args, final int srcRowIndex, final int srcColumnIndex) { - if(args.length == 0 || args.length > 2) { - // Wrong number of arguments - return ErrorEval.VALUE_INVALID; - } - - try { - double[] values = AggregateFunction.ValueCollector.collectValues(args[0]); - double guess; - if(args.length == 2) { - guess = NumericFunction.singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex); - } else { - guess = 0.1d; - } - double result = irr(values, guess); - NumericFunction.checkValue(result); - return new NumberEval(result); - } catch (EvaluationException e){ - return e.getErrorEval(); - } - } - - /** - * Computes the internal rate of return using an estimated irr of 10 percent. - * - * @param income the income values. - * @return the irr. - */ - public static double irr(double[] income) { - return irr(income, 0.1d); - } - - - /** - * Calculates IRR using the Newton-Raphson Method. - *

        - * Starting with the guess, the method cycles through the calculation until the result - * is accurate within 0.00001 percent. If IRR can't find a result that works - * after 20 tries, the Double.NaN<> is returned. - *

        - *

        - * The implementation is inspired by the NewtonSolver from the Apache Commons-Math library, - * @see http://commons.apache.org - *

        - * - * @param values the income values. - * @param guess the initial guess of irr. - * @return the irr value. The method returns Double.NaN - * if the maximum iteration count is exceeded - * - * @see - * http://en.wikipedia.org/wiki/Internal_rate_of_return#Numerical_solution - * @see - * http://en.wikipedia.org/wiki/Newton%27s_method - */ - public static double irr(double[] values, double guess) { - int maxIterationCount = 20; - double absoluteAccuracy = 1E-7; - - double x0 = guess; - double x1; - - int i = 0; - while (i < maxIterationCount) { - - // the value of the function (NPV) and its derivate can be calculated in the same loop - double fValue = 0; - double fDerivative = 0; - for (int k = 0; k < values.length; k++) { - fValue += values[k] / Math.pow(1.0 + x0, k); - fDerivative += -k * values[k] / Math.pow(1.0 + x0, k + 1); - } - - // the essense of the Newton-Raphson Method - x1 = x0 - fValue/fDerivative; - - if (Math.abs(x1 - x0) <= absoluteAccuracy) { - return x1; - } - - x0 = x1; - ++i; - } - // maximum number of iterations is exceeded - return Double.NaN; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java deleted file mode 100644 index 73a0204be..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; - -/** - * Base class for linear regression functions. - * - * Calculates the linear regression line that is used to predict y values from x values
        - * (http://introcs.cs.princeton.edu/java/97data/LinearRegression.java.html) - * Syntax:
        - * INTERCEPT(arrayX, arrayY)

        - * or - * SLOPE(arrayX, arrayY)

        - * - * - * @author Johan Karlsteen - */ -public final class LinearRegressionFunction extends Fixed2ArgFunction { - - private static abstract class ValueArray implements ValueVector { - private final int _size; - protected ValueArray(int size) { - _size = size; - } - - public ValueEval getItem(int index) { - if (index < 0 || index > _size) { - throw new IllegalArgumentException("Specified index " + index - + " is outside range (0.." + (_size - 1) + ")"); - } - return getItemInternal(index); - } - protected abstract ValueEval getItemInternal(int index); - - public final int getSize() { - return _size; - } - } - - private static final class SingleCellValueArray extends ValueArray { - private final ValueEval _value; - public SingleCellValueArray(ValueEval value) { - super(1); - _value = value; - } - - protected ValueEval getItemInternal(int index) { - return _value; - } - } - - private static final class RefValueArray extends ValueArray { - private final RefEval _ref; - private final int _width; - public RefValueArray(RefEval ref) { - super(ref.getNumberOfSheets()); - _ref = ref; - _width = ref.getNumberOfSheets(); - } - - protected ValueEval getItemInternal(int index) { - int sIx = (index % _width) + _ref.getFirstSheetIndex(); - return _ref.getInnerValueEval(sIx); - } - } - - private static final class AreaValueArray extends ValueArray { - private final TwoDEval _ae; - private final int _width; - - public AreaValueArray(TwoDEval ae) { - super(ae.getWidth() * ae.getHeight()); - _ae = ae; - _width = ae.getWidth(); - } - - protected ValueEval getItemInternal(int index) { - int rowIx = index / _width; - int colIx = index % _width; - return _ae.getValue(rowIx, colIx); - } - } - - public enum FUNCTION {INTERCEPT, SLOPE} - public FUNCTION function; - - public LinearRegressionFunction(FUNCTION function) { - this.function = function; - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, - ValueEval arg0, ValueEval arg1) { - double result; - try { - ValueVector vvY = createValueVector(arg0); - ValueVector vvX = createValueVector(arg1); - int size = vvX.getSize(); - if (size == 0 || vvY.getSize() != size) { - return ErrorEval.NA; - } - result = evaluateInternal(vvX, vvY, size); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (Double.isNaN(result) || Double.isInfinite(result)) { - return ErrorEval.NUM_ERROR; - } - return new NumberEval(result); - } - - private double evaluateInternal(ValueVector x, ValueVector y, int size) - throws EvaluationException { - - // error handling is as if the x is fully evaluated before y - ErrorEval firstXerr = null; - ErrorEval firstYerr = null; - boolean accumlatedSome = false; - // first pass: read in data, compute xbar and ybar - double sumx = 0.0, sumy = 0.0; - - for (int i = 0; i < size; i++) { - ValueEval vx = x.getItem(i); - ValueEval vy = y.getItem(i); - if (vx instanceof ErrorEval) { - if (firstXerr == null) { - firstXerr = (ErrorEval) vx; - continue; - } - } - if (vy instanceof ErrorEval) { - if (firstYerr == null) { - firstYerr = (ErrorEval) vy; - continue; - } - } - // only count pairs if both elements are numbers - if (vx instanceof NumberEval && vy instanceof NumberEval) { - accumlatedSome = true; - NumberEval nx = (NumberEval) vx; - NumberEval ny = (NumberEval) vy; - sumx += nx.getNumberValue(); - sumy += ny.getNumberValue(); - } else { - // all other combinations of value types are silently ignored - } - } - double xbar = sumx / size; - double ybar = sumy / size; - - // second pass: compute summary statistics - double xxbar = 0.0, xybar = 0.0; - for (int i = 0; i < size; i++) { - ValueEval vx = x.getItem(i); - ValueEval vy = y.getItem(i); - - if (vx instanceof ErrorEval) { - if (firstXerr == null) { - firstXerr = (ErrorEval) vx; - continue; - } - } - if (vy instanceof ErrorEval) { - if (firstYerr == null) { - firstYerr = (ErrorEval) vy; - continue; - } - } - - // only count pairs if both elements are numbers - if (vx instanceof NumberEval && vy instanceof NumberEval) { - NumberEval nx = (NumberEval) vx; - NumberEval ny = (NumberEval) vy; - xxbar += (nx.getNumberValue() - xbar) * (nx.getNumberValue() - xbar); - xybar += (nx.getNumberValue() - xbar) * (ny.getNumberValue() - ybar); - } else { - // all other combinations of value types are silently ignored - } - } - double beta1 = xybar / xxbar; - double beta0 = ybar - beta1 * xbar; - - if (firstXerr != null) { - throw new EvaluationException(firstXerr); - } - if (firstYerr != null) { - throw new EvaluationException(firstYerr); - } - if (!accumlatedSome) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - - if(function == FUNCTION.INTERCEPT) { - return beta0; - } else { - return beta1; - } - } - - private static ValueVector createValueVector(ValueEval arg) throws EvaluationException { - if (arg instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) arg); - } - if (arg instanceof TwoDEval) { - return new AreaValueArray((TwoDEval) arg); - } - if (arg instanceof RefEval) { - return new RefValueArray((RefEval) arg); - } - return new SingleCellValueArray(arg); - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java deleted file mode 100644 index a0825774b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation of the various ISxxx Logical Functions, which - * take a single expression argument, and return True or False. - */ -public abstract class LogicalFunction extends Fixed1ArgFunction { - - @SuppressWarnings("unused") - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - ValueEval ve; - try { - ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - // Note - it is more usual to propagate error codes straight to the result like this: - // but logical functions behave a little differently - // return e.getErrorEval(); - - // this will usually cause a 'FALSE' result except for ISNONTEXT() - ve = e.getErrorEval(); - } - return BoolEval.valueOf(evaluate(ve)); - - } - /** - * @param arg any {@link ValueEval}, potentially {@link BlankEval} or {@link ErrorEval}. - */ - protected abstract boolean evaluate(ValueEval arg); - - public static final Function ISLOGICAL = new LogicalFunction() { - protected boolean evaluate(ValueEval arg) { - return arg instanceof BoolEval; - } - }; - public static final Function ISNONTEXT = new LogicalFunction() { - protected boolean evaluate(ValueEval arg) { - return !(arg instanceof StringEval); - } - }; - public static final Function ISNUMBER = new LogicalFunction() { - protected boolean evaluate(ValueEval arg) { - return arg instanceof NumberEval; - } - }; - public static final Function ISTEXT = new LogicalFunction() { - protected boolean evaluate(ValueEval arg) { - return arg instanceof StringEval; - } - }; - - public static final Function ISBLANK = new LogicalFunction() { - - protected boolean evaluate(ValueEval arg) { - return arg instanceof BlankEval; - } - }; - - public static final Function ISERROR = new LogicalFunction() { - - protected boolean evaluate(ValueEval arg) { - return arg instanceof ErrorEval; - } - }; - - /** - * Implementation of Excel ISERR() function.

        - * - * Syntax:
        - * ISERR(value)

        - * - * value The value to be tested

        - * - * Returns the logical value TRUE if value refers to any error value except - * '#N/A'; otherwise, it returns FALSE. - */ - public static final Function ISERR = new LogicalFunction() { - @Override - protected boolean evaluate(ValueEval arg) { - if (arg instanceof ErrorEval) { - return arg != ErrorEval.NA; - } - return false; - } - }; - - /** - * Implementation for Excel ISNA() function.

        - * - * Syntax:
        - * ISNA(value)

        - * - * value The value to be tested
        - *
        - * Returns TRUE if the specified value is '#N/A', FALSE otherwise. - */ - public static final Function ISNA = new LogicalFunction() { - - protected boolean evaluate(ValueEval arg) { - return arg == ErrorEval.NA; - } - }; - - public static final Function ISREF = new Fixed1ArgFunction() { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - if (arg0 instanceof RefEval || arg0 instanceof AreaEval) { - return BoolEval.TRUE; - } - return BoolEval.FALSE; - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Lookup.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Lookup.java deleted file mode 100644 index 10f8a09a7..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Lookup.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; -import org.apache.poi.ss.formula.TwoDEval; - -/** - * Implementation of Excel function LOOKUP.

        - * - * LOOKUP finds an index row in a lookup table by the first column value and returns the value from another column. - * - * Syntax:
        - * VLOOKUP(lookup_value, lookup_vector, result_vector)

        - * - * lookup_value The value to be found in the lookup vector.
        - * lookup_vector An area reference for the lookup data.
        - * result_vector Single row or single column area reference from which the result value is chosen.
        - * - * @author Josh Micich - */ -public final class Lookup extends Var2or3ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - // complex rules to choose lookupVector and resultVector from the single area ref - throw new RuntimeException("Two arg version of LOOKUP not supported yet"); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - try { - ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - TwoDEval aeLookupVector = LookupUtils.resolveTableArrayArg(arg1); - TwoDEval aeResultVector = LookupUtils.resolveTableArrayArg(arg2); - - ValueVector lookupVector = createVector(aeLookupVector); - ValueVector resultVector = createVector(aeResultVector); - if(lookupVector.getSize() > resultVector.getSize()) { - // Excel seems to handle this by accessing past the end of the result vector. - throw new RuntimeException("Lookup vector and result vector of differing sizes not supported yet"); - } - int index = LookupUtils.lookupIndexOfValue(lookupValue, lookupVector, true); - - return resultVector.getItem(index); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private static ValueVector createVector(TwoDEval ae) { - ValueVector result = LookupUtils.createVector(ae); - if (result != null) { - return result; - } - // extra complexity required to emulate the way LOOKUP can handles these abnormal cases. - throw new RuntimeException("non-vector lookup or result areas not supported yet"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java b/trunk/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java deleted file mode 100644 index fce264245..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java +++ /dev/null @@ -1,660 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.NumericValueEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH - */ -final class LookupUtils { - - /** - * Represents a single row or column within an AreaEval. - */ - public interface ValueVector { - ValueEval getItem(int index); - int getSize(); - } - - - private static final class RowVector implements ValueVector { - - private final TwoDEval _tableArray; - private final int _size; - private final int _rowIndex; - - public RowVector(TwoDEval tableArray, int rowIndex) { - _rowIndex = rowIndex; - int lastRowIx = tableArray.getHeight() - 1; - if(rowIndex < 0 || rowIndex > lastRowIx) { - throw new IllegalArgumentException("Specified row index (" + rowIndex - + ") is outside the allowed range (0.." + lastRowIx + ")"); - } - _tableArray = tableArray; - _size = tableArray.getWidth(); - } - - public ValueEval getItem(int index) { - if(index > _size) { - throw new ArrayIndexOutOfBoundsException("Specified index (" + index - + ") is outside the allowed range (0.." + (_size-1) + ")"); - } - return _tableArray.getValue(_rowIndex, index); - } - public int getSize() { - return _size; - } - } - - private static final class ColumnVector implements ValueVector { - - private final TwoDEval _tableArray; - private final int _size; - private final int _columnIndex; - - public ColumnVector(TwoDEval tableArray, int columnIndex) { - _columnIndex = columnIndex; - int lastColIx = tableArray.getWidth()-1; - if(columnIndex < 0 || columnIndex > lastColIx) { - throw new IllegalArgumentException("Specified column index (" + columnIndex - + ") is outside the allowed range (0.." + lastColIx + ")"); - } - _tableArray = tableArray; - _size = _tableArray.getHeight(); - } - - public ValueEval getItem(int index) { - if(index > _size) { - throw new ArrayIndexOutOfBoundsException("Specified index (" + index - + ") is outside the allowed range (0.." + (_size-1) + ")"); - } - return _tableArray.getValue(index, _columnIndex); - } - public int getSize() { - return _size; - } - } - - private static final class SheetVector implements ValueVector { - private final RefEval _re; - private final int _size; - - public SheetVector(RefEval re) { - _size = re.getNumberOfSheets(); - _re = re; - } - - public ValueEval getItem(int index) { - if(index >= _size) { - throw new ArrayIndexOutOfBoundsException("Specified index (" + index - + ") is outside the allowed range (0.." + (_size-1) + ")"); - } - int sheetIndex = _re.getFirstSheetIndex() + index; - return _re.getInnerValueEval(sheetIndex); - } - public int getSize() { - return _size; - } - } - - public static ValueVector createRowVector(TwoDEval tableArray, int relativeRowIndex) { - return new RowVector(tableArray, relativeRowIndex); - } - public static ValueVector createColumnVector(TwoDEval tableArray, int relativeColumnIndex) { - return new ColumnVector(tableArray, relativeColumnIndex); - } - /** - * @return null if the supplied area is neither a single row nor a single colum - */ - public static ValueVector createVector(TwoDEval ae) { - if (ae.isColumn()) { - return createColumnVector(ae, 0); - } - if (ae.isRow()) { - return createRowVector(ae, 0); - } - return null; - } - - public static ValueVector createVector(RefEval re) { - return new SheetVector(re); - } - - /** - * Enumeration to support 4 valued comparison results.

        - * Excel lookup functions have complex behaviour in the case where the lookup array has mixed - * types, and/or is unordered. Contrary to suggestions in some Excel documentation, there - * does not appear to be a universal ordering across types. The binary search algorithm used - * changes behaviour when the evaluated 'mid' value has a different type to the lookup value.

        - * - * A simple int might have done the same job, but there is risk in confusion with the well - * known Comparable.compareTo() and Comparator.compare() which both use - * a ubiquitous 3 value result encoding. - */ - public static final class CompareResult { - private final boolean _isTypeMismatch; - private final boolean _isLessThan; - private final boolean _isEqual; - private final boolean _isGreaterThan; - - private CompareResult(boolean isTypeMismatch, int simpleCompareResult) { - if(isTypeMismatch) { - _isTypeMismatch = true; - _isLessThan = false; - _isEqual = false; - _isGreaterThan = false; - } else { - _isTypeMismatch = false; - _isLessThan = simpleCompareResult < 0; - _isEqual = simpleCompareResult == 0; - _isGreaterThan = simpleCompareResult > 0; - } - } - public static final CompareResult TYPE_MISMATCH = new CompareResult(true, 0); - public static final CompareResult LESS_THAN = new CompareResult(false, -1); - public static final CompareResult EQUAL = new CompareResult(false, 0); - public static final CompareResult GREATER_THAN = new CompareResult(false, +1); - - public static final CompareResult valueOf(int simpleCompareResult) { - if(simpleCompareResult < 0) { - return LESS_THAN; - } - if(simpleCompareResult > 0) { - return GREATER_THAN; - } - return EQUAL; - } - - public static final CompareResult valueOf(boolean matches) { - if(matches) { - return EQUAL ; - } - return LESS_THAN; - } - - - public boolean isTypeMismatch() { - return _isTypeMismatch; - } - public boolean isLessThan() { - return _isLessThan; - } - public boolean isEqual() { - return _isEqual; - } - public boolean isGreaterThan() { - return _isGreaterThan; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - - private String formatAsString() { - if(_isTypeMismatch) { - return "TYPE_MISMATCH"; - } - if(_isLessThan) { - return "LESS_THAN"; - } - if(_isEqual) { - return "EQUAL"; - } - if(_isGreaterThan) { - return "GREATER_THAN"; - } - // toString must be reliable - return "??error??"; - } - } - - public interface LookupValueComparer { - /** - * @return one of 4 instances or CompareResult: LESS_THAN, EQUAL, - * GREATER_THAN or TYPE_MISMATCH - */ - CompareResult compareTo(ValueEval other); - } - - private static abstract class LookupValueComparerBase implements LookupValueComparer { - - private final Class _targetClass; - protected LookupValueComparerBase(ValueEval targetValue) { - if(targetValue == null) { - throw new RuntimeException("targetValue cannot be null"); - } - _targetClass = targetValue.getClass(); - } - public final CompareResult compareTo(ValueEval other) { - if (other == null) { - throw new RuntimeException("compare to value cannot be null"); - } - if (_targetClass != other.getClass()) { - return CompareResult.TYPE_MISMATCH; - } - return compareSameType(other); - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(getValueAsString()); - sb.append("]"); - return sb.toString(); - } - protected abstract CompareResult compareSameType(ValueEval other); - /** used only for debug purposes */ - protected abstract String getValueAsString(); - } - - - private static final class StringLookupComparer extends LookupValueComparerBase { - - private String _value; - private final Pattern _wildCardPattern; - private boolean _matchExact; - private boolean _isMatchFunction; - - protected StringLookupComparer(StringEval se, boolean matchExact, boolean isMatchFunction) { - super(se); - _value = se.getStringValue(); - _wildCardPattern = Countif.StringMatcher.getWildCardPattern(_value); - _matchExact = matchExact; - _isMatchFunction = isMatchFunction; - } - - protected CompareResult compareSameType(ValueEval other) { - StringEval se = (StringEval) other; - - String stringValue = se.getStringValue(); - if (_wildCardPattern != null) { - Matcher matcher = _wildCardPattern.matcher(stringValue); - boolean matches = matcher.matches(); - - if (_isMatchFunction || - !_matchExact) { - return CompareResult.valueOf(matches); - } - } - - return CompareResult.valueOf(_value.compareToIgnoreCase(stringValue)); - } - protected String getValueAsString() { - return _value; - } - } - private static final class NumberLookupComparer extends LookupValueComparerBase { - private double _value; - - protected NumberLookupComparer(NumberEval ne) { - super(ne); - _value = ne.getNumberValue(); - } - protected CompareResult compareSameType(ValueEval other) { - NumberEval ne = (NumberEval) other; - return CompareResult.valueOf(Double.compare(_value, ne.getNumberValue())); - } - protected String getValueAsString() { - return String.valueOf(_value); - } - } - private static final class BooleanLookupComparer extends LookupValueComparerBase { - private boolean _value; - - protected BooleanLookupComparer(BoolEval be) { - super(be); - _value = be.getBooleanValue(); - } - protected CompareResult compareSameType(ValueEval other) { - BoolEval be = (BoolEval) other; - boolean otherVal = be.getBooleanValue(); - if(_value == otherVal) { - return CompareResult.EQUAL; - } - // TRUE > FALSE - if(_value) { - return CompareResult.GREATER_THAN; - } - return CompareResult.LESS_THAN; - } - protected String getValueAsString() { - return String.valueOf(_value); - } - } - - /** - * Processes the third argument to VLOOKUP, or HLOOKUP (col_index_num - * or row_index_num respectively).
        - * Sample behaviour: - * - * - * - * - * - * - * - * - * - * - * - * - * - *
        Input   ReturnValue  Thrown Error
        54 
        2.92 
        "5"4 
        "2.18e1"21 
        "-$2"-3*
        FALSE-1*
        TRUE0 
        "TRUE" #REF!
        "abc" #REF!
        "" #REF!
        <blank> #VALUE!

        - * - * Note - out of range errors (result index too high) are handled by the caller. - * @return column or row index as a zero-based value, never negative. - * @throws EvaluationException when the specified arg cannot be coerced to a non-negative integer - */ - public static int resolveRowOrColIndexArg(ValueEval rowColIndexArg, int srcCellRow, int srcCellCol) throws EvaluationException { - if(rowColIndexArg == null) { - throw new IllegalArgumentException("argument must not be null"); - } - - ValueEval veRowColIndexArg; - try { - veRowColIndexArg = OperandResolver.getSingleValue(rowColIndexArg, srcCellRow, (short)srcCellCol); - } catch (EvaluationException e) { - // All errors get translated to #REF! - throw EvaluationException.invalidRef(); - } - int oneBasedIndex; - if(veRowColIndexArg instanceof StringEval) { - StringEval se = (StringEval) veRowColIndexArg; - String strVal = se.getStringValue(); - Double dVal = OperandResolver.parseDouble(strVal); - if(dVal == null) { - // String does not resolve to a number. Raise #REF! error. - throw EvaluationException.invalidRef(); - // This includes text booleans "TRUE" and "FALSE". They are not valid. - } - // else - numeric value parses OK - } - // actual BoolEval values get interpreted as FALSE->0 and TRUE->1 - oneBasedIndex = OperandResolver.coerceValueToInt(veRowColIndexArg); - if (oneBasedIndex < 1) { - // note this is asymmetric with the errors when the index is too large (#REF!) - throw EvaluationException.invalidValue(); - } - return oneBasedIndex - 1; // convert to zero based - } - - - - /** - * The second argument (table_array) should be an area ref, but can actually be a cell ref, in - * which case it is interpreted as a 1x1 area ref. Other scalar values cause #VALUE! error. - */ - public static TwoDEval resolveTableArrayArg(ValueEval eval) throws EvaluationException { - if (eval instanceof TwoDEval) { - return (TwoDEval) eval; - } - - if(eval instanceof RefEval) { - RefEval refEval = (RefEval) eval; - // Make this cell ref look like a 1x1 area ref. - - // It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval. - return refEval.offset(0, 0, 0, 0); - } - throw EvaluationException.invalidValue(); - } - - - /** - * Resolves the last (optional) parameter (range_lookup) to the VLOOKUP and HLOOKUP functions. - * @param rangeLookupArg must not be null - */ - public static boolean resolveRangeLookupArg(ValueEval rangeLookupArg, int srcCellRow, int srcCellCol) throws EvaluationException { - - ValueEval valEval = OperandResolver.getSingleValue(rangeLookupArg, srcCellRow, srcCellCol); - if(valEval instanceof BlankEval) { - // Tricky: - // fourth arg supplied but evaluates to blank - // this does not get the default value - return false; - } - if(valEval instanceof BoolEval) { - // Happy day flow - BoolEval boolEval = (BoolEval) valEval; - return boolEval.getBooleanValue(); - } - - if (valEval instanceof StringEval) { - String stringValue = ((StringEval) valEval).getStringValue(); - if(stringValue.length() < 1) { - // More trickiness: - // Empty string is not the same as BlankEval. It causes #VALUE! error - throw EvaluationException.invalidValue(); - } - // TODO move parseBoolean to OperandResolver - Boolean b = Countif.parseBoolean(stringValue); - if(b != null) { - // string converted to boolean OK - return b.booleanValue(); - } - // Even more trickiness: - // Note - even if the StringEval represents a number value (for example "1"), - // Excel does not resolve it to a boolean. - throw EvaluationException.invalidValue(); - // This is in contrast to the code below,, where NumberEvals values (for - // example 0.01) *do* resolve to equivalent boolean values. - } - if (valEval instanceof NumericValueEval) { - NumericValueEval nve = (NumericValueEval) valEval; - // zero is FALSE, everything else is TRUE - return 0.0 != nve.getNumberValue(); - } - throw new RuntimeException("Unexpected eval type (" + valEval.getClass().getName() + ")"); - } - - public static int lookupIndexOfValue(ValueEval lookupValue, ValueVector vector, boolean isRangeLookup) throws EvaluationException { - LookupValueComparer lookupComparer = createLookupComparer(lookupValue, isRangeLookup, false); - int result; - if(isRangeLookup) { - result = performBinarySearch(vector, lookupComparer); - } else { - result = lookupIndexOfExactValue(lookupComparer, vector); - } - if(result < 0) { - throw new EvaluationException(ErrorEval.NA); - } - return result; - } - - - /** - * Finds first (lowest index) exact occurrence of specified value. - * @param lookupComparer the value to be found in column or row vector - * @param vector the values to be searched. For VLOOKUP this is the first column of the - * tableArray. For HLOOKUP this is the first row of the tableArray. - * @return zero based index into the vector, -1 if value cannot be found - */ - private static int lookupIndexOfExactValue(LookupValueComparer lookupComparer, ValueVector vector) { - - // find first occurrence of lookup value - int size = vector.getSize(); - for (int i = 0; i < size; i++) { - if(lookupComparer.compareTo(vector.getItem(i)).isEqual()) { - return i; - } - } - return -1; - } - - - /** - * Encapsulates some standard binary search functionality so the unusual Excel behaviour can - * be clearly distinguished. - */ - private static final class BinarySearchIndexes { - - private int _lowIx; - private int _highIx; - - public BinarySearchIndexes(int highIx) { - _lowIx = -1; - _highIx = highIx; - } - - /** - * @return -1 if the search range is empty - */ - public int getMidIx() { - int ixDiff = _highIx - _lowIx; - if(ixDiff < 2) { - return -1; - } - return _lowIx + (ixDiff / 2); - } - - public int getLowIx() { - return _lowIx; - } - public int getHighIx() { - return _highIx; - } - public void narrowSearch(int midIx, boolean isLessThan) { - if(isLessThan) { - _highIx = midIx; - } else { - _lowIx = midIx; - } - } - } - /** - * Excel has funny behaviour when the some elements in the search vector are the wrong type. - * - */ - private static int performBinarySearch(ValueVector vector, LookupValueComparer lookupComparer) { - // both low and high indexes point to values assumed too low and too high. - BinarySearchIndexes bsi = new BinarySearchIndexes(vector.getSize()); - - while(true) { - int midIx = bsi.getMidIx(); - - if(midIx < 0) { - return bsi.getLowIx(); - } - CompareResult cr = lookupComparer.compareTo(vector.getItem(midIx)); - if(cr.isTypeMismatch()) { - int newMidIx = handleMidValueTypeMismatch(lookupComparer, vector, bsi, midIx); - if(newMidIx < 0) { - continue; - } - midIx = newMidIx; - cr = lookupComparer.compareTo(vector.getItem(midIx)); - } - if(cr.isEqual()) { - return findLastIndexInRunOfEqualValues(lookupComparer, vector, midIx, bsi.getHighIx()); - } - bsi.narrowSearch(midIx, cr.isLessThan()); - } - } - /** - * Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the - * first compatible value. - * @param midIx 'mid' index (value which has the wrong type) - * @return usually -1, signifying that the BinarySearchIndex has been narrowed to the new mid - * index. Zero or greater signifies that an exact match for the lookup value was found - */ - private static int handleMidValueTypeMismatch(LookupValueComparer lookupComparer, ValueVector vector, - BinarySearchIndexes bsi, int midIx) { - int newMid = midIx; - int highIx = bsi.getHighIx(); - - while(true) { - newMid++; - if(newMid == highIx) { - // every element from midIx to highIx was the wrong type - // move highIx down to the low end of the mid values - bsi.narrowSearch(midIx, true); - return -1; - } - CompareResult cr = lookupComparer.compareTo(vector.getItem(newMid)); - if(cr.isLessThan() && newMid == highIx-1) { - // move highIx down to the low end of the mid values - bsi.narrowSearch(midIx, true); - return -1; - // but only when "newMid == highIx-1"? slightly weird. - // It would seem more efficient to always do this. - } - if(cr.isTypeMismatch()) { - // keep stepping over values until the right type is found - continue; - } - if(cr.isEqual()) { - return newMid; - } - // Note - if moving highIx down (due to lookup - * - * Syntax:
        - * MATCH(lookup_value, lookup_array, match_type)

        - * - * Returns a 1-based index specifying at what position in the lookup_array the specified - * lookup_value is found.

        - * - * Specific matching behaviour can be modified with the optional match_type parameter. - * - * - * - * - * - * - *
        ValueMatching Behaviour
        1(default) find the largest value that is less than or equal to lookup_value. - * The lookup_array must be in ascending order*.
        0find the first value that is exactly equal to lookup_value. - * The lookup_array can be in any order.
        -1find the smallest value that is greater than or equal to lookup_value. - * The lookup_array must be in descending order*.
        - * - * * Note regarding order - For the match_type cases that require the lookup_array to - * be ordered, MATCH() can produce incorrect results if this requirement is not met. Observed - * behaviour in Excel is to return the lowest index value for which every item after that index - * breaks the match rule.
        - * The (ascending) sort order expected by MATCH() is:
        - * numbers (low to high), strings (A to Z), boolean (FALSE to TRUE)
        - * MATCH() ignores all elements in the lookup_array with a different type to the lookup_value. - * Type conversion of the lookup_array elements is never performed. - */ -public final class Match extends Var2or3ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - // default match_type is 1.0 - return eval(srcRowIndex, srcColumnIndex, arg0, arg1, 1.0); - } - - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - - double match_type; - - try { - match_type = evaluateMatchTypeArg(arg2, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - // Excel/MATCH() seems to have slightly abnormal handling of errors with - // the last parameter. Errors do not propagate up. Every error gets - // translated into #REF! - return ErrorEval.REF_INVALID; - } - - return eval(srcRowIndex, srcColumnIndex, arg0, arg1, match_type); - } - - private static ValueEval eval(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - double match_type) { - boolean matchExact = match_type == 0; - // Note - Excel does not strictly require -1 and +1 - boolean findLargestLessThanOrEqual = match_type > 0; - - try { - ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - ValueVector lookupRange = evaluateLookupRange(arg1); - int index = findIndexOfValue(lookupValue, lookupRange, matchExact, findLargestLessThanOrEqual); - return new NumberEval(index + 1); // +1 to convert to 1-based - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private static final class SingleValueVector implements ValueVector { - - private final ValueEval _value; - - public SingleValueVector(ValueEval value) { - _value = value; - } - - public ValueEval getItem(int index) { - if (index != 0) { - throw new RuntimeException("Invalid index (" - + index + ") only zero is allowed"); - } - return _value; - } - - public int getSize() { - return 1; - } - } - - private static ValueVector evaluateLookupRange(ValueEval eval) throws EvaluationException { - if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - if (re.getNumberOfSheets() == 1) { - return new SingleValueVector(re.getInnerValueEval(re.getFirstSheetIndex())); - } else { - return LookupUtils.createVector(re); - } - } - if (eval instanceof TwoDEval) { - ValueVector result = LookupUtils.createVector((TwoDEval)eval); - if (result == null) { - throw new EvaluationException(ErrorEval.NA); - } - return result; - } - - // Error handling for lookup_range arg is also unusual - if(eval instanceof NumericValueEval) { - throw new EvaluationException(ErrorEval.NA); - } - if (eval instanceof StringEval) { - StringEval se = (StringEval) eval; - Double d = OperandResolver.parseDouble(se.getStringValue()); - if(d == null) { - // plain string - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - // else looks like a number - throw new EvaluationException(ErrorEval.NA); - } - throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")"); - } - - - - private static double evaluateMatchTypeArg(ValueEval arg, int srcCellRow, int srcCellCol) - throws EvaluationException { - ValueEval match_type = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - - if(match_type instanceof ErrorEval) { - throw new EvaluationException((ErrorEval)match_type); - } - if(match_type instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) match_type; - return ne.getNumberValue(); - } - if (match_type instanceof StringEval) { - StringEval se = (StringEval) match_type; - Double d = OperandResolver.parseDouble(se.getStringValue()); - if(d == null) { - // plain string - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - // if the string parses as a number, it is OK - return d.doubleValue(); - } - throw new RuntimeException("Unexpected match_type type (" + match_type.getClass().getName() + ")"); - } - - /** - * @return zero based index - */ - private static int findIndexOfValue(ValueEval lookupValue, ValueVector lookupRange, - boolean matchExact, boolean findLargestLessThanOrEqual) throws EvaluationException { - - LookupValueComparer lookupComparer = createLookupComparer(lookupValue, matchExact); - - int size = lookupRange.getSize(); - if(matchExact) { - for (int i = 0; i < size; i++) { - if(lookupComparer.compareTo(lookupRange.getItem(i)).isEqual()) { - return i; - } - } - throw new EvaluationException(ErrorEval.NA); - } - - if(findLargestLessThanOrEqual) { - // Note - backward iteration - for (int i = size - 1; i>=0; i--) { - CompareResult cmp = lookupComparer.compareTo(lookupRange.getItem(i)); - if(cmp.isTypeMismatch()) { - continue; - } - if(!cmp.isLessThan()) { - return i; - } - } - throw new EvaluationException(ErrorEval.NA); - } - - // else - find smallest greater than or equal to - // TODO - is binary search used for (match_type==+1) ? - for (int i = 0; iIf n is negative, the resulting value is obtained - * as the round value of absolute value of n multiplied - * by the sign value of n (@see MathX.sign(double d)). - * Thus, -0.6666666 rounded to p=0 will give -1 not 0. - *

        If n is NaN, returned value is NaN. - * @param n - * @param p - */ - public static double round(double n, int p) { - double retval; - - if (Double.isNaN(n) || Double.isInfinite(n)) { - retval = Double.NaN; - } - else { - retval = new java.math.BigDecimal(NumberToTextConverter.toText(n)).setScale(p, java.math.RoundingMode.HALF_UP).doubleValue(); - } - - return retval; - } - - /** - * Returns a value rounded-up to p digits after decimal. - * If p is negative, then the number is rounded to - * places to the left of the decimal point. eg. - * 10.23 rounded to -1 will give: 20. If p is zero, - * the returned value is rounded to the nearest integral - * value. - *

        If n is negative, the resulting value is obtained - * as the round-up value of absolute value of n multiplied - * by the sign value of n (@see MathX.sign(double d)). - * Thus, -0.2 rounded-up to p=0 will give -1 not 0. - *

        If n is NaN, returned value is NaN. - * @param n - * @param p - */ - public static double roundUp(double n, int p) { - double retval; - - if (Double.isNaN(n) || Double.isInfinite(n)) { - retval = Double.NaN; - } - else { - retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.UP).doubleValue(); - } - - return retval; - } - - /** - * Returns a value rounded to p digits after decimal. - * If p is negative, then the number is rounded to - * places to the left of the decimal point. eg. - * 10.23 rounded to -1 will give: 10. If p is zero, - * the returned value is rounded to the nearest integral - * value. - *

        If n is negative, the resulting value is obtained - * as the round-up value of absolute value of n multiplied - * by the sign value of n (@see MathX.sign(double d)). - * Thus, -0.8 rounded-down to p=0 will give 0 not -1. - *

        If n is NaN, returned value is NaN. - * @param n - * @param p - */ - public static double roundDown(double n, int p) { - double retval; - - if (Double.isNaN(n) || Double.isInfinite(n)) { - retval = Double.NaN; - } - else { - retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.DOWN).doubleValue(); - } - - return retval; - } - - - /** - * If d < 0, returns short -1 - *
        - * If d > 0, returns short 1 - *
        - * If d == 0, returns short 0 - *

        If d is NaN, then 1 will be returned. It is the responsibility - * of caller to check for d isNaN if some other value is desired. - * @param d - */ - public static short sign(double d) { - return (short) ((d == 0) - ? 0 - : (d < 0) - ? -1 - : 1); - } - - /** - * average of all values - * @param values - */ - public static double average(double[] values) { - double ave = 0; - double sum = 0; - for (int i=0, iSize=values.length; i 0) { - product = 1; - for (int i=0, iSize=values.length; i - * When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s; - *
        - * n and s are invalid if any of following conditions are true: - *

          - *
        • s is zero
        • - *
        • n is negative and s is positive
        • - *
        • n is positive and s is negative
        • - *
        - * In all such cases, Double.NaN is returned. - * @param n - * @param s - */ - public static double floor(double n, double s) { - double f; - - if ((n<0 && s>0) || (n>0 && s<0) || (s==0 && n!=0)) { - f = Double.NaN; - } - else { - f = (n==0 || s==0) ? 0 : Math.floor(n/s) * s; - } - - return f; - } - - /** - * Note: this function is different from java.lang.Math.ceil(..). - *

        - * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s; - *
        - * n and s are invalid if any of following conditions are true: - *

          - *
        • s is zero
        • - *
        • n is negative and s is positive
        • - *
        • n is positive and s is negative
        • - *
        - * In all such cases, Double.NaN is returned. - * @param n - * @param s - */ - public static double ceiling(double n, double s) { - double c; - - if ((n<0 && s>0) || (n>0 && s<0)) { - c = Double.NaN; - } - else { - c = (n == 0 || s == 0) ? 0 : Math.ceil(n/s) * s; - } - - return c; - } - - /** - *
        for all n >= 1; factorial n = n * (n-1) * (n-2) * ... * 1 - *
        else if n == 0; factorial n = 1 - *
        else if n < 0; factorial n = Double.NaN - *
        Loss of precision can occur if n is large enough. - * If n is large so that the resulting value would be greater - * than Double.MAX_VALUE; Double.POSITIVE_INFINITY is returned. - * If n < 0, Double.NaN is returned. - * @param n - */ - public static double factorial(int n) { - double d = 1; - - if (n >= 0) { - if (n <= 170) { - for (int i=1; i<=n; i++) { - d *= i; - } - } - else { - d = Double.POSITIVE_INFINITY; - } - } - else { - d = Double.NaN; - } - return d; - } - - - /** - * returns the remainder resulting from operation: - * n / d. - *
        The result has the sign of the divisor. - *
        Examples: - *
          - *
        • mod(3.4, 2) = 1.4
        • - *
        • mod(-3.4, 2) = 0.6
        • - *
        • mod(-3.4, -2) = -1.4
        • - *
        • mod(3.4, -2) = -0.6
        • - *
        - * If d == 0, result is NaN - * @param n - * @param d - */ - public static double mod(double n, double d) { - double result = 0; - - if (d == 0) { - result = Double.NaN; - } - else if (sign(n) == sign(d)) { - result = n % d; - } - else { - result = ((n % d) + d) % d; - } - - return result; - } - - /** - * inverse hyperbolic cosine - * @param d - */ - public static double acosh(double d) { - return Math.log(Math.sqrt(Math.pow(d, 2) - 1) + d); - } - - /** - * inverse hyperbolic sine - * @param d - */ - public static double asinh(double d) { - return Math.log(Math.sqrt(d*d + 1) + d); - } - - /** - * inverse hyperbolic tangent - * @param d - */ - public static double atanh(double d) { - return Math.log((1 + d)/(1 - d)) / 2; - } - - /** - * hyperbolic cosine - * @param d - */ - public static double cosh(double d) { - double ePowX = Math.pow(Math.E, d); - double ePowNegX = Math.pow(Math.E, -d); - return (ePowX + ePowNegX) / 2; - } - - /** - * hyperbolic sine - * @param d - */ - public static double sinh(double d) { - double ePowX = Math.pow(Math.E, d); - double ePowNegX = Math.pow(Math.E, -d); - return (ePowX - ePowNegX) / 2; - } - - /** - * hyperbolic tangent - * @param d - */ - public static double tanh(double d) { - double ePowX = Math.pow(Math.E, d); - double ePowNegX = Math.pow(Math.E, -d); - return (ePowX - ePowNegX) / (ePowX + ePowNegX); - } - - - /** - * returns the total number of combinations possible when - * k items are chosen out of total of n items. If the number - * is too large, loss of precision may occur (since returned - * value is double). If the returned value is larger than - * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned. - * If either of the parameters is negative, Double.NaN is returned. - * @param n - * @param k - */ - public static double nChooseK(int n, int k) { - double d = 1; - if (n<0 || k<0 || n 0 ? MathX.max(values) : 0; - } - }; - public static final Function MINA = new MinaMaxa() { - protected double evaluate(double[] values) { - return values.length > 0 ? MathX.min(values) : 0; - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Mirr.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Mirr.java deleted file mode 100644 index 934f50881..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Mirr.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; - -/** - * Calculates Modified internal rate of return. Syntax is MIRR(cash_flow_values, finance_rate, reinvest_rate) - * - *

        Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both the cost - * of the investment and the interest received on reinvestment of cash.

        - * - * Values is an array or a reference to cells that contain numbers. These numbers represent a series of payments (negative values) and income (positive values) occurring at regular periods. - *
          - *
        • Values must contain at least one positive value and one negative value to calculate the modified internal rate of return. Otherwise, MIRR returns the #DIV/0! error value.
        • - *
        • If an array or reference argument contains text, logical values, or empty cells, those values are ignored; however, cells with the value zero are included.
        • - *
        - * - * Finance_rate is the interest rate you pay on the money used in the cash flows. - * Reinvest_rate is the interest rate you receive on the cash flows as you reinvest them. - * - * @author Carlos Delgado (carlos dot del dot est at gmail dot com) - * @author Cedric Walter (cedric dot walter at gmail dot com) - * - * @see Wikipedia on MIRR - * @see Excel MIRR - * @see Irr - */ -public class Mirr extends MultiOperandNumericFunction { - - public Mirr() { - super(false, false); - } - - @Override - protected int getMaxNumOperands() { - return 3; - } - - @Override - protected double evaluate(double[] values) throws EvaluationException { - - double financeRate = values[values.length-1]; - double reinvestRate = values[values.length-2]; - - double[] mirrValues = new double[values.length - 2]; - System.arraycopy(values, 0, mirrValues, 0, mirrValues.length); - - boolean mirrValuesAreAllNegatives = true; - for (double mirrValue : mirrValues) { - mirrValuesAreAllNegatives &= mirrValue < 0; - } - if (mirrValuesAreAllNegatives) { - return -1.0d; - } - - boolean mirrValuesAreAllPositives = true; - for (double mirrValue : mirrValues) { - mirrValuesAreAllPositives &= mirrValue > 0; - } - if (mirrValuesAreAllPositives) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - - return mirr(mirrValues, financeRate, reinvestRate); - } - - private static double mirr(double[] in, double financeRate, double reinvestRate) { - double value = 0; - int numOfYears = in.length - 1; - double pv = 0; - double fv = 0; - - int indexN = 0; - for (double anIn : in) { - if (anIn < 0) { - pv += anIn / Math.pow(1 + financeRate + reinvestRate, indexN++); - } - } - - for (double anIn : in) { - if (anIn > 0) { - fv += anIn * Math.pow(1 + financeRate, numOfYears - indexN++); - } - } - - if (fv != 0 && pv != 0) { - value = Math.pow(-fv / pv, 1d / numOfYears) - 1; - } - return value; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Mode.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Mode.java deleted file mode 100644 index 5f21324d5..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Mode.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Mode implements Function { - - /** - * if v is zero length or contains no duplicates, return value is - * Double.NaN. Else returns the value that occurs most times and if there is - * a tie, returns the first such value. - * - * @param v - */ - public static double evaluate(double[] v) throws EvaluationException { - if (v.length < 2) { - throw new EvaluationException(ErrorEval.NA); - } - - // very naive impl, may need to be optimized - int[] counts = new int[v.length]; - Arrays.fill(counts, 1); - for (int i = 0, iSize = v.length; i < iSize; i++) { - for (int j = i + 1, jSize = v.length; j < jSize; j++) { - if (v[i] == v[j]) - counts[i]++; - } - } - double maxv = 0; - int maxc = 0; - for (int i = 0, iSize = counts.length; i < iSize; i++) { - if (counts[i] > maxc) { - maxv = v[i]; - maxc = counts[i]; - } - } - if (maxc > 1) { - return maxv; - } - throw new EvaluationException(ErrorEval.NA); - - } - - public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - double result; - try { - List temp = new ArrayList(); - for (int i = 0; i < args.length; i++) { - collectValues(args[i], temp); - } - double[] values = new double[temp.size()]; - for (int i = 0; i < values.length; i++) { - values[i] = temp.get(i).doubleValue(); - } - result = evaluate(values); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - - private static void collectValues(ValueEval arg, List temp) throws EvaluationException { - if (arg instanceof TwoDEval) { - TwoDEval ae = (TwoDEval) arg; - int width = ae.getWidth(); - int height = ae.getHeight(); - for (int rrIx = 0; rrIx < height; rrIx++) { - for (int rcIx = 0; rcIx < width; rcIx++) { - ValueEval ve1 = ae.getValue(rrIx, rcIx); - collectValue(ve1, temp, false); - } - } - return; - } - if (arg instanceof RefEval) { - RefEval re = (RefEval) arg; - final int firstSheetIndex = re.getFirstSheetIndex(); - final int lastSheetIndex = re.getLastSheetIndex(); - for (int sIx = firstSheetIndex; sIx <= lastSheetIndex; sIx++) { - collectValue(re.getInnerValueEval(sIx), temp, true); - } - return; - } - collectValue(arg, temp, true); - - } - - private static void collectValue(ValueEval arg, List temp, boolean mustBeNumber) - throws EvaluationException { - if (arg instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) arg); - } - if (arg == BlankEval.instance || arg instanceof BoolEval || arg instanceof StringEval) { - if (mustBeNumber) { - throw EvaluationException.invalidValue(); - } - return; - } - if (arg instanceof NumberEval) { - temp.add(new Double(((NumberEval) arg).getNumberValue())); - return; - } - throw new RuntimeException("Unexpected value type (" + arg.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java deleted file mode 100644 index 6e0f364f1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java +++ /dev/null @@ -1,222 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.ThreeDEval; -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.NumericValueEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringValueEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * This is the super class for all excel function evaluator - * classes that take variable number of operands, and - * where the order of operands does not matter - */ -public abstract class MultiOperandNumericFunction implements Function { - - private final boolean _isReferenceBoolCounted; - private final boolean _isBlankCounted; - - protected MultiOperandNumericFunction(boolean isReferenceBoolCounted, boolean isBlankCounted) { - _isReferenceBoolCounted = isReferenceBoolCounted; - _isBlankCounted = isBlankCounted; - } - - static final double[] EMPTY_DOUBLE_ARRAY = { }; - - private static class DoubleList { - private double[] _array; - private int _count; - - public DoubleList() { - _array = new double[8]; - _count = 0; - } - - public double[] toArray() { - if(_count < 1) { - return EMPTY_DOUBLE_ARRAY; - } - double[] result = new double[_count]; - System.arraycopy(_array, 0, result, 0, _count); - return result; - } - - private void ensureCapacity(int reqSize) { - if(reqSize > _array.length) { - int newSize = reqSize * 3 / 2; // grow with 50% extra - double[] newArr = new double[newSize]; - System.arraycopy(_array, 0, newArr, 0, _count); - _array = newArr; - } - } - - public void add(double value) { - ensureCapacity(_count + 1); - _array[_count] = value; - _count++; - } - } - - private static final int DEFAULT_MAX_NUM_OPERANDS = 30; - - public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - - double d; - try { - double[] values = getNumberArray(args); - d = evaluate(values); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - if (Double.isNaN(d) || Double.isInfinite(d)) - return ErrorEval.NUM_ERROR; - - return new NumberEval(d); - } - - protected abstract double evaluate(double[] values) throws EvaluationException; - - /** - * Maximum number of operands accepted by this function. - * Subclasses may override to change default value. - */ - protected int getMaxNumOperands() { - return DEFAULT_MAX_NUM_OPERANDS; - } - - /** - * Returns a double array that contains values for the numeric cells - * from among the list of operands. Blanks and Blank equivalent cells - * are ignored. Error operands or cells containing operands of type - * that are considered invalid and would result in #VALUE! error in - * excel cause this function to return null. - * - * @return never null - */ - protected final double[] getNumberArray(ValueEval[] operands) throws EvaluationException { - if (operands.length > getMaxNumOperands()) { - throw EvaluationException.invalidValue(); - } - DoubleList retval = new DoubleList(); - - for (int i=0, iSize=operands.length; iresult is NaN or Infinity - */ - public static final void checkValue(double result) throws EvaluationException { - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - } - - public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - double result; - try { - result = eval(args, srcCellRow, srcCellCol); - checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - - protected abstract double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException; - - /* -------------------------------------------------------------------------- */ - // intermediate sub-classes (one-arg, two-arg and multi-arg) - - public static abstract class OneArg extends Fixed1ArgFunction { - protected OneArg() { - // no fields to initialise - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - double result; - try { - double d = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - result = evaluate(d); - checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - protected final double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException { - if (args.length != 1) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - double d = singleOperandEvaluate(args[0], srcCellRow, srcCellCol); - return evaluate(d); - } - protected abstract double evaluate(double d) throws EvaluationException; - } - - public static abstract class TwoArg extends Fixed2ArgFunction { - protected TwoArg() { - // no fields to initialise - } - - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - double result; - try { - double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - result = evaluate(d0, d1); - checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - - protected abstract double evaluate(double d0, double d1) throws EvaluationException; - } - - /* -------------------------------------------------------------------------- */ - - public static final Function ABS = new OneArg() { - protected double evaluate(double d) { - return Math.abs(d); - } - }; - public static final Function ACOS = new OneArg() { - protected double evaluate(double d) { - return Math.acos(d); - } - }; - public static final Function ACOSH = new OneArg() { - protected double evaluate(double d) { - return MathX.acosh(d); - } - }; - public static final Function ASIN = new OneArg() { - protected double evaluate(double d) { - return Math.asin(d); - } - }; - public static final Function ASINH = new OneArg() { - protected double evaluate(double d) { - return MathX.asinh(d); - } - }; - public static final Function ATAN = new OneArg() { - protected double evaluate(double d) { - return Math.atan(d); - } - }; - public static final Function ATANH = new OneArg() { - protected double evaluate(double d) { - return MathX.atanh(d); - } - }; - public static final Function COS = new OneArg() { - protected double evaluate(double d) { - return Math.cos(d); - } - }; - public static final Function COSH = new OneArg() { - protected double evaluate(double d) { - return MathX.cosh(d); - } - }; - public static final Function DEGREES = new OneArg() { - protected double evaluate(double d) { - return Math.toDegrees(d); - } - }; - static final NumberEval DOLLAR_ARG2_DEFAULT = new NumberEval(2.0); - public static final Function DOLLAR = new Var1or2ArgFunction() { - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, DOLLAR_ARG2_DEFAULT); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1) { - double val; - double d1; - try { - val = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - // second arg converts to int by truncating toward zero - int nPlaces = (int)d1; - - if (nPlaces > 127) { - return ErrorEval.VALUE_INVALID; - } - - - // TODO - DOLLAR() function impl is NQR - // result should be StringEval, with leading '$' and thousands separators - // current junits are asserting incorrect behaviour - return new NumberEval(val); - } - }; - public static final Function EXP = new OneArg() { - protected double evaluate(double d) { - return Math.pow(Math.E, d); - } - }; - public static final Function FACT = new OneArg() { - protected double evaluate(double d) { - return MathX.factorial((int)d); - } - }; - public static final Function INT = new OneArg() { - protected double evaluate(double d) { - return Math.round(d-0.5); - } - }; - public static final Function LN = new OneArg() { - protected double evaluate(double d) { - return Math.log(d); - } - }; - public static final Function LOG10 = new OneArg() { - protected double evaluate(double d) { - return Math.log(d) / LOG_10_TO_BASE_e; - } - }; - public static final Function RADIANS = new OneArg() { - protected double evaluate(double d) { - return Math.toRadians(d); - } - }; - public static final Function SIGN = new OneArg() { - protected double evaluate(double d) { - return MathX.sign(d); - } - }; - public static final Function SIN = new OneArg() { - protected double evaluate(double d) { - return Math.sin(d); - } - }; - public static final Function SINH = new OneArg() { - protected double evaluate(double d) { - return MathX.sinh(d); - } - }; - public static final Function SQRT = new OneArg() { - protected double evaluate(double d) { - return Math.sqrt(d); - } - }; - - public static final Function TAN = new OneArg() { - protected double evaluate(double d) { - return Math.tan(d); - } - }; - public static final Function TANH = new OneArg() { - protected double evaluate(double d) { - return MathX.tanh(d); - } - }; - - /* -------------------------------------------------------------------------- */ - - public static final Function ATAN2 = new TwoArg() { - protected double evaluate(double d0, double d1) throws EvaluationException { - if (d0 == ZERO && d1 == ZERO) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return Math.atan2(d1, d0); - } - }; - public static final Function CEILING = new TwoArg() { - protected double evaluate(double d0, double d1) { - return MathX.ceiling(d0, d1); - } - }; - public static final Function COMBIN = new TwoArg() { - protected double evaluate(double d0, double d1) throws EvaluationException { - if (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - return MathX.nChooseK((int) d0, (int) d1); - } - }; - public static final Function FLOOR = new TwoArg() { - protected double evaluate(double d0, double d1) throws EvaluationException { - if (d1 == ZERO) { - if (d0 == ZERO) { - return ZERO; - } - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return MathX.floor(d0, d1); - } - }; - public static final Function MOD = new TwoArg() { - protected double evaluate(double d0, double d1) throws EvaluationException { - if (d1 == ZERO) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return MathX.mod(d0, d1); - } - }; - public static final Function POWER = new TwoArg() { - protected double evaluate(double d0, double d1) { - return Math.pow(d0, d1); - } - }; - public static final Function ROUND = new TwoArg() { - protected double evaluate(double d0, double d1) { - return MathX.round(d0, (int)d1); - } - }; - public static final Function ROUNDDOWN = new TwoArg() { - protected double evaluate(double d0, double d1) { - return MathX.roundDown(d0, (int)d1); - } - }; - public static final Function ROUNDUP = new TwoArg() { - protected double evaluate(double d0, double d1) { - return MathX.roundUp(d0, (int)d1); - } - }; - static final NumberEval TRUNC_ARG2_DEFAULT = new NumberEval(0); - public static final Function TRUNC = new Var1or2ArgFunction() { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, TRUNC_ARG2_DEFAULT); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - double result; - try { - double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - double multi = Math.pow(10d,d1); - if(d0 < 0) result = -Math.floor(-d0 * multi) / multi; - else result = Math.floor(d0 * multi) / multi; - checkValue(result); - }catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - }; - - /* -------------------------------------------------------------------------- */ - - private static final class Log extends Var1or2ArgFunction { - public Log() { - // no instance fields - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - double result; - try { - double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - result = Math.log(d0) / LOG_10_TO_BASE_e; - NumericFunction.checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1) { - double result; - try { - double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - double logE = Math.log(d0); - double base = d1; - if (Double.compare(base, Math.E) == 0) { - result = logE; - } else { - result = logE / Math.log(base); - } - NumericFunction.checkValue(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - } - - public static final Function LOG = new Log(); - - static final NumberEval PI_EVAL = new NumberEval(Math.PI); - public static final Function PI = new Fixed0ArgFunction() { - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) { - return PI_EVAL; - } - }; - public static final Function RAND = new Fixed0ArgFunction() { - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) { - return new NumberEval(Math.random()); - } - }; - public static final Function POISSON = new Fixed3ArgFunction() { - - private final static double DEFAULT_RETURN_RESULT =1; - - /** - * This checks is x = 0 and the mean = 0. - * Excel currently returns the value 1 where as the - * maths common implementation will error. - * @param x The number. - * @param mean The mean. - * @return If a default value should be returned. - */ - private boolean isDefaultResult(double x, double mean) { - - if ( x == 0 && mean == 0 ) { - return true; - } - return false; - } - - private boolean checkArgument(double aDouble) throws EvaluationException { - - NumericFunction.checkValue(aDouble); - - // make sure that the number is positive - if (aDouble < 0) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - - return true; - } - - private double probability(int k, double lambda) { - return Math.pow(lambda, k) * Math.exp(-lambda) / factorial(k); - } - - private double cumulativeProbability(int x, double lambda) { - double result = 0; - for(int k = 0; k <= x; k++){ - result += probability(k, lambda); - } - return result; - } - - /** All long-representable factorials */ - private final long[] FACTORIALS = new long[] { - 1l, 1l, 2l, - 6l, 24l, 120l, - 720l, 5040l, 40320l, - 362880l, 3628800l, 39916800l, - 479001600l, 6227020800l, 87178291200l, - 1307674368000l, 20922789888000l, 355687428096000l, - 6402373705728000l, 121645100408832000l, 2432902008176640000l }; - - - public long factorial(final int n) { - if (n < 0 || n > 20) { - throw new IllegalArgumentException("Valid argument should be in the range [0..20]"); - } - return FACTORIALS[n]; - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2) { - - // arguments/result for this function - double mean=0; - double x=0; - boolean cumulative = ((BoolEval)arg2).getBooleanValue(); - double result=0; - - try { - x = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex); - mean = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex); - - // check for default result : excel implementation for 0,0 - // is different to Math Common. - if (isDefaultResult(x,mean)) { - return new NumberEval(DEFAULT_RETURN_RESULT); - } - // check the arguments : as per excel function def - checkArgument(x); - checkArgument(mean); - - // truncate x : as per excel function def - if ( cumulative ) { - result = cumulativeProbability((int)x, mean); - } else { - result = probability((int)x, mean); - } - - // check the result - NumericFunction.checkValue(result); - - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return new NumberEval(result); - - } - }; -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Oct2Dec.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Oct2Dec.java deleted file mode 100644 index db9447df5..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Oct2Dec.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - *

        Implementation for Excel Oct2Dec() function.

        - *

        - * Converts an octal number to decimal. - *

        - *

        - * Syntax:
        Oct2Dec (number ) - *

        - *

        - * Number is the octal number you want to convert. Number may not contain more than 10 octal characters (30 bits). - * The most significant bit of number is the sign bit. The remaining 29 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation.. - *

        - * If number is not a valid octal number, OCT2DEC returns the #NUM! error value. - * - * @author cedric dot walter @ gmail dot com - */ -public class Oct2Dec extends Fixed1ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Oct2Dec(); - - static final int MAX_NUMBER_OF_PLACES = 10; - static final int OCTAL_BASE = 8; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE) { - String octal = OperandResolver.coerceValueToString(numberVE); - try { - return new NumberEval(BaseNumberUtils.convertToDecimal(octal, OCTAL_BASE, MAX_NUMBER_OF_PLACES)); - } catch (IllegalArgumentException e) { - return ErrorEval.NUM_ERROR; - } - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Odd.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Odd.java deleted file mode 100644 index 6762fcb5f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Odd.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Odd extends NumericFunction.OneArg { - private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL; - - protected double evaluate(double d) { - if (d==0) { - return 1; - } - return (d>0) ? calcOdd(d) : -calcOdd(-d); - } - - private static long calcOdd(double d) { - double dpm1 = d+1; - long x = ((long) dpm1) & PARITY_MASK; - return ( Double.compare(x, dpm1) == 0 ) ? x-1 : x+1; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Offset.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Offset.java deleted file mode 100644 index 37ae8e682..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Offset.java +++ /dev/null @@ -1,241 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -/** - * Implementation for Excel function OFFSET()

        - * - * OFFSET returns an area reference that is a specified number of rows and columns from a - * reference cell or area.

        - * - * Syntax:
        - * OFFSET(reference, rows, cols, height, width)

        - * reference is the base reference.
        - * rows is the number of rows up or down from the base reference.
        - * cols is the number of columns left or right from the base reference.
        - * height (default same height as base reference) is the row count for the returned area reference.
        - * width (default same width as base reference) is the column count for the returned area reference.
        - * - * @author Josh Micich - */ -public final class Offset implements Function { - // These values are specific to BIFF8 - private static final int LAST_VALID_ROW_INDEX = 0xFFFF; - private static final int LAST_VALID_COLUMN_INDEX = 0xFF; - - - /** - * A one dimensional base + offset. Represents either a row range or a column range. - * Two instances of this class together specify an area range. - */ - /* package */ static final class LinearOffsetRange { - - private final int _offset; - private final int _length; - - public LinearOffsetRange(int offset, int length) { - if(length == 0) { - // handled that condition much earlier - throw new RuntimeException("length may not be zero"); - } - _offset = offset; - _length = length; - } - - public short getFirstIndex() { - return (short) _offset; - } - public short getLastIndex() { - return (short) (_offset + _length - 1); - } - /** - * Moves the range by the specified translation amount.

        - * - * This method also 'normalises' the range: Excel specifies that the width and height - * parameters (length field here) cannot be negative. However, OFFSET() does produce - * sensible results in these cases. That behavior is replicated here.

        - * - * @param translationAmount may be zero negative or positive - * - * @return the equivalent LinearOffsetRange with a positive length, moved by the - * specified translationAmount. - */ - public LinearOffsetRange normaliseAndTranslate(int translationAmount) { - if (_length > 0) { - if(translationAmount == 0) { - return this; - } - return new LinearOffsetRange(translationAmount + _offset, _length); - } - return new LinearOffsetRange(translationAmount + _offset + _length + 1, -_length); - } - - public boolean isOutOfBounds(int lowValidIx, int highValidIx) { - if(_offset < lowValidIx) { - return true; - } - if(getLastIndex() > highValidIx) { - return true; - } - return false; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_offset).append("...").append(getLastIndex()); - sb.append("]"); - return sb.toString(); - } - } - - /** - * Encapsulates either an area or cell reference which may be 2d or 3d. - */ - private static final class BaseRef { - private final int _firstRowIndex; - private final int _firstColumnIndex; - private final int _width; - private final int _height; - private final RefEval _refEval; - private final AreaEval _areaEval; - - public BaseRef(RefEval re) { - _refEval = re; - _areaEval = null; - _firstRowIndex = re.getRow(); - _firstColumnIndex = re.getColumn(); - _height = 1; - _width = 1; - } - - public BaseRef(AreaEval ae) { - _refEval = null; - _areaEval = ae; - _firstRowIndex = ae.getFirstRow(); - _firstColumnIndex = ae.getFirstColumn(); - _height = ae.getLastRow() - ae.getFirstRow() + 1; - _width = ae.getLastColumn() - ae.getFirstColumn() + 1; - } - - public int getWidth() { - return _width; - } - public int getHeight() { - return _height; - } - public int getFirstRowIndex() { - return _firstRowIndex; - } - public int getFirstColumnIndex() { - return _firstColumnIndex; - } - - public AreaEval offset(int relFirstRowIx, int relLastRowIx, - int relFirstColIx, int relLastColIx) { - if (_refEval == null) { - return _areaEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx); - } - return _refEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx); - } - } - - @SuppressWarnings("fallthrough") - public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - if(args.length < 3 || args.length > 5) { - return ErrorEval.VALUE_INVALID; - } - - try { - BaseRef baseRef = evaluateBaseRef(args[0]); - int rowOffset = evaluateIntArg(args[1], srcCellRow, srcCellCol); - int columnOffset = evaluateIntArg(args[2], srcCellRow, srcCellCol); - int height = baseRef.getHeight(); - int width = baseRef.getWidth(); - // optional arguments - // If height or width is omitted, it is assumed to be the same height or width as reference. - switch(args.length) { - case 5: - if(!(args[4] instanceof MissingArgEval)) { - width = evaluateIntArg(args[4], srcCellRow, srcCellCol); - } - // fall-through to pick up height - case 4: - if(!(args[3] instanceof MissingArgEval)) { - height = evaluateIntArg(args[3], srcCellRow, srcCellCol); - } - break; - //case 3: - // nothing to do - default: - break; - } - // Zero height or width raises #REF! error - if(height == 0 || width == 0) { - return ErrorEval.REF_INVALID; - } - LinearOffsetRange rowOffsetRange = new LinearOffsetRange(rowOffset, height); - LinearOffsetRange colOffsetRange = new LinearOffsetRange(columnOffset, width); - return createOffset(baseRef, rowOffsetRange, colOffsetRange); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private static AreaEval createOffset(BaseRef baseRef, - LinearOffsetRange orRow, LinearOffsetRange orCol) throws EvaluationException { - LinearOffsetRange absRows = orRow.normaliseAndTranslate(baseRef.getFirstRowIndex()); - LinearOffsetRange absCols = orCol.normaliseAndTranslate(baseRef.getFirstColumnIndex()); - - if(absRows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) { - throw new EvaluationException(ErrorEval.REF_INVALID); - } - if(absCols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) { - throw new EvaluationException(ErrorEval.REF_INVALID); - } - return baseRef.offset(orRow.getFirstIndex(), orRow.getLastIndex(), orCol.getFirstIndex(), orCol.getLastIndex()); - } - - private static BaseRef evaluateBaseRef(ValueEval eval) throws EvaluationException { - - if(eval instanceof RefEval) { - return new BaseRef((RefEval)eval); - } - if(eval instanceof AreaEval) { - return new BaseRef((AreaEval)eval); - } - if (eval instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) eval); - } - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - - /** - * OFFSET's numeric arguments (2..5) have similar processing rules - */ - static int evaluateIntArg(ValueEval eval, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(eval, srcCellRow, srcCellCol); - return OperandResolver.coerceValueToInt(ve); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/PPMT.java b/trunk/src/java/org/apache/poi/ss/formula/functions/PPMT.java deleted file mode 100644 index 2df2304db..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/PPMT.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.*; - -/** - * Compute the interest portion of a payment. - * - * @author Mike Argyriou micharg@gmail.com - */ -public class PPMT extends NumericFunction { - - @Override - public double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException { - - if(args.length < 4) - throw new EvaluationException(ErrorEval.VALUE_INVALID); - - double result; - - ValueEval v1 = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - ValueEval v2 = OperandResolver.getSingleValue(args[1], srcCellRow, srcCellCol); - ValueEval v3 = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol); - ValueEval v4 = OperandResolver.getSingleValue(args[3], srcCellRow, srcCellCol); - - double interestRate = OperandResolver.coerceValueToDouble(v1); - int period = OperandResolver.coerceValueToInt(v2); - int numberPayments = OperandResolver.coerceValueToInt(v3); - double PV = OperandResolver.coerceValueToDouble(v4); - - result = Finance.ppmt(interestRate, period, numberPayments, PV) ; - - checkValue(result); - - return result; - } - - - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Quotient.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Quotient.java deleted file mode 100644 index 40d1debd3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Quotient.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ValueEval; - -import org.apache.poi.ss.formula.eval.*; - -/** - *

        Implementation for Excel QUOTIENT () function.

        - *

        - * Syntax:
        QUOTIENT(Numerator,Denominator)
        - *

        - *

        - * Numerator is the dividend. - * Denominator is the divisor. - * - * Returns the integer portion of a division. Use this function when you want to discard the remainder of a division. - *

        - * - * If either enumerator/denominator is non numeric, QUOTIENT returns the #VALUE! error value. - * If denominator is equals to zero, QUOTIENT returns the #DIV/0! error value. - */ -public class Quotient extends Fixed2ArgFunction implements FreeRefFunction { - - public static final FreeRefFunction instance = new Quotient(); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval venumerator, ValueEval vedenominator) { - - double enumerator = 0; - try { - enumerator = OperandResolver.coerceValueToDouble(venumerator); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - double denominator = 0; - try { - denominator = OperandResolver.coerceValueToDouble(vedenominator); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - if (denominator == 0) { - return ErrorEval.DIV_ZERO; - } - - return new NumberEval((int)(enumerator / denominator)); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Rank.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Rank.java deleted file mode 100644 index c6ff86068..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Rank.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; - - -/** - * Returns the rank of a number in a list of numbers. The rank of a number is its size relative to other values in a list. - - * Syntax: - * RANK(number,ref,order) - * Number is the number whose rank you want to find. - * Ref is an array of, or a reference to, a list of numbers. Nonnumeric values in ref are ignored. - * Order is a number specifying how to rank number. - - * If order is 0 (zero) or omitted, Microsoft Excel ranks number as if ref were a list sorted in descending order. - * If order is any nonzero value, Microsoft Excel ranks number as if ref were a list sorted in ascending order. - * - * @author Rubin Wang - */ -public class Rank extends Var2or3ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - - AreaEval aeRange; - double result; - try { - ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - result = OperandResolver.coerceValueToDouble(ve); - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - aeRange = convertRangeArg(arg1); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return eval(srcRowIndex, srcColumnIndex, result, aeRange, true); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2) { - - AreaEval aeRange; - double result; - boolean order=false; - try { - ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - result = OperandResolver.coerceValueToDouble(ve); - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - aeRange = convertRangeArg(arg1); - - ve = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex); - int order_value = OperandResolver.coerceValueToInt(ve); - if(order_value==0){ - order=true; - }else if(order_value==1){ - order=false; - }else throw new EvaluationException(ErrorEval.NUM_ERROR); - - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return eval(srcRowIndex, srcColumnIndex, result, aeRange, order); - } - - private static ValueEval eval(int srcRowIndex, int srcColumnIndex, double arg0, AreaEval aeRange, boolean descending_order) { - - int rank = 1; - int height=aeRange.getHeight(); - int width= aeRange.getWidth(); - for (int r=0; rarg0 || !descending_order && value= 4) - v4 = OperandResolver.getSingleValue(args[3], srcRowIndex, srcColumnIndex); - ValueEval v5 = null; - if (args.length >= 5) - v5 = OperandResolver.getSingleValue(args[4], srcRowIndex, srcColumnIndex); - ValueEval v6 = null; - if (args.length >= 6) - v6 = OperandResolver.getSingleValue(args[5], srcRowIndex, srcColumnIndex); - - periods = OperandResolver.coerceValueToDouble(v1); - payment = OperandResolver.coerceValueToDouble(v2); - present_val = OperandResolver.coerceValueToDouble(v3); - if (args.length >= 4) - future_val = OperandResolver.coerceValueToDouble(v4); - if (args.length >= 5) - type = OperandResolver.coerceValueToDouble(v5); - if (args.length >= 6) - estimate = OperandResolver.coerceValueToDouble(v6); - rate = calculateRate(periods, payment, present_val, future_val, type, estimate) ; - - checkValue(rate); - } catch (EvaluationException e) { - LOG.log(POILogger.ERROR, "Can't evaluate rate function", e); - return e.getErrorEval(); - } - - return new NumberEval( rate ) ; - } - - private double calculateRate(double nper, double pmt, double pv, double fv, double type, double guess) { - //FROM MS http://office.microsoft.com/en-us/excel-help/rate-HP005209232.aspx - int FINANCIAL_MAX_ITERATIONS = 20;//Bet accuracy with 128 - double FINANCIAL_PRECISION = 0.0000001;//1.0e-8 - - double y, y0, y1, x0, x1 = 0, f = 0, i = 0; - double rate = guess; - if (Math.abs(rate) < FINANCIAL_PRECISION) { - y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv; - } else { - f = Math.exp(nper * Math.log(1 + rate)); - y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; - } - y0 = pv + pmt * nper + fv; - y1 = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; - - // find root by Newton secant method - i = x0 = 0.0; - x1 = rate; - while ((Math.abs(y0 - y1) > FINANCIAL_PRECISION) && (i < FINANCIAL_MAX_ITERATIONS)) { - rate = (y1 * x0 - y0 * x1) / (y1 - y0); - x0 = x1; - x1 = rate; - - if (Math.abs(rate) < FINANCIAL_PRECISION) { - y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv; - } else { - f = Math.exp(nper * Math.log(1 + rate)); - y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; - } - - y0 = y1; - y1 = y; - ++i; - } - return rate; - } - - /** - * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases - * - * @throws EvaluationException (#NUM!) if result is NaN or Infinity - */ - static final void checkValue(double result) throws EvaluationException { - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Replace.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Replace.java deleted file mode 100644 index dd366dbd2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Replace.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * An implementation of the Excel REPLACE() function:

        - * Replaces part of a text string based on the number of characters - * you specify, with another text string.
        - * - * Syntax:
        - * REPLACE(oldText, startNum, numChars, newText)

        - * - * oldText The text string containing characters to replace
        - * startNum The position of the first character to replace (1-based)
        - * numChars The number of characters to replace
        - * newText The new text value to replace the removed section
        - * - * @author Manda Wilson < wilson at c bio dot msk cc dot org > - */ -public final class Replace extends Fixed4ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2, ValueEval arg3) { - - String oldStr; - int startNum; - int numChars; - String newStr; - try { - oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - startNum = TextFunction.evaluateIntArg(arg1, srcRowIndex, srcColumnIndex); - numChars = TextFunction.evaluateIntArg(arg2, srcRowIndex, srcColumnIndex); - newStr = TextFunction.evaluateStringArg(arg3, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - if (startNum < 1 || numChars < 0) { - return ErrorEval.VALUE_INVALID; - } - StringBuffer strBuff = new StringBuffer(oldStr); - // remove any characters that should be replaced - if (startNum <= oldStr.length() && numChars != 0) { - strBuff.delete(startNum - 1, startNum - 1 + numChars); - } - // now insert (or append) newStr - if (startNum > strBuff.length()) { - strBuff.append(newStr); - } else { - strBuff.insert(startNum - 1, newStr); - } - return new StringEval(strBuff.toString()); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Rept.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Rept.java deleted file mode 100644 index 0c8a5f876..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Rept.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel REPT () function.

        - *

        - * Syntax:
        REPT (text,number_times )
        - *

        - * Repeats text a given number of times. Use REPT to fill a cell with a number of instances of a text string. - * - * text : text The text that you want to repeat. - * number_times: A positive number specifying the number of times to repeat text. - * - * If number_times is 0 (zero), REPT returns "" (empty text). - * If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point. - * - * The result of the REPT function cannot be longer than 32,767 characters, or REPT returns #VALUE!. - * - * @author cedric dot walter @ gmail dot com - */ -public class Rept extends Fixed2ArgFunction { - - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval text, ValueEval number_times) { - - ValueEval veText1; - try { - veText1 = OperandResolver.getSingleValue(text, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String strText1 = OperandResolver.coerceValueToString(veText1); - double numberOfTime = 0; - try { - numberOfTime = OperandResolver.coerceValueToDouble(number_times); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - - int numberOfTimeInt = (int)numberOfTime; - StringBuffer strb = new StringBuffer(strText1.length() * numberOfTimeInt); - for(int i = 0; i < numberOfTimeInt; i++) { - strb.append(strText1); - } - - if (strb.toString().length() > 32767) { - return ErrorEval.VALUE_INVALID; - } - - return new StringEval(strb.toString()); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Roman.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Roman.java deleted file mode 100644 index 45b400e2f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Roman.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel WeekNum() function.

        - *

        - * Syntax:
        WeekNum (Serial_num,Return_type)
        - *

        - * Returns a number that indicates where the week falls numerically within a year. - *

        - *

        - * Serial_num is a date within the week. Dates should be entered by using the DATE function, - * or as results of other formulas or functions. For example, use DATE(2008,5,23) - * for the 23rd day of May, 2008. Problems can occur if dates are entered as text. - * Return_type is a number that determines on which day the week begins. The default is 1. - * 1 Week begins on Sunday. Weekdays are numbered 1 through 7. - * 2 Week begins on Monday. Weekdays are numbered 1 through 7. - * - * @author cedric dot walter @ gmail dot com - */ -public class Roman extends Fixed2ArgFunction { - - //M (1000), CM (900), D (500), CD (400), C (100), XC (90), L (50), XL (40), X (10), IX (9), V (5), IV (4) and I (1). - public static final int[] VALUES = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; - public static final String[] ROMAN = new String[] - {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; - - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval numberVE, ValueEval formVE) { - int number = 0; - try { - ValueEval ve = OperandResolver.getSingleValue(numberVE, srcRowIndex, srcColumnIndex); - number = OperandResolver.coerceValueToInt(ve); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - if (number < 0) { - return ErrorEval.VALUE_INVALID; - } - if (number > 3999) { - return ErrorEval.VALUE_INVALID; - } - if (number == 0) { - return new StringEval(""); - } - - int form = 0; - try { - ValueEval ve = OperandResolver.getSingleValue(formVE, srcRowIndex, srcColumnIndex); - form = OperandResolver.coerceValueToInt(ve); - } catch (EvaluationException e) { - return ErrorEval.NUM_ERROR; - } - - if (form > 4 || form < 0) { - return ErrorEval.VALUE_INVALID; - } - - String result = this.integerToRoman(number); - - if (form == 0) { - return new StringEval(result); - } - - return new StringEval(makeConcise(result, form)); - } - - /** - * Classic conversion. - * - * @param number - */ - private String integerToRoman(int number) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < 13; i++) { - while (number >= VALUES[i]) { - number -= VALUES[i]; - result.append(ROMAN[i]); - } - } - return result.toString(); - } - - /** - * Use conversion rule to factor some parts and make them more concise - * - * @param result - * @param form - */ - public String makeConcise(String result, int form) { - if (form > 0) { - result = result.replaceAll("XLV", "VL"); //45 - result = result.replaceAll("XCV", "VC"); //95 - result = result.replaceAll("CDL", "LD"); //450 - result = result.replaceAll("CML", "LM"); //950 - result = result.replaceAll("CMVC", "LMVL"); //995 - } - if (form == 1) { - result = result.replaceAll("CDXC", "LDXL"); //490 - result = result.replaceAll("CDVC", "LDVL"); //495 - result = result.replaceAll("CMXC", "LMXL"); //990 - result = result.replaceAll("XCIX", "VCIV"); //99 - result = result.replaceAll("XLIX", "VLIV"); //49 - } - if (form > 1) { - result = result.replaceAll("XLIX", "IL"); //49 - result = result.replaceAll("XCIX", "IC"); //99 - result = result.replaceAll("CDXC", "XD"); //490 - result = result.replaceAll("CDVC", "XDV"); //495 - result = result.replaceAll("CDIC", "XDIX"); //499 - result = result.replaceAll("LMVL", "XMV"); //995 - result = result.replaceAll("CMIC", "XMIX"); //999 - result = result.replaceAll("CMXC", "XM"); // 990 - } - if (form > 2) { - result = result.replaceAll("XDV", "VD"); //495 - result = result.replaceAll("XDIX", "VDIV"); //499 - result = result.replaceAll("XMV", "VM"); // 995 - result = result.replaceAll("XMIX", "VMIV"); //999 - } - if (form == 4) { - result = result.replaceAll("VDIV", "ID"); //499 - result = result.replaceAll("VMIV", "IM"); //999 - } - - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/RowFunc.java b/trunk/src/java/org/apache/poi/ss/formula/functions/RowFunc.java deleted file mode 100644 index f0d468fb6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/RowFunc.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for the Excel function ROW - * - * @author Josh Micich - */ -public final class RowFunc implements Function0Arg, Function1Arg { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) { - return new NumberEval(srcRowIndex+1); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - int rnum; - - if (arg0 instanceof AreaEval) { - rnum = ((AreaEval) arg0).getFirstRow(); - } else if (arg0 instanceof RefEval) { - rnum = ((RefEval) arg0).getRow(); - } else { - // anything else is not valid argument - return ErrorEval.VALUE_INVALID; - } - - return new NumberEval(rnum + 1); - } - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 1: - return evaluate(srcRowIndex, srcColumnIndex, args[0]); - case 0: - return new NumberEval(srcRowIndex+1); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Rows.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Rows.java deleted file mode 100644 index 1e363222a..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Rows.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.TwoDEval; - -/** - * Implementation for Excel ROWS function. - * - * @author Josh Micich - */ -public final class Rows extends Fixed1ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - - int result; - if (arg0 instanceof TwoDEval) { - result = ((TwoDEval) arg0).getHeight(); - } else if (arg0 instanceof RefEval) { - result = 1; - } else { // anything else is not valid argument - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(result); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Slope.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Slope.java deleted file mode 100644 index 63449d568..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Slope.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LinearRegressionFunction.FUNCTION; - -/** - * Implementation of Excel function SLOPE()

        - * - * Calculates the SLOPE of the linear regression line that is used to predict y values from x values
        - * (http://introcs.cs.princeton.edu/java/97data/LinearRegression.java.html) - * Syntax:
        - * SLOPE(arrayX, arrayY)

        - * - * - * @author Johan Karlsteen - */ -public final class Slope extends Fixed2ArgFunction { - - private final LinearRegressionFunction func; - public Slope() { - func = new LinearRegressionFunction(FUNCTION.SLOPE); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, - ValueEval arg0, ValueEval arg1) { - return func.evaluate(srcRowIndex, srcColumnIndex, arg0, arg1); - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/StatsLib.java b/trunk/src/java/org/apache/poi/ss/formula/functions/StatsLib.java deleted file mode 100644 index ebef9d4b2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/StatsLib.java +++ /dev/null @@ -1,152 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Arrays; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - * Library for common statistics functions - */ -final class StatsLib { - - private StatsLib() { - // no instances of this class - } - - - /** - * returns the mean of deviations from mean. - * @param v - */ - public static double avedev(double[] v) { - double r = 0; - double m = 0; - double s = 0; - for (int i=0, iSize=v.length; i 1) { - r = Math.sqrt( devsq(v) / (v.length - 1) ); - } - return r; - } - - public static double var(double[] v) { - double r = Double.NaN; - if (v!=null && v.length > 1) { - r = devsq(v) / (v.length - 1); - } - return r; - } - - public static double varp(double[] v) { - double r = Double.NaN; - if (v!=null && v.length > 1) { - r = devsq(v) /v.length; - } - return r; - } - - public static double median(double[] v) { - double r = Double.NaN; - - if (v!=null && v.length >= 1) { - int n = v.length; - Arrays.sort(v); - r = (n % 2 == 0) - ? (v[n / 2] + v[n / 2 - 1]) / 2 - : v[n / 2]; - } - - return r; - } - - - public static double devsq(double[] v) { - double r = Double.NaN; - if (v!=null && v.length >= 1) { - double m = 0; - double s = 0; - int n = v.length; - for (int i=0; i - * k <= 0 & k >= v.length and null or empty arrays - * will result in return value Double.NaN - */ - public static double kthLargest(double[] v, int k) { - double r = Double.NaN; - int index = k-1; // since arrays are 0-based - if (v!=null && v.length > index && index >= 0) { - Arrays.sort(v); - r = v[v.length-index-1]; - } - return r; - } - - /** - * returns the kth smallest element in the array. Duplicates - * are considered as distinct values. Hence, eg. - * for array {1,1,2,4,3,3} & k=2, returned value is 1. - *
        - * k <= 0 & k >= v.length or null array or empty array - * will result in return value Double.NaN - * @param v - * @param k - */ - public static double kthSmallest(double[] v, int k) { - double r = Double.NaN; - int index = k-1; // since arrays are 0-based - if (v!=null && v.length > index && index >= 0) { - Arrays.sort(v); - r = v[index]; - } - return r; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java deleted file mode 100644 index 23954b1f0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * An implementation of the SUBSTITUTE function:

        - * Substitutes text in a text string with new text, some number of times. - * @author Manda Wilson < wilson at c bio dot msk cc dot org > - */ -public final class Substitute extends Var3or4ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - String result; - try { - String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex); - String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex); - - result = replaceAllOccurrences(oldStr, searchStr, newStr); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new StringEval(result); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2, ValueEval arg3) { - String result; - try { - String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex); - String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex); - - int instanceNumber = TextFunction.evaluateIntArg(arg3, srcRowIndex, srcColumnIndex); - if (instanceNumber < 1) { - return ErrorEval.VALUE_INVALID; - } - result = replaceOneOccurrence(oldStr, searchStr, newStr, instanceNumber); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new StringEval(result); - } - - private static String replaceAllOccurrences(String oldStr, String searchStr, String newStr) { - StringBuffer sb = new StringBuffer(); - int startIndex = 0; - int nextMatch = -1; - while (true) { - nextMatch = oldStr.indexOf(searchStr, startIndex); - if (nextMatch < 0) { - // store everything from end of last match to end of string - sb.append(oldStr.substring(startIndex)); - return sb.toString(); - } - // store everything from end of last match to start of this match - sb.append(oldStr.substring(startIndex, nextMatch)); - sb.append(newStr); - startIndex = nextMatch + searchStr.length(); - } - } - - private static String replaceOneOccurrence(String oldStr, String searchStr, String newStr, int instanceNumber) { - if (searchStr.length() < 1) { - return oldStr; - } - int startIndex = 0; - int nextMatch = -1; - int count=0; - while (true) { - nextMatch = oldStr.indexOf(searchStr, startIndex); - if (nextMatch < 0) { - // not enough occurrences found - leave unchanged - return oldStr; - } - count++; - if (count == instanceNumber) { - StringBuffer sb = new StringBuffer(oldStr.length() + newStr.length()); - sb.append(oldStr.substring(0, nextMatch)); - sb.append(newStr); - sb.append(oldStr.substring(nextMatch + searchStr.length())); - return sb.toString(); - } - startIndex = nextMatch + searchStr.length(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Subtotal.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Subtotal.java deleted file mode 100644 index f3b24cd1c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Subtotal.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import static org.apache.poi.ss.formula.functions.AggregateFunction.subtotalInstance; - -import org.apache.poi.ss.formula.LazyRefEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NotImplementedException; -import org.apache.poi.ss.formula.eval.NotImplementedFunctionException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -/** - * Implementation for the Excel function SUBTOTAL

        - * - * Syntax :
        - * SUBTOTAL ( functionCode, ref1, ref2 ... )
        - * - * - * - *
        functionCode(1-11) Selects the underlying aggregate function to be used (see table below)
        ref1, ref2 ...Arguments to be passed to the underlying aggregate function

        - *

        - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
        functionCodeAggregate Function
        1AVERAGE
        2COUNT
        3COUNTA
        4MAX
        5MIN
        6PRODUCT
        7STDEV
        8STDEVP *
        9SUM
        10VAR *
        11VARP *
        101-111*

        - * * Not implemented in POI yet. Functions 101-111 are the same as functions 1-11 but with - * the option 'ignore hidden values'. - *

        - * - * @author Paul Tomlin < pault at bulk sms dot com > - */ -public class Subtotal implements Function { - - private static Function findFunction(int functionCode) throws EvaluationException { - switch (functionCode) { - case 1: return subtotalInstance(AggregateFunction.AVERAGE); - case 2: return Count.subtotalInstance(); - case 3: return Counta.subtotalInstance(); - case 4: return subtotalInstance(AggregateFunction.MAX); - case 5: return subtotalInstance(AggregateFunction.MIN); - case 6: return subtotalInstance(AggregateFunction.PRODUCT); - case 7: return subtotalInstance(AggregateFunction.STDEV); - case 8: throw new NotImplementedFunctionException("STDEVP"); - case 9: return subtotalInstance(AggregateFunction.SUM); - case 10: throw new NotImplementedFunctionException("VAR"); - case 11: throw new NotImplementedFunctionException("VARP"); - } - if (functionCode > 100 && functionCode < 112) { - throw new NotImplementedException("SUBTOTAL - with 'exclude hidden values' option"); - } - throw EvaluationException.invalidValue(); - } - - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - int nInnerArgs = args.length-1; // -1: first arg is used to select from a basic aggregate function - if (nInnerArgs < 1) { - return ErrorEval.VALUE_INVALID; - } - - final Function innerFunc; - try { - ValueEval ve = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex); - int functionCode = OperandResolver.coerceValueToInt(ve); - innerFunc = findFunction(functionCode); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - // ignore the first arg, this is the function-type, we check for the length above - final List list = new ArrayList(Arrays.asList(args).subList(1, args.length)); - - Iterator it = list.iterator(); - - // See https://support.office.com/en-us/article/SUBTOTAL-function-7b027003-f060-4ade-9040-e478765b9939 - // "If there are other subtotals within ref1, ref2,... (or nested subtotals), these nested subtotals are ignored to avoid double counting." - // For array references it is handled in other evaluation steps, but we need to handle this here for references to subtotal-functions - while(it.hasNext()) { - ValueEval eval = it.next(); - if(eval instanceof LazyRefEval) { - LazyRefEval lazyRefEval = (LazyRefEval) eval; - if(lazyRefEval.isSubTotal()) { - it.remove(); - } - } - } - - return innerFunc.evaluate(list.toArray(new ValueEval[list.size()]), srcRowIndex, srcColumnIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumif.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Sumif.java deleted file mode 100644 index 977647fd2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumif.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate; - -/** - * Implementation for the Excel function SUMIF

        - * - * Syntax :
        - * SUMIF ( range, criteria, sum_range )
        - * - * - * - * - *
        rangeThe range over which criteria is applied. Also used for addend values when the third parameter is not present
        criteriaThe value or expression used to filter rows from range
        sum_rangeLocates the top-left corner of the corresponding range of addends - values to be added (after being selected by the criteria)

        - *

        - * @author Josh Micich - */ -public final class Sumif extends Var2or3ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - - AreaEval aeRange; - try { - aeRange = convertRangeArg(arg0); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return eval(srcRowIndex, srcColumnIndex, arg1, aeRange, aeRange); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - - AreaEval aeRange; - AreaEval aeSum; - try { - aeRange = convertRangeArg(arg0); - aeSum = createSumRange(arg2, aeRange); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return eval(srcRowIndex, srcColumnIndex, arg1, aeRange, aeSum); - } - - private static ValueEval eval(int srcRowIndex, int srcColumnIndex, ValueEval arg1, AreaEval aeRange, - AreaEval aeSum) { - // TODO - junit to prove last arg must be srcColumnIndex and not srcRowIndex - I_MatchPredicate mp = Countif.createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex); - - // handle empty cells - if(mp == null) { - return NumberEval.ZERO; - } - - double result = sumMatchingCells(aeRange, mp, aeSum); - return new NumberEval(result); - } - - private static double sumMatchingCells(AreaEval aeRange, I_MatchPredicate mp, AreaEval aeSum) { - int height=aeRange.getHeight(); - int width= aeRange.getWidth(); - - double result = 0.0; - for (int r=0; r - * - * Syntax :
        - * SUMIFS ( sum_range, criteria_range1, criteria1, - * [criteria_range2, criteria2], ...)
        - *
          - *
        • sum_range Required. One or more cells to sum, including numbers or names, ranges, - * or cell references that contain numbers. Blank and text values are ignored.
        • - *
        • criteria1_range Required. The first range in which - * to evaluate the associated criteria.
        • - *
        • criteria1 Required. The criteria in the form of a number, expression, - * cell reference, or text that define which cells in the criteria_range1 - * argument will be added
        • - *
        • criteria_range2, criteria2, ... Optional. Additional ranges and their associated criteria. - * Up to 127 range/criteria pairs are allowed. - *
        - *

        - * - * @author Yegor Kozlov - */ -public final class Sumifs implements FreeRefFunction { - public static final FreeRefFunction instance = new Sumifs(); - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - // https://support.office.com/en-us/article/SUMIFS-function-c9e748f5-7ea7-455d-9406-611cebce642b - // COUNTIFS(sum_range, criteria_range1, criteria1, [criteria_range2, criteria2], ... - // need at least 3 arguments and need to have an odd number of arguments (sum-range plus x*(criteria_range, criteria)) - if(args.length < 3 || args.length % 2 == 0) { - return ErrorEval.VALUE_INVALID; - } - - try { - AreaEval sumRange = convertRangeArg(args[0]); - - // collect pairs of ranges and criteria - AreaEval[] ae = new AreaEval[(args.length - 1)/2]; - I_MatchPredicate[] mp = new I_MatchPredicate[ae.length]; - for(int i = 1, k=0; i < args.length; i += 2, k++){ - ae[k] = convertRangeArg(args[i]); - - mp[k] = Countif.createCriteriaPredicate(args[i+1], ec.getRowIndex(), ec.getColumnIndex()); - } - - validateCriteriaRanges(ae, sumRange); - validateCriteria(mp); - - double result = sumMatchingCells(ae, mp, sumRange); - return new NumberEval(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - /** - * Verify that each criteriaRanges argument contains the same number of rows and columns - * as the sumRange argument - * - * @throws EvaluationException if the ranges do not match. - */ - private void validateCriteriaRanges(AreaEval[] criteriaRanges, AreaEval sumRange) throws EvaluationException { - for(AreaEval r : criteriaRanges){ - if(r.getHeight() != sumRange.getHeight() || - r.getWidth() != sumRange.getWidth() ) { - throw EvaluationException.invalidValue(); - } - } - } - - /** - * Verify that each criteria predicate is valid, i.e. not an error - * - * @throws EvaluationException if there are criteria which resulted in Errors. - */ - private void validateCriteria(I_MatchPredicate[] criteria) throws EvaluationException { - for(I_MatchPredicate predicate : criteria) { - - // check for errors in predicate and return immediately using this error code - if(predicate instanceof ErrorMatcher) { - throw new EvaluationException(ErrorEval.valueOf(((ErrorMatcher)predicate).getValue())); - } - } - } - - - /** - * - * @param ranges criteria ranges, each range must be of the same dimensions as aeSum - * @param predicates array of predicates, a predicate for each value in ranges - * @param aeSum the range to sum - * - * @return the computed value - */ - private static double sumMatchingCells(AreaEval[] ranges, I_MatchPredicate[] predicates, AreaEval aeSum) { - int height = aeSum.getHeight(); - int width = aeSum.getWidth(); - - double result = 0.0; - for (int r = 0; r < height; r++) { - for (int c = 0; c < width; c++) { - - boolean matches = true; - for(int i = 0; i < ranges.length; i++){ - AreaEval aeRange = ranges[i]; - I_MatchPredicate mp = predicates[i]; - - if (!mp.matches(aeRange.getRelativeValue(r, c))) { - matches = false; - break; - } - - } - - if(matches) { // sum only if all of the corresponding criteria specified are true for that cell. - result += accumulate(aeSum, r, c); - } - } - } - return result; - } - - private static double accumulate(AreaEval aeSum, int relRowIndex, - int relColIndex) { - - ValueEval addend = aeSum.getRelativeValue(relRowIndex, relColIndex); - if (addend instanceof NumberEval) { - return ((NumberEval)addend).getNumberValue(); - } - // everything else (including string and boolean values) counts as zero - return 0.0; - } - - private static AreaEval convertRangeArg(ValueEval eval) throws EvaluationException { - if (eval instanceof AreaEval) { - return (AreaEval) eval; - } - if (eval instanceof RefEval) { - return ((RefEval)eval).offset(0, 0, 0, 0); - } - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java deleted file mode 100644 index 8bae16e3b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java +++ /dev/null @@ -1,234 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.NumericValueEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - - -/** - * Implementation for the Excel function SUMPRODUCT

        - * - * Syntax :
        - * SUMPRODUCT ( array1[, array2[, array3[, ...]]]) - * - * - *
        array1, ... arrayN  typically area references, - * possibly cell references or scalar values

        - * - * Let An(i,j) represent the element in the ith row jth column - * of the nth array
        - * Assuming each array has the same dimensions (W, H), the result is defined as:
        - * SUMPRODUCT = Σi: 1..H   - * (  Σj: 1..W   - * (  Πn: 1..N - * An(i,j)  - * )  - * ) - *

        - * @author Josh Micich - */ -public final class Sumproduct implements Function { - - - public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - - int maxN = args.length; - - if(maxN < 1) { - return ErrorEval.VALUE_INVALID; - } - ValueEval firstArg = args[0]; - try { - if(firstArg instanceof NumericValueEval) { - return evaluateSingleProduct(args); - } - if(firstArg instanceof RefEval) { - return evaluateSingleProduct(args); - } - if (firstArg instanceof TwoDEval) { - TwoDEval ae = (TwoDEval) firstArg; - if(ae.isRow() && ae.isColumn()) { - return evaluateSingleProduct(args); - } - return evaluateAreaSumProduct(args); - } - } catch (EvaluationException e) { - return e.getErrorEval(); - } - throw new RuntimeException("Invalid arg type for SUMPRODUCT: (" - + firstArg.getClass().getName() + ")"); - } - - private static ValueEval evaluateSingleProduct(ValueEval[] evalArgs) throws EvaluationException { - int maxN = evalArgs.length; - - double term = 1D; - for(int n=0; n 1) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - eval = re.getInnerValueEval(re.getFirstSheetIndex()); - } else { - eval = arg; - } - - if (eval == null) { - throw new RuntimeException("parameter may not be null"); - } - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - // an area ref can work as a scalar value if it is 1x1 - if(!ae.isColumn() || !ae.isRow()) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - eval = ae.getRelativeValue(0, 0); - } - - return getProductTerm(eval, true); - } - - private static ValueEval evaluateAreaSumProduct(ValueEval[] evalArgs) throws EvaluationException { - int maxN = evalArgs.length; - TwoDEval[] args = new TwoDEval[maxN]; - try { - System.arraycopy(evalArgs, 0, args, 0, maxN); - } catch (ArrayStoreException e) { - // one of the other args was not an AreaRef - return ErrorEval.VALUE_INVALID; - } - - - TwoDEval firstArg = args[0]; - - int height = firstArg.getHeight(); - int width = firstArg.getWidth(); // TODO - junit - - // first check dimensions - if (!areasAllSameSize(args, height, width)) { - // normally this results in #VALUE!, - // but errors in individual cells take precedence - for (int i = 1; i < args.length; i++) { - throwFirstError(args[i]); - } - return ErrorEval.VALUE_INVALID; - } - - double acc = 0; - - for (int rrIx=0; rrIxdouble value for the specified ValueEval. - * @param isScalarProduct false for SUMPRODUCTs over area refs. - * @throws EvaluationException if ve represents an error value. - *

        - * Note - string values and empty cells are interpreted differently depending on - * isScalarProduct. For scalar products, if any term is blank or a string, the - * error (#VALUE!) is raised. For area (sum)products, if any term is blank or a string, the - * result is zero. - */ - private static double getProductTerm(ValueEval ve, boolean isScalarProduct) throws EvaluationException { - - if(ve instanceof BlankEval || ve == null) { - // TODO - shouldn't BlankEval.INSTANCE be used always instead of null? - // null seems to occur when the blank cell is part of an area ref (but not reliably) - if(isScalarProduct) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - return 0; - } - - if(ve instanceof ErrorEval) { - throw new EvaluationException((ErrorEval)ve); - } - if(ve instanceof StringEval) { - if(isScalarProduct) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - // Note for area SUMPRODUCTs, string values are interpreted as zero - // even if they would parse as valid numeric values - return 0; - } - if(ve instanceof NumericValueEval) { - NumericValueEval nve = (NumericValueEval) ve; - return nve.getNumberValue(); - } - throw new RuntimeException("Unexpected value eval class (" - + ve.getClass().getName() + ")"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumx2my2.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Sumx2my2.java deleted file mode 100644 index 9c8c38668..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumx2my2.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - - -/** - * Implementation of Excel function SUMX2MY2()

        - * - * Calculates the sum of differences of squares in two arrays of the same size.
        - * Syntax:
        - * SUMX2MY2(arrayX, arrayY)

        - * - * result = Σi: 0..n(xi2-yi2) - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class Sumx2my2 extends XYNumericFunction { - - private static final Accumulator XSquaredMinusYSquaredAccumulator = new Accumulator() { - public double accumulate(double x, double y) { - return x * x - y * y; - } - }; - - protected Accumulator createAccumulator() { - return XSquaredMinusYSquaredAccumulator; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumx2py2.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Sumx2py2.java deleted file mode 100644 index 6e40445a4..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumx2py2.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - - -/** - * Implementation of Excel function SUMX2PY2()

        - * - * Calculates the sum of squares in two arrays of the same size.
        - * Syntax:
        - * SUMX2PY2(arrayX, arrayY)

        - * - * result = Σi: 0..n(xi2+yi2) - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class Sumx2py2 extends XYNumericFunction { - - private static final Accumulator XSquaredPlusYSquaredAccumulator = new Accumulator() { - public double accumulate(double x, double y) { - return x * x + y * y; - } - }; - - protected Accumulator createAccumulator() { - return XSquaredPlusYSquaredAccumulator; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumxmy2.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Sumxmy2.java deleted file mode 100644 index 3955d06da..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Sumxmy2.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -/** - * Implementation of Excel function SUMXMY2()

        - * - * Calculates the sum of squares of differences between two arrays of the same size.
        - * Syntax:
        - * SUMXMY2(arrayX, arrayY)

        - * - * result = Σi: 0..n(xi-yi)2 - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class Sumxmy2 extends XYNumericFunction { - - private static final Accumulator XMinusYSquaredAccumulator = new Accumulator() { - public double accumulate(double x, double y) { - double xmy = x - y; - return xmy * xmy; - } - }; - - protected Accumulator createAccumulator() { - return XMinusYSquaredAccumulator; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/T.java b/trunk/src/java/org/apache/poi/ss/formula/functions/T.java deleted file mode 100644 index 1e74c5b10..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/T.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation of Excel T() function - *

        - * If the argument is a text or error value it is returned unmodified. All other argument types - * cause an empty string result. If the argument is an area, the first (top-left) cell is used - * (regardless of the coordinates of the evaluating formula cell). - */ -public final class T extends Fixed1ArgFunction { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - ValueEval arg = arg0; - if (arg instanceof RefEval) { - // always use the first sheet - RefEval re = (RefEval)arg; - arg = re.getInnerValueEval(re.getFirstSheetIndex()); - } else if (arg instanceof AreaEval) { - // when the arg is an area, choose the top left cell - arg = ((AreaEval) arg).getRelativeValue(0, 0); - } - - if (arg instanceof StringEval) { - // Text values are returned unmodified - return arg; - } - - if (arg instanceof ErrorEval) { - // Error values also returned unmodified - return arg; - } - // for all other argument types the result is empty string - return StringEval.EMPTY_INSTANCE; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/TextFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/TextFunction.java deleted file mode 100644 index c8b4b3ca0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/TextFunction.java +++ /dev/null @@ -1,396 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.*; -import org.apache.poi.ss.usermodel.DataFormatter; - -import java.util.Locale; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * @author Josh Micich - * @author Stephen Wolke (smwolke at geistig.com) - */ -public abstract class TextFunction implements Function { - protected static final DataFormatter formatter = new DataFormatter(); - - protected static String evaluateStringArg(ValueEval eval, int srcRow, int srcCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(eval, srcRow, srcCol); - return OperandResolver.coerceValueToString(ve); - } - protected static int evaluateIntArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - return OperandResolver.coerceValueToInt(ve); - } - - protected static double evaluateDoubleArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - return OperandResolver.coerceValueToDouble(ve); - } - - public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { - try { - return evaluateFunc(args, srcCellRow, srcCellCol); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - protected abstract ValueEval evaluateFunc(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException; - - /* ---------------------------------------------------------------------- */ - - private static abstract class SingleArgTextFunc extends Fixed1ArgFunction { - - protected SingleArgTextFunc() { - // no fields to initialise - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - String arg; - try { - arg = evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return evaluate(arg); - } - protected abstract ValueEval evaluate(String arg); - } - - /** - * Returns the character specified by a number. - */ - public static final Function CHAR = new Fixed1ArgFunction() { - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - int arg; - try { - arg = evaluateIntArg(arg0, srcRowIndex, srcColumnIndex); - if (arg < 0 || arg >= 256) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new StringEval(String.valueOf((char)arg)); - } - }; - - public static final Function LEN = new SingleArgTextFunc() { - protected ValueEval evaluate(String arg) { - return new NumberEval(arg.length()); - } - }; - public static final Function LOWER = new SingleArgTextFunc() { - protected ValueEval evaluate(String arg) { - return new StringEval(arg.toLowerCase(Locale.ROOT)); - } - }; - public static final Function UPPER = new SingleArgTextFunc() { - protected ValueEval evaluate(String arg) { - return new StringEval(arg.toUpperCase(Locale.ROOT)); - } - }; - - /** - * Implementation of the PROPER function: - * Normalizes all words (separated by non-word characters) by - * making the first letter upper and the rest lower case. - * - * This is nearly equivalent to toTitleCase if the Java language had it - */ - public static final Function PROPER = new SingleArgTextFunc() { - protected ValueEval evaluate(String text) { - StringBuilder sb = new StringBuilder(); - boolean shouldMakeUppercase = true; - for(final char ch : text.toCharArray()) { - - // Note: we are using String.toUpperCase() here on purpose as it handles certain things - // better than Character.toUpperCase(), e.g. German "scharfes s" is translated - // to "SS" (i.e. two characters), if uppercased properly! - if (shouldMakeUppercase) { - sb.append(String.valueOf(ch).toUpperCase(Locale.ROOT)); - } - else { - sb.append(String.valueOf(ch).toLowerCase(Locale.ROOT)); - } - shouldMakeUppercase = !Character.isLetter(ch); - } - return new StringEval(sb.toString()); - } - }; - - /** - * An implementation of the TRIM function: - * Removes leading and trailing spaces from value if evaluated operand - * value is string. - * Author: Manda Wilson < wilson at c bio dot msk cc dot org > - */ - public static final Function TRIM = new SingleArgTextFunc() { - protected ValueEval evaluate(String arg) { - return new StringEval(arg.trim()); - } - }; - - /** - * An implementation of the CLEAN function: - * In Excel, the Clean function removes all non-printable characters from a string. - * - * Author: Aniket Banerjee(banerjee@google.com) - */ - public static final Function CLEAN = new SingleArgTextFunc() { - protected ValueEval evaluate(String arg) { - StringBuilder result = new StringBuilder(); - for (final char c : arg.toCharArray()) { - if (isPrintable(c)) { - result.append(c); - } - } - return new StringEval(result.toString()); - } - - /** - * From Excel docs: The CLEAN function was designed to remove the first 32 nonprinting characters - * in the 7-bit ASCII code (values 0 through 31) from text. In the Unicode character set, - * there are additional nonprinting characters (values 127, 129, 141, 143, 144, and 157). By itself, - * the CLEAN function does not remove these additional nonprinting characters. To do this task, - * use the SUBSTITUTE function to replace the higher value Unicode characters with the 7-bit ASCII - * characters for which the TRIM and CLEAN functions were designed. - * - * @param c the character to test - * @return whether the character is printable - */ - private boolean isPrintable(char c){ - return c >= 32; - } - }; - - /** - * An implementation of the MID function
        - * MID returns a specific number of - * characters from a text string, starting at the specified position.

        - * - * Syntax:
        MID(text, start_num, - * num_chars)
        - * - * Author: Manda Wilson < wilson at c bio dot msk cc dot org > - */ - public static final Function MID = new Fixed3ArgFunction() { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1, ValueEval arg2) { - String text; - int startCharNum; - int numChars; - try { - text = evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - startCharNum = evaluateIntArg(arg1, srcRowIndex, srcColumnIndex); - numChars = evaluateIntArg(arg2, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - int startIx = startCharNum - 1; // convert to zero-based - - // Note - for start_num arg, blank/zero causes error(#VALUE!), - // but for num_chars causes empty string to be returned. - if (startIx < 0) { - return ErrorEval.VALUE_INVALID; - } - if (numChars < 0) { - return ErrorEval.VALUE_INVALID; - } - int len = text.length(); - if (numChars < 0 || startIx > len) { - return new StringEval(""); - } - int endIx = Math.min(startIx + numChars, len); - String result = text.substring(startIx, endIx); - return new StringEval(result); - } - }; - - private static final class LeftRight extends Var1or2ArgFunction { - private static final ValueEval DEFAULT_ARG1 = new NumberEval(1.0); - private final boolean _isLeft; - protected LeftRight(boolean isLeft) { - _isLeft = isLeft; - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, DEFAULT_ARG1); - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1) { - String arg; - int index; - try { - arg = evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - index = evaluateIntArg(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - if(index < 0) { - return ErrorEval.VALUE_INVALID; - } - - String result; - if (_isLeft) { - result = arg.substring(0, Math.min(arg.length(), index)); - } else { - result = arg.substring(Math.max(0, arg.length()-index)); - } - return new StringEval(result); - } - } - - public static final Function LEFT = new LeftRight(true); - public static final Function RIGHT = new LeftRight(false); - - public static final Function CONCATENATE = new Function() { - - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - StringBuilder sb = new StringBuilder(); - for (ValueEval arg : args) { - try { - sb.append(evaluateStringArg(arg, srcRowIndex, srcColumnIndex)); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - return new StringEval(sb.toString()); - } - }; - - public static final Function EXACT = new Fixed2ArgFunction() { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, - ValueEval arg1) { - String s0; - String s1; - try { - s0 = evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - s1 = evaluateStringArg(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return BoolEval.valueOf(s0.equals(s1)); - } - }; - - /** - * An implementation of the TEXT function
        - * TEXT returns a number value formatted with the given number formatting string. - * This function is not a complete implementation of the Excel function, but - * handles most of the common cases. All work is passed down to - * {@link DataFormatter} to be done, as this works much the same as the - * display focused work that that does. - * - * Syntax:
        TEXT(value, format_text)
        - */ - public static final Function TEXT = new Fixed2ArgFunction() { - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - double s0; - String s1; - try { - s0 = evaluateDoubleArg(arg0, srcRowIndex, srcColumnIndex); - s1 = evaluateStringArg(arg1, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - try { - // Ask DataFormatter to handle the String for us - String formattedStr = formatter.formatRawCellContents(s0, -1, s1); - return new StringEval(formattedStr); - } catch (Exception e) { - return ErrorEval.VALUE_INVALID; - } - } - }; - - private static final class SearchFind extends Var2or3ArgFunction { - - private final boolean _isCaseSensitive; - - public SearchFind(boolean isCaseSensitive) { - _isCaseSensitive = isCaseSensitive; - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - try { - String needle = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - String haystack = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex); - return eval(haystack, needle, 0); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - try { - String needle = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex); - String haystack = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex); - // evaluate third arg and convert from 1-based to 0-based index - int startpos = TextFunction.evaluateIntArg(arg2, srcRowIndex, srcColumnIndex) - 1; - if (startpos < 0) { - return ErrorEval.VALUE_INVALID; - } - return eval(haystack, needle, startpos); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - private ValueEval eval(String haystack, String needle, int startIndex) { - int result; - if (_isCaseSensitive) { - result = haystack.indexOf(needle, startIndex); - } else { - result = haystack.toUpperCase(Locale.ROOT) - .indexOf(needle.toUpperCase(Locale.ROOT), startIndex); - } - if (result == -1) { - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(result + 1); - } - } - /** - * Implementation of the FIND() function.

        - * - * Syntax:
        - * FIND(find_text, within_text, start_num)

        - * - * FIND returns the character position of the first (case sensitive) occurrence of - * find_text inside within_text. The third parameter, - * start_num, is optional (default=1) and specifies where to start searching - * from. Character positions are 1-based.

        - * - * Author: Torstein Tauno Svendsen (torstei@officenet.no) - */ - public static final Function FIND = new SearchFind(true); - /** - * Implementation of the FIND() function.

        - * - * Syntax:
        - * SEARCH(find_text, within_text, start_num)

        - * - * SEARCH is a case-insensitive version of FIND() - */ - public static final Function SEARCH = new SearchFind(false); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/TimeFunc.java b/trunk/src/java/org/apache/poi/ss/formula/functions/TimeFunc.java deleted file mode 100644 index 8423919e1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/TimeFunc.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for the Excel function TIME - * - * @author Steven Butler (sebutler @ gmail dot com) - * - * Based on POI {@link DateFunc} - */ -public final class TimeFunc extends Fixed3ArgFunction { - - private static final int SECONDS_PER_MINUTE = 60; - private static final int SECONDS_PER_HOUR = 3600; - private static final int HOURS_PER_DAY = 24; - private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR; - - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - double result; - try { - result = evaluate(evalArg(arg0, srcRowIndex, srcColumnIndex), evalArg(arg1, srcRowIndex, srcColumnIndex), evalArg(arg2, srcRowIndex, srcColumnIndex)); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(result); - } - private static int evalArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException { - if (arg == MissingArgEval.instance) { - return 0; - } - ValueEval ev = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex); - // Excel silently truncates double values to integers - return OperandResolver.coerceValueToInt(ev); - } - /** - * Converts the supplied hours, minutes and seconds to an Excel time value. - * - * - * @param ds array of 3 doubles containing hours, minutes and seconds. - * Non-integer inputs are truncated to an integer before further calculation - * of the time value. - * @return An Excel representation of a time of day. - * If the time value represents more than a day, the days are removed from - * the result, leaving only the time of day component. - * @throws org.apache.poi.ss.formula.eval.EvaluationException - * If any of the arguments are greater than 32767 or the hours - * minutes and seconds when combined form a time value less than 0, the function - * evaluates to an error. - */ - private static double evaluate(int hours, int minutes, int seconds) throws EvaluationException { - - if (hours > 32767 || minutes > 32767 || seconds > 32767) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - int totalSeconds = hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds; - - if (totalSeconds < 0) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - return (totalSeconds % SECONDS_PER_DAY) / (double)SECONDS_PER_DAY; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Today.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Today.java deleted file mode 100644 index d86844aa2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Today.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - -/** - * Implementation of Excel TODAY() Function
        - */ -public final class Today extends Fixed0ArgFunction { - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) { - Calendar now = LocaleUtil.getLocaleCalendar(); - now.clear(Calendar.HOUR); - now.set(Calendar.HOUR_OF_DAY,0); - now.clear(Calendar.MINUTE); - now.clear(Calendar.SECOND); - now.clear(Calendar.MILLISECOND); - return new NumberEval(DateUtil.getExcelDate(now.getTime())); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Value.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Value.java deleted file mode 100644 index 056ec2f3d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Value.java +++ /dev/null @@ -1,192 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Implementation for Excel VALUE() function.

        - * - * Syntax:
        VALUE(text)
        - * - * Converts the text argument to a number. Leading and/or trailing whitespace is - * ignored. Currency symbols and thousands separators are stripped out. - * Scientific notation is also supported. If the supplied text does not convert - * properly the result is #VALUE! error. Blank string converts to zero. - */ -public final class Value extends Fixed1ArgFunction { - - /** "1,0000" is valid, "1,00" is not */ - private static final int MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR = 4; - private static final Double ZERO = new Double(0.0); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - ValueEval veText; - try { - veText = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - String strText = OperandResolver.coerceValueToString(veText); - Double result = convertTextToNumber(strText); - if (result == null) { - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(result.doubleValue()); - } - - /** - * TODO see if the same functionality is needed in {@link OperandResolver#parseDouble(String)} - * - * @return null if there is any problem converting the text - */ - private static Double convertTextToNumber(String strText) { - boolean foundCurrency = false; - boolean foundUnaryPlus = false; - boolean foundUnaryMinus = false; - boolean foundPercentage = false; - - int len = strText.length(); - int i; - for (i = 0; i < len; i++) { - char ch = strText.charAt(i); - if (Character.isDigit(ch) || ch == '.') { - break; - } - switch (ch) { - case ' ': - // intervening spaces between '$', '-', '+' are OK - continue; - case '$': - if (foundCurrency) { - // only one currency symbols is allowed - return null; - } - foundCurrency = true; - continue; - case '+': - if (foundUnaryMinus || foundUnaryPlus) { - return null; - } - foundUnaryPlus = true; - continue; - case '-': - if (foundUnaryMinus || foundUnaryPlus) { - return null; - } - foundUnaryMinus = true; - continue; - default: - // all other characters are illegal - return null; - } - } - if (i >= len) { - // didn't find digits or '.' - if (foundCurrency || foundUnaryMinus || foundUnaryPlus) { - return null; - } - return ZERO; - } - - // remove thousands separators - - boolean foundDecimalPoint = false; - int lastThousandsSeparatorIndex = Short.MIN_VALUE; - - StringBuffer sb = new StringBuffer(len); - for (; i < len; i++) { - char ch = strText.charAt(i); - if (Character.isDigit(ch)) { - sb.append(ch); - continue; - } - switch (ch) { - case ' ': - String remainingTextTrimmed = strText.substring(i).trim(); - // support for value[space]% - if (remainingTextTrimmed.equals("%")) { - foundPercentage= true; - break; - } - if (remainingTextTrimmed.length() > 0) { - // intervening spaces not allowed once the digits start - return null; - } - break; - case '.': - if (foundDecimalPoint) { - return null; - } - if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { - return null; - } - foundDecimalPoint = true; - sb.append('.'); - continue; - case ',': - if (foundDecimalPoint) { - // thousands separators not allowed after '.' or 'E' - return null; - } - int distanceBetweenThousandsSeparators = i - lastThousandsSeparatorIndex; - // as long as there are 3 or more digits between - if (distanceBetweenThousandsSeparators < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { - return null; - } - lastThousandsSeparatorIndex = i; - // don't append ',' - continue; - - case 'E': - case 'e': - if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { - return null; - } - // append rest of strText and skip to end of loop - sb.append(strText.substring(i)); - i = len; - break; - case '%': - foundPercentage = true; - break; - default: - // all other characters are illegal - return null; - } - } - if (!foundDecimalPoint) { - if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { - return null; - } - } - double d; - try { - d = Double.parseDouble(sb.toString()); - } catch (NumberFormatException e) { - // still a problem parsing the number - probably out of range - return null; - } - double result = foundUnaryMinus ? -d : d; - return foundPercentage ? result/100. : result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Var1or2ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Var1or2ArgFunction.java deleted file mode 100644 index 1938b79d3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Var1or2ArgFunction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for any function which must take two or three - * arguments - * - * @author Josh Micich - */ -abstract class Var1or2ArgFunction implements Function1Arg, Function2Arg { - - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 1: - return evaluate(srcRowIndex, srcColumnIndex, args[0]); - case 2: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Var2or3ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Var2or3ArgFunction.java deleted file mode 100644 index cf3f350d6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Var2or3ArgFunction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for any function which must take two or three - * arguments - * - * @author Josh Micich - */ -abstract class Var2or3ArgFunction implements Function2Arg, Function3Arg { - - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 2: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]); - case 3: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Var3or4ArgFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Var3or4ArgFunction.java deleted file mode 100644 index e701b2d9a..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Var3or4ArgFunction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.ValueEval; - -/** - * Convenience base class for any function which must take three or four - * arguments - * - * @author Josh Micich - */ -abstract class Var3or4ArgFunction implements Function3Arg, Function4Arg { - - public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - switch (args.length) { - case 3: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]); - case 4: - return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], args[3]); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/Vlookup.java b/trunk/src/java/org/apache/poi/ss/formula/functions/Vlookup.java deleted file mode 100644 index 2f21e21cf..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/Vlookup.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; -import org.apache.poi.ss.formula.TwoDEval; -/** - * Implementation of the VLOOKUP() function.

        - * - * VLOOKUP finds a row in a lookup table by the first column value and returns the value from another column.
        - * - * Syntax:
        - * VLOOKUP(lookup_value, table_array, col_index_num, range_lookup)

        - * - * lookup_value The value to be found in the first column of the table array.
        - * table_array An area reference for the lookup data.
        - * col_index_num a 1 based index specifying which column value of the lookup data will be returned.
        - * range_lookup If TRUE (default), VLOOKUP finds the largest value less than or equal to - * the lookup_value. If FALSE, only exact matches will be considered
        - */ -public final class Vlookup extends Var3or4ArgFunction { - private static final ValueEval DEFAULT_ARG3 = BoolEval.TRUE; - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - return evaluate(srcRowIndex, srcColumnIndex, arg0, arg1, arg2, DEFAULT_ARG3); - } - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval lookup_value, ValueEval table_array, - ValueEval col_index, ValueEval range_lookup) { - try { - // Evaluation order: - // lookup_value , table_array, range_lookup, find lookup value, col_index, fetch result - ValueEval lookupValue = OperandResolver.getSingleValue(lookup_value, srcRowIndex, srcColumnIndex); - TwoDEval tableArray = LookupUtils.resolveTableArrayArg(table_array); - boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(range_lookup, srcRowIndex, srcColumnIndex); - int rowIndex = LookupUtils.lookupIndexOfValue(lookupValue, LookupUtils.createColumnVector(tableArray, 0), isRangeLookup); - int colIndex = LookupUtils.resolveRowOrColIndexArg(col_index, srcRowIndex, srcColumnIndex); - ValueVector resultCol = createResultColumnVector(tableArray, colIndex); - return resultCol.getItem(rowIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - - /** - * Returns one column from an AreaEval - * - * @param colIndex assumed to be non-negative - * - * @throws EvaluationException (#REF!) if colIndex is too high - */ - private ValueVector createResultColumnVector(TwoDEval tableArray, int colIndex) throws EvaluationException { - if(colIndex >= tableArray.getWidth()) { - throw EvaluationException.invalidRef(); - } - return LookupUtils.createColumnVector(tableArray, colIndex); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/WeekNum.java b/trunk/src/java/org/apache/poi/ss/formula/functions/WeekNum.java deleted file mode 100644 index 888ad11a0..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/WeekNum.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.LocaleUtil; - -/** - * Implementation for Excel WeekNum() function.

        - *

        - * Syntax:
        WeekNum (Serial_num,Return_type)
        - *

        - * Returns a number that indicates where the week falls numerically within a year. - *

        - *

        - * Serial_num is a date within the week. Dates should be entered by using the DATE function, - * or as results of other formulas or functions. For example, use DATE(2008,5,23) - * for the 23rd day of May, 2008. Problems can occur if dates are entered as text. - * Return_type is a number that determines on which day the week begins. The default is 1. - * 1 Week begins on Sunday. Weekdays are numbered 1 through 7. - * 2 Week begins on Monday. Weekdays are numbered 1 through 7. - */ -public class WeekNum extends Fixed2ArgFunction implements FreeRefFunction { - public static final FreeRefFunction instance = new WeekNum(); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval serialNumVE, ValueEval returnTypeVE) { - double serialNum = 0.0; - try { - serialNum = NumericFunction.singleOperandEvaluate(serialNumVE, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return ErrorEval.VALUE_INVALID; - } - Calendar serialNumCalendar = LocaleUtil.getLocaleCalendar(); - serialNumCalendar.setTime(DateUtil.getJavaDate(serialNum, false)); - - int returnType = 0; - try { - ValueEval ve = OperandResolver.getSingleValue(returnTypeVE, srcRowIndex, srcColumnIndex); - returnType = OperandResolver.coerceValueToInt(ve); - } catch (EvaluationException e) { - return ErrorEval.NUM_ERROR; - } - - if (returnType != 1 && returnType != 2) { - return ErrorEval.NUM_ERROR; - } - - return new NumberEval(this.getWeekNo(serialNumCalendar, returnType)); - } - - public int getWeekNo(Calendar cal, int weekStartOn) { - if (weekStartOn == 1) { - cal.setFirstDayOfWeek(Calendar.SUNDAY); - } else { - cal.setFirstDayOfWeek(Calendar.MONDAY); - } - return cal.get(Calendar.WEEK_OF_YEAR); - } - - public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { - if (args.length == 2) { - return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]); - } - return ErrorEval.VALUE_INVALID; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/WeekdayFunc.java b/trunk/src/java/org/apache/poi/ss/formula/functions/WeekdayFunc.java deleted file mode 100644 index deab05baf..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/WeekdayFunc.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.formula.functions; - -import java.util.Calendar; - -import org.apache.poi.ss.formula.eval.BlankEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.MissingArgEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.OperandResolver; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.DateUtil; - - -/** - * Implementation for the Excel function WEEKDAY - * - * @author Thies Wellpott - */ -public final class WeekdayFunc implements Function { -//or: extends Var1or2ArgFunction { - - public static final Function instance = new WeekdayFunc(); - - private WeekdayFunc() { - // no fields to initialise - } - - /* for Var1or2ArgFunction: - @Override - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { - } - - @Override - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - } - */ - - - /** - * Perform WEEKDAY(date, returnOption) function. - * Note: Parameter texts are from German EXCEL-2010 help. - * Parameters in args[]: - * args[0] serialDate - * EXCEL-date value - * Standardmaessig ist der 1. Januar 1900 die fortlaufende Zahl 1 und - * der 1. Januar 2008 die fortlaufende Zahl 39.448, da dieser Tag nach 39.448 Tagen - * auf den 01.01.1900 folgt. - * @return Option (optional) - * Bestimmt den Rueckgabewert: - 1 oder nicht angegeben Zahl 1 (Sonntag) bis 7 (Samstag). Verhaelt sich wie fruehere Microsoft Excel-Versionen. - 2 Zahl 1 (Montag) bis 7 (Sonntag). - 3 Zahl 0 (Montag) bis 6 (Sonntag). - 11 Die Zahlen 1 (Montag) bis 7 (Sonntag) - 12 Die Zahlen 1 (Dienstag) bis 7 (Montag) - 13 Die Zahlen 1 (Mittwoch) bis 7 (Dienstag) - 14 Die Zahlen 1 (Donnerstag) bis 7 (Mittwoch) - 15 Die Zahlen 1 (Freitag) bis 7 (Donnerstag) - 16 Die Zahlen 1 (Samstag) bis 7 (Freitag) - 17 Die Zahlen 1 (Sonntag) bis 7 (Samstag) - */ - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - try { - if (args.length < 1 || args.length > 2) { - return ErrorEval.VALUE_INVALID; - } - - // extract first parameter - ValueEval serialDateVE = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex); - double serialDate = OperandResolver.coerceValueToDouble(serialDateVE); - if (!DateUtil.isValidExcelDate(serialDate)) { - return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR - } - Calendar date = DateUtil.getJavaCalendar(serialDate, false); // (XXX 1904-windowing not respected) - int weekday = date.get(Calendar.DAY_OF_WEEK); // => sunday = 1, monday = 2, ..., saturday = 7 - - // extract second parameter - int returnOption = 1; // default value - if (args.length == 2) { - ValueEval ve = OperandResolver.getSingleValue(args[1], srcRowIndex, srcColumnIndex); - if (ve == MissingArgEval.instance || ve == BlankEval.instance) { - return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR - } - returnOption = OperandResolver.coerceValueToInt(ve); - if (returnOption == 2) { - returnOption = 11; // both mean the same - } - } // if - - // perform calculation - double result; - if (returnOption == 1) { - result = weekday; - // value 2 is handled above (as value 11) - } else if (returnOption == 3) { - result = (weekday + 6 - 1) % 7; - } else if (returnOption >= 11 && returnOption <= 17) { - result = (weekday + 6 - (returnOption - 10)) % 7 + 1; // rotate in the value range 1 to 7 - } else { - return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR - } - - return new NumberEval(result); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } // evaluate() - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java b/trunk/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java deleted file mode 100644 index da2a0f312..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java +++ /dev/null @@ -1,181 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.ss.formula.TwoDEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.EvaluationException; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public abstract class XYNumericFunction extends Fixed2ArgFunction { - - private static abstract class ValueArray implements ValueVector { - private final int _size; - protected ValueArray(int size) { - _size = size; - } - public ValueEval getItem(int index) { - if (index < 0 || index > _size) { - throw new IllegalArgumentException("Specified index " + index - + " is outside range (0.." + (_size - 1) + ")"); - } - return getItemInternal(index); - } - protected abstract ValueEval getItemInternal(int index); - public final int getSize() { - return _size; - } - } - - private static final class SingleCellValueArray extends ValueArray { - private final ValueEval _value; - public SingleCellValueArray(ValueEval value) { - super(1); - _value = value; - } - protected ValueEval getItemInternal(int index) { - return _value; - } - } - - private static final class RefValueArray extends ValueArray { - private final RefEval _ref; - private final int _width; - - public RefValueArray(RefEval ref) { - super(ref.getNumberOfSheets()); - _ref = ref; - _width = ref.getNumberOfSheets(); - } - protected ValueEval getItemInternal(int index) { - int sIx = (index % _width) + _ref.getFirstSheetIndex(); - return _ref.getInnerValueEval(sIx); - } - } - - private static final class AreaValueArray extends ValueArray { - private final TwoDEval _ae; - private final int _width; - - public AreaValueArray(TwoDEval ae) { - super(ae.getWidth() * ae.getHeight()); - _ae = ae; - _width = ae.getWidth(); - } - protected ValueEval getItemInternal(int index) { - int rowIx = index / _width; - int colIx = index % _width; - return _ae.getValue(rowIx, colIx); - } - } - - protected static interface Accumulator { - double accumulate(double x, double y); - } - - /** - * Constructs a new instance of the Accumulator used to calculated this function - */ - protected abstract Accumulator createAccumulator(); - - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - - double result; - try { - ValueVector vvX = createValueVector(arg0); - ValueVector vvY = createValueVector(arg1); - int size = vvX.getSize(); - if (size == 0 || vvY.getSize() != size) { - return ErrorEval.NA; - } - result = evaluateInternal(vvX, vvY, size); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (Double.isNaN(result) || Double.isInfinite(result)) { - return ErrorEval.NUM_ERROR; - } - return new NumberEval(result); - } - - private double evaluateInternal(ValueVector x, ValueVector y, int size) - throws EvaluationException { - Accumulator acc = createAccumulator(); - - // error handling is as if the x is fully evaluated before y - ErrorEval firstXerr = null; - ErrorEval firstYerr = null; - boolean accumlatedSome = false; - double result = 0.0; - - for (int i = 0; i < size; i++) { - ValueEval vx = x.getItem(i); - ValueEval vy = y.getItem(i); - if (vx instanceof ErrorEval) { - if (firstXerr == null) { - firstXerr = (ErrorEval) vx; - continue; - } - } - if (vy instanceof ErrorEval) { - if (firstYerr == null) { - firstYerr = (ErrorEval) vy; - continue; - } - } - // only count pairs if both elements are numbers - if (vx instanceof NumberEval && vy instanceof NumberEval) { - accumlatedSome = true; - NumberEval nx = (NumberEval) vx; - NumberEval ny = (NumberEval) vy; - result += acc.accumulate(nx.getNumberValue(), ny.getNumberValue()); - } else { - // all other combinations of value types are silently ignored - } - } - if (firstXerr != null) { - throw new EvaluationException(firstXerr); - } - if (firstYerr != null) { - throw new EvaluationException(firstYerr); - } - if (!accumlatedSome) { - throw new EvaluationException(ErrorEval.DIV_ZERO); - } - return result; - } - - private static ValueVector createValueVector(ValueEval arg) throws EvaluationException { - if (arg instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) arg); - } - if (arg instanceof TwoDEval) { - return new AreaValueArray((TwoDEval) arg); - } - if (arg instanceof RefEval) { - return new RefValueArray((RefEval) arg); - } - return new SingleCellValueArray(arg); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/package.html b/trunk/src/java/org/apache/poi/ss/formula/package.html deleted file mode 100644 index 3296708d5..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -This package contains common internal POI code for manipulating formulas. -Client applications should not refer to these classes directly. - - - diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java deleted file mode 100644 index c3ae44487..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import java.util.Locale; - -import org.apache.poi.ss.formula.function.FunctionMetadata; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; - -/** - * This class provides the base functionality for Excel sheet functions - * There are two kinds of function Ptgs - tFunc and tFuncVar - * Therefore, this class will have ONLY two subclasses - * @author Avik Sengupta - * @author Andrew C. Oliver (acoliver at apache dot org) - */ -public abstract class AbstractFunctionPtg extends OperationPtg { - - /** - * The name of the IF function (i.e. "IF"). Extracted as a constant for clarity. - */ - public static final String FUNCTION_NAME_IF = "IF"; - /** All external functions have function index 255 */ - private static final short FUNCTION_INDEX_EXTERNAL = 255; - - private final byte returnClass; - private final byte[] paramClass; - - private final byte _numberOfArgs; - private final short _functionIndex; - - protected AbstractFunctionPtg(int functionIndex, int pReturnClass, byte[] paramTypes, int nParams) { - _numberOfArgs = (byte) nParams; - _functionIndex = (short) functionIndex; - returnClass = (byte) pReturnClass; - paramClass = paramTypes; - } - public final boolean isBaseToken() { - return false; - } - - public final String toString() { - StringBuilder sb = new StringBuilder(64); - sb.append(getClass().getName()).append(" ["); - sb.append(lookupName(_functionIndex)); - sb.append(" nArgs=").append(_numberOfArgs); - sb.append("]"); - return sb.toString(); - } - - public final short getFunctionIndex() { - return _functionIndex; - } - public final int getNumberOfOperands() { - return _numberOfArgs; - } - - public final String getName() { - return lookupName(_functionIndex); - } - /** - * external functions get some special processing - * @return true if this is an external function - */ - public final boolean isExternalFunction() { - return _functionIndex == FUNCTION_INDEX_EXTERNAL; - } - - public final String toFormulaString() { - return getName(); - } - - public String toFormulaString(String[] operands) { - StringBuilder buf = new StringBuilder(); - - if(isExternalFunction()) { - buf.append(operands[0]); // first operand is actually the function name - appendArgs(buf, 1, operands); - } else { - buf.append(getName()); - appendArgs(buf, 0, operands); - } - return buf.toString(); - } - - private static void appendArgs(StringBuilder buf, int firstArgIx, String[] operands) { - buf.append('('); - for (int i=firstArgIx;ifirstArgIx) { - buf.append(','); - } - buf.append(operands[i]); - } - buf.append(")"); - } - - public abstract int getSize(); - - - /** - * Used to detect whether a function name found in a formula is one of the standard excel functions - *

        - * The name matching is case insensitive. - * @return true if the name specifies a standard worksheet function, - * false if the name should be assumed to be an external function. - */ - public static final boolean isBuiltInFunctionName(String name) { - short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase(Locale.ROOT)); - return ix >= 0; - } - - protected final String lookupName(short index) { - if(index == FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL) { - return "#external#"; - } - FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(index); - if(fm == null) { - throw new RuntimeException("bad function index (" + index + ")"); - } - return fm.getName(); - } - - /** - * Resolves internal function names into function indexes. - *

        - * The name matching is case insensitive. - * @return the standard worksheet function index if found, otherwise FUNCTION_INDEX_EXTERNAL - */ - protected static short lookupIndex(String name) { - short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase(Locale.ROOT)); - if (ix < 0) { - return FUNCTION_INDEX_EXTERNAL; - } - return ix; - } - - public byte getDefaultOperandClass() { - return returnClass; - } - - public final byte getParameterClass(int index) { - if (index >= paramClass.length) { - // For var-arg (and other?) functions, the metadata does not list all the parameter - // operand classes. In these cases, all extra parameters are assumed to have the - // same operand class as the last one specified. - return paramClass[paramClass.length - 1]; - } - return paramClass[index]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AddPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AddPtg.java deleted file mode 100644 index e275d8c43..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AddPtg.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Addition operator PTG the "+" binomial operator. If you need more - * explanation than that then well...We really can't help you here. - * @author Andrew C. Oliver (acoliver@apache.org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class AddPtg extends ValueOperatorPtg { - public final static byte sid = 0x03; - - private final static String ADD = "+"; - - public static final ValueOperatorPtg instance = new AddPtg(); - - private AddPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - /** implementation of method from OperationsPtg*/ - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append(ADD); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java deleted file mode 100644 index 59324f809..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Common superclass of 2-D area refs - */ -public abstract class Area2DPtgBase extends AreaPtgBase { - private final static int SIZE = 9; - - protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) { - super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative); - } - protected Area2DPtgBase(AreaReference ar) { - super(ar); - } - - protected Area2DPtgBase(LittleEndianInput in) { - readCoordinates(in); - } - - protected abstract byte getSid(); - - public final void write(LittleEndianOutput out) { - out.writeByte(getSid() + getPtgClass()); - writeCoordinates(out); - } - - public final int getSize() { - return SIZE; - } - - public final String toFormulaString() { - return formatReferenceAsString(); - } - - public final String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - sb.append(formatReferenceAsString()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java deleted file mode 100644 index 7bf64c067..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.ExternSheetReferenceToken; -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - *

        Title: Area 3D Ptg - 3D reference (Sheet + Area)

        - *

        Description: Defined an area in Extern Sheet.

        - *

        REFERENCE:

        - * - *

        This is HSSF only, as it matches the HSSF file format way of - * referring to the sheet by an extern index. The XSSF equivalent - * is {@link Area3DPxg} - */ -public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken { - public final static byte sid = 0x3b; - private final static int SIZE = 11; // 10 + 1 for Ptg - - private int field_1_index_extern_sheet; - - - public Area3DPtg(String arearef, int externIdx) { - super(new AreaReference(arearef)); - setExternSheetIndex(externIdx); - } - - public Area3DPtg(LittleEndianInput in) { - field_1_index_extern_sheet = in.readShort(); - readCoordinates(in); - } - - public Area3DPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, - boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative, - int externalSheetIndex) { - super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative); - setExternSheetIndex(externalSheetIndex); - } - - public Area3DPtg(AreaReference arearef, int externIdx) { - super(arearef); - setExternSheetIndex(externIdx); - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - sb.append("sheetIx=").append(getExternSheetIndex()); - sb.append(" ! "); - sb.append(formatReferenceAsString()); - sb.append("]"); - return sb.toString(); - } - - @Override - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_index_extern_sheet); - writeCoordinates(out); - } - - @Override - public int getSize() { - return SIZE; - } - - public int getExternSheetIndex() { - return field_1_index_extern_sheet; - } - - public void setExternSheetIndex(int index) { - field_1_index_extern_sheet = index; - } - public String format2DRefAsString() { - return formatReferenceAsString(); - } - /** - * @return text representation of this area reference that can be used in text - * formulas. The sheet name will get properly delimited if required. - */ - public String toFormulaString(FormulaRenderingWorkbook book) { - return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString()); - } - @Override - public String toFormulaString() { - throw new RuntimeException("3D references need a workbook to determine formula text"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java deleted file mode 100644 index 2916211b6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.SheetIdentifier; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.formula.SheetRangeIdentifier; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.util.LittleEndianOutput; - -/** - *

        Title: XSSF Area 3D Reference (Sheet + Area)

        - *

        Description: Defined an area in an external or different sheet.

        - *

        REFERENCE:

        - * - *

        This is XSSF only, as it stores the sheet / book references - * in String form. The HSSF equivalent using indexes is {@link Area3DPtg}

        - */ -public final class Area3DPxg extends AreaPtgBase implements Pxg3D { - private int externalWorkbookNumber = -1; - private String firstSheetName; - private String lastSheetName; - - public Area3DPxg(int externalWorkbookNumber, SheetIdentifier sheetName, String arearef) { - this(externalWorkbookNumber, sheetName, new AreaReference(arearef)); - } - public Area3DPxg(int externalWorkbookNumber, SheetIdentifier sheetName, AreaReference arearef) { - super(arearef); - this.externalWorkbookNumber = externalWorkbookNumber; - this.firstSheetName = sheetName.getSheetIdentifier().getName(); - if (sheetName instanceof SheetRangeIdentifier) { - this.lastSheetName = ((SheetRangeIdentifier)sheetName).getLastSheetIdentifier().getName(); - } else { - this.lastSheetName = null; - } - } - - public Area3DPxg(SheetIdentifier sheetName, String arearef) { - this(sheetName, new AreaReference(arearef)); - } - public Area3DPxg(SheetIdentifier sheetName, AreaReference arearef) { - this(-1, sheetName, arearef); - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - if (externalWorkbookNumber >= 0) { - sb.append(" ["); - sb.append("workbook=").append(getExternalWorkbookNumber()); - sb.append("] "); - } - sb.append("sheet=").append(getSheetName()); - if (lastSheetName != null) { - sb.append(" : "); - sb.append("sheet=").append(lastSheetName); - } - sb.append(" ! "); - sb.append(formatReferenceAsString()); - sb.append("]"); - return sb.toString(); - } - - public int getExternalWorkbookNumber() { - return externalWorkbookNumber; - } - public String getSheetName() { - return firstSheetName; - } - public String getLastSheetName() { - return lastSheetName; - } - - public void setSheetName(String sheetName) { - this.firstSheetName = sheetName; - } - public void setLastSheetName(String sheetName) { - this.lastSheetName = sheetName; - } - - public String format2DRefAsString() { - return formatReferenceAsString(); - } - - public String toFormulaString() { - StringBuffer sb = new StringBuffer(); - if (externalWorkbookNumber >= 0) { - sb.append('['); - sb.append(externalWorkbookNumber); - sb.append(']'); - } - SheetNameFormatter.appendFormat(sb, firstSheetName); - if (lastSheetName != null) { - sb.append(':'); - SheetNameFormatter.appendFormat(sb, lastSheetName); - } - sb.append('!'); - sb.append(formatReferenceAsString()); - return sb.toString(); - } - - public int getSize() { - return 1; - } - public void write(LittleEndianOutput out) { - throw new IllegalStateException("XSSF-only Ptg, should not be serialised"); - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java deleted file mode 100644 index 0685e8ec9..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * AreaErr - handles deleted cell area references. - * - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public final class AreaErrPtg extends OperandPtg { - public final static byte sid = 0x2B; - private final int unused1; - private final int unused2; - - public AreaErrPtg() { - unused1 = 0; - unused2 = 0; - } - - public AreaErrPtg(LittleEndianInput in) { - // 8 bytes unused: - unused1 = in.readInt(); - unused2 = in.readInt(); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeInt(unused1); - out.writeInt(unused2); - } - - public String toFormulaString() { - return FormulaError.REF.getString(); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } - - public int getSize() { - return 9; - } -} - diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaI.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaI.java deleted file mode 100644 index 361012662..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaI.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Common interface for AreaPtg and Area3DPtg, and their child classes. - */ -public interface AreaI { - /** - * @return the first row in the area - */ - int getFirstRow(); - - /** - * @return last row in the range (x2 in x1,y1-x2,y2) - */ - int getLastRow(); - - /** - * @return the first column number in the area. - */ - int getFirstColumn(); - - /** - * @return lastcolumn in the area - */ - int getLastColumn(); - - class OffsetArea implements AreaI { - - private final int _firstColumn; - private final int _firstRow; - private final int _lastColumn; - private final int _lastRow; - - public OffsetArea(int baseRow, int baseColumn, int relFirstRowIx, int relLastRowIx, - int relFirstColIx, int relLastColIx) { - _firstRow = baseRow + Math.min(relFirstRowIx, relLastRowIx); - _lastRow = baseRow + Math.max(relFirstRowIx, relLastRowIx); - _firstColumn = baseColumn + Math.min(relFirstColIx, relLastColIx); - _lastColumn = baseColumn + Math.max(relFirstColIx, relLastColIx); - } - - public int getFirstColumn() { - return _firstColumn; - } - - public int getFirstRow() { - return _firstRow; - } - - public int getLastColumn() { - return _lastColumn; - } - - public int getLastRow() { - return _lastRow; - } - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java deleted file mode 100644 index bc8f76e3d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; - -/** - * Specifies a rectangular area of cells A1:A4 for instance. - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class AreaNPtg extends Area2DPtgBase { - public final static short sid = 0x2D; - - public AreaNPtg(LittleEndianInput in) { - super(in); - } - - protected byte getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java deleted file mode 100644 index a0bb8f696..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.util.LittleEndianInput; - -/** - * Specifies a rectangular area of cells A1:A4 for instance. - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class AreaPtg extends Area2DPtgBase { - public final static short sid = 0x25; - - public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) { - super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative); - } - public AreaPtg(LittleEndianInput in) { - super(in); - } - public AreaPtg(String arearef) { - super(new AreaReference(arearef)); - } - public AreaPtg(AreaReference areaRef) { - super(areaRef); - } - @Override - protected byte getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java deleted file mode 100644 index 816287620..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java +++ /dev/null @@ -1,302 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Specifies a rectangular area of cells A1:A4 for instance. - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public abstract class AreaPtgBase extends OperandPtg implements AreaI { - /** - * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas. - * see similar comment in ReferencePtg - */ - protected final RuntimeException notImplemented() { - return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted"); - } - - /** zero based, unsigned 16 bit */ - private int field_1_first_row; - /** zero based, unsigned 16 bit */ - private int field_2_last_row; - /** zero based, unsigned 8 bit */ - private int field_3_first_column; //BitFields: (first row relative, first col relative, first column number) - /** zero based, unsigned 8 bit */ - private int field_4_last_column; //BitFields: (last row relative, last col relative, last column number) - - private final static BitField rowRelative = BitFieldFactory.getInstance(0x8000); - private final static BitField colRelative = BitFieldFactory.getInstance(0x4000); - private final static BitField columnMask = BitFieldFactory.getInstance(0x3FFF); - - protected AreaPtgBase() { - // do nothing - } - - protected AreaPtgBase(AreaReference ar) { - CellReference firstCell = ar.getFirstCell(); - CellReference lastCell = ar.getLastCell(); - setFirstRow(firstCell.getRow()); - setFirstColumn(firstCell.getCol() == -1 ? 0 : firstCell.getCol()); - setLastRow(lastCell.getRow()); - setLastColumn(lastCell.getCol() == -1 ? 0xFF : lastCell.getCol()); - setFirstColRelative(!firstCell.isColAbsolute()); - setLastColRelative(!lastCell.isColAbsolute()); - setFirstRowRelative(!firstCell.isRowAbsolute()); - setLastRowRelative(!lastCell.isRowAbsolute()); - } - - protected AreaPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, - boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) { - - if (lastRow >= firstRow) { - setFirstRow(firstRow); - setLastRow(lastRow); - setFirstRowRelative(firstRowRelative); - setLastRowRelative(lastRowRelative); - } else { - setFirstRow(lastRow); - setLastRow(firstRow); - setFirstRowRelative(lastRowRelative); - setLastRowRelative(firstRowRelative); - } - - if (lastColumn >= firstColumn) { - setFirstColumn(firstColumn); - setLastColumn(lastColumn); - setFirstColRelative(firstColRelative); - setLastColRelative(lastColRelative); - } else { - setFirstColumn(lastColumn); - setLastColumn(firstColumn); - setFirstColRelative(lastColRelative); - setLastColRelative(firstColRelative); - } - } - - /** - * Sort the first and last row and columns in-place to the preferred (top left:bottom right) order - * Note: Sort only occurs when an instance is constructed or when this method is called. - * - *

        For example, $E5:B$10 becomes B5:$E$10

        - */ - public void sortTopLeftToBottomRight() { - if (getFirstRow() > getLastRow()) { - //swap first row and last row numbers and relativity - //Note: cannot just swap the fields because row relativity is stored in fields 3 and 4 - final int firstRow = getFirstRow(); - final boolean firstRowRel = isFirstRowRelative(); - setFirstRow(getLastRow()); - setFirstRowRelative(isLastRowRelative()); - setLastRow(firstRow); - setLastRowRelative(firstRowRel); - } - if (getFirstColumn() > getLastColumn()) { - //swap first column and last column numbers and relativity - //Note: cannot just swap the fields because row relativity is stored in fields 3 and 4 - final int firstCol = getFirstColumn(); - final boolean firstColRel = isFirstColRelative(); - setFirstColumn(getLastColumn()); - setFirstColRelative(isLastColRelative()); - setLastColumn(firstCol); - setLastColRelative(firstColRel); - } - } - - protected final void readCoordinates(LittleEndianInput in) { - field_1_first_row = in.readUShort(); - field_2_last_row = in.readUShort(); - field_3_first_column = in.readUShort(); - field_4_last_column = in.readUShort(); - } - protected final void writeCoordinates(LittleEndianOutput out) { - out.writeShort(field_1_first_row); - out.writeShort(field_2_last_row); - out.writeShort(field_3_first_column); - out.writeShort(field_4_last_column); - } - - /** - * @return the first row in the area - */ - public final int getFirstRow() { - return field_1_first_row; - } - - /** - * sets the first row - * @param rowIx number (0-based) - */ - public final void setFirstRow(int rowIx) { - field_1_first_row = rowIx; - } - - /** - * @return last row in the range (x2 in x1,y1-x2,y2) - */ - public final int getLastRow() { - return field_2_last_row; - } - - /** - * @param rowIx last row number in the area - */ - public final void setLastRow(int rowIx) { - field_2_last_row = rowIx; - } - - /** - * @return the first column number in the area. - */ - public final int getFirstColumn() { - return columnMask.getValue(field_3_first_column); - } - - /** - * @return the first column number + the options bit settings unstripped - */ - public final short getFirstColumnRaw() { - return (short) field_3_first_column; // TODO - } - - /** - * @return whether or not the first row is a relative reference or not. - */ - public final boolean isFirstRowRelative() { - return rowRelative.isSet(field_3_first_column); - } - - /** - * sets the first row to relative or not - * @param rel is relative or not. - */ - public final void setFirstRowRelative(boolean rel) { - field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel); - } - - /** - * @return isrelative first column to relative or not - */ - public final boolean isFirstColRelative() { - return colRelative.isSet(field_3_first_column); - } - - /** - * set whether the first column is relative - */ - public final void setFirstColRelative(boolean rel) { - field_3_first_column=colRelative.setBoolean(field_3_first_column,rel); - } - - /** - * set the first column in the area - */ - public final void setFirstColumn(int colIx) { - field_3_first_column=columnMask.setValue(field_3_first_column, colIx); - } - - /** - * set the first column irrespective of the bitmasks - */ - public final void setFirstColumnRaw(int column) { - field_3_first_column = column; - } - - /** - * @return lastcolumn in the area - */ - public final int getLastColumn() { - return columnMask.getValue(field_4_last_column); - } - - /** - * @return last column and bitmask (the raw field) - */ - public final short getLastColumnRaw() { - return (short) field_4_last_column; - } - - /** - * @return last row relative or not - */ - public final boolean isLastRowRelative() { - return rowRelative.isSet(field_4_last_column); - } - - /** - * set whether the last row is relative or not - * @param rel true if the last row relative, else - * false - */ - public final void setLastRowRelative(boolean rel) { - field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel); - } - - /** - * @return lastcol relative or not - */ - public final boolean isLastColRelative() { - return colRelative.isSet(field_4_last_column); - } - - /** - * set whether the last column should be relative or not - */ - public final void setLastColRelative(boolean rel) { - field_4_last_column=colRelative.setBoolean(field_4_last_column,rel); - } - - /** - * set the last column in the area - */ - public final void setLastColumn(int colIx) { - field_4_last_column=columnMask.setValue(field_4_last_column, colIx); - } - - /** - * set the last column irrespective of the bitmasks - */ - public final void setLastColumnRaw(short column) { - field_4_last_column = column; - } - protected final String formatReferenceAsString() { - CellReference topLeft = new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative()); - CellReference botRight = new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative()); - - if(AreaReference.isWholeColumnReference(SpreadsheetVersion.EXCEL97, topLeft, botRight)) { - return (new AreaReference(topLeft, botRight)).formatAsString(); - } - return topLeft.formatAsString() + ":" + botRight.formatAsString(); - } - - public String toFormulaString() { - return formatReferenceAsString(); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java deleted file mode 100644 index 1dcf023b6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java +++ /dev/null @@ -1,268 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.constant.ConstantValueParser; -import org.apache.poi.ss.formula.constant.ErrorConstant; -import org.apache.poi.ss.util.NumberToTextConverter; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ArrayPtg - handles arrays - * - * The ArrayPtg is a little weird, the size of the Ptg when parsing initially only - * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows. - * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually - * held after this. So Ptg.createParsedExpression keeps track of the number of - * ArrayPtg elements and need to parse the data upto the FORMULA record size. - * - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class ArrayPtg extends Ptg { - public static final byte sid = 0x20; - - private static final int RESERVED_FIELD_LEN = 7; - /** - * The size of the plain tArray token written within the standard formula tokens - * (not including the data which comes after all formula tokens) - */ - public static final int PLAIN_TOKEN_SIZE = 1+RESERVED_FIELD_LEN; - - // 7 bytes of data (stored as an int, short and byte here) - private final int _reserved0Int; - private final int _reserved1Short; - private final int _reserved2Byte; - - // data from these fields comes after the Ptg data of all tokens in current formula - private final int _nColumns; - private final int _nRows; - private final Object[] _arrayValues; - - ArrayPtg(int reserved0, int reserved1, int reserved2, int nColumns, int nRows, Object[] arrayValues) { - _reserved0Int = reserved0; - _reserved1Short = reserved1; - _reserved2Byte = reserved2; - _nColumns = nColumns; - _nRows = nRows; - _arrayValues = arrayValues.clone(); - } - /** - * @param values2d array values arranged in rows - */ - public ArrayPtg(Object[][] values2d) { - int nColumns = values2d[0].length; - int nRows = values2d.length; - // convert 2-d to 1-d array (row by row according to getValueIndex()) - _nColumns = (short) nColumns; - _nRows = (short) nRows; - - Object[] vv = new Object[_nColumns * _nRows]; - for (int r=0; r= _nColumns) { - throw new IllegalArgumentException("Specified colIx (" + colIx - + ") is outside the allowed range (0.." + (_nColumns-1) + ")"); - } - if(rowIx < 0 || rowIx >= _nRows) { - throw new IllegalArgumentException("Specified rowIx (" + rowIx - + ") is outside the allowed range (0.." + (_nRows-1) + ")"); - } - return rowIx * _nColumns + colIx; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeInt(_reserved0Int); - out.writeShort(_reserved1Short); - out.writeByte(_reserved2Byte); - } - - public int writeTokenValueBytes(LittleEndianOutput out) { - - out.writeByte(_nColumns-1); - out.writeShort(_nRows-1); - ConstantValueParser.encode(out, _arrayValues); - return 3 + ConstantValueParser.getEncodedSize(_arrayValues); - } - - public int getRowCount() { - return _nRows; - } - - public int getColumnCount() { - return _nColumns; - } - - /** This size includes the size of the array Ptg plus the Array Ptg Token value size*/ - public int getSize() { - return PLAIN_TOKEN_SIZE - // data written after the all tokens: - + 1 + 2 // column, row - + ConstantValueParser.getEncodedSize(_arrayValues); - } - - public String toFormulaString() { - StringBuffer b = new StringBuffer(); - b.append("{"); - for (int y = 0; y < _nRows; y++) { - if (y > 0) { - b.append(";"); - } - for (int x = 0; x < _nColumns; x++) { - if (x > 0) { - b.append(","); - } - Object o = _arrayValues[getValueIndex(x, y)]; - b.append(getConstantText(o)); - } - } - b.append("}"); - return b.toString(); - } - - private static String getConstantText(Object o) { - - if (o == null) { - throw new RuntimeException("Array item cannot be null"); - } - if (o instanceof String) { - return "\"" + (String)o + "\""; - } - if (o instanceof Double) { - return NumberToTextConverter.toText(((Double)o).doubleValue()); - } - if (o instanceof Boolean) { - return ((Boolean)o).booleanValue() ? "TRUE" : "FALSE"; - } - if (o instanceof ErrorConstant) { - return ((ErrorConstant)o).getText(); - } - throw new IllegalArgumentException("Unexpected constant class (" + o.getClass().getName() + ")"); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_ARRAY; - } - - /** - * Represents the initial plain tArray token (without the constant data that trails the whole - * formula). Objects of this class are only temporary and cannot be used as {@link Ptg}s. - * These temporary objects get converted to {@link ArrayPtg} by the - * {@link #finishReading(LittleEndianInput)} method. - */ - static final class Initial extends Ptg { - private final int _reserved0; - private final int _reserved1; - private final int _reserved2; - - public Initial(LittleEndianInput in) { - _reserved0 = in.readInt(); - _reserved1 = in.readUShort(); - _reserved2 = in.readUByte(); - } - private static RuntimeException invalid() { - throw new IllegalStateException("This object is a partially initialised tArray, and cannot be used as a Ptg"); - } - public byte getDefaultOperandClass() { - throw invalid(); - } - public int getSize() { - return PLAIN_TOKEN_SIZE; - } - public boolean isBaseToken() { - return false; - } - public String toFormulaString() { - throw invalid(); - } - public void write(LittleEndianOutput out) { - throw invalid(); - } - /** - * Read in the actual token (array) values. This occurs - * AFTER the last Ptg in the expression. - * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf - */ - public ArrayPtg finishReading(LittleEndianInput in) { - int nColumns = in.readUByte(); - short nRows = in.readShort(); - //The token_1_columns and token_2_rows do not follow the documentation. - //The number of physical rows and columns is actually +1 of these values. - //Which is not explicitly documented. - nColumns++; - nRows++; - - int totalCount = nRows * nColumns; - Object[] arrayValues = ConstantValueParser.parse(in, totalCount); - - ArrayPtg result = new ArrayPtg(_reserved0, _reserved1, _reserved2, nColumns, nRows, arrayValues); - result.setClass(getPtgClass()); - return result; - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java deleted file mode 100644 index 96da29445..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java +++ /dev/null @@ -1,263 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * "Special Attributes" - * This seems to be a Misc Stuff and Junk record. One function it serves is - * in SUM functions (i.e. SUM(A1:A3) causes an area PTG then an ATTR with the SUM option set) - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class AttrPtg extends ControlPtg { - public final static byte sid = 0x19; - private final static int SIZE = 4; - private final byte _options; - private final short _data; - - /** only used for tAttrChoose: table of offsets to starts of args */ - private final int[] _jumpTable; - /** only used for tAttrChoose: offset to the tFuncVar for CHOOSE() */ - private final int _chooseFuncOffset; - - // flags 'volatile' and 'space', can be combined. - // OOO spec says other combinations are theoretically possible but not likely to occur. - private static final BitField semiVolatile = BitFieldFactory.getInstance(0x01); - private static final BitField optiIf = BitFieldFactory.getInstance(0x02); - private static final BitField optiChoose = BitFieldFactory.getInstance(0x04); - private static final BitField optiSkip = BitFieldFactory.getInstance(0x08); - private static final BitField optiSum = BitFieldFactory.getInstance(0x10); - private static final BitField baxcel = BitFieldFactory.getInstance(0x20); // 'assignment-style formula in a macro sheet' - private static final BitField space = BitFieldFactory.getInstance(0x40); - - public static final AttrPtg SUM = new AttrPtg(0x0010, 0, null, -1); - - public static final class SpaceType { - private SpaceType() { - // no instances of this class - } - - /** 00H = Spaces before the next token (not allowed before tParen token) */ - public static final int SPACE_BEFORE = 0x00; - /** 01H = Carriage returns before the next token (not allowed before tParen token) */ - public static final int CR_BEFORE = 0x01; - /** 02H = Spaces before opening parenthesis (only allowed before tParen token) */ - public static final int SPACE_BEFORE_OPEN_PAREN = 0x02; - /** 03H = Carriage returns before opening parenthesis (only allowed before tParen token) */ - public static final int CR_BEFORE_OPEN_PAREN = 0x03; - /** 04H = Spaces before closing parenthesis (only allowed before tParen, tFunc, and tFuncVar tokens) */ - public static final int SPACE_BEFORE_CLOSE_PAREN = 0x04; - /** 05H = Carriage returns before closing parenthesis (only allowed before tParen, tFunc, and tFuncVar tokens) */ - public static final int CR_BEFORE_CLOSE_PAREN = 0x05; - /** 06H = Spaces following the equality sign (only in macro sheets) */ - public static final int SPACE_AFTER_EQUALITY = 0x06; - } - - public AttrPtg(LittleEndianInput in) { - _options = in.readByte(); - _data = in.readShort(); - if (isOptimizedChoose()) { - int nCases = _data; - int[] jumpTable = new int[nCases]; - for (int i = 0; i < jumpTable.length; i++) { - jumpTable[i] = in.readUShort(); - } - _jumpTable = jumpTable; - _chooseFuncOffset = in.readUShort(); - } else { - _jumpTable = null; - _chooseFuncOffset = -1; - } - - } - private AttrPtg(int options, int data, int[] jt, int chooseFuncOffset) { - _options = (byte) options; - _data = (short) data; - _jumpTable = jt; - _chooseFuncOffset = chooseFuncOffset; - } - - /** - * @param type a constant from SpaceType - * @param count the number of space characters - */ - public static AttrPtg createSpace(int type, int count) { - int data = type & 0x00FF | (count << 8) & 0x00FFFF; - return new AttrPtg(space.set(0), data, null, -1); - } - - /** - * @param dist distance (in bytes) to start of either
        • false parameter
        • - *
        • tFuncVar(IF) token (when false parameter is not present)
        - */ - public static AttrPtg createIf(int dist) { - return new AttrPtg(optiIf.set(0), dist, null, -1); - } - - /** - * @param dist distance (in bytes) to position behind tFuncVar(IF) token (minus 1) - */ - public static AttrPtg createSkip(int dist) { - return new AttrPtg(optiSkip.set(0), dist, null, -1); - } - - public static AttrPtg getSumSingle() { - return new AttrPtg(optiSum.set(0), 0, null, -1); - } - - - public boolean isSemiVolatile() { - return semiVolatile.isSet(_options); - } - - public boolean isOptimizedIf() { - return optiIf.isSet(_options); - } - - public boolean isOptimizedChoose() { - return optiChoose.isSet(_options); - } - - public boolean isSum() { - return optiSum.isSet(_options); - } - public boolean isSkip() { - return optiSkip.isSet(_options); - } - - // lets hope no one uses this anymore - private boolean isBaxcel() { - return baxcel.isSet(_options); - } - - public boolean isSpace() { - return space.isSet(_options); - } - - public short getData() { - return _data; - } - public int[] getJumpTable() { - return _jumpTable.clone(); - } - public int getChooseFuncOffset() { - if (_jumpTable == null) { - throw new IllegalStateException("Not tAttrChoose"); - } - return _chooseFuncOffset; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - - if(isSemiVolatile()) { - sb.append("volatile "); - } - if(isSpace()) { - sb.append("space count=").append((_data >> 8) & 0x00FF); - sb.append(" type=").append(_data & 0x00FF).append(" "); - } - // the rest seem to be mutually exclusive - if(isOptimizedIf()) { - sb.append("if dist=").append(_data); - } else if(isOptimizedChoose()) { - sb.append("choose nCases=").append(_data); - } else if(isSkip()) { - sb.append("skip dist=").append(_data); - } else if(isSum()) { - sb.append("sum "); - } else if(isBaxcel()) { - sb.append("assign "); - } - sb.append("]"); - return sb.toString(); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeByte(_options); - out.writeShort(_data); - int[] jt = _jumpTable; - if (jt != null) { - for (int i = 0; i < jt.length; i++) { - out.writeShort(jt[i]); - } - out.writeShort(_chooseFuncOffset); - } - } - - public int getSize() { - if (_jumpTable != null) { - return SIZE + (_jumpTable.length + 1) * LittleEndian.SHORT_SIZE; - } - return SIZE; - } - - public String toFormulaString(String[] operands) { - if(space.isSet(_options)) { - return operands[ 0 ]; - } else if (optiIf.isSet(_options)) { - return toFormulaString() + "(" + operands[0] + ")"; - } else if (optiSkip.isSet(_options)) { - return toFormulaString() + operands[0]; //goto isn't a real formula element should not show up - } else { - return toFormulaString() + "(" + operands[0] + ")"; - } - } - - - public int getNumberOfOperands() { - return 1; - } - - public int getType() { - return -1; - } - - public String toFormulaString() { - if(semiVolatile.isSet(_options)) { - return "ATTR(semiVolatile)"; - } - if(optiIf.isSet(_options)) { - return "IF"; - } - if( optiChoose.isSet(_options)) { - return "CHOOSE"; - } - if(optiSkip.isSet(_options)) { - return ""; - } - if(optiSum.isSet(_options)) { - return "SUM"; - } - if(baxcel.isSet(_options)) { - return "ATTR(baxcel)"; - } - if(space.isSet(_options)) { - return ""; - } - return "UNKNOWN ATTRIBUTE"; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java deleted file mode 100644 index 28b561905..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Boolean (boolean) Stores a (java) boolean value in a formula. - * - * @author Paul Krause (pkrause at soundbite dot com) - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class BoolPtg extends ScalarConstantPtg { - public static final int SIZE = 2; - public static final byte sid = 0x1D; - - private static final BoolPtg FALSE = new BoolPtg(false); - private static final BoolPtg TRUE = new BoolPtg(true); - - private final boolean _value; - - private BoolPtg(boolean b) { - _value = b; - } - - public static BoolPtg valueOf(boolean b) { - return b ? TRUE : FALSE; - } - public static BoolPtg read(LittleEndianInput in) { - return valueOf(in.readByte() == 1); - } - - public boolean getValue() { - return _value; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeByte(_value ? 1 : 0); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return _value ? "TRUE" : "FALSE"; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java deleted file mode 100644 index eb11f8fc3..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class ConcatPtg extends ValueOperatorPtg { - public final static byte sid = 0x08; - - private final static String CONCAT = "&"; - - public static final ValueOperatorPtg instance = new ConcatPtg(); - - private ConcatPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append(CONCAT); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java deleted file mode 100644 index 6e819daab..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Common superclass for - * tExp - * tTbl - * tParen - * tNlr - * tAttr - * tSheet - * tEndSheet - */ -public abstract class ControlPtg extends Ptg { - - public boolean isBaseToken() { - return true; - } - public final byte getDefaultOperandClass() { - throw new IllegalStateException("Control tokens are not classified"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java deleted file mode 100644 index b1b58d6ea..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.LittleEndianOutput; - - -/** - * An XSSF only representation of a reference to a deleted area - */ -public final class Deleted3DPxg extends OperandPtg implements Pxg { - private int externalWorkbookNumber = -1; - private String sheetName; - - public Deleted3DPxg(int externalWorkbookNumber, String sheetName) { - this.externalWorkbookNumber = externalWorkbookNumber; - this.sheetName = sheetName; - } - public Deleted3DPxg(String sheetName) { - this(-1, sheetName); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - if (externalWorkbookNumber >= 0) { - sb.append(" ["); - sb.append("workbook=").append(getExternalWorkbookNumber()); - sb.append("] "); - } - sb.append("sheet=").append(getSheetName()); - sb.append(" ! "); - sb.append(FormulaError.REF.getString()); - sb.append("]"); - return sb.toString(); - } - - public int getExternalWorkbookNumber() { - return externalWorkbookNumber; - } - public String getSheetName() { - return sheetName; - } - - public void setSheetName(String sheetName) { - this.sheetName = sheetName; - } - - public String toFormulaString() { - StringBuffer sb = new StringBuffer(); - if (externalWorkbookNumber >= 0) { - sb.append('['); - sb.append(externalWorkbookNumber); - sb.append(']'); - } - if (sheetName != null) { - SheetNameFormatter.appendFormat(sb, sheetName); - } - sb.append('!'); - sb.append(FormulaError.REF.getString()); - return sb.toString(); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } - - public int getSize() { - return 1; - } - public void write(LittleEndianOutput out) { - throw new IllegalStateException("XSSF-only Ptg, should not be serialised"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java deleted file mode 100644 index 70dd6cb4f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Deleted Area 3D Ptg - 3D referecnce (Sheet + Area)

        - * Description: Defined a area in Extern Sheet.

        - * REFERENCE:

        - * @author Patrick Luby - * @version 1.0-pre - */ -public final class DeletedArea3DPtg extends OperandPtg implements WorkbookDependentFormula { - public final static byte sid = 0x3d; - private final int field_1_index_extern_sheet; - private final int unused1; - private final int unused2; - - public DeletedArea3DPtg(int externSheetIndex) { - field_1_index_extern_sheet = externSheetIndex; - unused1 = 0; - unused2 = 0; - } - - public DeletedArea3DPtg(LittleEndianInput in) { - field_1_index_extern_sheet = in.readUShort(); - unused1 = in.readInt(); - unused2 = in.readInt(); - } - public String toFormulaString(FormulaRenderingWorkbook book) { - return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, FormulaError.REF.getString()); - } - public String toFormulaString() { - throw new RuntimeException("3D references need a workbook to determine formula text"); - } - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } - public int getSize() { - return 11; - } - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_index_extern_sheet); - out.writeInt(unused1); - out.writeInt(unused2); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java deleted file mode 100644 index 6974defe4..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - - -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Title: Deleted Reference 3D Ptg

        - * Description: Defined a cell in extern sheet.

        - * @since 1.0-pre - */ -public final class DeletedRef3DPtg extends OperandPtg implements WorkbookDependentFormula { - public final static byte sid = 0x3c; - private final int field_1_index_extern_sheet; - private final int unused1; - - /** Creates new DeletedRef3DPtg */ - public DeletedRef3DPtg(LittleEndianInput in) { - field_1_index_extern_sheet = in.readUShort(); - unused1 = in.readInt(); - } - - public DeletedRef3DPtg(int externSheetIndex) { - field_1_index_extern_sheet = externSheetIndex; - unused1 = 0; - } - - public String toFormulaString(FormulaRenderingWorkbook book) { - return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, FormulaError.REF.getString()); - } - public String toFormulaString() { - throw new RuntimeException("3D references need a workbook to determine formula text"); - } - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } - public int getSize() { - return 7; - } - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_index_extern_sheet); - out.writeInt(unused1); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/DividePtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/DividePtg.java deleted file mode 100644 index 66e6913bc..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/DividePtg.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * This PTG implements the standard binomial divide "/" - * @author Andrew C. Oliver acoliver at apache dot org - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class DividePtg extends ValueOperatorPtg { - public final static byte sid = 0x06; - - public static final ValueOperatorPtg instance = new DividePtg(); - - private DividePtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append("/"); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java deleted file mode 100644 index 164ce981c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * - * @author andy - */ -public final class EqualPtg extends ValueOperatorPtg { - public final static byte sid = 0x0b; - - public static final ValueOperatorPtg instance = new EqualPtg(); - - private EqualPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - - buffer.append(operands[ 0 ]); - buffer.append("="); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java deleted file mode 100644 index 36c276f37..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -public final class ErrPtg extends ScalarConstantPtg { - - /** #NULL! - Intersection of two cell ranges is empty */ - public static final ErrPtg NULL_INTERSECTION = new ErrPtg(FormulaError.NULL.getCode()); - /** #DIV/0! - Division by zero */ - public static final ErrPtg DIV_ZERO = new ErrPtg(FormulaError.DIV0.getCode()); - /** #VALUE! - Wrong type of operand */ - public static final ErrPtg VALUE_INVALID = new ErrPtg(FormulaError.VALUE.getCode()); - /** #REF! - Illegal or deleted cell reference */ - public static final ErrPtg REF_INVALID = new ErrPtg(FormulaError.REF.getCode()); - /** #NAME? - Wrong function or range name */ - public static final ErrPtg NAME_INVALID = new ErrPtg(FormulaError.NAME.getCode()); - /** #NUM! - Value range overflow */ - public static final ErrPtg NUM_ERROR = new ErrPtg(FormulaError.NUM.getCode()); - /** #N/A - Argument or function not available */ - public static final ErrPtg N_A = new ErrPtg(FormulaError.NA.getCode()); - - - public static final short sid = 0x1c; - private static final int SIZE = 2; - private final int field_1_error_code; - - /** Creates new ErrPtg */ - - private ErrPtg(int errorCode) { - if(!FormulaError.isValidCode(errorCode)) { - throw new IllegalArgumentException("Invalid error code (" + errorCode + ")"); - } - field_1_error_code = errorCode; - } - - public static ErrPtg read(LittleEndianInput in) { - return valueOf(in.readByte()); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeByte(field_1_error_code); - } - - public String toFormulaString() { - return FormulaError.forInt(field_1_error_code).getString(); - } - - public int getSize() { - return SIZE; - } - - public int getErrorCode() { - return field_1_error_code; - } - - public static ErrPtg valueOf(int code) { - switch(FormulaError.forInt(code)) { - case DIV0: return DIV_ZERO; - case NA: return N_A; - case NAME: return NAME_INVALID; - case NULL: return NULL_INTERSECTION; - case NUM: return NUM_ERROR; - case REF: return REF_INVALID; - case VALUE: return VALUE_INVALID; - default: - throw new RuntimeException("Unexpected error code (" + code + ")"); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java deleted file mode 100644 index d128be995..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - * @author dmui (save existing implementation) - */ -public final class ExpPtg extends ControlPtg { - private final static int SIZE = 5; - public final static short sid = 0x1; - private final int field_1_first_row; - private final int field_2_first_col; - - public ExpPtg(LittleEndianInput in) { - field_1_first_row = in.readShort(); - field_2_first_col = in.readShort(); - } - - public ExpPtg(int firstRow, int firstCol) { - this.field_1_first_row = firstRow; - this.field_2_first_col = firstCol; - } - - @Override - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_first_row); - out.writeShort(field_2_first_col); - } - - @Override - public int getSize() { - return SIZE; - } - - public int getRow() { - return field_1_first_row; - } - - public int getColumn() { - return field_2_first_col; - } - - @Override - public String toFormulaString() { - throw new RuntimeException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't"); - } - - @Override - public String toString() { - StringBuffer buffer = new StringBuffer("[Array Formula or Shared Formula]\n"); - buffer.append("row = ").append(getRow()).append("\n"); - buffer.append("col = ").append(getColumn()).append("\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java deleted file mode 100644 index a61d1d575..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheetRange; -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.SheetNameFormatter; - -/** - * @author Josh Micich - */ -final class ExternSheetNameResolver { - private ExternSheetNameResolver() { - // no instances of this class - } - - public static String prependSheetName(FormulaRenderingWorkbook book, int field_1_index_extern_sheet, String cellRefText) { - ExternalSheet externalSheet = book.getExternalSheet(field_1_index_extern_sheet); - StringBuffer sb; - if (externalSheet != null) { - String wbName = externalSheet.getWorkbookName(); - String sheetName = externalSheet.getSheetName(); - if (wbName != null) { - sb = new StringBuffer(wbName.length() + sheetName.length() + cellRefText.length() + 4); - SheetNameFormatter.appendFormat(sb, wbName, sheetName); - } else { - sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4); - SheetNameFormatter.appendFormat(sb, sheetName); - } - if (externalSheet instanceof ExternalSheetRange) { - ExternalSheetRange r = (ExternalSheetRange)externalSheet; - if (! r.getFirstSheetName().equals(r.getLastSheetName())) { - sb.append(':'); - SheetNameFormatter.appendFormat(sb, r.getLastSheetName()); - } - } - } else { - String firstSheetName = book.getSheetFirstNameByExternSheet(field_1_index_extern_sheet); - String lastSheetName = book.getSheetLastNameByExternSheet(field_1_index_extern_sheet); - sb = new StringBuffer(firstSheetName.length() + cellRefText.length() + 4); - if (firstSheetName.length() < 1) { - // What excel does if sheet has been deleted - sb.append("#REF"); // note - '!' added just once below - } else { - SheetNameFormatter.appendFormat(sb, firstSheetName); - if (! firstSheetName.equals(lastSheetName)) { - sb.append(':'); - sb.append(lastSheetName); - } - } - } - sb.append('!'); - sb.append(cellRefText); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java deleted file mode 100644 index ecfccb67b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.function.FunctionMetadata; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author aviks - * @author Jason Height (jheight at chariot dot net dot au) - * @author Danny Mui (dmui at apache dot org) (Leftover handling) - */ -public final class FuncPtg extends AbstractFunctionPtg { - - public final static byte sid = 0x21; - public final static int SIZE = 3; - - public static FuncPtg create(LittleEndianInput in) { - return create(in.readUShort()); - } - - private FuncPtg(int funcIndex, FunctionMetadata fm) { - super(funcIndex, fm.getReturnClassCode(), fm.getParameterClassCodes(), fm.getMinParams()); // minParams same as max since these are not var-arg funcs - } - - public static FuncPtg create(int functionIndex) { - FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(functionIndex); - if(fm == null) { - throw new RuntimeException("Invalid built-in function index (" + functionIndex + ")"); - } - return new FuncPtg(functionIndex, fm); - } - - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(getFunctionIndex()); - } - - public int getSize() { - return SIZE; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java deleted file mode 100644 index 3392d04a7..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; -import org.apache.poi.ss.formula.function.FunctionMetadata; -import org.apache.poi.ss.formula.function.FunctionMetadataRegistry; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class FuncVarPtg extends AbstractFunctionPtg{ - - public final static byte sid = 0x22; - private final static int SIZE = 4; - - /** - * Single instance of this token for 'sum() taking a single argument' - */ - public static final OperationPtg SUM = FuncVarPtg.create("SUM", 1); - - private FuncVarPtg(int functionIndex, int returnClass, byte[] paramClasses, int numArgs) { - super(functionIndex, returnClass, paramClasses, numArgs); - } - - /**Creates new function pointer from a byte array - * usually called while reading an excel file. - */ - public static FuncVarPtg create(LittleEndianInput in) { - return create(in.readByte(), in.readShort()); - } - - /** - * Create a function ptg from a string tokenised by the parser - */ - public static FuncVarPtg create(String pName, int numArgs) { - return create(numArgs, lookupIndex(pName)); - } - - private static FuncVarPtg create(int numArgs, int functionIndex) { - FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(functionIndex); - if(fm == null) { - // Happens only as a result of a call to FormulaParser.parse(), with a non-built-in function name - return new FuncVarPtg(functionIndex, Ptg.CLASS_VALUE, new byte[] {Ptg.CLASS_VALUE}, numArgs); - } - return new FuncVarPtg(functionIndex, fm.getReturnClassCode(), fm.getParameterClassCodes(), numArgs); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeByte(getNumberOfOperands()); - out.writeShort(getFunctionIndex()); - } - - public int getSize() { - return SIZE; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java deleted file mode 100644 index eafbeba6f..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - - -/** - * PTG class to implement greater or equal to - * - * @author fred at stsci dot edu - */ -public final class GreaterEqualPtg extends ValueOperatorPtg { - public final static int SIZE = 1; - public final static byte sid = 0x0c; - - public static final ValueOperatorPtg instance = new GreaterEqualPtg(); - - private GreaterEqualPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - - buffer.append(">="); - buffer.append(operands[ 1 ]); - - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java deleted file mode 100644 index dabdab665..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - - -/** - * Greater than operator PTG ">" - * @author Cameron Riley (criley at ekmail.com) - */ -public final class GreaterThanPtg extends ValueOperatorPtg { - public final static byte sid = 0x0D; - private final static String GREATERTHAN = ">"; - - public static final ValueOperatorPtg instance = new GreaterThanPtg(); - - private GreaterThanPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - /** - * Get the number of operands for the Less than operator - * @return int the number of operands - */ - public int getNumberOfOperands() { - return 2; - } - - /** - * Implementation of method from OperationsPtg - * @param operands a String array of operands - * @return String the Formula as a String - */ - public String toFormulaString(String[] operands) - { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append(GREATERTHAN); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java deleted file mode 100644 index b91784edb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Integer (unsigned short integer) Stores an unsigned short value (java int) in - * a formula - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class IntPtg extends ScalarConstantPtg { - // 16 bit unsigned integer - private static final int MIN_VALUE = 0x0000; - private static final int MAX_VALUE = 0xFFFF; - - /** - * Excel represents integers 0..65535 with the tInt token. - * - * @return true if the specified value is within the range of values - * IntPtg can represent. - */ - public static boolean isInRange(int i) { - return i >= MIN_VALUE && i <= MAX_VALUE; - } - - public final static int SIZE = 3; - public final static byte sid = 0x1e; - private final int field_1_value; - - public IntPtg(LittleEndianInput in) { - this(in.readUShort()); - } - - public IntPtg(int value) { - if (!isInRange(value)) { - throw new IllegalArgumentException("value is out of range: " + value); - } - field_1_value = value; - } - - public int getValue() { - return field_1_value; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(getValue()); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return String.valueOf(getValue()); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java deleted file mode 100644 index ed2f327ba..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public final class IntersectionPtg extends OperationPtg { - public final static byte sid = 0x0f; - - public static final OperationPtg instance = new IntersectionPtg(); - - private IntersectionPtg() { - // enforce singleton - } - - public final boolean isBaseToken() { - return true; - } - - public int getSize() { - return 1; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - } - - public String toFormulaString() { - return " "; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[0]); - buffer.append(" "); - buffer.append(operands[1]); - return buffer.toString(); - } - - public int getNumberOfOperands() { - return 2; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java deleted file mode 100644 index ce70ae79d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java +++ /dev/null @@ -1,53 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - - - - -/** - * Ptg class to implement less than or equal - * - * @author fred at stsci dot edu - */ -public final class LessEqualPtg extends ValueOperatorPtg { - public final static byte sid = 0x0a; - - public static final ValueOperatorPtg instance = new LessEqualPtg(); - - private LessEqualPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - buffer.append( operands[0] ); - buffer.append("<="); - buffer.append( operands[1] ); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java deleted file mode 100644 index 51455c520..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Less than operator PTG "<". The SID is taken from the - * Openoffice.orgs Documentation of the Excel File Format, - * Table 3.5.7 - * @author Cameron Riley (criley at ekmail.com) - */ -public final class LessThanPtg extends ValueOperatorPtg { - /** the sid for the less than operator as hex */ - public final static byte sid = 0x09; - - /** identifier for LESS THAN char */ - private final static String LESSTHAN = "<"; - - public static final ValueOperatorPtg instance = new LessThanPtg(); - - private LessThanPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - /** - * Get the number of operands for the Less than operator - * @return int the number of operands - */ - public int getNumberOfOperands() { - return 2; - } - - /** - * Implementation of method from OperationsPtg - * @param operands a String array of operands - * @return String the Formula as a String - */ - public String toFormulaString(String[] operands) - { - StringBuffer buffer = new StringBuffer(); - buffer.append(operands[ 0 ]); - buffer.append(LESSTHAN); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java deleted file mode 100644 index 6c4568e66..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public final class MemAreaPtg extends OperandPtg { - public final static short sid = 0x26; - private final static int SIZE = 7; - private final int field_1_reserved; - private final int field_2_subex_len; - - /** Creates new MemAreaPtg */ - - public MemAreaPtg(int subexLen) { - field_1_reserved = 0; - field_2_subex_len = subexLen; - } - - public MemAreaPtg(LittleEndianInput in) { - field_1_reserved = in.readInt(); - field_2_subex_len = in.readShort(); - } - - public int getLenRefSubexpression() { - return field_2_subex_len; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeInt(field_1_reserved); - out.writeShort(field_2_subex_len); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return ""; // TODO: Not sure how to format this. -- DN - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } - - @Override - public final String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" [len="); - sb.append(field_2_subex_len); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java deleted file mode 100644 index 44f541da9..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public final class MemErrPtg extends OperandPtg { - public final static short sid = 0x27; - private final static int SIZE = 7; - private int field_1_reserved; - private short field_2_subex_len; - - public MemErrPtg(LittleEndianInput in) { - field_1_reserved = in.readInt(); - field_2_subex_len = in.readShort(); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeInt(field_1_reserved); - out.writeShort(field_2_subex_len); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return "ERR#"; - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java deleted file mode 100644 index 1837382f1..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class MemFuncPtg extends OperandPtg { - - public final static byte sid = 0x29; - private final int field_1_len_ref_subexpression; - - /** - * Creates new function pointer from a byte array usually called while - * reading an excel file. - */ - public MemFuncPtg(LittleEndianInput in) { - this(in.readUShort()); - } - - public MemFuncPtg(int subExprLen) { - field_1_len_ref_subexpression = subExprLen; - } - - public int getSize() { - return 3; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_len_ref_subexpression); - } - - public String toFormulaString() { - return ""; - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } - - public int getNumberOfOperands() { - return field_1_len_ref_subexpression; - } - - public int getLenRefSubexpression() { - return field_1_len_ref_subexpression; - } - @Override - public final String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" [len="); - sb.append(field_1_len_ref_subexpression); - sb.append("]"); - return sb.toString(); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java deleted file mode 100644 index 84e441287..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Missing Function Arguments - * - * Avik Sengupta <avik at apache.org> - * - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class MissingArgPtg extends ScalarConstantPtg { - - private final static int SIZE = 1; - public final static byte sid = 0x16; - - public static final Ptg instance = new MissingArgPtg(); - - private MissingArgPtg() { - // enforce singleton - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return " "; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java deleted file mode 100644 index ce251c82b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Implements the standard mathmatical multiplication - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class MultiplyPtg extends ValueOperatorPtg { - public final static byte sid = 0x05; - - public static final ValueOperatorPtg instance = new MultiplyPtg(); - - private MultiplyPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append("*"); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/NamePtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/NamePtg.java deleted file mode 100644 index 8218cbe9e..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/NamePtg.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class NamePtg extends OperandPtg implements WorkbookDependentFormula { - public final static short sid = 0x23; - private final static int SIZE = 5; - /** one-based index to defined name record */ - private int field_1_label_index; - private short field_2_zero; // reserved must be 0 - - /** - * @param nameIndex zero-based index to name within workbook - */ - public NamePtg(int nameIndex) { - field_1_label_index = 1 + nameIndex; // convert to 1-based - } - - /** Creates new NamePtg */ - - public NamePtg(LittleEndianInput in) { - field_1_label_index = in.readShort(); - field_2_zero = in.readShort(); - } - - /** - * @return zero based index to a defined name record in the LinkTable - */ - public int getIndex() { - return field_1_label_index - 1; // convert to zero based - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_label_index); - out.writeShort(field_2_zero); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString(FormulaRenderingWorkbook book) { - return book.getNameText(this); - } - - public String toFormulaString() { - throw new RuntimeException("3D references need a workbook to determine formula text"); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java deleted file mode 100644 index de88d1b8c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * A Name, be that a Named Range or a Function / User Defined - * Function, addressed in the HSSF External Sheet style. - * - *

        This is HSSF only, as it matches the HSSF file format way of - * referring to the sheet by an extern index. The XSSF equivalent - * is {@link NameXPxg} - */ -public final class NameXPtg extends OperandPtg implements WorkbookDependentFormula { - public final static short sid = 0x39; - private final static int SIZE = 7; - - /** index to REF entry in externsheet record */ - private final int _sheetRefIndex; - /** index to defined name or externname table(1 based) */ - private final int _nameNumber; - /** reserved must be 0 */ - private final int _reserved; - - private NameXPtg(int sheetRefIndex, int nameNumber, int reserved) { - _sheetRefIndex = sheetRefIndex; - _nameNumber = nameNumber; - _reserved = reserved; - } - - /** - * @param sheetRefIndex index to REF entry in externsheet record - * @param nameIndex index to defined name or externname table - */ - public NameXPtg(int sheetRefIndex, int nameIndex) { - this(sheetRefIndex, nameIndex + 1, 0); - } - - public NameXPtg(LittleEndianInput in) { - this(in.readUShort(), in.readUShort(), in.readUShort()); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(_sheetRefIndex); - out.writeShort(_nameNumber); - out.writeShort(_reserved); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString(FormulaRenderingWorkbook book) { - // -1 to convert definedNameIndex from 1-based to zero-based - return book.resolveNameXText(this); - } - public String toFormulaString() { - throw new RuntimeException("3D references need a workbook to determine formula text"); - } - - public String toString(){ - String retValue = "NameXPtg:[sheetRefIndex:" + _sheetRefIndex + - " , nameNumber:" + _nameNumber + "]" ; - return retValue; - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } - - public int getSheetRefIndex() { - return _sheetRefIndex; - } - public int getNameIndex() { - return _nameNumber - 1; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java deleted file mode 100644 index 8969ad47b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.util.LittleEndianOutput; - -/** - * A Name, be that a Named Range or a Function / User Defined - * Function, addressed in the HSSF External Sheet style. - * - *

        This is XSSF only, as it stores the sheet / book references - * in String form. The HSSF equivalent using indexes is {@link NameXPtg}

        - */ -public final class NameXPxg extends OperandPtg implements Pxg { - private int externalWorkbookNumber = -1; - private String sheetName; - private String nameName; - - public NameXPxg(int externalWorkbookNumber, String sheetName, String nameName) { - this.externalWorkbookNumber = externalWorkbookNumber; - this.sheetName = sheetName; - this.nameName = nameName; - } - public NameXPxg(String sheetName, String nameName) { - this(-1, sheetName, nameName); - } - public NameXPxg(String nameName) { - this(-1, null, nameName); - } - - public String toString(){ - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - if (externalWorkbookNumber >= 0) { - sb.append(" ["); - sb.append("workbook=").append(getExternalWorkbookNumber()); - sb.append("] "); - } - sb.append("sheet=").append(getSheetName()); - sb.append(" ! "); - sb.append("name="); - sb.append(nameName); - sb.append("]"); - return sb.toString(); - } - - public int getExternalWorkbookNumber() { - return externalWorkbookNumber; - } - public String getSheetName() { - return sheetName; - } - public String getNameName() { - return nameName; - } - - public void setSheetName(String sheetName) { - this.sheetName = sheetName; - } - - public String toFormulaString() { - StringBuffer sb = new StringBuffer(); - boolean needsExclamation = false; - if (externalWorkbookNumber >= 0) { - sb.append('['); - sb.append(externalWorkbookNumber); - sb.append(']'); - needsExclamation = true; - } - if (sheetName != null) { - SheetNameFormatter.appendFormat(sb, sheetName); - needsExclamation = true; - } - if (needsExclamation) { - sb.append('!'); - } - sb.append(nameName); - return sb.toString(); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } - - public int getSize() { - return 1; - } - public void write(LittleEndianOutput out) { - throw new IllegalStateException("XSSF-only Ptg, should not be serialised"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java deleted file mode 100644 index 2c91b9cd8..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Ptg class to implement not equal - * - * @author fred at stsci dot edu - */ -public final class NotEqualPtg extends ValueOperatorPtg { - public final static byte sid = 0x0e; - - public static final ValueOperatorPtg instance = new NotEqualPtg(); - - private NotEqualPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append( operands[0] ); - - buffer.append("<>"); - buffer.append( operands[1] ); - - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java deleted file mode 100644 index 6cec23604..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.util.NumberToTextConverter; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Number Stores a floating point value in a formula value stored in a 8 byte - * field using IEEE notation - * - * @author Avik Sengupta - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class NumberPtg extends ScalarConstantPtg { - public final static int SIZE = 9; - public final static byte sid = 0x1f; - private final double field_1_value; - - public NumberPtg(LittleEndianInput in) { - this(in.readDouble()); - } - - /** - * Create a NumberPtg from a string representation of the number Number - * format is not checked, it is expected to be validated in the parser that - * calls this method. - * - * @param value String representation of a floating point number - */ - public NumberPtg(String value) { - this(Double.parseDouble(value)); - } - - public NumberPtg(double value) { - field_1_value = value; - } - - public double getValue() { - return field_1_value; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeDouble(getValue()); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return NumberToTextConverter.toText(field_1_value); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java deleted file mode 100644 index 0c36a8443..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * @author Josh Micich - */ -public abstract class OperandPtg extends Ptg implements Cloneable { - - /** - * All Operand {@link Ptg}s are classified ('relative', 'value', 'array') - */ - public final boolean isBaseToken() { - return false; - } - public final OperandPtg copy() { - try { - return (OperandPtg) clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java deleted file mode 100644 index 089d3c736..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * defines a Ptg that is an operation instead of an operand - * @author andy - */ -public abstract class OperationPtg extends Ptg { - public final static int TYPE_UNARY = 0; - public final static int TYPE_BINARY = 1; - public final static int TYPE_FUNCTION = 2; - - /** - * returns a string representation of the operations - * the length of the input array should equal the number returned by - * @see #getNumberOfOperands - * - */ - public abstract String toFormulaString(String[] operands); - - /** - * The number of operands expected by the operations - */ - public abstract int getNumberOfOperands(); - - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java deleted file mode 100644 index 1ea30abe2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * While formula tokens are stored in RPN order and thus do not need parenthesis - * for precedence reasons, Parenthesis tokens ARE written to ensure that user - * entered parenthesis are displayed as-is on reading back - * - * Avik Sengupta <lists@aviksengupta.com> Andrew C. Oliver (acoliver at - * apache dot org) - * - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class ParenthesisPtg extends ControlPtg { - - private final static int SIZE = 1; - public final static byte sid = 0x15; - - public static final ControlPtg instance = new ParenthesisPtg(); - - private ParenthesisPtg() { - // enforce singleton - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - } - - public int getSize() { - return SIZE; - } - - public String toFormulaString() { - return "()"; - } - - public String toFormulaString(String[] operands) { - return "(" + operands[0] + ")"; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java deleted file mode 100644 index 12eabcaa6..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Percent PTG. - * - * @author Daniel Noll (daniel at nuix.com.au) - */ -public final class PercentPtg extends ValueOperatorPtg { - public final static int SIZE = 1; - public final static byte sid = 0x14; - - private final static String PERCENT = "%"; - - public static final ValueOperatorPtg instance = new PercentPtg(); - - private PercentPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 1; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append(PERCENT); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java deleted file mode 100644 index 3f240f40c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class PowerPtg extends ValueOperatorPtg { - public final static byte sid = 0x07; - - public static final ValueOperatorPtg instance = new PowerPtg(); - - private PowerPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; // TODO - 2 seems wrong (Jun 2008). Maybe this method is not relevant - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - - buffer.append(operands[ 0 ]); - buffer.append("^"); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java deleted file mode 100644 index bb6fb64fb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java +++ /dev/null @@ -1,317 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Ptg represents a syntactic token in a formula. 'PTG' is an acronym for - * 'parse thing'. Originally, the name referred to the single - * byte identifier at the start of the token, but in POI, Ptg encapsulates - * the whole formula token (initial byte + value data). - *

        - * - * Ptgs are logically arranged in a tree representing the structure of the - * parsed formula. However, in BIFF files Ptgs are written/read in - * Reverse-Polish Notation order. The RPN ordering also simplifies formula - * evaluation logic, so POI mostly accesses Ptgs in the same way. - * - * @author andy - * @author avik - * @author Jason Height (jheight at chariot dot net dot au) - */ -public abstract class Ptg { - public static final Ptg[] EMPTY_PTG_ARRAY = { }; - - /** - * Reads size bytes of the input stream, to create an array of Ptgs. - * Extra data (beyond size) may be read if and ArrayPtgs are present. - */ - public static Ptg[] readTokens(int size, LittleEndianInput in) { - List temp = new ArrayList(4 + size / 2); - int pos = 0; - boolean hasArrayPtgs = false; - while (pos < size) { - Ptg ptg = Ptg.createPtg(in); - if (ptg instanceof ArrayPtg.Initial) { - hasArrayPtgs = true; - } - pos += ptg.getSize(); - temp.add(ptg); - } - if(pos != size) { - throw new RuntimeException("Ptg array size mismatch"); - } - if (hasArrayPtgs) { - Ptg[] result = toPtgArray(temp); - for (int i=0;i= 0x60) { - retval.setClass(CLASS_ARRAY); - } else if (id >= 0x40) { - retval.setClass(CLASS_VALUE); - } else { - retval.setClass(CLASS_REF); - } - return retval; - } - - private static Ptg createClassifiedPtg(byte id, LittleEndianInput in) { - - int baseId = id & 0x1F | 0x20; - - switch (baseId) { - case ArrayPtg.sid: return new ArrayPtg.Initial(in);//0x20, 0x40, 0x60 - case FuncPtg.sid: return FuncPtg.create(in); // 0x21, 0x41, 0x61 - case FuncVarPtg.sid: return FuncVarPtg.create(in);//0x22, 0x42, 0x62 - case NamePtg.sid: return new NamePtg(in); // 0x23, 0x43, 0x63 - case RefPtg.sid: return new RefPtg(in); // 0x24, 0x44, 0x64 - case AreaPtg.sid: return new AreaPtg(in); // 0x25, 0x45, 0x65 - case MemAreaPtg.sid: return new MemAreaPtg(in); // 0x26, 0x46, 0x66 - case MemErrPtg.sid: return new MemErrPtg(in); // 0x27, 0x47, 0x67 - case MemFuncPtg.sid: return new MemFuncPtg(in); // 0x29, 0x49, 0x69 - case RefErrorPtg.sid: return new RefErrorPtg(in); // 0x2a, 0x4a, 0x6a - case AreaErrPtg.sid: return new AreaErrPtg(in); // 0x2b, 0x4b, 0x6b - case RefNPtg.sid: return new RefNPtg(in); // 0x2c, 0x4c, 0x6c - case AreaNPtg.sid: return new AreaNPtg(in); // 0x2d, 0x4d, 0x6d - - case NameXPtg.sid: return new NameXPtg(in); // 0x39, 0x49, 0x79 - case Ref3DPtg.sid: return new Ref3DPtg(in); // 0x3a, 0x5a, 0x7a - case Area3DPtg.sid: return new Area3DPtg(in); // 0x3b, 0x5b, 0x7b - case DeletedRef3DPtg.sid: return new DeletedRef3DPtg(in); // 0x3c, 0x5c, 0x7c - case DeletedArea3DPtg.sid: return new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d - } - throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+ - Integer.toHexString(id) + " (" + ( int ) id + ")"); - } - - private static Ptg createBasePtg(byte id, LittleEndianInput in) { - switch(id) { - case 0x00: return new UnknownPtg(id); // TODO - not a real Ptg - case ExpPtg.sid: return new ExpPtg(in); // 0x01 - case TblPtg.sid: return new TblPtg(in); // 0x02 - case AddPtg.sid: return AddPtg.instance; // 0x03 - case SubtractPtg.sid: return SubtractPtg.instance; // 0x04 - case MultiplyPtg.sid: return MultiplyPtg.instance; // 0x05 - case DividePtg.sid: return DividePtg.instance; // 0x06 - case PowerPtg.sid: return PowerPtg.instance; // 0x07 - case ConcatPtg.sid: return ConcatPtg.instance; // 0x08 - case LessThanPtg.sid: return LessThanPtg.instance; // 0x09 - case LessEqualPtg.sid: return LessEqualPtg.instance; // 0x0a - case EqualPtg.sid: return EqualPtg.instance; // 0x0b - case GreaterEqualPtg.sid: return GreaterEqualPtg.instance;// 0x0c - case GreaterThanPtg.sid: return GreaterThanPtg.instance; // 0x0d - case NotEqualPtg.sid: return NotEqualPtg.instance; // 0x0e - case IntersectionPtg.sid: return IntersectionPtg.instance;// 0x0f - case UnionPtg.sid: return UnionPtg.instance; // 0x10 - case RangePtg.sid: return RangePtg.instance; // 0x11 - case UnaryPlusPtg.sid: return UnaryPlusPtg.instance; // 0x12 - case UnaryMinusPtg.sid: return UnaryMinusPtg.instance; // 0x13 - case PercentPtg.sid: return PercentPtg.instance; // 0x14 - case ParenthesisPtg.sid: return ParenthesisPtg.instance; // 0x15 - case MissingArgPtg.sid: return MissingArgPtg.instance; // 0x16 - - case StringPtg.sid: return new StringPtg(in); // 0x17 - case AttrPtg.sid: return new AttrPtg(in); // 0x19 - case ErrPtg.sid: return ErrPtg.read(in); // 0x1c - case BoolPtg.sid: return BoolPtg.read(in); // 0x1d - case IntPtg.sid: return new IntPtg(in); // 0x1e - case NumberPtg.sid: return new NumberPtg(in); // 0x1f - } - throw new RuntimeException("Unexpected base token id (" + id + ")"); - } - - private static Ptg[] toPtgArray(List l) { - if (l.isEmpty()) { - return EMPTY_PTG_ARRAY; - } - Ptg[] result = new Ptg[l.size()]; - l.toArray(result); - return result; - } - /** - * This method will return the same result as {@link #getEncodedSizeWithoutArrayData(Ptg[])} - * if there are no array tokens present. - * @return the full size taken to encode the specified Ptgs - */ - public static int getEncodedSize(Ptg[] ptgs) { - int result = 0; - for (Ptg ptg : ptgs) { - result += ptg.getSize(); - } - return result; - } - /** - * Used to calculate value that should be encoded at the start of the encoded Ptg token array; - * @return the size of the encoded Ptg tokens not including any trailing array data. - */ - public static int getEncodedSizeWithoutArrayData(Ptg[] ptgs) { - int result = 0; - for (Ptg ptg : ptgs) { - if (ptg instanceof ArrayPtg) { - result += ArrayPtg.PLAIN_TOKEN_SIZE; - } else { - result += ptg.getSize(); - } - } - return result; - } - /** - * Writes the ptgs to the data buffer, starting at the specified offset. - * - *
        - * The 2 byte encode length field is not written by this method. - * @return number of bytes written - */ - public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) { - LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(array, offset); - - List arrayPtgs = null; - - for (Ptg ptg : ptgs) { - ptg.write(out); - if (ptg instanceof ArrayPtg) { - if (arrayPtgs == null) { - arrayPtgs = new ArrayList(5); - } - arrayPtgs.add(ptg); - } - } - if (arrayPtgs != null) { - for (Ptg arrayPtg : arrayPtgs) { - ArrayPtg p = (ArrayPtg) arrayPtg; - p.writeTokenValueBytes(out); - } - } - return out.getWriteIndex() - offset; - } - - /** - * @return the encoded length of this Ptg, including the initial Ptg type identifier byte. - */ - public abstract int getSize(); - - public abstract void write(LittleEndianOutput out); - - /** - * return a string representation of this token alone - */ - public abstract String toFormulaString(); - - /** Overridden toString method to ensure object hash is not printed. - * This helps get rid of gratuitous diffs when comparing two dumps - * Subclasses may output more relevant information by overriding this method - **/ - @Override - public String toString(){ - return this.getClass().toString(); - } - - public static final byte CLASS_REF = 0x00; - public static final byte CLASS_VALUE = 0x20; - public static final byte CLASS_ARRAY = 0x40; - - private byte ptgClass = CLASS_REF; //base ptg - - public final void setClass(byte thePtgClass) { - if (isBaseToken()) { - throw new RuntimeException("setClass should not be called on a base token"); - } - ptgClass = thePtgClass; - } - - /** - * @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg - */ - public final byte getPtgClass() { - return ptgClass; - } - - /** - * Debug / diagnostic method to get this token's 'operand class' type. - * @return 'R' for 'reference', 'V' for 'value', 'A' for 'array' and '.' for base tokens - */ - public final char getRVAType() { - if (isBaseToken()) { - return '.'; - } - switch (ptgClass) { - case Ptg.CLASS_REF: return 'R'; - case Ptg.CLASS_VALUE: return 'V'; - case Ptg.CLASS_ARRAY: return 'A'; - } - throw new RuntimeException("Unknown operand class (" + ptgClass + ")"); - } - - public abstract byte getDefaultOperandClass(); - - /** - * @return false if this token is classified as 'reference', 'value', or 'array' - */ - public abstract boolean isBaseToken(); - - public static boolean doesFormulaReferToDeletedCell(Ptg[] ptgs) { - for (Ptg ptg : ptgs) { - if (isDeletedCellRef(ptg)) { - return true; - } - } - return false; - } - - private static boolean isDeletedCellRef(Ptg ptg) { - if (ptg == ErrPtg.REF_INVALID) { - return true; - } - if (ptg instanceof DeletedArea3DPtg) { - return true; - } - if (ptg instanceof DeletedRef3DPtg) { - return true; - } - if (ptg instanceof AreaErrPtg) { - return true; - } - if (ptg instanceof RefErrorPtg) { - return true; - } - return false; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Pxg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Pxg.java deleted file mode 100644 index fa1c4ff07..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Pxg.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * An XSSF only special kind of Ptg, which stores the sheet / book - * reference in string form. - */ -public interface Pxg { - public int getExternalWorkbookNumber(); - public String getSheetName(); - public void setSheetName(String sheetName); - public String toFormulaString(); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Pxg3D.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Pxg3D.java deleted file mode 100644 index 49083fe15..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Pxg3D.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * An XSSF only special kind of Ptg, which stores a range of - * sheet / book references in string form. - */ -public interface Pxg3D extends Pxg { - public String getLastSheetName(); - public void setLastSheetName(String sheetName); -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java deleted file mode 100644 index 1ab4cf1b8..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - - -/** - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public final class RangePtg extends OperationPtg { - public final static int SIZE = 1; - public final static byte sid = 0x11; - - public static final OperationPtg instance = new RangePtg(); - - private RangePtg() { - // enforce singleton - } - - public final boolean isBaseToken() { - return true; - } - - public int getSize() - { - return SIZE; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - } - - public String toFormulaString() - { - return ":"; - } - - - /** implementation of method from OperationsPtg*/ - public String toFormulaString(String[] operands) - { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append(":"); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } - - public int getNumberOfOperands() - { - return 2; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java deleted file mode 100644 index 06af02a52..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author Josh Micich - */ -abstract class Ref2DPtgBase extends RefPtgBase { - private final static int SIZE = 5; - - - protected Ref2DPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) { - setRow(row); - setColumn(column); - setRowRelative(isRowRelative); - setColRelative(isColumnRelative); - } - - protected Ref2DPtgBase(LittleEndianInput in) { - readCoordinates(in); - } - - protected Ref2DPtgBase(CellReference cr) { - super(cr); - } - - @Override - public void write(LittleEndianOutput out) { - out.writeByte(getSid() + getPtgClass()); - writeCoordinates(out); - } - - @Override - public final String toFormulaString() { - return formatReferenceAsString(); - } - - protected abstract byte getSid(); - - @Override - public final int getSize() { - return SIZE; - } - - @Override - public final String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - sb.append(formatReferenceAsString()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java deleted file mode 100644 index 1366d2d35..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.ExternSheetReferenceToken; -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - *

        Title: Reference 3D Ptg

        - *

        Description: Defined a cell in extern sheet.

        - *

        REFERENCE:

        - * - *

        This is HSSF only, as it matches the HSSF file format way of - * referring to the sheet by an extern index. The XSSF equivalent - * is {@link Ref3DPxg} - */ -public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken { - public final static byte sid = 0x3a; - - private final static int SIZE = 7; // 6 + 1 for Ptg - private int field_1_index_extern_sheet; - - - public Ref3DPtg(LittleEndianInput in) { - field_1_index_extern_sheet = in.readShort(); - readCoordinates(in); - } - - public Ref3DPtg(String cellref, int externIdx ) { - this(new CellReference(cellref), externIdx); - } - - public Ref3DPtg(CellReference c, int externIdx) { - super(c); - setExternSheetIndex(externIdx); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - sb.append("sheetIx=").append(getExternSheetIndex()); - sb.append(" ! "); - sb.append(formatReferenceAsString()); - sb.append("]"); - return sb.toString(); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(getExternSheetIndex()); - writeCoordinates(out); - } - - public int getSize() { - return SIZE; - } - - public int getExternSheetIndex() { - return field_1_index_extern_sheet; - } - - public void setExternSheetIndex(int index) { - field_1_index_extern_sheet = index; - } - public String format2DRefAsString() { - return formatReferenceAsString(); - } - /** - * @return text representation of this cell reference that can be used in text - * formulas. The sheet name will get properly delimited if required. - */ - public String toFormulaString(FormulaRenderingWorkbook book) { - return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString()); - } - public String toFormulaString() { - throw new RuntimeException("3D references need a workbook to determine formula text"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java deleted file mode 100644 index 3b78c5a4b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.formula.SheetIdentifier; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.formula.SheetRangeIdentifier; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.LittleEndianOutput; - -/** - *

        Title: XSSF 3D Reference

        - *

        Description: Defines a cell in an external or different sheet.

        - *

        REFERENCE:

        - * - *

        This is XSSF only, as it stores the sheet / book references - * in String form. The HSSF equivalent using indexes is {@link Ref3DPtg}

        - */ -public final class Ref3DPxg extends RefPtgBase implements Pxg3D { - private int externalWorkbookNumber = -1; - private String firstSheetName; - private String lastSheetName; - - public Ref3DPxg(int externalWorkbookNumber, SheetIdentifier sheetName, String cellref) { - this(externalWorkbookNumber, sheetName, new CellReference(cellref)); - } - public Ref3DPxg(int externalWorkbookNumber, SheetIdentifier sheetName, CellReference c) { - super(c); - this.externalWorkbookNumber = externalWorkbookNumber; - - this.firstSheetName = sheetName.getSheetIdentifier().getName(); - if (sheetName instanceof SheetRangeIdentifier) { - this.lastSheetName = ((SheetRangeIdentifier)sheetName).getLastSheetIdentifier().getName(); - } else { - this.lastSheetName = null; - } - } - - public Ref3DPxg(SheetIdentifier sheetName, String cellref) { - this(sheetName, new CellReference(cellref)); - } - public Ref3DPxg(SheetIdentifier sheetName, CellReference c) { - this(-1, sheetName, c); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append(" ["); - if (externalWorkbookNumber >= 0) { - sb.append(" ["); - sb.append("workbook=").append(getExternalWorkbookNumber()); - sb.append("] "); - } - sb.append("sheet=").append(firstSheetName); - if (lastSheetName != null) { - sb.append(" : "); - sb.append("sheet=").append(lastSheetName); - } - sb.append(" ! "); - sb.append(formatReferenceAsString()); - sb.append("]"); - return sb.toString(); - } - - public int getExternalWorkbookNumber() { - return externalWorkbookNumber; - } - public String getSheetName() { - return firstSheetName; - } - public String getLastSheetName() { - return lastSheetName; - } - - public void setSheetName(String sheetName) { - this.firstSheetName = sheetName; - } - public void setLastSheetName(String sheetName) { - this.lastSheetName = sheetName; - } - - public String format2DRefAsString() { - return formatReferenceAsString(); - } - - public String toFormulaString() { - StringBuffer sb = new StringBuffer(); - if (externalWorkbookNumber >= 0) { - sb.append('['); - sb.append(externalWorkbookNumber); - sb.append(']'); - } - if (firstSheetName != null) { - SheetNameFormatter.appendFormat(sb, firstSheetName); - } - if (lastSheetName != null) { - sb.append(':'); - SheetNameFormatter.appendFormat(sb, lastSheetName); - } - sb.append('!'); - sb.append(formatReferenceAsString()); - return sb.toString(); - } - - public int getSize() { - return 1; - } - public void write(LittleEndianOutput out) { - throw new IllegalStateException("XSSF-only Ptg, should not be serialised"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java deleted file mode 100644 index e450644b8..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * RefError - handles deleted cell reference - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class RefErrorPtg extends OperandPtg { - - private final static int SIZE = 5; - public final static byte sid = 0x2A; - private int field_1_reserved; - - public RefErrorPtg() { - field_1_reserved = 0; - } - public RefErrorPtg(LittleEndianInput in) { - field_1_reserved = in.readInt(); - } - - public String toString() { - return getClass().getName(); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeInt(field_1_reserved); - } - - public int getSize() - { - return SIZE; - } - - public String toFormulaString() { - return FormulaError.REF.getString(); - } - - public byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java deleted file mode 100644 index 715836f8d..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; - -/** - * RefNPtg - * @author Jason Height (jheight at apache dot com) - */ -public final class RefNPtg extends Ref2DPtgBase { - public final static byte sid = 0x2C; - - public RefNPtg(LittleEndianInput in) { - super(in); - } - - protected byte getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java deleted file mode 100644 index 297c0e7d8..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.LittleEndianInput; - -/** - * ReferencePtg - handles references (such as A1, A2, IA4) - * @author Andrew C. Oliver (acoliver@apache.org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class RefPtg extends Ref2DPtgBase { - public final static byte sid = 0x24; - - /** - * Takes in a String representation of a cell reference and fills out the - * numeric fields. - */ - public RefPtg(String cellref) { - super(new CellReference(cellref)); - } - - public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) { - super(row, column, isRowRelative, isColumnRelative); - } - - public RefPtg(LittleEndianInput in) { - super(in); - } - - public RefPtg(CellReference cr) { - super(cr); - } - - protected byte getSid() { - return sid; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java deleted file mode 100644 index 5ff9a7a3c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ReferencePtgBase - handles references (such as A1, A2, IA4) - * - * @author Andrew C. Oliver (acoliver@apache.org) - * @author Jason Height (jheight at chariot dot net dot au) - */ -public abstract class RefPtgBase extends OperandPtg { - - /** The row index - zero based unsigned 16 bit value */ - private int field_1_row; - /** - * Field 2 - lower 8 bits is the zero based unsigned byte column index - bit - * 16 - isRowRelative - bit 15 - isColumnRelative - */ - private int field_2_col; - private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000); - private static final BitField colRelative = BitFieldFactory.getInstance(0x4000); - - /** - * YK: subclasses of RefPtgBase are used by the FormulaParser and FormulaEvaluator accross HSSF and XSSF. - * The bit mask should accomodate the maximum number of avaiable columns, i.e. 0x3FFF. - * - * @see org.apache.poi.ss.SpreadsheetVersion - */ - private static final BitField column = BitFieldFactory.getInstance(0x3FFF); - - protected RefPtgBase() { - // Required for clone methods - } - - protected RefPtgBase(CellReference c) { - setRow(c.getRow()); - setColumn(c.getCol()); - setColRelative(!c.isColAbsolute()); - setRowRelative(!c.isRowAbsolute()); - } - - protected final void readCoordinates(LittleEndianInput in) { - field_1_row = in.readUShort(); - field_2_col = in.readUShort(); - } - - protected final void writeCoordinates(LittleEndianOutput out) { - out.writeShort(field_1_row); - out.writeShort(field_2_col); - } - - public final void setRow(int rowIndex) { - field_1_row = rowIndex; - } - - /** - * @return the row number as an int - */ - public final int getRow() { - return field_1_row; - } - - public final boolean isRowRelative() { - return rowRelative.isSet(field_2_col); - } - - public final void setRowRelative(boolean rel) { - field_2_col = rowRelative.setBoolean(field_2_col, rel); - } - - public final boolean isColRelative() { - return colRelative.isSet(field_2_col); - } - - public final void setColRelative(boolean rel) { - field_2_col = colRelative.setBoolean(field_2_col, rel); - } - - public final void setColumn(int col) { - field_2_col = column.setValue(field_2_col, col); - } - - public final int getColumn() { - return column.getValue(field_2_col); - } - - protected final String formatReferenceAsString() { - // Only make cell references as needed. Memory is an issue - CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(), !isColRelative()); - return cr.formatAsString(); - } - - @Override - public final byte getDefaultOperandClass() { - return Ptg.CLASS_REF; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java deleted file mode 100644 index f916c3872..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - - -/** - * Common superclass of all {@link Ptg}s that represent simple constant values. - * - * @author Josh Micich - */ -public abstract class ScalarConstantPtg extends Ptg { - public final boolean isBaseToken() { - return true; - } - - public final byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } - - public final String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(toFormulaString()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java deleted file mode 100644 index 836ca0fea..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * String Stores a String value in a formula value stored in the format - * <length 2 bytes>char[] - * - * @author Werner Froidevaux - * @author Jason Height (jheight at chariot dot net dot au) - * @author Bernard Chesnoy - */ -public final class StringPtg extends ScalarConstantPtg { - public final static byte sid = 0x17; - /** the character (") used in formulas to delimit string literals */ - private static final char FORMULA_DELIMITER = '"'; - - private final boolean _is16bitUnicode; - /** - * NOTE: OO doc says 16bit length, but BiffViewer says 8 Book says something - * totally different, so don't look there! - */ - private final String field_3_string; - - /** Create a StringPtg from a stream */ - public StringPtg(LittleEndianInput in) { - int nChars = in.readUByte(); // Note - nChars is 8-bit - _is16bitUnicode = (in.readByte() & 0x01) != 0; - if (_is16bitUnicode) { - field_3_string = StringUtil.readUnicodeLE(in, nChars); - } else { - field_3_string = StringUtil.readCompressedUnicode(in, nChars); - } - } - - /** - * Create a StringPtg from a string representation of the number Number - * format is not checked, it is expected to be validated in the parser that - * calls this method. - * - * @param value : - * String representation of a floating point number - */ - public StringPtg(String value) { - if (value.length() > 255) { - throw new IllegalArgumentException( - "String literals in formulas can't be bigger than 255 characters ASCII"); - } - _is16bitUnicode = StringUtil.hasMultibyte(value); - field_3_string = value; - } - - public String getValue() { - return field_3_string; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeByte(field_3_string.length()); // Note - nChars is 8-bit - out.writeByte(_is16bitUnicode ? 0x01 : 0x00); - if (_is16bitUnicode) { - StringUtil.putUnicodeLE(field_3_string, out); - } else { - StringUtil.putCompressedUnicode(field_3_string, out); - } - } - - public int getSize() { - return 3 + field_3_string.length() * (_is16bitUnicode ? 2 : 1); - } - - public String toFormulaString() { - String value = field_3_string; - int len = value.length(); - StringBuffer sb = new StringBuffer(len + 4); - sb.append(FORMULA_DELIMITER); - - for (int i = 0; i < len; i++) { - char c = value.charAt(i); - if (c == FORMULA_DELIMITER) { - sb.append(FORMULA_DELIMITER); - } - sb.append(c); - } - - sb.append(FORMULA_DELIMITER); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java deleted file mode 100644 index f06e60496..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public final class SubtractPtg extends ValueOperatorPtg { - public final static byte sid = 0x04; - - public static final ValueOperatorPtg instance = new SubtractPtg(); - - private SubtractPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 2; - } - - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append("-"); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java deleted file mode 100644 index 5ab5558ff..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * This ptg indicates a data table. - * It only occurs in a FORMULA record, never in an - * ARRAY or NAME record. When ptgTbl occurs in a - * formula, it is the only token in the formula. - * - * This indicates that the cell containing the - * formula is an interior cell in a data table; - * the table description is found in a TABLE - * record. Rows and columns which contain input - * values to be substituted in the table do - * not contain ptgTbl. - * See page 811 of the june 08 binary docs. - */ -public final class TblPtg extends ControlPtg { - private final static int SIZE = 5; - public final static short sid = 0x02; - /** The row number of the upper left corner */ - private final int field_1_first_row; - /** The column number of the upper left corner */ - private final int field_2_first_col; - - public TblPtg(LittleEndianInput in) { - field_1_first_row = in.readUShort(); - field_2_first_col = in.readUShort(); - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - out.writeShort(field_1_first_row); - out.writeShort(field_2_first_col); - } - - public int getSize() { - return SIZE; - } - - public int getRow() { - return field_1_first_row; - } - - public int getColumn() { - return field_2_first_col; - } - - public String toFormulaString() - { - // table(....)[][] - throw new RuntimeException("Table and Arrays are not yet supported"); - } - - public String toString() { - StringBuffer buffer = new StringBuffer("[Data Table - Parent cell is an interior cell in a data table]\n"); - buffer.append("top left row = ").append(getRow()).append("\n"); - buffer.append("top left col = ").append(getColumn()).append("\n"); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java deleted file mode 100644 index 9079150eb..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Unary Plus operator - * does not have any effect on the operand - * @author Avik Sengupta - */ -public final class UnaryMinusPtg extends ValueOperatorPtg { - public final static byte sid = 0x13; - - private final static String MINUS = "-"; - - public static final ValueOperatorPtg instance = new UnaryMinusPtg(); - - private UnaryMinusPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 1; - } - - /** implementation of method from OperationsPtg*/ - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - buffer.append(MINUS); - buffer.append(operands[ 0]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java deleted file mode 100644 index 1596c6735..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -/** - * Unary Plus operator - * does not have any effect on the operand - * @author Avik Sengupta - */ -public final class UnaryPlusPtg extends ValueOperatorPtg { - public final static byte sid = 0x12; - - private final static String ADD = "+"; - - public static final ValueOperatorPtg instance = new UnaryPlusPtg(); - - private UnaryPlusPtg() { - // enforce singleton - } - - protected byte getSid() { - return sid; - } - - public int getNumberOfOperands() { - return 1; - } - - /** implementation of method from OperationsPtg*/ - public String toFormulaString(String[] operands) { - StringBuffer buffer = new StringBuffer(); - buffer.append(ADD); - buffer.append(operands[ 0]); - return buffer.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java deleted file mode 100644 index fcc2ae5a2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - - -/** - * @author Glen Stampoultzis (glens at apache.org) - */ -public final class UnionPtg extends OperationPtg { - public final static byte sid = 0x10; - - public static final OperationPtg instance = new UnionPtg(); - - private UnionPtg() { - // enforce singleton - } - - public final boolean isBaseToken() { - return true; - } - - public int getSize() - { - return 1; - } - - public void write(LittleEndianOutput out) { - out.writeByte(sid + getPtgClass()); - } - - public String toFormulaString() - { - return ","; - } - - - /** implementation of method from OperationsPtg*/ - public String toFormulaString(String[] operands) - { - StringBuffer buffer = new StringBuffer(); - - buffer.append(operands[ 0 ]); - buffer.append(","); - buffer.append(operands[ 1 ]); - return buffer.toString(); - } - - public int getNumberOfOperands() - { - return 2; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java deleted file mode 100644 index 8eac21208..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ -public class UnknownPtg extends Ptg { - private short size = 1; - private final int _sid; - - public UnknownPtg(int sid) { - _sid = sid; - } - - public boolean isBaseToken() { - return true; - } - public void write(LittleEndianOutput out) { - out.writeByte(_sid); - } - - public int getSize() { - return size; - } - - public String toFormulaString() { - return "UNKNOWN"; - } - public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java b/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java deleted file mode 100644 index 1194adfd2..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.ptg; - -import org.apache.poi.util.LittleEndianOutput; - -/** - * Common superclass of all value operators. Subclasses include all unary and - * binary operators except for the reference operators (IntersectionPtg, - * RangePtg, UnionPtg) - * - * @author Josh Micich - */ -public abstract class ValueOperatorPtg extends OperationPtg { - - /** - * All Operator Ptgs are base tokens (i.e. are not RVA classified) - */ - public final boolean isBaseToken() { - return true; - } - - public final byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } - - public void write(LittleEndianOutput out) { - out.writeByte(getSid()); - } - - protected abstract byte getSid(); - - public final int getSize() { - return 1; - } - - public final String toFormulaString() { - // TODO - prune this method out of the hierarchy - throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs"); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/ptg/package.html b/trunk/src/java/org/apache/poi/ss/formula/ptg/package.html deleted file mode 100644 index b0e899c1b..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/ptg/package.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - -formula package contains binary PTG structures used in Formulas - -

        Related Documentation

        - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - -@see org.apache.poi.hssf.record -@see org.apache.poi.hssf.record.FormulaRecord - - diff --git a/trunk/src/java/org/apache/poi/ss/formula/udf/AggregatingUDFFinder.java b/trunk/src/java/org/apache/poi/ss/formula/udf/AggregatingUDFFinder.java deleted file mode 100644 index ece80345c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/udf/AggregatingUDFFinder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.udf; - -import org.apache.poi.ss.formula.atp.AnalysisToolPak; -import org.apache.poi.ss.formula.functions.FreeRefFunction; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -/** - * Collects add-in libraries and VB macro functions together into one UDF finder - * - * @author PUdalau - */ -public class AggregatingUDFFinder implements UDFFinder { - - /** - * Default UDFFinder implementation - */ - public static final UDFFinder DEFAULT = new AggregatingUDFFinder(AnalysisToolPak.instance); - - private final Collection _usedToolPacks; - - public AggregatingUDFFinder(UDFFinder ... usedToolPacks) { - _usedToolPacks = new ArrayList(usedToolPacks.length); - _usedToolPacks.addAll(Arrays.asList(usedToolPacks)); - } - - /** - * Returns executor by specified name. Returns null if - * function isn't contained by any registered tool pack. - * - * @param name Name of function. - * @return Function executor. null if not found - */ - @Override - public FreeRefFunction findFunction(String name) { - FreeRefFunction evaluatorForFunction; - for (UDFFinder pack : _usedToolPacks) { - evaluatorForFunction = pack.findFunction(name); - if (evaluatorForFunction != null) { - return evaluatorForFunction; - } - } - return null; - } - - /** - * Add a new toolpack - * - * @param toolPack the UDF toolpack to add - */ - public void add(UDFFinder toolPack){ - _usedToolPacks.add(toolPack); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/udf/DefaultUDFFinder.java b/trunk/src/java/org/apache/poi/ss/formula/udf/DefaultUDFFinder.java deleted file mode 100644 index 382820b1e..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/udf/DefaultUDFFinder.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.udf; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.ss.formula.functions.FreeRefFunction; - -/** - * Default UDF finder - for adding your own user defined functions. - * - * @author PUdalau - */ -public final class DefaultUDFFinder implements UDFFinder { - private final Map _functionsByName; - - public DefaultUDFFinder(String[] functionNames, FreeRefFunction[] functionImpls) { - int nFuncs = functionNames.length; - if (functionImpls.length != nFuncs) { - throw new IllegalArgumentException( - "Mismatch in number of function names and implementations"); - } - HashMap m = new HashMap(nFuncs * 3 / 2); - for (int i = 0; i < functionImpls.length; i++) { - m.put(functionNames[i].toUpperCase(Locale.ROOT), functionImpls[i]); - } - _functionsByName = m; - } - - @Override - public FreeRefFunction findFunction(String name) { - return _functionsByName.get(name.toUpperCase(Locale.ROOT)); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/udf/IndexedUDFFinder.java b/trunk/src/java/org/apache/poi/ss/formula/udf/IndexedUDFFinder.java deleted file mode 100644 index 27ceaef3c..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/udf/IndexedUDFFinder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.formula.udf; - -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.util.Internal; - -import java.util.HashMap; - -/** - * A UDFFinder that can retrieve functions both by name and by fake index. - * - * @author Yegor Kozlov - */ -@Internal -public class IndexedUDFFinder extends AggregatingUDFFinder { - private final HashMap _funcMap; - - public IndexedUDFFinder(UDFFinder... usedToolPacks) { - super(usedToolPacks); - _funcMap = new HashMap(); - } - - @Override - public FreeRefFunction findFunction(String name) { - FreeRefFunction func = super.findFunction(name); - if (func != null) { - int idx = getFunctionIndex(name); - _funcMap.put(idx, name); - } - return func; - } - - public String getFunctionName(int idx) { - return _funcMap.get(idx); - } - - public int getFunctionIndex(String name) { - return name.hashCode(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/formula/udf/UDFFinder.java b/trunk/src/java/org/apache/poi/ss/formula/udf/UDFFinder.java deleted file mode 100644 index a434756e9..000000000 --- a/trunk/src/java/org/apache/poi/ss/formula/udf/UDFFinder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.udf; - -import org.apache.poi.ss.formula.atp.AnalysisToolPak; -import org.apache.poi.ss.formula.functions.FreeRefFunction; - -/** - * Common interface for "Add-in" libraries and user defined function libraries. - */ -public interface UDFFinder { - // FIXME: Findbugs error: IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION - /** - * Default UDFFinder implementation - * - * @deprecated use AggregatingUDFFinder.DEFAULT instead, deprecated in POI 3.15, - * scheduled for removable in POI 3.17 - */ - @Deprecated - public static final UDFFinder DEFAULT = new AggregatingUDFFinder(AnalysisToolPak.instance); - - /** - * Returns executor by specified name. Returns null if the function name is unknown. - * - * @param name Name of function. - * @return Function executor. - */ - FreeRefFunction findFunction(String name); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/AutoFilter.java b/trunk/src/java/org/apache/poi/ss/usermodel/AutoFilter.java deleted file mode 100644 index 82c7a439d..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/AutoFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * Represents autofiltering for the specified worksheet. - * - *

        - * Filtering data is a quick and easy way to find and work with a subset of data in a range of cells or table. - * For example, you can filter to see only the values that you specify, filter to see the top or bottom values, - * or filter to quickly see duplicate values. - *

        - * - * TODO YK: For now (Aug 2010) POI only supports setting a basic autofilter on a range of cells. - * In future, when we support more auto-filter functions like custom criteria, sort, etc. we will add - * corresponding methods to this interface. - */ -public interface AutoFilter { - /** - * Apply a custom filter - * - *

        - * A custom AutoFilter specifies an operator and a value. - * There can be at most two customFilters specified, and in that case the parent element - * specifies whether the two conditions are joined by 'and' or 'or'. For any cells whose - * values do not meet the specified criteria, the corresponding rows shall be hidden from - * view when the filter is applied. - *

        - * - *

        - * Example: - *

        -     *  AutoFilter filter = sheet.setAutoFilter(CellRangeAddress.valueOf("A1:F200"));
        -     *  filter.applyFilter(0, FilterOperator.GreaterThanOrEqual", "0.2");
        -     *  filter.applyFilter(1, FilterOperator.LessThanOrEqual"", "0.5");
        -     * 
        - *

        - * - * @param columnIndex 0-based column index - * @param operator the operator to apply - * @param criteria top or bottom value used in the filter criteria. - * - * TODO YK: think how to combine AutoFilter with with DataValidationConstraint, they are really close relatives - * void applyFilter(int columnIndex, FilterOperator operator, String criteria); - */ - - - /** - * Apply a filter against a list of values - * - *

        - * Example: - *

        -     *  AutoFilter filter = sheet.setAutoFilter(CellRangeAddress.valueOf("A1:F200"));
        -     *  filter.applyFilter(0, "apache", "poi", "java", "api");
        -     * 
        - *

        - * - * @param columnIndex 0-based column index - * @param values the filter values - * - * void applyFilter(int columnIndex, String ... values); - */ - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/BorderExtent.java b/trunk/src/java/org/apache/poi/ss/usermodel/BorderExtent.java deleted file mode 100644 index 7115883b3..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/BorderExtent.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating which borders to draw in a Property Template - */ -public enum BorderExtent { - /** - * No properties defined. This can be used to remove existing properties - * from the PropertyTemplate. - */ - NONE, - - /** - * All borders, that is top, bottom, left and right, including interior - * borders for the range. Does not include diagonals which are different - * and not implemented here. - */ - ALL, - - /** - * All inside borders. This is top, bottom, left, and right borders, but - * restricted to the interior borders for the range. For a range of one - * cell, this will produce no borders. - */ - INSIDE, - - /** - * All outside borders. That is top, bottom, left and right borders that - * bound the range only. - */ - OUTSIDE, - - /** - * This is just the top border for the range. No interior borders will - * be produced. - */ - TOP, - - /** - * This is just the bottom border for the range. No interior borders - * will be produced. - */ - BOTTOM, - - /** - * This is just the left border for the range, no interior borders will - * be produced. - */ - LEFT, - - /** - * This is just the right border for the range, no interior borders will - * be produced. - */ - RIGHT, - - /** - * This is all horizontal borders for the range, including interior and - * outside borders. - */ - HORIZONTAL, - - /** - * This is just the interior horizontal borders for the range. - */ - INSIDE_HORIZONTAL, - - /** - * This is just the outside horizontal borders for the range. - */ - OUTSIDE_HORIZONTAL, - - /** - * This is all vertical borders for the range, including interior and - * outside borders. - */ - VERTICAL, - - /** - * This is just the interior vertical borders for the range. - */ - INSIDE_VERTICAL, - - /** - * This is just the outside vertical borders for the range. - */ - OUTSIDE_VERTICAL -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java deleted file mode 100644 index 949cc3d00..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.util.Removal; - -/** - * High level representation for Border Formatting component - * of Conditional Formatting settings - */ -public interface BorderFormatting { - /** No border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#NONE} - */ - @Removal(version="3.17") - short BORDER_NONE = 0x0; - - /** Thin border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#THIN} - */ - @Removal(version="3.17") - short BORDER_THIN = 0x1; - - /** Medium border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM} - */ - @Removal(version="3.17") - short BORDER_MEDIUM = 0x2; - - /** dash border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASHED} - */ - @Removal(version="3.17") - short BORDER_DASHED = 0x3; - - /** dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOTTED} - */ - @Removal(version="3.17") - short BORDER_DOTTED = 0x4; - - /** Thick border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#THICK} - */ - @Removal(version="3.17") - short BORDER_THICK = 0x5; - - /** double-line border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOUBLE} - */ - @Removal(version="3.17") - short BORDER_DOUBLE = 0x6; - - /** hair-line border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#HAIR} - */ - @Removal(version="3.17") - short BORDER_HAIR = 0x7; - - /** Medium dashed border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASHED} - */ - @Removal(version="3.17") - short BORDER_MEDIUM_DASHED = 0x8; - - /** dash-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT} - */ - @Removal(version="3.17") - short BORDER_DASH_DOT = 0x9; - - /** medium dash-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT} - */ - @Removal(version="3.17") - short BORDER_MEDIUM_DASH_DOT = 0xA; - - /** dash-dot-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT_DOT} - */ - @Removal(version="3.17") - short BORDER_DASH_DOT_DOT = 0xB; - - /** medium dash-dot-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT_DOT} - */ - @Removal(version="3.17") - short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; - - /** slanted dash-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#SLANTED_DASH_DOT} - */ - @Removal(version="3.17") - short BORDER_SLANTED_DASH_DOT = 0xD; - - /** - * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()}. - * This method will return an BorderStyle enum in the future. - */ - short getBorderBottom(); - /** @since POI 3.15 */ - BorderStyle getBorderBottomEnum(); - - /** - * @deprecated POI 3.15. Use {@link #getBorderDiagonalEnum()}. - * This method will return an BorderStyle enum in the future. - */ - short getBorderDiagonal(); - /** @since POI 3.15 */ - BorderStyle getBorderDiagonalEnum(); - - /** - * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()}. - * This method will return an BorderStyle enum in the future. - */ - short getBorderLeft(); - /** @since POI 3.15 */ - BorderStyle getBorderLeftEnum(); - - /** - * @deprecated POI 3.15. Use {@link #getBorderRightEnum()}. - * This method will return an BorderStyle enum in the future. - */ - short getBorderRight(); - /** @since POI 3.15 */ - BorderStyle getBorderRightEnum(); - - /** - * @deprecated POI 3.15. Use {@link #getBorderTopEnum()}. - * This method will return an BorderStyle enum in the future. - */ - short getBorderTop(); - /** @since POI 3.15 */ - BorderStyle getBorderTopEnum(); - - - short getBottomBorderColor(); - Color getBottomBorderColorColor(); - - short getDiagonalBorderColor(); - Color getDiagonalBorderColorColor(); - - short getLeftBorderColor(); - Color getLeftBorderColorColor(); - - short getRightBorderColor(); - Color getRightBorderColorColor(); - - short getTopBorderColor(); - Color getTopBorderColorColor(); - - /** - * Set bottom border. - * - * @param border MUST be a BORDER_* constant - * @deprecated 3.15 beta 2. Use {@link BorderFormatting#setBorderBottom(BorderStyle)} - */ - void setBorderBottom(short border); - - /** - * Set bottom border. - * - * @param border - */ - void setBorderBottom(BorderStyle border); - - /** - * Set diagonal border. - * - * @param border MUST be a BORDER_* constant - * @deprecated 3.15 beta 2. Use {@link BorderFormatting#setBorderDiagonal(BorderStyle)} - */ - void setBorderDiagonal(short border); - - /** - * Set diagonal border. - * - * @param border - */ - void setBorderDiagonal(BorderStyle border); - - /** - * Set left border. - * - * @param border MUST be a BORDER_* constant - * @deprecated 3.15 beta 2. Use {@link BorderFormatting#setBorderLeft(BorderStyle)} - */ - void setBorderLeft(short border); - - /** - * Set left border. - * - * @param border - */ - void setBorderLeft(BorderStyle border); - - /** - * Set right border. - * - * @param border MUST be a BORDER_* constant - * @deprecated 3.15 beta 2. Use {@link BorderFormatting#setBorderRight(BorderStyle)} - */ - void setBorderRight(short border); - - /** - * Set right border. - * - * @param border - */ - void setBorderRight(BorderStyle border); - - /** - * Set top border. - * - * @param border MUST be a BORDER_* constant - * @deprecated 3.15 beta 2. Use {@link BorderFormatting#setBorderTop(BorderStyle)} - */ - void setBorderTop(short border); - - /** - * Set top border. - * - * @param border - */ - void setBorderTop(BorderStyle border); - - void setBottomBorderColor(short color); - void setBottomBorderColor(Color color); - - void setDiagonalBorderColor(short color); - void setDiagonalBorderColor(Color color); - - void setLeftBorderColor(short color); - void setLeftBorderColor(Color color); - - void setRightBorderColor(short color); - void setRightBorderColor(Color color); - - void setTopBorderColor(short color); - void setTopBorderColor(Color color); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/BorderStyle.java b/trunk/src/java/org/apache/poi/ss/usermodel/BorderStyle.java deleted file mode 100644 index 9fd5d15cb..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/BorderStyle.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating the line style of a border in a cell, - * i.e., whether it is bordered dash dot, dash dot dot, dashed, dotted, double, hair, medium, - * medium dash dot, medium dash dot dot, medium dashed, none, slant dash dot, thick or thin. - */ - public enum BorderStyle { - - /** - * No border (default) - */ - NONE(0x0), - - /** - * Thin border - */ - THIN(0x1), - - /** - * Medium border - */ - MEDIUM(0x2), - - /** - * dash border - */ - DASHED(0x3), - - /** - * dot border - */ - DOTTED(0x4), - - /** - * Thick border - */ - THICK(0x5), - - /** - * double-line border - */ - DOUBLE(0x6), - - /** - * hair-line border - */ - HAIR(0x7), - - /** - * Medium dashed border - */ - MEDIUM_DASHED(0x8), - - /** - * dash-dot border - */ - DASH_DOT(0x9), - - /** - * medium dash-dot border - */ - MEDIUM_DASH_DOT(0xA), - - /** - * dash-dot-dot border - */ - DASH_DOT_DOT(0xB), - - /** - * medium dash-dot-dot border - */ - MEDIUM_DASH_DOT_DOT(0xC), - - /** - * slanted dash-dot border - */ - SLANTED_DASH_DOT(0xD); - - private final short code; - - private BorderStyle(int code) { - this.code = (short)code; - } - - public short getCode() { - return code; - } - - private static final BorderStyle[] _table = new BorderStyle[0xD + 1]; - static { - for (BorderStyle c : values()) { - _table[c.getCode()] = c; - } - } - - public static BorderStyle valueOf(short code) { - return _table[code]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java b/trunk/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java deleted file mode 100644 index 8d1188178..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * Utility to identify built-in formats. The following is a list of the formats as - * returned by this class.

        - *

        - * 0, "General"
        - * 1, "0"
        - * 2, "0.00"
        - * 3, "#,##0"
        - * 4, "#,##0.00"
        - * 5, "$#,##0_);($#,##0)"
        - * 6, "$#,##0_);[Red]($#,##0)"
        - * 7, "$#,##0.00);($#,##0.00)"
        - * 8, "$#,##0.00_);[Red]($#,##0.00)"
        - * 9, "0%"
        - * 0xa, "0.00%"
        - * 0xb, "0.00E+00"
        - * 0xc, "# ?/?"
        - * 0xd, "# ??/??"
        - * 0xe, "m/d/yy"
        - * 0xf, "d-mmm-yy"
        - * 0x10, "d-mmm"
        - * 0x11, "mmm-yy"
        - * 0x12, "h:mm AM/PM"
        - * 0x13, "h:mm:ss AM/PM"
        - * 0x14, "h:mm"
        - * 0x15, "h:mm:ss"
        - * 0x16, "m/d/yy h:mm"
        - *

        - * // 0x17 - 0x24 reserved for international and undocumented - * 0x25, "#,##0_);(#,##0)"
        - * 0x26, "#,##0_);[Red](#,##0)"
        - * 0x27, "#,##0.00_);(#,##0.00)"
        - * 0x28, "#,##0.00_);[Red](#,##0.00)"
        - * 0x29, "_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)"
        - * 0x2a, "_($* #,##0_);_($* (#,##0);_($* \"-\"_);_(@_)"
        - * 0x2b, "_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)"
        - * 0x2c, "_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(@_)"
        - * 0x2d, "mm:ss"
        - * 0x2e, "[h]:mm:ss"
        - * 0x2f, "mm:ss.0"
        - * 0x30, "##0.0E+0"
        - * 0x31, "@" - This is text format.
        - * 0x31 "text" - Alias for "@"
        - *

        - */ -public final class BuiltinFormats { - /** - * The first user-defined number format starts at 164. - */ - public static final int FIRST_USER_DEFINED_FORMAT_INDEX = 164; - - private final static String[] _formats = { - "General", - "0", - "0.00", - "#,##0", - "#,##0.00", - "\"$\"#,##0_);(\"$\"#,##0)", - "\"$\"#,##0_);[Red](\"$\"#,##0)", - "\"$\"#,##0.00_);(\"$\"#,##0.00)", - "\"$\"#,##0.00_);[Red](\"$\"#,##0.00)", - "0%", - "0.00%", - "0.00E+00", - "# ?/?", - "# ??/??", - "m/d/yy", - "d-mmm-yy", - "d-mmm", - "mmm-yy", - "h:mm AM/PM", - "h:mm:ss AM/PM", - "h:mm", - "h:mm:ss", - "m/d/yy h:mm", - - // 0x17 - 0x24 reserved for international and undocumented - // TODO - one junit relies on these values which seems incorrect - "reserved-0x17", - "reserved-0x18", - "reserved-0x19", - "reserved-0x1A", - "reserved-0x1B", - "reserved-0x1C", - "reserved-0x1D", - "reserved-0x1E", - "reserved-0x1F", - "reserved-0x20", - "reserved-0x21", - "reserved-0x22", - "reserved-0x23", - "reserved-0x24", - - "#,##0_);(#,##0)", - "#,##0_);[Red](#,##0)", - "#,##0.00_);(#,##0.00)", - "#,##0.00_);[Red](#,##0.00)", - "_(\"$\"* #,##0_);_(\"$\"* (#,##0);_(\"$\"* \"-\"_);_(@_)", - "_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)", - "_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)", - "_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)", - "mm:ss", - "[h]:mm:ss", - "mm:ss.0", - "##0.0E+0", - "@" - }; - - /** - * @return array of built-in data formats - */ - public static String[] getAll() { - return _formats.clone(); - } - - /** - * Get the format string that matches the given format index - * - * @param index of a built in format - * @return string represented at index of format or null if there is not a built-in format at that index - */ - public static String getBuiltinFormat(int index) { - if (index < 0 || index >=_formats.length) { - return null; - } - return _formats[index]; - } - - /** - * Get the format index that matches the given format string.
        - * Automatically converts "text" to excel's format string to represent text. - * - * @param pFmt string matching a built-in format - * @return index of format or -1 if undefined. - */ - public static int getBuiltinFormat(String pFmt) { - String fmt = "TEXT".equalsIgnoreCase(pFmt) ? "@" : pFmt; - - int i = -1; - for (String f : _formats) { - i++; - if (f.equals(fmt)) { - return i; - } - } - - return -1; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java b/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java deleted file mode 100644 index a6f4f6387..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Cell.java +++ /dev/null @@ -1,464 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.ss.formula.FormulaParseException; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; - -/** - * High level representation of a cell in a row of a spreadsheet. - *

        - * Cells can be numeric, formula-based or string-based (text). The cell type - * specifies this. String cells cannot conatin numbers and numeric cells cannot - * contain strings (at least according to our model). Client apps should do the - * conversions themselves. Formula cells have the formula string, as well as - * the formula result, which can be numeric or string. - *

        - *

        - * Cells should have their number (0 based) before being added to a row. - *

        - */ -public interface Cell { - - /** - * Numeric Cell type (0) - * @see #setCellType(int) - * @see #getCellType() - * @deprecated POI 3.15 beta 3. Use {@link CellType#NUMERIC} instead. - */ - @Removal(version="4.0") - int CELL_TYPE_NUMERIC = 0; //CellType.NUMERIC.getCode(); - - /** - * String Cell type (1) - * @see #setCellType(int) - * @see #getCellType() - * @deprecated POI 3.15 beta 3. Use {@link CellType#STRING} instead. - */ - @Removal(version="4.0") - int CELL_TYPE_STRING = 1; //CellType.STRING.getCode(); - - /** - * Formula Cell type (2) - * @see #setCellType(int) - * @see #getCellType() - * @deprecated POI 3.15 beta 3. Use {@link CellType#FORMULA} instead. - */ - @Removal(version="4.0") - int CELL_TYPE_FORMULA = 2; //CellType.FORMULA.getCode(); - - /** - * Blank Cell type (3) - * @see #setCellType(int) - * @see #getCellType() - * @deprecated POI 3.15 beta 3. Use {@link CellType#BLANK} instead. - */ - @Removal(version="4.0") - int CELL_TYPE_BLANK = 3; //CellType.BLANK.getCode(); - - /** - * Boolean Cell type (4) - * @see #setCellType(int) - * @see #getCellType() - * @deprecated POI 3.15 beta 3. Use {@link CellType#BOOLEAN} instead. - */ - @Removal(version="4.0") - int CELL_TYPE_BOOLEAN = 4; //CellType.BOOLEAN.getCode(); - - /** - * Error Cell type (5) - * @see #setCellType(int) - * @see #getCellType() - * @deprecated POI 3.15 beta 3. Use {@link CellType#ERROR} instead. - */ - @Removal(version="4.0") - int CELL_TYPE_ERROR = 5; //CellType.ERROR.getCode(); - - /** - * Returns column index of this cell - * - * @return zero-based column index of a column in a sheet. - */ - int getColumnIndex(); - - /** - * Returns row index of a row in the sheet that contains this cell - * - * @return zero-based row index of a row in the sheet that contains this cell - */ - int getRowIndex(); - - /** - * Returns the sheet this cell belongs to - * - * @return the sheet this cell belongs to - */ - Sheet getSheet(); - - /** - * Returns the Row this cell belongs to - * - * @return the Row that owns this cell - */ - Row getRow(); - - /** - * Set the cells type (numeric, formula or string). - *

        If the cell currently contains a value, the value will - * be converted to match the new type, if possible. Formatting - * is generally lost in the process however.

        - *

        If what you want to do is get a String value for your - * numeric cell, stop!. This is not the way to do it. - * Instead, for fetching the string value of a numeric or boolean - * or date cell, use {@link DataFormatter} instead.

        - * - * @throws IllegalArgumentException if the specified cell type is invalid - * @throws IllegalStateException if the current value cannot be converted to the new type - * @see CellType#NUMERIC - * @see CellType#STRING - * @see CellType#FORMULA - * @see CellType#BLANK - * @see CellType#BOOLEAN - * @see CellType#ERROR - * @deprecated POI 3.15 beta 3. Use {@link #setCellType(CellType)} instead. - */ - @Removal(version="4.0") - void setCellType(int cellType); - /** - * Set the cells type (numeric, formula or string). - *

        If the cell currently contains a value, the value will - * be converted to match the new type, if possible. Formatting - * is generally lost in the process however.

        - *

        If what you want to do is get a String value for your - * numeric cell, stop!. This is not the way to do it. - * Instead, for fetching the string value of a numeric or boolean - * or date cell, use {@link DataFormatter} instead.

        - * - * @throws IllegalArgumentException if the specified cell type is invalid - * @throws IllegalStateException if the current value cannot be converted to the new type - */ - void setCellType(CellType cellType); - - /** - * Return the cell type. - * - * Will return {@link CellType} in version 4.0 of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return the cell type - * @deprecated POI 3.15. Will return a {@link CellType} enum in the future. - */ - int getCellType(); - - /** - * Return the cell type. - * - * @return the cell type - * @since POI 3.15 beta 3 - * Will be renamed to getCellType() when we make the CellType enum transition in POI 4.0. See bug 59791. - */ - @Removal(version="4.2") - CellType getCellTypeEnum(); - - /** - * Only valid for formula cells - * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - int getCachedFormulaResultType(); - - /** - * Only valid for formula cells - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @since POI 3.15 beta 3 - * Will be renamed to getCachedFormulaResultType() when we make the CellType enum transition in POI 4.0. See bug 59791. - */ - CellType getCachedFormulaResultTypeEnum(); - - /** - * Set a numeric value for the cell - * - * @param value the numeric value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numeric cell and set its value. - */ - void setCellValue(double value); - - /** - *

        Converts the supplied date to its equivalent Excel numeric value and sets - * that into the cell.

        - * - *

        Note - There is actually no 'DATE' cell type in Excel. In many - * cases (when entering date values), Excel automatically adjusts the - * cell style to some date format, creating the illusion that the cell - * data type is now something besides {@link CellType#NUMERIC}. POI - * does not attempt to replicate this behaviour. To make a numeric cell - * display as a date, use {@link #setCellStyle(CellStyle)} etc.

        - * - * @param value the numeric value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numerics cell and set its value. - */ - void setCellValue(Date value); - - /** - *

        Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as - * a date.

        - *

        - * This will set the cell value based on the Calendar's timezone. As Excel - * does not support timezones this means that both 20:00+03:00 and - * 20:00-03:00 will be reported as the same value (20:00) even that there - * are 6 hours difference between the two times. This difference can be - * preserved by using setCellValue(value.getTime()) which will - * automatically shift the times to the default timezone. - *

        - * - * @param value the date value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For othertypes we - * will change the cell to a numeric cell and set its value. - */ - void setCellValue(Calendar value); - - /** - * Set a rich string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - void setCellValue(RichTextString value); - - /** - * Set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - void setCellValue(String value); - - - /** - * Sets formula for this cell. - *

        - * Note, this method only sets the formula string and does not calculate the formula value. - * To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)} - *

        - * - * @param formula the formula to set, e.g. "SUM(C4:E4)". - * If the argument is null then the current formula is removed. - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - void setCellFormula(String formula) throws FormulaParseException; - - /** - * Return a formula for the cell, for example, SUM(C4:E4) - * - * @return a formula for the cell - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is not {@link CellType#FORMULA} - */ - String getCellFormula(); - - /** - * Get the value of the cell as a number. - *

        - * For strings we throw an exception. For blank cells we return a 0. - * For formulas or error cells we return the precalculated value; - *

        - * @return the value of the cell as a number - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is {@link CellType#STRING} - * @exception NumberFormatException if the cell value isn't a parsable double. - * @see DataFormatter for turning this number into a string similar to that which Excel would render this number as. - */ - double getNumericCellValue(); - - /** - * Get the value of the cell as a date. - *

        - * For strings we throw an exception. For blank cells we return a null. - *

        - * @return the value of the cell as a date - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is {@link CellType#STRING} - * @exception NumberFormatException if the cell value isn't a parsable double. - * @see DataFormatter for formatting this date into a string similar to how excel does. - */ - Date getDateCellValue(); - - /** - * Get the value of the cell as a XSSFRichTextString - *

        - * For numeric cells we throw an exception. For blank cells we return an empty string. - * For formula cells we return the pre-calculated value if a string, otherwise an exception. - *

        - * @return the value of the cell as a XSSFRichTextString - */ - RichTextString getRichStringCellValue(); - - /** - * Get the value of the cell as a string - *

        - * For numeric cells we throw an exception. For blank cells we return an empty string. - * For formulaCells that are not string Formulas, we throw an exception. - *

        - * @return the value of the cell as a string - */ - String getStringCellValue(); - - /** - * Set a boolean value for the cell - * - * @param value the boolean value to set this cell to. For formulas we'll set the - * precalculated value, for booleans we'll set its value. For other types we - * will change the cell to a boolean cell and set its value. - */ - void setCellValue(boolean value); - - /** - * Set a error value for the cell - * - * @param value the error value to set this cell to. For formulas we'll set the - * precalculated value , for errors we'll set - * its value. For other types we will change the cell to an error - * cell and set its value. - * @see FormulaError - */ - void setCellErrorValue(byte value); - - /** - * Get the value of the cell as a boolean. - *

        - * For strings, numbers, and errors, we throw an exception. For blank cells we return a false. - *

        - * @return the value of the cell as a boolean - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} - * is not {@link CellType#BOOLEAN}, {@link CellType#BLANK} or {@link CellType#FORMULA} - */ - boolean getBooleanCellValue(); - - /** - * Get the value of the cell as an error code. - *

        - * For strings, numbers, and booleans, we throw an exception. - * For blank cells we return a 0. - *

        - * - * @return the value of the cell as an error code - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} isn't {@link CellType#ERROR} - * @see FormulaError for error codes - */ - byte getErrorCellValue(); - - /** - *

        Set the style for the cell. The style should be an CellStyle created/retrieved from - * the Workbook.

        - * - *

        To change the style of a cell without affecting other cells that use the same style, - * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map)}

        - * - * @param style reference contained in the workbook. - * If the value is null then the style information is removed causing the cell to used the default workbook style. - * @see org.apache.poi.ss.usermodel.Workbook#createCellStyle() - */ - void setCellStyle(CellStyle style); - - /** - * Return the cell's style. - * - * @return the cell's style. Always not-null. Default cell style has zero index and can be obtained as - * workbook.getCellStyleAt(0) - * @see Workbook#getCellStyleAt(int) - */ - CellStyle getCellStyle(); - - /** - * Sets this cell as the active cell for the worksheet - */ - void setAsActiveCell(); - - /** - * Gets the address of this cell - * - * @return A1 style address of this cell - * @since 3.14beta1 - */ - CellAddress getAddress(); - - /** - * Assign a comment to this cell - * - * @param comment comment associated with this cell - */ - void setCellComment(Comment comment); - - /** - * Returns comment associated with this cell - * - * @return comment associated with this cell or null if not found - */ - Comment getCellComment(); - - /** - * Removes the comment for this cell, if there is one. - */ - void removeCellComment(); - - /** - * @return hyperlink associated with this cell or null if not found - */ - Hyperlink getHyperlink(); - - /** - * Assign a hyperlink to this cell - * - * @param link hyperlink associated with this cell - */ - void setHyperlink(Hyperlink link); - - /** - * Removes the hyperlink for this cell, if there is one. - */ - void removeHyperlink(); - - /** - * Only valid for array formula cells - * - * @return range of the array formula group that the cell belongs to. - */ - CellRangeAddress getArrayFormulaRange(); - - /** - * @return true if this cell is part of group of cells having a common array formula. - */ - boolean isPartOfArrayFormulaGroup(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/CellCopyPolicy.java b/trunk/src/java/org/apache/poi/ss/usermodel/CellCopyPolicy.java deleted file mode 100644 index 8a0377b9a..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/CellCopyPolicy.java +++ /dev/null @@ -1,294 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.util.Beta; - -@Beta -public class CellCopyPolicy { - // cell-level policies - public static final boolean DEFAULT_COPY_CELL_VALUE_POLICY = true; - public static final boolean DEFAULT_COPY_CELL_STYLE_POLICY = true; - public static final boolean DEFAULT_COPY_CELL_FORMULA_POLICY = true; - public static final boolean DEFAULT_COPY_HYPERLINK_POLICY = true; - public static final boolean DEFAULT_MERGE_HYPERLINK_POLICY = false; - - // row-level policies - public static final boolean DEFAULT_COPY_ROW_HEIGHT_POLICY = true; - public static final boolean DEFAULT_CONDENSE_ROWS_POLICY = false; - - // sheet-level policies - public static final boolean DEFAULT_COPY_MERGED_REGIONS_POLICY = true; - - // cell-level policies - private boolean copyCellValue = DEFAULT_COPY_CELL_VALUE_POLICY; - private boolean copyCellStyle = DEFAULT_COPY_CELL_STYLE_POLICY; - private boolean copyCellFormula = DEFAULT_COPY_CELL_FORMULA_POLICY; - private boolean copyHyperlink = DEFAULT_COPY_HYPERLINK_POLICY; - private boolean mergeHyperlink = DEFAULT_MERGE_HYPERLINK_POLICY; - - // row-level policies - private boolean copyRowHeight = DEFAULT_COPY_ROW_HEIGHT_POLICY; - private boolean condenseRows = DEFAULT_CONDENSE_ROWS_POLICY; - - // sheet-level policies - private boolean copyMergedRegions = DEFAULT_COPY_MERGED_REGIONS_POLICY; - - /** - * Default CellCopyPolicy, uses default policy - * For custom CellCopyPolicy, use {@link Builder} class - */ - public CellCopyPolicy() { } - - /** - * Copy constructor - * - * @param other policy to copy - */ - public CellCopyPolicy(CellCopyPolicy other) { - copyCellValue = other.isCopyCellValue(); - copyCellStyle = other.isCopyCellStyle(); - copyCellFormula = other.isCopyCellFormula(); - copyHyperlink = other.isCopyHyperlink(); - mergeHyperlink = other.isMergeHyperlink(); - - copyRowHeight = other.isCopyRowHeight(); - condenseRows = other.isCondenseRows(); - - copyMergedRegions = other.isCopyMergedRegions(); - } - - // should builder be replaced with CellCopyPolicy setters that return the object - // to allow setters to be chained together? - // policy.setCopyCellValue(true).setCopyCellStyle(true) - private CellCopyPolicy(Builder builder) { - copyCellValue = builder.copyCellValue; - copyCellStyle = builder.copyCellStyle; - copyCellFormula = builder.copyCellFormula; - copyHyperlink = builder.copyHyperlink; - mergeHyperlink = builder.mergeHyperlink; - - copyRowHeight = builder.copyRowHeight; - condenseRows = builder.condenseRows; - - copyMergedRegions = builder.copyMergedRegions; - } - - public static class Builder { - // cell-level policies - private boolean copyCellValue = DEFAULT_COPY_CELL_VALUE_POLICY; - private boolean copyCellStyle = DEFAULT_COPY_CELL_STYLE_POLICY; - private boolean copyCellFormula = DEFAULT_COPY_CELL_FORMULA_POLICY; - private boolean copyHyperlink = DEFAULT_COPY_HYPERLINK_POLICY; - private boolean mergeHyperlink = DEFAULT_MERGE_HYPERLINK_POLICY; - - // row-level policies - private boolean copyRowHeight = DEFAULT_COPY_ROW_HEIGHT_POLICY; - private boolean condenseRows = DEFAULT_CONDENSE_ROWS_POLICY; - - // sheet-level policies - private boolean copyMergedRegions = DEFAULT_COPY_MERGED_REGIONS_POLICY; - - /** - * Builder class for CellCopyPolicy - */ - public Builder() { - } - - // cell-level policies - public Builder cellValue(boolean copyCellValue) { - this.copyCellValue = copyCellValue; - return this; - } - public Builder cellStyle(boolean copyCellStyle) { - this.copyCellStyle = copyCellStyle; - return this; - } - public Builder cellFormula(boolean copyCellFormula) { - this.copyCellFormula = copyCellFormula; - return this; - } - public Builder copyHyperlink(boolean copyHyperlink) { - this.copyHyperlink = copyHyperlink; - return this; - } - public Builder mergeHyperlink(boolean mergeHyperlink) { - this.mergeHyperlink = mergeHyperlink; - return this; - } - - // row-level policies - public Builder rowHeight(boolean copyRowHeight) { - this.copyRowHeight = copyRowHeight; - return this; - } - public Builder condenseRows(boolean condenseRows) { - this.condenseRows = condenseRows; - return this; - } - - // sheet-level policies - public Builder mergedRegions(boolean copyMergedRegions) { - this.copyMergedRegions = copyMergedRegions; - return this; - } - public CellCopyPolicy build() { - return new CellCopyPolicy(this); - } - } - - public Builder createBuilder() { - final Builder builder = new Builder() - .cellValue(copyCellValue) - .cellStyle(copyCellStyle) - .cellFormula(copyCellFormula) - .copyHyperlink(copyHyperlink) - .mergeHyperlink(mergeHyperlink) - .rowHeight(copyRowHeight) - .condenseRows(condenseRows) - .mergedRegions(copyMergedRegions); - return builder; - } - -/* - * Cell-level policies - */ - /** - * @return the copyCellValue - */ - public boolean isCopyCellValue() { - return copyCellValue; - } - - /** - * @param copyCellValue the copyCellValue to set - */ - public void setCopyCellValue(boolean copyCellValue) { - this.copyCellValue = copyCellValue; - } - - /** - * @return the copyCellStyle - */ - public boolean isCopyCellStyle() { - return copyCellStyle; - } - - /** - * @param copyCellStyle the copyCellStyle to set - */ - public void setCopyCellStyle(boolean copyCellStyle) { - this.copyCellStyle = copyCellStyle; - } - - /** - * @return the copyCellFormula - */ - public boolean isCopyCellFormula() { - return copyCellFormula; - } - - /** - * @param copyCellFormula the copyCellFormula to set - */ - public void setCopyCellFormula(boolean copyCellFormula) { - this.copyCellFormula = copyCellFormula; - } - - /** - * @return the copyHyperlink - */ - public boolean isCopyHyperlink() { - return copyHyperlink; - } - - /** - * @param copyHyperlink the copyHyperlink to set - */ - public void setCopyHyperlink(boolean copyHyperlink) { - this.copyHyperlink = copyHyperlink; - } - - /** - * @return the mergeHyperlink - */ - public boolean isMergeHyperlink() { - return mergeHyperlink; - } - - /** - * @param mergeHyperlink the mergeHyperlink to set - */ - public void setMergeHyperlink(boolean mergeHyperlink) { - this.mergeHyperlink = mergeHyperlink; - } - -/* - * Row-level policies - */ - /** - * @return the copyRowHeight - */ - public boolean isCopyRowHeight() { - return copyRowHeight; - } - - /** - * @param copyRowHeight the copyRowHeight to set - */ - public void setCopyRowHeight(boolean copyRowHeight) { - this.copyRowHeight = copyRowHeight; - } - - /** - * If condenseRows is true, a discontinuities in srcRows will be removed when copied to destination - * For example: - * Sheet.copyRows({Row(1), Row(2), Row(5)}, 11, policy) results in rows 1, 2, and 5 - * being copied to rows 11, 12, and 13 if condenseRows is True, or rows 11, 11, 15 if condenseRows is false - * @return the condenseRows - */ - public boolean isCondenseRows() { - return condenseRows; - } - - /** - * @param condenseRows the condenseRows to set - */ - public void setCondenseRows(boolean condenseRows) { - this.condenseRows = condenseRows; - } - - -/* - * Sheet-level policies - */ - /** - * @return the copyMergedRegions - */ - public boolean isCopyMergedRegions() { - return copyMergedRegions; - } - - /** - * @param copyMergedRegions the copyMergedRegions to set - */ - public void setCopyMergedRegions(boolean copyMergedRegions) { - this.copyMergedRegions = copyMergedRegions; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/CellRange.java b/trunk/src/java/org/apache/poi/ss/usermodel/CellRange.java deleted file mode 100644 index 4868dd8e8..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/CellRange.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.Iterator; - - -/** - * Represents a rectangular region of a {@link Sheet} - */ -public interface CellRange extends Iterable { - int getWidth(); - int getHeight(); - - /** - * Gets the number of cells in this range. - * @return height * width - */ - int size(); - - /** - * @return the text format of this range. Single cell ranges are formatted - * like single cell references (e.g. 'A1' instead of 'A1:A1'). - */ - String getReferenceText(); - - /** - * @return the cell at relative coordinates (0,0). Never null. - */ - C getTopLeftCell(); - - /** - * @param relativeRowIndex must be between 0 and height-1 - * @param relativeColumnIndex must be between 0 and width-1 - * @return the cell at the specified coordinates. Never null. - */ - C getCell(int relativeRowIndex, int relativeColumnIndex); - /** - * @return a flattened array of all the cells in this {@link CellRange} - */ - C[] getFlattenedCells(); - /** - * @return a 2-D array of all the cells in this {@link CellRange}. The first - * array dimension is the row index (values 0...height-1) - * and the second dimension is the column index (values 0...width-1) - */ - C[][] getCells(); - - /** - * @return an {@link Iterator} over all cells in this range. Iteration starts - * with all cells in the first row followed by all cells in the next row, etc. - */ - Iterator iterator(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/CellStyle.java b/trunk/src/java/org/apache/poi/ss/usermodel/CellStyle.java deleted file mode 100644 index d16619c4d..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/CellStyle.java +++ /dev/null @@ -1,902 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.util.Removal; - -public interface CellStyle { - - /** - * general (normal) horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#GENERAL} instead. - */ - @Removal(version="3.17") - short ALIGN_GENERAL = 0x0; //HorizontalAlignment.GENERAL.getCode(); - - /** - * left-justified horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#LEFT} instead. - */ - @Removal(version="3.17") - short ALIGN_LEFT = 0x1; //HorizontalAlignment.LEFT.getCode(); - - /** - * center horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#CENTER} instead. - */ - @Removal(version="3.17") - short ALIGN_CENTER = 0x2; //HorizontalAlignment.CENTER.getCode(); - - /** - * right-justified horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#RIGHT} instead. - */ - @Removal(version="3.17") - short ALIGN_RIGHT = 0x3; //HorizontalAlignment.RIGHT.getCode(); - - /** - * fill? horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#FILL} instead. - */ - @Removal(version="3.17") - short ALIGN_FILL = 0x4; //HorizontalAlignment.FILL.getCode(); - - /** - * justified horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#JUSTIFY} instead. - */ - @Removal(version="3.17") - short ALIGN_JUSTIFY = 0x5; //HorizontalAlignment.JUSTIFY.getCode(); - - /** - * center-selection? horizontal alignment - * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#CENTER_SELECTION} instead. - */ - @Removal(version="3.17") - short ALIGN_CENTER_SELECTION = 0x6; //HorizontalAlignment.CENTER_SELECTION.getCode(); - - /** - * top-aligned vertical alignment - * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#TOP} instead. - */ - @Removal(version="3.17") - short VERTICAL_TOP = 0x0; //VerticalAlignment.TOP.getCode(); - - /** - * center-aligned vertical alignment - * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#CENTER} instead. - */ - @Removal(version="3.17") - short VERTICAL_CENTER = 0x1; //VerticalAlignment.CENTER.getCode(); - - /** - * bottom-aligned vertical alignment - * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#BOTTOM} instead. - */ - @Removal(version="3.17") - short VERTICAL_BOTTOM = 0x2; //VerticalAlignment.BOTTOM.getCode(); - - /** - * vertically justified vertical alignment - * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#JUSTIFY} instead. - */ - @Removal(version="3.17") - short VERTICAL_JUSTIFY = 0x3; //VerticalAlignment.JUSTIFY.getCode(); - - /** - * No border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#NONE} instead. - */ - @Removal(version="3.17") - short BORDER_NONE = 0x0; //BorderStyle.NONE.getCode(); - - /** - * Thin border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#THIN} instead. - */ - @Removal(version="3.17") - short BORDER_THIN = 0x1; //BorderStyle.THIN.getCode(); - - /** - * Medium border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM} instead. - */ - @Removal(version="3.17") - short BORDER_MEDIUM = 0x2; //BorderStyle.MEDIUM.getCode(); - - /** - * dash border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASHED} instead. - */ - @Removal(version="3.17") - short BORDER_DASHED = 0x3; //BorderStyle.DASHED.getCode(); - - /** - * dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOTTED} instead. - */ - @Removal(version="3.17") - short BORDER_DOTTED = 0x4; //BorderStyle.DOTTED.getCode(); - - /** - * Thick border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#THICK} instead. - */ - @Removal(version="3.17") - short BORDER_THICK = 0x5; //BorderStyle.THICK.getCode(); - - /** - * double-line border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOUBLE} instead. - */ - @Removal(version="3.17") - short BORDER_DOUBLE = 0x6; //BorderStyle.DOUBLE.getCode(); - - /** - * hair-line border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#HAIR} instead. - */ - @Removal(version="3.17") - short BORDER_HAIR = 0x7; //BorderStyle.HAIR.getCode(); - - /** - * Medium dashed border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASHED} instead. - */ - @Removal(version="3.17") - short BORDER_MEDIUM_DASHED = 0x8; //BorderStyle.MEDIUM_DASHED.getCode(); - - /** - * dash-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT} instead. - */ - @Removal(version="3.17") - short BORDER_DASH_DOT = 0x9; //BorderStyle.DASH_DOT.getCode(); - - /** - * medium dash-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT} instead. - */ - @Removal(version="3.17") - short BORDER_MEDIUM_DASH_DOT = 0xA; //BorderStyle.MEDIUM_DASH_DOT.getCode(); - - /** - * dash-dot-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT_DOT} instead. - */ - @Removal(version="3.17") - short BORDER_DASH_DOT_DOT = 0xB; //BorderStyle.DASH_DOT_DOT.getCode(); - - /** - * medium dash-dot-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT_DOT} instead. - */ - @Removal(version="3.17") - short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; //BorderStyle.MEDIUM_DASH_DOT_DOT.getCode(); - - /** - * slanted dash-dot border - * @deprecated 3.15 beta 2. Use {@link BorderStyle#SLANTED_DASH_DOT} instead. - */ - @Removal(version="3.17") - short BORDER_SLANTED_DASH_DOT = 0xD; //BorderStyle.SLANTED_DASH_DOT.getCode(); - - /** - * Fill Pattern: No background - * @deprecated 3.15 beta 3. Use {@link FillPatternType#NO_FILL} instead. - */ - @Removal(version="3.17") - short NO_FILL = 0; //FillPatternType.NO_FILL.getCode(); - - /** - * Fill Pattern: Solidly filled - * @deprecated 3.15 beta 3. Use {@link FillPatternType#SOLID_FOREGROUND} instead. - */ - @Removal(version="3.17") - short SOLID_FOREGROUND = 1; //FillPatternType.SOLID_FOREGROUND.getCode(); - - /** - * Fill Pattern: Small fine dots - * @deprecated 3.15 beta 3. Use {@link FillPatternType#FINE_DOTS} instead. - */ - @Removal(version="3.17") - short FINE_DOTS = 2; //FillPatternType.FINE_DOTS.getCode(); - - /** - * Fill Pattern: Wide dots - * @deprecated 3.15 beta 3. Use {@link FillPatternType#ALT_BARS} instead. - */ - @Removal(version="3.17") - short ALT_BARS = 3; //FillPatternType.ALT_BARS.getCode(); - - /** - * Fill Pattern: Sparse dots - * @deprecated 3.15 beta 3. Use {@link FillPatternType#SPARSE_DOTS} instead. - */ - @Removal(version="3.17") - short SPARSE_DOTS = 4; //FillPatternType.SPARSE_DOTS.getCode(); - - /** - * Fill Pattern: Thick horizontal bands - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_HORZ_BANDS} instead. - */ - @Removal(version="3.17") - short THICK_HORZ_BANDS = 5; //FillPatternType.THICK_HORZ_BANDS.getCode(); - - /** - * Fill Pattern: Thick vertical bands - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_VERT_BANDS} instead. - */ - @Removal(version="3.17") - short THICK_VERT_BANDS = 6; //FillPatternType.THICK_VERT_BANDS.getCode(); - - /** - * Fill Pattern: Thick backward facing diagonals - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_BACKWARD_DIAG} instead. - */ - @Removal(version="3.17") - short THICK_BACKWARD_DIAG = 7; //FillPatternType.THICK_BACKWARD_DIAG.getCode(); - - /** - * Fill Pattern: Thick forward facing diagonals - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_FORWARD_DIAG} instead. - */ - @Removal(version="3.17") - short THICK_FORWARD_DIAG = 8; //FillPatternType.THICK_FORWARD_DIAG.getCode(); - - /** - * Fill Pattern: Large spots - * @deprecated 3.15 beta 3. Use {@link FillPatternType#BIG_SPOTS} instead. - */ - @Removal(version="3.17") - short BIG_SPOTS = 9; //FillPatternType.BIG_SPOTS.getCode(); - - /** - * Fill Pattern: Brick-like layout - * @deprecated 3.15 beta 3. Use {@link FillPatternType#BRICKS} instead. - */ - @Removal(version="3.17") - short BRICKS = 10; //FillPatternType.BRICKS.getCode(); - - /** - * Fill Pattern: Thin horizontal bands - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_HORZ_BANDS} instead. - */ - @Removal(version="3.17") - short THIN_HORZ_BANDS = 11; //FillPatternType.THIN_HORZ_BANDS.getCode(); - - /** - * Fill Pattern: Thin vertical bands - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_VERT_BANDS} instead. - */ - @Removal(version="3.17") - short THIN_VERT_BANDS = 12; //FillPatternType.THIN_VERT_BANDS.getCode(); - - /** - * Fill Pattern: Thin backward diagonal - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_BACKWARD_DIAG} instead. - */ - @Removal(version="3.17") - short THIN_BACKWARD_DIAG = 13; //FillPatternType.THIN_BACKWARD_DIAG.getCode(); - - /** - * Fill Pattern: Thin forward diagonal - * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_FORWARD_DIAG} instead. - */ - @Removal(version="3.17") - short THIN_FORWARD_DIAG = 14; //FillPatternType.THIN_FORWARD_DIAG.getCode(); - - /** - * Fill Pattern: Squares - * @deprecated 3.15 beta 3. Use {@link FillPatternType#SQUARES} instead. - */ - @Removal(version="3.17") - short SQUARES = 15; //FillPatternType.SQUARES.getCode(); - - /** - * Fill Pattern: Diamonds - * @deprecated 3.15 beta 3. Use {@link FillPatternType#DIAMONDS} instead. - */ - @Removal(version="3.17") - short DIAMONDS = 16; //FillPatternType.DIAMONDS.getCode(); - - /** - * Fill Pattern: Less Dots - * @deprecated 3.15 beta 3. Use {@link FillPatternType#LESS_DOTS} instead. - */ - @Removal(version="3.17") - short LESS_DOTS = 17; //FillPatternType.LESS_DOTS.getCode(); - - /** - * Fill Pattern: Least Dots - * @deprecated 3.15 beta 3. Use {@link FillPatternType#LEAST_DOTS} instead. - */ - @Removal(version="3.17") - short LEAST_DOTS = 18; //FillPatternType.LEAST_DOTS.getCode(); - - /** - * get the index within the Workbook (sequence within the collection of ExtnededFormat objects) - * @return unique index number of the underlying record this style represents (probably you don't care - * unless you're comparing which one is which) - */ - - short getIndex(); - - /** - * set the data format (must be a valid format) - * @see DataFormat - */ - - void setDataFormat(short fmt); - - /** - * get the index of the format - * @see DataFormat - */ - short getDataFormat(); - - /** - * Get the format string - */ - String getDataFormatString(); - - /** - * set the font for this style - * @param font a font object created or retrieved from the Workbook object - * @see Workbook#createFont() - * @see Workbook#getFontAt(short) - */ - - void setFont(Font font); - - /** - * gets the index of the font for this style - * @see Workbook#getFontAt(short) - */ - short getFontIndex(); - - /** - * set the cell's using this style to be hidden - * @param hidden - whether the cell using this style should be hidden - */ - - void setHidden(boolean hidden); - - /** - * get whether the cell's using this style are to be hidden - * @return hidden - whether the cell using this style should be hidden - */ - - boolean getHidden(); - - /** - * set the cell's using this style to be locked - * @param locked - whether the cell using this style should be locked - */ - - void setLocked(boolean locked); - - /** - * get whether the cell's using this style are to be locked - * @return hidden - whether the cell using this style should be locked - */ - - boolean getLocked(); - - /** - * Turn on or off "Quote Prefix" or "123 Prefix" for the style, - * which is used to tell Excel that the thing which looks like - * a number or a formula shouldn't be treated as on. - * Turning this on is somewhat (but not completely, see {@link IgnoredErrorType}) - * like prefixing the cell value with a ' in Excel - */ - void setQuotePrefixed(boolean quotePrefix); - - /** - * Is "Quote Prefix" or "123 Prefix" enabled for the cell? - * Having this on is somewhat (but not completely, see {@link IgnoredErrorType}) - * like prefixing the cell value with a ' in Excel - */ - boolean getQuotePrefixed(); - - /** - * set the type of horizontal alignment for the cell - * @param align - the type of alignment - * @see #ALIGN_GENERAL - * @see #ALIGN_LEFT - * @see #ALIGN_CENTER - * @see #ALIGN_RIGHT - * @see #ALIGN_FILL - * @see #ALIGN_JUSTIFY - * @see #ALIGN_CENTER_SELECTION - * @deprecated POI 3.15 beta 3. Use {@link #setAlignment(HorizontalAlignment)} instead. - */ - void setAlignment(short align); - /** - * set the type of horizontal alignment for the cell - * @param align - the type of alignment - */ - void setAlignment(HorizontalAlignment align); - - /** - * get the type of horizontal alignment for the cell - * @return align - the type of alignment - * @see #ALIGN_GENERAL - * @see #ALIGN_LEFT - * @see #ALIGN_CENTER - * @see #ALIGN_RIGHT - * @see #ALIGN_FILL - * @see #ALIGN_JUSTIFY - * @see #ALIGN_CENTER_SELECTION - * @deprecated POI 3.15 beta 3. Use {@link #getAlignmentEnum()} instead. - */ - short getAlignment(); - /** - * get the type of horizontal alignment for the cell - * @return align - the type of alignment - */ - HorizontalAlignment getAlignmentEnum(); - - /** - * Set whether the text should be wrapped. - * Setting this flag to true make all content visible - * within a cell by displaying it on multiple lines - * - * @param wrapped wrap text or not - */ - - void setWrapText(boolean wrapped); - - /** - * get whether the text should be wrapped - * @return wrap text or not - */ - - boolean getWrapText(); - - /** - * set the type of vertical alignment for the cell - * @param align the type of alignment - * @see #VERTICAL_TOP - * @see #VERTICAL_CENTER - * @see #VERTICAL_BOTTOM - * @see #VERTICAL_JUSTIFY - * @deprecated POI 3.15 beta 3. Use {@link #setVerticalAlignment(VerticalAlignment)} instead. - */ - void setVerticalAlignment(short align); - /** - * set the type of vertical alignment for the cell - * @param align the type of alignment - */ - void setVerticalAlignment(VerticalAlignment align); - - /** - * get the type of vertical alignment for the cell - * @return align the type of alignment - * @see #VERTICAL_TOP - * @see #VERTICAL_CENTER - * @see #VERTICAL_BOTTOM - * @see #VERTICAL_JUSTIFY - * @deprecated POI 3.15 beta 3. Use {@link #getVerticalAlignmentEnum()} instead. - */ - short getVerticalAlignment(); - /** - * get the type of vertical alignment for the cell - * @return align the type of alignment - */ - VerticalAlignment getVerticalAlignmentEnum(); - - /** - * set the degree of rotation for the text in the cell. - * - * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF - * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges - * accordingly, however the corresponding getter is returning values in the range mandated by the current type - * of Excel file-format that this CellStyle is applied to. - * - * @param rotation degrees (see note above) - */ - void setRotation(short rotation); - - /** - * get the degree of rotation for the text in the cell. - * - * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF - * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges - * value-range as used by the type of Excel file-format that this CellStyle is applied to. - * - * @return rotation degrees (see note above) - */ - short getRotation(); - - /** - * set the number of spaces to indent the text in the cell - * @param indent - number of spaces - */ - - void setIndention(short indent); - - /** - * get the number of spaces to indent the text in the cell - * @return indent - number of spaces - */ - - short getIndention(); - - /** - * set the type of border to use for the left border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link #setBorderLeft(BorderStyle)} instead - */ - @Removal(version="3.17") - void setBorderLeft(short border); - - /** - * set the type of border to use for the left border of the cell - * @param border type - * @since POI 3.15 - */ - void setBorderLeft(BorderStyle border); - - /** - * get the type of border to use for the left border of the cell - * @return border type - * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()} instead. - * This will return a BorderStyle enum in the future. - */ - short getBorderLeft(); - /** - * get the type of border to use for the left border of the cell - * @return border type - * @since POI 3.15 - */ - BorderStyle getBorderLeftEnum(); - - /** - * set the type of border to use for the right border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link #setBorderRight(BorderStyle)} instead - */ - @Removal(version="3.17") - void setBorderRight(short border); - - /** - * set the type of border to use for the right border of the cell - * @param border type - * @since POI 3.15 - */ - void setBorderRight(BorderStyle border); - - /** - * get the type of border to use for the right border of the cell - * @return border type - * @deprecated POI 3.15. Use {@link #getBorderRightEnum()} instead. - * This will return a BorderStyle enum in the future. - */ - short getBorderRight(); - /** - * get the type of border to use for the right border of the cell - * @return border type - * @since POI 3.15 - */ - BorderStyle getBorderRightEnum(); - - /** - * set the type of border to use for the top border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link #setBorderTop(BorderStyle)} instead - */ - @Removal(version="3.17") - void setBorderTop(short border); - - /** - * set the type of border to use for the top border of the cell - * @param border type - * @since POI 3.15 - */ - void setBorderTop(BorderStyle border); - - /** - * get the type of border to use for the top border of the cell - * @return border type - * @deprecated POI 3.15. Use {@link #getBorderTopEnum()} instead. - * This will return a BorderStyle enum in the future. - */ - short getBorderTop(); - /** - * get the type of border to use for the top border of the cell - * @return border type - * @since POI 3.15 - */ - BorderStyle getBorderTopEnum(); - - /** - * set the type of border to use for the bottom border of the cell - * @param border type - * @see #BORDER_NONE - * @see #BORDER_THIN - * @see #BORDER_MEDIUM - * @see #BORDER_DASHED - * @see #BORDER_DOTTED - * @see #BORDER_THICK - * @see #BORDER_DOUBLE - * @see #BORDER_HAIR - * @see #BORDER_MEDIUM_DASHED - * @see #BORDER_DASH_DOT - * @see #BORDER_MEDIUM_DASH_DOT - * @see #BORDER_DASH_DOT_DOT - * @see #BORDER_MEDIUM_DASH_DOT_DOT - * @see #BORDER_SLANTED_DASH_DOT - * @deprecated 3.15 beta 2. Use {@link #setBorderBottom(BorderStyle)} instead. - */ - @Removal(version="3.17") - void setBorderBottom(short border); - - /** - * set the type of border to use for the bottom border of the cell - * @param border type - * @since POI 3.15 - */ - void setBorderBottom(BorderStyle border); - - /** - * get the type of border to use for the bottom border of the cell - * @return border type - * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()} instead. - * This will return a BorderStyle enum in the future. - */ - short getBorderBottom(); - /** - * get the type of border to use for the bottom border of the cell - * @return border type - * @since POI 3.15 - */ - BorderStyle getBorderBottomEnum(); - - /** - * set the color to use for the left border - * @param color The index of the color definition - */ - void setLeftBorderColor(short color); - - /** - * get the color to use for the left border - */ - short getLeftBorderColor(); - - /** - * set the color to use for the right border - * @param color The index of the color definition - */ - void setRightBorderColor(short color); - - /** - * get the color to use for the left border - * @return the index of the color definition - */ - short getRightBorderColor(); - - /** - * set the color to use for the top border - * @param color The index of the color definition - */ - void setTopBorderColor(short color); - - /** - * get the color to use for the top border - * @return the index of the color definition - */ - short getTopBorderColor(); - - /** - * set the color to use for the bottom border - * @param color The index of the color definition - */ - void setBottomBorderColor(short color); - - /** - * get the color to use for the left border - * @return the index of the color definition - */ - short getBottomBorderColor(); - - /** - * setting to one fills the cell with the foreground color... No idea about - * other values - * - * @see #NO_FILL - * @see #SOLID_FOREGROUND - * @see #FINE_DOTS - * @see #ALT_BARS - * @see #SPARSE_DOTS - * @see #THICK_HORZ_BANDS - * @see #THICK_VERT_BANDS - * @see #THICK_BACKWARD_DIAG - * @see #THICK_FORWARD_DIAG - * @see #BIG_SPOTS - * @see #BRICKS - * @see #THIN_HORZ_BANDS - * @see #THIN_VERT_BANDS - * @see #THIN_BACKWARD_DIAG - * @see #THIN_FORWARD_DIAG - * @see #SQUARES - * @see #DIAMONDS - * - * @param fp fill pattern (set to 1 to fill w/foreground color) - * @deprecated POI 3.15 beta 3. Use {@link #setFillPattern(FillPatternType)} instead. - */ - void setFillPattern(short fp); - /** - * setting to one fills the cell with the foreground color... No idea about - * other values - * - * @see #NO_FILL - * @see #SOLID_FOREGROUND - * @see #FINE_DOTS - * @see #ALT_BARS - * @see #SPARSE_DOTS - * @see #THICK_HORZ_BANDS - * @see #THICK_VERT_BANDS - * @see #THICK_BACKWARD_DIAG - * @see #THICK_FORWARD_DIAG - * @see #BIG_SPOTS - * @see #BRICKS - * @see #THIN_HORZ_BANDS - * @see #THIN_VERT_BANDS - * @see #THIN_BACKWARD_DIAG - * @see #THIN_FORWARD_DIAG - * @see #SQUARES - * @see #DIAMONDS - * - * @param fp fill pattern (set to {@link FillPatternType#SOLID_FOREGROUND} to fill w/foreground color) - * @since POI 3.15 beta 3 - */ - void setFillPattern(FillPatternType fp); - - /** - * get the fill pattern (??) - set to 1 to fill with foreground color - * @return fill pattern - * @deprecated POI 3.15 beta 3. This method will return {@link FillPatternType} in the future. Use {@link #setFillPattern(FillPatternType)} instead. - */ - short getFillPattern(); - /** - * get the fill pattern (??) - set to 1 to fill with foreground color - * @return fill pattern - * @since POI 3.15 beta 3 - */ - FillPatternType getFillPatternEnum(); - - /** - * set the background fill color. - * - * @param bg color - */ - - void setFillBackgroundColor(short bg); - - /** - * get the background fill color, if the fill - * is defined with an indexed color. - * @return fill color index, or 0 if not indexed (XSSF only) - */ - short getFillBackgroundColor(); - - /** - * Gets the color object representing the current - * background fill, resolving indexes using - * the supplied workbook. - * This will work for both indexed and rgb - * defined colors. - */ - Color getFillBackgroundColorColor(); - - /** - * set the foreground fill color - * Note: Ensure Foreground color is set prior to background color. - * @param bg color - */ - void setFillForegroundColor(short bg); - - /** - * get the foreground fill color, if the fill - * is defined with an indexed color. - * @return fill color, or 0 if not indexed (XSSF only) - */ - short getFillForegroundColor(); - - /** - * Gets the color object representing the current - * foreground fill, resolving indexes using - * the supplied workbook. - * This will work for both indexed and rgb - * defined colors. - */ - Color getFillForegroundColorColor(); - - /** - * Clones all the style information from another - * CellStyle, onto this one. This - * CellStyle will then have all the same - * properties as the source, but the two may - * be edited independently. - * Any stylings on this CellStyle will be lost! - * - * The source CellStyle could be from another - * Workbook if you like. This allows you to - * copy styles from one Workbook to another. - * - * However, both of the CellStyles will need - * to be of the same type (HSSFCellStyle or - * XSSFCellStyle) - */ - void cloneStyleFrom(CellStyle source); - - /** - * Controls if the Cell should be auto-sized - * to shrink to fit if the text is too long - */ - void setShrinkToFit(boolean shrinkToFit); - - /** - * Should the Cell be auto-sized by Excel to shrink - * it to fit if this text is too long? - */ - boolean getShrinkToFit(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/CellType.java b/trunk/src/java/org/apache/poi/ss/usermodel/CellType.java deleted file mode 100644 index c8e81c9c1..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/CellType.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.util.Internal; - -/** - * @since POI 3.15 beta 3 - */ -public enum CellType { - /** - * Unknown type, used to represent a state prior to initialization or the - * lack of a concrete type. - * For internal use only. - */ - @Internal(since="POI 3.15 beta 3") - _NONE(-1), - - /** - * Numeric cell type (whole numbers, fractional numbers, dates) - */ - NUMERIC(0), - - /** String (text) cell type */ - STRING(1), - - /** - * Formula cell type - * @see FormulaType - */ - FORMULA(2), - - /** - * Blank cell type - */ - BLANK(3), - - /** - * Boolean cell type - */ - BOOLEAN(4), - - /** - * Error cell type - * @see FormulaError - */ - ERROR(5); - - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3 - */ - private final int code; - - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3 - */ - private CellType(int code) { - this.code = code; - } - - /** - * @since POI 3.15 beta 3. - * @deprecated POI 3.15 beta 3. Used to transition code from ints to CellTypes. - */ - public static CellType forInt(int code) { - for (CellType type : values()) { - if (type.code == code) { - return type; - } - } - throw new IllegalArgumentException("Invalid CellType code: " + code); - } - - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3 - */ - public int getCode() { - return code; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/CellValue.java b/trunk/src/java/org/apache/poi/ss/usermodel/CellValue.java deleted file mode 100644 index 78636d989..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/CellValue.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; - -/** - * Mimics the 'data view' of a cell. This allows formula evaluator - * to return a CellValue instead of precasting the value to String - * or Number or boolean type. - */ -public final class CellValue { - public static final CellValue TRUE = new CellValue(CellType.BOOLEAN, 0.0, true, null, 0); - public static final CellValue FALSE= new CellValue(CellType.BOOLEAN, 0.0, false, null, 0); - - private final CellType _cellType; - private final double _numberValue; - private final boolean _booleanValue; - private final String _textValue; - private final int _errorCode; - - private CellValue(CellType cellType, double numberValue, boolean booleanValue, - String textValue, int errorCode) { - _cellType = cellType; - _numberValue = numberValue; - _booleanValue = booleanValue; - _textValue = textValue; - _errorCode = errorCode; - } - - - public CellValue(double numberValue) { - this(CellType.NUMERIC, numberValue, false, null, 0); - } - - public static CellValue valueOf(boolean booleanValue) { - return booleanValue ? TRUE : FALSE; - } - - public CellValue(String stringValue) { - this(CellType.STRING, 0.0, false, stringValue, 0); - } - - public static CellValue getError(int errorCode) { - return new CellValue(CellType.ERROR, 0.0, false, null, errorCode); - } - - - /** - * @return Returns the booleanValue. - */ - public boolean getBooleanValue() { - return _booleanValue; - } - - /** - * @return Returns the numberValue. - */ - public double getNumberValue() { - return _numberValue; - } - - /** - * @return Returns the stringValue. - */ - public String getStringValue() { - return _textValue; - } - - /** - * Return the cell type. - * - * @return the cell type - * @since POI 3.15 - * Will be renamed to getCellTypeEnum() when we make the CellType enum transition in POI 4.0. See bug 59791. - */ - @Removal(version="4.2") - public CellType getCellTypeEnum() { - return _cellType; - } - - /** - * Return the cell type. - * - * Will return {@link CellType} in version 4.0 of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return the cell type - * - * @deprecated POI 3.15. Use {@link #getCellTypeEnum()} instead. - */ - @Deprecated - public int getCellType() { - return _cellType.getCode(); - } - - /** - * @return Returns the errorValue. - */ - public byte getErrorValue() { - return (byte) _errorCode; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - - public String formatAsString() { - switch (_cellType) { - case NUMERIC: - return String.valueOf(_numberValue); - case STRING: - return '"' + _textValue + '"'; - case BOOLEAN: - return _booleanValue ? "TRUE" : "FALSE"; - case ERROR: - return ErrorEval.getText(_errorCode); - default: - return ""; - } - - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Chart.java b/trunk/src/java/org/apache/poi/ss/usermodel/Chart.java deleted file mode 100644 index f8a55a28e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Chart.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.List; - -import org.apache.poi.ss.usermodel.charts.ChartData; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.ManuallyPositionable; -import org.apache.poi.ss.usermodel.charts.ChartDataFactory; -import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; - -/** - * High level representation of a chart. - * - * @author Roman Kashitsyn - */ -public interface Chart extends ManuallyPositionable { - - /** - * @return an appropriate ChartDataFactory implementation - */ - ChartDataFactory getChartDataFactory(); - - /** - * @return an appropriate ChartAxisFactory implementation - */ - ChartAxisFactory getChartAxisFactory(); - - /** - * @return chart legend instance - */ - ChartLegend getOrCreateLegend(); - - /** - * Delete current chart legend. - */ - void deleteLegend(); - - /** - * @return list of all chart axis - */ - List getAxis(); - - /** - * Plots specified data on the chart. - * - * @param data a data to plot - */ - void plot(ChartData data, ChartAxis... axis); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java b/trunk/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java deleted file mode 100644 index 702970c69..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java +++ /dev/null @@ -1,313 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; - -/** - * A client anchor is attached to an excel worksheet. It anchors against a - * top-left and bottom-right cell. - * - * @author Yegor Kozlov - */ -public interface ClientAnchor { - - /** - * Move and Resize With Anchor Cells - *

        - * Specifies that the current drawing shall move and - * resize to maintain its row and column anchors (i.e. the - * object is anchored to the actual from and to row and column) - *

        - * @deprecated since POI 3.14beta1 (circa 2015-11-24). Use {@link AnchorType#MOVE_AND_RESIZE} instead. - */ - @Removal(version="3.17") - public static final AnchorType MOVE_AND_RESIZE = AnchorType.MOVE_AND_RESIZE; - - /** - * Move With Cells but Do Not Resize - *

        - * Specifies that the current drawing shall move with its - * row and column (i.e. the object is anchored to the - * actual from row and column), but that the size shall remain absolute. - *

        - *

        - * If additional rows/columns are added between the from and to locations of the drawing, - * the drawing shall move its to anchors as needed to maintain this same absolute size. - *

        - * @deprecated since POI 3.14beta1 (circa 2015-11-24). Use {@link AnchorType#MOVE_DONT_RESIZE} instead. - */ - @Removal(version="3.17") - public static final AnchorType MOVE_DONT_RESIZE = AnchorType.MOVE_DONT_RESIZE; - - /** - * Do Not Move or Resize With Underlying Rows/Columns - *

        - * Specifies that the current start and end positions shall - * be maintained with respect to the distances from the - * absolute start point of the worksheet. - *

        - *

        - * If additional rows/columns are added before the - * drawing, the drawing shall move its anchors as needed - * to maintain this same absolute position. - *

        - * @deprecated since POI 3.14beta1 (circa 2015-11-24). Use {@link AnchorType#DONT_MOVE_AND_RESIZE} instead. - */ - @Removal(version="3.17") - public static final AnchorType DONT_MOVE_AND_RESIZE = AnchorType.DONT_MOVE_AND_RESIZE; - - /** - * @since POI 3.14beta1 - */ - public static enum AnchorType { - /** - * Move and Resize With Anchor Cells (0) - *

        - * Specifies that the current drawing shall move and - * resize to maintain its row and column anchors (i.e. the - * object is anchored to the actual from and to row and column) - *

        - */ - MOVE_AND_RESIZE(0), - - /** - * Don't Move but do Resize With Anchor Cells (1) - *

        - * Specifies that the current drawing shall not move with its - * row and column, but should be resized. This option is not normally - * used, but is included for completeness. - *

        - */ - DONT_MOVE_DO_RESIZE(1), - - /** - * Move With Cells but Do Not Resize (2) - *

        - * Specifies that the current drawing shall move with its - * row and column (i.e. the object is anchored to the - * actual from row and column), but that the size shall remain absolute. - *

        - *

        - * If additional rows/columns are added between the from and to locations of the drawing, - * the drawing shall move its to anchors as needed to maintain this same absolute size. - *

        - */ - MOVE_DONT_RESIZE(2), - - /** - * Do Not Move or Resize With Underlying Rows/Columns (3) - *

        - * Specifies that the current start and end positions shall - * be maintained with respect to the distances from the - * absolute start point of the worksheet. - *

        - *

        - * If additional rows/columns are added before the - * drawing, the drawing shall move its anchors as needed - * to maintain this same absolute position. - *

        - */ - DONT_MOVE_AND_RESIZE(3); - - public final short value; - - // disallow non-sequential enum instance creation - private AnchorType(int value) { - this.value = (short) value; - } - - /** - * return the AnchorType corresponding to the code - * - * @param value the anchor type code - * @return the anchor type enum - */ - @Internal - public static AnchorType byId(int value) { - return values()[value]; - } - } - - /** - * Returns the column (0 based) of the first cell. - * - * @return 0-based column of the first cell. - */ - public short getCol1(); - - /** - * Sets the column (0 based) of the first cell. - * - * @param col1 0-based column of the first cell. - */ - public void setCol1(int col1); - - /** - * Returns the column (0 based) of the second cell. - * - * @return 0-based column of the second cell. - */ - public short getCol2(); - - /** - * Returns the column (0 based) of the second cell. - * - * @param col2 0-based column of the second cell. - */ - public void setCol2(int col2); - - /** - * Returns the row (0 based) of the first cell. - * - * @return 0-based row of the first cell. - */ - public int getRow1(); - - /** - * Returns the row (0 based) of the first cell. - * - * @param row1 0-based row of the first cell. - */ - public void setRow1(int row1); - - /** - * Returns the row (0 based) of the second cell. - * - * @return 0-based row of the second cell. - */ - public int getRow2(); - - /** - * Returns the row (0 based) of the first cell. - * - * @param row2 0-based row of the first cell. - */ - public void setRow2(int row2); - - /** - * Returns the x coordinate within the first cell. - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @return the x coordinate within the first cell - */ - public int getDx1(); - - /** - * Sets the x coordinate within the first cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @param dx1 the x coordinate within the first cell - */ - public void setDx1(int dx1); - - /** - * Returns the y coordinate within the first cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @return the y coordinate within the first cell - */ - public int getDy1(); - - /** - * Sets the y coordinate within the first cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @param dy1 the y coordinate within the first cell - */ - public void setDy1(int dy1); - - /** - * Sets the y coordinate within the second cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @return the y coordinate within the second cell - */ - public int getDy2(); - - /** - * Sets the y coordinate within the second cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @param dy2 the y coordinate within the second cell - */ - public void setDy2(int dy2); - - /** - * Returns the x coordinate within the second cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @return the x coordinate within the second cell - */ - public int getDx2(); - - /** - * Sets the x coordinate within the second cell - * - * Note - XSSF and HSSF have a slightly different coordinate - * system, values in XSSF are larger by a factor of - * {@link org.apache.poi.util.Units#EMU_PER_PIXEL} - * - * @param dx2 the x coordinate within the second cell - */ - public void setDx2(int dx2); - - - /** - * Sets the anchor type - * @param anchorType the anchor type to set - * @since POI 3.14 - */ - public void setAnchorType( AnchorType anchorType ); - /** - * Sets the anchor type - * @param anchorType the anchor type to set - * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead. - */ - @Removal(version="3.17") - public void setAnchorType( int anchorType ); - - /** - * Gets the anchor type - * Changed from returning an int to an enum in POI 3.14 beta 1. - * @return the anchor type - */ - public AnchorType getAnchorType(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Color.java b/trunk/src/java/org/apache/poi/ss/usermodel/Color.java deleted file mode 100644 index 29555a184..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Color.java +++ /dev/null @@ -1,21 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -public interface Color { -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ColorScaleFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/ColorScaleFormatting.java deleted file mode 100644 index 4d6f58b58..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ColorScaleFormatting.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.hssf.record.cf.Threshold; - -/** - * High level representation for the Color Scale / Colour Scale / - * Color Gradient Formatting component of Conditional Formatting settings - */ -public interface ColorScaleFormatting { - /** - * How many control points should be used to map - * the colours? Normally 2 or 3 - */ - int getNumControlPoints(); - /** - * Sets the number of control points to use to map - * the colours. Should normally be 2 or 3. - *

        After updating, you need to ensure that the - * {@link Threshold} count and Color count match - */ - void setNumControlPoints(int num); - - /** - * Gets the list of colours that are interpolated - * between. - */ - Color[] getColors(); - /** - * Sets the list of colours that are interpolated - * between. The number must match {@link #getNumControlPoints()} - */ - void setColors(Color[] colors); - - /** - * Gets the list of thresholds - */ - ConditionalFormattingThreshold[] getThresholds(); - /** - * Sets the of thresholds. The number must match - * {@link #getNumControlPoints()} - */ - void setThresholds(ConditionalFormattingThreshold[] thresholds); - /** - * Creates a new, empty Threshold - */ - ConditionalFormattingThreshold createThreshold(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Comment.java b/trunk/src/java/org/apache/poi/ss/usermodel/Comment.java deleted file mode 100644 index c39040cfe..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Comment.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.util.CellAddress; - -public interface Comment { - - /** - * Sets whether this comment is visible. - * - * @param visible true if the comment is visible, false otherwise - */ - void setVisible(boolean visible); - - /** - * Returns whether this comment is visible. - * - * @return true if the comment is visible, false otherwise - */ - boolean isVisible(); - - /** - * Get the address of the cell that this comment is attached to - * - * @return comment cell address - * @since 3.15-beta1 - */ - CellAddress getAddress(); - - /** - * Set the address of the cell that this comment is attached to - * - * @param addr - * @since 3.15-beta1 - */ - void setAddress(CellAddress addr); - - /** - * Set the address of the cell that this comment is attached to - * - * @param row - * @param col - * @since 3.15-beta1 - */ - void setAddress(int row, int col); - - /** - * Return the row of the cell that contains the comment - * - * @return the 0-based row of the cell that contains the comment - */ - int getRow(); - - /** - * Set the row of the cell that contains the comment - * - * @param row the 0-based row of the cell that contains the comment - */ - void setRow(int row); - - /** - * Return the column of the cell that contains the comment - * - * @return the 0-based column of the cell that contains the comment - */ - int getColumn(); - - /** - * Set the column of the cell that contains the comment - * - * @param col the 0-based column of the cell that contains the comment - */ - void setColumn(int col); - - /** - * Name of the original comment author - * - * @return the name of the original author of the comment - */ - String getAuthor(); - - /** - * Name of the original comment author - * - * @param author the name of the original author of the comment - */ - void setAuthor(String author); - - /** - * Fetches the rich text string of the comment - */ - public RichTextString getString(); - - /** - * Sets the rich text string used by this comment. - * - * @param string Sets the rich text string used by this object. - */ - void setString(RichTextString string); - - /** - * Return defines position of this anchor in the sheet. - * The anchor is the yellow box/balloon that is rendered on top of the sheets - * when the comment is visible. - * - * To associate a comment with a different cell, use {@link #setAddress}. - * - * @return defines position of this anchor in the sheet - */ - public ClientAnchor getClientAnchor(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java b/trunk/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java deleted file mode 100644 index 7eee78903..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -/** - * The conditional format operators used for "Highlight Cells That Contain..." rules. - *

        - * For example, "highlight cells that begin with "M2" and contain "Mountain Gear". - *

        - */ -public final class ComparisonOperator { - public static final byte NO_COMPARISON = 0; - - /** - * 'Between' operator - */ - public static final byte BETWEEN = 1; - - /** - * 'Not between' operator - */ - public static final byte NOT_BETWEEN = 2; - - /** - * 'Equal to' operator - */ - public static final byte EQUAL = 3; - - /** - * 'Not equal to' operator - */ - public static final byte NOT_EQUAL = 4; - - /** - * 'Greater than' operator - */ - public static final byte GT = 5; - - /** - * 'Less than' operator - */ - public static final byte LT = 6; - - /** - * 'Greater than or equal to' operator - */ - public static final byte GE = 7; - - /** - * 'Less than or equal to' operator - */ - public static final byte LE = 8; -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionType.java b/trunk/src/java/org/apache/poi/ss/usermodel/ConditionType.java deleted file mode 100644 index 8bd61410e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionType.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Represents a type of a conditional formatting rule - */ -public class ConditionType { - private static Map lookup = new HashMap(); - - /** - * This conditional formatting rule compares a cell value - * to a formula calculated result, using an operator - */ - public static final ConditionType CELL_VALUE_IS = - new ConditionType(1, "cellIs"); - - /** - * This conditional formatting rule contains a formula to evaluate. - * When the formula result is true, the cell is highlighted. - */ - public static final ConditionType FORMULA = - new ConditionType(2, "expression"); - - /** - * This conditional formatting rule contains a color scale, - * with the cell background set according to a gradient. - */ - public static final ConditionType COLOR_SCALE = - new ConditionType(3, "colorScale"); - - /** - * This conditional formatting rule sets a data bar, with the - * cell populated with bars based on their values - */ - public static final ConditionType DATA_BAR = - new ConditionType(4, "dataBar"); - - /** - * This conditional formatting rule that files the values - */ - public static final ConditionType FILTER = - new ConditionType(5, null); - - /** - * This conditional formatting rule sets a data bar, with the - * cell populated with bars based on their values - */ - public static final ConditionType ICON_SET = - new ConditionType(6, "iconSet"); - - - public final byte id; - public final String type; - - public String toString() { - return id + " - " + type; - } - - - public static ConditionType forId(byte id) { - return forId((int)id); - } - public static ConditionType forId(int id) { - return lookup.get(id); - } - - private ConditionType(int id, String type) { - this.id = (byte)id; this.type = type; - lookup.put(id, this); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java deleted file mode 100644 index 09d63a407..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * The ConditionalFormatting class encapsulates all settings of Conditional Formatting. - * - * The class can be used - * - *
          - *
        • - * to make a copy ConditionalFormatting settings. - *
        • - * - * - * For example: - *
          - * ConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
          - * newSheet.addConditionalFormatting(cf);
          - * 
          - * - *
        • - * or to modify existing Conditional Formatting settings (formatting regions and/or rules). - *
        • - *
        - * - * Use {@link org.apache.poi.ss.usermodel.Sheet#getSheetConditionalFormatting()} - * to get access to an instance of this class. - *

        - * To create a new Conditional Formatting set use the following approach: - * - *

        - *
        - * // Define a Conditional Formatting rule, which triggers formatting
        - * // when cell's value is greater or equal than 100.0 and
        - * // applies patternFormatting defined below.
        - * ConditionalFormattingRule rule = sheet.createConditionalFormattingRule(
        - *     ComparisonOperator.GE,
        - *     "100.0", // 1st formula
        - *     null     // 2nd formula is not used for comparison operator GE
        - * );
        - *
        - * // Create pattern with red background
        - * PatternFormatting patternFmt = rule.cretePatternFormatting();
        - * patternFormatting.setFillBackgroundColor(IndexedColor.RED.getIndex());
        - *
        - * // Define a region containing first column
        - * Region [] regions =
        - * {
        - *     new Region(1,(short)1,-1,(short)1)
        - * };
        - *
        - * // Apply Conditional Formatting rule defined above to the regions
        - * sheet.addConditionalFormatting(regions, rule);
        - * 
        - */ -public interface ConditionalFormatting { - - /** - * @return array of CellRangeAddresss. Never null - */ - CellRangeAddress[] getFormattingRanges(); - - /** - * Sets the cell ranges the rule conditional formatting must be applied to. - * @param ranges non-null array of CellRangeAddresss - */ - void setFormattingRanges(CellRangeAddress[] ranges); - - /** - * Replaces an existing Conditional Formatting rule at position idx. - * Excel pre-2007 allows to create up to 3 Conditional Formatting rules, - * 2007 and later allow unlimited numbers. - * This method can be useful to modify existing Conditional Formatting rules. - * - * @param idx position of the rule. Should be between 0 and 2 for Excel before 2007, otherwise 0+. - * @param cfRule - Conditional Formatting rule - */ - void setRule(int idx, ConditionalFormattingRule cfRule); - - /** - * Add a Conditional Formatting rule. - * Excel pre-2007 allows to create up to 3 Conditional Formatting rules. - * - * @param cfRule - Conditional Formatting rule - */ - void addRule(ConditionalFormattingRule cfRule); - - /** - * @return the Conditional Formatting rule at position idx. - */ - ConditionalFormattingRule getRule(int idx); - - /** - * @return number of Conditional Formatting rules. - */ - int getNumberOfRules(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java b/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java deleted file mode 100644 index 28f5d2258..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -/** - * Represents a description of a conditional formatting rule - */ -public interface ConditionalFormattingRule { - /** - * Create a new border formatting structure if it does not exist, - * otherwise just return existing object. - * - * @return - border formatting object, never returns null. - */ - BorderFormatting createBorderFormatting(); - - /** - * @return - border formatting object if defined, null otherwise - */ - BorderFormatting getBorderFormatting(); - - /** - * Create a new font formatting structure if it does not exist, - * otherwise just return existing object. - * - * @return - font formatting object, never returns null. - */ - FontFormatting createFontFormatting(); - - /** - * @return - font formatting object if defined, null otherwise - */ - FontFormatting getFontFormatting(); - - /** - * Create a new pattern formatting structure if it does not exist, - * otherwise just return existing object. - * - * @return - pattern formatting object, never returns null. - */ - PatternFormatting createPatternFormatting(); - - /** - * @return - pattern formatting object if defined, null otherwise - */ - PatternFormatting getPatternFormatting(); - - /** - * @return - databar / data-bar formatting object if defined, null otherwise - */ - DataBarFormatting getDataBarFormatting(); - - /** - * @return - icon / multi-state formatting object if defined, null otherwise - */ - IconMultiStateFormatting getMultiStateFormatting(); - - /** - * @return color scale / color grate formatting object if defined, null otherwise - */ - ColorScaleFormatting getColorScaleFormatting(); - - /** - * Type of conditional formatting rule. - * - * @return the type of condition - */ - ConditionType getConditionType(); - - /** - * The comparison function used when the type of conditional formatting is set to - * {@link ConditionType#CELL_VALUE_IS} - *

        - * MUST be a constant from {@link ComparisonOperator} - *

        - * - * @return the conditional format operator - */ - byte getComparisonOperation(); - - /** - * The formula used to evaluate the first operand for the conditional formatting rule. - *

        - * If the condition type is {@link ConditionType#CELL_VALUE_IS}, - * this field is the first operand of the comparison. - * If type is {@link ConditionType#FORMULA}, this formula is used - * to determine if the conditional formatting is applied. - *

        - *

        - * If comparison type is {@link ConditionType#FORMULA} the formula MUST be a Boolean function - *

        - * - * @return the first formula - */ - String getFormula1(); - - /** - * The formula used to evaluate the second operand of the comparison when - * comparison type is {@link ConditionType#CELL_VALUE_IS} and operator - * is either {@link ComparisonOperator#BETWEEN} or {@link ComparisonOperator#NOT_BETWEEN} - * - * @return the second formula - */ - String getFormula2(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingThreshold.java b/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingThreshold.java deleted file mode 100644 index a5e52b1b3..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingThreshold.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - - -/** - * The Threshold / CFVO / Conditional Formatting Value Object. - *

        This defines how to calculate the ranges for a conditional - * formatting rule, eg which values get a Green Traffic Light - * icon and which Yellow or Red.

        - */ -public interface ConditionalFormattingThreshold { - public enum RangeType { - /** Number / Parameter */ - NUMBER(1, "num"), - /** The minimum value from the range */ - MIN(2, "min"), - /** The maximum value from the range */ - MAX(3, "max"), - /** Percent of the way from the mi to the max value in the range */ - PERCENT(4, "percent"), - /** The minimum value of the cell that is in X percentile of the range */ - PERCENTILE(5, "percentile"), - UNALLOCATED(6, null), - /** Formula result */ - FORMULA(7, "formula"); - - /** Numeric ID of the type */ - public final int id; - /** Name (system) of the type */ - public final String name; - - public String toString() { - return id + " - " + name; - } - - public static RangeType byId(int id) { - return values()[id-1]; // 1-based IDs - } - public static RangeType byName(String name) { - for (RangeType t : values()) { - if (t.name.equals(name)) return t; - } - return null; - } - - private RangeType(int id, String name) { - this.id = id; this.name = name; - } - } - - /** - * Get the Range Type used - */ - RangeType getRangeType(); - - /** - * Changes the Range Type used - * - *

        If you change the range type, you need to - * ensure that the Formula and Value parameters - * are compatible with it before saving

        - */ - void setRangeType(RangeType type); - - /** - * Formula to use to calculate the threshold, - * or null if no formula - */ - String getFormula(); - - /** - * Sets the formula used to calculate the threshold, - * or unsets it if null is given. - */ - void setFormula(String formula); - - /** - * Gets the value used for the threshold, or - * null if there isn't one. - */ - Double getValue(); - - /** - * Sets the value used for the threshold. - *

        If the type is {@link RangeType#PERCENT} or - * {@link RangeType#PERCENTILE} it must be between 0 and 100. - *

        If the type is {@link RangeType#MIN} or {@link RangeType#MAX} - * or {@link RangeType#FORMULA} it shouldn't be set. - *

        Use null to unset - */ - void setValue(Double value); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/CreationHelper.java b/trunk/src/java/org/apache/poi/ss/usermodel/CreationHelper.java deleted file mode 100644 index 53462c1d4..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/CreationHelper.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.util.Removal; - -/** - * An object that handles instantiating concrete - * classes of the various instances one needs for - * HSSF and XSSF. - * Works around a limitation in Java where we - * cannot have static methods on interfaces or abstract - * classes. - * This allows you to get the appropriate class for - * a given interface, without you having to worry - * about if you're dealing with HSSF or XSSF. - */ -public interface CreationHelper { - /** - * Creates a new RichTextString instance - * @param text The text to initialise the RichTextString with - */ - RichTextString createRichTextString(String text); - - /** - * Creates a new DataFormat instance - */ - DataFormat createDataFormat(); - - /** - * Creates a new Hyperlink, of the given type - * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. - */ - @Removal(version="3.17") - @Deprecated - Hyperlink createHyperlink(int type); - - /** - * Creates a new Hyperlink, of the given type - */ - Hyperlink createHyperlink(HyperlinkType type); - - /** - * Creates FormulaEvaluator - an object that evaluates formula cells. - * - * @return a FormulaEvaluator instance - */ - FormulaEvaluator createFormulaEvaluator(); - - /** - * Creates a XSSF-style Color object, used for extended sheet - * formattings and conditional formattings - */ - ExtendedColor createExtendedColor(); - - /** - * Creates a ClientAnchor. Use this object to position drawing object in a sheet - * - * @return a ClientAnchor instance - * @see org.apache.poi.ss.usermodel.Drawing - */ - ClientAnchor createClientAnchor(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataBarFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataBarFormatting.java deleted file mode 100644 index df9a0fef7..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataBarFormatting.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -/** - * High level representation for the DataBar Formatting - * component of Conditional Formatting settings - */ -public interface DataBarFormatting { - /** - * Is the bar drawn from Left-to-Right, or from - * Right-to-Left - */ - boolean isLeftToRight(); - /** - * Control if the bar is drawn from Left-to-Right, - * or from Right-to-Left - */ - void setLeftToRight(boolean ltr); - - /** - * Should Icon + Value be displayed, or only the Icon? - */ - boolean isIconOnly(); - /** - * Control if only the Icon is shown, or Icon + Value - */ - void setIconOnly(boolean only); - - /** - * How much of the cell width, in %, should be given to - * the min value? - */ - int getWidthMin(); - void setWidthMin(int width); - - /** - * How much of the cell width, in %, should be given to - * the max value? - */ - int getWidthMax(); - void setWidthMax(int width); - - Color getColor(); - void setColor(Color color); - - /** - * The threshold that defines "everything from here down is minimum" - */ - ConditionalFormattingThreshold getMinThreshold(); - /** - * The threshold that defines "everything from here up is maximum" - */ - ConditionalFormattingThreshold getMaxThreshold(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java deleted file mode 100644 index d40a8d11c..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.util.Beta; - -/** - * Enum mapping the values of STDataConsolidateFunction - */ -@Beta -public enum DataConsolidateFunction { - AVERAGE(1,"Average"), - COUNT(2, "Count"), - COUNT_NUMS(3, "Count"), - MAX(4, "Max"), - MIN(5, "Min"), - PRODUCT(6, "Product"), - STD_DEV(7, "StdDev"), - STD_DEVP(8, "StdDevp"), - SUM(9, "Sum"), - VAR(10, "Var"), - VARP(11, "Varp"); - - private final int value; - private final String name; - - DataConsolidateFunction(int value, String name) { - this.value = value; - this.name = name; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataFormat.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataFormat.java deleted file mode 100644 index 3728541ef..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataFormat.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -public interface DataFormat { - /** - * get the format index that matches the given format string. - * Creates a new format if one is not found. Aliases text to the proper format. - * @param format string matching a built in format - * @return index of format. - */ - short getFormat(String format); - - /** - * get the format string that matches the given format index - * @param index of a format - * @return string represented at index of format or null if there is not a format at that index - */ - String getFormat(short index); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java deleted file mode 100644 index 61a5092f2..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ /dev/null @@ -1,1197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - 2012 - Alfresco Software, Ltd. - Alfresco Software has modified source of this file - The details of changes as svn diff can be found in svn at location root/projects/3rd-party/src -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Observable; -import java.util.Observer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.ss.format.CellFormat; -import org.apache.poi.ss.format.CellFormatResult; -import org.apache.poi.ss.util.DateFormatConverter; -import org.apache.poi.ss.util.NumberToTextConverter; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - - -/** - * DataFormatter contains methods for formatting the value stored in an - * Cell. This can be useful for reports and GUI presentations when you - * need to display data exactly as it appears in Excel. Supported formats - * include currency, SSN, percentages, decimals, dates, phone numbers, zip - * codes, etc. - *

        - * Internally, formats will be implemented using subclasses of {@link Format} - * such as {@link DecimalFormat} and {@link java.text.SimpleDateFormat}. Therefore the - * formats used by this class must obey the same pattern rules as these Format - * subclasses. This means that only legal number pattern characters ("0", "#", - * ".", "," etc.) may appear in number formats. Other characters can be - * inserted before or after the number pattern to form a - * prefix or suffix. - *

        - *

        - * For example the Excel pattern "$#,##0.00 "USD"_);($#,##0.00 "USD")" - * will be correctly formatted as "$1,000.00 USD" or "($1,000.00 USD)". - * However the pattern "00-00-00" is incorrectly formatted by - * DecimalFormat as "000000--". For Excel formats that are not compatible with - * DecimalFormat, you can provide your own custom {@link Format} implementation - * via DataFormatter.addFormat(String,Format). The following - * custom formats are already provided by this class: - *

        - *
        - * 
        • SSN "000-00-0000"
        • - *
        • Phone Number "(###) ###-####"
        • - *
        • Zip plus 4 "00000-0000"
        • - *
        - *
        - *

        - * If the Excel format pattern cannot be parsed successfully, then a default - * format will be used. The default number format will mimic the Excel General - * format: "#" for whole numbers and "#.##########" for decimal numbers. You - * can override the default format pattern with - * DataFormatter.setDefaultNumberFormat(Format). Note: the - * default format will only be used when a Format cannot be created from the - * cell's data format string. - * - *

        - * Note that by default formatted numeric values are trimmed. - * Excel formats can contain spacers and padding and the default behavior is to strip them off. - *

        - *

        Example:

        - *

        - * Consider a numeric cell with a value 12.343 and format "##.##_ ". - * The trailing underscore and space ("_ ") in the format adds a space to the end and Excel formats this cell as "12.34 ", - * but DataFormatter trims the formatted value and returns "12.34". - *

        - * You can enable spaces by passing the emulateCSV=true flag in the DateFormatter cosntructor. - * If set to true, then the output tries to conform to what you get when you take an xls or xlsx in Excel and Save As CSV file: - *
          - *
        • returned values are not trimmed
        • - *
        • Invalid dates are formatted as 255 pound signs ("#")
        • - *
        • simulate Excel's handling of a format string of all # when the value is 0. - * Excel will output "", DataFormatter will output "0". - *
        - *

        - * Some formats are automatically "localized" by Excel, eg show as mm/dd/yyyy when - * loaded in Excel in some Locales but as dd/mm/yyyy in others. These are always - * returned in the "default" (US) format, as stored in the file. - * Some format strings request an alternate locale, eg - * [$-809]d/m/yy h:mm AM/PM which explicitly requests UK locale. - * These locale directives are (currently) ignored. - * You can use {@link DateFormatConverter} to do some of this localisation if - * you need it. - */ -public class DataFormatter implements Observer { - private static final String defaultFractionWholePartFormat = "#"; - private static final String defaultFractionFractionPartFormat = "#/##"; - /** Pattern to find a number format: "0" or "#" */ - private static final Pattern numPattern = Pattern.compile("[0#]+"); - - /** Pattern to find days of week as text "ddd...." */ - private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE); - - /** Pattern to find "AM/PM" marker */ - private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE); - - /** - * A regex to find locale patterns like [$$-1009] and [$?-452]. - * Note that we don't currently process these into locales - */ - private static final Pattern localePatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])"); - - /** - * A regex to match the colour formattings rules. - * Allowed colours are: Black, Blue, Cyan, Green, - * Magenta, Red, White, Yellow, "Color n" (1<=n<=56) - */ - private static final Pattern colorPattern = - Pattern.compile("(\\[BLACK\\])|(\\[BLUE\\])|(\\[CYAN\\])|(\\[GREEN\\])|" + - "(\\[MAGENTA\\])|(\\[RED\\])|(\\[WHITE\\])|(\\[YELLOW\\])|" + - "(\\[COLOR\\s*\\d\\])|(\\[COLOR\\s*[0-5]\\d\\])", Pattern.CASE_INSENSITIVE); - - /** - * A regex to identify a fraction pattern. - * This requires that replaceAll("\\?", "#") has already been called - */ - private static final Pattern fractionPattern = Pattern.compile("(?:([#\\d]+)\\s+)?(#+)\\s*\\/\\s*([#\\d]+)"); - - /** - * A regex to strip junk out of fraction formats - */ - private static final Pattern fractionStripper = Pattern.compile("(\"[^\"]*\")|([^ \\?#\\d\\/]+)"); - - /** - * A regex to detect if an alternate grouping character is used - * in a numeric format - */ - private static final Pattern alternateGrouping = Pattern.compile("([#0]([^.#0])[#0]{3})"); - - /** - * Cells formatted with a date or time format and which contain invalid date or time values - * show 255 pound signs ("#"). - */ - private static final String invalidDateTimeString; - static { - StringBuilder buf = new StringBuilder(); - for(int i = 0; i < 255; i++) buf.append('#'); - invalidDateTimeString = buf.toString(); - } - - /** - * The decimal symbols of the locale used for formatting values. - */ - private DecimalFormatSymbols decimalSymbols; - - /** - * The date symbols of the locale used for formatting values. - */ - private DateFormatSymbols dateSymbols; - - /** - * A default date format, if no date format was given - */ - private DateFormat defaultDateformat; - - /** General format for numbers. */ - private Format generalNumberFormat; - - /** A default format to use when a number pattern cannot be parsed. */ - private Format defaultNumFormat; - - /** - * A map to cache formats. - * Map formats - */ - private final Map formats = new HashMap(); - - private final boolean emulateCSV; - - /** stores the locale valid it the last formatting call */ - private Locale locale; - - /** stores if the locale should change according to {@link LocaleUtil#getUserLocale()} */ - private boolean localeIsAdapting; - - private class LocaleChangeObservable extends Observable { - void checkForLocaleChange() { - checkForLocaleChange(LocaleUtil.getUserLocale()); - } - void checkForLocaleChange(Locale newLocale) { - if (!localeIsAdapting) return; - if (newLocale.equals(locale)) return; - super.setChanged(); - notifyObservers(newLocale); - } - } - - /** the Observable to notify, when the locale has been changed */ - private final LocaleChangeObservable localeChangedObservable = new LocaleChangeObservable(); - - /** For logging any problems we find */ - private static POILogger logger = POILogFactory.getLogger(DataFormatter.class); - - /** - * Creates a formatter using the {@link Locale#getDefault() default locale}. - */ - public DataFormatter() { - this(false); - } - - /** - * Creates a formatter using the {@link Locale#getDefault() default locale}. - * - * @param emulateCSV whether to emulate CSV output. - */ - public DataFormatter(boolean emulateCSV) { - this(LocaleUtil.getUserLocale(), true, emulateCSV); - } - - /** - * Creates a formatter using the given locale. - */ - public DataFormatter(Locale locale) { - this(locale, false); - } - - /** - * Creates a formatter using the given locale. - * - * @param emulateCSV whether to emulate CSV output. - */ - public DataFormatter(Locale locale, boolean emulateCSV) { - this(locale, false, emulateCSV); - } - - /** - * Creates a formatter using the given locale. - * @param localeIsAdapting (true only if locale is not user-specified) - * @param emulateCSV whether to emulate CSV output. - */ - private DataFormatter(Locale locale, boolean localeIsAdapting, boolean emulateCSV) { - this.localeIsAdapting = true; - localeChangedObservable.addObserver(this); - // localeIsAdapting must be true prior to this first checkForLocaleChange call. - localeChangedObservable.checkForLocaleChange(locale); - // set localeIsAdapting so subsequent checks perform correctly - // (whether a specific locale was provided to this DataFormatter or DataFormatter should - // adapt to the current user locale as the locale changes) - this.localeIsAdapting = localeIsAdapting; - this.emulateCSV = emulateCSV; - } - - /** - * Return a Format for the given cell if one exists, otherwise try to - * create one. This method will return null if the any of the - * following is true: - *

          - *
        • the cell's style is null
        • - *
        • the style's data format string is null or empty
        • - *
        • the format string cannot be recognized as either a number or date
        • - *
        - * - * @param cell The cell to retrieve a Format for - * @return A Format for the format String - */ - private Format getFormat(Cell cell) { - if ( cell.getCellStyle() == null) { - return null; - } - - int formatIndex = cell.getCellStyle().getDataFormat(); - String formatStr = cell.getCellStyle().getDataFormatString(); - if(formatStr == null || formatStr.trim().length() == 0) { - return null; - } - return getFormat(cell.getNumericCellValue(), formatIndex, formatStr); - } - - private Format getFormat(double cellValue, int formatIndex, String formatStrIn) { - localeChangedObservable.checkForLocaleChange(); - -// // Might be better to separate out the n p and z formats, falling back to p when n and z are not set. -// // That however would require other code to be re factored. -// String[] formatBits = formatStrIn.split(";"); -// int i = cellValue > 0.0 ? 0 : cellValue < 0.0 ? 1 : 2; -// String formatStr = (i < formatBits.length) ? formatBits[i] : formatBits[0]; - - String formatStr = formatStrIn; - - // Excel supports 3+ part conditional data formats, eg positive/negative/zero, - // or (>1000),(>0),(0),(negative). As Java doesn't handle these kinds - // of different formats for different ranges, just +ve/-ve, we need to - // handle these ourselves in a special way. - // For now, if we detect 3+ parts, we call out to CellFormat to handle it - // TODO Going forward, we should really merge the logic between the two classes - if (formatStr.contains(";") && - formatStr.indexOf(';') != formatStr.lastIndexOf(';')) { - try { - // Ask CellFormat to get a formatter for it - CellFormat cfmt = CellFormat.getInstance(formatStr); - // CellFormat requires callers to identify date vs not, so do so - Object cellValueO = Double.valueOf(cellValue); - if (DateUtil.isADateFormat(formatIndex, formatStr) && - // don't try to handle Date value 0, let a 3 or 4-part format take care of it - ((Double)cellValueO).doubleValue() != 0.0) { - cellValueO = DateUtil.getJavaDate(cellValue); - } - // Wrap and return (non-cachable - CellFormat does that) - return new CellFormatResultWrapper( cfmt.apply(cellValueO) ); - } catch (Exception e) { - logger.log(POILogger.WARN, "Formatting failed for format " + formatStr + ", falling back", e); - } - } - - // Excel's # with value 0 will output empty where Java will output 0. This hack removes the # from the format. - if (emulateCSV && cellValue == 0.0 && formatStr.contains("#") && !formatStr.contains("0")) { - formatStr = formatStr.replaceAll("#", ""); - } - - // See if we already have it cached - Format format = formats.get(formatStr); - if (format != null) { - return format; - } - - // Is it one of the special built in types, General or @? - if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) { - return generalNumberFormat; - } - - // Build a formatter, and cache it - format = createFormat(cellValue, formatIndex, formatStr); - formats.put(formatStr, format); - return format; - } - - /** - * Create and return a Format based on the format string from a cell's - * style. If the pattern cannot be parsed, return a default pattern. - * - * @param cell The Excel cell - * @return A Format representing the excel format. May return null. - */ - public Format createFormat(Cell cell) { - - int formatIndex = cell.getCellStyle().getDataFormat(); - String formatStr = cell.getCellStyle().getDataFormatString(); - return createFormat(cell.getNumericCellValue(), formatIndex, formatStr); - } - - private Format createFormat(double cellValue, int formatIndex, String sFormat) { - localeChangedObservable.checkForLocaleChange(); - - String formatStr = sFormat; - - // Remove colour formatting if present - Matcher colourM = colorPattern.matcher(formatStr); - while(colourM.find()) { - String colour = colourM.group(); - - // Paranoid replacement... - int at = formatStr.indexOf(colour); - if(at == -1) break; - String nFormatStr = formatStr.substring(0,at) + - formatStr.substring(at+colour.length()); - if(nFormatStr.equals(formatStr)) break; - - // Try again in case there's multiple - formatStr = nFormatStr; - colourM = colorPattern.matcher(formatStr); - } - - // Strip off the locale information, we use an instance-wide locale for everything - Matcher m = localePatternGroup.matcher(formatStr); - while(m.find()) { - String match = m.group(); - String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-')); - if (symbol.indexOf('$') > -1) { - symbol = symbol.substring(0, symbol.indexOf('$')) + - '\\' + - symbol.substring(symbol.indexOf('$'), symbol.length()); - } - formatStr = m.replaceAll(symbol); - m = localePatternGroup.matcher(formatStr); - } - - // Check for special cases - if(formatStr == null || formatStr.trim().length() == 0) { - return getDefaultFormat(cellValue); - } - - if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) { - return generalNumberFormat; - } - - if(DateUtil.isADateFormat(formatIndex,formatStr) && - DateUtil.isValidExcelDate(cellValue)) { - return createDateFormat(formatStr, cellValue); - } - // Excel supports fractions in format strings, which Java doesn't - if (formatStr.contains("#/") || formatStr.contains("?/")) { - String[] chunks = formatStr.split(";"); - for (String chunk1 : chunks) { - String chunk = chunk1.replaceAll("\\?", "#"); - Matcher matcher = fractionStripper.matcher(chunk); - chunk = matcher.replaceAll(" "); - chunk = chunk.replaceAll(" +", " "); - Matcher fractionMatcher = fractionPattern.matcher(chunk); - //take the first match - if (fractionMatcher.find()) { - String wholePart = (fractionMatcher.group(1) == null) ? "" : defaultFractionWholePartFormat; - return new FractionFormat(wholePart, fractionMatcher.group(3)); - } - } - - // Strip custom text in quotes and escaped characters for now as it can cause performance problems in fractions. - //String strippedFormatStr = formatStr.replaceAll("\\\\ ", " ").replaceAll("\\\\.", "").replaceAll("\"[^\"]*\"", " ").replaceAll("\\?", "#"); - //System.out.println("formatStr: "+strippedFormatStr); - return new FractionFormat(defaultFractionWholePartFormat, defaultFractionFractionPartFormat); - } - - if (numPattern.matcher(formatStr).find()) { - return createNumberFormat(formatStr, cellValue); - } - - if (emulateCSV) { - return new ConstantStringFormat(cleanFormatForNumber(formatStr)); - } - // TODO - when does this occur? - return null; - } - - - - private Format createDateFormat(String pFormatStr, double cellValue) { - String formatStr = pFormatStr; - formatStr = formatStr.replaceAll("\\\\-","-"); - formatStr = formatStr.replaceAll("\\\\,",","); - formatStr = formatStr.replaceAll("\\\\\\.","."); // . is a special regexp char - formatStr = formatStr.replaceAll("\\\\ "," "); - formatStr = formatStr.replaceAll("\\\\/","/"); // weird: m\\/d\\/yyyy - formatStr = formatStr.replaceAll(";@", ""); - formatStr = formatStr.replaceAll("\"/\"", "/"); // "/" is escaped for no reason in: mm"/"dd"/"yyyy - formatStr = formatStr.replace("\"\"", "'"); // replace Excel quoting with Java style quoting - formatStr = formatStr.replaceAll("\\\\T","'T'"); // Quote the T is iso8601 style dates - - - boolean hasAmPm = false; - Matcher amPmMatcher = amPmPattern.matcher(formatStr); - while (amPmMatcher.find()) { - formatStr = amPmMatcher.replaceAll("@"); - hasAmPm = true; - amPmMatcher = amPmPattern.matcher(formatStr); - } - formatStr = formatStr.replaceAll("@", "a"); - - - Matcher dateMatcher = daysAsText.matcher(formatStr); - if (dateMatcher.find()) { - String match = dateMatcher.group(0).toUpperCase(Locale.ROOT).replaceAll("D", "E"); - formatStr = dateMatcher.replaceAll(match); - } - - // Convert excel date format to SimpleDateFormat. - // Excel uses lower and upper case 'm' for both minutes and months. - // From Excel help: - /* - The "m" or "mm" code must appear immediately after the "h" or"hh" - code or immediately before the "ss" code; otherwise, Microsoft - Excel displays the month instead of minutes." - */ - - StringBuilder sb = new StringBuilder(); - char[] chars = formatStr.toCharArray(); - boolean mIsMonth = true; - List ms = new ArrayList(); - boolean isElapsed = false; - for(int j=0; j 0 && sb.charAt((i - 1)) == '\\') { - // It's escaped, don't worry - continue; - } - if (c == '?') { - sb.setCharAt(i, ' '); - } else if (i < sb.length() - 1) { - // Remove the character we're supposed - // to match the space of / pad to the - // column width with - if (c == '_') { - sb.setCharAt(i + 1, ' '); - } else { - sb.deleteCharAt(i + 1); - } - // Remove the character too - sb.deleteCharAt(i); - i--; - } - } - } - } else { - // If they requested spacers, with "_", - // remove those as we don't do spacing - // If they requested full-column-width - // padding, with "*", remove those too - for (int i = 0; i < sb.length(); i++) { - char c = sb.charAt(i); - if (c == '_' || c == '*') { - if (i > 0 && sb.charAt((i - 1)) == '\\') { - // It's escaped, don't worry - continue; - } - if (i < sb.length() - 1) { - // Remove the character we're supposed - // to match the space of / pad to the - // column width with - sb.deleteCharAt(i + 1); - } - // Remove the _ too - sb.deleteCharAt(i); - i--; - } - } - } - - // Now, handle the other aspects like - // quoting and scientific notation - for(int i = 0; i < sb.length(); i++) { - char c = sb.charAt(i); - // remove quotes and back slashes - if (c == '\\' || c == '"') { - sb.deleteCharAt(i); - i--; - - // for scientific/engineering notation - } else if (c == '+' && i > 0 && sb.charAt(i - 1) == 'E') { - sb.deleteCharAt(i); - i--; - } - } - - return sb.toString(); - } - - private Format createNumberFormat(String formatStr, double cellValue) { - String format = cleanFormatForNumber(formatStr); - DecimalFormatSymbols symbols = decimalSymbols; - - // Do we need to change the grouping character? - // eg for a format like #'##0 which wants 12'345 not 12,345 - Matcher agm = alternateGrouping.matcher(format); - if (agm.find()) { - char grouping = agm.group(2).charAt(0); - // Only replace the grouping character if it is not the default - // grouping character for the US locale (',') in order to enable - // correct grouping for non-US locales. - if (grouping!=',') { - symbols = DecimalFormatSymbols.getInstance(locale); - - symbols.setGroupingSeparator(grouping); - String oldPart = agm.group(1); - String newPart = oldPart.replace(grouping, ','); - format = format.replace(oldPart, newPart); - } - } - - try { - DecimalFormat df = new DecimalFormat(format, symbols); - setExcelStyleRoundingMode(df); - return df; - } catch(IllegalArgumentException iae) { - - // the pattern could not be parsed correctly, - // so fall back to the default number format - return getDefaultFormat(cellValue); - } - } - - /** - * Returns a default format for a cell. - * @param cell The cell - * @return a default format - */ - public Format getDefaultFormat(Cell cell) { - return getDefaultFormat(cell.getNumericCellValue()); - } - private Format getDefaultFormat(double cellValue) { - localeChangedObservable.checkForLocaleChange(); - - // for numeric cells try user supplied default - if (defaultNumFormat != null) { - return defaultNumFormat; - - // otherwise use general format - } - return generalNumberFormat; - } - - /** - * Performs Excel-style date formatting, using the - * supplied Date and format - */ - private String performDateFormatting(Date d, Format dateFormat) { - return (dateFormat != null ? dateFormat : defaultDateformat).format(d); - } - - /** - * Returns the formatted value of an Excel date as a String based - * on the cell's DataFormat. i.e. "Thursday, January 02, 2003" - * , "01/02/2003" , "02-Jan" , etc. - * - * @param cell The cell - * @return a formatted date string - */ - private String getFormattedDateString(Cell cell) { - Format dateFormat = getFormat(cell); - if(dateFormat instanceof ExcelStyleDateFormatter) { - // Hint about the raw excel value - ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted( - cell.getNumericCellValue() - ); - } - Date d = cell.getDateCellValue(); - return performDateFormatting(d, dateFormat); - } - - /** - * Returns the formatted value of an Excel number as a String - * based on the cell's DataFormat. Supported formats include - * currency, percents, decimals, phone number, SSN, etc.: - * "61.54%", "$100.00", "(800) 555-1234". - * - * @param cell The cell - * @return a formatted number string - */ - private String getFormattedNumberString(Cell cell) { - - Format numberFormat = getFormat(cell); - double d = cell.getNumericCellValue(); - if (numberFormat == null) { - return String.valueOf(d); - } - String formatted = numberFormat.format(new Double(d)); - return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation - } - - /** - * Formats the given raw cell value, based on the supplied - * format index and string, according to excel style rules. - * @see #formatCellValue(Cell) - */ - public String formatRawCellContents(double value, int formatIndex, String formatString) { - return formatRawCellContents(value, formatIndex, formatString, false); - } - /** - * Formats the given raw cell value, based on the supplied - * format index and string, according to excel style rules. - * @see #formatCellValue(Cell) - */ - public String formatRawCellContents(double value, int formatIndex, String formatString, boolean use1904Windowing) { - localeChangedObservable.checkForLocaleChange(); - - // Is it a date? - if(DateUtil.isADateFormat(formatIndex,formatString)) { - if(DateUtil.isValidExcelDate(value)) { - Format dateFormat = getFormat(value, formatIndex, formatString); - if(dateFormat instanceof ExcelStyleDateFormatter) { - // Hint about the raw excel value - ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(value); - } - Date d = DateUtil.getJavaDate(value, use1904Windowing); - return performDateFormatting(d, dateFormat); - } - // RK: Invalid dates are 255 #s. - if (emulateCSV) { - return invalidDateTimeString; - } - } - - // else Number - Format numberFormat = getFormat(value, formatIndex, formatString); - if (numberFormat == null) { - return String.valueOf(value); - } - - // When formatting 'value', double to text to BigDecimal produces more - // accurate results than double to Double in JDK8 (as compared to - // previous versions). However, if the value contains E notation, this - // would expand the values, which we do not want, so revert to - // original method. - String result; - final String textValue = NumberToTextConverter.toText(value); - if (textValue.indexOf('E') > -1) { - result = numberFormat.format(new Double(value)); - } - else { - result = numberFormat.format(new BigDecimal(textValue)); - } - // Complete scientific notation by adding the missing +. - if (result.indexOf('E') > -1 && !result.contains("E-")) { - result = result.replaceFirst("E", "E+"); - } - return result; - } - - /** - *

        - * Returns the formatted value of a cell as a String regardless - * of the cell type. If the Excel format pattern cannot be parsed then the - * cell value will be formatted using a default format. - *

        - *

        When passed a null or blank cell, this method will return an empty - * String (""). Formulas in formula type cells will not be evaluated. - *

        - * - * @param cell The cell - * @return the formatted cell value as a String - */ - public String formatCellValue(Cell cell) { - return formatCellValue(cell, null); - } - - /** - *

        - * Returns the formatted value of a cell as a String regardless - * of the cell type. If the Excel format pattern cannot be parsed then the - * cell value will be formatted using a default format. - *

        - *

        When passed a null or blank cell, this method will return an empty - * String (""). Formula cells will be evaluated using the given - * {@link FormulaEvaluator} if the evaluator is non-null. If the - * evaluator is null, then the formula String will be returned. The caller - * is responsible for setting the currentRow on the evaluator - *

        - * - * @param cell The cell (can be null) - * @param evaluator The FormulaEvaluator (can be null) - * @return a string value of the cell - */ - public String formatCellValue(Cell cell, FormulaEvaluator evaluator) { - localeChangedObservable.checkForLocaleChange(); - - if (cell == null) { - return ""; - } - - CellType cellType = cell.getCellTypeEnum(); - if (cellType == CellType.FORMULA) { - if (evaluator == null) { - return cell.getCellFormula(); - } - cellType = evaluator.evaluateFormulaCellEnum(cell); - } - switch (cellType) { - case NUMERIC : - - if (DateUtil.isCellDateFormatted(cell)) { - return getFormattedDateString(cell); - } - return getFormattedNumberString(cell); - - case STRING : - return cell.getRichStringCellValue().getString(); - - case BOOLEAN : - return cell.getBooleanCellValue() ? "TRUE" : "FALSE"; - case BLANK : - return ""; - case ERROR: - return FormulaError.forInt(cell.getErrorCellValue()).getString(); - default: - throw new RuntimeException("Unexpected celltype (" + cellType + ")"); - } - } - - - /** - *

        - * Sets a default number format to be used when the Excel format cannot be - * parsed successfully. Note: This is a fall back for when an error - * occurs while parsing an Excel number format pattern. This will not - * affect cells with the General format. - *

        - *

        - * The value that will be passed to the Format's format method (specified - * by java.text.Format#format) will be a double value from a - * numeric cell. Therefore the code in the format method should expect a - * Number value. - *

        - * - * @param format A Format instance to be used as a default - * @see java.text.Format#format - */ - public void setDefaultNumberFormat(Format format) { - for (Map.Entry entry : formats.entrySet()) { - if (entry.getValue() == generalNumberFormat) { - entry.setValue(format); - } - } - defaultNumFormat = format; - } - - /** - * Adds a new format to the available formats. - *

        - * The value that will be passed to the Format's format method (specified - * by java.text.Format#format) will be a double value from a - * numeric cell. Therefore the code in the format method should expect a - * Number value. - *

        - * @param excelFormatStr The data format string - * @param format A Format instance - */ - public void addFormat(String excelFormatStr, Format format) { - formats.put(excelFormatStr, format); - } - - // Some custom formats - - /** - * @return a DecimalFormat with parseIntegerOnly set true - */ - private static DecimalFormat createIntegerOnlyFormat(String fmt) { - DecimalFormatSymbols dsf = DecimalFormatSymbols.getInstance(Locale.ROOT); - DecimalFormat result = new DecimalFormat(fmt, dsf); - result.setParseIntegerOnly(true); - return result; - } - - /** - * Enables excel style rounding mode (round half up) on the - * Decimal Format given. - */ - public static void setExcelStyleRoundingMode(DecimalFormat format) { - setExcelStyleRoundingMode(format, RoundingMode.HALF_UP); - } - - /** - * Enables custom rounding mode on the given Decimal Format. - * @param format DecimalFormat - * @param roundingMode RoundingMode - */ - public static void setExcelStyleRoundingMode(DecimalFormat format, RoundingMode roundingMode) { - format.setRoundingMode(roundingMode); - } - - /** - * If the Locale has been changed via {@link LocaleUtil#setUserLocale(Locale)} the stored - * formats need to be refreshed. All formats which aren't originated from DataFormatter - * itself, i.e. all Formats added via {@link DataFormatter#addFormat(String, Format)} and - * {@link DataFormatter#setDefaultNumberFormat(Format)}, need to be added again. - * To notify callers, the returned {@link Observable} should be used. - * The Object in {@link Observer#update(Observable, Object)} is the new Locale. - * - * @return the listener object, where callers can register themselves - */ - public Observable getLocaleChangedObservable() { - return localeChangedObservable; - } - - /** - * Update formats when locale has been changed - * - * @param observable usually this is our own Observable instance - * @param localeObj only reacts on Locale objects - */ - public void update(Observable observable, Object localeObj) { - if (!(localeObj instanceof Locale)) return; - Locale newLocale = (Locale)localeObj; - if (!localeIsAdapting || newLocale.equals(locale)) return; - - locale = newLocale; - - dateSymbols = DateFormatSymbols.getInstance(locale); - decimalSymbols = DecimalFormatSymbols.getInstance(locale); - generalNumberFormat = new ExcelGeneralNumberFormat(locale); - - // taken from Date.toString() - defaultDateformat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dateSymbols); - defaultDateformat.setTimeZone(LocaleUtil.getUserTimeZone()); - - // init built-in formats - - formats.clear(); - Format zipFormat = ZipPlusFourFormat.instance; - addFormat("00000\\-0000", zipFormat); - addFormat("00000-0000", zipFormat); - - Format phoneFormat = PhoneFormat.instance; - // allow for format string variations - addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); - addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat); - addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); - addFormat("###-####;(###) ###-####", phoneFormat); - - Format ssnFormat = SSNFormat.instance; - addFormat("000\\-00\\-0000", ssnFormat); - addFormat("000-00-0000", ssnFormat); - } - - - - /** - * Format class for Excel's SSN format. This class mimics Excel's built-in - * SSN formatting. - * - * @author James May - */ - @SuppressWarnings("serial") - private static final class SSNFormat extends Format { - public static final Format instance = new SSNFormat(); - private static final DecimalFormat df = createIntegerOnlyFormat("000000000"); - private SSNFormat() { - // enforce singleton - } - - /** Format a number as an SSN */ - public static String format(Number num) { - String result = df.format(num); - return result.substring(0, 3) + '-' + - result.substring(3, 5) + '-' + - result.substring(5, 9); - } - - @Override - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - @Override - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } - - /** - * Format class for Excel Zip + 4 format. This class mimics Excel's - * built-in formatting for Zip + 4. - * @author James May - */ - @SuppressWarnings("serial") - private static final class ZipPlusFourFormat extends Format { - public static final Format instance = new ZipPlusFourFormat(); - private static final DecimalFormat df = createIntegerOnlyFormat("000000000"); - private ZipPlusFourFormat() { - // enforce singleton - } - - /** Format a number as Zip + 4 */ - public static String format(Number num) { - String result = df.format(num); - return result.substring(0, 5) + '-' + - result.substring(5, 9); - } - - @Override - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - @Override - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } - - /** - * Format class for Excel phone number format. This class mimics Excel's - * built-in phone number formatting. - * @author James May - */ - @SuppressWarnings("serial") - private static final class PhoneFormat extends Format { - public static final Format instance = new PhoneFormat(); - private static final DecimalFormat df = createIntegerOnlyFormat("##########"); - private PhoneFormat() { - // enforce singleton - } - - /** Format a number as a phone number */ - public static String format(Number num) { - String result = df.format(num); - StringBuilder sb = new StringBuilder(); - String seg1, seg2, seg3; - int len = result.length(); - if (len <= 4) { - return result; - } - - seg3 = result.substring(len - 4, len); - seg2 = result.substring(Math.max(0, len - 7), len - 4); - seg1 = result.substring(Math.max(0, len - 10), Math.max(0, len - 7)); - - if(seg1.trim().length() > 0) { - sb.append('(').append(seg1).append(") "); - } - if(seg2.trim().length() > 0) { - sb.append(seg2).append('-'); - } - sb.append(seg3); - return sb.toString(); - } - - @Override - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - @Override - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } - - - - - /** - * Format class that does nothing and always returns a constant string. - * - * This format is used to simulate Excel's handling of a format string - * of all # when the value is 0. Excel will output "", Java will output "0". - * - * @see DataFormatter#createFormat(double, int, String) - */ - @SuppressWarnings("serial") - private static final class ConstantStringFormat extends Format { - private static final DecimalFormat df = createIntegerOnlyFormat("##########"); - private final String str; - public ConstantStringFormat(String s) { - str = s; - } - - @Override - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(str); - } - - @Override - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } - /** - * Workaround until we merge {@link DataFormatter} with {@link CellFormat}. - * Constant, non-cachable wrapper around a {@link CellFormatResult} - */ - @SuppressWarnings("serial") - private final class CellFormatResultWrapper extends Format { - private final CellFormatResult result; - private CellFormatResultWrapper(CellFormatResult result) { - this.result = result; - } - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - if (emulateCSV) { - return toAppendTo.append(result.text); - } else { - return toAppendTo.append(result.text.trim()); - } - } - public Object parseObject(String source, ParsePosition pos) { - return null; // Not supported - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataValidation.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataValidation.java deleted file mode 100644 index c80ed6a74..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataValidation.java +++ /dev/null @@ -1,152 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.util.CellRangeAddressList; - - -public interface DataValidation { - /** - * Error style constants for error box - */ - public static final class ErrorStyle { - /** STOP style */ - public static final int STOP = 0x00; - /** WARNING style */ - public static final int WARNING = 0x01; - /** INFO style */ - public static final int INFO = 0x02; - } - - public abstract DataValidationConstraint getValidationConstraint(); - - /** - * Sets the error style for error box - * @see ErrorStyle - */ - public abstract void setErrorStyle(int error_style); - - /**o - * @return the error style of error box - * @see ErrorStyle - */ - public abstract int getErrorStyle(); - - /** - * Sets if this object allows empty as a valid value - * - * @param allowed true if this object should treats empty as valid value , false - * otherwise - */ - public abstract void setEmptyCellAllowed(boolean allowed); - - /** - * Retrieve the settings for empty cells allowed - * - * @return True if this object should treats empty as valid value , false - * otherwise - */ - public abstract boolean getEmptyCellAllowed(); - - /** - * Useful for list validation objects . - * - * @param suppress - * True if a list should display the values into a drop down list , - * false otherwise . In other words , if a list should display - * the arrow sign on its right side - */ - public abstract void setSuppressDropDownArrow(boolean suppress); - - /** - * Useful only list validation objects . This method always returns false if - * the object isn't a list validation object - * - * @return true if a list should display the values into a drop down list , - * false otherwise . - */ - public abstract boolean getSuppressDropDownArrow(); - - /** - * Sets the behaviour when a cell which belongs to this object is selected - * - * @param show true if an prompt box should be displayed , false otherwise - */ - public abstract void setShowPromptBox(boolean show); - - /** - * @return true if an prompt box should be displayed , false otherwise - */ - public abstract boolean getShowPromptBox(); - - /** - * Sets the behaviour when an invalid value is entered - * - * @param show true if an error box should be displayed , false otherwise - */ - public abstract void setShowErrorBox(boolean show); - - /** - * @return true if an error box should be displayed , false otherwise - */ - public abstract boolean getShowErrorBox(); - - /** - * Sets the title and text for the prompt box . Prompt box is displayed when - * the user selects a cell which belongs to this validation object . In - * order for a prompt box to be displayed you should also use method - * setShowPromptBox( boolean show ) - * - * @param title The prompt box's title - * @param text The prompt box's text - */ - public abstract void createPromptBox(String title, String text); - - /** - * @return Prompt box's title or null - */ - public abstract String getPromptBoxTitle(); - - /** - * @return Prompt box's text or null - */ - public abstract String getPromptBoxText(); - - /** - * Sets the title and text for the error box . Error box is displayed when - * the user enters an invalid value int o a cell which belongs to this - * validation object . In order for an error box to be displayed you should - * also use method setShowErrorBox( boolean show ) - * - * @param title The error box's title - * @param text The error box's text - */ - public abstract void createErrorBox(String title, String text); - - /** - * @return Error box's title or null - */ - public abstract String getErrorBoxTitle(); - - /** - * @return Error box's text or null - */ - public abstract String getErrorBoxText(); - - public abstract CellRangeAddressList getRegions(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataValidationConstraint.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataValidationConstraint.java deleted file mode 100644 index 38f78e868..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataValidationConstraint.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - - -public interface DataValidationConstraint { - - /** - * @return data validation type of this constraint - * @see ValidationType - */ - public abstract int getValidationType(); - - /** - * @return the operator used for this constraint - * @see OperatorType - */ - public abstract int getOperator(); - - /** - * Sets the comparison operator for this constraint - * @see OperatorType - */ - public abstract void setOperator(int operator); - - /** - * If validation type is {@link ValidationType#LIST} - * and formula1 was comma-separated literal values rather than a range or named range, - * returns list of literal values. - * Otherwise returns null. - */ - public abstract String[] getExplicitListValues(); - - public abstract void setExplicitListValues(String[] explicitListValues); - - /** - * @return the formula for expression 1. May be null - */ - public abstract String getFormula1(); - - /** - * Sets a formula for expression 1. - */ - public abstract void setFormula1(String formula1); - - /** - * @return the formula for expression 2. May be null - */ - public abstract String getFormula2(); - - /** - * Sets a formula for expression 2. - */ - public abstract void setFormula2(String formula2); - - /** - * ValidationType enum - */ - public static final class ValidationType { - private ValidationType() { - // no instances of this class - } - /** 'Any value' type - value not restricted */ - public static final int ANY = 0x00; - /** Integer ('Whole number') type */ - public static final int INTEGER = 0x01; - /** Decimal type */ - public static final int DECIMAL = 0x02; - /** List type ( combo box type ) */ - public static final int LIST = 0x03; - /** Date type */ - public static final int DATE = 0x04; - /** Time type */ - public static final int TIME = 0x05; - /** String length type */ - public static final int TEXT_LENGTH = 0x06; - /** Formula ( 'Custom' ) type */ - public static final int FORMULA = 0x07; - } - /** - * Condition operator enum - */ - public static final class OperatorType { - private OperatorType() { - // no instances of this class - } - - public static final int BETWEEN = 0x00; - public static final int NOT_BETWEEN = 0x01; - public static final int EQUAL = 0x02; - public static final int NOT_EQUAL = 0x03; - public static final int GREATER_THAN = 0x04; - public static final int LESS_THAN = 0x05; - public static final int GREATER_OR_EQUAL = 0x06; - public static final int LESS_OR_EQUAL = 0x07; - /** default value to supply when the operator type is not used */ - public static final int IGNORED = BETWEEN; - - /* package */ public static void validateSecondArg(int comparisonOperator, String paramValue) { - switch (comparisonOperator) { - case BETWEEN: - case NOT_BETWEEN: - if (paramValue == null) { - throw new IllegalArgumentException("expr2 must be supplied for 'between' comparisons"); - } - // all other operators don't need second arg - } - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DataValidationHelper.java b/trunk/src/java/org/apache/poi/ss/usermodel/DataValidationHelper.java deleted file mode 100644 index 2e749467e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DataValidationHelper.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.util.CellRangeAddressList; - -/** - * @author Radhakrishnan J - * - */ -public interface DataValidationHelper { - - DataValidationConstraint createFormulaListConstraint(String listFormula); - - DataValidationConstraint createExplicitListConstraint(String[] listOfValues); - - DataValidationConstraint createNumericConstraint(int validationType,int operatorType, String formula1, String formula2); - - DataValidationConstraint createTextLengthConstraint(int operatorType, String formula1, String formula2); - - DataValidationConstraint createDecimalConstraint(int operatorType, String formula1, String formula2); - - DataValidationConstraint createIntegerConstraint(int operatorType, String formula1, String formula2); - - DataValidationConstraint createDateConstraint(int operatorType, String formula1, String formula2,String dateFormat); - - DataValidationConstraint createTimeConstraint(int operatorType, String formula1, String formula2); - - DataValidationConstraint createCustomConstraint(String formula); - - DataValidation createValidation(DataValidationConstraint constraint,CellRangeAddressList cellRangeAddressList); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java b/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java deleted file mode 100644 index f4e4cc575..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java +++ /dev/null @@ -1,682 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.ss.usermodel; - -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; -import java.util.regex.Pattern; - -import org.apache.poi.util.LocaleUtil; - -/** - * Contains methods for dealing with Excel dates. - */ -public class DateUtil { - protected DateUtil() { - // no instances of this class - } - - public static final int SECONDS_PER_MINUTE = 60; - public static final int MINUTES_PER_HOUR = 60; - public static final int HOURS_PER_DAY = 24; - public static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE); - - private static final int BAD_DATE = -1; // used to specify that date is invalid - public static final long DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L; - - private static final Pattern TIME_SEPARATOR_PATTERN = Pattern.compile(":"); - - /** - * The following patterns are used in {@link #isADateFormat(int, String)} - */ - private static final Pattern date_ptrn1 = Pattern.compile("^\\[\\$\\-.*?\\]"); - private static final Pattern date_ptrn2 = Pattern.compile("^\\[[a-zA-Z]+\\]"); - private static final Pattern date_ptrn3a = Pattern.compile("[yYmMdDhHsS]"); - private static final Pattern date_ptrn3b = Pattern.compile("^[\\[\\]yYmMdDhHsS\\-T/,. :\"\\\\]+0*[ampAMP/]*$"); - // elapsed time patterns: [h],[m] and [s] - private static final Pattern date_ptrn4 = Pattern.compile("^\\[([hH]+|[mM]+|[sS]+)\\]"); - - /** - * Given a Date, converts it into a double representing its internal Excel representation, - * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. - * - * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) - * @param date the Date - */ - public static double getExcelDate(Date date) { - return getExcelDate(date, false); - } - /** - * Given a Date, converts it into a double representing its internal Excel representation, - * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. - * - * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) - * @param date the Date - * @param use1904windowing Should 1900 or 1904 date windowing be used? - */ - public static double getExcelDate(Date date, boolean use1904windowing) { - Calendar calStart = LocaleUtil.getLocaleCalendar(); - calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0 - return internalGetExcelDate(calStart, use1904windowing); - } - /** - * Given a Date in the form of a Calendar, converts it into a double - * representing its internal Excel representation, which is the - * number of days since 1/1/1900. Fractional days represent hours, - * minutes, and seconds. - * - * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) - * @param date the Calendar holding the date to convert - * @param use1904windowing Should 1900 or 1904 date windowing be used? - */ - public static double getExcelDate(Calendar date, boolean use1904windowing) { - // Don't alter the supplied Calendar as we do our work - return internalGetExcelDate( (Calendar)date.clone(), use1904windowing ); - } - private static double internalGetExcelDate(Calendar date, boolean use1904windowing) { - if ((!use1904windowing && date.get(Calendar.YEAR) < 1900) || - (use1904windowing && date.get(Calendar.YEAR) < 1904)) - { - return BAD_DATE; - } - // Because of daylight time saving we cannot use - // date.getTime() - calStart.getTimeInMillis() - // as the difference in milliseconds between 00:00 and 04:00 - // can be 3, 4 or 5 hours but Excel expects it to always - // be 4 hours. - // E.g. 2004-03-28 04:00 CEST - 2004-03-28 00:00 CET is 3 hours - // and 2004-10-31 04:00 CET - 2004-10-31 00:00 CEST is 5 hours - double fraction = (((date.get(Calendar.HOUR_OF_DAY) * 60 - + date.get(Calendar.MINUTE) - ) * 60 + date.get(Calendar.SECOND) - ) * 1000 + date.get(Calendar.MILLISECOND) - ) / ( double ) DAY_MILLISECONDS; - Calendar calStart = dayStart(date); - - double value = fraction + absoluteDay(calStart, use1904windowing); - - if (!use1904windowing && value >= 60) { - value++; - } else if (use1904windowing) { - value--; - } - - return value; - } - - /** - * Given an Excel date with using 1900 date windowing, and - * converts it to a java.util.Date. - * - * Excel Dates and Times are stored without any timezone - * information. If you know (through other means) that your file - * uses a different TimeZone to the system default, you can use - * this version of the getJavaDate() method to handle it. - * - * @param date The Excel date. - * @param tz The TimeZone to evaluate the date in - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Date getJavaDate(double date, TimeZone tz) { - return getJavaDate(date, false, tz, false); - } - /** - * Given an Excel date with using 1900 date windowing, and - * converts it to a java.util.Date. - * - * NOTE: If the default TimeZone in Java uses Daylight - * Saving Time then the conversion back to an Excel date may not give - * the same value, that is the comparison - * excelDate == getExcelDate(getJavaDate(excelDate,false)) - * is not always true. For example if default timezone is - * Europe/Copenhagen, on 2004-03-28 the minute after - * 01:59 CET is 03:00 CEST, if the excel date represents a time between - * 02:00 and 03:00 then it is converted to past 03:00 summer time - * - * @param date The Excel date. - * @return Java representation of the date, or null if date is not a valid Excel date - * @see java.util.TimeZone - */ - public static Date getJavaDate(double date) { - return getJavaDate(date, false, null, false); - } - - /** - * Given an Excel date with either 1900 or 1904 date windowing, - * converts it to a java.util.Date. - * - * Excel Dates and Times are stored without any timezone - * information. If you know (through other means) that your file - * uses a different TimeZone to the system default, you can use - * this version of the getJavaDate() method to handle it. - * - * @param date The Excel date. - * @param tz The TimeZone to evaluate the date in - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Date getJavaDate(double date, boolean use1904windowing, TimeZone tz) { - return getJavaDate(date, use1904windowing, tz, false); - } - - /** - * Given an Excel date with either 1900 or 1904 date windowing, - * converts it to a java.util.Date. - * - * Excel Dates and Times are stored without any timezone - * information. If you know (through other means) that your file - * uses a different TimeZone to the system default, you can use - * this version of the getJavaDate() method to handle it. - * - * @param date The Excel date. - * @param tz The TimeZone to evaluate the date in - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @param roundSeconds round to closest second - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Date getJavaDate(double date, boolean use1904windowing, TimeZone tz, boolean roundSeconds) { - Calendar calendar = getJavaCalendar(date, use1904windowing, tz, roundSeconds); - return calendar == null ? null : calendar.getTime(); - } - - /** - * Given an Excel date with either 1900 or 1904 date windowing, - * converts it to a java.util.Date. - * - * NOTE: If the default TimeZone in Java uses Daylight - * Saving Time then the conversion back to an Excel date may not give - * the same value, that is the comparison - * excelDate == getExcelDate(getJavaDate(excelDate,false)) - * is not always true. For example if default timezone is - * Europe/Copenhagen, on 2004-03-28 the minute after - * 01:59 CET is 03:00 CEST, if the excel date represents a time between - * 02:00 and 03:00 then it is converted to past 03:00 summer time - * - * @param date The Excel date. - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @return Java representation of the date, or null if date is not a valid Excel date - * @see java.util.TimeZone - */ - public static Date getJavaDate(double date, boolean use1904windowing) { - return getJavaDate(date, use1904windowing, null, false); - } - - public static void setCalendar(Calendar calendar, int wholeDays, - int millisecondsInDay, boolean use1904windowing, boolean roundSeconds) { - int startYear = 1900; - int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't - if (use1904windowing) { - startYear = 1904; - dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day - } - else if (wholeDays < 61) { - // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists - // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation - dayAdjust = 0; - } - calendar.set(startYear,0, wholeDays + dayAdjust, 0, 0, 0); - calendar.set(Calendar.MILLISECOND, millisecondsInDay); - if (calendar.get(Calendar.MILLISECOND) == 0) { - calendar.clear(Calendar.MILLISECOND); - } - if (roundSeconds) { - calendar.add(Calendar.MILLISECOND, 500); - calendar.clear(Calendar.MILLISECOND); - } - } - - - /** - * Get EXCEL date as Java Calendar (with default time zone). - * This is like {@link #getJavaDate(double)} but returns a Calendar object. - * @param date The Excel date. - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Calendar getJavaCalendar(double date) { - return getJavaCalendar(date, false, (TimeZone)null, false); - } - - /** - * Get EXCEL date as Java Calendar (with default time zone). - * This is like {@link #getJavaDate(double, boolean)} but returns a Calendar object. - * @param date The Excel date. - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Calendar getJavaCalendar(double date, boolean use1904windowing) { - return getJavaCalendar(date, use1904windowing, (TimeZone)null, false); - } - - /** - * Get EXCEL date as Java Calendar with UTC time zone. - * This is similar to {@link #getJavaDate(double, boolean)} but returns a - * Calendar object that has UTC as time zone, so no daylight saving hassle. - * @param date The Excel date. - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @return Java representation of the date in UTC, or null if date is not a valid Excel date - */ - public static Calendar getJavaCalendarUTC(double date, boolean use1904windowing) { - return getJavaCalendar(date, use1904windowing, LocaleUtil.TIMEZONE_UTC, false); - } - - - /** - * Get EXCEL date as Java Calendar with given time zone. - * @param date The Excel date. - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @param timeZone The TimeZone to evaluate the date in - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Calendar getJavaCalendar(double date, boolean use1904windowing, TimeZone timeZone) { - return getJavaCalendar(date, use1904windowing, timeZone, false); - } - - /** - * Get EXCEL date as Java Calendar with given time zone. - * @param date The Excel date. - * @param use1904windowing true if date uses 1904 windowing, - * or false if using 1900 date windowing. - * @param timeZone The TimeZone to evaluate the date in - * @param roundSeconds round to closest second - * @return Java representation of the date, or null if date is not a valid Excel date - */ - public static Calendar getJavaCalendar(double date, boolean use1904windowing, TimeZone timeZone, boolean roundSeconds) { - if (!isValidExcelDate(date)) { - return null; - } - int wholeDays = (int)Math.floor(date); - int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5); - Calendar calendar; - if (timeZone != null) { - calendar = LocaleUtil.getLocaleCalendar(timeZone); - } else { - calendar = LocaleUtil.getLocaleCalendar(); // using default time-zone - } - setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing, roundSeconds); - return calendar; - } - - // variables for performance optimization: - // avoid re-checking DataUtil.isADateFormat(int, String) if a given format - // string represents a date format if the same string is passed multiple times. - // see https://issues.apache.org/bugzilla/show_bug.cgi?id=55611 - private static ThreadLocal lastFormatIndex = new ThreadLocal() { - protected Integer initialValue() { - return -1; - } - }; - private static ThreadLocal lastFormatString = new ThreadLocal(); - private static ThreadLocal lastCachedResult = new ThreadLocal(); - - private static boolean isCached(String formatString, int formatIndex) { - String cachedFormatString = lastFormatString.get(); - return cachedFormatString != null && formatIndex == lastFormatIndex.get() - && formatString.equals(cachedFormatString); - } - - private static void cache(String formatString, int formatIndex, boolean cached) { - lastFormatIndex.set(formatIndex); - lastFormatString.set(formatString); - lastCachedResult.set(Boolean.valueOf(cached)); - } - - /** - * Given a format ID and its format String, will check to see if the - * format represents a date format or not. - * Firstly, it will check to see if the format ID corresponds to an - * internal excel date format (eg most US date formats) - * If not, it will check to see if the format string only contains - * date formatting characters (ymd-/), which covers most - * non US date formats. - * - * @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex - * @param formatString The format string, eg from FormatRecord.getFormatString - * @see #isInternalDateFormat(int) - */ - - public static boolean isADateFormat(int formatIndex, String formatString) { - // First up, is this an internal date format? - if(isInternalDateFormat(formatIndex)) { - cache(formatString, formatIndex, true); - return true; - } - - // If we didn't get a real string, don't even cache it as we can always find this out quickly - if(formatString == null || formatString.length() == 0) { - return false; - } - - // check the cache first - if (isCached(formatString, formatIndex)) { - return lastCachedResult.get(); - } - - String fs = formatString; - /*if (false) { - // Normalize the format string. The code below is equivalent - // to the following consecutive regexp replacements: - - // Translate \- into just -, before matching - fs = fs.replaceAll("\\\\-","-"); - // And \, into , - fs = fs.replaceAll("\\\\,",","); - // And \. into . - fs = fs.replaceAll("\\\\\\.","."); - // And '\ ' into ' ' - fs = fs.replaceAll("\\\\ "," "); - - // If it end in ;@, that's some crazy dd/mm vs mm/dd - // switching stuff, which we can ignore - fs = fs.replaceAll(";@", ""); - - // The code above was reworked as suggested in bug 48425: - // simple loop is more efficient than consecutive regexp replacements. - }*/ - final int length = fs.length(); - StringBuilder sb = new StringBuilder(length); - for (int i = 0; i < length; i++) { - char c = fs.charAt(i); - if (i < length - 1) { - char nc = fs.charAt(i + 1); - if (c == '\\') { - switch (nc) { - case '-': - case ',': - case '.': - case ' ': - case '\\': - // skip current '\' and continue to the next char - continue; - } - } else if (c == ';' && nc == '@') { - i++; - // skip ";@" duplets - continue; - } - } - sb.append(c); - } - fs = sb.toString(); - - // short-circuit if it indicates elapsed time: [h], [m] or [s] - if(date_ptrn4.matcher(fs).matches()){ - cache(formatString, formatIndex, true); - return true; - } - - // If it starts with [$-...], then could be a date, but - // who knows what that starting bit is all about - fs = date_ptrn1.matcher(fs).replaceAll(""); - // If it starts with something like [Black] or [Yellow], - // then it could be a date - fs = date_ptrn2.matcher(fs).replaceAll(""); - // You're allowed something like dd/mm/yy;[red]dd/mm/yy - // which would place dates before 1900/1904 in red - // For now, only consider the first one - final int separatorIndex = fs.indexOf(';'); - if(0 < separatorIndex && separatorIndex < fs.length()-1) { - fs = fs.substring(0, separatorIndex); - } - - // Ensure it has some date letters in it - // (Avoids false positives on the rest of pattern 3) - if (! date_ptrn3a.matcher(fs).find()) { - return false; - } - - // If we get here, check it's only made up, in any case, of: - // y m d h s - \ / , . : [ ] T - // optionally followed by AM/PM - - boolean result = date_ptrn3b.matcher(fs).matches(); - cache(formatString, formatIndex, result); - return result; - } - - /** - * Given a format ID this will check whether the format represents - * an internal excel date format or not. - * @see #isADateFormat(int, java.lang.String) - */ - public static boolean isInternalDateFormat(int format) { - switch(format) { - // Internal Date Formats as described on page 427 in - // Microsoft Excel Dev's Kit... - case 0x0e: - case 0x0f: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x2d: - case 0x2e: - case 0x2f: - return true; - } - return false; - } - - /** - * Check if a cell contains a date - * Since dates are stored internally in Excel as double values - * we infer it is a date if it is formatted as such. - * @see #isADateFormat(int, String) - * @see #isInternalDateFormat(int) - */ - public static boolean isCellDateFormatted(Cell cell) { - if (cell == null) return false; - boolean bDate = false; - - double d = cell.getNumericCellValue(); - if ( DateUtil.isValidExcelDate(d) ) { - CellStyle style = cell.getCellStyle(); - if(style==null) return false; - int i = style.getDataFormat(); - String f = style.getDataFormatString(); - bDate = isADateFormat(i, f); - } - return bDate; - } - /** - * Check if a cell contains a date, checking only for internal - * excel date formats. - * As Excel stores a great many of its dates in "non-internal" - * date formats, you will not normally want to use this method. - * @see #isADateFormat(int,String) - * @see #isInternalDateFormat(int) - */ - public static boolean isCellInternalDateFormatted(Cell cell) { - if (cell == null) return false; - boolean bDate = false; - - double d = cell.getNumericCellValue(); - if ( DateUtil.isValidExcelDate(d) ) { - CellStyle style = cell.getCellStyle(); - int i = style.getDataFormat(); - bDate = isInternalDateFormat(i); - } - return bDate; - } - - - /** - * Given a double, checks if it is a valid Excel date. - * - * @return true if valid - * @param value the double value - */ - - public static boolean isValidExcelDate(double value) - { - return (value > -Double.MIN_VALUE); - } - - /** - * Given a Calendar, return the number of days since 1900/12/31. - * - * @return days number of days since 1900/12/31 - * @param cal the Calendar - * @exception IllegalArgumentException if date is invalid - */ - protected static int absoluteDay(Calendar cal, boolean use1904windowing) - { - return cal.get(Calendar.DAY_OF_YEAR) - + daysInPriorYears(cal.get(Calendar.YEAR), use1904windowing); - } - - /** - * Return the number of days in prior years since 1900 - * - * @return days number of days in years prior to yr. - * @param yr a year (1900 < yr < 4000) - * @param use1904windowing - * @exception IllegalArgumentException if year is outside of range. - */ - - private static int daysInPriorYears(int yr, boolean use1904windowing) - { - if ((!use1904windowing && yr < 1900) || (use1904windowing && yr < 1904)) { - throw new IllegalArgumentException("'year' must be 1900 or greater"); - } - - int yr1 = yr - 1; - int leapDays = yr1 / 4 // plus julian leap days in prior years - - yr1 / 100 // minus prior century years - + yr1 / 400 // plus years divisible by 400 - - 460; // leap days in previous 1900 years - - return 365 * (yr - (use1904windowing ? 1904 : 1900)) + leapDays; - } - - // set HH:MM:SS fields of cal to 00:00:00:000 - private static Calendar dayStart(final Calendar cal) - { - cal.get(Calendar - .HOUR_OF_DAY); // force recalculation of internal fields - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - cal.get(Calendar - .HOUR_OF_DAY); // force recalculation of internal fields - return cal; - } - - - @SuppressWarnings("serial") - private static final class FormatException extends Exception { - public FormatException(String msg) { - super(msg); - } - } - - /** - * Converts a string of format "HH:MM" or "HH:MM:SS" to its (Excel) numeric equivalent - * - * @return a double between 0 and 1 representing the fraction of the day - */ - public static double convertTime(String timeStr) { - try { - return convertTimeInternal(timeStr); - } catch (FormatException e) { - String msg = "Bad time format '" + timeStr - + "' expected 'HH:MM' or 'HH:MM:SS' - " + e.getMessage(); - throw new IllegalArgumentException(msg); - } - } - private static double convertTimeInternal(String timeStr) throws FormatException { - int len = timeStr.length(); - if (len < 4 || len > 8) { - throw new FormatException("Bad length"); - } - String[] parts = TIME_SEPARATOR_PATTERN.split(timeStr); - - String secStr; - switch (parts.length) { - case 2: secStr = "00"; break; - case 3: secStr = parts[2]; break; - default: - throw new FormatException("Expected 2 or 3 fields but got (" + parts.length + ")"); - } - String hourStr = parts[0]; - String minStr = parts[1]; - int hours = parseInt(hourStr, "hour", HOURS_PER_DAY); - int minutes = parseInt(minStr, "minute", MINUTES_PER_HOUR); - int seconds = parseInt(secStr, "second", SECONDS_PER_MINUTE); - - double totalSeconds = seconds + (minutes + (hours) * 60) * 60; - return totalSeconds / (SECONDS_PER_DAY); - } - /** - * Converts a string of format "YYYY/MM/DD" to its (Excel) numeric equivalent - * - * @return a double representing the (integer) number of days since the start of the Excel epoch - */ - public static Date parseYYYYMMDDDate(String dateStr) { - try { - return parseYYYYMMDDDateInternal(dateStr); - } catch (FormatException e) { - String msg = "Bad time format " + dateStr - + " expected 'YYYY/MM/DD' - " + e.getMessage(); - throw new IllegalArgumentException(msg); - } - } - private static Date parseYYYYMMDDDateInternal(String timeStr) throws FormatException { - if(timeStr.length() != 10) { - throw new FormatException("Bad length"); - } - - String yearStr = timeStr.substring(0, 4); - String monthStr = timeStr.substring(5, 7); - String dayStr = timeStr.substring(8, 10); - int year = parseInt(yearStr, "year", Short.MIN_VALUE, Short.MAX_VALUE); - int month = parseInt(monthStr, "month", 1, 12); - int day = parseInt(dayStr, "day", 1, 31); - - Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day); - return cal.getTime(); - } - private static int parseInt(String strVal, String fieldName, int rangeMax) throws FormatException { - return parseInt(strVal, fieldName, 0, rangeMax-1); - } - - private static int parseInt(String strVal, String fieldName, int lowerLimit, int upperLimit) throws FormatException { - int result; - try { - result = Integer.parseInt(strVal); - } catch (NumberFormatException e) { - throw new FormatException("Bad int format '" + strVal + "' for " + fieldName + " field"); - } - if (result < lowerLimit || result > upperLimit) { - throw new FormatException(fieldName + " value (" + result - + ") is outside the allowable range(0.." + upperLimit + ")"); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java b/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java deleted file mode 100644 index aaf56606e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * High level representation of spreadsheet drawing. - * @author Yegor Kozlov - * @author Roman Kashitsyn - */ -public interface Drawing { - /** - * 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. - * - * @return the newly created picture. - */ - Picture createPicture(ClientAnchor anchor, int pictureIndex); - - /** - * Creates a comment. - * @param anchor the client anchor describes how this comment is attached - * to the sheet. - * @return the newly created comment. - */ - Comment createCellComment(ClientAnchor anchor); - - /** - * Creates a chart. - * @param anchor the client anchor describes how this chart is attached to - * the sheet. - * @return the newly created chart - */ - Chart createChart(ClientAnchor anchor); - - /** - * Creates a new client anchor and sets the top-left and bottom-right - * coordinates of the anchor. - * - * @param dx1 the x coordinate in EMU within the first cell. - * @param dy1 the y coordinate in EMU within the first cell. - * @param dx2 the x coordinate in EMU within the second cell. - * @param dy2 the y coordinate in EMU 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. - * @return the newly created client anchor - */ - ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java b/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java deleted file mode 100644 index 2efbb3ff0..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - 2012 - Alfresco Software, Ltd. - Alfresco Software has modified source of this file - The details of changes as svn diff can be found in svn at location root/projects/3rd-party/src -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; -import java.util.Locale; - -/** - * A format that formats a double as Excel would, ignoring FieldPosition. - * All other operations are unsupported. - **/ -public class ExcelGeneralNumberFormat extends Format { - - private static final long serialVersionUID = 1L; - - private static final MathContext TO_10_SF = new MathContext(10, RoundingMode.HALF_UP); - - private final DecimalFormatSymbols decimalSymbols; - private final DecimalFormat integerFormat; - private final DecimalFormat decimalFormat; - private final DecimalFormat scientificFormat; - - public ExcelGeneralNumberFormat(final Locale locale) { - decimalSymbols = DecimalFormatSymbols.getInstance(locale); - scientificFormat = new DecimalFormat("0.#####E0", decimalSymbols); - DataFormatter.setExcelStyleRoundingMode(scientificFormat); - integerFormat = new DecimalFormat("#", decimalSymbols); - DataFormatter.setExcelStyleRoundingMode(integerFormat); - decimalFormat = new DecimalFormat("#.##########", decimalSymbols); - DataFormatter.setExcelStyleRoundingMode(decimalFormat); - } - - public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) { - final double value; - if (number instanceof Number) { - value = ((Number)number).doubleValue(); - if (Double.isInfinite(value) || Double.isNaN(value)) { - return integerFormat.format(number, toAppendTo, pos); - } - } else { - // testBug54786 gets here with a date, so retain previous behaviour - return integerFormat.format(number, toAppendTo, pos); - } - - final double abs = Math.abs(value); - if (abs >= 1E11 || (abs <= 1E-10 && abs > 0)) { - return scientificFormat.format(number, toAppendTo, pos); - } else if (Math.floor(value) == value || abs >= 1E10) { - // integer, or integer portion uses all 11 allowed digits - return integerFormat.format(number, toAppendTo, pos); - } - // Non-integers of non-scientific magnitude are formatted as "up to 11 - // numeric characters, with the decimal point counting as a numeric - // character". We know there is a decimal point, so limit to 10 digits. - // https://support.microsoft.com/en-us/kb/65903 - final double rounded = new BigDecimal(value).round(TO_10_SF).doubleValue(); - return decimalFormat.format(rounded, toAppendTo, pos); - } - - public Object parseObject(String source, ParsePosition pos) { - throw new UnsupportedOperationException(); - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java b/trunk/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java deleted file mode 100644 index 5f37bce45..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.util.*; - -import org.apache.poi.util.LocaleUtil; - -import java.math.RoundingMode; -import java.text.*; - -/** - * A wrapper around a {@link SimpleDateFormat} instance, - * which handles a few Excel-style extensions that - * are not supported by {@link SimpleDateFormat}. - * Currently, the extensions are around the handling - * of elapsed time, eg rendering 1 day 2 hours - * as 26 hours. - */ -public class ExcelStyleDateFormatter extends SimpleDateFormat { - public static final char MMMMM_START_SYMBOL = '\ue001'; - public static final char MMMMM_TRUNCATE_SYMBOL = '\ue002'; - public static final char H_BRACKET_SYMBOL = '\ue010'; - public static final char HH_BRACKET_SYMBOL = '\ue011'; - public static final char M_BRACKET_SYMBOL = '\ue012'; - public static final char MM_BRACKET_SYMBOL = '\ue013'; - public static final char S_BRACKET_SYMBOL = '\ue014'; - public static final char SS_BRACKET_SYMBOL = '\ue015'; - public static final char L_BRACKET_SYMBOL = '\ue016'; - public static final char LL_BRACKET_SYMBOL = '\ue017'; - - private static final DecimalFormat format1digit; - private static final DecimalFormat format2digits; - - private static final DecimalFormat format3digit; - private static final DecimalFormat format4digits; - - static { - DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(Locale.ROOT); - format1digit = new DecimalFormat("0", dfs); - format2digits = new DecimalFormat("00", dfs); - format3digit = new DecimalFormat("0", dfs); - format4digits = new DecimalFormat("00", dfs); - DataFormatter.setExcelStyleRoundingMode(format1digit, RoundingMode.DOWN); - DataFormatter.setExcelStyleRoundingMode(format2digits, RoundingMode.DOWN); - DataFormatter.setExcelStyleRoundingMode(format3digit); - DataFormatter.setExcelStyleRoundingMode(format4digits); - } - - { - setTimeZone(LocaleUtil.getUserTimeZone()); - } - - private double dateToBeFormatted = 0.0; - - // no-arg constructor is private because of undefined super call with locale - - public ExcelStyleDateFormatter(String pattern) { - super(processFormatPattern(pattern), LocaleUtil.getUserLocale()); - } - - public ExcelStyleDateFormatter(String pattern, - DateFormatSymbols formatSymbols) { - super(processFormatPattern(pattern), formatSymbols); - } - - public ExcelStyleDateFormatter(String pattern, Locale locale) { - super(processFormatPattern(pattern), locale); - } - - /** - * Takes a format String, and replaces Excel specific bits - * with our detection sequences - */ - private static String processFormatPattern(String f) { - String t = f.replaceAll("MMMMM", MMMMM_START_SYMBOL + "MMM" + MMMMM_TRUNCATE_SYMBOL); - t = t.replaceAll("\\[H\\]", String.valueOf(H_BRACKET_SYMBOL)); - t = t.replaceAll("\\[HH\\]", String.valueOf(HH_BRACKET_SYMBOL)); - t = t.replaceAll("\\[m\\]", String.valueOf(M_BRACKET_SYMBOL)); - t = t.replaceAll("\\[mm\\]", String.valueOf(MM_BRACKET_SYMBOL)); - t = t.replaceAll("\\[s\\]", String.valueOf(S_BRACKET_SYMBOL)); - t = t.replaceAll("\\[ss\\]", String.valueOf(SS_BRACKET_SYMBOL)); - t = t.replaceAll("s.000", "s.SSS"); - t = t.replaceAll("s.00", "s." + LL_BRACKET_SYMBOL); - t = t.replaceAll("s.0", "s." + L_BRACKET_SYMBOL); - return t; - } - - /** - * Used to let us know what the date being - * formatted is, in Excel terms, which we - * may wish to use when handling elapsed - * times. - */ - public void setDateToBeFormatted(double date) { - this.dateToBeFormatted = date; - } - - @Override - public StringBuffer format(Date date, StringBuffer paramStringBuffer, - FieldPosition paramFieldPosition) { - // Do the normal format - String s = super.format(date, paramStringBuffer, paramFieldPosition).toString(); - - // Now handle our special cases - if (s.indexOf(MMMMM_START_SYMBOL) != -1) { - s = s.replaceAll( - MMMMM_START_SYMBOL + "(\\w)\\w+" + MMMMM_TRUNCATE_SYMBOL, - "$1" - ); - } - - if (s.indexOf(H_BRACKET_SYMBOL) != -1 || - s.indexOf(HH_BRACKET_SYMBOL) != -1) { - float hours = (float) dateToBeFormatted * 24; - - s = s.replaceAll( - String.valueOf(H_BRACKET_SYMBOL), - format1digit.format(hours) - ); - s = s.replaceAll( - String.valueOf(HH_BRACKET_SYMBOL), - format2digits.format(hours) - ); - } - - if (s.indexOf(M_BRACKET_SYMBOL) != -1 || - s.indexOf(MM_BRACKET_SYMBOL) != -1) { - float minutes = (float) dateToBeFormatted * 24 * 60; - s = s.replaceAll( - String.valueOf(M_BRACKET_SYMBOL), - format1digit.format(minutes) - ); - s = s.replaceAll( - String.valueOf(MM_BRACKET_SYMBOL), - format2digits.format(minutes) - ); - } - if (s.indexOf(S_BRACKET_SYMBOL) != -1 || - s.indexOf(SS_BRACKET_SYMBOL) != -1) { - float seconds = (float) (dateToBeFormatted * 24.0 * 60.0 * 60.0); - s = s.replaceAll( - String.valueOf(S_BRACKET_SYMBOL), - format1digit.format(seconds) - ); - s = s.replaceAll( - String.valueOf(SS_BRACKET_SYMBOL), - format2digits.format(seconds) - ); - } - - if (s.indexOf(L_BRACKET_SYMBOL) != -1 || - s.indexOf(LL_BRACKET_SYMBOL) != -1) { - float millisTemp = (float) ((dateToBeFormatted - Math.floor(dateToBeFormatted)) * 24.0 * 60.0 * 60.0); - float millis = (millisTemp - (int) millisTemp); - s = s.replaceAll( - String.valueOf(L_BRACKET_SYMBOL), - format3digit.format(millis * 10) - ); - s = s.replaceAll( - String.valueOf(LL_BRACKET_SYMBOL), - format4digits.format(millis * 100) - ); - } - - return new StringBuffer(s); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof ExcelStyleDateFormatter)) { - return false; - } - - ExcelStyleDateFormatter other = (ExcelStyleDateFormatter) o; - return dateToBeFormatted == other.dateToBeFormatted; - } - - @Override - public int hashCode() { - return new Double(dateToBeFormatted).hashCode(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java b/trunk/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java deleted file mode 100644 index 2259bbfc2..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java +++ /dev/null @@ -1,254 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.util.Locale; - -import org.apache.poi.hssf.util.HSSFColor; - -/** - * Represents a XSSF-style color (based on either a - * {@link org.apache.poi.xssf.usermodel.XSSFColor} or a - * {@link org.apache.poi.hssf.record.common.ExtendedColor} - */ -public abstract class ExtendedColor implements Color { - protected void setColor(java.awt.Color clr) { - setRGB(new byte[]{(byte)clr.getRed(), (byte)clr.getGreen(), (byte)clr.getBlue()}); - } - - /** - * A boolean value indicating the color is automatic - */ - public abstract boolean isAuto(); - - /** - * A boolean value indicating the color is indexed - */ - public abstract boolean isIndexed(); - - /** - * A boolean value indicating the color is RGB / ARGB - */ - public abstract boolean isRGB(); - - /** - * A boolean value indicating the color is from a Theme - */ - public abstract boolean isThemed(); - - /** - * Indexed Color value, if {@link #isIndexed()} is true - */ - public abstract short getIndex(); - - /** - * Index of Theme color, if {@link #isThemed()} is true - */ - public abstract int getTheme(); - - /** - * Standard Red Green Blue ctColor value (RGB). - * If there was an A (Alpha) value, it will be stripped. - */ - public abstract byte[] getRGB(); - /** - * Standard Alpha Red Green Blue ctColor value (ARGB). - */ - public abstract byte[] getARGB(); - - /** - * RGB or ARGB or null - */ - protected abstract byte[] getStoredRBG(); - - /** - * Sets the Red Green Blue or Alpha Red Green Blue - */ - public abstract void setRGB(byte[] rgb); - - protected byte[] getRGBOrARGB() { - if (isIndexed() && getIndex() > 0) { - int indexNum = getIndex(); - HSSFColor indexed = HSSFColor.getIndexHash().get(indexNum); - if (indexed != null) { - byte[] rgb = new byte[3]; - rgb[0] = (byte) indexed.getTriplet()[0]; - rgb[1] = (byte) indexed.getTriplet()[1]; - rgb[2] = (byte) indexed.getTriplet()[2]; - return rgb; - } - } - - // Grab the colour - return getStoredRBG(); - } - - /** - * Standard Red Green Blue ctColor value (RGB) with applied tint. - * Alpha values are ignored. - */ - public byte[] getRGBWithTint() { - byte[] rgb = getStoredRBG(); - if (rgb != null) { - if(rgb.length == 4) { - byte[] tmp = new byte[3]; - System.arraycopy(rgb, 1, tmp, 0, 3); - rgb = tmp; - } - double tint = getTint(); - for (int i = 0; i < rgb.length; i++){ - rgb[i] = applyTint(rgb[i] & 0xFF, tint); - } - } - return rgb; - } - - /** - * Return the ARGB value in hex format, eg FF00FF00. - * Works for both regular and indexed colours. - */ - public String getARGBHex() { - byte[] rgb = getARGB(); - if(rgb == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - for(byte c : rgb) { - int i = c & 0xff; - String cs = Integer.toHexString(i); - if(cs.length() == 1) { - sb.append('0'); - } - sb.append(cs); - } - return sb.toString().toUpperCase(Locale.ROOT); - } - - /** - * Sets the ARGB value from hex format, eg FF0077FF. - * Only works for regular (non-indexed) colours - */ - public void setARGBHex(String argb) { - if (argb.length() == 6 || argb.length() == 8) { - byte[] rgb = new byte[argb.length()/2]; - for (int i=0; i 0){ - return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint))); - } else if (tint < 0){ - return (byte)(lum*(1+tint)); - } else { - return (byte)lum; - } - } - - /** - * Specifies the tint value applied to the ctColor. - * - *

        - * If tint is supplied, then it is applied to the RGB value of the ctColor to determine the final - * ctColor applied. - *

        - *

        - * The tint value is stored as a double from -1.0 .. 1.0, where -1.0 means 100% darken and - * 1.0 means 100% lighten. Also, 0.0 means no change. - *

        - *

        - * In loading the RGB value, it is converted to HLS where HLS values are (0..HLSMAX), where - * HLSMAX is currently 255. - *

        - * Here are some examples of how to apply tint to ctColor: - *
        - *
        -     * If (tint < 0)
        -     * Lum' = Lum * (1.0 + tint)
        -     *
        -     * For example: Lum = 200; tint = -0.5; Darken 50%
        -     * Lum' = 200 * (0.5) => 100
        -     * For example: Lum = 200; tint = -1.0; Darken 100% (make black)
        -     * Lum' = 200 * (1.0-1.0) => 0
        -     * If (tint > 0)
        -     * Lum' = Lum * (1.0-tint) + (HLSMAX - HLSMAX * (1.0-tint))
        -     * For example: Lum = 100; tint = 0.75; Lighten 75%
        -     *
        -     * Lum' = 100 * (1-.75) + (HLSMAX - HLSMAX*(1-.75))
        -     * = 100 * .25 + (255 - 255 * .25)
        -     * = 25 + (255 - 63) = 25 + 192 = 217
        -     * For example: Lum = 100; tint = 1.0; Lighten 100% (make white)
        -     * Lum' = 100 * (1-1) + (HLSMAX - HLSMAX*(1-1))
        -     * = 100 * 0 + (255 - 255 * 0)
        -     * = 0 + (255 - 0) = 255
        -     * 
        - *
        - * - * @return the tint value - */ - public abstract double getTint(); - - /** - * Specifies the tint value applied to the ctColor. - * - *

        - * If tint is supplied, then it is applied to the RGB value of the ctColor to determine the final - * ctColor applied. - *

        - *

        - * The tint value is stored as a double from -1.0 .. 1.0, where -1.0 means 100% darken and - * 1.0 means 100% lighten. Also, 0.0 means no change. - *

        - *

        - * In loading the RGB value, it is converted to HLS where HLS values are (0..HLSMAX), where - * HLSMAX is currently 255. - *

        - * Here are some examples of how to apply tint to ctColor: - *
        - *
        -     * If (tint < 0)
        -     * Lum' = Lum * (1.0 + tint)
        -     *
        -     * For example: Lum = 200; tint = -0.5; Darken 50%
        -     * Lum' = 200 * (0.5) => 100
        -     * For example: Lum = 200; tint = -1.0; Darken 100% (make black)
        -     * Lum' = 200 * (1.0-1.0) => 0
        -     * If (tint > 0)
        -     * Lum' = Lum * (1.0-tint) + (HLSMAX - HLSMAX * (1.0-tint))
        -     * For example: Lum = 100; tint = 0.75; Lighten 75%
        -     *
        -     * Lum' = 100 * (1-.75) + (HLSMAX - HLSMAX*(1-.75))
        -     * = 100 * .25 + (255 - 255 * .25)
        -     * = 25 + (255 - 63) = 25 + 192 = 217
        -     * For example: Lum = 100; tint = 1.0; Lighten 100% (make white)
        -     * Lum' = 100 * (1-1) + (HLSMAX - HLSMAX*(1-1))
        -     * = 100 * 0 + (255 - 255 * 0)
        -     * = 0 + (255 - 0) = 255
        -     * 
        - *
        - * - * @param tint the tint value - */ - public abstract void setTint(double tint); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FillPatternType.java b/trunk/src/java/org/apache/poi/ss/usermodel/FillPatternType.java deleted file mode 100644 index 705fd6d4e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FillPatternType.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating the style of fill pattern being used for a cell format. - * - */ -public enum FillPatternType { - - /** No background */ - NO_FILL(0), - - /** Solidly filled */ - SOLID_FOREGROUND(1), - - /** Small fine dots */ - FINE_DOTS(2), - - /** Wide dots */ - ALT_BARS(3), - - /** Sparse dots */ - SPARSE_DOTS(4), - - /** Thick horizontal bands */ - THICK_HORZ_BANDS(5), - - /** Thick vertical bands */ - THICK_VERT_BANDS(6), - - /** Thick backward facing diagonals */ - THICK_BACKWARD_DIAG(7), - - /** Thick forward facing diagonals */ - THICK_FORWARD_DIAG(8), - - /** Large spots */ - BIG_SPOTS(9), - - /** Brick-like layout */ - BRICKS(10), - - /** Thin horizontal bands */ - THIN_HORZ_BANDS(11), - - /** Thin vertical bands */ - THIN_VERT_BANDS(12), - - /** Thin backward diagonal */ - THIN_BACKWARD_DIAG(13), - - /** Thin forward diagonal */ - THIN_FORWARD_DIAG(14), - - /** Squares */ - SQUARES(15), - - /** Diamonds */ - DIAMONDS(16), - - /** Less Dots */ - LESS_DOTS(17), - - /** Least Dots */ - LEAST_DOTS(18); - - /** Codes are used by ExtendedFormatRecord in HSSF */ - private final short code; - private FillPatternType(int code) { - this.code = (short) code; - } - - public short getCode() { - return code; - } - - private final static int length = values().length; - public static FillPatternType forInt(int code) { - if (code < 0 || code > length) { - throw new IllegalArgumentException("Invalid FillPatternType code: " + code); - } - return values()[code]; - } - // it may also make sense to have an @Internal method to convert STPatternType.Enum - // but may cause errors if poi-ooxml.jar is not on the classpath - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Font.java b/trunk/src/java/org/apache/poi/ss/usermodel/Font.java deleted file mode 100644 index d4bcc110a..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Font.java +++ /dev/null @@ -1,297 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - - -public interface Font { - /** - * Normal boldness (not bold) - * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. - * Boldweight constants no longer needed due to {@link #getBold} and {@link #setBold(boolean)} - */ - public final static short BOLDWEIGHT_NORMAL = 0x190; - - /** - * Bold boldness (bold) - * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. - * Boldweight constants no longer needed due to {@link #getBold} and {@link #setBold(boolean)} - */ - public final static short BOLDWEIGHT_BOLD = 0x2bc; - - /** - * normal type of black color. - */ - - public final static short COLOR_NORMAL = 0x7fff; - - /** - * Dark Red color - */ - - public final static short COLOR_RED = 0xa; - - /** - * no type offsetting (not super or subscript) - */ - - public final static short SS_NONE = 0; - - /** - * superscript - */ - - public final static short SS_SUPER = 1; - - /** - * subscript - */ - - public final static short SS_SUB = 2; - - /** - * not underlined - */ - - public final static byte U_NONE = 0; - - /** - * single (normal) underline - */ - - public final static byte U_SINGLE = 1; - - /** - * double underlined - */ - - public final static byte U_DOUBLE = 2; - - /** - * accounting style single underline - */ - - public final static byte U_SINGLE_ACCOUNTING = 0x21; - - /** - * accounting style double underline - */ - - public final static byte U_DOUBLE_ACCOUNTING = 0x22; - - /** - * ANSI character set - */ - public final static byte ANSI_CHARSET = 0; - - /** - * Default character set. - */ - public final static byte DEFAULT_CHARSET = 1; - - /** - * Symbol character set - */ - public final static byte SYMBOL_CHARSET = 2; - - /** - * set the name for the font (i.e. Arial) - * @param name String representing the name of the font to use - */ - - void setFontName(String name); - - /** - * get the name for the font (i.e. Arial) - * @return String representing the name of the font to use - */ - - String getFontName(); - - /** - * set the font height in unit's of 1/20th of a point. Maybe you might want to - * use the setFontHeightInPoints which matches to the familiar 10, 12, 14 etc.. - * @param height height in 1/20ths of a point - * @see #setFontHeightInPoints(short) - */ - - void setFontHeight(short height); - - /** - * set the font height - * @param height height in the familiar unit of measure - points - * @see #setFontHeight(short) - */ - - void setFontHeightInPoints(short height); - - /** - * Get the font height in unit's of 1/20th of a point. - *

        - * For many users, the related {@link #getFontHeightInPoints()} - * will be more helpful, as that returns font heights in the - * more familiar points units, eg 10, 12, 14. - - * @return short - height in 1/20ths of a point - * @see #getFontHeightInPoints() - */ - short getFontHeight(); - - /** - * Get the font height in points. - *

        - * This will return the same font height that is shown in Excel, - * such as 10 or 14 or 28. - * @return short - height in the familiar unit of measure - points - * @see #getFontHeight() - */ - short getFontHeightInPoints(); - - /** - * set whether to use italics or not - * @param italic italics or not - */ - - void setItalic(boolean italic); - - /** - * get whether to use italics or not - * @return italics or not - */ - - boolean getItalic(); - - /** - * set whether to use a strikeout horizontal line through the text or not - * @param strikeout or not - */ - - void setStrikeout(boolean strikeout); - - /** - * get whether to use a strikeout horizontal line through the text or not - * @return strikeout or not - */ - - boolean getStrikeout(); - - /** - * set the color for the font - * @param color to use - * @see #COLOR_NORMAL Note: Use this rather than HSSFColor.AUTOMATIC for default font color - * @see #COLOR_RED - */ - - void setColor(short color); - - /** - * get the color for the font - * @return color to use - * @see #COLOR_NORMAL - * @see #COLOR_RED - * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short) - */ - short getColor(); - - /** - * set normal,super or subscript. - * @param offset type to use (none,super,sub) - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - - void setTypeOffset(short offset); - - /** - * get normal,super or subscript. - * @return offset type to use (none,super,sub) - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - - short getTypeOffset(); - - /** - * set type of text underlining to use - * @param underline type - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - - void setUnderline(byte underline); - - /** - * get type of text underlining to use - * @return underlining type - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - - byte getUnderline(); - - /** - * get character-set to use. - * @return character-set - * @see #ANSI_CHARSET - * @see #DEFAULT_CHARSET - * @see #SYMBOL_CHARSET - */ - int getCharSet(); - - /** - * set character-set to use. - * @see #ANSI_CHARSET - * @see #DEFAULT_CHARSET - * @see #SYMBOL_CHARSET - */ - void setCharSet(byte charset); - /** - * set character-set to use. - * @see #ANSI_CHARSET - * @see #DEFAULT_CHARSET - * @see #SYMBOL_CHARSET - */ - void setCharSet(int charset); - - /** - * get the index within the XSSFWorkbook (sequence within the collection of Font objects) - * - * @return unique index number of the underlying record this Font represents (probably you don't care - * unless you're comparing which one is which) - */ - public short getIndex(); - - /** - * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. Use {@link #setBold(boolean)}. - */ - public void setBoldweight(short boldweight); - public void setBold(boolean bold); - - /** - * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. Use {@link #getBold()}. - */ - public short getBoldweight(); - public boolean getBold(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FontCharset.java b/trunk/src/java/org/apache/poi/ss/usermodel/FontCharset.java deleted file mode 100644 index 90e4038b3..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FontCharset.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - - -/** - * Charset represents the basic set of characters associated with a font (that it can display), and - * corresponds to the ANSI codepage (8-bit or DBCS) of that character set used by a given language. - * - * @author Gisella Bronzetti - */ -public enum FontCharset { - - ANSI(0), - DEFAULT(1), - SYMBOL(2), - MAC(77), - SHIFTJIS(128), - HANGEUL(129), - JOHAB(130), - GB2312(134), - CHINESEBIG5(136), - GREEK(161), - TURKISH(162), - VIETNAMESE(163), - HEBREW(177), - ARABIC(178), - BALTIC(186), - RUSSIAN(204), - THAI(222), - EASTEUROPE(238), - OEM(255); - - - private int charset; - - private FontCharset(int value){ - charset = value; - } - - /** - * Returns value of this charset - * - * @return value of this charset - */ - public int getValue(){ - return charset; - } - - private static FontCharset[] _table = new FontCharset[256]; - static { - for (FontCharset c : values()) { - _table[c.getValue()] = c; - } - } - - public static FontCharset valueOf(int value){ - if(value >= _table.length) - return null; - return _table[value]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FontFamily.java b/trunk/src/java/org/apache/poi/ss/usermodel/FontFamily.java deleted file mode 100644 index 829246678..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FontFamily.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - - -/** - * The font family this font belongs to. A font family is a set of fonts having common stroke width and serif - * characteristics. The font name overrides when there are conflicting values. - * - * @author Gisella Bronzetti - */ -public enum FontFamily { - - NOT_APPLICABLE(0), - ROMAN(1), - SWISS(2), - MODERN(3), - SCRIPT(4), - DECORATIVE(5); - - private int family; - - private FontFamily(int value) { - family = value; - } - - /** - * Returns index of this font family - * - * @return index of this font family - */ - public int getValue() { - return family; - } - - private static FontFamily[] _table = new FontFamily[6]; - - static { - for (FontFamily c : values()) { - _table[c.getValue()] = c; - } - } - - public static FontFamily valueOf(int family) { - return _table[family]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FontFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/FontFormatting.java deleted file mode 100644 index a6f21bde4..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FontFormatting.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -/** - * High level representation for Font Formatting component - * of Conditional Formatting settings - */ -public interface FontFormatting { - /** Escapement type - None */ - public final static short SS_NONE = 0; - /** Escapement type - Superscript */ - public final static short SS_SUPER = 1; - /** Escapement type - Subscript */ - public final static short SS_SUB = 2; - - /** Underline type - None */ - public final static byte U_NONE = 0; - /** Underline type - Single */ - public final static byte U_SINGLE = 1; - /** Underline type - Double */ - public final static byte U_DOUBLE = 2; - /** Underline type - Single Accounting */ - public final static byte U_SINGLE_ACCOUNTING = 0x21; - /** Underline type - Double Accounting */ - public final static byte U_DOUBLE_ACCOUNTING = 0x22; - - /** - * get the type of super or subscript for the font - * - * @return super or subscript option - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - short getEscapementType(); - - /** - * set the escapement type for the font - * - * @param escapementType super or subscript option - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - void setEscapementType(short escapementType); - - /** - * @return font colour index, or 0 if not indexed (XSSF only) - */ - short getFontColorIndex(); - - /** - * Sets the indexed colour to use - * @param color font colour index - */ - void setFontColorIndex(short color); - - /** - * @return The colour of the font, or null if no colour applied - */ - Color getFontColor(); - - /** - * Sets the colour to use - * @param color font colour to use - */ - void setFontColor(Color color); - - /** - * gets the height of the font in 1/20th point units - * - * @return fontheight (in points/20); or -1 if not modified - */ - int getFontHeight(); - - /** - * Sets the height of the font in 1/20th point units - * - * @param height the height in twips (in points/20) - */ - void setFontHeight(int height); - - /** - * get the type of underlining for the font - * - * @return font underlining type - * - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - short getUnderlineType(); - - /** - * set the type of underlining type for the font - * - * @param underlineType super or subscript option - * - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - void setUnderlineType(short underlineType); - - /** - * get whether the font weight is set to bold or not - * - * @return bold - whether the font is bold or not - */ - boolean isBold(); - - /** - * @return true if font style was set to italic - */ - boolean isItalic(); - - /** - * set font style options. - * - * @param italic - if true, set posture style to italic, otherwise to normal - * @param bold if true, set font weight to bold, otherwise to normal - */ - void setFontStyle(boolean italic, boolean bold); - - /** - * set font style options to default values (non-italic, non-bold) - */ - void resetFontStyle(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FontScheme.java b/trunk/src/java/org/apache/poi/ss/usermodel/FontScheme.java deleted file mode 100644 index e1b771230..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FontScheme.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - - -/** - * Defines the font scheme to which this font belongs. - * When a font definition is part of a theme definition, then the font is categorized as either a major or minor font scheme component. - * When a new theme is chosen, every font that is part of a theme definition is updated to use the new major or minor font definition for that - * theme. - * Usually major fonts are used for styles like headings, and minor fonts are used for body & paragraph text. - * - * @author Gisella Bronzetti - */ -public enum FontScheme { - - - NONE(1), - MAJOR(2), - MINOR(3); - - private int value; - - private FontScheme(int val) { - value = val; - } - - public int getValue() { - return value; - } - - private static FontScheme[] _table = new FontScheme[4]; - static { - for (FontScheme c : values()) { - _table[c.getValue()] = c; - } - } - - public static FontScheme valueOf(int value){ - return _table[value]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FontUnderline.java b/trunk/src/java/org/apache/poi/ss/usermodel/FontUnderline.java deleted file mode 100644 index a78062b92..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FontUnderline.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * the different types of possible underline formatting - * - * @author Gisella Bronzetti - */ -public enum FontUnderline { - - /** - * Single-line underlining under each character in the cell. - * The underline is drawn through the descenders of - * characters such as g and p.. - */ - SINGLE(1), - - /** - * Double-line underlining under each character in the - * cell. underlines are drawn through the descenders of - * characters such as g and p. - */ - DOUBLE(2), - - /** - * Single-line accounting underlining under each - * character in the cell. The underline is drawn under the - * descenders of characters such as g and p. - */ - SINGLE_ACCOUNTING(3), - - /** - * Double-line accounting underlining under each - * character in the cell. The underlines are drawn under - * the descenders of characters such as g and p. - */ - DOUBLE_ACCOUNTING(4), - - /** - * No underline. - */ - NONE(5); - - private int value; - - - private FontUnderline(int val) { - value = val; - } - - public int getValue() { - return value; - } - - public byte getByteValue() { - switch (this) { - case DOUBLE: - return Font.U_DOUBLE; - case DOUBLE_ACCOUNTING: - return Font.U_DOUBLE_ACCOUNTING; - case SINGLE_ACCOUNTING: - return Font.U_SINGLE_ACCOUNTING; - case NONE: - return Font.U_NONE; - case SINGLE: - return Font.U_SINGLE; - default: - return Font.U_SINGLE; - } - } - - private static FontUnderline[] _table = new FontUnderline[6]; - static { - for (FontUnderline c : values()) { - _table[c.getValue()] = c; - } - } - - public static FontUnderline valueOf(int value){ - return _table[value]; - } - - public static FontUnderline valueOf(byte value){ - FontUnderline val; - switch (value) { - case Font.U_DOUBLE: - val = FontUnderline.DOUBLE; - break; - case Font.U_DOUBLE_ACCOUNTING: - val = FontUnderline.DOUBLE_ACCOUNTING; - break; - case Font.U_SINGLE_ACCOUNTING: - val = FontUnderline.SINGLE_ACCOUNTING; - break; - case Font.U_SINGLE: - val = FontUnderline.SINGLE; - break; - default: - val = FontUnderline.NONE; - break; - } - return val; - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Footer.java b/trunk/src/java/org/apache/poi/ss/usermodel/Footer.java deleted file mode 100644 index f982b71e6..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Footer.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * Common definition of a HSSF or XSSF page footer. - * For a list of all the different fields that can be - * placed into a footer, such as page number, - * bold, underline etc, see - * {@link org.apache.poi.ss.usermodel.HeaderFooter}. - */ -public interface Footer extends HeaderFooter { - /** - * Get the left side of the footer. - * @return The string representing the left side. - */ - String getLeft(); - - /** - * Sets the left string. - * @param newLeft The string to set as the left side. - */ - void setLeft(String newLeft); - - /** - * Get the center of the footer. - * @return The string representing the center. - */ - String getCenter(); - - /** - * Sets the center string. - * @param newCenter The string to set as the center. - */ - void setCenter(String newCenter); - - /** - * Get the right side of the footer. - * @return The string representing the right side. - */ - String getRight(); - - /** - * Sets the right string. - * @param newRight The string to set as the right side. - */ - void setRight(String newRight); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FormulaError.java b/trunk/src/java/org/apache/poi/ss/usermodel/FormulaError.java deleted file mode 100644 index fa102299e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FormulaError.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.util.Map; - -import org.apache.poi.util.Internal; - -import java.util.HashMap; - -/** - * Enumerates error values in SpreadsheetML formula calculations. - * - * See also OOO's excelfileformat.pdf (2.5.6) - */ -public enum FormulaError { - @Internal - _NO_ERROR(-1, "(no error)"), - - /** - * Intended to indicate when two areas are required to intersect, but do not. - *

        Example: - * In the case of SUM(B1 C1), the space between B1 and C1 is treated as the binary - * intersection operator, when a comma was intended. end example] - *

        - */ - NULL(0x00, "#NULL!"), - - /** - * Intended to indicate when any number, including zero, is divided by zero. - * Note: However, any error code divided by zero results in that error code. - */ - DIV0(0x07, "#DIV/0!"), - - /** - * Intended to indicate when an incompatible type argument is passed to a function, or - * an incompatible type operand is used with an operator. - *

        Example: - * In the case of a function argument, text was expected, but a number was provided - *

        - */ - VALUE(0x0F, "#VALUE!"), - - /** - * Intended to indicate when a cell reference is invalid. - *

        Example: - * If a formula contains a reference to a cell, and then the row or column containing that cell is deleted, - * a #REF! error results. If a worksheet does not support 20,001 columns, - * OFFSET(A1,0,20000) will result in a #REF! error. - *

        - */ - REF(0x17, "#REF!"), - - /** - * Intended to indicate when what looks like a name is used, but no such name has been defined. - *

        Example: - * XYZ/3, where XYZ is not a defined name. Total is & A10, - * where neither Total nor is is a defined name. Presumably, "Total is " & A10 - * was intended. SUM(A1C10), where the range A1:C10 was intended. - *

        - */ - NAME(0x1D, "#NAME?"), - - /** - * Intended to indicate when an argument to a function has a compatible type, but has a - * value that is outside the domain over which that function is defined. (This is known as - * a domain error.) - *

        Example: - * Certain calls to ASIN, ATANH, FACT, and SQRT might result in domain errors. - *

        - * Intended to indicate that the result of a function cannot be represented in a value of - * the specified type, typically due to extreme magnitude. (This is known as a range - * error.) - *

        Example: FACT(1000) might result in a range error.

        - */ - NUM(0x24, "#NUM!"), - - /** - * Intended to indicate when a designated value is not available. - *

        Example: - * Some functions, such as SUMX2MY2, perform a series of operations on corresponding - * elements in two arrays. If those arrays do not have the same number of elements, then - * for some elements in the longer array, there are no corresponding elements in the - * shorter one; that is, one or more values in the shorter array are not available. - *

        - * This error value can be produced by calling the function NA - */ - NA(0x2A, "#N/A"), - - // These are POI-specific error codes - // It is desirable to make these (arbitrary) strings look clearly different from any other - // value expression that might appear in a formula. In addition these error strings should - // look unlike the standard Excel errors. Hence tilde ('~') was used. - - /** - * POI specific code to indicate that there is a circular reference - * in the formula - */ - CIRCULAR_REF(0xFFFFFFC4, "~CIRCULAR~REF~"), - /** - * POI specific code to indicate that the funcition required is - * not implemented in POI - */ - FUNCTION_NOT_IMPLEMENTED(0xFFFFFFE2, "~FUNCTION~NOT~IMPLEMENTED~"); - - private final byte type; - private final int longType; - private final String repr; - - private FormulaError(int type, String repr) { - this.type = (byte)type; - this.longType = type; - this.repr = repr; - } - - /** - * @return numeric code of the error - */ - public byte getCode() { - return type; - } - /** - * @return long (internal) numeric code of the error - */ - public int getLongCode() { - return longType; - } - - /** - * @return string representation of the error - */ - public String getString() { - return repr; - } - - private static final Map smap = new HashMap(); - private static final Map bmap = new HashMap(); - private static final Map imap = new HashMap(); - static{ - for (FormulaError error : values()) { - bmap.put(error.getCode(), error); - imap.put(error.getLongCode(), error); - smap.put(error.getString(), error); - } - } - - public static final boolean isValidCode(int errorCode) { - for (FormulaError error : values()) { - if (error.getCode() == errorCode) return true; - if (error.getLongCode() == errorCode) return true; - } - return false; - } - - public static FormulaError forInt(byte type) throws IllegalArgumentException { - FormulaError err = bmap.get(type); - if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); - return err; - } - public static FormulaError forInt(int type) throws IllegalArgumentException { - FormulaError err = imap.get(type); - if(err == null) err = bmap.get((byte)type); - if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); - return err; - } - - public static FormulaError forString(String code) throws IllegalArgumentException { - FormulaError err = smap.get(code); - if(err == null) throw new IllegalArgumentException("Unknown error code: " + code); - return err; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java b/trunk/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java deleted file mode 100644 index 44908e9c1..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java +++ /dev/null @@ -1,186 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.Map; - -import org.apache.poi.util.Internal; - -/** - * Evaluates formula cells.

        - * - * For performance reasons, this class keeps a cache of all previously calculated intermediate - * cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between - * calls to evaluate~ methods on this class. - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * @author Josh Micich - */ -public interface FormulaEvaluator { - - /** - * Should be called whenever there are changes to input cells in the evaluated workbook. - * Failure to call this method after changing cell values will cause incorrect behaviour - * of the evaluate~ methods of this class - */ - void clearAllCachedResultValues(); - /** - * Should be called to tell the cell value cache that the specified (value or formula) cell - * has changed. - * Failure to call this method after changing cell values will cause incorrect behaviour - * of the evaluate~ methods of this class - */ - void notifySetFormula(Cell cell); - /** - * Should be called to tell the cell value cache that the specified cell has just become a - * formula cell, or the formula text has changed - */ - void notifyDeleteCell(Cell cell); - - /** - * Should be called to tell the cell value cache that the specified (value or formula) cell - * has changed. - * Failure to call this method after changing cell values will cause incorrect behaviour - * of the evaluate~ methods of this class - */ - void notifyUpdateCell(Cell cell); - - /** - * Loops over all cells in all sheets of the associated workbook. - * For cells that contain formulas, their formulas are evaluated, - * and the results are saved. These cells remain as formula cells. - * For cells that do not contain formulas, no changes are made. - * This is a helpful wrapper around looping over all cells, and - * calling evaluateFormulaCell on each one. - */ - void evaluateAll(); - - /** - * If cell contains a formula, the formula is evaluated and returned, - * else the CellValue simply copies the appropriate cell value from - * the cell and also its cell type. This method should be preferred over - * evaluateInCell() when the call should not modify the contents of the - * original cell. - * @param cell - */ - CellValue evaluate(Cell cell); - - - /** - * If cell contains formula, it evaluates the formula, - * and saves the result of the formula. The cell - * remains as a formula cell. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the type of the formula result is returned, - * so you know what kind of value is also stored with - * the formula. - *

        -     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
        -     * 
        - * Be aware that your cell will hold both the formula, - * and the result. If you want the cell replaced with - * the result of the formula, use {@link #evaluateInCell(Cell)} - * @param cell The cell to evaluate - * @return The type of the formula result, i.e. -1 if the cell is not a formula, - * or one of {@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR} - * Note: the cell's type remains as CellType.FORMULA however. - * @deprecated 3.15. Will return a {@link CellType} enum in the future - */ - int evaluateFormulaCell(Cell cell); - - /** - * If cell contains formula, it evaluates the formula, - * and saves the result of the formula. The cell - * remains as a formula cell. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the type of the formula result is returned, - * so you know what kind of value is also stored with - * the formula. - *
        -     * CellType evaluatedCellType = evaluator.evaluateFormulaCellEnum(cell);
        -     * 
        - * Be aware that your cell will hold both the formula, - * and the result. If you want the cell replaced with - * the result of the formula, use {@link #evaluateInCell(Cell)} - * @param cell The cell to evaluate - * @return The type of the formula result, i.e. -1 if the cell is not a formula, - * or one of {@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR} - * Note: the cell's type remains as CellType.FORMULA however. - */ - CellType evaluateFormulaCellEnum(Cell cell); - - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of Cell is returned to - * allow chained calls like: - *
        -     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
        -     * 
        - * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCellEnum(Cell)} - * @param cell - */ - Cell evaluateInCell(Cell cell); - - /** - * Sets up the Formula Evaluator to be able to reference and resolve - * links to other workbooks, eg [Test.xls]Sheet1!A1. - *

        For a workbook referenced as [Test.xls]Sheet1!A1, you should - * supply a map containing the key Test.xls (no square brackets), - * and an open FormulaEvaluator onto that Workbook. - * @param workbooks Map of workbook names (no square brackets) to an evaluator on that workbook - */ - void setupReferencedWorkbooks(Map workbooks); - - /** - * Whether to ignore missing references to external workbooks and - * use cached formula results in the main workbook instead. - *

        - * In some cases external workbooks referenced by formulas in the main workbook are not available. - * With this method you can control how POI handles such missing references: - *

          - *
        • by default ignoreMissingWorkbooks=false and POI throws - * {@link org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException} - * if an external reference cannot be resolved
        • - *
        • if ignoreMissingWorkbooks=true then POI uses cached formula result - * that already exists in the main workbook
        • - *
        - * - * @param ignore whether to ignore missing references to external workbooks - */ - void setIgnoreMissingWorkbooks(boolean ignore); - - /** - * Perform detailed output of formula evaluation for next evaluation only? - * Is for developer use only (also developers using POI for their XLS files). - * Log-Level WARN is for basic info, INFO for detailed information. These quite - * high levels are used because you have to explicitly enable this specific logging. - - * @param value whether to perform detailed output - */ - void setDebugEvaluationOutputForNextEval(boolean value); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java b/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java deleted file mode 100644 index bd5c8c8fe..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.poi.ss.usermodel; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.ss.format.SimpleFraction; -import org.apache.poi.ss.formula.eval.NotImplementedException; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - *

        Format class that handles Excel style fractions, such as "# #/#" and "#/###"

        - * - *

        As of this writing, this is still not 100% accurate, but it does a reasonable job - * of trying to mimic Excel's fraction calculations. It does not currently - * maintain Excel's spacing.

        - * - *

        This class relies on a method lifted nearly verbatim from org.apache.math.fraction. - * If further uses for Commons Math are found, we will consider adding it as a dependency. - * For now, we have in-lined the one method to keep things simple.

        - */ - -@SuppressWarnings("serial") -public class FractionFormat extends Format { - private static final POILogger LOGGER = POILogFactory.getLogger(FractionFormat.class); - private static final Pattern DENOM_FORMAT_PATTERN = Pattern.compile("(?:(#+)|(\\d+))"); - - //this was chosen to match the earlier limitation of max denom power - //it can be expanded to get closer to Excel's calculations - //with custom formats # #/######### - //but as of this writing, the numerators and denominators - //with formats of that nature on very small values were quite - //far from Excel's calculations - private static final int MAX_DENOM_POW = 4; - - //there are two options: - //a) an exact denominator is specified in the formatString - //b) the maximum denominator can be calculated from the formatString - private final int exactDenom; - private final int maxDenom; - - private final String wholePartFormatString; - /** - * Single parameter ctor - * @param denomFormatString The format string for the denominator - */ - public FractionFormat(String wholePartFormatString, String denomFormatString) { - this.wholePartFormatString = wholePartFormatString; - //init exactDenom and maxDenom - Matcher m = DENOM_FORMAT_PATTERN.matcher(denomFormatString); - int tmpExact = -1; - int tmpMax = -1; - if (m.find()){ - if (m.group(2) != null){ - try{ - tmpExact = Integer.parseInt(m.group(2)); - //if the denom is 0, fall back to the default: tmpExact=100 - - if (tmpExact == 0){ - tmpExact = -1; - } - } catch (NumberFormatException e){ - //should never happen - } - } else if (m.group(1) != null) { - int len = m.group(1).length(); - len = len > MAX_DENOM_POW ? MAX_DENOM_POW : len; - tmpMax = (int)Math.pow(10, len); - } else { - tmpExact = 100; - } - } - if (tmpExact <= 0 && tmpMax <= 0){ - //use 100 as the default denom if something went horribly wrong - tmpExact = 100; - } - exactDenom = tmpExact; - maxDenom = tmpMax; - } - - public String format(Number num) { - - final double doubleValue = num.doubleValue(); - - final boolean isNeg = (doubleValue < 0.0f) ? true : false; - final double absDoubleValue = Math.abs(doubleValue); - - final double wholePart = Math.floor(absDoubleValue); - final double decPart = absDoubleValue - wholePart; - if (wholePart + decPart == 0) { - return "0"; - } - - // if the absolute value is smaller than 1 over the exact or maxDenom - // you can stop here and return "0" - // reciprocal is result of an int devision ... and so it's nearly always 0 - // double reciprocal = 1/Math.max(exactDenom, maxDenom); - // if (absDoubleValue < reciprocal) { - // return "0"; - // } - - //this is necessary to prevent overflow in the maxDenom calculation - if (Double.compare(decPart, 0) == 0){ - - StringBuilder sb = new StringBuilder(); - if (isNeg){ - sb.append("-"); - } - sb.append((int)wholePart); - return sb.toString(); - } - - SimpleFraction fract = null; - try{ - //this should be the case because of the constructor - if (exactDenom > 0){ - fract = SimpleFraction.buildFractionExactDenominator(decPart, exactDenom); - } else { - fract = SimpleFraction.buildFractionMaxDenominator(decPart, maxDenom); - } - } catch (RuntimeException e){ - LOGGER.log(POILogger.WARN, "Can't format fraction", e); - return Double.toString(doubleValue); - } - - StringBuilder sb = new StringBuilder(); - - //now format the results - if (isNeg){ - sb.append("-"); - } - - //if whole part has to go into the numerator - if ("".equals(wholePartFormatString)){ - int trueNum = (fract.getDenominator()*(int)wholePart)+fract.getNumerator(); - sb.append(trueNum).append("/").append(fract.getDenominator()); - return sb.toString(); - } - - - //short circuit if fraction is 0 or 1 - if (fract.getNumerator() == 0){ - sb.append(Integer.toString((int)wholePart)); - return sb.toString(); - } else if (fract.getNumerator() == fract.getDenominator()){ - sb.append(Integer.toString((int)wholePart+1)); - return sb.toString(); - } - //as mentioned above, this ignores the exact space formatting in Excel - if (wholePart > 0){ - sb.append(Integer.toString((int)wholePart)).append(" "); - } - sb.append(fract.getNumerator()).append("/").append(fract.getDenominator()); - return sb.toString(); - } - - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - public Object parseObject(String source, ParsePosition pos) { - throw new NotImplementedException("Reverse parsing not supported"); - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Header.java b/trunk/src/java/org/apache/poi/ss/usermodel/Header.java deleted file mode 100644 index 22f38a665..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Header.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * Common definition of a HSSF or XSSF page header. - * For a list of all the different fields that can be - * placed into a header, such as page number, - * bold, underline etc, see - * {@link org.apache.poi.ss.usermodel.HeaderFooter}. - */ -public interface Header extends HeaderFooter { - /** - * Get the left side of the header. - * - * @return The string representing the left side. - */ - String getLeft(); - - /** - * Sets the left string. - * - * @param newLeft The string to set as the left side. - */ - void setLeft(String newLeft); - - /** - * Get the center of the header. - * - * @return The string representing the center. - */ - String getCenter(); - - /** - * Sets the center string. - * - * @param newCenter The string to set as the center. - */ - void setCenter(String newCenter); - - /** - * Get the right side of the header. - * - * @return The string representing the right side. - */ - String getRight(); - - /** - * Sets the right string. - * - * @param newRight The string to set as the right side. - */ - void setRight(String newRight); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/HeaderFooter.java b/trunk/src/java/org/apache/poi/ss/usermodel/HeaderFooter.java deleted file mode 100644 index 41c0e9ea3..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/HeaderFooter.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * Common interface for {@link org.apache.poi.ss.usermodel.Header} and - * {@link org.apache.poi.ss.usermodel.Footer}. - */ -public interface HeaderFooter { - /** - * Get the left side of the header or footer. - * - * @return The string representing the left side. - */ - String getLeft(); - - /** - * Sets the left string. - * - * @param newLeft The string to set as the left side. - */ - void setLeft(String newLeft); - - /** - * Get the center of the header or footer. - * - * @return The string representing the center. - */ - String getCenter(); - - /** - * Sets the center string. - * - * @param newCenter The string to set as the center. - */ - void setCenter(String newCenter); - - /** - * Get the right side of the header or footer. - * - * @return The string representing the right side. - */ - String getRight(); - - /** - * Sets the right string or footer. - * - * @param newRight The string to set as the right side. - */ - void setRight(String newRight); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java b/trunk/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java deleted file mode 100644 index 6b9a31326..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating horizontal alignment of a cell, - * i.e., whether it is aligned general, left, right, horizontally centered, filled (replicated), - * justified, centered across multiple cells, or distributed. - */ -public enum HorizontalAlignment { - /** - * The horizontal alignment is general-aligned. Text data is left-aligned. - * Numbers, dates, and times are rightaligned. Boolean types are centered. - * Changing the alignment does not change the type of data. - */ - GENERAL, - - /** - * The horizontal alignment is left-aligned, even in Rightto-Left mode. - * Aligns contents at the left edge of the cell. If an indent amount is specified, the contents of - * the cell is indented from the left by the specified number of character spaces. The character spaces are - * based on the default font and font size for the workbook. - */ - LEFT, - - /** - * The horizontal alignment is centered, meaning the text is centered across the cell. - */ - CENTER, - - /** - * The horizontal alignment is right-aligned, meaning that cell contents are aligned at the right edge of the cell, - * even in Right-to-Left mode. - */ - RIGHT, - - /** - * Indicates that the value of the cell should be filled - * across the entire width of the cell. If blank cells to the right also have the fill alignment, - * they are also filled with the value, using a convention similar to centerContinuous. - *

        - * Additional rules: - *

          - *
        1. Only whole values can be appended, not partial values.
        2. - *
        3. The column will not be widened to 'best fit' the filled value
        4. - *
        5. If appending an additional occurrence of the value exceeds the boundary of the cell - * left/right edge, don't append the additional occurrence of the value.
        6. - *
        7. The display value of the cell is filled, not the underlying raw number.
        8. - *
        - *

        - */ - FILL, - - /** - * The horizontal alignment is justified (flush left and right). - * For each line of text, aligns each line of the wrapped text in a cell to the right and left - * (except the last line). If no single line of text wraps in the cell, then the text is not justified. - */ - JUSTIFY, - - /** - * The horizontal alignment is centered across multiple cells. - * The information about how many cells to span is expressed in the Sheet Part, - * in the row of the cell in question. For each cell that is spanned in the alignment, - * a cell element needs to be written out, with the same style Id which references the centerContinuous alignment. - */ - CENTER_SELECTION, - - /** - * Indicates that each 'word' in each line of text inside the cell is evenly distributed - * across the width of the cell, with flush right and left margins. - *

        - * When there is also an indent value to apply, both the left and right side of the cell - * are padded by the indent value. - *

        - *

        A 'word' is a set of characters with no space character in them.

        - *

        Two lines inside a cell are separated by a carriage return.

        - */ - DISTRIBUTED; - - public short getCode() { - return (short) ordinal(); - } - public static HorizontalAlignment forInt(int code) { - if (code < 0 || code >= values().length) { - throw new IllegalArgumentException("Invalid HorizontalAlignment code: " + code); - } - return values()[code]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Hyperlink.java b/trunk/src/java/org/apache/poi/ss/usermodel/Hyperlink.java deleted file mode 100644 index c067cc002..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Hyperlink.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * Represents an Excel hyperlink. - */ -public interface Hyperlink extends org.apache.poi.common.usermodel.Hyperlink { - /** - * Return the row of the first cell that contains the hyperlink - * - * @return the 0-based row of the cell that contains the hyperlink - */ - public int getFirstRow(); - - /** - * Set the row of the first cell that contains the hyperlink - * - * @param row the 0-based row of the first cell that contains the hyperlink - */ - public void setFirstRow(int row); - - /** - * Return the row of the last cell that contains the hyperlink - * - * @return the 0-based row of the last cell that contains the hyperlink - */ - public int getLastRow(); - - /** - * Set the row of the last cell that contains the hyperlink - * - * @param row the 0-based row of the last cell that contains the hyperlink - */ - public void setLastRow(int row); - - /** - * Return the column of the first cell that contains the hyperlink - * - * @return the 0-based column of the first cell that contains the hyperlink - */ - public int getFirstColumn(); - - /** - * Set the column of the first cell that contains the hyperlink - * - * @param col the 0-based column of the first cell that contains the hyperlink - */ - public void setFirstColumn(int col); - - /** - * Return the column of the last cell that contains the hyperlink - * - * @return the 0-based column of the last cell that contains the hyperlink - */ - public int getLastColumn(); - - /** - * Set the column of the last cell that contains the hyperlink - * - * @param col the 0-based column of the last cell that contains the hyperlink - */ - public void setLastColumn(int col); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java deleted file mode 100644 index e7577c3f6..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -/** - * High level representation for the Icon / Multi-State Formatting - * component of Conditional Formatting settings - */ -public interface IconMultiStateFormatting { - public enum IconSet { - /** Green Up / Yellow Side / Red Down arrows */ - GYR_3_ARROW(0, 3, "3Arrows"), - /** Grey Up / Side / Down arrows */ - GREY_3_ARROWS(1, 3, "3ArrowsGray"), - /** Green / Yellow / Red flags */ - GYR_3_FLAGS(2, 3, "3Flags"), - /** Green / Yellow / Red traffic lights (no background). Default */ - GYR_3_TRAFFIC_LIGHTS(3, 3, "3TrafficLights1"), - /** Green / Yellow / Red traffic lights on a black square background. - * Note, MS-XLS docs v20141018 say this is id=5 but seems to be id=4 */ - GYR_3_TRAFFIC_LIGHTS_BOX(4, 3, "3TrafficLights2"), - /** Green Circle / Yellow Triangle / Red Diamond. - * Note, MS-XLS docs v20141018 say this is id=4 but seems to be id=5 */ - GYR_3_SHAPES(5, 3, "3Signs"), - /** Green Tick / Yellow ! / Red Cross on a circle background */ - GYR_3_SYMBOLS_CIRCLE(6, 3, "3Symbols"), - /** Green Tick / Yellow ! / Red Cross (no background) */ - GYR_3_SYMBOLS(7, 3, "3Symbols2"), - /** Green Up / Yellow NE / Yellow SE / Red Down arrows */ - GYR_4_ARROWS(8, 4, "4Arrows"), - /** Grey Up / NE / SE / Down arrows */ - GREY_4_ARROWS(9, 4, "4ArrowsGray"), - /** Red / Light Red / Grey / Black traffic lights */ - RB_4_TRAFFIC_LIGHTS(0xA, 4, "4RedToBlack"), - RATINGS_4(0xB, 4, "4Rating"), - /** Green / Yellow / Red / Black traffic lights */ - GYRB_4_TRAFFIC_LIGHTS(0xC, 4, "4TrafficLights"), - GYYYR_5_ARROWS(0xD, 5, "5Arrows"), - GREY_5_ARROWS(0xE, 5, "5ArrowsGray"), - RATINGS_5(0xF, 5, "5Rating"), - QUARTERS_5(0x10, 5, "5Quarters"); - - protected static final IconSet DEFAULT_ICONSET = IconSet.GYR_3_TRAFFIC_LIGHTS; - - /** Numeric ID of the icon set */ - public final int id; - /** How many icons in the set */ - public final int num; - /** Name (system) of the set */ - public final String name; - - public String toString() { - return id + " - " + name; - } - - public static IconSet byId(int id) { - return values()[id]; - } - public static IconSet byName(String name) { - for (IconSet set : values()) { - if (set.name.equals(name)) return set; - } - return null; - } - - private IconSet(int id, int num, String name) { - this.id = id; this.num = num; this.name = name; - } - } - - /** - * Get the Icon Set used - */ - IconSet getIconSet(); - - /** - * Changes the Icon Set used - * - *

        If the new Icon Set has a different number of - * icons to the old one, you must update the - * thresholds before saving!

        - */ - void setIconSet(IconSet set); - - /** - * Should Icon + Value be displayed, or only the Icon? - */ - boolean isIconOnly(); - /** - * Control if only the Icon is shown, or Icon + Value - */ - void setIconOnly(boolean only); - - boolean isReversed(); - void setReversed(boolean reversed); - - /** - * Gets the list of thresholds - */ - ConditionalFormattingThreshold[] getThresholds(); - /** - * Sets the of thresholds. The number must match - * {@link IconSet#num} for the current {@link #getIconSet()} - */ - void setThresholds(ConditionalFormattingThreshold[] thresholds); - /** - * Creates a new, empty Threshold - */ - ConditionalFormattingThreshold createThreshold(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/IgnoredErrorType.java b/trunk/src/java/org/apache/poi/ss/usermodel/IgnoredErrorType.java deleted file mode 100644 index 2843de4de..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/IgnoredErrorType.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * Types of ignored workbook and worksheet error. - * - * TODO Implement these for HSSF too, using FeatFormulaErr2, - * see bugzilla bug #46136 for details - */ -public enum IgnoredErrorType { - /** - * ????. Probably XSSF-only. - */ - CALCULATED_COLUMN, - - /** - * Whether to check for references to empty cells. - * HSSF + XSSF. - */ - EMPTY_CELL_REFERENCE, - - /** - * Whether to check for calculation/evaluation errors. - * HSSF + XSSF. - */ - EVALUATION_ERROR, - - /** - * Whether to check formulas in the range of the shared feature - * that are inconsistent with formulas in neighbouring cells. - * HSSF + XSSF. - */ - FORMULA, - - /** - * Whether to check formulas in the range of the shared feature - * with references to less than the entirety of a range containing - * continuous data. - * HSSF + XSSF. - */ - FORMULA_RANGE, - - /** - * ????. Is this XSSF-specific the same as performDataValidation - * in HSSF? - */ - LIST_DATA_VALIDATION, - - /** - * Whether to check the format of string values and warn - * if they look to actually be numeric values. - * HSSF + XSSF. - */ - NUMBER_STORED_AS_TEXT, - - /** - * ????. Is this XSSF-specific the same as checkDateTimeFormats - * in HSSF? - */ - TWO_DIGIT_TEXT_YEAR, - - /** - * Whether to check for unprotected formulas. - * HSSF + XSSF. - */ - UNLOCKED_FORMULA -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/IndexedColors.java b/trunk/src/java/org/apache/poi/ss/usermodel/IndexedColors.java deleted file mode 100644 index 92ebc08a1..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/IndexedColors.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * A deprecated indexing scheme for colours that is still required for some records, and for backwards - * compatibility with OLE2 formats. - * - *

        - * Each element corresponds to a color index (zero-based). When using the default indexed color palette, - * the values are not written out, but instead are implied. When the color palette has been modified from default, - * then the entire color palette is used. - *

        - * - * @author Yegor Kozlov - */ -public enum IndexedColors { - - // 0-7? - BLACK(8), - WHITE(9), - RED(10), - BRIGHT_GREEN(11), - BLUE(12), - YELLOW(13), - PINK(14), - TURQUOISE(15), - DARK_RED(16), - GREEN(17), - DARK_BLUE(18), - DARK_YELLOW(19), - VIOLET(20), - TEAL(21), - GREY_25_PERCENT(22), - GREY_50_PERCENT(23), - CORNFLOWER_BLUE(24), - MAROON(25), - LEMON_CHIFFON(26), - // 27? - ORCHID(28), - CORAL(29), - ROYAL_BLUE(30), - LIGHT_CORNFLOWER_BLUE(31), - SKY_BLUE(40), - LIGHT_TURQUOISE(41), - LIGHT_GREEN(42), - LIGHT_YELLOW(43), - PALE_BLUE(44), - ROSE(45), - LAVENDER(46), - TAN(47), - LIGHT_BLUE(48), - AQUA(49), - LIME(50), - GOLD(51), - LIGHT_ORANGE(52), - ORANGE(53), - BLUE_GREY(54), - GREY_40_PERCENT(55), - DARK_TEAL(56), - SEA_GREEN(57), - DARK_GREEN(58), - OLIVE_GREEN(59), - BROWN(60), - PLUM(61), - INDIGO(62), - GREY_80_PERCENT(63), - AUTOMATIC(64); - - private final static IndexedColors[] _values = new IndexedColors[65]; - static { - for (IndexedColors color : values()) { - _values[color.index] = color; - } - } - - public final short index; - - IndexedColors(int idx){ - index = (short)idx; - } - - /** - * Returns index of this color - * - * @return index of this color - */ - public short getIndex(){ - return index; - } - - /** - * - * - * @param index the index of the color - * @return the corresponding IndexedColors enum - * @throws IllegalArgumentException if index is not a valid IndexedColors - * @since 3.15-beta2 - */ - public static IndexedColors fromInt(int index) { - if (index < 0 || index >= _values.length) { - throw new IllegalArgumentException("Illegal IndexedColor index: " + index); - } - IndexedColors color = _values[index]; - if (color == null) { - throw new IllegalArgumentException("Illegal IndexedColor index: " + index); - } - return color; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Name.java b/trunk/src/java/org/apache/poi/ss/usermodel/Name.java deleted file mode 100644 index 983e438b5..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Name.java +++ /dev/null @@ -1,192 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * Represents a defined name for a range of cells. - *

        - * A name is a meaningful shorthand that makes it easier to understand the purpose of a - * cell reference, constant or a formula. - *

        - * Examples: - *
        - * Sheet sheet = workbook.createSheet("Loan Calculator"); - * Name name; - * - * name = workbook.createName(); - * name.setNameName("Interest_Rate"); - * name.setRefersToFormula("'Loan Calculator'!$E$5"); - * - * name = wb.createName(); - * name.setNameName("Loan_Amount"); - * name.setRefersToFormula("'Loan Calculator'!$E$4"); - * - * name = wb.createName(); - * name.setNameName("Number_of_Payments"); - * name.setRefersToFormula("'Loan Calculator'!$E$10"); - * - * name = wb.createName(); - * name.setNameName("Monthly_Payment"); - * name.setRefersToFormula("-PMT(Interest_Rate/12,Number_of_Payments,Loan_Amount)"); - * - * name = wb.createName(); - * name.setNameName("Values_Entered"); - * name.setRefersToFormula("IF(Loan_Amount*Interest_Rate>0,1,0)"); - * - *
        - */ -public interface Name { - - /** - * Get the sheets name which this named range is referenced to - * - * @return sheet name, which this named range referred to - */ - String getSheetName(); - - /** - * Gets the name of the named range - * - * @return named range name - */ - String getNameName(); - - /** - * Sets the name of the named range - * - *

        The following is a list of syntax rules that you need to be aware of when you create and edit names.

        - *
          - *
        • Valid characters - * The first character of a name must be a letter, an underscore character (_), or a backslash (\). - * Remaining characters in the name can be letters, numbers, periods, and underscore characters. - *
        • - *
        • Cell references disallowed - * Names cannot be the same as a cell reference, such as Z$100 or R1C1.
        • - *
        • Spaces are not valid - * Spaces are not allowed as part of a name. Use the underscore character (_) and period (.) as word separators, such as, Sales_Tax or First.Quarter. - *
        • - *
        • Name length - * A name can contain up to 255 characters. - *
        • - *
        • Case sensitivity - * Names can contain uppercase and lowercase letters. - *
        • - *
        - *

        - * A name must always be unique within its scope. POI prevents you from defining a name that is not unique - * within its scope. However you can use the same name in different scopes. Example: - *

        - * //by default names are workbook-global - * Name name; - * name = workbook.createName(); - * name.setNameName("sales_08"); - * - * name = workbook.createName(); - * name.setNameName("sales_08"); //will throw an exception: "The workbook already contains this name (case-insensitive)" - * - * //create sheet-level name - * name = workbook.createName(); - * name.setSheetIndex(0); //the scope of the name is the first sheet - * name.setNameName("sales_08"); //ok - * - * name = workbook.createName(); - * name.setSheetIndex(0); - * name.setNameName("sales_08"); //will throw an exception: "The sheet already contains this name (case-insensitive)" - * - *
        - *

        - * @param name named range name to set - * @throws IllegalArgumentException if the name is invalid or the already exists within its scope (case-insensitive) - */ - void setNameName(String name); - - /** - * Returns the formula that the name is defined to refer to. - * - * @return the reference for this name, null if it has not been set yet. Never empty string - * @see #setRefersToFormula(String) - */ - String getRefersToFormula(); - - /** - * Sets the formula that the name is defined to refer to. The following are representative examples: - * - *
          - *
        • 'My Sheet'!$A$3
        • - *
        • 8.3
        • - *
        • HR!$A$1:$Z$345
        • - *
        • SUM(Sheet1!A1,Sheet2!B2)
        • - *
        • -PMT(Interest_Rate/12,Number_of_Payments,Loan_Amount)
        • - *
        - * - * @param formulaText the reference for this name - * @throws IllegalArgumentException if the specified formulaText is unparsable - */ - void setRefersToFormula(String formulaText); - - /** - * Checks if this name is a function name - * - * @return true if this name is a function name - */ - boolean isFunctionName(); - - /** - * Checks if this name points to a cell that no longer exists - * - * @return true if the name refers to a deleted cell, false otherwise - */ - boolean isDeleted(); - - /** - * Tell Excel that this name applies to the worksheet with the specified index instead of the entire workbook. - * - * @param sheetId the sheet index this name applies to, -1 unsets this property making the name workbook-global - * @throws IllegalArgumentException if the sheet index is invalid. - */ - public void setSheetIndex(int sheetId); - - /** - * Returns the sheet index this name applies to. - * - * @return the sheet index this name applies to, -1 if this name applies to the entire workbook - */ - public int getSheetIndex(); - - /** - * Returns the comment the user provided when the name was created. - * - * @return the user comment for this named range - */ - public String getComment(); - - /** - * Sets the comment the user provided when the name was created. - * - * @param comment the user comment for this named range - */ - public void setComment(String comment); - - /** - * Indicates that the defined name refers to a user-defined function. - * This attribute is used when there is an add-in or other code project associated with the file. - * - * @param value true indicates the name refers to a function. - */ - void setFunction(boolean value); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PageOrder.java b/trunk/src/java/org/apache/poi/ss/usermodel/PageOrder.java deleted file mode 100644 index 341f2bf72..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PageOrder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * Specifies printed page order. - * - * @author Gisella Bronzetti - */ -public enum PageOrder { - - /** - * Order pages vertically first, then move horizontally. - */ - DOWN_THEN_OVER(1), - /** - * Order pages horizontally first, then move vertically - */ - OVER_THEN_DOWN(2); - - - private int order; - - - private PageOrder(int order) { - this.order = order; - } - - public int getValue() { - return order; - } - - - private static PageOrder[] _table = new PageOrder[3]; - static { - for (PageOrder c : values()) { - _table[c.getValue()] = c; - } - } - - public static PageOrder valueOf(int value){ - return _table[value]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PaperSize.java b/trunk/src/java/org/apache/poi/ss/usermodel/PaperSize.java deleted file mode 100644 index abd65f3ea..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PaperSize.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating the possible paper size for a sheet - * - * @author Daniele Montagni - */ -public enum PaperSize { - LETTER_PAPER, - LETTER_SMALL_PAPER, - TABLOID_PAPER, - LEDGER_PAPER, - LEGAL_PAPER, - STATEMENT_PAPER, - EXECUTIVE_PAPER, - A3_PAPER, - A4_PAPER, - A4_SMALL_PAPER, - A5_PAPER, - B4_PAPER, - B5_PAPER, - FOLIO_PAPER, - QUARTO_PAPER, - STANDARD_PAPER_10_14, - STANDARD_PAPER_11_17 -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java deleted file mode 100644 index 0311ffb75..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -/** - * @author Yegor Kozlov - */ -public interface PatternFormatting { - /** No background */ - public final static short NO_FILL = 0 ; - /** Solidly filled */ - public final static short SOLID_FOREGROUND = 1 ; - /** Small fine dots */ - public final static short FINE_DOTS = 2 ; - /** Wide dots */ - public final static short ALT_BARS = 3 ; - /** Sparse dots */ - public final static short SPARSE_DOTS = 4 ; - /** Thick horizontal bands */ - public final static short THICK_HORZ_BANDS = 5 ; - /** Thick vertical bands */ - public final static short THICK_VERT_BANDS = 6 ; - /** Thick backward facing diagonals */ - public final static short THICK_BACKWARD_DIAG = 7 ; - /** Thick forward facing diagonals */ - public final static short THICK_FORWARD_DIAG = 8 ; - /** Large spots */ - public final static short BIG_SPOTS = 9 ; - /** Brick-like layout */ - public final static short BRICKS = 10 ; - /** Thin horizontal bands */ - public final static short THIN_HORZ_BANDS = 11 ; - /** Thin vertical bands */ - public final static short THIN_VERT_BANDS = 12 ; - /** Thin backward diagonal */ - public final static short THIN_BACKWARD_DIAG = 13 ; - /** Thin forward diagonal */ - public final static short THIN_FORWARD_DIAG = 14 ; - /** Squares */ - public final static short SQUARES = 15 ; - /** Diamonds */ - public final static short DIAMONDS = 16 ; - /** Less Dots */ - public final static short LESS_DOTS = 17 ; - /** Least Dots */ - public final static short LEAST_DOTS = 18 ; - - short getFillBackgroundColor(); - short getFillForegroundColor(); - Color getFillBackgroundColorColor(); - Color getFillForegroundColorColor(); - - short getFillPattern(); - - void setFillBackgroundColor(short bg); - void setFillForegroundColor(short fg); - void setFillBackgroundColor(Color bg); - void setFillForegroundColor(Color fg); - - void setFillPattern(short fp); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Picture.java b/trunk/src/java/org/apache/poi/ss/usermodel/Picture.java deleted file mode 100644 index 58ad44812..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Picture.java +++ /dev/null @@ -1,102 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.awt.Dimension; - - -/** - * Repersents a picture in a SpreadsheetML document - * - * @author Yegor Kozlov - */ -public interface Picture { - - /** - * Reset the image to the dimension of the embedded image - * - * @see #resize(double, double) - */ - void resize(); - - /** - * Resize the image proportionally. - * - * @see #resize(double, double) - */ - void resize(double scale); - - /** - * Resize the image. - *

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). - * If the default font is changed the resized image can be streched vertically or horizontally. - *

        - *

        - * resize(1.0,1.0) keeps the original size,
        - * resize(0.5,0.5) resize to 50% of the original,
        - * resize(2.0,2.0) resizes to 200% of the original.
        - * resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE}) resizes to the dimension of the embedded image. - *

        - * - * @param scaleX the amount by which the image width is multiplied relative to the original width. - * @param scaleY the amount by which the image height is multiplied relative to the original height. - */ - void resize(double scaleX, double scaleY); - - /** - * Calculate the preferred size for this picture. - * - * @return XSSFClientAnchor with the preferred size for this image - */ - ClientAnchor getPreferredSize(); - - /** - * Calculate the preferred size for this picture. - * - * @param scaleX the amount by which image width is multiplied relative to the original width. - * @param scaleY the amount by which image height is multiplied relative to the original height. - * @return ClientAnchor with the preferred size for this image - */ - ClientAnchor getPreferredSize(double scaleX, double scaleY); - - /** - * Return the dimension of the embedded image in pixel - * - * @return image dimension in pixels - */ - Dimension getImageDimension(); - - /** - * Return picture data for this picture - * - * @return picture data for this picture - */ - PictureData getPictureData(); - - /** - * @return the anchor that is used by this picture - */ - ClientAnchor getClientAnchor(); - - - /** - * @return the sheet which contains the picture - */ - Sheet getSheet(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PictureData.java b/trunk/src/java/org/apache/poi/ss/usermodel/PictureData.java deleted file mode 100644 index 67d3cefcd..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PictureData.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -public interface PictureData { - - /** - * Gets the picture data. - * - * @return the picture data. - */ - byte[] getData(); - - /** - * Suggests a file extension for this image. - * - * @return the file extension. - */ - String suggestFileExtension(); - - /** - * Returns the mime type for the image - */ - String getMimeType(); - - /** - * @return the POI internal image type, 0 if unknown image type - * - * @see Workbook#PICTURE_TYPE_DIB - * @see Workbook#PICTURE_TYPE_EMF - * @see Workbook#PICTURE_TYPE_JPEG - * @see Workbook#PICTURE_TYPE_PICT - * @see Workbook#PICTURE_TYPE_PNG - * @see Workbook#PICTURE_TYPE_WMF - */ - int getPictureType(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PrintCellComments.java b/trunk/src/java/org/apache/poi/ss/usermodel/PrintCellComments.java deleted file mode 100644 index ecbea6daf..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PrintCellComments.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * These enumerations specify how cell comments shall be displayed for paper printing purposes. - * - * @author Gisella Bronzetti - */ -public enum PrintCellComments { - - /** - * Do not print cell comments. - */ - NONE(1), - /** - * Print cell comments as displayed. - */ - AS_DISPLAYED(2), - /** - * Print cell comments at end of document. - */ - AT_END(3); - - - private int comments; - - private PrintCellComments(int comments) { - this.comments = comments; - } - - public int getValue() { - return comments; - } - - private static PrintCellComments[] _table = new PrintCellComments[4]; - static { - for (PrintCellComments c : values()) { - _table[c.getValue()] = c; - } - } - - public static PrintCellComments valueOf(int value){ - return _table[value]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PrintOrientation.java b/trunk/src/java/org/apache/poi/ss/usermodel/PrintOrientation.java deleted file mode 100644 index 8d5716f31..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PrintOrientation.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating the print orientation for a sheet. - * - * @author Gisella Bronzetti - */ -public enum PrintOrientation { - - /** - * orientation not specified - */ - DEFAULT(1), - /** - * portrait orientation - */ - PORTRAIT(2), - /** - * landscape orientations - */ - LANDSCAPE(3); - - - private int orientation; - - private PrintOrientation(int orientation) { - this.orientation = orientation; - } - - - public int getValue() { - return orientation; - } - - - private static PrintOrientation[] _table = new PrintOrientation[4]; - static { - for (PrintOrientation c : values()) { - _table[c.getValue()] = c; - } - } - - public static PrintOrientation valueOf(int value){ - return _table[value]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/PrintSetup.java b/trunk/src/java/org/apache/poi/ss/usermodel/PrintSetup.java deleted file mode 100644 index bba72c395..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/PrintSetup.java +++ /dev/null @@ -1,303 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -public interface PrintSetup { - /** Whatever the printer's default paper size is */ - public static final short PRINTER_DEFAULT_PAPERSIZE = 0; - /** US Letter 8 1/2 x 11 in */ - public static final short LETTER_PAPERSIZE = 1; - /** US Letter Small 8 1/2 x 11 in */ - public static final short LETTER_SMALL_PAGESIZE = 2; - /** US Tabloid 11 x 17 in */ - public static final short TABLOID_PAPERSIZE = 3; - /** US Ledger 17 x 11 in */ - public static final short LEDGER_PAPERSIZE = 4; - /** US Legal 8 1/2 x 14 in */ - public static final short LEGAL_PAPERSIZE = 5; - /** US Statement 5 1/2 x 8 1/2 in */ - public static final short STATEMENT_PAPERSIZE = 6; - /** US Executive 7 1/4 x 10 1/2 in */ - public static final short EXECUTIVE_PAPERSIZE = 7; - /** A3 - 297x420 mm */ - public static final short A3_PAPERSIZE = 8; - /** A4 - 210x297 mm */ - public static final short A4_PAPERSIZE = 9; - /** A4 Small - 210x297 mm */ - public static final short A4_SMALL_PAPERSIZE = 10; - /** A5 - 148x210 mm */ - public static final short A5_PAPERSIZE = 11; - /** B4 (JIS) 250x354 mm */ - public static final short B4_PAPERSIZE = 12; - /** B5 (JIS) 182x257 mm */ - public static final short B5_PAPERSIZE = 13; - /** Folio 8 1/2 x 13 in */ - public static final short FOLIO8_PAPERSIZE = 14; - /** Quarto 215x275 mm */ - public static final short QUARTO_PAPERSIZE = 15; - /** 10 x 14 in */ - public static final short TEN_BY_FOURTEEN_PAPERSIZE = 16; - /** 11 x 17 in */ - public static final short ELEVEN_BY_SEVENTEEN_PAPERSIZE = 17; - /** US Note 8 1/2 x 11 in */ - public static final short NOTE8_PAPERSIZE = 18; - /** US Envelope #9 3 7/8 x 8 7/8 */ - public static final short ENVELOPE_9_PAPERSIZE = 19; - /** US Envelope #10 4 1/8 x 9 1/2 */ - public static final short ENVELOPE_10_PAPERSIZE = 20; - /** Envelope DL 110x220 mm */ - public static final short ENVELOPE_DL_PAPERSIZE = 27; - /** Envelope C5 162x229 mm */ - public static final short ENVELOPE_CS_PAPERSIZE = 28; - public static final short ENVELOPE_C5_PAPERSIZE = 28; - /** Envelope C3 324x458 mm */ - public static final short ENVELOPE_C3_PAPERSIZE = 29; - /** Envelope C4 229x324 mm */ - public static final short ENVELOPE_C4_PAPERSIZE = 30; - /** Envelope C6 114x162 mm */ - public static final short ENVELOPE_C6_PAPERSIZE = 31; - - public static final short ENVELOPE_MONARCH_PAPERSIZE = 37; - /** A4 Extra - 9.27 x 12.69 in */ - public static final short A4_EXTRA_PAPERSIZE = 53; - /** A4 Transverse - 210x297 mm */ - public static final short A4_TRANSVERSE_PAPERSIZE = 55; - /** A4 Plus - 210x330 mm */ - public static final short A4_PLUS_PAPERSIZE = 60; - /** US Letter Rotated 11 x 8 1/2 in */ - public static final short LETTER_ROTATED_PAPERSIZE = 75; - /** A4 Rotated - 297x210 mm */ - public static final short A4_ROTATED_PAPERSIZE = 77; - - /** - * Set the paper size. - * @param size the paper size. - */ - void setPaperSize(short size); - - /** - * Set the scale. - * @param scale the scale to use - */ - void setScale(short scale); - - /** - * Set the page numbering start. - * @param start the page numbering start - */ - void setPageStart(short start); - - /** - * Set the number of pages wide to fit the sheet in - * @param width the number of pages - */ - void setFitWidth(short width); - - /** - * Set the number of pages high to fit the sheet in - * @param height the number of pages - */ - void setFitHeight(short height); - - /** - * Set whether to go left to right or top down in ordering - * @param ltor left to right - */ - void setLeftToRight(boolean ltor); - - /** - * Set whether to print in landscape - * @param ls landscape - */ - void setLandscape(boolean ls); - - /** - * Valid settings. I'm not for sure. - * @param valid Valid - */ - void setValidSettings(boolean valid); - - /** - * Set whether it is black and white - * @param mono Black and white - */ - void setNoColor(boolean mono); - - /** - * Set whether it is in draft mode - * @param d draft - */ - void setDraft(boolean d); - - /** - * Print the include notes - * @param printnotes print the notes - */ - void setNotes(boolean printnotes); - - /** - * Set no orientation. ? - * @param orientation Orientation. - */ - void setNoOrientation(boolean orientation); - - /** - * Set whether to use page start - * @param page Use page start - */ - void setUsePage(boolean page); - - /** - * Sets the horizontal resolution. - * @param resolution horizontal resolution - */ - void setHResolution(short resolution); - - /** - * Sets the vertical resolution. - * @param resolution vertical resolution - */ - void setVResolution(short resolution); - - /** - * Sets the header margin. - * @param headermargin header margin - */ - void setHeaderMargin(double headermargin); - - /** - * Sets the footer margin. - * @param footermargin footer margin - */ - void setFooterMargin(double footermargin); - - /** - * Sets the number of copies. - * @param copies number of copies - */ - void setCopies(short copies); - - /** - * Returns the paper size. - * @return paper size - */ - short getPaperSize(); - - /** - * Returns the scale. - * @return scale - */ - short getScale(); - - /** - * Returns the page start. - * @return page start - */ - short getPageStart(); - - /** - * Returns the number of pages wide to fit sheet in. - * @return number of pages wide to fit sheet in - */ - short getFitWidth(); - - /** - * Returns the number of pages high to fit the sheet in. - * @return number of pages high to fit the sheet in - */ - short getFitHeight(); - - /** - * Returns the left to right print order. - * @return left to right print order - */ - boolean getLeftToRight(); - - /** - * Returns the landscape mode. - * @return landscape mode - */ - boolean getLandscape(); - - /** - * Returns the valid settings. - * @return valid settings - */ - boolean getValidSettings(); - - /** - * Returns the black and white setting. - * @return black and white setting - */ - boolean getNoColor(); - - /** - * Returns the draft mode. - * @return draft mode - */ - boolean getDraft(); - - /** - * Returns the print notes. - * @return print notes - */ - boolean getNotes(); - - /** - * Returns the no orientation. - * @return no orientation - */ - boolean getNoOrientation(); - - /** - * Returns the use page numbers. - * @return use page numbers - */ - boolean getUsePage(); - - /** - * Returns the horizontal resolution. - * @return horizontal resolution - */ - short getHResolution(); - - /** - * Returns the vertical resolution. - * @return vertical resolution - */ - short getVResolution(); - - /** - * Returns the header margin. - * @return header margin - */ - double getHeaderMargin(); - - /** - * Returns the footer margin. - * @return footer margin - */ - double getFooterMargin(); - - /** - * Returns the number of copies. - * @return number of copies - */ - short getCopies(); - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/RichTextString.java b/trunk/src/java/org/apache/poi/ss/usermodel/RichTextString.java deleted file mode 100644 index 551fede97..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/RichTextString.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * Rich text unicode string. These strings can have fonts - * applied to arbitary parts of the string. - * - * @author Glen Stampoultzis (glens at apache.org) - * @author Jason Height (jheight at apache.org) - */ -public interface RichTextString { - - /** - * Applies a font to the specified characters of a string. - * - * @param startIndex The start index to apply the font to (inclusive) - * @param endIndex The end index to apply the font to (exclusive) - * @param fontIndex The font to use. - */ - void applyFont(int startIndex, int endIndex, short fontIndex); - - /** - * Applies a font to the specified characters of a string. - * - * @param startIndex The start index to apply the font to (inclusive) - * @param endIndex The end index to apply to font to (exclusive) - * @param font The index of the font to use. - */ - void applyFont(int startIndex, int endIndex, Font font); - - /** - * Sets the font of the entire string. - * @param font The font to use. - */ - void applyFont(Font font); - - /** - * Removes any formatting that may have been applied to the string. - */ - void clearFormatting(); - - /** - * Returns the plain string representation. - */ - String getString(); - - /** - * @return the number of characters in the font. - */ - int length(); - - /** - * @return The number of formatting runs used. - * - */ - int numFormattingRuns(); - - /** - * The index within the string to which the specified formatting run applies. - * @param index the index of the formatting run - * @return the index within the string. - */ - int getIndexOfFormattingRun(int index); - - /** - * Applies the specified font to the entire string. - * - * @param fontIndex the font to apply. - */ - void applyFont(short fontIndex); - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Row.java b/trunk/src/java/org/apache/poi/ss/usermodel/Row.java deleted file mode 100644 index f58775704..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Row.java +++ /dev/null @@ -1,287 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.Iterator; - -import org.apache.poi.util.Removal; - -/** - * High level representation of a row of a spreadsheet. - */ -public interface Row extends Iterable { - - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned is a {@link CellType#BLANK}. The type can be changed - * either through calling setCellValue or setCellType. - * - * @param column - the column number this cell represents - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greater than the maximum number of supported columns - * (255 for *.xls, 1048576 for *.xlsx) - */ - Cell createCell(int column); - - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned will be of the requested type. - * The type can be changed either through calling setCellValue - * or setCellType, but there is a small overhead to doing this, - * so it is best to create of the required type up front. - * - * @param column - the column number this cell represents - * @param type - the cell's data type - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greater than a maximum number of supported columns - * (255 for *.xls, 1048576 for *.xlsx) - * @see CellType#BLANK - * @see CellType#BOOLEAN - * @see CellType#ERROR - * @see CellType#FORMULA - * @see CellType#NUMERIC - * @see CellType#STRING - * @deprecated POI 3.15 beta 3. Use {@link #createCell(int, CellType)} instead. - */ - Cell createCell(int column, int type); - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned will be of the requested type. - * The type can be changed either through calling setCellValue - * or setCellType, but there is a small overhead to doing this, - * so it is best to create of the required type up front. - * - * @param column - the column number this cell represents - * @param type - the cell's data type - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greater than a maximum number of supported columns - * (255 for *.xls, 1048576 for *.xlsx) - */ - Cell createCell(int column, CellType type); - - /** - * Remove the Cell from this row. - * - * @param cell the cell to remove - */ - void removeCell(Cell cell); - - /** - * Set the row number of this row. - * - * @param rowNum the row number (0-based) - * @throws IllegalArgumentException if rowNum < 0 - */ - void setRowNum(int rowNum); - - /** - * Get row number this row represents - * - * @return the row number (0 based) - */ - int getRowNum(); - - /** - * Get the cell representing a given column (logical cell) 0-based. If you - * ask for a cell that is not defined....you get a null. - * - * @param cellnum 0 based column number - * @return Cell representing that column or null if undefined. - * @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy) - */ - Cell getCell(int cellnum); - - /** - * Returns the cell at the given (0 based) index, with the specified {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} - * - * @return the cell at the given (0 based) index - * @throws IllegalArgumentException if cellnum < 0 or the specified MissingCellPolicy is invalid - */ - Cell getCell(int cellnum, MissingCellPolicy policy); - - /** - * Get the number of the first cell contained in this row. - * - * @return short representing the first logical cell in the row, - * or -1 if the row does not contain any cells. - */ - short getFirstCellNum(); - - /** - * Gets the index of the last cell contained in this row PLUS ONE. The result also - * happens to be the 1-based column number of the last cell. This value can be used as a - * standard upper bound when iterating over cells: - *

        -     * short minColIx = row.getFirstCellNum();
        -     * short maxColIx = row.getLastCellNum();
        -     * for(short colIx=minColIx; colIx<maxColIx; colIx++) {
        -     *   Cell cell = row.getCell(colIx);
        -     *   if(cell == null) {
        -     *     continue;
        -     *   }
        -     *   //... do something with cell
        -     * }
        -     * 
        - * - * @return short representing the last logical cell in the row PLUS ONE, - * or -1 if the row does not contain any cells. - */ - short getLastCellNum(); - - /** - * Gets the number of defined cells (NOT number of cells in the actual row!). - * That is to say if only columns 0,4,5 have values then there would be 3. - * - * @return int representing the number of defined cells in the row. - */ - int getPhysicalNumberOfCells(); - - /** - * Set the row's height or set to ff (-1) for undefined/default-height. Set the height in "twips" or - * 1/20th of a point. - * - * @param height rowheight or 0xff for undefined (use sheet default) - */ - void setHeight(short height); - - /** - * Set whether or not to display this row with 0 height - * - * @param zHeight height is zero or not. - */ - void setZeroHeight(boolean zHeight); - - /** - * Get whether or not to display this row with 0 height - * - * @return - zHeight height is zero or not. - */ - boolean getZeroHeight(); - - /** - * Set the row's height in points. - * - * @param height the height in points. -1 resets to the default height - */ - void setHeightInPoints(float height); - - /** - * Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned, - * See {@link Sheet#getDefaultRowHeightInPoints()} - * - * @return row height measured in twips (1/20th of a point) - */ - short getHeight(); - - /** - * Returns row height measured in point size. If the height is not set, the default worksheet value is returned, - * See {@link Sheet#getDefaultRowHeightInPoints()} - * - * @return row height measured in point size - * @see Sheet#getDefaultRowHeightInPoints() - */ - float getHeightInPoints(); - - /** - * Is this row formatted? Most aren't, but some rows - * do have whole-row styles. For those that do, you - * can get the formatting from {@link #getRowStyle()} - */ - boolean isFormatted(); - - /** - * Returns the whole-row cell styles. Most rows won't - * have one of these, so will return null. Call - * {@link #isFormatted()} to check first. - */ - CellStyle getRowStyle(); - - /** - * Applies a whole-row cell styling to the row. - */ - void setRowStyle(CellStyle style); - - /** - * @return Cell iterator of the physically defined cells. Note element 4 may - * actually be row cell depending on how many are defined! - */ - Iterator cellIterator(); - - /** - * Returns the Sheet this row belongs to - * - * @return the Sheet that owns this row - */ - Sheet getSheet(); - - /** - * Used to specify the different possible policies - * if for the case of null and blank cells - */ - public enum MissingCellPolicy { - RETURN_NULL_AND_BLANK(1), - RETURN_BLANK_AS_NULL(2), - CREATE_NULL_AS_BLANK(3); - - /** - * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - the id has no function and will be removed. - * The {@code id} is only kept only for backwards compatibility with applications that hard-coded the number - */ - @Removal(version="3.17") - @Deprecated - public final int id; - private MissingCellPolicy(int id) { - this.id = id; - } - } - - /** - * Missing cells are returned as null, Blank cells are returned as normal - * - * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - use the MissingCellPolicy enum - **/ - @Removal(version="3.17") - @Deprecated - public static final MissingCellPolicy RETURN_NULL_AND_BLANK = MissingCellPolicy.RETURN_NULL_AND_BLANK; - /** - * Missing cells and blank cells are returned as null - * - * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - use the MissingCellPolicy enum - **/ - @Removal(version="3.17") - @Deprecated - public static final MissingCellPolicy RETURN_BLANK_AS_NULL = MissingCellPolicy.RETURN_BLANK_AS_NULL; - /** - * A new, blank cell is created for missing cells. Blank cells are returned as normal - * - * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - use the MissingCellPolicy enum - **/ - @Removal(version="3.17") - @Deprecated - public static final MissingCellPolicy CREATE_NULL_AS_BLANK = MissingCellPolicy.CREATE_NULL_AS_BLANK; - - /** - * Returns the rows outline level. Increased as you - * put it into more groups (outlines), reduced as - * you take it out of them. - */ - public int getOutlineLevel(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java b/trunk/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java deleted file mode 100644 index 3c5747ee5..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java +++ /dev/null @@ -1,212 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * All known types of automatic shapes in DrawingML - * - * @author Yegor Kozlov - */ -public class ShapeTypes { - public static final int LINE = 1; - public static final int LINE_INV = 2; - public static final int TRIANGLE = 3; - public static final int RT_TRIANGLE = 4; - public static final int RECT = 5; - public static final int DIAMOND = 6; - public static final int PARALLELOGRAM = 7; - public static final int TRAPEZOID = 8; - public static final int NON_ISOSCELES_TRAPEZOID = 9; - public static final int PENTAGON = 10; - public static final int HEXAGON = 11; - public static final int HEPTAGON = 12; - public static final int OCTAGON = 13; - public static final int DECAGON = 14; - public static final int DODECAGON = 15; - public static final int STAR_4 = 16; - public static final int STAR_5 = 17; - public static final int STAR_6 = 18; - public static final int STAR_7 = 19; - public static final int STAR_8 = 20; - public static final int STAR_10 = 21; - public static final int STAR_12 = 22; - public static final int STAR_16 = 23; - public static final int STAR_24 = 24; - public static final int STAR_32 = 25; - public static final int ROUND_RECT = 26; - public static final int ROUND_1_RECT = 27; - public static final int ROUND_2_SAME_RECT = 28; - public static final int ROUND_2_DIAG_RECT = 29; - public static final int SNIP_ROUND_RECT = 30; - public static final int SNIP_1_RECT = 31; - public static final int SNIP_2_SAME_RECT = 32; - public static final int SNIP_2_DIAG_RECT = 33; - public static final int PLAQUE = 34; - public static final int ELLIPSE = 35; - public static final int TEARDROP = 36; - public static final int HOME_PLATE = 37; - public static final int CHEVRON = 38; - public static final int PIE_WEDGE = 39; - public static final int PIE = 40; - public static final int BLOCK_ARC = 41; - public static final int DONUT = 42; - public static final int NO_SMOKING = 43; - public static final int RIGHT_ARROW = 44; - public static final int LEFT_ARROW = 45; - public static final int UP_ARROW = 46; - public static final int DOWN_ARROW = 47; - public static final int STRIPED_RIGHT_ARROW = 48; - public static final int NOTCHED_RIGHT_ARROW = 49; - public static final int BENT_UP_ARROW = 50; - public static final int LEFT_RIGHT_ARROW = 51; - public static final int UP_DOWN_ARROW = 52; - public static final int LEFT_UP_ARROW = 53; - public static final int LEFT_RIGHT_UP_ARROW = 54; - public static final int QUAD_ARROW = 55; - public static final int LEFT_ARROW_CALLOUT = 56; - public static final int RIGHT_ARROW_CALLOUT = 57; - public static final int UP_ARROW_CALLOUT = 58; - public static final int DOWN_ARROW_CALLOUT = 59; - public static final int LEFT_RIGHT_ARROW_CALLOUT = 60; - public static final int UP_DOWN_ARROW_CALLOUT = 61; - public static final int QUAD_ARROW_CALLOUT = 62; - public static final int BENT_ARROW = 63; - public static final int UTURN_ARROW = 64; - public static final int CIRCULAR_ARROW = 65; - public static final int LEFT_CIRCULAR_ARROW = 66; - public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67; - public static final int CURVED_RIGHT_ARROW = 68; - public static final int CURVED_LEFT_ARROW = 69; - public static final int CURVED_UP_ARROW = 70; - public static final int CURVED_DOWN_ARROW = 71; - public static final int SWOOSH_ARROW = 72; - public static final int CUBE = 73; - public static final int CAN = 74; - public static final int LIGHTNING_BOLT = 75; - public static final int HEART = 76; - public static final int SUN = 77; - public static final int MOON = 78; - public static final int SMILEY_FACE = 79; - public static final int IRREGULAR_SEAL_1 = 80; - public static final int IRREGULAR_SEAL_2 = 81; - public static final int FOLDED_CORNER = 82; - public static final int BEVEL = 83; - public static final int FRAME = 84; - public static final int HALF_FRAME = 85; - public static final int CORNER = 86; - public static final int DIAG_STRIPE = 87; - public static final int CHORD = 88; - public static final int ARC = 89; - public static final int LEFT_BRACKET = 90; - public static final int RIGHT_BRACKET = 91; - public static final int LEFT_BRACE = 92; - public static final int RIGHT_BRACE = 93; - public static final int BRACKET_PAIR = 94; - public static final int BRACE_PAIR = 95; - public static final int STRAIGHT_CONNECTOR_1 = 96; - public static final int BENT_CONNECTOR_2 = 97; - public static final int BENT_CONNECTOR_3 = 98; - public static final int BENT_CONNECTOR_4 = 99; - public static final int BENT_CONNECTOR_5 = 100; - public static final int CURVED_CONNECTOR_2 = 101; - public static final int CURVED_CONNECTOR_3 = 102; - public static final int CURVED_CONNECTOR_4 = 103; - public static final int CURVED_CONNECTOR_5 = 104; - public static final int CALLOUT_1 = 105; - public static final int CALLOUT_2 = 106; - public static final int CALLOUT_3 = 107; - public static final int ACCENT_CALLOUT_1 = 108; - public static final int ACCENT_CALLOUT_2 = 109; - public static final int ACCENT_CALLOUT_3 = 110; - public static final int BORDER_CALLOUT_1 = 111; - public static final int BORDER_CALLOUT_2 = 112; - public static final int BORDER_CALLOUT_3 = 113; - public static final int ACCENT_BORDER_CALLOUT_1 = 114; - public static final int ACCENT_BORDER_CALLOUT_2 = 115; - public static final int ACCENT_BORDER_CALLOUT_3 = 116; - public static final int WEDGE_RECT_CALLOUT = 117; - public static final int WEDGE_ROUND_RECT_CALLOUT = 118; - public static final int WEDGE_ELLIPSE_CALLOUT = 119; - public static final int CLOUD_CALLOUT = 120; - public static final int CLOUD = 121; - public static final int RIBBON = 122; - public static final int RIBBON_2 = 123; - public static final int ELLIPSE_RIBBON = 124; - public static final int ELLIPSE_RIBBON_2 = 125; - public static final int LEFT_RIGHT_RIBBON = 126; - public static final int VERTICAL_SCROLL = 127; - public static final int HORIZONTAL_SCROLL = 128; - public static final int WAVE = 129; - public static final int DOUBLE_WAVE = 130; - public static final int PLUS = 131; - public static final int FLOW_CHART_PROCESS = 132; - public static final int FLOW_CHART_DECISION = 133; - public static final int FLOW_CHART_INPUT_OUTPUT = 134; - public static final int FLOW_CHART_PREDEFINED_PROCESS = 135; - public static final int FLOW_CHART_INTERNAL_STORAGE = 136; - public static final int FLOW_CHART_DOCUMENT = 137; - public static final int FLOW_CHART_MULTIDOCUMENT = 138; - public static final int FLOW_CHART_TERMINATOR = 139; - public static final int FLOW_CHART_PREPARATION = 140; - public static final int FLOW_CHART_MANUAL_INPUT = 141; - public static final int FLOW_CHART_MANUAL_OPERATION = 142; - public static final int FLOW_CHART_CONNECTOR = 143; - public static final int FLOW_CHART_PUNCHED_CARD = 144; - public static final int FLOW_CHART_PUNCHED_TAPE = 145; - public static final int FLOW_CHART_SUMMING_JUNCTION = 146; - public static final int FLOW_CHART_OR = 147; - public static final int FLOW_CHART_COLLATE = 148; - public static final int FLOW_CHART_SORT = 149; - public static final int FLOW_CHART_EXTRACT = 150; - public static final int FLOW_CHART_MERGE = 151; - public static final int FLOW_CHART_OFFLINE_STORAGE = 152; - public static final int FLOW_CHART_ONLINE_STORAGE = 153; - public static final int FLOW_CHART_MAGNETIC_TAPE = 154; - public static final int FLOW_CHART_MAGNETIC_DISK = 155; - public static final int FLOW_CHART_MAGNETIC_DRUM = 156; - public static final int FLOW_CHART_DISPLAY = 157; - public static final int FLOW_CHART_DELAY = 158; - public static final int FLOW_CHART_ALTERNATE_PROCESS = 159; - public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160; - public static final int ACTION_BUTTON_BLANK = 161; - public static final int ACTION_BUTTON_HOME = 162; - public static final int ACTION_BUTTON_HELP = 163; - public static final int ACTION_BUTTON_INFORMATION = 164; - public static final int ACTION_BUTTON_FORWARD_NEXT = 165; - public static final int ACTION_BUTTON_BACK_PREVIOUS = 166; - public static final int ACTION_BUTTON_END = 167; - public static final int ACTION_BUTTON_BEGINNING = 168; - public static final int ACTION_BUTTON_RETURN = 169; - public static final int ACTION_BUTTON_DOCUMENT = 170; - public static final int ACTION_BUTTON_SOUND = 171; - public static final int ACTION_BUTTON_MOVIE = 172; - public static final int GEAR_6 = 173; - public static final int GEAR_9 = 174; - public static final int FUNNEL = 175; - public static final int MATH_PLUS = 176; - public static final int MATH_MINUS = 177; - public static final int MATH_MULTIPLY = 178; - public static final int MATH_DIVIDE = 179; - public static final int MATH_EQUAL = 180; - public static final int MATH_NOT_EQUAL = 181; - public static final int CORNER_TABS = 182; - public static final int SQUARE_TABS = 183; - public static final int PLAQUE_TABS = 184; - public static final int CHART_X = 185; - public static final int CHART_STAR = 186; - public static final int CHART_PLUS = 187; -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Sheet.java b/trunk/src/java/org/apache/poi/ss/usermodel/Sheet.java deleted file mode 100644 index 4c171ff2c..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Sheet.java +++ /dev/null @@ -1,1192 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.PaneInformation; -import org.apache.poi.util.Removal; - -/** - * High level representation of a Excel worksheet. - * - *

        - * Sheets are the central structures within a workbook, and are where a user does most of his spreadsheet work. - * The most common type of sheet is the worksheet, which is represented as a grid of cells. Worksheet cells can - * contain text, numbers, dates, and formulas. Cells can also be formatted. - *

        - */ -public interface Sheet extends Iterable { - - /* Constants for margins */ - public static final short LeftMargin = 0; - - public static final short RightMargin = 1; - - public static final short TopMargin = 2; - - public static final short BottomMargin = 3; - - public static final short HeaderMargin = 4; - - public static final short FooterMargin = 5; - - public static final byte PANE_LOWER_RIGHT = (byte) 0; - - public static final byte PANE_UPPER_RIGHT = (byte) 1; - - public static final byte PANE_LOWER_LEFT = (byte) 2; - - public static final byte PANE_UPPER_LEFT = (byte) 3; - - /** - * Create a new row within the sheet and return the high level representation - * - * @param rownum row number - * @return high level Row object representing a row in the sheet - * @see #removeRow(Row) - */ - Row createRow(int rownum); - - /** - * Remove a row from this sheet. All cells contained in the row are removed as well - * - * @param row representing a row to remove. - */ - void removeRow(Row row); - - /** - * Returns the logical row (not physical) 0-based. If you ask for a row that is not - * defined you get a null. This is to say row 4 represents the fifth row on a sheet. - * - * @param rownum row to get (0-based) - * @return Row representing the rownumber or null if its not defined on the sheet - */ - Row getRow(int rownum); - - /** - * Returns the number of physically defined rows (NOT the number of rows in the sheet) - * - * @return the number of physically defined rows in this sheet - */ - int getPhysicalNumberOfRows(); - - /** - * Gets the first row on the sheet - * - * @return the number of the first logical row on the sheet (0-based) - */ - int getFirstRowNum(); - - /** - * Gets the last row on the sheet - * - * @return last row contained n this sheet (0-based) - */ - int getLastRowNum(); - - /** - * Get the visibility state for a given column - * - * @param columnIndex - the column to get (0-based) - * @param hidden - the visiblity state of the column - */ - void setColumnHidden(int columnIndex, boolean hidden); - - /** - * Get the hidden state for a given column - * - * @param columnIndex - the column to set (0-based) - * @return hidden - false if the column is visible - */ - boolean isColumnHidden(int columnIndex); - - /** - * Sets whether the worksheet is displayed from right to left instead of from left to right. - * - * @param value true for right to left, false otherwise. - */ - public void setRightToLeft(boolean value); - - /** - * Whether the text is displayed in right-to-left mode in the window - * - * @return whether the text is displayed in right-to-left mode in the window - */ - public boolean isRightToLeft(); - - /** - * Set the width (in units of 1/256th of a character width)

        - * - * The maximum column width for an individual cell is 255 characters. - * This value represents the number of characters that can be displayed - * in a cell that is formatted with the standard font (first font in the workbook).

        - * - * Character width is defined as the maximum digit width - * of the numbers 0, 1, 2, ... 9 as rendered - * using the default font (first font in the workbook).

        - * - * Unless you are using a very special font, the default character is '0' (zero), - * this is true for Arial (default font font in HSSF) and Calibri (default font in XSSF)

        - * - * Please note, that the width set by this method includes 4 pixels of margin padding (two on each side), - * plus 1 pixel padding for the gridlines (Section 3.3.1.12 of the OOXML spec). - * This results is a slightly less value of visible characters than passed to this method (approx. 1/2 of a character).

        - * - * To compute the actual number of visible characters, - * Excel uses the following formula (Section 3.3.1.12 of the OOXML spec):

        - * - * - * width = Truncate([{Number of Visible Characters} * - * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256 - * - * - * Using the Calibri font as an example, the maximum digit width of 11 point font size is 7 pixels (at 96 dpi). - * If you set a column width to be eight characters wide, e.g. setColumnWidth(columnIndex, 8*256), - * then the actual value of visible characters (the value shown in Excel) is derived from the following equation: - * - * Truncate([numChars*7+5]/7*256)/256 = 8; - * - * - * which gives 7.29. - * - * @param columnIndex - the column to set (0-based) - * @param width - the width in units of 1/256th of a character width - * @throws IllegalArgumentException if width > 255*256 (the maximum column width in Excel is 255 characters) - */ - void setColumnWidth(int columnIndex, int width); - - /** - * get the width (in units of 1/256th of a character width ) - * - *

        - * Character width is defined as the maximum digit width - * of the numbers 0, 1, 2, ... 9 as rendered - * using the default font (first font in the workbook) - *

        - * - * @param columnIndex - the column to get (0-based) - * @return width - the width in units of 1/256th of a character width - */ - int getColumnWidth(int columnIndex); - - /** - * get the width in pixel - * - *

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). - * If the default font is changed the column width can be streched - *

        - * - * @param columnIndex - the column to set (0-based) - * @return width in pixels - */ - float getColumnWidthInPixels(int columnIndex); - - - /** - * Set the default column width for the sheet (if the columns do not define their own width) - * in characters - * - * @param width default column width measured in characters - */ - void setDefaultColumnWidth(int width); - - /** - * Get the default column width for the sheet (if the columns do not define their own width) - * in characters - * - * @return default column width measured in characters - */ - int getDefaultColumnWidth(); - - /** - * Get the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @return default row height measured in twips (1/20 of a point) - */ - short getDefaultRowHeight(); - - /** - * Get the default row height for the sheet (if the rows do not define their own height) in - * points. - * - * @return default row height in points - */ - float getDefaultRowHeightInPoints(); - - /** - * Set the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @param height default row height measured in twips (1/20 of a point) - */ - void setDefaultRowHeight(short height); - - /** - * Set the default row height for the sheet (if the rows do not define their own height) in - * points - * @param height default row height - */ - void setDefaultRowHeightInPoints(float height); - - /** - * Returns the CellStyle that applies to the given - * (0 based) column, or null if no style has been - * set for that column - */ - public CellStyle getColumnStyle(int column); - - /** - * Sets the CellStyle that applies to the given - * (0 based) column. - */ -// public CellStyle setColumnStyle(int column, CellStyle style); - - /** - * Adds a merged region of cells (hence those cells form one) - * - * @param region (rowfrom/colfrom-rowto/colto) to merge - * @return index of this region - */ - int addMergedRegion(CellRangeAddress region); - - /** - * Adds a merged region of cells (hence those cells form one). - * Skips validation. It is possible to create overlapping merged regions - * or create a merged region that intersects a multi-cell array formula - * with this formula, which may result in a corrupt workbook. - * - * To check for merged regions overlapping array formulas or other merged regions - * after addMergedRegionUnsafe has been called, call {@link #validateMergedRegions()}, which runs in O(n^2) time. - * - * @param region to merge - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells - */ - int addMergedRegionUnsafe(CellRangeAddress region); - - /** - * Verify that merged regions do not intersect multi-cell array formulas and - * no merged regions intersect another merged region in this sheet. - * - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if at least one region intersects with another merged region in this sheet - */ - void validateMergedRegions(); - - /** - * Determines whether the output is vertically centered on the page. - * - * @param value true to vertically center, false otherwise. - */ - void setVerticallyCenter(boolean value); - - /** - * Determines whether the output is horizontally centered on the page. - * - * @param value true to horizontally center, false otherwise. - */ - void setHorizontallyCenter(boolean value); - - /** - * Determine whether printed output for this sheet will be horizontally centered. - */ - - boolean getHorizontallyCenter(); - - /** - * Determine whether printed output for this sheet will be vertically centered. - */ - boolean getVerticallyCenter(); - - /** - * Removes a merged region of cells (hence letting them free) - * - * @param index of the region to unmerge - */ - void removeMergedRegion(int index); - - /** - * Removes a number of merged regions of cells (hence letting them free) - * - * @param indices A set of the regions to unmerge - */ - void removeMergedRegions(Collection indices); - - /** - * Returns the number of merged regions - * - * @return number of merged regions - */ - int getNumMergedRegions(); - - /** - * Returns the merged region at the specified index - * - * @return the merged region at the specified index - */ - public CellRangeAddress getMergedRegion(int index); - - /** - * Returns the list of merged regions. - * - * @return the list of merged regions - */ - public List getMergedRegions(); - - /** - * Returns an iterator of the physical rows - * - * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not - * be the third row if say for instance the second row is undefined. - */ - Iterator rowIterator(); - - /** - * Control if Excel should be asked to recalculate all formulas on this sheet - * when the workbook is opened. - * - *

        - * Calculating the formula values with {@link FormulaEvaluator} is the - * recommended solution, but this may be used for certain cases where - * evaluation in POI is not possible. - *

        - * - * To force recalcuation of formulas in the entire workbook - * use {@link Workbook#setForceFormulaRecalculation(boolean)} instead. - * - * @param value true if the application will perform a full recalculation of - * this worksheet values when the workbook is opened - * - * @see Workbook#setForceFormulaRecalculation(boolean) - */ - void setForceFormulaRecalculation(boolean value); - - /** - * Whether Excel will be asked to recalculate all formulas in this sheet when the - * workbook is opened. - */ - boolean getForceFormulaRecalculation(); - - /** - * Flag indicating whether the sheet displays Automatic Page Breaks. - * - * @param value true if the sheet displays Automatic Page Breaks. - */ - void setAutobreaks(boolean value); - - /** - * Set whether to display the guts or not - * - * @param value - guts or no guts - */ - void setDisplayGuts(boolean value); - - /** - * Set whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - * - * @param value whether to display or hide all zero values on the worksheet - */ - void setDisplayZeros(boolean value); - - - /** - * Gets the flag indicating whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - * - * @return whether all zero values on the worksheet are displayed - */ - boolean isDisplayZeros(); - - /** - * Flag indicating whether the Fit to Page print option is enabled. - * - * @param value true if the Fit to Page print option is enabled. - */ - void setFitToPage(boolean value); - - /** - * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. - * - *

        - * When true a summary row is inserted below the detailed data being summarized and a - * new outline level is established on that row. - *

        - *

        - * When false a summary row is inserted above the detailed data being summarized and a new outline level - * is established on that row. - *

        - * @param value true if row summaries appear below detail in the outline - */ - void setRowSumsBelow(boolean value); - - /** - * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. - * - *

        - * When true a summary column is inserted to the right of the detailed data being summarized - * and a new outline level is established on that column. - *

        - *

        - * When false a summary column is inserted to the left of the detailed data being - * summarized and a new outline level is established on that column. - *

        - * @param value true if col summaries appear right of the detail in the outline - */ - void setRowSumsRight(boolean value); - - /** - * Flag indicating whether the sheet displays Automatic Page Breaks. - * - * @return true if the sheet displays Automatic Page Breaks. - */ - boolean getAutobreaks(); - - /** - * Get whether to display the guts or not, - * default value is true - * - * @return boolean - guts or no guts - */ - boolean getDisplayGuts(); - - /** - * Flag indicating whether the Fit to Page print option is enabled. - * - * @return true if the Fit to Page print option is enabled. - */ - boolean getFitToPage(); - - /** - * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. - * - *

        - * When true a summary row is inserted below the detailed data being summarized and a - * new outline level is established on that row. - *

        - *

        - * When false a summary row is inserted above the detailed data being summarized and a new outline level - * is established on that row. - *

        - * @return true if row summaries appear below detail in the outline - */ - boolean getRowSumsBelow(); - - /** - * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. - * - *

        - * When true a summary column is inserted to the right of the detailed data being summarized - * and a new outline level is established on that column. - *

        - *

        - * When false a summary column is inserted to the left of the detailed data being - * summarized and a new outline level is established on that column. - *

        - * @return true if col summaries appear right of the detail in the outline - */ - boolean getRowSumsRight(); - - /** - * Gets the flag indicating whether this sheet displays the lines - * between rows and columns to make editing and reading easier. - * - * @return true if this sheet prints gridlines. - * @see #isDisplayGridlines() to check if gridlines are displayed on screen - */ - boolean isPrintGridlines(); - - /** - * Sets the flag indicating whether this sheet should print the lines - * between rows and columns to make editing and reading easier. - * - * @param show true if this sheet should print gridlines. - * @see #setDisplayGridlines(boolean) to display gridlines on screen - */ - void setPrintGridlines(boolean show); - - /** - * Gets the flag indicating whether this sheet prints the - * row and column headings when printing. - * - * @return true if this sheet prints row and column headings. - */ - boolean isPrintRowAndColumnHeadings(); - - /** - * Sets the flag indicating whether this sheet should print - * row and columns headings when printing. - * - * @param show true if this sheet should print row and column headings. - */ - void setPrintRowAndColumnHeadings(boolean show); - - /** - * Gets the print setup object. - * - * @return The user model for the print setup object. - */ - PrintSetup getPrintSetup(); - - /** - * Gets the user model for the default document header.

        - * - * Note that XSSF offers more kinds of document headers than HSSF does - * - * @return the document header. Never null - */ - Header getHeader(); - - /** - * Gets the user model for the default document footer.

        - * - * Note that XSSF offers more kinds of document footers than HSSF does. - * - * @return the document footer. Never null - */ - Footer getFooter(); - - /** - * Sets a flag indicating whether this sheet is selected.

        - * - * Note: multiple sheets can be selected, but only one sheet can be active at one time. - * - * @param value true if this sheet is selected - * @see Workbook#setActiveSheet(int) - */ - void setSelected(boolean value); - - /** - * Gets the size of the margin in inches. - * - * @param margin which margin to get - * @return the size of the margin - */ - double getMargin(short margin); - - /** - * Sets the size of the margin in inches. - * - * @param margin which margin to get - * @param size the size of the margin - */ - void setMargin(short margin, double size); - - /** - * Answer whether protection is enabled or disabled - * - * @return true => protection enabled; false => protection disabled - */ - boolean getProtect(); - - /** - * Sets the protection enabled as well as the password - * @param password to set for protection. Pass null to remove protection - */ - public void protectSheet(String password); - - /** - * Answer whether scenario protection is enabled or disabled - * - * @return true => protection enabled; false => protection disabled - */ - boolean getScenarioProtect(); - - /** - * Sets the zoom magnication for the sheet. The zoom is expressed as a - * fraction. For example to express a zoom of 75% use 3 for the numerator - * and 4 for the denominator. - * - * @param numerator The numerator for the zoom magnification. - * @param denominator The denominator for the zoom magnification. - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #setZoom(int)} instead. - */ - @Removal(version="3.16") - @Deprecated - void setZoom(int numerator, int denominator); - - /** - * Window zoom magnification for current view representing percent values. - * Valid values range from 10 to 400. Horizontal & Vertical scale together. - * - * For example: - *

        -     * 10 - 10%
        -     * 20 - 20%
        -     * ...
        -     * 100 - 100%
        -     * ...
        -     * 400 - 400%
        -     * 
        - * - * @param scale window zoom magnification - * @throws IllegalArgumentException if scale is invalid - */ - public void setZoom(int scale); - - /** - * The top row in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return short indicating the rownum (0 based) of the top row - */ - short getTopRow(); - - /** - * The left col in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return short indicating the rownum (0 based) of the top row - */ - short getLeftCol(); - - /** - * Sets desktop window pane display area, when the - * file is first opened in a viewer. - * - * @param toprow the top row to show in desktop window pane - * @param leftcol the left column to show in desktop window pane - */ - void showInPane(int toprow, int leftcol); - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around. - * - * Calls shiftRows(startRow, endRow, n, false, false); - * - *

        - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - */ - void shiftRows(int startRow, int endRow, int n); - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around - * - *

        - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). All merged regions that are - * completely overlaid by shifting will be deleted. - *

        - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - * @param copyRowHeight whether to copy the row height during the shift - * @param resetOriginalRowHeight whether to set the original row's height to the default - */ - void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight); - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - *

        - * If both colSplit and rowSplit are zero then the existing freeze pane is removed - *

        - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - * @param leftmostColumn Left column visible in right pane. - * @param topRow Top row visible in bottom pane - */ - void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow); - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - *

        - * If both colSplit and rowSplit are zero then the existing freeze pane is removed - *

        - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - */ - void createFreezePane(int colSplit, int rowSplit); - - /** - * Creates a split pane. Any existing freezepane or split pane is overwritten. - * @param xSplitPos Horizonatal position of split (in 1/20th of a point). - * @param ySplitPos Vertical position of split (in 1/20th of a point). - * @param topRow Top row visible in bottom pane - * @param leftmostColumn Left column visible in right pane. - * @param activePane Active pane. One of: PANE_LOWER_RIGHT, - * PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT - * @see #PANE_LOWER_LEFT - * @see #PANE_LOWER_RIGHT - * @see #PANE_UPPER_LEFT - * @see #PANE_UPPER_RIGHT - */ - void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane); - - /** - * Returns the information regarding the currently configured pane (split or freeze) - * - * @return null if no pane configured, or the pane information. - */ - PaneInformation getPaneInformation(); - - /** - * Sets whether the gridlines are shown in a viewer - * - * @param show whether to show gridlines or not - */ - void setDisplayGridlines(boolean show); - - /** - * Returns if gridlines are displayed - * - * @return whether gridlines are displayed - */ - boolean isDisplayGridlines(); - - /** - * Sets whether the formulas are shown in a viewer - * - * @param show whether to show formulas or not - */ - void setDisplayFormulas(boolean show); - - /** - * Returns if formulas are displayed - * - * @return whether formulas are displayed - */ - boolean isDisplayFormulas(); - - /** - * Sets whether the RowColHeadings are shown in a viewer - * - * @param show whether to show RowColHeadings or not - */ - void setDisplayRowColHeadings(boolean show); - - /** - * Returns if RowColHeadings are displayed. - * @return whether RowColHeadings are displayed - */ - boolean isDisplayRowColHeadings(); - - /** - * Sets a page break at the indicated row - * Breaks occur above the specified row and left of the specified column inclusive. - * - * For example, sheet.setColumnBreak(2); breaks the sheet into two parts - * with columns A,B,C in the first and D,E,... in the second. Simuilar, sheet.setRowBreak(2); - * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part - * and rows starting with rownum=4 in the second. - * - * @param row the row to break, inclusive - */ - void setRowBreak(int row); - - /** - * Determines if there is a page break at the indicated row - * @param row FIXME: Document this! - * @return FIXME: Document this! - */ - boolean isRowBroken(int row); - - /** - * Removes the page break at the indicated row - * @param row - */ - void removeRowBreak(int row); - - /** - * Retrieves all the horizontal page breaks - * @return all the horizontal page breaks, or null if there are no row page breaks - */ - int[] getRowBreaks(); - - /** - * Retrieves all the vertical page breaks - * @return all the vertical page breaks, or null if there are no column page breaks - */ - int[] getColumnBreaks(); - - /** - * Sets a page break at the indicated column. - * Breaks occur above the specified row and left of the specified column inclusive. - * - * For example, sheet.setColumnBreak(2); breaks the sheet into two parts - * with columns A,B,C in the first and D,E,... in the second. Simuilar, sheet.setRowBreak(2); - * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part - * and rows starting with rownum=4 in the second. - * - * @param column the column to break, inclusive - */ - void setColumnBreak(int column); - - /** - * Determines if there is a page break at the indicated column - * @param column FIXME: Document this! - * @return FIXME: Document this! - */ - boolean isColumnBroken(int column); - - /** - * Removes a page break at the indicated column - * @param column - */ - void removeColumnBreak(int column); - - /** - * Expands or collapses a column group. - * - * @param columnNumber One of the columns in the group. - * @param collapsed true = collapse group, false = expand group. - */ - void setColumnGroupCollapsed(int columnNumber, boolean collapsed); - - /** - * Create an outline for the provided column range. - * - * @param fromColumn beginning of the column range. - * @param toColumn end of the column range. - */ - void groupColumn(int fromColumn, int toColumn); - - /** - * Ungroup a range of columns that were previously grouped - * - * @param fromColumn start column (0-based) - * @param toColumn end column (0-based) - */ - void ungroupColumn(int fromColumn, int toColumn); - - /** - * Tie a range of rows together so that they can be collapsed or expanded - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - void groupRow(int fromRow, int toRow); - - /** - * Ungroup a range of rows that were previously grouped - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - void ungroupRow(int fromRow, int toRow); - - /** - * Set view state of a grouped range of rows - * - * @param row start row of a grouped range of rows (0-based) - * @param collapse whether to expand/collapse the detail rows - */ - void setRowGroupCollapsed(int row, boolean collapse); - - /** - * Sets the default column style for a given column. POI will only apply this style to new cells added to the sheet. - * - * @param column the column index - * @param style the style to set - */ - void setDefaultColumnStyle(int column, CellStyle style); - - /** - * Adjusts the column width to fit the contents. - * - *

        - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - *

        - * You can specify whether the content of merged cells should be considered or ignored. - * Default is to ignore merged cells. - * - * @param column the column index - */ - void autoSizeColumn(int column); - - /** - * Adjusts the column width to fit the contents. - *

        - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - *

        - * You can specify whether the content of merged cells should be considered or ignored. - * Default is to ignore merged cells. - * - * @param column the column index - * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column - */ - void autoSizeColumn(int column, boolean useMergedCells); - - /** - * Returns cell comment for the specified row and column - * - * @return cell comment or null if not found - * @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellAddress)} instead. - */ - @Deprecated - Comment getCellComment(int row, int column); - - /** - * Returns cell comment for the specified location - * - * @return cell comment or null if not found - */ - Comment getCellComment(CellAddress ref); - - /** - * Returns all cell comments on this sheet. - * @return A map of each Comment in the sheet, keyed on the cell address where - * the comment is located. - */ - Map getCellComments(); - - /** - * Return the sheet's existing drawing, or null if there isn't yet one. - * - * Use {@link #createDrawingPatriarch()} to get or create - * - * @return a SpreadsheetML drawing - */ - Drawing getDrawingPatriarch(); - - /** - * Creates the top-level drawing patriarch. - *

        This may then be used to add graphics or charts.

        - *

        Note that this will normally have the effect of removing - * any existing drawings on this sheet.

        - * - * @return The new drawing patriarch. - */ - Drawing createDrawingPatriarch(); - - - /** - * Return the parent workbook - * - * @return the parent workbook - */ - Workbook getWorkbook(); - - /** - * Returns the name of this sheet - * - * @return the name of this sheet - */ - String getSheetName(); - - /** - * Note - this is not the same as whether the sheet is focused (isActive) - * @return true if this sheet is currently selected - */ - boolean isSelected(); - - - /** - * Sets array formula to specified region for result. - * - * @param formula text representation of the formula - * @param range Region of array formula for result. - * @return the {@link CellRange} of cells affected by this change - */ - CellRange setArrayFormula(String formula, CellRangeAddress range); - - /** - * Remove a Array Formula from this sheet. All cells contained in the Array Formula range are removed as well - * - * @param cell any cell within Array Formula range - * @return the {@link CellRange} of cells affected by this change - */ - CellRange removeArrayFormula(Cell cell); - - public DataValidationHelper getDataValidationHelper(); - - /** - * Returns the list of DataValidation in the sheet. - * @return list of DataValidation in the sheet - */ - public List getDataValidations(); - - /** - * Creates a data validation object - * @param dataValidation The Data validation object settings - */ - public void addValidationData(DataValidation dataValidation); - - /** - * Enable filtering for a range of cells - * - * @param range the range of cells to filter - */ - AutoFilter setAutoFilter(CellRangeAddress range); - - /** - * The 'Conditional Formatting' facet for this Sheet - * - * @return conditional formatting rule for this sheet - */ - SheetConditionalFormatting getSheetConditionalFormatting(); - - - /** - * Gets the repeating rows used when printing the sheet, as found in - * File->PageSetup->Sheet.

        - * - * Repeating rows cover a range of contiguous rows, e.g.: - *

        -     * Sheet1!$1:$1
        -     * Sheet2!$5:$8
        -     * 
        - * The {@link CellRangeAddress} returned contains a column part which spans - * all columns, and a row part which specifies the contiguous range of - * repeating rows.

        - * - * If the Sheet does not have any repeating rows defined, null is returned. - * - * @return an {@link CellRangeAddress} containing the repeating rows for the - * Sheet, or null. - */ - CellRangeAddress getRepeatingRows(); - - - /** - * Gets the repeating columns used when printing the sheet, as found in - * File->PageSetup->Sheet.

        - * - * Repeating columns cover a range of contiguous columns, e.g.: - *

        -     * Sheet1!$A:$A
        -     * Sheet2!$C:$F
        -     * 
        - * The {@link CellRangeAddress} returned contains a row part which spans all - * rows, and a column part which specifies the contiguous range of - * repeating columns.

        - * - * If the Sheet does not have any repeating columns defined, null is - * returned. - * - * @return an {@link CellRangeAddress} containing the repeating columns for - * the Sheet, or null. - */ - CellRangeAddress getRepeatingColumns(); - - - /** - * Sets the repeating rows used when printing the sheet, as found in - * File->PageSetup->Sheet.

        - * - * Repeating rows cover a range of contiguous rows, e.g.: - *

        -     * Sheet1!$1:$1
        -     * Sheet2!$5:$8
        - * The parameter {@link CellRangeAddress} should specify a column part - * which spans all columns, and a row part which specifies the contiguous - * range of repeating rows, e.g.: - *
        -     * sheet.setRepeatingRows(CellRangeAddress.valueOf("2:3"));
        - * A null parameter value indicates that repeating rows should be removed - * from the Sheet: - *
        -     * sheet.setRepeatingRows(null);
        - * - * @param rowRangeRef a {@link CellRangeAddress} containing the repeating - * rows for the Sheet, or null. - */ - void setRepeatingRows(CellRangeAddress rowRangeRef); - - - /** - * Sets the repeating columns used when printing the sheet, as found in - * File->PageSetup->Sheet.

        - * - * Repeating columns cover a range of contiguous columns, e.g.: - *

        -     * Sheet1!$A:$A
        -     * Sheet2!$C:$F
        - * The parameter {@link CellRangeAddress} should specify a row part - * which spans all rows, and a column part which specifies the contiguous - * range of repeating columns, e.g.: - *
        -     * sheet.setRepeatingColumns(CellRangeAddress.valueOf("B:C"));
        - * A null parameter value indicates that repeating columns should be removed - * from the Sheet: - *
        -     * sheet.setRepeatingColumns(null);
        - * - * @param columnRangeRef a {@link CellRangeAddress} containing the repeating - * columns for the Sheet, or null. - */ - void setRepeatingColumns(CellRangeAddress columnRangeRef); - - /** - * Returns the column outline level. Increased as you - * put it into more groups (outlines), reduced as - * you take it out of them. - */ - int getColumnOutlineLevel(int columnIndex); - - /** - * Get a Hyperlink in this sheet anchored at row, column - * - * @param row - * @param column - * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null - */ - public Hyperlink getHyperlink(int row, int column); - - /** - * Get a Hyperlink in this sheet located in a cell specified by {code addr} - * - * @param addr The address of the cell containing the hyperlink - * @return hyperlink if there is a hyperlink anchored at {@code addr}; otherwise returns {@code null} - * @since POI 3.15 beta 3 - */ - public Hyperlink getHyperlink(CellAddress addr); - - /** - * Get a list of Hyperlinks in this sheet - * - * @return Hyperlinks for the sheet - */ - public List getHyperlinkList(); - - /** - * Return location of the active cell, e.g. A1. - * - * @return the location of the active cell. - * @since 3.14beta1 - */ - public CellAddress getActiveCell(); - - /** - * Sets location of the active cell - * - * @param address the location of the active cell, e.g. A1. - * @since 3.14beta1 - */ - public void setActiveCell(CellAddress address); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java b/trunk/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java deleted file mode 100644 index 853eec6ff..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet; -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * The 'Conditional Formatting' facet of Sheet - * - * @since 3.8 - */ -public interface SheetConditionalFormatting { - /** - * Add a new Conditional Formatting to the sheet. - * - * @param regions - list of rectangular regions to apply conditional formatting rules - * @param rule - the rule to apply - * - * @return index of the newly created Conditional Formatting object - */ - int addConditionalFormatting(CellRangeAddress[] regions, - ConditionalFormattingRule rule); - - /** - * Add a new Conditional Formatting consisting of two rules. - * - * @param regions - list of rectangular regions to apply conditional formatting rules - * @param rule1 - the first rule - * @param rule2 - the second rule - * - * @return index of the newly created Conditional Formatting object - */ - int addConditionalFormatting(CellRangeAddress[] regions, - ConditionalFormattingRule rule1, - ConditionalFormattingRule rule2); - - /** - * Add a new Conditional Formatting set to the sheet. - * - * @param regions - list of rectangular regions to apply conditional formatting rules - * @param cfRules - set of up to conditional formatting rules (max 3 for Excel pre-2007) - * - * @return index of the newly created Conditional Formatting object - */ - int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules); - - /** - * Adds a copy of a ConditionalFormatting object to the sheet - *

        - * This method could be used to copy ConditionalFormatting object - * from one sheet to another. For example: - *

        - *
        -     * ConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
        -     * newSheet.addConditionalFormatting(cf);
        -     * 
        - * - * @param cf the Conditional Formatting to clone - * @return index of the new Conditional Formatting object - */ - int addConditionalFormatting(ConditionalFormatting cf); - - /** - * A factory method allowing to create a conditional formatting rule - * with a cell comparison operator - *

        - * The created conditional formatting rule compares a cell value - * to a formula calculated result, using the specified operator. - * The type of the created condition is {@link ConditionType#CELL_VALUE_IS} - *

        - * - * @param comparisonOperation - MUST be a constant value from - * {@link ComparisonOperator}:

        - *

          - *
        • BETWEEN
        • - *
        • NOT_BETWEEN
        • - *
        • EQUAL
        • - *
        • NOT_EQUAL
        • - *
        • GT
        • - *
        • LT
        • - *
        • GE
        • - *
        • LE
        • - *
        - *

        - * @param formula1 - formula for the valued, compared with the cell - * @param formula2 - second formula (only used with - * {@link ComparisonOperator#BETWEEN}) and {@link ComparisonOperator#NOT_BETWEEN} operations) - */ - ConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula1, - String formula2); - - /** - * Create a conditional formatting rule that compares a cell value - * to a formula calculated result, using an operator * - *

        - * The type of the created condition is {@link ConditionType#CELL_VALUE_IS} - *

        - * - * @param comparisonOperation MUST be a constant value from - * {@link ComparisonOperator} except BETWEEN and NOT_BETWEEN - * - * @param formula the formula to determine if the conditional formatting is applied - */ - ConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula); - - /** - * Create a conditional formatting rule based on a Boolean formula. - * When the formula result is true, the cell is highlighted. - * - *

        - * The type of the created format condition is {@link ConditionType#FORMULA} - *

        - * @param formula the formula to evaluate. MUST be a Boolean function. - */ - ConditionalFormattingRule createConditionalFormattingRule(String formula); - - /** - * Create a Databar conditional formatting rule. - *

        The thresholds and colour for it will be created, but will be - * empty and require configuring with - * {@link ConditionalFormattingRule#getDataBarFormatting()} - * then - * {@link DataBarFormatting#getMinThreshold()} - * and - * {@link DataBarFormatting#getMaxThreshold()} - */ - ConditionalFormattingRule createConditionalFormattingRule(ExtendedColor color); - - /** - * Create an Icon Set / Multi-State conditional formatting rule. - *

        The thresholds for it will be created, but will be empty - * and require configuring with - * {@link ConditionalFormattingRule#getMultiStateFormatting()} - * then - * {@link IconMultiStateFormatting#getThresholds()} - */ - ConditionalFormattingRule createConditionalFormattingRule(IconSet iconSet); - - /** - * Create a Color Scale / Color Gradient conditional formatting rule. - *

        The thresholds and colours for it will be created, but will be - * empty and require configuring with - * {@link ConditionalFormattingRule#getColorScaleFormatting()} - * then - * {@link ColorScaleFormatting#getThresholds()} - * and - * {@link ColorScaleFormatting#getColors()} - */ - ConditionalFormattingRule createConditionalFormattingColorScaleRule(); - - /** - * Gets Conditional Formatting object at a particular index - * - * @param index 0-based index of the Conditional Formatting object to fetch - * @return Conditional Formatting object or null if not found - * @throws IllegalArgumentException if the index is outside of the allowable range (0 ... numberOfFormats-1) - */ - ConditionalFormatting getConditionalFormattingAt(int index); - - /** - * - * @return the number of conditional formats in this sheet - */ - int getNumConditionalFormattings(); - - /** - * Removes a Conditional Formatting object by index - * - * @param index 0-based index of the Conditional Formatting object to remove - * @throws IllegalArgumentException if the index is outside of the allowable range (0 ... numberOfFormats-1) - */ - void removeConditionalFormatting(int index); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Table.java b/trunk/src/java/org/apache/poi/ss/usermodel/Table.java deleted file mode 100644 index 8a189d6bd..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Table.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.util.regex.Pattern; - -/** - * XSSF Only! - * High level abstraction of table in a workbook. - */ -public interface Table { - /** - * Regular expression matching a Structured Reference (Table syntax) for XSSF table expressions. - * Public for unit tests - * @see - * Excel Structured Reference Syntax - * - */ - Pattern isStructuredReference = Pattern.compile("[a-zA-Z_\\\\][a-zA-Z0-9._]*\\[.*\\]"); - - /** - * Get the top-left column index relative to the sheet - * @return table start column index on sheet - */ - int getStartColIndex(); - /** - * Get the top-left row index on the sheet - * @return table start row index on sheet - */ - int getStartRowIndex(); - /** - * Get the bottom-right column index on the sheet - * @return table end column index on sheet - */ - int getEndColIndex(); - /** - * Get the bottom-right row index - * @return table end row index on sheet - */ - int getEndRowIndex(); - /** - * Get the name of the table. - * @return table name - */ - String getName(); - - /** - * Returns the index of a given named column in the table (names are case insensitive in XSSF). - * Note this list is lazily loaded and cached for performance. - * Changes to the underlying table structure are not reflected in later calls - * unless XSSFTable.updateHeaders() is called to reset the cache. - * @param columnHeader the column header name to get the table column index of - * @return column index corresponding to columnHeader - */ - int findColumnIndex(String columnHeader); - /** - * Returns the sheet name that the table belongs to. - */ - String getSheetName(); - /** - * Returns true iff the table has a 'Totals' row - */ - boolean isHasTotalsRow(); - - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Textbox.java b/trunk/src/java/org/apache/poi/ss/usermodel/Textbox.java deleted file mode 100644 index 21b7c7c5f..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Textbox.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -public interface Textbox { - - public final static short OBJECT_TYPE_TEXT = 6; - - /** - * @return the rich text string for this textbox. - */ - RichTextString getString(); - - /** - * @param string Sets the rich text string used by this object. - */ - void setString(RichTextString string); - - /** - * @return Returns the left margin within the textbox. - */ - int getMarginLeft(); - - /** - * Sets the left margin within the textbox. - */ - void setMarginLeft(int marginLeft); - - /** - * @return returns the right margin within the textbox. - */ - int getMarginRight(); - - /** - * Sets the right margin within the textbox. - */ - void setMarginRight(int marginRight); - - /** - * @return returns the top margin within the textbox. - */ - int getMarginTop(); - - /** - * Sets the top margin within the textbox. - */ - void setMarginTop(int marginTop); - - /** - * Gets the bottom margin within the textbox. - */ - int getMarginBottom(); - - /** - * Sets the bottom margin within the textbox. - */ - void setMarginBottom(int marginBottom); - -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java b/trunk/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java deleted file mode 100644 index f8976d130..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * This enumeration value indicates the type of vertical alignment for a cell, i.e., - * whether it is aligned top, bottom, vertically centered, justified or distributed. - * - * - */ -public enum VerticalAlignment { - /** - * The vertical alignment is aligned-to-top. - */ - TOP, - - /** - * The vertical alignment is centered across the height of the cell. - */ - CENTER, - - /** - * The vertical alignment is aligned-to-bottom. (typically the default value) - */ - BOTTOM, - - /** - *

        - * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, - * where each line of text inside the cell is evenly distributed across the height of the cell, - * with flush top and bottom margins. - *

        - *

        - * When text direction is vertical: similar behavior as horizontal justification. - * The alignment is justified (flush top and bottom in this case). For each line of text, each - * line of the wrapped text in a cell is aligned to the top and bottom (except the last line). - * If no single line of text wraps in the cell, then the text is not justified. - *

        - */ - JUSTIFY, - - /** - *

        - * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, - * where each line of text inside the cell is evenly distributed across the height of the cell, - * with flush top - *

        - *

        - * When text direction is vertical: behaves exactly as distributed horizontal alignment. - * The first words in a line of text (appearing at the top of the cell) are flush - * with the top edge of the cell, and the last words of a line of text are flush with the bottom edge of the cell, - * and the line of text is distributed evenly from top to bottom. - *

        - */ - DISTRIBUTED; - - public short getCode() { - return (short) ordinal(); - } - public static VerticalAlignment forInt(int code) { - if (code < 0 || code >= values().length) { - throw new IllegalArgumentException("Invalid VerticalAlignment code: " + code); - } - return values()[code]; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java b/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java deleted file mode 100644 index f5043b727..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java +++ /dev/null @@ -1,638 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.io.Closeable; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; - -/** - * High level representation of a Excel workbook. This is the first object most users - * will construct whether they are reading or writing a workbook. It is also the - * top level object for creating new sheets/etc. - */ -public interface Workbook extends Closeable, Iterable { - - /** Extended windows meta file */ - int PICTURE_TYPE_EMF = 2; - - /** Windows Meta File */ - int PICTURE_TYPE_WMF = 3; - - /** Mac PICT format */ - int PICTURE_TYPE_PICT = 4; - - /** JPEG format */ - int PICTURE_TYPE_JPEG = 5; - - /** PNG format */ - int PICTURE_TYPE_PNG = 6; - - /** Device independent bitmap */ - int PICTURE_TYPE_DIB = 7; - - - /** - * Indicates the sheet is visible. - * - * @see #setSheetHidden(int, int) - */ - int SHEET_STATE_VISIBLE = 0; - - /** - * Indicates the book window is hidden, but can be shown by the user via the user interface. - * - * @see #setSheetHidden(int, int) - */ - int SHEET_STATE_HIDDEN = 1; - - /** - * Indicates the sheet is hidden and cannot be shown in the user interface (UI). - * - *

        - * In Excel this state is only available programmatically in VBA: - * ThisWorkbook.Sheets("MySheetName").Visible = xlSheetVeryHidden - *

        - * - * @see #setSheetHidden(int, int) - */ - int SHEET_STATE_VERY_HIDDEN = 2; - - /** - * Convenience method to get the active sheet. The active sheet is is the sheet - * which is currently displayed when the workbook is viewed in Excel. - * 'Selected' sheet(s) is a distinct concept. - * - * @return the index of the active sheet (0-based) - */ - int getActiveSheetIndex(); - - /** - * Convenience method to set the active sheet. The active sheet is is the sheet - * which is currently displayed when the workbook is viewed in Excel. - * 'Selected' sheet(s) is a distinct concept. - * - * @param sheetIndex index of the active sheet (0-based) - */ - void setActiveSheet(int sheetIndex); - - /** - * Gets the first tab that is displayed in the list of tabs in excel. - * - * @return the first tab that to display in the list of tabs (0-based). - */ - int getFirstVisibleTab(); - - /** - * Sets the first tab that is displayed in the list of tabs in excel. - * - * @param sheetIndex the first tab that to display in the list of tabs (0-based) - */ - void setFirstVisibleTab(int sheetIndex); - - /** - * Sets the order of appearance for a given sheet. - * - * @param sheetname the name of the sheet to reorder - * @param pos the position that we want to insert the sheet into (0 based) - */ - void setSheetOrder(String sheetname, int pos); - - /** - * Sets the tab whose data is actually seen when the sheet is opened. - * This may be different from the "selected sheet" since excel seems to - * allow you to show the data of one sheet when another is seen "selected" - * in the tabs (at the bottom). - * - * @see Sheet#setSelected(boolean) - * @param index the index of the sheet to select (0 based) - */ - void setSelectedTab(int index); - - /** - * Set the sheet name. - *

        - * See {@link org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)} - * for a safe way to create valid names - *

        - * @param sheet number (0 based) - * @throws IllegalArgumentException if the name is null or invalid - * or workbook already contains a sheet with this name - * @see #createSheet(String) - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - */ - void setSheetName(int sheet, String name); - - /** - * Get the sheet name - * - * @param sheet sheet number (0 based) - * @return Sheet name - */ - String getSheetName(int sheet); - - /** - * Returns the index of the sheet by his name - * - * @param name the sheet name - * @return index of the sheet (0 based) - */ - int getSheetIndex(String name); - - /** - * Returns the index of the given sheet - * - * @param sheet the sheet to look up - * @return index of the sheet (0 based) - */ - int getSheetIndex(Sheet sheet); - - /** - * Create a Sheet for this Workbook, adds it to the sheets and returns - * the high level representation. Use this to create new sheets. - * - * @return Sheet representing the new sheet. - */ - Sheet createSheet(); - - /** - * Create a new sheet for this Workbook and return the high level representation. - * Use this to create new sheets. - * - *

        - * Note that Excel allows sheet names up to 31 chars in length but other applications - * (such as OpenOffice) allow more. Some versions of Excel crash with names longer than 31 chars, - * others - truncate such names to 31 character. - *

        - *

        - * POI's SpreadsheetAPI silently truncates the input argument to 31 characters. - * Example: - * - *

        
        -     *     Sheet sheet = workbook.createSheet("My very long sheet name which is longer than 31 chars"); // will be truncated
        -     *     assert 31 == sheet.getSheetName().length();
        -     *     assert "My very long sheet name which i" == sheet.getSheetName();
        -     *     
        - *

        - * - * Except the 31-character constraint, Excel applies some other rules: - *

        - * Sheet name MUST be unique in the workbook and MUST NOT contain the any of the following characters: - *

          - *
        • 0x0000
        • - *
        • 0x0003
        • - *
        • colon (:)
        • - *
        • backslash (\)
        • - *
        • asterisk (*)
        • - *
        • question mark (?)
        • - *
        • forward slash (/)
        • - *
        • opening square bracket ([)
        • - *
        • closing square bracket (])
        • - *
        - * The string MUST NOT begin or end with the single quote (') character. - *

        - * - *

        - * See {@link org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)} - * for a safe way to create valid names - *

        - * @param sheetname The name to set for the sheet. - * @return Sheet representing the new sheet. - * @throws IllegalArgumentException if the name is null or invalid - * or workbook already contains a sheet with this name - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - */ - Sheet createSheet(String sheetname); - - /** - * Create an Sheet from an existing sheet in the Workbook. - * - * @return Sheet representing the cloned sheet. - */ - Sheet cloneSheet(int sheetNum); - - - /** - * Returns an iterator of the sheets in the workbook - * in sheet order. Includes hidden and very hidden sheets. - * - * @return an iterator of the sheets. - */ - Iterator sheetIterator(); - - /** - * Get the number of spreadsheets in the workbook - * - * @return the number of sheets - */ - int getNumberOfSheets(); - - /** - * Get the Sheet object at the given index. - * - * @param index of the sheet number (0-based physical & logical) - * @return Sheet at the provided index - * @throws IllegalArgumentException if the index is out of range (index - * < 0 || index >= getNumberOfSheets()). - */ - Sheet getSheetAt(int index); - - /** - * Get sheet with the given name - * - * @param name of the sheet - * @return Sheet with the name provided or null if it does not exist - */ - Sheet getSheet(String name); - - /** - * Removes sheet at the given index - * - * @param index of the sheet to remove (0-based) - */ - void removeSheetAt(int index); - - /** - * Create a new Font and add it to the workbook's font table - * - * @return new font object - */ - Font createFont(); - - /** - * Finds a font that matches the one with the supplied attributes - * - * @return the font with the matched attributes or null - * @deprecated POI 3.15 beta 2. Use {@link #findFont(boolean, short, short, String, boolean, boolean, short, byte)} instead. - */ - Font findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline); - - /** - * Finds a font that matches the one with the supplied attributes - * - * @return the font with the matched attributes or null - */ - Font findFont(boolean bold, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline); - - /** - * Get the number of fonts in the font table - * - * @return number of fonts - */ - short getNumberOfFonts(); - - /** - * Get the font at the given index number - * - * @param idx index number (0-based) - * @return font at the index - */ - Font getFontAt(short idx); - - /** - * Create a new Cell style and add it to the workbook's style table - * - * @return the new Cell Style object - * @throws IllegalStateException if the number of cell styles exceeded the limit for this type of Workbook. - */ - CellStyle createCellStyle(); - - /** - * Get the number of styles the workbook contains - * - * @return count of cell styles - */ - int getNumCellStyles(); - - /** - * Get the cell style object at the given index - * - * @param idx index within the set of styles (0-based) - * @return CellStyle object at the index - */ - CellStyle getCellStyleAt(int idx); - - /** - * Write out this workbook to an Outputstream. - * - * @param stream - the java OutputStream you wish to write to - * @exception IOException if anything can't be written. - */ - void write(OutputStream stream) throws IOException; - - /** - * Close the underlying input resource (File or Stream), - * from which the Workbook was read. - * - *

        Once this has been called, no further - * operations, updates or reads should be performed on the - * Workbook. - */ - @Override - void close() throws IOException; - - /** - * @return the total number of defined names in this workbook - */ - int getNumberOfNames(); - - /** - * @param name the name of the defined name - * @return the defined name with the specified name. null if not found. - */ - Name getName(String name); - - /** - * Returns all defined names with the given name. - * - * @param name the name of the defined name - * @return a list of the defined names with the specified name. An empty list is returned if none is found. - */ - List getNames(String name); - - /** - * Returns all defined names. - * - * @return a list of the defined names. An empty list is returned if none is found. - */ - List getAllNames(); - - /** - * @param nameIndex position of the named range (0-based) - * @return the defined name at the specified index - * @throws IllegalArgumentException if the supplied index is invalid - */ - Name getNameAt(int nameIndex); - - /** - * Creates a new (uninitialised) defined name in this workbook - * - * @return new defined name object - */ - Name createName(); - - /** - * Gets the defined name index by name
        - * Note: Excel defined names are case-insensitive and - * this method performs a case-insensitive search. - * - * @param name the name of the defined name - * @return zero based index of the defined name. -1 if not found. - */ - int getNameIndex(String name); - - /** - * Remove the defined name at the specified index - * - * @param index named range index (0 based) - */ - void removeName(int index); - - /** - * Remove a defined name by name - * - * @param name the name of the defined name - */ - void removeName(String name); - - /** - * Remove a defined name - * - * @param name the name of the defined name - */ - void removeName(Name name); - - /** - * Adds the linking required to allow formulas referencing - * the specified external workbook to be added to this one. - *

        In order for formulas such as "[MyOtherWorkbook]Sheet3!$A$5" - * to be added to the file, some linking information must first - * be recorded. Once a given external workbook has been linked, - * then formulas using it can added. Each workbook needs linking - * only once. - *

        This linking only applies for writing formulas. To link things - * for evaluation, see {@link FormulaEvaluator#setupReferencedWorkbooks(java.util.Map)} - * - * @param name The name the workbook will be referenced as in formulas - * @param workbook The open workbook to fetch the link required information from - */ - int linkExternalWorkbook(String name, Workbook workbook); - - /** - * Sets the printarea for the sheet provided - *

        - * i.e. Reference = $A$1:$B$2 - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @param reference Valid name Reference for the Print Area - */ - void setPrintArea(int sheetIndex, String reference); - - /** - * For the Convenience of Java Programmers maintaining pointers. - * @see #setPrintArea(int, String) - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - * @param startColumn Column to begin printarea - * @param endColumn Column to end the printarea - * @param startRow Row to begin the printarea - * @param endRow Row to end the printarea - */ - void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow); - - /** - * Retrieves the reference for the printarea of the specified sheet, - * the sheet name is appended to the reference even if it was not specified. - * - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @return String Null if no print area has been defined - */ - String getPrintArea(int sheetIndex); - - /** - * Delete the printarea for the sheet specified - * - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - */ - void removePrintArea(int sheetIndex); - - /** - * Retrieves the current policy on what to do when - * getting missing or blank cells from a row. - *

        - * The default is to return blank and null cells. - * {@link MissingCellPolicy} - *

        - */ - MissingCellPolicy getMissingCellPolicy(); - - /** - * Sets the policy on what to do when - * getting missing or blank cells from a row. - * - * This will then apply to all calls to - * {@link Row#getCell(int)} }. See - * {@link MissingCellPolicy} - */ - void setMissingCellPolicy(MissingCellPolicy missingCellPolicy); - - /** - * Returns the instance of DataFormat for this workbook. - * - * @return the DataFormat object - */ - DataFormat createDataFormat(); - - /** - * Adds a picture to the workbook. - * - * @param pictureData The bytes of the picture - * @param format The format of the picture. - * - * @return the index to this picture (1 based). - * @see #PICTURE_TYPE_EMF - * @see #PICTURE_TYPE_WMF - * @see #PICTURE_TYPE_PICT - * @see #PICTURE_TYPE_JPEG - * @see #PICTURE_TYPE_PNG - * @see #PICTURE_TYPE_DIB - */ - int addPicture(byte[] pictureData, int format); - - /** - * Gets all pictures from the Workbook. - * - * @return the list of pictures (a list of {@link PictureData} objects.) - */ - List getAllPictures(); - - /** - * Returns an object that handles instantiating concrete - * classes of the various instances one needs for HSSF and XSSF. - */ - CreationHelper getCreationHelper(); - - /** - * @return false if this workbook is not visible in the GUI - */ - boolean isHidden(); - - /** - * @param hiddenFlag pass false to make the workbook visible in the GUI - */ - void setHidden(boolean hiddenFlag); - - /** - * Check whether a sheet is hidden. - *

        - * Note that a sheet could instead be set to be very hidden, which is different - * ({@link #isSheetVeryHidden(int)}) - *

        - * @param sheetIx Number - * @return true if sheet is hidden - */ - boolean isSheetHidden(int sheetIx); - - /** - * Check whether a sheet is very hidden. - *

        - * This is different from the normal hidden status - * ({@link #isSheetHidden(int)}) - *

        - * @param sheetIx sheet index to check - * @return true if sheet is very hidden - */ - boolean isSheetVeryHidden(int sheetIx); - - /** - * Hide or unhide a sheet. - * - * Please note that the sheet currently set as active sheet (sheet 0 in a newly - * created workbook or the one set via setActiveSheet()) cannot be hidden. - * - * @param sheetIx the sheet index (0-based) - * @param hidden True to mark the sheet as hidden, false otherwise - */ - void setSheetHidden(int sheetIx, boolean hidden); - - /** - * Hide or unhide a sheet. - * - *
          - *
        • 0 - visible.
        • - *
        • 1 - hidden.
        • - *
        • 2 - very hidden.
        • - *
        - * - * Please note that the sheet currently set as active sheet (sheet 0 in a newly - * created workbook or the one set via setActiveSheet()) cannot be hidden. - * - * @param sheetIx the sheet index (0-based) - * @param hidden one of the following Workbook constants: - * Workbook.SHEET_STATE_VISIBLE, - * Workbook.SHEET_STATE_HIDDEN, or - * Workbook.SHEET_STATE_VERY_HIDDEN. - * @throws IllegalArgumentException if the supplied sheet index or state is invalid - */ - void setSheetHidden(int sheetIx, int hidden); - - /** - * Register a new toolpack in this workbook. - * - * @param toopack the toolpack to register - */ - void addToolPack(UDFFinder toopack); - - /** - * Whether the application shall perform a full recalculation when the workbook is opened. - *

        - * Typically you want to force formula recalculation when you modify cell formulas or values - * of a workbook previously created by Excel. When set to true, this flag will tell Excel - * that it needs to recalculate all formulas in the workbook the next time the file is opened. - *

        - *

        - * Note, that recalculation updates cached formula results and, thus, modifies the workbook. - * Depending on the version, Excel may prompt you with "Do you want to save the changes in filename?" - * on close. - *

        - * - * @param value true if the application will perform a full recalculation of - * workbook values when the workbook is opened - * @since 3.8 - */ - void setForceFormulaRecalculation(boolean value); - - /** - * Whether Excel will be asked to recalculate all formulas when the workbook is opened. - * - * @since 3.8 - */ - boolean getForceFormulaRecalculation(); - - /** - * Returns the spreadsheet version of this workbook - * - * @return SpreadsheetVersion enum - * @since 3.14 beta 2 - */ - SpreadsheetVersion getSpreadsheetVersion(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java deleted file mode 100644 index d470cf61f..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Specifies the possible crossing states of an axis. - * - * @author Roman Kashitsyn - */ -public enum AxisCrossBetween { - /** - * Specifies the value axis shall cross the category axis - * between data markers. - */ - BETWEEN, - /** - * Specifies the value axis shall cross the category axis at - * the midpoint of a category. - */ - MIDPOINT_CATEGORY -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java deleted file mode 100644 index 906198bb4..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Specifies the possible crossing points for an axis. - * - * @author Roman Kashitsyn - */ -public enum AxisCrosses { - /** - * The category axis crosses at the zero point of the value axis (if - * possible), or the minimum value (if the minimum is greater than zero) or - * the maximum (if the maximum is less than zero). - */ - AUTO_ZERO, - /** - * The axis crosses at the maximum value. - */ - MIN, - /** - * Axis crosses at the minimum value of the chart. - */ - MAX -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java deleted file mode 100644 index e8c219b43..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Specifies the possible ways to place a picture on a data point, series, wall, or floor. - * - * @author Roman Kashitsyn - */ -public enum AxisOrientation { - /** - * Specifies that the values on the axis shall be reversed - * so they go from maximum to minimum. - */ - MAX_MIN, - /** - * Specifies that the axis values shall be in the usual - * order, minimum to maximum. - */ - MIN_MAX -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java deleted file mode 100644 index db189f998..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Enumeration of all possible axis positions. - * - * @author Roman Kashitsyn - */ -public enum AxisPosition { - BOTTOM, - LEFT, - RIGHT, - TOP -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java deleted file mode 100644 index 5c7d16a4e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Enumeration of possible axis tick marks. - * - * @author Martin Andersson - */ -public enum AxisTickMark { - NONE, - CROSS, - IN, - OUT -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java deleted file mode 100644 index f3d936589..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * High level representation of chart axis. - * - * @author Roman Kashitsyn - */ -@Beta -public interface ChartAxis { - - /** - * @return axis id - */ - long getId(); - - /** - * @return axis position - */ - AxisPosition getPosition(); - - /** - * @param position new axis position - */ - void setPosition(AxisPosition position); - - /** - * @return axis number format - */ - String getNumberFormat(); - - /** - * @param format axis number format - */ - void setNumberFormat(String format); - - /** - * @return true if log base is defined, false otherwise - */ - boolean isSetLogBase(); - - /** - * @param logBase a number between 2 and 1000 (inclusive) - * @throws IllegalArgumentException if log base not within allowed range - */ - void setLogBase(double logBase); - - /** - * @return axis log base or 0.0 if not set - */ - double getLogBase(); - - /** - * @return true if minimum value is defined, false otherwise - */ - boolean isSetMinimum(); - - /** - * @return axis minimum or 0.0 if not set - */ - double getMinimum(); - - /** - * @param min axis minimum - */ - void setMinimum(double min); - - /** - * @return true if maximum value is defined, false otherwise - */ - boolean isSetMaximum(); - - /** - * @return axis maximum or 0.0 if not set - */ - double getMaximum(); - - /** - * @param max axis maximum - */ - void setMaximum(double max); - - /** - * @return axis orientation - */ - AxisOrientation getOrientation(); - - /** - * @param orientation axis orientation - */ - void setOrientation(AxisOrientation orientation); - - /** - * @param crosses axis cross type - */ - void setCrosses(AxisCrosses crosses); - - /** - * @return axis cross type - */ - AxisCrosses getCrosses(); - - /** - * Declare this axis cross another axis. - * @param axis that this axis should cross - */ - void crossAxis(ChartAxis axis); - - /** - * @return visibility of the axis. - */ - boolean isVisible(); - - /** - * @param value visibility of the axis. - */ - void setVisible(boolean value); - - /** - * @return major tick mark. - */ - AxisTickMark getMajorTickMark(); - - /** - * @param tickMark major tick mark type. - */ - void setMajorTickMark(AxisTickMark tickMark); - - /** - * @return minor tick mark. - */ - AxisTickMark getMinorTickMark(); - - /** - * @param tickMark minor tick mark type. - */ - void setMinorTickMark(AxisTickMark tickMark); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java deleted file mode 100644 index 87eff04cf..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * A factory for different chart axis. - * - * @author Roman Kashitsyn - * @author Martin Andersson - */ -@Beta -public interface ChartAxisFactory { - - /** - * @return new value axis - */ - ValueAxis createValueAxis(AxisPosition pos); - - /** - * @return new category axis. - */ - ChartAxis createCategoryAxis(AxisPosition pos); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java deleted file mode 100644 index 7a4aec5f0..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.util.Beta; - -/** - * A base for all charts data types. - * - * @author Roman Kashitsyn - */ -@Beta -public interface ChartData { - - /** - * Fills a charts with data specified by implementation. - * - * @param chart a charts to fill in - * @param axis charts axis to use - */ - void fillChart(Chart chart, ChartAxis... axis); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java deleted file mode 100644 index 675322da7..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * A factory for different charts data types. - * - * @author Roman Kashitsyn, Martin Andersson - */ -@Beta -public interface ChartDataFactory { - - /** - * @return an appropriate ScatterChartData instance - */ - ScatterChartData createScatterChartData(); - - /** - * @return a LineChartData instance - */ - LineChartData createLineChartData(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java deleted file mode 100644 index d843cac9b..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * Represents data model of the charts. - * - * @param type of points the data source contents - * @author Roman Kashitsyn - */ -@Beta -public interface ChartDataSource { - - /** - * Return number of points contained by data source. - * - * @return number of points contained by data source - */ - int getPointCount(); - - /** - * Returns point value at specified index. - * - * @param index index to value from - * @return point value at specified index. - * @throws {@code IndexOutOfBoundsException} if index - * parameter not in range {@code 0 <= index <= pointCount} - */ - T getPointAt(int index); - - /** - * Returns {@code true} if charts data source is valid cell range. - * - * @return {@code true} if charts data source is valid cell range - */ - boolean isReference(); - - /** - * Returns {@code true} if data source points should be treated as numbers. - * - * @return {@code true} if data source points should be treated as numbers - */ - boolean isNumeric(); - - /** - * Returns formula representation of the data source. It is only applicable - * for data source that is valid cell range. - * - * @return formula representation of the data source - * @throws {@code UnsupportedOperationException} if the data source is not a - * reference. - */ - String getFormulaString(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java deleted file mode 100644 index f8ab5c969..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * High level representation of chart legend. - * - * @author Roman Kashitsyn - * @author Martin Andersson - */ -@Beta -public interface ChartLegend extends ManuallyPositionable { - - /** - * @return legend position - */ - LegendPosition getPosition(); - - /** - * @param position new legend position - */ - void setPosition(LegendPosition position); - - /** - * @return overlay value. - */ - boolean isOverlay(); - - /** - * If true the legend is positioned over the chart area otherwise - * the legend is displayed next to it. - * - * Default is no overlay. - * - * @param value - */ - void setOverlay(boolean value); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java deleted file mode 100644 index 05a39d45e..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.ss.util.CellReference; - -/** - * Basic settings for all chart series. - */ -public interface ChartSeries { - - /** - * Sets the title of the series as a string literal. - * - * @param title - */ - void setTitle(String title); - - /** - * Sets the title of the series as a cell reference. - * - * @param titleReference - */ - void setTitle(CellReference titleReference); - - /** - * @return title as string literal. - */ - String getTitleString(); - - /** - * @return title as cell reference. - */ - CellReference getTitleCellReference(); - - /** - * @return title type. - */ - TitleType getTitleType(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java deleted file mode 100644 index 75e7fd9a8..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.Beta; - -/** - * Class {@code DataSources} is a factory for {@link ChartDataSource} instances. - * - * @author Roman Kashitsyn - */ -@Beta -public class DataSources { - - private DataSources() { - } - - public static ChartDataSource fromArray(T[] elements) { - return new ArrayDataSource(elements); - } - - public static ChartDataSource fromNumericCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) { - return new AbstractCellRangeDataSource(sheet, cellRangeAddress) { - public Number getPointAt(int index) { - CellValue cellValue = getCellValueAt(index); - if (cellValue != null && cellValue.getCellTypeEnum() == CellType.NUMERIC) { - return Double.valueOf(cellValue.getNumberValue()); - } else { - return null; - } - } - - public boolean isNumeric() { - return true; - } - }; - } - - public static ChartDataSource fromStringCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) { - return new AbstractCellRangeDataSource(sheet, cellRangeAddress) { - public String getPointAt(int index) { - CellValue cellValue = getCellValueAt(index); - if (cellValue != null && cellValue.getCellTypeEnum() == CellType.STRING) { - return cellValue.getStringValue(); - } else { - return null; - } - } - - public boolean isNumeric() { - return false; - } - }; - } - - private static class ArrayDataSource implements ChartDataSource { - - private final T[] elements; - - public ArrayDataSource(T[] elements) { - this.elements = elements.clone(); - } - - public int getPointCount() { - return elements.length; - } - - public T getPointAt(int index) { - return elements[index]; - } - - public boolean isReference() { - return false; - } - - public boolean isNumeric() { - Class arrayComponentType = elements.getClass().getComponentType(); - return (Number.class.isAssignableFrom(arrayComponentType)); - } - - public String getFormulaString() { - throw new UnsupportedOperationException("Literal data source can not be expressed by reference."); - } - } - - private abstract static class AbstractCellRangeDataSource implements ChartDataSource { - private final Sheet sheet; - private final CellRangeAddress cellRangeAddress; - private final int numOfCells; - private FormulaEvaluator evaluator; - - protected AbstractCellRangeDataSource(Sheet sheet, CellRangeAddress cellRangeAddress) { - this.sheet = sheet; - // Make copy since CellRangeAddress is mutable. - this.cellRangeAddress = cellRangeAddress.copy(); - this.numOfCells = this.cellRangeAddress.getNumberOfCells(); - this.evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator(); - } - - public int getPointCount() { - return numOfCells; - } - - public boolean isReference() { - return true; - } - - public String getFormulaString() { - return cellRangeAddress.formatAsString(sheet.getSheetName(), true); - } - - protected CellValue getCellValueAt(int index) { - if (index < 0 || index >= numOfCells) { - throw new IndexOutOfBoundsException("Index must be between 0 and " + - (numOfCells - 1) + " (inclusive), given: " + index); - } - int firstRow = cellRangeAddress.getFirstRow(); - int firstCol = cellRangeAddress.getFirstColumn(); - int lastCol = cellRangeAddress.getLastColumn(); - int width = lastCol - firstCol + 1; - int rowIndex = firstRow + index / width; - int cellIndex = firstCol + index % width; - Row row = sheet.getRow(rowIndex); - return (row == null) ? null : evaluator.evaluate(row.getCell(cellIndex)); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java deleted file mode 100644 index 87769701b..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Specifies the possible ways to store a chart element's position. - * @author Roman Kashitsyn - */ -public enum LayoutMode { - /** - * Specifies that the Width or Height shall be interpreted as the - * Right or Bottom of the chart element. - */ - EDGE, - /** - * Specifies that the Width or Height shall be interpreted as the - * Width or Height of the chart element. - */ - FACTOR -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java deleted file mode 100644 index f95c5370f..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Specifies whether to layout the plot area by its inside (not including axis - * and axis labels) or outside (including axis and axis labels). - * - * @author Roman Kashitsyn - */ -public enum LayoutTarget { - /** - * Specifies that the plot area size shall determine the - * size of the plot area, not including the tick marks and - * axis labels. - */ - INNER, - /** - * Specifies that the plot area size shall determine the - * size of the plot area, the tick marks, and the axis - * labels. - */ - OUTER -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java deleted file mode 100644 index 7536168a6..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Enumeration of all possible chart legend positions. - * - * @author Roman Kashitsyn - */ -public enum LegendPosition { - BOTTOM, - LEFT, - RIGHT, - TOP, - TOP_RIGHT -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java deleted file mode 100644 index f3bf10f56..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import java.util.List; - -import org.apache.poi.util.Beta; - -/** - * Data for a Line Chart - */ -@Beta -public interface LineChartData extends ChartData { - - /** - * @param categories data source for categories. - * @param values data source for values. - * @return a new line chart serie. - */ - LineChartSeries addSeries(ChartDataSource categories, ChartDataSource values); - - /** - * @return list of all series. - */ - List getSeries(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java deleted file mode 100644 index d1c03a951..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * Represents a line chart series. - */ -@Beta -public interface LineChartSeries extends ChartSeries { - - /** - * @return data source used for category axis data. - */ - ChartDataSource getCategoryAxisData(); - - /** - * @return data source used for value axis. - */ - ChartDataSource getValues(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java deleted file mode 100644 index 2d8bfbd96..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java +++ /dev/null @@ -1,153 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * High level representation of chart element manual layout. - * - * @author Roman Kashitsyn - */ -@Beta -public interface ManualLayout { - - /** - * Sets the layout target. - * @param target new layout target. - */ - public void setTarget(LayoutTarget target); - - /** - * Returns current layout target. - * @return current layout target - */ - public LayoutTarget getTarget(); - - /** - * Sets the x-coordinate layout mode. - * @param mode new x-coordinate layout mode. - */ - public void setXMode(LayoutMode mode); - - /** - * Returns current x-coordinnate layout mode. - * @return current x-coordinate layout mode. - */ - public LayoutMode getXMode(); - - /** - * Sets the y-coordinate layout mode. - * @param mode new y-coordinate layout mode. - */ - public void setYMode(LayoutMode mode); - - /** - * Returns current y-coordinate layout mode. - * @return current y-coordinate layout mode. - */ - public LayoutMode getYMode(); - - /** - * Returns the x location of the chart element. - * @return the x location (left) of the chart element or 0.0 if - * not set. - */ - public double getX(); - - /** - * Specifies the x location (left) of the chart element as a - * fraction of the width of the chart. If Left Mode is Factor, - * then the position is relative to the default position for the - * chart element. - */ - public void setX(double x); - - - /** - * Returns current y location of the chart element. - * @return the y location (top) of the chart element or 0.0 if not - * set. - */ - public double getY(); - - /** - * Specifies the y location (top) of the chart element as a - * fraction of the height of the chart. If Top Mode is Factor, - * then the position is relative to the default position for the - * chart element. - */ - public void setY(double y); - - - /** - * Specifies how to interpret the Width element for this manual - * layout. - * @param mode new width layout mode of this manual layout. - */ - public void setWidthMode(LayoutMode mode); - - - /** - * Returns current width mode of this manual layout. - * @return width mode of this manual layout. - */ - public LayoutMode getWidthMode(); - - /** - * Specifies how to interpret the Height element for this manual - * layout. - * @param mode new height mode of this manual layout. - */ - public void setHeightMode(LayoutMode mode); - - /** - * Returns current height mode of this - * @return height mode of this manual layout. - */ - public LayoutMode getHeightMode(); - - /** - * Specifies the width (if Width Mode is Factor) or right (if - * Width Mode is Edge) of the chart element as a fraction of the - * width of the chart. - * @param ratio a fraction of the width of the chart. - */ - public void setWidthRatio(double ratio); - - /** - * Returns current fraction of the width of the chart. - * @return fraction of the width of the chart or 0.0 if not set. - */ - public double getWidthRatio(); - - /** - * Specifies the height (if Height Mode is Factor) or bottom (if - * Height Mode is edge) of the chart element as a fraction of the - * height of the chart. - * @param ratio a fraction of the height of the chart. - */ - public void setHeightRatio(double ratio); - - /** - * Returns current fraction of the height of the chart. - * @return fraction of the height of the chart or 0.0 if not set. - */ - public double getHeightRatio(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java deleted file mode 100644 index 0d749fb4b..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * Abstraction of chart element that can be positioned with manual - * layout. - * - * @author Roman Kashitsyn - */ -@Beta -public interface ManuallyPositionable { - - /** - * Returns manual layout for the chart element. - * @return manual layout for the chart element. - */ - public ManualLayout getManualLayout(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java deleted file mode 100644 index 594b5bdfe..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import java.util.List; - -/** - * Data for a Scatter Chart - */ -public interface ScatterChartData extends ChartData { - /** - * @param xs data source to be used for X axis values - * @param ys data source to be used for Y axis values - * @return a new scatter charts series - */ - ScatterChartSeries addSerie(ChartDataSource xs, ChartDataSource ys); - - /** - * @return list of all series - */ - List getSeries(); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java deleted file mode 100644 index f200cb6ba..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * Represents scatter charts series. - */ -@Beta -public interface ScatterChartSeries extends ChartSeries { - - /** - * @return data source used for X axis values - */ - ChartDataSource getXValues(); - - /** - * @return data source used for Y axis values - */ - ChartDataSource getYValues(); - -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java deleted file mode 100644 index 6d93d61d3..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -/** - * Title types for charts. - * - * @author Martin Andersson - */ -public enum TitleType { - STRING, - CELL_REFERENCE -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java b/trunk/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java deleted file mode 100644 index f6673dae4..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.charts; - -import org.apache.poi.util.Beta; - -/** - * @author Roman Kashitsyn - */ -@Beta -public interface ValueAxis extends ChartAxis { - - /** - * @return cross between type - */ - AxisCrossBetween getCrossBetween(); - - /** - * @param crossBetween cross between type - */ - void setCrossBetween(AxisCrossBetween crossBetween); -} diff --git a/trunk/src/java/org/apache/poi/ss/usermodel/helpers/RowShifter.java b/trunk/src/java/org/apache/poi/ss/usermodel/helpers/RowShifter.java deleted file mode 100644 index 680abff62..000000000 --- a/trunk/src/java/org/apache/poi/ss/usermodel/helpers/RowShifter.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel.helpers; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Helper for shifting rows up or down - * - * This abstract class exists to consolidate duplicated code between XSSFRowShifter and HSSFRowShifter (currently methods sprinkled throughout HSSFSheet) - */ -public abstract class RowShifter { - protected final Sheet sheet; - - public RowShifter(Sheet sh) { - sheet = sh; - } - - /** - * Shifts, grows, or shrinks the merged regions due to a row shift. - * Merged regions that are completely overlaid by shifting will be deleted. - * - * @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 merged regions, doesn't contain deleted ones - */ - public List shiftMergedRegions(int startRow, int endRow, int n) { - List shiftedRegions = new ArrayList(); - Set removedIndices = new HashSet(); - //move merged regions completely if they fall within the new region boundaries when they are shifted - int size = sheet.getNumMergedRegions(); - for (int i = 0; i < size; i++) { - CellRangeAddress merged = sheet.getMergedRegion(i); - - // remove merged region that overlaps shifting - if (startRow + n <= merged.getFirstRow() && endRow + n >= merged.getLastRow()) { - removedIndices.add(i); - continue; - } - - 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 (!merged.containsRow(startRow - 1) && !merged.containsRow(endRow + 1)) { - merged.setFirstRow(merged.getFirstRow() + n); - merged.setLastRow(merged.getLastRow() + n); - //have to remove/add it back - shiftedRegions.add(merged); - removedIndices.add(i); - } - } - - if(!removedIndices.isEmpty()) { - sheet.removeMergedRegions(removedIndices); - } - - //read so it doesn't get shifted again - for (CellRangeAddress region : shiftedRegions) { - sheet.addMergedRegion(region); - } - return shiftedRegions; - } - - /** - * Updated named ranges - */ - public abstract void updateNamedRanges(FormulaShifter shifter); - - /** - * Update formulas. - */ - public abstract void updateFormulas(FormulaShifter shifter); - - /** - * Update the formulas in specified row using the formula shifting policy specified by shifter - * - * @param row the row to update the formulas on - * @param shifter the formula shifting policy - */ - @Internal - public abstract void updateRowFormulas(Row row, FormulaShifter shifter); - - public abstract void updateConditionalFormatting(FormulaShifter shifter); - - /** - * Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink - * is of type LINK_DOCUMENT and refers to a cell that was shifted). Hyperlinks - * do not track the content they point to. - * - * @param shifter the formula shifting policy - */ - public abstract void updateHyperlinks(FormulaShifter shifter); - -} diff --git a/trunk/src/java/org/apache/poi/ss/util/AreaReference.java b/trunk/src/java/org/apache/poi/ss/util/AreaReference.java deleted file mode 100644 index 8576511a2..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/AreaReference.java +++ /dev/null @@ -1,407 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -import org.apache.poi.ss.SpreadsheetVersion; - -public class AreaReference { - - /** The character (!) that separates sheet names from cell references */ - private static final char SHEET_NAME_DELIMITER = '!'; - /** The character (:) that separates the two cell references in a multi-cell area reference */ - private static final char CELL_DELIMITER = ':'; - /** The character (') used to quote sheet names when they contain special characters */ - private static final char SPECIAL_NAME_DELIMITER = '\''; - private static final SpreadsheetVersion DEFAULT_SPREADSHEET_VERSION = SpreadsheetVersion.EXCEL97; - - private final CellReference _firstCell; - private final CellReference _lastCell; - private final boolean _isSingleCell; - private final SpreadsheetVersion _version; // never null - - /** - * @deprecated POI 3.13 beta 1. Prefer supplying a version. - */ - @Deprecated - public AreaReference(String reference) { - this(reference, DEFAULT_SPREADSHEET_VERSION); - // generateContiguous must be updated before this can be deleted. - } - - /** - * Create an area ref from a string representation. Sheet names containing special characters should be - * delimited and escaped as per normal syntax rules for formulas.
        - * The area reference must be contiguous (i.e. represent a single rectangle, not a union of rectangles) - */ - public AreaReference(String reference, SpreadsheetVersion version) { - _version = (null != version) ? version : DEFAULT_SPREADSHEET_VERSION; - if(! isContiguous(reference)) { - throw new IllegalArgumentException( - "References passed to the AreaReference must be contiguous, " + - "use generateContiguous(ref) if you have non-contiguous references"); - } - - String[] parts = separateAreaRefs(reference); - String part0 = parts[0]; - if (parts.length == 1) { - // TODO - probably shouldn't initialize area ref when text is really a cell ref - // Need to fix some named range stuff to get rid of this - _firstCell = new CellReference(part0); - - _lastCell = _firstCell; - _isSingleCell = true; - return; - } - if (parts.length != 2) { - throw new IllegalArgumentException("Bad area ref '" + reference + "'"); - } - - String part1 = parts[1]; - if (isPlainColumn(part0)) { - if (!isPlainColumn(part1)) { - throw new RuntimeException("Bad area ref '" + reference + "'"); - } - // Special handling for whole-column references - // Represented internally as x$1 to x$65536 - // which is the maximum range of rows - - boolean firstIsAbs = CellReference.isPartAbsolute(part0); - boolean lastIsAbs = CellReference.isPartAbsolute(part1); - - int col0 = CellReference.convertColStringToIndex(part0); - int col1 = CellReference.convertColStringToIndex(part1); - - _firstCell = new CellReference(0, col0, true, firstIsAbs); - _lastCell = new CellReference(0xFFFF, col1, true, lastIsAbs); - _isSingleCell = false; - // TODO - whole row refs - } else { - _firstCell = new CellReference(part0); - _lastCell = new CellReference(part1); - _isSingleCell = part0.equals(part1); - } - } - - private static boolean isPlainColumn(String refPart) { - for(int i=refPart.length()-1; i>=0; i--) { - int ch = refPart.charAt(i); - if (ch == '$' && i==0) { - continue; - } - if (ch < 'A' || ch > 'Z') { - return false; - } - } - return true; - } - - /** - * Creates an area ref from a pair of Cell References. - */ - public AreaReference(CellReference topLeft, CellReference botRight) { - _version = DEFAULT_SPREADSHEET_VERSION; - boolean swapRows = topLeft.getRow() > botRight.getRow(); - boolean swapCols = topLeft.getCol() > botRight.getCol(); - if (swapRows || swapCols) { - int firstRow; - int lastRow; - int firstColumn; - int lastColumn; - boolean firstRowAbs; - boolean lastRowAbs; - boolean firstColAbs; - boolean lastColAbs; - if (swapRows) { - firstRow = botRight.getRow(); - firstRowAbs = botRight.isRowAbsolute(); - lastRow = topLeft.getRow(); - lastRowAbs = topLeft.isRowAbsolute(); - } else { - firstRow = topLeft.getRow(); - firstRowAbs = topLeft.isRowAbsolute(); - lastRow = botRight.getRow(); - lastRowAbs = botRight.isRowAbsolute(); - } - if (swapCols) { - firstColumn = botRight.getCol(); - firstColAbs = botRight.isColAbsolute(); - lastColumn = topLeft.getCol(); - lastColAbs = topLeft.isColAbsolute(); - } else { - firstColumn = topLeft.getCol(); - firstColAbs = topLeft.isColAbsolute(); - lastColumn = botRight.getCol(); - lastColAbs = botRight.isColAbsolute(); - } - _firstCell = new CellReference(firstRow, firstColumn, firstRowAbs, firstColAbs); - _lastCell = new CellReference(lastRow, lastColumn, lastRowAbs, lastColAbs); - } else { - _firstCell = topLeft; - _lastCell = botRight; - } - _isSingleCell = false; - } - - /** - * Is the reference for a contiguous (i.e. - * unbroken) area, or is it made up of - * several different parts? - * (If it is, you will need to call - * {@link #generateContiguous(String)}) - */ - public static boolean isContiguous(String reference) { - // If there's a sheet name, strip it off - int sheetRefEnd = reference.indexOf('!'); - if(sheetRefEnd != -1) { - reference = reference.substring(sheetRefEnd); - } - - // Check for the , as a sign of non-coniguous - if(reference.indexOf(',') == -1) { - return true; - } - return false; - } - - public static AreaReference getWholeRow(SpreadsheetVersion version, String start, String end) { - if (null == version) { - version = DEFAULT_SPREADSHEET_VERSION; - } - return new AreaReference("$A" + start + ":$" + version.getLastColumnName() + end, version); - } - - public static AreaReference getWholeColumn(SpreadsheetVersion version, String start, String end) { - if (null == version) { - version = DEFAULT_SPREADSHEET_VERSION; - } - return new AreaReference(start + "$1:" + end + "$" + version.getMaxRows(), version); - } - - /** - * Is the reference for a whole-column reference, - * such as C:C or D:G ? - */ - public static boolean isWholeColumnReference(SpreadsheetVersion version, CellReference topLeft, CellReference botRight) { - if (null == version) { - version = DEFAULT_SPREADSHEET_VERSION; // how the code used to behave. - } - - // These are represented as something like - // C$1:C$65535 or D$1:F$0 - // i.e. absolute from 1st row to 0th one - if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() && - botRight.getRow() == version.getLastRowIndex() && botRight.isRowAbsolute()) { - return true; - } - return false; - } - public boolean isWholeColumnReference() { - return isWholeColumnReference(_version, _firstCell, _lastCell); - } - - /** - * Takes a non-contiguous area reference, and - * returns an array of contiguous area references. - */ - public static AreaReference[] generateContiguous(String reference) { - List refs = new ArrayList(); - StringTokenizer st = new StringTokenizer(reference, ","); - while(st.hasMoreTokens()) { - refs.add( - new AreaReference(st.nextToken()) - ); - } - return refs.toArray(new AreaReference[refs.size()]); - } - - /** - * @return false if this area reference involves more than one cell - */ - public boolean isSingleCell() { - return _isSingleCell; - } - - /** - * @return the first cell reference which defines this area. Usually this cell is in the upper - * left corner of the area (but this is not a requirement). - */ - public CellReference getFirstCell() { - return _firstCell; - } - - /** - * Note - if this area reference refers to a single cell, the return value of this method will - * be identical to that of getFirstCell() - * @return the second cell reference which defines this area. For multi-cell areas, this is - * cell diagonally opposite the 'first cell'. Usually this cell is in the lower right corner - * of the area (but this is not a requirement). - */ - public CellReference getLastCell() { - return _lastCell; - } - /** - * Returns a reference to every cell covered by this area - */ - public CellReference[] getAllReferencedCells() { - // Special case for single cell reference - if(_isSingleCell) { - return new CellReference[] { _firstCell, }; - } - - // Interpolate between the two - int minRow = Math.min(_firstCell.getRow(), _lastCell.getRow()); - int maxRow = Math.max(_firstCell.getRow(), _lastCell.getRow()); - int minCol = Math.min(_firstCell.getCol(), _lastCell.getCol()); - int maxCol = Math.max(_firstCell.getCol(), _lastCell.getCol()); - String sheetName = _firstCell.getSheetName(); - - List refs = new ArrayList(); - for(int row=minRow; row<=maxRow; row++) { - for(int col=minCol; col<=maxCol; col++) { - CellReference ref = new CellReference(sheetName, row, col, _firstCell.isRowAbsolute(), _firstCell.isColAbsolute()); - refs.add(ref); - } - } - return refs.toArray(new CellReference[refs.size()]); - } - - /** - * Returns a text representation of this area reference. - *

        - * Example return values: - * - * - * - * - * - * - *
        ResultComment
        A1:A1Single cell area reference without sheet
        A1:$C$1Multi-cell area reference without sheet
        Sheet1!A$1:B4Standard sheet name
        'O''Brien''s Sales'!B5:C6' Sheet name with special characters
        - * @return the text representation of this area reference as it would appear in a formula. - */ - public String formatAsString() { - // Special handling for whole-column references - if(isWholeColumnReference()) { - return - CellReference.convertNumToColString(_firstCell.getCol()) - + ":" + - CellReference.convertNumToColString(_lastCell.getCol()); - } - - StringBuffer sb = new StringBuffer(32); - sb.append(_firstCell.formatAsString()); - if(!_isSingleCell) { - sb.append(CELL_DELIMITER); - if(_lastCell.getSheetName() == null) { - sb.append(_lastCell.formatAsString()); - } else { - // don't want to include the sheet name twice - _lastCell.appendCellReference(sb); - } - } - return sb.toString(); - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - - /** - * Separates Area refs in two parts and returns them as separate elements in a String array, - * each qualified with the sheet name (if present) - * - * @return array with one or two elements. never null - */ - private static String[] separateAreaRefs(String reference) { - // TODO - refactor cell reference parsing logic to one place. - // Current known incarnations: - // FormulaParser.GetName() - // CellReference.separateRefParts() - // AreaReference.separateAreaRefs() (here) - // SheetNameFormatter.format() (inverse) - - - int len = reference.length(); - int delimiterPos = -1; - boolean insideDelimitedName = false; - for(int i=0; i=0) { - throw new IllegalArgumentException("More than one cell delimiter '" - + CELL_DELIMITER + "' appears in area reference '" + reference + "'"); - } - delimiterPos = i; - } - continue; //continue the for-loop - case SPECIAL_NAME_DELIMITER: - break; - default: - continue; //continue the for-loop - } - if(!insideDelimitedName) { - insideDelimitedName = true; - continue; - } - - if(i >= len-1) { - // reference ends with the delimited name. - // Assume names like: "Sheet1!'A1'" are never legal. - throw new IllegalArgumentException("Area reference '" + reference - + "' ends with special name delimiter '" + SPECIAL_NAME_DELIMITER + "'"); - } - if(reference.charAt(i+1) == SPECIAL_NAME_DELIMITER) { - // two consecutive quotes is the escape sequence for a single one - i++; // skip this and keep parsing the special name - } else { - // this is the end of the delimited name - insideDelimitedName = false; - } - } - if(delimiterPos < 0) { - return new String[] { reference, }; - } - - String partA = reference.substring(0, delimiterPos); - String partB = reference.substring(delimiterPos+1); - if(partB.indexOf(SHEET_NAME_DELIMITER) >=0) { - // TODO - are references like "Sheet1!A1:Sheet1:B2" ever valid? - // FormulaParser has code to handle that. - - throw new RuntimeException("Unexpected " + SHEET_NAME_DELIMITER - + " in second cell reference of '" + reference + "'"); - } - - int plingPos = partA.lastIndexOf(SHEET_NAME_DELIMITER); - if(plingPos < 0) { - return new String [] { partA, partB, }; - } - - String sheetName = partA.substring(0, plingPos + 1); // +1 to include delimiter - - return new String [] { partA, sheetName + partB, }; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellAddress.java b/trunk/src/java/org/apache/poi/ss/util/CellAddress.java deleted file mode 100644 index 32c2711e2..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellAddress.java +++ /dev/null @@ -1,179 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.Locale; - -import org.apache.poi.ss.usermodel.Cell; - -/** - *

        This class is a container for POI usermodel row=0 column=0 cell references. - * It is barely a container for these two coordinates. The implementation - * of the Comparable interface sorts by "natural" order top left to bottom right.

        - * - *

        Use CellAddress when you want to refer to the location of a cell in a sheet - * when the concept of relative/absolute does not apply (such as the anchor location - * of a cell comment). Use {@link CellReference} when the concept of - * relative/absolute does apply (such as a cell reference in a formula). - * CellAddresses do not have a concept of "sheet", while CellReferences do.

        - */ -public class CellAddress implements Comparable { - /** A constant for references to the first cell in a sheet. */ - public static final CellAddress A1 = new CellAddress(0, 0); - - private final int _row; - private final int _col; - - /** - * Create a new CellAddress object. - * - * @param row Row index (first row is 0) - * @param column Column index (first column is 0) - */ - public CellAddress(int row, int column) { - super(); - this._row = row; - this._col = column; - } - - /** - * Create a new CellAddress object. - * - * @param address a cell address in A1 format. Address may not contain sheet name or dollar signs. - * (that is, address is not a cell reference. Use {@link #CellAddress(CellReference)} instead if - * starting with a cell reference.) - */ - public CellAddress(String address) { - int length = address.length(); - - int loc = 0; - // step over column name chars until first digit for row number. - for (; loc < length; loc++) { - char ch = address.charAt(loc); - if (Character.isDigit(ch)) { - break; - } - } - - String sCol = address.substring(0,loc).toUpperCase(Locale.ROOT); - String sRow = address.substring(loc); - - // FIXME: breaks if address contains a sheet name or dollar signs from an absolute CellReference - this._row = Integer.parseInt(sRow)-1; - this._col = CellReference.convertColStringToIndex(sCol); - } - - /** - * Create a new CellAddress object. - * - * @param reference a reference to a cell - */ - public CellAddress(CellReference reference) { - this(reference.getRow(), reference.getCol()); - } - - /** - * Create a new CellAddress object - * - * @param address a CellAddress - */ - public CellAddress(CellAddress address) { - this(address.getRow(), address.getColumn()); - } - - /** - * Create a new CellAddress object. - * - * @param cell the Cell to get the location of - */ - public CellAddress(Cell cell) { - this(cell.getRowIndex(), cell.getColumnIndex()); - } - - /** - * Get the cell address row - * - * @return row - */ - public int getRow() { - return _row; - } - - /** - * Get the cell address column - * - * @return column - */ - public int getColumn() { - return _col; - } - - /** - * Compare this CellAddress using the "natural" row-major, column-minor ordering. - * That is, top-left to bottom-right ordering. - * - * @param other - * @return
          - *
        • -1 if this CellAddress is before (above/left) of other
        • - *
        • 0 if addresses are the same
        • - *
        • 1 if this CellAddress is after (below/right) of other
        • - *
        - */ - @Override - public int compareTo(CellAddress other) { - int r = this._row-other._row; - if (r!=0) return r; - - r = this._col-other._col; - if (r!=0) return r; - - return 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if(!(o instanceof CellAddress)) { - return false; - } - - CellAddress other = (CellAddress) o; - return _row == other._row && - _col == other._col; - } - - @Override - public int hashCode() { - return this._row + this._col<<16; - } - - @Override - public String toString() { - return formatAsString(); - } - - /** - * Same as {@link #toString()} - * @return A1-style cell address string representation - */ - public String formatAsString() { - return CellReference.convertNumToColString(this._col)+(this._row+1); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java b/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java deleted file mode 100644 index aee9f82b4..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.SelectionRecord; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.util.LittleEndianOutput; - -/** - * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

        - * - *

        In the Microsoft documentation, this is also known as a - * Ref8U - see page 831 of version 1.0 of the documentation. - * - * Note - {@link SelectionRecord} uses the BIFF5 version of this structure - * @author Dragos Buleandra (dragos.buleandra@trade2b.ro) - */ -public class CellRangeAddress extends CellRangeAddressBase { - /* - * TODO - replace org.apache.poi.hssf.util.Region - */ - public static final int ENCODED_SIZE = 8; - - /** - * Creates new cell range. Indexes are zero-based. - * - * @param firstRow Index of first row - * @param lastRow Index of last row (inclusive), must be equal to or larger than {@code firstRow} - * @param firstCol Index of first column - * @param lastCol Index of last column (inclusive), must be equal to or larger than {@code firstCol} - */ - public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) { - super(firstRow, lastRow, firstCol, lastCol); - - if (lastRow < firstRow || lastCol < firstCol) - throw new IllegalArgumentException("lastRow < firstRow || lastCol < firstCol"); - } - - public void serialize(LittleEndianOutput out) { - out.writeShort(getFirstRow()); - out.writeShort(getLastRow()); - out.writeShort(getFirstColumn()); - out.writeShort(getLastColumn()); - } - - public CellRangeAddress(RecordInputStream in) { - super(readUShortAndCheck(in), in.readUShort(), in.readUShort(), in.readUShort()); - } - - private static int readUShortAndCheck(RecordInputStream in) { - if (in.remaining() < ENCODED_SIZE) { - // Ran out of data - throw new RuntimeException("Ran out of data reading CellRangeAddress"); - } - return in.readUShort(); - } - - public CellRangeAddress copy() { - return new CellRangeAddress(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn()); - } - - public static int getEncodedSize(int numberOfItems) { - return numberOfItems * ENCODED_SIZE; - } - - /** - * @return the text format of this range. Single cell ranges are formatted - * like single cell references (e.g. 'A1' instead of 'A1:A1'). - */ - public String formatAsString() { - return formatAsString(null, false); - } - - /** - * @return the text format of this range using specified sheet name. - */ - public String formatAsString(String sheetName, boolean useAbsoluteAddress) { - StringBuffer sb = new StringBuffer(); - if (sheetName != null) { - sb.append(SheetNameFormatter.format(sheetName)); - sb.append("!"); - } - CellReference cellRefFrom = new CellReference(getFirstRow(), getFirstColumn(), - useAbsoluteAddress, useAbsoluteAddress); - CellReference cellRefTo = new CellReference(getLastRow(), getLastColumn(), - useAbsoluteAddress, useAbsoluteAddress); - sb.append(cellRefFrom.formatAsString()); - - //for a single-cell reference return A1 instead of A1:A1 - //for full-column ranges or full-row ranges return A:A instead of A, - //and 1:1 instead of 1 - if(!cellRefFrom.equals(cellRefTo) - || isFullColumnRange() || isFullRowRange()){ - sb.append(':'); - sb.append(cellRefTo.formatAsString()); - } - return sb.toString(); - } - - /** - * Creates a CellRangeAddress from a cell range reference string. - * - * @param ref usually a standard area ref (e.g. "B1:D8"). May be a single - * cell ref (e.g. "B5") in which case the result is a 1 x 1 cell - * range. May also be a whole row range (e.g. "3:5"), or a whole - * column range (e.g. "C:F") - */ - public static CellRangeAddress valueOf(String ref) { - int sep = ref.indexOf(":"); - CellReference a; - CellReference b; - if (sep == -1) { - a = new CellReference(ref); - b = a; - } else { - a = new CellReference(ref.substring(0, sep)); - b = new CellReference(ref.substring(sep + 1)); - } - return new CellRangeAddress(a.getRow(), b.getRow(), a.getCol(), b.getCol()); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java b/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java deleted file mode 100644 index f94444d9a..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java +++ /dev/null @@ -1,237 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import org.apache.poi.ss.SpreadsheetVersion; - - -/** - * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

        - * - * Common superclass of 8-bit and 16-bit versions - */ -public abstract class CellRangeAddressBase { - - private int _firstRow; - private int _firstCol; - private int _lastRow; - private int _lastCol; - - protected CellRangeAddressBase(int firstRow, int lastRow, int firstCol, int lastCol) { - _firstRow = firstRow; - _lastRow = lastRow; - _firstCol = firstCol; - _lastCol = lastCol; - } - - /** - * Validate the range limits against the supplied version of Excel - * - * @param ssVersion the version of Excel to validate against - * @throws IllegalArgumentException if the range limits are outside of the allowed range - */ - public void validate(SpreadsheetVersion ssVersion) { - validateRow(_firstRow, ssVersion); - validateRow(_lastRow, ssVersion); - validateColumn(_firstCol, ssVersion); - validateColumn(_lastCol, ssVersion); - } - /** - * Runs a bounds check for row numbers - * @param row - */ - private static void validateRow(int row, SpreadsheetVersion ssVersion) { - int maxrow = ssVersion.getLastRowIndex(); - if (row > maxrow) throw new IllegalArgumentException("Maximum row number is " + maxrow); - if (row < 0) throw new IllegalArgumentException("Minumum row number is 0"); - } - - /** - * Runs a bounds check for column numbers - * @param column - */ - private static void validateColumn(int column, SpreadsheetVersion ssVersion) { - int maxcol = ssVersion.getLastColumnIndex(); - if (column > maxcol) throw new IllegalArgumentException("Maximum column number is " + maxcol); - if (column < 0) throw new IllegalArgumentException("Minimum column number is 0"); - } - - - //TODO use the correct SpreadsheetVersion - public final boolean isFullColumnRange() { - return (_firstRow == 0 && _lastRow == SpreadsheetVersion.EXCEL97.getLastRowIndex()) - || (_firstRow == -1 && _lastRow == -1); - } - //TODO use the correct SpreadsheetVersion - public final boolean isFullRowRange() { - return (_firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex()) - || (_firstCol == -1 && _lastCol == -1); - } - - /** - * @return column number for the upper left hand corner - */ - public final int getFirstColumn() { - return _firstCol; - } - - /** - * @return row number for the upper left hand corner - */ - public final int getFirstRow() { - return _firstRow; - } - - /** - * @return column number for the lower right hand corner - */ - public final int getLastColumn() { - return _lastCol; - } - - /** - * @return row number for the lower right hand corner - */ - public final int getLastRow() { - return _lastRow; - } - - /** - * Determines if the given coordinates lie within the bounds - * of this range. - * - * @param rowInd The row, 0-based. - * @param colInd The column, 0-based. - * @return True if the coordinates lie within the bounds, false otherwise. - * @see #intersects(CellRangeAddressBase) for checking if two ranges overlap - */ - public boolean isInRange(int rowInd, int colInd) { - return _firstRow <= rowInd && rowInd <= _lastRow && //containsRow - _firstCol <= colInd && colInd <= _lastCol; //containsColumn - } - - /** - * Check if the row is in the specified cell range - * - * @param rowInd the row to check - * @return true if the range contains the row [rowInd] - */ - public boolean containsRow(int rowInd) { - return _firstRow <= rowInd && rowInd <= _lastRow; - } - - /** - * Check if the column is in the specified cell range - * - * @param colInd the column to check - * @return true if the range contains the column [colInd] - */ - public boolean containsColumn(int colInd) { - return _firstCol <= colInd && colInd <= _lastCol; - } - - /** - * Determines whether or not this CellRangeAddress and the specified CellRangeAddress intersect. - * - * @param other a candidate cell range address to check for intersection with this range - * @return returns true if this range and other range have at least 1 cell in common - * @see #isInRange(int, int) for checking if a single cell intersects - */ - public boolean intersects(CellRangeAddressBase other) { - return this._firstRow <= other._lastRow && - this._firstCol <= other._lastCol && - other._firstRow <= this._lastRow && - other._firstCol <= this._lastCol; - } - - /** - * @param firstCol column number for the upper left hand corner - */ - public final void setFirstColumn(int firstCol) { - _firstCol = firstCol; - } - - /** - * @param firstRow row number for the upper left hand corner - */ - public final void setFirstRow(int firstRow) { - _firstRow = firstRow; - } - - /** - * @param lastCol column number for the lower right hand corner - */ - public final void setLastColumn(int lastCol) { - _lastCol = lastCol; - } - - /** - * @param lastRow row number for the lower right hand corner - */ - public final void setLastRow(int lastRow) { - _lastRow = lastRow; - } - /** - * @return the size of the range (number of cells in the area). - */ - public int getNumberOfCells() { - return (_lastRow - _firstRow + 1) * (_lastCol - _firstCol + 1); - } - - @Override - public final String toString() { - CellReference crA = new CellReference(_firstRow, _firstCol); - CellReference crB = new CellReference(_lastRow, _lastCol); - return getClass().getName() + " [" + crA.formatAsString() + ":" + crB.formatAsString() +"]"; - } - - // In case _firstRow > _lastRow or _firstCol > _lastCol - protected int getMinRow() { - return Math.min(_firstRow, _lastRow); - } - protected int getMaxRow() { - return Math.max(_firstRow, _lastRow); - } - protected int getMinColumn() { - return Math.min(_firstCol, _lastCol); - } - protected int getMaxColumn() { - return Math.max(_firstCol, _lastCol); - } - - @Override - public boolean equals(Object other) { - if (other instanceof CellRangeAddressBase) { - CellRangeAddressBase o = (CellRangeAddressBase) other; - return ((getMinRow() == o.getMinRow()) && - (getMaxRow() == o.getMaxRow()) && - (getMinColumn() == o.getMinColumn()) && - (getMaxColumn() == o.getMaxColumn())); - } - return false; - } - - @Override - public int hashCode() { - int code = (getMinColumn() + - (getMaxColumn() << 8) + - (getMinRow() << 16) + - (getMaxRow() << 24)); - return code; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java b/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java deleted file mode 100644 index 8d9919823..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Implementation of the cell range address lists,like is described - * in OpenOffice.org's Excel Documentation: excelfileformat.pdf sec 2.5.14 - - * 'Cell Range Address List' - * - * In BIFF8 there is a common way to store absolute cell range address lists in - * several records (not formulas). A cell range address list consists of a field - * with the number of ranges and the list of the range addresses. Each cell - * range address (called an ADDR structure) contains 4 16-bit-values. - *

        - * - * @author Dragos Buleandra (dragos.buleandra@trade2b.ro) - */ -public class CellRangeAddressList { - - /** - * List of CellRangeAddresses. Each structure represents a cell range - */ - protected final List _list; - - public CellRangeAddressList() { - _list = new ArrayList(); - } - /** - * Convenience constructor for creating a CellRangeAddressList with a single - * CellRangeAddress. Other CellRangeAddresses may be added later. - */ - public CellRangeAddressList(int firstRow, int lastRow, int firstCol, int lastCol) { - this(); - addCellRangeAddress(firstRow, firstCol, lastRow, lastCol); - } - /** - * @param in the RecordInputstream to read the record from - */ - public CellRangeAddressList(RecordInputStream in) { - this(); - int nItems = in.readUShort(); - - for (int k = 0; k < nItems; k++) { - _list.add(new CellRangeAddress(in)); - } - } - /** - * Get the number of following ADDR structures. The number of this - * structures is automatically set when reading an Excel file and/or - * increased when you manually add a new ADDR structure . This is the reason - * there isn't a set method for this field . - * - * @return number of ADDR structures - */ - public int countRanges() { - return _list.size(); - } - - /** - * Add a cell range structure. - * - * @param firstRow - the upper left hand corner's row - * @param firstCol - the upper left hand corner's col - * @param lastRow - the lower right hand corner's row - * @param lastCol - the lower right hand corner's col - */ - public void addCellRangeAddress(int firstRow, int firstCol, int lastRow, int lastCol) { - CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol); - addCellRangeAddress(region); - } - public void addCellRangeAddress(CellRangeAddress cra) { - _list.add(cra); - } - public CellRangeAddress remove(int rangeIndex) { - if (_list.isEmpty()) { - throw new RuntimeException("List is empty"); - } - if (rangeIndex < 0 || rangeIndex >= _list.size()) { - throw new RuntimeException("Range index (" + rangeIndex - + ") is outside allowable range (0.." + (_list.size()-1) + ")"); - } - return _list.remove(rangeIndex); - } - - /** - * @return CellRangeAddress at the given index - */ - public CellRangeAddress getCellRangeAddress(int index) { - return _list.get(index); - } - - public int getSize() { - return getEncodedSize(_list.size()); - } - /** - * @return the total size of for the specified number of ranges, - * including the initial 2 byte range count - */ - public static int getEncodedSize(int numberOfRanges) { - return 2 + CellRangeAddress.getEncodedSize(numberOfRanges); - } - - public int serialize(int offset, byte[] data) { - int totalSize = getSize(); - serialize(new LittleEndianByteArrayOutputStream(data, offset, totalSize)); - return totalSize; - } - public void serialize(LittleEndianOutput out) { - int nItems = _list.size(); - out.writeShort(nItems); - for (int k = 0; k < nItems; k++) { - CellRangeAddress region = _list.get(k); - region.serialize(out); - } - } - - - public CellRangeAddressList copy() { - CellRangeAddressList result = new CellRangeAddressList(); - - int nItems = _list.size(); - for (int k = 0; k < nItems; k++) { - CellRangeAddress region = _list.get(k); - result.addCellRangeAddress(region.copy()); - } - return result; - } - public CellRangeAddress[] getCellRangeAddresses() { - CellRangeAddress[] result = new CellRangeAddress[_list.size()]; - _list.toArray(result); - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellRangeUtil.java b/trunk/src/java/org/apache/poi/ss/util/CellRangeUtil.java deleted file mode 100644 index 3fd013577..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellRangeUtil.java +++ /dev/null @@ -1,275 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.ArrayList; -import java.util.List; - -/** - * Utility class that builds on {@link CellRangeAddress} - * - * Portions of this class may be moved to {@link CellRangeAddressBase} - */ -public final class CellRangeUtil { - private CellRangeUtil() { - // no instance of this class - } - - public static final int NO_INTERSECTION = 1; - public static final int OVERLAP = 2; - /** first range is within the second range */ - public static final int INSIDE = 3; - /** first range encloses or is equal to the second */ - public static final int ENCLOSES = 4; - - /** - * Get the type of intersection between two cell ranges - * - * @param crB - the specified range - * @return code which reflects how the specified range is related to this range.
        - * Possible return codes are: - *
          - *
        • {@link #NO_INTERSECTION} - the specified range is outside of this range;
        • - *
        • {@link #OVERLAP} - both ranges partially overlap
        • - *
        • {@link #INSIDE} - the specified range is inside of this one
        • - *
        • {@link #ENCLOSES} - the specified range encloses (possibly exactly the same as) this range
        • - *
        - * @see CellRangeAddressBase#intersects(CellRangeAddressBase) - */ - public static int intersect(CellRangeAddress crA, CellRangeAddress crB ) - { - - int firstRow = crB.getFirstRow(); - int lastRow = crB.getLastRow(); - int firstCol = crB.getFirstColumn(); - int lastCol = crB.getLastColumn(); - - if ( - gt(crA.getFirstRow(), lastRow) || lt(crA.getLastRow(), firstRow) || - gt(crA.getFirstColumn(), lastCol) || lt(crA.getLastColumn(), firstCol) - ) - { - return NO_INTERSECTION; - } - else if( contains(crA, crB) ) - { - return INSIDE; - } - else if( contains(crB, crA)) - { - return ENCLOSES; - } - else - { - return OVERLAP; - } - } - - /** - * Do all possible cell merges between cells of the list so that:
        - *
          - *
        • if a cell range is completely inside of another cell range, it gets removed from the list
        • - *
        • if two cells have a shared border, merge them into one bigger cell range
        • - *
        - * @param cellRanges the ranges to merge - * @return list of merged cell ranges - */ - public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) { - if(cellRanges.length < 1) { - return new CellRangeAddress[] {}; - } - List list = toList(cellRanges); - List temp = mergeCellRanges(list); - return toArray(temp); - } - - private static List mergeCellRanges(List cellRangeList) - { - // loop until either only one item is left or we did not merge anything any more - while (cellRangeList.size() > 1) { - boolean somethingGotMerged = false; - - // look at all cell-ranges - for (int i = 0; i < cellRangeList.size(); i++) { - CellRangeAddress range1 = cellRangeList.get(i); - - // compare each cell range to all other cell-ranges - for (int j = i + 1; j < cellRangeList.size(); j++) { - CellRangeAddress range2 = cellRangeList.get(j); - - CellRangeAddress[] mergeResult = mergeRanges(range1, range2); - if (mergeResult == null) { - continue; - } - somethingGotMerged = true; - // overwrite range1 with first result - cellRangeList.set(i, mergeResult[0]); - // remove range2 - cellRangeList.remove(j--); - // add any extra results beyond the first - for (int k = 1; k < mergeResult.length; k++) { - j++; - cellRangeList.add(j, mergeResult[k]); - } - } - } - if (!somethingGotMerged) { - break; - } - } - - return cellRangeList; - } - - /** - * @return the new range(s) to replace the supplied ones. null if no merge is possible - */ - private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) { - int x = intersect(range1, range2); - switch(x) - { - case CellRangeUtil.NO_INTERSECTION: - // nothing in common: at most they could be adjacent to each other and thus form a single bigger area - if(hasExactSharedBorder(range1, range2)) { - return new CellRangeAddress[] { createEnclosingCellRange(range1, range2), }; - } - // else - No intersection and no shared border: do nothing - return null; - case CellRangeUtil.OVERLAP: - // commented out the cells overlap implementation, it caused endless loops, see Bug 55380 - // disabled for now, the algorithm will not detect some border cases this way currently! - //return resolveRangeOverlap(range1, range2); - return null; - case CellRangeUtil.INSIDE: - // Remove range2, since it is completely inside of range1 - return new CellRangeAddress[] { range1 }; - case CellRangeUtil.ENCLOSES: - // range2 encloses range1, so replace it with the enclosing one - return new CellRangeAddress[] { range2 }; - } - throw new RuntimeException("unexpected intersection result (" + x + ")"); - } - - private static CellRangeAddress[] toArray(List temp) { - CellRangeAddress[] result = new CellRangeAddress[temp.size()]; - temp.toArray(result); - return result; - } - private static List toList(CellRangeAddress[] temp) { - List result = new ArrayList(temp.length); - for (CellRangeAddress range : temp) { - result.add(range); - } - return result; - } - - /** - * Check if cell range A contains cell range B (B <= A) - * - * TODO: move this into {@link CellRangeAddressBase} - * - * @param crA cell range A - * @param crB cell range B - * @return true if cell range A contains cell range B - */ - public static boolean contains(CellRangeAddress crA, CellRangeAddress crB) - { - return le(crA.getFirstRow(), crB.getFirstRow()) && - ge(crA.getLastRow(), crB.getLastRow()) && - le(crA.getFirstColumn(), crB.getFirstColumn()) && - ge(crA.getLastColumn(), crB.getLastColumn()); - } - - /** - * Check if the two cell ranges have a shared border. - * - * @return true if the ranges have a complete shared border (i.e. - * the two ranges together make a simple rectangular region. - */ - public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) { - int oFirstRow = crB.getFirstRow(); - int oLastRow = crB.getLastRow(); - int oFirstCol = crB.getFirstColumn(); - int oLastCol = crB.getLastColumn(); - - if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || - oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) { - // ranges have a horizontal border in common - // make sure columns are identical: - return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol; - } - - if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol || - oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) { - // ranges have a vertical border in common - // make sure rows are identical: - return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow; - } - return false; - } - - /** - * Create an enclosing CellRange for the two cell ranges. - * - * @return enclosing CellRange - */ - public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) { - if( crB == null) { - return crA.copy(); - } - - int minRow = lt(crB.getFirstRow(), crA.getFirstRow()) ?crB.getFirstRow() :crA.getFirstRow(); - int maxRow = gt(crB.getLastRow(), crA.getLastRow()) ?crB.getLastRow() :crA.getLastRow(); - int minCol = lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(); - int maxCol = gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn(); - - return new CellRangeAddress(minRow, maxRow, minCol, maxCol); - } - - /** - * @return true if a < b - */ - private static boolean lt(int a, int b) - { - return a == -1 ? false : (b == -1 ? true : a < b); - } - - /** - * @return true if a <= b - */ - private static boolean le(int a, int b) - { - return a == b || lt(a,b); - } - - /** - * @return true if a > b - */ - private static boolean gt(int a, int b) - { - return lt(b,a); - } - - /** - * @return true if a >= b - */ - private static boolean ge(int a, int b) - { - return !lt(a,b); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellReference.java b/trunk/src/java/org/apache/poi/ss/util/CellReference.java deleted file mode 100644 index 6adc53007..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellReference.java +++ /dev/null @@ -1,572 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.usermodel.Cell; - -/** - *

        Common conversion functions between Excel style A1, C27 style - * cell references, and POI usermodel style row=0, column=0 - * style references. Handles sheet-based and sheet-free references - * as well, eg "Sheet1!A1" and "$B$72"

        - * - *

        Use CellReference when the concept of - * relative/absolute does apply (such as a cell reference in a formula). - * Use {@link CellAddress} when you want to refer to the location of a cell in a sheet - * when the concept of relative/absolute does not apply (such as the anchor location - * of a cell comment). - * CellReferences have a concept of "sheet", while CellAddresses do not.

        - */ -public class CellReference { - /** - * Used to classify identifiers found in formulas as cell references or not. - */ - public enum NameType { - CELL, - NAMED_RANGE, - COLUMN, - ROW, - BAD_CELL_OR_NAMED_RANGE - } - - /** The character ($) that signifies a row or column value is absolute instead of relative */ - private static final char ABSOLUTE_REFERENCE_MARKER = '$'; - /** The character (!) that separates sheet names from cell references */ - private static final char SHEET_NAME_DELIMITER = '!'; - /** The character (') used to quote sheet names when they contain special characters */ - private static final char SPECIAL_NAME_DELIMITER = '\''; - - /** - * Matches a run of one or more letters followed by a run of one or more digits. - * Both the letter and number groups are optional. - * The run of letters is group 1 and the run of digits is group 2. - * Each group may optionally be prefixed with a single '$'. - */ - private static final Pattern CELL_REF_PATTERN = Pattern.compile("(\\$?[A-Z]+)?" + "(\\$?[0-9]+)?", Pattern.CASE_INSENSITIVE); - /** - * Matches references only where row and column are included. - * Matches a run of one or more letters followed by a run of one or more digits. - * If a reference does not match this pattern, it might match COLUMN_REF_PATTERN or ROW_REF_PATTERN - * References may optionally include a single '$' before each group, but these are excluded from the Matcher.group(int). - */ - private static final Pattern STRICTLY_CELL_REF_PATTERN = Pattern.compile("\\$?([A-Z]+)" + "\\$?([0-9]+)", Pattern.CASE_INSENSITIVE); - /** - * Matches a run of one or more letters. The run of letters is group 1. - * References may optionally include a single '$' before the group, but these are excluded from the Matcher.group(int). - */ - private static final Pattern COLUMN_REF_PATTERN = Pattern.compile("\\$?([A-Z]+)", Pattern.CASE_INSENSITIVE); - /** - * Matches a run of one or more letters. The run of numbers is group 1. - * References may optionally include a single '$' before the group, but these are excluded from the Matcher.group(int). - */ - private static final Pattern ROW_REF_PATTERN = Pattern.compile("\\$?([0-9]+)"); - /** - * Named range names must start with a letter or underscore. Subsequent characters may include - * digits or dot. (They can even end in dot). - */ - private static final Pattern NAMED_RANGE_NAME_PATTERN = Pattern.compile("[_A-Z][_.A-Z0-9]*", Pattern.CASE_INSENSITIVE); - //private static final String BIFF8_LAST_COLUMN = SpreadsheetVersion.EXCEL97.getLastColumnName(); - //private static final int BIFF8_LAST_COLUMN_TEXT_LEN = BIFF8_LAST_COLUMN.length(); - //private static final String BIFF8_LAST_ROW = String.valueOf(SpreadsheetVersion.EXCEL97.getMaxRows()); - //private static final int BIFF8_LAST_ROW_TEXT_LEN = BIFF8_LAST_ROW.length(); - - // FIXME: _sheetName may be null, depending on the entry point. - // Perhaps it would be better to declare _sheetName is never null, using an empty string to represent a 2D reference. - private final String _sheetName; - private final int _rowIndex; - private final int _colIndex; - private final boolean _isRowAbs; - private final boolean _isColAbs; - - /** - * Create an cell ref from a string representation. Sheet names containing special characters should be - * delimited and escaped as per normal syntax rules for formulas. - */ - public CellReference(String cellRef) { - if(cellRef.toUpperCase(Locale.ROOT).endsWith("#REF!")) { - throw new IllegalArgumentException("Cell reference invalid: " + cellRef); - } - - CellRefParts parts = separateRefParts(cellRef); - _sheetName = parts.sheetName; - - String colRef = parts.colRef; - _isColAbs = (colRef.length() > 0) && colRef.charAt(0) == '$'; - if (_isColAbs) { - colRef = colRef.substring(1); - } - if (colRef.length() == 0) { - _colIndex = -1; - } else { - _colIndex = convertColStringToIndex(colRef); - } - - String rowRef=parts.rowRef; - _isRowAbs = (rowRef.length() > 0) && rowRef.charAt(0) == '$'; - if (_isRowAbs) { - rowRef = rowRef.substring(1); - } - if (rowRef.length() == 0) { - _rowIndex = -1; - } else { - _rowIndex = Integer.parseInt(rowRef)-1; // -1 to convert 1-based to zero-based - } - } - - public CellReference(int pRow, int pCol) { - this(pRow, pCol, false, false); - } - public CellReference(int pRow, short pCol) { - this(pRow, pCol & 0xFFFF, false, false); - } - - public CellReference(Cell cell) { - this(cell.getRowIndex(), cell.getColumnIndex(), false, false); - } - - public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) { - this(null, pRow, pCol, pAbsRow, pAbsCol); - } - public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) { - // TODO - "-1" is a special value being temporarily used for whole row and whole column area references. - // so these checks are currently N.Q.R. - if(pRow < -1) { - throw new IllegalArgumentException("row index may not be negative, but had " + pRow); - } - if(pCol < -1) { - throw new IllegalArgumentException("column index may not be negative, but had " + pCol); - } - _sheetName = pSheetName; - _rowIndex=pRow; - _colIndex=pCol; - _isRowAbs = pAbsRow; - _isColAbs=pAbsCol; - } - - public int getRow(){return _rowIndex;} - public short getCol(){return (short) _colIndex;} - public boolean isRowAbsolute(){return _isRowAbs;} - public boolean isColAbsolute(){return _isColAbs;} - /** - * @return possibly null if this is a 2D reference. Special characters are not - * escaped or delimited - */ - public String getSheetName(){ - return _sheetName; - } - - public static boolean isPartAbsolute(String part) { - return part.charAt(0) == ABSOLUTE_REFERENCE_MARKER; - } - /** - * takes in a column reference portion of a CellRef and converts it from - * ALPHA-26 number format to 0-based base 10. - * 'A' -> 0 - * 'Z' -> 25 - * 'AA' -> 26 - * 'IV' -> 255 - * @return zero based column index - */ - public static int convertColStringToIndex(String ref) { - int retval=0; - char[] refs = ref.toUpperCase(Locale.ROOT).toCharArray(); - for (int k=0; kNameType
        - */ - public static NameType classifyCellReference(String str, SpreadsheetVersion ssVersion) { - int len = str.length(); - if (len < 1) { - throw new IllegalArgumentException("Empty string not allowed"); - } - char firstChar = str.charAt(0); - switch (firstChar) { - case ABSOLUTE_REFERENCE_MARKER: - case '.': - case '_': - break; - default: - if (!Character.isLetter(firstChar) && !Character.isDigit(firstChar)) { - throw new IllegalArgumentException("Invalid first char (" + firstChar - + ") of cell reference or named range. Letter expected"); - } - } - if (!Character.isDigit(str.charAt(len-1))) { - // no digits at end of str - return validateNamedRangeName(str, ssVersion); - } - Matcher cellRefPatternMatcher = STRICTLY_CELL_REF_PATTERN.matcher(str); - if (!cellRefPatternMatcher.matches()) { - return validateNamedRangeName(str, ssVersion); - } - String lettersGroup = cellRefPatternMatcher.group(1); - String digitsGroup = cellRefPatternMatcher.group(2); - if (cellReferenceIsWithinRange(lettersGroup, digitsGroup, ssVersion)) { - // valid cell reference - return NameType.CELL; - } - // If str looks like a cell reference, but is out of (row/col) range, it is a valid - // named range name - // This behaviour is a little weird. For example, "IW123" is a valid named range name - // because the column "IW" is beyond the maximum "IV". Note - this behaviour is version - // dependent. In BIFF12, "IW123" is not a valid named range name, but in BIFF8 it is. - if (str.indexOf(ABSOLUTE_REFERENCE_MARKER) >= 0) { - // Of course, named range names cannot have '$' - return NameType.BAD_CELL_OR_NAMED_RANGE; - } - return NameType.NAMED_RANGE; - } - - private static NameType validateNamedRangeName(String str, SpreadsheetVersion ssVersion) { - Matcher colMatcher = COLUMN_REF_PATTERN.matcher(str); - if (colMatcher.matches()) { - String colStr = colMatcher.group(1); - if (isColumnWithinRange(colStr, ssVersion)) { - return NameType.COLUMN; - } - } - Matcher rowMatcher = ROW_REF_PATTERN.matcher(str); - if (rowMatcher.matches()) { - String rowStr = rowMatcher.group(1); - if (isRowWithinRange(rowStr, ssVersion)) { - return NameType.ROW; - } - } - if (!NAMED_RANGE_NAME_PATTERN.matcher(str).matches()) { - return NameType.BAD_CELL_OR_NAMED_RANGE; - } - return NameType.NAMED_RANGE; - } - - - /** - * Used to decide whether a name of the form "[A-Z]*[0-9]*" that appears in a formula can be - * interpreted as a cell reference. Names of that form can be also used for sheets and/or - * named ranges, and in those circumstances, the question of whether the potential cell - * reference is valid (in range) becomes important. - *

        - * Note - that the maximum sheet size varies across Excel versions: - *

        - *

        - * - * - * - * - *
        Version  File Format  Last Column  Last Row
        97-2003BIFF8"IV" (2^8)65536 (2^14)
        2007BIFF12"XFD" (2^14)1048576 (2^20)
        - * POI currently targets BIFF8 (Excel 97-2003), so the following behaviour can be observed for - * this method: - *
        - * - * - * - * - * - * - * - * - * - * - * - *
        Input           Result 
        "A", "1"true
        "a", "111"true
        "A", "65536"true
        "A", "65537"false
        "iv", "1"true
        "IW", "1"false
        "AAA", "1"false
        "a", "111"true
        "Sheet", "1"false
        - * - * @param colStr a string of only letter characters - * @param rowStr a string of only digit characters - * @return true if the row and col parameters are within range of a BIFF8 spreadsheet. - */ - public static boolean cellReferenceIsWithinRange(String colStr, String rowStr, SpreadsheetVersion ssVersion) { - if (!isColumnWithinRange(colStr, ssVersion)) { - return false; - } - return isRowWithinRange(rowStr, ssVersion); - } - - /** - * @deprecated 3.15 beta 2. Use {@link #isColumnWithinRange}. - */ - public static boolean isColumnWithnRange(String colStr, SpreadsheetVersion ssVersion) { - return isColumnWithinRange(colStr, ssVersion); - } - - public static boolean isColumnWithinRange(String colStr, SpreadsheetVersion ssVersion) { - // Equivalent to 0 <= CellReference.convertColStringToIndex(colStr) <= ssVersion.getLastColumnIndex() - - String lastCol = ssVersion.getLastColumnName(); - int lastColLength = lastCol.length(); - - int numberOfLetters = colStr.length(); - if(numberOfLetters > lastColLength) { - // "Sheet1" case etc - return false; // that was easy - } - if(numberOfLetters == lastColLength) { - if(colStr.toUpperCase(Locale.ROOT).compareTo(lastCol) > 0) { - return false; - } - } else { - // apparent column name has less chars than max - // no need to check range - } - return true; - } - - /** - * @deprecated 3.15 beta 2. Use {@link #isRowWithinRange} - */ - public static boolean isRowWithnRange(String rowStr, SpreadsheetVersion ssVersion) { - return isRowWithinRange(rowStr, ssVersion); - } - - public static boolean isRowWithinRange(String rowStr, SpreadsheetVersion ssVersion) { - int rowNum = Integer.parseInt(rowStr) - 1; - return 0 <= rowNum && rowNum <= ssVersion.getLastRowIndex(); - } - - private static final class CellRefParts { - final String sheetName; - final String rowRef; - final String colRef; - - private CellRefParts(String sheetName, String rowRef, String colRef) { - this.sheetName = sheetName; - this.rowRef = (rowRef != null) ? rowRef : ""; - this.colRef = (colRef != null) ? colRef : ""; - } - } - - /** - * Separates the sheet name, row, and columns from a cell reference string. - * - * @param reference is a string that identifies a cell within the sheet or workbook - * reference may not refer to a cell in an external workbook - * reference may be absolute or relative. - * @return String array of sheetName, column (in ALPHA-26 format), and row - * output column or row elements will contain absolute reference markers if they - * existed in the input reference. - */ - private static CellRefParts separateRefParts(String reference) { - int plingPos = reference.lastIndexOf(SHEET_NAME_DELIMITER); - final String sheetName = parseSheetName(reference, plingPos); - String cell = reference.substring(plingPos+1).toUpperCase(Locale.ROOT); - Matcher matcher = CELL_REF_PATTERN.matcher(cell); - if (!matcher.matches()) throw new IllegalArgumentException("Invalid CellReference: " + reference); - String col = matcher.group(1); - String row = matcher.group(2); - - CellRefParts cellRefParts = new CellRefParts(sheetName, row, col); - return cellRefParts; - } - - private static String parseSheetName(String reference, int indexOfSheetNameDelimiter) { - if(indexOfSheetNameDelimiter < 0) { - return null; - } - - boolean isQuoted = reference.charAt(0) == SPECIAL_NAME_DELIMITER; - if(!isQuoted) { - // sheet names with spaces must be quoted - if (reference.indexOf(' ') == -1) { - return reference.substring(0, indexOfSheetNameDelimiter); - } else { - throw new IllegalArgumentException("Sheet names containing spaces must be quoted: (" + reference + ")"); - } - } - int lastQuotePos = indexOfSheetNameDelimiter-1; - if(reference.charAt(lastQuotePos) != SPECIAL_NAME_DELIMITER) { - throw new IllegalArgumentException("Mismatched quotes: (" + reference + ")"); - } - - // TODO - refactor cell reference parsing logic to one place. - // Current known incarnations: - // FormulaParser.GetName() - // CellReference.parseSheetName() (here) - // AreaReference.separateAreaRefs() - // SheetNameFormatter.format() (inverse) - - StringBuffer sb = new StringBuffer(indexOfSheetNameDelimiter); - - for(int i=1; i D - */ - public static String convertNumToColString(int col) { - // Excel counts column A as the 1st column, we - // treat it as the 0th one - int excelColNum = col + 1; - - StringBuilder colRef = new StringBuilder(2); - int colRemain = excelColNum; - - while(colRemain > 0) { - int thisPart = colRemain % 26; - if(thisPart == 0) { thisPart = 26; } - colRemain = (colRemain - thisPart) / 26; - - // The letter A is at 65 - char colChar = (char)(thisPart+64); - colRef.insert(0, colChar); - } - - return colRef.toString(); - } - - /** - * Returns a text representation of this cell reference. - *

        - * Example return values: - * - * - * - * - * - *
        ResultComment
        A1Cell reference without sheet
        Sheet1!A1Standard sheet name
        'O''Brien''s Sales'!A1' Sheet name with special characters
        - * @return the text representation of this cell reference as it would appear in a formula. - */ - public String formatAsString() { - StringBuffer sb = new StringBuffer(32); - if(_sheetName != null) { - SheetNameFormatter.appendFormat(sb, _sheetName); - sb.append(SHEET_NAME_DELIMITER); - } - appendCellReference(sb); - return sb.toString(); - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - - /** - * Returns the three parts of the cell reference, the - * Sheet name (or null if none supplied), the 1 based - * row number, and the A based column letter. - * This will not include any markers for absolute - * references, so use {@link #formatAsString()} - * to properly turn references into strings. - * @return String array of { sheetName, rowString, colString } - */ - public String[] getCellRefParts() { - return new String[] { - _sheetName, - Integer.toString(_rowIndex+1), - convertNumToColString(_colIndex) - }; - } - - /** - * Appends cell reference with '$' markers for absolute values as required. - * Sheet name is not included. - */ - /* package */ void appendCellReference(StringBuffer sb) { - if (_colIndex != -1) { - if(_isColAbs) { - sb.append(ABSOLUTE_REFERENCE_MARKER); - } - sb.append( convertNumToColString(_colIndex)); - } - if (_rowIndex != -1) { - if(_isRowAbs) { - sb.append(ABSOLUTE_REFERENCE_MARKER); - } - sb.append(_rowIndex+1); - } - } - - /** - * Checks whether this cell reference is equal to another object. - *

        - * Two cells references are assumed to be equal if their string representations - * ({@link #formatAsString()} are equal. - *

        - */ - @Override - public boolean equals(Object o){ - if (this == o) { - return true; - } - if(!(o instanceof CellReference)) { - return false; - } - CellReference cr = (CellReference) o; - return _rowIndex == cr._rowIndex - && _colIndex == cr._colIndex - && _isRowAbs == cr._isRowAbs - && _isColAbs == cr._isColAbs - && ((_sheetName == null) - ? (cr._sheetName == null) - : _sheetName.equals(cr._sheetName)); - } - - @Override - public int hashCode() { - int result = 17; - result = 31 * result + _rowIndex; - result = 31 * result + _colIndex; - result = 31 * result + (_isRowAbs ? 1 : 0); - result = 31 * result + (_isColAbs ? 1 : 0); - result = 31 * result + (_sheetName == null ? 0 : _sheetName.hashCode()); - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/CellUtil.java b/trunk/src/java/org/apache/poi/ss/util/CellUtil.java deleted file mode 100644 index 3dad83aab..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/CellUtil.java +++ /dev/null @@ -1,749 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Removal; - -/** - * Various utility functions that make working with a cells and rows easier. The various methods - * that deal with style's allow you to create your CellStyles as you need them. When you apply a - * style change to a cell, the code will attempt to see if a style already exists that meets your - * needs. If not, then it will create a new style. This is to prevent creating too many styles. - * there is an upper limit in Excel on the number of styles that can be supported. - * - *@author Eric Pugh epugh@upstate.com - *@author (secondary) Avinash Kewalramani akewalramani@accelrys.com - */ -public final class CellUtil { - - private static final POILogger log = POILogFactory.getLogger(CellUtil.class); - - // FIXME: Move these constants into an enum - public static final String ALIGNMENT = "alignment"; - public static final String BORDER_BOTTOM = "borderBottom"; - public static final String BORDER_LEFT = "borderLeft"; - public static final String BORDER_RIGHT = "borderRight"; - public static final String BORDER_TOP = "borderTop"; - public static final String BOTTOM_BORDER_COLOR = "bottomBorderColor"; - public static final String LEFT_BORDER_COLOR = "leftBorderColor"; - public static final String RIGHT_BORDER_COLOR = "rightBorderColor"; - public static final String TOP_BORDER_COLOR = "topBorderColor"; - public static final String DATA_FORMAT = "dataFormat"; - public static final String FILL_BACKGROUND_COLOR = "fillBackgroundColor"; - public static final String FILL_FOREGROUND_COLOR = "fillForegroundColor"; - public static final String FILL_PATTERN = "fillPattern"; - public static final String FONT = "font"; - public static final String HIDDEN = "hidden"; - public static final String INDENTION = "indention"; - public static final String LOCKED = "locked"; - public static final String ROTATION = "rotation"; - public static final String VERTICAL_ALIGNMENT = "verticalAlignment"; - public static final String WRAP_TEXT = "wrapText"; - - private static final Set shortValues = Collections.unmodifiableSet( - new HashSet(Arrays.asList( - BOTTOM_BORDER_COLOR, - LEFT_BORDER_COLOR, - RIGHT_BORDER_COLOR, - TOP_BORDER_COLOR, - FILL_FOREGROUND_COLOR, - FILL_BACKGROUND_COLOR, - INDENTION, - DATA_FORMAT, - FONT, - ROTATION - ))); - private static final Set booleanValues = Collections.unmodifiableSet( - new HashSet(Arrays.asList( - LOCKED, - HIDDEN, - WRAP_TEXT - ))); - private static final Set borderTypeValues = Collections.unmodifiableSet( - new HashSet(Arrays.asList( - BORDER_BOTTOM, - BORDER_LEFT, - BORDER_RIGHT, - BORDER_TOP - ))); - - - - private static UnicodeMapping unicodeMappings[]; - - private static final class UnicodeMapping { - - public final String entityName; - public final String resolvedValue; - - public UnicodeMapping(String pEntityName, String pResolvedValue) { - entityName = "&" + pEntityName + ";"; - resolvedValue = pResolvedValue; - } - } - - private CellUtil() { - // no instances of this class - } - - /** - * Get a row from the spreadsheet, and create it if it doesn't exist. - * - * @param rowIndex The 0 based row number - * @param sheet The sheet that the row is part of. - * @return The row indicated by the rowCounter - */ - public static Row getRow(int rowIndex, Sheet sheet) { - Row row = sheet.getRow(rowIndex); - if (row == null) { - row = sheet.createRow(rowIndex); - } - return row; - } - - - /** - * Get a specific cell from a row. If the cell doesn't exist, then create it. - * - * @param row The row that the cell is part of - * @param columnIndex The column index that the cell is in. - * @return The cell indicated by the column. - */ - public static Cell getCell(Row row, int columnIndex) { - Cell cell = row.getCell(columnIndex); - - if (cell == null) { - cell = row.createCell(columnIndex); - } - return cell; - } - - - /** - * Creates a cell, gives it a value, and applies a style if provided - * - * @param row the row to create the cell in - * @param column the column index to create the cell in - * @param value The value of the cell - * @param style If the style is not null, then set - * @return A new Cell - */ - public static Cell createCell(Row row, int column, String value, CellStyle style) { - Cell cell = getCell(row, column); - - cell.setCellValue(cell.getRow().getSheet().getWorkbook().getCreationHelper() - .createRichTextString(value)); - if (style != null) { - cell.setCellStyle(style); - } - return cell; - } - - - /** - * Create a cell, and give it a value. - * - *@param row the row to create the cell in - *@param column the column index to create the cell in - *@param value The value of the cell - *@return A new Cell. - */ - public static Cell createCell(Row row, int column, String value) { - return createCell(row, column, value, null); - } - - /** - * Take a cell, and align it. - * - * This is superior to cell.getCellStyle().setAlignment(align) because - * this method will not modify the CellStyle object that may be referenced - * by multiple cells. Instead, this method will search for existing CellStyles - * that match the desired CellStyle, creating a new CellStyle with the desired - * style if no match exists. - * - * @param cell the cell to set the alignment for - * @param workbook The workbook that is being worked with. - * @param align the column alignment to use. - * - * @deprecated 3.15-beta2. Use {@link #setAlignment(Cell, HorizontalAlignment)} instead. - * - * @see CellStyle for alignment options - */ - @Deprecated - @Removal(version="3.17") - public static void setAlignment(Cell cell, Workbook workbook, short align) { - setAlignment(cell, HorizontalAlignment.forInt(align)); - } - - /** - * Take a cell, and align it. - * - * This is superior to cell.getCellStyle().setAlignment(align) because - * this method will not modify the CellStyle object that may be referenced - * by multiple cells. Instead, this method will search for existing CellStyles - * that match the desired CellStyle, creating a new CellStyle with the desired - * style if no match exists. - * - * @param cell the cell to set the alignment for - * @param align the horizontal alignment to use. - * - * @see HorizontalAlignment for alignment options - * @since POI 3.15 beta 3 - */ - public static void setAlignment(Cell cell, HorizontalAlignment align) { - setCellStyleProperty(cell, ALIGNMENT, align); - } - - /** - * Take a cell, and vertically align it. - * - * This is superior to cell.getCellStyle().setVerticalAlignment(align) because - * this method will not modify the CellStyle object that may be referenced - * by multiple cells. Instead, this method will search for existing CellStyles - * that match the desired CellStyle, creating a new CellStyle with the desired - * style if no match exists. - * - * @param cell the cell to set the alignment for - * @param align the vertical alignment to use. - * - * @see VerticalAlignment for alignment options - * @since POI 3.15 beta 3 - */ - public static void setVerticalAlignment(Cell cell, VerticalAlignment align) { - setCellStyleProperty(cell, VERTICAL_ALIGNMENT, align); - } - - /** - * Take a cell, and apply a font to it - * - * @param cell the cell to set the alignment for - * @param workbook The workbook that is being worked with. - * @param font The Font that you want to set. - * @throws IllegalArgumentException if font and cell do not belong to the same workbook - * - * @deprecated 3.15-beta2. Use {@link #setFont(Cell, Font)} instead. - */ - @Deprecated - @Removal(version="3.17") - public static void setFont(Cell cell, Workbook workbook, Font font) { - setFont(cell, font); - } - - /** - * Take a cell, and apply a font to it - * - * @param cell the cell to set the alignment for - * @param font The Font that you want to set. - * @throws IllegalArgumentException if font and cell do not belong to the same workbook - */ - public static void setFont(Cell cell, Font font) { - // Check if font belongs to workbook - Workbook wb = cell.getSheet().getWorkbook(); - final short fontIndex = font.getIndex(); - if (!wb.getFontAt(fontIndex).equals(font)) { - throw new IllegalArgumentException("Font does not belong to this workbook"); - } - - // Check if cell belongs to workbook - // (checked in setCellStyleProperty) - - setCellStyleProperty(cell, FONT, fontIndex); - } - - /** - *

        This method attempts to find an existing CellStyle that matches the cell's - * current style plus styles properties in properties. A new style is created if the - * workbook does not contain a matching style.

        - * - *

        Modifies the cell style of cell without affecting other cells that use the - * same style.

        - * - *

        This is necessary because Excel has an upper limit on the number of styles that it supports.

        - * - *

        This function is more efficient than multiple calls to - * {@link #setCellStyleProperty(org.apache.poi.ss.usermodel.Cell, org.apache.poi.ss.usermodel.Workbook, String, Object)} - * if adding multiple cell styles.

        - * - *

        For performance reasons, if this is the only cell in a workbook that uses a cell style, - * this method does NOT remove the old style from the workbook. - * - *

        - * - * @param cell The cell to change the style of - * @param properties The properties to be added to a cell style, as {propertyName: propertyValue}. - * @since POI 3.14 beta 2 - */ - public static void setCellStyleProperties(Cell cell, Map properties) { - Workbook workbook = cell.getSheet().getWorkbook(); - CellStyle originalStyle = cell.getCellStyle(); - CellStyle newStyle = null; - Map values = getFormatProperties(originalStyle); - putAll(properties, values); - - // index seems like what index the cellstyle is in the list of styles for a workbook. - // not good to compare on! - int numberCellStyles = workbook.getNumCellStyles(); - - for (int i = 0; i < numberCellStyles; i++) { - CellStyle wbStyle = workbook.getCellStyleAt(i); - Map wbStyleMap = getFormatProperties(wbStyle); - - // the desired style already exists in the workbook. Use the existing style. - if (wbStyleMap.equals(values)) { - newStyle = wbStyle; - break; - } - } - - // the desired style does not exist in the workbook. Create a new style with desired properties. - if (newStyle == null) { - newStyle = workbook.createCellStyle(); - setFormatProperties(newStyle, workbook, values); - } - - cell.setCellStyle(newStyle); - } - - /** - *

        This method attempts to find an existing CellStyle that matches the cell's - * current style plus a single style property propertyName with value - * propertyValue. - * A new style is created if the workbook does not contain a matching style.

        - * - *

        Modifies the cell style of cell without affecting other cells that use the - * same style.

        - * - *

        If setting more than one cell style property on a cell, use - * {@link #setCellStyleProperties(org.apache.poi.ss.usermodel.Cell, Map)}, - * which is faster and does not add unnecessary intermediate CellStyles to the workbook.

        - * - * @param cell The cell that is to be changed. - * @param workbook The workbook that is being worked with. - * @param propertyName The name of the property that is to be changed. - * @param propertyValue The value of the property that is to be changed. - * - * @deprecated 3.15-beta2. Use {@link #setCellStyleProperty(Cell, String, Object)} instead. - */ - @Deprecated - @Removal(version="3.17") - public static void setCellStyleProperty(Cell cell, Workbook workbook, String propertyName, - Object propertyValue) { - setCellStyleProperty(cell, propertyName, propertyValue); - } - - /** - *

        This method attempts to find an existing CellStyle that matches the cell's - * current style plus a single style property propertyName with value - * propertyValue. - * A new style is created if the workbook does not contain a matching style.

        - * - *

        Modifies the cell style of cell without affecting other cells that use the - * same style.

        - * - *

        If setting more than one cell style property on a cell, use - * {@link #setCellStyleProperties(org.apache.poi.ss.usermodel.Cell, Map)}, - * which is faster and does not add unnecessary intermediate CellStyles to the workbook.

        - * - * @param cell The cell that is to be changed. - * @param propertyName The name of the property that is to be changed. - * @param propertyValue The value of the property that is to be changed. - */ - public static void setCellStyleProperty(Cell cell, String propertyName, Object propertyValue) { - Map property = Collections.singletonMap(propertyName, propertyValue); - setCellStyleProperties(cell, property); - } - - /** - * Returns a map containing the format properties of the given cell style. - * The returned map is not tied to style, so subsequent changes - * to style will not modify the map, and changes to the returned - * map will not modify the cell style. The returned map is mutable. - * - * @param style cell style - * @return map of format properties (String -> Object) - * @see #setFormatProperties(org.apache.poi.ss.usermodel.CellStyle, org.apache.poi.ss.usermodel.Workbook, java.util.Map) - */ - private static Map getFormatProperties(CellStyle style) { - Map properties = new HashMap(); - put(properties, ALIGNMENT, style.getAlignmentEnum()); - put(properties, VERTICAL_ALIGNMENT, style.getVerticalAlignmentEnum()); - put(properties, BORDER_BOTTOM, style.getBorderBottomEnum()); - put(properties, BORDER_LEFT, style.getBorderLeftEnum()); - put(properties, BORDER_RIGHT, style.getBorderRightEnum()); - put(properties, BORDER_TOP, style.getBorderTopEnum()); - put(properties, BOTTOM_BORDER_COLOR, style.getBottomBorderColor()); - put(properties, DATA_FORMAT, style.getDataFormat()); - put(properties, FILL_PATTERN, style.getFillPatternEnum()); - put(properties, FILL_FOREGROUND_COLOR, style.getFillForegroundColor()); - put(properties, FILL_BACKGROUND_COLOR, style.getFillBackgroundColor()); - put(properties, FONT, style.getFontIndex()); - put(properties, HIDDEN, style.getHidden()); - put(properties, INDENTION, style.getIndention()); - put(properties, LEFT_BORDER_COLOR, style.getLeftBorderColor()); - put(properties, LOCKED, style.getLocked()); - put(properties, RIGHT_BORDER_COLOR, style.getRightBorderColor()); - put(properties, ROTATION, style.getRotation()); - put(properties, TOP_BORDER_COLOR, style.getTopBorderColor()); - put(properties, WRAP_TEXT, style.getWrapText()); - return properties; - } - - /** - * Copies the entries in src to dest, using the preferential data type - * so that maps can be compared for equality - * - * @param src the property map to copy from (read-only) - * @param dest the property map to copy into - * @since POI 3.15 beta 3 - */ - private static void putAll(final Map src, Map dest) { - for (final String key : src.keySet()) { - if (shortValues.contains(key)) { - dest.put(key, getShort(src, key)); - } else if (booleanValues.contains(key)) { - dest.put(key, getBoolean(src, key)); - } else if (borderTypeValues.contains(key)) { - dest.put(key, getBorderStyle(src, key)); - } else if (ALIGNMENT.equals(key)) { - dest.put(key, getHorizontalAlignment(src, key)); - } else if (VERTICAL_ALIGNMENT.equals(key)) { - dest.put(key, getVerticalAlignment(src, key)); - } else if (FILL_PATTERN.equals(key)) { - dest.put(key, getFillPattern(src, key)); - } else { - if (log.check(POILogger.INFO)) { - log.log(POILogger.INFO, "Ignoring unrecognized CellUtil format properties key: " + key); - } - } - } - } - - /** - * Sets the format properties of the given style based on the given map. - * - * @param style cell style - * @param workbook parent workbook - * @param properties map of format properties (String -> Object) - * @see #getFormatProperties(CellStyle) - */ - private static void setFormatProperties(CellStyle style, Workbook workbook, Map properties) { - style.setAlignment(getHorizontalAlignment(properties, ALIGNMENT)); - style.setVerticalAlignment(getVerticalAlignment(properties, VERTICAL_ALIGNMENT)); - style.setBorderBottom(getBorderStyle(properties, BORDER_BOTTOM)); - style.setBorderLeft(getBorderStyle(properties, BORDER_LEFT)); - style.setBorderRight(getBorderStyle(properties, BORDER_RIGHT)); - style.setBorderTop(getBorderStyle(properties, BORDER_TOP)); - style.setBottomBorderColor(getShort(properties, BOTTOM_BORDER_COLOR)); - style.setDataFormat(getShort(properties, DATA_FORMAT)); - style.setFillPattern(getFillPattern(properties, FILL_PATTERN)); - style.setFillForegroundColor(getShort(properties, FILL_FOREGROUND_COLOR)); - style.setFillBackgroundColor(getShort(properties, FILL_BACKGROUND_COLOR)); - style.setFont(workbook.getFontAt(getShort(properties, FONT))); - style.setHidden(getBoolean(properties, HIDDEN)); - style.setIndention(getShort(properties, INDENTION)); - style.setLeftBorderColor(getShort(properties, LEFT_BORDER_COLOR)); - style.setLocked(getBoolean(properties, LOCKED)); - style.setRightBorderColor(getShort(properties, RIGHT_BORDER_COLOR)); - style.setRotation(getShort(properties, ROTATION)); - style.setTopBorderColor(getShort(properties, TOP_BORDER_COLOR)); - style.setWrapText(getBoolean(properties, WRAP_TEXT)); - } - - /** - * Utility method that returns the named short value form the given map. - * - * @param properties map of named properties (String -> Object) - * @param name property name - * @return zero if the property does not exist, or is not a {@link Short} - * otherwise the property value - */ - private static short getShort(Map properties, String name) { - Object value = properties.get(name); - if (value instanceof Short) { - return ((Short) value).shortValue(); - } - return 0; - } - - /** - * Utility method that returns the named BorderStyle value form the given map. - * - * @param properties map of named properties (String -> Object) - * @param name property name - * @return Border style if set, otherwise {@link BorderStyle#NONE} - */ - private static BorderStyle getBorderStyle(Map properties, String name) { - Object value = properties.get(name); - BorderStyle border; - if (value instanceof BorderStyle) { - border = (BorderStyle) value; - } - // @deprecated 3.15 beta 2. getBorderStyle will only work on BorderStyle enums instead of codes in the future. - else if (value instanceof Short) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Deprecation warning: CellUtil properties map uses Short values for " - + name + ". Should use BorderStyle enums instead."); - } - System.out.println("BorderStyle short usage"); - short code = ((Short) value).shortValue(); - border = BorderStyle.valueOf(code); - } - else if (value == null) { - border = BorderStyle.NONE; - } - else { - throw new RuntimeException("Unexpected border style class. Must be BorderStyle or Short (deprecated)."); - } - return border; - } - - /** - * Utility method that returns the named FillPatternType value form the given map. - * - * @param properties map of named properties (String -> Object) - * @param name property name - * @return FillPatternType style if set, otherwise {@link FillPatternType#NO_FILL} - * @since POI 3.15 beta 3 - */ - private static FillPatternType getFillPattern(Map properties, String name) { - Object value = properties.get(name); - FillPatternType pattern; - if (value instanceof FillPatternType) { - pattern = (FillPatternType) value; - } - // @deprecated 3.15 beta 2. getFillPattern will only work on FillPatternType enums instead of codes in the future. - else if (value instanceof Short) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Deprecation warning: CellUtil properties map uses Short values for " - + name + ". Should use FillPatternType enums instead."); - } - System.out.println("FillPatternType short usage"); - short code = ((Short) value).shortValue(); - pattern = FillPatternType.forInt(code); - } - else if (value == null) { - pattern = FillPatternType.NO_FILL; - } - else { - throw new RuntimeException("Unexpected fill pattern style class. Must be FillPatternType or Short (deprecated)."); - } - return pattern; - } - - /** - * Utility method that returns the named HorizontalAlignment value form the given map. - * - * @param properties map of named properties (String -> Object) - * @param name property name - * @return HorizontalAlignment style if set, otherwise {@link HorizontalAlignment#GENERAL} - * @since POI 3.15 beta 3 - */ - private static HorizontalAlignment getHorizontalAlignment(Map properties, String name) { - Object value = properties.get(name); - HorizontalAlignment align; - if (value instanceof HorizontalAlignment) { - align = (HorizontalAlignment) value; - } - // @deprecated 3.15 beta 2. getHorizontalAlignment will only work on HorizontalAlignment enums instead of codes in the future. - else if (value instanceof Short) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Deprecation warning: CellUtil properties map used a Short value for " - + name + ". Should use HorizontalAlignment enums instead."); - } - System.out.println("HorizontalAlignment short usage"); - short code = ((Short) value).shortValue(); - align = HorizontalAlignment.forInt(code); - } - else if (value == null) { - align = HorizontalAlignment.GENERAL; - } - else { - throw new RuntimeException("Unexpected horizontal alignment style class. Must be HorizontalAlignment or Short (deprecated)."); - } - return align; - } - - /** - * Utility method that returns the named VerticalAlignment value form the given map. - * - * @param properties map of named properties (String -> Object) - * @param name property name - * @return VerticalAlignment style if set, otherwise {@link VerticalAlignment#BOTTOM} - * @since POI 3.15 beta 3 - */ - private static VerticalAlignment getVerticalAlignment(Map properties, String name) { - Object value = properties.get(name); - VerticalAlignment align; - if (value instanceof VerticalAlignment) { - align = (VerticalAlignment) value; - } - // @deprecated 3.15 beta 2. getVerticalAlignment will only work on VerticalAlignment enums instead of codes in the future. - else if (value instanceof Short) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Deprecation warning: CellUtil properties map used a Short value for " - + name + ". Should use VerticalAlignment enums instead."); - } - System.out.println("VerticalAlignment usage " + name + " " + value); - short code = ((Short) value).shortValue(); - align = VerticalAlignment.forInt(code); - } - else if (value == null) { - align = VerticalAlignment.BOTTOM; - } - else { - throw new RuntimeException("Unexpected vertical alignment style class. Must be VerticalAlignment or Short (deprecated)."); - } - return align; - } - - /** - * Utility method that returns the named boolean value form the given map. - * - * @param properties map of properties (String -> Object) - * @param name property name - * @return false if the property does not exist, or is not a {@link Boolean}, - * true otherwise - */ - private static boolean getBoolean(Map properties, String name) { - Object value = properties.get(name); - //noinspection SimplifiableIfStatement - if (value instanceof Boolean) { - return ((Boolean) value).booleanValue(); - } - return false; - } - - /** - * Utility method that puts the given value to the given map. - * - * @param properties map of properties (String -> Object) - * @param name property name - * @param value property value - */ - private static void put(Map properties, String name, Object value) { - properties.put(name, value); - } - - /** - * Utility method that puts the named short value to the given map. - * - * @param properties map of properties (String -> Object) - * @param name property name - * @param value property value - */ - private static void putShort(Map properties, String name, short value) { - properties.put(name, value); - } - - /** - * Utility method that puts the named BorderStyle, HorizontalAlignment, VerticalAlignment, etc - * value to the given map. - * - * @param properties map of properties (String -> Object) - * @param name property name - * @param value property value - */ - private static void putEnum(Map properties, String name, Enum value) { - properties.put(name, value); - } - - /** - * Utility method that puts the named boolean value to the given map. - * - * @param properties map of properties (String -> Object) - * @param name property name - * @param value property value - */ - private static void putBoolean(Map properties, String name, boolean value) { - properties.put(name, value); - } - - /** - * Looks for text in the cell that should be unicode, like α and provides the - * unicode version of it. - * - *@param cell The cell to check for unicode values - *@return translated to unicode - */ - public static Cell translateUnicodeValues(Cell cell) { - - String s = cell.getRichStringCellValue().getString(); - boolean foundUnicode = false; - String lowerCaseStr = s.toLowerCase(Locale.ROOT); - - for (UnicodeMapping entry : unicodeMappings) { - String key = entry.entityName; - if (lowerCaseStr.contains(key)) { - s = s.replaceAll(key, entry.resolvedValue); - foundUnicode = true; - } - } - if (foundUnicode) { - cell.setCellValue(cell.getRow().getSheet().getWorkbook().getCreationHelper() - .createRichTextString(s)); - } - return cell; - } - - static { - unicodeMappings = new UnicodeMapping[] { - um("alpha", "\u03B1" ), - um("beta", "\u03B2" ), - um("gamma", "\u03B3" ), - um("delta", "\u03B4" ), - um("epsilon", "\u03B5" ), - um("zeta", "\u03B6" ), - um("eta", "\u03B7" ), - um("theta", "\u03B8" ), - um("iota", "\u03B9" ), - um("kappa", "\u03BA" ), - um("lambda", "\u03BB" ), - um("mu", "\u03BC" ), - um("nu", "\u03BD" ), - um("xi", "\u03BE" ), - um("omicron", "\u03BF" ), - }; - } - - private static UnicodeMapping um(String entityName, String resolvedValue) { - return new UnicodeMapping(entityName, resolvedValue); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/DateFormatConverter.java b/trunk/src/java/org/apache/poi/ss/util/DateFormatConverter.java deleted file mode 100644 index 6339a6ea7..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/DateFormatConverter.java +++ /dev/null @@ -1,433 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.util; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Convert java DateFormat patterns into Excel custom number formats. - * For example, to format a date in excel using the "dd MMMM, yyyy" pattern and Japanese - * locale, use the following code: - * - *
        
        - *      // returns "[$-0411]dd MMMM, yyyy;@" where the [$-0411] prefix tells Excel to use the Japanese locale
        - *      String excelFormatPattern = DateFormatConverter.convert(Locale.JAPANESE, "dd MMMM, yyyy");
        - *
        - *      CellStyle cellStyle = workbook.createCellStyle();
        - *
        - *      DataFormat poiFormat = workbook.createDataFormat();
        - *      cellStyle.setDataFormat(poiFormat.getFormat(excelFormatPattern));
        - *      cell.setCellValue(new Date());
        - *      cell.setCellStyle(cellStyle);  // formats date as '2012\u5e743\u670817\u65e5'
        - *  
        - * - * TODO Generalise this for all Excel format strings - */ -public class DateFormatConverter { - private static POILogger logger = POILogFactory.getLogger(DateFormatConverter.class); - - public static class DateFormatTokenizer { - String format; - int pos; - - public DateFormatTokenizer(String format) { - this.format = format; - } - - public String getNextToken() { - if( pos >= format.length() ) { - return null; - } - int subStart = pos; - char curChar = format.charAt(pos); - ++pos; - if( curChar == '\'' ) { - while( ( pos < format.length() ) && ( ( curChar = format.charAt(pos) ) != '\'' ) ) { - ++pos; - } - if( pos < format.length() ) { - ++pos; - } - } else { - char activeChar = curChar; - while( ( pos < format.length() ) && ( ( curChar = format.charAt(pos) ) == activeChar ) ) { - ++pos; - } - } - return format.substring(subStart,pos); - } - - public static String[] tokenize( String format ) { - List result = new ArrayList(); - - DateFormatTokenizer tokenizer = new DateFormatTokenizer(format); - String token; - while( ( token = tokenizer.getNextToken() ) != null ) { - result.add(token); - } - - return result.toArray(new String[0]); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - - DateFormatTokenizer tokenizer = new DateFormatTokenizer(format); - String token; - while( ( token = tokenizer.getNextToken() ) != null ) { - if( result.length() > 0 ) { - result.append( ", " ); - } - result.append("[").append(token).append("]"); - } - - return result.toString(); - } - } - - private static Map tokenConversions = prepareTokenConversions(); - private static Map localePrefixes = prepareLocalePrefixes(); - - private static Map prepareTokenConversions() { - Map result = new HashMap(); - - result.put( "EEEE", "dddd" ); - result.put( "EEE", "ddd" ); - result.put( "EE", "ddd" ); - result.put( "E", "d" ); - result.put( "Z", "" ); - result.put( "z", "" ); - result.put( "a", "am/pm" ); - result.put( "A", "AM/PM" ); - result.put( "K", "H" ); - result.put( "KK", "HH" ); - result.put( "k", "h" ); - result.put( "kk", "hh" ); - result.put( "S", "0" ); - result.put( "SS", "00" ); - result.put( "SSS", "000" ); - - return result; - } - - private static Map prepareLocalePrefixes() { - Map result = new HashMap(); - - result.put( "af", "[$-0436]" ); - result.put( "am", "[$-45E]" ); - result.put( "ar_ae", "[$-3801]" ); - result.put( "ar_bh", "[$-3C01]" ); - result.put( "ar_dz", "[$-1401]" ); - result.put( "ar_eg", "[$-C01]" ); - result.put( "ar_iq", "[$-0801]" ); - result.put( "ar_jo", "[$-2C01]" ); - result.put( "ar_kw", "[$-3401]" ); - result.put( "ar_lb", "[$-3001]" ); - result.put( "ar_ly", "[$-1001]" ); - result.put( "ar_ma", "[$-1801]" ); - result.put( "ar_om", "[$-2001]" ); - result.put( "ar_qa", "[$-4001]" ); - result.put( "ar_sa", "[$-0401]" ); - result.put( "ar_sy", "[$-2801]" ); - result.put( "ar_tn", "[$-1C01]" ); - result.put( "ar_ye", "[$-2401]" ); - result.put( "as", "[$-44D]" ); - result.put( "az_az", "[$-82C]" ); - result.put( "az_az", "[$-42C]" ); - result.put( "be", "[$-0423]" ); - result.put( "bg", "[$-0402]" ); - result.put( "bn", "[$-0845]" ); - result.put( "bn", "[$-0445]" ); - result.put( "bo", "[$-0451]" ); - result.put( "bs", "[$-141A]" ); - result.put( "ca", "[$-0403]" ); - result.put( "cs", "[$-0405]" ); - result.put( "cy", "[$-0452]" ); - result.put( "da", "[$-0406]" ); - result.put( "de_at", "[$-C07]" ); - result.put( "de_ch", "[$-0807]" ); - result.put( "de_de", "[$-0407]" ); - result.put( "de_li", "[$-1407]" ); - result.put( "de_lu", "[$-1007]" ); - result.put( "dv", "[$-0465]" ); - result.put( "el", "[$-0408]" ); - result.put( "en_au", "[$-C09]" ); - result.put( "en_bz", "[$-2809]" ); - result.put( "en_ca", "[$-1009]" ); - result.put( "en_cb", "[$-2409]" ); - result.put( "en_gb", "[$-0809]" ); - result.put( "en_ie", "[$-1809]" ); - result.put( "en_in", "[$-4009]" ); - result.put( "en_jm", "[$-2009]" ); - result.put( "en_nz", "[$-1409]" ); - result.put( "en_ph", "[$-3409]" ); - result.put( "en_tt", "[$-2C09]" ); - result.put( "en_us", "[$-0409]" ); - result.put( "en_za", "[$-1C09]" ); - result.put( "es_ar", "[$-2C0A]" ); - result.put( "es_bo", "[$-400A]" ); - result.put( "es_cl", "[$-340A]" ); - result.put( "es_co", "[$-240A]" ); - result.put( "es_cr", "[$-140A]" ); - result.put( "es_do", "[$-1C0A]" ); - result.put( "es_ec", "[$-300A]" ); - result.put( "es_es", "[$-40A]" ); - result.put( "es_gt", "[$-100A]" ); - result.put( "es_hn", "[$-480A]" ); - result.put( "es_mx", "[$-80A]" ); - result.put( "es_ni", "[$-4C0A]" ); - result.put( "es_pa", "[$-180A]" ); - result.put( "es_pe", "[$-280A]" ); - result.put( "es_pr", "[$-500A]" ); - result.put( "es_py", "[$-3C0A]" ); - result.put( "es_sv", "[$-440A]" ); - result.put( "es_uy", "[$-380A]" ); - result.put( "es_ve", "[$-200A]" ); - result.put( "et", "[$-0425]" ); - result.put( "eu", "[$-42D]" ); - result.put( "fa", "[$-0429]" ); - result.put( "fi", "[$-40B]" ); - result.put( "fo", "[$-0438]" ); - result.put( "fr_be", "[$-80C]" ); - result.put( "fr_ca", "[$-C0C]" ); - result.put( "fr_ch", "[$-100C]" ); - result.put( "fr_fr", "[$-40C]" ); - result.put( "fr_lu", "[$-140C]" ); - result.put( "gd", "[$-43C]" ); - result.put( "gd_ie", "[$-83C]" ); - result.put( "gn", "[$-0474]" ); - result.put( "gu", "[$-0447]" ); - result.put( "he", "[$-40D]" ); - result.put( "hi", "[$-0439]" ); - result.put( "hr", "[$-41A]" ); - result.put( "hu", "[$-40E]" ); - result.put( "hy", "[$-42B]" ); - result.put( "id", "[$-0421]" ); - result.put( "is", "[$-40F]" ); - result.put( "it_ch", "[$-0810]" ); - result.put( "it_it", "[$-0410]" ); - result.put( "ja", "[$-0411]" ); - result.put( "kk", "[$-43F]" ); - result.put( "km", "[$-0453]" ); - result.put( "kn", "[$-44B]" ); - result.put( "ko", "[$-0412]" ); - result.put( "ks", "[$-0460]" ); - result.put( "la", "[$-0476]" ); - result.put( "lo", "[$-0454]" ); - result.put( "lt", "[$-0427]" ); - result.put( "lv", "[$-0426]" ); - result.put( "mi", "[$-0481]" ); - result.put( "mk", "[$-42F]" ); - result.put( "ml", "[$-44C]" ); - result.put( "mn", "[$-0850]" ); - result.put( "mn", "[$-0450]" ); - result.put( "mr", "[$-44E]" ); - result.put( "ms_bn", "[$-83E]" ); - result.put( "ms_my", "[$-43E]" ); - result.put( "mt", "[$-43A]" ); - result.put( "my", "[$-0455]" ); - result.put( "ne", "[$-0461]" ); - result.put( "nl_be", "[$-0813]" ); - result.put( "nl_nl", "[$-0413]" ); - result.put( "no_no", "[$-0814]" ); - result.put( "or", "[$-0448]" ); - result.put( "pa", "[$-0446]" ); - result.put( "pl", "[$-0415]" ); - result.put( "pt_br", "[$-0416]" ); - result.put( "pt_pt", "[$-0816]" ); - result.put( "rm", "[$-0417]" ); - result.put( "ro", "[$-0418]" ); - result.put( "ro_mo", "[$-0818]" ); - result.put( "ru", "[$-0419]" ); - result.put( "ru_mo", "[$-0819]" ); - result.put( "sa", "[$-44F]" ); - result.put( "sb", "[$-42E]" ); - result.put( "sd", "[$-0459]" ); - result.put( "si", "[$-45B]" ); - result.put( "sk", "[$-41B]" ); - result.put( "sl", "[$-0424]" ); - result.put( "so", "[$-0477]" ); - result.put( "sq", "[$-41C]" ); - result.put( "sr_sp", "[$-C1A]" ); - result.put( "sr_sp", "[$-81A]" ); - result.put( "sv_fi", "[$-81D]" ); - result.put( "sv_se", "[$-41D]" ); - result.put( "sw", "[$-0441]" ); - result.put( "ta", "[$-0449]" ); - result.put( "te", "[$-44A]" ); - result.put( "tg", "[$-0428]" ); - result.put( "th", "[$-41E]" ); - result.put( "tk", "[$-0442]" ); - result.put( "tn", "[$-0432]" ); - result.put( "tr", "[$-41F]" ); - result.put( "ts", "[$-0431]" ); - result.put( "tt", "[$-0444]" ); - result.put( "uk", "[$-0422]" ); - result.put( "ur", "[$-0420]" ); - result.put( "UTF_8", "[$-0000]" ); - result.put( "uz_uz", "[$-0843]" ); - result.put( "uz_uz", "[$-0443]" ); - result.put( "vi", "[$-42A]" ); - result.put( "xh", "[$-0434]" ); - result.put( "yi", "[$-43D]" ); - result.put( "zh_cn", "[$-0804]" ); - result.put( "zh_hk", "[$-C04]" ); - result.put( "zh_mo", "[$-1404]" ); - result.put( "zh_sg", "[$-1004]" ); - result.put( "zh_tw", "[$-0404]" ); - result.put( "zu", "[$-0435]" ); - - result.put( "ar", "[$-0401]" ); - result.put( "bn", "[$-0845]" ); - result.put( "de", "[$-0407]" ); - result.put( "en", "[$-0409]" ); - result.put( "es", "[$-40A]" ); - result.put( "fr", "[$-40C]" ); - result.put( "it", "[$-0410]" ); - result.put( "ms", "[$-43E]" ); - result.put( "nl", "[$-0413]" ); - result.put( "nn", "[$-0814]" ); - result.put( "no", "[$-0414]" ); - result.put( "pt", "[$-0816]" ); - result.put( "sr", "[$-C1A]" ); - result.put( "sv", "[$-41D]" ); - result.put( "uz", "[$-0843]" ); - result.put( "zh", "[$-0804]" ); - - result.put( "ga", "[$-43C]" ); - result.put( "ga_ie", "[$-83C]" ); - result.put( "in", "[$-0421]" ); - result.put( "iw", "[$-40D]" ); - - // JDK 8 adds an empty locale-string, see also https://issues.apache.org/jira/browse/LANG-941 - result.put( "", "[$-0409]" ); - - return result; - } - - public static String getPrefixForLocale( Locale locale ) { - String localeString = locale.toString().toLowerCase(locale); - String result = localePrefixes.get( localeString ); - if( result == null ) { - result = localePrefixes.get( localeString.substring( 0, 2 ) ); - if( result == null ) { - Locale parentLocale = new Locale(localeString.substring( 0, 2 )); - logger.log( POILogger.ERROR, "Unable to find prefix for " + locale + "(" + locale.getDisplayName(Locale.ROOT) + ") or " - + localeString.substring( 0, 2 ) + "(" + parentLocale.getDisplayName(Locale.ROOT) + ")" ); - return ""; - } - } - return result; - } - - public static String convert( Locale locale, DateFormat df ) { - String ptrn = ((SimpleDateFormat)df).toPattern(); - return convert(locale, ptrn); - } - - public static String convert( Locale locale, String format ) { - StringBuilder result = new StringBuilder(); - - result.append(getPrefixForLocale(locale)); - DateFormatTokenizer tokenizer = new DateFormatTokenizer(format); - String token; - while( ( token = tokenizer.getNextToken() ) != null ) { - if( token.startsWith("'") ) { - result.append( token.replaceAll("'", "\"") ); - } else if( ! Character.isLetter( token.charAt( 0 ) ) ) { - result.append( token ); - } else { - // It's a code, translate it if necessary - String mappedToken = tokenConversions.get(token); - result.append( mappedToken == null ? token : mappedToken ); - } - } - result.append(";@"); - return result.toString().trim(); - } - - public static String getJavaDatePattern(int style, Locale locale) { - DateFormat df = DateFormat.getDateInstance(style, locale); - if( df instanceof SimpleDateFormat ) { - return ((SimpleDateFormat)df).toPattern(); - } else { - switch( style ) { - case DateFormat.SHORT: - return "d/MM/yy"; - case DateFormat.MEDIUM: - return "MMM d, yyyy"; - case DateFormat.LONG: - return "MMMM d, yyyy"; - case DateFormat.FULL: - return "dddd, MMMM d, yyyy"; - default: - return "MMM d, yyyy"; - } - } - } - - public static String getJavaTimePattern(int style, Locale locale) { - DateFormat df = DateFormat.getTimeInstance(style, locale); - if( df instanceof SimpleDateFormat ) { - return ((SimpleDateFormat)df).toPattern(); - } else { - switch( style ) { - case DateFormat.SHORT: - return "h:mm a"; - case DateFormat.MEDIUM: - return "h:mm:ss a"; - case DateFormat.LONG: - return "h:mm:ss a"; - case DateFormat.FULL: - return "h:mm:ss a"; - default: - return "h:mm:ss a"; - } - } - } - - public static String getJavaDateTimePattern(int style, Locale locale) { - DateFormat df = DateFormat.getDateTimeInstance(style, style, locale); - if( df instanceof SimpleDateFormat ) { - return ((SimpleDateFormat)df).toPattern(); - } else { - switch( style ) { - case DateFormat.SHORT: - return "M/d/yy h:mm a"; - case DateFormat.MEDIUM: - return "MMM d, yyyy h:mm:ss a"; - case DateFormat.LONG: - return "MMMM d, yyyy h:mm:ss a"; - case DateFormat.FULL: - return "dddd, MMMM d, yyyy h:mm:ss a"; - default: - return "MMM d, yyyy h:mm:ss a"; - } - } - } - -} diff --git a/trunk/src/java/org/apache/poi/ss/util/ExpandedDouble.java b/trunk/src/java/org/apache/poi/ss/util/ExpandedDouble.java deleted file mode 100644 index 41827df04..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/ExpandedDouble.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.math.BigInteger; -import static org.apache.poi.ss.util.IEEEDouble.*; - -/** - * Represents a 64 bit IEEE double quantity expressed with both decimal and binary exponents - * Does not handle negative numbers or zero - *

        - * The value of a {@link ExpandedDouble} is given by
        - * a × 2b - *
        - * where:
        - * - * a = significand
        - * b = binaryExponent - bitLength(significand) + 1
        - * - * @author Josh Micich - */ -final class ExpandedDouble { - private static final BigInteger BI_FRAC_MASK = BigInteger.valueOf(FRAC_MASK); - private static final BigInteger BI_IMPLIED_FRAC_MSB = BigInteger.valueOf(FRAC_ASSUMED_HIGH_BIT); - - private static BigInteger getFrac(long rawBits) { - return BigInteger.valueOf(rawBits).and(BI_FRAC_MASK).or(BI_IMPLIED_FRAC_MSB).shiftLeft(11); - } - - - public static ExpandedDouble fromRawBitsAndExponent(long rawBits, int exp) { - return new ExpandedDouble(getFrac(rawBits), exp); - } - - /** - * Always 64 bits long (MSB, bit-63 is '1') - */ - private final BigInteger _significand; - private final int _binaryExponent; - - public ExpandedDouble(long rawBits) { - int biasedExp = (int) (rawBits >> 52); - if (biasedExp == 0) { - // sub-normal numbers - BigInteger frac = BigInteger.valueOf(rawBits).and(BI_FRAC_MASK); - int expAdj = 64 - frac.bitLength(); - _significand = frac.shiftLeft(expAdj); - _binaryExponent = (biasedExp & 0x07FF) - 1023 - expAdj; - } else { - BigInteger frac = getFrac(rawBits); - _significand = frac; - _binaryExponent = (biasedExp & 0x07FF) - 1023; - } - } - - ExpandedDouble(BigInteger frac, int binaryExp) { - if (frac.bitLength() != 64) { - throw new IllegalArgumentException("bad bit length"); - } - _significand = frac; - _binaryExponent = binaryExp; - } - - - /** - * Convert to an equivalent {@link NormalisedDecimal} representation having 15 decimal digits of precision in the - * non-fractional bits of the significand. - */ - public NormalisedDecimal normaliseBaseTen() { - return NormalisedDecimal.create(_significand, _binaryExponent); - } - - /** - * @return the number of non-fractional bits after the MSB of the significand - */ - public int getBinaryExponent() { - return _binaryExponent; - } - - public BigInteger getSignificand() { - return _significand; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/IEEEDouble.java b/trunk/src/java/org/apache/poi/ss/util/IEEEDouble.java deleted file mode 100644 index f5a42edca..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/IEEEDouble.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - - -/** - * For working with the internals of IEEE 754-2008 'binary64' (double precision) floating point numbers - * - * @author Josh Micich - */ -final class IEEEDouble { - private static final long EXPONENT_MASK = 0x7FF0000000000000L; - private static final int EXPONENT_SHIFT = 52; - public static final long FRAC_MASK = 0x000FFFFFFFFFFFFFL; - public static final int EXPONENT_BIAS = 1023; - public static final long FRAC_ASSUMED_HIGH_BIT = ( 1L<NaN and Infinity values - */ - public static final int BIASED_EXPONENT_SPECIAL_VALUE = 0x07FF; - - /** - * @param rawBits the 64 bit binary representation of the double value - * @return the top 12 bits (sign and biased exponent value) - */ - public static int getBiasedExponent(long rawBits) { - return (int) ((rawBits & EXPONENT_MASK) >> EXPONENT_SHIFT); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/ImageUtils.java b/trunk/src/java/org/apache/poi/ss/util/ImageUtils.java deleted file mode 100644 index 991a2efab..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/ImageUtils.java +++ /dev/null @@ -1,285 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.util; - -import static org.apache.poi.util.Units.EMU_PER_PIXEL; - -import java.awt.Dimension; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; - -import org.apache.poi.hssf.usermodel.HSSFClientAnchor; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Picture; -import org.apache.poi.ss.usermodel.PictureData; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * @author Yegor Kozlov - */ -public class ImageUtils { - private static final POILogger logger = POILogFactory.getLogger(ImageUtils.class); - - public static final int PIXEL_DPI = 96; - - /** - * Return the dimension of this image - * - * @param is the stream containing the image data - * @param type type of the picture: {@link org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_JPEG}, - * {@link org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_PNG} or {@link org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_DIB} - * - * @return image dimension in pixels - */ - public static Dimension getImageDimension(InputStream is, 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( is ); - try { - Iterator i = ImageIO.getImageReaders( iis ); - ImageReader r = i.next(); - try { - 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]; - } finally { - r.dispose(); - } - } finally { - iis.close(); - } - - } 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 25.4/HorizontalPixelSize - * and 25.4/VerticalPixelSize. Where 25.4 is the number of mm in inch. - * - * @return array of two elements: {horisontalPdi, verticalDpi}. - * {96, 96} is the default. - */ - public static int[] getResolution(ImageReader r) throws IOException { - int hdpi=96, vdpi=96; - 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}; - } - - /** - * Calculate and set the preferred size (anchor) for this picture. - * - * @param scaleX the amount by which image width is multiplied relative to the original width. - * @param scaleY the amount by which image height is multiplied relative to the original height. - * @return the new Dimensions of the scaled picture in EMUs - */ - public static Dimension setPreferredSize(Picture picture, double scaleX, double scaleY){ - ClientAnchor anchor = picture.getClientAnchor(); - boolean isHSSF = (anchor instanceof HSSFClientAnchor); - PictureData data = picture.getPictureData(); - Sheet sheet = picture.getSheet(); - - // in pixel - Dimension imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType()); - // in emus - Dimension anchorSize = ImageUtils.getDimensionFromAnchor(picture); - final double scaledWidth = (scaleX == Double.MAX_VALUE) - ? imgSize.getWidth() : anchorSize.getWidth()/EMU_PER_PIXEL * scaleX; - final double scaledHeight = (scaleY == Double.MAX_VALUE) - ? imgSize.getHeight() : anchorSize.getHeight()/EMU_PER_PIXEL * scaleY; - - double w = 0; - int col2 = anchor.getCol1(); - int dx2 = 0; - - //space in the leftmost cell - w = sheet.getColumnWidthInPixels(col2++); - if (isHSSF) { - w *= 1d - anchor.getDx1()/1024d; - } else { - w -= anchor.getDx1()/(double)EMU_PER_PIXEL; - } - - while(w < scaledWidth){ - w += sheet.getColumnWidthInPixels(col2++); - } - - if(w > scaledWidth) { - //calculate dx2, offset in the rightmost cell - double cw = sheet.getColumnWidthInPixels(--col2); - double delta = w - scaledWidth; - if (isHSSF) { - dx2 = (int)((cw-delta)/cw*1024); - } else { - dx2 = (int)((cw-delta)*EMU_PER_PIXEL); - } - if (dx2 < 0) dx2 = 0; - } - anchor.setCol2(col2); - anchor.setDx2(dx2); - - double h = 0; - int row2 = anchor.getRow1(); - int dy2 = 0; - - h = getRowHeightInPixels(sheet,row2++); - if (isHSSF) { - h *= 1 - anchor.getDy1()/256d; - } else { - h -= anchor.getDy1()/(double)EMU_PER_PIXEL; - } - - while(h < scaledHeight){ - h += getRowHeightInPixels(sheet,row2++); - } - - if(h > scaledHeight) { - double ch = getRowHeightInPixels(sheet,--row2); - double delta = h - scaledHeight; - if (isHSSF) { - dy2 = (int)((ch-delta)/ch*256); - } else { - dy2 = (int)((ch-delta)*EMU_PER_PIXEL); - } - if (dy2 < 0) dy2 = 0; - } - - anchor.setRow2(row2); - anchor.setDy2(dy2); - - Dimension dim = new Dimension( - (int)Math.round(scaledWidth*EMU_PER_PIXEL), - (int)Math.round(scaledHeight*EMU_PER_PIXEL) - ); - - return dim; - } - - /** - * Calculates the dimensions in EMUs for the anchor of the given picture - * - * @param picture the picture containing the anchor - * @return the dimensions in EMUs - */ - public static Dimension getDimensionFromAnchor(Picture picture) { - ClientAnchor anchor = picture.getClientAnchor(); - boolean isHSSF = (anchor instanceof HSSFClientAnchor); - Sheet sheet = picture.getSheet(); - - double w = 0; - int col2 = anchor.getCol1(); - - //space in the leftmost cell - w = sheet.getColumnWidthInPixels(col2++); - if (isHSSF) { - w *= 1 - anchor.getDx1()/1024d; - } else { - w -= anchor.getDx1()/(double)EMU_PER_PIXEL; - } - - while(col2 < anchor.getCol2()){ - w += sheet.getColumnWidthInPixels(col2++); - } - - if (isHSSF) { - w += sheet.getColumnWidthInPixels(col2) * anchor.getDx2()/1024d; - } else { - w += anchor.getDx2()/(double)EMU_PER_PIXEL; - } - - double h = 0; - int row2 = anchor.getRow1(); - - h = getRowHeightInPixels(sheet,row2++); - if (isHSSF) { - h *= 1 - anchor.getDy1()/256d; - } else { - h -= anchor.getDy1()/(double)EMU_PER_PIXEL; - } - - while(row2 < anchor.getRow2()){ - h += getRowHeightInPixels(sheet,row2++); - } - - if (isHSSF) { - h += getRowHeightInPixels(sheet,row2) * anchor.getDy2()/256; - } else { - h += anchor.getDy2()/(double)EMU_PER_PIXEL; - } - - w *= EMU_PER_PIXEL; - h *= EMU_PER_PIXEL; - - return new Dimension((int)Math.rint(w), (int)Math.rint(h)); - } - - - private static double getRowHeightInPixels(Sheet sheet, int rowNum) { - Row r = sheet.getRow(rowNum); - double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints(); - return Units.toEMU(points)/(double)EMU_PER_PIXEL; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/MutableFPNumber.java b/trunk/src/java/org/apache/poi/ss/util/MutableFPNumber.java deleted file mode 100644 index 50d872f67..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/MutableFPNumber.java +++ /dev/null @@ -1,201 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.math.BigInteger; - -final class MutableFPNumber { - - - // TODO - what about values between (1014-0.5) and (1014-0.05) ? - /** - * The minimum value in 'Base-10 normalised form'.
        - * When {@link #_binaryExponent} == 46 this is the the minimum {@link #_frac} value - * (1014-0.05) * 2^17 - *
        - * Values between (1014-0.05) and 1014 will be represented as '1' - * followed by 14 zeros. - * Values less than (1014-0.05) will get shifted by one more power of 10 - * - * This frac value rounds to '1' followed by fourteen zeros with an incremented decimal exponent - */ - private static final BigInteger BI_MIN_BASE = new BigInteger("0B5E620F47FFFE666", 16); - /** - * For 'Base-10 normalised form'
        - * The maximum {@link #_frac} value when {@link #_binaryExponent} == 49 - * (10^15-0.5) * 2^14 - */ - private static final BigInteger BI_MAX_BASE = new BigInteger("0E35FA9319FFFE000", 16); - - /** - * Width of a long - */ - private static final int C_64 = 64; - - /** - * Minimum precision after discarding whole 32-bit words from the significand - */ - private static final int MIN_PRECISION = 72; - private BigInteger _significand; - private int _binaryExponent; - public MutableFPNumber(BigInteger frac, int binaryExponent) { - _significand = frac; - _binaryExponent = binaryExponent; - } - - - public MutableFPNumber copy() { - return new MutableFPNumber(_significand, _binaryExponent); - } - public void normalise64bit() { - int oldBitLen = _significand.bitLength(); - int sc = oldBitLen - C_64; - if (sc == 0) { - return; - } - if (sc < 0) { - throw new IllegalStateException("Not enough precision"); - } - _binaryExponent += sc; - if (sc > 32) { - int highShift = (sc-1) & 0xFFFFE0; - _significand = _significand.shiftRight(highShift); - sc -= highShift; - oldBitLen -= highShift; - } - if (sc < 1) { - throw new IllegalStateException(); - } - _significand = Rounder.round(_significand, sc); - if (_significand.bitLength() > oldBitLen) { - sc++; - _binaryExponent++; - } - _significand = _significand.shiftRight(sc); - } - public int get64BitNormalisedExponent() { - return _binaryExponent + _significand.bitLength() - C_64; - - } - - public boolean isBelowMaxRep() { - int sc = _significand.bitLength() - C_64; - return _significand.compareTo(BI_MAX_BASE.shiftLeft(sc)) < 0; - } - public boolean isAboveMinRep() { - int sc = _significand.bitLength() - C_64; - return _significand.compareTo(BI_MIN_BASE.shiftLeft(sc)) > 0; - } - public NormalisedDecimal createNormalisedDecimal(int pow10) { - // missingUnderBits is (0..3) - int missingUnderBits = _binaryExponent-39; - int fracPart = (_significand.intValue() << missingUnderBits) & 0xFFFF80; - long wholePart = _significand.shiftRight(C_64-_binaryExponent-1).longValue(); - return new NormalisedDecimal(wholePart, fracPart, pow10); - } - public void multiplyByPowerOfTen(int pow10) { - TenPower tp = TenPower.getInstance(Math.abs(pow10)); - if (pow10 < 0) { - mulShift(tp._divisor, tp._divisorShift); - } else { - mulShift(tp._multiplicand, tp._multiplierShift); - } - } - private void mulShift(BigInteger multiplicand, int multiplierShift) { - _significand = _significand.multiply(multiplicand); - _binaryExponent += multiplierShift; - // check for too much precision - int sc = (_significand.bitLength() - MIN_PRECISION) & 0xFFFFFFE0; - // mask makes multiples of 32 which optimises BigInteger.shiftRight - if (sc > 0) { - // no need to round because we have at least 8 bits of extra precision - _significand = _significand.shiftRight(sc); - _binaryExponent += sc; - } - } - - private static final class Rounder { - private static final BigInteger[] HALF_BITS; - - static { - BigInteger[] bis = new BigInteger[33]; - long acc=1; - for (int i = 1; i < bis.length; i++) { - bis[i] = BigInteger.valueOf(acc); - acc <<=1; - } - HALF_BITS = bis; - } - /** - * @param nBits number of bits to shift right - */ - public static BigInteger round(BigInteger bi, int nBits) { - if (nBits < 1) { - return bi; - } - return bi.add(HALF_BITS[nBits]); - } - } - - /** - * Holds values for quick multiplication and division by 10 - */ - private static final class TenPower { - private static final BigInteger FIVE = new BigInteger("5"); - private static final TenPower[] _cache = new TenPower[350]; - - public final BigInteger _multiplicand; - public final BigInteger _divisor; - public final int _divisorShift; - public final int _multiplierShift; - - private TenPower(int index) { - BigInteger fivePowIndex = FIVE.pow(index); - - int bitsDueToFiveFactors = fivePowIndex.bitLength(); - int px = 80 + bitsDueToFiveFactors; - BigInteger fx = BigInteger.ONE.shiftLeft(px).divide(fivePowIndex); - int adj = fx.bitLength() - 80; - _divisor = fx.shiftRight(adj); - bitsDueToFiveFactors -= adj; - - _divisorShift = -(bitsDueToFiveFactors+index+80); - int sc = fivePowIndex.bitLength() - 68; - if (sc > 0) { - _multiplierShift = index + sc; - _multiplicand = fivePowIndex.shiftRight(sc); - } else { - _multiplierShift = index; - _multiplicand = fivePowIndex; - } - } - - static TenPower getInstance(int index) { - TenPower result = _cache[index]; - if (result == null) { - result = new TenPower(index); - _cache[index] = result; - } - return result; - } - } - - public ExpandedDouble createExpandedDouble() { - return new ExpandedDouble(_significand, _binaryExponent); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/NormalisedDecimal.java b/trunk/src/java/org/apache/poi/ss/util/NormalisedDecimal.java deleted file mode 100644 index 84f4d7285..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/NormalisedDecimal.java +++ /dev/null @@ -1,271 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.math.BigDecimal; -import java.math.BigInteger; - -/** - * Represents a transformation of a 64 bit IEEE double quantity having a decimal exponent and a - * fixed point (15 decimal digit) significand. Some quirks of Excel's calculation behaviour are - * simpler to reproduce with numeric quantities in this format. This class is currently used to - * help: - *

          - *
        1. Comparison operations
        2. - *
        3. Conversions to text
        4. - *
        - * - *

        - * This class does not handle negative numbers or zero. - *

        - * The value of a {@link NormalisedDecimal} is given by
        - * significand × 10decimalExponent - *
        - * where:
        - * - * significand = wholePart + fractionalPart / 224
        - * - * @author Josh Micich - */ -final class NormalisedDecimal { - /** - * Number of powers of ten contained in the significand - */ - private static final int EXPONENT_OFFSET = 14; - - private static final BigDecimal BD_2_POW_24 = new BigDecimal(BigInteger.ONE.shiftLeft(24)); - - /** - * log10(2)×220 - */ - private static final int LOG_BASE_10_OF_2_TIMES_2_POW_20 = 315653; // 315652.8287 - - /** - * 219 - */ - private static final int C_2_POW_19 = 1 << 19; - - - /** - * the value of {@link #_fractionalPart} that represents 0.5 - */ - private static final int FRAC_HALF = 0x800000; - - /** - * 1015 - */ - private static final long MAX_REP_WHOLE_PART = 0x38D7EA4C68000L; - - - - public static NormalisedDecimal create(BigInteger frac, int binaryExponent) { - // estimate pow2&pow10 first, perform optional mulShift, then normalize - int pow10; - if (binaryExponent > 49 || binaryExponent < 46) { - - // working with ints (left shifted 20) instead of doubles - // x = 14.5 - binaryExponent * log10(2); - int x = (29 << 19) - binaryExponent * LOG_BASE_10_OF_2_TIMES_2_POW_20; - x += C_2_POW_19; // round - pow10 = -(x >> 20); - } else { - pow10 = 0; - } - MutableFPNumber cc = new MutableFPNumber(frac, binaryExponent); - if (pow10 != 0) { - cc.multiplyByPowerOfTen(-pow10); - } - - switch (cc.get64BitNormalisedExponent()) { - case 46: - if (cc.isAboveMinRep()) { - break; - } - case 44: - case 45: - cc.multiplyByPowerOfTen(1); - pow10--; - break; - case 47: - case 48: - break; - case 49: - if (cc.isBelowMaxRep()) { - break; - } - case 50: - cc.multiplyByPowerOfTen(-1); - pow10++; - break; - - default: - throw new IllegalStateException("Bad binary exp " + cc.get64BitNormalisedExponent() + "."); - } - cc.normalise64bit(); - - return cc.createNormalisedDecimal(pow10); - } - - /** - * Rounds at the digit with value 10decimalExponent - */ - public NormalisedDecimal roundUnits() { - long wholePart = _wholePart; - if (_fractionalPart >= FRAC_HALF) { - wholePart++; - } - - int de = _relativeDecimalExponent; - - if (wholePart < MAX_REP_WHOLE_PART) { - return new NormalisedDecimal(wholePart, 0, de); - } - return new NormalisedDecimal(wholePart/10, 0, de+1); - } - - /** - * The decimal exponent increased by one less than the digit count of {@link #_wholePart} - */ - private final int _relativeDecimalExponent; - /** - * The whole part of the significand (typically 15 digits). - * - * 47-50 bits long (MSB may be anywhere from bit 46 to 49) - * LSB is units bit. - */ - private final long _wholePart; - /** - * The fractional part of the significand. - * 24 bits (only top 14-17 bits significant): a value between 0x000000 and 0xFFFF80 - */ - private final int _fractionalPart; - - - NormalisedDecimal(long wholePart, int fracPart, int decimalExponent) { - _wholePart = wholePart; - _fractionalPart = fracPart; - _relativeDecimalExponent = decimalExponent; - } - - - /** - * Convert to an equivalent {@link ExpandedDouble} representation (binary frac and exponent). - * The resulting transformed object is easily converted to a 64 bit IEEE double: - *

          - *
        • bits 2-53 of the {@link #getSignificand()} become the 52 bit 'fraction'.
        • - *
        • {@link #getBinaryExponent()} is biased by 1023 to give the 'exponent'.
        • - *
        - * The sign bit must be obtained from somewhere else. - * @return a new {@link NormalisedDecimal} normalised to base 2 representation. - */ - public ExpandedDouble normaliseBaseTwo() { - MutableFPNumber cc = new MutableFPNumber(composeFrac(), 39); - cc.multiplyByPowerOfTen(_relativeDecimalExponent); - cc.normalise64bit(); - return cc.createExpandedDouble(); - } - - /** - * @return the significand as a fixed point number (with 24 fraction bits and 47-50 whole bits) - */ - BigInteger composeFrac() { - long wp = _wholePart; - int fp = _fractionalPart; - return new BigInteger(new byte[] { - (byte) (wp >> 56), // N.B. assuming sign bit is zero - (byte) (wp >> 48), - (byte) (wp >> 40), - (byte) (wp >> 32), - (byte) (wp >> 24), - (byte) (wp >> 16), - (byte) (wp >> 8), - (byte) (wp >> 0), - (byte) (fp >> 16), - (byte) (fp >> 8), - (byte) (fp >> 0), - }); - } - - public String getSignificantDecimalDigits() { - return Long.toString(_wholePart); - } - /** - * Rounds the first whole digit position (considers only units digit, not frational part). - * Caller should check total digit count of result to see whether the rounding operation caused - * a carry out of the most significant digit - */ - public String getSignificantDecimalDigitsLastDigitRounded() { - long wp = _wholePart + 5; // rounds last digit - StringBuilder sb = new StringBuilder(24); - sb.append(wp); - sb.setCharAt(sb.length()-1, '0'); - return sb.toString(); - } - - /** - * @return the number of powers of 10 which have been extracted from the significand and binary exponent. - */ - public int getDecimalExponent() { - return _relativeDecimalExponent+EXPONENT_OFFSET; - } - - /** - * assumes both this and other are normalised - */ - public int compareNormalised(NormalisedDecimal other) { - int cmp = _relativeDecimalExponent - other._relativeDecimalExponent; - if (cmp != 0) { - return cmp; - } - if (_wholePart > other._wholePart) { - return 1; - } - if (_wholePart < other._wholePart) { - return -1; - } - return _fractionalPart - other._fractionalPart; - } - public BigDecimal getFractionalPart() { - return new BigDecimal(_fractionalPart).divide(BD_2_POW_24); - } - - private String getFractionalDigits() { - if (_fractionalPart == 0) { - return "0"; - } - return getFractionalPart().toString().substring(2); - } - - @Override - public String toString() { - - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getName()); - sb.append(" ["); - String ws = String.valueOf(_wholePart); - sb.append(ws.charAt(0)); - sb.append('.'); - sb.append(ws.substring(1)); - sb.append(' '); - sb.append(getFractionalDigits()); - sb.append("E"); - sb.append(getDecimalExponent()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/NumberComparer.java b/trunk/src/java/org/apache/poi/ss/util/NumberComparer.java deleted file mode 100644 index 1d7a8dbe0..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/NumberComparer.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.Locale; - -import static org.apache.poi.ss.util.IEEEDouble.*; - -/** - * Excel compares numbers using different rules to those of java, so - * {@link Double#compare(double, double)} won't do. - * - * - * @author Josh Micich - */ -public final class NumberComparer { - - /** - * This class attempts to reproduce Excel's behaviour for comparing numbers. Results are - * mostly the same as those from {@link Double#compare(double, double)} but with some - * rounding. For numbers that are very close, this code converts to a format having 15 - * decimal digits of precision and a decimal exponent, before completing the comparison. - *

        - * In Excel formula evaluation, expressions like "(0.06-0.01)=0.05" evaluate to "TRUE" even - * though the equivalent java expression is false. In examples like this, - * Excel achieves the effect by having additional logic for comparison operations. - *

        - *

          - *
        • No more than 15 significant figures are output (java does 18).
        • - *
        • The sign char for the exponent is included even if positive
        • - *
        • Special values (NaN and Infinity) get rendered like the ordinary - * number that the bit pattern represents.
        • - *
        • Denormalised values (between ±2-1074 and ±2-1022 - * are displayed as "0" - *
        - * IEEE 64-bit Double Rendering Comparison - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
        Raw bitsJavaExcel
        0x0000000000000000L0.00
        0x3FF0000000000000L1.01
        0x3FF00068DB8BAC71L1.00011.0001
        0x4087A00000000000L756.0756
        0x401E3D70A3D70A3DL7.567.56
        0x405EDD3C07FB4C99L123.45678901234568123.456789012346
        0x4132D687E3DF2180L1234567.89012345671234567.89012346
        0x3EE9E409302678BAL1.2345678901234568E-51.23456789012346E-05
        0x3F202E85BE180B74L1.2345678901234567E-40.000123456789012346
        0x3F543A272D9E0E51L0.00123456789012345670.00123456789012346
        0x3F8948B0F90591E6L0.0123456789012345680.0123456789012346
        0x3EE9E409301B5A02L1.23456789E-50.0000123456789
        0x3E6E7D05BDABDE50L5.6789012345E-80.000000056789012345
        0x3E6E7D05BDAD407EL5.67890123456E-85.67890123456E-08
        0x3E6E7D06029F18BEL5.678902E-80.00000005678902
        0x2BCB5733CB32AE6EL9.999999999999123E-989.99999999999912E-98
        0x2B617F7D4ED8C59EL1.0000000000001235E-991.0000000000001E-99
        0x0036319916D67853L1.2345678901234578E-3071.2345678901235E-307
        0x359DEE7A4AD4B81FL2.0E-502E-50
        0x41678C29DCD6E9E0L1.2345678901234567E712345678.9012346
        0x42A674E79C5FE523L1.2345678901234568E1312345678901234.6
        0x42DC12218377DE6BL1.2345678901234567E14123456789012346
        0x43118B54F22AEB03L1.2345678901234568E151234567890123460
        0x43E56A95319D63E1L1.2345678901234567E1912345678901234600000
        0x441AC53A7E04BCDAL1.2345678901234568E201.23456789012346E+20
        0xC3E56A95319D63E1L-1.2345678901234567E19-12345678901234600000
        0xC41AC53A7E04BCDAL-1.2345678901234568E20-1.23456789012346E+20
        0x54820FE0BA17F46DL1.2345678901234577E991.2345678901235E+99
        0x54B693D8E89DF188L1.2345678901234576E1001.2345678901235E+100
        0x4A611B0EC57E649AL2.0E502E+50
        0x7FEFFFFFFFFFFFFFL1.7976931348623157E3081.7976931348623E+308
        0x0010000000000000L2.2250738585072014E-3082.2250738585072E-308
        0x000FFFFFFFFFFFFFL2.225073858507201E-3080
        0x0000000000000001L4.9E-3240
        0x7FF0000000000000LInfinity1.7976931348623E+308
        0xFFF0000000000000L-Infinity1.7976931348623E+308
        0x441AC7A08EAD02F2L1.234999999999999E201.235E+20
        0x40FE26BFFFFFFFF9L123499.9999999999123500
        0x3E4A857BFB2F2809L1.234999999999999E-80.00000001235
        0x3BCD291DEF868C89L1.234999999999999E-201.235E-20
        0x444B1AE4D6E2EF4FL9.999999999999999E201E+21
        0x412E847FFFFFFFFFL999999.99999999991000000
        0x3E45798EE2308C39L9.999999999999999E-90.00000001
        0x3C32725DD1D243ABL9.999999999999999E-190.000000000000000001
        0x3BFD83C94FB6D2ABL9.999999999999999E-201E-19
        0xC44B1AE4D6E2EF4FL-9.999999999999999E20-1E+21
        0xC12E847FFFFFFFFFL-999999.9999999999-1000000
        0xBE45798EE2308C39L-9.999999999999999E-9-0.00000001
        0xBC32725DD1D243ABL-9.999999999999999E-19-0.000000000000000001
        0xBBFD83C94FB6D2ABL-9.999999999999999E-20-1E-19
        0xFFFF0420003C0000LNaN3.484840871308E+308
        0x7FF8000000000000LNaN2.6965397022935E+308
        0x7FFF0420003C0000LNaN3.484840871308E+308
        0xFFF8000000000000LNaN2.6965397022935E+308
        0xFFFF0AAAAAAAAAAALNaN3.4877119413344E+308
        0x7FF80AAAAAAAAAAALNaN2.7012211948322E+308
        0xFFFFFFFFFFFFFFFFLNaN3.5953862697246E+308
        0x7FFFFFFFFFFFFFFFLNaN3.5953862697246E+308
        0xFFF7FFFFFFFFFFFFLNaN2.6965397022935E+308
        - * - * Note: - * Excel has inconsistent rules for the following numeric operations: - *
          - *
        • Conversion to string (as handled here)
        • - *
        • Rendering numerical quantities in the cell grid.
        • - *
        • Conversion from text
        • - *
        • General arithmetic
        • - *
        - * Excel's text to number conversion is not a true inverse of this operation. The - * allowable ranges are different. Some numbers that don't correctly convert to text actually - * do get handled properly when used in arithmetic evaluations. - * - * @author Josh Micich - */ -public final class NumberToTextConverter { - - private static final long EXCEL_NAN_BITS = 0xFFFF0420003C0000L; - private static final int MAX_TEXT_LEN = 20; - - private NumberToTextConverter() { - // no instances of this class - } - - /** - * Converts the supplied value to the text representation that Excel would give if - * the value were to appear in an unformatted cell, or as a literal number in a formula.
        - * Note - the results from this method differ slightly from those of Double.toString() - * In some special cases Excel behaves quite differently. This function attempts to reproduce - * those results. - */ - public static String toText(double value) { - return rawDoubleBitsToText(Double.doubleToLongBits(value)); - } - /* package */ static String rawDoubleBitsToText(long pRawBits) { - - long rawBits = pRawBits; - boolean isNegative = rawBits < 0; // sign bit is in the same place for long and double - if (isNegative) { - rawBits &= 0x7FFFFFFFFFFFFFFFL; - } - if (rawBits == 0) { - return isNegative ? "-0" : "0"; - } - ExpandedDouble ed = new ExpandedDouble(rawBits); - if (ed.getBinaryExponent() < -1022) { - // value is 'denormalised' which means it is less than 2^-1022 - // excel displays all these numbers as zero, even though calculations work OK - return isNegative ? "-0" : "0"; - } - if (ed.getBinaryExponent() == 1024) { - // Special number NaN /Infinity - // Normally one would not create HybridDecimal objects from these values - // except in these cases Excel really tries to render them as if they were normal numbers - if(rawBits == EXCEL_NAN_BITS) { - return "3.484840871308E+308"; - } - // This is where excel really gets it wrong - // Special numbers like Infinity and NaN are interpreted according to - // the standard rules below. - isNegative = false; // except that the sign bit is ignored - } - NormalisedDecimal nd = ed.normaliseBaseTen(); - StringBuilder sb = new StringBuilder(MAX_TEXT_LEN+1); - if (isNegative) { - sb.append('-'); - } - convertToText(sb, nd); - return sb.toString(); - } - private static void convertToText(StringBuilder sb, NormalisedDecimal pnd) { - NormalisedDecimal rnd = pnd.roundUnits(); - int decExponent = rnd.getDecimalExponent(); - String decimalDigits; - if (Math.abs(decExponent)>98) { - decimalDigits = rnd.getSignificantDecimalDigitsLastDigitRounded(); - if (decimalDigits.length() == 16) { - // rounding caused carry - decExponent++; - } - } else { - decimalDigits = rnd.getSignificantDecimalDigits(); - } - int countSigDigits = countSignifantDigits(decimalDigits); - if (decExponent < 0) { - formatLessThanOne(sb, decimalDigits, decExponent, countSigDigits); - } else { - formatGreaterThanOne(sb, decimalDigits, decExponent, countSigDigits); - } - } - - private static void formatLessThanOne(StringBuilder sb, String decimalDigits, int decExponent, - int countSigDigits) { - int nLeadingZeros = -decExponent - 1; - int normalLength = 2 + nLeadingZeros + countSigDigits; // 2 == "0.".length() - - if (needsScientificNotation(normalLength)) { - sb.append(decimalDigits.charAt(0)); - if (countSigDigits > 1) { - sb.append('.'); - sb.append(decimalDigits.subSequence(1, countSigDigits)); - } - sb.append("E-"); - appendExp(sb, -decExponent); - return; - } - sb.append("0."); - for (int i=nLeadingZeros; i>0; i--) { - sb.append('0'); - } - sb.append(decimalDigits.subSequence(0, countSigDigits)); - } - - private static void formatGreaterThanOne(StringBuilder sb, String decimalDigits, int decExponent, int countSigDigits) { - - if (decExponent > 19) { - // scientific notation - sb.append(decimalDigits.charAt(0)); - if (countSigDigits>1) { - sb.append('.'); - sb.append(decimalDigits.subSequence(1, countSigDigits)); - } - sb.append("E+"); - appendExp(sb, decExponent); - return; - } - int nFractionalDigits = countSigDigits - decExponent-1; - if (nFractionalDigits > 0) { - sb.append(decimalDigits.subSequence(0, decExponent+1)); - sb.append('.'); - sb.append(decimalDigits.subSequence(decExponent+1, countSigDigits)); - return; - } - sb.append(decimalDigits.subSequence(0, countSigDigits)); - for (int i=-nFractionalDigits; i>0; i--) { - sb.append('0'); - } - } - - private static boolean needsScientificNotation(int nDigits) { - return nDigits > MAX_TEXT_LEN; - } - - private static int countSignifantDigits(String sb) { - int result=sb.length()-1; - while(sb.charAt(result) == '0') { - result--; - if(result < 0) { - throw new RuntimeException("No non-zero digits found"); - } - } - return result + 1; - } - - private static void appendExp(StringBuilder sb, int val) { - if(val < 10) { - sb.append('0'); - sb.append((char)('0' + val)); - return; - } - sb.append(val); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/PaneInformation.java b/trunk/src/java/org/apache/poi/ss/util/PaneInformation.java deleted file mode 100644 index dc54b4cf3..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/PaneInformation.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -/** - * Holds information regarding a split plane or freeze plane for a sheet. - * - */ -public class PaneInformation -{ - /** Constant for active pane being the lower right*/ - public static final byte PANE_LOWER_RIGHT = (byte)0; - /** Constant for active pane being the upper right*/ - public static final byte PANE_UPPER_RIGHT = (byte)1; - /** Constant for active pane being the lower left*/ - public static final byte PANE_LOWER_LEFT = (byte)2; - /** Constant for active pane being the upper left*/ - public static final byte PANE_UPPER_LEFT = (byte)3; - - private final short x; - private final short y; - private final short topRow; - private final short leftColumn; - private final byte activePane; - private final boolean frozen; - - public PaneInformation(short x, short y, short top, short left, byte active, boolean frozen) { - this.x = x; - this.y = y; - this.topRow = top; - this.leftColumn = left; - this.activePane = active; - this.frozen = frozen; - } - - - /** - * Returns the vertical position of the split. - * @return 0 if there is no vertical spilt, - * or for a freeze pane the number of columns in the TOP pane, - * or for a split plane the position of the split in 1/20th of a point. - */ - public short getVerticalSplitPosition() { - return x; - } - - /** - * Returns the horizontal position of the split. - * @return 0 if there is no horizontal spilt, - * or for a freeze pane the number of rows in the LEFT pane, - * or for a split plane the position of the split in 1/20th of a point. - */ - public short getHorizontalSplitPosition() { - return y; - } - - /** - * For a horizontal split returns the top row in the BOTTOM pane. - * @return 0 if there is no horizontal split, or the top row of the bottom pane. - */ - public short getHorizontalSplitTopRow() { - return topRow; - } - - /** - * For a vertical split returns the left column in the RIGHT pane. - * @return 0 if there is no vertical split, or the left column in the RIGHT pane. - */ - public short getVerticalSplitLeftColumn() { - return leftColumn; - } - - /** - * Returns the active pane - * @see #PANE_LOWER_RIGHT - * @see #PANE_UPPER_RIGHT - * @see #PANE_LOWER_LEFT - * @see #PANE_UPPER_LEFT - * @return the active pane. - */ - public byte getActivePane() { - return activePane; - } - - /** Returns true if this is a Freeze pane, false if it is a split pane. - */ - public boolean isFreezePane() { - return frozen; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/PropertyTemplate.java b/trunk/src/java/org/apache/poi/ss/util/PropertyTemplate.java deleted file mode 100644 index 1b0e27593..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/PropertyTemplate.java +++ /dev/null @@ -1,966 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.BorderExtent; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; - -/** - *

        - * A {@link PropertyTemplate} is a template that can be applied to any sheet in - * a project. It contains all the border type and color attributes needed to - * draw all the borders for a single sheet. That template can be applied to any - * sheet in any workbook. - * - * This class requires the full spreadsheet to be in memory, so - * {@link org.apache.poi.xssf.streaming.SXSSFWorkbook} Spreadsheets are not - * supported. The same {@link PropertyTemplate} can, however, be applied to both - * {@link HSSFWorkbook} and {@link org.apache.poi.xssf.usermodel.XSSFWorkbook} - * objects if necessary. Portions of the border that fall outside the max range - * of the {@link Workbook} sheet are ignored. - *

        - * - *

        - * This would replace {@link RegionUtil}. - *

        - */ -public final class PropertyTemplate { - - /** - * This is a list of cell properties for one shot application to a range of - * cells at a later time. - */ - private Map> _propertyTemplate; - - /** - * Create a PropertyTemplate object - */ - public PropertyTemplate() { - _propertyTemplate = new HashMap>(); - } - - /** - * Create a PropertyTemplate object from another PropertyTemplate - * - * @param template a PropertyTemplate object - */ - public PropertyTemplate(PropertyTemplate template) { - this(); - for(Map.Entry> entry : template.getTemplate().entrySet()) { - _propertyTemplate.put(new CellAddress(entry.getKey()), cloneCellProperties(entry.getValue())); - } - } - - private Map> getTemplate() { - return _propertyTemplate; - } - - private static Map cloneCellProperties(Map properties) { - Map newProperties = new HashMap(); - for(Map.Entry entry : properties.entrySet()) { - newProperties.put(entry.getKey(), entry.getValue()); - } - return newProperties; - } - - /** - * Draws a group of cell borders for a cell range. The borders are not - * applied to the cells at this time, just the template is drawn. To apply - * the drawn borders to a sheet, use {@link #applyBorders}. - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link BorderExtent} of the borders to be - * applied. - */ - public void drawBorders(CellRangeAddress range, BorderStyle borderType, - BorderExtent extent) { - switch (extent) { - case NONE: - removeBorders(range); - break; - case ALL: - drawHorizontalBorders(range, borderType, BorderExtent.ALL); - drawVerticalBorders(range, borderType, BorderExtent.ALL); - break; - case INSIDE: - drawHorizontalBorders(range, borderType, BorderExtent.INSIDE); - drawVerticalBorders(range, borderType, BorderExtent.INSIDE); - break; - case OUTSIDE: - drawOutsideBorders(range, borderType, BorderExtent.ALL); - break; - case TOP: - drawTopBorder(range, borderType); - break; - case BOTTOM: - drawBottomBorder(range, borderType); - break; - case LEFT: - drawLeftBorder(range, borderType); - break; - case RIGHT: - drawRightBorder(range, borderType); - break; - case HORIZONTAL: - drawHorizontalBorders(range, borderType, BorderExtent.ALL); - break; - case INSIDE_HORIZONTAL: - drawHorizontalBorders(range, borderType, BorderExtent.INSIDE); - break; - case OUTSIDE_HORIZONTAL: - drawOutsideBorders(range, borderType, BorderExtent.HORIZONTAL); - break; - case VERTICAL: - drawVerticalBorders(range, borderType, BorderExtent.ALL); - break; - case INSIDE_VERTICAL: - drawVerticalBorders(range, borderType, BorderExtent.INSIDE); - break; - case OUTSIDE_VERTICAL: - drawOutsideBorders(range, borderType, BorderExtent.VERTICAL); - break; - } - } - - /** - * Draws a group of cell borders for a cell range. The borders are not - * applied to the cells at this time, just the template is drawn. To apply - * the drawn borders to a sheet, use {@link #applyBorders}. - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link BorderExtent} of the borders to be - * applied. - */ - public void drawBorders(CellRangeAddress range, BorderStyle borderType, - short color, BorderExtent extent) { - drawBorders(range, borderType, extent); - if (borderType != BorderStyle.NONE) { - drawBorderColors(range, color, extent); - } - } - - /** - *

        - * Draws the top border for a range of cells - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawTopBorder(CellRangeAddress range, BorderStyle borderType) { - int row = range.getFirstRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - addProperty(row, i, CellUtil.BORDER_TOP, borderType); - if (borderType == BorderStyle.NONE && row > 0) { - addProperty(row - 1, i, CellUtil.BORDER_BOTTOM, borderType); - } - } - } - - /** - *

        - * Draws the bottom border for a range of cells - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawBottomBorder(CellRangeAddress range, - BorderStyle borderType) { - int row = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - addProperty(row, i, CellUtil.BORDER_BOTTOM, borderType); - if (borderType == BorderStyle.NONE - && row < SpreadsheetVersion.EXCEL2007.getMaxRows() - 1) { - addProperty(row + 1, i, CellUtil.BORDER_TOP, borderType); - } - } - } - - /** - *

        - * Draws the left border for a range of cells - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawLeftBorder(CellRangeAddress range, - BorderStyle borderType) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getFirstColumn(); - for (int i = firstRow; i <= lastRow; i++) { - addProperty(i, col, CellUtil.BORDER_LEFT, borderType); - if (borderType == BorderStyle.NONE && col > 0) { - addProperty(i, col - 1, CellUtil.BORDER_RIGHT, borderType); - } - } - } - - /** - *

        - * Draws the right border for a range of cells - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawRightBorder(CellRangeAddress range, - BorderStyle borderType) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - addProperty(i, col, CellUtil.BORDER_RIGHT, borderType); - if (borderType == BorderStyle.NONE - && col < SpreadsheetVersion.EXCEL2007.getMaxColumns() - 1) { - addProperty(i, col + 1, CellUtil.BORDER_LEFT, borderType); - } - } - } - - /** - *

        - * Draws the outside borders for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link BorderExtent} of the borders to be - * applied. Valid Values are: - *
          - *
        • BorderExtent.ALL
        • - *
        • BorderExtent.HORIZONTAL
        • - *
        • BorderExtent.VERTICAL
        • - *
        - */ - private void drawOutsideBorders(CellRangeAddress range, - BorderStyle borderType, BorderExtent extent) { - switch (extent) { - case ALL: - case HORIZONTAL: - case VERTICAL: - if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) { - drawTopBorder(range, borderType); - drawBottomBorder(range, borderType); - } - if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) { - drawLeftBorder(range, borderType); - drawRightBorder(range, borderType); - } - break; - default: - throw new IllegalArgumentException( - "Unsupported PropertyTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL"); - } - } - - /** - *

        - * Draws the horizontal borders for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link BorderExtent} of the borders to be - * applied. Valid Values are: - *
          - *
        • BorderExtent.ALL
        • - *
        • BorderExtent.INSIDE
        • - *
        - */ - private void drawHorizontalBorders(CellRangeAddress range, - BorderStyle borderType, BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - CellRangeAddress row = new CellRangeAddress(i, i, firstCol, - lastCol); - if (extent == BorderExtent.ALL || i > firstRow) { - drawTopBorder(row, borderType); - } - if (extent == BorderExtent.ALL || i < lastRow) { - drawBottomBorder(row, borderType); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - *

        - * Draws the vertical borders for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderType - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link BorderExtent} of the borders to be - * applied. Valid Values are: - *
          - *
        • BorderExtent.ALL
        • - *
        • BorderExtent.INSIDE
        • - *
        - */ - private void drawVerticalBorders(CellRangeAddress range, - BorderStyle borderType, BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - CellRangeAddress row = new CellRangeAddress(firstRow, lastRow, - i, i); - if (extent == BorderExtent.ALL || i > firstCol) { - drawLeftBorder(row, borderType); - } - if (extent == BorderExtent.ALL || i < lastCol) { - drawRightBorder(row, borderType); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - * Removes all border properties from this {@link PropertyTemplate} for the - * specified range. - * - * @parm range - {@link CellRangeAddress} range of cells to remove borders. - */ - private void removeBorders(CellRangeAddress range) { - Set properties = new HashSet(); - properties.add(CellUtil.BORDER_TOP); - properties.add(CellUtil.BORDER_BOTTOM); - properties.add(CellUtil.BORDER_LEFT); - properties.add(CellUtil.BORDER_RIGHT); - for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) { - for (int col = range.getFirstColumn(); col <= range - .getLastColumn(); col++) { - removeProperties(row, col, properties); - } - } - removeBorderColors(range); - } - - /** - * Applies the drawn borders to a Sheet. The borders that are applied are - * the ones that have been drawn by the {@link #drawBorders} and - * {@link #drawBorderColors} methods. - * - * @param sheet - * - {@link Sheet} on which to apply borders - */ - public void applyBorders(Sheet sheet) { - Workbook wb = sheet.getWorkbook(); - for (Map.Entry> entry : _propertyTemplate - .entrySet()) { - CellAddress cellAddress = entry.getKey(); - if (cellAddress.getRow() < wb.getSpreadsheetVersion().getMaxRows() - && cellAddress.getColumn() < wb.getSpreadsheetVersion() - .getMaxColumns()) { - Map properties = entry.getValue(); - Row row = CellUtil.getRow(cellAddress.getRow(), sheet); - Cell cell = CellUtil.getCell(row, cellAddress.getColumn()); - CellUtil.setCellStyleProperties(cell, properties); - } - } - } - - /** - * Sets the color for a group of cell borders for a cell range. The borders - * are not applied to the cells at this time, just the template is drawn. If - * the borders do not exist, a BORDER_THIN border is used. To apply the - * drawn borders to a sheet, use {@link #applyBorders}. - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link BorderExtent} of the borders for which - * colors are set. - */ - public void drawBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case NONE: - removeBorderColors(range); - break; - case ALL: - drawHorizontalBorderColors(range, color, BorderExtent.ALL); - drawVerticalBorderColors(range, color, BorderExtent.ALL); - break; - case INSIDE: - drawHorizontalBorderColors(range, color, BorderExtent.INSIDE); - drawVerticalBorderColors(range, color, BorderExtent.INSIDE); - break; - case OUTSIDE: - drawOutsideBorderColors(range, color, BorderExtent.ALL); - break; - case TOP: - drawTopBorderColor(range, color); - break; - case BOTTOM: - drawBottomBorderColor(range, color); - break; - case LEFT: - drawLeftBorderColor(range, color); - break; - case RIGHT: - drawRightBorderColor(range, color); - break; - case HORIZONTAL: - drawHorizontalBorderColors(range, color, BorderExtent.ALL); - break; - case INSIDE_HORIZONTAL: - drawHorizontalBorderColors(range, color, BorderExtent.INSIDE); - break; - case OUTSIDE_HORIZONTAL: - drawOutsideBorderColors(range, color, BorderExtent.HORIZONTAL); - break; - case VERTICAL: - drawVerticalBorderColors(range, color, BorderExtent.ALL); - break; - case INSIDE_VERTICAL: - drawVerticalBorderColors(range, color, BorderExtent.INSIDE); - break; - case OUTSIDE_VERTICAL: - drawOutsideBorderColors(range, color, BorderExtent.VERTICAL); - break; - } - } - - /** - *

        - * Sets the color of the top border for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawTopBorderColor(CellRangeAddress range, short color) { - int row = range.getFirstRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - if (getBorderStyle(row, i, - CellUtil.BORDER_TOP) == BorderStyle.NONE) { - drawTopBorder(new CellRangeAddress(row, row, i, i), - BorderStyle.THIN); - } - addProperty(row, i, CellUtil.TOP_BORDER_COLOR, color); - } - } - - /** - *

        - * Sets the color of the bottom border for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawBottomBorderColor(CellRangeAddress range, short color) { - int row = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - if (getBorderStyle(row, i, - CellUtil.BORDER_BOTTOM) == BorderStyle.NONE) { - drawBottomBorder(new CellRangeAddress(row, row, i, i), - BorderStyle.THIN); - } - addProperty(row, i, CellUtil.BOTTOM_BORDER_COLOR, color); - } - } - - /** - *

        - * Sets the color of the left border for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawLeftBorderColor(CellRangeAddress range, short color) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getFirstColumn(); - for (int i = firstRow; i <= lastRow; i++) { - if (getBorderStyle(i, col, - CellUtil.BORDER_LEFT) == BorderStyle.NONE) { - drawLeftBorder(new CellRangeAddress(i, i, col, col), - BorderStyle.THIN); - } - addProperty(i, col, CellUtil.LEFT_BORDER_COLOR, color); - } - } - - /** - *

        - * Sets the color of the right border for a range of cells. If the border is - * not drawn, it defaults to BORDER_THIN - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawRightBorderColor(CellRangeAddress range, short color) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - if (getBorderStyle(i, col, - CellUtil.BORDER_RIGHT) == BorderStyle.NONE) { - drawRightBorder(new CellRangeAddress(i, i, col, col), - BorderStyle.THIN); - } - addProperty(i, col, CellUtil.RIGHT_BORDER_COLOR, color); - } - } - - /** - *

        - * Sets the color of the outside borders for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link BorderExtent} of the borders for which - * colors are set. Valid Values are: - *
          - *
        • BorderExtent.ALL
        • - *
        • BorderExtent.HORIZONTAL
        • - *
        • BorderExtent.VERTICAL
        • - *
        - */ - private void drawOutsideBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case ALL: - case HORIZONTAL: - case VERTICAL: - if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) { - drawTopBorderColor(range, color); - drawBottomBorderColor(range, color); - } - if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) { - drawLeftBorderColor(range, color); - drawRightBorderColor(range, color); - } - break; - default: - throw new IllegalArgumentException( - "Unsupported PropertyTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL"); - } - } - - /** - *

        - * Sets the color of the horizontal borders for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link BorderExtent} of the borders for which - * colors are set. Valid Values are: - *
          - *
        • BorderExtent.ALL
        • - *
        • BorderExtent.INSIDE
        • - *
        - */ - private void drawHorizontalBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - CellRangeAddress row = new CellRangeAddress(i, i, firstCol, - lastCol); - if (extent == BorderExtent.ALL || i > firstRow) { - drawTopBorderColor(row, color); - } - if (extent == BorderExtent.ALL || i < lastRow) { - drawBottomBorderColor(row, color); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - *

        - * Sets the color of the vertical borders for a range of cells. - *

        - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link BorderExtent} of the borders for which - * colors are set. Valid Values are: - *
          - *
        • BorderExtent.ALL
        • - *
        • BorderExtent.INSIDE
        • - *
        - */ - private void drawVerticalBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - CellRangeAddress row = new CellRangeAddress(firstRow, lastRow, - i, i); - if (extent == BorderExtent.ALL || i > firstCol) { - drawLeftBorderColor(row, color); - } - if (extent == BorderExtent.ALL || i < lastCol) { - drawRightBorderColor(row, color); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - * Removes all border properties from this {@link PropertyTemplate} for the - * specified range. - * - * @parm range - {@link CellRangeAddress} range of cells to remove borders. - */ - private void removeBorderColors(CellRangeAddress range) { - Set properties = new HashSet(); - properties.add(CellUtil.TOP_BORDER_COLOR); - properties.add(CellUtil.BOTTOM_BORDER_COLOR); - properties.add(CellUtil.LEFT_BORDER_COLOR); - properties.add(CellUtil.RIGHT_BORDER_COLOR); - for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) { - for (int col = range.getFirstColumn(); col <= range - .getLastColumn(); col++) { - removeProperties(row, col, properties); - } - } - } - - /** - * Adds a property to this {@link PropertyTemplate} for a given cell - * - * @param row - * @param col - * @param property - * @param value - */ - private void addProperty(int row, int col, String property, short value) { - addProperty(row, col, property, Short.valueOf(value)); - } - - /** - * Adds a property to this {@link PropertyTemplate} for a given cell - * - * @param row - * @param col - * @param property - * @param value - */ - private void addProperty(int row, int col, String property, Object value) { - CellAddress cell = new CellAddress(row, col); - Map cellProperties = _propertyTemplate.get(cell); - if (cellProperties == null) { - cellProperties = new HashMap(); - } - cellProperties.put(property, value); - _propertyTemplate.put(cell, cellProperties); - } - - /** - * Removes a set of properties from this {@link PropertyTemplate} for a - * given cell - * - * @param row - * @param col - * @param properties - */ - private void removeProperties(int row, int col, Set properties) { - CellAddress cell = new CellAddress(row, col); - Map cellProperties = _propertyTemplate.get(cell); - if (cellProperties != null) { - cellProperties.keySet().removeAll(properties); - if (cellProperties.isEmpty()) { - _propertyTemplate.remove(cell); - } else { - _propertyTemplate.put(cell, cellProperties); - } - } - } - - /** - * Retrieves the number of borders assigned to a cell - * - * @param cell - */ - public int getNumBorders(CellAddress cell) { - Map cellProperties = _propertyTemplate.get(cell); - if (cellProperties == null) { - return 0; - } - - int count = 0; - for (String property : cellProperties.keySet()) { - if (property.equals(CellUtil.BORDER_TOP)) - count += 1; - if (property.equals(CellUtil.BORDER_BOTTOM)) - count += 1; - if (property.equals(CellUtil.BORDER_LEFT)) - count += 1; - if (property.equals(CellUtil.BORDER_RIGHT)) - count += 1; - } - return count; - } - - /** - * Retrieves the number of borders assigned to a cell - * - * @param row - * @param col - */ - public int getNumBorders(int row, int col) { - return getNumBorders(new CellAddress(row, col)); - } - - /** - * Retrieves the number of border colors assigned to a cell - * - * @param cell - */ - public int getNumBorderColors(CellAddress cell) { - Map cellProperties = _propertyTemplate.get(cell); - if (cellProperties == null) { - return 0; - } - - int count = 0; - for (String property : cellProperties.keySet()) { - if (property.equals(CellUtil.TOP_BORDER_COLOR)) - count += 1; - if (property.equals(CellUtil.BOTTOM_BORDER_COLOR)) - count += 1; - if (property.equals(CellUtil.LEFT_BORDER_COLOR)) - count += 1; - if (property.equals(CellUtil.RIGHT_BORDER_COLOR)) - count += 1; - } - return count; - } - - /** - * Retrieves the number of border colors assigned to a cell - * - * @param row - * @param col - */ - public int getNumBorderColors(int row, int col) { - return getNumBorderColors(new CellAddress(row, col)); - } - - /** - * Retrieves the border style for a given cell - * - * @param cell - * @param property - */ - public BorderStyle getBorderStyle(CellAddress cell, String property) { - BorderStyle value = BorderStyle.NONE; - Map cellProperties = _propertyTemplate.get(cell); - if (cellProperties != null) { - Object obj = cellProperties.get(property); - if (obj instanceof BorderStyle) { - value = (BorderStyle) obj; - } - } - return value; - } - - /** - * Retrieves the border style for a given cell - * - * @param row - * @param col - * @param property - */ - public BorderStyle getBorderStyle(int row, int col, String property) { - return getBorderStyle(new CellAddress(row, col), property); - } - - /** - * Retrieves the border style for a given cell - * - * @param cell - * @param property - */ - public short getTemplateProperty(CellAddress cell, String property) { - short value = 0; - Map cellProperties = _propertyTemplate.get(cell); - if (cellProperties != null) { - Object obj = cellProperties.get(property); - if (obj != null) { - value = getShort(obj); - } - } - return value; - } - - /** - * Retrieves the border style for a given cell - * - * @param row - * @param col - * @param property - */ - public short getTemplateProperty(int row, int col, String property) { - return getTemplateProperty(new CellAddress(row, col), property); - } - - /** - * Converts a Short object to a short value or 0 if the object is not a - * Short - * - * @param value Potentially short value to convert - * @return short value, or 0 if not a short - */ - private static short getShort(Object value) { - if (value instanceof Short) { - return ((Short) value).shortValue(); - } - return 0; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/RegionUtil.java b/trunk/src/java/org/apache/poi/ss/util/RegionUtil.java deleted file mode 100644 index caec5a009..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/RegionUtil.java +++ /dev/null @@ -1,416 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.Removal; - -/** - * Various utility functions that make working with a region of cells easier. - */ -public final class RegionUtil { - - private RegionUtil() { - // no instances of this class - } - - /** - * For setting the same property on many cells to the same value - */ - private static final class CellPropertySetter { - - private final String _propertyName; - private final Object _propertyValue; - - - public CellPropertySetter(String propertyName, int value) { - _propertyName = propertyName; - _propertyValue = Short.valueOf((short) value); - } - public CellPropertySetter(String propertyName, BorderStyle value) { - _propertyName = propertyName; - _propertyValue = value; - } - - public void setProperty(Row row, int column) { - // create cell if it does not exist - Cell cell = CellUtil.getCell(row, column); - CellUtil.setCellStyleProperty(cell, _propertyName, _propertyValue); - } - } - - /** - * Sets the left border style for a region of cells by manipulating the cell style of the individual - * cells on the left - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setBorderLeft(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setBorderLeft(int border, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setBorderLeft(border, region, sheet); - } - /** - * Sets the left border style for a region of cells by manipulating the cell style of the individual - * cells on the left - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - * @deprecated 3.16 beta 1. Use {@link #setBorderLeft(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.18") - public static void setBorderLeft(int border, CellRangeAddress region, Sheet sheet) { - int rowStart = region.getFirstRow(); - int rowEnd = region.getLastRow(); - int column = region.getFirstColumn(); - - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_LEFT, border); - for (int i = rowStart; i <= rowEnd; i++) { - cps.setProperty(CellUtil.getRow(i, sheet), column); - } - } - /** - * Sets the left border style for a region of cells by manipulating the cell style of the individual - * cells on the left - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.16 beta 1 - */ - public static void setBorderLeft(BorderStyle border, CellRangeAddress region, Sheet sheet) { - int rowStart = region.getFirstRow(); - int rowEnd = region.getLastRow(); - int column = region.getFirstColumn(); - - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_LEFT, border); - for (int i = rowStart; i <= rowEnd; i++) { - cps.setProperty(CellUtil.getRow(i, sheet), column); - } - } - - /** - * Sets the left border color for a region of cells by manipulating the cell style of the individual - * cells on the left - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setLeftBorderColor(int, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setLeftBorderColor(int color, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setLeftBorderColor(color, region, sheet); - } - /** - * Sets the left border color for a region of cells by manipulating the cell style of the individual - * cells on the left - * - * @param color The color of the border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - */ - public static void setLeftBorderColor(int color, CellRangeAddress region, Sheet sheet) { - int rowStart = region.getFirstRow(); - int rowEnd = region.getLastRow(); - int column = region.getFirstColumn(); - - CellPropertySetter cps = new CellPropertySetter(CellUtil.LEFT_BORDER_COLOR, color); - for (int i = rowStart; i <= rowEnd; i++) { - cps.setProperty(CellUtil.getRow(i, sheet), column); - } - } - - /** - * Sets the right border style for a region of cells by manipulating the cell style of the individual - * cells on the right - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setBorderRight(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setBorderRight(int border, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setBorderRight(border, region, sheet); - } - /** - * Sets the right border style for a region of cells by manipulating the cell style of the individual - * cells on the right - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - * @deprecated POI 3.16 beta 1. Use {@link #setBorderRight(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.18") - public static void setBorderRight(int border, CellRangeAddress region, Sheet sheet) { - int rowStart = region.getFirstRow(); - int rowEnd = region.getLastRow(); - int column = region.getLastColumn(); - - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_RIGHT, border); - for (int i = rowStart; i <= rowEnd; i++) { - cps.setProperty(CellUtil.getRow(i, sheet), column); - } - } - /** - * Sets the right border style for a region of cells by manipulating the cell style of the individual - * cells on the right - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.16 beta 1 - */ - public static void setBorderRight(BorderStyle border, CellRangeAddress region, Sheet sheet) { - int rowStart = region.getFirstRow(); - int rowEnd = region.getLastRow(); - int column = region.getLastColumn(); - - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_RIGHT, border); - for (int i = rowStart; i <= rowEnd; i++) { - cps.setProperty(CellUtil.getRow(i, sheet), column); - } - } - - /** - * Sets the right border color for a region of cells by manipulating the cell style of the individual - * cells on the right - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setRightBorderColor(int, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setRightBorderColor(int color, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setRightBorderColor(color, region, sheet); - } - /** - * Sets the right border color for a region of cells by manipulating the cell style of the individual - * cells on the right - * - * @param color The color of the border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - */ - public static void setRightBorderColor(int color, CellRangeAddress region, Sheet sheet) { - int rowStart = region.getFirstRow(); - int rowEnd = region.getLastRow(); - int column = region.getLastColumn(); - - CellPropertySetter cps = new CellPropertySetter(CellUtil.RIGHT_BORDER_COLOR, color); - for (int i = rowStart; i <= rowEnd; i++) { - cps.setProperty(CellUtil.getRow(i, sheet), column); - } - } - - /** - * Sets the bottom border style for a region of cells by manipulating the cell style of the individual - * cells on the bottom - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setBorderBottom(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setBorderBottom(int border, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setBorderBottom(border, region, sheet); - } - /** - * Sets the bottom border style for a region of cells by manipulating the cell style of the individual - * cells on the bottom - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - * @deprecated POI 3.16 beta 1. Use {@link #setBorderBottom(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.18") - public static void setBorderBottom(int border, CellRangeAddress region, Sheet sheet) { - int colStart = region.getFirstColumn(); - int colEnd = region.getLastColumn(); - int rowIndex = region.getLastRow(); - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_BOTTOM, border); - Row row = CellUtil.getRow(rowIndex, sheet); - for (int i = colStart; i <= colEnd; i++) { - cps.setProperty(row, i); - } - } - /** - * Sets the bottom border style for a region of cells by manipulating the cell style of the individual - * cells on the bottom - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.16 beta 1 - */ - public static void setBorderBottom(BorderStyle border, CellRangeAddress region, Sheet sheet) { - int colStart = region.getFirstColumn(); - int colEnd = region.getLastColumn(); - int rowIndex = region.getLastRow(); - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_BOTTOM, border); - Row row = CellUtil.getRow(rowIndex, sheet); - for (int i = colStart; i <= colEnd; i++) { - cps.setProperty(row, i); - } - } - - /** - * Sets the bottom border color for a region of cells by manipulating the cell style of the individual - * cells on the bottom - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setBottomBorderColor(int, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setBottomBorderColor(int color, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setBottomBorderColor(color, region, sheet); - } - /** - * Sets the bottom border color for a region of cells by manipulating the cell style of the individual - * cells on the bottom - * - * @param color The color of the border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - */ - public static void setBottomBorderColor(int color, CellRangeAddress region, Sheet sheet) { - int colStart = region.getFirstColumn(); - int colEnd = region.getLastColumn(); - int rowIndex = region.getLastRow(); - CellPropertySetter cps = new CellPropertySetter(CellUtil.BOTTOM_BORDER_COLOR, color); - Row row = CellUtil.getRow(rowIndex, sheet); - for (int i = colStart; i <= colEnd; i++) { - cps.setProperty(row, i); - } - } - - /** - * Sets the top border style for a region of cells by manipulating the cell style of the individual - * cells on the top - * - * @param border The new border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setBorderTop(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setBorderTop(int border, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setBorderTop(border, region, sheet); - } - /** - * Sets the top border style for a region of cells by manipulating the cell style of the individual - * cells on the top - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - * @deprecated 3.16 beta 1. Use {@link #setBorderTop(BorderStyle, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.18") - public static void setBorderTop(int border, CellRangeAddress region, Sheet sheet) { - int colStart = region.getFirstColumn(); - int colEnd = region.getLastColumn(); - int rowIndex = region.getFirstRow(); - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_TOP, border); - Row row = CellUtil.getRow(rowIndex, sheet); - for (int i = colStart; i <= colEnd; i++) { - cps.setProperty(row, i); - } - } - /** - * Sets the top border style for a region of cells by manipulating the cell style of the individual - * cells on the top - * - * @param border The new border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.16 beta 1 - */ - public static void setBorderTop(BorderStyle border, CellRangeAddress region, Sheet sheet) { - int colStart = region.getFirstColumn(); - int colEnd = region.getLastColumn(); - int rowIndex = region.getFirstRow(); - CellPropertySetter cps = new CellPropertySetter(CellUtil.BORDER_TOP, border); - Row row = CellUtil.getRow(rowIndex, sheet); - for (int i = colStart; i <= colEnd; i++) { - cps.setProperty(row, i); - } - } - - /** - * Sets the top border color for a region of cells by manipulating the cell style of the individual - * cells on the top - * - * @param color The color of the border - * @param region The region that should have the border - * @param workbook The workbook that the region is on. - * @param sheet The sheet that the region is on. - * @deprecated 3.15 beta 2. Use {@link #setTopBorderColor(int, CellRangeAddress, Sheet)}. - */ - @Removal(version="3.17") - public static void setTopBorderColor(int color, CellRangeAddress region, Sheet sheet, Workbook workbook) { - setTopBorderColor(color, region, sheet); - } - /** - * Sets the top border color for a region of cells by manipulating the cell style of the individual - * cells on the top - * - * @param color The color of the border - * @param region The region that should have the border - * @param sheet The sheet that the region is on. - * @since POI 3.15 beta 2 - */ - public static void setTopBorderColor(int color, CellRangeAddress region, Sheet sheet) { - int colStart = region.getFirstColumn(); - int colEnd = region.getLastColumn(); - int rowIndex = region.getFirstRow(); - CellPropertySetter cps = new CellPropertySetter(CellUtil.TOP_BORDER_COLOR, color); - Row row = CellUtil.getRow(rowIndex, sheet); - for (int i = colStart; i <= colEnd; i++) { - cps.setProperty(row, i); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java b/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java deleted file mode 100644 index f58a2780e..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.lang.reflect.Array; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellRange; -import org.apache.poi.util.Internal; - -/** - * For POI internal use only - * - * @author Josh Micich - */ -@Internal -public final class SSCellRange implements CellRange { - - private final int _height; - private final int _width; - private final K[] _flattenedArray; - private final int _firstRow; - private final int _firstColumn; - - private SSCellRange(int firstRow, int firstColumn, int height, int width, K[] flattenedArray) { - _firstRow = firstRow; - _firstColumn = firstColumn; - _height = height; - _width = width; - _flattenedArray = flattenedArray.clone(); - } - - public static SSCellRange create(int firstRow, int firstColumn, int height, int width, List flattenedList, Class cellClass) { - int nItems = flattenedList.size(); - if (height * width != nItems) { - throw new IllegalArgumentException("Array size mismatch."); - } - - @SuppressWarnings("unchecked") - B[] flattenedArray = (B[]) Array.newInstance(cellClass, nItems); - flattenedList.toArray(flattenedArray); - return new SSCellRange(firstRow, firstColumn, height, width, flattenedArray); - } - - public int getHeight() { - return _height; - } - public int getWidth() { - return _width; - } - public int size() { - return _height*_width; - } - - public String getReferenceText() { - CellRangeAddress cra = new CellRangeAddress(_firstRow, _firstRow+_height-1, _firstColumn, _firstColumn+_width-1); - return cra.formatAsString(); - } - - public K getTopLeftCell() { - return _flattenedArray[0]; - } - - public K getCell(int relativeRowIndex, int relativeColumnIndex) { - if (relativeRowIndex < 0 || relativeRowIndex >= _height) { - throw new ArrayIndexOutOfBoundsException("Specified row " + relativeRowIndex - + " is outside the allowable range (0.." + (_height-1) + ")."); - } - if (relativeColumnIndex < 0 || relativeColumnIndex >= _width) { - throw new ArrayIndexOutOfBoundsException("Specified colummn " + relativeColumnIndex - + " is outside the allowable range (0.." + (_width-1) + ")."); - } - int flatIndex = _width * relativeRowIndex + relativeColumnIndex; - return _flattenedArray[flatIndex]; - } - public K[] getFlattenedCells() { - return _flattenedArray.clone(); - } - - public K[][] getCells() { - Class itemCls = _flattenedArray.getClass(); - @SuppressWarnings("unchecked") - K[][] result = (K[][]) Array.newInstance(itemCls, _height); - itemCls = itemCls.getComponentType(); - for (int r=_height-1; r>=0; r--) { - @SuppressWarnings("unchecked") - K[] row = (K[]) Array.newInstance(itemCls, _width); - int flatIndex = _width * r; - System.arraycopy(_flattenedArray, flatIndex, row, 0, _width); - } - return result; - } - public Iterator iterator() { - return new ArrayIterator(_flattenedArray); - } - private static final class ArrayIterator implements Iterator { - - private final D[] _array; - private int _index; - - public ArrayIterator(D[] array) { - _array = array.clone(); - _index = 0; - } - public boolean hasNext() { - return _index < _array.length; - } - public D next() { - if (_index >= _array.length) { - throw new NoSuchElementException(String.valueOf(_index)); - } - return _array[_index++]; - } - - public void remove() { - throw new UnsupportedOperationException("Cannot remove cells from this CellRange."); - } - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/SheetBuilder.java b/trunk/src/java/org/apache/poi/ss/util/SheetBuilder.java deleted file mode 100644 index 366d783ba..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/SheetBuilder.java +++ /dev/null @@ -1,158 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== */ -package org.apache.poi.ss.util; - -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Cell; - -/** - * Class {@code SheetBuilder} provides an easy way of building workbook sheets - * from 2D array of Objects. It can be used in test cases to improve code - * readability or in Swing applications with tables. - * - * @author Roman Kashitsyn - */ -public class SheetBuilder { - - private final Workbook workbook; - private final Object[][] cells; - private boolean shouldCreateEmptyCells = false; - private String sheetName = null; - - public SheetBuilder(Workbook workbook, Object[][] cells) { - this.workbook = workbook; - this.cells = cells.clone(); - } - - /** - * Returns {@code true} if null array elements should be treated as empty - * cells. - * - * @return {@code true} if null objects should be treated as empty cells - * and {@code false} otherwise - */ - public boolean getCreateEmptyCells() { - return shouldCreateEmptyCells; - } - - /** - * Specifies if null array elements should be treated as empty cells. - * - * @param shouldCreateEmptyCells {@code true} if null array elements should be - * treated as empty cells - * @return {@code this} - */ - public SheetBuilder setCreateEmptyCells(boolean shouldCreateEmptyCells) { - this.shouldCreateEmptyCells = shouldCreateEmptyCells; - return this; - } - - /** - * Specifies name of the sheet to build. If not specified, default name (provided by - * workbook) will be used instead. - * @param sheetName sheet name to use - * @return {@code this} - */ - public SheetBuilder setSheetName(String sheetName) { - this.sheetName = sheetName; - return this; - } - - /** - * Builds sheet from parent workbook and 2D array with cell - * values. Creates rows anyway (even if row contains only null - * cells), creates cells if either corresponding array value is not - * null or createEmptyCells property is true. - * The conversion is performed in the following way: - *

        - *

          - *
        • Numbers become numeric cells.
        • - *
        • java.util.Date or java.util.Calendar - * instances become date cells.
        • - *
        • String with leading '=' char become formulas (leading '=' - * will be truncated).
        • - *
        • Other objects become strings via Object.toString() - * method call.
        • - *
        - * - * @return newly created sheet - */ - public Sheet build() { - Sheet sheet = (sheetName == null) ? workbook.createSheet() : workbook.createSheet(sheetName); - Row currentRow = null; - Cell currentCell = null; - - for (int rowIndex = 0; rowIndex < cells.length; ++rowIndex) { - Object[] rowArray = cells[rowIndex]; - currentRow = sheet.createRow(rowIndex); - - for (int cellIndex = 0; cellIndex < rowArray.length; ++cellIndex) { - Object cellValue = rowArray[cellIndex]; - if (cellValue != null || shouldCreateEmptyCells) { - currentCell = currentRow.createCell(cellIndex); - setCellValue(currentCell, cellValue); - } - } - } - return sheet; - } - - /** - * Sets the cell value using object type information. - * - * @param cell cell to change - * @param value value to set - */ - private void setCellValue(Cell cell, Object value) { - if (value == null || cell == null) { - return; - } else if (value instanceof Number) { - double doubleValue = ((Number) value).doubleValue(); - cell.setCellValue(doubleValue); - } else if (value instanceof Date) { - cell.setCellValue((Date) value); - } else if (value instanceof Calendar) { - cell.setCellValue((Calendar) value); - } else if (isFormulaDefinition(value)) { - cell.setCellFormula(getFormula(value)); - } else { - cell.setCellValue(value.toString()); - } - } - - private boolean isFormulaDefinition(Object obj) { - if (obj instanceof String) { - String str = (String) obj; - if (str.length() < 2) { - return false; - } else { - return ((String) obj).charAt(0) == '='; - } - } else { - return false; - } - } - - private String getFormula(Object obj) { - return ((String) obj).substring(1); - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/ss/util/SheetReferences.java b/trunk/src/java/org/apache/poi/ss/util/SheetReferences.java deleted file mode 100644 index a7542763d..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/SheetReferences.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.util.HashMap; -import java.util.Map; - -/** - * Holds a collection of Sheet names and their associated - * reference numbers. - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * - */ -public class SheetReferences -{ - Map map; - public SheetReferences() - { - map = new HashMap(5); - } - - public void addSheetReference(String sheetName, int number) { - map.put(number, sheetName); - } - - public String getSheetName(int number) { - return map.get(number); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/SheetUtil.java b/trunk/src/java/org/apache/poi/ss/util/SheetUtil.java deleted file mode 100644 index f234380fe..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/SheetUtil.java +++ /dev/null @@ -1,390 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import java.awt.font.FontRenderContext; -import java.awt.font.TextAttribute; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.text.AttributedString; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.Internal; - - -/** - * Helper methods for when working with Usermodel sheets - * - * @author Yegor Kozlov - */ -public class SheetUtil { - - /** - * Excel measures columns in units of 1/256th of a character width - * but the docs say nothing about what particular character is used. - * '0' looks to be a good choice. - */ - private static final char defaultChar = '0'; - - /** - * This is the multiple that the font height is scaled by when determining the - * boundary of rotated text. - */ - private static final double fontHeightMultiple = 2.0; - - /** - * Dummy formula evaluator that does nothing. - * YK: The only reason of having this class is that - * {@link org.apache.poi.ss.usermodel.DataFormatter#formatCellValue(org.apache.poi.ss.usermodel.Cell)} - * returns formula string for formula cells. Dummy evaluator makes it to format the cached formula result. - * - * See Bugzilla #50021 - */ - private static final FormulaEvaluator dummyEvaluator = new FormulaEvaluator(){ - @Override - public void clearAllCachedResultValues(){} - @Override - public void notifySetFormula(Cell cell) {} - @Override - public void notifyDeleteCell(Cell cell) {} - @Override - public void notifyUpdateCell(Cell cell) {} - @Override - public CellValue evaluate(Cell cell) {return null; } - @Override - public Cell evaluateInCell(Cell cell) { return null; } - @Override - public void setupReferencedWorkbooks(Map workbooks) {} - @Override - public void setDebugEvaluationOutputForNextEval(boolean value) {} - @Override - public void setIgnoreMissingWorkbooks(boolean ignore) {} - @Override - public void evaluateAll() {} - @Override - public int evaluateFormulaCell(Cell cell) { - return cell.getCachedFormulaResultType(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Internal(since="POI 3.15 beta 3") - @Override - public CellType evaluateFormulaCellEnum(Cell cell) { - return cell.getCachedFormulaResultTypeEnum(); - } - }; - - /** - * drawing context to measure text - */ - private static final FontRenderContext fontRenderContext = new FontRenderContext(null, true, true); - - /** - * Compute width of a single cell - * - * @param cell the cell whose width is to be calculated - * @param defaultCharWidth the width of a single character - * @param formatter formatter used to prepare the text to be measured - * @param useMergedCells whether to use merged cells - * @return the width in pixels or -1 if cell is empty - */ - public static double getCellWidth(Cell cell, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) { - Sheet sheet = cell.getSheet(); - Workbook wb = sheet.getWorkbook(); - Row row = cell.getRow(); - int column = cell.getColumnIndex(); - - // FIXME: this looks very similar to getCellWithMerges below. Consider consolidating. - // We should only be checking merged regions if useMergedCells is true. Why are we doing this for-loop? - int colspan = 1; - for (CellRangeAddress region : sheet.getMergedRegions()) { - if (region.isInRange(row.getRowNum(), column)) { - if (!useMergedCells) { - // If we're not using merged cells, skip this one and move on to the next. - return -1; - } - cell = row.getCell(region.getFirstColumn()); - colspan = 1 + region.getLastColumn() - region.getFirstColumn(); - } - } - - CellStyle style = cell.getCellStyle(); - CellType cellType = cell.getCellTypeEnum(); - - // for formula cells we compute the cell width for the cached formula result - if (cellType == CellType.FORMULA) - cellType = cell.getCachedFormulaResultTypeEnum(); - - Font font = wb.getFontAt(style.getFontIndex()); - - double width = -1; - if (cellType == CellType.STRING) { - RichTextString rt = cell.getRichStringCellValue(); - String[] lines = rt.getString().split("\\n"); - for (String line : lines) { - String txt = line + defaultChar; - - AttributedString str = new AttributedString(txt); - copyAttributes(font, str, 0, txt.length()); - - if (rt.numFormattingRuns() > 0) { - // TODO: support rich text fragments - } - - width = getCellWidth(defaultCharWidth, colspan, style, width, str); - } - } else { - String sval = null; - if (cellType == CellType.NUMERIC) { - // Try to get it formatted to look the same as excel - try { - sval = formatter.formatCellValue(cell, dummyEvaluator); - } catch (Exception e) { - sval = String.valueOf(cell.getNumericCellValue()); - } - } else if (cellType == CellType.BOOLEAN) { - sval = String.valueOf(cell.getBooleanCellValue()).toUpperCase(Locale.ROOT); - } - if(sval != null) { - String txt = sval + defaultChar; - AttributedString str = new AttributedString(txt); - copyAttributes(font, str, 0, txt.length()); - - width = getCellWidth(defaultCharWidth, colspan, style, width, str); - } - } - return width; - } - - /** - * Calculate the best-fit width for a cell - * If a merged cell spans multiple columns, evenly distribute the column width among those columns - * - * @param defaultCharWidth the width of a character using the default font in a workbook - * @param colspan the number of columns that is spanned by the cell (1 if the cell is not part of a merged region) - * @param style the cell style, which contains text rotation and indention information needed to compute the cell width - * @param minWidth the minimum best-fit width. This algorithm will only return values greater than or equal to the minimum width. - * @param str the text contained in the cell - * @return the best fit cell width - */ - private static double getCellWidth(int defaultCharWidth, int colspan, - CellStyle style, double minWidth, AttributedString str) { - TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext); - final Rectangle2D bounds; - if(style.getRotation() != 0){ - /* - * Transform the text using a scale so that it's height is increased by a multiple of the leading, - * and then rotate the text before computing the bounds. The scale results in some whitespace around - * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but - * is added by the standard Excel autosize. - */ - AffineTransform trans = new AffineTransform(); - trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0)); - trans.concatenate( - AffineTransform.getScaleInstance(1, fontHeightMultiple) - ); - bounds = layout.getOutline(trans).getBounds(); - } else { - bounds = layout.getBounds(); - } - // frameWidth accounts for leading spaces which is excluded from bounds.getWidth() - final double frameWidth = bounds.getX() + bounds.getWidth(); - return Math.max(minWidth, ((frameWidth / colspan) / defaultCharWidth) + style.getIndention()); - } - - /** - * Compute width of a column and return the result - * - * @param sheet the sheet to calculate - * @param column 0-based index of the column - * @param useMergedCells whether to use merged cells - * @return the width in pixels or -1 if all cells are empty - */ - public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells) { - return getColumnWidth(sheet, column, useMergedCells, sheet.getFirstRowNum(), sheet.getLastRowNum()); - } - - /** - * Compute width of a column based on a subset of the rows and return the result - * - * @param sheet the sheet to calculate - * @param column 0-based index of the column - * @param useMergedCells whether to use merged cells - * @param firstRow 0-based index of the first row to consider (inclusive) - * @param lastRow 0-based index of the last row to consider (inclusive) - * @return the width in pixels or -1 if cell is empty - */ - public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells, int firstRow, int lastRow){ - DataFormatter formatter = new DataFormatter(); - int defaultCharWidth = getDefaultCharWidth(sheet.getWorkbook()); - - double width = -1; - for (int rowIdx = firstRow; rowIdx <= lastRow; ++rowIdx) { - Row row = sheet.getRow(rowIdx); - if( row != null ) { - double cellWidth = getColumnWidthForRow(row, column, defaultCharWidth, formatter, useMergedCells); - width = Math.max(width, cellWidth); - } - } - return width; - } - - /** - * Get default character width using the Workbook's default font - * - * @param wb the workbook to get the default character width from - * @return default character width in pixels - */ - @Internal - public static int getDefaultCharWidth(final Workbook wb) { - Font defaultFont = wb.getFontAt((short) 0); - - AttributedString str = new AttributedString(String.valueOf(defaultChar)); - copyAttributes(defaultFont, str, 0, 1); - TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext); - return (int) layout.getAdvance(); - } - - /** - * Compute width of a single cell in a row - * Convenience method for {@link #getCellWidth} - * - * @param row the row that contains the cell of interest - * @param column the column number of the cell whose width is to be calculated - * @param defaultCharWidth the width of a single character - * @param formatter formatter used to prepare the text to be measured - * @param useMergedCells whether to use merged cells - * @return the width in pixels or -1 if cell is empty - */ - private static double getColumnWidthForRow( - Row row, int column, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) { - if( row == null ) { - return -1; - } - - Cell cell = row.getCell(column); - - if (cell == null) { - return -1; - } - - return getCellWidth(cell, defaultCharWidth, formatter, useMergedCells); - } - - /** - * Check if the Fonts are installed correctly so that Java can compute the size of - * columns. - * - * If a Cell uses a Font which is not available on the operating system then Java may - * fail to return useful Font metrics and thus lead to an auto-computed size of 0. - * - * This method allows to check if computing the sizes for a given Font will succeed or not. - * - * @param font The Font that is used in the Cell - * @return true if computing the size for this Font will succeed, false otherwise - */ - public static boolean canComputeColumnWidth(Font font) { - // not sure what is the best value sample-here, only "1" did not work on some platforms... - AttributedString str = new AttributedString("1w"); - copyAttributes(font, str, 0, "1w".length()); - - TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext); - if(layout.getBounds().getWidth() > 0) { - return true; - } - - return false; - } - - /** - * Copy text attributes from the supplied Font to Java2D AttributedString - */ - private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) { - str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx); - str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints()); - if (font.getBold()) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx); - if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx); - if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx); - } - - /** - * Check if the cell is 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] - * @deprecated 3.15 beta 2. Use {@link CellRangeAddressBase#isInRange(int, int)}. - */ - @Deprecated - public static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) { - return cr.isInRange(rowIx, colIx); - } - - /** - * Return the cell, taking account of merged regions. Allows you to find the - * cell who's contents are shown in a given position in the sheet. - * - *

        If the cell at the given co-ordinates is a merged cell, this will - * return the primary (top-left) most cell of the merged region. - *

        If the cell at the given co-ordinates is not in a merged region, - * then will return the cell itself. - *

        If there is no cell defined at the given co-ordinates, will return - * null. - */ - public static Cell getCellWithMerges(Sheet sheet, int rowIx, int colIx) { - Row r = sheet.getRow(rowIx); - if (r != null) { - Cell c = r.getCell(colIx); - if (c != null) { - // Normal, non-merged cell - return c; - } - } - - for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) { - if (mergedRegion.isInRange(rowIx, colIx)) { - // The cell wanted is in this merged range - // Return the primary (top-left) cell for the range - r = sheet.getRow(mergedRegion.getFirstRow()); - if (r != null) { - return r.getCell(mergedRegion.getFirstColumn()); - } - } - } - - // If we get here, then the cell isn't defined, and doesn't - // live within any merged regions - return null; - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/WorkbookUtil.java b/trunk/src/java/org/apache/poi/ss/util/WorkbookUtil.java deleted file mode 100644 index 684434823..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/WorkbookUtil.java +++ /dev/null @@ -1,182 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import org.apache.poi.ss.usermodel.Workbook; - - -/** - * Helper methods for when working with Usermodel Workbooks - */ -public class WorkbookUtil { - - /** - * Creates a valid sheet name, which is conform to the rules. - * In any case, the result safely can be used for - * {@link org.apache.poi.ss.usermodel.Workbook#setSheetName(int, String)}. - *
        - * Rules: - *

          - *
        • never null
        • - *
        • minimum length is 1
        • - *
        • maximum length is 31
        • - *
        • doesn't contain special chars: : 0x0000, 0x0003, / \ ? * ] [
        • - *
        • Sheet names must not begin or end with ' (apostrophe)
        • - *
        - * Invalid characters are replaced by one space character ' '. - * - * @param nameProposal can be any string, will be truncated if necessary, - * allowed to be null - * @return a valid string, "empty" if to short, "null" if null - */ - public final static String createSafeSheetName(final String nameProposal) { - return createSafeSheetName(nameProposal, ' '); - } - - /** - * Creates a valid sheet name, which is conform to the rules. - * In any case, the result safely can be used for - * {@link org.apache.poi.ss.usermodel.Workbook#setSheetName(int, String)}. - *
        - * Rules: - *
          - *
        • never null
        • - *
        • minimum length is 1
        • - *
        • maximum length is 31
        • - *
        • doesn't contain special chars: : 0x0000, 0x0003, / \ ? * ] [
        • - *
        • Sheet names must not begin or end with ' (apostrophe)
        • - *
        - * - * @param nameProposal can be any string, will be truncated if necessary, - * allowed to be null - * @param replaceChar the char to replace invalid characters. - * @return a valid string, "empty" if to short, "null" if null - */ - public final static String createSafeSheetName(final String nameProposal, char replaceChar) { - if (nameProposal == null) { - return "null"; - } - if (nameProposal.length() < 1) { - return "empty"; - } - final int length = Math.min(31, nameProposal.length()); - final String shortenname = nameProposal.substring(0, length); - final StringBuilder result = new StringBuilder(shortenname); - for (int i=0; i - * The character count MUST be greater than or equal to 1 and less than or equal to 31. - * The string MUST NOT contain the any of the following characters: - *
          - *
        • 0x0000
        • - *
        • 0x0003
        • - *
        • colon (:)
        • - *
        • backslash (\)
        • - *
        • asterisk (*)
        • - *
        • question mark (?)
        • - *
        • forward slash (/)
        • - *
        • opening square bracket ([)
        • - *
        • closing square bracket (])
        • - *
        - * The string MUST NOT begin or end with the single quote (') character. - *

        - * - * @param sheetName the name to validate - * @throws IllegalArgumentException if validation fails - */ - public static void validateSheetName(String sheetName) { - if (sheetName == null) { - throw new IllegalArgumentException("sheetName must not be null"); - } - int len = sheetName.length(); - if (len < 1 || len > 31) { - throw new IllegalArgumentException("sheetName '" + sheetName - + "' is invalid - character count MUST be greater than or equal to 1 and less than or equal to 31"); - } - - for (int i=0; i - * - * 12 - * 34 - * - * - * - * @return ordinal number of current cell - */ - long getOrdinalNumber(); - - /** - * Returns number of current row. - * @return number of current row - */ - int getRowNumber(); - - /** - * Returns number of current column. - * @return number of current column - */ - int getColumnNumber(); -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/util/ArrayUtil.java b/trunk/src/java/org/apache/poi/util/ArrayUtil.java deleted file mode 100644 index 17f6a2964..000000000 --- a/trunk/src/java/org/apache/poi/util/ArrayUtil.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - - -/** - * Utility classes for dealing with arrays. - * - * @author Glen Stampoultzis - */ -public class ArrayUtil -{ - /** - * This is really a debugging version of System.arraycopy(). - * Use it to provide better exception messages when copying arrays around. - * For production use it's better to use the original for speed. - */ - public static void arraycopy(byte[] src, int src_position, byte[] dst, int dst_position, int length) - { - if (src_position < 0) - throw new IllegalArgumentException("src_position was less than 0. Actual value " + src_position); - if (src_position >= src.length) - throw new IllegalArgumentException( "src_position was greater than src array size. Tried to write starting at position " + src_position + " but the array length is " + src.length ); - if (src_position + length > src.length) - throw new IllegalArgumentException("src_position + length would overrun the src array. Expected end at " + (src_position + length) + " actual end at " + src.length); - if (dst_position < 0) - throw new IllegalArgumentException("dst_position was less than 0. Actual value " + dst_position); - if (dst_position >= dst.length) - throw new IllegalArgumentException( "dst_position was greater than dst array size. Tried to write starting at position " + dst_position + " but the array length is " + dst.length ); - if (dst_position + length > dst.length) - throw new IllegalArgumentException("dst_position + length would overrun the dst array. Expected end at " + (dst_position + length) + " actual end at " + dst.length); - - System.arraycopy( src, src_position, dst, dst_position, length); - } - - /** - * Moves a number of entries in an array to another point in the array, - * shifting those inbetween as required. - * @param array The array to alter - * @param moveFrom The (0 based) index of the first entry to move - * @param moveTo The (0 based) index of the positition to move to - * @param numToMove The number of entries to move - */ - public static void arrayMoveWithin(Object[] array, int moveFrom, int moveTo, int numToMove) { - // If we're not asked to do anything, return now - if(numToMove <= 0) { return; } - if(moveFrom == moveTo) { return; } - - // Check that the values supplied are valid - if(moveFrom < 0 || moveFrom >= array.length) { - throw new IllegalArgumentException("The moveFrom must be a valid array index"); - } - if(moveTo < 0 || moveTo >= array.length) { - throw new IllegalArgumentException("The moveTo must be a valid array index"); - } - if(moveFrom+numToMove > array.length) { - throw new IllegalArgumentException("Asked to move more entries than the array has"); - } - if(moveTo+numToMove > array.length) { - throw new IllegalArgumentException("Asked to move to a position that doesn't have enough space"); - } - - // Grab the bit to move - Object[] toMove = new Object[numToMove]; - System.arraycopy(array, moveFrom, toMove, 0, numToMove); - - // Grab the bit to be shifted - Object[] toShift; - int shiftTo; - if(moveFrom > moveTo) { - // Moving to an earlier point in the array - // Grab everything between the two points - toShift = new Object[(moveFrom-moveTo)]; - System.arraycopy(array, moveTo, toShift, 0, toShift.length); - shiftTo = moveTo + numToMove; - } else { - // Moving to a later point in the array - // Grab everything from after the toMove block, to the new point - toShift = new Object[(moveTo-moveFrom)]; - System.arraycopy(array, moveFrom+numToMove, toShift, 0, toShift.length); - shiftTo = moveFrom; - } - - // Copy the moved block to its new location - System.arraycopy(toMove, 0, array, moveTo, toMove.length); - - // And copy the shifted block to the shifted location - System.arraycopy(toShift, 0, array, shiftTo, toShift.length); - - - // We're done - array will now have everything moved as required - } - -} diff --git a/trunk/src/java/org/apache/poi/util/Beta.java b/trunk/src/java/org/apache/poi/util/Beta.java deleted file mode 100644 index 0f0d808b7..000000000 --- a/trunk/src/java/org/apache/poi/util/Beta.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -/** - * Signifies that a public API (public class, method or field) is subject to - * incompatible changes, or even removal, in a future release. An API bearing - * this annotation is exempt from any compatibility guarantees made by its - * containing library. - */ -@Documented -@Retention(RetentionPolicy.SOURCE) -public @interface Beta { - // just an annotation, no code needed -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/util/BitField.java b/trunk/src/java/org/apache/poi/util/BitField.java deleted file mode 100644 index 012e6acf9..000000000 --- a/trunk/src/java/org/apache/poi/util/BitField.java +++ /dev/null @@ -1,321 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -/** - * Manage operations dealing with bit-mapped fields. - * - * @author Marc Johnson (mjohnson at apache dot org) - * @author Andrew C. Oliver (acoliver at apache dot org) - */ -@Internal(since="POI 3.15 beta 3") -public class BitField -{ - private final int _mask; - private final int _shift_count; - - /** - * Create a BitField instance - * - * @param mask the mask specifying which bits apply to this - * BitField. Bits that are set in this mask are the - * bits that this BitField operates on - */ - - public BitField(final int mask) - { - _mask = mask; - int count = 0; - int bit_pattern = mask; - - if (bit_pattern != 0) - { - while ((bit_pattern & 1) == 0) - { - count++; - bit_pattern >>= 1; - } - } - _shift_count = count; - } - - /** - * Obtain the value for the specified BitField, appropriately - * shifted right. Many users of a BitField will want to treat the - * specified bits as an int value, and will not want to be aware - * that the value is stored as a BitField (and so shifted left so - * many bits) - * - * @param holder the int data containing the bits we're interested - * in - * - * @return the selected bits, shifted right appropriately - */ - - public int getValue(final int holder) - { - return getRawValue(holder) >>> _shift_count; - } - - /** - * Obtain the value for the specified BitField, appropriately - * shifted right, as a short. Many users of a BitField will want - * to treat the specified bits as an int value, and will not want - * to be aware that the value is stored as a BitField (and so - * shifted left so many bits) - * - * @param holder the short data containing the bits we're - * interested in - * - * @return the selected bits, shifted right appropriately - */ - - public short getShortValue(final short holder) - { - return ( short ) getValue(holder); - } - - /** - * Obtain the value for the specified BitField, unshifted - * - * @param holder the int data containing the bits we're interested - * in - * - * @return the selected bits - */ - - public int getRawValue(final int holder) - { - return (holder & _mask); - } - - /** - * Obtain the value for the specified BitField, unshifted - * - * @param holder the short data containing the bits we're - * interested in - * - * @return the selected bits - */ - - public short getShortRawValue(final short holder) - { - return ( short ) getRawValue(holder); - } - - /** - * Is the field set or not? This is most commonly used for a - * single-bit field, which is often used to represent a boolean - * value; the results of using it for a multi-bit field is to - * determine whether *any* of its bits are set - * - * @param holder the int data containing the bits we're interested in - * - * @return true if any of the bits are set, else false - */ - - public boolean isSet(final int holder) - { - return (holder & _mask) != 0; - } - - /** - * Are all of the bits set or not? This is a stricter test than - * isSet, in that all of the bits in a multi-bit set must be set - * for this method to return true - * - * @param holder the int data containing the bits we're interested in - * - * @return true if all of the bits are set, else false - */ - - public boolean isAllSet(final int holder) - { - return (holder & _mask) == _mask; - } - - /** - * Replace the bits with new values. - * - * @param holder the int data containing the bits we're interested in - * @param value the new value for the specified bits - * - * @return the value of holder with the bits from the value - * parameter replacing the old bits - */ - - public int setValue(final int holder, final int value) - { - return (holder & ~_mask) | ((value << _shift_count) & _mask); - } - - /** - * Replace the bits with new values. - * - * @param holder the short data containing the bits we're interested in - * @param value the new value for the specified bits - * - * @return the value of holder with the bits from the value - * parameter replacing the old bits - */ - - public short setShortValue(final short holder, final short value) - { - return ( short ) setValue(holder, value); - } - - /** - * Clear the bits. - * - * @param holder the int data containing the bits we're interested in - * - * @return the value of holder with the specified bits cleared - * (set to 0) - */ - - public int clear(final int holder) - { - return holder & ~_mask; - } - - /** - * Clear the bits. - * - * @param holder the short data containing the bits we're - * interested in - * - * @return the value of holder with the specified bits cleared - * (set to 0) - */ - - public short clearShort(final short holder) - { - return ( short ) clear(holder); - } - - /** - * Clear the bits. - * - * @param holder the byte data containing the bits we're - * interested in - * - * @return the value of holder with the specified bits cleared - * (set to 0) - */ - - public byte clearByte(final byte holder) - { - return ( byte ) clear(holder); - } - - /** - * Set the bits. - * - * @param holder the int data containing the bits we're interested - * in - * - * @return the value of holder with the specified bits set to 1 - */ - - public int set(final int holder) - { - return holder | _mask; - } - - /** - * Set the bits. - * - * @param holder the short data containing the bits we're - * interested in - * - * @return the value of holder with the specified bits set to 1 - */ - - public short setShort(final short holder) - { - return ( short ) set(holder); - } - - /** - * Set the bits. - * - * @param holder the byte data containing the bits we're - * interested in - * - * @return the value of holder with the specified bits set to 1 - */ - - public byte setByte(final byte holder) - { - return ( byte ) set(holder); - } - - /** - * Set a boolean BitField - * - * @param holder the int data containing the bits we're interested - * in - * @param flag indicating whether to set or clear the bits - * - * @return the value of holder with the specified bits set or - * cleared - */ - - public int setBoolean(final int holder, final boolean flag) - { - return flag ? set(holder) - : clear(holder); - } - - /** - * Set a boolean BitField - * - * @param holder the short data containing the bits we're - * interested in - * @param flag indicating whether to set or clear the bits - * - * @return the value of holder with the specified bits set or - * cleared - */ - - public short setShortBoolean(final short holder, final boolean flag) - { - return flag ? setShort(holder) - : clearShort(holder); - } - - /** - * Set a boolean BitField - * - * @param holder the byte data containing the bits we're - * interested in - * @param flag indicating whether to set or clear the bits - * - * @return the value of holder with the specified bits set or - * cleared - */ - - public byte setByteBoolean(final byte holder, final boolean flag) - { - return flag ? setByte(holder) - : clearByte(holder); - } -} // end public class BitField - diff --git a/trunk/src/java/org/apache/poi/util/BitFieldFactory.java b/trunk/src/java/org/apache/poi/util/BitFieldFactory.java deleted file mode 100644 index 047d5cb1d..000000000 --- a/trunk/src/java/org/apache/poi/util/BitFieldFactory.java +++ /dev/null @@ -1,37 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.util.*; - -/** - * Returns immutable Bitfield instances. - */ -public class BitFieldFactory { - private static Map instances = new HashMap(); - - public static BitField getInstance(int mask) { - BitField f = instances.get(Integer.valueOf(mask)); - if (f == null) { - f = new BitField(mask); - instances.put(Integer.valueOf(mask), f); - } - return f; - } -} diff --git a/trunk/src/java/org/apache/poi/util/BlockingInputStream.java b/trunk/src/java/org/apache/poi/util/BlockingInputStream.java deleted file mode 100644 index 298c6aa7f..000000000 --- a/trunk/src/java/org/apache/poi/util/BlockingInputStream.java +++ /dev/null @@ -1,119 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import java.io.InputStream; -import java.io.IOException; - -/** - * Implementation of a BlockingInputStream to provide data to - * RawDataBlock that expects data in 512 byte chunks. Useful to read - * data from slow (ie, non FileInputStream) sources, for example when - * reading an OLE2 Document over a network. - * - * Possible extensions: add a timeout. Currently a call to read(byte[]) on this - * class is blocking, so use at your own peril if your underlying stream blocks. - * - * @author Jens Gerhard - * @author aviks - documentation cleanups. - */ -public class BlockingInputStream - extends InputStream -{ - protected InputStream is; - - public BlockingInputStream(InputStream is) - { - this.is = is; - } - - public int available() - throws IOException - { - return is.available(); - } - - public void close() - throws IOException - { - is.close(); - } - - public void mark(int readLimit) - { - is.mark(readLimit); - } - - public boolean markSupported() - { - return is.markSupported(); - } - - public int read() - throws IOException - { - return is.read(); - } - - /** - * We had to revert to byte per byte reading to keep - * with slow network connections on one hand, without - * missing the end-of-file. - * This is the only method that does its own thing in this class - * everything else is delegated to aggregated stream. - * THIS IS A BLOCKING BLOCK READ!!! - */ - public int read(byte[] bf) - throws IOException - { - - int i = 0; - int b = 4611; - while ( i < bf.length ) - { - b = is.read(); - if ( b == -1 ) - break; - bf[i++] = (byte) b; - } - if ( i == 0 && b == -1 ) - return -1; - return i; - } - - public int read(byte[] bf, int s, int l) - throws IOException - { - return is.read(bf, s, l); - } - - public void reset() - throws IOException - { - is.reset(); - } - - public long skip(long n) - throws IOException - { - return is.skip(n); - } -} - diff --git a/trunk/src/java/org/apache/poi/util/BoundedInputStream.java b/trunk/src/java/org/apache/poi/util/BoundedInputStream.java deleted file mode 100644 index 78121163b..000000000 --- a/trunk/src/java/org/apache/poi/util/BoundedInputStream.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.poi.util; - -import java.io.IOException; -import java.io.InputStream; - -/** - * This is a stream that will only supply bytes up to a certain length - if its - * position goes above that, it will stop. - *

        - * This is useful to wrap ServletInputStreams. The ServletInputStream will block - * if you try to read content from it that isn't there, because it doesn't know - * whether the content hasn't arrived yet or whether the content has finished. - * So, one of these, initialized with the Content-length sent in the - * ServletInputStream's header, will stop it blocking, providing it's been sent - * with a correct content length. - * - * @version $Id$ - * @since Commons IO 2.0 - */ -public class BoundedInputStream extends InputStream { - - /** the wrapped input stream */ - private final InputStream in; - - /** the max length to provide */ - private final long max; - - /** the number of bytes already returned */ - private long pos = 0; - - /** the marked position */ - private long mark = -1; - - /** flag if close shoud be propagated */ - private boolean propagateClose = true; - - /** - * Creates a new BoundedInputStream that wraps the given input - * stream and limits it to a certain size. - * - * @param in The wrapped input stream - * @param size The maximum number of bytes to return - */ - public BoundedInputStream(InputStream in, long size) { - // Some badly designed methods - eg the servlet API - overload length - // such that "-1" means stream finished - this.max = size; - this.in = in; - } - - /** - * Creates a new BoundedInputStream that wraps the given input - * stream and is unlimited. - * - * @param in The wrapped input stream - */ - public BoundedInputStream(InputStream in) { - this(in, -1); - } - - /** - * Invokes the delegate's read() method if - * the current position is less than the limit. - * @return the byte read or -1 if the end of stream or - * the limit has been reached. - * @throws IOException if an I/O error occurs - */ - @Override - public int read() throws IOException { - if (max>=0 && pos==max) { - return -1; - } - int result = in.read(); - pos++; - return result; - } - - /** - * Invokes the delegate's read(byte[]) method. - * @param b the buffer to read the bytes into - * @return the number of bytes read or -1 if the end of stream or - * the limit has been reached. - * @throws IOException if an I/O error occurs - */ - @Override - public int read(byte[] b) throws IOException { - return this.read(b, 0, b.length); - } - - /** - * Invokes the delegate's read(byte[], int, int) method. - * @param b the buffer to read the bytes into - * @param off The start offset - * @param len The number of bytes to read - * @return the number of bytes read or -1 if the end of stream or - * the limit has been reached. - * @throws IOException if an I/O error occurs - */ - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (max>=0 && pos>=max) { - return -1; - } - long maxRead = max>=0 ? Math.min(len, max-pos) : len; - int bytesRead = in.read(b, off, (int)maxRead); - - if (bytesRead==-1) { - return -1; - } - - pos+=bytesRead; - return bytesRead; - } - - /** - * Invokes the delegate's skip(long) method. - * @param n the number of bytes to skip - * @return the actual number of bytes skipped - * @throws IOException if an I/O error occurs - */ - @Override - public long skip(long n) throws IOException { - long toSkip = max>=0 ? Math.min(n, max-pos) : n; - long skippedBytes = in.skip(toSkip); - pos+=skippedBytes; - return skippedBytes; - } - - /** - * {@inheritDoc} - */ - @Override - public int available() throws IOException { - if (max>=0 && pos>=max) { - return 0; - } - return in.available(); - } - - /** - * Invokes the delegate's toString() method. - * @return the delegate's toString() - */ - @Override - public String toString() { - return in.toString(); - } - - /** - * Invokes the delegate's close() method - * if {@link #isPropagateClose()} is true. - * @throws IOException if an I/O error occurs - */ - @Override - public void close() throws IOException { - if (propagateClose) { - in.close(); - } - } - - /** - * Invokes the delegate's reset() method. - * @throws IOException if an I/O error occurs - */ - @Override - public synchronized void reset() throws IOException { - in.reset(); - pos = mark; - } - - /** - * Invokes the delegate's mark(int) method. - * @param readlimit read ahead limit - */ - @Override - public synchronized void mark(int readlimit) { - in.mark(readlimit); - mark = pos; - } - - /** - * Invokes the delegate's markSupported() method. - * @return true if mark is supported, otherwise false - */ - @Override - public boolean markSupported() { - return in.markSupported(); - } - - /** - * Indicates whether the {@link #close()} method - * should propagate to the underling {@link InputStream}. - * - * @return true if calling {@link #close()} - * propagates to the close() method of the - * underlying stream or false if it does not. - */ - public boolean isPropagateClose() { - return propagateClose; - } - - /** - * Set whether the {@link #close()} method - * should propagate to the underling {@link InputStream}. - * - * @param propagateClose true if calling - * {@link #close()} propagates to the close() - * method of the underlying stream or - * false if it does not. - */ - public void setPropagateClose(boolean propagateClose) { - this.propagateClose = propagateClose; - } -} diff --git a/trunk/src/java/org/apache/poi/util/ByteField.java b/trunk/src/java/org/apache/poi/util/ByteField.java deleted file mode 100644 index ca6227791..000000000 --- a/trunk/src/java/org/apache/poi/util/ByteField.java +++ /dev/null @@ -1,225 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import org.apache.poi.util.LittleEndian.BufferUnderrunException; - -import java.io.*; -import java.nio.BufferUnderflowException; - -/** - * representation of a byte (8-bit) field at a fixed location within a - * byte array - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public class ByteField - implements FixedField -{ - private static final byte _default_value = 0; - private byte _value; - private final int _offset; - - /** - * construct the ByteField with its offset into its containing - * byte array and a default value of 0 - * - * @param offset of the field within its byte array - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public ByteField(final int offset) - throws ArrayIndexOutOfBoundsException - { - this(offset, _default_value); - } - - /** - * construct the ByteField with its offset into its containing - * byte array and initialize its value - * - * @param offset of the field within its byte array - * @param value the initial value - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public ByteField(final int offset, final byte value) - throws ArrayIndexOutOfBoundsException - { - if (offset < 0) - { - throw new ArrayIndexOutOfBoundsException( - "offset cannot be negative"); - } - _offset = offset; - set(value); - } - - /** - * Construct the ByteField with its offset into its containing - * byte array and initialize its value from its byte array - * - * @param offset of the field within its byte array - * @param data the byte array to read the value from - * - * @exception ArrayIndexOutOfBoundsException if the offset is not - * within the range of 0..(data.length - 1) - */ - - public ByteField(final int offset, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - readFromBytes(data); - } - - /** - * construct the ByteField with its offset into its containing - * byte array, initialize its value, and write its value to its - * byte array - * - * @param offset of the field within its byte array - * @param value the initial value - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if the offset is not - * within the range of 0..(data.length - 1) - */ - - public ByteField(final int offset, final byte value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset, value); - writeToBytes(data); - } - - /** - * get the ByteField's current value - * - * @return current value - */ - - public byte get() - { - return _value; - } - - /** - * set the ByteField's current value - * - * @param value to be set - */ - - public void set(final byte value) - { - _value = value; - } - - /** - * set the ByteField's current value and write it to a byte array - * - * @param value to be set - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of the byte array's range - */ - - public void set(final byte value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - set(value); - writeToBytes(data); - } - - /* ********** START implementation of FixedField ********** */ - - /** - * set the value from its offset into an array of bytes - * - * @param data the byte array from which the value is to be read - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range of the bte array - */ - - public void readFromBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = data[ _offset ]; - } - - /** - * set the value from an InputStream - * - * @param stream the InputStream from which the value is to be - * read - * - * @exception BufferUnderrunException if there is not enough data - * available from the InputStream - * @exception IOException if an IOException is thrown from reading - * the InputStream - */ - - public void readFromStream(final InputStream stream) - throws IOException - { - // TODO - are these ~Field used / necessary - int ib = stream.read(); - if (ib < 0) { - throw new BufferUnderflowException(); - } - _value = (byte) ib; - } - - /** - * write the value out to an array of bytes at the appropriate - * offset - * - * @param data the array of bytes to which the value is to be - * written - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of the byte array's range - */ - - public void writeToBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - data[ _offset ] = _value; - } - - /** - * return the value as a String - * - * @return the value as a String - */ - - public String toString() - { - return String.valueOf(_value); - } - - /* ********** END implementation of FixedField ********** */ -} // end public class ByteField - diff --git a/trunk/src/java/org/apache/poi/util/CloseIgnoringInputStream.java b/trunk/src/java/org/apache/poi/util/CloseIgnoringInputStream.java deleted file mode 100644 index 82247b13a..000000000 --- a/trunk/src/java/org/apache/poi/util/CloseIgnoringInputStream.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.FilterInputStream; -import java.io.InputStream; - -/** - * A wrapper around an {@link InputStream}, which - * ignores close requests made to it. - * - * Useful with {@link org.apache.poi.poifs.filesystem.POIFSFileSystem}, where you want - * to control the close yourself. - */ -public class CloseIgnoringInputStream extends FilterInputStream { - public CloseIgnoringInputStream(InputStream in) { - super(in); - } - - public void close() { - // Does nothing and ignores closing the wrapped stream - } -} diff --git a/trunk/src/java/org/apache/poi/util/CodePageUtil.java b/trunk/src/java/org/apache/poi/util/CodePageUtil.java deleted file mode 100644 index 145929182..000000000 --- a/trunk/src/java/org/apache/poi/util/CodePageUtil.java +++ /dev/null @@ -1,443 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.UnsupportedEncodingException; - -/** - * Utilities for working with Microsoft CodePages. - * - *

        Provides constants for understanding numeric codepages, - * along with utilities to translate these into Java Character Sets.

        - */ -public class CodePageUtil -{ - /**

        Codepage 037, a special case

        */ - public static final int CP_037 = 37; - - /**

        Codepage for SJIS

        */ - public static final int CP_SJIS = 932; - - /**

        Codepage for GBK, aka MS936

        */ - public static final int CP_GBK = 936; - - /**

        Codepage for MS949

        */ - public static final int CP_MS949 = 949; - - /**

        Codepage for UTF-16

        */ - public static final int CP_UTF16 = 1200; - - /**

        Codepage for UTF-16 big-endian

        */ - public static final int CP_UTF16_BE = 1201; - - /**

        Codepage for Windows 1250

        */ - public static final int CP_WINDOWS_1250 = 1250; - - /**

        Codepage for Windows 1251

        */ - public static final int CP_WINDOWS_1251 = 1251; - - /**

        Codepage for Windows 1252

        */ - public static final int CP_WINDOWS_1252 = 1252; - public static final int CP_WINDOWS_1252_BIFF23 = 32769; - - /**

        Codepage for Windows 1253

        */ - public static final int CP_WINDOWS_1253 = 1253; - - /**

        Codepage for Windows 1254

        */ - public static final int CP_WINDOWS_1254 = 1254; - - /**

        Codepage for Windows 1255

        */ - public static final int CP_WINDOWS_1255 = 1255; - - /**

        Codepage for Windows 1256

        */ - public static final int CP_WINDOWS_1256 = 1256; - - /**

        Codepage for Windows 1257

        */ - public static final int CP_WINDOWS_1257 = 1257; - - /**

        Codepage for Windows 1258

        */ - public static final int CP_WINDOWS_1258 = 1258; - - /**

        Codepage for Johab

        */ - public static final int CP_JOHAB = 1361; - - /**

        Codepage for Macintosh Roman (Java: MacRoman)

        */ - public static final int CP_MAC_ROMAN = 10000; - public static final int CP_MAC_ROMAN_BIFF23 = 32768; - - /**

        Codepage for Macintosh Japan (Java: unknown - use SJIS, cp942 or - * cp943)

        */ - public static final int CP_MAC_JAPAN = 10001; - - /**

        Codepage for Macintosh Chinese Traditional (Java: unknown - use Big5, - * MS950, or cp937)

        */ - public static final int CP_MAC_CHINESE_TRADITIONAL = 10002; - - /**

        Codepage for Macintosh Korean (Java: unknown - use EUC_KR or - * cp949)

        */ - public static final int CP_MAC_KOREAN = 10003; - - /**

        Codepage for Macintosh Arabic (Java: MacArabic)

        */ - public static final int CP_MAC_ARABIC = 10004; - - /**

        Codepage for Macintosh Hebrew (Java: MacHebrew)

        */ - public static final int CP_MAC_HEBREW = 10005; - - /**

        Codepage for Macintosh Greek (Java: MacGreek)

        */ - public static final int CP_MAC_GREEK = 10006; - - /**

        Codepage for Macintosh Cyrillic (Java: MacCyrillic)

        */ - public static final int CP_MAC_CYRILLIC = 10007; - - /**

        Codepage for Macintosh Chinese Simplified (Java: unknown - use - * EUC_CN, ISO2022_CN_GB, MS936 or cp935)

        */ - public static final int CP_MAC_CHINESE_SIMPLE = 10008; - - /**

        Codepage for Macintosh Romanian (Java: MacRomania)

        */ - public static final int CP_MAC_ROMANIA = 10010; - - /**

        Codepage for Macintosh Ukrainian (Java: MacUkraine)

        */ - public static final int CP_MAC_UKRAINE = 10017; - - /**

        Codepage for Macintosh Thai (Java: MacThai)

        */ - public static final int CP_MAC_THAI = 10021; - - /**

        Codepage for Macintosh Central Europe (Latin-2) - * (Java: MacCentralEurope)

        */ - public static final int CP_MAC_CENTRAL_EUROPE = 10029; - - /**

        Codepage for Macintosh Iceland (Java: MacIceland)

        */ - public static final int CP_MAC_ICELAND = 10079; - - /**

        Codepage for Macintosh Turkish (Java: MacTurkish)

        */ - public static final int CP_MAC_TURKISH = 10081; - - /**

        Codepage for Macintosh Croatian (Java: MacCroatian)

        */ - public static final int CP_MAC_CROATIAN = 10082; - - /**

        Codepage for US-ASCII

        */ - public static final int CP_US_ACSII = 20127; - - /**

        Codepage for KOI8-R

        */ - public static final int CP_KOI8_R = 20866; - - /**

        Codepage for ISO-8859-1

        */ - public static final int CP_ISO_8859_1 = 28591; - - /**

        Codepage for ISO-8859-2

        */ - public static final int CP_ISO_8859_2 = 28592; - - /**

        Codepage for ISO-8859-3

        */ - public static final int CP_ISO_8859_3 = 28593; - - /**

        Codepage for ISO-8859-4

        */ - public static final int CP_ISO_8859_4 = 28594; - - /**

        Codepage for ISO-8859-5

        */ - public static final int CP_ISO_8859_5 = 28595; - - /**

        Codepage for ISO-8859-6

        */ - public static final int CP_ISO_8859_6 = 28596; - - /**

        Codepage for ISO-8859-7

        */ - public static final int CP_ISO_8859_7 = 28597; - - /**

        Codepage for ISO-8859-8

        */ - public static final int CP_ISO_8859_8 = 28598; - - /**

        Codepage for ISO-8859-9

        */ - public static final int CP_ISO_8859_9 = 28599; - - /**

        Codepage for ISO-2022-JP

        */ - public static final int CP_ISO_2022_JP1 = 50220; - - /**

        Another codepage for ISO-2022-JP

        */ - public static final int CP_ISO_2022_JP2 = 50221; - - /**

        Yet another codepage for ISO-2022-JP

        */ - public static final int CP_ISO_2022_JP3 = 50222; - - /**

        Codepage for ISO-2022-KR

        */ - public static final int CP_ISO_2022_KR = 50225; - - /**

        Codepage for EUC-JP

        */ - public static final int CP_EUC_JP = 51932; - - /**

        Codepage for EUC-KR

        */ - public static final int CP_EUC_KR = 51949; - - /**

        Codepage for GB2312

        */ - public static final int CP_GB2312 = 52936; - - /**

        Codepage for GB18030

        */ - public static final int CP_GB18030 = 54936; - - /**

        Another codepage for US-ASCII

        */ - public static final int CP_US_ASCII2 = 65000; - - /**

        Codepage for UTF-8

        */ - public static final int CP_UTF8 = 65001; - - /**

        Codepage for Unicode

        */ - public static final int CP_UNICODE = CP_UTF16; - - /** - * Converts a string into bytes, in the equivalent character encoding - * to the supplied codepage number. - * @param string The string to convert - * @param codepage The codepage number - */ - public static byte[] getBytesInCodePage(final String string, final int codepage) - throws UnsupportedEncodingException - { - String encoding = codepageToEncoding(codepage); - return string.getBytes(encoding); - } - - /** - * Converts the bytes into a String, based on the equivalent character encoding - * to the supplied codepage number. - * @param string The byte of the string to convert - * @param codepage The codepage number - */ - public static String getStringFromCodePage(final byte[] string, final int codepage) - throws UnsupportedEncodingException - { - return getStringFromCodePage(string, 0, string.length, codepage); - } - - /** - * Converts the bytes into a String, based on the equivalent character encoding - * to the supplied codepage number. - * @param string The byte of the string to convert - * @param codepage The codepage number - */ - public static String getStringFromCodePage(final byte[] string, final int offset, - final int length, final int codepage) throws UnsupportedEncodingException - { - String encoding = codepageToEncoding(codepage); - return new String(string, offset, length, encoding); - } - - /** - *

        Turns a codepage number into the equivalent character encoding's - * name (in Java NIO canonical naming format).

        - * - * @param codepage The codepage number - * - * @return The character encoding's name. If the codepage number is 65001, - * the encoding name is "UTF-8". All other positive numbers are mapped to - * their Java NIO names, normally either "windows-" followed by the number, - * eg "windows-1251", or "cp" followed by the number, e.g. if the codepage - * number is 1252 the returned character encoding name will be "cp1252". - * - * @exception UnsupportedEncodingException if the specified codepage is - * less than zero. - */ - public static String codepageToEncoding(final int codepage) - throws UnsupportedEncodingException - { - return codepageToEncoding(codepage, false); - } - - /** - *

        Turns a codepage number into the equivalent character encoding's - * name, in either Java NIO or Java Lang canonical naming.

        - * - * @param codepage The codepage number - * @param javaLangFormat Should Java Lang or Java NIO naming be used? - * - * @return The character encoding's name, in either Java Lang format - * (eg Cp1251, ISO8859_5) or Java NIO format (eg windows-1252, ISO-8859-9) - * - * @see Supported Encodings - * - * @exception UnsupportedEncodingException if the specified codepage is - * less than zero. - */ - public static String codepageToEncoding(final int codepage, boolean javaLangFormat) - throws UnsupportedEncodingException - { - if (codepage <= 0) - throw new UnsupportedEncodingException("Codepage number may not be " + codepage); - - switch (codepage) { - case CP_UTF16: - return "UTF-16"; - case CP_UTF16_BE: - return "UTF-16BE"; - case CP_UTF8: - return "UTF-8"; - case CP_037: - return "cp037"; - case CP_GBK: - return "GBK"; - case CP_MS949: - return "ms949"; - case CP_WINDOWS_1250: - if (javaLangFormat) - return "Cp1250"; - else - return "windows-1250"; - case CP_WINDOWS_1251: - if (javaLangFormat) - return "Cp1251"; - else - return "windows-1251"; - case CP_WINDOWS_1252: - case CP_WINDOWS_1252_BIFF23: - if (javaLangFormat) - return "Cp1252"; - else - return "windows-1252"; - case CP_WINDOWS_1253: - if (javaLangFormat) - return "Cp1253"; - else - return "windows-1253"; - case CP_WINDOWS_1254: - if (javaLangFormat) - return "Cp1254"; - else - return "windows-1254"; - case CP_WINDOWS_1255: - if (javaLangFormat) - return "Cp1255"; - else - return "windows-1255"; - case CP_WINDOWS_1256: - if (javaLangFormat) - return "Cp1255"; - else - return "windows-1256"; - case CP_WINDOWS_1257: - if (javaLangFormat) - return "Cp1257"; - else - return "windows-1257"; - case CP_WINDOWS_1258: - if (javaLangFormat) - return "Cp1258"; - else - return "windows-1258"; - case CP_JOHAB: - return "johab"; - case CP_MAC_ROMAN: - case CP_MAC_ROMAN_BIFF23: - return "MacRoman"; - case CP_MAC_JAPAN: - return "SJIS"; - case CP_MAC_CHINESE_TRADITIONAL: - return "Big5"; - case CP_MAC_KOREAN: - return "EUC-KR"; - case CP_MAC_ARABIC: - return "MacArabic"; - case CP_MAC_HEBREW: - return "MacHebrew"; - case CP_MAC_GREEK: - return "MacGreek"; - case CP_MAC_CYRILLIC: - return "MacCyrillic"; - case CP_MAC_CHINESE_SIMPLE: - return "EUC_CN"; - case CP_MAC_ROMANIA: - return "MacRomania"; - case CP_MAC_UKRAINE: - return "MacUkraine"; - case CP_MAC_THAI: - return "MacThai"; - case CP_MAC_CENTRAL_EUROPE: - return "MacCentralEurope"; - case CP_MAC_ICELAND: - return "MacIceland"; - case CP_MAC_TURKISH: - return "MacTurkish"; - case CP_MAC_CROATIAN: - return "MacCroatian"; - case CP_US_ACSII: - case CP_US_ASCII2: - return "US-ASCII"; - case CP_KOI8_R: - return "KOI8-R"; - case CP_ISO_8859_1: - if (javaLangFormat) - return "ISO8859_1"; - else - return "ISO-8859-1"; - case CP_ISO_8859_2: - if (javaLangFormat) - return "ISO8859_2"; - else - return "ISO-8859-2"; - case CP_ISO_8859_3: - if (javaLangFormat) - return "ISO8859_3"; - else - return "ISO-8859-3"; - case CP_ISO_8859_4: - if (javaLangFormat) - return "ISO8859_4"; - else - return "ISO-8859-4"; - case CP_ISO_8859_5: - if (javaLangFormat) - return "ISO8859_5"; - else - return "ISO-8859-5"; - case CP_ISO_8859_6: - if (javaLangFormat) - return "ISO8859_6"; - else - return "ISO-8859-6"; - case CP_ISO_8859_7: - if (javaLangFormat) - return "ISO8859_7"; - else - return "ISO-8859-7"; - case CP_ISO_8859_8: - if (javaLangFormat) - return "ISO8859_8"; - else - return "ISO-8859-8"; - case CP_ISO_8859_9: - if (javaLangFormat) - return "ISO8859_9"; - else - return "ISO-8859-9"; - case CP_ISO_2022_JP1: - case CP_ISO_2022_JP2: - case CP_ISO_2022_JP3: - return "ISO-2022-JP"; - case CP_ISO_2022_KR: - return "ISO-2022-KR"; - case CP_EUC_JP: - return "EUC-JP"; - case CP_EUC_KR: - return "EUC-KR"; - case CP_GB2312: - return "GB2312"; - case CP_GB18030: - return "GB18030"; - case CP_SJIS: - return "SJIS"; - default: - return "cp" + codepage; - } - } -} diff --git a/trunk/src/java/org/apache/poi/util/CommonsLogger.java b/trunk/src/java/org/apache/poi/util/CommonsLogger.java deleted file mode 100644 index a204fde17..000000000 --- a/trunk/src/java/org/apache/poi/util/CommonsLogger.java +++ /dev/null @@ -1,225 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A logger class that strives to make it as easy as possible for - * developers to write log calls, while simultaneously making those - * calls as cheap as possible by performing lazy evaluation of the log - * message.

        - */ -public class CommonsLogger extends POILogger -{ - private static final LogFactory _creator = LogFactory.getFactory(); - private Log log = null; - - @Override - public void initialize(final String cat) - { - this.log = _creator.getInstance(cat); - } - - /** - * Log a message - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param obj1 The object to log. - */ - @Override - protected void _log(final int level, final Object obj1) - { - // FIXME: What happens if level is in between two levels (an even number)? - // Should this be `if (level >= FATAL) ...`? - if(level==FATAL) - { - if(log.isFatalEnabled()) - { - log.fatal(obj1); - } - } - else if(level==ERROR) - { - if(log.isErrorEnabled()) - { - log.error(obj1); - } - } - else if(level==WARN) - { - if(log.isWarnEnabled()) - { - log.warn(obj1); - } - } - else if(level==INFO) - { - if(log.isInfoEnabled()) - { - log.info(obj1); - } - } - else if(level==DEBUG) - { - if(log.isDebugEnabled()) - { - log.debug(obj1); - } - } - else - { - if(log.isTraceEnabled()) - { - log.trace(obj1); - } - } - } - - /** - * Log a message - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param obj1 The object to log. This is converted to a string. - * @param exception An exception to be logged - */ - @Override - protected void _log(final int level, final Object obj1, - final Throwable exception) - { - // FIXME: What happens if level is in between two levels (an even number)? - // Should this be `if (level >= FATAL) ...`? - if(level==FATAL) - { - if(log.isFatalEnabled()) - { - if(obj1 != null) - log.fatal(obj1, exception); - else - log.fatal(exception); - } - } - else if(level==ERROR) - { - if(log.isErrorEnabled()) - { - if(obj1 != null) - log.error(obj1, exception); - else - log.error(exception); - } - } - else if(level==WARN) - { - if(log.isWarnEnabled()) - { - if(obj1 != null) - log.warn(obj1, exception); - else - log.warn(exception); - } - } - else if(level==INFO) - { - if(log.isInfoEnabled()) - { - if(obj1 != null) - log.info(obj1, exception); - else - log.info(exception); - } - } - else if(level==DEBUG) - { - if(log.isDebugEnabled()) - { - if(obj1 != null) - log.debug(obj1, exception); - else - log.debug(exception); - } - } - else - { - if(log.isTraceEnabled()) - { - if(obj1 != null) - log.trace(obj1, exception); - else - log.trace(exception); - } - } - - } - - /** - * Check if a logger is enabled to log at the specified level - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - */ - @Override - public boolean check(final int level) - { - // FIXME: What happens if level is in between two levels (an even number)? - // Should this be `if (level >= FATAL) ...`? - if(level==FATAL) - { - if(log.isFatalEnabled()) - { - return true; - } - } - else if(level==ERROR) - { - if(log.isErrorEnabled()) - { - return true; - } - } - else if(level==WARN) - { - if(log.isWarnEnabled()) - { - return true; - } - } - else if(level==INFO) - { - if(log.isInfoEnabled()) - { - return true; - } - } - else if(level==DEBUG) - { - if(log.isDebugEnabled()) - { - return true; - } - } - - return false; - - } - - -} // end package scope class POILogger - diff --git a/trunk/src/java/org/apache/poi/util/Configurator.java b/trunk/src/java/org/apache/poi/util/Configurator.java deleted file mode 100644 index 4c9651f8e..000000000 --- a/trunk/src/java/org/apache/poi/util/Configurator.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.apache.poi.util; - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/** - * Helper for fetching int values from system properties - */ -public class Configurator { - private static POILogger logger = POILogFactory.getLogger(Configurator.class); - - public static int getIntValue(String systemProperty, int defaultValue) { - int result = defaultValue; - String property = System.getProperty(systemProperty); - try { - result = Integer.parseInt(property); - } catch (Exception e) { - logger.log(POILogger.ERROR, "System property -D"+systemProperty +" do not contains a valid integer " + property); - } - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java b/trunk/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java deleted file mode 100644 index 6f4475287..000000000 --- a/trunk/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.File; -import java.io.IOException; -import java.security.SecureRandom; - -/** - * Default implementation of the {@link TempFileCreationStrategy} used by {@link TempFile}: - * Files are collected into one directory and by default are deleted on exit from the VM. - * Files may be manually deleted by user prior to JVM exit. - * Files can be kept by defining the system property {@link #KEEP_FILES}. - * - * Each file is registered for deletion with the JVM and the temporary directory is not deleted - * after the JVM exits. Files that are created in the poifiles directory outside - * the control of DefaultTempFileCreationStrategy are not deleted. - * See {@link TempFileCreationStrategy} for better strategies for long-running - * processes or limited temporary storage. - */ -public class DefaultTempFileCreationStrategy implements TempFileCreationStrategy { - /** Define a constant for this property as it is sometimes mistypes as "tempdir" otherwise - * This is private to avoid having two public-visible constants ({@link TempFile#JAVA_IO_TMPDIR}). */ - private static final String JAVA_IO_TMPDIR = TempFile.JAVA_IO_TMPDIR; - /*package*/ static final String POIFILES = "poifiles"; - - /** To keep files after JVM exit, set the -Dpoi.keep.tmp.files JVM property */ - public static final String KEEP_FILES = "poi.keep.tmp.files"; - - /** random number generator to generate unique filenames */ - private static final SecureRandom random = new SecureRandom(); - - /** The directory where the temporary files will be created (null to use the default directory). */ - private File dir; - - /** - * Creates the strategy so that it creates the temporary files in the default directory. - * - * @see File#createTempFile(String, String) - */ - public DefaultTempFileCreationStrategy() { - this(null); - } - - /** - * Creates the strategy allowing to set the - * - * @param dir The directory where the temporary files will be created (null to use the default directory). - * - * @see File#createTempFile(String, String, File) - */ - public DefaultTempFileCreationStrategy(File dir) { - this.dir = dir; - } - - private void createPOIFilesDirectory() throws IOException { - // Identify and create our temp dir, if needed - // The directory is not deleted, even if it was created by this TempFileCreationStrategy - if (dir == null) { - String tmpDir = System.getProperty(JAVA_IO_TMPDIR); - if (tmpDir == null) { - throw new IOException("Systems temporary directory not defined - set the -D"+JAVA_IO_TMPDIR+" jvm property!"); - } - dir = new File(tmpDir, POIFILES); - } - - createTempDirectory(dir); - } - - /** - * Attempt to create a directory, including any necessary parent directories. - * Does nothing if directory already exists. - * - * @param directory the directory to create - * @throws IOException if unable to create temporary directory or it is not a directory - */ - private void createTempDirectory(File directory) throws IOException { - // create directory if it doesn't exist - final boolean dirExists = (directory.exists() || directory.mkdirs()); - - if (!dirExists) { - throw new IOException("Could not create temporary directory '" + directory + "'"); - } - else if (!directory.isDirectory()) { - throw new IOException("Could not create temporary directory. '" + directory + "' exists but is not a directory."); - } - } - - @Override - public File createTempFile(String prefix, String suffix) throws IOException { - // Identify and create our temp dir, if needed - createPOIFilesDirectory(); - - // Generate a unique new filename - File newFile = File.createTempFile(prefix, suffix, dir); - - // Set the delete on exit flag, unless explicitly disabled - if (System.getProperty(KEEP_FILES) == null) { - newFile.deleteOnExit(); - } - - // All done - return newFile; - } - - /* (non-JavaDoc) Created directory path is /poifiles/prefix0123456789 */ - @Override - public File createTempDirectory(String prefix) throws IOException { - // Identify and create our temp dir, if needed - createPOIFilesDirectory(); - - // Generate a unique new filename - // FIXME: Java 7+: use java.nio.Files#createTempDirectory - final long n = random.nextLong(); - File newDirectory = new File(dir, prefix + Long.toString(n)); - createTempDirectory(newDirectory); - - // Set the delete on exit flag, unless explicitly disabled - if (System.getProperty(KEEP_FILES) == null) { - newDirectory.deleteOnExit(); - } - - // All done - return newDirectory; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java b/trunk/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java deleted file mode 100644 index 13282ac37..000000000 --- a/trunk/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; -/** - * Implementors of this interface allow client code to 'delay' writing to a certain section of a - * data output stream.
        - * A typical application is for writing BIFF records when the size is not known until well after - * the header has been written. The client code can call {@link #createDelayedOutput(int)} - * to reserve two bytes of the output for the 'ushort size' header field. The delayed output can - * be written at any stage. - * - * @author Josh Micich - */ -public interface DelayableLittleEndianOutput extends LittleEndianOutput { - /** - * Creates an output stream intended for outputting a sequence of size bytes. - */ - LittleEndianOutput createDelayedOutput(int size); -} diff --git a/trunk/src/java/org/apache/poi/util/DrawingDump.java b/trunk/src/java/org/apache/poi/util/DrawingDump.java deleted file mode 100644 index bc06bcfc1..000000000 --- a/trunk/src/java/org/apache/poi/util/DrawingDump.java +++ /dev/null @@ -1,57 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.nio.charset.Charset; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.ss.usermodel.Sheet; - -/** - * Dump out the aggregated escher records - */ -public class DrawingDump -{ - public static void main( String[] args ) throws IOException { - OutputStreamWriter osw = new OutputStreamWriter(System.out, Charset.defaultCharset()); - PrintWriter pw = new PrintWriter(osw); - NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(args[0])); - HSSFWorkbook wb = new HSSFWorkbook(fs); - try { - pw.println( "Drawing group:" ); - wb.dumpDrawingGroupRecords(true); - - int i = 1; - for (Sheet sheet : wb) - { - pw.println( "Sheet " + i + "(" + sheet.getSheetName() + "):" ); - ((HSSFSheet) sheet).dumpDrawingRecords(true, pw); - } - } finally { - wb.close(); - fs.close(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/util/FixedField.java b/trunk/src/java/org/apache/poi/util/FixedField.java deleted file mode 100644 index 45d6c6f71..000000000 --- a/trunk/src/java/org/apache/poi/util/FixedField.java +++ /dev/null @@ -1,84 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import org.apache.poi.util.LittleEndian.BufferUnderrunException; - -import java.io.*; - -/** - * behavior of a field at a fixed location within a byte array - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public interface FixedField -{ - - /** - * set the value from its offset into an array of bytes - * - * @param data the byte array from which the value is to be read - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of the array's valid index range - */ - - void readFromBytes(byte [] data) - throws ArrayIndexOutOfBoundsException; - - /** - * set the value from an InputStream - * - * @param stream the InputStream from which the value is to be - * read - * - * @exception BufferUnderrunException if there is not enough data - * available from the InputStream - * @exception IOException if an IOException is thrown from reading - * the InputStream - */ - - void readFromStream(InputStream stream) - throws IOException; - - /** - * write the value out to an array of bytes at the appropriate - * offset - * - * @param data the array of bytes to which the value is to be - * written - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of the array's valid index range - */ - - void writeToBytes(byte [] data) - throws ArrayIndexOutOfBoundsException; - - /** - * return the value as a String - * - * @return the value as a String - */ - - String toString(); -} // end public interface FixedField - diff --git a/trunk/src/java/org/apache/poi/util/FontMetricsDumper.java b/trunk/src/java/org/apache/poi/util/FontMetricsDumper.java deleted file mode 100644 index 514764657..000000000 --- a/trunk/src/java/org/apache/poi/util/FontMetricsDumper.java +++ /dev/null @@ -1,81 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.GraphicsEnvironment; -import java.awt.Toolkit; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Properties; - -@SuppressWarnings("deprecation") -public class FontMetricsDumper -{ - @SuppressForbidden("command line tool") - public static void main( String[] args ) throws IOException - { - - Properties props = new Properties(); - - Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); - for (Font allFont : allFonts) { - String fontName = allFont.getFontName(); - - Font font = new Font(fontName, Font.BOLD, 10); - FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font); - int fontHeight = fontMetrics.getHeight(); - - props.setProperty("font." + fontName + ".height", fontHeight + ""); - StringBuilder characters = new StringBuilder(); - for (char c = 'a'; c <= 'z'; c++) { - characters.append(c).append(", "); - } - for (char c = 'A'; c <= 'Z'; c++) { - characters.append(c).append(", "); - } - for (char c = '0'; c <= '9'; c++) { - characters.append(c).append(", "); - } - StringBuilder widths = new StringBuilder(); - for (char c = 'a'; c <= 'z'; c++) { - widths.append(fontMetrics.getWidths()[c]).append(", "); - } - for (char c = 'A'; c <= 'Z'; c++) { - widths.append(fontMetrics.getWidths()[c]).append(", "); - } - for (char c = '0'; c <= '9'; c++) { - widths.append(fontMetrics.getWidths()[c]).append(", "); - } - props.setProperty("font." + fontName + ".characters", characters.toString()); - props.setProperty("font." + fontName + ".widths", widths.toString()); - } - - FileOutputStream fileOut = new FileOutputStream("font_metrics.properties"); - try - { - props.store(fileOut, "Font Metrics"); - } - finally - { - fileOut.close(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/util/HexDump.java b/trunk/src/java/org/apache/poi/util/HexDump.java deleted file mode 100644 index 01a8f5091..000000000 --- a/trunk/src/java/org/apache/poi/util/HexDump.java +++ /dev/null @@ -1,419 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.nio.charset.Charset; - -import org.apache.commons.codec.CharEncoding; - -/** - * dump data in hexadecimal format - */ -@Internal -public class HexDump { - public static final String EOL = System.getProperty("line.separator"); - public static final Charset UTF8 = Charset.forName(CharEncoding.UTF_8); - - private HexDump() { - // all static methods, so no need for a public constructor - } - - /** - * dump an array of bytes to an OutputStream - * - * @param data the byte array to be dumped - * @param offset its offset, whatever that might mean - * @param stream the OutputStream to which the data is to be - * written - * @param index initial index into the byte array - * @param length number of characters to output - * - * @exception IOException is thrown if anything goes wrong writing - * the data to stream - * @exception ArrayIndexOutOfBoundsException if the index is - * outside the data array's bounds - * @exception IllegalArgumentException if the output stream is - * null - */ - public static void dump(final byte [] data, final long offset, - final OutputStream stream, final int index, final int length) - throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException { - if (stream == null) { - throw new IllegalArgumentException("cannot write to nullstream"); - } - - OutputStreamWriter osw = new OutputStreamWriter(stream, UTF8); - osw.write(dump(data, offset, index, length)); - osw.flush(); - } - - /** - * dump an array of bytes to an OutputStream - * - * @param data the byte array to be dumped - * @param offset its offset, whatever that might mean - * @param stream the OutputStream to which the data is to be - * written - * @param index initial index into the byte array - * - * @exception IOException is thrown if anything goes wrong writing - * the data to stream - * @exception ArrayIndexOutOfBoundsException if the index is - * outside the data array's bounds - * @exception IllegalArgumentException if the output stream is - * null - */ - - public synchronized static void dump(final byte [] data, final long offset, - final OutputStream stream, final int index) - throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException { - dump(data, offset, stream, index, Integer.MAX_VALUE); - } - - /** - * dump an array of bytes to a String - * - * @param data the byte array to be dumped - * @param offset its offset, whatever that might mean - * @param index initial index into the byte array - * - * @exception ArrayIndexOutOfBoundsException if the index is - * outside the data array's bounds - * @return output string - */ - - public static String dump(final byte [] data, final long offset, final int index) { - return dump(data, offset, index, Integer.MAX_VALUE); - } - - /** - * dump an array of bytes to a String - * - * @param data the byte array to be dumped - * @param offset its offset, whatever that might mean - * @param index initial index into the byte array - * @param length number of characters to output - * - * @exception ArrayIndexOutOfBoundsException if the index is - * outside the data array's bounds - * @return output string - */ - - public static String dump(final byte [] data, final long offset, final int index, final int length) { - if (data == null || data.length == 0) { - return "No Data"+EOL; - } - - int data_length = (length == Integer.MAX_VALUE || length < 0 || index+length < 0) - ? data.length - : Math.min(data.length,index+length); - - - if ((index < 0) || (index >= data.length)) { - String err = "illegal index: "+index+" into array of length "+data.length; - throw new ArrayIndexOutOfBoundsException(err); - } - - long display_offset = offset + index; - StringBuilder buffer = new StringBuilder(74); - - for (int j = index; j < data_length; j += 16) { - int chars_read = data_length - j; - - if (chars_read > 16) { - chars_read = 16; - } - - writeHex(buffer, display_offset, 8, ""); - for (int k = 0; k < 16; k++) { - if (k < chars_read) { - writeHex(buffer, data[ k + j ], 2, " "); - } else { - buffer.append(" "); - } - } - buffer.append(' '); - for (int k = 0; k < chars_read; k++) { - buffer.append(toAscii(data[ k + j ])); - } - buffer.append(EOL); - display_offset += chars_read; - } - return buffer.toString(); - } - - public static char toAscii(int dataB) { - char charB = (char)(dataB & 0xFF); - if (Character.isISOControl(charB)) return '.'; - - switch (charB) { - // printable, but not compilable with current compiler encoding - case 0xFF: - case 0xDD: - charB = '.'; - break; - default: - break; - } - return charB; - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert - * @return A String representing the array of bytes - */ - public static String toHex(final byte[] value) - { - StringBuilder retVal = new StringBuilder(); - retVal.append('['); - if (value != null && value.length > 0) - { - for(int x = 0; x < value.length; x++) - { - if (x>0) { - retVal.append(", "); - } - retVal.append(toHex(value[x])); - } - } - retVal.append(']'); - return retVal.toString(); - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert - * @return A String representing the array of shorts - */ - public static String toHex(final short[] value) - { - StringBuilder retVal = new StringBuilder(); - retVal.append('['); - for(int x = 0; x < value.length; x++) - { - if (x>0) { - retVal.append(", "); - } - retVal.append(toHex(value[x])); - } - retVal.append(']'); - return retVal.toString(); - } - - /** - *

        Converts the parameter to a hex value breaking the results into - * lines.

        - * - * @param value The value to convert - * @param bytesPerLine The maximum number of bytes per line. The next byte - * will be written to a new line - * @return A String representing the array of bytes - */ - public static String toHex(final byte[] value, final int bytesPerLine) { - if (value.length == 0) { - return ": 0"; - } - final int digits = (int) Math.round(Math.log(value.length) / Math.log(10) + 0.5); - StringBuilder retVal = new StringBuilder(); - writeHex(retVal, 0, digits, ""); - retVal.append(": "); - for(int x=0, i=-1; x < value.length; x++) { - if (++i == bytesPerLine) { - retVal.append('\n'); - writeHex(retVal, x, digits, ""); - retVal.append(": "); - i = 0; - } else if (x>0) { - retVal.append(", "); - } - retVal.append(toHex(value[x])); - } - return retVal.toString(); - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert - * @return The result right padded with 0 - */ - public static String toHex(short value) { - StringBuilder sb = new StringBuilder(4); - writeHex(sb, value & 0xFFFF, 4, ""); - return sb.toString(); - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert - * @return The result right padded with 0 - */ - public static String toHex(byte value) { - StringBuilder sb = new StringBuilder(2); - writeHex(sb, value & 0xFF, 2, ""); - return sb.toString(); - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert - * @return The result right padded with 0 - */ - public static String toHex(int value) { - StringBuilder sb = new StringBuilder(8); - writeHex(sb, value & 0xFFFFFFFFL, 8, ""); - return sb.toString(); - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert - * @return The result right padded with 0 - */ - public static String toHex(long value) { - StringBuilder sb = new StringBuilder(16); - writeHex(sb, value, 16, ""); - return sb.toString(); - } - - /** - * Converts the string to a string of hex values. - * - * @param value The value to convert - * @return The resulted hex string - */ - public static String toHex(String value) { - return (value == null || value.length() == 0) - ? "[]" - : toHex(value.getBytes(LocaleUtil.CHARSET_1252)); - } - - /** - * Dumps bytesToDump bytes to an output stream. - * - * @param in The stream to read from - * @param out The output stream - * @param start The index to use as the starting position for the left hand side label - * @param bytesToDump The number of bytes to output. Use -1 to read until the end of file. - */ - public static void dump( InputStream in, PrintStream out, int start, int bytesToDump ) throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - if (bytesToDump == -1) - { - int c = in.read(); - while (c != -1) - { - buf.write(c); - c = in.read(); - } - } - else - { - int bytesRemaining = bytesToDump; - while (bytesRemaining-- > 0) - { - int c = in.read(); - if (c == -1) { - break; - } - buf.write(c); - } - } - - byte[] data = buf.toByteArray(); - dump(data, 0, out, start, data.length); - } - - /** - * @return string of 16 (zero padded) uppercase hex chars and prefixed with '0x' - */ - public static String longToHex(long value) { - StringBuilder sb = new StringBuilder(18); - writeHex(sb, value, 16, "0x"); - return sb.toString(); - } - - /** - * @return string of 8 (zero padded) uppercase hex chars and prefixed with '0x' - */ - public static String intToHex(int value) { - StringBuilder sb = new StringBuilder(10); - writeHex(sb, value & 0xFFFFFFFFL, 8, "0x"); - return sb.toString(); - } - - /** - * @return string of 4 (zero padded) uppercase hex chars and prefixed with '0x' - */ - public static String shortToHex(int value) { - StringBuilder sb = new StringBuilder(6); - writeHex(sb, value & 0xFFFFL, 4, "0x"); - return sb.toString(); - } - - /** - * @return string of 2 (zero padded) uppercase hex chars and prefixed with '0x' - */ - public static String byteToHex(int value) { - StringBuilder sb = new StringBuilder(4); - writeHex(sb, value & 0xFFL, 2, "0x"); - return sb.toString(); - } - - /** - * @see Integer#toHexString(int) - * @see Long#toHexString(long) - */ - private static void writeHex(StringBuilder sb, long value, int nDigits, String prefix) { - sb.append(prefix); - char[] buf = new char[nDigits]; - long acc = value; - for(int i=nDigits-1; i>=0; i--) { - int digit = (int)(acc & 0x0F); - buf[i] = (char) (digit < 10 ? ('0' + digit) : ('A' + digit - 10)); - acc >>>= 4; - } - sb.append(buf); - } - - - public static void main(String[] args) throws Exception { - File file = new File(args[0]); - InputStream in = new BufferedInputStream(new FileInputStream(file)); - byte[] b = new byte[(int)file.length()]; - in.read(b); - System.out.println(HexDump.dump(b, 0, 0)); - in.close(); - } -} diff --git a/trunk/src/java/org/apache/poi/util/HexRead.java b/trunk/src/java/org/apache/poi/util/HexRead.java deleted file mode 100644 index 4d9ac9752..000000000 --- a/trunk/src/java/org/apache/poi/util/HexRead.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.*; -import java.util.List; -import java.util.ArrayList; - -/** - * Utilities to read hex from files. - * TODO - move to test packages - */ -public class HexRead -{ - /** - * This method reads hex data from a filename and returns a byte array. - * The file may contain line comments that are preceeded with a # symbol. - * - * @param filename The filename to read - * @return The bytes read from the file. - * @throws IOException If there was a problem while reading the file. - */ - public static byte[] readData( String filename ) throws IOException - { - File file = new File( filename ); - FileInputStream stream = new FileInputStream( file ); - try - { - return readData( stream, -1 ); - } - finally - { - stream.close(); - } - } - - /** - * Same as readData(String) except that this method allows you to specify sections within - * a file. Sections are referenced using section headers in the form: - *
        -     *  [sectioname]
        -     * 
        - * - * @see #readData(String) - */ - public static byte[] readData(InputStream stream, String section ) throws IOException { - - try - { - StringBuffer sectionText = new StringBuffer(); - boolean inSection = false; - int c = stream.read(); - while ( c != -1 ) - { - switch ( c ) - { - case '[': - inSection = true; - break; - case '\n': - case '\r': - inSection = false; - sectionText = new StringBuffer(); - break; - case ']': - inSection = false; - if ( sectionText.toString().equals( section ) ) return readData( stream, '[' ); - sectionText = new StringBuffer(); - break; - default: - if ( inSection ) sectionText.append( (char) c ); - } - c = stream.read(); - } - } - finally - { - stream.close(); - } - throw new IOException( "Section '" + section + "' not found" ); - } - public static byte[] readData( String filename, String section ) throws IOException - { - File file = new File( filename ); - FileInputStream stream = new FileInputStream( file ); - return readData(stream, section); - } - - @SuppressWarnings("fallthrough") - static public byte[] readData( InputStream stream, int eofChar ) - throws IOException - { - int characterCount = 0; - byte b = (byte) 0; - List bytes = new ArrayList(); - final char a = 'a' - 10; - final char A = 'A' - 10; - while ( true ) - { - int count = stream.read(); - int digitValue = -1; - if ( '0' <= count && count <= '9' ) { - digitValue = count - '0'; - } else if ( 'A' <= count && count <= 'F' ) { - digitValue = count - A; - } else if ( 'a' <= count && count <= 'f' ) { - digitValue = count - a; - } else if ( '#' == count ) { - readToEOL( stream ); - } else if ( -1 == count || eofChar == count ) { - break; - } - // else: ignore the character - - if (digitValue != -1) { - b <<= 4; - b += (byte) digitValue; - characterCount++; - if ( characterCount == 2 ) - { - bytes.add( Byte.valueOf( b ) ); - characterCount = 0; - b = (byte) 0; - } - } - } - Byte[] polished = bytes.toArray(new Byte[bytes.size()]); - byte[] rval = new byte[polished.length]; - for ( int j = 0; j < polished.length; j++ ) - { - rval[j] = polished[j].byteValue(); - } - return rval; - } - - static public byte[] readFromString(String data) { - try { - return readData(new ByteArrayInputStream( data.getBytes(StringUtil.UTF8) ), -1); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - static private void readToEOL( InputStream stream ) throws IOException - { - int c = stream.read(); - while ( c != -1 && c != '\n' && c != '\r' ) - { - c = stream.read(); - } - } -} diff --git a/trunk/src/java/org/apache/poi/util/IOUtils.java b/trunk/src/java/org/apache/poi/util/IOUtils.java deleted file mode 100644 index 2f61fd1d7..000000000 --- a/trunk/src/java/org/apache/poi/util/IOUtils.java +++ /dev/null @@ -1,238 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PushbackInputStream; -import java.nio.ByteBuffer; -import java.nio.channels.ReadableByteChannel; -import java.util.zip.CRC32; -import java.util.zip.Checksum; - -import org.apache.poi.EmptyFileException; - -public final class IOUtils { - private static final POILogger logger = POILogFactory.getLogger( IOUtils.class ); - - private IOUtils() { - // no instances of this class - } - - /** - * Peeks at the first 8 bytes of the stream. Returns those bytes, but - * with the stream unaffected. Requires a stream that supports mark/reset, - * or a PushbackInputStream. If the stream has >0 but <8 bytes, - * remaining bytes will be zero. - * @throws EmptyFileException if the stream is empty - */ - public static byte[] peekFirst8Bytes(InputStream stream) throws IOException, EmptyFileException { - // We want to peek at the first 8 bytes - stream.mark(8); - - byte[] header = new byte[8]; - int read = IOUtils.readFully(stream, header); - - if (read < 1) - throw new EmptyFileException(); - - // Wind back those 8 bytes - if(stream instanceof PushbackInputStream) { - PushbackInputStream pin = (PushbackInputStream)stream; - pin.unread(header, 0, read); - } else { - stream.reset(); - } - - return header; - } - - /** - * Reads all the data from the input stream, and returns the bytes read. - */ - public static byte[] toByteArray(InputStream stream) throws IOException { - return toByteArray(stream, Integer.MAX_VALUE); - } - - /** - * Reads up to {@code length} bytes from the input stream, and returns the bytes read. - */ - public static byte[] toByteArray(InputStream stream, int length) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(length == Integer.MAX_VALUE ? 4096 : length); - - byte[] buffer = new byte[4096]; - int totalBytes = 0, readBytes; - do { - readBytes = stream.read(buffer, 0, Math.min(buffer.length, length-totalBytes)); - totalBytes += Math.max(readBytes,0); - if (readBytes > 0) { - baos.write(buffer, 0, readBytes); - } - } while (totalBytes < length && readBytes > -1); - - if (length != Integer.MAX_VALUE && totalBytes < length) { - throw new IOException("unexpected EOF"); - } - - return baos.toByteArray(); - } - - - /** - * Returns an array (that shouldn't be written to!) of the - * ByteBuffer. Will be of the requested length, or possibly - * longer if that's easier. - */ - public static byte[] toByteArray(ByteBuffer buffer, int length) { - if(buffer.hasArray() && buffer.arrayOffset() == 0) { - // The backing array should work out fine for us - return buffer.array(); - } - - byte[] data = new byte[length]; - buffer.get(data); - return data; - } - - /** - * Helper method, just calls readFully(in, b, 0, b.length) - */ - public static int readFully(InputStream in, byte[] b) throws IOException { - return readFully(in, b, 0, b.length); - } - - /** - *

        Same as the normal {@link InputStream#read(byte[], int, int)}, but tries to ensure - * that the entire len number of bytes is read.

        - * - *

        If the end of file is reached before any bytes are read, returns -1. If - * the end of the file is reached after some bytes are read, returns the - * number of bytes read. If the end of the file isn't reached before len - * bytes have been read, will return len bytes.

        - * - * @param in the stream from which the data is read. - * @param b the buffer into which the data is read. - * @param off the start offset in array b at which the data is written. - * @param len the maximum number of bytes to read. - */ - public static int readFully(InputStream in, byte[] b, int off, int len) throws IOException { - int total = 0; - while (true) { - int got = in.read(b, off + total, len - total); - if (got < 0) { - return (total == 0) ? -1 : total; - } - total += got; - if (total == len) { - return total; - } - } - } - - /** - * Same as the normal channel.read(b), but tries to ensure - * that the buffer is filled completely if possible, i.e. b.remaining() - * returns 0. - *

        - * If the end of file is reached before any bytes are read, returns -1. If - * the end of the file is reached after some bytes are read, returns the - * number of bytes read. If the end of the file isn't reached before the - * buffer has no more remaining capacity, will return the number of bytes - * that were read. - */ - public static int readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException { - int total = 0; - while (true) { - int got = channel.read(b); - if (got < 0) { - return (total == 0) ? -1 : total; - } - total += got; - if (total == b.capacity() || b.position() == b.capacity()) { - return total; - } - } - } - - /** - * Copies all the data from the given InputStream to the OutputStream. It - * leaves both streams open, so you will still need to close them once done. - */ - public static void copy(InputStream inp, OutputStream out) throws IOException { - byte[] buff = new byte[4096]; - int count; - while ((count = inp.read(buff)) != -1) { - if (count > 0) { - out.write(buff, 0, count); - } - } - } - - /** - * Calculate checksum on input data - */ - public static long calculateChecksum(byte[] data) { - Checksum sum = new CRC32(); - sum.update(data, 0, data.length); - return sum.getValue(); - } - - /** - * Calculate checksum on all the data read from input stream. - * - * This should be more efficient than the equivalent code - * {@code IOUtils.calculateChecksum(IOUtils.toByteArray(stream))} - */ - public static long calculateChecksum(InputStream stream) throws IOException { - Checksum sum = new CRC32(); - - byte[] buf = new byte[4096]; - int count; - while ((count = stream.read(buf)) != -1) { - if (count > 0) { - sum.update(buf, 0, count); - } - } - return sum.getValue(); - } - - - /** - * Quietly (no exceptions) close Closable resource. In case of error it will - * be printed to {@link IOUtils} class logger. - * - * @param closeable - * resource to close - */ - public static void closeQuietly( final Closeable closeable ) { - // no need to log a NullPointerException here - if(closeable == null) { - return; - } - - try { - closeable.close(); - } catch ( Exception exc ) { - logger.log( POILogger.ERROR, "Unable to close resource: " + exc, - exc ); - } - } -} diff --git a/trunk/src/java/org/apache/poi/util/IntList.java b/trunk/src/java/org/apache/poi/util/IntList.java deleted file mode 100644 index 08f024082..000000000 --- a/trunk/src/java/org/apache/poi/util/IntList.java +++ /dev/null @@ -1,662 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -/** - * A List of int's; as full an implementation of the java.util.List - * interface as possible, with an eye toward minimal creation of - * objects - * - * the mimicry of List is as follows: - *

          - *
        • if possible, operations designated 'optional' in the List - * interface are attempted - *
        • wherever the List interface refers to an Object, substitute - * int - *
        • wherever the List interface refers to a Collection or List, - * substitute IntList - *
        - * - * the mimicry is not perfect, however: - *
          - *
        • operations involving Iterators or ListIterators are not - * supported - *
        • remove(Object) becomes removeValue to distinguish it from - * remove(int index) - *
        • subList is not supported - *
        - * - * @author Marc Johnson - */ -public class IntList -{ - private int[] _array; - private int _limit; - private int fillval = 0; - private static final int _default_size = 128; - - /** - * create an IntList of default size - */ - - public IntList() - { - this(_default_size); - } - - public IntList(final int initialCapacity) - { - this(initialCapacity,0); - } - - - /** - * create a copy of an existing IntList - * - * @param list the existing IntList - */ - - public IntList(final IntList list) - { - this(list._array.length); - System.arraycopy(list._array, 0, _array, 0, _array.length); - _limit = list._limit; - } - - /** - * create an IntList with a predefined initial size - * - * @param initialCapacity the size for the internal array - */ - - public IntList(final int initialCapacity, int fillvalue) - { - _array = new int[ initialCapacity ]; - if (fillval != 0) { - fillval = fillvalue; - fillArray(fillval, _array, 0); - } - _limit = 0; - } - - private void fillArray(int val, int[] array, int index) { - for (int k = index; k < array.length; k++) { - array[k] = val; - } - } - - /** - * add the specfied value at the specified index - * - * @param index the index where the new value is to be added - * @param value the new value - * - * @exception IndexOutOfBoundsException if the index is out of - * range (index < 0 || index > size()). - */ - - public void add(final int index, final int value) - { - if (index > _limit) - { - throw new IndexOutOfBoundsException(); - } - else if (index == _limit) - { - add(value); - } - else - { - - // index < limit -- insert into the middle - if (_limit == _array.length) - { - growArray(_limit * 2); - } - System.arraycopy(_array, index, _array, index + 1, - _limit - index); - _array[ index ] = value; - _limit++; - } - } - - /** - * Appends the specified element to the end of this list - * - * @param value element to be appended to this list. - * - * @return true (as per the general contract of the Collection.add - * method). - */ - - public boolean add(final int value) - { - if (_limit == _array.length) - { - growArray(_limit * 2); - } - _array[ _limit++ ] = value; - return true; - } - - /** - * Appends all of the elements in the specified collection to the - * end of this list, in the order that they are returned by the - * specified collection's iterator. The behavior of this - * operation is unspecified if the specified collection is - * modified while the operation is in progress. (Note that this - * will occur if the specified collection is this list, and it's - * nonempty.) - * - * @param c collection whose elements are to be added to this - * list. - * - * @return true if this list changed as a result of the call. - */ - - public boolean addAll(final IntList c) - { - if (c._limit != 0) - { - if ((_limit + c._limit) > _array.length) - { - growArray(_limit + c._limit); - } - System.arraycopy(c._array, 0, _array, _limit, c._limit); - _limit += c._limit; - } - return true; - } - - /** - * Inserts all of the elements in the specified collection into - * this list at the specified position. Shifts the element - * currently at that position (if any) and any subsequent elements - * to the right (increases their indices). The new elements will - * appear in this list in the order that they are returned by the - * specified collection's iterator. The behavior of this - * operation is unspecified if the specified collection is - * modified while the operation is in progress. (Note that this - * will occur if the specified collection is this list, and it's - * nonempty.) - * - * @param index index at which to insert first element from the - * specified collection. - * @param c elements to be inserted into this list. - * - * @return true if this list changed as a result of the call. - * - * @exception IndexOutOfBoundsException if the index is out of - * range (index < 0 || index > size()) - */ - - public boolean addAll(final int index, final IntList c) - { - if (index > _limit) - { - throw new IndexOutOfBoundsException(); - } - if (c._limit != 0) - { - if ((_limit + c._limit) > _array.length) - { - growArray(_limit + c._limit); - } - - // make a hole - System.arraycopy(_array, index, _array, index + c._limit, - _limit - index); - - // fill it in - System.arraycopy(c._array, 0, _array, index, c._limit); - _limit += c._limit; - } - return true; - } - - /** - * Removes all of the elements from this list. This list will be - * empty after this call returns (unless it throws an exception). - */ - - public void clear() - { - _limit = 0; - } - - /** - * Returns true if this list contains the specified element. More - * formally, returns true if and only if this list contains at - * least one element e such that o == e - * - * @param o element whose presence in this list is to be tested. - * - * @return true if this list contains the specified element. - */ - - public boolean contains(final int o) - { - boolean rval = false; - - for (int j = 0; !rval && (j < _limit); j++) - { - if (_array[ j ] == o) - { - rval = true; - } - } - return rval; - } - - /** - * Returns true if this list contains all of the elements of the - * specified collection. - * - * @param c collection to be checked for containment in this list. - * - * @return true if this list contains all of the elements of the - * specified collection. - */ - - public boolean containsAll(final IntList c) - { - boolean rval = true; - - if (this != c) - { - for (int j = 0; rval && (j < c._limit); j++) - { - if (!contains(c._array[ j ])) - { - rval = false; - } - } - } - return rval; - } - - /** - * Compares the specified object with this list for equality. - * Returns true if and only if the specified object is also a - * list, both lists have the same size, and all corresponding - * pairs of elements in the two lists are equal. (Two elements e1 - * and e2 are equal if e1 == e2.) In other words, two lists are - * defined to be equal if they contain the same elements in the - * same order. This definition ensures that the equals method - * works properly across different implementations of the List - * interface. - * - * @param o the object to be compared for equality with this list. - * - * @return true if the specified object is equal to this list. - */ - - public boolean equals(final Object o) - { - boolean rval = this == o; - - if (!rval && (o != null) && (o.getClass() == this.getClass())) - { - IntList other = ( IntList ) o; - - if (other._limit == _limit) - { - - // assume match - rval = true; - for (int j = 0; rval && (j < _limit); j++) - { - rval = _array[ j ] == other._array[ j ]; - } - } - } - return rval; - } - - /** - * Returns the element at the specified position in this list. - * - * @param index index of element to return. - * - * @return the element at the specified position in this list. - * - * @exception IndexOutOfBoundsException if the index is out of - * range (index < 0 || index >= size()). - */ - - public int get(final int index) - { - if (index >= _limit) - { - throw new IndexOutOfBoundsException( - index + " not accessible in a list of length " + _limit - ); - } - return _array[ index ]; - } - - /** - * Returns the hash code value for this list. The hash code of a - * list is defined to be the result of the following calculation: - * - * - * hashCode = 1; - * Iterator i = list.iterator(); - * while (i.hasNext()) { - * Object obj = i.next(); - * hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode()); - * } - * - * - * This ensures that list1.equals(list2) implies that - * list1.hashCode()==list2.hashCode() for any two lists, list1 and - * list2, as required by the general contract of Object.hashCode. - * - * @return the hash code value for this list. - */ - - public int hashCode() - { - int hash = 0; - - for (int j = 0; j < _limit; j++) - { - hash = (31 * hash) + _array[ j ]; - } - return hash; - } - - /** - * Returns the index in this list of the first occurrence of the - * specified element, or -1 if this list does not contain this - * element. More formally, returns the lowest index i such that - * (o == get(i)), or -1 if there is no such index. - * - * @param o element to search for. - * - * @return the index in this list of the first occurrence of the - * specified element, or -1 if this list does not contain - * this element. - */ - - public int indexOf(final int o) - { - int rval = 0; - - for (; rval < _limit; rval++) - { - if (o == _array[ rval ]) - { - break; - } - } - if (rval == _limit) - { - rval = -1; // didn't find it - } - return rval; - } - - /** - * Returns true if this list contains no elements. - * - * @return true if this list contains no elements. - */ - - public boolean isEmpty() - { - return _limit == 0; - } - - /** - * Returns the index in this list of the last occurrence of the - * specified element, or -1 if this list does not contain this - * element. More formally, returns the highest index i such that - * (o == get(i)), or -1 if there is no such index. - * - * @param o element to search for. - * - * @return the index in this list of the last occurrence of the - * specified element, or -1 if this list does not contain - * this element. - */ - - public int lastIndexOf(final int o) - { - int rval = _limit - 1; - - for (; rval >= 0; rval--) - { - if (o == _array[ rval ]) - { - break; - } - } - return rval; - } - - /** - * Removes the element at the specified position in this list. - * Shifts any subsequent elements to the left (subtracts one from - * their indices). Returns the element that was removed from the - * list. - * - * @param index the index of the element to removed. - * - * @return the element previously at the specified position. - * - * @exception IndexOutOfBoundsException if the index is out of - * range (index < 0 || index >= size()). - */ - - public int remove(final int index) - { - if (index >= _limit) - { - throw new IndexOutOfBoundsException(); - } - int rval = _array[ index ]; - - System.arraycopy(_array, index + 1, _array, index, _limit - index); - _limit--; - return rval; - } - - /** - * Removes the first occurrence in this list of the specified - * element (optional operation). If this list does not contain - * the element, it is unchanged. More formally, removes the - * element with the lowest index i such that (o.equals(get(i))) - * (if such an element exists). - * - * @param o element to be removed from this list, if present. - * - * @return true if this list contained the specified element. - */ - - public boolean removeValue(final int o) - { - boolean rval = false; - - for (int j = 0; !rval && (j < _limit); j++) - { - if (o == _array[ j ]) - { - if (j+1 < _limit) { - System.arraycopy(_array, j + 1, _array, j, _limit - j); - } - _limit--; - rval = true; - } - } - return rval; - } - - /** - * Removes from this list all the elements that are contained in - * the specified collection - * - * @param c collection that defines which elements will be removed - * from this list. - * - * @return true if this list changed as a result of the call. - */ - - public boolean removeAll(final IntList c) - { - boolean rval = false; - - for (int j = 0; j < c._limit; j++) - { - if (removeValue(c._array[ j ])) - { - rval = true; - } - } - return rval; - } - - /** - * Retains only the elements in this list that are contained in - * the specified collection. In other words, removes from this - * list all the elements that are not contained in the specified - * collection. - * - * @param c collection that defines which elements this set will - * retain. - * - * @return true if this list changed as a result of the call. - */ - - public boolean retainAll(final IntList c) - { - boolean rval = false; - - for (int j = 0; j < _limit; ) - { - if (!c.contains(_array[ j ])) - { - remove(j); - rval = true; - } - else - { - j++; - } - } - return rval; - } - - /** - * Replaces the element at the specified position in this list - * with the specified element - * - * @param index index of element to replace. - * @param element element to be stored at the specified position. - * - * @return the element previously at the specified position. - * - * @exception IndexOutOfBoundsException if the index is out of - * range (index < 0 || index >= size()). - */ - - public int set(final int index, final int element) - { - if (index >= _limit) - { - throw new IndexOutOfBoundsException(); - } - int rval = _array[ index ]; - - _array[ index ] = element; - return rval; - } - - /** - * Returns the number of elements in this list. If this list - * contains more than Integer.MAX_VALUE elements, returns - * Integer.MAX_VALUE. - * - * @return the number of elements in this IntList - */ - - public int size() - { - return _limit; - } - - /** - * Returns an array containing all of the elements in this list in - * proper sequence. Obeys the general contract of the - * Collection.toArray method. - * - * @return an array containing all of the elements in this list in - * proper sequence. - */ - - public int [] toArray() - { - int[] rval = new int[ _limit ]; - - System.arraycopy(_array, 0, rval, 0, _limit); - return rval; - } - - /** - * Returns an array containing all of the elements in this list in - * proper sequence. Obeys the general contract of the - * Collection.toArray(Object[]) method. - * - * @param a the array into which the elements of this list are to - * be stored, if it is big enough; otherwise, a new array - * is allocated for this purpose. - * - * @return an array containing the elements of this list. - */ - - public int [] toArray(final int [] a) - { - int[] rval; - - if (a.length == _limit) - { - System.arraycopy(_array, 0, a, 0, _limit); - rval = a; - } - else - { - rval = toArray(); - } - return rval; - } - - private void growArray(final int new_size) - { - int size = (new_size == _array.length) ? new_size + 1 - : new_size; - int[] new_array = new int[ size ]; - - if (fillval != 0) { - fillArray(fillval, new_array, _array.length); - } - - System.arraycopy(_array, 0, new_array, 0, _limit); - _array = new_array; - } -} // end public class IntList - diff --git a/trunk/src/java/org/apache/poi/util/IntMapper.java b/trunk/src/java/org/apache/poi/util/IntMapper.java deleted file mode 100644 index d5cdc7b67..000000000 --- a/trunk/src/java/org/apache/poi/util/IntMapper.java +++ /dev/null @@ -1,94 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import java.util.*; - -/** - * A List of objects that are indexed AND keyed by an int; also allows for getting - * the index of a value in the list - * - *

        I am happy is someone wants to re-implement this without using the - * internal list and hashmap. If so could you please make sure that - * you can add elements half way into the list and have the value-key mappings - * update

        - * - * - * @author Jason Height - */ - -public class IntMapper -{ - private List elements; - private Map valueKeyMap; - - private static final int _default_size = 10; - - /** - * create an IntMapper of default size - */ - - public IntMapper() - { - this(_default_size); - } - - public IntMapper(final int initialCapacity) - { - elements = new ArrayList(initialCapacity); - valueKeyMap = new HashMap(initialCapacity); - } - - /** - * Appends the specified element to the end of this list - * - * @param value element to be appended to this list. - * - * @return true (as per the general contract of the Collection.add - * method). - */ - public boolean add(final T value) - { - int index = elements.size(); - elements.add(value); - valueKeyMap.put(value, index); - return true; - } - - public int size() { - return elements.size(); - } - - public T get(int index) { - return elements.get(index); - } - - public int getIndex(T o) { - Integer i = valueKeyMap.get(o); - if (i == null) - return -1; - return i.intValue(); - } - - public Iterator iterator() { - return elements.iterator(); - } -} // end public class IntMapper - diff --git a/trunk/src/java/org/apache/poi/util/IntegerField.java b/trunk/src/java/org/apache/poi/util/IntegerField.java deleted file mode 100644 index c86a008b7..000000000 --- a/trunk/src/java/org/apache/poi/util/IntegerField.java +++ /dev/null @@ -1,220 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import org.apache.poi.util.LittleEndian.BufferUnderrunException; - -import java.io.*; - -/** - * representation of an integer (32-bit) field at a fixed location - * within a byte array - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public class IntegerField - implements FixedField -{ - private int _value; - private final int _offset; - - /** - * construct the IntegerField with its offset into its containing - * byte array - * - * @param offset of the field within its byte array - * - * @exception ArrayIndexOutOfBoundsException if the offset is - * negative - */ - - public IntegerField(final int offset) - throws ArrayIndexOutOfBoundsException - { - if (offset < 0) - { - throw new ArrayIndexOutOfBoundsException("negative offset"); - } - _offset = offset; - } - - /** - * construct the IntegerField with its offset into its containing - * byte array and initialize its value - * - * @param offset of the field within its byte array - * @param value the initial value - * - * @exception ArrayIndexOutOfBoundsException if the offset is - * negative - */ - - public IntegerField(final int offset, final int value) - throws ArrayIndexOutOfBoundsException - { - this(offset); - set(value); - } - - /** - * Construct the IntegerField with its offset into its containing - * byte array and initialize its value from its byte array - * - * @param offset of the field within its byte array - * @param data the byte array to read the value from - * - * @exception ArrayIndexOutOfBoundsException if the offset is not - * within the range of 0..(data.length - 1) - */ - - public IntegerField(final int offset, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - readFromBytes(data); - } - - /** - * construct the IntegerField with its offset into its containing - * byte array, initialize its value, and write the value to a byte - * array - * - * @param offset of the field within its byte array - * @param value the initial value - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if the offset is - * negative or too large - */ - - public IntegerField(final int offset, final int value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - set(value, data); - } - - /** - * get the IntegerField's current value - * - * @return current value - */ - - public int get() - { - return _value; - } - - /** - * set the IntegerField's current value - * - * @param value to be set - */ - - public void set(final int value) - { - _value = value; - } - - /** - * set the IntegerField's current value and write it to a byte - * array - * - * @param value to be set - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if the offset is too - * large - */ - - public void set(final int value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = value; - writeToBytes(data); - } - - /* ********** START implementation of FixedField ********** */ - - /** - * set the value from its offset into an array of bytes - * - * @param data the byte array from which the value is to be read - * - * @exception ArrayIndexOutOfBoundsException if the offset is too - * large - */ - - public void readFromBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = LittleEndian.getInt(data, _offset); - } - - /** - * set the value from an InputStream - * - * @param stream the InputStream from which the value is to be - * read - * - * @exception BufferUnderrunException if there is not enough data - * available from the InputStream - * @exception IOException if an IOException is thrown from reading - * the InputStream - */ - - public void readFromStream(final InputStream stream) - throws IOException - { - _value = LittleEndian.readInt(stream); - } - - /** - * write the value out to an array of bytes at the appropriate - * offset - * - * @param data the array of bytes to which the value is to be - * written - * - * @exception ArrayIndexOutOfBoundsException if the offset is too - * large - */ - - public void writeToBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - LittleEndian.putInt(data, _offset, _value); - } - - /** - * return the value as a String - * - * @return the value as a String - */ - - public String toString() - { - return String.valueOf(_value); - } - - /* ********** END implementation of FixedField ********** */ -} // end public class IntegerField - diff --git a/trunk/src/java/org/apache/poi/util/Internal.java b/trunk/src/java/org/apache/poi/util/Internal.java deleted file mode 100644 index 565a908d7..000000000 --- a/trunk/src/java/org/apache/poi/util/Internal.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Retention; -import java.lang.annotation.Documented; - - -/** - * Program elements annotated @Internal are intended for - * POI internal use only. - * - * Such elements are not public by design and likely to be removed, have their - * signature change, or have their access level decreased from public to - * protected, package, or private in future versions of POI without notice. - * - * @Internal elements are eligible for immediate modification or removal and are - * not subject to the POI project policy of deprecating an element for 2 major - * releases before removing. - * - * @author Yegor Kozlov - * @since POI-3.6 - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface Internal { - String value() default ""; - /** - * The POI version when an element was declared internal. - * This is not the same as an @since javadoc annotation - * which specifies when the feature itself was added. - * A feature that was made internal after it was added may - * have a different since and Internal-since version numbers. - * */ - String since() default ""; -} diff --git a/trunk/src/java/org/apache/poi/util/JvmBugs.java b/trunk/src/java/org/apache/poi/util/JvmBugs.java deleted file mode 100644 index 66e8468e4..000000000 --- a/trunk/src/java/org/apache/poi/util/JvmBugs.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.util; - -import java.util.Locale; - -public class JvmBugs { - private static final POILogger LOG = POILogFactory.getLogger(JvmBugs.class); - - /** - * The LineBreakMeasurer is used for calculating text bounds. - * The last official JDK 6 version (1.6.0_45) and also JDK 7 (1.7.0_21) - * for Windows are affected. For JDK 7 - update to a more recent version. - * For JDK 6 - replace the fontmanager.dll with the previous release. - * - * For performance reasons, this method only checks for a windows jvm - * with version 1.6.0_45 and 1.7.0_21. - * - * Set system property "org.apache.poi.JvmBugs.LineBreakMeasurer.ignore" to "true" - * to bypass this check and use the normal fonts. - * - * @return true, if jvm is bugged, caller code should use Lucida Sans - * instead of Calibri and Lucida Bright instead of Cambria - * - * @see Workaround for XSLF - * @see Workaround for XSSF and HSSF - * @see POI Bug #54904 - * @see JDK Bug #6501991 - * @see LineBreakMeasurerTest - */ - public static boolean hasLineBreakMeasurerBug() { - String version = System.getProperty("java.version"); - String os = System.getProperty("os.name").toLowerCase(Locale.ROOT); - boolean ignore = Boolean.getBoolean("org.apache.poi.JvmBugs.LineBreakMeasurer.ignore"); - boolean hasBug = (!ignore && (os.contains("win") && ("1.6.0_45".equals(version) || "1.7.0_21".equals(version)))); - if (hasBug) { - LOG.log(POILogger.WARN, "JVM has LineBreakMeasurer bug - see POI bug #54904 - caller code might default to Lucida Sans"); - } - return hasBug; - } -} diff --git a/trunk/src/java/org/apache/poi/util/LZWDecompresser.java b/trunk/src/java/org/apache/poi/util/LZWDecompresser.java deleted file mode 100644 index 91aeb23b9..000000000 --- a/trunk/src/java/org/apache/poi/util/LZWDecompresser.java +++ /dev/null @@ -1,202 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * This class provides common functionality for the - * various LZW implementations in the different file - * formats. - * It's currently used by HDGF and HMEF. - * - * Two good resources on LZW are: - * http://en.wikipedia.org/wiki/LZW - * http://marknelson.us/1989/10/01/lzw-data-compression/ - */ -public abstract class LZWDecompresser { - /** - * Does the mask bit mean it's compressed or uncompressed? - */ - private final boolean maskMeansCompressed; - /** - * How much to append to the code length in the stream - * to get the real code length? Normally 2 or 3 - */ - private final int codeLengthIncrease; - /** - * Does the 12 bits of the position get stored in - * Little Endian or Big Endian form? - * This controls whether a pos+length of 0x12 0x34 - * becomes a position of 0x123 or 0x312 - */ - private final boolean positionIsBigEndian; - - protected LZWDecompresser(boolean maskMeansCompressed, - int codeLengthIncrease, boolean positionIsBigEndian) { - this.maskMeansCompressed = maskMeansCompressed; - this.codeLengthIncrease = codeLengthIncrease; - this.positionIsBigEndian = positionIsBigEndian; - } - - /** - * Populates the dictionary, and returns where in it - * to begin writing new codes. - * Generally, if the dictionary is pre-populated, then new - * codes should be placed at the end of that block. - * Equally, if the dictionary is left with all zeros, then - * usually the new codes can go in at the start. - */ - protected abstract int populateDictionary(byte[] dict); - - /** - * Adjusts the position offset if needed when looking - * something up in the dictionary. - */ - protected abstract int adjustDictionaryOffset(int offset); - - /** - * Decompresses the given input stream, returning the array of bytes - * of the decompressed input. - */ - public byte[] decompress(InputStream src) throws IOException { - ByteArrayOutputStream res = new ByteArrayOutputStream(); - decompress(src,res); - return res.toByteArray(); - } - - /** - * Perform a streaming decompression of the input. - * Works by: - * 1) Reading a flag byte, the 8 bits of which tell you if the - * following 8 codes are compressed our un-compressed - * 2) Consider the 8 bits in turn - * 3) If the bit is set, the next code is un-compressed, so - * add it to the dictionary and output it - * 4) If the bit isn't set, then read in the length and start - * position in the dictionary, and output the bytes there - * 5) Loop until we've done all 8 bits, then read in the next - * flag byte - */ - public void decompress(InputStream src, OutputStream res) throws IOException { - // How far through the output we've got - // (This is normally used &4095, so it nicely wraps) - // The initial value is set when populating the dictionary - int pos; - // The flag byte is treated as its 8 individual - // bits, which tell us if the following 8 codes - // are compressed or un-compressed - int flag; - // The mask, between 1 and 255, which is used when - // processing each bit of the flag byte in turn - int mask; - - // We use 12 bit codes: - // * 0-255 are real bytes - // * 256-4095 are the substring codes - // Java handily initialises our buffer / dictionary - // to all zeros - byte[] buffer = new byte[4096]; - pos = populateDictionary(buffer); - - // These are bytes as looked up in the dictionary - // It needs to be signed, as it'll get passed on to - // the output stream - byte[] dataB = new byte[16+codeLengthIncrease]; - // This is an unsigned byte read from the stream - // It needs to be unsigned, so that bit stuff works - int dataI; - // The compressed code sequence is held over 2 bytes - int dataIPt1, dataIPt2; - // How long a code sequence is, and where in the - // dictionary to start at - int len, pntr; - - while( (flag = src.read()) != -1 ) { - // Compare each bit in our flag byte in turn: - for(mask = 1; mask < 256 ; mask <<= 1) { - // Is this a new code (un-compressed), or - // the use of existing codes (compressed)? - boolean isMaskSet = (flag & mask) > 0; - if( isMaskSet ^ maskMeansCompressed ) { - // Retrieve the un-compressed code - if( (dataI = src.read()) != -1) { - // Save the byte into the dictionary - buffer[(pos&4095)] = fromInt(dataI); - pos++; - // And output the byte - res.write( new byte[] {fromInt(dataI)} ); - } - } else { - // We have a compressed sequence - // Grab the next 16 bits of data - dataIPt1 = src.read(); - dataIPt2 = src.read(); - if(dataIPt1 == -1 || dataIPt2 == -1) break; - - // Build up how long the code sequence is, and - // what position of the code to start at - // (The position is the usually the first 12 bits, - // and the length is usually the last 4 bits) - len = (dataIPt2 & 15) + codeLengthIncrease; - if(positionIsBigEndian) { - pntr = (dataIPt1<<4) + (dataIPt2>>4); - } else { - pntr = dataIPt1 + ((dataIPt2&0xF0)<<4); - } - - // Adjust the pointer as needed - pntr = adjustDictionaryOffset(pntr); - - // Loop over the codes, outputting what they correspond to - for(int i=0; i= 0) { - return b; - } - return b + 256; - } -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndian.java b/trunk/src/java/org/apache/poi/util/LittleEndian.java deleted file mode 100644 index 45fc0eb30..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndian.java +++ /dev/null @@ -1,765 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Serializable; - -/** - * a utility class for handling little-endian numbers, which the 80x86 world is - * replete with. The methods are all static, and input/output is from/to byte - * arrays, or from InputStreams. - * - * @author Marc Johnson (mjohnson at apache dot org) - * @author Andrew Oliver (acoliver at apache dot org) - */ -public class LittleEndian implements LittleEndianConsts -{ - - /** - * Exception to handle buffer underruns - * - * @author Marc Johnson (mjohnson at apache dot org) - */ - public static final class BufferUnderrunException extends IOException - { - /** - * Serial version UID - * - * @see Serializable - */ - private static final long serialVersionUID = 8736973884877006145L; - - BufferUnderrunException() - { - super( "buffer underrun" ); - } - } - - /** - * Copy a portion of a byte array - * - * @param data - * the original byte array - * @param offset - * Where to start copying from. - * @param size - * Number of bytes to copy. - * @return The byteArray value - * @throws IndexOutOfBoundsException - * - if copying would cause access of data outside array bounds. - */ - public static byte[] getByteArray( byte[] data, int offset, int size ) - { - byte[] copy = new byte[size]; - System.arraycopy( data, offset, copy, 0, size ); - - return copy; - } - - /** - * get a double value from a byte array, reads it in little endian format - * then converts the resulting revolting IEEE 754 (curse them) floating - * point number to a happy java double - * - * @param data - * the byte array - * @return the double (64-bit) value - */ - public static double getDouble( byte[] data ) - { - return Double.longBitsToDouble( getLong( data, 0 ) ); - } - - /** - * get a double value from a byte array, reads it in little endian format - * then converts the resulting revolting IEEE 754 (curse them) floating - * point number to a happy java double - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the double (64-bit) value - */ - public static double getDouble( byte[] data, int offset ) - { - return Double.longBitsToDouble( getLong( data, offset ) ); - } - - /** - * get a float value from a byte array, reads it in little endian format - * then converts the resulting revolting IEEE 754 (curse them) floating - * point number to a happy java float - * - * @param data - * the byte array - * @return the double (64-bit) value - */ - public static float getFloat( byte[] data ) - { - return getFloat( data, 0 ); - } - - /** - * get a float value from a byte array, reads it in little endian format - * then converts the resulting revolting IEEE 754 (curse them) floating - * point number to a happy java float - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the double (64-bit) value - */ - public static float getFloat( byte[] data, int offset ) - { - return Float.intBitsToFloat( getInt( data, offset ) ); - } - - /** - * get an int value from the beginning of a byte array - * - * @param data - * the byte array - * @return the int (32-bit) value - */ - public static int getInt( byte[] data ) - { - return getInt( data, 0 ); - } - - /** - * get an int value from a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the int (32-bit) value - */ - public static int getInt( byte[] data, int offset ) - { - int i = offset; - int b0 = data[i++] & 0xFF; - int b1 = data[i++] & 0xFF; - int b2 = data[i++] & 0xFF; - int b3 = data[i++] & 0xFF; - return ( b3 << 24 ) + ( b2 << 16 ) + ( b1 << 8 ) + ( b0 << 0 ); - } - - /** - * get a long value from a byte array - * - * @param data - * the byte array - * @return the long (64-bit) value - */ - public static long getLong( byte[] data ) - { - return getLong( data, 0 ); - } - - /** - * get a long value from a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the long (64-bit) value - */ - public static long getLong( byte[] data, int offset ) - { - long result = 0xff & data[offset + 7]; - - for ( int j = offset + LONG_SIZE - 1; j >= offset; j-- ) - { - result <<= 8; - result |= 0xff & data[j]; - } - return result; - } - - /** - * get a short value from the beginning of a byte array - * - * @param data - * the byte array - * @return the short (16-bit) value - */ - public static short getShort( byte[] data ) - { - return getShort( data, 0 ); - } - - /** - * get a short value from a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the short (16-bit) value - */ - public static short getShort( byte[] data, int offset ) - { - int b0 = data[offset] & 0xFF; - int b1 = data[offset + 1] & 0xFF; - return (short) ( ( b1 << 8 ) + ( b0 << 0 ) ); - } - - /** - * Read short array - * - * @param data - * the original byte array - * @param offset - * Where to start copying from. - * @param size - * Number of bytes to copy. - * @throws IndexOutOfBoundsException - * - if read would cause access of data outside array bounds. - */ - public static short[] getShortArray( byte[] data, int offset, int size ) - { - short[] result = new short[size / SHORT_SIZE]; - for ( int i = 0; i < result.length; i++ ) - { - result[i] = getShort( data, offset + i * SHORT_SIZE ); - } - return result; - } - - /** - * get the unsigned value of a byte. - * - * @param data - * the byte array. - * @return the unsigned value of the byte as a 16 bit short - */ - public static short getUByte( byte[] data ) - { - return (short) ( data[0] & 0xFF ); - } - - /** - * get the unsigned value of a byte. - * - * @param data - * the byte array. - * @param offset - * a starting offset into the byte array. - * @return the unsigned value of the byte as a 16 bit short - */ - public static short getUByte( byte[] data, int offset ) - { - return (short) ( data[offset] & 0xFF ); - } - - /** - * get an unsigned int value from a byte array - * - * @param data - * the byte array - * @return the unsigned int (32-bit) value in a long - */ - public static long getUInt( byte[] data ) - { - return getUInt( data, 0 ); - } - - /** - * get an unsigned int value from a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the unsigned int (32-bit) value in a long - */ - public static long getUInt( byte[] data, int offset ) - { - long retNum = getInt( data, offset ); - return retNum & 0x00FFFFFFFFl; - } - - /** - * get an unsigned short value from the beginning of a byte array - * - * @param data - * the byte array - * @return the unsigned short (16-bit) value in an int - */ - public static int getUShort( byte[] data ) - { - return getUShort( data, 0 ); - } - - /** - * get an unsigned short value from a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @return the unsigned short (16-bit) value in an integer - */ - public static int getUShort( byte[] data, int offset ) - { - int b0 = data[offset] & 0xFF; - int b1 = data[offset + 1] & 0xFF; - return ( b1 << 8 ) + ( b0 << 0 ); - } - - /** - * executes: - *

        - * - * data[offset] = (byte)value; - * - *

        - * Added for consistency with other put~() methods - */ - public static void putByte( byte[] data, int offset, int value ) - { - data[offset] = (byte) value; - } - - /** - * put a double value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the double (64-bit) value - */ - public static void putDouble( byte[] data, int offset, double value ) - { - putLong( data, offset, Double.doubleToLongBits( value ) ); - } - - /** - * put a double value into a byte array - * - * @param value - * the double (64-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putDouble( double value, OutputStream outputStream ) - throws IOException - { - putLong( Double.doubleToLongBits( value ), outputStream ); - } - - /** - * put a float value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the float (32-bit) value - */ - public static void putFloat( byte[] data, int offset, float value ) - { - putInt( data, offset, Float.floatToIntBits( value ) ); - } - - /** - * put a float value into a byte array - * - * @param value - * the float (32-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putFloat( float value, OutputStream outputStream ) - throws IOException - { - putInt( Float.floatToIntBits( value ), outputStream ); - } - - /** - * put an int value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the int (32-bit) value - */ - public static void putInt( byte[] data, int offset, int value ) - { - int i = offset; - data[i++] = (byte) ( ( value >>> 0 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 8 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 16 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 24 ) & 0xFF ); - } - - /** - * Put int into output stream - * - * @param value - * the int (32-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putInt( int value, OutputStream outputStream ) - throws IOException - { - outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) ); - } - - /** - * put a long value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the long (64-bit) value - */ - public static void putLong( byte[] data, int offset, long value ) - { - data[offset + 0] = (byte) ( ( value >>> 0 ) & 0xFF ); - data[offset + 1] = (byte) ( ( value >>> 8 ) & 0xFF ); - data[offset + 2] = (byte) ( ( value >>> 16 ) & 0xFF ); - data[offset + 3] = (byte) ( ( value >>> 24 ) & 0xFF ); - data[offset + 4] = (byte) ( ( value >>> 32 ) & 0xFF ); - data[offset + 5] = (byte) ( ( value >>> 40 ) & 0xFF ); - data[offset + 6] = (byte) ( ( value >>> 48 ) & 0xFF ); - data[offset + 7] = (byte) ( ( value >>> 56 ) & 0xFF ); - } - - /** - * Put long into output stream - * - * @param value - * the long (64-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putLong( long value, OutputStream outputStream ) - throws IOException - { - outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 32 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 40 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 48 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 56 ) & 0xFF ) ); - } - - /** - * put a short value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the short (16-bit) value - */ - public static void putShort( byte[] data, int offset, short value ) - { - int i = offset; - data[i++] = (byte) ( ( value >>> 0 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 8 ) & 0xFF ); - } - - /** - * Put signed short into output stream - * - * @param value - * the short (16-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putShort( OutputStream outputStream, short value ) - throws IOException - { - outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) ); - } - - /** - * Stores short array in buffer - * - * @param data - * the byte array - * @param startOffset - * a starting offset into the byte array - * @param value - * the short (16-bit) values - */ - public static void putShortArray( byte[] data, int startOffset, - short[] value ) - { - int offset = startOffset; - for ( short s : value ) - { - putShort( data, offset, s ); - offset += SHORT_SIZE; - } - } - - /** - * put an unsigned byte value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the short (16-bit) value - * - * @exception ArrayIndexOutOfBoundsException - * may be thrown - */ - public static void putUByte( byte[] data, int offset, short value ) - { - data[offset] = (byte) ( value & 0xFF ); - } - - /** - * put an unsigned int value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the int (32-bit) value - * - * @exception ArrayIndexOutOfBoundsException - * may be thrown - */ - public static void putUInt( byte[] data, int offset, long value ) - { - int i = offset; - data[i++] = (byte) ( ( value >>> 0 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 8 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 16 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 24 ) & 0xFF ); - } - - /** - * Put unsigned int into output stream - * - * @param value - * the int (32-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putUInt( long value, OutputStream outputStream ) - throws IOException - { - outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) ); - } - - /** - * put an unsigned short value into a byte array - * - * @param data - * the byte array - * @param offset - * a starting offset into the byte array - * @param value - * the short (16-bit) value - * - * @exception ArrayIndexOutOfBoundsException - * may be thrown - */ - public static void putUShort( byte[] data, int offset, int value ) - { - int i = offset; - data[i++] = (byte) ( ( value >>> 0 ) & 0xFF ); - data[i++] = (byte) ( ( value >>> 8 ) & 0xFF ); - } - - /** - * Put unsigned short into output stream - * - * @param value - * the unsigned short (16-bit) value - * @param outputStream - * output stream - * @throws IOException - * if an I/O error occurs - */ - public static void putUShort( int value, OutputStream outputStream ) - throws IOException - { - outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) ); - outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) ); - } - - /** - * get an int value from an InputStream - * - * @param stream - * the InputStream from which the int is to be read - * @return the int (32-bit) value - * @exception IOException - * will be propagated back to the caller - * @exception BufferUnderrunException - * if the stream cannot provide enough bytes - */ - public static int readInt( InputStream stream ) throws IOException, - BufferUnderrunException - { - int ch1 = stream.read(); - int ch2 = stream.read(); - int ch3 = stream.read(); - int ch4 = stream.read(); - if ( ( ch1 | ch2 | ch3 | ch4 ) < 0 ) - { - throw new BufferUnderrunException(); - } - return ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 ); - } - - /** - * get an unsigned int value from an InputStream - * - * @param stream - * the InputStream from which the int is to be read - * @return the unsigned int (32-bit) value - * @exception IOException - * will be propagated back to the caller - * @exception BufferUnderrunException - * if the stream cannot provide enough bytes - */ - public static long readUInt( InputStream stream ) throws IOException, - BufferUnderrunException - { - long retNum = readInt(stream); - return retNum & 0x00FFFFFFFFl; - } - - /** - * get a long value from an InputStream - * - * @param stream - * the InputStream from which the long is to be read - * @return the long (64-bit) value - * @exception IOException - * will be propagated back to the caller - * @exception BufferUnderrunException - * if the stream cannot provide enough bytes - */ - public static long readLong( InputStream stream ) throws IOException, - BufferUnderrunException - { - int ch1 = stream.read(); - int ch2 = stream.read(); - int ch3 = stream.read(); - int ch4 = stream.read(); - int ch5 = stream.read(); - int ch6 = stream.read(); - int ch7 = stream.read(); - int ch8 = stream.read(); - if ( ( ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8 ) < 0 ) - { - throw new BufferUnderrunException(); - } - - return ( (long) ch8 << 56 ) + ( (long) ch7 << 48 ) - + ( (long) ch6 << 40 ) + ( (long) ch5 << 32 ) - + ( (long) ch4 << 24 ) + // cast to long to preserve bit 31 - // (sign bit for ints) - ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 ); - } - - /** - * get a short value from an InputStream - * - * @param stream - * the InputStream from which the short is to be read - * @return the short (16-bit) value - * @exception IOException - * will be propagated back to the caller - * @exception BufferUnderrunException - * if the stream cannot provide enough bytes - */ - public static short readShort( InputStream stream ) throws IOException, - BufferUnderrunException - { - return (short) readUShort( stream ); - } - - public static int readUShort( InputStream stream ) throws IOException, - BufferUnderrunException - { - int ch1 = stream.read(); - int ch2 = stream.read(); - if ( ( ch1 | ch2 ) < 0 ) - { - throw new BufferUnderrunException(); - } - return ( ch2 << 8 ) + ( ch1 << 0 ); - } - - /** - * Convert an 'unsigned' byte to an integer. ie, don't carry across the - * sign. - * - * @param b - * Description of the Parameter - * @return Description of the Return Value - */ - public static int ubyteToInt( byte b ) - { - return b & 0xFF; - } - - private LittleEndian() - { - // no instances of this class - } -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java b/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java deleted file mode 100644 index 2c5fe70b7..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.ByteArrayInputStream; - -/** - * Adapts a plain byte array to {@link LittleEndianInput} - */ -public final class LittleEndianByteArrayInputStream extends ByteArrayInputStream implements LittleEndianInput { - public LittleEndianByteArrayInputStream(byte[] buf, int startOffset, int maxReadLen) { // NOSONAR - super(buf, startOffset, maxReadLen); - } - - public LittleEndianByteArrayInputStream(byte[] buf, int startOffset) { - super(buf, startOffset, buf.length - startOffset); - } - - public LittleEndianByteArrayInputStream(byte[] buf) { - super(buf); - } - - private void checkPosition(int i) { - if (i > count - pos) { - throw new RuntimeException("Buffer overrun"); - } - } - - public int getReadIndex() { - return pos; - } - - @Override - public byte readByte() { - checkPosition(1); - return (byte)read(); - } - - @Override - public int readInt() { - final int size = LittleEndianConsts.INT_SIZE; - checkPosition(size); - int le = LittleEndian.getInt(buf, pos); - super.skip(size); - return le; - } - - @Override - public long readLong() { - final int size = LittleEndianConsts.LONG_SIZE; - checkPosition(size); - long le = LittleEndian.getLong(buf, pos); - super.skip(size); - return le; - } - - @Override - public short readShort() { - return (short)readUShort(); - } - - @Override - public int readUByte() { - return readByte() & 0xFF; - } - - @Override - public int readUShort() { - final int size = LittleEndianConsts.SHORT_SIZE; - checkPosition(size); - int le = LittleEndian.getUShort(buf, pos); - super.skip(size); - return le; - } - - @Override - public double readDouble() { - return Double.longBitsToDouble(readLong()); - } - - @Override - public void readFully(byte[] buffer, int off, int len) { - checkPosition(len); - read(buffer, off, len); - } - - @Override - public void readFully(byte[] buffer) { - checkPosition(buffer.length); - read(buffer, 0, buffer.length); - } - - @Override - public void readPlain(byte[] buf, int off, int len) { - readFully(buf, off, len); - } -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayOutputStream.java b/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayOutputStream.java deleted file mode 100644 index fe9949f1a..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayOutputStream.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.OutputStream; - -/** - * Adapts a plain byte array to {@link LittleEndianOutput} - */ -public final class LittleEndianByteArrayOutputStream extends OutputStream implements LittleEndianOutput, DelayableLittleEndianOutput { - private final byte[] _buf; - private final int _endIndex; - private int _writeIndex; - - public LittleEndianByteArrayOutputStream(byte[] buf, int startOffset, int maxWriteLen) { // NOSONAR - if (startOffset < 0 || startOffset > buf.length) { - throw new IllegalArgumentException("Specified startOffset (" + startOffset - + ") is out of allowable range (0.." + buf.length + ")"); - } - _buf = buf; - _writeIndex = startOffset; - _endIndex = startOffset + maxWriteLen; - if (_endIndex < startOffset || _endIndex > buf.length) { - throw new IllegalArgumentException("calculated end index (" + _endIndex - + ") is out of allowable range (" + _writeIndex + ".." + buf.length + ")"); - } - } - public LittleEndianByteArrayOutputStream(byte[] buf, int startOffset) { - this(buf, startOffset, buf.length - startOffset); - } - - private void checkPosition(int i) { - if (i > _endIndex - _writeIndex) { - throw new RuntimeException("Buffer overrun"); - } - } - - @Override - public void writeByte(int v) { - checkPosition(1); - _buf[_writeIndex++] = (byte)v; - } - - @Override - public void writeDouble(double v) { - writeLong(Double.doubleToLongBits(v)); - } - - @Override - public void writeInt(int v) { - checkPosition(4); - int i = _writeIndex; - _buf[i++] = (byte)((v >>> 0) & 0xFF); - _buf[i++] = (byte)((v >>> 8) & 0xFF); - _buf[i++] = (byte)((v >>> 16) & 0xFF); - _buf[i++] = (byte)((v >>> 24) & 0xFF); - _writeIndex = i; - } - - @Override - public void writeLong(long v) { - writeInt((int)(v >> 0)); - writeInt((int)(v >> 32)); - } - - @Override - public void writeShort(int v) { - checkPosition(2); - int i = _writeIndex; - _buf[i++] = (byte)((v >>> 0) & 0xFF); - _buf[i++] = (byte)((v >>> 8) & 0xFF); - _writeIndex = i; - } - - @Override - public void write(int b) { - writeByte(b); - } - - @Override - public void write(byte[] b) { - int len = b.length; - checkPosition(len); - System.arraycopy(b, 0, _buf, _writeIndex, len); - _writeIndex += len; - } - - @Override - public void write(byte[] b, int offset, int len) { - checkPosition(len); - System.arraycopy(b, offset, _buf, _writeIndex, len); - _writeIndex += len; - } - - public int getWriteIndex() { - return _writeIndex; - } - - @Override - public LittleEndianOutput createDelayedOutput(int size) { - checkPosition(size); - LittleEndianOutput result = new LittleEndianByteArrayOutputStream(_buf, _writeIndex, size); - _writeIndex += size; - return result; - } -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianConsts.java b/trunk/src/java/org/apache/poi/util/LittleEndianConsts.java deleted file mode 100644 index 9f7e4a21a..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianConsts.java +++ /dev/null @@ -1,36 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -/** - * a repository for constants shared by classes within this package - * - * @author Marc Johnson - * @author Andrew C. Oliver (acoliver at apache dot org) - */ - -public interface LittleEndianConsts { - // sizes of various numbers in this environment - int BYTE_SIZE = 1; - int SHORT_SIZE = 2; - int INT_SIZE = 4; - int LONG_SIZE = 8; - int DOUBLE_SIZE = 8; -} // end public interface LittleEndianConsts diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianInput.java b/trunk/src/java/org/apache/poi/util/LittleEndianInput.java deleted file mode 100644 index c140c275d..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianInput.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -public interface LittleEndianInput { - int available(); - byte readByte(); - int readUByte(); - short readShort(); - int readUShort(); - int readInt(); - long readLong(); - double readDouble(); - void readFully(byte[] buf); - void readFully(byte[] buf, int off, int len); - - /** - * Usually acts the same as {@link #readFully(byte[], int, int)}, but - * for an encrypted stream the raw (unencrypted) data is filled - * - * @param buf the byte array to receive the bytes - * @param off the start offset into the byte array - * @param len the amount of bytes to fill - */ - void readPlain(byte[] buf, int off, int len); -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianInputStream.java b/trunk/src/java/org/apache/poi/util/LittleEndianInputStream.java deleted file mode 100644 index 3062c50ff..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianInputStream.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Wraps an {@link InputStream} providing {@link LittleEndianInput}

        - * - * This class does not buffer any input, so the stream read position maintained - * by this class is consistent with that of the inner stream. - * - * @author Josh Micich - */ -public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput { - public LittleEndianInputStream(InputStream is) { - super(is); - } - - @Override - public int available() { - try { - return super.available(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public byte readByte() { - return (byte)readUByte(); - } - - @Override - public int readUByte() { - byte buf[] = new byte[1]; - try { - checkEOF(read(buf), 1); - } catch (IOException e) { - throw new RuntimeException(e); - } - return LittleEndian.getUByte(buf); - } - - @Override - public double readDouble() { - return Double.longBitsToDouble(readLong()); - } - - @Override - public int readInt() { - byte buf[] = new byte[LittleEndianConsts.INT_SIZE]; - try { - checkEOF(read(buf), buf.length); - } catch (IOException e) { - throw new RuntimeException(e); - } - return LittleEndian.getInt(buf); - } - - /** - * get an unsigned int value from an InputStream - * - * @return the unsigned int (32-bit) value - * @exception RuntimeException - * wraps any IOException thrown from reading the stream. - */ - public long readUInt() { - long retNum = readInt(); - return retNum & 0x00FFFFFFFFL; - } - - @Override - public long readLong() { - byte buf[] = new byte[LittleEndianConsts.LONG_SIZE]; - try { - checkEOF(read(buf), LittleEndianConsts.LONG_SIZE); - } catch (IOException e) { - throw new RuntimeException(e); - } - return LittleEndian.getLong(buf); - } - - @Override - public short readShort() { - return (short)readUShort(); - } - - @Override - public int readUShort() { - byte buf[] = new byte[LittleEndianConsts.SHORT_SIZE]; - try { - checkEOF(read(buf), LittleEndianConsts.SHORT_SIZE); - } catch (IOException e) { - throw new RuntimeException(e); - } - return LittleEndian.getUShort(buf); - } - - private static void checkEOF(int actualBytes, int expectedBytes) { - if (expectedBytes != 0 && (actualBytes == -1 || actualBytes != expectedBytes)) { - throw new RuntimeException("Unexpected end-of-file"); - } - } - - @Override - public void readFully(byte[] buf) { - readFully(buf, 0, buf.length); - } - - @Override - public void readFully(byte[] buf, int off, int len) { - try { - checkEOF(read(buf, off, len), len); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void readPlain(byte[] buf, int off, int len) { - readFully(buf, off, len); - } -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianOutput.java b/trunk/src/java/org/apache/poi/util/LittleEndianOutput.java deleted file mode 100644 index 708d97bf4..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianOutput.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; -/** - * - * @author Josh Micich - */ -public interface LittleEndianOutput { - void writeByte(int v); - void writeShort(int v); - void writeInt(int v); - void writeLong(long v); - void writeDouble(double v); - void write(byte[] b); - void write(byte[] b, int offset, int len); -} diff --git a/trunk/src/java/org/apache/poi/util/LittleEndianOutputStream.java b/trunk/src/java/org/apache/poi/util/LittleEndianOutputStream.java deleted file mode 100644 index 3e0daa310..000000000 --- a/trunk/src/java/org/apache/poi/util/LittleEndianOutputStream.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * - * @author Josh Micich - */ -public final class LittleEndianOutputStream extends FilterOutputStream implements LittleEndianOutput { - public LittleEndianOutputStream(OutputStream out) { - super(out); - } - - @Override - public void writeByte(int v) { - try { - out.write(v); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void writeDouble(double v) { - writeLong(Double.doubleToLongBits(v)); - } - - @Override - public void writeInt(int v) { - int b3 = (v >>> 24) & 0xFF; - int b2 = (v >>> 16) & 0xFF; - int b1 = (v >>> 8) & 0xFF; - int b0 = (v >>> 0) & 0xFF; - try { - out.write(b0); - out.write(b1); - out.write(b2); - out.write(b3); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void writeLong(long v) { - writeInt((int)(v >> 0)); - writeInt((int)(v >> 32)); - } - - @Override - public void writeShort(int v) { - int b1 = (v >>> 8) & 0xFF; - int b0 = (v >>> 0) & 0xFF; - try { - out.write(b0); - out.write(b1); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - @Override - public void write(byte[] b) { - // suppress IOException for interface method - try { - super.write(b); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - @Override - public void write(byte[] b, int off, int len) { - // suppress IOException for interface method - try { - super.write(b, off, len); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/trunk/src/java/org/apache/poi/util/LocaleUtil.java b/trunk/src/java/org/apache/poi/util/LocaleUtil.java deleted file mode 100644 index 81bdd4a07..000000000 --- a/trunk/src/java/org/apache/poi/util/LocaleUtil.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import java.nio.charset.Charset; -import java.util.Calendar; -import java.util.Locale; -import java.util.TimeZone; - -/** - * This utility class is used to set locale and time zone settings beside - * of the JDK internal {@link java.util.Locale#setDefault(Locale)} and - * {@link java.util.TimeZone#setDefault(TimeZone)} methods, because - * the locale/time zone specific handling of certain office documents - - * maybe for different time zones / locales ... - shouldn't affect - * other java components. - * - * The settings are saved in a {@link java.lang.ThreadLocal}, - * so they only apply to the current thread and can't be set globally. - */ -public final class LocaleUtil { - private LocaleUtil() { - // no instances of this class - } - - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - public static final TimeZone TIMEZONE_UTC = TimeZone.getTimeZone("UTC"); - - /** - * Default encoding for unknown byte encodings of native files - * (at least it's better than to rely on a platform dependent encoding - * for legacy stuff ...) - */ - public static final Charset CHARSET_1252 = Charset.forName("CP1252"); - - private static final ThreadLocal userTimeZone = new ThreadLocal(); - private static final ThreadLocal userLocale = new ThreadLocal(); - - /** - * As time zone information is not stored in any format, it can be - * set before any date calculations take place. - * This setting is specific to the current thread. - * - * @param timezone the timezone under which date calculations take place - */ - public static void setUserTimeZone(TimeZone timezone) { - userTimeZone.set(timezone); - } - - /** - * @return the time zone which is used for date calculations. If not set, returns {@link TimeZone#getDefault()}. - */ - @SuppressForbidden("implementation around default locales in POI") - public static TimeZone getUserTimeZone() { - TimeZone timeZone = userTimeZone.get(); - return (timeZone != null) ? timeZone : TimeZone.getDefault(); - } - - /** - * Clear the thread-local user time zone. - */ - public static void resetUserTimeZone() { - userTimeZone.remove(); - } - - /** - * Sets default user locale. - * This setting is specific to the current thread. - */ - public static void setUserLocale(Locale locale) { - userLocale.set(locale); - } - - /** - * @return the default user locale. If not set, returns {@link Locale#getDefault()}. - */ - @SuppressForbidden("implementation around default locales in POI") - public static Locale getUserLocale() { - Locale locale = userLocale.get(); - return (locale != null) ? locale : Locale.getDefault(); - } - - public static void resetUserLocale() { - userLocale.remove(); - } - - /** - * @return a calendar for the user locale and time zone - */ - public static Calendar getLocaleCalendar() { - return getLocaleCalendar(getUserTimeZone()); - } - - /** - * Convenience method - month is 0-based as in java.util.Calendar - * - * @param year - * @param month - * @param day - * @return a calendar for the user locale and time zone, and the given date - */ - public static Calendar getLocaleCalendar(int year, int month, int day) { - return getLocaleCalendar(year, month, day, 0, 0, 0); - } - - /** - * Convenience method - month is 0-based as in java.util.Calendar - * - * @param year - * @param month - * @param day - * @param hour - * @param minute - * @param second - * @return a calendar for the user locale and time zone, and the given date - */ - public static Calendar getLocaleCalendar(int year, int month, int day, int hour, int minute, int second) { - Calendar cal = getLocaleCalendar(); - cal.set(year, month, day, hour, minute, second); - cal.clear(Calendar.MILLISECOND); - return cal; - } - - /** - * @return a calendar for the user locale and time zone - */ - public static Calendar getLocaleCalendar(TimeZone timeZone) { - return Calendar.getInstance(timeZone, getUserLocale()); - } -} - diff --git a/trunk/src/java/org/apache/poi/util/LongField.java b/trunk/src/java/org/apache/poi/util/LongField.java deleted file mode 100644 index 9aeffb36e..000000000 --- a/trunk/src/java/org/apache/poi/util/LongField.java +++ /dev/null @@ -1,217 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import org.apache.poi.util.LittleEndian.BufferUnderrunException; - -import java.io.*; - -/** - * representation of a long (16-bit) field at a fixed location within - * a byte array - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public class LongField - implements FixedField -{ - private long _value; - private final int _offset; - - /** - * construct the LongField with its offset into its containing - * byte array - * - * @param offset of the field within its byte array - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public LongField(final int offset) - throws ArrayIndexOutOfBoundsException - { - if (offset < 0) - { - throw new ArrayIndexOutOfBoundsException("Illegal offset: " - + offset); - } - _offset = offset; - } - - /** - * construct the LongField with its offset into its containing - * byte array and initialize its value - * - * @param offset of the field within its byte array - * @param value the initial value - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public LongField(final int offset, final long value) - throws ArrayIndexOutOfBoundsException - { - this(offset); - set(value); - } - - /** - * Construct the LongField with its offset into its containing - * byte array and initialize its value from its byte array - * - * @param offset of the field within its byte array - * @param data the byte array to read the value from - * - * @exception ArrayIndexOutOfBoundsException if the offset is not - * within the range of 0..(data.length - 1) - */ - - public LongField(final int offset, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - readFromBytes(data); - } - - /** - * construct the LongField with its offset into its containing - * byte array, initialize its value, and write the value to a byte - * array - * - * @param offset of the field within its byte array - * @param value the initial value - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public LongField(final int offset, final long value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - set(value, data); - } - - /** - * get the LongField's current value - * - * @return current value - */ - - public long get() - { - return _value; - } - - /** - * set the LongField's current value - * - * @param value to be set - */ - - public void set(final long value) - { - _value = value; - } - - /** - * set the LongField's current value and write it to a byte array - * - * @param value to be set - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range - */ - - public void set(final long value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = value; - writeToBytes(data); - } - - /* ********** START implementation of FixedField ********** */ - - /** - * set the value from its offset into an array of bytes - * - * @param data the byte array from which the value is to be read - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range - */ - - public void readFromBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = LittleEndian.getLong(data, _offset); - } - - /** - * set the value from an InputStream - * - * @param stream the InputStream from which the value is to be - * read - * - * @exception BufferUnderrunException if there is not enough data - * available from the InputStream - * @exception IOException if an IOException is thrown from reading - * the InputStream - */ - - public void readFromStream(final InputStream stream) - throws IOException - { - _value = LittleEndian.readLong(stream); - } - - /** - * write the value out to an array of bytes at the appropriate - * offset - * - * @param data the array of bytes to which the value is to be - * written - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range - */ - - public void writeToBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - LittleEndian.putLong(data, _offset, _value); - } - - /** - * return the value as a String - * - * @return the value as a String - */ - - public String toString() - { - return String.valueOf(_value); - } - - /* ********** END implementation of FixedField ********** */ -} // end public class LongField - diff --git a/trunk/src/java/org/apache/poi/util/NotImplemented.java b/trunk/src/java/org/apache/poi/util/NotImplemented.java deleted file mode 100644 index e815c5d15..000000000 --- a/trunk/src/java/org/apache/poi/util/NotImplemented.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Retention; -import java.lang.annotation.Documented; - - -/** - * This feature has not been implemented yet. - * Calling this method will result in a raised Exception - * at runtime. - * - * @since POI-3.14beta1 - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface NotImplemented { - String value() default ""; -} diff --git a/trunk/src/java/org/apache/poi/util/NullLogger.java b/trunk/src/java/org/apache/poi/util/NullLogger.java deleted file mode 100644 index e21adfaa7..000000000 --- a/trunk/src/java/org/apache/poi/util/NullLogger.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -/** - * A logger class that strives to make it as easy as possible for - * developers to write log calls, while simultaneously making those - * calls as cheap as possible by performing lazy evaluation of the log - * message.

        - */ -@Internal -public class NullLogger extends POILogger { - @Override - public void initialize(final String cat) { - // do nothing - } - - /** - * Log a message - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param obj1 The object to log. - */ - - @Override - protected void _log(final int level, final Object obj1) { - // do nothing - } - - /** - * Log a message - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param obj1 The object to log. This is converted to a string. - * @param exception An exception to be logged - */ - @Override - protected void _log(int level, Object obj1, final Throwable exception) { - // do nothing - } - - /** - * Log a message. Lazily appends Object parameters together. - * If the last parameter is a {@link Throwable} it is logged specially. - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param objs the objects to place in the message - */ - @Override - public void log(int level, Object... objs) { - // do nothing - } - - - /** - * Check if a logger is enabled to log at the specified level - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - */ - @Override - public boolean check(final int level) { - return false; - } -} - diff --git a/trunk/src/java/org/apache/poi/util/POILogFactory.java b/trunk/src/java/org/apache/poi/util/POILogFactory.java deleted file mode 100644 index 1e34ccd29..000000000 --- a/trunk/src/java/org/apache/poi/util/POILogFactory.java +++ /dev/null @@ -1,122 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import java.util.HashMap; -import java.util.Map; - -/** - * Provides logging without clients having to mess with - * configuration/initialization. - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author Marc Johnson (mjohnson at apache dot org) - * @author Nicola Ken Barozzi (nicolaken at apache.org) - */ -@Internal -public final class POILogFactory { - /** - * Map of POILogger instances, with classes as keys - */ - private static final Map _loggers = new HashMap(); - - /** - * A common instance of NullLogger, as it does nothing - * we only need the one - */ - private static final POILogger _nullLogger = new NullLogger(); - /** - * The name of the class to use. Initialised the - * first time we need it - */ - static String _loggerClassName = null; - - /** - * Construct a POILogFactory. - */ - private POILogFactory() {} - - /** - * Get a logger, based on a class name - * - * @param theclass the class whose name defines the log - * - * @return a POILogger for the specified class - */ - public static POILogger getLogger(final Class theclass) { - return getLogger(theclass.getName()); - } - - /** - * Get a logger, based on a String - * - * @param cat the String that defines the log - * - * @return a POILogger for the specified class - */ - public static POILogger getLogger(final String cat) { - // If we haven't found out what logger to use yet, - // then do so now - // Don't look it up until we're first asked, so - // that our users can set the system property - // between class loading and first use - if(_loggerClassName == null) { - try { - _loggerClassName = System.getProperty("org.apache.poi.util.POILogger"); - } catch(Exception e) { - // ignore any exception here - } - - // Use the default logger if none specified, - // or none could be fetched - if(_loggerClassName == null) { - _loggerClassName = _nullLogger.getClass().getName(); - } - } - - // Short circuit for the null logger, which - // ignores all categories - if(_loggerClassName.equals(_nullLogger.getClass().getName())) { - return _nullLogger; - } - - - // Fetch the right logger for them, creating - // it if that's required - POILogger logger = _loggers.get(cat); - if (logger == null) { - try { - @SuppressWarnings("unchecked") - Class loggerClass = - (Class) Class.forName(_loggerClassName); - logger = loggerClass.newInstance(); - logger.initialize(cat); - } catch(Exception e) { - // Give up and use the null logger - logger = _nullLogger; - _loggerClassName = _nullLogger.getClass().getName(); - } - - // Save for next time - _loggers.put(cat, logger); - } - return logger; - } -} \ No newline at end of file diff --git a/trunk/src/java/org/apache/poi/util/POILogger.java b/trunk/src/java/org/apache/poi/util/POILogger.java deleted file mode 100644 index c54c75425..000000000 --- a/trunk/src/java/org/apache/poi/util/POILogger.java +++ /dev/null @@ -1,115 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -/** - * A logger interface that strives to make it as easy as possible for - * developers to write log calls, while simultaneously making those - * calls as cheap as possible by performing lazy evaluation of the log - * message.

        - */ -@Internal -public abstract class POILogger { - - public static final int DEBUG = 1; - public static final int INFO = 3; - public static final int WARN = 5; - public static final int ERROR = 7; - public static final int FATAL = 9; - - /** Short strings for numeric log level. Use level as array index. */ - protected static final String LEVEL_STRINGS_SHORT[] = {"?", "D", "?", "I", "?", "W", "?", "E", "?", "F", "?"}; - /** Long strings for numeric log level. Use level as array index. */ - protected static final String LEVEL_STRINGS[] = {"?0?", "DEBUG", "?2?", "INFO", "?4?", "WARN", "?6?", "ERROR", "?8?", "FATAL", "?10+?"}; - - - /** - * package scope so it cannot be instantiated outside of the util - * package. You need a POILogger? Go to the POILogFactory for one - */ - POILogger() { - // no fields to initialize - } - - abstract public void initialize(String cat); - - /** - * Log a message - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param obj1 The object to log. This is converted to a string. - */ - abstract protected void _log(int level, Object obj1); - - /** - * Log a message - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param obj1 The object to log. This is converted to a string. - * @param exception An exception to be logged - */ - abstract protected void _log(int level, Object obj1, final Throwable exception); - - - /** - * Check if a logger is enabled to log at the specified level - * This allows code to avoid building strings or evaluating functions in - * the arguments to log. - * - * An example: - *

        -     * if (logger.check(POILogger.INFO)) {
        -     *     logger.log(POILogger.INFO, "Avoid concatenating " + " strings and evaluating " + functions());
        -     * }
        -     * 
        - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - */ - abstract public boolean check(int level); - - /** - * Log a message. Lazily appends Object parameters together. - * If the last parameter is a {@link Throwable} it is logged specially. - * - * @param level One of DEBUG, INFO, WARN, ERROR, FATAL - * @param objs the objects to place in the message - */ - public void log(int level, Object... objs) { - if (!check(level)) return; - StringBuilder sb = new StringBuilder(32); - Throwable lastEx = null; - for (int i=0; i= len) { - if ((len = readChunk()) == -1) { - return -1; - } - } - return buf[pos++]& 0xFF; - } - - @Override - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - @Override - public int read(byte[] b, int off, int l) throws IOException { - if (len == -1) { - return -1; - } - int offset = off; - int length = l; - while (length > 0) { - if (pos >= len) { - if ((len = readChunk()) == -1) { - return offset > off ? offset - off : -1; - } - } - int c = Math.min(length, len - pos); - System.arraycopy(buf, pos, b, offset, c); - pos += c; - length -= c; - offset += c; - } - return l; - } - - @Override - public long skip(long n) throws IOException { - long length = n; - while (length > 0) { - if (pos >= len) { - if ((len = readChunk()) == -1) { - return -1; - } - } - int c = (int) Math.min(n, len - pos); - pos += c; - length -= c; - } - return n; - } - - @Override - public int available() { - return (len > 0 ? len - pos : 0); - } - - @Override - public void close() throws IOException { - in.close(); - } - - /** - * Reads a single chunk from the underlying inputstream. - * - * @return number of bytes that were read, or -1 if the end of the stream was reached. - * @throws IOException - */ - private int readChunk() throws IOException { - pos = 0; - int w = readShort(in); - if (w == -1) { - return -1; - } - int chunkSize = (w & 0x0FFF) + 1; // plus 3 bytes minus 2 for the length - if ((w & 0x7000) != 0x3000) { - throw new IllegalArgumentException(String.format(Locale.ROOT, "Chunksize header A should be 0x3000, received 0x%04X", w & 0xE000)); - } - boolean rawChunk = (w & 0x8000) == 0; - if (rawChunk) { - if (in.read(buf, 0, chunkSize) < chunkSize) { - throw new IllegalStateException(String.format(Locale.ROOT, "Not enough bytes read, expected %d", chunkSize)); - } - return chunkSize; - } else { - int inOffset = 0; - int outOffset = 0; - while (inOffset < chunkSize) { - int tokenFlags = in.read(); - inOffset++; - if (tokenFlags == -1) { - break; - } - for (int n = 0; n < 8; n++) { - if (inOffset >= chunkSize) { - break; - } - if ((tokenFlags & POWER2[n]) == 0) { - // literal - final int b = in.read(); - if (b == -1) { - return -1; - } - buf[outOffset++] = (byte) b; - inOffset++; - } else { - // compressed token - int token = readShort(in); - if (token == -1) { - return -1; - } - inOffset += 2; - int copyLenBits = getCopyLenBits(outOffset - 1); - int copyOffset = (token >> (copyLenBits)) + 1; - int copyLen = (token & (POWER2[copyLenBits] - 1)) + 3; - int startPos = outOffset - copyOffset; - int endPos = startPos + copyLen; - for (int i = startPos; i < endPos; i++) { - buf[outOffset++] = buf[i]; - } - } - } - } - return outOffset; - } - } - - /** - * Helper method to determine how many bits in the CopyToken are used for the CopyLength. - * - * @param offset - * @return returns the number of bits in the copy token (a value between 4 and 12) - */ - static int getCopyLenBits(int offset) { - for (int n = 11; n >= 4; n--) { - if ((offset & POWER2[n]) != 0) { - return 15 - n; - } - } - return 12; - } - - /** - * Convenience method for read a 2-bytes short in little endian encoding. - * - * @return short value from the stream, -1 if end of stream is reached - * @throws IOException - */ - public int readShort() throws IOException { - return readShort(this); - } - - /** - * Convenience method for read a 4-bytes int in little endian encoding. - * - * @return integer value from the stream, -1 if end of stream is reached - * @throws IOException - */ - public int readInt() throws IOException { - return readInt(this); - } - - private int readShort(InputStream stream) throws IOException { - int b0, b1; - if ((b0 = stream.read()) == -1) { - return -1; - } - if ((b1 = stream.read()) == -1) { - return -1; - } - return (b0 & 0xFF) | ((b1 & 0xFF) << 8); - } - - private int readInt(InputStream stream) throws IOException { - int b0, b1, b2, b3; - if ((b0 = stream.read()) == -1) { - return -1; - } - if ((b1 = stream.read()) == -1) { - return -1; - } - if ((b2 = stream.read()) == -1) { - return -1; - } - if ((b3 = stream.read()) == -1) { - return -1; - } - return (b0 & 0xFF) | ((b1 & 0xFF) << 8) | ((b2 & 0xFF) << 16) | ((b3 & 0xFF) << 24); - } - - public static byte[] decompress(byte[] compressed) throws IOException { - return decompress(compressed, 0, compressed.length); - } - - public static byte[] decompress(byte[] compressed, int offset, int length) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream instream = new ByteArrayInputStream(compressed, offset, length); - InputStream stream = new RLEDecompressingInputStream(instream); - IOUtils.copy(stream, out); - stream.close(); - out.close(); - return out.toByteArray(); - } -} diff --git a/trunk/src/java/org/apache/poi/util/RecordFormatException.java b/trunk/src/java/org/apache/poi/util/RecordFormatException.java deleted file mode 100644 index d1643b8be..000000000 --- a/trunk/src/java/org/apache/poi/util/RecordFormatException.java +++ /dev/null @@ -1,42 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -/** - * A common exception thrown by our binary format parsers - * (especially HSSF and DDF), when they hit invalid - * format or data when processing a record. - */ -public class RecordFormatException - extends RuntimeException -{ - public RecordFormatException(String exception) - { - super(exception); - } - - public RecordFormatException(String exception, Throwable thr) { - super(exception, thr); - } - - public RecordFormatException(Throwable thr) { - super(thr); - } -} diff --git a/trunk/src/java/org/apache/poi/util/Removal.java b/trunk/src/java/org/apache/poi/util/Removal.java deleted file mode 100644 index a94be1e63..000000000 --- a/trunk/src/java/org/apache/poi/util/Removal.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Retention; -import java.lang.annotation.Documented; - - -/** - *

        Program elements annotated @Removal track the earliest final release - * when a deprecated feature will be removed. This is an internal decoration: - * a feature may be removed in a release earlier or later than the release - * number specified by this annotation.

        - * - *

        The POI project policy is to deprecate an element for 2 final releases - * before removing. This annotation exists to make it easier to follow up on the - * second step of the two-step deprecate and remove process.

        - * - *

        A deprecated feature may be removed in nightly and beta releases prior - * to the final release for which it is eligible, but may be removed later for - * various reasons. If it is known in advance that the feature will not be - * removed in the n+2 release, a later version should be specified by this - * annotation. The annotation version number should not include beta

        - * - *

        For example, a feature with a @deprecated POI 3.15 beta 3 - * is deprecated in POI 3.15 and 3.16 and becomes eligible for deletion during - * the POI 3.17 release series, and may be deleted immediately after POI 3.16 is - * released. This would be annotated @Removal(version="3.17")

        . - * - * @since POI-3.15 beta 3 - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface Removal { - /** - * The POI version when this feature may be removed. - * - * To ensure that the version number can be compared to the current version - * and a unit test can generate a warning if a removal-eligible feature has - * not been removed yet, the version number should adhere to the following format: - * Format: "(?\d+)\.(?\d+)" - * Example: "3.15" - */ - String version() default ""; -} diff --git a/trunk/src/java/org/apache/poi/util/ShortField.java b/trunk/src/java/org/apache/poi/util/ShortField.java deleted file mode 100644 index 29d91df7f..000000000 --- a/trunk/src/java/org/apache/poi/util/ShortField.java +++ /dev/null @@ -1,217 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.util; - -import org.apache.poi.util.LittleEndian.BufferUnderrunException; - -import java.io.*; - -/** - * representation of a short (16-bit) field at a fixed location within - * a byte array - * - * @author Marc Johnson (mjohnson at apache dot org - */ - -public class ShortField - implements FixedField -{ - private short _value; - private final int _offset; - - /** - * construct the ShortField with its offset into its containing - * byte array - * - * @param offset of the field within its byte array - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public ShortField(final int offset) - throws ArrayIndexOutOfBoundsException - { - if (offset < 0) - { - throw new ArrayIndexOutOfBoundsException("Illegal offset: " - + offset); - } - _offset = offset; - } - - /** - * construct the ShortField with its offset into its containing - * byte array and initialize its value - * - * @param offset of the field within its byte array - * @param value the initial value - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public ShortField(final int offset, final short value) - throws ArrayIndexOutOfBoundsException - { - this(offset); - set(value); - } - - /** - * Construct the ShortField with its offset into its containing - * byte array and initialize its value from its byte array - * - * @param offset of the field within its byte array - * @param data the byte array to read the value from - * - * @exception ArrayIndexOutOfBoundsException if the offset is not - * within the range of 0..(data.length - 1) - */ - - public ShortField(final int offset, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - readFromBytes(data); - } - - /** - * construct the ShortField with its offset into its containing - * byte array, initialize its value, and write its value to its - * byte array - * - * @param offset of the field within its byte array - * @param value the initial value - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if offset is negative - */ - - public ShortField(final int offset, final short value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - this(offset); - set(value, data); - } - - /** - * get the ShortField's current value - * - * @return current value - */ - - public short get() - { - return _value; - } - - /** - * set the ShortField's current value - * - * @param value to be set - */ - - public void set(final short value) - { - _value = value; - } - - /** - * set the ShortField's current value and write it to a byte array - * - * @param value to be set - * @param data the byte array to write the value to - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range - */ - - public void set(final short value, final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = value; - writeToBytes(data); - } - - /* ********** START implementation of FixedField ********** */ - - /** - * set the value from its offset into an array of bytes - * - * @param data the byte array from which the value is to be read - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range - */ - - public void readFromBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - _value = LittleEndian.getShort(data, _offset); - } - - /** - * set the value from an InputStream - * - * @param stream the InputStream from which the value is to be - * read - * - * @exception BufferUnderrunException if there is not enough data - * available from the InputStream - * @exception IOException if an IOException is thrown from reading - * the InputStream - */ - - public void readFromStream(final InputStream stream) - throws IOException - { - _value = LittleEndian.readShort(stream); - } - - /** - * write the value out to an array of bytes at the appropriate - * offset - * - * @param data the array of bytes to which the value is to be - * written - * - * @exception ArrayIndexOutOfBoundsException if the offset is out - * of range - */ - - public void writeToBytes(final byte [] data) - throws ArrayIndexOutOfBoundsException - { - LittleEndian.putShort(data, _offset, _value); - } - - /** - * return the value as a String - * - * @return the value as a String - */ - - public String toString() - { - return String.valueOf(_value); - } - - /* ********** END implementation of FixedField ********** */ -} // end public class ShortField - diff --git a/trunk/src/java/org/apache/poi/util/StringUtil.java b/trunk/src/java/org/apache/poi/util/StringUtil.java deleted file mode 100644 index 20a6824c9..000000000 --- a/trunk/src/java/org/apache/poi/util/StringUtil.java +++ /dev/null @@ -1,623 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * Collection of string handling utilities - */ -@Internal -public class StringUtil { - protected static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - protected static final Charset UTF16LE = Charset.forName("UTF-16LE"); - public static final Charset UTF8 = Charset.forName("UTF-8"); - - private static Map msCodepointToUnicode; - - private StringUtil() { - // no instances of this class - } - - /** - * Given a byte array of 16-bit unicode characters in Little Endian - * format (most important byte last), return a Java String representation - * of it. - * - * { 0x16, 0x00 } -0x16 - * - * @param string the byte array to be converted - * @param offset the initial offset into the - * byte array. it is assumed that string[ offset ] and string[ offset + - * 1 ] contain the first 16-bit unicode character - * @param len the length of the final string - * @return the converted string, never null. - * @exception ArrayIndexOutOfBoundsException if offset is out of bounds for - * the byte array (i.e., is negative or is greater than or equal to - * string.length) - * @exception IllegalArgumentException if len is too large (i.e., - * there is not enough data in string to create a String of that - * length) - */ - public static String getFromUnicodeLE( - final byte[] string, - final int offset, - final int len) - throws ArrayIndexOutOfBoundsException, IllegalArgumentException { - if ((offset < 0) || (offset >= string.length)) { - throw new ArrayIndexOutOfBoundsException("Illegal offset " + offset + " (String data is of length " + string.length + ")"); - } - if ((len < 0) || (((string.length - offset) / 2) < len)) { - throw new IllegalArgumentException("Illegal length " + len); - } - - return new String(string, offset, len * 2, UTF16LE); - } - - /** - * Given a byte array of 16-bit unicode characters in little endian - * format (most important byte last), return a Java String representation - * of it. - * - * { 0x16, 0x00 } -0x16 - * - * @param string the byte array to be converted - * @return the converted string, never null - */ - public static String getFromUnicodeLE(byte[] string) { - if(string.length == 0) { return ""; } - return getFromUnicodeLE(string, 0, string.length / 2); - } - - /** - * Convert String to 16-bit unicode characters in little endian format - * - * @param string the string - * @return the byte array of 16-bit unicode characters - */ - public static byte[] getToUnicodeLE(String string) { - return string.getBytes(UTF16LE); - } - - /** - * Read 8 bit data (in ISO-8859-1 codepage) into a (unicode) Java - * String and return. - * (In Excel terms, read compressed 8 bit unicode as a string) - * - * @param string byte array to read - * @param offset offset to read byte array - * @param len length to read byte array - * @return String generated String instance by reading byte array - */ - public static String getFromCompressedUnicode( - final byte[] string, - final int offset, - final int len) { - int len_to_use = Math.min(len, string.length - offset); - return new String(string, offset, len_to_use, ISO_8859_1); - } - - public static String readCompressedUnicode(LittleEndianInput in, int nChars) { - byte[] buf = new byte[nChars]; - in.readFully(buf); - return new String(buf, ISO_8859_1); - } - - /** - * InputStream in is expected to contain: - *
          - *
        1. ushort nChars
        2. - *
        3. byte is16BitFlag
        4. - *
        5. byte[]/char[] characterData
        6. - *
        - * For this encoding, the is16BitFlag is always present even if nChars==0. - * - * This structure is also known as a XLUnicodeString. - */ - public static String readUnicodeString(LittleEndianInput in) { - - int nChars = in.readUShort(); - byte flag = in.readByte(); - if ((flag & 0x01) == 0) { - return readCompressedUnicode(in, nChars); - } - return readUnicodeLE(in, nChars); - } - /** - * InputStream in is expected to contain: - *
          - *
        1. byte is16BitFlag
        2. - *
        3. byte[]/char[] characterData
        4. - *
        - * For this encoding, the is16BitFlag is always present even if nChars==0. - *
        - * This method should be used when the nChars field is not stored - * as a ushort immediately before the is16BitFlag. Otherwise, {@link - * #readUnicodeString(LittleEndianInput)} can be used. - */ - public static String readUnicodeString(LittleEndianInput in, int nChars) { - byte is16Bit = in.readByte(); - if ((is16Bit & 0x01) == 0) { - return readCompressedUnicode(in, nChars); - } - return readUnicodeLE(in, nChars); - } - /** - * OutputStream out will get: - *
          - *
        1. ushort nChars
        2. - *
        3. byte is16BitFlag
        4. - *
        5. byte[]/char[] characterData
        6. - *
        - * For this encoding, the is16BitFlag is always present even if nChars==0. - */ - public static void writeUnicodeString(LittleEndianOutput out, String value) { - int nChars = value.length(); - out.writeShort(nChars); - boolean is16Bit = hasMultibyte(value); - out.writeByte(is16Bit ? 0x01 : 0x00); - if (is16Bit) { - putUnicodeLE(value, out); - } else { - putCompressedUnicode(value, out); - } - } - /** - * OutputStream out will get: - *
          - *
        1. byte is16BitFlag
        2. - *
        3. byte[]/char[] characterData
        4. - *
        - * For this encoding, the is16BitFlag is always present even if nChars==0. - *
        - * This method should be used when the nChars field is not stored - * as a ushort immediately before the is16BitFlag. Otherwise, {@link - * #writeUnicodeString(LittleEndianOutput, String)} can be used. - */ - public static void writeUnicodeStringFlagAndData(LittleEndianOutput out, String value) { - boolean is16Bit = hasMultibyte(value); - out.writeByte(is16Bit ? 0x01 : 0x00); - if (is16Bit) { - putUnicodeLE(value, out); - } else { - putCompressedUnicode(value, out); - } - } - - /** - * @return the number of bytes that would be written by {@link #writeUnicodeString(LittleEndianOutput, String)} - */ - public static int getEncodedSize(String value) { - int result = 2 + 1; - result += value.length() * (StringUtil.hasMultibyte(value) ? 2 : 1); - return result; - } - - /** - * Takes a unicode (java) string, and returns it as 8 bit data (in ISO-8859-1 - * codepage). - * (In Excel terms, write compressed 8 bit unicode) - * - * @param input the String containing the data to be written - * @param output the byte array to which the data is to be written - * @param offset an offset into the byte arrat at which the data is start - * when written - */ - public static void putCompressedUnicode(String input, byte[] output, int offset) { - byte[] bytes = input.getBytes(ISO_8859_1); - System.arraycopy(bytes, 0, output, offset, bytes.length); - } - - public static void putCompressedUnicode(String input, LittleEndianOutput out) { - byte[] bytes = input.getBytes(ISO_8859_1); - out.write(bytes); - } - - /** - * Takes a unicode string, and returns it as little endian (most - * important byte last) bytes in the supplied byte array. - * (In Excel terms, write uncompressed unicode) - * - * @param input the String containing the unicode data to be written - * @param output the byte array to hold the uncompressed unicode, should be twice the length of the String - * @param offset the offset to start writing into the byte array - */ - public static void putUnicodeLE(String input, byte[] output, int offset) { - byte[] bytes = input.getBytes(UTF16LE); - System.arraycopy(bytes, 0, output, offset, bytes.length); - } - public static void putUnicodeLE(String input, LittleEndianOutput out) { - byte[] bytes = input.getBytes(UTF16LE); - out.write(bytes); - } - - public static String readUnicodeLE(LittleEndianInput in, int nChars) { - byte[] bytes = new byte[nChars*2]; - in.readFully(bytes); - return new String(bytes, UTF16LE); - } - - /** - * @return the encoding we want to use, currently hardcoded to ISO-8859-1 - */ - public static String getPreferredEncoding() { - return ISO_8859_1.name(); - } - - /** - * check the parameter has multibyte character - * - * @param value string to check - * @return boolean result true:string has at least one multibyte character - */ - public static boolean hasMultibyte(String value) { - if (value == null) - return false; - for (char c : value.toCharArray()) { - if (c > 0xFF) { - return true; - } - } - return false; - } - - /** - * Checks to see if a given String needs to be represented as Unicode - * - * @param value The string to look at. - * @return true if string needs Unicode to be represented. - */ - public static boolean isUnicodeString(final String value) { - return !value.equals(new String(value.getBytes(ISO_8859_1), ISO_8859_1)); - } - - /** - * Tests if the string starts with the specified prefix, ignoring case consideration. - */ - public static boolean startsWithIgnoreCase(String haystack, String prefix) { - return haystack.regionMatches(true, 0, prefix, 0, prefix.length()); - } - - /** - * Tests if the string ends with the specified suffix, ignoring case consideration. - */ - public static boolean endsWithIgnoreCase(String haystack, String suffix) { - int length = suffix.length(); - int start = haystack.length() - length; - return haystack.regionMatches(true, start, suffix, 0, length); - } - - /** - * An Iterator over an array of Strings. - */ - public static class StringsIterator implements Iterator { - private String[] strings = {}; - private int position = 0; - public StringsIterator(String[] strings) { - if (strings != null) { - this.strings = strings.clone(); - } - } - - public boolean hasNext() { - return position < strings.length; - } - public String next() { - int ourPos = position++; - if(ourPos >= strings.length) { - throw new ArrayIndexOutOfBoundsException(ourPos); - } - return strings[ourPos]; - } - public void remove() {} - } - - - /** - * Some strings may contain encoded characters of the unicode private use area. - * Currently the characters of the symbol fonts are mapped to the corresponding - * characters in the normal unicode range. - * - * @param string the original string - * @return the string with mapped characters - * - * @see Private Use Area (symbol) - * @see Symbol font - Unicode alternatives for Greek and special characters in HTML - */ - public static String mapMsCodepointString(String string) { - if (string == null || "".equals(string)) return string; - initMsCodepointMap(); - - StringBuilder sb = new StringBuilder(); - final int length = string.length(); - for (int offset = 0; offset < length; ) { - Integer msCodepoint = string.codePointAt(offset); - Integer uniCodepoint = msCodepointToUnicode.get(msCodepoint); - sb.appendCodePoint(uniCodepoint == null ? msCodepoint : uniCodepoint); - offset += Character.charCount(msCodepoint); - } - - return sb.toString(); - } - - public static synchronized void mapMsCodepoint(int msCodepoint, int unicodeCodepoint) { - initMsCodepointMap(); - msCodepointToUnicode.put(msCodepoint, unicodeCodepoint); - } - - private static synchronized void initMsCodepointMap() { - if (msCodepointToUnicode != null) return; - msCodepointToUnicode = new HashMap(); - int i=0xF020; - for (int ch : symbolMap_f020) { - msCodepointToUnicode.put(i++, ch); - } - i = 0xf0a0; - for (int ch : symbolMap_f0a0) { - msCodepointToUnicode.put(i++, ch); - } - } - - private static final int symbolMap_f020[] = { - ' ', // 0xf020 space - '!', // 0xf021 exclam - 8704, // 0xf022 universal - '#', // 0xf023 numbersign - 8707, // 0xf024 existential - '%', // 0xf025 percent - '&', // 0xf026 ampersand - 8717, // 0xf027 suchthat - '(', // 0xf028 parenleft - ')', // 0xf029 parentright - 8727, // 0xf02a asteriskmath - '+', // 0xf02b plus - ',', // 0xf02c comma - 8722, // 0xf02d minus sign (long -) - '.', // 0xf02e period - '/', // 0xf02f slash - '0', // 0xf030 0 - '1', // 0xf031 1 - '2', // 0xf032 2 - '3', // 0xf033 3 - '4', // 0xf034 4 - '5', // 0xf035 5 - '6', // 0xf036 6 - '7', // 0xf037 7 - '8', // 0xf038 8 - '9', // 0xf039 9 - ':', // 0xf03a colon - ';', // 0xf03b semicolon - '<', // 0xf03c less - '=', // 0xf03d equal - '>', // 0xf03e greater - '?', // 0xf03f question - 8773, // 0xf040 congruent - 913, // 0xf041 alpha (upper) - 914, // 0xf042 beta (upper) - 935, // 0xf043 chi (upper) - 916, // 0xf044 delta (upper) - 917, // 0xf045 epsilon (upper) - 934, // 0xf046 phi (upper) - 915, // 0xf047 gamma (upper) - 919, // 0xf048 eta (upper) - 921, // 0xf049 iota (upper) - 977, // 0xf04a theta1 (lower) - 922, // 0xf04b kappa (upper) - 923, // 0xf04c lambda (upper) - 924, // 0xf04d mu (upper) - 925, // 0xf04e nu (upper) - 927, // 0xf04f omicron (upper) - 928, // 0xf050 pi (upper) - 920, // 0xf051 theta (upper) - 929, // 0xf052 rho (upper) - 931, // 0xf053 sigma (upper) - 932, // 0xf054 tau (upper) - 933, // 0xf055 upsilon (upper) - 962, // 0xf056 simga1 (lower) - 937, // 0xf057 omega (upper) - 926, // 0xf058 xi (upper) - 936, // 0xf059 psi (upper) - 918, // 0xf05a zeta (upper) - '[', // 0xf05b bracketleft - 8765, // 0xf05c therefore - ']', // 0xf05d bracketright - 8869, // 0xf05e perpendicular - '_', // 0xf05f underscore - ' ', // 0xf060 radicalex (doesn't exist in unicode) - 945, // 0xf061 alpha (lower) - 946, // 0xf062 beta (lower) - 967, // 0xf063 chi (lower) - 948, // 0xf064 delta (lower) - 949, // 0xf065 epsilon (lower) - 966, // 0xf066 phi (lower) - 947, // 0xf067 gamma (lower) - 951, // 0xf068 eta (lower) - 953, // 0xf069 iota (lower) - 981, // 0xf06a phi1 (lower) - 954, // 0xf06b kappa (lower) - 955, // 0xf06c lambda (lower) - 956, // 0xf06d mu (lower) - 957, // 0xf06e nu (lower) - 959, // 0xf06f omnicron (lower) - 960, // 0xf070 pi (lower) - 952, // 0xf071 theta (lower) - 961, // 0xf072 rho (lower) - 963, // 0xf073 sigma (lower) - 964, // 0xf074 tau (lower) - 965, // 0xf075 upsilon (lower) - 982, // 0xf076 piv (lower) - 969, // 0xf077 omega (lower) - 958, // 0xf078 xi (lower) - 968, // 0xf079 psi (lower) - 950, // 0xf07a zeta (lower) - '{', // 0xf07b braceleft - '|', // 0xf07c bar - '}', // 0xf07d braceright - 8764, // 0xf07e similar '~' - ' ', // 0xf07f not defined - }; - - private static final int symbolMap_f0a0[] = { - 8364, // 0xf0a0 not defined / euro symbol - 978, // 0xf0a1 upsilon1 (upper) - 8242, // 0xf0a2 minute - 8804, // 0xf0a3 lessequal - 8260, // 0xf0a4 fraction - 8734, // 0xf0a5 infinity - 402, // 0xf0a6 florin - 9827, // 0xf0a7 club - 9830, // 0xf0a8 diamond - 9829, // 0xf0a9 heart - 9824, // 0xf0aa spade - 8596, // 0xf0ab arrowboth - 8591, // 0xf0ac arrowleft - 8593, // 0xf0ad arrowup - 8594, // 0xf0ae arrowright - 8595, // 0xf0af arrowdown - 176, // 0xf0b0 degree - 177, // 0xf0b1 plusminus - 8243, // 0xf0b2 second - 8805, // 0xf0b3 greaterequal - 215, // 0xf0b4 multiply - 181, // 0xf0b5 proportional - 8706, // 0xf0b6 partialdiff - 8729, // 0xf0b7 bullet - 247, // 0xf0b8 divide - 8800, // 0xf0b9 notequal - 8801, // 0xf0ba equivalence - 8776, // 0xf0bb approxequal - 8230, // 0xf0bc ellipsis - 9168, // 0xf0bd arrowvertex - 9135, // 0xf0be arrowhorizex - 8629, // 0xf0bf carriagereturn - 8501, // 0xf0c0 aleph - 8475, // 0xf0c1 Ifraktur - 8476, // 0xf0c2 Rfraktur - 8472, // 0xf0c3 weierstrass - 8855, // 0xf0c4 circlemultiply - 8853, // 0xf0c5 circleplus - 8709, // 0xf0c6 emptyset - 8745, // 0xf0c7 intersection - 8746, // 0xf0c8 union - 8835, // 0xf0c9 propersuperset - 8839, // 0xf0ca reflexsuperset - 8836, // 0xf0cb notsubset - 8834, // 0xf0cc propersubset - 8838, // 0xf0cd reflexsubset - 8712, // 0xf0ce element - 8713, // 0xf0cf notelement - 8736, // 0xf0d0 angle - 8711, // 0xf0d1 gradient - 174, // 0xf0d2 registerserif - 169, // 0xf0d3 copyrightserif - 8482, // 0xf0d4 trademarkserif - 8719, // 0xf0d5 product - 8730, // 0xf0d6 radical - 8901, // 0xf0d7 dotmath - 172, // 0xf0d8 logicalnot - 8743, // 0xf0d9 logicaland - 8744, // 0xf0da logicalor - 8660, // 0xf0db arrowdblboth - 8656, // 0xf0dc arrowdblleft - 8657, // 0xf0dd arrowdblup - 8658, // 0xf0de arrowdblright - 8659, // 0xf0df arrowdbldown - 9674, // 0xf0e0 lozenge - 9001, // 0xf0e1 angleleft - 174, // 0xf0e2 registersans - 169, // 0xf0e3 copyrightsans - 8482, // 0xf0e4 trademarksans - 8721, // 0xf0e5 summation - 9115, // 0xf0e6 parenlefttp - 9116, // 0xf0e7 parenleftex - 9117, // 0xf0e8 parenleftbt - 9121, // 0xf0e9 bracketlefttp - 9122, // 0xf0ea bracketleftex - 9123, // 0xf0eb bracketleftbt - 9127, // 0xf0ec bracelefttp - 9128, // 0xf0ed braceleftmid - 9129, // 0xf0ee braceleftbt - 9130, // 0xf0ef braceex - ' ', // 0xf0f0 not defined - 9002, // 0xf0f1 angleright - 8747, // 0xf0f2 integral - 8992, // 0xf0f3 integraltp - 9134, // 0xf0f4 integralex - 8993, // 0xf0f5 integralbt - 9118, // 0xf0f6 parenrighttp - 9119, // 0xf0f7 parenrightex - 9120, // 0xf0f8 parenrightbt - 9124, // 0xf0f9 bracketrighttp - 9125, // 0xf0fa bracketrightex - 9126, // 0xf0fb bracketrightbt - 9131, // 0xf0fc bracerighttp - 9132, // 0xf0fd bracerightmid - 9133, // 0xf0fe bracerightbt - ' ', // 0xf0ff not defined - }; - - // Could be replaced with org.apache.commons.lang3.StringUtils#join - @Internal - public static String join(Object[] array, String separator) { - if (array == null || array.length == 0) return ""; - StringBuilder sb = new StringBuilder(); - sb.append(array[0]); - for (int i=1; i= currentLevel; - } - - -} // end package scope class POILogger - diff --git a/trunk/src/java/org/apache/poi/util/TempFile.java b/trunk/src/java/org/apache/poi/util/TempFile.java deleted file mode 100644 index ceb7c1d1c..000000000 --- a/trunk/src/java/org/apache/poi/util/TempFile.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.File; -import java.io.IOException; - -/** - * Interface for creating temporary files. Collects them all into one directory by default. - */ -public final class TempFile { - /** The strategy used by {@link #createTempFile(String, String)} to create the temporary files. */ - private static TempFileCreationStrategy strategy = new DefaultTempFileCreationStrategy(); - - /** Define a constant for this property as it is sometimes mistypes as "tempdir" otherwise */ - public static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; - - private TempFile() { - // no instances of this class - } - - /** - * Configures the strategy used by {@link #createTempFile(String, String)} to create the temporary files. - * - * @param strategy The new strategy to be used to create the temporary files. - * - * @throws IllegalArgumentException When the given strategy is null. - */ - public static void setTempFileCreationStrategy(TempFileCreationStrategy strategy) { - if (strategy == null) { - throw new IllegalArgumentException("strategy == null"); - } - TempFile.strategy = strategy; - } - - /** - * Creates a new and empty temporary file. By default, files are collected into one directory and are - * deleted on exit from the VM, although they can be kept by defining the system property - * poi.keep.tmp.files (see {@link DefaultTempFileCreationStrategy}). - *

        - * Don't forget to close all files or it might not be possible to delete them. - * - * @param prefix The prefix to be used to generate the name of the temporary file. - * @param suffix The suffix to be used to generate the name of the temporary file. - * - * @return The path to the newly created and empty temporary file. - * - * @throws IOException If no temporary file could be created. - */ - public static File createTempFile(String prefix, String suffix) throws IOException { - return strategy.createTempFile(prefix, suffix); - } - - public static File createTempDirectory(String name) throws IOException { - return strategy.createTempDirectory(name); - } - - /** - * @deprecated POI 3.15 beta 3. Moved to {@link org.apache.poi.util.DefaultTempFileCreationStrategy}. - */ - public static class DefaultTempFileCreationStrategy extends org.apache.poi.util.DefaultTempFileCreationStrategy {} -} diff --git a/trunk/src/java/org/apache/poi/util/TempFileCreationStrategy.java b/trunk/src/java/org/apache/poi/util/TempFileCreationStrategy.java deleted file mode 100644 index d576f0885..000000000 --- a/trunk/src/java/org/apache/poi/util/TempFileCreationStrategy.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.File; -import java.io.IOException; - -/** - * Interface used by the {@link TempFile} utility class to create temporary files. - * - * Classes that implement a TempFileCreationStrategy attempt to handle the cleanup - * of temporary files. - * - * Examples include: - *

          - *
        • {@link DefaultTempFileCreationStrategy} deletes temporary files when - * the JVM exits. - * This may not be suitable for long-running applications that never - * shut down the JVM since the list of registered files and disk space - * usage would grow for as long as the JVM is running. - * You may wish to implement your own strategy that meets the needs of - * your situation. - *
        • - *
        • A strategy that keeps the n most-recent files, discarding - * older files on a first-in, first-out basis. - * A java.util.Deque or org.apache.commons.collections4.queue.CircularFifoQueue - * may be helpful for achieving this. - *
        • - *
        • A strategy that keeps track of every temporary file that has been - * created by the class or instance and provides a method to explicitly - * delete the temporary files in the reverse order that they were created. - * This is the same as DefaultTempFileCreationStrategy, except the strategy - * class would maintain the list of files to delete rather than or in - * addition to {@link java.io.DeleteOnExitHook} maintaining the list, and - * the files could be deleted before the JVM exit. - *
        • - *
        • A strategy that creates a directory that is deleted on JVM exit. - * Any files inside the directory do not need to be registered since the - * entire directory will be deleted at exit. - * This could be dangerous if files were added to the temporary directory - * outside of this TempFileCreationStrategy's control. - * This could be accomplished with {@link #createTempDirectory(String)} and - * creating regular (unregistered) files in the temp directory. - *
        • - *
        - * - */ -public interface TempFileCreationStrategy { - /** - * Creates a new and empty temporary file. - * - * @param prefix The prefix to be used to generate the name of the temporary file. - * @param suffix The suffix to be used to generate the name of the temporary file. - * - * @return The path to the newly created and empty temporary file. - * - * @throws IOException If no temporary file could be created. - */ - File createTempFile(String prefix, String suffix) throws IOException; - - /** - * Creates a new and empty temporary directory. - * - * @param prefix The directory name to be used to generate the name of the temporary directory. - * - * @return The path to the newly created and empty temporary directory. - * - * @throws IOException If no temporary directory could be created. - * - * @since POI 3.15 beta 3. - */ - File createTempDirectory(String prefix) throws IOException; -} diff --git a/trunk/src/java/org/apache/poi/util/Units.java b/trunk/src/java/org/apache/poi/util/Units.java deleted file mode 100644 index 4ee12cb9c..000000000 --- a/trunk/src/java/org/apache/poi/util/Units.java +++ /dev/null @@ -1,130 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.util; - -/** - * @author Yegor Kozlov - */ -public class Units { - /** - * In Escher absolute distances are specified in - * English Metric Units (EMUs), occasionally referred to as A units; - * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point. - */ - public static final int EMU_PER_PIXEL = 9525; - public static final int EMU_PER_POINT = 12700; - public static final int EMU_PER_CENTIMETER = 360000; - - /** - * Master DPI (576 pixels per inch). - * Used by the reference coordinate system in PowerPoint (HSLF) - */ - public static final int MASTER_DPI = 576; - - /** - * Pixels DPI (96 pixels per inch) - */ - public static final int PIXEL_DPI = 96; - - /** - * Points DPI (72 pixels per inch) - */ - public static final int POINT_DPI = 72; - - /** - * Converts points to EMUs - * @param points points - * @return EMUs - */ - public static int toEMU(double points){ - return (int)Math.rint(EMU_PER_POINT*points); - } - - /** - * Converts pixels to EMUs - * @param pixels pixels - * @return EMUs - */ - public static int pixelToEMU(int pixels) { - return pixels*EMU_PER_PIXEL; - } - - /** - * Converts EMUs to points - * @param emu emu - * @return points - */ - public static double toPoints(long emu){ - return (double)emu/EMU_PER_POINT; - } - - /** - * Converts a value of type FixedPoint to a floating point - * - * @param fixedPoint value in fixed point notation - * @return floating point (double) - * - * @see [MS-OSHARED] - 2.2.1.6 FixedPoint - */ - public static double fixedPointToDouble(int fixedPoint) { - int i = (fixedPoint >> 16); - int f = fixedPoint & 0xFFFF; - return (i + f/65536d); - } - - /** - * Converts a value of type floating point to a FixedPoint - * - * @param floatPoint value in floating point notation - * @return fixedPoint value in fixed points notation - * - * @see [MS-OSHARED] - 2.2.1.6 FixedPoint - */ - public static int doubleToFixedPoint(double floatPoint) { - double fractionalPart = floatPoint % 1d; - double integralPart = floatPoint - fractionalPart; - int i = (int)Math.floor(integralPart); - int f = (int)Math.rint(fractionalPart*65536d); - return (i << 16) | (f & 0xFFFF); - } - - public static double masterToPoints(int masterDPI) { - double points = masterDPI; - points *= POINT_DPI; - points /= MASTER_DPI; - return points; - } - - public static int pointsToMaster(double points) { - points *= MASTER_DPI; - points /= POINT_DPI; - return (int)Math.rint(points); - } - - public static int pointsToPixel(double points) { - points *= PIXEL_DPI; - points /= POINT_DPI; - return (int)Math.rint(points); - } - - public static double pixelToPoints(int pixel) { - double points = pixel; - points *= POINT_DPI; - points /= PIXEL_DPI; - return points; - } -} diff --git a/trunk/src/java/org/apache/poi/util/XMLHelper.java b/trunk/src/java/org/apache/poi/util/XMLHelper.java deleted file mode 100644 index 879747546..000000000 --- a/trunk/src/java/org/apache/poi/util/XMLHelper.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilderFactory; - -/** - * Helper methods for working with javax.xml classes. - */ -public final class XMLHelper -{ - private static POILogger logger = POILogFactory.getLogger(XMLHelper.class); - - /** - * Creates a new DocumentBuilderFactory, with sensible defaults - */ - public static DocumentBuilderFactory getDocumentBuilderFactory() { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setExpandEntityReferences(false); - trySetSAXFeature(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true); - trySetSAXFeature(factory, "http://xml.org/sax/features/external-general-entities", false); - trySetSAXFeature(factory, "http://xml.org/sax/features/external-parameter-entities", false); - trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); - return factory; - } - - private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) { - try { - documentBuilderFactory.setFeature(feature, enabled); - } catch (Exception e) { - logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e); - } catch (AbstractMethodError ame) { - logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame); - } - } - - -} diff --git a/trunk/src/java/org/apache/poi/util/package.html b/trunk/src/java/org/apache/poi/util/package.html deleted file mode 100644 index c8eeaab89..000000000 --- a/trunk/src/java/org/apache/poi/util/package.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - -Top-level util package are classes that are useful throughout the project. These classes are -generally generic enough to be useful in any project and should be contributed elsewhere! - -

        Related Documentation

        - -For overviews, tutorials, examples, guides, and tool documentation, please see: - - - - diff --git a/trunk/src/java/org/apache/poi/wp/usermodel/CharacterRun.java b/trunk/src/java/org/apache/poi/wp/usermodel/CharacterRun.java deleted file mode 100644 index 549ef6779..000000000 --- a/trunk/src/java/org/apache/poi/wp/usermodel/CharacterRun.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.wp.usermodel; - -/** - * This class represents a run of text that share common properties. - */ -public interface CharacterRun { - boolean isBold(); - void setBold(boolean bold); - - boolean isItalic(); - void setItalic(boolean italic); - - boolean isSmallCaps(); - void setSmallCaps(boolean smallCaps); - - boolean isCapitalized(); - void setCapitalized(boolean caps); - - boolean isStrikeThrough(); - void setStrikeThrough(boolean strike); - boolean isDoubleStrikeThrough(); - void setDoubleStrikethrough(boolean dstrike); - - boolean isShadowed(); - void setShadow(boolean shadow); - - boolean isEmbossed(); - void setEmbossed(boolean emboss); - - boolean isImprinted(); - void setImprinted(boolean imprint); - - int getFontSize(); - void setFontSize(int halfPoints); - - int getCharacterSpacing(); - void setCharacterSpacing(int twips); - - int getKerning(); - void setKerning(int kern); - - boolean isHighlighted(); - - // HWPF has colour indexes, XWPF has a highlight enum with the colours in -// byte getHighlightedColor(); -// void setHighlighted(byte color); - - // HWPF has colour indexes, XWPF colour names -// int getColor(); -// void setColor(int color); - - - /** - * Gets the fonts which shall be used to display the text contents of - * this run. Specifies a font which shall be used to format all "normal" - * characters in the run - * - * @return a string representing the font - */ - String getFontName(); - - /** - * @return The text of the run, including any tabs/spaces/etc - */ - String text(); - - // HWPF uses indexes, XWPF special -// int getUnderlineCode(); -// void setUnderlineCode(int kul); - - // HWPF uses indexes, XWPF special vertical alignments -// short getSubSuperScriptIndex(); -// void setSubSuperScriptIndex(short iss); - - // TODO Review these, and add to XWPFRun if possible -/* - boolean isFldVanished(); - void setFldVanish(boolean fldVanish); - - boolean isOutlined(); - void setOutline(boolean outlined); - - boolean isVanished(); - void setVanished(boolean vanish); - - boolean isMarkedDeleted(); - void markDeleted(boolean mark); - - boolean isMarkedInserted(); - void markInserted(boolean mark); -*/ -} diff --git a/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java b/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java deleted file mode 100644 index bca6b6658..000000000 --- a/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.wp.usermodel; - -/** - * @since POI v3.16 beta 1 - */ -public enum HeaderFooterType { - - /** - * This is the default header or Footer, It is displayed on every page where - * a more specific header or footer is not specified. It is always displayed - * on ODD pages that are not the first page of the section. - */ - DEFAULT(2), - - /** - * This is an even page header or footer, it is displayed on even pages that - * are not the first page of the section. - */ - EVEN(1), - - /** - * This is a first page header or footer It is displayed on the first page - * of the section. - */ - FIRST(3); - - private final int code; - - private HeaderFooterType(int i) { - code = i; - } - - public int toInt() { - return code; - } - - public static HeaderFooterType forInt(int i) { - for (HeaderFooterType type : values()) { - if (type.code == i) { - return type; - } - } - throw new IllegalArgumentException("Invalid HeaderFooterType code: " + i); - } -} diff --git a/trunk/src/java/org/apache/poi/wp/usermodel/Paragraph.java b/trunk/src/java/org/apache/poi/wp/usermodel/Paragraph.java deleted file mode 100644 index be488a2ef..000000000 --- a/trunk/src/java/org/apache/poi/wp/usermodel/Paragraph.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.wp.usermodel; - -/** - * This class represents a paragraph, made up of one or more - * runs of text. - */ -public interface Paragraph { - // Tables work very differently between the formats -// public boolean isInTable(); -// public boolean isTableRowEnd(); -// public int getTableLevel(); - - // TODO Implement justifaction in XWPF -// public int getJustification(); -// public void setJustification(byte jc); - - // TODO Expose the different page break related things, - // XWPF currently doesn't have the full set -/* - public boolean keepOnPage(); - public void setKeepOnPage(boolean fKeep); - - public boolean keepWithNext(); - public void setKeepWithNext(boolean fKeepFollow); - - public boolean pageBreakBefore(); - public void setPageBreakBefore(boolean fPageBreak); - - public boolean isSideBySide(); - public void setSideBySide(boolean fSideBySide); -*/ - - public int getIndentFromRight(); - public void setIndentFromRight(int dxaRight); - - public int getIndentFromLeft(); - public void setIndentFromLeft(int dxaLeft); - - public int getFirstLineIndent(); - public void setFirstLineIndent(int first); - -/* - public boolean isLineNotNumbered(); - public void setLineNotNumbered(boolean fNoLnn); - - public boolean isAutoHyphenated(); - public void setAutoHyphenated(boolean autoHyph); - - public boolean isWidowControlled(); - public void setWidowControl(boolean widowControl); - - public int getSpacingBefore(); - public void setSpacingBefore(int before); - - public int getSpacingAfter(); - public void setSpacingAfter(int after); -*/ - - // public LineSpacingDescriptor getLineSpacing(); - // public void setLineSpacing(LineSpacingDescriptor lspd); - - public int getFontAlignment(); - public void setFontAlignment(int align); - - public boolean isWordWrapped(); - public void setWordWrapped(boolean wrap); - -/* - public boolean isVertical(); - public void setVertical(boolean vertical); - - public boolean isBackward(); - public void setBackward(boolean bward); -*/ - - // TODO Make the HWPF and XWPF interface wrappers compatible for these -/* - public BorderCode getTopBorder(); - public void setTopBorder(BorderCode top); - public BorderCode getLeftBorder(); - public void setLeftBorder(BorderCode left); - public BorderCode getBottomBorder(); - public void setBottomBorder(BorderCode bottom); - public BorderCode getRightBorder(); - public void setRightBorder(BorderCode right); - public BorderCode getBarBorder(); - public void setBarBorder(BorderCode bar); - - public ShadingDescriptor getShading(); - public void setShading(ShadingDescriptor shd); -*/ - - /** - * Returns the ilfo, an index to the document's hpllfo, which - * describes the automatic number formatting of the paragraph. - * A value of zero means it isn't numbered. - */ -// public int getIlfo(); - - /** - * Returns the multi-level indent for the paragraph. Will be - * zero for non-list paragraphs, and the first level of any - * list. Subsequent levels in hold values 1-8. - */ -// public int getIlvl(); - - /** - * Returns the heading level (1-8), or 9 if the paragraph - * isn't in a heading style. - */ -// public int getLvl(); - - /** - * Returns number of tabs stops defined for paragraph. Must be >= 0 and <= - * 64. - * - * @return number of tabs stops defined for paragraph. Must be >= 0 and <= - * 64 - */ -// public int getTabStopsNumber(); - - /** - * Returns array of positions of itbdMac tab stops - * - * @return array of positions of itbdMac tab stops - */ -// public int[] getTabStopsPositions(); -} diff --git a/trunk/src/models/BlockClassDiagram.pgml b/trunk/src/models/BlockClassDiagram.pgml deleted file mode 100644 index 11d979ad4..000000000 --- a/trunk/src/models/BlockClassDiagram.pgml +++ /dev/null @@ -1,621 +0,0 @@ - - - - - - - - - - BigBlock - - #BIG_BLOCK_SIZE : int = 512 - +writeData(in stream:OutputStream) -#doWriteData(in stream:OutputStream, in data[]:byte) - - - - - - - HeaderBlock - - -_bat_count : IntegerField --_property_start : IntegerField --_sbat_start : IntegerField = -2 --_xbat_start : IntegerField = -2 --_xbat_count : IntegerField = 0 --_data[ 512 ] : byte - +setBATBlocks(in blockCount:int, in startBlock:int) : BATBlock -+setPropertyStart(in startBlock:int) -+setXBATStart(in startBlock:int) -+Header() -+calculateXBATStorageRequirements(in blockCount:int) : int - - - - - - - PropertyBlock - - -_properties[ 4 ] : Property - +createPropertyBlockArray(in properties:List) : BlockWritable - - - - - - - BATBlock - - -_fields[ 128 ] : IntegerField --_data[ 512 ] : byte - +createBATBlocks(in entries[]:int) : BATBlock -+calculateStorageRequirements(in entryCount:int) : int - - - - - - - DocumentBlock - - -_data[ 512 ] : byte --_bytes_read : int - +DocumentBlock(in stream:InputStream) -+size() : int -+partiallyRead() : boolean - - - - - - - <<Interface>> - BlockWritable - +writeBlocks(in stream:OutputStream) - - - - sourcePortFig="Fig1.0" - destPortFig="Fig0.0" - sourceFigNode="Fig1" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig0.0" - sourceFigNode="Fig2" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig0.0" - sourceFigNode="Fig3" - destFigNode="Fig0" - - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig0.0" - sourceFigNode="Fig4" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig5.0" - sourceFigNode="Fig0" - destFigNode="Fig5" - - - - - - - - - diff --git a/trunk/src/models/HSSFOperationalUseCases.pgml b/trunk/src/models/HSSFOperationalUseCases.pgml deleted file mode 100644 index fe331fdff..000000000 --- a/trunk/src/models/HSSFOperationalUseCases.pgml +++ /dev/null @@ -1,730 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - ClientApps - - - - - - - create HSSF File - - - - - - - write Workbook Entry - - - - - - - write sheet entry - - - - - - - new MUseCase - - - - - - - new MUseCase - - - - - - - new MUseCase - - - - - - - new MUseCase - - - - - - - new MUseCase - - - - - - - new MUseCase - - - - sourcePortFig="Fig0.0" - destPortFig="Fig1.0" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig2.0" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig3.0" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig4.0" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig5.0" - sourceFigNode="Fig0" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig6.0" - sourceFigNode="Fig0" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig7.0" - sourceFigNode="Fig0" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig9.0" - sourceFigNode="Fig0" - destFigNode="Fig9" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig8.0" - sourceFigNode="Fig0" - destFigNode="Fig8" - - - - - - - - - diff --git a/trunk/src/models/HSSFSerializerClassDiagram.pgml b/trunk/src/models/HSSFSerializerClassDiagram.pgml deleted file mode 100644 index 474a2bfb0..000000000 --- a/trunk/src/models/HSSFSerializerClassDiagram.pgml +++ /dev/null @@ -1,669 +0,0 @@ - - - - - - - - - - POIFSSerializer - - -_output_stream : OutputStream = null --_locator : Locator = null --_open_elements : Stack = new Stack() --_filesystem : Filesystem = new Filesystem() - +startPrefixMapping(in ignoredPrefix:String, in ignoredUri:String) -+endPrefixMapping(in ignoredPrefix:String) -+processingInstruction(in ignoredTarget:String, in ignoredData:String) -+skippedEntity(in ignoredName:String) -+startDTD(in ignoredName:String, in ignoredPublicId:String, in ignoredSystemId:String) -+endDTD() -+startEntity(in ignoredName:String) -+endEntity(in ignoredName:String) -+startCDATA() -+endCDATA() -+comment(in ignoredCh[]:char, in ignoredStart:int, in ignoredLength:int) -+shouldSetContentLength() : boolean -+setOutputStream(in out:OutputStream) -+setDocumentLocator(in locator:Locator) -+startDocument() -+endDocument() -+startElement(in namespaceURI:String, in localName:String, in qName:String, in atts:Attributes) -+endElement(in namespaceURI:String, in localName:String, in qName:String) -+characters(in ch[]:char, in start:int, in length:int) -+ignorableWhitespace(in ch[]:char, in start:int, in length:int) -#getElementProcessorFactory() : ElementProcessorFactory -#doLocalPreEndDocument() -#doLocalPostEndDocument() -#getFilesystem() : Filesystem -#SAXExceptionFactory(in message:String, in e:Exception) : SAXException -#SAXExceptionFactory(in message:String) : SAXException - - - - - - - Attribute - - -_name : String --_value : String - +getName() : String -+getValue() : String -+getValueAsInt() : int -+getValueAsShort() : short -+getValueAsLong() : long -+getValueAsBoolean() : boolean -+Attribute(in name:String, in value:String) - - - - - - - <<Interface>> - ElementProcessor - +initialize(in attributes[]:Attribute, in parent:ElementProcessor, in filesystem:Filesystem) -+acceptCharacters(in data[]:char) -+acceptWhitespaceCharacters(in data[]:char) -+endProcessing() - - - - - - - ElementProcessorFactory - - -_element_processor_map : Map - +createElementProcessor(in name:String) : ElementProcessor -#addElementProcessorProgenitor(in name:String, in progenitor:Object) -#lookupElementProcessorProgenitor(in name:String) : Object -#doCreateElementProcessor(in progenitor:Object) : ElementProcessor -#constructElementProcessor(in progenitor:Constructor) : ElementProcessor -#createNewElementProcessorInstance(in progenitor:Class) : ElementProcessor - - - - - - - HSSFSerializer - - -_element_processor_factory : HSSFElementProcessorFactory - +getMimeType() : String - - - - - - - HSSFElementProcessorFactory - - - - - - - - - - ElementProcessorFactory.CannotCreateElementProcessorException - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig0.0" - sourceFigNode="Fig4" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig3.0" - sourceFigNode="Fig5" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig5.0" - sourceFigNode="Fig4" - destFigNode="Fig5" - - - - - - - - - diff --git a/trunk/src/models/HSSFSerializerUseCases.pgml b/trunk/src/models/HSSFSerializerUseCases.pgml deleted file mode 100644 index e7dfc3f10..000000000 --- a/trunk/src/models/HSSFSerializerUseCases.pgml +++ /dev/null @@ -1,1049 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Cocoon - - - - - - - Sends Sax Events - - - - - - - Sends an Ignored Event - - - - - - - Sends and Interrogative Event - - - - - - - Sends Setup Event - - - - - - - Sends Start Document Event - - - - - - - Sends End Document Event - - - - - - - Sends Start Element Event - - - - - - - Sends End Element Event - - - - - - - Sends Raw Data Event - - - - sourcePortFig="Fig9.0" - destPortFig="Fig1.0" - sourceFigNode="Fig9" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig7.0" - destPortFig="Fig1.0" - sourceFigNode="Fig7" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig8.0" - destPortFig="Fig1.0" - sourceFigNode="Fig8" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig6.0" - destPortFig="Fig1.0" - sourceFigNode="Fig6" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig1.0" - sourceFigNode="Fig5" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig1.0" - sourceFigNode="Fig4" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig1.0" - sourceFigNode="Fig3" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig1.0" - sourceFigNode="Fig2" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig0.0" - sourceFigNode="Fig1" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig0.0" - sourceFigNode="Fig3" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig7.0" - destPortFig="Fig0.0" - sourceFigNode="Fig7" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig0.0" - sourceFigNode="Fig5" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig6.0" - destPortFig="Fig0.0" - sourceFigNode="Fig6" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig8.0" - destPortFig="Fig0.0" - sourceFigNode="Fig8" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig0.0" - sourceFigNode="Fig2" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig9.0" - destPortFig="Fig0.0" - sourceFigNode="Fig9" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig0.0" - sourceFigNode="Fig4" - destFigNode="Fig0" - - - - - - - - - diff --git a/trunk/src/models/HSSFUseCases.pgml b/trunk/src/models/HSSFUseCases.pgml deleted file mode 100644 index 0bca88408..000000000 --- a/trunk/src/models/HSSFUseCases.pgml +++ /dev/null @@ -1,725 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - ClientApps - - - - - - - create HSSF File - - - - - - - read existing HSSF File - - - - - - - write HSSF File - - - - - - - read Workbook Entry - - - - - - - write Workbook Entry - - - - - - - write sheet entry - - - - - - - read Sheet Entry - - - - sourcePortFig="Fig0.0" - destPortFig="Fig1.0" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig2.0" - sourceFigNode="Fig0" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig2.0" - sourceFigNode="Fig4" - destFigNode="Fig2" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig3.0" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig3.0" - sourceFigNode="Fig5" - destFigNode="Fig3" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig2.0" - sourceFigNode="Fig3" - destFigNode="Fig2" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig6.0" - destPortFig="Fig3.0" - sourceFigNode="Fig6" - destFigNode="Fig3" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig7.0" - destPortFig="Fig2.0" - sourceFigNode="Fig7" - destFigNode="Fig2" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig1.0" - sourceFigNode="Fig3" - destFigNode="Fig1" - - - - - - - <<extends>> - - - diff --git a/trunk/src/models/POIFSAddDocument.pgml b/trunk/src/models/POIFSAddDocument.pgml deleted file mode 100644 index 211754623..000000000 --- a/trunk/src/models/POIFSAddDocument.pgml +++ /dev/null @@ -1,1042 +0,0 @@ - - - - - - - - - - Filesystem : - - - - - - - - - - - - - - - - - - - - - - Document : - - - - - - - - - - - - - - - - - - - - - DocumentProperty : - - - - - - - - - - - - - - - - - - DocumentBlock : - - - - - - - - - - - - - - - - - - PropertyTable : - - - - - - - - - - - - - - - - - - - RootProperty : - - - - - - - - - - - - - - - - : create - - - - - : create (1 .. n) - - - - - : create - - - - - : getDocumentProperty - - - - - : addProperty - - - - - : getRoot - - - - - : addChild - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.8" - destPortFig="Fig3.7" - sourceFigNode="Fig1" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig1.9" - destPortFig="Fig2.7" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig1.10" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.9" - destPortFig="Fig4.7" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig0.10" - destPortFig="Fig4.8" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig0.11" - destPortFig="Fig5.7" - sourceFigNode="Fig0" - destFigNode="Fig5" - - - - - - - - - diff --git a/trunk/src/models/POIFSClassDiagram.pgml b/trunk/src/models/POIFSClassDiagram.pgml deleted file mode 100644 index 0f20959a3..000000000 --- a/trunk/src/models/POIFSClassDiagram.pgml +++ /dev/null @@ -1,1125 +0,0 @@ - - - - - - - - - - Filesystem - - -_property_table : PropertyTable --_header_block : HeaderBlock --_documents : List - +createDocument(in stream:InputStream, in name:String) -+writeFilesystem(in stream:OutputStream) -+Filesystem() - - - - - - - Document - - -_property : DocumentProperty --_blocks[] : DocumentBlock - #getDocumentProperty() : DocumentProperty -#Document(in name:String, in stream:InputStream) - - - - - - - DocumentBlock - - -_data[ 512 ] : byte --_bytes_read : int - +DocumentBlock(in stream:InputStream) -+size() : int -+partiallyRead() : boolean - - - - - - - HeaderBlock - - -_bat_count : IntegerField --_property_start : IntegerField --_sbat_start : IntegerField = -2 --_xbat_start : IntegerField = -2 --_xbat_count : IntegerField = 0 --_data[ 512 ] : byte - +setBATBlocks(in blockCount:int, in startBlock:int) : BATBlock -+setPropertyStart(in startBlock:int) -+setXBATStart(in startBlock:int) -+Header() -+calculateXBATStorageRequirements(in blockCount:int) : int - - - - - - - PropertyTable - - -_properties : List --_blocks[ ] : BlockWritable --_start_block : int - +getRoot() : Directory -+addProperty(in property:Property) -+preWrite() -+PropertyTable() -+getStartBlock() : int - - - - - - - DocumentProperty - - - +DocumentProperty(in name:String, in size:int) - - - - - - - <<Interface>> - BATManaged - +countBlocks() : int -+setStartBlock(in index:int) - - - - - - - <<Interface>> - BlockWritable - +writeBlocks(in stream:OutputStream) - - - - - - - BlockAllocationTable - - -_entries : IntList --_blocks[] : BATBlock - #createBlocks() -#allocateSpace(in blockCount:int) : int -#BlockAllocationTable() -#countBlocks() : int - - - - - - - BATBlock - - -_fields[ 128 ] : IntegerField --_data[ 512 ] : byte - +createBATBlocks(in entries[]:int) : BATBlock -+calculateStorageRequirements(in entryCount:int) : int - - - - sourcePortFig="Fig0.0" - destPortFig="Fig1.0" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - 0..* - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig2.0" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - 1..* - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig3.0" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig4.0" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig5.0" - sourceFigNode="Fig1" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig6.0" - sourceFigNode="Fig4" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig6.0" - sourceFigNode="Fig1" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig7.0" - sourceFigNode="Fig1" - destFigNode="Fig7" - - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig7.0" - sourceFigNode="Fig4" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig8.0" - destPortFig="Fig7.0" - sourceFigNode="Fig8" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig8.0" - destPortFig="Fig9.0" - sourceFigNode="Fig8" - destFigNode="Fig9" - - - - - - - 1..* - - - diff --git a/trunk/src/models/POIFSInitialization.pgml b/trunk/src/models/POIFSInitialization.pgml deleted file mode 100644 index 3c487567b..000000000 --- a/trunk/src/models/POIFSInitialization.pgml +++ /dev/null @@ -1,590 +0,0 @@ - - - - - - - enclosingFig="Fig0" - - - - Filesystem : - - - - - - - - - - - - - - - - enclosingFig="Fig1" - - - - HeaderBlock : - - - - - - - - - - - - - - - enclosingFig="Fig2" - - - - PropertyTable : - - - - - - - - - - - - - - - - enclosingFig="Fig3" - - - - RootProperty : - - - - - - - - - - - - - - - - : create - - - - - : create - - - - - : create - - - - sourcePortFig="Fig0.7" - destPortFig="Fig2.7" - sourceFigNode="Fig0" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig2.8" - destPortFig="Fig3.7" - sourceFigNode="Fig2" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - diff --git a/trunk/src/models/POIFSLifeCycle.pgml b/trunk/src/models/POIFSLifeCycle.pgml deleted file mode 100644 index 88c431588..000000000 --- a/trunk/src/models/POIFSLifeCycle.pgml +++ /dev/null @@ -1,410 +0,0 @@ - - - - - - - - - - (Client Application) : - - - - - - - - - - - - - - - - - - - - Filesystem : - - - - - - - - - - - - - - - - - - : create - - - - - : createDocument - - - - - : writeFileSystem - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig1.8" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.9" - destPortFig="Fig1.9" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - diff --git a/trunk/src/models/POIFSPropertyTablePreWrite.pgml b/trunk/src/models/POIFSPropertyTablePreWrite.pgml deleted file mode 100644 index dba9bb2e8..000000000 --- a/trunk/src/models/POIFSPropertyTablePreWrite.pgml +++ /dev/null @@ -1,814 +0,0 @@ - - - - - - - - - - PropertyTable : - - - - - - - - - - - - - - - - - - - - Property : - - - - - - - - - - - - - - - - - - - PropertyBlock : - - - - - - - - - - - - - - - - - - - - PropertyBlock : - - - - - - - - - - - - - - - - - - Property : - - - - - - - - - - - - - - - - : setIndex (for each Property) - - - - - : createPropertyBlockArray - - - - - : create (enough so we have a multiple of 4 properties) - - - - - : create (1 for every 4 properties) - - - - - : preWrite (for each Property) - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig2.7" - sourceFigNode="Fig0" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig2.8" - destPortFig="Fig4.7" - sourceFigNode="Fig2" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig2.9" - destPortFig="Fig3.7" - sourceFigNode="Fig2" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.9" - destPortFig="Fig1.8" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - diff --git a/trunk/src/models/POIFSRootPropertyPreWrite.pgml b/trunk/src/models/POIFSRootPropertyPreWrite.pgml deleted file mode 100644 index 829e8d36d..000000000 --- a/trunk/src/models/POIFSRootPropertyPreWrite.pgml +++ /dev/null @@ -1,416 +0,0 @@ - - - - - - - enclosingFig="Fig0" - - - - RootProperty : - - - - - - - - - - - - - - - - - - enclosingFig="Fig1" - - - - Property : - - - - - - - - - - - - - - - - - : setNextFile - - - - - : set _child_property - - - - - : setPreviousFile - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig0.9" - sourceFigNode="Fig0" - destFigNode="Fig0" - - - - - - - - - - - - - sourcePortFig="Fig0.10" - destPortFig="Fig1.8" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - diff --git a/trunk/src/models/POIFSWriteFilesystem.pgml b/trunk/src/models/POIFSWriteFilesystem.pgml deleted file mode 100644 index 1a0196527..000000000 --- a/trunk/src/models/POIFSWriteFilesystem.pgml +++ /dev/null @@ -1,1258 +0,0 @@ - - - - - - - enclosingFig="Fig0" - - - - Filesystem : - - - - - - - - - - - - - - - - - - - - - - - - enclosingFig="Fig1" - - - - PropertyTable : - - - - - - - - - - - - - - - enclosingFig="Fig2" - - - - BATManaged : - - - - - - - - - - - - - - - - enclosingFig="Fig3" - - - - BlockAllocationTable : - - - - - - - - - - - - - - - - - enclosingFig="Fig4" - - - - HeaderBlock : - - - - - - - - - - - - - - - - - enclosingFig="Fig5" - - - - BlockWritable : - - - - - - - - - - - - - - - - : preWrite - - - - - : countBlocks - - - - - : allocateSpace - - - - - : setStartBlock - - - - - : createBlocks - - - - - : setBatBlocks - - - - - : setPropertyStart - - - - - : writeBlocks - - - - - : create - - - - - : setXBATStart - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig2.7" - sourceFigNode="Fig0" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig0.9" - destPortFig="Fig3.7" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.10" - destPortFig="Fig2.8" - sourceFigNode="Fig0" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig0.11" - destPortFig="Fig3.8" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.12" - destPortFig="Fig4.7" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig0.13" - destPortFig="Fig4.8" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig0.14" - destPortFig="Fig5.7" - sourceFigNode="Fig0" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig0.15" - destPortFig="Fig3.9" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig0.16" - destPortFig="Fig4.9" - sourceFigNode="Fig0" - destFigNode="Fig4" - - - - - - - - - diff --git a/trunk/src/models/POIUseCases.pgml b/trunk/src/models/POIUseCases.pgml deleted file mode 100644 index ee5a00286..000000000 --- a/trunk/src/models/POIUseCases.pgml +++ /dev/null @@ -1,1006 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - ClientApps - - - - - - - read existing filesystem - - - - - - - write file system - - - - - - - create new filesystem - - - - - - - read file system directory - - - - - - - read existing file from file system - - - - - - - write new file to file system - - - - - - - delete file from file system - - - - - - - replace file in file system - - - - - - - read file - - - - - - - rename existing file in file system - - - - sourcePortFig="Fig0.0" - destPortFig="Fig1.0" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig2.0" - sourceFigNode="Fig0" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig3.0" - sourceFigNode="Fig0" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig1.0" - sourceFigNode="Fig2" - destFigNode="Fig1" - - - - - - - <<includes>> - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig1.0" - sourceFigNode="Fig4" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig1.0" - sourceFigNode="Fig5" - destFigNode="Fig1" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig6.0" - destPortFig="Fig2.0" - sourceFigNode="Fig6" - destFigNode="Fig2" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig7.0" - destPortFig="Fig2.0" - sourceFigNode="Fig7" - destFigNode="Fig2" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig8.0" - destPortFig="Fig2.0" - sourceFigNode="Fig8" - destFigNode="Fig2" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig3.0" - sourceFigNode="Fig2" - destFigNode="Fig3" - - - - - - - <<extends>> - - - - - sourcePortFig="Fig9.0" - destPortFig="Fig4.0" - sourceFigNode="Fig9" - destFigNode="Fig4" - - - - - - - uses - - - - - sourcePortFig="Fig9.0" - destPortFig="Fig5.0" - sourceFigNode="Fig9" - destFigNode="Fig5" - - - - - - - uses - - - - - sourcePortFig="Fig10.0" - destPortFig="Fig2.0" - sourceFigNode="Fig10" - destFigNode="Fig2" - - - - - - - <<extends>> - - - diff --git a/trunk/src/models/PropertyTableClassDiagram.pgml b/trunk/src/models/PropertyTableClassDiagram.pgml deleted file mode 100644 index de6ae19bb..000000000 --- a/trunk/src/models/PropertyTableClassDiagram.pgml +++ /dev/null @@ -1,818 +0,0 @@ - - - - - - - - - - Property - - -_name : String --_name_size : ShortField --_property_type : ByteField --_storage_type : ByteField --_previous_property : IntegerField --_next_property : IntegerField --_child_property : IntegerField --_seconds_1 : IntegerField --_days_1 : IntegerField --_seconds_2 : IntegerField --_days_2 : IntegerField --_start_block : IntegerField --_size : IntegerField --_raw_data[ 128 ] : byte --_index : int -+PROPERTY_SIZE : int = 128 -#_NO_INDEX : int = -1 -#_DIRECTORY_TYPE : byte = 1 -#_DOCUMENT_TYPE : byte = 2 -#_ROOT_TYPE : byte = 5 -#_BIG_BLOCK_STORAGE : byte = 1 -#_SMALL_BLOCK_STORAGE : byte = 0 --_next_file : File --_previous_file : File - #setIndex(in index:int) -#preWrite() -#getIndex() : int -+setStartBlock(in startBlock:int) -#Property() -#setName(in name:String) -#setPropertyType(in propertyType:byte) -#setStorageType(in storageType:byte) -#setChildProperty(in child:int) -#getChildProperty() : int -#setSize(in size:int) -#shouldUseSmallBlocks() : boolean - - - - - - - RootProperty - - -_children : List - - - - - - - - DocumentProperty - - - +DocumentProperty(in name:String, in size:int) - - - - - - - PropertyBlock - - -_properties[ 4 ] : Property - +createPropertyBlockArray(in properties:List) : BlockWritable - - - - - - - PropertyTable - - -_properties : List --_blocks[ ] : BlockWritable --_start_block : int - +getRoot() : Directory -+addProperty(in property:Property) -+preWrite() -+PropertyTable() -+getStartBlock() : int - - - - - - - <<Interface>> - File - +getNextFile() : File -+setNextFile(in file:File) -+getPreviousFile() : File -+setPreviousFile(in file:File) - - - - - - - <<Interface>> - Directory - +getChildren() : Iterator -+addChild(in property:Property) - - - - sourcePortFig="Fig1.0" - destPortFig="Fig0.0" - sourceFigNode="Fig1" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig0.0" - sourceFigNode="Fig2" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig0.0" - sourceFigNode="Fig3" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig3.0" - sourceFigNode="Fig4" - destFigNode="Fig3" - - - - - - - - 1..* - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig0.0" - sourceFigNode="Fig4" - destFigNode="Fig0" - - - - - - - 1..* - - - - - sourcePortFig="Fig6.0" - destPortFig="Fig5.0" - sourceFigNode="Fig6" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig6.0" - sourceFigNode="Fig1" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig0.0" - destPortFig="Fig5.0" - sourceFigNode="Fig0" - destFigNode="Fig5" - - - - - - - - - diff --git a/trunk/src/models/analysismain.pgml b/trunk/src/models/analysismain.pgml deleted file mode 100644 index 5e2ca17bd..000000000 --- a/trunk/src/models/analysismain.pgml +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - - - - POI - - - - - - - HSSF - - - - - - - HSSFSerializer - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig1.0" - sourceFigNode="Fig2" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.0" - destPortFig="Fig0.0" - sourceFigNode="Fig1" - destFigNode="Fig0" - - - - - - - - - diff --git a/trunk/src/models/poi.argo b/trunk/src/models/poi.argo deleted file mode 100644 index 80c189b5b..000000000 --- a/trunk/src/models/poi.argo +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {} - - diff --git a/trunk/src/models/poi.xmi b/trunk/src/models/poi.xmi deleted file mode 100644 index 5feadacec..000000000 --- a/trunk/src/models/poi.xmi +++ /dev/null @@ -1,19132 +0,0 @@ - - - - - - Novosoft UML Library - 0.4.19 - - - - - - project - - - - - - - analysisModel - - - - - - - - - - POI - - - - - - - - - - - - - read existing filesystem - - - - - - - - - - - - - - - create the filesystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - read all bytes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create a header block from first 512 bytes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create blocks from all blocks that are not header,bat or property blocks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create bat blocks from bytes that are in bat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create property table blocks from bytes starting at header.rootstartblock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - assign BAT Blocks to the BAT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - derive property instances from the Property Table Blocks and add them to the property table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputStream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - write file system - - - - - - - - - - - - - - - - - - - - createFileSystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - createHeaderBlock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - createBlock [until all files have blocks] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create a record [until all files have records] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create bat block [if need more] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create a record [until all files have records] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - get the bat array info - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - get the extended bat array info - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set the bat info - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set the extended bat info - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create a block [if needed] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create a property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - add the propert to the block - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - write all blocks to stream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OutputStream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - read file system directory - - - - - - - - - - - - - requests directory listing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - enumerates properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - read existing file from file system - - - - - - - - - - - - - gets property from - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - gets property from - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - gets BAT Chain from - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - gets next bat chain element [until all are read] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - gets bytes [from each block in bat chain] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - constructs a byte array input stream with file bytes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - requests file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - returns input stream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PropertyBlock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ByteArrayInputStream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - delete file from file system - - - - - - - - - - - - - replace file in file system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - read file - - - - - - - - - - - - - - - - - - - uses - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uses - - - - - - - - - - - - - - - - - - - - - - - - - - rename existing file in file system - - - - - - - - - - - - - - - - - - - - - - - - - POIFileSystem - - - - - - - - - - - - readFileSystem(InputStream in) - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - - - Block - - - - - - - - - - - - - - - - - createBlock(byte[] bytes, int offset, int length) - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - - - HeaderBlock - - - - - - - - - - - - - - - BATBlock - - - - - - - - - - - - - - - PropertyTableBlock - - - - - - - - - - - - - - - Property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - BAT - - - - - - - - - - - - createRecord - - - - - - - - - - - - - - - - return - - - - - - - - - - - bytes - - - - - - - - - - - - - - - - - - - - - - - getBlocks - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - blocks - - - - - - - - 0 - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void - - - - - - - - - - - PropertyTable - - - - - - - - - - - - createRecord - - - - - - - - - - - - - - - - return - - - - - - - - - - - name - - - - - - - - - - - startBlock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DirectoryProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FileProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - child - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - next - - - - - - - - - - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - previous - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HSSF - - - - - - - - - - - - - - - - ClientApps - - - - - - - - - - create HSSF File - - - - - - - - - - - - - create new filesystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - read existing HSSF File - - - - - - - - - - - - - - - write HSSF File - - - - - - - - - - - - - - - - - - read Workbook Entry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - write Workbook Entry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - write sheet entry - - - - - - - - - - - - - - - - - - - - - - - - - write new file to file system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - read Sheet Entry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HSSFSerializer - - - - - - - - - - - - - Cocoon - - - - - - - - - - Sends Sax Events - - - - - - - - - - - - - - - - - - - - Sends an Ignored Event - - - - - - - - - - - - - Sends and Interrogative Event - - - - - - - - - - - - - Sends Setup Event - - - - - - - - - - - - - Sends Start Document Event - - - - - - - - - - - - - Sends End Document Event - - - - - - - - - - - - - Sends Start Element Event - - - - - - - - - - - - - Sends End Element Event - - - - - - - - - - - - - Sends Raw Data Event - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - designModel - - - - - - - - - - Property - - - - - - - - - - - - - - - - - - - _name - - - - - - - - - - - - _name_size - - - - - - - - - - - - _property_type - - - - - - - - - - - - _storage_type - - - - - - - - - - - - _previous_property - - - - - - - - - - - - _next_property - - - - - - - - - - - - _child_property - - - - - - - - - - - - _seconds_1 - - - - - - - - - - - - _days_1 - - - - - - - - - - - - _seconds_2 - - - - - - - - - - - - _days_2 - - - - - - - - - - - - _start_block - - - - - - - - - - - - _size - - - - - - - - - - - - _raw_data[ 128 ] - - - - - - - - - - - - _index - - - - - - - - - - - - setIndex - - - - - - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - preWrite - - - - - - - - - - - - - - - - - - - - - - - - - - getIndex - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setStartBlock - - - - - - - - - - - - - - - - startBlock - - - - - - - - - - - - - - - - - - - - - - - PROPERTY_SIZE - - - - - - - java - 128 - - - - - - - - - - - _NO_INDEX - - - - - - - java - -1 - - - - - - - - - - - _DIRECTORY_TYPE - - - - - - - java - 1 - - - - - - - - - - - _DOCUMENT_TYPE - - - - - - - java - 2 - - - - - - - - - - - _ROOT_TYPE - - - - - - - java - 5 - - - - - - - - - - - _BIG_BLOCK_STORAGE - - - - - - - java - 1 - - - - - - - - - - - _SMALL_BLOCK_STORAGE - - - - - - - java - 0 - - - - - - - - - - - Property - - - - - - - - - - - - - - - - - - - - - - - - - - setName - - - - - - - - - - - - - - - - name - - - - - - - - - - - - - - - - - - - - - - - setPropertyType - - - - - - - - - - - - - - - - propertyType - - - - - - - - - - - - - - - - - - - - - - - setStorageType - - - - - - - - - - - - - - - - storageType - - - - - - - - - - - - - - - - - - - - - - - setChildProperty - - - - - - - - - - - - - - - - child - - - - - - - - - - - - - - - - - - - - - - - getChildProperty - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setSize - - - - - - - - - - - - - - - - size - - - - - - - - - - - - - - - - - - - - - - - shouldUseSmallBlocks - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - _next_file - - - - - - - - - - - - _previous_file - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - - - - _children - - - - - - - - - - - - - - DocumentProperty - - - - - - - - - - - - - - - DocumentProperty - - - - - - - - - - - - - - - - name - - - - - - - - - - - size - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PropertyBlock - - - - - - - - - - - - - - - - - - _properties[ 4 ] - - - - - - - - - - - - - createPropertyBlockArray - - - - - - - - - - - - - - - - return - - - - - - - - - - - properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - - _properties - - - - - - - - - - - - _blocks[ ] - - - - - - - - - - - - getRoot - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - addProperty - - - - - - - - - - - - - - - - property - - - - - - - - - - - - - - - - - - - - - - - preWrite - - - - - - - - - - - - - - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - - - - - - - - - - - - getStartBlock - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - _start_block - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - File - - - - - - - - - - - - - - - - - getNextFile - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setNextFile - - - - - - - - - - - - - - - - file - - - - - - - - - - - - - - - - - - - - - - - getPreviousFile - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setPreviousFile - - - - - - - - - - - - - - - - file - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - Directory - - - - - - - - - - - - - - - - - getChildren - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - addChild - - - - - - - - - - - - - - - - property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - BigBlock - - - - - - - - - - - - - - - - - - - - - writeData - - - - - - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - BIG_BLOCK_SIZE - - - - - - - java - 512 - - - - - - - - - - - doWriteData - - - - - - - - - - - - - - - - stream - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - - - HeaderBlock - - - - - - - - - - - - - - - _bat_count - - - - - - - - - - - - _property_start - - - - - - - - - - - - _sbat_start - - - - - - java - -2 - - - - - - - - - - - _xbat_start - - - - - - java - -2 - - - - - - - - - - - _xbat_count - - - - - - java - 0 - - - - - - - - - - - _data[ 512 ] - - - - - - - - - - - - setBATBlocks - - - - - - - - - - - - - - - - blockCount - - - - - - - - - - - startBlock - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setPropertyStart - - - - - - - - - - - - - - - - startBlock - - - - - - - - - - - - - - - - - - - - - - - setXBATStart - - - - - - - - - - - - - - - - startBlock - - - - - - - - - - - - - - - - - - - - - - - Header - - - - - - - - - - - - - - - - - - - - - - - - - - calculateXBATStorageRequirements - - - - - - - - - - - - - - - - return - - - - - - - - - - - blockCount - - - - - - - - - - - - - - - - - - - - - - - - - BATBlock - - - - - - - - - - - - - - - _fields[ 128 ] - - - - - - - - - - - - _data[ 512 ] - - - - - - - - - - - - createBATBlocks - - - - - - - - - - - - - - - - return - - - - - - - - - - - entries[] - - - - - - - - - - - - - - - - - - - - - - - calculateStorageRequirements - - - - - - - - - - - - - - - - return - - - - - - - - - - - entryCount - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - createDocument - - - - - - - - - - - - - - - - stream - - - - - - - - - - - name - - - - - - - - - - - - - - - - - - - - - - - writeFilesystem - - - - - - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - - - - - - - - - - - - _property_table - - - - - - - - - - - - _header_block - - - - - - - - - - - - _documents - - - - - - - - - - - - volatile - true - - - - - - - - - - Document - - - - - - - - - - - - - - - - getDocumentProperty - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - _property - - - - - - - - - - - - _blocks[] - - - - - - - - - - - - Document - - - - - - - - - - - - - - - - name - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DocumentBlock - - - - - - - - - - - - - - - - _data[ 512 ] - - - - - - - - - - - - DocumentBlock - - - - - - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - size - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - partiallyRead - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - _bytes_read - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BATManaged - - - - - - - - - - - - - - - countBlocks - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setStartBlock - - - - - - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - BlockWritable - - - - - - - - - - - - - - - - - writeBlocks - - - - - - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - BlockAllocationTable - - - - - - - - - - - - - - - createBlocks - - - - - - - - - - - - - - - - - - - - - - - - - - allocateSpace - - - - - - - - - - - - - - - - return - - - - - - - - - - - blockCount - - - - - - - - - - - - - - - - - - - - - - - _entries - - - - - - - - - - - - _blocks[] - - - - - - - - - - - - BlockAllocationTable - - - - - - - - - - - - - - - - - - - - - - - - - - countBlocks - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POIFSSerializer - - - - - - - - - - - - - - - startPrefixMapping - - - - - - - - - - - - - - - - ignoredPrefix - - - - - - - - - - - ignoredUri - - - - - - - - - - - - - - - - - - - - - - - endPrefixMapping - - - - - - - - - - - - - - - - ignoredPrefix - - - - - - - - - - - - - - - - - - - - - - - processingInstruction - - - - - - - - - - - - - - - - ignoredTarget - - - - - - - - - - - ignoredData - - - - - - - - - - - - - - - - - - - - - - - skippedEntity - - - - - - - - - - - - - - - - ignoredName - - - - - - - - - - - - - - - - - - - - - - - startDTD - - - - - - - - - - - - - - - - ignoredName - - - - - - - - - - - ignoredPublicId - - - - - - - - - - - ignoredSystemId - - - - - - - - - - - - - - - - - - - - - - - endDTD - - - - - - - - - - - - - - - - - - - - - - - - - - startEntity - - - - - - - - - - - - - - - - ignoredName - - - - - - - - - - - - - - - - - - - - - - - endEntity - - - - - - - - - - - - - - - - ignoredName - - - - - - - - - - - - - - - - - - - - - - - startCDATA - - - - - - - - - - - - - - - - - - - - - - - - - - endCDATA - - - - - - - - - - - - - - - - - - - - - - - - - - comment - - - - - - - - - - - - - - - - ignoredCh[] - - - - - - - - - - - ignoredStart - - - - - - - - - - - ignoredLength - - - - - - - - - - - - - - - - - - - - - - - shouldSetContentLength - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - setOutputStream - - - - - - - - - - - - - - - - out - - - - - - - - - - - - - - - - - - - - - - - _output_stream - - - - - - java - null - - - - - - - - - - - _locator - - - - - - java - null - - - - - - - - - - - setDocumentLocator - - - - - - - - - - - - - - - - locator - - - - - - - - - - - - - - - - - - - - - - - startDocument - - - - - - - - - - - - - - - - - - - - - - - - - - endDocument - - - - - - - - - - - - - - - - - - - - - - - - - - startElement - - - - - - - - - - - - - - - - namespaceURI - - - - - - - - - - - localName - - - - - - - - - - - qName - - - - - - - - - - - atts - - - - - - - - - - - - - - - - - - - - - - - endElement - - - - - - - - - - - - - - - - namespaceURI - - - - - - - - - - - localName - - - - - - - - - - - qName - - - - - - - - - - - - - - - - - - - - - - - characters - - - - - - - - - - - - - - - - ch[] - - - - - - - - - - - start - - - - - - - - - - - length - - - - - - - - - - - - - - - - - - - - - - - ignorableWhitespace - - - - - - - - - - - - - - - - ch[] - - - - - - - - - - - start - - - - - - - - - - - length - - - - - - - - - - - - - - - - - - - - - - - _open_elements - - - - - - java - new Stack() - - - - - - - - - - - _filesystem - - - - - - java - new Filesystem() - - - - - - - - - - - getElementProcessorFactory - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - doLocalPreEndDocument - - - - - - - - - - - - - - - - - - - - - - - - - - doLocalPostEndDocument - - - - - - - - - - - - - - - - - - - - - - - - - - getFilesystem - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - SAXExceptionFactory - - - - - - - - - - - - - - - - return - - - - - - - - - - - message - - - - - - - - - - - e - - - - - - - - - - - - - - - - - - - - - - - SAXExceptionFactory - - - - - - - - - - - - - - - - return - - - - - - - - - - - message - - - - - - - - - - - - - - - - - - - - - - - - - org.xml.sax - - - - - - - - - - Locator - - - - - - - - - - Attributes - - - - - - - - - - SAXException - - - - - - - - - - - - - Attribute - - - - - - - - - - - - _name - - - - - - - - - - - - - _value - - - - - - - - - - - - - getName - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - getValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - getValueAsInt - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - getValueAsShort - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - getValueAsLong - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - getValueAsBoolean - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - Attribute - - - - - - - - - - - - - - - - name - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - - - ElementProcessor - - - - - - - - - - - initialize - - - - - - - - - - - - - - - - attributes[] - - - - - - - - - - - parent - - - - - - - - - - - filesystem - - - - - - - - - - - - - - - - - - - - - - - acceptCharacters - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - acceptWhitespaceCharacters - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - endProcessing - - - - - - - - - - - - - - - - - - - - - - - - - - - - ElementProcessorFactory - - - - - - - - - - - - - - - _element_processor_map - - - - - - - - - - - - - createElementProcessor - - - - - - - - - - - - - - - - return - - - - - - - - - - - name - - - - - - - - - - - - - - - - - - - - - - - addElementProcessorProgenitor - - - - - - - - - - - - - - - - name - - - - - - - - - - - progenitor - - - - - - - - - - - - - - - - - - - - - - - lookupElementProcessorProgenitor - - - - - - - - - - - - - - - - return - - - - - - - - - - - name - - - - - - - - - - - - - - - - - - - - - - - doCreateElementProcessor - - - - - - - - - - - - - - - - return - - - - - - - - - - - progenitor - - - - - - - - - - - - - - - - - - - - - - - constructElementProcessor - - - - - - - - - - - - - - - - return - - - - - - - - - - - progenitor - - - - - - - - - - - - - - - - - - - - - - - createNewElementProcessorInstance - - - - - - - - - - - - - - - - return - - - - - - - - - - - progenitor - - - - - - - - - - - - - - - - - - - - - - - - - HSSFSerializer - - - - - - - - - - - - - - - _element_processor_factory - - - - - - - - - - - - getMimeType - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HSSFElementProcessorFactory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ElementProcessorFactory.CannotCreateElementProcessorException - - - - - - - - - - - - - - - - - - - - - - - - - - - includes - - - - - - - - - - - - - extends - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - java - - - - - - - - - - lang - - - - - - - - - - Object - - - - - - - - - - - Integer - - - - - - - - - - - int - - - - - - - - - - String - - - - - - - - - - - Char - - - - - - - - - - - short - - - - - - - - - - byte - - - - - - - - - - Byte - - - - - - - - - - - Short - - - - - - - - - - - boolean - - - - - - - - - - long - - - - - - - - - - double - - - - - - - - - - char - - - - - - - - - - Cloneable - - - - - - - - - - - reflect - - - - - - - - - - Constructor - - - - - - - - - - - - - Class - - - - - - - - - - - Exception - - - - - - - - - - - - - util - - - - - - - - - - Iterator - - - - - - - - - - Collection - - - - - - - - - - List - - - - - - - - - - Vector - - - - - - - - - - - SortedSet - - - - - - - - - - Set - - - - - - - - - - Stack - - - - - - - - - - - Map - - - - - - - - - - - - io - - - - - - - - - - InputStream - - - - - - - - - - - OutputStream - - - - - - - - - - - - - - - util - - - - - - - - - - FixedField - - - - - - - - - - - - - - - - - readFromBytes - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - readFromStream - - - - - - - - - - - - - - - - return - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - writeToBytes - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - toString - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - - - BitField - - - - - - - - - - - - getValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - getShortValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - getRawValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - getShortRawValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - isSet - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - isAllSet - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - setValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - setShortValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - clear - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - clearShort - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - clearByte - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - setShort - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - setByte - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - - - - - - - - - - - - - setBoolean - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - flag - - - - - - - - - - - - - - - - - - - - - - - setShortBoolean - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - flag - - - - - - - - - - - - - - - - - - - - - - - setByteBoolean - - - - - - - - - - - - - - - - return - - - - - - - - - - - holder - - - - - - - - - - - flag - - - - - - - - - - - - - - - - - - - - - - - - - ByteField - - - - - - - - - - - - - - - get - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - - - HexDump - - - - - - - - - - - - EOL - - - - - - - - - - - - dump - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - stream - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - - - IntList - - - - - - - - - - - - add - - - - - - - - - - - - - - - - index - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - add - - - - - - - - - - - - - - - - return - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - addAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - addAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - clear - - - - - - - - - - - - - - - - - - - - - - - - - - contains - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - containsAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - equals - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - get - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - hashCode - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - indexOf - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - isEmpty - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - lastIndexOf - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - remove - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - removeValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - removeAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - retainAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - element - - - - - - - - - - - - - - - - - - - - - - - size - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - toArray - - - - - - - - - - - - - - - - return[] - - - - - - - - - - - - - - - - - - - - - - - toArray - - - - - - - - - - - - - - - - return[] - - - - - - - - - - - a[] - - - - - - - - - - - - - - - - - - - - - - - - - LittleEndian - - - - - - - - - - - - BufferUnderrunException - - - - - - - - - - - - - - getShort - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - - - - - - - - - - - - - getShort - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - getInt - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - - - - - - - - - - - - - getInt - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - getLong - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - - - - - - - - - - - - - getDouble - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - - - - - - - - - - - - - getDouble - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - putShort - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - putShort - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - getLong - - - - - - - - - - - - - - - - return - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - putInt - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - putInt - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - putLong - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - offset - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - putLong - - - - - - - - - - - - - - - - data[] - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - readShort - - - - - - - - - - - - - - - - return - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - readInt - - - - - - - - - - - - - - - - return - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - readLong - - - - - - - - - - - - - - - - return - - - - - - - - - - - stream - - - - - - - - - - - - - - - - - - - - - - - readFromStream - - - - - - - - - - - - - - - - return [] - - - - - - - - - - - stream - - - - - - - - - - - size - - - - - - - - - - - - - - - - - - - - - - - - - LittleEndianConsts - - - - - - - - - - - - SHORT_SIZE - - - - - - - java - 2 - - - - - - - - - - - INT_SIZE - - - - - - - java - 4 - - - - - - - - - - - LONG_SIZE - - - - - - - java - 8 - - - - - - - - - - - DOUBLE_SIZE - - - - - - - java - 8 - - - - - - - - - - - transient - false - - - - - - - - - - LongField - - - - - - - - - - - - - - - get - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - - - ShortField - - - - - - - - - - - - - - - get - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - - - ShortList - - - - - - - - - - - - add - - - - - - - - - - - - - - - - index - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - add - - - - - - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - addAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - addAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - clear - - - - - - - - - - - - - - - - - - - - - - - - - - contains - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - containsAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - equals - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - get - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - hashCode - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - indexOf - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - isEmpty - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - lastIndexof - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - remove - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - - - - - - - - - - - - - removeValue - - - - - - - - - - - - - - - - return - - - - - - - - - - - o - - - - - - - - - - - - - - - - - - - - - - - removeAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - retainAll - - - - - - - - - - - - - - - - return - - - - - - - - - - - c - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - return - - - - - - - - - - - index - - - - - - - - - - - element - - - - - - - - - - - - - - - - - - - - - - - size - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - toArray - - - - - - - - - - - - - - - - return[] - - - - - - - - - - - - - - - - - - - - - - - toArray - - - - - - - - - - - - - - - - return [] - - - - - - - - - - - a[] - - - - - - - - - - - - - - - - - - - - - - - - - IntegerField - - - - - - - - - - - - - - - get - - - - - - - - - - - - - - - - return - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - - - - - - - - - - - - - set - - - - - - - - - - - - - - - - value - - - - - - - - - - - data[] - - - - - - - - - - - - - - - - - - - - - - - - - StringUtil - - - - - - - - - - - - getFromUnicode - - - - - - - - - - - - - - - - return - - - - - - - - - - - string[] - - - - - - - - - - - offset - - - - - - - - - - - len - - - - - - - - - - - - - - - - - - - - - - - getFromUnicode - - - - - - - - - - - - - - - - return - - - - - - - - - - - string[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - - - - - - - - - - - realize - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - addProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - addChild - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - - - HeaderBlock - - - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - getDocumentProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - getRoot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create (multiple) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - - - - - - - Document - - - - - - - - - - - - - - - - - - - - - DocumentBlock - - - - - - - - - - - - - DocumentProperty - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create (1 .. n) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - getDocumentProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - addProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - getRoot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - addChild - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - setIndex (for each Property) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - createPropertyBlockArray - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create (enough so we have a multiple of 4 properties) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create (1 for every 4 properties) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - preWrite (for each Property) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setNextFile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set _child_property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setPreviousFile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - preWrite - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - countBlocks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - allocateSpace - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setStartBlock - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - createBlocks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setBatBlocks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setPropertyStart - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - writeBlocks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setXBATStart - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - createDocument - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - writeFileSystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - HeaderBlock - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - - - - - - - Document - - - - - - - - - - - - - - - - - - - - - DocumentProperty - - - - - - - - - - - - - DocumentBlock - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - - - - - Property - - - - - - - - - - - - - - - PropertyBlock - - - - - - - - - - - - - - - - - - - PropertyBlock - - - - - - - - - - - - - Property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RootProperty - - - - - - - - - - - - - - - - - - - - - Property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PropertyTable - - - - - - - - - - - - - BATManaged - - - - - - - - - - - - - - - BlockAllocationTable - - - - - - - - - - - - - - - - - HeaderBlock - - - - - - - - - - - - - - - - - BlockWritable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Client Application) - - - - - - - - - - - - - - - - - Filesystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/models/poifsAnalysisClasses.pgml b/trunk/src/models/poifsAnalysisClasses.pgml deleted file mode 100644 index 91ae56432..000000000 --- a/trunk/src/models/poifsAnalysisClasses.pgml +++ /dev/null @@ -1,1243 +0,0 @@ - - - - - - - - - - POIFileSystem - - - +readFileSystem(InputStream in)() : POIFileSystem - - - - - - - Block - - - +createBlock(byte[] bytes, int offset, int length)() : Block - - - - - - - HeaderBlock - - - - - - - - - - BATBlock - - - - - - - - - - PropertyTableBlock - - - - - - - - - - Property - - - - - - - - - - RootProperty - - - - - - - - - - BAT - - -blocks[0..*] : BATBlock - +createRecord(bytes:Collection) : int -+getBlocks() : Collection - - - - - - - PropertyTable - - - +createRecord(name:String, startBlock:int, :) - - - - - - - DirectoryProperty - - - - - - - - - - FileProperty - - - - - - - sourcePortFig="Fig3.0" - destPortFig="Fig1.0" - sourceFigNode="Fig3" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig1.0" - sourceFigNode="Fig4" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig2.0" - destPortFig="Fig1.0" - sourceFigNode="Fig2" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig7.0" - destPortFig="Fig1.0" - sourceFigNode="Fig7" - destFigNode="Fig1" - - - - - - - 0..* - - - - - sourcePortFig="Fig4.0" - destPortFig="Fig5.0" - sourceFigNode="Fig4" - destFigNode="Fig5" - - - - - - - 0..* - - - - - sourcePortFig="Fig9.0" - destPortFig="Fig5.0" - sourceFigNode="Fig9" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig6.0" - destPortFig="Fig9.0" - sourceFigNode="Fig6" - destFigNode="Fig9" - - - - - - - - - - - sourcePortFig="Fig10.0" - destPortFig="Fig5.0" - sourceFigNode="Fig10" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig9.0" - destPortFig="Fig5.0" - sourceFigNode="Fig9" - destFigNode="Fig5" - - - - - - - child - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig5.0" - sourceFigNode="Fig5" - destFigNode="Fig5" - - - - - - - - - +next - 0..1 - - - - - sourcePortFig="Fig5.0" - destPortFig="Fig5.0" - sourceFigNode="Fig5" - destFigNode="Fig5" - - - - - - - - - 0..1 - previous - - - diff --git a/trunk/src/models/projectmain.pgml b/trunk/src/models/projectmain.pgml deleted file mode 100644 index e385871f9..000000000 --- a/trunk/src/models/projectmain.pgml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - analysisModel - - - - - - - designModel - - - - - - - util - - - diff --git a/trunk/src/models/readFileFromFilesystemSequenceDiagram.pgml b/trunk/src/models/readFileFromFilesystemSequenceDiagram.pgml deleted file mode 100644 index e2af7401f..000000000 --- a/trunk/src/models/readFileFromFilesystemSequenceDiagram.pgml +++ /dev/null @@ -1,1296 +0,0 @@ - - - - - - - enclosingFig="Fig0" - - - - : ClientApps - - - - - - - - - - - - - - - - enclosingFig="Fig1" - - - - : POIFileSystem - - - - - - - - - - - - - - - - - - - - enclosingFig="Fig2" - - - - : PropertyTable - - - - - - - - - - - - - - - - enclosingFig="Fig3" - - - - PropertyBlock : - - - - - - - - - - - - - - - enclosingFig="Fig4" - - - - : BAT - - - - - - - - - - - - - - - - enclosingFig="Fig5" - - - - : BATBlock - - - - - - - - - - - - - - - enclosingFig="Fig6" - - - - : Block - - - - - - - - - - - - - - - enclosingFig="Fig7" - - - - ByteArrayInputStream : Object - - - - - - - - - - - - - - - - : gets property from - - - - - : gets property from - - - - - : gets BAT Chain from - - - - - : gets next bat chain element [until all are read] - - - - - : gets bytes [from each block in bat chain] - - - - - : constructs a byte array input stream with file bytes - - - - - : requests file - - - - - : returns input stream - - - - sourcePortFig="Fig1.7" - destPortFig="Fig2.7" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig2.8" - destPortFig="Fig3.7" - sourceFigNode="Fig2" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig1.8" - destPortFig="Fig4.7" - sourceFigNode="Fig1" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig4.8" - destPortFig="Fig5.7" - sourceFigNode="Fig4" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig1.9" - destPortFig="Fig6.7" - sourceFigNode="Fig1" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig1.10" - destPortFig="Fig7.7" - sourceFigNode="Fig1" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.11" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.12" - destPortFig="Fig0.8" - sourceFigNode="Fig1" - destFigNode="Fig0" - - - - - - - - - diff --git a/trunk/src/models/readFileSystemDirectorySequenceDiagram.pgml b/trunk/src/models/readFileSystemDirectorySequenceDiagram.pgml deleted file mode 100644 index 5456e960d..000000000 --- a/trunk/src/models/readFileSystemDirectorySequenceDiagram.pgml +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - - : ClientApps - - - - - - - - - - - - - - - - - - : POIFileSystem - - - - - - - - - - - - - - - - - - - : PropertyTable - - - - - - - - - - - - - - - - : requests directory listing - - - - - : enumerates properties - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.8" - destPortFig="Fig2.7" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - diff --git a/trunk/src/models/readFilesystemSequenceDiagram.pgml b/trunk/src/models/readFilesystemSequenceDiagram.pgml deleted file mode 100644 index 5c72dad5a..000000000 --- a/trunk/src/models/readFilesystemSequenceDiagram.pgml +++ /dev/null @@ -1,1382 +0,0 @@ - - - - - - - enclosingFig="Fig0" - - - - : ClientApps - - - - - - - - - - - - - - - enclosingFig="Fig1" - - - - : POIFileSystem - - - - - - - - - - - - - - - - - - - - - - - - - InputStream : Object - - - - - - - - - - - - - - - enclosingFig="Fig3" - - - - : HeaderBlock - - - - - - - - - - - - - - - enclosingFig="Fig4" - - - - : Block - - - - - - - - - - - - - - - enclosingFig="Fig5" - - - - : BATBlock - - - - - - - - - - - - - - - - - - : PropertyTableBlock - - - - - - - - - - - - - - - enclosingFig="Fig7" - - - - : BAT - - - - - - - - - - - - - - - - - - : PropertyTable - - - - - - - - - - - - - - - - : create the filesystem - - - - - : read all bytes - - - - - : create a header block from first 512 bytes - - - - - : create blocks from all blocks that are not header,bat or property blocks - - - - - : create bat blocks from bytes that are in bat - - - - - : create property table blocks from bytes starting at header.rootstartblock - - - - - : assign BAT Blocks to the BAT - - - - - : derive property instances from the Property Table Blocks and add them to the property table - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.8" - destPortFig="Fig2.7" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig1.9" - destPortFig="Fig3.7" - sourceFigNode="Fig1" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig1.10" - destPortFig="Fig4.7" - sourceFigNode="Fig1" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig1.11" - destPortFig="Fig5.7" - sourceFigNode="Fig1" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig1.12" - destPortFig="Fig6.7" - sourceFigNode="Fig1" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig1.13" - destPortFig="Fig7.7" - sourceFigNode="Fig1" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig1.14" - destPortFig="Fig8.7" - sourceFigNode="Fig1" - destFigNode="Fig8" - - - - - - - - - diff --git a/trunk/src/models/utilClasses.pgml b/trunk/src/models/utilClasses.pgml deleted file mode 100644 index d70dec548..000000000 --- a/trunk/src/models/utilClasses.pgml +++ /dev/null @@ -1,1123 +0,0 @@ - - - - - - - - - - <<Interface>> - FixedField - +readFromBytes(in data[]:byte) -+readFromStream(in stream:InputStream) -+writeToBytes(in data[]:byte) -+toString() : String - - - - - - - BitField - - - +getValue(in holder:int) : int -+getShortValue(in holder:Short) : short -+getRawValue(in holder:int) : int -+getShortRawValue(in holder:short) : short -+isSet(in holder:int) : boolean -+isAllSet(in holder:int) : boolean -+setValue(in holder:int, in value:int) : int -+setShortValue(in holder:short, in value:short) : short -+clear(in holder:int) : int -+clearShort(in holder:short) : short -+clearByte(in holder:byte) : byte -+set(in holder:int) : int -+setShort(in holder:short) : short -+setByte(in holder:byte) : byte -+setBoolean(in holder:int, in flag:boolean) : int -+setShortBoolean(in holder:short, in flag:boolean) : short -+setByteBoolean(in holder:byte, in flag:boolean) : byte - - - - - - - ByteField - - - +get() : byte -+set(in value:byte) -+set(in value:byte, in data[]:byte) - - - - - - - HexDump - - +EOL : String - +dump(in data[]:byte, in offset:long, in stream:OutputStream, in index:int) - - - - - - - IntList - - - +add(in index:int, in value:int) -+add(in value:int) : boolean -+addAll(in c:IntList) : boolean -+addAll(in index:int, in c:IntList) : boolean -+clear() -+contains(in o:int) : boolean -+containsAll(in c:IntList) : boolean -+equals(in o:Object) : boolean -+get(in index:int) : int -+hashCode() : int -+indexOf(in o:int) : int -+isEmpty() : boolean -+lastIndexOf(in o:int) : int -+remove(in index:int) : int -+removeValue(in o:int) : boolean -+removeAll(in c:IntList) : boolean -+retainAll(in c:IntList) : boolean -+set(in index:int, in element:int) : int -+size() : int -+toArray() : int -+toArray(in a[]:int) : int - - - - - - - LittleEndian - - - +getShort(in data[]:byte, in offset:int) : short -+getShort(in data[]:byte) : short -+getInt(in data[]:byte, in offset:int) : int -+getInt(in data[]:byte) : int -+getLong(in data[]:byte, in offset:int) : long -+getDouble(in data[]:byte, in offset:int) : double -+getDouble(in data[]:byte) : double -+putShort(in data[]:byte, in offset:int, in value:short) -+putShort(in data[]:byte, in value:short) -+getLong(in data[]:byte) : long -+putInt(in data[]:byte, in offset:int, in value:int) -+putInt(in data[]:byte, in value:int) -+putLong(in data[]:byte, in offset:int, in value:long) -+putLong(in data[]:byte, in value:long) -+readShort(in stream:InputStream) : short -+readInt(in stream:InputStream) : int -+readLong(in stream:InputStream) : long -+readFromStream(in stream:InputStream, in size:int) : byte - - - - - - - LittleEndianConsts - - +SHORT_SIZE : int = 2 -+INT_SIZE : int = 4 -+LONG_SIZE : int = 8 -+DOUBLE_SIZE : int = 8 - - - - - - - - LongField - - - +get() : long -+set(in value:long) -+set(in value:long, in data[]:byte) - - - - - - - ShortField - - - +get() : short -+set(in value:short) -+set(in value:short, in data[]:byte) - - - - - - - ShortList - - - +add(in index:int, in value:short) -+add(in value:short) -+addAll(in c:ShortList) : boolean -+addAll(in index:int, in c:ShortList) : boolean -+clear() -+contains(in o:short) : boolean -+containsAll(in c:ShortList) : boolean -+equals(in o:Object) : boolean -+get(in index:int) : short -+hashCode() : int -+indexOf(in o:short) : int -+isEmpty() : boolean -+lastIndexof(in o:short) : int -+remove(in index:int) : short -+removeValue(in o:short) : boolean -+removeAll(in c:ShortList) : boolean -+retainAll(in return:boolean, in c:ShortList) -+set(in index:int, in element:short) : short -+size() : int -+toArray() : short -+toArray(in a[]:short) : short - - - - - - - IntegerField - - - +get() : int -+set(in value:int) -+set(in value:int, in data[]:byte) - - - - - - - StringUtil - - - +getFromUnicode(in string[]:byte, in offset:int, in len:int) : String -+getFromUnicode(in string[]:byte) : String - - - - sourcePortFig="Fig2.0" - destPortFig="Fig0.0" - sourceFigNode="Fig2" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig10.0" - destPortFig="Fig0.0" - sourceFigNode="Fig10" - destFigNode="Fig0" - - - - - - - - - - - - sourcePortFig="Fig7.0" - destPortFig="Fig0.0" - sourceFigNode="Fig7" - destFigNode="Fig0" - - - - - - - - - - - sourcePortFig="Fig8.0" - destPortFig="Fig0.0" - sourceFigNode="Fig8" - destFigNode="Fig0" - - - - - - - - - diff --git a/trunk/src/models/writeFilesystemSequenceDiagram.pgml b/trunk/src/models/writeFilesystemSequenceDiagram.pgml deleted file mode 100644 index fc5746c26..000000000 --- a/trunk/src/models/writeFilesystemSequenceDiagram.pgml +++ /dev/null @@ -1,1892 +0,0 @@ - - - - - - - - - - : ClientApps - - - - - - - - - - - - - - - - enclosingFig="Fig1" - - - - : POIFileSystem - - - - - - - - - - - - - - - - - - - - - - - enclosingFig="Fig2" - - - - : HeaderBlock - - - - - - - - - - - - - - - - - enclosingFig="Fig3" - - - - : Block - - - - - - - - - - - - - - - enclosingFig="Fig4" - - - - : BAT - - - - - - - - - - - - - - - - - - enclosingFig="Fig5" - - - - : BATBlock - - - - - - - - - - - - - - - - - - : PropertyTable - - - - - - - - - - - - - - - - - - enclosingFig="Fig7" - - - - : PropertyTableBlock - - - - - - - - - - - - - - - - enclosingFig="Fig8" - - - - : Property - - - - - - - - - - - - - - - enclosingFig="Fig9" - - - - OutputStream : Object - - - - - - - - - - - - - - - - : createFileSystem - - - - - : createHeaderBlock - - - - - : createBlock [until all files have blocks] - - - - - : create a record [until all files have records] - - - - - : create bat block [if need more] - - - - - : create a record [until all files have records] - - - - - : get the bat array info - - - - - : get the extended bat array info - - - - - : set the bat info - - - - - : set the extended bat info - - - - - : create a block [if needed] - - - - - : create a property - - - - - : add the propert to the block - - - - - : write all blocks to stream - - - - sourcePortFig="Fig0.7" - destPortFig="Fig1.7" - sourceFigNode="Fig0" - destFigNode="Fig1" - - - - - - - - - - - sourcePortFig="Fig1.8" - destPortFig="Fig2.7" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig1.9" - destPortFig="Fig3.7" - sourceFigNode="Fig1" - destFigNode="Fig3" - - - - - - - - - - - sourcePortFig="Fig1.10" - destPortFig="Fig4.7" - sourceFigNode="Fig1" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig4.8" - destPortFig="Fig5.7" - sourceFigNode="Fig4" - destFigNode="Fig5" - - - - - - - - - - - sourcePortFig="Fig1.11" - destPortFig="Fig6.7" - sourceFigNode="Fig1" - destFigNode="Fig6" - - - - - - - - - - - sourcePortFig="Fig1.12" - destPortFig="Fig4.9" - sourceFigNode="Fig1" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig1.13" - destPortFig="Fig4.10" - sourceFigNode="Fig1" - destFigNode="Fig4" - - - - - - - - - - - sourcePortFig="Fig1.14" - destPortFig="Fig2.8" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig1.15" - destPortFig="Fig2.9" - sourceFigNode="Fig1" - destFigNode="Fig2" - - - - - - - - - - - sourcePortFig="Fig6.8" - destPortFig="Fig7.7" - sourceFigNode="Fig6" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig6.9" - destPortFig="Fig8.7" - sourceFigNode="Fig6" - destFigNode="Fig8" - - - - - - - - - - - sourcePortFig="Fig6.10" - destPortFig="Fig7.8" - sourceFigNode="Fig6" - destFigNode="Fig7" - - - - - - - - - - - sourcePortFig="Fig0.8" - destPortFig="Fig9.7" - sourceFigNode="Fig0" - destFigNode="Fig9" - - - - - - - - - diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLDocument.java deleted file mode 100644 index 93afa6163..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ /dev/null @@ -1,250 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; -import org.apache.xmlbeans.impl.common.SystemCache; - -/** - * This holds the common functionality for all POI OOXML Document classes. - */ -// TODO: implements AutoCloseable in Java 7+ when POI drops support for Java 6. -public abstract class POIXMLDocument extends POIXMLDocumentPart implements Closeable { - public static final String DOCUMENT_CREATOR = "Apache POI"; - - // OLE embeddings relation name - public static final String OLE_OBJECT_REL_TYPE="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"; - - // Embedded OPC documents relation name - public static final String PACK_OBJECT_REL_TYPE="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"; - - /** The OPC Package */ - private OPCPackage pkg; - - /** - * The properties of the OPC package, opened as needed - */ - private POIXMLProperties properties; - - protected POIXMLDocument(OPCPackage pkg) { - super(pkg); - init(pkg); - } - - protected POIXMLDocument(OPCPackage pkg, String coreDocumentRel) { - super(pkg, coreDocumentRel); - init(pkg); - } - - private void init(OPCPackage p) { - this.pkg = p; - - // Workaround for XMLBEANS-512 - ensure that when we parse - // the file, we start with a fresh XML Parser each time, - // and avoid the risk of getting a SaxHandler that's in error - SystemCache.get().setSaxLoader(null); - } - - /** - * Wrapper to open a package, which works around shortcomings in java's this() constructor calls - * - * @param path the path to the document - * @return the new OPCPackage - * - * @exception IOException if there was a problem opening the document - */ - public static OPCPackage openPackage(String path) throws IOException { - try { - return OPCPackage.open(path); - } catch (InvalidFormatException e) { - throw new IOException(e.toString(), e); - } - } - - /** - * Get the assigned OPCPackage - * - * @return the assigned OPCPackage - */ - public OPCPackage getPackage() { - return this.pkg; - } - - protected PackagePart getCorePart() { - return getPackagePart(); - } - - /** - * Retrieves all the PackageParts which are defined as relationships of the base document with the - * specified content type. - * - * @param contentType the content type - * - * @return all the base document PackageParts which match the content type - * - * @throws InvalidFormatException when the relationships or the parts contain errors - * - * @see org.apache.poi.xssf.usermodel.XSSFRelation - * @see org.apache.poi.xslf.usermodel.XSLFRelation - * @see org.apache.poi.xwpf.usermodel.XWPFRelation - * @see org.apache.poi.xdgf.usermodel.XDGFRelation - */ - protected PackagePart[] getRelatedByType(String contentType) throws InvalidFormatException { - PackageRelationshipCollection partsC = - getPackagePart().getRelationshipsByType(contentType); - - PackagePart[] parts = new PackagePart[partsC.size()]; - int count = 0; - for (PackageRelationship rel : partsC) { - parts[count] = getPackagePart().getRelatedPart(rel); - count++; - } - return parts; - } - - /** - * Checks that the supplied InputStream (which MUST - * support mark and reset, or be a PushbackInputStream) - * has a OOXML (zip) header at the start of it. - * If your InputStream does not support mark / reset, - * then wrap it in a PushBackInputStream, then be - * sure to always use that, and not the original! - * - * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream - * @return true, if the InputStream is an ooxml document - * - * @throws IOException if the InputStream can't be read - * - * @deprecated use the method from DocumentFactoryHelper, deprecated as of 3.15-beta1, therefore eligible for removal in 3.17 - */ - @Deprecated - public static boolean hasOOXMLHeader(InputStream inp) throws IOException { - return DocumentFactoryHelper.hasOOXMLHeader(inp); - } - - /** - * Get the document properties. This gives you access to the - * core ooxml properties, and the extended ooxml properties. - * - * @return the document properties - */ - public POIXMLProperties getProperties() { - if(properties == null) { - try { - properties = new POIXMLProperties(pkg); - } catch (Exception e){ - throw new POIXMLException(e); - } - } - return properties; - } - - /** - * Get the document's embedded files. - * - * @return the document's embedded files - * - * @throws OpenXML4JException if the embedded parts can't be determined - */ - public abstract List getAllEmbedds() throws OpenXML4JException; - - protected final void load(POIXMLFactory factory) throws IOException { - Map context = new HashMap(); - try { - read(factory, context); - } catch (OpenXML4JException e){ - throw new POIXMLException(e); - } - onDocumentRead(); - context.clear(); - } - - /** - * Closes the underlying {@link OPCPackage} from which this - * document was read, if there is one - * - *

        Once this has been called, no further - * operations, updates or reads should be performed on the - * document. - * - * @throws IOException for writable packages, if an IO exception occur during the saving process. - */ - @Override - public void close() throws IOException { - if (pkg != null) { - if (pkg.getPackageAccess() == PackageAccess.READ) { - pkg.revert(); - } else { - pkg.close(); - } - pkg = null; - } - } - - /** - * Write out this document to an Outputstream. - * - * Note - if the Document was opened from a {@link File} rather - * than an {@link InputStream}, you must write out to - * a different file, overwriting via an OutputStream isn't possible. - * - * If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive - * or has a high cost/latency associated with each written byte, - * consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream} - * to improve write performance. - * - * @param stream - the java OutputStream you wish to write the file to - * - * @exception IOException if anything can't be written. - */ - @SuppressWarnings("resource") - public final void write(OutputStream stream) throws IOException { - OPCPackage p = getPackage(); - if(p == null) { - throw new IOException("Cannot write data, document seems to have been closed already"); - } - - //force all children to commit their changes into the underlying OOXML Package - // TODO Shouldn't they be committing to the new one instead? - Set context = new HashSet(); - onSave(context); - context.clear(); - - //save extended and custom properties - getProperties().commit(); - - p.save(stream); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java deleted file mode 100644 index e1b94b64e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ /dev/null @@ -1,770 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException; -import org.apache.poi.openxml4j.opc.OPCPackage; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.usermodel.XSSFRelation; - -/** - * Represents an entry of a OOXML package. - * - *

        - * Each POIXMLDocumentPart keeps a reference to the underlying a {@link org.apache.poi.openxml4j.opc.PackagePart}. - *

        - */ -public class POIXMLDocumentPart { - private static final POILogger logger = POILogFactory.getLogger(POIXMLDocumentPart.class); - - private String coreDocumentRel = PackageRelationshipTypes.CORE_DOCUMENT; - private PackagePart packagePart; - private POIXMLDocumentPart parent; - private Map relations = new LinkedHashMap(); - - /** - * The RelationPart is a cached relationship between the document, which contains the RelationPart, - * and one of its referenced child document parts. - * The child document parts may only belong to one parent, but it's often referenced by other - * parents too, having varying {@link PackageRelationship#getId() relationship ids} pointing to it. - */ - public static class RelationPart { - private final PackageRelationship relationship; - private final POIXMLDocumentPart documentPart; - - RelationPart(PackageRelationship relationship, POIXMLDocumentPart documentPart) { - this.relationship = relationship; - this.documentPart = documentPart; - } - - /** - * @return the cached relationship, which uniquely identifies this child document part within the parent - */ - public PackageRelationship getRelationship() { - return relationship; - } - - /** - * @param the cast of the caller to a document sub class - * - * @return the child document part - */ - @SuppressWarnings("unchecked") - public T getDocumentPart() { - return (T)documentPart; - } - } - - /** - * Counter that provides the amount of incoming relations from other parts - * to this part. - */ - private int relationCounter = 0; - - int incrementRelationCounter() { - relationCounter++; - return relationCounter; - } - - int decrementRelationCounter() { - relationCounter--; - return relationCounter; - } - - int getRelationCounter() { - return relationCounter; - } - - /** - * Construct POIXMLDocumentPart representing a "core document" package part. - * - * @param pkg the OPCPackage containing this document - */ - public POIXMLDocumentPart(OPCPackage pkg) { - this(pkg, PackageRelationshipTypes.CORE_DOCUMENT); - } - - /** - * Construct POIXMLDocumentPart representing a custom "core document" package part. - * - * @param pkg the OPCPackage containing this document - * @param coreDocumentRel the relation type of this document - */ - public POIXMLDocumentPart(OPCPackage pkg, String coreDocumentRel) { - this(getPartFromOPCPackage(pkg, coreDocumentRel)); - this.coreDocumentRel = coreDocumentRel; - } - - /** - * Creates new POIXMLDocumentPart - called by client code to create new parts from scratch. - * - * @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean) - */ - public POIXMLDocumentPart() { - } - - /** - * Creates an POIXMLDocumentPart representing the given package part and relationship. - * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file. - * - * @param part - The package part that holds xml data representing this sheet. - * @see #read(POIXMLFactory, java.util.Map) - * - * @since POI 3.14-Beta1 - */ - public POIXMLDocumentPart(PackagePart part) { - this(null, part); - } - - /** - * Creates an POIXMLDocumentPart representing the given package part, relationship and parent - * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file. - * - * @param parent - Parent part - * @param part - The package part that holds xml data representing this sheet. - * @see #read(POIXMLFactory, java.util.Map) - * - * @since POI 3.14-Beta1 - */ - public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part) { - this.packagePart = part; - this.parent = parent; - } - - /** - * Creates an POIXMLDocumentPart representing the given package part and relationship. - * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file. - * - * @param part - The package part that holds xml data representing this sheet. - * @param rel - the relationship of the given package part - * @see #read(POIXMLFactory, java.util.Map) - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public POIXMLDocumentPart(PackagePart part, PackageRelationship rel){ - this(null, part); - } - - /** - * Creates an POIXMLDocumentPart representing the given package part, relationship and parent - * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an exisiting file. - * - * @param parent - Parent part - * @param part - The package part that holds xml data represenring this sheet. - * @param rel - the relationship of the given package part - * @see #read(POIXMLFactory, java.util.Map) - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel){ - this(parent, part); - } - - /** - * When you open something like a theme, call this to - * re-base the XML Document onto the core child of the - * current core document - * - * @param pkg the package to be rebased - * - * @throws InvalidFormatException if there was an error in the core document relation - * @throws IllegalStateException if there are more than one core document relations - */ - protected final void rebase(OPCPackage pkg) throws InvalidFormatException { - PackageRelationshipCollection cores = - packagePart.getRelationshipsByType(coreDocumentRel); - if(cores.size() != 1) { - throw new IllegalStateException( - "Tried to rebase using " + coreDocumentRel + - " but found " + cores.size() + " parts of the right type" - ); - } - packagePart = packagePart.getRelatedPart(cores.getRelationship(0)); - } - - /** - * Provides access to the underlying PackagePart - * - * @return the underlying PackagePart - */ - public final PackagePart getPackagePart(){ - return packagePart; - } - - /** - * Provides access to the PackageRelationship that identifies this POIXMLDocumentPart - * - * @return the PackageRelationship that identifies this POIXMLDocumentPart - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - @SuppressWarnings("resource") - public final PackageRelationship getPackageRelationship() { - if (this.parent != null) { - for (RelationPart rp : parent.getRelationParts()) { - if (rp.getDocumentPart() == this) { - return rp.getRelationship(); - } - } - } else { - OPCPackage pkg = getPackagePart().getPackage(); - String partName = getPackagePart().getPartName().getName(); - for (PackageRelationship rel : pkg.getRelationships()) { - if (rel.getTargetURI().toASCIIString().equals(partName)) { - return rel; - } - } - } - return null; - } - - /** - * Returns the list of child relations for this POIXMLDocumentPart - * - * @return child relations - */ - public final List getRelations(){ - List l = new ArrayList(); - for (RelationPart rp : relations.values()) { - l.add(rp.getDocumentPart()); - } - return Collections.unmodifiableList(l); - } - - /** - * Returns the list of child relations for this POIXMLDocumentPart - * - * @return child relations - */ - public final List getRelationParts() { - List l = new ArrayList(relations.values()); - return Collections.unmodifiableList(l); - } - - /** - * Returns the target {@link POIXMLDocumentPart}, where a - * {@link PackageRelationship} is set from the {@link PackagePart} of this - * {@link POIXMLDocumentPart} to the {@link PackagePart} of the target - * {@link POIXMLDocumentPart} with a {@link PackageRelationship#getId()} - * matching the given parameter value. - * - * @param id - * The relation id to look for - * @return the target part of the relation, or null, if none exists - */ - public final POIXMLDocumentPart getRelationById(String id) { - RelationPart rp = relations.get(id); - return (rp == null) ? null : rp.getDocumentPart(); - } - - /** - * Returns the {@link PackageRelationship#getId()} of the - * {@link PackageRelationship}, that sources from the {@link PackagePart} of - * this {@link POIXMLDocumentPart} to the {@link PackagePart} of the given - * parameter value. - * - * @param part - * The {@link POIXMLDocumentPart} for which the according - * relation-id shall be found. - * @return The value of the {@link PackageRelationship#getId()} or null, if - * parts are not related. - */ - public final String getRelationId(POIXMLDocumentPart part) { - for (RelationPart rp : relations.values()) { - if (rp.getDocumentPart() == part) { - return rp.getRelationship().getId(); - } - } - return null; - } - - /** - * Add a new child POIXMLDocumentPart - * - * @param id the id of an existing child to replace - * @param part the child to add - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public final void addRelation(String id, POIXMLDocumentPart part) { - PackageRelationship pr = part.getPackagePart().getRelationship(id); - addRelation(pr, part); - } - - /** - * Add a new child POIXMLDocumentPart - * - * @param relId the preferred relation id, when null the next free relation id will be used - * @param relationshipType the package relationship type - * @param part the child to add - * - * @return the new RelationPart - * - * @since 3.14-Beta1 - */ - public final RelationPart addRelation(String relId, POIXMLRelation relationshipType, POIXMLDocumentPart part) { - PackageRelationship pr = findExistingRelation(part); - if (pr == null) { - PackagePartName ppn = part.getPackagePart().getPartName(); - String relType = relationshipType.getRelation(); - pr = packagePart.addRelationship(ppn, TargetMode.INTERNAL, relType, relId); - } - addRelation(pr, part); - return new RelationPart(pr, part); - } - - /** - * Add a new child POIXMLDocumentPart - * - * @param pr the relationship of the child - * @param part the child to add - */ - private void addRelation(PackageRelationship pr, POIXMLDocumentPart part) { - relations.put(pr.getId(), new RelationPart(pr,part)); - part.incrementRelationCounter(); - - } - - /** - * Check if the new part was already added before via PackagePart.addRelationship() - * - * @param part to find the relationship for - * @return The existing relationship, or null if there isn't yet one - */ - private PackageRelationship findExistingRelation(POIXMLDocumentPart part) { - String ppn = part.getPackagePart().getPartName().getName(); - try { - for (PackageRelationship pr : packagePart.getRelationships()) { - if (pr.getTargetMode() == TargetMode.EXTERNAL) { - continue; - } - PackagePart pp = packagePart.getRelatedPart(pr); - if (ppn.equals(pp.getPartName().getName())) { - return pr; - } - } - } catch (InvalidFormatException e) { - throw new POIXMLException("invalid package relationships", e); - } - return null; - } - - /** - * Remove the relation to the specified part in this package and remove the - * part, if it is no longer needed. - * - * @param part the part which relation is to be removed from this document - */ - protected final void removeRelation(POIXMLDocumentPart part){ - removeRelation(part,true); - } - - /** - * Remove the relation to the specified part in this package and remove the - * part, if it is no longer needed and flag is set to true. - * - * @param part - * The related part, to which the relation shall be removed. - * @param removeUnusedParts - * true, if the part shall be removed from the package if not - * needed any longer. - * @return true, if the relation was removed - */ - protected final boolean removeRelation(POIXMLDocumentPart part, boolean removeUnusedParts){ - String id = getRelationId(part); - if (id == null) { - // part is not related with this POIXMLDocumentPart - return false; - } - /* decrement usage counter */ - part.decrementRelationCounter(); - /* remove packagepart relationship */ - getPackagePart().removeRelationship(id); - /* remove POIXMLDocument from relations */ - relations.remove(id); - - if (removeUnusedParts) { - /* if last relation to target part was removed, delete according target part */ - if (part.getRelationCounter() == 0) { - try { - part.onDocumentRemove(); - } catch (IOException e) { - throw new POIXMLException(e); - } - getPackagePart().getPackage().removePart(part.getPackagePart()); - } - } - return true; - } - - /** - * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent. - * - * @return the parent POIXMLDocumentPart or null for the root element. - */ - public final POIXMLDocumentPart getParent(){ - return parent; - } - - @Override - public String toString(){ - return packagePart == null ? "" : packagePart.toString(); - } - - /** - * Save the content in the underlying package part. - * Default implementation is empty meaning that the package part is left unmodified. - * - * Sub-classes should override and add logic to marshal the "model" into Ooxml4J. - * - * For example, the code saving a generic XML entry may look as follows: - *
        -     * protected void commit() throws IOException {
        -     *   PackagePart part = getPackagePart();
        -     *   OutputStream out = part.getOutputStream();
        -     *   XmlObject bean = getXmlBean(); //the "model" which holds changes in memory
        -     *   bean.save(out, DEFAULT_XML_OPTIONS);
        -     *   out.close();
        -     * }
        -     * 
        - * - * @throws IOException a subclass may throw an IOException if the changes can't be committed - */ - protected void commit() throws IOException { - - } - - /** - * Save changes in the underlying OOXML package. - * Recursively fires {@link #commit()} for each package part - * - * @param alreadySaved context set containing already visited nodes - * - * @throws IOException a related part may throw an IOException if the changes can't be saved - */ - protected final void onSave(Set alreadySaved) throws IOException{ - // this usually clears out previous content in the part... - prepareForCommit(); - - commit(); - alreadySaved.add(this.getPackagePart()); - for(RelationPart rp : relations.values()){ - POIXMLDocumentPart p = rp.getDocumentPart(); - if (!alreadySaved.contains(p.getPackagePart())) { - p.onSave(alreadySaved); - } - } - } - - /** - * Ensure that a memory based package part does not have lingering data from previous - * commit() calls. - * - * Note: This is overwritten for some objects, as *PictureData seem to store the actual content - * in the part directly without keeping a copy like all others therefore we need to handle them differently. - */ - protected void prepareForCommit() { - PackagePart part = this.getPackagePart(); - if(part != null) { - part.clear(); - } - } - - /** - * Create a new child POIXMLDocumentPart - * - * @param descriptor the part descriptor - * @param factory the factory that will create an instance of the requested relation - * @return the created child POIXMLDocumentPart - * @throws PartAlreadyExistsException - * If rule M1.12 is not verified : Packages shall not contain - * equivalent part names and package implementers shall neither - * create nor recognize packages with equivalent part names. - */ - public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){ - return createRelationship(descriptor, factory, -1, false).getDocumentPart(); - } - - /** - * Create a new child POIXMLDocumentPart - * - * @param descriptor the part descriptor - * @param factory the factory that will create an instance of the requested relation - * @param idx part number - * @return the created child POIXMLDocumentPart - * @throws PartAlreadyExistsException - * If rule M1.12 is not verified : Packages shall not contain - * equivalent part names and package implementers shall neither - * create nor recognize packages with equivalent part names. - */ - public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){ - return createRelationship(descriptor, factory, idx, false).getDocumentPart(); - } - - /** - * Identifies the next available part number for a part of the given type, - * if possible, otherwise -1 if none are available. - * The found (valid) index can then be safely given to - * {@link #createRelationship(POIXMLRelation, POIXMLFactory, int)} or - * {@link #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)} - * without naming clashes. - * If parts with other types are already claiming a name for this relationship - * type (eg a {@link XSSFRelation#CHART} using the drawing part namespace - * normally used by {@link XSSFRelation#DRAWINGS}), those will be considered - * when finding the next spare number. - * - * @param descriptor The relationship type to find the part number for - * @param minIdx The minimum free index to assign, use -1 for any - * @return The next free part number, or -1 if none available - */ - protected final int getNextPartNumber(POIXMLRelation descriptor, int minIdx) { - OPCPackage pkg = packagePart.getPackage(); - - try { - String name = descriptor.getDefaultFileName(); - if (name.equals(descriptor.getFileName(9999))) { - // Non-index based, check if default is free - PackagePartName ppName = PackagingURIHelper.createPartName(name); - if (pkg.containPart(ppName)) { - // Default name already taken, not index based, nothing free - return -1; - } else { - // Default name free - return 0; - } - } - - // Default to searching from 1, unless they asked for 0+ - int idx = (minIdx < 0) ? 1 : minIdx; - int maxIdx = minIdx + pkg.getParts().size(); - while (idx <= maxIdx) { - name = descriptor.getFileName(idx); - PackagePartName ppName = PackagingURIHelper.createPartName(name); - if (!pkg.containPart(ppName)) { - return idx; - } - idx++; - } - } catch (InvalidFormatException e) { - // Give a general wrapped exception for the problem - throw new POIXMLException(e); - } - return -1; - } - - /** - * Create a new child POIXMLDocumentPart - * - * @param descriptor the part descriptor - * @param factory the factory that will create an instance of the requested relation - * @param idx part number - * @param noRelation if true, then no relationship is added. - * @return the created child POIXMLDocumentPart - * @throws PartAlreadyExistsException - * If rule M1.12 is not verified : Packages shall not contain - * equivalent part names and package implementers shall neither - * create nor recognize packages with equivalent part names. - */ - protected final RelationPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){ - try { - PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx)); - PackageRelationship rel = null; - PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType()); - if(!noRelation) { - /* only add to relations, if according relationship is being created. */ - rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation()); - } - POIXMLDocumentPart doc = factory.newDocumentPart(descriptor); - doc.packagePart = part; - doc.parent = this; - if (!noRelation) { - /* only add to relations, if according relationship is being created. */ - addRelation(rel,doc); - } - - return new RelationPart(rel,doc); - } catch (PartAlreadyExistsException pae) { - // Return the specific exception so the user knows - // that the name is already taken - throw pae; - } catch (Exception e){ - // Give a general wrapped exception for the problem - throw new POIXMLException(e); - } - } - - /** - * Iterate through the underlying PackagePart and create child POIXMLFactory instances - * using the specified factory - * - * @param factory the factory object that creates POIXMLFactory instances - * @param context context map containing already visited noted keyed by targetURI - * - * @throws OpenXML4JException thrown when a related part can't be read - */ - protected void read(POIXMLFactory factory, Map context) throws OpenXML4JException { - PackagePart pp = getPackagePart(); - // add mapping a second time, in case of initial caller hasn't done so - POIXMLDocumentPart otherChild = context.put(pp, this); - if (otherChild != null && otherChild != this) { - throw new POIXMLException("Unique PackagePart-POIXMLDocumentPart relation broken!"); - } - - if (!pp.hasRelationships()) return; - - PackageRelationshipCollection rels = packagePart.getRelationships(); - List readLater = new ArrayList(); - - // scan breadth-first, so parent-relations are hopefully the shallowest element - for (PackageRelationship rel : rels) { - if(rel.getTargetMode() == TargetMode.INTERNAL){ - URI uri = rel.getTargetURI(); - - // check for internal references (e.g. '#Sheet1!A1') - PackagePartName relName; - if(uri.getRawFragment() != null) { - relName = PackagingURIHelper.createPartName(uri.getPath()); - } else { - relName = PackagingURIHelper.createPartName(uri); - } - - final PackagePart p = packagePart.getPackage().getPart(relName); - if (p == null) { - logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI()); - continue; - } - - POIXMLDocumentPart childPart = context.get(p); - if (childPart == null) { - childPart = factory.createDocumentPart(this, p); - childPart.parent = this; - // already add child to context, so other children can reference it - context.put(p, childPart); - readLater.add(childPart); - } - - addRelation(rel,childPart); - } - } - - for (POIXMLDocumentPart childPart : readLater) { - childPart.read(factory, context); - } - } - - /** - * Get the PackagePart that is the target of a relationship from this Part. - * - * @param rel The relationship - * @return The target part - * @throws InvalidFormatException thrown if the related part has is erroneous - */ - protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException { - return getPackagePart().getRelatedPart(rel); - } - - - /** - * Fired when a new package part is created - * - * @throws IOException a subclass may throw an IOException on document creation - */ - protected void onDocumentCreate() throws IOException { - - } - - /** - * Fired when a package part is read - * - * @throws IOException a subclass may throw an IOException when a document is read - */ - protected void onDocumentRead() throws IOException { - - } - - /** - * Fired when a package part is about to be removed from the package - * - * @throws IOException a subclass may throw an IOException when a document is removed - */ - protected void onDocumentRemove() throws IOException { - - } - - /** - * Internal method, do not use! - *

        - * This method only exists to allow access to protected {@link POIXMLDocumentPart#onDocumentRead()} - * from {@link org.apache.poi.xwpf.usermodel.XWPFDocument} without reflection. It should be removed. - * - * @param part the part which is to be read - * - * @throws IOException if the part can't be read - */ - @Internal @Deprecated - public static void _invokeOnDocumentRead(POIXMLDocumentPart part) throws IOException { - part.onDocumentRead(); - } - - /** - * Retrieves the core document part - * - * @since POI 3.14-Beta1 - */ - private static PackagePart getPartFromOPCPackage(OPCPackage pkg, String coreDocumentRel) { - PackageRelationship coreRel = pkg.getRelationshipsByType(coreDocumentRel).getRelationship(0); - - if (coreRel != null) { - PackagePart pp = pkg.getPart(coreRel); - if (pp == null) { - throw new POIXMLException("OOXML file structure broken/invalid - core document '"+coreRel.getTargetURI()+"' not found."); - } - return pp; - } - - coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0); - if (coreRel != null) { - throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699"); - } - - throw new POIXMLException("OOXML file structure broken/invalid - no core document found!"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLException.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLException.java deleted file mode 100644 index 82832ecff..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLException.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 - */ -@SuppressWarnings("serial") -public final class POIXMLException extends RuntimeException{ - /** - * Create a new POIXMLException with no - * detail mesage. - */ - public POIXMLException() { - super(); - } - - /** - * Create a new POIXMLException with - * the String specified as an error message. - * - * @param msg The error message for the exception. - */ - public POIXMLException(String msg) { - super(msg); - } - - /** - * Create a new POIXMLException with - * the String 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 null value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) - */ - public POIXMLException(String msg, Throwable cause) { - super(msg, cause); - } - - /** - * Create a new POIXMLException with - * the specified cause. - * - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) - */ - public POIXMLException(Throwable cause) { - super(cause); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLFactory.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLFactory.java deleted file mode 100644 index aabe964ae..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLFactory.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.lang.reflect.InvocationTargetException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Defines a factory API that enables sub-classes to create instances of POIXMLDocumentPart - */ -public abstract class POIXMLFactory { - private static final POILogger LOGGER = POILogFactory.getLogger(POIXMLFactory.class); - - private static final Class[] PARENT_PART = {POIXMLDocumentPart.class, PackagePart.class}; - private static final Class[] ORPHAN_PART = {PackagePart.class}; - - /** - * Create a POIXMLDocumentPart from existing package part and relation. This method is called - * from {@link POIXMLDocument#load(POIXMLFactory)} when parsing a document - * - * @param parent parent part - * @param part the PackagePart representing the created instance - * @return A new instance of a POIXMLDocumentPart. - * - * @since by POI 3.14-Beta1 - */ - public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackagePart part) { - PackageRelationship rel = getPackageRelationship(parent, part); - POIXMLRelation descriptor = getDescriptor(rel.getRelationshipType()); - - if (descriptor == null || descriptor.getRelationClass() == null) { - LOGGER.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType()); - return new POIXMLDocumentPart(parent, part); - } - - Class cls = descriptor.getRelationClass(); - try { - try { - return createDocumentPart(cls, PARENT_PART, new Object[]{parent, part}); - } catch (NoSuchMethodException e) { - return createDocumentPart(cls, ORPHAN_PART, new Object[]{part}); - } - } catch (Exception e) { - throw new POIXMLException(e); - } - } - - /** - * Need to delegate instantiation to sub class because of constructor visibility - * - * @param cls the document class to be instantiated - * @param classes the classes of the constructor arguments - * @param values the values of the constructor arguments - * @return the new document / part - * @throws SecurityException thrown if the object can't be instantiated - * @throws NoSuchMethodException thrown if there is no constructor found for the given arguments - * @throws InstantiationException thrown if the object can't be instantiated - * @throws IllegalAccessException thrown if the object can't be instantiated - * @throws InvocationTargetException thrown if the object can't be instantiated - * - * @since POI 3.14-Beta1 - */ - protected abstract POIXMLDocumentPart createDocumentPart - (Class cls, Class[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException; - - /** - * returns the descriptor for the given relationship type - * - * @param relationshipType the relationship type of the descriptor - * @return the descriptor or null if type is unknown - * - * @since POI 3.14-Beta1 - */ - protected abstract POIXMLRelation getDescriptor(String relationshipType); - - /** - * Create a POIXMLDocumentPart from existing package part and relation. This method is called - * from {@link POIXMLDocument#load(POIXMLFactory)} when parsing a document - * - * @param parent parent part - * @param rel the package part relationship - * @param part the PackagePart representing the created instance - * @return A new instance of a POIXMLDocumentPart. - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public final POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part) { - return createDocumentPart(parent, 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 POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor) { - Class cls = descriptor.getRelationClass(); - try { - return createDocumentPart(cls, null, null); - } catch (Exception e) { - throw new POIXMLException(e); - } - } - - /** - * Retrieves the package relationship of the child part within the parent - * - * @param parent the parent to search for the part - * @param part the part to look for - * - * @return the relationship - * - * @throws POIXMLException if the relations are erroneous or the part is not related - * - * @since POI 3.14-Beta1 - */ - protected PackageRelationship getPackageRelationship(POIXMLDocumentPart parent, PackagePart part) { - try { - String partName = part.getPartName().getName(); - for (PackageRelationship pr : parent.getPackagePart().getRelationships()) { - String packName = pr.getTargetURI().toASCIIString(); - if (packName.equalsIgnoreCase(partName)) { - return pr; - } - } - } catch (InvalidFormatException e) { - throw new POIXMLException("error while determining package relations", e); - } - - throw new POIXMLException("package part isn't a child of the parent document."); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLProperties.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLProperties.java deleted file mode 100644 index b956b7ee5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLProperties.java +++ /dev/null @@ -1,611 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Date; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -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.PackagePropertiesPart; -import org.apache.poi.openxml4j.util.Nullable; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty; - -/** - * Wrapper around the three different kinds of OOXML properties - * and metadata a document can have (Core, Extended and Custom), - * as well Thumbnails. - */ -public class POIXMLProperties { - private OPCPackage pkg; - private CoreProperties core; - private ExtendedProperties ext; - private CustomProperties cust; - - private PackagePart extPart; - private PackagePart custPart; - - - private static final org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument NEW_EXT_INSTANCE; - private static final org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument NEW_CUST_INSTANCE; - static { - NEW_EXT_INSTANCE = org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument.Factory.newInstance(); - NEW_EXT_INSTANCE.addNewProperties(); - - NEW_CUST_INSTANCE = org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument.Factory.newInstance(); - NEW_CUST_INSTANCE.addNewProperties(); - } - - public POIXMLProperties(OPCPackage docPackage) throws IOException, OpenXML4JException, XmlException { - this.pkg = docPackage; - - // Core properties - core = new CoreProperties((PackagePropertiesPart)pkg.getPackageProperties() ); - - // Extended properties - PackageRelationshipCollection extRel = - pkg.getRelationshipsByType(PackageRelationshipTypes.EXTENDED_PROPERTIES); - if(extRel.size() == 1) { - extPart = pkg.getPart( extRel.getRelationship(0)); - org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument props = org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument.Factory.parse( - extPart.getInputStream(), DEFAULT_XML_OPTIONS - ); - ext = new ExtendedProperties(props); - } else { - extPart = null; - ext = new ExtendedProperties((org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument)NEW_EXT_INSTANCE.copy()); - } - - // Custom properties - PackageRelationshipCollection custRel = - pkg.getRelationshipsByType(PackageRelationshipTypes.CUSTOM_PROPERTIES); - if(custRel.size() == 1) { - custPart = pkg.getPart( custRel.getRelationship(0)); - org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props = org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument.Factory.parse( - custPart.getInputStream(), DEFAULT_XML_OPTIONS - ); - cust = new CustomProperties(props); - } else { - custPart = null; - cust = new CustomProperties((org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument)NEW_CUST_INSTANCE.copy()); - } - } - - /** - * Returns the core document properties - * - * @return the core document properties - */ - public CoreProperties getCoreProperties() { - return core; - } - - /** - * Returns the extended document properties - * - * @return the extended document properties - */ - public ExtendedProperties getExtendedProperties() { - return ext; - } - - /** - * Returns the custom document properties - * - * @return the custom document properties - */ - public CustomProperties getCustomProperties() { - return cust; - } - - /** - * Returns the {@link PackagePart} for the Document - * Thumbnail, or null if there isn't one - * - * @return The Document Thumbnail part or null - */ - protected PackagePart getThumbnailPart() { - PackageRelationshipCollection rels = - pkg.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL); - if(rels.size() == 1) { - return pkg.getPart(rels.getRelationship(0)); - } - return null; - } - /** - * Returns the name of the Document thumbnail, eg - * thumbnail.jpeg, or null if there - * isn't one. - * - * @return The thumbnail filename, or null - */ - public String getThumbnailFilename() { - PackagePart tPart = getThumbnailPart(); - if (tPart == null) return null; - String name = tPart.getPartName().getName(); - return name.substring(name.lastIndexOf('/')); - } - /** - * Returns the Document thumbnail image data, or {@code null} if there isn't one. - * - * @return The thumbnail data, or null - * - * @throws IOException if the thumbnail can't be read - */ - public InputStream getThumbnailImage() throws IOException { - PackagePart tPart = getThumbnailPart(); - if (tPart == null) return null; - return tPart.getInputStream(); - } - - /** - * Sets the Thumbnail for the document, replacing any existing one. - * - * @param filename The filename for the thumbnail image, eg {@code thumbnail.jpg} - * @param imageData The inputstream to read the thumbnail image from - * - * @throws IOException if the thumbnail can't be written - */ - public void setThumbnail(String filename, InputStream imageData) throws IOException { - PackagePart tPart = getThumbnailPart(); - if (tPart == null) { - // New thumbnail - pkg.addThumbnail(filename, imageData); - } else { - // Change existing - String newType = ContentTypes.getContentTypeFromFileExtension(filename); - if (! newType.equals(tPart.getContentType())) { - throw new IllegalArgumentException("Can't set a Thumbnail of type " + - newType + " when existing one is of a different type " + - tPart.getContentType()); - } - StreamHelper.copyStream(imageData, tPart.getOutputStream()); - } - } - - /** - * Commit changes to the underlying OPC package - * - * @throws IOException if the properties can't be saved - * @throws POIXMLException if the properties are erroneous - */ - public void commit() throws IOException{ - - if(extPart == null && !NEW_EXT_INSTANCE.toString().equals(ext.props.toString())){ - try { - PackagePartName prtname = PackagingURIHelper.createPartName("/docProps/app.xml"); - pkg.addRelationship(prtname, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"); - extPart = pkg.createPart(prtname, "application/vnd.openxmlformats-officedocument.extended-properties+xml"); - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } - } - if(custPart == null && !NEW_CUST_INSTANCE.toString().equals(cust.props.toString())){ - try { - PackagePartName prtname = PackagingURIHelper.createPartName("/docProps/custom.xml"); - pkg.addRelationship(prtname, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties"); - custPart = pkg.createPart(prtname, "application/vnd.openxmlformats-officedocument.custom-properties+xml"); - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } - } - if(extPart != null){ - OutputStream out = extPart.getOutputStream(); - if (extPart.getSize() > 0) { - extPart.clear(); - } - ext.props.save(out, DEFAULT_XML_OPTIONS); - out.close(); - } - if(custPart != null){ - OutputStream out = custPart.getOutputStream(); - cust.props.save(out, DEFAULT_XML_OPTIONS); - out.close(); - } - } - - /** - * The core document properties - */ - public static class CoreProperties { - private PackagePropertiesPart part; - private CoreProperties(PackagePropertiesPart part) { - this.part = part; - } - - public String getCategory() { - return part.getCategoryProperty().getValue(); - } - public void setCategory(String category) { - part.setCategoryProperty(category); - } - public String getContentStatus() { - return part.getContentStatusProperty().getValue(); - } - public void setContentStatus(String contentStatus) { - part.setContentStatusProperty(contentStatus); - } - public String getContentType() { - return part.getContentTypeProperty().getValue(); - } - public void setContentType(String contentType) { - part.setContentTypeProperty(contentType); - } - public Date getCreated() { - return part.getCreatedProperty().getValue(); - } - public void setCreated(Nullable date) { - part.setCreatedProperty(date); - } - public void setCreated(String date) { - part.setCreatedProperty(date); - } - public String getCreator() { - return part.getCreatorProperty().getValue(); - } - public void setCreator(String creator) { - part.setCreatorProperty(creator); - } - public String getDescription() { - return part.getDescriptionProperty().getValue(); - } - public void setDescription(String description) { - part.setDescriptionProperty(description); - } - public String getIdentifier() { - return part.getIdentifierProperty().getValue(); - } - public void setIdentifier(String identifier) { - part.setIdentifierProperty(identifier); - } - public String getKeywords() { - return part.getKeywordsProperty().getValue(); - } - public void setKeywords(String keywords) { - part.setKeywordsProperty(keywords); - } - public Date getLastPrinted() { - return part.getLastPrintedProperty().getValue(); - } - public void setLastPrinted(Nullable date) { - part.setLastPrintedProperty(date); - } - public void setLastPrinted(String date) { - part.setLastPrintedProperty(date); - } - /** @since POI 3.15 beta 3 */ - public String getLastModifiedByUser() { - return part.getLastModifiedByProperty().getValue(); - } - /** @since POI 3.15 beta 3 */ - public void setLastModifiedByUser(String user) { - part.setLastModifiedByProperty(user); - } - public Date getModified() { - return part.getModifiedProperty().getValue(); - } - public void setModified(Nullable date) { - part.setModifiedProperty(date); - } - public void setModified(String date) { - part.setModifiedProperty(date); - } - public String getSubject() { - return part.getSubjectProperty().getValue(); - } - public void setSubjectProperty(String subject) { - part.setSubjectProperty(subject); - } - public void setTitle(String title) { - part.setTitleProperty(title); - } - public String getTitle() { - return part.getTitleProperty().getValue(); - } - public String getRevision() { - return part.getRevisionProperty().getValue(); - } - public void setRevision(String revision) { - try { - Long.valueOf(revision); - part.setRevisionProperty(revision); - } - catch (NumberFormatException e) {} - } - - public PackagePropertiesPart getUnderlyingProperties() { - return part; - } - } - - /** - * Extended document properties - */ - public static class ExtendedProperties { - private org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument props; - private ExtendedProperties(org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument props) { - this.props = props; - } - - public org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties getUnderlyingProperties() { - return props.getProperties(); - } - - public String getTemplate() { - if (props.getProperties().isSetTemplate()) { - return props.getProperties().getTemplate(); - } - return null; - } - public String getManager() { - if (props.getProperties().isSetManager()) { - return props.getProperties().getManager(); - } - return null; - } - public String getCompany() { - if (props.getProperties().isSetCompany()) { - return props.getProperties().getCompany(); - } - return null; - } - public String getPresentationFormat() { - if (props.getProperties().isSetPresentationFormat()) { - return props.getProperties().getPresentationFormat(); - } - return null; - } - public String getApplication() { - if (props.getProperties().isSetApplication()) { - return props.getProperties().getApplication(); - } - return null; - } - public String getAppVersion() { - if (props.getProperties().isSetAppVersion()) { - return props.getProperties().getAppVersion(); - } - return null; - } - - public int getPages() { - if (props.getProperties().isSetPages()) { - return props.getProperties().getPages(); - } - return -1; - } - public int getWords() { - if (props.getProperties().isSetWords()) { - return props.getProperties().getWords(); - } - return -1; - } - public int getCharacters() { - if (props.getProperties().isSetCharacters()) { - return props.getProperties().getCharacters(); - } - return -1; - } - public int getCharactersWithSpaces() { - if (props.getProperties().isSetCharactersWithSpaces()) { - return props.getProperties().getCharactersWithSpaces(); - } - return -1; - } - public int getLines() { - if (props.getProperties().isSetLines()) { - return props.getProperties().getLines(); - } - return -1; - } - public int getParagraphs() { - if (props.getProperties().isSetParagraphs()) { - return props.getProperties().getParagraphs(); - } - return -1; - } - public int getSlides() { - if (props.getProperties().isSetSlides()) { - return props.getProperties().getSlides(); - } - return -1; - } - public int getNotes() { - if (props.getProperties().isSetNotes()) { - return props.getProperties().getNotes(); - } - return -1; - } - public int getTotalTime() { - if (props.getProperties().isSetTotalTime()) { - return props.getProperties().getTotalTime(); - } - return -1; - } - public int getHiddenSlides() { - if (props.getProperties().isSetHiddenSlides()) { - return props.getProperties().getHiddenSlides(); - } - return -1; - } - public int getMMClips() { - if (props.getProperties().isSetMMClips()) { - return props.getProperties().getMMClips(); - } - return -1; - } - - public String getHyperlinkBase() { - if (props.getProperties().isSetHyperlinkBase()) { - return props.getProperties().getHyperlinkBase(); - } - return null; - } - } - - /** - * Custom document properties - */ - public static class CustomProperties { - /** - * Each custom property element contains an fmtid attribute - * with the same GUID value ({D5CDD505-2E9C-101B-9397-08002B2CF9AE}). - */ - public static final String FORMAT_ID = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"; - - private org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props; - private CustomProperties(org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props) { - this.props = props; - } - - public org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties getUnderlyingProperties() { - return props.getProperties(); - } - - /** - * Add a new property - * - * @param name the property name - * @throws IllegalArgumentException if a property with this name already exists - */ - private CTProperty add(String name) { - if(contains(name)) { - throw new IllegalArgumentException("A property with this name " + - "already exists in the custom properties"); - } - - CTProperty p = props.getProperties().addNewProperty(); - int pid = nextPid(); - p.setPid(pid); - p.setFmtid(FORMAT_ID); - p.setName(name); - return p; - } - - /** - * Add a new string property - * - * @param name the property name - * @param value the property value - * - * @throws IllegalArgumentException if a property with this name already exists - */ - public void addProperty(String name, String value){ - CTProperty p = add(name); - p.setLpwstr(value); - } - - /** - * Add a new double property - * - * @param name the property name - * @param value the property value - * - * @throws IllegalArgumentException if a property with this name already exists - */ - public void addProperty(String name, double value){ - CTProperty p = add(name); - p.setR8(value); - } - - /** - * Add a new integer property - * - * @param name the property name - * @param value the property value - * - * @throws IllegalArgumentException if a property with this name already exists - */ - public void addProperty(String name, int value){ - CTProperty p = add(name); - p.setI4(value); - } - - /** - * Add a new boolean property - * - * @param name the property name - * @param value the property value - * - * @throws IllegalArgumentException if a property with this name already exists - */ - public void addProperty(String name, boolean value){ - CTProperty p = add(name); - p.setBool(value); - } - - /** - * Generate next id that uniquely relates a custom property - * - * @return next property id starting with 2 - */ - protected int nextPid() { - int propid = 1; - for(CTProperty p : props.getProperties().getPropertyArray()){ - if(p.getPid() > propid) propid = p.getPid(); - } - return propid + 1; - } - - /** - * Check if a property with this name already exists in the collection of custom properties - * - * @param name the name to check - * @return whether a property with the given name exists in the custom properties - */ - public boolean contains(String name) { - for(CTProperty p : props.getProperties().getPropertyArray()){ - if(p.getName().equals(name)) return true; - } - return false; - } - - /** - * Retrieve the custom property with this name, or null if none exists. - * - * You will need to test the various isSetX methods to work out - * what the type of the property is, before fetching the - * appropriate value for it. - * - * @param name the name of the property to fetch - * - * @return the custom property with this name, or null if none exists - */ - public CTProperty getProperty(String name) { - for(CTProperty p : props.getProperties().getPropertyArray()){ - if(p.getName().equals(name)) { - return p; - } - } - return null; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java deleted file mode 100644 index b2621ebd1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java +++ /dev/null @@ -1,279 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.math.BigDecimal; -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; -import org.apache.poi.util.LocaleUtil; -import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty; - -/** - * A {@link POITextExtractor} for returning the textual - * content of the OOXML file properties, eg author - * and title. - */ -public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { - - private final DateFormat dateFormat; - - /** - * Creates a new POIXMLPropertiesTextExtractor for the given open document. - * - * @param doc the given open document - */ - public POIXMLPropertiesTextExtractor(POIXMLDocument doc) { - super(doc); - DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ROOT); - dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dfs); - dateFormat.setTimeZone(LocaleUtil.TIMEZONE_UTC); - } - - /** - * Creates a new POIXMLPropertiesTextExtractor, for the - * same file that another TextExtractor is already - * working on. - * - * @param otherExtractor the extractor referencing the given file - */ - public POIXMLPropertiesTextExtractor(POIXMLTextExtractor otherExtractor) { - this(otherExtractor.getDocument()); - } - - private void appendIfPresent(StringBuffer text, String thing, boolean value) { - appendIfPresent(text, thing, Boolean.toString(value)); - } - private void appendIfPresent(StringBuffer text, String thing, int value) { - appendIfPresent(text, thing, Integer.toString(value)); - } - private void appendIfPresent(StringBuffer text, String thing, Date value) { - if(value == null) { return; } - appendIfPresent(text, thing, dateFormat.format(value)); - } - private void appendIfPresent(StringBuffer text, String thing, String value) { - if(value == null) { return; } - text.append(thing); - text.append(" = "); - text.append(value); - text.append("\n"); - } - - /** - * Returns the core document properties, eg author - * - * @return the core document properties - */ - @SuppressWarnings("resource") - public String getCorePropertiesText() { - POIXMLDocument document = getDocument(); - if(document == null) { // event based extractor does not have a document - return ""; - } - - StringBuffer text = new StringBuffer(); - PackagePropertiesPart props = - document.getProperties().getCoreProperties().getUnderlyingProperties(); - - appendIfPresent(text, "Category", props.getCategoryProperty().getValue()); - appendIfPresent(text, "Category", props.getCategoryProperty().getValue()); - appendIfPresent(text, "ContentStatus", props.getContentStatusProperty().getValue()); - appendIfPresent(text, "ContentType", props.getContentTypeProperty().getValue()); - appendIfPresent(text, "Created", props.getCreatedProperty().getValue()); - appendIfPresent(text, "CreatedString", props.getCreatedPropertyString()); - appendIfPresent(text, "Creator", props.getCreatorProperty().getValue()); - appendIfPresent(text, "Description", props.getDescriptionProperty().getValue()); - appendIfPresent(text, "Identifier", props.getIdentifierProperty().getValue()); - appendIfPresent(text, "Keywords", props.getKeywordsProperty().getValue()); - appendIfPresent(text, "Language", props.getLanguageProperty().getValue()); - appendIfPresent(text, "LastModifiedBy", props.getLastModifiedByProperty().getValue()); - appendIfPresent(text, "LastPrinted", props.getLastPrintedProperty().getValue()); - appendIfPresent(text, "LastPrintedString", props.getLastPrintedPropertyString()); - appendIfPresent(text, "Modified", props.getModifiedProperty().getValue()); - appendIfPresent(text, "ModifiedString", props.getModifiedPropertyString()); - appendIfPresent(text, "Revision", props.getRevisionProperty().getValue()); - appendIfPresent(text, "Subject", props.getSubjectProperty().getValue()); - appendIfPresent(text, "Title", props.getTitleProperty().getValue()); - appendIfPresent(text, "Version", props.getVersionProperty().getValue()); - - return text.toString(); - } - /** - * Returns the extended document properties, eg application - * - * @return the extended document properties - */ - @SuppressWarnings("resource") - public String getExtendedPropertiesText() { - POIXMLDocument document = getDocument(); - if(document == null) { // event based extractor does not have a document - return ""; - } - - StringBuffer text = new StringBuffer(); - org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties - props = document.getProperties().getExtendedProperties().getUnderlyingProperties(); - - appendIfPresent(text, "Application", props.getApplication()); - appendIfPresent(text, "AppVersion", props.getAppVersion()); - appendIfPresent(text, "Characters", props.getCharacters()); - appendIfPresent(text, "CharactersWithSpaces", props.getCharactersWithSpaces()); - appendIfPresent(text, "Company", props.getCompany()); - appendIfPresent(text, "HyperlinkBase", props.getHyperlinkBase()); - appendIfPresent(text, "HyperlinksChanged", props.getHyperlinksChanged()); - appendIfPresent(text, "Lines", props.getLines()); - appendIfPresent(text, "LinksUpToDate", props.getLinksUpToDate()); - appendIfPresent(text, "Manager", props.getManager()); - appendIfPresent(text, "Pages", props.getPages()); - appendIfPresent(text, "Paragraphs", props.getParagraphs()); - appendIfPresent(text, "PresentationFormat", props.getPresentationFormat()); - appendIfPresent(text, "Template", props.getTemplate()); - appendIfPresent(text, "TotalTime", props.getTotalTime()); - - return text.toString(); - } - /** - * Returns the custom document properties, if there are any - * - * @return the custom document properties - */ - @SuppressWarnings({ "resource" }) - public String getCustomPropertiesText() { - POIXMLDocument document = getDocument(); - if(document == null) { // event based extractor does not have a document - return ""; - } - - StringBuilder text = new StringBuilder(); - org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties - props = document.getProperties().getCustomProperties().getUnderlyingProperties(); - - for(CTProperty property : props.getPropertyArray()) { - String val = "(not implemented!)"; - - if (property.isSetLpwstr()) { - val = property.getLpwstr(); - } - else if (property.isSetLpstr()) { - val = property.getLpstr(); - } - else if (property.isSetDate()) { - val = property.getDate().toString(); - } - else if (property.isSetFiletime()) { - val = property.getFiletime().toString(); - } - else if (property.isSetBool()) { - val = Boolean.toString( property.getBool() ); - } - - // Integers - else if (property.isSetI1()) { - val = Integer.toString(property.getI1()); - } - else if (property.isSetI2()) { - val = Integer.toString(property.getI2()); - } - else if (property.isSetI4()) { - val = Integer.toString(property.getI4()); - } - else if (property.isSetI8()) { - val = Long.toString(property.getI8()); - } - else if (property.isSetInt()) { - val = Integer.toString( property.getInt() ); - } - - // Unsigned Integers - else if (property.isSetUi1()) { - val = Integer.toString(property.getUi1()); - } - else if (property.isSetUi2()) { - val = Integer.toString(property.getUi2()); - } - else if (property.isSetUi4()) { - val = Long.toString(property.getUi4()); - } - else if (property.isSetUi8()) { - val = property.getUi8().toString(); - } - else if (property.isSetUint()) { - val = Long.toString(property.getUint()); - } - - // Reals - else if (property.isSetR4()) { - val = Float.toString( property.getR4() ); - } - else if (property.isSetR8()) { - val = Double.toString( property.getR8() ); - } - else if (property.isSetDecimal()) { - BigDecimal d = property.getDecimal(); - if (d == null) { - val = null; - } else { - val = d.toPlainString(); - } - } - - /*else if (property.isSetArray()) { - // TODO Fetch the array values and output - } - else if (property.isSetVector()) { - // TODO Fetch the vector values and output - } - - else if (property.isSetBlob() || property.isSetOblob()) { - // TODO Decode, if possible - } - else if (property.isSetStream() || property.isSetOstream() || - property.isSetVstream()) { - // TODO Decode, if possible - } - else if (property.isSetStorage() || property.isSetOstorage()) { - // TODO Decode, if possible - }*/ - - text.append(property.getName()).append(" = ").append(val).append("\n"); - } - - return text.toString(); - } - - @Override - public String getText() { - try { - return - getCorePropertiesText() + - getExtendedPropertiesText() + - getCustomPropertiesText(); - } catch(Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public POIXMLPropertiesTextExtractor getMetadataTextExtractor() { - throw new IllegalStateException("You already have the Metadata Text Extractor, not recursing!"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLRelation.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLRelation.java deleted file mode 100644 index 8578f8025..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLRelation.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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. - */ -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 _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 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 - * - * @param index the suffix for the document type - * @return the filename including the suffix - */ - public String getFileName(int index) { - if(_defaultName.indexOf("#") == -1) { - // Generic filename in all cases - return getDefaultFileName(); - } - return _defaultName.replace("#", Integer.toString(index)); - } - - /** - * Returns the index of the filename within the package for the given part. - * e.g. 4 for /xl/comments4.xml - * - * @param part the part to read the suffix from - * @return the suffix - */ - public Integer getFileNameIndex(POIXMLDocumentPart part) { - String regex = _defaultName.replace("#", "(\\d+)"); - return Integer.valueOf(part.getPackagePart().getPartName().getName().replaceAll(regex, "$1")); - } - - /** - * Return type of the object used to construct instances of this relationship - * - * @return the class of the object used to construct instances of this relation - */ - public Class getRelationClass(){ - return _cls; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java deleted file mode 100644 index 954feb80e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java +++ /dev/null @@ -1,120 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.IOException; - -import org.apache.poi.POIXMLProperties.CoreProperties; -import org.apache.poi.POIXMLProperties.CustomProperties; -import org.apache.poi.POIXMLProperties.ExtendedProperties; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.util.ZipSecureFile; - -public abstract class POIXMLTextExtractor extends POITextExtractor { - /** The POIXMLDocument that's open */ - private final POIXMLDocument _document; - - /** - * Creates a new text extractor for the given document - * - * @param document the document to extract from - */ - public POIXMLTextExtractor(POIXMLDocument document) { - _document = document; - } - - /** - * Returns the core document properties - * - * @return the core document properties - */ - public CoreProperties getCoreProperties() { - return _document.getProperties().getCoreProperties(); - } - /** - * Returns the extended document properties - * - * @return the extended document properties - */ - public ExtendedProperties getExtendedProperties() { - return _document.getProperties().getExtendedProperties(); - } - /** - * Returns the custom document properties - * - * @return the custom document properties - */ - public CustomProperties getCustomProperties() { - return _document.getProperties().getCustomProperties(); - } - - /** - * Returns opened document - * - * @return the opened document - */ - public final POIXMLDocument getDocument() { - return _document; - } - - /** - * Returns the opened OPCPackage that contains the document - * - * @return the opened OPCPackage - */ - public OPCPackage getPackage() { - return _document.getPackage(); - } - - /** - * Returns an OOXML properties text extractor for the - * document properties metadata, such as title and author. - */ - @Override - public POIXMLPropertiesTextExtractor getMetadataTextExtractor() { - return new POIXMLPropertiesTextExtractor(_document); - } - - @Override - public void close() throws IOException { - // e.g. XSSFEventBaseExcelExtractor passes a null-document - if(_document != null) { - @SuppressWarnings("resource") - OPCPackage pkg = _document.getPackage(); - if(pkg != null) { - // revert the package to not re-write the file, which is very likely not wanted for a TextExtractor! - pkg.revert(); - } - } - super.close(); - } - - protected void checkMaxTextSize(StringBuffer text, String string) { - if(string == null) { - return; - } - - int size = text.length() + string.length(); - if(size > ZipSecureFile.getMaxTextSize()) { - throw new IllegalStateException("The text would exceed the max allowed overall size of extracted text. " - + "By default this is prevented as some documents may exhaust available memory and it may indicate that the file is used to inflate memory usage and thus could pose a security risk. " - + "You can adjust this limit via ZipSecureFile.setMaxTextSize() if you need to work with files which have a lot of text. " - + "Size: " + size + ", limit: MAX_TEXT_SIZE: " + ZipSecureFile.getMaxTextSize()); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/POIXMLTypeLoader.java b/trunk/src/ooxml/java/org/apache/poi/POIXMLTypeLoader.java deleted file mode 100644 index eeed5f7c8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/POIXMLTypeLoader.java +++ /dev/null @@ -1,174 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.lang.ref.WeakReference; -import java.net.URL; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.stream.XMLStreamReader; - -import org.apache.poi.util.DocumentHelper; -import org.apache.xmlbeans.SchemaType; -import org.apache.xmlbeans.SchemaTypeLoader; -import org.apache.xmlbeans.XmlBeans; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.apache.xmlbeans.xml.stream.XMLInputStream; -import org.apache.xmlbeans.xml.stream.XMLStreamException; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -@SuppressWarnings("deprecation") -public class POIXMLTypeLoader { - - private static ThreadLocal classLoader = new ThreadLocal(); - - public static final XmlOptions DEFAULT_XML_OPTIONS; - static { - DEFAULT_XML_OPTIONS = new XmlOptions(); - DEFAULT_XML_OPTIONS.setSaveOuter(); - DEFAULT_XML_OPTIONS.setUseDefaultNamespace(); - DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces(); - DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8"); - // Piccolo is disabled for POI builts, i.e. JAXP is used for parsing - // so only user code using XmlObject/XmlToken.Factory.parse - // directly can bypass the entity check, which is probably unlikely (... and not within our responsibility :)) - // DEFAULT_XML_OPTIONS.setLoadEntityBytesLimit(4096); - - Map map = new HashMap(); - map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a"); - map.put("http://schemas.openxmlformats.org/drawingml/2006/chart", "c"); - map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp"); - map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve"); - map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m"); - map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r"); - map.put("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "vt"); - map.put("http://schemas.openxmlformats.org/presentationml/2006/main", "p"); - map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w"); - map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne"); - map.put("urn:schemas-microsoft-com:office:office", "o"); - map.put("urn:schemas-microsoft-com:office:excel", "x"); - map.put("urn:schemas-microsoft-com:office:word", "w10"); - map.put("urn:schemas-microsoft-com:vml", "v"); - DEFAULT_XML_OPTIONS.setSaveSuggestedPrefixes(Collections.unmodifiableMap(map)); - } - - private static XmlOptions getXmlOptions(XmlOptions options) { - return options == null ? DEFAULT_XML_OPTIONS : options; - } - - /** - * Sets the {@link ClassLoader} which is used, when XmlBeans are dynamically instantiated - - * opposed to being loaded by the factory class which is accompanied by each generated XmlBeans interface. - *

        - * This is especially necessary in a context which doesn't guarantee that the current (thread) context - * cassloader has access to all XmlBeans schema definitions (*.xsb) - which is typically in OSGI the case. - *

        - * The classloader will be only set for the current thread in a {@link ThreadLocal}. Although the - * ThreadLocal is implemented via a {@link WeakReference}, it's good style to {@code null} the classloader - * when the user code is finalized. - * - * @param cl the classloader to be used when XmlBeans classes and definitions are looked up - */ - public static void setClassLoader(ClassLoader cl) { - classLoader.set(cl); - } - - private static SchemaTypeLoader getTypeLoader() { - ClassLoader cl = classLoader.get(); - return (cl == null) - ? XmlBeans.getContextTypeLoader() - : XmlBeans.typeLoaderForClassLoader(cl); - } - - public static XmlObject newInstance(SchemaType type, XmlOptions options) { - return getTypeLoader().newInstance(type, getXmlOptions(options)); - } - - public static XmlObject parse(String xmlText, SchemaType type, XmlOptions options) throws XmlException { - try { - return parse(new StringReader(xmlText), type, options); - } catch (IOException e) { - throw new XmlException("Unable to parse xml bean", e); - } - } - - public static XmlObject parse(File file, SchemaType type, XmlOptions options) throws XmlException, IOException { - InputStream is = new FileInputStream(file); - try { - return parse(is, type, options); - } finally { - is.close(); - } - } - - public static XmlObject parse(URL file, SchemaType type, XmlOptions options) throws XmlException, IOException { - InputStream is = file.openStream(); - try { - return parse(is, type, options); - } finally { - is.close(); - } - } - - public static XmlObject parse(InputStream jiois, SchemaType type, XmlOptions options) throws XmlException, IOException { - try { - Document doc = DocumentHelper.readDocument(jiois); - return getTypeLoader().parse(doc.getDocumentElement(), type, getXmlOptions(options)); - } catch (SAXException e) { - throw new IOException("Unable to parse xml bean", e); - } - } - - public static XmlObject parse(XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException { - return getTypeLoader().parse(xsr, type, getXmlOptions(options)); - } - - public static XmlObject parse(Reader jior, SchemaType type, XmlOptions options) throws XmlException, IOException { - try { - Document doc = DocumentHelper.readDocument(new InputSource(jior)); - return getTypeLoader().parse(doc.getDocumentElement(), type, getXmlOptions(options)); - } catch (SAXException e) { - throw new XmlException("Unable to parse xml bean", e); - } - } - - public static XmlObject parse(Node node, SchemaType type, XmlOptions options) throws XmlException { - return getTypeLoader().parse(node, type, getXmlOptions(options)); - } - - public static XmlObject parse(XMLInputStream xis, SchemaType type, XmlOptions options) throws XmlException, XMLStreamException { - return getTypeLoader().parse(xis, type, getXmlOptions(options)); - } - - public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException { - return getTypeLoader().newValidatingXMLInputStream(xis, type, getXmlOptions(options)); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java b/trunk/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java deleted file mode 100644 index 2e5f339b0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.dev; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.ArrayList; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; - -/** - * Prints out the contents of a OOXML container. - * Useful for seeing what parts are defined, and how - * they're all related to each other. - */ -public class OOXMLLister { - private final OPCPackage container; - private final PrintStream disp; - - public OOXMLLister(OPCPackage container) { - this(container, System.out); - } - public OOXMLLister(OPCPackage container, PrintStream disp) { - this.container = container; - this.disp = disp; - } - - /** - * Figures out how big a given PackagePart is. - * - * @param part the PackagePart - * @return the size of the PackagePart - * - * @throws IOException if the part can't be read - */ - public static long getSize(PackagePart part) throws IOException { - InputStream in = part.getInputStream(); - try { - byte[] b = new byte[8192]; - long size = 0; - int read = 0; - - while(read > -1) { - read = in.read(b); - if(read > 0) { - size += read; - } - } - - return size; - } finally { - in.close(); - } - } - - /** - * Displays information on all the different - * parts of the OOXML file container. - * @throws InvalidFormatException if the package relations are invalid - * @throws IOException if the package can't be read - */ - public void displayParts() throws InvalidFormatException, IOException { - ArrayList parts = container.getParts(); - for (PackagePart part : parts) { - disp.println(part.getPartName()); - disp.println("\t" + part.getContentType()); - - if(! part.getPartName().toString().equals("/docProps/core.xml")) { - disp.println("\t" + getSize(part) + " bytes"); - } - - if(! part.isRelationshipPart()) { - disp.println("\t" + part.getRelationships().size() + " relations"); - for(PackageRelationship rel : part.getRelationships()) { - displayRelation(rel, "\t "); - } - } - } - } - /** - * Displays information on all the different - * relationships between different parts - * of the OOXML file container. - */ - public void displayRelations() { - PackageRelationshipCollection rels = - container.getRelationships(); - for (PackageRelationship rel : rels) { - displayRelation(rel, ""); - } - } - private void displayRelation(PackageRelationship rel, String indent) { - disp.println(indent+"Relationship:"); - disp.println(indent+"\tFrom: "+ rel.getSourceURI()); - disp.println(indent+"\tTo: " + rel.getTargetURI()); - disp.println(indent+"\tID: " + rel.getId()); - disp.println(indent+"\tMode: " + rel.getTargetMode()); - disp.println(indent+"\tType: " + rel.getRelationshipType()); - } - - public static void main(String[] args) throws Exception { - if(args.length == 0) { - System.err.println("Use:"); - System.err.println("\tjava OOXMLLister "); - System.exit(1); - } - - File f = new File(args[0]); - if(! f.exists()) { - System.err.println("Error, file not found!"); - System.err.println("\t" + f.toString()); - System.exit(2); - } - - OOXMLLister lister = new OOXMLLister( - OPCPackage.open(f.toString(), PackageAccess.READ) - ); - - lister.disp.println(f.toString() + "\n"); - lister.displayParts(); - lister.disp.println(); - lister.displayRelations(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java b/trunk/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java deleted file mode 100644 index 1a7a9d6c5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.dev; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.apache.poi.openxml4j.opc.internal.ZipHelper; -import org.apache.poi.openxml4j.util.ZipSecureFile; -import org.apache.poi.util.IOUtils; -import org.w3c.dom.Document; -import org.xml.sax.InputSource; - -/** - * Reads a zipped OOXML file and produces a copy with the included - * pretty-printed XML files. - * - * This is useful for comparing OOXML files produced by different tools as the often - * use different formatting of the XML. - */ -public class OOXMLPrettyPrint { - private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - private final DocumentBuilder documentBuilder; - - public OOXMLPrettyPrint() throws ParserConfigurationException { - // allow files with much lower inflation rate here as there is no risk of Zip Bomb attacks in this developer tool - ZipSecureFile.setMinInflateRatio(0.00001); - - documentBuilder = documentBuilderFactory.newDocumentBuilder(); - } - - public static void main(String[] args) throws Exception { - if(args.length <= 1 || args.length % 2 != 0) { - System.err.println("Use:"); - System.err.println("\tjava OOXMLPrettyPrint [ ] ..."); - System.exit(1); - } - - for(int i = 0;i < args.length;i+=2) { - File f = new File(args[i]); - if(! f.exists()) { - System.err.println("Error, file not found!"); - System.err.println("\t" + f.toString()); - System.exit(2); - } - - handleFile(f, new File(args[i+1])); - } - System.out.println("Done."); - } - - private static void handleFile(File file, File outFile) throws ZipException, - IOException, TransformerException, ParserConfigurationException { - System.out.println("Reading zip-file " + file + " and writing pretty-printed XML to " + outFile); - - ZipFile zipFile = ZipHelper.openZipFile(file); - try { - ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile))); - try { - new OOXMLPrettyPrint().handle(zipFile, out); - } finally { - out.close(); - } - } finally { - zipFile.close(); - - System.out.println(); - } - } - - private void handle(ZipFile file, ZipOutputStream out) throws IOException, TransformerException { - Enumeration entries = file.entries(); - while(entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - - String name = entry.getName(); - out.putNextEntry(new ZipEntry(name)); - try { - if(name.endsWith(".xml") || name.endsWith(".rels")) { - Document document = documentBuilder.parse(new InputSource(file.getInputStream(entry))); - document.setXmlStandalone(true); - pretty(document, out, 2); - } else { - System.out.println("Not pretty-printing non-XML file " + name); - IOUtils.copy(file.getInputStream(entry), out); - } - } catch (Exception e) { - throw new IOException("While handling entry " + name, e); - } finally { - out.closeEntry(); - } - System.out.print("."); - } - } - - private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException { - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - if (indent > 0) { - // set properties to indent the resulting XML nicely - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indent)); - } - Result result = new StreamResult(outputStream); - Source source = new DOMSource(document); - transformer.transform(source, result); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/extractor/CommandLineTextExtractor.java b/trunk/src/ooxml/java/org/apache/poi/extractor/CommandLineTextExtractor.java deleted file mode 100644 index 264daa028..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/extractor/CommandLineTextExtractor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.extractor; - -import java.io.File; - -import org.apache.poi.POITextExtractor; - -/** - * A command line wrapper around {@link ExtractorFactory}, useful - * for when debugging. - */ -public class CommandLineTextExtractor { - public static final String DIVIDER = "======================="; - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" CommandLineTextExtractor [filename] [filename]"); - System.exit(1); - } - - for (String arg : args) { - System.out.println(DIVIDER); - - File f = new File(arg); - System.out.println(f); - - POITextExtractor extractor = - ExtractorFactory.createExtractor(f); - try { - POITextExtractor metadataExtractor = - extractor.getMetadataTextExtractor(); - - System.out.println(" " + DIVIDER); - String metaData = metadataExtractor.getText(); - System.out.println(metaData); - System.out.println(" " + DIVIDER); - String text = extractor.getText(); - System.out.println(text); - System.out.println(DIVIDER); - System.out.println("Had " + metaData.length() + " characters of metadata and " + text.length() + " characters of text"); - } finally { - extractor.close(); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java b/trunk/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java deleted file mode 100644 index cdd35b359..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java +++ /dev/null @@ -1,392 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.extractor; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.util.ArrayList; -import java.util.Iterator; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.POITextExtractor; -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.hsmf.datatypes.AttachmentChunks; -import org.apache.poi.hsmf.extractor.OutlookTextExtactor; -import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.hwpf.extractor.WordExtractor; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.NotOLE2FileException; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OfficeXmlFileException; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xdgf.extractor.XDGFVisioExtractor; -import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor; -import org.apache.poi.xslf.usermodel.XSLFRelation; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; -import org.apache.poi.xssf.extractor.XSSFExcelExtractor; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.poi.xwpf.extractor.XWPFWordExtractor; -import org.apache.poi.xwpf.usermodel.XWPFRelation; -import org.apache.xmlbeans.XmlException; - -/** - * Figures out the correct POITextExtractor for your supplied - * document, and returns it. - * - *

        Note 1 - will fail for many file formats if the POI Scratchpad jar is - * not present on the runtime classpath

        - *

        Note 2 - rather than using this, for most cases you would be better - * off switching to Apache Tika instead!

        - */ -@SuppressWarnings("WeakerAccess") -public class ExtractorFactory { - private static final POILogger logger = POILogFactory.getLogger(ExtractorFactory.class); - - public static final String CORE_DOCUMENT_REL = PackageRelationshipTypes.CORE_DOCUMENT; - protected static final String VISIO_DOCUMENT_REL = PackageRelationshipTypes.VISIO_CORE_DOCUMENT; - protected static final String STRICT_DOCUMENT_REL = PackageRelationshipTypes.STRICT_CORE_DOCUMENT; - - /** - * Should this thread prefer event based over usermodel based extractors? - * (usermodel extractors tend to be more accurate, but use more memory) - * Default is false. - */ - public static boolean getThreadPrefersEventExtractors() { - return OLE2ExtractorFactory.getThreadPrefersEventExtractors(); - } - - /** - * Should all threads prefer event based over usermodel based extractors? - * (usermodel extractors tend to be more accurate, but use more memory) - * Default is to use the thread level setting, which defaults to false. - */ - public static Boolean getAllThreadsPreferEventExtractors() { - return OLE2ExtractorFactory.getAllThreadsPreferEventExtractors(); - } - - /** - * Should this thread prefer event based over usermodel based extractors? - * Will only be used if the All Threads setting is null. - */ - public static void setThreadPrefersEventExtractors(boolean preferEventExtractors) { - OLE2ExtractorFactory.setThreadPrefersEventExtractors(preferEventExtractors); - } - - /** - * Should all threads prefer event based over usermodel based extractors? - * If set, will take preference over the Thread level setting. - */ - public static void setAllThreadsPreferEventExtractors(Boolean preferEventExtractors) { - OLE2ExtractorFactory.setAllThreadsPreferEventExtractors(preferEventExtractors); - } - - /** - * Should this thread use event based extractors is available? - * Checks the all-threads one first, then thread specific. - */ - protected static boolean getPreferEventExtractor() { - return OLE2ExtractorFactory.getPreferEventExtractor(); - } - - public static POITextExtractor createExtractor(File f) throws IOException, OpenXML4JException, XmlException { - NPOIFSFileSystem fs = null; - try { - fs = new NPOIFSFileSystem(f); - POIOLE2TextExtractor extractor = createExtractor(fs); - extractor.setFilesystem(fs); - return extractor; - - } catch (OfficeXmlFileException e) { - // ensure file-handle release - IOUtils.closeQuietly(fs); - return createExtractor(OPCPackage.open(f.toString(), PackageAccess.READ)); - - } catch (NotOLE2FileException ne) { - // ensure file-handle release - IOUtils.closeQuietly(fs); - throw new IllegalArgumentException("Your File was neither an OLE2 file, nor an OOXML file"); - - } catch (OpenXML4JException e) { - // ensure file-handle release - IOUtils.closeQuietly(fs); - throw e; - - } catch (XmlException e) { - // ensure file-handle release - IOUtils.closeQuietly(fs); - throw e; - - } catch (IOException e) { - // ensure file-handle release - IOUtils.closeQuietly(fs); - throw e; - - } catch (RuntimeException e) { - // ensure file-handle release - IOUtils.closeQuietly(fs); - throw e; - } - } - - public static POITextExtractor createExtractor(InputStream inp) throws IOException, OpenXML4JException, XmlException { - // Figure out the kind of stream - // If clearly doesn't do mark/reset, wrap up - if (! inp.markSupported()) { - inp = new PushbackInputStream(inp, 8); - } - - if (NPOIFSFileSystem.hasPOIFSHeader(inp)) { - return createExtractor(new NPOIFSFileSystem(inp)); - } - if (DocumentFactoryHelper.hasOOXMLHeader(inp)) { - return createExtractor(OPCPackage.open(inp)); - } - throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream"); - } - - /** - * Tries to determine the actual type of file and produces a matching text-extractor for it. - * - * @param pkg An {@link OPCPackage}. - * @return A {@link POIXMLTextExtractor} for the given file. - * @throws IOException If an error occurs while reading the file - * @throws OpenXML4JException If an error parsing the OpenXML file format is found. - * @throws XmlException If an XML parsing error occurs. - * @throws IllegalArgumentException If no matching file type could be found. - */ - public static POIXMLTextExtractor createExtractor(OPCPackage pkg) throws IOException, OpenXML4JException, XmlException { - try { - // Check for the normal Office core document - PackageRelationshipCollection core; - core = pkg.getRelationshipsByType(CORE_DOCUMENT_REL); - - // If nothing was found, try some of the other OOXML-based core types - if (core.size() == 0) { - // Could it be an OOXML-Strict one? - core = pkg.getRelationshipsByType(STRICT_DOCUMENT_REL); - } - if (core.size() == 0) { - // Could it be a visio one? - core = pkg.getRelationshipsByType(VISIO_DOCUMENT_REL); - if (core.size() == 1) - return new XDGFVisioExtractor(pkg); - } - - // Should just be a single core document, complain if not - if (core.size() != 1) { - throw new IllegalArgumentException("Invalid OOXML Package received - expected 1 core document, found " + core.size()); - } - - // Grab the core document part, and try to identify from that - final PackagePart corePart = pkg.getPart(core.getRelationship(0)); - final String contentType = corePart.getContentType(); - - // Is it XSSF? - for (XSSFRelation rel : XSSFExcelExtractor.SUPPORTED_TYPES) { - if ( rel.getContentType().equals( contentType ) ) { - if (getPreferEventExtractor()) { - return new XSSFEventBasedExcelExtractor(pkg); - } - return new XSSFExcelExtractor(pkg); - } - } - - // Is it XWPF? - for (XWPFRelation rel : XWPFWordExtractor.SUPPORTED_TYPES) { - if ( rel.getContentType().equals( contentType ) ) { - return new XWPFWordExtractor(pkg); - } - } - - // Is it XSLF? - for (XSLFRelation rel : XSLFPowerPointExtractor.SUPPORTED_TYPES) { - if ( rel.getContentType().equals( contentType ) ) { - return new XSLFPowerPointExtractor(pkg); - } - } - - // special handling for SlideShow-Theme-files, - if (XSLFRelation.THEME_MANAGER.getContentType().equals(contentType)) { - return new XSLFPowerPointExtractor(new XSLFSlideShow(pkg)); - } - - throw new IllegalArgumentException("No supported documents found in the OOXML package (found "+contentType+")"); - - } catch (IOException e) { - // ensure that we close the package again if there is an error opening it, however - // we need to revert the package to not re-write the file via close(), which is very likely not wanted for a TextExtractor! - pkg.revert(); - throw e; - } catch (OpenXML4JException e) { - // ensure that we close the package again if there is an error opening it, however - // we need to revert the package to not re-write the file via close(), which is very likely not wanted for a TextExtractor! - pkg.revert(); - throw e; - } catch (XmlException e) { - // ensure that we close the package again if there is an error opening it, however - // we need to revert the package to not re-write the file via close(), which is very likely not wanted for a TextExtractor! - pkg.revert(); - throw e; - } catch (RuntimeException e) { - // ensure that we close the package again if there is an error opening it, however - // we need to revert the package to not re-write the file via close(), which is very likely not wanted for a TextExtractor! - pkg.revert(); - throw e; - } - } - - public static POIOLE2TextExtractor createExtractor(POIFSFileSystem fs) throws IOException, OpenXML4JException, XmlException { - return OLE2ExtractorFactory.createExtractor(fs); - } - public static POIOLE2TextExtractor createExtractor(NPOIFSFileSystem fs) throws IOException, OpenXML4JException, XmlException { - return OLE2ExtractorFactory.createExtractor(fs); - } - public static POIOLE2TextExtractor createExtractor(OPOIFSFileSystem fs) throws IOException, OpenXML4JException, XmlException { - return OLE2ExtractorFactory.createExtractor(fs); - } - - public static POITextExtractor createExtractor(DirectoryNode poifsDir) throws IOException, OpenXML4JException, XmlException - { - // First, check for OOXML - for (String entryName : poifsDir.getEntryNames()) { - if (entryName.equals("Package")) { - OPCPackage pkg = OPCPackage.open(poifsDir.createDocumentInputStream("Package")); - return createExtractor(pkg); - } - } - - // If not, ask the OLE2 code to check, with Scratchpad if possible - return OLE2ExtractorFactory.createExtractor(poifsDir); - } - - /** - * Returns an array of text extractors, one for each of - * the embedded documents in the file (if there are any). - * If there are no embedded documents, you'll get back an - * empty array. Otherwise, you'll get one open - * {@link POITextExtractor} for each embedded file. - */ - public static POITextExtractor[] getEmbededDocsTextExtractors(POIOLE2TextExtractor ext) throws IOException, OpenXML4JException, XmlException { - // All the embedded directories we spotted - ArrayList dirs = new ArrayList(); - // For anything else not directly held in as a POIFS directory - ArrayList nonPOIFS = new ArrayList(); - - // Find all the embedded directories - DirectoryEntry root = ext.getRoot(); - if (root == null) { - throw new IllegalStateException("The extractor didn't know which POIFS it came from!"); - } - - if (ext instanceof ExcelExtractor) { - // These are in MBD... under the root - Iterator it = root.getEntries(); - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getName().startsWith("MBD")) { - dirs.add(entry); - } - } - } else if (ext instanceof WordExtractor) { - // These are in ObjectPool -> _... under the root - try { - DirectoryEntry op = (DirectoryEntry) root.getEntry("ObjectPool"); - Iterator it = op.getEntries(); - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getName().startsWith("_")) { - dirs.add(entry); - } - } - } catch (FileNotFoundException e) { - logger.log(POILogger.INFO, "Ignoring FileNotFoundException while extracting Word document", e.getLocalizedMessage()); - // ignored here - } - //} else if(ext instanceof PowerPointExtractor) { - // Tricky, not stored directly in poifs - // TODO - } else if (ext instanceof OutlookTextExtactor) { - // Stored in the Attachment blocks - MAPIMessage msg = ((OutlookTextExtactor)ext).getMAPIMessage(); - for (AttachmentChunks attachment : msg.getAttachmentFiles()) { - if (attachment.attachData != null) { - byte[] data = attachment.attachData.getValue(); - nonPOIFS.add( new ByteArrayInputStream(data) ); - } else if (attachment.attachmentDirectory != null) { - dirs.add(attachment.attachmentDirectory.getDirectory()); - } - } - } - - // Create the extractors - if (dirs.size() == 0 && nonPOIFS.size() == 0){ - return new POITextExtractor[0]; - } - - ArrayList textExtractors = new ArrayList(); - for (Entry dir : dirs) { - textExtractors.add(createExtractor((DirectoryNode) dir)); - } - for (InputStream nonPOIF : nonPOIFS) { - try { - textExtractors.add(createExtractor(nonPOIF)); - } catch (IllegalArgumentException e) { - // Ignore, just means it didn't contain - // a format we support as yet - logger.log(POILogger.INFO, "Format not supported yet", e.getLocalizedMessage()); - } catch (XmlException e) { - throw new IOException(e.getMessage(), e); - } catch (OpenXML4JException e) { - throw new IOException(e.getMessage(), e); - } - } - return textExtractors.toArray(new POITextExtractor[textExtractors.size()]); - } - - /** - * Returns an array of text extractors, one for each of - * the embedded documents in the file (if there are any). - * If there are no embedded documents, you'll get back an - * empty array. Otherwise, you'll get one open - * {@link POITextExtractor} for each embedded file. - */ - @NotImplemented - @SuppressWarnings("UnusedParameters") - public static POITextExtractor[] getEmbededDocsTextExtractors(POIXMLTextExtractor ext) { - throw new IllegalStateException("Not yet supported"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java deleted file mode 100644 index 832d47623..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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); - } - - public InvalidFormatException(String message, Throwable cause){ - super(message,cause); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java deleted file mode 100644 index 7a8338ed8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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. - */ -@SuppressWarnings("serial") -public class InvalidOperationException extends OpenXML4JRuntimeException{ - public InvalidOperationException(String message){ - super(message); - } - - public InvalidOperationException(String message, Throwable reason){ - super(message, reason); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/NotOfficeXmlFileException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/NotOfficeXmlFileException.java deleted file mode 100644 index 901967e20..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/NotOfficeXmlFileException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import org.apache.poi.UnsupportedFileFormatException; - -/** - * This exception is thrown when we try to open a file that doesn't - * seem to actually be an OOXML (Office Open XML) file after all - */ -public class NotOfficeXmlFileException extends UnsupportedFileFormatException { - public NotOfficeXmlFileException(String message) { - super(message); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/ODFNotOfficeXmlFileException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/ODFNotOfficeXmlFileException.java deleted file mode 100644 index 61d8c8cd9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/ODFNotOfficeXmlFileException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * This exception is thrown when we are given an ODF-based file - * (eg OpenOffice .ods) instead of an actually OOXML (Office Open XML) file - */ -public class ODFNotOfficeXmlFileException extends NotOfficeXmlFileException { - public ODFNotOfficeXmlFileException(String message) { - super(message); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OLE2NotOfficeXmlFileException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OLE2NotOfficeXmlFileException.java deleted file mode 100644 index 2f82d1100..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OLE2NotOfficeXmlFileException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * This exception is thrown when we are given an OLE2-based file - * (eg Excel .xls) instead of an actually OOXML (Office Open XML) file - */ -public class OLE2NotOfficeXmlFileException extends NotOfficeXmlFileException { - public OLE2NotOfficeXmlFileException(String message) { - super(message); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java deleted file mode 100644 index 4c7430df5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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). - */ -@SuppressWarnings("serial") -public class OpenXML4JException extends Exception { - - public OpenXML4JException(String msg) { - super(msg); - } - - public OpenXML4JException(String msg, Throwable cause) { - super(msg, cause); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java deleted file mode 100644 index 40086aa9f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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); - } - - public OpenXML4JRuntimeException(String msg, Throwable reason) { - super(msg, reason); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/PartAlreadyExistsException.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/PartAlreadyExistsException.java deleted file mode 100644 index e469ace56..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/exceptions/PartAlreadyExistsException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import org.apache.poi.openxml4j.opc.PackagePart; - -/** - * Throw when trying to create a {@link PackagePart} but one - * already exists with that name. - */ -@SuppressWarnings("serial") -public final class PartAlreadyExistsException extends InvalidOperationException { - public PartAlreadyExistsException(String message){ - super(message); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java deleted file mode 100644 index cd7b45694..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -/** - * Specifies the location where the X.509 certificate that is used in signing is stored. - * - * @author Julien Chable - */ -public enum CertificateEmbeddingOption { - /** The certificate is embedded in its own PackagePart. */ - IN_CERTIFICATE_PART, - /** The certificate is embedded in the SignaturePart that is created for the signature being added. */ - IN_SIGNATURE_PART, - /** The certificate in not embedded in the package. */ - NOT_EMBEDDED -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java deleted file mode 100644 index 583b5c51d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -import java.util.zip.Deflater; - -/** - * Specifies the compression level for content that is stored in a PackagePart. - * - * @author Julien Chable - * @version 1.0 - */ -public enum CompressionOption { - /** Compression is optimized for performance. */ - FAST(Deflater.BEST_SPEED), - /** Compression is optimized for size. */ - MAXIMUM(Deflater.BEST_COMPRESSION), - /** Compression is optimized for a balance between size and performance. */ - NORMAL(Deflater.DEFAULT_COMPRESSION), - /** Compression is turned off. */ - NOT_COMPRESSED(Deflater.NO_COMPRESSION); - - private final int value; - - CompressionOption(int value) { - this.value = value; - } - - public int value() { - return this.value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java deleted file mode 100644 index 9109f28f3..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 not done with JAXP by default -> remove the schema or do it ? - * - * @author CDubettier, Julen Chable - * @version 1.0 - */ -public final class Configuration { - // TODO configuration by default. should be clearly stated that it should be - // changed to match installation path - // as schemas dir is needed in runtime - static private String pathForXmlSchema = System.getProperty("user.dir") - + File.separator + "src" + File.separator + "schemas"; - - public static String getPathForXmlSchema() { - return pathForXmlSchema; - } - - public static void setPathForXmlSchema(String pathForXmlSchema) { - Configuration.pathForXmlSchema = pathForXmlSchema; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java deleted file mode 100644 index 805a5172a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.Locale; - -/** - * 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 - * http://partners.adobe.com/public/developer/tiff/index.html#spec - */ - public static final String IMAGE_TIFF = "image/tiff"; - - public static final String EXTENSION_TIFF = "tiff"; - - /** - * Pict image format. - * - * @see - * http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html - */ - 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(Locale.ROOT); - if (extension.equals(EXTENSION_JPG_1) - || extension.equals(EXTENSION_JPG_2)) - return IMAGE_JPEG; - else if (extension.equals(EXTENSION_GIF)) - return IMAGE_GIF; - else if (extension.equals(EXTENSION_PICT)) - return IMAGE_PICT; - else if (extension.equals(EXTENSION_PNG)) - return IMAGE_PNG; - else if (extension.equals(EXTENSION_TIFF)) - return IMAGE_TIFF; - else if (extension.equals(EXTENSION_XML)) - return XML; - else - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java deleted file mode 100644 index bc994e0f1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -/** - * Specifies the encryption option for parts in a Package. - * - * @author Julien Chable - * @version 0.1 - */ -public enum EncryptionOption { - /** No encryption. */ - NONE -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java deleted file mode 100644 index 5220529fd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java +++ /dev/null @@ -1,1695 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -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.exceptions.OpenXML4JRuntimeException; -import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException; -import org.apache.poi.openxml4j.opc.internal.ContentType; -import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; -import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; -import org.apache.poi.openxml4j.opc.internal.PartMarshaller; -import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller; -import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager; -import org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller; -import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller; -import org.apache.poi.openxml4j.opc.internal.unmarshallers.PackagePropertiesUnmarshaller; -import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext; -import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.openxml4j.util.ZipEntrySource; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Represents a container that can store multiple data objects. - */ -public abstract class OPCPackage implements RelationshipSource, Closeable { - - /** - * Logger. - */ - private static final POILogger logger = POILogFactory.getLogger(OPCPackage.class); - - /** - * Default package access. - */ - protected static final PackageAccess defaultPackageAccess = PackageAccess.READ_WRITE; - - /** - * Package access. - */ - private PackageAccess packageAccess; - - /** - * Package parts collection. - */ - protected PackagePartCollection partList; - - /** - * Package relationships. - */ - protected PackageRelationshipCollection relationships; - - /** - * Part marshallers by content type. - */ - protected Map partMarshallers; - - /** - * Default part marshaller. - */ - protected PartMarshaller defaultPartMarshaller; - - /** - * Part unmarshallers by content type. - */ - protected Map partUnmarshallers; - - /** - * Core package properties. - */ - protected PackagePropertiesPart packageProperties; - - /** - * Manage parts content types of this package. - */ - protected ContentTypeManager contentTypeManager; - - /** - * Flag if a modification is done to the document. - */ - protected boolean isDirty = false; - - /** - * File path of this package. - */ - protected String originalPackagePath; - - /** - * Output stream for writing this package. - */ - protected OutputStream output; - - /** - * Constructor. - * - * @param access - * Package access. - */ - OPCPackage(PackageAccess access) { - if (getClass() != ZipPackage.class) { - throw new IllegalArgumentException("PackageBase may not be subclassed"); - } - init(); - this.packageAccess = access; - } - - /** - * Initialize the package instance. - */ - private void init() { - this.partMarshallers = new HashMap(5); - this.partUnmarshallers = new HashMap(2); - - try { - // Add 'default' unmarshaller - this.partUnmarshallers.put(new ContentType( - ContentTypes.CORE_PROPERTIES_PART), - new PackagePropertiesUnmarshaller()); - - // Add default marshaller - this.defaultPartMarshaller = new DefaultMarshaller(); - // TODO Delocalize specialized marshallers - this.partMarshallers.put(new ContentType( - ContentTypes.CORE_PROPERTIES_PART), - new ZipPackagePropertiesMarshaller()); - } catch (InvalidFormatException e) { - // Should never happen - throw new OpenXML4JRuntimeException( - "Package.init() : this exception should never happen, " + - "if you read this message please send a mail to the developers team. : " + - e.getMessage(), - e - ); - } - } - - - /** - * Open a package with read/write permission. - * - * @param path - * The document path. - * @return A Package object, else null. - * @throws InvalidFormatException - * If the specified file doesn't exist, and a parsing error - * occur. - */ - public static OPCPackage open(String path) throws InvalidFormatException { - return open(path, defaultPackageAccess); - } - - /** - * Open a package with read/write permission. - * - * @param file - * The file to open. - * @return A Package object, else null. - * @throws InvalidFormatException - * If the specified file doesn't exist, and a parsing error - * occur. - */ - public static OPCPackage open(File file) throws InvalidFormatException { - return open(file, defaultPackageAccess); - } - - /** - * Open an user provided {@link ZipEntrySource} with read-only permission. - * This method can be used to stream data into POI. - * Opposed to other open variants, the data is read as-is, e.g. there aren't - * any zip-bomb protection put in place. - * - * @param zipEntry the custom source - * @return A Package object - * @throws InvalidFormatException if a parsing error occur. - */ - public static OPCPackage open(ZipEntrySource zipEntry) - throws InvalidFormatException { - OPCPackage pack = new ZipPackage(zipEntry, PackageAccess.READ); - try { - if (pack.partList == null) { - pack.getParts(); - } - // pack.originalPackagePath = file.getAbsolutePath(); - return pack; - } catch (InvalidFormatException e) { - IOUtils.closeQuietly(pack); - throw e; - } catch (RuntimeException e) { - IOUtils.closeQuietly(pack); - throw e; - } - } - - /** - * Open a package. - * - * @param path - * The document path. - * @param access - * PackageBase access. - * @return A PackageBase object, else null. - * @throws InvalidFormatException - * If the specified file doesn't exist, and a parsing error - * occur. - * @throws InvalidOperationException - */ - public static OPCPackage open(String path, PackageAccess access) - throws InvalidFormatException, InvalidOperationException { - if (path == null || "".equals(path.trim())) { - throw new IllegalArgumentException("'path' must be given"); - } - - File file = new File(path); - if (file.exists() && file.isDirectory()) { - throw new IllegalArgumentException("path must not be a directory"); - } - - OPCPackage pack = new ZipPackage(path, access); - boolean success = false; - if (pack.partList == null && access != PackageAccess.WRITE) { - try { - pack.getParts(); - success = true; - } finally { - if (! success) { - try { - pack.close(); - } catch (final IOException e) { - throw new InvalidOperationException("Could not close OPCPackage while cleaning up", e); - } - } - } - } - - pack.originalPackagePath = new File(path).getAbsolutePath(); - return pack; - } - - /** - * Open a package. - * - * @param file - * The file to open. - * @param access - * PackageBase access. - * @return A PackageBase object, else null. - * @throws InvalidFormatException - * If the specified file doesn't exist, and a parsing error - * occur. - */ - public static OPCPackage open(File file, PackageAccess access) - throws InvalidFormatException { - if (file == null) { - throw new IllegalArgumentException("'file' must be given"); - } - if (file.exists() && file.isDirectory()) { - throw new IllegalArgumentException("file must not be a directory"); - } - - OPCPackage pack = new ZipPackage(file, access); - try { - if (pack.partList == null && access != PackageAccess.WRITE) { - pack.getParts(); - } - pack.originalPackagePath = file.getAbsolutePath(); - return pack; - } catch (InvalidFormatException e) { - IOUtils.closeQuietly(pack); - throw e; - } catch (RuntimeException e) { - IOUtils.closeQuietly(pack); - throw e; - } - } - - /** - * Open a package. - * - * Note - uses quite a bit more memory than {@link #open(String)}, which - * doesn't need to hold the whole zip file in memory, and can take advantage - * of native methods - * - * @param in - * The InputStream to read the package from - * @return A PackageBase object - */ - public static OPCPackage open(InputStream in) throws InvalidFormatException, - IOException { - OPCPackage pack = new ZipPackage(in, PackageAccess.READ_WRITE); - try { - if (pack.partList == null) { - pack.getParts(); - } - } catch (InvalidFormatException e) { - IOUtils.closeQuietly(pack); - throw e; - } catch (RuntimeException e) { - IOUtils.closeQuietly(pack); - throw e; - } - return pack; - } - - /** - * Opens a package if it exists, else it creates one. - * - * @param file - * The file to open or to create. - * @return A newly created package if the specified file does not exist, - * else the package extract from the file. - * @throws InvalidFormatException - * Throws if the specified file exist and is not valid. - */ - public static OPCPackage openOrCreate(File file) throws InvalidFormatException { - if (file.exists()) { - return open(file.getAbsolutePath()); - } else { - return create(file); - } - } - - /** - * Creates a new package. - * - * @param path - * Path of the document. - * @return A newly created PackageBase ready to use. - */ - public static OPCPackage create(String path) { - return create(new File(path)); - } - - /** - * Creates a new package. - * - * @param file - * Path of the document. - * @return A newly created PackageBase ready to use. - */ - public static OPCPackage create(File file) { - if (file == null || (file.exists() && file.isDirectory())) { - throw new IllegalArgumentException("file"); - } - - if (file.exists()) { - throw new InvalidOperationException( - "This package (or file) already exists : use the open() method or delete the file."); - } - - // Creates a new package - OPCPackage pkg = new ZipPackage(); - pkg.originalPackagePath = file.getAbsolutePath(); - - configurePackage(pkg); - return pkg; - } - - public static OPCPackage create(OutputStream output) { - OPCPackage pkg = new ZipPackage(); - pkg.originalPackagePath = null; - pkg.output = output; - - configurePackage(pkg); - return pkg; - } - - /** - * Configure the package. - * - * @param pkg - */ - private static void configurePackage(OPCPackage pkg) { - try { - // Content type manager - pkg.contentTypeManager = new ZipContentTypeManager(null, pkg); - - // Add default content types for .xml and .rels - pkg.contentTypeManager.addContentType( - PackagingURIHelper.createPartName( - PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_URI), - ContentTypes.RELATIONSHIPS_PART); - pkg.contentTypeManager.addContentType( - PackagingURIHelper.createPartName("/default.xml"), - ContentTypes.PLAIN_OLD_XML); - - // Initialise some PackageBase properties - pkg.packageProperties = new PackagePropertiesPart(pkg, - PackagingURIHelper.CORE_PROPERTIES_PART_NAME); - pkg.packageProperties.setCreatorProperty("Generated by Apache POI OpenXML4J"); - pkg.packageProperties.setCreatedProperty(new Nullable(new Date())); - } catch (InvalidFormatException e) { - // Should never happen - throw new IllegalStateException(e); - } - } - - /** - * Flush the package : save all. - * - * @see #close() - */ - public void flush() { - throwExceptionIfReadOnly(); - - if (this.packageProperties != null) { - this.packageProperties.flush(); - } - - this.flushImpl(); - } - - /** - * Close the open, writable package and save its content. - * - * If your package is open read only, then you should call {@link #revert()} - * when finished with the package. - * - * @throws IOException - * If an IO exception occur during the saving process. - */ - @Override - public void close() throws IOException { - if (this.packageAccess == PackageAccess.READ) { - logger.log(POILogger.WARN, - "The close() method is intended to SAVE a package. This package is open in READ ONLY mode, use the revert() method instead !"); - revert(); - return; - } - if (this.contentTypeManager == null) { - logger.log(POILogger.WARN, - "Unable to call close() on a package that hasn't been fully opened yet"); - revert(); - return; - } - - // Save the content - ReentrantReadWriteLock l = new ReentrantReadWriteLock(); - try { - l.writeLock().lock(); - if (this.originalPackagePath != null - && !"".equals(this.originalPackagePath.trim())) { - File targetFile = new File(this.originalPackagePath); - if (!targetFile.exists() - || !(this.originalPackagePath - .equalsIgnoreCase(targetFile.getAbsolutePath()))) { - // Case of a package created from scratch - save(targetFile); - } else { - closeImpl(); - } - } else if (this.output != null) { - save(this.output); - output.close(); - } - } finally { - l.writeLock().unlock(); - } - - // Clear - this.contentTypeManager.clearAll(); - } - - /** - * Close the package WITHOUT saving its content. Reinitialize this package - * and cancel all changes done to it. - */ - public void revert() { - revertImpl(); - } - - /** - * Add a thumbnail to the package. This method is provided to make easier - * the addition of a thumbnail in a package. You can do the same work by - * using the traditionnal relationship and part mechanism. - * - * @param path The full path to the image file. - */ - public void addThumbnail(String path) throws IOException { - // Check parameter - if (path == null || path.isEmpty()) { - throw new IllegalArgumentException("path"); - } - String name = path.substring(path.lastIndexOf(File.separatorChar) + 1); - - FileInputStream is = new FileInputStream(path); - try { - addThumbnail(name, is); - } finally { - is.close(); - } - } - /** - * Add a thumbnail to the package. This method is provided to make easier - * the addition of a thumbnail in a package. You can do the same work by - * using the traditionnal relationship and part mechanism. - * - * @param filename The full path to the image file. - * @param data the image data - */ - public void addThumbnail(String filename, InputStream data) throws IOException { - // Check parameter - if (filename == null || filename.isEmpty()) { - throw new IllegalArgumentException("filename"); - } - - // Create the thumbnail part name - String contentType = ContentTypes - .getContentTypeFromFileExtension(filename); - PackagePartName thumbnailPartName; - try { - thumbnailPartName = PackagingURIHelper.createPartName("/docProps/" - + filename); - } catch (InvalidFormatException e) { - String partName = "/docProps/thumbnail" + - filename.substring(filename.lastIndexOf(".") + 1); - try { - thumbnailPartName = PackagingURIHelper.createPartName(partName); - } catch (InvalidFormatException e2) { - throw new InvalidOperationException( - "Can't add a thumbnail file named '" + filename + "'", e2); - } - } - - // Check if part already exist - if (this.getPart(thumbnailPartName) != null) - throw new InvalidOperationException( - "You already add a thumbnail named '" + filename + "'"); - - // Add the thumbnail part to this package. - PackagePart thumbnailPart = this.createPart(thumbnailPartName, - contentType, false); - - // Add the relationship between the package and the thumbnail part - this.addRelationship(thumbnailPartName, TargetMode.INTERNAL, - PackageRelationshipTypes.THUMBNAIL); - - // Copy file data to the newly created part - StreamHelper.copyStream(data, thumbnailPart.getOutputStream()); - } - - /** - * Throws an exception if the package access mode is in read only mode - * (PackageAccess.Read). - * - * @throws InvalidOperationException - * Throws if a writing operation is done on a read only package. - * @see org.apache.poi.openxml4j.opc.PackageAccess - */ - void throwExceptionIfReadOnly() throws InvalidOperationException { - if (packageAccess == PackageAccess.READ) { - throw new InvalidOperationException( - "Operation not allowed, document open in read only mode!"); - } - } - - /** - * Throws an exception if the package access mode is in write only mode - * (PackageAccess.Write). This method is call when other methods need write - * right. - * - * @throws InvalidOperationException - * Throws if a read operation is done on a write only package. - * @see org.apache.poi.openxml4j.opc.PackageAccess - */ - void throwExceptionIfWriteOnly() throws InvalidOperationException { - if (packageAccess == PackageAccess.WRITE) { - throw new InvalidOperationException( - "Operation not allowed, document open in write only mode!"); - } - } - - /** - * Retrieves or creates if none exists, core package property part. - * - * @return The PackageProperties part of this package. - */ - public PackageProperties getPackageProperties() - throws InvalidFormatException { - this.throwExceptionIfWriteOnly(); - // If no properties part has been found then we create one - if (this.packageProperties == null) { - this.packageProperties = new PackagePropertiesPart(this, - PackagingURIHelper.CORE_PROPERTIES_PART_NAME); - } - return this.packageProperties; - } - - /** - * Retrieve a part identified by its name. - * - * @param partName - * Part name of the part to retrieve. - * @return The part with the specified name, else null. - */ - public PackagePart getPart(PackagePartName partName) { - throwExceptionIfWriteOnly(); - - if (partName == null) { - throw new IllegalArgumentException("partName"); - } - - // If the partlist is null, then we parse the package. - if (partList == null) { - try { - getParts(); - } catch (InvalidFormatException e) { - return null; - } - } - return getPartImpl(partName); - } - - /** - * Retrieve parts by content type. - * - * @param contentType - * The content type criteria. - * @return All part associated to the specified content type. - */ - public ArrayList getPartsByContentType(String contentType) { - ArrayList retArr = new ArrayList(); - for (PackagePart part : partList.values()) { - if (part.getContentType().equals(contentType)) { - retArr.add(part); - } - } - Collections.sort(retArr); - return retArr; - } - - /** - * Retrieve parts by relationship type. - * - * @param relationshipType - * Relationship type. - * @return All parts which are the target of a relationship with the - * specified type, if the method can't retrieve relationships from - * the package, then return null. - */ - public ArrayList getPartsByRelationshipType( - String relationshipType) { - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } - ArrayList retArr = new ArrayList(); - for (PackageRelationship rel : getRelationshipsByType(relationshipType)) { - PackagePart part = getPart(rel); - if (part != null) { - retArr.add(part); - } - } - Collections.sort(retArr); - return retArr; - } - - /** - * Retrieve parts by name - * - * @param namePattern - * The pattern for matching the names - * @return All parts associated to the specified content type, sorted - * in alphanumerically by the part-name - */ - public List getPartsByName(final Pattern namePattern) { - if (namePattern == null) { - throw new IllegalArgumentException("name pattern must not be null"); - } - Matcher matcher = namePattern.matcher(""); - ArrayList result = new ArrayList(); - for (PackagePart part : partList.values()) { - PackagePartName partName = part.getPartName(); - if (matcher.reset(partName.getName()).matches()) { - result.add(part); - } - } - Collections.sort(result); - return result; - } - - /** - * Get the target part from the specified relationship. - * - * @param partRel - * The part relationship uses to retrieve the part. - */ - public PackagePart getPart(PackageRelationship partRel) { - PackagePart retPart = null; - ensureRelationships(); - for (PackageRelationship rel : relationships) { - if (rel.getRelationshipType().equals(partRel.getRelationshipType())) { - try { - retPart = getPart(PackagingURIHelper.createPartName(rel - .getTargetURI())); - } catch (InvalidFormatException e) { - continue; - } - break; - } - } - return retPart; - } - - /** - * Load the parts of the archive if it has not been done yet. The - * relationships of each part are not loaded. - * - * Note - Rule M4.1 states that there may only ever be one Core - * Properties Part, but Office produced files will sometimes - * have multiple! As Office ignores all but the first, we relax - * Compliance with Rule M4.1, and ignore all others silently too. - * - * @return All this package's parts. - */ - public ArrayList getParts() throws InvalidFormatException { - throwExceptionIfWriteOnly(); - - // If the part list is null, we parse the package to retrieve all parts. - if (partList == null) { - /* Variables use to validate OPC Compliance */ - - // Check rule M4.1 -> A format consumer shall consider more than - // one core properties relationship for a package to be an error - // (We just log it and move on, as real files break this!) - boolean hasCorePropertiesPart = false; - boolean needCorePropertiesPart = true; - - PackagePart[] parts = this.getPartsImpl(); - this.partList = new PackagePartCollection(); - for (PackagePart part : parts) { - if (partList.containsKey(part._partName)) { - throw new InvalidFormatException( - "A part with the name '" + - part._partName + - "' already exist : Packages shall not contain equivalent " + - "part names and package implementers shall neither create " + - "nor recognize packages with equivalent part names. [M1.12]"); - } - - // Check OPC compliance rule M4.1 - if (part.getContentType().equals( - ContentTypes.CORE_PROPERTIES_PART)) { - if (!hasCorePropertiesPart) { - hasCorePropertiesPart = true; - } else { - logger.log(POILogger.WARN, "OPC Compliance error [M4.1]: " + - "there is more than one core properties relationship in the package! " + - "POI will use only the first, but other software may reject this file."); - } - } - - PartUnmarshaller partUnmarshaller = partUnmarshallers.get(part._contentType); - - if (partUnmarshaller != null) { - UnmarshallContext context = new UnmarshallContext(this, - part._partName); - try { - PackagePart unmarshallPart = partUnmarshaller - .unmarshall(context, part.getInputStream()); - partList.put(unmarshallPart._partName, unmarshallPart); - - // Core properties case-- use first CoreProperties part we come across - // and ignore any subsequent ones - if (unmarshallPart instanceof PackagePropertiesPart && - hasCorePropertiesPart && - needCorePropertiesPart) { - this.packageProperties = (PackagePropertiesPart) unmarshallPart; - needCorePropertiesPart = false; - } - } catch (IOException ioe) { - logger.log(POILogger.WARN, "Unmarshall operation : IOException for " - + part._partName); - continue; - } catch (InvalidOperationException invoe) { - throw new InvalidFormatException(invoe.getMessage(), invoe); - } - } else { - try { - partList.put(part._partName, part); - } catch (InvalidOperationException e) { - throw new InvalidFormatException(e.getMessage(), e); - } - } - } - } - ArrayList result = new ArrayList(partList.values()); - java.util.Collections.sort(result); - return result; - } - - /** - * Create and add a part, with the specified name and content type, to the - * package. - * - * @param partName - * Part name. - * @param contentType - * Part content type. - * @return The newly created part. - * @throws PartAlreadyExistsException - * If rule M1.12 is not verified : Packages shall not contain - * equivalent part names and package implementers shall neither - * create nor recognize packages with equivalent part names. - * @see #createPartImpl(PackagePartName, String, boolean) - */ - public PackagePart createPart(PackagePartName partName, String contentType) { - return this.createPart(partName, contentType, true); - } - - /** - * Create and add a part, with the specified name and content type, to the - * package. For general purpose, prefer the overload version of this method - * without the 'loadRelationships' parameter. - * - * @param partName - * Part name. - * @param contentType - * Part content type. - * @param loadRelationships - * Specify if the existing relationship part, if any, logically - * associated to the newly created part will be loaded. - * @return The newly created part. - * @throws PartAlreadyExistsException - * If rule M1.12 is not verified : Packages shall not contain - * equivalent part names and package implementers shall neither - * create nor recognize packages with equivalent part names. - * @see #createPartImpl(PackagePartName, String, boolean) - */ - PackagePart createPart(PackagePartName partName, String contentType, - boolean loadRelationships) { - throwExceptionIfReadOnly(); - if (partName == null) { - throw new IllegalArgumentException("partName"); - } - - if (contentType == null || contentType.equals("")) { - throw new IllegalArgumentException("contentType"); - } - - // Check if the specified part name already exists - if (partList.containsKey(partName) - && !partList.get(partName).isDeleted()) { - throw new PartAlreadyExistsException( - "A part with the name '" + partName.getName() + "'" + - " already exists : Packages shall not contain equivalent part names and package" + - " implementers shall neither create nor recognize packages with equivalent part names. [M1.12]"); - } - - /* Check OPC compliance */ - - // Rule [M4.1]: The format designer shall specify and the format producer - // shall create at most one core properties relationship for a package. - // A format consumer shall consider more than one core properties - // relationship for a package to be an error. If present, the - // relationship shall target the Core Properties part. - // Note - POI will read files with more than one Core Properties, which - // Office sometimes produces, but is strict on generation - if (contentType.equals(ContentTypes.CORE_PROPERTIES_PART)) { - if (this.packageProperties != null) { - throw new InvalidOperationException( - "OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !"); - } - } - - /* End check OPC compliance */ - - PackagePart part = this.createPartImpl(partName, contentType, - loadRelationships); - this.contentTypeManager.addContentType(partName, contentType); - this.partList.put(partName, part); - this.isDirty = true; - return part; - } - - /** - * Add a part to the package. - * - * @param partName - * Part name of the part to create. - * @param contentType - * type associated with the file - * @param content - * the contents to add. In order to have faster operation in - * document merge, the data are stored in memory not on a hard - * disk - * - * @return The new part. - * @see #createPart(PackagePartName, String) - */ - public PackagePart createPart(PackagePartName partName, String contentType, - ByteArrayOutputStream content) { - PackagePart addedPart = this.createPart(partName, contentType); - if (addedPart == null) { - return null; - } - // Extract the zip entry content to put it in the part content - if (content != null) { - try { - OutputStream partOutput = addedPart.getOutputStream(); - if (partOutput == null) { - return null; - } - - partOutput.write(content.toByteArray(), 0, content.size()); - partOutput.close(); - - } catch (IOException ioe) { - return null; - } - } else { - return null; - } - return addedPart; - } - - /** - * Add the specified part to the package. If a part already exists in the - * package with the same name as the one specified, then we replace the old - * part by the specified part. - * - * @param part - * The part to add (or replace). - * @return The part added to the package, the same as the one specified. - * @throws InvalidFormatException - * If rule M1.12 is not verified : Packages shall not contain - * equivalent part names and package implementers shall neither - * create nor recognize packages with equivalent part names. - */ - protected PackagePart addPackagePart(PackagePart part) { - throwExceptionIfReadOnly(); - if (part == null) { - throw new IllegalArgumentException("part"); - } - - if (partList.containsKey(part._partName)) { - if (!partList.get(part._partName).isDeleted()) { - throw new InvalidOperationException( - "A part with the name '" - + part._partName.getName() - + "' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]"); - } - // If the specified partis flagged as deleted, we make it - // available - part.setDeleted(false); - // and delete the old part to replace it thereafeter - this.partList.remove(part._partName); - } - this.partList.put(part._partName, part); - this.isDirty = true; - return part; - } - - /** - * Remove the specified part in this package. If this part is relationship - * part, then delete all relationships in the source part. - * - * @param part - * The part to remove. If null, skip the action. - * @see #removePart(PackagePartName) - */ - public void removePart(PackagePart part) { - if (part != null) { - removePart(part.getPartName()); - } - } - - /** - * Remove a part in this package. If this part is relationship part, then - * delete all relationships in the source part. - * - * @param partName - * The part name of the part to remove. - */ - public void removePart(PackagePartName partName) { - throwExceptionIfReadOnly(); - if (partName == null || !this.containPart(partName)) { - throw new IllegalArgumentException("partName"); - } - - // Delete the specified part from the package. - if (this.partList.containsKey(partName)) { - this.partList.get(partName).setDeleted(true); - this.removePartImpl(partName); - this.partList.remove(partName); - } else { - this.removePartImpl(partName); - } - - // Delete content type - this.contentTypeManager.removeContentType(partName); - - // If this part is a relationship part, then delete all relationships of - // the source part. - if (partName.isRelationshipPartURI()) { - URI sourceURI = PackagingURIHelper - .getSourcePartUriFromRelationshipPartUri(partName.getURI()); - PackagePartName sourcePartName; - try { - sourcePartName = PackagingURIHelper.createPartName(sourceURI); - } catch (InvalidFormatException e) { - logger - .log(POILogger.ERROR, "Part name URI '" - + sourceURI - + "' is not valid ! This message is not intended to be displayed !"); - return; - } - if (sourcePartName.getURI().equals( - PackagingURIHelper.PACKAGE_ROOT_URI)) { - clearRelationships(); - } else if (containPart(sourcePartName)) { - PackagePart part = getPart(sourcePartName); - if (part != null) { - part.clearRelationships(); - } - } - } - - this.isDirty = true; - } - - /** - * Remove a part from this package as well as its relationship part, if one - * exists, and all parts listed in the relationship part. Be aware that this - * do not delete relationships which target the specified part. - * - * @param partName - * The name of the part to delete. - * @throws InvalidFormatException - * Throws if the associated relationship part of the specified - * part is not valid. - */ - public void removePartRecursive(PackagePartName partName) - throws InvalidFormatException { - // Retrieves relationship part, if one exists - PackagePart relPart = this.partList.get(PackagingURIHelper - .getRelationshipPartName(partName)); - // Retrieves PackagePart object from the package - PackagePart partToRemove = this.partList.get(partName); - - if (relPart != null) { - PackageRelationshipCollection partRels = new PackageRelationshipCollection( - partToRemove); - for (PackageRelationship rel : partRels) { - PackagePartName partNameToRemove = PackagingURIHelper - .createPartName(PackagingURIHelper.resolvePartUri(rel - .getSourceURI(), rel.getTargetURI())); - removePart(partNameToRemove); - } - - // Finally delete its relationship part if one exists - this.removePart(relPart._partName); - } - - // Delete the specified part - this.removePart(partToRemove._partName); - } - - /** - * Delete the part with the specified name and its associated relationships - * part if one exists. Prefer the use of this method to delete a part in the - * package, compare to the remove() methods that don't remove associated - * relationships part. - * - * @param partName - * Name of the part to delete - */ - public void deletePart(PackagePartName partName) { - if (partName == null) { - throw new IllegalArgumentException("partName"); - } - - // Remove the part - this.removePart(partName); - // Remove the relationships part - this.removePart(PackagingURIHelper.getRelationshipPartName(partName)); - } - - /** - * Delete the part with the specified name and all part listed in its - * associated relationships part if one exists. This process is recursively - * apply to all parts in the relationships part of the specified part. - * Prefer the use of this method to delete a part in the package, compare to - * the remove() methods that don't remove associated relationships part. - * - * @param partName - * Name of the part to delete - */ - public void deletePartRecursive(PackagePartName partName) { - if (partName == null || !this.containPart(partName)) { - throw new IllegalArgumentException("partName"); - } - - PackagePart partToDelete = this.getPart(partName); - // Remove the part - this.removePart(partName); - // Remove all relationship parts associated - try { - for (PackageRelationship relationship : partToDelete - .getRelationships()) { - PackagePartName targetPartName = PackagingURIHelper - .createPartName(PackagingURIHelper.resolvePartUri( - partName.getURI(), relationship.getTargetURI())); - this.deletePartRecursive(targetPartName); - } - } catch (InvalidFormatException e) { - logger.log(POILogger.WARN, "An exception occurs while deleting part '" - + partName.getName() - + "'. Some parts may remain in the package. - " - + e.getMessage()); - return; - } - // Remove the relationships part - PackagePartName relationshipPartName = PackagingURIHelper - .getRelationshipPartName(partName); - if (relationshipPartName != null && containPart(relationshipPartName)) { - this.removePart(relationshipPartName); - } - } - - /** - * Check if a part already exists in this package from its name. - * - * @param partName - * Part name to check. - * @return true if the part is logically added to this package, else - * false. - */ - public boolean containPart(PackagePartName partName) { - return (this.getPart(partName) != null); - } - - /** - * Add a relationship to the package (except relationships part). - * - * Check rule M4.1 : The format designer shall specify and the format - * producer shall create at most one core properties relationship for a - * package. A format consumer shall consider more than one core properties - * relationship for a package to be an error. If present, the relationship - * shall target the Core Properties part. - * - * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - * - * @param targetPartName - * Target part name. - * @param targetMode - * Target mode, either Internal or External. - * @param relationshipType - * Relationship type. - * @param relID - * ID of the relationship. - * @see PackageRelationshipTypes - */ - @Override - public PackageRelationship addRelationship(PackagePartName targetPartName, - TargetMode targetMode, String relationshipType, String relID) { - /* Check OPC compliance */ - - // Check rule M4.1 : The format designer shall specify and the format - // producer - // shall create at most one core properties relationship for a package. - // A format consumer shall consider more than one core properties - // relationship for a package to be an error. If present, the - // relationship shall target the Core Properties part. - if (relationshipType.equals(PackageRelationshipTypes.CORE_PROPERTIES) - && this.packageProperties != null) { - throw new InvalidOperationException( - "OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead."); - } - - /* - * Check rule M1.25: The Relationships part shall not have relationships - * to any other part. Package implementers shall enforce this - * requirement upon the attempt to create such a relationship and shall - * treat any such relationship as invalid. - */ - if (targetPartName.isRelationshipPartURI()) { - throw new InvalidOperationException( - "Rule M1.25: The Relationships part shall not have relationships to any other part."); - } - - /* End OPC compliance */ - - ensureRelationships(); - PackageRelationship retRel = relationships.addRelationship( - targetPartName.getURI(), targetMode, relationshipType, relID); - this.isDirty = true; - return retRel; - } - - /** - * Add a package relationship. - * - * @param targetPartName - * Target part name. - * @param targetMode - * Target mode, either Internal or External. - * @param relationshipType - * Relationship type. - * @see PackageRelationshipTypes - */ - @Override - public PackageRelationship addRelationship(PackagePartName targetPartName, - TargetMode targetMode, String relationshipType) { - return this.addRelationship(targetPartName, targetMode, - relationshipType, null); - } - - /** - * Adds an external relationship to a part (except relationships part). - * - * The targets of external relationships are not subject to the same - * validity checks that internal ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target - * External target of the relationship - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, - * java.lang.String) - */ - @Override - public PackageRelationship addExternalRelationship(String target, - String relationshipType) { - return addExternalRelationship(target, relationshipType, null); - } - - /** - * Adds an external relationship to a part (except relationships part). - * - * The targets of external relationships are not subject to the same - * validity checks that internal ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target - * External target of the relationship - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, - * java.lang.String) - */ - @Override - public PackageRelationship addExternalRelationship(String target, - String relationshipType, String id) { - if (target == null) { - throw new IllegalArgumentException("target"); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } - - URI targetURI; - try { - targetURI = new URI(target); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid target - " + e); - } - - ensureRelationships(); - PackageRelationship retRel = relationships.addRelationship(targetURI, - TargetMode.EXTERNAL, relationshipType, id); - this.isDirty = true; - return retRel; - } - - /** - * Delete a relationship from this package. - * - * @param id - * Id of the relationship to delete. - */ - @Override - public void removeRelationship(String id) { - if (relationships != null) { - relationships.removeRelationship(id); - this.isDirty = true; - } - } - - /** - * Retrieves all package relationships. - * - * @return All package relationships of this package. - * @throws OpenXML4JException - * @see #getRelationshipsHelper(String) - */ - @Override - public PackageRelationshipCollection getRelationships() { - return getRelationshipsHelper(null); - } - - /** - * Retrieves all relationships with the specified type. - * - * @param relationshipType - * The filter specifying the relationship type. - * @return All relationships with the specified relationship type. - */ - @Override - public PackageRelationshipCollection getRelationshipsByType( - String relationshipType) { - throwExceptionIfWriteOnly(); - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } - return getRelationshipsHelper(relationshipType); - } - - /** - * Retrieves all relationships with specified id (normally just ine because - * a relationship id is supposed to be unique). - * - * @param id - * Id of the wanted relationship. - */ - private PackageRelationshipCollection getRelationshipsHelper(String id) { - throwExceptionIfWriteOnly(); - ensureRelationships(); - return this.relationships.getRelationships(id); - } - - /** - * Clear package relationships. - */ - @Override - public void clearRelationships() { - if (relationships != null) { - relationships.clear(); - this.isDirty = true; - } - } - - /** - * Ensure that the relationships collection is not null. - */ - public void ensureRelationships() { - if (this.relationships == null) { - try { - this.relationships = new PackageRelationshipCollection(this); - } catch (InvalidFormatException e) { - this.relationships = new PackageRelationshipCollection(); - } - } - } - - /** - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String) - */ - @Override - public PackageRelationship getRelationship(String id) { - return this.relationships.getRelationshipByID(id); - } - - /** - * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships() - */ - @Override - public boolean hasRelationships() { - return (relationships.size() > 0); - } - - /** - * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship) - */ - @Override - public boolean isRelationshipExists(PackageRelationship rel) { - for (PackageRelationship r : relationships) { - if (r == rel) { - return true; - } - } - return false; - } - - /** - * Add a marshaller. - * - * @param contentType - * The content type to bind to the specified marshaller. - * @param marshaller - * The marshaller to register with the specified content type. - */ - public void addMarshaller(String contentType, PartMarshaller marshaller) { - try { - partMarshallers.put(new ContentType(contentType), marshaller); - } catch (InvalidFormatException e) { - logger.log(POILogger.WARN, "The specified content type is not valid: '" - + e.getMessage() + "'. The marshaller will not be added !"); - } - } - - /** - * Add an unmarshaller. - * - * @param contentType - * The content type to bind to the specified unmarshaller. - * @param unmarshaller - * The unmarshaller to register with the specified content type. - */ - public void addUnmarshaller(String contentType, - PartUnmarshaller unmarshaller) { - try { - partUnmarshallers.put(new ContentType(contentType), unmarshaller); - } catch (InvalidFormatException e) { - logger.log(POILogger.WARN, "The specified content type is not valid: '" - + e.getMessage() - + "'. The unmarshaller will not be added !"); - } - } - - /** - * Remove a marshaller by its content type. - * - * @param contentType - * The content type associated with the marshaller to remove. - */ - public void removeMarshaller(String contentType) { - try { - partMarshallers.remove(new ContentType(contentType)); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } - } - - /** - * Remove an unmarshaller by its content type. - * - * @param contentType - * The content type associated with the unmarshaller to remove. - */ - public void removeUnmarshaller(String contentType) { - try { - partUnmarshallers.remove(new ContentType(contentType)); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } - } - - /* Accesseurs */ - - /** - * Get the package access mode. - * - * @return the packageAccess The current package access. - */ - public PackageAccess getPackageAccess() { - return packageAccess; - } - - /** - * Validates the package compliance with the OPC specifications. - * - * @return true if the package is valid else false - */ - @NotImplemented - public boolean validatePackage(OPCPackage pkg) throws InvalidFormatException { - throw new InvalidOperationException("Not implemented yet !!!"); - } - - /** - * Save the document in the specified file. - * - * @param targetFile - * Destination file. - * @throws IOException - * Throws if an IO exception occur. - * @see #save(OutputStream) - */ - public void save(File targetFile) throws IOException { - if (targetFile == null) { - throw new IllegalArgumentException("targetFile"); - } - - this.throwExceptionIfReadOnly(); - - // You shouldn't save the the same file, do a close instead - if(targetFile.exists() && - targetFile.getAbsolutePath().equals(this.originalPackagePath)) { - throw new InvalidOperationException( - "You can't call save(File) to save to the currently open " + - "file. To save to the current file, please just call close()" - ); - } - - // Do the save - FileOutputStream fos = null; - try { - fos = new FileOutputStream(targetFile); - this.save(fos); - } finally { - if (fos != null) fos.close(); - } - } - - /** - * Save the document in the specified output stream. - * - * @param outputStream - * The stream to save the package. - * @see #saveImpl(OutputStream) - */ - public void save(OutputStream outputStream) throws IOException { - throwExceptionIfReadOnly(); - this.saveImpl(outputStream); - } - - /** - * Core method to create a package part. This method must be implemented by - * the subclass. - * - * @param partName - * URI of the part to create. - * @param contentType - * Content type of the part to create. - * @return The newly created package part. - */ - protected abstract PackagePart createPartImpl(PackagePartName partName, - String contentType, boolean loadRelationships); - - /** - * Core method to delete a package part. This method must be implemented by - * the subclass. - * - * @param partName - * The URI of the part to delete. - */ - protected abstract void removePartImpl(PackagePartName partName); - - /** - * Flush the package but not save. - */ - protected abstract void flushImpl(); - - /** - * Close the package and cause a save of the package. - * - */ - protected abstract void closeImpl() throws IOException; - - /** - * Close the package without saving the document. Discard all changes made - * to this package. - */ - protected abstract void revertImpl(); - - /** - * Save the package into the specified output stream. - * - * @param outputStream - * The output stream use to save this package. - */ - protected abstract void saveImpl(OutputStream outputStream) - throws IOException; - - /** - * Get the package part mapped to the specified URI. - * - * @param partName - * The URI of the part to retrieve. - * @return The package part located by the specified URI, else null. - */ - protected abstract PackagePart getPartImpl(PackagePartName partName); - - /** - * Get all parts link to the package. - * - * @return A list of the part owned by the package. - */ - protected abstract PackagePart[] getPartsImpl() - throws InvalidFormatException; - - /** - * Replace a content type in this package. - * - *

        - * A typical scneario to call this method is to rename a template file to the main format, e.g. - * ".dotx" to ".docx" - * ".dotm" to ".docm" - * ".xltx" to ".xlsx" - * ".xltm" to ".xlsm" - * ".potx" to ".pptx" - * ".potm" to ".pptm" - *

        - * For example, a code converting a .xlsm macro workbook to .xlsx would look as follows: - *

        - *

        
        -     *
        -     *     OPCPackage pkg = OPCPackage.open(new FileInputStream("macro-workbook.xlsm"));
        -     *     pkg.replaceContentType(
        -     *         "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
        -     *         "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
        -     *
        -     *     FileOutputStream out = new FileOutputStream("workbook.xlsx");
        -     *     pkg.save(out);
        -     *     out.close();
        -     *
        -     *    
        - *

        - * - * @param oldContentType the content type to be replaced - * @param newContentType the replacement - * @return whether replacement was succesfull - * @since POI-3.8 - */ - public boolean replaceContentType(String oldContentType, String newContentType){ - boolean success = false; - ArrayList list = getPartsByContentType(oldContentType); - for (PackagePart packagePart : list) { - if (packagePart.getContentType().equals(oldContentType)) { - PackagePartName partName = packagePart.getPartName(); - contentTypeManager.addContentType(partName, newContentType); - try { - packagePart.setContentType(newContentType); - } catch (InvalidFormatException e) { - throw new OpenXML4JRuntimeException("invalid content type - "+newContentType, e); - } - success = true; - this.isDirty = true; - } - } - return success; - } - - /** - * Add the specified part, and register its content type with the content - * type manager. - * - * @param part - * The part to add. - */ - public void registerPartAndContentType(PackagePart part) { - addPackagePart(part); - this.contentTypeManager.addContentType(part.getPartName(), part.getContentType()); - this.isDirty = true; - } - - /** - * Remove the specified part, and clear its content type from the content - * type manager. - * - * @param partName - * The part name of the part to remove. - */ - public void unregisterPartAndContentType(PackagePartName partName) { - removePart(partName); - this.contentTypeManager.removeContentType(partName); - this.isDirty = true; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java deleted file mode 100644 index 256882228..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -/** - * Specifies package access. - * - * @author Julien Chable - * @version 1.0 - */ -public enum PackageAccess { - /** Read only. Write not authorized. */ - READ, - /** Write only. Read not authorized. */ - WRITE, - /** Read and Write mode. */ - READ_WRITE -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java deleted file mode 100644 index d1adc519f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -/** - * Open Packaging Convention namespaces URI. - * - * @author Julien Chable - * @version 1.0 - */ -public interface PackageNamespaces { - - /** - * Content Types. - */ - public static final String CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; - - /** - * Core Properties. - */ - public static final String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; - - /** - * Digital Signatures. - */ - public static final String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/digital-signature"; - - /** - * Relationships. - */ - public static final String RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships"; - - /** - * Markup Compatibility. - */ - public static final String MARKUP_COMPATIBILITY = "http://schemas.openxmlformats.org/markup-compatibility/2006"; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java deleted file mode 100644 index 23969fa68..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java +++ /dev/null @@ -1,720 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URI; -import java.net.URISyntaxException; - -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.ContentType; - -/** - * Provides a base class for parts stored in a Package. - */ -public abstract class PackagePart implements RelationshipSource, Comparable { - - /** - * This part's container. - */ - protected OPCPackage _container; - - /** - * The part name. (required by the specification [M1.1]) - */ - protected PackagePartName _partName; - - /** - * The type of content of this part. (required by the specification [M1.2]) - */ - protected ContentType _contentType; - - /** - * Flag to know if this part is a relationship. - */ - private boolean _isRelationshipPart; - - /** - * Flag to know if this part has been logically deleted. - */ - private boolean _isDeleted; - - /** - * This part's relationships. - */ - private PackageRelationshipCollection _relationships; - - /** - * Constructor. - * - * @param pack - * Parent package. - * @param partName - * The part name, relative to the parent Package root. - * @param contentType - * The content type. - * @throws InvalidFormatException - * If the specified URI is not valid. - */ - protected PackagePart(OPCPackage pack, PackagePartName partName, - ContentType contentType) throws InvalidFormatException { - this(pack, partName, contentType, true); - } - - /** - * Constructor. - * - * @param pack - * Parent package. - * @param partName - * The part name, relative to the parent Package root. - * @param contentType - * The content type. - * @param loadRelationships - * Specify if the relationships will be loaded - * @throws InvalidFormatException - * If the specified URI is not valid. - */ - protected PackagePart(OPCPackage pack, PackagePartName partName, - ContentType contentType, boolean loadRelationships) - throws InvalidFormatException { - _partName = partName; - _contentType = contentType; - _container = pack; - - // Check if this part is a relationship part - _isRelationshipPart = this._partName.isRelationshipPartURI(); - - // Load relationships if any - if (loadRelationships) - loadRelationships(); - } - - /** - * Constructor. - * - * @param pack - * Parent package. - * @param partName - * The part name, relative to the parent Package root. - * @param contentType - * The Multipurpose Internet Mail Extensions (MIME) content type - * of the part's data stream. - */ - public PackagePart(OPCPackage pack, PackagePartName partName, - String contentType) throws InvalidFormatException { - this(pack, partName, new ContentType(contentType)); - } - - /** - * Adds an external relationship to a part (except relationships part). - * - * The targets of external relationships are not subject to the same - * validity checks that internal ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target - * External target of the relationship - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, - * java.lang.String) - */ - public PackageRelationship addExternalRelationship(String target, - String relationshipType) { - return addExternalRelationship(target, relationshipType, null); - } - - /** - * Adds an external relationship to a part (except relationships part). - * - * The targets of external relationships are not subject to the same - * validity checks that internal ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target - * External target of the relationship - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, - * java.lang.String) - */ - public PackageRelationship addExternalRelationship(String target, - String relationshipType, String id) { - if (target == null) { - throw new IllegalArgumentException("target is null for type " + relationshipType); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } - - if (_relationships == null) { - _relationships = new PackageRelationshipCollection(); - } - - URI targetURI; - try { - targetURI = new URI(target); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid target - " + e); - } - - return _relationships.addRelationship(targetURI, TargetMode.EXTERNAL, - relationshipType, id); - } - - /** - * Add a relationship to a part (except relationships part). - * - * @param targetPartName - * Name of the target part. This one must be relative to the - * source root directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String) - */ - public PackageRelationship addRelationship(PackagePartName targetPartName, - TargetMode targetMode, String relationshipType) { - return addRelationship(targetPartName, targetMode, relationshipType, - null); - } - - /** - * Add a relationship to a part (except relationships part). - *

        - * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - *

        - * @param targetPartName - * Name of the target part. This one must be relative to the - * source root directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * - * @throws InvalidOperationException - * If a writing operation is done on a read only package or - * invalid nested relations are created. - * @throws InvalidFormatException - * If the URI point to a relationship part URI. - * @throws IllegalArgumentException if targetPartName, targetMode - * or relationshipType are passed as null - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String) - */ - public PackageRelationship addRelationship(PackagePartName targetPartName, - TargetMode targetMode, String relationshipType, String id) { - _container.throwExceptionIfReadOnly(); - - if (targetPartName == null) { - throw new IllegalArgumentException("targetPartName"); - } - if (targetMode == null) { - throw new IllegalArgumentException("targetMode"); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } - - if (this._isRelationshipPart || targetPartName.isRelationshipPartURI()) { - throw new InvalidOperationException( - "Rule M1.25: The Relationships part shall not have relationships to any other part."); - } - - if (_relationships == null) { - _relationships = new PackageRelationshipCollection(); - } - - return _relationships.addRelationship(targetPartName.getURI(), - targetMode, relationshipType, id); - } - - /** - * Add a relationship to a part (except relationships part). - * - * @param targetURI - * URI the target part. Must be relative to the source root - * directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String) - */ - public PackageRelationship addRelationship(URI targetURI, - TargetMode targetMode, String relationshipType) { - return addRelationship(targetURI, targetMode, relationshipType, null); - } - - /** - * Add a relationship to a part (except relationships part). - *

        - * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - *

        - * @param targetURI - * URI of the target part. Must be relative to the source root - * directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * - * @throws InvalidFormatException - * If the URI point to a relationship part URI. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String) - */ - public PackageRelationship addRelationship(URI targetURI, - TargetMode targetMode, String relationshipType, String id) { - _container.throwExceptionIfReadOnly(); - - if (targetURI == null) { - throw new IllegalArgumentException("targetPartName"); - } - if (targetMode == null) { - throw new IllegalArgumentException("targetMode"); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } - - // Try to retrieve the target part - - if (this._isRelationshipPart - || PackagingURIHelper.isRelationshipPartURI(targetURI)) { - throw new InvalidOperationException( - "Rule M1.25: The Relationships part shall not have relationships to any other part."); - } - - if (_relationships == null) { - _relationships = new PackageRelationshipCollection(); - } - - return _relationships.addRelationship(targetURI, - targetMode, relationshipType, id); - } - - /** - * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships() - */ - public void clearRelationships() { - if (_relationships != null) { - _relationships.clear(); - } - } - - /** - * Delete the relationship specified by its id. - * - * @param id - * The ID identified the part to delete. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#removeRelationship(java.lang.String) - */ - public void removeRelationship(String id) { - this._container.throwExceptionIfReadOnly(); - if (this._relationships != null) - this._relationships.removeRelationship(id); - } - - /** - * Retrieve all the relationships attached to this part. - * - * @return This part's relationships. - * @throws OpenXML4JException - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationships() - */ - public PackageRelationshipCollection getRelationships() - throws InvalidFormatException { - return getRelationshipsCore(null); - } - - /** - * Retrieves a package relationship from its id. - * - * @param id - * ID of the package relationship to retrieve. - * @return The package relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String) - */ - public PackageRelationship getRelationship(String id) { - return this._relationships.getRelationshipByID(id); - } - - /** - * Retrieve all relationships attached to this part which have the specified - * type. - * - * @param relationshipType - * Relationship type filter. - * @return All relationships from this part that have the specified type. - * @throws InvalidFormatException - * If an error occurs while parsing the part. - * @throws InvalidOperationException - * If the package is open in write only mode. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationshipsByType(java.lang.String) - */ - public PackageRelationshipCollection getRelationshipsByType( - String relationshipType) throws InvalidFormatException { - _container.throwExceptionIfWriteOnly(); - - return getRelationshipsCore(relationshipType); - } - - /** - * Implementation of the getRelationships method(). - * - * @param filter - * Relationship type filter. If null then the filter is - * disabled and return all the relationships. - * @return All relationships from this part that have the specified type. - * @throws InvalidFormatException - * Throws if an error occurs during parsing the relationships - * part. - * @throws InvalidOperationException - * Throws if the package is open en write only mode. - * @see #getRelationshipsByType(String) - */ - private PackageRelationshipCollection getRelationshipsCore(String filter) - throws InvalidFormatException { - this._container.throwExceptionIfWriteOnly(); - if (_relationships == null) { - this.throwExceptionIfRelationship(); - _relationships = new PackageRelationshipCollection(this); - } - return new PackageRelationshipCollection(_relationships, filter); - } - - /** - * Knows if the part have any relationships. - * - * @return true if the part have at least one relationship else - * false. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships() - */ - public boolean hasRelationships() { - return (!this._isRelationshipPart && (_relationships != null && _relationships - .size() > 0)); - } - - /** - * Checks if the specified relationship is part of this package part. - * - * @param rel - * The relationship to check. - * @return true if the specified relationship exists in this part, - * else returns false - * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship) - */ - public boolean isRelationshipExists(PackageRelationship rel) { - for (PackageRelationship r : _relationships) { - if (r == rel) - return true; - } - return false; - } - - /** - * Get the PackagePart that is the target of a relationship. - * - * @param rel A relationship from this part to another one - * @return The target part of the relationship - */ - public PackagePart getRelatedPart(PackageRelationship rel) throws InvalidFormatException { - // Ensure this is one of ours - if(! isRelationshipExists(rel)) { - throw new IllegalArgumentException("Relationship " + rel + " doesn't start with this part " + _partName); - } - - // Get the target URI, excluding any relative fragments - URI target = rel.getTargetURI(); - if(target.getFragment() != null) { - String t = target.toString(); - try { - target = new URI( t.substring(0, t.indexOf('#')) ); - } catch(URISyntaxException e) { - throw new InvalidFormatException("Invalid target URI: " + target); - } - } - - // Turn that into a name, and fetch - PackagePartName relName = PackagingURIHelper.createPartName(target); - PackagePart part = _container.getPart(relName); - if (part == null) { - throw new IllegalArgumentException("No part found for relationship " + rel); - } - return part; - } - - /** - * Get the input stream of this part to read its content. - * - * @return The input stream of the content of this part, else - * null. - */ - public InputStream getInputStream() throws IOException { - InputStream inStream = this.getInputStreamImpl(); - if (inStream == null) { - throw new IOException("Can't obtain the input stream from " - + _partName.getName()); - } - return inStream; - } - - /** - * Get the output stream of this part. If the part is originally embedded in - * Zip package, it'll be transform intot a MemoryPackagePart in - * order to write inside (the standard Java API doesn't allow to write in - * the file) - * - * @see org.apache.poi.openxml4j.opc.internal.MemoryPackagePart - */ - public OutputStream getOutputStream() { - OutputStream outStream; - // If this part is a zip package part (read only by design) we convert - // this part into a MemoryPackagePart instance for write purpose. - if (this instanceof ZipPackagePart) { - // Delete logically this part - _container.removePart(this._partName); - - // Create a memory part - PackagePart part = _container.createPart(this._partName, - this._contentType.toString(), false); - if (part == null) { - throw new InvalidOperationException( - "Can't create a temporary part !"); - } - part._relationships = this._relationships; - outStream = part.getOutputStreamImpl(); - } else { - outStream = this.getOutputStreamImpl(); - } - return outStream; - } - - /** - * Throws an exception if this package part is a relationship part. - * - * @throws InvalidOperationException - * If this part is a relationship part. - */ - private void throwExceptionIfRelationship() - throws InvalidOperationException { - if (this._isRelationshipPart) - throw new InvalidOperationException( - "Can do this operation on a relationship part !"); - } - - /** - * Ensure the package relationships collection instance is built. - * - * @throws InvalidFormatException - * Throws if - */ - private void loadRelationships() throws InvalidFormatException { - if (this._relationships == null && !this._isRelationshipPart) { - this.throwExceptionIfRelationship(); - _relationships = new PackageRelationshipCollection(this); - } - } - - /* - * Accessors - */ - - /** - * @return the uri - */ - public PackagePartName getPartName() { - return _partName; - } - - /** - * @return The Content Type of the part - */ - public String getContentType() { - return _contentType.toString(); - } - - /** - * @return The Content Type, including parameters, of the part - */ - public ContentType getContentTypeDetails() { - return _contentType; - } - - /** - * Set the content type. - * - * @param contentType - * the contentType to set - * - * @throws InvalidFormatException - * Throws if the content type is not valid. - * @throws InvalidOperationException - * Throws if you try to change the content type whereas this - * part is already attached to a package. - */ - public void setContentType(String contentType) - throws InvalidFormatException { - if (_container == null) { - _contentType = new ContentType(contentType); - } - else { - _container.unregisterPartAndContentType(_partName); - _contentType = new ContentType(contentType); - _container.registerPartAndContentType(this); - } - } - - public OPCPackage getPackage() { - return _container; - } - - /** - * @return true if this part is a relationship - */ - public boolean isRelationshipPart() { - return this._isRelationshipPart; - } - - /** - * @return true if this part has been logically deleted - */ - public boolean isDeleted() { - return _isDeleted; - } - - /** - * @param isDeleted - * the isDeleted to set - */ - public void setDeleted(boolean isDeleted) { - this._isDeleted = isDeleted; - } - - /** - * @return The length of the part in bytes, or -1 if not known - */ - public long getSize() { - return -1; - } - - @Override - public String toString() { - return "Name: " + this._partName + " - Content Type: " - + this._contentType.toString(); - } - - /** - * Compare based on the package part name, using a natural sort order - */ - @Override - public int compareTo(PackagePart other) - { - // NOTE could also throw a NullPointerException() if desired - if (other == null) - return -1; - - return PackagePartName.compare(this._partName, other._partName); - } - - /*-------------- Abstract methods ------------- */ - - /** - * Abtract method that get the input stream of this part. - * - * @exception IOException - * Throws if an IO Exception occur in the implementation - * method. - */ - protected abstract InputStream getInputStreamImpl() throws IOException; - - /** - * Abstract method that get the output stream of this part. - */ - protected abstract OutputStream getOutputStreamImpl(); - - /** - * Save the content of this part and the associated relationships part (if - * this part own at least one relationship) into the specified output - * stream. - * - * @param zos - * Output stream to save this part. - * @throws OpenXML4JException - * If any exception occur. - */ - public abstract boolean save(OutputStream zos) throws OpenXML4JException; - - /** - * Load the content of this part. - * - * @param ios - * The input stream of the content to load. - * @return true if the content has been successfully loaded, else - * false. - * @throws InvalidFormatException - * Throws if the content format is invalid. - */ - public abstract boolean load(InputStream ios) throws InvalidFormatException; - - /** - * Close this part : flush this part, close the input stream and output - * stream. After this method call, the part must be available for packaging. - */ - public abstract void close(); - - /** - * Flush the content of this part. If the input stream and/or output stream - * as in a waiting state to read or write, the must to empty their - * respective buffer. - */ - public abstract void flush(); - - /** - * Allows sub-classes to clean up before new data is added. - */ - public void clear() { - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java deleted file mode 100644 index e4ecbd44b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 { - - private static final long serialVersionUID = 2515031135957635515L; - - /** - * Arraylist use to store this collection part names as string for rule - * M1.11 optimized checking. - */ - private ArrayList registerPartNameStr = new ArrayList(); - - @Override - public Object clone() { - return super.clone(); - } - - /** - * Check rule [M1.11]: a package implementer shall neither create nor - * recognize a part with a part name derived from another part name by - * appending segments to it. - * - * @exception InvalidOperationException - * Throws if you try to add a part with a name derived from - * another part name. - */ - @Override - public PackagePart put(PackagePartName partName, PackagePart part) { - String[] segments = partName.getURI().toASCIIString().split( - PackagingURIHelper.FORWARD_SLASH_STRING); - StringBuffer concatSeg = new StringBuffer(); - for (String seg : segments) { - if (!seg.equals("")) - concatSeg.append(PackagingURIHelper.FORWARD_SLASH_CHAR); - concatSeg.append(seg); - if (this.registerPartNameStr.contains(concatSeg.toString())) { - throw new InvalidOperationException( - "You can't add a part with a part name derived from another part ! [M1.11]"); - } - } - this.registerPartNameStr.add(partName.getName()); - return super.put(partName, part); - } - - @Override - public PackagePart remove(Object key) { - if (key instanceof PackagePartName) { - this.registerPartNameStr.remove(((PackagePartName) key).getName()); - } - return super.remove(key); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java deleted file mode 100644 index 37ee63177..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java +++ /dev/null @@ -1,615 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.math.BigInteger; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Locale; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; - -/** - * An immutable Open Packaging Convention compliant part name. - * - * @author Julien Chable - * - * @see http://www.ietf.org/rfc/rfc3986.txt - */ -public final class PackagePartName implements Comparable { - - /** - * Part name stored as an URI. - */ - private URI partNameURI; - - /* - * URI Characters definition (RFC 3986) - */ - - /** - * Reserved characters for sub delimitations. - */ - private static String[] RFC3986_PCHAR_SUB_DELIMS = { "!", "$", "&", "'", - "(", ")", "*", "+", ",", ";", "=" }; - - /** - * Unreserved character (+ ALPHA & DIGIT). - */ - private static String[] RFC3986_PCHAR_UNRESERVED_SUP = { "-", ".", "_", "~" }; - - /** - * Authorized reserved characters for pChar. - */ - private static String[] RFC3986_PCHAR_AUTHORIZED_SUP = { ":", "@" }; - - /** - * Flag to know if this part name is from a relationship part name. - */ - private boolean isRelationship; - - /** - * Constructor. Makes a ValidPartName object from a java.net.URI - * - * @param uri - * The URI to validate and to transform into ValidPartName. - * @param checkConformance - * Flag to specify if the contructor have to validate the OPC - * conformance. Must be always true except for - * special URI like '/' which is needed for internal use by - * OpenXML4J but is not valid. - * @throws InvalidFormatException - * Throw if the specified part name is not conform to Open - * Packaging Convention specifications. - * @see java.net.URI - */ - PackagePartName(URI uri, boolean checkConformance) - throws InvalidFormatException { - if (checkConformance) { - throwExceptionIfInvalidPartUri(uri); - } else { - if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(uri)) { - throw new OpenXML4JRuntimeException( - "OCP conformance must be check for ALL part name except special cases : ['/']"); - } - } - this.partNameURI = uri; - this.isRelationship = isRelationshipPartURI(this.partNameURI); - } - - /** - * Constructor. Makes a ValidPartName object from a String part name. - * - * @param partName - * Part name to valid and to create. - * @param checkConformance - * Flag to specify if the contructor have to validate the OPC - * conformance. Must be always true except for - * special URI like '/' which is needed for internal use by - * OpenXML4J but is not valid. - * @throws InvalidFormatException - * Throw if the specified part name is not conform to Open - * Packaging Convention specifications. - */ - PackagePartName(String partName, boolean checkConformance) - throws InvalidFormatException { - URI partURI; - try { - partURI = new URI(partName); - } catch (URISyntaxException e) { - throw new IllegalArgumentException( - "partName argmument is not a valid OPC part name !"); - } - - if (checkConformance) { - throwExceptionIfInvalidPartUri(partURI); - } else { - if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(partURI)) { - throw new OpenXML4JRuntimeException( - "OCP conformance must be check for ALL part name except special cases : ['/']"); - } - } - this.partNameURI = partURI; - this.isRelationship = isRelationshipPartURI(this.partNameURI); - } - - /** - * Check if the specified part name is a relationship part name. - * - * @param partUri - * The URI to check. - * @return true if this part name respect the relationship - * part naming convention else false. - */ - private boolean isRelationshipPartURI(URI partUri) { - if (partUri == null) - throw new IllegalArgumentException("partUri"); - - return partUri.getPath().matches( - "^.*/" + PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME + "/.*\\" - + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME - + "$"); - } - - /** - * Know if this part name is a relationship part name. - * - * @return true if this part name respect the relationship - * part naming convention else false. - */ - public boolean isRelationshipPartURI() { - return this.isRelationship; - } - - /** - * Throws an exception (of any kind) if the specified part name does not - * follow the Open Packaging Convention specifications naming rules. - * - * @param partUri - * The part name to check. - * @throws Exception - * Throws if the part name is invalid. - */ - private static void throwExceptionIfInvalidPartUri(URI partUri) - throws InvalidFormatException { - if (partUri == null) - throw new IllegalArgumentException("partUri"); - // Check if the part name URI is empty [M1.1] - throwExceptionIfEmptyURI(partUri); - - // Check if the part name URI is absolute - throwExceptionIfAbsoluteUri(partUri); - - // Check if the part name URI starts with a forward slash [M1.4] - throwExceptionIfPartNameNotStartsWithForwardSlashChar(partUri); - - // Check if the part name URI ends with a forward slash [M1.5] - throwExceptionIfPartNameEndsWithForwardSlashChar(partUri); - - // Check if the part name does not have empty segments. [M1.3] - // Check if a segment ends with a dot ('.') character. [M1.9] - throwExceptionIfPartNameHaveInvalidSegments(partUri); - } - - /** - * Throws an exception if the specified URI is empty. [M1.1] - * - * @param partURI - * Part URI to check. - * @throws InvalidFormatException - * If the specified URI is empty. - */ - private static void throwExceptionIfEmptyURI(URI partURI) - throws InvalidFormatException { - if (partURI == null) - throw new IllegalArgumentException("partURI"); - - String uriPath = partURI.getPath(); - if (uriPath.length() == 0 - || ((uriPath.length() == 1) && (uriPath.charAt(0) == PackagingURIHelper.FORWARD_SLASH_CHAR))) - throw new InvalidFormatException( - "A part name shall not be empty [M1.1]: " - + partURI.getPath()); - } - - /** - * Throws an exception if the part name has empty segments. [M1.3] - * - * Throws an exception if a segment any characters other than pchar - * characters. [M1.6] - * - * Throws an exception if a segment contain percent-encoded forward slash - * ('/'), or backward slash ('\') characters. [M1.7] - * - * Throws an exception if a segment contain percent-encoded unreserved - * characters. [M1.8] - * - * Throws an exception if the specified part name's segments end with a dot - * ('.') character. [M1.9] - * - * Throws an exception if a segment doesn't include at least one non-dot - * character. [M1.10] - * - * @param partUri - * The part name to check. - * @throws InvalidFormatException - * if the specified URI contain an empty segments or if one the - * segments contained in the part name, ends with a dot ('.') - * character. - */ - private static void throwExceptionIfPartNameHaveInvalidSegments(URI partUri) - throws InvalidFormatException { - if (partUri == null) { - throw new IllegalArgumentException("partUri"); - } - - // Split the URI into several part and analyze each - String[] segments = partUri.toASCIIString().split("/"); - if (segments.length <= 1 || !segments[0].equals("")) - throw new InvalidFormatException( - "A part name shall not have empty segments [M1.3]: " - + partUri.getPath()); - - for (int i = 1; i < segments.length; ++i) { - String seg = segments[i]; - if (seg == null || "".equals(seg)) { - throw new InvalidFormatException( - "A part name shall not have empty segments [M1.3]: " - + partUri.getPath()); - } - - if (seg.endsWith(".")) { - throw new InvalidFormatException( - "A segment shall not end with a dot ('.') character [M1.9]: " - + partUri.getPath()); - } - - if ("".equals(seg.replaceAll("\\\\.", ""))) { - // Normally will never been invoked with the previous - // implementation rule [M1.9] - throw new InvalidFormatException( - "A segment shall include at least one non-dot character. [M1.10]: " - + partUri.getPath()); - } - - // Check for rule M1.6, M1.7, M1.8 - checkPCharCompliance(seg); - } - } - - /** - * Throws an exception if a segment any characters other than pchar - * characters. [M1.6] - * - * Throws an exception if a segment contain percent-encoded forward slash - * ('/'), or backward slash ('\') characters. [M1.7] - * - * Throws an exception if a segment contain percent-encoded unreserved - * characters. [M1.8] - * - * @param segment - * The segment to check - */ - private static void checkPCharCompliance(String segment) - throws InvalidFormatException { - boolean errorFlag; - final int length = segment.length(); - for (int i = 0; i < length; ++i) { - char c = segment.charAt(i); - errorFlag = true; - - /* Check rule M1.6 */ - - // Check for digit or letter - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') - || (c >= '0' && c <= '9')) { - errorFlag = false; - } else { - // Check "-", ".", "_", "~" - for (int j = 0; j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) { - if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) { - errorFlag = false; - break; - } - } - - // Check ":", "@" - for (int j = 0; errorFlag - && j < RFC3986_PCHAR_AUTHORIZED_SUP.length; ++j) { - if (c == RFC3986_PCHAR_AUTHORIZED_SUP[j].charAt(0)) { - errorFlag = false; - } - } - - // Check "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" - for (int j = 0; errorFlag - && j < RFC3986_PCHAR_SUB_DELIMS.length; ++j) { - if (c == RFC3986_PCHAR_SUB_DELIMS[j].charAt(0)) { - errorFlag = false; - } - } - } - - if (errorFlag && c == '%') { - // We certainly found an encoded character, check for length - // now ( '%' HEXDIGIT HEXDIGIT) - if (((length - i) < 2)) { - throw new InvalidFormatException("The segment " + segment - + " contain invalid encoded character !"); - } - - // If not percent encoded character error occur then reset the - // flag -> the character is valid - errorFlag = false; - - // Decode the encoded character - char decodedChar = (char) Integer.parseInt(segment.substring( - i + 1, i + 3), 16); - i += 2; - - /* Check rule M1.7 */ - if (decodedChar == '/' || decodedChar == '\\') - throw new InvalidFormatException( - "A segment shall not contain percent-encoded forward slash ('/'), or backward slash ('\') characters. [M1.7]"); - - /* Check rule M1.8 */ - - // Check for unreserved character like define in RFC3986 - if ((decodedChar >= 'A' && decodedChar <= 'Z') - || (decodedChar >= 'a' && decodedChar <= 'z') - || (decodedChar >= '0' && decodedChar <= '9')) - errorFlag = true; - - // Check for unreserved character "-", ".", "_", "~" - for (int j = 0; !errorFlag - && j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) { - if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) { - errorFlag = true; - break; - } - } - if (errorFlag) - throw new InvalidFormatException( - "A segment shall not contain percent-encoded unreserved characters. [M1.8]"); - } - - if (errorFlag) - throw new InvalidFormatException( - "A segment shall not hold any characters other than pchar characters. [M1.6]"); - } - } - - /** - * Throws an exception if the specified part name doesn't start with a - * forward slash character '/'. [M1.4] - * - * @param partUri - * The part name to check. - * @throws InvalidFormatException - * If the specified part name doesn't start with a forward slash - * character '/'. - */ - private static void throwExceptionIfPartNameNotStartsWithForwardSlashChar( - URI partUri) throws InvalidFormatException { - String uriPath = partUri.getPath(); - if (uriPath.length() > 0 - && uriPath.charAt(0) != PackagingURIHelper.FORWARD_SLASH_CHAR) - throw new InvalidFormatException( - "A part name shall start with a forward slash ('/') character [M1.4]: " - + partUri.getPath()); - } - - /** - * Throws an exception if the specified part name ends with a forwar slash - * character '/'. [M1.5] - * - * @param partUri - * The part name to check. - * @throws InvalidFormatException - * If the specified part name ends with a forwar slash character - * '/'. - */ - private static void throwExceptionIfPartNameEndsWithForwardSlashChar( - URI partUri) throws InvalidFormatException { - String uriPath = partUri.getPath(); - if (uriPath.length() > 0 - && uriPath.charAt(uriPath.length() - 1) == PackagingURIHelper.FORWARD_SLASH_CHAR) - throw new InvalidFormatException( - "A part name shall not have a forward slash as the last character [M1.5]: " - + partUri.getPath()); - } - - /** - * Throws an exception if the specified URI is absolute. - * - * @param partUri - * The URI to check. - * @throws InvalidFormatException - * Throws if the specified URI is absolute. - */ - private static void throwExceptionIfAbsoluteUri(URI partUri) - throws InvalidFormatException { - if (partUri.isAbsolute()) - throw new InvalidFormatException("Absolute URI forbidden: " - + partUri); - } - - /** - * Compare two part names following the rule M1.12 : - * - * Part name equivalence is determined by comparing part names as - * case-insensitive ASCII strings. Packages shall not contain equivalent - * part names and package implementers shall neither create nor recognize - * packages with equivalent part names. [M1.12] - */ - @Override - public int compareTo(PackagePartName other) - { - // compare with natural sort order - return compare(this, other); - } - - - /** - * Retrieves the extension of the part name if any. If there is no extension - * returns an empty String. Example : '/document/content.xml' => 'xml' - * - * @return The extension of the part name. - */ - public String getExtension() { - String fragment = this.partNameURI.getPath(); - if (fragment.length() > 0) { - int i = fragment.lastIndexOf("."); - if (i > -1) - return fragment.substring(i + 1); - } - return ""; - } - - /** - * Get this part name. - * - * @return The name of this part name. - */ - public String getName() { - return this.partNameURI.toASCIIString(); - } - - /** - * Part name equivalence is determined by comparing part names as - * case-insensitive ASCII strings. Packages shall not contain equivalent - * part names and package implementers shall neither create nor recognize - * packages with equivalent part names. [M1.12] - */ - @Override - public boolean equals(Object other) { - if (other instanceof PackagePartName) { - // String.equals() is compatible with our compareTo(), but cheaper - return this.partNameURI.toASCIIString().toLowerCase(Locale.ROOT).equals - ( - ((PackagePartName) other).partNameURI.toASCIIString().toLowerCase(Locale.ROOT) - ); - } else { - return false; - } - } - - @Override - public int hashCode() { - return this.partNameURI.toASCIIString().toLowerCase(Locale.ROOT).hashCode(); - } - - @Override - public String toString() { - return getName(); - } - - /* Getters and setters */ - - /** - * Part name property getter. - * - * @return This part name URI. - */ - public URI getURI() { - return this.partNameURI; - } - - - /** - * A natural sort order for package part names, consistent with the - * requirements of {@code java.util.Comparator}, but simply implemented - * as a static method. - *

        - * For example, this sorts "file10.png" after "file2.png" (comparing the - * numerical portion), but sorts "File10.png" before "file2.png" - * (lexigraphical sort) - * - *

        - * When comparing part names, the rule M1.12 is followed: - * - * Part name equivalence is determined by comparing part names as - * case-insensitive ASCII strings. Packages shall not contain equivalent - * part names and package implementers shall neither create nor recognize - * packages with equivalent part names. [M1.12] - */ - public static int compare(PackagePartName obj1, PackagePartName obj2) - { - // NOTE could also throw a NullPointerException() if desired - if (obj1 == null) - { - // (null) == (null), (null) < (non-null) - return (obj2 == null ? 0 : -1); - } - else if (obj2 == null) - { - // (non-null) > (null) - return 1; - } - - return compare - ( - obj1.getURI().toASCIIString().toLowerCase(Locale.ROOT), - obj2.getURI().toASCIIString().toLowerCase(Locale.ROOT) - ); - } - - - /** - * A natural sort order for strings, consistent with the - * requirements of {@code java.util.Comparator}, but simply implemented - * as a static method. - *

        - * For example, this sorts "file10.png" after "file2.png" (comparing the - * numerical portion), but sorts "File10.png" before "file2.png" - * (lexigraphical sort) - */ - public static int compare(String str1, String str2) - { - if (str1 == null) - { - // (null) == (null), (null) < (non-null) - return (str2 == null ? 0 : -1); - } - else if (str2 == null) - { - // (non-null) > (null) - return 1; - } - - int len1 = str1.length(); - int len2 = str2.length(); - for (int idx1 = 0, idx2 = 0; idx1 < len1 && idx2 < len2; /*nil*/) - { - char c1 = str1.charAt(idx1++); - char c2 = str2.charAt(idx2++); - - if (Character.isDigit(c1) && Character.isDigit(c2)) - { - int beg1 = idx1 - 1; // undo previous increment - while (idx1 < len1 && Character.isDigit(str1.charAt(idx1))) - { - ++idx1; - } - - int beg2 = idx2 - 1; // undo previous increment - while (idx2 < len2 && Character.isDigit(str2.charAt(idx2))) - { - ++idx2; - } - - // note: BigInteger for extra safety - int cmp = new BigInteger(str1.substring(beg1, idx1)).compareTo - ( - new BigInteger(str2.substring(beg2, idx2)) - ); - if (cmp != 0) return cmp; - } - else if (c1 != c2) - { - return (c1 - c2); - } - } - - return (len1 - len2); - } - -} - -/* ************************************************************************** */ diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java deleted file mode 100644 index 3013af435..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java +++ /dev/null @@ -1,227 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.Date; - -import org.apache.poi.openxml4j.util.Nullable; - -/** - * Represents the core properties of an OPC package. - * - * @author Julien Chable - * @version 1.0 - * @see org.apache.poi.openxml4j.opc.OPCPackage - */ -public interface PackageProperties { - - /** - * Dublin Core Terms URI. - */ - public final static String NAMESPACE_DCTERMS = "http://purl.org/dc/terms/"; - - /** - * Dublin Core namespace URI. - */ - public final static String NAMESPACE_DC = "http://purl.org/dc/elements/1.1/"; - - /* Getters and setters */ - - /** - * Set the category of the content of this package. - */ - public abstract Nullable getCategoryProperty(); - - /** - * Set the category of the content of this package. - */ - public abstract void setCategoryProperty(String category); - - /** - * Set the status of the content. - */ - public abstract Nullable getContentStatusProperty(); - - /** - * Get the status of the content. - */ - public abstract void setContentStatusProperty(String contentStatus); - - /** - * Get the type of content represented, generally defined by a specific use - * and intended audience. - */ - public abstract Nullable getContentTypeProperty(); - - /** - * Set the type of content represented, generally defined by a specific use - * and intended audience. - */ - public abstract void setContentTypeProperty(String contentType); - - /** - * Get the date of creation of the resource. - */ - public abstract Nullable getCreatedProperty(); - - /** - * Set the date of creation of the resource. - */ - public abstract void setCreatedProperty(String created); - - /** - * Set the date of creation of the resource. - */ - public abstract void setCreatedProperty(Nullable created); - - /** - * Get the entity primarily responsible for making the content of the - * resource. - */ - public abstract Nullable getCreatorProperty(); - - /** - * Set the entity primarily responsible for making the content of the - * resource. - */ - public abstract void setCreatorProperty(String creator); - - /** - * Get the explanation of the content of the resource. - */ - public abstract Nullable getDescriptionProperty(); - - /** - * Set the explanation of the content of the resource. - */ - public abstract void setDescriptionProperty(String description); - - /** - * Get an unambiguous reference to the resource within a given context. - */ - public abstract Nullable getIdentifierProperty(); - - /** - * Set an unambiguous reference to the resource within a given context. - */ - public abstract void setIdentifierProperty(String identifier); - - /** - * Get a delimited set of keywords to support searching and indexing. This - * is typically a list of terms that are not available elsewhere in the - * properties - */ - public abstract Nullable getKeywordsProperty(); - - /** - * Set a delimited set of keywords to support searching and indexing. This - * is typically a list of terms that are not available elsewhere in the - * properties - */ - public abstract void setKeywordsProperty(String keywords); - - /** - * Get the language of the intellectual content of the resource. - */ - public abstract Nullable getLanguageProperty(); - - /** - * Set the language of the intellectual content of the resource. - */ - public abstract void setLanguageProperty(String language); - - /** - * Get the user who performed the last modification. - */ - public abstract Nullable getLastModifiedByProperty(); - - /** - * Set the user who performed the last modification. - */ - public abstract void setLastModifiedByProperty(String lastModifiedBy); - - /** - * Get the date and time of the last printing. - */ - public abstract Nullable getLastPrintedProperty(); - - /** - * Set the date and time of the last printing. - */ - public abstract void setLastPrintedProperty(String lastPrinted); - - /** - * Set the date and time of the last printing. - */ - public abstract void setLastPrintedProperty(Nullable lastPrinted); - - /** - * Get the date on which the resource was changed. - */ - public abstract Nullable getModifiedProperty(); - - /** - * Set the date on which the resource was changed. - */ - public abstract void setModifiedProperty(String modified); - - /** - * Set the date on which the resource was changed. - */ - public abstract void setModifiedProperty(Nullable modified); - - /** - * Get the revision number. - */ - public abstract Nullable getRevisionProperty(); - - /** - * Set the revision number. - */ - public abstract void setRevisionProperty(String revision); - - /** - * Get the topic of the content of the resource. - */ - public abstract Nullable getSubjectProperty(); - - /** - * Set the topic of the content of the resource. - */ - public abstract void setSubjectProperty(String subject); - - /** - * Get the name given to the resource. - */ - public abstract Nullable getTitleProperty(); - - /** - * Set the name given to the resource. - */ - public abstract void setTitleProperty(String title); - - /** - * Get the version number. - */ - public abstract Nullable getVersionProperty(); - - /** - * Set the version number. - */ - public abstract void setVersionProperty(String version); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java deleted file mode 100644 index 90ee15e29..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java +++ /dev/null @@ -1,227 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -import java.net.URI; -import java.net.URISyntaxException; - -/** - * A part relationship. - * - * @author Julien Chable - * @version 1.0 - */ -public final class PackageRelationship { - - private static URI containerRelationshipPart; - - static { - try { - containerRelationshipPart = new URI("/_rels/.rels"); - } catch (URISyntaxException e) { - // Do nothing - } - } - - /* XML markup */ - - public static final String ID_ATTRIBUTE_NAME = "Id"; - - public static final String RELATIONSHIPS_TAG_NAME = "Relationships"; - - public static final String RELATIONSHIP_TAG_NAME = "Relationship"; - - public static final String TARGET_ATTRIBUTE_NAME = "Target"; - - public static final String TARGET_MODE_ATTRIBUTE_NAME = "TargetMode"; - - public static final String TYPE_ATTRIBUTE_NAME = "Type"; - - /* End XML markup */ - - /** - * Relation id. - */ - private String id; - - /** - * Reference to the package. - */ - private OPCPackage container; - - /** - * Relationship type - */ - private String relationshipType; - - /** - * Part of this relationship source - */ - private PackagePart source; - - /** - * Targeting mode [Internal|External] - */ - private TargetMode targetMode; - - /** - * Target URI - */ - private URI targetUri; - - /** - * Constructor. - * - * @param pkg - * @param sourcePart - * @param targetUri - * @param targetMode - * @param relationshipType - * @param id - */ - public PackageRelationship(OPCPackage pkg, PackagePart sourcePart, - URI targetUri, TargetMode targetMode, String relationshipType, - String id) { - if (pkg == null) - throw new IllegalArgumentException("pkg"); - if (targetUri == null) - throw new IllegalArgumentException("targetUri"); - if (relationshipType == null) - throw new IllegalArgumentException("relationshipType"); - if (id == null) - throw new IllegalArgumentException("id"); - - this.container = pkg; - this.source = sourcePart; - this.targetUri = targetUri; - this.targetMode = targetMode; - this.relationshipType = relationshipType; - this.id = id; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof PackageRelationship)) { - return false; - } - PackageRelationship rel = (PackageRelationship) obj; - return (this.id.equals(rel.id) - && this.relationshipType.equals(rel.relationshipType) - && (rel.source != null ? rel.source.equals(this.source) : true) - && this.targetMode == rel.targetMode && this.targetUri - .equals(rel.targetUri)); - } - - @Override - public int hashCode() { - return this.id.hashCode() - + this.relationshipType.hashCode() - + (this.source == null ? 0 : this.source.hashCode()) - + this.targetMode.hashCode() - + this.targetUri.hashCode(); - } - - /* Getters */ - - public static URI getContainerPartRelationship() { - return containerRelationshipPart; - } - - /** - * @return the container - */ - public OPCPackage getPackage() { - return container; - } - - /** - * @return the id - */ - public String getId() { - return id; - } - - /** - * @return the relationshipType - */ - public String getRelationshipType() { - return relationshipType; - } - - /** - * @return the source - */ - public PackagePart getSource() { - return source; - } - - /** - * - * @return URL of the source part of this relationship - */ - public URI getSourceURI() { - if (source == null) { - return PackagingURIHelper.PACKAGE_ROOT_URI; - } - return source._partName.getURI(); - } - - /** - * @return the targetMode - */ - public TargetMode getTargetMode() { - return targetMode; - } - - /** - * @return the targetUri - */ - public URI getTargetURI() { - // If it's an external target, we don't - // need to apply our normal validation rules - if(targetMode == TargetMode.EXTERNAL) { - return targetUri; - } - - // Internal target - // If it isn't absolute, resolve it relative - // to ourselves - if (!targetUri.toASCIIString().startsWith("/")) { - // So it's a relative part name, try to resolve it - return PackagingURIHelper.resolvePartUri(getSourceURI(), targetUri); - } - return targetUri; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(id == null ? "id=null" : "id=" + id); - sb.append(container == null ? " - container=null" : " - container=" - + container.toString()); - sb.append(relationshipType == null ? " - relationshipType=null" - : " - relationshipType=" + relationshipType); - sb.append(source == null ? " - source=null" : " - source=" - + getSourceURI().toASCIIString()); - sb.append(targetUri == null ? " - target=null" : " - target=" - + getTargetURI().toASCIIString()); - sb.append(targetMode == null ? ",targetMode=null" : ",targetMode=" - + targetMode.toString()); - return sb.toString(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java deleted file mode 100644 index 665c51f6c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java +++ /dev/null @@ -1,447 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.openxml4j.opc; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Locale; -import java.util.TreeMap; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * Represents a collection of PackageRelationship elements that are owned by a - * given PackagePart or the Package. - * - * @author Julien Chable, CDubettier - * @version 0.1 - */ -public final class PackageRelationshipCollection implements - Iterable { - - private static POILogger logger = POILogFactory.getLogger(PackageRelationshipCollection.class); - - /** - * Package relationships ordered by ID. - */ - private TreeMap relationshipsByID; - - /** - * Package relationships ordered by type. - */ - private TreeMap relationshipsByType; - - /** - * This relationshipPart. - */ - private PackagePart relationshipPart; - - /** - * Source part. - */ - private PackagePart sourcePart; - - /** - * This part name. - */ - private PackagePartName partName; - - /** - * Reference to the package. - */ - private OPCPackage container; - - /** - * The ID number of the next rID# to generate, or -1 - * if that is still to be determined. - */ - private int nextRelationshipId = -1; - - /** - * Constructor. - */ - PackageRelationshipCollection() { - relationshipsByID = new TreeMap(); - relationshipsByType = new TreeMap(); - } - - /** - * Copy constructor. - * - * This collection will contain only elements from the specified collection - * for which the type is compatible with the specified relationship type - * filter. - * - * @param coll - * Collection to import. - * @param filter - * Relationship type filter. - */ - public PackageRelationshipCollection(PackageRelationshipCollection coll, - String filter) { - this(); - for (PackageRelationship rel : coll.relationshipsByID.values()) { - if (filter == null || rel.getRelationshipType().equals(filter)) - addRelationship(rel); - } - } - - /** - * Constructor. - */ - public PackageRelationshipCollection(OPCPackage container) - throws InvalidFormatException { - this(container, null); - } - - /** - * Constructor. - * - * @throws InvalidFormatException - * Throws if the format of the content part is invalid. - * - * @throws InvalidOperationException - * Throws if the specified part is a relationship part. - */ - public PackageRelationshipCollection(PackagePart part) - throws InvalidFormatException { - this(part._container, part); - } - - /** - * Constructor. Parse the existing package relationship part if one exists. - * - * @param container - * The parent package. - * @param part - * The part that own this relationships collection. If null - * then this part is considered as the package root. - * @throws InvalidFormatException - * If an error occurs during the parsing of the relatinships - * part fo the specified part. - */ - public PackageRelationshipCollection(OPCPackage container, PackagePart part) - throws InvalidFormatException { - this(); - - if (container == null) - throw new IllegalArgumentException("container"); - - // Check if the specified part is not a relationship part - if (part != null && part.isRelationshipPart()) - throw new IllegalArgumentException("part"); - - this.container = container; - this.sourcePart = part; - this.partName = getRelationshipPartName(part); - if ((container.getPackageAccess() != PackageAccess.WRITE) - && container.containPart(this.partName)) { - relationshipPart = container.getPart(this.partName); - parseRelationshipsPart(relationshipPart); - } - } - - /** - * Get the relationship part name of the specified part. - * - * @param part - * The part . - * @return The relationship part name of the specified part. Be careful, - * only the correct name is returned, this method does not check if - * the part really exist in a package ! - * @throws InvalidOperationException - * Throws if the specified part is a relationship part. - */ - private static PackagePartName getRelationshipPartName(PackagePart part) - throws InvalidOperationException { - PackagePartName partName; - if (part == null) { - partName = PackagingURIHelper.PACKAGE_ROOT_PART_NAME; - } else { - partName = part.getPartName(); - } - return PackagingURIHelper.getRelationshipPartName(partName); - } - - /** - * Add the specified relationship to the collection. - * - * @param relPart - * The relationship to add. - */ - public void addRelationship(PackageRelationship relPart) { - relationshipsByID.put(relPart.getId(), relPart); - relationshipsByType.put(relPart.getRelationshipType(), relPart); - } - - /** - * Add a relationship to the collection. - * - * @param targetUri - * Target URI. - * @param targetMode - * The target mode : INTERNAL or EXTERNAL - * @param relationshipType - * Relationship type. - * @param id - * Relationship ID. - * @return The newly created relationship. - * @see PackageAccess - */ - public PackageRelationship addRelationship(URI targetUri, - TargetMode targetMode, String relationshipType, String id) { - if (id == null) { - // Generate a unique ID is id parameter is null. - if (nextRelationshipId == -1) { - nextRelationshipId = size() + 1; - } - - // Work up until we find a unique number (there could be gaps etc) - do { - id = "rId" + nextRelationshipId++; - } while (relationshipsByID.get(id) != null); - } - - PackageRelationship rel = new PackageRelationship(container, - sourcePart, targetUri, targetMode, relationshipType, id); - relationshipsByID.put(rel.getId(), rel); - relationshipsByType.put(rel.getRelationshipType(), rel); - return rel; - } - - /** - * Remove a relationship by its ID. - * - * @param id - * The relationship ID to remove. - */ - public void removeRelationship(String id) { - if (relationshipsByID != null && relationshipsByType != null) { - PackageRelationship rel = relationshipsByID.get(id); - if (rel != null) { - relationshipsByID.remove(rel.getId()); - relationshipsByType.values().remove(rel); - } - } - } - - /** - * Remove a relationship by its reference. - * - * @param rel - * The relationship to delete. - */ - public void removeRelationship(PackageRelationship rel) { - if (rel == null) - throw new IllegalArgumentException("rel"); - - relationshipsByID.values().remove(rel); - relationshipsByType.values().remove(rel); - } - - /** - * Retrieves a relationship by its index in the collection. - * - * @param index - * Must be a value between [0-relationships_count-1] - */ - public PackageRelationship getRelationship(int index) { - if (index < 0 || index > relationshipsByID.values().size()) - throw new IllegalArgumentException("index"); - - int i = 0; - for (PackageRelationship rel : relationshipsByID.values()) { - if (index == i++) - return rel; - } - - return null; - } - - /** - * Retrieves a package relationship based on its id. - * - * @param id - * ID of the package relationship to retrieve. - * @return The package relationship identified by the specified id. - */ - public PackageRelationship getRelationshipByID(String id) { - return relationshipsByID.get(id); - } - - /** - * Get the numbe rof relationships in the collection. - */ - public int size() { - return relationshipsByID.values().size(); - } - - /** - * Parse the relationship part and add all relationship in this collection. - * - * @param relPart - * The package part to parse. - * @throws InvalidFormatException - * Throws if the relationship part is invalid. - */ - public void parseRelationshipsPart(PackagePart relPart) - throws InvalidFormatException { - try { - logger.log(POILogger.DEBUG, "Parsing relationship: " + relPart.getPartName()); - Document xmlRelationshipsDoc = DocumentHelper.readDocument(relPart.getInputStream()); - - // Browse default types - Element root = xmlRelationshipsDoc.getDocumentElement(); - - // Check OPC compliance M4.1 rule - boolean fCorePropertiesRelationship = false; - - NodeList nodeList = root.getElementsByTagNameNS(PackageNamespaces.RELATIONSHIPS, PackageRelationship.RELATIONSHIP_TAG_NAME); - int nodeCount = nodeList.getLength(); - for (int i = 0; i < nodeCount; i++) { - Element element = (Element)nodeList.item(i); - // Relationship ID - String id = element.getAttribute(PackageRelationship.ID_ATTRIBUTE_NAME); - // Relationship type - String type = element.getAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME); - - /* Check OPC Compliance */ - // Check Rule M4.1 - if (type.equals(PackageRelationshipTypes.CORE_PROPERTIES)) - if (!fCorePropertiesRelationship) - fCorePropertiesRelationship = true; - else - throw new InvalidFormatException( - "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !"); - - /* End OPC Compliance */ - - // TargetMode (default value "Internal") - Attr targetModeAttr = element.getAttributeNode(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME); - TargetMode targetMode = TargetMode.INTERNAL; - if (targetModeAttr != null) { - targetMode = targetModeAttr.getValue().toLowerCase(Locale.ROOT) - .equals("internal") ? TargetMode.INTERNAL - : TargetMode.EXTERNAL; - } - - // Target converted in URI - URI target = PackagingURIHelper.toURI("http://invalid.uri"); // dummy url - String value = element.getAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME); - try { - // when parsing of the given uri fails, we can either - // ignore this relationship, which leads to IllegalStateException - // later on, or use a dummy value and thus enable processing of the - // package - target = PackagingURIHelper.toURI(value); - } catch (URISyntaxException e) { - logger.log(POILogger.ERROR, "Cannot convert " + value - + " in a valid relationship URI-> dummy-URI used", e); - } - addRelationship(target, targetMode, type, id); - } - } catch (Exception e) { - logger.log(POILogger.ERROR, e); - throw new InvalidFormatException(e.getMessage()); - } - } - - /** - * Retrieves all relations with the specified type. - * - * @param typeFilter - * Relationship type filter. If null then all - * relationships are returned. - * @return All relationships of the type specified by the filter. - */ - public PackageRelationshipCollection getRelationships(String typeFilter) { - PackageRelationshipCollection coll = new PackageRelationshipCollection( - this, typeFilter); - return coll; - } - - /** - * Get this collection's iterator. - */ - public Iterator iterator() { - return relationshipsByID.values().iterator(); - } - - /** - * Get an iterator of a collection with all relationship with the specified - * type. - * - * @param typeFilter - * Type filter. - * @return An iterator to a collection containing all relationships with the - * specified type contain in this collection. - */ - public Iterator iterator(String typeFilter) { - ArrayList retArr = new ArrayList(); - for (PackageRelationship rel : relationshipsByID.values()) { - if (rel.getRelationshipType().equals(typeFilter)) - retArr.add(rel); - } - return retArr.iterator(); - } - - /** - * Clear all relationships. - */ - public void clear() { - relationshipsByID.clear(); - relationshipsByType.clear(); - } - - @Override - public String toString() { - String str; - if (relationshipsByID == null) { - str = "relationshipsByID=null"; - } else { - str = relationshipsByID.size() + " relationship(s) = ["; - } - if ((relationshipPart != null) && (relationshipPart._partName != null)) { - str = str + "," + relationshipPart._partName; - } else { - str = str + ",relationshipPart=null"; - } - - // Source of this relationship - if ((sourcePart != null) && (sourcePart._partName != null)) { - str = str + "," + sourcePart._partName; - } else { - str = str + ",sourcePart=null"; - } - if (partName != null) { - str = str + "," + partName; - } else { - str = str + ",uri=null)"; - } - return str + "]"; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java deleted file mode 100644 index 5d9801cd8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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. - */ -public interface PackageRelationshipTypes { - /** - * Core properties relationship type. - * - *

        - * The standard specifies a source relations ship for the Core File Properties part as follows: - * http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties. - *

        - *

        - * Office uses the following source relationship for the Core File Properties part: - * http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties. - *

        - * See 2.1.33 Part 1 Section 15.2.11.1, Core File Properties Part in [MS-OE376].pdf - */ - String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; - - /** - * Core properties relationship type as defiend in ECMA 376. - */ - String CORE_PROPERTIES_ECMA376 = "http://schemas.openxmlformats.org/officedocument/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"; - - /** - * Extended properties relationship type for strict ooxml. - */ - String STRICT_EXTENDED_PROPERTIES = "http://purl.oclc.org/ooxml/officeDocument/relationships/extendedProperties"; - - /** - * Custom properties relationship type. - */ - String CUSTOM_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties"; - - /** - * Core document relationship type. - */ - String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; - - /** - * Core document relationship type for strict ooxml. - */ - String STRICT_CORE_DOCUMENT = "http://purl.oclc.org/ooxml/officeDocument/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"; - - /** - * Hyperlink type. - */ - String HYPERLINK_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; - - /** - * Style type. - */ - String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"; - - /** - * External Link to another Document - */ - String EXTERNAL_LINK_PATH = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath"; - - /** - * Visio 2010 VSDX equivalent of package {@link #CORE_DOCUMENT} - */ - String VISIO_CORE_DOCUMENT = "http://schemas.microsoft.com/visio/2010/relationships/document"; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java deleted file mode 100644 index f44bf7367..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java +++ /dev/null @@ -1,776 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc; - -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.regex.Pattern; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Helper for part and pack URI. - * - * @author Julien Chable, CDubet, Kim Ung - * @version 0.1 - */ -public final class PackagingURIHelper { - private final static POILogger _logger = POILogFactory.getLogger(PackagingURIHelper.class); - - /** - * Package root URI. - */ - private static URI packageRootUri; - - /** - * Extension name of a relationship part. - */ - public static final String RELATIONSHIP_PART_EXTENSION_NAME; - - /** - * Segment name of a relationship part. - */ - public static final String RELATIONSHIP_PART_SEGMENT_NAME; - - /** - * Segment name of the package properties folder. - */ - public static final String PACKAGE_PROPERTIES_SEGMENT_NAME; - - /** - * Core package properties art name. - */ - public static final String PACKAGE_CORE_PROPERTIES_NAME; - - /** - * Forward slash URI separator. - */ - public static final char FORWARD_SLASH_CHAR; - - /** - * Forward slash URI separator. - */ - public static final String FORWARD_SLASH_STRING; - - /** - * Package relationships part URI - */ - public static final URI PACKAGE_RELATIONSHIPS_ROOT_URI; - - /** - * Package relationships part name. - */ - public static final PackagePartName PACKAGE_RELATIONSHIPS_ROOT_PART_NAME; - - /** - * Core properties part URI. - */ - public static final URI CORE_PROPERTIES_URI; - - /** - * Core properties partname. - */ - public static final PackagePartName CORE_PROPERTIES_PART_NAME; - - /** - * Root package URI. - */ - public static final URI PACKAGE_ROOT_URI; - - /** - * Root package part name. - */ - public static final PackagePartName PACKAGE_ROOT_PART_NAME; - - /* Static initialization */ - static { - RELATIONSHIP_PART_SEGMENT_NAME = "_rels"; - RELATIONSHIP_PART_EXTENSION_NAME = ".rels"; - FORWARD_SLASH_CHAR = '/'; - FORWARD_SLASH_STRING = "/"; - PACKAGE_PROPERTIES_SEGMENT_NAME = "docProps"; - PACKAGE_CORE_PROPERTIES_NAME = "core.xml"; - - // Make URI - URI uriPACKAGE_ROOT_URI = null; - URI uriPACKAGE_RELATIONSHIPS_ROOT_URI = null; - URI uriPACKAGE_PROPERTIES_URI = null; - try { - uriPACKAGE_ROOT_URI = new URI("/"); - uriPACKAGE_RELATIONSHIPS_ROOT_URI = new URI(FORWARD_SLASH_CHAR - + RELATIONSHIP_PART_SEGMENT_NAME + FORWARD_SLASH_CHAR - + RELATIONSHIP_PART_EXTENSION_NAME); - packageRootUri = new URI("/"); - uriPACKAGE_PROPERTIES_URI = new URI(FORWARD_SLASH_CHAR - + PACKAGE_PROPERTIES_SEGMENT_NAME + FORWARD_SLASH_CHAR - + PACKAGE_CORE_PROPERTIES_NAME); - } catch (URISyntaxException e) { - // Should never happen in production as all data are fixed - } - PACKAGE_ROOT_URI = uriPACKAGE_ROOT_URI; - PACKAGE_RELATIONSHIPS_ROOT_URI = uriPACKAGE_RELATIONSHIPS_ROOT_URI; - CORE_PROPERTIES_URI = uriPACKAGE_PROPERTIES_URI; - - // Make part name from previous URI - PackagePartName tmpPACKAGE_ROOT_PART_NAME = null; - PackagePartName tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = null; - PackagePartName tmpCORE_PROPERTIES_URI = null; - try { - tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = createPartName(PACKAGE_RELATIONSHIPS_ROOT_URI); - tmpCORE_PROPERTIES_URI = createPartName(CORE_PROPERTIES_URI); - tmpPACKAGE_ROOT_PART_NAME = new PackagePartName(PACKAGE_ROOT_URI, - false); - } catch (InvalidFormatException e) { - // Should never happen in production as all data are fixed - } - PACKAGE_RELATIONSHIPS_ROOT_PART_NAME = tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME; - CORE_PROPERTIES_PART_NAME = tmpCORE_PROPERTIES_URI; - PACKAGE_ROOT_PART_NAME = tmpPACKAGE_ROOT_PART_NAME; - } - - private static final Pattern missingAuthPattern = Pattern.compile("\\w+://"); - - /** - * Gets the URI for the package root. - * - * @return URI of the package root. - */ - public static URI getPackageRootUri() { - return packageRootUri; - } - - /** - * Know if the specified URI is a relationship part name. - * - * @param partUri - * URI to check. - * @return true if the URI false. - */ - public static boolean isRelationshipPartURI(URI partUri) { - if (partUri == null) - throw new IllegalArgumentException("partUri"); - - return partUri.getPath().matches( - ".*" + RELATIONSHIP_PART_SEGMENT_NAME + ".*" - + RELATIONSHIP_PART_EXTENSION_NAME + "$"); - } - - /** - * Get file name from the specified URI. - */ - public static String getFilename(URI uri) { - if (uri != null) { - String path = uri.getPath(); - int len = path.length(); - int num2 = len; - while (--num2 >= 0) { - char ch1 = path.charAt(num2); - if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) - return path.substring(num2 + 1, len); - } - } - return ""; - } - - /** - * Get the file name without the trailing extension. - */ - public static String getFilenameWithoutExtension(URI uri) { - String filename = getFilename(uri); - int dotIndex = filename.lastIndexOf("."); - if (dotIndex == -1) - return filename; - return filename.substring(0, dotIndex); - } - - /** - * Get the directory path from the specified URI. - */ - public static URI getPath(URI uri) { - if (uri != null) { - String path = uri.getPath(); - int len = path.length(); - int num2 = len; - while (--num2 >= 0) { - char ch1 = path.charAt(num2); - if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) { - try { - return new URI(path.substring(0, num2)); - } catch (URISyntaxException e) { - return null; - } - } - } - } - return null; - } - - /** - * Combine two URIs. - * - * @param prefix the prefix URI - * @param suffix the suffix URI - * - * @return the combined URI - */ - public static URI combine(URI prefix, URI suffix) { - URI retUri = null; - try { - retUri = new URI(combine(prefix.getPath(), suffix.getPath())); - } catch (URISyntaxException e) { - throw new IllegalArgumentException( - "Prefix and suffix can't be combine !"); - } - return retUri; - } - - /** - * Combine a string URI with a prefix and a suffix. - */ - public static String combine(String prefix, String suffix) { - if (!prefix.endsWith("" + FORWARD_SLASH_CHAR) - && !suffix.startsWith("" + FORWARD_SLASH_CHAR)) - return prefix + FORWARD_SLASH_CHAR + suffix; - else if ((!prefix.endsWith("" + FORWARD_SLASH_CHAR) - && suffix.startsWith("" + FORWARD_SLASH_CHAR) || (prefix - .endsWith("" + FORWARD_SLASH_CHAR) && !suffix.startsWith("" - + FORWARD_SLASH_CHAR)))) - return prefix + suffix; - else - return ""; - } - - /** - * Fully relativize the source part URI against the target part URI. - * - * @param sourceURI - * The source part URI. - * @param targetURI - * The target part URI. - * @param msCompatible if true then remove leading slash from the relativized URI. - * This flag violates [M1.4]: A part name shall start with a forward slash ('/') character, but - * allows generating URIs compatible with MS Office and OpenOffice. - * @return A fully relativize part name URI ('word/media/image1.gif', - * '/word/document.xml' => 'media/image1.gif') else - * null. - */ - public static URI relativizeURI(URI sourceURI, URI targetURI, boolean msCompatible) { - StringBuilder retVal = new StringBuilder(); - String[] segmentsSource = sourceURI.getPath().split("/", -1); - String[] segmentsTarget = targetURI.getPath().split("/", -1); - - // If the source URI is empty - if (segmentsSource.length == 0) { - throw new IllegalArgumentException( - "Can't relativize an empty source URI !"); - } - - // If target URI is empty - if (segmentsTarget.length == 0) { - throw new IllegalArgumentException( - "Can't relativize an empty target URI !"); - } - - // If the source is the root, then the relativized - // form must actually be an absolute URI - if(sourceURI.toString().equals("/")) { - String path = targetURI.getPath(); - if(msCompatible && path.length() > 0 && path.charAt(0) == '/') { - try { - targetURI = new URI(path.substring(1)); - } catch (Exception e) { - _logger.log(POILogger.WARN, e); - return null; - } - } - return targetURI; - } - - - // Relativize the source URI against the target URI. - // First up, figure out how many steps along we can go - // and still have them be the same - int segmentsTheSame = 0; - for (int i = 0; i < segmentsSource.length && i < segmentsTarget.length; i++) { - if (segmentsSource[i].equals(segmentsTarget[i])) { - // Match so far, good - segmentsTheSame++; - } else { - break; - } - } - - // If we didn't have a good match or at least except a first empty element - if ((segmentsTheSame == 0 || segmentsTheSame == 1) && - segmentsSource[0].equals("") && segmentsTarget[0].equals("")) { - for (int i = 0; i < segmentsSource.length - 2; i++) { - retVal.append("../"); - } - for (int i = 0; i < segmentsTarget.length; i++) { - if (segmentsTarget[i].equals("")) - continue; - retVal.append(segmentsTarget[i]); - if (i != segmentsTarget.length - 1) - retVal.append("/"); - } - - try { - return new URI(retVal.toString()); - } catch (Exception e) { - _logger.log(POILogger.WARN, e); - return null; - } - } - - // Special case for where the two are the same - if (segmentsTheSame == segmentsSource.length - && segmentsTheSame == segmentsTarget.length) { - if(sourceURI.equals(targetURI)){ - // if source and target are the same they should be resolved to the last segment, - // Example: if a slide references itself, e.g. the source URI is - // "/ppt/slides/slide1.xml" and the targetURI is "slide1.xml" then - // this it should be relativized as "slide1.xml", i.e. the last segment. - retVal.append(segmentsSource[segmentsSource.length - 1]); - } else { - retVal.append(""); - } - - } else { - // Matched for so long, but no more - - // Do we need to go up a directory or two from - // the source to get here? - // (If it's all the way up, then don't bother!) - if (segmentsTheSame == 1) { - retVal.append("/"); - } else { - for (int j = segmentsTheSame; j < segmentsSource.length - 1; j++) { - retVal.append("../"); - } - } - - // Now go from here on down - for (int j = segmentsTheSame; j < segmentsTarget.length; j++) { - if (retVal.length() > 0 - && retVal.charAt(retVal.length() - 1) != '/') { - retVal.append("/"); - } - retVal.append(segmentsTarget[j]); - } - } - - // if the target had a fragment then append it to the result - String fragment = targetURI.getRawFragment(); - if (fragment != null) { - retVal.append("#").append(fragment); - } - - try { - return new URI(retVal.toString()); - } catch (Exception e) { - _logger.log(POILogger.WARN, e); - return null; - } - } - - /** - * Fully relativize the source part URI against the target part URI. - * - * @param sourceURI - * The source part URI. - * @param targetURI - * The target part URI. - * @return A fully relativize part name URI ('word/media/image1.gif', - * '/word/document.xml' => 'media/image1.gif') else - * null. - */ - public static URI relativizeURI(URI sourceURI, URI targetURI) { - return relativizeURI(sourceURI, targetURI, false); - } - - /** - * Resolve a source uri against a target. - * - * @param sourcePartUri - * The source URI. - * @param targetUri - * The target URI. - * @return The resolved URI. - */ - public static URI resolvePartUri(URI sourcePartUri, URI targetUri) { - if (sourcePartUri == null || sourcePartUri.isAbsolute()) { - throw new IllegalArgumentException("sourcePartUri invalid - " - + sourcePartUri); - } - - if (targetUri == null || targetUri.isAbsolute()) { - throw new IllegalArgumentException("targetUri invalid - " - + targetUri); - } - - return sourcePartUri.resolve(targetUri); - } - - /** - * Get URI from a string path. - */ - public static URI getURIFromPath(String path) { - URI retUri; - try { - retUri = toURI(path); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("path"); - } - return retUri; - } - - /** - * Get the source part URI from a specified relationships part. - * - * @param relationshipPartUri - * The relationship part use to retrieve the source part. - * @return The source part URI from the specified relationships part. - */ - public static URI getSourcePartUriFromRelationshipPartUri( - URI relationshipPartUri) { - if (relationshipPartUri == null) - throw new IllegalArgumentException( - "Must not be null"); - - if (!isRelationshipPartURI(relationshipPartUri)) - throw new IllegalArgumentException( - "Must be a relationship part"); - - if (relationshipPartUri.compareTo(PACKAGE_RELATIONSHIPS_ROOT_URI) == 0) - return PACKAGE_ROOT_URI; - - String filename = relationshipPartUri.getPath(); - String filenameWithoutExtension = getFilenameWithoutExtension(relationshipPartUri); - filename = filename - .substring(0, ((filename.length() - filenameWithoutExtension - .length()) - RELATIONSHIP_PART_EXTENSION_NAME.length())); - filename = filename.substring(0, filename.length() - - RELATIONSHIP_PART_SEGMENT_NAME.length() - 1); - filename = combine(filename, filenameWithoutExtension); - return getURIFromPath(filename); - } - - /** - * Create an OPC compliant part name by throwing an exception if the URI is - * not valid. - * - * @param partUri - * The part name URI to validate. - * @return A valid part name object, else null. - * @throws InvalidFormatException - * Throws if the specified URI is not OPC compliant. - */ - public static PackagePartName createPartName(URI partUri) - throws InvalidFormatException { - if (partUri == null) - throw new IllegalArgumentException("partName"); - - return new PackagePartName(partUri, true); - } - - /** - * Create an OPC compliant part name. - * - * @param partName - * The part name to validate. - * @return The correspondant part name if valid, else null. - * @throws InvalidFormatException - * Throws if the specified part name is not OPC compliant. - * @see #createPartName(URI) - */ - public static PackagePartName createPartName(String partName) - throws InvalidFormatException { - URI partNameURI; - try { - partNameURI = toURI(partName); - } catch (URISyntaxException e) { - throw new InvalidFormatException(e.getMessage()); - } - return createPartName(partNameURI); - } - - /** - * Create an OPC compliant part name by resolving it using a base part. - * - * @param partName - * The part name to validate. - * @param relativePart - * The relative base part. - * @return The correspondant part name if valid, else null. - * @throws InvalidFormatException - * Throws if the specified part name is not OPC compliant. - * @see #createPartName(URI) - */ - public static PackagePartName createPartName(String partName, - PackagePart relativePart) throws InvalidFormatException { - URI newPartNameURI; - try { - newPartNameURI = resolvePartUri( - relativePart.getPartName().getURI(), new URI(partName)); - } catch (URISyntaxException e) { - throw new InvalidFormatException(e.getMessage()); - } - return createPartName(newPartNameURI); - } - - /** - * Create an OPC compliant part name by resolving it using a base part. - * - * @param partName - * The part name URI to validate. - * @param relativePart - * The relative base part. - * @return The correspondant part name if valid, else null. - * @throws InvalidFormatException - * Throws if the specified part name is not OPC compliant. - * @see #createPartName(URI) - */ - public static PackagePartName createPartName(URI partName, - PackagePart relativePart) throws InvalidFormatException { - URI newPartNameURI = resolvePartUri( - relativePart.getPartName().getURI(), partName); - return createPartName(newPartNameURI); - } - - /** - * Validate a part URI by returning a boolean. - * ([M1.1],[M1.3],[M1.4],[M1.5],[M1.6]) - * - * (OPC Specifications 8.1.1 Part names) : - * - * Part Name Syntax - * - * The part name grammar is defined as follows: - * - * part_name = 1*( "/" segment ) - * - * segment = 1*( pchar ) - * - * - * (pchar is defined in RFC 3986) - * - * @param partUri - * The URI to validate. - * @return true if the URI is valid to the OPC Specifications, else - * false - * - * @see #createPartName(URI) - */ - public static boolean isValidPartName(URI partUri) { - if (partUri == null) - throw new IllegalArgumentException("partUri"); - - try { - createPartName(partUri); - return true; - } catch (Exception e) { - return false; - } - } - - /** - * Decode a URI by converting all percent encoded character into a String - * character. - * - * @param uri - * The URI to decode. - * @return The specified URI in a String with converted percent encoded - * characters. - */ - public static String decodeURI(URI uri) { - StringBuffer retVal = new StringBuffer(); - String uriStr = uri.toASCIIString(); - char c; - final int length = uriStr.length(); - for (int i = 0; i < length; ++i) { - c = uriStr.charAt(i); - if (c == '%') { - // We certainly found an encoded character, check for length - // now ( '%' HEXDIGIT HEXDIGIT) - if (((length - i) < 2)) { - throw new IllegalArgumentException("The uri " + uriStr - + " contain invalid encoded character !"); - } - - // Decode the encoded character - char decodedChar = (char) Integer.parseInt(uriStr.substring( - i + 1, i + 3), 16); - retVal.append(decodedChar); - i += 2; - continue; - } - retVal.append(c); - } - return retVal.toString(); - } - - /** - * Build a part name where the relationship should be stored ((ex - * /word/document.xml -> /word/_rels/document.xml.rels) - * - * @param partName - * Source part URI - * @return the full path (as URI) of the relation file - * @throws InvalidOperationException - * Throws if the specified URI is a relationshp part. - */ - public static PackagePartName getRelationshipPartName( - PackagePartName partName) { - if (partName == null) - throw new IllegalArgumentException("partName"); - - if (PackagingURIHelper.PACKAGE_ROOT_URI.getPath().equals( - partName.getURI().getPath()) ) - return PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME; - - if (partName.isRelationshipPartURI()) - throw new InvalidOperationException("Can't be a relationship part"); - - String fullPath = partName.getURI().getPath(); - String filename = getFilename(partName.getURI()); - fullPath = fullPath.substring(0, fullPath.length() - filename.length()); - fullPath = combine(fullPath, - PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME); - fullPath = combine(fullPath, filename); - fullPath = fullPath - + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME; - - PackagePartName retPartName; - try { - retPartName = createPartName(fullPath); - } catch (InvalidFormatException e) { - // Should never happen in production as all data are fixed but in - // case of return null: - return null; - } - return retPartName; - } - - /** - * Convert a string to {@link java.net.URI} - * - * If part name is not a valid URI, it is resolved as follows: - *

        - * 1. Percent-encode each open bracket ([) and close bracket (]). - * 2. Percent-encode each percent (%) character that is not followed by a hexadecimal notation of an octet value. - * 3. Un-percent-encode each percent-encoded unreserved character. - * 4. Un-percent-encode each forward slash (/) and back slash (\). - * 5. Convert all back slashes to forward slashes. - * 6. If present in a segment containing non-dot (?.?) characters, remove trailing dot (?.?) characters from each segment. - * 7. Replace each occurrence of multiple consecutive forward slashes (/) with a single forward slash. - * 8. If a single trailing forward slash (/) is present, remove that trailing forward slash. - * 9. Remove complete segments that consist of three or more dots. - * 10. Resolve the relative reference against the base URI of the part holding the Unicode string, as it is defined - * in ?5.2 of RFC 3986. The path component of the resulting absolute URI is the part name. - *

        - * - * @param value the string to be parsed into a URI - * @return the resolved part name that should be OK to construct a URI - * - * TODO YK: for now this method does only (5). Finish the rest. - */ - public static URI toURI(String value) throws URISyntaxException { - //5. Convert all back slashes to forward slashes - if (value.indexOf("\\") != -1) { - value = value.replace('\\', '/'); - } - - // URI fragemnts (those starting with '#') are not encoded - // and may contain white spaces and raw unicode characters - int fragmentIdx = value.indexOf('#'); - if(fragmentIdx != -1){ - String path = value.substring(0, fragmentIdx); - String fragment = value.substring(fragmentIdx + 1); - - value = path + "#" + encode(fragment); - } - - // trailing white spaces must be url-encoded, see Bugzilla 53282 - if(value.length() > 0 ){ - StringBuilder b = new StringBuilder(); - int idx = value.length() - 1; - for(; idx >= 0; idx--){ - char c = value.charAt(idx); - if(Character.isWhitespace(c) || c == '\u00A0') { - b.append(c); - } else { - break; - } - } - if(b.length() > 0){ - value = value.substring(0, idx+1) + encode(b.reverse().toString()); - } - } - - // MS Office can insert URIs with missing authority, e.g. "http://" or "javascript://" - // append a forward slash to avoid parse exception - if(missingAuthPattern.matcher(value).matches()){ - value += "/"; - } - return new URI(value); - } - - /** - * percent-encode white spaces and characters above 0x80. - *

        - * Examples: - * 'Apache POI' --> 'Apache%20POI' - * 'Apache\u0410POI' --> 'Apache%04%10POI' - * - * @param s the string to encode - * @return the encoded string - */ - public static String encode(String s) { - int n = s.length(); - if (n == 0) return s; - - ByteBuffer bb = ByteBuffer.wrap(s.getBytes(Charset.forName("UTF-8"))); - StringBuilder sb = new StringBuilder(); - while (bb.hasRemaining()) { - int b = bb.get() & 0xff; - if (isUnsafe(b)) { - sb.append('%'); - sb.append(hexDigits[(b >> 4) & 0x0F]); - sb.append(hexDigits[(b >> 0) & 0x0F]); - } else { - sb.append((char)b); - } - } - return sb.toString(); - } - - private final static char[] hexDigits = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - - private static boolean isUnsafe(int ch) { - return ch > 0x80 || Character.isWhitespace(ch); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java deleted file mode 100644 index 87c424df5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; - -public interface RelationshipSource { - - /** - * Add a relationship to a part (except relationships part). - * - * @param targetPartName - * Name of the target part. This one must be relative to the - * source root directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - */ - public abstract PackageRelationship addRelationship( - PackagePartName targetPartName, TargetMode targetMode, - String relationshipType); - - /** - * Add a relationship to a part (except relationships part). - *

        - * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - *

        - * @param targetPartName - * Name of the target part. This one must be relative to the - * source root directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * - * @throws InvalidFormatException - * If the URI point to a relationship part URI. - */ - public abstract PackageRelationship addRelationship( - PackagePartName targetPartName, TargetMode targetMode, - String relationshipType, String id); - - /** - * Adds an external relationship to a part - * (except relationships part). - * - * The targets of external relationships are not - * subject to the same validity checks that internal - * ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target External target of the relationship - * @param relationshipType Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, java.lang.String) - */ - public PackageRelationship addExternalRelationship(String target, String relationshipType); - - /** - * Adds an external relationship to a part - * (except relationships part). - * - * The targets of external relationships are not - * subject to the same validity checks that internal - * ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target External target of the relationship - * @param relationshipType Type of relationship. - * @param id Relationship unique id. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, java.lang.String) - */ - public PackageRelationship addExternalRelationship(String target, String relationshipType, String id); - - /** - * Delete all the relationships attached to this. - */ - public abstract void clearRelationships(); - - /** - * Delete the relationship specified by its id. - * - * @param id - * The ID identified the part to delete. - */ - public abstract void removeRelationship(String id); - - /** - * Retrieve all the relationships attached to this. - * - * @return This part's relationships. - * @throws OpenXML4JException - */ - public abstract PackageRelationshipCollection getRelationships() - throws InvalidFormatException, OpenXML4JException; - - /** - * Retrieves a package relationship from its id. - * - * @param id - * ID of the package relationship to retrieve. - * @return The package relationship - */ - public abstract PackageRelationship getRelationship(String id); - - /** - * Retrieve all relationships attached to this part which have the specified - * type. - * - * @param relationshipType - * Relationship type filter. - * @return All relationships from this part that have the specified type. - * @throws InvalidFormatException - * If an error occurs while parsing the part. - * @throws InvalidOperationException - * If the package is open in write only mode. - */ - public abstract PackageRelationshipCollection getRelationshipsByType( - String relationshipType) throws InvalidFormatException, - IllegalArgumentException, OpenXML4JException; - - /** - * Knows if the part have any relationships. - * - * @return true if the part have at least one relationship else - * false. - */ - public abstract boolean hasRelationships(); - - /** - * Checks if the specified relationship is part of this package part. - * - * @param rel - * The relationship to check. - * @return true if the specified relationship exists in this part, - * else returns false - */ - public abstract boolean isRelationshipExists(PackageRelationship rel); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java deleted file mode 100644 index 860d71159..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; - -public final class StreamHelper { - - private StreamHelper() { - // Do nothing - } - - private static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); - - private static synchronized Transformer getIdentityTransformer() throws TransformerException { - return transformerFactory.newTransformer(); - } - - /** - * Save the document object in the specified output stream. - * - * @param xmlContent - * The XML document. - * @param outStream - * The OutputStream in which the XML document will be written. - * @return true if the xml is successfully written in the stream, - * else false. - */ - public static boolean saveXmlInStream(Document xmlContent, - OutputStream outStream) { - try { - Transformer trans = getIdentityTransformer(); - Source xmlSource = new DOMSource(xmlContent); - // prevent close of stream by transformer: - Result outputTarget = new StreamResult(new FilterOutputStream( - outStream) { - @Override - public void write(byte b[], int off, int len) - throws IOException { - out.write(b, off, len); - } - - @Override - public void close() throws IOException { - out.flush(); // only flush, don't close! - } - }); - trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - trans.setOutputProperty(OutputKeys.INDENT, "yes"); - trans.setOutputProperty(OutputKeys.STANDALONE, "yes"); - trans.transform(xmlSource, outputTarget); - } catch (TransformerException e) { - return false; - } - return true; - } - - /** - * Copy the input stream into the output stream. - * - * @param inStream - * The source stream. - * @param outStream - * The destination stream. - * @return true if the operation succeed, else return false. - */ - public static boolean copyStream(InputStream inStream, OutputStream outStream) { - try { - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = inStream.read(buffer)) >= 0) { - outStream.write(buffer, 0, bytesRead); - } - } catch (Exception e) { - return false; - } - return true; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java deleted file mode 100644 index 59f45f538..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 part that is inside the package. */ - INTERNAL, - /** The relationship references a resource that is external to the package. */ - EXTERNAL -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java deleted file mode 100644 index 33333c3c5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ /dev/null @@ -1,616 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.FileInputStream; -import java.io.FileNotFoundException; -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.ZipOutputStream; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; -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.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.openxml4j.util.ZipSecureFile.ThresholdInputStream; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; - -/** - * Physical zip package. - */ -public final class ZipPackage extends OPCPackage { - private static final String MIMETYPE = "mimetype"; - private static final String SETTINGS_XML = "settings.xml"; - - private static final 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, empty ZipPackage. - */ - public ZipPackage() { - super(defaultPackageAccess); - this.zipArchive = null; - - try { - this.contentTypeManager = new ZipContentTypeManager(null, this); - } catch (InvalidFormatException e) { - logger.log(POILogger.WARN,"Could not parse ZipPackage", e); - } - } - - /** - * Constructor. Opens a Zip based Open XML document from - * an InputStream. - * - * @param in - * Zip input stream to load. - * @param access - * The package access mode. - * @throws IllegalArgumentException - * If the specified input stream not an instance of - * ZipInputStream. - * @throws IOException - * if input stream cannot be opened, read, or closed - */ - ZipPackage(InputStream in, PackageAccess access) throws IOException { - super(access); - ThresholdInputStream zis = ZipHelper.openZipStream(in); - try { - this.zipArchive = new ZipInputStreamZipEntrySource(zis); - } catch (final IOException e) { - try { - zis.close(); - } catch (final IOException e2) { - throw new IOException("Failed to close zip input stream while cleaning up. " + e.getMessage(), e2); - } - throw new IOException("Failed to read zip entry source", e); - } - } - - /** - * Constructor. Opens a Zip based Open XML document from a file. - * - * @param path - * The path of the file to open or create. - * @param access - * The package access mode. - * @throws InvalidOperationException - */ - ZipPackage(String path, PackageAccess access) throws InvalidOperationException { - this(new File(path), access); - } - - /** - * Constructor. Opens a Zip based Open XML document from a File. - * - * @param file - * The file to open or create. - * @param access - * The package access mode. - * @throws InvalidOperationException - */ - ZipPackage(File file, PackageAccess access) throws InvalidOperationException { - super(access); - - ZipEntrySource ze; - try { - final ZipFile zipFile = ZipHelper.openZipFile(file); - ze = new ZipFileZipEntrySource(zipFile); - } catch (IOException e) { - // probably not happening with write access - not sure how to handle the default read-write access ... - if (access == PackageAccess.WRITE) { - throw new InvalidOperationException("Can't open the specified file: '" + file + "'", e); - } - logger.log(POILogger.ERROR, "Error in zip file "+file+" - falling back to stream processing (i.e. ignoring zip central directory)"); - ze = openZipEntrySourceStream(file); - } - this.zipArchive = ze; - } - - private static ZipEntrySource openZipEntrySourceStream(File file) throws InvalidOperationException { - final FileInputStream fis; - // Acquire a resource that is needed to read the next level of openZipEntrySourceStream - try { - // open the file input stream - fis = new FileInputStream(file); - } catch (final FileNotFoundException e) { - // If the source cannot be acquired, abort (no resources to free at this level) - throw new InvalidOperationException("Can't open the specified file input stream from file: '" + file + "'", e); - } - - // If an error occurs while reading the next level of openZipEntrySourceStream, free the acquired resource - try { - // read from the file input stream - return openZipEntrySourceStream(fis); - } catch (final Exception e) { - try { - // abort: close the file input stream - fis.close(); - } catch (final IOException e2) { - throw new InvalidOperationException("Could not close the specified file input stream from file: '" + file + "'", e2); - } - throw new InvalidOperationException("Failed to read the file input stream from file: '" + file + "'", e); - } - } - - private static ZipEntrySource openZipEntrySourceStream(FileInputStream fis) throws InvalidOperationException { - final ThresholdInputStream zis; - // Acquire a resource that is needed to read the next level of openZipEntrySourceStream - try { - // open the zip input stream - zis = ZipHelper.openZipStream(fis); - } catch (final IOException e) { - // If the source cannot be acquired, abort (no resources to free at this level) - throw new InvalidOperationException("Could not open the file input stream", e); - } - - // If an error occurs while reading the next level of openZipEntrySourceStream, free the acquired resource - try { - // read from the zip input stream - return openZipEntrySourceStream(zis); - } catch (final Exception e) { - try { - // abort: close the zip input stream - zis.close(); - } catch (final IOException e2) { - throw new InvalidOperationException("Failed to read the zip entry source stream and could not close the zip input stream", e2); - } - throw new InvalidOperationException("Failed to read the zip entry source stream", e); - } - } - - private static ZipEntrySource openZipEntrySourceStream(ThresholdInputStream zis) throws InvalidOperationException { - // Acquire the final level resource. If this is acquired successfully, the zip package was read successfully from the input stream - try { - // open the zip entry source stream - return new ZipInputStreamZipEntrySource(zis); - } catch (IOException e) { - throw new InvalidOperationException("Could not open the specified zip entry source stream", e); - } - } - - /** - * Constructor. Opens a Zip based Open XML document from - * a custom ZipEntrySource, typically an open archive - * from another system - * - * @param zipEntry - * Zip data to load. - * @param access - * The package access mode. - */ - ZipPackage(ZipEntrySource zipEntry, PackageAccess access) { - super(access); - this.zipArchive = zipEntry; - } - - /** - * 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 entries = this.zipArchive.getEntries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - if (entry.getName().equalsIgnoreCase( - ContentTypeManager.CONTENT_TYPES_PART_NAME)) { - try { - this.contentTypeManager = new ZipContentTypeManager( - getZipArchive().getInputStream(entry), this); - } catch (IOException e) { - throw new InvalidFormatException(e.getMessage(), e); - } - break; - } - } - - // At this point, we should have loaded the content type part - if (this.contentTypeManager == null) { - // Is it a different Zip-based format? - int numEntries = 0; - boolean hasMimetype = false; - boolean hasSettingsXML = false; - entries = this.zipArchive.getEntries(); - while (entries.hasMoreElements()) { - final ZipEntry entry = entries.nextElement(); - final String name = entry.getName(); - if (MIMETYPE.equals(name)) { - hasMimetype = true; - } - if (SETTINGS_XML.equals(name)) { - hasSettingsXML = true; - } - numEntries++; - } - if (hasMimetype && hasSettingsXML) { - throw new ODFNotOfficeXmlFileException( - "The supplied data appears to be in ODF (Open Document) Format. " + - "Formats like these (eg ODS, ODP) are not supported, try Apache ODFToolkit"); - } - if (numEntries == 0) { - throw new NotOfficeXmlFileException( - "No valid entries or contents found, this is not a valid OOXML " + - "(Office Open XML) file"); - } - - // Fallback exception - 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 { - PackagePart part = new ZipPackagePart(this, entry, partName, contentType); - partList.put(partName, part); - } catch (InvalidOperationException e) { - throw new InvalidFormatException(e.getMessage(), e); - } - } - } - - // 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 { - PackagePart part = new ZipPackagePart(this, entry, partName, contentType); - partList.put(partName, part); - } catch (InvalidOperationException e) { - throw new InvalidFormatException(e.getMessage(), e); - } - } 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().equalsIgnoreCase( - 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.", e); - 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 null. - */ - @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) { - logger.log(POILogger.WARN, 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 = TempFile.createTempFile( - generateTempFileName(FileHelper - .getDirectory(targetFile)), ".tmp"); - - // Save the final package to a temporary file - try { - save(tempFile); - } finally { - try { - // Close the current zip file, so we can - // overwrite it on all platforms - this.zipArchive.close(); - // Copy the new file over the old one - 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(); - - final ZipOutputStream zos; - 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 && - this.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES_ECMA376).size() == 0 ) { - logger.log(POILogger.DEBUG,"Save core properties part"); - - // Ensure that core properties are added if missing - getPackageProperties(); - // Add core properties to part list ... - addPackagePart(this.packageProperties); - // ... 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 (OpenXML4JRuntimeException e) { - // no need to wrap this type of Exception - throw e; - } catch (Exception e) { - throw new OpenXML4JRuntimeException( - "Fail to save: an error occurs while saving the package : " - + e.getMessage(), e); - } - } - - /** - * Get the zip archive - * - * @return The zip archive. - */ - public ZipEntrySource getZipArchive() { - return zipArchive; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackagePart.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackagePart.java deleted file mode 100644 index 58bbbfe22..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackagePart.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.ZipEntry; - -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.marshallers.ZipPartMarshaller; -import org.apache.poi.util.NotImplemented; - -/** - * Zip implementation of a PackagePart. - * - * @author Julien Chable - * @version 1.0 - * @see PackagePart - */ -public class ZipPackagePart extends PackagePart { - - /** - * The zip entry corresponding to this part. - */ - private ZipEntry zipEntry; - - /** - * Constructor. - * - * @param container - * The container package. - * @param partName - * Part name. - * @param contentType - * Content type. - * @throws InvalidFormatException - * Throws if the content of this part invalid. - */ - public ZipPackagePart(OPCPackage container, PackagePartName partName, - String contentType) throws InvalidFormatException { - super(container, partName, contentType); - } - - /** - * Constructor. - * - * @param container - * The container package. - * @param zipEntry - * The zip entry corresponding to this part. - * @param partName - * The part name. - * @param contentType - * Content type. - * @throws InvalidFormatException - * Throws if the content of this part is invalid. - */ - public ZipPackagePart(OPCPackage container, ZipEntry zipEntry, - PackagePartName partName, String contentType) - throws InvalidFormatException { - super(container, partName, contentType); - this.zipEntry = zipEntry; - } - - /** - * Get the zip entry of this part. - * - * @return The zip entry in the zip structure coresponding to this part. - */ - public ZipEntry getZipArchive() { - return zipEntry; - } - - /** - * Implementation of the getInputStream() which return the inputStream of - * this part zip entry. - * - * @return Input stream of this part zip entry. - */ - @Override - protected InputStream getInputStreamImpl() throws IOException { - // We use the getInputStream() method from java.util.zip.ZipFile - // class which return an InputStream to this part zip entry. - return ((ZipPackage) _container).getZipArchive() - .getInputStream(zipEntry); - } - - /** - * Implementation of the getOutputStream(). Return null. Normally - * will never be called since the MemoryPackage is use instead. - * - * @return null - */ - @Override - protected OutputStream getOutputStreamImpl() { - return null; - } - - @Override - public long getSize() { - return zipEntry.getSize(); - } - - @Override - public boolean save(OutputStream os) throws OpenXML4JException { - return new ZipPartMarshaller().marshall(this, os); - } - - @Override - @NotImplemented - public boolean load(InputStream ios) { - throw new InvalidOperationException("Method not implemented !"); - } - - @Override - @NotImplemented - public void close() { - throw new InvalidOperationException("Method not implemented !"); - } - - @Override - @NotImplemented - public void flush() { - throw new InvalidOperationException("Method not implemented !"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java deleted file mode 100644 index a56e0cdf3..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java +++ /dev/null @@ -1,264 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -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) - *

        - * media-type = type "/" subtype *( ";" parameter ) type = token
        - * subtype = token
        - *

        - * 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. - *

        - * 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. - *

        - * @author Julien Chable - * @version 0.1 - * - * @see http://www.ietf.org/rfc/rfc2045.txt - * @see http://www.ietf.org/rfc/rfc2616.txt - */ -public final class ContentType { - - /** - * Type in Type/Subtype. - */ - private final String type; - - /** - * Subtype - */ - private final String subType; - - /** - * Parameters - */ - private final Map parameters; - - /** - * Media type compiled pattern, without parameters - */ - private final static Pattern patternTypeSubType; - /** - * Media type compiled pattern, with parameters. - */ - private final static Pattern patternTypeSubTypeParams; - /** - * Pattern to match on just the parameters part, to work - * around the Java Regexp group capture behaviour - */ - private final static Pattern patternParams; - - static { - /* - * token = 1* - * - * separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | - * <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT - * - * CTL = - * - * CHAR = - */ - String token = "[\\x21-\\x7E&&[^\\(\\)<>@,;:\\\\/\"\\[\\]\\?={}\\x20\\x09]]"; - - /* - * parameter = attribute "=" value - * - * attribute = token - * - * value = token | quoted-string - */ - 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 = - * - * TEXT = - * - * LWS = [CRLF] 1*( SP | HT ) - * - * CR = - * - * LF = - * - * SP = - * - * HT = - * - * quoted-pair = "\" CHAR - */ - - patternTypeSubType = Pattern.compile("^(" + token + "+)/(" + - token + "+)$"); - patternTypeSubTypeParams = Pattern.compile("^(" + token + "+)/(" + - token + "+)(;" + parameter + ")*$"); - patternParams = Pattern.compile(";" + parameter); - } - - /** - * 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 { - Matcher mMediaType = patternTypeSubType.matcher(contentType); - if (!mMediaType.matches()) { - // How about with parameters? - mMediaType = patternTypeSubTypeParams.matcher(contentType); - } - 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 HashMap(); - // Java RegExps are unhelpful, and won't do multiple group captures - // See http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#cg - if (mMediaType.groupCount() >= 5) { - Matcher mParams = patternParams.matcher(contentType.substring(mMediaType.end(2))); - while (mParams.find()) { - this.parameters.put(mParams.group(1), mParams.group(2)); - } - } - } else { - // missing media type and subtype - this.type = ""; - this.subType = ""; - this.parameters = Collections.emptyMap(); - } - } - - /** - * Returns the content type as a string, including parameters - */ - @Override - public final String toString() { - return toString(true); - } - - public final String toString(boolean withParameters) { - StringBuffer retVal = new StringBuffer(); - retVal.append(this.getType()); - retVal.append("/"); - retVal.append(this.getSubType()); - - if (withParameters) { - for (Entry me : parameters.entrySet()) { - retVal.append(";"); - retVal.append(me.getKey()); - retVal.append("="); - retVal.append(me.getValue()); - } - } - 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; - } - - /** - * Does this content type have any parameters associated with it? - */ - public boolean hasParameters() { - return (parameters != null) && !parameters.isEmpty(); - } - - /** - * Return the parameter keys - */ - public String[] getParameterKeys() { - if (parameters == null) - return new String[0]; - return parameters.keySet().toArray(new String[parameters.size()]); - } - - /** - * 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 getParameter(String key) { - return parameters.get(key); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java deleted file mode 100644 index 750f9cd71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java +++ /dev/null @@ -1,479 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.OutputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Locale; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; -import org.apache.poi.openxml4j.opc.*; -import org.apache.poi.util.DocumentHelper; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Manage package content types ([Content_Types].xml part). - * - * @author Julien Chable - */ -public abstract class ContentTypeManager { - - /** - * Content type part name. - */ - public static final String CONTENT_TYPES_PART_NAME = "[Content_Types].xml"; - - /** - * Content type namespace - */ - public static final String TYPES_NAMESPACE_URI = PackageNamespaces.CONTENT_TYPES; - - /* Xml elements in content type part */ - - private static final String TYPES_TAG_NAME = "Types"; - - private static final String DEFAULT_TAG_NAME = "Default"; - - private static final String EXTENSION_ATTRIBUTE_NAME = "Extension"; - - private static final String CONTENT_TYPE_ATTRIBUTE_NAME = "ContentType"; - - private static final String OVERRIDE_TAG_NAME = "Override"; - - private static final String PART_NAME_ATTRIBUTE_NAME = "PartName"; - - /** - * Reference to the package using this content type manager. - */ - protected OPCPackage container; - - /** - * Default content type tree. - */ - private TreeMap defaultContentType; - - /** - * Override content type tree. - */ - private TreeMap overrideContentType; - - /** - * Constructor. Parses the content of the specified input stream. - * - * @param in - * If different of null then the content types part is - * retrieve and parse. - * @throws InvalidFormatException - * If the content types part content is not valid. - */ - public ContentTypeManager(InputStream in, OPCPackage pkg) - throws InvalidFormatException { - this.container = pkg; - this.defaultContentType = new TreeMap(); - if (in != null) { - try { - parseContentTypesFile(in); - } catch (InvalidFormatException e) { - InvalidFormatException ex = new InvalidFormatException("Can't read content types part !"); - - // here it is useful to add the cause to not loose the original stack-trace - ex.initCause(e); - - throw ex; - } - } - } - - /** - * Build association extention-> content type (will be stored in - * [Content_Types].xml) for example ContentType="image/png" Extension="png" - *

        - * [M2.8]: When adding a new part to a package, the package implementer - * shall ensure that a content type for that part is specified in the - * Content Types stream; the package implementer shall perform the steps - * described in §9.1.2.3: - *

        - * 1. Get the extension from the part name by taking the substring to the - * right of the rightmost occurrence of the dot character (.) from the - * rightmost segment. - *

        - * 2. If a part name has no extension, a corresponding Override element - * shall be added to the Content Types stream. - *

        - * 3. Compare the resulting extension with the values specified for the - * Extension attributes of the Default elements in the Content Types stream. - * The comparison shall be case-insensitive ASCII. - *

        - * 4. If there is a Default element with a matching Extension attribute, - * then the content type of the new part shall be compared with the value of - * the ContentType attribute. The comparison might be case-sensitive and - * include every character regardless of the role it plays in the - * content-type grammar of RFC 2616, or it might follow the grammar of RFC - * 2616. - *

        - * a. If the content types match, no further action is required. - *

        - * b. If the content types do not match, a new Override element shall be - * added to the Content Types stream. . - *

        - * 5. If there is no Default element with a matching Extension attribute, a - * new Default element or Override element shall be added to the Content - * Types stream. - *

        - */ - public void addContentType(PackagePartName partName, String contentType) { - boolean defaultCTExists = this.defaultContentType.containsValue(contentType); - String extension = partName.getExtension().toLowerCase(Locale.ROOT); - if ((extension.length() == 0) - || (this.defaultContentType.containsKey(extension) && !defaultCTExists)) - this.addOverrideContentType(partName, contentType); - else if (!defaultCTExists) - this.addDefaultContentType(extension, contentType); - } - - /** - * Add an override content type for a specific part. - * - * @param partName - * Name of the part. - * @param contentType - * Content type of the part. - */ - private void addOverrideContentType(PackagePartName partName, - String contentType) { - if (overrideContentType == null) - overrideContentType = new TreeMap(); - overrideContentType.put(partName, contentType); - } - - /** - * Add a content type associated with the specified extension. - * - * @param extension - * The part name extension to bind to a content type. - * @param contentType - * The content type associated with the specified extension. - */ - private void addDefaultContentType(String extension, String contentType) { - // Remark : Originally the latest parameter was : - // contentType.toLowerCase(). Change due to a request ID 1996748. - defaultContentType.put(extension.toLowerCase(Locale.ROOT), contentType); - } - - /** - *

        - * Delete a content type based on the specified part name. If the specified - * part name is register with an override content type, then this content - * type is remove, else the content type is remove in the default content - * type list if it exists and if no part is associated with it yet. - *

        - * Check rule M2.4: The package implementer shall require that the Content - * Types stream contain one of the following for every part in the package: - * One matching Default element One matching Override element Both a - * matching Default element and a matching Override element, in which case - * the Override element takes precedence. - *

        - * @param partName - * The part URI associated with the override content type to - * delete. - * @exception InvalidOperationException - * Throws if - */ - public void removeContentType(PackagePartName partName) - throws InvalidOperationException { - if (partName == null) - throw new IllegalArgumentException("partName"); - - /* Override content type */ - if (this.overrideContentType != null - && (this.overrideContentType.get(partName) != null)) { - // Remove the override definition for the specified part. - this.overrideContentType.remove(partName); - return; - } - - /* Default content type */ - String extensionToDelete = partName.getExtension(); - boolean deleteDefaultContentTypeFlag = true; - if (this.container != null) { - try { - for (PackagePart part : this.container.getParts()) { - if (!part.getPartName().equals(partName) - && part.getPartName().getExtension() - .equalsIgnoreCase(extensionToDelete)) { - deleteDefaultContentTypeFlag = false; - break; - } - } - } catch (InvalidFormatException e) { - throw new InvalidOperationException(e.getMessage()); - } - } - - // Remove the default content type, no other part use this content type. - if (deleteDefaultContentTypeFlag) { - this.defaultContentType.remove(extensionToDelete); - } - - /* - * Check rule 2.4: The package implementer shall require that the - * Content Types stream contain one of the following for every part in - * the package: One matching Default element One matching Override - * element Both a matching Default element and a matching Override - * element, in which case the Override element takes precedence. - */ - if (this.container != null) { - try { - for (PackagePart part : this.container.getParts()) { - if (!part.getPartName().equals(partName) - && this.getContentType(part.getPartName()) == null) - throw new InvalidOperationException( - "Rule M2.4 is not respected: Nor a default element or override element is associated with the part: " - + part.getPartName().getName()); - } - } catch (InvalidFormatException e) { - throw new InvalidOperationException(e.getMessage()); - } - } - } - - /** - * Check if the specified content type is already register. - * - * @param contentType - * The content type to check. - * @return true if the specified content type is already - * register, then false. - */ - public boolean isContentTypeRegister(String contentType) { - if (contentType == null) - throw new IllegalArgumentException("contentType"); - - return (this.defaultContentType.values().contains(contentType) || (this.overrideContentType != null && this.overrideContentType - .values().contains(contentType))); - } - - /** - * Get the content type for the specified part, if any. - *

        - * Rule [M2.9]: To get the content type of a part, the package implementer - * shall perform the steps described in §9.1.2.4: - *

        - * 1. Compare the part name with the values specified for the PartName - * attribute of the Override elements. The comparison shall be - * case-insensitive ASCII. - *

        - * 2. If there is an Override element with a matching PartName attribute, - * return the value of its ContentType attribute. No further action is - * required. - *

        - * 3. If there is no Override element with a matching PartName attribute, - * then a. Get the extension from the part name by taking the substring to - * the right of the rightmost occurrence of the dot character (.) from the - * rightmost segment. b. Check the Default elements of the Content Types - * stream, comparing the extension with the value of the Extension - * attribute. The comparison shall be case-insensitive ASCII. - *

        - * 4. If there is a Default element with a matching Extension attribute, - * return the value of its ContentType attribute. No further action is - * required. - *

        - * 5. If neither Override nor Default elements with matching attributes are - * found for the specified part name, the implementation shall not map this - * part name to a part. - *

        - * @param partName - * The URI part to check. - * @return The content type associated with the URI (in case of an override - * content type) or the extension (in case of default content type), - * else null. - * - * @exception OpenXML4JRuntimeException - * Throws if the content type manager is not able to find the - * content from an existing part. - */ - public String getContentType(PackagePartName partName) { - if (partName == null) - throw new IllegalArgumentException("partName"); - - if ((this.overrideContentType != null) - && this.overrideContentType.containsKey(partName)) - return this.overrideContentType.get(partName); - - String extension = partName.getExtension().toLowerCase(Locale.ROOT); - if (this.defaultContentType.containsKey(extension)) - return this.defaultContentType.get(extension); - - /* - * [M2.4] : The package implementer shall require that the Content Types - * stream contain one of the following for every part in the package: - * One matching Default element, One matching Override element, Both a - * matching Default element and a matching Override element, in which - * case the Override element takes precedence. - */ - if (this.container != null && this.container.getPart(partName) != null) { - throw new OpenXML4JRuntimeException( - "Rule M2.4 exception : this error should NEVER happen! If you can provide the triggering file, then please raise a bug at https://bz.apache.org/bugzilla/enter_bug.cgi?product=POI and attach the file that triggers it, thanks!"); - } - return null; - } - - /** - * Clear all content types. - */ - public void clearAll() { - this.defaultContentType.clear(); - if (this.overrideContentType != null) - this.overrideContentType.clear(); - } - - /** - * Clear all override content types. - * - */ - public void clearOverrideContentTypes() { - if (this.overrideContentType != null) - this.overrideContentType.clear(); - } - - /** - * Parse the content types part. - * - * @throws InvalidFormatException - * Throws if the content type doesn't exist or the XML format is - * invalid. - */ - private void parseContentTypesFile(InputStream in) - throws InvalidFormatException { - try { - Document xmlContentTypetDoc = DocumentHelper.readDocument(in); - - // Default content types - NodeList defaultTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagNameNS(TYPES_NAMESPACE_URI, DEFAULT_TAG_NAME); - int defaultTypeCount = defaultTypes.getLength(); - for (int i = 0; i < defaultTypeCount; i++) { - Element element = (Element) defaultTypes.item(i); - String extension = element.getAttribute(EXTENSION_ATTRIBUTE_NAME); - String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME); - addDefaultContentType(extension, contentType); - } - - // Overriden content types - NodeList overrideTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagNameNS(TYPES_NAMESPACE_URI, OVERRIDE_TAG_NAME); - int overrideTypeCount = overrideTypes.getLength(); - for (int i = 0; i < overrideTypeCount; i++) { - Element element = (Element) overrideTypes.item(i); - URI uri = new URI(element.getAttribute(PART_NAME_ATTRIBUTE_NAME)); - PackagePartName partName = PackagingURIHelper.createPartName(uri); - String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME); - addOverrideContentType(partName, contentType); - } - } catch (URISyntaxException urie) { - throw new InvalidFormatException(urie.getMessage()); - } catch (SAXException e) { - throw new InvalidFormatException(e.getMessage()); - } catch (IOException e) { - throw new InvalidFormatException(e.getMessage()); - } - } - - /** - * Save the contents type part. - * - * @param outStream - * The output stream use to save the XML content of the content - * types part. - * @return true if the operation success, else false. - */ - public boolean save(OutputStream outStream) { - Document xmlOutDoc = DocumentHelper.createDocument(); - - // Building namespace - Element typesElem = xmlOutDoc.createElementNS(TYPES_NAMESPACE_URI, TYPES_TAG_NAME); - xmlOutDoc.appendChild(typesElem); - - // Adding default types - for (Entry entry : defaultContentType.entrySet()) { - appendDefaultType(typesElem, entry); - } - - // Adding specific types if any exist - if (overrideContentType != null) { - for (Entry entry : overrideContentType - .entrySet()) { - appendSpecificTypes(typesElem, entry); - } - } - xmlOutDoc.normalize(); - - // Save content in the specified output stream - return this.saveImpl(xmlOutDoc, outStream); - } - - /** - * Use to append specific type XML elements, use by the save() method. - * - * @param root - * XML parent element use to append this override type element. - * @param entry - * The values to append. - * @see #save(java.io.OutputStream) - */ - private void appendSpecificTypes(Element root, - Entry entry) { - Element specificType = root.getOwnerDocument().createElementNS(TYPES_NAMESPACE_URI, OVERRIDE_TAG_NAME); - specificType.setAttribute(PART_NAME_ATTRIBUTE_NAME, entry.getKey().getName()); - specificType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue()); - root.appendChild(specificType); - } - - /** - * Use to append default types XML elements, use by the save() method. - * - * @param root - * XML parent element use to append this default type element. - * @param entry - * The values to append. - * @see #save(java.io.OutputStream) - */ - private void appendDefaultType(Element root, Entry entry) { - Element defaultType = root.getOwnerDocument().createElementNS(TYPES_NAMESPACE_URI, DEFAULT_TAG_NAME); - defaultType.setAttribute(EXTENSION_ATTRIBUTE_NAME, entry.getKey()); - defaultType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue()); - root.appendChild(defaultType); - } - - /** - * Specific implementation of the save method. Call by the save() method, - * call before exiting. - * - * @param out - * The output stream use to write the content type XML. - */ - public abstract boolean saveImpl(Document content, OutputStream out); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java deleted file mode 100644 index cc41e4352..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.channels.FileChannel; - -/** - * Provide useful method to manage file. - * - * @author Julien Chable - * @version 0.1 - */ -public final class FileHelper { - - /** - * Get the directory part of the specified file path. - * - * @param f - * File to process. - * @return The directory path from the specified - */ - public static File getDirectory(File f) { - if (f != null) { - String path = f.getPath(); - int len = path.length(); - int num2 = len; - while (--num2 >= 0) { - char ch1 = path.charAt(num2); - if (ch1 == File.separatorChar) { - return new File(path.substring(0, num2)); - } - } - } - return null; - } - - /** - * Copy a file. - * - * @param in - * The source file. - * @param out - * The target location. - * @throws IOException - * If an I/O error occur. - */ - public static void copyFile(File in, File out) throws IOException { - FileChannel sourceChannel = new FileInputStream(in).getChannel(); - FileChannel destinationChannel = new FileOutputStream(out).getChannel(); - sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel); - sourceChannel.close(); - destinationChannel.close(); - } - - /** - * Get file name from the specified File object. - */ - public static String getFilename(File file) { - if (file != null) { - String path = file.getPath(); - int len = path.length(); - int num2 = len; - while (--num2 >= 0) { - char ch1 = path.charAt(num2); - if (ch1 == File.separatorChar) - return path.substring(num2 + 1, len); - } - } - return ""; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePart.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePart.java deleted file mode 100644 index f2d8c3115..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePart.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -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.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller; -import org.apache.poi.util.IOUtils; - -/** - * Memory version of a package part. Use to - * - * @author Julien Chable - * @version 1.0 - */ -public final class MemoryPackagePart extends PackagePart { - - /** - * Storage for the part data. - */ - protected byte[] data; - - /** - * Constructor. - * - * @param pack - * The owner package. - * @param partName - * The part name. - * @param contentType - * The content type. - * @throws InvalidFormatException - * If the specified URI is not OPC compliant. - */ - public MemoryPackagePart(OPCPackage pack, PackagePartName partName, - String contentType) throws InvalidFormatException { - super(pack, partName, contentType); - } - - /** - * Constructor. - * - * @param pack - * The owner package. - * @param partName - * The part name. - * @param contentType - * The content type. - * @param loadRelationships - * Specify if the relationships will be loaded. - * @throws InvalidFormatException - * If the specified URI is not OPC compliant. - */ - public MemoryPackagePart(OPCPackage pack, PackagePartName partName, - String contentType, boolean loadRelationships) - throws InvalidFormatException { - super(pack, partName, new ContentType(contentType), loadRelationships); - } - - @Override - protected InputStream getInputStreamImpl() { - // If this part has been created from scratch and/or the data buffer is - // not - // initialize, so we do it now. - if (data == null) { - data = new byte[0]; - } - return new ByteArrayInputStream(data); - } - - @Override - protected OutputStream getOutputStreamImpl() { - return new MemoryPackagePartOutputStream(this); - } - - @Override - public long getSize() { - return data == null ? 0 : data.length; - } - - @Override - public void clear() { - data = null; - } - - @Override - public boolean save(OutputStream os) throws OpenXML4JException { - return new ZipPartMarshaller().marshall(this, os); - } - - @Override - public boolean load(InputStream ios) throws InvalidFormatException { - // Grab the data - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - IOUtils.copy(ios, baos); - } catch(IOException e) { - throw new InvalidFormatException(e.getMessage()); - } - - // Save it - data = baos.toByteArray(); - - // All done - return true; - } - - @Override - public void close() { - // Do nothing - } - - @Override - public void flush() { - // Do nothing - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java deleted file mode 100644 index cf809d667..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 - */ -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) { - _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) { - _buff.write(b, off, len); - } - - @Override - public void write(byte[] b) throws IOException { - _buff.write(b); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java deleted file mode 100644 index 6fb7f65be..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java +++ /dev/null @@ -1,675 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.InputStream; -import java.io.OutputStream; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackageProperties; -import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.util.LocaleUtil; - -/** - * Represents the core properties part of a package. - * - * @author Julien Chable - */ -public final class PackagePropertiesPart extends PackagePart implements - PackageProperties { - - public final static String NAMESPACE_DC_URI = "http://purl.org/dc/elements/1.1/"; - - public final static String NAMESPACE_CP_URI = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; - - public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/"; - - private final static String DEFAULT_DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; - - private final static String[] DATE_FORMATS = new String[]{ - DEFAULT_DATEFORMAT, - "yyyy-MM-dd'T'HH:mm:ss.SS'Z'", - "yyyy-MM-dd" - }; - - //Had to add this and TIME_ZONE_PAT to handle tz with colons. - //When we move to Java 7, we should be able to add another - //date format to DATE_FORMATS that uses XXX and get rid of this - //and TIME_ZONE_PAT - // TODO Fix this after the Java 7 upgrade - private final String[] TZ_DATE_FORMATS = new String[]{ - "yyyy-MM-dd'T'HH:mm:ssz", - "yyyy-MM-dd'T'HH:mm:ss.Sz", - "yyyy-MM-dd'T'HH:mm:ss.SSz", - "yyyy-MM-dd'T'HH:mm:ss.SSSz", - }; - - private final Pattern TIME_ZONE_PAT = Pattern.compile("([-+]\\d\\d):?(\\d\\d)"); - /** - * Constructor. - * - * @param pack - * Container package. - * @param partName - * Name of this part. - * @throws InvalidFormatException - * Throws if the content is invalid. - */ - public PackagePropertiesPart(OPCPackage pack, PackagePartName partName) - throws InvalidFormatException { - super(pack, partName, ContentTypes.CORE_PROPERTIES_PART); - } - - /** - * A categorization of the content of this package. - * - * [Example: Example values for this property might include: Resume, Letter, - * Financial Forecast, Proposal, Technical Presentation, and so on. This - * value might be used by an application's user interface to facilitate - * navigation of a large set of documents. end example] - */ - protected Nullable category = new Nullable(); - - /** - * The status of the content. - * - * [Example: Values might include "Draft", "Reviewed", and "Final". end - * example] - */ - protected Nullable contentStatus = new Nullable(); - - /** - * The type of content represented, generally defined by a specific use and - * intended audience. - * - * [Example: Values might include "Whitepaper", "Security Bulletin", and - * "Exam". end example] [Note: This property is distinct from MIME content - * types as defined in RFC 2616. end note] - */ - protected Nullable contentType = new Nullable(); - - /** - * Date of creation of the resource. - */ - protected Nullable created = new Nullable(); - - /** - * An entity primarily responsible for making the content of the resource. - */ - protected Nullable creator = new Nullable(); - - /** - * An explanation of the content of the resource. - * - * [Example: Values might include an abstract, table of contents, reference - * to a graphical representation of content, and a free-text account of the - * content. end example] - */ - protected Nullable description = new Nullable(); - - /** - * An unambiguous reference to the resource within a given context. - */ - protected Nullable identifier = new Nullable(); - - /** - * A delimited set of keywords to support searching and indexing. This is - * typically a list of terms that are not available elsewhere in the - * properties. - */ - protected Nullable keywords = new Nullable(); - - /** - * The language of the intellectual content of the resource. - * - * [Note: IETF RFC 3066 provides guidance on encoding to represent - * languages. end note] - */ - protected Nullable language = new Nullable(); - - /** - * The user who performed the last modification. The identification is - * environment-specific. - * - * [Example: A name, email address, or employee ID. end example] It is - * recommended that this value be as concise as possible. - */ - protected Nullable lastModifiedBy = new Nullable(); - - /** - * The date and time of the last printing. - */ - protected Nullable lastPrinted = new Nullable(); - - /** - * Date on which the resource was changed. - */ - protected Nullable modified = new Nullable(); - - /** - * The revision number. - * - * [Example: This value might indicate the number of saves or revisions, - * provided the application updates it after each revision. end example] - */ - protected Nullable revision = new Nullable(); - - /** - * The topic of the content of the resource. - */ - protected Nullable subject = new Nullable(); - - /** - * The name given to the resource. - */ - protected Nullable title = new Nullable(); - - /** - * The version number. This value is set by the user or by the application. - */ - protected Nullable version = new Nullable(); - - /* - * Getters and setters - */ - - /** - * Get the category property. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty() - */ - public Nullable getCategoryProperty() { - return category; - } - - /** - * Get content status. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty() - */ - public Nullable getContentStatusProperty() { - return contentStatus; - } - - /** - * Get content type. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty() - */ - public Nullable getContentTypeProperty() { - return contentType; - } - - /** - * Get created date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty() - */ - public Nullable getCreatedProperty() { - return created; - } - - /** - * Get created date formated into a String. - * - * @return A string representation of the created date. - */ - public String getCreatedPropertyString() { - return getDateValue(created); - } - - /** - * Get creator. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty() - */ - public Nullable getCreatorProperty() { - return creator; - } - - /** - * Get description. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty() - */ - public Nullable getDescriptionProperty() { - return description; - } - - /** - * Get identifier. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty() - */ - public Nullable getIdentifierProperty() { - return identifier; - } - - /** - * Get keywords. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty() - */ - public Nullable getKeywordsProperty() { - return keywords; - } - - /** - * Get the language. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty() - */ - public Nullable getLanguageProperty() { - return language; - } - - /** - * Get the author of last modifications. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastModifiedByProperty() - */ - public Nullable getLastModifiedByProperty() { - return lastModifiedBy; - } - - /** - * Get last printed date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastPrintedProperty() - */ - public Nullable getLastPrintedProperty() { - return lastPrinted; - } - - /** - * Get last printed date formated into a String. - * - * @return A string representation of the last printed date. - */ - public String getLastPrintedPropertyString() { - return getDateValue(lastPrinted); - } - - /** - * Get modified date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty() - */ - public Nullable getModifiedProperty() { - return modified; - } - - /** - * Get modified date formated into a String. - * - * @return A string representation of the modified date. - */ - public String getModifiedPropertyString() { - if (modified.hasValue()) { - return getDateValue(modified); - } - return getDateValue(new Nullable(new Date())); - } - - /** - * Get revision. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty() - */ - public Nullable getRevisionProperty() { - return revision; - } - - /** - * Get subject. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty() - */ - public Nullable getSubjectProperty() { - return subject; - } - - /** - * Get title. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty() - */ - public Nullable getTitleProperty() { - return title; - } - - /** - * Get version. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty() - */ - public Nullable getVersionProperty() { - return version; - } - - /** - * Set the category. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.lang.String) - */ - public void setCategoryProperty(String category) { - this.category = setStringValue(category); - } - - /** - * Set the content status. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.lang.String) - */ - public void setContentStatusProperty(String contentStatus) { - this.contentStatus = setStringValue(contentStatus); - } - - /** - * Set the content type. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.lang.String) - */ - public void setContentTypeProperty(String contentType) { - this.contentType = setStringValue(contentType); - } - - /** - * Set the created date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable) - */ - public void setCreatedProperty(String created) { - try { - this.created = setDateValue(created); - } catch (InvalidFormatException e) { - throw new IllegalArgumentException("Date for created could not be parsed: " + created, e); - } - } - - /** - * Set the created date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable) - */ - public void setCreatedProperty(Nullable created) { - if (created.hasValue()) - this.created = created; - } - - /** - * Set the creator. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.lang.String) - */ - public void setCreatorProperty(String creator) { - this.creator = setStringValue(creator); - } - - /** - * Set the description. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.lang.String) - */ - public void setDescriptionProperty(String description) { - this.description = setStringValue(description); - } - - /** - * Set identifier. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.lang.String) - */ - public void setIdentifierProperty(String identifier) { - this.identifier = setStringValue(identifier); - } - - /** - * Set keywords. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.lang.String) - */ - public void setKeywordsProperty(String keywords) { - this.keywords = setStringValue(keywords); - } - - /** - * Set language. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.lang.String) - */ - public void setLanguageProperty(String language) { - this.language = setStringValue(language); - } - - /** - * Set last modifications author. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.lang.String) - */ - public void setLastModifiedByProperty(String lastModifiedBy) { - this.lastModifiedBy = setStringValue(lastModifiedBy); - } - - /** - * Set last printed date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable) - */ - public void setLastPrintedProperty(String lastPrinted) { - try { - this.lastPrinted = setDateValue(lastPrinted); - } catch (InvalidFormatException e) { - throw new IllegalArgumentException("lastPrinted : " - + e.getLocalizedMessage(), e); - } - } - - /** - * Set last printed date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable) - */ - public void setLastPrintedProperty(Nullable lastPrinted) { - if (lastPrinted.hasValue()) - this.lastPrinted = lastPrinted; - } - - /** - * Set last modification date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable) - */ - public void setModifiedProperty(String modified) { - try { - this.modified = setDateValue(modified); - } catch (InvalidFormatException e) { - throw new IllegalArgumentException("modified : " - + e.getLocalizedMessage(), e); - } - } - - /** - * Set last modification date. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable) - */ - public void setModifiedProperty(Nullable modified) { - if (modified.hasValue()) - this.modified = modified; - } - - /** - * Set revision. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.lang.String) - */ - public void setRevisionProperty(String revision) { - this.revision = setStringValue(revision); - } - - /** - * Set subject. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.lang.String) - */ - public void setSubjectProperty(String subject) { - this.subject = setStringValue(subject); - } - - /** - * Set title. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.lang.String) - */ - public void setTitleProperty(String title) { - this.title = setStringValue(title); - } - - /** - * Set version. - * - * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.lang.String) - */ - public void setVersionProperty(String version) { - this.version = setStringValue(version); - } - - /** - * Convert a strig value into a Nullable - */ - private Nullable setStringValue(String s) { - if (s == null || s.equals("")) { - return new Nullable(); - } - return new Nullable(s); - } - - /** - * Convert a string value represented a date into a Nullable. - * - * @throws InvalidFormatException - * Throws if the date format isnot valid. - */ - private Nullable setDateValue(String dateStr) throws InvalidFormatException { - if (dateStr == null || dateStr.equals("")) { - return new Nullable(); - } - - Matcher m = TIME_ZONE_PAT.matcher(dateStr); - if (m.find()) { - String dateTzStr = dateStr.substring(0, m.start())+ - m.group(1)+m.group(2); - for (String fStr : TZ_DATE_FORMATS) { - SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - Date d = df.parse(dateTzStr, new ParsePosition(0)); - if (d != null) { - return new Nullable(d); - } - } - } - String dateTzStr = dateStr.endsWith("Z") ? dateStr : (dateStr + "Z"); - for (String fStr : DATE_FORMATS) { - SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - Date d = df.parse(dateTzStr, new ParsePosition(0)); - if (d != null) { - return new Nullable(d); - } - } - //if you're here, no pattern matched, throw exception - StringBuilder sb = new StringBuilder(); - int i = 0; - for (String fStr : TZ_DATE_FORMATS) { - if (i++ > 0) { - sb.append(", "); - } - sb.append(fStr); - } - for (String fStr : DATE_FORMATS) { - sb.append(", ").append(fStr); - } - throw new InvalidFormatException("Date " + dateStr + " not well formatted, " - + "expected format in: "+sb.toString()); - } - - /** - * Convert a Nullable into a String. - * - * @param d - * The Date to convert. - * @return The formated date or null. - * @see java.text.SimpleDateFormat - */ - private String getDateValue(Nullable d) { - if (d == null) { - return ""; - } - Date date = d.getValue(); - if (date == null) { - return ""; - } - - SimpleDateFormat df = new SimpleDateFormat(DEFAULT_DATEFORMAT, Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - return df.format(date); - } - - @Override - protected InputStream getInputStreamImpl() { - throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart"); - } - - @Override - protected OutputStream getOutputStreamImpl() { - throw new InvalidOperationException( - "Can't use output stream to set properties !"); - } - - @Override - public boolean save(OutputStream zos) { - throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart"); - } - - @Override - public boolean load(InputStream ios) { - throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart"); - } - - @Override - public void close() { - // Do nothing - } - - @Override - public void flush() { - // Do nothing - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java deleted file mode 100644 index e30d71783..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 false if any marshall error occurs, else true - * @throws OpenXML4JException - * Throws only if any other exceptions are thrown by inner - * methods. - */ - public boolean marshall(PackagePart part, OutputStream out) - throws OpenXML4JException; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java deleted file mode 100644 index e5487a638..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc.internal; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext; - -/** - * Object implemented this interface are considered as part unmarshaller. A part - * unmarshaller is responsible to unmarshall a part in order to load it from a - * package. - * - * @author Julien Chable - * @version 0.1 - */ -public interface PartUnmarshaller { - - /** - * Save the content of the package in the stream - * - * @param in - * The input stream from which the part will be unmarshall. - * @return The part freshly unmarshall from the input stream. - * @throws OpenXML4JException - * Throws only if any other exceptions are thrown by inner - * methods. - */ - public PackagePart unmarshall(UnmarshallContext context, InputStream in) - throws InvalidFormatException, IOException; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java deleted file mode 100644 index 1e00d9308..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.OutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.StreamHelper; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.w3c.dom.Document; - -/** - * Zip implementation of the ContentTypeManager. - * - * @author Julien Chable - * @version 1.0 - * @see ContentTypeManager - */ -public class ZipContentTypeManager extends ContentTypeManager { - private static POILogger logger = POILogFactory.getLogger(ZipContentTypeManager.class); - - /** - * Delegate constructor to the super constructor. - * - * @param in - * The input stream to parse to fill internal content type - * collections. - * @throws InvalidFormatException - * If the content types part content is not valid. - */ - public ZipContentTypeManager(InputStream in, OPCPackage pkg) - throws InvalidFormatException { - super(in, pkg); - } - - @SuppressWarnings("resource") - @Override - public boolean saveImpl(Document content, OutputStream out) { - ZipOutputStream zos = null; - if (out instanceof ZipOutputStream) - zos = (ZipOutputStream) out; - else - zos = new ZipOutputStream(out); - - ZipEntry partEntry = new ZipEntry(CONTENT_TYPES_PART_NAME); - try { - // Referenced in ZIP - zos.putNextEntry(partEntry); - // Saving data in the ZIP file - if (!StreamHelper.saveXmlInStream(content, zos)) { - return false; - } - zos.closeEntry(); - } catch (IOException ioe) { - logger.log(POILogger.ERROR, "Cannot write: " + CONTENT_TYPES_PART_NAME - + " in Zip !", ioe); - return false; - } - return true; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java deleted file mode 100644 index b674b3ad2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java +++ /dev/null @@ -1,276 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; - -import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException; -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; -import org.apache.poi.openxml4j.util.ZipSecureFile; -import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream; -import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.poifs.storage.HeaderBlockConstants; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; - -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) { - 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 = 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; - } - 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 = 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 = opcItemName; - while (retVal.startsWith(FORWARD_SLASH)) - retVal = retVal.substring(1); - try { - return new URI(retVal); - } catch (URISyntaxException e) { - return null; - } - } - - /** - * Verifies that the given stream starts with a Zip structure. - * - * Warning - this will consume the first few bytes of the stream, - * you should push-back or reset the stream after use! - */ - public static void verifyZipHeader(InputStream stream) - throws NotOfficeXmlFileException, IOException { - // Grab the first 8 bytes - byte[] data = new byte[8]; - IOUtils.readFully(stream, data); - - // OLE2? - long signature = LittleEndian.getLong(data); - if (signature == HeaderBlockConstants._signature) { - throw new OLE2NotOfficeXmlFileException( - "The supplied data appears to be in the OLE2 Format. " + - "You are calling the part of POI that deals with OOXML "+ - "(Office Open XML) Documents. You need to call a different " + - "part of POI to process this data (eg HSSF instead of XSSF)"); - } - - // Raw XML? - byte[] RAW_XML_FILE_HEADER = POIFSConstants.RAW_XML_FILE_HEADER; - if (data[0] == RAW_XML_FILE_HEADER[0] && - data[1] == RAW_XML_FILE_HEADER[1] && - data[2] == RAW_XML_FILE_HEADER[2] && - data[3] == RAW_XML_FILE_HEADER[3] && - data[4] == RAW_XML_FILE_HEADER[4]) { - throw new NotOfficeXmlFileException( - "The supplied data appears to be a raw XML file. " + - "Formats such as Office 2003 XML are not supported"); - } - - // Don't check for a Zip header, as to maintain backwards - // compatibility we need to let them seek over junk at the - // start before beginning processing. - - // Put things back - if (stream instanceof PushbackInputStream) { - ((PushbackInputStream)stream).unread(data); - } else if (stream.markSupported()) { - stream.reset(); - } else if (stream instanceof FileInputStream) { - // File open check, about to be closed, nothing to do - } else { - // Oh dear... I hope you know what you're doing! - } - } - - private static InputStream prepareToCheckHeader(InputStream stream) { - if (stream instanceof PushbackInputStream) { - return stream; - } - if (stream.markSupported()) { - stream.mark(8); - return stream; - } - return new PushbackInputStream(stream, 8); - } - - /** - * Opens the specified stream as a secure zip - * - * @param stream - * The stream to open. - * @return The zip stream freshly open. - */ - @SuppressWarnings("resource") - public static ThresholdInputStream openZipStream(InputStream stream) throws IOException { - // Peek at the first few bytes to sanity check - InputStream checkedStream = prepareToCheckHeader(stream); - verifyZipHeader(checkedStream); - - // Open as a proper zip stream - InputStream zis = new ZipInputStream(checkedStream); - return ZipSecureFile.addThreshold(zis); - } - - /** - * Opens the specified file as a secure zip, or returns null if no - * such file exists - * - * @param file - * The file to open. - * @return The zip archive freshly open. - * @throws IOException if the zip file cannot be opened or closed to read the header signature - * @throws NotOfficeXmlFileException if stream does not start with zip header signature - */ - public static ZipFile openZipFile(File file) throws IOException, NotOfficeXmlFileException { - if (!file.exists()) { - throw new FileNotFoundException("File does not exist"); - } - if (file.isDirectory()) { - throw new IOException("File is a directory"); - } - - // Peek at the first few bytes to sanity check - FileInputStream input = new FileInputStream(file); - try { - verifyZipHeader(input); - } finally { - input.close(); - } - - // Open as a proper zip file - return new ZipSecureFile(file); - } - - /** - * Retrieve and open as a secure zip file with the specified path. - * - * @param path - * The file path. - * @return The zip archive freshly open. - */ - public static ZipFile openZipFile(String path) throws IOException { - return openZipFile(new File(path)); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java deleted file mode 100644 index 8cd2f7d24..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.openxml4j.opc.internal.marshallers; - -import java.io.OutputStream; - -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.internal.PartMarshaller; - -/** - * Default marshaller that specified that the part is responsible to marshall its content. - * - * @author Julien Chable - * @version 1.0 - * @see PartMarshaller - */ -public final class DefaultMarshaller implements PartMarshaller { - - /** - * Save part in the output stream by using the save() method of the part. - * - * @throws OpenXML4JException - * If any error occur. - */ - public boolean marshall(PackagePart part, OutputStream out) - throws OpenXML4JException { - return part.save(out); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java deleted file mode 100644 index 7a8f40072..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java +++ /dev/null @@ -1,272 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 javax.xml.XMLConstants; -import javax.xml.stream.XMLEventFactory; -import javax.xml.stream.events.Namespace; - -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; -import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.util.DocumentHelper; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * Package properties marshaller. - */ -public class PackagePropertiesMarshaller implements PartMarshaller { - private final static Namespace namespaceDC, namespaceCoreProperties, namespaceDcTerms, namespaceXSI; - static { - final XMLEventFactory f = XMLEventFactory.newInstance(); - namespaceDC = f.createNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI); - namespaceCoreProperties = f.createNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI); - namespaceDcTerms = f.createNamespace("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI); - namespaceXSI = f.createNamespace("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_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 - * true. - */ - @Override - 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.createElementNS(namespaceCoreProperties.getNamespaceURI(), - getQName("coreProperties", namespaceCoreProperties)); - DocumentHelper.addNamespaceDeclaration(rootElem, namespaceCoreProperties); - DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDC); - DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDcTerms); - DocumentHelper.addNamespaceDeclaration(rootElem, namespaceXSI); - xmlDoc.appendChild(rootElem); - - addCategory(); - addContentStatus(); - addContentType(); - addCreated(); - addCreator(); - addDescription(); - addIdentifier(); - addKeywords(); - addLanguage(); - addLastModifiedBy(); - addLastPrinted(); - addModified(); - addRevision(); - addSubject(); - addTitle(); - addVersion(); - return true; - } - - /** - * Sets the given element's text content, creating it if necessary. - */ - private Element setElementTextContent(String localName, Namespace namespace, Nullable property) { - return setElementTextContent(localName, namespace, property, property.getValue()); - } - - private String getQName(String localName, Namespace namespace) { - return namespace.getPrefix().isEmpty() ? localName : namespace.getPrefix() + ':' + localName; - } - - private Element setElementTextContent(String localName, Namespace namespace, Nullable property, String propertyValue) { - if (!property.hasValue()) - return null; - - Element root = xmlDoc.getDocumentElement(); - Element elem = (Element) root.getElementsByTagNameNS(namespace.getNamespaceURI(), localName).item(0); - if (elem == null) { - // missing, we add it - elem = xmlDoc.createElementNS(namespace.getNamespaceURI(), getQName(localName, namespace)); - root.appendChild(elem); - } - elem.setTextContent(propertyValue); - return elem; - } - - private Element setElementTextContent(String localName, Namespace namespace, Nullable property, String propertyValue, String xsiType) { - Element element = setElementTextContent(localName, namespace, property, propertyValue); - if (element != null) { - element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType); - } - return element; - } - - - /** - * Add category property element if needed. - */ - private void addCategory() { - setElementTextContent(KEYWORD_CATEGORY, namespaceCoreProperties, propsPart.getCategoryProperty()); - } - - /** - * Add content status property element if needed. - */ - private void addContentStatus() { - setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty()); - } - - /** - * Add content type property element if needed. - */ - private void addContentType() { - setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty()); - } - - /** - * Add created property element if needed. - */ - private void addCreated() { - setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(), - propsPart.getCreatedPropertyString(), "dcterms:W3CDTF"); - } - - /** - * Add creator property element if needed. - */ - private void addCreator() { - setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty()); - } - - /** - * Add description property element if needed. - */ - private void addDescription() { - setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty()); - } - - /** - * Add identifier property element if needed. - */ - private void addIdentifier() { - setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty()); - } - - /** - * Add keywords property element if needed. - */ - private void addKeywords() { - setElementTextContent(KEYWORD_KEYWORDS, namespaceCoreProperties, propsPart.getKeywordsProperty()); - } - - /** - * Add language property element if needed. - */ - private void addLanguage() { - setElementTextContent(KEYWORD_LANGUAGE, namespaceDC, propsPart.getLanguageProperty()); - } - - /** - * Add 'last modified by' property if needed. - */ - private void addLastModifiedBy() { - setElementTextContent(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties, propsPart.getLastModifiedByProperty()); - } - - /** - * Add 'last printed' property if needed. - * - */ - private void addLastPrinted() { - setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString()); - } - - /** - * Add modified property element if needed. - */ - private void addModified() { - setElementTextContent(KEYWORD_MODIFIED, namespaceDcTerms, propsPart.getModifiedProperty(), - propsPart.getModifiedPropertyString(), "dcterms:W3CDTF"); - } - - /** - * Add revision property if needed. - */ - private void addRevision() { - setElementTextContent(KEYWORD_REVISION, namespaceCoreProperties, propsPart.getRevisionProperty()); - } - - /** - * Add subject property if needed. - */ - private void addSubject() { - setElementTextContent(KEYWORD_SUBJECT, namespaceDC, propsPart.getSubjectProperty()); - } - - /** - * Add title property if needed. - */ - private void addTitle() { - setElementTextContent(KEYWORD_TITLE, namespaceDC, propsPart.getTitleProperty()); - } - - private void addVersion() { - setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java deleted file mode 100644 index 6b4b21551..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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(), e); - } - return true; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java deleted file mode 100644 index 8860ae37e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java +++ /dev/null @@ -1,191 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.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.DocumentHelper; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * 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 - } - - // check if there is anything to save for some parts. We don't do this for all parts as some code - // might depend on empty parts being saved, e.g. some unit tests verify this currently. - if(part.getSize() == 0 && part.getPartName().getName().equals(XSSFRelation.SHARED_STRINGS.getDefaultFileName())) { - return true; - } - - 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 - Element root = xmlOutDoc.createElementNS(PackageNamespaces.RELATIONSHIPS, PackageRelationship.RELATIONSHIPS_TAG_NAME); - xmlOutDoc.appendChild(root); - - // - - URI sourcePartURI = PackagingURIHelper - .getSourcePartUriFromRelationshipPartUri(relPartName.getURI()); - - for (PackageRelationship rel : rels) { - // the relationship element - Element relElem = xmlOutDoc.createElementNS(PackageNamespaces.RELATIONSHIPS, PackageRelationship.RELATIONSHIP_TAG_NAME); - root.appendChild(relElem); - - // the relationship ID - relElem.setAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel.getId()); - - // the relationship Type - relElem.setAttribute(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.setAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External"); - } else { - URI targetURI = rel.getTargetURI(); - targetValue = PackagingURIHelper.relativizeURI( - sourcePartURI, targetURI, true).toString(); - } - relElem.setAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME, targetValue); - } - - xmlOutDoc.normalize(); - - // String schemaFilename = Configuration.getPathForXmlSchema()+ - // File.separator + "opc-relationships.xsd"; - - // Save part in zip - ZipEntry ctEntry = new ZipEntry(ZipHelper.getZipURIFromOPCName( - relPartName.getURI().toASCIIString()).getPath()); - try { - zos.putNextEntry(ctEntry); - if (!StreamHelper.saveXmlInStream(xmlOutDoc, zos)) { - return false; - } - zos.closeEntry(); - } catch (IOException e) { - logger.log(POILogger.ERROR,"Cannot create zip entry " + relPartName, e); - return false; - } - return true; // success - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java deleted file mode 100644 index 0ccbf30e1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java +++ /dev/null @@ -1,293 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.zip.ZipEntry; - -import javax.xml.XMLConstants; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -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; -import org.apache.poi.util.DocumentHelper; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Package properties unmarshaller. - * - * @author Julien Chable - */ -public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { - - 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 = ZipHelper - .getCorePropertiesZipEntry((ZipPackage) context - .getPackage()); - in = ((ZipPackage) context.getPackage()).getZipArchive() - .getInputStream(zipEntry); - } else - throw new IOException( - "Error while trying to get the part input stream."); - } - - Document xmlDoc; - try { - xmlDoc = DocumentHelper.readDocument(in); - - /* Check OPC compliance */ - - // Rule M4.2, M4.3, M4.4 and M4.5/ - checkElementForOPCCompliance(xmlDoc.getDocumentElement()); - - /* End OPC compliance */ - - } catch (SAXException 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 readElement(Document xmlDoc, String localName, String namespaceURI) { - Element el = (Element)xmlDoc.getDocumentElement().getElementsByTagNameNS(namespaceURI, localName).item(0); - if (el == null) { - return null; - } - return el.getTextContent(); - } - - private String loadCategory(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_CATEGORY, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadContentStatus(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_CONTENT_STATUS, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadContentType(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_CONTENT_TYPE, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadCreated(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_CREATED, PackageProperties.NAMESPACE_DCTERMS); - } - - private String loadCreator(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_CREATOR, PackageProperties.NAMESPACE_DC); - } - - private String loadDescription(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_DESCRIPTION, PackageProperties.NAMESPACE_DC); - } - - private String loadIdentifier(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_IDENTIFIER, PackageProperties.NAMESPACE_DC); - } - - private String loadKeywords(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_KEYWORDS, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadLanguage(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_LANGUAGE, PackageProperties.NAMESPACE_DC); - } - - private String loadLastModifiedBy(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_LAST_MODIFIED_BY, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadLastPrinted(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_LAST_PRINTED, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadModified(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_MODIFIED, PackageProperties.NAMESPACE_DCTERMS); - } - - private String loadRevision(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_REVISION, PackageNamespaces.CORE_PROPERTIES); - } - - private String loadSubject(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_SUBJECT, PackageProperties.NAMESPACE_DC); - } - - private String loadTitle(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_TITLE, PackageProperties.NAMESPACE_DC); - } - - private String loadVersion(Document xmlDoc) { - return readElement(xmlDoc, KEYWORD_VERSION, PackageNamespaces.CORE_PROPERTIES); - } - - /* OPC Compliance methods */ - - /** - * Check the element for the following OPC compliance rules: - *

        - * Rule M4.2: A format consumer shall consider the use of the Markup - * Compatibility namespace to be an error. - *

        - * 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: and Consumers shall - * consider a document element that violates this constraint to be an error. - *

        - * 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. - *

        - * Rule M4.5: Producers shall not create a document element that contains - * the xsi:type attribute, except for a or - * 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. - *

        - */ - public void checkElementForOPCCompliance(Element el) - throws InvalidFormatException { - // Check the current element - NamedNodeMap namedNodeMap = el.getAttributes(); - int namedNodeCount = namedNodeMap.getLength(); - for (int i = 0; i < namedNodeCount; i++) { - Attr attr = (Attr)namedNodeMap.item(0); - - if (attr.getNamespaceURI().equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) { - // Rule M4.2 - if (attr.getValue().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 - String elName = el.getLocalName(); - if (el.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS)) - if (!(elName.equals(KEYWORD_CREATED) || elName.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: and Consumers shall consider a document element that violates this constraint to be an error."); - - // Rule M4.4 - if (el.getAttributeNodeNS(XMLConstants.XML_NS_URI, "lang") != 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.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS)) { - // DCTerms namespace only use with 'created' and 'modified' elements - 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 - Attr typeAtt = el.getAttributeNodeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"); - if (typeAtt == null) - throw new InvalidFormatException("The element '" + elName - + "' must have the 'xsi:type' attribute present !"); - - // Check for the attribute value => 'dcterms:W3CDTF' - if (!typeAtt.getValue().equals(el.getPrefix() + ":W3CDTF")) - throw new InvalidFormatException("The element '" + elName - + "' must have the 'xsi:type' attribute with the value '" + el.getPrefix() + ":W3CDTF', but had '" + typeAtt.getValue() + "' !"); - } - - // Check its children - NodeList childElements = el.getElementsByTagName("*"); - int childElementCount = childElements.getLength(); - for (int i = 0; i < childElementCount; i++) - checkElementForOPCCompliance((Element)childElements.item(i)); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/UnmarshallContext.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/UnmarshallContext.java deleted file mode 100644 index c4e01ca7a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/UnmarshallContext.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util.zip.ZipEntry; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePartName; - -/** - * Context needed for the unmarshall process of a part. This class is immutable. - * - * @author Julien Chable - * @version 1.0 - */ -public final class UnmarshallContext { - - private OPCPackage _package; - - private PackagePartName partName; - - private ZipEntry zipEntry; - - /** - * Constructor. - * - * @param targetPackage - * Container. - * @param partName - * Name of the part to unmarshall. - */ - public UnmarshallContext(OPCPackage targetPackage, PackagePartName partName) { - this._package = targetPackage; - this.partName = partName; - } - - /** - * @return the container - */ - OPCPackage getPackage() { - return _package; - } - - /** - * @param container - * the container to set - */ - public void setPackage(OPCPackage container) { - this._package = container; - } - - /** - * @return the partName - */ - PackagePartName getPartName() { - return partName; - } - - /** - * @param partName - * the partName to set - */ - public void setPartName(PackagePartName partName) { - this.partName = partName; - } - - /** - * @return the zipEntry - */ - ZipEntry getZipEntry() { - return zipEntry; - } - - /** - * @param zipEntry - * the zipEntry to set - */ - public void setZipEntry(ZipEntry zipEntry) { - this.zipEntry = zipEntry; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java deleted file mode 100644 index 8c1a24c86..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 { - - 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 true if the nullable store a value (empty string is - * considered to be a value) else false. - */ - public boolean hasValue() { - return value != null; - } - - /** - * Set the stored value to null. - */ - public void nullify() { - value = null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java deleted file mode 100644 index 8ce82325c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.zip.ZipEntry; - -/** - * An Interface to make getting the different bits - * of a Zip File easy. - * Allows you to get at the ZipEntries, without - * needing to worry about ZipFile vs ZipInputStream - * being annoyingly very different. - */ -public interface ZipEntrySource extends Closeable { - /** - * Returns an Enumeration of all the Entries - */ - public Enumeration getEntries(); - - /** - * Returns an InputStream of the decompressed - * data that makes up the entry - */ - public InputStream getInputStream(ZipEntry entry) throws IOException; - - /** - * Indicates we are done with reading, and - * resources may be freed - */ - @Override - public void close() throws IOException; - - /** - * Has close been called already? - */ - public boolean isClosed(); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java deleted file mode 100644 index 09317d361..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * A ZipEntrySource wrapper around a ZipFile. - * Should be as low in terms of memory as a - * normal ZipFile implementation is. - */ -public class ZipFileZipEntrySource implements ZipEntrySource { - private ZipFile zipArchive; - public ZipFileZipEntrySource(ZipFile zipFile) { - this.zipArchive = zipFile; - } - - public void close() throws IOException { - if(zipArchive != null) { - zipArchive.close(); - } - zipArchive = null; - } - public boolean isClosed() { - return (zipArchive == null); - } - - public Enumeration getEntries() { - if (zipArchive == null) - throw new IllegalStateException("Zip File is closed"); - - return zipArchive.entries(); - } - - public InputStream getInputStream(ZipEntry entry) throws IOException { - if (zipArchive == null) - throw new IllegalStateException("Zip File is closed"); - - return zipArchive.getInputStream(entry); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java deleted file mode 100644 index 4c2b9df3e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.zip.ZipEntry; - -import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream; - -/** - * Provides a way to get at all the ZipEntries - * from a ZipInputStream, as many times as required. - * Allows a ZipInputStream to be treated much like - * a ZipFile, for a price in terms of memory. - * Be sure to call {@link #close()} as soon as you're - * done, to free up that memory! - */ -public class ZipInputStreamZipEntrySource implements ZipEntrySource { - private ArrayList zipEntries; - - /** - * Reads all the entries from the ZipInputStream - * into memory, and closes the source stream. - * We'll then eat lots of memory, but be able to - * work with the entries at-will. - */ - public ZipInputStreamZipEntrySource(ThresholdInputStream inp) throws IOException { - zipEntries = new ArrayList(); - - boolean going = true; - while(going) { - ZipEntry zipEntry = inp.getNextEntry(); - if(zipEntry == null) { - going = false; - } else { - FakeZipEntry entry = new FakeZipEntry(zipEntry, inp); - inp.closeEntry(); - - zipEntries.add(entry); - } - } - inp.close(); - } - - public Enumeration getEntries() { - return new EntryEnumerator(); - } - - public InputStream getInputStream(ZipEntry zipEntry) { - assert (zipEntry instanceof FakeZipEntry); - FakeZipEntry entry = (FakeZipEntry)zipEntry; - return entry.getInputStream(); - } - - public void close() { - // Free the memory - zipEntries = null; - } - public boolean isClosed() { - return (zipEntries == null); - } - - /** - * Why oh why oh why are Iterator and Enumeration - * still not compatible? - */ - private class EntryEnumerator implements Enumeration { - private Iterator iterator; - - private EntryEnumerator() { - iterator = zipEntries.iterator(); - } - - public boolean hasMoreElements() { - return iterator.hasNext(); - } - - public ZipEntry nextElement() { - return iterator.next(); - } - } - - /** - * So we can close the real zip entry and still - * effectively work with it. - * Holds the (decompressed!) data in memory, so - * close this as soon as you can! - */ - public static class FakeZipEntry extends ZipEntry { - private byte[] data; - - public FakeZipEntry(ZipEntry entry, InputStream inp) throws IOException { - super(entry.getName()); - - // Grab the de-compressed contents for later - ByteArrayOutputStream baos; - - long entrySize = entry.getSize(); - - if (entrySize !=-1) { - if (entrySize>=Integer.MAX_VALUE) { - throw new IOException("ZIP entry size is too large"); - } - - baos = new ByteArrayOutputStream((int) entrySize); - } else { - baos = new ByteArrayOutputStream(); - } - - byte[] buffer = new byte[4096]; - int read = 0; - while( (read = inp.read(buffer)) != -1 ) { - baos.write(buffer, 0, read); - } - - data = baos.toByteArray(); - } - - public InputStream getInputStream() { - return new ByteArrayInputStream(data); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java b/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java deleted file mode 100644 index 9000656e5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java +++ /dev/null @@ -1,309 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.File; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.zip.InflaterInputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.SuppressForbidden; - -/** - * This class wraps a {@link ZipFile} in order to check the - * entries for zip bombs - * while reading the archive. - * If a {@link ZipInputStream} is directly used, the wrapper - * can be applied via {@link #addThreshold(InputStream)}. - * The alert limits can be globally defined via {@link #setMaxEntrySize(long)} - * and {@link #setMinInflateRatio(double)}. - */ -public class ZipSecureFile extends ZipFile { - private static POILogger logger = POILogFactory.getLogger(ZipSecureFile.class); - - private static double MIN_INFLATE_RATIO = 0.01d; - private static long MAX_ENTRY_SIZE = 0xFFFFFFFFL; - - // don't alert for expanded sizes smaller than 100k - private final static long GRACE_ENTRY_SIZE = 100*1024; - - // The default maximum size of extracted text - private static long MAX_TEXT_SIZE = 10*1024*1024; - - /** - * Sets the ratio between de- and inflated bytes to detect zipbomb. - * It defaults to 1% (= 0.01d), i.e. when the compression is better than - * 1% for any given read package part, the parsing will fail indicating a - * Zip-Bomb. - * - * @param ratio the ratio between de- and inflated bytes to detect zipbomb - */ - public static void setMinInflateRatio(double ratio) { - MIN_INFLATE_RATIO = ratio; - } - - /** - * Returns the current minimum compression rate that is used. - * - * See setMinInflateRatio() for details. - * - * @return The min accepted compression-ratio. - */ - public static double getMinInflateRatio() { - return MIN_INFLATE_RATIO; - } - - /** - * Sets the maximum file size of a single zip entry. It defaults to 4GB, - * i.e. the 32-bit zip format maximum. - * - * This can be used to limit memory consumption and protect against - * security vulnerabilities when documents are provided by users. - * - * @param maxEntrySize the max. file size of a single zip entry - */ - public static void setMaxEntrySize(long maxEntrySize) { - if (maxEntrySize < 0 || maxEntrySize > 0xFFFFFFFFL) { // don't use MAX_ENTRY_SIZE here! - throw new IllegalArgumentException("Max entry size is bounded [0-4GB], but had " + maxEntrySize); - } - MAX_ENTRY_SIZE = maxEntrySize; - } - - /** - * Returns the current maximum allowed uncompressed file size. - * - * See setMaxEntrySize() for details. - * - * @return The max accepted uncompressed file size. - */ - public static long getMaxEntrySize() { - return MAX_ENTRY_SIZE; - } - - /** - * Sets the maximum number of characters of text that are - * extracted before an exception is thrown during extracting - * text from documents. - * - * This can be used to limit memory consumption and protect against - * security vulnerabilities when documents are provided by users. - * - * @param maxTextSize the max. file size of a single zip entry - */ - public static void setMaxTextSize(long maxTextSize) { - if (maxTextSize < 0 || maxTextSize > 0xFFFFFFFFL) { // don't use MAX_ENTRY_SIZE here! - throw new IllegalArgumentException("Max text size is bounded [0-4GB], but had " + maxTextSize); - } - MAX_TEXT_SIZE = maxTextSize; - } - - /** - * Returns the current maximum allowed text size. - * - * See setMaxTextSize() for details. - * - * @return The max accepted text size. - */ - public static long getMaxTextSize() { - return MAX_TEXT_SIZE; - } - - public ZipSecureFile(File file, int mode) throws ZipException, IOException { - super(file, mode); - } - - public ZipSecureFile(File file) throws ZipException, IOException { - super(file); - } - - public ZipSecureFile(String name) throws ZipException, IOException { - super(name); - } - - /** - * Returns an input stream for reading the contents of the specified - * zip file entry. - * - *

        Closing this ZIP file will, in turn, close all input - * streams that have been returned by invocations of this method. - * - * @param entry the zip file entry - * @return the input stream for reading the contents of the specified - * zip file entry. - * @throws ZipException if a ZIP format error has occurred - * @throws IOException if an I/O error has occurred - * @throws IllegalStateException if the zip file has been closed - */ - @SuppressWarnings("resource") - public InputStream getInputStream(ZipEntry entry) throws IOException { - InputStream zipIS = super.getInputStream(entry); - return addThreshold(zipIS); - } - - public static ThresholdInputStream addThreshold(final InputStream zipIS) throws IOException { - ThresholdInputStream newInner; - if (zipIS instanceof InflaterInputStream) { - newInner = AccessController.doPrivileged(new PrivilegedAction() { - @SuppressForbidden("TODO: Fix this to not use reflection (it will break in Java 9)! " + - "Better would be to wrap *before* instead of tyring to insert wrapper afterwards.") - public ThresholdInputStream run() { - try { - Field f = FilterInputStream.class.getDeclaredField("in"); - f.setAccessible(true); - InputStream oldInner = (InputStream)f.get(zipIS); - ThresholdInputStream newInner = new ThresholdInputStream(oldInner, null); - f.set(zipIS, newInner); - return newInner; - } catch (Exception ex) { - logger.log(POILogger.WARN, "SecurityManager doesn't allow manipulation via reflection for zipbomb detection - continue with original input stream", ex); - } - return null; - } - }); - } else { - // the inner stream is a ZipFileInputStream, i.e. the data wasn't compressed - newInner = null; - } - - return new ThresholdInputStream(zipIS, newInner); - } - - public static class ThresholdInputStream extends PushbackInputStream { - long counter = 0; - ThresholdInputStream cis; - - public ThresholdInputStream(InputStream is, ThresholdInputStream cis) { - super(is,1); - this.cis = cis; - } - - public int read() throws IOException { - int b = in.read(); - if (b > -1) advance(1); - return b; - } - - public int read(byte b[], int off, int len) throws IOException { - int cnt = in.read(b, off, len); - if (cnt > -1) advance(cnt); - return cnt; - - } - - public long skip(long n) throws IOException { - counter = 0; - return in.skip(n); - } - - public synchronized void reset() throws IOException { - counter = 0; - in.reset(); - } - - public void advance(int advance) throws IOException { - counter += advance; - - // check the file size first, in case we are working on uncompressed streams - if(counter > MAX_ENTRY_SIZE) { - throw new IOException("Zip bomb detected! The file would exceed the max size of the expanded data in the zip-file. " - + "This may indicates that the file is used to inflate memory usage and thus could pose a security risk. " - + "You can adjust this limit via ZipSecureFile.setMaxEntrySize() if you need to work with files which are very large. " - + "Counter: " + counter + ", cis.counter: " + (cis == null ? 0 : cis.counter) - + "Limits: MAX_ENTRY_SIZE: " + MAX_ENTRY_SIZE); - } - - // no expanded size? - if (cis == null) { - return; - } - - // don't alert for small expanded size - if (counter <= GRACE_ENTRY_SIZE) { - return; - } - - double ratio = (double)cis.counter/(double)counter; - if (ratio >= MIN_INFLATE_RATIO) { - return; - } - - // one of the limits was reached, report it - throw new IOException("Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data. " - + "This may indicate that the file is used to inflate memory usage and thus could pose a security risk. " - + "You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit. " - + "Counter: " + counter + ", cis.counter: " + cis.counter + ", ratio: " + (((double)cis.counter)/counter) - + "Limits: MIN_INFLATE_RATIO: " + MIN_INFLATE_RATIO); - } - - public ZipEntry getNextEntry() throws IOException { - if (!(in instanceof ZipInputStream)) { - throw new UnsupportedOperationException("underlying stream is not a ZipInputStream"); - } - counter = 0; - return ((ZipInputStream)in).getNextEntry(); - } - - public void closeEntry() throws IOException { - if (!(in instanceof ZipInputStream)) { - throw new UnsupportedOperationException("underlying stream is not a ZipInputStream"); - } - counter = 0; - ((ZipInputStream)in).closeEntry(); - } - - public void unread(int b) throws IOException { - if (!(in instanceof PushbackInputStream)) { - throw new UnsupportedOperationException("underlying stream is not a PushbackInputStream"); - } - if (--counter < 0) counter = 0; - ((PushbackInputStream)in).unread(b); - } - - public void unread(byte[] b, int off, int len) throws IOException { - if (!(in instanceof PushbackInputStream)) { - throw new UnsupportedOperationException("underlying stream is not a PushbackInputStream"); - } - counter -= len; - if (--counter < 0) counter = 0; - ((PushbackInputStream)in).unread(b, off, len); - } - - public int available() throws IOException { - return in.available(); - } - - public boolean markSupported() { - return in.markSupported(); - } - - public synchronized void mark(int readlimit) { - in.mark(readlimit); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java deleted file mode 100644 index 0263790df..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java +++ /dev/null @@ -1,356 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt.agile; - -import static org.apache.poi.poifs.crypt.CryptoFunctions.generateIv; -import static org.apache.poi.poifs.crypt.CryptoFunctions.generateKey; -import static org.apache.poi.poifs.crypt.CryptoFunctions.getBlock0; -import static org.apache.poi.poifs.crypt.CryptoFunctions.getCipher; -import static org.apache.poi.poifs.crypt.CryptoFunctions.getMessageDigest; -import static org.apache.poi.poifs.crypt.CryptoFunctions.hashPassword; - -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.MessageDigest; -import java.security.cert.X509Certificate; -import java.security.spec.AlgorithmParameterSpec; -import java.util.Arrays; - -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.RC2ParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionHeader; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier.AgileCertificateEntry; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.util.LittleEndian; - -/** - * Decryptor implementation for Agile Encryption - */ -public class AgileDecryptor extends Decryptor implements Cloneable { - private long _length = -1; - - /* package */ static final byte[] kVerifierInputBlock; - /* package */ static final byte[] kHashedVerifierBlock; - /* package */ static final byte[] kCryptoKeyBlock; - /* package */ static final byte[] kIntegrityKeyBlock; - /* package */ static final byte[] kIntegrityValueBlock; - - static { - kVerifierInputBlock = - new byte[] { (byte)0xfe, (byte)0xa7, (byte)0xd2, (byte)0x76, - (byte)0x3b, (byte)0x4b, (byte)0x9e, (byte)0x79 }; - kHashedVerifierBlock = - new byte[] { (byte)0xd7, (byte)0xaa, (byte)0x0f, (byte)0x6d, - (byte)0x30, (byte)0x61, (byte)0x34, (byte)0x4e }; - kCryptoKeyBlock = - new byte[] { (byte)0x14, (byte)0x6e, (byte)0x0b, (byte)0xe7, - (byte)0xab, (byte)0xac, (byte)0xd0, (byte)0xd6 }; - kIntegrityKeyBlock = - new byte[] { (byte)0x5f, (byte)0xb2, (byte)0xad, (byte)0x01, - (byte)0x0c, (byte)0xb9, (byte)0xe1, (byte)0xf6 }; - kIntegrityValueBlock = - new byte[] { (byte)0xa0, (byte)0x67, (byte)0x7f, (byte)0x02, - (byte)0xb2, (byte)0x2c, (byte)0x84, (byte)0x33 }; - } - - protected AgileDecryptor() { - } - - /** - * set decryption password - */ - @Override - public boolean verifyPassword(String password) throws GeneralSecurityException { - AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - - int blockSize = header.getBlockSize(); - - byte[] pwHash = hashPassword(password, ver.getHashAlgorithm(), ver.getSalt(), ver.getSpinCount()); - - /** - * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps: - * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize - * attribute. - * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password, - * the binary byte array used to create the saltValue attribute, and a blockKey byte array - * consisting of the following bytes: 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, and 0x79. - * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue - * attribute as an initialization vector as specified in section 2.3.4.12. If the array of bytes is not an - * integral multiple of blockSize bytes, pad the array with 0x00 to the next integral multiple of - * blockSize bytes. - * 4. Use base64 to encode the result of step 3. - */ - byte verfierInputEnc[] = hashInput(ver, pwHash, kVerifierInputBlock, ver.getEncryptedVerifier(), Cipher.DECRYPT_MODE); - setVerifier(verfierInputEnc); - MessageDigest hashMD = getMessageDigest(ver.getHashAlgorithm()); - byte[] verifierHash = hashMD.digest(verfierInputEnc); - - /** - * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps: - * 1. Obtain the hash value of the random array of bytes generated in step 1 of the steps for - * encryptedVerifierHashInput. - * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password, - * the binary byte array used to create the saltValue attribute, and a blockKey byte array - * consisting of the following bytes: 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, and 0x4e. - * 3. Encrypt the hash value obtained in step 1 by using the binary form of the saltValue attribute as - * an initialization vector as specified in section 2.3.4.12. If hashSize is not an integral multiple of - * blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes. - * 4. Use base64 to encode the result of step 3. - */ - byte verifierHashDec[] = hashInput(ver, pwHash, kHashedVerifierBlock, ver.getEncryptedVerifierHash(), Cipher.DECRYPT_MODE); - verifierHashDec = getBlock0(verifierHashDec, ver.getHashAlgorithm().hashSize); - - /** - * encryptedKeyValue: This attribute MUST be generated by using the following steps: - * 1. Generate a random array of bytes that is the same size as specified by the - * Encryptor.KeyData.keyBits attribute of the parent element. - * 2. Generate an encryption key as specified in section 2.3.4.11, using the user-supplied password, - * the binary byte array used to create the saltValue attribute, and a blockKey byte array - * consisting of the following bytes: 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, and 0xd6. - * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue - * attribute as an initialization vector as specified in section 2.3.4.12. If the array of bytes is not an - * integral multiple of blockSize bytes, pad the array with 0x00 to an integral multiple of - * blockSize bytes. - * 4. Use base64 to encode the result of step 3. - */ - byte keyspec[] = hashInput(ver, pwHash, kCryptoKeyBlock, ver.getEncryptedKey(), Cipher.DECRYPT_MODE); - keyspec = getBlock0(keyspec, header.getKeySize()/8); - SecretKeySpec secretKey = new SecretKeySpec(keyspec, header.getCipherAlgorithm().jceId); - - /** - * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor - * contained within the KeyEncryptors sequence. Use this key for encryption operations in the - * remaining steps of this section. - * 2. Generate a random array of bytes, known as Salt, of the same length as the value of the - * KeyData.hashSize attribute. - * 3. Encrypt the random array of bytes generated in step 2 by using the binary form of the - * KeyData.saltValue attribute and a blockKey byte array consisting of the following bytes: 0x5f, - * 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, and 0xf6 used to form an initialization vector as specified in - * section 2.3.4.12. If the array of bytes is not an integral multiple of blockSize bytes, pad the - * array with 0x00 to the next integral multiple of blockSize bytes. - * 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3. - */ - byte vec[] = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityKeyBlock, blockSize); - CipherAlgorithm cipherAlgo = header.getCipherAlgorithm(); - Cipher cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE); - byte hmacKey[] = cipher.doFinal(header.getEncryptedHmacKey()); - hmacKey = getBlock0(hmacKey, header.getHashAlgorithm().hashSize); - - /** - * 5. Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message), - * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key. - * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be - * used as the message. - * 6. Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes: - * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33. - * 7. Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6. - */ - vec = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityValueBlock, blockSize); - cipher = getCipher(secretKey, cipherAlgo, ver.getChainingMode(), vec, Cipher.DECRYPT_MODE); - byte hmacValue[] = cipher.doFinal(header.getEncryptedHmacValue()); - hmacValue = getBlock0(hmacValue, header.getHashAlgorithm().hashSize); - - if (Arrays.equals(verifierHashDec, verifierHash)) { - setSecretKey(secretKey); - setIntegrityHmacKey(hmacKey); - setIntegrityHmacValue(hmacValue); - return true; - } else { - return false; - } - } - - /** - * instead of a password, it's also possible to decrypt via certificate. - * Warning: this code is experimental and hasn't been validated - * - * @see Agile encryption with certificates - * - * @param keyPair - * @param x509 - * @return true, when the data can be successfully decrypted with the given private key - * @throws GeneralSecurityException - */ - public boolean verifyPassword(KeyPair keyPair, X509Certificate x509) throws GeneralSecurityException { - AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - HashAlgorithm hashAlgo = header.getHashAlgorithm(); - CipherAlgorithm cipherAlgo = header.getCipherAlgorithm(); - int blockSize = header.getBlockSize(); - - AgileCertificateEntry ace = null; - for (AgileCertificateEntry aceEntry : ver.getCertificates()) { - if (x509.equals(aceEntry.x509)) { - ace = aceEntry; - break; - } - } - if (ace == null) { - return false; - } - - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); - byte keyspec[] = cipher.doFinal(ace.encryptedKey); - SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.getCipherAlgorithm().jceId); - - Mac x509Hmac = CryptoFunctions.getMac(hashAlgo); - x509Hmac.init(secretKey); - byte certVerifier[] = x509Hmac.doFinal(ace.x509.getEncoded()); - - byte vec[] = CryptoFunctions.generateIv(hashAlgo, header.getKeySalt(), kIntegrityKeyBlock, blockSize); - cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE); - byte hmacKey[] = cipher.doFinal(header.getEncryptedHmacKey()); - hmacKey = getBlock0(hmacKey, hashAlgo.hashSize); - - vec = CryptoFunctions.generateIv(hashAlgo, header.getKeySalt(), kIntegrityValueBlock, blockSize); - cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE); - byte hmacValue[] = cipher.doFinal(header.getEncryptedHmacValue()); - hmacValue = getBlock0(hmacValue, hashAlgo.hashSize); - - - if (Arrays.equals(ace.certVerifier, certVerifier)) { - setSecretKey(secretKey); - setIntegrityHmacKey(hmacKey); - setIntegrityHmacValue(hmacValue); - return true; - } else { - return false; - } - } - - protected static int getNextBlockSize(int inputLen, int blockSize) { - int fillSize; - for (fillSize=blockSize; fillSize certList = new ArrayList(); - private int keyBits = -1; - private int blockSize = -1; - - public AgileEncryptionVerifier(String descriptor) { - this(AgileEncryptionInfoBuilder.parseDescriptor(descriptor)); - } - - protected AgileEncryptionVerifier(EncryptionDocument ed) { - Iterator encList = ed.getEncryption().getKeyEncryptors().getKeyEncryptorList().iterator(); - CTPasswordKeyEncryptor keyData; - try { - keyData = encList.next().getEncryptedPasswordKey(); - if (keyData == null) { - throw new NullPointerException("encryptedKey not set"); - } - } catch (Exception e) { - throw new EncryptedDocumentException("Unable to parse keyData", e); - } - - int kb = (int)keyData.getKeyBits(); - CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), kb); - setCipherAlgorithm(ca); - - setKeySize(kb); - - int blockSize = keyData.getBlockSize(); - setBlockSize(blockSize); - - int hashSize = keyData.getHashSize(); - - HashAlgorithm ha = HashAlgorithm.fromEcmaId(keyData.getHashAlgorithm().toString()); - setHashAlgorithm(ha); - - if (getHashAlgorithm().hashSize != hashSize) { - throw new EncryptedDocumentException("Unsupported hash algorithm: " + - keyData.getHashAlgorithm() + " @ " + hashSize + " bytes"); - } - - setSpinCount(keyData.getSpinCount()); - setEncryptedVerifier(keyData.getEncryptedVerifierHashInput()); - setSalt(keyData.getSaltValue()); - setEncryptedKey(keyData.getEncryptedKeyValue()); - setEncryptedVerifierHash(keyData.getEncryptedVerifierHashValue()); - - int saltSize = keyData.getSaltSize(); - if (saltSize != getSalt().length) { - throw new EncryptedDocumentException("Invalid salt size"); - } - - switch (keyData.getCipherChaining().intValue()) { - case STCipherChaining.INT_CHAINING_MODE_CBC: - setChainingMode(ChainingMode.cbc); - break; - case STCipherChaining.INT_CHAINING_MODE_CFB: - setChainingMode(ChainingMode.cfb); - break; - default: - throw new EncryptedDocumentException("Unsupported chaining mode - "+keyData.getCipherChaining().toString()); - } - - if (!encList.hasNext()) { - return; - } - - try { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - while (encList.hasNext()) { - CTCertificateKeyEncryptor certKey = encList.next().getEncryptedCertificateKey(); - AgileCertificateEntry ace = new AgileCertificateEntry(); - ace.certVerifier = certKey.getCertVerifier(); - ace.encryptedKey = certKey.getEncryptedKeyValue(); - ace.x509 = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(certKey.getX509Certificate())); - certList.add(ace); - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException("can't parse X509 certificate", e); - } - } - - public AgileEncryptionVerifier(CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode) { - setCipherAlgorithm(cipherAlgorithm); - setHashAlgorithm(hashAlgorithm); - setChainingMode(chainingMode); - setKeySize(keyBits); - setBlockSize(blockSize); - setSpinCount(100000); // TODO: use parameter - } - - @Override - protected void setSalt(byte salt[]) { - if (salt == null || salt.length != getCipherAlgorithm().blockSize) { - throw new EncryptedDocumentException("invalid verifier salt"); - } - super.setSalt(salt); - } - - // make method visible for this package - @Override - protected void setEncryptedVerifier(byte encryptedVerifier[]) { - super.setEncryptedVerifier(encryptedVerifier); - } - - // make method visible for this package - @Override - protected void setEncryptedVerifierHash(byte encryptedVerifierHash[]) { - super.setEncryptedVerifierHash(encryptedVerifierHash); - } - - // make method visible for this package - @Override - protected void setEncryptedKey(byte[] encryptedKey) { - super.setEncryptedKey(encryptedKey); - } - - public void addCertificate(X509Certificate x509) { - AgileCertificateEntry ace = new AgileCertificateEntry(); - ace.x509 = x509; - certList.add(ace); - } - - public List getCertificates() { - return certList; - } - - @Override - public AgileEncryptionVerifier clone() throws CloneNotSupportedException { - AgileEncryptionVerifier other = (AgileEncryptionVerifier)super.clone(); - // TODO: deep copy of certList - other.certList = new ArrayList(certList); - return other; - } - - - /** - * The keysize (in bits) of the verifier data. This usually equals the keysize of the header, - * but only on a few exceptions, like files generated by Office for Mac, can be - * different. - * - * @return the keysize (in bits) of the verifier. - */ - public int getKeySize() { - return keyBits; - } - - - /** - * The blockSize (in bytes) of the verifier data. - * This usually equals the blocksize of the header. - * - * @return the blockSize (in bytes) of the verifier, - */ - public int getBlockSize() { - return blockSize; - } - - /** - * Sets the keysize (in bits) of the verifier - * - * @param keyBits the keysize (in bits) - */ - protected void setKeySize(int keyBits) { - this.keyBits = keyBits; - for (int allowedBits : getCipherAlgorithm().allowedKeySize) { - if (allowedBits == keyBits) { - return; - } - } - throw new EncryptedDocumentException("KeySize "+keyBits+" not allowed for cipher "+getCipherAlgorithm()); - } - - - /** - * Sets the blockSize (in bytes) of the verifier - * - * @param blockSize the blockSize (in bytes) - */ - protected void setBlockSize(int blockSize) { - this.blockSize = blockSize; - } - - @Override - protected final void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) { - super.setCipherAlgorithm(cipherAlgorithm); - if (cipherAlgorithm.allowedKeySize.length == 1) { - setKeySize(cipherAlgorithm.defaultKeySize); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java deleted file mode 100644 index 96aa9b5f9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java +++ /dev/null @@ -1,460 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt.agile; - -import static org.apache.poi.poifs.crypt.CryptoFunctions.getBlock0; -import static org.apache.poi.poifs.crypt.CryptoFunctions.getCipher; -import static org.apache.poi.poifs.crypt.CryptoFunctions.getMessageDigest; -import static org.apache.poi.poifs.crypt.CryptoFunctions.hashPassword; -import static org.apache.poi.poifs.crypt.DataSpaceMapUtils.createEncryptionEntry; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.getNextBlockSize; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.hashInput; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kCryptoKeyBlock; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kHashedVerifierBlock; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kIntegrityKeyBlock; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kIntegrityValueBlock; -import static org.apache.poi.poifs.crypt.agile.AgileDecryptor.kVerifierInputBlock; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.security.cert.CertificateEncodingException; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.DataSpaceMapUtils; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier.AgileCertificateEntry; -import org.apache.poi.poifs.crypt.standard.EncryptionRecord; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.xmlbeans.XmlOptions; - -import com.microsoft.schemas.office.x2006.encryption.CTDataIntegrity; -import com.microsoft.schemas.office.x2006.encryption.CTEncryption; -import com.microsoft.schemas.office.x2006.encryption.CTKeyData; -import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor; -import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptors; -import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument; -import com.microsoft.schemas.office.x2006.encryption.STCipherAlgorithm; -import com.microsoft.schemas.office.x2006.encryption.STCipherChaining; -import com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm; -import com.microsoft.schemas.office.x2006.keyEncryptor.certificate.CTCertificateKeyEncryptor; -import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor; - -public class AgileEncryptor extends Encryptor implements Cloneable { - private byte integritySalt[]; - private byte pwHash[]; - - protected AgileEncryptor() { - } - - @Override - public void confirmPassword(String password) { - // see [MS-OFFCRYPTO] - 2.3.3 EncryptionVerifier - Random r = new SecureRandom(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - int blockSize = header.getBlockSize(); - int keySize = header.getKeySize()/8; - int hashSize = header.getHashAlgorithm().hashSize; - - byte[] newVerifierSalt = new byte[blockSize] - , newVerifier = new byte[blockSize] - , newKeySalt = new byte[blockSize] - , newKeySpec = new byte[keySize] - , newIntegritySalt = new byte[hashSize]; - r.nextBytes(newVerifierSalt); // blocksize - r.nextBytes(newVerifier); // blocksize - r.nextBytes(newKeySalt); // blocksize - r.nextBytes(newKeySpec); // keysize - r.nextBytes(newIntegritySalt); // hashsize - - confirmPassword(password, newKeySpec, newKeySalt, newVerifierSalt, newVerifier, newIntegritySalt); - } - - @Override - public void confirmPassword(String password, byte keySpec[], byte keySalt[], byte verifier[], byte verifierSalt[], byte integritySalt[]) { - AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - - ver.setSalt(verifierSalt); - header.setKeySalt(keySalt); - - int blockSize = header.getBlockSize(); - - pwHash = hashPassword(password, ver.getHashAlgorithm(), verifierSalt, ver.getSpinCount()); - - /** - * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps: - * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize - * attribute. - * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password, - * the binary byte array used to create the saltValue attribute, and a blockKey byte array - * consisting of the following bytes: 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, and 0x79. - * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue - * attribute as an initialization vector as specified in section 2.3.4.12. If the array of bytes is not an - * integral multiple of blockSize bytes, pad the array with 0x00 to the next integral multiple of - * blockSize bytes. - * 4. Use base64 to encode the result of step 3. - */ - byte encryptedVerifier[] = hashInput(ver, pwHash, kVerifierInputBlock, verifier, Cipher.ENCRYPT_MODE); - ver.setEncryptedVerifier(encryptedVerifier); - - - /** - * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps: - * 1. Obtain the hash value of the random array of bytes generated in step 1 of the steps for - * encryptedVerifierHashInput. - * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password, - * the binary byte array used to create the saltValue attribute, and a blockKey byte array - * consisting of the following bytes: 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, and 0x4e. - * 3. Encrypt the hash value obtained in step 1 by using the binary form of the saltValue attribute as - * an initialization vector as specified in section 2.3.4.12. If hashSize is not an integral multiple of - * blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes. - * 4. Use base64 to encode the result of step 3. - */ - MessageDigest hashMD = getMessageDigest(ver.getHashAlgorithm()); - byte[] hashedVerifier = hashMD.digest(verifier); - byte encryptedVerifierHash[] = hashInput(ver, pwHash, kHashedVerifierBlock, hashedVerifier, Cipher.ENCRYPT_MODE); - ver.setEncryptedVerifierHash(encryptedVerifierHash); - - /** - * encryptedKeyValue: This attribute MUST be generated by using the following steps: - * 1. Generate a random array of bytes that is the same size as specified by the - * Encryptor.KeyData.keyBits attribute of the parent element. - * 2. Generate an encryption key as specified in section 2.3.4.11, using the user-supplied password, - * the binary byte array used to create the saltValue attribute, and a blockKey byte array - * consisting of the following bytes: 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, and 0xd6. - * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue - * attribute as an initialization vector as specified in section 2.3.4.12. If the array of bytes is not an - * integral multiple of blockSize bytes, pad the array with 0x00 to an integral multiple of - * blockSize bytes. - * 4. Use base64 to encode the result of step 3. - */ - byte encryptedKey[] = hashInput(ver, pwHash, kCryptoKeyBlock, keySpec, Cipher.ENCRYPT_MODE); - ver.setEncryptedKey(encryptedKey); - - SecretKey secretKey = new SecretKeySpec(keySpec, header.getCipherAlgorithm().jceId); - setSecretKey(secretKey); - - /* - * 2.3.4.14 DataIntegrity Generation (Agile Encryption) - * - * The DataIntegrity element contained within an Encryption element MUST be generated by using - * the following steps: - * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor - * contained within the KeyEncryptors sequence. Use this key for encryption operations in the - * remaining steps of this section. - * 2. Generate a random array of bytes, known as Salt, of the same length as the value of the - * KeyData.hashSize attribute. - * 3. Encrypt the random array of bytes generated in step 2 by using the binary form of the - * KeyData.saltValue attribute and a blockKey byte array consisting of the following bytes: - * 0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, and 0xf6 used to form an initialization vector as - * specified in section 2.3.4.12. If the array of bytes is not an integral multiple of blockSize - * bytes, pad the array with 0x00 to the next integral multiple of blockSize bytes. - * 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3. - * 5. Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message), - * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key. - * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be - * used as the message. - * 6. Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes: - * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33. - * 7. Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6. - */ - this.integritySalt = integritySalt.clone(); - - try { - byte vec[] = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityKeyBlock, header.getBlockSize()); - Cipher cipher = getCipher(secretKey, header.getCipherAlgorithm(), header.getChainingMode(), vec, Cipher.ENCRYPT_MODE); - byte hmacKey[] = getBlock0(this.integritySalt, getNextBlockSize(this.integritySalt.length, blockSize)); - byte encryptedHmacKey[] = cipher.doFinal(hmacKey); - header.setEncryptedHmacKey(encryptedHmacKey); - - cipher = Cipher.getInstance("RSA"); - for (AgileCertificateEntry ace : ver.getCertificates()) { - cipher.init(Cipher.ENCRYPT_MODE, ace.x509.getPublicKey()); - ace.encryptedKey = cipher.doFinal(getSecretKey().getEncoded()); - Mac x509Hmac = CryptoFunctions.getMac(header.getHashAlgorithm()); - x509Hmac.init(getSecretKey()); - ace.certVerifier = x509Hmac.doFinal(ace.x509.getEncoded()); - } - } catch (GeneralSecurityException e) { - throw new EncryptedDocumentException(e); - } - } - - @Override - public OutputStream getDataStream(DirectoryNode dir) - throws IOException, GeneralSecurityException { - // TODO: initialize headers - AgileCipherOutputStream countStream = new AgileCipherOutputStream(dir); - return countStream; - } - - /** - * Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message), - * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key. - * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be - * used as the message. - * - * Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes: - * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33. - **/ - protected void updateIntegrityHMAC(File tmpFile, int oleStreamSize) throws GeneralSecurityException, IOException { - // as the integrity hmac needs to contain the StreamSize, - // it's not possible to calculate it on-the-fly while buffering - // TODO: add stream size parameter to getDataStream() - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - int blockSize = header.getBlockSize(); - HashAlgorithm hashAlgo = header.getHashAlgorithm(); - Mac integrityMD = CryptoFunctions.getMac(hashAlgo); - byte hmacKey[] = getBlock0(this.integritySalt, getNextBlockSize(this.integritySalt.length, blockSize)); - integrityMD.init(new SecretKeySpec(hmacKey, hashAlgo.jceHmacId)); - - byte buf[] = new byte[1024]; - LittleEndian.putLong(buf, 0, oleStreamSize); - integrityMD.update(buf, 0, LittleEndianConsts.LONG_SIZE); - - InputStream fis = new FileInputStream(tmpFile); - try { - int readBytes; - while ((readBytes = fis.read(buf)) != -1) { - integrityMD.update(buf, 0, readBytes); - } - } finally { - fis.close(); - } - - byte hmacValue[] = integrityMD.doFinal(); - byte hmacValueFilled[] = getBlock0(hmacValue, getNextBlockSize(hmacValue.length, blockSize)); - - byte iv[] = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityValueBlock, blockSize); - Cipher cipher = CryptoFunctions.getCipher(getSecretKey(), header.getCipherAlgorithm(), header.getChainingMode(), iv, Cipher.ENCRYPT_MODE); - byte encryptedHmacValue[] = cipher.doFinal(hmacValueFilled); - - header.setEncryptedHmacValue(encryptedHmacValue); - } - - private final CTKeyEncryptor.Uri.Enum passwordUri = - CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_PASSWORD; - private final CTKeyEncryptor.Uri.Enum certificateUri = - CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_CERTIFICATE; - - protected EncryptionDocument createEncryptionDocument() { - AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - - EncryptionDocument ed = EncryptionDocument.Factory.newInstance(); - CTEncryption edRoot = ed.addNewEncryption(); - - CTKeyData keyData = edRoot.addNewKeyData(); - CTKeyEncryptors keyEncList = edRoot.addNewKeyEncryptors(); - CTKeyEncryptor keyEnc = keyEncList.addNewKeyEncryptor(); - keyEnc.setUri(passwordUri); - CTPasswordKeyEncryptor keyPass = keyEnc.addNewEncryptedPasswordKey(); - - keyPass.setSpinCount(ver.getSpinCount()); - - keyData.setSaltSize(header.getBlockSize()); - keyPass.setSaltSize(ver.getBlockSize()); - - keyData.setBlockSize(header.getBlockSize()); - keyPass.setBlockSize(ver.getBlockSize()); - - keyData.setKeyBits(header.getKeySize()); - keyPass.setKeyBits(ver.getKeySize()); - - keyData.setHashSize(header.getHashAlgorithm().hashSize); - keyPass.setHashSize(ver.getHashAlgorithm().hashSize); - - // header and verifier have to have the same cipher algorithm - if (!header.getCipherAlgorithm().xmlId.equals(ver.getCipherAlgorithm().xmlId)) { - throw new EncryptedDocumentException("Cipher algorithm of header and verifier have to match"); - } - STCipherAlgorithm.Enum xmlCipherAlgo = STCipherAlgorithm.Enum.forString(header.getCipherAlgorithm().xmlId); - if (xmlCipherAlgo == null) { - throw new EncryptedDocumentException("CipherAlgorithm "+header.getCipherAlgorithm()+" not supported."); - } - keyData.setCipherAlgorithm(xmlCipherAlgo); - keyPass.setCipherAlgorithm(xmlCipherAlgo); - - switch (header.getChainingMode()) { - case cbc: - keyData.setCipherChaining(STCipherChaining.CHAINING_MODE_CBC); - keyPass.setCipherChaining(STCipherChaining.CHAINING_MODE_CBC); - break; - case cfb: - keyData.setCipherChaining(STCipherChaining.CHAINING_MODE_CFB); - keyPass.setCipherChaining(STCipherChaining.CHAINING_MODE_CFB); - break; - default: - throw new EncryptedDocumentException("ChainingMode "+header.getChainingMode()+" not supported."); - } - - keyData.setHashAlgorithm(mapHashAlgorithm(header.getHashAlgorithm())); - keyPass.setHashAlgorithm(mapHashAlgorithm(ver.getHashAlgorithm())); - - keyData.setSaltValue(header.getKeySalt()); - keyPass.setSaltValue(ver.getSalt()); - keyPass.setEncryptedVerifierHashInput(ver.getEncryptedVerifier()); - keyPass.setEncryptedVerifierHashValue(ver.getEncryptedVerifierHash()); - keyPass.setEncryptedKeyValue(ver.getEncryptedKey()); - - CTDataIntegrity hmacData = edRoot.addNewDataIntegrity(); - hmacData.setEncryptedHmacKey(header.getEncryptedHmacKey()); - hmacData.setEncryptedHmacValue(header.getEncryptedHmacValue()); - - for (AgileCertificateEntry ace : ver.getCertificates()) { - keyEnc = keyEncList.addNewKeyEncryptor(); - keyEnc.setUri(certificateUri); - CTCertificateKeyEncryptor certData = keyEnc.addNewEncryptedCertificateKey(); - try { - certData.setX509Certificate(ace.x509.getEncoded()); - } catch (CertificateEncodingException e) { - throw new EncryptedDocumentException(e); - } - certData.setEncryptedKeyValue(ace.encryptedKey); - certData.setCertVerifier(ace.certVerifier); - } - - return ed; - } - - private static STHashAlgorithm.Enum mapHashAlgorithm(HashAlgorithm hashAlgo) { - STHashAlgorithm.Enum xmlHashAlgo = STHashAlgorithm.Enum.forString(hashAlgo.ecmaString); - if (xmlHashAlgo == null) { - throw new EncryptedDocumentException("HashAlgorithm "+hashAlgo+" not supported."); - } - return xmlHashAlgo; - } - - protected void marshallEncryptionDocument(EncryptionDocument ed, LittleEndianByteArrayOutputStream os) { - XmlOptions xo = new XmlOptions(); - xo.setCharacterEncoding("UTF-8"); - Map nsMap = new HashMap(); - nsMap.put(passwordUri.toString(),"p"); - nsMap.put(certificateUri.toString(), "c"); - xo.setUseDefaultNamespace(); - xo.setSaveSuggestedPrefixes(nsMap); - xo.setSaveNamespacesFirst(); - xo.setSaveAggressiveNamespaces(); - - // setting standalone doesn't work with xmlbeans-2.3 & 2.6 - // ed.documentProperties().setStandalone(true); - xo.setSaveNoXmlDecl(); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - bos.write("\r\n".getBytes("UTF-8")); - ed.save(bos, xo); - bos.writeTo(os); - } catch (IOException e) { - throw new EncryptedDocumentException("error marshalling encryption info document", e); - } - } - - protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) - throws IOException, GeneralSecurityException { - DataSpaceMapUtils.addDefaultDataSpace(dir); - - final EncryptionInfo info = getEncryptionInfo(); - - EncryptionRecord er = new EncryptionRecord(){ - @Override - public void write(LittleEndianByteArrayOutputStream bos) { - // EncryptionVersionInfo (4 bytes): A Version structure (section 2.1.4), where - // Version.vMajor MUST be 0x0004 and Version.vMinor MUST be 0x0004 - bos.writeShort(info.getVersionMajor()); - bos.writeShort(info.getVersionMinor()); - // Reserved (4 bytes): A value that MUST be 0x00000040 - bos.writeInt(info.getEncryptionFlags()); - - EncryptionDocument ed = createEncryptionDocument(); - marshallEncryptionDocument(ed, bos); - } - }; - - createEncryptionEntry(dir, "EncryptionInfo", er); - } - - - /** - * 2.3.4.15 Data Encryption (Agile Encryption) - * - * The EncryptedPackage stream (1) MUST be encrypted in 4096-byte segments to facilitate nearly - * random access while allowing CBC modes to be used in the encryption process. - * The initialization vector for the encryption process MUST be obtained by using the zero-based - * segment number as a blockKey and the binary form of the KeyData.saltValue as specified in - * section 2.3.4.12. The block number MUST be represented as a 32-bit unsigned integer. - * Data blocks MUST then be encrypted by using the initialization vector and the intermediate key - * obtained by decrypting the encryptedKeyValue from a KeyEncryptor contained within the - * KeyEncryptors sequence as specified in section 2.3.4.10. The final data block MUST be padded to - * the next integral multiple of the KeyData.blockSize value. Any padding bytes can be used. Note - * that the StreamSize field of the EncryptedPackage field specifies the number of bytes of - * unencrypted data as specified in section 2.3.4.4. - */ - private class AgileCipherOutputStream extends ChunkedCipherOutputStream { - public AgileCipherOutputStream(DirectoryNode dir) throws IOException, GeneralSecurityException { - super(dir, 4096); - } - - @Override - protected Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk) - throws GeneralSecurityException { - return AgileDecryptor.initCipherForBlock(existing, block, lastChunk, getEncryptionInfo(), getSecretKey(), Cipher.ENCRYPT_MODE); - } - - @Override - protected void calculateChecksum(File fileOut, int oleStreamSize) - throws GeneralSecurityException, IOException { - // integrityHMAC needs to be updated before the encryption document is created - updateIntegrityHMAC(fileOut, oleStreamSize); - } - - @Override - protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) - throws IOException, GeneralSecurityException { - AgileEncryptor.this.createEncryptionInfoEntry(dir, tmpFile); - } - } - - @Override - public AgileEncryptor clone() throws CloneNotSupportedException { - AgileEncryptor other = (AgileEncryptor)super.clone(); - other.integritySalt = (integritySalt == null) ? null : integritySalt.clone(); - other.pwHash = (pwHash == null) ? null : pwHash.clone(); - return other; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/CertificateSecurityException.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/CertificateSecurityException.java deleted file mode 100644 index 707ad758a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/CertificateSecurityException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -/** - * Exception thrown in case there is something wrong with the incoming eID - * certificate. - * - * @author Frank Cornelis - * - */ -public class CertificateSecurityException extends SecurityException { - - private static final long serialVersionUID = 1L; - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/DigestInfo.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/DigestInfo.java deleted file mode 100644 index 33ae03c68..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/DigestInfo.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -import java.io.Serializable; - -import org.apache.poi.poifs.crypt.HashAlgorithm; - -/** - * Digest Information data transfer class. - */ -public class DigestInfo implements Serializable { - - private static final long serialVersionUID = 1L; - - /** - * Main constructor. - * - * @param digestValue - * @param hashAlgo - * @param description - */ - public DigestInfo(byte[] digestValue, HashAlgorithm hashAlgo, String description) { - this.digestValue = digestValue.clone(); - this.hashAlgo = hashAlgo; - this.description = description; - } - - public final byte[] digestValue; - - public final String description; - - public final HashAlgorithm hashAlgo; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/ExpiredCertificateSecurityException.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/ExpiredCertificateSecurityException.java deleted file mode 100644 index adbcfdb35..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/ExpiredCertificateSecurityException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -/** - * Exception thrown in case the incoming eID certificate is expired. - * - * @author Frank Cornelis - * - */ -public class ExpiredCertificateSecurityException extends - CertificateSecurityException { - - private static final long serialVersionUID = 1L; - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/KeyInfoKeySelector.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/KeyInfoKeySelector.java deleted file mode 100644 index 90294105e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/KeyInfoKeySelector.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -import java.security.Key; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.crypto.AlgorithmMethod; -import javax.xml.crypto.KeySelector; -import javax.xml.crypto.KeySelectorException; -import javax.xml.crypto.KeySelectorResult; -import javax.xml.crypto.XMLCryptoContext; -import javax.xml.crypto.XMLStructure; -import javax.xml.crypto.dsig.keyinfo.KeyInfo; -import javax.xml.crypto.dsig.keyinfo.X509Data; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * JSR105 key selector implementation using the ds:KeyInfo data of the signature - * itself. - */ -public class KeyInfoKeySelector extends KeySelector implements KeySelectorResult { - - private static final POILogger LOG = POILogFactory.getLogger(KeyInfoKeySelector.class); - - private List certChain = new ArrayList(); - - @SuppressWarnings("unchecked") - @Override - public KeySelectorResult select(KeyInfo keyInfo, Purpose purpose, AlgorithmMethod method, XMLCryptoContext context) throws KeySelectorException { - LOG.log(POILogger.DEBUG, "select key"); - if (null == keyInfo) { - throw new KeySelectorException("no ds:KeyInfo present"); - } - List keyInfoContent = keyInfo.getContent(); - certChain.clear(); - for (XMLStructure keyInfoStructure : keyInfoContent) { - if (!(keyInfoStructure instanceof X509Data)) { - continue; - } - X509Data x509Data = (X509Data) keyInfoStructure; - List x509DataList = x509Data.getContent(); - for (Object x509DataObject : x509DataList) { - if (!(x509DataObject instanceof X509Certificate)) { - continue; - } - X509Certificate certificate = (X509Certificate) x509DataObject; - LOG.log(POILogger.DEBUG, "certificate", certificate.getSubjectX500Principal()); - certChain.add(certificate); - } - } - if (certChain.isEmpty()) { - throw new KeySelectorException("No key found!"); - } - return this; - } - - public Key getKey() { - // The first certificate is presumably the signer. - return certChain.isEmpty() ? null : certChain.get(0).getPublicKey(); - } - - /** - * Gives back the X509 certificate used during the last signature - * verification operation. - * - * @return the certificate which was used to sign the xml content - */ - public X509Certificate getSigner() { - // The first certificate is presumably the signer. - return certChain.isEmpty() ? null : certChain.get(0); - } - - public List getCertChain() { - return certChain; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java deleted file mode 100644 index 64eb53d6f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/OOXMLURIDereferencer.java +++ /dev/null @@ -1,130 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.xml.crypto.Data; -import javax.xml.crypto.OctetStreamData; -import javax.xml.crypto.URIDereferencer; -import javax.xml.crypto.URIReference; -import javax.xml.crypto.URIReferenceException; -import javax.xml.crypto.XMLCryptoContext; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * JSR105 URI dereferencer for Office Open XML documents. - */ -public class OOXMLURIDereferencer implements URIDereferencer, SignatureConfigurable { - - private static final POILogger LOG = POILogFactory.getLogger(OOXMLURIDereferencer.class); - - private SignatureConfig signatureConfig; - private URIDereferencer baseUriDereferencer; - - public void setSignatureConfig(SignatureConfig signatureConfig) { - this.signatureConfig = signatureConfig; - } - - public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException { - if (baseUriDereferencer == null) { - baseUriDereferencer = signatureConfig.getSignatureFactory().getURIDereferencer(); - } - - if (null == uriReference) { - throw new NullPointerException("URIReference cannot be null"); - } - if (null == context) { - throw new NullPointerException("XMLCrytoContext cannot be null"); - } - - URI uri; - try { - uri = new URI(uriReference.getURI()); - } catch (URISyntaxException e) { - throw new URIReferenceException("could not URL decode the uri: "+uriReference.getURI(), e); - } - - PackagePart part = findPart(uri); - if (part == null) { - LOG.log(POILogger.DEBUG, "cannot resolve, delegating to base DOM URI dereferencer", uri); - return this.baseUriDereferencer.dereference(uriReference, context); - } - - InputStream dataStream; - try { - dataStream = part.getInputStream(); - - // workaround for office 2007 pretty-printed .rels files - if (part.getPartName().toString().endsWith(".rels")) { - // although xmlsec has an option to ignore line breaks, currently this - // only affects .rels files, so we only modify these - // http://stackoverflow.com/questions/4728300 - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - for (int ch; (ch = dataStream.read()) != -1; ) { - if (ch == 10 || ch == 13) continue; - bos.write(ch); - } - dataStream = new ByteArrayInputStream(bos.toByteArray()); - } - } catch (IOException e) { - throw new URIReferenceException("I/O error: " + e.getMessage(), e); - } - - return new OctetStreamData(dataStream, uri.toString(), null); - } - - private PackagePart findPart(URI uri) { - LOG.log(POILogger.DEBUG, "dereference", uri); - - String path = uri.getPath(); - if (path == null || "".equals(path)) { - LOG.log(POILogger.DEBUG, "illegal part name (expected)", uri); - return null; - } - - PackagePartName ppn; - try { - ppn = PackagingURIHelper.createPartName(path); - } catch (InvalidFormatException e) { - LOG.log(POILogger.WARN, "illegal part name (not expected)", uri); - return null; - } - - return signatureConfig.getOpcPackage().getPart(ppn); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/RevokedCertificateSecurityException.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/RevokedCertificateSecurityException.java deleted file mode 100644 index fa4fee737..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/RevokedCertificateSecurityException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -/** - * Exception thrown in case the incoming eID certificate has been revoked. - * - * @author Frank Cornelis - * - */ -public class RevokedCertificateSecurityException extends - CertificateSecurityException { - - private static final long serialVersionUID = 1L; - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java deleted file mode 100644 index 6779d8a21..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java +++ /dev/null @@ -1,897 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.dsig; - -import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS; -import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XADES_132_NS; - -import java.security.PrivateKey; -import java.security.Provider; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import javax.xml.crypto.URIDereferencer; -import javax.xml.crypto.dsig.CanonicalizationMethod; -import javax.xml.crypto.dsig.DigestMethod; -import javax.xml.crypto.dsig.XMLSignatureFactory; -import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.OOXMLSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.Office2010SignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService; -import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService; -import org.apache.poi.poifs.crypt.dsig.services.TSPTimeStampService; -import org.apache.poi.poifs.crypt.dsig.services.TimeStampService; -import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.xml.security.signature.XMLSignature; -import org.w3c.dom.events.EventListener; - -/** - * This class bundles the configuration options used for the existing - * signature facets. - * Apart of the thread local members (e.g. opc-package) most values will probably be constant, so - * it might be configured centrally (e.g. by spring) - */ -public class SignatureConfig { - - private static final POILogger LOG = POILogFactory.getLogger(SignatureConfig.class); - - public interface SignatureConfigurable { - void setSignatureConfig(SignatureConfig signatureConfig); - } - - private ThreadLocal opcPackage = new ThreadLocal(); - private ThreadLocal signatureFactory = new ThreadLocal(); - private ThreadLocal keyInfoFactory = new ThreadLocal(); - private ThreadLocal provider = new ThreadLocal(); - - private List signatureFacets = new ArrayList(); - private HashAlgorithm digestAlgo = HashAlgorithm.sha1; - private Date executionTime = new Date(); - private PrivateKey key; - private List signingCertificateChain; - - /** - * the optional signature policy service used for XAdES-EPES. - */ - private SignaturePolicyService signaturePolicyService; - private URIDereferencer uriDereferencer = null; - private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE; - - private boolean includeEntireCertificateChain = true; - private boolean includeIssuerSerial = false; - private boolean includeKeyValue = false; - - /** - * the time-stamp service used for XAdES-T and XAdES-X. - */ - private TimeStampService tspService = new TSPTimeStampService(); - /** - * timestamp service provider URL - */ - private String tspUrl; - private boolean tspOldProtocol = false; - /** - * if not defined, it's the same as the main digest - */ - private HashAlgorithm tspDigestAlgo = null; - private String tspUser; - private String tspPass; - private TimeStampServiceValidator tspValidator; - /** - * the optional TSP request policy OID. - */ - private String tspRequestPolicy = "1.3.6.1.4.1.13762.3"; - private String userAgent = "POI XmlSign Service TSP Client"; - private String proxyUrl; - - /** - * the optional revocation data service used for XAdES-C and XAdES-X-L. - * When null the signature will be limited to XAdES-T only. - */ - private RevocationDataService revocationDataService; - /** - * if not defined, it's the same as the main digest - */ - private HashAlgorithm xadesDigestAlgo = null; - private String xadesRole = null; - private String xadesSignatureId = "idSignedProperties"; - private boolean xadesSignaturePolicyImplied = true; - private String xadesCanonicalizationMethod = CanonicalizationMethod.EXCLUSIVE; - - /** - * Work-around for Office 2010 IssuerName encoding. - */ - private boolean xadesIssuerNameNoReverseOrder = true; - - /** - * The signature Id attribute value used to create the XML signature. A - * null value will trigger an automatically generated signature Id. - */ - private String packageSignatureId = "idPackageSignature"; - - /** - * Gives back the human-readable description of what the citizen will be - * signing. The default value is "Office OpenXML Document". - */ - private String signatureDescription = "Office OpenXML Document"; - - /** - * The process of signing includes the marshalling of xml structures. - * This also includes the canonicalization. Currently this leads to problems - * with certain namespaces, so this EventListener is used to interfere - * with the marshalling process. - */ - EventListener signatureMarshalListener = null; - - /** - * Map of namespace uris to prefix - * If a mapping is specified, the corresponding elements will be prefixed - */ - Map namespacePrefixes = new HashMap(); - - /** - * Inits and checks the config object. - * If not set previously, complex configuration properties also get - * created/initialized via this initialization call. - * - * @param onlyValidation if true, only a subset of the properties - * is initialized, which are necessary for validation. If false, - * also the other properties needed for signing are been taken care of - */ - protected void init(boolean onlyValidation) { - if (opcPackage == null) { - throw new EncryptedDocumentException("opcPackage is null"); - } - if (uriDereferencer == null) { - uriDereferencer = new OOXMLURIDereferencer(); - } - if (uriDereferencer instanceof SignatureConfigurable) { - ((SignatureConfigurable)uriDereferencer).setSignatureConfig(this); - } - if (namespacePrefixes.isEmpty()) { - /* - * OOo doesn't like ds namespaces so per default prefixing is off. - */ - // namespacePrefixes.put(XML_DIGSIG_NS, ""); - namespacePrefixes.put(OO_DIGSIG_NS, "mdssi"); - namespacePrefixes.put(XADES_132_NS, "xd"); - } - - if (onlyValidation) return; - - if (signatureMarshalListener == null) { - signatureMarshalListener = new SignatureMarshalListener(); - } - - if (signatureMarshalListener instanceof SignatureConfigurable) { - ((SignatureConfigurable)signatureMarshalListener).setSignatureConfig(this); - } - - if (tspService != null) { - tspService.setSignatureConfig(this); - } - - if (signatureFacets.isEmpty()) { - addSignatureFacet(new OOXMLSignatureFacet()); - addSignatureFacet(new KeyInfoSignatureFacet()); - addSignatureFacet(new XAdESSignatureFacet()); - addSignatureFacet(new Office2010SignatureFacet()); - } - - for (SignatureFacet sf : signatureFacets) { - sf.setSignatureConfig(this); - } - } - - /** - * @param signatureFacet the signature facet is appended to facet list - */ - public void addSignatureFacet(SignatureFacet signatureFacet) { - signatureFacets.add(signatureFacet); - } - - /** - * @return the list of facets, may be empty when the config object is not initialized - */ - public List getSignatureFacets() { - return signatureFacets; - } - - /** - * @param signatureFacets the new list of facets - */ - public void setSignatureFacets(List signatureFacets) { - this.signatureFacets = signatureFacets; - } - - /** - * @return the main digest algorithm, defaults to sha-1 - */ - public HashAlgorithm getDigestAlgo() { - return digestAlgo; - } - - /** - * @param digestAlgo the main digest algorithm - */ - public void setDigestAlgo(HashAlgorithm digestAlgo) { - this.digestAlgo = digestAlgo; - } - - /** - * @return the opc package to be used by this thread, stored as thread-local - */ - public OPCPackage getOpcPackage() { - return opcPackage.get(); - } - - /** - * @param opcPackage the opc package to be handled by this thread, stored as thread-local - */ - public void setOpcPackage(OPCPackage opcPackage) { - this.opcPackage.set(opcPackage); - } - - /** - * @return the private key - */ - public PrivateKey getKey() { - return key; - } - - /** - * @param key the private key - */ - public void setKey(PrivateKey key) { - this.key = key; - } - - /** - * @return the certificate chain, index 0 is usually the certificate matching - * the private key - */ - public List getSigningCertificateChain() { - return signingCertificateChain; - } - - /** - * @param signingCertificateChain the certificate chain, index 0 should be - * the certificate matching the private key - */ - public void setSigningCertificateChain( - List signingCertificateChain) { - this.signingCertificateChain = signingCertificateChain; - } - - /** - * @return the time at which the document is signed, also used for the timestamp service. - * defaults to now - */ - public Date getExecutionTime() { - return executionTime; - } - - /** - * @param executionTime sets the time at which the document ought to be signed - */ - public void setExecutionTime(Date executionTime) { - this.executionTime = executionTime; - } - - /** - * @return the service to be used for XAdES-EPES properties. There's no default implementation - */ - public SignaturePolicyService getSignaturePolicyService() { - return signaturePolicyService; - } - - /** - * @param signaturePolicyService the service to be used for XAdES-EPES properties - */ - public void setSignaturePolicyService(SignaturePolicyService signaturePolicyService) { - this.signaturePolicyService = signaturePolicyService; - } - - /** - * @return the dereferencer used for Reference/@URI attributes, defaults to {@link OOXMLURIDereferencer} - */ - public URIDereferencer getUriDereferencer() { - return uriDereferencer; - } - - /** - * @param uriDereferencer the dereferencer used for Reference/@URI attributes - */ - public void setUriDereferencer(URIDereferencer uriDereferencer) { - this.uriDereferencer = uriDereferencer; - } - - /** - * @return Gives back the human-readable description of what the citizen - * will be signing. The default value is "Office OpenXML Document". - */ - public String getSignatureDescription() { - return signatureDescription; - } - - /** - * @param signatureDescription the human-readable description of - * what the citizen will be signing. - */ - public void setSignatureDescription(String signatureDescription) { - this.signatureDescription = signatureDescription; - } - - /** - * @return the default canonicalization method, defaults to INCLUSIVE - */ - public String getCanonicalizationMethod() { - return canonicalizationMethod; - } - - /** - * @param canonicalizationMethod the default canonicalization method - */ - public void setCanonicalizationMethod(String canonicalizationMethod) { - this.canonicalizationMethod = canonicalizationMethod; - } - - /** - * @return The signature Id attribute value used to create the XML signature. - * Defaults to "idPackageSignature" - */ - public String getPackageSignatureId() { - return packageSignatureId; - } - - /** - * @param packageSignatureId The signature Id attribute value used to create the XML signature. - * A null value will trigger an automatically generated signature Id. - */ - public void setPackageSignatureId(String packageSignatureId) { - this.packageSignatureId = nvl(packageSignatureId,"xmldsig-"+UUID.randomUUID()); - } - - /** - * @return the url of the timestamp provider (TSP) - */ - public String getTspUrl() { - return tspUrl; - } - - /** - * @param tspUrl the url of the timestamp provider (TSP) - */ - public void setTspUrl(String tspUrl) { - this.tspUrl = tspUrl; - } - - /** - * @return if true, uses timestamp-request/response mimetype, - * if false, timestamp-query/reply mimetype - */ - public boolean isTspOldProtocol() { - return tspOldProtocol; - } - - /** - * @param tspOldProtocol defines the timestamp-protocol mimetype - * @see #isTspOldProtocol - */ - public void setTspOldProtocol(boolean tspOldProtocol) { - this.tspOldProtocol = tspOldProtocol; - } - - /** - * @return the hash algorithm to be used for the timestamp entry. - * Defaults to the hash algorithm of the main entry - */ - public HashAlgorithm getTspDigestAlgo() { - return nvl(tspDigestAlgo,digestAlgo); - } - - /** - * @param tspDigestAlgo the algorithm to be used for the timestamp entry. - * if null, the hash algorithm of the main entry - */ - public void setTspDigestAlgo(HashAlgorithm tspDigestAlgo) { - this.tspDigestAlgo = tspDigestAlgo; - } - - /** - * @return the proxy url to be used for all communications. - * Currently this affects the timestamp service - */ - public String getProxyUrl() { - return proxyUrl; - } - - /** - * @param proxyUrl the proxy url to be used for all communications. - * Currently this affects the timestamp service - */ - public void setProxyUrl(String proxyUrl) { - this.proxyUrl = proxyUrl; - } - - /** - * @return the timestamp service. Defaults to {@link TSPTimeStampService} - */ - public TimeStampService getTspService() { - return tspService; - } - - /** - * @param tspService the timestamp service - */ - public void setTspService(TimeStampService tspService) { - this.tspService = tspService; - } - - /** - * @return the user id for the timestamp service - currently only basic authorization is supported - */ - public String getTspUser() { - return tspUser; - } - - /** - * @param tspUser the user id for the timestamp service - currently only basic authorization is supported - */ - public void setTspUser(String tspUser) { - this.tspUser = tspUser; - } - - /** - * @return the password for the timestamp service - */ - public String getTspPass() { - return tspPass; - } - - /** - * @param tspPass the password for the timestamp service - */ - public void setTspPass(String tspPass) { - this.tspPass = tspPass; - } - - /** - * @return the validator for the timestamp service (certificate) - */ - public TimeStampServiceValidator getTspValidator() { - return tspValidator; - } - - /** - * @param tspValidator the validator for the timestamp service (certificate) - */ - public void setTspValidator(TimeStampServiceValidator tspValidator) { - this.tspValidator = tspValidator; - } - - /** - * @return the optional revocation data service used for XAdES-C and XAdES-X-L. - * When null the signature will be limited to XAdES-T only. - */ - public RevocationDataService getRevocationDataService() { - return revocationDataService; - } - - /** - * @param revocationDataService the optional revocation data service used for XAdES-C and XAdES-X-L. - * When null the signature will be limited to XAdES-T only. - */ - public void setRevocationDataService(RevocationDataService revocationDataService) { - this.revocationDataService = revocationDataService; - } - - /** - * @return hash algorithm used for XAdES. Defaults to the {@link #getDigestAlgo()} - */ - public HashAlgorithm getXadesDigestAlgo() { - return nvl(xadesDigestAlgo,digestAlgo); - } - - /** - * @param xadesDigestAlgo hash algorithm used for XAdES. - * When null, defaults to {@link #getDigestAlgo()} - */ - public void setXadesDigestAlgo(HashAlgorithm xadesDigestAlgo) { - this.xadesDigestAlgo = xadesDigestAlgo; - } - - /** - * @return the user agent used for http communication (e.g. to the TSP) - */ - public String getUserAgent() { - return userAgent; - } - - /** - * @param userAgent the user agent used for http communication (e.g. to the TSP) - */ - public void setUserAgent(String userAgent) { - this.userAgent = userAgent; - } - - /** - * @return the asn.1 object id for the tsp request policy. - * Defaults to 1.3.6.1.4.1.13762.3 - */ - public String getTspRequestPolicy() { - return tspRequestPolicy; - } - - /** - * @param tspRequestPolicy the asn.1 object id for the tsp request policy. - */ - public void setTspRequestPolicy(String tspRequestPolicy) { - this.tspRequestPolicy = tspRequestPolicy; - } - - /** - * @return true, if the whole certificate chain is included in the signature. - * When false, only the signer cert will be included - */ - public boolean isIncludeEntireCertificateChain() { - return includeEntireCertificateChain; - } - - /** - * @param includeEntireCertificateChain if true, include the whole certificate chain. - * If false, only include the signer cert - */ - public void setIncludeEntireCertificateChain(boolean includeEntireCertificateChain) { - this.includeEntireCertificateChain = includeEntireCertificateChain; - } - - /** - * @return if true, issuer serial number is included - */ - public boolean isIncludeIssuerSerial() { - return includeIssuerSerial; - } - - /** - * @param includeIssuerSerial if true, issuer serial number is included - */ - public void setIncludeIssuerSerial(boolean includeIssuerSerial) { - this.includeIssuerSerial = includeIssuerSerial; - } - - /** - * @return if true, the key value of the public key (certificate) is included - */ - public boolean isIncludeKeyValue() { - return includeKeyValue; - } - - /** - * @param includeKeyValue if true, the key value of the public key (certificate) is included - */ - public void setIncludeKeyValue(boolean includeKeyValue) { - this.includeKeyValue = includeKeyValue; - } - - /** - * @return the xades role element. If null the claimed role element is omitted. - * Defaults to null - */ - public String getXadesRole() { - return xadesRole; - } - - /** - * @param xadesRole the xades role element. If null the claimed role element is omitted. - */ - public void setXadesRole(String xadesRole) { - this.xadesRole = xadesRole; - } - - /** - * @return the Id for the XAdES SignedProperties element. - * Defaults to idSignedProperties - */ - public String getXadesSignatureId() { - return nvl(xadesSignatureId, "idSignedProperties"); - } - - /** - * @param xadesSignatureId the Id for the XAdES SignedProperties element. - * When null defaults to idSignedProperties - */ - public void setXadesSignatureId(String xadesSignatureId) { - this.xadesSignatureId = xadesSignatureId; - } - - /** - * @return when true, include the policy-implied block. - * Defaults to true - */ - public boolean isXadesSignaturePolicyImplied() { - return xadesSignaturePolicyImplied; - } - - /** - * @param xadesSignaturePolicyImplied when true, include the policy-implied block - */ - public void setXadesSignaturePolicyImplied(boolean xadesSignaturePolicyImplied) { - this.xadesSignaturePolicyImplied = xadesSignaturePolicyImplied; - } - - /** - * Make sure the DN is encoded using the same order as present - * within the certificate. This is an Office2010 work-around. - * Should be reverted back. - * - * XXX: not correct according to RFC 4514. - * - * @return when true, the issuer DN is used instead of the issuer X500 principal - */ - public boolean isXadesIssuerNameNoReverseOrder() { - return xadesIssuerNameNoReverseOrder; - } - - /** - * @param xadesIssuerNameNoReverseOrder when true, the issuer DN instead of the issuer X500 prinicpal is used - */ - public void setXadesIssuerNameNoReverseOrder(boolean xadesIssuerNameNoReverseOrder) { - this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder; - } - - - /** - * @return the event listener which is active while xml structure for - * the signature is created. - * Defaults to {@link SignatureMarshalListener} - */ - public EventListener getSignatureMarshalListener() { - return signatureMarshalListener; - } - - /** - * @param signatureMarshalListener the event listener watching the xml structure - * generation for the signature - */ - public void setSignatureMarshalListener(EventListener signatureMarshalListener) { - this.signatureMarshalListener = signatureMarshalListener; - } - - /** - * @return the map of namespace uri (key) to prefix (value) - */ - public Map getNamespacePrefixes() { - return namespacePrefixes; - } - - /** - * @param namespacePrefixes the map of namespace uri (key) to prefix (value) - */ - public void setNamespacePrefixes(Map namespacePrefixes) { - this.namespacePrefixes = namespacePrefixes; - } - - /** - * helper method for null/default value handling - * @param value - * @param defaultValue - * @return if value is not null, return value otherwise defaultValue - */ - protected static T nvl(T value, T defaultValue) { - return value == null ? defaultValue : value; - } - - /** - * Each digest method has its own IV (initial vector) - * - * @return the IV depending on the main digest method - */ - public byte[] getHashMagic() { - // see https://www.ietf.org/rfc/rfc3110.txt - // RSA/SHA1 SIG Resource Records - byte result[]; - switch (getDigestAlgo()) { - case sha1: result = new byte[] - { 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e - , 0x03, 0x02, 0x1a, 0x04, 0x14 }; - break; - case sha224: result = new byte[] - { 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, (byte) 0x86 - , 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x04, 0x1c }; - break; - case sha256: result = new byte[] - { 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, (byte) 0x86 - , 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x04, 0x20 }; - break; - case sha384: result = new byte[] - { 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, (byte) 0x86 - , 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x04, 0x30 }; - break; - case sha512: result = new byte[] - { 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, (byte) 0x86 - , 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x04, 0x40 }; - break; - case ripemd128: result = new byte[] - { 0x30, 0x1b, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x24 - , 0x03, 0x02, 0x02, 0x04, 0x10 }; - break; - case ripemd160: result = new byte[] - { 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x24 - , 0x03, 0x02, 0x01, 0x04, 0x14 }; - break; - // case ripemd256: result = new byte[] - // { 0x30, 0x2b, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x24 - // , 0x03, 0x02, 0x03, 0x04, 0x20 }; - // break; - default: throw new EncryptedDocumentException("Hash algorithm " - +getDigestAlgo()+" not supported for signing."); - } - - return result; - } - - /** - * @return the uri for the signature method, i.e. currently only rsa is - * supported, so it's the rsa variant of the main digest - */ - public String getSignatureMethodUri() { - switch (getDigestAlgo()) { - case sha1: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1; - case sha224: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224; - case sha256: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256; - case sha384: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384; - case sha512: return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512; - case ripemd160: return XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160; - default: throw new EncryptedDocumentException("Hash algorithm " - +getDigestAlgo()+" not supported for signing."); - } - } - - /** - * @return the uri for the main digest - */ - public String getDigestMethodUri() { - return getDigestMethodUri(getDigestAlgo()); - } - - /** - * @param digestAlgo the digest algo, currently only sha* and ripemd160 is supported - * @return the uri for the given digest - */ - public static String getDigestMethodUri(HashAlgorithm digestAlgo) { - switch (digestAlgo) { - case sha1: return DigestMethod.SHA1; - case sha224: return "http://www.w3.org/2001/04/xmldsig-more#sha224"; - case sha256: return DigestMethod.SHA256; - case sha384: return "http://www.w3.org/2001/04/xmldsig-more#sha384"; - case sha512: return DigestMethod.SHA512; - case ripemd160: return DigestMethod.RIPEMD160; - default: throw new EncryptedDocumentException("Hash algorithm " - +digestAlgo+" not supported for signing."); - } - } - - /** - * @param signatureFactory the xml signature factory, saved as thread-local - */ - public void setSignatureFactory(XMLSignatureFactory signatureFactory) { - this.signatureFactory.set(signatureFactory); - } - - /** - * @return the xml signature factory (thread-local) - */ - public XMLSignatureFactory getSignatureFactory() { - XMLSignatureFactory sigFac = signatureFactory.get(); - if (sigFac == null) { - sigFac = XMLSignatureFactory.getInstance("DOM", getProvider()); - setSignatureFactory(sigFac); - } - return sigFac; - } - - /** - * @param keyInfoFactory the key factory, saved as thread-local - */ - public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) { - this.keyInfoFactory.set(keyInfoFactory); - } - - /** - * @return the key factory (thread-local) - */ - public KeyInfoFactory getKeyInfoFactory() { - KeyInfoFactory keyFac = keyInfoFactory.get(); - if (keyFac == null) { - keyFac = KeyInfoFactory.getInstance("DOM", getProvider()); - setKeyInfoFactory(keyFac); - } - return keyFac; - } - - /** - * This method tests the existence of xml signature provider in the following order: - *

          - *
        • the class pointed to by the system property "jsr105Provider"
        • - *
        • the Santuario xmlsec provider
        • - *
        • the JDK xmlsec provider
        • - *
        - * - * For signing the classes are linked against the Santuario xmlsec, so this might - * only work for validation (not tested). - * - * @return the xml dsig provider - */ - public Provider getProvider() { - Provider prov = provider.get(); - if (prov == null) { - String dsigProviderNames[] = { - System.getProperty("jsr105Provider"), - "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI", // Santuario xmlsec - "org.jcp.xml.dsig.internal.dom.XMLDSigRI" // JDK xmlsec - }; - for (String pn : dsigProviderNames) { - if (pn == null) continue; - try { - prov = (Provider)Class.forName(pn).newInstance(); - break; - } catch (Exception e) { - LOG.log(POILogger.DEBUG, "XMLDsig-Provider '"+pn+"' can't be found - trying next."); - } - } - } - - if (prov == null) { - throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!"); - } - - return prov; - } - - /** - * @return the cannonicalization method for XAdES-XL signing. - * Defaults to EXCLUSIVE - * @see javax.xml.crypto.dsig.CanonicalizationMethod - */ - public String getXadesCanonicalizationMethod() { - return xadesCanonicalizationMethod; - } - - /** - * @param xadesCanonicalizationMethod the cannonicalization method for XAdES-XL signing - * @see javax.xml.crypto.dsig.CanonicalizationMethod - */ - public void setXadesCanonicalizationMethod(String xadesCanonicalizationMethod) { - this.xadesCanonicalizationMethod = xadesCanonicalizationMethod; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java deleted file mode 100644 index d7f648fae..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java +++ /dev/null @@ -1,701 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_DIGSIG_NS; - -import javax.crypto.Cipher; -import javax.xml.crypto.MarshalException; -import javax.xml.crypto.URIDereferencer; -import javax.xml.crypto.XMLStructure; -import javax.xml.crypto.dsig.CanonicalizationMethod; -import javax.xml.crypto.dsig.Manifest; -import javax.xml.crypto.dsig.Reference; -import javax.xml.crypto.dsig.SignatureMethod; -import javax.xml.crypto.dsig.SignedInfo; -import javax.xml.crypto.dsig.XMLObject; -import javax.xml.crypto.dsig.XMLSignContext; -import javax.xml.crypto.dsig.XMLSignature; -import javax.xml.crypto.dsig.XMLSignatureException; -import javax.xml.crypto.dsig.XMLSignatureFactory; -import javax.xml.crypto.dsig.XMLValidateContext; -import javax.xml.crypto.dsig.dom.DOMSignContext; -import javax.xml.crypto.dsig.dom.DOMValidateContext; -import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.Provider; -import java.security.Security; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; - -import org.apache.jcp.xml.dsig.internal.dom.DOMReference; -import org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo; -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable; -import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet; -import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.xml.security.Init; -import org.apache.xml.security.utils.Base64; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.w3.x2000.x09.xmldsig.SignatureDocument; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.w3c.dom.events.EventListener; -import org.w3c.dom.events.EventTarget; -import org.xml.sax.SAXException; - - -/** - *

        This class is the default entry point for XML signatures and can be used for - * validating an existing signed office document and signing a office document.

        - * - *

        Validating a signed office document

        - * - *
        - * OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ);
        - * SignatureConfig sic = new SignatureConfig();
        - * sic.setOpcPackage(pkg);
        - * SignatureInfo si = new SignatureInfo();
        - * si.setSignatureConfig(sic);
        - * boolean isValid = si.validate();
        - * ...
        - * 
        - * - *

        Signing an office document

        - * - *
        - * // loading the keystore - pkcs12 is used here, but of course jks & co are also valid
        - * // the keystore needs to contain a private key and it's certificate having a
        - * // 'digitalSignature' key usage
        - * char password[] = "test".toCharArray();
        - * File file = new File("test.pfx");
        - * KeyStore keystore = KeyStore.getInstance("PKCS12");
        - * FileInputStream fis = new FileInputStream(file);
        - * keystore.load(fis, password);
        - * fis.close();
        - * 
        - * // extracting private key and certificate
        - * String alias = "xyz"; // alias of the keystore entry
        - * Key key = keystore.getKey(alias, password);
        - * X509Certificate x509 = (X509Certificate)keystore.getCertificate(alias);
        - * 
        - * // filling the SignatureConfig entries (minimum fields, more options are available ...)
        - * SignatureConfig signatureConfig = new SignatureConfig();
        - * signatureConfig.setKey(keyPair.getPrivate());
        - * signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
        - * OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ_WRITE);
        - * signatureConfig.setOpcPackage(pkg);
        - * 
        - * // adding the signature document to the package
        - * SignatureInfo si = new SignatureInfo();
        - * si.setSignatureConfig(signatureConfig);
        - * si.confirmSignature();
        - * // optionally verify the generated signature
        - * boolean b = si.verifySignature();
        - * assert (b);
        - * // write the changes back to disc
        - * pkg.close();
        - * 
        - * - *

        Implementation notes:

        - * - *

        Although there's a XML signature implementation in the Oracle JDKs 6 and higher, - * compatibility with IBM JDKs is also in focus (... but maybe not thoroughly tested ...). - * Therefore we are using the Apache Santuario libs (xmlsec) instead of the built-in classes, - * as the compatibility seems to be provided there.

        - * - *

        To use SignatureInfo and its sibling classes, you'll need to have the following libs - * in the classpath:

        - *
          - *
        • BouncyCastle bcpkix and bcprov (tested against 1.54)
        • - *
        • Apache Santuario "xmlsec" (tested against 2.0.5)
        • - *
        • and slf4j-api (tested against 1.7.12)
        • - *
        - */ -public class SignatureInfo implements SignatureConfigurable { - - private static final POILogger LOG = POILogFactory.getLogger(SignatureInfo.class); - private static boolean isInitialized = false; - - private SignatureConfig signatureConfig; - - public class SignaturePart { - private final PackagePart signaturePart; - private X509Certificate signer; - private List certChain; - - private SignaturePart(PackagePart signaturePart) { - this.signaturePart = signaturePart; - } - - /** - * @return the package part containing the signature - */ - public PackagePart getPackagePart() { - return signaturePart; - } - - /** - * @return the signer certificate - */ - public X509Certificate getSigner() { - return signer; - } - - /** - * @return the certificate chain of the signer - */ - public List getCertChain() { - return certChain; - } - - /** - * Helper method for examining the xml signature - * - * @return the xml signature document - * @throws IOException if the xml signature doesn't exist or can't be read - * @throws XmlException if the xml signature is malformed - */ - public SignatureDocument getSignatureDocument() throws IOException, XmlException { - // TODO: check for XXE - return SignatureDocument.Factory.parse(signaturePart.getInputStream(), DEFAULT_XML_OPTIONS); - } - - /** - * @return true, when the xml signature is valid, false otherwise - * - * @throws EncryptedDocumentException if the signature can't be extracted or if its malformed - */ - @SuppressWarnings("unchecked") - public boolean validate() { - KeyInfoKeySelector keySelector = new KeyInfoKeySelector(); - try { - Document doc = DocumentHelper.readDocument(signaturePart.getInputStream()); - XPath xpath = XPathFactory.newInstance().newXPath(); - NodeList nl = (NodeList)xpath.compile("//*[@Id]").evaluate(doc, XPathConstants.NODESET); - final int length = nl.getLength(); - for (int i=0; i)xmlSignature.getSignedInfo().getReferences()) { - SignatureFacet.brokenJvmWorkaround(ref); - } - for (XMLObject xo : (List)xmlSignature.getObjects()) { - for (XMLStructure xs : (List)xo.getContent()) { - if (xs instanceof Manifest) { - for (Reference ref : (List)((Manifest)xs).getReferences()) { - SignatureFacet.brokenJvmWorkaround(ref); - } - } - } - } - - boolean valid = xmlSignature.validate(domValidateContext); - - if (valid) { - signer = keySelector.getSigner(); - certChain = keySelector.getCertChain(); - } - - return valid; - } catch (IOException e) { - String s = "error in reading document"; - LOG.log(POILogger.ERROR, s, e); - throw new EncryptedDocumentException(s, e); - } catch (SAXException e) { - String s = "error in parsing document"; - LOG.log(POILogger.ERROR, s, e); - throw new EncryptedDocumentException(s, e); - } catch (XPathExpressionException e) { - String s = "error in searching document with xpath expression"; - LOG.log(POILogger.ERROR, s, e); - throw new EncryptedDocumentException(s, e); - } catch (MarshalException e) { - String s = "error in unmarshalling the signature"; - LOG.log(POILogger.ERROR, s, e); - throw new EncryptedDocumentException(s, e); - } catch (XMLSignatureException e) { - String s = "error in validating the signature"; - LOG.log(POILogger.ERROR, s, e); - throw new EncryptedDocumentException(s, e); - } - } - } - - /** - * Constructor initializes xml signature environment, if it hasn't been initialized before - */ - public SignatureInfo() { - initXmlProvider(); - } - - /** - * @return the signature config - */ - public SignatureConfig getSignatureConfig() { - return signatureConfig; - } - - /** - * @param signatureConfig the signature config, needs to be set before a SignatureInfo object is used - */ - public void setSignatureConfig(SignatureConfig signatureConfig) { - this.signatureConfig = signatureConfig; - } - - /** - * @return true, if first signature part is valid - */ - public boolean verifySignature() { - // http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html - for (SignaturePart sp : getSignatureParts()){ - // only validate first part - return sp.validate(); - } - return false; - } - - /** - * add the xml signature to the document - * - * @throws XMLSignatureException - * @throws MarshalException - */ - public void confirmSignature() throws XMLSignatureException, MarshalException { - Document document = DocumentHelper.createDocument(); - - // operate - DigestInfo digestInfo = preSign(document, null); - - // setup: key material, signature value - byte[] signatureValue = signDigest(digestInfo.digestValue); - - // operate: postSign - postSign(document, signatureValue); - } - - /** - * Sign (encrypt) the digest with the private key. - * Currently only rsa is supported. - * - * @param digest the hashed input - * @return the encrypted hash - */ - public byte[] signDigest(byte digest[]) { - Cipher cipher = CryptoFunctions.getCipher(signatureConfig.getKey(), CipherAlgorithm.rsa - , ChainingMode.ecb, null, Cipher.ENCRYPT_MODE, "PKCS1Padding"); - - try { - ByteArrayOutputStream digestInfoValueBuf = new ByteArrayOutputStream(); - digestInfoValueBuf.write(signatureConfig.getHashMagic()); - digestInfoValueBuf.write(digest); - byte[] digestInfoValue = digestInfoValueBuf.toByteArray(); - byte[] signatureValue = cipher.doFinal(digestInfoValue); - return signatureValue; - } catch (Exception e) { - throw new EncryptedDocumentException(e); - } - } - - /** - * @return a signature part for each signature document. - * the parts can be validated independently. - */ - public Iterable getSignatureParts() { - signatureConfig.init(true); - return new Iterable() { - public Iterator iterator() { - return new Iterator() { - OPCPackage pkg = signatureConfig.getOpcPackage(); - Iterator sigOrigRels = - pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN).iterator(); - Iterator sigRels = null; - PackagePart sigPart = null; - - public boolean hasNext() { - while (sigRels == null || !sigRels.hasNext()) { - if (!sigOrigRels.hasNext()) return false; - sigPart = pkg.getPart(sigOrigRels.next()); - LOG.log(POILogger.DEBUG, "Digital Signature Origin part", sigPart); - try { - sigRels = sigPart.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE).iterator(); - } catch (InvalidFormatException e) { - LOG.log(POILogger.WARN, "Reference to signature is invalid.", e); - } - } - return true; - } - - public SignaturePart next() { - PackagePart sigRelPart = null; - do { - try { - if (!hasNext()) throw new NoSuchElementException(); - sigRelPart = sigPart.getRelatedPart(sigRels.next()); - LOG.log(POILogger.DEBUG, "XML Signature part", sigRelPart); - } catch (InvalidFormatException e) { - LOG.log(POILogger.WARN, "Reference to signature is invalid.", e); - } - } while (sigPart == null); - return new SignaturePart(sigRelPart); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - }; - } - - /** - * Initialize the xml signing environment and the bouncycastle provider - */ - protected static synchronized void initXmlProvider() { - if (isInitialized) return; - isInitialized = true; - - try { - Init.init(); - RelationshipTransformService.registerDsigProvider(); - CryptoFunctions.registerBouncyCastle(); - } catch (Exception e) { - throw new RuntimeException("Xml & BouncyCastle-Provider initialization failed", e); - } - } - - /** - * Helper method for adding informations before the signing. - * Normally {@link #confirmSignature()} is sufficient to be used. - */ - @SuppressWarnings("unchecked") - public DigestInfo preSign(Document document, List digestInfos) - throws XMLSignatureException, MarshalException { - signatureConfig.init(false); - - // it's necessary to explicitly set the mdssi namespace, but the sign() method has no - // normal way to interfere with, so we need to add the namespace under the hand ... - EventTarget target = (EventTarget)document; - EventListener creationListener = signatureConfig.getSignatureMarshalListener(); - if (creationListener != null) { - if (creationListener instanceof SignatureMarshalListener) { - ((SignatureMarshalListener)creationListener).setEventTarget(target); - } - SignatureMarshalListener.setListener(target, creationListener, true); - } - - /* - * Signature context construction. - */ - XMLSignContext xmlSignContext = new DOMSignContext(signatureConfig.getKey(), document); - URIDereferencer uriDereferencer = signatureConfig.getUriDereferencer(); - if (null != uriDereferencer) { - xmlSignContext.setURIDereferencer(uriDereferencer); - } - - for (Map.Entry me : signatureConfig.getNamespacePrefixes().entrySet()) { - xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue()); - } - xmlSignContext.setDefaultNamespacePrefix(""); - // signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS)); - - brokenJvmWorkaround(xmlSignContext); - - XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory(); - - /* - * Add ds:References that come from signing client local files. - */ - List references = new ArrayList(); - for (DigestInfo digestInfo : safe(digestInfos)) { - byte[] documentDigestValue = digestInfo.digestValue; - - String uri = new File(digestInfo.description).getName(); - Reference reference = SignatureFacet.newReference - (uri, null, null, null, documentDigestValue, signatureConfig); - references.add(reference); - } - - /* - * Invoke the signature facets. - */ - List objects = new ArrayList(); - for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) { - LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName()); - signatureFacet.preSign(document, references, objects); - } - - /* - * ds:SignedInfo - */ - SignedInfo signedInfo; - try { - SignatureMethod signatureMethod = signatureFactory.newSignatureMethod - (signatureConfig.getSignatureMethodUri(), null); - CanonicalizationMethod canonicalizationMethod = signatureFactory - .newCanonicalizationMethod(signatureConfig.getCanonicalizationMethod(), - (C14NMethodParameterSpec) null); - signedInfo = signatureFactory.newSignedInfo( - canonicalizationMethod, signatureMethod, references); - } catch (GeneralSecurityException e) { - throw new XMLSignatureException(e); - } - - /* - * JSR105 ds:Signature creation - */ - String signatureValueId = signatureConfig.getPackageSignatureId() + "-signature-value"; - javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory - .newXMLSignature(signedInfo, null, objects, signatureConfig.getPackageSignatureId(), - signatureValueId); - - /* - * ds:Signature Marshalling. - */ - xmlSignature.sign(xmlSignContext); - - /* - * Completion of undigested ds:References in the ds:Manifests. - */ - for (XMLObject object : objects) { - LOG.log(POILogger.DEBUG, "object java type: " + object.getClass().getName()); - List objectContentList = object.getContent(); - for (XMLStructure objectContent : objectContentList) { - LOG.log(POILogger.DEBUG, "object content java type: " + objectContent.getClass().getName()); - if (!(objectContent instanceof Manifest)) continue; - Manifest manifest = (Manifest) objectContent; - List manifestReferences = manifest.getReferences(); - for (Reference manifestReference : manifestReferences) { - if (manifestReference.getDigestValue() != null) continue; - - DOMReference manifestDOMReference = (DOMReference)manifestReference; - manifestDOMReference.digest(xmlSignContext); - } - } - } - - /* - * Completion of undigested ds:References. - */ - List signedInfoReferences = signedInfo.getReferences(); - for (Reference signedInfoReference : signedInfoReferences) { - DOMReference domReference = (DOMReference)signedInfoReference; - - // ds:Reference with external digest value - if (domReference.getDigestValue() != null) continue; - - domReference.digest(xmlSignContext); - } - - /* - * Calculation of XML signature digest value. - */ - DOMSignedInfo domSignedInfo = (DOMSignedInfo)signedInfo; - ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); - domSignedInfo.canonicalize(xmlSignContext, dataStream); - byte[] octets = dataStream.toByteArray(); - - /* - * TODO: we could be using DigestOutputStream here to optimize memory - * usage. - */ - - MessageDigest md = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo()); - byte[] digestValue = md.digest(octets); - - - String description = signatureConfig.getSignatureDescription(); - return new DigestInfo(digestValue, signatureConfig.getDigestAlgo(), description); - } - - /** - * Helper method for adding informations after the signing. - * Normally {@link #confirmSignature()} is sufficient to be used. - */ - public void postSign(Document document, byte[] signatureValue) - throws MarshalException { - LOG.log(POILogger.DEBUG, "postSign"); - - /* - * Check ds:Signature node. - */ - String signatureId = signatureConfig.getPackageSignatureId(); - if (!signatureId.equals(document.getDocumentElement().getAttribute("Id"))) { - throw new RuntimeException("ds:Signature not found for @Id: " + signatureId); - } - - /* - * Insert signature value into the ds:SignatureValue element - */ - NodeList sigValNl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "SignatureValue"); - if (sigValNl.getLength() != 1) { - throw new RuntimeException("preSign has to be called before postSign"); - } - sigValNl.item(0).setTextContent(Base64.encode(signatureValue)); - - /* - * Allow signature facets to inject their own stuff. - */ - for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) { - signatureFacet.postSign(document); - } - - writeDocument(document); - } - - /** - * Write XML signature into the OPC package - * - * @param document the xml signature document - * @throws MarshalException - */ - protected void writeDocument(Document document) throws MarshalException { - XmlOptions xo = new XmlOptions(); - Map namespaceMap = new HashMap(); - for(Map.Entry entry : signatureConfig.getNamespacePrefixes().entrySet()){ - namespaceMap.put(entry.getValue(), entry.getKey()); - } - xo.setSaveSuggestedPrefixes(namespaceMap); - xo.setUseDefaultNamespace(); - - LOG.log(POILogger.DEBUG, "output signed Office OpenXML document"); - - /* - * Copy the original OOXML content to the signed OOXML package. During - * copying some files need to changed. - */ - OPCPackage pkg = signatureConfig.getOpcPackage(); - - PackagePartName sigPartName, sigsPartName; - try { - // - sigPartName = PackagingURIHelper.createPartName("/_xmlsignatures/sig1.xml"); - // - sigsPartName = PackagingURIHelper.createPartName("/_xmlsignatures/origin.sigs"); - } catch (InvalidFormatException e) { - throw new MarshalException(e); - } - - PackagePart sigPart = pkg.getPart(sigPartName); - if (sigPart == null) { - sigPart = pkg.createPart(sigPartName, ContentTypes.DIGITAL_SIGNATURE_XML_SIGNATURE_PART); - } - - try { - OutputStream os = sigPart.getOutputStream(); - SignatureDocument sigDoc = SignatureDocument.Factory.parse(document, DEFAULT_XML_OPTIONS); - sigDoc.save(os, xo); - os.close(); - } catch (Exception e) { - throw new MarshalException("Unable to write signature document", e); - } - - PackagePart sigsPart = pkg.getPart(sigsPartName); - if (sigsPart == null) { - // touch empty marker file - sigsPart = pkg.createPart(sigsPartName, ContentTypes.DIGITAL_SIGNATURE_ORIGIN_PART); - } - - PackageRelationshipCollection relCol = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN); - for (PackageRelationship pr : relCol) { - pkg.removeRelationship(pr.getId()); - } - pkg.addRelationship(sigsPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN); - - sigsPart.addRelationship(sigPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE); - } - - /** - * Helper method for null lists, which are converted to empty lists - * - * @param other the reference to wrap, if null - * @return if other is null, an empty lists is returned, otherwise other is returned - */ - private static List safe(List other) { - List emptyList = Collections.emptyList(); - return other == null ? emptyList : other; - } - - private void brokenJvmWorkaround(XMLSignContext context) { - // workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1155012 - Provider bcProv = Security.getProvider("BC"); - if (bcProv != null) { - context.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", bcProv); - } - } - - private void brokenJvmWorkaround(XMLValidateContext context) { - // workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1155012 - Provider bcProv = Security.getProvider("BC"); - if (bcProv != null) { - context.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", bcProv); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java deleted file mode 100644 index f0f43c674..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureMarshalListener.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt.dsig; - -import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.OO_DIGSIG_NS; -import static org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet.XML_NS; - -import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.events.Event; -import org.w3c.dom.events.EventListener; -import org.w3c.dom.events.EventTarget; -import org.w3c.dom.events.MutationEvent; - -/** - * This listener class is used, to modify the to be digested xml document, - * e.g. to register id attributes or set prefixes for registered namespaces - */ -public class SignatureMarshalListener implements EventListener, SignatureConfigurable { - ThreadLocal target = new ThreadLocal(); - SignatureConfig signatureConfig; - public void setEventTarget(EventTarget target) { - this.target.set(target); - } - - public void handleEvent(Event e) { - if (!(e instanceof MutationEvent)) return; - MutationEvent mutEvt = (MutationEvent)e; - EventTarget et = mutEvt.getTarget(); - if (!(et instanceof Element)) return; - handleElement((Element)et); - } - - public void handleElement(Element el) { - EventTarget target = this.target.get(); - String packageId = signatureConfig.getPackageSignatureId(); - if (el.hasAttribute("Id")) { - el.setIdAttribute("Id", true); - } - - setListener(target, this, false); - if (packageId.equals(el.getAttribute("Id"))) { - el.setAttributeNS(XML_NS, "xmlns:mdssi", OO_DIGSIG_NS); - } - setPrefix(el); - setListener(target, this, true); - } - - // helper method to keep it in one place - public static void setListener(EventTarget target, EventListener listener, boolean enabled) { - String type = "DOMSubtreeModified"; - boolean useCapture = false; - if (enabled) { - target.addEventListener(type, listener, useCapture); - } else { - target.removeEventListener(type, listener, useCapture); - } - } - - protected void setPrefix(Node el) { - String prefix = signatureConfig.getNamespacePrefixes().get(el.getNamespaceURI()); - if (prefix != null && el.getPrefix() == null) { - el.setPrefix(prefix); - } - - NodeList nl = el.getChildNodes(); - for (int i=0; i references - , List objects) - throws XMLSignatureException { - List transforms = new ArrayList(); - Transform envelopedTransform = newTransform(CanonicalizationMethod.ENVELOPED); - transforms.add(envelopedTransform); - Transform exclusiveTransform = newTransform(CanonicalizationMethod.EXCLUSIVE); - transforms.add(exclusiveTransform); - - Reference reference = newReference("", transforms, null, null, null); - references.add(reference); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java deleted file mode 100644 index 93f0f5b8b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java +++ /dev/null @@ -1,148 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.facets; - -import java.security.Key; -import java.security.KeyException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.xml.crypto.MarshalException; -import javax.xml.crypto.XMLStructure; -import javax.xml.crypto.dom.DOMStructure; -import javax.xml.crypto.dsig.dom.DOMSignContext; -import javax.xml.crypto.dsig.keyinfo.KeyInfo; -import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; -import javax.xml.crypto.dsig.keyinfo.KeyValue; -import javax.xml.crypto.dsig.keyinfo.X509Data; - -import org.apache.jcp.xml.dsig.internal.dom.DOMKeyInfo; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Signature Facet implementation that adds ds:KeyInfo to the XML signature. - * - * @author Frank Cornelis - * - */ -public class KeyInfoSignatureFacet extends SignatureFacet { - - private static final POILogger LOG = POILogFactory.getLogger(KeyInfoSignatureFacet.class); - - @Override - public void postSign(Document document) - throws MarshalException { - LOG.log(POILogger.DEBUG, "postSign"); - - NodeList nl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "Object"); - - /* - * Make sure we insert right after the ds:SignatureValue element, just - * before the first ds:Object element. - */ - Node nextSibling = (nl.getLength() == 0) ? null : nl.item(0); - - /* - * Construct the ds:KeyInfo element using JSR 105. - */ - KeyInfoFactory keyInfoFactory = signatureConfig.getKeyInfoFactory(); - List x509DataObjects = new ArrayList(); - X509Certificate signingCertificate = signatureConfig.getSigningCertificateChain().get(0); - - List keyInfoContent = new ArrayList(); - - if (signatureConfig.isIncludeKeyValue()) { - KeyValue keyValue; - try { - keyValue = keyInfoFactory.newKeyValue(signingCertificate.getPublicKey()); - } catch (KeyException e) { - throw new RuntimeException("key exception: " + e.getMessage(), e); - } - keyInfoContent.add(keyValue); - } - - if (signatureConfig.isIncludeIssuerSerial()) { - x509DataObjects.add(keyInfoFactory.newX509IssuerSerial( - signingCertificate.getIssuerX500Principal().toString(), - signingCertificate.getSerialNumber())); - } - - if (signatureConfig.isIncludeEntireCertificateChain()) { - x509DataObjects.addAll(signatureConfig.getSigningCertificateChain()); - } else { - x509DataObjects.add(signingCertificate); - } - - if (!x509DataObjects.isEmpty()) { - X509Data x509Data = keyInfoFactory.newX509Data(x509DataObjects); - keyInfoContent.add(x509Data); - } - KeyInfo keyInfo = keyInfoFactory.newKeyInfo(keyInfoContent); - DOMKeyInfo domKeyInfo = (DOMKeyInfo)keyInfo; - - Key key = new Key() { - private static final long serialVersionUID = 1L; - - public String getAlgorithm() { - return null; - } - - public byte[] getEncoded() { - return null; - } - - public String getFormat() { - return null; - } - }; - - Element n = document.getDocumentElement(); - DOMSignContext domSignContext = (nextSibling == null) - ? new DOMSignContext(key, n) - : new DOMSignContext(key, n, nextSibling); - for (Map.Entry me : signatureConfig.getNamespacePrefixes().entrySet()) { - domSignContext.putNamespacePrefix(me.getKey(), me.getValue()); - } - - DOMStructure domStructure = new DOMStructure(n); - domKeyInfo.marshal(domStructure, domSignContext); - - // move keyinfo into the right place - if (nextSibling != null) { - NodeList kiNl = document.getElementsByTagNameNS(XML_DIGSIG_NS, "KeyInfo"); - if (kiNl.getLength() != 1) { - throw new RuntimeException("KeyInfo wasn't set"); - } - nextSibling.getParentNode().insertBefore(kiNl.item(0), nextSibling); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java deleted file mode 100644 index 9e094a641..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java +++ /dev/null @@ -1,475 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.facets; - -import java.net.URI; -import java.net.URISyntaxException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import javax.xml.XMLConstants; -import javax.xml.crypto.XMLStructure; -import javax.xml.crypto.dom.DOMStructure; -import javax.xml.crypto.dsig.CanonicalizationMethod; -import javax.xml.crypto.dsig.Manifest; -import javax.xml.crypto.dsig.Reference; -import javax.xml.crypto.dsig.SignatureProperties; -import javax.xml.crypto.dsig.SignatureProperty; -import javax.xml.crypto.dsig.Transform; -import javax.xml.crypto.dsig.XMLObject; -import javax.xml.crypto.dsig.XMLSignatureException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -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.TargetMode; -import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService; -import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService.RelationshipTransformParameterSpec; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.CTSignatureTime; -import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.SignatureTimeDocument; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import com.microsoft.schemas.office.x2006.digsig.CTSignatureInfoV1; -import com.microsoft.schemas.office.x2006.digsig.SignatureInfoV1Document; - -/** - * Office OpenXML Signature Facet implementation. - * - * @author fcorneli - * @see [MS-OFFCRYPTO]: Office Document Cryptography Structure - */ -public class OOXMLSignatureFacet extends SignatureFacet { - - private static final POILogger LOG = POILogFactory.getLogger(OOXMLSignatureFacet.class); - - @Override - public void preSign( - Document document - , List references - , List objects) - throws XMLSignatureException { - LOG.log(POILogger.DEBUG, "pre sign"); - addManifestObject(document, references, objects); - addSignatureInfo(document, references, objects); - } - - protected void addManifestObject( - Document document - , List references - , List objects) - throws XMLSignatureException { - - List manifestReferences = new ArrayList(); - addManifestReferences(manifestReferences); - Manifest manifest = getSignatureFactory().newManifest(manifestReferences); - - String objectId = "idPackageObject"; // really has to be this value. - List objectContent = new ArrayList(); - objectContent.add(manifest); - - addSignatureTime(document, objectContent); - - XMLObject xo = getSignatureFactory().newXMLObject(objectContent, objectId, null, null); - objects.add(xo); - - Reference reference = newReference("#" + objectId, null, XML_DIGSIG_NS+"Object", null, null); - references.add(reference); - } - - @SuppressWarnings("resource") - protected void addManifestReferences(List manifestReferences) - throws XMLSignatureException { - - OPCPackage ooxml = signatureConfig.getOpcPackage(); - List relsEntryNames = ooxml.getPartsByContentType(ContentTypes.RELATIONSHIPS_PART); - - Set digestedPartNames = new HashSet(); - for (PackagePart pp : relsEntryNames) { - String baseUri = pp.getPartName().getName().replaceFirst("(.*)/_rels/.*", "$1"); - - PackageRelationshipCollection prc; - try { - prc = new PackageRelationshipCollection(ooxml); - prc.parseRelationshipsPart(pp); - } catch (InvalidFormatException e) { - throw new XMLSignatureException("Invalid relationship descriptor: "+pp.getPartName().getName(), e); - } - - RelationshipTransformParameterSpec parameterSpec = new RelationshipTransformParameterSpec(); - for (PackageRelationship relationship : prc) { - String relationshipType = relationship.getRelationshipType(); - - /* - * ECMA-376 Part 2 - 3rd edition - * 13.2.4.16 Manifest Element - * "The producer shall not create a Manifest element that references any data outside of the package." - */ - if (TargetMode.EXTERNAL == relationship.getTargetMode()) { - continue; - } - - if (!isSignedRelationship(relationshipType)) continue; - - parameterSpec.addRelationshipReference(relationship.getId()); - - // TODO: find a better way ... - String partName = relationship.getTargetURI().toString(); - if (!partName.startsWith(baseUri)) { - partName = baseUri + partName; - } - try { - partName = new URI(partName).normalize().getPath().replace('\\', '/'); - LOG.log(POILogger.DEBUG, "part name: " + partName); - } catch (URISyntaxException e) { - throw new XMLSignatureException(e); - } - - String contentType; - try { - PackagePartName relName = PackagingURIHelper.createPartName(partName); - PackagePart pp2 = ooxml.getPart(relName); - contentType = pp2.getContentType(); - } catch (InvalidFormatException e) { - throw new XMLSignatureException(e); - } - - if (relationshipType.endsWith("customXml") - && !(contentType.equals("inkml+xml") || contentType.equals("text/xml"))) { - LOG.log(POILogger.DEBUG, "skipping customXml with content type: " + contentType); - continue; - } - - if (!digestedPartNames.contains(partName)) { - // We only digest a part once. - String uri = partName + "?ContentType=" + contentType; - Reference reference = newReference(uri, null, null, null, null); - manifestReferences.add(reference); - digestedPartNames.add(partName); - } - } - - if (parameterSpec.hasSourceIds()) { - List transforms = new ArrayList(); - transforms.add(newTransform(RelationshipTransformService.TRANSFORM_URI, parameterSpec)); - transforms.add(newTransform(CanonicalizationMethod.INCLUSIVE)); - String uri = pp.getPartName().getName() - + "?ContentType=application/vnd.openxmlformats-package.relationships+xml"; - Reference reference = newReference(uri, transforms, null, null, null); - manifestReferences.add(reference); - } - } - } - - - protected void addSignatureTime(Document document, List objectContent) { - /* - * SignatureTime - */ - DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); - fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); - String nowStr = fmt.format(signatureConfig.getExecutionTime()); - LOG.log(POILogger.DEBUG, "now: " + nowStr); - - SignatureTimeDocument sigTime = SignatureTimeDocument.Factory.newInstance(); - CTSignatureTime ctTime = sigTime.addNewSignatureTime(); - ctTime.setFormat("YYYY-MM-DDThh:mm:ssTZD"); - ctTime.setValue(nowStr); - - Element n = (Element)document.importNode(ctTime.getDomNode(),true); - List signatureTimeContent = new ArrayList(); - signatureTimeContent.add(new DOMStructure(n)); - SignatureProperty signatureTimeSignatureProperty = getSignatureFactory() - .newSignatureProperty(signatureTimeContent, "#" + signatureConfig.getPackageSignatureId(), - "idSignatureTime"); - List signaturePropertyContent = new ArrayList(); - signaturePropertyContent.add(signatureTimeSignatureProperty); - SignatureProperties signatureProperties = getSignatureFactory() - .newSignatureProperties(signaturePropertyContent, - "id-signature-time-" + signatureConfig.getExecutionTime()); - objectContent.add(signatureProperties); - } - - protected void addSignatureInfo(Document document, - List references, - List objects) - throws XMLSignatureException { - List objectContent = new ArrayList(); - - SignatureInfoV1Document sigV1 = SignatureInfoV1Document.Factory.newInstance(); - CTSignatureInfoV1 ctSigV1 = sigV1.addNewSignatureInfoV1(); - ctSigV1.setManifestHashAlgorithm(signatureConfig.getDigestMethodUri()); - Element n = (Element)document.importNode(ctSigV1.getDomNode(), true); - n.setAttributeNS(XML_NS, XMLConstants.XMLNS_ATTRIBUTE, MS_DIGSIG_NS); - - List signatureInfoContent = new ArrayList(); - signatureInfoContent.add(new DOMStructure(n)); - SignatureProperty signatureInfoSignatureProperty = getSignatureFactory() - .newSignatureProperty(signatureInfoContent, "#" + signatureConfig.getPackageSignatureId(), - "idOfficeV1Details"); - - List signaturePropertyContent = new ArrayList(); - signaturePropertyContent.add(signatureInfoSignatureProperty); - SignatureProperties signatureProperties = getSignatureFactory() - .newSignatureProperties(signaturePropertyContent, null); - objectContent.add(signatureProperties); - - String objectId = "idOfficeObject"; - objects.add(getSignatureFactory().newXMLObject(objectContent, objectId, null, null)); - - Reference reference = newReference("#" + objectId, null, XML_DIGSIG_NS+"Object", null, null); - references.add(reference); - } - - protected static String getRelationshipReferenceURI(String zipEntryName) { - return "/" - + zipEntryName - + "?ContentType=application/vnd.openxmlformats-package.relationships+xml"; - } - - protected static String getResourceReferenceURI(String resourceName, String contentType) { - return "/" + resourceName + "?ContentType=" + contentType; - } - - protected static boolean isSignedRelationship(String relationshipType) { - LOG.log(POILogger.DEBUG, "relationship type: " + relationshipType); - for (String signedTypeExtension : signed) { - if (relationshipType.endsWith(signedTypeExtension)) { - return true; - } - } - if (relationshipType.endsWith("customXml")) { - LOG.log(POILogger.DEBUG, "customXml relationship type"); - return true; - } - return false; - } - - public static final String[] contentTypes = { - /* - * Word - */ - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", - "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml", - "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml", - "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml", - "application/vnd.openxmlformats-officedocument.theme+xml", - "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml", - "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml", - - /* - * Word 2010 - */ - "application/vnd.ms-word.stylesWithEffects+xml", - - /* - * Excel - */ - "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", - "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", - "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", - - /* - * Powerpoint - */ - "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml", - "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml", - "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml", - "application/vnd.openxmlformats-officedocument.presentationml.slide+xml", - "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml", - - /* - * Powerpoint 2010 - */ - "application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml", - "application/vnd.openxmlformats-officedocument.presentationml.presProps+xml" - }; - - /** - * Office 2010 list of signed types (extensions). - */ - public static final String[] signed = { - "powerPivotData", // - "activeXControlBinary", // - "attachedToolbars", // - "connectorXml", // - "downRev", // - "functionPrototypes", // - "graphicFrameDoc", // - "groupShapeXml", // - "ink", // - "keyMapCustomizations", // - "legacyDiagramText", // - "legacyDocTextInfo", // - "officeDocument", // - "pictureXml", // - "shapeXml", // - "smartTags", // - "ui/altText", // - "ui/buttonSize", // - "ui/controlID", // - "ui/description", // - "ui/enabled", // - "ui/extensibility", // - "ui/helperText", // - "ui/imageID", // - "ui/imageMso", // - "ui/keyTip", // - "ui/label", // - "ui/lcid", // - "ui/loud", // - "ui/pressed", // - "ui/progID", // - "ui/ribbonID", // - "ui/showImage", // - "ui/showLabel", // - "ui/supertip", // - "ui/target", // - "ui/text", // - "ui/title", // - "ui/tooltip", // - "ui/userCustomization", // - "ui/visible", // - "userXmlData", // - "vbaProject", // - "wordVbaData", // - "wsSortMap", // - "xlBinaryIndex", // - "xlExternalLinkPath/xlAlternateStartup", // - "xlExternalLinkPath/xlLibrary", // - "xlExternalLinkPath/xlPathMissing", // - "xlExternalLinkPath/xlStartup", // - "xlIntlMacrosheet", // - "xlMacrosheet", // - "customData", // - "diagramDrawing", // - "hdphoto", // - "inkXml", // - "media", // - "slicer", // - "slicerCache", // - "stylesWithEffects", // - "ui/extensibility", // - "chartColorStyle", // - "chartLayout", // - "chartStyle", // - "dictionary", // - "timeline", // - "timelineCache", // - "aFChunk", // - "attachedTemplate", // - "audio", // - "calcChain", // - "chart", // - "chartsheet", // - "chartUserShapes", // - "commentAuthors", // - "comments", // - "connections", // - "control", // - "customProperty", // - "customXml", // - "diagramColors", // - "diagramData", // - "diagramLayout", // - "diagramQuickStyle", // - "dialogsheet", // - "drawing", // - "endnotes", // - "externalLink", // - "externalLinkPath", // - "font", // - "fontTable", // - "footer", // - "footnotes", // - "glossaryDocument", // - "handoutMaster", // - "header", // - "hyperlink", // - "image", // - "mailMergeHeaderSource", // - "mailMergeRecipientData", // - "mailMergeSource", // - "notesMaster", // - "notesSlide", // - "numbering", // - "officeDocument", // - "oleObject", // - "package", // - "pivotCacheDefinition", // - "pivotCacheRecords", // - "pivotTable", // - "presProps", // - "printerSettings", // - "queryTable", // - "recipientData", // - "settings", // - "sharedStrings", // - "sheetMetadata", // - "slide", // - "slideLayout", // - "slideMaster", // - "slideUpdateInfo", // - "slideUpdateUrl", // - "styles", // - "table", // - "tableSingleCells", // - "tableStyles", // - "tags", // - "theme", // - "themeOverride", // - "transform", // - "video", // - "viewProps", // - "volatileDependencies", // - "webSettings", // - "worksheet", // - "xmlMaps", // - "ctrlProp", // - "customData", // - "diagram", // - "diagramColorsHeader", // - "diagramLayoutHeader", // - "diagramQuickStyleHeader", // - "documentParts", // - "slicer", // - "slicerCache", // - "vmlDrawing" // - }; -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java deleted file mode 100644 index c6dc2491e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/Office2010SignatureFacet.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.facets; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import javax.xml.crypto.MarshalException; - -import org.apache.xmlbeans.XmlException; -import org.etsi.uri.x01903.v13.QualifyingPropertiesType; -import org.etsi.uri.x01903.v13.UnsignedPropertiesType; -import org.etsi.uri.x01903.v13.UnsignedSignaturePropertiesType; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Work-around for Office2010 to accept the XAdES-BES/EPES signature. - * - * xades:UnsignedProperties/xades:UnsignedSignatureProperties needs to be - * present. - * - * @author Frank Cornelis - * - */ -public class Office2010SignatureFacet extends SignatureFacet { - - @Override - public void postSign(Document document) - throws MarshalException { - // check for XAdES-BES - NodeList nl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties"); - if (nl.getLength() != 1) { - throw new MarshalException("no XAdES-BES extension present"); - } - - QualifyingPropertiesType qualProps; - try { - qualProps = QualifyingPropertiesType.Factory.parse(nl.item(0), DEFAULT_XML_OPTIONS); - } catch (XmlException e) { - throw new MarshalException(e); - } - - // create basic XML container structure - UnsignedPropertiesType unsignedProps = qualProps.getUnsignedProperties(); - if (unsignedProps == null) { - unsignedProps = qualProps.addNewUnsignedProperties(); - } - UnsignedSignaturePropertiesType unsignedSigProps = unsignedProps.getUnsignedSignatureProperties(); - if (unsignedSigProps == null) { - /* unsignedSigProps = */ unsignedProps.addNewUnsignedSignatureProperties(); - } - - Node n = document.importNode(qualProps.getDomNode().getFirstChild(), true); - nl.item(0).getParentNode().replaceChild(n, nl.item(0)); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java deleted file mode 100644 index 43bef872f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/SignatureFacet.java +++ /dev/null @@ -1,190 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.facets; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.PrivilegedAction; -import java.security.Provider; -import java.security.Security; -import java.util.List; - -import javax.xml.XMLConstants; -import javax.xml.crypto.MarshalException; -import javax.xml.crypto.dsig.DigestMethod; -import javax.xml.crypto.dsig.Reference; -import javax.xml.crypto.dsig.Transform; -import javax.xml.crypto.dsig.XMLObject; -import javax.xml.crypto.dsig.XMLSignature; -import javax.xml.crypto.dsig.XMLSignatureException; -import javax.xml.crypto.dsig.XMLSignatureFactory; -import javax.xml.crypto.dsig.spec.TransformParameterSpec; - -import org.apache.jcp.xml.dsig.internal.dom.DOMDigestMethod; -import org.apache.jcp.xml.dsig.internal.dom.DOMReference; -import org.apache.poi.openxml4j.opc.PackageNamespaces; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.SuppressForbidden; -import org.w3c.dom.Document; - -/** - * JSR105 Signature Facet base class. - */ -public abstract class SignatureFacet implements SignatureConfigurable { - - private static final POILogger LOG = POILogFactory.getLogger(SignatureFacet.class); - - public static final String XML_NS = XMLConstants.XMLNS_ATTRIBUTE_NS_URI; - public static final String XML_DIGSIG_NS = XMLSignature.XMLNS; - public static final String OO_DIGSIG_NS = PackageNamespaces.DIGITAL_SIGNATURE; - public static final String MS_DIGSIG_NS = "http://schemas.microsoft.com/office/2006/digsig"; - public static final String XADES_132_NS = "http://uri.etsi.org/01903/v1.3.2#"; - public static final String XADES_141_NS = "http://uri.etsi.org/01903/v1.4.1#"; - - protected SignatureConfig signatureConfig; - - public void setSignatureConfig(SignatureConfig signatureConfig) { - this.signatureConfig = signatureConfig; - } - - /** - * This method is being invoked by the XML signature service engine during - * pre-sign phase. Via this method a signature facet implementation can add - * signature facets to an XML signature. - * - * @param document the signature document to be used for imports - * @param references list of reference definitions - * @param objects objects to be signed/included in the signature document - * @throws XMLSignatureException - */ - public void preSign( - Document document - , List references - , List objects - ) throws XMLSignatureException { - // empty - } - - /** - * This method is being invoked by the XML signature service engine during - * the post-sign phase. Via this method a signature facet can extend the XML - * signatures with for example key information. - * - * @param document the signature document to be modified - * @throws MarshalException - */ - public void postSign(Document document) throws MarshalException { - // empty - } - - protected XMLSignatureFactory getSignatureFactory() { - return signatureConfig.getSignatureFactory(); - } - - protected Transform newTransform(String canonicalizationMethod) throws XMLSignatureException { - return newTransform(canonicalizationMethod, null); - } - - protected Transform newTransform(String canonicalizationMethod, TransformParameterSpec paramSpec) - throws XMLSignatureException { - try { - return getSignatureFactory().newTransform(canonicalizationMethod, paramSpec); - } catch (GeneralSecurityException e) { - throw new XMLSignatureException("unknown canonicalization method: "+canonicalizationMethod, e); - } - } - - protected Reference newReference(String uri, List transforms, String type, String id, byte digestValue[]) - throws XMLSignatureException { - return newReference(uri, transforms, type, id, digestValue, signatureConfig); - } - - public static Reference newReference( - String uri - , List transforms - , String type - , String id - , byte digestValue[] - , SignatureConfig signatureConfig) - throws XMLSignatureException { - // the references appear in the package signature or the package object - // so we can use the default digest algorithm - String digestMethodUri = signatureConfig.getDigestMethodUri(); - XMLSignatureFactory sigFac = signatureConfig.getSignatureFactory(); - DigestMethod digestMethod; - try { - digestMethod = sigFac.newDigestMethod(digestMethodUri, null); - } catch (GeneralSecurityException e) { - throw new XMLSignatureException("unknown digest method uri: "+digestMethodUri, e); - } - - Reference reference; - if (digestValue == null) { - reference = sigFac.newReference(uri, digestMethod, transforms, type, id); - } else { - reference = sigFac.newReference(uri, digestMethod, transforms, type, id, digestValue); - } - - brokenJvmWorkaround(reference); - - return reference; - } - - // helper method ... will be removed soon - public static void brokenJvmWorkaround(final Reference reference) { - final DigestMethod digestMethod = reference.getDigestMethod(); - final String digestMethodUri = digestMethod.getAlgorithm(); - - final Provider bcProv = Security.getProvider("BC"); - if (bcProv != null && !DigestMethod.SHA1.equals(digestMethodUri)) { - // workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1155012 - // overwrite standard message digest, if a digest <> SHA1 is used - AccessController.doPrivileged(new PrivilegedAction() { - @Override - @SuppressForbidden("Workaround for a bug, needs access to private JDK members (may fail in Java 9): https://bugzilla.redhat.com/show_bug.cgi?id=1155012") - public Void run() { - try { - Method m = DOMDigestMethod.class.getDeclaredMethod("getMessageDigestAlgorithm"); - m.setAccessible(true); - String mdAlgo = (String)m.invoke(digestMethod); - MessageDigest md = MessageDigest.getInstance(mdAlgo, bcProv); - Field f = DOMReference.class.getDeclaredField("md"); - f.setAccessible(true); - f.set(reference, md); - } catch (Exception e) { - LOG.log(POILogger.WARN, "Can't overwrite message digest (workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1155012)", e); - } - return null; // Void - } - }); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java deleted file mode 100644 index 5441d58bb..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java +++ /dev/null @@ -1,286 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.facets; - -import java.security.MessageDigest; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -import javax.xml.crypto.XMLStructure; -import javax.xml.crypto.dom.DOMStructure; -import javax.xml.crypto.dsig.CanonicalizationMethod; -import javax.xml.crypto.dsig.Reference; -import javax.xml.crypto.dsig.Transform; -import javax.xml.crypto.dsig.XMLObject; -import javax.xml.crypto.dsig.XMLSignatureException; - -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig; -import org.apache.poi.poifs.crypt.dsig.services.SignaturePolicyService; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlString; -import org.etsi.uri.x01903.v13.AnyType; -import org.etsi.uri.x01903.v13.CertIDListType; -import org.etsi.uri.x01903.v13.CertIDType; -import org.etsi.uri.x01903.v13.ClaimedRolesListType; -import org.etsi.uri.x01903.v13.DataObjectFormatType; -import org.etsi.uri.x01903.v13.DigestAlgAndValueType; -import org.etsi.uri.x01903.v13.IdentifierType; -import org.etsi.uri.x01903.v13.ObjectIdentifierType; -import org.etsi.uri.x01903.v13.QualifyingPropertiesDocument; -import org.etsi.uri.x01903.v13.QualifyingPropertiesType; -import org.etsi.uri.x01903.v13.SigPolicyQualifiersListType; -import org.etsi.uri.x01903.v13.SignaturePolicyIdType; -import org.etsi.uri.x01903.v13.SignaturePolicyIdentifierType; -import org.etsi.uri.x01903.v13.SignedDataObjectPropertiesType; -import org.etsi.uri.x01903.v13.SignedPropertiesType; -import org.etsi.uri.x01903.v13.SignedSignaturePropertiesType; -import org.etsi.uri.x01903.v13.SignerRoleType; -import org.w3.x2000.x09.xmldsig.DigestMethodType; -import org.w3.x2000.x09.xmldsig.X509IssuerSerialType; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * XAdES Signature Facet. Implements XAdES v1.4.1 which is compatible with XAdES - * v1.3.2. The implemented XAdES format is XAdES-BES/EPES. It's up to another - * part of the signature service to upgrade the XAdES-BES to a XAdES-X-L. - * - * This implementation has been tested against an implementation that - * participated multiple ETSI XAdES plugtests. - * - * @author Frank Cornelis - * @see XAdES - * - */ -public class XAdESSignatureFacet extends SignatureFacet { - - private static final POILogger LOG = POILogFactory.getLogger(XAdESSignatureFacet.class); - - private static final String XADES_TYPE = "http://uri.etsi.org/01903#SignedProperties"; - - private Map dataObjectFormatMimeTypes = new HashMap(); - - - @Override - public void preSign( - Document document - , List references - , List objects) - throws XMLSignatureException { - LOG.log(POILogger.DEBUG, "preSign"); - - // QualifyingProperties - QualifyingPropertiesDocument qualDoc = QualifyingPropertiesDocument.Factory.newInstance(); - QualifyingPropertiesType qualifyingProperties = qualDoc.addNewQualifyingProperties(); - qualifyingProperties.setTarget("#" + signatureConfig.getPackageSignatureId()); - - // SignedProperties - SignedPropertiesType signedProperties = qualifyingProperties.addNewSignedProperties(); - signedProperties.setId(signatureConfig.getXadesSignatureId()); - - // SignedSignatureProperties - SignedSignaturePropertiesType signedSignatureProperties = signedProperties.addNewSignedSignatureProperties(); - - // SigningTime - Calendar xmlGregorianCalendar = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT); - xmlGregorianCalendar.setTime(signatureConfig.getExecutionTime()); - xmlGregorianCalendar.clear(Calendar.MILLISECOND); - signedSignatureProperties.setSigningTime(xmlGregorianCalendar); - - // SigningCertificate - if (signatureConfig.getSigningCertificateChain() == null - || signatureConfig.getSigningCertificateChain().isEmpty()) { - throw new RuntimeException("no signing certificate chain available"); - } - CertIDListType signingCertificates = signedSignatureProperties.addNewSigningCertificate(); - CertIDType certId = signingCertificates.addNewCert(); - X509Certificate certificate = signatureConfig.getSigningCertificateChain().get(0); - setCertID(certId, signatureConfig, signatureConfig.isXadesIssuerNameNoReverseOrder(), certificate); - - // ClaimedRole - String role = signatureConfig.getXadesRole(); - if (role != null && !role.isEmpty()) { - SignerRoleType signerRole = signedSignatureProperties.addNewSignerRole(); - signedSignatureProperties.setSignerRole(signerRole); - ClaimedRolesListType claimedRolesList = signerRole.addNewClaimedRoles(); - AnyType claimedRole = claimedRolesList.addNewClaimedRole(); - XmlString roleString = XmlString.Factory.newInstance(); - roleString.setStringValue(role); - insertXChild(claimedRole, roleString); - } - - // XAdES-EPES - SignaturePolicyService policyService = signatureConfig.getSignaturePolicyService(); - if (policyService != null) { - SignaturePolicyIdentifierType signaturePolicyIdentifier = - signedSignatureProperties.addNewSignaturePolicyIdentifier(); - - SignaturePolicyIdType signaturePolicyId = signaturePolicyIdentifier.addNewSignaturePolicyId(); - - ObjectIdentifierType objectIdentifier = signaturePolicyId.addNewSigPolicyId(); - objectIdentifier.setDescription(policyService.getSignaturePolicyDescription()); - - IdentifierType identifier = objectIdentifier.addNewIdentifier(); - identifier.setStringValue(policyService.getSignaturePolicyIdentifier()); - - byte[] signaturePolicyDocumentData = policyService.getSignaturePolicyDocument(); - DigestAlgAndValueType sigPolicyHash = signaturePolicyId.addNewSigPolicyHash(); - setDigestAlgAndValue(sigPolicyHash, signaturePolicyDocumentData, signatureConfig.getDigestAlgo()); - - String signaturePolicyDownloadUrl = policyService.getSignaturePolicyDownloadUrl(); - if (null != signaturePolicyDownloadUrl) { - SigPolicyQualifiersListType sigPolicyQualifiers = signaturePolicyId.addNewSigPolicyQualifiers(); - AnyType sigPolicyQualifier = sigPolicyQualifiers.addNewSigPolicyQualifier(); - XmlString spUriElement = XmlString.Factory.newInstance(); - spUriElement.setStringValue(signaturePolicyDownloadUrl); - insertXChild(sigPolicyQualifier, spUriElement); - } - } else if (signatureConfig.isXadesSignaturePolicyImplied()) { - SignaturePolicyIdentifierType signaturePolicyIdentifier = - signedSignatureProperties.addNewSignaturePolicyIdentifier(); - signaturePolicyIdentifier.addNewSignaturePolicyImplied(); - } - - // DataObjectFormat - if (!dataObjectFormatMimeTypes.isEmpty()) { - SignedDataObjectPropertiesType signedDataObjectProperties = - signedProperties.addNewSignedDataObjectProperties(); - - List dataObjectFormats = signedDataObjectProperties - .getDataObjectFormatList(); - for (Map.Entry dataObjectFormatMimeType : this.dataObjectFormatMimeTypes - .entrySet()) { - DataObjectFormatType dataObjectFormat = DataObjectFormatType.Factory.newInstance(); - dataObjectFormat.setObjectReference("#" + dataObjectFormatMimeType.getKey()); - dataObjectFormat.setMimeType(dataObjectFormatMimeType.getValue()); - dataObjectFormats.add(dataObjectFormat); - } - } - - // add XAdES ds:Object - List xadesObjectContent = new ArrayList(); - Element qualDocElSrc = (Element)qualifyingProperties.getDomNode(); - Element qualDocEl = (Element)document.importNode(qualDocElSrc, true); - xadesObjectContent.add(new DOMStructure(qualDocEl)); - XMLObject xadesObject = getSignatureFactory().newXMLObject(xadesObjectContent, null, null, null); - objects.add(xadesObject); - - // add XAdES ds:Reference - List transforms = new ArrayList(); - Transform exclusiveTransform = newTransform(CanonicalizationMethod.INCLUSIVE); - transforms.add(exclusiveTransform); - Reference reference = newReference - ("#"+signatureConfig.getXadesSignatureId(), transforms, XADES_TYPE, null, null); - references.add(reference); - } - - /** - * Gives back the JAXB DigestAlgAndValue data structure. - * - * @param digestAlgAndValue the parent for the new digest element - * @param data the data to be digested - * @param digestAlgo the digest algorithm - */ - protected static void setDigestAlgAndValue( - DigestAlgAndValueType digestAlgAndValue, - byte[] data, - HashAlgorithm digestAlgo) { - DigestMethodType digestMethod = digestAlgAndValue.addNewDigestMethod(); - digestMethod.setAlgorithm(SignatureConfig.getDigestMethodUri(digestAlgo)); - - MessageDigest messageDigest = CryptoFunctions.getMessageDigest(digestAlgo); - byte[] digestValue = messageDigest.digest(data); - digestAlgAndValue.setDigestValue(digestValue); - } - - /** - * Gives back the JAXB CertID data structure. - */ - protected static void setCertID - (CertIDType certId, SignatureConfig signatureConfig, boolean issuerNameNoReverseOrder, X509Certificate certificate) { - X509IssuerSerialType issuerSerial = certId.addNewIssuerSerial(); - String issuerName; - if (issuerNameNoReverseOrder) { - /* - * Make sure the DN is encoded using the same order as present - * within the certificate. This is an Office2010 work-around. - * Should be reverted back. - * - * XXX: not correct according to RFC 4514. - */ - // TODO: check if issuerName is different on getTBSCertificate - // issuerName = PrincipalUtil.getIssuerX509Principal(certificate).getName().replace(",", ", "); - issuerName = certificate.getIssuerDN().getName().replace(",", ", "); - } else { - issuerName = certificate.getIssuerX500Principal().toString(); - } - issuerSerial.setX509IssuerName(issuerName); - issuerSerial.setX509SerialNumber(certificate.getSerialNumber()); - - byte[] encodedCertificate; - try { - encodedCertificate = certificate.getEncoded(); - } catch (CertificateEncodingException e) { - throw new RuntimeException("certificate encoding error: " - + e.getMessage(), e); - } - DigestAlgAndValueType certDigest = certId.addNewCertDigest(); - setDigestAlgAndValue(certDigest, encodedCertificate, signatureConfig.getXadesDigestAlgo()); - } - - /** - * Adds a mime-type for the given ds:Reference (referred via its @URI). This - * information is added via the xades:DataObjectFormat element. - * - * @param dsReferenceUri - * @param mimetype - */ - public void addMimeType(String dsReferenceUri, String mimetype) { - this.dataObjectFormatMimeTypes.put(dsReferenceUri, mimetype); - } - - protected static void insertXChild(XmlObject root, XmlObject child) { - XmlCursor rootCursor = root.newCursor(); - rootCursor.toEndToken(); - XmlCursor childCursor = child.newCursor(); - childCursor.toNextToken(); - childCursor.moveXml(rootCursor); - childCursor.dispose(); - rootCursor.dispose(); - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java deleted file mode 100644 index d25bd7d1b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java +++ /dev/null @@ -1,409 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.facets; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet.insertXChild; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.cert.CRLException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; -import java.util.UUID; - -import javax.xml.crypto.MarshalException; - -import org.apache.poi.poifs.crypt.dsig.services.RevocationData; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.xml.security.c14n.Canonicalizer; -import org.apache.xmlbeans.XmlException; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.DERTaggedObject; -import org.bouncycastle.asn1.ocsp.ResponderID; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.cert.ocsp.BasicOCSPResp; -import org.bouncycastle.cert.ocsp.OCSPResp; -import org.bouncycastle.cert.ocsp.RespID; -import org.etsi.uri.x01903.v13.CRLIdentifierType; -import org.etsi.uri.x01903.v13.CRLRefType; -import org.etsi.uri.x01903.v13.CRLRefsType; -import org.etsi.uri.x01903.v13.CRLValuesType; -import org.etsi.uri.x01903.v13.CertIDListType; -import org.etsi.uri.x01903.v13.CertIDType; -import org.etsi.uri.x01903.v13.CertificateValuesType; -import org.etsi.uri.x01903.v13.CompleteCertificateRefsType; -import org.etsi.uri.x01903.v13.CompleteRevocationRefsType; -import org.etsi.uri.x01903.v13.DigestAlgAndValueType; -import org.etsi.uri.x01903.v13.EncapsulatedPKIDataType; -import org.etsi.uri.x01903.v13.OCSPIdentifierType; -import org.etsi.uri.x01903.v13.OCSPRefType; -import org.etsi.uri.x01903.v13.OCSPRefsType; -import org.etsi.uri.x01903.v13.OCSPValuesType; -import org.etsi.uri.x01903.v13.QualifyingPropertiesDocument; -import org.etsi.uri.x01903.v13.QualifyingPropertiesType; -import org.etsi.uri.x01903.v13.ResponderIDType; -import org.etsi.uri.x01903.v13.RevocationValuesType; -import org.etsi.uri.x01903.v13.UnsignedPropertiesType; -import org.etsi.uri.x01903.v13.UnsignedSignaturePropertiesType; -import org.etsi.uri.x01903.v13.XAdESTimeStampType; -import org.etsi.uri.x01903.v14.ValidationDataType; -import org.w3.x2000.x09.xmldsig.CanonicalizationMethodType; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * XAdES-X-L v1.4.1 signature facet. This signature facet implementation will - * upgrade a given XAdES-BES/EPES signature to XAdES-X-L. - * - * We don't inherit from XAdESSignatureFacet as we also want to be able to use - * this facet out of the context of a signature creation. This signature facet - * assumes that the signature is already XAdES-BES/EPES compliant. - * - * This implementation has been tested against an implementation that - * participated multiple ETSI XAdES plugtests. - * - * @author Frank Cornelis - * @see XAdESSignatureFacet - */ -public class XAdESXLSignatureFacet extends SignatureFacet { - - private static final POILogger LOG = POILogFactory.getLogger(XAdESXLSignatureFacet.class); - - private final CertificateFactory certificateFactory; - - public XAdESXLSignatureFacet() { - try { - this.certificateFactory = CertificateFactory.getInstance("X.509"); - } catch (CertificateException e) { - throw new RuntimeException("X509 JCA error: " + e.getMessage(), e); - } - } - - @Override - public void postSign(Document document) throws MarshalException { - LOG.log(POILogger.DEBUG, "XAdES-X-L post sign phase"); - - QualifyingPropertiesDocument qualDoc = null; - QualifyingPropertiesType qualProps = null; - - // check for XAdES-BES - NodeList qualNl = document.getElementsByTagNameNS(XADES_132_NS, "QualifyingProperties"); - if (qualNl.getLength() == 1) { - try { - qualDoc = QualifyingPropertiesDocument.Factory.parse(qualNl.item(0), DEFAULT_XML_OPTIONS); - } catch (XmlException e) { - throw new MarshalException(e); - } - qualProps = qualDoc.getQualifyingProperties(); - } else { - throw new MarshalException("no XAdES-BES extension present"); - } - - // create basic XML container structure - UnsignedPropertiesType unsignedProps = qualProps.getUnsignedProperties(); - if (unsignedProps == null) { - unsignedProps = qualProps.addNewUnsignedProperties(); - } - UnsignedSignaturePropertiesType unsignedSigProps = unsignedProps.getUnsignedSignatureProperties(); - if (unsignedSigProps == null) { - unsignedSigProps = unsignedProps.addNewUnsignedSignatureProperties(); - } - - - // create the XAdES-T time-stamp - NodeList nlSigVal = document.getElementsByTagNameNS(XML_DIGSIG_NS, "SignatureValue"); - if (nlSigVal.getLength() != 1) { - throw new IllegalArgumentException("SignatureValue is not set."); - } - - RevocationData tsaRevocationDataXadesT = new RevocationData(); - LOG.log(POILogger.DEBUG, "creating XAdES-T time-stamp"); - XAdESTimeStampType signatureTimeStamp = createXAdESTimeStamp - (Collections.singletonList(nlSigVal.item(0)), tsaRevocationDataXadesT); - - // marshal the XAdES-T extension - unsignedSigProps.addNewSignatureTimeStamp().set(signatureTimeStamp); - - // xadesv141::TimeStampValidationData - if (tsaRevocationDataXadesT.hasRevocationDataEntries()) { - ValidationDataType validationData = createValidationData(tsaRevocationDataXadesT); - insertXChild(unsignedSigProps, validationData); - } - - if (signatureConfig.getRevocationDataService() == null) { - /* - * Without revocation data service we cannot construct the XAdES-C - * extension. - */ - return; - } - - // XAdES-C: complete certificate refs - CompleteCertificateRefsType completeCertificateRefs = - unsignedSigProps.addNewCompleteCertificateRefs(); - - CertIDListType certIdList = completeCertificateRefs.addNewCertRefs(); - /* - * We skip the signing certificate itself according to section - * 4.4.3.2 of the XAdES 1.4.1 specification. - */ - List certChain = signatureConfig.getSigningCertificateChain(); - int chainSize = certChain.size(); - if (chainSize > 1) { - for (X509Certificate cert : certChain.subList(1, chainSize)) { - CertIDType certId = certIdList.addNewCert(); - XAdESSignatureFacet.setCertID(certId, signatureConfig, false, cert); - } - } - - // XAdES-C: complete revocation refs - CompleteRevocationRefsType completeRevocationRefs = - unsignedSigProps.addNewCompleteRevocationRefs(); - RevocationData revocationData = signatureConfig.getRevocationDataService() - .getRevocationData(certChain); - if (revocationData.hasCRLs()) { - CRLRefsType crlRefs = completeRevocationRefs.addNewCRLRefs(); - completeRevocationRefs.setCRLRefs(crlRefs); - - for (byte[] encodedCrl : revocationData.getCRLs()) { - CRLRefType crlRef = crlRefs.addNewCRLRef(); - X509CRL crl; - try { - crl = (X509CRL) this.certificateFactory - .generateCRL(new ByteArrayInputStream(encodedCrl)); - } catch (CRLException e) { - throw new RuntimeException("CRL parse error: " - + e.getMessage(), e); - } - - CRLIdentifierType crlIdentifier = crlRef.addNewCRLIdentifier(); - String issuerName = crl.getIssuerDN().getName().replace(",", ", "); - crlIdentifier.setIssuer(issuerName); - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT); - cal.setTime(crl.getThisUpdate()); - crlIdentifier.setIssueTime(cal); - crlIdentifier.setNumber(getCrlNumber(crl)); - - DigestAlgAndValueType digestAlgAndValue = crlRef.addNewDigestAlgAndValue(); - XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, encodedCrl, signatureConfig.getDigestAlgo()); - } - } - if (revocationData.hasOCSPs()) { - OCSPRefsType ocspRefs = completeRevocationRefs.addNewOCSPRefs(); - for (byte[] ocsp : revocationData.getOCSPs()) { - try { - OCSPRefType ocspRef = ocspRefs.addNewOCSPRef(); - - DigestAlgAndValueType digestAlgAndValue = ocspRef.addNewDigestAlgAndValue(); - XAdESSignatureFacet.setDigestAlgAndValue(digestAlgAndValue, ocsp, signatureConfig.getDigestAlgo()); - - OCSPIdentifierType ocspIdentifier = ocspRef.addNewOCSPIdentifier(); - - OCSPResp ocspResp = new OCSPResp(ocsp); - - BasicOCSPResp basicOcspResp = (BasicOCSPResp)ocspResp.getResponseObject(); - - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT); - cal.setTime(basicOcspResp.getProducedAt()); - ocspIdentifier.setProducedAt(cal); - - ResponderIDType responderId = ocspIdentifier.addNewResponderID(); - - RespID respId = basicOcspResp.getResponderId(); - ResponderID ocspResponderId = respId.toASN1Primitive(); - DERTaggedObject derTaggedObject = (DERTaggedObject)ocspResponderId.toASN1Primitive(); - if (2 == derTaggedObject.getTagNo()) { - ASN1OctetString keyHashOctetString = (ASN1OctetString)derTaggedObject.getObject(); - byte key[] = keyHashOctetString.getOctets(); - responderId.setByKey(key); - } else { - X500Name name = X500Name.getInstance(derTaggedObject.getObject()); - String nameStr = name.toString(); - responderId.setByName(nameStr); - } - } catch (Exception e) { - throw new RuntimeException("OCSP decoding error: " + e.getMessage(), e); - } - } - } - - // marshal XAdES-C - - // XAdES-X Type 1 timestamp - List timeStampNodesXadesX1 = new ArrayList(); - timeStampNodesXadesX1.add(nlSigVal.item(0)); - timeStampNodesXadesX1.add(signatureTimeStamp.getDomNode()); - timeStampNodesXadesX1.add(completeCertificateRefs.getDomNode()); - timeStampNodesXadesX1.add(completeRevocationRefs.getDomNode()); - - RevocationData tsaRevocationDataXadesX1 = new RevocationData(); - LOG.log(POILogger.DEBUG, "creating XAdES-X time-stamp"); - XAdESTimeStampType timeStampXadesX1 = createXAdESTimeStamp - (timeStampNodesXadesX1, tsaRevocationDataXadesX1); - if (tsaRevocationDataXadesX1.hasRevocationDataEntries()) { - ValidationDataType timeStampXadesX1ValidationData = createValidationData(tsaRevocationDataXadesX1); - insertXChild(unsignedSigProps, timeStampXadesX1ValidationData); - } - - // marshal XAdES-X - unsignedSigProps.addNewSigAndRefsTimeStamp().set(timeStampXadesX1); - - // XAdES-X-L - CertificateValuesType certificateValues = unsignedSigProps.addNewCertificateValues(); - for (X509Certificate certificate : certChain) { - EncapsulatedPKIDataType encapsulatedPKIDataType = certificateValues.addNewEncapsulatedX509Certificate(); - try { - encapsulatedPKIDataType.setByteArrayValue(certificate.getEncoded()); - } catch (CertificateEncodingException e) { - throw new RuntimeException("certificate encoding error: " + e.getMessage(), e); - } - } - - RevocationValuesType revocationValues = unsignedSigProps.addNewRevocationValues(); - createRevocationValues(revocationValues, revocationData); - - // marshal XAdES-X-L - Node n = document.importNode(qualProps.getDomNode(), true); - qualNl.item(0).getParentNode().replaceChild(n, qualNl.item(0)); - } - - public static byte[] getC14nValue(List nodeList, String c14nAlgoId) { - ByteArrayOutputStream c14nValue = new ByteArrayOutputStream(); - try { - for (Node node : nodeList) { - /* - * Re-initialize the c14n else the namespaces will get cached - * and will be missing from the c14n resulting nodes. - */ - Canonicalizer c14n = Canonicalizer.getInstance(c14nAlgoId); - c14nValue.write(c14n.canonicalizeSubtree(node)); - } - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new RuntimeException("c14n error: " + e.getMessage(), e); - } - return c14nValue.toByteArray(); - } - - private BigInteger getCrlNumber(X509CRL crl) { - byte[] crlNumberExtensionValue = crl.getExtensionValue(Extension.cRLNumber.getId()); - if (null == crlNumberExtensionValue) { - return null; - } - - try { - ASN1InputStream asn1IS1 = null, asn1IS2 = null; - try { - asn1IS1 = new ASN1InputStream(crlNumberExtensionValue); - ASN1OctetString octetString = (ASN1OctetString)asn1IS1.readObject(); - byte[] octets = octetString.getOctets(); - asn1IS2 = new ASN1InputStream(octets); - ASN1Integer integer = (ASN1Integer)asn1IS2.readObject(); - return integer.getPositiveValue(); - } finally { - asn1IS2.close(); - asn1IS1.close(); - } - } catch (IOException e) { - throw new RuntimeException("I/O error: " + e.getMessage(), e); - } - } - - private XAdESTimeStampType createXAdESTimeStamp( - List nodeList, - RevocationData revocationData) { - byte[] c14nSignatureValueElement = getC14nValue(nodeList, signatureConfig.getXadesCanonicalizationMethod()); - - return createXAdESTimeStamp(c14nSignatureValueElement, revocationData); - } - - private XAdESTimeStampType createXAdESTimeStamp(byte[] data, RevocationData revocationData) { - // create the time-stamp - byte[] timeStampToken; - try { - timeStampToken = signatureConfig.getTspService().timeStamp(data, revocationData); - } catch (Exception e) { - throw new RuntimeException("error while creating a time-stamp: " - + e.getMessage(), e); - } - - // create a XAdES time-stamp container - XAdESTimeStampType xadesTimeStamp = XAdESTimeStampType.Factory.newInstance(); - xadesTimeStamp.setId("time-stamp-" + UUID.randomUUID().toString()); - CanonicalizationMethodType c14nMethod = xadesTimeStamp.addNewCanonicalizationMethod(); - c14nMethod.setAlgorithm(signatureConfig.getXadesCanonicalizationMethod()); - - // embed the time-stamp - EncapsulatedPKIDataType encapsulatedTimeStamp = xadesTimeStamp.addNewEncapsulatedTimeStamp(); - encapsulatedTimeStamp.setByteArrayValue(timeStampToken); - encapsulatedTimeStamp.setId("time-stamp-token-" + UUID.randomUUID().toString()); - - return xadesTimeStamp; - } - - private ValidationDataType createValidationData( - RevocationData revocationData) { - ValidationDataType validationData = ValidationDataType.Factory.newInstance(); - RevocationValuesType revocationValues = validationData.addNewRevocationValues(); - createRevocationValues(revocationValues, revocationData); - return validationData; - } - - private void createRevocationValues( - RevocationValuesType revocationValues, RevocationData revocationData) { - if (revocationData.hasCRLs()) { - CRLValuesType crlValues = revocationValues.addNewCRLValues(); - for (byte[] crl : revocationData.getCRLs()) { - EncapsulatedPKIDataType encapsulatedCrlValue = crlValues.addNewEncapsulatedCRLValue(); - encapsulatedCrlValue.setByteArrayValue(crl); - } - } - if (revocationData.hasOCSPs()) { - OCSPValuesType ocspValues = revocationValues.addNewOCSPValues(); - for (byte[] ocsp : revocationData.getOCSPs()) { - EncapsulatedPKIDataType encapsulatedOcspValue = ocspValues.addNewEncapsulatedOCSPValue(); - encapsulatedOcspValue.setByteArrayValue(ocsp); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java deleted file mode 100644 index 495d843b4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RelationshipTransformService.java +++ /dev/null @@ -1,248 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.InvalidAlgorithmParameterException; -import java.security.Provider; -import java.security.Security; -import java.security.spec.AlgorithmParameterSpec; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import javax.xml.crypto.Data; -import javax.xml.crypto.MarshalException; -import javax.xml.crypto.OctetStreamData; -import javax.xml.crypto.XMLCryptoContext; -import javax.xml.crypto.XMLStructure; -import javax.xml.crypto.dom.DOMStructure; -import javax.xml.crypto.dsig.TransformException; -import javax.xml.crypto.dsig.TransformService; -import javax.xml.crypto.dsig.spec.TransformParameterSpec; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.XmlSort; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.CTRelationshipReference; -import org.openxmlformats.schemas.xpackage.x2006.digitalSignature.RelationshipReferenceDocument; -import org.openxmlformats.schemas.xpackage.x2006.relationships.CTRelationship; -import org.openxmlformats.schemas.xpackage.x2006.relationships.CTRelationships; -import org.openxmlformats.schemas.xpackage.x2006.relationships.RelationshipsDocument; -import org.openxmlformats.schemas.xpackage.x2006.relationships.STTargetMode; -import org.w3.x2000.x09.xmldsig.TransformDocument; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -/** - * JSR105 implementation of the RelationshipTransform transformation. - * - *

        - * Specs: http://openiso.org/Ecma/376/Part2/12.2.4#26 - *

        - */ -public class RelationshipTransformService extends TransformService { - - public static final String TRANSFORM_URI = "http://schemas.openxmlformats.org/package/2006/RelationshipTransform"; - - private final List sourceIds; - - private static final POILogger LOG = POILogFactory.getLogger(RelationshipTransformService.class); - - /** - * Relationship Transform parameter specification class. - */ - public static class RelationshipTransformParameterSpec implements TransformParameterSpec { - List sourceIds = new ArrayList(); - public void addRelationshipReference(String relationshipId) { - sourceIds.add(relationshipId); - } - public boolean hasSourceIds() { - return !sourceIds.isEmpty(); - } - } - - - public RelationshipTransformService() { - super(); - LOG.log(POILogger.DEBUG, "constructor"); - this.sourceIds = new ArrayList(); - } - - /** - * Register the provider for this TransformService - * - * @see javax.xml.crypto.dsig.TransformService - */ - public static synchronized void registerDsigProvider() { - // the xml signature classes will try to find a special TransformerService, - // which is ofcourse unknown to JCE before ... - final String dsigProvider = "POIXmlDsigProvider"; - if (Security.getProperty(dsigProvider) == null) { - Provider p = new Provider(dsigProvider, 1.0, dsigProvider){ - static final long serialVersionUID = 1L; - }; - p.put("TransformService." + TRANSFORM_URI, RelationshipTransformService.class.getName()); - p.put("TransformService." + TRANSFORM_URI + " MechanismType", "DOM"); - Security.addProvider(p); - } - } - - - @Override - public void init(TransformParameterSpec params) throws InvalidAlgorithmParameterException { - LOG.log(POILogger.DEBUG, "init(params)"); - if (!(params instanceof RelationshipTransformParameterSpec)) { - throw new InvalidAlgorithmParameterException(); - } - RelationshipTransformParameterSpec relParams = (RelationshipTransformParameterSpec) params; - for (String sourceId : relParams.sourceIds) { - this.sourceIds.add(sourceId); - } - } - - @Override - public void init(XMLStructure parent, XMLCryptoContext context) throws InvalidAlgorithmParameterException { - LOG.log(POILogger.DEBUG, "init(parent,context)"); - LOG.log(POILogger.DEBUG, "parent java type: " + parent.getClass().getName()); - DOMStructure domParent = (DOMStructure) parent; - Node parentNode = domParent.getNode(); - - try { - TransformDocument transDoc = TransformDocument.Factory.parse(parentNode, DEFAULT_XML_OPTIONS); - XmlObject xoList[] = transDoc.getTransform().selectChildren(RelationshipReferenceDocument.type.getDocumentElementName()); - if (xoList.length == 0) { - LOG.log(POILogger.WARN, "no RelationshipReference/@SourceId parameters present"); - } - for (XmlObject xo : xoList) { - String sourceId = ((CTRelationshipReference)xo).getSourceId(); - LOG.log(POILogger.DEBUG, "sourceId: ", sourceId); - this.sourceIds.add(sourceId); - } - } catch (XmlException e) { - throw new InvalidAlgorithmParameterException(e); - } - } - - @Override - public void marshalParams(XMLStructure parent, XMLCryptoContext context) throws MarshalException { - LOG.log(POILogger.DEBUG, "marshallParams(parent,context)"); - DOMStructure domParent = (DOMStructure) parent; - Element parentNode = (Element)domParent.getNode(); - // parentNode.setAttributeNS(XML_NS, "xmlns:mdssi", XML_DIGSIG_NS); - Document doc = parentNode.getOwnerDocument(); - - for (String sourceId : this.sourceIds) { - RelationshipReferenceDocument relRef = RelationshipReferenceDocument.Factory.newInstance(); - relRef.addNewRelationshipReference().setSourceId(sourceId); - Node n = relRef.getRelationshipReference().getDomNode(); - n = doc.importNode(n, true); - parentNode.appendChild(n); - } - } - - public AlgorithmParameterSpec getParameterSpec() { - LOG.log(POILogger.DEBUG, "getParameterSpec"); - return null; - } - - public Data transform(Data data, XMLCryptoContext context) throws TransformException { - LOG.log(POILogger.DEBUG, "transform(data,context)"); - LOG.log(POILogger.DEBUG, "data java type: " + data.getClass().getName()); - OctetStreamData octetStreamData = (OctetStreamData) data; - LOG.log(POILogger.DEBUG, "URI: " + octetStreamData.getURI()); - InputStream octetStream = octetStreamData.getOctetStream(); - - RelationshipsDocument relDoc; - try { - relDoc = RelationshipsDocument.Factory.parse(octetStream, DEFAULT_XML_OPTIONS); - } catch (Exception e) { - throw new TransformException(e.getMessage(), e); - } - LOG.log(POILogger.DEBUG, "relationships document", relDoc); - - CTRelationships rels = relDoc.getRelationships(); - List relList = rels.getRelationshipList(); - Iterator relIter = rels.getRelationshipList().iterator(); - while (relIter.hasNext()) { - CTRelationship rel = relIter.next(); - /* - * See: ISO/IEC 29500-2:2008(E) - 13.2.4.24 Relationships Transform - * Algorithm. - */ - if (!this.sourceIds.contains(rel.getId())) { - LOG.log(POILogger.DEBUG, "removing element: " + rel.getId()); - relIter.remove(); - } else { - if (!rel.isSetTargetMode()) { - rel.setTargetMode(STTargetMode.INTERNAL); - } - } - } - - // TODO: remove non element nodes ??? - LOG.log(POILogger.DEBUG, "# Relationship elements", relList.size()); - - XmlSort.sort(rels, new Comparator(){ - public int compare(XmlCursor c1, XmlCursor c2) { - String id1 = ((CTRelationship)c1.getObject()).getId(); - String id2 = ((CTRelationship)c2.getObject()).getId(); - return id1.compareTo(id2); - } - }); - - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - XmlOptions xo = new XmlOptions(); - xo.setSaveNoXmlDecl(); - relDoc.save(bos, xo); - return new OctetStreamData(new ByteArrayInputStream(bos.toByteArray())); - } catch (IOException e) { - throw new TransformException(e.getMessage(), e); - } - } - - public Data transform(Data data, XMLCryptoContext context, OutputStream os) throws TransformException { - LOG.log(POILogger.DEBUG, "transform(data,context,os)"); - return null; - } - - public boolean isFeatureSupported(String feature) { - LOG.log(POILogger.DEBUG, "isFeatureSupported(feature)"); - return false; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java deleted file mode 100644 index 22e667bf1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationData.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -import java.security.cert.CRLException; -import java.security.cert.X509CRL; -import java.util.ArrayList; -import java.util.List; - -/** - * Container class for PKI revocation data. - * - * @author Frank Cornelis - * - */ -public class RevocationData { - - private final List crls; - - private final List ocsps; - - /** - * Default constructor. - */ - public RevocationData() { - this.crls = new ArrayList(); - this.ocsps = new ArrayList(); - } - - /** - * Adds a CRL to this revocation data set. - * - * @param encodedCrl - */ - public void addCRL(byte[] encodedCrl) { - this.crls.add(encodedCrl); - } - - /** - * Adds a CRL to this revocation data set. - * - * @param crl - */ - public void addCRL(X509CRL crl) { - byte[] encodedCrl; - try { - encodedCrl = crl.getEncoded(); - } catch (CRLException e) { - throw new IllegalArgumentException("CRL coding error: " - + e.getMessage(), e); - } - addCRL(encodedCrl); - } - - /** - * Adds an OCSP response to this revocation data set. - * - * @param encodedOcsp - */ - public void addOCSP(byte[] encodedOcsp) { - this.ocsps.add(encodedOcsp); - } - - /** - * Gives back a list of all CRLs. - * - * @return a list of all CRLs - */ - public List getCRLs() { - return this.crls; - } - - /** - * Gives back a list of all OCSP responses. - * - * @return a list of all OCSP response - */ - public List getOCSPs() { - return this.ocsps; - } - - /** - * Returns true if this revocation data set holds OCSP - * responses. - * - * @return true if this revocation data set holds OCSP - * responses. - */ - public boolean hasOCSPs() { - return false == this.ocsps.isEmpty(); - } - - /** - * Returns true if this revocation data set holds CRLs. - * - * @return true if this revocation data set holds CRLs. - */ - public boolean hasCRLs() { - return false == this.crls.isEmpty(); - } - - /** - * Returns true if this revocation data is not empty. - * - * @return true if this revocation data is not empty. - */ - public boolean hasRevocationDataEntries() { - return hasOCSPs() || hasCRLs(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java deleted file mode 100644 index 02bd6a057..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/RevocationDataService.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -import java.security.cert.X509Certificate; -import java.util.List; - -/** - * Interface for a service that retrieves revocation data about some given - * certificate chain. - * - * @author Frank Cornelis - * - */ -public interface RevocationDataService { - - /** - * Gives back the revocation data corresponding with the given certificate - * chain. - * - * @param certificateChain the certificate chain - * @return the revocation data corresponding with the given certificate chain. - */ - RevocationData getRevocationData(List certificateChain); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignaturePolicyService.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignaturePolicyService.java deleted file mode 100644 index 9716e6353..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/SignaturePolicyService.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -/** - * Interface for the signature policy service. - * - * @author Frank Cornelis - * - */ -public interface SignaturePolicyService { - - /** - * Gives back the signature policy identifier URI. - * - * @return the signature policy identifier URI. - */ - String getSignaturePolicyIdentifier(); - - /** - * Gives back the short description of the signature policy or - * null if a description is not available. - * - * @return the description, or null. - */ - String getSignaturePolicyDescription(); - - /** - * Gives back the download URL where the signature policy document can be - * found. Can be null in case such a download location does not - * exist. - * - * @return the download URL, or null. - */ - String getSignaturePolicyDownloadUrl(); - - /** - * Gives back the signature policy document. - * - * @return the bytes of the signature policy document. - */ - byte[] getSignaturePolicyDocument(); -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java deleted file mode 100644 index cc1c4c4a9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java +++ /dev/null @@ -1,261 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.math.BigInteger; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.URL; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.DatatypeConverter; - -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.cmp.PKIFailureInfo; -import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; -import org.bouncycastle.cms.SignerId; -import org.bouncycastle.cms.SignerInformationVerifier; -import org.bouncycastle.cms.bc.BcRSASignerInfoVerifierBuilder; -import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; -import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; -import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; -import org.bouncycastle.tsp.TimeStampRequest; -import org.bouncycastle.tsp.TimeStampRequestGenerator; -import org.bouncycastle.tsp.TimeStampResponse; -import org.bouncycastle.tsp.TimeStampToken; - -/** - * A TSP time-stamp service implementation. - * - * @author Frank Cornelis - * - */ -public class TSPTimeStampService implements TimeStampService { - - private static final POILogger LOG = POILogFactory.getLogger(TSPTimeStampService.class); - - private SignatureConfig signatureConfig; - - /** - * Maps the digest algorithm to corresponding OID value. - */ - public ASN1ObjectIdentifier mapDigestAlgoToOID(HashAlgorithm digestAlgo) { - switch (digestAlgo) { - case sha1: return X509ObjectIdentifiers.id_SHA1; - case sha256: return NISTObjectIdentifiers.id_sha256; - case sha384: return NISTObjectIdentifiers.id_sha384; - case sha512: return NISTObjectIdentifiers.id_sha512; - default: - throw new IllegalArgumentException("unsupported digest algo: " + digestAlgo); - } - } - - @SuppressWarnings("unchecked") - public byte[] timeStamp(byte[] data, RevocationData revocationData) - throws Exception { - // digest the message - MessageDigest messageDigest = CryptoFunctions.getMessageDigest(signatureConfig.getTspDigestAlgo()); - byte[] digest = messageDigest.digest(data); - - // generate the TSP request - BigInteger nonce = new BigInteger(128, new SecureRandom()); - TimeStampRequestGenerator requestGenerator = new TimeStampRequestGenerator(); - requestGenerator.setCertReq(true); - String requestPolicy = signatureConfig.getTspRequestPolicy(); - if (requestPolicy != null) { - requestGenerator.setReqPolicy(new ASN1ObjectIdentifier(requestPolicy)); - } - ASN1ObjectIdentifier digestAlgoOid = mapDigestAlgoToOID(signatureConfig.getTspDigestAlgo()); - TimeStampRequest request = requestGenerator.generate(digestAlgoOid, digest, nonce); - byte[] encodedRequest = request.getEncoded(); - - // create the HTTP POST request - Proxy proxy = Proxy.NO_PROXY; - if (signatureConfig.getProxyUrl() != null) { - URL proxyUrl = new URL(signatureConfig.getProxyUrl()); - String host = proxyUrl.getHost(); - int port = proxyUrl.getPort(); - proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(InetAddress.getByName(host), (port == -1 ? 80 : port))); - } - - HttpURLConnection huc = (HttpURLConnection)new URL(signatureConfig.getTspUrl()).openConnection(proxy); - - if (signatureConfig.getTspUser() != null) { - String userPassword = signatureConfig.getTspUser() + ":" + signatureConfig.getTspPass(); - String encoding = DatatypeConverter.printBase64Binary(userPassword.getBytes(Charset.forName("iso-8859-1"))); - huc.setRequestProperty("Authorization", "Basic " + encoding); - } - - huc.setRequestMethod("POST"); - huc.setConnectTimeout(20000); - huc.setReadTimeout(20000); - huc.setDoOutput(true); // also sets method to POST. - huc.setRequestProperty("User-Agent", signatureConfig.getUserAgent()); - huc.setRequestProperty("Content-Type", signatureConfig.isTspOldProtocol() - ? "application/timestamp-request" - : "application/timestamp-query"); // "; charset=ISO-8859-1"); - - OutputStream hucOut = huc.getOutputStream(); - hucOut.write(encodedRequest); - - // invoke TSP service - huc.connect(); - - int statusCode = huc.getResponseCode(); - if (statusCode != 200) { - LOG.log(POILogger.ERROR, "Error contacting TSP server ", signatureConfig.getTspUrl() + - ", had status code " + statusCode + "/" + huc.getResponseMessage()); - throw new IOException("Error contacting TSP server " + signatureConfig.getTspUrl() + - ", had status code " + statusCode + "/" + huc.getResponseMessage()); - } - - // HTTP input validation - String contentType = huc.getHeaderField("Content-Type"); - if (null == contentType) { - throw new RuntimeException("missing Content-Type header"); - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(huc.getInputStream(), bos); - LOG.log(POILogger.DEBUG, "response content: ", HexDump.dump(bos.toByteArray(), 0, 0)); - - if (!contentType.startsWith(signatureConfig.isTspOldProtocol() - ? "application/timestamp-response" - : "application/timestamp-reply" - )) { - throw new RuntimeException("invalid Content-Type: " + contentType + - // dump the first few bytes - ": " + HexDump.dump(bos.toByteArray(), 0, 0, 200)); - } - - if (bos.size() == 0) { - throw new RuntimeException("Content-Length is zero"); - } - - // TSP response parsing and validation - TimeStampResponse timeStampResponse = new TimeStampResponse(bos.toByteArray()); - timeStampResponse.validate(request); - - if (0 != timeStampResponse.getStatus()) { - LOG.log(POILogger.DEBUG, "status: " + timeStampResponse.getStatus()); - LOG.log(POILogger.DEBUG, "status string: " + timeStampResponse.getStatusString()); - PKIFailureInfo failInfo = timeStampResponse.getFailInfo(); - if (null != failInfo) { - LOG.log(POILogger.DEBUG, "fail info int value: " + failInfo.intValue()); - if (/*PKIFailureInfo.unacceptedPolicy*/(1 << 8) == failInfo.intValue()) { - LOG.log(POILogger.DEBUG, "unaccepted policy"); - } - } - throw new RuntimeException("timestamp response status != 0: " - + timeStampResponse.getStatus()); - } - TimeStampToken timeStampToken = timeStampResponse.getTimeStampToken(); - SignerId signerId = timeStampToken.getSID(); - BigInteger signerCertSerialNumber = signerId.getSerialNumber(); - X500Name signerCertIssuer = signerId.getIssuer(); - LOG.log(POILogger.DEBUG, "signer cert serial number: " + signerCertSerialNumber); - LOG.log(POILogger.DEBUG, "signer cert issuer: " + signerCertIssuer); - - // TSP signer certificates retrieval - Collection certificates = timeStampToken.getCertificates().getMatches(null); - - X509CertificateHolder signerCert = null; - Map certificateMap = new HashMap(); - for (X509CertificateHolder certificate : certificates) { - if (signerCertIssuer.equals(certificate.getIssuer()) - && signerCertSerialNumber.equals(certificate.getSerialNumber())) { - signerCert = certificate; - } - certificateMap.put(certificate.getSubject(), certificate); - } - - // TSP signer cert path building - if (signerCert == null) { - throw new RuntimeException("TSP response token has no signer certificate"); - } - List tspCertificateChain = new ArrayList(); - JcaX509CertificateConverter x509converter = new JcaX509CertificateConverter(); - x509converter.setProvider("BC"); - X509CertificateHolder certificate = signerCert; - do { - LOG.log(POILogger.DEBUG, "adding to certificate chain: " + certificate.getSubject()); - tspCertificateChain.add(x509converter.getCertificate(certificate)); - if (certificate.getSubject().equals(certificate.getIssuer())) { - break; - } - certificate = certificateMap.get(certificate.getIssuer()); - } while (null != certificate); - - // verify TSP signer signature - X509CertificateHolder holder = new X509CertificateHolder(tspCertificateChain.get(0).getEncoded()); - DefaultCMSSignatureAlgorithmNameGenerator nameGen = new DefaultCMSSignatureAlgorithmNameGenerator(); - DefaultSignatureAlgorithmIdentifierFinder sigAlgoFinder = new DefaultSignatureAlgorithmIdentifierFinder(); - DefaultDigestAlgorithmIdentifierFinder hashAlgoFinder = new DefaultDigestAlgorithmIdentifierFinder(); - BcDigestCalculatorProvider calculator = new BcDigestCalculatorProvider(); - BcRSASignerInfoVerifierBuilder verifierBuilder = new BcRSASignerInfoVerifierBuilder(nameGen, sigAlgoFinder, hashAlgoFinder, calculator); - SignerInformationVerifier verifier = verifierBuilder.build(holder); - - timeStampToken.validate(verifier); - - // verify TSP signer certificate - if (signatureConfig.getTspValidator() != null) { - signatureConfig.getTspValidator().validate(tspCertificateChain, revocationData); - } - - LOG.log(POILogger.DEBUG, "time-stamp token time: " - + timeStampToken.getTimeStampInfo().getGenTime()); - - return timeStampToken.getEncoded(); - } - - public void setSignatureConfig(SignatureConfig signatureConfig) { - this.signatureConfig = signatureConfig; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java deleted file mode 100644 index 84cde9237..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampService.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable; - - -/** - * Interface for a time-stamp service. - * - * @author Frank Cornelis - * - */ -public interface TimeStampService extends SignatureConfigurable { - - /** - * Gives back the encoded time-stamp token for the given array of data - * bytes. We assume that the time-stamp token itself contains its full - * certificate chain required for proper validation. - * - * @param data - * the data to be time-stamped. - * @param revocationData - * the optional container that needs to be filled up with the - * revocation data used to validate the TSA certificate chain. - * @return the DER encoded time-stamp token. - * @throws Exception - * in case something went wrong. - */ - byte[] timeStamp(byte[] data, RevocationData revocationData) - throws Exception; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java deleted file mode 100644 index 4d36be9ec..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TimeStampServiceValidator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ - -package org.apache.poi.poifs.crypt.dsig.services; - -import java.security.cert.X509Certificate; -import java.util.List; - -/** - * Interface for trust validator of a TSP. - * - * @author Frank Cornelis - * - */ -public interface TimeStampServiceValidator { - - /** - * Validates the given certificate chain. - * - * @param certificateChain - * @param revocationData - * the optional data container that should be filled with - * revocation data that was used to validate the given - * certificate chain. - * @throws Exception - * in case the certificate chain is invalid. - */ - void validate(List certificateChain, - RevocationData revocationData) throws Exception; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java deleted file mode 100644 index 5e1f4b383..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.poifs.crypt.temp; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.SecureRandom; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.openxml4j.util.ZipEntrySource; -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.util.Beta; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; - -/** - * An example ZipEntrySource that has encrypted temp files to ensure that - * sensitive data is not stored in raw format on disk. - */ -@Beta -public class AesZipFileZipEntrySource implements ZipEntrySource { - private static POILogger LOG = POILogFactory.getLogger(AesZipFileZipEntrySource.class); - - private final File tmpFile; - private final ZipFile zipFile; - private final Cipher ci; - private boolean closed; - - public AesZipFileZipEntrySource(File tmpFile, Cipher ci) throws IOException { - this.tmpFile = tmpFile; - this.zipFile = new ZipFile(tmpFile); - this.ci = ci; - this.closed = false; - } - - /** - * Note: the file sizes are rounded up to the next cipher block size, - * so don't rely on file sizes of these custom encrypted zip file entries! - */ - @Override - public Enumeration getEntries() { - return zipFile.entries(); - } - - @Override - public InputStream getInputStream(ZipEntry entry) throws IOException { - InputStream is = zipFile.getInputStream(entry); - return new CipherInputStream(is, ci); - } - - @Override - public void close() throws IOException { - if(!closed) { - zipFile.close(); - if (!tmpFile.delete()) { - LOG.log(POILogger.WARN, tmpFile.getAbsolutePath()+" can't be removed (or was already removed."); - }; - } - closed = true; - } - - @Override - public boolean isClosed() { - return closed; - } - - public static AesZipFileZipEntrySource createZipEntrySource(InputStream is) throws IOException, GeneralSecurityException { - // generate session key - SecureRandom sr = new SecureRandom(); - byte[] ivBytes = new byte[16], keyBytes = new byte[16]; - sr.nextBytes(ivBytes); - sr.nextBytes(keyBytes); - final File tmpFile = TempFile.createTempFile("protectedXlsx", ".zip"); - copyToFile(is, tmpFile, CipherAlgorithm.aes128, keyBytes, ivBytes); - IOUtils.closeQuietly(is); - return fileToSource(tmpFile, CipherAlgorithm.aes128, keyBytes, ivBytes); - } - - private static void copyToFile(InputStream is, File tmpFile, CipherAlgorithm cipherAlgorithm, byte keyBytes[], byte ivBytes[]) throws IOException, GeneralSecurityException { - SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); - Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, "PKCS5Padding"); - - ZipInputStream zis = new ZipInputStream(is); - FileOutputStream fos = new FileOutputStream(tmpFile); - ZipOutputStream zos = new ZipOutputStream(fos); - - ZipEntry ze; - while ((ze = zis.getNextEntry()) != null) { - // the cipher output stream pads the data, therefore we can't reuse the ZipEntry with set sizes - // as those will be validated upon close() - ZipEntry zeNew = new ZipEntry(ze.getName()); - zeNew.setComment(ze.getComment()); - zeNew.setExtra(ze.getExtra()); - zeNew.setTime(ze.getTime()); - // zeNew.setMethod(ze.getMethod()); - zos.putNextEntry(zeNew); - FilterOutputStream fos2 = new FilterOutputStream(zos){ - // don't close underlying ZipOutputStream - @Override - public void close() {} - }; - CipherOutputStream cos = new CipherOutputStream(fos2, ciEnc); - IOUtils.copy(zis, cos); - cos.close(); - fos2.close(); - zos.closeEntry(); - zis.closeEntry(); - } - zos.close(); - fos.close(); - zis.close(); - } - - private static AesZipFileZipEntrySource fileToSource(File tmpFile, CipherAlgorithm cipherAlgorithm, byte keyBytes[], byte ivBytes[]) throws ZipException, IOException { - SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); - Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, "PKCS5Padding"); - return new AesZipFileZipEntrySource(tmpFile, ciDec); - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java deleted file mode 100644 index 7a3981dc5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.poifs.crypt.temp; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; - -/** - * EncryptedTempData can be used to buffer binary data in a secure way, by using encrypted temp files. - */ -@Beta -public class EncryptedTempData { - private static POILogger LOG = POILogFactory.getLogger(EncryptedTempData.class); - - private final static CipherAlgorithm cipherAlgorithm = CipherAlgorithm.aes128; - private final SecretKeySpec skeySpec; - private final byte[] ivBytes; - private final File tempFile; - - public EncryptedTempData() throws IOException { - SecureRandom sr = new SecureRandom(); - ivBytes = new byte[16]; - byte[] keyBytes = new byte[16]; - sr.nextBytes(ivBytes); - sr.nextBytes(keyBytes); - skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); - tempFile = TempFile.createTempFile("poi-temp-data", ".tmp"); - } - - public OutputStream getOutputStream() throws IOException { - Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, null); - return new CipherOutputStream(new FileOutputStream(tempFile), ciEnc); - } - - public InputStream getInputStream() throws IOException { - Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, null); - return new CipherInputStream(new FileInputStream(tempFile), ciDec); - } - - public void dispose() { - if (!tempFile.delete()) { - LOG.log(POILogger.WARN, tempFile.getAbsolutePath()+" can't be removed (or was already removed."); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SXSSFWorkbookWithCustomZipEntrySource.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SXSSFWorkbookWithCustomZipEntrySource.java deleted file mode 100644 index 54600684e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SXSSFWorkbookWithCustomZipEntrySource.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.poifs.crypt.temp; - -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; - -import org.apache.poi.openxml4j.util.ZipEntrySource; -import org.apache.poi.util.Beta; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.streaming.SheetDataWriter; - -@Beta -public class SXSSFWorkbookWithCustomZipEntrySource extends SXSSFWorkbook { - private static final POILogger LOG = POILogFactory.getLogger(SXSSFWorkbookWithCustomZipEntrySource.class); - - public SXSSFWorkbookWithCustomZipEntrySource() { - super(20); - setCompressTempFiles(true); - } - - @Override - public void write(OutputStream stream) throws IOException { - flushSheets(); - EncryptedTempData tempData = new EncryptedTempData(); - ZipEntrySource source = null; - try { - OutputStream os = tempData.getOutputStream(); - try { - getXSSFWorkbook().write(os); - } finally { - IOUtils.closeQuietly(os); - } - // provide ZipEntrySource to poi which decrypts on the fly - source = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream()); - injectData(source, stream); - } catch (GeneralSecurityException e) { - throw new IOException(e); - } finally { - tempData.dispose(); - IOUtils.closeQuietly(source); - } - } - - @Override - protected SheetDataWriter createSheetDataWriter() throws IOException { - //log values to ensure these values are accessible to subclasses - LOG.log(POILogger.INFO, "isCompressTempFiles: " + isCompressTempFiles()); - LOG.log(POILogger.INFO, "SharedStringSource: " + getSharedStringSource()); - return new SheetDataWriterWithDecorator(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SheetDataWriterWithDecorator.java b/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SheetDataWriterWithDecorator.java deleted file mode 100644 index 08163ead9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SheetDataWriterWithDecorator.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.poifs.crypt.temp; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.util.Beta; -import org.apache.poi.xssf.streaming.SheetDataWriter; - -@Beta -public class SheetDataWriterWithDecorator extends SheetDataWriter { - final static CipherAlgorithm cipherAlgorithm = CipherAlgorithm.aes128; - SecretKeySpec skeySpec; - byte[] ivBytes; - - public SheetDataWriterWithDecorator() throws IOException { - super(); - } - - void init() { - if(skeySpec == null) { - SecureRandom sr = new SecureRandom(); - ivBytes = new byte[16]; - byte[] keyBytes = new byte[16]; - sr.nextBytes(ivBytes); - sr.nextBytes(keyBytes); - skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); - } - } - - @Override - protected OutputStream decorateOutputStream(FileOutputStream fos) { - init(); - Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, "PKCS5Padding"); - return new CipherOutputStream(fos, ciEnc); - } - - @Override - protected InputStream decorateInputStream(FileInputStream fis) { - Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, "PKCS5Padding"); - return new CipherInputStream(fis, ciDec); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java b/trunk/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java deleted file mode 100644 index 621e71d8d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java +++ /dev/null @@ -1,281 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.io.*; - -import org.apache.poi.EmptyFileException; -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OfficeXmlFileException; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Factory for creating the appropriate kind of Workbook - * (be it {@link HSSFWorkbook} or {@link XSSFWorkbook}), - * by auto-detecting from the supplied input. - */ -public class WorkbookFactory { - /** - * Creates a HSSFWorkbook from the given POIFSFileSystem - *

        Note that in order to properly release resources the - * Workbook should be closed after use. - */ - public static Workbook create(POIFSFileSystem fs) throws IOException { - return new HSSFWorkbook(fs); - } - - /** - * Creates a HSSFWorkbook from the given NPOIFSFileSystem - *

        Note that in order to properly release resources the - * Workbook should be closed after use. - */ - public static Workbook create(NPOIFSFileSystem fs) throws IOException { - try { - return create(fs, null); - } catch (InvalidFormatException e) { - // Special case of OOXML-in-POIFS which is broken - throw new IOException(e); - } - } - - /** - * Creates a Workbook from the given NPOIFSFileSystem, which may - * be password protected - * - * @param fs The {@link NPOIFSFileSystem} to read the document from - * @param password The password that should be used or null if no password is necessary. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook} - */ - private static Workbook create(final NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException { - DirectoryNode root = fs.getRoot(); - - // Encrypted OOXML files go inside OLE2 containers, is this one? - if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { - InputStream stream = DocumentFactoryHelper.getDecryptedStream(fs, password); - - OPCPackage pkg = OPCPackage.open(stream); - return create(pkg); - } - - // If we get here, it isn't an encrypted XLSX file - // So, treat it as a regular HSSF XLS one - if (password != null) { - Biff8EncryptionKey.setCurrentUserPassword(password); - } - try { - return new HSSFWorkbook(root, true); - } finally { - Biff8EncryptionKey.setCurrentUserPassword(null); - } - } - - /** - * Creates a XSSFWorkbook from the given OOXML Package - * - *

        Note that in order to properly release resources the - * Workbook should be closed after use.

        - * - * @param pkg The {@link OPCPackage} opened for reading data. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - */ - public static Workbook create(OPCPackage pkg) throws IOException { - return new XSSFWorkbook(pkg); - } - - /** - * Creates the appropriate HSSFWorkbook / XSSFWorkbook from - * the given InputStream. - * - *

        Your input stream MUST either support mark/reset, or - * be wrapped as a {@link PushbackInputStream}! Note that - * using an {@link InputStream} has a higher memory footprint - * than using a {@link File}.

        - * - *

        Note that in order to properly release resources the - * Workbook should be closed after use. Note also that loading - * from an InputStream requires more memory than loading - * from a File, so prefer {@link #create(File)} where possible. - * - * @param inp The {@link InputStream} to read data from. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook} - * @throws EncryptedDocumentException If the workbook given is password protected - */ - public static Workbook create(InputStream inp) throws IOException, InvalidFormatException, EncryptedDocumentException { - return create(inp, null); - } - - /** - * Creates the appropriate HSSFWorkbook / XSSFWorkbook from - * the given InputStream, which may be password protected. - *

        Your input stream MUST either support mark/reset, or - * be wrapped as a {@link PushbackInputStream}! Note that - * using an {@link InputStream} has a higher memory footprint - * than using a {@link File}.

        - * - *

        Note that in order to properly release resources the - * Workbook should be closed after use. Note also that loading - * from an InputStream requires more memory than loading - * from a File, so prefer {@link #create(File)} where possible.

        - * - * @param inp The {@link InputStream} to read data from. - * @param password The password that should be used or null if no password is necessary. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook} - * @throws EncryptedDocumentException If the wrong password is given for a protected file - * @throws EmptyFileException If an empty stream is given - */ - public static Workbook create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException { - // If clearly doesn't do mark/reset, wrap up - if (! inp.markSupported()) { - inp = new PushbackInputStream(inp, 8); - } - - // Ensure that there is at least some data there - byte[] header8 = IOUtils.peekFirst8Bytes(inp); - - // Try to create - if (NPOIFSFileSystem.hasPOIFSHeader(header8)) { - NPOIFSFileSystem fs = new NPOIFSFileSystem(inp); - return create(fs, password); - } - if (DocumentFactoryHelper.hasOOXMLHeader(inp)) { - return new XSSFWorkbook(OPCPackage.open(inp)); - } - throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream"); - } - - /** - * Creates the appropriate HSSFWorkbook / XSSFWorkbook from - * the given File, which must exist and be readable. - *

        Note that in order to properly release resources the - * Workbook should be closed after use. - * - * @param file The file to read data from. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook} - * @throws EncryptedDocumentException If the workbook given is password protected - */ - public static Workbook create(File file) throws IOException, InvalidFormatException, EncryptedDocumentException { - return create(file, null); - } - - /** - * Creates the appropriate HSSFWorkbook / XSSFWorkbook from - * the given File, which must exist and be readable, and - * may be password protected - *

        Note that in order to properly release resources the - * Workbook should be closed after use. - * - * @param file The file to read data from. - * @param password The password that should be used or null if no password is necessary. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook} - * @throws EncryptedDocumentException If the wrong password is given for a protected file - * @throws EmptyFileException If an empty stream is given - */ - public static Workbook create(File file, String password) throws IOException, InvalidFormatException, EncryptedDocumentException { - return create(file, password, false); - } - - /** - * Creates the appropriate HSSFWorkbook / XSSFWorkbook from - * the given File, which must exist and be readable, and - * may be password protected - *

        Note that in order to properly release resources the - * Workbook should be closed after use. - * - * @param file The file to read data from. - * @param password The password that should be used or null if no password is necessary. - * @param readOnly If the Workbook should be opened in read-only mode to avoid writing back - * changes when the document is closed. - * - * @return The created Workbook - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook} - * @throws EncryptedDocumentException If the wrong password is given for a protected file - * @throws EmptyFileException If an empty stream is given - */ - public static Workbook create(File file, String password, boolean readOnly) throws IOException, InvalidFormatException, EncryptedDocumentException { - if (! file.exists()) { - throw new FileNotFoundException(file.toString()); - } - - try { - NPOIFSFileSystem fs = new NPOIFSFileSystem(file, readOnly); - try { - return create(fs, password); - } catch (RuntimeException e) { - // ensure that the file-handle is closed again - fs.close(); - - throw e; - } - } catch(OfficeXmlFileException e) { - // opening as .xls failed => try opening as .xlsx - OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE); - try { - return new XSSFWorkbook(pkg); - } catch (IOException ioe) { - // ensure that file handles are closed (use revert() to not re-write the file) - pkg.revert(); - //pkg.close(); - - // rethrow exception - throw ioe; - } catch (RuntimeException ioe) { - // ensure that file handles are closed (use revert() to not re-write the file) - pkg.revert(); - //pkg.close(); - - // rethrow exception - throw ioe; - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/util/DocumentHelper.java b/trunk/src/ooxml/java/org/apache/poi/util/DocumentHelper.java deleted file mode 100644 index 3b7d68ae5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/util/DocumentHelper.java +++ /dev/null @@ -1,176 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.stream.events.Namespace; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -public final class DocumentHelper { - private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class); - - private DocumentHelper() {} - - private static class DocHelperErrorHandler implements ErrorHandler { - - public void warning(SAXParseException exception) throws SAXException { - printError(POILogger.WARN, exception); - } - - public void error(SAXParseException exception) throws SAXException { - printError(POILogger.ERROR, exception); - } - - public void fatalError(SAXParseException exception) throws SAXException { - printError(POILogger.FATAL, exception); - throw exception; - } - - /** Prints the error message. */ - private void printError(int type, SAXParseException ex) { - StringBuilder sb = new StringBuilder(); - - String systemId = ex.getSystemId(); - if (systemId != null) { - int index = systemId.lastIndexOf('/'); - if (index != -1) - systemId = systemId.substring(index + 1); - sb.append(systemId); - } - sb.append(':'); - sb.append(ex.getLineNumber()); - sb.append(':'); - sb.append(ex.getColumnNumber()); - sb.append(": "); - sb.append(ex.getMessage()); - - logger.log(type, sb.toString(), ex); - } - } - - /** - * Creates a new document builder, with sensible defaults - */ - public static synchronized DocumentBuilder newDocumentBuilder() { - try { - DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); - documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER); - documentBuilder.setErrorHandler(new DocHelperErrorHandler()); - return documentBuilder; - } catch (ParserConfigurationException e) { - throw new IllegalStateException("cannot create a DocumentBuilder", e); - } - } - - private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - static { - documentBuilderFactory.setNamespaceAware(true); - documentBuilderFactory.setValidating(false); - trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true); - trySetXercesSecurityManager(documentBuilderFactory); - } - - private static void trySetSAXFeature(DocumentBuilderFactory dbf, String feature, boolean enabled) { - try { - dbf.setFeature(feature, enabled); - } catch (Exception e) { - logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e); - } catch (AbstractMethodError ame) { - logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame); - } - } - - private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf) { - // Try built-in JVM one first, standalone if not - for (String securityManagerClassName : new String[] { - "com.sun.org.apache.xerces.internal.util.SecurityManager", - "org.apache.xerces.util.SecurityManager" - }) { - try { - Object mgr = Class.forName(securityManagerClassName).newInstance(); - Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); - setLimit.invoke(mgr, 4096); - dbf.setAttribute("http://apache.org/xml/properties/security-manager", mgr); - // Stop once one can be setup without error - return; - } catch (Throwable t) { - logger.log(POILogger.WARN, "SAX Security Manager could not be setup", t); - } - } - } - - /** - * Parses the given stream via the default (sensible) - * DocumentBuilder - * @param inp Stream to read the XML data from - * @return the parsed Document - */ - public static Document readDocument(InputStream inp) throws IOException, SAXException { - return newDocumentBuilder().parse(inp); - } - - /** - * Parses the given stream via the default (sensible) - * DocumentBuilder - * @param inp sax source to read the XML data from - * @return the parsed Document - */ - public static Document readDocument(InputSource inp) throws IOException, SAXException { - return newDocumentBuilder().parse(inp); - } - - // must only be used to create empty documents, do not use it for parsing! - private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder(); - - /** - * Creates a new DOM Document - */ - public static synchronized Document createDocument() { - return documentBuilderSingleton.newDocument(); - } - - /** - * Adds a namespace declaration attribute to the given element. - */ - public static void addNamespaceDeclaration(Element element, String namespacePrefix, String namespaceURI) { - element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, - XMLConstants.XMLNS_ATTRIBUTE + ':' + namespacePrefix, - namespaceURI); - } - - /** - * Adds a namespace declaration attribute to the given element. - */ - public static void addNamespaceDeclaration(Element element, Namespace namespace) { - addNamespaceDeclaration(element, namespace.getPrefix(), namespace.getNamespaceURI()); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/util/IdentifierManager.java b/trunk/src/ooxml/java/org/apache/poi/util/IdentifierManager.java deleted file mode 100644 index 4b57e7770..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/util/IdentifierManager.java +++ /dev/null @@ -1,266 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.util; - -import java.util.LinkedList; -import java.util.ListIterator; - -/** - *

        - * 24.08.2009
        - *

        - * - * @author Stefan Stern
        - */ - -public class IdentifierManager { - - public static final long MAX_ID = Long.MAX_VALUE - 1; - - public static final long MIN_ID = 0L; - - /** - * - */ - private final long upperbound; - - /** - * - */ - private final long lowerbound; - - /** - * List of segments of available identifiers - */ - private LinkedList segments; - - /** - * @param lowerbound the lower limit of the id-range to manage. Must be greater than or equal to {@link #MIN_ID}. - * @param upperbound the upper limit of the id-range to manage. Must be less then or equal {@link #MAX_ID}. - */ - public IdentifierManager(long lowerbound, long upperbound) { - if (lowerbound > upperbound) { - throw new IllegalArgumentException("lowerbound must not be greater than upperbound, had " + lowerbound + " and " + upperbound); - } - else if (lowerbound < MIN_ID) { - String message = "lowerbound must be greater than or equal to " + Long.toString(MIN_ID); - throw new IllegalArgumentException(message); - } - else if (upperbound > MAX_ID) { - /* - * while MAX_ID is Long.MAX_VALUE, this check is pointless. But if - * someone subclasses / tweaks the limits, this check is fine. - */ - throw new IllegalArgumentException("upperbound must be less than or equal to " + Long.toString(MAX_ID) + " but had " + upperbound); - } - this.lowerbound = lowerbound; - this.upperbound = upperbound; - this.segments = new LinkedList(); - segments.add(new Segment(lowerbound, upperbound)); - } - - public long reserve(long id) { - if (id < lowerbound || id > upperbound) { - throw new IllegalArgumentException("Value for parameter 'id' was out of bounds, had " + id + ", but should be within [" + lowerbound + ":" + upperbound + "]"); - } - verifyIdentifiersLeft(); - - if (id == upperbound) { - Segment lastSegment = segments.getLast(); - if (lastSegment.end == upperbound) { - lastSegment.end = upperbound - 1; - if (lastSegment.start > lastSegment.end) { - segments.removeLast(); - } - return id; - } - return reserveNew(); - } - - if (id == lowerbound) { - Segment firstSegment = segments.getFirst(); - if (firstSegment.start == lowerbound) { - firstSegment.start = lowerbound + 1; - if (firstSegment.end < firstSegment.start) { - segments.removeFirst(); - } - return id; - } - return reserveNew(); - } - - ListIterator iter = segments.listIterator(); - while (iter.hasNext()) { - Segment segment = iter.next(); - if (segment.end < id) { - continue; - } - else if (segment.start > id) { - break; - } - else if (segment.start == id) { - segment.start = id + 1; - if (segment.end < segment.start) { - iter.remove(); - } - return id; - } - else if (segment.end == id) { - segment.end = id - 1; - if (segment.start > segment.end) { - iter.remove(); - } - return id; - } - else { - iter.add(new Segment(id + 1, segment.end)); - segment.end = id - 1; - return id; - } - } - return reserveNew(); - } - - /** - * @return a new identifier. - * @throws IllegalStateException if no more identifiers are available, then an Exception is raised. - */ - public long reserveNew() { - verifyIdentifiersLeft(); - Segment segment = segments.getFirst(); - long result = segment.start; - segment.start += 1; - if (segment.start > segment.end) { - segments.removeFirst(); - } - return result; - } - - /** - * @param id - * the identifier to release. Must be greater than or equal to - * {@link #lowerbound} and must be less than or equal to {@link #upperbound} - * @return true, if the identifier was reserved and has been successfully - * released, false, if the identifier was not reserved. - */ - public boolean release(long id) { - if (id < lowerbound || id > upperbound) { - throw new IllegalArgumentException("Value for parameter 'id' was out of bounds, had " + id + ", but should be within [" + lowerbound + ":" + upperbound + "]"); - } - - if (id == upperbound) { - Segment lastSegment = segments.getLast(); - if (lastSegment.end == upperbound - 1) { - lastSegment.end = upperbound; - return true; - } else if (lastSegment.end == upperbound) { - return false; - } else { - segments.add(new Segment(upperbound, upperbound)); - return true; - } - } - - if (id == lowerbound) { - Segment firstSegment = segments.getFirst(); - if (firstSegment.start == lowerbound + 1) { - firstSegment.start = lowerbound; - return true; - } else if (firstSegment.start == lowerbound) { - return false; - } else { - segments.addFirst(new Segment(lowerbound, lowerbound)); - return true; - } - } - - long higher = id + 1; - long lower = id - 1; - ListIterator iter = segments.listIterator(); - - while (iter.hasNext()) { - Segment segment = iter.next(); - if (segment.end < lower) { - continue; - } - if (segment.start > higher) { - iter.previous(); - iter.add(new Segment(id, id)); - return true; - } - if (segment.start == higher) { - segment.start = id; - return true; - } - else if (segment.end == lower) { - segment.end = id; - /* check if releasing this elements glues two segments into one */ - if (iter.hasNext()) { - Segment next = iter.next(); - if (next.start == segment.end + 1) { - segment.end = next.end; - iter.remove(); - } - } - return true; - } - else { - /* id was not reserved, return false */ - break; - } - } - return false; - } - - public long getRemainingIdentifiers() { - long result = 0; - for (Segment segment : segments) { - result = result - segment.start; - result = result + segment.end + 1; - } - return result; - } - - /** - * - */ - private void verifyIdentifiersLeft() { - if (segments.isEmpty()) { - throw new IllegalStateException("No identifiers left"); - } - } - - private static class Segment { - - public Segment(long start, long end) { - this.start = start; - this.end = end; - } - - public long start; - public long end; - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - public String toString() { - return "[" + start + "; " + end + "]"; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/util/OOXMLLite.java b/trunk/src/ooxml/java/org/apache/poi/util/OOXMLLite.java deleted file mode 100644 index c42ba5e03..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/util/OOXMLLite.java +++ /dev/null @@ -1,298 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessController; -import java.security.CodeSource; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.regex.Pattern; - -import junit.framework.TestCase; - -import org.junit.Test; -import org.junit.internal.TextListener; -import org.junit.runner.JUnitCore; -import org.junit.runner.Result; - -/** - * Build a 'lite' version of the ooxml-schemas.jar - * - * @author Yegor Kozlov - */ -public final class OOXMLLite { - - /** - * Destination directory to copy filtered classes - */ - private File _destDest; - - /** - * Directory with the compiled ooxml tests - */ - private File _testDir; - - /** - * Reference to the ooxml-schemas.jar - */ - private File _ooxmlJar; - - - OOXMLLite(String dest, String test, String ooxmlJar) { - _destDest = new File(dest); - _testDir = new File(test); - _ooxmlJar = new File(ooxmlJar); - } - - public static void main(String[] args) throws IOException, ClassNotFoundException { - - String dest = null, test = null, ooxml = null; - - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-dest")) dest = args[++i]; - else if (args[i].equals("-test")) test = args[++i]; - else if (args[i].equals("-ooxml")) ooxml = args[++i]; - } - OOXMLLite builder = new OOXMLLite(dest, test, ooxml); - builder.build(); - } - - void build() throws IOException, ClassNotFoundException { - List> lst = new ArrayList>(); - //collect unit tests - String exclude = StringUtil.join("|", - "BaseTestXWorkbook", - "BaseTestXSheet", - "BaseTestXRow", - "BaseTestXCell", - "BaseTestXSSFPivotTable", - "TestSXSSFWorkbook\\$\\d", - "TestUnfixedBugs", - "MemoryUsage", - "TestDataProvider", - "TestDataSamples", - "All.+Tests", - "ZipFileAssert", - "AesZipFileZipEntrySource", - "TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource", - "PkiTestUtils", - "TestCellFormatPart\\$\\d", - "TestSignatureInfo\\$\\d", - "TestCertificateEncryption\\$CertData", - "TestPOIXMLDocument\\$OPCParser", - "TestPOIXMLDocument\\$TestFactory", - "TestXSLFTextParagraph\\$DrawTextParagraphProxy", - "TestXSSFExportToXML\\$\\d", - "TestXSSFExportToXML\\$DummyEntityResolver", - "TestFormulaEvaluatorOnXSSF\\$Result", - "TestFormulaEvaluatorOnXSSF\\$SS", - "TestMultiSheetFormulaEvaluatorOnXSSF\\$Result", - "TestMultiSheetFormulaEvaluatorOnXSSF\\$SS", - "TestXSSFBugs\\$\\d" - ); - System.out.println("Collecting unit tests from " + _testDir); - collectTests(_testDir, _testDir, lst, ".+.class$", ".+(" + exclude + ").class"); - System.out.println("Found " + lst.size() + " classes"); - - //run tests - JUnitCore jUnitCore = new JUnitCore(); - jUnitCore.addListener(new TextListener(System.out)); - Result result = jUnitCore.run(lst.toArray(new Class[lst.size()])); - if (!result.wasSuccessful()) { - throw new RuntimeException("Tests did not succeed, cannot build ooxml-lite jar"); - } - - //see what classes from the ooxml-schemas.jar are loaded - System.out.println("Copying classes to " + _destDest); - Map> classes = getLoadedClasses(_ooxmlJar.getName()); - for (Class cls : classes.values()) { - String className = cls.getName(); - String classRef = className.replace('.', '/') + ".class"; - File destFile = new File(_destDest, classRef); - copyFile(cls.getResourceAsStream('/' + classRef), destFile); - - if(cls.isInterface()){ - /** - * Copy classes and interfaces declared as members of this class - */ - for(Class fc : cls.getDeclaredClasses()){ - className = fc.getName(); - classRef = className.replace('.', '/') + ".class"; - destFile = new File(_destDest, classRef); - copyFile(fc.getResourceAsStream('/' + classRef), destFile); - } - } - } - - //finally copy the compiled .xsb files - System.out.println("Copying .xsb resources"); - JarFile jar = new JarFile(_ooxmlJar); - Pattern p = Pattern.compile("schemaorg_apache_xmlbeans/(system|element)/.*\\.xsb"); - try { - for(Enumeration e = jar.entries(); e.hasMoreElements(); ){ - JarEntry je = e.nextElement(); - if(p.matcher(je.getName()).matches()) { - File destFile = new File(_destDest, je.getName()); - copyFile(jar.getInputStream(je), destFile); - } - } - } finally { - jar.close(); - } - } - - private static boolean checkForTestAnnotation(Class testclass) { - for (Method m : testclass.getDeclaredMethods()) { - if(m.isAnnotationPresent(Test.class)) { - return true; - } - } - - // also check super classes - if(testclass.getSuperclass() != null) { - for (Method m : testclass.getSuperclass().getDeclaredMethods()) { - if(m.isAnnotationPresent(Test.class)) { - return true; - } - } - } - - System.out.println("Class " + testclass.getName() + " does not derive from TestCase and does not have a @Test annotation"); - - // Should we also look at superclasses to find cases - // where we have abstract base classes with derived tests? - // if(checkForTestAnnotation(testclass.getSuperclass())) return true; - - return false; - } - - /** - * Recursively collect classes from the supplied directory - * - * @param arg the directory to search in - * @param out output - * @param ptrn the pattern (regexp) to filter found files - */ - private static void collectTests(File root, File arg, List> out, String ptrn, String exclude) - throws ClassNotFoundException { - if (arg.isDirectory()) { - File files[] = arg.listFiles(); - if (files != null) { - for (File f : files) { - collectTests(root, f, out, ptrn, exclude); - } - } - } else { - String path = arg.getAbsolutePath(); - String prefix = root.getAbsolutePath(); - String cls = path.substring(prefix.length() + 1).replace(File.separator, "."); - if(!cls.matches(ptrn)) return; - if (cls.matches(exclude)) return; - //ignore inner classes defined in tests - if (cls.indexOf('$') != -1) { - System.out.println("Inner class " + cls + " not included"); - return; - } - - cls = cls.replace(".class", ""); - - Class testclass = Class.forName(cls); - if (TestCase.class.isAssignableFrom(testclass) - || checkForTestAnnotation(testclass)) { - out.add(testclass); - } - } - } - - /** - * - * @param ptrn the pattern to filter output - * @return the classes loaded by the system class loader keyed by class name - */ - @SuppressWarnings("unchecked") - private static Map> getLoadedClasses(String ptrn) { - // make the field accessible, we defer this from static initialization to here to - // allow JDKs which do not have this field (e.g. IBM JDK) to at least load the class - // without failing, see https://issues.apache.org/bugzilla/show_bug.cgi?id=56550 - final Field _classes = AccessController.doPrivileged(new PrivilegedAction() { - @SuppressForbidden("TODO: Reflection works until Java 8 on Oracle/Sun JDKs, but breaks afterwards (different classloader types, access checks)") - public Field run() { - try { - Field fld = ClassLoader.class.getDeclaredField("classes"); - fld.setAccessible(true); - return fld; - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - }); - - ClassLoader appLoader = ClassLoader.getSystemClassLoader(); - try { - Vector> classes = (Vector>) _classes.get(appLoader); - Map> map = new HashMap>(); - for (Class cls : classes) { - // e.g. proxy-classes, ... - ProtectionDomain pd = cls.getProtectionDomain(); - if (pd == null) continue; - CodeSource cs = pd.getCodeSource(); - if (cs == null) continue; - URL loc = cs.getLocation(); - if (loc == null) continue; - - String jar = loc.toString(); - if(jar.indexOf(ptrn) != -1) map.put(cls.getName(), cls); - } - return map; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - private static void copyFile(InputStream srcStream, File destFile) throws IOException { - File destDirectory = destFile.getParentFile(); - if (!(destDirectory.exists() || destDirectory.mkdirs())) { - throw new RuntimeException("Can't create destination directory: "+destDirectory); - } - ; - OutputStream destStream = new FileOutputStream(destFile); - try { - IOUtils.copy(srcStream, destStream); - } finally { - destStream.close(); - } - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/util/PackageHelper.java b/trunk/src/ooxml/java/org/apache/poi/util/PackageHelper.java deleted file mode 100644 index 884868f1b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/util/PackageHelper.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import org.apache.poi.openxml4j.opc.*; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.util.IOUtils; -import org.apache.poi.POIXMLException; - -import java.io.*; -import java.net.URI; - -/** - * Provides handy methods to work with OOXML packages - */ -public final class PackageHelper { - - public static OPCPackage open(InputStream is) throws IOException { - try { - return OPCPackage.open(is); - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } - } - - /** - * Clone the specified package. - * - * @param pkg the package to clone - * @param file the destination file - * @return the cloned package - */ - public static OPCPackage clone(OPCPackage pkg, File file) throws OpenXML4JException, IOException { - - String path = file.getAbsolutePath(); - - OPCPackage dest = OPCPackage.create(path); - PackageRelationshipCollection rels = pkg.getRelationships(); - for (PackageRelationship rel : rels) { - PackagePart part = pkg.getPart(rel); - PackagePart part_tgt; - if (rel.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) { - copyProperties(pkg.getPackageProperties(), dest.getPackageProperties()); - continue; - } - dest.addRelationship(part.getPartName(), rel.getTargetMode(), rel.getRelationshipType()); - part_tgt = dest.createPart(part.getPartName(), part.getContentType()); - - OutputStream out = part_tgt.getOutputStream(); - IOUtils.copy(part.getInputStream(), out); - out.close(); - - if(part.hasRelationships()) { - copy(pkg, part, dest, part_tgt); - } - } - dest.close(); - - //the temp file will be deleted when JVM terminates - new File(path).deleteOnExit(); - return OPCPackage.open(path); - } - - /** - * Recursively copy package parts to the destination package - */ - private static void copy(OPCPackage pkg, PackagePart part, OPCPackage tgt, PackagePart part_tgt) throws OpenXML4JException, IOException { - PackageRelationshipCollection rels = part.getRelationships(); - if(rels != null) for (PackageRelationship rel : rels) { - PackagePart p; - if(rel.getTargetMode() == TargetMode.EXTERNAL){ - part_tgt.addExternalRelationship(rel.getTargetURI().toString(), rel.getRelationshipType(), rel.getId()); - //external relations don't have associated package parts - continue; - } - URI uri = rel.getTargetURI(); - - if(uri.getRawFragment() != null) { - part_tgt.addRelationship(uri, rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); - continue; - } - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - p = pkg.getPart(relName); - part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); - - - - - PackagePart dest; - if(!tgt.containPart(p.getPartName())){ - dest = tgt.createPart(p.getPartName(), p.getContentType()); - OutputStream out = dest.getOutputStream(); - IOUtils.copy(p.getInputStream(), out); - out.close(); - copy(pkg, p, tgt, dest); - } - } - } - - /** - * Copy core package properties - * - * @param src source properties - * @param tgt target properties - */ - private static void copyProperties(PackageProperties src, PackageProperties tgt){ - tgt.setCategoryProperty(src.getCategoryProperty().getValue()); - tgt.setContentStatusProperty(src.getContentStatusProperty().getValue()); - tgt.setContentTypeProperty(src.getContentTypeProperty().getValue()); - tgt.setCreatorProperty(src.getCreatorProperty().getValue()); - tgt.setDescriptionProperty(src.getDescriptionProperty().getValue()); - tgt.setIdentifierProperty(src.getIdentifierProperty().getValue()); - tgt.setKeywordsProperty(src.getKeywordsProperty().getValue()); - tgt.setLanguageProperty(src.getLanguageProperty().getValue()); - tgt.setRevisionProperty(src.getRevisionProperty().getValue()); - tgt.setSubjectProperty(src.getSubjectProperty().getValue()); - tgt.setTitleProperty(src.getTitleProperty().getValue()); - tgt.setVersionProperty(src.getVersionProperty().getValue()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/util/SAXHelper.java b/trunk/src/ooxml/java/org/apache/poi/util/SAXHelper.java deleted file mode 100644 index 1fbe744b0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/util/SAXHelper.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.IOException; -import java.io.StringReader; -import java.lang.reflect.Method; - -import javax.xml.XMLConstants; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; - - -/** - * Provides handy methods for working with SAX parsers and readers - */ -public final class SAXHelper { - private static POILogger logger = POILogFactory.getLogger(SAXHelper.class); - - private SAXHelper() {} - - /** - * Creates a new SAX XMLReader, with sensible defaults - */ - public static synchronized XMLReader newXMLReader() throws SAXException, ParserConfigurationException { - XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader(); - xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER); - trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING, true); - trySetXercesSecurityManager(xmlReader); - return xmlReader; - } - - static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() { - @Override - public InputSource resolveEntity(String publicId, String systemId) - throws SAXException, IOException { - return new InputSource(new StringReader("")); - } - }; - - private static final SAXParserFactory saxFactory; - static { - saxFactory = SAXParserFactory.newInstance(); - saxFactory.setValidating(false); - saxFactory.setNamespaceAware(true); - } - - private static void trySetSAXFeature(XMLReader xmlReader, String feature, boolean enabled) { - try { - xmlReader.setFeature(feature, enabled); - } catch (Exception e) { - logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e); - } catch (AbstractMethodError ame) { - logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame); - } - } - - private static void trySetXercesSecurityManager(XMLReader xmlReader) { - // Try built-in JVM one first, standalone if not - for (String securityManagerClassName : new String[] { - "com.sun.org.apache.xerces.internal.util.SecurityManager", - "org.apache.xerces.util.SecurityManager" - }) { - try { - Object mgr = Class.forName(securityManagerClassName).newInstance(); - Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); - setLimit.invoke(mgr, 4096); - xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr); - // Stop once one can be setup without error - return; - } catch (Exception e) { - logger.log(POILogger.WARN, "SAX Security Manager could not be setup", e); - } catch (Error err) { - logger.log(POILogger.WARN, "SAX Security Manager could not be setup", err); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/util/XmlSort.java b/trunk/src/ooxml/java/org/apache/poi/util/XmlSort.java deleted file mode 100644 index e6be79702..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/util/XmlSort.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.util.Comparator; - -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; - -public final class XmlSort { - /** - * Sorts the children of element according to the order indicated by the - * comparator. - * @param element the element whose content is to be sorted. Only element children are sorted, - * attributes are not touched. When elements are reordered, all the text, comments and PIs - * follow the element that they come immediately after. - * @param comp a comparator that is to be used when comparing the QNames of two - * elements. - * @throws IllegalArgumentException if the input XmlObject does not represent - * an element - */ - public static void sort(XmlObject element, Comparator comp) { - XmlCursor headCursor = element.newCursor(); - if (!headCursor.isStart()) { - throw new IllegalStateException("The element parameter must point to a STARTDOC"); - } - // We use insertion sort to minimize the number of swaps, because each swap means - // moving a part of the document - /* headCursor points to the beginning of the list of the already sorted items and - listCursor points to the beginning of the list of unsorted items - At the beginning, headCursor points to the first element and listCursor points to the - second element. The algorithm ends when listCursor cannot be moved to the "next" - element in the unsorted list, i.e. the unsorted list becomes empty */ - boolean moved = headCursor.toFirstChild(); - if (!moved) { - // Cursor was not moved, which means that the given element has no children and - // therefore there is nothing to sort - return; - } - XmlCursor listCursor = headCursor.newCursor(); - boolean moreElements = listCursor.toNextSibling(); - while (moreElements) { - moved = false; - // While we can move the head of the unsorted list, it means that there are still - // items (elements) that need to be sorted - while (headCursor.comparePosition(listCursor) < 0) { - if (comp.compare(headCursor, listCursor) > 0) { - // We have found the position in the sorted list, insert the element and the - // text following the element in the current position - // Move the element - listCursor.moveXml(headCursor); - // Move the text following the element - while (!listCursor.isStart() && !listCursor.isEnd()) - listCursor.moveXml(headCursor); - moreElements = listCursor.isStart(); - moved = true; - break; - } - headCursor.toNextSibling(); - } - if (!moved) { - // Because during the move of a fragment of XML, the listCursor is also moved, in - // case we didn't need to move XML (the new element to be inserted happened to - // be the last one in order), we need to move this cursor - moreElements = listCursor.toNextSibling(); - } - // Reposition the head of the sorted list - headCursor.toParent(); - headCursor.toFirstChild(); - } - } -} - \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/exceptions/XDGFException.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/exceptions/XDGFException.java deleted file mode 100644 index 379877e0d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/exceptions/XDGFException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.exceptions; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; - -public class XDGFException { - - /** - * Creates an error message to be thrown - */ - public static POIXMLException error(String message, Object o) { - return new POIXMLException(o.toString() + ": " + message); - } - - public static POIXMLException error(String message, Object o, Throwable t) { - return new POIXMLException(o.toString() + ": " + message, t); - } - - // - // Use these to wrap error messages coming up so that we have at least - // some idea where the error was located - // - - public static POIXMLException wrap(POIXMLDocumentPart part, - POIXMLException e) { - return new POIXMLException(part.getPackagePart().getPartName() - .toString() - + ": " + e.getMessage(), e.getCause() == null ? e - : e.getCause()); - } - - public static POIXMLException wrap(String where, POIXMLException e) { - return new POIXMLException(where + ": " + e.getMessage(), - e.getCause() == null ? e : e.getCause()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/extractor/XDGFVisioExtractor.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/extractor/XDGFVisioExtractor.java deleted file mode 100644 index 5f474fc73..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/extractor/XDGFVisioExtractor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.extractor; - -import java.io.IOException; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xdgf.usermodel.XDGFPage; -import org.apache.poi.xdgf.usermodel.XmlVisioDocument; -import org.apache.poi.xdgf.usermodel.shape.ShapeTextVisitor; - -/** - * Helper class to extract text from an OOXML Visio File - */ -public class XDGFVisioExtractor extends POIXMLTextExtractor { - - protected final XmlVisioDocument document; - - public XDGFVisioExtractor(XmlVisioDocument document) { - super(document); - this.document = document; - } - - public XDGFVisioExtractor(OPCPackage openPackage) throws IOException { - this(new XmlVisioDocument(openPackage)); - } - - public String getText() { - ShapeTextVisitor visitor = new ShapeTextVisitor(); - - for (XDGFPage page: document.getPages()) { - page.getContent().visitShapes(visitor); - } - - return visitor.getText().toString(); - } - - public static void main(String [] args) throws IOException { - if (args.length < 1) { - System.err.println("Use:"); - System.err.println(" XDGFVisioExtractor "); - System.exit(1); - } - POIXMLTextExtractor extractor = - new XDGFVisioExtractor(POIXMLDocument.openPackage( - args[0] - )); - System.out.println(extractor.getText()); - extractor.close(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/Dimension2dDouble.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/Dimension2dDouble.java deleted file mode 100644 index 94b887e04..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/Dimension2dDouble.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.geom; - -import java.awt.geom.Dimension2D; - -public class Dimension2dDouble extends Dimension2D { - - double width; - double height; - - public Dimension2dDouble() { - width = 0d; - height = 0d; - } - - public Dimension2dDouble(double width, double height) { - this.width = width; - this.height = height; - } - - @Override - public double getWidth() { - return width; - } - - @Override - public double getHeight() { - return height; - } - - @Override - public void setSize(double width, double height) { - this.width = width; - this.height = height; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Dimension2dDouble) { - Dimension2dDouble other = (Dimension2dDouble) obj; - return width == other.width && height == other.height; - } - - return false; - } - - @Override - public int hashCode() { - double sum = width + height; - return (int) Math.ceil(sum * (sum + 1) / 2 + width); - } - - @Override - public String toString() { - return "Dimension2dDouble[" + width + ", " + height + "]"; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/SplineCollector.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/SplineCollector.java deleted file mode 100644 index a977cb627..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/SplineCollector.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.geom; - -import java.awt.geom.Point2D; -import java.util.ArrayList; - -import org.apache.poi.xdgf.usermodel.XDGFShape; -import org.apache.poi.xdgf.usermodel.section.geometry.SplineKnot; -import org.apache.poi.xdgf.usermodel.section.geometry.SplineStart; - -import com.graphbuilder.curve.ControlPath; -import com.graphbuilder.curve.ShapeMultiPath; -import com.graphbuilder.curve.ValueVector; -import com.graphbuilder.geom.PointFactory; - -public class SplineCollector { - - SplineStart _start; - ArrayList _knots = new ArrayList(); - - public SplineCollector(SplineStart start) { - _start = start; - } - - public void addKnot(SplineKnot knot) { - if (!knot.getDel()) - _knots.add(knot); - } - - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - // ok, we have the start, and all knots... do something with this - - Point2D last = path.getCurrentPoint(); - - // create a control path and knots - ControlPath controlPath = new ControlPath(); - ValueVector knots = new ValueVector(_knots.size() + 3); - - double firstKnot = _start.getB(); - double lastKnot = _start.getC(); - int degree = _start.getD(); - - // first/second knot - knots.add(firstKnot); - knots.add(_start.getA()); - - // first/second control point - controlPath.addPoint(PointFactory.create(last.getX(), last.getY())); - controlPath.addPoint(PointFactory.create(_start.getX(), _start.getY())); - - // middle knots/control points - for (SplineKnot knot: _knots) { - knots.add(knot.getA()); - controlPath.addPoint(PointFactory.create(knot.getX(), knot.getY())); - } - - // last knot - knots.add(lastKnot); - - ShapeMultiPath shape = SplineRenderer.createNurbsSpline(controlPath, knots, null, degree); - path.append(shape, true); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/SplineRenderer.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/SplineRenderer.java deleted file mode 100644 index c16835604..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/geom/SplineRenderer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.geom; - -import com.graphbuilder.curve.ControlPath; -import com.graphbuilder.curve.GroupIterator; -import com.graphbuilder.curve.NURBSpline; -import com.graphbuilder.curve.ShapeMultiPath; -import com.graphbuilder.curve.ValueVector; - - -public class SplineRenderer { - - public static ShapeMultiPath createNurbsSpline(ControlPath controlPoints, - ValueVector knots, ValueVector weights, int degree) { - - double firstKnot = knots.get(0); - final int count = knots.size(); - double lastKnot = knots.get(count - 1); - - // scale knots to [0, 1] based on first/last knots - for (int i = 0; i < count; i++) { - knots.set((knots.get(i) - firstKnot) / lastKnot, i); - } - - // if we don't have enough knots, duplicate the last knot until we do - final int knotsToAdd = controlPoints.numPoints() + degree + 1; - for (int i = count; i < knotsToAdd; i++) { - knots.add(1); - } - - GroupIterator gi = new GroupIterator("0:n-1", controlPoints.numPoints()); - - NURBSpline spline = new NURBSpline(controlPoints, gi); - - spline.setDegree(degree); - spline.setKnotVectorType(NURBSpline.NON_UNIFORM); - spline.setKnotVector(knots); - - if (weights == null) { - spline.setUseWeightVector(false); - } else { - spline.setWeightVector(weights); - } - - // now that this is done, add it to the path - ShapeMultiPath shape = new ShapeMultiPath(); - shape.setFlatness(0.01); - - spline.appendTo(shape); - return shape; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java deleted file mode 100644 index 4ee9ee5eb..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java +++ /dev/null @@ -1,172 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.usermodel; - -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Internal; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.poi.xdgf.usermodel.shape.ShapeRenderer; -import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor; -import org.apache.poi.xdgf.usermodel.shape.exceptions.StopVisiting; -import org.apache.poi.xdgf.xml.XDGFXMLDocumentPart; - -import com.microsoft.schemas.office.visio.x2012.main.ConnectType; -import com.microsoft.schemas.office.visio.x2012.main.PageContentsType; -import com.microsoft.schemas.office.visio.x2012.main.ShapeSheetType; - -/** - * Container of shapes for a page in a Visio diagram. Shapes are not - * necessarily literal shapes in the diagram, but is the term that is - * used to describe the basic elements that make up a Visio diagram. - */ -public class XDGFBaseContents extends XDGFXMLDocumentPart { - - protected PageContentsType _pageContents; - - // shapes without parents - protected List _toplevelShapes = new ArrayList(); - protected Map _shapes = new HashMap(); - protected List _connections = new ArrayList(); - - /** - * @since POI 3.14-Beta1 - */ - public XDGFBaseContents(PackagePart part, XDGFDocument document) { - super(part, document); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XDGFBaseContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { - this(part, document); - } - - @Internal - public PageContentsType getXmlObject() { - return _pageContents; - } - - - @Override - protected void onDocumentRead() { - - if (_pageContents.isSetShapes()) { - for (ShapeSheetType shapeSheet: _pageContents.getShapes().getShapeArray()) { - XDGFShape shape = new XDGFShape(shapeSheet, this, _document); - _toplevelShapes.add(shape); - addToShapeIndex(shape); - } - } - - if (_pageContents.isSetConnects()) { - for (ConnectType connect: _pageContents.getConnects().getConnectArray()) { - - XDGFShape from = _shapes.get(connect.getFromSheet()); - XDGFShape to = _shapes.get(connect.getToSheet()); - - if (from == null) - throw new POIXMLException(this.toString() + "; Connect; Invalid from id: " + connect.getFromSheet()); - - if (to == null) - throw new POIXMLException(this.toString() + "; Connect; Invalid to id: " + connect.getToSheet()); - - _connections.add(new XDGFConnection(connect, from, to)); - } - } - } - - protected void addToShapeIndex(XDGFShape shape) { - _shapes.put(shape.getID(), shape); - - List shapes = shape.getShapes(); - if (shapes == null) - return; - - for (XDGFShape subshape: shapes) - addToShapeIndex(subshape); - } - - // - // API - // - - /** - * Draws the contents of a page onto a Graphics2D object - * - * @param graphics - */ - public void draw(Graphics2D graphics) { - visitShapes(new ShapeRenderer(graphics)); - } - - - public XDGFShape getShapeById(long id) { - return _shapes.get(id); - } - - public Map getShapesMap() { - return Collections.unmodifiableMap(_shapes); - } - - public Collection getShapes() { - return _shapes.values(); - } - - public List getTopLevelShapes() { - return Collections.unmodifiableList(_toplevelShapes); - } - - public List getConnections() { - return Collections.unmodifiableList(_connections); - } - - @Override - public String toString() { - return getPackagePart().getPartName().toString(); - } - - - /** - * Provides iteration over the shapes using the visitor pattern, and provides - * an easy way to convert shape coordinates into global coordinates - */ - public void visitShapes(ShapeVisitor visitor) { - try { - for (XDGFShape shape: _toplevelShapes) { - shape.visitShapes(visitor, new AffineTransform(), 0); - } - } catch (StopVisiting e) { - // intentionally empty - } catch (POIXMLException e) { - throw XDGFException.wrap(this, e); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFCell.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFCell.java deleted file mode 100644 index f7f329184..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFCell.java +++ /dev/null @@ -1,162 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.util.Map; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.Internal; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; - -/** - * There are a lot of different cell types. Cell is really just an attribute of - * the thing that it's attached to. Will probably refactor this once I figure - * out a better way to use them - * - * The various attributes of a Cell are constrained, and are better defined in - * the XSD 1.1 visio schema - * - * Values of a cell are often the result of a formula computation. Luckily for - * you, Visio seems to always write the result to the document file, so unless - * the values change we don't need to recompute the values. - */ -public class XDGFCell { - - public static Boolean maybeGetBoolean(Map cells, - String name) { - XDGFCell cell = cells.get(name); - if (cell == null) - return null; - - if (cell.getValue().equals("0")) - return false; - if (cell.getValue().equals("1")) - return true; - - throw new POIXMLException("Invalid boolean value for '" - + cell.getName() + "'"); - } - - public static Double maybeGetDouble(Map cells, String name) { - XDGFCell cell = cells.get(name); - if (cell != null) - return parseDoubleValue(cell._cell); - return null; - } - - public static Integer maybeGetInteger(Map cells, - String name) { - XDGFCell cell = cells.get(name); - if (cell != null) - return parseIntegerValue(cell._cell); - return null; - } - - public static String maybeGetString(Map cells, String name) { - XDGFCell cell = cells.get(name); - if (cell != null) { - String v = cell._cell.getV(); - if (v.equals("Themed")) - return null; - return v; - } - return null; - } - - public static Double parseDoubleValue(CellType cell) { - try { - return Double.parseDouble(cell.getV()); - } catch (NumberFormatException e) { - if (cell.getV().equals("Themed")) - return null; - throw new POIXMLException("Invalid float value for '" + cell.getN() - + "': " + e); - } - } - - public static Integer parseIntegerValue(CellType cell) { - try { - return Integer.parseInt(cell.getV()); - } catch (NumberFormatException e) { - if (cell.getV().equals("Themed")) - return null; - throw new POIXMLException("Invalid integer value for '" - + cell.getN() + "': " + e); - } - } - - /** - * @param cell - * @return A value converted to inches - */ - public static Double parseVLength(CellType cell) { - try { - return Double.parseDouble(cell.getV()); - } catch (NumberFormatException e) { - if (cell.getV().equals("Themed")) - return null; - throw new POIXMLException("Invalid float value for '" + cell.getN() - + "': " + e); - } - } - - CellType _cell; - - public XDGFCell(CellType cell) { - _cell = cell; - } - - @Internal - protected CellType getXmlObject() { - return _cell; - } - - /** - * Represents the name of the ShapeSheet cell. - */ - public String getName() { - return _cell.getN(); - } - - /** - * Represents the value of the cell. - */ - public String getValue() { - return _cell.getV(); - } - - /** - * Represents the element's formula. This attribute can contain one of the - * following strings: - '(some formula)' if the formula exists locally - No - * Formula if the formula is locally deleted or blocked - Inh if the formula - * is inherited. - */ - public String getFormula() { - return _cell.getF(); - } - - /* - * Indicates that the formula evaluates to an error. The value of E is the - * current value (an error message string); the value of the V attribute is - * the last valid value. - */ - public String getError() { - return _cell.getE(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFConnection.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFConnection.java deleted file mode 100644 index cc24a41fc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFConnection.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import com.microsoft.schemas.office.visio.x2012.main.ConnectType; - -/** - * Represents connections in a Visio diagram. - * - * Note that just because something appears to be visually connected in a - * document does not mean that the user actually connected the elements. It - * turns out there are a lot of ways that a careless user can neglect to - * properly make connections that will not be recorded in the diagram - * in a machine readable way. - */ -public class XDGFConnection { - - // comments on frompart/topart taken from pkgVisio - - // https://msdn.microsoft.com/en-us/library/ms367611(v=office.12).aspx - - // The following constants declared by the Microsoft Office Visio type - // library show return values for the FromPart property. - // Constant Value - // visConnectFromError -1 - // visFromNone 0 - // visLeftEdge 1 - // visCenterEdge 2 - // visRightEdge 3 - // visBottomEdge 4 - // visMiddleEdge 5 - // visTopEdge 6 - // visBeginX 7 - // visBeginY 8 - // visBegin 9 - // visEndX 10 - // visEndY 11 - // visEnd 12 - // visFromAngle 13 - // visFromPin 14 - // visControlPoint 100 + zero-based row index (for example, visControlPoint - // = 100 if the control point is in row 0; visControlPoint = 101 if the - // control point is in row 1) - - public static final int visConnectFromError = -1; - public static final int visFromNone = 0; - public static final int visLeftEdge = 1; - public static final int visCenterEdge = 2; - public static final int visRightEdge = 3; - public static final int visBottomEdge = 4; - public static final int visMiddleEdge = 5; - public static final int visTopEdge = 6; - public static final int visBeginX = 7; - public static final int visBeginY = 8; - public static final int visBegin = 9; - public static final int visEndX = 10; - public static final int visEndY = 11; - public static final int visEnd = 12; - public static final int visFromAngle = 13; - public static final int visFromPin = 14; - - // The ToPart property identifies the part of a shape to which another - // shape is glued, such as its begin point or endpoint, one of its edges, - // or a connection point. The following constants declared by the Visio type - // library in member VisToParts show possible return values for the ToPart - // property. - // Constant Value - // visConnectToError -1 - // visToNone 0 - // visGuideX 1 - // visGuideY 2 - // visWholeShape 3 - // visGuideIntersect 4 - // visToAngle 7 - // visConnectionPoint 100 + row index of connection point - - public static final int visConnectToError = -1; - public static final int visToNone = 0; - public static final int visGuideX = 1; - public static final int visGuideY = 2; - public static final int visWholeShape = 3; - public static final int visGuideIntersect = 4; - public static final int visToAngle = 7; - - private ConnectType _connect; - private XDGFShape _from; - private XDGFShape _to; - - public XDGFConnection(ConnectType connect, XDGFShape from, XDGFShape to) { - _connect = connect; - _from = from; - _to = to; - } - - public XDGFShape getFromShape() { - return _from; - } - - public XDGFCell getFromCell() { - return _from.getCell(_connect.getFromCell()); - } - - public String getFromCellName() { - return _connect.getFromCell(); - } - - public XDGFShape getToShape() { - return _to; - } - - public String getToCellName() { - return _connect.getToCell(); - } - - // see constants above - public Integer getFromPart() { - if (_connect.isSetFromPart()) - return _connect.getFromPart(); - else - return null; - } - - /** - * The ToPart property identifies the part of a shape to which another - * shape is glued, such as its begin point or endpoint, one of its edges, - * or a connection point. - */ - public Integer getToPart() { - if (_connect.isSetToPart()) - return _connect.getToPart(); - else - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFDocument.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFDocument.java deleted file mode 100644 index ba460cc13..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFDocument.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.Internal; - -import com.microsoft.schemas.office.visio.x2012.main.DocumentSettingsType; -import com.microsoft.schemas.office.visio.x2012.main.StyleSheetType; -import com.microsoft.schemas.office.visio.x2012.main.VisioDocumentType; - -/** - * Represents the root document: /visio/document.xml - * - * You're probably actually looking for {@link XmlVisioDocument}, this - * only contains metadata about the root document in the OOXML package. - */ -public class XDGFDocument { - - protected VisioDocumentType _document; - - Map _styleSheets = new HashMap(); - - // defaults - long _defaultFillStyle = 0; - long _defaultGuideStyle = 0; - long _defaultLineStyle = 0; - long _defaultTextStyle = 0; - - - public XDGFDocument(VisioDocumentType document) { - - _document = document; - - if (!_document.isSetDocumentSettings()) - throw new POIXMLException("Document settings not found"); - - DocumentSettingsType docSettings = _document.getDocumentSettings(); - - if (docSettings.isSetDefaultFillStyle()) - _defaultFillStyle = docSettings.getDefaultFillStyle(); - - if (docSettings.isSetDefaultGuideStyle()) - _defaultGuideStyle = docSettings.getDefaultGuideStyle(); - - if (docSettings.isSetDefaultLineStyle()) - _defaultLineStyle = docSettings.getDefaultLineStyle(); - - if (docSettings.isSetDefaultTextStyle()) - _defaultTextStyle = docSettings.getDefaultTextStyle(); - - if (_document.isSetStyleSheets()) { - - for (StyleSheetType styleSheet: _document.getStyleSheets().getStyleSheetArray()) { - _styleSheets.put(styleSheet.getID(), new XDGFStyleSheet(styleSheet, this)); - } - } - } - - - @Internal - public VisioDocumentType getXmlObject() { - return _document; - } - - - public XDGFStyleSheet getStyleById(long id) { - return _styleSheets.get(id); - } - - - public XDGFStyleSheet getDefaultFillStyle() { - XDGFStyleSheet style = getStyleById(_defaultFillStyle); - if (style == null) - throw new POIXMLException("No default fill style found!"); - return style; - } - - public XDGFStyleSheet getDefaultGuideStyle() { - XDGFStyleSheet style = getStyleById(_defaultGuideStyle); - if (style == null) - throw new POIXMLException("No default guide style found!"); - return style; - } - - public XDGFStyleSheet getDefaultLineStyle() { - XDGFStyleSheet style = getStyleById(_defaultLineStyle); - if (style == null) - throw new POIXMLException("No default line style found!"); - return style; - } - - public XDGFStyleSheet getDefaultTextStyle() { - XDGFStyleSheet style = getStyleById(_defaultTextStyle); - if (style == null) - throw new POIXMLException("No default text style found!"); - return style; - } - - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java deleted file mode 100644 index 83ac58ce0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLFactory; -import org.apache.poi.POIXMLRelation; - -/** - * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - */ -public class XDGFFactory extends POIXMLFactory { - - private final XDGFDocument document; - - public XDGFFactory(XDGFDocument document) { - this.document = document; - } - - /** - * @since POI 3.14-Beta1 - */ - protected POIXMLRelation getDescriptor(String relationshipType) { - return XDGFRelation.getInstance(relationshipType); - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLDocumentPart createDocumentPart - (Class cls, Class[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Class[] cl; - Object[] vals; - if (classes == null) { - cl = new Class[]{XDGFDocument.class}; - vals = new Object[]{document}; - } else { - cl = new Class[classes.length+1]; - System.arraycopy(classes, 0, cl, 0, classes.length); - cl[classes.length] = XDGFDocument.class; - vals = new Object[values.length+1]; - System.arraycopy(values, 0, vals, 0, values.length); - vals[values.length] = document; - } - - Constructor constructor = cls.getDeclaredConstructor(cl); - return constructor.newInstance(vals); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMaster.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMaster.java deleted file mode 100644 index 68c2c8626..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMaster.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import org.apache.poi.util.Internal; - -import com.microsoft.schemas.office.visio.x2012.main.MasterType; - -/** - * Provides the API to work with an underlying master. Typically, each set of - * stencils used in a Visio diagram are found in a separate master for each. - */ -public class XDGFMaster { - - private MasterType _master; - protected XDGFMasterContents _content; - protected XDGFSheet _pageSheet = null; - - public XDGFMaster(MasterType master, XDGFMasterContents content, - XDGFDocument document) { - _master = master; - _content = content; - content.setMaster(this); - - if (master.isSetPageSheet()) - _pageSheet = new XDGFPageSheet(master.getPageSheet(), document); - } - - @Internal - protected MasterType getXmlObject() { - return _master; - } - - @Override - public String toString() { - return ""; - } - - public long getID() { - return _master.getID(); - } - - public String getName() { - return _master.getName(); - } - - public XDGFMasterContents getContent() { - return _content; - } - - public XDGFSheet getPageSheet() { - return _pageSheet; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java deleted file mode 100644 index 335a32289..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.io.IOException; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.xmlbeans.XmlException; - -import com.microsoft.schemas.office.visio.x2012.main.MasterContentsDocument; - -/** - * Contains the actual contents of the master/stencil - */ -public class XDGFMasterContents extends XDGFBaseContents { - - protected XDGFMaster _master; - - /** - * @since POI 3.14-Beta1 - */ - public XDGFMasterContents(PackagePart part, XDGFDocument document) { - super(part, document); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XDGFMasterContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { - this(part, document); - } - - - @Override - protected void onDocumentRead() { - - try { - - try { - _pageContents = MasterContentsDocument.Factory.parse(getPackagePart().getInputStream()).getMasterContents(); - } catch (XmlException e) { - throw new POIXMLException(e); - } catch (IOException e) { - throw new POIXMLException(e); - } - - super.onDocumentRead(); - - } catch (POIXMLException e) { - throw XDGFException.wrap(this, e); - } - } - - public XDGFMaster getMaster() { - return _master; - } - - protected void setMaster(XDGFMaster master) { - _master = master; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java deleted file mode 100644 index 9fa90b832..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Internal; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.poi.xdgf.xml.XDGFXMLDocumentPart; -import org.apache.xmlbeans.XmlException; - -import com.microsoft.schemas.office.visio.x2012.main.MasterType; -import com.microsoft.schemas.office.visio.x2012.main.MastersDocument; -import com.microsoft.schemas.office.visio.x2012.main.MastersType; - -/** - * A collection of masters (typically stencils) in a Visio document - */ -public class XDGFMasters extends XDGFXMLDocumentPart { - - MastersType _mastersObject; - - // key: id of master - protected Map _masters = new HashMap(); - - /** - * @since POI 3.14-Beta1 - */ - public XDGFMasters(PackagePart part, XDGFDocument document) { - super(part, document); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XDGFMasters(PackagePart part, PackageRelationship rel, XDGFDocument document) { - this(part, document); - } - - @Internal - protected MastersType getXmlObject() { - return _mastersObject; - } - - @Override - protected void onDocumentRead() { - try { - try { - _mastersObject = MastersDocument.Factory.parse(getPackagePart().getInputStream()).getMasters(); - } catch (XmlException e) { - throw new POIXMLException(e); - } catch (IOException e) { - throw new POIXMLException(e); - } - - Map masterSettings = new HashMap(); - for (MasterType master: _mastersObject.getMasterArray()) { - masterSettings.put(master.getRel().getId(), master); - } - - // create the masters - for (RelationPart rp : getRelationParts()) { - POIXMLDocumentPart part = rp.getDocumentPart(); - - String relId = rp.getRelationship().getId(); - MasterType settings = masterSettings.get(relId); - - if (settings == null) { - throw new POIXMLException("Master relationship for " + relId + " not found"); - } - - if (!(part instanceof XDGFMasterContents)) { - throw new POIXMLException("Unexpected masters relationship for " + relId + ": " + part); - } - - XDGFMasterContents contents = (XDGFMasterContents)part; - contents.onDocumentRead(); - - XDGFMaster master = new XDGFMaster(settings, contents, _document); - _masters.put(master.getID(), master); - } - } catch (POIXMLException e) { - throw XDGFException.wrap(this, e); - } - } - - public Collection getMastersList() { - return Collections.unmodifiableCollection(_masters.values()); - } - - public XDGFMaster getMasterById(long masterId) { - return _masters.get(masterId); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPage.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPage.java deleted file mode 100644 index 3bdbd2e1b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPage.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.Internal; -import org.apache.poi.xdgf.geom.Dimension2dDouble; - -import com.microsoft.schemas.office.visio.x2012.main.PageType; - -/** - * Provides the API to work with an underlying page - */ -public class XDGFPage { - - private PageType _page; - protected XDGFPageContents _content; - protected XDGFPages _pages; - protected XDGFSheet _pageSheet = null; - - public XDGFPage(PageType page, XDGFPageContents content, - XDGFDocument document, XDGFPages pages) { - _page = page; - _content = content; - _pages = pages; - content.setPage(this); - - if (page.isSetPageSheet()) - _pageSheet = new XDGFPageSheet(page.getPageSheet(), document); - } - - @Internal - protected PageType getXmlObject() { - return _page; - } - - public long getID() { - return _page.getID(); - } - - public String getName() { - return _page.getName(); - } - - public XDGFPageContents getContent() { - return _content; - } - - public XDGFSheet getPageSheet() { - return _pageSheet; - } - - public long getPageNumber() { - return _pages.getPageList().indexOf(this) + 1; - } - - /** - * @return width/height of page - */ - public Dimension2dDouble getPageSize() { - XDGFCell w = _pageSheet.getCell("PageWidth"); - XDGFCell h = _pageSheet.getCell("PageHeight"); - - if (w == null || h == null) - throw new POIXMLException("Cannot determine page size"); - - return new Dimension2dDouble(Double.parseDouble(w.getValue()), - Double.parseDouble(h.getValue())); - } - - /** - * @return origin of coordinate system - */ - public Point2D.Double getPageOffset() { - XDGFCell xoffcell = _pageSheet.getCell("XRulerOrigin"); - XDGFCell yoffcell = _pageSheet.getCell("YRulerOrigin"); - - double xoffset = 0; - double yoffset = 0; - - if (xoffcell != null) - xoffset = Double.parseDouble(xoffcell.getValue()); - - if (xoffcell != null) - yoffset = Double.parseDouble(yoffcell.getValue()); - - return new Point2D.Double(xoffset, yoffset); - } - - /** - * @return bounding box of page - */ - public Rectangle2D getBoundingBox() { - Dimension2dDouble sz = getPageSize(); - Point2D.Double offset = getPageOffset(); - - return new Rectangle2D.Double(-offset.getX(), -offset.getY(), - sz.getWidth(), sz.getHeight()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java deleted file mode 100644 index e1965f3c2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.xmlbeans.XmlException; - -import com.microsoft.schemas.office.visio.x2012.main.PageContentsDocument; - -public class XDGFPageContents extends XDGFBaseContents { - - protected Map _masters = new HashMap(); - protected XDGFPage _page; - - /** - * @since POI 3.14-Beta1 - */ - public XDGFPageContents(PackagePart part, XDGFDocument document) { - super(part, document); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XDGFPageContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { - this(part, document); - } - - @Override - protected void onDocumentRead() { - try { - try { - _pageContents = PageContentsDocument.Factory.parse(getPackagePart().getInputStream()).getPageContents(); - } catch (XmlException e) { - throw new POIXMLException(e); - } catch (IOException e) { - throw new POIXMLException(e); - } - - for (POIXMLDocumentPart part: getRelations()) { - if (!(part instanceof XDGFMasterContents)) - continue; - //throw new POIXMLException("Unexpected page relation: " + part); - - XDGFMaster master = ((XDGFMasterContents)part).getMaster(); - _masters.put(master.getID(), master); - } - - super.onDocumentRead(); - - for (XDGFShape shape: _shapes.values()) { - if (shape.isTopmost()) - shape.setupMaster(this, null); - } - - } catch (POIXMLException e) { - throw XDGFException.wrap(this, e); - } - } - - /** - * @return Parent page - */ - public XDGFPage getPage() { - return _page; - } - - protected void setPage(XDGFPage page) { - _page = page; - } - - public XDGFMaster getMasterById(long id) { - return _masters.get(id); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageSheet.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageSheet.java deleted file mode 100644 index 1d27969fe..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageSheet.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import com.microsoft.schemas.office.visio.x2012.main.PageSheetType; - -public class XDGFPageSheet extends XDGFSheet { - - PageSheetType _pageSheet; - - public XDGFPageSheet(PageSheetType sheet, XDGFDocument document) { - super(sheet, document); - _pageSheet = sheet; - } - - @Override - PageSheetType getXmlObject() { - return _pageSheet; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java deleted file mode 100644 index a2fc4c7a0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.usermodel; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Internal; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.poi.xdgf.xml.XDGFXMLDocumentPart; -import org.apache.xmlbeans.XmlException; - -import com.microsoft.schemas.office.visio.x2012.main.PageType; -import com.microsoft.schemas.office.visio.x2012.main.PagesDocument; -import com.microsoft.schemas.office.visio.x2012.main.PagesType; - - -/** - * Contains a list of Page objects (not page content!) - */ -public class XDGFPages extends XDGFXMLDocumentPart { - - PagesType _pagesObject; - - // ordered by page number - List _pages = new ArrayList(); - - /** - * @since POI 3.14-Beta1 - */ - public XDGFPages(PackagePart part, XDGFDocument document) { - super(part, document); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XDGFPages(PackagePart part, PackageRelationship rel, XDGFDocument document) { - this(part, document); - } - - @Internal - PagesType getXmlObject() { - return _pagesObject; - } - - @Override - protected void onDocumentRead() { - try { - try { - _pagesObject = PagesDocument.Factory.parse(getPackagePart().getInputStream()).getPages(); - } catch (XmlException e) { - throw new POIXMLException(e); - } catch (IOException e) { - throw new POIXMLException(e); - } - - // this iteration is ordered by page number - for (PageType pageSettings: _pagesObject.getPageArray()) { - - String relId = pageSettings.getRel().getId(); - - POIXMLDocumentPart pageContentsPart = getRelationById(relId); - if (pageContentsPart == null) - throw new POIXMLException("PageSettings relationship for " + relId + " not found"); - - if (!(pageContentsPart instanceof XDGFPageContents)) - throw new POIXMLException("Unexpected pages relationship for " + relId + ": " + pageContentsPart); - - XDGFPageContents contents = (XDGFPageContents)pageContentsPart; - XDGFPage page = new XDGFPage(pageSettings, contents, _document, this); - - contents.onDocumentRead(); - - _pages.add(page); - } - - } catch (POIXMLException e) { - throw XDGFException.wrap(this, e); - } - } - - /** - * @return A list of pages ordered by page number - */ - public List getPageList() { - return Collections.unmodifiableList(_pages); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java deleted file mode 100644 index 3ab1f91d3..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.xdgf.xml.XDGFXMLDocumentPart; - -public class XDGFRelation extends POIXMLRelation { - - /** - * A map to lookup POIXMLRelation by its relation type - */ - private static final Map _table = new HashMap(); - - public static final XDGFRelation DOCUMENT = new XDGFRelation( - "application/vnd.ms-visio.drawing.main+xml", - PackageRelationshipTypes.VISIO_CORE_DOCUMENT, - "/visio/document.xml", null); - - public static final XDGFRelation MASTERS = new XDGFRelation( - "application/vnd.ms-visio.masters+xml", - "http://schemas.microsoft.com/visio/2010/relationships/masters", - "/visio/masters/masters.xml", XDGFMasters.class); - - public static final XDGFRelation MASTER = new XDGFRelation( - "application/vnd.ms-visio.master+xml", - "http://schemas.microsoft.com/visio/2010/relationships/master", - "/visio/masters/master#.xml", XDGFMasterContents.class); - - public static final XDGFRelation IMAGES = new XDGFRelation(null, - PackageRelationshipTypes.IMAGE_PART, null, null // XSSFPictureData.class - ); - - public static final XDGFRelation PAGES = new XDGFRelation( - "application/vnd.ms-visio.pages+xml", - "http://schemas.microsoft.com/visio/2010/relationships/pages", - "/visio/pages/pages.xml", XDGFPages.class); - - public static final XDGFRelation PAGE = new XDGFRelation( - "application/vnd.ms-visio.page+xml", - "http://schemas.microsoft.com/visio/2010/relationships/page", - "/visio/pages/page#.xml", XDGFPageContents.class); - - public static final XDGFRelation WINDOW = new XDGFRelation( - "application/vnd.ms-visio.windows+xml", - "http://schemas.microsoft.com/visio/2010/relationships/windows", - "/visio/windows.xml", null); - - private XDGFRelation(String type, String rel, String defaultName, Class cls) { - super(type, rel, defaultName, cls); - _table.put(rel, this); - } - - /** - * Get POIXMLRelation by relation type - * - * @param rel - * relation type, for example, - * http://schemas.openxmlformats.org/officeDocument/2006/relationships/image - * @return registered POIXMLRelation or null if not found - */ - public static XDGFRelation getInstance(String rel) { - return _table.get(rel); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java deleted file mode 100644 index 42deac4c2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java +++ /dev/null @@ -1,932 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map.Entry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.Internal; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.poi.xdgf.usermodel.section.CombinedIterable; -import org.apache.poi.xdgf.usermodel.section.GeometrySection; -import org.apache.poi.xdgf.usermodel.section.XDGFSection; -import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor; -import org.apache.poi.xdgf.usermodel.shape.exceptions.StopVisitingThisBranch; - -import com.microsoft.schemas.office.visio.x2012.main.ShapeSheetType; -import com.microsoft.schemas.office.visio.x2012.main.TextType; - -/** - * A shape is a collection of Geometry Visualization, Format, Text, Images, and - * Shape Data in a Drawing Page. - */ -public class XDGFShape extends XDGFSheet { - - XDGFBaseContents _parentPage; - XDGFShape _parent; // only non-null if a subshape - - XDGFMaster _master = null; - XDGFShape _masterShape = null; - - XDGFText _text = null; - - // subshapes if they exist - List _shapes = null; - - // properties specific to shapes - - // center of rotation relative to origin of parent - Double _pinX = null; - Double _pinY = null; - - Double _width = null; - Double _height = null; - - // center of rotation relative to self - Double _locPinX = null; - Double _locPinY = null; - - // start x coordinate, relative to parent - // -> one dimensional shapes only - Double _beginX = null; - Double _beginY = null; - - // end x coordinate, relative to parent - // -> one dimensional shapes only - Double _endX = null; - Double _endY = null; - - Double _angle = null; - Double _rotationXAngle = null; - Double _rotationYAngle = null; - Double _rotationZAngle = null; - - // end x coordinate, relative to parent - Boolean _flipX = null; - Boolean _flipY = null; - - // center of text relative to this shape - Double _txtPinX = null; - Double _txtPinY = null; - - // center of text relative to text block - Double _txtLocPinX = null; - Double _txtLocPinY = null; - - Double _txtAngle = null; - - Double _txtWidth = null; - Double _txtHeight = null; - - public XDGFShape(ShapeSheetType shapeSheet, XDGFBaseContents parentPage, - XDGFDocument document) { - this(null, shapeSheet, parentPage, document); - } - - public XDGFShape(XDGFShape parent, ShapeSheetType shapeSheet, - XDGFBaseContents parentPage, XDGFDocument document) { - - super(shapeSheet, document); - - _parent = parent; - _parentPage = parentPage; - - TextType text = shapeSheet.getText(); - if (text != null) - _text = new XDGFText(text, this); - - if (shapeSheet.isSetShapes()) { - _shapes = new ArrayList(); - for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray()) - _shapes.add(new XDGFShape(this, shape, parentPage, document)); - } - - readProperties(); - } - - @Override - public String toString() { - if (_parentPage instanceof XDGFMasterContents) - return _parentPage + ": "; - else - return ""; - } - - protected void readProperties() { - - _pinX = XDGFCell.maybeGetDouble(_cells, "PinX"); - _pinY = XDGFCell.maybeGetDouble(_cells, "PinY"); - _width = XDGFCell.maybeGetDouble(_cells, "Width"); - _height = XDGFCell.maybeGetDouble(_cells, "Height"); - _locPinX = XDGFCell.maybeGetDouble(_cells, "LocPinX"); - _locPinY = XDGFCell.maybeGetDouble(_cells, "LocPinY"); - _beginX = XDGFCell.maybeGetDouble(_cells, "BeginX"); - _beginY = XDGFCell.maybeGetDouble(_cells, "BeginY"); - _endX = XDGFCell.maybeGetDouble(_cells, "EndX"); - _endY = XDGFCell.maybeGetDouble(_cells, "EndY"); - - _angle = XDGFCell.maybeGetDouble(_cells, "Angle"); - _rotationXAngle = XDGFCell.maybeGetDouble(_cells, "RotationXAngle"); - _rotationYAngle = XDGFCell.maybeGetDouble(_cells, "RotationYAngle"); - _rotationZAngle = XDGFCell.maybeGetDouble(_cells, "RotationZAngle"); - - _flipX = XDGFCell.maybeGetBoolean(_cells, "FlipX"); - _flipY = XDGFCell.maybeGetBoolean(_cells, "FlipY"); - - _txtPinX = XDGFCell.maybeGetDouble(_cells, "TxtPinX"); - _txtPinY = XDGFCell.maybeGetDouble(_cells, "TxtPinY"); - _txtLocPinX = XDGFCell.maybeGetDouble(_cells, "TxtLocPinX"); - _txtLocPinY = XDGFCell.maybeGetDouble(_cells, "TxtLocPinY"); - _txtWidth = XDGFCell.maybeGetDouble(_cells, "TxtWidth"); - _txtHeight = XDGFCell.maybeGetDouble(_cells, "TxtHeight"); - - _txtAngle = XDGFCell.maybeGetDouble(_cells, "TxtAngle"); - } - - /** - * Setup top level shapes - * - * Shapes that have a 'Master' attribute refer to a specific master in the - * page, whereas shapes with a 'MasterShape' attribute refer to a subshape - * of a Master. - */ - protected void setupMaster(XDGFPageContents pageContents, - XDGFMasterContents master) { - - ShapeSheetType obj = getXmlObject(); - - if (obj.isSetMaster()) { - _master = pageContents.getMasterById(obj.getMaster()); - if (_master == null) - throw XDGFException.error("refers to non-existant master " - + obj.getMaster(), this); - - /* - * If a master has one top-level shape, a shape that inherits from - * that master inherits the descendant elements of that master - * shape. If a master has more than one master shape, a shape that - * inherits from that master inherits those master shapes as - * subshapes. - */ - - Collection masterShapes = _master.getContent() - .getTopLevelShapes(); - - switch (masterShapes.size()) { - case 0: - throw XDGFException - .error("Could not retrieve master shape from " - + _master, this); - case 1: - _masterShape = masterShapes.iterator().next(); - break; - default: - break; - } - - } else if (obj.isSetMasterShape()) { - _masterShape = master.getShapeById(obj.getMasterShape()); - if (_masterShape == null) - throw XDGFException.error( - "refers to non-existant master shape " - + obj.getMasterShape(), this); - - } - - setupSectionMasters(); - - if (_shapes != null) { - for (XDGFShape shape : _shapes) { - shape.setupMaster(pageContents, _master == null ? master - : _master.getContent()); - } - } - } - - protected void setupSectionMasters() { - - if (_masterShape == null) - return; - - try { - for (Entry section : _sections.entrySet()) { - XDGFSection master = _masterShape.getSection(section.getKey()); - if (master != null) - section.getValue().setupMaster(master); - } - - for (Entry section : _geometry.entrySet()) { - GeometrySection master = _masterShape.getGeometryByIdx(section - .getKey()); - if (master != null) - section.getValue().setupMaster(master); - } - } catch (POIXMLException e) { - throw XDGFException.wrap(this.toString(), e); - } - } - - @Override - @Internal - public ShapeSheetType getXmlObject() { - return (ShapeSheetType) _sheet; - } - - public long getID() { - return getXmlObject().getID(); - } - - public String getType() { - return getXmlObject().getType(); - } - - public String getTextAsString() { - XDGFText text = getText(); - if (text == null) - return ""; - - return text.getTextContent(); - } - - public boolean hasText() { - return _text != null - || (_masterShape != null && _masterShape._text != null); - } - - @Override - public XDGFCell getCell(String cellName) { - XDGFCell _cell = super.getCell(cellName); - - // if not found, ask the master - if (_cell == null && _masterShape != null) { - _cell = _masterShape.getCell(cellName); - } - - return _cell; - } - - public GeometrySection getGeometryByIdx(long idx) { - return _geometry.get(idx); - } - - /** - * Only available if this shape is a shape group, may be null - */ - // -> May be null - public List getShapes() { - return _shapes; - } - - // unique to this shape on the page? - public String getName() { - String name = getXmlObject().getName(); - if (name == null) - return ""; - return name; - } - - // unique to this shape on the page? - public String getShapeType() { - String type = getXmlObject().getType(); - if (type == null) - return ""; - return type; - } - - // name of the symbol that this was derived from - public String getSymbolName() { - - if (_master == null) - return ""; - - String name = _master.getName(); - if (name == null) - return ""; - - return name; - } - - public XDGFShape getMasterShape() { - return _masterShape; - } - - /** - * @return The parent shape if this is a subshape, null otherwise - */ - public XDGFShape getParentShape() { - return _parent; - } - - public XDGFShape getTopmostParentShape() { - XDGFShape top = null; - if (_parent != null) { - top = _parent.getTopmostParentShape(); - if (top == null) - top = _parent; - } - - return top; - } - - public boolean hasMaster() { - return _master != null; - } - - public boolean hasMasterShape() { - return _masterShape != null; - } - - public boolean hasParent() { - return _parent != null; - } - - public boolean hasShapes() { - return _shapes != null; - } - - public boolean isTopmost() { - return _parent == null; - } - - public boolean isShape1D() { - return getBeginX() != null; - } - - public boolean isDeleted() { - return getXmlObject().isSetDel() ? getXmlObject().getDel() : false; - } - - public XDGFText getText() { - if (_text == null && _masterShape != null) - return _masterShape.getText(); - - return _text; - } - - public Double getPinX() { - if (_pinX == null && _masterShape != null) - return _masterShape.getPinX(); - - if (_pinX == null) - throw XDGFException.error("PinX not set!", this); - - return _pinX; - } - - public Double getPinY() { - if (_pinY == null && _masterShape != null) - return _masterShape.getPinY(); - - if (_pinY == null) - throw XDGFException.error("PinY not specified!", this); - - return _pinY; - } - - public Double getWidth() { - if (_width == null && _masterShape != null) - return _masterShape.getWidth(); - - if (_width == null) - throw XDGFException.error("Width not specified!", this); - - return _width; - } - - public Double getHeight() { - if (_height == null && _masterShape != null) - return _masterShape.getHeight(); - - if (_height == null) - throw XDGFException.error("Height not specified!", this); - - return _height; - } - - public Double getLocPinX() { - if (_locPinX == null && _masterShape != null) - return _masterShape.getLocPinX(); - - if (_locPinX == null) - throw XDGFException.error("LocPinX not specified!", this); - - return _locPinX; - } - - public Double getLocPinY() { - if (_locPinY == null && _masterShape != null) - return _masterShape.getLocPinY(); - - if (_locPinY == null) - throw XDGFException.error("LocPinY not specified!", this); - - return _locPinY; - } - - public Double getBeginX() { - if (_beginX == null && _masterShape != null) - return _masterShape.getBeginX(); - - return _beginX; - } - - public Double getBeginY() { - if (_beginY == null && _masterShape != null) - return _masterShape.getBeginY(); - - return _beginY; - } - - public Double getEndX() { - if (_endX == null && _masterShape != null) - return _masterShape.getEndX(); - - return _endX; - } - - public Double getEndY() { - if (_endY == null && _masterShape != null) - return _masterShape.getEndY(); - - return _endY; - } - - public Double getAngle() { - if (_angle == null && _masterShape != null) - return _masterShape.getAngle(); - - return _angle; - } - - public Boolean getFlipX() { - if (_flipX == null && _masterShape != null) - return _masterShape.getFlipX(); - - return _flipX; - } - - public Boolean getFlipY() { - if (_flipY == null && _masterShape != null) - return _masterShape.getFlipY(); - - return _flipY; - } - - public Double getTxtPinX() { - if (_txtPinX == null && _masterShape != null - && _masterShape._txtPinX != null) - return _masterShape._txtPinX; - - if (_txtPinX == null) - return getWidth() * 0.5; - - return _txtPinX; - } - - public Double getTxtPinY() { - if (_txtLocPinY == null && _masterShape != null - && _masterShape._txtLocPinY != null) - return _masterShape._txtLocPinY; - - if (_txtPinY == null) - return getHeight() * 0.5; - - return _txtPinY; - } - - public Double getTxtLocPinX() { - if (_txtLocPinX == null && _masterShape != null - && _masterShape._txtLocPinX != null) - return _masterShape._txtLocPinX; - - if (_txtLocPinX == null) - return getTxtWidth() * 0.5; - - return _txtLocPinX; - } - - public Double getTxtLocPinY() { - if (_txtLocPinY == null && _masterShape != null - && _masterShape._txtLocPinY != null) - return _masterShape._txtLocPinY; - - if (_txtLocPinY == null) - return getTxtHeight() * 0.5; - - return _txtLocPinY; - } - - public Double getTxtAngle() { - if (_txtAngle == null && _masterShape != null) - return _masterShape.getTxtAngle(); - - return _txtAngle; - } - - public Double getTxtWidth() { - if (_txtWidth == null && _masterShape != null - && _masterShape._txtWidth != null) - return _masterShape._txtWidth; - - if (_txtWidth == null) - return getWidth(); - - return _txtWidth; - } - - public Double getTxtHeight() { - if (_txtHeight == null && _masterShape != null - && _masterShape._txtHeight != null) - return _masterShape._txtHeight; - - if (_txtHeight == null) - return getHeight(); - - return _txtHeight; - } - - @Override - public Integer getLineCap() { - - Integer lineCap = super.getLineCap(); - if (lineCap != null) - return lineCap; - - // get from master - if (_masterShape != null) { - return _masterShape.getLineCap(); - } - - // get default - return _document.getDefaultLineStyle().getLineCap(); - } - - @Override - public Color getLineColor() { - - Color lineColor = super.getLineColor(); - if (lineColor != null) - return lineColor; - - // get from master - if (_masterShape != null) { - return _masterShape.getLineColor(); - } - - // get default - return _document.getDefaultLineStyle().getLineColor(); - } - - @Override - public Integer getLinePattern() { - - Integer linePattern = super.getLinePattern(); - if (linePattern != null) - return linePattern; - - // get from master - if (_masterShape != null) { - return _masterShape.getLinePattern(); - } - - // get default - return _document.getDefaultLineStyle().getLinePattern(); - } - - @Override - public Double getLineWeight() { - - Double lineWeight = super.getLineWeight(); - if (lineWeight != null) - return lineWeight; - - // get from master - if (_masterShape != null) { - return _masterShape.getLineWeight(); - } - - // get default - return _document.getDefaultLineStyle().getLineWeight(); - } - - @Override - public Color getFontColor() { - - Color fontColor = super.getFontColor(); - if (fontColor != null) - return fontColor; - - // get from master - if (_masterShape != null) { - return _masterShape.getFontColor(); - } - - // get default - return _document.getDefaultTextStyle().getFontColor(); - } - - @Override - public Double getFontSize() { - - Double fontSize = super.getFontSize(); - if (fontSize != null) - return fontSize; - - // get from master - if (_masterShape != null) { - return _masterShape.getFontSize(); - } - - // get default - return _document.getDefaultTextStyle().getFontSize(); - } - - public Stroke getStroke() { - - float lineWeight = getLineWeight().floatValue(); - int cap; - int join = BasicStroke.JOIN_MITER; - float miterlimit = 10.0f; - - switch (getLineCap()) { - case 0: - cap = BasicStroke.CAP_ROUND; - break; - case 1: - cap = BasicStroke.CAP_SQUARE; - break; - case 2: - cap = BasicStroke.CAP_BUTT; // TODO: what does extended mean? - break; - default: - throw new POIXMLException("Invalid line cap specified"); - } - - float[] dash = null; - - // these line patterns are just approximations - switch (getLinePattern()) { - case 0: // transparent - break; - case 1: // solid - break; - case 2: - dash = new float[] { 5, 3 }; - break; - case 3: - dash = new float[] { 1, 4 }; - break; - case 4: - dash = new float[] { 6, 3, 1, 3 }; - break; - case 5: - dash = new float[] { 6, 3, 1, 3, 1, 3 }; - break; - case 6: - dash = new float[] { 1, 3, 6, 3, 6, 3 }; - break; - case 7: - dash = new float[] { 15, 3, 6, 3 }; - break; - case 8: - dash = new float[] { 6, 3, 6, 3 }; - break; - case 9: - dash = new float[] { 3, 2 }; - break; - case 10: - dash = new float[] { 1, 2 }; - break; - case 11: - dash = new float[] { 3, 2, 1, 2 }; - break; - case 12: - dash = new float[] { 3, 2, 1, 2, 1 }; - break; - case 13: - dash = new float[] { 1, 2, 3, 2, 3, 2 }; - break; - case 14: - dash = new float[] { 3, 2, 7, 2 }; - break; - case 15: - dash = new float[] { 7, 2, 3, 2, 3, 2 }; - break; - case 16: - dash = new float[] { 12, 6 }; - break; - case 17: - dash = new float[] { 1, 6 }; - break; - case 18: - dash = new float[] { 1, 6, 12, 6 }; - break; - case 19: - dash = new float[] { 1, 6, 1, 6, 12, 6 }; - break; - case 20: - dash = new float[] { 1, 6, 12, 6, 12, 6 }; - break; - case 21: - dash = new float[] { 30, 6, 12, 6 }; - break; - case 22: - dash = new float[] { 30, 6, 12, 6, 12, 6 }; - break; - case 23: - dash = new float[] { 1 }; - break; - case 254: - throw new POIXMLException("Unsupported line pattern value"); - default: - throw new POIXMLException("Invalid line pattern value"); - } - - // dashes are in units of line width - if (dash != null) { - for (int i = 0; i < dash.length; i++) { - dash[i] *= lineWeight; - } - } - - return new BasicStroke(lineWeight, cap, join, miterlimit, dash, 0); - } - - // - // Geometry - // - - public Iterable getGeometrySections() { - return new CombinedIterable(_geometry, - _masterShape != null ? _masterShape._geometry : null); - } - - /** - * @return rectangle in local coordinates - */ - public Rectangle2D.Double getBounds() { - return new Rectangle2D.Double(0, 0, getWidth(), getHeight()); - } - - /** - * @return returns bounds as a path in local coordinates, which is - * userful if you need to transform to global coordinates - * - * Warning: Don't use this for 1d objects, and will fail for - * infinite line objects - */ - public Path2D.Double getBoundsAsPath() { - - Double w = getWidth(); - Double h = getHeight(); - - Path2D.Double bounds = new Path2D.Double(); - bounds.moveTo(0, 0); - bounds.lineTo(w, 0); - bounds.lineTo(w, h); - bounds.lineTo(0, h); - bounds.lineTo(0, 0); - - return bounds; - } - - /** - * @return The outline of the shape in local coordinates - */ - public Path2D.Double getPath() { - for (GeometrySection geoSection : getGeometrySections()) { - if (geoSection.getNoShow() == true) - continue; - - return geoSection.getPath(this); - } - - return null; - } - - /* - * Returns true if the shape has a drawable geometry associated with it - */ - public boolean hasGeometry() { - for (GeometrySection geoSection : getGeometrySections()) { - if (geoSection.getNoShow() == false) - return true; - } - return false; - } - - /** - * Returns a transform that can translate shape-local coordinates to the - * coordinates of its parent shape - */ - protected AffineTransform getParentTransform() { - // TODO: There's probably a better way to do this - AffineTransform tr = new AffineTransform(); - - Double locX = getLocPinX(); - Double locY = getLocPinY(); - Boolean flipX = getFlipX(); - Boolean flipY = getFlipY(); - Double angle = getAngle(); - - tr.translate(-locX, -locY); - - tr.translate(getPinX(), getPinY()); - - // rotate about the origin - if (angle != null && Math.abs(angle) > 0.001) { - tr.rotate(angle, locX, locY); - } - - // flip if necessary - - if (flipX != null && flipX) { - tr.scale(-1, 1); - tr.translate(-getWidth(), 0); - } - - if (flipY != null && flipY) { - tr.scale(1, -1); - tr.translate(0, -getHeight()); - } - - return tr; - } - - /** - * The visitor will first visit this shape, then it's children - * - * This is useful because exceptions will be marked with the shapes as it - * propagates up the shape hierarchy. - */ - public void visitShapes(ShapeVisitor visitor, AffineTransform tr, int level) { - - tr = (AffineTransform) tr.clone(); - tr.concatenate(getParentTransform()); - - try { - if (visitor.accept(this)) - visitor.visit(this, tr, level); - - if (_shapes != null) { - for (XDGFShape shape : _shapes) { - shape.visitShapes(visitor, tr, level + 1); - } - } - } catch (StopVisitingThisBranch e) { - // intentionally empty - } catch (POIXMLException e) { - throw XDGFException.wrap(this.toString(), e); - } - } - - /** - * The visitor will first visit this shape, then it's children. No transform - * is calculated for this visit - * - * This is useful because exceptions will be marked with the shapes as it - * propagates up the shape hierarchy. - */ - public void visitShapes(ShapeVisitor visitor, int level) { - - try { - if (visitor.accept(this)) - visitor.visit(this, null, level); - - if (_shapes != null) { - for (XDGFShape shape : _shapes) { - shape.visitShapes(visitor, level + 1); - } - } - } catch (StopVisitingThisBranch e) { - // intentionally empty - } catch (POIXMLException e) { - throw XDGFException.wrap(this.toString(), e); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFSheet.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFSheet.java deleted file mode 100644 index 1cc807fdf..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFSheet.java +++ /dev/null @@ -1,208 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.awt.Color; -import java.util.HashMap; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.exceptions.XDGFException; -import org.apache.poi.xdgf.usermodel.section.CharacterSection; -import org.apache.poi.xdgf.usermodel.section.GeometrySection; -import org.apache.poi.xdgf.usermodel.section.XDGFSection; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.SectionType; -import com.microsoft.schemas.office.visio.x2012.main.SheetType; - -/** - * A sheet is a collection of properties that specify information for a shape, - * master, drawing page, style, or web drawing. - */ -public abstract class XDGFSheet { - - protected XDGFDocument _document; - protected SheetType _sheet; - - // cells - protected Map _cells = new HashMap(); - - // sections - protected Map _sections = new HashMap(); - - // special: geometry sections (key: index, value: section) - protected SortedMap _geometry = new TreeMap(); - - // special: character section - protected CharacterSection _character = null; - - public XDGFSheet(SheetType sheet, XDGFDocument document) { - try { - _sheet = sheet; - _document = document; - - for (CellType cell: sheet.getCellArray()) { - if (_cells.containsKey(cell.getN())) - throw new POIXMLException("Unexpected duplicate cell " + cell.getN()); // this shouldn't happen - - _cells.put(cell.getN(), new XDGFCell(cell)); - } - - // only geometry sections can have duplicate names - // sections can be found in the master too, if there are no attributes here! - - // no idea if I have a master in this space. go figure. - - for (SectionType section: sheet.getSectionArray()) { - String name = section.getN(); - if (name.equals("Geometry")) { - _geometry.put(section.getIX(), new GeometrySection(section, this)); - } else if (name.equals("Character")) { - _character = new CharacterSection(section, this); - } else { - _sections.put(name, XDGFSection.load(section, this)); - } - } - } catch (POIXMLException e) { - throw XDGFException.wrap(this.toString(), e); - } - } - - abstract SheetType getXmlObject(); - - public XDGFDocument getDocument() { - return _document; - } - - /** - * A cell is really just a setting - * - * @param cellName The particular setting you want - */ - public XDGFCell getCell(String cellName) { - return _cells.get(cellName); - } - - public XDGFSection getSection(String sectionName) { - return _sections.get(sectionName); - } - - public XDGFStyleSheet getLineStyle() { - if (!_sheet.isSetLineStyle()) - return null; - - return _document.getStyleById(_sheet.getLineStyle()); - } - - public XDGFStyleSheet getFillStyle() { - if (!_sheet.isSetFillStyle()) - return null; - - return _document.getStyleById(_sheet.getFillStyle()); - } - - public XDGFStyleSheet getTextStyle() { - if (!_sheet.isSetTextStyle()) - return null; - - return _document.getStyleById(_sheet.getTextStyle()); - } - - public Color getFontColor() { - Color fontColor = null; - - if (_character != null) { - fontColor = _character.getFontColor(); - if (fontColor != null) - return fontColor; - } - - XDGFStyleSheet style = getTextStyle(); - if (style != null) - return style.getFontColor(); - - return null; - } - - public Double getFontSize() { - Double fontSize = null; - - if (_character != null) { - fontSize = _character.getFontSize(); - if (fontSize != null) - return fontSize; - } - - XDGFStyleSheet style = getTextStyle(); - if (style != null) - return style.getFontSize(); - - return null; - } - - public Integer getLineCap() { - Integer lineCap = XDGFCell.maybeGetInteger(_cells, "LineCap"); - if (lineCap != null) - return lineCap; - - XDGFStyleSheet style = getLineStyle(); - if (style != null) - return style.getLineCap(); - - return null; - } - - public Color getLineColor() { - String lineColor = XDGFCell.maybeGetString(_cells, "LineColor"); - if (lineColor != null) - return Color.decode(lineColor); - - XDGFStyleSheet style = getLineStyle(); - if (style != null) - return style.getLineColor(); - - return null; - } - - public Integer getLinePattern() { - Integer linePattern = XDGFCell.maybeGetInteger(_cells, "LinePattern"); - if (linePattern != null) - return linePattern; - - XDGFStyleSheet style = getLineStyle(); - if (style != null) - return style.getLinePattern(); - - return null; - } - - public Double getLineWeight() { - Double lineWeight = XDGFCell.maybeGetDouble(_cells, "LineWeight"); - if (lineWeight != null) - return lineWeight; - - XDGFStyleSheet style = getLineStyle(); - if (style != null) - return style.getLineWeight(); - - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFStyleSheet.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFStyleSheet.java deleted file mode 100644 index 50f61842b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFStyleSheet.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import org.apache.poi.util.Internal; - -import com.microsoft.schemas.office.visio.x2012.main.StyleSheetType; - -public class XDGFStyleSheet extends XDGFSheet { - - public XDGFStyleSheet(StyleSheetType styleSheet, XDGFDocument document) { - super(styleSheet, document); - } - - @Override - @Internal - public StyleSheetType getXmlObject() { - return (StyleSheetType) _sheet; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFText.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFText.java deleted file mode 100644 index f3b24f905..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFText.java +++ /dev/null @@ -1,166 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.font.FontRenderContext; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.util.Internal; - -import com.microsoft.schemas.office.visio.x2012.main.TextType; -import com.microsoft.schemas.office.visio.x2012.main.impl.TextTypeImpl; - -public class XDGFText { - - TextType _text; - XDGFShape _parent; - - public XDGFText(TextType text, XDGFShape parent) { - _text = text; - _parent = parent; - } - - @Internal - TextType getXmlObject() { - return _text; - } - - public String getTextContent() { - // casting here is wrong, but there's no other way of getting the value, - // as it doesn't seem to be exposed by complex types (even though this - // is a mixed type) - return ((TextTypeImpl) _text).getStringValue(); - } - - /** - * These are in the shape coordinate system - * - * @see Text Block Coordinate System docs - */ - public Rectangle2D.Double getTextBounds() { - - double txtPinX = _parent.getTxtPinX(); - double txtPinY = _parent.getTxtPinY(); - - double txtLocPinX = _parent.getTxtLocPinX(); - double txtLocPinY = _parent.getTxtLocPinY(); - - double txtWidth = _parent.getTxtWidth(); - double txtHeight = _parent.getTxtHeight(); - - double x = txtPinX - txtLocPinX; - double y = txtPinY - txtLocPinY; - - return new Rectangle2D.Double(x, y, txtWidth, txtHeight); - } - - /** - * @return Text bounds as a path in local coordinates, which is useful - * if you need to transform to global coordinates - */ - public Path2D.Double getBoundsAsPath() { - - Rectangle2D.Double rect = getTextBounds(); - Double w = rect.getWidth(); - Double h = rect.getHeight(); - - Path2D.Double bounds = new Path2D.Double(); - bounds.moveTo(0, 0); - bounds.lineTo(w, 0); - bounds.lineTo(w, h); - bounds.lineTo(0, h); - bounds.lineTo(0, 0); - - return bounds; - } - - /** - * @return Center of text in local coordinates - */ - public Point2D.Double getTextCenter() { - return new Point2D.Double(_parent.getTxtLocPinX(), - _parent.getTxtLocPinY()); - } - - /** - * When calling this to draw text, it assumes graphics is set properly - * to draw in the right style. - */ - public void draw(Graphics2D graphics) { - - String textContent = getTextContent(); - if (textContent.length() == 0) - return; - - Rectangle2D.Double bounds = getTextBounds(); - - String[] lines = textContent.trim().split("\n"); - FontRenderContext frc = graphics.getFontRenderContext(); - Font font = graphics.getFont(); - - AffineTransform oldTr = graphics.getTransform(); - - // visio is in flipped coordinates, so translate the text to be in the - // right place - Boolean flipX = _parent.getFlipX(); - Boolean flipY = _parent.getFlipY(); - - if (flipY == null || !_parent.getFlipY()) { - graphics.translate(bounds.x, bounds.y); - graphics.scale(1, -1); - graphics.translate(0, -bounds.height - + graphics.getFontMetrics().getMaxCharBounds(graphics) - .getHeight()); - } - - if (flipX != null && _parent.getFlipX()) { - graphics.scale(-1, 1); - graphics.translate(-bounds.width, 0); - } - - Double txtAngle = _parent.getTxtAngle(); - if (txtAngle != null && Math.abs(txtAngle) > 0.01) - graphics.rotate(txtAngle); - - float nextY = 0; - for (String line : lines) { - - if (line.length() == 0) - continue; - - TextLayout layout = new TextLayout(line, font, frc); - - if (layout.isLeftToRight()) - layout.draw(graphics, 0, nextY); - else - layout.draw(graphics, - (float) (bounds.width - layout.getAdvance()), nextY); - - nextY += layout.getAscent() + layout.getDescent() - + layout.getLeading(); - } - - graphics.setTransform(oldTr); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XmlVisioDocument.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XmlVisioDocument.java deleted file mode 100644 index 879487404..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XmlVisioDocument.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.util.PackageHelper; -import org.apache.xmlbeans.XmlException; - -import com.microsoft.schemas.office.visio.x2012.main.VisioDocumentDocument1; -import com.microsoft.schemas.office.visio.x2012.main.VisioDocumentType; - -/** - * This is your high-level starting point for working with Visio XML - * documents (.vsdx). - * - * Currently, only read support has been implemented, and the API is - * not mature and is subject to change. - * - * For more information about the visio XML format (with an XSD 1.0 - * schema), you can find documentation at - * https://msdn.microsoft.com/en-us/library/hh645006(v=office.12).aspx - * - * That document lacks in some areas, but you can find additional - * documentation and an updated XSD 1.1 schema at - * https://msdn.microsoft.com/en-us/library/office/jj684209(v=office.15).aspx - * - * Each provides different details, but the SharePoint reference - * has better documentation and is more useful. - */ -public class XmlVisioDocument extends POIXMLDocument { - - protected XDGFPages _pages; - protected XDGFMasters _masters; - protected XDGFDocument _document; - - public XmlVisioDocument(OPCPackage pkg) throws IOException { - super(pkg, PackageRelationshipTypes.VISIO_CORE_DOCUMENT); - - VisioDocumentType document; - - try { - document = VisioDocumentDocument1.Factory.parse(getPackagePart().getInputStream()).getVisioDocument(); - } catch (XmlException e) { - throw new POIXMLException(e); - } catch (IOException e) { - throw new POIXMLException(e); - } - - _document = new XDGFDocument(document); - - //build a tree of POIXMLDocumentParts, this document being the root - load(new XDGFFactory(_document)); - } - - public XmlVisioDocument(InputStream is) throws IOException { - this(PackageHelper.open(is)); - } - - @Override - protected void onDocumentRead() throws IOException { - - // by the time this gets called, all other document parts should - // have been loaded, so it's safe to build the document structure - - // note that in other onDocumentRead(), relations/etc may not have - // loaded yet, so it's not quite safe - - for (POIXMLDocumentPart part : getRelations()) { - - // organize the document pieces - if (part instanceof XDGFPages) - _pages = (XDGFPages) part; - - else if (part instanceof XDGFMasters) - _masters = (XDGFMasters) part; - } - - if (_masters != null) - _masters.onDocumentRead(); - - _pages.onDocumentRead(); - } - - /** - * Not currently implemented - */ - @Override - public List getAllEmbedds() throws OpenXML4JException { - return new ArrayList(); - } - - // - // Useful public API goes here - // - - /** - * @return pages ordered by page number - */ - public Collection getPages() { - return _pages.getPageList(); - } - - public XDGFStyleSheet getStyleById(long id) { - return _document.getStyleById(id); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CharacterSection.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CharacterSection.java deleted file mode 100644 index 7c1aa3f0c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CharacterSection.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section; - -import java.awt.Color; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFSheet; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; -import com.microsoft.schemas.office.visio.x2012.main.SectionType; - -public class CharacterSection extends XDGFSection { - - Double _fontSize = null; - Color _fontColor = null; - - Map _characterCells = new HashMap(); - - public CharacterSection(SectionType section, XDGFSheet containingSheet) { - super(section, containingSheet); - - // there aren't cells for this, just a single row - RowType row = section.getRowArray(0); - - for (CellType cell: row.getCellArray()) { - _characterCells.put(cell.getN(), new XDGFCell(cell)); - } - - _fontSize = XDGFCell.maybeGetDouble(_characterCells, "Size"); - - String tmpColor = XDGFCell.maybeGetString(_characterCells, "Color"); - if (tmpColor != null) - _fontColor = Color.decode(tmpColor); - } - - public Double getFontSize() { - return _fontSize; - } - - public Color getFontColor() { - return _fontColor; - } - - @Override - public void setupMaster(XDGFSection section) { - - } - -} - diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CombinedIterable.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CombinedIterable.java deleted file mode 100644 index bca48bc09..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CombinedIterable.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section; - -import java.util.Collections; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.SortedMap; - -/** - * An iterator used to iterate over the base and master items - * - * @param - */ -public class CombinedIterable implements Iterable { - - final SortedMap _baseItems; - final SortedMap _masterItems; - - public CombinedIterable(SortedMap baseItems, - SortedMap masterItems) { - _baseItems = baseItems; - _masterItems = masterItems; - } - - @Override - public Iterator iterator() { - - final Iterator> vmasterI; - - if (_masterItems != null) { - vmasterI = _masterItems.entrySet().iterator(); - } else { - final Set> empty = Collections.emptySet(); - vmasterI = empty.iterator(); - } - - return new Iterator() { - - Long lastI = Long.MIN_VALUE; - - Entry currentBase = null; - Entry currentMaster = null; - - // grab the iterator for both - Iterator> baseI = _baseItems.entrySet().iterator(); - Iterator> masterI = vmasterI; - - @Override - public boolean hasNext() { - return currentBase != null || currentMaster != null - || baseI.hasNext() || masterI.hasNext(); - } - - @Override - public T next() { - - // TODO: This seems far more complex than it needs to be - - long baseIdx = Long.MAX_VALUE; - long masterIdx = Long.MAX_VALUE; - - if (currentBase == null) { - while (baseI.hasNext()) { - currentBase = baseI.next(); - if (currentBase.getKey() > lastI) { - baseIdx = currentBase.getKey(); - break; - } - } - } else { - baseIdx = currentBase.getKey(); - } - - if (currentMaster == null) { - while (masterI.hasNext()) { - currentMaster = masterI.next(); - if (currentMaster.getKey() > lastI) { - masterIdx = currentMaster.getKey(); - break; - } - } - } else { - masterIdx = currentMaster.getKey(); - } - - T val; - - if (currentBase != null) { - - if (baseIdx <= masterIdx) { - lastI = baseIdx; - val = currentBase.getValue(); - - // discard master if same as base - if (masterIdx == baseIdx) { - currentMaster = null; - } - - currentBase = null; - - } else { - lastI = masterIdx; - val = currentMaster.getValue(); - currentMaster = null; - } - - } else if (currentMaster != null) { - lastI = currentMaster.getKey(); - val = currentMaster.getValue(); - - currentMaster = null; - } else { - throw new NoSuchElementException(); - } - - return val; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/GenericSection.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/GenericSection.java deleted file mode 100644 index b0ecf2051..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/GenericSection.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section; - -import org.apache.poi.xdgf.usermodel.XDGFSheet; - -import com.microsoft.schemas.office.visio.x2012.main.SectionType; - -public class GenericSection extends XDGFSection { - - public GenericSection(SectionType section, XDGFSheet containingSheet) { - super(section, containingSheet); - } - - @Override - public void setupMaster(XDGFSection section) { - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/GeometrySection.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/GeometrySection.java deleted file mode 100644 index bc7cdf60b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/GeometrySection.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section; - -import java.awt.geom.Path2D; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.geom.SplineCollector; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; -import org.apache.poi.xdgf.usermodel.XDGFSheet; -import org.apache.poi.xdgf.usermodel.section.geometry.Ellipse; -import org.apache.poi.xdgf.usermodel.section.geometry.GeometryRow; -import org.apache.poi.xdgf.usermodel.section.geometry.GeometryRowFactory; -import org.apache.poi.xdgf.usermodel.section.geometry.InfiniteLine; -import org.apache.poi.xdgf.usermodel.section.geometry.SplineKnot; -import org.apache.poi.xdgf.usermodel.section.geometry.SplineStart; - -import com.microsoft.schemas.office.visio.x2012.main.RowType; -import com.microsoft.schemas.office.visio.x2012.main.SectionType; - -public class GeometrySection extends XDGFSection { - - GeometrySection _master = null; - - // rows - SortedMap _rows = new TreeMap(); - - public GeometrySection(SectionType section, XDGFSheet containingSheet) { - super(section, containingSheet); - - for (RowType row: section.getRowArray()) { - if (_rows.containsKey(row.getIX())) - throw new POIXMLException("Index element '" + row.getIX() + "' already exists"); - - _rows.put(row.getIX(), GeometryRowFactory.load(row)); - } - } - - @Override - public void setupMaster(XDGFSection master) { - - _master = (GeometrySection)master; - - for (Entry entry : _rows.entrySet()) { - GeometryRow masterRow = _master._rows.get(entry.getKey()); - if (masterRow != null) { - try { - entry.getValue().setupMaster(masterRow); - } catch (ClassCastException e) { - // this can happen when a dynamic connector overrides its master's geometry - // .. probably can happen elsewhere too, I imagine. - //throw XDGFException.error("Mismatched geometry section '" + entry.getKey() + "' in master", this, e); - } - } - } - } - - // returns True if this row shouldn't be displayed - public Boolean getNoShow() { - Boolean noShow = XDGFCell.maybeGetBoolean(_cells, "NoShow"); - if (noShow == null) { - if (_master != null) - return _master.getNoShow(); - - return false; - } - - return noShow; - } - - public Iterable getCombinedRows() { - return new CombinedIterable(_rows, - _master == null ? null : _master._rows); - } - - public Path2D.Double getPath(XDGFShape parent) { - - Iterator rows = getCombinedRows().iterator(); - - // special cases - GeometryRow first = rows.next(); - - if (first instanceof Ellipse) { - return ((Ellipse)first).getPath(); - } else if (first instanceof InfiniteLine) { - return ((InfiniteLine)first).getPath(); - } else if (first instanceof SplineStart) { - throw new POIXMLException("SplineStart must be preceded by another type"); - } else { - - // everything else is a path - Path2D.Double path = new Path2D.Double(); - - // dealing with splines makes this more complex - SplineCollector renderer = null; - GeometryRow row; - - while (true) { - - if (first != null) { - row = first; - first = null; - } else { - if (!rows.hasNext()) - break; - row = rows.next(); - } - - if (row instanceof SplineStart) { - if (renderer != null) - throw new POIXMLException("SplineStart found multiple times!"); - renderer = new SplineCollector((SplineStart) row); - } else if (row instanceof SplineKnot) { - if (renderer == null) - throw new POIXMLException("SplineKnot found without SplineStart!"); - renderer.addKnot((SplineKnot) row); - } else { - if (renderer != null) { - renderer.addToPath(path, parent); - renderer = null; - } - - row.addToPath(path, parent); - } - } - - // just in case we end iteration - if (renderer != null) - renderer.addToPath(path, parent); - - return path; - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/XDGFSection.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/XDGFSection.java deleted file mode 100644 index 1448a60ba..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/XDGFSection.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.Internal; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFSheet; -import org.apache.poi.xdgf.util.ObjectFactory; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.SectionType; - -public abstract class XDGFSection { - - static final ObjectFactory _sectionTypes; - - static { - _sectionTypes = new ObjectFactory(); - try { - _sectionTypes.put("LineGradient", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("FillGradient", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Character", CharacterSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Paragraph", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Tabs", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Scratch", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Connection", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("ConnectionABCD", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Field", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Control", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Geometry", GeometrySection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Actions", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Layer", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("User", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Property", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Hyperlink", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Reviewer", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("Annotation", GenericSection.class, SectionType.class, XDGFSheet.class); - _sectionTypes.put("ActionTag", GenericSection.class, SectionType.class, XDGFSheet.class); - } catch (NoSuchMethodException e) { - throw new POIXMLException("Internal error"); - } catch (SecurityException e) { - throw new POIXMLException("Internal error"); - } - - } - - public static XDGFSection load(SectionType section, XDGFSheet containingSheet) { - return _sectionTypes.load(section.getN(), section, containingSheet); - } - - - protected SectionType _section; - protected XDGFSheet _containingSheet; - - protected Map _cells = new HashMap(); - - - public XDGFSection(SectionType section, XDGFSheet containingSheet) { - _section = section; - _containingSheet = containingSheet; - - // only store cells in the base, not rows -- because rows are handled - // specially for geometry sections - for (CellType cell: section.getCellArray()) { - _cells.put(cell.getN(), new XDGFCell(cell)); - } - } - - @Internal - public SectionType getXmlObject() { - return _section; - } - - @Override - public String toString() { - return "
        "; - } - - public abstract void setupMaster(XDGFSection section); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/ArcTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/ArcTo.java deleted file mode 100644 index fdcce8056..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/ArcTo.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Path2D; -import java.awt.geom.Point2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class ArcTo implements GeometryRow { - - ArcTo _master = null; - - // The x-coordinate of the ending vertex of an arc. - Double x = null; - - // The y-coordinate of the ending vertex of an arc. - Double y = null; - - // The distance from the arc's midpoint to the midpoint of its chord. - Double a = null; - - Boolean deleted = null; - - // TODO: support formulas - - public ArcTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in ArcTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (ArcTo) row; - } - - @Override - public void addToPath(Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - Point2D last = path.getCurrentPoint(); - - // intentionally shadowing variables here - double x = getX(); - double y = getY(); - double a = getA(); - - if (a == 0) { - path.lineTo(x, y); - return; - } - - double x0 = last.getX(); - double y0 = last.getY(); - - double chordLength = Math.hypot(y - y0, x - x0); - double radius = (4 * a * a + chordLength * chordLength) - / (8 * Math.abs(a)); - - // center point - double cx = x0 + (x - x0) / 2.0; - double cy = y0 + (y - y0) / 2.0; - - double rotate = Math.atan2(y - cy, x - cx); - - Arc2D arc = new Arc2D.Double(x0, y0 - radius, chordLength, 2 * radius, - 180, x0 < x ? 180 : -180, Arc2D.OPEN); - - path.append(AffineTransform.getRotateInstance(rotate, x0, y0) - .createTransformedShape(arc), true); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/Ellipse.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/Ellipse.java deleted file mode 100644 index 01eecdd00..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/Ellipse.java +++ /dev/null @@ -1,160 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Path2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class Ellipse implements GeometryRow { - - Ellipse _master = null; - - // x coordinate of center point - Double x = null; - // y coordinate of center point - Double y = null; - - // x coordinate of first point on ellipse - Double a = null; - // y coordinate of first point on ellipse - Double b = null; - - // x coordinate of second point on ellipse - Double c = null; - // y coordinate of second point on ellipse - Double d = null; - - Boolean deleted = null; - - // TODO: support formulas - - public Ellipse(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("C")) { - c = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("D")) { - d = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in Ellipse row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - public Double getC() { - return c == null ? _master.c : c; - } - - public Double getD() { - return d == null ? _master.d : d; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (Ellipse) row; - } - - public Path2D.Double getPath() { - - if (getDel()) - return null; - - // intentionally shadowing variables here - double cx = getX(); // center - double cy = getY(); - double a = getA(); // left - double b = getB(); - double c = getC(); // top - double d = getD(); - - // compute radius - double rx = Math.hypot(a - cx, b - cy); - double ry = Math.hypot(c - cx, d - cy); - - // compute angle of ellipse - double angle = (2.0 * Math.PI + (cy > b ? 1.0 : -1.0) - * Math.acos((cx - a) / rx)) - % (2.0 * Math.PI); - - // create ellipse - Ellipse2D.Double ellipse = new Ellipse2D.Double(cx - rx, cy - ry, - rx * 2, ry * 2); - - // create a path, rotate it about its center - Path2D.Double path = new Path2D.Double(ellipse); - - AffineTransform tr = new AffineTransform(); - tr.rotate(angle, cx, cy); - path.transform(tr); - - return path; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - throw new POIXMLException("Ellipse elements cannot be part of a path"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/EllipticalArcTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/EllipticalArcTo.java deleted file mode 100644 index 02fc5aef4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/EllipticalArcTo.java +++ /dev/null @@ -1,246 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Point2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class EllipticalArcTo implements GeometryRow { - - EllipticalArcTo _master = null; - - // The x-coordinate of the ending vertex on an arc. - Double x = null; - - // The y-coordinate of the ending vertex on an arc. - Double y = null; - - // The x-coordinate of the arc's control point; a point on the arc. The - // control point is best located about halfway between the beginning and - // ending vertices of the arc. Otherwise, the arc may grow to an extreme - // size in order to pass through the control point, with unpredictable - // results. - Double a = null; - - // The y-coordinate of an arc's control point. - Double b = null; - - // The angle of an arc's major axis relative to the x-axis of its parent - // shape. - Double c = null; - - // The ratio of an arc's major axis to its minor axis. Despite the usual - // meaning of these words, the "major" axis does not have to be greater than - // the "minor" axis, so this ratio does not have to be greater than 1. - // Setting this cell to a value less than or equal to 0 or greater than 1000 - // can lead to unpredictable results. - Double d = null; - - Boolean deleted = null; - - // TODO: support formulas - - public EllipticalArcTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("C")) { - c = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("D")) { - d = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in EllipticalArcTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - public Double getC() { - return c == null ? _master.c : c; - } - - public Double getD() { - return d == null ? _master.d : d; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (EllipticalArcTo) row; - } - - public static int draw = 0; - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - // intentionally shadowing variables here - double x = getX(); - double y = getY(); - double a = getA(); - double b = getB(); - double c = getC(); - double d = getD(); - - createEllipticalArc(x, y, a, b, c, d, path); - } - - public static void createEllipticalArc(double x, double y, double a, - double b, double c, double d, java.awt.geom.Path2D.Double path) { - - // Formula for center of ellipse by Junichi Yoda & nashwaan: - // -> From http://visguy.com/vgforum/index.php?topic=2464.0 - // - // x1,y1 = start; x2,y2 = end; x3,y3 = control point - // - // x0 = - // ((x1-x2)*(x1+x2)*(y2-y3)-(x2-x3)*(x2+x3)*(y1-y2)+D^2*(y1-y2)*(y2-y3)*(y1-y3))/(2*((x1-x2)*(y2-y3)-(x2-x3)*(y1-y2))) - // y0 = - // ((x1-x2)*(x2-x3)*(x1-x3)/D^2+(x2-x3)*(y1-y2)*(y1+y2)-(x1-x2)*(y2-y3)*(y2+y3))/(2*((x2-x3)*(y1-y2)-(x1-x2)*(y2-y3))) - // radii along axis: a = sqrt{ (x1-x0)^2 + (y1-y0)^2 * D^2 } - // - - Point2D last = path.getCurrentPoint(); - double x0 = last.getX(); - double y0 = last.getY(); - - // translate all of the points to the same angle as the ellipse - AffineTransform at = AffineTransform.getRotateInstance(-c); - double[] pts = new double[] { x0, y0, x, y, a, b }; - at.transform(pts, 0, pts, 0, 3); - - x0 = pts[0]; - y0 = pts[1]; - x = pts[2]; - y = pts[3]; - a = pts[4]; - b = pts[5]; - - // nasty math time - - double d2 = d * d; - double cx = ((x0 - x) * (x0 + x) * (y - b) - (x - a) * (x + a) - * (y0 - y) + d2 * (y0 - y) * (y - b) * (y0 - b)) - / (2.0 * ((x0 - x) * (y - b) - (x - a) * (y0 - y))); - double cy = ((x0 - x) * (x - a) * (x0 - a) / d2 + (x - a) * (y0 - y) - * (y0 + y) - (x0 - x) * (y - b) * (y + b)) - / (2.0 * ((x - a) * (y0 - y) - (x0 - x) * (y - b))); - - // calculate radii of ellipse - double rx = Math.sqrt(Math.pow(x0 - cx, 2) + Math.pow(y0 - cy, 2) * d2); - double ry = rx / d; - - // Arc2D requires us to draw an arc from one point to another, so we - // need to calculate the angle of the start point and end point along - // the ellipse - // - Derived from parametric form of ellipse: x = h + a*cos(t); y = k + - // b*sin(t) - - double ctrlAngle = Math.toDegrees(Math.atan2((b - cy) / ry, (a - cx) - / rx)); - double startAngle = Math.toDegrees(Math.atan2((y0 - cy) / ry, (x0 - cx) - / rx)); - double endAngle = Math.toDegrees(Math.atan2((y - cy) / ry, (x - cx) - / rx)); - - double sweep = computeSweep(startAngle, endAngle, ctrlAngle); - - // Now we have enough information to go on. Create the arc. - Arc2D arc = new Arc2D.Double(cx - rx, cy - ry, rx * 2, ry * 2, - -startAngle, sweep, Arc2D.OPEN); - - // rotate the arc back to the original coordinate system - at.setToRotation(c); - path.append(at.createTransformedShape(arc), false); - } - - protected static double computeSweep(double startAngle, double endAngle, - double ctrlAngle) { - double sweep; - - startAngle = (360.0 + startAngle) % 360.0; - endAngle = (360.0 + endAngle) % 360.0; - ctrlAngle = (360.0 + ctrlAngle) % 360.0; - - // different sweeps depending on where the control point is - - if (startAngle < endAngle) { - if (startAngle < ctrlAngle && ctrlAngle < endAngle) { - sweep = startAngle - endAngle; - } else { - sweep = 360 + (startAngle - endAngle); - } - } else { - if (endAngle < ctrlAngle && ctrlAngle < startAngle) { - sweep = startAngle - endAngle; - } else { - sweep = -(360 - (startAngle - endAngle)); - } - } - - return sweep; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryRow.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryRow.java deleted file mode 100644 index 8ffaef26f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryRow.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import java.awt.geom.Path2D; - -import org.apache.poi.xdgf.usermodel.XDGFShape; - -public interface GeometryRow { - - public void setupMaster(GeometryRow row); - - public void addToPath(Path2D.Double path, XDGFShape parent); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryRowFactory.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryRowFactory.java deleted file mode 100644 index 50e85e878..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/GeometryRowFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.util.ObjectFactory; - -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class GeometryRowFactory { - - static final ObjectFactory _rowTypes; - - static { - _rowTypes = new ObjectFactory(); - try { - _rowTypes.put("ArcTo", ArcTo.class, RowType.class); - _rowTypes.put("Ellipse", Ellipse.class, RowType.class); - _rowTypes.put("EllipticalArcTo", EllipticalArcTo.class, - RowType.class); - _rowTypes.put("InfiniteLine", InfiniteLine.class, RowType.class); - _rowTypes.put("LineTo", LineTo.class, RowType.class); - _rowTypes.put("MoveTo", MoveTo.class, RowType.class); - _rowTypes.put("NURBSTo", NURBSTo.class, RowType.class); - _rowTypes.put("PolyLineTo", PolyLineTo.class, RowType.class); - _rowTypes.put("RelCubBezTo", RelCubBezTo.class, RowType.class); - _rowTypes.put("RelEllipticalArcTo", RelEllipticalArcTo.class, - RowType.class); - _rowTypes.put("RelLineTo", RelLineTo.class, RowType.class); - _rowTypes.put("RelMoveTo", RelMoveTo.class, RowType.class); - _rowTypes.put("RelQuadBezTo", RelQuadBezTo.class, RowType.class); - _rowTypes.put("SplineKnot", SplineKnot.class, RowType.class); - _rowTypes.put("SplineStart", SplineStart.class, RowType.class); - } catch (NoSuchMethodException e) { - throw new POIXMLException("Internal error", e); - } catch (SecurityException e) { - throw new POIXMLException("Internal error", e); - } - - } - - public static GeometryRow load(RowType row) { - return _rowTypes.load(row.getT(), row); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/InfiniteLine.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/InfiniteLine.java deleted file mode 100644 index 6965c1b89..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/InfiniteLine.java +++ /dev/null @@ -1,154 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import java.awt.geom.Path2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -/** - * Contains the x- and y-coordinates of two points on an infinite line. - */ -public class InfiniteLine implements GeometryRow { - - InfiniteLine _master = null; - - // An x-coordinate of a point on the infinite line; paired with y-coordinate - // represented by the Y cell. - Double x = null; - - // A y-coordinate of a point on the infinite line; paired with x-coordinate - // represented by the X cell. - Double y = null; - - // An x-coordinate of a point on the infinite line; paired with y-coordinate - // represented by the B cell. - Double a = null; - - // A y-coordinate of a point on an infinite line; paired with x-coordinate - // represented by the A cell. - Double b = null; - - Boolean deleted = null; - - // TODO: support formulas - - public InfiniteLine(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in InfiniteLine row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (InfiniteLine) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - throw new POIXMLException( - "InfiniteLine elements cannot be part of a path"); - } - - // returns this object as a line that extends between the boundaries of - // the document - public Path2D.Double getPath() { - Path2D.Double path = new Path2D.Double(); - - // this is a bit of a hack, but it works - double max_val = 100000; - - // compute slope.. - double x0 = getX(); - double y0 = getY(); - double x1 = getA(); // second x - double y1 = getB(); // second y - - if (x0 == x1) { - path.moveTo(x0, -max_val); - path.lineTo(x0, max_val); - } else if (y0 == y1) { - path.moveTo(-max_val, y0); - path.lineTo(max_val, y0); - } else { - - // normal case: compute slope/intercept - double m = (y1 - y0) / (x1 - x0); - double c = y0 - m * x0; - - // y = mx + c - - path.moveTo(max_val, m * max_val + c); - path.lineTo(max_val, (max_val - c) / m); - } - - return path; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/LineTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/LineTo.java deleted file mode 100644 index 93857f09b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/LineTo.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class LineTo implements GeometryRow { - - LineTo _master = null; - - Double x = null; - Double y = null; - - Boolean deleted = null; - - // TODO: support formulas - - public LineTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in LineTo row"); - } - } - } - - @Override - public String toString() { - return "LineTo: x=" + getX() + "; y=" + getY(); - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (LineTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - if (getDel()) - return; - path.lineTo(getX(), getY()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/MoveTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/MoveTo.java deleted file mode 100644 index 6dca12b2b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/MoveTo.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -/** - * Contains the x- and y-coordinates of the first vertex of a shape or the x- - * and y-coordinates of the first vertex after a break in a path, relative to - * the height and width of the shape. - */ -public class MoveTo implements GeometryRow { - - MoveTo _master = null; - - Double x = null; - Double y = null; - - Boolean deleted = null; - - // TODO: support formulas - - public MoveTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in MoveTo row"); - } - } - } - - @Override - public String toString() { - return "MoveTo: x=" + getX() + "; y=" + getY(); - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (MoveTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - if (getDel()) - return; - path.moveTo(getX(), getY()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/NURBSTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/NURBSTo.java deleted file mode 100644 index 353d694f9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/NURBSTo.java +++ /dev/null @@ -1,214 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import java.awt.geom.Point2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.geom.SplineRenderer; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.graphbuilder.curve.ControlPath; -import com.graphbuilder.curve.ShapeMultiPath; -import com.graphbuilder.curve.ValueVector; -import com.graphbuilder.geom.PointFactory; -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class NURBSTo implements GeometryRow { - - NURBSTo _master = null; - - // The x-coordinate of the last control point of a NURBS. - Double x = null; - - // The y-coordinate of the last control point of a NURBS. - Double y = null; - - // The second to the last knot of the NURBS. - Double a = null; - - // The last weight of the NURBS. - Double b = null; - - // The first knot of the NURBS. - Double c = null; - - // The first weight of the NURBS. - Double d = null; - - // A NURBS formula. - String e = null; - - Boolean deleted = null; - - // TODO: support formulas - - public NURBSTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("C")) { - c = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("D")) { - d = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("E")) { - e = cell.getV(); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in NURBS row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - public Double getC() { - return c == null ? _master.c : c; - } - - public Double getD() { - return d == null ? _master.d : d; - } - - public String getE() { - return e == null ? _master.e : e; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (NURBSTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - if (getDel()) - return; - - Point2D last = path.getCurrentPoint(); - - // A NURBS formula: knotLast, degree, xType, yType, x1, y1, knot1, - // weight1, .. - String formula = getE().trim(); - if (!formula.startsWith("NURBS(") || !formula.endsWith(")")) - throw new POIXMLException("Invalid NURBS formula: " + formula); - - String[] components = formula.substring(6, formula.length() - 1).split( - ","); - - if (components.length < 8) - throw new POIXMLException( - "Invalid NURBS formula (not enough arguments)"); - - if ((components.length - 4) % 4 != 0) - throw new POIXMLException( - "Invalid NURBS formula -- need 4 + n*4 arguments, got " - + components.length); - - double lastControlX = getX(); - double lastControlY = getY(); - double secondToLastKnot = getA(); - double lastWeight = getB(); - double firstKnot = getC(); - double firstWeight = getD(); - - double lastKnot = Double.parseDouble(components[0].trim()); - int degree = Integer.parseInt(components[1].trim()); - int xType = Integer.parseInt(components[2].trim()); - int yType = Integer.parseInt(components[3].trim()); - - double xScale = 1; - double yScale = 1; - - if (xType == 0) - xScale = parent.getWidth(); - if (yType == 0) - yScale = parent.getHeight(); - - // setup first knots/weights/control point - ControlPath controlPath = new ControlPath(); - ValueVector knots = new ValueVector(); - ValueVector weights = new ValueVector(); - - knots.add(firstKnot); - weights.add(firstWeight); - controlPath.addPoint(PointFactory.create(last.getX(), last.getY())); - - // iterate get knots/weights - int sets = (components.length - 4) / 4; - for (int i = 0; i < sets; i++) { - double x1 = Double.parseDouble(components[4 + i * 4 + 0].trim()); - double y1 = Double.parseDouble(components[4 + i * 4 + 1].trim()); - double k = Double.parseDouble(components[4 + i * 4 + 2].trim()); - double w = Double.parseDouble(components[4 + i * 4 + 3].trim()); - - controlPath.addPoint(PointFactory.create(x1 * xScale, y1 * yScale)); - knots.add(k); - weights.add(w); - } - - // last knots/weights/control point - knots.add(secondToLastKnot); - knots.add(lastKnot); - - weights.add(lastWeight); - - controlPath.addPoint(PointFactory.create(lastControlX, lastControlY)); - - ShapeMultiPath shape = SplineRenderer.createNurbsSpline(controlPath, - knots, weights, degree); - path.append(shape, true); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java deleted file mode 100644 index c5f1ba011..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/PolyLineTo.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class PolyLineTo implements GeometryRow { - - PolyLineTo _master = null; - - // The x-coordinate of the ending vertex of a polyline. - Double x = null; - - // The y-coordinate of the ending vertex of a polyline. - Double y = null; - - // The polyline formula - String a = null; - - Boolean deleted = null; - - // TODO: support formulas - - public PolyLineTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = cell.getV(); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in ArcTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public String getA() { - return a == null ? _master.a : a; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (PolyLineTo) row; - } - - @Override - @NotImplemented - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - if (getDel()) - return; - throw new POIXMLException("Polyline support not implemented"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelCubBezTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelCubBezTo.java deleted file mode 100644 index 3a419bb50..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelCubBezTo.java +++ /dev/null @@ -1,139 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class RelCubBezTo implements GeometryRow { - - RelCubBezTo _master = null; - - // The x-coordinate of the ending vertex of a cubic Bezier curve relative to - // the width of the shape. - Double x = null; - - // The y-coordinate of the ending vertex of a cubic Bezier curve relative to - // the height of the shape. - Double y = null; - - // The x-coordinate of the curve's beginning control point relative to the - // shape's width; a point on the arc. The control point is best located - // between the beginning and ending vertices of the arc. - Double a = null; - - // The y-coordinate of a curve's beginning control point relative to the - // shape's height. - Double b = null; - - // The x-coordinate of the curve's ending control point relative to the - // shape's width; a point on the arc. The control point is best located - // between the beginning control point and ending vertices of the arc. - Double c = null; - - // The y-coordinate of a curve's ending control point relative to the - // shape's height. - Double d = null; - - Boolean deleted = null; - - // TODO: support formulas - - public RelCubBezTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("C")) { - c = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("D")) { - d = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in RelCubBezTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - public Double getC() { - return c == null ? _master.c : c; - } - - public Double getD() { - return d == null ? _master.d : d; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (RelCubBezTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - double w = parent.getWidth(); - double h = parent.getHeight(); - - path.curveTo(getA() * w, getB() * h, getC() * w, getD() * h, - getX() * w, getY() * h); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelEllipticalArcTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelEllipticalArcTo.java deleted file mode 100644 index 9b58406cd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelEllipticalArcTo.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class RelEllipticalArcTo implements GeometryRow { - - RelEllipticalArcTo _master = null; - - // The x-coordinate of the ending vertex on an arc relative to the width of - // the shape. - Double x = null; - - // The y-coordinate of the ending vertex on an arc relative to the height of - // the shape. - Double y = null; - - // The x-coordinate of the arc's control point relative to the shape's - // width; a point on the arc. - Double a = null; - - // The y-coordinate of an arc's control point relative to the shape's width. - Double b = null; - - // The angle of an arc's major axis relative to the x-axis of its parent. - Double c = null; - - // The ratio of an arc's major axis to its minor axis. Despite the usual - // meaning of these words, the "major" axis does not have to be greater than - // the "minor" axis, so this ratio does not have to be greater than 1. - Double d = null; - - Boolean deleted = null; - - // TODO: support formulas - - public RelEllipticalArcTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("C")) { - c = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("D")) { - d = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in RelEllipticalArcTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - public Double getC() { - return c == null ? _master.c : c; - } - - public Double getD() { - return d == null ? _master.d : d; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (RelEllipticalArcTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - double w = parent.getWidth(); - double h = parent.getHeight(); - - // intentionally shadowing variables here - double x = getX() * w; - double y = getY() * h; - double a = getA() * w; - double b = getB() * h; - double c = getC(); - double d = getD(); - - EllipticalArcTo.createEllipticalArc(x, y, a, b, c, d, path); - - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelLineTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelLineTo.java deleted file mode 100644 index 1886f2059..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelLineTo.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -/** - * Contains x-and y-coordinates of the ending vertex of a straight line segment - * relative to a shape's width and height. - */ -public class RelLineTo implements GeometryRow { - - RelLineTo _master = null; - - Double x = null; - Double y = null; - - Boolean deleted = null; - - // TODO: support formulas - - public RelLineTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in RelLineTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (RelLineTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - path.lineTo(getX() * parent.getWidth(), getY() * parent.getHeight()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelMoveTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelMoveTo.java deleted file mode 100644 index 0b6f51c19..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelMoveTo.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -public class RelMoveTo implements GeometryRow { - - RelMoveTo _master = null; - - Double x = null; - Double y = null; - - Boolean deleted = null; - - // TODO: support formulas - - public RelMoveTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in RelMoveTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (RelMoveTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - path.moveTo(getX() * parent.getWidth(), getY() * parent.getHeight()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelQuadBezTo.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelQuadBezTo.java deleted file mode 100644 index ecb4a3a43..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/RelQuadBezTo.java +++ /dev/null @@ -1,122 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -/** - * Contains the x- and y-coordinates of the endpoint of a quadratic Bezier curve - * relative to the shape's width and height and the x- and y-coordinates of the - * control point of the curve relative shape's width and height. - */ -public class RelQuadBezTo implements GeometryRow { - - RelQuadBezTo _master = null; - - // The x-coordinate of the ending vertex of a quadratic Bezier curve - // relative to the width of the shape. - Double x = null; - - // The y-coordinate of the ending vertex of a quadratic Bezier curve - // relative to the height of the shape. - Double y = null; - - // The x-coordinate of the curve's control point relative to the shape's - // width; a point on the arc. The control point is best located about - // halfway between the beginning and ending vertices of the arc. - Double a = null; - - // The y-coordinate of a curve's control point relative to the shape's - // height. - Double b = null; - - Boolean deleted = null; - - // TODO: support formulas - - public RelQuadBezTo(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in RelQuadBezTo row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (RelQuadBezTo) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - - if (getDel()) - return; - - double w = parent.getWidth(); - double h = parent.getHeight(); - - path.quadTo(getA() * w, getB() * h, getX() * w, getY() * h); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/SplineKnot.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/SplineKnot.java deleted file mode 100644 index f75490b07..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/SplineKnot.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -/** - * Contains x- and y-coordinates for a spline's control point and a spline's - * knot. - */ -public class SplineKnot implements GeometryRow { - - SplineKnot _master = null; - - // The x-coordinate of a control point. - Double x = null; - - // The y-coordinate of a control point. - Double y = null; - - // One of the spline's knots (other than the last one or the first two). - Double a = null; - - Boolean deleted = null; - - // TODO: support formulas - - public SplineKnot(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in SplineKnot row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (SplineKnot) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - throw new POIXMLException("Error: Use SplineRenderer!"); - } - - @Override - public String toString() { - return "{SplineKnot x=" + getX() + " y=" + getY() + " a=" + getA() - + "}"; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/SplineStart.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/SplineStart.java deleted file mode 100644 index 224a36c03..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/section/geometry/SplineStart.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.usermodel.section.geometry; - -import org.apache.poi.POIXMLException; -import org.apache.poi.xdgf.usermodel.XDGFCell; -import org.apache.poi.xdgf.usermodel.XDGFShape; - -import com.microsoft.schemas.office.visio.x2012.main.CellType; -import com.microsoft.schemas.office.visio.x2012.main.RowType; - -/** - * Contains x- and y-coordinates for a spline's second control point, its second - * knot, its first knot, the last knot, and the degree of the spline. - */ -public class SplineStart implements GeometryRow { - - SplineStart _master = null; - - // The x-coordinate of a spline's second control point. - Double x = null; - - // The y-coordinate of a spline's second control point. - Double y = null; - - // The second knot of the spline. - Double a = null; - - // The first knot of a spline. - Double b = null; - - // The last knot of a spline. - Double c = null; - - // The degree of a spline (an integer from 1 to 25). - Integer d = null; - - Boolean deleted = null; - - // TODO: support formulas - - public SplineStart(RowType row) { - - if (row.isSetDel()) - deleted = row.getDel(); - - for (CellType cell : row.getCellArray()) { - String cellName = cell.getN(); - - if (cellName.equals("X")) { - x = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("Y")) { - y = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("A")) { - a = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("B")) { - b = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("C")) { - c = XDGFCell.parseDoubleValue(cell); - } else if (cellName.equals("D")) { - d = XDGFCell.parseIntegerValue(cell); - } else { - throw new POIXMLException("Invalid cell '" + cellName - + "' in SplineStart row"); - } - } - } - - public boolean getDel() { - if (deleted != null) - return deleted; - - if (_master != null) - return _master.getDel(); - - return false; - } - - public Double getX() { - return x == null ? _master.x : x; - } - - public Double getY() { - return y == null ? _master.y : y; - } - - public Double getA() { - return a == null ? _master.a : a; - } - - public Double getB() { - return b == null ? _master.b : b; - } - - public Double getC() { - return c == null ? _master.c : c; - } - - public Integer getD() { - return d == null ? _master.d : d; - } - - @Override - public void setupMaster(GeometryRow row) { - _master = (SplineStart) row; - } - - @Override - public void addToPath(java.awt.geom.Path2D.Double path, XDGFShape parent) { - throw new POIXMLException("Error: Use SplineRenderer!"); - } - - @Override - public String toString() { - return "{SplineStart x=" + getX() + " y=" + getY() + " a=" + getA() - + " b=" + getB() + " c=" + getC() + " d=" + getD() + "}"; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeDataAcceptor.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeDataAcceptor.java deleted file mode 100644 index 57c9cdec9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeDataAcceptor.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape; - -import org.apache.poi.xdgf.usermodel.XDGFShape; - -/** - * This acceptor only allows traversal to shapes that have useful data - * associated with them, and tries to elide details that aren't useful when - * analyzing the content of a document. - * - * Useful is subjective of course, and is defined as any of: - * - * - Has non-empty text - Is a 1d shape, such as a line - User specified shapes - * - The outline of stencil objects - TODO - */ -public class ShapeDataAcceptor implements ShapeVisitorAcceptor { - - @Override - public boolean accept(XDGFShape shape) { - - if (shape.isDeleted()) - return false; - - // text is interesting - if (shape.hasText() && shape.getTextAsString().length() != 0) - return true; - - // 1d shapes are interesting, they create connections - if (shape.isShape1D()) - return true; - - // User specified shapes are interesting - if (!shape.hasMaster() && !shape.hasMasterShape()) - return true; - - if (shape.hasMaster() && !shape.hasMasterShape()) - return true; - - // include stencil content, but try to elide stencil interiors - // if (shape.getXmlObject().isSetMaster()) - // return true; - - if (shape.hasMasterShape() && shape.getMasterShape().isTopmost()) - return true; - - return false; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeDebuggerRenderer.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeDebuggerRenderer.java deleted file mode 100644 index d4a010ba2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeDebuggerRenderer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape; - -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.geom.Path2D; - -import org.apache.poi.xdgf.usermodel.XDGFShape; - -public class ShapeDebuggerRenderer extends ShapeRenderer { - - ShapeVisitorAcceptor _debugAcceptor = null; - - public ShapeDebuggerRenderer() { - super(); - } - - public ShapeDebuggerRenderer(Graphics2D g) { - super(g); - } - - public void setDebugAcceptor(ShapeVisitorAcceptor acceptor) { - _debugAcceptor = acceptor; - } - - @Override - protected Path2D drawPath(XDGFShape shape) { - - Path2D path = super.drawPath(shape); - if (_debugAcceptor == null || _debugAcceptor.accept(shape)) { - - // show numbers to associate shapes with ids.. doesn't always work - Font f = _graphics.getFont(); - _graphics.scale(1, -1); - _graphics.setFont(f.deriveFont(0.05F)); - - String shapeId = "" + shape.getID(); - float shapeOffset = -0.1F; - - if (shape.hasMasterShape()) { - shapeId += " MS:" + shape.getMasterShape().getID(); - shapeOffset -= 0.15F; - } - - _graphics.drawString(shapeId, shapeOffset, 0); - _graphics.setFont(f); - _graphics.scale(1, -1); - } - - return path; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeRenderer.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeRenderer.java deleted file mode 100644 index a6a76642d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeRenderer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape; - -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; - -import org.apache.poi.xdgf.usermodel.XDGFShape; -import org.apache.poi.xdgf.usermodel.XDGFText; - -/** - * To use this to render only particular shapes, override it and provide an - * appropriate implementation of getAcceptor() or accept() - */ -public class ShapeRenderer extends ShapeVisitor { - - protected Graphics2D _graphics; - - public ShapeRenderer() { - _graphics = null; - } - - public ShapeRenderer(Graphics2D g) { - _graphics = g; - } - - public void setGraphics(Graphics2D g) { - _graphics = g; - } - - @Override - public void visit(XDGFShape shape, AffineTransform globalTransform, - int level) { - - AffineTransform savedTr = _graphics.getTransform(); - _graphics.transform(globalTransform); - - drawPath(shape); - drawText(shape); - - // we're done, undo the transforms - _graphics.setTransform(savedTr); - } - - protected Path2D drawPath(XDGFShape shape) { - Path2D.Double path = shape.getPath(); - if (path != null) { - - // setup the stroke for this line - - _graphics.setColor(shape.getLineColor()); - _graphics.setStroke(shape.getStroke()); - _graphics.draw(path); - } - - return path; - } - - protected void drawText(XDGFShape shape) { - XDGFText text = shape.getText(); - if (text != null) { - - if (text.getTextContent().equals("Header")) - text.getTextBounds(); - - Font oldFont = _graphics.getFont(); - - _graphics.setFont(oldFont.deriveFont(shape.getFontSize() - .floatValue())); - _graphics.setColor(shape.getFontColor()); - - text.draw(_graphics); - _graphics.setFont(oldFont); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeTextVisitor.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeTextVisitor.java deleted file mode 100644 index 9a0f28cf5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeTextVisitor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.usermodel.shape; - -import java.awt.geom.AffineTransform; - -import org.apache.poi.xdgf.usermodel.XDGFShape; - -/** - * Only visits text nodes, accumulates text content into a string - * - * The text is returned in arbitrary order, with no regards to - * the location of the text on the page. This may change in the - * future. - */ -public class ShapeTextVisitor extends ShapeVisitor { - - protected StringBuilder text = new StringBuilder(); - - public static class TextAcceptor implements ShapeVisitorAcceptor { - public boolean accept(XDGFShape shape) { - return shape.hasText(); - } - } - - protected ShapeVisitorAcceptor getAcceptor() { - return new TextAcceptor(); - } - - public void visit(XDGFShape shape, AffineTransform globalTransform, - int level) { - text.append(shape.getText().getTextContent().trim()); - text.append('\n'); - } - - /** - * Call this after visitation has completed - */ - public String getText() { - return text.toString(); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeVisitor.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeVisitor.java deleted file mode 100644 index 2e4d89647..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeVisitor.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape; - -import java.awt.geom.AffineTransform; - -import org.apache.poi.xdgf.usermodel.XDGFShape; - -/** - * Used to iterate through shapes - * - * To change the behavior of a particular visitor, you can override either - * accept() or getAcceptor() [preferred] - * - * If accept() or visit() throw StopVisitingThisBranch, the iteration will not - * visit subshapes of the shape. - */ -public abstract class ShapeVisitor { - - protected ShapeVisitorAcceptor _acceptor; - - public ShapeVisitor() { - _acceptor = getAcceptor(); - } - - /** - * Is only called on construction of the visitor, allows - * mixing visitors and acceptors - */ - protected ShapeVisitorAcceptor getAcceptor() { - return new ShapeVisitorAcceptor() { - @Override - public boolean accept(XDGFShape shape) { - return !shape.isDeleted(); - } - }; - } - - public void setAcceptor(ShapeVisitorAcceptor acceptor) { - _acceptor = acceptor; - } - - public boolean accept(XDGFShape shape) { - return _acceptor.accept(shape); - } - - /** - * @param shape - * Current shape - * @param globalTransform - * A transform that can convert the shapes points to global - * coordinates - * @param level - * Level in the tree (0 is topmost, 1 is next level... - */ - public abstract void visit(XDGFShape shape, - AffineTransform globalTransform, int level); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeVisitorAcceptor.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeVisitorAcceptor.java deleted file mode 100644 index e50ce11ea..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/ShapeVisitorAcceptor.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape; - -import org.apache.poi.xdgf.usermodel.XDGFShape; - -public interface ShapeVisitorAcceptor { - - public boolean accept(XDGFShape shape); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/exceptions/StopVisiting.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/exceptions/StopVisiting.java deleted file mode 100644 index 2a33c4340..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/exceptions/StopVisiting.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape.exceptions; - -public class StopVisiting extends RuntimeException { - - private static final long serialVersionUID = -4651207777092840750L; - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/exceptions/StopVisitingThisBranch.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/exceptions/StopVisitingThisBranch.java deleted file mode 100644 index eb9e4a620..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/shape/exceptions/StopVisitingThisBranch.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.shape.exceptions; - -public class StopVisitingThisBranch extends RuntimeException { - - private static final long serialVersionUID = 5262319077534717862L; - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/HierarchyPrinter.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/util/HierarchyPrinter.java deleted file mode 100644 index eb9aa9796..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/HierarchyPrinter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.util; - -import java.awt.geom.AffineTransform; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; - -import org.apache.poi.xdgf.usermodel.XDGFPage; -import org.apache.poi.xdgf.usermodel.XDGFShape; -import org.apache.poi.xdgf.usermodel.XmlVisioDocument; -import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor; - -/** - * Debugging tool useful when trying to figure out the hierarchy of the - * shapes in a Visio diagram - */ -public class HierarchyPrinter { - - public static void printHierarchy(XDGFPage page, File outDir) - throws FileNotFoundException, UnsupportedEncodingException { - - File pageFile = new File(outDir, "page" + page.getPageNumber() + "-" - + Util.sanitizeFilename(page.getName()) + ".txt"); - - OutputStream os = new FileOutputStream(pageFile); - PrintStream pos = new PrintStream(os, false, "utf-8"); - - printHierarchy(page, pos); - - pos.close(); - } - - public static void printHierarchy(XDGFPage page, final PrintStream os) { - - page.getContent().visitShapes(new ShapeVisitor() { - - @Override - public void visit(XDGFShape shape, AffineTransform globalTransform, - int level) { - for (int i = 0; i < level; i++) { - os.append(" "); - } - // TODO: write text? - os.println(shape.toString() + " [" + shape.getShapeType() - + ", " + shape.getSymbolName() + "] " - + shape.getMasterShape() + " " - + shape.getTextAsString().trim()); - } - }); - } - - public static void printHierarchy(XmlVisioDocument document, - String outDirname) throws FileNotFoundException, UnsupportedEncodingException { - - File outDir = new File(outDirname); - - for (XDGFPage page : document.getPages()) { - printHierarchy(page, outDir); - } - } - - public static void main(String[] args) throws Exception { - if (args.length != 2) { - System.err.println("Usage: in.vsdx outdir"); - System.exit(1); - } - - String inFilename = args[0]; - String outDir = args[1]; - - XmlVisioDocument doc = new XmlVisioDocument(new FileInputStream( - inFilename)); - printHierarchy(doc, outDir); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/ObjectFactory.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/util/ObjectFactory.java deleted file mode 100644 index af0253f59..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/ObjectFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.util; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLException; -import org.apache.xmlbeans.XmlObject; - - -public class ObjectFactory { - - Map> _types = new HashMap>(); - - public void put(String typeName, Class cls, Class... varargs) throws NoSuchMethodException, SecurityException { - _types.put(typeName, cls.getDeclaredConstructor(varargs)); - } - - public T load(String name, Object... varargs) { - Constructor constructor = _types.get(name); - if (constructor == null) { - - @SuppressWarnings("unchecked") - X xmlObject = (X) varargs[0]; - - String typeName = xmlObject.schemaType().getName().getLocalPart(); - throw new POIXMLException("Invalid '" + typeName + "' name '" + name + "'"); - } - - try { - return constructor.newInstance(varargs); - } catch (InvocationTargetException e) { - throw new POIXMLException(e.getCause()); - } catch (Exception e) { - throw new POIXMLException(e); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/Util.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/util/Util.java deleted file mode 100644 index 0e08294c8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/Util.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.util; - -public class Util { - - public static int countLines(String str) { - int lines = 1; - int pos = 0; - while ((pos = str.indexOf("\n", pos) + 1) != 0) { - lines++; - } - return lines; - } - - // this probably isn't 100% correct, so don't use it in security-sensitive - // applications! - // from: http://www.rgagnon.com/javadetails/java-0662.html - public static String sanitizeFilename(String name) { - return name.replaceAll("[:\\\\/*\"?|<>]", "_"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/VsdxToPng.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/util/VsdxToPng.java deleted file mode 100644 index 9ab71ea8c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/util/VsdxToPng.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.util; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import javax.imageio.ImageIO; - -import org.apache.poi.xdgf.geom.Dimension2dDouble; -import org.apache.poi.xdgf.usermodel.XDGFPage; -import org.apache.poi.xdgf.usermodel.XmlVisioDocument; -import org.apache.poi.xdgf.usermodel.shape.ShapeDebuggerRenderer; -import org.apache.poi.xdgf.usermodel.shape.ShapeRenderer; - -/** - * Converts a Visio diagram to a PNG file. - * - * As more elements and styles are added/supported the output will get - * better, but it's very rough right now. - */ -public class VsdxToPng { - - public static void renderToPng(XDGFPage page, String outFilename, - double scale, ShapeRenderer renderer) throws IOException { - renderToPng(page, new File(outFilename), scale, renderer); - } - - public static void renderToPngDir(XDGFPage page, File outDir, double scale, - ShapeRenderer renderer) throws IOException { - - File pageFile = new File(outDir, "page" + page.getPageNumber() + "-" - + Util.sanitizeFilename(page.getName()) + ".png"); - System.out.println("** Writing image to " + pageFile); - - renderToPng(page, pageFile, scale, renderer); - - } - - public static void renderToPng(XDGFPage page, File outFile, double scale, - ShapeRenderer renderer) throws IOException { - - Dimension2dDouble sz = page.getPageSize(); - - int width = (int) (scale * sz.getWidth()); - int height = (int) (scale * sz.getHeight()); - - BufferedImage img = new BufferedImage(width, height, - BufferedImage.TYPE_INT_RGB); - final Graphics2D graphics = img.createGraphics(); - - // default rendering options - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_QUALITY); - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BICUBIC); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, - RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - graphics.setColor(Color.black); - graphics.setBackground(Color.white); - graphics.clearRect(0, 0, width, height); - - // Visio's coordinate system is flipped, so flip the image vertically - graphics.translate(0, img.getHeight()); - graphics.scale(scale, -scale); - - // toplevel shapes only - renderer.setGraphics(graphics); - page.getContent().visitShapes(renderer); - - graphics.dispose(); - - FileOutputStream out = new FileOutputStream(outFile); - ImageIO.write(img, "png", out); - out.close(); - } - - public static void renderToPng(XmlVisioDocument document, - String outDirname, double scale, ShapeRenderer renderer) - throws IOException { - - File outDir = new File(outDirname); - - for (XDGFPage page : document.getPages()) { - renderToPngDir(page, outDir, scale, renderer); - } - } - - public static void main(String[] args) throws Exception { - if (args.length > 2) { - System.err.println("Usage: [--debug] in.vsdx outdir"); - System.exit(1); - } - - ShapeRenderer renderer = new ShapeRenderer(); - - String inFilename = args[0]; - String pngDir = args[1]; - - if (args[0].equals("--debug")) { - inFilename = args[1]; - pngDir = args[2]; - renderer = new ShapeDebuggerRenderer(); - } - - XmlVisioDocument doc = new XmlVisioDocument(new FileInputStream( - inFilename)); - renderToPng(doc, pngDir, 2000 / 11.0, renderer); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java b/trunk/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java deleted file mode 100644 index 5e5264645..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.xml; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xdgf.usermodel.XDGFDocument; - -public class XDGFXMLDocumentPart extends POIXMLDocumentPart { - - protected XDGFDocument _document; - - /** - * @since POI 3.14-Beta1 - */ - public XDGFXMLDocumentPart(PackagePart part, XDGFDocument document) { - super(part); - _document = document; - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XDGFXMLDocumentPart(PackagePart part, PackageRelationship rel, XDGFDocument document) { - this(part, document); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java b/trunk/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java deleted file mode 100644 index 5f757d0c5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java +++ /dev/null @@ -1,223 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.extractor; - -import java.io.IOException; - -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFCommentAuthors; -import org.apache.poi.xslf.usermodel.XSLFComments; -import org.apache.poi.xslf.usermodel.XSLFNotes; -import org.apache.poi.xslf.usermodel.XSLFRelation; -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.poi.xslf.usermodel.XSLFShapeContainer; -import org.apache.poi.xslf.usermodel.XSLFSlide; -import org.apache.poi.xslf.usermodel.XSLFSlideLayout; -import org.apache.poi.xslf.usermodel.XSLFSlideMaster; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.poi.xslf.usermodel.XSLFTable; -import org.apache.poi.xslf.usermodel.XSLFTableCell; -import org.apache.poi.xslf.usermodel.XSLFTableRow; -import org.apache.poi.xslf.usermodel.XSLFTextShape; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTComment; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentAuthor; - -public class XSLFPowerPointExtractor extends POIXMLTextExtractor { - public static final XSLFRelation[] SUPPORTED_TYPES = new XSLFRelation[] { - XSLFRelation.MAIN, XSLFRelation.MACRO, XSLFRelation.MACRO_TEMPLATE, - XSLFRelation.PRESENTATIONML, XSLFRelation.PRESENTATIONML_TEMPLATE, - XSLFRelation.PRESENTATION_MACRO - }; - - private XMLSlideShow slideshow; - private boolean slidesByDefault = true; - private boolean notesByDefault = false; - private boolean masterByDefault = false; - - public XSLFPowerPointExtractor(XMLSlideShow slideshow) { - super(slideshow); - this.slideshow = slideshow; - } - public XSLFPowerPointExtractor(XSLFSlideShow slideshow) throws XmlException, IOException { - this(new XMLSlideShow(slideshow.getPackage())); - } - public XSLFPowerPointExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException { - this(new XSLFSlideShow(container)); - } - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" XSLFPowerPointExtractor "); - System.exit(1); - } - POIXMLTextExtractor extractor = - new XSLFPowerPointExtractor( - new XSLFSlideShow(args[0])); - System.out.println(extractor.getText()); - extractor.close(); - } - - /** - * Should a call to getText() return slide text? - * Default is yes - */ - public void setSlidesByDefault(boolean slidesByDefault) { - this.slidesByDefault = slidesByDefault; - } - /** - * Should a call to getText() return notes text? - * Default is no - */ - public void setNotesByDefault(boolean notesByDefault) { - this.notesByDefault = notesByDefault; - } - - /** - * Should a call to getText() return text from master? Default is no - */ - public void setMasterByDefault(boolean masterByDefault) { - this.masterByDefault = masterByDefault; - } - - /** - * Gets the slide text, but not the notes text - */ - public String getText() { - return getText(slidesByDefault, notesByDefault); - } - - /** - * Gets the requested text from the file - * @param slideText Should we retrieve text from slides? - * @param notesText Should we retrieve text from notes? - */ - public String getText(boolean slideText, boolean notesText) { - return getText(slideText, notesText, masterByDefault); - } - - /** - * Gets the requested text from the file - * - * @param slideText Should we retrieve text from slides? - * @param notesText Should we retrieve text from notes? - * @param masterText Should we retrieve text from master slides? - * - * @return the extracted text - */ - public String getText(boolean slideText, boolean notesText, boolean masterText) { - StringBuilder text = new StringBuilder(); - - for (XSLFSlide slide : slideshow.getSlides()) { - text.append(getText(slide, slideText, notesText, masterText)); - } - - return text.toString(); - } - - /** - * Gets the requested text from the slide - * - * @param slide the slide to retrieve the text from - * @param slideText Should we retrieve text from slides? - * @param notesText Should we retrieve text from notes? - * @param masterText Should we retrieve text from master slides? - * - * @return the extracted text - */ - public static String getText(XSLFSlide slide, boolean slideText, boolean notesText, boolean masterText) { - StringBuilder text = new StringBuilder(); - - XSLFCommentAuthors commentAuthors = slide.getSlideShow().getCommentAuthors(); - - XSLFNotes notes = slide.getNotes(); - XSLFComments comments = slide.getComments(); - XSLFSlideLayout layout = slide.getSlideLayout(); - XSLFSlideMaster master = layout.getSlideMaster(); - - // TODO Do the slide's name - // (Stored in docProps/app.xml) - - // Do the slide's text if requested - if (slideText) { - extractText(slide, false, text); - - // If requested, get text from the master and it's layout - if(masterText) { - if(layout != null) { - extractText(layout, true, text); - } - if(master != null) { - extractText(master, true, text); - } - } - - // If the slide has comments, do those too - if (comments != null) { - for (CTComment comment : comments.getCTCommentsList().getCmArray()) { - // Do the author if we can - if (commentAuthors != null) { - CTCommentAuthor author = commentAuthors.getAuthorById(comment.getAuthorId()); - if(author != null) { - text.append(author.getName() + ": "); - } - } - - // Then the comment text, with a new line afterwards - text.append(comment.getText()); - text.append("\n"); - } - } - } - - // Do the notes if requested - if (notesText && notes != null) { - extractText(notes, false, text); - } - - return text.toString(); - } - - private static void extractText(XSLFShapeContainer data, boolean skipPlaceholders, StringBuilder text) { - for (XSLFShape s : data) { - if (s instanceof XSLFShapeContainer) { - extractText((XSLFShapeContainer)s, skipPlaceholders, text); - } else if (s instanceof XSLFTextShape) { - XSLFTextShape ts = (XSLFTextShape)s; - // Skip non-customised placeholder text - if (!(skipPlaceholders && ts.isPlaceholder())) { - text.append(ts.getText()); - text.append("\n"); - } - } else if (s instanceof XSLFTable) { - XSLFTable ts = (XSLFTable)s; - // Skip non-customised placeholder text - for (XSLFTableRow r : ts) { - for (XSLFTableCell c : r) { - text.append(c.getText()); - text.append("\t"); - } - text.append("\n"); - } - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java b/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java deleted file mode 100644 index 3358a7277..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.model; - -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; - -public abstract class CharacterPropertyFetcher extends ParagraphPropertyFetcher { - public CharacterPropertyFetcher(int level) { - super(level); - } - - public boolean fetch(CTTextParagraphProperties props) { - if (props != null && props.isSetDefRPr()) { - return fetch(props.getDefRPr()); - } - - return false; - } - - public abstract boolean fetch(CTTextCharacterProperties props); - -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java b/trunk/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java deleted file mode 100644 index c6c583616..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.model; - -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; - -/** - * - * @author Yegor Kozlov - */ -public abstract class ParagraphPropertyFetcher extends PropertyFetcher { - int _level; - - public ParagraphPropertyFetcher(int level) { - _level = level; - } - - public boolean fetch(XSLFShape shape) { - - XmlObject[] o = shape.getXmlObject().selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + - "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + - ".//p:txBody/a:lstStyle/a:lvl" + (_level + 1) + "pPr" - ); - if (o.length == 1) { - CTTextParagraphProperties props = (CTTextParagraphProperties) o[0]; - return fetch(props); - } - return false; - } - - public abstract boolean fetch(CTTextParagraphProperties props); -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java b/trunk/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java deleted file mode 100644 index f9e8a780d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.model; - -import org.apache.poi.util.Internal; -import org.apache.poi.xslf.usermodel.XSLFShape; - -/** - * Used internally to navigate the PresentationML text style hierarchy and fetch properties - * - * @author Yegor Kozlov -*/ -@Internal -public abstract class PropertyFetcher { - private T _value; - - /** - * - * @param shape the shape being examined - * @return true if the desired property was fetched - */ - public abstract boolean fetch(XSLFShape shape); - - public T getValue(){ - return _value; - } - - public void setValue(T val){ - _value = val; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java b/trunk/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java deleted file mode 100644 index cc8486a33..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.model; - -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; - -/** - * Created by IntelliJ IDEA. - * User: yegor - * Date: Oct 21, 2011 - * Time: 1:18:52 PM - * To change this template use File | Settings | File Templates. - */ -public abstract class TextBodyPropertyFetcher extends PropertyFetcher { - - public boolean fetch(XSLFShape shape) { - - XmlObject[] o = shape.getXmlObject().selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + - "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + - ".//p:txBody/a:bodyPr" - ); - if (o.length == 1) { - CTTextBodyProperties props = (CTTextBodyProperties) o[0]; - return fetch(props); - } - - return false; - } - - public abstract boolean fetch(CTTextBodyProperties props); - -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java deleted file mode 100644 index 6a6ee3807..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.util.Removal; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; - -/* - * @deprecated POI 3.16 beta 1. Instead iterate over the shapes/notes of the slides - */ -@Removal(version="3.18") -public class DrawingParagraph { - private final CTTextParagraph p; - - public DrawingParagraph(CTTextParagraph p) { - this.p = p; - } - - public CharSequence getText() { - StringBuilder text = new StringBuilder(); - - XmlCursor c = p.newCursor(); - c.selectPath("./*"); - while (c.toNextSelection()) { - XmlObject o = c.getObject(); - if (o instanceof CTRegularTextRun) { - CTRegularTextRun txrun = (CTRegularTextRun) o; - text.append(txrun.getT()); - } else if (o instanceof CTTextLineBreak) { - text.append('\n'); - } - } - - c.dispose(); - - return text; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java deleted file mode 100644 index b59a5bb23..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.util.Removal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTable; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; - -/* - * @deprecated POI 3.16 beta 1. use {@link XSLFTable} instead - */ -@Removal(version="3.18") -public class DrawingTable { - private final CTTable table; - - public DrawingTable(CTTable table) { - this.table = table; - } - - public DrawingTableRow[] getRows() { - CTTableRow[] ctTableRows = table.getTrArray(); - DrawingTableRow[] o = new DrawingTableRow[ctTableRows.length]; - - for (int i=0; i { - private static POILogger _logger = POILogFactory.getLogger(XMLSlideShow.class); - - private CTPresentation _presentation; - private List _slides; - private List _masters; - private List _pictures; - private XSLFTableStyles _tableStyles; - private XSLFNotesMaster _notesMaster; - private XSLFCommentAuthors _commentAuthors; - - public XMLSlideShow() { - this(empty()); - } - - public XMLSlideShow(OPCPackage pkg) { - super(pkg); - - try { - if(getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) { - rebase(getPackage()); - } - - //build a tree of POIXMLDocumentParts, this presentation being the root - load(XSLFFactory.getInstance()); - } catch (Exception e){ - throw new POIXMLException(e); - } - } - - public XMLSlideShow(InputStream is) throws IOException { - this(PackageHelper.open(is)); - } - - static OPCPackage empty() { - InputStream is = XMLSlideShow.class.getResourceAsStream("empty.pptx"); - if (is == null) { - throw new POIXMLException("Missing resource 'empty.pptx'"); - } - try { - return OPCPackage.open(is); - } catch (Exception e){ - throw new POIXMLException(e); - } finally { - try { - is.close(); - } catch (Exception e) { - throw new POIXMLException(e); - } - } - } - - @Override - protected void onDocumentRead() throws IOException { - try { - PresentationDocument doc = - PresentationDocument.Factory.parse(getCorePart().getInputStream(), DEFAULT_XML_OPTIONS); - _presentation = doc.getPresentation(); - - Map masterMap = new HashMap(); - Map shIdMap = new HashMap(); - for (RelationPart rp : getRelationParts()) { - POIXMLDocumentPart p = rp.getDocumentPart(); - if (p instanceof XSLFSlide) { - shIdMap.put(rp.getRelationship().getId(), (XSLFSlide) p); - } else if (p instanceof XSLFSlideMaster) { - masterMap.put(getRelationId(p), (XSLFSlideMaster) p); - } else if (p instanceof XSLFTableStyles){ - _tableStyles = (XSLFTableStyles)p; - } else if (p instanceof XSLFNotesMaster) { - _notesMaster = (XSLFNotesMaster)p; - } else if (p instanceof XSLFCommentAuthors) { - _commentAuthors = (XSLFCommentAuthors)p; - } - } - - _masters = new ArrayList(masterMap.size()); - for (CTSlideMasterIdListEntry masterId : _presentation.getSldMasterIdLst().getSldMasterIdList()) { - XSLFSlideMaster master = masterMap.get(masterId.getId2()); - _masters.add(master); - } - - _slides = new ArrayList(shIdMap.size()); - if (_presentation.isSetSldIdLst()) { - for (CTSlideIdListEntry slId : _presentation.getSldIdLst().getSldIdList()) { - XSLFSlide sh = shIdMap.get(slId.getId2()); - if (sh == null) { - _logger.log(POILogger.WARN, "Slide with r:id " + slId.getId() + " was defined, but didn't exist in package, skipping"); - continue; - } - _slides.add(sh); - } - } - } catch (XmlException e) { - throw new POIXMLException(e); - } - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - _presentation.save(out, DEFAULT_XML_OPTIONS); - out.close(); - } - - /** - * Get the document's embedded files. - */ - @Override - public List getAllEmbedds() throws OpenXML4JException { - return Collections.unmodifiableList( - getPackage().getPartsByName(Pattern.compile("/ppt/embeddings/.*?")) - ); - } - - @Override - public List getPictureData() { - if(_pictures == null){ - List mediaParts = getPackage().getPartsByName(Pattern.compile("/ppt/media/.*?")); - _pictures = new ArrayList(mediaParts.size()); - for(PackagePart part : mediaParts){ - XSLFPictureData pd = new XSLFPictureData(part); - pd.setIndex(_pictures.size()); - _pictures.add(pd); - } - } - return Collections.unmodifiableList(_pictures); - } - - /** - * Create a slide and initialize it from the specified layout. - * - * @param layout The layout to use for the new slide. - * @return created slide - */ - public XSLFSlide createSlide(XSLFSlideLayout layout) { - int slideNumber = 256, cnt = 1; - CTSlideIdList slideList; - if (!_presentation.isSetSldIdLst()) slideList = _presentation.addNewSldIdLst(); - else { - slideList = _presentation.getSldIdLst(); - for(CTSlideIdListEntry slideId : slideList.getSldIdArray()){ - slideNumber = (int)Math.max(slideId.getId() + 1, slideNumber); - cnt++; - } - - // Bug 55791: We also need to check that the resulting file name is not already taken - // this can happen when removing/adding slides - while(true) { - String slideName = XSLFRelation.SLIDE.getFileName(cnt); - boolean found = false; - for (POIXMLDocumentPart relation : getRelations()) { - if (relation.getPackagePart() != null && - slideName.equals(relation.getPackagePart().getPartName().getName())) { - // name is taken => try next one - found = true; - break; - } - } - - if(!found && - getPackage().getPartsByName(Pattern.compile(Pattern.quote(slideName))).size() > 0) { - // name is taken => try next one - found = true; - } - - if (!found) { - break; - } - cnt++; - } - } - - RelationPart rp = createRelationship( - XSLFRelation.SLIDE, XSLFFactory.getInstance(), cnt, false); - XSLFSlide slide = rp.getDocumentPart(); - - CTSlideIdListEntry slideId = slideList.addNewSldId(); - slideId.setId(slideNumber); - slideId.setId2(rp.getRelationship().getId()); - - layout.copyLayout(slide); - slide.addRelation(null, XSLFRelation.SLIDE_LAYOUT, layout); - - _slides.add(slide); - return slide; - } - - /** - * Create a blank slide using the default (first) master. - */ - @Override - public XSLFSlide createSlide() { - XSLFSlideLayout layout = _masters.get(0).getLayout(SlideLayout.BLANK); - if(layout == null) throw new IllegalArgumentException("Blank layout was not found"); - - return createSlide(layout); - } - - /** - * Return notes slide for the specified slide or create new if it does not exist yet. - */ - public XSLFNotes getNotesSlide(XSLFSlide slide) { - - XSLFNotes notesSlide = slide.getNotes(); - if (notesSlide == null) { - notesSlide = createNotesSlide(slide); - } - - return notesSlide; - } - - /** - * Create a blank notes slide. - */ - private XSLFNotes createNotesSlide(XSLFSlide slide) { - - if (_notesMaster == null) { - createNotesMaster(); - } - - Integer slideIndex = XSLFRelation.SLIDE.getFileNameIndex(slide); - - // add notes slide to presentation - XSLFNotes notesSlide = (XSLFNotes) createRelationship - (XSLFRelation.NOTES, XSLFFactory.getInstance(), slideIndex); - // link slide and notes slide with each other - slide.addRelation(null, XSLFRelation.NOTES, notesSlide); - notesSlide.addRelation(null, XSLFRelation.NOTES_MASTER, _notesMaster); - notesSlide.addRelation(null, XSLFRelation.SLIDE, slide); - - notesSlide.importContent(_notesMaster); - - return notesSlide; - } - - /** - * Create a notes master. - */ - public void createNotesMaster() { - RelationPart rp = createRelationship - (XSLFRelation.NOTES_MASTER, XSLFFactory.getInstance(), 1, false); - _notesMaster = rp.getDocumentPart(); - - CTNotesMasterIdList notesMasterIdList = _presentation.addNewNotesMasterIdLst(); - CTNotesMasterIdListEntry notesMasterId = notesMasterIdList.addNewNotesMasterId(); - notesMasterId.setId(rp.getRelationship().getId()); - - Integer themeIndex = 1; - // TODO: check if that list can be replaced by idx = Math.max(idx,themeIdx) - List themeIndexList = new ArrayList(); - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFTheme) { - themeIndexList.add(XSLFRelation.THEME.getFileNameIndex(p)); - } - } - - if (!themeIndexList.isEmpty()) { - Boolean found = false; - for (Integer i = 1; i <= themeIndexList.size(); i++) { - if (!themeIndexList.contains(i)) { - found = true; - themeIndex = i; - } - } - if (!found) { - themeIndex = themeIndexList.size() + 1; - } - } - - XSLFTheme theme = (XSLFTheme) createRelationship - (XSLFRelation.THEME, XSLFFactory.getInstance(), themeIndex); - theme.importTheme(getSlides().get(0).getTheme()); - - _notesMaster.addRelation(null, XSLFRelation.THEME, theme); - } - - /** - * Return the Notes Master, if there is one. - * (May not be present if no notes exist) - */ - public XSLFNotesMaster getNotesMaster() { - return _notesMaster; - } - - @Override - public List getSlideMasters() { - return _masters; - } - - /** - * Return all the slides in the slideshow - */ - public List getSlides() { - return _slides; - } - - /** - * Returns the list of comment authors, if there is one. - * Will only be present if at least one slide has comments on it. - */ - public XSLFCommentAuthors getCommentAuthors() { - return _commentAuthors; - } - - /** - * - * @param newIndex 0-based index of the slide - */ - public void setSlideOrder(XSLFSlide slide, int newIndex){ - int oldIndex = _slides.indexOf(slide); - if(oldIndex == -1) throw new IllegalArgumentException("Slide not found"); - if (oldIndex == newIndex) return; - - // fix the usermodel container - _slides.add(newIndex, _slides.remove(oldIndex)); - - // fix ordering in the low-level xml - CTSlideIdList sldIdLst = _presentation.getSldIdLst(); - CTSlideIdListEntry[] entries = sldIdLst.getSldIdArray(); - CTSlideIdListEntry oldEntry = entries[oldIndex]; - if (oldIndex < newIndex) { - System.arraycopy(entries, oldIndex + 1, entries, oldIndex, newIndex - oldIndex); - } else { - System.arraycopy(entries, newIndex, entries, newIndex + 1, oldIndex - newIndex); - } - entries[newIndex] = oldEntry; - sldIdLst.setSldIdArray(entries); - } - - public XSLFSlide removeSlide(int index){ - XSLFSlide slide = _slides.remove(index); - removeRelation(slide); - _presentation.getSldIdLst().removeSldId(index); - return slide; - } - - @Override - public Dimension getPageSize(){ - CTSlideSize sz = _presentation.getSldSz(); - int cx = sz.getCx(); - int cy = sz.getCy(); - return new Dimension((int)Units.toPoints(cx), (int)Units.toPoints(cy)); - } - - @Override - public void setPageSize(Dimension pgSize){ - CTSlideSize sz = CTSlideSize.Factory.newInstance(); - sz.setCx(Units.toEMU(pgSize.getWidth())); - sz.setCy(Units.toEMU(pgSize.getHeight())); - _presentation.setSldSz(sz); - } - - - @Internal - public CTPresentation getCTPresentation(){ - return _presentation; - } - - /** - * Adds a picture to the workbook. - * - * @param pictureData The bytes of the picture - * @param format The format of the picture. - * - * @return the picture data - */ - public XSLFPictureData addPicture(byte[] pictureData, PictureType format) { - XSLFPictureData img = findPictureData(pictureData); - - if (img != null) return img; - - int imageNumber = _pictures.size(); - XSLFRelation relType = XSLFPictureData.getRelationForType(format); - if (relType == null) { - throw new IllegalArgumentException("Picture type "+format+" is not supported."); - } - img = (XSLFPictureData) createRelationship(relType, XSLFFactory.getInstance(), imageNumber + 1, true).getDocumentPart(); - img.setIndex(imageNumber); - _pictures.add(img); - try { - OutputStream out = img.getPackagePart().getOutputStream(); - out.write(pictureData); - out.close(); - } catch (IOException e) { - throw new POIXMLException(e); - } - - return img; - } - - - /** - * Adds a picture to the slideshow. - * - * @param is The stream to read image from - * @param format The format of the picture - * - * @return the picture data - * @since 3.15 beta 2 - */ - @Override - public XSLFPictureData addPicture(InputStream is, PictureType format) throws IOException - { - return addPicture(IOUtils.toByteArray(is), format); - } - - - /** - * Adds a picture to the presentation. - * - * @param pict The file containing the image to add - * @param format The format of the picture. - * - * @return the picture data - * @since 3.15 beta 2 - */ - @Override - public XSLFPictureData addPicture(File pict, PictureType format) throws IOException - { - int length = (int) pict.length(); - byte[] data = new byte[length]; - FileInputStream is = new FileInputStream(pict); - try { - IOUtils.readFully(is, data); - } finally { - is.close(); - } - return addPicture(data, format); - } - - - /** - * check if a picture with this picture data already exists in this presentation - * - * @param pictureData The picture data to find in the SlideShow - * @return {@code null} if picture data is not found in this slideshow - * @since 3.15 beta 2 - */ - @Override - public XSLFPictureData findPictureData(byte[] pictureData) { - long checksum = IOUtils.calculateChecksum(pictureData); - byte cs[] = new byte[LittleEndianConsts.LONG_SIZE]; - LittleEndian.putLong(cs,0,checksum); - - for(XSLFPictureData pic : getPictureData()){ - if(Arrays.equals(pic.getChecksum(), cs)) { - return pic; - } - } - return null; - } - - - /** - * Scan the master slides for the first slide layout with the given name. - * - * @param name The layout name (case-insensitive). Cannot be null. - * @return the first layout found or null on failure - */ - public XSLFSlideLayout findLayout(String name) { - for (XSLFSlideMaster master : getSlideMasters()) { - XSLFSlideLayout layout = master.getLayout(name); - if (layout != null) { - return layout; - } - } - return null; - } - - - public XSLFTableStyles getTableStyles(){ - return _tableStyles; - } - - CTTextParagraphProperties getDefaultParagraphStyle(int level) { - XmlObject[] o = _presentation.selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + - "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + - ".//p:defaultTextStyle/a:lvl" +(level+1)+ "pPr"); - if(o.length == 1){ - return (CTTextParagraphProperties)o[0]; - } - return null; - } - - @Override - public MasterSheet createMasterSheet() throws IOException { - // TODO: implement! - throw new UnsupportedOperationException(); - } - - public Resources getResources() { - // TODO: implement! - throw new UnsupportedOperationException(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java deleted file mode 100644 index e45df5ee2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.sl.usermodel.AutoShape; -import org.apache.poi.util.Beta; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; - - -/** - * Represents a shape with a preset geometry. - * - * @author Yegor Kozlov - */ -@Beta -public class XSLFAutoShape extends XSLFTextShape - implements AutoShape { - - /*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { - super(shape, sheet); - } - - /*package*/ - static XSLFAutoShape create(CTShape shape, XSLFSheet sheet) { - if (shape.getSpPr().isSetCustGeom()) { - return new XSLFFreeformShape(shape, sheet); - } else if (shape.getNvSpPr().getCNvSpPr().isSetTxBox()) { - return new XSLFTextBox(shape, sheet); - } else { - return new XSLFAutoShape(shape, sheet); - } - } - - /** - * @param shapeId 1-based shapeId - */ - static CTShape prototype(int shapeId) { - CTShape ct = CTShape.Factory.newInstance(); - CTShapeNonVisual nvSpPr = ct.addNewNvSpPr(); - CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); - cnv.setName("AutoShape " + shapeId); - cnv.setId(shapeId + 1); - nvSpPr.addNewCNvSpPr(); - nvSpPr.addNewNvPr(); - CTShapeProperties spPr = ct.addNewSpPr(); - CTPresetGeometry2D prst = spPr.addNewPrstGeom(); - prst.setPrst(STShapeType.RECT); - prst.addNewAvLst(); - return ct; - } - - protected static void initTextBody(CTTextBody txBody) { - CTTextBodyProperties bodypr = txBody.addNewBodyPr(); - bodypr.setAnchor(STTextAnchoringType.T); - bodypr.setRtlCol(false); - CTTextParagraph p = txBody.addNewP(); - p.addNewPPr().setAlgn(STTextAlignType.L); - CTTextCharacterProperties endPr = p.addNewEndParaRPr(); - endPr.setLang("en-US"); - endPr.setSz(1100); - p.addNewR().setT(""); - txBody.addNewLstStyle(); - } - - protected CTTextBody getTextBody(boolean create){ - CTShape shape = (CTShape)getXmlObject(); - CTTextBody txBody = shape.getTxBody(); - if (txBody == null && create) { - txBody = shape.addNewTxBody(); - initTextBody(txBody); - } - return txBody; - } - - @Override - public String toString(){ - return "[" + getClass().getSimpleName() + "] " + getShapeName(); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java deleted file mode 100644 index 1eac4b277..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.POIXMLException; -import org.apache.poi.sl.usermodel.Background; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; - -/** - * Background shape - */ -public class XSLFBackground extends XSLFSimpleShape - implements Background { - - /* package */XSLFBackground(CTBackground shape, XSLFSheet sheet) { - super(shape, sheet); - } - - @Override - public Rectangle2D getAnchor(){ - Dimension pg = getSheet().getSlideShow().getPageSize(); - return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); - } - - /** - * background does not have a associated transform, therefore we return null - * - * @param create ignored - * - * @return null - */ - @Override - protected CTTransform2D getXfrm(boolean create) { - return null; - } - - @Override - public void setPlaceholder(Placeholder placeholder) { - // extending XSLFSimpleShape is a bit unlucky ... - throw new POIXMLException("Can't set a placeholder for a background"); - } - - protected CTBackgroundProperties getBgPr(boolean create) { - CTBackground bg = (CTBackground)getXmlObject(); - if (!bg.isSetBgPr() && create) { - if (bg.isSetBgRef()) { - bg.unsetBgRef(); - } - return bg.addNewBgPr(); - } - return bg.getBgPr(); - } - - public void setFillColor(Color color) { - CTBackgroundProperties bgPr = getBgPr(true); - - if (color == null) { - if (bgPr.isSetSolidFill()) { - bgPr.unsetSolidFill(); - } - - if (!bgPr.isSetNoFill()) { - bgPr.addNewNoFill(); - } - } else { - if (bgPr.isSetNoFill()) { - bgPr.unsetNoFill(); - } - - CTSolidColorFillProperties fill = bgPr.isSetSolidFill() ? bgPr.getSolidFill() : bgPr.addNewSolidFill(); - - XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); - col.setColor(color); - } - } - - @Override - protected XmlObject getShapeProperties() { - CTBackground bg = (CTBackground)getXmlObject(); - if (bg.isSetBgPr()) { - return bg.getBgPr(); - } else if (bg.isSetBgRef()) { - return bg.getBgRef(); - } else { - return null; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java deleted file mode 100644 index 40b254c93..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; -import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; - -/** - * Represents a Chart in a .pptx presentation - * - * - */ -@Beta -public final class XSLFChart extends POIXMLDocumentPart { - - /** - * Root element of the Chart part - */ - private CTChartSpace chartSpace; - - /** - * The Chart within that - */ - private CTChart chart; - - /** - * Construct a chart from a package part. - * - * @param part the package part holding the chart data, - * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml - * - * @since POI 3.14-Beta1 - */ - protected XSLFChart(PackagePart part) throws IOException, XmlException { - super(part); - - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); - chart = chartSpace.getChart(); - } - - /** - * Construct a chart from a package part. - * - * @param part the package part holding the chart data, - * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml - * @param rel the package relationship holding this chart, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSLFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - /** - * Return the underlying CTChartSpace bean, the root element of the Chart part. - * - * @return the underlying CTChartSpace bean - */ - @Internal - public CTChartSpace getCTChartSpace(){ - return chartSpace; - } - - /** - * Return the underlying CTChart bean, within the Chart Space - * - * @return the underlying CTChart bean - */ - @Internal - public CTChart getCTChart(){ - return chart; - } - - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - chartSpace.save(out, xmlOptions); - out.close(); - } - - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java deleted file mode 100644 index f519f7ec2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; - -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.ColorStyle; -import org.apache.poi.sl.usermodel.PresetColor; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference; -import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveFixedPercentage; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTScRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSystemColor; -import org.w3c.dom.Node; - -/** - * Encapsulates logic to read color definitions from DrawingML and convert them to java.awt.Color - */ -@Beta -@Internal -public class XSLFColor { - private static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class); - - private XmlObject _xmlObject; - private Color _color; - private CTSchemeColor _phClr; - - public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) { - _xmlObject = obj; - _phClr = phClr; - _color = toColor(obj, theme); - } - - @Internal - public XmlObject getXmlObject() { - return _xmlObject; - } - - /** - * - * @return the displayed color as a Java Color. - * If not color information was found in the supplied xml object then a null is returned. - */ - public Color getColor() { - return DrawPaint.applyColorTransform(getColorStyle()); - } - - public ColorStyle getColorStyle() { - return new ColorStyle() { - public Color getColor() { - return _color; - } - - public int getAlpha() { - return getRawValue("alpha"); - } - - public int getHueOff() { - return getRawValue("hueOff"); - } - - public int getHueMod() { - return getRawValue("hueMod"); - } - - public int getSatOff() { - return getRawValue("satOff"); - } - - public int getSatMod() { - return getRawValue("satMod"); - } - - public int getLumOff() { - return getRawValue("lumOff"); - } - - public int getLumMod() { - return getRawValue("lumMod"); - } - - public int getShade() { - return getRawValue("shade"); - } - - public int getTint() { - return getRawValue("tint"); - } - }; - } - - Color toColor(XmlObject obj, XSLFTheme theme) { - Color color = null; - for (XmlObject ch : obj.selectPath("*")) { - if (ch instanceof CTHslColor) { - CTHslColor hsl = (CTHslColor)ch; - int h = hsl.getHue2(); - int s = hsl.getSat2(); - int l = hsl.getLum2(); - color = DrawPaint.HSL2RGB(h / 60000d, s / 1000d, l / 1000d, 1d); - } else if (ch instanceof CTPresetColor) { - CTPresetColor prst = (CTPresetColor)ch; - String colorName = prst.getVal().toString(); - PresetColor pc = PresetColor.valueOfOoxmlId(colorName); - if (pc != null) { - color = pc.color; - } - } else if (ch instanceof CTSchemeColor) { - CTSchemeColor schemeColor = (CTSchemeColor)ch; - String colorRef = schemeColor.getVal().toString(); - if(_phClr != null) { - // context color overrides the theme - colorRef = _phClr.getVal().toString(); - } - // find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call - CTColor ctColor = theme.getCTColor(colorRef); - if(ctColor != null) color = toColor(ctColor, null); - } else if (ch instanceof CTScRgbColor) { - // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color - CTScRgbColor scrgb = (CTScRgbColor)ch; - color = new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB())); - } else if (ch instanceof CTSRgbColor) { - // color in sRGB color space, i.e. same as AWT Color - CTSRgbColor srgb = (CTSRgbColor)ch; - byte[] val = srgb.getVal(); - color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); - } else if (ch instanceof CTSystemColor) { - CTSystemColor sys = (CTSystemColor)ch; - if(sys.isSetLastClr()) { - byte[] val = sys.getLastClr(); - color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); - } else { - String colorName = sys.getVal().toString(); - PresetColor pc = PresetColor.valueOfOoxmlId(colorName); - if (pc != null) { - color = pc.color; - } - if (color == null) { - color = Color.black; - } - } - } else if (ch instanceof CTFontReference) { - // try next ... - continue; - } else { - throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass()); - } - } - return color; - } - - /** - * Sets the solid color - * - * @param color solid color - */ - @Internal - protected void setColor(Color color) { - if (!(_xmlObject instanceof CTSolidColorFillProperties)) { - LOGGER.log(POILogger.ERROR, "XSLFColor.setColor currently only supports CTSolidColorFillProperties"); - return; - } - CTSolidColorFillProperties fill = (CTSolidColorFillProperties)_xmlObject; - if (fill.isSetSrgbClr()) { - fill.unsetSrgbClr(); - } - - if (fill.isSetScrgbClr()) { - fill.unsetScrgbClr(); - } - - if (fill.isSetHslClr()) { - fill.unsetHslClr(); - } - - if (fill.isSetPrstClr()) { - fill.unsetPrstClr(); - } - - if (fill.isSetSchemeClr()) { - fill.unsetSchemeClr(); - } - - if (fill.isSetSysClr()) { - fill.unsetSysClr(); - } - - float[] rgbaf = color.getRGBComponents(null); - boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f); - CTPositiveFixedPercentage alphaPct; - - // see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32 - if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) { - // sRGB has a gamma of 2.2 - CTSRgbColor rgb = fill.addNewSrgbClr(); - - byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() }; - rgb.setVal(rgbBytes); - alphaPct = (addAlpha) ? rgb.addNewAlpha() : null; - } else { - CTScRgbColor rgb = fill.addNewScrgbClr(); - rgb.setR(DrawPaint.srgb2lin(rgbaf[0])); - rgb.setG(DrawPaint.srgb2lin(rgbaf[1])); - rgb.setB(DrawPaint.srgb2lin(rgbaf[2])); - alphaPct = (addAlpha) ? rgb.addNewAlpha() : null; - } - - // alpha (%) - if (alphaPct != null) { - alphaPct.setVal((int)(100000 * rgbaf[3])); - } - } - - /** - * @return true, if this is an integer color value - */ - private static boolean isInt(float f) { - return Math.abs((f*255f) - Math.rint(f*255f)) < 0.00001f; - } - - private int getRawValue(String elem) { - String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem; - - XmlObject[] obj; - - // first ask the context color and if not found, ask the actual color bean - if (_phClr != null){ - obj = _phClr.selectPath(query); - if (obj.length == 1){ - Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val"); - if(attr != null) { - return Integer.parseInt(attr.getNodeValue()); - } - } - } - - obj = _xmlObject.selectPath(query); - if (obj.length == 1){ - Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val"); - if(attr != null) { - return Integer.parseInt(attr.getNodeValue()); - } - } - - return -1; - } - - /** - * Read a perecentage value from the supplied xml bean. - * Example: - * - * - * the returned value is 45 - * - * @return the percentage value in the range [0 .. 100] - */ - private int getPercentageValue(String elem){ - int val = getRawValue(elem); - return (val == -1) ? val : (val / 1000); - } - - private int getAngleValue(String elem){ - int val = getRawValue(elem); - return (val == -1) ? val : (val / 60000); - } - - /** - * the opacity as expressed by a percentage value - * - * @return opacity in percents in the range [0..100] - * or -1 if the value is not set - */ - int getAlpha(){ - return getPercentageValue("alpha"); - } - - /** - * the opacity as expressed by a percentage relative to the input color - * - * @return opacity in percents in the range [0..100] - * or -1 if the value is not set - */ - int getAlphaMod(){ - return getPercentageValue("alphaMod"); - } - - /** - * the opacity as expressed by a percentage offset increase or decrease relative to - * the input color. Increases will never increase the opacity beyond 100%, decreases will - * never decrease the opacity below 0%. - * - * @return opacity shift in percents in the range [0..100] - * or -1 if the value is not set - */ - int getAlphaOff(){ - return getPercentageValue("alphaOff"); - } - - - int getHue(){ - return getAngleValue("hue"); - } - - int getHueMod(){ - return getPercentageValue("hueMod"); - } - - int getHueOff(){ - return getPercentageValue("hueOff"); - } - - /** - * specifies the input color with the specified luminance, - * but with its hue and saturation unchanged. - * - * @return luminance in percents in the range [0..100] - * or -1 if the value is not set - */ - int getLum(){ - return getPercentageValue("lum"); - } - - /** - * the luminance as expressed by a percentage relative to the input color - * - * @return luminance in percents in the range [0..100] - * or -1 if the value is not set - */ - int getLumMod(){ - return getPercentageValue("lumMod"); - } - - /** - * the luminance shift as expressed by a percentage relative to the input color - * - * @return luminance shift in percents in the range [0..100] - * or -1 if the value is not set - */ - int getLumOff(){ - return getPercentageValue("lumOff"); - } - - /** - * specifies the input color with the specified saturation, - * but with its hue and luminance unchanged. - * - * @return saturation in percents in the range [0..100] - * or -1 if the value is not set - */ - int getSat(){ - return getPercentageValue("sat"); - } - - /** - * the saturation as expressed by a percentage relative to the input color - * - * @return saturation in percents in the range [0..100] - * or -1 if the value is not set - */ - int getSatMod(){ - return getPercentageValue("satMod"); - } - - /** - * the saturation shift as expressed by a percentage relative to the input color - * - * @return saturation shift in percents in the range [0..100] - * or -1 if the value is not set - */ - int getSatOff(){ - return getPercentageValue("satOff"); - } - - /** - * specifies the input color with the specific red component, but with the blue and green color - * components unchanged - * - * @return the value of the red component specified as a - * percentage with 0% indicating minimal blue and 100% indicating maximum - * or -1 if the value is not set - */ - int getRed(){ - return getPercentageValue("red"); - } - - int getRedMod(){ - return getPercentageValue("redMod"); - } - - int getRedOff(){ - return getPercentageValue("redOff"); - } - - /** - * specifies the input color with the specific green component, but with the red and blue color - * components unchanged - * - * @return the value of the green component specified as a - * percentage with 0% indicating minimal blue and 100% indicating maximum - * or -1 if the value is not set - */ - int getGreen(){ - return getPercentageValue("green"); - } - - int getGreenMod(){ - return getPercentageValue("greenMod"); - } - - int getGreenOff(){ - return getPercentageValue("greenOff"); - } - - /** - * specifies the input color with the specific blue component, but with the red and green color - * components unchanged - * - * @return the value of the blue component specified as a - * percentage with 0% indicating minimal blue and 100% indicating maximum - * or -1 if the value is not set - */ - int getBlue(){ - return getPercentageValue("blue"); - } - - int getBlueMod(){ - return getPercentageValue("blueMod"); - } - - int getBlueOff(){ - return getPercentageValue("blueOff"); - } - - /** - * specifies a darker version of its input color. - * A 10% shade is 10% of the input color combined with 90% black. - * - * @return the value of the shade specified as a - * percentage with 0% indicating minimal shade and 100% indicating maximum - * or -1 if the value is not set - */ - public int getShade(){ - return getPercentageValue("shade"); - } - - /** - * specifies a lighter version of its input color. - * A 10% tint is 10% of the input color combined with 90% white. - * - * @return the value of the tint specified as a - * percentage with 0% indicating minimal tint and 100% indicating maximum - * or -1 if the value is not set - */ - public int getTint(){ - return getPercentageValue("tint"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java deleted file mode 100644 index 52aa0f6ff..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentAuthor; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentAuthorList; -import org.openxmlformats.schemas.presentationml.x2006.main.CmAuthorLstDocument; - -@Beta -public class XSLFCommentAuthors extends POIXMLDocumentPart { - private final CTCommentAuthorList _authors; - - /** - * Create a new set of slide comments - */ - XSLFCommentAuthors() { - super(); - CmAuthorLstDocument doc = CmAuthorLstDocument.Factory.newInstance(); - _authors = doc.addNewCmAuthorLst(); - } - - /** - * Construct a SpreadsheetML slide authors from a package part - * - * @param part the package part holding the comment authors data, - * the content type must be application/vnd.openxmlformats-officedocument.commentAuthors+xml - * - * @since POI 3.14-Beta1 - */ - XSLFCommentAuthors(PackagePart part) throws IOException, XmlException { - super(part); - CmAuthorLstDocument doc = - CmAuthorLstDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _authors = doc.getCmAuthorLst(); - } - - /** - * Construct a SpreadsheetML slide authors from a package part - * - * @param part the package part holding the comment authors data, - * the content type must be application/vnd.openxmlformats-officedocument.commentAuthors+xml - * @param rel the package relationship holding this comment authors, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - XSLFCommentAuthors(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - public CTCommentAuthorList getCTCommentAuthorsList() { - return _authors; - } - - public CTCommentAuthor getAuthorById(long id) { - // TODO Have a map - for (CTCommentAuthor author : _authors.getCmAuthorArray()) { - if (author.getId() == id) { - return author; - } - } - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java deleted file mode 100644 index c2e1c732f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTComment; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList; -import org.openxmlformats.schemas.presentationml.x2006.main.CmLstDocument; - -@Beta -public class XSLFComments extends POIXMLDocumentPart { - private final CTCommentList _comments; - - /** - * Create a new set of slide comments - */ - XSLFComments() { - super(); - CmLstDocument doc = CmLstDocument.Factory.newInstance(); - _comments = doc.addNewCmLst(); - } - - /** - * Construct a SpreadsheetML slide comments from a package part - * - * @param part the package part holding the comments data, - * the content type must be application/vnd.openxmlformats-officedocument.comments+xml - * - * @since POI 3.14-Beta1 - */ - XSLFComments(PackagePart part) throws IOException, XmlException { - super(part); - - CmLstDocument doc = - CmLstDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _comments = doc.getCmLst(); - } - - /** - * Construct a SpreadsheetML slide comments from a package part - * - * @param part the package part holding the comments data, - * the content type must be application/vnd.openxmlformats-officedocument.comments+xml - * @param rel the package relationship holding this comments, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments - * - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - XSLFComments(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - public CTCommentList getCTCommentsList() { - return _comments; - } - - public int getNumberOfComments() { - return _comments.sizeOfCmArray(); - } - - public CTComment getCommentAt(int pos) { - return _comments.getCmArray(pos); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java deleted file mode 100644 index 2fd336543..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.apache.poi.POIXMLException; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Removal; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTable; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; -import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; - -/* - * @deprecated POI 3.16 beta 1. - iterate over the shapes of a slide instead - */ -@Removal(version="3.18") -@Beta -public class XSLFCommonSlideData { - private final CTCommonSlideData data; - - public XSLFCommonSlideData(CTCommonSlideData data) { - this.data = data; - } - - public List getDrawingText() { - CTGroupShape gs = data.getSpTree(); - - List out = new ArrayList(); - - processShape(gs, out); - - for (CTGroupShape shape : gs.getGrpSpArray()) { - processShape(shape, out); - } - - for (CTGraphicalObjectFrame frame: gs.getGraphicFrameArray()) { - CTGraphicalObjectData data = frame.getGraphic().getGraphicData(); - XmlCursor c = data.newCursor(); - c.selectPath("declare namespace pic='"+CTTable.type.getName().getNamespaceURI()+"' .//pic:tbl"); - - while (c.toNextSelection()) { - XmlObject o = c.getObject(); - - if (o instanceof XmlAnyTypeImpl) { - // Pesky XmlBeans bug - see Bugzilla #49934 - try { - o = CTTable.Factory.parse(o.toString(), DEFAULT_XML_OPTIONS); - } catch (XmlException e) { - throw new POIXMLException(e); - } - } - - if (o instanceof CTTable) { - DrawingTable table = new DrawingTable((CTTable) o); - - for (DrawingTableRow row : table.getRows()) { - for (DrawingTableCell cell : row.getCells()) { - DrawingTextBody textBody = cell.getTextBody(); - out.add(textBody); - } - } - } - } - - c.dispose(); - } - - return out; - } - public List getText() { - List paragraphs = new ArrayList(); - for(DrawingTextBody textBody : getDrawingText()) { - paragraphs.addAll(Arrays.asList(textBody.getParagraphs())); - } - return paragraphs; - } - - private void processShape(CTGroupShape gs, List out) { - for (CTShape shape : gs.getSpArray()) { - CTTextBody ctTextBody = shape.getTxBody(); - if (ctTextBody==null) { - continue; - } - - DrawingTextBody textBody; - CTApplicationNonVisualDrawingProps nvpr = shape.getNvSpPr().getNvPr(); - if(nvpr.isSetPh()) { - textBody = new DrawingTextPlaceholder(ctTextBody, nvpr.getPh()); - } else { - textBody = new DrawingTextBody(ctTextBody); - } - - out.add(textBody); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java deleted file mode 100644 index 0ca895efa..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.POIXMLException; -import org.apache.poi.sl.usermodel.ConnectorShape; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.util.Beta; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; -import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual; - -/** - * Specifies a connection shape. - * - * @author Yegor Kozlov - */ -@Beta -public class XSLFConnectorShape extends XSLFSimpleShape - implements ConnectorShape { - - /*package*/ XSLFConnectorShape(CTConnector shape, XSLFSheet sheet) { - super(shape, sheet); - } - - /** - * @param shapeId 1-based shapeId - */ - static CTConnector prototype(int shapeId) { - CTConnector ct = CTConnector.Factory.newInstance(); - CTConnectorNonVisual nvSpPr = ct.addNewNvCxnSpPr(); - CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); - cnv.setName("Connector " + shapeId); - cnv.setId(shapeId + 1); - nvSpPr.addNewCNvCxnSpPr(); - nvSpPr.addNewNvPr(); - CTShapeProperties spPr = ct.addNewSpPr(); - CTPresetGeometry2D prst = spPr.addNewPrstGeom(); - prst.setPrst(STShapeType.LINE); - prst.addNewAvLst(); - /* CTLineProperties ln = */ spPr.addNewLn(); - return ct; - } - - - /** - * YK: shadows of lines are suppressed for now. - */ - @Override - public XSLFShadow getShadow() { - return null; - } - - @Override - public void setPlaceholder(Placeholder placeholder) { - throw new POIXMLException("A connector shape can't be a placeholder."); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java deleted file mode 100644 index ccf0c7b30..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java +++ /dev/null @@ -1,113 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; - - -/** - * @author Yegor Kozlov - */ -@Beta -public class XSLFDrawing { - private XSLFSheet _sheet; - private int _shapeId = 1; - private CTGroupShape _spTree; - - /*package*/ XSLFDrawing(XSLFSheet sheet, CTGroupShape spTree){ - _sheet = sheet; - _spTree = spTree; - XmlObject[] cNvPr = sheet.getSpTree().selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"); - for(XmlObject o : cNvPr) { - // powerpoint generates AlternateContent elements which cNvPr elements aren't recognized - // ignore them for now - if (o instanceof CTNonVisualDrawingProps) { - CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o; - _shapeId = (int)Math.max(_shapeId, p.getId()); - } - } - } - - public XSLFAutoShape createAutoShape(){ - CTShape sp = _spTree.addNewSp(); - sp.set(XSLFAutoShape.prototype(_shapeId++)); - XSLFAutoShape shape = new XSLFAutoShape(sp, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - return shape; - } - - public XSLFFreeformShape createFreeform(){ - CTShape sp = _spTree.addNewSp(); - sp.set(XSLFFreeformShape.prototype(_shapeId++)); - XSLFFreeformShape shape = new XSLFFreeformShape(sp, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - return shape; - } - - public XSLFTextBox createTextBox(){ - CTShape sp = _spTree.addNewSp(); - sp.set(XSLFTextBox.prototype(_shapeId++)); - XSLFTextBox shape = new XSLFTextBox(sp, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - return shape; - } - - public XSLFConnectorShape createConnector(){ - CTConnector sp = _spTree.addNewCxnSp(); - sp.set(XSLFConnectorShape.prototype(_shapeId++)); - XSLFConnectorShape shape = new XSLFConnectorShape(sp, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - shape.setLineColor(Color.black); - shape.setLineWidth(0.75); - return shape; - } - - public XSLFGroupShape createGroup(){ - CTGroupShape obj = _spTree.addNewGrpSp(); - obj.set(XSLFGroupShape.prototype(_shapeId++)); - XSLFGroupShape shape = new XSLFGroupShape(obj, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - return shape; - } - - public XSLFPictureShape createPicture(String rel){ - CTPicture obj = _spTree.addNewPic(); - obj.set(XSLFPictureShape.prototype(_shapeId++, rel)); - XSLFPictureShape shape = new XSLFPictureShape(obj, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - return shape; - } - - public XSLFTable createTable(){ - CTGraphicalObjectFrame obj = _spTree.addNewGraphicFrame(); - obj.set(XSLFTable.prototype(_shapeId++)); - XSLFTable shape = new XSLFTable(obj, _sheet); - shape.setAnchor(new Rectangle2D.Double()); - return shape; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java deleted file mode 100644 index 897ebaec6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLFactory; -import org.apache.poi.POIXMLRelation; - -/** - * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - */ -public final class XSLFFactory extends POIXMLFactory { - private XSLFFactory(){ - - } - - private static final XSLFFactory inst = new XSLFFactory(); - - public static XSLFFactory getInstance(){ - return inst; - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLRelation getDescriptor(String relationshipType) { - return XSLFRelation.getInstance(relationshipType); - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLDocumentPart createDocumentPart - (Class cls, Class[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Constructor constructor = cls.getDeclaredConstructor(classes); - return constructor.newInstance(values); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFontManager.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFontManager.java deleted file mode 100644 index cc5fc6c2d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFontManager.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -/** - * Manages fonts when rendering slides. - * - * Use this class to handle unknown / missing fonts or to substitute fonts - */ -public interface XSLFFontManager { - - /** - * select a font to be used to paint text - * - * @param typeface the font family as defined in the .pptx file. - * This can be unknown or missing in the graphic environment. - * - * @return the font to be used to paint text - */ - - String getRendererableFont(String typeface, int pitchFamily); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java deleted file mode 100644 index 3e482d3ea..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.sl.usermodel.FreeformShape; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Units; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomRect; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DClose; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DCubicBezierTo; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DLineTo; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DMoveTo; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DQuadBezierTo; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; - -/** - * Represents a custom geometric shape. - * This shape will consist of a series of lines and curves described within a creation path. - */ -@Beta -public class XSLFFreeformShape extends XSLFAutoShape - implements FreeformShape { - - /*package*/ XSLFFreeformShape(CTShape shape, XSLFSheet sheet) { - super(shape, sheet); - } - - @Override - public int setPath(Path2D.Double path) { - CTPath2D ctPath = CTPath2D.Factory.newInstance(); - - Rectangle2D bounds = path.getBounds2D(); - int x0 = Units.toEMU(bounds.getX()); - int y0 = Units.toEMU(bounds.getY()); - PathIterator it = path.getPathIterator(new AffineTransform()); - int numPoints = 0; - ctPath.setH(Units.toEMU(bounds.getHeight())); - ctPath.setW(Units.toEMU(bounds.getWidth())); - while (!it.isDone()) { - double[] vals = new double[6]; - int type = it.currentSegment(vals); - switch (type) { - case PathIterator.SEG_MOVETO: - CTAdjPoint2D mv = ctPath.addNewMoveTo().addNewPt(); - mv.setX(Units.toEMU(vals[0]) - x0); - mv.setY(Units.toEMU(vals[1]) - y0); - numPoints++; - break; - case PathIterator.SEG_LINETO: - CTAdjPoint2D ln = ctPath.addNewLnTo().addNewPt(); - ln.setX(Units.toEMU(vals[0]) - x0); - ln.setY(Units.toEMU(vals[1]) - y0); - numPoints++; - break; - case PathIterator.SEG_QUADTO: - CTPath2DQuadBezierTo qbez = ctPath.addNewQuadBezTo(); - CTAdjPoint2D qp1 = qbez.addNewPt(); - qp1.setX(Units.toEMU(vals[0]) - x0); - qp1.setY(Units.toEMU(vals[1]) - y0); - CTAdjPoint2D qp2 = qbez.addNewPt(); - qp2.setX(Units.toEMU(vals[2]) - x0); - qp2.setY(Units.toEMU(vals[3]) - y0); - numPoints += 2; - break; - case PathIterator.SEG_CUBICTO: - CTPath2DCubicBezierTo bez = ctPath.addNewCubicBezTo(); - CTAdjPoint2D p1 = bez.addNewPt(); - p1.setX(Units.toEMU(vals[0]) - x0); - p1.setY(Units.toEMU(vals[1]) - y0); - CTAdjPoint2D p2 = bez.addNewPt(); - p2.setX(Units.toEMU(vals[2]) - x0); - p2.setY(Units.toEMU(vals[3]) - y0); - CTAdjPoint2D p3 = bez.addNewPt(); - p3.setX(Units.toEMU(vals[4]) - x0); - p3.setY(Units.toEMU(vals[5]) - y0); - numPoints += 3; - break; - case PathIterator.SEG_CLOSE: - numPoints++; - ctPath.addNewClose(); - break; - default: - throw new IllegalStateException("Unrecognized path segment type: " + type); - } - it.next(); - } - - XmlObject xo = getShapeProperties(); - if (!(xo instanceof CTShapeProperties)) { - return -1; - } - - ((CTShapeProperties)xo).getCustGeom().getPathLst().setPathArray(new CTPath2D[]{ctPath}); - setAnchor(bounds); - return numPoints; - } - - @Override - public Path2D.Double getPath() { - Path2D.Double path = new Path2D.Double(); - Rectangle2D bounds = getAnchor(); - - XmlObject xo = getShapeProperties(); - if (!(xo instanceof CTShapeProperties)) { - return null; - } - - CTCustomGeometry2D geom = ((CTShapeProperties)xo).getCustGeom(); - for(CTPath2D spPath : geom.getPathLst().getPathArray()){ - double scaleW = bounds.getWidth() / Units.toPoints(spPath.getW()); - double scaleH = bounds.getHeight() / Units.toPoints(spPath.getH()); - for(XmlObject ch : spPath.selectPath("*")){ - if(ch instanceof CTPath2DMoveTo){ - CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt(); - path.moveTo( - (float) (Units.toPoints((Long) pt.getX()) * scaleW), - (float) (Units.toPoints((Long) pt.getY()) * scaleH)); - } else if (ch instanceof CTPath2DLineTo){ - CTAdjPoint2D pt = ((CTPath2DLineTo)ch).getPt(); - path.lineTo((float)Units.toPoints((Long)pt.getX()), - (float)Units.toPoints((Long)pt.getY())); - } else if (ch instanceof CTPath2DQuadBezierTo){ - CTPath2DQuadBezierTo bez = ((CTPath2DQuadBezierTo)ch); - CTAdjPoint2D pt1 = bez.getPtArray(0); - CTAdjPoint2D pt2 = bez.getPtArray(1); - path.quadTo( - (float) (Units.toPoints((Long) pt1.getX()) * scaleW), - (float) (Units.toPoints((Long) pt1.getY()) * scaleH), - (float) (Units.toPoints((Long) pt2.getX()) * scaleW), - (float) (Units.toPoints((Long) pt2.getY()) * scaleH)); - } else if (ch instanceof CTPath2DCubicBezierTo){ - CTPath2DCubicBezierTo bez = ((CTPath2DCubicBezierTo)ch); - CTAdjPoint2D pt1 = bez.getPtArray(0); - CTAdjPoint2D pt2 = bez.getPtArray(1); - CTAdjPoint2D pt3 = bez.getPtArray(2); - path.curveTo( - (float) (Units.toPoints((Long) pt1.getX()) * scaleW), - (float) (Units.toPoints((Long) pt1.getY()) * scaleH), - (float) (Units.toPoints((Long) pt2.getX()) * scaleW), - (float) (Units.toPoints((Long) pt2.getY()) * scaleH), - (float) (Units.toPoints((Long) pt3.getX()) * scaleW), - (float) (Units.toPoints((Long) pt3.getY()) * scaleH)); - } else if (ch instanceof CTPath2DClose){ - path.closePath(); - } - } - } - - // the created path starts at (x=0, y=0). - // The returned path should fit in the bounding rectangle - AffineTransform at = new AffineTransform(); - at.translate(bounds.getX(), bounds.getY()); - return new Path2D.Double(at.createTransformedShape(path)); - } - /** - * @param shapeId 1-based shapeId - */ - static CTShape prototype(int shapeId) { - CTShape ct = CTShape.Factory.newInstance(); - CTShapeNonVisual nvSpPr = ct.addNewNvSpPr(); - CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); - cnv.setName("Freeform " + shapeId); - cnv.setId(shapeId + 1); - nvSpPr.addNewCNvSpPr(); - nvSpPr.addNewNvPr(); - CTShapeProperties spPr = ct.addNewSpPr(); - CTCustomGeometry2D geom = spPr.addNewCustGeom(); - geom.addNewAvLst(); - geom.addNewGdLst(); - geom.addNewAhLst(); - geom.addNewCxnLst(); - CTGeomRect rect = geom.addNewRect(); - rect.setR("r"); - rect.setB("b"); - rect.setT("t"); - rect.setL("l"); - geom.addNewPathLst(); - return ct; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java deleted file mode 100644 index 1b5a9dcbd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.geom.Rectangle2D; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.GraphicalFrame; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.Beta; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; - -@Beta -public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame { - private static final POILogger LOG = POILogFactory.getLogger(XSLFGraphicFrame.class); - - /*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){ - super(shape,sheet); - } - - public ShapeType getShapeType(){ - throw new UnsupportedOperationException(); - } - - @Override - public Rectangle2D getAnchor(){ - CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm(); - CTPoint2D off = xfrm.getOff(); - double x = Units.toPoints(off.getX()); - double y = Units.toPoints(off.getY()); - CTPositiveSize2D ext = xfrm.getExt(); - double cx = Units.toPoints(ext.getCx()); - double cy = Units.toPoints(ext.getCy()); - return new Rectangle2D.Double(x, y, cx, cy); - } - - @Override - public void setAnchor(Rectangle2D anchor){ - CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm(); - CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); - long x = Units.toEMU(anchor.getX()); - long y = Units.toEMU(anchor.getY()); - off.setX(x); - off.setY(y); - CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm - .addNewExt(); - long cx = Units.toEMU(anchor.getWidth()); - long cy = Units.toEMU(anchor.getHeight()); - ext.setCx(cx); - ext.setCy(cy); - } - - - static XSLFGraphicFrame create(CTGraphicalObjectFrame shape, XSLFSheet sheet){ - String uri = shape.getGraphic().getGraphicData().getUri(); - if(XSLFTable.TABLE_URI.equals(uri)){ - return new XSLFTable(shape, sheet); - } else { - return new XSLFGraphicFrame(shape, sheet); - } - } - - /** - * Rotate this shape. - *

        - * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

        - * - * @param theta the rotation angle in degrees. - */ - public void setRotation(double theta){ - throw new IllegalArgumentException("Operation not supported"); - } - - /** - * Rotation angle in degrees - *

        - * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

        - * - * @return rotation angle in degrees - */ - public double getRotation(){ - return 0; - } - - public void setFlipHorizontal(boolean flip){ - throw new IllegalArgumentException("Operation not supported"); - } - - public void setFlipVertical(boolean flip){ - throw new IllegalArgumentException("Operation not supported"); - } - - /** - * Whether the shape is horizontally flipped - * - * @return whether the shape is horizontally flipped - */ - public boolean getFlipHorizontal(){ - return false; - } - - public boolean getFlipVertical(){ - return false; - } - - @Override - void copy(XSLFShape sh){ - super.copy(sh); - - CTGraphicalObjectData data = ((CTGraphicalObjectFrame)getXmlObject()).getGraphic().getGraphicData(); - String uri = data.getUri(); - if(uri.equals("http://schemas.openxmlformats.org/drawingml/2006/diagram")){ - copyDiagram(data, (XSLFGraphicFrame)sh); - } else { - // TODO support other types of objects - - } - } - - // TODO should be moved to a sub-class - private void copyDiagram(CTGraphicalObjectData objData, XSLFGraphicFrame srcShape){ - String xpath = "declare namespace dgm='http://schemas.openxmlformats.org/drawingml/2006/diagram' $this//dgm:relIds"; - XmlObject[] obj = objData.selectPath(xpath); - if(obj != null && obj.length == 1){ - XmlCursor c = obj[0].newCursor(); - - XSLFSheet sheet = srcShape.getSheet(); - try { - String dm = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "dm")); - PackageRelationship dmRel = sheet.getPackagePart().getRelationship(dm); - PackagePart dmPart = sheet.getPackagePart().getRelatedPart(dmRel); - getSheet().importPart(dmRel, dmPart); - - String lo = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "lo")); - PackageRelationship loRel = sheet.getPackagePart().getRelationship(lo); - PackagePart loPart = sheet.getPackagePart().getRelatedPart(loRel); - getSheet().importPart(loRel, loPart); - - String qs = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "qs")); - PackageRelationship qsRel = sheet.getPackagePart().getRelationship(qs); - PackagePart qsPart = sheet.getPackagePart().getRelatedPart(qsRel); - getSheet().importPart(qsRel, qsPart); - - String cs = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "cs")); - PackageRelationship csRel = sheet.getPackagePart().getRelationship(cs); - PackagePart csPart = sheet.getPackagePart().getRelatedPart(csRel); - getSheet().importPart(csRel, csPart); - - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } - c.dispose(); - } - } - - @Override - public XSLFPictureShape getFallbackPicture() { - String xquery = - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main'; " - + "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' " - + ".//mc:Fallback/*/p:pic" - ; - XmlObject xo = selectProperty(XmlObject.class, xquery); - if (xo == null) { - return null; - } - - CTGroupShape gs; - try { - gs = CTGroupShape.Factory.parse(xo.newDomNode()); - } catch (XmlException e) { - LOG.log(POILogger.WARN, "Can't parse fallback picture stream of graphical frame", e); - return null; - } - - if (gs.sizeOfPicArray() == 0) { - return null; - } - - return new XSLFPictureShape(gs.getPicArray(0), getSheet()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java deleted file mode 100644 index 08022e976..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.sl.draw.DrawPictureShape; -import org.apache.poi.sl.usermodel.GroupShape; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.util.Beta; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; - -/** - * Represents a group shape that consists of many shapes grouped together. - * - * @author Yegor Kozlov - */ -@Beta -public class XSLFGroupShape extends XSLFShape -implements XSLFShapeContainer, GroupShape { - private static POILogger _logger = POILogFactory.getLogger(XSLFGroupShape.class); - - private final List _shapes; - private final CTGroupShapeProperties _grpSpPr; - private XSLFDrawing _drawing; - - protected XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){ - super(shape,sheet); - _shapes = XSLFSheet.buildShapes(shape, sheet); - _grpSpPr = shape.getGrpSpPr(); - } - - protected CTGroupShapeProperties getGrpSpPr() { - return _grpSpPr; - } - - protected CTGroupTransform2D getSafeXfrm() { - CTGroupTransform2D xfrm = getXfrm(); - return (xfrm == null ? getGrpSpPr().addNewXfrm() : xfrm); - } - - protected CTGroupTransform2D getXfrm() { - return getGrpSpPr().getXfrm(); - } - - @Override - public Rectangle2D getAnchor(){ - CTGroupTransform2D xfrm = getXfrm(); - CTPoint2D off = xfrm.getOff(); - double x = Units.toPoints(off.getX()); - double y = Units.toPoints(off.getY()); - CTPositiveSize2D ext = xfrm.getExt(); - double cx = Units.toPoints(ext.getCx()); - double cy = Units.toPoints(ext.getCy()); - return new Rectangle2D.Double(x,y,cx,cy); - } - - @Override - public void setAnchor(Rectangle2D anchor){ - CTGroupTransform2D xfrm = getSafeXfrm(); - CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); - long x = Units.toEMU(anchor.getX()); - long y = Units.toEMU(anchor.getY()); - off.setX(x); - off.setY(y); - CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm.addNewExt(); - long cx = Units.toEMU(anchor.getWidth()); - long cy = Units.toEMU(anchor.getHeight()); - ext.setCx(cx); - ext.setCy(cy); - } - - /** - * - * @return the coordinates of the child extents rectangle - * used for calculations of grouping, scaling, and rotation - * behavior of shapes placed within a group. - */ - @Override - public Rectangle2D getInteriorAnchor(){ - CTGroupTransform2D xfrm = getXfrm(); - CTPoint2D off = xfrm.getChOff(); - double x = Units.toPoints(off.getX()); - double y = Units.toPoints(off.getY()); - CTPositiveSize2D ext = xfrm.getChExt(); - double cx = Units.toPoints(ext.getCx()); - double cy = Units.toPoints(ext.getCy()); - return new Rectangle2D.Double(x, y, cx, cy); - } - - /** - * - * @param anchor the coordinates of the child extents rectangle - * used for calculations of grouping, scaling, and rotation - * behavior of shapes placed within a group. - */ - @Override - public void setInteriorAnchor(Rectangle2D anchor) { - CTGroupTransform2D xfrm = getSafeXfrm(); - CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff(); - long x = Units.toEMU(anchor.getX()); - long y = Units.toEMU(anchor.getY()); - off.setX(x); - off.setY(y); - CTPositiveSize2D ext = xfrm.isSetChExt() ? xfrm.getChExt() : xfrm.addNewChExt(); - long cx = Units.toEMU(anchor.getWidth()); - long cy = Units.toEMU(anchor.getHeight()); - ext.setCx(cx); - ext.setCy(cy); - } - - /** - * @return child shapes contained within this group - */ - @Override - public List getShapes(){ - return _shapes; - } - - /** - * Returns an iterator over the shapes in this sheet - * - * @return an iterator over the shapes in this sheet - */ - public Iterator iterator(){ - return _shapes.iterator(); - } - - /** - * Remove the specified shape from this group - */ - public boolean removeShape(XSLFShape xShape) { - XmlObject obj = xShape.getXmlObject(); - CTGroupShape grpSp = (CTGroupShape)getXmlObject(); - if(obj instanceof CTShape){ - grpSp.getSpList().remove(obj); - } else if (obj instanceof CTGroupShape){ - grpSp.getGrpSpList().remove(obj); - } else if (obj instanceof CTConnector){ - grpSp.getCxnSpList().remove(obj); - } else if (obj instanceof CTGraphicalObjectFrame) { - grpSp.getGraphicFrameList().remove(obj); - } else if (obj instanceof CTPicture) { - XSLFPictureShape ps = (XSLFPictureShape)xShape; - XSLFSheet sh = getSheet(); - if (sh != null) { - sh.removePictureRelation(ps); - } - grpSp.getPicList().remove(obj); - } else { - throw new IllegalArgumentException("Unsupported shape: " + xShape); - } - return _shapes.remove(xShape); - } - - /** - * @param shapeId 1-based shapeId - */ - static CTGroupShape prototype(int shapeId) { - CTGroupShape ct = CTGroupShape.Factory.newInstance(); - CTGroupShapeNonVisual nvSpPr = ct.addNewNvGrpSpPr(); - CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); - cnv.setName("Group " + shapeId); - cnv.setId(shapeId + 1); - - nvSpPr.addNewCNvGrpSpPr(); - nvSpPr.addNewNvPr(); - ct.addNewGrpSpPr(); - return ct; - } - - // shape factory methods - private XSLFDrawing getDrawing(){ - if(_drawing == null) { - _drawing = new XSLFDrawing(getSheet(), (CTGroupShape)getXmlObject()); - } - return _drawing; - } - - public XSLFAutoShape createAutoShape(){ - XSLFAutoShape sh = getDrawing().createAutoShape(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - public XSLFFreeformShape createFreeform(){ - XSLFFreeformShape sh = getDrawing().createFreeform(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - public XSLFTextBox createTextBox(){ - XSLFTextBox sh = getDrawing().createTextBox(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - public XSLFConnectorShape createConnector(){ - XSLFConnectorShape sh = getDrawing().createConnector(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - public XSLFGroupShape createGroup(){ - XSLFGroupShape sh = getDrawing().createGroup(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - public XSLFPictureShape createPicture(PictureData pictureData){ - if (!(pictureData instanceof XSLFPictureData)) { - throw new IllegalArgumentException("pictureData needs to be of type XSLFPictureData"); - } - XSLFPictureData xPictureData = (XSLFPictureData)pictureData; - PackagePart pic = xPictureData.getPackagePart(); - - PackageRelationship rel = getSheet().getPackagePart().addRelationship( - pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation()); - - XSLFPictureShape sh = getDrawing().createPicture(rel.getId()); - new DrawPictureShape(sh).resize(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - public XSLFTable createTable(){ - XSLFTable sh = getDrawing().createTable(); - _shapes.add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFTable createTable(int numRows, int numCols){ - if (numRows < 1 || numCols < 1) { - throw new IllegalArgumentException("numRows and numCols must be greater than 0"); - } - XSLFTable sh = getDrawing().createTable(); - _shapes.add(sh); - sh.setParent(this); - for (int r=0; r shapes = new ArrayList(getShapes()); - for(XSLFShape shape : shapes){ - removeShape(shape); - } - } - - public void addShape(XSLFShape shape) { - throw new UnsupportedOperationException( - "Adding a shape from a different container is not supported -" - + " create it from scratch with XSLFGroupShape.create* methods"); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java deleted file mode 100644 index 2f300623f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import java.net.URI; - -import org.apache.poi.common.usermodel.HyperlinkType; -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.TargetMode; -import org.apache.poi.sl.usermodel.Hyperlink; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink; - -public class XSLFHyperlink implements Hyperlink { - final XSLFSheet _sheet; - final CTHyperlink _link; - - XSLFHyperlink(CTHyperlink link, XSLFSheet sheet){ - _sheet = sheet; - _link = link; - } - - @Internal - public CTHyperlink getXmlObject(){ - return _link; - } - - @Override - public void setAddress(String address) { - linkToUrl(address); - } - - @Override - public String getAddress() { - String id = _link.getId(); - if (id == null || "".equals(id)) { - return _link.getAction(); - } - - URI targetURI = _sheet.getPackagePart().getRelationship(id).getTargetURI(); - - return targetURI.toASCIIString(); - } - - @Override - public String getLabel() { - return _link.getTooltip(); - } - - @Override - public void setLabel(String label) { - _link.setTooltip(label); - } - - /* (non-Javadoc) - * @deprecated POI 3.15. Use {@link #getTypeEnum()} instead. - * Will return a HyperlinkType enum in the future - */ - @Override - public int getType() { - return getTypeEnum().getCode(); - } - - @Override - public HyperlinkType getTypeEnum() { - String action = _link.getAction(); - if (action == null) { - action = ""; - } - if (action.equals("ppaction://hlinksldjump") || action.startsWith("ppaction://hlinkshowjump")) { - return HyperlinkType.DOCUMENT; - } - - String address = getAddress(); - if (address == null) { - address = ""; - } - if (address.startsWith("mailto:")) { - return HyperlinkType.EMAIL; - } else { - return HyperlinkType.URL; - } - } - - @Override - public void linkToEmail(String emailAddress) { - linkToExternal("mailto:"+emailAddress); - setLabel(emailAddress); - } - - @Override - public void linkToUrl(String url) { - linkToExternal(url); - setLabel(url); - } - - private void linkToExternal(String url) { - PackagePart thisPP = _sheet.getPackagePart(); - if (_link.isSetId() && !_link.getId().isEmpty()) { - thisPP.removeRelationship(_link.getId()); - } - PackageRelationship rel = thisPP.addExternalRelationship(url, XSLFRelation.HYPERLINK.getRelation()); - _link.setId(rel.getId()); - if (_link.isSetAction()) { - _link.unsetAction(); - } - } - - @Override - public void linkToSlide(Slide slide) { - PackagePart thisPP = _sheet.getPackagePart(); - PackagePartName otherPPN = ((XSLFSheet)slide).getPackagePart().getPartName(); - if (_link.isSetId() && !_link.getId().isEmpty()) { - thisPP.removeRelationship(_link.getId()); - } - PackageRelationship rel = - thisPP.addRelationship(otherPPN, TargetMode.INTERNAL, XSLFRelation.SLIDE.getRelation()); - _link.setId(rel.getId()); - _link.setAction("ppaction://hlinksldjump"); - } - - @Override - public void linkToNextSlide() { - linkToRelativeSlide("nextslide"); - } - - @Override - public void linkToPreviousSlide() { - linkToRelativeSlide("previousslide"); - } - - @Override - public void linkToFirstSlide() { - linkToRelativeSlide("firstslide"); - } - - @Override - public void linkToLastSlide() { - linkToRelativeSlide("lastslide"); - } - - private void linkToRelativeSlide(String jump) { - PackagePart thisPP = _sheet.getPackagePart(); - if (_link.isSetId() && !_link.getId().isEmpty()) { - thisPP.removeRelationship(_link.getId()); - } - _link.setId(""); - _link.setAction("ppaction://hlinkshowjump?jump="+jump); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java deleted file mode 100644 index 7153bc86a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; - -import javax.imageio.ImageIO; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.util.Beta; - -/** - * For now this class renders only images supported by the javax.imageio.ImageIO - * framework. Subclasses can override this class to support other formats, for - * example, Use Apache batik to render WMF: - * - *
        - * 
        - * public class MyImageRendener extends XSLFImageRendener{
        - * public boolean drawImage(Graphics2D graphics, XSLFPictureData data, Rectangle2D anchor){
        - * 	boolean ok = super.drawImage(graphics, data, anchor);
        - * 	if(!ok){
        - * 		// see what type of image we are
        - * 		String contentType = data.getPackagePart().getContentType();
        - * 		if(contentType.equals("image/wmf")){
        - * 			// use Apache Batik to handle WMF
        - * 			// see http://xmlgraphics.apache.org/batik/
        - * 		}
        - * 		
        - * 	}
        - * 	return ok;
        - * }
        - * }
        - * 
        - * 
        - * - * and then pass this class to your instance of java.awt.Graphics2D: - * - *
        - * 
        - * graphics.setRenderingHint(XSLFRenderingHint.IMAGE_RENDERER, new MyImageRendener());
        - * 
        - * 
        - * - * @author Yegor Kozlov - */ -@Beta -public class XSLFImageRenderer { - - /** - * Render picture data into the supplied graphics - * - * @return true if the picture data was successfully rendered - */ - public boolean drawImage(Graphics2D graphics, XSLFPictureData data, - Rectangle2D anchor) { - return drawImage(graphics, data, anchor, null); - } - - /** - * Render picture data into the supplied graphics - * - * @return true if the picture data was successfully rendered - */ - public boolean drawImage(Graphics2D graphics, XSLFPictureData data, - Rectangle2D anchor, Insets clip) { - boolean isClipped = true; - if (clip == null) { - isClipped = false; - clip = new Insets(0,0,0,0); - } - - BufferedImage img; - try { - img = ImageIO.read(data.getPackagePart().getInputStream()); - } catch (Exception e) { - return false; - } - - if(img == null) { - return false; - } - - int iw = img.getWidth(); - int ih = img.getHeight(); - - double cw = (100000-clip.left-clip.right) / 100000.0; - double ch = (100000-clip.top-clip.bottom) / 100000.0; - double sx = anchor.getWidth()/(iw*cw); - double sy = anchor.getHeight()/(ih*ch); - double tx = anchor.getX()-(iw*sx*clip.left/100000.0); - double ty = anchor.getY()-(ih*sy*clip.top/100000.0); - AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ; - - Shape clipOld = graphics.getClip(); - if (isClipped) graphics.clip(anchor.getBounds2D()); - graphics.drawRenderedImage(img, at); - graphics.setClip(clipOld); - - return true; - } - - /** - * Create a buffered image from the supplied package part. - * This method is called to create texture paints. - * - * @return a BufferedImage containing the decoded - * contents of the input, or null. - */ - public BufferedImage readImage(PackagePart packagePart) throws IOException { - return ImageIO.read(packagePart.getInputStream()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java deleted file mode 100644 index bdbc461f4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; - -class XSLFLineBreak extends XSLFTextRun { - private final CTTextCharacterProperties _brProps; - - XSLFLineBreak(CTRegularTextRun r, XSLFTextParagraph p, CTTextCharacterProperties brProps){ - super(r, p); - _brProps = brProps; - } - - @Override - protected CTTextCharacterProperties getRPr(boolean create){ - return _brProps; - } - - public void setText(String text){ - throw new IllegalStateException("You cannot change text of a line break, it is always '\\n'"); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFMetroShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFMetroShape.java deleted file mode 100644 index 652cedcb5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFMetroShape.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; - -/** - * Experimental class for metro blobs, i.e. an alternative escher property - * containing an ooxml representation of the shape. - * This is the helper class for HSLFMetroShape to dive into OOXML classes - */ -@Internal -public class XSLFMetroShape { - /* - * parses the metro bytes to a XSLF shape - */ - public static Shape parseShape(byte metroBytes[]) - throws InvalidFormatException, IOException, XmlException { - PackagePartName shapePN = PackagingURIHelper.createPartName("/drs/shapexml.xml"); - OPCPackage pkg = null; - try { - pkg = OPCPackage.open(new ByteArrayInputStream(metroBytes)); - PackagePart shapePart = pkg.getPart(shapePN); - CTGroupShape gs = CTGroupShape.Factory.parse(shapePart.getInputStream(), DEFAULT_XML_OPTIONS); - XSLFGroupShape xgs = new XSLFGroupShape(gs, null); - return xgs.getShapes().get(0); - } finally { - if (pkg != null) { - pkg.close(); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java deleted file mode 100644 index 5c0ec58d2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java +++ /dev/null @@ -1,120 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.Notes; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData; -import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide; -import org.openxmlformats.schemas.presentationml.x2006.main.NotesDocument; - -@Beta -public final class XSLFNotes extends XSLFSheet -implements Notes { - private CTNotesSlide _notes; - - /** - * Create a new notes - */ - XSLFNotes() { - super(); - _notes = prototype(); - setCommonSlideData(_notes.getCSld()); - } - - /** - * Construct a SpreadsheetML notes from a package part - * - * @param part the package part holding the notes data, - * the content type must be application/vnd.openxmlformats-officedocument.notes+xml - * @param rel the package relationship holding this notes, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/notes - * - * @since POI 3.14-Beta1 - */ - XSLFNotes(PackagePart part) throws IOException, XmlException { - super(part); - - NotesDocument doc = - NotesDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _notes = doc.getNotes(); - setCommonSlideData(_notes.getCSld()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - XSLFNotes(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - private static CTNotesSlide prototype(){ - CTNotesSlide ctNotes = CTNotesSlide.Factory.newInstance(); - CTCommonSlideData cSld = ctNotes.addNewCSld(); - cSld.addNewSpTree(); - - return ctNotes; - } - - @Override - public CTNotesSlide getXmlObject() { - return _notes; - } - - @Override - protected String getRootElementName(){ - return "notes"; - } - - @Override - public XSLFTheme getTheme(){ - return getMasterSheet().getTheme(); - } - - @Override - public XSLFNotesMaster getMasterSheet() { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFNotesMaster){ - return (XSLFNotesMaster)p; - } - } - return null; - } - - @Override - public List> getTextParagraphs() { - List> tp = new ArrayList>(); - for (XSLFShape sh : super.getShapes()) { - if (sh instanceof XSLFTextShape) { - XSLFTextShape txt = (XSLFTextShape)sh; - tp.add(txt.getTextParagraphs()); - } - } - return tp; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java deleted file mode 100644 index 6f955a45e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java +++ /dev/null @@ -1,131 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping; -import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMaster; -import org.openxmlformats.schemas.presentationml.x2006.main.NotesMasterDocument; - -/** -* Notes master object associated with this layout. -*

        -* Within a notes master slide are contained all elements -* that describe the objects and their corresponding formatting -* for within a presentation slide. -*

        -*

        -* Within a nodes master slide are two main elements. -* The cSld element specifies the common slide elements such as shapes and -* their attached text bodies. Then the notesStyles element specifies the -* formatting for the text within each of these shapes. -*

        - * - * @author Yegor Kozlov -*/ -@Beta - public class XSLFNotesMaster extends XSLFSheet - implements MasterSheet { - private CTNotesMaster _slide; - private XSLFTheme _theme; - - XSLFNotesMaster() { - super(); - _slide = prototype(); - } - - /** - * @since POI 3.14-Beta1 - */ - protected XSLFNotesMaster(PackagePart part) throws IOException, XmlException { - super(part); - NotesMasterDocument doc = - NotesMasterDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _slide = doc.getNotesMaster(); - setCommonSlideData(_slide.getCSld()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSLFNotesMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - private static CTNotesMaster prototype() { - InputStream is = XSLFNotesMaster.class.getResourceAsStream("notesMaster.xml"); - if (is == null) { - throw new POIXMLException("Missing resource 'notesMaster.xml'"); - } - - try { - try { - NotesMasterDocument doc = NotesMasterDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - CTNotesMaster slide = doc.getNotesMaster(); - return slide; - } finally { - is.close(); - } - } catch (Exception e) { - throw new POIXMLException("Can't initialize NotesMaster", e); - } - } - - @Override - public CTNotesMaster getXmlObject() { - return _slide; - } - - @Override - protected String getRootElementName(){ - return "notesMaster"; - } - - @Override - public MasterSheet getMasterSheet() { - return null; - } - - @Override - public XSLFTheme getTheme() { - if (_theme == null) { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFTheme) { - _theme = (XSLFTheme) p; - CTColorMapping cmap = _slide.getClrMap(); - if (cmap != null) { - _theme.initColorMap(cmap); - } - break; - } - } - } - return _theme; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java deleted file mode 100644 index 9f705e0e0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Dimension; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.imageio.ImageIO; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.hslf.blip.EMF; -import org.apache.poi.hslf.blip.PICT; -import org.apache.poi.hslf.blip.WMF; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.util.Beta; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - */ -@Beta -public final class XSLFPictureData extends POIXMLDocumentPart implements PictureData { - private static final POILogger logger = POILogFactory.getLogger(XSLFPictureData.class); - - private Long checksum = null; - - // original image dimensions (for formats supported by BufferedImage) - private Dimension origSize = null; - private int index = -1; - - /** - * Create a new XSLFGraphicData node - */ - protected XSLFPictureData() { - super(); - } - - /** - * Construct XSLFPictureData from a package part - * - * @param part the package part holding the drawing data - * - * @since POI 3.14-Beta1 - */ - public XSLFPictureData(PackagePart part) { - super(part); - } - - /** - * Construct XSLFPictureData from a package part - * - * @param part the package part holding the drawing data, - * @param rel the package relationship holding this drawing, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSLFPictureData(PackagePart part, PackageRelationship rel) { - this(part); - } - - /** - * An InputStream to read the picture data directly - * from the underlying package part - * - * @return InputStream - */ - public InputStream getInputStream() throws IOException { - return getPackagePart().getInputStream(); - } - - /** - * Gets the picture data as a byte array. - * - * You can grab the picture data directly from the underlying package part with the {@link #getInputStream()} method - * - * @return the Picture data. - */ - public byte[] getData() { - try { - return IOUtils.toByteArray(getInputStream()); - } catch (IOException e) { - throw new POIXMLException(e); - } - } - - /** - * Returns the file name of the image, eg image7.jpg . The original filename - * isn't always available, but if it can be found it's likely to be in the - * CTDrawing - */ - public String getFileName() { - String name = getPackagePart().getPartName().getName(); - return name.substring(name.lastIndexOf('/') + 1); - } - - /** - * Suggests a file extension for this image. - * - * @return the file extension. - */ - public String suggestFileExtension() { - return getPackagePart().getPartName().getExtension(); - } - - @Override - public byte[] getChecksum() { - cacheProperties(); - byte cs[] = new byte[LittleEndianConsts.LONG_SIZE]; - LittleEndian.putLong(cs,0,checksum); - return cs; - } - - @Override - public Dimension getImageDimension() { - cacheProperties(); - return origSize; - } - - @Override - public Dimension getImageDimensionInPixels() { - Dimension dim = getImageDimension(); - return new Dimension( - Units.pointsToPixel(dim.getWidth()), - Units.pointsToPixel(dim.getHeight()) - ); - } - - /** - * Determine and cache image properties - */ - protected void cacheProperties() { - if (origSize == null || checksum == null) { - byte data[] = getData(); - checksum = IOUtils.calculateChecksum(data); - - PictureType pt = getType(); - if (pt == null) { - origSize = new Dimension(1,1); - return; - } - - switch (pt) { - case EMF: - origSize = new EMF.NativeHeader(data, 0).getSize(); - break; - case WMF: - // wmf files in pptx usually have their placeable header - // stripped away, so this returns only the dummy size - origSize = new WMF.NativeHeader(data, 0).getSize(); - break; - case PICT: - origSize = new PICT.NativeHeader(data, 0).getSize(); - break; - default: - BufferedImage img = null; - try { - img = ImageIO.read(new ByteArrayInputStream(data)); - } catch (IOException e) { - logger.log(POILogger.WARN, "Can't determine image dimensions", e); - } - // set dummy size, in case of dummy dimension can't be set - origSize = (img == null) - ? new Dimension(200,200) - : new Dimension( - (int)Units.pixelToPoints(img.getWidth()), - (int)Units.pixelToPoints(img.getHeight()) - ); - break; - } - } - } - - /** - * *PictureData objects store the actual content in the part directly without keeping a - * copy like all others therefore we need to handle them differently. - */ - @Override - protected void prepareForCommit() { - // do not clear the part here - } - - @Override - public String getContentType() { - return getPackagePart().getContentType(); - } - - public void setData(byte[] data) throws IOException { - OutputStream os = getPackagePart().getOutputStream(); - os.write(data); - os.close(); - // recalculate now since we already have the data bytes available anyhow - checksum = IOUtils.calculateChecksum(data); - - origSize = null; // need to recalculate image size - } - - @Override - public PictureType getType() { - String ct = getContentType(); - if (XSLFRelation.IMAGE_EMF.getContentType().equals(ct)) { - return PictureType.EMF; - } else if (XSLFRelation.IMAGE_WMF.getContentType().equals(ct)) { - return PictureType.WMF; - } else if (XSLFRelation.IMAGE_PICT.getContentType().equals(ct)) { - return PictureType.PICT; - } else if (XSLFRelation.IMAGE_JPEG.getContentType().equals(ct)) { - return PictureType.JPEG; - } else if (XSLFRelation.IMAGE_PNG.getContentType().equals(ct)) { - return PictureType.PNG; - } else if (XSLFRelation.IMAGE_DIB.getContentType().equals(ct)) { - return PictureType.DIB; - } else if (XSLFRelation.IMAGE_GIF.getContentType().equals(ct)) { - return PictureType.GIF; - } else if (XSLFRelation.IMAGE_EPS.getContentType().equals(ct)) { - return PictureType.EPS; - } else if (XSLFRelation.IMAGE_BMP.getContentType().equals(ct)) { - return PictureType.BMP; - } else if (XSLFRelation.IMAGE_WPG.getContentType().equals(ct)) { - return PictureType.WPG; - } else if (XSLFRelation.IMAGE_WDP.getContentType().equals(ct)) { - return PictureType.WDP; - } else if (XSLFRelation.IMAGE_TIFF.getContentType().equals(ct)) { - return PictureType.TIFF; - } else { - return null; - } - } - - /* package */ static XSLFRelation getRelationForType(PictureType pt) { - switch (pt) { - case EMF: return XSLFRelation.IMAGE_EMF; - case WMF: return XSLFRelation.IMAGE_WMF; - case PICT: return XSLFRelation.IMAGE_PICT; - case JPEG: return XSLFRelation.IMAGE_JPEG; - case PNG: return XSLFRelation.IMAGE_PNG; - case DIB: return XSLFRelation.IMAGE_DIB; - case GIF: return XSLFRelation.IMAGE_GIF; - case EPS: return XSLFRelation.IMAGE_EPS; - case BMP: return XSLFRelation.IMAGE_BMP; - case WPG: return XSLFRelation.IMAGE_WPG; - case WDP: return XSLFRelation.IMAGE_WDP; - case TIFF: return XSLFRelation.IMAGE_TIFF; - default: return null; - } - } - - /** - * @return the 0-based index of this pictures within the picture parts - */ - public int getIndex() { - return index; - } - - /** - * @param index sets the 0-based index of this pictures within the picture parts - */ - public void setIndex(int index) { - this.index = index; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java deleted file mode 100644 index c2428bc2e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Insets; -import java.net.URI; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.PictureShape; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtension; -import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtensionList; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTRelativeRect; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual; - -/** - * Represents a picture shape - */ -@Beta -public class XSLFPictureShape extends XSLFSimpleShape - implements PictureShape { - private XSLFPictureData _data; - - /*package*/ XSLFPictureShape(CTPicture shape, XSLFSheet sheet) { - super(shape, sheet); - } - - - /** - * @param shapeId 1-based shapeId - * @param rel relationship to the picture data in the ooxml package - */ - static CTPicture prototype(int shapeId, String rel) { - CTPicture ct = CTPicture.Factory.newInstance(); - CTPictureNonVisual nvSpPr = ct.addNewNvPicPr(); - CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); - cnv.setName("Picture " + shapeId); - cnv.setId(shapeId + 1); - nvSpPr.addNewCNvPicPr().addNewPicLocks().setNoChangeAspect(true); - nvSpPr.addNewNvPr(); - - CTBlipFillProperties blipFill = ct.addNewBlipFill(); - CTBlip blip = blipFill.addNewBlip(); - blip.setEmbed(rel); - blipFill.addNewStretch().addNewFillRect(); - - CTShapeProperties spPr = ct.addNewSpPr(); - CTPresetGeometry2D prst = spPr.addNewPrstGeom(); - prst.setPrst(STShapeType.RECT); - prst.addNewAvLst(); - return ct; - } - - - /** - * Is this an internal picture (image data included within - * the PowerPoint file), or an external linked picture - * (image lives outside)? - */ - public boolean isExternalLinkedPicture() { - if (getBlipId() == null && getBlipLink() != null) { - return true; - } - return false; - } - - /** - * Return the data on the (internal) picture. - * For an external linked picture, will return null - */ - public XSLFPictureData getPictureData() { - if(_data == null){ - String blipId = getBlipId(); - if (blipId == null) return null; - - PackagePart p = getSheet().getPackagePart(); - PackageRelationship rel = p.getRelationship(blipId); - if (rel != null) { - try { - PackagePart imgPart = p.getRelatedPart(rel); - _data = new XSLFPictureData(imgPart); - } - catch (Exception e) { - throw new POIXMLException(e); - } - } - } - return _data; - } - - @Override - public void setPlaceholder(Placeholder placeholder) { - super.setPlaceholder(placeholder); - } - - - /** - * For an external linked picture, return the last-seen - * path to the picture. - * For an internal picture, returns null. - */ - public URI getPictureLink() { - if (getBlipId() != null) { - // Internal picture, nothing to return - return null; - } - - String rId = getBlipLink(); - if (rId == null) { - // No link recorded, nothing we can do - return null; - } - - PackagePart p = getSheet().getPackagePart(); - PackageRelationship rel = p.getRelationship(rId); - if (rel != null) { - return rel.getTargetURI(); - } - return null; - } - - protected CTBlipFillProperties getBlipFill() { - CTPicture ct = (CTPicture)getXmlObject(); - CTBlipFillProperties bfp = ct.getBlipFill(); - if (bfp != null) { - return bfp; - } - - String xquery = - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main'; " - + "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' " - + ".//mc:Fallback/p:blipFill" - ; - XmlObject xo = selectProperty(XmlObject.class, xquery); - try { - xo = CTPicture.Factory.parse(xo.getDomNode()); - } catch (XmlException xe) { - return null; - } - return ((CTPicture)xo).getBlipFill(); - } - - protected CTBlip getBlip(){ - return getBlipFill().getBlip(); - } - - protected String getBlipLink(){ - String link = getBlip().getLink(); - if (link.isEmpty()) return null; - return link; - } - - protected String getBlipId(){ - String id = getBlip().getEmbed(); - if (id.isEmpty()) return null; - return id; - } - - @Override - public Insets getClipping(){ - CTRelativeRect r = getBlipFill().getSrcRect(); - return (r == null) ? null : new Insets(r.getT(), r.getL(), r.getB(), r.getR()); - } - - @Override - void copy(XSLFShape sh){ - super.copy(sh); - - XSLFPictureShape p = (XSLFPictureShape)sh; - String blipId = p.getBlipId(); - String relId = getSheet().importBlip(blipId, p.getSheet().getPackagePart()); - - CTPicture ct = (CTPicture)getXmlObject(); - CTBlip blip = getBlipFill().getBlip(); - blip.setEmbed(relId); - - CTApplicationNonVisualDrawingProps nvPr = ct.getNvPicPr().getNvPr(); - if(nvPr.isSetCustDataLst()) { - // discard any custom tags associated with the picture being copied - nvPr.unsetCustDataLst(); - } - if(blip.isSetExtLst()) { - - CTOfficeArtExtensionList extLst = blip.getExtLst(); - for(CTOfficeArtExtension ext : extLst.getExtArray()){ - String xpath = "declare namespace a14='http://schemas.microsoft.com/office/drawing/2010/main' $this//a14:imgProps/a14:imgLayer"; - XmlObject[] obj = ext.selectPath(xpath); - if(obj != null && obj.length == 1){ - XmlCursor c = obj[0].newCursor(); - String id = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "embed"));//selectPath("declare namespace r='http://schemas.openxmlformats.org/officeDocument/2006/relationships' $this//[@embed]"); - String newId = getSheet().importBlip(id, p.getSheet().getPackagePart()); - c.setAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "embed"), newId); - c.dispose(); - } - } - } - - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java deleted file mode 100644 index f6e5ad0a9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java +++ /dev/null @@ -1,1830 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectContainer; -import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectList; -import org.openxmlformats.schemas.drawingml.x2006.main.CTFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPatternFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; - -/** - * Internal helper class to unify property access. - * - * This class is experimental and not (yet) supposed for public usage. - * Maybe the xml schemas might be enhanced with interfaces to make this class superfluous - * - * @since POI 3.15-beta2 - */ -@Internal -/* package */ class XSLFPropertiesDelegate { - private static final POILogger LOG = POILogFactory.getLogger(XSLFPropertiesDelegate.class); - - - public static XSLFFillProperties getFillDelegate(XmlObject props) { - return getDelegate(XSLFFillProperties.class, props); - } - - public static XSLFGeometryProperties getGeometryDelegate(XmlObject props) { - return getDelegate(XSLFGeometryProperties.class, props); - } - - public static XSLFEffectProperties getEffectDelegate(XmlObject props) { - return getDelegate(XSLFEffectProperties.class, props); - } - - public interface XSLFFillProperties { - /** - * Gets the "noFill" element - */ - CTNoFillProperties getNoFill(); - - /** - * True if has "noFill" element - */ - boolean isSetNoFill(); - - /** - * Sets the "noFill" element - */ - void setNoFill(CTNoFillProperties noFill); - - /** - * Appends and returns a new empty "noFill" element - */ - CTNoFillProperties addNewNoFill(); - - /** - * Unsets the "noFill" element - */ - void unsetNoFill(); - - /** - * Gets the "solidFill" element - */ - CTSolidColorFillProperties getSolidFill(); - - /** - * True if has "solidFill" element - */ - boolean isSetSolidFill(); - - /** - * Sets the "solidFill" element - */ - void setSolidFill(CTSolidColorFillProperties solidFill); - - /** - * Appends and returns a new empty "solidFill" element - */ - CTSolidColorFillProperties addNewSolidFill(); - - /** - * Unsets the "solidFill" element - */ - void unsetSolidFill(); - - /** - * Gets the "gradFill" element - */ - CTGradientFillProperties getGradFill(); - - /** - * True if has "gradFill" element - */ - boolean isSetGradFill(); - - /** - * Sets the "gradFill" element - */ - void setGradFill(CTGradientFillProperties gradFill); - - /** - * Appends and returns a new empty "gradFill" element - */ - CTGradientFillProperties addNewGradFill(); - - /** - * Unsets the "gradFill" element - */ - void unsetGradFill(); - - /** - * Gets the "blipFill" element - */ - CTBlipFillProperties getBlipFill(); - - /** - * True if has "blipFill" element - */ - boolean isSetBlipFill(); - - /** - * Sets the "blipFill" element - */ - void setBlipFill(CTBlipFillProperties blipFill); - - /** - * Appends and returns a new empty "blipFill" element - */ - CTBlipFillProperties addNewBlipFill(); - - /** - * Unsets the "blipFill" element - */ - void unsetBlipFill(); - - /** - * Gets the "pattFill" element - */ - CTPatternFillProperties getPattFill(); - - /** - * True if has "pattFill" element - */ - boolean isSetPattFill(); - - /** - * Sets the "pattFill" element - */ - void setPattFill(CTPatternFillProperties pattFill); - - /** - * Appends and returns a new empty "pattFill" element - */ - CTPatternFillProperties addNewPattFill(); - - /** - * Unsets the "pattFill" element - */ - void unsetPattFill(); - - /** - * Gets the "grpFill" element - */ - CTGroupFillProperties getGrpFill(); - - /** - * True if has "grpFill" element - */ - boolean isSetGrpFill(); - - /** - * Sets the "grpFill" element - */ - void setGrpFill(CTGroupFillProperties grpFill); - - /** - * Appends and returns a new empty "grpFill" element - */ - CTGroupFillProperties addNewGrpFill(); - - /** - * Unsets the "grpFill" element - */ - void unsetGrpFill(); - - /** - * Helper method to unify other properties with style matrix references - * @return true, if this is a matrix style delegate - */ - boolean isSetMatrixStyle(); - - /** - * Helper method to unify other properties with style matrix references - */ - CTStyleMatrixReference getMatrixStyle(); - - /** - * Helper method to choose between fill and line style - * - * @return true, if this applies to a line - */ - boolean isLineStyle(); - } - - public interface XSLFGeometryProperties { - /** - * Gets the "custGeom" element - */ - CTCustomGeometry2D getCustGeom(); - - /** - * True if has "custGeom" element - */ - boolean isSetCustGeom(); - - /** - * Sets the "custGeom" element - */ - void setCustGeom(CTCustomGeometry2D custGeom); - - /** - * Appends and returns a new empty "custGeom" element - */ - CTCustomGeometry2D addNewCustGeom(); - - /** - * Unsets the "custGeom" element - */ - void unsetCustGeom(); - - /** - * Gets the "prstGeom" element - */ - CTPresetGeometry2D getPrstGeom(); - - /** - * True if has "prstGeom" element - */ - boolean isSetPrstGeom(); - - /** - * Sets the "prstGeom" element - */ - void setPrstGeom(CTPresetGeometry2D prstGeom); - - /** - * Appends and returns a new empty "prstGeom" element - */ - CTPresetGeometry2D addNewPrstGeom(); - - /** - * Unsets the "prstGeom" element - */ - void unsetPrstGeom(); - } - - public interface XSLFEffectProperties { - /** - * Gets the "effectLst" element - */ - CTEffectList getEffectLst(); - - /** - * True if has "effectLst" element - */ - boolean isSetEffectLst(); - - /** - * Sets the "effectLst" element - */ - void setEffectLst(CTEffectList effectLst); - - /** - * Appends and returns a new empty "effectLst" element - */ - CTEffectList addNewEffectLst(); - - /** - * Unsets the "effectLst" element - */ - void unsetEffectLst(); - - /** - * Gets the "effectDag" element - */ - CTEffectContainer getEffectDag(); - - /** - * True if has "effectDag" element - */ - boolean isSetEffectDag(); - - /** - * Sets the "effectDag" element - */ - void setEffectDag(CTEffectContainer effectDag); - - /** - * Appends and returns a new empty "effectDag" element - */ - CTEffectContainer addNewEffectDag(); - - /** - * Unsets the "effectDag" element - */ - void unsetEffectDag(); - } - - private static class ShapeDelegate implements XSLFFillProperties, XSLFGeometryProperties, XSLFEffectProperties { - final CTShapeProperties props; - - ShapeDelegate(CTShapeProperties props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return props.getNoFill(); - } - - @Override - public boolean isSetNoFill() { - return props.isSetNoFill(); - } - - @Override - public void setNoFill(CTNoFillProperties noFill) { - props.setNoFill(noFill); - } - - @Override - public CTNoFillProperties addNewNoFill() { - return props.addNewNoFill(); - } - - @Override - public void unsetNoFill() { - props.unsetNoFill(); - } - - @Override - public CTSolidColorFillProperties getSolidFill() { - return props.getSolidFill(); - } - - @Override - public boolean isSetSolidFill() { - return props.isSetSolidFill(); - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) { - props.setSolidFill(solidFill); - } - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return props.addNewSolidFill(); - } - - @Override - public void unsetSolidFill() { - props.unsetSolidFill(); - } - - @Override - public CTGradientFillProperties getGradFill() { - return props.getGradFill(); - } - - @Override - public boolean isSetGradFill() { - return props.isSetGradFill(); - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) { - props.setGradFill(gradFill); - } - - @Override - public CTGradientFillProperties addNewGradFill() { - return props.addNewGradFill(); - } - - @Override - public void unsetGradFill() { - props.unsetGradFill(); - } - - @Override - public CTBlipFillProperties getBlipFill() { - return props.getBlipFill(); - } - - @Override - public boolean isSetBlipFill() { - return props.isSetBlipFill(); - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) { - props.setBlipFill(blipFill); - } - - @Override - public CTBlipFillProperties addNewBlipFill() { - return props.addNewBlipFill(); - } - - @Override - public void unsetBlipFill() { - props.unsetBlipFill(); - } - - @Override - public CTPatternFillProperties getPattFill() { - return props.getPattFill(); - } - - @Override - public boolean isSetPattFill() { - return props.isSetPattFill(); - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) { - props.setPattFill(pattFill); - } - - @Override - public CTPatternFillProperties addNewPattFill() { - return props.addNewPattFill(); - } - - @Override - public void unsetPattFill() { - props.unsetPattFill(); - } - - @Override - public CTGroupFillProperties getGrpFill() { - return props.getGrpFill(); - } - - @Override - public boolean isSetGrpFill() { - return props.isSetGrpFill(); - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) { - props.setGrpFill(grpFill); - } - - @Override - public CTGroupFillProperties addNewGrpFill() { - return props.addNewGrpFill(); - } - - @Override - public void unsetGrpFill() { - props.unsetGrpFill(); - } - - @Override - public CTCustomGeometry2D getCustGeom() { - return props.getCustGeom(); - } - - @Override - public boolean isSetCustGeom() { - return props.isSetCustGeom(); - } - - @Override - public void setCustGeom(CTCustomGeometry2D custGeom) { - props.setCustGeom(custGeom); - } - - @Override - public CTCustomGeometry2D addNewCustGeom() { - return props.addNewCustGeom(); - } - - @Override - public void unsetCustGeom() { - props.unsetCustGeom(); - } - - @Override - public CTPresetGeometry2D getPrstGeom() { - return props.getPrstGeom(); - } - - @Override - public boolean isSetPrstGeom() { - return props.isSetPrstGeom(); - } - - @Override - public void setPrstGeom(CTPresetGeometry2D prstGeom) { - props.setPrstGeom(prstGeom); - } - - @Override - public CTPresetGeometry2D addNewPrstGeom() { - return props.addNewPrstGeom(); - } - - @Override - public void unsetPrstGeom() { - props.unsetPrstGeom(); - } - - @Override - public CTEffectList getEffectLst() { - return props.getEffectLst(); - } - - @Override - public boolean isSetEffectLst() { - return props.isSetEffectLst(); - } - - @Override - public void setEffectLst(CTEffectList effectLst) { - props.setEffectLst(effectLst); - } - - @Override - public CTEffectList addNewEffectLst() { - return props.addNewEffectLst(); - } - - @Override - public void unsetEffectLst() { - props.unsetEffectLst(); - } - - @Override - public CTEffectContainer getEffectDag() { - return props.getEffectDag(); - } - - @Override - public boolean isSetEffectDag() { - return props.isSetEffectDag(); - } - - @Override - public void setEffectDag(CTEffectContainer effectDag) { - props.setEffectDag(effectDag); - } - - @Override - public CTEffectContainer addNewEffectDag() { - return props.addNewEffectDag(); - } - - @Override - public void unsetEffectDag() { - props.unsetEffectDag(); - } - - @Override - public boolean isSetMatrixStyle() { - return false; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return false; - } - } - - private static class BackgroundDelegate implements XSLFFillProperties, XSLFEffectProperties { - final CTBackgroundProperties props; - - BackgroundDelegate(CTBackgroundProperties props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return props.getNoFill(); - } - - @Override - public boolean isSetNoFill() { - return props.isSetNoFill(); - } - - @Override - public void setNoFill(CTNoFillProperties noFill) { - props.setNoFill(noFill); - } - - @Override - public CTNoFillProperties addNewNoFill() { - return props.addNewNoFill(); - } - - @Override - public void unsetNoFill() { - props.unsetNoFill(); - } - - @Override - public CTSolidColorFillProperties getSolidFill() { - return props.getSolidFill(); - } - - @Override - public boolean isSetSolidFill() { - return props.isSetSolidFill(); - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) { - props.setSolidFill(solidFill); - } - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return props.addNewSolidFill(); - } - - @Override - public void unsetSolidFill() { - props.unsetSolidFill(); - } - - @Override - public CTGradientFillProperties getGradFill() { - return props.getGradFill(); - } - - @Override - public boolean isSetGradFill() { - return props.isSetGradFill(); - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) { - props.setGradFill(gradFill); - } - - @Override - public CTGradientFillProperties addNewGradFill() { - return props.addNewGradFill(); - } - - @Override - public void unsetGradFill() { - props.unsetGradFill(); - } - - @Override - public CTBlipFillProperties getBlipFill() { - return props.getBlipFill(); - } - - @Override - public boolean isSetBlipFill() { - return props.isSetBlipFill(); - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) { - props.setBlipFill(blipFill); - } - - @Override - public CTBlipFillProperties addNewBlipFill() { - return props.addNewBlipFill(); - } - - @Override - public void unsetBlipFill() { - props.unsetBlipFill(); - } - - @Override - public CTPatternFillProperties getPattFill() { - return props.getPattFill(); - } - - @Override - public boolean isSetPattFill() { - return props.isSetPattFill(); - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) { - props.setPattFill(pattFill); - } - - @Override - public CTPatternFillProperties addNewPattFill() { - return props.addNewPattFill(); - } - - @Override - public void unsetPattFill() { - props.unsetPattFill(); - } - - @Override - public CTGroupFillProperties getGrpFill() { - return props.getGrpFill(); - } - - @Override - public boolean isSetGrpFill() { - return props.isSetGrpFill(); - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) { - props.setGrpFill(grpFill); - } - - @Override - public CTGroupFillProperties addNewGrpFill() { - return props.addNewGrpFill(); - } - - @Override - public void unsetGrpFill() { - props.unsetGrpFill(); - } - - @Override - public CTEffectList getEffectLst() { - return props.getEffectLst(); - } - - @Override - public boolean isSetEffectLst() { - return props.isSetEffectLst(); - } - - @Override - public void setEffectLst(CTEffectList effectLst) { - props.setEffectLst(effectLst); - } - - @Override - public CTEffectList addNewEffectLst() { - return props.addNewEffectLst(); - } - - @Override - public void unsetEffectLst() { - props.unsetEffectLst(); - } - - @Override - public CTEffectContainer getEffectDag() { - return props.getEffectDag(); - } - - @Override - public boolean isSetEffectDag() { - return props.isSetEffectDag(); - } - - @Override - public void setEffectDag(CTEffectContainer effectDag) { - props.setEffectDag(effectDag); - } - - @Override - public CTEffectContainer addNewEffectDag() { - return props.addNewEffectDag(); - } - - @Override - public void unsetEffectDag() { - props.unsetEffectDag(); - } - - @Override - public boolean isSetMatrixStyle() { - return false; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return false; - } - } - - private static class TableCellDelegate implements XSLFFillProperties { - final CTTableCellProperties props; - - TableCellDelegate(CTTableCellProperties props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return props.getNoFill(); - } - - @Override - public boolean isSetNoFill() { - return props.isSetNoFill(); - } - - @Override - public void setNoFill(CTNoFillProperties noFill) { - props.setNoFill(noFill); - } - - @Override - public CTNoFillProperties addNewNoFill() { - return props.addNewNoFill(); - } - - @Override - public void unsetNoFill() { - props.unsetNoFill(); - } - - @Override - public CTSolidColorFillProperties getSolidFill() { - return props.getSolidFill(); - } - - @Override - public boolean isSetSolidFill() { - return props.isSetSolidFill(); - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) { - props.setSolidFill(solidFill); - } - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return props.addNewSolidFill(); - } - - @Override - public void unsetSolidFill() { - props.unsetSolidFill(); - } - - @Override - public CTGradientFillProperties getGradFill() { - return props.getGradFill(); - } - - @Override - public boolean isSetGradFill() { - return props.isSetGradFill(); - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) { - props.setGradFill(gradFill); - } - - @Override - public CTGradientFillProperties addNewGradFill() { - return props.addNewGradFill(); - } - - @Override - public void unsetGradFill() { - props.unsetGradFill(); - } - - @Override - public CTBlipFillProperties getBlipFill() { - return props.getBlipFill(); - } - - @Override - public boolean isSetBlipFill() { - return props.isSetBlipFill(); - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) { - props.setBlipFill(blipFill); - } - - @Override - public CTBlipFillProperties addNewBlipFill() { - return props.addNewBlipFill(); - } - - @Override - public void unsetBlipFill() { - props.unsetBlipFill(); - } - - @Override - public CTPatternFillProperties getPattFill() { - return props.getPattFill(); - } - - @Override - public boolean isSetPattFill() { - return props.isSetPattFill(); - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) { - props.setPattFill(pattFill); - } - - @Override - public CTPatternFillProperties addNewPattFill() { - return props.addNewPattFill(); - } - - @Override - public void unsetPattFill() { - props.unsetPattFill(); - } - - @Override - public CTGroupFillProperties getGrpFill() { - return props.getGrpFill(); - } - - @Override - public boolean isSetGrpFill() { - return props.isSetGrpFill(); - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) { - props.setGrpFill(grpFill); - } - - @Override - public CTGroupFillProperties addNewGrpFill() { - return props.addNewGrpFill(); - } - - @Override - public void unsetGrpFill() { - props.unsetGrpFill(); - } - - @Override - public boolean isSetMatrixStyle() { - return false; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return false; - } - } - - private static class StyleMatrixDelegate implements XSLFFillProperties { - final CTStyleMatrixReference props; - - StyleMatrixDelegate(CTStyleMatrixReference props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return null; - } - - @Override - public boolean isSetNoFill() { - return false; - } - - @Override - public void setNoFill(CTNoFillProperties noFill) {} - - @Override - public CTNoFillProperties addNewNoFill() { - return null; - } - - @Override - public void unsetNoFill() {} - - @Override - public CTSolidColorFillProperties getSolidFill() { - return null; - } - - @Override - public boolean isSetSolidFill() { - return false; - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) {} - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return null; - } - - @Override - public void unsetSolidFill() {} - - @Override - public CTGradientFillProperties getGradFill() { - return null; - } - - @Override - public boolean isSetGradFill() { - return false; - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) {} - - @Override - public CTGradientFillProperties addNewGradFill() { - return null; - } - - @Override - public void unsetGradFill() {} - - @Override - public CTBlipFillProperties getBlipFill() { - return null; - } - - @Override - public boolean isSetBlipFill() { - return false; - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) {} - - @Override - public CTBlipFillProperties addNewBlipFill() { - return null; - } - - @Override - public void unsetBlipFill() {} - - @Override - public CTPatternFillProperties getPattFill() { - return null; - } - - @Override - public boolean isSetPattFill() { - return false; - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) {} - - @Override - public CTPatternFillProperties addNewPattFill() { - return null; - } - - @Override - public void unsetPattFill() {} - - @Override - public CTGroupFillProperties getGrpFill() { - return null; - } - - @Override - public boolean isSetGrpFill() { - return false; - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) {} - - @Override - public CTGroupFillProperties addNewGrpFill() { - return null; - } - - @Override - public void unsetGrpFill() {} - - - @Override - public boolean isSetMatrixStyle() { - return true; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return props; - } - - @Override - public boolean isLineStyle() { - XmlCursor cur = props.newCursor(); - String name = cur.getName().getLocalPart(); - cur.dispose(); - return "lnRef".equals(name); - } - } - - private static class FillDelegate implements XSLFFillProperties { - final CTFillProperties props; - - FillDelegate(CTFillProperties props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return props.getNoFill(); - } - - @Override - public boolean isSetNoFill() { - return props.isSetNoFill(); - } - - @Override - public void setNoFill(CTNoFillProperties noFill) { - props.setNoFill(noFill); - } - - @Override - public CTNoFillProperties addNewNoFill() { - return props.addNewNoFill(); - } - - @Override - public void unsetNoFill() { - props.unsetNoFill(); - } - - @Override - public CTSolidColorFillProperties getSolidFill() { - return props.getSolidFill(); - } - - @Override - public boolean isSetSolidFill() { - return props.isSetSolidFill(); - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) { - props.setSolidFill(solidFill); - } - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return props.addNewSolidFill(); - } - - @Override - public void unsetSolidFill() { - props.unsetSolidFill(); - } - - @Override - public CTGradientFillProperties getGradFill() { - return props.getGradFill(); - } - - @Override - public boolean isSetGradFill() { - return props.isSetGradFill(); - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) { - props.setGradFill(gradFill); - } - - @Override - public CTGradientFillProperties addNewGradFill() { - return props.addNewGradFill(); - } - - @Override - public void unsetGradFill() { - props.unsetGradFill(); - } - - @Override - public CTBlipFillProperties getBlipFill() { - return props.getBlipFill(); - } - - @Override - public boolean isSetBlipFill() { - return props.isSetBlipFill(); - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) { - props.setBlipFill(blipFill); - } - - @Override - public CTBlipFillProperties addNewBlipFill() { - return props.addNewBlipFill(); - } - - @Override - public void unsetBlipFill() { - props.unsetBlipFill(); - } - - @Override - public CTPatternFillProperties getPattFill() { - return props.getPattFill(); - } - - @Override - public boolean isSetPattFill() { - return props.isSetPattFill(); - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) { - props.setPattFill(pattFill); - } - - @Override - public CTPatternFillProperties addNewPattFill() { - return props.addNewPattFill(); - } - - @Override - public void unsetPattFill() { - props.unsetPattFill(); - } - - @Override - public CTGroupFillProperties getGrpFill() { - return props.getGrpFill(); - } - - @Override - public boolean isSetGrpFill() { - return props.isSetGrpFill(); - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) { - props.setGrpFill(grpFill); - } - - @Override - public CTGroupFillProperties addNewGrpFill() { - return props.addNewGrpFill(); - } - - @Override - public void unsetGrpFill() { - props.unsetGrpFill(); - } - - @Override - public boolean isSetMatrixStyle() { - return false; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return false; - } - } - - private static class FillPartDelegate implements XSLFFillProperties { - final XmlObject props; - - FillPartDelegate(XmlObject props) { - this.props = props; - } - - public CTNoFillProperties getNoFill() { - return isSetNoFill() ? (CTNoFillProperties)props : null; - } - - public boolean isSetNoFill() { - return (props instanceof CTNoFillProperties); - } - - public void setNoFill(CTNoFillProperties noFill) {} - - public CTNoFillProperties addNewNoFill() { - return null; - } - - public void unsetNoFill() {} - - public CTSolidColorFillProperties getSolidFill() { - return isSetSolidFill() ? (CTSolidColorFillProperties)props : null; - } - - public boolean isSetSolidFill() { - return (props instanceof CTSolidColorFillProperties); - } - - public void setSolidFill(CTSolidColorFillProperties solidFill) {} - - public CTSolidColorFillProperties addNewSolidFill() { - return null; - } - - public void unsetSolidFill() {} - - public CTGradientFillProperties getGradFill() { - return isSetGradFill() ? (CTGradientFillProperties)props : null; - } - - public boolean isSetGradFill() { - return (props instanceof CTGradientFillProperties); - } - - public void setGradFill(CTGradientFillProperties gradFill) {} - - public CTGradientFillProperties addNewGradFill() { - return null; - } - - public void unsetGradFill() {} - - public CTBlipFillProperties getBlipFill() { - return isSetBlipFill() ? (CTBlipFillProperties)props : null; - } - - public boolean isSetBlipFill() { - return (props instanceof CTBlipFillProperties); - } - - public void setBlipFill(CTBlipFillProperties blipFill) {} - - public CTBlipFillProperties addNewBlipFill() { - return null; - } - - public void unsetBlipFill() {} - - public CTPatternFillProperties getPattFill() { - return isSetPattFill() ? (CTPatternFillProperties)props : null; - } - - public boolean isSetPattFill() { - return (props instanceof CTPatternFillProperties); - } - - public void setPattFill(CTPatternFillProperties pattFill) {} - - public CTPatternFillProperties addNewPattFill() { - return null; - } - - public void unsetPattFill() {} - - public CTGroupFillProperties getGrpFill() { - return isSetGrpFill() ? (CTGroupFillProperties)props : null; - } - - public boolean isSetGrpFill() { - return (props instanceof CTGroupFillProperties); - } - - public void setGrpFill(CTGroupFillProperties grpFill) {} - - public CTGroupFillProperties addNewGrpFill() { - return null; - } - - public void unsetGrpFill() {} - - public boolean isSetMatrixStyle() { - return false; - } - - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return false; - } - } - - private static class LineStyleDelegate implements XSLFFillProperties { - final CTLineProperties props; - - LineStyleDelegate(CTLineProperties props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return props.getNoFill(); - } - - @Override - public boolean isSetNoFill() { - return props.isSetNoFill(); - } - - @Override - public void setNoFill(CTNoFillProperties noFill) { - props.setNoFill(noFill); - } - - @Override - public CTNoFillProperties addNewNoFill() { - return props.addNewNoFill(); - } - - @Override - public void unsetNoFill() { - props.unsetNoFill(); - } - - @Override - public CTSolidColorFillProperties getSolidFill() { - return props.getSolidFill(); - } - - @Override - public boolean isSetSolidFill() { - return props.isSetSolidFill(); - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) { - props.setSolidFill(solidFill); - } - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return props.addNewSolidFill(); - } - - @Override - public void unsetSolidFill() { - props.unsetSolidFill(); - } - - @Override - public CTGradientFillProperties getGradFill() { - return props.getGradFill(); - } - - @Override - public boolean isSetGradFill() { - return props.isSetGradFill(); - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) { - props.setGradFill(gradFill); - } - - @Override - public CTGradientFillProperties addNewGradFill() { - return props.addNewGradFill(); - } - - @Override - public void unsetGradFill() { - props.unsetGradFill(); - } - - @Override - public CTBlipFillProperties getBlipFill() { - return null; - } - - @Override - public boolean isSetBlipFill() { - return false; - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) {} - - @Override - public CTBlipFillProperties addNewBlipFill() { - return null; - } - - @Override - public void unsetBlipFill() {} - - @Override - public CTPatternFillProperties getPattFill() { - return props.getPattFill(); - } - - @Override - public boolean isSetPattFill() { - return props.isSetPattFill(); - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) { - props.setPattFill(pattFill); - } - - @Override - public CTPatternFillProperties addNewPattFill() { - return props.addNewPattFill(); - } - - @Override - public void unsetPattFill() { - props.unsetPattFill(); - } - - @Override - public CTGroupFillProperties getGrpFill() { - return null; - } - - @Override - public boolean isSetGrpFill() { - return false; - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) {} - - @Override - public CTGroupFillProperties addNewGrpFill() { - return null; - } - - @Override - public void unsetGrpFill() {} - - @Override - public boolean isSetMatrixStyle() { - return false; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return true; - } - } - - private static class TextCharDelegate implements XSLFFillProperties { - final CTTextCharacterProperties props; - - TextCharDelegate(CTTextCharacterProperties props) { - this.props = props; - } - - @Override - public CTNoFillProperties getNoFill() { - return props.getNoFill(); - } - - @Override - public boolean isSetNoFill() { - return props.isSetNoFill(); - } - - @Override - public void setNoFill(CTNoFillProperties noFill) { - props.setNoFill(noFill); - } - - @Override - public CTNoFillProperties addNewNoFill() { - return props.addNewNoFill(); - } - - @Override - public void unsetNoFill() { - props.unsetNoFill(); - } - - @Override - public CTSolidColorFillProperties getSolidFill() { - return props.getSolidFill(); - } - - @Override - public boolean isSetSolidFill() { - return props.isSetSolidFill(); - } - - @Override - public void setSolidFill(CTSolidColorFillProperties solidFill) { - props.setSolidFill(solidFill); - } - - @Override - public CTSolidColorFillProperties addNewSolidFill() { - return props.addNewSolidFill(); - } - - @Override - public void unsetSolidFill() { - props.unsetSolidFill(); - } - - @Override - public CTGradientFillProperties getGradFill() { - return props.getGradFill(); - } - - @Override - public boolean isSetGradFill() { - return props.isSetGradFill(); - } - - @Override - public void setGradFill(CTGradientFillProperties gradFill) { - props.setGradFill(gradFill); - } - - @Override - public CTGradientFillProperties addNewGradFill() { - return props.addNewGradFill(); - } - - @Override - public void unsetGradFill() { - props.unsetGradFill(); - } - - @Override - public CTBlipFillProperties getBlipFill() { - return props.getBlipFill(); - } - - @Override - public boolean isSetBlipFill() { - return props.isSetBlipFill(); - } - - @Override - public void setBlipFill(CTBlipFillProperties blipFill) { - props.setBlipFill(blipFill); - } - - @Override - public CTBlipFillProperties addNewBlipFill() { - return props.addNewBlipFill(); - } - - @Override - public void unsetBlipFill() { - props.unsetBlipFill(); - } - - @Override - public CTPatternFillProperties getPattFill() { - return props.getPattFill(); - } - - @Override - public boolean isSetPattFill() { - return props.isSetPattFill(); - } - - @Override - public void setPattFill(CTPatternFillProperties pattFill) { - props.setPattFill(pattFill); - } - - @Override - public CTPatternFillProperties addNewPattFill() { - return props.addNewPattFill(); - } - - @Override - public void unsetPattFill() { - props.unsetPattFill(); - } - - @Override - public CTGroupFillProperties getGrpFill() { - return props.getGrpFill(); - } - - @Override - public boolean isSetGrpFill() { - return props.isSetGrpFill(); - } - - @Override - public void setGrpFill(CTGroupFillProperties grpFill) { - props.setGrpFill(grpFill); - } - - @Override - public CTGroupFillProperties addNewGrpFill() { - return props.addNewGrpFill(); - } - - @Override - public void unsetGrpFill() { - props.unsetGrpFill(); - } - - @Override - public boolean isSetMatrixStyle() { - return false; - } - - @Override - public CTStyleMatrixReference getMatrixStyle() { - return null; - } - - @Override - public boolean isLineStyle() { - return false; - } - } - - @SuppressWarnings("unchecked") - private static T getDelegate(Class clazz, XmlObject props) { - Object obj = null; - if (props == null) { - return null; - } else if (props instanceof CTShapeProperties) { - obj = new ShapeDelegate((CTShapeProperties)props); - } else if (props instanceof CTBackgroundProperties) { - obj = new BackgroundDelegate((CTBackgroundProperties)props); - } else if (props instanceof CTStyleMatrixReference) { - obj = new StyleMatrixDelegate((CTStyleMatrixReference)props); - } else if (props instanceof CTTableCellProperties) { - obj = new TableCellDelegate((CTTableCellProperties)props); - } else if (props instanceof CTNoFillProperties - || props instanceof CTSolidColorFillProperties - || props instanceof CTGradientFillProperties - || props instanceof CTBlipFillProperties - || props instanceof CTPatternFillProperties - || props instanceof CTGroupFillProperties) { - obj = new FillPartDelegate(props); - } else if (props instanceof CTFillProperties) { - obj = new FillDelegate((CTFillProperties)props); - } else if (props instanceof CTLineProperties) { - obj = new LineStyleDelegate((CTLineProperties)props); - } else if (props instanceof CTTextCharacterProperties) { - obj = new TextCharDelegate((CTTextCharacterProperties)props); - } else { - LOG.log(POILogger.ERROR, props.getClass().toString()+" is an unknown properties type"); - return null; - } - - if (clazz.isInstance(obj)) { - return (T)obj; - } - - LOG.log(POILogger.WARN, obj.getClass().toString()+" doesn't implement "+clazz.toString()); - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java deleted file mode 100644 index f3f59b918..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java +++ /dev/null @@ -1,249 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLRelation; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.util.Beta; - -@Beta -public class XSLFRelation extends POIXMLRelation { - - /** - * A map to lookup POIXMLRelation by its relation type - */ - private static final Map _table = new HashMap(); - - public static final XSLFRelation MAIN = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml", - null, null, null - ); - - public static final XSLFRelation MACRO = new XSLFRelation( - "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml", - null, null, null - ); - - public static final XSLFRelation MACRO_TEMPLATE = new XSLFRelation( - "application/vnd.ms-powerpoint.template.macroEnabled.main+xml", - null, null, null - ); - - public static final XSLFRelation PRESENTATIONML = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml", - null, null, null - ); - - public static final XSLFRelation PRESENTATIONML_TEMPLATE = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml", - null, null, null - ); - - public static final XSLFRelation PRESENTATION_MACRO = new XSLFRelation( - "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml", - null, null, null - ); - - public static final XSLFRelation THEME_MANAGER = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.themeManager+xml", - null, null, null - ); - - public static final XSLFRelation NOTES = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", - "/ppt/notesSlides/notesSlide#.xml", - XSLFNotes.class - ); - - public static final XSLFRelation SLIDE = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.slide+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", - "/ppt/slides/slide#.xml", - XSLFSlide.class - ); - - public static final XSLFRelation SLIDE_LAYOUT = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout", - "/ppt/slideLayouts/slideLayout#.xml", - XSLFSlideLayout.class - ); - - public static final XSLFRelation SLIDE_MASTER = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster", - "/ppt/slideMasters/slideMaster#.xml", - XSLFSlideMaster.class - ); - - public static final XSLFRelation NOTES_MASTER = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", - "/ppt/notesMasters/notesMaster#.xml", - XSLFNotesMaster.class - ); - - public static final XSLFRelation COMMENTS = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.comments+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", - "/ppt/comments/comment#.xml", - XSLFComments.class - ); - - public static final XSLFRelation COMMENT_AUTHORS = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors", - "/ppt/commentAuthors.xml", - XSLFCommentAuthors.class - ); - - public static final XSLFRelation HYPERLINK = new XSLFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", - null, - null - ); - - public static final XSLFRelation THEME = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.theme+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", - "/ppt/theme/theme#.xml", - XSLFTheme.class - ); - - public static final XSLFRelation VML_DRAWING = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.vmlDrawing", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing", - "/ppt/drawings/vmlDrawing#.vml", - null - ); - - public static final XSLFRelation CHART = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.drawingml.chart+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", - "/ppt/charts/chart#.xml", - XSLFChart.class - ); - - public static final XSLFRelation IMAGE_EMF = new XSLFRelation( - PictureType.EMF.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.emf", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_WMF = new XSLFRelation( - PictureType.WMF.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.wmf", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_PICT = new XSLFRelation( - PictureType.PICT.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.pict", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_JPEG = new XSLFRelation( - PictureType.JPEG.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.jpeg", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_PNG = new XSLFRelation( - PictureType.PNG.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.png", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_DIB = new XSLFRelation( - PictureType.DIB.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.dib", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_GIF = new XSLFRelation( - PictureType.GIF.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.gif", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_TIFF = new XSLFRelation( - PictureType.TIFF.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.tiff", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_EPS = new XSLFRelation( - PictureType.EPS.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.eps", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_BMP = new XSLFRelation( - PictureType.BMP.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.bmp", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_WPG = new XSLFRelation( - PictureType.WPG.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.wpg", - XSLFPictureData.class - ); - public static final XSLFRelation IMAGE_WDP = new XSLFRelation( - PictureType.WDP.contentType, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/ppt/media/image#.wdp", - XSLFPictureData.class - ); - - public static final XSLFRelation IMAGES = new XSLFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - null, - XSLFPictureData.class - ); - - public static final XSLFRelation TABLE_STYLES = new XSLFRelation( - "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles", - "/ppt/tableStyles.xml", - XSLFTableStyles.class - ); - - private XSLFRelation(String type, String rel, String defaultName, Class cls) { - super(type, rel, defaultName, cls); - _table.put(rel, this); - } - - /** - * Get POIXMLRelation by relation type - * - * @param rel relation type, for example, - * http://schemas.openxmlformats.org/officeDocument/2006/relationships/image - * @return registered POIXMLRelation or null if not found - */ - public static XSLFRelation getInstance(String rel){ - return _table.get(rel); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java deleted file mode 100644 index fe6838568..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.util.Internal; - -import java.awt.RenderingHints; - -/** - * - * @author Yegor Kozlov - */ -public class XSLFRenderingHint extends RenderingHints.Key { - - public XSLFRenderingHint(int i){ - super(i); - } - - @Override - public boolean isCompatibleValue(Object val) { - return true; - } - - public static final XSLFRenderingHint GSAVE = new XSLFRenderingHint(1); - public static final XSLFRenderingHint GRESTORE = new XSLFRenderingHint(2); - - /** - * Use a custom image rendener - * - * @see XSLFImageRenderer - */ - public static final XSLFRenderingHint IMAGE_RENDERER = new XSLFRenderingHint(3); - - /** - * how to render text: - * - * {@link #TEXT_AS_CHARACTERS} (default) means to draw via - * {@link java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float)}. - * This mode draws text as characters. Use it if the target graphics writes the actual - * character codes instead of glyph outlines (PDFGraphics2D, SVGGraphics2D, etc.) - * - * {@link #TEXT_AS_SHAPES} means to render via - * {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)}. - * This mode draws glyphs as shapes and provides some advanced capabilities such as - * justification and font substitution. Use it if the target graphics is an image. - * - */ - public static final XSLFRenderingHint TEXT_RENDERING_MODE = new XSLFRenderingHint(4); - - /** - * draw text via {@link java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float)} - */ - public static final int TEXT_AS_CHARACTERS = 1; - - /** - * draw text via {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)} - */ - public static final int TEXT_AS_SHAPES = 2; - - @Internal - static final XSLFRenderingHint GROUP_TRANSFORM = new XSLFRenderingHint(5); - - /** - * Use this object to resolve unknown / missing fonts when rendering slides - */ - public static final XSLFRenderingHint FONT_HANDLER = new XSLFRenderingHint(6); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java deleted file mode 100644 index 4adeba302..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java +++ /dev/null @@ -1,107 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.Shadow; -import org.apache.poi.util.Units; -import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; - -/** - * Represents a shadow of a shape. For now supports only outer shadows. - * - * @author Yegor Kozlov - */ -public class XSLFShadow extends XSLFShape implements Shadow { - - private XSLFSimpleShape _parent; - - /* package */XSLFShadow(CTOuterShadowEffect shape, XSLFSimpleShape parentShape) { - super(shape, parentShape.getSheet()); - - _parent = parentShape; - } - - @Override - public XSLFSimpleShape getShadowParent() { - return _parent; - } - - @Override - public Rectangle2D getAnchor(){ - return _parent.getAnchor(); - } - - public void setAnchor(Rectangle2D anchor){ - throw new IllegalStateException("You can't set anchor of a shadow"); - } - - /** - * @return the offset of this shadow in points - */ - public double getDistance(){ - CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); - return ct.isSetDist() ? Units.toPoints(ct.getDist()) : 0; - } - - /** - * - * @return the direction to offset the shadow in angles - */ - public double getAngle(){ - CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); - return ct.isSetDir() ? (double)ct.getDir() / 60000 : 0; - } - - /** - * - * @return the blur radius of the shadow - * TODO: figure out how to make sense of this property when rendering shadows - */ - public double getBlur(){ - CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); - return ct.isSetBlurRad() ? Units.toPoints(ct.getBlurRad()) : 0; - } - - /** - * @return the color of this shadow. - * Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow - */ - public Color getFillColor() { - SolidPaint ps = getFillStyle(); - if (ps == null) return null; - Color col = DrawPaint.applyColorTransform(ps.getSolidColor()); - return col; - } - - @Override - public SolidPaint getFillStyle() { - XSLFTheme theme = getSheet().getTheme(); - CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); - if(ct == null) return null; - - CTSchemeColor phClr = ct.getSchemeClr(); - final XSLFColor xc = new XSLFColor(ct, theme, phClr); - return DrawPaint.createSolidPaint(xc.getColorStyle()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java deleted file mode 100644 index 70df3f806..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Comparator; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.ColorStyle; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; -import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; -import org.apache.poi.sl.usermodel.PlaceableShape; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.xslf.model.PropertyFetcher; -import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; -import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; -import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; - -/** - * Base super-class class for all shapes in PresentationML - */ -@Beta -public abstract class XSLFShape implements Shape { - protected static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main"; - - private final XmlObject _shape; - private final XSLFSheet _sheet; - private XSLFShapeContainer _parent; - - private CTShapeStyle _spStyle; - private CTNonVisualDrawingProps _nvPr; - private CTPlaceholder _ph; - - protected XSLFShape(XmlObject shape, XSLFSheet sheet) { - _shape = shape; - _sheet = sheet; - } - - /** - * @return the xml bean holding this shape's data - */ - public final XmlObject getXmlObject() { - // it's final because the xslf inheritance hierarchy is not necessary the same as - // the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value - return _shape; - } - - public XSLFSheet getSheet() { - return _sheet; - } - - /** - * @return human-readable name of this shape, e.g. "Rectange 3" - */ - public String getShapeName(){ - return getCNvPr().getName(); - } - - /** - * Returns a unique identifier for this shape within the current document. - * This ID may be used to assist in uniquely identifying this object so that it can - * be referred to by other parts of the document. - *

        - * If multiple objects within the same document share the same id attribute value, - * then the document shall be considered non-conformant. - *

        - * - * @return unique id of this shape - */ - public int getShapeId() { - return (int)getCNvPr().getId(); - } - - /** - * Set the contents of this shape to be a copy of the source shape. - * This method is called recursively for each shape when merging slides - * - * @param sh the source shape - * @see org.apache.poi.xslf.usermodel.XSLFSlide#importContent(XSLFSheet) - */ - @Internal - void copy(XSLFShape sh) { - if (!getClass().isInstance(sh)) { - throw new IllegalArgumentException( - "Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName()); - } - - if (this instanceof PlaceableShape) { - PlaceableShape ps = (PlaceableShape)this; - ps.setAnchor(sh.getAnchor()); - } - - - } - - public void setParent(XSLFShapeContainer parent) { - this._parent = parent; - } - - public XSLFShapeContainer getParent() { - return this._parent; - } - - protected PaintStyle getFillPaint() { - final XSLFTheme theme = getSheet().getTheme(); - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties()); - if (fp == null) { - return false; - } - - if (fp.isSetNoFill()) { - setValue(null); - return true; - } - - PackagePart pp = shape.getSheet().getPackagePart(); - PaintStyle paint = selectPaint(fp, null, pp, theme); - if (paint != null) { - setValue(paint); - return true; - } - - CTShapeStyle style = shape.getSpStyle(); - if (style != null) { - fp = XSLFPropertiesDelegate.getFillDelegate(style.getFillRef()); - paint = selectPaint(fp, null, pp, theme); - } - if (paint != null) { - setValue(paint); - return true; - } - - - return false; - } - }; - fetchShapeProperty(fetcher); - - return fetcher.getValue(); - } - - protected CTBackgroundProperties getBgPr() { - return getChild(CTBackgroundProperties.class, PML_NS, "bgPr"); - } - - protected CTStyleMatrixReference getBgRef() { - return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef"); - } - - protected CTGroupShapeProperties getGrpSpPr() { - return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr"); - } - - protected CTNonVisualDrawingProps getCNvPr() { - if (_nvPr == null) { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"; - _nvPr = selectProperty(CTNonVisualDrawingProps.class, xquery); - } - return _nvPr; - } - - protected CTShapeStyle getSpStyle() { - if (_spStyle == null) { - _spStyle = getChild(CTShapeStyle.class, PML_NS, "style"); - } - return _spStyle; - } - - /** - * Return direct child objects of this shape - * - * @param childClass the class to cast the properties to - * @param namespace the namespace - usually it is {@code "http://schemas.openxmlformats.org/presentationml/2006/main"} - * @param nodename the node name, without prefix - * @return the properties object or null if it can't be found - */ - @SuppressWarnings("unchecked") - protected T getChild(Class childClass, String namespace, String nodename) { - XmlCursor cur = getXmlObject().newCursor(); - T child = null; - if (cur.toChild(namespace, nodename)) { - child = (T)cur.getObject(); - } - cur.dispose(); - return child; - } - - protected CTPlaceholder getCTPlaceholder() { - if (_ph == null) { - String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr/p:ph"; - _ph = selectProperty(CTPlaceholder.class, xquery); - } - return _ph; - } - - public Placeholder getPlaceholder() { - CTPlaceholder ph = getCTPlaceholder(); - if (ph == null || !(ph.isSetType() || ph.isSetIdx())) { - return null; - } - return Placeholder.lookupOoxml(ph.getType().intValue()); - } - - /** - * Specifies that the corresponding shape should be represented by the generating application - * as a placeholder. When a shape is considered a placeholder by the generating application - * it can have special properties to alert the user that they may enter content into the shape. - * Different types of placeholders are allowed and can be specified by using the placeholder - * type attribute for this element - * - * @param placeholder The shape to use as placeholder or null if no placeholder should be set. - */ - protected void setPlaceholder(Placeholder placeholder) { - String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr"; - CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery); - if (nv == null) return; - if(placeholder == null) { - if (nv.isSetPh()) nv.unsetPh(); - _ph = null; - } else { - nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ooxmlId)); - } - } - - - /** - * As there's no xmlbeans hierarchy, but XSLF works with subclassing, not all - * child classes work with a {@link CTShape} object, but often contain the same - * properties. This method is the generalized form of selecting and casting those - * properties. - * - * @param resultClass the requested result class - * @param xquery the simple (xmlbean) xpath expression to the property - * @return the xml object at the xpath location, or null if not found - */ - @SuppressWarnings("unchecked") - protected T selectProperty(Class resultClass, String xquery) { - XmlObject[] rs = getXmlObject().selectPath(xquery); - if (rs.length == 0) return null; - return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null; - } - - /** - * Walk up the inheritance tree and fetch shape properties. - * - * The following order of inheritance is assumed: - *

        - * slide <-- slideLayout <-- slideMaster - *

        - * - * @param visitor the object that collects the desired property - * @return true if the property was fetched - */ - protected boolean fetchShapeProperty(PropertyFetcher visitor) { - boolean ok = visitor.fetch(this); - - XSLFSimpleShape masterShape; - XSLFSheet masterSheet = (XSLFSheet)getSheet().getMasterSheet(); - CTPlaceholder ph = getCTPlaceholder(); - - if (masterSheet != null && ph != null) { - if (!ok) { - masterShape = masterSheet.getPlaceholder(ph); - if (masterShape != null) { - ok = visitor.fetch(masterShape); - } - } - - // try slide master - if (!ok ) { - int textType; - if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY; - else { - switch (ph.getType().intValue()) { - case STPlaceholderType.INT_TITLE: - case STPlaceholderType.INT_CTR_TITLE: - textType = STPlaceholderType.INT_TITLE; - break; - case STPlaceholderType.INT_FTR: - case STPlaceholderType.INT_SLD_NUM: - case STPlaceholderType.INT_DT: - textType = ph.getType().intValue(); - break; - default: - textType = STPlaceholderType.INT_BODY; - break; - } - } - XSLFSheet master = (XSLFSheet)masterSheet.getMasterSheet(); - if (master != null) { - masterShape = master.getPlaceholderByType(textType); - if (masterShape != null) { - ok = visitor.fetch(masterShape); - } - } - } - } - return ok; - } - - /** - * Convert shape fill into java.awt.Paint. The result is either Color or - * TexturePaint or GradientPaint or null - * - * @param fp a properties handler specific to the underlying shape properties - * @param phClr context color - * @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it. - * @param theme the theme for the shape/sheet - * - * @return the applied Paint or null if none was applied - */ - protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) { - if (fp == null || fp.isSetNoFill()) { - return null; - } else if (fp.isSetSolidFill()) { - return selectPaint(fp.getSolidFill(), phClr, theme); - } else if (fp.isSetBlipFill()) { - return selectPaint(fp.getBlipFill(), parentPart); - } else if (fp.isSetGradFill()) { - return selectPaint(fp.getGradFill(), phClr, theme); - } else if (fp.isSetMatrixStyle()) { - return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle()); - } else { - return null; - } - } - - protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) { - if (phClr == null && solidFill.isSetSchemeClr()) { - phClr = solidFill.getSchemeClr(); - } - final XSLFColor c = new XSLFColor(solidFill, theme, phClr); - return DrawPaint.createSolidPaint(c.getColorStyle()); - } - - protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) { - final CTBlip blip = blipFill.getBlip(); - return new TexturePaint() { - private PackagePart getPart() { - try { - String blipId = blip.getEmbed(); - PackageRelationship rel = parentPart.getRelationship(blipId); - return parentPart.getRelatedPart(rel); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } - } - - public InputStream getImageData() { - try { - return getPart().getInputStream(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public String getContentType() { - /* TOOD: map content-type */ - return getPart().getContentType(); - } - - public int getAlpha() { - return (blip.sizeOfAlphaModFixArray() > 0) - ? blip.getAlphaModFixArray(0).getAmt() - : 100000; - } - }; - } - - protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) { - - final CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); - - Arrays.sort(gs, new Comparator() { - public int compare(CTGradientStop o1, CTGradientStop o2) { - Integer pos1 = o1.getPos(); - Integer pos2 = o2.getPos(); - return pos1.compareTo(pos2); - } - }); - - final ColorStyle cs[] = new ColorStyle[gs.length]; - final float fractions[] = new float[gs.length]; - - int i=0; - for (CTGradientStop cgs : gs) { - CTSchemeColor phClrCgs = phClr; - if (phClrCgs == null && cgs.isSetSchemeClr()) { - phClrCgs = cgs.getSchemeClr(); - } - cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle(); - fractions[i] = cgs.getPos() / 100000.f; - i++; - } - - return new GradientPaint() { - - public double getGradientAngle() { - return (gradFill.isSetLin()) - ? gradFill.getLin().getAng() / 60000.d - : 0; - } - - public ColorStyle[] getGradientColors() { - return cs; - } - - public float[] getGradientFractions() { - return fractions; - } - - public boolean isRotatedWithShape() { - // TODO: is this correct??? - return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape()); - } - - public GradientType getGradientType() { - if (gradFill.isSetLin()) { - return GradientType.linear; - } - - if (gradFill.isSetPath()) { - /* TODO: handle rect path */ - STPathShadeType.Enum ps = gradFill.getPath().getPath(); - if (ps == STPathShadeType.CIRCLE) { - return GradientType.circular; - } else if (ps == STPathShadeType.SHAPE) { - return GradientType.shape; - } - } - - return GradientType.linear; - } - }; - } - - protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) { - if (fillRef == null) return null; - - // The idx attribute refers to the index of a fill style or - // background fill style within the presentation's style matrix, defined by the fmtScheme element. - // value of 0 or 1000 indicates no background, - // values 1-999 refer to the index of a fill style within the fillStyleLst element - // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element. - int idx = (int)fillRef.getIdx(); - CTSchemeColor phClr = fillRef.getSchemeClr(); - CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme(); - final XmlObject styleLst; - int childIdx; - if (idx >= 1 && idx <= 999) { - childIdx = idx-1; - styleLst = (isLineStyle) ? matrix.getLnStyleLst() : matrix.getFillStyleLst(); - } else if (idx >= 1001 ){ - childIdx = idx - 1001; - styleLst = matrix.getBgFillStyleLst(); - } else { - return null; - } - XmlCursor cur = styleLst.newCursor(); - XSLFFillProperties fp = null; - if (cur.toChild(childIdx)) { - fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject()); - } - cur.dispose(); - - return selectPaint(fp, phClr, theme.getPackagePart(), theme); - } - - @Override - public void draw(Graphics2D graphics, Rectangle2D bounds) { - DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); - } - - /** - * Return the shape specific (visual) properties - * - * @return the shape specific properties - */ - protected XmlObject getShapeProperties() { - return getChild(CTShapeProperties.class, PML_NS, "spPr"); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java deleted file mode 100644 index ddf832d3d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.ShapeContainer; - -/** - * Common interface for shape containers, e.g. sheets or groups of shapes - */ -public interface XSLFShapeContainer - extends ShapeContainer { - - @Override - XSLFAutoShape createAutoShape(); - - @Override - XSLFFreeformShape createFreeform(); - - @Override - XSLFTextBox createTextBox(); - - @Override - XSLFConnectorShape createConnector(); - - @Override - XSLFGroupShape createGroup(); - - @Override - XSLFPictureShape createPicture(PictureData pictureData); - - /** - * Removes all of the elements from this container (optional operation). - * The container will be empty after this call returns. - */ - void clear(); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java deleted file mode 100644 index 1edfff7cc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java +++ /dev/null @@ -1,618 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.awt.Graphics2D; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -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.TargetMode; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.DrawPictureShape; -import org.apache.poi.sl.draw.Drawable; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.Sheet; -import org.apache.poi.util.Beta; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData; -import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; - -@Beta -public abstract class XSLFSheet extends POIXMLDocumentPart -implements XSLFShapeContainer, Sheet { - private XSLFCommonSlideData _commonSlideData; - private XSLFDrawing _drawing; - private List _shapes; - private CTGroupShape _spTree; - - private List_placeholders; - private Map _placeholderByIdMap; - private Map _placeholderByTypeMap; - - public XSLFSheet() { - super(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XSLFSheet(PackagePart part) { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSLFSheet(PackagePart part, PackageRelationship rel){ - this(part); - } - - /** - * @return the XMLSlideShow this sheet belongs to - */ - @Override - public XMLSlideShow getSlideShow() { - POIXMLDocumentPart p = getParent(); - while(p != null) { - if(p instanceof XMLSlideShow){ - return (XMLSlideShow)p; - } - p = p.getParent(); - } - throw new IllegalStateException("SlideShow was not found"); - } - - protected static List buildShapes(CTGroupShape spTree, XSLFSheet sheet){ - List shapes = new ArrayList(); - for(XmlObject ch : spTree.selectPath("*")){ - if(ch instanceof CTShape){ // simple shape - XSLFAutoShape shape = XSLFAutoShape.create((CTShape)ch, sheet); - shapes.add(shape); - } else if (ch instanceof CTGroupShape){ - shapes.add(new XSLFGroupShape((CTGroupShape)ch, sheet)); - } else if (ch instanceof CTConnector){ - shapes.add(new XSLFConnectorShape((CTConnector)ch, sheet)); - } else if (ch instanceof CTPicture){ - shapes.add(new XSLFPictureShape((CTPicture)ch, sheet)); - } else if (ch instanceof CTGraphicalObjectFrame){ - XSLFGraphicFrame shape = XSLFGraphicFrame.create((CTGraphicalObjectFrame)ch, sheet); - shapes.add(shape); - } - } - return shapes; - } - - /** - * @return top-level Xml bean representing this sheet - */ - public abstract XmlObject getXmlObject(); - - /* - * @deprecated POI 3.16 beta 1. use {@link XSLFTable} instead - */ - @Removal(version="3.18") - @Internal - public XSLFCommonSlideData getCommonSlideData() { - return _commonSlideData; - } - - /* - * @deprecated POI 3.16 beta 1. use {@link XSLFTable} instead - */ - @Removal(version="3.18") - protected void setCommonSlideData(CTCommonSlideData data) { - if(data == null) { - _commonSlideData = null; - } else { - _commonSlideData = new XSLFCommonSlideData(data); - } - } - - private XSLFDrawing getDrawing(){ - initDrawingAndShapes(); - return _drawing; - } - - /** - * Returns an array containing all of the shapes in this sheet - * - * @return an array of all shapes in this sheet - */ - @Override - public List getShapes(){ - initDrawingAndShapes(); - return _shapes; - } - - /** - * Helper method for initializing drawing and shapes in one go. - * If they are initialized separately, there's a risk that shapes - * get added twice, e.g. a shape is added to the drawing, then - * buildShapes is called and at last the shape is added to shape list - */ - private void initDrawingAndShapes() { - CTGroupShape cgs = getSpTree(); - if(_drawing == null) { - _drawing = new XSLFDrawing(this, cgs); - } - if (_shapes == null) { - _shapes = buildShapes(cgs, this); - } - } - - // shape factory methods - - @Override - public XSLFAutoShape createAutoShape(){ - XSLFAutoShape sh = getDrawing().createAutoShape(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFFreeformShape createFreeform(){ - XSLFFreeformShape sh = getDrawing().createFreeform(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFTextBox createTextBox(){ - XSLFTextBox sh = getDrawing().createTextBox(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFConnectorShape createConnector(){ - XSLFConnectorShape sh = getDrawing().createConnector(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFGroupShape createGroup(){ - XSLFGroupShape sh = getDrawing().createGroup(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFPictureShape createPicture(PictureData pictureData){ - if (!(pictureData instanceof XSLFPictureData)) { - throw new IllegalArgumentException("pictureData needs to be of type XSLFPictureData"); - } - XSLFPictureData xPictureData = (XSLFPictureData)pictureData; - PackagePart pic = xPictureData.getPackagePart(); - - RelationPart rp = addRelation(null, XSLFRelation.IMAGES, new XSLFPictureData(pic)); - - XSLFPictureShape sh = getDrawing().createPicture(rp.getRelationship().getId()); - new DrawPictureShape(sh).resize(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - public XSLFTable createTable(){ - XSLFTable sh = getDrawing().createTable(); - getShapes().add(sh); - sh.setParent(this); - return sh; - } - - @Override - public XSLFTable createTable(int numRows, int numCols){ - if (numRows < 1 || numCols < 1) { - throw new IllegalArgumentException("numRows and numCols must be greater than 0"); - } - XSLFTable sh = getDrawing().createTable(); - getShapes().add(sh); - sh.setParent(this); - for (int r=0; r iterator(){ - return getShapes().iterator(); - } - - public void addShape(XSLFShape shape) { - throw new UnsupportedOperationException( - "Adding a shape from a different container is not supported -" - + " create it from scratch witht XSLFSheet.create* methods"); - } - - /** - * Removes the specified shape from this sheet, if it is present - * (optional operation). If this sheet does not contain the element, - * it is unchanged. - * - * @param xShape shape to be removed from this sheet, if present - * @return true if this sheet contained the specified element - * @throws IllegalArgumentException if the type of the specified shape - * is incompatible with this sheet (optional) - */ - public boolean removeShape(XSLFShape xShape) { - XmlObject obj = xShape.getXmlObject(); - CTGroupShape spTree = getSpTree(); - if(obj instanceof CTShape){ - spTree.getSpList().remove(obj); - } else if (obj instanceof CTGroupShape) { - spTree.getGrpSpList().remove(obj); - } else if (obj instanceof CTConnector) { - spTree.getCxnSpList().remove(obj); - } else if (obj instanceof CTGraphicalObjectFrame) { - spTree.getGraphicFrameList().remove(obj); - } else if (obj instanceof CTPicture) { - XSLFPictureShape ps = (XSLFPictureShape)xShape; - removePictureRelation(ps); - spTree.getPicList().remove(obj); - } else { - throw new IllegalArgumentException("Unsupported shape: " + xShape); - } - return getShapes().remove(xShape); - } - - /** - * Removes all of the elements from this container (optional operation). - * The container will be empty after this call returns. - */ - public void clear() { - List shapes = new ArrayList(getShapes()); - for(XSLFShape shape : shapes){ - removeShape(shape); - } - } - - protected abstract String getRootElementName(); - - protected CTGroupShape getSpTree(){ - if(_spTree == null) { - XmlObject root = getXmlObject(); - XmlObject[] sp = root.selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:spTree"); - if(sp.length == 0) throw new IllegalStateException("CTGroupShape was not found"); - _spTree = (CTGroupShape)sp[0]; - } - return _spTree; - } - - protected final void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - String docName = getRootElementName(); - if(docName != null) { - xmlOptions.setSaveSyntheticDocumentElement( - new QName("http://schemas.openxmlformats.org/presentationml/2006/main", docName)); - } - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - getXmlObject().save(out, xmlOptions); - out.close(); - } - - /** - * Set the contents of this sheet to be a copy of the source sheet. - * This method erases any existing shapes and replaces them with - * object from the source sheet. - * - * @param src the source sheet to copy data from - * @return modified 'this' - */ - public XSLFSheet importContent(XSLFSheet src){ - _shapes = null; - _spTree = null; - _drawing = null; - _spTree = null; - _placeholders = null; - - // fix-me: wth would this ever happen to work ... - - - // first copy the source xml - getSpTree().set(src.getSpTree()); - - // recursively update each shape - List tgtShapes = getShapes(); - List srcShapes = src.getShapes(); - for(int i = 0; i < tgtShapes.size(); i++){ - XSLFShape s1 = srcShapes.get(i); - XSLFShape s2 = tgtShapes.get(i); - - s2.copy(s1); - } - return this; - } - - /** - * Append content to this sheet. - * - * @param src the source sheet - * @return modified this. - */ - public XSLFSheet appendContent(XSLFSheet src){ - CTGroupShape spTree = getSpTree(); - int numShapes = getShapes().size(); - - CTGroupShape srcTree = src.getSpTree(); - for(XmlObject ch : srcTree.selectPath("*")){ - if(ch instanceof CTShape){ // simple shape - spTree.addNewSp().set(ch); - } else if (ch instanceof CTGroupShape){ - spTree.addNewGrpSp().set(ch); - } else if (ch instanceof CTConnector){ - spTree.addNewCxnSp().set(ch); - } else if (ch instanceof CTPicture){ - spTree.addNewPic().set(ch); - } else if (ch instanceof CTGraphicalObjectFrame){ - spTree.addNewGraphicFrame().set(ch); - } - } - - _shapes = null; - _spTree = null; - _drawing = null; - _spTree = null; - _placeholders = null; - - // recursively update each shape - List tgtShapes = getShapes(); - List srcShapes = src.getShapes(); - for(int i = 0; i < srcShapes.size(); i++){ - XSLFShape s1 = srcShapes.get(i); - XSLFShape s2 = tgtShapes.get(numShapes + i); - - s2.copy(s1); - } - return this; - } - - /** - * @return theme (shared styles) associated with this theme. - * By default returns null which means that this sheet is theme-less. - * Sheets that support the notion of themes (slides, masters, layouts, etc.) should override this - * method and return the corresponding package part. - */ - XSLFTheme getTheme(){ - return null; - } - - protected XSLFTextShape getTextShapeByType(Placeholder type){ - for(XSLFShape shape : this.getShapes()){ - if(shape instanceof XSLFTextShape) { - XSLFTextShape txt = (XSLFTextShape)shape; - if(txt.getTextType() == type) { - return txt; - } - } - } - return null; - } - - XSLFSimpleShape getPlaceholder(CTPlaceholder ph) { - XSLFSimpleShape shape = null; - if(ph.isSetIdx()) shape = getPlaceholderById((int)ph.getIdx()); - - if (shape == null && ph.isSetType()) { - shape = getPlaceholderByType(ph.getType().intValue()); - } - return shape; - } - - void initPlaceholders() { - if(_placeholders == null) { - _placeholders = new ArrayList(); - _placeholderByIdMap = new HashMap(); - _placeholderByTypeMap = new HashMap(); - - for(XSLFShape sh : getShapes()){ - if(sh instanceof XSLFTextShape){ - XSLFTextShape sShape = (XSLFTextShape)sh; - CTPlaceholder ph = sShape.getCTPlaceholder(); - if(ph != null) { - _placeholders.add(sShape); - if(ph.isSetIdx()) { - int idx = (int)ph.getIdx(); - _placeholderByIdMap.put(idx, sShape); - } - if(ph.isSetType()){ - _placeholderByTypeMap.put(ph.getType().intValue(), sShape); - } - } - } - } - } - } - - XSLFSimpleShape getPlaceholderById(int id) { - initPlaceholders(); - return _placeholderByIdMap.get(id); - } - - XSLFSimpleShape getPlaceholderByType(int ordinal) { - initPlaceholders(); - return _placeholderByTypeMap.get(ordinal); - } - - /** - * - * @param idx 0-based index of a placeholder in the sheet - * @return placeholder - */ - public XSLFTextShape getPlaceholder(int idx) { - initPlaceholders(); - return _placeholders.get(idx); - } - - /** - * - * @return all placeholder shapes in this sheet - */ - public XSLFTextShape[] getPlaceholders() { - initPlaceholders(); - return _placeholders.toArray(new XSLFTextShape[_placeholders.size()]); - } - - /** - * Checks if this sheet displays the specified shape. - * - * Subclasses can override it and skip certain shapes from drawings, - * for instance, slide masters and layouts don't display placeholders - */ - protected boolean canDraw(XSLFShape shape){ - return true; - } - - /** - * - * @return whether shapes on the master sheet should be shown. By default master graphics is turned off. - * Sheets that support the notion of master (slide, slideLayout) should override it and - * check this setting in the sheet XML - */ - public boolean getFollowMasterGraphics(){ - return false; - } - - /** - * @return background for this sheet - */ - @Override - public XSLFBackground getBackground() { - return null; - } - - /** - * Render this sheet into the supplied graphics object - * - * @param graphics - */ - @Override - public void draw(Graphics2D graphics){ - DrawFactory drawFact = DrawFactory.getInstance(graphics); - Drawable draw = drawFact.getDrawable(this); - draw.draw(graphics); - } - - /** - * Import a picture data from another document. - * - * @param blipId ID of the package relationship to retrieve. - * @param packagePart package part containing the data to import - * @return ID of the created relationship - */ - String importBlip(String blipId, PackagePart packagePart) { - PackageRelationship blipRel = packagePart.getRelationship(blipId); - PackagePart blipPart; - try { - blipPart = packagePart.getRelatedPart(blipRel); - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } - XSLFPictureData data = new XSLFPictureData(blipPart); - - XMLSlideShow ppt = getSlideShow(); - XSLFPictureData pictureData = ppt.addPicture(data.getData(), data.getType()); - PackagePart pic = pictureData.getPackagePart(); - - RelationPart rp = addRelation(blipId, XSLFRelation.IMAGES, new XSLFPictureData(pic)); - - return rp.getRelationship().getId(); - } - - /** - * Import a package part into this sheet. - */ - PackagePart importPart(PackageRelationship srcRel, PackagePart srcPafrt) { - PackagePart destPP = getPackagePart(); - PackagePartName srcPPName = srcPafrt.getPartName(); - - OPCPackage pkg = destPP.getPackage(); - if(pkg.containPart(srcPPName)){ - // already exists - return pkg.getPart(srcPPName); - } - - destPP.addRelationship(srcPPName, TargetMode.INTERNAL, srcRel.getRelationshipType()); - - PackagePart part = pkg.createPart(srcPPName, srcPafrt.getContentType()); - try { - OutputStream out = part.getOutputStream(); - InputStream is = srcPafrt.getInputStream(); - IOUtils.copy(is, out); - is.close(); - out.close(); - } catch (IOException e){ - throw new POIXMLException(e); - } - return part; - } - - /** - * Helper method for sheet and group shapes - * - * @param pictureShape the picture shapes whose relation is to be removed - */ - void removePictureRelation(XSLFPictureShape pictureShape) { - POIXMLDocumentPart pd = getRelationById(pictureShape.getBlipId()); - removeRelation(pd); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java deleted file mode 100644 index ce058f15a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.awt.geom.Rectangle2D; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.draw.geom.CustomGeometry; -import org.apache.poi.sl.draw.geom.Guide; -import org.apache.poi.sl.draw.geom.PresetGeometries; -import org.apache.poi.sl.usermodel.FillStyle; -import org.apache.poi.sl.usermodel.LineDecoration; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.SimpleShape; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; -import org.apache.poi.util.Beta; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; -import org.apache.poi.xslf.model.PropertyFetcher; -import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFEffectProperties; -import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; -import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; -import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineStyleList; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth; -import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; - -/** - * Represents a single (non-group) shape in a .pptx slide show - */ -@Beta -public abstract class XSLFSimpleShape extends XSLFShape - implements SimpleShape { - private static CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance(); - private static final POILogger LOG = POILogFactory.getLogger(XSLFSimpleShape.class); - - /* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) { - super(shape,sheet); - } - - @Override - public void setShapeType(ShapeType type) { - XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); - if (gp == null) { - return; - } - if (gp.isSetCustGeom()) { - gp.unsetCustGeom(); - } - CTPresetGeometry2D prst = (gp.isSetPrstGeom()) ? gp.getPrstGeom() : gp.addNewPrstGeom(); - prst.setPrst(STShapeType.Enum.forInt(type.ooxmlId)); - } - - @Override - public ShapeType getShapeType(){ - XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); - if (gp != null && gp.isSetPrstGeom()) { - STShapeType.Enum geom = gp.getPrstGeom().getPrst(); - if (geom != null) { - return ShapeType.forId(geom.intValue(), true); - } - } - return null; - } - - protected CTTransform2D getXfrm(boolean create) { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - XmlObject xo = shape.getShapeProperties(); - if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) { - setValue(((CTShapeProperties)xo).getXfrm()); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - - CTTransform2D xfrm = fetcher.getValue(); - if (!create || xfrm != null) { - return xfrm; - } else { - XmlObject xo = getShapeProperties(); - if (xo instanceof CTShapeProperties) { - return ((CTShapeProperties)xo).addNewXfrm(); - } else { - // ... group shapes have their own getXfrm() - LOG.log(POILogger.WARN, getClass().toString()+" doesn't have xfrm element."); - return null; - } - } - } - - @Override - public Rectangle2D getAnchor() { - - CTTransform2D xfrm = getXfrm(false); - if (xfrm == null) { - return null; - } - - CTPoint2D off = xfrm.getOff(); - double x = Units.toPoints(off.getX()); - double y = Units.toPoints(off.getY()); - CTPositiveSize2D ext = xfrm.getExt(); - double cx = Units.toPoints(ext.getCx()); - double cy = Units.toPoints(ext.getCy()); - return new Rectangle2D.Double(x, y, cx, cy); - } - - @Override - public void setAnchor(Rectangle2D anchor) { - CTTransform2D xfrm = getXfrm(true); - if (xfrm == null) { - return; - } - CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); - long x = Units.toEMU(anchor.getX()); - long y = Units.toEMU(anchor.getY()); - off.setX(x); - off.setY(y); - CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm - .addNewExt(); - long cx = Units.toEMU(anchor.getWidth()); - long cy = Units.toEMU(anchor.getHeight()); - ext.setCx(cx); - ext.setCy(cy); - } - - @Override - public void setRotation(double theta) { - CTTransform2D xfrm = getXfrm(true); - if (xfrm != null) { - xfrm.setRot((int) (theta * 60000)); - } - } - - @Override - public double getRotation() { - CTTransform2D xfrm = getXfrm(false); - return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d); - } - - @Override - public void setFlipHorizontal(boolean flip) { - CTTransform2D xfrm = getXfrm(true); - if (xfrm != null) { - xfrm.setFlipH(flip); - } - } - - @Override - public void setFlipVertical(boolean flip) { - CTTransform2D xfrm = getXfrm(true); - if (xfrm != null) { - xfrm.setFlipV(flip); - } - } - - @Override - public boolean getFlipHorizontal() { - CTTransform2D xfrm = getXfrm(false); - return (xfrm == null || !xfrm.isSetFlipH()) ? false : xfrm.getFlipH(); - } - - @Override - public boolean getFlipVertical() { - CTTransform2D xfrm = getXfrm(false); - return (xfrm == null || !xfrm.isSetFlipV()) ? false : xfrm.getFlipV(); - } - - - /** - * Get default line properties defined in the theme (if any). - * Used internally to resolve shape properties. - * - * @return line properties from the theme of null - */ - CTLineProperties getDefaultLineProperties() { - CTShapeStyle style = getSpStyle(); - if (style == null) return null; - CTStyleMatrixReference lnRef = style.getLnRef(); - if (lnRef == null) return null; - // 1-based index of a line style within the style matrix - int idx = (int)lnRef.getIdx(); - - XSLFTheme theme = getSheet().getTheme(); - if (theme == null) return null; - CTBaseStyles styles = theme.getXmlObject().getThemeElements(); - if (styles == null) return null; - CTStyleMatrix styleMatrix = styles.getFmtScheme(); - if (styleMatrix == null) return null; - CTLineStyleList lineStyles = styleMatrix.getLnStyleLst(); - if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) return null; - - return lineStyles.getLnArray(idx - 1); - } - - /** - * @param color the color to paint the shape outline. - * A null value turns off the shape outline. - */ - public void setLineColor(Color color) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - - if (ln.isSetSolidFill()) { - ln.unsetSolidFill(); - } - if (ln.isSetGradFill()) { - ln.unsetGradFill(); - } - if (ln.isSetPattFill()) { - ln.unsetPattFill(); - } - if (ln.isSetNoFill()) { - ln.unsetNoFill(); - } - - - if (color == null) { - ln.addNewNoFill(); - } else { - CTSolidColorFillProperties fill = ln.addNewSolidFill(); - XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); - col.setColor(color); - } - } - - /** - * - * @return the color of the shape outline or null - * if outline is turned off - */ - public Color getLineColor() { - PaintStyle ps = getLinePaint(); - if (ps instanceof SolidPaint) { - return ((SolidPaint)ps).getSolidColor().getColor(); - } - return null; - } - - protected PaintStyle getLinePaint() { - XSLFSheet sheet = getSheet(); - final XSLFTheme theme = sheet.getTheme(); - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTLineProperties spPr = getLn(shape, false); - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr); - PackagePart pp = shape.getSheet().getPackagePart(); - PaintStyle paint = selectPaint(fp, null, pp, theme); - if (paint != null) { - setValue(paint); - return true; - } - - CTShapeStyle style = shape.getSpStyle(); - if (style != null) { - fp = XSLFPropertiesDelegate.getFillDelegate(style.getLnRef()); - paint = selectPaint(fp, null, pp, theme); - } - if (paint != null) { - setValue(paint); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - - PaintStyle paint = fetcher.getValue(); - if (paint != null) return paint; - - // line color was not found, check if it is defined in the theme - CTShapeStyle style = getSpStyle(); - if (style == null) return null; - - // get a reference to a line style within the style matrix. - CTStyleMatrixReference lnRef = style.getLnRef(); - int idx = (int)lnRef.getIdx(); - CTSchemeColor phClr = lnRef.getSchemeClr(); - if(idx > 0){ - CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1); - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); - PackagePart pp = sheet.getPackagePart(); - paint = selectPaint(fp, phClr, pp, theme); - } - - return paint; - } - - /** - * - * @param width line width in points. 0 means no line - */ - public void setLineWidth(double width) { - CTLineProperties lnPr = getLn(this, true); - if (lnPr == null) { - return; - } - - if (width == 0.) { - if (lnPr.isSetW()) { - lnPr.unsetW(); - } - if (!lnPr.isSetNoFill()) { - lnPr.addNewNoFill(); - } - if (lnPr.isSetSolidFill()) { - lnPr.unsetSolidFill(); - } - if (lnPr.isSetGradFill()) { - lnPr.unsetGradFill(); - } - if (lnPr.isSetPattFill()) { - lnPr.unsetPattFill(); - } - } else { - if (lnPr.isSetNoFill()) { - lnPr.unsetNoFill(); - } - - lnPr.setW(Units.toEMU(width)); - } - } - - /** - * @return line width in points. 0 means no line. - */ - public double getLineWidth() { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTLineProperties ln = getLn(shape, false); - if (ln != null) { - if (ln.isSetNoFill()) { - setValue(0.); - return true; - } - - if (ln.isSetW()) { - setValue(Units.toPoints(ln.getW())); - return true; - } - } - return false; - } - }; - fetchShapeProperty(fetcher); - - double lineWidth = 0; - if (fetcher.getValue() == null) { - CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null) { - if (defaultLn.isSetW()) lineWidth = Units.toPoints(defaultLn.getW()); - } - } else { - lineWidth = fetcher.getValue(); - } - - return lineWidth; - } - - - /** - * @param compound set the line compound style - */ - public void setLineCompound(LineCompound compound) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - if (compound == null) { - if (ln.isSetCmpd()) { - ln.unsetCmpd(); - } - } else { - STCompoundLine.Enum xCmpd; - switch (compound) { - default: - case SINGLE: - xCmpd = STCompoundLine.SNG; - break; - case DOUBLE: - xCmpd = STCompoundLine.DBL; - break; - case THICK_THIN: - xCmpd = STCompoundLine.THICK_THIN; - break; - case THIN_THICK: - xCmpd = STCompoundLine.THIN_THICK; - break; - case TRIPLE: - xCmpd = STCompoundLine.TRI; - break; - } - ln.setCmpd(xCmpd); - } - } - - /** - * @return the line compound - */ - public LineCompound getLineCompound() { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTLineProperties ln = getLn(shape, false); - if (ln != null) { - STCompoundLine.Enum stCmpd = ln.getCmpd(); - if (stCmpd != null) { - setValue(stCmpd.intValue()); - return true; - } - } - return false; - } - }; - fetchShapeProperty(fetcher); - - Integer cmpd = fetcher.getValue(); - if (cmpd == null) { - CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null && defaultLn.isSetCmpd()) { - switch (defaultLn.getCmpd().intValue()) { - default: - case STCompoundLine.INT_SNG: - return LineCompound.SINGLE; - case STCompoundLine.INT_DBL: - return LineCompound.DOUBLE; - case STCompoundLine.INT_THICK_THIN: - return LineCompound.THICK_THIN; - case STCompoundLine.INT_THIN_THICK: - return LineCompound.THIN_THICK; - case STCompoundLine.INT_TRI: - return LineCompound.TRIPLE; - } - } - } - - return null; - } - - /** - * - * @param dash a preset line dashing scheme to stroke thr shape outline - */ - public void setLineDash(LineDash dash) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - if (dash == null) { - if (ln.isSetPrstDash()) { - ln.unsetPrstDash(); - } - } else { - CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash(); - ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId)); - } - } - - /** - * @return a preset line dashing scheme to stroke the shape outline - */ - public LineDash getLineDash() { - - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTLineProperties ln = getLn(shape, false); - if (ln == null || !ln.isSetPrstDash()) { - return false; - } - - setValue(LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue())); - return true; - } - }; - fetchShapeProperty(fetcher); - - LineDash dash = fetcher.getValue(); - if (dash == null) { - CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null && defaultLn.isSetPrstDash()) { - dash = LineDash.fromOoxmlId(defaultLn.getPrstDash().getVal().intValue()); - } - } - return dash; - } - - /** - * - * @param cap the line end cap style - */ - public void setLineCap(LineCap cap) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - - if (cap == null) { - if (ln.isSetCap()) { - ln.unsetCap(); - } - } else { - ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId)); - } - } - - /** - * - * @return the line end cap style - */ - public LineCap getLineCap() { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTLineProperties ln = getLn(shape, false); - if (ln != null && ln.isSetCap()) { - setValue(LineCap.fromOoxmlId(ln.getCap().intValue())); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - - LineCap cap = fetcher.getValue(); - if (cap == null) { - CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null && defaultLn.isSetCap()) { - cap = LineCap.fromOoxmlId(defaultLn.getCap().intValue()); - } - } - return cap; - } - - @Override - public void setFillColor(Color color) { - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties()); - if (fp == null) { - return; - } - if (color == null) { - if (fp.isSetSolidFill()) { - fp.unsetSolidFill(); - } - - if (fp.isSetGradFill()) { - fp.unsetGradFill(); - } - - if (fp.isSetPattFill()) { - fp.unsetGradFill(); - } - - if (fp.isSetBlipFill()) { - fp.unsetBlipFill(); - } - - if (!fp.isSetNoFill()) { - fp.addNewNoFill(); - } - } else { - if (fp.isSetNoFill()) { - fp.unsetNoFill(); - } - - CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill(); - - XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); - col.setColor(color); - } - } - - @Override - public Color getFillColor() { - PaintStyle ps = getFillPaint(); - if (ps instanceof SolidPaint) { - return DrawPaint.applyColorTransform(((SolidPaint)ps).getSolidColor()); - } - return null; - } - - /** - * @return shadow of this shape or null if shadow is disabled - */ - public XSLFShadow getShadow() { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties()); - if (ep != null && ep.isSetEffectLst()) { - CTOuterShadowEffect obj = ep.getEffectLst().getOuterShdw(); - setValue(obj == null ? NO_SHADOW : obj); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - - CTOuterShadowEffect obj = fetcher.getValue(); - if (obj == null) { - // fill color was not found, check if it is defined in the theme - CTShapeStyle style = getSpStyle(); - if (style != null && style.getEffectRef() != null) { - // 1-based index of a shadow style within the style matrix - int idx = (int) style.getEffectRef().getIdx(); - if(idx != 0) { - CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme(); - CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1); - obj = ef.getEffectLst().getOuterShdw(); - } - } - } - return (obj == null || obj == NO_SHADOW) ? null : new XSLFShadow(obj, this); - } - - /** - * - * @return definition of the shape geometry - */ - public CustomGeometry getGeometry() { - XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); - - if (gp == null) { - return null; - } - - CustomGeometry geom; - PresetGeometries dict = PresetGeometries.getInstance(); - if(gp.isSetPrstGeom()){ - String name = gp.getPrstGeom().getPrst().toString(); - geom = dict.get(name); - if(geom == null) { - throw new IllegalStateException("Unknown shape geometry: " + name + ", available geometries are: " + dict.keySet()); - } - } else if (gp.isSetCustGeom()){ - XMLStreamReader staxReader = gp.getCustGeom().newXMLStreamReader(); - geom = PresetGeometries.convertCustomGeometry(staxReader); - try { - staxReader.close(); - } - catch (XMLStreamException e) { - LOG.log(POILogger.WARN, - "An error occurred while closing a Custom Geometry XML Stream Reader: " + e.getMessage()); - } - } else { - geom = dict.get("rect"); - } - return geom; - } - - @Override - void copy(XSLFShape sh){ - super.copy(sh); - - XSLFSimpleShape s = (XSLFSimpleShape)sh; - - Color srsSolidFill = s.getFillColor(); - Color tgtSoliFill = getFillColor(); - if(srsSolidFill != null && !srsSolidFill.equals(tgtSoliFill)){ - setFillColor(srsSolidFill); - } - - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties()); - if(fp != null && fp.isSetBlipFill()){ - CTBlip blip = fp.getBlipFill().getBlip(); - String blipId = blip.getEmbed(); - - String relId = getSheet().importBlip(blipId, s.getSheet().getPackagePart()); - blip.setEmbed(relId); - } - - Color srcLineColor = s.getLineColor(); - Color tgtLineColor = getLineColor(); - if(srcLineColor != null && !srcLineColor.equals(tgtLineColor)) { - setLineColor(srcLineColor); - } - - double srcLineWidth = s.getLineWidth(); - double tgtLineWidth = getLineWidth(); - if(srcLineWidth != tgtLineWidth) { - setLineWidth(srcLineWidth); - } - - LineDash srcLineDash = s.getLineDash(); - LineDash tgtLineDash = getLineDash(); - if(srcLineDash != null && srcLineDash != tgtLineDash) { - setLineDash(srcLineDash); - } - - LineCap srcLineCap = s.getLineCap(); - LineCap tgtLineCap = getLineCap(); - if(srcLineCap != null && srcLineCap != tgtLineCap) { - setLineCap(srcLineCap); - } - - } - - /** - * Specifies the line end decoration, such as a triangle or arrowhead. - * - * @param style the line end docoration style - */ - public void setLineHeadDecoration(DecorationShape style) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); - if (style == null) { - if (lnEnd.isSetType()) { - lnEnd.unsetType(); - } - } else { - lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId)); - } - } - - /** - * @return the line end decoration shape - */ - public DecorationShape getLineHeadDecoration() { - CTLineProperties ln = getLn(this, false); - DecorationShape ds = DecorationShape.NONE; - if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetType()) { - ds = DecorationShape.fromOoxmlId(ln.getHeadEnd().getType().intValue()); - } - return ds; - } - - /** - * specifies decoration width of the head of a line. - * - * @param style the decoration width - */ - public void setLineHeadWidth(DecorationSize style) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); - if (style == null) { - if (lnEnd.isSetW()) { - lnEnd.unsetW(); - } - } else { - lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId)); - } - } - - /** - * @return the line end decoration width - */ - public DecorationSize getLineHeadWidth() { - CTLineProperties ln = getLn(this, false); - DecorationSize ds = DecorationSize.MEDIUM; - if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetW()) { - ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getW().intValue()); - } - return ds; - } - - /** - * Specifies the line end width in relation to the line width. - */ - public void setLineHeadLength(DecorationSize style) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - - CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); - if (style == null) { - if (lnEnd.isSetLen()) { - lnEnd.unsetLen(); - } - } else { - lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId)); - } - } - - /** - * @return the line end decoration length - */ - public DecorationSize getLineHeadLength() { - CTLineProperties ln = getLn(this, false); - - DecorationSize ds = DecorationSize.MEDIUM; - if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetLen()) { - ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getLen().intValue()); - } - return ds; - } - - /** - * Specifies the line end decoration, such as a triangle or arrowhead. - */ - public void setLineTailDecoration(DecorationShape style) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - - CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); - if (style == null) { - if (lnEnd.isSetType()) { - lnEnd.unsetType(); - } - } else { - lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId)); - } - } - - /** - * @return the line end decoration shape - */ - public DecorationShape getLineTailDecoration() { - CTLineProperties ln = getLn(this, false); - - DecorationShape ds = DecorationShape.NONE; - if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetType()) { - ds = DecorationShape.fromOoxmlId(ln.getTailEnd().getType().intValue()); - } - return ds; - } - - /** - * specifies decorations which can be added to the tail of a line. - */ - public void setLineTailWidth(DecorationSize style) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - - CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); - if (style == null) { - if (lnEnd.isSetW()) { - lnEnd.unsetW(); - } - } else { - lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId)); - } - } - - /** - * @return the line end decoration width - */ - public DecorationSize getLineTailWidth() { - CTLineProperties ln = getLn(this, false); - DecorationSize ds = DecorationSize.MEDIUM; - if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetW()) { - ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getW().intValue()); - } - return ds; - } - - /** - * Specifies the line end width in relation to the line width. - */ - public void setLineTailLength(DecorationSize style) { - CTLineProperties ln = getLn(this, true); - if (ln == null) { - return; - } - - CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); - if (style == null) { - if (lnEnd.isSetLen()) { - lnEnd.unsetLen(); - } - } else { - lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId)); - } - } - - /** - * @return the line end decoration length - */ - public DecorationSize getLineTailLength() { - CTLineProperties ln = getLn(this, false); - - DecorationSize ds = DecorationSize.MEDIUM; - if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetLen()) { - ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getLen().intValue()); - } - return ds; - } - - public boolean isPlaceholder() { - CTPlaceholder ph = getCTPlaceholder(); - return ph != null; - } - - public Guide getAdjustValue(String name) { - XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); - - if (gp != null && gp.isSetPrstGeom() && gp.getPrstGeom().isSetAvLst()) { - for (CTGeomGuide g : gp.getPrstGeom().getAvLst().getGdArray()) { - if (g.getName().equals(name)) { - return new Guide(g.getName(), g.getFmla()); - } - } - } - - return null; - } - - public LineDecoration getLineDecoration() { - return new LineDecoration() { - public DecorationShape getHeadShape() { - return getLineHeadDecoration(); - } - - public DecorationSize getHeadWidth() { - return getLineHeadWidth(); - } - - public DecorationSize getHeadLength() { - return getLineHeadLength(); - } - - public DecorationShape getTailShape() { - return getLineTailDecoration(); - } - - public DecorationSize getTailWidth() { - return getLineTailWidth(); - } - - public DecorationSize getTailLength() { - return getLineTailLength(); - } - }; - } - - /** - * fetch shape fill as a java.awt.Paint - * - * @return either Color or GradientPaint or TexturePaint or null - */ - public FillStyle getFillStyle() { - return new FillStyle() { - public PaintStyle getPaint() { - return XSLFSimpleShape.this.getFillPaint(); - } - }; - } - - public StrokeStyle getStrokeStyle() { - return new StrokeStyle() { - public PaintStyle getPaint() { - return XSLFSimpleShape.this.getLinePaint(); - } - - public LineCap getLineCap() { - return XSLFSimpleShape.this.getLineCap(); - } - - public LineDash getLineDash() { - return XSLFSimpleShape.this.getLineDash(); - } - - public double getLineWidth() { - return XSLFSimpleShape.this.getLineWidth(); - } - - public LineCompound getLineCompound() { - return XSLFSimpleShape.this.getLineCompound(); - } - - }; - } - - @Override - public void setStrokeStyle(Object... styles) { - if (styles.length == 0) { - // remove stroke - setLineColor(null); - return; - } - - // TODO: handle PaintStyle - for (Object st : styles) { - if (st instanceof Number) { - setLineWidth(((Number)st).doubleValue()); - } else if (st instanceof LineCap) { - setLineCap((LineCap)st); - } else if (st instanceof LineDash) { - setLineDash((LineDash)st); - } else if (st instanceof LineCompound) { - setLineCompound((LineCompound)st); - } else if (st instanceof Color) { - setLineColor((Color)st); - } - } - } - - @Override - public void setPlaceholder(Placeholder placeholder) { - super.setPlaceholder(placeholder); - } - - @Override - public XSLFHyperlink getHyperlink() { - CTNonVisualDrawingProps cNvPr = getCNvPr(); - if (!cNvPr.isSetHlinkClick()) { - return null; - } - return new XSLFHyperlink(cNvPr.getHlinkClick(), getSheet()); - } - - @Override - public XSLFHyperlink createHyperlink() { - XSLFHyperlink hl = getHyperlink(); - if (hl == null) { - CTNonVisualDrawingProps cNvPr = getCNvPr(); - hl = new XSLFHyperlink(cNvPr.addNewHlinkClick(), getSheet()); - } - return hl; - } - - private static CTLineProperties getLn(XSLFShape shape, boolean create) { - XmlObject pr = shape.getShapeProperties(); - if (!(pr instanceof CTShapeProperties)) { - LOG.log(POILogger.WARN, shape.getClass().toString()+" doesn't have line properties"); - return null; - } - - CTShapeProperties spr = (CTShapeProperties)pr; - return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java deleted file mode 100644 index 66ec5e176..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java +++ /dev/null @@ -1,320 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.awt.Graphics2D; -import java.io.IOException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.Drawable; -import org.apache.poi.sl.usermodel.Notes; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.util.Beta; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.NotImplemented; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; -import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -@Beta -public final class XSLFSlide extends XSLFSheet -implements Slide { - private final CTSlide _slide; - private XSLFSlideLayout _layout; - private XSLFComments _comments; - private XSLFNotes _notes; - - /** - * Create a new slide - */ - XSLFSlide() { - super(); - _slide = prototype(); - setCommonSlideData(_slide.getCSld()); - } - - /** - * Construct a SpreadsheetML slide from a package part - * - * @param part the package part holding the slide data, - * the content type must be application/vnd.openxmlformats-officedocument.slide+xml - * - * @since POI 3.14-Beta1 - */ - XSLFSlide(PackagePart part) throws IOException, XmlException { - super(part); - - Document _doc; - try { - _doc = DocumentHelper.readDocument(getPackagePart().getInputStream()); - } catch (SAXException e) { - throw new IOException(e); - } - - SldDocument doc = SldDocument.Factory.parse(_doc, DEFAULT_XML_OPTIONS); - _slide = doc.getSld(); - setCommonSlideData(_slide.getCSld()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - XSLFSlide(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - - private static CTSlide prototype(){ - CTSlide ctSlide = CTSlide.Factory.newInstance(); - CTCommonSlideData cSld = ctSlide.addNewCSld(); - CTGroupShape spTree = cSld.addNewSpTree(); - - CTGroupShapeNonVisual nvGrpSpPr = spTree.addNewNvGrpSpPr(); - CTNonVisualDrawingProps cnvPr = nvGrpSpPr.addNewCNvPr(); - cnvPr.setId(1); - cnvPr.setName(""); - nvGrpSpPr.addNewCNvGrpSpPr(); - nvGrpSpPr.addNewNvPr(); - - CTGroupShapeProperties grpSpr = spTree.addNewGrpSpPr(); - CTGroupTransform2D xfrm = grpSpr.addNewXfrm(); - CTPoint2D off = xfrm.addNewOff(); - off.setX(0); - off.setY(0); - CTPositiveSize2D ext = xfrm.addNewExt(); - ext.setCx(0); - ext.setCy(0); - CTPoint2D choff = xfrm.addNewChOff(); - choff.setX(0); - choff.setY(0); - CTPositiveSize2D chExt = xfrm.addNewChExt(); - chExt.setCx(0); - chExt.setCy(0); - ctSlide.addNewClrMapOvr().addNewMasterClrMapping(); - return ctSlide; - } - - @Override - public CTSlide getXmlObject() { - return _slide; - } - - @Override - protected String getRootElementName(){ - return "sld"; - } - - public XSLFSlideLayout getMasterSheet(){ - return getSlideLayout(); - } - - public XSLFSlideLayout getSlideLayout(){ - if(_layout == null){ - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFSlideLayout){ - _layout = (XSLFSlideLayout)p; - } - } - } - if(_layout == null) { - throw new IllegalArgumentException("SlideLayout was not found for " + this.toString()); - } - return _layout; - } - - public XSLFSlideMaster getSlideMaster(){ - return getSlideLayout().getSlideMaster(); - } - - public XSLFComments getComments() { - if(_comments == null) { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFComments) { - _comments = (XSLFComments)p; - } - } - } - if(_comments == null) { - // This slide lacks comments - // Not all have them, sorry... - return null; - } - return _comments; - } - - public XSLFNotes getNotes() { - if(_notes == null) { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFNotes){ - _notes = (XSLFNotes)p; - } - } - } - if(_notes == null) { - // This slide lacks notes - // Not all have them, sorry... - return null; - } - return _notes; - } - - @Override - public String getTitle(){ - XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE); - return txt == null ? null : txt.getText(); - } - - @Override - public XSLFTheme getTheme(){ - return getSlideLayout().getSlideMaster().getTheme(); - } - - /** - * - * @return the information about background appearance of this slide - */ - @Override - public XSLFBackground getBackground() { - CTBackground bg = _slide.getCSld().getBg(); - if(bg != null) { - return new XSLFBackground(bg, this); - } else { - return getMasterSheet().getBackground(); - } - } - - @Override - public boolean getFollowMasterGraphics(){ - return _slide.isSetShowMasterSp() && _slide.getShowMasterSp(); - } - - /** - * - * @param value whether shapes on the master slide should be shown or not. - */ - public void setFollowMasterGraphics(boolean value){ - _slide.setShowMasterSp(value); - } - - - public boolean getFollowMasterObjects() { - return getFollowMasterGraphics(); - } - - public void setFollowMasterObjects(boolean follow) { - setFollowMasterGraphics(follow); - } - - @Override - public XSLFSlide importContent(XSLFSheet src){ - super.importContent(src); - if (!(src instanceof XSLFSlide)) { - return this; - } - - // only copy direct backgrounds - not backgrounds of master sheet - CTBackground bgOther = ((XSLFSlide)src)._slide.getCSld().getBg(); - if (bgOther == null) { - return this; - } - - CTBackground bgThis = _slide.getCSld().getBg(); - // remove existing background - if (bgThis != null) { - if (bgThis.isSetBgPr() && bgThis.getBgPr().isSetBlipFill()) { - String oldId = bgThis.getBgPr().getBlipFill().getBlip().getEmbed(); - removeRelation(getRelationById(oldId)); - } - _slide.getCSld().unsetBg(); - } - - bgThis = (CTBackground)_slide.getCSld().addNewBg().set(bgOther); - - if(bgOther.isSetBgPr() && bgOther.getBgPr().isSetBlipFill()){ - String idOther = bgOther.getBgPr().getBlipFill().getBlip().getEmbed(); - String idThis = importBlip(idOther, src.getPackagePart()); - bgThis.getBgPr().getBlipFill().getBlip().setEmbed(idThis); - - } - - return this; - } - - public boolean getFollowMasterBackground() { - return false; - } - - @NotImplemented - public void setFollowMasterBackground(boolean follow) { - // not implemented ... also not in the specs - throw new UnsupportedOperationException(); - } - - public boolean getFollowMasterColourScheme() { - return false; - } - - @NotImplemented - public void setFollowMasterColourScheme(boolean follow) { - // not implemented ... only for OLE objects in the specs - throw new UnsupportedOperationException(); - } - - @Override - @NotImplemented - public void setNotes(Notes notes) { - assert(notes instanceof XSLFNotes); - // TODO Auto-generated method stub - } - - @Override - public int getSlideNumber() { - int idx = getSlideShow().getSlides().indexOf(this); - return (idx == -1) ? idx : idx+1; - } - - /** - * Render this sheet into the supplied graphics object - * - * @param graphics - */ - @Override - public void draw(Graphics2D graphics){ - DrawFactory drawFact = DrawFactory.getInstance(graphics); - Drawable draw = drawFact.getDrawable(this); - draw.draw(graphics); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java deleted file mode 100644 index 15a4a169e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java +++ /dev/null @@ -1,178 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout; -import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument; - -@Beta -public class XSLFSlideLayout extends XSLFSheet -implements MasterSheet { - private CTSlideLayout _layout; - private XSLFSlideMaster _master; - - XSLFSlideLayout() { - super(); - _layout = CTSlideLayout.Factory.newInstance(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XSLFSlideLayout(PackagePart part) throws IOException, XmlException { - super(part); - SldLayoutDocument doc = - SldLayoutDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _layout = doc.getSldLayout(); - setCommonSlideData(_layout.getCSld()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSLFSlideLayout(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - public String getName() { - return _layout.getCSld().getName(); - } - - /** - * While developing only! - */ - @Internal - public CTSlideLayout getXmlObject() { - return _layout; - } - - @Override - protected String getRootElementName() { - return "sldLayout"; - } - - /** - * Slide master object associated with this layout. - * - * @return slide master. Never null. - * @throws IllegalStateException if slide master was not found - */ - public XSLFSlideMaster getSlideMaster() { - if (_master == null) { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFSlideMaster) { - _master = (XSLFSlideMaster) p; - } - } - } - if (_master == null) { - throw new IllegalStateException("SlideMaster was not found for " + this.toString()); - } - return _master; - } - - @Override - public XSLFSlideMaster getMasterSheet() { - return getSlideMaster(); - } - - @Override - public XSLFTheme getTheme() { - return getSlideMaster().getTheme(); - } - - - @Override - public boolean getFollowMasterGraphics() { - return _layout.isSetShowMasterSp() && _layout.getShowMasterSp(); - } - - /** - * Render this sheet into the supplied graphics object - */ - @Override - protected boolean canDraw(XSLFShape shape) { - if (shape instanceof XSLFSimpleShape) { - XSLFSimpleShape txt = (XSLFSimpleShape) shape; - CTPlaceholder ph = txt.getCTPlaceholder(); - if (ph != null) { - return false; - } - } - return true; - } - - - @Override - public XSLFBackground getBackground() { - CTBackground bg = _layout.getCSld().getBg(); - if(bg != null) { - return new XSLFBackground(bg, this); - } else { - return getMasterSheet().getBackground(); - } - } - - /** - * Copy placeholders from this layout to the destination slide - * - * @param slide destination slide - */ - public void copyLayout(XSLFSlide slide) { - for (XSLFShape sh : getShapes()) { - if (sh instanceof XSLFTextShape) { - XSLFTextShape tsh = (XSLFTextShape) sh; - Placeholder ph = tsh.getTextType(); - if (ph == null) continue; - - switch (ph) { - // these are special and not copied by default - case DATETIME: - case SLIDE_NUMBER: - case FOOTER: - break; - default: - slide.getSpTree().addNewSp().set(tsh.getXmlObject().copy()); - } - } - } - } - - /** - * - * @return type of this layout - */ - public SlideLayout getType(){ - int ordinal = _layout.getType().intValue() - 1; - return SlideLayout.values()[ordinal]; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java deleted file mode 100644 index ae6c40936..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java +++ /dev/null @@ -1,216 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterTextStyles; -import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; - -/** -* Slide master object associated with this layout. -*

        -* Within a slide master slide are contained all elements -* that describe the objects and their corresponding formatting -* for within a presentation slide. -*

        -*

        -* Within a slide master slide are two main elements. -* The cSld element specifies the common slide elements such as shapes and -* their attached text bodies. Then the txStyles element specifies the -* formatting for the text within each of these shapes. The other properties -* within a slide master slide specify other properties for within a presentation slide -* such as color information, headers and footers, as well as timing and -* transition information for all corresponding presentation slides. -*

        - * - * @author Yegor Kozlov -*/ -@Beta - public class XSLFSlideMaster extends XSLFSheet - implements MasterSheet { - private CTSlideMaster _slide; - private Map _layouts; - private XSLFTheme _theme; - - XSLFSlideMaster() { - super(); - _slide = CTSlideMaster.Factory.newInstance(); - } - - /** - * @since POI 3.14-Beta1 - */ - protected XSLFSlideMaster(PackagePart part) throws IOException, XmlException { - super(part); - SldMasterDocument doc = - SldMasterDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _slide = doc.getSldMaster(); - setCommonSlideData(_slide.getCSld()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSLFSlideMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - @Override - public CTSlideMaster getXmlObject() { - return _slide; - } - - @Override - protected String getRootElementName(){ - return "sldMaster"; - } - - @Override - public XSLFSlideMaster getMasterSheet() { - return null; - } - - private Map getLayouts(){ - if(_layouts == null){ - _layouts = new HashMap(); - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFSlideLayout){ - XSLFSlideLayout layout = (XSLFSlideLayout)p; - _layouts.put(layout.getName().toLowerCase(Locale.ROOT), layout); - } - } - } - return _layouts; - } - - /** - * - * @return all slide layouts referencing this master - */ - public XSLFSlideLayout[] getSlideLayouts() { - return getLayouts().values().toArray(new XSLFSlideLayout[_layouts.size()]); - } - - /** - * Get the slide layout by type. - * - * @param type The layout type. Cannot be null. - * - * @return the layout found or null on failure - */ - public XSLFSlideLayout getLayout(SlideLayout type){ - for(XSLFSlideLayout layout : getLayouts().values()){ - if(layout.getType() == type) { - return layout; - } - } - return null; - } - - /** - * Get the slide layout by name. - * - * @param name The layout name (case-insensitive). Cannot be null. - * - * @return the layout found or null on failure - */ - public XSLFSlideLayout getLayout(String name) { - return getLayouts().get(name.toLowerCase(Locale.ROOT)); - } - - - @Override - public XSLFTheme getTheme(){ - if(_theme == null){ - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFTheme){ - _theme = (XSLFTheme)p; - CTColorMapping cmap = _slide.getClrMap(); - if(cmap != null){ - _theme.initColorMap(cmap); - } - break; - } - } - } - return _theme; - } - - protected CTTextListStyle getTextProperties(Placeholder textType) { - CTTextListStyle props; - CTSlideMasterTextStyles txStyles = getXmlObject().getTxStyles(); - switch (textType){ - case TITLE: - case CENTERED_TITLE: - case SUBTITLE: - props = txStyles.getTitleStyle(); - break; - case BODY: - props = txStyles.getBodyStyle(); - break; - default: - props = txStyles.getOtherStyle(); - break; - } - return props; - } - - /** - * Render this sheet into the supplied graphics object - * - */ - @Override - protected boolean canDraw(XSLFShape shape){ - if(shape instanceof XSLFSimpleShape){ - XSLFSimpleShape txt = (XSLFSimpleShape)shape; - CTPlaceholder ph = txt.getCTPlaceholder(); - if(ph != null) { - return false; - } - } - return true; - } - - @Override - public XSLFBackground getBackground() { - CTBackground bg = _slide.getCSld().getBg(); - if(bg != null) { - return new XSLFBackground(bg, this); - } else { - return null; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShow.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShow.java deleted file mode 100644 index 8a49e3943..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShow.java +++ /dev/null @@ -1,263 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList; -import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry; -import org.openxmlformats.schemas.presentationml.x2006.main.CmLstDocument; -import org.openxmlformats.schemas.presentationml.x2006.main.NotesDocument; -import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument; -import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument; -import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; - -/** - * Experimental class to do low level processing of pptx files. - * - * Most users should use the higher level {@link XMLSlideShow} instead. - * - * If you are using these low level classes, then you - * will almost certainly need to refer to the OOXML - * specifications from - * http://www.ecma-international.org/publications/standards/Ecma-376.htm - * - * WARNING - APIs expected to change rapidly - */ -public class XSLFSlideShow extends POIXMLDocument { - - private PresentationDocument presentationDoc; - /** - * The embedded OLE2 files in the OPC package - */ - private List embedds; - - public XSLFSlideShow(OPCPackage container) throws OpenXML4JException, IOException, XmlException { - super(container); - - if(getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) { - rebase(getPackage()); - } - - presentationDoc = - PresentationDocument.Factory.parse(getCorePart().getInputStream(), DEFAULT_XML_OPTIONS); - - embedds = new LinkedList(); - for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdArray()) { - PackagePart corePart = getCorePart(); - PackagePart slidePart = corePart.getRelatedPart(corePart.getRelationship(ctSlide.getId2())); - - for(PackageRelationship rel : slidePart.getRelationshipsByType(OLE_OBJECT_REL_TYPE)) { - if (TargetMode.EXTERNAL == rel.getTargetMode()) { - continue; - } - // TODO: Add this reference to each slide as well - embedds.add(slidePart.getRelatedPart(rel)); - } - - for (PackageRelationship rel : slidePart.getRelationshipsByType(PACK_OBJECT_REL_TYPE)) { - embedds.add(slidePart.getRelatedPart(rel)); - } - } - } - public XSLFSlideShow(String file) throws OpenXML4JException, IOException, XmlException { - this(openPackage(file)); - } - - /** - * Returns the low level presentation base object - */ - @Internal - public CTPresentation getPresentation() { - return presentationDoc.getPresentation(); - } - - /** - * Returns the references from the presentation to its - * slides. - * You'll need these to figure out the slide ordering, - * and to get at the actual slides themselves - */ - @Internal - public CTSlideIdList getSlideReferences() { - if(! getPresentation().isSetSldIdLst()) { - getPresentation().setSldIdLst(CTSlideIdList.Factory.newInstance()); - } - return getPresentation().getSldIdLst(); - } - - /** - * Returns the references from the presentation to its - * slide masters. - * You'll need these to get at the actual slide - * masters themselves - */ - @Internal - public CTSlideMasterIdList getSlideMasterReferences() { - return getPresentation().getSldMasterIdLst(); - } - - public PackagePart getSlideMasterPart(CTSlideMasterIdListEntry master) throws IOException, XmlException { - try { - PackagePart corePart = getCorePart(); - return corePart.getRelatedPart( - corePart.getRelationship(master.getId2()) - ); - } catch(InvalidFormatException e) { - throw new XmlException(e); - } - } - /** - * Returns the low level slide master object from - * the supplied slide master reference - */ - @Internal - public CTSlideMaster getSlideMaster(CTSlideMasterIdListEntry master) throws IOException, XmlException { - PackagePart masterPart = getSlideMasterPart(master); - SldMasterDocument masterDoc = - SldMasterDocument.Factory.parse(masterPart.getInputStream(), DEFAULT_XML_OPTIONS); - return masterDoc.getSldMaster(); - } - - public PackagePart getSlidePart(CTSlideIdListEntry slide) throws IOException, XmlException { - try { - PackagePart corePart = getCorePart(); - return corePart.getRelatedPart(corePart.getRelationship(slide.getId2())); - } catch(InvalidFormatException e) { - throw new XmlException(e); - } - } - /** - * Returns the low level slide object from - * the supplied slide reference - */ - @Internal - public CTSlide getSlide(CTSlideIdListEntry slide) throws IOException, XmlException { - PackagePart slidePart = getSlidePart(slide); - SldDocument slideDoc = - SldDocument.Factory.parse(slidePart.getInputStream(), DEFAULT_XML_OPTIONS); - return slideDoc.getSld(); - } - - /** - * Gets the PackagePart of the notes for the - * given slide, or null if there isn't one. - */ - public PackagePart getNodesPart(CTSlideIdListEntry parentSlide) throws IOException, XmlException { - PackageRelationshipCollection notes; - PackagePart slidePart = getSlidePart(parentSlide); - - try { - notes = slidePart.getRelationshipsByType(XSLFRelation.NOTES.getRelation()); - } catch(InvalidFormatException e) { - throw new IllegalStateException(e); - } - - if(notes.size() == 0) { - // No notes for this slide - return null; - } - if(notes.size() > 1) { - throw new IllegalStateException("Expecting 0 or 1 notes for a slide, but found " + notes.size()); - } - - try { - return slidePart.getRelatedPart(notes.getRelationship(0)); - } catch(InvalidFormatException e) { - throw new IllegalStateException(e); - } - } - /** - * Returns the low level notes object for the given - * slide, as found from the supplied slide reference - */ - @Internal - public CTNotesSlide getNotes(CTSlideIdListEntry slide) throws IOException, XmlException { - PackagePart notesPart = getNodesPart(slide); - if(notesPart == null) - return null; - - NotesDocument notesDoc = - NotesDocument.Factory.parse(notesPart.getInputStream(), DEFAULT_XML_OPTIONS); - - return notesDoc.getNotes(); - } - - /** - * Returns all the comments for the given slide - */ - @Internal - public CTCommentList getSlideComments(CTSlideIdListEntry slide) throws IOException, XmlException { - PackageRelationshipCollection commentRels; - PackagePart slidePart = getSlidePart(slide); - - try { - commentRels = slidePart.getRelationshipsByType(XSLFRelation.COMMENTS.getRelation()); - } catch(InvalidFormatException e) { - throw new IllegalStateException(e); - } - - if(commentRels.size() == 0) { - // No comments for this slide - return null; - } - if(commentRels.size() > 1) { - throw new IllegalStateException("Expecting 0 or 1 comments for a slide, but found " + commentRels.size()); - } - - try { - PackagePart cPart = slidePart.getRelatedPart( - commentRels.getRelationship(0) - ); - CmLstDocument commDoc = - CmLstDocument.Factory.parse(cPart.getInputStream(), DEFAULT_XML_OPTIONS); - return commDoc.getCmLst(); - } catch(InvalidFormatException e) { - throw new IllegalStateException(e); - } - } - - /** - * Get the document's embedded files. - */ - @Override - public List getAllEmbedds() throws OpenXML4JException { - return embedds; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java deleted file mode 100644 index 346d81b73..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.util.Internal; - -@Internal -public class XSLFSlideShowFactory extends SlideShowFactory { - - /** - * Creates a XMLSlideShow from the given OOXML Package - * - *

        Note that in order to properly release resources the - * SlideShow should be closed after use.

        - * - * @param pkg The {@link OPCPackage} opened for reading data. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException - */ - public static SlideShow createSlideShow(OPCPackage pkg) throws IOException { - try { - return new XMLSlideShow(pkg); - } catch (IllegalArgumentException ioe) { - // ensure that file handles are closed (use revert() to not re-write the file) - pkg.revert(); - //pkg.close(); - - // rethrow exception - throw ioe; - } - } - - /** - * Creates the XMLSlideShow from the given File, which must exist and be readable. - *

        Note that in order to properly release resources theSlideShow should be closed after use. - * - * @param file The file to read data from. - * @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back - * changes when the document is closed. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws EncryptedDocumentException If the wrong password is given for a protected file - */ - @SuppressWarnings("resource") - public static SlideShow createSlideShow(File file, boolean readOnly) - throws IOException, InvalidFormatException { - OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE); - return createSlideShow(pkg); - } - - /** - * Creates a XMLSlideShow from the given InputStream - * - *

        Note that in order to properly release resources the - * SlideShow should be closed after use.

        - * - * @param stream The {@link InputStream} to read data from. - * - * @return The created SlideShow - * - * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException - */ - @SuppressWarnings("resource") - public static SlideShow createSlideShow(InputStream stream) throws IOException, InvalidFormatException { - OPCPackage pkg = OPCPackage.open(stream); - return createSlideShow(pkg); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java deleted file mode 100644 index 61ab6b44d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.DrawTableShape; -import org.apache.poi.sl.draw.DrawTextShape; -import org.apache.poi.sl.usermodel.TableShape; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTable; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrameNonVisual; - -/** - * Represents a table in a .pptx presentation - */ -public class XSLFTable extends XSLFGraphicFrame implements Iterable, - TableShape { - /* package */ static final String TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table"; - /* package */ static final String DRAWINGML_URI = "http://schemas.openxmlformats.org/drawingml/2006/main"; - - private CTTable _table; - private List _rows; - - /*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){ - super(shape, sheet); - - CTGraphicalObjectData god = shape.getGraphic().getGraphicData(); - XmlCursor xc = god.newCursor(); - if (!xc.toChild(DRAWINGML_URI, "tbl")) { - throw new IllegalStateException("a:tbl element was not found in\n " + god); - } - - XmlObject xo = xc.getObject(); - // Pesky XmlBeans bug - see Bugzilla #49934 - // it never happens when using the full ooxml-schemas jar but may happen with the abridged poi-ooxml-schemas - if (xo instanceof XmlAnyTypeImpl){ - String errStr = - "Schemas (*.xsb) for CTTable can't be loaded - usually this happens when OSGI " + - "loading is used and the thread context classloader has no reference to " + - "the xmlbeans classes - use POIXMLTypeLoader.setClassLoader() to set the loader, " + - "e.g. with CTTable.class.getClassLoader()" - ; - throw new IllegalStateException(errStr); - } - _table = (CTTable)xo; - xc.dispose(); - - _rows = new ArrayList(_table.sizeOfTrArray()); - for(CTTableRow row : _table.getTrArray()) { - _rows.add(new XSLFTableRow(row, this)); - } - updateRowColIndexes(); - } - - @Override - public XSLFTableCell getCell(int row, int col) { - List rows = getRows(); - if (row < 0 || rows.size() <= row) { - return null; - } - XSLFTableRow r = rows.get(row); - if (r == null) { - // empty row - return null; - } - List cells = r.getCells(); - if (col < 0 || cells.size() <= col) { - return null; - } - // cell can be potentially empty ... - return cells.get(col); - } - - @Internal - public CTTable getCTTable(){ - return _table; - } - - @Override - public int getNumberOfColumns() { - return _table.getTblGrid().sizeOfGridColArray(); - } - - @Override - public int getNumberOfRows() { - return _table.sizeOfTrArray(); - } - - @Override - public double getColumnWidth(int idx){ - return Units.toPoints( - _table.getTblGrid().getGridColArray(idx).getW()); - } - - @Override - public void setColumnWidth(int idx, double width) { - _table.getTblGrid().getGridColArray(idx).setW(Units.toEMU(width)); - } - - @Override - public double getRowHeight(int row) { - return Units.toPoints(_table.getTrArray(row).getH()); - } - - @Override - public void setRowHeight(int row, double height) { - _table.getTrArray(row).setH(Units.toEMU(height)); - } - - public Iterator iterator(){ - return _rows.iterator(); - } - - public List getRows(){ - return Collections.unmodifiableList(_rows); - } - - public XSLFTableRow addRow(){ - CTTableRow tr = _table.addNewTr(); - XSLFTableRow row = new XSLFTableRow(tr, this); - // default height is 20 points - row.setHeight(20.0); - _rows.add(row); - updateRowColIndexes(); - return row; - } - - static CTGraphicalObjectFrame prototype(int shapeId){ - CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance(); - CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr(); - - CTNonVisualDrawingProps cnv = nvGr.addNewCNvPr(); - cnv.setName("Table " + shapeId); - cnv.setId(shapeId + 1); - nvGr.addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoGrp(true); - nvGr.addNewNvPr(); - - frame.addNewXfrm(); - CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData(); - XmlCursor grCur = gr.newCursor(); - grCur.toNextToken(); - grCur.beginElement(new QName(DRAWINGML_URI, "tbl")); - - CTTable tbl = CTTable.Factory.newInstance(); - tbl.addNewTblPr(); - tbl.addNewTblGrid(); - XmlCursor tblCur = tbl.newCursor(); - - tblCur.moveXmlContents(grCur); - tblCur.dispose(); - grCur.dispose(); - gr.setUri(TABLE_URI); - return frame; - } - - /** - * Merge cells of a table - */ - public void mergeCells(int firstRow, int lastRow, int firstCol, int lastCol) { - - if(firstRow > lastRow) { - throw new IllegalArgumentException( - "Cannot merge, first row > last row : " - + firstRow + " > " + lastRow - ); - } - - if(firstCol > lastCol) { - throw new IllegalArgumentException( - "Cannot merge, first column > last column : " - + firstCol + " > " + lastCol - ); - } - - int rowSpan = (lastRow - firstRow) + 1; - boolean mergeRowRequired = rowSpan > 1; - - int colSpan = (lastCol - firstCol) + 1; - boolean mergeColumnRequired = colSpan > 1; - - for(int i = firstRow; i <= lastRow; i++) { - - XSLFTableRow row = _rows.get(i); - - for(int colPos = firstCol; colPos <= lastCol; colPos++) { - - XSLFTableCell cell = row.getCells().get(colPos); - - if(mergeRowRequired) { - if(i == firstRow) { - cell.setRowSpan(rowSpan); - } else { - cell.setVMerge(true); - } - } - if(mergeColumnRequired) { - if(colPos == firstCol) { - cell.setGridSpan(colSpan); - } else { - cell.setHMerge(true); - } - } - } - } - } - - /** - * Get assigned TableStyle - * - * @return the assigned TableStyle - * - * @since POI 3.15-beta2 - */ - protected XSLFTableStyle getTableStyle() { - CTTable tab = getCTTable(); - // TODO: support inline table style - if (!tab.isSetTblPr() || !tab.getTblPr().isSetTableStyleId()) { - return null; - } - - String styleId = tab.getTblPr().getTableStyleId(); - XSLFTableStyles styles = getSheet().getSlideShow().getTableStyles(); - for (XSLFTableStyle style : styles.getStyles()) { - if (style.getStyleId().equals(styleId)) { - return style; - } - } - return null; - } - - /* package */ void updateRowColIndexes() { - int rowIdx = 0; - for (XSLFTableRow xr : this) { - int colIdx = 0; - for (XSLFTableCell tc : xr) { - tc.setRowColIndex(rowIdx, colIdx); - colIdx++; - } - rowIdx++; - } - } - - /* package */ void updateCellAnchor() { - int rows = getNumberOfRows(); - int cols = getNumberOfColumns(); - - double colWidths[] = new double[cols]; - double rowHeights[] = new double[rows]; - - for (int row=0; row { - private CTTableCellProperties _tcPr = null; - private final XSLFTable table; - private int row = 0, col = 0; - - /** - * Volatile/temporary anchor - e.g. for rendering - */ - private Rectangle2D anchor = null; - - /*package*/ XSLFTableCell(CTTableCell cell, XSLFTable table){ - super(cell, table.getSheet()); - this.table = table; - } - - @Override - protected CTTextBody getTextBody(boolean create){ - CTTableCell cell = getCell(); - CTTextBody txBody = cell.getTxBody(); - if (txBody == null && create) { - txBody = cell.addNewTxBody(); - XSLFAutoShape.initTextBody(txBody); - } - return txBody; - } - - static CTTableCell prototype() { - CTTableCell cell = CTTableCell.Factory.newInstance(); - CTTableCellProperties pr = cell.addNewTcPr(); - pr.addNewLnL().addNewNoFill(); - pr.addNewLnR().addNewNoFill(); - pr.addNewLnT().addNewNoFill(); - pr.addNewLnB().addNewNoFill(); - return cell; - } - - protected CTTableCellProperties getCellProperties(boolean create) { - if (_tcPr == null) { - CTTableCell cell = getCell(); - _tcPr = cell.getTcPr(); - if (_tcPr == null && create) { - _tcPr = cell.addNewTcPr(); - } - } - return _tcPr; - } - - @Override - public void setLeftInset(double margin){ - CTTableCellProperties pr = getCellProperties(true); - pr.setMarL(Units.toEMU(margin)); - } - - @Override - public void setRightInset(double margin){ - CTTableCellProperties pr = getCellProperties(true); - pr.setMarR(Units.toEMU(margin)); - } - - @Override - public void setTopInset(double margin){ - CTTableCellProperties pr = getCellProperties(true); - pr.setMarT(Units.toEMU(margin)); - } - - @Override - public void setBottomInset(double margin){ - CTTableCellProperties pr = getCellProperties(true); - pr.setMarB(Units.toEMU(margin)); - } - - private CTLineProperties getCTLine(BorderEdge edge, boolean create) { - if (edge == null) { - throw new IllegalArgumentException("BorderEdge needs to be specified."); - } - - CTTableCellProperties pr = getCellProperties(create); - if (pr == null) return null; - - switch (edge) { - case bottom: - return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null); - case left: - return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null); - case top: - return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null); - case right: - return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null); - default: - return null; - } - } - - @Override - public void removeBorder(BorderEdge edge) { - CTTableCellProperties pr = getCellProperties(false); - if (pr == null) return; - switch (edge) { - case bottom: - if (pr.isSetLnB()) { - pr.unsetLnB(); - } - break; - case left: - if (pr.isSetLnL()) { - pr.unsetLnL(); - } - break; - case top: - if (pr.isSetLnT()) { - pr.unsetLnT(); - } - break; - case right: - if (pr.isSetLnR()) { - pr.unsetLnB(); - } - break; - default: - throw new IllegalArgumentException(); - } - } - - @Override - public StrokeStyle getBorderStyle(final BorderEdge edge) { - final Double width = getBorderWidth(edge); - return (width == null) ? null : new StrokeStyle() { - public PaintStyle getPaint() { - return DrawPaint.createSolidPaint(getBorderColor(edge)); - } - - public LineCap getLineCap() { - return getBorderCap(edge); - } - - public LineDash getLineDash() { - return getBorderDash(edge); - } - - public LineCompound getLineCompound() { - return getBorderCompound(edge); - } - - public double getLineWidth() { - return width; - } - }; - } - - @Override - public void setBorderStyle(BorderEdge edge, StrokeStyle style) { - if (style == null) { - throw new IllegalArgumentException("StrokeStyle needs to be specified."); - } - - LineCap cap = style.getLineCap(); - if (cap != null) { - setBorderCap(edge, cap); - } - - LineCompound compound = style.getLineCompound(); - if (compound != null) { - setBorderCompound(edge, compound); - } - - LineDash dash = style.getLineDash(); - if (dash != null) { - setBorderDash(edge, dash); - } - - double width = style.getLineWidth(); - setBorderWidth(edge, width); - } - - public Double getBorderWidth(BorderEdge edge) { - CTLineProperties ln = getCTLine(edge, false); - return (ln == null || !ln.isSetW()) ? null : Units.toPoints(ln.getW()); - } - - @Override - public void setBorderWidth(BorderEdge edge, double width) { - CTLineProperties ln = getCTLine(edge, true); - ln.setW(Units.toEMU(width)); - } - - private CTLineProperties setBorderDefaults(BorderEdge edge) { - CTLineProperties ln = getCTLine(edge, true); - if (ln.isSetNoFill()) { - ln.unsetNoFill(); - } - - if(!ln.isSetPrstDash()) { - ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID); - } - if (!ln.isSetCmpd()) { - ln.setCmpd(STCompoundLine.SNG); - } - if (!ln.isSetAlgn()) { - ln.setAlgn(STPenAlignment.CTR); - } - if (!ln.isSetCap()) { - ln.setCap(STLineCap.FLAT); - } - if (!ln.isSetRound()) { - ln.addNewRound(); - } - - if (!ln.isSetHeadEnd()) { - CTLineEndProperties hd = ln.addNewHeadEnd(); - hd.setType(STLineEndType.NONE); - hd.setW(STLineEndWidth.MED); - hd.setLen(STLineEndLength.MED); - } - - if (!ln.isSetTailEnd()) { - CTLineEndProperties tl = ln.addNewTailEnd(); - tl.setType(STLineEndType.NONE); - tl.setW(STLineEndWidth.MED); - tl.setLen(STLineEndLength.MED); - } - - return ln; - } - - @Override - public void setBorderColor(BorderEdge edge, Color color) { - if (color == null) { - throw new IllegalArgumentException("Colors need to be specified."); - } - - CTLineProperties ln = setBorderDefaults(edge); - CTSolidColorFillProperties fill = ln.addNewSolidFill(); - XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); - c.setColor(color); - } - - public Color getBorderColor(BorderEdge edge) { - CTLineProperties ln = getCTLine(edge, false); - if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null; - - CTSolidColorFillProperties fill = ln.getSolidFill(); - XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); - return c.getColor(); - } - - public LineCompound getBorderCompound(BorderEdge edge) { - CTLineProperties ln = getCTLine(edge, false); - if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) { - return null; - } - - return LineCompound.fromOoxmlId(ln.getCmpd().intValue()); - } - - @Override - public void setBorderCompound(BorderEdge edge, LineCompound compound) { - if (compound == null) { - throw new IllegalArgumentException("LineCompound need to be specified."); - } - - CTLineProperties ln = setBorderDefaults(edge); - ln.setCmpd(STCompoundLine.Enum.forInt(compound.ooxmlId)); - } - - public LineDash getBorderDash(BorderEdge edge) { - CTLineProperties ln = getCTLine(edge, false); - if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetPrstDash()) { - return null; - } - - return LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue()); - } - - @Override - public void setBorderDash(BorderEdge edge, LineDash dash) { - if (dash == null) { - throw new IllegalArgumentException("LineDash need to be specified."); - } - - CTLineProperties ln = setBorderDefaults(edge); - ln.getPrstDash().setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId)); - } - - public LineCap getBorderCap(BorderEdge edge) { - CTLineProperties ln = getCTLine(edge, false); - if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCap()) { - return null; - } - - return LineCap.fromOoxmlId(ln.getCap().intValue()); - } - - public void setBorderCap(BorderEdge edge, LineCap cap) { - if (cap == null) { - throw new IllegalArgumentException("LineCap need to be specified."); - } - - CTLineProperties ln = setBorderDefaults(edge); - ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId)); - } - - - - /** - * Specifies a solid color fill. The shape is filled entirely with the specified color. - * - * @param color the solid color fill. - * The value of null unsets the solidFIll attribute from the underlying xml - */ - @Override - public void setFillColor(Color color) { - CTTableCellProperties spPr = getCellProperties(true); - if (color == null) { - if(spPr.isSetSolidFill()) spPr.unsetSolidFill(); - } else { - CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill(); - XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); - c.setColor(color); - } - } - - /** - * - * @return solid fill color of null if not set - */ - @Override - public Color getFillColor(){ - PaintStyle ps = getFillPaint(); - if (ps instanceof SolidPaint) { - ColorStyle cs = ((SolidPaint)ps).getSolidColor(); - return DrawPaint.applyColorTransform(cs); - } - - return null; - } - - @SuppressWarnings("resource") - @Override - public PaintStyle getFillPaint() { - XSLFSheet sheet = getSheet(); - XSLFTheme theme = sheet.getTheme(); - XmlObject props = getCellProperties(false); - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); - if (fp != null) { - PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme); - if (paint != null) { - return paint; - } - } - - CTTablePartStyle tps = getTablePartStyle(null); - if (tps == null || !tps.isSetTcStyle()) { - tps = getTablePartStyle(TablePartStyle.wholeTbl); - if (tps == null || !tps.isSetTcStyle()) { - return null; - } - } - - XMLSlideShow slideShow = sheet.getSlideShow(); - CTTableStyleCellStyle tcStyle = tps.getTcStyle(); - if (tcStyle.isSetFill()) { - props = tcStyle.getFill(); - } else if (tcStyle.isSetFillRef()) { - props = tcStyle.getFillRef(); - } else { - return null; - } - - fp = XSLFPropertiesDelegate.getFillDelegate(props); - if (fp != null) { - PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme); - if (paint != null) { - return paint; - } - } - - return null; - } - - /** - * Retrieves the part style depending on the location of this cell - * - * @param tablePartStyle the part to be returned, usually this is null - * and only set when used as a helper method - * @return the table part style - */ - private CTTablePartStyle getTablePartStyle(TablePartStyle tablePartStyle) { - CTTable ct = table.getCTTable(); - if (!ct.isSetTblPr()) { - return null; - } - - CTTableProperties pr = ct.getTblPr(); - boolean bandRow = (pr.isSetBandRow() && pr.getBandRow()); - boolean firstRow = (pr.isSetFirstRow() && pr.getFirstRow()); - boolean lastRow = (pr.isSetLastRow() && pr.getLastRow()); - boolean bandCol = (pr.isSetBandCol() && pr.getBandCol()); - boolean firstCol = (pr.isSetFirstCol() && pr.getFirstCol()); - boolean lastCol = (pr.isSetLastCol() && pr.getLastCol()); - - TablePartStyle tps; - if (tablePartStyle != null) { - tps = tablePartStyle; - } else if (row == 0 && firstRow) { - tps = TablePartStyle.firstRow; - } else if (row == table.getNumberOfRows()-1 && lastRow) { - tps = TablePartStyle.lastRow; - } else if (col == 0 && firstCol) { - tps = TablePartStyle.firstCol; - } else if (col == table.getNumberOfColumns()-1 && lastCol) { - tps = TablePartStyle.lastCol; - } else { - tps = TablePartStyle.wholeTbl; - - int br = row + (firstRow ? 1 : 0); - int bc = col + (firstCol ? 1 : 0); - if (bandRow && (br & 1) == 0) { - tps = TablePartStyle.band1H; - } else if (bandCol && (bc & 1) == 0) { - tps = TablePartStyle.band1V; - } - } - - XSLFTableStyle tabStyle = table.getTableStyle(); - if (tabStyle == null) { - return null; - } - - CTTablePartStyle part = tabStyle.getTablePartStyle(tps); - return (part == null) ? tabStyle.getTablePartStyle(TablePartStyle.wholeTbl) : part; - } - - void setGridSpan(int gridSpan_) { - getCell().setGridSpan(gridSpan_); - } - - @Override - public int getGridSpan() { - CTTableCell c = getCell(); - return (c.isSetGridSpan()) ? c.getGridSpan() : 1; - } - - void setRowSpan(int rowSpan_) { - getCell().setRowSpan(rowSpan_); - } - - @Override - public int getRowSpan() { - CTTableCell c = getCell(); - return (c.isSetRowSpan()) ? c.getRowSpan() : 1; - } - - void setHMerge(boolean merge_) { - getCell().setHMerge(merge_); - } - - void setVMerge(boolean merge_) { - getCell().setVMerge(merge_); - } - - @Override - public void setVerticalAlignment(VerticalAlignment anchor){ - CTTableCellProperties cellProps = getCellProperties(true); - if(anchor == null) { - if(cellProps.isSetAnchor()) { - cellProps.unsetAnchor(); - } - } else { - cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); - } - } - - @Override - public VerticalAlignment getVerticalAlignment(){ - CTTableCellProperties cellProps = getCellProperties(false); - - VerticalAlignment align = VerticalAlignment.TOP; - if(cellProps != null && cellProps.isSetAnchor()) { - int ival = cellProps.getAnchor().intValue(); - align = VerticalAlignment.values()[ival - 1]; - } - return align; - } - - /** - * @since POI 3.15-beta2 - */ - @Override - public void setTextDirection(TextDirection orientation) { - CTTableCellProperties cellProps = getCellProperties(true); - if(orientation == null) { - if (cellProps.isSetVert()) { - cellProps.unsetVert(); - } - } else { - STTextVerticalType.Enum vt; - switch (orientation) { - default: - case HORIZONTAL: - vt = STTextVerticalType.HORZ; - break; - case VERTICAL: - vt = STTextVerticalType.VERT; - break; - case VERTICAL_270: - vt = STTextVerticalType.VERT_270; - break; - case STACKED: - vt = STTextVerticalType.WORD_ART_VERT; - break; - } - - cellProps.setVert(vt); - } - } - - /** - * @since POI 3.15-beta2 - */ - @Override - public TextDirection getTextDirection() { - CTTableCellProperties cellProps = getCellProperties(false); - - STTextVerticalType.Enum orientation; - if (cellProps != null && cellProps.isSetVert()) { - orientation = cellProps.getVert(); - } else { - orientation = STTextVerticalType.HORZ; - } - - switch (orientation.intValue()) { - default: - case STTextVerticalType.INT_HORZ: - return TextDirection.HORIZONTAL; - case STTextVerticalType.INT_VERT: - case STTextVerticalType.INT_EA_VERT: - case STTextVerticalType.INT_MONGOLIAN_VERT: - return TextDirection.VERTICAL; - case STTextVerticalType.INT_VERT_270: - return TextDirection.VERTICAL_270; - case STTextVerticalType.INT_WORD_ART_VERT: - case STTextVerticalType.INT_WORD_ART_VERT_RTL: - return TextDirection.STACKED; - } - } - - private CTTableCell getCell() { - return (CTTableCell)getXmlObject(); - } - - /* package */ void setRowColIndex(int row, int col) { - this.row = row; - this.col = col; - } - - /** - * Return a fake-xfrm which is used for calculating the text height - */ - protected CTTransform2D getXfrm() { - Rectangle2D anc = getAnchor(); - CTTransform2D xfrm = CTTransform2D.Factory.newInstance(); - CTPoint2D off = xfrm.addNewOff(); - off.setX(Units.toEMU(anc.getX())); - off.setY(Units.toEMU(anc.getY())); - CTPositiveSize2D size = xfrm.addNewExt(); - size.setCx(Units.toEMU(anc.getWidth())); - size.setCy(Units.toEMU(anc.getHeight())); - return xfrm; - } - - /** - * There's no real anchor for table cells - this method is used to temporarily store the location - * of the cell for a later retrieval, e.g. for rendering - * - * @since POI 3.15-beta2 - */ - @Override - public void setAnchor(Rectangle2D anchor) { - if (this.anchor == null) { - this.anchor = (Rectangle2D)anchor.clone(); - } else { - this.anchor.setRect(anchor); - } - } - - /** - * @since POI 3.15-beta2 - */ - @Override - public Rectangle2D getAnchor() { - if (anchor == null) { - table.updateCellAnchor(); - } - // anchor should be set, after updateCellAnchor is through - assert(anchor != null); - return anchor; - } - - /** - * @since POI 3.15-beta2 - */ - @Override - public boolean isMerged() { - CTTableCell c = getCell(); - return (c.isSetHMerge() && c.getHMerge()) || (c.isSetVMerge() && c.getVMerge()); - } - - /** - * @since POI 3.15-beta2 - */ - @Override - protected XSLFCellTextParagraph newTextParagraph(CTTextParagraph p) { - return new XSLFCellTextParagraph(p, this); - } - - @Override - protected XmlObject getShapeProperties() { - return getCellProperties(false); - } - - /** - * @since POI 3.15-beta2 - */ - private class XSLFCellTextParagraph extends XSLFTextParagraph { - protected XSLFCellTextParagraph(CTTextParagraph p, XSLFTextShape shape) { - super(p, shape); - } - - @Override - protected XSLFCellTextRun newTextRun(CTRegularTextRun r) { - return new XSLFCellTextRun(r, this); - } - } - - /** - * @since POI 3.15-beta2 - */ - private class XSLFCellTextRun extends XSLFTextRun { - protected XSLFCellTextRun(CTRegularTextRun r, XSLFTextParagraph p) { - super(r, p); - } - - @Override - public PaintStyle getFontColor(){ - CTTableStyleTextStyle txStyle = getTextStyle(); - if (txStyle == null) { - return super.getFontColor(); - } - - CTSchemeColor phClr = null; - CTFontReference fontRef = txStyle.getFontRef(); - if (fontRef != null) { - phClr = fontRef.getSchemeClr(); - } - - XSLFTheme theme = getSheet().getTheme(); - final XSLFColor c = new XSLFColor(txStyle, theme, phClr); - return DrawPaint.createSolidPaint(c.getColorStyle()); - } - - @Override - public boolean isBold() { - CTTableStyleTextStyle txStyle = getTextStyle(); - if (txStyle == null) { - return super.isBold(); - } else { - return txStyle.isSetB() && txStyle.getB().intValue() == STOnOffStyleType.INT_ON; - } - } - - @Override - public boolean isItalic() { - CTTableStyleTextStyle txStyle = getTextStyle(); - if (txStyle == null) { - return super.isItalic(); - } else { - return txStyle.isSetI() && txStyle.getI().intValue() == STOnOffStyleType.INT_ON; - } - } - - private CTTableStyleTextStyle getTextStyle() { - CTTablePartStyle tps = getTablePartStyle(null); - if (tps == null || !tps.isSetTcTxStyle()) { - tps = getTablePartStyle(TablePartStyle.wholeTbl); - } - return (tps == null) ? null : tps.getTcTxStyle(); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java deleted file mode 100644 index c4529c4aa..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.util.Units; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; - -/** - * Represents a table in a .pptx presentation - */ -public class XSLFTableRow implements Iterable { - private final CTTableRow _row; - private final List _cells; - private final XSLFTable _table; - - /*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){ - _row = row; - _table = table; - CTTableCell[] tcArray = _row.getTcArray(); - _cells = new ArrayList(tcArray.length); - for(CTTableCell cell : tcArray) { - _cells.add(new XSLFTableCell(cell, table)); - } - } - - public CTTableRow getXmlObject(){ - return _row; - } - - public Iterator iterator(){ - return _cells.iterator(); - } - - public List getCells(){ - return Collections.unmodifiableList(_cells); - } - - public double getHeight(){ - return Units.toPoints(_row.getH()); - } - - public void setHeight(double height){ - _row.setH(Units.toEMU(height)); - } - - public XSLFTableCell addCell(){ - CTTableCell c = _row.addNewTc(); - c.set(XSLFTableCell.prototype()); - XSLFTableCell cell = new XSLFTableCell(c, _table); - _cells.add(cell); - - if(_table.getNumberOfColumns() < _row.sizeOfTcArray()) { - _table.getCTTable().getTblGrid().addNewGridCol().setW(Units.toEMU(100.0)); - } - _table.updateRowColIndexes(); - return cell; - } - - /** - * Merge cells of a table row, inclusive. - * Indices are 0-based. - * - * @param firstCol 0-based index of first column to merge, inclusive - * @param lastCol 0-based index of last column to merge, inclusive - */ - public void mergeCells(int firstCol, int lastCol) - { - if (firstCol >= lastCol) { - throw new IllegalArgumentException( - "Cannot merge, first column >= last column : " - + firstCol + " >= " + lastCol - ); - } - - final int colSpan = (lastCol - firstCol) + 1; - - _cells.get(firstCol).setGridSpan(colSpan); - for (final XSLFTableCell cell : _cells.subList(firstCol+1, lastCol+1)) { - cell.setHMerge(true); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyle.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyle.java deleted file mode 100644 index b3bcdfabd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyle.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.openxmlformats.schemas.drawingml.x2006.main.CTTablePartStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyle; - -/** - * Represents a table style in a .pptx presentation - */ -public class XSLFTableStyle { - private CTTableStyle _tblStyle; - - public enum TablePartStyle { - wholeTbl, band1H, band2H, band1V, band2V, firstCol, lastCol, firstRow, lastRow, seCell, swCell, neCell, nwCell; - } - - /*package*/ XSLFTableStyle(CTTableStyle style){ - _tblStyle = style; - } - - public CTTableStyle getXmlObject(){ - return _tblStyle; - } - - public String getStyleName(){ - return _tblStyle.getStyleName(); - } - - public String getStyleId(){ - return _tblStyle.getStyleId(); - } - - /** - * @since POI 3.15-beta2 - */ - protected CTTablePartStyle getTablePartStyle(TablePartStyle tps) { - switch (tps) { - default: - case wholeTbl: - return _tblStyle.getWholeTbl(); - case band1H: - return _tblStyle.getBand1H(); - case band2H: - return _tblStyle.getBand2H(); - case band1V: - return _tblStyle.getBand1V(); - case band2V: - return _tblStyle.getBand2V(); - case firstCol: - return _tblStyle.getFirstCol(); - case lastCol: - return _tblStyle.getLastCol(); - case firstRow: - return _tblStyle.getFirstRow(); - case lastRow: - return _tblStyle.getLastRow(); - case seCell: - return _tblStyle.getSeCell(); - case swCell: - return _tblStyle.getSwCell(); - case neCell: - return _tblStyle.getNeCell(); - case nwCell: - return _tblStyle.getNwCell(); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java deleted file mode 100644 index 410f84101..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleList; -import org.openxmlformats.schemas.drawingml.x2006.main.TblStyleLstDocument; - -@Beta -public class XSLFTableStyles extends POIXMLDocumentPart implements Iterable{ - private CTTableStyleList _tblStyleLst; - private List _styles; - - public XSLFTableStyles(){ - super(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XSLFTableStyles(PackagePart part) throws IOException, XmlException { - super(part); - - InputStream is = getPackagePart().getInputStream(); - TblStyleLstDocument styleDoc = TblStyleLstDocument.Factory.parse(is); - is.close(); - _tblStyleLst = styleDoc.getTblStyleLst(); - CTTableStyle[] tblStyleArray = _tblStyleLst.getTblStyleArray(); - _styles = new ArrayList(tblStyleArray.length); - for(CTTableStyle c : tblStyleArray){ - _styles.add(new XSLFTableStyle(c)); - } - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSLFTableStyles(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - public CTTableStyleList getXmlObject(){ - return _tblStyleLst; - } - - public Iterator iterator(){ - return _styles.iterator(); - } - - public List getStyles(){ - return Collections.unmodifiableList(_styles); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java deleted file mode 100644 index bb5bd42ae..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import org.apache.poi.sl.usermodel.TextBox; -import org.apache.poi.util.Beta; -import org.openxmlformats.schemas.drawingml.x2006.main.*; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; -import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; - - -/** - * @author Yegor Kozlov - */ -@Beta -public class XSLFTextBox extends XSLFAutoShape - implements TextBox { - - /*package*/ XSLFTextBox(CTShape shape, XSLFSheet sheet){ - super(shape, sheet); - } - - /** - * - * @param shapeId 1-based shapeId - */ - static CTShape prototype(int shapeId){ - CTShape ct = CTShape.Factory.newInstance(); - CTShapeNonVisual nvSpPr = ct.addNewNvSpPr(); - CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); - cnv.setName("TextBox " + shapeId); - cnv.setId(shapeId + 1); - nvSpPr.addNewCNvSpPr().setTxBox(true); - nvSpPr.addNewNvPr(); - CTShapeProperties spPr = ct.addNewSpPr(); - CTPresetGeometry2D prst = spPr.addNewPrstGeom(); - prst.setPrst(STShapeType.RECT); - prst.addNewAvLst(); - CTTextBody txBody = ct.addNewTxBody(); - XSLFAutoShape.initTextBody(txBody); - - return ct; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java deleted file mode 100644 index 38c298275..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ /dev/null @@ -1,1079 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.AutoNumberingScheme; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.apache.poi.xslf.model.ParagraphPropertyFetcher; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextFontAlignType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; - -/** - * Represents a paragraph of text within the containing text body. - * The paragraph is the highest level text separation mechanism. - * - * @since POI-3.8 - */ -@Beta -public class XSLFTextParagraph implements TextParagraph { - private final CTTextParagraph _p; - private final List _runs; - private final XSLFTextShape _shape; - - XSLFTextParagraph(CTTextParagraph p, XSLFTextShape shape){ - _p = p; - _runs = new ArrayList(); - _shape = shape; - - for(XmlObject ch : _p.selectPath("*")){ - if(ch instanceof CTRegularTextRun){ - CTRegularTextRun r = (CTRegularTextRun)ch; - _runs.add(newTextRun(r)); - } else if (ch instanceof CTTextLineBreak){ - CTTextLineBreak br = (CTTextLineBreak)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(br.getRPr()); - r.setT("\n"); - _runs.add(newTextRun(r)); - } else if (ch instanceof CTTextField){ - CTTextField f = (CTTextField)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(f.getRPr()); - r.setT(f.getT()); - _runs.add(newTextRun(r)); - } - } - } - - public String getText(){ - StringBuilder out = new StringBuilder(); - for (XSLFTextRun r : _runs) { - out.append(r.getRawText()); - } - return out.toString(); - } - - String getRenderableText(){ - StringBuilder out = new StringBuilder(); - for (XSLFTextRun r : _runs) { - out.append(r.getRenderableText()); - } - return out.toString(); - } - - @Internal - public CTTextParagraph getXmlObject(){ - return _p; - } - - public XSLFTextShape getParentShape() { - return _shape; - - } - - @Override - public List getTextRuns(){ - return _runs; - } - - public Iterator iterator(){ - return _runs.iterator(); - } - - /** - * Add a new run of text - * - * @return a new run of text - */ - public XSLFTextRun addNewTextRun(){ - CTRegularTextRun r = _p.addNewR(); - CTTextCharacterProperties rPr = r.addNewRPr(); - rPr.setLang("en-US"); - XSLFTextRun run = newTextRun(r); - _runs.add(run); - return run; - } - - /** - * Insert a line break - * - * @return text run representing this line break ('\n') - */ - public XSLFTextRun addLineBreak(){ - CTTextLineBreak br = _p.addNewBr(); - CTTextCharacterProperties brProps = br.addNewRPr(); - if(_runs.size() > 0){ - // by default line break has the font size of the last text run - CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true); - brProps.set(prevRun); - } - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(brProps); - r.setT("\n"); - XSLFTextRun run = new XSLFLineBreak(r, this, brProps); - _runs.add(run); - return run; - } - - @Override - public TextAlign getTextAlign(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetAlgn()){ - TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1]; - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public void setTextAlign(TextAlign align) { - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(align == null) { - if(pr.isSetAlgn()) pr.unsetAlgn(); - } else { - pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1)); - } - } - - @Override - public FontAlign getFontAlign(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetFontAlgn()){ - FontAlign val = FontAlign.values()[props.getFontAlgn().intValue() - 1]; - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * Specifies the font alignment that is to be applied to the paragraph. - * Possible values for this include auto, top, center, baseline and bottom. - * see {@link org.apache.poi.sl.usermodel.TextParagraph.FontAlign}. - * - * @param align font align - */ - public void setFontAlign(FontAlign align){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(align == null) { - if(pr.isSetFontAlgn()) pr.unsetFontAlgn(); - } else { - pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1)); - } - } - - - - /** - * @return the font to be used on bullet characters within a given paragraph - */ - public String getBulletFont(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuFont()){ - setValue(props.getBuFont().getTypeface()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public void setBulletFont(String typeface){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextFont font = pr.isSetBuFont() ? pr.getBuFont() : pr.addNewBuFont(); - font.setTypeface(typeface); - } - - /** - * @return the character to be used in place of the standard bullet point - */ - public String getBulletCharacter(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuChar()){ - setValue(props.getBuChar().getChar()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public void setBulletCharacter(String str){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextCharBullet c = pr.isSetBuChar() ? pr.getBuChar() : pr.addNewBuChar(); - c.setChar(str); - } - - /** - * - * @return the color of bullet characters within a given paragraph. - * A null value means to use the text font color. - */ - public PaintStyle getBulletFontColor(){ - final XSLFTheme theme = getParentShape().getSheet().getTheme(); - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuClr()){ - XSLFColor c = new XSLFColor(props.getBuClr(), theme, null); - setValue(c.getColor()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - Color col = fetcher.getValue(); - return (col == null) ? null : DrawPaint.createSolidPaint(col); - } - - public void setBulletFontColor(Color color) { - setBulletFontColor(DrawPaint.createSolidPaint(color)); - } - - - /** - * Set the color to be used on bullet characters within a given paragraph. - * - * @param color the bullet color - */ - public void setBulletFontColor(PaintStyle color) { - if (!(color instanceof SolidPaint)) { - throw new IllegalArgumentException("Currently XSLF only supports SolidPaint"); - } - - // TODO: implement setting bullet color to null - SolidPaint sp = (SolidPaint)color; - Color col = DrawPaint.applyColorTransform(sp.getSolidColor()); - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr(); - CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr(); - clr.setVal(new byte[]{(byte) col.getRed(), (byte) col.getGreen(), (byte) col.getBlue()}); - } - - /** - * Returns the bullet size that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If bulletSize >= 0, then bulletSize is a percentage of the font size. - * If bulletSize < 0, then it specifies the size in points - *

        - * - * @return the bullet size - */ - public Double getBulletFontSize(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuSzPct()){ - setValue(props.getBuSzPct().getVal() * 0.001); - return true; - } - if(props.isSetBuSzPts()){ - setValue( - props.getBuSzPts().getVal() * 0.01); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * Sets the bullet size that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If bulletSize >= 0, then bulletSize is a percentage of the font size. - * If bulletSize < 0, then it specifies the size in points - *

        - */ - public void setBulletFontSize(double bulletSize){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - - if(bulletSize >= 0) { - CTTextBulletSizePercent pt = pr.isSetBuSzPct() ? pr.getBuSzPct() : pr.addNewBuSzPct(); - pt.setVal((int)(bulletSize*1000)); - if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); - } else { - CTTextBulletSizePoint pt = pr.isSetBuSzPts() ? pr.getBuSzPts() : pr.addNewBuSzPts(); - pt.setVal((int)(-bulletSize*100)); - if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); - } - } - - /** - * @return the auto numbering scheme, or null if not defined - */ - public AutoNumberingScheme getAutoNumberingScheme() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()) { - public boolean fetch(CTTextParagraphProperties props) { - if (props.isSetBuAutoNum()) { - AutoNumberingScheme ans = AutoNumberingScheme.forOoxmlID(props.getBuAutoNum().getType().intValue()); - if (ans != null) { - setValue(ans); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * @return the auto numbering starting number, or null if not defined - */ - public Integer getAutoNumberingStartAt() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()) { - public boolean fetch(CTTextParagraphProperties props) { - if (props.isSetBuAutoNum()) { - if (props.getBuAutoNum().isSetStartAt()) { - setValue(props.getBuAutoNum().getStartAt()); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - - @Override - public void setIndent(Double indent){ - if ((indent == null) && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(indent == null) { - if(pr.isSetIndent()) pr.unsetIndent(); - } else { - pr.setIndent(Units.toEMU(indent)); - } - } - - @Override - public Double getIndent() { - - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetIndent()){ - setValue(Units.toPoints(props.getIndent())); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - return fetcher.getValue(); - } - - @Override - public void setLeftMargin(Double leftMargin){ - if (leftMargin == null && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if (leftMargin == null) { - if(pr.isSetMarL()) pr.unsetMarL(); - } else { - pr.setMarL(Units.toEMU(leftMargin)); - } - - } - - /** - * @return the left margin (in points) of the paragraph, null if unset - */ - @Override - public Double getLeftMargin(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetMarL()){ - double val = Units.toPoints(props.getMarL()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - // if the marL attribute is omitted, then a value of 347663 is implied - return fetcher.getValue(); - } - - @Override - public void setRightMargin(Double rightMargin){ - if (rightMargin == null && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(rightMargin == null) { - if(pr.isSetMarR()) pr.unsetMarR(); - } else { - pr.setMarR(Units.toEMU(rightMargin)); - } - } - - /** - * - * @return the right margin of the paragraph, null if unset - */ - @Override - public Double getRightMargin(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetMarR()){ - double val = Units.toPoints(props.getMarR()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public Double getDefaultTabSize(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetDefTabSz()){ - double val = Units.toPoints(props.getDefTabSz()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public double getTabStop(final int idx){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetTabLst()){ - CTTextTabStopList tabStops = props.getTabLst(); - if(idx < tabStops.sizeOfTabArray() ) { - CTTextTabStop ts = tabStops.getTabArray(idx); - double val = Units.toPoints(ts.getPos()); - setValue(val); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 0. : fetcher.getValue(); - } - - public void addTabStop(double value){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst(); - tabStops.addNewTab().setPos(Units.toEMU(value)); - } - - @Override - public void setLineSpacing(Double lineSpacing){ - if (lineSpacing == null && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(lineSpacing == null) { - if (pr.isSetLnSpc()) pr.unsetLnSpc(); - } else { - CTTextSpacing spc = (pr.isSetLnSpc()) ? pr.getLnSpc() : pr.addNewLnSpc(); - if (lineSpacing >= 0) { - (spc.isSetSpcPct() ? spc.getSpcPct() : spc.addNewSpcPct()).setVal((int)(lineSpacing*1000)); - if (spc.isSetSpcPts()) spc.unsetSpcPts(); - } else { - (spc.isSetSpcPts() ? spc.getSpcPts() : spc.addNewSpcPts()).setVal((int)(-lineSpacing*100)); - if (spc.isSetSpcPct()) spc.unsetSpcPct(); - } - } - } - - @Override - public Double getLineSpacing(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetLnSpc()){ - CTTextSpacing spc = props.getLnSpc(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - Double lnSpc = fetcher.getValue(); - if (lnSpc != null && lnSpc > 0) { - // check if the percentage value is scaled - CTTextNormalAutofit normAutofit = getParentShape().getTextBodyPr().getNormAutofit(); - if(normAutofit != null) { - double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000; - lnSpc *= scale; - } - } - - return lnSpc; - } - - @Override - public void setSpaceBefore(Double spaceBefore){ - if (spaceBefore == null && !_p.isSetPPr()) { - return; - } - - // unset the space before on null input - if (spaceBefore == null) { - if(_p.getPPr().isSetSpcBef()) { - _p.getPPr().unsetSpcBef(); - } - return; - } - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - - if(spaceBefore >= 0) { - spc.addNewSpcPct().setVal((int)(spaceBefore*1000)); - } else { - spc.addNewSpcPts().setVal((int)(-spaceBefore*100)); - } - pr.setSpcBef(spc); - } - - @Override - public Double getSpaceBefore(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetSpcBef()){ - CTTextSpacing spc = props.getSpcBef(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - return fetcher.getValue(); - } - - @Override - public void setSpaceAfter(Double spaceAfter){ - if (spaceAfter == null && !_p.isSetPPr()) { - return; - } - - // unset the space before on null input - if (spaceAfter == null) { - if(_p.getPPr().isSetSpcAft()) { - _p.getPPr().unsetSpcAft(); - } - return; - } - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - - if(spaceAfter >= 0) { - spc.addNewSpcPct().setVal((int)(spaceAfter*1000)); - } else { - spc.addNewSpcPts().setVal((int)(-spaceAfter*100)); - } - pr.setSpcAft(spc); - } - - @Override - public Double getSpaceAfter(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetSpcAft()){ - CTTextSpacing spc = props.getSpcAft(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public void setIndentLevel(int level){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - pr.setLvl(level); - } - - @Override - public int getIndentLevel() { - CTTextParagraphProperties pr = _p.getPPr(); - return (pr == null || !pr.isSetLvl()) ? 0 : pr.getLvl(); - } - - /** - * Returns whether this paragraph has bullets - */ - public boolean isBullet() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuNone()) { - setValue(false); - return true; - } - if(props.isSetBuFont() || props.isSetBuChar()){ - setValue(true); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * - * @param flag whether text in this paragraph has bullets - */ - public void setBullet(boolean flag) { - if(isBullet() == flag) return; - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(flag) { - pr.addNewBuFont().setTypeface("Arial"); - pr.addNewBuChar().setChar("\u2022"); - } else { - if (pr.isSetBuFont()) pr.unsetBuFont(); - if (pr.isSetBuChar()) pr.unsetBuChar(); - if (pr.isSetBuAutoNum()) pr.unsetBuAutoNum(); - if (pr.isSetBuBlip()) pr.unsetBuBlip(); - if (pr.isSetBuClr()) pr.unsetBuClr(); - if (pr.isSetBuClrTx()) pr.unsetBuClrTx(); - if (pr.isSetBuFont()) pr.unsetBuFont(); - if (pr.isSetBuFontTx()) pr.unsetBuFontTx(); - if (pr.isSetBuSzPct()) pr.unsetBuSzPct(); - if (pr.isSetBuSzPts()) pr.unsetBuSzPts(); - if (pr.isSetBuSzTx()) pr.unsetBuSzTx(); - pr.addNewBuNone(); - } - } - - /** - * Specifies that automatic numbered bullet points should be applied to this paragraph - * - * @param scheme type of auto-numbering - * @param startAt the number that will start number for a given sequence of automatically - numbered bullets (1-based). - */ - public void setBulletAutoNumber(AutoNumberingScheme scheme, int startAt) { - if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); - lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ooxmlId)); - lst.setStartAt(startAt); - } - - @Override - public String toString(){ - return "[" + getClass() + "]" + getText(); - } - - - /** - * @return master style text paragraph properties, or null if - * there are no master slides or the master slides do not contain a text paragraph - */ - /* package */ CTTextParagraphProperties getDefaultMasterStyle(){ - CTPlaceholder ph = _shape.getCTPlaceholder(); - String defaultStyleSelector; - switch(ph == null ? -1 : ph.getType().intValue()) { - case STPlaceholderType.INT_TITLE: - case STPlaceholderType.INT_CTR_TITLE: - defaultStyleSelector = "titleStyle"; - break; - case -1: // no placeholder means plain text box - case STPlaceholderType.INT_FTR: - case STPlaceholderType.INT_SLD_NUM: - case STPlaceholderType.INT_DT: - defaultStyleSelector = "otherStyle"; - break; - default: - defaultStyleSelector = "bodyStyle"; - break; - } - int level = getIndentLevel(); - - // wind up and find the root master sheet which must be slide master - final String nsPML = "http://schemas.openxmlformats.org/presentationml/2006/main"; - final String nsDML = "http://schemas.openxmlformats.org/drawingml/2006/main"; - XSLFSheet masterSheet = _shape.getSheet(); - for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) { - masterSheet = m; - XmlObject xo = masterSheet.getXmlObject(); - XmlCursor cur = xo.newCursor(); - try { - cur.push(); - if ((cur.toChild(nsPML, "txStyles") && cur.toChild(nsPML, defaultStyleSelector)) || - (cur.pop() && cur.toChild(nsPML, "notesStyle"))) { - while (level >= 0) { - cur.push(); - if (cur.toChild(nsDML, "lvl" +(level+1)+ "pPr")) { - return (CTTextParagraphProperties)cur.getObject(); - } - cur.pop(); - level--; - } - } - } finally { - cur.dispose(); - } - } - - return null; - } - - private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){ - boolean ok = false; - XSLFTextShape shape = getParentShape(); - XSLFSheet sheet = shape.getSheet(); - - if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr()); - if (ok) return true; - - ok = shape.fetchShapeProperty(visitor); - if (ok) return true; - - - CTPlaceholder ph = shape.getCTPlaceholder(); - if(ph == null){ - // if it is a plain text box then take defaults from presentation.xml - @SuppressWarnings("resource") - XMLSlideShow ppt = sheet.getSlideShow(); - CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel()); - if (themeProps != null) ok = visitor.fetch(themeProps); - } - if (ok) return true; - - // defaults for placeholders are defined in the slide master - CTTextParagraphProperties defaultProps = getDefaultMasterStyle(); - // TODO: determine master shape - if(defaultProps != null) ok = visitor.fetch(defaultProps); - if (ok) return true; - - return false; - } - - void copy(XSLFTextParagraph other){ - if (other == this) return; - - CTTextParagraph thisP = getXmlObject(); - CTTextParagraph otherP = other.getXmlObject(); - - if (thisP.isSetPPr()) thisP.unsetPPr(); - if (thisP.isSetEndParaRPr()) thisP.unsetEndParaRPr(); - - _runs.clear(); - for (int i=thisP.sizeOfBrArray(); i>0; i--) { - thisP.removeBr(i-1); - } - for (int i=thisP.sizeOfRArray(); i>0; i--) { - thisP.removeR(i-1); - } - for (int i=thisP.sizeOfFldArray(); i>0; i--) { - thisP.removeFld(i-1); - } - - XmlCursor thisC = thisP.newCursor(); - thisC.toEndToken(); - XmlCursor otherC = otherP.newCursor(); - otherC.copyXmlContents(thisC); - otherC.dispose(); - thisC.dispose(); - - List otherRs = other.getTextRuns(); - int i=0; - for(CTRegularTextRun rtr : thisP.getRArray()) { - XSLFTextRun run = newTextRun(rtr); - run.copy(otherRs.get(i++)); - _runs.add(run); - } - - - // set properties again, in case we are based on a different - // template - TextAlign srcAlign = other.getTextAlign(); - if(srcAlign != getTextAlign()){ - setTextAlign(srcAlign); - } - - boolean isBullet = other.isBullet(); - if(isBullet != isBullet()){ - setBullet(isBullet); - if(isBullet) { - String buFont = other.getBulletFont(); - if(buFont != null && !buFont.equals(getBulletFont())){ - setBulletFont(buFont); - } - String buChar = other.getBulletCharacter(); - if(buChar != null && !buChar.equals(getBulletCharacter())){ - setBulletCharacter(buChar); - } - PaintStyle buColor = other.getBulletFontColor(); - if(buColor != null && !buColor.equals(getBulletFontColor())){ - setBulletFontColor(buColor); - } - Double buSize = other.getBulletFontSize(); - if(!doubleEquals(buSize, getBulletFontSize())){ - setBulletFontSize(buSize); - } - } - } - - Double leftMargin = other.getLeftMargin(); - if (!doubleEquals(leftMargin, getLeftMargin())){ - setLeftMargin(leftMargin); - } - - Double indent = other.getIndent(); - if (!doubleEquals(indent, getIndent())) { - setIndent(indent); - } - - Double spaceAfter = other.getSpaceAfter(); - if (!doubleEquals(spaceAfter, getSpaceAfter())) { - setSpaceAfter(spaceAfter); - } - - Double spaceBefore = other.getSpaceBefore(); - if (!doubleEquals(spaceBefore, getSpaceBefore())) { - setSpaceBefore(spaceBefore); - } - - Double lineSpacing = other.getLineSpacing(); - if (!doubleEquals(lineSpacing, getLineSpacing())) { - setLineSpacing(lineSpacing); - } - } - - private static boolean doubleEquals(Double d1, Double d2) { - return (d1 == d2 || (d1 != null && d1.equals(d2))); - } - - @Override - public Double getDefaultFontSize() { - CTTextCharacterProperties endPr = _p.getEndParaRPr(); - if (endPr == null || !endPr.isSetSz()) { - // inherit the font size from the master style - CTTextParagraphProperties masterStyle = getDefaultMasterStyle(); - if (masterStyle != null) { - endPr = masterStyle.getDefRPr(); - } - } - return (endPr == null || !endPr.isSetSz()) ? 12 : (endPr.getSz() / 100.); - } - - @Override - public String getDefaultFontFamily() { - return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily()); - } - - @Override - public BulletStyle getBulletStyle() { - if (!isBullet()) return null; - return new BulletStyle(){ - @Override - public String getBulletCharacter() { - return XSLFTextParagraph.this.getBulletCharacter(); - } - - @Override - public String getBulletFont() { - return XSLFTextParagraph.this.getBulletFont(); - } - - @Override - public Double getBulletFontSize() { - return XSLFTextParagraph.this.getBulletFontSize(); - } - - @Override - public PaintStyle getBulletFontColor() { - return XSLFTextParagraph.this.getBulletFontColor(); - } - - @Override - public void setBulletFontColor(Color color) { - setBulletFontColor(DrawPaint.createSolidPaint(color)); - } - - @Override - public void setBulletFontColor(PaintStyle color) { - XSLFTextParagraph.this.setBulletFontColor(color); - } - - @Override - public AutoNumberingScheme getAutoNumberingScheme() { - return XSLFTextParagraph.this.getAutoNumberingScheme(); - } - - @Override - public Integer getAutoNumberingStartAt() { - return XSLFTextParagraph.this.getAutoNumberingStartAt(); - } - - }; - } - - @Override - public void setBulletStyle(Object... styles) { - if (styles.length == 0) { - setBullet(false); - } else { - setBullet(true); - for (Object ostyle : styles) { - if (ostyle instanceof Number) { - setBulletFontSize(((Number)ostyle).doubleValue()); - } else if (ostyle instanceof Color) { - setBulletFontColor((Color)ostyle); - } else if (ostyle instanceof Character) { - setBulletCharacter(ostyle.toString()); - } else if (ostyle instanceof String) { - setBulletFont((String)ostyle); - } else if (ostyle instanceof AutoNumberingScheme) { - setBulletAutoNumber((AutoNumberingScheme)ostyle, 0); - } - } - } - } - - /** - * Helper method for appending text and keeping paragraph and character properties. - * The character properties are moved to the end paragraph marker - */ - /* package */ void clearButKeepProperties() { - CTTextParagraph thisP = getXmlObject(); - for (int i=thisP.sizeOfBrArray(); i>0; i--) { - thisP.removeBr(i-1); - } - for (int i=thisP.sizeOfFldArray(); i>0; i--) { - thisP.removeFld(i-1); - } - if (!_runs.isEmpty()) { - int size = _runs.size(); - XSLFTextRun lastRun = _runs.get(size-1); - CTTextCharacterProperties cpOther = lastRun.getRPr(false); - if (cpOther != null) { - if (thisP.isSetEndParaRPr()) { - thisP.unsetEndParaRPr(); - } - CTTextCharacterProperties cp = thisP.addNewEndParaRPr(); - cp.set(cpOther); - } - for (int i=size; i>0; i--) { - thisP.removeR(i-1); - } - _runs.clear(); - } - } - - @Override - public boolean isHeaderOrFooter() { - CTPlaceholder ph = _shape.getCTPlaceholder(); - int phId = (ph == null ? -1 : ph.getType().intValue()); - switch (phId) { - case STPlaceholderType.INT_SLD_NUM: - case STPlaceholderType.INT_DT: - case STPlaceholderType.INT_FTR: - case STPlaceholderType.INT_HDR: - return true; - default: - return false; - } - } - - /** - * Helper method to allow subclasses to provide their own text run - * - * @param r the xml reference - * - * @return a new text paragraph - * - * @since POI 3.15-beta2 - */ - protected XSLFTextRun newTextRun(CTRegularTextRun r) { - return new XSLFTextRun(r, this); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java deleted file mode 100644 index b0bbd4557..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java +++ /dev/null @@ -1,560 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import java.awt.Color; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.TextRun; -import org.apache.poi.util.Beta; -import org.apache.poi.xslf.model.CharacterPropertyFetcher; -import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink; -import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; - -/** - * Represents a run of text within the containing text body. The run element is the - * lowest level text separation mechanism within a text body. - */ -@Beta -public class XSLFTextRun implements TextRun { - private final CTRegularTextRun _r; - private final XSLFTextParagraph _p; - - protected XSLFTextRun(CTRegularTextRun r, XSLFTextParagraph p){ - _r = r; - _p = p; - } - - XSLFTextParagraph getParentParagraph(){ - return _p; - } - - public String getRawText(){ - return _r.getT(); - } - - String getRenderableText(){ - String txt = _r.getT(); - TextCap cap = getTextCap(); - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < txt.length(); i++) { - char c = txt.charAt(i); - if(c == '\t') { - // TODO: finish support for tabs - buf.append(" "); - } else { - switch (cap){ - case ALL: - buf.append(Character.toUpperCase(c)); - break; - case SMALL: - buf.append(Character.toLowerCase(c)); - break; - default: - buf.append(c); - } - } - } - - return buf.toString(); - } - - public void setText(String text){ - _r.setT(text); - } - - public CTRegularTextRun getXmlObject(){ - return _r; - } - - @Override - public void setFontColor(Color color) { - setFontColor(DrawPaint.createSolidPaint(color)); - } - - @Override - public void setFontColor(PaintStyle color) { - if (!(color instanceof SolidPaint)) { - throw new IllegalArgumentException("Currently only SolidPaint is supported!"); - } - SolidPaint sp = (SolidPaint)color; - Color c = DrawPaint.applyColorTransform(sp.getSolidColor()); - - CTTextCharacterProperties rPr = getRPr(true); - CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill(); - - XSLFColor col = new XSLFColor(fill, getParentParagraph().getParentShape().getSheet().getTheme(), fill.getSchemeClr()); - col.setColor(c); - } - - @Override - public PaintStyle getFontColor(){ - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props == null) { - return false; - } - - XSLFShape shape = _p.getParentShape(); - CTShapeStyle style = shape.getSpStyle(); - CTSchemeColor phClr = null; - if (style != null && style.getFontRef() != null) { - phClr = style.getFontRef().getSchemeClr(); - } - - XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); - XSLFSheet sheet = shape.getSheet(); - PackagePart pp = sheet.getPackagePart(); - XSLFTheme theme = sheet.getTheme(); - PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme); - - if (ps != null) { - setValue(ps); - return true; - } - - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public void setFontSize(Double fontSize){ - CTTextCharacterProperties rPr = getRPr(true); - if(fontSize == null) { - if (rPr.isSetSz()) rPr.unsetSz(); - } else { - if (fontSize < 1.0) { - throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize); - } - - rPr.setSz((int)(100*fontSize)); - } - } - - @Override - public Double getFontSize(){ - double scale = 1; - CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit(); - if(afit != null) scale = (double)afit.getFontScale() / 100000; - - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetSz()) { - setValue(props.getSz()*0.01); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? null : fetcher.getValue()*scale; - } - - /** - * - * @return the spacing between characters within a text run, - * If this attribute is omitted than a value of 0 or no adjustment is assumed. - */ - public double getCharacterSpacing(){ - - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetSpc()) { - setValue(props.getSpc()*0.01); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - /** - * Set the spacing between characters within a text run. - *

        - * The spacing is specified in points. Positive values will cause the text to expand, - * negative values to condense. - *

        - * - * @param spc character spacing in points. - */ - public void setCharacterSpacing(double spc){ - CTTextCharacterProperties rPr = getRPr(true); - if(spc == 0.0) { - if(rPr.isSetSpc()) rPr.unsetSpc(); - } else { - rPr.setSpc((int)(100*spc)); - } - } - - @Override - public void setFontFamily(String typeface){ - setFontFamily(typeface, (byte)-1, (byte)-1, false); - } - - public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){ - CTTextCharacterProperties rPr = getRPr(true); - - if(typeface == null){ - if(rPr.isSetLatin()) rPr.unsetLatin(); - if(rPr.isSetCs()) rPr.unsetCs(); - if(rPr.isSetSym()) rPr.unsetSym(); - } else { - if(isSymbol){ - CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym(); - font.setTypeface(typeface); - } else { - CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin(); - latin.setTypeface(typeface); - if(charset != -1) latin.setCharset(charset); - if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily); - } - } - } - - @Override - public String getFontFamily(){ - final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); - - CharacterPropertyFetcher visitor = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null) { - CTTextFont font = props.getLatin(); - if (font != null) { - String typeface = font.getTypeface(); - if("+mj-lt".equals(typeface)) { - typeface = theme.getMajorFont(); - } else if ("+mn-lt".equals(typeface)){ - typeface = theme.getMinorFont(); - } - setValue(typeface); - return true; - } - } - return false; - } - }; - fetchCharacterProperty(visitor); - - return visitor.getValue(); - } - - public byte getPitchAndFamily(){ - // final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); - - CharacterPropertyFetcher visitor = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null) { - CTTextFont font = props.getLatin(); - if (font != null) { - setValue(font.getPitchFamily()); - return true; - } - } - return false; - } - }; - fetchCharacterProperty(visitor); - - return visitor.getValue() == null ? 0 : visitor.getValue(); - } - - @Override - public void setStrikethrough(boolean strike) { - getRPr(true).setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE); - } - - @Override - public boolean isStrikethrough() { - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if(props != null && props.isSetStrike()) { - setValue(props.getStrike() != STTextStrikeType.NO_STRIKE); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - @Override - public boolean isSuperscript() { - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetBaseline()) { - setValue(props.getBaseline() > 0); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * Set the baseline for both the superscript and subscript fonts. - *

        - * The size is specified using a percentage. - * Positive values indicate superscript, negative values indicate subscript. - *

        - * - * @param baselineOffset - */ - public void setBaselineOffset(double baselineOffset){ - getRPr(true).setBaseline((int) baselineOffset * 1000); - } - - /** - * Set whether the text in this run is formatted as superscript. - * Default base line offset is 30% - * - * @see #setBaselineOffset(double) - */ - public void setSuperscript(boolean flag){ - setBaselineOffset(flag ? 30. : 0.); - } - - /** - * Set whether the text in this run is formatted as subscript. - * Default base line offset is -25%. - * - * @see #setBaselineOffset(double) - */ - public void setSubscript(boolean flag){ - setBaselineOffset(flag ? -25.0 : 0.); - } - - @Override - public boolean isSubscript() { - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetBaseline()) { - setValue(props.getBaseline() < 0); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * @return whether a run of text will be formatted as a superscript text. Default is false. - */ - public TextCap getTextCap() { - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetCap()) { - int idx = props.getCap().intValue() - 1; - setValue(TextCap.values()[idx]); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? TextCap.NONE : fetcher.getValue(); - } - - @Override - public void setBold(boolean bold){ - getRPr(true).setB(bold); - } - - @Override - public boolean isBold(){ - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetB()) { - setValue(props.getB()); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - @Override - public void setItalic(boolean italic){ - getRPr(true).setI(italic); - } - - @Override - public boolean isItalic(){ - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetI()) { - setValue(props.getI()); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - @Override - public void setUnderlined(boolean underline) { - getRPr(true).setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE); - } - - @Override - public boolean isUnderlined(){ - CharacterPropertyFetcher fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ - public boolean fetch(CTTextCharacterProperties props){ - if (props != null && props.isSetU()) { - setValue(props.getU() != STTextUnderlineType.NONE); - return true; - } - return false; - } - }; - fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * Return the character properties - * - * @param create if true, create an empty character properties object if it doesn't exist - * @return the character properties or null if create was false and the properties haven't exist - */ - protected CTTextCharacterProperties getRPr(boolean create) { - if (_r.isSetRPr()) { - return _r.getRPr(); - } else if (create) { - return _r.addNewRPr(); - } else { - return null; - } - } - - @Override - public String toString(){ - return "[" + getClass() + "]" + getRawText(); - } - - @Override - public XSLFHyperlink createHyperlink(){ - XSLFHyperlink hl = getHyperlink(); - if (hl == null) { - hl = new XSLFHyperlink(_r.getRPr().addNewHlinkClick(), _p.getParentShape().getSheet()); - } - return hl; - } - - @Override - public XSLFHyperlink getHyperlink(){ - CTTextCharacterProperties rPr = _r.getRPr(); - if (rPr == null) { - return null; - } - CTHyperlink hl = rPr.getHlinkClick(); - if (hl == null) { - return null; - } - return new XSLFHyperlink(hl, _p.getParentShape().getSheet()); - } - - private boolean fetchCharacterProperty(CharacterPropertyFetcher fetcher){ - XSLFTextShape shape = _p.getParentShape(); - XSLFSheet sheet = shape.getSheet(); - boolean ok = false; - - if (_r.isSetRPr()) ok = fetcher.fetch(getRPr(false)); - if (ok) return true; - - ok = shape.fetchShapeProperty(fetcher); - if (ok) return true; - - CTPlaceholder ph = shape.getCTPlaceholder(); - if (ph == null){ - // if it is a plain text box then take defaults from presentation.xml - @SuppressWarnings("resource") - XMLSlideShow ppt = sheet.getSlideShow(); - CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel()); - if (themeProps != null) { - // TODO: determine master shape - ok = fetcher.fetch(themeProps); - } - } - if (ok) return true; - - CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle(); - if(defaultProps != null) { - // TODO: determine master shape - ok = fetcher.fetch(defaultProps); - } - if (ok) return true; - - return false; - } - - void copy(XSLFTextRun r){ - String srcFontFamily = r.getFontFamily(); - if(srcFontFamily != null && !srcFontFamily.equals(getFontFamily())){ - setFontFamily(srcFontFamily); - } - - PaintStyle srcFontColor = r.getFontColor(); - if(srcFontColor != null && !srcFontColor.equals(getFontColor())){ - setFontColor(srcFontColor); - } - - double srcFontSize = r.getFontSize(); - if(srcFontSize != getFontSize()){ - setFontSize(srcFontSize); - } - - boolean bold = r.isBold(); - if(bold != isBold()) setBold(bold); - - boolean italic = r.isItalic(); - if(italic != isItalic()) setItalic(italic); - - boolean underline = r.isUnderlined(); - if(underline != isUnderlined()) setUnderlined(underline); - - boolean strike = r.isStrikethrough(); - if(strike != isStrikethrough()) setStrikethrough(strike); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java deleted file mode 100644 index 91b0869b8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java +++ /dev/null @@ -1,690 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIXMLException; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.DrawTextShape; -import org.apache.poi.sl.usermodel.Insets2D; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.TextShape; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Units; -import org.apache.poi.xslf.model.PropertyFetcher; -import org.apache.poi.xslf.model.TextBodyPropertyFetcher; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; - -/** - * Represents a shape that can hold text. - */ -@Beta -public abstract class XSLFTextShape extends XSLFSimpleShape - implements TextShape { - private final List _paragraphs; - - /*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { - super(shape, sheet); - - _paragraphs = new ArrayList(); - CTTextBody txBody = getTextBody(false); - if (txBody != null) { - for (CTTextParagraph p : txBody.getPArray()) { - _paragraphs.add(newTextParagraph(p)); - } - } - } - - public Iterator iterator(){ - return getTextParagraphs().iterator(); - } - - @Override - public String getText() { - StringBuilder out = new StringBuilder(); - for (XSLFTextParagraph p : _paragraphs) { - if (out.length() > 0) out.append('\n'); - out.append(p.getText()); - } - return out.toString(); - } - - /** - * unset text from this shape - */ - public void clearText(){ - _paragraphs.clear(); - CTTextBody txBody = getTextBody(true); - txBody.setPArray(null); // remove any existing paragraphs - } - - @Override - public XSLFTextRun setText(String text) { - // calling clearText or setting to a new Array leads to a XmlValueDisconnectedException - if (!_paragraphs.isEmpty()) { - CTTextBody txBody = getTextBody(false); - int cntPs = txBody.sizeOfPArray(); - for (int i = cntPs; i > 1; i--) { - txBody.removeP(i-1); - _paragraphs.remove(i-1); - } - - _paragraphs.get(0).clearButKeepProperties(); - } - - return appendText(text, false); - } - - @Override - public XSLFTextRun appendText(String text, boolean newParagraph) { - if (text == null) return null; - - // copy properties from last paragraph / textrun or paragraph end marker - CTTextParagraphProperties otherPPr = null; - CTTextCharacterProperties otherRPr = null; - - boolean firstPara; - XSLFTextParagraph para; - if (_paragraphs.isEmpty()) { - firstPara = false; - para = null; - } else { - firstPara = !newParagraph; - para = _paragraphs.get(_paragraphs.size()-1); - CTTextParagraph ctp = para.getXmlObject(); - otherPPr = ctp.getPPr(); - List runs = para.getTextRuns(); - if (!runs.isEmpty()) { - XSLFTextRun r0 = runs.get(runs.size()-1); - otherRPr = r0.getRPr(false); - if (otherRPr == null) { - otherRPr = ctp.getEndParaRPr(); - } - } - // don't copy endParaRPr to the run in case there aren't any other runs - // this is the case when setText() was called initially - // otherwise the master style will be overridden/ignored - } - - XSLFTextRun run = null; - for (String lineTxt : text.split("\\r\\n?|\\n")) { - if (!firstPara) { - if (para != null) { - CTTextParagraph ctp = para.getXmlObject(); - CTTextCharacterProperties unexpectedRPr = ctp.getEndParaRPr(); - if (unexpectedRPr != null && unexpectedRPr != otherRPr) { - ctp.unsetEndParaRPr(); - } - } - para = addNewTextParagraph(); - if (otherPPr != null) { - para.getXmlObject().setPPr(otherPPr); - } - } - boolean firstRun = true; - for (String runText : lineTxt.split("[\u000b]")) { - if (!firstRun) { - para.addLineBreak(); - } - run = para.addNewTextRun(); - run.setText(runText); - if (otherRPr != null) { - run.getRPr(true).set(otherRPr); - } - firstRun = false; - } - firstPara = false; - } - - assert(run != null); - return run; - } - - @Override - public List getTextParagraphs() { - return _paragraphs; - } - - /** - * add a new paragraph run to this shape - * - * @return created paragraph run - */ - public XSLFTextParagraph addNewTextParagraph() { - CTTextBody txBody = getTextBody(false); - CTTextParagraph p; - if (txBody == null) { - txBody = getTextBody(true); - p = txBody.getPArray(0); - p.removeR(0); - } else { - p = txBody.addNewP(); - } - XSLFTextParagraph paragraph = newTextParagraph(p); - _paragraphs.add(paragraph); - return paragraph; - } - - @Override - public void setVerticalAlignment(VerticalAlignment anchor){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(anchor == null) { - if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor(); - } else { - bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); - } - } - } - - @Override - public VerticalAlignment getVerticalAlignment(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetAnchor()){ - int val = props.getAnchor().intValue(); - setValue(VerticalAlignment.values()[val - 1]); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue(); - } - - @Override - public void setHorizontalCentered(Boolean isCentered){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if (isCentered == null) { - if (bodyPr.isSetAnchorCtr()) bodyPr.unsetAnchorCtr(); - } else { - bodyPr.setAnchorCtr(isCentered); - } - } - } - - @Override - public boolean isHorizontalCentered(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetAnchorCtr()){ - setValue(props.getAnchorCtr()); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - @Override - public void setTextDirection(TextDirection orientation){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(orientation == null) { - if(bodyPr.isSetVert()) bodyPr.unsetVert(); - } else { - bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1)); - } - } - } - - @Override - public TextDirection getTextDirection(){ - CTTextBodyProperties bodyPr = getTextBodyPr(); - if (bodyPr != null) { - STTextVerticalType.Enum val = bodyPr.getVert(); - if(val != null) { - switch (val.intValue()) { - default: - case STTextVerticalType.INT_HORZ: - return TextDirection.HORIZONTAL; - case STTextVerticalType.INT_EA_VERT: - case STTextVerticalType.INT_MONGOLIAN_VERT: - case STTextVerticalType.INT_VERT: - return TextDirection.VERTICAL; - case STTextVerticalType.INT_VERT_270: - return TextDirection.VERTICAL_270; - case STTextVerticalType.INT_WORD_ART_VERT_RTL: - case STTextVerticalType.INT_WORD_ART_VERT: - return TextDirection.STACKED; - } - } - } - return TextDirection.HORIZONTAL; - } - - @Override - public Double getTextRotation() { - CTTextBodyProperties bodyPr = getTextBodyPr(); - if (bodyPr != null && bodyPr.isSetRot()) { - return bodyPr.getRot() / 60000.; - } - return null; - } - - @Override - public void setTextRotation(Double rotation) { - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - bodyPr.setRot((int)(rotation * 60000.)); - } - } - - - /** - * Returns the distance (in points) between the bottom of the text frame - * and the bottom of the inscribed rectangle of the shape that contains the text. - * - * @return the bottom inset in points - */ - public double getBottomInset(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetBIns()){ - double val = Units.toPoints(props.getBIns()); - setValue(val); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - // If this attribute is omitted, then a value of 0.05 inches is implied - return fetcher.getValue() == null ? 3.6 : fetcher.getValue(); - } - - /** - * Returns the distance (in points) between the left edge of the text frame - * and the left edge of the inscribed rectangle of the shape that contains - * the text. - * - * @return the left inset in points - */ - public double getLeftInset(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetLIns()){ - double val = Units.toPoints(props.getLIns()); - setValue(val); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - // If this attribute is omitted, then a value of 0.1 inches is implied - return fetcher.getValue() == null ? 7.2 : fetcher.getValue(); - } - - /** - * Returns the distance (in points) between the right edge of the - * text frame and the right edge of the inscribed rectangle of the shape - * that contains the text. - * - * @return the right inset in points - */ - public double getRightInset(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetRIns()){ - double val = Units.toPoints(props.getRIns()); - setValue(val); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - // If this attribute is omitted, then a value of 0.1 inches is implied - return fetcher.getValue() == null ? 7.2 : fetcher.getValue(); - } - - /** - * Returns the distance (in points) between the top of the text frame - * and the top of the inscribed rectangle of the shape that contains the text. - * - * @return the top inset in points - */ - public double getTopInset(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetTIns()){ - double val = Units.toPoints(props.getTIns()); - setValue(val); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - // If this attribute is omitted, then a value of 0.05 inches is implied - return fetcher.getValue() == null ? 3.6 : fetcher.getValue(); - } - - /** - * Sets the bottom margin. - * @see #getBottomInset() - * - * @param margin the bottom margin - */ - public void setBottomInset(double margin){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(margin == -1) bodyPr.unsetBIns(); - else bodyPr.setBIns(Units.toEMU(margin)); - } - } - - /** - * Sets the left margin. - * @see #getLeftInset() - * - * @param margin the left margin - */ - public void setLeftInset(double margin){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(margin == -1) bodyPr.unsetLIns(); - else bodyPr.setLIns(Units.toEMU(margin)); - } - } - - /** - * Sets the right margin. - * @see #getRightInset() - * - * @param margin the right margin - */ - public void setRightInset(double margin){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(margin == -1) bodyPr.unsetRIns(); - else bodyPr.setRIns(Units.toEMU(margin)); - } - } - - /** - * Sets the top margin. - * @see #getTopInset() - * - * @param margin the top margin - */ - public void setTopInset(double margin){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(margin == -1) bodyPr.unsetTIns(); - else bodyPr.setTIns(Units.toEMU(margin)); - } - } - - @Override - public Insets2D getInsets() { - Insets2D insets = new Insets2D(getTopInset(), getLeftInset(), getBottomInset(), getRightInset()); - return insets; - } - - @Override - public void setInsets(Insets2D insets) { - setTopInset(insets.top); - setLeftInset(insets.left); - setBottomInset(insets.bottom); - setRightInset(insets.right); - } - - @Override - public boolean getWordWrap(){ - PropertyFetcher fetcher = new TextBodyPropertyFetcher(){ - public boolean fetch(CTTextBodyProperties props){ - if(props.isSetWrap()){ - setValue(props.getWrap() == STTextWrappingType.SQUARE); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - return fetcher.getValue() == null ? true : fetcher.getValue(); - } - - @Override - public void setWordWrap(boolean wrap){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE); - } - } - - /** - * - * Specifies that a shape should be auto-fit to fully contain the text described within it. - * Auto-fitting is when text within a shape is scaled in order to contain all the text inside - * - * @param value type of autofit - */ - public void setTextAutofit(TextAutofit value){ - CTTextBodyProperties bodyPr = getTextBodyPr(true); - if (bodyPr != null) { - if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit(); - if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit(); - if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit(); - - switch(value){ - case NONE: bodyPr.addNewNoAutofit(); break; - case NORMAL: bodyPr.addNewNormAutofit(); break; - case SHAPE: bodyPr.addNewSpAutoFit(); break; - } - } - } - - /** - * - * @return type of autofit - */ - public TextAutofit getTextAutofit(){ - CTTextBodyProperties bodyPr = getTextBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE; - else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL; - else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE; - } - return TextAutofit.NORMAL; - } - - protected CTTextBodyProperties getTextBodyPr(){ - return getTextBodyPr(false); - } - - protected CTTextBodyProperties getTextBodyPr(boolean create) { - CTTextBody textBody = getTextBody(create); - if (textBody == null) { - return null; - } - CTTextBodyProperties textBodyPr = textBody.getBodyPr(); - if (textBodyPr == null && create) { - textBodyPr = textBody.addNewBodyPr(); - } - return textBodyPr; - } - - protected abstract CTTextBody getTextBody(boolean create); - - @Override - public void setPlaceholder(Placeholder placeholder) { - super.setPlaceholder(placeholder); - } - - public Placeholder getTextType(){ - CTPlaceholder ph = getCTPlaceholder(); - if (ph == null) return null; - - int val = ph.getType().intValue(); - return Placeholder.lookupOoxml(val); - } - - @Override - public double getTextHeight(){ - DrawFactory drawFact = DrawFactory.getInstance(null); - DrawTextShape dts = drawFact.getDrawable(this); - return dts.getTextHeight(); - } - - /** - * Adjust the size of the shape so it encompasses the text inside it. - * - * @return a Rectangle2D that is the bounds of this shape. - */ - public Rectangle2D resizeToFitText(){ - Rectangle2D anchor = getAnchor(); - if(anchor.getWidth() == 0.) throw new POIXMLException( - "Anchor of the shape was not set."); - double height = getTextHeight(); - height += 1; // add a pixel to compensate rounding errors - - anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height); - setAnchor(anchor); - - return anchor; - } - - - @Override - void copy(XSLFShape other){ - super.copy(other); - - XSLFTextShape otherTS = (XSLFTextShape)other; - CTTextBody otherTB = otherTS.getTextBody(false); - CTTextBody thisTB = getTextBody(true); - if (otherTB == null) { - return; - } - - thisTB.setBodyPr((CTTextBodyProperties)otherTB.getBodyPr().copy()); - - if (thisTB.isSetLstStyle()) thisTB.unsetLstStyle(); - if (otherTB.isSetLstStyle()) { - thisTB.setLstStyle((CTTextListStyle)otherTB.getLstStyle().copy()); - } - - boolean srcWordWrap = otherTS.getWordWrap(); - if(srcWordWrap != getWordWrap()){ - setWordWrap(srcWordWrap); - } - - double leftInset = otherTS.getLeftInset(); - if(leftInset != getLeftInset()) { - setLeftInset(leftInset); - } - double rightInset = otherTS.getRightInset(); - if(rightInset != getRightInset()) { - setRightInset(rightInset); - } - double topInset = otherTS.getTopInset(); - if(topInset != getTopInset()) { - setTopInset(topInset); - } - double bottomInset = otherTS.getBottomInset(); - if(bottomInset != getBottomInset()) { - setBottomInset(bottomInset); - } - - VerticalAlignment vAlign = otherTS.getVerticalAlignment(); - if(vAlign != getVerticalAlignment()) { - setVerticalAlignment(vAlign); - } - - clearText(); - - for (XSLFTextParagraph srcP : otherTS.getTextParagraphs()) { - XSLFTextParagraph tgtP = addNewTextParagraph(); - tgtP.copy(srcP); - } - } - - @Override - public void setTextPlaceholder(TextPlaceholder placeholder) { - switch (placeholder) { - default: - case NOTES: - case HALF_BODY: - case QUARTER_BODY: - case BODY: - setPlaceholder(Placeholder.BODY); - break; - case TITLE: - setPlaceholder(Placeholder.TITLE); - break; - case CENTER_BODY: - setPlaceholder(Placeholder.BODY); - setHorizontalCentered(true); - break; - case CENTER_TITLE: - setPlaceholder(Placeholder.CENTERED_TITLE); - break; - case OTHER: - setPlaceholder(Placeholder.CONTENT); - break; - } - } - - @Override - public TextPlaceholder getTextPlaceholder() { - Placeholder ph = getTextType(); - if (ph == null) return TextPlaceholder.BODY; - switch (ph) { - case BODY: return TextPlaceholder.BODY; - case TITLE: return TextPlaceholder.TITLE; - case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE; - default: - case CONTENT: return TextPlaceholder.OTHER; - } - } - - /** - * Helper method to allow subclasses to provide their own text paragraph - * - * @param p the xml reference - * - * @return a new text paragraph - * - * @since POI 3.15-beta2 - */ - protected XSLFTextParagraph newTextParagraph(CTTextParagraph p) { - return new XSLFTextParagraph(p, this); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java b/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java deleted file mode 100644 index 37bc34dba..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java +++ /dev/null @@ -1,182 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme; -import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; - -/** - * A shared style sheet in a .pptx slide show - * - * @author Yegor Kozlov - */ -@Beta -public class XSLFTheme extends POIXMLDocumentPart { - private CTOfficeStyleSheet _theme; - private Map _schemeColors; - - XSLFTheme() { - super(); - _theme = CTOfficeStyleSheet.Factory.newInstance(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XSLFTheme(PackagePart part) throws IOException, XmlException { - super(part); - ThemeDocument doc = - ThemeDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - _theme = doc.getTheme(); - initialize(); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSLFTheme(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - public void importTheme(XSLFTheme theme) { - _theme = theme.getXmlObject(); - _schemeColors = theme._schemeColors; - } - - private void initialize(){ - CTBaseStyles elems = _theme.getThemeElements(); - CTColorScheme scheme = elems.getClrScheme(); - // The color scheme is responsible for defining a list of twelve colors. - _schemeColors = new HashMap(12); - for(XmlObject o : scheme.selectPath("*")){ - CTColor c = (CTColor)o; - String name = c.getDomNode().getLocalName(); - _schemeColors.put(name, c); - } - } - - /** - * re-map colors - * - * @param cmap color map defined in the master slide referencing this theme - */ - void initColorMap(CTColorMapping cmap) { - _schemeColors.put("bg1", _schemeColors.get(cmap.getBg1().toString())); - _schemeColors.put("bg2", _schemeColors.get(cmap.getBg2().toString())); - _schemeColors.put("tx1", _schemeColors.get(cmap.getTx1().toString())); - _schemeColors.put("tx2", _schemeColors.get(cmap.getTx2().toString())); - } - - /** - * - * @return name of this theme, e.g. "Office Theme" - */ - public String getName(){ - return _theme.getName(); - } - - /** - * Set name of this theme - * - * @param name name of this theme - */ - public void setName(String name){ - _theme.setName(name); - } - - /** - * Get a color from the theme's color scheme by name - * - * @return a theme color or null if not found - */ - CTColor getCTColor(String name){ - return _schemeColors.get(name); - } - - /** - * While developing only! - */ - @Internal - public CTOfficeStyleSheet getXmlObject() { - return _theme; - } - - protected final void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement( - new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "theme")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - getXmlObject().save(out, xmlOptions); - out.close(); - } - - /** - * @return typeface of the major font to use in a document. - * Typically the major font is used for heading areas of a document. - * - */ - public String getMajorFont(){ - return _theme.getThemeElements().getFontScheme().getMajorFont().getLatin().getTypeface(); - } - - /** - * @return typeface of the minor font to use in a document. - * Typically the monor font is used for normal text or paragraph areas. - * - */ - public String getMinorFont(){ - return _theme.getThemeElements().getFontScheme().getMinorFont().getLatin().getTypeface(); - } - - - CTTextParagraphProperties getDefaultParagraphStyle(){ - XmlObject[] o = _theme.selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + - "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + - ".//a:objectDefaults/a:spDef/a:lstStyle/a:defPPr"); - if(o.length == 1){ - return (CTTextParagraphProperties)o[0]; - } - return null; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java b/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java deleted file mode 100644 index 76d1b5900..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.util; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.TreeSet; - -import javax.imageio.ImageIO; - -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; - -/** - * An utility to convert slides of a .pptx slide show to a PNG image - * - * @author Yegor Kozlov - */ -public class PPTX2PNG { - - static void usage(String error){ - String msg = - "Usage: PPTX2PNG [options] \n" + - (error == null ? "" : ("Error: "+error+"\n")) + - "Options:\n" + - " -scale scale factor\n" + - " -slide 1-based index of a slide to render\n" + - " -format png,gif,jpg (,null for testing)" + - " -outdir output directory, defaults to origin of the ppt/pptx file" + - " -quiet do not write to console (for normal processing)"; - - System.out.println(msg); - // no System.exit here, as we also run in junit tests! - } - - public static void main(String[] args) throws Exception { - if (args.length == 0) { - usage(null); - return; - } - - String slidenumStr = "-1"; - float scale = 1; - File file = null; - String format = "png"; - File outdir = null; - boolean quiet = false; - - for (int i = 0; i < args.length; i++) { - if (args[i].startsWith("-")) { - if ("-scale".equals(args[i])) { - scale = Float.parseFloat(args[++i]); - } else if ("-slide".equals(args[i])) { - slidenumStr = args[++i]; - } else if ("-format".equals(args[i])) { - format = args[++i]; - } else if ("-outdir".equals(args[i])) { - outdir = new File(args[++i]); - } else if ("-quiet".equals(args[i])) { - quiet = true; - } - } else { - file = new File(args[i]); - } - } - - if (file == null || !file.exists()) { - usage("File not specified or it doesn't exist"); - return; - } - - if (format == null || !format.matches("^(png|gif|jpg|null)$")) { - usage("Invalid format given"); - return; - } - - if (outdir == null) { - outdir = file.getParentFile(); - } - - if (!"null".equals(format) && (outdir == null || !outdir.exists() || !outdir.isDirectory())) { - usage("Output directory doesn't exist"); - return; - } - - if (scale < 0) { - usage("Invalid scale given"); - return; - } - - if (!quiet) { - System.out.println("Processing " + file); - } - SlideShow ss = SlideShowFactory.create(file, null, true); - try { - List> slides = ss.getSlides(); - - Set slidenum = slideIndexes(slides.size(), slidenumStr); - - if (slidenum.isEmpty()) { - usage("slidenum must be either -1 (for all) or within range: [1.." + slides.size() + "] for " + file); - return; - } - - Dimension pgsize = ss.getPageSize(); - int width = (int) (pgsize.width * scale); - int height = (int) (pgsize.height * scale); - - for (Integer slideNo : slidenum) { - Slide slide = slides.get(slideNo); - String title = slide.getTitle(); - if (!quiet) { - System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title)); - } - - BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = img.createGraphics(); - DrawFactory.getInstance(graphics).fixFonts(graphics); - - // default rendering options - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - graphics.scale(scale, scale); - - // draw stuff - slide.draw(graphics); - - // save the result - if (!"null".equals(format)) { - String outname = file.getName().replaceFirst(".pptx?", ""); - outname = String.format(Locale.ROOT, "%1$s-%2$04d.%3$s", outname, slideNo, format); - File outfile = new File(outdir, outname); - ImageIO.write(img, format, outfile); - } - - graphics.dispose(); - img.flush(); - } - } finally { - ss.close(); - } - - if (!quiet) { - System.out.println("Done"); - } - } - - private static Set slideIndexes(final int slideCount, String range) { - Set slideIdx = new TreeSet(); - if ("-1".equals(range)) { - for (int i=0; i en = zip.entries(); - while (en.hasMoreElements()) { - ZipEntry entry = en.nextElement(); - String name = entry.getName(); - int idx = name.lastIndexOf('/'); - if (idx != -1) { - File bs = new File(root, name.substring(0, idx)); - recursivelyCreateDirIfMissing(bs); - } - - File f = new File(root, entry.getName()); - OutputStream out = new FileOutputStream(f); - try { - if (entry.getName().endsWith(".xml") || entry.getName().endsWith(".vml") || entry.getName().endsWith(".rels")) { - try { - Document doc = DocumentHelper.readDocument(zip.getInputStream(entry)); - XmlObject xml = XmlObject.Factory.parse(doc, DEFAULT_XML_OPTIONS); - XmlOptions options = new XmlOptions(); - options.setSavePrettyPrint(); - xml.save(out, options); - } catch (XmlException e) { - System.err.println("Failed to parse " + entry.getName() + ", dumping raw content"); - IOUtils.copy(zip.getInputStream(entry), out); - } - } else { - IOUtils.copy(zip.getInputStream(entry), out); - } - } finally { - out.close(); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java b/trunk/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java deleted file mode 100644 index 1660f452a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxml4j.opc.OPCPackage; -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++) { - OPCPackage pkg = OPCPackage.open(args[i]); - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - 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(); - - pkg.close(); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java deleted file mode 100644 index f2554e6b4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java +++ /dev/null @@ -1,245 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel; - -import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML; - -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.SAXHelper; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -/** - *

        This is a lightweight way to process the Shared Strings - * table. Most of the text cells will reference something - * from in here. - *

        Note that each SI entry can have multiple T elements, if the - * string is made up of bits with different formatting. - *

        Example input: - *

        -<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
        -<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2">
        - <si>
        -   <r>
        -     <rPr>
        -       <b />
        -       <sz val="11" />
        -       <color theme="1" />
        -       <rFont val="Calibri" />
        -       <family val="2" />
        -       <scheme val="minor" />
        -     </rPr>
        -     <t>This:</t>
        -   </r>
        -   <r>
        -     <rPr>
        -       <sz val="11" />
        -       <color theme="1" />
        -       <rFont val="Calibri" />
        -       <family val="2" />
        -       <scheme val="minor" />
        -     </rPr>
        -     <t xml:space="preserve">Causes Problems</t>
        -   </r>
        - </si>
        - <si>
        -   <t>This does not</t>
        - </si>
        -</sst>
        -* 
        - * - */ -public class ReadOnlySharedStringsTable extends DefaultHandler { - /** - * An integer representing the total count of strings in the workbook. This count does not - * include any numbers, it counts only the total of text strings in the workbook. - */ - private int count; - - /** - * An integer representing the total count of unique strings in the Shared String Table. - * A string is unique even if it is a copy of another string, but has different formatting applied - * at the character level. - */ - private int uniqueCount; - - /** - * The shared strings table. - */ - private List strings; - - /** - * @param pkg - * @throws IOException - * @throws SAXException - * @throws ParserConfigurationException - */ - public ReadOnlySharedStringsTable(OPCPackage pkg) - throws IOException, SAXException { - ArrayList parts = - pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()); - - // Some workbooks have no shared strings table. - if (parts.size() > 0) { - PackagePart sstPart = parts.get(0); - readFrom(sstPart.getInputStream()); - } - } - - /** - * Like POIXMLDocumentPart constructor - * - * @since POI 3.14-Beta1 - */ - public ReadOnlySharedStringsTable(PackagePart part) throws IOException, SAXException { - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public ReadOnlySharedStringsTable(PackagePart part, PackageRelationship rel_ignored) - throws IOException, SAXException { - this(part); - } - - /** - * Read this shared strings table from an XML file. - * - * @param is The input stream containing the XML document. - * @throws IOException if an error occurs while reading. - * @throws SAXException - * @throws ParserConfigurationException - */ - public void readFrom(InputStream is) throws IOException, SAXException { - // test if the file is empty, otherwise parse it - PushbackInputStream pis = new PushbackInputStream(is, 1); - int emptyTest = pis.read(); - if (emptyTest > -1) { - pis.unread(emptyTest); - InputSource sheetSource = new InputSource(pis); - try { - XMLReader sheetParser = SAXHelper.newXMLReader(); - sheetParser.setContentHandler(this); - sheetParser.parse(sheetSource); - } catch(ParserConfigurationException e) { - throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage()); - } - } - } - - /** - * Return an integer representing the total count of strings in the workbook. This count does not - * include any numbers, it counts only the total of text strings in the workbook. - * - * @return the total count of strings in the workbook - */ - public int getCount() { - return this.count; - } - - /** - * Returns an integer representing the total count of unique strings in the Shared String Table. - * A string is unique even if it is a copy of another string, but has different formatting applied - * at the character level. - * - * @return the total count of unique strings in the workbook - */ - public int getUniqueCount() { - return this.uniqueCount; - } - - /** - * Return the string at a given index. - * Formatting is ignored. - * - * @param idx index of item to return. - * @return the item at the specified position in this Shared String table. - */ - public String getEntryAt(int idx) { - return strings.get(idx); - } - - public List getItems() { - return strings; - } - - //// ContentHandler methods //// - - private StringBuffer characters; - private boolean tIsOpen; - - public void startElement(String uri, String localName, String name, - Attributes attributes) throws SAXException { - if (uri != null && ! uri.equals(NS_SPREADSHEETML)) { - return; - } - - if ("sst".equals(localName)) { - String count = attributes.getValue("count"); - if(count != null) this.count = Integer.parseInt(count); - String uniqueCount = attributes.getValue("uniqueCount"); - if(uniqueCount != null) this.uniqueCount = Integer.parseInt(uniqueCount); - - this.strings = new ArrayList(this.uniqueCount); - - characters = new StringBuffer(); - } else if ("si".equals(localName)) { - characters.setLength(0); - } else if ("t".equals(localName)) { - tIsOpen = true; - } - } - - public void endElement(String uri, String localName, String name) - throws SAXException { - if (uri != null && ! uri.equals(NS_SPREADSHEETML)) { - return; - } - - if ("si".equals(localName)) { - strings.add(characters.toString()); - } else if ("t".equals(localName)) { - tIsOpen = false; - } - } - - /** - * Captures characters only if a t(ext) element is open. - */ - public void characters(char[] ch, int start, int length) - throws SAXException { - if (tIsOpen) - characters.append(ch, start, length); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFReader.java b/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFReader.java deleted file mode 100644 index 71942a132..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFReader.java +++ /dev/null @@ -1,350 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.model.ThemesTable; -import org.apache.poi.xssf.usermodel.XSSFDrawing; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.poi.xssf.usermodel.XSSFShape; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; - -/** - * This class makes it easy to get at individual parts - * of an OOXML .xlsx file, suitable for low memory sax - * parsing or similar. - * It makes up the core part of the EventUserModel support - * for XSSF. - */ -public class XSSFReader { - private OPCPackage pkg; - private PackagePart workbookPart; - - /** - * Creates a new XSSFReader, for the given package - */ - public XSSFReader(OPCPackage pkg) throws IOException, OpenXML4JException { - this.pkg = pkg; - - PackageRelationship coreDocRelationship = this.pkg.getRelationshipsByType( - PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0); - - // strict OOXML likely not fully supported, see #57699 - // this code is similar to POIXMLDocumentPart.getPartFromOPCPackage(), but I could not combine it - // easily due to different return values - if(coreDocRelationship == null) { - if (this.pkg.getRelationshipsByType( - PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0) != null) { - throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699"); - } - - throw new POIXMLException("OOXML file structure broken/invalid - no core document found!"); - } - - // Get the part that holds the workbook - workbookPart = this.pkg.getPart(coreDocRelationship); - } - - - /** - * Opens up the Shared Strings Table, parses it, and - * returns a handy object for working with - * shared strings. - */ - public SharedStringsTable getSharedStringsTable() throws IOException, InvalidFormatException { - ArrayList parts = pkg.getPartsByContentType( XSSFRelation.SHARED_STRINGS.getContentType()); - return parts.size() == 0 ? null : new SharedStringsTable(parts.get(0), null); - } - - /** - * Opens up the Styles Table, parses it, and - * returns a handy object for working with cell styles - */ - public StylesTable getStylesTable() throws IOException, InvalidFormatException { - ArrayList parts = pkg.getPartsByContentType( XSSFRelation.STYLES.getContentType()); - if(parts.size() == 0) return null; - - // Create the Styles Table, and associate the Themes if present - StylesTable styles = new StylesTable(parts.get(0), null); - parts = pkg.getPartsByContentType( XSSFRelation.THEME.getContentType()); - if(parts.size() != 0) { - styles.setTheme(new ThemesTable(parts.get(0), null)); - } - return styles; - } - - - - /** - * Returns an InputStream to read the contents of the - * shared strings table. - */ - public InputStream getSharedStringsData() throws IOException, InvalidFormatException { - return XSSFRelation.SHARED_STRINGS.getContents(workbookPart); - } - - /** - * Returns an InputStream to read the contents of the - * styles table. - */ - public InputStream getStylesData() throws IOException, InvalidFormatException { - return XSSFRelation.STYLES.getContents(workbookPart); - } - - /** - * Returns an InputStream to read the contents of the - * themes table. - */ - public InputStream getThemesData() throws IOException, InvalidFormatException { - return XSSFRelation.THEME.getContents(workbookPart); - } - - /** - * Returns an InputStream to read the contents of the - * main Workbook, which contains key overall data for - * the file, including sheet definitions. - */ - public InputStream getWorkbookData() throws IOException, InvalidFormatException { - return workbookPart.getInputStream(); - } - - /** - * Returns an InputStream to read the contents of the - * specified Sheet. - * @param relId The relationId of the sheet, from a r:id on the workbook - */ - public InputStream getSheet(String relId) throws IOException, InvalidFormatException { - PackageRelationship rel = workbookPart.getRelationship(relId); - if(rel == null) { - throw new IllegalArgumentException("No Sheet found with r:id " + relId); - } - - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - PackagePart sheet = pkg.getPart(relName); - if(sheet == null) { - throw new IllegalArgumentException("No data found for Sheet with r:id " + relId); - } - return sheet.getInputStream(); - } - - /** - * Returns an Iterator which will let you get at all the - * different Sheets in turn. - * Each sheet's InputStream is only opened when fetched - * from the Iterator. It's up to you to close the - * InputStreams when done with each one. - */ - public Iterator getSheetsData() throws IOException, InvalidFormatException { - return new SheetIterator(workbookPart); - } - - /** - * Iterator over sheet data. - */ - public static class SheetIterator implements Iterator { - - /** - * Maps relId and the corresponding PackagePart - */ - private final Map sheetMap; - - /** - * Current CTSheet bean - */ - private CTSheet ctSheet; - - /** - * Iterator over CTSheet objects, returns sheets in logical order. - * We can't rely on the Ooxml4J's relationship iterator because it returns objects in physical order, - * i.e. as they are stored in the underlying package - */ - private final Iterator sheetIterator; - - /** - * Construct a new SheetIterator - * - * @param wb package part holding workbook.xml - */ - private SheetIterator(PackagePart wb) throws IOException { - - /** - * The order of sheets is defined by the order of CTSheet elements in workbook.xml - */ - try { - //step 1. Map sheet's relationship Id and the corresponding PackagePart - sheetMap = new HashMap(); - OPCPackage pkg = wb.getPackage(); - String REL_WORKSHEET = XSSFRelation.WORKSHEET.getRelation(); - String REL_CHARTSHEET = XSSFRelation.CHARTSHEET.getRelation(); - for(PackageRelationship rel : wb.getRelationships()){ - String relType = rel.getRelationshipType(); - if (relType.equals(REL_WORKSHEET) || relType.equals(REL_CHARTSHEET)) { - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - sheetMap.put(rel.getId(), pkg.getPart(relName)); - } - } - //step 2. Read array of CTSheet elements, wrap it in a ArayList and construct an iterator - //Note, using XMLBeans might be expensive, consider refactoring to use SAX or a plain regexp search - CTWorkbook wbBean = WorkbookDocument.Factory.parse(wb.getInputStream(), DEFAULT_XML_OPTIONS).getWorkbook(); - List validSheets = new ArrayList(); - for (CTSheet ctSheet : wbBean.getSheets().getSheetList()) { - //if there's no relationship id, silently skip the sheet - String sheetId = ctSheet.getId(); - if (sheetId != null && sheetId.length() > 0) { - validSheets.add(ctSheet); - } - } - sheetIterator = validSheets.iterator(); - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } catch (XmlException e){ - throw new POIXMLException(e); - } - } - - /** - * Returns true if the iteration has more elements. - * - * @return true if the iterator has more elements. - */ - @Override - public boolean hasNext() { - return sheetIterator.hasNext(); - } - - /** - * Returns input stream of the next sheet in the iteration - * - * @return input stream of the next sheet in the iteration - */ - @Override - public InputStream next() { - ctSheet = sheetIterator.next(); - - String sheetId = ctSheet.getId(); - try { - PackagePart sheetPkg = sheetMap.get(sheetId); - return sheetPkg.getInputStream(); - } catch(IOException e) { - throw new POIXMLException(e); - } - } - - /** - * Returns name of the current sheet - * - * @return name of the current sheet - */ - public String getSheetName() { - return ctSheet.getName(); - } - - /** - * Returns the comments associated with this sheet, - * or null if there aren't any - */ - public CommentsTable getSheetComments() { - PackagePart sheetPkg = getSheetPart(); - - // Do we have a comments relationship? (Only ever one if so) - try { - PackageRelationshipCollection commentsList = - sheetPkg.getRelationshipsByType(XSSFRelation.SHEET_COMMENTS.getRelation()); - if(commentsList.size() > 0) { - PackageRelationship comments = commentsList.getRelationship(0); - PackagePartName commentsName = PackagingURIHelper.createPartName(comments.getTargetURI()); - PackagePart commentsPart = sheetPkg.getPackage().getPart(commentsName); - return new CommentsTable(commentsPart, comments); - } - } catch (InvalidFormatException e) { - return null; - } catch (IOException e) { - return null; - } - return null; - } - - /** - * Returns the shapes associated with this sheet, - * an empty list or null if there is an exception - */ - public List getShapes() { - PackagePart sheetPkg = getSheetPart(); - List shapes= new LinkedList(); - // Do we have a comments relationship? (Only ever one if so) - try { - PackageRelationshipCollection drawingsList = sheetPkg.getRelationshipsByType(XSSFRelation.DRAWINGS.getRelation()); - for (int i = 0; i < drawingsList.size(); i++){ - PackageRelationship drawings = drawingsList.getRelationship(i); - PackagePartName drawingsName = PackagingURIHelper.createPartName(drawings.getTargetURI()); - PackagePart drawingsPart = sheetPkg.getPackage().getPart(drawingsName); - XSSFDrawing drawing = new XSSFDrawing(drawingsPart, drawings); - for (XSSFShape shape : drawing.getShapes()){ - shapes.add(shape); - } - } - } catch (XmlException e){ - return null; - } catch (InvalidFormatException e) { - return null; - } catch (IOException e) { - return null; - } - return shapes; - } - - public PackagePart getSheetPart() { - String sheetId = ctSheet.getId(); - return sheetMap.get(sheetId); - } - - /** - * We're read only, so remove isn't supported - */ - @Override - public void remove() { - throw new IllegalStateException("Not supported"); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java b/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java deleted file mode 100644 index 49c966a31..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java +++ /dev/null @@ -1,513 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel; - -import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML; - -import java.util.LinkedList; -import java.util.Queue; - -import org.apache.poi.ss.usermodel.BuiltinFormats; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFComment; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * This class handles the processing of a sheet#.xml - * sheet part of a XSSF .xlsx file, and generates - * row and cell events for it. - */ -public class XSSFSheetXMLHandler extends DefaultHandler { - private static final POILogger logger = POILogFactory.getLogger(XSSFSheetXMLHandler.class); - - /** - * These are the different kinds of cells we support. - * We keep track of the current one between - * the start and end. - */ - enum xssfDataType { - BOOLEAN, - ERROR, - FORMULA, - INLINE_STRING, - SST_STRING, - NUMBER, - } - - /** - * Table with the styles used for formatting - */ - private StylesTable stylesTable; - - /** - * Table with cell comments - */ - private CommentsTable commentsTable; - - /** - * Read only access to the shared strings table, for looking - * up (most) string cell's contents - */ - private ReadOnlySharedStringsTable sharedStringsTable; - - /** - * Where our text is going - */ - private final SheetContentsHandler output; - - // Set when V start element is seen - private boolean vIsOpen; - // Set when F start element is seen - private boolean fIsOpen; - // Set when an Inline String "is" is seen - private boolean isIsOpen; - // Set when a header/footer element is seen - private boolean hfIsOpen; - - // Set when cell start element is seen; - // used when cell close element is seen. - private xssfDataType nextDataType; - - // Used to format numeric cell values. - private short formatIndex; - private String formatString; - private final DataFormatter formatter; - private int rowNum; - private int nextRowNum; // some sheets do not have rowNums, Excel can read them so we should try to handle them correctly as well - private String cellRef; - private boolean formulasNotResults; - - // Gathers characters as they are seen. - private StringBuffer value = new StringBuffer(); - private StringBuffer formula = new StringBuffer(); - private StringBuffer headerFooter = new StringBuffer(); - - private Queue commentCellRefs; - - /** - * Accepts objects needed while parsing. - * - * @param styles Table of styles - * @param strings Table of shared strings - */ - public XSSFSheetXMLHandler( - StylesTable styles, - CommentsTable comments, - ReadOnlySharedStringsTable strings, - SheetContentsHandler sheetContentsHandler, - DataFormatter dataFormatter, - boolean formulasNotResults) { - this.stylesTable = styles; - this.commentsTable = comments; - this.sharedStringsTable = strings; - this.output = sheetContentsHandler; - this.formulasNotResults = formulasNotResults; - this.nextDataType = xssfDataType.NUMBER; - this.formatter = dataFormatter; - init(); - } - - /** - * Accepts objects needed while parsing. - * - * @param styles Table of styles - * @param strings Table of shared strings - */ - public XSSFSheetXMLHandler( - StylesTable styles, - ReadOnlySharedStringsTable strings, - SheetContentsHandler sheetContentsHandler, - DataFormatter dataFormatter, - boolean formulasNotResults) { - this(styles, null, strings, sheetContentsHandler, dataFormatter, formulasNotResults); - } - - /** - * Accepts objects needed while parsing. - * - * @param styles Table of styles - * @param strings Table of shared strings - */ - public XSSFSheetXMLHandler( - StylesTable styles, - ReadOnlySharedStringsTable strings, - SheetContentsHandler sheetContentsHandler, - boolean formulasNotResults) { - this(styles, strings, sheetContentsHandler, new DataFormatter(), formulasNotResults); - } - - private void init() { - if (commentsTable != null) { - commentCellRefs = new LinkedList(); - for (CTComment comment : commentsTable.getCTComments().getCommentList().getCommentArray()) { - commentCellRefs.add(new CellAddress(comment.getRef())); - } - } - } - - private boolean isTextTag(String name) { - if("v".equals(name)) { - // Easy, normal v text tag - return true; - } - if("inlineStr".equals(name)) { - // Easy inline string - return true; - } - if("t".equals(name) && isIsOpen) { - // Inline string ... pair - return true; - } - // It isn't a text tag - return false; - } - - @Override - @SuppressWarnings("unused") - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - - if (uri != null && ! uri.equals(NS_SPREADSHEETML)) { - return; - } - - if (isTextTag(localName)) { - vIsOpen = true; - // Clear contents cache - value.setLength(0); - } else if ("is".equals(localName)) { - // Inline string outer tag - isIsOpen = true; - } else if ("f".equals(localName)) { - // Clear contents cache - formula.setLength(0); - - // Mark us as being a formula if not already - if(nextDataType == xssfDataType.NUMBER) { - nextDataType = xssfDataType.FORMULA; - } - - // Decide where to get the formula string from - String type = attributes.getValue("t"); - if(type != null && type.equals("shared")) { - // Is it the one that defines the shared, or uses it? - String ref = attributes.getValue("ref"); - String si = attributes.getValue("si"); - - if(ref != null) { - // This one defines it - // TODO Save it somewhere - fIsOpen = true; - } else { - // This one uses a shared formula - // TODO Retrieve the shared formula and tweak it to - // match the current cell - if(formulasNotResults) { - logger.log(POILogger.WARN, "shared formulas not yet supported!"); - } else { - // It's a shared formula, so we can't get at the formula string yet - // However, they don't care about the formula string, so that's ok! - } - } - } else { - fIsOpen = true; - } - } - else if("oddHeader".equals(localName) || "evenHeader".equals(localName) || - "firstHeader".equals(localName) || "firstFooter".equals(localName) || - "oddFooter".equals(localName) || "evenFooter".equals(localName)) { - hfIsOpen = true; - // Clear contents cache - headerFooter.setLength(0); - } - else if("row".equals(localName)) { - String rowNumStr = attributes.getValue("r"); - if(rowNumStr != null) { - rowNum = Integer.parseInt(rowNumStr) - 1; - } else { - rowNum = nextRowNum; - } - output.startRow(rowNum); - } - // c => cell - else if ("c".equals(localName)) { - // Set up defaults. - this.nextDataType = xssfDataType.NUMBER; - this.formatIndex = -1; - this.formatString = null; - cellRef = attributes.getValue("r"); - String cellType = attributes.getValue("t"); - String cellStyleStr = attributes.getValue("s"); - if ("b".equals(cellType)) - nextDataType = xssfDataType.BOOLEAN; - else if ("e".equals(cellType)) - nextDataType = xssfDataType.ERROR; - else if ("inlineStr".equals(cellType)) - nextDataType = xssfDataType.INLINE_STRING; - else if ("s".equals(cellType)) - nextDataType = xssfDataType.SST_STRING; - else if ("str".equals(cellType)) - nextDataType = xssfDataType.FORMULA; - else { - // Number, but almost certainly with a special style or format - XSSFCellStyle style = null; - if (stylesTable != null) { - if (cellStyleStr != null) { - int styleIndex = Integer.parseInt(cellStyleStr); - style = stylesTable.getStyleAt(styleIndex); - } else if (stylesTable.getNumCellStyles() > 0) { - style = stylesTable.getStyleAt(0); - } - } - if (style != null) { - this.formatIndex = style.getDataFormat(); - this.formatString = style.getDataFormatString(); - if (this.formatString == null) - this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex); - } - } - } - } - - @Override - public void endElement(String uri, String localName, String qName) - throws SAXException { - - if (uri != null && ! uri.equals(NS_SPREADSHEETML)) { - return; - } - - String thisStr = null; - - // v => contents of a cell - if (isTextTag(localName)) { - vIsOpen = false; - - // Process the value contents as required, now we have it all - switch (nextDataType) { - case BOOLEAN: - char first = value.charAt(0); - thisStr = first == '0' ? "FALSE" : "TRUE"; - break; - - case ERROR: - thisStr = "ERROR:" + value.toString(); - break; - - case FORMULA: - if(formulasNotResults) { - thisStr = formula.toString(); - } else { - String fv = value.toString(); - - if (this.formatString != null) { - try { - // Try to use the value as a formattable number - double d = Double.parseDouble(fv); - thisStr = formatter.formatRawCellContents(d, this.formatIndex, this.formatString); - } catch(NumberFormatException e) { - // Formula is a String result not a Numeric one - thisStr = fv; - } - } else { - // No formating applied, just do raw value in all cases - thisStr = fv; - } - } - break; - - case INLINE_STRING: - // TODO: Can these ever have formatting on them? - XSSFRichTextString rtsi = new XSSFRichTextString(value.toString()); - thisStr = rtsi.toString(); - break; - - case SST_STRING: - String sstIndex = value.toString(); - try { - int idx = Integer.parseInt(sstIndex); - XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getEntryAt(idx)); - thisStr = rtss.toString(); - } - catch (NumberFormatException ex) { - logger.log(POILogger.ERROR, "Failed to parse SST index '" + sstIndex, ex); - } - break; - - case NUMBER: - String n = value.toString(); - if (this.formatString != null && n.length() > 0) - thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString); - else - thisStr = n; - break; - - default: - thisStr = "(TODO: Unexpected type: " + nextDataType + ")"; - break; - } - - // Do we have a comment for this cell? - checkForEmptyCellComments(EmptyCellCommentsCheckType.CELL); - XSSFComment comment = commentsTable != null ? commentsTable.findCellComment(new CellAddress(cellRef)) : null; - - // Output - output.cell(cellRef, thisStr, comment); - } else if ("f".equals(localName)) { - fIsOpen = false; - } else if ("is".equals(localName)) { - isIsOpen = false; - } else if ("row".equals(localName)) { - // Handle any "missing" cells which had comments attached - checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_ROW); - - // Finish up the row - output.endRow(rowNum); - - // some sheets do not have rowNum set in the XML, Excel can read them so we should try to read them as well - nextRowNum = rowNum + 1; - } else if ("sheetData".equals(localName)) { - // Handle any "missing" cells which had comments attached - checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_SHEET_DATA); - } - else if("oddHeader".equals(localName) || "evenHeader".equals(localName) || - "firstHeader".equals(localName)) { - hfIsOpen = false; - output.headerFooter(headerFooter.toString(), true, localName); - } - else if("oddFooter".equals(localName) || "evenFooter".equals(localName) || - "firstFooter".equals(localName)) { - hfIsOpen = false; - output.headerFooter(headerFooter.toString(), false, localName); - } - } - - /** - * Captures characters only if a suitable element is open. - * Originally was just "v"; extended for inlineStr also. - */ - @Override - public void characters(char[] ch, int start, int length) - throws SAXException { - if (vIsOpen) { - value.append(ch, start, length); - } - if (fIsOpen) { - formula.append(ch, start, length); - } - if (hfIsOpen) { - headerFooter.append(ch, start, length); - } - } - - /** - * Do a check for, and output, comments in otherwise empty cells. - */ - private void checkForEmptyCellComments(EmptyCellCommentsCheckType type) { - if (commentCellRefs != null && !commentCellRefs.isEmpty()) { - // If we've reached the end of the sheet data, output any - // comments we haven't yet already handled - if (type == EmptyCellCommentsCheckType.END_OF_SHEET_DATA) { - while (!commentCellRefs.isEmpty()) { - outputEmptyCellComment(commentCellRefs.remove()); - } - return; - } - - // At the end of a row, handle any comments for "missing" rows before us - if (this.cellRef == null) { - if (type == EmptyCellCommentsCheckType.END_OF_ROW) { - while (!commentCellRefs.isEmpty()) { - if (commentCellRefs.peek().getRow() == rowNum) { - outputEmptyCellComment(commentCellRefs.remove()); - } else { - return; - } - } - return; - } else { - throw new IllegalStateException("Cell ref should be null only if there are only empty cells in the row; rowNum: " + rowNum); - } - } - - CellAddress nextCommentCellRef; - do { - CellAddress cellRef = new CellAddress(this.cellRef); - CellAddress peekCellRef = commentCellRefs.peek(); - if (type == EmptyCellCommentsCheckType.CELL && cellRef.equals(peekCellRef)) { - // remove the comment cell ref from the list if we're about to handle it alongside the cell content - commentCellRefs.remove(); - return; - } else { - // fill in any gaps if there are empty cells with comment mixed in with non-empty cells - int comparison = peekCellRef.compareTo(cellRef); - if (comparison > 0 && type == EmptyCellCommentsCheckType.END_OF_ROW && peekCellRef.getRow() <= rowNum) { - nextCommentCellRef = commentCellRefs.remove(); - outputEmptyCellComment(nextCommentCellRef); - } else if (comparison < 0 && type == EmptyCellCommentsCheckType.CELL && peekCellRef.getRow() <= rowNum) { - nextCommentCellRef = commentCellRefs.remove(); - outputEmptyCellComment(nextCommentCellRef); - } else { - nextCommentCellRef = null; - } - } - } while (nextCommentCellRef != null && !commentCellRefs.isEmpty()); - } - } - - - /** - * Output an empty-cell comment. - */ - private void outputEmptyCellComment(CellAddress cellRef) { - XSSFComment comment = commentsTable.findCellComment(cellRef); - output.cell(cellRef.formatAsString(), null, comment); - } - - private enum EmptyCellCommentsCheckType { - CELL, - END_OF_ROW, - END_OF_SHEET_DATA - } - - /** - * You need to implement this to handle the results - * of the sheet parsing. - */ - public interface SheetContentsHandler { - /** A row with the (zero based) row number has started */ - public void startRow(int rowNum); - /** A row with the (zero based) row number has ended */ - public void endRow(int rowNum); - /** - * A cell, with the given formatted value (may be null), - * and possibly a comment (may be null), was encountered */ - public void cell(String cellReference, String formattedValue, XSSFComment comment); - /** A header or footer has been encountered */ - public void headerFooter(String text, boolean isHeader, String tagName); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFEventBasedExcelExtractor.java b/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFEventBasedExcelExtractor.java deleted file mode 100644 index 18db97f43..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFEventBasedExcelExtractor.java +++ /dev/null @@ -1,383 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.poi.POIXMLProperties; -import org.apache.poi.POIXMLProperties.CoreProperties; -import org.apache.poi.POIXMLProperties.CustomProperties; -import org.apache.poi.POIXMLProperties.ExtendedProperties; -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.util.SAXHelper; -import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; -import org.apache.poi.xssf.eventusermodel.XSSFReader; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.XSSFComment; -import org.apache.poi.xssf.usermodel.XSSFShape; -import org.apache.poi.xssf.usermodel.XSSFSimpleShape; -import org.apache.xmlbeans.XmlException; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; - -/** - * Implementation of a text extractor from OOXML Excel - * files that uses SAX event based parsing. - */ -public class XSSFEventBasedExcelExtractor extends POIXMLTextExtractor - implements org.apache.poi.ss.extractor.ExcelExtractor { - private OPCPackage container; - private POIXMLProperties properties; - - private Locale locale; - private boolean includeTextBoxes = true; - private boolean includeSheetNames = true; - private boolean includeCellComments = false; - private boolean includeHeadersFooters = true; - private boolean formulasNotResults = false; - - public XSSFEventBasedExcelExtractor(String path) throws XmlException, OpenXML4JException, IOException { - this(OPCPackage.open(path)); - } - public XSSFEventBasedExcelExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException { - super(null); - this.container = container; - - properties = new POIXMLProperties(container); - } - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" XSSFEventBasedExcelExtractor "); - System.exit(1); - } - POIXMLTextExtractor extractor = - new XSSFEventBasedExcelExtractor(args[0]); - System.out.println(extractor.getText()); - extractor.close(); - } - - /** - * Should sheet names be included? Default is true - */ - public void setIncludeSheetNames(boolean includeSheetNames) { - this.includeSheetNames = includeSheetNames; - } - /** - * Should we return the formula itself, and not - * the result it produces? Default is false - */ - public void setFormulasNotResults(boolean formulasNotResults) { - this.formulasNotResults = formulasNotResults; - } - /** - * Should headers and footers be included? Default is true - */ - public void setIncludeHeadersFooters(boolean includeHeadersFooters) { - this.includeHeadersFooters = includeHeadersFooters; - } - /** - * Should text from textboxes be included? Default is true - */ - public void setIncludeTextBoxes(boolean includeTextBoxes) { - this.includeTextBoxes = includeTextBoxes; - } - - /** - * Should cell comments be included? Default is false - */ - public void setIncludeCellComments(boolean includeCellComments) { - this.includeCellComments = includeCellComments; - } - - public void setLocale(Locale locale) { - this.locale = locale; - } - - /** - * Returns the opened OPCPackage container. - */ - @Override - public OPCPackage getPackage() { - return container; - } - - /** - * Returns the core document properties - */ - @Override - public CoreProperties getCoreProperties() { - return properties.getCoreProperties(); - } - /** - * Returns the extended document properties - */ - @Override - public ExtendedProperties getExtendedProperties() { - return properties.getExtendedProperties(); - } - /** - * Returns the custom document properties - */ - @Override - public CustomProperties getCustomProperties() { - return properties.getCustomProperties(); - } - - /** - * Processes the given sheet - */ - public void processSheet( - SheetContentsHandler sheetContentsExtractor, - StylesTable styles, - CommentsTable comments, - ReadOnlySharedStringsTable strings, - InputStream sheetInputStream) - throws IOException, SAXException { - - DataFormatter formatter; - if(locale == null) { - formatter = new DataFormatter(); - } else { - formatter = new DataFormatter(locale); - } - - InputSource sheetSource = new InputSource(sheetInputStream); - try { - XMLReader sheetParser = SAXHelper.newXMLReader(); - ContentHandler handler = new XSSFSheetXMLHandler( - styles, comments, strings, sheetContentsExtractor, formatter, formulasNotResults); - sheetParser.setContentHandler(handler); - sheetParser.parse(sheetSource); - } catch(ParserConfigurationException e) { - throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage()); - } - } - - /** - * Processes the file and returns the text - */ - public String getText() { - try { - ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(container); - XSSFReader xssfReader = new XSSFReader(container); - StylesTable styles = xssfReader.getStylesTable(); - XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); - - StringBuffer text = new StringBuffer(); - SheetTextExtractor sheetExtractor = new SheetTextExtractor(); - - while (iter.hasNext()) { - InputStream stream = iter.next(); - if(includeSheetNames) { - text.append(iter.getSheetName()); - text.append('\n'); - } - CommentsTable comments = includeCellComments ? iter.getSheetComments() : null; - processSheet(sheetExtractor, styles, comments, strings, stream); - if (includeHeadersFooters) { - sheetExtractor.appendHeaderText(text); - } - sheetExtractor.appendCellText(text); - if (includeTextBoxes){ - processShapes(iter.getShapes(), text); - } - if (includeHeadersFooters) { - sheetExtractor.appendFooterText(text); - } - sheetExtractor.reset(); - stream.close(); - } - - return text.toString(); - } catch(IOException e) { - System.err.println(e); - return null; - } catch(SAXException se) { - System.err.println(se); - return null; - } catch(OpenXML4JException o4je) { - System.err.println(o4je); - return null; - } - } - - private void processShapes(List shapes, StringBuffer text) { - if (shapes == null){ - return; - } - for (XSSFShape shape : shapes){ - if (shape instanceof XSSFSimpleShape){ - String sText = ((XSSFSimpleShape)shape).getText(); - if (sText != null && sText.length() > 0){ - text.append(sText).append('\n'); - } - } - } - } - @Override - public void close() throws IOException { - if (container != null) { - container.close(); - container = null; - } - super.close(); - } - - protected class SheetTextExtractor implements SheetContentsHandler { - private final StringBuffer output; - private boolean firstCellOfRow; - private final Map headerFooterMap; - - protected SheetTextExtractor() { - this.output = new StringBuffer(); - this.firstCellOfRow = true; - this.headerFooterMap = includeHeadersFooters ? new HashMap() : null; - } - - @Override - public void startRow(int rowNum) { - firstCellOfRow = true; - } - - @Override - public void endRow(int rowNum) { - output.append('\n'); - } - - @Override - public void cell(String cellRef, String formattedValue, XSSFComment comment) { - if(firstCellOfRow) { - firstCellOfRow = false; - } else { - output.append('\t'); - } - if (formattedValue != null) { - checkMaxTextSize(output, formattedValue); - output.append(formattedValue); - } - if (includeCellComments && comment != null) { - String commentText = comment.getString().getString().replace('\n', ' '); - output.append(formattedValue != null ? " Comment by " : "Comment by "); - checkMaxTextSize(output, commentText); - if (commentText.startsWith(comment.getAuthor() + ": ")) { - output.append(commentText); - } else { - output.append(comment.getAuthor()).append(": ").append(commentText); - } - } - } - - @Override - public void headerFooter(String text, boolean isHeader, String tagName) { - if (headerFooterMap != null) { - headerFooterMap.put(tagName, text); - } - } - - /** - * Append the text for the named header or footer if found. - */ - private void appendHeaderFooterText(StringBuffer buffer, String name) { - String text = headerFooterMap.get(name); - if (text != null && text.length() > 0) { - // this is a naive way of handling the left, center, and right - // header and footer delimiters, but it seems to be as good as - // the method used by XSSFExcelExtractor - text = handleHeaderFooterDelimiter(text, "&L"); - text = handleHeaderFooterDelimiter(text, "&C"); - text = handleHeaderFooterDelimiter(text, "&R"); - buffer.append(text).append('\n'); - } - } - /** - * Remove the delimiter if its found at the beginning of the text, - * or replace it with a tab if its in the middle. - */ - private String handleHeaderFooterDelimiter(String text, String delimiter) { - int index = text.indexOf(delimiter); - if (index == 0) { - text = text.substring(2); - } else if (index > 0) { - text = text.substring(0, index) + "\t" + text.substring(index + 2); - } - return text; - } - - - /** - * Append the text for each header type in the same order - * they are appended in XSSFExcelExtractor. - * @see XSSFExcelExtractor#getText() - * @see org.apache.poi.hssf.extractor.ExcelExtractor#_extractHeaderFooter(org.apache.poi.ss.usermodel.HeaderFooter) - */ - private void appendHeaderText(StringBuffer buffer) { - appendHeaderFooterText(buffer, "firstHeader"); - appendHeaderFooterText(buffer, "oddHeader"); - appendHeaderFooterText(buffer, "evenHeader"); - } - - /** - * Append the text for each footer type in the same order - * they are appended in XSSFExcelExtractor. - * @see XSSFExcelExtractor#getText() - * @see org.apache.poi.hssf.extractor.ExcelExtractor#_extractHeaderFooter(org.apache.poi.ss.usermodel.HeaderFooter) - */ - private void appendFooterText(StringBuffer buffer) { - // append the text for each footer type in the same order - // they are appended in XSSFExcelExtractor - appendHeaderFooterText(buffer, "firstFooter"); - appendHeaderFooterText(buffer, "oddFooter"); - appendHeaderFooterText(buffer, "evenFooter"); - } - - /** - * Append the cell contents we have collected. - */ - private void appendCellText(StringBuffer buffer) { - checkMaxTextSize(buffer, output.toString()); - buffer.append(output); - } - - /** - * Reset this SheetTextExtractor for the next sheet. - */ - private void reset() { - output.setLength(0); - firstCellOfRow = true; - if (headerFooterMap != null) { - headerFooterMap.clear(); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java b/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java deleted file mode 100644 index 192d60d71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java +++ /dev/null @@ -1,265 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; -import java.util.Iterator; -import java.util.Locale; - -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.HeaderFooter; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFDrawing; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.poi.xssf.usermodel.XSSFShape; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFSimpleShape; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xmlbeans.XmlException; - -/** - * Helper class to extract text from an OOXML Excel file - */ -public class XSSFExcelExtractor extends POIXMLTextExtractor - implements org.apache.poi.ss.extractor.ExcelExtractor { - public static final XSSFRelation[] SUPPORTED_TYPES = new XSSFRelation[] { - XSSFRelation.WORKBOOK, XSSFRelation.MACRO_TEMPLATE_WORKBOOK, - XSSFRelation.MACRO_ADDIN_WORKBOOK, XSSFRelation.TEMPLATE_WORKBOOK, - XSSFRelation.MACROS_WORKBOOK - }; - - private Locale locale; - private XSSFWorkbook workbook; - private boolean includeSheetNames = true; - private boolean formulasNotResults = false; - private boolean includeCellComments = false; - private boolean includeHeadersFooters = true; - private boolean includeTextBoxes = true; - - public XSSFExcelExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException { - this(new XSSFWorkbook(container)); - } - public XSSFExcelExtractor(XSSFWorkbook workbook) { - super(workbook); - this.workbook = workbook; - } - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" XSSFExcelExtractor "); - System.exit(1); - } - OPCPackage pkg = OPCPackage.create(args[0]); - POIXMLTextExtractor extractor = new XSSFExcelExtractor(pkg); - try { - System.out.println(extractor.getText()); - } finally { - extractor.close(); - } - } - - /** - * Should sheet names be included? Default is true - */ - public void setIncludeSheetNames(boolean includeSheetNames) { - this.includeSheetNames = includeSheetNames; - } - /** - * Should we return the formula itself, and not - * the result it produces? Default is false - */ - public void setFormulasNotResults(boolean formulasNotResults) { - this.formulasNotResults = formulasNotResults; - } - /** - * Should cell comments be included? Default is false - */ - public void setIncludeCellComments(boolean includeCellComments) { - this.includeCellComments = includeCellComments; - } - /** - * Should headers and footers be included? Default is true - */ - public void setIncludeHeadersFooters(boolean includeHeadersFooters) { - this.includeHeadersFooters = includeHeadersFooters; - } - /** - * Should text within textboxes be included? Default is true - * @param includeTextBoxes - */ - public void setIncludeTextBoxes(boolean includeTextBoxes){ - this.includeTextBoxes = includeTextBoxes; - } - /** - * What Locale should be used for formatting numbers (based - * on the styles applied to the cells) - */ - public void setLocale(Locale locale) { - this.locale = locale; - } - - - /** - * Retrieves the text contents of the file - */ - public String getText() { - DataFormatter formatter; - if(locale == null) { - formatter = new DataFormatter(); - } else { - formatter = new DataFormatter(locale); - } - - StringBuffer text = new StringBuffer(); - for(Sheet sh : workbook) { - XSSFSheet sheet = (XSSFSheet) sh; - if(includeSheetNames) { - text.append(sheet.getSheetName()).append("\n"); - } - - // Header(s), if present - if(includeHeadersFooters) { - text.append( - extractHeaderFooter(sheet.getFirstHeader()) - ); - text.append( - extractHeaderFooter(sheet.getOddHeader()) - ); - text.append( - extractHeaderFooter(sheet.getEvenHeader()) - ); - } - - // Rows and cells - for (Object rawR : sheet) { - Row row = (Row)rawR; - for(Iterator ri = row.cellIterator(); ri.hasNext();) { - Cell cell = ri.next(); - - // Is it a formula one? - if(cell.getCellTypeEnum() == CellType.FORMULA) { - if (formulasNotResults) { - String contents = cell.getCellFormula(); - checkMaxTextSize(text, contents); - text.append(contents); - } else { - if (cell.getCachedFormulaResultTypeEnum() == CellType.STRING) { - handleStringCell(text, cell); - } else { - handleNonStringCell(text, cell, formatter); - } - } - } else if(cell.getCellTypeEnum() == CellType.STRING) { - handleStringCell(text, cell); - } else { - handleNonStringCell(text, cell, formatter); - } - - // Output the comment, if requested and exists - Comment comment = cell.getCellComment(); - if(includeCellComments && comment != null) { - // Replace any newlines with spaces, otherwise it - // breaks the output - String commentText = comment.getString().getString().replace('\n', ' '); - checkMaxTextSize(text, commentText); - text.append(" Comment by ").append(comment.getAuthor()).append(": ").append(commentText); - } - - if(ri.hasNext()) { - text.append("\t"); - } - } - text.append("\n"); - } - - // add textboxes - if (includeTextBoxes){ - XSSFDrawing drawing = sheet.getDrawingPatriarch(); - if (drawing != null) { - for (XSSFShape shape : drawing.getShapes()){ - if (shape instanceof XSSFSimpleShape){ - String boxText = ((XSSFSimpleShape)shape).getText(); - if (boxText.length() > 0){ - text.append(boxText); - text.append('\n'); - } - } - } - } - } - // Finally footer(s), if present - if(includeHeadersFooters) { - text.append( - extractHeaderFooter(sheet.getFirstFooter()) - ); - text.append( - extractHeaderFooter(sheet.getOddFooter()) - ); - text.append( - extractHeaderFooter(sheet.getEvenFooter()) - ); - } - } - - return text.toString(); - } - - private void handleStringCell(StringBuffer text, Cell cell) { - String contents = cell.getRichStringCellValue().getString(); - checkMaxTextSize(text, contents); - text.append(contents); - } - - private void handleNonStringCell(StringBuffer text, Cell cell, DataFormatter formatter) { - CellType type = cell.getCellTypeEnum(); - if (type == CellType.FORMULA) { - type = cell.getCachedFormulaResultTypeEnum(); - } - - if (type == CellType.NUMERIC) { - CellStyle cs = cell.getCellStyle(); - - if (cs != null && cs.getDataFormatString() != null) { - String contents = formatter.formatRawCellContents( - cell.getNumericCellValue(), cs.getDataFormat(), cs.getDataFormatString()); - checkMaxTextSize(text, contents); - text.append(contents); - return; - } - } - - // No supported styling applies to this cell - String contents = ((XSSFCell)cell).getRawValue(); - checkMaxTextSize(text, contents); - text.append( contents ); - } - - private String extractHeaderFooter(HeaderFooter hf) { - return ExcelExtractor._extractHeaderFooter(hf); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java b/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java deleted file mode 100644 index 7febd236b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java +++ /dev/null @@ -1,532 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; -import java.io.OutputStream; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Vector; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFMap; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFTable; -import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell; -import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * - * Maps an XLSX to an XML according to one of the mapping defined. - * - * - * The output XML Schema must respect this limitations: - * - *
          - *
        • all mandatory elements and attributes must be mapped (enable validation to check this)
        • - * - *
        • no <any> in complex type/element declaration
        • - *
        • no <anyAttribute> attributes declaration
        • - *
        • no recursive structures: recursive structures can't be nested more than one level
        • - *
        • no abstract elements: abstract complex types can be declared but must not be used in elements.
        • - *
        • no mixed content: an element can't contain simple text and child element(s) together
        • - *
        • no <substitutionGroup> in complex type/element declaration
        • - *
        - */ -public class XSSFExportToXml implements Comparator{ - private static final POILogger LOG = POILogFactory.getLogger(XSSFExportToXml.class); - - private XSSFMap map; - - /** - * Creates a new exporter and sets the mapping to be used when generating the XML output document - * - * @param map the mapping rule to be used - */ - public XSSFExportToXml(XSSFMap map) { - this.map = map; - } - - /** - * - * Exports the data in an XML stream - * - * @param os OutputStream in which will contain the output XML - * @param validate if true, validates the XML against the XML Schema - * @throws SAXException If validating the document fails - * @throws TransformerException If transforming the document fails - */ - public void exportToXML(OutputStream os, boolean validate) throws SAXException, TransformerException { - exportToXML(os, "UTF-8", validate); - } - - /** - * Exports the data in an XML stream - * - * @param os OutputStream in which will contain the output XML - * @param encoding the output charset encoding - * @param validate if true, validates the XML against the XML Schema - * @throws SAXException If validating the document fails - * @throws TransformerException If transforming the document fails - */ - public void exportToXML(OutputStream os, String encoding, boolean validate) throws SAXException, TransformerException{ - List singleXMLCells = map.getRelatedSingleXMLCell(); - List tables = map.getRelatedTables(); - - String rootElement = map.getCtMap().getRootElement(); - - Document doc = DocumentHelper.createDocument(); - - final Element root; - - if (isNamespaceDeclared()) { - root = doc.createElementNS(getNamespace(),rootElement); - } else { - root = doc.createElementNS("", rootElement); - } - doc.appendChild(root); - - - List xpaths = new Vector(); - Map singleXmlCellsMappings = new HashMap(); - Map tableMappings = new HashMap(); - - for(XSSFSingleXmlCell simpleXmlCell : singleXMLCells) { - xpaths.add(simpleXmlCell.getXpath()); - singleXmlCellsMappings.put(simpleXmlCell.getXpath(), simpleXmlCell); - } - for(XSSFTable table : tables) { - String commonXPath = table.getCommonXpath(); - xpaths.add(commonXPath); - tableMappings.put(commonXPath, table); - } - - Collections.sort(xpaths,this); - - for(String xpath : xpaths) { - - XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath); - XSSFTable table = tableMappings.get(xpath); - - if (!xpath.matches(".*\\[.*")) { - - // Exports elements and attributes mapped with simpleXmlCell - if (simpleXmlCell!=null) { - XSSFCell cell = simpleXmlCell.getReferencedCell(); - if (cell!=null) { - Node currentNode = getNodeByXPath(xpath,doc.getFirstChild(),doc,false); - mapCellOnNode(cell,currentNode); - - //remove nodes which are empty in order to keep the output xml valid - if("".equals(currentNode.getTextContent()) && currentNode.getParentNode() != null) { - currentNode.getParentNode().removeChild(currentNode); - } - } - } - - // Exports elements and attributes mapped with tables - if (table!=null) { - - List tableColumns = table.getXmlColumnPrs(); - - XSSFSheet sheet = table.getXSSFSheet(); - - int startRow = table.getStartCellReference().getRow(); - // In mappings created with Microsoft Excel the first row contains the table header and must be skipped - startRow +=1; - - int endRow = table.getEndCellReference().getRow(); - - for(int i = startRow; i<= endRow; i++) { - XSSFRow row = sheet.getRow(i); - - Node tableRootNode = getNodeByXPath(table.getCommonXpath(),doc.getFirstChild(),doc,true); - - short startColumnIndex = table.getStartCellReference().getCol(); - for(int j = startColumnIndex; j<= table.getEndCellReference().getCol();j++) { - XSSFCell cell = row.getCell(j); - if (cell!=null) { - XSSFXmlColumnPr pointer = tableColumns.get(j-startColumnIndex); - String localXPath = pointer.getLocalXPath(); - Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false); - - mapCellOnNode(cell,currentNode); - } - } - } - } - } /*else { - // TODO: implement filtering management in xpath - }*/ - } - - boolean isValid = true; - if (validate) { - isValid =isValid(doc); - } - - if (isValid) { - - ///////////////// - //Output the XML - - //set up a transformer - TransformerFactory transfac = TransformerFactory.newInstance(); - Transformer trans = transfac.newTransformer(); - trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - trans.setOutputProperty(OutputKeys.INDENT, "yes"); - trans.setOutputProperty(OutputKeys.ENCODING, encoding); - - //create string from xml tree - - StreamResult result = new StreamResult(os); - DOMSource source = new DOMSource(doc); - trans.transform(source, result); - - } - } - - - /** - * Validate the generated XML against the XML Schema associated with the XSSFMap - * - * @param xml the XML to validate - * @return true, if document is valid - * @throws SAXException If validating the document fails - */ - private boolean isValid(Document xml) throws SAXException{ - try{ - String language = "http://www.w3.org/2001/XMLSchema"; - SchemaFactory factory = SchemaFactory.newInstance(language); - - Source source = new DOMSource(map.getSchema()); - Schema schema = factory.newSchema(source); - Validator validator = schema.newValidator(); - validator.validate(new DOMSource(xml)); - - //if no exceptions where raised, the document is valid - return true; - } catch(IOException e) { - LOG.log(POILogger.ERROR, "document is not valid", e); - } - - return false; - } - - - private void mapCellOnNode(XSSFCell cell, Node node) { - - String value =""; - switch (cell.getCellTypeEnum()) { - - case STRING: value = cell.getStringCellValue(); break; - case BOOLEAN: value += cell.getBooleanCellValue(); break; - case ERROR: value = cell.getErrorCellString(); break; - case FORMULA: - if (cell.getCachedFormulaResultTypeEnum() == CellType.STRING) { - value = cell.getStringCellValue(); - } else { - if (DateUtil.isCellDateFormatted(cell)) { - value = getFormattedDate(cell); - } else { - value += cell.getNumericCellValue(); - } - } - break; - - case NUMERIC: - if (DateUtil.isCellDateFormatted(cell)) { - value = getFormattedDate(cell); - } else { - value += cell.getRawValue(); - } - break; - - default: - - } - if (node instanceof Element) { - Element currentElement = (Element) node; - currentElement.setTextContent(value); - } else { - node.setNodeValue(value); - } - } - - private String removeNamespace(String elementName) { - return elementName.matches(".*:.*")?elementName.split(":")[1]:elementName; - } - - private String getFormattedDate(XSSFCell cell) { - DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); - sdf.setTimeZone(LocaleUtil.getUserTimeZone()); - return sdf.format(cell.getDateCellValue()); - } - - private Node getNodeByXPath(String xpath,Node rootNode,Document doc,boolean createMultipleInstances) { - String[] xpathTokens = xpath.split("/"); - - - Node currentNode =rootNode; - // The first token is empty, the second is the root node - for(int i =2; i rightIndex) { - return 1; - } - } /*else { - // NOTE: the xpath doesn't match correctly in the schema - }*/ - } - } - - return 0; - } - - private int indexOfElementInComplexType(String elementName,Node complexType) { - if(complexType == null) { - return -1; - } - - NodeList list = complexType.getChildNodes(); - int indexOf = -1; - - for(int i=0; i< list.getLength();i++) { - Node node = list.item(i); - if (node instanceof Element) { - if (node.getLocalName().equals("element")) { - Node element = getNameOrRefElement(node); - if (element.getNodeValue().equals(removeNamespace(elementName))) { - indexOf = i; - break; - } - - } - } - } - return indexOf; - } - - private Node getNameOrRefElement(Node node) { - Node returnNode = node.getAttributes().getNamedItem("name"); - if(returnNode != null) { - return returnNode; - } - - return node.getAttributes().getNamedItem("ref"); - } - - private Node getComplexTypeForElement(String elementName,Node xmlSchema,Node localComplexTypeRootNode) { - String elementNameWithoutNamespace = removeNamespace(elementName); - - String complexTypeName = getComplexTypeNameFromChildren(localComplexTypeRootNode, elementNameWithoutNamespace); - - // Note: we expect that all the complex types are defined at root level - Node complexTypeNode = null; - if (!"".equals(complexTypeName)) { - complexTypeNode = getComplexTypeNodeFromSchemaChildren(xmlSchema, null, complexTypeName); - } - - return complexTypeNode; - } - - private String getComplexTypeNameFromChildren(Node localComplexTypeRootNode, - String elementNameWithoutNamespace) { - if(localComplexTypeRootNode == null) { - return ""; - } - - NodeList list = localComplexTypeRootNode.getChildNodes(); - String complexTypeName = ""; - - for(int i=0; i< list.getLength();i++) { - Node node = list.item(i); - if ( node instanceof Element) { - if (node.getLocalName().equals("element")) { - Node nameAttribute = getNameOrRefElement(node); - if (nameAttribute.getNodeValue().equals(elementNameWithoutNamespace)) { - Node complexTypeAttribute = node.getAttributes().getNamedItem("type"); - if (complexTypeAttribute!=null) { - complexTypeName = complexTypeAttribute.getNodeValue(); - break; - } - } - } - } - } - return complexTypeName; - } - - private Node getComplexTypeNodeFromSchemaChildren(Node xmlSchema, Node complexTypeNode, - String complexTypeName) { - NodeList complexTypeList = xmlSchema.getChildNodes(); - for(int i=0; i< complexTypeList.getLength();i++) { - Node node = complexTypeList.item(i); - if ( node instanceof Element) { - if (node.getLocalName().equals("complexType")) { - Node nameAttribute = getNameOrRefElement(node); - if (nameAttribute.getNodeValue().equals(complexTypeName)) { - - NodeList complexTypeChildList =node.getChildNodes(); - for(int j=0; j - *
      • the input XML must be valid according to the XML Schema used in the mapping
      • - *
      • denormalized table mapping is not supported (see OpenOffice part 4: chapter 3.5.1.7)
      • - *
      • all the namespaces used in the document must be declared in the root node
      • - * - */ -public class XSSFImportFromXML { - - private final XSSFMap _map; - - private static POILogger logger = POILogFactory.getLogger(XSSFImportFromXML.class); - - public XSSFImportFromXML(XSSFMap map) { - _map = map; - } - - /** - * Imports an XML into the XLSX using the Custom XML mapping defined - * - * @param xmlInputString the XML to import - * @throws SAXException if error occurs during XML parsing - * @throws XPathExpressionException if error occurs during XML navigation - * @throws ParserConfigurationException if there are problems with XML parser configuration - * @throws IOException if there are problems reading the input string - */ - public void importFromXML(String xmlInputString) throws SAXException, XPathExpressionException, IOException { - - DocumentBuilder builder = DocumentHelper.newDocumentBuilder(); - - Document doc = builder.parse(new InputSource(new StringReader(xmlInputString.trim()))); - - List singleXmlCells = _map.getRelatedSingleXMLCell(); - - List tables = _map.getRelatedTables(); - - XPathFactory xpathFactory = XPathFactory.newInstance(); - XPath xpath = xpathFactory.newXPath(); - - // Setting namespace context to XPath - // Assuming that the namespace prefix in the mapping xpath is the - // same as the one used in the document - xpath.setNamespaceContext(new DefaultNamespaceContext(doc)); - - for (XSSFSingleXmlCell singleXmlCell : singleXmlCells) { - - STXmlDataType.Enum xmlDataType = singleXmlCell.getXmlDataType(); - String xpathString = singleXmlCell.getXpath(); - Node result = (Node) xpath.evaluate(xpathString, doc, XPathConstants.NODE); - // result can be null if value is optional (xsd:minOccurs=0), see bugzilla 55864 - if (result != null) { - String textContent = result.getTextContent(); - logger.log(POILogger.DEBUG, "Extracting with xpath " + xpathString + " : value is '" + textContent + "'"); - XSSFCell cell = singleXmlCell.getReferencedCell(); - logger.log(POILogger.DEBUG, "Setting '" + textContent + "' to cell " + cell.getColumnIndex() + "-" + cell.getRowIndex() + " in sheet " - + cell.getSheet().getSheetName()); - setCellValue(textContent, cell, xmlDataType); - } - } - - for (XSSFTable table : tables) { - - String commonXPath = table.getCommonXpath(); - NodeList result = (NodeList) xpath.evaluate(commonXPath, doc, XPathConstants.NODESET); - int rowOffset = table.getStartCellReference().getRow() + 1;// the first row contains the table header - int columnOffset = table.getStartCellReference().getCol() - 1; - - for (int i = 0; i < result.getLength(); i++) { - - // TODO: implement support for denormalized XMLs (see - // OpenOffice part 4: chapter 3.5.1.7) - - for (XSSFXmlColumnPr xmlColumnPr : table.getXmlColumnPrs()) { - - int localColumnId = (int) xmlColumnPr.getId(); - int rowId = rowOffset + i; - int columnId = columnOffset + localColumnId; - String localXPath = xmlColumnPr.getLocalXPath(); - localXPath = localXPath.substring(localXPath.substring(1).indexOf('/') + 1); - - // Build an XPath to select the right node (assuming - // that the commonXPath != "/") - String nodeXPath = commonXPath + "[" + (i + 1) + "]" + localXPath; - - // TODO: convert the data to the cell format - String value = (String) xpath.evaluate(nodeXPath, result.item(i), XPathConstants.STRING); - logger.log(POILogger.DEBUG, "Extracting with xpath " + nodeXPath + " : value is '" + value + "'"); - XSSFRow row = table.getXSSFSheet().getRow(rowId); - if (row == null) { - row = table.getXSSFSheet().createRow(rowId); - } - - XSSFCell cell = row.getCell(columnId); - if (cell == null) { - cell = row.createCell(columnId); - } - logger.log(POILogger.DEBUG, "Setting '" + value + "' to cell " + cell.getColumnIndex() + "-" + cell.getRowIndex() + " in sheet " - + table.getXSSFSheet().getSheetName()); - setCellValue(value, cell, xmlColumnPr.getXmlDataType()); - } - } - } - } - - private static enum DataType { - BOOLEAN(STXmlDataType.BOOLEAN), // - DOUBLE(STXmlDataType.DOUBLE), // - INTEGER(STXmlDataType.INT, STXmlDataType.UNSIGNED_INT, STXmlDataType.INTEGER), // - STRING(STXmlDataType.STRING), // - DATE(STXmlDataType.DATE); - - private Set xmlDataTypes; - - private DataType(STXmlDataType.Enum... xmlDataTypes) { - this.xmlDataTypes = new HashSet(Arrays.asList(xmlDataTypes)); - } - - public static DataType getDataType(STXmlDataType.Enum xmlDataType) { - for (DataType dataType : DataType.values()) { - if (dataType.xmlDataTypes.contains(xmlDataType)) { - return dataType; - } - } - return null; - } - } - - private void setCellValue(String value, XSSFCell cell, STXmlDataType.Enum xmlDataType) { - DataType type = DataType.getDataType(xmlDataType); - try { - if (value.isEmpty() || type == null) { - cell.setCellValue((String) null); - } else { - switch (type) { - case BOOLEAN: - cell.setCellValue(Boolean.parseBoolean(value)); - break; - case DOUBLE: - cell.setCellValue(Double.parseDouble(value)); - break; - case INTEGER: - cell.setCellValue(Integer.parseInt(value)); - break; - case DATE: - DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", LocaleUtil.getUserLocale()); - Date date = sdf.parse(value); - cell.setCellValue(date); - if (!DateUtil.isValidExcelDate(cell.getNumericCellValue())) { - cell.setCellValue(value); - } - break; - case STRING: - default: - cell.setCellValue(value.trim()); - break; - } - } - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(), "Unable to format value '%s' as %s for cell %s", value, - type, new CellReference(cell).formatAsString())); - } catch (ParseException e) { - throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(), "Unable to format value '%s' as %s for cell %s", value, - type, new CellReference(cell).formatAsString())); - } - } - - private static final class DefaultNamespaceContext implements NamespaceContext { - /** - * Node from which to start searching for a xmlns attribute that binds a - * prefix to a namespace. - */ - private final Element _docElem; - - public DefaultNamespaceContext(Document doc) { - _docElem = doc.getDocumentElement(); - } - - @Override - public String getNamespaceURI(String prefix) { - return getNamespaceForPrefix(prefix); - } - - /** - * @param prefix Prefix to resolve. - * @return uri of Namespace that prefix resolves to, or - * null if specified prefix is not bound. - */ - private String getNamespaceForPrefix(String prefix) { - - // Code adapted from Xalan's org.apache.xml.utils.PrefixResolverDefault.getNamespaceForPrefix() - - if (prefix.equals("xml")) { - return "http://www.w3.org/XML/1998/namespace"; - } - - Node parent = _docElem; - - while (parent != null) { - - int type = parent.getNodeType(); - if (type == Node.ELEMENT_NODE) { - if (parent.getNodeName().startsWith(prefix + ":")) { - return parent.getNamespaceURI(); - } - NamedNodeMap nnm = parent.getAttributes(); - - for (int i = 0; i < nnm.getLength(); i++) { - Node attr = nnm.item(i); - String aname = attr.getNodeName(); - boolean isPrefix = aname.startsWith("xmlns:"); - - if (isPrefix || aname.equals("xmlns")) { - int index = aname.indexOf(':'); - String p = isPrefix ? aname.substring(index + 1) : ""; - - if (p.equals(prefix)) { - return attr.getNodeValue(); - } - } - } - } else if (type == Node.ENTITY_REFERENCE_NODE) { - continue; - } else { - break; - } - parent = parent.getParentNode(); - } - - return null; - } - - // Dummy implementation - not used! - @Override - public Iterator getPrefixes(String val) { - return null; - } - - // Dummy implementation - not used! - @Override - public String getPrefix(String uri) { - return null; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/CalculationChain.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/CalculationChain.java deleted file mode 100644 index 6f254b3f1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/CalculationChain.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcChain; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CalcChainDocument; - -/** - * The cells in a workbook can be calculated in different orders depending on various optimizations and - * dependencies. The calculation chain object specifies the order in which the cells in a workbook were last calculated. - * - * @author Yegor Kozlov - */ -public class CalculationChain extends POIXMLDocumentPart { - private CTCalcChain chain; - - public CalculationChain() { - super(); - chain = CTCalcChain.Factory.newInstance(); - } - - /** - * @since POI 3.14-Beta1 - */ - public CalculationChain(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public CalculationChain(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void readFrom(InputStream is) throws IOException { - try { - CalcChainDocument doc = CalcChainDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - chain = doc.getCalcChain(); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - public void writeTo(OutputStream out) throws IOException { - CalcChainDocument doc = CalcChainDocument.Factory.newInstance(); - doc.setCalcChain(chain); - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - - - public CTCalcChain getCTCalcChain(){ - return chain; - } - - /** - * Remove a formula reference from the calculation chain - * - * @param sheetId the sheet Id of a sheet the formula belongs to. - * @param ref A1 style reference to the cell containing the formula. - */ - public void removeItem(int sheetId, String ref){ - //sheet Id of a sheet the cell belongs to - int id = -1; - CTCalcCell[] c = chain.getCArray(); - - for (int i = 0; i < c.length; i++){ - //If sheet Id is omitted, it is assumed to be the same as the value of the previous cell. - if(c[i].isSetI()) id = c[i].getI(); - - if(id == sheetId && c[i].getR().equals(ref)){ - if(c[i].isSetI() && i < c.length - 1 && !c[i+1].isSetI()) { - c[i+1].setI(id); - } - chain.removeC(i); - break; - } - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java deleted file mode 100644 index 4dfd4bc86..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java +++ /dev/null @@ -1,315 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.util.Internal; -import org.apache.poi.xssf.usermodel.XSSFComment; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument; - -@Internal -public class CommentsTable extends POIXMLDocumentPart { - public static final String DEFAULT_AUTHOR = ""; - public static final int DEFAULT_AUTHOR_ID = 0; - /** - * Underlying XML Beans CTComment list. - */ - private CTComments comments; - /** - * XML Beans uses a list, which is very slow - * to search, so we wrap things with our own - * map for fast lookup. - */ - private Map commentRefs; - - public CommentsTable() { - super(); - comments = CTComments.Factory.newInstance(); - comments.addNewCommentList(); - comments.addNewAuthors().addAuthor(DEFAULT_AUTHOR); - } - - /** - * @since POI 3.14-Beta1 - */ - public CommentsTable(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public CommentsTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void readFrom(InputStream is) throws IOException { - try { - CommentsDocument doc = CommentsDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - comments = doc.getComments(); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - public void writeTo(OutputStream out) throws IOException { - CommentsDocument doc = CommentsDocument.Factory.newInstance(); - doc.setComments(comments); - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - - /** - * Called after the reference is updated, so that - * we can reflect that in our cache - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #referenceUpdated(CellAddress, CTComment)} instead - */ - public void referenceUpdated(String oldReference, CTComment comment) { - referenceUpdated(new CellAddress(oldReference), comment); - } - - /** - * Called after the reference is updated, so that - * we can reflect that in our cache - * @param oldReference the comment to remove from the commentRefs map - * @param comment the comment to replace in the commentRefs map - */ - public void referenceUpdated(CellAddress oldReference, CTComment comment) { - if(commentRefs != null) { - commentRefs.remove(oldReference); - commentRefs.put(new CellAddress(comment.getRef()), comment); - } - } - - public int getNumberOfComments() { - return comments.getCommentList().sizeOfCommentArray(); - } - - public int getNumberOfAuthors() { - return comments.getAuthors().sizeOfAuthorArray(); - } - - public String getAuthor(long authorId) { - return comments.getAuthors().getAuthorArray((int)authorId); - } - - public int findAuthor(String author) { - String[] authorArray = comments.getAuthors().getAuthorArray(); - for (int i = 0 ; i < authorArray.length; i++) { - if (authorArray[i].equals(author)) { - return i; - } - } - return addNewAuthor(author); - } - - /** - * Finds the cell comment at cellAddress, if one exists - * - * @param cellRef the address of the cell to find a comment - * @return cell comment if one exists, otherwise returns null - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #findCellComment(CellAddress)} instead - */ - public XSSFComment findCellComment(String cellRef) { - return findCellComment(new CellAddress(cellRef)); - } - - /** - * Finds the cell comment at cellAddress, if one exists - * - * @param cellAddress the address of the cell to find a comment - * @return cell comment if one exists, otherwise returns null - */ - public XSSFComment findCellComment(CellAddress cellAddress) { - CTComment ct = getCTComment(cellAddress); - return ct == null ? null : new XSSFComment(this, ct, null); - } - - - /** - * Get the underlying CTComment xmlbean for a comment located at cellRef, if it exists - * - * @param ref the location of the cell comment - * @return CTComment xmlbean if comment exists, otherwise return null. - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link CommentsTable#getCTComment(CellAddress)} instead - */ - @Internal - public CTComment getCTComment(String ref) { - return getCTComment(new CellAddress(ref)); - } - - /** - * Get the underlying CTComment xmlbean for a comment located at cellRef, if it exists - * - * @param cellRef the location of the cell comment - * @return CTComment xmlbean if comment exists, otherwise return null. - */ - @Internal - public CTComment getCTComment(CellAddress cellRef) { - // Create the cache if needed - prepareCTCommentCache(); - - // Return the comment, or null if not known - return commentRefs.get(cellRef); - } - - /** - * Returns all cell comments on this sheet. - * @return A map of each Comment in this sheet, keyed on the cell address where - * the comment is located. - */ - public Map getCellComments() { - prepareCTCommentCache(); - final TreeMap map = new TreeMap(); - - for (final Entry e: commentRefs.entrySet()) { - map.put(e.getKey(), new XSSFComment(this, e.getValue(), null)); - } - - return map; - } - - /** - * Refresh Map commentRefs cache, - * Calls that use the commentRefs cache will perform in O(1) - * time rather than O(n) lookup time for List comments. - */ - private void prepareCTCommentCache() { - // Create the cache if needed - if(commentRefs == null) { - commentRefs = new HashMap(); - for (CTComment comment : comments.getCommentList().getCommentArray()) { - commentRefs.put(new CellAddress(comment.getRef()), comment); - } - } - } - - /** - * Create a new comment located at cell address - * - * @param ref the location to add the comment - * @return a new CTComment located at ref with default author - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #newComment(CellAddress)} instead - */ - @Internal - public CTComment newComment(String ref) { - return newComment(new CellAddress(ref)); - } - - /** - * Create a new comment located` at cell address - * - * @param ref the location to add the comment - * @return a new CTComment located at ref with default author - */ - @Internal - public CTComment newComment(CellAddress ref) { - CTComment ct = comments.getCommentList().addNewComment(); - ct.setRef(ref.formatAsString()); - ct.setAuthorId(DEFAULT_AUTHOR_ID); - - if(commentRefs != null) { - commentRefs.put(ref, ct); - } - return ct; - } - - /** - * Remove the comment at cellRef location, if one exists - * - * @param cellRef the location of the comment to remove - * @return returns true if a comment was removed - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #removeComment(CellAddress)} instead - */ - public boolean removeComment(String cellRef) { - return removeComment(new CellAddress(cellRef)); - } - - /** - * Remove the comment at cellRef location, if one exists - * - * @param cellRef the location of the comment to remove - * @return returns true if a comment was removed - */ - public boolean removeComment(CellAddress cellRef) { - final String stringRef = cellRef.formatAsString(); - CTCommentList lst = comments.getCommentList(); - if(lst != null) { - CTComment[] commentArray = lst.getCommentArray(); - for (int i = 0; i < commentArray.length; i++) { - CTComment comment = commentArray[i]; - if (stringRef.equals(comment.getRef())) { - lst.removeComment(i); - - if(commentRefs != null) { - commentRefs.remove(cellRef); - } - return true; - } - } - } - return false; - } - - /** - * Add a new author to the CommentsTable. - * This does not check if the author already exists. - * - * @param author the name of the comment author - * @return the index of the new author - */ - private int addNewAuthor(String author) { - int index = comments.getAuthors().sizeOfAuthorArray(); - comments.getAuthors().insertAuthor(index, author); - return index; - } - - /** - * Returns the underlying CTComments list xmlbean - * - * @return underlying comments list xmlbean - */ - @Internal - public CTComments getCTComments(){ - return comments; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/ExternalLinksTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/ExternalLinksTable.java deleted file mode 100644 index 55762f6b6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/ExternalLinksTable.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.ss.usermodel.Name; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalDefinedName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalLink; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalSheetName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.ExternalLinkDocument; - -/** - * Holds details of links to parts of other workbooks (eg named ranges), - * along with the most recently seen values for what they point to. - */ -public class ExternalLinksTable extends POIXMLDocumentPart { - private CTExternalLink link; - - public ExternalLinksTable() { - super(); - link = CTExternalLink.Factory.newInstance(); - link.addNewExternalBook(); - } - - /** - * @since POI 3.14-Beta1 - */ - public ExternalLinksTable(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public ExternalLinksTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void readFrom(InputStream is) throws IOException { - try { - ExternalLinkDocument doc = ExternalLinkDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - link = doc.getExternalLink(); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - public void writeTo(OutputStream out) throws IOException { - ExternalLinkDocument doc = ExternalLinkDocument.Factory.newInstance(); - doc.setExternalLink(link); - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - - /** - * Returns the underlying xmlbeans object for the external - * link table - */ - public CTExternalLink getCTExternalLink(){ - return link; - } - - /** - * Returns the last recorded name of the file that this - * is linked to - */ - public String getLinkedFileName() { - String rId = link.getExternalBook().getId(); - PackageRelationship rel = getPackagePart().getRelationship(rId); - if (rel != null && rel.getTargetMode() == TargetMode.EXTERNAL) { - return rel.getTargetURI().toString(); - } else { - return null; - } - } - /** - * Updates the last recorded name for the file that this links to - */ - public void setLinkedFileName(String target) { - String rId = link.getExternalBook().getId(); - - if (rId == null || rId.isEmpty()) { - // We're a new External Link Table, so nothing to remove - } else { - // Relationships can't be changed, so remove the old one - getPackagePart().removeRelationship(rId); - } - - // Have a new one added - PackageRelationship newRel = getPackagePart().addExternalRelationship( - target, PackageRelationshipTypes.EXTERNAL_LINK_PATH); - link.getExternalBook().setId(newRel.getId()); - } - - public List getSheetNames() { - CTExternalSheetName[] sheetNames = - link.getExternalBook().getSheetNames().getSheetNameArray(); - List names = new ArrayList(sheetNames.length); - for (CTExternalSheetName name : sheetNames) { - names.add(name.getVal()); - } - return names; - } - - public List getDefinedNames() { - CTExternalDefinedName[] extNames = - link.getExternalBook().getDefinedNames().getDefinedNameArray(); - List names = new ArrayList(extNames.length); - for (CTExternalDefinedName extName : extNames) { - names.add(new ExternalName(extName)); - } - return names; - } - - - // TODO Last seen data - - - protected class ExternalName implements Name { - private CTExternalDefinedName name; - protected ExternalName(CTExternalDefinedName name) { - this.name = name; - } - - public String getNameName() { - return name.getName(); - } - public void setNameName(String name) { - this.name.setName(name); - } - - public String getSheetName() { - int sheetId = getSheetIndex(); - if (sheetId >= 0) { - return getSheetNames().get(sheetId); - } else { - return null; - } - } - public int getSheetIndex() { - if (name.isSetSheetId()) { - return (int)name.getSheetId(); - } - return -1; - } - public void setSheetIndex(int sheetId) { - name.setSheetId(sheetId); - } - - public String getRefersToFormula() { - // Return, without the leading = - return name.getRefersTo().substring(1); - } - public void setRefersToFormula(String formulaText) { - // Save with leading = - name.setRefersTo('=' + formulaText); - } - - public boolean isFunctionName() { - return false; - } - public boolean isDeleted() { - return false; - } - - public String getComment() { - return null; - } - public void setComment(String comment) { - throw new IllegalStateException("Not Supported"); - } - public void setFunction(boolean value) { - throw new IllegalStateException("Not Supported"); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/MapInfo.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/MapInfo.java deleted file mode 100644 index e639591d4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/MapInfo.java +++ /dev/null @@ -1,169 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xssf.usermodel.XSSFMap; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMap; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMapInfo; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSchema; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.MapInfoDocument; - -/** - * - * This class implements the Custom XML Mapping Part (Open Office XML Part 1: - * chapter 12.3.6) - * - * An instance of this part type contains a schema for an XML file, and - * information on the behavior that is used when allowing this custom XML schema - * to be mapped into the spreadsheet. - * - * @author Roberto Manicardi - */ - -public class MapInfo extends POIXMLDocumentPart { - - private CTMapInfo mapInfo; - - private Map maps ; - - public MapInfo() { - super(); - mapInfo = CTMapInfo.Factory.newInstance(); - - } - - /** - * @since POI 3.14-Beta1 - */ - public MapInfo(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - public MapInfo(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void readFrom(InputStream is) throws IOException { - try { - MapInfoDocument doc = MapInfoDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - mapInfo = doc.getMapInfo(); - - maps= new HashMap(); - for(CTMap map :mapInfo.getMapArray()){ - maps.put((int)map.getID(), new XSSFMap(map,this)); - } - - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - /** - * Returns the parent XSSFWorkbook - * - * @return the parent XSSFWorkbook - */ - public XSSFWorkbook getWorkbook() { - return (XSSFWorkbook)getParent(); - } - - /** - * - * @return the internal data object - */ - public CTMapInfo getCTMapInfo(){ - return mapInfo; - - } - - /** - * Gets the - * @param schemaId the schema ID - * @return CTSchema by it's ID - */ - public CTSchema getCTSchemaById(String schemaId){ - CTSchema xmlSchema = null; - - for(CTSchema schema: mapInfo.getSchemaArray()){ - if(schema.getID().equals(schemaId)){ - xmlSchema = schema; - break; - } - } - return xmlSchema; - } - - - public XSSFMap getXSSFMapById(int id){ - return maps.get(id); - } - - public XSSFMap getXSSFMapByName(String name){ - - XSSFMap matchedMap = null; - - for(XSSFMap map :maps.values()){ - if(map.getCtMap().getName()!=null && map.getCtMap().getName().equals(name)){ - matchedMap = map; - } - } - - return matchedMap; - } - - /** - * - * @return all the mappings configured in this document - */ - public Collection getAllXSSFMaps(){ - return maps.values(); - } - - protected void writeTo(OutputStream out) throws IOException { - MapInfoDocument doc = MapInfoDocument.Factory.newInstance(); - doc.setMapInfo(mapInfo); - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/ParagraphPropertyFetcher.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/ParagraphPropertyFetcher.java deleted file mode 100644 index 00f40f790..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/ParagraphPropertyFetcher.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; -import org.apache.xmlbeans.XmlObject; -import org.apache.poi.util.Internal; - -/** - * Used internally to navigate the paragraph text style hierarchy within a shape and fetch properties -*/ -@Internal -public abstract class ParagraphPropertyFetcher { - - private T _value; - private int _level; - - public T getValue(){ - return _value; - } - - public void setValue(T val){ - _value = val; - } - - public ParagraphPropertyFetcher(int level) { - _level = level; - } - - /** - * - * @param shape the shape being examined - * @return true if the desired property was fetched - */ - public boolean fetch(CTShape shape) { - - XmlObject[] o = shape.selectPath( - "declare namespace xdr='http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing' " + - "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + - ".//xdr:txBody/a:lstStyle/a:lvl" + (_level + 1) + "pPr" - ); - if (o.length == 1) { - CTTextParagraphProperties props = (CTTextParagraphProperties) o[0]; - return fetch(props); - } - return false; - } - - public abstract boolean fetch(CTTextParagraphProperties props); -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java deleted file mode 100644 index 8ade04f8f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java +++ /dev/null @@ -1,240 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSst; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.SstDocument; - -/** - * Table of strings shared across all sheets in a workbook. - *

        - * A workbook may contain thousands of cells containing string (non-numeric) data. Furthermore this data is very - * likely to be repeated across many rows or columns. The goal of implementing a single string table that is shared - * across the workbook is to improve performance in opening and saving the file by only reading and writing the - * repetitive information once. - *

        - *

        - * Consider for example a workbook summarizing information for cities within various countries. There may be a - * column for the name of the country, a column for the name of each city in that country, and a column - * containing the data for each city. In this case the country name is repetitive, being duplicated in many cells. - * In many cases the repetition is extensive, and a tremendous savings is realized by making use of a shared string - * table when saving the workbook. When displaying text in the spreadsheet, the cell table will just contain an - * index into the string table as the value of a cell, instead of the full string. - *

        - *

        - * The shared string table contains all the necessary information for displaying the string: the text, formatting - * properties, and phonetic properties (for East Asian languages). - *

        - */ -public class SharedStringsTable extends POIXMLDocumentPart { - - /** - * Array of individual string items in the Shared String table. - */ - private final List strings = new ArrayList(); - - /** - * Maps strings and their indexes in the strings arrays - */ - private final Map stmap = new HashMap(); - - /** - * An integer representing the total count of strings in the workbook. This count does not - * include any numbers, it counts only the total of text strings in the workbook. - */ - private int count; - - /** - * An integer representing the total count of unique strings in the Shared String Table. - * A string is unique even if it is a copy of another string, but has different formatting applied - * at the character level. - */ - private int uniqueCount; - - private SstDocument _sstDoc; - - private final static XmlOptions options = new XmlOptions(); - static { - options.put( XmlOptions.SAVE_INNER ); - options.put( XmlOptions.SAVE_AGGRESSIVE_NAMESPACES ); - options.put( XmlOptions.SAVE_USE_DEFAULT_NAMESPACE ); - options.setSaveImplicitNamespaces(Collections.singletonMap("", NS_SPREADSHEETML)); - } - - public SharedStringsTable() { - super(); - _sstDoc = SstDocument.Factory.newInstance(); - _sstDoc.addNewSst(); - } - - /** - * @since POI 3.14-Beta1 - */ - public SharedStringsTable(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - public SharedStringsTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - /** - * Read this shared strings table from an XML file. - * - * @param is The input stream containing the XML document. - * @throws IOException if an error occurs while reading. - */ - public void readFrom(InputStream is) throws IOException { - try { - int cnt = 0; - _sstDoc = SstDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - CTSst sst = _sstDoc.getSst(); - count = (int)sst.getCount(); - uniqueCount = (int)sst.getUniqueCount(); - for (CTRst st : sst.getSiArray()) { - stmap.put(getKey(st), cnt); - strings.add(st); - cnt++; - } - } catch (XmlException e) { - throw new IOException("unable to parse shared strings table", e); - } - } - - private String getKey(CTRst st) { - return st.xmlText(options); - } - - /** - * Return a string item by index - * - * @param idx index of item to return. - * @return the item at the specified position in this Shared String table. - */ - public CTRst getEntryAt(int idx) { - return strings.get(idx); - } - - /** - * Return an integer representing the total count of strings in the workbook. This count does not - * include any numbers, it counts only the total of text strings in the workbook. - * - * @return the total count of strings in the workbook - */ - public int getCount(){ - return count; - } - - /** - * Returns an integer representing the total count of unique strings in the Shared String Table. - * A string is unique even if it is a copy of another string, but has different formatting applied - * at the character level. - * - * @return the total count of unique strings in the workbook - */ - public int getUniqueCount(){ - return uniqueCount; - } - - /** - * Add an entry to this Shared String table (a new value is appened to the end). - * - *

        - * If the Shared String table already contains this CTRst bean, its index is returned. - * Otherwise a new entry is aded. - *

        - * - * @param st the entry to add - * @return index the index of added entry - */ - public int addEntry(CTRst st) { - String s = getKey(st); - count++; - if (stmap.containsKey(s)) { - return stmap.get(s); - } - - uniqueCount++; - //create a CTRst bean attached to this SstDocument and copy the argument CTRst into it - CTRst newSt = _sstDoc.getSst().addNewSi(); - newSt.set(st); - int idx = strings.size(); - stmap.put(s, idx); - strings.add(newSt); - return idx; - } - /** - * Provide low-level access to the underlying array of CTRst beans - * - * @return array of CTRst beans - */ - public List getItems() { - return Collections.unmodifiableList(strings); - } - - /** - * Write this table out as XML. - * - * @param out The stream to write to. - * @throws IOException if an error occurs while writing. - */ - public void writeTo(OutputStream out) throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - // the following two lines turn off writing CDATA - // see Bugzilla 48936 - xmlOptions.setSaveCDataLengthThreshold(1000000); - xmlOptions.setSaveCDataEntityCountThreshold(-1); - - //re-create the sst table every time saving a workbook - CTSst sst = _sstDoc.getSst(); - sst.setCount(count); - sst.setUniqueCount(uniqueCount); - - _sstDoc.save(out, xmlOptions); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/SingleXmlCells.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/SingleXmlCells.java deleted file mode 100644 index 4b661438a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/SingleXmlCells.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; -import java.util.Vector; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSingleXmlCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSingleXmlCells; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.SingleXmlCellsDocument; - - -/** - * - * This class implements the Single Cell Tables Part (Open Office XML Part 4: - * chapter 3.5.2) - * - * - * @author Roberto Manicardi - */ -public class SingleXmlCells extends POIXMLDocumentPart { - - - private CTSingleXmlCells singleXMLCells; - - public SingleXmlCells() { - super(); - singleXMLCells = CTSingleXmlCells.Factory.newInstance(); - - } - - /** - * @since POI 3.14-Beta1 - */ - public SingleXmlCells(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public SingleXmlCells(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void readFrom(InputStream is) throws IOException { - try { - SingleXmlCellsDocument doc = SingleXmlCellsDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - singleXMLCells = doc.getSingleXmlCells(); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - public XSSFSheet getXSSFSheet(){ - return (XSSFSheet) getParent(); - } - - protected void writeTo(OutputStream out) throws IOException { - SingleXmlCellsDocument doc = SingleXmlCellsDocument.Factory.newInstance(); - doc.setSingleXmlCells(singleXMLCells); - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - - public CTSingleXmlCells getCTSingleXMLCells(){ - return singleXMLCells; - } - - /** - * - * @return all the SimpleXmlCell contained in this SingleXmlCells element - */ - public List getAllSimpleXmlCell(){ - List list = new Vector(); - - for(CTSingleXmlCell singleXmlCell: singleXMLCells.getSingleXmlCellArray()){ - list.add(new XSSFSingleXmlCell(singleXmlCell,this)); - } - return list; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java deleted file mode 100644 index 18b88203f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java +++ /dev/null @@ -1,833 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.BuiltinFormats; -import org.apache.poi.ss.usermodel.FontFamily; -import org.apache.poi.ss.usermodel.FontScheme; -import org.apache.poi.util.Internal; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFFactory; -import org.apache.poi.xssf.usermodel.XSSFFont; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorders; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyleXfs; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellXfs; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxfs; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFills; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFonts; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmts; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument; - -/** - * Table of styles shared across all sheets in a workbook. - */ -public class StylesTable extends POIXMLDocumentPart { - private final SortedMap numberFormats = new TreeMap(); - private final List fonts = new ArrayList(); - private final List fills = new ArrayList(); - private final List borders = new ArrayList(); - private final List styleXfs = new ArrayList(); - private final List xfs = new ArrayList(); - - private final List dxfs = new ArrayList(); - - /** - * The first style id available for use as a custom style - */ - public static final int FIRST_CUSTOM_STYLE_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX + 1; - // Is this right? Number formats (XSSFDataFormat) and cell styles (XSSFCellStyle) are different. What's up with the plus 1? - private static final int MAXIMUM_STYLE_ID = SpreadsheetVersion.EXCEL2007.getMaxCellStyles(); - - private static final short FIRST_USER_DEFINED_NUMBER_FORMAT_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX; - /** - * Depending on the version of Excel, the maximum number of number formats in a workbook is between 200 and 250 - * See https://support.office.com/en-us/article/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 - * POI defaults this limit to 250, but can be increased or decreased on a per-StylesTable basis with - * {@link #setMaxNumberOfDataFormats(int)} if needed. - */ - private int MAXIMUM_NUMBER_OF_DATA_FORMATS = 250; - - /** - * Changes the maximum number of data formats that may be in a style table - * - * @param num the upper limit on number of data formats in the styles table when adding new data formats - * @throws IllegalArgumentException if num < 0 - * @throws IllegalStateException if num < current number of data formats in the style table. - * Data formats must be explicitly removed before the limit can be decreased. - */ - public void setMaxNumberOfDataFormats(int num) { - if (num < getNumDataFormats()) { - if (num < 0) { - throw new IllegalArgumentException("Maximum Number of Data Formats must be greater than or equal to 0"); - } else { - throw new IllegalStateException("Cannot set the maximum number of data formats less than the current quantity." + - "Data formats must be explicitly removed (via StylesTable.removeNumberFormat) before the limit can be decreased."); - } - } - MAXIMUM_NUMBER_OF_DATA_FORMATS = num; - } - - /** - * Get the upper limit on the number of data formats that has been set for the style table. - * To get the current number of data formats in use, use {@link #getNumDataFormats()}. - * - * @return the maximum number of data formats allowed in the workbook - */ - public int getMaxNumberOfDataFormats() { - return MAXIMUM_NUMBER_OF_DATA_FORMATS; - } - - private StyleSheetDocument doc; - private XSSFWorkbook workbook; - private ThemesTable theme; - - /** - * Create a new, empty StylesTable - */ - public StylesTable() { - super(); - doc = StyleSheetDocument.Factory.newInstance(); - doc.addNewStyleSheet(); - // Initialization required in order to make the document readable by MSExcel - initialize(); - } - - /** - * @since POI 3.14-Beta1 - */ - public StylesTable(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public StylesTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void setWorkbook(XSSFWorkbook wb) { - this.workbook = wb; - } - - /** - * Get the current Workbook's theme table, or null if the - * Workbook lacks any themes. - *

        Use {@link #ensureThemesTable()} to have a themes table - * created if needed - */ - public ThemesTable getTheme() { - return theme; - } - - public void setTheme(ThemesTable theme) { - this.theme = theme; - - // Pass the themes table along to things which need to - // know about it, but have already been created by now - for(XSSFFont font : fonts) { - font.setThemesTable(theme); - } - for(XSSFCellBorder border : borders) { - border.setThemesTable(theme); - } - } - - /** - * If there isn't currently a {@link ThemesTable} for the - * current Workbook, then creates one and sets it up. - * After this, calls to {@link #getTheme()} won't give null - */ - public void ensureThemesTable() { - if (theme != null) return; - - theme = (ThemesTable)workbook.createRelationship(XSSFRelation.THEME, XSSFFactory.getInstance()); - } - - /** - * Read this shared styles table from an XML file. - * - * @param is The input stream containing the XML document. - * @throws IOException if an error occurs while reading. - */ - protected void readFrom(InputStream is) throws IOException { - try { - doc = StyleSheetDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - - CTStylesheet styleSheet = doc.getStyleSheet(); - - // Grab all the different bits we care about - CTNumFmts ctfmts = styleSheet.getNumFmts(); - if( ctfmts != null){ - for (CTNumFmt nfmt : ctfmts.getNumFmtArray()) { - short formatId = (short)nfmt.getNumFmtId(); - numberFormats.put(formatId, nfmt.getFormatCode()); - } - } - - CTFonts ctfonts = styleSheet.getFonts(); - if(ctfonts != null){ - int idx = 0; - for (CTFont font : ctfonts.getFontArray()) { - // Create the font and save it. Themes Table supplied later - XSSFFont f = new XSSFFont(font, idx); - fonts.add(f); - idx++; - } - } - CTFills ctfills = styleSheet.getFills(); - if(ctfills != null){ - for (CTFill fill : ctfills.getFillArray()) { - fills.add(new XSSFCellFill(fill)); - } - } - - CTBorders ctborders = styleSheet.getBorders(); - if(ctborders != null) { - for (CTBorder border : ctborders.getBorderArray()) { - borders.add(new XSSFCellBorder(border)); - } - } - - CTCellXfs cellXfs = styleSheet.getCellXfs(); - if(cellXfs != null) xfs.addAll(Arrays.asList(cellXfs.getXfArray())); - - CTCellStyleXfs cellStyleXfs = styleSheet.getCellStyleXfs(); - if(cellStyleXfs != null) styleXfs.addAll(Arrays.asList(cellStyleXfs.getXfArray())); - - CTDxfs styleDxfs = styleSheet.getDxfs(); - if(styleDxfs != null) dxfs.addAll(Arrays.asList(styleDxfs.getDxfArray())); - - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - // =========================================================== - // Start of style related getters and setters - // =========================================================== - - /** - * Get number format string given its id - * - * @param fmtId number format id - * @return number format code - */ - public String getNumberFormatAt(short fmtId) { - return numberFormats.get(fmtId); - } - - private short getNumberFormatId(String fmt) { - // Find the key, and return that - for (Entry numFmt : numberFormats.entrySet()) { - if(numFmt.getValue().equals(fmt)) { - return numFmt.getKey(); - } - } - throw new IllegalStateException("Number format not in style table: " + fmt); - } - - /** - * Puts fmt in the numberFormats map if the format is not - * already in the the number format style table. - * Does nothing if fmt is already in number format style table. - * - * @param fmt the number format to add to number format style table - * @return the index of fmt in the number format style table - * @throws IllegalStateException if adding the number format to the styles table - * would exceed the {@link #MAXIMUM_NUMBER_OF_DATA_FORMATS} allowed. - */ - public int putNumberFormat(String fmt) { - // Check if number format already exists - if (numberFormats.containsValue(fmt)) { - try { - return getNumberFormatId(fmt); - } catch (final IllegalStateException e) { - throw new IllegalStateException("Found the format, but couldn't figure out where - should never happen!"); - } - } - - - if (numberFormats.size() >= MAXIMUM_NUMBER_OF_DATA_FORMATS) { - throw new IllegalStateException("The maximum number of Data Formats was exceeded. " + - "You can define up to " + MAXIMUM_NUMBER_OF_DATA_FORMATS + " formats in a .xlsx Workbook."); - } - - // Find a spare key, and add that - final short formatIndex; - if (numberFormats.isEmpty()) { - formatIndex = FIRST_USER_DEFINED_NUMBER_FORMAT_ID; - } - else { - // get next-available numberFormat index. - // Assumption: gaps in number format ids are acceptable - // to catch arithmetic overflow, nextKey's data type - // must match numberFormat's key data type - short nextKey = (short) (numberFormats.lastKey() + 1); - if (nextKey < 0) { - throw new IllegalStateException( - "Cowardly avoiding creating a number format with a negative id." + - "This is probably due to arithmetic overflow."); - } - formatIndex = (short) Math.max(nextKey, FIRST_USER_DEFINED_NUMBER_FORMAT_ID); - } - - numberFormats.put(formatIndex, fmt); - return formatIndex; - } - - - /** - * Add a number format with a specific ID into the numberFormats map. - * If a format with the same ID already exists, overwrite the format code - * with fmt - * This may be used to override built-in number formats. - * - * @param index the number format ID - * @param fmt the number format code - */ - public void putNumberFormat(short index, String fmt) { - numberFormats.put(index, fmt); - } - - /** - * Remove a number format from the style table if it exists. - * All cell styles with this number format will be modified to use the default number format. - * - * @param index the number format id to remove - * @return true if the number format was removed - */ - public boolean removeNumberFormat(short index) { - String fmt = numberFormats.remove(index); - boolean removed = (fmt != null); - if (removed) { - for (final CTXf style : xfs) { - if (style.isSetNumFmtId() && style.getNumFmtId() == index) { - style.unsetApplyNumberFormat(); - style.unsetNumFmtId(); - } - } - } - return removed; - } - - /** - * Remove a number format from the style table if it exists - * All cell styles with this number format will be modified to use the default number format - * - * @param fmt the number format to remove - * @return true if the number format was removed - */ - public boolean removeNumberFormat(String fmt) { - short id = getNumberFormatId(fmt); - return removeNumberFormat(id); - } - - public XSSFFont getFontAt(int idx) { - return fonts.get(idx); - } - - /** - * Records the given font in the font table. - * Will re-use an existing font index if this - * font matches another, EXCEPT if forced - * registration is requested. - * This allows people to create several fonts - * then customise them later. - * Note - End Users probably want to call - * {@link XSSFFont#registerTo(StylesTable)} - */ - public int putFont(XSSFFont font, boolean forceRegistration) { - int idx = -1; - if(!forceRegistration) { - idx = fonts.indexOf(font); - } - - if (idx != -1) { - return idx; - } - - idx = fonts.size(); - fonts.add(font); - return idx; - } - public int putFont(XSSFFont font) { - return putFont(font, false); - } - - public XSSFCellStyle getStyleAt(int idx) { - int styleXfId = 0; - - // 0 is the empty default - if(xfs.get(idx).getXfId() > 0) { - styleXfId = (int) xfs.get(idx).getXfId(); - } - - return new XSSFCellStyle(idx, styleXfId, this, theme); - } - public int putStyle(XSSFCellStyle style) { - CTXf mainXF = style.getCoreXf(); - - if(! xfs.contains(mainXF)) { - xfs.add(mainXF); - } - return xfs.indexOf(mainXF); - } - - public XSSFCellBorder getBorderAt(int idx) { - return borders.get(idx); - } - - /** - * Adds a border to the border style table if it isn't already in the style table - * Does nothing if border is already in borders style table - * - * @param border border to add - * @return the index of the added border - */ - public int putBorder(XSSFCellBorder border) { - int idx = borders.indexOf(border); - if (idx != -1) { - return idx; - } - borders.add(border); - border.setThemesTable(theme); - return borders.size() - 1; - } - - public XSSFCellFill getFillAt(int idx) { - return fills.get(idx); - } - - public List getBorders(){ - return Collections.unmodifiableList(borders); - } - - public List getFills(){ - return Collections.unmodifiableList(fills); - } - - public List getFonts(){ - return Collections.unmodifiableList(fonts); - } - - public Map getNumberFormats(){ - return Collections.unmodifiableMap(numberFormats); - } - - /** - * Adds a fill to the fill style table if it isn't already in the style table - * Does nothing if fill is already in fill style table - * - * @param fill fill to add - * @return the index of the added fill - */ - public int putFill(XSSFCellFill fill) { - int idx = fills.indexOf(fill); - if (idx != -1) { - return idx; - } - fills.add(fill); - return fills.size() - 1; - } - - @Internal - public CTXf getCellXfAt(int idx) { - return xfs.get(idx); - } - - /** - * Adds a cell to the styles table. - * Does not check for duplicates. - * - * @param cellXf the cell to add to the styles table - * @return the added cell ID in the style table - */ - @Internal - public int putCellXf(CTXf cellXf) { - xfs.add(cellXf); - return xfs.size(); - } - - @Internal - public void replaceCellXfAt(int idx, CTXf cellXf) { - xfs.set(idx, cellXf); - } - - @Internal - public CTXf getCellStyleXfAt(int idx) { - try { - return styleXfs.get(idx); - } - catch (final IndexOutOfBoundsException e) { - return null; - } - } - - /** - * Adds a cell style to the styles table. - * Does not check for duplicates. - * - * @param cellStyleXf the cell style to add to the styles table - * @return the cell style ID in the style table - */ - @Internal - public int putCellStyleXf(CTXf cellStyleXf) { - styleXfs.add(cellStyleXf); - // TODO: check for duplicate - return styleXfs.size(); - } - - @Internal - protected void replaceCellStyleXfAt(int idx, CTXf cellStyleXf) { - styleXfs.set(idx, cellStyleXf); - } - - /** - * get the size of cell styles - */ - public int getNumCellStyles(){ - // Each cell style has a unique xfs entry - // Several might share the same styleXfs entry - return xfs.size(); - } - - /** - * @return number of data formats in the styles table - */ - public int getNumDataFormats() { - return numberFormats.size(); - } - - /** - * For unit testing only - * @deprecated POI 3.14 beta 2. Use {@link #getNumDataFormats()} instead. - */ - @Internal - public int _getNumberFormatSize() { - return getNumDataFormats(); - } - - /** - * For unit testing only - */ - @Internal - /*package*/ int _getXfsSize() { - return xfs.size(); - } - /** - * For unit testing only - */ - @Internal - public int _getStyleXfsSize() { - return styleXfs.size(); - } - - /** - * For unit testing only! - */ - @Internal - public CTStylesheet getCTStylesheet() { - return doc.getStyleSheet(); - } - - @Internal - public int _getDXfsSize() { - return dxfs.size(); - } - - - /** - * Write this table out as XML. - * - * @param out The stream to write to. - * @throws IOException if an error occurs while writing. - */ - public void writeTo(OutputStream out) throws IOException { - // Work on the current one - // Need to do this, as we don't handle - // all the possible entries yet - CTStylesheet styleSheet = doc.getStyleSheet(); - - // Formats - CTNumFmts formats = CTNumFmts.Factory.newInstance(); - formats.setCount(numberFormats.size()); - for (final Entry entry : numberFormats.entrySet()) { - CTNumFmt ctFmt = formats.addNewNumFmt(); - ctFmt.setNumFmtId(entry.getKey()); - ctFmt.setFormatCode(entry.getValue()); - } - styleSheet.setNumFmts(formats); - - int idx; - // Fonts - CTFonts ctFonts = styleSheet.getFonts(); - if (ctFonts == null) { - ctFonts = CTFonts.Factory.newInstance(); - } - ctFonts.setCount(fonts.size()); - CTFont[] ctfnt = new CTFont[fonts.size()]; - idx = 0; - for(XSSFFont f : fonts) ctfnt[idx++] = f.getCTFont(); - ctFonts.setFontArray(ctfnt); - styleSheet.setFonts(ctFonts); - - // Fills - CTFills ctFills = styleSheet.getFills(); - if (ctFills == null) { - ctFills = CTFills.Factory.newInstance(); - } - ctFills.setCount(fills.size()); - CTFill[] ctf = new CTFill[fills.size()]; - idx = 0; - for(XSSFCellFill f : fills) ctf[idx++] = f.getCTFill(); - ctFills.setFillArray(ctf); - styleSheet.setFills(ctFills); - - // Borders - CTBorders ctBorders = styleSheet.getBorders(); - if (ctBorders == null) { - ctBorders = CTBorders.Factory.newInstance(); - } - ctBorders.setCount(borders.size()); - CTBorder[] ctb = new CTBorder[borders.size()]; - idx = 0; - for(XSSFCellBorder b : borders) ctb[idx++] = b.getCTBorder(); - ctBorders.setBorderArray(ctb); - styleSheet.setBorders(ctBorders); - - // Xfs - if(xfs.size() > 0) { - CTCellXfs ctXfs = styleSheet.getCellXfs(); - if (ctXfs == null) { - ctXfs = CTCellXfs.Factory.newInstance(); - } - ctXfs.setCount(xfs.size()); - ctXfs.setXfArray( - xfs.toArray(new CTXf[xfs.size()]) - ); - styleSheet.setCellXfs(ctXfs); - } - - // Style xfs - if(styleXfs.size() > 0) { - CTCellStyleXfs ctSXfs = styleSheet.getCellStyleXfs(); - if (ctSXfs == null) { - ctSXfs = CTCellStyleXfs.Factory.newInstance(); - } - ctSXfs.setCount(styleXfs.size()); - ctSXfs.setXfArray( - styleXfs.toArray(new CTXf[styleXfs.size()]) - ); - styleSheet.setCellStyleXfs(ctSXfs); - } - - // Style dxfs - if(dxfs.size() > 0) { - CTDxfs ctDxfs = styleSheet.getDxfs(); - if (ctDxfs == null) { - ctDxfs = CTDxfs.Factory.newInstance(); - } - ctDxfs.setCount(dxfs.size()); - ctDxfs.setDxfArray(dxfs.toArray(new CTDxf[dxfs.size()])); - styleSheet.setDxfs(ctDxfs); - } - - // Save - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - - private void initialize() { - //CTFont ctFont = createDefaultFont(); - XSSFFont xssfFont = createDefaultFont(); - fonts.add(xssfFont); - - CTFill[] ctFill = createDefaultFills(); - fills.add(new XSSFCellFill(ctFill[0])); - fills.add(new XSSFCellFill(ctFill[1])); - - CTBorder ctBorder = createDefaultBorder(); - borders.add(new XSSFCellBorder(ctBorder)); - - CTXf styleXf = createDefaultXf(); - styleXfs.add(styleXf); - CTXf xf = createDefaultXf(); - xf.setXfId(0); - xfs.add(xf); - } - - private static CTXf createDefaultXf() { - CTXf ctXf = CTXf.Factory.newInstance(); - ctXf.setNumFmtId(0); - ctXf.setFontId(0); - ctXf.setFillId(0); - ctXf.setBorderId(0); - return ctXf; - } - private static CTBorder createDefaultBorder() { - CTBorder ctBorder = CTBorder.Factory.newInstance(); - ctBorder.addNewBottom(); - ctBorder.addNewTop(); - ctBorder.addNewLeft(); - ctBorder.addNewRight(); - ctBorder.addNewDiagonal(); - return ctBorder; - } - - - private static CTFill[] createDefaultFills() { - CTFill[] ctFill = new CTFill[]{CTFill.Factory.newInstance(),CTFill.Factory.newInstance()}; - ctFill[0].addNewPatternFill().setPatternType(STPatternType.NONE); - ctFill[1].addNewPatternFill().setPatternType(STPatternType.DARK_GRAY); - return ctFill; - } - - private static XSSFFont createDefaultFont() { - CTFont ctFont = CTFont.Factory.newInstance(); - XSSFFont xssfFont=new XSSFFont(ctFont, 0); - xssfFont.setFontHeightInPoints(XSSFFont.DEFAULT_FONT_SIZE); - xssfFont.setColor(XSSFFont.DEFAULT_FONT_COLOR);//setTheme - xssfFont.setFontName(XSSFFont.DEFAULT_FONT_NAME); - xssfFont.setFamily(FontFamily.SWISS); - xssfFont.setScheme(FontScheme.MINOR); - return xssfFont; - } - - @Internal - public CTDxf getDxfAt(int idx) { - return dxfs.get(idx); - } - - /** - * Adds a Dxf to the style table - * Does not check for duplicates. - * - * @param dxf the Dxf to add - * @return added dxf ID in the style table - */ - @Internal - public int putDxf(CTDxf dxf) { - this.dxfs.add(dxf); - return this.dxfs.size(); - } - - /** - * Create a cell style in this style table. - * Note - End users probably want to call {@link XSSFWorkbook#createCellStyle()} - * rather than working with the styles table directly. - * @throws IllegalStateException if the maximum number of cell styles has been reached. - */ - public XSSFCellStyle createCellStyle() { - if (getNumCellStyles() > MAXIMUM_STYLE_ID) { - throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " + - "You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook"); - } - - int xfSize = styleXfs.size(); - CTXf xf = CTXf.Factory.newInstance(); - xf.setNumFmtId(0); - xf.setFontId(0); - xf.setFillId(0); - xf.setBorderId(0); - xf.setXfId(0); - int indexXf = putCellXf(xf); - return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme); - } - - /** - * Finds a font that matches the one with the supplied attributes - * @deprecated POI 3.15 beta 2. Use {@link #findFont(boolean, short, short, String, boolean, boolean, short, byte)} instead. - */ - public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) { - for (XSSFFont font : fonts) { - if ( (font.getBoldweight() == boldWeight) - && font.getColor() == color - && font.getFontHeight() == fontHeight - && font.getFontName().equals(name) - && font.getItalic() == italic - && font.getStrikeout() == strikeout - && font.getTypeOffset() == typeOffset - && font.getUnderline() == underline) - { - return font; - } - } - return null; - } - - /** - * Finds a font that matches the one with the supplied attributes - */ - public XSSFFont findFont(boolean bold, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) { - for (XSSFFont font : fonts) { - if ( (font.getBold() == bold) - && font.getColor() == color - && font.getFontHeight() == fontHeight - && font.getFontName().equals(name) - && font.getItalic() == italic - && font.getStrikeout() == strikeout - && font.getTypeOffset() == typeOffset - && font.getUnderline() == underline) - { - return font; - } - } - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java deleted file mode 100644 index 0fe4abf42..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java +++ /dev/null @@ -1,188 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme; -import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; - -/** - * Class that represents theme of XLSX document. The theme includes specific - * colors and fonts. - */ -public class ThemesTable extends POIXMLDocumentPart { - public enum ThemeElement { - LT1(0, "Lt1"), - DK1(1,"Dk1"), - LT2(2,"Lt2"), - DK2(3,"Dk2"), - ACCENT1(4,"Accent1"), - ACCENT2(5,"Accent2"), - ACCENT3(6,"Accent3"), - ACCENT4(7,"Accent4"), - ACCENT5(8,"Accent5"), - ACCENT6(9,"Accent6"), - HLINK(10,"Hlink"), - FOLHLINK(11,"FolHlink"), - UNKNOWN(-1,null); - - public static ThemeElement byId(int idx) { - if (idx >= values().length || idx < 0) return UNKNOWN; - return values()[idx]; - } - private ThemeElement(int idx, String name) { - this.idx = idx; this.name = name; - } - public final int idx; - public final String name; - } - - private ThemeDocument theme; - - /** - * Create a new, empty ThemesTable - */ - public ThemesTable() { - super(); - theme = ThemeDocument.Factory.newInstance(); - theme.addNewTheme().addNewThemeElements(); - } - - /** - * Construct a ThemesTable. - * @param part A PackagePart. - * - * @since POI 3.14-Beta1 - */ - public ThemesTable(PackagePart part) throws IOException { - super(part); - - try { - theme = ThemeDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS); - } catch(XmlException e) { - throw new IOException(e.getLocalizedMessage(), e); - } - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public ThemesTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - /** - * Construct a ThemesTable from an existing ThemeDocument. - * @param theme A ThemeDocument. - */ - public ThemesTable(ThemeDocument theme) { - this.theme = theme; - } - - /** - * Convert a theme "index" (as used by fonts etc) into a color. - * @param idx A theme "index" - * @return The mapped XSSFColor, or null if not mapped. - */ - public XSSFColor getThemeColor(int idx) { - // Theme color references are NOT positional indices into the color scheme, - // i.e. these keys are NOT the same as the order in which theme colors appear - // in theme1.xml. They are keys to a mapped color. - CTColorScheme colorScheme = theme.getTheme().getThemeElements().getClrScheme(); - CTColor ctColor; - switch (ThemeElement.byId(idx)) { - case LT1: ctColor = colorScheme.getLt1(); break; - case DK1: ctColor = colorScheme.getDk1(); break; - case LT2: ctColor = colorScheme.getLt2(); break; - case DK2: ctColor = colorScheme.getDk2(); break; - case ACCENT1: ctColor = colorScheme.getAccent1(); break; - case ACCENT2: ctColor = colorScheme.getAccent2(); break; - case ACCENT3: ctColor = colorScheme.getAccent3(); break; - case ACCENT4: ctColor = colorScheme.getAccent4(); break; - case ACCENT5: ctColor = colorScheme.getAccent5(); break; - case ACCENT6: ctColor = colorScheme.getAccent6(); break; - case HLINK: ctColor = colorScheme.getHlink(); break; - case FOLHLINK:ctColor = colorScheme.getFolHlink();break; - default: return null; - } - - byte[] rgb = null; - if (ctColor.isSetSrgbClr()) { - // Color is a regular one - rgb = ctColor.getSrgbClr().getVal(); - } else if (ctColor.isSetSysClr()) { - // Color is a tint of white or black - rgb = ctColor.getSysClr().getLastClr(); - } else { - return null; - } - return new XSSFColor(rgb); - } - - /** - * If the colour is based on a theme, then inherit - * information (currently just colours) from it as - * required. - */ - public void inheritFromThemeAsRequired(XSSFColor color) { - if(color == null) { - // Nothing for us to do - return; - } - if(! color.getCTColor().isSetTheme()) { - // No theme set, nothing to do - return; - } - - // Get the theme colour - XSSFColor themeColor = getThemeColor(color.getTheme()); - // Set the raw colour, not the adjusted one - // Do a raw set, no adjusting at the XSSFColor layer either - color.getCTColor().setRgb(themeColor.getCTColor().getRgb()); - - // All done - } - - /** - * Write this table out as XML. - * - * @param out The stream to write to. - * @throws IOException if an error occurs while writing. - */ - public void writeTo(OutputStream out) throws IOException { - theme.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/AutoSizeColumnTracker.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/AutoSizeColumnTracker.java deleted file mode 100644 index 03a29a367..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/AutoSizeColumnTracker.java +++ /dev/null @@ -1,371 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.SheetUtil; -import org.apache.poi.util.Internal; - -/** - * Tracks best fit column width for rows of an {@link SXSSFSheet}, - * to be able to correctly calculate auto-sized column widths even - * if some rows are already flushed to disk. - * This is an auxiliary data structure that uses a TreeMap containing - * one entry per tracked column, where the key is the column index and - * the value is a pair of doubles. This data structure's memory footprint - * is linear with the number of *tracked* columns and invariant with - * the number of rows or columns in the sheet. - * @since 3.14beta1 -*/ -@Internal -/*package*/ class AutoSizeColumnTracker { - private final int defaultCharWidth; - private final DataFormatter dataFormatter = new DataFormatter(); - - // map of tracked columns, with values containing the best-fit width for the column - // Using a HashMap instead of a TreeMap because insertion (trackColumn), removal (untrackColumn), and membership (everything) - // will be called more frequently than getTrackedColumns(). The O(1) cost of insertion, removal, and membership operations - // outweigh the infrequent O(n*log n) cost of sorting getTrackedColumns(). - // Memory consumption for a HashMap and TreeMap is about the same - private final Map maxColumnWidths = new HashMap(); - // untrackedColumns stores columns have been explicitly untracked so they aren't implicitly re-tracked by trackAllColumns - // Using a HashSet instead of a TreeSet because we don't care about order. - private final Set untrackedColumns = new HashSet(); - private boolean trackAllColumns = false; - - /** - * Tuple to store the column widths considering and not considering merged cells - * If more permutations are needed, it may be prudent to require the user to specify - * how they intend to auto-size a column when they track the column, so calculations - * are limited to the desired intentions. Unless this proves to be a performance problem, - * it's probably better to let the user defer how they want to auto-size to SXSSFSheet.autoSizeColumn, - * rather than twice (via SXSSFSheet.trackColumn(int column, boolean useMergedCells) and again at - * SXSFSheet.autoSizeColumn(int column, boolean useMergedCells)) - * @since 3.14beta1 - */ - private static class ColumnWidthPair { - private double withSkipMergedCells; - private double withUseMergedCells; - - public ColumnWidthPair() { - this(-1.0, -1.0); - } - - public ColumnWidthPair(final double columnWidthSkipMergedCells, final double columnWidthUseMergedCells) { - withSkipMergedCells = columnWidthSkipMergedCells; - withUseMergedCells = columnWidthUseMergedCells; - } - - /** - * Gets the current best-fit column width for the provided settings - * - * @param useMergedCells true if merged cells are considered into the best-fit column width calculation - * @return best fit column width, measured in default character widths. - */ - public double getMaxColumnWidth(final boolean useMergedCells) { - return useMergedCells ? withUseMergedCells : withSkipMergedCells; - } - - /** - * Sets the best-fit column width to the maximum of the current width and the provided width - * - * @param unmergedWidth the best-fit column width calculated with useMergedCells=False - * @param mergedWidth the best-fit column width calculated with useMergedCells=True - */ - public void setMaxColumnWidths(double unmergedWidth, double mergedWidth) { - withUseMergedCells = Math.max(withUseMergedCells, mergedWidth); - withSkipMergedCells = Math.max(withUseMergedCells, unmergedWidth); - } - } - - /** - * AutoSizeColumnTracker constructor. Holds no reference to sheet - * - * @param sheet the sheet associated with this auto-size column tracker - * @since 3.14beta1 - */ - public AutoSizeColumnTracker(final Sheet sheet) { - // If sheet needs to be saved, use a java.lang.ref.WeakReference to avoid garbage collector gridlock. - defaultCharWidth = SheetUtil.getDefaultCharWidth(sheet.getWorkbook()); - } - - /** - * Get the currently tracked columns, naturally ordered. - * Note if all columns are tracked, this will only return the columns that have been explicitly or implicitly tracked, - * which is probably only columns containing 1 or more non-blank values - * - * @return a set of the indices of all tracked columns - * @since 3.14beta1 - */ - public SortedSet getTrackedColumns() { - SortedSet sorted = new TreeSet(maxColumnWidths.keySet()); - return Collections.unmodifiableSortedSet(sorted); - } - - /** - * Returns true if column is currently tracked for auto-sizing. - * - * @param column the index of the column to check - * @return true if column is tracked - * @since 3.14beta1 - */ - public boolean isColumnTracked(int column) { - return trackAllColumns || maxColumnWidths.containsKey(column); - } - - /** - * Returns true if all columns are implicitly tracked. - * - * @return true if all columns are implicitly tracked - * @since 3.14beta1 - */ - public boolean isAllColumnsTracked() { - return trackAllColumns; - } - - /** - * Tracks all non-blank columns - * Allows columns that have been explicitly untracked to be tracked - * @since 3.14beta1 - */ - public void trackAllColumns() { - trackAllColumns = true; - untrackedColumns.clear(); - } - - /** - * Untrack all columns that were previously tracked for auto-sizing. - * All best-fit column widths are forgotten. - * @since 3.14beta1 - */ - public void untrackAllColumns() { - trackAllColumns = false; - maxColumnWidths.clear(); - untrackedColumns.clear(); - } - - /** - * Marks multiple columns for inclusion in auto-size column tracking. - * Note this has undefined behavior if columns are tracked after one or more rows are written to the sheet. - * Any column in columns that are already tracked are ignored by this call. - * - * @param columns the indices of the columns to track - * @since 3.14beta1 - */ - public void trackColumns(Collection columns) - { - for (final int column : columns) { - trackColumn(column); - } - } - - /** - * Marks a column for inclusion in auto-size column tracking. - * Note this has undefined behavior if a column is tracked after one or more rows are written to the sheet. - * If column is already tracked, this call does nothing. - * - * @param column the index of the column to track for auto-sizing - * @return if column is already tracked, the call does nothing and returns false - * @since 3.14beta1 - */ - public boolean trackColumn(int column) { - untrackedColumns.remove(column); - if (!maxColumnWidths.containsKey(column)) { - maxColumnWidths.put(column, new ColumnWidthPair()); - return true; - } - return false; - } - - /** - * Implicitly track a column if it has not been explicitly untracked - * If it has been explicitly untracked, this call does nothing and returns false. - * Otherwise return true - * - * @param column the column to implicitly track - * @return false if column has been explicitly untracked, otherwise return true - */ - private boolean implicitlyTrackColumn(int column) { - if (!untrackedColumns.contains(column)) { - trackColumn(column); - return true; - } - return false; - } - - /** - * Removes columns that were previously marked for inclusion in auto-size column tracking. - * When a column is untracked, the best-fit width is forgotten. - * Any column in columns that is not tracked will be ignored by this call. - * - * @param columns the indices of the columns to track for auto-sizing - * @return true if one or more columns were untracked as a result of this call - * @since 3.14beta1 - */ - public boolean untrackColumns(Collection columns) - { - untrackedColumns.addAll(columns); - return maxColumnWidths.keySet().removeAll(columns); - } - - /** - * Removes a column that was previously marked for inclusion in auto-size column tracking. - * When a column is untracked, the best-fit width is forgotten. - * If column is not tracked, it will be ignored by this call. - * - * @param column the index of the column to track for auto-sizing - * @return true if column was tracked prior this call, false if no action was taken - * @since 3.14beta1 - */ - public boolean untrackColumn(int column) { - untrackedColumns.add(column); - return maxColumnWidths.keySet().remove(column); - } - - /** - * Get the best-fit width of a tracked column - * - * @param column the index of the column to get the current best-fit width of - * @param useMergedCells true if merged cells should be considered when computing the best-fit width - * @return best-fit column width, measured in number of characters - * @throws IllegalStateException if column is not tracked and trackAllColumns is false - * @since 3.14beta1 - */ - public int getBestFitColumnWidth(int column, boolean useMergedCells) { - if (!maxColumnWidths.containsKey(column)) { - // if column is not tracked, implicitly track the column if trackAllColumns is True and column has not been explicitly untracked - if (trackAllColumns) { - if (!implicitlyTrackColumn(column)) { - final Throwable reason = new IllegalStateException( - "Column was explicitly untracked after trackAllColumns() was called."); - throw new IllegalStateException( - "Cannot get best fit column width on explicitly untracked column " + column + ". " + - "Either explicitly track the column or track all columns.", reason); - } - } - else { - final Throwable reason = new IllegalStateException( - "Column was never explicitly tracked and isAllColumnsTracked() is false " + - "(trackAllColumns() was never called or untrackAllColumns() was called after trackAllColumns() was called)."); - throw new IllegalStateException( - "Cannot get best fit column width on untracked column " + column + ". " + - "Either explicitly track the column or track all columns.", reason); - } - } - final double width = maxColumnWidths.get(column).getMaxColumnWidth(useMergedCells); - return (int) (256*width); - } - - - - /** - * Calculate the best fit width for each tracked column in row - * - * @param row the row to get the cells - * @since 3.14beta1 - */ - public void updateColumnWidths(Row row) { - // track new columns - implicitlyTrackColumnsInRow(row); - - // update the widths - // for-loop over the shorter of the number of cells in the row and the number of tracked columns - // these two for-loops should do the same thing - if (maxColumnWidths.size() < row.getPhysicalNumberOfCells()) { - // loop over the tracked columns, because there are fewer tracked columns than cells in this row - for (final Entry e : maxColumnWidths.entrySet()) { - final int column = e.getKey(); - final Cell cell = row.getCell(column); //is MissingCellPolicy=Row.RETURN_NULL_AND_BLANK needed? - - // FIXME: if cell belongs to a merged region, some of the merged region may have fallen outside of the random access window - // In this case, getting the column width may result in an error. Need to gracefully handle this. - - // FIXME: Most cells are not merged, so calling getCellWidth twice re-computes the same value twice. - // Need to rewrite this to avoid unnecessary computation if this proves to be a performance bottleneck. - - if (cell != null) { - final ColumnWidthPair pair = e.getValue(); - updateColumnWidth(cell, pair); - } - } - } - else { - // loop over the cells in this row, because there are fewer cells in this row than tracked columns - for (final Cell cell : row) { - final int column = cell.getColumnIndex(); - - // FIXME: if cell belongs to a merged region, some of the merged region may have fallen outside of the random access window - // In this case, getting the column width may result in an error. Need to gracefully handle this. - - // FIXME: Most cells are not merged, so calling getCellWidth twice re-computes the same value twice. - // Need to rewrite this to avoid unnecessary computation if this proves to be a performance bottleneck. - - if (maxColumnWidths.containsKey(column)) { - final ColumnWidthPair pair = maxColumnWidths.get(column); - updateColumnWidth(cell, pair); - } - } - } - } - - /** - * Helper for {@link #updateColumnWidths(Row)}. - * Implicitly track the columns corresponding to the cells in row. - * If all columns in the row are already tracked, this call does nothing. - * Explicitly untracked columns will not be tracked. - * - * @param row the row containing cells to implicitly track the columns - * @since 3.14beta1 - */ - private void implicitlyTrackColumnsInRow(Row row) { - // track new columns - if (trackAllColumns) { - // if column is not tracked, implicitly track the column if trackAllColumns is True and column has not been explicitly untracked - for (final Cell cell : row) { - final int column = cell.getColumnIndex(); - implicitlyTrackColumn(column); - } - } - } - - /** - * Helper for {@link #updateColumnWidths(Row)}. - * - * @param cell the cell to compute the best fit width on - * @param pair the column width pair to update - * @since 3.14beta1 - */ - private void updateColumnWidth(final Cell cell, final ColumnWidthPair pair) { - final double unmergedWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, false); - final double mergedWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, true); - pair.setMaxColumnWidths(unmergedWidth, mergedWidth); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java deleted file mode 100644 index 45ce38153..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.model.SharedStringsTable; - -/** - * Sheet writer that supports gzip compression of the temp files. - */ -public class GZIPSheetDataWriter extends SheetDataWriter { - - public GZIPSheetDataWriter() throws IOException { - super(); - } - - /** - * @param sharedStringsTable the shared strings table, or null if inline text is used - */ - public GZIPSheetDataWriter(SharedStringsTable sharedStringsTable) throws IOException { - super(sharedStringsTable); - } - - /** - * @return temp file to write sheet data - */ - @Override - public File createTempFile() throws IOException { - return TempFile.createTempFile("poi-sxssf-sheet-xml", ".gz"); - } - - @Override - protected InputStream decorateInputStream(FileInputStream fis) throws IOException { - return new GZIPInputStream(fis); - } - - @Override - protected OutputStream decorateOutputStream(FileOutputStream fos) throws IOException { - return new GZIPOutputStream(fos); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java deleted file mode 100644 index 3a1d85cb0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ /dev/null @@ -1,1306 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Map; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaParseException; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Removal; -import org.apache.poi.xssf.usermodel.XSSFHyperlink; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; - -/** - * Streaming version of XSSFRow implementing the "BigGridDemo" strategy. -*/ -public class SXSSFCell implements Cell { - private static final POILogger logger = POILogFactory.getLogger(SXSSFCell.class); - - private final SXSSFRow _row; - private Value _value; - private CellStyle _style; - private Property _firstProperty; - - /** - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Removal(version="3.17") - @Deprecated - public SXSSFCell(SXSSFRow row, int cellType) - { - this(row, CellType.forInt((cellType))); - } - - public SXSSFCell(SXSSFRow row,CellType cellType) - { - _row=row; - setType(cellType); - } - -//start of interface implementation - - /** - * Returns column index of this cell - * - * @return zero-based column index of a column in a sheet. - */ - @Override - public int getColumnIndex() - { - return _row.getCellIndex(this); - } - - /** - * Returns row index of a row in the sheet that contains this cell - * - * @return zero-based row index of a row in the sheet that contains this cell - */ - @Override - public int getRowIndex() - { - return _row.getRowNum(); - } - - /** - * {@inheritDoc} - */ - @Override - public CellAddress getAddress() { - return new CellAddress(this); - } - - /** - * Returns the sheet this cell belongs to - * - * @return the sheet this cell belongs to - */ - @Override - public SXSSFSheet getSheet() - { - return _row.getSheet(); - } - - /** - * Returns the Row this cell belongs to - * - * @return the Row that owns this cell - */ - @Override - public Row getRow() - { - return _row; - } - - /** - * Set the cells type (numeric, formula or string) - * - * @throws IllegalArgumentException if the specified cell type is invalid - * @see CellType#NUMERIC - * @see CellType#STRING - * @see CellType#FORMULA - * @see CellType#BLANK - * @see CellType#BOOLEAN - * @see CellType#ERROR - * @deprecated POI 3.15 beta 3. Use {@link #setCellType(CellType)} instead. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public void setCellType(int cellType) - { - ensureType(CellType.forInt(cellType)); - } - /** - * Set the cells type (numeric, formula or string) - * - * @throws IllegalArgumentException if the specified cell type is invalid - */ - @Override - public void setCellType(CellType cellType) - { - ensureType(cellType); - } - - /** - * Return the cell type. - * - * @return the cell type - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCellType() - { - return getCellTypeEnum().getCode(); - } - - /** - * Return the cell type. - * - * @return the cell type - * @since POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCellTypeEnum() - { - return _value.getType(); - } - - /** - * Only valid for formula cells - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCachedFormulaResultType() - { - return getCachedFormulaResultTypeEnum().getCode(); - } - - /** - * Only valid for formula cells - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @since POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCachedFormulaResultTypeEnum() - { - if (_value.getType() != CellType.FORMULA) { - throw new IllegalStateException("Only formula cells have cached results"); - } - - return ((FormulaValue)_value).getFormulaType(); - } - - /** - * Set a numeric value for the cell - * - * @param value the numeric value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numeric cell and set its value. - */ - @Override - public void setCellValue(double value) - { - if(Double.isInfinite(value)) { - // Excel does not support positive/negative infinities, - // rather, it gives a #DIV/0! error in these cases. - setCellErrorValue(FormulaError.DIV0.getCode()); - } else if (Double.isNaN(value)){ - setCellErrorValue(FormulaError.NUM.getCode()); - } else { - ensureTypeOrFormulaType(CellType.NUMERIC); - if(_value.getType()==CellType.FORMULA) - ((NumericFormulaValue)_value).setPreEvaluatedValue(value); - else - ((NumericValue)_value).setValue(value); - } - } - - /** - * Converts the supplied date to its equivalent Excel numeric value and sets - * that into the cell. - *

        - * Note - There is actually no 'DATE' cell type in Excel. In many - * cases (when entering date values), Excel automatically adjusts the - * cell style to some date format, creating the illusion that the cell - * data type is now something besides {@link CellType#NUMERIC}. POI - * does not attempt to replicate this behaviour. To make a numeric cell - * display as a date, use {@link #setCellStyle(CellStyle)} etc. - * - * @param value the numeric value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numerics cell and set its value. - */ - @Override - public void setCellValue(Date value) { - if(value == null) { - setCellType(CellType.BLANK); - return; - } - - boolean date1904 = getSheet().getWorkbook().isDate1904(); - setCellValue(DateUtil.getExcelDate(value, date1904)); - } - - /** - * Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as - * a date. - *

        - * This will set the cell value based on the Calendar's timezone. As Excel - * does not support timezones this means that both 20:00+03:00 and - * 20:00-03:00 will be reported as the same value (20:00) even that there - * are 6 hours difference between the two times. This difference can be - * preserved by using setCellValue(value.getTime()) which will - * automatically shift the times to the default timezone. - *

        - * - * @param value the date value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For othertypes we - * will change the cell to a numeric cell and set its value. - */ - @Override - public void setCellValue(Calendar value) { - if(value == null) { - setCellType(CellType.BLANK); - return; - } - - boolean date1904 = getSheet().getWorkbook().isDate1904(); - setCellValue( DateUtil.getExcelDate(value, date1904 )); - } - - /** - * Set a rich string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - @Override - public void setCellValue(RichTextString value) - { - XSSFRichTextString xvalue = (XSSFRichTextString)value; - - if (xvalue != null && xvalue.getString() != null) { - ensureRichTextStringType(); - - if (xvalue.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()) { - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - if (xvalue.hasFormatting()) - logger.log(POILogger.WARN, "SXSSF doesn't support Shared Strings, rich text formatting information has be lost"); - - ((RichTextValue)_value).setValue(xvalue); - } else { - setCellType(CellType.BLANK); - } - } - - /** - * Set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - @Override - public void setCellValue(String value) - { - if (value != null) { - ensureTypeOrFormulaType(CellType.STRING); - - if (value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()) { - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - - if(_value.getType()==CellType.FORMULA) - if(_value instanceof NumericFormulaValue) { - ((NumericFormulaValue) _value).setPreEvaluatedValue(Double.parseDouble(value)); - } else { - ((StringFormulaValue) _value).setPreEvaluatedValue(value); - } - else - ((PlainStringValue)_value).setValue(value); - } else { - setCellType(CellType.BLANK); - } - } - - /** - * Sets formula for this cell. - *

        - * Note, this method only sets the formula string and does not calculate the formula value. - * To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)} - *

        - * - * @param formula the formula to set, e.g. "SUM(C4:E4)". - * If the argument is null then the current formula is removed. - * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid - */ - @Override - public void setCellFormula(String formula) throws FormulaParseException - { - if(formula == null) { - setType(CellType.BLANK); - return; - } - - ensureFormulaType(computeTypeFromFormula(formula)); - ((FormulaValue)_value).setValue(formula); - } - /** - * Return a formula for the cell, for example, SUM(C4:E4) - * - * @return a formula for the cell - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is not CellType.FORMULA - */ - @Override - public String getCellFormula() - { - if(_value.getType()!=CellType.FORMULA) - throw typeMismatch(CellType.FORMULA,_value.getType(),false); - return ((FormulaValue)_value).getValue(); - } - - /** - * Get the value of the cell as a number. - *

        - * For strings we throw an exception. For blank cells we return a 0. - * For formulas or error cells we return the precalculated value; - *

        - * @return the value of the cell as a number - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is CellType.STRING - * @exception NumberFormatException if the cell value isn't a parsable double. - * @see org.apache.poi.ss.usermodel.DataFormatter for turning this number into a string similar to that which Excel would render this number as. - */ - @Override - public double getNumericCellValue() - { - CellType cellType = getCellTypeEnum(); - switch(cellType) - { - case BLANK: - return 0.0; - case FORMULA: - { - FormulaValue fv=(FormulaValue)_value; - if(fv.getFormulaType()!=CellType.NUMERIC) - throw typeMismatch(CellType.NUMERIC, CellType.FORMULA, false); - return ((NumericFormulaValue)_value).getPreEvaluatedValue(); - } - case NUMERIC: - return ((NumericValue)_value).getValue(); - default: - throw typeMismatch(CellType.NUMERIC, cellType, false); - } - } - - /** - * Get the value of the cell as a date. - *

        - * For strings we throw an exception. For blank cells we return a null. - *

        - * @return the value of the cell as a date - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is CellType.STRING - * @exception NumberFormatException if the cell value isn't a parsable double. - * @see org.apache.poi.ss.usermodel.DataFormatter for formatting this date into a string similar to how excel does. - */ - @Override - public Date getDateCellValue() - { - CellType cellType = getCellTypeEnum(); - if (cellType == CellType.BLANK) - { - return null; - } - - double value = getNumericCellValue(); - boolean date1904 = getSheet().getWorkbook().isDate1904(); - return DateUtil.getJavaDate(value, date1904); - } - - /** - * Get the value of the cell as a XSSFRichTextString - *

        - * For numeric cells we throw an exception. For blank cells we return an empty string. - * For formula cells we return the pre-calculated value if a string, otherwise an exception. - *

        - * @return the value of the cell as a XSSFRichTextString - */ - @Override - public RichTextString getRichStringCellValue() - { - CellType cellType = getCellTypeEnum(); - if(getCellTypeEnum() != CellType.STRING) - throw typeMismatch(CellType.STRING, cellType, false); - - StringValue sval = (StringValue)_value; - if(sval.isRichText()) - return ((RichTextValue)_value).getValue(); - else { - String plainText = getStringCellValue(); - return getSheet().getWorkbook().getCreationHelper().createRichTextString(plainText); - } - } - - - /** - * Get the value of the cell as a string - *

        - * For numeric cells we throw an exception. For blank cells we return an empty string. - * For formulaCells that are not string Formulas, we throw an exception. - *

        - * @return the value of the cell as a string - */ - @Override - public String getStringCellValue() - { - CellType cellType = getCellTypeEnum(); - switch(cellType) - { - case BLANK: - return ""; - case FORMULA: - { - FormulaValue fv=(FormulaValue)_value; - if(fv.getFormulaType()!=CellType.STRING) - throw typeMismatch(CellType.STRING, CellType.FORMULA, false); - return ((StringFormulaValue)_value).getPreEvaluatedValue(); - } - case STRING: - { - if(((StringValue)_value).isRichText()) - return ((RichTextValue)_value).getValue().getString(); - else - return ((PlainStringValue)_value).getValue(); - } - default: - throw typeMismatch(CellType.STRING, cellType, false); - } - } - - /** - * Set a boolean value for the cell - * - * @param value the boolean value to set this cell to. For formulas we'll set the - * precalculated value, for booleans we'll set its value. For other types we - * will change the cell to a boolean cell and set its value. - */ - @Override - public void setCellValue(boolean value) - { - ensureTypeOrFormulaType(CellType.BOOLEAN); - if(_value.getType()==CellType.FORMULA) - ((BooleanFormulaValue)_value).setPreEvaluatedValue(value); - else - ((BooleanValue)_value).setValue(value); - } - - /** - * Set a error value for the cell - * - * @param value the error value to set this cell to. For formulas we'll set the - * precalculated value , for errors we'll set - * its value. For other types we will change the cell to an error - * cell and set its value. - * @see org.apache.poi.ss.usermodel.FormulaError - */ - @Override - public void setCellErrorValue(byte value) - { - ensureType(CellType.ERROR); - if(_value.getType()==CellType.FORMULA) - ((ErrorFormulaValue)_value).setPreEvaluatedValue(value); - else - ((ErrorValue)_value).setValue(value); - } - - /** - * Get the value of the cell as a boolean. - *

        - * For strings, numbers, and errors, we throw an exception. For blank cells we return a false. - *

        - * @return the value of the cell as a boolean - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} - * is not CellType.BOOLEAN, CellType.BLANK or CellType.FORMULA - */ - @Override - public boolean getBooleanCellValue() - { - CellType cellType = getCellTypeEnum(); - switch(cellType) - { - case BLANK: - return false; - case FORMULA: - { - FormulaValue fv=(FormulaValue)_value; - if(fv.getFormulaType()!=CellType.BOOLEAN) - throw typeMismatch(CellType.BOOLEAN, CellType.FORMULA, false); - return ((BooleanFormulaValue)_value).getPreEvaluatedValue(); - } - case BOOLEAN: - { - return ((BooleanValue)_value).getValue(); - } - default: - throw typeMismatch(CellType.BOOLEAN, cellType, false); - } - } - - /** - * Get the value of the cell as an error code. - *

        - * For strings, numbers, and booleans, we throw an exception. - * For blank cells we return a 0. - *

        - * - * @return the value of the cell as an error code - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} isn't CellType.ERROR - * @see org.apache.poi.ss.usermodel.FormulaError for error codes - */ - @Override - public byte getErrorCellValue() - { - CellType cellType = getCellTypeEnum(); - switch(cellType) - { - case BLANK: - return 0; - case FORMULA: - { - FormulaValue fv=(FormulaValue)_value; - if(fv.getFormulaType()!=CellType.ERROR) - throw typeMismatch(CellType.ERROR, CellType.FORMULA, false); - return ((ErrorFormulaValue)_value).getPreEvaluatedValue(); - } - case ERROR: - { - return ((ErrorValue)_value).getValue(); - } - default: - throw typeMismatch(CellType.ERROR, cellType, false); - } - } - - /** - *

        Set the style for the cell. The style should be an CellStyle created/retreived from - * the Workbook.

        - * - *

        To change the style of a cell without affecting other cells that use the same style, - * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map)}

        - * - * @param style reference contained in the workbook. - * If the value is null then the style information is removed causing the cell to used the default workbook style. - * @see org.apache.poi.ss.usermodel.Workbook#createCellStyle - */ - @Override - public void setCellStyle(CellStyle style) - { - _style=style; - } - - /** - * Return the cell's style. - * - * @return the cell's style. Always not-null. Default cell style has zero index and can be obtained as - * workbook.getCellStyleAt(0) - * @see org.apache.poi.ss.usermodel.Workbook#getCellStyleAt(int) - */ - @Override - public CellStyle getCellStyle() - { - if(_style == null){ - SXSSFWorkbook wb = (SXSSFWorkbook)getRow().getSheet().getWorkbook(); - return wb.getCellStyleAt((short)0); - } else { - return _style; - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setAsActiveCell() - { - getSheet().setActiveCell(getAddress()); - } - - /** - * Assign a comment to this cell - * - * @param comment comment associated with this cell - */ - @Override - public void setCellComment(Comment comment) - { - setProperty(Property.COMMENT,comment); - } - - /** - * Returns comment associated with this cell - * - * @return comment associated with this cell or null if not found - */ - @Override - public Comment getCellComment() - { - return (Comment)getPropertyValue(Property.COMMENT); - } - - /** - * Removes the comment for this cell, if there is one. - */ - @Override - public void removeCellComment() - { - removeProperty(Property.COMMENT); - } - - /** - * @return hyperlink associated with this cell or null if not found - */ - @Override - public Hyperlink getHyperlink() - { - return (Hyperlink)getPropertyValue(Property.HYPERLINK); - } - - /** - * Assign a hyperlink to this cell. If the supplied hyperlink is null, the - * hyperlink for this cell will be removed. - * - * @param link hyperlink associated with this cell - */ - @Override - public void setHyperlink(Hyperlink link) - { - if (link == null) { - removeHyperlink(); - return; - } - - setProperty(Property.HYPERLINK,link); - - XSSFHyperlink xssfobj = (XSSFHyperlink)link; - // Assign to us - CellReference ref = new CellReference(getRowIndex(), getColumnIndex()); - xssfobj.getCTHyperlink().setRef( ref.formatAsString() ); - - // Add to the lists - getSheet()._sh.addHyperlink(xssfobj); - } - - /** - * Removes the hyperlink for this cell, if there is one. - */ - @Override - public void removeHyperlink() - { - removeProperty(Property.HYPERLINK); - - getSheet()._sh.removeHyperlink(getRowIndex(), getColumnIndex()); - } - - /** - * Only valid for array formula cells - * - * @return range of the array formula group that the cell belongs to. - */ -// TODO: What is this? - @NotImplemented - public CellRangeAddress getArrayFormulaRange() - { - return null; - } - - /** - * @return true if this cell is part of group of cells having a common array formula. - */ -//TODO: What is this? - @NotImplemented - public boolean isPartOfArrayFormulaGroup() - { - return false; - } -//end of interface implementation - - /** - * Returns a string representation of the cell - *

        - * Formula cells return the formula string, rather than the formula result. - * Dates are displayed in dd-MMM-yyyy format - * Errors are displayed as #ERR<errIdx> - *

        - */ - @Override - public String toString() { - switch (getCellTypeEnum()) { - case BLANK: - return ""; - case BOOLEAN: - return getBooleanCellValue() ? "TRUE" : "FALSE"; - case ERROR: - return ErrorEval.getText(getErrorCellValue()); - case FORMULA: - return getCellFormula(); - case NUMERIC: - if (DateUtil.isCellDateFormatted(this)) { - DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale()); - sdf.setTimeZone(LocaleUtil.getUserTimeZone()); - return sdf.format(getDateCellValue()); - } - return getNumericCellValue() + ""; - case STRING: - return getRichStringCellValue().toString(); - default: - return "Unknown Cell Type: " + getCellTypeEnum(); - } - } - - /*package*/ void removeProperty(int type) - { - Property current=_firstProperty; - Property previous=null; - while(current!=null&¤t.getType()!=type) - { - previous=current; - current=current._next; - } - if(current!=null) - { - if(previous!=null) - { - previous._next=current._next; - } - else - { - _firstProperty=current._next; - } - } - } - /*package*/ void setProperty(int type,Object value) - { - Property current=_firstProperty; - Property previous=null; - while(current!=null&¤t.getType()!=type) - { - previous=current; - current=current._next; - } - if(current!=null) - { - current.setValue(value); - } - else - { - switch(type) - { - case Property.COMMENT: - { - current=new CommentProperty(value); - break; - } - case Property.HYPERLINK: - { - current=new HyperlinkProperty(value); - break; - } - default: - { - throw new IllegalArgumentException("Invalid type: " + type); - } - } - if(previous!=null) - { - previous._next=current; - } - else - { - _firstProperty=current; - } - } - } - /*package*/ Object getPropertyValue(int type) - { - return getPropertyValue(type,null); - } - /*package*/ Object getPropertyValue(int type,String defaultValue) - { - Property current=_firstProperty; - while(current!=null&¤t.getType()!=type) current=current._next; - return current==null?defaultValue:current.getValue(); - } - /*package*/ void ensurePlainStringType() - { - if(_value.getType()!=CellType.STRING - ||((StringValue)_value).isRichText()) - _value=new PlainStringValue(); - } - /*package*/ void ensureRichTextStringType() - { - if(_value.getType()!=CellType.STRING - ||!((StringValue)_value).isRichText()) - _value=new RichTextValue(); - } - /*package*/ void ensureType(CellType type) - { - if(_value.getType()!=type) - setType(type); - } - /*package*/ void ensureFormulaType(CellType type) - { - if(_value.getType()!=CellType.FORMULA - ||((FormulaValue)_value).getFormulaType()!=type) - setFormulaType(type); - } - /* - * Sets the cell type to type if it is different - */ - /*package*/ void ensureTypeOrFormulaType(CellType type) - { - if(_value.getType()==type) - { - if(type==CellType.STRING&&((StringValue)_value).isRichText()) - setType(CellType.STRING); - return; - } - if(_value.getType()==CellType.FORMULA) - { - if(((FormulaValue)_value).getFormulaType()==type) - return; - setFormulaType(type); // once a formula, always a formula - return; - } - setType(type); - } - /** - * changes the cell type to the specified type, and resets the value to the default value for that type - * If cell type is the same as specified type, this will reset the value to the default value for that type - * - * @param type the cell type to set - * @throws IllegalArgumentException if type is not a recognized type - */ - /*package*/ void setType(CellType type) - { - switch(type) - { - case NUMERIC: - { - _value=new NumericValue(); - break; - } - case STRING: - { - PlainStringValue sval = new PlainStringValue(); - if(_value != null){ - // if a cell is not blank then convert the old value to string - String str = convertCellValueToString(); - sval.setValue(str); - } - _value = sval; - break; - } - case FORMULA: - { - _value=new NumericFormulaValue(); - break; - } - case BLANK: - { - _value=new BlankValue(); - break; - } - case BOOLEAN: - { - BooleanValue bval = new BooleanValue(); - if(_value != null){ - // if a cell is not blank then convert the old value to string - boolean val = convertCellValueToBoolean(); - bval.setValue(val); - } - _value = bval; - break; - } - case ERROR: - { - _value=new ErrorValue(); - break; - } - default: - { - throw new IllegalArgumentException("Illegal type " + type); - } - } - } - /*package*/ void setFormulaType(CellType type) - { - Value prevValue = _value; - switch(type) - { - case NUMERIC: - { - _value=new NumericFormulaValue(); - break; - } - case STRING: - { - _value=new StringFormulaValue(); - break; - } - case BOOLEAN: - { - _value=new BooleanFormulaValue(); - break; - } - case ERROR: - { - _value=new ErrorFormulaValue(); - break; - } - default: - { - throw new IllegalArgumentException("Illegal type " + type); - } - } - - // if we had a Formula before, we should copy over the _value of the formula - if(prevValue instanceof FormulaValue) { - ((FormulaValue)_value)._value = ((FormulaValue)prevValue)._value; - } - } - -//TODO: implement this correctly - @NotImplemented - /*package*/ CellType computeTypeFromFormula(String formula) - { - return CellType.NUMERIC; - } -//COPIED FROM https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java since the functions are declared private there - /** - * Used to help format error messages - */ - private static RuntimeException typeMismatch(CellType expectedTypeCode, CellType actualTypeCode, boolean isFormulaCell) { - String msg = "Cannot get a " + expectedTypeCode + " value from a " + actualTypeCode - + " " + (isFormulaCell ? "formula " : "") + "cell"; - return new IllegalStateException(msg); - } - - private boolean convertCellValueToBoolean() { - CellType cellType = getCellTypeEnum(); - - if (cellType == CellType.FORMULA) { - cellType = getCachedFormulaResultTypeEnum(); - } - - switch (cellType) { - case BOOLEAN: - return getBooleanCellValue(); - case STRING: - - String text = getStringCellValue(); - return Boolean.parseBoolean(text); - case NUMERIC: - return getNumericCellValue() != 0; - case ERROR: - case BLANK: - return false; - default: throw new RuntimeException("Unexpected cell type (" + cellType + ")"); - } - - } - private String convertCellValueToString() { - CellType cellType = getCellTypeEnum(); - return convertCellValueToString(cellType); - } - private String convertCellValueToString(CellType cellType) { - switch (cellType) { - case BLANK: - return ""; - case BOOLEAN: - return getBooleanCellValue() ? "TRUE" : "FALSE"; - case STRING: - return getStringCellValue(); - case NUMERIC: - return Double.toString( getNumericCellValue() ); - case ERROR: - byte errVal = getErrorCellValue(); - return FormulaError.forInt(errVal).getString(); - case FORMULA: - if (_value != null) { - FormulaValue fv = (FormulaValue)_value; - if (fv.getFormulaType() != CellType.FORMULA) { - return convertCellValueToString(fv.getFormulaType()); - } - } - return ""; - default: - throw new IllegalStateException("Unexpected cell type (" + cellType + ")"); - } - } - -//END OF COPIED CODE - - static abstract class Property - { - final static int COMMENT=1; - final static int HYPERLINK=2; - Object _value; - Property _next; - public Property(Object value) - { - _value=value; - } - abstract int getType(); - void setValue(Object value) - { - _value=value; - } - Object getValue() - { - return _value; - } - } - static class CommentProperty extends Property - { - public CommentProperty(Object value) - { - super(value); - } - @Override - public int getType() - { - return COMMENT; - } - } - static class HyperlinkProperty extends Property - { - public HyperlinkProperty(Object value) - { - super(value); - } - @Override - public int getType() - { - return HYPERLINK; - } - } - interface Value - { - CellType getType(); - } - static class NumericValue implements Value - { - double _value; - public CellType getType() - { - return CellType.NUMERIC; - } - void setValue(double value) - { - _value=value; - } - double getValue() - { - return _value; - } - } - static abstract class StringValue implements Value - { - public CellType getType() - { - return CellType.STRING; - } -//We cannot introduce a new type CellType.RICH_TEXT because the types are public so we have to make rich text as a type of string - abstract boolean isRichText(); // using the POI style which seems to avoid "instanceof". - } - static class PlainStringValue extends StringValue - { - String _value; - void setValue(String value) - { - _value=value; - } - String getValue() - { - return _value; - } - @Override - boolean isRichText() - { - return false; - } - } - static class RichTextValue extends StringValue - { - RichTextString _value; - @Override - public CellType getType() - { - return CellType.STRING; - } - void setValue(RichTextString value) - { - _value=value; - } - RichTextString getValue() - { - return _value; - } - @Override - boolean isRichText() - { - return true; - } - } - static abstract class FormulaValue implements Value - { - String _value; - public CellType getType() - { - return CellType.FORMULA; - } - void setValue(String value) - { - _value=value; - } - String getValue() - { - return _value; - } - abstract CellType getFormulaType(); - } - static class NumericFormulaValue extends FormulaValue - { - double _preEvaluatedValue; - @Override - CellType getFormulaType() - { - return CellType.NUMERIC; - } - void setPreEvaluatedValue(double value) - { - _preEvaluatedValue=value; - } - double getPreEvaluatedValue() - { - return _preEvaluatedValue; - } - } - static class StringFormulaValue extends FormulaValue - { - String _preEvaluatedValue; - @Override - CellType getFormulaType() - { - return CellType.STRING; - } - void setPreEvaluatedValue(String value) - { - _preEvaluatedValue=value; - } - String getPreEvaluatedValue() - { - return _preEvaluatedValue; - } - } - static class BooleanFormulaValue extends FormulaValue - { - boolean _preEvaluatedValue; - @Override - CellType getFormulaType() - { - return CellType.BOOLEAN; - } - void setPreEvaluatedValue(boolean value) - { - _preEvaluatedValue=value; - } - boolean getPreEvaluatedValue() - { - return _preEvaluatedValue; - } - } - static class ErrorFormulaValue extends FormulaValue - { - byte _preEvaluatedValue; - @Override - CellType getFormulaType() - { - return CellType.ERROR; - } - void setPreEvaluatedValue(byte value) - { - _preEvaluatedValue=value; - } - byte getPreEvaluatedValue() - { - return _preEvaluatedValue; - } - } - static class BlankValue implements Value - { - public CellType getType() - { - return CellType.BLANK; - } - } - static class BooleanValue implements Value - { - boolean _value; - public CellType getType() - { - return CellType.BOOLEAN; - } - void setValue(boolean value) - { - _value=value; - } - boolean getValue() - { - return _value; - } - } - static class ErrorValue implements Value - { - byte _value; - public CellType getType() - { - return CellType.ERROR; - } - void setValue(byte value) - { - _value=value; - } - byte getValue() - { - return _value; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java deleted file mode 100644 index f2687ff1d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.DataFormat; -import org.apache.poi.ss.usermodel.ExtendedColor; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Removal; -import org.apache.poi.xssf.usermodel.XSSFCreationHelper; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; - -/** - * Streaming Creation Helper, which performs some actions - * based on the Streaming Workbook, and some on the related - * regular XSSF Workbook - */ -public class SXSSFCreationHelper implements CreationHelper { - private static final POILogger logger = POILogFactory.getLogger(SXSSFCreationHelper.class); - - private final SXSSFWorkbook wb; - private final XSSFCreationHelper helper; - - /** - * Should only be called by {@link SXSSFWorkbook#getCreationHelper()} - * - * @param workbook the workbook to create objects for - */ - @Internal - public SXSSFCreationHelper(SXSSFWorkbook workbook) { - this.helper = new XSSFCreationHelper(workbook.getXSSFWorkbook()); - this.wb = workbook; - } - - @Override - public XSSFRichTextString createRichTextString(String text) { - logger.log(POILogger.INFO, "SXSSF doesn't support Rich Text Strings, any formatting information will be lost"); - return new XSSFRichTextString(text); - } - - @Override - public SXSSFFormulaEvaluator createFormulaEvaluator() { - return new SXSSFFormulaEvaluator(wb); - } - - // Pass-through methods - @Override - public DataFormat createDataFormat() { - return helper.createDataFormat(); - } - /** - * {@inheritDoc} - * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. - */ - @Deprecated - @Removal(version="3.17") - @Override - public Hyperlink createHyperlink(int type) { - return helper.createHyperlink(type); - } - @Override - public Hyperlink createHyperlink(HyperlinkType type) { - return helper.createHyperlink(type); - } - @Override - public ExtendedColor createExtendedColor() { - return helper.createExtendedColor(); - } - @Override - public ClientAnchor createClientAnchor() { - return helper.createClientAnchor(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java deleted file mode 100644 index 2bb226cac..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.xssf.usermodel.XSSFDrawing; -import org.apache.poi.xssf.usermodel.XSSFPicture; - -/** - * Streaming version of Drawing. - * Delegates most tasks to the non-streaming XSSF code. - * TODO: Potentially, Comment and Chart need a similar streaming wrapper like Picture. - */ -public class SXSSFDrawing implements Drawing { - private final SXSSFWorkbook _wb; - private final XSSFDrawing _drawing; - - public SXSSFDrawing(SXSSFWorkbook workbook, XSSFDrawing drawing) { - this._wb = workbook; - this._drawing = drawing; - } - - @Override - public SXSSFPicture createPicture(ClientAnchor anchor, int pictureIndex) { - XSSFPicture pict = _drawing.createPicture(anchor, pictureIndex); - return new SXSSFPicture(_wb, pict); - } - - @Override - public Comment createCellComment(ClientAnchor anchor) { - return _drawing.createCellComment(anchor); - } - - @Override - public Chart createChart(ClientAnchor anchor) { - return _drawing.createChart(anchor); - } - - @Override - public ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) { - return _drawing.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2); - } -} - diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationCell.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationCell.java deleted file mode 100644 index 8c11e8b8b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationCell.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.util.Internal; - -/** - * SXSSF wrapper for a cell under evaluation - */ -final class SXSSFEvaluationCell implements EvaluationCell { - private final EvaluationSheet _evalSheet; - private final SXSSFCell _cell; - - public SXSSFEvaluationCell(SXSSFCell cell, SXSSFEvaluationSheet evaluationSheet) { - _cell = cell; - _evalSheet = evaluationSheet; - } - - public SXSSFEvaluationCell(SXSSFCell cell) { - this(cell, new SXSSFEvaluationSheet(cell.getSheet())); - } - - @Override - public Object getIdentityKey() { - // save memory by just using the cell itself as the identity key - // Note - this assumes SXSSFCell has not overridden hashCode and equals - return _cell; - } - - public SXSSFCell getSXSSFCell() { - return _cell; - } - @Override - public boolean getBooleanCellValue() { - return _cell.getBooleanCellValue(); - } - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type - */ - @Override - public int getCellType() { - return _cell.getCellType(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Internal(since="POI 3.15 beta 3") - @Override - public CellType getCellTypeEnum() { - return _cell.getCellTypeEnum(); - } - @Override - public int getColumnIndex() { - return _cell.getColumnIndex(); - } - @Override - public int getErrorCellValue() { - return _cell.getErrorCellValue(); - } - @Override - public double getNumericCellValue() { - return _cell.getNumericCellValue(); - } - @Override - public int getRowIndex() { - return _cell.getRowIndex(); - } - @Override - public EvaluationSheet getSheet() { - return _evalSheet; - } - @Override - public String getStringCellValue() { - return _cell.getRichStringCellValue().getString(); - } - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type of cached formula result - */ - @Override - public int getCachedFormulaResultType() { - return _cell.getCachedFormulaResultType(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Internal(since="POI 3.15 beta 3") - @Override - public CellType getCachedFormulaResultTypeEnum() { - return _cell.getCachedFormulaResultTypeEnum(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationSheet.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationSheet.java deleted file mode 100644 index 57d7cc57b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationSheet.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.util.Internal; - -/** - * SXSSF wrapper for a sheet under evaluation - */ -@Internal -final class SXSSFEvaluationSheet implements EvaluationSheet { - private final SXSSFSheet _xs; - - public SXSSFEvaluationSheet(SXSSFSheet sheet) { - _xs = sheet; - } - - public SXSSFSheet getSXSSFSheet() { - return _xs; - } - @Override - public EvaluationCell getCell(int rowIndex, int columnIndex) { - SXSSFRow row = _xs.getRow(rowIndex); - if (row == null) { - if (rowIndex <= _xs.getLastFlushedRowNum()) { - throw new SXSSFFormulaEvaluator.RowFlushedException(rowIndex); - } - return null; - } - SXSSFCell cell = row.getCell(columnIndex); - if (cell == null) { - return null; - } - return new SXSSFEvaluationCell(cell, this); - } - - /* (non-JavaDoc), inherit JavaDoc from EvaluationSheet - * @since POI 3.15 beta 3 - */ - @Override - public void clearAllCachedResultValues() { - // nothing to do - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationWorkbook.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationWorkbook.java deleted file mode 100644 index e9040c912..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationWorkbook.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.xssf.usermodel.BaseXSSFEvaluationWorkbook; -import org.apache.poi.util.Internal; - -/** - * SXSSF wrapper around the SXSSF and XSSF workbooks - */ -@Internal -public final class SXSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook { - private final SXSSFWorkbook _uBook; - - public static SXSSFEvaluationWorkbook create(SXSSFWorkbook book) { - if (book == null) { - return null; - } - return new SXSSFEvaluationWorkbook(book); - } - - private SXSSFEvaluationWorkbook(SXSSFWorkbook book) { - super(book.getXSSFWorkbook()); - _uBook = book; - } - - @Override - public int getSheetIndex(EvaluationSheet evalSheet) { - SXSSFSheet sheet = ((SXSSFEvaluationSheet)evalSheet).getSXSSFSheet(); - return _uBook.getSheetIndex(sheet); - } - - @Override - public EvaluationSheet getSheet(int sheetIndex) { - return new SXSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex)); - } - - @Override - public Ptg[] getFormulaTokens(EvaluationCell evalCell) { - SXSSFCell cell = ((SXSSFEvaluationCell)evalCell).getSXSSFCell(); - return FormulaParser.parse(cell.getCellFormula(), this, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet())); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java deleted file mode 100644 index 0ac776ffc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java +++ /dev/null @@ -1,139 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.IStabilityClassifier; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.usermodel.BaseXSSFFormulaEvaluator; - -/** - * Streaming-specific Formula Evaluator, which is able to - * lookup cells within the current Window. - */ -public final class SXSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator { - private static POILogger logger = POILogFactory.getLogger(SXSSFFormulaEvaluator.class); - - private SXSSFWorkbook wb; - - public SXSSFFormulaEvaluator(SXSSFWorkbook workbook) { - this(workbook, null, null); - } - private SXSSFFormulaEvaluator(SXSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - this(workbook, new WorkbookEvaluator(SXSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder)); - } - private SXSSFFormulaEvaluator(SXSSFWorkbook workbook, WorkbookEvaluator bookEvaluator) { - super(bookEvaluator); - this.wb = workbook; - } - - /** - * @param stabilityClassifier used to optimise caching performance. Pass null - * for the (conservative) assumption that any cell may have its definition changed after - * evaluation begins. - * @param udfFinder pass null for default (AnalysisToolPak only) - */ - public static SXSSFFormulaEvaluator create(SXSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - return new SXSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder); - } - - /** - * Turns a SXSSFCell into a SXSSFEvaluationCell - */ - @Override - protected EvaluationCell toEvaluationCell(Cell cell) { - if (!(cell instanceof SXSSFCell)){ - throw new IllegalArgumentException("Unexpected type of cell: " + cell.getClass() + "." + - " Only SXSSFCells can be evaluated."); - } - - return new SXSSFEvaluationCell((SXSSFCell)cell); - } - - @Override - public SXSSFCell evaluateInCell(Cell cell) { - return (SXSSFCell) super.evaluateInCell(cell); - } - - /** - * For active worksheets only, will loop over rows and - * cells, evaluating formula cells there. - * If formula cells are outside the window for that sheet, - * it can either skip them silently, or give an exception - */ - public static void evaluateAllFormulaCells(SXSSFWorkbook wb, boolean skipOutOfWindow) { - SXSSFFormulaEvaluator eval = new SXSSFFormulaEvaluator(wb); - - // Check they're all available - for (Sheet sheet : wb) { - if (((SXSSFSheet)sheet).areAllRowsFlushed()) { - throw new SheetsFlushedException(); - } - } - - // Process the sheets as best we can - for (Sheet sheet : wb) { - - // Check if any rows have already been flushed out - int lastFlushedRowNum = ((SXSSFSheet) sheet).getLastFlushedRowNum(); - if (lastFlushedRowNum > -1) { - if (! skipOutOfWindow) throw new RowFlushedException(0); - logger.log(POILogger.INFO, "Rows up to " + lastFlushedRowNum + " have already been flushed, skipping"); - } - - // Evaluate what we have - for (Row r : sheet) { - for (Cell c : r) { - if (c.getCellTypeEnum() == CellType.FORMULA) { - eval.evaluateFormulaCellEnum(c); - } - } - } - } - } - - /** - * Loops over rows and cells, evaluating formula cells there. - * If any sheets are inactive, or any cells outside of the window, - * will give an Exception. - * For SXSSF, you generally don't want to use this method, instead - * evaluate your formulas as you go before they leave the window. - */ - public void evaluateAll() { - // Have the evaluation done, with exceptions - evaluateAllFormulaCells(wb, false); - } - - public static class SheetsFlushedException extends IllegalStateException { - protected SheetsFlushedException() { - super("One or more sheets have been flushed, cannot evaluate all cells"); - } - } - public static class RowFlushedException extends IllegalStateException { - protected RowFlushedException(int rowNum) { - super("Row " + rowNum + " has been flushed, cannot evaluate all cells"); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFPicture.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFPicture.java deleted file mode 100644 index 631d0e356..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFPicture.java +++ /dev/null @@ -1,272 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.ss.usermodel.Picture; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.ImageUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.usermodel.*; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; - -import java.awt.Dimension; -import java.io.IOException; - -/** - * Streaming version of Picture. - * Most of the code is a copy of the non-streaming XSSFPicture code. - * This is necessary as a private method getRowHeightInPixels of that class needs to be changed, which is called by a method call chain nested several levels. - * - * The main change is to access the rows in the SXSSF sheet, not the always empty rows in the XSSF sheet when checking the row heights. - */ -public final class SXSSFPicture implements Picture { - private static final POILogger logger = POILogFactory.getLogger(SXSSFPicture.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; - - private final SXSSFWorkbook _wb; - private final XSSFPicture _picture; - - SXSSFPicture(SXSSFWorkbook _wb, XSSFPicture _picture) { - this._wb = _wb; - this._picture = _picture; - } - - /** - * Return the underlying CTPicture bean that holds all properties for this picture - * - * @return the underlying CTPicture bean - */ - @Internal - public CTPicture getCTPicture(){ - return _picture.getCTPicture(); - } - - /** - * Reset the image to the original size. - * - *

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Calibri 11pt for .xlsx). - * If the default font is changed the resized image can be streched vertically or horizontally. - *

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

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Calibri 11pt for .xlsx). - * If the default font is changed the resized image can be streched vertically or horizontally. - *

        - * - * @param scale the amount by which image dimensions are multiplied relative to the original size. - * resize(1.0) sets the original size, resize(0.5) resize to 50% of the original, - * resize(2.0) resizes to 200% of the original. - */ - @Override - public void resize(double scale){ - XSSFClientAnchor anchor = getClientAnchor(); - - 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 - */ - @Override - public XSSFClientAnchor getPreferredSize(){ - return getPreferredSize(1.0); - } - - /** - * 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 = getClientAnchor(); - - 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; - - for (;;) { - w += getColumnWidthInPixels(col2); - if(w > scaledWidth) break; - col2++; - } - - if(w > scaledWidth) { - double cw = getColumnWidthInPixels(col2 ); - double delta = w - scaledWidth; - dx2 = (int)(XSSFShape.EMU_PER_PIXEL * (cw - delta)); - } - anchor.setCol2(col2); - anchor.setDx2(dx2); - - double h = 0; - int row2 = anchor.getRow1(); - int dy2 = 0; - - for (;;) { - h += getRowHeightInPixels(row2); - if(h > scaledHeight) break; - row2++; - } - - if(h > scaledHeight) { - double ch = getRowHeightInPixels(row2); - double delta = h - scaledHeight; - dy2 = (int)(XSSFShape.EMU_PER_PIXEL * (ch - delta)); - } - anchor.setRow2(row2); - anchor.setDy2(dy2); - - CTPositiveSize2D size2d = getCTPicture().getSpPr().getXfrm().getExt(); - size2d.setCx((long)(scaledWidth * XSSFShape.EMU_PER_PIXEL)); - size2d.setCy((long)(scaledHeight * XSSFShape.EMU_PER_PIXEL)); - - return anchor; - } - - private float getColumnWidthInPixels(int columnIndex){ - XSSFSheet sheet = 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) { - // THE FOLLOWING THREE LINES ARE THE MAIN CHANGE compared to the non-streaming version: use the SXSSF sheet, - // not the XSSF sheet (which never contais rows when using SXSSF) - XSSFSheet xssfSheet = getParent(); - SXSSFSheet sheet = _wb.getSXSSFSheet(xssfSheet); - Row row = sheet.getRow(rowIndex); - float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints(); - return height * XSSFShape.PIXEL_DPI / XSSFShape.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){ - try { - return ImageUtils.getImageDimension(part.getInputStream(), type); - } catch (IOException e){ - //return a "singulariry" if ImageIO failed to read the image - logger.log(POILogger.WARN, e); - return new Dimension(); - } - } - - /** - * Return picture data for this shape - * - * @return picture data for this shape - */ - @Override - public XSSFPictureData getPictureData() { - return _picture.getPictureData(); - } - - protected CTShapeProperties getShapeProperties(){ - return getCTPicture().getSpPr(); - } - - private XSSFSheet getParent() { - return (XSSFSheet)_picture.getDrawing().getParent(); - } - - private XSSFAnchor getAnchor() { - return _picture.getAnchor(); - } - - @Override - public void resize(double scaleX, double scaleY) { - _picture.resize(scaleX, scaleY); - } - - @Override - public XSSFClientAnchor getPreferredSize(double scaleX, double scaleY) { - return _picture.getPreferredSize(scaleX, scaleY); - } - - @Override - public Dimension getImageDimension() { - return _picture.getImageDimension(); - } - - @Override - public XSSFClientAnchor getClientAnchor() { - XSSFAnchor a = getAnchor(); - return (a instanceof XSSFClientAnchor) ? (XSSFClientAnchor)a : null; - } - - public XSSFDrawing getDrawing() { - return _picture.getDrawing(); - } - - @Override - public XSSFSheet getSheet() { - return _picture.getSheet(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java deleted file mode 100644 index 7aaacdd9b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java +++ /dev/null @@ -1,579 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.util.Internal; - -/** - * Streaming version of XSSFRow implementing the "BigGridDemo" strategy. - */ -public class SXSSFRow implements Row, Comparable -{ - private static final Boolean UNDEFINED = null; - - private final SXSSFSheet _sheet; // parent sheet - private final SortedMap _cells = new TreeMap(); - private short _style = -1; // index of cell style in style table - private short _height = -1; // row height in twips (1/20 point) - private boolean _zHeight = false; // row zero-height (this is somehow different than being hidden) - private int _outlineLevel = 0; // Outlining level of the row, when outlining is on - // use Boolean to have a tri-state for on/off/undefined - private Boolean _hidden = UNDEFINED; - private Boolean _collapsed = UNDEFINED; - - /** - * - * @param sheet the parent sheet the row belongs to - * @param initialSize - no longer needed - * @deprecated 2015-11-30 (circa POI 3.14beta1). Use {@link #SXSSFRow(SXSSFSheet)} instead. - */ - @Deprecated - public SXSSFRow(SXSSFSheet sheet, @SuppressWarnings("UnusedParameters") int initialSize) - { - this(sheet); - } - - public SXSSFRow(SXSSFSheet sheet) - { - _sheet=sheet; - } - - public Iterator allCellsIterator() - { - return new CellIterator(); - } - public boolean hasCustomHeight() - { - return _height!=-1; - } - - @Override - public int getOutlineLevel(){ - return _outlineLevel; - } - void setOutlineLevel(int level){ - _outlineLevel = level; - } - - /** - * get row hidden state: Hidden (true), Unhidden (false), Undefined (null) - * - * @return row hidden state - */ - public Boolean getHidden() { - return _hidden; - } - - /** - * set row hidden state: Hidden (true), Unhidden (false), Undefined (null) - * - * @param hidden row hidden state - */ - public void setHidden(Boolean hidden) { - this._hidden = hidden; - } - - public Boolean getCollapsed() { - return _collapsed; - } - - public void setCollapsed(Boolean collapsed) { - this._collapsed = collapsed; - } -//begin of interface implementation - /** - * {@inheritDoc} - */ - @Override - public Iterator iterator() - { - return new FilledCellIterator(); - } - - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned is a {@link CellType#BLANK}. The type can be changed - * either through calling setCellValue or setCellType. - * - * @param column - the column number this cell represents - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greater than the maximum number of supported columns - * (255 for *.xls, 1048576 for *.xlsx) - */ - @Override - public SXSSFCell createCell(int column) - { - return createCell(column, CellType.BLANK); - } - - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned is a {@link CellType#BLANK}. The type can be changed - * either through calling setCellValue or setCellType. - * - * @param column - the column number this cell represents - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greate than a maximum number of supported columns - * (255 for *.xls, 1048576 for *.xlsx) - * @deprecated POI 3.15 beta 3. Use {@link #createCell(int, CellType)} instead. - */ - @Override - public SXSSFCell createCell(int column, int type) - { - return createCell(column, CellType.forInt(type)); - } - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned is a {@link CellType#BLANK}. The type can be changed - * either through calling setCellValue or setCellType. - * - * @param column - the column number this cell represents - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greate than a maximum number of supported columns - * (255 for *.xls, 1048576 for *.xlsx) - */ - @Override - public SXSSFCell createCell(int column, CellType type) - { - checkBounds(column); - SXSSFCell cell = new SXSSFCell(this, type); - _cells.put(column, cell); - return cell; - } - - /** - * @throws RuntimeException if the bounds are exceeded. - */ - private static void checkBounds(int cellIndex) { - SpreadsheetVersion v = SpreadsheetVersion.EXCEL2007; - int maxcol = SpreadsheetVersion.EXCEL2007.getLastColumnIndex(); - if (cellIndex < 0 || cellIndex > maxcol) { - throw new IllegalArgumentException("Invalid column index (" + cellIndex - + "). Allowable column range for " + v.name() + " is (0.." - + maxcol + ") or ('A'..'" + v.getLastColumnName() + "')"); - } - } - - /** - * Remove the Cell from this row. - * - * @param cell the cell to remove - */ - @Override - public void removeCell(Cell cell) - { - int index = getCellIndex((SXSSFCell) cell); - _cells.remove(index); - } - - /** - * Return the column number of a cell if it is in this row - * Otherwise return -1 - * - * @param cell the cell to get the index of - * @return cell column index if it is in this row, -1 otherwise - */ - /*package*/ int getCellIndex(SXSSFCell cell) - { - for (Entry entry : _cells.entrySet()) { - if (entry.getValue()==cell) { - return entry.getKey(); - } - } - return -1; - } - - /** - * Set the row number of this row. - * - * @param rowNum the row number (0-based) - * @throws IllegalArgumentException if rowNum < 0 - */ - @Override - public void setRowNum(int rowNum) - { - _sheet.changeRowNum(this,rowNum); - } - - /** - * Get row number this row represents - * - * @return the row number (0 based) - */ - @Override - public int getRowNum() - { - return _sheet.getRowNum(this); - } - - /** - * Get the cell representing a given column (logical cell) 0-based. - * If cell is missing or blank, uses the workbook's MissingCellPolicy - * to determine the return value. - * - * @param cellnum 0 based column number - * @return Cell representing that column or null if undefined. - * @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy) - * @throws RuntimeException if cellnum is out of bounds - */ - @Override - public SXSSFCell getCell(int cellnum) { - MissingCellPolicy policy = _sheet.getWorkbook().getMissingCellPolicy(); - return getCell(cellnum, policy); - } - - /** - * Returns the cell at the given (0 based) index, with the specified {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} - * - * @return the cell at the given (0 based) index - * @throws IllegalArgumentException if cellnum < 0 or the specified MissingCellPolicy is invalid - */ - @Override - public SXSSFCell getCell(int cellnum, MissingCellPolicy policy) - { - checkBounds(cellnum); - - final SXSSFCell cell = _cells.get(cellnum); - switch (policy) { - case RETURN_NULL_AND_BLANK: - return cell; - case RETURN_BLANK_AS_NULL: - boolean isBlank = (cell != null && cell.getCellTypeEnum() == CellType.BLANK); - return (isBlank) ? null : cell; - case CREATE_NULL_AS_BLANK: - return (cell == null) ? createCell(cellnum, CellType.BLANK) : cell; - default: - throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")"); - } - } - - /** - * Get the number of the first cell contained in this row. - * - * @return short representing the first logical cell in the row, - * or -1 if the row does not contain any cells. - */ - @Override - public short getFirstCellNum() - { - try { - return _cells.firstKey().shortValue(); - } catch (final NoSuchElementException e) { - return -1; - } - } - - /** - * Gets the index of the last cell contained in this row PLUS ONE. The result also - * happens to be the 1-based column number of the last cell. This value can be used as a - * standard upper bound when iterating over cells: - *

        -     * short minColIx = row.getFirstCellNum();
        -     * short maxColIx = row.getLastCellNum();
        -     * for(short colIx=minColIx; colIx<maxColIx; colIx++) {
        -     *   Cell cell = row.getCell(colIx);
        -     *   if(cell == null) {
        -     *     continue;
        -     *   }
        -     *   //... do something with cell
        -     * }
        -     * 
        - * - * @return short representing the last logical cell in the row PLUS ONE, - * or -1 if the row does not contain any cells. - */ - @Override - public short getLastCellNum() - { - return _cells.isEmpty() ? -1 : (short)(_cells.lastKey() + 1); - } - - /** - * Gets the number of defined cells (NOT number of cells in the actual row!). - * That is to say if only columns 0,4,5 have values then there would be 3. - * - * @return int representing the number of defined cells in the row. - */ - @Override - public int getPhysicalNumberOfCells() - { - return _cells.size(); - } - - /** - * Set the row's height or set to ff (-1) for undefined/default-height. Set the height in "twips" or - * 1/20th of a point. - * - * @param height rowheight or 0xff for undefined (use sheet default) - */ - @Override - public void setHeight(short height) - { - _height=height; - } - - /** - * Set whether or not to display this row with 0 height - * - * @param zHeight height is zero or not. - */ - @Override - public void setZeroHeight(boolean zHeight) - { - _zHeight=zHeight; - } - - /** - * Get whether or not to display this row with 0 height - * - * @return - zHeight height is zero or not. - */ - @Override - public boolean getZeroHeight() - { - return _zHeight; - } - - /** - * Set the row's height in points. - * - * @param height the height in points. -1 resets to the default height - */ - @Override - public void setHeightInPoints(float height) - { - if(height==-1) - _height=-1; - else - _height=(short)(height*20); - } - - /** - * Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned, - * See {@link Sheet#getDefaultRowHeightInPoints()} - * - * @return row height measured in twips (1/20th of a point) - */ - @Override - public short getHeight() - { - return (short)(_height==-1?getSheet().getDefaultRowHeightInPoints()*20:_height); - } - - /** - * Returns row height measured in point size. If the height is not set, the default worksheet value is returned, - * See {@link Sheet#getDefaultRowHeightInPoints()} - * - * @return row height measured in point size - * @see Sheet#getDefaultRowHeightInPoints() - */ - @Override - public float getHeightInPoints() - { - return (float)(_height==-1?getSheet().getDefaultRowHeightInPoints():_height/20.0); - } - - /** - * Is this row formatted? Most aren't, but some rows - * do have whole-row styles. For those that do, you - * can get the formatting from {@link #getRowStyle()} - */ - @Override - public boolean isFormatted() { - return _style > -1; - } - /** - * Returns the whole-row cell style. Most rows won't - * have one of these, so will return null. Call - * {@link #isFormatted()} to check first. - */ - @Override - public CellStyle getRowStyle() { - if(!isFormatted()) return null; - - return getSheet().getWorkbook().getCellStyleAt(_style); - } - - @Internal - /*package*/ int getRowStyleIndex() { - return _style; - } - - /** - * Applies a whole-row cell styling to the row. - * The row style can be cleared by passing in null. - */ - @Override - public void setRowStyle(CellStyle style) { - if(style == null) { - _style = -1; - } else { - _style = style.getIndex(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Iterator cellIterator() - { - return iterator(); - } - - /** - * Returns the Sheet this row belongs to - * - * @return the Sheet that owns this row - */ - @Override - public SXSSFSheet getSheet() - { - return _sheet; - } -//end of interface implementation - - - /** - * Create an iterator over the cells from [0, getLastCellNum()). - * Includes blank cells, excludes empty cells - * - * Returns an iterator over all filled cells (created via Row.createCell()) - * Throws ConcurrentModificationException if cells are added, moved, or - * removed after the iterator is created. - */ - public class FilledCellIterator implements Iterator - { - private final Iterator iter = _cells.values().iterator(); - - @Override - public boolean hasNext() - { - return iter.hasNext(); - } - @Override - public Cell next() throws NoSuchElementException - { - return iter.next(); - } - @Override - public void remove() - { - throw new UnsupportedOperationException(); - } - } - /** - * returns all cells including empty cells (null values are returned - * for empty cells). - * This method is not synchronized. This iterator should not be used after - * cells are added, moved, or removed, though a ConcurrentModificationException - * is NOT thrown. - */ - public class CellIterator implements Iterator - { - final int maxColumn = getLastCellNum(); //last column PLUS ONE - int pos = 0; - - @Override - public boolean hasNext() - { - return pos < maxColumn; - } - @Override - public Cell next() throws NoSuchElementException - { - if (hasNext()) - return _cells.get(pos++); - else - throw new NoSuchElementException(); - } - @Override - public void remove() - { - throw new UnsupportedOperationException(); - } - } - - /** - * Compares two SXSSFRow objects. Two rows are equal if they belong to the same worksheet and - * their row indexes are equal. - * - * @param other the SXSSFRow to be compared. - * @return
          - *
        • - * the value 0 if the row number of this SXSSFRow is - * equal to the row number of the argument SXSSFRow - *
        • - *
        • - * a value less than 0 if the row number of this this SXSSFRow is - * numerically less than the row number of the argument SXSSFRow - *
        • - *
        • - * a value greater than 0 if the row number of this this SXSSFRow is - * numerically greater than the row number of the argument SXSSFRow - *
        • - *
        - * @throws IllegalArgumentException if the argument row belongs to a different worksheet - */ - @Override - public int compareTo(SXSSFRow other) { - if (this.getSheet() != other.getSheet()) { - throw new IllegalArgumentException("The compared rows must belong to the same sheet"); - } - - Integer thisRow = this.getRowNum(); - Integer otherRow = other.getRowNum(); - return thisRow.compareTo(otherRow); - } - - @Override - public boolean equals(Object obj) - { - if (!(obj instanceof SXSSFRow)) - { - return false; - } - SXSSFRow other = (SXSSFRow) obj; - - return (this.getRowNum() == other.getRowNum()) && - (this.getSheet() == other.getSheet()); - } - - @Override - public int hashCode() { - return _cells.hashCode(); - } - - -} - diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java deleted file mode 100644 index 2c9fb6e37..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ /dev/null @@ -1,1953 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.AutoFilter; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellRange; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Footer; -import org.apache.poi.ss.usermodel.Header; -import org.apache.poi.ss.usermodel.PrintSetup; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.SheetConditionalFormatting; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.PaneInformation; -import org.apache.poi.ss.util.SheetUtil; -import org.apache.poi.util.Internal; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.Removal; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.xssf.usermodel.XSSFComment; -import org.apache.poi.xssf.usermodel.XSSFDataValidation; -import org.apache.poi.xssf.usermodel.XSSFHyperlink; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; - -/** - * Streaming version of XSSFSheet implementing the "BigGridDemo" strategy. -*/ -public class SXSSFSheet implements Sheet -{ - /*package*/ final XSSFSheet _sh; - private final SXSSFWorkbook _workbook; - private final TreeMap _rows=new TreeMap(); - private final SheetDataWriter _writer; - private int _randomAccessWindowSize = SXSSFWorkbook.DEFAULT_WINDOW_SIZE; - private final AutoSizeColumnTracker _autoSizeColumnTracker; - private int outlineLevelRow = 0; - private int lastFlushedRowNumber = -1; - private boolean allFlushed = false; - - public SXSSFSheet(SXSSFWorkbook workbook, XSSFSheet xSheet) throws IOException { - _workbook = workbook; - _sh = xSheet; - _writer = workbook.createSheetDataWriter(); - setRandomAccessWindowSize(_workbook.getRandomAccessWindowSize()); - _autoSizeColumnTracker = new AutoSizeColumnTracker(this); - } - - /** - * for testing purposes only - */ - @Internal - SheetDataWriter getSheetDataWriter(){ - return _writer; - } - -/* Gets "" document fragment*/ - public InputStream getWorksheetXMLInputStream() throws IOException - { - // flush all remaining data and close the temp file writer - flushRows(0); - _writer.close(); - return _writer.getWorksheetXMLInputStream(); - } - -//start of interface implementation - @Override - public Iterator iterator() - { - return rowIterator(); - } - - /** - * Create a new row within the sheet and return the high level representation - * - * @param rownum row number - * @return high level Row object representing a row in the sheet - * @throws IllegalArgumentException If the max. number of rows is exceeded or - * a rownum is provided where the row is already flushed to disk. - * @see #removeRow(Row) - */ - @Override - public SXSSFRow createRow(int rownum) - { - int maxrow = SpreadsheetVersion.EXCEL2007.getLastRowIndex(); - if (rownum < 0 || rownum > maxrow) { - throw new IllegalArgumentException("Invalid row number (" + rownum - + ") outside allowable range (0.." + maxrow + ")"); - } - - // attempt to overwrite a row that is already flushed to disk - if(rownum <= _writer.getLastFlushedRow() ) { - throw new IllegalArgumentException( - "Attempting to write a row["+rownum+"] " + - "in the range [0," + _writer.getLastFlushedRow() + "] that is already written to disk."); - } - - // attempt to overwrite a existing row in the input template - if(_sh.getPhysicalNumberOfRows() > 0 && rownum <= _sh.getLastRowNum() ) { - throw new IllegalArgumentException( - "Attempting to write a row["+rownum+"] " + - "in the range [0," + _sh.getLastRowNum() + "] that is already written to disk."); - } - - SXSSFRow newRow=new SXSSFRow(this); - _rows.put(rownum,newRow); - allFlushed = false; - if(_randomAccessWindowSize>=0&&_rows.size()>_randomAccessWindowSize) - { - try - { - flushRows(_randomAccessWindowSize); - } - catch (IOException ioe) - { - throw new RuntimeException(ioe); - } - } - return newRow; - } - - /** - * Remove a row from this sheet. All cells contained in the row are removed as well - * - * @param row representing a row to remove. - */ - @Override - public void removeRow(Row row) - { - if (row.getSheet() != this) { - throw new IllegalArgumentException("Specified row does not belong to this sheet"); - } - - for(Iterator> iter=_rows.entrySet().iterator();iter.hasNext();) - { - Map.Entry entry=iter.next(); - if(entry.getValue()==row) - { - iter.remove(); - return; - } - } - } - - /** - * Returns the logical row (not physical) 0-based. If you ask for a row that is not - * defined you get a null. This is to say row 4 represents the fifth row on a sheet. - * - * @param rownum row to get (0-based) - * @return Row representing the rownumber or null if its not defined on the sheet - */ - @Override - public SXSSFRow getRow(int rownum) - { - return _rows.get(rownum); - } - - /** - * Returns the number of physically defined rows (NOT the number of rows in the sheet) - * - * @return the number of physically defined rows in this sheet - */ - @Override - public int getPhysicalNumberOfRows() - { - return _rows.size()+_writer.getNumberOfFlushedRows(); - } - - /** - * Gets the first row on the sheet - * - * @return the number of the first logical row on the sheet (0-based) - */ - @Override - public int getFirstRowNum() - { - if(_writer.getNumberOfFlushedRows() > 0) - return _writer.getLowestIndexOfFlushedRows(); - return _rows.size() == 0 ? 0 : _rows.firstKey(); - } - - /** - * Gets the last row on the sheet - * - * @return last row contained n this sheet (0-based) - */ - @Override - public int getLastRowNum() - { - return _rows.size() == 0 ? 0 : _rows.lastKey(); - } - - /** - * Get the visibility state for a given column - * - * @param columnIndex - the column to get (0-based) - * @param hidden - the visiblity state of the column - */ - @Override - public void setColumnHidden(int columnIndex, boolean hidden) - { - _sh.setColumnHidden(columnIndex,hidden); - } - - /** - * Get the hidden state for a given column - * - * @param columnIndex - the column to set (0-based) - * @return hidden - false if the column is visible - */ - @Override - public boolean isColumnHidden(int columnIndex) - { - return _sh.isColumnHidden(columnIndex); - } - - /** - * Set the width (in units of 1/256th of a character width) - *

        - * The maximum column width for an individual cell is 255 characters. - * This value represents the number of characters that can be displayed - * in a cell that is formatted with the standard font. - *

        - * - * @param columnIndex - the column to set (0-based) - * @param width - the width in units of 1/256th of a character width - */ - @Override - public void setColumnWidth(int columnIndex, int width) - { - _sh.setColumnWidth(columnIndex,width); - } - - /** - * get the width (in units of 1/256th of a character width ) - * @param columnIndex - the column to set (0-based) - * @return width - the width in units of 1/256th of a character width - */ - @Override - public int getColumnWidth(int columnIndex) - { - return _sh.getColumnWidth(columnIndex); - } - - /** - * Get the actual column width in pixels - * - *

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Calibri 11pt for .xlsx). - *

        - */ - @Override - public float getColumnWidthInPixels(int columnIndex) { - return _sh.getColumnWidthInPixels(columnIndex); - } - - /** - * Set the default column width for the sheet (if the columns do not define their own width) - * in characters - * - * @param width default column width measured in characters - */ - @Override - public void setDefaultColumnWidth(int width) - { - _sh.setDefaultColumnWidth(width); - } - - /** - * Get the default column width for the sheet (if the columns do not define their own width) - * in characters - * - * @return default column width measured in characters - */ - @Override - public int getDefaultColumnWidth() - { - return _sh.getDefaultColumnWidth(); - } - - - /** - * Get the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @return default row height measured in twips (1/20 of a point) - */ - @Override - public short getDefaultRowHeight() - { - return _sh.getDefaultRowHeight(); - } - - /** - * Get the default row height for the sheet (if the rows do not define their own height) in - * points. - * - * @return default row height in points - */ - @Override - public float getDefaultRowHeightInPoints() - { - return _sh.getDefaultRowHeightInPoints(); - } - - /** - * Set the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @param height default row height measured in twips (1/20 of a point) - */ - @Override - public void setDefaultRowHeight(short height) - { - _sh.setDefaultRowHeight(height); - } - - /** - * Set the default row height for the sheet (if the rows do not define their own height) in - * points - * @param height default row height - */ - @Override - public void setDefaultRowHeightInPoints(float height) - { - _sh.setDefaultRowHeightInPoints(height); - } - - - /** - * Returns the CellStyle that applies to the given - * (0 based) column, or null if no style has been - * set for that column - */ - @Override - public CellStyle getColumnStyle(int column) - { - return _sh.getColumnStyle(column); - } - - /** - * Sets the CellStyle that applies to the given - * (0 based) column. - */ -// public CellStyle setColumnStyle(int column, CellStyle style); - - /** - * Adds a merged region of cells (hence those cells form one) - * - * @param region (rowfrom/colfrom-rowto/colto) to merge - * @return index of this region - */ - @Override - public int addMergedRegion(CellRangeAddress region) - { - return _sh.addMergedRegion(region); - } - - /** - * Adds a merged region of cells (hence those cells form one) - * - * @param region (rowfrom/colfrom-rowto/colto) to merge - * @return index of this region - */ - @Override - public int addMergedRegionUnsafe(CellRangeAddress region) - { - return _sh.addMergedRegionUnsafe(region); - } - - /** - * Verify that merged regions do not intersect multi-cell array formulas and - * no merged regions intersect another merged region in this sheet. - * - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if at least one region intersects with another merged region in this sheet - */ - @Override - public void validateMergedRegions() { - _sh.validateMergedRegions(); - } - - /** - * Determines whether the output is vertically centered on the page. - * - * @param value true to vertically center, false otherwise. - */ - @Override - public void setVerticallyCenter(boolean value) - { - _sh.setVerticallyCenter(value); - } - - /** - * Determines whether the output is horizontally centered on the page. - * - * @param value true to horizontally center, false otherwise. - */ - @Override - public void setHorizontallyCenter(boolean value) - { - _sh.setHorizontallyCenter(value); - } - - /** - * Determine whether printed output for this sheet will be horizontally centered. - */ - @Override - public boolean getHorizontallyCenter() - { - return _sh.getHorizontallyCenter(); - } - - /** - * Determine whether printed output for this sheet will be vertically centered. - */ - @Override - public boolean getVerticallyCenter() - { - return _sh.getVerticallyCenter(); - } - - /** - * Removes a merged region of cells (hence letting them free) - * - * @param index of the region to unmerge - */ - @Override - public void removeMergedRegion(int index) - { - _sh.removeMergedRegion(index); - } - - /** - * Removes a merged region of cells (hence letting them free) - * - * @param indices of the regions to unmerge - */ - @Override - public void removeMergedRegions(Collection indices) - { - _sh.removeMergedRegions(indices); - } - - /** - * Returns the number of merged regions - * - * @return number of merged regions - */ - @Override - public int getNumMergedRegions() - { - return _sh.getNumMergedRegions(); - } - - /** - * Returns the merged region at the specified index. If you want multiple - * regions, it is faster to call {@link #getMergedRegions()} than to call - * this each time. - * - * @return the merged region at the specified index - */ - @Override - public CellRangeAddress getMergedRegion(int index) - { - return _sh.getMergedRegion(index); - } - - /** - * Returns the list of merged regions. If you want multiple regions, this is - * faster than calling {@link #getMergedRegion(int)} each time. - * - * @return the list of merged regions - */ - @Override - public List getMergedRegions() { - return _sh.getMergedRegions(); - } - - /** - * Returns an iterator of the physical rows - * - * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not - * be the third row if say for instance the second row is undefined. - */ - @Override - public Iterator rowIterator() - { - @SuppressWarnings("unchecked") - Iterator result = (Iterator)(Iterator)_rows.values().iterator(); - return result; - } - - /** - * Flag indicating whether the sheet displays Automatic Page Breaks. - * - * @param value true if the sheet displays Automatic Page Breaks. - */ - @Override - public void setAutobreaks(boolean value) - { - _sh.setAutobreaks(value); - } - - /** - * Set whether to display the guts or not - * - * @param value - guts or no guts - */ - @Override - public void setDisplayGuts(boolean value) - { - _sh.setDisplayGuts(value); - } - - /** - * Set whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - * - * @param value whether to display or hide all zero values on the worksheet - */ - @Override - public void setDisplayZeros(boolean value) - { - _sh.setDisplayZeros(value); - } - - - /** - * Gets the flag indicating whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - * - * @return whether all zero values on the worksheet are displayed - */ - @Override - public boolean isDisplayZeros() - { - return _sh.isDisplayZeros(); - } - - /** - * Sets whether the worksheet is displayed from right to left instead of from left to right. - * - * @param value true for right to left, false otherwise. - */ - @Override - public void setRightToLeft(boolean value) - { - _sh.setRightToLeft(value); - } - - /** - * Whether the text is displayed in right-to-left mode in the window - * - * @return whether the text is displayed in right-to-left mode in the window - */ - @Override - public boolean isRightToLeft() - { - return _sh.isRightToLeft(); - } - - /** - * Flag indicating whether the Fit to Page print option is enabled. - * - * @param value true if the Fit to Page print option is enabled. - */ - @Override - public void setFitToPage(boolean value) - { - _sh.setFitToPage(value); - } - - /** - * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. - * - *

        - * When true a summary row is inserted below the detailed data being summarized and a - * new outline level is established on that row. - *

        - *

        - * When false a summary row is inserted above the detailed data being summarized and a new outline level - * is established on that row. - *

        - * @param value true if row summaries appear below detail in the outline - */ - @Override - public void setRowSumsBelow(boolean value) - { - _sh.setRowSumsBelow(value); - } - - /** - * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. - * - *

        - * When true a summary column is inserted to the right of the detailed data being summarized - * and a new outline level is established on that column. - *

        - *

        - * When false a summary column is inserted to the left of the detailed data being - * summarized and a new outline level is established on that column. - *

        - * @param value true if col summaries appear right of the detail in the outline - */ - @Override - public void setRowSumsRight(boolean value) - { - _sh.setRowSumsRight(value); - } - - /** - * Flag indicating whether the sheet displays Automatic Page Breaks. - * - * @return true if the sheet displays Automatic Page Breaks. - */ - @Override - public boolean getAutobreaks() - { - return _sh.getAutobreaks(); - } - - /** - * Get whether to display the guts or not, - * default value is true - * - * @return boolean - guts or no guts - */ - @Override - public boolean getDisplayGuts() - { - return _sh.getDisplayGuts(); - } - - /** - * Flag indicating whether the Fit to Page print option is enabled. - * - * @return true if the Fit to Page print option is enabled. - */ - @Override - public boolean getFitToPage() - { - return _sh.getFitToPage(); - } - - /** - * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. - * - *

        - * When true a summary row is inserted below the detailed data being summarized and a - * new outline level is established on that row. - *

        - *

        - * When false a summary row is inserted above the detailed data being summarized and a new outline level - * is established on that row. - *

        - * @return true if row summaries appear below detail in the outline - */ - @Override - public boolean getRowSumsBelow() - { - return _sh.getRowSumsBelow(); - } - - /** - * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. - * - *

        - * When true a summary column is inserted to the right of the detailed data being summarized - * and a new outline level is established on that column. - *

        - *

        - * When false a summary column is inserted to the left of the detailed data being - * summarized and a new outline level is established on that column. - *

        - * @return true if col summaries appear right of the detail in the outline - */ - @Override - public boolean getRowSumsRight() - { - return _sh.getRowSumsRight(); - } - - /** - * Returns whether gridlines are printed. - * - * @return whether gridlines are printed - */ - @Override - public boolean isPrintGridlines() - { - return _sh.isPrintGridlines(); - } - - /** - * Turns on or off the printing of gridlines. - * - * @param show boolean to turn on or off the printing of gridlines - */ - @Override - public void setPrintGridlines(boolean show) - { - _sh.setPrintGridlines(show); - } - - /** - * Returns whether row and column headings are printed. - * - * @return whether row and column headings are printed - */ - @Override - public boolean isPrintRowAndColumnHeadings() - { - return _sh.isPrintRowAndColumnHeadings(); - } - - /** - * Turns on or off the printing of row and column headings. - * - * @param show boolean to turn on or off the printing of row and column headings - */ - @Override - public void setPrintRowAndColumnHeadings(boolean show) - { - _sh.setPrintRowAndColumnHeadings(show); - } - - /** - * Gets the print setup object. - * - * @return The user model for the print setup object. - */ - @Override - public PrintSetup getPrintSetup() - { - return _sh.getPrintSetup(); - } - - /** - * Gets the user model for the default document header. - *

        - * Note that XSSF offers more kinds of document headers than HSSF does - *

        - * @return the document header. Never null - */ - @Override - public Header getHeader() - { - return _sh.getHeader(); - } - - /** - * Gets the user model for the default document footer. - *

        - * Note that XSSF offers more kinds of document footers than HSSF does. - *

        - * @return the document footer. Never null - */ - @Override - public Footer getFooter() - { - return _sh.getFooter(); - } - - /** - * Sets a flag indicating whether this sheet is selected. - *

        - * Note: multiple sheets can be selected, but only one sheet can be active at one time. - *

        - * @param value true if this sheet is selected - * @see Workbook#setActiveSheet(int) - */ - @Override - public void setSelected(boolean value) - { - _sh.setSelected(value); - } - - /** - * Gets the size of the margin in inches. - * - * @param margin which margin to get - * @return the size of the margin - */ - @Override - public double getMargin(short margin) - { - return _sh.getMargin(margin); - } - - /** - * Sets the size of the margin in inches. - * - * @param margin which margin to get - * @param size the size of the margin - */ - @Override - public void setMargin(short margin, double size) - { - _sh.setMargin(margin,size); - } - - /** - * Answer whether protection is enabled or disabled - * - * @return true means protection enabled; false means protection disabled - */ - @Override - public boolean getProtect() - { - return _sh.getProtect(); - } - - /** - * Sets the protection enabled as well as the password - * @param password to set for protection. Pass null to remove protection - */ - @Override - public void protectSheet(String password) - { - _sh.protectSheet(password); - } - - /** - * Answer whether scenario protection is enabled or disabled - * - * @return true means protection enabled; false means protection disabled - */ - @Override - public boolean getScenarioProtect() - { - return _sh.getScenarioProtect(); - } - - /** - * Sets the zoom magnification for the sheet. The zoom is expressed as a - * fraction. For example to express a zoom of 75% use 3 for the numerator - * and 4 for the denominator. - * - * @param numerator The numerator for the zoom magnification. - * @param denominator The denominator for the zoom magnification. - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #setZoom(int)} instead. - */ - @Removal(version="3.16") - @Override - public void setZoom(int numerator, int denominator) - { - _sh.setZoom(numerator,denominator); - } - - /** - * Window zoom magnification for current view representing percent values. - * Valid values range from 10 to 400. Horizontal and Vertical scale together. - * - * For example: - *
        -     * 10 - 10%
        -     * 20 - 20%
        -     * ...
        -     * 100 - 100%
        -     * ...
        -     * 400 - 400%
        -     * 
        - * - * Current view can be Normal, Page Layout, or Page Break Preview. - * - * @param scale window zoom magnification - * @throws IllegalArgumentException if scale is invalid - */ - @Override - public void setZoom(int scale) { - _sh.setZoom(scale); - } - - /** - * The top row in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return short indicating the rownum (0 based) of the top row - */ - @Override - public short getTopRow() - { - return _sh.getTopRow(); - } - - /** - * The left col in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return short indicating the rownum (0 based) of the top row - */ - @Override - public short getLeftCol() - { - return _sh.getLeftCol(); - } - - /** - * Sets desktop window pane display area, when the - * file is first opened in a viewer. - * - * @param toprow the top row to show in desktop window pane - * @param leftcol the left column to show in desktop window pane - */ - @Override - public void showInPane(int toprow, int leftcol) - { - _sh.showInPane(toprow, leftcol); - } - - /** - * Control if Excel should be asked to recalculate all formulas when the - * workbook is opened, via the "sheetCalcPr fullCalcOnLoad" option. - * Calculating the formula values with {@link org.apache.poi.ss.usermodel.FormulaEvaluator} is the - * recommended solution, but this may be used for certain cases where - * evaluation in POI is not possible. - */ - @Override - public void setForceFormulaRecalculation(boolean value) { - _sh.setForceFormulaRecalculation(value); - } - - /** - * Whether Excel will be asked to recalculate all formulas when the - * workbook is opened. - */ - @Override - public boolean getForceFormulaRecalculation() { - return _sh.getForceFormulaRecalculation(); - } - - /** - * Not implemented for SXSSFSheets - * - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around. - * - * Calls shiftRows(startRow, endRow, n, false, false); - * - *

        - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - */ - @NotImplemented - @Override - public void shiftRows(int startRow, int endRow, int n) - { - throw new RuntimeException("NotImplemented"); - } - - /** - * Not implemented for SXSSFSheets - * - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around - * - *

        - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). All merged regions that are - * completely overlaid by shifting will be deleted. - *

        - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - * @param copyRowHeight whether to copy the row height during the shift - * @param resetOriginalRowHeight whether to set the original row's height to the default - */ - @NotImplemented - @Override - public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) - { - throw new RuntimeException("NotImplemented"); - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - * @param leftmostColumn Left column visible in right pane. - * @param topRow Top row visible in bottom pane - */ - @Override - public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) - { - _sh.createFreezePane(colSplit, rowSplit, leftmostColumn, topRow); - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - * @param colSplit Horizonatal position of split. - * @param rowSplit Vertical position of split. - */ - @Override - public void createFreezePane(int colSplit, int rowSplit) - { - _sh.createFreezePane(colSplit,rowSplit); - } - - /** - * Creates a split pane. Any existing freezepane or split pane is overwritten. - * @param xSplitPos Horizonatal position of split (in 1/20th of a point). - * @param ySplitPos Vertical position of split (in 1/20th of a point). - * @param topRow Top row visible in bottom pane - * @param leftmostColumn Left column visible in right pane. - * @param activePane Active pane. One of: PANE_LOWER_RIGHT, - * PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT - * @see #PANE_LOWER_LEFT - * @see #PANE_LOWER_RIGHT - * @see #PANE_UPPER_LEFT - * @see #PANE_UPPER_RIGHT - */ - @Override - public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) - { - _sh.createSplitPane(xSplitPos, ySplitPos, leftmostColumn, topRow, activePane); - } - - /** - * Returns the information regarding the currently configured pane (split or freeze) - * - * @return null if no pane configured, or the pane information. - */ - @Override - public PaneInformation getPaneInformation() - { - return _sh.getPaneInformation(); - } - - /** - * Sets whether the gridlines are shown in a viewer - * - * @param show whether to show gridlines or not - */ - @Override - public void setDisplayGridlines(boolean show) - { - _sh.setDisplayGridlines(show); - } - - /** - * Returns if gridlines are displayed - * - * @return whether gridlines are displayed - */ - @Override - public boolean isDisplayGridlines() - { - return _sh.isDisplayGridlines(); - } - - /** - * Sets whether the formulas are shown in a viewer - * - * @param show whether to show formulas or not - */ - @Override - public void setDisplayFormulas(boolean show) - { - _sh.setDisplayFormulas(show); - } - - /** - * Returns if formulas are displayed - * - * @return whether formulas are displayed - */ - @Override - public boolean isDisplayFormulas() - { - return _sh.isDisplayFormulas(); - } - - /** - * Sets whether the RowColHeadings are shown in a viewer - * - * @param show whether to show RowColHeadings or not - */ - @Override - public void setDisplayRowColHeadings(boolean show) - { - _sh.setDisplayRowColHeadings(show); - } - - /** - * Returns if RowColHeadings are displayed. - * @return whether RowColHeadings are displayed - */ - @Override - public boolean isDisplayRowColHeadings() - { - return _sh.isDisplayRowColHeadings(); - } - - /** - * Sets a page break at the indicated row - * @param row FIXME: Document this! - */ - @Override - public void setRowBreak(int row) - { - _sh.setRowBreak(row); - } - - /** - * Determines if there is a page break at the indicated row - * @param row FIXME: Document this! - * @return FIXME: Document this! - */ - @Override - public boolean isRowBroken(int row) - { - return _sh.isRowBroken(row); - } - - /** - * Removes the page break at the indicated row - * @param row - */ - @Override - public void removeRowBreak(int row) - { - _sh.removeRowBreak(row); - } - - /** - * Retrieves all the horizontal page breaks - * @return all the horizontal page breaks, or null if there are no row page breaks - */ - @Override - public int[] getRowBreaks() - { - return _sh.getRowBreaks(); - } - - /** - * Retrieves all the vertical page breaks - * @return all the vertical page breaks, or null if there are no column page breaks - */ - @Override - public int[] getColumnBreaks() - { - return _sh.getColumnBreaks(); - } - - /** - * Sets a page break at the indicated column - * @param column - */ - @Override - public void setColumnBreak(int column) - { - _sh.setColumnBreak(column); - } - - /** - * Determines if there is a page break at the indicated column - * @param column FIXME: Document this! - * @return FIXME: Document this! - */ - @Override - public boolean isColumnBroken(int column) - { - return _sh.isColumnBroken(column); - } - - /** - * Removes a page break at the indicated column - * @param column - */ - @Override - public void removeColumnBreak(int column) - { - _sh.removeColumnBreak(column); - } - - /** - * Expands or collapses a column group. - * - * @param columnNumber One of the columns in the group. - * @param collapsed true = collapse group, false = expand group. - */ - @Override - public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) - { - _sh.setColumnGroupCollapsed(columnNumber, collapsed); - } - - /** - * Create an outline for the provided column range. - * - * @param fromColumn beginning of the column range. - * @param toColumn end of the column range. - */ - @Override - public void groupColumn(int fromColumn, int toColumn) - { - _sh.groupColumn(fromColumn,toColumn); - } - - /** - * Ungroup a range of columns that were previously groupped - * - * @param fromColumn start column (0-based) - * @param toColumn end column (0-based) - */ - @Override - public void ungroupColumn(int fromColumn, int toColumn) - { - _sh.ungroupColumn(fromColumn, toColumn); - } - - /** - * Tie a range of rows together so that they can be collapsed or expanded - * - *

        - * Please note the rows being grouped must be in the current window, - * if the rows are already flushed then groupRow has no effect. - *

        - * - * Correct code: - *
        
        -     *       Workbook wb = new SXSSFWorkbook(100);  // keep 100 rows in memory
        -     *       Sheet sh = wb.createSheet();
        -     *       for (int rownum = 0; rownum < 1000; rownum++) {
        -     *           Row row = sh.createRow(rownum);
        -     *           if(rownum == 200)  {
        -     *               sh.groupRow(100, 200);
        -     *           }
        -     *       }
        -     *
        -     *      
        - * - * - * Incorrect code: - *
        
        -     *       Workbook wb = new SXSSFWorkbook(100);  // keep 100 rows in memory
        -     *       Sheet sh = wb.createSheet();
        -     *       for (int rownum = 0; rownum < 1000; rownum++) {
        -     *           Row row = sh.createRow(rownum);
        -     *       }
        -     *       sh.groupRow(100, 200); // the rows in the range [100, 200] are already flushed and groupRows has no effect
        -     *
        -     *      
        - * - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - @Override - public void groupRow(int fromRow, int toRow) - { - for(SXSSFRow row : _rows.subMap(fromRow, toRow + 1).values()){ - int level = row.getOutlineLevel() + 1; - row.setOutlineLevel(level); - - if(level > outlineLevelRow) outlineLevelRow = level; - } - - setWorksheetOutlineLevelRow(); - } - - /** - * Set row groupings (like groupRow) in a stream-friendly manner - * - *

        - * groupRows requires all rows in the group to be in the current window. - * This is not always practical. Instead use setRowOutlineLevel to - * explicitly set the group level. Level 1 is the top level group, - * followed by 2, etc. It is up to the user to ensure that level 2 - * groups are correctly nested under level 1, etc. - *

        - * - * @param rownum index of row to update (0-based) - * @param level outline level (greater than 0) - */ - public void setRowOutlineLevel(int rownum, int level) - { - SXSSFRow row = _rows.get(rownum); - row.setOutlineLevel(level); - if(level > 0 && level > outlineLevelRow) { - outlineLevelRow = level; - setWorksheetOutlineLevelRow(); - } - } - - private void setWorksheetOutlineLevelRow() { - CTWorksheet ct = _sh.getCTWorksheet(); - CTSheetFormatPr pr = ct.isSetSheetFormatPr() ? - ct.getSheetFormatPr() : - ct.addNewSheetFormatPr(); - if(outlineLevelRow > 0) pr.setOutlineLevelRow((short)outlineLevelRow); - } - - /** - * Ungroup a range of rows that were previously groupped - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - @Override - public void ungroupRow(int fromRow, int toRow) - { - _sh.ungroupRow(fromRow, toRow); - } - - /** - * Set view state of a grouped range of rows. - * - * Not implemented for expanding (i.e. collapse == false) - * - * @param row start row of a groupped range of rows (0-based) - * @param collapse whether to expand/collapse the detail rows - * @throws RuntimeException if collapse is false as this is not implemented for SXSSF. - */ - @Override - public void setRowGroupCollapsed(int row, boolean collapse) - { - if (collapse) { - collapseRow(row); - } else { - //expandRow(rowIndex); - throw new RuntimeException("Unable to expand row: Not Implemented"); - } - } - - /** - * @param rowIndex the zero based row index to collapse - */ - private void collapseRow(int rowIndex) { - SXSSFRow row = getRow(rowIndex); - if(row == null) { - throw new IllegalArgumentException("Invalid row number("+ rowIndex + "). Row does not exist."); - } else { - int startRow = findStartOfRowOutlineGroup(rowIndex); - - // Hide all the columns until the end of the group - int lastRow = writeHidden(row, startRow, true); - SXSSFRow lastRowObj = getRow(lastRow); - if (lastRowObj != null) { - lastRowObj.setCollapsed(true); - } else { - SXSSFRow newRow = createRow(lastRow); - newRow.setCollapsed(true); - } - } - } - - /** - * @param rowIndex the zero based row index to find from - */ - private int findStartOfRowOutlineGroup(int rowIndex) { - // Find the start of the group. - Row row = getRow(rowIndex); - int level = ((SXSSFRow) row).getOutlineLevel(); - if(level == 0) { - throw new IllegalArgumentException("Outline level is zero for the row (" + rowIndex + ")."); - } - int currentRow = rowIndex; - while (getRow(currentRow) != null) { - if (getRow(currentRow).getOutlineLevel() < level) - return currentRow + 1; - currentRow--; - } - return currentRow + 1; - } - - private int writeHidden(SXSSFRow xRow, int rowIndex, boolean hidden) { - int level = xRow.getOutlineLevel(); - SXSSFRow currRow = getRow(rowIndex); - - while (currRow != null && currRow.getOutlineLevel() >= level) { - currRow.setHidden(hidden); - rowIndex++; - currRow = getRow(rowIndex); - } - return rowIndex; - } - - /** - * Sets the default column style for a given column. POI will only apply this style to new cells added to the sheet. - * - * @param column the column index - * @param style the style to set - */ - @Override - public void setDefaultColumnStyle(int column, CellStyle style) - { - _sh.setDefaultColumnStyle(column, style); - } - - - /** - * Track a column in the sheet for auto-sizing. - * Note this has undefined behavior if a column is tracked after one or more rows are written to the sheet. - * If column is already tracked, this call does nothing. - * - * @param column the column to track for auto-sizing - * @since 3.14beta1 - * @see #trackColumnsForAutoSizing(Collection) - * @see #trackAllColumnsForAutoSizing() - */ - public void trackColumnForAutoSizing(int column) - { - _autoSizeColumnTracker.trackColumn(column); - } - - /** - * Track several columns in the sheet for auto-sizing. - * Note this has undefined behavior if columns are tracked after one or more rows are written to the sheet. - * Any column in columns that are already tracked are ignored by this call. - * - * @param columns the columns to track for auto-sizing - * @since 3.14beta1 - */ - public void trackColumnsForAutoSizing(Collection columns) - { - _autoSizeColumnTracker.trackColumns(columns); - } - - /** - * Tracks all columns in the sheet for auto-sizing. If this is called, individual columns do not need to be tracked. - * Because determining the best-fit width for a cell is expensive, this may affect the performance. - * @since 3.14beta1 - */ - public void trackAllColumnsForAutoSizing() - { - _autoSizeColumnTracker.trackAllColumns(); - } - - /** - * Removes a column that was previously marked for inclusion in auto-size column tracking. - * When a column is untracked, the best-fit width is forgotten. - * If column is not tracked, it will be ignored by this call. - * - * @param column the index of the column to track for auto-sizing - * @return true if column was tracked prior to this call, false if no action was taken - * @since 3.14beta1 - * @see #untrackColumnsForAutoSizing(Collection) - * @see #untrackAllColumnsForAutoSizing() - */ - public boolean untrackColumnForAutoSizing(int column) - { - return _autoSizeColumnTracker.untrackColumn(column); - } - - /** - * Untracks several columns in the sheet for auto-sizing. - * When a column is untracked, the best-fit width is forgotten. - * Any column in columns that is not tracked will be ignored by this call. - * - * @param columns the indices of the columns to track for auto-sizing - * @return true if one or more columns were untracked as a result of this call - * @since 3.14beta1 - */ - public boolean untrackColumnsForAutoSizing(Collection columns) - { - return _autoSizeColumnTracker.untrackColumns(columns); - } - - /** - * Untracks all columns in the sheet for auto-sizing. Best-fit column widths are forgotten. - * If this is called, individual columns do not need to be untracked. - * @since 3.14beta1 - */ - public void untrackAllColumnsForAutoSizing() - { - _autoSizeColumnTracker.untrackAllColumns(); - } - - /** - * Returns true if column is currently tracked for auto-sizing. - * - * @param column the index of the column to check - * @return true if column is tracked - * @since 3.14beta1 - */ - public boolean isColumnTrackedForAutoSizing(int column) - { - return _autoSizeColumnTracker.isColumnTracked(column); - } - - /** - * Get the currently tracked columns for auto-sizing. - * Note if all columns are tracked, this will only return the columns that have been explicitly or implicitly tracked, - * which is probably only columns containing 1 or more non-blank values - * - * @return a set of the indices of all tracked columns - * @since 3.14beta1 - */ - public Set getTrackedColumnsForAutoSizing() - { - return _autoSizeColumnTracker.getTrackedColumns(); - } - - /** - * Adjusts the column width to fit the contents. - * - *

        - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - *

        - * You can specify whether the content of merged cells should be considered or ignored. - * Default is to ignore merged cells. - * - *

        - * Special note about SXSSF implementation: You must register the columns you wish to track with - * the SXSSFSheet using {@link #trackColumnForAutoSizing(int)} or {@link #trackAllColumnsForAutoSizing()}. - * This is needed because the rows needed to compute the column width may have fallen outside the - * random access window and been flushed to disk. - * Tracking columns is required even if all rows are in the random access window. - *

        - *

        New in POI 3.14 beta 1: auto-sizes columns using cells from current and flushed rows.

        - * - * @param column the column index to auto-size - */ - @Override - public void autoSizeColumn(int column) - { - autoSizeColumn(column, false); - } - - /** - * Adjusts the column width to fit the contents. - *

        - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - *

        - * You can specify whether the content of merged cells should be considered or ignored. - * Default is to ignore merged cells. - * - *

        - * Special note about SXSSF implementation: You must register the columns you wish to track with - * the SXSSFSheet using {@link #trackColumnForAutoSizing(int)} or {@link #trackAllColumnsForAutoSizing()}. - * This is needed because the rows needed to compute the column width may have fallen outside the - * random access window and been flushed to disk. - * Tracking columns is required even if all rows are in the random access window. - *

        - *

        New in POI 3.14 beta 1: auto-sizes columns using cells from current and flushed rows.

        - * - * @param column the column index to auto-size - * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column - */ - @Override - public void autoSizeColumn(int column, boolean useMergedCells) - { - // Multiple calls to autoSizeColumn need to look up the best-fit width - // of rows already flushed to disk plus re-calculate the best-fit width - // of rows in the current window. It isn't safe to update the column - // widths before flushing to disk because columns in the random access - // window rows may change in best-fit width. The best-fit width of a cell - // is only fixed when it becomes inaccessible for modification. - // Changes to the shared strings table, styles table, or formulas might - // be able to invalidate the auto-size width without the opportunity - // to recalculate the best-fit width for the flushed rows. This is an - // inherent limitation of SXSSF. If having correct auto-sizing is - // critical, the flushed rows would need to be re-read by the read-only - // XSSF eventmodel (SAX) or the memory-heavy XSSF usermodel (DOM). - final int flushedWidth; - try { - // get the best fit width of rows already flushed to disk - flushedWidth = _autoSizeColumnTracker.getBestFitColumnWidth(column, useMergedCells); - } - catch (final IllegalStateException e) { - throw new IllegalStateException("Could not auto-size column. Make sure the column was tracked prior to auto-sizing the column.", e); - } - - // get the best-fit width of rows currently in the random access window - final int activeWidth = (int) (256 * SheetUtil.getColumnWidth(this, column, useMergedCells)); - - // the best-fit width for both flushed rows and random access window rows - // flushedWidth or activeWidth may be negative if column contains only blank cells - final int bestFitWidth = Math.max(flushedWidth, activeWidth); - - if (bestFitWidth > 0) { - final int maxColumnWidth = 255*256; // The maximum column width for an individual cell is 255 characters - final int width = Math.min(bestFitWidth, maxColumnWidth); - setColumnWidth(column, width); - } - } - - /** - * Returns cell comment for the specified row and column - * - * @return cell comment or null if not found - * @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellAddress)} instead. - */ - @Override - public XSSFComment getCellComment(int row, int column) - { - return getCellComment(new CellAddress(row, column)); - } - - /** - * Returns cell comment for the specified row and column - * - * @return cell comment or null if not found - */ - @Override - public XSSFComment getCellComment(CellAddress ref) - { - return _sh.getCellComment(ref); - } - - /** - * Returns all cell comments on this sheet. - * @return A map of each Comment in the sheet, keyed on the cell address where - * the comment is located. - */ - @Override - public Map getCellComments() { - return _sh.getCellComments(); - } - - /** - * Get a Hyperlink in this sheet anchored at row, column - * - * @param row - * @param column - * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null - */ - @Override - public XSSFHyperlink getHyperlink(int row, int column) { - return _sh.getHyperlink(row, column); - } - - /** - * Get a Hyperlink in this sheet located in a cell specified by {code addr} - * - * @param addr The address of the cell containing the hyperlink - * @return hyperlink if there is a hyperlink anchored at {@code addr}; otherwise returns {@code null} - * @since POI 3.15 beta 3 - */ - @Override - public XSSFHyperlink getHyperlink(CellAddress addr) { - return _sh.getHyperlink(addr); - } - - /** - * Get a list of Hyperlinks in this sheet - * - * @return Hyperlinks for the sheet - */ - @Override - public List getHyperlinkList() { - return _sh.getHyperlinkList(); - } - - /** - * {@inheritDoc} - */ - @Override - public Drawing getDrawingPatriarch() - { - return _sh.getDrawingPatriarch(); - } - - /** - * Creates the top-level drawing patriarch. - * - * @return The new drawing patriarch. - */ - @Override - public Drawing createDrawingPatriarch() - { - return new SXSSFDrawing((SXSSFWorkbook)getWorkbook(), _sh.createDrawingPatriarch()); - } - - - /** - * Return the parent workbook - * - * @return the parent workbook - */ - @Override - public SXSSFWorkbook getWorkbook() - { - return _workbook; - } - - /** - * Returns the name of this sheet - * - * @return the name of this sheet - */ - @Override - public String getSheetName() - { - return _sh.getSheetName(); - } - - /** - * Note - this is not the same as whether the sheet is focused (isActive) - * @return true if this sheet is currently selected - */ - @Override - public boolean isSelected() - { - return _sh.isSelected(); - } - - - /** - * Sets array formula to specified region for result. - * - * @param formula text representation of the formula - * @param range Region of array formula for result. - * @return the {@link CellRange} of cells affected by this change - */ - @Override - public CellRange setArrayFormula(String formula, CellRangeAddress range) - { - return _sh.setArrayFormula(formula, range); - } - - /** - * Remove a Array Formula from this sheet. All cells contained in the Array Formula range are removed as well - * - * @param cell any cell within Array Formula range - * @return the {@link CellRange} of cells affected by this change - */ - @Override - public CellRange removeArrayFormula(Cell cell) - { - return _sh.removeArrayFormula(cell); - } - - @Override - public DataValidationHelper getDataValidationHelper() - { - return _sh.getDataValidationHelper(); - } - - @Override - public List getDataValidations() - { - return _sh.getDataValidations(); - } - - /** - * Creates a data validation object - * @param dataValidation The Data validation object settings - */ - @Override - public void addValidationData(DataValidation dataValidation) - { - _sh.addValidationData(dataValidation); - } - - /** - * Enable filtering for a range of cells - * - * @param range the range of cells to filter - */ - @Override - public AutoFilter setAutoFilter(CellRangeAddress range) - { - return _sh.setAutoFilter(range); - } - - @Override - public SheetConditionalFormatting getSheetConditionalFormatting(){ - return _sh.getSheetConditionalFormatting(); - } - - - @Override - public CellRangeAddress getRepeatingRows() { - return _sh.getRepeatingRows(); - } - - @Override - public CellRangeAddress getRepeatingColumns() { - return _sh.getRepeatingColumns(); - } - - @Override - public void setRepeatingRows(CellRangeAddress rowRangeRef) { - _sh.setRepeatingRows(rowRangeRef); - } - - @Override - public void setRepeatingColumns(CellRangeAddress columnRangeRef) { - _sh.setRepeatingColumns(columnRangeRef); - } - - - -//end of interface implementation - /** - * Specifies how many rows can be accessed at most via getRow(). - * When a new node is created via createRow() and the total number - * of unflushed records would exeed the specified value, then the - * row with the lowest index value is flushed and cannot be accessed - * via getRow() anymore. - * A value of -1 indicates unlimited access. In this case all - * records that have not been flushed by a call to flush() are available - * for random access. - * A value of 0 is not allowed because it would flush any newly created row - * without having a chance to specify any cells. - */ - public void setRandomAccessWindowSize(int value) - { - if(value == 0 || value < -1) { - throw new IllegalArgumentException("RandomAccessWindowSize must be either -1 or a positive integer"); - } - _randomAccessWindowSize=value; - } - - /** - * Are all rows flushed to disk? - */ - public boolean areAllRowsFlushed() { - return allFlushed; - } - /** - * @return Last row number to be flushed to disk, or -1 if none flushed yet - */ - public int getLastFlushedRowNum() { - return lastFlushedRowNumber; - } - - /** - * Specifies how many rows can be accessed at most via getRow(). - * The exeeding rows (if any) are flushed to the disk while rows - * with lower index values are flushed first. - */ - public void flushRows(int remaining) throws IOException - { - while(_rows.size() > remaining) flushOneRow(); - if (remaining == 0) allFlushed = true; - } - - /** - * Flush all rows to disk. After this call no rows can be accessed via getRow() - * - * @throws IOException - */ - public void flushRows() throws IOException - { - this.flushRows(0); - } - - private void flushOneRow() throws IOException - { - Integer firstRowNum = _rows.firstKey(); - if (firstRowNum!=null) { - int rowIndex = firstRowNum.intValue(); - SXSSFRow row = _rows.get(firstRowNum); - // Update the best fit column widths for auto-sizing just before the rows are flushed - _autoSizeColumnTracker.updateColumnWidths(row); - _writer.writeRow(rowIndex, row); - _rows.remove(firstRowNum); - lastFlushedRowNumber = rowIndex; - } - } - public void changeRowNum(SXSSFRow row, int newRowNum) - { - - removeRow(row); - _rows.put(newRowNum,row); - } - - public int getRowNum(SXSSFRow row) - { - for(Iterator> iter=_rows.entrySet().iterator();iter.hasNext();) - { - Map.Entry entry=iter.next(); - if(entry.getValue()==row) - return entry.getKey().intValue(); - } - return -1; - } - - /** - * Deletes the temporary file that backed this sheet on disk. - * @return true if the file was deleted, false if it wasn't. - */ - boolean dispose() throws IOException { - if (!allFlushed) flushRows(); - return _writer.dispose(); - } - - @Override - public int getColumnOutlineLevel(int columnIndex) { - return _sh.getColumnOutlineLevel(columnIndex); - } - - /** - * {@inheritDoc} - */ - @Override - public CellAddress getActiveCell() { - return _sh.getActiveCell(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setActiveCell(CellAddress address) { - _sh.setActiveCell(address); - } - - public XSSFColor getTabColor() { - return _sh.getTabColor(); - } - - public void setTabColor(XSSFColor color) { - _sh.setTabColor(color); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java deleted file mode 100644 index 18a77bf56..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ /dev/null @@ -1,1412 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.util.ZipEntrySource; -import org.apache.poi.openxml4j.util.ZipFileZipEntrySource; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.DataFormat; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.PictureData; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.Internal; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Streaming version of XSSFWorkbook implementing the "BigGridDemo" strategy. - * - * This allows to write very large files without running out of memory as only - * a configurable portion of the rows are kept in memory at any one time. - * - * You can provide a template workbook which is used as basis for the written - * data. - * - * See https://poi.apache.org/spreadsheet/how-to.html#sxssf for details. - * - * Please note that there are still things that still may consume a large - * amount of memory based on which features you are using, e.g. merged regions, - * comments, ... are still only stored in memory and thus may require a lot of - * memory if used extensively. - * - * SXSSFWorkbook defaults to using inline strings instead of a shared strings - * table. This is very efficient, since no document content needs to be kept in - * memory, but is also known to produce documents that are incompatible with - * some clients. With shared strings enabled all unique strings in the document - * has to be kept in memory. Depending on your document content this could use - * a lot more resources than with shared strings disabled. - * - * Carefully review your memory budget and compatibility needs before deciding - * whether to enable shared strings or not. - */ -public class SXSSFWorkbook implements Workbook { - /** - * Specifies how many rows can be accessed at most via {@link SXSSFSheet#getRow}. - * When a new node is created via {@link SXSSFSheet#createRow} and the total number - * of unflushed records would exceed the specified value, then the - * row with the lowest index value is flushed and cannot be accessed - * via {@link SXSSFSheet#getRow} anymore. - */ - public static final int DEFAULT_WINDOW_SIZE = 100; - private static final POILogger logger = POILogFactory.getLogger(SXSSFWorkbook.class); - - private final XSSFWorkbook _wb; - - private final Map _sxFromXHash = new HashMap(); - private final Map _xFromSxHash = new HashMap(); - - private int _randomAccessWindowSize = DEFAULT_WINDOW_SIZE; - - /** - * whether temp files should be compressed. - */ - private boolean _compressTmpFiles = false; - - /** - * shared string table - a cache of strings in this workbook - */ - private final SharedStringsTable _sharedStringSource; - - /** - * Construct a new workbook with default row window size - */ - public SXSSFWorkbook(){ - this(null /*workbook*/); - } - - /** - *

        Construct a workbook from a template.

        - * - * There are three use-cases to use SXSSFWorkbook(XSSFWorkbook) : - *
          - *
        1. - * Append new sheets to existing workbooks. You can open existing - * workbook from a file or create on the fly with XSSF. - *
        2. - *
        3. - * Append rows to existing sheets. The row number MUST be greater - * than {@code max(rownum)} in the template sheet. - *
        4. - *
        5. - * Use existing workbook as a template and re-use global objects such - * as cell styles, formats, images, etc. - *
        6. - *
        - * All three use cases can work in a combination. - * - * What is not supported: - *
          - *
        • - * Access initial cells and rows in the template. After constructing - * {@link #SXSSFWorkbook(XSSFWorkbook)} all internal windows are empty and - * {@link SXSSFSheet#getRow} and {@link SXSSFRow#getCell} return null. - *
        • - *
        • - * Override existing cells and rows. The API silently allows that but - * the output file is invalid and Excel cannot read it. - *
        • - *
        - * - * @param workbook the template workbook - */ - public SXSSFWorkbook(XSSFWorkbook workbook){ - this(workbook, DEFAULT_WINDOW_SIZE); - } - - - /** - * Constructs an workbook from an existing workbook. - *

        - * When a new node is created via {@link SXSSFSheet#createRow} and the total number - * of unflushed records would exceed the specified value, then the - * row with the lowest index value is flushed and cannot be accessed - * via {@link SXSSFSheet#getRow} anymore. - *

        - *

        - * A value of -1 indicates unlimited access. In this case all - * records that have not been flushed by a call to flush() are available - * for random access. - *

        - *

        - * A value of 0 is not allowed because it would flush any newly created row - * without having a chance to specify any cells. - *

        - * - * @param rowAccessWindowSize the number of rows that are kept in memory until flushed out, see above. - */ - public SXSSFWorkbook(XSSFWorkbook workbook, int rowAccessWindowSize){ - this(workbook,rowAccessWindowSize, false); - } - - /** - * Constructs an workbook from an existing workbook. - *

        - * When a new node is created via {@link SXSSFSheet#createRow} and the total number - * of unflushed records would exceed the specified value, then the - * row with the lowest index value is flushed and cannot be accessed - * via {@link SXSSFSheet#getRow} anymore. - *

        - *

        - * A value of -1 indicates unlimited access. In this case all - * records that have not been flushed by a call to flush() are available - * for random access. - *

        - *

        - * A value of 0 is not allowed because it would flush any newly created row - * without having a chance to specify any cells. - *

        - * - * @param rowAccessWindowSize the number of rows that are kept in memory until flushed out, see above. - * @param compressTmpFiles whether to use gzip compression for temporary files - */ - public SXSSFWorkbook(XSSFWorkbook workbook, int rowAccessWindowSize, boolean compressTmpFiles){ - this(workbook,rowAccessWindowSize, compressTmpFiles, false); - } - - /** - * Constructs an workbook from an existing workbook. - *

        - * When a new node is created via {@link SXSSFSheet#createRow} and the total number - * of unflushed records would exceed the specified value, then the - * row with the lowest index value is flushed and cannot be accessed - * via {@link SXSSFSheet#getRow} anymore. - *

        - *

        - * A value of -1 indicates unlimited access. In this case all - * records that have not been flushed by a call to flush() are available - * for random access. - *

        - *

        - * A value of 0 is not allowed because it would flush any newly created row - * without having a chance to specify any cells. - *

        - * - * @param workbook the template workbook - * @param rowAccessWindowSize the number of rows that are kept in memory until flushed out, see above. - * @param compressTmpFiles whether to use gzip compression for temporary files - * @param useSharedStringsTable whether to use a shared strings table - */ - public SXSSFWorkbook(XSSFWorkbook workbook, int rowAccessWindowSize, boolean compressTmpFiles, boolean useSharedStringsTable){ - setRandomAccessWindowSize(rowAccessWindowSize); - setCompressTempFiles(compressTmpFiles); - if (workbook == null) - { - _wb=new XSSFWorkbook(); - _sharedStringSource = useSharedStringsTable ? _wb.getSharedStringSource() : null; - } - else - { - _wb=workbook; - _sharedStringSource = useSharedStringsTable ? _wb.getSharedStringSource() : null; - final int numberOfSheets = _wb.getNumberOfSheets(); - for ( int i = 0; i < numberOfSheets; i++ ) - { - XSSFSheet sheet = _wb.getSheetAt( i ); - createAndRegisterSXSSFSheet( sheet ); - } - } - } - /** - * Construct an empty workbook and specify the window for row access. - *

        - * When a new node is created via {@link SXSSFSheet#createRow} and the total number - * of unflushed records would exceed the specified value, then the - * row with the lowest index value is flushed and cannot be accessed - * via {@link SXSSFSheet#getRow} anymore. - *

        - *

        - * A value of -1 indicates unlimited access. In this case all - * records that have not been flushed by a call to flush() are available - * for random access. - *

        - *

        - * A value of 0 is not allowed because it would flush any newly created row - * without having a chance to specify any cells. - *

        - * - * @param rowAccessWindowSize the number of rows that are kept in memory until flushed out, see above. - */ - public SXSSFWorkbook(int rowAccessWindowSize){ - this(null /*workbook*/, rowAccessWindowSize); - } - - /** - * See the constructors for a more detailed description of the sliding window of rows. - * - * @return The number of rows that are kept in memory at once before flushing them out. - */ - public int getRandomAccessWindowSize() { - return _randomAccessWindowSize; - } - - private void setRandomAccessWindowSize(int rowAccessWindowSize) { - if(rowAccessWindowSize == 0 || rowAccessWindowSize < -1) { - throw new IllegalArgumentException("rowAccessWindowSize must be greater than 0 or -1"); - } - _randomAccessWindowSize = rowAccessWindowSize; - } - - /** - * Get whether temp files should be compressed. - * - * @return whether to compress temp files - */ - public boolean isCompressTempFiles() { - return _compressTmpFiles; - } - /** - * Set whether temp files should be compressed. - *

        - * SXSSF writes sheet data in temporary files (a temp file per-sheet) - * and the size of these temp files can grow to to a very large size, - * e.g. for a 20 MB csv data the size of the temp xml file become few GB large. - * If the "compress" flag is set to true then the temporary XML is gzipped. - *

        - *

        - * Please note the the "compress" option may cause performance penalty. - *

        - * @param compress whether to compress temp files - */ - public void setCompressTempFiles(boolean compress) { - _compressTmpFiles = compress; - } - - @Internal - protected SharedStringsTable getSharedStringSource() { - return _sharedStringSource; - } - - protected SheetDataWriter createSheetDataWriter() throws IOException { - if(_compressTmpFiles) { - return new GZIPSheetDataWriter(_sharedStringSource); - } - - return new SheetDataWriter(_sharedStringSource); - } - - XSSFSheet getXSSFSheet(SXSSFSheet sheet) - { - return _sxFromXHash.get(sheet); - } - - SXSSFSheet getSXSSFSheet(XSSFSheet sheet) - { - return _xFromSxHash.get(sheet); - } - - void registerSheetMapping(SXSSFSheet sxSheet,XSSFSheet xSheet) - { - _sxFromXHash.put(sxSheet,xSheet); - _xFromSxHash.put(xSheet,sxSheet); - } - - void deregisterSheetMapping(XSSFSheet xSheet) - { - SXSSFSheet sxSheet=getSXSSFSheet(xSheet); - - // ensure that the writer is closed in all cases to not have lingering writers - try { - sxSheet.getSheetDataWriter().close(); - } catch (IOException e) { - // ignore exception here - } - - _sxFromXHash.remove(sxSheet); - - _xFromSxHash.remove(xSheet); - } - - private XSSFSheet getSheetFromZipEntryName(String sheetRef) - { - for(XSSFSheet sheet : _sxFromXHash.values()) - { - if(sheetRef.equals(sheet.getPackagePart().getPartName().getName().substring(1))) return sheet; - } - return null; - } - - protected void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException - { - try - { - ZipOutputStream zos = new ZipOutputStream(out); - try - { - Enumeration en = zipEntrySource.getEntries(); - while (en.hasMoreElements()) - { - ZipEntry ze = en.nextElement(); - zos.putNextEntry(new ZipEntry(ze.getName())); - InputStream is = zipEntrySource.getInputStream(ze); - XSSFSheet xSheet=getSheetFromZipEntryName(ze.getName()); - if(xSheet!=null) - { - SXSSFSheet sxSheet=getSXSSFSheet(xSheet); - InputStream xis = sxSheet.getWorksheetXMLInputStream(); - try - { - copyStreamAndInjectWorksheet(is,zos,xis); - } - finally - { - xis.close(); - } - } - else - { - copyStream(is, zos); - } - is.close(); - } - } - finally - { - zos.close(); - } - } - finally - { - zipEntrySource.close(); - } - } - private static void copyStream(InputStream in, OutputStream out) throws IOException { - byte[] chunk = new byte[1024]; - int count; - while ((count = in.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - } - private static void copyStreamAndInjectWorksheet(InputStream in, OutputStream out, InputStream worksheetData) throws IOException { - InputStreamReader inReader=new InputStreamReader(in,"UTF-8"); //TODO: Is it always UTF-8 or do we need to read the xml encoding declaration in the file? If not, we should perhaps use a SAX reader instead. - OutputStreamWriter outWriter=new OutputStreamWriter(out,"UTF-8"); - boolean needsStartTag = true; - int c; - int pos=0; - String s="" or "
        " (excluding). - while(((c=inReader.read())!=-1)) - { - if(c==s.charAt(pos)) - { - pos++; - if(pos==n) - { - if ("') - { - // Found - outWriter.write(s); - outWriter.write(c); - s = ""; - n = s.length(); - pos = 0; - needsStartTag = false; - continue; - } - if (c == '/') - { - // Found ') - { - // Found - break; - } - - outWriter.write(s); - outWriter.write('/'); - outWriter.write(c); - pos = 0; - continue; - } - - outWriter.write(s); - outWriter.write('/'); - outWriter.write(c); - pos = 0; - continue; - } - else - { - // Found - break; - } - } - } - else - { - if(pos>0) outWriter.write(s,0,pos); - if(c==s.charAt(0)) - { - pos=1; - } - else - { - outWriter.write(c); - pos=0; - } - } - } - outWriter.flush(); - if (needsStartTag) - { - outWriter.write("\n"); - outWriter.flush(); - } -//Copy the worksheet data to "out". - copyStream(worksheetData,out); - outWriter.write(""); - outWriter.flush(); -//Copy the rest of "in" to "out". - while(((c=inReader.read())!=-1)) - outWriter.write(c); - outWriter.flush(); - } - - public XSSFWorkbook getXSSFWorkbook() - { - return _wb; - } - -//start of interface implementation - - /** - * Convenience method to get the active sheet. The active sheet is is the sheet - * which is currently displayed when the workbook is viewed in Excel. - * 'Selected' sheet(s) is a distinct concept. - * - * @return the index of the active sheet (0-based) - */ - @Override - public int getActiveSheetIndex() - { - return _wb.getActiveSheetIndex(); - } - - /** - * Convenience method to set the active sheet. The active sheet is is the sheet - * which is currently displayed when the workbook is viewed in Excel. - * 'Selected' sheet(s) is a distinct concept. - * - * @param sheetIndex index of the active sheet (0-based) - */ - @Override - public void setActiveSheet(int sheetIndex) - { - _wb.setActiveSheet(sheetIndex); - } - - /** - * Gets the first tab that is displayed in the list of tabs in excel. - * - * @return the first tab that to display in the list of tabs (0-based). - */ - @Override - public int getFirstVisibleTab() - { - return _wb.getFirstVisibleTab(); - } - - /** - * Sets the first tab that is displayed in the list of tabs in excel. - * - * @param sheetIndex the first tab that to display in the list of tabs (0-based) - */ - @Override - public void setFirstVisibleTab(int sheetIndex) - { - _wb.setFirstVisibleTab(sheetIndex); - } - - /** - * Sets the order of appearance for a given sheet. - * - * @param sheetname the name of the sheet to reorder - * @param pos the position that we want to insert the sheet into (0 based) - */ - @Override - public void setSheetOrder(String sheetname, int pos) - { - _wb.setSheetOrder(sheetname,pos); - } - - /** - * Sets the tab whose data is actually seen when the sheet is opened. - * This may be different from the "selected sheet" since excel seems to - * allow you to show the data of one sheet when another is seen "selected" - * in the tabs (at the bottom). - * - * @see Sheet#setSelected(boolean) - * @param index the index of the sheet to select (0 based) - */ - @Override - public void setSelectedTab(int index) - { - _wb.setSelectedTab(index); - } - - /** - * Set the sheet name. - * - * @param sheet number (0 based) - * @throws IllegalArgumentException if the name is greater than 31 chars or contains /\?*[] - */ - @Override - public void setSheetName(int sheet, String name) - { - _wb.setSheetName(sheet,name); - } - - /** - * Set the sheet name - * - * @param sheet sheet number (0 based) - * @return Sheet name - */ - @Override - public String getSheetName(int sheet) - { - return _wb.getSheetName(sheet); - } - - /** - * Returns the index of the sheet by his name - * - * @param name the sheet name - * @return index of the sheet (0 based) - */ - @Override - public int getSheetIndex(String name) - { - return _wb.getSheetIndex(name); - } - - /** - * Returns the index of the given sheet - * - * @param sheet the sheet to look up - * @return index of the sheet (0 based) - */ - @Override - public int getSheetIndex(Sheet sheet) - { - return _wb.getSheetIndex(getXSSFSheet((SXSSFSheet)sheet)); - } - - /** - * Sreate an Sheet for this Workbook, adds it to the sheets and returns - * the high level representation. Use this to create new sheets. - * - * @return Sheet representing the new sheet. - */ - @Override - public SXSSFSheet createSheet() - { - return createAndRegisterSXSSFSheet(_wb.createSheet()); - } - - SXSSFSheet createAndRegisterSXSSFSheet(XSSFSheet xSheet) - { - final SXSSFSheet sxSheet; - try - { - sxSheet=new SXSSFSheet(this,xSheet); - } - catch (IOException ioe) - { - throw new RuntimeException(ioe); - } - registerSheetMapping(sxSheet,xSheet); - return sxSheet; - } - - /** - * Create an Sheet for this Workbook, adds it to the sheets and returns - * the high level representation. Use this to create new sheets. - * - * @param sheetname sheetname to set for the sheet. - * @return Sheet representing the new sheet. - * @throws IllegalArgumentException if the name is greater than 31 chars or contains /\?*[] - */ - @Override - public SXSSFSheet createSheet(String sheetname) - { - return createAndRegisterSXSSFSheet(_wb.createSheet(sheetname)); - } - - /** - * Not implemented for SXSSFWorkbook - * - * Create an Sheet from an existing sheet in the Workbook. - * - * @return Sheet representing the cloned sheet. - */ - @Override - @NotImplemented - public Sheet cloneSheet(int sheetNum) - { - throw new RuntimeException("NotImplemented"); - } - - - /** - * Get the number of spreadsheets in the workbook - * - * @return the number of sheets - */ - @Override - public int getNumberOfSheets() - { - return _wb.getNumberOfSheets(); - } - - /** - * Returns an iterator of the sheets in the workbook - * in sheet order. Includes hidden and very hidden sheets. - * - * @return an iterator of the sheets. - */ - @Override - public Iterator sheetIterator() { - return new SheetIterator(); - } - - private final class SheetIterator implements Iterator { - final private Iterator it; - @SuppressWarnings("unchecked") - public SheetIterator() { - it = (Iterator)(Iterator) _wb.iterator(); - } - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - @SuppressWarnings("unchecked") - public T next() throws NoSuchElementException { - final XSSFSheet xssfSheet = it.next(); - return (T) getSXSSFSheet(xssfSheet); - } - /** - * Unexpected behavior may occur if sheets are reordered after iterator - * has been created. Support for the remove method may be added in the future - * if someone can figure out a reliable implementation. - */ - @Override - public void remove() throws IllegalStateException { - throw new UnsupportedOperationException("remove method not supported on XSSFWorkbook.iterator(). "+ - "Use Sheet.removeSheetAt(int) instead."); - } - } - - /** - * Alias for {@link #sheetIterator()} to allow - * foreach loops - */ - @Override - public Iterator iterator() { - return sheetIterator(); - } - - /** - * Get the Sheet object at the given index. - * - * @param index of the sheet number (0-based physical and logical) - * @return Sheet at the provided index - */ - @Override - public SXSSFSheet getSheetAt(int index) - { - return getSXSSFSheet(_wb.getSheetAt(index)); - } - - /** - * Get sheet with the given name - * - * @param name of the sheet - * @return Sheet with the name provided or null if it does not exist - */ - @Override - public SXSSFSheet getSheet(String name) - { - return getSXSSFSheet(_wb.getSheet(name)); - } - - /** - * Removes sheet at the given index - * - * @param index of the sheet to remove (0-based) - */ - @Override - public void removeSheetAt(int index) - { - // Get the sheet to be removed - XSSFSheet xSheet = _wb.getSheetAt(index); - SXSSFSheet sxSheet = getSXSSFSheet(xSheet); - - // De-register it - _wb.removeSheetAt(index); - deregisterSheetMapping(xSheet); - - // Clean up temporary resources - try { - sxSheet.dispose(); - } catch (IOException e) { - logger.log(POILogger.WARN, e); - } - } - - /** - * Create a new Font and add it to the workbook's font table - * - * @return new font object - */ - @Override - public Font createFont() - { - return _wb.createFont(); - } - - /** - * Finds a font that matches the one with the supplied attributes - * - * @return the font with the matched attributes or null - * @deprecated POI 3.15 beta 2. Use {@link #findFont(boolean, short, short, String, boolean, boolean, short, byte)} instead. - */ - @Override - public Font findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) - { - return _wb.findFont(boldWeight, color, fontHeight, name, italic, strikeout, typeOffset, underline); - } - - /** - * Finds a font that matches the one with the supplied attributes - * - * @return the font with the matched attributes or null - */ - @Override - public Font findFont(boolean bold, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) - { - return _wb.findFont(bold, color, fontHeight, name, italic, strikeout, typeOffset, underline); - } - - - /** - * Get the number of fonts in the font table - * - * @return number of fonts - */ - @Override - public short getNumberOfFonts() - { - return _wb.getNumberOfFonts(); - } - - /** - * Get the font at the given index number - * - * @param idx index number (0-based) - * @return font at the index - */ - @Override - public Font getFontAt(short idx) - { - return _wb.getFontAt(idx); - } - - /** - * Create a new Cell style and add it to the workbook's style table - * - * @return the new Cell Style object - */ - @Override - public CellStyle createCellStyle() - { - return _wb.createCellStyle(); - } - - /** - * Get the number of styles the workbook contains - * - * @return count of cell styles - */ - @Override - public int getNumCellStyles() - { - return _wb.getNumCellStyles(); - } - - /** - * Get the cell style object at the given index - * - * @param idx index within the set of styles (0-based) - * @return CellStyle object at the index - */ - @Override - public CellStyle getCellStyleAt(int idx) - { - return _wb.getCellStyleAt(idx); - } - - /** - * Closes the underlying {@link XSSFWorkbook} and {@link OPCPackage} - * on which this Workbook is based, if any. - * - *

        Once this has been called, no further - * operations, updates or reads should be performed on the - * Workbook. - */ - @Override - public void close() throws IOException { - // ensure that any lingering writer is closed - for (SXSSFSheet sheet : _xFromSxHash.values()) - { - try { - sheet.getSheetDataWriter().close(); - } catch (IOException e) { - logger.log(POILogger.WARN, - "An exception occurred while closing sheet data writer for sheet " - + sheet.getSheetName() + ".", e); - } - } - - - // Tell the base workbook to close, does nothing if - // it's a newly created one - _wb.close(); - } - - /** - * Write out this workbook to an Outputstream. - * - * @param stream - the java OutputStream you wish to write to - * @exception IOException if anything can't be written. - */ - @Override - public void write(OutputStream stream) throws IOException - { - flushSheets(); - - //Save the template - File tmplFile = TempFile.createTempFile("poi-sxssf-template", ".xlsx"); - try - { - FileOutputStream os = new FileOutputStream(tmplFile); - try - { - _wb.write(os); - } - finally - { - os.close(); - } - - //Substitute the template entries with the generated sheet data files - final ZipEntrySource source = new ZipFileZipEntrySource(new ZipFile(tmplFile)); - injectData(source, stream); - } - finally - { - if(!tmplFile.delete()) { - throw new IOException("Could not delete temporary file after processing: " + tmplFile); - } - } - } - - protected void flushSheets() throws IOException { - for (SXSSFSheet sheet : _xFromSxHash.values()) - { - sheet.flushRows(); - } - } - - /** - * Dispose of temporary files backing this workbook on disk. - * Calling this method will render the workbook unusable. - * @return true if all temporary files were deleted successfully. - */ - public boolean dispose() - { - boolean success = true; - for (SXSSFSheet sheet : _sxFromXHash.keySet()) - { - try { - success = sheet.dispose() && success; - } catch (IOException e) { - logger.log(POILogger.WARN, e); - success = false; - } - } - return success; - } - - /** - * @return the total number of defined names in this workbook - */ - @Override - public int getNumberOfNames() - { - return _wb.getNumberOfNames(); - } - - /** - * @param name the name of the defined name - * @return the defined name with the specified name. null if not found. - */ - @Override - public Name getName(String name) - { - return _wb.getName(name); - } - - /** - * Returns all defined names with the given name. - * - * @param name the name of the defined name - * @return a list of the defined names with the specified name. An empty list is returned if none is found. - */ - @Override - public List getNames(String name) { - return _wb.getNames(name); - } - - /** - * Returns all defined names - * - * @return all defined names - */ - @Override - public List getAllNames() - { - return _wb.getAllNames(); - } - - /** - * @param nameIndex position of the named range (0-based) - * @return the defined name at the specified index - * @throws IllegalArgumentException if the supplied index is invalid - * @deprecated 3.16. New projects should avoid accessing named ranges by index. - */ - @Override - @Deprecated - public Name getNameAt(int nameIndex) - { - return _wb.getNameAt(nameIndex); - } - - /** - * Creates a new (uninitialised) defined name in this workbook - * - * @return new defined name object - */ - @Override - public Name createName() - { - return _wb.createName(); - } - - /** - * Gets the defined name index by name - * - * Note: Excel defined names are case-insensitive and - * this method performs a case-insensitive search. - * - * @param name the name of the defined name - * @return zero based index of the defined name. -1 if not found. - * - * @deprecated 3.16. New projects should avoid accessing named ranges by index. - * Use {@link #getName(String)} instead. - */ - @Override - @Deprecated - public int getNameIndex(String name) - { - return _wb.getNameIndex(name); - } - - /** - * Remove the defined name at the specified index - * - * @param index named range index (0 based) - * - * @deprecated 3.16. New projects should use {@link #removeName(Name)}. - */ - @Override - @Deprecated - public void removeName(int index) - { - _wb.removeName(index); - } - - /** - * Remove a defined name by name - * - * @param name the name of the defined name - * - * @deprecated 3.16. New projects should use {@link #removeName(Name)}. - */ - @Override - @Deprecated - public void removeName(String name) - { - _wb.removeName(name); - } - - /** - * Remove the given defined name - * - * @param name the name to remove - */ - @Override - public void removeName(Name name) - { - _wb.removeName(name); - } - - /** - * Sets the printarea for the sheet provided - *

        - * i.e. Reference = $A$1:$B$2 - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @param reference Valid name Reference for the Print Area - */ - @Override - public void setPrintArea(int sheetIndex, String reference) - { - _wb.setPrintArea(sheetIndex,reference); - } - - /** - * For the Convenience of Java Programmers maintaining pointers. - * @see #setPrintArea(int, String) - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - * @param startColumn Column to begin printarea - * @param endColumn Column to end the printarea - * @param startRow Row to begin the printarea - * @param endRow Row to end the printarea - */ - @Override - public void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) - { - _wb.setPrintArea(sheetIndex, startColumn, endColumn, startRow, endRow); - } - - /** - * Retrieves the reference for the printarea of the specified sheet, - * the sheet name is appended to the reference even if it was not specified. - * - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @return String Null if no print area has been defined - */ - @Override - public String getPrintArea(int sheetIndex) - { - return _wb.getPrintArea(sheetIndex); - } - - /** - * Delete the printarea for the sheet specified - * - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - */ - @Override - public void removePrintArea(int sheetIndex) - { - _wb.removePrintArea(sheetIndex); - } - - /** - * Retrieves the current policy on what to do when - * getting missing or blank cells from a row. - *

        - * The default is to return blank and null cells. - * {@link MissingCellPolicy} - *

        - */ - @Override - public MissingCellPolicy getMissingCellPolicy() - { - return _wb.getMissingCellPolicy(); - } - - /** - * Sets the policy on what to do when - * getting missing or blank cells from a row. - * - * This will then apply to all calls to - * {@link org.apache.poi.ss.usermodel.Row#getCell(int)}. See - * {@link MissingCellPolicy} - */ - @Override - public void setMissingCellPolicy(MissingCellPolicy missingCellPolicy) - { - _wb.setMissingCellPolicy(missingCellPolicy); - } - - /** - * Returns the instance of DataFormat for this workbook. - * - * @return the DataFormat object - */ - @Override - public DataFormat createDataFormat() - { - return _wb.createDataFormat(); - } - - /** - * Adds a picture to the workbook. - * - * @param pictureData The bytes of the picture - * @param format The format of the picture. - * - * @return the index to this picture (1 based). - * @see #PICTURE_TYPE_EMF - * @see #PICTURE_TYPE_WMF - * @see #PICTURE_TYPE_PICT - * @see #PICTURE_TYPE_JPEG - * @see #PICTURE_TYPE_PNG - * @see #PICTURE_TYPE_DIB - */ - @Override - public int addPicture(byte[] pictureData, int format) - { - return _wb.addPicture(pictureData,format); - } - - /** - * Gets all pictures from the Workbook. - * - * @return the list of pictures (a list of {@link PictureData} objects.) - */ - @Override - public List getAllPictures() - { - return _wb.getAllPictures(); - } - - /** - * Returns an object that handles instantiating concrete - * classes of the various instances one needs for HSSF, XSSF - * and SXSSF. - */ - @Override - public CreationHelper getCreationHelper() { - return new SXSSFCreationHelper(this); - } - - protected boolean isDate1904() { - return _wb.isDate1904(); - } - - /** - * @return false if this workbook is not visible in the GUI - */ - @Override - public boolean isHidden() - { - return _wb.isHidden(); - } - - /** - * @param hiddenFlag pass false to make the workbook visible in the GUI - */ - @Override - public void setHidden(boolean hiddenFlag) - { - _wb.setHidden(hiddenFlag); - } - - /** - * Check whether a sheet is hidden. - *

        - * Note that a sheet could instead be set to be very hidden, which is different - * ({@link #isSheetVeryHidden(int)}) - *

        - * @param sheetIx Number - * @return true if sheet is hidden - */ - @Override - public boolean isSheetHidden(int sheetIx) - { - return _wb.isSheetHidden(sheetIx); - } - - /** - * Check whether a sheet is very hidden. - *

        - * This is different from the normal hidden status - * ({@link #isSheetHidden(int)}) - *

        - * @param sheetIx sheet index to check - * @return true if sheet is very hidden - */ - @Override - public boolean isSheetVeryHidden(int sheetIx) - { - return _wb.isSheetVeryHidden(sheetIx); - } - - /** - * Hide or unhide a sheet - * - * Please note that the sheet currently set as active sheet (sheet 0 in a newly - * created workbook or the one set via setActiveSheet()) cannot be hidden. - * - * @param sheetIx the sheet index (0-based) - * @param hidden True to mark the sheet as hidden, false otherwise - */ - @Override - public void setSheetHidden(int sheetIx, boolean hidden) - { - _wb.setSheetHidden(sheetIx,hidden); - } - - /** - * Hide or unhide a sheet. - * - *
          - *
        • 0 - visible.
        • - *
        • 1 - hidden.
        • - *
        • 2 - very hidden.
        • - *
        - * - * Please note that the sheet currently set as active sheet (sheet 0 in a newly - * created workbook or the one set via setActiveSheet()) cannot be hidden. - * - * @param sheetIx the sheet index (0-based) - * @param hidden one of the following Workbook constants: - * Workbook.SHEET_STATE_VISIBLE, - * Workbook.SHEET_STATE_HIDDEN, or - * Workbook.SHEET_STATE_VERY_HIDDEN. - * @throws IllegalArgumentException if the supplied sheet index or state is invalid - */ - @Override - public void setSheetHidden(int sheetIx, int hidden) - { - _wb.setSheetHidden(sheetIx,hidden); - } - - /** - * Not implemented for SXSSFWorkbook - * - * Adds the LinkTable records required to allow formulas referencing - * the specified external workbook to be added to this one. Allows - * formulas such as "[MyOtherWorkbook]Sheet3!$A$5" to be added to the - * file, for workbooks not already referenced. - * - * @param name The name the workbook will be referenced as in formulas - * @param workbook The open workbook to fetch the link required information from - */ - @Override - @NotImplemented - public int linkExternalWorkbook(String name, Workbook workbook) { - throw new RuntimeException("NotImplemented"); - } - - /** - * Register a new toolpack in this workbook. - * - * @param toopack the toolpack to register - */ - @Override - public void addToolPack(UDFFinder toopack) - { - _wb.addToolPack(toopack); - } - - /** - * Whether the application shall perform a full recalculation when the workbook is opened. - *

        - * Typically you want to force formula recalculation when you modify cell formulas or values - * of a workbook previously created by Excel. When set to 0, this flag will tell Excel - * that it needs to recalculate all formulas in the workbook the next time the file is opened. - *

        - * - * @param value true if the application will perform a full recalculation of - * workbook values when the workbook is opened - * @since 3.8 - */ - @Override - public void setForceFormulaRecalculation(boolean value){ - _wb.setForceFormulaRecalculation(value); - } - - /** - * Whether Excel will be asked to recalculate all formulas when the workbook is opened. - */ - @Override - public boolean getForceFormulaRecalculation(){ - return _wb.getForceFormulaRecalculation(); - } - - /** - * Returns the spreadsheet version (EXCLE2007) of this workbook - * - * @return EXCEL2007 SpreadsheetVersion enum - * @since 3.14 beta 2 - */ - @Override - public SpreadsheetVersion getSpreadsheetVersion() { - return SpreadsheetVersion.EXCEL2007; - } - -//end of interface implementation -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java deleted file mode 100644 index 9820ddd0f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Iterator; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; - -/** - * Initially copied from BigGridDemo "SpreadsheetWriter". - * Unlike the original code which wrote the entire document, - * this class only writes the "sheetData" document fragment - * so that it was renamed to "SheetDataWriter" - */ -public class SheetDataWriter { - private static final POILogger logger = POILogFactory.getLogger(SheetDataWriter.class); - - private final File _fd; - private final Writer _out; - private int _rownum; - private int _numberOfFlushedRows; - private int _lowestIndexOfFlushedRows; // meaningful only of _numberOfFlushedRows>0 - private int _numberOfCellsOfLastFlushedRow; // meaningful only of _numberOfFlushedRows>0 - private int _numberLastFlushedRow = -1; // meaningful only of _numberOfFlushedRows>0 - - /** - * Table of strings shared across this workbook. - * If two cells contain the same string, then the cell value is the same index into SharedStringsTable - */ - private SharedStringsTable _sharedStringSource; - - public SheetDataWriter() throws IOException { - _fd = createTempFile(); - _out = createWriter(_fd); - } - - public SheetDataWriter(SharedStringsTable sharedStringsTable) throws IOException { - this(); - this._sharedStringSource = sharedStringsTable; - } - /** - * Create a temp file to write sheet data. - * By default, temp files are created in the default temporary-file directory - * with a prefix "poi-sxssf-sheet" and suffix ".xml". Subclasses can override - * it and specify a different temp directory or filename or suffix, e.g. .gz - * - * @return temp file to write sheet data - */ - public File createTempFile() throws IOException { - return TempFile.createTempFile("poi-sxssf-sheet", ".xml"); - } - - /** - * Create a writer for the sheet data. - * - * @param fd the file to write to - */ - public Writer createWriter(File fd) throws IOException { - FileOutputStream fos = new FileOutputStream(fd); - OutputStream decorated; - try { - decorated = decorateOutputStream(fos); - } catch (final IOException e) { - fos.close(); - throw e; - } - return new BufferedWriter( - new OutputStreamWriter(decorated, "UTF-8")); - } - - /** - * Override this to translate (such as encrypt or compress) the file output stream - * as it is being written to disk. - * The default behavior is to to pass the stream through unmodified. - * - * @param fos the stream to decorate - * @return a decorated stream - * @throws IOException - * @see #decorateInputStream(FileInputStream) - */ - protected OutputStream decorateOutputStream(FileOutputStream fos) throws IOException { - return fos; - } - - /** - * flush and close the temp data writer. - * This method must be invoked before calling {@link #getWorksheetXMLInputStream()} - */ - public void close() throws IOException{ - _out.flush(); - _out.close(); - } - - protected File getTempFile(){ - return _fd; - } - - /** - * @return a stream to read temp file with the sheet data - */ - public InputStream getWorksheetXMLInputStream() throws IOException { - File fd = getTempFile(); - FileInputStream fis = new FileInputStream(fd); - try { - return decorateInputStream(fis); - } catch (IOException e) { - fis.close(); - throw e; - } - } - - /** - * Override this to translate (such as decrypt or expand) the file input stream - * as it is being read from disk. - * The default behavior is to to pass the stream through unmodified. - * - * @param fis the stream to decorate - * @return a decorated stream - * @throws IOException - * @see #decorateOutputStream(FileOutputStream) - */ - protected InputStream decorateInputStream(FileInputStream fis) throws IOException { - return fis; - } - - public int getNumberOfFlushedRows() { - return _numberOfFlushedRows; - } - - public int getNumberOfCellsOfLastFlushedRow() { - return _numberOfCellsOfLastFlushedRow; - } - - public int getLowestIndexOfFlushedRows() { - return _lowestIndexOfFlushedRows; - } - - public int getLastFlushedRow() { - return _numberLastFlushedRow; - } - - @Override - protected void finalize() throws Throwable { - if (!_fd.delete()) { - logger.log(POILogger.ERROR, "Can't delete temporary encryption file: "+_fd); - } - - super.finalize(); - } - - /** - * Write a row to the file - * - * @param rownum 0-based row number - * @param row a row - */ - public void writeRow(int rownum, SXSSFRow row) throws IOException { - if (_numberOfFlushedRows == 0) - _lowestIndexOfFlushedRows = rownum; - _numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow); - _numberOfCellsOfLastFlushedRow = row.getLastCellNum(); - _numberOfFlushedRows++; - beginRow(rownum, row); - Iterator cells = row.allCellsIterator(); - int columnIndex = 0; - while (cells.hasNext()) { - writeCell(columnIndex++, cells.next()); - } - endRow(); - } - - void beginRow(int rownum, SXSSFRow row) throws IOException { - _out.write("\n"); - } - - public void writeCell(int columnIndex, Cell cell) throws IOException { - if (cell == null) { - return; - } - String ref = new CellReference(_rownum, columnIndex).formatAsString(); - _out.write(""); - break; - } - case FORMULA: { - _out.write(">"); - _out.write(""); - outputQuotedString(cell.getCellFormula()); - _out.write(""); - switch (cell.getCachedFormulaResultTypeEnum()) { - case NUMERIC: - double nval = cell.getNumericCellValue(); - if (!Double.isNaN(nval)) { - _out.write("" + nval + ""); - } - break; - default: - break; - } - break; - } - case STRING: { - if (_sharedStringSource != null) { - XSSFRichTextString rt = new XSSFRichTextString(cell.getStringCellValue()); - int sRef = _sharedStringSource.addEntry(rt.getCTRst()); - - _out.write(" t=\"" + STCellType.S.toString() + "\">"); - _out.write(""); - _out.write(String.valueOf(sRef)); - _out.write(""); - } else { - _out.write(" t=\"inlineStr\">"); - _out.write(""); - outputQuotedString(cell.getStringCellValue()); - _out.write("
        "); - } - break; - } - case NUMERIC: { - _out.write(" t=\"n\">"); - _out.write("" + cell.getNumericCellValue() + ""); - break; - } - case BOOLEAN: { - _out.write(" t=\"b\">"); - _out.write("" + (cell.getBooleanCellValue() ? "1" : "0") + ""); - break; - } - case ERROR: { - FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); - - _out.write(" t=\"e\">"); - _out.write("" + error.getString() + ""); - break; - } - default: { - throw new IllegalStateException("Invalid cell type: " + cellType); - } - } - _out.write(""); - } - - - /** - * @return whether the string has leading / trailing spaces that - * need to be preserved with the xml:space=\"preserve\" attribute - */ - boolean hasLeadingTrailingSpaces(String str) { - if (str != null && str.length() > 0) { - char firstChar = str.charAt(0); - char lastChar = str.charAt(str.length() - 1); - return Character.isWhitespace(firstChar) || Character.isWhitespace(lastChar) ; - } - return false; - } - - //Taken from jdk1.3/src/javax/swing/text/html/HTMLWriter.java - protected void outputQuotedString(String s) throws IOException { - if (s == null || s.length() == 0) { - return; - } - - char[] chars = s.toCharArray(); - int last = 0; - int length = s.length(); - for (int counter = 0; counter < length; counter++) { - char c = chars[counter]; - switch (c) { - case '<': - if (counter > last) { - _out.write(chars, last, counter - last); - } - last = counter + 1; - _out.write("<"); - break; - case '>': - if (counter > last) { - _out.write(chars, last, counter - last); - } - last = counter + 1; - _out.write(">"); - break; - case '&': - if (counter > last) { - _out.write(chars, last, counter - last); - } - last = counter + 1; - _out.write("&"); - break; - case '"': - if (counter > last) { - _out.write(chars, last, counter - last); - } - last = counter + 1; - _out.write("""); - break; - // Special characters - case '\n': - case '\r': - if (counter > last) { - _out.write(chars, last, counter - last); - } - _out.write(" "); - last = counter + 1; - break; - case '\t': - if (counter > last) { - _out.write(chars, last, counter - last); - } - _out.write(" "); - last = counter + 1; - break; - case 0xa0: - if (counter > last) { - _out.write(chars, last, counter - last); - } - _out.write(" "); - last = counter + 1; - break; - default: - // YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks. - // the same rule applies to unicode surrogates and "not a character" symbols. - if( c < ' ' || Character.isLowSurrogate(c) || Character.isHighSurrogate(c) || - ('\uFFFE' <= c && c <= '\uFFFF')) { - if (counter > last) { - _out.write(chars, last, counter - last); - } - _out.write('?'); - last = counter + 1; - } - else if (c > 127) { - if (counter > last) { - _out.write(chars, last, counter - last); - } - last = counter + 1; - // If the character is outside of ascii, write the - // numeric value. - _out.write("&#"); - _out.write(String.valueOf((int) c)); - _out.write(";"); - } - break; - } - } - if (last < length) { - _out.write(chars, last, length - last); - } - } - - /** - * Deletes the temporary file that backed this sheet on disk. - * @return true if the file was deleted, false if it wasn't. - */ - boolean dispose() throws IOException { - final boolean ret; - try { - _out.close(); - } finally { - ret = _fd.delete(); - } - return ret; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java deleted file mode 100644 index 9c5e6ffb1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java +++ /dev/null @@ -1,449 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.EvaluationName; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaParsingWorkbook; -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.SheetIdentifier; -import org.apache.poi.ss.formula.functions.FreeRefFunction; -import org.apache.poi.ss.formula.ptg.Area3DPxg; -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.NameXPtg; -import org.apache.poi.ss.formula.ptg.NameXPxg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPxg; -import org.apache.poi.ss.formula.udf.IndexedUDFFinder; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.Internal; -import org.apache.poi.xssf.model.ExternalLinksTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; - -/** - * Internal POI use only - parent of XSSF and SXSSF evaluation workbooks - */ -@Internal -public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook { - protected final XSSFWorkbook _uBook; - - // lazily populated. This should only be accessed through getTableCache - // keys are lower-case to make this a quasi-case-insensitive map - private Map _tableCache = null; - - - protected BaseXSSFEvaluationWorkbook(XSSFWorkbook book) { - _uBook = book; - } - - /* (non-JavaDoc), inherit JavaDoc from EvaluationWorkbook - * @since POI 3.15 beta 3 - */ - @Override - public void clearAllCachedResultValues() { - _tableCache = null; - } - - private int convertFromExternalSheetIndex(int externSheetIndex) { - return externSheetIndex; - } - /** - * XSSF doesn't use external sheet indexes, so when asked treat - * it just as a local index - */ - @Override - 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 - * indices are the same - */ - private int convertToExternalSheetIndex(int sheetIndex) { - return sheetIndex; - } - - @Override - public int getExternalSheetIndex(String sheetName) { - int sheetIndex = _uBook.getSheetIndex(sheetName); - return convertToExternalSheetIndex(sheetIndex); - } - - private int resolveBookIndex(String bookName) { - // Strip the [] wrapper, if still present - if (bookName.startsWith("[") && bookName.endsWith("]")) { - bookName = bookName.substring(1, bookName.length()-2); - } - - // Is it already in numeric form? - try { - return Integer.parseInt(bookName); - } catch (NumberFormatException e) {} - - // Look up an External Link Table for this name - List tables = _uBook.getExternalLinksTable(); - int index = findExternalLinkIndex(bookName, tables); - if (index != -1) return index; - - // Is it an absolute file reference? - if (bookName.startsWith("'file:///") && bookName.endsWith("'")) { - String relBookName = bookName.substring(bookName.lastIndexOf('/')+1); - relBookName = relBookName.substring(0, relBookName.length()-1); // Trailing ' - - // Try with this name - index = findExternalLinkIndex(relBookName, tables); - if (index != -1) return index; - - // If we get here, it's got no associated proper links yet - // So, add the missing reference and return - // Note - this is really rather nasty... - ExternalLinksTable fakeLinkTable = new FakeExternalLinksTable(relBookName); - tables.add(fakeLinkTable); - return tables.size(); // 1 based results, 0 = current workbook - } - - // Not properly referenced - throw new RuntimeException("Book not linked for filename " + bookName); - } - /* This is case-sensitive. Is that correct? */ - private int findExternalLinkIndex(String bookName, List tables) { - int i = 0; - for (ExternalLinksTable table : tables) { - if (table.getLinkedFileName().equals(bookName)) { - return i+1; // 1 based results, 0 = current workbook - } - i++; - } - return -1; - } - private static class FakeExternalLinksTable extends ExternalLinksTable { - private final String fileName; - private FakeExternalLinksTable(String fileName) { - this.fileName = fileName; - } - @Override - public String getLinkedFileName() { - return fileName; - } - } - - /** - * Return EvaluationName wrapper around the matching XSSFName (named range) - * @param name case-aware but case-insensitive named range in workbook - * @param sheetIndex index of sheet if named range scope is limited to one sheet - * if named range scope is global to the workbook, sheetIndex is -1. - * @return If name is a named range in the workbook, returns - * EvaluationName corresponding to that named range - * Returns null if there is no named range with the same name and scope in the workbook - */ - @Override - public EvaluationName getName(String name, int sheetIndex) { - for (int i = 0; i < _uBook.getNumberOfNames(); i++) { - XSSFName nm = _uBook.getNameAt(i); - String nameText = nm.getNameName(); - int nameSheetindex = nm.getSheetIndex(); - if (name.equalsIgnoreCase(nameText) && - (nameSheetindex == -1 || nameSheetindex == sheetIndex)) { - return new Name(nm, i, this); - } - } - return sheetIndex == -1 ? null : getName(name, -1); - } - - @Override - public String getSheetName(int sheetIndex) { - return _uBook.getSheetName(sheetIndex); - } - - @Override - public ExternalName getExternalName(int externSheetIndex, int externNameIndex) { - throw new IllegalStateException("HSSF-style external references are not supported for XSSF"); - } - - @Override - public ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber) { - if (externalWorkbookNumber > 0) { - // External reference - reference is 1 based, link table is 0 based - int linkNumber = externalWorkbookNumber - 1; - ExternalLinksTable linkTable = _uBook.getExternalLinksTable().get(linkNumber); - - for (org.apache.poi.ss.usermodel.Name name : linkTable.getDefinedNames()) { - if (name.getNameName().equals(nameName)) { - // HSSF returns one sheet higher than normal, and various bits - // of the code assume that. So, make us match that behaviour! - int nameSheetIndex = name.getSheetIndex() + 1; - - // TODO Return a more specialised form of this, see bug #56752 - // Should include the cached values, for in case that book isn't available - // Should support XSSF stuff lookups - return new ExternalName(nameName, -1, nameSheetIndex); - } - } - throw new IllegalArgumentException("Name '"+nameName+"' not found in " + - "reference to " + linkTable.getLinkedFileName()); - } else { - // Internal reference - int nameIdx = _uBook.getNameIndex(nameName); - return new ExternalName(nameName, nameIdx, 0); // TODO Is this right? - } - - } - - /** - * Return an external name (named range, function, user-defined function) Pxg - */ - @Override - public NameXPxg getNameXPtg(String name, SheetIdentifier sheet) { - // First, try to find it as a User Defined Function - IndexedUDFFinder udfFinder = (IndexedUDFFinder)getUDFFinder(); - FreeRefFunction func = udfFinder.findFunction(name); - if (func != null) { - return new NameXPxg(null, name); - } - - // Otherwise, try it as a named range - if (sheet == null) { - if (!_uBook.getNames(name).isEmpty()) { - return new NameXPxg(null, name); - } - return null; - } - if (sheet._sheetIdentifier == null) { - // Workbook + Named Range only - int bookIndex = resolveBookIndex(sheet._bookName); - return new NameXPxg(bookIndex, null, name); - } - - // Use the sheetname and process - String sheetName = sheet._sheetIdentifier.getName(); - - if (sheet._bookName != null) { - int bookIndex = resolveBookIndex(sheet._bookName); - return new NameXPxg(bookIndex, sheetName, name); - } else { - return new NameXPxg(sheetName, name); - } - } - @Override - public Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet) { - if (sheet._bookName != null) { - int bookIndex = resolveBookIndex(sheet._bookName); - return new Ref3DPxg(bookIndex, sheet, cell); - } else { - return new Ref3DPxg(sheet, cell); - } - } - @Override - public Ptg get3DReferencePtg(AreaReference area, SheetIdentifier sheet) { - if (sheet._bookName != null) { - int bookIndex = resolveBookIndex(sheet._bookName); - return new Area3DPxg(bookIndex, sheet, area); - } else { - return new Area3DPxg(sheet, area); - } - } - - @Override - public String resolveNameXText(NameXPtg n) { - int idx = n.getNameIndex(); - String name = null; - - // First, try to find it as a User Defined Function - IndexedUDFFinder udfFinder = (IndexedUDFFinder)getUDFFinder(); - name = udfFinder.getFunctionName(idx); - if (name != null) return name; - - // Otherwise, try it as a named range - XSSFName xname = _uBook.getNameAt(idx); - if (xname != null) { - name = xname.getNameName(); - } - - return name; - } - - @Override - public ExternalSheet getExternalSheet(int externSheetIndex) { - throw new IllegalStateException("HSSF-style external references are not supported for XSSF"); - } - @Override - public ExternalSheet getExternalSheet(String firstSheetName, String lastSheetName, int externalWorkbookNumber) { - String workbookName; - if (externalWorkbookNumber > 0) { - // External reference - reference is 1 based, link table is 0 based - int linkNumber = externalWorkbookNumber - 1; - ExternalLinksTable linkTable = _uBook.getExternalLinksTable().get(linkNumber); - workbookName = linkTable.getLinkedFileName(); - } else { - // Internal reference - workbookName = null; - } - - if (lastSheetName == null || firstSheetName.equals(lastSheetName)) { - return new ExternalSheet(workbookName, firstSheetName); - } else { - return new ExternalSheetRange(workbookName, firstSheetName, lastSheetName); - } - } - - @NotImplemented - public int getExternalSheetIndex(String workbookName, String sheetName) { - throw new RuntimeException("not implemented yet"); - } - @Override - public int getSheetIndex(String sheetName) { - return _uBook.getSheetIndex(sheetName); - } - - @Override - public String getSheetFirstNameByExternSheet(int externSheetIndex) { - int sheetIndex = convertFromExternalSheetIndex(externSheetIndex); - return _uBook.getSheetName(sheetIndex); - } - @Override - public String getSheetLastNameByExternSheet(int externSheetIndex) { - // XSSF does multi-sheet references differently, so this is the same as the first - return getSheetFirstNameByExternSheet(externSheetIndex); - } - - @Override - public String getNameText(NamePtg namePtg) { - return _uBook.getNameAt(namePtg.getIndex()).getNameName(); - } - @Override - public EvaluationName getName(NamePtg namePtg) { - int ix = namePtg.getIndex(); - return new Name(_uBook.getNameAt(ix), ix, this); - } - @Override - public XSSFName createName() { - return _uBook.createName(); - } - - private static String caseInsensitive(String s) { - return s.toUpperCase(Locale.ROOT); - } - - /* - * TODO: data tables are stored at the workbook level in XSSF, but are bound to a single sheet. - * The current code structure has them hanging off XSSFSheet, but formulas reference them - * only by name (names are global, and case insensitive). - * This map stores names as lower case for case-insensitive lookups. - * - * FIXME: Caching tables by name here for fast formula lookup means the map is out of date if - * a table is renamed or added/removed to a sheet after the map is created. - * - * Perhaps tables can be managed similar to PivotTable references above? - */ - private Map getTableCache() { - if ( _tableCache != null ) { - return _tableCache; - } - // FIXME: use org.apache.commons.collections.map.CaseInsensitiveMap - _tableCache = new HashMap(); - - for (Sheet sheet : _uBook) { - for (XSSFTable tbl : ((XSSFSheet)sheet).getTables()) { - String lname = caseInsensitive(tbl.getName()); - _tableCache.put(lname, tbl); - } - } - return _tableCache; - } - - /** - * Returns the data table with the given name (case insensitive). - * Tables are cached for performance (formula evaluation looks them up by name repeatedly). - * After the first table lookup, adding or removing a table from the document structure will cause trouble. - * This is meant to be used on documents whose structure is essentially static at the point formulas are evaluated. - * - * @param name the data table name (case-insensitive) - * @return The Data table in the workbook named name, or null if no table is named name. - * @since 3.15 beta 2 - */ - @Override - public XSSFTable getTable(String name) { - if (name == null) return null; - String lname = caseInsensitive(name); - return getTableCache().get(lname); - } - - @Override - public UDFFinder getUDFFinder(){ - return _uBook.getUDFFinder(); - } - - @Override - public SpreadsheetVersion getSpreadsheetVersion(){ - return SpreadsheetVersion.EXCEL2007; - } - - 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); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java deleted file mode 100644 index 780126c3d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.BaseFormulaEvaluator; -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.formula.eval.BoolEval; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.RichTextString; - -/** - * Internal POI use only - parent of XSSF and SXSSF formula evaluators - */ -public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { - protected BaseXSSFFormulaEvaluator(WorkbookEvaluator bookEvaluator) { - super(bookEvaluator); - } - @Override - protected RichTextString createRichTextString(String str) { - return new XSSFRichTextString(str); - } - - public void notifySetFormula(Cell cell) { - _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell)); - } - public void notifyDeleteCell(Cell cell) { - _bookEvaluator.notifyDeleteCell(new XSSFEvaluationCell((XSSFCell)cell)); - } - public void notifyUpdateCell(Cell cell) { - _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell)); - } - - /** - * Turns a XSSFCell / SXSSFCell into a XSSFEvaluationCell - */ - protected abstract EvaluationCell toEvaluationCell(Cell cell); - - /** - * Returns a CellValue wrapper around the supplied ValueEval instance. - */ - protected CellValue evaluateFormulaCellValue(Cell cell) { - EvaluationCell evalCell = toEvaluationCell(cell); - ValueEval eval = _bookEvaluator.evaluate(evalCell); - if (eval instanceof NumberEval) { - NumberEval ne = (NumberEval) eval; - return new CellValue(ne.getNumberValue()); - } - if (eval instanceof BoolEval) { - BoolEval be = (BoolEval) eval; - return CellValue.valueOf(be.getBooleanValue()); - } - if (eval instanceof StringEval) { - StringEval ne = (StringEval) eval; - return new CellValue(ne.getStringValue()); - } - if (eval instanceof ErrorEval) { - return CellValue.getError(((ErrorEval)eval).getErrorCode()); - } - throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")"); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/ListAutoNumber.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/ListAutoNumber.java deleted file mode 100644 index 5108813b2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/ListAutoNumber.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Specifies type of automatic numbered bullet points that should be applied to a paragraph. - */ -public enum ListAutoNumber { - /** - * (a), (b), (c), ... - */ - ALPHA_LC_PARENT_BOTH, - /** - * (A), (B), (C), ... - */ - ALPHA_UC_PARENT_BOTH, - /** - * a), b), c), ... - */ - ALPHA_LC_PARENT_R, - /** - * A), B), C), ... - */ - ALPHA_UC_PARENT_R, - /** - * a., b., c., ... - */ - ALPHA_LC_PERIOD, - /** - * A., B., C., ... - */ - ALPHA_UC_PERIOD, - /** - * (1), (2), (3), ... - */ - ARABIC_PARENT_BOTH, - /** - * 1), 2), 3), ... - */ - ARABIC_PARENT_R, - - /** - * 1., 2., 3., ... - */ - ARABIC_PERIOD, - /** - * 1, 2, 3, ... - */ - ARABIC_PLAIN, - - /** - * (i), (ii), (iii), ... - */ - ROMAN_LC_PARENT_BOTH, - /** - * (I), (II), (III), ... - */ - ROMAN_UC_PARENT_BOTH, - /** - * i), ii), iii), ... - */ - ROMAN_LC_PARENT_R, - /** - * I), II), III), ... - */ - ROMAN_UC_PARENT_R, - /** - * i., ii., iii., ... - */ - ROMAN_LC_PERIOD , - /** - * I., II., III., ... - */ - ROMAN_UC_PERIOD, - /** - * Dbl-byte circle numbers - */ - CIRCLE_NUM_DB_PLAIN, - /** - * Wingdings black circle numbers - */ - CIRCLE_NUM_WD_BLACK_PLAIN, - /** - * Wingdings white circle numbers - */ - CIRCLE_NUM_WD_WHITE_PLAIN -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextAlign.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextAlign.java deleted file mode 100644 index b93a885c2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextAlign.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Specified a list of text alignment types - */ -public enum TextAlign { - /** - * Align text to the left margin. - */ - LEFT, - /** - * Align text in the center. - */ - CENTER, - - /** - * Align text to the right margin. - */ - RIGHT, - - /** - * Align text so that it is justified across the whole line. It - * is smart in the sense that it will not justify sentences - * which are short - */ - JUSTIFY, - JUSTIFY_LOW, - DIST, - THAI_DIST -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextAutofit.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextAutofit.java deleted file mode 100644 index 6e01b134f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextAutofit.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Specifies a list of auto-fit types. - *

        - * Autofit specifies that a shape should be auto-fit to fully contain the text described within it. - * Auto-fitting is when text within a shape is scaled in order to contain all the text inside - *

        - */ -public enum TextAutofit { - /** - * Specifies that text within the text body should not be auto-fit to the bounding box. - * Auto-fitting is when text within a text box is scaled in order to remain inside - * the text box. - */ - NONE, - /** - * Specifies that text within the text body should be normally auto-fit to the bounding box. - * Autofitting is when text within a text box is scaled in order to remain inside the text box. - * - *

        - * Example: Consider the situation where a user is building a diagram and needs - * to have the text for each shape that they are using stay within the bounds of the shape. - * An easy way this might be done is by using NORMAL autofit - *

        - */ - NORMAL, - /** - * Specifies that a shape should be auto-fit to fully contain the text described within it. - * Auto-fitting is when text within a shape is scaled in order to contain all the text inside. - * - *

        - * Example: Consider the situation where a user is building a diagram and needs to have - * the text for each shape that they are using stay within the bounds of the shape. - * An easy way this might be done is by using SHAPE autofit - *

        - */ - SHAPE -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextCap.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextCap.java deleted file mode 100644 index 9202e92b4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextCap.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Text Capitalization that is to be applied to the text run. This is a render-only - * modification and does not affect the actual characters stored in the text run. - */ -public enum TextCap { - NONE, - SMALL, - ALL -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextDirection.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextDirection.java deleted file mode 100644 index f91fcca7a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextDirection.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Vertical Text Types - */ -public enum TextDirection { - /** - * Horizontal text. This should be default. - */ - HORIZONTAL, - /** - * Vertical orientation. - * (each line is 90 degrees rotated clockwise, so it goes - * from top to bottom; each next line is to the left from - * the previous one). - */ - VERTICAL, - /** - * Vertical orientation. - * (each line is 270 degrees rotated clockwise, so it goes - * from bottom to top; each next line is to the right from - * the previous one). - */ - VERTICAL_270, - /** - * Determines if all of the text is vertical - * ("one letter on top of another"). - */ - STACKED -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextFontAlign.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextFontAlign.java deleted file mode 100644 index 96417980c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextFontAlign.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Specified a list of text font alignment types - */ -public enum TextFontAlign { - /** - * Automatic alignment - */ - AUTO, - /** - * Align text to the top. - */ - TOP, - /** - * Align text in the center. - */ - CENTER, - - /** - * Align text to the baseline. - */ - BASELINE, - - /** - * Align text to the bottom. - */ - BOTTOM -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextHorizontalOverflow.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextHorizontalOverflow.java deleted file mode 100644 index b1fe0c18d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextHorizontalOverflow.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Text Horizontal Overflow - */ -public enum TextHorizontalOverflow { - /** - * When a big character does not fit into a line, allow a - * horizontal overflow. - */ - OVERFLOW, - - /** - * When a big character does not fit into a line, clip it at - * the proper horizontal overflow. - */ - CLIP -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextVerticalOverflow.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextVerticalOverflow.java deleted file mode 100644 index 87d3e4018..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/TextVerticalOverflow.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Text Vertical Overflow - */ -public enum TextVerticalOverflow { - /** - * Overflow the text and pay no attention to top and bottom barriers. - */ - OVERFLOW, - - /** - * Pay attention to top and bottom barriers. Use an - * ellipsis to denote that there is text which is not visible. - */ - ELLIPSIS, - - /** - * Pay attention to top and bottom barriers. Provide no - * indication that there is text which is not visible. - */ - CLIP -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java deleted file mode 100644 index a804176fc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xssf.usermodel; - -/** - * An anchor is what specifics the position of a shape within a client object - * or within another containing shape. - * - * @author Yegor Kozlov - */ -public abstract class XSSFAnchor { - - public abstract int getDx1(); - public abstract void setDx1( int dx1 ); - public abstract int getDy1(); - public abstract void setDy1( int dy1 ); - public abstract int getDy2(); - public abstract void setDy2( int dy2 ); - public abstract int getDx2(); - public abstract void setDx2( int dx2 ); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAutoFilter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAutoFilter.java deleted file mode 100644 index d363ab31a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAutoFilter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.AutoFilter; - -/** - * Represents autofiltering for the specified worksheet. - * - * @author Yegor Kozlov - */ -public final class XSSFAutoFilter implements AutoFilter { - private XSSFSheet _sheet; - - XSSFAutoFilter(XSSFSheet sheet){ - _sheet = sheet; - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java deleted file mode 100644 index edea8cda9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java +++ /dev/null @@ -1,367 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.BorderFormatting; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Color; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; - -/** - * XSSF high level representation for Border Formatting component - * of Conditional Formatting settings - */ -public class XSSFBorderFormatting implements BorderFormatting { - CTBorder _border; - - /*package*/ XSSFBorderFormatting(CTBorder border) { - _border = border; - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderBottom() { - return getBorderBottomEnum().getCode(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderBottomEnum() { - STBorderStyle.Enum ptrn = _border.isSetBottom() ? _border.getBottom().getStyle() : null; - return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderDiagonalEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderDiagonal() { - return getBorderDiagonalEnum().getCode(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderDiagonalEnum() { - STBorderStyle.Enum ptrn = _border.isSetDiagonal() ? _border.getDiagonal().getStyle() : null; - return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderLeft() { - return getBorderLeftEnum().getCode(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderLeftEnum() { - STBorderStyle.Enum ptrn = _border.isSetLeft() ? _border.getLeft().getStyle() : null; - return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderRightEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderRight() { - return getBorderRightEnum().getCode(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderRightEnum() { - STBorderStyle.Enum ptrn = _border.isSetRight() ? _border.getRight().getStyle() : null; - return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - - /** - * @deprecated POI 3.15. Use {@link #getBorderTopEnum()}. - * This method will return an BorderStyle enum in the future. - */ - @Override - public short getBorderTop() { - return getBorderTopEnum().getCode(); - } - /** - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderTopEnum() { - STBorderStyle.Enum ptrn = _border.isSetTop() ? _border.getTop().getStyle() : null; - return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - - @Override - public XSSFColor getBottomBorderColorColor() { - if(!_border.isSetBottom()) return null; - - CTBorderPr pr = _border.getBottom(); - return new XSSFColor(pr.getColor()); - } - @Override - public short getBottomBorderColor() { - XSSFColor color = getBottomBorderColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - - @Override - public XSSFColor getDiagonalBorderColorColor() { - if(!_border.isSetDiagonal()) return null; - - CTBorderPr pr = _border.getDiagonal(); - return new XSSFColor(pr.getColor()); - } - @Override - public short getDiagonalBorderColor() { - XSSFColor color = getDiagonalBorderColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - - @Override - public XSSFColor getLeftBorderColorColor() { - if(!_border.isSetLeft()) return null; - - CTBorderPr pr = _border.getLeft(); - return new XSSFColor(pr.getColor()); - } - @Override - public short getLeftBorderColor() { - XSSFColor color = getLeftBorderColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - - @Override - public XSSFColor getRightBorderColorColor() { - if(!_border.isSetRight()) return null; - - CTBorderPr pr = _border.getRight(); - return new XSSFColor(pr.getColor()); - } - @Override - public short getRightBorderColor() { - XSSFColor color = getRightBorderColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - - @Override - public XSSFColor getTopBorderColorColor() { - if(!_border.isSetTop()) return null; - - CTBorderPr pr = _border.getTop(); - return new XSSFColor(pr.getColor()); - } - @Override - public short getTopBorderColor() { - XSSFColor color = getRightBorderColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - - /** - * @deprecated 3.15 beta 2. Use {@link #setBorderBottom(BorderStyle)} - */ - @Override - public void setBorderBottom(short border) { - setBorderBottom(BorderStyle.valueOf(border)); - } - @Override - public void setBorderBottom(BorderStyle border) { - CTBorderPr pr = _border.isSetBottom() ? _border.getBottom() : _border.addNewBottom(); - if(border == BorderStyle.NONE) _border.unsetBottom(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - } - - /** - * @deprecated 3.15 beta 2. Use {@link #setBorderDiagonal(BorderStyle)} - */ - @Override - public void setBorderDiagonal(short border) { - setBorderDiagonal(BorderStyle.valueOf(border)); - } - @Override - public void setBorderDiagonal(BorderStyle border) { - CTBorderPr pr = _border.isSetDiagonal() ? _border.getDiagonal() : _border.addNewDiagonal(); - if(border == BorderStyle.NONE) _border.unsetDiagonal(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - } - - /** - * @deprecated 3.15 beta 2. Use {@link #setBorderLeft(BorderStyle)} - */ - @Override - public void setBorderLeft(short border) { - setBorderLeft(BorderStyle.valueOf(border)); - } - @Override - public void setBorderLeft(BorderStyle border) { - CTBorderPr pr = _border.isSetLeft() ? _border.getLeft() : _border.addNewLeft(); - if(border == BorderStyle.NONE) _border.unsetLeft(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - } - - /** - * @deprecated 3.15 beta 2. Use {@link #setBorderRight(BorderStyle)} - */ - @Override - public void setBorderRight(short border) { - setBorderRight(BorderStyle.valueOf(border)); - } - @Override - public void setBorderRight(BorderStyle border) { - CTBorderPr pr = _border.isSetRight() ? _border.getRight() : _border.addNewRight(); - if(border == BorderStyle.NONE) _border.unsetRight(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - } - - /** - * @deprecated 3.15 beta 2. Use {@link #setBorderTop(BorderStyle)} - */ - @Override - public void setBorderTop(short border) { - setBorderTop(BorderStyle.valueOf(border)); - } - @Override - public void setBorderTop(BorderStyle border) { - CTBorderPr pr = _border.isSetTop() ? _border.getTop() : _border.addNewTop(); - if(border == BorderStyle.NONE) _border.unsetTop(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - } - - @Override - public void setBottomBorderColor(Color color) { - XSSFColor xcolor = XSSFColor.toXSSFColor(color); - if (xcolor == null) setBottomBorderColor((CTColor)null); - else setBottomBorderColor(xcolor.getCTColor()); - } - @Override - public void setBottomBorderColor(short color) { - CTColor ctColor = CTColor.Factory.newInstance(); - ctColor.setIndexed(color); - setBottomBorderColor(ctColor); - } - public void setBottomBorderColor(CTColor color) { - CTBorderPr pr = _border.isSetBottom() ? _border.getBottom() : _border.addNewBottom(); - if (color == null) { - pr.unsetColor(); - } else { - pr.setColor(color); - } - } - - @Override - public void setDiagonalBorderColor(Color color) { - XSSFColor xcolor = XSSFColor.toXSSFColor(color); - if (xcolor == null) setDiagonalBorderColor((CTColor)null); - else setDiagonalBorderColor(xcolor.getCTColor()); - } - @Override - public void setDiagonalBorderColor(short color) { - CTColor ctColor = CTColor.Factory.newInstance(); - ctColor.setIndexed(color); - setDiagonalBorderColor(ctColor); - } - public void setDiagonalBorderColor(CTColor color) { - CTBorderPr pr = _border.isSetDiagonal() ? _border.getDiagonal() : _border.addNewDiagonal(); - if (color == null) { - pr.unsetColor(); - } else { - pr.setColor(color); - } - } - - @Override - public void setLeftBorderColor(Color color) { - XSSFColor xcolor = XSSFColor.toXSSFColor(color); - if (xcolor == null) setLeftBorderColor((CTColor)null); - else setLeftBorderColor(xcolor.getCTColor()); - } - @Override - public void setLeftBorderColor(short color) { - CTColor ctColor = CTColor.Factory.newInstance(); - ctColor.setIndexed(color); - setLeftBorderColor(ctColor); - } - public void setLeftBorderColor(CTColor color) { - CTBorderPr pr = _border.isSetLeft() ? _border.getLeft() : _border.addNewLeft(); - if (color == null) { - pr.unsetColor(); - } else { - pr.setColor(color); - } - } - - @Override - public void setRightBorderColor(Color color) { - XSSFColor xcolor = XSSFColor.toXSSFColor(color); - if (xcolor == null) setRightBorderColor((CTColor)null); - else setRightBorderColor(xcolor.getCTColor()); - } - @Override - public void setRightBorderColor(short color) { - CTColor ctColor = CTColor.Factory.newInstance(); - ctColor.setIndexed(color); - setRightBorderColor(ctColor); - } - public void setRightBorderColor(CTColor color) { - CTBorderPr pr = _border.isSetRight() ? _border.getRight() : _border.addNewRight(); - if (color == null) { - pr.unsetColor(); - } else { - pr.setColor(color); - } - } - - @Override - public void setTopBorderColor(Color color) { - XSSFColor xcolor = XSSFColor.toXSSFColor(color); - if (xcolor == null) setTopBorderColor((CTColor)null); - else setTopBorderColor(xcolor.getCTColor()); - } - @Override - public void setTopBorderColor(short color) { - CTColor ctColor = CTColor.Factory.newInstance(); - ctColor.setIndexed(color); - setTopBorderColor(ctColor); - } - public void setTopBorderColor(CTColor color) { - CTBorderPr pr = _border.isSetTop() ? _border.getTop() : _border.addNewTop(); - if (color == null) { - pr.unsetColor(); - } else { - pr.setColor(color); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java deleted file mode 100644 index f1f1ca381..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ /dev/null @@ -1,1300 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaRenderer; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.SharedFormula; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellCopyPolicy; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; - -/** - * High level representation of a cell in a row of a spreadsheet. - *

        - * Cells can be numeric, formula-based or string-based (text). The cell type - * specifies this. String cells cannot contain numbers and numeric cells cannot - * contain strings (at least according to our model). Client apps should do the - * conversions themselves. Formula cells have the formula string, as well as - * the formula result, which can be numeric or string. - *

        - *

        - * Cells should have their number (0 based) before being added to a row. Only - * cells that have values should be added. - *

        - */ -public final class XSSFCell implements Cell { - - private static final String FALSE_AS_STRING = "0"; - private static final String TRUE_AS_STRING = "1"; - private static final String FALSE = "FALSE"; - private static final String TRUE = "TRUE"; - - /** - * the xml bean containing information about the cell's location, value, - * data type, formatting, and formula - */ - private CTCell _cell; - - /** - * the XSSFRow this cell belongs to - */ - private final XSSFRow _row; - - /** - * 0-based column index - */ - private int _cellNum; - - /** - * Table of strings shared across this workbook. - * If two cells contain the same string, then the cell value is the same index into SharedStringsTable - */ - private SharedStringsTable _sharedStringSource; - - /** - * Table of cell styles shared across all cells in a workbook. - */ - private StylesTable _stylesSource; - - /** - * Construct a XSSFCell. - * - * @param row the parent row. - * @param cell the xml bean containing information about the cell. - */ - protected XSSFCell(XSSFRow row, CTCell cell) { - _cell = cell; - _row = row; - if (cell.getR() != null) { - _cellNum = new CellReference(cell.getR()).getCol(); - } else { - int prevNum = row.getLastCellNum(); - if(prevNum != -1){ - _cellNum = row.getCell(prevNum-1, MissingCellPolicy.RETURN_NULL_AND_BLANK).getColumnIndex() + 1; - } - } - _sharedStringSource = row.getSheet().getWorkbook().getSharedStringSource(); - _stylesSource = row.getSheet().getWorkbook().getStylesSource(); - } - - /** - * Copy cell value, formula and style, from srcCell per cell copy policy - * If srcCell is null, clears the cell value and cell style per cell copy policy - * - * This does not shift references in formulas. Use {@link org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter} to shift references in formulas. - * - * @param srcCell The cell to take value, formula and style from - * @param policy The policy for copying the information, see {@link CellCopyPolicy} - * @throws IllegalArgumentException if copy cell style and srcCell is from a different workbook - */ - @Beta - @Internal - public void copyCellFrom(Cell srcCell, CellCopyPolicy policy) { - // Copy cell value (cell type is updated implicitly) - if (policy.isCopyCellValue()) { - if (srcCell != null) { - CellType copyCellType = srcCell.getCellTypeEnum(); - if (copyCellType == CellType.FORMULA && !policy.isCopyCellFormula()) { - // Copy formula result as value - // FIXME: Cached value may be stale - copyCellType = srcCell.getCachedFormulaResultTypeEnum(); - } - switch (copyCellType) { - case NUMERIC: - // DataFormat is not copied unless policy.isCopyCellStyle is true - if (DateUtil.isCellDateFormatted(srcCell)) { - setCellValue(srcCell.getDateCellValue()); - } - else { - setCellValue(srcCell.getNumericCellValue()); - } - break; - case STRING: - setCellValue(srcCell.getStringCellValue()); - break; - case FORMULA: - setCellFormula(srcCell.getCellFormula()); - break; - case BLANK: - setBlank(); - break; - case BOOLEAN: - setCellValue(srcCell.getBooleanCellValue()); - break; - case ERROR: - setCellErrorValue(srcCell.getErrorCellValue()); - break; - - default: - throw new IllegalArgumentException("Invalid cell type " + srcCell.getCellTypeEnum()); - } - } else { //srcCell is null - setBlank(); - } - } - - // Copy CellStyle - if (policy.isCopyCellStyle()) { - if (srcCell != null) { - setCellStyle(srcCell.getCellStyle()); - } - else { - // clear cell style - setCellStyle(null); - } - } - - if (policy.isMergeHyperlink()) { - // if srcCell doesn't have a hyperlink and destCell has a hyperlink, don't clear destCell's hyperlink - final Hyperlink srcHyperlink = srcCell.getHyperlink(); - if (srcHyperlink != null) { - setHyperlink(new XSSFHyperlink(srcHyperlink)); - } - } - else if (policy.isCopyHyperlink()) { - // overwrite the hyperlink at dest cell with srcCell's hyperlink - // if srcCell doesn't have a hyperlink, clear the hyperlink (if one exists) at destCell - final Hyperlink srcHyperlink = srcCell.getHyperlink(); - if (srcHyperlink == null) { - setHyperlink(null); - } - else { - setHyperlink(new XSSFHyperlink(srcHyperlink)); - } - } - } - - /** - * @return table of strings shared across this workbook - */ - protected SharedStringsTable getSharedStringSource() { - return _sharedStringSource; - } - - /** - * @return table of cell styles shared across this workbook - */ - protected StylesTable getStylesSource() { - return _stylesSource; - } - - /** - * Returns the sheet this cell belongs to - * - * @return the sheet this cell belongs to - */ - @Override - public XSSFSheet getSheet() { - return getRow().getSheet(); - } - - /** - * Returns the row this cell belongs to - * - * @return the row this cell belongs to - */ - @Override - public XSSFRow getRow() { - return _row; - } - - /** - * Get the value of the cell as a boolean. - *

        - * For strings, numbers, and errors, we throw an exception. For blank cells we return a false. - *

        - * @return the value of the cell as a boolean - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} - * is not {@link CellType#BOOLEAN}, {@link CellType#BLANK} or {@link CellType#FORMULA} - */ - @Override - public boolean getBooleanCellValue() { - CellType cellType = getCellTypeEnum(); - switch(cellType) { - case BLANK: - return false; - case BOOLEAN: - return _cell.isSetV() && TRUE_AS_STRING.equals(_cell.getV()); - case FORMULA: - //YK: should throw an exception if requesting boolean value from a non-boolean formula - return _cell.isSetV() && TRUE_AS_STRING.equals(_cell.getV()); - default: - throw typeMismatch(CellType.BOOLEAN, cellType, false); - } - } - - /** - * Set a boolean value for the cell - * - * @param value the boolean value to set this cell to. For formulas we'll set the - * precalculated value, for booleans we'll set its value. For other types we - * will change the cell to a boolean cell and set its value. - */ - @Override - public void setCellValue(boolean value) { - _cell.setT(STCellType.B); - _cell.setV(value ? TRUE_AS_STRING : FALSE_AS_STRING); - } - - /** - * Get the value of the cell as a number. - *

        - * For strings we throw an exception. For blank cells we return a 0. - * For formulas or error cells we return the precalculated value; - *

        - * @return the value of the cell as a number - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is {@link CellType#STRING} - * @exception NumberFormatException if the cell value isn't a parsable double. - * @see DataFormatter for turning this number into a string similar to that which Excel would render this number as. - */ - @Override - public double getNumericCellValue() { - CellType cellType = getCellTypeEnum(); - switch(cellType) { - case BLANK: - return 0.0; - case FORMULA: - // fall-through - case NUMERIC: - if(_cell.isSetV()) { - String v = _cell.getV(); - if (v.isEmpty()) return 0.0; - try { - return Double.parseDouble(v); - } catch(NumberFormatException e) { - throw typeMismatch(CellType.NUMERIC, CellType.STRING, false); - } - } else { - return 0.0; - } - default: - throw typeMismatch(CellType.NUMERIC, cellType, false); - } - } - - - /** - * Set a numeric value for the cell - * - * @param value the numeric value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numeric cell and set its value. - */ - @Override - public void setCellValue(double value) { - if(Double.isInfinite(value)) { - // Excel does not support positive/negative infinities, - // rather, it gives a #DIV/0! error in these cases. - _cell.setT(STCellType.E); - _cell.setV(FormulaError.DIV0.getString()); - } else if (Double.isNaN(value)){ - // Excel does not support Not-a-Number (NaN), - // instead it immediately generates an #NUM! error. - _cell.setT(STCellType.E); - _cell.setV(FormulaError.NUM.getString()); - } else { - _cell.setT(STCellType.N); - _cell.setV(String.valueOf(value)); - } - } - - /** - * Get the value of the cell as a string - *

        - * For numeric cells we throw an exception. For blank cells we return an empty string. - * For formulaCells that are not string Formulas, we throw an exception - *

        - * @return the value of the cell as a string - */ - @Override - public String getStringCellValue() { - return getRichStringCellValue().getString(); - } - - /** - * Get the value of the cell as a XSSFRichTextString - *

        - * For numeric cells we throw an exception. For blank cells we return an empty string. - * For formula cells we return the pre-calculated value if a string, otherwise an exception - *

        - * @return the value of the cell as a XSSFRichTextString - */ - @Override - public XSSFRichTextString getRichStringCellValue() { - CellType cellType = getCellTypeEnum(); - XSSFRichTextString rt; - switch (cellType) { - case BLANK: - rt = new XSSFRichTextString(""); - break; - case STRING: - if (_cell.getT() == STCellType.INLINE_STR) { - if(_cell.isSetIs()) { - //string is expressed directly in the cell definition instead of implementing the shared string table. - rt = new XSSFRichTextString(_cell.getIs()); - } else if (_cell.isSetV()) { - //cached result of a formula - rt = new XSSFRichTextString(_cell.getV()); - } else { - rt = new XSSFRichTextString(""); - } - } else if (_cell.getT() == STCellType.STR) { - //cached formula value - rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : ""); - } else { - if (_cell.isSetV()) { - int idx = Integer.parseInt(_cell.getV()); - rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(idx)); - } - else { - rt = new XSSFRichTextString(""); - } - } - break; - case FORMULA: - checkFormulaCachedValueType(CellType.STRING, getBaseCellType(false)); - rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : ""); - break; - default: - throw typeMismatch(CellType.STRING, cellType, false); - } - rt.setStylesTableReference(_stylesSource); - return rt; - } - - private static void checkFormulaCachedValueType(CellType expectedTypeCode, CellType cachedValueType) { - if (cachedValueType != expectedTypeCode) { - throw typeMismatch(expectedTypeCode, cachedValueType, true); - } - } - - /** - * Set a string value for the cell. - * - * @param str value to set the cell to. For formulas we'll set the formula - * cached string result, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - @Override - public void setCellValue(String str) { - setCellValue(str == null ? null : new XSSFRichTextString(str)); - } - - /** - * Set a string value for the cell. - * - * @param str value to set the cell to. For formulas we'll set the 'pre-evaluated result string, - * for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. - */ - @Override - public void setCellValue(RichTextString str) { - if(str == null || str.getString() == null){ - setCellType(CellType.BLANK); - return; - } - - if(str.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){ - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - - CellType cellType = getCellTypeEnum(); - switch (cellType){ - case FORMULA: - _cell.setV(str.getString()); - _cell.setT(STCellType.STR); - break; - default: - if(_cell.getT() == STCellType.INLINE_STR) { - //set the 'pre-evaluated result - _cell.setV(str.getString()); - } else { - _cell.setT(STCellType.S); - XSSFRichTextString rt = (XSSFRichTextString)str; - rt.setStylesTableReference(_stylesSource); - int sRef = _sharedStringSource.addEntry(rt.getCTRst()); - _cell.setV(Integer.toString(sRef)); - } - break; - } - } - - /** - * Return a formula for the cell, for example, SUM(C4:E4) - * - * @return a formula for the cell - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is not {@link CellType#FORMULA} - */ - @Override - public String getCellFormula() { - // existing behavior - create a new XSSFEvaluationWorkbook for every call - return getCellFormula(null); - } - - /** - * package/hierarchy use only - reuse an existing evaluation workbook if available for caching - * - * @param fpb evaluation workbook for reuse, if available, or null to create a new one as needed - * @return a formula for the cell - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is not {@link CellType#FORMULA} - */ - protected String getCellFormula(XSSFEvaluationWorkbook fpb) { - CellType cellType = getCellTypeEnum(); - if(cellType != CellType.FORMULA) throw typeMismatch(CellType.FORMULA, cellType, false); - - CTCellFormula f = _cell.getF(); - if (isPartOfArrayFormulaGroup() && f == null) { - XSSFCell cell = getSheet().getFirstCellInArrayFormula(this); - return cell.getCellFormula(fpb); - } - if (f.getT() == STCellFormulaType.SHARED) { - return convertSharedFormula((int)f.getSi(), fpb == null ? XSSFEvaluationWorkbook.create(getSheet().getWorkbook()) : fpb); - } - return f.getStringValue(); - } - - /** - * Creates a non shared formula from the shared formula counterpart - * - * @param si Shared Group Index - * @return non shared formula created for the given shared formula and this cell - */ - private String convertSharedFormula(int si, XSSFEvaluationWorkbook fpb){ - XSSFSheet sheet = getSheet(); - - CTCellFormula f = sheet.getSharedFormula(si); - if(f == null) throw new IllegalStateException( - "Master cell of a shared formula with sid="+si+" was not found"); - - String sharedFormula = f.getStringValue(); - //Range of cells which the shared formula applies to - String sharedFormulaRange = f.getRef(); - - CellRangeAddress ref = CellRangeAddress.valueOf(sharedFormulaRange); - - int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet); - SharedFormula sf = new SharedFormula(SpreadsheetVersion.EXCEL2007); - - Ptg[] ptgs = FormulaParser.parse(sharedFormula, fpb, FormulaType.CELL, sheetIndex, getRowIndex()); - Ptg[] fmla = sf.convertSharedFormulas(ptgs, - getRowIndex() - ref.getFirstRow(), getColumnIndex() - ref.getFirstColumn()); - return FormulaRenderer.toFormulaString(fpb, fmla); - } - - /** - * Sets formula for this cell. - *

        - * Note, this method only sets the formula string and does not calculate the formula value. - * To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)} - *

        - * - * @param formula the formula to set, e.g. "SUM(C4:E4)". - * If the argument is null then the current formula is removed. - * @throws org.apache.poi.ss.formula.FormulaParseException if the formula has incorrect syntax or is otherwise invalid - * @throws IllegalStateException if the operation is not allowed, for example, - * when the cell is a part of a multi-cell array formula - */ - @Override - public void setCellFormula(String formula) { - if(isPartOfArrayFormulaGroup()){ - notifyArrayFormulaChanging(); - } - setFormula(formula, FormulaType.CELL); - } - - /* package */ void setCellArrayFormula(String formula, CellRangeAddress range) { - setFormula(formula, FormulaType.ARRAY); - CTCellFormula cellFormula = _cell.getF(); - cellFormula.setT(STCellFormulaType.ARRAY); - cellFormula.setRef(range.formatAsString()); - } - - private void setFormula(String formula, FormulaType formulaType) { - XSSFWorkbook wb = _row.getSheet().getWorkbook(); - if (formula == null) { - wb.onDeleteFormula(this); - if(_cell.isSetF()) _cell.unsetF(); - return; - } - - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - //validate through the FormulaParser - FormulaParser.parse(formula, fpb, formulaType, wb.getSheetIndex(getSheet()), getRowIndex()); - - CTCellFormula f = CTCellFormula.Factory.newInstance(); - f.setStringValue(formula); - _cell.setF(f); - if(_cell.isSetV()) _cell.unsetV(); - } - - /** - * Returns column index of this cell - * - * @return zero-based column index of a column in a sheet. - */ - @Override - public int getColumnIndex() { - return this._cellNum; - } - - /** - * Returns row index of a row in the sheet that contains this cell - * - * @return zero-based row index of a row in the sheet that contains this cell - */ - @Override - public int getRowIndex() { - return _row.getRowNum(); - } - - /** - * Returns an A1 style reference to the location of this cell - * - * @return A1 style reference to the location of this cell - */ - public String getReference() { - String ref = _cell.getR(); - if(ref == null) { - return getAddress().formatAsString(); - } - return ref; - } - - /** - * {@inheritDoc} - */ - @Override - public CellAddress getAddress() { - return new CellAddress(this); - } - - /** - * Return the cell's style. - * - * @return the cell's style. - */ - @Override - public XSSFCellStyle getCellStyle() { - XSSFCellStyle style = null; - if(_stylesSource.getNumCellStyles() > 0){ - long idx = _cell.isSetS() ? _cell.getS() : 0; - style = _stylesSource.getStyleAt((int)idx); - } - return style; - } - - /** - *

        Set the style for the cell. The style should be an XSSFCellStyle created/retreived from - * the XSSFWorkbook.

        - * - *

        To change the style of a cell without affecting other cells that use the same style, - * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, java.util.Map)}

        - * - * @param style reference contained in the workbook. - * If the value is null then the style information is removed causing the cell to used the default workbook style. - * @throws IllegalArgumentException if style belongs to a different styles source (most likely because style is from a different Workbook) - */ - @Override - public void setCellStyle(CellStyle style) { - if(style == null) { - if(_cell.isSetS()) _cell.unsetS(); - } else { - XSSFCellStyle xStyle = (XSSFCellStyle)style; - xStyle.verifyBelongsToStylesSource(_stylesSource); - - long idx = _stylesSource.putStyle(xStyle); - _cell.setS(idx); - } - } - - private boolean isFormulaCell() { - if (_cell.getF() != null || getSheet().isCellInArrayFormulaContext(this)) { - return true; - } - return false; - } - - /** - * Return the cell type. - * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return the cell type - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCellType() { - return getCellTypeEnum().getCode(); - } - - /** - * Return the cell type. - * - * @return the cell type - * @since POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCellTypeEnum() { - if (isFormulaCell()) return CellType.FORMULA; - - return getBaseCellType(true); - } - - /** - * Only valid for formula cells - * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCachedFormulaResultType() { - return getCachedFormulaResultTypeEnum().getCode(); - } - - /** - * Only valid for formula cells - * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, - * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula - * @since POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCachedFormulaResultTypeEnum() { - if (! isFormulaCell()) { - throw new IllegalStateException("Only formula cells have cached results"); - } - - return getBaseCellType(false); - } - - /** - * Detect cell type based on the "t" attribute of the CTCell bean - */ - private CellType getBaseCellType(boolean blankCells) { - switch (_cell.getT().intValue()) { - case STCellType.INT_B: - return CellType.BOOLEAN; - case STCellType.INT_N: - if (!_cell.isSetV() && blankCells) { - // ooxml does have a separate cell type of 'blank'. A blank cell gets encoded as - // (either not present or) a numeric cell with no value set. - // The formula evaluator (and perhaps other clients of this interface) needs to - // distinguish blank values which sometimes get translated into zero and sometimes - // empty string, depending on context - return CellType.BLANK; - } - return CellType.NUMERIC; - case STCellType.INT_E: - return CellType.ERROR; - case STCellType.INT_S: // String is in shared strings - case STCellType.INT_INLINE_STR: // String is inline in cell - case STCellType.INT_STR: - return CellType.STRING; - default: - throw new IllegalStateException("Illegal cell type: " + this._cell.getT()); - } - } - - /** - * Get the value of the cell as a date. - *

        - * For strings we throw an exception. For blank cells we return a null. - *

        - * @return the value of the cell as a date - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} is {@link CellType#STRING} - * @exception NumberFormatException if the cell value isn't a parsable double. - * @see DataFormatter for formatting this date into a string similar to how excel does. - */ - @Override - public Date getDateCellValue() { - if (getCellTypeEnum() == CellType.BLANK) { - return null; - } - - double value = getNumericCellValue(); - boolean date1904 = getSheet().getWorkbook().isDate1904(); - return DateUtil.getJavaDate(value, date1904); - } - - /** - * Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as - * a date. - * - * @param value the date value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For other types we - * will change the cell to a numeric cell and set its value. - */ - @Override - public void setCellValue(Date value) { - if(value == null) { - setCellType(CellType.BLANK); - return; - } - - boolean date1904 = getSheet().getWorkbook().isDate1904(); - setCellValue(DateUtil.getExcelDate(value, date1904)); - } - - /** - * Set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as - * a date. - *

        - * This will set the cell value based on the Calendar's timezone. As Excel - * does not support timezones this means that both 20:00+03:00 and - * 20:00-03:00 will be reported as the same value (20:00) even that there - * are 6 hours difference between the two times. This difference can be - * preserved by using setCellValue(value.getTime()) which will - * automatically shift the times to the default timezone. - *

        - * - * @param value the date value to set this cell to. For formulas we'll set the - * precalculated value, for numerics we'll set its value. For othertypes we - * will change the cell to a numeric cell and set its value. - */ - @Override - public void setCellValue(Calendar value) { - if(value == null) { - setCellType(CellType.BLANK); - return; - } - - boolean date1904 = getSheet().getWorkbook().isDate1904(); - setCellValue( DateUtil.getExcelDate(value, date1904 )); - } - - /** - * Returns the error message, such as #VALUE! - * - * @return the error message such as #VALUE! - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} isn't {@link CellType#ERROR} - * @see FormulaError - */ - public String getErrorCellString() throws IllegalStateException { - CellType cellType = getBaseCellType(true); - if(cellType != CellType.ERROR) throw typeMismatch(CellType.ERROR, cellType, false); - - return _cell.getV(); - } - /** - * Get the value of the cell as an error code. - *

        - * For strings, numbers, and booleans, we throw an exception. - * For blank cells we return a 0. - *

        - * - * @return the value of the cell as an error code - * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} isn't {@link CellType #ERROR} - * @see FormulaError - */ - @Override - public byte getErrorCellValue() throws IllegalStateException { - String code = getErrorCellString(); - if (code == null) { - return 0; - } - try { - return FormulaError.forString(code).getCode(); - } catch (final IllegalArgumentException e) { - throw new IllegalStateException("Unexpected error code", e); - } - } - - /** - * Set a error value for the cell - * - * @param errorCode the error value to set this cell to. For formulas we'll set the - * precalculated value , for errors we'll set - * its value. For other types we will change the cell to an error - * cell and set its value. - * @see FormulaError - */ - @Override - public void setCellErrorValue(byte errorCode) { - FormulaError error = FormulaError.forInt(errorCode); - setCellErrorValue(error); - } - - /** - * Set a error value for the cell - * - * @param error the error value to set this cell to. For formulas we'll set the - * precalculated value , for errors we'll set - * its value. For other types we will change the cell to an error - * cell and set its value. - */ - public void setCellErrorValue(FormulaError error) { - _cell.setT(STCellType.E); - _cell.setV(error.getString()); - } - - /** - * {@inheritDoc} - */ - @Override - public void setAsActiveCell() { - getSheet().setActiveCell(getAddress()); - } - - /** - * Blanks this cell. Blank cells have no formula or value but may have styling. - * This method erases all the data previously associated with this cell. - */ - private void setBlank(){ - CTCell blank = CTCell.Factory.newInstance(); - blank.setR(_cell.getR()); - if(_cell.isSetS()) blank.setS(_cell.getS()); - _cell.set(blank); - } - - /** - * Sets column index of this cell - * - * @param num column index of this cell - */ - protected void setCellNum(int num) { - checkBounds(num); - _cellNum = num; - String ref = new CellReference(getRowIndex(), getColumnIndex()).formatAsString(); - _cell.setR(ref); - } - - /** - * Set the cells type (numeric, formula or string) - * - * @throws IllegalArgumentException if the specified cell type is invalid - * @see CellType#NUMERIC - * @see CellType#STRING - * @see CellType#FORMULA - * @see CellType#BLANK - * @see CellType#BOOLEAN - * @see CellType#ERROR - * @deprecated POI 3.15 beta 3. Use {@link #setCellType(CellType)} instead. - */ - @Override - public void setCellType(int cellType) { - setCellType(CellType.forInt(cellType)); - } - /** - * Set the cells type (numeric, formula or string) - * - * @throws IllegalArgumentException if the specified cell type is invalid - */ - @Override - public void setCellType(CellType cellType) { - CellType prevType = getCellTypeEnum(); - - if(isPartOfArrayFormulaGroup()){ - notifyArrayFormulaChanging(); - } - if(prevType == CellType.FORMULA && cellType != CellType.FORMULA) { - getSheet().getWorkbook().onDeleteFormula(this); - } - - switch (cellType) { - case NUMERIC: - _cell.setT(STCellType.N); - break; - case STRING: - if(prevType != CellType.STRING){ - String str = convertCellValueToString(); - XSSFRichTextString rt = new XSSFRichTextString(str); - rt.setStylesTableReference(_stylesSource); - int sRef = _sharedStringSource.addEntry(rt.getCTRst()); - _cell.setV(Integer.toString(sRef)); - } - _cell.setT(STCellType.S); - break; - case FORMULA: - if(!_cell.isSetF()){ - CTCellFormula f = CTCellFormula.Factory.newInstance(); - f.setStringValue("0"); - _cell.setF(f); - if(_cell.isSetT()) _cell.unsetT(); - } - break; - case BLANK: - setBlank(); - break; - case BOOLEAN: - String newVal = convertCellValueToBoolean() ? TRUE_AS_STRING : FALSE_AS_STRING; - _cell.setT(STCellType.B); - _cell.setV(newVal); - break; - - case ERROR: - _cell.setT(STCellType.E); - break; - - - default: - throw new IllegalArgumentException("Illegal cell type: " + cellType); - } - if (cellType != CellType.FORMULA && _cell.isSetF()) { - _cell.unsetF(); - } - } - - /** - * Returns a string representation of the cell - *

        - * Formula cells return the formula string, rather than the formula result. - * Dates are displayed in dd-MMM-yyyy format - * Errors are displayed as #ERR<errIdx> - *

        - */ - @Override - public String toString() { - switch (getCellTypeEnum()) { - case NUMERIC: - if (DateUtil.isCellDateFormatted(this)) { - DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale()); - sdf.setTimeZone(LocaleUtil.getUserTimeZone()); - return sdf.format(getDateCellValue()); - } - return Double.toString(getNumericCellValue()); - case STRING: - return getRichStringCellValue().toString(); - case FORMULA: - return getCellFormula(); - case BLANK: - return ""; - case BOOLEAN: - return getBooleanCellValue() ? TRUE : FALSE; - case ERROR: - return ErrorEval.getText(getErrorCellValue()); - default: - return "Unknown Cell Type: " + getCellTypeEnum(); - } - } - - /** - * Returns the raw, underlying ooxml value for the cell - *

        - * If the cell contains a string, then this value is an index into - * the shared string table, pointing to the actual string value. Otherwise, - * the value of the cell is expressed directly in this element. Cells containing formulas express - * the last calculated result of the formula in this element. - *

        - * - * @return the raw cell value as contained in the underlying CTCell bean, - * null for blank cells. - */ - public String getRawValue() { - return _cell.getV(); - } - - - /** - * Used to help format error messages - */ - private static RuntimeException typeMismatch(CellType expectedType, CellType actualType, boolean isFormulaCell) { - String msg = "Cannot get a " + expectedType + " value from a " + actualType+ " " + (isFormulaCell ? "formula " : "") + "cell"; - return new IllegalStateException(msg); - } - - /** - * @throws RuntimeException if the bounds are exceeded. - */ - private static void checkBounds(int cellIndex) { - SpreadsheetVersion v = SpreadsheetVersion.EXCEL2007; - int maxcol = SpreadsheetVersion.EXCEL2007.getLastColumnIndex(); - if (cellIndex < 0 || cellIndex > maxcol) { - throw new IllegalArgumentException("Invalid column index (" + cellIndex - + "). Allowable column range for " + v.name() + " is (0.." - + maxcol + ") or ('A'..'" + v.getLastColumnName() + "')"); - } - } - - /** - * Returns cell comment associated with this cell - * - * @return the cell comment associated with this cell or null - */ - @Override - public XSSFComment getCellComment() { - return getSheet().getCellComment(new CellAddress(this)); - } - - /** - * Assign a comment to this cell. If the supplied comment is null, - * the comment for this cell will be removed. - * - * @param comment the XSSFComment associated with this cell - */ - @Override - public void setCellComment(Comment comment) { - if(comment == null) { - removeCellComment(); - return; - } - - comment.setAddress(getRowIndex(), getColumnIndex()); - } - - /** - * Removes the comment for this cell, if there is one. - */ - @Override - public void removeCellComment() { - XSSFComment comment = getCellComment(); - if(comment != null){ - CellAddress ref = new CellAddress(getReference()); - XSSFSheet sh = getSheet(); - sh.getCommentsTable(false).removeComment(ref); - sh.getVMLDrawing(false).removeCommentShape(getRowIndex(), getColumnIndex()); - } - } - - /** - * Returns hyperlink associated with this cell - * - * @return hyperlink associated with this cell or null if not found - */ - @Override - public XSSFHyperlink getHyperlink() { - return getSheet().getHyperlink(_row.getRowNum(), _cellNum); - } - - /** - * Assign a hyperlink to this cell. If the supplied hyperlink is null, the - * hyperlink for this cell will be removed. - * - * @param hyperlink the hyperlink to associate with this cell - */ - @Override - public void setHyperlink(Hyperlink hyperlink) { - if (hyperlink == null) { - removeHyperlink(); - return; - } - - XSSFHyperlink link = (XSSFHyperlink)hyperlink; - - // Assign to us - link.setCellReference( new CellReference(_row.getRowNum(), _cellNum).formatAsString() ); - - // Add to the lists - getSheet().addHyperlink(link); - } - - /** - * Removes the hyperlink for this cell, if there is one. - */ - @Override - public void removeHyperlink() { - getSheet().removeHyperlink(_row.getRowNum(), _cellNum); - } - - /** - * Returns the xml bean containing information about the cell's location (reference), value, - * data type, formatting, and formula - * - * @return the xml bean containing information about this cell - */ - @Internal - public CTCell getCTCell(){ - return _cell; - } - - /** - * Set a new internal xml bean. This is only for internal use, do not call this from outside! - * - * This is necessary in some rare cases to work around XMLBeans specialties. - */ - @Internal - public void setCTCell(CTCell cell) { - _cell = cell; - } - - /** - * Chooses a new boolean value for the cell when its type is changing.

        - * - * Usually the caller is calling setCellType() with the intention of calling - * setCellValue(boolean) straight afterwards. This method only exists to give - * the cell a somewhat reasonable value until the setCellValue() call (if at all). - * TODO - perhaps a method like setCellTypeAndValue(int, Object) should be introduced to avoid this - */ - private boolean convertCellValueToBoolean() { - CellType cellType = getCellTypeEnum(); - - if (cellType == CellType.FORMULA) { - cellType = getBaseCellType(false); - } - - switch (cellType) { - case BOOLEAN: - return TRUE_AS_STRING.equals(_cell.getV()); - case STRING: - int sstIndex = Integer.parseInt(_cell.getV()); - XSSFRichTextString rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(sstIndex)); - String text = rt.getString(); - return Boolean.parseBoolean(text); - case NUMERIC: - return Double.parseDouble(_cell.getV()) != 0; - - case ERROR: - // fall-through - case BLANK: - return false; - - default: - throw new RuntimeException("Unexpected cell type (" + cellType + ")"); - } - } - - private String convertCellValueToString() { - CellType cellType = getCellTypeEnum(); - - switch (cellType) { - case BLANK: - return ""; - case BOOLEAN: - return TRUE_AS_STRING.equals(_cell.getV()) ? TRUE : FALSE; - case STRING: - int sstIndex = Integer.parseInt(_cell.getV()); - XSSFRichTextString rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(sstIndex)); - return rt.getString(); - case NUMERIC: - case ERROR: - return _cell.getV(); - case FORMULA: - // should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator - // just use cached formula result instead - break; - default: - throw new IllegalStateException("Unexpected cell type (" + cellType + ")"); - } - cellType = getBaseCellType(false); - String textValue = _cell.getV(); - switch (cellType) { - case BOOLEAN: - if (TRUE_AS_STRING.equals(textValue)) { - return TRUE; - } - if (FALSE_AS_STRING.equals(textValue)) { - return FALSE; - } - throw new IllegalStateException("Unexpected boolean cached formula value '" - + textValue + "'."); - - case STRING: - // fall-through - case NUMERIC: - // fall-through - case ERROR: - return textValue; - - default: - throw new IllegalStateException("Unexpected formula result type (" + cellType + ")"); - } - - } - - @Override - public CellRangeAddress getArrayFormulaRange() { - XSSFCell cell = getSheet().getFirstCellInArrayFormula(this); - if (cell == null) { - throw new IllegalStateException("Cell " + getReference() - + " is not part of an array formula."); - } - String formulaRef = cell._cell.getF().getRef(); - return CellRangeAddress.valueOf(formulaRef); - } - - @Override - public boolean isPartOfArrayFormulaGroup() { - return getSheet().isCellInArrayFormulaContext(this); - } - - /** - * The purpose of this method is to validate the cell state prior to modification - * - * @see #notifyArrayFormulaChanging() - */ - void notifyArrayFormulaChanging(String msg){ - if(isPartOfArrayFormulaGroup()){ - CellRangeAddress cra = getArrayFormulaRange(); - if(cra.getNumberOfCells() > 1) { - throw new IllegalStateException(msg); - } - //un-register the single-cell array formula from the parent XSSFSheet - getRow().getSheet().removeArrayFormula(this); - } - } - - /** - * Called when this cell is modified. - *

        - * The purpose of this method is to validate the cell state prior to modification. - *

        - * - * @see #setCellType(int) - * @see #setCellFormula(String) - * @see XSSFRow#removeCell(org.apache.poi.ss.usermodel.Cell) - * @see org.apache.poi.xssf.usermodel.XSSFSheet#removeRow(org.apache.poi.ss.usermodel.Row) - * @see org.apache.poi.xssf.usermodel.XSSFSheet#shiftRows(int, int, int) - * @see org.apache.poi.xssf.usermodel.XSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress) - * @throws IllegalStateException if modification is not allowed - */ - void notifyArrayFormulaChanging(){ - CellReference ref = new CellReference(this); - String msg = "Cell "+ref.formatAsString()+" is part of a multi-cell array formula. " + - "You cannot change part of an array."; - notifyArrayFormulaChanging(msg); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java deleted file mode 100644 index 6e66f9926..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java +++ /dev/null @@ -1,1522 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import org.apache.poi.POIXMLException; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.model.ThemesTable; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellAlignment; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder.BorderSide; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellAlignment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; - -/** - * - * High level representation of the the possible formatting information for the contents of the cells on a sheet in a - * SpreadsheetML document. - * - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#createCellStyle() - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#getCellStyleAt(int) - * @see org.apache.poi.xssf.usermodel.XSSFCell#setCellStyle(org.apache.poi.ss.usermodel.CellStyle) - */ -public class XSSFCellStyle implements CellStyle { - - private int _cellXfId; - private final StylesTable _stylesSource; - private CTXf _cellXf; - private final CTXf _cellStyleXf; - private XSSFFont _font; - private XSSFCellAlignment _cellAlignment; - private ThemesTable _theme; - - /** - * Creates a Cell Style from the supplied parts - * @param cellXfId The main XF for the cell. Must be a valid 0-based index into the XF table - * @param cellStyleXfId Optional, style xf. A value of -1 means no xf. - * @param stylesSource Styles Source to work off - */ - public XSSFCellStyle(int cellXfId, int cellStyleXfId, StylesTable stylesSource, ThemesTable theme) { - _cellXfId = cellXfId; - _stylesSource = stylesSource; - _cellXf = stylesSource.getCellXfAt(this._cellXfId); - _cellStyleXf = cellStyleXfId == -1 ? null : stylesSource.getCellStyleXfAt(cellStyleXfId); - _theme = theme; - } - - /** - * Used so that StylesSource can figure out our location - */ - @Internal - public CTXf getCoreXf() { - return _cellXf; - } - - /** - * Used so that StylesSource can figure out our location - */ - @Internal - public CTXf getStyleXf() { - return _cellStyleXf; - } - - /** - * Creates an empty Cell Style - */ - public XSSFCellStyle(StylesTable stylesSource) { - _stylesSource = stylesSource; - // We need a new CTXf for the main styles - // TODO decide on a style ctxf - _cellXf = CTXf.Factory.newInstance(); - _cellStyleXf = null; - } - - /** - * Verifies that this style belongs to the supplied Workbook - * Styles Source. - * Will throw an exception if it belongs to a different one. - * This is normally called when trying to assign a style to a - * cell, to ensure the cell and the style are from the same - * workbook (if they're not, it won't work) - * @throws IllegalArgumentException if there's a workbook mis-match - */ - public void verifyBelongsToStylesSource(StylesTable src) { - if(this._stylesSource != src) { - throw new IllegalArgumentException("This Style does not belong to the supplied Workbook Stlyes Source. Are you trying to assign a style from one workbook to the cell of a differnt workbook?"); - } - } - - /** - * Clones all the style information from another - * XSSFCellStyle, onto this one. This - * XSSFCellStyle will then have all the same - * properties as the source, but the two may - * be edited independently. - * Any stylings on this XSSFCellStyle will be lost! - * - * The source XSSFCellStyle could be from another - * XSSFWorkbook if you like. This allows you to - * copy styles from one XSSFWorkbook to another. - */ - @Override - public void cloneStyleFrom(CellStyle source) { - if(source instanceof XSSFCellStyle) { - XSSFCellStyle src = (XSSFCellStyle)source; - - // Is it on our Workbook? - if(src._stylesSource == _stylesSource) { - // Nice and easy - _cellXf.set(src.getCoreXf()); - _cellStyleXf.set(src.getStyleXf()); - } else { - // Copy the style - try { - // Remove any children off the current style, to - // avoid orphaned nodes - if(_cellXf.isSetAlignment()) - _cellXf.unsetAlignment(); - if(_cellXf.isSetExtLst()) - _cellXf.unsetExtLst(); - - // Create a new Xf with the same contents - _cellXf = CTXf.Factory.parse( - src.getCoreXf().toString(), DEFAULT_XML_OPTIONS - ); - - // bug 56295: ensure that the fills is available and set correctly - CTFill fill = CTFill.Factory.parse( - src.getCTFill().toString(), DEFAULT_XML_OPTIONS - ); - addFill(fill); - - // bug 58084: set borders correctly - CTBorder border = CTBorder.Factory.parse( - src.getCTBorder().toString(), DEFAULT_XML_OPTIONS - ); - addBorder(border); - - // Swap it over - _stylesSource.replaceCellXfAt(_cellXfId, _cellXf); - } catch(XmlException e) { - throw new POIXMLException(e); - } - - // Copy the format - String fmt = src.getDataFormatString(); - setDataFormat( - (new XSSFDataFormat(_stylesSource)).getFormat(fmt) - ); - - // Copy the font - try { - CTFont ctFont = CTFont.Factory.parse( - src.getFont().getCTFont().toString(), DEFAULT_XML_OPTIONS - ); - XSSFFont font = new XSSFFont(ctFont); - font.registerTo(_stylesSource); - setFont(font); - } catch(XmlException e) { - throw new POIXMLException(e); - } - } - - // Clear out cached details - _font = null; - _cellAlignment = null; - } else { - throw new IllegalArgumentException("Can only clone from one XSSFCellStyle to another, not between HSSFCellStyle and XSSFCellStyle"); - } - } - - private void addFill(CTFill fill) { - int idx = _stylesSource.putFill(new XSSFCellFill(fill)); - - _cellXf.setFillId(idx); - _cellXf.setApplyFill(true); - } - - private void addBorder(CTBorder border) { - int idx = _stylesSource.putBorder(new XSSFCellBorder(border, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Get the type of horizontal alignment for the cell - * - * @return short - the type of alignment - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_GENERAL - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_LEFT - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_CENTER - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_RIGHT - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_FILL - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_JUSTIFY - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_CENTER_SELECTION - * @deprecated POI 3.15 beta 3. Use {@link #getAlignmentEnum()} instead. - */ - @Override - public short getAlignment() { - return getAlignmentEnum().getCode(); - } - - /** - * Get the type of horizontal alignment for the cell - * - * @return HorizontalAlignment - the type of alignment - */ - @Override - public HorizontalAlignment getAlignmentEnum() { - CTCellAlignment align = _cellXf.getAlignment(); - if(align != null && align.isSetHorizontal()) { - return HorizontalAlignment.forInt(align.getHorizontal().intValue()-1); - } - return HorizontalAlignment.GENERAL; - } - - /** - * Get the type of border to use for the bottom border of the cell - * Will be removed when {@link #getBorderBottom()} returns a BorderStyle enum - * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderBottomEnum() { - if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; - - int idx = (int)_cellXf.getBorderId(); - CTBorder ct = _stylesSource.getBorderAt(idx).getCTBorder(); - STBorderStyle.Enum ptrn = ct.isSetBottom() ? ct.getBottom().getStyle() : null; - if (ptrn == null) { - return BorderStyle.NONE; - } - return BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - /** - * Get the type of border to use for the bottom border of the cell - * This will return a BorderStyle enum in the future. - * - * @return border type code - * @deprecated 3.15 beta 2. Use {@link #getBorderBottomEnum()} - */ - public short getBorderBottom() { - return getBorderBottomEnum().getCode(); - } - - /** - * Get the type of border to use for the left border of the cell - * Will be removed when {@link #getBorderLeft()} returns a BorderStyle enum - * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderLeftEnum() { - if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; - - int idx = (int)_cellXf.getBorderId(); - CTBorder ct = _stylesSource.getBorderAt(idx).getCTBorder(); - STBorderStyle.Enum ptrn = ct.isSetLeft() ? ct.getLeft().getStyle() : null; - if (ptrn == null) { - return BorderStyle.NONE; - } - return BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - - /** - * Get the type of border to use for the left border of the cell - * This will return a BorderStyle enum in the future. - * - * @return border type code - * @deprecated 3.15 beta 2. Use {@link #getBorderLeftEnum()} - */ - public short getBorderLeft() { - return getBorderLeftEnum().getCode(); - } - - /** - * Get the type of border to use for the right border of the cell - * Will be removed when {@link #getBorderRight()} returns a BorderStyle enum - * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderRightEnum() { - if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; - - int idx = (int)_cellXf.getBorderId(); - CTBorder ct = _stylesSource.getBorderAt(idx).getCTBorder(); - STBorderStyle.Enum ptrn = ct.isSetRight() ? ct.getRight().getStyle() : null; - if (ptrn == null) { - return BorderStyle.NONE; - } - return BorderStyle.valueOf((short)(ptrn.intValue() - 1)); - } - /** - * Get the type of border to use for the right border of the cell - * This will return a BorderStyle enum in the future. - * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @deprecated 3.15 beta 2. Use {@link #getBorderRightEnum()} instead - */ - public short getBorderRight() { - return getBorderRightEnum().getCode(); - } - - /** - * Get the type of border to use for the top border of the cell - * Will be removed when {@link #getBorderTop()} returns a BorderStyle enum - * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @since POI 3.15 - */ - @Override - public BorderStyle getBorderTopEnum() { - if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; - - int idx = (int)_cellXf.getBorderId(); - CTBorder ct = _stylesSource.getBorderAt(idx).getCTBorder(); - STBorderStyle.Enum ptrn = ct.isSetTop() ? ct.getTop().getStyle() : null; - if (ptrn == null) { - return BorderStyle.NONE; - } - return BorderStyle.valueOf((short) (ptrn.intValue() - 1)); - } - /** - * Get the type of border to use for the top border of the cell - * This will return a BorderStyle enum in the future. - * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @deprecated 3.15 beta 2. Use {@link #getBorderTopEnum()} instead. - */ - public short getBorderTop() { - return getBorderTopEnum().getCode(); - } - - /** - * Get the color to use for the bottom border - *
        - * Color is optional. When missing, IndexedColors.AUTOMATIC is implied. - * @return the index of the color definition, default value is {@link org.apache.poi.ss.usermodel.IndexedColors#AUTOMATIC} - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public short getBottomBorderColor() { - XSSFColor clr = getBottomBorderXSSFColor(); - return clr == null ? IndexedColors.BLACK.getIndex() : clr.getIndexed(); - } - - /** - * Get the color to use for the bottom border as a {@link XSSFColor} - * - * @return the used color or null if not set - */ - public XSSFColor getBottomBorderXSSFColor() { - if(!_cellXf.getApplyBorder()) return null; - - int idx = (int)_cellXf.getBorderId(); - XSSFCellBorder border = _stylesSource.getBorderAt(idx); - - return border.getBorderColor(BorderSide.BOTTOM); - } - - /** - * Get the index of the number format (numFmt) record used by this cell format. - * - * @return the index of the number format - */ - @Override - public short getDataFormat() { - return (short)_cellXf.getNumFmtId(); - } - - /** - * Get the contents of the format string, by looking up - * the StylesSource - * - * @return the number format string - */ - @Override - public String getDataFormatString() { - int idx = getDataFormat(); - return new XSSFDataFormat(_stylesSource).getFormat((short)idx); - } - - /** - * Get the background fill color. - *

        - * Note - many cells are actually filled with a foreground - * fill, not a background fill - see {@link #getFillForegroundColor()} - *

        - * @return fill color, default value is {@link org.apache.poi.ss.usermodel.IndexedColors#AUTOMATIC} - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public short getFillBackgroundColor() { - XSSFColor clr = getFillBackgroundXSSFColor(); - return clr == null ? IndexedColors.AUTOMATIC.getIndex() : clr.getIndexed(); - } - - @Override - public XSSFColor getFillBackgroundColorColor() { - return getFillBackgroundXSSFColor(); - } - - /** - * Get the background fill color. - *

        - * Note - many cells are actually filled with a foreground - * fill, not a background fill - see {@link #getFillForegroundColor()} - *

        - * @see org.apache.poi.xssf.usermodel.XSSFColor#getRGB() - * @return XSSFColor - fill color or null if not set - */ - public XSSFColor getFillBackgroundXSSFColor() { - // bug 56295: handle missing applyFill attribute as "true" because Excel does as well - if(_cellXf.isSetApplyFill() && !_cellXf.getApplyFill()) return null; - - int fillIndex = (int)_cellXf.getFillId(); - XSSFCellFill fg = _stylesSource.getFillAt(fillIndex); - - XSSFColor fillBackgroundColor = fg.getFillBackgroundColor(); - if (fillBackgroundColor != null && _theme != null) { - _theme.inheritFromThemeAsRequired(fillBackgroundColor); - } - return fillBackgroundColor; - } - - /** - * Get the foreground fill color. - *

        - * Many cells are filled with this, instead of a - * background color ({@link #getFillBackgroundColor()}) - *

        - * @see IndexedColors - * @return fill color, default value is {@link org.apache.poi.ss.usermodel.IndexedColors#AUTOMATIC} - */ - @Override - public short getFillForegroundColor() { - XSSFColor clr = getFillForegroundXSSFColor(); - return clr == null ? IndexedColors.AUTOMATIC.getIndex() : clr.getIndexed(); - } - - @Override - public XSSFColor getFillForegroundColorColor() { - return getFillForegroundXSSFColor(); - } - - /** - * Get the foreground fill color. - * - * @return XSSFColor - fill color or null if not set - */ - public XSSFColor getFillForegroundXSSFColor() { - // bug 56295: handle missing applyFill attribute as "true" because Excel does as well - if(_cellXf.isSetApplyFill() && !_cellXf.getApplyFill()) return null; - - int fillIndex = (int)_cellXf.getFillId(); - XSSFCellFill fg = _stylesSource.getFillAt(fillIndex); - - XSSFColor fillForegroundColor = fg.getFillForegroundColor(); - if (fillForegroundColor != null && _theme != null) { - _theme.inheritFromThemeAsRequired(fillForegroundColor); - } - return fillForegroundColor; - } - - /** - * Get the fill pattern - * @return fill pattern, default value is {@link org.apache.poi.ss.usermodel.CellStyle#NO_FILL} - * - * @see org.apache.poi.ss.usermodel.CellStyle#NO_FILL - * @see org.apache.poi.ss.usermodel.CellStyle#SOLID_FOREGROUND - * @see org.apache.poi.ss.usermodel.CellStyle#FINE_DOTS - * @see org.apache.poi.ss.usermodel.CellStyle#ALT_BARS - * @see org.apache.poi.ss.usermodel.CellStyle#SPARSE_DOTS - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_HORZ_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_VERT_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_BACKWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_FORWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#BIG_SPOTS - * @see org.apache.poi.ss.usermodel.CellStyle#BRICKS - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_HORZ_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_VERT_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_BACKWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_FORWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#SQUARES - * @see org.apache.poi.ss.usermodel.CellStyle#DIAMONDS - * @deprecated POI 3.15 beta 3. This method will return {@link FillPatternType} in the future. Use {@link #setFillPattern(FillPatternType)} instead. - */ - @Override - public short getFillPattern() { - return getFillPatternEnum().getCode(); - } - - /** - * Get the fill pattern - * - * @return the fill pattern, default value is {@link FillPatternType#NO_FILL} - */ - @Override - public FillPatternType getFillPatternEnum() { - // bug 56295: handle missing applyFill attribute as "true" because Excel does as well - if(_cellXf.isSetApplyFill() && !_cellXf.getApplyFill()) return FillPatternType.NO_FILL; - - int fillIndex = (int)_cellXf.getFillId(); - XSSFCellFill fill = _stylesSource.getFillAt(fillIndex); - - STPatternType.Enum ptrn = fill.getPatternType(); - if(ptrn == null) return FillPatternType.NO_FILL; - return FillPatternType.forInt(ptrn.intValue() - 1); - } - - /** - * Gets the font for this style - * @return Font - font - */ - public XSSFFont getFont() { - if (_font == null) { - _font = _stylesSource.getFontAt(getFontId()); - } - return _font; - } - - /** - * Gets the index of the font for this style - * - * @return short - font index - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#getFontAt(short) - */ - @Override - public short getFontIndex() { - return (short) getFontId(); - } - - /** - * Get whether the cell's using this style are to be hidden - * - * @return boolean - whether the cell using this style is hidden - */ - @Override - public boolean getHidden() { - if (!_cellXf.isSetProtection() || !_cellXf.getProtection().isSetHidden()) { - return false; - } - return _cellXf.getProtection().getHidden(); - } - - /** - * Get the number of spaces to indent the text in the cell - * - * @return indent - number of spaces - */ - @Override - public short getIndention() { - CTCellAlignment align = _cellXf.getAlignment(); - return (short)(align == null ? 0 : align.getIndent()); - } - - /** - * Get the index within the StylesTable (sequence within the collection of CTXf elements) - * - * @return unique index number of the underlying record this style represents, as a short (may wrap) - */ - @Override - public short getIndex() { - return (short)this._cellXfId; - } - - /** - * Workaround for places where we need to support more than 32767 cell styles, ideally - * the main getIndex() and others would return int, not short, but that would affect some - * public APIs - * - * @return unique index number of the underlying record this style represents, as an int (always positive) - */ - protected int getUIndex() { - return this._cellXfId; - } - - /** - * Get the color to use for the left border - * - * @return the index of the color definition, default value is {@link org.apache.poi.ss.usermodel.IndexedColors#BLACK} - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public short getLeftBorderColor() { - XSSFColor clr = getLeftBorderXSSFColor(); - return clr == null ? IndexedColors.BLACK.getIndex() : clr.getIndexed(); - } - - /** - * Get the color to use for the left border - * - * @return the index of the color definition or null if not set - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - public XSSFColor getLeftBorderXSSFColor() { - if(!_cellXf.getApplyBorder()) return null; - - int idx = (int)_cellXf.getBorderId(); - XSSFCellBorder border = _stylesSource.getBorderAt(idx); - - return border.getBorderColor(BorderSide.LEFT); - } - - /** - * Get whether the cell's using this style are locked - * - * @return whether the cell using this style are locked - */ - @Override - public boolean getLocked() { - if (!_cellXf.isSetProtection() || !_cellXf.getProtection().isSetLocked()) { - return true; - } - return _cellXf.getProtection().getLocked(); - } - - /** - * Is "Quote Prefix" or "123 Prefix" enabled for the cell? - */ - @Override - public boolean getQuotePrefixed() { - return _cellXf.getQuotePrefix(); - } - - /** - * Get the color to use for the right border - * - * @return the index of the color definition, default value is {@link org.apache.poi.ss.usermodel.IndexedColors#BLACK} - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public short getRightBorderColor() { - XSSFColor clr = getRightBorderXSSFColor(); - return clr == null ? IndexedColors.BLACK.getIndex() : clr.getIndexed(); - } - /** - * Get the color to use for the right border - * - * @return the used color or null if not set - */ - public XSSFColor getRightBorderXSSFColor() { - if(!_cellXf.getApplyBorder()) return null; - - int idx = (int)_cellXf.getBorderId(); - XSSFCellBorder border = _stylesSource.getBorderAt(idx); - - return border.getBorderColor(BorderSide.RIGHT); - } - - /** - * Get the degree of rotation for the text in the cell - *

        - * Expressed in degrees. Values range from 0 to 180. The first letter of - * the text is considered the center-point of the arc. - *
        - * For 0 - 90, the value represents degrees above horizon. For 91-180 the degrees below the - * horizon is calculated as: - *
        - * [degrees below horizon] = 90 - textRotation. - *

        - * - * @return rotation degrees (between 0 and 180 degrees) - */ - @Override - public short getRotation() { - CTCellAlignment align = _cellXf.getAlignment(); - return (short)(align == null ? 0 : align.getTextRotation()); - } - - @Override - public boolean getShrinkToFit() { - CTCellAlignment align = _cellXf.getAlignment(); - return align != null && align.getShrinkToFit(); - } - - /** - * Get the color to use for the top border - * - * @return the index of the color definition, default value is {@link org.apache.poi.ss.usermodel.IndexedColors#BLACK} - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public short getTopBorderColor() { - XSSFColor clr = getTopBorderXSSFColor(); - return clr == null ? IndexedColors.BLACK.getIndex() : clr.getIndexed(); - } - - /** - * Get the color to use for the top border - * - * @return the used color or null if not set - */ - public XSSFColor getTopBorderXSSFColor() { - if(!_cellXf.getApplyBorder()) return null; - - int idx = (int)_cellXf.getBorderId(); - XSSFCellBorder border = _stylesSource.getBorderAt(idx); - - return border.getBorderColor(BorderSide.TOP); - } - - /** - * Get the type of vertical alignment for the cell - * - * @return align the type of alignment, default value is {@link org.apache.poi.ss.usermodel.CellStyle#VERTICAL_BOTTOM} - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_TOP - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_CENTER - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_BOTTOM - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_JUSTIFY - * @deprecated POI 3.15 beta 3. Use {@link #getVerticalAlignmentEnum()} instead. - */ - @Override - public short getVerticalAlignment() { - return getVerticalAlignmentEnum().getCode(); - } - - /** - * Get the type of vertical alignment for the cell - * - * @return the type of alignment, default value is {@link VerticalAlignment#BOTTOM} - */ - @Override - public VerticalAlignment getVerticalAlignmentEnum() { - CTCellAlignment align = _cellXf.getAlignment(); - if(align != null && align.isSetVertical()) { - return VerticalAlignment.forInt(align.getVertical().intValue()-1); - } - return VerticalAlignment.BOTTOM; - } - - /** - * Whether the text should be wrapped - * - * @return a boolean value indicating if the text in a cell should be line-wrapped within the cell. - */ - @Override - public boolean getWrapText() { - CTCellAlignment align = _cellXf.getAlignment(); - return align != null && align.getWrapText(); - } - - /** - * Set the type of horizontal alignment for the cell - * - * @param align - the type of alignment - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_GENERAL - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_LEFT - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_CENTER - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_RIGHT - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_FILL - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_JUSTIFY - * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_CENTER_SELECTION - * @deprecated POI 3.15 beta 3. Use {@link #setAlignment(HorizontalAlignment)} instead. - */ - @Removal(version="3.17") - @Override - public void setAlignment(short align) { - setAlignment(HorizontalAlignment.forInt(align)); - } - - /** - * Set the type of horizontal alignment for the cell - * - * @param align - the type of alignment - */ - @Override - public void setAlignment(HorizontalAlignment align) { - getCellAlignment().setHorizontal(align); - } - - /** - * Set the type of border to use for the bottom border of the cell - * - * @param border the type of border to use - * @deprecated 3.15 beta 2. Use {@link #setBorderBottom(BorderStyle)} - */ - @Removal(version="3.17") - @Override - public void setBorderBottom(short border) { - setBorderBottom(BorderStyle.valueOf(border)); - } - - /** - * Set the type of border to use for the bottom border of the cell - * - * @param border - type of border to use - * @see org.apache.poi.ss.usermodel.BorderStyle - * @since POI 3.15 - */ - @Override - public void setBorderBottom(BorderStyle border) { - CTBorder ct = getCTBorder(); - CTBorderPr pr = ct.isSetBottom() ? ct.getBottom() : ct.addNewBottom(); - if(border == BorderStyle.NONE) ct.unsetBottom(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the type of border to use for the left border of the cell - * @param border the type of border to use - * @deprecated 3.15 beta 2. Use {@link #setBorderLeft(BorderStyle)} - */ - @Removal(version="3.17") - @Override - public void setBorderLeft(short border) { - setBorderLeft(BorderStyle.valueOf(border)); - } - - /** - * Set the type of border to use for the left border of the cell - * - * @param border the type of border to use - * @since POI 3.15 - */ - @Override - public void setBorderLeft(BorderStyle border) { - CTBorder ct = getCTBorder(); - CTBorderPr pr = ct.isSetLeft() ? ct.getLeft() : ct.addNewLeft(); - if(border == BorderStyle.NONE) ct.unsetLeft(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the type of border to use for the right border of the cell - * - * @param border the type of border to use - * @deprecated 3.15 beta 2. Use {@link #setBorderRight(BorderStyle)} - */ - @Removal(version="3.17") - @Override - public void setBorderRight(short border) { - setBorderRight(BorderStyle.valueOf(border)); - } - - /** - * Set the type of border to use for the right border of the cell - * - * @param border the type of border to use - * @since POI 3.15 - */ - @Override - public void setBorderRight(BorderStyle border) { - CTBorder ct = getCTBorder(); - CTBorderPr pr = ct.isSetRight() ? ct.getRight() : ct.addNewRight(); - if(border == BorderStyle.NONE) ct.unsetRight(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the type of border to use for the top border of the cell - * - * @param border the type of border to use - * @deprecated 3.15 beta 2. Use {@link #setBorderTop(BorderStyle)} - */ - @Removal(version="3.17") - @Override - public void setBorderTop(short border) { - setBorderTop(BorderStyle.valueOf(border)); - } - - /** - * Set the type of border to use for the top border of the cell - * - * @param border the type of border to use - * @since POI 3.15 - */ - @Override - public void setBorderTop(BorderStyle border) { - CTBorder ct = getCTBorder(); - CTBorderPr pr = ct.isSetTop() ? ct.getTop() : ct.addNewTop(); - if(border == BorderStyle.NONE) ct.unsetTop(); - else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the color to use for the bottom border - * @param color the index of the color definition - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public void setBottomBorderColor(short color) { - XSSFColor clr = new XSSFColor(); - clr.setIndexed(color); - setBottomBorderColor(clr); - } - - /** - * Set the color to use for the bottom border - * - * @param color the color to use, null means no color - */ - public void setBottomBorderColor(XSSFColor color) { - CTBorder ct = getCTBorder(); - if(color == null && !ct.isSetBottom()) return; - - CTBorderPr pr = ct.isSetBottom() ? ct.getBottom() : ct.addNewBottom(); - if(color != null) pr.setColor(color.getCTColor()); - else pr.unsetColor(); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the index of a data format - * - * @param fmt the index of a data format - */ - @Override - public void setDataFormat(short fmt) { - // XSSF supports >32,767 formats - setDataFormat(fmt&0xffff); - } - /** - * Set the index of a data format - * - * @param fmt the index of a data format - */ - public void setDataFormat(int fmt) { - _cellXf.setApplyNumberFormat(true); - _cellXf.setNumFmtId(fmt); - } - - /** - * Set the background fill color represented as a {@link XSSFColor} value. - *

        - * For example: - *

        -     * cs.setFillPattern(XSSFCellStyle.FINE_DOTS );
        -     * cs.setFillBackgroundXSSFColor(new XSSFColor(java.awt.Color.RED));
        -     * 
        - * optionally a Foreground and background fill can be applied: - * Note: Ensure Foreground color is set prior to background - *
        -     * cs.setFillPattern(XSSFCellStyle.FINE_DOTS );
        -     * cs.setFillForegroundColor(new XSSFColor(java.awt.Color.BLUE));
        -     * cs.setFillBackgroundColor(new XSSFColor(java.awt.Color.GREEN));
        -     * 
        - * or, for the special case of SOLID_FILL: - *
        -     * cs.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND );
        -     * cs.setFillForegroundColor(new XSSFColor(java.awt.Color.GREEN));
        -     * 
        - * It is necessary to set the fill style in order - * for the color to be shown in the cell. - * - * @param color - the color to use - */ - public void setFillBackgroundColor(XSSFColor color) { - CTFill ct = getCTFill(); - CTPatternFill ptrn = ct.getPatternFill(); - if(color == null) { - if(ptrn != null && ptrn.isSetBgColor()) ptrn.unsetBgColor(); - } else { - if(ptrn == null) ptrn = ct.addNewPatternFill(); - ptrn.setBgColor(color.getCTColor()); - } - - addFill(ct); - } - - /** - * Set the background fill color represented as a indexed color value. - *

        - * For example: - *

        -     * cs.setFillPattern(XSSFCellStyle.FINE_DOTS );
        -     * cs.setFillBackgroundXSSFColor(IndexedColors.RED.getIndex());
        -     * 
        - * optionally a Foreground and background fill can be applied: - * Note: Ensure Foreground color is set prior to background - *
        -     * cs.setFillPattern(XSSFCellStyle.FINE_DOTS );
        -     * cs.setFillForegroundColor(IndexedColors.BLUE.getIndex());
        -     * cs.setFillBackgroundColor(IndexedColors.RED.getIndex());
        -     * 
        - * or, for the special case of SOLID_FILL: - *
        -     * cs.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND );
        -     * cs.setFillForegroundColor(IndexedColors.RED.getIndex());
        -     * 
        - * It is necessary to set the fill style in order - * for the color to be shown in the cell. - * - * @param bg - the color to use - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public void setFillBackgroundColor(short bg) { - XSSFColor clr = new XSSFColor(); - clr.setIndexed(bg); - setFillBackgroundColor(clr); - } - - /** - * Set the foreground fill color represented as a {@link XSSFColor} value. - *
        - * Note: Ensure Foreground color is set prior to background color. - * @param color the color to use - * @see #setFillBackgroundColor(org.apache.poi.xssf.usermodel.XSSFColor) ) - */ - public void setFillForegroundColor(XSSFColor color) { - CTFill ct = getCTFill(); - - CTPatternFill ptrn = ct.getPatternFill(); - if(color == null) { - if(ptrn != null && ptrn.isSetFgColor()) ptrn.unsetFgColor(); - } else { - if(ptrn == null) ptrn = ct.addNewPatternFill(); - ptrn.setFgColor(color.getCTColor()); - } - - addFill(ct); - } - - /** - * Set the foreground fill color as a indexed color value - *
        - * Note: Ensure Foreground color is set prior to background color. - * @param fg the color to use - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public void setFillForegroundColor(short fg) { - XSSFColor clr = new XSSFColor(); - clr.setIndexed(fg); - setFillForegroundColor(clr); - } - - /** - * Get a copy of the currently used CTFill, if none is used, return a new instance. - */ - private CTFill getCTFill(){ - CTFill ct; - // bug 56295: handle missing applyFill attribute as "true" because Excel does as well - if(!_cellXf.isSetApplyFill() || _cellXf.getApplyFill()) { - int fillIndex = (int)_cellXf.getFillId(); - XSSFCellFill cf = _stylesSource.getFillAt(fillIndex); - - ct = (CTFill)cf.getCTFill().copy(); - } else { - ct = CTFill.Factory.newInstance(); - } - return ct; - } - - /** - * Get a copy of the currently used CTBorder, if none is used, return a new instance. - */ - private CTBorder getCTBorder(){ - CTBorder ct; - if(_cellXf.getApplyBorder()) { - int idx = (int)_cellXf.getBorderId(); - XSSFCellBorder cf = _stylesSource.getBorderAt(idx); - - ct = (CTBorder)cf.getCTBorder().copy(); - } else { - ct = CTBorder.Factory.newInstance(); - } - return ct; - } - - /** - * This element is used to specify cell fill information for pattern and solid color cell fills. - * For solid cell fills (no pattern), foreground color is used. - * For cell fills with patterns specified, then the cell fill color is specified by the background color. - * - * @see org.apache.poi.ss.usermodel.CellStyle#NO_FILL - * @see org.apache.poi.ss.usermodel.CellStyle#SOLID_FOREGROUND - * @see org.apache.poi.ss.usermodel.CellStyle#FINE_DOTS - * @see org.apache.poi.ss.usermodel.CellStyle#ALT_BARS - * @see org.apache.poi.ss.usermodel.CellStyle#SPARSE_DOTS - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_HORZ_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_VERT_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_BACKWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#THICK_FORWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#BIG_SPOTS - * @see org.apache.poi.ss.usermodel.CellStyle#BRICKS - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_HORZ_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_VERT_BANDS - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_BACKWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#THIN_FORWARD_DIAG - * @see org.apache.poi.ss.usermodel.CellStyle#SQUARES - * @see org.apache.poi.ss.usermodel.CellStyle#DIAMONDS - * @see #setFillBackgroundColor(short) - * @see #setFillForegroundColor(short) - * @param fp fill pattern (set to {@link org.apache.poi.ss.usermodel.CellStyle#SOLID_FOREGROUND} to fill w/foreground color) - * @deprecated POI 3.15. Use {@link #setFillPattern(FillPatternType)} instead. - */ - @Removal(version="3.17") - @Override - public void setFillPattern(short fp) { - setFillPattern(FillPatternType.forInt(fp)); - } - - /** - * This element is used to specify cell fill information for pattern and solid color cell fills. For solid cell fills (no pattern), - * foreground color is used is used. For cell fills with patterns specified, then the cell fill color is specified by the background color element. - * - * @param pattern the fill pattern to use - * @see #setFillBackgroundColor(XSSFColor) - * @see #setFillForegroundColor(XSSFColor) - * @see org.apache.poi.ss.usermodel.FillPatternType - */ - @Override - public void setFillPattern(FillPatternType pattern) { - CTFill ct = getCTFill(); - CTPatternFill ctptrn = ct.isSetPatternFill() ? ct.getPatternFill() : ct.addNewPatternFill(); - if (pattern == FillPatternType.NO_FILL && ctptrn.isSetPatternType()) { - ctptrn.unsetPatternType(); - } else { - ctptrn.setPatternType(STPatternType.Enum.forInt(pattern.getCode() + 1)); - } - - addFill(ct); - } - - /** - * Set the font for this style - * - * @param font a font object created or retrieved from the XSSFWorkbook object - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#createFont() - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#getFontAt(short) - */ - @Override - public void setFont(Font font) { - if(font != null){ - long index = font.getIndex(); - this._cellXf.setFontId(index); - this._cellXf.setApplyFont(true); - } else { - this._cellXf.setApplyFont(false); - } - } - - /** - * Set the cell's using this style to be hidden - * - * @param hidden - whether the cell using this style should be hidden - */ - @Override - public void setHidden(boolean hidden) { - if (!_cellXf.isSetProtection()) { - _cellXf.addNewProtection(); - } - _cellXf.getProtection().setHidden(hidden); - } - - /** - * Set the number of spaces to indent the text in the cell - * - * @param indent - number of spaces - */ - @Override - public void setIndention(short indent) { - getCellAlignment().setIndent(indent); - } - - /** - * Set the color to use for the left border as a indexed color value - * - * @param color the index of the color definition - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public void setLeftBorderColor(short color) { - XSSFColor clr = new XSSFColor(); - clr.setIndexed(color); - setLeftBorderColor(clr); - } - - /** - * Set the color to use for the left border as a {@link XSSFColor} value - * - * @param color the color to use - */ - public void setLeftBorderColor(XSSFColor color) { - CTBorder ct = getCTBorder(); - if(color == null && !ct.isSetLeft()) return; - - CTBorderPr pr = ct.isSetLeft() ? ct.getLeft() : ct.addNewLeft(); - if(color != null) pr.setColor(color.getCTColor()); - else pr.unsetColor(); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the cell's using this style to be locked - * - * @param locked - whether the cell using this style should be locked - */ - @Override - public void setLocked(boolean locked) { - if (!_cellXf.isSetProtection()) { - _cellXf.addNewProtection(); - } - _cellXf.getProtection().setLocked(locked); - } - - /** - * Turn on or off "Quote Prefix" or "123 Prefix" for the style, - * which is used to tell Excel that the thing which looks like - * a number or a formula shouldn't be treated as on. - */ - @Override - public void setQuotePrefixed(boolean quotePrefix) { - _cellXf.setQuotePrefix(quotePrefix); - } - - /** - * Set the color to use for the right border - * - * @param color the index of the color definition - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public void setRightBorderColor(short color) { - XSSFColor clr = new XSSFColor(); - clr.setIndexed(color); - setRightBorderColor(clr); - } - - /** - * Set the color to use for the right border as a {@link XSSFColor} value - * - * @param color the color to use - */ - public void setRightBorderColor(XSSFColor color) { - CTBorder ct = getCTBorder(); - if(color == null && !ct.isSetRight()) return; - - CTBorderPr pr = ct.isSetRight() ? ct.getRight() : ct.addNewRight(); - if(color != null) pr.setColor(color.getCTColor()); - else pr.unsetColor(); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the degree of rotation for the text in the cell - *

        - * Expressed in degrees. Values range from 0 to 180. The first letter of - * the text is considered the center-point of the arc. - *
        - * For 0 - 90, the value represents degrees above horizon. For 91-180 the degrees below the - * horizon is calculated as: - *
        - * [degrees below horizon] = 90 - textRotation. - *

        - * - * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF - * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges - * accordingly, however the corresponding getter is returning values in the range mandated by the current type - * of Excel file-format that this CellStyle is applied to. - * - * @param rotation - the rotation degrees (between 0 and 180 degrees) - */ - @Override - public void setRotation(short rotation) { - getCellAlignment().setTextRotation(rotation); - } - - - /** - * Set the color to use for the top border - * - * @param color the index of the color definition - * @see org.apache.poi.ss.usermodel.IndexedColors - */ - @Override - public void setTopBorderColor(short color) { - XSSFColor clr = new XSSFColor(); - clr.setIndexed(color); - setTopBorderColor(clr); - } - - /** - * Set the color to use for the top border as a {@link XSSFColor} value - * - * @param color the color to use - */ - public void setTopBorderColor(XSSFColor color) { - CTBorder ct = getCTBorder(); - if(color == null && !ct.isSetTop()) return; - - CTBorderPr pr = ct.isSetTop() ? ct.getTop() : ct.addNewTop(); - if(color != null) pr.setColor(color.getCTColor()); - else pr.unsetColor(); - - int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme)); - - _cellXf.setBorderId(idx); - _cellXf.setApplyBorder(true); - } - - /** - * Set the type of vertical alignment for the cell - * - * @param align - align the type of alignment - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_TOP - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_CENTER - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_BOTTOM - * @see org.apache.poi.ss.usermodel.CellStyle#VERTICAL_JUSTIFY - * @see org.apache.poi.ss.usermodel.VerticalAlignment - * @deprecated POI 3.15 beta 3. Use {@link #setVerticalAlignment(VerticalAlignment)} instead. - */ - @Removal(version="3.17") - @Override - public void setVerticalAlignment(short align) { - setVerticalAlignment(VerticalAlignment.forInt(align)); - } - - /** - * Set the type of vertical alignment for the cell - * - * @param align - the type of alignment - */ - public void setVerticalAlignment(VerticalAlignment align) { - getCellAlignment().setVertical(align); - } - - /** - * Set whether the text should be wrapped. - *

        - * Setting this flag to true make all content visible - * whithin a cell by displaying it on multiple lines - *

        - * - * @param wrapped a boolean value indicating if the text in a cell should be line-wrapped within the cell. - */ - @Override - public void setWrapText(boolean wrapped) { - getCellAlignment().setWrapText(wrapped); - } - - /** - * Gets border color - * - * @param side the border side - * @return the used color - */ - public XSSFColor getBorderColor(BorderSide side) { - switch(side){ - case BOTTOM: - return getBottomBorderXSSFColor(); - case RIGHT: - return getRightBorderXSSFColor(); - case TOP: - return getTopBorderXSSFColor(); - case LEFT: - return getLeftBorderXSSFColor(); - default: - throw new IllegalArgumentException("Unknown border: " + side); - } - } - - /** - * Set the color to use for the selected border - * - * @param side - where to apply the color definition - * @param color - the color to use - */ - public void setBorderColor(BorderSide side, XSSFColor color) { - switch(side){ - case BOTTOM: - setBottomBorderColor(color); - break; - case RIGHT: - setRightBorderColor(color); - break; - case TOP: - setTopBorderColor(color); - break; - case LEFT: - setLeftBorderColor(color); - break; - } - } - - @Override - public void setShrinkToFit(boolean shrinkToFit) { - getCellAlignment().setShrinkToFit(shrinkToFit); - } - - private int getFontId() { - if (_cellXf.isSetFontId()) { - return (int) _cellXf.getFontId(); - } - return (int) _cellStyleXf.getFontId(); - } - - /** - * get the cellAlignment object to use for manage alignment - * @return XSSFCellAlignment - cell alignment - */ - protected XSSFCellAlignment getCellAlignment() { - if (this._cellAlignment == null) { - this._cellAlignment = new XSSFCellAlignment(getCTCellAlignment()); - } - return this._cellAlignment; - } - - /** - * Return the CTCellAlignment instance for alignment - * - * @return CTCellAlignment - */ - private CTCellAlignment getCTCellAlignment() { - if (_cellXf.getAlignment() == null) { - _cellXf.setAlignment(CTCellAlignment.Factory.newInstance()); - } - return _cellXf.getAlignment(); - } - - /** - * Returns a hash code value for the object. The hash is derived from the underlying CTXf bean. - * - * @return the hash code value for this style - */ - @Override - public int hashCode(){ - return _cellXf.toString().hashCode(); - } - - /** - * Checks is the supplied style is equal to this style - * - * @param o the style to check - * @return true if the supplied style is equal to this style - */ - @Override - public boolean equals(Object o){ - if(o == null || !(o instanceof XSSFCellStyle)) return false; - - XSSFCellStyle cf = (XSSFCellStyle)o; - return _cellXf.toString().equals(cf.getCoreXf().toString()); - } - - /** - * Make a copy of this style. The underlying CTXf bean is cloned, - * the references to fills and borders remain. - * - * @return a copy of this style - */ - @Override - public Object clone(){ - CTXf xf = (CTXf)_cellXf.copy(); - - int xfSize = _stylesSource._getStyleXfsSize(); - int indexXf = _stylesSource.putCellXf(xf); - return new XSSFCellStyle(indexXf-1, xfSize-1, _stylesSource, _theme); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java deleted file mode 100644 index d39679213..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java +++ /dev/null @@ -1,377 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; -import org.apache.poi.ss.usermodel.charts.ChartData; -import org.apache.poi.util.Internal; -import org.apache.poi.xssf.usermodel.charts.XSSFCategoryAxis; -import org.apache.poi.xssf.usermodel.charts.XSSFChartAxis; -import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory; -import org.apache.poi.xssf.usermodel.charts.XSSFChartLegend; -import org.apache.poi.xssf.usermodel.charts.XSSFManualLayout; -import org.apache.poi.xssf.usermodel.charts.XSSFValueAxis; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPrintSettings; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx; -import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; -import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; - -/** - * Represents a SpreadsheetML Chart - */ -public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartAxisFactory { - - /** - * Parent graphic frame. - */ - private XSSFGraphicFrame frame; - - /** - * Root element of the SpreadsheetML Chart part - */ - private CTChartSpace chartSpace; - /** - * The Chart within that - */ - private CTChart chart; - - List axis = new ArrayList(); - - /** - * Create a new SpreadsheetML chart - */ - protected XSSFChart() { - super(); - createChart(); - } - - /** - * Construct a SpreadsheetML chart from a package part. - * - * @param part the package part holding the chart data, - * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml - * - * @since POI 3.14-Beta1 - */ - protected XSSFChart(PackagePart part) throws IOException, XmlException { - super(part); - - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); - chart = chartSpace.getChart(); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - - /** - * Construct a new CTChartSpace bean. - * By default, it's just an empty placeholder for chart objects. - * - * @return a new CTChartSpace bean - */ - private void createChart() { - chartSpace = CTChartSpace.Factory.newInstance(); - chart = chartSpace.addNewChart(); - CTPlotArea plotArea = chart.addNewPlotArea(); - - plotArea.addNewLayout(); - chart.addNewPlotVisOnly().setVal(true); - - CTPrintSettings printSettings = chartSpace.addNewPrintSettings(); - printSettings.addNewHeaderFooter(); - - CTPageMargins pageMargins = printSettings.addNewPageMargins(); - pageMargins.setB(0.75); - pageMargins.setL(0.70); - pageMargins.setR(0.70); - pageMargins.setT(0.75); - pageMargins.setHeader(0.30); - pageMargins.setFooter(0.30); - printSettings.addNewPageSetup(); - } - - /** - * Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part. - * - * @return the underlying CTChartSpace bean - */ - @Internal - public CTChartSpace getCTChartSpace(){ - return chartSpace; - } - - /** - * Return the underlying CTChart bean, within the Chart Space - * - * @return the underlying CTChart bean - */ - @Internal - public CTChart getCTChart(){ - return chart; - } - - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - - /* - Saved chart space must have the following namespaces set: - - */ - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - chartSpace.save(out, xmlOptions); - out.close(); - } - - /** - * Returns the parent graphic frame. - * @return the graphic frame this chart belongs to - */ - public XSSFGraphicFrame getGraphicFrame() { - return frame; - } - - /** - * Sets the parent graphic frame. - */ - protected void setGraphicFrame(XSSFGraphicFrame frame) { - this.frame = frame; - } - - public XSSFChartDataFactory getChartDataFactory() { - return XSSFChartDataFactory.getInstance(); - } - - public XSSFChart getChartAxisFactory() { - return this; - } - - public void plot(ChartData data, ChartAxis... chartAxis) { - data.fillChart(this, chartAxis); - } - - public XSSFValueAxis createValueAxis(AxisPosition pos) { - long id = axis.size() + 1; - XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); - if (axis.size() == 1) { - ChartAxis ax = axis.get(0); - ax.crossAxis(valueAxis); - valueAxis.crossAxis(ax); - } - axis.add(valueAxis); - return valueAxis; - } - - public XSSFCategoryAxis createCategoryAxis(AxisPosition pos) { - long id = axis.size() + 1; - XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos); - if (axis.size() == 1) { - ChartAxis ax = axis.get(0); - ax.crossAxis(categoryAxis); - categoryAxis.crossAxis(ax); - } - axis.add(categoryAxis); - return categoryAxis; - } - - public List getAxis() { - if (axis.isEmpty() && hasAxis()) { - parseAxis(); - } - return axis; - } - - public XSSFManualLayout getManualLayout() { - return new XSSFManualLayout(this); - } - - /** - * @return true if only visible cells will be present on the chart, - * false otherwise - */ - public boolean isPlotOnlyVisibleCells() { - return chart.getPlotVisOnly().getVal(); - } - - /** - * @param plotVisOnly a flag specifying if only visible cells should be - * present on the chart - */ - public void setPlotOnlyVisibleCells(boolean plotVisOnly) { - chart.getPlotVisOnly().setVal(plotVisOnly); - } - - /** - * Returns the title, or null if none is set - */ - public XSSFRichTextString getTitle() { - if(! chart.isSetTitle()) { - return null; - } - - // TODO Do properly - CTTitle title = chart.getTitle(); - - StringBuffer text = new StringBuffer(); - XmlObject[] t = title - .selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); - for (int m = 0; m < t.length; m++) { - NodeList kids = t[m].getDomNode().getChildNodes(); - final int count = kids.getLength(); - for (int n = 0; n < count; n++) { - Node kid = kids.item(n); - if (kid instanceof Text) { - text.append(kid.getNodeValue()); - } - } - } - - return new XSSFRichTextString(text.toString()); - } - - /** - * Sets the title text. - */ - public void setTitle(String newTitle) { - CTTitle ctTitle; - if (chart.isSetTitle()) { - ctTitle = chart.getTitle(); - } else { - ctTitle = chart.addNewTitle(); - } - - CTTx tx; - if (ctTitle.isSetTx()) { - tx = ctTitle.getTx(); - } else { - tx = ctTitle.addNewTx(); - } - - if (tx.isSetStrRef()) { - tx.unsetStrRef(); - } - - CTTextBody rich; - if (tx.isSetRich()) { - rich = tx.getRich(); - } else { - rich = tx.addNewRich(); - rich.addNewBodyPr(); // body properties must exist (but can be empty) - } - - CTTextParagraph para; - if (rich.sizeOfPArray() > 0) { - para = rich.getPArray(0); - } else { - para = rich.addNewP(); - } - - if (para.sizeOfRArray() > 0) { - CTRegularTextRun run = para.getRArray(0); - run.setT(newTitle); - } else if (para.sizeOfFldArray() > 0) { - CTTextField fld = para.getFldArray(0); - fld.setT(newTitle); - } else { - CTRegularTextRun run = para.addNewR(); - run.setT(newTitle); - } - } - - public XSSFChartLegend getOrCreateLegend() { - return new XSSFChartLegend(this); - } - - public void deleteLegend() { - if (chart.isSetLegend()) { - chart.unsetLegend(); - } - } - - private boolean hasAxis() { - CTPlotArea ctPlotArea = chart.getPlotArea(); - int totalAxisCount = - ctPlotArea.sizeOfValAxArray() + - ctPlotArea.sizeOfCatAxArray() + - ctPlotArea.sizeOfDateAxArray() + - ctPlotArea.sizeOfSerAxArray(); - return totalAxisCount > 0; - } - - private void parseAxis() { - // TODO: add other axis types - parseCategoryAxis(); - parseValueAxis(); - } - - private void parseCategoryAxis() { - for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) { - axis.add(new XSSFCategoryAxis(this, catAx)); - } - } - - private void parseValueAxis() { - for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { - axis.add(new XSSFValueAxis(this, valAx)); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java deleted file mode 100644 index 03194ae02..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTChartsheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTLegacyDrawing; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.ChartsheetDocument; - -/** - * High level representation of Sheet Parts that are of type 'chartsheet'. - *

        - * Chart sheet is a special kind of Sheet that contains only chart and no data. - *

        - * - * @author Yegor Kozlov - */ -public class XSSFChartSheet extends XSSFSheet { - - private static final byte[] BLANK_WORKSHEET = blankWorksheet(); - - protected CTChartsheet chartsheet; - - /** - * @since POI 3.14-Beta1 - */ - protected XSSFChartSheet(PackagePart part) { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFChartSheet(PackagePart part, PackageRelationship rel) { - this(part); - } - - protected void read(InputStream is) throws IOException { - //initialize the supeclass with a blank worksheet - super.read(new ByteArrayInputStream(BLANK_WORKSHEET)); - - try { - chartsheet = ChartsheetDocument.Factory.parse(is, DEFAULT_XML_OPTIONS).getChartsheet(); - } catch (XmlException e){ - throw new POIXMLException(e); - } - } - - /** - * Provide access to the CTChartsheet bean holding this sheet's data - * - * @return the CTChartsheet bean holding this sheet's data - */ - public CTChartsheet getCTChartsheet() { - return chartsheet; - } - - @Override - protected CTDrawing getCTDrawing() { - return chartsheet.getDrawing(); - } - - @Override - protected CTLegacyDrawing getCTLegacyDrawing() { - return chartsheet.getLegacyDrawing(); - } - - @Override - protected void write(OutputStream out) throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement( - new QName(CTChartsheet.type.getName().getNamespaceURI(), "chartsheet")); - chartsheet.save(out, xmlOptions); - - } - - private static byte[] blankWorksheet(){ - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - new XSSFSheet().write(out); - } catch (IOException e){ - throw new RuntimeException(e); - } - return out.toByteArray(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java deleted file mode 100644 index 4dc3db8c4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; -import org.apache.poi.util.Internal; - -/** - * @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; - } - - @Internal - public CTTransform2D getCTTransform2D() { - return t2d; - } - - public int getDx1() { - return (int)t2d.getOff().getX(); - } - - public void setDx1(int dx1) { - t2d.getOff().setX(dx1); - } - - public int getDy1() { - return (int)t2d.getOff().getY(); - } - - public void setDy1(int dy1) { - t2d.getOff().setY(dy1); - } - - public int getDy2() { - return (int)(getDy1() + t2d.getExt().getCy()); - } - - public void setDy2(int dy2) { - t2d.getExt().setCy(dy2 - getDy1()); - } - - public int getDx2() { - return (int)(getDx1() + t2d.getExt().getCx()); - } - - public void setDx2(int dx2) { - t2d.getExt().setCx(dx2 - getDx1()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java deleted file mode 100644 index df47fc227..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java +++ /dev/null @@ -1,256 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.ClientAnchor; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; - -/** - * 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 AnchorType DEFAULT_ANCHOR_TYPE = AnchorType.MOVE_AND_RESIZE; - private AnchorType 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() { - anchorType = DEFAULT_ANCHOR_TYPE; - 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) { - anchorType = DEFAULT_ANCHOR_TYPE; - 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 getDx1() == anchor.getDx1() && - getDx2() == anchor.getDx2() && - getDy1() == anchor.getDy1() && - getDy2() == anchor.getDy2() && - getCol1() == anchor.getCol1() && - getCol2() == anchor.getCol2() && - getRow1() == anchor.getRow1() && - getRow2() == anchor.getRow2() ; - - } - - @Override - public int hashCode() { - assert false : "hashCode not designed"; - return 42; // any arbitrary constant will do - } - - @Override - public String toString(){ - return "from : " + cell1.toString() + "; to: " + cell2.toString(); - } - - /** - * Return starting anchor point - * - * @return starting anchor point - */ - @Internal - public CTMarker getFrom(){ - return cell1; - } - - protected void setFrom(CTMarker from){ - cell1 = from; - } - - /** - * Return ending anchor point - * - * @return ending anchor point - */ - @Internal - public CTMarker getTo(){ - return cell2; - } - - protected void setTo(CTMarker to){ - cell2 = to; - } - - - /** - * Sets the anchor type - * @param anchorType the anchor type to set - * @since POI 3.14 - */ - @Override - public void setAnchorType( AnchorType anchorType ) - { - this.anchorType = anchorType; - } - /** - * Sets the anchor type - * @param anchorType the anchor type to set - * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead - */ - @Removal(version="3.17") - @Override - public void setAnchorType( int anchorType ) - { - this.anchorType = AnchorType.byId(anchorType); - } - - /** - * Gets the anchor type - * Changed from returning an int to an enum in POI 3.14 beta 1. - * @return the anchor type - */ - @Override - public AnchorType getAnchorType() - { - return anchorType; - } - - public boolean isSet(){ - return !(cell1.getCol() == 0 && cell2.getCol() == 0 && - cell1.getRow() == 0 && cell2.getRow() == 0); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java deleted file mode 100644 index 441f42fdb..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java +++ /dev/null @@ -1,395 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.Arrays; - -import org.apache.poi.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.ExtendedColor; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; - -/** - * Represents a color in SpreadsheetML - */ -public class XSSFColor extends ExtendedColor { - private final CTColor ctColor; - - /** - * Create an instance of XSSFColor from the supplied XML bean - */ - public XSSFColor(CTColor color) { - this.ctColor = color; - } - - /** - * Create an new instance of XSSFColor - */ - public XSSFColor() { - this.ctColor = CTColor.Factory.newInstance(); - } - - public XSSFColor(java.awt.Color clr) { - this(); - setColor(clr); - } - - public XSSFColor(byte[] rgb) { - this(); - ctColor.setRgb(rgb); - } - - public XSSFColor(IndexedColors indexedColor) { - this(); - ctColor.setIndexed(indexedColor.index); - } - - /** - * A boolean value indicating the ctColor is automatic and system ctColor dependent. - */ - @Override - public boolean isAuto() { - return ctColor.getAuto(); - } - /** - * A boolean value indicating the ctColor is automatic and system ctColor dependent. - */ - public void setAuto(boolean auto) { - ctColor.setAuto(auto); - } - - /** - * A boolean value indicating the ctColor is Indexed - */ - @Override - public boolean isIndexed() { - return ctColor.isSetIndexed(); - } - - /** - * A boolean value indicating the ctColor is RGB or ARGB based - */ - @Override - public boolean isRGB() { - return ctColor.isSetRgb(); - } - - /** - * A boolean value indicating the ctColor is Theme based - */ - @Override - public boolean isThemed() { - return ctColor.isSetTheme(); - } - - /** - * A boolean value indicating if the ctColor has a alpha or not - */ - public boolean hasAlpha() { - if (! ctColor.isSetRgb()) { - return false; - } - return ctColor.getRgb().length == 4; - } - - /** - * A boolean value indicating if the ctColor has a tint or not - */ - public boolean hasTint() { - if (!ctColor.isSetTint()) { - return false; - } - return ctColor.getTint() != 0; - } - - /** - * Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors. - */ - @Override - public short getIndex() { - return (short)ctColor.getIndexed(); - } - /** - * Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors. - */ - public short getIndexed() { - return getIndex(); - } - - /** - * Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors. - */ - public void setIndexed(int indexed) { - ctColor.setIndexed(indexed); - } - - /** - * Standard Red Green Blue ctColor value (RGB). - * If there was an A (Alpha) value, it will be stripped. - */ - @Override - public byte[] getRGB() { - byte[] rgb = getRGBOrARGB(); - if(rgb == null) { - return null; - } - - if(rgb.length == 4) { - // Need to trim off the alpha - byte[] tmp = new byte[3]; - System.arraycopy(rgb, 1, tmp, 0, 3); - return tmp; - } else { - return rgb; - } - } - - /** - * Standard Alpha Red Green Blue ctColor value (ARGB). - */ - @Override - public byte[] getARGB() { - byte[] rgb = getRGBOrARGB(); - if(rgb == null) { - return null; - } - - if(rgb.length == 3) { - // Pad with the default Alpha - byte[] tmp = new byte[4]; - tmp[0] = -1; - System.arraycopy(rgb, 0, tmp, 1, 3); - return tmp; - } else { - return rgb; - } - } - - @Override - protected byte[] getStoredRBG() { - return ctColor.getRgb(); - } - - /** - * Standard Alpha Red Green Blue ctColor value (ARGB). - */ - @Override - public void setRGB(byte[] rgb) { - ctColor.setRgb(rgb); - } - - /** - * Index into the collection, referencing a particular or - * value expressed in the Theme part. - */ - @Override - public int getTheme() { - return (int)ctColor.getTheme(); - } - - /** - * Index into the collection, referencing a particular or - * value expressed in the Theme part. - */ - public void setTheme(int theme) { - ctColor.setTheme(theme); - } - - /** - * Specifies the tint value applied to the ctColor. - * - *

        - * If tint is supplied, then it is applied to the RGB value of the ctColor to determine the final - * ctColor applied. - *

        - *

        - * The tint value is stored as a double from -1.0 .. 1.0, where -1.0 means 100% darken and - * 1.0 means 100% lighten. Also, 0.0 means no change. - *

        - *

        - * In loading the RGB value, it is converted to HLS where HLS values are (0..HLSMAX), where - * HLSMAX is currently 255. - *

        - * Here are some examples of how to apply tint to ctColor: - *
        - *
        -     * If (tint < 0)
        -     * Lum' = Lum * (1.0 + tint)
        -     *
        -     * For example: Lum = 200; tint = -0.5; Darken 50%
        -     * Lum' = 200 * (0.5) => 100
        -     * For example: Lum = 200; tint = -1.0; Darken 100% (make black)
        -     * Lum' = 200 * (1.0-1.0) => 0
        -     * If (tint > 0)
        -     * Lum' = Lum * (1.0-tint) + (HLSMAX - HLSMAX * (1.0-tint))
        -     * For example: Lum = 100; tint = 0.75; Lighten 75%
        -     *
        -     * Lum' = 100 * (1-.75) + (HLSMAX - HLSMAX*(1-.75))
        -     * = 100 * .25 + (255 - 255 * .25)
        -     * = 25 + (255 - 63) = 25 + 192 = 217
        -     * For example: Lum = 100; tint = 1.0; Lighten 100% (make white)
        -     * Lum' = 100 * (1-1) + (HLSMAX - HLSMAX*(1-1))
        -     * = 100 * 0 + (255 - 255 * 0)
        -     * = 0 + (255 - 0) = 255
        -     * 
        - *
        - * - * @return the tint value - */ - @Override - public double getTint() { - return ctColor.getTint(); - } - - /** - * Specifies the tint value applied to the ctColor. - * - *

        - * If tint is supplied, then it is applied to the RGB value of the ctColor to determine the final - * ctColor applied. - *

        - *

        - * The tint value is stored as a double from -1.0 .. 1.0, where -1.0 means 100% darken and - * 1.0 means 100% lighten. Also, 0.0 means no change. - *

        - *

        - * In loading the RGB value, it is converted to HLS where HLS values are (0..HLSMAX), where - * HLSMAX is currently 255. - *

        - * Here are some examples of how to apply tint to ctColor: - *
        - *
        -     * If (tint < 0)
        -     * Lum' = Lum * (1.0 + tint)
        -     *
        -     * For example: Lum = 200; tint = -0.5; Darken 50%
        -     * Lum' = 200 * (0.5) => 100
        -     * For example: Lum = 200; tint = -1.0; Darken 100% (make black)
        -     * Lum' = 200 * (1.0-1.0) => 0
        -     * If (tint > 0)
        -     * Lum' = Lum * (1.0-tint) + (HLSMAX - HLSMAX * (1.0-tint))
        -     * For example: Lum = 100; tint = 0.75; Lighten 75%
        -     *
        -     * Lum' = 100 * (1-.75) + (HLSMAX - HLSMAX*(1-.75))
        -     * = 100 * .25 + (255 - 255 * .25)
        -     * = 25 + (255 - 63) = 25 + 192 = 217
        -     * For example: Lum = 100; tint = 1.0; Lighten 100% (make white)
        -     * Lum' = 100 * (1-1) + (HLSMAX - HLSMAX*(1-1))
        -     * = 100 * 0 + (255 - 255 * 0)
        -     * = 0 + (255 - 0) = 255
        -     * 
        - *
        - * - * @param tint the tint value - */ - @Override - public void setTint(double tint) { - ctColor.setTint(tint); - } - - /** - * Returns the underlying XML bean - * - * @return the underlying XML bean - */ - @Internal - public CTColor getCTColor(){ - return ctColor; - } - - /** - * Checked type cast color to an XSSFColor. - * - * @param color the color to type cast - * @return the type casted color - * @throws IllegalArgumentException if color is null or is not an instance of XSSFColor - */ - public static XSSFColor toXSSFColor(Color color) { - // FIXME: this method would be more useful if it could convert any Color to an XSSFColor - // Currently the only benefit of this method is to throw an IllegalArgumentException - // instead of a ClassCastException. - if (color != null && !(color instanceof XSSFColor)) { - throw new IllegalArgumentException("Only XSSFColor objects are supported"); - } - return (XSSFColor)color; - } - - @Override - public int hashCode(){ - return ctColor.toString().hashCode(); - } - - // Helper methods for {@link #equals(Object)} - private boolean sameIndexed(XSSFColor other) { - if (isIndexed() == other.isIndexed()) { - if (isIndexed()) { - return getIndexed() == other.getIndexed(); - } - return true; - } - return false; - } - private boolean sameARGB(XSSFColor other) { - if (isRGB() == other.isRGB()) { - if (isRGB()) { - return Arrays.equals(getARGB(), other.getARGB()); - } - return true; - } - return false; - } - private boolean sameTheme(XSSFColor other) { - if (isThemed() == other.isThemed()) { - if (isThemed()) { - return getTheme() == other.getTheme(); - } - return true; - } - return false; - } - private boolean sameTint(XSSFColor other) { - if (hasTint() == other.hasTint()) { - if (hasTint()) { - return getTint() == other.getTint(); - } - return true; - } - return false; - } - private boolean sameAuto(XSSFColor other) { - return isAuto() == other.isAuto(); - } - - @Override - public boolean equals(Object o){ - if(!(o instanceof XSSFColor)) { - return false; - } - - XSSFColor other = (XSSFColor)o; - - // Compare each field in ctColor. - // Cannot compare ctColor's XML string representation because equivalent - // colors may have different relation namespace URI's - return sameARGB(other) - && sameTheme(other) - && sameIndexed(other) - && sameTint(other) - && sameAuto(other); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColorScaleFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColorScaleFormatting.java deleted file mode 100644 index eb15001b0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColorScaleFormatting.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.ColorScaleFormatting; -import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfvo; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColorScale; - -/** - * High level representation for Color Scale / Color Gradient Formatting - * component of Conditional Formatting settings - */ -public class XSSFColorScaleFormatting implements ColorScaleFormatting { - CTColorScale _scale; - - /*package*/ XSSFColorScaleFormatting(CTColorScale scale){ - _scale = scale; - } - - public int getNumControlPoints() { - return _scale.sizeOfCfvoArray(); - } - public void setNumControlPoints(int num) { - while (num < _scale.sizeOfCfvoArray()) { - _scale.removeCfvo(_scale.sizeOfCfvoArray()-1); - _scale.removeColor(_scale.sizeOfColorArray()-1); - } - while (num > _scale.sizeOfCfvoArray()) { - _scale.addNewCfvo(); - _scale.addNewColor(); - } - } - - public XSSFColor[] getColors() { - CTColor[] ctcols = _scale.getColorArray(); - XSSFColor[] c = new XSSFColor[ctcols.length]; - for (int i=0; i 0) { - CellReference ref = new CellReference(comment.getRef()); - CTClientData clientData = vmlShape.getClientDataArray(0); - clientData.setRowArray(0, new BigInteger(String.valueOf(ref.getRow()))); - clientData.setColumnArray(0, new BigInteger(String.valueOf(ref.getCol()))); - - avoidXmlbeansCorruptPointer(vmlShape); - } - } - - /** - * - * @return Name of the original comment author. Default value is blank. - */ - @Override - public String getAuthor() { - return _comments.getAuthor((int) _comment.getAuthorId()); - } - - /** - * Name of the original comment author. Default value is blank. - * - * @param author the name of the original author of the comment - */ - @Override - public void setAuthor(String author) { - _comment.setAuthorId( - _comments.findAuthor(author) - ); - } - - /** - * @return the 0-based column of the cell that the comment is associated with. - */ - @Override - public int getColumn() { - return getAddress().getColumn(); - } - - /** - * @return the 0-based row index of the cell that the comment is associated with. - */ - @Override - public int getRow() { - return getAddress().getRow(); - } - - /** - * Returns whether this comment is visible. - * - * @return true if the comment is visible, false otherwise - */ - @Override - public boolean isVisible() { - boolean visible = false; - if(_vmlShape != null){ - String style = _vmlShape.getStyle(); - visible = style != null && style.indexOf("visibility:visible") != -1; - } - return visible; - } - - /** - * Sets whether this comment is visible. - * - * @param visible true if the comment is visible, false otherwise - */ - @Override - public void setVisible(boolean visible) { - if(_vmlShape != null){ - String style; - if(visible) style = "position:absolute;visibility:visible"; - else style = "position:absolute;visibility:hidden"; - _vmlShape.setStyle(style); - } - } - - @Override - public CellAddress getAddress() { - return new CellAddress(_comment.getRef()); - } - - @Override - public void setAddress(int row, int col) { - setAddress(new CellAddress(row, col)); - } - - @Override - public void setAddress(CellAddress address) { - CellAddress oldRef = new CellAddress(_comment.getRef()); - if (address.equals(oldRef)) { - // nothing to do - return; - } - - _comment.setRef(address.formatAsString()); - _comments.referenceUpdated(oldRef, _comment); - - if (_vmlShape != null) { - CTClientData clientData = _vmlShape.getClientDataArray(0); - clientData.setRowArray(0, new BigInteger(String.valueOf(address.getRow()))); - clientData.setColumnArray(0, new BigInteger(String.valueOf(address.getColumn()))); - - avoidXmlbeansCorruptPointer(_vmlShape); - } - } - - /** - * Set the column of the cell that contains the comment - * - * If changing both row and column, use {@link #setAddress}. - * - * @param col the 0-based column of the cell that contains the comment - */ - @Override - public void setColumn(int col) { - setAddress(getRow(), col); - } - - /** - * Set the row of the cell that contains the comment - * - * If changing both row and column, use {@link #setAddress}. - * - * @param row the 0-based row of the cell that contains the comment - */ - @Override - public void setRow(int row) { - setAddress(row, getColumn()); - } - - /** - * @return the rich text string of the comment - */ - @Override - public XSSFRichTextString getString() { - if(_str == null) { - CTRst rst = _comment.getText(); - if(rst != null) _str = new XSSFRichTextString(_comment.getText()); - } - return _str; - } - - /** - * Sets the rich text string used by this comment. - * - * @param string the XSSFRichTextString used by this object. - */ - @Override - public void setString(RichTextString string) { - if(!(string instanceof XSSFRichTextString)){ - throw new IllegalArgumentException("Only XSSFRichTextString argument is supported"); - } - _str = (XSSFRichTextString)string; - _comment.setText(_str.getCTRst()); - } - - public void setString(String string) { - setString(new XSSFRichTextString(string)); - } - - @Override - public ClientAnchor getClientAnchor() { - String position = _vmlShape.getClientDataArray(0).getAnchorArray(0); - int[] pos = new int[8]; - int i = 0; - for (String s : position.split(",")) { - pos[i++] = Integer.parseInt(s.trim()); - } - XSSFClientAnchor ca = new XSSFClientAnchor(pos[1]*EMU_PER_PIXEL, pos[3]*EMU_PER_PIXEL, pos[5]*EMU_PER_PIXEL, pos[7]*EMU_PER_PIXEL, pos[0], pos[2], pos[4], pos[6]); - return ca; - } - - /** - * @return the xml bean holding this comment's properties - */ - protected CTComment getCTComment(){ - return _comment; - } - - protected CTShape getCTShape(){ - return _vmlShape; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof XSSFComment)) { - return false; - } - XSSFComment other = (XSSFComment) obj; - return ((getCTComment() == other.getCTComment()) && - (getCTShape() == other.getCTShape())); - } - - @Override - public int hashCode() { - return ((getRow()*17) + getColumn())*31; - } - - private static void avoidXmlbeansCorruptPointer(CTShape vmlShape) { - // There is a very odd xmlbeans bug when changing the row - // arrays which can lead to corrupt pointer - // This call seems to fix them again... See bug #50795 - vmlShape.getClientDataList().toString(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java deleted file mode 100644 index 915ba5d4b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.ConditionalFormatting; -import org.apache.poi.ss.usermodel.ConditionalFormattingRule; -import org.apache.poi.ss.util.CellRangeAddress; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting; - -import java.util.ArrayList; -import java.util.Collections; - -/** - * @author Yegor Kozlov - */ -public class XSSFConditionalFormatting implements ConditionalFormatting { - private final CTConditionalFormatting _cf; - private final XSSFSheet _sh; - - /*package*/ XSSFConditionalFormatting(XSSFSheet sh) { - _cf = CTConditionalFormatting.Factory.newInstance(); - _sh = sh; - } - - /*package*/ XSSFConditionalFormatting( - XSSFSheet sh, CTConditionalFormatting cf) { - _cf = cf; - _sh = sh; - } - - /*package*/ CTConditionalFormatting getCTConditionalFormatting() { - return _cf; - } - - /** - * @return array of CellRangeAddresss. Never null - */ - @Override - public CellRangeAddress[] getFormattingRanges() { - ArrayList lst = new ArrayList(); - for (Object stRef : _cf.getSqref()) { - String[] regions = stRef.toString().split(" "); - for (final String region : regions) { - lst.add(CellRangeAddress.valueOf(region)); - } - } - return lst.toArray(new CellRangeAddress[lst.size()]); - } - - @Override - public void setFormattingRanges(CellRangeAddress[] ranges) { - if (ranges == null) { - throw new IllegalArgumentException("cellRanges must not be null"); - } - final StringBuilder sb = new StringBuilder(); - boolean first = true; - for (CellRangeAddress range : ranges) { - if (!first) { - sb.append(" "); - } else { - first = false; - } - sb.append(range.formatAsString()); - } - _cf.setSqref(Collections.singletonList(sb.toString())); - } - - /** - * Replaces an existing Conditional Formatting rule at position idx. - * Excel allows to create up to 3 Conditional Formatting rules. - * This method can be useful to modify existing Conditional Formatting rules. - * - * @param idx position of the rule. Should be between 0 and 2. - * @param cfRule - Conditional Formatting rule - */ - @Override - public void setRule(int idx, ConditionalFormattingRule cfRule) { - XSSFConditionalFormattingRule xRule = (XSSFConditionalFormattingRule) cfRule; - _cf.getCfRuleArray(idx).set(xRule.getCTCfRule()); - } - - /** - * Add a Conditional Formatting rule. - * Excel allows to create up to 3 Conditional Formatting rules. - * - * @param cfRule - Conditional Formatting rule - */ - @Override - public void addRule(ConditionalFormattingRule cfRule) { - XSSFConditionalFormattingRule xRule = (XSSFConditionalFormattingRule) cfRule; - _cf.addNewCfRule().set(xRule.getCTCfRule()); - } - - /** - * @return the Conditional Formatting rule at position idx. - */ - @Override - public XSSFConditionalFormattingRule getRule(int idx) { - return new XSSFConditionalFormattingRule(_sh, _cf.getCfRuleArray(idx)); - } - - /** - * @return number of Conditional Formatting rules. - */ - @Override - public int getNumberOfRules() { - return _cf.sizeOfCfRuleArray(); - } - - @Override - public String toString() { - return _cf.toString(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java deleted file mode 100644 index a639f2c27..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType; -import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet; -import org.apache.poi.xssf.usermodel.XSSFFontFormatting; -import org.apache.poi.xssf.model.StylesTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; - -/** - * XSSF suport for Conditional Formatting rules - */ -public class XSSFConditionalFormattingRule implements ConditionalFormattingRule { - private final CTCfRule _cfRule; - private XSSFSheet _sh; - - private static Map typeLookup = new HashMap(); - static { - typeLookup.put(STCfType.CELL_IS, ConditionType.CELL_VALUE_IS); - typeLookup.put(STCfType.EXPRESSION, ConditionType.FORMULA); - typeLookup.put(STCfType.COLOR_SCALE, ConditionType.COLOR_SCALE); - typeLookup.put(STCfType.DATA_BAR, ConditionType.DATA_BAR); - typeLookup.put(STCfType.ICON_SET, ConditionType.ICON_SET); - - // These are all subtypes of Filter, we think... - typeLookup.put(STCfType.TOP_10, ConditionType.FILTER); - typeLookup.put(STCfType.UNIQUE_VALUES, ConditionType.FILTER); - typeLookup.put(STCfType.DUPLICATE_VALUES, ConditionType.FILTER); - typeLookup.put(STCfType.CONTAINS_TEXT, ConditionType.FILTER); - typeLookup.put(STCfType.NOT_CONTAINS_TEXT, ConditionType.FILTER); - typeLookup.put(STCfType.BEGINS_WITH, ConditionType.FILTER); - typeLookup.put(STCfType.ENDS_WITH, ConditionType.FILTER); - typeLookup.put(STCfType.CONTAINS_BLANKS, ConditionType.FILTER); - typeLookup.put(STCfType.NOT_CONTAINS_BLANKS, ConditionType.FILTER); - typeLookup.put(STCfType.CONTAINS_ERRORS, ConditionType.FILTER); - typeLookup.put(STCfType.NOT_CONTAINS_ERRORS, ConditionType.FILTER); - typeLookup.put(STCfType.TIME_PERIOD, ConditionType.FILTER); - typeLookup.put(STCfType.ABOVE_AVERAGE, ConditionType.FILTER); - } - - /*package*/ XSSFConditionalFormattingRule(XSSFSheet sh){ - _cfRule = CTCfRule.Factory.newInstance(); - _sh = sh; - } - - /*package*/ XSSFConditionalFormattingRule(XSSFSheet sh, CTCfRule cfRule){ - _cfRule = cfRule; - _sh = sh; - } - - /*package*/ CTCfRule getCTCfRule(){ - return _cfRule; - } - - /*package*/ CTDxf getDxf(boolean create){ - StylesTable styles = _sh.getWorkbook().getStylesSource(); - CTDxf dxf = null; - if(styles._getDXfsSize() > 0 && _cfRule.isSetDxfId()){ - int dxfId = (int)_cfRule.getDxfId(); - dxf = styles.getDxfAt(dxfId); - } - if(create && dxf == null) { - dxf = CTDxf.Factory.newInstance(); - int dxfId = styles.putDxf(dxf); - _cfRule.setDxfId(dxfId - 1); - } - return dxf; - } - - /** - * Create a new border formatting structure if it does not exist, - * otherwise just return existing object. - * - * @return - border formatting object, never returns null. - */ - public XSSFBorderFormatting createBorderFormatting(){ - CTDxf dxf = getDxf(true); - CTBorder border; - if(!dxf.isSetBorder()) { - border = dxf.addNewBorder(); - } else { - border = dxf.getBorder(); - } - - return new XSSFBorderFormatting(border); - } - - /** - * @return - border formatting object if defined, null otherwise - */ - public XSSFBorderFormatting getBorderFormatting(){ - CTDxf dxf = getDxf(false); - if(dxf == null || !dxf.isSetBorder()) return null; - - return new XSSFBorderFormatting(dxf.getBorder()); - } - - /** - * Create a new font formatting structure if it does not exist, - * otherwise just return existing object. - * - * @return - font formatting object, never returns null. - */ - public XSSFFontFormatting createFontFormatting(){ - CTDxf dxf = getDxf(true); - CTFont font; - if(!dxf.isSetFont()) { - font = dxf.addNewFont(); - } else { - font = dxf.getFont(); - } - - return new XSSFFontFormatting(font); - } - - /** - * @return - font formatting object if defined, null otherwise - */ - public XSSFFontFormatting getFontFormatting(){ - CTDxf dxf = getDxf(false); - if(dxf == null || !dxf.isSetFont()) return null; - - return new XSSFFontFormatting(dxf.getFont()); - } - - /** - * Create a new pattern formatting structure if it does not exist, - * otherwise just return existing object. - * - * @return - pattern formatting object, never returns null. - */ - public XSSFPatternFormatting createPatternFormatting(){ - CTDxf dxf = getDxf(true); - CTFill fill; - if(!dxf.isSetFill()) { - fill = dxf.addNewFill(); - } else { - fill = dxf.getFill(); - } - - return new XSSFPatternFormatting(fill); - } - - /** - * @return - pattern formatting object if defined, null otherwise - */ - public XSSFPatternFormatting getPatternFormatting(){ - CTDxf dxf = getDxf(false); - if(dxf == null || !dxf.isSetFill()) return null; - - return new XSSFPatternFormatting(dxf.getFill()); - } - - public XSSFDataBarFormatting createDataBarFormatting(XSSFColor color) { - // Is it already there? - if (_cfRule.isSetDataBar() && _cfRule.getType() == STCfType.DATA_BAR) - return getDataBarFormatting(); - - // Mark it as being a Data Bar - _cfRule.setType(STCfType.DATA_BAR); - - // Ensure the right element - CTDataBar bar = null; - if (_cfRule.isSetDataBar()) { - bar = _cfRule.getDataBar(); - } else { - bar = _cfRule.addNewDataBar(); - } - // Set the color - bar.setColor(color.getCTColor()); - - // Add the default thresholds - CTCfvo min = bar.addNewCfvo(); - min.setType(STCfvoType.Enum.forString(RangeType.MIN.name)); - CTCfvo max = bar.addNewCfvo(); - max.setType(STCfvoType.Enum.forString(RangeType.MAX.name)); - - // Wrap and return - return new XSSFDataBarFormatting(bar); - } - public XSSFDataBarFormatting getDataBarFormatting() { - if (_cfRule.isSetDataBar()) { - CTDataBar bar = _cfRule.getDataBar(); - return new XSSFDataBarFormatting(bar); - } else { - return null; - } - } - - public XSSFIconMultiStateFormatting createMultiStateFormatting(IconSet iconSet) { - // Is it already there? - if (_cfRule.isSetIconSet() && _cfRule.getType() == STCfType.ICON_SET) - return getMultiStateFormatting(); - - // Mark it as being an Icon Set - _cfRule.setType(STCfType.ICON_SET); - - // Ensure the right element - CTIconSet icons = null; - if (_cfRule.isSetIconSet()) { - icons = _cfRule.getIconSet(); - } else { - icons = _cfRule.addNewIconSet(); - } - // Set the type of the icon set - if (iconSet.name != null) { - STIconSetType.Enum xIconSet = STIconSetType.Enum.forString(iconSet.name); - icons.setIconSet(xIconSet); - } - - // Add a default set of thresholds - int jump = 100 / iconSet.num; - STCfvoType.Enum type = STCfvoType.Enum.forString(RangeType.PERCENT.name); - for (int i=0; i - * MUST be a constant from {@link org.apache.poi.ss.usermodel.ComparisonOperator} - *

        - * - * @return the conditional format operator - */ - @Override - public byte getComparisonOperation(){ - STConditionalFormattingOperator.Enum op = _cfRule.getOperator(); - if(op == null) return ComparisonOperator.NO_COMPARISON; - - switch(op.intValue()){ - case STConditionalFormattingOperator.INT_LESS_THAN: return ComparisonOperator.LT; - case STConditionalFormattingOperator.INT_LESS_THAN_OR_EQUAL: return ComparisonOperator.LE; - case STConditionalFormattingOperator.INT_GREATER_THAN: return ComparisonOperator.GT; - case STConditionalFormattingOperator.INT_GREATER_THAN_OR_EQUAL: return ComparisonOperator.GE; - case STConditionalFormattingOperator.INT_EQUAL: return ComparisonOperator.EQUAL; - case STConditionalFormattingOperator.INT_NOT_EQUAL: return ComparisonOperator.NOT_EQUAL; - case STConditionalFormattingOperator.INT_BETWEEN: return ComparisonOperator.BETWEEN; - case STConditionalFormattingOperator.INT_NOT_BETWEEN: return ComparisonOperator.NOT_BETWEEN; - } - return ComparisonOperator.NO_COMPARISON; - } - - /** - * The formula used to evaluate the first operand for the conditional formatting rule. - *

        - * If the condition type is {@link ConditionType#CELL_VALUE_IS}, - * this field is the first operand of the comparison. - * If type is {@link ConditionType#FORMULA}, this formula is used - * to determine if the conditional formatting is applied. - *

        - *

        - * If comparison type is {@link ConditionType#FORMULA} the formula MUST be a Boolean function - *

        - * - * @return the first formula - */ - public String getFormula1(){ - return _cfRule.sizeOfFormulaArray() > 0 ? _cfRule.getFormulaArray(0) : null; - } - - /** - * The formula used to evaluate the second operand of the comparison when - * comparison type is {@link ConditionType#CELL_VALUE_IS} and operator - * is either {@link org.apache.poi.ss.usermodel.ComparisonOperator#BETWEEN} or {@link org.apache.poi.ss.usermodel.ComparisonOperator#NOT_BETWEEN} - * - * @return the second formula - */ - public String getFormula2(){ - return _cfRule.sizeOfFormulaArray() == 2 ? _cfRule.getFormulaArray(1) : null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java deleted file mode 100644 index bfdd87807..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.spreadsheetml.x2006.main.CTCfvo; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfvoType; - -/** - * High level representation for Icon / Multi-State / Databar / - * Colour Scale change thresholds - */ -public class XSSFConditionalFormattingThreshold implements org.apache.poi.ss.usermodel.ConditionalFormattingThreshold { - private CTCfvo cfvo; - - protected XSSFConditionalFormattingThreshold(CTCfvo cfvo) { - this.cfvo = cfvo; - } - - protected CTCfvo getCTCfvo() { - return cfvo; - } - - public RangeType getRangeType() { - return RangeType.byName(cfvo.getType().toString()); - } - public void setRangeType(RangeType type) { - STCfvoType.Enum xtype = STCfvoType.Enum.forString(type.name); - cfvo.setType(xtype); - } - - public String getFormula() { - if (cfvo.getType() == STCfvoType.FORMULA) { - return cfvo.getVal(); - } - return null; - } - public void setFormula(String formula) { - cfvo.setVal(formula); - } - - public Double getValue() { - if (cfvo.getType() == STCfvoType.FORMULA || - cfvo.getType() == STCfvoType.MIN || - cfvo.getType() == STCfvoType.MAX) { - return null; - } - if (cfvo.isSetVal()) { - return Double.parseDouble(cfvo.getVal()); - } else { - return null; - } - } - public void setValue(Double value) { - if (value == null) { - cfvo.unsetVal(); - } else { - cfvo.setVal(value.toString()); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java deleted file mode 100644 index 7dab16c71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.CTFontReference; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.STFontCollectionIndex; -import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnectorNonVisual; -import org.apache.poi.util.Internal; - -/** - * 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; - } - - @Internal - public CTConnector getCTConnector(){ - return ctShape; - } - - /** - * Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}. - * - * @return the shape type - * @see org.apache.poi.ss.usermodel.ShapeTypes - */ - public int getShapeType() { - return ctShape.getSpPr().getPrstGeom().getPrst().intValue(); - } - - /** - * Sets the shape types. - * - * @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}. - * @see org.apache.poi.ss.usermodel.ShapeTypes - */ - public void setShapeType(int type) { - ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type)); - } - - protected CTShapeProperties getShapeProperties(){ - return ctShape.getSpPr(); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java deleted file mode 100644 index cb11a73b2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java +++ /dev/null @@ -1,102 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.common.usermodel.HyperlinkType; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; - -public class XSSFCreationHelper implements CreationHelper { - private final XSSFWorkbook workbook; - - /** - * Should only be called by {@link XSSFWorkbook#getCreationHelper()} - * - * @param wb the workbook to create objects for - */ - @Internal - public XSSFCreationHelper(XSSFWorkbook wb) { - workbook = wb; - } - - /** - * Creates a new XSSFRichTextString for you. - */ - @Override - public XSSFRichTextString createRichTextString(String text) { - XSSFRichTextString rt = new XSSFRichTextString(text); - rt.setStylesTableReference(workbook.getStylesSource()); - return rt; - } - - @Override - public XSSFDataFormat createDataFormat() { - return workbook.createDataFormat(); - } - - @Override - public XSSFColor createExtendedColor() { - return new XSSFColor(); - } - - /** - * Create a new XSSFHyperlink. - * - * @param type - the type of hyperlink to create, see {@link HyperlinkType} - * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. - */ - @Deprecated - @Removal(version="3.17") - @Override - public XSSFHyperlink createHyperlink(int type) { - return new XSSFHyperlink(type); - } - - /** - * Create a new XSSFHyperlink. - * - * @param type - the type of hyperlink to create, see {@link Hyperlink} - */ - @Override - public XSSFHyperlink createHyperlink(HyperlinkType type) { - return new XSSFHyperlink(type); - } - - /** - * Creates a XSSFFormulaEvaluator, the object that evaluates formula cells. - * - * @return a XSSFFormulaEvaluator instance - */ - @Override - public XSSFFormulaEvaluator createFormulaEvaluator() { - return new XSSFFormulaEvaluator(workbook); - } - - /** - * Creates a XSSFClientAnchor. Use this object to position drawing object in - * a sheet - * - * @return a XSSFClientAnchor instance - * @see org.apache.poi.ss.usermodel.Drawing - */ - @Override - public XSSFClientAnchor createClientAnchor() { - return new XSSFClientAnchor(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java deleted file mode 100644 index bc7b9cf71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.DataBarFormatting; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataBar; - -/** - * High level representation for DataBar / Data Bar Formatting - * component of Conditional Formatting settings - */ -public class XSSFDataBarFormatting implements DataBarFormatting { - CTDataBar _databar; - - /*package*/ XSSFDataBarFormatting(CTDataBar databar){ - _databar = databar; - } - - public boolean isIconOnly() { - if (_databar.isSetShowValue()) - return !_databar.getShowValue(); - return false; - } - public void setIconOnly(boolean only) { - _databar.setShowValue(!only); - } - - public boolean isLeftToRight() { - return true; - } - public void setLeftToRight(boolean ltr) { - // TODO How does XSSF encode this? - } - - public int getWidthMin() { - return 0; - } - public void setWidthMin(int width) { - // TODO How does XSSF encode this? - } - - public int getWidthMax() { - return 100; - } - public void setWidthMax(int width) { - // TODO How does XSSF encode this? - } - - public XSSFColor getColor() { - return new XSSFColor(_databar.getColor()); - } - public void setColor(Color color) { - _databar.setColor( ((XSSFColor)color).getCTColor() ); - } - - public XSSFConditionalFormattingThreshold getMinThreshold() { - return new XSSFConditionalFormattingThreshold(_databar.getCfvoArray(0)); - } - public XSSFConditionalFormattingThreshold getMaxThreshold() { - return new XSSFConditionalFormattingThreshold(_databar.getCfvoArray(1)); - } - - public XSSFConditionalFormattingThreshold createThreshold() { - return new XSSFConditionalFormattingThreshold(_databar.addNewCfvo()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java deleted file mode 100644 index d82524515..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.BuiltinFormats; -import org.apache.poi.ss.usermodel.DataFormat; -import org.apache.poi.util.Removal; -import org.apache.poi.xssf.model.StylesTable; - -/** - * Handles data formats for XSSF. - * - * Per Microsoft Excel 2007+ format limitations: - * Workbooks support between 200 and 250 "number formats" - * (POI calls them "data formats") So short or even byte - * would be acceptable data types to use for referring to - * data format indices. - * https://support.office.com/en-us/article/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 - * - */ -public class XSSFDataFormat implements DataFormat { - private final StylesTable stylesSource; - - protected XSSFDataFormat(StylesTable stylesSource) { - this.stylesSource = stylesSource; - } - - /** - * Get the format index that matches the given format - * string, creating a new format entry if required. - * Aliases text to the proper format as required. - * - * @param format string matching a built-in format - * @return index of format. - */ - @Override - public short getFormat(String format) { - int idx = BuiltinFormats.getBuiltinFormat(format); - if(idx == -1) idx = stylesSource.putNumberFormat(format); - return (short)idx; - } - - /** - * get the format string that matches the given format index - * @param index of a format - * @return string represented at index of format or null if there is not a format at that index - */ - @Override - public String getFormat(short index) { - // Indices used for built-in formats may be overridden with - // custom formats, such as locale-specific currency. - // See org.apache.poi.xssf.usermodel.TestXSSFDataFormat#test49928() - // or bug 49928 for an example. - // This is why we need to check stylesSource first and only fall back to - // BuiltinFormats if the format hasn't been overridden. - String fmt = stylesSource.getNumberFormatAt(index); - if(fmt == null) fmt = BuiltinFormats.getBuiltinFormat(index); - return fmt; - } - /** - * get the format string that matches the given format index - * @param index of a format - * @return string represented at index of format or null if there is not a format at that index - * - * @deprecated POI 3.16 beta 1 - use {@link #getFormat(short)} instead - */ - @Removal(version="3.18") - public String getFormat(int index) { - return getFormat((short)index); - } - - /** - * Add a number format with a specific ID into the number format style table. - * If a format with the same ID already exists, overwrite the format code - * with fmt - * This may be used to override built-in number formats. - * - * @param index the number format ID - * @param format the number format code - */ - public void putFormat(short index, String format) { - stylesSource.putNumberFormat(index, format); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java deleted file mode 100644 index c204e86a8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidation.java +++ /dev/null @@ -1,250 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationErrorStyle; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator.Enum; - -/** - * @author Radhakrishnan J - * - */ -public class XSSFDataValidation implements DataValidation { - private CTDataValidation ctDdataValidation; - private XSSFDataValidationConstraint validationConstraint; - private CellRangeAddressList regions; - - static Map operatorTypeMappings = new HashMap(); - static Map operatorTypeReverseMappings = new HashMap(); - static Map validationTypeMappings = new HashMap(); - static Map validationTypeReverseMappings = new HashMap(); - static Map errorStyleMappings = new HashMap(); - static { - errorStyleMappings.put(DataValidation.ErrorStyle.INFO, STDataValidationErrorStyle.INFORMATION); - errorStyleMappings.put(DataValidation.ErrorStyle.STOP, STDataValidationErrorStyle.STOP); - errorStyleMappings.put(DataValidation.ErrorStyle.WARNING, STDataValidationErrorStyle.WARNING); - } - - - static { - operatorTypeMappings.put(DataValidationConstraint.OperatorType.BETWEEN,STDataValidationOperator.BETWEEN); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.NOT_BETWEEN,STDataValidationOperator.NOT_BETWEEN); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.EQUAL,STDataValidationOperator.EQUAL); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.NOT_EQUAL,STDataValidationOperator.NOT_EQUAL); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.GREATER_THAN,STDataValidationOperator.GREATER_THAN); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.GREATER_OR_EQUAL,STDataValidationOperator.GREATER_THAN_OR_EQUAL); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.LESS_THAN,STDataValidationOperator.LESS_THAN); - operatorTypeMappings.put(DataValidationConstraint.OperatorType.LESS_OR_EQUAL,STDataValidationOperator.LESS_THAN_OR_EQUAL); - - for( Map.Entry entry : operatorTypeMappings.entrySet() ) { - operatorTypeReverseMappings.put(entry.getValue(),entry.getKey()); - } - } - - static { - validationTypeMappings.put(DataValidationConstraint.ValidationType.FORMULA,STDataValidationType.CUSTOM); - validationTypeMappings.put(DataValidationConstraint.ValidationType.DATE,STDataValidationType.DATE); - validationTypeMappings.put(DataValidationConstraint.ValidationType.DECIMAL,STDataValidationType.DECIMAL); - validationTypeMappings.put(DataValidationConstraint.ValidationType.LIST,STDataValidationType.LIST); - validationTypeMappings.put(DataValidationConstraint.ValidationType.ANY,STDataValidationType.NONE); - validationTypeMappings.put(DataValidationConstraint.ValidationType.TEXT_LENGTH,STDataValidationType.TEXT_LENGTH); - validationTypeMappings.put(DataValidationConstraint.ValidationType.TIME,STDataValidationType.TIME); - validationTypeMappings.put(DataValidationConstraint.ValidationType.INTEGER,STDataValidationType.WHOLE); - - for( Map.Entry entry : validationTypeMappings.entrySet() ) { - validationTypeReverseMappings.put(entry.getValue(),entry.getKey()); - } - } - - - XSSFDataValidation(CellRangeAddressList regions,CTDataValidation ctDataValidation) { - this(getConstraint(ctDataValidation), regions, ctDataValidation); - } - - public XSSFDataValidation(XSSFDataValidationConstraint constraint,CellRangeAddressList regions,CTDataValidation ctDataValidation) { - super(); - this.validationConstraint = constraint; - this.ctDdataValidation = ctDataValidation; - this.regions = regions; - } - - CTDataValidation getCtDdataValidation() { - return ctDdataValidation; - } - - - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#createErrorBox(java.lang.String, java.lang.String) - */ - public void createErrorBox(String title, String text) { - ctDdataValidation.setErrorTitle(title); - ctDdataValidation.setError(text); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#createPromptBox(java.lang.String, java.lang.String) - */ - public void createPromptBox(String title, String text) { - ctDdataValidation.setPromptTitle(title); - ctDdataValidation.setPrompt(text); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getEmptyCellAllowed() - */ - public boolean getEmptyCellAllowed() { - return ctDdataValidation.getAllowBlank(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getErrorBoxText() - */ - public String getErrorBoxText() { - return ctDdataValidation.getError(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getErrorBoxTitle() - */ - public String getErrorBoxTitle() { - return ctDdataValidation.getErrorTitle(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getErrorStyle() - */ - public int getErrorStyle() { - return ctDdataValidation.getErrorStyle().intValue(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getPromptBoxText() - */ - public String getPromptBoxText() { - return ctDdataValidation.getPrompt(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getPromptBoxTitle() - */ - public String getPromptBoxTitle() { - return ctDdataValidation.getPromptTitle(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getShowErrorBox() - */ - public boolean getShowErrorBox() { - return ctDdataValidation.getShowErrorMessage(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getShowPromptBox() - */ - public boolean getShowPromptBox() { - return ctDdataValidation.getShowInputMessage(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getSuppressDropDownArrow() - */ - public boolean getSuppressDropDownArrow() { - return !ctDdataValidation.getShowDropDown(); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#getValidationConstraint() - */ - public DataValidationConstraint getValidationConstraint() { - return validationConstraint; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#setEmptyCellAllowed(boolean) - */ - public void setEmptyCellAllowed(boolean allowed) { - ctDdataValidation.setAllowBlank(allowed); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#setErrorStyle(int) - */ - public void setErrorStyle(int errorStyle) { - ctDdataValidation.setErrorStyle(errorStyleMappings.get(errorStyle)); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#setShowErrorBox(boolean) - */ - public void setShowErrorBox(boolean show) { - ctDdataValidation.setShowErrorMessage(show); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#setShowPromptBox(boolean) - */ - public void setShowPromptBox(boolean show) { - ctDdataValidation.setShowInputMessage(show); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidation#setSuppressDropDownArrow(boolean) - */ - public void setSuppressDropDownArrow(boolean suppress) { - if (validationConstraint.getValidationType()==ValidationType.LIST) { - ctDdataValidation.setShowDropDown(!suppress); - } - } - - public CellRangeAddressList getRegions() { - return regions; - } - - public String prettyPrint() { - StringBuilder builder = new StringBuilder(); - for(CellRangeAddress address : regions.getCellRangeAddresses()) { - builder.append(address.formatAsString()); - } - builder.append(" => "); - builder.append(this.validationConstraint.prettyPrint()); - return builder.toString(); - } - - private static XSSFDataValidationConstraint getConstraint(CTDataValidation ctDataValidation) { - XSSFDataValidationConstraint constraint = null; - String formula1 = ctDataValidation.getFormula1(); - String formula2 = ctDataValidation.getFormula2(); - Enum operator = ctDataValidation.getOperator(); - org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType.Enum type = ctDataValidation.getType(); - Integer validationType = XSSFDataValidation.validationTypeReverseMappings.get(type); - Integer operatorType = XSSFDataValidation.operatorTypeReverseMappings.get(operator); - constraint = new XSSFDataValidationConstraint(validationType,operatorType, formula1,formula2); - return constraint; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidationConstraint.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidationConstraint.java deleted file mode 100644 index d42641eb8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidationConstraint.java +++ /dev/null @@ -1,246 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.Arrays; -import java.util.regex.Pattern; - -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator.Enum; - -/** - * @author Radhakrishnan J - * - */ -public class XSSFDataValidationConstraint implements DataValidationConstraint { - /** - * Excel validation constraints with static lists are delimited with optional whitespace and the Windows List Separator, - * which is typically comma, but can be changed by users. POI will just assume comma. - */ - private static final String LIST_SEPARATOR = ","; - private static final Pattern LIST_SPLIT_REGEX = Pattern.compile("\\s*" + LIST_SEPARATOR + "\\s*"); - private static final String QUOTE = "\""; - - private String formula1; - private String formula2; - private int validationType = -1; - private int operator = -1; - private String[] explicitListOfValues; - - /** - * list literal constructor - */ - public XSSFDataValidationConstraint(String[] explicitListOfValues) { - if( explicitListOfValues==null || explicitListOfValues.length==0) { - throw new IllegalArgumentException("List validation with explicit values must specify at least one value"); - } - this.validationType = ValidationType.LIST; - setExplicitListValues(explicitListOfValues); - - validate(); - } - - public XSSFDataValidationConstraint(int validationType, String formula1) { - super(); - setFormula1(formula1); - this.validationType = validationType; - validate(); - } - - - - public XSSFDataValidationConstraint(int validationType, int operator, String formula1) { - super(); - setFormula1(formula1); - this.validationType = validationType; - this.operator = operator; - validate(); - } - - /** - * This is the constructor called using the OOXML raw data. Excel overloads formula1 to also encode explicit value lists, - * so this constructor has to check for and parse that syntax. - * @param validationType - * @param operator - * @param formula1 Overloaded: formula1 or list of explicit values - * @param formula2 (formula1 is a list of explicit values, this is ignored: use null) - */ - public XSSFDataValidationConstraint(int validationType, int operator, String formula1, String formula2) { - super(); - //removes leading equals sign if present - setFormula1(formula1); - setFormula2(formula2); - this.validationType = validationType; - this.operator = operator; - - validate(); - - //FIXME: Need to confirm if this is not a formula. - // empirical testing shows Excel saves explicit lists surrounded by double quotes, - // range formula expressions can't start with quotes (I think - anyone have a creative counter example?) - if ( ValidationType.LIST == validationType - && this.formula1 != null - && isQuoted(this.formula1) ) { - explicitListOfValues = LIST_SPLIT_REGEX.split(unquote(this.formula1)); - } - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#getExplicitListValues() - */ - public String[] getExplicitListValues() { - return explicitListOfValues; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#getFormula1() - */ - public String getFormula1() { - return formula1; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#getFormula2() - */ - public String getFormula2() { - return formula2; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#getOperator() - */ - public int getOperator() { - return operator; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#getValidationType() - */ - public int getValidationType() { - return validationType; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#setExplicitListValues(java.lang.String[]) - */ - public void setExplicitListValues(String[] explicitListValues) { - this.explicitListOfValues = explicitListValues; - - // for OOXML we need to set formula1 to the quoted csv list of values (doesn't appear documented, but that's where Excel puts its lists) - // further, Excel has no escaping for commas in explicit lists, so we don't need to worry about that. - if ( explicitListOfValues!=null && explicitListOfValues.length > 0 ) { - StringBuilder builder = new StringBuilder(QUOTE); - for (int i = 0; i < explicitListValues.length; i++) { - String string = explicitListValues[i]; - if (builder.length() > 1) { - builder.append(LIST_SEPARATOR); - } - builder.append(string); - } - builder.append(QUOTE); - setFormula1(builder.toString()); - } - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#setFormula1(java.lang.String) - */ - public void setFormula1(String formula1) { - this.formula1 = removeLeadingEquals(formula1); - } - - protected static String removeLeadingEquals(String formula1) { - return isFormulaEmpty(formula1) ? formula1 : formula1.charAt(0)=='=' ? formula1.substring(1) : formula1; - } - private static boolean isQuoted(String s) { - return s.startsWith(QUOTE) && s.endsWith(QUOTE); - } - private static String unquote(String s) { - // removes leading and trailing quotes from a quoted string - if (isQuoted(s)) { - return s.substring(1, s.length()-1); - } - return s; - } - protected static boolean isFormulaEmpty(String formula1) { - return formula1 == null || formula1.trim().length()==0; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#setFormula2(java.lang.String) - */ - public void setFormula2(String formula2) { - this.formula2 = removeLeadingEquals(formula2); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationConstraint#setOperator(int) - */ - public void setOperator(int operator) { - this.operator = operator; - } - - public void validate() { - if (validationType==ValidationType.ANY) { - return; - } - - if (validationType==ValidationType.LIST ) { - if (isFormulaEmpty(formula1)) { - throw new IllegalArgumentException("A valid formula or a list of values must be specified for list validation."); - } - } else { - if( isFormulaEmpty(formula1) ) { - throw new IllegalArgumentException("Formula is not specified. Formula is required for all validation types except explicit list validation."); - } - - if( validationType!= ValidationType.FORMULA ) { - if (operator==-1) { - throw new IllegalArgumentException("This validation type requires an operator to be specified."); - } else if (( operator==OperatorType.BETWEEN || operator==OperatorType.NOT_BETWEEN) && isFormulaEmpty(formula2)) { - throw new IllegalArgumentException("Between and not between comparisons require two formulae to be specified."); - } - } - } - } - - - public String prettyPrint() { - StringBuilder builder = new StringBuilder(); - STDataValidationType.Enum vt = XSSFDataValidation.validationTypeMappings.get(validationType); - Enum ot = XSSFDataValidation.operatorTypeMappings.get(operator); - builder.append(vt); - builder.append(' '); - if (validationType!=ValidationType.ANY) { - if (validationType != ValidationType.LIST - && validationType != ValidationType.FORMULA) { - builder.append(LIST_SEPARATOR).append(ot).append(", "); - } - final String NOQUOTE = ""; - if (validationType == ValidationType.LIST && explicitListOfValues != null) { - builder.append(NOQUOTE).append(Arrays.asList(explicitListOfValues)).append(NOQUOTE).append(' '); - } else { - builder.append(NOQUOTE).append(formula1).append(NOQUOTE).append(' '); - } - if (formula2 != null) { - builder.append(NOQUOTE).append(formula2).append(NOQUOTE).append(' '); - } - } - return builder.toString(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidationHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidationHelper.java deleted file mode 100644 index 8f7908dbd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataValidationHelper.java +++ /dev/null @@ -1,177 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationErrorStyle; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType; - -/** - * @author Radhakrishnan J - * - */ -public class XSSFDataValidationHelper implements DataValidationHelper { - // Findbugs: URF_UNREAD_FIELD. Do not delete without understanding how this class works. - //private XSSFSheet xssfSheet; - - - public XSSFDataValidationHelper(XSSFSheet xssfSheet) { - super(); - // Findbugs: URF_UNREAD_FIELD. Do not delete without understanding how this class works. - //this.xssfSheet = xssfSheet; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createDateConstraint(int, java.lang.String, java.lang.String, java.lang.String) - */ - public DataValidationConstraint createDateConstraint(int operatorType, String formula1, String formula2, String dateFormat) { - return new XSSFDataValidationConstraint(ValidationType.DATE, operatorType,formula1, formula2); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createDecimalConstraint(int, java.lang.String, java.lang.String) - */ - public DataValidationConstraint createDecimalConstraint(int operatorType, String formula1, String formula2) { - return new XSSFDataValidationConstraint(ValidationType.DECIMAL, operatorType,formula1, formula2); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createExplicitListConstraint(java.lang.String[]) - */ - public DataValidationConstraint createExplicitListConstraint(String[] listOfValues) { - return new XSSFDataValidationConstraint(listOfValues); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createFormulaListConstraint(java.lang.String) - */ - public DataValidationConstraint createFormulaListConstraint(String listFormula) { - return new XSSFDataValidationConstraint(ValidationType.LIST, listFormula); - } - - - - public DataValidationConstraint createNumericConstraint(int validationType, int operatorType, String formula1, String formula2) { - if( validationType==ValidationType.INTEGER) { - return createIntegerConstraint(operatorType, formula1, formula2); - } else if ( validationType==ValidationType.DECIMAL) { - return createDecimalConstraint(operatorType, formula1, formula2); - } else if ( validationType==ValidationType.TEXT_LENGTH) { - return createTextLengthConstraint(operatorType, formula1, formula2); - } - return null; - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createIntegerConstraint(int, java.lang.String, java.lang.String) - */ - public DataValidationConstraint createIntegerConstraint(int operatorType, String formula1, String formula2) { - return new XSSFDataValidationConstraint(ValidationType.INTEGER, operatorType,formula1,formula2); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createTextLengthConstraint(int, java.lang.String, java.lang.String) - */ - public DataValidationConstraint createTextLengthConstraint(int operatorType, String formula1, String formula2) { - return new XSSFDataValidationConstraint(ValidationType.TEXT_LENGTH, operatorType,formula1,formula2); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createTimeConstraint(int, java.lang.String, java.lang.String, java.lang.String) - */ - public DataValidationConstraint createTimeConstraint(int operatorType, String formula1, String formula2) { - return new XSSFDataValidationConstraint(ValidationType.TIME, operatorType,formula1,formula2); - } - - public DataValidationConstraint createCustomConstraint(String formula) { - return new XSSFDataValidationConstraint(ValidationType.FORMULA, formula); - } - - /* (non-Javadoc) - * @see org.apache.poi.ss.usermodel.DataValidationHelper#createValidation(org.apache.poi.ss.usermodel.DataValidationConstraint, org.apache.poi.ss.util.CellRangeAddressList) - */ - public DataValidation createValidation(DataValidationConstraint constraint, CellRangeAddressList cellRangeAddressList) { - XSSFDataValidationConstraint dataValidationConstraint = (XSSFDataValidationConstraint)constraint; - CTDataValidation newDataValidation = CTDataValidation.Factory.newInstance(); - - int validationType = constraint.getValidationType(); - switch(validationType) { - case DataValidationConstraint.ValidationType.LIST: - newDataValidation.setType(STDataValidationType.LIST); - newDataValidation.setFormula1(constraint.getFormula1()); - break; - case DataValidationConstraint.ValidationType.ANY: - newDataValidation.setType(STDataValidationType.NONE); - break; - case DataValidationConstraint.ValidationType.TEXT_LENGTH: - newDataValidation.setType(STDataValidationType.TEXT_LENGTH); - break; - case DataValidationConstraint.ValidationType.DATE: - newDataValidation.setType(STDataValidationType.DATE); - break; - case DataValidationConstraint.ValidationType.INTEGER: - newDataValidation.setType(STDataValidationType.WHOLE); - break; - case DataValidationConstraint.ValidationType.DECIMAL: - newDataValidation.setType(STDataValidationType.DECIMAL); - break; - case DataValidationConstraint.ValidationType.TIME: - newDataValidation.setType(STDataValidationType.TIME); - break; - case DataValidationConstraint.ValidationType.FORMULA: - newDataValidation.setType(STDataValidationType.CUSTOM); - break; - default: - newDataValidation.setType(STDataValidationType.NONE); - } - - if (validationType!=ValidationType.ANY && validationType!=ValidationType.LIST) { - STDataValidationOperator.Enum op = XSSFDataValidation.operatorTypeMappings.get(constraint.getOperator()); - if(op != null) { - newDataValidation.setOperator(op); - } - if (constraint.getFormula1() != null) { - newDataValidation.setFormula1(constraint.getFormula1()); - } - if (constraint.getFormula2() != null) { - newDataValidation.setFormula2(constraint.getFormula2()); - } - } - - CellRangeAddress[] cellRangeAddresses = cellRangeAddressList.getCellRangeAddresses(); - List sqref = new ArrayList(); - for (int i = 0; i < cellRangeAddresses.length; i++) { - CellRangeAddress cellRangeAddress = cellRangeAddresses[i]; - sqref.add(cellRangeAddress.formatAsString()); - } - newDataValidation.setSqref(sqref); - newDataValidation.setAllowBlank(true); - newDataValidation.setErrorStyle(STDataValidationErrorStyle.STOP); - - return new XSSFDataValidation(dataValidationConstraint,cellRangeAddressList,newDataValidation); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java deleted file mode 100644 index 388577061..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.Sheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; - -//YK: TODO: this is only a prototype -public class XSSFDialogsheet extends XSSFSheet implements Sheet{ - protected CTDialogsheet dialogsheet; - - protected XSSFDialogsheet(XSSFSheet sheet, PackageRelationship rel) { - super(sheet.getPackagePart(), rel); - this.dialogsheet = CTDialogsheet.Factory.newInstance(); - this.worksheet = CTWorksheet.Factory.newInstance(); - } - - public XSSFRow createRow(int rowNum) { - return null; - } - - protected CTHeaderFooter getSheetTypeHeaderFooter() { - if (dialogsheet.getHeaderFooter() == null) { - dialogsheet.setHeaderFooter(CTHeaderFooter.Factory.newInstance()); - } - return dialogsheet.getHeaderFooter(); - } - - protected CTSheetPr getSheetTypeSheetPr() { - if (dialogsheet.getSheetPr() == null) { - dialogsheet.setSheetPr(CTSheetPr.Factory.newInstance()); - } - return dialogsheet.getSheetPr(); - } - - protected CTPageBreak getSheetTypeColumnBreaks() { - return null; - } - - protected CTSheetFormatPr getSheetTypeSheetFormatPr() { - if (dialogsheet.getSheetFormatPr() == null) { - dialogsheet.setSheetFormatPr(CTSheetFormatPr.Factory.newInstance()); - } - return dialogsheet.getSheetFormatPr(); - } - - protected CTPageMargins getSheetTypePageMargins() { - if (dialogsheet.getPageMargins() == null) { - dialogsheet.setPageMargins(CTPageMargins.Factory.newInstance()); - } - return dialogsheet.getPageMargins(); - } - - protected CTPageBreak getSheetTypeRowBreaks() { - return null; - } - - protected CTSheetViews getSheetTypeSheetViews() { - if (dialogsheet.getSheetViews() == null) { - dialogsheet.setSheetViews(CTSheetViews.Factory.newInstance()); - dialogsheet.getSheetViews().addNewSheetView(); - } - return dialogsheet.getSheetViews(); - } - - protected CTPrintOptions getSheetTypePrintOptions() { - if (dialogsheet.getPrintOptions() == null) { - dialogsheet.setPrintOptions(CTPrintOptions.Factory.newInstance()); - } - return dialogsheet.getPrintOptions(); - } - - protected CTSheetProtection getSheetTypeProtection() { - if (dialogsheet.getSheetProtection() == null) { - dialogsheet.setSheetProtection(CTSheetProtection.Factory.newInstance()); - } - return dialogsheet.getSheetProtection(); - } - - public boolean getDialog(){ - return true; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java deleted file mode 100644 index 8b70d712a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ /dev/null @@ -1,435 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs; - -/** - * Represents a SpreadsheetML drawing - */ -public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { - /** - * Root element of the SpreadsheetML Drawing part - */ - private CTDrawing drawing; - private long numOfGraphicFrames = 0L; - - protected static final String NAMESPACE_A = XSSFRelation.NS_DRAWINGML; - protected static final String NAMESPACE_C = XSSFRelation.NS_CHART; - - /** - * Create a new SpreadsheetML drawing - * - * @see org.apache.poi.xssf.usermodel.XSSFSheet#createDrawingPatriarch() - */ - protected XSSFDrawing() { - super(); - drawing = newDrawing(); - } - - /** - * Construct a SpreadsheetML drawing from a package part - * - * @param part the package part holding the drawing data, - * the content type must be application/vnd.openxmlformats-officedocument.drawing+xml - * - * @since POI 3.14-Beta1 - */ - public XSSFDrawing(PackagePart part) throws IOException, XmlException { - super(part); - XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS); - //Removing root element - options.setLoadReplaceDocumentElement(null); - drawing = CTDrawing.Factory.parse(part.getInputStream(),options); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - /** - * 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 - */ - @Internal - 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: - - */ - xmlOptions.setSaveSyntheticDocumentElement( - new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr") - ); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - drawing.save(out, xmlOptions); - out.close(); - } - - @Override - public XSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, - int col1, int row1, int col2, int row2) { - return new XSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2); - } - - /** - * 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){ - long shapeId = newShapeId(); - CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); - CTShape ctShape = ctAnchor.addNewSp(); - ctShape.set(XSSFSimpleShape.prototype()); - ctShape.getNvSpPr().getCNvPr().setId(shapeId); - 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); - - long shapeId = newShapeId(); - CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); - CTPicture ctShape = ctAnchor.addNewPic(); - ctShape.set(XSSFPicture.prototype()); - - ctShape.getNvPicPr().getCNvPr().setId(shapeId); - - XSSFPicture shape = new XSSFPicture(this, ctShape); - shape.anchor = anchor; - shape.setPictureReference(rel); - return shape; - } - - @Override - public XSSFPicture createPicture(ClientAnchor anchor, int pictureIndex){ - return createPicture((XSSFClientAnchor)anchor, pictureIndex); - } - - /** - * Creates a chart. - * @param anchor the client anchor describes how this chart is attached to - * the sheet. - * @return the newly created chart - * @see org.apache.poi.xssf.usermodel.XSSFDrawing#createChart(ClientAnchor) - */ - public XSSFChart createChart(XSSFClientAnchor anchor) { - int chartNumber = getPackagePart().getPackage(). - getPartsByContentType(XSSFRelation.CHART.getContentType()).size() + 1; - - RelationPart rp = createRelationship( - XSSFRelation.CHART, XSSFFactory.getInstance(), chartNumber, false); - XSSFChart chart = rp.getDocumentPart(); - String chartRelId = rp.getRelationship().getId(); - - XSSFGraphicFrame frame = createGraphicFrame(anchor); - frame.setChart(chart, chartRelId); - - return chart; - } - - @Override - public XSSFChart createChart(ClientAnchor anchor) { - return createChart((XSSFClientAnchor)anchor); - } - - /** - * 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()} . - */ - @SuppressWarnings("resource") - protected PackageRelationship addPictureReference(int pictureIndex){ - XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent(); - XSSFPictureData data = wb.getAllPictures().get(pictureIndex); - XSSFPictureData pic = new XSSFPictureData(data.getPackagePart()); - RelationPart rp = addRelation(null, XSSFRelation.IMAGES, pic); - return rp.getRelationship(); - } - - /** - * 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) - { - long shapeId = newShapeId(); - CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); - CTShape ctShape = ctAnchor.addNewSp(); - ctShape.set(XSSFSimpleShape.prototype()); - ctShape.getNvSpPr().getCNvPr().setId(shapeId); - 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; - } - - /** - * Creates a comment. - * @param anchor the client anchor describes how this comment is attached - * to the sheet. - * @return the newly created comment. - */ - @Override - public XSSFComment createCellComment(ClientAnchor anchor) { - XSSFClientAnchor ca = (XSSFClientAnchor)anchor; - XSSFSheet sheet = (XSSFSheet)getParent(); - - //create comments and vmlDrawing parts if they don't exist - CommentsTable comments = sheet.getCommentsTable(true); - XSSFVMLDrawing vml = sheet.getVMLDrawing(true); - com.microsoft.schemas.vml.CTShape vmlShape = vml.newCommentShape(); - if(ca.isSet()){ - // convert offsets from emus to pixels since we get a DrawingML-anchor - // but create a VML Drawing - int dx1Pixels = ca.getDx1()/Units.EMU_PER_PIXEL; - int dy1Pixels = ca.getDy1()/Units.EMU_PER_PIXEL; - int dx2Pixels = ca.getDx2()/Units.EMU_PER_PIXEL; - int dy2Pixels = ca.getDy2()/Units.EMU_PER_PIXEL; - String position = - ca.getCol1() + ", " + dx1Pixels + ", " + - ca.getRow1() + ", " + dy1Pixels + ", " + - ca.getCol2() + ", " + dx2Pixels + ", " + - ca.getRow2() + ", " + dy2Pixels; - vmlShape.getClientDataArray(0).setAnchorArray(0, position); - } - CellAddress ref = new CellAddress(ca.getRow1(), ca.getCol1()); - - if(comments.findCellComment(ref) != null) { - throw new IllegalArgumentException("Multiple cell comments in one cell are not allowed, cell: " + ref); - } - - return new XSSFComment(comments, comments.newComment(ref), vmlShape); - } - - /** - * Creates a new graphic frame. - * - * @param anchor the client anchor describes how this frame is attached - * to the sheet - * @return the newly created graphic frame - */ - private XSSFGraphicFrame createGraphicFrame(XSSFClientAnchor anchor) { - CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); - CTGraphicalObjectFrame ctGraphicFrame = ctAnchor.addNewGraphicFrame(); - ctGraphicFrame.set(XSSFGraphicFrame.prototype()); - - long frameId = numOfGraphicFrames++; - XSSFGraphicFrame graphicFrame = new XSSFGraphicFrame(this, ctGraphicFrame); - graphicFrame.setAnchor(anchor); - graphicFrame.setId(frameId); - graphicFrame.setName("Diagramm" + frameId); - return graphicFrame; - } - - /** - * Returns all charts in this drawing. - */ - public List getCharts() { - List charts = new ArrayList(); - for(POIXMLDocumentPart part : getRelations()) { - if(part instanceof XSSFChart) { - charts.add((XSSFChart)part); - } - } - return charts; - } - - /** - * 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 DONT_MOVE_AND_RESIZE: aditAs = STEditAs.ABSOLUTE; break; - case MOVE_AND_RESIZE: aditAs = STEditAs.TWO_CELL; break; - case MOVE_DONT_RESIZE: aditAs = STEditAs.ONE_CELL; break; - default: aditAs = STEditAs.ONE_CELL; - } - ctAnchor.setEditAs(aditAs); - return ctAnchor; - } - - private long newShapeId(){ - return drawing.sizeOfTwoCellAnchorArray() + 1; - } - - /** - * - * @return list of shapes in this drawing - */ - public List getShapes(){ - List lst = new ArrayList(); - for(XmlObject obj : drawing.selectPath("./*/*")) { - XSSFShape shape = null; - if(obj instanceof CTPicture) shape = new XSSFPicture(this, (CTPicture)obj) ; - else if(obj instanceof CTConnector) shape = new XSSFConnector(this, (CTConnector)obj) ; - else if(obj instanceof CTShape) shape = new XSSFSimpleShape(this, (CTShape)obj) ; - else if(obj instanceof CTGraphicalObjectFrame) shape = new XSSFGraphicFrame(this, (CTGraphicalObjectFrame)obj) ; - else if(obj instanceof CTGroupShape) shape = new XSSFShapeGroup(this, (CTGroupShape)obj) ; - - if(shape != null){ - shape.anchor = getAnchorFromParent(obj); - lst.add(shape); - } - } - return lst; - } - - - private XSSFAnchor getAnchorFromParent(XmlObject obj){ - XSSFAnchor anchor = null; - - XmlObject parentXbean = null; - XmlCursor cursor = obj.newCursor(); - if(cursor.toParent()) parentXbean = cursor.getObject(); - cursor.dispose(); - if(parentXbean != null){ - if (parentXbean instanceof CTTwoCellAnchor) { - CTTwoCellAnchor ct = (CTTwoCellAnchor)parentXbean; - anchor = new XSSFClientAnchor(ct.getFrom(), ct.getTo()); - } else if (parentXbean instanceof CTOneCellAnchor) { - CTOneCellAnchor ct = (CTOneCellAnchor)parentXbean; - anchor = new XSSFClientAnchor(ct.getFrom(), CTMarker.Factory.newInstance()); - } - } - return anchor; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java deleted file mode 100644 index 129052e79..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java +++ /dev/null @@ -1,120 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.util.Internal; - -/** - * XSSF wrapper for a cell under evaluation - */ -final class XSSFEvaluationCell implements EvaluationCell { - - private final EvaluationSheet _evalSheet; - private final XSSFCell _cell; - - public XSSFEvaluationCell(XSSFCell cell, XSSFEvaluationSheet evaluationSheet) { - _cell = cell; - _evalSheet = evaluationSheet; - } - - public XSSFEvaluationCell(XSSFCell cell) { - this(cell, new XSSFEvaluationSheet(cell.getSheet())); - } - - @Override - public Object getIdentityKey() { - // save memory by just using the cell itself as the identity key - // Note - this assumes XSSFCell has not overridden hashCode and equals - return _cell; - } - - public XSSFCell getXSSFCell() { - return _cell; - } - @Override - public boolean getBooleanCellValue() { - return _cell.getBooleanCellValue(); - } -/** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type - * @deprecated 3.15. Will return a {@link CellType} enum in the future. - */ - @Override - public int getCellType() { - return _cell.getCellType(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType getCellTypeEnum() { - return _cell.getCellTypeEnum(); - } - @Override - public int getColumnIndex() { - return _cell.getColumnIndex(); - } - @Override - public int getErrorCellValue() { - return _cell.getErrorCellValue(); - } - @Override - public double getNumericCellValue() { - return _cell.getNumericCellValue(); - } - @Override - public int getRowIndex() { - return _cell.getRowIndex(); - } - @Override - public EvaluationSheet getSheet() { - return _evalSheet; - } - @Override - public String getStringCellValue() { - return _cell.getRichStringCellValue().getString(); - } - /** - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * - * @return cell type of cached formula result - */ - @Override - public int getCachedFormulaResultType() { - return _cell.getCachedFormulaResultType(); - } - /** - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. - * Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Internal(since="POI 3.15 beta 3") - @Override - public CellType getCachedFormulaResultTypeEnum() { - return _cell.getCachedFormulaResultTypeEnum(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java deleted file mode 100644 index fb042afaf..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java +++ /dev/null @@ -1,122 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.util.Internal; - -/** - * XSSF wrapper for a sheet under evaluation - */ -@Internal -final class XSSFEvaluationSheet implements EvaluationSheet { - - private final XSSFSheet _xs; - private Map _cellCache; - - public XSSFEvaluationSheet(XSSFSheet sheet) { - _xs = sheet; - } - - public XSSFSheet getXSSFSheet() { - return _xs; - } - - /* (non-JavaDoc), inherit JavaDoc from EvaluationWorkbook - * @since POI 3.15 beta 3 - */ - @Override - public void clearAllCachedResultValues() { - _cellCache = null; - } - - @Override - public EvaluationCell getCell(int rowIndex, int columnIndex) { - // cache for performance: ~30% speedup due to caching - if (_cellCache == null) { - _cellCache = new HashMap(_xs.getLastRowNum()*3); - for (final Row row : _xs) { - final int rowNum = row.getRowNum(); - for (final Cell cell : row) { - // cast is safe, the iterator is just defined using the interface - final CellKey key = new CellKey(rowNum, cell.getColumnIndex()); - final EvaluationCell evalcell = new XSSFEvaluationCell((XSSFCell) cell, this); - _cellCache.put(key, evalcell); - } - } - } - - final CellKey key = new CellKey(rowIndex, columnIndex); - EvaluationCell evalcell = _cellCache.get(key); - - // If cache is stale, update cache with this one cell - // This is a compromise between rebuilding the entire cache - // (which would quickly defeat the benefit of the cache) - // and not caching at all. - // See bug 59958: Add cells on the fly to the evaluation sheet cache on cache miss - if (evalcell == null) { - XSSFRow row = _xs.getRow(rowIndex); - if (row == null) { - return null; - } - XSSFCell cell = row.getCell(columnIndex); - if (cell == null) { - return null; - } - evalcell = new XSSFEvaluationCell(cell, this); - _cellCache.put(key, evalcell); - } - - return evalcell; - } - - private static class CellKey { - private final int _row; - private final int _col; - private int _hash = -1; //lazily computed - - protected CellKey(int row, int col) { - _row = row; - _col = col; - } - - @Override - public int hashCode() { - if ( _hash == -1 ) { - _hash = (17 * 37 + _row) * 37 + _col; - } - return _hash; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CellKey)) { - return false; - } - // assumes other object is one of us, otherwise ClassCastException is thrown - final CellKey oKey = (CellKey) obj; - return _row == oKey._row && _col == oKey._col; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java deleted file mode 100644 index 2c13f8266..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.util.Internal; - -/** - * Internal POI use only - */ -@Internal -public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook { - private XSSFEvaluationSheet[] _sheetCache; - - public static XSSFEvaluationWorkbook create(XSSFWorkbook book) { - if (book == null) { - return null; - } - return new XSSFEvaluationWorkbook(book); - } - - private XSSFEvaluationWorkbook(XSSFWorkbook book) { - super(book); - } - - /* (non-JavaDoc), inherit JavaDoc from EvaluationSheet - * @since POI 3.15 beta 3 - */ - @Override - public void clearAllCachedResultValues() { - super.clearAllCachedResultValues(); - _sheetCache = null; - } - - @Override - public int getSheetIndex(EvaluationSheet evalSheet) { - XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet(); - return _uBook.getSheetIndex(sheet); - } - - @Override - public EvaluationSheet getSheet(int sheetIndex) { - // Performance optimization: build sheet cache the first time this is called - // to avoid re-creating the XSSFEvaluationSheet each time a new cell is evaluated - // EvaluationWorkbooks make not guarantee to synchronize changes made to - // the underlying workbook after the EvaluationWorkbook is created. - if (_sheetCache == null) { - final int numberOfSheets = _uBook.getNumberOfSheets(); - _sheetCache = new XSSFEvaluationSheet[numberOfSheets]; - for (int i=0; i < numberOfSheets; i++) { - _sheetCache[i] = new XSSFEvaluationSheet(_uBook.getSheetAt(i)); - } - } - if (sheetIndex < 0 || sheetIndex >= _sheetCache.length) { - // do this to reuse the out-of-bounds logic and message from XSSFWorkbook - _uBook.getSheetAt(sheetIndex); - } - return _sheetCache[sheetIndex]; - } - - @Override - public Ptg[] getFormulaTokens(EvaluationCell evalCell) { - final XSSFCell cell = ((XSSFEvaluationCell)evalCell).getXSSFCell(); - final int sheetIndex = _uBook.getSheetIndex(cell.getSheet()); - final int rowIndex = cell.getRowIndex(); - return FormulaParser.parse(cell.getCellFormula(this), this, FormulaType.CELL, sheetIndex, rowIndex); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvenFooter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvenFooter.java deleted file mode 100644 index 9dd28daf2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvenFooter.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Footer; -import org.apache.poi.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - * - * Even page footer value. Corresponds to even printed pages. - * Even page(s) in the sheet may not be printed, for example, if the print area is specified to be - * a range such that it falls outside an even page's scope. - * If no even footer is specified, then the odd footer's value is assumed for even page footers. - * - */ -public class XSSFEvenFooter extends XSSFHeaderFooter implements Footer{ - - /** - * Create an instance of XSSFEvenFooter from the supplied XML bean - * @see XSSFSheet#getEvenFooter() - * @param headerFooter - */ - public XSSFEvenFooter(CTHeaderFooter headerFooter) { - super(headerFooter); - headerFooter.setDifferentOddEven(true); - } - - /** - * Get the content text representing the footer - * @return text - */ - public String getText() { - return getHeaderFooter().getEvenFooter(); - } - - /** - * Set a text for the footer. If null unset the value. - * @see XSSFHeaderFooter to see how to create a string with Header/Footer Formatting Syntax - * @param text - a string representing the footer. - */ - public void setText(String text) { - if(text == null) { - getHeaderFooter().unsetEvenFooter(); - } else { - getHeaderFooter().setEvenFooter(text); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvenHeader.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvenHeader.java deleted file mode 100644 index 1bf9555fc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvenHeader.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Header; -import org.apache.poi.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - *

        - * Even page header value. Corresponds to even printed pages. - * Even page(s) in the sheet may not be printed, for example, if the print area is specified to be - * a range such that it falls outside an even page's scope. - * If no even header is specified, then odd header value is assumed for even page headers. - *

        - * - */ -public class XSSFEvenHeader extends XSSFHeaderFooter implements Header{ - - /** - * Create an instance of XSSFEvenHeader from the supplied XML bean - * @see XSSFSheet#getEvenHeader() - * @param headerFooter - */ - public XSSFEvenHeader(CTHeaderFooter headerFooter) { - super(headerFooter); - headerFooter.setDifferentOddEven(true); - } - - /** - * Get the content text representing this header - * @return text - */ - public String getText() { - return getHeaderFooter().getEvenHeader(); - } - - /** - * Set a text for the header. If null unset the value - * @see XSSFHeaderFooter to see how to create a string with Header/Footer Formatting Syntax - * @param text - a string representing the header. - */ - public void setText(String text) { - if(text == null) { - getHeaderFooter().unsetEvenHeader(); - } else { - getHeaderFooter().setEvenHeader(text); - } - } - - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java deleted file mode 100644 index 763b094f9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLFactory; -import org.apache.poi.POIXMLRelation; - -/** - * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - */ -public final class XSSFFactory extends POIXMLFactory { - private XSSFFactory() { - } - - private static final XSSFFactory inst = new XSSFFactory(); - - public static XSSFFactory getInstance(){ - return inst; - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLRelation getDescriptor(String relationshipType) { - return XSSFRelation.getInstance(relationshipType); - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLDocumentPart createDocumentPart - (Class cls, Class[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Constructor constructor = cls.getDeclaredConstructor(classes); - return constructor.newInstance(values); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFirstFooter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFirstFooter.java deleted file mode 100644 index b0f2cb517..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFirstFooter.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Footer; -import org.apache.poi.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - * - * First page footer content. Corresponds to first printed page. - * The first logical page in the sheet may not be printed, for example, if the print area is specified to - * be a range such that it falls outside the first page's scope. - * - */ -public class XSSFFirstFooter extends XSSFHeaderFooter implements Footer{ - - /** - * Create an instance of XSSFFirstFooter from the supplied XML bean - * @see XSSFSheet#getFirstFooter() - * @param headerFooter - */ - protected XSSFFirstFooter(CTHeaderFooter headerFooter) { - super(headerFooter); - headerFooter.setDifferentFirst(true); - } - - /** - * Get the content text representing the footer - * @return text - */ - public String getText() { - return getHeaderFooter().getFirstFooter(); - } - - /** - * Set a text for the footer. If null unset the value. - * @see XSSFHeaderFooter to see how to create a string with Header/Footer Formatting Syntax - * @param text - a string representing the footer. - */ - public void setText(String text) { - if(text == null) { - getHeaderFooter().unsetFirstFooter(); - } else { - getHeaderFooter().setFirstFooter(text); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFirstHeader.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFirstHeader.java deleted file mode 100644 index 9ffd45781..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFirstHeader.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Header; -import org.apache.poi.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - * - * First page header content. Corresponds to first printed page. - * The first logical page in the sheet may not be printed, for example, if the print area is specified to - * be a range such that it falls outside the first page's scope. - * - */ -public class XSSFFirstHeader extends XSSFHeaderFooter implements Header{ - - /** - * Create an instance of XSSFFirstHeader from the supplied XML bean - * @see XSSFSheet#getFirstHeader() - * @param headerFooter - */ - protected XSSFFirstHeader(CTHeaderFooter headerFooter) { - super(headerFooter); - headerFooter.setDifferentFirst(true); - } - - /** - * Get the content text representing this header - * @return text - */ - public String getText() { - return getHeaderFooter().getFirstHeader(); - } - - /** - * Set a text for the header. If null unset the value - * @see XSSFHeaderFooter to see how to create a string with Header/Footer Formatting Syntax - * @param text - a string representing the header. - */ - public void setText(String text) { - if(text == null) { - getHeaderFooter().unsetFirstHeader(); - } else { - getHeaderFooter().setFirstHeader(text); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFont.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFont.java deleted file mode 100644 index bdbbf7478..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFont.java +++ /dev/null @@ -1,650 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.POIXMLException; -import org.apache.poi.util.Internal; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.FontCharset; -import org.apache.poi.ss.usermodel.FontFamily; -import org.apache.poi.ss.usermodel.FontScheme; -import org.apache.poi.ss.usermodel.FontUnderline; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.model.ThemesTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontScheme; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIntProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFontScheme; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun; - -/** - * Represents a font used in a workbook. - * - * @author Gisella Bronzetti - */ -public class XSSFFont implements Font { - - /** - * By default, Microsoft Office Excel 2007 uses the Calibry font in font size 11 - */ - public static final String DEFAULT_FONT_NAME = "Calibri"; - /** - * By default, Microsoft Office Excel 2007 uses the Calibry font in font size 11 - */ - public static final short DEFAULT_FONT_SIZE = 11; - /** - * Default font color is black - * @see org.apache.poi.ss.usermodel.IndexedColors#BLACK - */ - public static final short DEFAULT_FONT_COLOR = IndexedColors.BLACK.getIndex(); - - private ThemesTable _themes; - private CTFont _ctFont; - private short _index; - - /** - * Create a new XSSFFont - * - * @param font the underlying CTFont bean - */ - public XSSFFont(CTFont font) { - _ctFont = font; - _index = 0; - } - - public XSSFFont(CTFont font, int index) { - _ctFont = font; - _index = (short)index; - } - - /** - * Create a new XSSFont. This method is protected to be used only by XSSFWorkbook - */ - protected XSSFFont() { - this._ctFont = CTFont.Factory.newInstance(); - setFontName(DEFAULT_FONT_NAME); - setFontHeight((double)DEFAULT_FONT_SIZE); - } - - /** - * get the underlying CTFont font - */ - @Internal - public CTFont getCTFont() { - return _ctFont; - } - - /** - * get a boolean value for the boldness to use. - * - * @return boolean - bold - */ - public boolean getBold() { - CTBooleanProperty bold = _ctFont.sizeOfBArray() == 0 ? null : _ctFont.getBArray(0); - return (bold != null && bold.getVal()); - } - - /** - * get character-set to use. - * - * @return int - character-set (0-255) - * @see org.apache.poi.ss.usermodel.FontCharset - */ - public int getCharSet() { - CTIntProperty charset = _ctFont.sizeOfCharsetArray() == 0 ? null : _ctFont.getCharsetArray(0); - int val = charset == null ? FontCharset.ANSI.getValue() : FontCharset.valueOf(charset.getVal()).getValue(); - return val; - } - - - /** - * get the indexed color value for the font - * References a color defined in IndexedColors. - * - * @return short - indexed color to use - * @see IndexedColors - */ - public short getColor() { - CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); - if (color == null) return IndexedColors.BLACK.getIndex(); - - long index = color.getIndexed(); - if (index == XSSFFont.DEFAULT_FONT_COLOR) { - return IndexedColors.BLACK.getIndex(); - } else if (index == IndexedColors.RED.getIndex()) { - return IndexedColors.RED.getIndex(); - } else { - return (short)index; - } - } - - - /** - * get the color value for the font - * References a color defined as Standard Alpha Red Green Blue color value (ARGB). - * - * @return XSSFColor - rgb color to use - */ - public XSSFColor getXSSFColor() { - CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); - if(ctColor != null) { - XSSFColor color = new XSSFColor(ctColor); - if(_themes != null) { - _themes.inheritFromThemeAsRequired(color); - } - return color; - } else { - return null; - } - } - - - /** - * get the color value for the font - * References a color defined in theme. - * - * @return short - theme defined to use - */ - public short getThemeColor() { - CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); - long index = color == null ? 0 : color.getTheme(); - return (short) index; - } - - /** - * Get the font height in unit's of 1/20th of a point. - *

        - * For many users, the related {@link #getFontHeightInPoints()} - * will be more helpful, as that returns font heights in the - * more familiar points units, eg 10, 12, 14. - - * @return short - height in 1/20ths of a point - * @see #getFontHeightInPoints() - */ - public short getFontHeight() { - return (short)(getFontHeightRaw()*20); - } - - /** - * Get the font height in points. - *

        - * This will return the same font height that is shown in Excel, - * such as 10 or 14 or 28. - * @return short - height in the familiar unit of measure - points - * @see #getFontHeight() - */ - public short getFontHeightInPoints() { - return (short)getFontHeightRaw(); - } - - /** - * Return the raw font height, in points, but also - * including fractions. - */ - private double getFontHeightRaw() { - CTFontSize size = _ctFont.sizeOfSzArray() == 0 ? null : _ctFont.getSzArray(0); - if (size != null) { - double fontHeight = size.getVal(); - return fontHeight; - } - return DEFAULT_FONT_SIZE; - } - - /** - * get the name of the font (i.e. Arial) - * - * @return String - a string representing the name of the font to use - */ - public String getFontName() { - CTFontName name = _ctFont.sizeOfNameArray() == 0 ? null : _ctFont.getNameArray(0); - return name == null ? DEFAULT_FONT_NAME : name.getVal(); - } - - /** - * get a boolean value that specify whether to use italics or not - * - * @return boolean - value for italic - */ - public boolean getItalic() { - CTBooleanProperty italic = _ctFont.sizeOfIArray() == 0 ? null : _ctFont.getIArray(0); - return italic != null && italic.getVal(); - } - - /** - * get a boolean value that specify whether to use a strikeout horizontal line through the text or not - * - * @return boolean - value for strikeout - */ - public boolean getStrikeout() { - CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? null : _ctFont.getStrikeArray(0); - return strike != null && strike.getVal(); - } - - /** - * get normal,super or subscript. - * - * @return short - offset type to use (none,super,sub) - * @see Font#SS_NONE - * @see Font#SS_SUPER - * @see Font#SS_SUB - */ - public short getTypeOffset() { - CTVerticalAlignFontProperty vAlign = _ctFont.sizeOfVertAlignArray() == 0 ? null : _ctFont.getVertAlignArray(0); - if (vAlign == null) { - return Font.SS_NONE; - } - int val = vAlign.getVal().intValue(); - switch (val) { - case STVerticalAlignRun.INT_BASELINE: - return Font.SS_NONE; - case STVerticalAlignRun.INT_SUBSCRIPT: - return Font.SS_SUB; - case STVerticalAlignRun.INT_SUPERSCRIPT: - return Font.SS_SUPER; - default: - throw new POIXMLException("Wrong offset value " + val); - } - } - - /** - * get type of text underlining to use - * - * @return byte - underlining type - * @see org.apache.poi.ss.usermodel.FontUnderline - */ - public byte getUnderline() { - CTUnderlineProperty underline = _ctFont.sizeOfUArray() == 0 ? null : _ctFont.getUArray(0); - if (underline != null) { - FontUnderline val = FontUnderline.valueOf(underline.getVal().intValue()); - return val.getByteValue(); - } - return Font.U_NONE; - } - - /** - * set a boolean value for the boldness to use. If omitted, the default value is true. - * - * @param bold - boldness to use - */ - public void setBold(boolean bold) { - if(bold){ - CTBooleanProperty ctBold = _ctFont.sizeOfBArray() == 0 ? _ctFont.addNewB() : _ctFont.getBArray(0); - ctBold.setVal(bold); - } else { - _ctFont.setBArray(null); - } - } - - /** - * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. Use {@link #setBold(boolean)} instead. - */ - public void setBoldweight(short boldweight) - { - setBold(boldweight == BOLDWEIGHT_BOLD); - } - - /** - * get the boldness to use - * @return boldweight - * @see #BOLDWEIGHT_NORMAL - * @see #BOLDWEIGHT_BOLD - * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. Use {@link #getBold} instead. - */ - public short getBoldweight() - { - return getBold() ? BOLDWEIGHT_BOLD : BOLDWEIGHT_NORMAL; - } - - /** - * set character-set to use. - * - * @param charset - charset - * @see FontCharset - */ - public void setCharSet(byte charset) { - int cs = charset & 0xff; - setCharSet(cs); - } - /** - * set character-set to use. - * - * @param charset - charset - * @see FontCharset - */ - public void setCharSet(int charset) { - FontCharset fontCharset = FontCharset.valueOf(charset); - if(fontCharset != null) { - setCharSet(fontCharset); - } else { - throw new POIXMLException("Attention: an attempt to set a type of unknow charset and charset"); - } - } - - /** - * set character-set to use. - * - * @param charSet - */ - public void setCharSet(FontCharset charSet) { - CTIntProperty charsetProperty; - if(_ctFont.sizeOfCharsetArray() == 0) { - charsetProperty = _ctFont.addNewCharset(); - } else { - charsetProperty = _ctFont.getCharsetArray(0); - } - // We know that FontCharset only has valid entries in it, - // so we can just set the int value from it - charsetProperty.setVal( charSet.getValue() ); - } - - /** - * set the indexed color for the font - * - * @param color - color to use - * @see #DEFAULT_FONT_COLOR - Note: default font color - * @see IndexedColors - */ - public void setColor(short color) { - CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); - switch (color) { - case Font.COLOR_NORMAL: { - ctColor.setIndexed(XSSFFont.DEFAULT_FONT_COLOR); - break; - } - case Font.COLOR_RED: { - ctColor.setIndexed(IndexedColors.RED.getIndex()); - break; - } - default: - ctColor.setIndexed(color); - } - } - - /** - * set the color for the font in Standard Alpha Red Green Blue color value - * - * @param color - color to use - */ - public void setColor(XSSFColor color) { - if(color == null) _ctFont.setColorArray(null); - else { - CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); - if (ctColor.isSetIndexed()) { - ctColor.unsetIndexed(); - } - ctColor.setRgb(color.getRGB()); - } - } - - /** - * set the font height in points. - * - * @param height - height in points - */ - public void setFontHeight(short height) { - setFontHeight((double) height/20); - } - - /** - * set the font height in points. - * - * @param height - height in points - */ - public void setFontHeight(double height) { - CTFontSize fontSize = _ctFont.sizeOfSzArray() == 0 ? _ctFont.addNewSz() : _ctFont.getSzArray(0); - fontSize.setVal(height); - } - - /** - * set the font height in points. - * - * @link #setFontHeight - */ - public void setFontHeightInPoints(short height) { - setFontHeight((double)height); - } - - /** - * set the theme color for the font to use - * - * @param theme - theme color to use - */ - public void setThemeColor(short theme) { - CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); - ctColor.setTheme(theme); - } - - /** - * set the name for the font (i.e. Arial). - * If the font doesn't exist (because it isn't installed on the system), - * or the charset is invalid for that font, then another font should - * be substituted. - * The string length for this attribute shall be 0 to 31 characters. - * Default font name is Calibri. - * - * @param name - value representing the name of the font to use - * @see #DEFAULT_FONT_NAME - */ - public void setFontName(String name) { - CTFontName fontName = _ctFont.sizeOfNameArray() == 0 ? _ctFont.addNewName() : _ctFont.getNameArray(0); - fontName.setVal(name == null ? DEFAULT_FONT_NAME : name); - } - - - /** - * set a boolean value for the property specifying whether to use italics or not - * If omitted, the default value is true. - * - * @param italic - value for italics or not - */ - public void setItalic(boolean italic) { - if(italic){ - CTBooleanProperty bool = _ctFont.sizeOfIArray() == 0 ? _ctFont.addNewI() : _ctFont.getIArray(0); - bool.setVal(italic); - } else { - _ctFont.setIArray(null); - } - } - - - /** - * set a boolean value for the property specifying whether to use a strikeout horizontal line through the text or not - * If omitted, the default value is true. - * - * @param strikeout - value for strikeout or not - */ - public void setStrikeout(boolean strikeout) { - if(!strikeout) _ctFont.setStrikeArray(null); - else { - CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? _ctFont.addNewStrike() : _ctFont.getStrikeArray(0); - strike.setVal(strikeout); - } - } - - /** - * set normal,super or subscript, that representing the vertical-alignment setting. - * Setting this to either subscript or superscript shall make the font size smaller if a - * smaller font size is available. - * - * @param offset - offset type to use (none,super,sub) - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - public void setTypeOffset(short offset) { - if(offset == Font.SS_NONE){ - _ctFont.setVertAlignArray(null); - } else { - CTVerticalAlignFontProperty offsetProperty = _ctFont.sizeOfVertAlignArray() == 0 ? _ctFont.addNewVertAlign() : _ctFont.getVertAlignArray(0); - switch (offset) { - case Font.SS_NONE: - offsetProperty.setVal(STVerticalAlignRun.BASELINE); - break; - case Font.SS_SUB: - offsetProperty.setVal(STVerticalAlignRun.SUBSCRIPT); - break; - case Font.SS_SUPER: - offsetProperty.setVal(STVerticalAlignRun.SUPERSCRIPT); - break; - default: - throw new IllegalStateException("Invalid type offset: " + offset); - } - } - } - - /** - * set the style of underlining that is used. - * The none style is equivalent to not using underlining at all. - * - * @param underline - underline type to use - * @see FontUnderline - */ - public void setUnderline(byte underline) { - setUnderline(FontUnderline.valueOf(underline)); - } - - /** - * set an enumeration representing the style of underlining that is used. - * The none style is equivalent to not using underlining at all. - * The possible values for this attribute are defined by the FontUnderline - * - * @param underline - FontUnderline enum value - */ - public void setUnderline(FontUnderline underline) { - if(underline == FontUnderline.NONE && _ctFont.sizeOfUArray() > 0){ - _ctFont.setUArray(null); - } else { - CTUnderlineProperty ctUnderline = _ctFont.sizeOfUArray() == 0 ? _ctFont.addNewU() : _ctFont.getUArray(0); - STUnderlineValues.Enum val = STUnderlineValues.Enum.forInt(underline.getValue()); - ctUnderline.setVal(val); - } - } - - - public String toString() { - return _ctFont.toString(); - } - - - /** - * Perform a registration of ourselves - * to the style table - */ - public long registerTo(StylesTable styles) { - this._themes = styles.getTheme(); - short idx = (short)styles.putFont(this, true); - this._index = idx; - return idx; - } - /** - * Records the Themes Table that is associated with - * the current font, used when looking up theme - * based colours and properties. - */ - public void setThemesTable(ThemesTable themes) { - this._themes = themes; - } - - /** - * get the font scheme property. - * is used only in StylesTable to create the default instance of font - * - * @return FontScheme - * @see org.apache.poi.xssf.model.StylesTable#createDefaultFont() - */ - public FontScheme getScheme() { - CTFontScheme scheme = _ctFont.sizeOfSchemeArray() == 0 ? null : _ctFont.getSchemeArray(0); - return scheme == null ? FontScheme.NONE : FontScheme.valueOf(scheme.getVal().intValue()); - } - - /** - * set font scheme property - * - * @param scheme - FontScheme enum value - * @see FontScheme - */ - public void setScheme(FontScheme scheme) { - CTFontScheme ctFontScheme = _ctFont.sizeOfSchemeArray() == 0 ? _ctFont.addNewScheme() : _ctFont.getSchemeArray(0); - STFontScheme.Enum val = STFontScheme.Enum.forInt(scheme.getValue()); - ctFontScheme.setVal(val); - } - - /** - * get the font family to use. - * - * @return the font family to use - * @see org.apache.poi.ss.usermodel.FontFamily - */ - public int getFamily() { - CTIntProperty family = _ctFont.sizeOfFamilyArray() == 0 ? _ctFont.addNewFamily() : _ctFont.getFamilyArray(0); - return family == null ? FontFamily.NOT_APPLICABLE.getValue() : FontFamily.valueOf(family.getVal()).getValue(); - } - - /** - * Set the font family this font belongs to. - * A font family is a set of fonts having common stroke width and serif characteristics. - * The font name overrides when there are conflicting values. - * - * @param value - font family - * @see FontFamily - */ - public void setFamily(int value) { - CTIntProperty family = _ctFont.sizeOfFamilyArray() == 0 ? _ctFont.addNewFamily() : _ctFont.getFamilyArray(0); - family.setVal(value); - } - - /** - * set an enumeration representing the font family this font belongs to. - * A font family is a set of fonts having common stroke width and serif characteristics. - * - * @param family font family - * @link #setFamily(int value) - */ - public void setFamily(FontFamily family) { - setFamily(family.getValue()); - } - - /** - * get the index within the XSSFWorkbook (sequence within the collection of Font objects) - * @return unique index number of the underlying record this Font represents (probably you don't care - * unless you're comparing which one is which) - */ - public short getIndex() - { - return _index; - } - - public int hashCode(){ - return _ctFont.toString().hashCode(); - } - - public boolean equals(Object o){ - if(!(o instanceof XSSFFont)) return false; - - XSSFFont cf = (XSSFFont)o; - return _ctFont.toString().equals(cf.getCTFont().toString()); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java deleted file mode 100644 index 8e8a3d85c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.*; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun; - - -/** - * @author Yegor Kozlov - */ -public class XSSFFontFormatting implements FontFormatting { - CTFont _font; - - /*package*/ XSSFFontFormatting(CTFont font){ - _font = font; - } - - /** - * get the type of super or subscript for the font - * - * @return super or subscript option - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - @Override - public short getEscapementType(){ - if(_font.sizeOfVertAlignArray() == 0) return SS_NONE; - - CTVerticalAlignFontProperty prop = _font.getVertAlignArray(0); - return (short)(prop.getVal().intValue() - 1); - } - - /** - * set the escapement type for the font - * - * @param escapementType super or subscript option - * @see #SS_NONE - * @see #SS_SUPER - * @see #SS_SUB - */ - @Override - public void setEscapementType(short escapementType){ - _font.setVertAlignArray(null); - if(escapementType != SS_NONE){ - _font.addNewVertAlign().setVal(STVerticalAlignRun.Enum.forInt(escapementType + 1)); - } - } - - /** - * @return font color index - */ - @Override - public short getFontColorIndex(){ - if(_font.sizeOfColorArray() == 0) return -1; - - int idx = 0; - CTColor color = _font.getColorArray(0); - if(color.isSetIndexed()) idx = (int)color.getIndexed(); - return (short)idx; - } - - /** - * @param color font color index - */ - @Override - public void setFontColorIndex(short color){ - _font.setColorArray(null); - if(color != -1){ - _font.addNewColor().setIndexed(color); - } - } - - @Override - public XSSFColor getFontColor() { - if(_font.sizeOfColorArray() == 0) return null; - - return new XSSFColor(_font.getColorArray(0)); - } - - @Override - public void setFontColor(Color color) { - XSSFColor xcolor = XSSFColor.toXSSFColor(color); - if (xcolor == null) { - _font.getColorList().clear(); - } else { - _font.setColorArray(0, xcolor.getCTColor()); - } - } - - /** - * gets the height of the font in 1/20th point units - * - * @return fontheight (in points/20); or -1 if not modified - */ - @Override - public int getFontHeight(){ - if(_font.sizeOfSzArray() == 0) return -1; - - CTFontSize sz = _font.getSzArray(0); - return (short)(20*sz.getVal()); - } - - /** - * Sets the height of the font in 1/20th point units - * - * @param height the height in twips (in points/20) - */ - @Override - public void setFontHeight(int height){ - _font.setSzArray(null); - if(height != -1){ - _font.addNewSz().setVal((double)height / 20); - } - } - - /** - * get the type of underlining for the font - * - * @return font underlining type - * - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - @Override - public short getUnderlineType(){ - if(_font.sizeOfUArray() == 0) return U_NONE; - CTUnderlineProperty u = _font.getUArray(0); - switch(u.getVal().intValue()){ - case STUnderlineValues.INT_SINGLE: return U_SINGLE; - case STUnderlineValues.INT_DOUBLE: return U_DOUBLE; - case STUnderlineValues.INT_SINGLE_ACCOUNTING: return U_SINGLE_ACCOUNTING; - case STUnderlineValues.INT_DOUBLE_ACCOUNTING: return U_DOUBLE_ACCOUNTING; - default: return U_NONE; - } - } - - /** - * set the type of underlining type for the font - * - * @param underlineType super or subscript option - * - * @see #U_NONE - * @see #U_SINGLE - * @see #U_DOUBLE - * @see #U_SINGLE_ACCOUNTING - * @see #U_DOUBLE_ACCOUNTING - */ - @Override - public void setUnderlineType(short underlineType){ - _font.setUArray(null); - if(underlineType != U_NONE){ - FontUnderline fenum = FontUnderline.valueOf(underlineType); - STUnderlineValues.Enum val = STUnderlineValues.Enum.forInt(fenum.getValue()); - _font.addNewU().setVal(val); - } - } - - /** - * get whether the font weight is set to bold or not - * - * @return bold - whether the font is bold or not - */ - @Override - public boolean isBold(){ - return _font.sizeOfBArray() == 1 && _font.getBArray(0).getVal(); - } - - /** - * @return true if font style was set to italic - */ - @Override - public boolean isItalic(){ - return _font.sizeOfIArray() == 1 && _font.getIArray(0).getVal(); - } - - /** - * set font style options. - * - * @param italic - if true, set posture style to italic, otherwise to normal - * @param bold if true, set font weight to bold, otherwise to normal - */ - @Override - public void setFontStyle(boolean italic, boolean bold){ - _font.setIArray(null); - _font.setBArray(null); - if(italic) _font.addNewI().setVal(true); - if(bold) _font.addNewB().setVal(true); - } - - /** - * set font style options to default values (non-italic, non-bold) - */ - @Override - public void resetFontStyle(){ - _font.set(CTFont.Factory.newInstance()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java deleted file mode 100644 index e63f47b46..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.BaseFormulaEvaluator; -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.IStabilityClassifier; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; - -/** - * Evaluates formula cells.

        - * - * For performance reasons, this class keeps a cache of all previously calculated intermediate - * cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between - * calls to evaluate~ methods on this class. - */ -public final class XSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator { - private XSSFWorkbook _book; - - public XSSFFormulaEvaluator(XSSFWorkbook workbook) { - this(workbook, null, null); - } - private XSSFFormulaEvaluator(XSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - this(workbook, new WorkbookEvaluator(XSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder)); - } - protected XSSFFormulaEvaluator(XSSFWorkbook workbook, WorkbookEvaluator bookEvaluator) { - super(bookEvaluator); - _book = workbook; - } - - /** - * @param stabilityClassifier used to optimise caching performance. Pass null - * for the (conservative) assumption that any cell may have its definition changed after - * evaluation begins. - * @param udfFinder pass null for default (AnalysisToolPak only) - */ - public static XSSFFormulaEvaluator create(XSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { - return new XSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder); - } - - /** - * Loops over all cells in all sheets of the supplied - * workbook. - * For cells that contain formulas, their formulas are - * evaluated, and the results are saved. These cells - * remain as formula cells. - * For cells that do not contain formulas, no changes - * are made. - * This is a helpful wrapper around looping over all - * cells, and calling evaluateFormulaCell on each one. - */ - public static void evaluateAllFormulaCells(XSSFWorkbook wb) { - BaseFormulaEvaluator.evaluateAllFormulaCells(wb); - } - - @Override - public XSSFCell evaluateInCell(Cell cell) { - return (XSSFCell) super.evaluateInCell(cell); - } - - /** - * Loops over all cells in all sheets of the supplied - * workbook. - * For cells that contain formulas, their formulas are - * evaluated, and the results are saved. These cells - * remain as formula cells. - * For cells that do not contain formulas, no changes - * are made. - * This is a helpful wrapper around looping over all - * cells, and calling evaluateFormulaCell on each one. - */ - public void evaluateAll() { - evaluateAllFormulaCells(_book, this); - } - - /** - * Turns a XSSFCell into a XSSFEvaluationCell - */ - protected EvaluationCell toEvaluationCell(Cell cell) { - if (!(cell instanceof XSSFCell)){ - throw new IllegalArgumentException("Unexpected type of cell: " + cell.getClass() + "." + - " Only XSSFCells can be evaluated."); - } - - return new XSSFEvaluationCell((XSSFCell)cell); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFGraphicFrame.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFGraphicFrame.java deleted file mode 100644 index 08d781bef..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFGraphicFrame.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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 javax.xml.namespace.QName; - -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlCursor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrameNonVisual; -import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; - -/** - * Represents DrawingML GraphicalObjectFrame. - * - * @author Roman Kashitsyn - */ -public final class XSSFGraphicFrame extends XSSFShape { - - private static CTGraphicalObjectFrame prototype = null; - - private CTGraphicalObjectFrame graphicFrame; - private XSSFClientAnchor anchor; - - /** - * Construct a new XSSFGraphicFrame object. - * - * @param drawing the XSSFDrawing that owns this frame - * @param ctGraphicFrame the XML bean that stores this frame content - */ - protected XSSFGraphicFrame(XSSFDrawing drawing, CTGraphicalObjectFrame ctGraphicFrame) { - this.drawing = drawing; // protected field on XSSFShape - this.graphicFrame = ctGraphicFrame; - } - - @Internal - public CTGraphicalObjectFrame getCTGraphicalObjectFrame() { - return graphicFrame; - } - - /** - * Initialize default structure of a new graphic frame - */ - protected static CTGraphicalObjectFrame prototype() { - if (prototype == null) { - CTGraphicalObjectFrame graphicFrame = CTGraphicalObjectFrame.Factory.newInstance(); - - CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.addNewNvGraphicFramePr(); - CTNonVisualDrawingProps props = nvGraphic.addNewCNvPr(); - props.setId(0); - props.setName("Diagramm 1"); - nvGraphic.addNewCNvGraphicFramePr(); - - CTTransform2D transform = graphicFrame.addNewXfrm(); - CTPositiveSize2D extPoint = transform.addNewExt(); - CTPoint2D offPoint = transform.addNewOff(); - - extPoint.setCx(0); - extPoint.setCy(0); - offPoint.setX(0); - offPoint.setY(0); - - /* CTGraphicalObject graphic = */ graphicFrame.addNewGraphic(); - - prototype = graphicFrame; - } - return prototype; - } - - /** - * Sets the frame macro. - */ - public void setMacro(String macro) { - graphicFrame.setMacro(macro); - } - - /** - * Sets the frame name. - */ - public void setName(String name) { - getNonVisualProperties().setName(name); - } - - /** - * Returns the frame name. - * @return name of the frame - */ - public String getName() { - return getNonVisualProperties().getName(); - } - - private CTNonVisualDrawingProps getNonVisualProperties() { - CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.getNvGraphicFramePr(); - return nvGraphic.getCNvPr(); - } - - /** - * Attaches frame to an anchor. - */ - protected void setAnchor(XSSFClientAnchor anchor) { - this.anchor = anchor; - } - - /** - * Returns the frame anchor. - * @return the anchor this frame is attached to - */ - public XSSFClientAnchor getAnchor() { - return anchor; - } - - /** - * Assign a DrawingML chart to the graphic frame. - */ - protected void setChart(XSSFChart chart, String relId) { - CTGraphicalObjectData data = graphicFrame.getGraphic().addNewGraphicData(); - appendChartElement(data, relId); - chart.setGraphicFrame(this); - return; - } - - /** - * Gets the frame id. - */ - public long getId() { - return graphicFrame.getNvGraphicFramePr().getCNvPr().getId(); - } - - /** - * Sets the frame id. - */ - protected void setId(long id) { - graphicFrame.getNvGraphicFramePr().getCNvPr().setId(id); - } - - /** - * The low level code to insert {@code } tag into - * {@code}. - * - * Here is the schema (ECMA-376): - *

        -	 * {@code
        -	 * 
        -	 *   
        -	 *     
        -	 *   
        -	 *   
        -	 * 
        -	 * }
        -	 * 
        - */ - private void appendChartElement(CTGraphicalObjectData data, String id) { - String r_namespaceUri = STRelationshipId.type.getName().getNamespaceURI(); - String c_namespaceUri = XSSFDrawing.NAMESPACE_C; - XmlCursor cursor = data.newCursor(); - cursor.toNextToken(); - cursor.beginElement(new QName(c_namespaceUri, "chart", "c")); - cursor.insertAttributeWithValue(new QName(r_namespaceUri, "id", "r"), id); - cursor.dispose(); - data.setUri(c_namespaceUri); - } - - @Override - protected CTShapeProperties getShapeProperties(){ - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java deleted file mode 100644 index 9d26a6658..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java +++ /dev/null @@ -1,403 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.net.URI; -import java.net.URISyntaxException; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink; - -/** - * XSSF Implementation of a Hyperlink. - * Note - unlike with HSSF, many kinds of hyperlink - * are largely stored as relations of the sheet - */ -public class XSSFHyperlink implements Hyperlink { - final private HyperlinkType _type; - final private PackageRelationship _externalRel; - final private CTHyperlink _ctHyperlink; //contains a reference to the cell where the hyperlink is anchored, getRef() - private String _location; //what the hyperlink refers to - - /** - * Create a new XSSFHyperlink. This method is protected to be used only by - * {@link XSSFCreationHelper#createHyperlink(int)}. - * - * @param type - the type of hyperlink to create, see {@link Hyperlink} - * @deprecated POI 3.15 beta 3. Use {@link #XSSFHyperlink(HyperlinkType)} instead. - */ - protected XSSFHyperlink(int type) { - this(HyperlinkType.forInt(type)); - } - - /** - * Create a new XSSFHyperlink. This method is protected to be used only by - * {@link XSSFCreationHelper#createHyperlink(HyperlinkType)}. - * - * @param type - the type of hyperlink to create - */ - protected XSSFHyperlink(HyperlinkType type) { - _type = type; - _ctHyperlink = CTHyperlink.Factory.newInstance(); - _externalRel = null; - } - - /** - * Create a XSSFHyperlink and initialize it from the supplied CTHyperlink bean and package relationship - * - * @param ctHyperlink the xml bean containing xml properties - * @param hyperlinkRel the relationship in the underlying OPC package which stores the actual link's address - */ - protected XSSFHyperlink(CTHyperlink ctHyperlink, PackageRelationship hyperlinkRel) { - _ctHyperlink = ctHyperlink; - _externalRel = hyperlinkRel; - - // Figure out the Hyperlink type and destination - - if (_externalRel == null) { - // If it has a location, it's internal - if (ctHyperlink.getLocation() != null) { - _type = HyperlinkType.DOCUMENT; - _location = ctHyperlink.getLocation(); - } else if (ctHyperlink.getId() != null) { - throw new IllegalStateException("The hyperlink for cell " - + ctHyperlink.getRef() + " references relation " - + ctHyperlink.getId() + ", but that didn't exist!"); - } else { - // hyperlink is internal and is not related to other parts - _type = HyperlinkType.DOCUMENT; - } - } else { - URI target = _externalRel.getTargetURI(); - _location = target.toString(); - if (ctHyperlink.getLocation() != null) { - // URI fragment - _location += "#" + ctHyperlink.getLocation(); - } - - // Try to figure out the type - if (_location.startsWith("http://") || _location.startsWith("https://") - || _location.startsWith("ftp://")) { - _type = HyperlinkType.URL; - } else if (_location.startsWith("mailto:")) { - _type = HyperlinkType.EMAIL; - } else { - _type = HyperlinkType.FILE; - } - } - - } - - /** - * Create a new XSSFHyperlink. This method is for Internal use only. - * XSSFHyperlinks can be created by {@link XSSFCreationHelper}. - * See the spreadsheet quick-guide - * for an example. - * - * @param other the hyperlink to copy - */ - @Internal //FIXME: change to protected if/when SXSSFHyperlink class is created - public XSSFHyperlink(Hyperlink other) { - if (other instanceof XSSFHyperlink) { - XSSFHyperlink xlink = (XSSFHyperlink) other; - _type = xlink.getTypeEnum(); - _location = xlink._location; - _externalRel = xlink._externalRel; - _ctHyperlink = (CTHyperlink) xlink._ctHyperlink.copy(); - } - else { - _type = other.getTypeEnum(); - _location = other.getAddress(); - _externalRel = null; - _ctHyperlink = CTHyperlink.Factory.newInstance(); - setCellReference(new CellReference(other.getFirstRow(), other.getFirstColumn())); - } - } - /** - * @return the underlying CTHyperlink object - */ - @Internal - public CTHyperlink getCTHyperlink() { - return _ctHyperlink; - } - - /** - * Do we need to a relation too, to represent - * this hyperlink? - */ - public boolean needsRelationToo() { - return (_type != HyperlinkType.DOCUMENT); - } - - /** - * Generates the relation if required - */ - protected void generateRelationIfNeeded(PackagePart sheetPart) { - if (_externalRel == null && needsRelationToo()) { - // Generate the relation - PackageRelationship rel = - sheetPart.addExternalRelationship(_location, XSSFRelation.SHEET_HYPERLINKS.getRelation()); - - // Update the r:id - _ctHyperlink.setId(rel.getId()); - } - } - - /** - * Return the type of this hyperlink - * - * @return the type of this hyperlink - * @see HyperlinkType#forInt - * @deprecated POI 3.15 beta 3. Use {@link #getTypeEnum()} instead. - * getType will return a HyperlinkType enum in the future. - */ - @Override - public int getType() { - return _type.getCode(); - } - - /** - * Return the type of this hyperlink - * - * @return the type of this hyperlink - */ - @Override - public HyperlinkType getTypeEnum() { - return _type; - } - - /** - * Get the reference of the cell this applies to, - * es A55 - */ - public String getCellRef() { - return _ctHyperlink.getRef(); - } - - /** - * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file. - * The is the hyperlink target. - * - * @return the address of this hyperlink - */ - @Override - public String getAddress() { - return _location; - } - - /** - * Return text label for this hyperlink - * - * @return text to display - */ - @Override - public String getLabel() { - return _ctHyperlink.getDisplay(); - } - - /** - * Location within target. If target is a workbook (or this workbook) this shall refer to a - * sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file. - * - * @return location - */ - public String getLocation() { - return _ctHyperlink.getLocation(); - } - - /** - * Sets text label for this hyperlink - * - * @param label text label for this hyperlink - */ - @Override - public void setLabel(String label) { - _ctHyperlink.setDisplay(label); - } - - /** - * Location within target. If target is a workbook (or this workbook) this shall refer to a - * sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file. - * - * @param location - string representing a location of this hyperlink - */ - public void setLocation(String location) { - _ctHyperlink.setLocation(location); - } - - /** - * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file - * This is the hyperlink target. - * - * @param address - the address of this hyperlink - */ - @Override - public void setAddress(String address) { - validate(address); - - _location = address; - //we must set location for internal hyperlinks - if (_type == HyperlinkType.DOCUMENT) { - setLocation(address); - } - } - - @SuppressWarnings("fall-through") - private void validate(String address) { - switch (_type) { - // email, path to file and url must be valid URIs - case EMAIL: - case FILE: - case URL: - try { - new URI(address); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Address of hyperlink must be a valid URI", e); - } - break; - case DOCUMENT: - // currently not evaluating anything. - break; - default: - throw new IllegalStateException("Invalid Hyperlink type: " + _type); - } - } - - /** - * Assigns this hyperlink to the given cell reference - */ - @Internal - public void setCellReference(String ref) { - _ctHyperlink.setRef(ref); - } - @Internal - protected void setCellReference(CellReference ref) { - setCellReference(ref.formatAsString()); - } - - private CellReference buildCellReference() { - String ref = _ctHyperlink.getRef(); - if (ref == null) { - ref = "A1"; - } - return new CellReference(ref); - } - - - /** - * Return the column of the first cell that contains the hyperlink - * - * @return the 0-based column of the first cell that contains the hyperlink - */ - @Override - public int getFirstColumn() { - return buildCellReference().getCol(); - } - - - /** - * Return the column of the last cell that contains the hyperlink - * - * @return the 0-based column of the last cell that contains the hyperlink - */ - @Override - public int getLastColumn() { - return buildCellReference().getCol(); - } - - /** - * Return the row of the first cell that contains the hyperlink - * - * @return the 0-based row of the cell that contains the hyperlink - */ - @Override - public int getFirstRow() { - return buildCellReference().getRow(); - } - - - /** - * Return the row of the last cell that contains the hyperlink - * - * @return the 0-based row of the last cell that contains the hyperlink - */ - @Override - public int getLastRow() { - return buildCellReference().getRow(); - } - - /** - * Set the column of the first cell that contains the hyperlink - * - * @param col the 0-based column of the first cell that contains the hyperlink - */ - @Override - public void setFirstColumn(int col) { - setCellReference(new CellReference( getFirstRow(), col )); - } - - /** - * Set the column of the last cell that contains the hyperlink. - * For XSSF, a Hyperlink may only reference one cell - * - * @param col the 0-based column of the last cell that contains the hyperlink - */ - @Override - public void setLastColumn(int col) { - setFirstColumn(col); - } - - /** - * Set the row of the first cell that contains the hyperlink - * - * @param row the 0-based row of the first cell that contains the hyperlink - */ - @Override - public void setFirstRow(int row) { - setCellReference(new CellReference( row, getFirstColumn() )); - } - - /** - * Set the row of the last cell that contains the hyperlink. - * For XSSF, a Hyperlink may only reference one cell - * - * @param row the 0-based row of the last cell that contains the hyperlink - */ - @Override - public void setLastRow(int row) { - setFirstRow(row); - } - - /** - * @return additional text to help the user understand more about the hyperlink - */ - public String getTooltip() { - return _ctHyperlink.getTooltip(); - } - - /** - * @param text additional text to help the user understand more about the hyperlink - */ - public void setTooltip(String text) { - _ctHyperlink.setTooltip(text); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java deleted file mode 100644 index c2e26911a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.ConditionalFormattingThreshold; -import org.apache.poi.ss.usermodel.IconMultiStateFormatting; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfvo; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIconSet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STIconSetType; - -/** - * High level representation for Icon / Multi-State Formatting - * component of Conditional Formatting settings - */ -public class XSSFIconMultiStateFormatting implements IconMultiStateFormatting { - CTIconSet _iconset; - - /*package*/ XSSFIconMultiStateFormatting(CTIconSet iconset){ - _iconset = iconset; - } - - public IconSet getIconSet() { - String set = _iconset.getIconSet().toString(); - return IconSet.byName(set); - } - public void setIconSet(IconSet set) { - STIconSetType.Enum xIconSet = STIconSetType.Enum.forString(set.name); - _iconset.setIconSet(xIconSet); - } - - public boolean isIconOnly() { - if (_iconset.isSetShowValue()) - return !_iconset.getShowValue(); - return false; - } - public void setIconOnly(boolean only) { - _iconset.setShowValue(!only); - } - - public boolean isReversed() { - if (_iconset.isSetReverse()) - return _iconset.getReverse(); - return false; - } - public void setReversed(boolean reversed) { - _iconset.setReverse(reversed); - } - - public XSSFConditionalFormattingThreshold[] getThresholds() { - CTCfvo[] cfvos = _iconset.getCfvoArray(); - XSSFConditionalFormattingThreshold[] t = - new XSSFConditionalFormattingThreshold[cfvos.length]; - for (int i=0; i - * This element contains all of the properties related to the XML map, - * and the behaviors expected during data refresh operations. - * - * @author Roberto Manicardi - */ - - -public class XSSFMap { - private CTMap ctMap; - private MapInfo mapInfo; - - public XSSFMap(CTMap ctMap, MapInfo mapInfo) { - this.ctMap = ctMap; - this.mapInfo = mapInfo; - } - - - @Internal - public CTMap getCtMap() { - return ctMap; - } - - @Internal - public CTSchema getCTSchema() { - String schemaId = ctMap.getSchemaID(); - return mapInfo.getCTSchemaById(schemaId); - } - - public Node getSchema() { - Node xmlSchema = null; - - CTSchema schema = getCTSchema(); - xmlSchema = schema.getDomNode().getFirstChild(); - - return xmlSchema; - } - - /** - * @return the list of Single Xml Cells that provide a map rule to this mapping. - */ - public List getRelatedSingleXMLCell() { - List relatedSimpleXmlCells = new ArrayList(); - - int sheetNumber = mapInfo.getWorkbook().getNumberOfSheets(); - for (int i = 0; i < sheetNumber; i++) { - XSSFSheet sheet = mapInfo.getWorkbook().getSheetAt(i); - for (POIXMLDocumentPart p : sheet.getRelations()) { - if (p instanceof SingleXmlCells) { - SingleXmlCells singleXMLCells = (SingleXmlCells) p; - for (XSSFSingleXmlCell cell : singleXMLCells.getAllSimpleXmlCell()) { - if (cell.getMapId() == ctMap.getID()) { - relatedSimpleXmlCells.add(cell); - } - } - } - } - } - return relatedSimpleXmlCells; - } - - /** - * @return the list of all Tables that provide a map rule to this mapping - */ - public List getRelatedTables() { - List tables = new ArrayList(); - for (Sheet sheet : mapInfo.getWorkbook()) { - for (RelationPart rp : ((XSSFSheet)sheet).getRelationParts()) { - if (rp.getRelationship().getRelationshipType().equals(XSSFRelation.TABLE.getRelation())) { - XSSFTable table = rp.getDocumentPart(); - if (table.mapsTo(ctMap.getID())) { - tables.add(table); - } - } - } - } - - return tables; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java deleted file mode 100644 index dd6fbccc7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java +++ /dev/null @@ -1,415 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.ptg.Ptg; - -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; - -/** - * Represents a defined named range in a SpreadsheetML workbook. - *

        - * Defined names are descriptive text that is used to represents a cell, range of cells, formula, or constant value. - * Use easy-to-understand names, such as Products, to refer to hard to understand ranges, such as Sales!C20:C30. - *

        - * Example: - *
        - * XSSFWorkbook wb = new XSSFWorkbook(); - * XSSFSheet sh = wb.createSheet("Sheet1"); - * - * //applies to the entire workbook - * XSSFName name1 = wb.createName(); - * name1.setNameName("FMLA"); - * name1.setRefersToFormula("Sheet1!$B$3"); - * - * //applies to Sheet1 - * XSSFName name2 = wb.createName(); - * name2.setNameName("SheetLevelName"); - * name2.setComment("This name is scoped to Sheet1"); - * name2.setLocalSheetId(0); - * name2.setRefersToFormula("Sheet1!$B$3"); - * - *
        - * - * @author Nick Burch - * @author Yegor Kozlov - */ -public final class XSSFName implements Name { - - /** - * A built-in defined name that specifies the workbook's print area - */ - public final static String BUILTIN_PRINT_AREA = "_xlnm.Print_Area"; - - /** - * A built-in defined name that specifies the row(s) or column(s) to repeat - * at the top of each printed page. - */ - public final static String BUILTIN_PRINT_TITLE = "_xlnm.Print_Titles"; - - /** - * A built-in defined name that refers to a range containing the criteria values - * to be used in applying an advanced filter to a range of data - */ - public final static String BUILTIN_CRITERIA = "_xlnm.Criteria:"; - - - /** - * this defined name refers to the range containing the filtered - * output values resulting from applying an advanced filter criteria to a source - * range - */ - public final static String BUILTIN_EXTRACT = "_xlnm.Extract:"; - - /** - * ?an be one of the following - *
      • this defined name refers to a range to which an advanced filter has been - * applied. This represents the source data range, unfiltered. - *
      • This defined name refers to a range to which an AutoFilter has been - * applied - */ - public final static String BUILTIN_FILTER_DB = "_xlnm._FilterDatabase"; - - /** - * A built-in defined name that refers to a consolidation area - */ - public final static String BUILTIN_CONSOLIDATE_AREA = "_xlnm.Consolidate_Area"; - - /** - * A built-in defined name that specified that the range specified is from a database data source - */ - public final static String BUILTIN_DATABASE = "_xlnm.Database"; - - /** - * A built-in defined name that refers to a sheet title. - */ - public final static String BUILTIN_SHEET_TITLE = "_xlnm.Sheet_Title"; - - private XSSFWorkbook _workbook; - private CTDefinedName _ctName; - - /** - * Creates an XSSFName object - called internally by XSSFWorkbook. - * - * @param name - the xml bean that holds data represenring this defined name. - * @param workbook - the workbook object associated with the name - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#createName() - */ - protected XSSFName(CTDefinedName name, XSSFWorkbook workbook) { - _workbook = workbook; - _ctName = name; - } - - /** - * Returns the underlying named range object - */ - protected CTDefinedName getCTName() { - return _ctName; - } - - /** - * Returns the name that will appear in the user interface for the defined name. - * - * @return text name of this defined name - */ - public String getNameName() { - return _ctName.getName(); - } - - /** - * Sets the name that will appear in the user interface for the defined name. - * Names must begin with a letter or underscore, not contain spaces and be unique across the workbook. - * - *

        - * A name must always be unique within its scope. POI prevents you from defining a name that is not unique - * within its scope. However you can use the same name in different scopes. Example: - *

        - * //by default names are workbook-global - * XSSFName name; - * name = workbook.createName(); - * name.setNameName("sales_08"); - * - * name = workbook.createName(); - * name.setNameName("sales_08"); //will throw an exception: "The workbook already contains this name (case-insensitive)" - * - * //create sheet-level name - * name = workbook.createName(); - * name.setSheetIndex(0); //the scope of the name is the first sheet - * name.setNameName("sales_08"); //ok - * - * name = workbook.createName(); - * name.setSheetIndex(0); - * name.setNameName("sales_08"); //will throw an exception: "The sheet already contains this name (case-insensitive)" - * - *
        - *

        - * @param name name of this defined name - * @throws IllegalArgumentException if the name is invalid or the workbook already contains this name (case-insensitive) - */ - public void setNameName(String name) { - validateName(name); - - String oldName = getNameName(); - int sheetIndex = getSheetIndex(); - //Check to ensure no other names have the same case-insensitive name at the same scope - for (XSSFName foundName : _workbook.getNames(name)) { - if (foundName.getSheetIndex() == sheetIndex && foundName != this) { - String msg = "The "+(sheetIndex == -1 ? "workbook" : "sheet")+" already contains this name: " + name; - throw new IllegalArgumentException(msg); - } - } - _ctName.setName(name); - //Need to update the name -> named ranges map - _workbook.updateName(this, oldName); - } - - public String getRefersToFormula() { - String result = _ctName.getStringValue(); - if (result == null || result.length() < 1) { - return null; - } - return result; - } - - public void setRefersToFormula(String formulaText) { - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(_workbook); - //validate through the FormulaParser - FormulaParser.parse(formulaText, fpb, FormulaType.NAMEDRANGE, getSheetIndex(), -1); - - _ctName.setStringValue(formulaText); - } - - public boolean isDeleted(){ - String formulaText = getRefersToFormula(); - if (formulaText == null) { - return false; - } - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(_workbook); - Ptg[] ptgs = FormulaParser.parse(formulaText, fpb, FormulaType.NAMEDRANGE, getSheetIndex(), -1); - return Ptg.doesFormulaReferToDeletedCell(ptgs); - } - - /** - * Tell Excel that this name applies to the worksheet with the specified index instead of the entire workbook. - * - * @param index the sheet index this name applies to, -1 unsets this property making the name workbook-global - */ - public void setSheetIndex(int index) { - int lastSheetIx = _workbook.getNumberOfSheets() - 1; - if (index < -1 || index > lastSheetIx) { - throw new IllegalArgumentException("Sheet index (" + index +") is out of range" + - (lastSheetIx == -1 ? "" : (" (0.." + lastSheetIx + ")"))); - } - - if(index == -1) { - if(_ctName.isSetLocalSheetId()) _ctName.unsetLocalSheetId(); - } else { - _ctName.setLocalSheetId(index); - } - } - - /** - * Returns the sheet index this name applies to. - * - * @return the sheet index this name applies to, -1 if this name applies to the entire workbook - */ - public int getSheetIndex() { - return _ctName.isSetLocalSheetId() ? (int) _ctName.getLocalSheetId() : -1; - } - - /** - * Indicates that the defined name refers to a user-defined function. - * This attribute is used when there is an add-in or other code project associated with the file. - * - * @param value true indicates the name refers to a function. - */ - public void setFunction(boolean value) { - _ctName.setFunction(value); - } - - /** - * Indicates that the defined name refers to a user-defined function. - * This attribute is used when there is an add-in or other code project associated with the file. - * - * @return true indicates the name refers to a function. - */ - public boolean getFunction() { - return _ctName.getFunction(); - } - - /** - * Specifies the function group index if the defined name refers to a function. The function - * group defines the general category for the function. This attribute is used when there is - * an add-in or other code project associated with the file. - * - * @param functionGroupId the function group index that defines the general category for the function - */ - public void setFunctionGroupId(int functionGroupId) { - _ctName.setFunctionGroupId(functionGroupId); - } - - /** - * Returns the function group index if the defined name refers to a function. The function - * group defines the general category for the function. This attribute is used when there is - * an add-in or other code project associated with the file. - * - * @return the function group index that defines the general category for the function - */ - public int getFunctionGroupId() { - return (int) _ctName.getFunctionGroupId(); - } - - /** - * Get the sheets name which this named range is referenced to - * - * @return sheet name, which this named range referred to. - * Empty string if the referenced sheet name weas not found. - */ - public String getSheetName() { - if (_ctName.isSetLocalSheetId()) { - // Given as explicit sheet id - int sheetId = (int)_ctName.getLocalSheetId(); - return _workbook.getSheetName(sheetId); - } - String ref = getRefersToFormula(); - AreaReference areaRef = new AreaReference(ref); - return areaRef.getFirstCell().getSheetName(); - } - - /** - * Is the name refers to a user-defined function ? - * - * @return true if this name refers to a user-defined function - */ - public boolean isFunctionName() { - return getFunction(); - } - - /** - * Returns the comment the user provided when the name was created. - * - * @return the user comment for this named range - */ - public String getComment() { - return _ctName.getComment(); - } - - /** - * Specifies the comment the user provided when the name was created. - * - * @param comment the user comment for this named range - */ - public void setComment(String comment) { - _ctName.setComment(comment); - } - - @Override - public int hashCode() { - return _ctName.toString().hashCode(); - } - - /** - * Compares this name to the specified object. - * The result is true if the argument is XSSFName and the - * underlying CTDefinedName bean equals to the CTDefinedName representing this name - * - * @param o the object to compare this XSSFName against. - * @return true if the XSSFName are equal; - * false otherwise. - */ - @Override - public boolean equals(Object o) { - if(o == this) return true; - - if (!(o instanceof XSSFName)) return false; - - XSSFName cf = (XSSFName) o; - return _ctName.toString().equals(cf.getCTName().toString()); - } - - /** - * https://support.office.com/en-us/article/Define-and-use-names-in-formulas-4D0F13AC-53B7-422E-AFD2-ABD7FF379C64#bmsyntax_rules_for_names - * - * Valid characters: - * First character: { letter | underscore | backslash } - * Remaining characters: { letter | number | period | underscore } - * - * Cell shorthand: cannot be { "C" | "c" | "R" | "r" } - * - * Cell references disallowed: cannot be a cell reference $A$1 or R1C1 - * - * Spaces are not valid (follows from valid characters above) - * - * Name length: (XSSF-specific?) 255 characters maximum - * - * Case sensitivity: all names are case-insensitive - * - * Uniqueness: must be unique (for names with the same scope) - * - * @param name - */ - private static void validateName(String name) { - - if (name.length() == 0) { - throw new IllegalArgumentException("Name cannot be blank"); - } - if (name.length() > 255) { - throw new IllegalArgumentException("Invalid name: '"+name+"': cannot exceed 255 characters in length"); - } - if (name.equalsIgnoreCase("R") || name.equalsIgnoreCase("C")) { - throw new IllegalArgumentException("Invalid name: '"+name+"': cannot be special shorthand R or C"); - } - - // is first character valid? - char c = name.charAt(0); - String allowedSymbols = "_\\"; - boolean characterIsValid = (Character.isLetter(c) || allowedSymbols.indexOf(c) != -1); - if (!characterIsValid) { - throw new IllegalArgumentException("Invalid name: '"+name+"': first character must be underscore or a letter"); - } - - // are all other characters valid? - allowedSymbols = "_.\\"; //backslashes needed for unicode escape - for (final char ch : name.toCharArray()) { - characterIsValid = (Character.isLetterOrDigit(ch) || allowedSymbols.indexOf(ch) != -1); - if (!characterIsValid) { - throw new IllegalArgumentException("Invalid name: '"+name+"': name must be letter, digit, period, or underscore"); - } - } - - // Is the name a valid $A$1 cell reference - // Because $, :, and ! are disallowed characters, A1-style references become just a letter-number combination - if (name.matches("[A-Za-z]+\\d+")) { - String col = name.replaceAll("\\d", ""); - String row = name.replaceAll("[A-Za-z]", ""); - if (CellReference.cellReferenceIsWithinRange(col, row, SpreadsheetVersion.EXCEL97)) { - throw new IllegalArgumentException("Invalid name: '"+name+"': cannot be $A$1-style cell reference"); - } - } - - // Is the name a valid R1C1 cell reference? - if (name.matches("[Rr]\\d+[Cc]\\d+")) { - throw new IllegalArgumentException("Invalid name: '"+name+"': cannot be R1C1-style cell reference"); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFOddFooter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFOddFooter.java deleted file mode 100644 index ca3950f81..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFOddFooter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Footer; -import org.apache.poi.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - * Odd page footer value. Corresponds to odd printed pages. - * Odd page(s) in the sheet may not be printed, for example, if the print area is specified to be - * a range such that it falls outside an odd page's scope. - * - */ -public class XSSFOddFooter extends XSSFHeaderFooter implements Footer{ - - /** - * Create an instance of XSSFOddFooter from the supplied XML bean - * @see XSSFSheet#getOddFooter() - * @param headerFooter - */ - public XSSFOddFooter(CTHeaderFooter headerFooter) { - super(headerFooter); - } - - /** - * Get the content text representing the footer - * @return text - */ - public String getText() { - return getHeaderFooter().getOddFooter(); - } - - /** - * Set a text for the footer. If null unset the value. - * @see XSSFHeaderFooter to see how to create a string with Header/Footer Formatting Syntax - * @param text - a string representing the footer. - */ - public void setText(String text) { - if(text == null) { - getHeaderFooter().unsetOddFooter(); - } else { - getHeaderFooter().setOddFooter(text); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFOddHeader.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFOddHeader.java deleted file mode 100644 index ba5c1a06f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFOddHeader.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Header; -import org.apache.poi.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - * Odd page header value. Corresponds to odd printed pages. - * Odd page(s) in the sheet may not be printed, for example, if the print area is specified to be - * a range such that it falls outside an odd page's scope. - * - */ -public class XSSFOddHeader extends XSSFHeaderFooter implements Header{ - - /** - * Create an instance of XSSFOddHeader from the supplied XML bean - * @see XSSFSheet#getOddHeader() - * @param headerFooter - */ - protected XSSFOddHeader(CTHeaderFooter headerFooter) { - super(headerFooter); - } - - /** - * Get the content text representing this header - * @return text - */ - public String getText() { - return getHeaderFooter().getOddHeader(); - } - - /** - * Set a text for the header. If null unset the value - * @see XSSFHeaderFooter to see how to create a string with Header/Footer Formatting Syntax - * @param text - a string representing the header. - */ - public void setText(String text) { - if(text == null) { - getHeaderFooter().unsetOddHeader(); - } else { - getHeaderFooter().setOddHeader(text); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java deleted file mode 100644 index 3ca68f2ba..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Color; -import org.apache.poi.ss.usermodel.PatternFormatting; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; - -/** - * @author Yegor Kozlov - */ -public class XSSFPatternFormatting implements PatternFormatting { - CTFill _fill; - - XSSFPatternFormatting(CTFill fill){ - _fill = fill; - } - - public XSSFColor getFillBackgroundColorColor() { - if(!_fill.isSetPatternFill()) return null; - return new XSSFColor(_fill.getPatternFill().getBgColor()); - } - public XSSFColor getFillForegroundColorColor() { - if(!_fill.isSetPatternFill() || ! _fill.getPatternFill().isSetFgColor()) - return null; - return new XSSFColor(_fill.getPatternFill().getFgColor()); - } - - public short getFillPattern() { - if(!_fill.isSetPatternFill() || !_fill.getPatternFill().isSetPatternType()) return NO_FILL; - - return (short)(_fill.getPatternFill().getPatternType().intValue() - 1); - } - - public short getFillBackgroundColor() { - XSSFColor color = getFillBackgroundColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - public short getFillForegroundColor() { - XSSFColor color = getFillForegroundColorColor(); - if (color == null) return 0; - return color.getIndexed(); - } - - public void setFillBackgroundColor(Color bg) { - XSSFColor xcolor = XSSFColor.toXSSFColor(bg); - if (xcolor == null) setFillBackgroundColor((CTColor)null); - else setFillBackgroundColor(xcolor.getCTColor()); - } - public void setFillBackgroundColor(short bg) { - CTColor bgColor = CTColor.Factory.newInstance(); - bgColor.setIndexed(bg); - setFillBackgroundColor(bgColor); - } - private void setFillBackgroundColor(CTColor color) { - CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill(); - if (color == null) { - ptrn.unsetBgColor(); - } else { - ptrn.setBgColor(color); - } - } - - public void setFillForegroundColor(Color fg) { - XSSFColor xcolor = XSSFColor.toXSSFColor(fg); - if (xcolor == null) setFillForegroundColor((CTColor)null); - else setFillForegroundColor(xcolor.getCTColor()); - } - public void setFillForegroundColor(short fg) { - CTColor fgColor = CTColor.Factory.newInstance(); - fgColor.setIndexed(fg); - setFillForegroundColor(fgColor); - } - private void setFillForegroundColor(CTColor color) { - CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill(); - if (color == null) { - ptrn.unsetFgColor(); - } else { - ptrn.setFgColor(color); - } - } - - public void setFillPattern(short fp){ - CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill(); - if(fp == NO_FILL) ptrn.unsetPatternType(); - else ptrn.setPatternType(STPatternType.Enum.forInt(fp + 1)); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java deleted file mode 100644 index 1d87facee..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java +++ /dev/null @@ -1,287 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.awt.Dimension; -import java.io.IOException; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.Picture; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.ImageUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualPictureProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPictureNonVisual; - -/** - * 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 - */ - @Internal - public CTPicture getCTPicture(){ - return ctPicture; - } - - /** - * Reset the image to the dimension of the embedded image - * - * @see #resize(double, double) - */ - public void resize(){ - resize(Double.MAX_VALUE); - } - - /** - * Resize the image proportionally. - * - * @see #resize(double, double) - */ - public void resize(double scale) { - resize(scale, scale); - } - - /** - * Resize the image relatively to its current size. - *

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Calibri 11pt for .xlsx). - * If the default font is changed the resized image can be streched vertically or horizontally. - *

        - *

        - * resize(1.0,1.0) keeps the original size,
        - * resize(0.5,0.5) resize to 50% of the original,
        - * resize(2.0,2.0) resizes to 200% of the original.
        - * resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE}) resizes to the dimension of the embedded image. - *

        - * - * @param scaleX the amount by which the image width is multiplied relative to the original width, - * when set to {@link java.lang.Double#MAX_VALUE} the width of the embedded image is used - * @param scaleY the amount by which the image height is multiplied relative to the original height, - * when set to {@link java.lang.Double#MAX_VALUE} the height of the embedded image is used - */ - public void resize(double scaleX, double scaleY){ - XSSFClientAnchor anchor = getClientAnchor(); - - XSSFClientAnchor pref = getPreferredSize(scaleX,scaleY); - - 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){ - return getPreferredSize(scale, scale); - } - - /** - * Calculate the preferred size for this picture. - * - * @param scaleX the amount by which image width is multiplied relative to the original width. - * @param scaleY the amount by which image height is multiplied relative to the original height. - * @return XSSFClientAnchor with the preferred size for this image - */ - public XSSFClientAnchor getPreferredSize(double scaleX, double scaleY){ - Dimension dim = ImageUtils.setPreferredSize(this, scaleX, scaleY); - CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt(); - size2d.setCx((int)dim.getWidth()); - size2d.setCy((int)dim.getHeight()); - return getClientAnchor(); - } - - /** - * 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){ - try { - return ImageUtils.getImageDimension(part.getInputStream(), type); - } catch (IOException e){ - //return a "singulariry" if ImageIO failed to read the image - logger.log(POILogger.WARN, e); - return new Dimension(); - } - } - - /** - * Return the dimension of the embedded image in pixel - * - * @return image dimension in pixels - */ - public Dimension getImageDimension() { - XSSFPictureData picData = getPictureData(); - return getImageDimension(picData.getPackagePart(), picData.getPictureType()); - } - - /** - * Return picture data for this shape - * - * @return picture data for this shape - */ - public XSSFPictureData getPictureData() { - String blipId = ctPicture.getBlipFill().getBlip().getEmbed(); - return (XSSFPictureData)getDrawing().getRelationById(blipId); - } - - protected CTShapeProperties getShapeProperties(){ - return ctPicture.getSpPr(); - } - - /** - * @return the anchor that is used by this shape. - */ - @Override - public XSSFClientAnchor getClientAnchor() { - XSSFAnchor a = getAnchor(); - return (a instanceof XSSFClientAnchor) ? (XSSFClientAnchor)a : null; - } - - /** - * @return the sheet which contains the picture shape - */ - @Override - public XSSFSheet getSheet() { - return (XSSFSheet)getDrawing().getParent(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java deleted file mode 100644 index f8c9c226c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.IOException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.PictureData; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.IOUtils; - -/** - * Raw picture data, normally attached to a SpreadsheetML Drawing. - * As a rule, pictures are stored in the /xl/media/ part of a SpreadsheetML package. - */ -public class XSSFPictureData extends POIXMLDocumentPart implements PictureData { - - /** - * Relationships for each known picture type - */ - protected static final POIXMLRelation[] RELATIONS; - static { - RELATIONS = new POIXMLRelation[13]; - RELATIONS[Workbook.PICTURE_TYPE_EMF] = XSSFRelation.IMAGE_EMF; - RELATIONS[Workbook.PICTURE_TYPE_WMF] = XSSFRelation.IMAGE_WMF; - RELATIONS[Workbook.PICTURE_TYPE_PICT] = XSSFRelation.IMAGE_PICT; - RELATIONS[Workbook.PICTURE_TYPE_JPEG] = XSSFRelation.IMAGE_JPEG; - RELATIONS[Workbook.PICTURE_TYPE_PNG] = XSSFRelation.IMAGE_PNG; - RELATIONS[Workbook.PICTURE_TYPE_DIB] = XSSFRelation.IMAGE_DIB; - RELATIONS[XSSFWorkbook.PICTURE_TYPE_GIF] = XSSFRelation.IMAGE_GIF; - RELATIONS[XSSFWorkbook.PICTURE_TYPE_TIFF] = XSSFRelation.IMAGE_TIFF; - RELATIONS[XSSFWorkbook.PICTURE_TYPE_EPS] = XSSFRelation.IMAGE_EPS; - RELATIONS[XSSFWorkbook.PICTURE_TYPE_BMP] = XSSFRelation.IMAGE_BMP; - RELATIONS[XSSFWorkbook.PICTURE_TYPE_WPG] = XSSFRelation.IMAGE_WPG; - } - - /** - * Create a new XSSFPictureData node - * - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#addPicture(byte[], int) - */ - protected XSSFPictureData() { - super(); - } - - /** - * Construct XSSFPictureData from a package part - * - * @param part the package part holding the drawing data, - * - * @since POI 3.14-Beta1 - */ - protected XSSFPictureData(PackagePart part) { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFPictureData(PackagePart part, PackageRelationship rel) { - this(part); - } - - /** - * Gets the picture data as a byte array. - *

        - * Note, that this call might be expensive since all the picture data is copied into a temporary byte array. - * You can grab the picture data directly from the underlying package part as follows: - *
        - * - * InputStream is = getPackagePart().getInputStream(); - * - *

        - * - * @return the picture data. - */ - public byte[] getData() { - try { - return IOUtils.toByteArray(getPackagePart().getInputStream()); - } catch(IOException e) { - throw new POIXMLException(e); - } - } - - /** - * Suggests a file extension for this image. - * - * @return the file extension. - */ - public String suggestFileExtension() { - return getPackagePart().getPartName().getExtension(); - } - - /** - * Return an integer constant that specifies type of this picture - * - * @return an integer constant that specifies type of this picture - * @see org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_EMF - * @see org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_WMF - * @see org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_PICT - * @see org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_JPEG - * @see org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_PNG - * @see org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_DIB - */ - public int getPictureType(){ - String contentType = getPackagePart().getContentType(); - for (int i = 0; i < RELATIONS.length; i++) { - if(RELATIONS[i] == null) continue; - - if(RELATIONS[i].getContentType().equals(contentType)){ - return i; - } - } - return 0; - } - - public String getMimeType() { - return getPackagePart().getContentType(); - } - - /** - * *PictureData objects store the actual content in the part directly without keeping a - * copy like all others therefore we need to handle them differently. - */ - @Override - protected void prepareForCommit() { - // do not clear the part here - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java deleted file mode 100644 index 418185f2b..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCache; - -public class XSSFPivotCache extends POIXMLDocumentPart { - - private CTPivotCache ctPivotCache; - - @Beta - public XSSFPivotCache(){ - super(); - ctPivotCache = CTPivotCache.Factory.newInstance(); - } - - @Beta - public XSSFPivotCache(CTPivotCache ctPivotCache) { - super(); - this.ctPivotCache = ctPivotCache; - } - - /** - * Creates n XSSFPivotCache representing the given package part and relationship. - * Should only be called when reading in an existing file. - * - * @param part - The package part that holds xml data representing this pivot cache definition. - * - * @since POI 3.14-Beta1 - */ - @Beta - protected XSSFPivotCache(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFPivotCache(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - @Beta - protected void readFrom(InputStream is) throws IOException { - try { - XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS); - //Removing root element - options.setLoadReplaceDocumentElement(null); - ctPivotCache = CTPivotCache.Factory.parse(is, options); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - @Beta - public CTPivotCache getCTPivotCache() { - return ctPivotCache; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java deleted file mode 100644 index 26735c782..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java +++ /dev/null @@ -1,190 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Date; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCacheField; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCacheFields; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCacheDefinition; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheetSource; - -public class XSSFPivotCacheDefinition extends POIXMLDocumentPart{ - - private CTPivotCacheDefinition ctPivotCacheDefinition; - - @Beta - public XSSFPivotCacheDefinition(){ - super(); - ctPivotCacheDefinition = CTPivotCacheDefinition.Factory.newInstance(); - createDefaultValues(); - } - - /** - * Creates an XSSFPivotCacheDefintion representing the given package part and relationship. - * Should only be called when reading in an existing file. - * - * @param part - The package part that holds xml data representing this pivot cache definition. - * - * @since POI 3.14-Beta1 - */ - @Beta - protected XSSFPivotCacheDefinition(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFPivotCacheDefinition(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - @Beta - public void readFrom(InputStream is) throws IOException { - try { - XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS); - //Removing root element - options.setLoadReplaceDocumentElement(null); - ctPivotCacheDefinition = CTPivotCacheDefinition.Factory.parse(is, options); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - @Beta - @Internal - public CTPivotCacheDefinition getCTPivotCacheDefinition() { - return ctPivotCacheDefinition; - } - - @Beta - private void createDefaultValues() { - ctPivotCacheDefinition.setCreatedVersion(XSSFPivotTable.CREATED_VERSION); - ctPivotCacheDefinition.setMinRefreshableVersion(XSSFPivotTable.MIN_REFRESHABLE_VERSION); - ctPivotCacheDefinition.setRefreshedVersion(XSSFPivotTable.UPDATED_VERSION); - ctPivotCacheDefinition.setRefreshedBy("Apache POI"); - ctPivotCacheDefinition.setRefreshedDate(new Date().getTime()); - ctPivotCacheDefinition.setRefreshOnLoad(true); - } - - @Beta - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - //Sets the pivotCacheDefinition tag - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTPivotCacheDefinition.type.getName(). - getNamespaceURI(), "pivotCacheDefinition")); - ctPivotCacheDefinition.save(out, xmlOptions); - out.close(); - } - - /** - * Find the 2D base data area for the pivot table, either from its direct reference or named table/range. - * @return AreaReference representing the current area defined by the pivot table - * @throws IllegalArgumentException if the ref attribute is not contiguous or the name attribute is not found. - */ - @Beta - public AreaReference getPivotArea(Workbook wb) throws IllegalArgumentException { - final CTWorksheetSource wsSource = ctPivotCacheDefinition.getCacheSource().getWorksheetSource(); - - final String ref = wsSource.getRef(); - final String name = wsSource.getName(); - - if (ref == null && name == null) throw new IllegalArgumentException("Pivot cache must reference an area, named range, or table."); - - // this is the XML format, so tell the reference that. - if (ref != null) return new AreaReference(ref, SpreadsheetVersion.EXCEL2007); - - if (name != null) { - // named range or table? - final Name range = wb.getName(name); - if (range != null) return new AreaReference(range.getRefersToFormula(), SpreadsheetVersion.EXCEL2007); - // not a named range, check for a table. - // do this second, as tables are sheet-specific, but named ranges are not, and may not have a sheet name given. - final XSSFSheet sheet = (XSSFSheet) wb.getSheet(wsSource.getSheet()); - for (XSSFTable table : sheet.getTables()) { - if (table.getName().equals(name)) { //case-sensitive? - return new AreaReference(table.getStartCellReference(), table.getEndCellReference()); - } - } - } - - throw new IllegalArgumentException("Name '" + name + "' was not found."); - } - - /** - * Generates a cache field for each column in the reference area for the pivot table. - * @param sheet The sheet where the data i collected from - */ - @Beta - protected void createCacheFields(Sheet sheet) { - //Get values for start row, start and end column - AreaReference ar = getPivotArea(sheet.getWorkbook()); - CellReference firstCell = ar.getFirstCell(); - CellReference lastCell = ar.getLastCell(); - int columnStart = firstCell.getCol(); - int columnEnd = lastCell.getCol(); - Row row = sheet.getRow(firstCell.getRow()); - CTCacheFields cFields; - if(ctPivotCacheDefinition.getCacheFields() != null) { - cFields = ctPivotCacheDefinition.getCacheFields(); - } else { - cFields = ctPivotCacheDefinition.addNewCacheFields(); - } - //For each column, create a cache field and give it en empty sharedItems - for(int i=columnStart; i<=columnEnd; i++) { - CTCacheField cf = cFields.addNewCacheField(); - if(i==columnEnd){ - cFields.setCount(cFields.sizeOfCacheFieldArray()); - } - //General number format - cf.setNumFmtId(0); - Cell cell = row.getCell(i); - cell.setCellType(CellType.STRING); - cf.setName(row.getCell(i).getStringCellValue()); - cf.addNewSharedItems(); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java deleted file mode 100644 index 5dcf0d3b7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCacheRecords; - -public class XSSFPivotCacheRecords extends POIXMLDocumentPart { - private CTPivotCacheRecords ctPivotCacheRecords; - - @Beta - public XSSFPivotCacheRecords() { - super(); - ctPivotCacheRecords = CTPivotCacheRecords.Factory.newInstance(); - } - - /** - * Creates an XSSFPivotCacheRecords representing the given package part and relationship. - * Should only be called when reading in an existing file. - * - * @param part - The package part that holds xml data representing this pivot cache records. - * - * @since POI 3.14-Beta1 - */ - @Beta - protected XSSFPivotCacheRecords(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFPivotCacheRecords(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - @Beta - protected void readFrom(InputStream is) throws IOException { - try { - XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS); - //Removing root element - options.setLoadReplaceDocumentElement(null); - ctPivotCacheRecords = CTPivotCacheRecords.Factory.parse(is, options); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - @Beta - @Internal - public CTPivotCacheRecords getCtPivotCacheRecords() { - return ctPivotCacheRecords; - } - - @Beta - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - //Sets the pivotCacheDefinition tag - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTPivotCacheRecords.type.getName(). - getNamespaceURI(), "pivotCacheRecords")); - ctPivotCacheRecords.save(out, xmlOptions); - out.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java deleted file mode 100644 index e6f91afde..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java +++ /dev/null @@ -1,479 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DataConsolidateFunction; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; - -public class XSSFPivotTable extends POIXMLDocumentPart { - - protected final static short CREATED_VERSION = 3; - protected final static short MIN_REFRESHABLE_VERSION = 3; - protected final static short UPDATED_VERSION = 3; - - private CTPivotTableDefinition pivotTableDefinition; - private XSSFPivotCacheDefinition pivotCacheDefinition; - private XSSFPivotCache pivotCache; - private XSSFPivotCacheRecords pivotCacheRecords; - private Sheet parentSheet; - private Sheet dataSheet; - - @Beta - protected XSSFPivotTable() { - super(); - pivotTableDefinition = CTPivotTableDefinition.Factory.newInstance(); - pivotCache = new XSSFPivotCache(); - pivotCacheDefinition = new XSSFPivotCacheDefinition(); - pivotCacheRecords = new XSSFPivotCacheRecords(); - } - - /** - * Creates an XSSFPivotTable representing the given package part and relationship. - * Should only be called when reading in an existing file. - * - * @param part - The package part that holds xml data representing this pivot table. - * - * @since POI 3.14-Beta1 - */ - @Beta - protected XSSFPivotTable(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFPivotTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - @Beta - public void readFrom(InputStream is) throws IOException { - try { - XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS); - //Removing root element - options.setLoadReplaceDocumentElement(null); - pivotTableDefinition = CTPivotTableDefinition.Factory.parse(is, options); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - @Beta - public void setPivotCache(XSSFPivotCache pivotCache) { - this.pivotCache = pivotCache; - } - - @Beta - public XSSFPivotCache getPivotCache() { - return pivotCache; - } - - @Beta - public Sheet getParentSheet() { - return parentSheet; - } - - @Beta - public void setParentSheet(XSSFSheet parentSheet) { - this.parentSheet = parentSheet; - } - - @Beta - @Internal - public CTPivotTableDefinition getCTPivotTableDefinition() { - return pivotTableDefinition; - } - - @Beta - @Internal - public void setCTPivotTableDefinition(CTPivotTableDefinition pivotTableDefinition) { - this.pivotTableDefinition = pivotTableDefinition; - } - - @Beta - public XSSFPivotCacheDefinition getPivotCacheDefinition() { - return pivotCacheDefinition; - } - - @Beta - public void setPivotCacheDefinition(XSSFPivotCacheDefinition pivotCacheDefinition) { - this.pivotCacheDefinition = pivotCacheDefinition; - } - - @Beta - public XSSFPivotCacheRecords getPivotCacheRecords() { - return pivotCacheRecords; - } - - @Beta - public void setPivotCacheRecords(XSSFPivotCacheRecords pivotCacheRecords) { - this.pivotCacheRecords = pivotCacheRecords; - } - - @Beta - public Sheet getDataSheet() { - return dataSheet; - } - - @Beta - private void setDataSheet(Sheet dataSheet) { - this.dataSheet = dataSheet; - } - - @Beta - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - //Sets the pivotTableDefinition tag - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTPivotTableDefinition.type.getName(). - getNamespaceURI(), "pivotTableDefinition")); - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - pivotTableDefinition.save(out, xmlOptions); - out.close(); - } - - /** - * Set default values for the table definition. - */ - @Beta - protected void setDefaultPivotTableDefinition() { - //Not more than one until more created - pivotTableDefinition.setMultipleFieldFilters(false); - //Indentation increment for compact rows - pivotTableDefinition.setIndent(0); - //The pivot version which created the pivot cache set to default value - pivotTableDefinition.setCreatedVersion(CREATED_VERSION); - //Minimun version required to update the pivot cache - pivotTableDefinition.setMinRefreshableVersion(MIN_REFRESHABLE_VERSION); - //Version of the application which "updated the spreadsheet last" - pivotTableDefinition.setUpdatedVersion(UPDATED_VERSION); - //Titles shown at the top of each page when printed - pivotTableDefinition.setItemPrintTitles(true); - //Set autoformat properties - pivotTableDefinition.setUseAutoFormatting(true); - pivotTableDefinition.setApplyNumberFormats(false); - pivotTableDefinition.setApplyWidthHeightFormats(true); - pivotTableDefinition.setApplyAlignmentFormats(false); - pivotTableDefinition.setApplyPatternFormats(false); - pivotTableDefinition.setApplyFontFormats(false); - pivotTableDefinition.setApplyBorderFormats(false); - pivotTableDefinition.setCacheId(pivotCache.getCTPivotCache().getCacheId()); - pivotTableDefinition.setName("PivotTable"+pivotTableDefinition.getCacheId()); - pivotTableDefinition.setDataCaption("Values"); - - //Set the default style for the pivot table - CTPivotTableStyle style = pivotTableDefinition.addNewPivotTableStyleInfo(); - style.setName("PivotStyleLight16"); - style.setShowLastColumn(true); - style.setShowColStripes(false); - style.setShowRowStripes(false); - style.setShowColHeaders(true); - style.setShowRowHeaders(true); - } - - protected AreaReference getPivotArea() { - final Workbook wb = getDataSheet().getWorkbook(); - AreaReference pivotArea = getPivotCacheDefinition().getPivotArea(wb); - return pivotArea; - } - - /** - * Verify column index (relative to first column in pivot area) is within the - * pivot area - * - * @param columnIndex - * @throws IndexOutOfBoundsException - */ - private void checkColumnIndex(int columnIndex) throws IndexOutOfBoundsException { - AreaReference pivotArea = getPivotArea(); - int size = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol() + 1; - - if (columnIndex < 0 || columnIndex >= size) { - throw new IndexOutOfBoundsException("Column Index: " + columnIndex + ", Size: " + size); - } - } - - /** - * Add a row label using data from the given column. - * @param columnIndex the index of the source column to be used as row label. - * {@code columnIndex} is 0-based indexed and relative to the first column in the source. - */ - @Beta - public void addRowLabel(int columnIndex) { - checkColumnIndex(columnIndex); - - AreaReference pivotArea = getPivotArea(); - final int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow(); - CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); - - CTPivotField pivotField = CTPivotField.Factory.newInstance(); - CTItems items = pivotField.addNewItems(); - - pivotField.setAxis(STAxis.AXIS_ROW); - pivotField.setShowAll(false); - for (int i = 0; i <= lastRowIndex; i++) { - items.addNewItem().setT(STItemType.DEFAULT); - } - items.setCount(items.sizeOfItemArray()); - pivotFields.setPivotFieldArray(columnIndex, pivotField); - - CTRowFields rowFields; - if(pivotTableDefinition.getRowFields() != null) { - rowFields = pivotTableDefinition.getRowFields(); - } else { - rowFields = pivotTableDefinition.addNewRowFields(); - } - - rowFields.addNewField().setX(columnIndex); - rowFields.setCount(rowFields.sizeOfFieldArray()); - } - - @Beta - public List getRowLabelColumns() { - if (pivotTableDefinition.getRowFields() != null) { - List columnIndexes = new ArrayList(); - for (CTField f : pivotTableDefinition.getRowFields().getFieldArray()) { - columnIndexes.add(f.getX()); - } - return columnIndexes; - } else { - return Collections.emptyList(); - } - } - - /** - * Add a column label using data from the given column and specified function - * @param columnIndex the index of the source column to be used as column label. - * {@code columnIndex} is 0-based indexed and relative to the first column in the source. - * @param function the function to be used on the data - * The following functions exists: - * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp - * @param valueFieldName the name of pivot table value field - */ - @Beta - public void addColumnLabel(DataConsolidateFunction function, int columnIndex, String valueFieldName) { - checkColumnIndex(columnIndex); - - addDataColumn(columnIndex, true); - addDataField(function, columnIndex, valueFieldName); - - // colfield should be added for the second one. - if (pivotTableDefinition.getDataFields().getCount() == 2) { - CTColFields colFields; - if(pivotTableDefinition.getColFields() != null) { - colFields = pivotTableDefinition.getColFields(); - } else { - colFields = pivotTableDefinition.addNewColFields(); - } - colFields.addNewField().setX(-2); - colFields.setCount(colFields.sizeOfFieldArray()); - } - } - - /** - * Add a column label using data from the given column and specified function - * @param columnIndex the index of the source column to be used as column label - * {@code columnIndex} is 0-based indexed and relative to the first column in the source.. - * @param function the function to be used on the data - * The following functions exists: - * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp - */ - @Beta - public void addColumnLabel(DataConsolidateFunction function, int columnIndex) { - addColumnLabel(function, columnIndex, function.getName()); - } - - /** - * Add data field with data from the given column and specified function. - * @param function the function to be used on the data - * The following functions exists: - * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp - * @param columnIndex the index of the column to be used as column label. - * @param valueFieldName the name of pivot table value field - */ - @Beta - private void addDataField(DataConsolidateFunction function, int columnIndex, String valueFieldName) { - checkColumnIndex(columnIndex); - - AreaReference pivotArea = getPivotArea(); - - CTDataFields dataFields; - if(pivotTableDefinition.getDataFields() != null) { - dataFields = pivotTableDefinition.getDataFields(); - } else { - dataFields = pivotTableDefinition.addNewDataFields(); - } - CTDataField dataField = dataFields.addNewDataField(); - dataField.setSubtotal(STDataConsolidateFunction.Enum.forInt(function.getValue())); - Cell cell = getDataSheet().getRow(pivotArea.getFirstCell().getRow()) - .getCell(pivotArea.getFirstCell().getCol() + columnIndex); - cell.setCellType(CellType.STRING); - dataField.setName(valueFieldName); - dataField.setFld(columnIndex); - dataFields.setCount(dataFields.sizeOfDataFieldArray()); - } - - /** - * Add column containing data from the referenced area. - * @param columnIndex the index of the column containing the data - * @param isDataField true if the data should be displayed in the pivot table. - */ - @Beta - public void addDataColumn(int columnIndex, boolean isDataField) { - checkColumnIndex(columnIndex); - - CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); - CTPivotField pivotField = CTPivotField.Factory.newInstance(); - - pivotField.setDataField(isDataField); - pivotField.setShowAll(false); - pivotFields.setPivotFieldArray(columnIndex, pivotField); - } - - /** - * Add filter for the column with the corresponding index and cell value - * @param columnIndex index of column to filter on - */ - @Beta - public void addReportFilter(int columnIndex) { - checkColumnIndex(columnIndex); - - AreaReference pivotArea = getPivotArea(); - int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow(); - - CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); - - CTPivotField pivotField = CTPivotField.Factory.newInstance(); - CTItems items = pivotField.addNewItems(); - - pivotField.setAxis(STAxis.AXIS_PAGE); - pivotField.setShowAll(false); - for(int i = 0; i <= lastRowIndex; i++) { - items.addNewItem().setT(STItemType.DEFAULT); - } - items.setCount(items.sizeOfItemArray()); - pivotFields.setPivotFieldArray(columnIndex, pivotField); - - CTPageFields pageFields; - if (pivotTableDefinition.getPageFields()!= null) { - pageFields = pivotTableDefinition.getPageFields(); - //Another filter has already been created - pivotTableDefinition.setMultipleFieldFilters(true); - } else { - pageFields = pivotTableDefinition.addNewPageFields(); - } - CTPageField pageField = pageFields.addNewPageField(); - pageField.setHier(-1); - pageField.setFld(columnIndex); - - pageFields.setCount(pageFields.sizeOfPageFieldArray()); - pivotTableDefinition.getLocation().setColPageCount(pageFields.getCount()); - } - - /** - * Creates cacheSource and workSheetSource for pivot table and sets the source reference as well assets the location of the pivot table - * @param position Position for pivot table in sheet - * @param sourceSheet Sheet where the source will be collected from - * @param refConfig an configurator that knows how to configure pivot table references - */ - @Beta - protected void createSourceReferences(CellReference position, Sheet sourceSheet, PivotTableReferenceConfigurator refConfig){ - - //Get cell one to the right and one down from position, add both to AreaReference and set pivot table location. - AreaReference destination = new AreaReference(position, new CellReference(position.getRow()+1, position.getCol()+1)); - - CTLocation location; - if(pivotTableDefinition.getLocation() == null) { - location = pivotTableDefinition.addNewLocation(); - location.setFirstDataCol(1); - location.setFirstDataRow(1); - location.setFirstHeaderRow(1); - } else { - location = pivotTableDefinition.getLocation(); - } - location.setRef(destination.formatAsString()); - pivotTableDefinition.setLocation(location); - - //Set source for the pivot table - CTPivotCacheDefinition cacheDef = getPivotCacheDefinition().getCTPivotCacheDefinition(); - CTCacheSource cacheSource = cacheDef.addNewCacheSource(); - cacheSource.setType(STSourceType.WORKSHEET); - CTWorksheetSource worksheetSource = cacheSource.addNewWorksheetSource(); - worksheetSource.setSheet(sourceSheet.getSheetName()); - setDataSheet(sourceSheet); - - refConfig.configureReference(worksheetSource); - if (worksheetSource.getName() == null && worksheetSource.getRef() == null) throw new IllegalArgumentException("Pivot table source area reference or name must be specified."); - } - - @Beta - protected void createDefaultDataColumns() { - CTPivotFields pivotFields; - if (pivotTableDefinition.getPivotFields() != null) { - pivotFields = pivotTableDefinition.getPivotFields(); - } else { - pivotFields = pivotTableDefinition.addNewPivotFields(); - } - AreaReference sourceArea = getPivotArea(); - int firstColumn = sourceArea.getFirstCell().getCol(); - int lastColumn = sourceArea.getLastCell().getCol(); - CTPivotField pivotField; - for(int i = firstColumn; i<=lastColumn; i++) { - pivotField = pivotFields.addNewPivotField(); - pivotField.setDataField(false); - pivotField.setShowAll(false); - } - pivotFields.setCount(pivotFields.sizeOfPivotFieldArray()); - } - - protected static interface PivotTableReferenceConfigurator { - - /** - * Configure the name or area reference for the pivot table - * @param wsSource CTWorksheetSource that needs the pivot source reference assignment - */ - public void configureReference(CTWorksheetSource wsSource); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java deleted file mode 100644 index 43b8c5a21..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java +++ /dev/null @@ -1,468 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.POIXMLException; -import org.apache.poi.ss.usermodel.PageOrder; -import org.apache.poi.ss.usermodel.PaperSize; -import org.apache.poi.ss.usermodel.PrintCellComments; -import org.apache.poi.ss.usermodel.PrintOrientation; -import org.apache.poi.ss.usermodel.PrintSetup; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetup; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellComments; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STOrientation; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPageOrder; - - -/** - * Page setup and page margins settings for the worksheet. - */ -public class XSSFPrintSetup implements PrintSetup { - private CTWorksheet ctWorksheet; - private CTPageSetup pageSetup; - private CTPageMargins pageMargins; - - protected XSSFPrintSetup(CTWorksheet worksheet) { - this.ctWorksheet = worksheet; - - if(ctWorksheet.isSetPageSetup()) { - this.pageSetup = ctWorksheet.getPageSetup(); - } else { - this.pageSetup = ctWorksheet.addNewPageSetup(); - } - if(ctWorksheet.isSetPageMargins()) { - this.pageMargins = ctWorksheet.getPageMargins(); - } else { - this.pageMargins = ctWorksheet.addNewPageMargins(); - } - } - - /** - * Set the paper size. - * - * @param size the paper size. - */ - public void setPaperSize(short size) { - pageSetup.setPaperSize(size); - } - - /** - * Set the paper size as enum value. - * - * @param size value for the paper size. - */ - public void setPaperSize(PaperSize size) { - setPaperSize((short) (size.ordinal() + 1)); - } - - /** - * Set the scale. - * Valid values range from 10 to 400. - * This setting is overridden when fitToWidth and/or fitToHeight are in use - * - * @param scale the scale to use - */ - public void setScale(short scale) { - if (scale < 10 || scale > 400) throw new POIXMLException("Scale value not accepted: you must choose a value between 10 and 400."); - pageSetup.setScale(scale); - } - - /** - * Set the page numbering start. - * Page number for first printed page. If no value is specified, then 'automatic' is assumed. - * - * @param start the page numbering start - */ - public void setPageStart(short start) { - pageSetup.setFirstPageNumber(start); - } - - /** - * Set the number of pages wide to fit the sheet in - * - * @param width the number of pages - */ - public void setFitWidth(short width) { - pageSetup.setFitToWidth(width); - } - - /** - * Set the number of pages high to fit the sheet in - * - * @param height the number of pages - */ - public void setFitHeight(short height) { - pageSetup.setFitToHeight(height); - } - - /** - * Set whether to go left to right or top down in ordering - * - * @param ltor left to right - */ - public void setLeftToRight(boolean ltor) { - if (ltor) - setPageOrder(PageOrder.OVER_THEN_DOWN); - else - setPageOrder(PageOrder.DOWN_THEN_OVER); - } - - /** - * Set whether to print in landscape - * - * @param ls landscape - */ - public void setLandscape(boolean ls) { - if (ls) - setOrientation(PrintOrientation.LANDSCAPE); - else - setOrientation(PrintOrientation.PORTRAIT); - } - - /** - * Use the printer's defaults settings for page setup values and don't use the default values - * specified in the schema. For example, if dpi is not present or specified in the XML, the - * a plication shall not assume 600dpi as specified in the schema as a default and instead - * shall let the printer specify the default dpi. - * - * @param valid Valid - */ - public void setValidSettings(boolean valid) { - pageSetup.setUsePrinterDefaults(valid); - } - - /** - * Set whether it is black and white - * - * @param mono Black and white - */ - public void setNoColor(boolean mono) { - pageSetup.setBlackAndWhite(mono); - } - - /** - * Set whether it is in draft mode - * - * @param d draft - */ - public void setDraft(boolean d) { - pageSetup.setDraft(d); - } - - /** - * Print the include notes - * - * @param printnotes print the notes - */ - public void setNotes(boolean printnotes) { - if (printnotes){ - pageSetup.setCellComments(STCellComments.AS_DISPLAYED); - } - } - - /** - * Set no orientation. - * - * @param orientation Orientation. - */ - public void setNoOrientation(boolean orientation) { - if (orientation) { - setOrientation(PrintOrientation.DEFAULT); - } - } - - /** - * Set whether to use page start - * - * @param page Use page start - */ - public void setUsePage(boolean page) { - pageSetup.setUseFirstPageNumber(page); - } - - /** - * Sets the horizontal resolution. - * - * @param resolution horizontal resolution - */ - public void setHResolution(short resolution) { - pageSetup.setHorizontalDpi(resolution); - } - - /** - * Sets the vertical resolution. - * - * @param resolution vertical resolution - */ - public void setVResolution(short resolution) { - pageSetup.setVerticalDpi(resolution); - } - - /** - * Sets the header margin. - * - * @param headermargin header margin - */ - public void setHeaderMargin(double headermargin) { - pageMargins.setHeader(headermargin); - } - - /** - * Sets the footer margin. - * - * @param footermargin footer margin - */ - public void setFooterMargin(double footermargin) { - pageMargins.setFooter(footermargin); - } - - /** - * Sets the number of copies. - * - * @param copies number of copies - */ - public void setCopies(short copies) { - pageSetup.setCopies(copies); - } - - /** - * Orientation of the page: landscape - portrait. - * - * @param orientation - Orientation of the page - * @see PrintOrientation - */ - public void setOrientation(PrintOrientation orientation) { - STOrientation.Enum v = STOrientation.Enum.forInt(orientation.getValue()); - pageSetup.setOrientation(v); - } - - /** - * Orientation of the page: landscape - portrait. - * - * @return Orientation of the page - * @see PrintOrientation - */ - public PrintOrientation getOrientation() { - STOrientation.Enum val = pageSetup.getOrientation(); - return val == null ? PrintOrientation.DEFAULT : PrintOrientation.valueOf(val.intValue()); - } - - - public PrintCellComments getCellComment() { - STCellComments.Enum val = pageSetup.getCellComments(); - return val == null ? PrintCellComments.NONE : PrintCellComments.valueOf(val.intValue()); - } - - /** - * Set print page order. - * - * @param pageOrder - */ - public void setPageOrder(PageOrder pageOrder) { - STPageOrder.Enum v = STPageOrder.Enum.forInt(pageOrder.getValue()); - pageSetup.setPageOrder(v); - } - - /** - * get print page order. - * - * @return PageOrder - */ - public PageOrder getPageOrder() { - return (pageSetup.getPageOrder() == null) ? null : PageOrder.valueOf(pageSetup.getPageOrder().intValue()); - } - - /** - * Returns the paper size. - * - * @return short - paper size - */ - public short getPaperSize() { - return (short) pageSetup.getPaperSize(); - } - - /** - * Returns the paper size as enum. - * - * @return PaperSize paper size - * @see PaperSize - */ - public PaperSize getPaperSizeEnum() { - return PaperSize.values()[getPaperSize() - 1]; - } - - /** - * Returns the scale. - * - * @return short - scale - */ - public short getScale() { - return (short) pageSetup.getScale(); - } - - /** - * Set the page numbering start. - * Page number for first printed page. If no value is specified, then 'automatic' is assumed. - * - * @return page number for first printed page - */ - public short getPageStart() { - return (short) pageSetup.getFirstPageNumber(); - } - - /** - * Returns the number of pages wide to fit sheet in. - * - * @return number of pages wide to fit sheet in - */ - public short getFitWidth() { - return (short) pageSetup.getFitToWidth(); - } - - /** - * Returns the number of pages high to fit the sheet in. - * - * @return number of pages high to fit the sheet in - */ - public short getFitHeight() { - return (short) pageSetup.getFitToHeight(); - } - - /** - * Returns the left to right print order. - * - * @return left to right print order - */ - public boolean getLeftToRight() { - return getPageOrder() == PageOrder.OVER_THEN_DOWN; - } - - /** - * Returns the landscape mode. - * - * @return landscape mode - */ - public boolean getLandscape() { - return getOrientation() == PrintOrientation.LANDSCAPE; - } - - /** - * Use the printer's defaults settings for page setup values and don't use the default values - * specified in the schema. For example, if dpi is not present or specified in the XML, the - * application shall not assume 600dpi as specified in the schema as a default and instead - * shall let the printer specify the default dpi. - * - * @return valid settings - */ - public boolean getValidSettings() { - return pageSetup.getUsePrinterDefaults(); - } - - /** - * Returns the black and white setting. - * - * @return black and white setting - */ - public boolean getNoColor() { - return pageSetup.getBlackAndWhite(); - } - - /** - * Returns the draft mode. - * - * @return draft mode - */ - public boolean getDraft() { - return pageSetup.getDraft(); - } - - /** - * Returns the print notes. - * - * @return print notes - */ - public boolean getNotes() { - return getCellComment() == PrintCellComments.AS_DISPLAYED; - } - - /** - * Returns the no orientation. - * - * @return no orientation - */ - public boolean getNoOrientation() { - return getOrientation() == PrintOrientation.DEFAULT; - } - - /** - * Returns the use page numbers. - * - * @return use page numbers - */ - public boolean getUsePage() { - return pageSetup.getUseFirstPageNumber(); - } - - /** - * Returns the horizontal resolution. - * - * @return horizontal resolution - */ - public short getHResolution() { - return (short) pageSetup.getHorizontalDpi(); - } - - /** - * Returns the vertical resolution. - * - * @return vertical resolution - */ - public short getVResolution() { - return (short) pageSetup.getVerticalDpi(); - } - - /** - * Returns the header margin. - * - * @return header margin - */ - public double getHeaderMargin() { - return pageMargins.getHeader(); - } - - /** - * Returns the footer margin. - * - * @return footer margin - */ - public double getFooterMargin() { - return pageMargins.getFooter(); - } - - /** - * Returns the number of copies. - * - * @return number of copies - */ - public short getCopies() { - return (short) pageSetup.getCopies(); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java deleted file mode 100644 index 9a16f00dc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java +++ /dev/null @@ -1,393 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.model.CalculationChain; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.model.ExternalLinksTable; -import org.apache.poi.xssf.model.MapInfo; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.model.SingleXmlCells; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.model.ThemesTable; - -/** - * Defines namespaces, content types and normal file names / naming - * patterns, for the well-known XSSF format parts. - */ -public final class XSSFRelation extends POIXMLRelation { - - private static final POILogger log = POILogFactory.getLogger(XSSFRelation.class); - - /** - * A map to lookup POIXMLRelation by its relation type - */ - private static final Map _table = new HashMap(); - - - public static final XSSFRelation WORKBOOK = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/workbook", - "/xl/workbook.xml", - null - ); - public static final XSSFRelation MACROS_WORKBOOK = new XSSFRelation( - "application/vnd.ms-excel.sheet.macroEnabled.main+xml", - PackageRelationshipTypes.CORE_DOCUMENT, - "/xl/workbook.xml", - null - ); - public static final XSSFRelation TEMPLATE_WORKBOOK = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml", - PackageRelationshipTypes.CORE_DOCUMENT, - "/xl/workbook.xml", - null - ); - - public static final XSSFRelation MACRO_TEMPLATE_WORKBOOK = new XSSFRelation( - "application/vnd.ms-excel.template.macroEnabled.main+xml", - PackageRelationshipTypes.CORE_DOCUMENT, - "/xl/workbook.xml", - null - ); - public static final XSSFRelation MACRO_ADDIN_WORKBOOK = new XSSFRelation( - "application/vnd.ms-excel.addin.macroEnabled.main+xml", - PackageRelationshipTypes.CORE_DOCUMENT, - "/xl/workbook.xml", - null - ); - - public static final XSSFRelation XLSB_BINARY_WORKBOOK = new XSSFRelation( - "application/vnd.ms-excel.sheet.binary.macroEnabled.main", - PackageRelationshipTypes.CORE_DOCUMENT, - "/xl/workbook.bin", - null - ); - - public static final XSSFRelation WORKSHEET = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", - "/xl/worksheets/sheet#.xml", - XSSFSheet.class - ); - - public static final XSSFRelation CHARTSHEET = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet", - "/xl/chartsheets/sheet#.xml", - XSSFChartSheet.class - ); - - public static final XSSFRelation SHARED_STRINGS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", - "/xl/sharedStrings.xml", - SharedStringsTable.class - ); - - public static final XSSFRelation STYLES = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml", - PackageRelationshipTypes.STYLE_PART, - "/xl/styles.xml", - StylesTable.class - ); - - public static final XSSFRelation DRAWINGS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.drawing+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing", - "/xl/drawings/drawing#.xml", - XSSFDrawing.class - ); - - public static final XSSFRelation VML_DRAWINGS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.vmlDrawing", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing", - "/xl/drawings/vmlDrawing#.vml", - XSSFVMLDrawing.class - ); - - public static final XSSFRelation CHART = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.drawingml.chart+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", - "/xl/charts/chart#.xml", - XSSFChart.class - ); - - public static final XSSFRelation CUSTOM_XML_MAPPINGS = new XSSFRelation( - "application/xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/xmlMaps", - "/xl/xmlMaps.xml", - MapInfo.class - ); - - public static final XSSFRelation SINGLE_XML_CELLS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableSingleCells", - "/xl/tables/tableSingleCells#.xml", - SingleXmlCells.class - ); - - public static final XSSFRelation TABLE = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table", - "/xl/tables/table#.xml", - XSSFTable.class - ); - - public static final XSSFRelation IMAGES = new XSSFRelation( - null, - PackageRelationshipTypes.IMAGE_PART, - null, - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_EMF = new XSSFRelation( - "image/x-emf", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.emf", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_WMF = new XSSFRelation( - "image/x-wmf", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.wmf", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_PICT = new XSSFRelation( - "image/pict", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.pict", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_JPEG = new XSSFRelation( - "image/jpeg", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.jpeg", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_PNG = new XSSFRelation( - "image/png", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.png", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_DIB = new XSSFRelation( - "image/dib", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.dib", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_GIF = new XSSFRelation( - "image/gif", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.gif", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_TIFF = new XSSFRelation( - "image/tiff", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.tiff", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_EPS = new XSSFRelation( - "image/x-eps", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.eps", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_BMP = new XSSFRelation( - "image/x-ms-bmp", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.bmp", - XSSFPictureData.class - ); - - public static final XSSFRelation IMAGE_WPG = new XSSFRelation( - "image/x-wpg", - PackageRelationshipTypes.IMAGE_PART, - "/xl/media/image#.wpg", - XSSFPictureData.class - ); - - public static final XSSFRelation SHEET_COMMENTS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", - "/xl/comments#.xml", - CommentsTable.class - ); - - public static final XSSFRelation SHEET_HYPERLINKS = new XSSFRelation( - null, - PackageRelationshipTypes.HYPERLINK_PART, - null, - null - ); - - public static final XSSFRelation OLEEMBEDDINGS = new XSSFRelation( - null, - POIXMLDocument.OLE_OBJECT_REL_TYPE, - null, - null - ); - - public static final XSSFRelation PACKEMBEDDINGS = new XSSFRelation( - null, - POIXMLDocument.PACK_OBJECT_REL_TYPE, - null, - null - ); - - public static final XSSFRelation VBA_MACROS = new XSSFRelation( - "application/vnd.ms-office.vbaProject", - "http://schemas.microsoft.com/office/2006/relationships/vbaProject", - "/xl/vbaProject.bin", - XSSFVBAPart.class - ); - - public static final XSSFRelation ACTIVEX_CONTROLS = new XSSFRelation( - "application/vnd.ms-office.activeX+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control", - "/xl/activeX/activeX#.xml", - null - ); - - public static final XSSFRelation ACTIVEX_BINS = new XSSFRelation( - "application/vnd.ms-office.activeX", - "http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary", - "/xl/activeX/activeX#.bin", - null - ); - - public static final XSSFRelation THEME = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.theme+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", - "/xl/theme/theme#.xml", - ThemesTable.class - ); - - public static final XSSFRelation CALC_CHAIN = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain", - "/xl/calcChain.xml", - CalculationChain.class - ); - - public static final XSSFRelation EXTERNAL_LINKS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink", - "/xl/externalLinks/externalLink#.xmll", - ExternalLinksTable.class - ); - - public static final XSSFRelation PRINTER_SETTINGS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings", - "/xl/printerSettings/printerSettings#.bin", - null - ); - public static final XSSFRelation PIVOT_TABLE = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable", - "/xl/pivotTables/pivotTable#.xml", - XSSFPivotTable.class - ); - public static final XSSFRelation PIVOT_CACHE_DEFINITION = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition", - "/xl/pivotCache/pivotCacheDefinition#.xml", - XSSFPivotCacheDefinition.class - ); - public static final XSSFRelation PIVOT_CACHE_RECORDS = new XSSFRelation( - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords", - "/xl/pivotCache/pivotCacheRecords#.xml", - XSSFPivotCacheRecords.class - ); - - public static final XSSFRelation CTRL_PROP_RECORDS = new XSSFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp", - "/xl/ctrlProps/ctrlProp#.xml", - null - ); - - public static final String NS_SPREADSHEETML = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; - public static final String NS_DRAWINGML = "http://schemas.openxmlformats.org/drawingml/2006/main"; - public static final String NS_CHART = "http://schemas.openxmlformats.org/drawingml/2006/chart"; - - private XSSFRelation(String type, String rel, String defaultName, Class cls) { - super(type, rel, defaultName, cls); - _table.put(rel, this); - } - - /** - * Fetches the InputStream to read the contents, based - * of the specified core part, for which we are defined - * as a suitable relationship - */ - public InputStream getContents(PackagePart corePart) throws IOException, InvalidFormatException { - PackageRelationshipCollection prc = - corePart.getRelationshipsByType(_relation); - Iterator it = prc.iterator(); - if(it.hasNext()) { - PackageRelationship rel = it.next(); - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - PackagePart part = corePart.getPackage().getPart(relName); - return part.getInputStream(); - } - log.log(POILogger.WARN, "No part " + _defaultName + " found"); - return null; - } - - /** - * Get POIXMLRelation by relation type - * - * @param rel relation type, for example, - * http://schemas.openxmlformats.org/officeDocument/2006/relationships/image - * @return registered POIXMLRelation or null if not found - */ - public static XSSFRelation getInstance(String rel){ - return _table.get(rel); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java deleted file mode 100644 index e93f0fa4a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java +++ /dev/null @@ -1,601 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.*; -import java.util.regex.Pattern; -import java.util.regex.Matcher; - -import javax.xml.namespace.QName; - -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.model.ThemesTable; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlCursor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXstring; - - -/** - * Rich text unicode string. These strings can have fonts applied to arbitary parts of the string. - * - *

        - * Most strings in a workbook have formatting applied at the cell level, that is, the entire string in the cell has the - * same formatting applied. In these cases, the formatting for the cell is stored in the styles part, - * and the string for the cell can be shared across the workbook. The following code illustrates the example. - *

        - * - *
        - *
        - *     cell1.setCellValue(new XSSFRichTextString("Apache POI"));
        - *     cell2.setCellValue(new XSSFRichTextString("Apache POI"));
        - *     cell3.setCellValue(new XSSFRichTextString("Apache POI"));
        - * 
        - *
        - * In the above example all three cells will use the same string cached on workbook level. - * - *

        - * Some strings in the workbook may have formatting applied at a level that is more granular than the cell level. - * For instance, specific characters within the string may be bolded, have coloring, italicizing, etc. - * In these cases, the formatting is stored along with the text in the string table, and is treated as - * a unique entry in the workbook. The following xml and code snippet illustrate this. - *

        - * - *
        - *
        - *     XSSFRichTextString s1 = new XSSFRichTextString("Apache POI");
        - *     s1.applyFont(boldArial);
        - *     cell1.setCellValue(s1);
        - *
        - *     XSSFRichTextString s2 = new XSSFRichTextString("Apache POI");
        - *     s2.applyFont(italicCourier);
        - *     cell2.setCellValue(s2);
        - * 
        - *
        - */ -public class XSSFRichTextString implements RichTextString { - private static final Pattern utfPtrn = Pattern.compile("_x([0-9A-Fa-f]{4})_"); - - private CTRst st; - private StylesTable styles; - - /** - * Create a rich text string - */ - public XSSFRichTextString(String str) { - st = CTRst.Factory.newInstance(); - st.setT(str); - preserveSpaces(st.xgetT()); - } - - /** - * Create empty rich text string and initialize it with empty string - */ - public XSSFRichTextString() { - st = CTRst.Factory.newInstance(); - } - - /** - * Create a rich text string from the supplied XML bean - */ - public XSSFRichTextString(CTRst st) { - this.st = st; - } - - /** - * Applies a font to the specified characters of a string. - * - * @param startIndex The start index to apply the font to (inclusive) - * @param endIndex The end index to apply the font to (exclusive) - * @param fontIndex The font to use. - */ - public void applyFont(int startIndex, int endIndex, short fontIndex) { - XSSFFont font; - if(styles == null) { - //style table is not set, remember fontIndex and set the run properties later, - //when setStylesTableReference is called - font = new XSSFFont(); - font.setFontName("#" + fontIndex); - } else { - font = styles.getFontAt(fontIndex); - } - applyFont(startIndex, endIndex, font); - } - - /** - * Applies a font to the specified characters of a string. - * - * @param startIndex The start index to apply the font to (inclusive) - * @param endIndex The end index to apply to font to (exclusive) - * @param font The index of the font to use. - */ - public void applyFont(int startIndex, int endIndex, Font font) { - if (startIndex > endIndex) - throw new IllegalArgumentException("Start index must be less than end index, but had " + startIndex + " and " + endIndex); - if (startIndex < 0 || endIndex > length()) - throw new IllegalArgumentException("Start and end index not in range, but had " + startIndex + " and " + endIndex); - - if (startIndex == endIndex) - return; - - if(st.sizeOfRArray() == 0 && st.isSetT()) { - //convert string into a text run: string - st.addNewR().setT(st.getT()); - st.unsetT(); - } - - String text = getString(); - XSSFFont xssfFont = (XSSFFont)font; - - TreeMap formats = getFormatMap(st); - CTRPrElt fmt = CTRPrElt.Factory.newInstance(); - setRunAttributes(xssfFont.getCTFont(), fmt); - applyFont(formats, startIndex, endIndex, fmt); - - CTRst newSt = buildCTRst(text, formats); - st.set(newSt); - } - - /** - * Sets the font of the entire string. - * @param font The font to use. - */ - public void applyFont(Font font) { - String text = getString(); - applyFont(0, text.length(), font); - } - - /** - * Applies the specified font to the entire string. - * - * @param fontIndex the font to apply. - */ - public void applyFont(short fontIndex) { - XSSFFont font; - if(styles == null) { - font = new XSSFFont(); - font.setFontName("#" + fontIndex); - } else { - font = styles.getFontAt(fontIndex); - } - String text = getString(); - applyFont(0, text.length(), font); - } - - /** - * Append new text to this text run and apply the specify font to it - * - * @param text the text to append - * @param font the font to apply to the appended text or null if no formatting is required - */ - public void append(String text, XSSFFont font){ - if(st.sizeOfRArray() == 0 && st.isSetT()) { - //convert string into a text run: string - CTRElt lt = st.addNewR(); - lt.setT(st.getT()); - preserveSpaces(lt.xgetT()); - st.unsetT(); - } - CTRElt lt = st.addNewR(); - lt.setT(text); - preserveSpaces(lt.xgetT()); - - if (font != null) { - CTRPrElt pr = lt.addNewRPr(); - setRunAttributes(font.getCTFont(), pr); - } - } - - /** - * Append new text to this text run - * - * @param text the text to append - */ - public void append(String text){ - append(text, null); - } - - /** - * Copy font attributes from CTFont bean into CTRPrElt bean - */ - private void setRunAttributes(CTFont ctFont, CTRPrElt pr){ - if(ctFont.sizeOfBArray() > 0) pr.addNewB().setVal(ctFont.getBArray(0).getVal()); - if(ctFont.sizeOfUArray() > 0) pr.addNewU().setVal(ctFont.getUArray(0).getVal()); - if(ctFont.sizeOfIArray() > 0) pr.addNewI().setVal(ctFont.getIArray(0).getVal()); - if(ctFont.sizeOfColorArray() > 0) { - CTColor c1 = ctFont.getColorArray(0); - CTColor c2 = pr.addNewColor(); - if(c1.isSetAuto()) c2.setAuto(c1.getAuto()); - if(c1.isSetIndexed()) c2.setIndexed(c1.getIndexed()); - if(c1.isSetRgb()) c2.setRgb(c1.getRgb()); - if(c1.isSetTheme()) c2.setTheme(c1.getTheme()); - if(c1.isSetTint()) c2.setTint(c1.getTint()); - } - if(ctFont.sizeOfSzArray() > 0) pr.addNewSz().setVal(ctFont.getSzArray(0).getVal()); - if(ctFont.sizeOfNameArray() > 0) pr.addNewRFont().setVal(ctFont.getNameArray(0).getVal()); - if(ctFont.sizeOfFamilyArray() > 0) pr.addNewFamily().setVal(ctFont.getFamilyArray(0).getVal()); - if(ctFont.sizeOfSchemeArray() > 0) pr.addNewScheme().setVal(ctFont.getSchemeArray(0).getVal()); - if(ctFont.sizeOfCharsetArray() > 0) pr.addNewCharset().setVal(ctFont.getCharsetArray(0).getVal()); - if(ctFont.sizeOfCondenseArray() > 0) pr.addNewCondense().setVal(ctFont.getCondenseArray(0).getVal()); - if(ctFont.sizeOfExtendArray() > 0) pr.addNewExtend().setVal(ctFont.getExtendArray(0).getVal()); - if(ctFont.sizeOfVertAlignArray() > 0) pr.addNewVertAlign().setVal(ctFont.getVertAlignArray(0).getVal()); - if(ctFont.sizeOfOutlineArray() > 0) pr.addNewOutline().setVal(ctFont.getOutlineArray(0).getVal()); - if(ctFont.sizeOfShadowArray() > 0) pr.addNewShadow().setVal(ctFont.getShadowArray(0).getVal()); - if(ctFont.sizeOfStrikeArray() > 0) pr.addNewStrike().setVal(ctFont.getStrikeArray(0).getVal()); - } - - /** - * Does this string have any explicit formatting applied, or is - * it just text in the default style? - */ - public boolean hasFormatting() { - //noinspection deprecation - for performance reasons! - CTRElt[] rs = st.getRArray(); - if (rs == null || rs.length == 0) { - return false; - } - for (CTRElt r : rs) { - if (r.isSetRPr()) return true; - } - return false; - } - - /** - * Removes any formatting that may have been applied to the string. - */ - public void clearFormatting() { - String text = getString(); - st.setRArray(null); - st.setT(text); - } - - /** - * The index within the string to which the specified formatting run applies. - * - * @param index the index of the formatting run - * @return the index within the string. - */ - public int getIndexOfFormattingRun(int index) { - if(st.sizeOfRArray() == 0) return 0; - - int pos = 0; - for(int i = 0; i < st.sizeOfRArray(); i++){ - CTRElt r = st.getRArray(i); - if(i == index) return pos; - - pos += r.getT().length(); - } - return -1; - } - - /** - * Returns the number of characters this format run covers. - * - * @param index the index of the formatting run - * @return the number of characters this format run covers - */ - public int getLengthOfFormattingRun(int index) { - if(st.sizeOfRArray() == 0 || index >= st.sizeOfRArray()) { - return -1; - } - - CTRElt r = st.getRArray(index); - return r.getT().length(); - } - - /** - * Returns the plain string representation. - */ - public String getString() { - if(st.sizeOfRArray() == 0) { - return utfDecode(st.getT()); - } - StringBuilder buf = new StringBuilder(); - //noinspection deprecation - for performance reasons! - for(CTRElt r : st.getRArray()){ - buf.append(r.getT()); - } - return utfDecode(buf.toString()); - } - - /** - * Removes any formatting and sets new string value - * - * @param s new string value - */ - public void setString(String s){ - clearFormatting(); - st.setT(s); - preserveSpaces(st.xgetT()); - } - - /** - * Returns the plain string representation. - */ - public String toString() { - return getString(); - } - - /** - * Returns the number of characters in this string. - */ - public int length() { - return getString().length(); - } - - /** - * @return The number of formatting runs used. - */ - public int numFormattingRuns() { - return st.sizeOfRArray(); - } - - /** - * Gets a copy of the font used in a particular formatting run. - * - * @param index the index of the formatting run - * @return A copy of the font used or null if no formatting is applied to the specified text run. - */ - public XSSFFont getFontOfFormattingRun(int index) { - if(st.sizeOfRArray() == 0 || index >= st.sizeOfRArray()) { - return null; - } - - CTRElt r = st.getRArray(index); - if(r.getRPr() != null) { - XSSFFont fnt = new XSSFFont(toCTFont(r.getRPr())); - fnt.setThemesTable(getThemesTable()); - return fnt; - } - - return null; - } - - /** - * Return a copy of the font in use at a particular index. - * - * @param index The index. - * @return A copy of the font that's currently being applied at that - * index or null if no font is being applied or the - * index is out of range. - */ - public XSSFFont getFontAtIndex( int index ) { - final ThemesTable themes = getThemesTable(); - int pos = 0; - //noinspection deprecation - for performance reasons! - for(CTRElt r : st.getRArray()){ - final int length = r.getT().length(); - if(index >= pos && index < pos + length) { - XSSFFont fnt = new XSSFFont(toCTFont(r.getRPr())); - fnt.setThemesTable(themes); - return fnt; - } - - pos += length; - } - return null; - - } - - /** - * Return the underlying xml bean - */ - @Internal - public CTRst getCTRst() { - return st; - } - - protected void setStylesTableReference(StylesTable tbl){ - styles = tbl; - if(st.sizeOfRArray() > 0) { - //noinspection deprecation - for performance reasons! - for (CTRElt r : st.getRArray()) { - CTRPrElt pr = r.getRPr(); - if(pr != null && pr.sizeOfRFontArray() > 0){ - String fontName = pr.getRFontArray(0).getVal(); - if(fontName.startsWith("#")){ - int idx = Integer.parseInt(fontName.substring(1)); - XSSFFont font = styles.getFontAt(idx); - pr.removeRFont(0); - setRunAttributes(font.getCTFont(), pr); - } - } - } - } - } - - /** - * - * CTRPrElt --> CTFont adapter - */ - protected static CTFont toCTFont(CTRPrElt pr){ - CTFont ctFont = CTFont.Factory.newInstance(); - - // Bug 58315: there are files where there is no pr-entry for a RichTextString - if(pr == null) { - return ctFont; - } - - if(pr.sizeOfBArray() > 0) ctFont.addNewB().setVal(pr.getBArray(0).getVal()); - if(pr.sizeOfUArray() > 0) ctFont.addNewU().setVal(pr.getUArray(0).getVal()); - if(pr.sizeOfIArray() > 0) ctFont.addNewI().setVal(pr.getIArray(0).getVal()); - if(pr.sizeOfColorArray() > 0) { - CTColor c1 = pr.getColorArray(0); - CTColor c2 = ctFont.addNewColor(); - if(c1.isSetAuto()) c2.setAuto(c1.getAuto()); - if(c1.isSetIndexed()) c2.setIndexed(c1.getIndexed()); - if(c1.isSetRgb()) c2.setRgb(c1.getRgb()); - if(c1.isSetTheme()) c2.setTheme(c1.getTheme()); - if(c1.isSetTint()) c2.setTint(c1.getTint()); - } - if(pr.sizeOfSzArray() > 0) ctFont.addNewSz().setVal(pr.getSzArray(0).getVal()); - if(pr.sizeOfRFontArray() > 0) ctFont.addNewName().setVal(pr.getRFontArray(0).getVal()); - if(pr.sizeOfFamilyArray() > 0) ctFont.addNewFamily().setVal(pr.getFamilyArray(0).getVal()); - if(pr.sizeOfSchemeArray() > 0) ctFont.addNewScheme().setVal(pr.getSchemeArray(0).getVal()); - if(pr.sizeOfCharsetArray() > 0) ctFont.addNewCharset().setVal(pr.getCharsetArray(0).getVal()); - if(pr.sizeOfCondenseArray() > 0) ctFont.addNewCondense().setVal(pr.getCondenseArray(0).getVal()); - if(pr.sizeOfExtendArray() > 0) ctFont.addNewExtend().setVal(pr.getExtendArray(0).getVal()); - if(pr.sizeOfVertAlignArray() > 0) ctFont.addNewVertAlign().setVal(pr.getVertAlignArray(0).getVal()); - if(pr.sizeOfOutlineArray() > 0) ctFont.addNewOutline().setVal(pr.getOutlineArray(0).getVal()); - if(pr.sizeOfShadowArray() > 0) ctFont.addNewShadow().setVal(pr.getShadowArray(0).getVal()); - if(pr.sizeOfStrikeArray() > 0) ctFont.addNewStrike().setVal(pr.getStrikeArray(0).getVal()); - - return ctFont; - } - - /** - * Add the xml:spaces="preserve" attribute if the string has leading or trailing spaces - * - * @param xs the string to check - */ - protected static void preserveSpaces(STXstring xs) { - String text = xs.getStringValue(); - if (text != null && text.length() > 0) { - char firstChar = text.charAt(0); - char lastChar = text.charAt(text.length() - 1); - if(Character.isWhitespace(firstChar) || Character.isWhitespace(lastChar)) { - XmlCursor c = xs.newCursor(); - c.toNextToken(); - c.insertAttributeWithValue(new QName("http://www.w3.org/XML/1998/namespace", "space"), "preserve"); - c.dispose(); - } - } - } - - /** - * For all characters which cannot be represented in XML as defined by the XML 1.0 specification, - * the characters are escaped using the Unicode numerical character representation escape character - * format _xHHHH_, where H represents a hexadecimal character in the character's value. - *

        - * Example: The Unicode character 0D is invalid in an XML 1.0 document, - * so it shall be escaped as _x000D_. - *

        - * See section 3.18.9 in the OOXML spec. - * - * @param value the string to decode - * @return the decoded string - */ - static String utfDecode(String value){ - if(value == null || !value.contains("_x")) { - return value; - } - - StringBuilder buf = new StringBuilder(); - Matcher m = utfPtrn.matcher(value); - int idx = 0; - while(m.find()) { - int pos = m.start(); - if( pos > idx) { - buf.append(value.substring(idx, pos)); - } - - String code = m.group(1); - int icode = Integer.decode("0x" + code); - buf.append((char)icode); - - idx = m.end(); - } - - // small optimization: don't go via StringBuilder if not necessary, - // the encodings are very rare, so we should almost always go via this shortcut. - if(idx == 0) { - return value; - } - - buf.append(value.substring(idx)); - return buf.toString(); - } - - void applyFont(TreeMap formats, int startIndex, int endIndex, CTRPrElt fmt) { - // delete format runs that fit between startIndex and endIndex - // runs intersecting startIndex and endIndex remain - int runStartIdx = 0; - for (Iterator it = formats.keySet().iterator(); it.hasNext();) { - int runEndIdx = it.next(); - if (runStartIdx >= startIndex && runEndIdx < endIndex) { - it.remove(); - } - runStartIdx = runEndIdx; - } - - if(startIndex > 0 && !formats.containsKey(startIndex)) { - // If there's a format that starts later in the string, make it start now - for(Map.Entry entry : formats.entrySet()) { - if(entry.getKey() > startIndex) { - formats.put(startIndex, entry.getValue()); - break; - } - } - } - formats.put(endIndex, fmt); - - // assure that the range [startIndex, endIndex] consists if a single run - // there can be two or three runs depending whether startIndex or endIndex - // intersected existing format runs - SortedMap sub = formats.subMap(startIndex, endIndex); - while(sub.size() > 1) sub.remove(sub.lastKey()); - } - - TreeMap getFormatMap(CTRst entry){ - int length = 0; - TreeMap formats = new TreeMap(); - //noinspection deprecation - for performance reasons! - for (CTRElt r : entry.getRArray()) { - String txt = r.getT(); - CTRPrElt fmt = r.getRPr(); - - length += txt.length(); - formats.put(length, fmt); - } - return formats; - } - - CTRst buildCTRst(String text, TreeMap formats){ - if(text.length() != formats.lastKey()) { - throw new IllegalArgumentException("Text length was " + text.length() + - " but the last format index was " + formats.lastKey()); - } - CTRst stf = CTRst.Factory.newInstance(); - int runStartIdx = 0; - for (Map.Entry me : formats.entrySet()) { - int runEndIdx = me.getKey(); - CTRElt run = stf.addNewR(); - String fragment = text.substring(runStartIdx, runEndIdx); - run.setT(fragment); - preserveSpaces(run.xgetT()); - - CTRPrElt fmt = me.getValue(); - if (fmt != null) { - run.setRPr(fmt); - } - runStartIdx = runEndIdx; - } - return stf; - } - - private ThemesTable getThemesTable() { - if(styles == null) return null; - return styles.getTheme(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java deleted file mode 100644 index e936ed554..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java +++ /dev/null @@ -1,675 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeMap; - -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellCopyPolicy; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.xssf.model.CalculationChain; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; - -/** - * High level representation of a row of a spreadsheet. - */ -public class XSSFRow implements Row, Comparable { - //private static final POILogger _logger = POILogFactory.getLogger(XSSFRow.class); - - /** - * the xml bean containing all cell definitions for this row - */ - private final CTRow _row; - - /** - * Cells of this row keyed by their column indexes. - * The TreeMap ensures that the cells are ordered by columnIndex in the ascending order. - */ - private final TreeMap _cells; - - /** - * the parent sheet - */ - private final XSSFSheet _sheet; - - /** - * Construct a XSSFRow. - * - * @param row the xml bean containing all cell definitions for this row. - * @param sheet the parent sheet. - */ - protected XSSFRow(CTRow row, XSSFSheet sheet) { - _row = row; - _sheet = sheet; - _cells = new TreeMap(); - for (CTCell c : row.getCArray()) { - XSSFCell cell = new XSSFCell(this, c); - // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer colI = new Integer(cell.getColumnIndex()); // NOSONAR - _cells.put(colI, cell); - sheet.onReadCell(cell); - } - - if (! row.isSetR()) { - // Certain file format writers skip the row number - // Assume no gaps, and give this the next row number - int nextRowNum = sheet.getLastRowNum()+2; - if (nextRowNum == 2 && sheet.getPhysicalNumberOfRows() == 0) { - nextRowNum = 1; - } - row.setR(nextRowNum); - } - } - - /** - * Returns the XSSFSheet this row belongs to - * - * @return the XSSFSheet that owns this row - */ - @Override - public XSSFSheet getSheet() { - return this._sheet; - } - - /** - * Cell iterator over the physically defined cells: - *
        -     * for (Iterator it = row.cellIterator(); it.hasNext(); ) {
        -     *     Cell cell = it.next();
        -     *     ...
        -     * }
        -     * 
        - * - * @return an iterator over cells in this row. - */ - @Override - @SuppressWarnings("unchecked") - public Iterator cellIterator() { - return (Iterator)(Iterator)_cells.values().iterator(); - } - - /** - * Alias for {@link #cellIterator()} to allow foreach loops: - *
        -     * for(Cell cell : row){
        -     *     ...
        -     * }
        -     * 
        - * - * @return an iterator over cells in this row. - */ - @Override - public Iterator iterator() { - return cellIterator(); - } - - /** - * Compares two XSSFRow objects. Two rows are equal if they belong to the same worksheet and - * their row indexes are equal. - * - * @param other the XSSFRow to be compared. - * @return
          - *
        • - * the value 0 if the row number of this XSSFRow is - * equal to the row number of the argument XSSFRow - *
        • - *
        • - * a value less than 0 if the row number of this this XSSFRow is - * numerically less than the row number of the argument XSSFRow - *
        • - *
        • - * a value greater than 0 if the row number of this this XSSFRow is - * numerically greater than the row number of the argument XSSFRow - *
        • - *
        - * @throws IllegalArgumentException if the argument row belongs to a different worksheet - */ - @Override - public int compareTo(XSSFRow other) { - if (this.getSheet() != other.getSheet()) { - throw new IllegalArgumentException("The compared rows must belong to the same sheet"); - } - - Integer thisRow = this.getRowNum(); - Integer otherRow = other.getRowNum(); - return thisRow.compareTo(otherRow); - } - - @Override - public boolean equals(Object obj) - { - if (!(obj instanceof XSSFRow)) - { - return false; - } - XSSFRow other = (XSSFRow) obj; - - return (this.getRowNum() == other.getRowNum()) && - (this.getSheet() == other.getSheet()); - } - - @Override - public int hashCode() { - return _row.hashCode(); - } - - /** - * Use this to create new cells within the row and return it. - *

        - * The cell that is returned is a {@link CellType#BLANK}. The type can be changed - * either through calling setCellValue or setCellType. - *

        - * @param columnIndex - the column number this cell represents - * @return Cell a high level representation of the created cell. - * @throws IllegalArgumentException if columnIndex < 0 or greater than 16384, - * the maximum number of columns supported by the SpreadsheetML format (.xlsx) - */ - @Override - public XSSFCell createCell(int columnIndex) { - return createCell(columnIndex, CellType.BLANK); - } - - /** - * Use this to create new cells within the row and return it. - * - * @param columnIndex - the column number this cell represents - * @param type - the cell's data type - * @return XSSFCell a high level representation of the created cell. - * @throws IllegalArgumentException if the specified cell type is invalid, columnIndex < 0 - * or greater than 16384, the maximum number of columns supported by the SpreadsheetML format (.xlsx) - * @see CellType#BLANK - * @see CellType#BOOLEAN - * @see CellType#ERROR - * @see CellType#FORMULA - * @see CellType#NUMERIC - * @see CellType#STRING - * @deprecated POI 3.15 beta 3. Use {@link #createCell(int, CellType)} instead. - */ - @Override - public XSSFCell createCell(int columnIndex, int type) { - return createCell(columnIndex, CellType.forInt(type)); - } - /** - * Use this to create new cells within the row and return it. - * - * @param columnIndex - the column number this cell represents - * @param type - the cell's data type - * @return XSSFCell a high level representation of the created cell. - * @throws IllegalArgumentException if the specified cell type is invalid, columnIndex < 0 - * or greater than 16384, the maximum number of columns supported by the SpreadsheetML format (.xlsx) - */ - @Override - public XSSFCell createCell(int columnIndex, CellType type) { - // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer colI = new Integer(columnIndex); // NOSONAR - CTCell ctCell; - XSSFCell prev = _cells.get(colI); - if(prev != null){ - ctCell = prev.getCTCell(); - ctCell.set(CTCell.Factory.newInstance()); - } else { - ctCell = _row.addNewC(); - } - XSSFCell xcell = new XSSFCell(this, ctCell); - xcell.setCellNum(columnIndex); - if (type != CellType.BLANK) { - xcell.setCellType(type); - } - _cells.put(colI, xcell); - return xcell; - } - - /** - * Returns the cell at the given (0 based) index, - * with the {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} from the parent Workbook. - * - * @return the cell at the given (0 based) index - */ - @Override - public XSSFCell getCell(int cellnum) { - return getCell(cellnum, _sheet.getWorkbook().getMissingCellPolicy()); - } - - /** - * Returns the cell at the given (0 based) index, with the specified {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} - * - * @return the cell at the given (0 based) index - * @throws IllegalArgumentException if cellnum < 0 or the specified MissingCellPolicy is invalid - */ - @Override - public XSSFCell getCell(int cellnum, MissingCellPolicy policy) { - if(cellnum < 0) throw new IllegalArgumentException("Cell index must be >= 0"); - - // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer colI = new Integer(cellnum); // NOSONAR - XSSFCell cell = _cells.get(colI); - switch (policy) { - case RETURN_NULL_AND_BLANK: - return cell; - case RETURN_BLANK_AS_NULL: - boolean isBlank = (cell != null && cell.getCellTypeEnum() == CellType.BLANK); - return (isBlank) ? null : cell; - case CREATE_NULL_AS_BLANK: - return (cell == null) ? createCell(cellnum, CellType.BLANK) : cell; - default: - throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")"); - } - } - - /** - * Get the number of the first cell contained in this row. - * - * @return short representing the first logical cell in the row, - * or -1 if the row does not contain any cells. - */ - @Override - public short getFirstCellNum() { - return (short)(_cells.size() == 0 ? -1 : _cells.firstKey()); - } - - /** - * Gets the index of the last cell contained in this row PLUS ONE. The result also - * happens to be the 1-based column number of the last cell. This value can be used as a - * standard upper bound when iterating over cells: - *
        -     * short minColIx = row.getFirstCellNum();
        -     * short maxColIx = row.getLastCellNum();
        -     * for(short colIx=minColIx; colIx<maxColIx; colIx++) {
        -     *   XSSFCell cell = row.getCell(colIx);
        -     *   if(cell == null) {
        -     *     continue;
        -     *   }
        -     *   //... do something with cell
        -     * }
        -     * 
        - * - * @return short representing the last logical cell in the row PLUS ONE, - * or -1 if the row does not contain any cells. - */ - @Override - public short getLastCellNum() { - return (short)(_cells.size() == 0 ? -1 : (_cells.lastKey() + 1)); - } - - /** - * Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned, - * See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()} - * - * @return row height measured in twips (1/20th of a point) - */ - @Override - public short getHeight() { - return (short)(getHeightInPoints()*20); - } - - /** - * Returns row height measured in point size. If the height is not set, the default worksheet value is returned, - * See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()} - * - * @return row height measured in point size - * @see org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints() - */ - @Override - public float getHeightInPoints() { - if (this._row.isSetHt()) { - return (float) this._row.getHt(); - } - return _sheet.getDefaultRowHeightInPoints(); - } - - /** - * Set the height in "twips" or 1/20th of a point. - * - * @param height the height in "twips" or 1/20th of a point. -1 resets to the default height - */ - @Override - public void setHeight(short height) { - if (height == -1) { - if (_row.isSetHt()) _row.unsetHt(); - if (_row.isSetCustomHeight()) _row.unsetCustomHeight(); - } else { - _row.setHt((double) height / 20); - _row.setCustomHeight(true); - - } - } - - /** - * Set the row's height in points. - * - * @param height the height in points. -1 resets to the default height - */ - @Override - public void setHeightInPoints(float height) { - setHeight((short)(height == -1 ? -1 : (height*20))); - } - - /** - * Gets the number of defined cells (NOT number of cells in the actual row!). - * That is to say if only columns 0,4,5 have values then there would be 3. - * - * @return int representing the number of defined cells in the row. - */ - @Override - public int getPhysicalNumberOfCells() { - return _cells.size(); - } - - /** - * Get row number this row represents - * - * @return the row number (0 based) - */ - @Override - public int getRowNum() { - return (int) (_row.getR() - 1); - } - - /** - * Set the row number of this row. - * - * @param rowIndex the row number (0-based) - * @throws IllegalArgumentException if rowNum < 0 or greater than 1048575 - */ - @Override - public void setRowNum(int rowIndex) { - int maxrow = SpreadsheetVersion.EXCEL2007.getLastRowIndex(); - if (rowIndex < 0 || rowIndex > maxrow) { - throw new IllegalArgumentException("Invalid row number (" + rowIndex - + ") outside allowable range (0.." + maxrow + ")"); - } - _row.setR(rowIndex + 1); - } - - /** - * Get whether or not to display this row with 0 height - * - * @return - height is zero or not. - */ - @Override - public boolean getZeroHeight() { - return this._row.getHidden(); - } - - /** - * Set whether or not to display this row with 0 height - * - * @param height height is zero or not. - */ - @Override - public void setZeroHeight(boolean height) { - this._row.setHidden(height); - - } - - /** - * Is this row formatted? Most aren't, but some rows - * do have whole-row styles. For those that do, you - * can get the formatting from {@link #getRowStyle()} - */ - @Override - public boolean isFormatted() { - return _row.isSetS(); - } - /** - * Returns the whole-row cell style. Most rows won't - * have one of these, so will return null. Call - * {@link #isFormatted()} to check first. - */ - @Override - public XSSFCellStyle getRowStyle() { - if(!isFormatted()) return null; - - StylesTable stylesSource = getSheet().getWorkbook().getStylesSource(); - if(stylesSource.getNumCellStyles() > 0) { - return stylesSource.getStyleAt((int)_row.getS()); - } else { - return null; - } - } - - /** - * Applies a whole-row cell styling to the row. - * If the value is null then the style information is removed, - * causing the cell to used the default workbook style. - */ - @Override - public void setRowStyle(CellStyle style) { - if(style == null) { - if(_row.isSetS()) { - _row.unsetS(); - _row.unsetCustomFormat(); - } - } else { - StylesTable styleSource = getSheet().getWorkbook().getStylesSource(); - - XSSFCellStyle xStyle = (XSSFCellStyle)style; - xStyle.verifyBelongsToStylesSource(styleSource); - - long idx = styleSource.putStyle(xStyle); - _row.setS(idx); - _row.setCustomFormat(true); - } - } - - /** - * Remove the Cell from this row. - * - * @param cell the cell to remove - */ - @Override - public void removeCell(Cell cell) { - if (cell.getRow() != this) { - throw new IllegalArgumentException("Specified cell does not belong to this row"); - } - - XSSFCell xcell = (XSSFCell)cell; - if(xcell.isPartOfArrayFormulaGroup()) { - xcell.notifyArrayFormulaChanging(); - } - if(cell.getCellTypeEnum() == CellType.FORMULA) { - _sheet.getWorkbook().onDeleteFormula(xcell); - } - // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer colI = new Integer(cell.getColumnIndex()); // NOSONAR - _cells.remove(colI); - } - - /** - * Returns the underlying CTRow xml bean containing all cell definitions in this row - * - * @return the underlying CTRow xml bean - */ - @Internal - public CTRow getCTRow(){ - return _row; - } - - /** - * Fired when the document is written to an output stream. - * - * @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) () - */ - protected void onDocumentWrite(){ - // check if cells in the CTRow are ordered - boolean isOrdered = true; - CTCell[] cArray = _row.getCArray(); - if (cArray.length != _cells.size()) { - isOrdered = false; - } else { - int i = 0; - for (XSSFCell cell : _cells.values()) { - CTCell c1 = cell.getCTCell(); - CTCell c2 = cArray[i++]; - - String r1 = c1.getR(); - String r2 = c2.getR(); - if (!(r1==null ? r2==null : r1.equals(r2))){ - isOrdered = false; - break; - } - } - } - - if(!isOrdered){ - cArray = new CTCell[_cells.size()]; - int i = 0; - for (XSSFCell xssfCell : _cells.values()) { - cArray[i] = (CTCell) xssfCell.getCTCell().copy(); - - // we have to copy and re-create the XSSFCell here because the - // elements as otherwise setCArray below invalidates all the columns! - // see Bug 56170, XMLBeans seems to always release previous objects - // in the CArray, so we need to provide completely new ones here! - //_cells.put(entry.getKey(), new XSSFCell(this, cArray[i])); - xssfCell.setCTCell(cArray[i]); - i++; - } - - _row.setCArray(cArray); - } - } - - /** - * @return formatted xml representation of this row - */ - @Override - public String toString(){ - return _row.toString(); - } - - /** - * update cell references when shifting rows - * - * @param n the number of rows to move - */ - protected void shift(int n) { - int rownum = getRowNum() + n; - CalculationChain calcChain = _sheet.getWorkbook().getCalculationChain(); - int sheetId = (int)_sheet.sheet.getSheetId(); - String msg = "Row[rownum="+getRowNum()+"] contains cell(s) included in a multi-cell array formula. " + - "You cannot change part of an array."; - for(Cell c : this){ - XSSFCell cell = (XSSFCell)c; - if(cell.isPartOfArrayFormulaGroup()){ - cell.notifyArrayFormulaChanging(msg); - } - - //remove the reference in the calculation chain - if(calcChain != null) calcChain.removeItem(sheetId, cell.getReference()); - - CTCell ctCell = cell.getCTCell(); - String r = new CellReference(rownum, cell.getColumnIndex()).formatAsString(); - ctCell.setR(r); - } - setRowNum(rownum); - } - - /** - * Copy the cells from srcRow to this row - * If this row is not a blank row, this will merge the two rows, overwriting - * the cells in this row with the cells in srcRow - * If srcRow is null, overwrite cells in destination row with blank values, styles, etc per cell copy policy - * srcRow may be from a different sheet in the same workbook - * @param srcRow the rows to copy from - * @param policy the policy to determine what gets copied - */ - @Beta - public void copyRowFrom(Row srcRow, CellCopyPolicy policy) { - if (srcRow == null) { - // srcRow is blank. Overwrite cells with blank values, blank styles, etc per cell copy policy - for (Cell destCell : this) { - final XSSFCell srcCell = null; - // FIXME: remove type casting when copyCellFrom(Cell, CellCopyPolicy) is added to Cell interface - ((XSSFCell)destCell).copyCellFrom(srcCell, policy); - } - - if (policy.isCopyMergedRegions()) { - // Remove MergedRegions in dest row - final int destRowNum = getRowNum(); - int index = 0; - final Set indices = new HashSet(); - for (CellRangeAddress destRegion : getSheet().getMergedRegions()) { - if (destRowNum == destRegion.getFirstRow() && destRowNum == destRegion.getLastRow()) { - indices.add(index); - } - index++; - } - getSheet().removeMergedRegions(indices); - } - - if (policy.isCopyRowHeight()) { - // clear row height - setHeight((short)-1); - } - - } - else { - for (final Cell c : srcRow){ - final XSSFCell srcCell = (XSSFCell)c; - final XSSFCell destCell = createCell(srcCell.getColumnIndex(), srcCell.getCellTypeEnum()); - destCell.copyCellFrom(srcCell, policy); - } - - final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet); - final int sheetIndex = _sheet.getWorkbook().getSheetIndex(_sheet); - final String sheetName = _sheet.getWorkbook().getSheetName(sheetIndex); - final int srcRowNum = srcRow.getRowNum(); - final int destRowNum = getRowNum(); - final int rowDifference = destRowNum - srcRowNum; - final FormulaShifter shifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007); - rowShifter.updateRowFormulas(this, shifter); - - // Copy merged regions that are fully contained on the row - // FIXME: is this something that rowShifter could be doing? - if (policy.isCopyMergedRegions()) { - for (CellRangeAddress srcRegion : srcRow.getSheet().getMergedRegions()) { - if (srcRowNum == srcRegion.getFirstRow() && srcRowNum == srcRegion.getLastRow()) { - CellRangeAddress destRegion = srcRegion.copy(); - destRegion.setFirstRow(destRowNum); - destRegion.setLastRow(destRowNum); - getSheet().addMergedRegion(destRegion); - } - } - } - - if (policy.isCopyRowHeight()) { - setHeight(srcRow.getHeight()); - } - } - } - - @Override - public int getOutlineLevel() { - return _row.getOutlineLevel(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java deleted file mode 100644 index 2c63525b0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.CTLineProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; - -/** - * Represents a shape in a SpreadsheetML drawing. - * - * @author Yegor Kozlov - */ -public abstract class XSSFShape { - public static final int EMU_PER_PIXEL = 9525; - public static final int EMU_PER_POINT = 12700; - - public static final int POINT_DPI = 72; - public static final int PIXEL_DPI = 96; - - /** - * Parent drawing - */ - protected XSSFDrawing drawing; - - /** - * The parent shape, always not-null for shapes in groups - */ - protected XSSFShapeGroup parent; - - /** - * anchor that is used by this shape - */ - protected XSSFAnchor anchor; - - /** - * Return the drawing that owns this shape - * - * @return the parent drawing that owns this shape - */ - public XSSFDrawing getDrawing(){ - return drawing; - } - - /** - * Gets the parent shape. - */ - public XSSFShapeGroup getParent() - { - return parent; - } - - /** - * @return the anchor that is used by this shape. - */ - public XSSFAnchor getAnchor() - { - return anchor; - } - - /** - * Returns xml bean with shape properties. - * - * @return xml bean with shape properties. - */ - protected abstract CTShapeProperties getShapeProperties(); - - /** - * Whether this shape is not filled with a color - * - * @return true if this shape is not filled with a color. - */ - public boolean isNoFill() { - return getShapeProperties().isSetNoFill(); - } - - /** - * Sets whether this shape is filled or transparent. - * - * @param noFill if true then no fill will be applied to the shape element. - */ - public void setNoFill(boolean noFill) { - CTShapeProperties props = getShapeProperties(); - //unset solid and pattern fills if they are set - if (props.isSetPattFill()) props.unsetPattFill(); - if (props.isSetSolidFill()) props.unsetSolidFill(); - - props.setNoFill(CTNoFillProperties.Factory.newInstance()); - } - - /** - * Sets the color used to fill this shape using the solid fill pattern. - */ - public void setFillColor(int red, int green, int blue) { - CTShapeProperties props = getShapeProperties(); - CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill(); - CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); - rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue}); - fill.setSrgbClr(rgb); - } - - /** - * The color applied to the lines of this shape. - */ - public void setLineStyleColor( int red, int green, int blue ) { - CTShapeProperties props = getShapeProperties(); - CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); - CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill(); - CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); - rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue}); - fill.setSrgbClr(rgb); - } - - /** - * Specifies the width to be used for the underline stroke. - * - * @param lineWidth width in points - */ - public void setLineWidth( double lineWidth ) { - CTShapeProperties props = getShapeProperties(); - CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); - ln.setW((int)(lineWidth*EMU_PER_POINT)); - } - - /** - * Sets the line style. - * - * @param lineStyle - */ - public void setLineStyle( int lineStyle ) { - CTShapeProperties props = getShapeProperties(); - CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); - CTPresetLineDashProperties dashStyle = CTPresetLineDashProperties.Factory.newInstance(); - dashStyle.setVal(STPresetLineDashVal.Enum.forInt(lineStyle+1)); - ln.setPrstDash(dashStyle); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java deleted file mode 100644 index b625134a7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShapeNonVisual; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; - -/** - * 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; - } - - @Internal - public CTGroupShape getCTGroupShape() { - return ctGroup; - } - - /** - * Sets the coordinate space of this group. All children are constrained - * to these coordinates. - */ - public void setCoordinates(int x1, int y1, int x2, int y2) { - CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm(); - CTPoint2D off = t2d.getOff(); - off.setX(x1); - off.setY(y1); - CTPositiveSize2D ext = t2d.getExt(); - ext.setCx(x2); - ext.setCy(y2); - - CTPoint2D chOff = t2d.getChOff(); - chOff.setX(x1); - chOff.setY(y1); - CTPositiveSize2D chExt = t2d.getChExt(); - chExt.setCx(x2); - chExt.setCy(y2); - } - - protected CTShapeProperties getShapeProperties() { - throw new IllegalStateException("Not supported for shape group"); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java deleted file mode 100644 index 563c55f45..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ /dev/null @@ -1,4382 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.setPassword; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.validatePassword; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellCopyPolicy; -import org.apache.poi.ss.usermodel.CellRange; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.Footer; -import org.apache.poi.ss.usermodel.Header; -import org.apache.poi.ss.usermodel.IgnoredErrorType; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Table; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.PaneInformation; -import org.apache.poi.ss.util.SSCellRange; -import org.apache.poi.ss.util.SheetUtil; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Removal; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.usermodel.XSSFPivotTable.PivotTableReferenceConfigurator; -import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; -import org.apache.poi.xssf.usermodel.helpers.XSSFIgnoredErrorHelper; -import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; - -/** - * High level representation of a SpreadsheetML worksheet. - * - *

        - * Sheets are the central structures within a workbook, and are where a user does most of his spreadsheet work. - * The most common type of sheet is the worksheet, which is represented as a grid of cells. Worksheet cells can - * contain text, numbers, dates, and formulas. Cells can also be formatted. - *

        - */ -public class XSSFSheet extends POIXMLDocumentPart implements Sheet { - private static final POILogger logger = POILogFactory.getLogger(XSSFSheet.class); - - private static final double DEFAULT_ROW_HEIGHT = 15.0; - private static final double DEFAULT_MARGIN_HEADER = 0.3; - private static final double DEFAULT_MARGIN_FOOTER = 0.3; - private static final double DEFAULT_MARGIN_TOP = 0.75; - private static final double DEFAULT_MARGIN_BOTTOM = 0.75; - private static final double DEFAULT_MARGIN_LEFT = 0.7; - private static final double DEFAULT_MARGIN_RIGHT = 0.7; - public static final int TWIPS_PER_POINT = 20; - - //TODO make the two variable below private! - protected CTSheet sheet; - protected CTWorksheet worksheet; - - private final SortedMap _rows = new TreeMap(); - private List hyperlinks; - private ColumnHelper columnHelper; - private CommentsTable sheetComments; - /** - * cache of master shared formulas in this sheet. - * Master shared formula is the first formula in a group of shared formulas is saved in the f element. - */ - private Map sharedFormulas; - private SortedMap tables; - private List arrayFormulas; - private XSSFDataValidationHelper dataValidationHelper; - - /** - * Creates new XSSFSheet - called by XSSFWorkbook to create a sheet from scratch. - * - * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#createSheet() - */ - protected XSSFSheet() { - super(); - dataValidationHelper = new XSSFDataValidationHelper(this); - onDocumentCreate(); - } - - /** - * Creates an XSSFSheet representing the given package part and relationship. - * Should only be called by XSSFWorkbook when reading in an existing file. - * - * @param part - The package part that holds xml data representing this sheet. - * - * @since POI 3.14-Beta1 - */ - protected XSSFSheet(PackagePart part) { - super(part); - dataValidationHelper = new XSSFDataValidationHelper(this); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFSheet(PackagePart part, PackageRelationship rel) { - this(part); - } - - /** - * Returns the parent XSSFWorkbook - * - * @return the parent XSSFWorkbook - */ - @Override - public XSSFWorkbook getWorkbook() { - return (XSSFWorkbook)getParent(); - } - - /** - * Initialize worksheet data when reading in an exisiting file. - */ - @Override - protected void onDocumentRead() { - try { - read(getPackagePart().getInputStream()); - } catch (IOException e){ - throw new POIXMLException(e); - } - } - - protected void read(InputStream is) throws IOException { - try { - worksheet = WorksheetDocument.Factory.parse(is, DEFAULT_XML_OPTIONS).getWorksheet(); - } catch (XmlException e){ - throw new POIXMLException(e); - } - - initRows(worksheet); - columnHelper = new ColumnHelper(worksheet); - // Look for bits we're interested in - for(RelationPart rp : getRelationParts()){ - POIXMLDocumentPart p = rp.getDocumentPart(); - if(p instanceof CommentsTable) { - sheetComments = (CommentsTable)p; - } - if(p instanceof XSSFTable) { - tables.put( rp.getRelationship().getId(), (XSSFTable)p ); - } - if(p instanceof XSSFPivotTable) { - getWorkbook().getPivotTables().add((XSSFPivotTable) p); - } - } - - // Process external hyperlinks for the sheet, if there are any - initHyperlinks(); - } - - /** - * Initialize worksheet data when creating a new sheet. - */ - @Override - protected void onDocumentCreate(){ - worksheet = newSheet(); - initRows(worksheet); - columnHelper = new ColumnHelper(worksheet); - hyperlinks = new ArrayList(); - } - - private void initRows(CTWorksheet worksheetParam) { - _rows.clear(); - tables = new TreeMap(); - sharedFormulas = new HashMap(); - arrayFormulas = new ArrayList(); - for (CTRow row : worksheetParam.getSheetData().getRowArray()) { - XSSFRow r = new XSSFRow(row, this); - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer rownumI = new Integer(r.getRowNum()); // NOSONAR - _rows.put(rownumI, r); - } - } - - /** - * Read hyperlink relations, link them with CTHyperlink beans in this worksheet - * and initialize the internal array of XSSFHyperlink objects - */ - private void initHyperlinks() { - hyperlinks = new ArrayList(); - - if(!worksheet.isSetHyperlinks()) return; - - try { - PackageRelationshipCollection hyperRels = - getPackagePart().getRelationshipsByType(XSSFRelation.SHEET_HYPERLINKS.getRelation()); - - // Turn each one into a XSSFHyperlink - for(CTHyperlink hyperlink : worksheet.getHyperlinks().getHyperlinkArray()) { - PackageRelationship hyperRel = null; - if(hyperlink.getId() != null) { - hyperRel = hyperRels.getRelationshipByID(hyperlink.getId()); - } - - hyperlinks.add( new XSSFHyperlink(hyperlink, hyperRel) ); - } - } catch (InvalidFormatException e){ - throw new POIXMLException(e); - } - } - - /** - * Create a new CTWorksheet instance with all values set to defaults - * - * @return a new instance - */ - private static CTWorksheet newSheet(){ - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTSheetFormatPr ctFormat = worksheet.addNewSheetFormatPr(); - ctFormat.setDefaultRowHeight(DEFAULT_ROW_HEIGHT); - - CTSheetView ctView = worksheet.addNewSheetViews().addNewSheetView(); - ctView.setWorkbookViewId(0); - - worksheet.addNewDimension().setRef("A1"); - - worksheet.addNewSheetData(); - - CTPageMargins ctMargins = worksheet.addNewPageMargins(); - ctMargins.setBottom(DEFAULT_MARGIN_BOTTOM); - ctMargins.setFooter(DEFAULT_MARGIN_FOOTER); - ctMargins.setHeader(DEFAULT_MARGIN_HEADER); - ctMargins.setLeft(DEFAULT_MARGIN_LEFT); - ctMargins.setRight(DEFAULT_MARGIN_RIGHT); - ctMargins.setTop(DEFAULT_MARGIN_TOP); - - return worksheet; - } - - /** - * Provide access to the CTWorksheet bean holding this sheet's data - * - * @return the CTWorksheet bean holding this sheet's data - */ - @Internal - public CTWorksheet getCTWorksheet() { - return this.worksheet; - } - - public ColumnHelper getColumnHelper() { - return columnHelper; - } - - /** - * Returns the name of this sheet - * - * @return the name of this sheet - */ - @Override - public String getSheetName() { - return sheet.getName(); - } - - /** - * Adds a merged region of cells on a sheet. - * - * @param region to merge - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if region intersects with an existing region on this sheet - */ - @Override - public int addMergedRegion(CellRangeAddress region) { - return addMergedRegion(region, true); - } - - /** - * Adds a merged region of cells (hence those cells form one). - * Skips validation. It is possible to create overlapping merged regions - * or create a merged region that intersects a multi-cell array formula - * with this formula, which may result in a corrupt workbook. - * - * To check for merged regions overlapping array formulas or other merged regions - * after addMergedRegionUnsafe has been called, call {@link #validateMergedRegions()}, which runs in O(n^2) time. - * - * @param region to merge - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells - */ - @Override - public int addMergedRegionUnsafe(CellRangeAddress region) { - return addMergedRegion(region, false); - } - - /** - * Adds a merged region of cells (hence those cells form one). - * If validate is true, check to make sure adding the merged region to the sheet doesn't create a corrupt workbook - * If validate is false, skips the expensive merged region checks, but may produce a corrupt workbook. - * - * @param region to merge - * @param validate whether to validate merged region - * @return index of this region - * @throws IllegalArgumentException if region contains fewer than 2 cells (this check is inexpensive and is performed regardless of validate) - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if region intersects with an existing region on this sheet - */ - private int addMergedRegion(CellRangeAddress region, boolean validate) { - if (region.getNumberOfCells() < 2) { - throw new IllegalArgumentException("Merged region " + region.formatAsString() + " must contain 2 or more cells"); - } - region.validate(SpreadsheetVersion.EXCEL2007); - - if (validate) { - // throw IllegalStateException if the argument CellRangeAddress intersects with - // a multi-cell array formula defined in this sheet - validateArrayFormulas(region); - - // Throw IllegalStateException if the argument CellRangeAddress intersects with - // a merged region already in this sheet - validateMergedRegions(region); - } - - CTMergeCells ctMergeCells = worksheet.isSetMergeCells() ? worksheet.getMergeCells() : worksheet.addNewMergeCells(); - CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell(); - ctMergeCell.setRef(region.formatAsString()); - return ctMergeCells.sizeOfMergeCellArray(); - } - - /** - * Verify that the candidate region does not intersect with an existing multi-cell array formula in this sheet - * - * @param region a region that is validated. - * @throws IllegalStateException if candidate region intersects an existing array formula in this sheet - */ - private void validateArrayFormulas(CellRangeAddress region) { - // FIXME: this may be faster if it looped over array formulas directly rather than looping over each cell in - // the region and searching if that cell belongs to an array formula - int firstRow = region.getFirstRow(); - int firstColumn = region.getFirstColumn(); - int lastRow = region.getLastRow(); - int lastColumn = region.getLastColumn(); - // for each cell in sheet, if cell belongs to an array formula, check if merged region intersects array formula cells - for (int rowIn = firstRow; rowIn <= lastRow; rowIn++) { - XSSFRow row = getRow(rowIn); - if (row == null) continue; - - for (int colIn = firstColumn; colIn <= lastColumn; colIn++) { - XSSFCell cell = row.getCell(colIn); - if (cell == null) continue; - - if (cell.isPartOfArrayFormulaGroup()) { - CellRangeAddress arrayRange = cell.getArrayFormulaRange(); - if (arrayRange.getNumberOfCells() > 1 && region.intersects(arrayRange)) { - String msg = "The range " + region.formatAsString() + " intersects with a multi-cell array formula. " + - "You cannot merge cells of an array."; - throw new IllegalStateException(msg); - } - } - } - } - } - - /** - * Verify that none of the merged regions intersect a multi-cell array formula in this sheet - * - * @throws IllegalStateException if candidate region intersects an existing array formula in this sheet - */ - private void checkForMergedRegionsIntersectingArrayFormulas() { - for (CellRangeAddress region : getMergedRegions()) { - validateArrayFormulas(region); - } - } - - /** - * Verify that candidate region does not intersect with an existing merged region in this sheet - * - * @param candidateRegion - * @throws IllegalStateException if candidate region intersects an existing merged region in this sheet (or candidateRegion is already merged in this sheet) - */ - private void validateMergedRegions(CellRangeAddress candidateRegion) { - for (final CellRangeAddress existingRegion : getMergedRegions()) { - if (existingRegion.intersects(candidateRegion)) { - throw new IllegalStateException("Cannot add merged region " + candidateRegion.formatAsString() + - " to sheet because it overlaps with an existing merged region (" + existingRegion.formatAsString() + ")."); - } - } - } - - /** - * Verify that no merged regions intersect another merged region in this sheet. - * - * @throws IllegalStateException if at least one region intersects with another merged region in this sheet - */ - private void checkForIntersectingMergedRegions() { - final List regions = getMergedRegions(); - final int size = regions.size(); - for (int i=0; i < size; i++) { - final CellRangeAddress region = regions.get(i); - for (final CellRangeAddress other : regions.subList(i+1, regions.size())) { - if (region.intersects(other)) { - String msg = "The range " + region.formatAsString() + - " intersects with another merged region " + - other.formatAsString() + " in this sheet"; - throw new IllegalStateException(msg); - } - } - } - } - - /** - * Verify that merged regions do not intersect multi-cell array formulas and - * no merged regions intersect another merged region in this sheet. - * - * @throws IllegalStateException if region intersects with a multi-cell array formula - * @throws IllegalStateException if at least one region intersects with another merged region in this sheet - */ - @Override - public void validateMergedRegions() { - checkForMergedRegionsIntersectingArrayFormulas(); - checkForIntersectingMergedRegions(); - } - - /** - * Adjusts the column width to fit the contents. - * - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - * - * @param column the column index - */ - @Override - public void autoSizeColumn(int column) { - autoSizeColumn(column, false); - } - - /** - * Adjusts the column width to fit the contents. - *

        - * This process can be relatively slow on large sheets, so this should - * normally only be called once per column, at the end of your - * processing. - *

        - * You can specify whether the content of merged cells should be considered or ignored. - * Default is to ignore merged cells. - * - * @param column the column index - * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column - */ - @Override - public void autoSizeColumn(int column, boolean useMergedCells) { - double width = SheetUtil.getColumnWidth(this, column, useMergedCells); - - if (width != -1) { - width *= 256; - int maxColumnWidth = 255*256; // The maximum column width for an individual cell is 255 characters - if (width > maxColumnWidth) { - width = maxColumnWidth; - } - setColumnWidth(column, (int)(width)); - columnHelper.setColBestFit(column, true); - } - } - - /** - * Return the sheet's existing drawing, or null if there isn't yet one. - * - * Use {@link #createDrawingPatriarch()} to get or create - * - * @return a SpreadsheetML drawing - */ - @Override - public XSSFDrawing getDrawingPatriarch() { - CTDrawing ctDrawing = getCTDrawing(); - if (ctDrawing != null) { - // Search the referenced drawing in the list of the sheet's relations - for (RelationPart rp : getRelationParts()){ - POIXMLDocumentPart p = rp.getDocumentPart(); - if (p instanceof XSSFDrawing) { - XSSFDrawing dr = (XSSFDrawing)p; - String drId = rp.getRelationship().getId(); - if (drId.equals(ctDrawing.getId())){ - return dr; - } - break; - } - } - logger.log(POILogger.ERROR, "Can't find drawing with id=" + ctDrawing.getId() + " in the list of the sheet's relationships"); - } - return null; - } - - /** - * Create a new SpreadsheetML drawing. If this sheet already contains a drawing - return that. - * - * @return a SpreadsheetML drawing - */ - @Override - public XSSFDrawing createDrawingPatriarch() { - CTDrawing ctDrawing = getCTDrawing(); - if (ctDrawing != null) { - return getDrawingPatriarch(); - } - - // Default drawingNumber = #drawings.size() + 1 - int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size() + 1; - drawingNumber = getNextPartNumber(XSSFRelation.DRAWINGS, drawingNumber); - RelationPart rp = createRelationship(XSSFRelation.DRAWINGS, XSSFFactory.getInstance(), drawingNumber, false); - XSSFDrawing drawing = rp.getDocumentPart(); - String relId = rp.getRelationship().getId(); - - //add CT_Drawing element which indicates that this sheet contains drawing components built on the drawingML platform. - //The relationship Id references the part containing the drawingML definitions. - ctDrawing = worksheet.addNewDrawing(); - ctDrawing.setId(relId); - - // Return the newly created drawing - return drawing; - } - - /** - * Get VML drawing for this sheet (aka 'legacy' drawig) - * - * @param autoCreate if true, then a new VML drawing part is created - * - * @return the VML drawing of null if the drawing was not found and autoCreate=false - */ - protected XSSFVMLDrawing getVMLDrawing(boolean autoCreate) { - XSSFVMLDrawing drawing = null; - CTLegacyDrawing ctDrawing = getCTLegacyDrawing(); - if(ctDrawing == null) { - if(autoCreate) { - //drawingNumber = #drawings.size() + 1 - int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.VML_DRAWINGS.getContentType()).size() + 1; - RelationPart rp = createRelationship(XSSFRelation.VML_DRAWINGS, XSSFFactory.getInstance(), drawingNumber, false); - drawing = rp.getDocumentPart(); - String relId = rp.getRelationship().getId(); - - //add CTLegacyDrawing element which indicates that this sheet contains drawing components built on the drawingML platform. - //The relationship Id references the part containing the drawing definitions. - ctDrawing = worksheet.addNewLegacyDrawing(); - ctDrawing.setId(relId); - } - } else { - //search the referenced drawing in the list of the sheet's relations - final String id = ctDrawing.getId(); - for (RelationPart rp : getRelationParts()){ - POIXMLDocumentPart p = rp.getDocumentPart(); - if(p instanceof XSSFVMLDrawing) { - XSSFVMLDrawing dr = (XSSFVMLDrawing)p; - String drId = rp.getRelationship().getId(); - if (drId.equals(id)) { - drawing = dr; - break; - } - // do not break here since drawing has not been found yet (see bug 52425) - } - } - if(drawing == null){ - logger.log(POILogger.ERROR, "Can't find VML drawing with id=" + id + " in the list of the sheet's relationships"); - } - } - return drawing; - } - - protected CTDrawing getCTDrawing() { - return worksheet.getDrawing(); - } - protected CTLegacyDrawing getCTLegacyDrawing() { - return worksheet.getLegacyDrawing(); - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - * @param colSplit Horizontal position of split. - * @param rowSplit Vertical position of split. - */ - @Override - public void createFreezePane(int colSplit, int rowSplit) { - createFreezePane( colSplit, rowSplit, colSplit, rowSplit ); - } - - /** - * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. - * - *

        - * If both colSplit and rowSplit are zero then the existing freeze pane is removed - *

        - * - * @param colSplit Horizontal position of split. - * @param rowSplit Vertical position of split. - * @param leftmostColumn Left column visible in right pane. - * @param topRow Top row visible in bottom pane - */ - @Override - public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) { - CTSheetView ctView = getDefaultSheetView(); - - // If both colSplit and rowSplit are zero then the existing freeze pane is removed - if(colSplit == 0 && rowSplit == 0){ - if(ctView.isSetPane()) ctView.unsetPane(); - ctView.setSelectionArray(null); - return; - } - - if (!ctView.isSetPane()) { - ctView.addNewPane(); - } - CTPane pane = ctView.getPane(); - - if (colSplit > 0) { - pane.setXSplit(colSplit); - } else { - if(pane.isSetXSplit()) pane.unsetXSplit(); - } - if (rowSplit > 0) { - pane.setYSplit(rowSplit); - } else { - if(pane.isSetYSplit()) pane.unsetYSplit(); - } - - pane.setState(STPaneState.FROZEN); - if (rowSplit == 0) { - pane.setTopLeftCell(new CellReference(0, leftmostColumn).formatAsString()); - pane.setActivePane(STPane.TOP_RIGHT); - } else if (colSplit == 0) { - pane.setTopLeftCell(new CellReference(topRow, 0).formatAsString()); - pane.setActivePane(STPane.BOTTOM_LEFT); - } else { - pane.setTopLeftCell(new CellReference(topRow, leftmostColumn).formatAsString()); - pane.setActivePane(STPane.BOTTOM_RIGHT); - } - - ctView.setSelectionArray(null); - CTSelection sel = ctView.addNewSelection(); - sel.setPane(pane.getActivePane()); - } - - /** - * Create a new row within the sheet and return the high level representation - * - * Note: If a row already exists at this position, it is removed/overwritten and - * any existing cell is removed! - * - * @param rownum row number - * @return High level {@link XSSFRow} object representing a row in the sheet - * @see #removeRow(org.apache.poi.ss.usermodel.Row) - */ - @Override - public XSSFRow createRow(int rownum) { - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer rownumI = new Integer(rownum); // NOSONAR - CTRow ctRow; - XSSFRow prev = _rows.get(rownumI); - if(prev != null){ - // the Cells in an existing row are invalidated on-purpose, in order to clean up correctly, we - // need to call the remove, so things like ArrayFormulas and CalculationChain updates are done - // correctly. - // We remove the cell this way as the internal cell-list is changed by the remove call and - // thus would cause ConcurrentModificationException otherwise - while(prev.getFirstCellNum() != -1) { - prev.removeCell(prev.getCell(prev.getFirstCellNum())); - } - - ctRow = prev.getCTRow(); - ctRow.set(CTRow.Factory.newInstance()); - } else { - if(_rows.isEmpty() || rownum > _rows.lastKey()) { - // we can append the new row at the end - ctRow = worksheet.getSheetData().addNewRow(); - } else { - // get number of rows where row index < rownum - // --> this tells us where our row should go - int idx = _rows.headMap(rownumI).size(); - ctRow = worksheet.getSheetData().insertNewRow(idx); - } - } - XSSFRow r = new XSSFRow(ctRow, this); - r.setRowNum(rownum); - _rows.put(rownumI, r); - return r; - } - - /** - * Creates a split pane. Any existing freezepane or split pane is overwritten. - * @param xSplitPos Horizontal position of split (in 1/20th of a point). - * @param ySplitPos Vertical position of split (in 1/20th of a point). - * @param topRow Top row visible in bottom pane - * @param leftmostColumn Left column visible in right pane. - * @param activePane Active pane. One of: PANE_LOWER_RIGHT, - * PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT - * @see org.apache.poi.ss.usermodel.Sheet#PANE_LOWER_LEFT - * @see org.apache.poi.ss.usermodel.Sheet#PANE_LOWER_RIGHT - * @see org.apache.poi.ss.usermodel.Sheet#PANE_UPPER_LEFT - * @see org.apache.poi.ss.usermodel.Sheet#PANE_UPPER_RIGHT - */ - @Override - public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) { - createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow); - getPane().setState(STPaneState.SPLIT); - getPane().setActivePane(STPane.Enum.forInt(activePane)); - } - - /** - * Return cell comment at row, column, if one exists. Otherwise returns null. - * @param row the row where the comment is located - * @param column the column where the comment is located - * @return the cell comment, if one exists. Otherwise return null. - * @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellAddress)} instead. - */ - @Override - public XSSFComment getCellComment(int row, int column) { - return getCellComment(new CellAddress(row, column)); - } - - /** - * Return cell comment at row, column, if one exists. Otherwise returns null. - * - * @param address the location of the cell comment - * @return the cell comment, if one exists. Otherwise return null. - */ - @Override - public XSSFComment getCellComment(CellAddress address) { - if (sheetComments == null) { - return null; - } - - final int row = address.getRow(); - final int column = address.getColumn(); - - CellAddress ref = new CellAddress(row, column); - CTComment ctComment = sheetComments.getCTComment(ref); - if(ctComment == null) return null; - - XSSFVMLDrawing vml = getVMLDrawing(false); - return new XSSFComment(sheetComments, ctComment, - vml == null ? null : vml.findCommentShape(row, column)); - } - - /** - * Returns all cell comments on this sheet. - * @return A map of each Comment in the sheet, keyed on the cell address where - * the comment is located. - */ - @Override - public Map getCellComments() { - if (sheetComments == null) { - return Collections.emptyMap(); - } - return sheetComments.getCellComments(); - } - - /** - * Get a Hyperlink in this sheet anchored at row, column - * - * @param row - * @param column - * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null - */ - @Override - public XSSFHyperlink getHyperlink(int row, int column) { - return getHyperlink(new CellAddress(row, column)); - } - - /** - * Get a Hyperlink in this sheet located in a cell specified by {code addr} - * - * @param addr The address of the cell containing the hyperlink - * @return hyperlink if there is a hyperlink anchored at {@code addr}; otherwise returns {@code null} - * @since POI 3.15 beta 3 - */ - @Override - public XSSFHyperlink getHyperlink(CellAddress addr) { - String ref = addr.formatAsString(); - for(XSSFHyperlink hyperlink : hyperlinks) { - if(hyperlink.getCellRef().equals(ref)) { - return hyperlink; - } - } - return null; - } - - /** - * Get a list of Hyperlinks in this sheet - * - * @return Hyperlinks for the sheet - */ - @Override - public List getHyperlinkList() { - return Collections.unmodifiableList(hyperlinks); - } - - private int[] getBreaks(CTPageBreak ctPageBreak) { - CTBreak[] brkArray = ctPageBreak.getBrkArray(); - int[] breaks = new int[brkArray.length]; - for (int i = 0 ; i < brkArray.length ; i++) { - breaks[i] = (int) brkArray[i].getId() - 1; - } - return breaks; - } - - private void removeBreak(int index, CTPageBreak ctPageBreak) { - int index1 = index + 1; - CTBreak[] brkArray = ctPageBreak.getBrkArray(); - for (int i = 0 ; i < brkArray.length ; i++) { - if (brkArray[i].getId() == index1) { - ctPageBreak.removeBrk(i); - // TODO: check if we can break here, i.e. if a page can have more than 1 break on the same id - } - } - } - - /** - * Vertical page break information used for print layout view, page layout view, drawing print breaks - * in normal view, and for printing the worksheet. - * - * @return column indexes of all the vertical page breaks, never null - */ - @Override - public int[] getColumnBreaks() { - return worksheet.isSetColBreaks() ? getBreaks(worksheet.getColBreaks()) : new int[0]; - } - - /** - * Get the actual column width (in units of 1/256th of a character width ) - * - *

        - * Note, the returned value is always gerater that {@link #getDefaultColumnWidth()} because the latter does not include margins. - * Actual 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. - *

        - * - * @param columnIndex - the column to set (0-based) - * @return width - the width in units of 1/256th of a character width - */ - @Override - public int getColumnWidth(int columnIndex) { - CTCol col = columnHelper.getColumn(columnIndex, false); - double width = col == null || !col.isSetWidth() ? getDefaultColumnWidth() : col.getWidth(); - return (int)(width*256); - } - - /** - * Get the actual column width in pixels - * - *

        - * Please note, that this method works correctly only for workbooks - * with the default font size (Calibri 11pt for .xlsx). - *

        - */ - @Override - public float getColumnWidthInPixels(int columnIndex) { - float widthIn256 = getColumnWidth(columnIndex); - return (float)(widthIn256/256.0*XSSFWorkbook.DEFAULT_CHARACTER_WIDTH); - } - - /** - * Get the default column width for the sheet (if the columns do not define their own width) in - * characters. - *

        - * Note, this value is different from {@link #getColumnWidth(int)}. The latter is always greater and includes - * 4 pixels of margin padding (two on each side), plus 1 pixel padding for the gridlines. - *

        - * @return column width, default value is 8 - */ - @Override - public int getDefaultColumnWidth() { - CTSheetFormatPr pr = worksheet.getSheetFormatPr(); - return pr == null ? 8 : (int)pr.getBaseColWidth(); - } - - /** - * Get the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @return default row height - */ - @Override - public short getDefaultRowHeight() { - return (short)(getDefaultRowHeightInPoints() * TWIPS_PER_POINT); - } - - - /** - * Get the default row height for the sheet measued in point size (if the rows do not define their own height). - * - * @return default row height in points - */ - @Override - public float getDefaultRowHeightInPoints() { - CTSheetFormatPr pr = worksheet.getSheetFormatPr(); - return (float)(pr == null ? 0 : pr.getDefaultRowHeight()); - } - - private CTSheetFormatPr getSheetTypeSheetFormatPr() { - return worksheet.isSetSheetFormatPr() ? - worksheet.getSheetFormatPr() : - worksheet.addNewSheetFormatPr(); - } - - /** - * Returns the CellStyle that applies to the given - * (0 based) column, or null if no style has been - * set for that column - */ - @Override - public CellStyle getColumnStyle(int column) { - int idx = columnHelper.getColDefaultStyle(column); - return getWorkbook().getCellStyleAt((short)(idx == -1 ? 0 : idx)); - } - - /** - * Sets whether the worksheet is displayed from right to left instead of from left to right. - * - * @param value true for right to left, false otherwise. - */ - @Override - public void setRightToLeft(boolean value) { - CTSheetView view = getDefaultSheetView(); - view.setRightToLeft(value); - } - - /** - * Whether the text is displayed in right-to-left mode in the window - * - * @return whether the text is displayed in right-to-left mode in the window - */ - @Override - public boolean isRightToLeft() { - CTSheetView view = getDefaultSheetView(); - return view != null && view.getRightToLeft(); - } - - /** - * Get whether to display the guts or not, - * default value is true - * - * @return boolean - guts or no guts - */ - @Override - public boolean getDisplayGuts() { - CTSheetPr sheetPr = getSheetTypeSheetPr(); - CTOutlinePr outlinePr = sheetPr.getOutlinePr() == null ? CTOutlinePr.Factory.newInstance() : sheetPr.getOutlinePr(); - return outlinePr.getShowOutlineSymbols(); - } - - /** - * Set whether to display the guts or not - * - * @param value - guts or no guts - */ - @Override - public void setDisplayGuts(boolean value) { - CTSheetPr sheetPr = getSheetTypeSheetPr(); - CTOutlinePr outlinePr = sheetPr.getOutlinePr() == null ? sheetPr.addNewOutlinePr() : sheetPr.getOutlinePr(); - outlinePr.setShowOutlineSymbols(value); - } - - /** - * Gets the flag indicating whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - * - * @return whether all zero values on the worksheet are displayed - */ - @Override - public boolean isDisplayZeros(){ - CTSheetView view = getDefaultSheetView(); - return view == null || view.getShowZeros(); - } - - /** - * Set whether the window should show 0 (zero) in cells containing zero value. - * When false, cells with zero value appear blank instead of showing the number zero. - * - * @param value whether to display or hide all zero values on the worksheet - */ - @Override - public void setDisplayZeros(boolean value){ - CTSheetView view = getSheetTypeSheetView(); - view.setShowZeros(value); - } - - /** - * Gets the first row on the sheet - * - * @return the number of the first logical row on the sheet, zero based - */ - @Override - public int getFirstRowNum() { - return _rows.isEmpty() ? 0 : _rows.firstKey(); - } - - /** - * Flag indicating whether the Fit to Page print option is enabled. - * - * @return true - */ - @Override - public boolean getFitToPage() { - CTSheetPr sheetPr = getSheetTypeSheetPr(); - CTPageSetUpPr psSetup = (sheetPr == null || !sheetPr.isSetPageSetUpPr()) ? - CTPageSetUpPr.Factory.newInstance() : sheetPr.getPageSetUpPr(); - return psSetup.getFitToPage(); - } - - private CTSheetPr getSheetTypeSheetPr() { - if (worksheet.getSheetPr() == null) { - worksheet.setSheetPr(CTSheetPr.Factory.newInstance()); - } - return worksheet.getSheetPr(); - } - - private CTHeaderFooter getSheetTypeHeaderFooter() { - if (worksheet.getHeaderFooter() == null) { - worksheet.setHeaderFooter(CTHeaderFooter.Factory.newInstance()); - } - return worksheet.getHeaderFooter(); - } - - - - /** - * Returns the default footer for the sheet, - * creating one as needed. - * You may also want to look at - * {@link #getFirstFooter()}, - * {@link #getOddFooter()} and - * {@link #getEvenFooter()} - */ - @Override - public Footer getFooter() { - // The default footer is an odd footer - return getOddFooter(); - } - - /** - * Returns the default header for the sheet, - * creating one as needed. - * You may also want to look at - * {@link #getFirstHeader()}, - * {@link #getOddHeader()} and - * {@link #getEvenHeader()} - */ - @Override - public Header getHeader() { - // The default header is an odd header - return getOddHeader(); - } - - /** - * Returns the odd footer. Used on all pages unless - * other footers also present, when used on only - * odd pages. - */ - public Footer getOddFooter() { - return new XSSFOddFooter(getSheetTypeHeaderFooter()); - } - /** - * Returns the even footer. Not there by default, but - * when set, used on even pages. - */ - public Footer getEvenFooter() { - return new XSSFEvenFooter(getSheetTypeHeaderFooter()); - } - /** - * Returns the first page footer. Not there by - * default, but when set, used on the first page. - */ - public Footer getFirstFooter() { - return new XSSFFirstFooter(getSheetTypeHeaderFooter()); - } - - /** - * Returns the odd header. Used on all pages unless - * other headers also present, when used on only - * odd pages. - */ - public Header getOddHeader() { - return new XSSFOddHeader(getSheetTypeHeaderFooter()); - } - /** - * Returns the even header. Not there by default, but - * when set, used on even pages. - */ - public Header getEvenHeader() { - return new XSSFEvenHeader(getSheetTypeHeaderFooter()); - } - /** - * Returns the first page header. Not there by - * default, but when set, used on the first page. - */ - public Header getFirstHeader() { - return new XSSFFirstHeader(getSheetTypeHeaderFooter()); - } - - - /** - * Determine whether printed output for this sheet will be horizontally centered. - */ - @Override - public boolean getHorizontallyCenter() { - CTPrintOptions opts = worksheet.getPrintOptions(); - return opts != null && opts.getHorizontalCentered(); - } - - @Override - public int getLastRowNum() { - return _rows.isEmpty() ? 0 : _rows.lastKey(); - } - - @Override - public short getLeftCol() { - String cellRef = worksheet.getSheetViews().getSheetViewArray(0).getTopLeftCell(); - if(cellRef == null) { - return 0; - } - CellReference cellReference = new CellReference(cellRef); - return cellReference.getCol(); - } - - /** - * Gets the size of the margin in inches. - * - * @param margin which margin to get - * @return the size of the margin - * @see Sheet#LeftMargin - * @see Sheet#RightMargin - * @see Sheet#TopMargin - * @see Sheet#BottomMargin - * @see Sheet#HeaderMargin - * @see Sheet#FooterMargin - */ - @Override - public double getMargin(short margin) { - if (!worksheet.isSetPageMargins()) return 0; - - CTPageMargins pageMargins = worksheet.getPageMargins(); - switch (margin) { - case LeftMargin: - return pageMargins.getLeft(); - case RightMargin: - return pageMargins.getRight(); - case TopMargin: - return pageMargins.getTop(); - case BottomMargin: - return pageMargins.getBottom(); - case HeaderMargin: - return pageMargins.getHeader(); - case FooterMargin: - return pageMargins.getFooter(); - default : - throw new IllegalArgumentException("Unknown margin constant: " + margin); - } - } - - /** - * Sets the size of the margin in inches. - * - * @param margin which margin to get - * @param size the size of the margin - * @see Sheet#LeftMargin - * @see Sheet#RightMargin - * @see Sheet#TopMargin - * @see Sheet#BottomMargin - * @see Sheet#HeaderMargin - * @see Sheet#FooterMargin - */ - @Override - public void setMargin(short margin, double size) { - CTPageMargins pageMargins = worksheet.isSetPageMargins() ? - worksheet.getPageMargins() : worksheet.addNewPageMargins(); - switch (margin) { - case LeftMargin: - pageMargins.setLeft(size); - break; - case RightMargin: - pageMargins.setRight(size); - break; - case TopMargin: - pageMargins.setTop(size); - break; - case BottomMargin: - pageMargins.setBottom(size); - break; - case HeaderMargin: - pageMargins.setHeader(size); - break; - case FooterMargin: - pageMargins.setFooter(size); - break; - default : - throw new IllegalArgumentException( "Unknown margin constant: " + margin ); - } - } - - /** - * Returns the merged region at the specified index. If you want multiple - * regions, it is faster to call {@link #getMergedRegions()} than to call - * this each time. - * - * @return the merged region at the specified index - */ - @Override - public CellRangeAddress getMergedRegion(int index) { - CTMergeCells ctMergeCells = worksheet.getMergeCells(); - if(ctMergeCells == null) throw new IllegalStateException("This worksheet does not contain merged regions"); - - CTMergeCell ctMergeCell = ctMergeCells.getMergeCellArray(index); - String ref = ctMergeCell.getRef(); - return CellRangeAddress.valueOf(ref); - } - - /** - * Returns the list of merged regions. If you want multiple regions, this is - * faster than calling {@link #getMergedRegion(int)} each time. - * - * @return the list of merged regions - */ - @Override - public List getMergedRegions() { - List addresses = new ArrayList(); - CTMergeCells ctMergeCells = worksheet.getMergeCells(); - if(ctMergeCells == null) return addresses; - - for(CTMergeCell ctMergeCell : ctMergeCells.getMergeCellArray()) { - String ref = ctMergeCell.getRef(); - addresses.add(CellRangeAddress.valueOf(ref)); - } - return addresses; - } - - /** - * Returns the number of merged regions defined in this worksheet - * - * @return number of merged regions in this worksheet - */ - @Override - public int getNumMergedRegions() { - CTMergeCells ctMergeCells = worksheet.getMergeCells(); - return ctMergeCells == null ? 0 : ctMergeCells.sizeOfMergeCellArray(); - } - - public int getNumHyperlinks() { - return hyperlinks.size(); - } - - /** - * Returns the information regarding the currently configured pane (split or freeze). - * - * @return null if no pane configured, or the pane information. - */ - @Override - public PaneInformation getPaneInformation() { - CTPane pane = getDefaultSheetView().getPane(); - // no pane configured - if(pane == null) return null; - - CellReference cellRef = pane.isSetTopLeftCell() ? new CellReference(pane.getTopLeftCell()) : null; - return new PaneInformation((short)pane.getXSplit(), (short)pane.getYSplit(), - (short)(cellRef == null ? 0 : cellRef.getRow()),(cellRef == null ? 0 : cellRef.getCol()), - (byte)(pane.getActivePane().intValue() - 1), pane.getState() == STPaneState.FROZEN); - } - - /** - * Returns the number of physically defined rows (NOT the number of rows in the sheet) - * - * @return the number of physically defined rows - */ - @Override - public int getPhysicalNumberOfRows() { - return _rows.size(); - } - - /** - * Gets the print setup object. - * - * @return The user model for the print setup object. - */ - @Override - public XSSFPrintSetup getPrintSetup() { - return new XSSFPrintSetup(worksheet); - } - - /** - * Answer whether protection is enabled or disabled - * - * @return true => protection enabled; false => protection disabled - */ - @Override - public boolean getProtect() { - return isSheetLocked(); - } - - /** - * Enables sheet protection and sets the password for the sheet. - * Also sets some attributes on the {@link CTSheetProtection} that correspond to - * the default values used by Excel - * - * @param password to set for protection. Pass null to remove protection - */ - @Override - public void protectSheet(String password) { - if (password != null) { - CTSheetProtection sheetProtection = safeGetProtectionField(); - setSheetPassword(password, null); // defaults to xor password - sheetProtection.setSheet(true); - sheetProtection.setScenarios(true); - sheetProtection.setObjects(true); - } else { - worksheet.unsetSheetProtection(); - } - } - - /** - * Sets the sheet password. - * - * @param password if null, the password will be removed - * @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier) - * otherwise the given algorithm is used for calculating the hash password (Excel 2013) - */ - public void setSheetPassword(String password, HashAlgorithm hashAlgo) { - if (password == null && !isSheetProtectionEnabled()) { - return; - } - setPassword(safeGetProtectionField(), password, hashAlgo, null); - } - - /** - * Validate the password against the stored hash, the hashing method will be determined - * by the existing password attributes - * @return true, if the hashes match (... though original password may differ ...) - */ - public boolean validateSheetPassword(String password) { - if (!isSheetProtectionEnabled()) { - return (password == null); - } - return validatePassword(safeGetProtectionField(), password, null); - } - - /** - * Returns the logical row ( 0-based). If you ask for a row that is not - * defined you get a null. This is to say row 4 represents the fifth row on a sheet. - * - * @param rownum row to get - * @return XSSFRow representing the rownumber or null if its not defined on the sheet - */ - @Override - public XSSFRow getRow(int rownum) { - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer rownumI = new Integer(rownum); // NOSONAR - return _rows.get(rownumI); - } - - /** - * returns all rows between startRow and endRow, inclusive. - * Rows between startRow and endRow that haven't been created are not included - * in result unless createRowIfMissing is true - * - * @param startRowNum the first row number in this sheet to return - * @param endRowNum the last row number in this sheet to return - * @param createRowIfMissing - * @return All rows between startRow and endRow, inclusive - * @throws IllegalArgumentException if startRowNum and endRowNum are not in ascending order - */ - private List getRows(int startRowNum, int endRowNum, boolean createRowIfMissing) { - if (startRowNum > endRowNum) { - throw new IllegalArgumentException("getRows: startRowNum must be less than or equal to endRowNum"); - } - final List rows = new ArrayList(); - if (createRowIfMissing) { - for (int i = startRowNum; i <= endRowNum; i++) { - XSSFRow row = getRow(i); - if (row == null) { - row = createRow(i); - } - rows.add(row); - } - } - else { - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer startI = new Integer(startRowNum); // NOSONAR - final Integer endI = new Integer(endRowNum+1); // NOSONAR - final Collection inclusive = _rows.subMap(startI, endI).values(); - rows.addAll(inclusive); - } - return rows; - } - - /** - * Horizontal page break information used for print layout view, page layout view, drawing print breaks in normal - * view, and for printing the worksheet. - * - * @return row indexes of all the horizontal page breaks, never null - */ - @Override - public int[] getRowBreaks() { - return worksheet.isSetRowBreaks() ? getBreaks(worksheet.getRowBreaks()) : new int[0]; - - } - - /** - * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. - * - *

        - * When true a summary row is inserted below the detailed data being summarized and a - * new outline level is established on that row. - *

        - *

        - * When false a summary row is inserted above the detailed data being summarized and a new outline level - * is established on that row. - *

        - * @return true if row summaries appear below detail in the outline - */ - @Override - public boolean getRowSumsBelow() { - CTSheetPr sheetPr = worksheet.getSheetPr(); - CTOutlinePr outlinePr = (sheetPr != null && sheetPr.isSetOutlinePr()) - ? sheetPr.getOutlinePr() : null; - return outlinePr == null || outlinePr.getSummaryBelow(); - } - - /** - * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. - * - *

        - * When true a summary row is inserted below the detailed data being summarized and a - * new outline level is established on that row. - *

        - *

        - * When false a summary row is inserted above the detailed data being summarized and a new outline level - * is established on that row. - *

        - * @param value true if row summaries appear below detail in the outline - */ - @Override - public void setRowSumsBelow(boolean value) { - ensureOutlinePr().setSummaryBelow(value); - } - - /** - * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. - * - *

        - * When true a summary column is inserted to the right of the detailed data being summarized - * and a new outline level is established on that column. - *

        - *

        - * When false a summary column is inserted to the left of the detailed data being - * summarized and a new outline level is established on that column. - *

        - * @return true if col summaries appear right of the detail in the outline - */ - @Override - public boolean getRowSumsRight() { - CTSheetPr sheetPr = worksheet.getSheetPr(); - CTOutlinePr outlinePr = (sheetPr != null && sheetPr.isSetOutlinePr()) - ? sheetPr.getOutlinePr() : CTOutlinePr.Factory.newInstance(); - return outlinePr.getSummaryRight(); - } - - /** - * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. - * - *

        - * When true a summary column is inserted to the right of the detailed data being summarized - * and a new outline level is established on that column. - *

        - *

        - * When false a summary column is inserted to the left of the detailed data being - * summarized and a new outline level is established on that column. - *

        - * @param value true if col summaries appear right of the detail in the outline - */ - @Override - public void setRowSumsRight(boolean value) { - ensureOutlinePr().setSummaryRight(value); - } - - - /** - * Ensure CTWorksheet.CTSheetPr.CTOutlinePr - */ - private CTOutlinePr ensureOutlinePr(){ - CTSheetPr sheetPr = worksheet.isSetSheetPr() ? worksheet.getSheetPr() : worksheet.addNewSheetPr(); - return sheetPr.isSetOutlinePr() ? sheetPr.getOutlinePr() : sheetPr.addNewOutlinePr(); - } - - /** - * A flag indicating whether scenarios are locked when the sheet is protected. - * - * @return true => protection enabled; false => protection disabled - */ - @Override - public boolean getScenarioProtect() { - return worksheet.isSetSheetProtection() && worksheet.getSheetProtection().getScenarios(); - } - - /** - * The top row in the visible view when the sheet is - * first viewed after opening it in a viewer - * - * @return integer indicating the rownum (0 based) of the top row - */ - @Override - public short getTopRow() { - String cellRef = getSheetTypeSheetView().getTopLeftCell(); - if(cellRef == null) { - return 0; - } - CellReference cellReference = new CellReference(cellRef); - return (short) cellReference.getRow(); - } - - /** - * Determine whether printed output for this sheet will be vertically centered. - * - * @return whether printed output for this sheet will be vertically centered. - */ - @Override - public boolean getVerticallyCenter() { - CTPrintOptions opts = worksheet.getPrintOptions(); - return opts != null && opts.getVerticalCentered(); - } - - /** - * Group between (0 based) columns - */ - @Override - public void groupColumn(int fromColumn, int toColumn) { - groupColumn1Based(fromColumn+1, toColumn+1); - } - private void groupColumn1Based(int fromColumn, int toColumn) { - CTCols ctCols=worksheet.getColsArray(0); - CTCol ctCol=CTCol.Factory.newInstance(); - - // copy attributes, as they might be removed by merging with the new column - // TODO: check if this fix is really necessary or if the sweeping algorithm - // in addCleanColIntoCols needs to be adapted ... - CTCol fixCol_before = this.columnHelper.getColumn1Based(toColumn, false); - if (fixCol_before != null) { - fixCol_before = (CTCol)fixCol_before.copy(); - } - - ctCol.setMin(fromColumn); - ctCol.setMax(toColumn); - this.columnHelper.addCleanColIntoCols(ctCols, ctCol); - - CTCol fixCol_after = this.columnHelper.getColumn1Based(toColumn, false); - if (fixCol_before != null && fixCol_after != null) { - this.columnHelper.setColumnAttributes(fixCol_before, fixCol_after); - } - - for(int index=fromColumn;index<=toColumn;index++){ - CTCol col=columnHelper.getColumn1Based(index, false); - //col must exist - short outlineLevel=col.getOutlineLevel(); - col.setOutlineLevel((short)(outlineLevel+1)); - index=(int)col.getMax(); - } - worksheet.setColsArray(0,ctCols); - setSheetFormatPrOutlineLevelCol(); - } - - /** - * Do not leave the width attribute undefined (see #52186). - */ - private void setColWidthAttribute(CTCols ctCols) { - for (CTCol col : ctCols.getColArray()) { - if (!col.isSetWidth()) { - col.setWidth(getDefaultColumnWidth()); - col.setCustomWidth(false); - } - } - } - - /** - * Tie a range of cell together so that they can be collapsed or expanded - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - @Override - public void groupRow(int fromRow, int toRow) { - for (int i = fromRow; i <= toRow; i++) { - XSSFRow xrow = getRow(i); - if (xrow == null) { - xrow = createRow(i); - } - CTRow ctrow = xrow.getCTRow(); - short outlineLevel = ctrow.getOutlineLevel(); - ctrow.setOutlineLevel((short) (outlineLevel + 1)); - } - setSheetFormatPrOutlineLevelRow(); - } - - private short getMaxOutlineLevelRows(){ - int outlineLevel = 0; - for (XSSFRow xrow : _rows.values()) { - outlineLevel = Math.max(outlineLevel, xrow.getCTRow().getOutlineLevel()); - } - return (short) outlineLevel; - } - - private short getMaxOutlineLevelCols() { - CTCols ctCols = worksheet.getColsArray(0); - int outlineLevel = 0; - for (CTCol col : ctCols.getColArray()) { - outlineLevel = Math.max(outlineLevel, col.getOutlineLevel()); - } - return (short) outlineLevel; - } - - /** - * Determines if there is a page break at the indicated column - */ - @Override - public boolean isColumnBroken(int column) { - for (int colBreak : getColumnBreaks()) { - if (colBreak == column) { - return true; - } - } - return false; - } - - /** - * Get the hidden state for a given column. - * - * @param columnIndex - the column to set (0-based) - * @return hidden - false if the column is visible - */ - @Override - public boolean isColumnHidden(int columnIndex) { - CTCol col = columnHelper.getColumn(columnIndex, false); - return col != null && col.getHidden(); - } - - /** - * Gets the flag indicating whether this sheet should display formulas. - * - * @return true if this sheet should display formulas. - */ - @Override - public boolean isDisplayFormulas() { - return getSheetTypeSheetView().getShowFormulas(); - } - - /** - * Gets the flag indicating whether this sheet displays the lines - * between rows and columns to make editing and reading easier. - * - * @return true if this sheet displays gridlines. - * @see #isPrintGridlines() to check if printing of gridlines is turned on or off - */ - @Override - public boolean isDisplayGridlines() { - return getSheetTypeSheetView().getShowGridLines(); - } - - /** - * Sets the flag indicating whether this sheet should display the lines - * between rows and columns to make editing and reading easier. - * To turn printing of gridlines use {@link #setPrintGridlines(boolean)} - * - * - * @param show true if this sheet should display gridlines. - * @see #setPrintGridlines(boolean) - */ - @Override - public void setDisplayGridlines(boolean show) { - getSheetTypeSheetView().setShowGridLines(show); - } - - /** - * Gets the flag indicating whether this sheet should display row and column headings. - *

        - * Row heading are the row numbers to the side of the sheet - *

        - *

        - * Column heading are the letters or numbers that appear above the columns of the sheet - *

        - * - * @return true if this sheet should display row and column headings. - */ - @Override - public boolean isDisplayRowColHeadings() { - return getSheetTypeSheetView().getShowRowColHeaders(); - } - - /** - * Sets the flag indicating whether this sheet should display row and column headings. - *

        - * Row heading are the row numbers to the side of the sheet - *

        - *

        - * Column heading are the letters or numbers that appear above the columns of the sheet - *

        - * - * @param show true if this sheet should display row and column headings. - */ - @Override - public void setDisplayRowColHeadings(boolean show) { - getSheetTypeSheetView().setShowRowColHeaders(show); - } - - /** - * Returns whether gridlines are printed. - * - * @return whether gridlines are printed - */ - @Override - public boolean isPrintGridlines() { - CTPrintOptions opts = worksheet.getPrintOptions(); - return opts != null && opts.getGridLines(); - } - - /** - * Turns on or off the printing of gridlines. - * - * @param value boolean to turn on or off the printing of gridlines - */ - @Override - public void setPrintGridlines(boolean value) { - CTPrintOptions opts = worksheet.isSetPrintOptions() ? - worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); - opts.setGridLines(value); - } - - /** - * Returns whether row and column headings are printed. - * - * @return whether row and column headings are printed - */ - @Override - public boolean isPrintRowAndColumnHeadings() { - CTPrintOptions opts = worksheet.getPrintOptions(); - return opts != null && opts.getHeadings(); - } - - /** - * Turns on or off the printing of row and column headings. - * - * @param value boolean to turn on or off the printing of row and column headings - */ - @Override - public void setPrintRowAndColumnHeadings(boolean value) { - CTPrintOptions opts = worksheet.isSetPrintOptions() ? - worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); - opts.setHeadings(value); - } - - /** - * Tests if there is a page break at the indicated row - * - * @param row index of the row to test - * @return true if there is a page break at the indicated row - */ - @Override - public boolean isRowBroken(int row) { - for (int rowBreak : getRowBreaks()) { - if (rowBreak == row) { - return true; - } - } - return false; - } - - private void setBreak(int id, CTPageBreak ctPgBreak, int lastIndex) { - CTBreak brk = ctPgBreak.addNewBrk(); - brk.setId(id + 1); // this is id of the element which is 1-based: - brk.setMan(true); - brk.setMax(lastIndex); //end column of the break - - int nPageBreaks = ctPgBreak.sizeOfBrkArray(); - ctPgBreak.setCount(nPageBreaks); - ctPgBreak.setManualBreakCount(nPageBreaks); - } - - /** - * Sets a page break at the indicated row - * Breaks occur above the specified row and left of the specified column inclusive. - * - * For example, sheet.setColumnBreak(2); breaks the sheet into two parts - * with columns A,B,C in the first and D,E,... in the second. Simuilar, sheet.setRowBreak(2); - * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part - * and rows starting with rownum=4 in the second. - * - * @param row the row to break, inclusive - */ - @Override - public void setRowBreak(int row) { - if (!isRowBroken(row)) { - CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks(); - setBreak(row, pgBreak, SpreadsheetVersion.EXCEL2007.getLastColumnIndex()); - } - } - - /** - * Removes a page break at the indicated column - */ - @Override - public void removeColumnBreak(int column) { - if (worksheet.isSetColBreaks()) { - removeBreak(column, worksheet.getColBreaks()); - } // else no breaks - } - - /** - * Removes a merged region of cells (hence letting them free) - * - * @param index of the region to unmerge - */ - @Override - public void removeMergedRegion(int index) { - if (!worksheet.isSetMergeCells()) return; - - CTMergeCells ctMergeCells = worksheet.getMergeCells(); - int size = ctMergeCells.sizeOfMergeCellArray(); - assert(0 <= index && index < size); - if (size > 1) { - ctMergeCells.removeMergeCell(index); - } else { - worksheet.unsetMergeCells(); - } - } - - /** - * Removes a number of merged regions of cells (hence letting them free) - * - * This method can be used to bulk-remove merged regions in a way - * much faster than calling removeMergedRegion() for every single - * merged region. - * - * @param indices A set of the regions to unmerge - */ - @Override - public void removeMergedRegions(Collection indices) { - if (!worksheet.isSetMergeCells()) return; - - CTMergeCells ctMergeCells = worksheet.getMergeCells(); - List newMergeCells = new ArrayList(ctMergeCells.sizeOfMergeCellArray()); - - int idx = 0; - for (CTMergeCell mc : ctMergeCells.getMergeCellArray()) { - if (!indices.contains(idx++)) { - newMergeCells.add(mc); - } - } - - if (newMergeCells.isEmpty()) { - worksheet.unsetMergeCells(); - } else { - CTMergeCell[] newMergeCellsArray = new CTMergeCell[newMergeCells.size()]; - ctMergeCells.setMergeCellArray(newMergeCells.toArray(newMergeCellsArray)); - } - } - - /** - * Remove a row from this sheet. All cells contained in the row are removed as well - * - * @param row the row to remove. - */ - @Override - public void removeRow(Row row) { - if (row.getSheet() != this) { - throw new IllegalArgumentException("Specified row does not belong to this sheet"); - } - // collect cells into a temporary array to avoid ConcurrentModificationException - ArrayList cellsToDelete = new ArrayList(); - for (Cell cell : row) { - cellsToDelete.add((XSSFCell)cell); - } - - for (XSSFCell cell : cellsToDelete) { - row.removeCell(cell); - } - - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final int rowNum = row.getRowNum(); - final Integer rowNumI = new Integer(rowNum); // NOSONAR - // this is not the physical row number! - final int idx = _rows.headMap(rowNumI).size(); - _rows.remove(rowNumI); - worksheet.getSheetData().removeRow(idx); - - // also remove any comment located in that row - if(sheetComments != null) { - for (CellAddress ref : getCellComments().keySet()) { - if (ref.getRow() == rowNum) { - sheetComments.removeComment(ref); - } - } - } - } - - /** - * Removes the page break at the indicated row - */ - @Override - public void removeRowBreak(int row) { - if (worksheet.isSetRowBreaks()) { - removeBreak(row, worksheet.getRowBreaks()); - } // else no breaks - } - - /** - * Control if Excel should be asked to recalculate all formulas on this sheet - * when the workbook is opened. - * - *

        - * Calculating the formula values with {@link org.apache.poi.ss.usermodel.FormulaEvaluator} is the - * recommended solution, but this may be used for certain cases where - * evaluation in POI is not possible. - *

        - * - *

        - * It is recommended to force recalcuation of formulas on workbook level using - * {@link org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean)} - * to ensure that all cross-worksheet formuals and external dependencies are updated. - *

        - * @param value true if the application will perform a full recalculation of - * this worksheet values when the workbook is opened - * - * @see org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean) - */ - @Override - public void setForceFormulaRecalculation(boolean value) { - CTCalcPr calcPr = getWorkbook().getCTWorkbook().getCalcPr(); - - if(worksheet.isSetSheetCalcPr()) { - // Change the current setting - CTSheetCalcPr calc = worksheet.getSheetCalcPr(); - calc.setFullCalcOnLoad(value); - } - else if(value) { - // Add the Calc block and set it - CTSheetCalcPr calc = worksheet.addNewSheetCalcPr(); - calc.setFullCalcOnLoad(value); - } - if(value && calcPr != null && calcPr.getCalcMode() == STCalcMode.MANUAL) { - calcPr.setCalcMode(STCalcMode.AUTO); - } - - } - - /** - * Whether Excel will be asked to recalculate all formulas when the - * workbook is opened. - */ - @Override - public boolean getForceFormulaRecalculation() { - if(worksheet.isSetSheetCalcPr()) { - CTSheetCalcPr calc = worksheet.getSheetCalcPr(); - return calc.getFullCalcOnLoad(); - } - return false; - } - - /** - * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not - * be the third row if say for instance the second row is undefined. - * Call getRowNum() on each row if you care which one it is. - */ - @Override - @SuppressWarnings("unchecked") - public Iterator rowIterator() { - return (Iterator)(Iterator) _rows.values().iterator(); - } - - /** - * Alias for {@link #rowIterator()} to - * allow foreach loops - */ - @Override - public Iterator iterator() { - return rowIterator(); - } - - /** - * Flag indicating whether the sheet displays Automatic Page Breaks. - * - * @return true if the sheet displays Automatic Page Breaks. - */ - @Override - public boolean getAutobreaks() { - CTSheetPr sheetPr = getSheetTypeSheetPr(); - CTPageSetUpPr psSetup = (sheetPr == null || !sheetPr.isSetPageSetUpPr()) ? - CTPageSetUpPr.Factory.newInstance() : sheetPr.getPageSetUpPr(); - return psSetup.getAutoPageBreaks(); - } - - /** - * Flag indicating whether the sheet displays Automatic Page Breaks. - * - * @param value true if the sheet displays Automatic Page Breaks. - */ - @Override - public void setAutobreaks(boolean value) { - CTSheetPr sheetPr = getSheetTypeSheetPr(); - CTPageSetUpPr psSetup = sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr(); - psSetup.setAutoPageBreaks(value); - } - - /** - * Sets a page break at the indicated column. - * Breaks occur above the specified row and left of the specified column inclusive. - * - * For example, sheet.setColumnBreak(2); breaks the sheet into two parts - * with columns A,B,C in the first and D,E,... in the second. Simuilar, sheet.setRowBreak(2); - * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part - * and rows starting with rownum=4 in the second. - * - * @param column the column to break, inclusive - */ - @Override - public void setColumnBreak(int column) { - if (!isColumnBroken(column)) { - CTPageBreak pgBreak = worksheet.isSetColBreaks() ? worksheet.getColBreaks() : worksheet.addNewColBreaks(); - setBreak(column, pgBreak, SpreadsheetVersion.EXCEL2007.getLastRowIndex()); - } - } - - @Override - public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) { - if (collapsed) { - collapseColumn(columnNumber); - } else { - expandColumn(columnNumber); - } - } - - private void collapseColumn(int columnNumber) { - CTCols cols = worksheet.getColsArray(0); - CTCol col = columnHelper.getColumn(columnNumber, false); - int colInfoIx = columnHelper.getIndexOfColumn(cols, col); - if (colInfoIx == -1) { - return; - } - // Find the start of the group. - int groupStartColInfoIx = findStartOfColumnOutlineGroup(colInfoIx); - - CTCol columnInfo = cols.getColArray(groupStartColInfoIx); - - // Hide all the columns until the end of the group - int lastColMax = setGroupHidden(groupStartColInfoIx, columnInfo - .getOutlineLevel(), true); - - // write collapse field - setColumn(lastColMax + 1, 0, null, null, Boolean.TRUE); - - } - - private void setColumn(int targetColumnIx, Integer style, - Integer level, Boolean hidden, Boolean collapsed) { - CTCols cols = worksheet.getColsArray(0); - CTCol ci = null; - for (CTCol tci : cols.getColArray()) { - long tciMin = tci.getMin(); - long tciMax = tci.getMax(); - if (tciMin >= targetColumnIx && tciMax <= targetColumnIx) { - ci = tci; - break; - } - if (tciMin > targetColumnIx) { - // call column infos after k are for later columns - break; // exit now so k will be the correct insert pos - } - } - - if (ci == null) { - // okay so there ISN'T a column info record that covers this column - // so lets create one! - CTCol nci = CTCol.Factory.newInstance(); - nci.setMin(targetColumnIx); - nci.setMax(targetColumnIx); - unsetCollapsed(collapsed, nci); - this.columnHelper.addCleanColIntoCols(cols, nci); - return; - } - - boolean styleChanged = style != null && ci.getStyle() != style; - boolean levelChanged = level != null && ci.getOutlineLevel() != level; - boolean hiddenChanged = hidden != null && ci.getHidden() != hidden; - boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed; - boolean columnChanged = levelChanged || hiddenChanged || collapsedChanged || styleChanged; - if (!columnChanged) { - // do nothing...nothing changed. - return; - } - - long ciMin = ci.getMin(); - long ciMax = ci.getMax(); - if (ciMin == targetColumnIx && ciMax == targetColumnIx) { - // ColumnInfo ci for a single column, the target column - unsetCollapsed(collapsed, ci); - return; - } - - if (ciMin == targetColumnIx || ciMax == targetColumnIx) { - // The target column is at either end of the multi-column ColumnInfo - // ci - // we'll just divide the info and create a new one - if (ciMin == targetColumnIx) { - ci.setMin(targetColumnIx + 1); - } else { - ci.setMax(targetColumnIx - 1); - } - CTCol nci = columnHelper.cloneCol(cols, ci); - nci.setMin(targetColumnIx); - unsetCollapsed(collapsed, nci); - this.columnHelper.addCleanColIntoCols(cols, nci); - - } else { - // split to 3 records - CTCol ciMid = columnHelper.cloneCol(cols, ci); - CTCol ciEnd = columnHelper.cloneCol(cols, ci); - int lastcolumn = (int) ciMax; - - ci.setMax(targetColumnIx - 1); - - ciMid.setMin(targetColumnIx); - ciMid.setMax(targetColumnIx); - unsetCollapsed(collapsed, ciMid); - this.columnHelper.addCleanColIntoCols(cols, ciMid); - - ciEnd.setMin(targetColumnIx + 1); - ciEnd.setMax(lastcolumn); - this.columnHelper.addCleanColIntoCols(cols, ciEnd); - } - } - - private void unsetCollapsed(boolean collapsed, CTCol ci) { - if (collapsed) { - ci.setCollapsed(collapsed); - } else { - ci.unsetCollapsed(); - } - } - - /** - * Sets all adjacent columns of the same outline level to the specified - * hidden status. - * - * @param pIdx - * the col info index of the start of the outline group - * @return the column index of the last column in the outline group - */ - private int setGroupHidden(int pIdx, int level, boolean hidden) { - CTCols cols = worksheet.getColsArray(0); - int idx = pIdx; - CTCol[] colArray = cols.getColArray(); - CTCol columnInfo = colArray[idx]; - while (idx < colArray.length) { - columnInfo.setHidden(hidden); - if (idx + 1 < colArray.length) { - CTCol nextColumnInfo = colArray[idx + 1]; - - if (!isAdjacentBefore(columnInfo, nextColumnInfo)) { - break; - } - - if (nextColumnInfo.getOutlineLevel() < level) { - break; - } - columnInfo = nextColumnInfo; - } - idx++; - } - return (int) columnInfo.getMax(); - } - - private boolean isAdjacentBefore(CTCol col, CTCol otherCol) { - return col.getMax() == otherCol.getMin() - 1; - } - - private int findStartOfColumnOutlineGroup(int pIdx) { - // Find the start of the group. - CTCols cols = worksheet.getColsArray(0); - CTCol[] colArray = cols.getColArray(); - CTCol columnInfo = colArray[pIdx]; - int level = columnInfo.getOutlineLevel(); - int idx = pIdx; - while (idx != 0) { - CTCol prevColumnInfo = colArray[idx - 1]; - if (!isAdjacentBefore(prevColumnInfo, columnInfo)) { - break; - } - if (prevColumnInfo.getOutlineLevel() < level) { - break; - } - idx--; - columnInfo = prevColumnInfo; - } - return idx; - } - - private int findEndOfColumnOutlineGroup(int colInfoIndex) { - CTCols cols = worksheet.getColsArray(0); - // Find the end of the group. - CTCol[] colArray = cols.getColArray(); - CTCol columnInfo = colArray[colInfoIndex]; - int level = columnInfo.getOutlineLevel(); - int idx = colInfoIndex; - int lastIdx = colArray.length - 1; - while (idx < lastIdx) { - CTCol nextColumnInfo = colArray[idx + 1]; - if (!isAdjacentBefore(columnInfo, nextColumnInfo)) { - break; - } - if (nextColumnInfo.getOutlineLevel() < level) { - break; - } - idx++; - columnInfo = nextColumnInfo; - } - return idx; - } - - private void expandColumn(int columnIndex) { - CTCols cols = worksheet.getColsArray(0); - CTCol col = columnHelper.getColumn(columnIndex, false); - int colInfoIx = columnHelper.getIndexOfColumn(cols, col); - - int idx = findColInfoIdx((int) col.getMax(), colInfoIx); - if (idx == -1) { - return; - } - - // If it is already expanded do nothing. - if (!isColumnGroupCollapsed(idx)) { - return; - } - - // Find the start/end of the group. - int startIdx = findStartOfColumnOutlineGroup(idx); - int endIdx = findEndOfColumnOutlineGroup(idx); - - // expand: - // colapsed bit must be unset - // hidden bit gets unset _if_ surrounding groups are expanded you can - // determine - // this by looking at the hidden bit of the enclosing group. You will - // have - // to look at the start and the end of the current group to determine - // which - // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't - // uncollapse contained groups - CTCol[] colArray = cols.getColArray(); - CTCol columnInfo = colArray[endIdx]; - if (!isColumnGroupHiddenByParent(idx)) { - short outlineLevel = columnInfo.getOutlineLevel(); - boolean nestedGroup = false; - for (int i = startIdx; i <= endIdx; i++) { - CTCol ci = colArray[i]; - if (outlineLevel == ci.getOutlineLevel()) { - ci.unsetHidden(); - if (nestedGroup) { - nestedGroup = false; - ci.setCollapsed(true); - } - } else { - nestedGroup = true; - } - } - } - // Write collapse flag (stored in a single col info record after this - // outline group) - setColumn((int) columnInfo.getMax() + 1, null, null, - Boolean.FALSE, Boolean.FALSE); - } - - private boolean isColumnGroupHiddenByParent(int idx) { - CTCols cols = worksheet.getColsArray(0); - // Look out outline details of end - int endLevel = 0; - boolean endHidden = false; - int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx); - CTCol[] colArray = cols.getColArray(); - if (endOfOutlineGroupIdx < colArray.length) { - CTCol nextInfo = colArray[endOfOutlineGroupIdx + 1]; - if (isAdjacentBefore(colArray[endOfOutlineGroupIdx], nextInfo)) { - endLevel = nextInfo.getOutlineLevel(); - endHidden = nextInfo.getHidden(); - } - } - // Look out outline details of start - int startLevel = 0; - boolean startHidden = false; - int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup(idx); - if (startOfOutlineGroupIdx > 0) { - CTCol prevInfo = colArray[startOfOutlineGroupIdx - 1]; - - if (isAdjacentBefore(prevInfo, colArray[startOfOutlineGroupIdx])) { - startLevel = prevInfo.getOutlineLevel(); - startHidden = prevInfo.getHidden(); - } - - } - if (endLevel > startLevel) { - return endHidden; - } - return startHidden; - } - - private int findColInfoIdx(int columnValue, int fromColInfoIdx) { - CTCols cols = worksheet.getColsArray(0); - - if (columnValue < 0) { - throw new IllegalArgumentException( - "column parameter out of range: " + columnValue); - } - if (fromColInfoIdx < 0) { - throw new IllegalArgumentException( - "fromIdx parameter out of range: " + fromColInfoIdx); - } - - CTCol[] colArray = cols.getColArray(); - for (int k = fromColInfoIdx; k < colArray.length; k++) { - CTCol ci = colArray[k]; - - if (containsColumn(ci, columnValue)) { - return k; - } - - if (ci.getMin() > fromColInfoIdx) { - break; - } - - } - return -1; - } - - private boolean containsColumn(CTCol col, int columnIndex) { - return col.getMin() <= columnIndex && columnIndex <= col.getMax(); - } - - /** - * 'Collapsed' state is stored in a single column col info record - * immediately after the outline group - * - * @param idx - * @return a boolean represented if the column is collapsed - */ - private boolean isColumnGroupCollapsed(int idx) { - CTCols cols = worksheet.getColsArray(0); - CTCol[] colArray = cols.getColArray(); - int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx); - int nextColInfoIx = endOfOutlineGroupIdx + 1; - if (nextColInfoIx >= colArray.length) { - return false; - } - CTCol nextColInfo = colArray[nextColInfoIx]; - - CTCol col = colArray[endOfOutlineGroupIdx]; - if (!isAdjacentBefore(col, nextColInfo)) { - return false; - } - - return nextColInfo.getCollapsed(); - } - - /** - * Get the visibility state for a given column. - * - * @param columnIndex - the column to get (0-based) - * @param hidden - the visiblity state of the column - */ - @Override - public void setColumnHidden(int columnIndex, boolean hidden) { - columnHelper.setColHidden(columnIndex, hidden); - } - - /** - * Set the width (in units of 1/256th of a character width) - * - *

        - * The maximum column width for an individual cell is 255 characters. - * This value represents the number of characters that can be displayed - * in a cell that is formatted with the standard font (first font in the workbook). - *

        - * - *

        - * Character width is defined as the maximum digit width - * of the numbers 0, 1, 2, ... 9 as rendered - * using the default font (first font in the workbook). - *
        - * Unless you are using a very special font, the default character is '0' (zero), - * this is true for Arial (default font font in HSSF) and Calibri (default font in XSSF) - *

        - * - *

        - * Please note, that the width set by this method includes 4 pixels of margin padding (two on each side), - * plus 1 pixel padding for the gridlines (Section 3.3.1.12 of the OOXML spec). - * This results is a slightly less value of visible characters than passed to this method (approx. 1/2 of a character). - *

        - *

        - * To compute the actual number of visible characters, - * Excel uses the following formula (Section 3.3.1.12 of the OOXML spec): - *

        - * - * width = Truncate([{Number of Visible Characters} * - * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256 - * - *

        Using the Calibri font as an example, the maximum digit width of 11 point font size is 7 pixels (at 96 dpi). - * If you set a column width to be eight characters wide, e.g. setColumnWidth(columnIndex, 8*256), - * then the actual value of visible characters (the value shown in Excel) is derived from the following equation: - * - Truncate([numChars*7+5]/7*256)/256 = 8; - * - * - * which gives 7.29. - * - * @param columnIndex - the column to set (0-based) - * @param width - the width in units of 1/256th of a character width - * @throws IllegalArgumentException if width > 255*256 (the maximum column width in Excel is 255 characters) - */ - @Override - public void setColumnWidth(int columnIndex, int width) { - if(width > 255*256) throw new IllegalArgumentException("The maximum column width for an individual cell is 255 characters."); - - columnHelper.setColWidth(columnIndex, (double)width/256); - columnHelper.setCustomWidth(columnIndex, true); - } - - @Override - public void setDefaultColumnStyle(int column, CellStyle style) { - columnHelper.setColDefaultStyle(column, style); - } - - /** - * Specifies the number of characters of the maximum digit width of the normal style's font. - * This value does not include margin padding or extra padding for gridlines. It is only the - * number of characters. - * - * @param width the number of characters. Default value is 8. - */ - @Override - public void setDefaultColumnWidth(int width) { - getSheetTypeSheetFormatPr().setBaseColWidth(width); - } - - /** - * Set the default row height for the sheet (if the rows do not define their own height) in - * twips (1/20 of a point) - * - * @param height default row height in twips (1/20 of a point) - */ - @Override - public void setDefaultRowHeight(short height) { - setDefaultRowHeightInPoints((float)height / TWIPS_PER_POINT); - } - - /** - * Sets default row height measured in point size. - * - * @param height default row height measured in point size. - */ - @Override - public void setDefaultRowHeightInPoints(float height) { - CTSheetFormatPr pr = getSheetTypeSheetFormatPr(); - pr.setDefaultRowHeight(height); - pr.setCustomHeight(true); - } - - /** - * Sets the flag indicating whether this sheet should display formulas. - * - * @param show true if this sheet should display formulas. - */ - @Override - public void setDisplayFormulas(boolean show) { - getSheetTypeSheetView().setShowFormulas(show); - } - - private CTSheetView getSheetTypeSheetView() { - if (getDefaultSheetView() == null) { - getSheetTypeSheetViews().setSheetViewArray(0, CTSheetView.Factory.newInstance()); - } - return getDefaultSheetView(); - } - - /** - * Flag indicating whether the Fit to Page print option is enabled. - * - * @param b true if the Fit to Page print option is enabled. - */ - @Override - public void setFitToPage(boolean b) { - getSheetTypePageSetUpPr().setFitToPage(b); - } - - /** - * Center on page horizontally when printing. - * - * @param value whether to center on page horizontally when printing. - */ - @Override - public void setHorizontallyCenter(boolean value) { - CTPrintOptions opts = worksheet.isSetPrintOptions() ? - worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); - opts.setHorizontalCentered(value); - } - - /** - * Whether the output is vertically centered on the page. - * - * @param value true to vertically center, false otherwise. - */ - @Override - public void setVerticallyCenter(boolean value) { - CTPrintOptions opts = worksheet.isSetPrintOptions() ? - worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); - opts.setVerticalCentered(value); - } - - /** - * group the row It is possible for collapsed to be false and yet still have - * the rows in question hidden. This can be achieved by having a lower - * outline level collapsed, thus hiding all the child rows. Note that in - * this case, if the lowest level were expanded, the middle level would - * remain collapsed. - * - * @param rowIndex - - * the row involved, 0 based - * @param collapse - - * boolean value for collapse - */ - @Override - public void setRowGroupCollapsed(int rowIndex, boolean collapse) { - if (collapse) { - collapseRow(rowIndex); - } else { - expandRow(rowIndex); - } - } - - /** - * @param rowIndex the zero based row index to collapse - */ - private void collapseRow(int rowIndex) { - XSSFRow row = getRow(rowIndex); - if (row != null) { - int startRow = findStartOfRowOutlineGroup(rowIndex); - - // Hide all the columns until the end of the group - int lastRow = writeHidden(row, startRow, true); - if (getRow(lastRow) != null) { - getRow(lastRow).getCTRow().setCollapsed(true); - } else { - XSSFRow newRow = createRow(lastRow); - newRow.getCTRow().setCollapsed(true); - } - } - } - - /** - * @param rowIndex the zero based row index to find from - */ - private int findStartOfRowOutlineGroup(int rowIndex) { - // Find the start of the group. - short level = getRow(rowIndex).getCTRow().getOutlineLevel(); - int currentRow = rowIndex; - while (getRow(currentRow) != null) { - if (getRow(currentRow).getCTRow().getOutlineLevel() < level) - return currentRow + 1; - currentRow--; - } - return currentRow; - } - - private int writeHidden(XSSFRow xRow, int rowIndex, boolean hidden) { - short level = xRow.getCTRow().getOutlineLevel(); - for (Iterator it = rowIterator(); it.hasNext();) { - xRow = (XSSFRow) it.next(); - - // skip rows before the start of this group - if(xRow.getRowNum() < rowIndex) { - continue; - } - - if (xRow.getCTRow().getOutlineLevel() >= level) { - xRow.getCTRow().setHidden(hidden); - rowIndex++; - } - - } - return rowIndex; - } - - /** - * @param rowNumber the zero based row index to expand - */ - private void expandRow(int rowNumber) { - if (rowNumber == -1) - return; - XSSFRow row = getRow(rowNumber); - // If it is already expanded do nothing. - if (!row.getCTRow().isSetHidden()) { - return; - } - - // Find the start of the group. - int startIdx = findStartOfRowOutlineGroup(rowNumber); - - // Find the end of the group. - int endIdx = findEndOfRowOutlineGroup(rowNumber); - - // expand: - // collapsed must be unset - // hidden bit gets unset _if_ surrounding groups are expanded you can - // determine - // this by looking at the hidden bit of the enclosing group. You will - // have - // to look at the start and the end of the current group to determine - // which - // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't - // un-collapse contained groups - short level = row.getCTRow().getOutlineLevel(); - if (!isRowGroupHiddenByParent(rowNumber)) { - for (int i = startIdx; i < endIdx; i++) { - if (level == getRow(i).getCTRow().getOutlineLevel()) { - getRow(i).getCTRow().unsetHidden(); - } else if (!isRowGroupCollapsed(i)) { - getRow(i).getCTRow().unsetHidden(); - } - } - } - // Write collapse field - CTRow ctRow = getRow(endIdx).getCTRow(); - // This avoids an IndexOutOfBounds if multiple nested groups are collapsed/expanded - if(ctRow.getCollapsed()) { - ctRow.unsetCollapsed(); - } - } - - /** - * @param row the zero based row index to find from - */ - public int findEndOfRowOutlineGroup(int row) { - short level = getRow(row).getCTRow().getOutlineLevel(); - int currentRow; - final int lastRowNum = getLastRowNum(); - for (currentRow = row; currentRow < lastRowNum; currentRow++) { - if (getRow(currentRow) == null - || getRow(currentRow).getCTRow().getOutlineLevel() < level) { - break; - } - } - return currentRow; - } - - /** - * @param row the zero based row index to find from - */ - private boolean isRowGroupHiddenByParent(int row) { - // Look out outline details of end - int endLevel; - boolean endHidden; - int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row); - if (getRow(endOfOutlineGroupIdx) == null) { - endLevel = 0; - endHidden = false; - } else { - endLevel = getRow(endOfOutlineGroupIdx).getCTRow().getOutlineLevel(); - endHidden = getRow(endOfOutlineGroupIdx).getCTRow().getHidden(); - } - - // Look out outline details of start - int startLevel; - boolean startHidden; - int startOfOutlineGroupIdx = findStartOfRowOutlineGroup(row); - if (startOfOutlineGroupIdx < 0 - || getRow(startOfOutlineGroupIdx) == null) { - startLevel = 0; - startHidden = false; - } else { - startLevel = getRow(startOfOutlineGroupIdx).getCTRow() - .getOutlineLevel(); - startHidden = getRow(startOfOutlineGroupIdx).getCTRow() - .getHidden(); - } - if (endLevel > startLevel) { - return endHidden; - } - return startHidden; - } - - /** - * @param row the zero based row index to find from - */ - private boolean isRowGroupCollapsed(int row) { - int collapseRow = findEndOfRowOutlineGroup(row) + 1; - if (getRow(collapseRow) == null) { - return false; - } - return getRow(collapseRow).getCTRow().getCollapsed(); - } - - /** - * Sets the zoom magnification for the sheet. The zoom is expressed as a - * fraction. For example to express a zoom of 75% use 3 for the numerator - * and 4 for the denominator. - * - * @param numerator The numerator for the zoom magnification. - * @param denominator The denominator for the zoom magnification. - * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #setZoom(int)} instead. - */ - @Removal(version="3.16") - @Override - public void setZoom(int numerator, int denominator) { - int zoom = 100*numerator/denominator; - setZoom(zoom); - } - - /** - * Window zoom magnification for current view representing percent values. - * Valid values range from 10 to 400. Horizontal & Vertical scale together. - * - * For example: - *

        -     * 10 - 10%
        -     * 20 - 20%
        -     * ...
        -     * 100 - 100%
        -     * ...
        -     * 400 - 400%
        -     * 
        - * - * Current view can be Normal, Page Layout, or Page Break Preview. - * - * @param scale window zoom magnification - * @throws IllegalArgumentException if scale is invalid - */ - @Override - public void setZoom(int scale) { - if (scale < 10 || scale > 400) { - throw new IllegalArgumentException("Valid scale values range from 10 to 400"); - } - getSheetTypeSheetView().setZoomScale(scale); - } - - - /** - * copyRows rows from srcRows to this sheet starting at destStartRow - * - * Additionally copies merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). - * @param srcRows the rows to copy. Formulas will be offset by the difference - * in the row number of the first row in srcRows and destStartRow (even if srcRows - * are from a different sheet). - * @param destStartRow the row in this sheet to paste the first row of srcRows - * the remainder of srcRows will be pasted below destStartRow per the cell copy policy - * @param policy is the cell copy policy, which can be used to merge the source and destination - * when the source is blank, copy styles only, paste as value, etc - */ - @Beta - public void copyRows(List srcRows, int destStartRow, CellCopyPolicy policy) { - if (srcRows == null || srcRows.size() == 0) { - throw new IllegalArgumentException("No rows to copy"); - } - final Row srcStartRow = srcRows.get(0); - final Row srcEndRow = srcRows.get(srcRows.size() - 1); - - if (srcStartRow == null) { - throw new IllegalArgumentException("copyRows: First row cannot be null"); - } - - final int srcStartRowNum = srcStartRow.getRowNum(); - final int srcEndRowNum = srcEndRow.getRowNum(); - - // check row numbers to make sure they are continuous and increasing (monotonic) - // and srcRows does not contain null rows - final int size = srcRows.size(); - for (int index=1; index < size; index++) { - final Row curRow = srcRows.get(index); - if (curRow == null) { - throw new IllegalArgumentException("srcRows may not contain null rows. Found null row at index " + index + "."); - //} else if (curRow.getRowNum() != prevRow.getRowNum() + 1) { - // throw new IllegalArgumentException("srcRows must contain continuously increasing row numbers. " + - // "Got srcRows[" + (index-1) + "]=Row " + prevRow.getRowNum() + ", srcRows[" + index + "]=Row " + curRow.getRowNum() + "."); - // FIXME: assumes row objects belong to non-null sheets and sheets belong to non-null workbooks. - } else if (srcStartRow.getSheet().getWorkbook() != curRow.getSheet().getWorkbook()) { - throw new IllegalArgumentException("All rows in srcRows must belong to the same sheet in the same workbook." + - "Expected all rows from same workbook (" + srcStartRow.getSheet().getWorkbook() + "). " + - "Got srcRows[" + index + "] from different workbook (" + curRow.getSheet().getWorkbook() + ")."); - } else if (srcStartRow.getSheet() != curRow.getSheet()) { - throw new IllegalArgumentException("All rows in srcRows must belong to the same sheet. " + - "Expected all rows from " + srcStartRow.getSheet().getSheetName() + ". " + - "Got srcRows[" + index + "] from " + curRow.getSheet().getSheetName()); - } - } - - // FIXME: is special behavior needed if srcRows and destRows belong to the same sheets and the regions overlap? - - final CellCopyPolicy options = new CellCopyPolicy(policy); - // avoid O(N^2) performance scanning through all regions for each row - // merged regions will be copied after all the rows have been copied - options.setCopyMergedRegions(false); - - // FIXME: if srcRows contains gaps or null values, clear out those rows that will be overwritten - // how will this work with merging (copy just values, leave cell styles in place?) - - int r = destStartRow; - for (Row srcRow : srcRows) { - int destRowNum; - if (policy.isCondenseRows()) { - destRowNum = r++; - } else { - final int shift = (srcRow.getRowNum() - srcStartRowNum); - destRowNum = destStartRow + shift; - } - //removeRow(destRowNum); //this probably clears all external formula references to destRow, causing unwanted #REF! errors - final XSSFRow destRow = createRow(destRowNum); - destRow.copyRowFrom(srcRow, options); - } - - // ====================== - // Only do additional copy operations here that cannot be done with Row.copyFromRow(Row, options) - // reasons: operation needs to interact with multiple rows or sheets - - // Copy merged regions that are contained within the copy region - if (policy.isCopyMergedRegions()) { - // FIXME: is this something that rowShifter could be doing? - final int shift = destStartRow - srcStartRowNum; - for (CellRangeAddress srcRegion : srcStartRow.getSheet().getMergedRegions()) { - if (srcStartRowNum <= srcRegion.getFirstRow() && srcRegion.getLastRow() <= srcEndRowNum) { - // srcRegion is fully inside the copied rows - final CellRangeAddress destRegion = srcRegion.copy(); - destRegion.setFirstRow(destRegion.getFirstRow() + shift); - destRegion.setLastRow(destRegion.getLastRow() + shift); - addMergedRegion(destRegion); - } - } - } - } - - /** - * Copies rows between srcStartRow and srcEndRow to the same sheet, starting at destStartRow - * Convenience function for {@link #copyRows(List, int, CellCopyPolicy)} - * - * Equivalent to copyRows(getRows(srcStartRow, srcEndRow, false), destStartRow, cellCopyPolicy) - * - * @param srcStartRow the index of the first row to copy the cells from in this sheet - * @param srcEndRow the index of the last row to copy the cells from in this sheet - * @param destStartRow the index of the first row to copy the cells to in this sheet - * @param cellCopyPolicy the policy to use to determine how cells are copied - */ - @Beta - public void copyRows(int srcStartRow, int srcEndRow, int destStartRow, CellCopyPolicy cellCopyPolicy) { - final List srcRows = getRows(srcStartRow, srcEndRow, false); //FIXME: should be false, no need to create rows where src is only to copy them to dest - copyRows(srcRows, destStartRow, cellCopyPolicy); - } - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around. - * - * Calls shiftRows(startRow, endRow, n, false, false); - * - *

        - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - */ - @Override - public void shiftRows(int startRow, int endRow, int n) { - shiftRows(startRow, endRow, n, false, false); - } - - /** - * Shifts rows between startRow and endRow n number of rows. - * If you use a negative number, it will shift rows up. - * Code ensures that rows don't wrap around - * - *

        - * Additionally shifts merged regions that are completely defined in these - * rows (ie. merged 2 cells on a row to be shifted). All merged regions that are - * completely overlaid by shifting will be deleted. - *

        - * @param startRow the row to start shifting - * @param endRow the row to end shifting - * @param n the number of rows to shift - * @param copyRowHeight whether to copy the row height during the shift - * @param resetOriginalRowHeight whether to set the original row's height to the default - */ - @Override - public void shiftRows(int startRow, int endRow, final int n, boolean copyRowHeight, boolean resetOriginalRowHeight) { - XSSFVMLDrawing vml = getVMLDrawing(false); - - // first remove all rows which will be overwritten - for (Iterator it = rowIterator() ; it.hasNext() ; ) { - XSSFRow row = (XSSFRow)it.next(); - int rownum = row.getRowNum(); - - // check if we should remove this row as it will be overwritten by the data later - if (shouldRemoveRow(startRow, endRow, n, rownum)) { - // remove row from worksheet.getSheetData row array - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer rownumI = new Integer(row.getRowNum()); // NOSONAR - int idx = _rows.headMap(rownumI).size(); - worksheet.getSheetData().removeRow(idx); - - // remove row from _rows - it.remove(); - - // FIXME: (performance optimization) this should be moved outside the for-loop so that comments only needs to be iterated over once. - // also remove any comments associated with this row - if(sheetComments != null){ - CTCommentList lst = sheetComments.getCTComments().getCommentList(); - for (CTComment comment : lst.getCommentArray()) { - String strRef = comment.getRef(); - CellAddress ref = new CellAddress(strRef); - - // is this comment part of the current row? - if(ref.getRow() == rownum) { - sheetComments.removeComment(ref); - vml.removeCommentShape(ref.getRow(), ref.getColumn()); - } - } - } - // FIXME: (performance optimization) this should be moved outside the for-loop so that hyperlinks only needs to be iterated over once. - // also remove any hyperlinks associated with this row - if (hyperlinks != null) { - for (XSSFHyperlink link : new ArrayList(hyperlinks)) { - CellReference ref = new CellReference(link.getCellRef()); - if (ref.getRow() == rownum) { - hyperlinks.remove(link); - } - } - } - } - } - - // then do the actual moving and also adjust comments/rowHeight - // we need to sort it in a way so the shifting does not mess up the structures, - // i.e. when shifting down, start from down and go up, when shifting up, vice-versa - SortedMap commentsToShift = new TreeMap(new Comparator() { - public int compare(XSSFComment o1, XSSFComment o2) { - int row1 = o1.getRow(); - int row2 = o2.getRow(); - - if(row1 == row2) { - // ordering is not important when row is equal, but don't return zero to still - // get multiple comments per row into the map - return o1.hashCode() - o2.hashCode(); - } - - // when shifting down, sort higher row-values first - if(n > 0) { - return row1 < row2 ? 1 : -1; - } else { - // sort lower-row values first when shifting up - return row1 > row2 ? 1 : -1; - } - } - }); - - - for (Iterator it = rowIterator() ; it.hasNext() ; ) { - XSSFRow row = (XSSFRow)it.next(); - int rownum = row.getRowNum(); - - if(sheetComments != null){ - // calculate the new rownum - int newrownum = shiftedRowNum(startRow, endRow, n, rownum); - - // is there a change necessary for the current row? - if(newrownum != rownum) { - CTCommentList lst = sheetComments.getCTComments().getCommentList(); - for (CTComment comment : lst.getCommentArray()) { - String oldRef = comment.getRef(); - CellReference ref = new CellReference(oldRef); - - // is this comment part of the current row? - if(ref.getRow() == rownum) { - XSSFComment xssfComment = new XSSFComment(sheetComments, comment, - vml == null ? null : vml.findCommentShape(rownum, ref.getCol())); - - // we should not perform the shifting right here as we would then find - // already shifted comments and would shift them again... - commentsToShift.put(xssfComment, newrownum); - } - } - } - } - - if(rownum < startRow || rownum > endRow) continue; - - if (!copyRowHeight) { - row.setHeight((short)-1); - } - - row.shift(n); - } - - // adjust all the affected comment-structures now - // the Map is sorted and thus provides them in the order that we need here, - // i.e. from down to up if shifting down, vice-versa otherwise - for(Map.Entry entry : commentsToShift.entrySet()) { - entry.getKey().setRow(entry.getValue()); - } - - XSSFRowShifter rowShifter = new XSSFRowShifter(this); - - int sheetIndex = getWorkbook().getSheetIndex(this); - String sheetName = getWorkbook().getSheetName(sheetIndex); - FormulaShifter shifter = FormulaShifter.createForRowShift( - sheetIndex, sheetName, startRow, endRow, n, SpreadsheetVersion.EXCEL2007); - - rowShifter.updateNamedRanges(shifter); - rowShifter.updateFormulas(shifter); - rowShifter.shiftMergedRegions(startRow, endRow, n); - rowShifter.updateConditionalFormatting(shifter); - rowShifter.updateHyperlinks(shifter); - - //rebuild the _rows map - Map map = new HashMap(); - for(XSSFRow r : _rows.values()) { - // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer rownumI = new Integer(r.getRowNum()); // NOSONAR - map.put(rownumI, r); - } - _rows.clear(); - _rows.putAll(map); - } - - private int shiftedRowNum(int startRow, int endRow, int n, int rownum) { - // no change if before any affected row - if(rownum < startRow && (n > 0 || (startRow - rownum) > n)) { - return rownum; - } - - // no change if after any affected row - if(rownum > endRow && (n < 0 || (rownum - endRow) > n)) { - return rownum; - } - - // row before and things are moved up - if(rownum < startRow) { - // row is moved down by the shifting - return rownum + (endRow - startRow); - } - - // row is after and things are moved down - if(rownum > endRow) { - // row is moved up by the shifting - return rownum - (endRow - startRow); - } - - // row is part of the shifted block - return rownum + n; - } - - /** - * Location of the top left visible cell Location of the top left visible cell in the bottom right - * pane (when in Left-to-Right mode). - * - * @param toprow the top row to show in desktop window pane - * @param leftcol the left column to show in desktop window pane - */ - @Override - public void showInPane(int toprow, int leftcol) { - CellReference cellReference = new CellReference(toprow, leftcol); - String cellRef = cellReference.formatAsString(); - getPane().setTopLeftCell(cellRef); - } - - @Override - public void ungroupColumn(int fromColumn, int toColumn) { - CTCols cols = worksheet.getColsArray(0); - for (int index = fromColumn; index <= toColumn; index++) { - CTCol col = columnHelper.getColumn(index, false); - if (col != null) { - short outlineLevel = col.getOutlineLevel(); - col.setOutlineLevel((short) (outlineLevel - 1)); - index = (int) col.getMax(); - - if (col.getOutlineLevel() <= 0) { - int colIndex = columnHelper.getIndexOfColumn(cols, col); - worksheet.getColsArray(0).removeCol(colIndex); - } - } - } - worksheet.setColsArray(0, cols); - setSheetFormatPrOutlineLevelCol(); - } - - /** - * Ungroup a range of rows that were previously groupped - * - * @param fromRow start row (0-based) - * @param toRow end row (0-based) - */ - @Override - public void ungroupRow(int fromRow, int toRow) { - for (int i = fromRow; i <= toRow; i++) { - XSSFRow xrow = getRow(i); - if (xrow != null) { - CTRow ctRow = xrow.getCTRow(); - int outlineLevel = ctRow.getOutlineLevel(); - ctRow.setOutlineLevel((short) (outlineLevel - 1)); - //remove a row only if the row has no cell and if the outline level is 0 - if (outlineLevel == 1 && xrow.getFirstCellNum() == -1) { - removeRow(xrow); - } - } - } - setSheetFormatPrOutlineLevelRow(); - } - - private void setSheetFormatPrOutlineLevelRow(){ - short maxLevelRow=getMaxOutlineLevelRows(); - getSheetTypeSheetFormatPr().setOutlineLevelRow(maxLevelRow); - } - - private void setSheetFormatPrOutlineLevelCol(){ - short maxLevelCol=getMaxOutlineLevelCols(); - getSheetTypeSheetFormatPr().setOutlineLevelCol(maxLevelCol); - } - - private CTSheetViews getSheetTypeSheetViews() { - if (worksheet.getSheetViews() == null) { - worksheet.setSheetViews(CTSheetViews.Factory.newInstance()); - worksheet.getSheetViews().addNewSheetView(); - } - return worksheet.getSheetViews(); - } - - /** - * Returns a flag indicating whether this sheet is selected. - *

        - * When only 1 sheet is selected and active, this value should be in synch with the activeTab value. - * In case of a conflict, the Start Part setting wins and sets the active sheet tab. - *

        - * Note: multiple sheets can be selected, but only one sheet can be active at one time. - * - * @return true if this sheet is selected - */ - @Override - public boolean isSelected() { - CTSheetView view = getDefaultSheetView(); - return view != null && view.getTabSelected(); - } - - /** - * Sets a flag indicating whether this sheet is selected. - * - *

        - * When only 1 sheet is selected and active, this value should be in synch with the activeTab value. - * In case of a conflict, the Start Part setting wins and sets the active sheet tab. - *

        - * Note: multiple sheets can be selected, but only one sheet can be active at one time. - * - * @param value true if this sheet is selected - */ - @Override - public void setSelected(boolean value) { - CTSheetViews views = getSheetTypeSheetViews(); - for (CTSheetView view : views.getSheetViewArray()) { - view.setTabSelected(value); - } - } - - /** - * Register a hyperlink in the collection of hyperlinks on this sheet - * - * @param hyperlink the link to add - */ - @Internal - public void addHyperlink(XSSFHyperlink hyperlink) { - hyperlinks.add(hyperlink); - } - - /** - * Removes a hyperlink in the collection of hyperlinks on this sheet - * - * @param row row index - * @param column column index - */ - @Internal - public void removeHyperlink(int row, int column) { - // CTHyperlinks is regenerated from scratch when writing out the spreadsheet - // so don't worry about maintaining hyperlinks and CTHyperlinks in parallel. - // only maintain hyperlinks - String ref = new CellReference(row, column).formatAsString(); - for (Iterator it = hyperlinks.iterator(); it.hasNext();) { - XSSFHyperlink hyperlink = it.next(); - if (hyperlink.getCellRef().equals(ref)) { - it.remove(); - return; - } - } - } - - /** - * Return location of the active cell, e.g. A1. - * - * @return the location of the active cell. - */ - @Override - public CellAddress getActiveCell() { - String address = getSheetTypeSelection().getActiveCell(); - if (address == null) { - return null; - } - return new CellAddress(address); - } - - /** - * Sets location of the active cell - * - * @param cellRef the location of the active cell, e.g. A1.. - * @deprecated 3.14beta2 (circa 2015-12-05). Use {@link #setActiveCell(CellAddress)} instead. - */ - public void setActiveCell(String cellRef) { - CTSelection ctsel = getSheetTypeSelection(); - ctsel.setActiveCell(cellRef); - ctsel.setSqref(Arrays.asList(cellRef)); - } - - /** - * {@inheritDoc} - */ - @Override - public void setActiveCell(CellAddress address) { - String ref = address.formatAsString(); - CTSelection ctsel = getSheetTypeSelection(); - ctsel.setActiveCell(ref); - ctsel.setSqref(Arrays.asList(ref)); - } - - /** - * Does this sheet have any comments on it? We need to know, - * so we can decide about writing it to disk or not - */ - public boolean hasComments() { - return sheetComments != null && sheetComments.getNumberOfComments() > 0; - } - - protected int getNumberOfComments() { - return sheetComments == null ? 0 : sheetComments.getNumberOfComments(); - } - - private CTSelection getSheetTypeSelection() { - if (getSheetTypeSheetView().sizeOfSelectionArray() == 0) { - getSheetTypeSheetView().insertNewSelection(0); - } - return getSheetTypeSheetView().getSelectionArray(0); - } - - /** - * Return the default sheet view. This is the last one if the sheet's views, according to sec. 3.3.1.83 - * of the OOXML spec: "A single sheet view definition. When more than 1 sheet view is defined in the file, - * it means that when opening the workbook, each sheet view corresponds to a separate window within the - * spreadsheet application, where each window is showing the particular sheet. containing the same - * workbookViewId value, the last sheetView definition is loaded, and the others are discarded. - * When multiple windows are viewing the same sheet, multiple sheetView elements (with corresponding - * workbookView entries) are saved." - */ - private CTSheetView getDefaultSheetView() { - CTSheetViews views = getSheetTypeSheetViews(); - int sz = views == null ? 0 : views.sizeOfSheetViewArray(); - if (sz == 0) { - return null; - } - return views.getSheetViewArray(sz - 1); - } - - /** - * Returns the sheet's comments object if there is one, - * or null if not - * - * @param create create a new comments table if it does not exist - */ - protected CommentsTable getCommentsTable(boolean create) { - if(sheetComments == null && create){ - // Try to create a comments table with the same number as - // the sheet has (i.e. sheet 1 -> comments 1) - try { - sheetComments = (CommentsTable)createRelationship( - XSSFRelation.SHEET_COMMENTS, XSSFFactory.getInstance(), (int)sheet.getSheetId()); - } catch(PartAlreadyExistsException e) { - // Technically a sheet doesn't need the same number as - // it's comments, and clearly someone has already pinched - // our number! Go for the next available one instead - sheetComments = (CommentsTable)createRelationship( - XSSFRelation.SHEET_COMMENTS, XSSFFactory.getInstance(), -1); - } - } - return sheetComments; - } - - private CTPageSetUpPr getSheetTypePageSetUpPr() { - CTSheetPr sheetPr = getSheetTypeSheetPr(); - return sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr(); - } - - private static boolean shouldRemoveRow(int startRow, int endRow, int n, int rownum) { - // is this row in the target-window where the moved rows will land? - if (rownum >= (startRow + n) && rownum <= (endRow + n)) { - // only remove it if the current row is not part of the data that is copied - if (n > 0 && rownum > endRow) { - return true; - } - else if (n < 0 && rownum < startRow) { - return true; - } - } - return false; - } - - private CTPane getPane() { - if (getDefaultSheetView().getPane() == null) { - getDefaultSheetView().addNewPane(); - } - return getDefaultSheetView().getPane(); - } - - /** - * Return a master shared formula by index - * - * @param sid shared group index - * @return a CTCellFormula bean holding shared formula or null if not found - */ - @Internal - public CTCellFormula getSharedFormula(int sid){ - return sharedFormulas.get(sid); - } - - void onReadCell(XSSFCell cell){ - //collect cells holding shared formulas - CTCell ct = cell.getCTCell(); - CTCellFormula f = ct.getF(); - if (f != null && f.getT() == STCellFormulaType.SHARED && f.isSetRef() && f.getStringValue() != null) { - // save a detached copy to avoid XmlValueDisconnectedException, - // this may happen when the master cell of a shared formula is changed - CTCellFormula sf = (CTCellFormula)f.copy(); - CellRangeAddress sfRef = CellRangeAddress.valueOf(sf.getRef()); - CellReference cellRef = new CellReference(cell); - // If the shared formula range precedes the master cell then the preceding part is discarded, e.g. - // if the cell is E60 and the shared formula range is C60:M85 then the effective range is E60:M85 - // see more details in https://issues.apache.org/bugzilla/show_bug.cgi?id=51710 - if(cellRef.getCol() > sfRef.getFirstColumn() || cellRef.getRow() > sfRef.getFirstRow()){ - String effectiveRef = new CellRangeAddress( - Math.max(cellRef.getRow(), sfRef.getFirstRow()), sfRef.getLastRow(), - Math.max(cellRef.getCol(), sfRef.getFirstColumn()), sfRef.getLastColumn()).formatAsString(); - sf.setRef(effectiveRef); - } - - sharedFormulas.put((int)f.getSi(), sf); - } - if (f != null && f.getT() == STCellFormulaType.ARRAY && f.getRef() != null) { - arrayFormulas.add(CellRangeAddress.valueOf(f.getRef())); - } - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - write(out); - out.close(); - } - - protected void write(OutputStream out) throws IOException { - boolean setToNull = false; - if(worksheet.sizeOfColsArray() == 1) { - CTCols col = worksheet.getColsArray(0); - if(col.sizeOfColArray() == 0) { - setToNull = true; - // this is necessary so that we do not write an empty item into the sheet-xml in the xlsx-file - // Excel complains about a corrupted file if this shows up there! - worksheet.setColsArray(null); - } else { - setColWidthAttribute(col); - } - } - - // Now re-generate our CTHyperlinks, if needed - if(hyperlinks.size() > 0) { - if(worksheet.getHyperlinks() == null) { - worksheet.addNewHyperlinks(); - } - CTHyperlink[] ctHls = new CTHyperlink[hyperlinks.size()]; - for(int i=0; i getCellRange(CellRangeAddress range) { - int firstRow = range.getFirstRow(); - int firstColumn = range.getFirstColumn(); - int lastRow = range.getLastRow(); - int lastColumn = range.getLastColumn(); - int height = lastRow - firstRow + 1; - int width = lastColumn - firstColumn + 1; - List temp = new ArrayList(height*width); - for (int rowIn = firstRow; rowIn <= lastRow; rowIn++) { - for (int colIn = firstColumn; colIn <= lastColumn; colIn++) { - XSSFRow row = getRow(rowIn); - if (row == null) { - row = createRow(rowIn); - } - XSSFCell cell = row.getCell(colIn); - if (cell == null) { - cell = row.createCell(colIn); - } - temp.add(cell); - } - } - return SSCellRange.create(firstRow, firstColumn, height, width, temp, XSSFCell.class); - } - - @Override - public CellRange setArrayFormula(String formula, CellRangeAddress range) { - - CellRange cr = getCellRange(range); - - XSSFCell mainArrayFormulaCell = cr.getTopLeftCell(); - mainArrayFormulaCell.setCellArrayFormula(formula, range); - arrayFormulas.add(range); - return cr; - } - - @Override - public CellRange removeArrayFormula(Cell cell) { - if (cell.getSheet() != this) { - throw new IllegalArgumentException("Specified cell does not belong to this sheet."); - } - for (CellRangeAddress range : arrayFormulas) { - if (range.isInRange(cell.getRowIndex(), cell.getColumnIndex())) { - arrayFormulas.remove(range); - CellRange cr = getCellRange(range); - for (XSSFCell c : cr) { - c.setCellType(CellType.BLANK); - } - return cr; - } - } - String ref = ((XSSFCell)cell).getCTCell().getR(); - throw new IllegalArgumentException("Cell " + ref + " is not part of an array formula."); - } - - - @Override - public DataValidationHelper getDataValidationHelper() { - return dataValidationHelper; - } - - public List getDataValidations() { - List xssfValidations = new ArrayList(); - CTDataValidations dataValidations = this.worksheet.getDataValidations(); - if( dataValidations!=null && dataValidations.getCount() > 0 ) { - for (CTDataValidation ctDataValidation : dataValidations.getDataValidationArray()) { - CellRangeAddressList addressList = new CellRangeAddressList(); - - @SuppressWarnings("unchecked") - List sqref = ctDataValidation.getSqref(); - for (String stRef : sqref) { - String[] regions = stRef.split(" "); - for (String region : regions) { - String[] parts = region.split(":"); - CellReference begin = new CellReference(parts[0]); - CellReference end = parts.length > 1 ? new CellReference(parts[1]) : begin; - CellRangeAddress cellRangeAddress = new CellRangeAddress(begin.getRow(), end.getRow(), begin.getCol(), end.getCol()); - addressList.addCellRangeAddress(cellRangeAddress); - } - } - XSSFDataValidation xssfDataValidation = new XSSFDataValidation(addressList, ctDataValidation); - xssfValidations.add(xssfDataValidation); - } - } - return xssfValidations; - } - - @Override - public void addValidationData(DataValidation dataValidation) { - XSSFDataValidation xssfDataValidation = (XSSFDataValidation)dataValidation; - CTDataValidations dataValidations = worksheet.getDataValidations(); - if( dataValidations==null ) { - dataValidations = worksheet.addNewDataValidations(); - } - int currentCount = dataValidations.sizeOfDataValidationArray(); - CTDataValidation newval = dataValidations.addNewDataValidation(); - newval.set(xssfDataValidation.getCtDdataValidation()); - dataValidations.setCount(currentCount + 1); - - } - - @SuppressWarnings("resource") - @Override - public XSSFAutoFilter setAutoFilter(CellRangeAddress range) { - CTAutoFilter af = worksheet.getAutoFilter(); - if(af == null) af = worksheet.addNewAutoFilter(); - - CellRangeAddress norm = new CellRangeAddress(range.getFirstRow(), range.getLastRow(), - range.getFirstColumn(), range.getLastColumn()); - String ref = norm.formatAsString(); - af.setRef(ref); - - XSSFWorkbook wb = getWorkbook(); - int sheetIndex = getWorkbook().getSheetIndex(this); - XSSFName name = wb.getBuiltInName(XSSFName.BUILTIN_FILTER_DB, sheetIndex); - if (name == null) { - name = wb.createBuiltInName(XSSFName.BUILTIN_FILTER_DB, sheetIndex); - } - - name.getCTName().setHidden(true); - CellReference r1 = new CellReference(getSheetName(), range.getFirstRow(), range.getFirstColumn(), true, true); - CellReference r2 = new CellReference(null, range.getLastRow(), range.getLastColumn(), true, true); - String fmla = r1.formatAsString() + ":" + r2.formatAsString(); - name.setRefersToFormula(fmla); - - return new XSSFAutoFilter(this); - } - - /** - * Creates a new Table, and associates it with this Sheet - */ - public XSSFTable createTable() { - if(! worksheet.isSetTableParts()) { - worksheet.addNewTableParts(); - } - - CTTableParts tblParts = worksheet.getTableParts(); - CTTablePart tbl = tblParts.addNewTablePart(); - - // Table numbers need to be unique in the file, not just - // unique within the sheet. Find the next one - int tableNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.TABLE.getContentType()).size() + 1; - RelationPart rp = createRelationship(XSSFRelation.TABLE, XSSFFactory.getInstance(), tableNumber, false); - XSSFTable table = rp.getDocumentPart(); - tbl.setId(rp.getRelationship().getId()); - - tables.put(tbl.getId(), table); - - return table; - } - - /** - * Returns any tables associated with this Sheet - */ - public List getTables() { - return new ArrayList(tables.values()); - } - - @Override - public XSSFSheetConditionalFormatting getSheetConditionalFormatting(){ - return new XSSFSheetConditionalFormatting(this); - } - - /** - * Get background color of the sheet tab. - * Returns null if no sheet tab color is set. - * - * @return the background color of the sheet tab - */ - public XSSFColor getTabColor() { - CTSheetPr pr = worksheet.getSheetPr(); - if(pr == null) pr = worksheet.addNewSheetPr(); - if (!pr.isSetTabColor()) { - return null; - } - return new XSSFColor(pr.getTabColor()); - } - - /** - * Set background color of the sheet tab - * - * @param colorIndex the indexed color to set, must be a constant from {@link org.apache.poi.ss.usermodel.IndexedColors} - * @deprecated 3.15-beta2. Removed in 3.17. Use {@link #setTabColor(XSSFColor)}. - */ - public void setTabColor(int colorIndex) { - IndexedColors indexedColor = IndexedColors.fromInt(colorIndex); - XSSFColor color = new XSSFColor(indexedColor); - setTabColor(color); - } - - /** - * Set background color of the sheet tab - * - * @param color the color to set - */ - public void setTabColor(XSSFColor color) { - CTSheetPr pr = worksheet.getSheetPr(); - if(pr == null) pr = worksheet.addNewSheetPr(); - pr.setTabColor(color.getCTColor()); - } - - @Override - public CellRangeAddress getRepeatingRows() { - return getRepeatingRowsOrColums(true); - } - - - @Override - public CellRangeAddress getRepeatingColumns() { - return getRepeatingRowsOrColums(false); - } - - @Override - public void setRepeatingRows(CellRangeAddress rowRangeRef) { - CellRangeAddress columnRangeRef = getRepeatingColumns(); - setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef); - } - - - @Override - public void setRepeatingColumns(CellRangeAddress columnRangeRef) { - CellRangeAddress rowRangeRef = getRepeatingRows(); - setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef); - } - - - private void setRepeatingRowsAndColumns( - CellRangeAddress rowDef, CellRangeAddress colDef) { - int col1 = -1; - int col2 = -1; - int row1 = -1; - int row2 = -1; - - if (rowDef != null) { - row1 = rowDef.getFirstRow(); - row2 = rowDef.getLastRow(); - if ((row1 == -1 && row2 != -1) - || row1 < -1 || row2 < -1 || row1 > row2) { - throw new IllegalArgumentException("Invalid row range specification"); - } - } - if (colDef != null) { - col1 = colDef.getFirstColumn(); - col2 = colDef.getLastColumn(); - if ((col1 == -1 && col2 != -1) - || col1 < -1 || col2 < -1 || col1 > col2) { - throw new IllegalArgumentException( - "Invalid column range specification"); - } - } - - int sheetIndex = getWorkbook().getSheetIndex(this); - - boolean removeAll = rowDef == null && colDef == null; - - XSSFName name = getWorkbook().getBuiltInName( - XSSFName.BUILTIN_PRINT_TITLE, sheetIndex); - if (removeAll) { - if (name != null) { - getWorkbook().removeName(name); - } - return; - } - if (name == null) { - name = getWorkbook().createBuiltInName( - XSSFName.BUILTIN_PRINT_TITLE, sheetIndex); - } - - String reference = getReferenceBuiltInRecord( - name.getSheetName(), col1, col2, row1, row2); - name.setRefersToFormula(reference); - - // If the print setup isn't currently defined, then add it - // in but without printer defaults - // If it's already there, leave it as-is! - if (worksheet.isSetPageSetup() && worksheet.isSetPageMargins()) { - // Everything we need is already there - } else { - // Have initial ones put in place - getPrintSetup().setValidSettings(false); - } - } - - private static String getReferenceBuiltInRecord( - String sheetName, int startC, int endC, int startR, int endR) { - // Excel example for built-in title: - // 'second sheet'!$E:$F,'second sheet'!$2:$3 - - CellReference colRef = - new CellReference(sheetName, 0, startC, true, true); - CellReference colRef2 = - new CellReference(sheetName, 0, endC, true, true); - CellReference rowRef = - new CellReference(sheetName, startR, 0, true, true); - CellReference rowRef2 = - new CellReference(sheetName, endR, 0, true, true); - - String escapedName = SheetNameFormatter.format(sheetName); - - String c = ""; - String r = ""; - - if (startC != -1 || endC != -1) { - String col1 = colRef.getCellRefParts()[2]; - String col2 = colRef2.getCellRefParts()[2]; - c = escapedName + "!$" + col1 + ":$" + col2; - } - - if (startR != -1 || endR != -1) { - String row1 = rowRef.getCellRefParts()[1]; - String row2 = rowRef2.getCellRefParts()[1]; - if (!row1.equals("0") && !row2.equals("0")) { - r = escapedName + "!$" + row1 + ":$" + row2; - } - } - - StringBuilder rng = new StringBuilder(); - rng.append(c); - if(rng.length() > 0 && r.length() > 0) { - rng.append(','); - } - rng.append(r); - return rng.toString(); - } - - - private CellRangeAddress getRepeatingRowsOrColums(boolean rows) { - int sheetIndex = getWorkbook().getSheetIndex(this); - XSSFName name = getWorkbook().getBuiltInName( - XSSFName.BUILTIN_PRINT_TITLE, sheetIndex); - if (name == null ) { - return null; - } - String refStr = name.getRefersToFormula(); - if (refStr == null) { - return null; - } - String[] parts = refStr.split(","); - int maxRowIndex = SpreadsheetVersion.EXCEL2007.getLastRowIndex(); - int maxColIndex = SpreadsheetVersion.EXCEL2007.getLastColumnIndex(); - for (String part : parts) { - CellRangeAddress range = CellRangeAddress.valueOf(part); - if ((range.getFirstColumn() == 0 - && range.getLastColumn() == maxColIndex) - || (range.getFirstColumn() == -1 - && range.getLastColumn() == -1)) { - if (rows) { - return range; - } - } else if (range.getFirstRow() == 0 - && range.getLastRow() == maxRowIndex - || (range.getFirstRow() == -1 - && range.getLastRow() == -1)) { - if (!rows) { - return range; - } - } - } - return null; - } - - /** - * Creates an empty XSSFPivotTable and sets up all its relationships - * including: pivotCacheDefinition, pivotCacheRecords - * @return returns a pivotTable - */ - @SuppressWarnings("resource") - @Beta - private XSSFPivotTable createPivotTable() { - XSSFWorkbook wb = getWorkbook(); - List pivotTables = wb.getPivotTables(); - int tableId = getWorkbook().getPivotTables().size()+1; - //Create relationship between pivotTable and the worksheet - XSSFPivotTable pivotTable = (XSSFPivotTable) createRelationship(XSSFRelation.PIVOT_TABLE, - XSSFFactory.getInstance(), tableId); - pivotTable.setParentSheet(this); - pivotTables.add(pivotTable); - XSSFWorkbook workbook = getWorkbook(); - - //Create relationship between the pivot cache defintion and the workbook - XSSFPivotCacheDefinition pivotCacheDefinition = (XSSFPivotCacheDefinition) workbook. - createRelationship(XSSFRelation.PIVOT_CACHE_DEFINITION, XSSFFactory.getInstance(), tableId); - String rId = workbook.getRelationId(pivotCacheDefinition); - //Create relationship between pivotTable and pivotCacheDefinition without creating a new instance - PackagePart pivotPackagePart = pivotTable.getPackagePart(); - pivotPackagePart.addRelationship(pivotCacheDefinition.getPackagePart().getPartName(), - TargetMode.INTERNAL, XSSFRelation.PIVOT_CACHE_DEFINITION.getRelation()); - - pivotTable.setPivotCacheDefinition(pivotCacheDefinition); - - //Create pivotCache and sets up it's relationship with the workbook - pivotTable.setPivotCache(new XSSFPivotCache(workbook.addPivotCache(rId))); - - //Create relationship between pivotcacherecord and pivotcachedefinition - XSSFPivotCacheRecords pivotCacheRecords = (XSSFPivotCacheRecords) pivotCacheDefinition. - createRelationship(XSSFRelation.PIVOT_CACHE_RECORDS, XSSFFactory.getInstance(), tableId); - - //Set relationships id for pivotCacheDefinition to pivotCacheRecords - pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().setId(pivotCacheDefinition.getRelationId(pivotCacheRecords)); - - wb.setPivotTables(pivotTables); - - return pivotTable; - } - - /** - * Create a pivot table using the AreaReference range on sourceSheet, at the given position. - * If the source reference contains a sheet name, it must match the sourceSheet - * @param source location of pivot data - * @param position A reference to the top left cell where the pivot table will start - * @param sourceSheet The sheet containing the source data, if the source reference doesn't contain a sheet name - * @throws IllegalArgumentException if source references a sheet different than sourceSheet - * @return The pivot table - */ - @Beta - public XSSFPivotTable createPivotTable(final AreaReference source, CellReference position, Sheet sourceSheet) { - final String sourceSheetName = source.getFirstCell().getSheetName(); - if(sourceSheetName != null && !sourceSheetName.equalsIgnoreCase(sourceSheet.getSheetName())) { - throw new IllegalArgumentException("The area is referenced in another sheet than the " - + "defined source sheet " + sourceSheet.getSheetName() + "."); - } - - return createPivotTable(position, sourceSheet, new PivotTableReferenceConfigurator() { - public void configureReference(CTWorksheetSource wsSource) { - final String[] firstCell = source.getFirstCell().getCellRefParts(); - final String firstRow = firstCell[1]; - final String firstCol = firstCell[2]; - final String[] lastCell = source.getLastCell().getCellRefParts(); - final String lastRow = lastCell[1]; - final String lastCol = lastCell[2]; - final String ref = firstCol+firstRow+':'+lastCol+lastRow; //or just source.formatAsString() - wsSource.setRef(ref); - } - }); - } - - /** - * Create a pivot table using the AreaReference or named/table range on sourceSheet, at the given position. - * If the source reference contains a sheet name, it must match the sourceSheet. - * @param position A reference to the top left cell where the pivot table will start - * @param sourceSheet The sheet containing the source data, if the source reference doesn't contain a sheet name - * @param refConfig A reference to the pivot table configurator - * @throws IllegalArgumentException if source references a sheet different than sourceSheet - * @return The pivot table - */ - private XSSFPivotTable createPivotTable(CellReference position, Sheet sourceSheet, PivotTableReferenceConfigurator refConfig) { - - XSSFPivotTable pivotTable = createPivotTable(); - //Creates default settings for the pivot table - pivotTable.setDefaultPivotTableDefinition(); - - //Set sources and references - pivotTable.createSourceReferences(position, sourceSheet, refConfig); - - //Create cachefield/s and empty SharedItems - must be after creating references - pivotTable.getPivotCacheDefinition().createCacheFields(sourceSheet); - pivotTable.createDefaultDataColumns(); - - return pivotTable; - } - - /** - * Create a pivot table using the AreaReference range, at the given position. - * If the source reference contains a sheet name, that sheet is used, otherwise this sheet is assumed as the source sheet. - * @param source location of pivot data - * @param position A reference to the top left cell where the pivot table will start - * @return The pivot table - */ - @Beta - public XSSFPivotTable createPivotTable(AreaReference source, CellReference position){ - final String sourceSheetName = source.getFirstCell().getSheetName(); - if(sourceSheetName != null && !sourceSheetName.equalsIgnoreCase(this.getSheetName())) { - final XSSFSheet sourceSheet = getWorkbook().getSheet(sourceSheetName); - return createPivotTable(source, position, sourceSheet); - } - return createPivotTable(source, position, this); - } - - /** - * Create a pivot table using the Name range reference on sourceSheet, at the given position. - * If the source reference contains a sheet name, it must match the sourceSheet - * @param source location of pivot data - * @param position A reference to the top left cell where the pivot table will start - * @param sourceSheet The sheet containing the source data, if the source reference doesn't contain a sheet name - * @throws IllegalArgumentException if source references a sheet different than sourceSheet - * @return The pivot table - */ - @Beta - public XSSFPivotTable createPivotTable(final Name source, CellReference position, Sheet sourceSheet) { - if(source.getSheetName() != null && !source.getSheetName().equals(sourceSheet.getSheetName())) { - throw new IllegalArgumentException("The named range references another sheet than the " - + "defined source sheet " + sourceSheet.getSheetName() + "."); - } - - return createPivotTable(position, sourceSheet, new PivotTableReferenceConfigurator() { - public void configureReference(CTWorksheetSource wsSource) { - wsSource.setName(source.getNameName()); - } - }); - } - - /** - * Create a pivot table using the Name range, at the given position. - * If the source reference contains a sheet name, that sheet is used, otherwise this sheet is assumed as the source sheet. - * @param source location of pivot data - * @param position A reference to the top left cell where the pivot table will start - * @return The pivot table - */ - @Beta - public XSSFPivotTable createPivotTable(Name source, CellReference position) { - return createPivotTable(source, position, getWorkbook().getSheet(source.getSheetName())); - } - - /** - * Create a pivot table using the Table, at the given position. - * Tables are required to have a sheet reference, so no additional logic around reference sheet is needed. - * @param source location of pivot data - * @param position A reference to the top left cell where the pivot table will start - * @return The pivot table - */ - @Beta - public XSSFPivotTable createPivotTable(final Table source, CellReference position) { - return createPivotTable(position, getWorkbook().getSheet(source.getSheetName()), new PivotTableReferenceConfigurator() { - public void configureReference(CTWorksheetSource wsSource) { - wsSource.setName(source.getName()); - } - }); - } - - /** - * Returns all the pivot tables for this Sheet - */ - @Beta - public List getPivotTables() { - List tables = new ArrayList(); - for (XSSFPivotTable table : getWorkbook().getPivotTables()) { - if (table.getParent() == this) { - tables.add(table); - } - } - return tables; - } - - public int getColumnOutlineLevel(int columnIndex) { - CTCol col = columnHelper.getColumn(columnIndex, false); - if (col == null) { - return 0; - } - return col.getOutlineLevel(); - } - - /** - * Add ignored errors (usually to suppress them in the UI of a consuming - * application). - * - * @param cell Cell. - * @param ignoredErrorTypes Types of error to ignore there. - */ - public void addIgnoredErrors(CellReference cell, IgnoredErrorType... ignoredErrorTypes) { - addIgnoredErrors(cell.formatAsString(), ignoredErrorTypes); - } - - /** - * Ignore errors across a range of cells. - * - * @param region Range of cells. - * @param ignoredErrorTypes Types of error to ignore there. - */ - public void addIgnoredErrors(CellRangeAddress region, IgnoredErrorType... ignoredErrorTypes) { - region.validate(SpreadsheetVersion.EXCEL2007); - addIgnoredErrors(region.formatAsString(), ignoredErrorTypes); - } - - /** - * Returns the errors currently being ignored and the ranges - * where they are ignored. - * - * @return Map of error type to the range(s) where they are ignored. - */ - public Map> getIgnoredErrors() { - Map> result = new LinkedHashMap>(); - if (worksheet.isSetIgnoredErrors()) { - for (CTIgnoredError err : worksheet.getIgnoredErrors().getIgnoredErrorList()) { - for (IgnoredErrorType errType : XSSFIgnoredErrorHelper.getErrorTypes(err)) { - if (!result.containsKey(errType)) { - result.put(errType, new LinkedHashSet()); - } - for (Object ref : err.getSqref()) { - result.get(errType).add(CellRangeAddress.valueOf(ref.toString())); - } - } - } - } - return result; - } - - private void addIgnoredErrors(String ref, IgnoredErrorType... ignoredErrorTypes) { - CTIgnoredErrors ctIgnoredErrors = worksheet.isSetIgnoredErrors() ? worksheet.getIgnoredErrors() : worksheet.addNewIgnoredErrors(); - CTIgnoredError ctIgnoredError = ctIgnoredErrors.addNewIgnoredError(); - XSSFIgnoredErrorHelper.addIgnoredErrors(ctIgnoredError, ref, ignoredErrorTypes); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java deleted file mode 100644 index a3781d22d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.ComparisonOperator; -import org.apache.poi.ss.usermodel.ConditionalFormatting; -import org.apache.poi.ss.usermodel.ConditionalFormattingRule; -import org.apache.poi.ss.usermodel.ExtendedColor; -import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet; -import org.apache.poi.ss.usermodel.SheetConditionalFormatting; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeUtil; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator; - -/** - * XSSF Conditional Formattings - */ -public class XSSFSheetConditionalFormatting implements SheetConditionalFormatting { - /** Office 2010 Conditional Formatting extensions namespace */ - protected static final String CF_EXT_2009_NS_X14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"; - - private final XSSFSheet _sheet; - - /* package */ XSSFSheetConditionalFormatting(XSSFSheet sheet) { - _sheet = sheet; - } - - /** - * A factory method allowing to create a conditional formatting rule - * with a cell comparison operator

        - * TODO - formulas containing cell references are currently not parsed properly - * - * @param comparisonOperation - a constant value from - * {@link org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator}:

        - *

          - *
        • BETWEEN
        • - *
        • NOT_BETWEEN
        • - *
        • EQUAL
        • - *
        • NOT_EQUAL
        • - *
        • GT
        • - *
        • LT
        • - *
        • GE
        • - *
        • LE
        • - *
        - *

        - * @param formula1 - formula for the valued, compared with the cell - * @param formula2 - second formula (only used with - * {@link org.apache.poi.ss.usermodel.ComparisonOperator#BETWEEN}) and - * {@link org.apache.poi.ss.usermodel.ComparisonOperator#NOT_BETWEEN} operations) - */ - public XSSFConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula1, - String formula2) { - - XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet); - CTCfRule cfRule = rule.getCTCfRule(); - cfRule.addFormula(formula1); - if(formula2 != null) cfRule.addFormula(formula2); - cfRule.setType(STCfType.CELL_IS); - STConditionalFormattingOperator.Enum operator; - switch (comparisonOperation){ - case ComparisonOperator.BETWEEN: operator = STConditionalFormattingOperator.BETWEEN; break; - case ComparisonOperator.NOT_BETWEEN: operator = STConditionalFormattingOperator.NOT_BETWEEN; break; - case ComparisonOperator.LT: operator = STConditionalFormattingOperator.LESS_THAN; break; - case ComparisonOperator.LE: operator = STConditionalFormattingOperator.LESS_THAN_OR_EQUAL; break; - case ComparisonOperator.GT: operator = STConditionalFormattingOperator.GREATER_THAN; break; - case ComparisonOperator.GE: operator = STConditionalFormattingOperator.GREATER_THAN_OR_EQUAL; break; - case ComparisonOperator.EQUAL: operator = STConditionalFormattingOperator.EQUAL; break; - case ComparisonOperator.NOT_EQUAL: operator = STConditionalFormattingOperator.NOT_EQUAL; break; - default: throw new IllegalArgumentException("Unknown comparison operator: " + comparisonOperation); - } - cfRule.setOperator(operator); - - return rule; - } - - public XSSFConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula) { - - return createConditionalFormattingRule(comparisonOperation, formula, null); - } - - /** - * A factory method allowing to create a conditional formatting rule with a formula.
        - * - * @param formula - formula for the valued, compared with the cell - */ - public XSSFConditionalFormattingRule createConditionalFormattingRule(String formula) { - XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet); - CTCfRule cfRule = rule.getCTCfRule(); - cfRule.addFormula(formula); - cfRule.setType(STCfType.EXPRESSION); - return rule; - } - - /** - * Create a Databar conditional formatting rule. - *

        The thresholds and colour for it will be created, but will be - * empty and require configuring with - * {@link XSSFConditionalFormattingRule#getDataBarFormatting()} - * then - * {@link XSSFDataBarFormatting#getMinThreshold()} - * and - * {@link XSSFDataBarFormatting#getMaxThreshold()} - */ - public XSSFConditionalFormattingRule createConditionalFormattingRule(XSSFColor color) { - XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet); - - // Have it setup, with suitable defaults - rule.createDataBarFormatting(color); - - // All done! - return rule; - } - public XSSFConditionalFormattingRule createConditionalFormattingRule(ExtendedColor color) { - return createConditionalFormattingRule((XSSFColor)color); - } - - /** - * A factory method allowing the creation of conditional formatting - * rules using an Icon Set / Multi-State formatting. - * The thresholds for it will be created, but will be empty - * and require configuring with - * {@link XSSFConditionalFormattingRule#getMultiStateFormatting()} - * then - * {@link XSSFIconMultiStateFormatting#getThresholds()} - */ - public XSSFConditionalFormattingRule createConditionalFormattingRule(IconSet iconSet) { - XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet); - - // Have it setup, with suitable defaults - rule.createMultiStateFormatting(iconSet); - - // All done! - return rule; - } - - /** - * Create a Color Scale / Color Gradient conditional formatting rule. - *

        The thresholds and colours for it will be created, but will be - * empty and require configuring with - * {@link XSSFConditionalFormattingRule#getColorScaleFormatting()} - * then - * {@link XSSFColorScaleFormatting#getThresholds()} - * and - * {@link XSSFColorScaleFormatting#getColors()} - */ - public XSSFConditionalFormattingRule createConditionalFormattingColorScaleRule() { - XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet); - - // Have it setup, with suitable defaults - rule.createColorScaleFormatting(); - - // All done! - return rule; - } - - public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) { - if (regions == null) { - throw new IllegalArgumentException("regions must not be null"); - } - for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL2007); - - if (cfRules == null) { - throw new IllegalArgumentException("cfRules must not be null"); - } - if (cfRules.length == 0) { - throw new IllegalArgumentException("cfRules must not be empty"); - } - if (cfRules.length > 3) { - throw new IllegalArgumentException("Number of rules must not exceed 3"); - } - - CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions); - CTConditionalFormatting cf = _sheet.getCTWorksheet().addNewConditionalFormatting(); - List refs = new ArrayList(); - for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString()); - cf.setSqref(refs); - - int priority = 1; - for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingArray()){ - priority += c.sizeOfCfRuleArray(); - } - - for(ConditionalFormattingRule rule : cfRules){ - XSSFConditionalFormattingRule xRule = (XSSFConditionalFormattingRule)rule; - xRule.getCTCfRule().setPriority(priority++); - cf.addNewCfRule().set(xRule.getCTCfRule()); - } - return _sheet.getCTWorksheet().sizeOfConditionalFormattingArray() - 1; - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - ConditionalFormattingRule rule1) - { - return addConditionalFormatting(regions, - rule1 == null ? null : new XSSFConditionalFormattingRule[] { - (XSSFConditionalFormattingRule)rule1 - }); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - ConditionalFormattingRule rule1, ConditionalFormattingRule rule2) - { - return addConditionalFormatting(regions, - rule1 == null ? null : new XSSFConditionalFormattingRule[] { - (XSSFConditionalFormattingRule)rule1, - (XSSFConditionalFormattingRule)rule2 - }); - } - - /** - * Adds a copy of HSSFConditionalFormatting object to the sheet - *

        This method could be used to copy HSSFConditionalFormatting object - * from one sheet to another. For example: - *

        -     * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
        -     * newSheet.addConditionalFormatting(cf);
        -     * 
        - * - * @param cf HSSFConditionalFormatting object - * @return index of the new Conditional Formatting object - */ - public int addConditionalFormatting( ConditionalFormatting cf ) { - XSSFConditionalFormatting xcf = (XSSFConditionalFormatting)cf; - CTWorksheet sh = _sheet.getCTWorksheet(); - sh.addNewConditionalFormatting().set(xcf.getCTConditionalFormatting().copy()); - return sh.sizeOfConditionalFormattingArray() - 1; - } - - /** - * gets Conditional Formatting object at a particular index - * - * @param index - * of the Conditional Formatting object to fetch - * @return Conditional Formatting object - */ - public XSSFConditionalFormatting getConditionalFormattingAt(int index) { - checkIndex(index); - CTConditionalFormatting cf = _sheet.getCTWorksheet().getConditionalFormattingArray(index); - return new XSSFConditionalFormatting(_sheet, cf); - } - - /** - * @return number of Conditional Formatting objects of the sheet - */ - public int getNumConditionalFormattings() { - return _sheet.getCTWorksheet().sizeOfConditionalFormattingArray(); - } - - /** - * removes a Conditional Formatting object by index - * @param index of a Conditional Formatting object to remove - */ - public void removeConditionalFormatting(int index) { - checkIndex(index); - _sheet.getCTWorksheet().removeConditionalFormatting(index); - } - - private void checkIndex(int index) { - int cnt = getNumConditionalFormattings(); - if (index < 0 || index >= cnt) { - throw new IllegalArgumentException("Specified CF index " + index - + " is outside the allowable range (0.." + (cnt - 1) + ")"); - } - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java deleted file mode 100644 index 3d5899340..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java +++ /dev/null @@ -1,866 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.openxmlformats.schemas.drawingml.x2006.main.*; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues; - -/** - * Represents a shape with a predefined geometry in a SpreadsheetML drawing. - * Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes} - */ -public class XSSFSimpleShape extends XSSFShape implements Iterable { // TODO - instantiable superclass - /** - * List of the paragraphs that make up the text in this shape - */ - private final List _paragraphs; - /** - * 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; - - _paragraphs = new ArrayList(); - - // initialize any existing paragraphs - this will be the default body paragraph in a new shape, - // or existing paragraphs that have been loaded from the file - CTTextBody body = ctShape.getTxBody(); - if(body != null) { - for(int i = 0; i < body.sizeOfPArray(); i++) { - _paragraphs.add(new XSSFTextParagraph(body.getPArray(i), 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(); - - CTTextBody body = shape.addNewTxBody(); - CTTextBodyProperties bodypr = body.addNewBodyPr(); - bodypr.setAnchor(STTextAnchoringType.T); - bodypr.setRtlCol(false); - CTTextParagraph p = body.addNewP(); - p.addNewPPr().setAlgn(STTextAlignType.L); - CTTextCharacterProperties endPr = p.addNewEndParaRPr(); - endPr.setLang("en-US"); - endPr.setSz(1100); - CTSolidColorFillProperties scfpr = endPr.addNewSolidFill(); - scfpr.addNewSrgbClr().setVal(new byte[] { 0, 0, 0 }); - - body.addNewLstStyle(); - - prototype = shape; - } - return prototype; - } - - @Internal - public CTShape getCTShape(){ - return ctShape; - } - - - public Iterator iterator(){ - return _paragraphs.iterator(); - } - - /** - * Returns the text from all paragraphs in the shape. Paragraphs are separated by new lines. - * - * @return text contained within this shape or empty string - */ - public String getText() { - final int MAX_LEVELS = 9; - StringBuilder out = new StringBuilder(); - List levelCount = new ArrayList(MAX_LEVELS); // maximum 9 levels - XSSFTextParagraph p = null; - - // initialise the levelCount array - this maintains a record of the numbering to be used at each level - for (int k = 0; k < MAX_LEVELS; k++){ - levelCount.add(0); - } - - for(int i = 0; i < _paragraphs.size(); i++) { - if (out.length() > 0) out.append('\n'); - p = _paragraphs.get(i); - - if(p.isBullet() && p.getText().length() > 0){ - - int level = Math.min(p.getLevel(), MAX_LEVELS - 1); - - if(p.isBulletAutoNumber()){ - i = processAutoNumGroup(i, level, levelCount, out); - } else { - // indent appropriately for the level - for(int j = 0; j < level; j++){ - out.append('\t'); - } - String character = p.getBulletCharacter(); - out.append(character.length() > 0 ? character + " " : "- "); - out.append(p.getText()); - } - } else { - out.append(p.getText()); - - // this paragraph is not a bullet, so reset the count array - for (int k = 0; k < MAX_LEVELS; k++){ - levelCount.set(k, 0); - } - } - } - - return out.toString(); - } - - /** - * - */ - private int processAutoNumGroup(int index, int level, List levelCount, StringBuilder out){ - XSSFTextParagraph p = null; - XSSFTextParagraph nextp = null; - ListAutoNumber scheme, nextScheme; - int startAt, nextStartAt; - - p = _paragraphs.get(index); - - // The rules for generating the auto numbers are as follows. If the following paragraph is also - // an auto-number, has the same type/scheme (and startAt if defined on this paragraph) then they are - // considered part of the same group. An empty bullet paragraph is counted as part of the same - // group but does not increment the count for the group. A change of type, startAt or the paragraph - // not being a bullet resets the count for that level to 1. - - // first auto-number paragraph so initialise to 1 or the bullets startAt if present - startAt = p.getBulletAutoNumberStart(); - scheme = p.getBulletAutoNumberScheme(); - if(levelCount.get(level) == 0) { - levelCount.set(level, startAt == 0 ? 1 : startAt); - } - // indent appropriately for the level - for(int j = 0; j < level; j++){ - out.append('\t'); - } - if (p.getText().length() > 0){ - out.append(getBulletPrefix(scheme, levelCount.get(level))); - out.append(p.getText()); - } - while(true) { - nextp = (index + 1) == _paragraphs.size() ? null : _paragraphs.get(index + 1); - if(nextp == null) break; // out of paragraphs - if(!(nextp.isBullet() && p.isBulletAutoNumber())) break; // not an auto-number bullet - if(nextp.getLevel() > level) { - // recurse into the new level group - if (out.length() > 0) out.append('\n'); - index = processAutoNumGroup(index + 1, nextp.getLevel(), levelCount, out); - continue; // restart the loop given the new index - } else if(nextp.getLevel() < level) { - break; // changed level - } - nextScheme = nextp.getBulletAutoNumberScheme(); - nextStartAt = nextp.getBulletAutoNumberStart(); - - if(nextScheme == scheme && nextStartAt == startAt) { - // bullet is valid, so increment i - ++index; - if (out.length() > 0) out.append('\n'); - // indent for the level - for(int j = 0; j < level; j++){ - out.append('\t'); - } - // check for empty text - only output a bullet if there is text, but it is still part of the group - if(nextp.getText().length() > 0) { - // increment the count for this level - levelCount.set(level, levelCount.get(level) + 1); - out.append(getBulletPrefix(nextScheme, levelCount.get(level))); - out.append(nextp.getText()); - } - } else { - // something doesn't match so stop - break; - } - } - // end of the group so reset the count for this level - levelCount.set(level, 0); - - return index; - } - /** - * Returns a string containing an appropriate prefix for an auto-numbering bullet - * @param scheme the auto-numbering scheme used by the bullet - * @param value the value of the bullet - * @return appropriate prefix for an auto-numbering bullet - */ - private String getBulletPrefix(ListAutoNumber scheme, int value){ - StringBuilder out = new StringBuilder(); - - switch(scheme) { - case ALPHA_LC_PARENT_BOTH: - case ALPHA_LC_PARENT_R: - if(scheme == ListAutoNumber.ALPHA_LC_PARENT_BOTH) out.append('('); - out.append(valueToAlpha(value).toLowerCase(Locale.ROOT)); - out.append(')'); - break; - case ALPHA_UC_PARENT_BOTH: - case ALPHA_UC_PARENT_R: - if(scheme == ListAutoNumber.ALPHA_UC_PARENT_BOTH) out.append('('); - out.append(valueToAlpha(value)); - out.append(')'); - break; - case ALPHA_LC_PERIOD: - out.append(valueToAlpha(value).toLowerCase(Locale.ROOT)); - out.append('.'); - break; - case ALPHA_UC_PERIOD: - out.append(valueToAlpha(value)); - out.append('.'); - break; - case ARABIC_PARENT_BOTH: - case ARABIC_PARENT_R: - if(scheme == ListAutoNumber.ARABIC_PARENT_BOTH) out.append('('); - out.append(value); - out.append(')'); - break; - case ARABIC_PERIOD: - out.append(value); - out.append('.'); - break; - case ARABIC_PLAIN: - out.append(value); - break; - case ROMAN_LC_PARENT_BOTH: - case ROMAN_LC_PARENT_R: - if(scheme == ListAutoNumber.ROMAN_LC_PARENT_BOTH) out.append('('); - out.append(valueToRoman(value).toLowerCase(Locale.ROOT)); - out.append(')'); - break; - case ROMAN_UC_PARENT_BOTH: - case ROMAN_UC_PARENT_R: - if(scheme == ListAutoNumber.ROMAN_UC_PARENT_BOTH) out.append('('); - out.append(valueToRoman(value)); - out.append(')'); - break; - case ROMAN_LC_PERIOD: - out.append(valueToRoman(value).toLowerCase(Locale.ROOT)); - out.append('.'); - break; - case ROMAN_UC_PERIOD: - out.append(valueToRoman(value)); - out.append('.'); - break; - default: - out.append('\u2022'); // can't set the font to wingdings so use the default bullet character - break; - } - out.append(" "); - return out.toString(); - } - - /** - * Convert an integer to its alpha equivalent e.g. 1 = A, 2 = B, 27 = AA etc - */ - private String valueToAlpha(int value) { - String alpha = ""; - int modulo; - while (value > 0) { - modulo = (value - 1) % 26; - alpha = (char)(65 + modulo) + alpha; - value = (value - modulo) / 26; - } - return alpha; - } - - private static String[] _romanChars = new String[] { "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" }; - private static int[] _romanAlphaValues = new int[] { 1000,900,500,400,100,90,50,40,10,9,5,4,1 }; - - /** - * Convert an integer to its roman equivalent e.g. 1 = I, 9 = IX etc - */ - private String valueToRoman(int value) { - StringBuilder out = new StringBuilder(); - for(int i = 0; value > 0 && i < _romanChars.length; i++) { - while(_romanAlphaValues[i] <= value) { - out.append(_romanChars[i]); - value -= _romanAlphaValues[i]; - } - } - return out.toString(); - } - - /** - * Clear all text from this shape - */ - public void clearText(){ - _paragraphs.clear(); - CTTextBody txBody = ctShape.getTxBody(); - txBody.setPArray(null); // remove any existing paragraphs - } - - /** - * Set a single paragraph of text on the shape. Note this will replace all existing paragraphs created on the shape. - * @param text string representing the paragraph text - */ - public void setText(String text){ - clearText(); - - addNewTextParagraph().addNewTextRun().setText(text); - } - - /** - * Set a single paragraph of text on the shape. Note this will replace all existing paragraphs created on the shape. - * @param str rich text string representing the paragraph text - */ - 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(); - if(ltPr == null) ltPr = lt.addNewRPr(); - - CTRegularTextRun r = p.addNewR(); - CTTextCharacterProperties rPr = r.addNewRPr(); - rPr.setLang("en-US"); - - applyAttributes(ltPr, rPr); - - r.setT(lt.getT()); - } - } - - clearText(); - ctShape.getTxBody().setPArray(new CTTextParagraph[]{p}); - _paragraphs.add(new XSSFTextParagraph(ctShape.getTxBody().getPArray(0), ctShape)); - } - - /** - * Returns a collection of the XSSFTextParagraphs that are attached to this shape - * - * @return text paragraphs in this shape - */ - public List getTextParagraphs() { - return _paragraphs; - } - - /** - * Add a new paragraph run to this shape - * - * @return created paragraph run - */ - public XSSFTextParagraph addNewTextParagraph() { - CTTextBody txBody = ctShape.getTxBody(); - CTTextParagraph p = txBody.addNewP(); - XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape); - _paragraphs.add(paragraph); - return paragraph; - } - - /** - * Add a new paragraph run to this shape, set to the provided string - * - * @return created paragraph run - */ - public XSSFTextParagraph addNewTextParagraph(String text) { - XSSFTextParagraph paragraph = addNewTextParagraph(); - paragraph.addNewTextRun().setText(text); - return paragraph; - } - - /** - * Add a new paragraph run to this shape, set to the provided rich text string - * - * @return created paragraph run - */ - public XSSFTextParagraph addNewTextParagraph(XSSFRichTextString str) { - CTTextBody txBody = ctShape.getTxBody(); - CTTextParagraph p = txBody.addNewP(); - - 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(); - if(ltPr == null) ltPr = lt.addNewRPr(); - - CTRegularTextRun r = p.addNewR(); - CTTextCharacterProperties rPr = r.addNewRPr(); - rPr.setLang("en-US"); - - applyAttributes(ltPr, rPr); - - r.setT(lt.getT()); - } - } - - // Note: the XSSFTextParagraph constructor will create its required XSSFTextRuns from the provided CTTextParagraph - XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape); - _paragraphs.add(paragraph); - - return paragraph; - } - - /** - * Sets the type of horizontal overflow for the text. - * - * @param overflow - the type of horizontal overflow. - * A null values unsets this property. - */ - public void setTextHorizontalOverflow(TextHorizontalOverflow overflow){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(overflow == null) { - if(bodyPr.isSetHorzOverflow()) bodyPr.unsetHorzOverflow(); - } else { - bodyPr.setHorzOverflow(STTextHorzOverflowType.Enum.forInt(overflow.ordinal() + 1)); - } - } - } - - /** - * Returns the type of horizontal overflow for the text. - * - * @return the type of horizontal overflow - */ - public TextHorizontalOverflow getTextHorizontalOverflow(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if(bodyPr != null) { - if(bodyPr.isSetHorzOverflow()){ - return TextHorizontalOverflow.values()[bodyPr.getHorzOverflow().intValue() - 1]; - } - } - return TextHorizontalOverflow.OVERFLOW; - } - - /** - * Sets the type of vertical overflow for the text. - * - * @param overflow - the type of vertical overflow. - * A null values unsets this property. - */ - public void setTextVerticalOverflow(TextVerticalOverflow overflow){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(overflow == null) { - if(bodyPr.isSetVertOverflow()) bodyPr.unsetVertOverflow(); - } else { - bodyPr.setVertOverflow(STTextVertOverflowType.Enum.forInt(overflow.ordinal() + 1)); - } - } - } - - /** - * Returns the type of vertical overflow for the text. - * - * @return the type of vertical overflow - */ - public TextVerticalOverflow getTextVerticalOverflow(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if(bodyPr != null) { - if(bodyPr.isSetVertOverflow()){ - return TextVerticalOverflow.values()[bodyPr.getVertOverflow().intValue() - 1]; - } - } - return TextVerticalOverflow.OVERFLOW; - } - - /** - * Sets the type of vertical alignment for the text within the shape. - * - * @param anchor - the type of alignment. - * A null values unsets this property. - */ - public void setVerticalAlignment(VerticalAlignment anchor){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(anchor == null) { - if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor(); - } else { - bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); - } - } - } - - /** - * Returns the type of vertical alignment for the text within the shape. - * - * @return the type of vertical alignment - */ - public VerticalAlignment getVerticalAlignment(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if(bodyPr != null) { - if(bodyPr.isSetAnchor()){ - return VerticalAlignment.values()[bodyPr.getAnchor().intValue() - 1]; - } - } - return VerticalAlignment.TOP; - } - - /** - * Sets the vertical orientation of the text - * - * @param orientation vertical orientation of the text - * A null values unsets this property. - */ - public void setTextDirection(TextDirection orientation){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(orientation == null) { - if(bodyPr.isSetVert()) bodyPr.unsetVert(); - } else { - bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1)); - } - } - } - - /** - * Gets the vertical orientation of the text - * - * @return vertical orientation of the text - */ - public TextDirection getTextDirection(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - STTextVerticalType.Enum val = bodyPr.getVert(); - if(val != null){ - return TextDirection.values()[val.intValue() - 1]; - } - } - return TextDirection.HORIZONTAL; - } - - - /** - * Returns the distance (in points) between the bottom of the text frame - * and the bottom of the inscribed rectangle of the shape that contains the text. - * - * @return the bottom inset in points - */ - public double getBottomInset(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetBIns()){ - return Units.toPoints(bodyPr.getBIns()); - } - } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; - } - - /** - * Returns the distance (in points) between the left edge of the text frame - * and the left edge of the inscribed rectangle of the shape that contains - * the text. - * - * @return the left inset in points - */ - public double getLeftInset(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetLIns()){ - return Units.toPoints(bodyPr.getLIns()); - } - } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; - } - - /** - * Returns the distance (in points) between the right edge of the - * text frame and the right edge of the inscribed rectangle of the shape - * that contains the text. - * - * @return the right inset in points - */ - public double getRightInset(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetRIns()){ - return Units.toPoints(bodyPr.getRIns()); - } - } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; - } - - /** - * Returns the distance (in points) between the top of the text frame - * and the top of the inscribed rectangle of the shape that contains the text. - * - * @return the top inset in points - */ - public double getTopInset(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetTIns()){ - return Units.toPoints(bodyPr.getTIns()); - } - } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; - } - - /** - * Sets the bottom inset. - * @see #getBottomInset() - * - * @param margin the bottom margin - */ - public void setBottomInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetBIns()) bodyPr.unsetBIns(); - } else bodyPr.setBIns(Units.toEMU(margin)); - } - } - - /** - * Sets the left inset. - * @see #getLeftInset() - * - * @param margin the left margin - */ - public void setLeftInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetLIns()) bodyPr.unsetLIns(); - } else bodyPr.setLIns(Units.toEMU(margin)); - } - } - - /** - * Sets the right inset. - * @see #getRightInset() - * - * @param margin the right margin - */ - public void setRightInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetRIns()) bodyPr.unsetRIns(); - } else bodyPr.setRIns(Units.toEMU(margin)); - } - } - - /** - * Sets the top inset. - * @see #getTopInset() - * - * @param margin the top margin - */ - public void setTopInset(double margin){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(margin == -1) { - if(bodyPr.isSetTIns()) bodyPr.unsetTIns(); - } else bodyPr.setTIns(Units.toEMU(margin)); - } - } - - - /** - * @return whether to wrap words within the bounding rectangle - */ - public boolean getWordWrap(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetWrap()){ - return bodyPr.getWrap() == STTextWrappingType.SQUARE; - } - } - return true; - } - - /** - * - * @param wrap whether to wrap words within the bounding rectangle - */ - public void setWordWrap(boolean wrap){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE); - } - } - - /** - * - * Specifies that a shape should be auto-fit to fully contain the text described within it. - * Auto-fitting is when text within a shape is scaled in order to contain all the text inside - * - * @param value type of autofit - */ - public void setTextAutofit(TextAutofit value){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit(); - if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit(); - if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit(); - - switch(value){ - case NONE: bodyPr.addNewNoAutofit(); break; - case NORMAL: bodyPr.addNewNormAutofit(); break; - case SHAPE: bodyPr.addNewSpAutoFit(); break; - } - } - } - - /** - * - * @return type of autofit - */ - public TextAutofit getTextAutofit(){ - CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr(); - if (bodyPr != null) { - if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE; - else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL; - else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE; - } - return TextAutofit.NORMAL; - } - - /** - * 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(); - } - - /** - * org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt to - * org.openxmlformats.schemas.drawingml.x2006.main.CTFont adapter - */ - private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){ - - if(pr.sizeOfBArray() > 0) rPr.setB(pr.getBArray(0).getVal()); - if(pr.sizeOfUArray() > 0) { - STUnderlineValues.Enum u1 = pr.getUArray(0).getVal(); - if(u1 == STUnderlineValues.SINGLE) rPr.setU(STTextUnderlineType.SNG); - else if(u1 == STUnderlineValues.DOUBLE) rPr.setU(STTextUnderlineType.DBL); - else if(u1 == STUnderlineValues.NONE) rPr.setU(STTextUnderlineType.NONE); - } - if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal()); - - if(pr.sizeOfRFontArray() > 0) { - CTTextFont rFont = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin(); - rFont.setTypeface(pr.getRFontArray(0).getVal()); - } - - if(pr.sizeOfSzArray() > 0) { - int sz = (int)(pr.getSzArray(0).getVal()*100); - rPr.setSz(sz); - } - - if(pr.sizeOfColorArray() > 0) { - CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill(); - org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor xlsColor = pr.getColorArray(0); - if(xlsColor.isSetRgb()) { - CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr(); - clr.setVal(xlsColor.getRgb()); - } - else if(xlsColor.isSetIndexed()) { - HSSFColor indexed = HSSFColor.getIndexHash().get((int) xlsColor.getIndexed()); - if (indexed != null) { - byte[] rgb = new byte[3]; - rgb[0] = (byte) indexed.getTriplet()[0]; - rgb[1] = (byte) indexed.getTriplet()[1]; - rgb[2] = (byte) indexed.getTriplet()[2]; - CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr(); - clr.setVal(rgb); - } - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java deleted file mode 100644 index fb59384a1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ /dev/null @@ -1,456 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.usermodel.Table; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; -import org.apache.poi.util.Internal; -import org.apache.poi.util.StringUtil; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.TableDocument; - -/** - * - * This class implements the Table Part (Open Office XML Part 4: - * chapter 3.5.1) - * - * This implementation works under the assumption that a table contains mappings to a subtree of an XML. - * The root element of this subtree an occur multiple times (one for each row of the table). The child nodes - * of the root element can be only attributes or element with maxOccurs=1 property set - * - * - * @author Roberto Manicardi - */ -public class XSSFTable extends POIXMLDocumentPart implements Table { - - private CTTable ctTable; - private transient List xmlColumnPr; - private transient CTTableColumn[] ctColumns; - private transient HashMap columnMap; - private transient CellReference startCellReference; - private transient CellReference endCellReference; - private transient String commonXPath; - - - public XSSFTable() { - super(); - ctTable = CTTable.Factory.newInstance(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XSSFTable(PackagePart part) throws IOException { - super(part); - readFrom(part.getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XSSFTable(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public void readFrom(InputStream is) throws IOException { - try { - TableDocument doc = TableDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - ctTable = doc.getTable(); - } catch (XmlException e) { - throw new IOException(e.getLocalizedMessage()); - } - } - - public XSSFSheet getXSSFSheet(){ - return (XSSFSheet) getParent(); - } - - public void writeTo(OutputStream out) throws IOException { - updateHeaders(); - - TableDocument doc = TableDocument.Factory.newInstance(); - doc.setTable(ctTable); - doc.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - writeTo(out); - out.close(); - } - - /** - * get the underlying CTTable XML bean - */ - @Internal(since="POI 3.15 beta 3") - public CTTable getCTTable() { - return ctTable; - } - - /** - * Checks if this Table element contains even a single mapping to the map identified by id - * @param id the XSSFMap ID - * @return true if the Table element contain mappings - */ - public boolean mapsTo(long id){ - List pointers = getXmlColumnPrs(); - - for (XSSFXmlColumnPr pointer: pointers) { - if (pointer.getMapId()==id) { - return true; - } - } - - return false; - } - - /** - * caches table columns for performance. - * Updated via updateHeaders - * @since 3.15 beta 2 - */ - private CTTableColumn[] getTableColumns() { - if (ctColumns == null) { - ctColumns = ctTable.getTableColumns().getTableColumnArray(); - } - return ctColumns; - } - - /** - * - * Calculates the xpath of the root element for the table. This will be the common part - * of all the mapping's xpaths - * Note: this function caches the result for performance. To flush the cache {@link #updateHeaders()} must be called. - * - * @return the xpath of the table's root element - */ - public String getCommonXpath() { - if (commonXPath == null) { - String[] commonTokens = {}; - for (CTTableColumn column : getTableColumns()) { - if (column.getXmlColumnPr()!=null) { - String xpath = column.getXmlColumnPr().getXpath(); - String[] tokens = xpath.split("/"); - if (commonTokens.length==0) { - commonTokens = tokens; - - } else { - final int maxLength = Math.min(commonTokens.length, tokens.length); - - for (int i =0; i subCommonTokens = Arrays.asList(commonTokens).subList(0, i); - - String[] container = {}; - - commonTokens = subCommonTokens.toArray(container); - break; - } - } - } - } - } - - commonTokens[0] = ""; - commonXPath = StringUtil.join(commonTokens, "/"); - } - - return commonXPath; - } - - - /** - * Note this list is static - once read, it does not notice later changes to the underlying column structures - * To clear the cache, call {@link #updateHeaders} - * @return List of XSSFXmlColumnPr - */ - public List getXmlColumnPrs() { - - if (xmlColumnPr==null) { - xmlColumnPr = new ArrayList(); - for (CTTableColumn column: getTableColumns()) { - if (column.getXmlColumnPr()!=null) { - XSSFXmlColumnPr columnPr = new XSSFXmlColumnPr(this,column,column.getXmlColumnPr()); - xmlColumnPr.add(columnPr); - } - } - } - return xmlColumnPr; - } - - /** - * @return the name of the Table, if set - */ - public String getName() { - return ctTable.getName(); - } - - /** - * Changes the name of the Table - */ - public void setName(String name) { - if (name == null) { - ctTable.unsetName(); - return; - } - ctTable.setName(name); - } - - /** - * @return the display name of the Table, if set - */ - public String getDisplayName() { - return ctTable.getDisplayName(); - } - - /** - * Changes the display name of the Table - */ - public void setDisplayName(String name) { - ctTable.setDisplayName(name); - } - - /** - * @return the number of mapped table columns (see Open Office XML Part 4: chapter 3.5.1.4) - */ - public long getNumberOfMappedColumns() { - return ctTable.getTableColumns().getCount(); - } - - /** - * @return the number of mapped table columns (see Open Office XML Part 4: chapter 3.5.1.4) - * @deprecated 3.15 beta 2. Use {@link #getNumberOfMappedColumns}. - */ - public long getNumerOfMappedColumns() { - return getNumberOfMappedColumns(); - } - - - - /** - * @return The reference for the cell in the top-left part of the table - * (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref) - * - * Does not track updates to underlying changes to CTTable - * To synchronize with changes to the underlying CTTable, - * call {@link #updateReferences()}. - */ - public CellReference getStartCellReference() { - if (startCellReference==null) { - setCellReferences(); - } - return startCellReference; - } - - /** - * @return The reference for the cell in the bottom-right part of the table - * (see Open Office XML Part 4: chapter 3.5.1.2, attribute ref) - * - * Does not track updates to underlying changes to CTTable - * To synchronize with changes to the underlying CTTable, - * call {@link #updateReferences()}. - */ - public CellReference getEndCellReference() { - if (endCellReference==null) { - setCellReferences(); - } - return endCellReference; - } - - /** - * @since POI 3.15 beta 3 - */ - private void setCellReferences() { - String ref = ctTable.getRef(); - if (ref != null) { - String[] boundaries = ref.split(":", 2); - String from = boundaries[0]; - String to = boundaries[1]; - startCellReference = new CellReference(from); - endCellReference = new CellReference(to); - } - } - - - /** - * Clears the cached values set by {@link #getStartCellReference()} - * and {@link #getEndCellReference()}. - * The next call to {@link #getStartCellReference()} and - * {@link #getEndCellReference()} will synchronize the - * cell references with the underlying CTTable. - * Thus, {@link #updateReferences()} is inexpensive. - * - * @since POI 3.15 beta 3 - */ - public void updateReferences() { - startCellReference = null; - endCellReference = null; - } - - - /** - * @return the total number of rows in the selection. (Note: in this version autofiltering is ignored) - * Returns 0 if the start or end cell references are not set. - * - * Does not track updates to underlying changes to CTTable - * To synchronize with changes to the underlying CTTable, - * call {@link #updateReferences()}. - */ - public int getRowCount() { - CellReference from = getStartCellReference(); - CellReference to = getEndCellReference(); - - int rowCount = 0; - if (from!=null && to!=null) { - rowCount = to.getRow() - from.getRow() + 1; - } - return rowCount; - } - - /** - * Synchronize table headers with cell values in the parent sheet. - * Headers must be in sync, otherwise Excel will display a - * "Found unreadable content" message on startup. - * - * If calling both {@link #updateReferences()} and - * {@link #updateHeaders()}, {@link #updateReferences()} - * should be called first. - */ - public void updateHeaders() { - XSSFSheet sheet = (XSSFSheet)getParent(); - CellReference ref = getStartCellReference(); - if(ref == null) return; - - int headerRow = ref.getRow(); - int firstHeaderColumn = ref.getCol(); - XSSFRow row = sheet.getRow(headerRow); - - if (row != null && row.getCTRow().validate()) { - int cellnum = firstHeaderColumn; - for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnArray()) { - XSSFCell cell = row.getCell(cellnum); - if (cell != null) { - col.setName(cell.getStringCellValue()); - } - cellnum++; - } - ctColumns = null; - columnMap = null; - xmlColumnPr = null; - commonXPath = null; - } - } - - private static String caseInsensitive(String s) { - return s.toUpperCase(Locale.ROOT); - } - - /** - * Gets the relative column index of a column in this table having the header name column. - * The column index is relative to the left-most column in the table, 0-indexed. - * Returns -1 if column is not a header name in table. - * - * Column Header names are case-insensitive - * - * Note: this function caches column names for performance. To flush the cache (because columns - * have been moved or column headers have been changed), {@link #updateHeaders()} must be called. - * - * @since 3.15 beta 2 - */ - public int findColumnIndex(String columnHeader) { - if (columnHeader == null) return -1; - if (columnMap == null) { - // FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap - final int count = getTableColumns().length; - columnMap = new HashMap(count * 3 / 2); - - int i = 0; - for (CTTableColumn column : getTableColumns()) { - String columnName = column.getName(); - columnMap.put(caseInsensitive(columnName), i); - i++; - } - } - // Table column names with special characters need a single quote escape - // but the escape is not present in the column definition - Integer idx = columnMap.get(caseInsensitive(columnHeader.replace("'", ""))); - return idx == null ? -1 : idx.intValue(); - } - - /** - * @since 3.15 beta 2 - */ - public String getSheetName() { - return getXSSFSheet().getSheetName(); - } - - /** - * @since 3.15 beta 2 - */ - public boolean isHasTotalsRow() { - return ctTable.getTotalsRowShown(); - } - - /** - * @since 3.15 beta 2 - */ - public int getStartColIndex() { - return getStartCellReference().getCol(); - } - - /** - * @since 3.15 beta 2 - */ - public int getStartRowIndex() { - return getStartCellReference().getRow(); - } - - /** - * @since 3.15 beta 2 - */ - public int getEndColIndex() { - return getEndCellReference().getCol(); - } - - /** - * @since 3.15 beta 2 - */ - public int getEndRowIndex() { - return getEndCellReference().getRow(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java deleted file mode 100644 index 74c26b930..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Represents a text box in a SpreadsheetML drawing. - * - * @author Yegor Kozlov - */ -public final class XSSFTextBox extends XSSFSimpleShape { - - protected XSSFTextBox(XSSFDrawing drawing, CTShape ctShape) { - super(drawing, ctShape); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java deleted file mode 100644 index 6500c1603..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java +++ /dev/null @@ -1,871 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util.Internal; -import org.apache.poi.util.Units; -import org.apache.poi.xssf.usermodel.TextAlign; -import org.apache.poi.xssf.model.ParagraphPropertyFetcher; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.*; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Represents a paragraph of text within the containing text body. - * The paragraph is the highest level text separation mechanism. - */ -public class XSSFTextParagraph implements Iterable{ - private final CTTextParagraph _p; - private final CTShape _shape; - private final List _runs; - - XSSFTextParagraph(CTTextParagraph p, CTShape ctShape){ - _p = p; - _shape = ctShape; - _runs = new ArrayList(); - - for(XmlObject ch : _p.selectPath("*")){ - if(ch instanceof CTRegularTextRun){ - CTRegularTextRun r = (CTRegularTextRun)ch; - _runs.add(new XSSFTextRun(r, this)); - } else if (ch instanceof CTTextLineBreak){ - CTTextLineBreak br = (CTTextLineBreak)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(br.getRPr()); - r.setT("\n"); - _runs.add(new XSSFTextRun(r, this)); - } else if (ch instanceof CTTextField){ - CTTextField f = (CTTextField)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(f.getRPr()); - r.setT(f.getT()); - _runs.add(new XSSFTextRun(r, this)); - } - } - } - - public String getText(){ - StringBuilder out = new StringBuilder(); - for (XSSFTextRun r : _runs) { - out.append(r.getText()); - } - return out.toString(); - } - - @Internal - public CTTextParagraph getXmlObject(){ - return _p; - } - - @Internal - public CTShape getParentShape(){ - return _shape; - } - - public List getTextRuns(){ - return _runs; - } - - public Iterator iterator(){ - return _runs.iterator(); - } - - /** - * Add a new run of text - * - * @return a new run of text - */ - public XSSFTextRun addNewTextRun(){ - CTRegularTextRun r = _p.addNewR(); - CTTextCharacterProperties rPr = r.addNewRPr(); - rPr.setLang("en-US"); - XSSFTextRun run = new XSSFTextRun(r, this); - _runs.add(run); - return run; - } - - /** - * Insert a line break - * - * @return text run representing this line break ('\n') - */ - public XSSFTextRun addLineBreak(){ - CTTextLineBreak br = _p.addNewBr(); - CTTextCharacterProperties brProps = br.addNewRPr(); - if(_runs.size() > 0){ - // by default line break has the font size of the last text run - CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(); - brProps.set(prevRun); - } - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(brProps); - r.setT("\n"); - XSSFTextRun run = new XSSFLineBreak(r, this, brProps); - _runs.add(run); - return run; - } - - /** - * Returns the alignment that is applied to the paragraph. - * - * If this attribute is omitted, then a value of left is implied. - * @return alignment that is applied to the paragraph - */ - public TextAlign getTextAlign(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetAlgn()){ - TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1]; - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? TextAlign.LEFT : fetcher.getValue(); - } - - /** - * Specifies the alignment that is to be applied to the paragraph. - * Possible values for this include left, right, centered, justified and distributed, - * see {@link org.apache.poi.xssf.usermodel.TextAlign}. - * - * @param align text align - */ - public void setTextAlign(TextAlign align){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(align == null) { - if(pr.isSetAlgn()) pr.unsetAlgn(); - } else { - pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1)); - } - } - - /** - * Returns where vertically on a line of text the actual words are positioned. This deals - * with vertical placement of the characters with respect to the baselines. - * - * If this attribute is omitted, then a value of baseline is implied. - * @return alignment that is applied to the paragraph - */ - public TextFontAlign getTextFontAlign(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetFontAlgn()){ - TextFontAlign val = TextFontAlign.values()[props.getFontAlgn().intValue() - 1]; - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? TextFontAlign.BASELINE : fetcher.getValue(); - } - - /** - * Determines where vertically on a line of text the actual words are positioned. This deals - * with vertical placement of the characters with respect to the baselines. For instance - * having text anchored to the top baseline, anchored to the bottom baseline, centered in - * between, etc. - * - * @param align text font align - */ - public void setTextFontAlign(TextFontAlign align){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(align == null) { - if(pr.isSetFontAlgn()) pr.unsetFontAlgn(); - } else { - pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1)); - } - } - - /** - * @return the font to be used on bullet characters within a given paragraph - */ - public String getBulletFont(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuFont()){ - setValue(props.getBuFont().getTypeface()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public void setBulletFont(String typeface){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextFont font = pr.isSetBuFont() ? pr.getBuFont() : pr.addNewBuFont(); - font.setTypeface(typeface); - } - - /** - * @return the character to be used in place of the standard bullet point - */ - public String getBulletCharacter(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuChar()){ - setValue(props.getBuChar().getChar()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public void setBulletCharacter(String str){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextCharBullet c = pr.isSetBuChar() ? pr.getBuChar() : pr.addNewBuChar(); - c.setChar(str); - } - - /** - * - * @return the color of bullet characters within a given paragraph. - * A null value means to use the text font color. - */ - public Color getBulletFontColor(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuClr()){ - if(props.getBuClr().isSetSrgbClr()){ - CTSRgbColor clr = props.getBuClr().getSrgbClr(); - byte[] rgb = clr.getVal(); - setValue(new Color(0xFF & rgb[0], 0xFF & rgb[1], 0xFF & rgb[2])); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * Set the color to be used on bullet characters within a given paragraph. - * - * @param color the bullet color - */ - public void setBulletFontColor(Color color){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr(); - CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr(); - clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}); - } - - /** - * Returns the bullet size that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If bulletSize >= 0, then bulletSize is a percentage of the font size. - * If bulletSize < 0, then it specifies the size in points - *

        - * - * @return the bullet size - */ - public double getBulletFontSize(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuSzPct()){ - setValue(props.getBuSzPct().getVal() * 0.001); - return true; - } - if(props.isSetBuSzPts()){ - setValue( - props.getBuSzPts().getVal() * 0.01); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 100 : fetcher.getValue(); - } - - /** - * Sets the bullet size that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If bulletSize >= 0, then bulletSize is a percentage of the font size. - * If bulletSize < 0, then it specifies the size in points - *

        - */ - public void setBulletFontSize(double bulletSize){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - - if(bulletSize >= 0) { - // percentage - CTTextBulletSizePercent pt = pr.isSetBuSzPct() ? pr.getBuSzPct() : pr.addNewBuSzPct(); - pt.setVal((int)(bulletSize*1000)); - // unset points if percentage is now set - if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); - } else { - // points - CTTextBulletSizePoint pt = pr.isSetBuSzPts() ? pr.getBuSzPts() : pr.addNewBuSzPts(); - pt.setVal((int)(-bulletSize*100)); - // unset percentage if points is now set - if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); - } - } - - /** - * Specifies the indent size that will be applied to the first line of text in the paragraph. - * - * @param value the indent in points, -1 to unset indent and use the default of 0. - */ - public void setIndent(double value){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(value == -1) { - if(pr.isSetIndent()) pr.unsetIndent(); - } else { - pr.setIndent(Units.toEMU(value)); - } - } - - /** - * - * @return the indent applied to the first line of text in the paragraph. - */ - public double getIndent(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetIndent()){ - setValue(Units.toPoints(props.getIndent())); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - - - /** - * Specifies the left margin of the paragraph. This is specified in addition to the text body - * inset and applies only to this text paragraph. That is the text body inset and the LeftMargin - * attributes are additive with respect to the text position. - * - * @param value the left margin of the paragraph, -1 to clear the margin and use the default of 0. - */ - public void setLeftMargin(double value){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(value == -1) { - if(pr.isSetMarL()) pr.unsetMarL(); - } else { - pr.setMarL(Units.toEMU(value)); - } - - } - - /** - * - * @return the left margin of the paragraph - */ - public double getLeftMargin(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetMarL()){ - double val = Units.toPoints(props.getMarL()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - // if the marL attribute is omitted, then a value of 347663 is implied - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - /** - * Specifies the right margin of the paragraph. This is specified in addition to the text body - * inset and applies only to this text paragraph. That is the text body inset and the marR - * attributes are additive with respect to the text position. - * - * @param value the right margin of the paragraph, -1 to clear the margin and use the default of 0. - */ - public void setRightMargin(double value){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(value == -1) { - if(pr.isSetMarR()) pr.unsetMarR(); - } else { - pr.setMarR(Units.toEMU(value)); - } - - } - - /** - * - * @return the right margin of the paragraph - */ - public double getRightMargin(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetMarR()){ - double val = Units.toPoints(props.getMarR()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - // if the marL attribute is omitted, then a value of 347663 is implied - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - /** - * - * @return the default size for a tab character within this paragraph in points - */ - public double getDefaultTabSize(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetDefTabSz()){ - double val = Units.toPoints(props.getDefTabSz()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - public double getTabStop(final int idx){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetTabLst()){ - CTTextTabStopList tabStops = props.getTabLst(); - if(idx < tabStops.sizeOfTabArray() ) { - CTTextTabStop ts = tabStops.getTabArray(idx); - double val = Units.toPoints(ts.getPos()); - setValue(val); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 0. : fetcher.getValue(); - } - /** - * Add a single tab stop to be used on a line of text when there are one or more tab characters - * present within the text. - * - * @param value the position of the tab stop relative to the left margin - */ - public void addTabStop(double value){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst(); - tabStops.addNewTab().setPos(Units.toEMU(value)); - } - - /** - * This element specifies the vertical line spacing that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If linespacing >= 0, then linespacing is a percentage of normal line height - * If linespacing < 0, the absolute value of linespacing is the spacing in points - *

        - * Examples: - *
        
        -     *      // spacing will be 120% of the size of the largest text on each line
        -     *      paragraph.setLineSpacing(120);
        -     *
        -     *      // spacing will be 200% of the size of the largest text on each line
        -     *      paragraph.setLineSpacing(200);
        -     *
        -     *      // spacing will be 48 points
        -     *      paragraph.setLineSpacing(-48.0);
        -     * 
        - * - * @param linespacing the vertical line spacing - */ - public void setLineSpacing(double linespacing){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - if(linespacing >= 0) spc.addNewSpcPct().setVal((int)(linespacing*1000)); - else spc.addNewSpcPts().setVal((int)(-linespacing*100)); - pr.setLnSpc(spc); - } - - /** - * Returns the vertical line spacing that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If linespacing >= 0, then linespacing is a percentage of normal line height. - * If linespacing < 0, the absolute value of linespacing is the spacing in points - *

        - * - * @return the vertical line spacing. - */ - public double getLineSpacing(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetLnSpc()){ - CTTextSpacing spc = props.getLnSpc(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - double lnSpc = fetcher.getValue() == null ? 100 : fetcher.getValue(); - if(lnSpc > 0) { - // check if the percentage value is scaled - CTTextNormalAutofit normAutofit = _shape.getTxBody().getBodyPr().getNormAutofit(); - if(normAutofit != null) { - double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000; - lnSpc *= scale; - } - } - - return lnSpc; - } - - /** - * Set the amount of vertical white space that will be present before the paragraph. - * This space is specified in either percentage or points: - *

        - * If spaceBefore >= 0, then space is a percentage of normal line height. - * If spaceBefore < 0, the absolute value of linespacing is the spacing in points - *

        - * Examples: - *
        
        -     *      // The paragraph will be formatted to have a spacing before the paragraph text.
        -     *      // The spacing will be 200% of the size of the largest text on each line
        -     *      paragraph.setSpaceBefore(200);
        -     *
        -     *      // The spacing will be a size of 48 points
        -     *      paragraph.setSpaceBefore(-48.0);
        -     * 
        - * - * @param spaceBefore the vertical white space before the paragraph. - */ - public void setSpaceBefore(double spaceBefore){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000)); - else spc.addNewSpcPts().setVal((int)(-spaceBefore*100)); - pr.setSpcBef(spc); - } - - /** - * The amount of vertical white space before the paragraph - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If spaceBefore >= 0, then space is a percentage of normal line height. - * If spaceBefore < 0, the absolute value of linespacing is the spacing in points - *

        - * - * @return the vertical white space before the paragraph - */ - public double getSpaceBefore(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetSpcBef()){ - CTTextSpacing spc = props.getSpcBef(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - double spcBef = fetcher.getValue() == null ? 0 : fetcher.getValue(); - return spcBef; - } - - /** - * Set the amount of vertical white space that will be present after the paragraph. - * This space is specified in either percentage or points: - *

        - * If spaceAfter >= 0, then space is a percentage of normal line height. - * If spaceAfter < 0, the absolute value of linespacing is the spacing in points - *

        - * Examples: - *
        
        -     *      // The paragraph will be formatted to have a spacing after the paragraph text.
        -     *      // The spacing will be 200% of the size of the largest text on each line
        -     *      paragraph.setSpaceAfter(200);
        -     *
        -     *      // The spacing will be a size of 48 points
        -     *      paragraph.setSpaceAfter(-48.0);
        -     * 
        - * - * @param spaceAfter the vertical white space after the paragraph. - */ - public void setSpaceAfter(double spaceAfter){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000)); - else spc.addNewSpcPts().setVal((int)(-spaceAfter*100)); - pr.setSpcAft(spc); - } - - /** - * The amount of vertical white space after the paragraph - * This may be specified in two different ways, percentage spacing and font point spacing: - *

        - * If spaceBefore >= 0, then space is a percentage of normal line height. - * If spaceBefore < 0, the absolute value of linespacing is the spacing in points - *

        - * - * @return the vertical white space after the paragraph - */ - public double getSpaceAfter(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetSpcAft()){ - CTTextSpacing spc = props.getSpcAft(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - /** - * Specifies the particular level text properties that this paragraph will follow. - * The value for this attribute formats the text according to the corresponding level - * paragraph properties defined in the list of styles associated with the body of text - * that this paragraph belongs to (therefore in the parent shape). - *

        - * Note that the closest properties object to the text is used, therefore if there is - * a conflict between the text paragraph properties and the list style properties for - * this level then the text paragraph properties will take precedence. - *

        - * - * @param level the level (0 ... 4) - */ - public void setLevel(int level){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - - pr.setLvl(level); - } - - /** - * Returns the level of text properties that this paragraph will follow. - * - * @return the text level of this paragraph (0-based). Default is 0. - */ - public int getLevel(){ - CTTextParagraphProperties pr = _p.getPPr(); - if(pr == null) return 0; - - return pr.getLvl(); - } - - - /** - * Returns whether this paragraph has bullets - */ - public boolean isBullet() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if (props.isSetBuNone()) { - setValue(false); - return true; - } - if (props.isSetBuFont()) { - if (props.isSetBuChar() || props.isSetBuAutoNum()) { - setValue(true); - return true; - } else { - // Excel treats text with buFont but no char/autonum - // as not bulleted - // Possibly the font is just used if bullets turned on again? - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * Set or unset this paragraph as a bullet point - * - * @param flag whether text in this paragraph has bullets - */ - public void setBullet(boolean flag) { - if(isBullet() == flag) return; - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(!flag) { - pr.addNewBuNone(); - - if(pr.isSetBuAutoNum()) pr.unsetBuAutoNum(); - if(pr.isSetBuBlip()) pr.unsetBuBlip(); - if(pr.isSetBuChar()) pr.unsetBuChar(); - if(pr.isSetBuClr()) pr.unsetBuClr(); - if(pr.isSetBuClrTx()) pr.unsetBuClrTx(); - if(pr.isSetBuFont()) pr.unsetBuFont(); - if(pr.isSetBuFontTx()) pr.unsetBuFontTx(); - if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); - if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); - if(pr.isSetBuSzTx()) pr.unsetBuSzTx(); - } else { - if(pr.isSetBuNone()) pr.unsetBuNone(); - if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial"); - if(!pr.isSetBuAutoNum()) pr.addNewBuChar().setChar("\u2022"); - } - } - - /** - * Set this paragraph as an automatic numbered bullet point - * - * @param scheme type of auto-numbering - * @param startAt the number that will start number for a given sequence of automatically - * numbered bullets (1-based). - */ - public void setBullet(ListAutoNumber scheme, int startAt) { - if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); - lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1)); - lst.setStartAt(startAt); - - if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial"); - if(pr.isSetBuNone()) pr.unsetBuNone(); - // remove these elements if present as it results in invalid content when opening in Excel. - if(pr.isSetBuBlip()) pr.unsetBuBlip(); - if(pr.isSetBuChar()) pr.unsetBuChar(); - } - - /** - * Set this paragraph as an automatic numbered bullet point - * - * @param scheme type of auto-numbering - */ - public void setBullet(ListAutoNumber scheme) { - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); - lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1)); - - if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial"); - if(pr.isSetBuNone()) pr.unsetBuNone(); - // remove these elements if present as it results in invalid content when opening in Excel. - if(pr.isSetBuBlip()) pr.unsetBuBlip(); - if(pr.isSetBuChar()) pr.unsetBuChar(); - } - - /** - * Returns whether this paragraph has automatic numbered bullets - */ - public boolean isBulletAutoNumber() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuAutoNum()) { - setValue(true); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * Returns the starting number if this paragraph has automatic numbered bullets, otherwise returns 0 - */ - public int getBulletAutoNumberStart() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuAutoNum() && props.getBuAutoNum().isSetStartAt()) { - setValue(props.getBuAutoNum().getStartAt()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 0 : fetcher.getValue(); - } - - /** - * Returns the auto number scheme if this paragraph has automatic numbered bullets, otherwise returns ListAutoNumber.ARABIC_PLAIN - */ - public ListAutoNumber getBulletAutoNumberScheme() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuAutoNum()) { - setValue(ListAutoNumber.values()[props.getBuAutoNum().getType().intValue() - 1]); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - // Note: documentation does not define a default, return ListAutoNumber.ARABIC_PLAIN (1,2,3...) - return fetcher.getValue() == null ? ListAutoNumber.ARABIC_PLAIN : fetcher.getValue(); - } - - - @SuppressWarnings("rawtypes") - private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){ - boolean ok = false; - - if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr()); - - if(!ok) { - ok = visitor.fetch(_shape); - } - - return ok; - } - - @Override - public String toString(){ - return "[" + getClass() + "]" + getText(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextRun.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextRun.java deleted file mode 100644 index 5b63e94f1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextRun.java +++ /dev/null @@ -1,356 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; - -import java.awt.Color; - -/** - * Represents a run of text within the containing text body. The run element is the - * lowest level text separation mechanism within a text body. - */ -public class XSSFTextRun { - private final CTRegularTextRun _r; - private final XSSFTextParagraph _p; - - XSSFTextRun(CTRegularTextRun r, XSSFTextParagraph p){ - _r = r; - _p = p; - } - - XSSFTextParagraph getParentParagraph(){ - return _p; - } - - public String getText(){ - return _r.getT(); - } - - public void setText(String text){ - _r.setT(text); - } - - public CTRegularTextRun getXmlObject(){ - return _r; - } - - public void setFontColor(Color color){ - CTTextCharacterProperties rPr = getRPr(); - CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill(); - CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr(); - clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); - - if(fill.isSetHslClr()) fill.unsetHslClr(); - if(fill.isSetPrstClr()) fill.unsetPrstClr(); - if(fill.isSetSchemeClr()) fill.unsetSchemeClr(); - if(fill.isSetScrgbClr()) fill.unsetScrgbClr(); - if(fill.isSetSysClr()) fill.unsetSysClr(); - - } - - public Color getFontColor(){ - - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetSolidFill()){ - CTSolidColorFillProperties fill = rPr.getSolidFill(); - - if(fill.isSetSrgbClr()){ - CTSRgbColor clr = fill.getSrgbClr(); - byte[] rgb = clr.getVal(); - return new Color(0xFF & rgb[0], 0xFF & rgb[1], 0xFF & rgb[2]); - } - } - - return new Color(0, 0, 0); - } - - /** - * - * @param fontSize font size in points. - * The value of -1 unsets the Sz attribute from the underlying xml bean - */ - public void setFontSize(double fontSize){ - CTTextCharacterProperties rPr = getRPr(); - if(fontSize == -1.0) { - if(rPr.isSetSz()) rPr.unsetSz(); - } else { - if(fontSize < 1.0) { - throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize); - } - - rPr.setSz((int)(100*fontSize)); - } - } - - /** - * @return font size in points or -1 if font size is not set. - */ - public double getFontSize(){ - double scale = 1; - double size = XSSFFont.DEFAULT_FONT_SIZE; // default font size - CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTxBody().getBodyPr().getNormAutofit(); - if(afit != null) scale = (double)afit.getFontScale() / 100000; - - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetSz()){ - size = rPr.getSz()*0.01; - } - - return size * scale; - } - - /** - * - * @return the spacing between characters within a text run, - * If this attribute is omitted then a value of 0 or no adjustment is assumed. - */ - public double getCharacterSpacing(){ - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetSpc()){ - return rPr.getSpc()*0.01; - } - return 0; - } - - /** - * Set the spacing between characters within a text run. - *

        - * The spacing is specified in points. Positive values will cause the text to expand, - * negative values to condense. - *

        - * - * @param spc character spacing in points. - */ - public void setCharacterSpacing(double spc){ - CTTextCharacterProperties rPr = getRPr(); - if(spc == 0.0) { - if(rPr.isSetSpc()) rPr.unsetSpc(); - } else { - rPr.setSpc((int)(100*spc)); - } - } - - /** - * Specifies the typeface, or name of the font that is to be used for this text run. - * - * @param typeface the font to apply to this text run. - * The value of null unsets the Typeface attribute from the underlying xml. - */ - public void setFont(String typeface){ - setFontFamily(typeface, (byte)-1, (byte)-1, false); - } - - public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){ - CTTextCharacterProperties rPr = getRPr(); - - if(typeface == null){ - if(rPr.isSetLatin()) rPr.unsetLatin(); - if(rPr.isSetCs()) rPr.unsetCs(); - if(rPr.isSetSym()) rPr.unsetSym(); - } else { - if(isSymbol){ - CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym(); - font.setTypeface(typeface); - } else { - CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin(); - latin.setTypeface(typeface); - if(charset != -1) latin.setCharset(charset); - if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily); - } - } - } - - /** - * @return font family or null if not set - */ - public String getFontFamily(){ - CTTextCharacterProperties rPr = getRPr(); - CTTextFont font = rPr.getLatin(); - if(font != null){ - return font.getTypeface(); - } - return XSSFFont.DEFAULT_FONT_NAME; - } - - public byte getPitchAndFamily(){ - CTTextCharacterProperties rPr = getRPr(); - CTTextFont font = rPr.getLatin(); - if(font != null){ - return font.getPitchFamily(); - } - return 0; - } - - /** - * Specifies whether a run of text will be formatted as strikethrough text. - * - * @param strike whether a run of text will be formatted as strikethrough text. - */ - public void setStrikethrough(boolean strike) { - getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE); - } - - /** - * @return whether a run of text will be formatted as strikethrough text. Default is false. - */ - public boolean isStrikethrough() { - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetStrike()){ - return rPr.getStrike() != STTextStrikeType.NO_STRIKE; - } - return false; - } - - /** - * @return whether a run of text will be formatted as a superscript text. Default is false. - */ - public boolean isSuperscript() { - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetBaseline()){ - return rPr.getBaseline() > 0; - } - return false; - } - - /** - * Set the baseline for both the superscript and subscript fonts. - *

        - * The size is specified using a percentage. - * Positive values indicate superscript, negative values indicate subscript. - *

        - * - * @param baselineOffset - */ - public void setBaselineOffset(double baselineOffset){ - getRPr().setBaseline((int) baselineOffset * 1000); - } - - /** - * Set whether the text in this run is formatted as superscript. - * Default base line offset is 30% - * - * @see #setBaselineOffset(double) - */ - public void setSuperscript(boolean flag){ - setBaselineOffset(flag ? 30. : 0.); - } - - /** - * Set whether the text in this run is formatted as subscript. - * Default base line offset is -25%. - * - * @see #setBaselineOffset(double) - */ - public void setSubscript(boolean flag){ - setBaselineOffset(flag ? -25.0 : 0.); - } - - /** - * @return whether a run of text will be formatted as a superscript text. Default is false. - */ - public boolean isSubscript() { - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetBaseline()){ - return rPr.getBaseline() < 0; - } - return false; - } - - /** - * @return whether a run of text will be formatted as a superscript text. Default is false. - */ - public TextCap getTextCap() { - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetCap()){ - return TextCap.values()[rPr.getCap().intValue() - 1]; - } - return TextCap.NONE; - } - - /** - * Specifies whether this run of text will be formatted as bold text - * - * @param bold whether this run of text will be formatted as bold text - */ - public void setBold(boolean bold){ - getRPr().setB(bold); - } - - /** - * @return whether this run of text is formatted as bold text - */ - public boolean isBold(){ - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetB()){ - return rPr.getB(); - } - return false; - } - - /** - * @param italic whether this run of text is formatted as italic text - */ - public void setItalic(boolean italic){ - getRPr().setI(italic); - } - - /** - * @return whether this run of text is formatted as italic text - */ - public boolean isItalic(){ - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetI()){ - return rPr.getI(); - } - return false; - } - - /** - * @param underline whether this run of text is formatted as underlined text - */ - public void setUnderline(boolean underline) { - getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE); - } - - /** - * @return whether this run of text is formatted as underlined text - */ - public boolean isUnderline(){ - CTTextCharacterProperties rPr = getRPr(); - if(rPr.isSetU()){ - return rPr.getU() != STTextUnderlineType.NONE; - } - return false; - } - - protected CTTextCharacterProperties getRPr(){ - return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr(); - } - - @Override - public String toString(){ - return "[" + getClass() + "]" + getText(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java deleted file mode 100644 index 11501e961..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; - -public class XSSFVBAPart extends POIXMLDocumentPart { - - /** - * Create a new XSSFVBAPart node - */ - protected XSSFVBAPart() { - super(); - } - - /** - * Construct XSSFVBAPart from a package part - * - * @param part the package part holding the VBA data, - * - * @since POI 3.14-Beta1 - */ - protected XSSFVBAPart(PackagePart part) { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFVBAPart(PackagePart part, PackageRelationship rel) { - this(part); - } - - /** - * Like *PictureData, VBA objects store the actual content in the part - * directly without keeping a copy like all others therefore we need to - * handle them differently. - */ - protected void prepareForCommit() { - // do not clear the part here - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java deleted file mode 100644 index 434742dd0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java +++ /dev/null @@ -1,292 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringReader; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.xssf.util.EvilUnclosedBRFixingInputStream; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import com.microsoft.schemas.office.excel.CTClientData; -import com.microsoft.schemas.office.excel.STObjectType; -import com.microsoft.schemas.office.office.CTIdMap; -import com.microsoft.schemas.office.office.CTShapeLayout; -import com.microsoft.schemas.office.office.STConnectType; -import com.microsoft.schemas.office.office.STInsetMode; -import com.microsoft.schemas.vml.CTPath; -import com.microsoft.schemas.vml.CTShadow; -import com.microsoft.schemas.vml.CTShape; -import com.microsoft.schemas.vml.CTShapetype; -import com.microsoft.schemas.vml.STExt; -import com.microsoft.schemas.vml.STStrokeJoinStyle; -import com.microsoft.schemas.vml.STTrueFalse; - -/** - * Represents a SpreadsheetML VML drawing. - * - *

        - * In Excel 2007 VML drawings are used to describe properties of cell comments, - * although the spec says that VML is deprecated: - *

        - *

        - * The VML format is a legacy format originally introduced with Office 2000 and is included and fully defined - * in this Standard for backwards compatibility reasons. The DrawingML format is a newer and richer format - * created with the goal of eventually replacing any uses of VML in the Office Open XML formats. VML should be - * considered a deprecated format included in Office Open XML for legacy reasons only and new applications that - * need a file format for drawings are strongly encouraged to use preferentially DrawingML - *

        - * - *

        - * Warning - Excel is known to put invalid XML into these files! - * For example, >br< without being closed or escaped crops up. - *

        - * - * See 6.4 VML - SpreadsheetML Drawing in Office Open XML Part 4 - Markup Language Reference.pdf - * - * @author Yegor Kozlov - */ -public final class XSSFVMLDrawing extends POIXMLDocumentPart { - private static final QName QNAME_SHAPE_LAYOUT = new QName("urn:schemas-microsoft-com:office:office", "shapelayout"); - private static final QName QNAME_SHAPE_TYPE = new QName("urn:schemas-microsoft-com:vml", "shapetype"); - private static final QName QNAME_SHAPE = new QName("urn:schemas-microsoft-com:vml", "shape"); - private static final String COMMENT_SHAPE_TYPE_ID = "_x0000_t202"; // this ID value seems to have significance to Excel >= 2010; see https://issues.apache.org/bugzilla/show_bug.cgi?id=55409 - - /** - * regexp to parse shape ids, in VML they have weird form of id="_x0000_s1026" - */ - private static final Pattern ptrn_shapeId = Pattern.compile("_x0000_s(\\d+)"); - - private List _qnames = new ArrayList(); - private List _items = new ArrayList(); - private String _shapeTypeId; - private int _shapeId = 1024; - - /** - * Create a new SpreadsheetML drawing - * - * @see XSSFSheet#createDrawingPatriarch() - */ - protected XSSFVMLDrawing() { - super(); - newDrawing(); - } - - /** - * Construct a SpreadsheetML drawing from a package part - * - * @param part the package part holding the drawing data, - * the content type must be application/vnd.openxmlformats-officedocument.drawing+xml - * - * @since POI 3.14-Beta1 - */ - protected XSSFVMLDrawing(PackagePart part) throws IOException, XmlException { - super(part); - read(getPackagePart().getInputStream()); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - protected XSSFVMLDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - this(part); - } - - @SuppressWarnings("resource") - protected void read(InputStream is) throws IOException, XmlException { - Document doc; - try { - doc = DocumentHelper.readDocument(new EvilUnclosedBRFixingInputStream(is)); - } catch (SAXException e) { - throw new XmlException(e.getMessage(), e); - } - XmlObject root = XmlObject.Factory.parse(doc, DEFAULT_XML_OPTIONS); - - _qnames = new ArrayList(); - _items = new ArrayList(); - for(XmlObject obj : root.selectPath("$this/xml/*")) { - Node nd = obj.getDomNode(); - QName qname = new QName(nd.getNamespaceURI(), nd.getLocalName()); - if (qname.equals(QNAME_SHAPE_LAYOUT)) { - _items.add(CTShapeLayout.Factory.parse(obj.xmlText(), DEFAULT_XML_OPTIONS)); - } else if (qname.equals(QNAME_SHAPE_TYPE)) { - CTShapetype st = CTShapetype.Factory.parse(obj.xmlText(), DEFAULT_XML_OPTIONS); - _items.add(st); - _shapeTypeId = st.getId(); - } else if (qname.equals(QNAME_SHAPE)) { - CTShape shape = CTShape.Factory.parse(obj.xmlText(), DEFAULT_XML_OPTIONS); - String id = shape.getId(); - if(id != null) { - Matcher m = ptrn_shapeId.matcher(id); - if(m.find()) _shapeId = Math.max(_shapeId, Integer.parseInt(m.group(1))); - } - _items.add(shape); - } else { - Document doc2; - try { - InputSource is2 = new InputSource(new StringReader(obj.xmlText())); - doc2 = DocumentHelper.readDocument(is2); - } catch (SAXException e) { - throw new XmlException(e.getMessage(), e); - } - - _items.add(XmlObject.Factory.parse(doc2, DEFAULT_XML_OPTIONS)); - } - _qnames.add(qname); - } - } - - protected List getItems(){ - return _items; - } - - protected void write(OutputStream out) throws IOException { - XmlObject rootObject = XmlObject.Factory.newInstance(); - XmlCursor rootCursor = rootObject.newCursor(); - rootCursor.toNextToken(); - rootCursor.beginElement("xml"); - - for(int i=0; i < _items.size(); i++){ - XmlCursor xc = _items.get(i).newCursor(); - rootCursor.beginElement(_qnames.get(i)); - while(xc.toNextToken() == XmlCursor.TokenType.ATTR) { - Node anode = xc.getDomNode(); - rootCursor.insertAttributeWithValue(anode.getLocalName(), anode.getNamespaceURI(), anode.getNodeValue()); - } - xc.toStartDoc(); - xc.copyXmlContents(rootCursor); - rootCursor.toNextToken(); - xc.dispose(); - } - rootCursor.dispose(); - - rootObject.save(out, DEFAULT_XML_OPTIONS); - } - - @Override - protected void commit() throws IOException { - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - write(out); - out.close(); - } - - /** - * Initialize a new Speadsheet VML drawing - */ - private void newDrawing(){ - CTShapeLayout layout = CTShapeLayout.Factory.newInstance(); - layout.setExt(STExt.EDIT); - CTIdMap idmap = layout.addNewIdmap(); - idmap.setExt(STExt.EDIT); - idmap.setData("1"); - _items.add(layout); - _qnames.add(QNAME_SHAPE_LAYOUT); - - CTShapetype shapetype = CTShapetype.Factory.newInstance(); - _shapeTypeId = COMMENT_SHAPE_TYPE_ID; - shapetype.setId(_shapeTypeId); - shapetype.setCoordsize("21600,21600"); - shapetype.setSpt(202); - shapetype.setPath2("m,l,21600r21600,l21600,xe"); - shapetype.addNewStroke().setJoinstyle(STStrokeJoinStyle.MITER); - CTPath path = shapetype.addNewPath(); - path.setGradientshapeok(STTrueFalse.T); - path.setConnecttype(STConnectType.RECT); - _items.add(shapetype); - _qnames.add(QNAME_SHAPE_TYPE); - } - - protected CTShape newCommentShape(){ - CTShape shape = CTShape.Factory.newInstance(); - shape.setId("_x0000_s" + (++_shapeId)); - shape.setType("#" + _shapeTypeId); - shape.setStyle("position:absolute; visibility:hidden"); - shape.setFillcolor("#ffffe1"); - shape.setInsetmode(STInsetMode.AUTO); - shape.addNewFill().setColor("#ffffe1"); - CTShadow shadow = shape.addNewShadow(); - shadow.setOn(STTrueFalse.T); - shadow.setColor("black"); - shadow.setObscured(STTrueFalse.T); - shape.addNewPath().setConnecttype(STConnectType.NONE); - shape.addNewTextbox().setStyle("mso-direction-alt:auto"); - CTClientData cldata = shape.addNewClientData(); - cldata.setObjectType(STObjectType.NOTE); - cldata.addNewMoveWithCells(); - cldata.addNewSizeWithCells(); - cldata.addNewAnchor().setStringValue("1, 15, 0, 2, 3, 15, 3, 16"); - cldata.addNewAutoFill().setStringValue("False"); - cldata.addNewRow().setBigIntegerValue(new BigInteger("0")); - cldata.addNewColumn().setBigIntegerValue(new BigInteger("0")); - _items.add(shape); - _qnames.add(QNAME_SHAPE); - return shape; - } - - /** - * Find a shape with ClientData of type "NOTE" and the specified row and column - * - * @return the comment shape or null - */ - protected CTShape findCommentShape(int row, int col){ - for(XmlObject itm : _items){ - if(itm instanceof CTShape){ - CTShape sh = (CTShape)itm; - if(sh.sizeOfClientDataArray() > 0){ - CTClientData cldata = sh.getClientDataArray(0); - if(cldata.getObjectType() == STObjectType.NOTE){ - int crow = cldata.getRowArray(0).intValue(); - int ccol = cldata.getColumnArray(0).intValue(); - if(crow == row && ccol == col) { - return sh; - } - } - } - } - } - return null; - } - - protected boolean removeCommentShape(int row, int col){ - CTShape shape = findCommentShape(row, col); - return shape != null && _items.remove(shape); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java deleted file mode 100644 index 019b145e9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ /dev/null @@ -1,2407 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.setPassword; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.validatePassword; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.regex.Pattern; - -import javax.xml.namespace.QName; - -import org.apache.commons.collections4.ListValuedMap; -import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; -import org.apache.poi.POIXMLDocument; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.POIXMLProperties; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.formula.SheetNameFormatter; -import org.apache.poi.ss.formula.udf.AggregatingUDFFinder; -import org.apache.poi.ss.formula.udf.IndexedUDFFinder; -import org.apache.poi.ss.formula.udf.UDFFinder; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.WorkbookUtil; -import org.apache.poi.util.Beta; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.PackageHelper; -import org.apache.poi.xssf.XLSBUnsupportedException; -import org.apache.poi.xssf.model.CalculationChain; -import org.apache.poi.xssf.model.ExternalLinksTable; -import org.apache.poi.xssf.model.MapInfo; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.model.ThemesTable; -import org.apache.poi.xssf.usermodel.helpers.XSSFFormulaUtils; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookView; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookViews; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalReference; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCache; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCaches; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheets; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookProtection; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; - -/** - * High level representation of a SpreadsheetML workbook. This is the first object most users - * will construct whether they are reading or writing a workbook. It is also the - * top level object for creating new sheets/etc. - */ -public class XSSFWorkbook extends POIXMLDocument implements Workbook { - private static final Pattern COMMA_PATTERN = Pattern.compile(","); - - /** - * Width of one character of the default font in pixels. Same for Calibry and Arial. - */ - public static final float DEFAULT_CHARACTER_WIDTH = 7.0017f; - - /** - * Excel silently truncates long sheet names to 31 chars. - * This constant is used to ensure uniqueness in the first 31 chars - */ - private static final int MAX_SENSITIVE_SHEET_NAME_LEN = 31; - - /** - * Images formats supported by XSSF but not by HSSF - */ - public static final int PICTURE_TYPE_GIF = 8; - public static final int PICTURE_TYPE_TIFF = 9; - public static final int PICTURE_TYPE_EPS = 10; - public static final int PICTURE_TYPE_BMP = 11; - public static final int PICTURE_TYPE_WPG = 12; - - /** - * The underlying XML bean - */ - private CTWorkbook workbook; - - /** - * this holds the XSSFSheet objects attached to this workbook - */ - private List sheets; - - /** - * this holds the XSSFName objects attached to this workbook, keyed by lower-case name - */ - private ListValuedMap namedRangesByName; - - /** - * this holds the XSSFName objects attached to this workbook - */ - private List namedRanges; - - /** - * shared string table - a cache of strings in this workbook - */ - private SharedStringsTable sharedStringSource; - - /** - * A collection of shared objects used for styling content, - * e.g. fonts, cell styles, colors, etc. - */ - private StylesTable stylesSource; - - /** - * The locator of user-defined functions. - * By default includes functions from the Excel Analysis Toolpack - */ - private IndexedUDFFinder _udfFinder = new IndexedUDFFinder(AggregatingUDFFinder.DEFAULT); - - /** - * TODO - */ - private CalculationChain calcChain; - - /** - * External Links, for referencing names or cells in other workbooks. - */ - private List externalLinks; - - /** - * A collection of custom XML mappings - */ - private MapInfo mapInfo; - - /** - * Used to keep track of the data formatter so that all - * createDataFormatter calls return the same one for a given - * book. This ensures that updates from one places is visible - * someplace else. - */ - private XSSFDataFormat formatter; - - /** - * The policy to apply in the event of missing or - * blank cells when fetching from a row. - * See {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} - */ - private MissingCellPolicy _missingCellPolicy = MissingCellPolicy.RETURN_NULL_AND_BLANK; - - /** - * array of pictures for this workbook - */ - private List pictures; - - private static POILogger logger = POILogFactory.getLogger(XSSFWorkbook.class); - - /** - * cached instance of XSSFCreationHelper for this workbook - * @see {@link #getCreationHelper()} - */ - private XSSFCreationHelper _creationHelper; - - /** - * List of all pivot tables in workbook - */ - private List pivotTables; - private List pivotCaches; - - - /** - * Create a new SpreadsheetML workbook. - */ - public XSSFWorkbook() { - this(XSSFWorkbookType.XLSX); - } - - /** - * Create a new SpreadsheetML workbook. - * @param workbookType The type of workbook to make (.xlsx or .xlsm). - */ - public XSSFWorkbook(XSSFWorkbookType workbookType) { - super(newPackage(workbookType)); - onWorkbookCreate(); - } - - /** - * Constructs a XSSFWorkbook object given a OpenXML4J Package object, - * see http://poi.apache.org/oxml4j/. - * - *

        Once you have finished working with the Workbook, you should close the package - * by calling either {@link #close()} or {@link OPCPackage#close()}, to avoid - * leaving file handles open. - * - *

        Creating a XSSFWorkbook from a file-backed OPC Package has a lower memory - * footprint than an InputStream backed one. - * - * @param pkg the OpenXML4J OPC Package object. - */ - public XSSFWorkbook(OPCPackage pkg) throws IOException { - super(pkg); - - beforeDocumentRead(); - - // Build a tree of POIXMLDocumentParts, this workbook being the root - load(XSSFFactory.getInstance()); - - // some broken Workbooks miss this... - if(!workbook.isSetBookViews()) { - CTBookViews bvs = workbook.addNewBookViews(); - CTBookView bv = bvs.addNewWorkbookView(); - bv.setActiveTab(0); - } - } - - /** - * Constructs a XSSFWorkbook object, by buffering the whole stream into memory - * and then opening an {@link OPCPackage} object for it. - * - *

        Using an {@link InputStream} requires more memory than using a File, so - * if a {@link File} is available then you should instead do something like - *

        
        -     *       OPCPackage pkg = OPCPackage.open(path);
        -     *       XSSFWorkbook wb = new XSSFWorkbook(pkg);
        -     *       // work with the wb object
        -     *       ......
        -     *       pkg.close(); // gracefully closes the underlying zip file
        -     *   
        - */ - public XSSFWorkbook(InputStream is) throws IOException { - super(PackageHelper.open(is)); - - beforeDocumentRead(); - - // Build a tree of POIXMLDocumentParts, this workbook being the root - load(XSSFFactory.getInstance()); - - // some broken Workbooks miss this... - if(!workbook.isSetBookViews()) { - CTBookViews bvs = workbook.addNewBookViews(); - CTBookView bv = bvs.addNewWorkbookView(); - bv.setActiveTab(0); - } - } - - /** - * Constructs a XSSFWorkbook object from a given file. - * - *

        Once you have finished working with the Workbook, you should close - * the package by calling {@link #close()}, to avoid leaving file - * handles open. - * - *

        Opening a XSSFWorkbook from a file has a lower memory footprint - * than opening from an InputStream - * - * @param file the file to open - */ - public XSSFWorkbook(File file) throws IOException, InvalidFormatException { - this(OPCPackage.open(file)); - } - - /** - * Constructs a XSSFWorkbook object given a file name. - * - * - *

        Once you have finished working with the Workbook, you should close - * the package by calling {@link #close()}, to avoid leaving file - * handles open. - * - *

        Opening a XSSFWorkbook from a file has a lower memory footprint - * than opening from an InputStream - * - * @param path the file name. - */ - public XSSFWorkbook(String path) throws IOException { - this(openPackage(path)); - } - - protected void beforeDocumentRead() { - // Ensure it isn't a XLSB file, which we don't support - if (getCorePart().getContentType().equals(XSSFRelation.XLSB_BINARY_WORKBOOK.getContentType())) { - throw new XLSBUnsupportedException(); - } - - // Create arrays for parts attached to the workbook itself - pivotTables = new ArrayList(); - pivotCaches = new ArrayList(); - } - - @Override - protected void onDocumentRead() throws IOException { - try { - WorkbookDocument doc = WorkbookDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - this.workbook = doc.getWorkbook(); - - ThemesTable theme = null; - Map shIdMap = new HashMap(); - Map elIdMap = new HashMap(); - for(RelationPart rp : getRelationParts()){ - POIXMLDocumentPart p = rp.getDocumentPart(); - if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p; - else if(p instanceof StylesTable) stylesSource = (StylesTable)p; - else if(p instanceof ThemesTable) theme = (ThemesTable)p; - else if(p instanceof CalculationChain) calcChain = (CalculationChain)p; - else if(p instanceof MapInfo) mapInfo = (MapInfo)p; - else if (p instanceof XSSFSheet) { - shIdMap.put(rp.getRelationship().getId(), (XSSFSheet)p); - } - else if (p instanceof ExternalLinksTable) { - elIdMap.put(rp.getRelationship().getId(), (ExternalLinksTable)p); - } - } - boolean packageReadOnly = (getPackage().getPackageAccess() == PackageAccess.READ); - - if (stylesSource == null) { - // Create Styles if it is missing - if (packageReadOnly) { - stylesSource = new StylesTable(); - } else { - stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance()); - } - } - stylesSource.setWorkbook(this); - stylesSource.setTheme(theme); - - if (sharedStringSource == null) { - // Create SST if it is missing - if (packageReadOnly) { - sharedStringSource = new SharedStringsTable(); - } else { - sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance()); - } - } - - // Load individual sheets. The order of sheets is defined by the order - // of CTSheet elements in the workbook - sheets = new ArrayList(shIdMap.size()); - for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) { - parseSheet(shIdMap, ctSheet); - } - - // Load the external links tables. Their order is defined by the order - // of CTExternalReference elements in the workbook - externalLinks = new ArrayList(elIdMap.size()); - if (this.workbook.isSetExternalReferences()) { - for (CTExternalReference er : this.workbook.getExternalReferences().getExternalReferenceArray()) { - ExternalLinksTable el = elIdMap.get(er.getId()); - if(el == null) { - logger.log(POILogger.WARN, "ExternalLinksTable with r:id " + er.getId()+ " was defined, but didn't exist in package, skipping"); - continue; - } - externalLinks.add(el); - } - } - - // Process the named ranges - reprocessNamedRanges(); - } catch (XmlException e) { - throw new POIXMLException(e); - } - } - - /** - * Not normally to be called externally, but possibly to be overridden to avoid - * the DOM based parse of large sheets (see examples). - */ - public void parseSheet(Map shIdMap, CTSheet ctSheet) { - XSSFSheet sh = shIdMap.get(ctSheet.getId()); - if(sh == null) { - logger.log(POILogger.WARN, "Sheet with name " + ctSheet.getName() + " and r:id " + ctSheet.getId()+ " was defined, but didn't exist in package, skipping"); - return; - } - sh.sheet = ctSheet; - sh.onDocumentRead(); - sheets.add(sh); - } - - /** - * Create a new CTWorkbook with all values set to default - */ - private void onWorkbookCreate() { - workbook = CTWorkbook.Factory.newInstance(); - - // don't EVER use the 1904 date system - CTWorkbookPr workbookPr = workbook.addNewWorkbookPr(); - workbookPr.setDate1904(false); - - CTBookViews bvs = workbook.addNewBookViews(); - CTBookView bv = bvs.addNewWorkbookView(); - bv.setActiveTab(0); - workbook.addNewSheets(); - - POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties(); - expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR); - - sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance()); - stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance()); - stylesSource.setWorkbook(this); - - namedRanges = new ArrayList(); - namedRangesByName = new ArrayListValuedHashMap(); - sheets = new ArrayList(); - pivotTables = new ArrayList(); - } - - /** - * Create a new SpreadsheetML package and setup the default minimal content - */ - protected static OPCPackage newPackage(XSSFWorkbookType workbookType) { - try { - OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream()); - // Main part - PackagePartName corePartName = PackagingURIHelper.createPartName(XSSFRelation.WORKBOOK.getDefaultFileName()); - // Create main part relationship - pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT); - // Create main document part - pkg.createPart(corePartName, workbookType.getContentType()); - - pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR); - - return pkg; - } catch (Exception e){ - throw new POIXMLException(e); - } - } - - /** - * Return the underlying XML bean - * - * @return the underlying CTWorkbook bean - */ - @Internal - public CTWorkbook getCTWorkbook() { - return this.workbook; - } - - /** - * Adds a picture to the workbook. - * - * @param pictureData The bytes of the picture - * @param format The format of the picture. - * - * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . - * @see Workbook#PICTURE_TYPE_EMF - * @see Workbook#PICTURE_TYPE_WMF - * @see Workbook#PICTURE_TYPE_PICT - * @see Workbook#PICTURE_TYPE_JPEG - * @see Workbook#PICTURE_TYPE_PNG - * @see Workbook#PICTURE_TYPE_DIB - * @see #getAllPictures() - */ - @Override - public int addPicture(byte[] pictureData, int format) { - int imageNumber = getAllPictures().size() + 1; - XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true).getDocumentPart(); - try { - OutputStream out = img.getPackagePart().getOutputStream(); - out.write(pictureData); - out.close(); - } catch (IOException e){ - throw new POIXMLException(e); - } - pictures.add(img); - return imageNumber - 1; - } - - /** - * Adds a picture to the workbook. - * - * @param is The sream to read image from - * @param format The format of the picture. - * - * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . - * @see Workbook#PICTURE_TYPE_EMF - * @see Workbook#PICTURE_TYPE_WMF - * @see Workbook#PICTURE_TYPE_PICT - * @see Workbook#PICTURE_TYPE_JPEG - * @see Workbook#PICTURE_TYPE_PNG - * @see Workbook#PICTURE_TYPE_DIB - * @see #getAllPictures() - */ - public int addPicture(InputStream is, int format) throws IOException { - int imageNumber = getAllPictures().size() + 1; - XSSFPictureData img = createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true).getDocumentPart(); - OutputStream out = img.getPackagePart().getOutputStream(); - IOUtils.copy(is, out); - out.close(); - pictures.add(img); - return imageNumber - 1; - } - - /** - * Create an XSSFSheet from an existing sheet in the XSSFWorkbook. - * The cloned sheet is a deep copy of the original. - * - * @param sheetNum The index of the sheet to clone - * @return XSSFSheet representing the cloned sheet. - * @throws IllegalArgumentException if the sheet index in invalid - * @throws POIXMLException if there were errors when cloning - */ - @Override - public XSSFSheet cloneSheet(int sheetNum) { - return cloneSheet(sheetNum, null); - } - - /** - * Create an XSSFSheet from an existing sheet in the XSSFWorkbook. - * The cloned sheet is a deep copy of the original but with a new given - * name. - * - * @param sheetNum The index of the sheet to clone - * @param newName The name to set for the newly created sheet - * @return XSSFSheet representing the cloned sheet. - * @throws IllegalArgumentException if the sheet index or the sheet - * name is invalid - * @throws POIXMLException if there were errors when cloning - */ - public XSSFSheet cloneSheet(int sheetNum, String newName) { - validateSheetIndex(sheetNum); - XSSFSheet srcSheet = sheets.get(sheetNum); - - if (newName == null) { - String srcName = srcSheet.getSheetName(); - newName = getUniqueSheetName(srcName); - } else { - validateSheetName(newName); - } - - XSSFSheet clonedSheet = createSheet(newName); - - // copy sheet's relations - List rels = srcSheet.getRelationParts(); - // if the sheet being cloned has a drawing then rememebr it and re-create it too - XSSFDrawing dg = null; - for(RelationPart rp : rels) { - POIXMLDocumentPart r = rp.getDocumentPart(); - // do not copy the drawing relationship, it will be re-created - if(r instanceof XSSFDrawing) { - dg = (XSSFDrawing)r; - continue; - } - - addRelation(rp, clonedSheet); - } - - try { - for(PackageRelationship pr : srcSheet.getPackagePart().getRelationships()) { - if (pr.getTargetMode() == TargetMode.EXTERNAL) { - clonedSheet.getPackagePart().addExternalRelationship - (pr.getTargetURI().toASCIIString(), pr.getRelationshipType(), pr.getId()); - } - } - } catch (InvalidFormatException e) { - throw new POIXMLException("Failed to clone sheet", e); - } - - - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - srcSheet.write(out); - clonedSheet.read(new ByteArrayInputStream(out.toByteArray())); - } catch (IOException e){ - throw new POIXMLException("Failed to clone sheet", e); - } - CTWorksheet ct = clonedSheet.getCTWorksheet(); - if(ct.isSetLegacyDrawing()) { - logger.log(POILogger.WARN, "Cloning sheets with comments is not yet supported."); - ct.unsetLegacyDrawing(); - } - if (ct.isSetPageSetup()) { - logger.log(POILogger.WARN, "Cloning sheets with page setup is not yet supported."); - ct.unsetPageSetup(); - } - - clonedSheet.setSelected(false); - - // clone the sheet drawing alongs with its relationships - if (dg != null) { - if(ct.isSetDrawing()) { - // unset the existing reference to the drawing, - // so that subsequent call of clonedSheet.createDrawingPatriarch() will create a new one - ct.unsetDrawing(); - } - XSSFDrawing clonedDg = clonedSheet.createDrawingPatriarch(); - // copy drawing contents - clonedDg.getCTDrawing().set(dg.getCTDrawing()); - - clonedDg = clonedSheet.createDrawingPatriarch(); - - // Clone drawing relations - List srcRels = srcSheet.createDrawingPatriarch().getRelationParts(); - for (RelationPart rp : srcRels) { - addRelation(rp, clonedDg); - } - } - return clonedSheet; - } - - /** - * @since 3.14-Beta1 - */ - private static void addRelation(RelationPart rp, POIXMLDocumentPart target) { - PackageRelationship rel = rp.getRelationship(); - if (rel.getTargetMode() == TargetMode.EXTERNAL) { - target.getPackagePart().addRelationship( - rel.getTargetURI(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); - } else { - XSSFRelation xssfRel = XSSFRelation.getInstance(rel.getRelationshipType()); - if (xssfRel == null) { - // Don't copy all relations blindly, but only the ones we know about - throw new POIXMLException("Can't clone sheet - unknown relation type found: "+rel.getRelationshipType()); - } - target.addRelation(rel.getId(), xssfRel, rp.getDocumentPart()); - } - } - - /** - * Generate a valid sheet name based on the existing one. Used when cloning sheets. - * - * @param srcName the original sheet name to - * @return clone sheet name - */ - private String getUniqueSheetName(String srcName) { - int uniqueIndex = 2; - String baseName = srcName; - int bracketPos = srcName.lastIndexOf('('); - if (bracketPos > 0 && srcName.endsWith(")")) { - String suffix = srcName.substring(bracketPos + 1, srcName.length() - ")".length()); - try { - uniqueIndex = Integer.parseInt(suffix.trim()); - uniqueIndex++; - baseName = srcName.substring(0, bracketPos).trim(); - } catch (NumberFormatException e) { - // contents of brackets not numeric - } - } - while (true) { - // Try and find the next sheet name that is unique - String index = Integer.toString(uniqueIndex++); - String name; - if (baseName.length() + index.length() + 2 < 31) { - name = baseName + " (" + index + ")"; - } else { - name = baseName.substring(0, 31 - index.length() - 2) + "(" + index + ")"; - } - - //If the sheet name is unique, then set it otherwise move on to the next number. - if (getSheetIndex(name) == -1) { - return name; - } - } - } - - /** - * Create a new XSSFCellStyle and add it to the workbook's style table - * - * @return the new XSSFCellStyle object - */ - @Override - public XSSFCellStyle createCellStyle() { - return stylesSource.createCellStyle(); - } - - /** - * Returns the workbook's data format table (a factory for creating data format strings). - * - * @return the XSSFDataFormat object - * @see org.apache.poi.ss.usermodel.DataFormat - */ - @Override - public XSSFDataFormat createDataFormat() { - if (formatter == null) - formatter = new XSSFDataFormat(stylesSource); - return formatter; - } - - /** - * Create a new Font and add it to the workbook's font table - * - * @return new font object - */ - @Override - public XSSFFont createFont() { - XSSFFont font = new XSSFFont(); - font.registerTo(stylesSource); - return font; - } - - @Override - public XSSFName createName() { - CTDefinedName ctName = CTDefinedName.Factory.newInstance(); - ctName.setName(""); - return createAndStoreName(ctName); - } - - private XSSFName createAndStoreName(CTDefinedName ctName) { - XSSFName name = new XSSFName(ctName, this); - namedRanges.add(name); - namedRangesByName.put(ctName.getName().toLowerCase(Locale.ENGLISH), name); - return name; - } - - /** - * Create an XSSFSheet for this workbook, adds it to the sheets and returns - * the high level representation. Use this to create new sheets. - * - * @return XSSFSheet representing the new sheet. - */ - @Override - public XSSFSheet createSheet() { - String sheetname = "Sheet" + (sheets.size()); - int idx = 0; - while(getSheet(sheetname) != null) { - sheetname = "Sheet" + idx; - idx++; - } - return createSheet(sheetname); - } - - /** - * Create a new sheet for this Workbook and return the high level representation. - * Use this to create new sheets. - * - *

        - * Note that Excel allows sheet names up to 31 chars in length but other applications - * (such as OpenOffice) allow more. Some versions of Excel crash with names longer than 31 chars, - * others - truncate such names to 31 character. - *

        - *

        - * POI's SpreadsheetAPI silently truncates the input argument to 31 characters. - * Example: - * - *

        
        -     *     Sheet sheet = workbook.createSheet("My very long sheet name which is longer than 31 chars"); // will be truncated
        -     *     assert 31 == sheet.getSheetName().length();
        -     *     assert "My very long sheet name which i" == sheet.getSheetName();
        -     *     
        - *

        - * - * Except the 31-character constraint, Excel applies some other rules: - *

        - * Sheet name MUST be unique in the workbook and MUST NOT contain the any of the following characters: - *

          - *
        • 0x0000
        • - *
        • 0x0003
        • - *
        • colon (:)
        • - *
        • backslash (\)
        • - *
        • asterisk (*)
        • - *
        • question mark (?)
        • - *
        • forward slash (/)
        • - *
        • opening square bracket ([)
        • - *
        • closing square bracket (])
        • - *
        - * The string MUST NOT begin or end with the single quote (') character. - *

        - * - *

        - * See {@link org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)} - * for a safe way to create valid names - *

        - * @param sheetname sheetname to set for the sheet. - * @return Sheet representing the new sheet. - * @throws IllegalArgumentException if the name is null or invalid - * or workbook already contains a sheet with this name - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - */ - @Override - public XSSFSheet createSheet(String sheetname) { - if (sheetname == null) { - throw new IllegalArgumentException("sheetName must not be null"); - } - - validateSheetName(sheetname); - - // YK: Mimic Excel and silently truncate sheet names longer than 31 characters - if(sheetname.length() > 31) sheetname = sheetname.substring(0, 31); - WorkbookUtil.validateSheetName(sheetname); - - CTSheet sheet = addSheet(sheetname); - - int sheetNumber = 1; - outerloop: - while(true) { - for(XSSFSheet sh : sheets) { - sheetNumber = (int)Math.max(sh.sheet.getSheetId() + 1, sheetNumber); - } - - // Bug 57165: We also need to check that the resulting file name is not already taken - // this can happen when moving/cloning sheets - String sheetName = XSSFRelation.WORKSHEET.getFileName(sheetNumber); - for(POIXMLDocumentPart relation : getRelations()) { - if(relation.getPackagePart() != null && - sheetName.equals(relation.getPackagePart().getPartName().getName())) { - // name is taken => try next one - sheetNumber++; - continue outerloop; - } - } - - // no duplicate found => use this one - break; - } - - RelationPart rp = createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber, false); - XSSFSheet wrapper = rp.getDocumentPart(); - wrapper.sheet = sheet; - sheet.setId(rp.getRelationship().getId()); - sheet.setSheetId(sheetNumber); - if (sheets.isEmpty()) wrapper.setSelected(true); - sheets.add(wrapper); - return wrapper; - } - - private void validateSheetName(final String sheetName) throws IllegalArgumentException { - if (containsSheet( sheetName, sheets.size() )) { - throw new IllegalArgumentException("The workbook already contains a sheet named '" + sheetName + "'"); - } - } - - protected XSSFDialogsheet createDialogsheet(String sheetname, CTDialogsheet dialogsheet) { - XSSFSheet sheet = createSheet(sheetname); - String sheetRelId = getRelationId(sheet); - PackageRelationship pr = getPackagePart().getRelationship(sheetRelId); - return new XSSFDialogsheet(sheet, pr); - } - - private CTSheet addSheet(String sheetname) { - CTSheet sheet = workbook.getSheets().addNewSheet(); - sheet.setName(sheetname); - return sheet; - } - - /** - * Finds a font that matches the one with the supplied attributes - * @deprecated POI 3.15. Use {@link #findFont(boolean, short, short, String, boolean, boolean, short, byte)} instead. - */ - @Deprecated - @Override - public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) { - return stylesSource.findFont(boldWeight, color, fontHeight, name, italic, strikeout, typeOffset, underline); - } - - /** - * Finds a font that matches the one with the supplied attributes - */ - @Override - public XSSFFont findFont(boolean bold, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) { - return stylesSource.findFont(bold, color, fontHeight, name, italic, strikeout, typeOffset, underline); - } - - /** - * Convenience method to get the active sheet. The active sheet is is the sheet - * which is currently displayed when the workbook is viewed in Excel. - * 'Selected' sheet(s) is a distinct concept. - */ - @Override - public int getActiveSheetIndex() { - //activeTab (Active Sheet Index) Specifies an unsignedInt - //that contains the index to the active sheet in this book view. - return (int)workbook.getBookViews().getWorkbookViewArray(0).getActiveTab(); - } - - /** - * Gets all pictures from the Workbook. - * - * @return the list of pictures (a list of {@link XSSFPictureData} objects.) - * @see #addPicture(byte[], int) - */ - @Override - public List getAllPictures() { - if(pictures == null){ - List mediaParts = getPackage().getPartsByName(Pattern.compile("/xl/media/.*?")); - pictures = new ArrayList(mediaParts.size()); - for(PackagePart part : mediaParts){ - pictures.add(new XSSFPictureData(part)); - } - } - return pictures; //YK: should return Collections.unmodifiableList(pictures); - } - - /** - * Get the cell style object at the given index - * - * @param idx index within the set of styles - * @return XSSFCellStyle object at the index - */ - @Override - public XSSFCellStyle getCellStyleAt(int idx) { - return stylesSource.getStyleAt(idx); - } - - /** - * Get the font at the given index number - * - * @param idx index number - * @return XSSFFont at the index - */ - @Override - public XSSFFont getFontAt(short idx) { - return stylesSource.getFontAt(idx); - } - - /** - * Get the first named range with the given name. - * - * Note: names of named ranges are not unique as they are scoped by sheet. - * {@link #getNames(String name)} returns all named ranges with the given name. - * - * @param name named range name - * @return XSSFName with the given name. null is returned no named range could be found. - */ - @Override - public XSSFName getName(String name) { - Collection list = getNames(name); - if (list.isEmpty()) { - return null; - } - return list.iterator().next(); - } - - /** - * Get the named ranges with the given name. - * Note:Excel named ranges are case-insensitive and - * this method performs a case-insensitive search. - * - * @param name named range name - * @return list of XSSFNames with the given name. An empty list if no named ranges could be found - */ - @Override - public List getNames(String name) { - return Collections.unmodifiableList(namedRangesByName.get(name.toLowerCase(Locale.ENGLISH))); - } - - /** - * Get the named range at the given index. - * - * @param nameIndex the index of the named range - * @return the XSSFName at the given index - * - * @deprecated 3.16. New projects should avoid accessing named ranges by index. - */ - @Override - @Deprecated - public XSSFName getNameAt(int nameIndex) { - int nNames = namedRanges.size(); - if (nNames < 1) { - throw new IllegalStateException("There are no defined names in this workbook"); - } - if (nameIndex < 0 || nameIndex > nNames) { - throw new IllegalArgumentException("Specified name index " + nameIndex - + " is outside the allowable range (0.." + (nNames-1) + ")."); - } - return namedRanges.get(nameIndex); - } - - /** - * Get a list of all the named ranges in the workbook. - * - * @return list of XSSFNames in the workbook - */ - @Override - public List getAllNames() { - return Collections.unmodifiableList(namedRanges); - } - - /** - * Gets the named range index by name. - * - * @param name named range name - * @return named range index. -1 is returned if no named ranges could be found. - * - * @deprecated 3.16. New projects should avoid accessing named ranges by index. - * Use {@link #getName(String)} instead. - */ - @Override - @Deprecated - public int getNameIndex(String name) { - XSSFName nm = getName(name); - if (nm != null) { - return namedRanges.indexOf(nm); - } - return -1; - } - - /** - * Get the number of styles the workbook contains - * - * @return count of cell styles - */ - @Override - public int getNumCellStyles() { - return stylesSource.getNumCellStyles(); - } - - /** - * Get the number of fonts in the this workbook - * - * @return number of fonts - */ - @Override - public short getNumberOfFonts() { - return (short)stylesSource.getFonts().size(); - } - - /** - * Get the number of named ranges in the this workbook - * - * @return number of named ranges - */ - @Override - public int getNumberOfNames() { - return namedRanges.size(); - } - - /** - * Get the number of worksheets in the this workbook - * - * @return number of worksheets - */ - @Override - public int getNumberOfSheets() { - return sheets.size(); - } - - /** - * Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified. - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @return String Null if no print area has been defined - */ - @Override - public String getPrintArea(int sheetIndex) { - XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex); - if (name == null) return null; - //adding one here because 0 indicates a global named region; doesnt make sense for print areas - return name.getRefersToFormula(); - - } - - /** - * Get sheet with the given name (case insensitive match) - * - * @param name of the sheet - * @return XSSFSheet with the name provided or null if it does not exist - */ - @Override - public XSSFSheet getSheet(String name) { - for (XSSFSheet sheet : sheets) { - if (name.equalsIgnoreCase(sheet.getSheetName())) { - return sheet; - } - } - return null; - } - - /** - * Get the XSSFSheet object at the given index. - * - * @param index of the sheet number (0-based physical & logical) - * @return XSSFSheet at the provided index - * @throws IllegalArgumentException if the index is out of range (index - * < 0 || index >= getNumberOfSheets()). - */ - @Override - public XSSFSheet getSheetAt(int index) { - validateSheetIndex(index); - return sheets.get(index); - } - - /** - * Returns the index of the sheet by his name (case insensitive match) - * - * @param name the sheet name - * @return index of the sheet (0 based) or -1-1 if not found - */ - @Override - public int getSheetIndex(Sheet sheet) { - int idx = 0; - for(XSSFSheet sh : sheets){ - if(sh == sheet) return idx; - idx++; - } - return -1; - } - - /** - * Get the sheet name - * - * @param sheetIx Number - * @return Sheet name - */ - @Override - public String getSheetName(int sheetIx) { - validateSheetIndex(sheetIx); - return sheets.get(sheetIx).getSheetName(); - } - - /** - * Returns an iterator of the sheets in the workbook - * in sheet order. Includes hidden and very hidden sheets. - * - * Note: remove() is not supported on this iterator. - * Use {@link #removeSheetAt(int)} to remove sheets instead. - * - * @return an iterator of the sheets. - */ - @Override - public Iterator sheetIterator() { - return new SheetIterator(); - } - - /** - * Alias for {@link #sheetIterator()} to allow - * foreach loops - * - * Iterator iterator() was replaced with Iterator iterator() - * to make iterating over a container (Workbook, Sheet, Row) consistent across POI spreadsheets. - * This breaks backwards compatibility and may affect your code. - * See {@link XSSFWorkbook#xssfSheetIterator} for how to upgrade your code to be compatible - * with the new interface. - * - * Note: remove() is not supported on this iterator. - * Use {@link #removeSheetAt(int)} to remove sheets instead. - * - * @return an iterator of the sheets. - */ - @Override - public Iterator iterator() { - return sheetIterator(); - } - - private final class SheetIterator implements Iterator { - final private Iterator it; - @SuppressWarnings("unchecked") - public SheetIterator() { - it = (Iterator) sheets.iterator(); - } - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - public T next() throws NoSuchElementException { - return it.next(); - } - /** - * Unexpected behavior may occur if sheets are reordered after iterator - * has been created. Support for the remove method may be added in the future - * if someone can figure out a reliable implementation. - */ - @Override - public void remove() throws IllegalStateException { - throw new UnsupportedOperationException("remove method not supported on XSSFWorkbook.iterator(). "+ - "Use Sheet.removeSheetAt(int) instead."); - } - } - - /** - * xssfSheetIterator was added to make transitioning to the new Iterator iterator() - * interface less painful for projects currently using POI. - * - * If your code was written using a for-each loop: - *
        
        -     *  for (XSSFSheet sh : wb) {
        -     *      sh.createRow(0);
        -     *  }
        -     *  
        - * - * There are two ways to upgrade your code: - * // Option A: - *
        
        -     *  for (XSSFSheet sh : (Iterable) (Iterable) wb) {
        -     *      sh.createRow(0);
        -     *  }
        -     *  
        - * - * // Option B (preferred for new code): - *
        
        -     *  for (Sheet sh : wb) {
        -     *      sh.createRow(0);
        -     *  }
        -     *  
        - * - * - * - * If your code was written using an iterator variable: - *
        
        -     *  Iterator it = wb.iterator();
        -     *  XSSFSheet sh = it.next();
        -     *  sh.createRow(0);
        -     *  
        - * - * There are three ways to upgrade your code: - * // Option A: - *
        
        -     *  Iterator it = (Iterator) (Iterator) wb.iterator();
        -     *  XSSFSheet sh = it.next();
        -     *  sh.createRow(0);
        -     *  
        - * - * // Option B: - *
        
        -     *  @SuppressWarnings("deprecation")
        -     *  Iterator it = wb.xssfSheetIterator();
        -     *  XSSFSheet sh = it.next();
        -     *  sh.createRow(0);
        -     *  
        - * - * // Option C (preferred for new code): - *
        
        -     *  Iterator it = wb.iterator();
        -     *  Sheet sh = it.next();
        -     *  sh.createRow(0);
        -     *  
        - * - * @deprecated 3.13. New projects should use the preferred options. Note: XSSFWorkbook.xssfSheetIterator - * is deprecated and will be removed in 3.15. - * - * @return an iterator of the sheets. - */ - @Deprecated - public Iterator xssfSheetIterator() { - return new SheetIterator(); - } - - /** - * Are we a normal workbook (.xlsx), or a - * macro enabled workbook (.xlsm)? - */ - public boolean isMacroEnabled() { - return getPackagePart().getContentType().equals(XSSFRelation.MACROS_WORKBOOK.getContentType()); - } - - /** - * Remove the named range at the given index. - * - * @param nameIndex the index of the named range name to remove - * - * @deprecated 3.16. New projects should use {@link #removeName(Name)}. - */ - @Override - @Deprecated - public void removeName(int nameIndex) { - removeName(getNameAt(nameIndex)); - } - - /** - * Remove the first named range found with the given name. - * - * Note: names of named ranges are not unique (name + sheet - * index is unique), so {@link #removeName(Name)} should - * be used if possible. - * - * @param name the named range name to remove - * - * @throws IllegalArgumentException if no named range could be found - * - * @deprecated 3.16. New projects should use {@link #removeName(Name)}. - */ - @Override - @Deprecated - public void removeName(String name) { - List names = namedRangesByName.get(name.toLowerCase(Locale.ENGLISH)); - if (names.isEmpty()) { - throw new IllegalArgumentException("Named range was not found: " + name); - } - removeName(names.get(0)); - } - - - /** - * As {@link #removeName(String)} is not necessarily unique - * (name + sheet index is unique), this method is more accurate. - * - * @param name the name to remove. - * - * @throws IllegalArgumentException if the named range is not a part of this XSSFWorkbook - */ - @Override - public void removeName(Name name) { - if (!namedRangesByName.removeMapping(name.getNameName().toLowerCase(Locale.ENGLISH), name) - || !namedRanges.remove(name)) { - throw new IllegalArgumentException("Name was not found: " + name); - } - } - - void updateName(XSSFName name, String oldName) { - if (!namedRangesByName.removeMapping(oldName.toLowerCase(Locale.ENGLISH), name)) { - throw new IllegalArgumentException("Name was not found: " + name); - } - namedRangesByName.put(name.getNameName().toLowerCase(Locale.ENGLISH), name); - } - - - /** - * Delete the printarea for the sheet specified - * - * @param sheetIndex 0-based sheet index (0 = First Sheet) - */ - @Override - public void removePrintArea(int sheetIndex) { - XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex); - if (name != null) { - removeName(name); - } - } - - /** - * Removes sheet at the given index.

        - * - * Care must be taken if the removed sheet is the currently active or only selected sheet in - * the workbook. There are a few situations when Excel must have a selection and/or active - * sheet. (For example when printing - see Bug 40414).
        - * - * This method makes sure that if the removed sheet was active, another sheet will become - * active in its place. Furthermore, if the removed sheet was the only selected sheet, another - * sheet will become selected. The newly active/selected sheet will have the same index, or - * one less if the removed sheet was the last in the workbook. - * - * @param index of the sheet (0-based) - */ - @Override - public void removeSheetAt(int index) { - validateSheetIndex(index); - - onSheetDelete(index); - - XSSFSheet sheet = getSheetAt(index); - removeRelation(sheet); - sheets.remove(index); - - // only set new sheet if there are still some left - if(sheets.size() == 0) { - return; - } - - // the index of the closest remaining sheet to the one just deleted - int newSheetIndex = index; - if (newSheetIndex >= sheets.size()) { - newSheetIndex = sheets.size()-1; - } - - // adjust active sheet - int active = getActiveSheetIndex(); - if(active == index) { - // removed sheet was the active one, reset active sheet if there is still one left now - setActiveSheet(newSheetIndex); - } else if (active > index) { - // removed sheet was below the active one => active is one less now - setActiveSheet(active-1); - } - } - - /** - * Gracefully remove references to the sheet being deleted - * - * @param index the 0-based index of the sheet to delete - */ - private void onSheetDelete(int index) { - //delete the CTSheet reference from workbook.xml - workbook.getSheets().removeSheet(index); - - //calculation chain is auxiliary, remove it as it may contain orphan references to deleted cells - if(calcChain != null) { - removeRelation(calcChain); - calcChain = null; - } - - //adjust indices of names ranges - List toRemove = new ArrayList(); - for (XSSFName nm : namedRanges) { - CTDefinedName ct = nm.getCTName(); - if(!ct.isSetLocalSheetId()) continue; - if (ct.getLocalSheetId() == index) { - toRemove.add(nm); - } else if (ct.getLocalSheetId() > index){ - // Bump down by one, so still points at the same sheet - ct.setLocalSheetId(ct.getLocalSheetId()-1); - } - } - for (XSSFName nm : toRemove) { - removeName(nm); - } - } - - /** - * Retrieves the current policy on what to do when - * getting missing or blank cells from a row. - * The default is to return blank and null cells. - * {@link MissingCellPolicy} - */ - @Override - public MissingCellPolicy getMissingCellPolicy() { - return _missingCellPolicy; - } - /** - * Sets the policy on what to do when - * getting missing or blank cells from a row. - * This will then apply to all calls to - * {@link Row#getCell(int)}}. See - * {@link MissingCellPolicy} - */ - @Override - public void setMissingCellPolicy(MissingCellPolicy missingCellPolicy) { - _missingCellPolicy = missingCellPolicy; - } - - /** - * Convenience method to set the active sheet. The active sheet is is the sheet - * which is currently displayed when the workbook is viewed in Excel. - * 'Selected' sheet(s) is a distinct concept. - */ - @Override - public void setActiveSheet(int index) { - - validateSheetIndex(index); - - for (CTBookView arrayBook : workbook.getBookViews().getWorkbookViewArray()) { - arrayBook.setActiveTab(index); - } - } - - /** - * Validate sheet index - * - * @param index the index to validate - * @throws IllegalArgumentException if the index is out of range (index - * < 0 || index >= getNumberOfSheets()). - */ - private void validateSheetIndex(int index) { - int lastSheetIx = sheets.size() - 1; - if (index < 0 || index > lastSheetIx) { - String range = "(0.." + lastSheetIx + ")"; - if (lastSheetIx == -1) { - range = "(no sheets)"; - } - throw new IllegalArgumentException("Sheet index (" - + index +") is out of range " + range); - } - } - - /** - * Gets the first tab that is displayed in the list of tabs in excel. - * - * @return integer that contains the index to the active sheet in this book view. - */ - @Override - public int getFirstVisibleTab() { - CTBookViews bookViews = workbook.getBookViews(); - CTBookView bookView = bookViews.getWorkbookViewArray(0); - return (short) bookView.getFirstSheet(); - } - - /** - * Sets the first tab that is displayed in the list of tabs in excel. - * - * @param index integer that contains the index to the active sheet in this book view. - */ - @Override - public void setFirstVisibleTab(int index) { - CTBookViews bookViews = workbook.getBookViews(); - CTBookView bookView= bookViews.getWorkbookViewArray(0); - bookView.setFirstSheet(index); - } - - /** - * Sets the printarea for the sheet provided - *

        - * i.e. Reference = $A$1:$B$2 - * @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java) - * @param reference Valid name Reference for the Print Area - */ - @Override - public void setPrintArea(int sheetIndex, String reference) { - XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex); - if (name == null) { - name = createBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex); - } - //short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex); - //name.setExternSheetNumber(externSheetIndex); - String[] parts = COMMA_PATTERN.split(reference); - StringBuffer sb = new StringBuffer(32); - for (int i = 0; i < parts.length; i++) { - if(i>0) { - sb.append(","); - } - SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex)); - sb.append("!"); - sb.append(parts[i]); - } - name.setRefersToFormula(sb.toString()); - } - - /** - * For the Convenience of Java Programmers maintaining pointers. - * @see #setPrintArea(int, String) - * @param sheetIndex Zero-based sheet index (0 = First Sheet) - * @param startColumn Column to begin printarea - * @param endColumn Column to end the printarea - * @param startRow Row to begin the printarea - * @param endRow Row to end the printarea - */ - @Override - public void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) { - String reference=getReferencePrintArea(getSheetName(sheetIndex), startColumn, endColumn, startRow, endRow); - setPrintArea(sheetIndex, reference); - } - - private static String getReferencePrintArea(String sheetName, int startC, int endC, int startR, int endR) { - //windows excel example: Sheet1!$C$3:$E$4 - CellReference colRef = new CellReference(sheetName, startR, startC, true, true); - CellReference colRef2 = new CellReference(sheetName, endR, endC, true, true); - - return "$" + colRef.getCellRefParts()[2] + "$" + colRef.getCellRefParts()[1] + ":$" + colRef2.getCellRefParts()[2] + "$" + colRef2.getCellRefParts()[1]; - } - - XSSFName getBuiltInName(String builtInCode, int sheetNumber) { - for (XSSFName name : namedRangesByName.get(builtInCode.toLowerCase(Locale.ENGLISH))) { - if (name.getSheetIndex() == sheetNumber) { - return name; - } - } - return null; - } - - /** - * Generates a NameRecord to represent a built-in region - * - * @return a new NameRecord - * @throws IllegalArgumentException if sheetNumber is invalid - * @throws POIXMLException if such a name already exists in the workbook - */ - XSSFName createBuiltInName(String builtInName, int sheetNumber) { - validateSheetIndex(sheetNumber); - - CTDefinedNames names = workbook.getDefinedNames() == null ? workbook.addNewDefinedNames() : workbook.getDefinedNames(); - CTDefinedName nameRecord = names.addNewDefinedName(); - nameRecord.setName(builtInName); - nameRecord.setLocalSheetId(sheetNumber); - - if (getBuiltInName(builtInName, sheetNumber) != null) { - throw new POIXMLException("Builtin (" + builtInName - + ") already exists for sheet (" + sheetNumber + ")"); - } - - return createAndStoreName(nameRecord); - } - - /** - * We only set one sheet as selected for compatibility with HSSF. - */ - @Override - public void setSelectedTab(int index) { - int idx = 0; - for (XSSFSheet sh : sheets) { - sh.setSelected(idx == index); - idx++; - } - } - - /** - * Set the sheet name. - * - * @param sheetIndex sheet number (0 based) - * @param sheetname the new sheet name - * @throws IllegalArgumentException if the name is null or invalid - * or workbook already contains a sheet with this name - * @see #createSheet(String) - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - */ - @Override - public void setSheetName(int sheetIndex, String sheetname) { - validateSheetIndex(sheetIndex); - String oldSheetName = getSheetName(sheetIndex); - - // YK: Mimic Excel and silently truncate sheet names longer than 31 characters - if(sheetname != null && sheetname.length() > 31) sheetname = sheetname.substring(0, 31); - WorkbookUtil.validateSheetName(sheetname); - // findbugs fix - validateSheetName has already checked for null value - assert(sheetname != null); - - // Do nothing if no change - if (sheetname.equals(oldSheetName)) return; - - // Check it isn't already taken - if (containsSheet(sheetname, sheetIndex )) - throw new IllegalArgumentException( "The workbook already contains a sheet of this name" ); - - // Update references to the name - XSSFFormulaUtils utils = new XSSFFormulaUtils(this); - utils.updateSheetName(sheetIndex, oldSheetName, sheetname); - - workbook.getSheets().getSheetArray(sheetIndex).setName(sheetname); - } - - /** - * sets the order of appearance for a given sheet. - * - * @param sheetname the name of the sheet to reorder - * @param pos the position that we want to insert the sheet into (0 based) - */ - @Override - public void setSheetOrder(String sheetname, int pos) { - int idx = getSheetIndex(sheetname); - sheets.add(pos, sheets.remove(idx)); - - // Reorder CTSheets - CTSheets ct = workbook.getSheets(); - XmlObject cts = ct.getSheetArray(idx).copy(); - workbook.getSheets().removeSheet(idx); - CTSheet newcts = ct.insertNewSheet(pos); - newcts.set(cts); - - //notify sheets - CTSheet[] sheetArray = ct.getSheetArray(); - for(int i=0; i < sheetArray.length; i++) { - sheets.get(i).sheet = sheetArray[i]; - } - - updateNamedRangesAfterSheetReorder(idx, pos); - updateActiveSheetAfterSheetReorder(idx, pos); - } - - /** - * update sheet-scoped named ranges in this workbook after changing the sheet order - * of a sheet at oldIndex to newIndex. - * Sheets between these indices will move left or right by 1. - * - * @param oldIndex the original index of the re-ordered sheet - * @param newIndex the new index of the re-ordered sheet - */ - private void updateNamedRangesAfterSheetReorder(int oldIndex, int newIndex) { - // update sheet index of sheet-scoped named ranges - for (final XSSFName name : namedRanges) { - final int i = name.getSheetIndex(); - // name has sheet-level scope - if (i != -1) { - // name refers to this sheet - if (i == oldIndex) { - name.setSheetIndex(newIndex); - } - // if oldIndex > newIndex then this sheet moved left and sheets between newIndex and oldIndex moved right - else if (newIndex <= i && i < oldIndex) { - name.setSheetIndex(i+1); - } - // if oldIndex < newIndex then this sheet moved right and sheets between oldIndex and newIndex moved left - else if (oldIndex < i && i <= newIndex) { - name.setSheetIndex(i-1); - } - } - } - } - - private void updateActiveSheetAfterSheetReorder(int oldIndex, int newIndex) { - // adjust active sheet if necessary - int active = getActiveSheetIndex(); - if(active == oldIndex) { - // moved sheet was the active one - setActiveSheet(newIndex); - } else if ((active < oldIndex && active < newIndex) || - (active > oldIndex && active > newIndex)) { - // not affected - } else if (newIndex > oldIndex) { - // moved sheet was below before and is above now => active is one less - setActiveSheet(active-1); - } else { - // remaining case: moved sheet was higher than active before and is lower now => active is one more - setActiveSheet(active+1); - } - } - - /** - * marshal named ranges from the {@link #namedRanges} collection to the underlying CTWorkbook bean - */ - private void saveNamedRanges(){ - // Named ranges - if(namedRanges.size() > 0) { - CTDefinedNames names = CTDefinedNames.Factory.newInstance(); - CTDefinedName[] nr = new CTDefinedName[namedRanges.size()]; - int i = 0; - for(XSSFName name : namedRanges) { - nr[i] = name.getCTName(); - i++; - } - names.setDefinedNameArray(nr); - if(workbook.isSetDefinedNames()) { - workbook.unsetDefinedNames(); - } - workbook.setDefinedNames(names); - - // Re-process the named ranges - reprocessNamedRanges(); - } else { - if(workbook.isSetDefinedNames()) { - workbook.unsetDefinedNames(); - } - } - } - - private void reprocessNamedRanges() { - namedRangesByName = new ArrayListValuedHashMap(); - namedRanges = new ArrayList(); - if(workbook.isSetDefinedNames()) { - for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) { - createAndStoreName(ctName); - } - } - } - - private void saveCalculationChain(){ - if(calcChain != null){ - int count = calcChain.getCTCalcChain().sizeOfCArray(); - if(count == 0){ - removeRelation(calcChain); - calcChain = null; - } - } - } - - @Override - protected void commit() throws IOException { - saveNamedRanges(); - saveCalculationChain(); - - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - workbook.save(out, xmlOptions); - out.close(); - } - - /** - * Returns SharedStringsTable - tha cache of string for this workbook - * - * @return the shared string table - */ - @Internal - public SharedStringsTable getSharedStringSource() { - return this.sharedStringSource; - } - - /** - * Return a object representing a collection of shared objects used for styling content, - * e.g. fonts, cell styles, colors, etc. - */ - public StylesTable getStylesSource() { - return this.stylesSource; - } - - /** - * Returns the Theme of current workbook. - */ - public ThemesTable getTheme() { - if (stylesSource == null) return null; - return stylesSource.getTheme(); - } - - /** - * Returns an object that handles instantiating concrete - * classes of the various instances for XSSF. - */ - @Override - public XSSFCreationHelper getCreationHelper() { - if(_creationHelper == null) _creationHelper = new XSSFCreationHelper(this); - return _creationHelper; - } - - /** - * Determines whether a workbook contains the provided sheet name. - * For the purpose of comparison, long names are truncated to 31 chars. - * - * @param name the name to test (case insensitive match) - * @param excludeSheetIdx the sheet to exclude from the check or -1 to include all sheets in the check. - * @return true if the sheet contains the name, false otherwise. - */ - private boolean containsSheet(String name, int excludeSheetIdx) { - CTSheet[] ctSheetArray = workbook.getSheets().getSheetArray(); - - if (name.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { - name = name.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN); - } - - for (int i = 0; i < ctSheetArray.length; i++) { - String ctName = ctSheetArray[i].getName(); - if (ctName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { - ctName = ctName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN); - } - - if (excludeSheetIdx != i && name.equalsIgnoreCase(ctName)) - return true; - } - return false; - } - - /** - * Gets a boolean value that indicates whether the date systems used in the workbook starts in 1904. - *

        - * The default value is false, meaning that the workbook uses the 1900 date system, - * where 1/1/1900 is the first day in the system.. - *

        - * @return true if the date systems used in the workbook starts in 1904 - */ - @Internal - public boolean isDate1904(){ - CTWorkbookPr workbookPr = workbook.getWorkbookPr(); - return workbookPr != null && workbookPr.getDate1904(); - } - - /** - * Get the document's embedded files. - */ - @Override - public List getAllEmbedds() throws OpenXML4JException { - List embedds = new LinkedList(); - - for(XSSFSheet sheet : sheets){ - // Get the embeddings for the workbook - for(PackageRelationship rel : sheet.getPackagePart().getRelationshipsByType(XSSFRelation.OLEEMBEDDINGS.getRelation())) { - embedds.add( sheet.getPackagePart().getRelatedPart(rel) ); - } - - for(PackageRelationship rel : sheet.getPackagePart().getRelationshipsByType(XSSFRelation.PACKEMBEDDINGS.getRelation())) { - embedds.add( sheet.getPackagePart().getRelatedPart(rel) ); - } - } - return embedds; - } - - @Override - @NotImplemented - public boolean isHidden() { - throw new RuntimeException("Not implemented yet"); - } - - @Override - @NotImplemented - public void setHidden(boolean hiddenFlag) { - throw new RuntimeException("Not implemented yet"); - } - - /** - * Check whether a sheet is hidden. - *

        - * Note that a sheet could instead be set to be very hidden, which is different - * ({@link #isSheetVeryHidden(int)}) - *

        - * @param sheetIx Number - * @return true if sheet is hidden - */ - @Override - public boolean isSheetHidden(int sheetIx) { - validateSheetIndex(sheetIx); - CTSheet ctSheet = sheets.get(sheetIx).sheet; - return ctSheet.getState() == STSheetState.HIDDEN; - } - - /** - * Check whether a sheet is very hidden. - *

        - * This is different from the normal hidden status - * ({@link #isSheetHidden(int)}) - *

        - * @param sheetIx sheet index to check - * @return true if sheet is very hidden - */ - @Override - public boolean isSheetVeryHidden(int sheetIx) { - validateSheetIndex(sheetIx); - CTSheet ctSheet = sheets.get(sheetIx).sheet; - return ctSheet.getState() == STSheetState.VERY_HIDDEN; - } - - /** - * Sets the visible state of this sheet. - *

        - * Calling setSheetHidden(sheetIndex, true) is equivalent to - * setSheetHidden(sheetIndex, Workbook.SHEET_STATE_HIDDEN). - *
        - * Calling setSheetHidden(sheetIndex, false) is equivalent to - * setSheetHidden(sheetIndex, Workbook.SHEET_STATE_VISIBLE). - *

        - * - * Please note that the sheet currently set as active sheet (sheet 0 in a newly - * created workbook or the one set via setActiveSheet()) cannot be hidden. - * - * @param sheetIx the 0-based index of the sheet - * @param hidden whether this sheet is hidden - * @see #setSheetHidden(int, int) - */ - @Override - public void setSheetHidden(int sheetIx, boolean hidden) { - setSheetHidden(sheetIx, hidden ? SHEET_STATE_HIDDEN : SHEET_STATE_VISIBLE); - } - - /** - * Hide or unhide a sheet. - * - *
          - *
        • 0 - visible.
        • - *
        • 1 - hidden.
        • - *
        • 2 - very hidden.
        • - *
        - * - * Please note that the sheet currently set as active sheet (sheet 0 in a newly - * created workbook or the one set via setActiveSheet()) cannot be hidden. - * - * @param sheetIx the sheet index (0-based) - * @param state one of the following Workbook constants: - * Workbook.SHEET_STATE_VISIBLE, - * Workbook.SHEET_STATE_HIDDEN, or - * Workbook.SHEET_STATE_VERY_HIDDEN. - * @throws IllegalArgumentException if the supplied sheet index or state is invalid - */ - @Override - public void setSheetHidden(int sheetIx, int state) { - validateSheetIndex(sheetIx); - WorkbookUtil.validateSheetState(state); - CTSheet ctSheet = sheets.get(sheetIx).sheet; - ctSheet.setState(STSheetState.Enum.forInt(state + 1)); - } - - /** - * Fired when a formula is deleted from this workbook, - * for example when calling cell.setCellFormula(null) - * - * @see XSSFCell#setCellFormula(String) - */ - protected void onDeleteFormula(XSSFCell cell){ - if(calcChain != null) { - int sheetId = (int)cell.getSheet().sheet.getSheetId(); - calcChain.removeItem(sheetId, cell.getReference()); - } - } - - /** - * Return the {@link CalculationChain} object for this workbook - *

        - * The calculation chain object specifies the order in which the cells in a workbook were last calculated - *

        - * - * @return the CalculationChain object or null if not defined - */ - @Internal - public CalculationChain getCalculationChain() { - return calcChain; - } - - /** - * Returns the list of {@link ExternalLinksTable} object for this workbook - * - *

        The external links table specifies details of named ranges etc - * that are referenced from other workbooks, along with the last seen - * values of what they point to.

        - * - *

        Note that Excel uses index 0 for the current workbook, so the first - * External Links in a formula would be '[1]Foo' which corresponds to - * entry 0 in this list.

        - - * @return the ExternalLinksTable list, which may be empty - */ - @Internal - public List getExternalLinksTable() { - return externalLinks; - } - - /** - * - * @return a collection of custom XML mappings defined in this workbook - */ - public Collection getCustomXMLMappings(){ - return mapInfo == null ? new ArrayList() : mapInfo.getAllXSSFMaps(); - } - - /** - * - * @return the helper class used to query the custom XML mapping defined in this workbook - */ - @Internal - public MapInfo getMapInfo(){ - return mapInfo; - } - - /** - * Adds the External Link Table part and relations required to allow formulas - * referencing the specified external workbook to be added to this one. Allows - * formulas such as "[MyOtherWorkbook.xlsx]Sheet3!$A$5" to be added to the - * file, for workbooks not already linked / referenced. - * - * @param name The name the workbook will be referenced as in formulas - * @param workbook The open workbook to fetch the link required information from - */ - @Override - @NotImplemented - public int linkExternalWorkbook(String name, Workbook workbook) { - throw new RuntimeException("Not Implemented - see bug #57184"); - } - - /** - * Specifies a boolean value that indicates whether structure of workbook is locked.
        - * A value true indicates the structure of the workbook is locked. Worksheets in the workbook can't be moved, - * deleted, hidden, unhidden, or renamed, and new worksheets can't be inserted.
        - * A value of false indicates the structure of the workbook is not locked.
        - * - * @return true if structure of workbook is locked - */ - public boolean isStructureLocked() { - return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockStructure(); - } - - /** - * Specifies a boolean value that indicates whether the windows that comprise the workbook are locked.
        - * A value of true indicates the workbook windows are locked. Windows are the same size and position each time the - * workbook is opened.
        - * A value of false indicates the workbook windows are not locked. - * - * @return true if windows that comprise the workbook are locked - */ - public boolean isWindowsLocked() { - return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockWindows(); - } - - /** - * Specifies a boolean value that indicates whether the workbook is locked for revisions. - * - * @return true if the workbook is locked for revisions. - */ - public boolean isRevisionLocked() { - return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockRevision(); - } - - /** - * Locks the structure of workbook. - */ - public void lockStructure() { - safeGetWorkbookProtection().setLockStructure(true); - } - - /** - * Unlocks the structure of workbook. - */ - public void unLockStructure() { - safeGetWorkbookProtection().setLockStructure(false); - } - - /** - * Locks the windows that comprise the workbook. - */ - public void lockWindows() { - safeGetWorkbookProtection().setLockWindows(true); - } - - /** - * Unlocks the windows that comprise the workbook. - */ - public void unLockWindows() { - safeGetWorkbookProtection().setLockWindows(false); - } - - /** - * Locks the workbook for revisions. - */ - public void lockRevision() { - safeGetWorkbookProtection().setLockRevision(true); - } - - /** - * Unlocks the workbook for revisions. - */ - public void unLockRevision() { - safeGetWorkbookProtection().setLockRevision(false); - } - - /** - * Sets the workbook password. - * - * @param password if null, the password will be removed - * @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier) - * otherwise the given algorithm is used for calculating the hash password (Excel 2013) - */ - public void setWorkbookPassword(String password, HashAlgorithm hashAlgo) { - if (password == null && !workbookProtectionPresent()) return; - setPassword(safeGetWorkbookProtection(), password, hashAlgo, "workbook"); - } - - /** - * Validate the password against the stored hash, the hashing method will be determined - * by the existing password attributes - * @return true, if the hashes match (... though original password may differ ...) - */ - public boolean validateWorkbookPassword(String password) { - if (!workbookProtectionPresent()) return (password == null); - return validatePassword(safeGetWorkbookProtection(), password, "workbook"); - } - - /** - * Sets the revisions password. - * - * @param password if null, the password will be removed - * @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier) - * otherwise the given algorithm is used for calculating the hash password (Excel 2013) - */ - public void setRevisionsPassword(String password, HashAlgorithm hashAlgo) { - if (password == null && !workbookProtectionPresent()) return; - setPassword(safeGetWorkbookProtection(), password, hashAlgo, "revisions"); - } - - /** - * Validate the password against the stored hash, the hashing method will be determined - * by the existing password attributes - * @return true if the hashes match (... though original password may differ ...) - */ - public boolean validateRevisionsPassword(String password) { - if (!workbookProtectionPresent()) return (password == null); - return validatePassword(safeGetWorkbookProtection(), password, "revisions"); - } - - /** - * Removes the workbook protection settings - */ - public void unLock() { - if (workbookProtectionPresent()) { - workbook.unsetWorkbookProtection(); - } - } - - private boolean workbookProtectionPresent() { - return workbook.isSetWorkbookProtection(); - } - - private CTWorkbookProtection safeGetWorkbookProtection() { - if (!workbookProtectionPresent()){ - return workbook.addNewWorkbookProtection(); - } - return workbook.getWorkbookProtection(); - } - - /** - * - * Returns the locator of user-defined functions. - *

        - * The default instance extends the built-in functions with the Excel Analysis Tool Pack. - * To set / evaluate custom functions you need to register them as follows: - * - * - * - *

        - * @return wrapped instance of UDFFinder that allows seeking functions both by index and name - */ - /*package*/ UDFFinder getUDFFinder() { - return _udfFinder; - } - - /** - * Register a new toolpack in this workbook. - * - * @param toopack the toolpack to register - */ - @Override - public void addToolPack(UDFFinder toopack){ - _udfFinder.add(toopack); - } - - /** - * Whether the application shall perform a full recalculation when the workbook is opened. - *

        - * Typically you want to force formula recalculation when you modify cell formulas or values - * of a workbook previously created by Excel. When set to true, this flag will tell Excel - * that it needs to recalculate all formulas in the workbook the next time the file is opened. - *

        - *

        - * Note, that recalculation updates cached formula results and, thus, modifies the workbook. - * Depending on the version, Excel may prompt you with "Do you want to save the changes in filename?" - * on close. - *

        - * - * @param value true if the application will perform a full recalculation of - * workbook values when the workbook is opened - * @since 3.8 - */ - @Override - public void setForceFormulaRecalculation(boolean value){ - CTWorkbook ctWorkbook = getCTWorkbook(); - CTCalcPr calcPr = ctWorkbook.isSetCalcPr() ? ctWorkbook.getCalcPr() : ctWorkbook.addNewCalcPr(); - // when set to 0, will tell Excel that it needs to recalculate all formulas - // in the workbook the next time the file is opened. - calcPr.setCalcId(0); - - if(value && calcPr.getCalcMode() == STCalcMode.MANUAL) { - calcPr.setCalcMode(STCalcMode.AUTO); - } - } - - /** - * Whether Excel will be asked to recalculate all formulas when the workbook is opened. - * - * @since 3.8 - */ - @Override - public boolean getForceFormulaRecalculation(){ - CTWorkbook ctWorkbook = getCTWorkbook(); - CTCalcPr calcPr = ctWorkbook.getCalcPr(); - return calcPr != null && calcPr.getCalcId() != 0; - } - - - - /** - * Add pivotCache to the workbook - */ - @Beta - protected CTPivotCache addPivotCache(String rId) { - CTWorkbook ctWorkbook = getCTWorkbook(); - CTPivotCaches caches; - if (ctWorkbook.isSetPivotCaches()) { - caches = ctWorkbook.getPivotCaches(); - } else { - caches = ctWorkbook.addNewPivotCaches(); - } - CTPivotCache cache = caches.addNewPivotCache(); - - int tableId = getPivotTables().size()+1; - cache.setCacheId(tableId); - cache.setId(rId); - if(pivotCaches == null) { - pivotCaches = new ArrayList(); - } - pivotCaches.add(cache); - return cache; - } - - @Beta - public List getPivotTables() { - return pivotTables; - } - - @Beta - protected void setPivotTables(List pivotTables) { - this.pivotTables = pivotTables; - } - - public XSSFWorkbookType getWorkbookType() { - return isMacroEnabled() ? XSSFWorkbookType.XLSM : XSSFWorkbookType.XLSX; - } - - /** - * Sets whether the workbook will be an .xlsx or .xlsm (macro-enabled) file. - */ - public void setWorkbookType(XSSFWorkbookType type) { - try { - getPackagePart().setContentType(type.getContentType()); - } catch (InvalidFormatException e) { - throw new POIXMLException(e); - } - } - - /** - * Adds a vbaProject.bin file to the workbook. This will change the workbook - * type if necessary. - * - * @throws IOException - */ - public void setVBAProject(InputStream vbaProjectStream) throws IOException { - if (!isMacroEnabled()) { - setWorkbookType(XSSFWorkbookType.XLSM); - } - - PackagePartName ppName; - try { - ppName = PackagingURIHelper.createPartName(XSSFRelation.VBA_MACROS.getDefaultFileName()); - } catch (InvalidFormatException e) { - throw new POIXMLException(e); - } - OPCPackage opc = getPackage(); - OutputStream outputStream; - if (!opc.containPart(ppName)) { - POIXMLDocumentPart relationship = createRelationship(XSSFRelation.VBA_MACROS, XSSFFactory.getInstance()); - outputStream = relationship.getPackagePart().getOutputStream(); - } else { - PackagePart part = opc.getPart(ppName); - outputStream = part.getOutputStream(); - } - try { - IOUtils.copy(vbaProjectStream, outputStream); - } finally { - IOUtils.closeQuietly(outputStream); - } - } - - /** - * Adds a vbaProject.bin file taken from another, given workbook to this one. - * @throws IOException - * @throws InvalidFormatException - */ - public void setVBAProject(XSSFWorkbook macroWorkbook) throws IOException, InvalidFormatException { - if (!macroWorkbook.isMacroEnabled()) { - return; - } - InputStream vbaProjectStream = XSSFRelation.VBA_MACROS.getContents(macroWorkbook.getCorePart()); - if (vbaProjectStream != null) { - setVBAProject(vbaProjectStream); - } - } - - /** - * Returns the spreadsheet version (EXCLE2007) of this workbook - * - * @return EXCEL2007 SpreadsheetVersion enum - * @since 3.14 beta 2 - */ - @Override - public SpreadsheetVersion getSpreadsheetVersion() { - return SpreadsheetVersion.EXCEL2007; - } - - /** - * Returns the data table with the given name (case insensitive). - * - * @param name the data table name (case-insensitive) - * @return The Data table in the workbook named name, or null if no table is named name. - * @since 3.15 beta 2 - */ - public XSSFTable getTable(String name) { - if (name != null && sheets != null) { - for (XSSFSheet sheet : sheets) { - for (XSSFTable tbl : sheet.getTables()) { - if (name.equalsIgnoreCase(tbl.getName())) { - return tbl; - } - } - } - } - return null; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookType.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookType.java deleted file mode 100644 index 917d3d6da..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookType.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - - -/** - * Represents the two different kinds of XML-based OOXML document. - */ -public enum XSSFWorkbookType { - - XLSX(XSSFRelation.WORKBOOK.getContentType(), "xlsx"), - XLSM(XSSFRelation.MACROS_WORKBOOK.getContentType(), "xlsm"); - - private final String _contentType; - private final String _extension; - - private XSSFWorkbookType(String contentType, String extension) { - _contentType = contentType; - _extension = extension; - } - - public String getContentType() { - return _contentType; - } - - public String getExtension() { - return _extension; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSeries.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSeries.java deleted file mode 100644 index 09393e51a..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSeries.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.ss.usermodel.charts.ChartSeries; -import org.apache.poi.ss.usermodel.charts.TitleType; -import org.apache.poi.ss.util.CellReference; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; - -/** - * Base of all XSSF Chart Series - */ -public abstract class AbstractXSSFChartSeries implements ChartSeries { - - private String titleValue; - private CellReference titleRef; - private TitleType titleType; - - public void setTitle(CellReference titleReference) { - titleType = TitleType.CELL_REFERENCE; - titleRef = titleReference; - } - - public void setTitle(String title) { - titleType = TitleType.STRING; - titleValue = title; - } - - public CellReference getTitleCellReference() { - if (TitleType.CELL_REFERENCE.equals(titleType)) { - return titleRef; - } - throw new IllegalStateException("Title type is not CellReference."); - } - - public String getTitleString() { - if (TitleType.STRING.equals(titleType)) { - return titleValue; - } - throw new IllegalStateException("Title type is not String."); - } - - public TitleType getTitleType() { - return titleType; - } - - protected boolean isTitleSet() { - return titleType != null; - } - - protected CTSerTx getCTSerTx() { - CTSerTx tx = CTSerTx.Factory.newInstance(); - switch (titleType) { - case CELL_REFERENCE: - tx.addNewStrRef().setF(titleRef.formatAsString()); - return tx; - case STRING: - tx.setV(titleValue); - return tx; - default: - throw new IllegalStateException("Unkown title type: " + titleType); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java deleted file mode 100644 index 43ac8f6c4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.util.Beta; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.*; - -/** - * Category axis type. - * - * @author Martin Andersson - */ -@Beta -public class XSSFCategoryAxis extends XSSFChartAxis { - - private CTCatAx ctCatAx; - - public XSSFCategoryAxis(XSSFChart chart, long id, AxisPosition pos) { - super(chart); - createAxis(id, pos); - } - - public XSSFCategoryAxis(XSSFChart chart, CTCatAx ctCatAx) { - super(chart); - this.ctCatAx = ctCatAx; - } - - public long getId() { - return ctCatAx.getAxId().getVal(); - } - - protected CTAxPos getCTAxPos() { - return ctCatAx.getAxPos(); - } - - protected CTNumFmt getCTNumFmt() { - if (ctCatAx.isSetNumFmt()) { - return ctCatAx.getNumFmt(); - } - return ctCatAx.addNewNumFmt(); - } - - protected CTScaling getCTScaling() { - return ctCatAx.getScaling(); - } - - protected CTCrosses getCTCrosses() { - return ctCatAx.getCrosses(); - } - - @Override - protected CTBoolean getDelete() { - return ctCatAx.getDelete(); - } - - @Override - protected CTTickMark getMajorCTTickMark() { - return ctCatAx.getMajorTickMark(); - } - - @Override - protected CTTickMark getMinorCTTickMark() { - return ctCatAx.getMinorTickMark(); - } - - public void crossAxis(ChartAxis axis) { - ctCatAx.getCrossAx().setVal(axis.getId()); - } - - private void createAxis(long id, AxisPosition pos) { - ctCatAx = chart.getCTChart().getPlotArea().addNewCatAx(); - ctCatAx.addNewAxId().setVal(id); - ctCatAx.addNewAxPos(); - ctCatAx.addNewScaling(); - ctCatAx.addNewCrosses(); - ctCatAx.addNewCrossAx(); - ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); - ctCatAx.addNewDelete(); - ctCatAx.addNewMajorTickMark(); - ctCatAx.addNewMinorTickMark(); - - setPosition(pos); - setOrientation(AxisOrientation.MIN_MAX); - setCrosses(AxisCrosses.AUTO_ZERO); - setVisible(true); - setMajorTickMark(AxisTickMark.CROSS); - setMinorTickMark(AxisTickMark.NONE); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java deleted file mode 100644 index 2e89755fc..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java +++ /dev/null @@ -1,276 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.AxisOrientation; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisTickMark; -import org.apache.poi.util.Beta; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTOrientation; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLogBase; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTTickMark; -import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation; -import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos; -import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses; -import org.openxmlformats.schemas.drawingml.x2006.chart.STTickMark; - -/** - * Base class for all axis types. - * - * @author Roman Kashitsyn - */ -@Beta -public abstract class XSSFChartAxis implements ChartAxis { - - protected XSSFChart chart; - - private static final double MIN_LOG_BASE = 2.0; - private static final double MAX_LOG_BASE = 1000.0; - - protected XSSFChartAxis(XSSFChart chart) { - this.chart = chart; - } - - public AxisPosition getPosition() { - return toAxisPosition(getCTAxPos()); - } - - public void setPosition(AxisPosition position) { - getCTAxPos().setVal(fromAxisPosition(position)); - } - - public void setNumberFormat(String format) { - getCTNumFmt().setFormatCode(format); - getCTNumFmt().setSourceLinked(true); - } - - public String getNumberFormat() { - return getCTNumFmt().getFormatCode(); - } - - public boolean isSetLogBase() { - return getCTScaling().isSetLogBase(); - } - - public void setLogBase(double logBase) { - if (logBase < MIN_LOG_BASE || - MAX_LOG_BASE < logBase) { - throw new IllegalArgumentException("Axis log base must be between 2 and 1000 (inclusive), got: " + logBase); - } - CTScaling scaling = getCTScaling(); - if (scaling.isSetLogBase()) { - scaling.getLogBase().setVal(logBase); - } else { - scaling.addNewLogBase().setVal(logBase); - } - } - - public double getLogBase() { - CTLogBase logBase = getCTScaling().getLogBase(); - if (logBase != null) { - return logBase.getVal(); - } - return 0.0; - } - - public boolean isSetMinimum() { - return getCTScaling().isSetMin(); - } - - public void setMinimum(double min) { - CTScaling scaling = getCTScaling(); - if (scaling.isSetMin()) { - scaling.getMin().setVal(min); - } else { - scaling.addNewMin().setVal(min); - } - } - - public double getMinimum() { - CTScaling scaling = getCTScaling(); - if (scaling.isSetMin()) { - return scaling.getMin().getVal(); - } else { - return 0.0; - } - } - - public boolean isSetMaximum() { - return getCTScaling().isSetMax(); - } - - public void setMaximum(double max) { - CTScaling scaling = getCTScaling(); - if (scaling.isSetMax()) { - scaling.getMax().setVal(max); - } else { - scaling.addNewMax().setVal(max); - } - } - - public double getMaximum() { - CTScaling scaling = getCTScaling(); - if (scaling.isSetMax()) { - return scaling.getMax().getVal(); - } else { - return 0.0; - } - } - - public AxisOrientation getOrientation() { - return toAxisOrientation(getCTScaling().getOrientation()); - } - - public void setOrientation(AxisOrientation orientation) { - CTScaling scaling = getCTScaling(); - STOrientation.Enum stOrientation = fromAxisOrientation(orientation); - if (scaling.isSetOrientation()) { - scaling.getOrientation().setVal(stOrientation); - } else { - getCTScaling().addNewOrientation().setVal(stOrientation); - } - } - - public AxisCrosses getCrosses() { - return toAxisCrosses(getCTCrosses()); - } - - public void setCrosses(AxisCrosses crosses) { - getCTCrosses().setVal(fromAxisCrosses(crosses)); - } - - public boolean isVisible() { - return !getDelete().getVal(); - } - - public void setVisible(boolean value) { - getDelete().setVal(!value); - } - - public AxisTickMark getMajorTickMark() { - return toAxisTickMark(getMajorCTTickMark()); - } - - public void setMajorTickMark(AxisTickMark tickMark) { - getMajorCTTickMark().setVal(fromAxisTickMark(tickMark)); - } - - public AxisTickMark getMinorTickMark() { - return toAxisTickMark(getMinorCTTickMark()); - } - - public void setMinorTickMark(AxisTickMark tickMark) { - getMinorCTTickMark().setVal(fromAxisTickMark(tickMark)); - } - - protected abstract CTAxPos getCTAxPos(); - protected abstract CTNumFmt getCTNumFmt(); - protected abstract CTScaling getCTScaling(); - protected abstract CTCrosses getCTCrosses(); - protected abstract CTBoolean getDelete(); - protected abstract CTTickMark getMajorCTTickMark(); - protected abstract CTTickMark getMinorCTTickMark(); - - private static STOrientation.Enum fromAxisOrientation(AxisOrientation orientation) { - switch (orientation) { - case MIN_MAX: return STOrientation.MIN_MAX; - case MAX_MIN: return STOrientation.MAX_MIN; - default: - throw new IllegalArgumentException(); - } - } - - private static AxisOrientation toAxisOrientation(CTOrientation ctOrientation) { - switch (ctOrientation.getVal().intValue()) { - case STOrientation.INT_MIN_MAX: return AxisOrientation.MIN_MAX; - case STOrientation.INT_MAX_MIN: return AxisOrientation.MAX_MIN; - default: - throw new IllegalArgumentException(); - } - } - - private static STCrosses.Enum fromAxisCrosses(AxisCrosses crosses) { - switch (crosses) { - case AUTO_ZERO: return STCrosses.AUTO_ZERO; - case MIN: return STCrosses.MIN; - case MAX: return STCrosses.MAX; - default: - throw new IllegalArgumentException(); - } - } - - private static AxisCrosses toAxisCrosses(CTCrosses ctCrosses) { - switch (ctCrosses.getVal().intValue()) { - case STCrosses.INT_AUTO_ZERO: return AxisCrosses.AUTO_ZERO; - case STCrosses.INT_MAX: return AxisCrosses.MAX; - case STCrosses.INT_MIN: return AxisCrosses.MIN; - default: - throw new IllegalArgumentException(); - } - } - - private static STAxPos.Enum fromAxisPosition(AxisPosition position) { - switch (position) { - case BOTTOM: return STAxPos.B; - case LEFT: return STAxPos.L; - case RIGHT: return STAxPos.R; - case TOP: return STAxPos.T; - default: - throw new IllegalArgumentException(); - } - } - - private static AxisPosition toAxisPosition(CTAxPos ctAxPos) { - switch (ctAxPos.getVal().intValue()) { - case STAxPos.INT_B: return AxisPosition.BOTTOM; - case STAxPos.INT_L: return AxisPosition.LEFT; - case STAxPos.INT_R: return AxisPosition.RIGHT; - case STAxPos.INT_T: return AxisPosition.TOP; - default: return AxisPosition.BOTTOM; - } - } - - private static STTickMark.Enum fromAxisTickMark(AxisTickMark tickMark) { - switch (tickMark) { - case NONE: return STTickMark.NONE; - case IN: return STTickMark.IN; - case OUT: return STTickMark.OUT; - case CROSS: return STTickMark.CROSS; - default: - throw new IllegalArgumentException("Unknown AxisTickMark: " + tickMark); - } - } - - private static AxisTickMark toAxisTickMark(CTTickMark ctTickMark) { - switch (ctTickMark.getVal().intValue()) { - case STTickMark.INT_NONE: return AxisTickMark.NONE; - case STTickMark.INT_IN: return AxisTickMark.IN; - case STTickMark.INT_OUT: return AxisTickMark.OUT; - case STTickMark.INT_CROSS: return AxisTickMark.CROSS; - default: return AxisTickMark.CROSS; - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java deleted file mode 100644 index 8bde83a25..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.util.Beta; - -/** - * @author Roman Kashitsyn - */ -@Beta -public class XSSFChartDataFactory implements ChartDataFactory { - - private static XSSFChartDataFactory instance; - - private XSSFChartDataFactory() { - super(); - } - - /** - * @return new scatter charts data instance - */ - public XSSFScatterChartData createScatterChartData() { - return new XSSFScatterChartData(); - } - - /** - * @return new line charts data instance - */ - public XSSFLineChartData createLineChartData() { - return new XSSFLineChartData(); - } - - /** - * @return factory instance - */ - public static XSSFChartDataFactory getInstance() { - if (instance == null) { - instance = new XSSFChartDataFactory(); - } - return instance; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java deleted file mode 100644 index 6d82881a1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java +++ /dev/null @@ -1,131 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.LegendPosition; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegendPos; -import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos; - -/** - * Represents a SpreadsheetML chart legend - * @author Roman Kashitsyn - * @author Martin Andersson - */ -@Beta -public final class XSSFChartLegend implements ChartLegend { - - /** - * Underlaying CTLagend bean - */ - private CTLegend legend; - - /** - * Create a new SpreadsheetML chart legend - */ - public XSSFChartLegend(XSSFChart chart) { - CTChart ctChart = chart.getCTChart(); - this.legend = (ctChart.isSetLegend()) ? - ctChart.getLegend() : - ctChart.addNewLegend(); - - setDefaults(); - } - - /** - * Set sensible default styling. - */ - private void setDefaults() { - if (!legend.isSetOverlay()) { - legend.addNewOverlay(); - } - legend.getOverlay().setVal(false); - } - - /** - * Return the underlying CTLegend bean. - * - * @return the underlying CTLegend bean - */ - @Internal - public CTLegend getCTLegend(){ - return legend; - } - - public void setPosition(LegendPosition position) { - if (!legend.isSetLegendPos()) { - legend.addNewLegendPos(); - } - legend.getLegendPos().setVal(fromLegendPosition(position)); - } - - /* - * According to ECMA-376 default position is RIGHT. - */ - public LegendPosition getPosition() { - if (legend.isSetLegendPos()) { - return toLegendPosition(legend.getLegendPos()); - } else { - return LegendPosition.RIGHT; - } - } - - public XSSFManualLayout getManualLayout() { - if (!legend.isSetLayout()) { - legend.addNewLayout(); - } - return new XSSFManualLayout(legend.getLayout()); - } - - public boolean isOverlay() { - return legend.getOverlay().getVal(); - } - - public void setOverlay(boolean value) { - legend.getOverlay().setVal(value); - } - - private STLegendPos.Enum fromLegendPosition(LegendPosition position) { - switch (position) { - case BOTTOM: return STLegendPos.B; - case LEFT: return STLegendPos.L; - case RIGHT: return STLegendPos.R; - case TOP: return STLegendPos.T; - case TOP_RIGHT: return STLegendPos.TR; - default: - throw new IllegalArgumentException(); - } - } - - private LegendPosition toLegendPosition(CTLegendPos ctLegendPos) { - switch (ctLegendPos.getVal().intValue()) { - case STLegendPos.INT_B: return LegendPosition.BOTTOM; - case STLegendPos.INT_L: return LegendPosition.LEFT; - case STLegendPos.INT_R: return LegendPosition.RIGHT; - case STLegendPos.INT_T: return LegendPosition.TOP; - case STLegendPos.INT_TR: return LegendPosition.TOP_RIGHT; - default: - throw new IllegalArgumentException(); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartUtil.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartUtil.java deleted file mode 100644 index d0a13b41c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartUtil.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.*; - -/** - * Package private class with utility methods. - * - * @author Roman Kashitsyn - */ -class XSSFChartUtil { - - private XSSFChartUtil() {} - - /** - * Builds CTAxDataSource object content from POI ChartDataSource. - * @param ctAxDataSource OOXML data source to build - * @param dataSource POI data source to use - */ - public static void buildAxDataSource(CTAxDataSource ctAxDataSource, ChartDataSource dataSource) { - if (dataSource.isNumeric()) { - if (dataSource.isReference()) { - buildNumRef(ctAxDataSource.addNewNumRef(), dataSource); - } else { - buildNumLit(ctAxDataSource.addNewNumLit(), dataSource); - } - } else { - if (dataSource.isReference()) { - buildStrRef(ctAxDataSource.addNewStrRef(), dataSource); - } else { - buildStrLit(ctAxDataSource.addNewStrLit(), dataSource); - } - } - } - - /** - * Builds CTNumDataSource object content from POI ChartDataSource - * @param ctNumDataSource OOXML data source to build - * @param dataSource POI data source to use - */ - public static void buildNumDataSource(CTNumDataSource ctNumDataSource, - ChartDataSource dataSource) { - if (dataSource.isReference()) { - buildNumRef(ctNumDataSource.addNewNumRef(), dataSource); - } else { - buildNumLit(ctNumDataSource.addNewNumLit(), dataSource); - } - } - - private static void buildNumRef(CTNumRef ctNumRef, ChartDataSource dataSource) { - ctNumRef.setF(dataSource.getFormulaString()); - CTNumData cache = ctNumRef.addNewNumCache(); - fillNumCache(cache, dataSource); - } - - private static void buildNumLit(CTNumData ctNumData, ChartDataSource dataSource) { - fillNumCache(ctNumData, dataSource); - } - - private static void buildStrRef(CTStrRef ctStrRef, ChartDataSource dataSource) { - ctStrRef.setF(dataSource.getFormulaString()); - CTStrData cache = ctStrRef.addNewStrCache(); - fillStringCache(cache, dataSource); - } - - private static void buildStrLit(CTStrData ctStrData, ChartDataSource dataSource) { - fillStringCache(ctStrData, dataSource); - } - - private static void fillStringCache(CTStrData cache, ChartDataSource dataSource) { - int numOfPoints = dataSource.getPointCount(); - cache.addNewPtCount().setVal(numOfPoints); - for (int i = 0; i < numOfPoints; ++i) { - Object value = dataSource.getPointAt(i); - if (value != null) { - CTStrVal ctStrVal = cache.addNewPt(); - ctStrVal.setIdx(i); - ctStrVal.setV(value.toString()); - } - } - - } - - private static void fillNumCache(CTNumData cache, ChartDataSource dataSource) { - int numOfPoints = dataSource.getPointCount(); - cache.addNewPtCount().setVal(numOfPoints); - for (int i = 0; i < numOfPoints; ++i) { - Number value = (Number) dataSource.getPointAt(i); - if (value != null) { - CTNumVal ctNumVal = cache.addNewPt(); - ctNumVal.setIdx(i); - ctNumVal.setV(value.toString()); - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java deleted file mode 100644 index 54bba03bb..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.LineChartData; -import org.apache.poi.ss.usermodel.charts.LineChartSeries; -import org.apache.poi.util.Beta; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.STMarkerStyle; - -/** - * Holds data for a XSSF Line Chart - */ -@Beta -public class XSSFLineChartData implements LineChartData { - - /** - * List of all data series. - */ - private List series; - - public XSSFLineChartData() { - series = new ArrayList(); - } - - static class Series extends AbstractXSSFChartSeries implements LineChartSeries { - private int id; - private int order; - private ChartDataSource categories; - private ChartDataSource values; - - protected Series(int id, int order, - ChartDataSource categories, - ChartDataSource values) { - this.id = id; - this.order = order; - this.categories = categories; - this.values = values; - } - - public ChartDataSource getCategoryAxisData() { - return categories; - } - - public ChartDataSource getValues() { - return values; - } - - protected void addToChart(CTLineChart ctLineChart) { - CTLineSer ctLineSer = ctLineChart.addNewSer(); - ctLineSer.addNewIdx().setVal(id); - ctLineSer.addNewOrder().setVal(order); - - // No marker symbol on the chart line. - ctLineSer.addNewMarker().addNewSymbol().setVal(STMarkerStyle.NONE); - - CTAxDataSource catDS = ctLineSer.addNewCat(); - XSSFChartUtil.buildAxDataSource(catDS, categories); - CTNumDataSource valueDS = ctLineSer.addNewVal(); - XSSFChartUtil.buildNumDataSource(valueDS, values); - - if (isTitleSet()) { - ctLineSer.setTx(getCTSerTx()); - } - } - } - - public LineChartSeries addSeries(ChartDataSource categoryAxisData, ChartDataSource values) { - if (!values.isNumeric()) { - throw new IllegalArgumentException("Value data source must be numeric."); - } - int numOfSeries = series.size(); - Series newSeries = new Series(numOfSeries, numOfSeries, categoryAxisData, values); - series.add(newSeries); - return newSeries; - } - - public List getSeries() { - return series; - } - - public void fillChart(Chart chart, ChartAxis... axis) { - if (!(chart instanceof XSSFChart)) { - throw new IllegalArgumentException("Chart must be instance of XSSFChart"); - } - - XSSFChart xssfChart = (XSSFChart) chart; - CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea(); - CTLineChart lineChart = plotArea.addNewLineChart(); - lineChart.addNewVaryColors().setVal(false); - - for (Series s : series) { - s.addToChart(lineChart); - } - - for (ChartAxis ax : axis) { - lineChart.addNewAxId().setVal(ax.getId()); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java deleted file mode 100644 index b71d0c9c1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java +++ /dev/null @@ -1,247 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.ss.usermodel.charts.ManualLayout; -import org.apache.poi.ss.usermodel.charts.LayoutMode; -import org.apache.poi.ss.usermodel.charts.LayoutTarget; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayoutMode; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayoutTarget; -import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode; - -/** - * Represents a SpreadsheetML manual layout. - * @author Roman Kashitsyn - */ -@Beta -public final class XSSFManualLayout implements ManualLayout { - - /** - * Underlaying CTManualLayout bean. - */ - private CTManualLayout layout; - - private static final LayoutMode defaultLayoutMode = LayoutMode.EDGE; - private static final LayoutTarget defaultLayoutTarget = LayoutTarget.INNER; - - /** - * Create a new SpreadsheetML manual layout. - * @param ctLayout a Spreadsheet ML layout that should be used as base. - */ - public XSSFManualLayout(CTLayout ctLayout) { - initLayout(ctLayout); - } - - /** - * Create a new SpreadsheetML manual layout for chart. - * @param chart a chart to create layout for. - */ - public XSSFManualLayout(XSSFChart chart) { - CTPlotArea ctPlotArea = chart.getCTChart().getPlotArea(); - CTLayout ctLayout = ctPlotArea.isSetLayout() ? - ctPlotArea.getLayout() : ctPlotArea.addNewLayout(); - - initLayout(ctLayout); - } - - /** - * Return the underlying CTManualLayout bean. - * - * @return the underlying CTManualLayout bean. - */ - @Internal public CTManualLayout getCTManualLayout(){ - return layout; - } - - public void setWidthRatio(double ratio) { - if (!layout.isSetW()) { - layout.addNewW(); - } - layout.getW().setVal(ratio); - } - - public double getWidthRatio() { - if (!layout.isSetW()) { - return 0.0; - } - return layout.getW().getVal(); - } - - public void setHeightRatio(double ratio) { - if (!layout.isSetH()) { - layout.addNewH(); - } - layout.getH().setVal(ratio); - } - - public double getHeightRatio() { - if (!layout.isSetH()) { - return 0.0; - } - return layout.getH().getVal(); - } - - public LayoutTarget getTarget() { - if (!layout.isSetLayoutTarget()) { - return defaultLayoutTarget; - } - return toLayoutTarget(layout.getLayoutTarget()); - } - - public void setTarget(LayoutTarget target) { - if (!layout.isSetLayoutTarget()) { - layout.addNewLayoutTarget(); - } - layout.getLayoutTarget().setVal(fromLayoutTarget(target)); - } - - public LayoutMode getXMode() { - if (!layout.isSetXMode()) { - return defaultLayoutMode; - } - return toLayoutMode(layout.getXMode()); - } - - public void setXMode(LayoutMode mode) { - if (!layout.isSetXMode()) { - layout.addNewXMode(); - } - layout.getXMode().setVal(fromLayoutMode(mode)); - } - - public LayoutMode getYMode() { - if (!layout.isSetYMode()) { - return defaultLayoutMode; - } - return toLayoutMode(layout.getYMode()); - } - - public void setYMode(LayoutMode mode) { - if (!layout.isSetYMode()) { - layout.addNewYMode(); - } - layout.getYMode().setVal(fromLayoutMode(mode)); - } - - public double getX() { - if (!layout.isSetX()) { - return 0.0; - } - return layout.getX().getVal(); - } - - public void setX(double x) { - if (!layout.isSetX()) { - layout.addNewX(); - } - layout.getX().setVal(x); - } - - public double getY() { - if (!layout.isSetY()) { - return 0.0; - } - return layout.getY().getVal(); - } - - public void setY(double y) { - if (!layout.isSetY()) { - layout.addNewY(); - } - layout.getY().setVal(y); - } - - public LayoutMode getWidthMode() { - if (!layout.isSetWMode()) { - return defaultLayoutMode; - } - return toLayoutMode(layout.getWMode()); - } - - public void setWidthMode(LayoutMode mode) { - if (!layout.isSetWMode()) { - layout.addNewWMode(); - } - layout.getWMode().setVal(fromLayoutMode(mode)); - } - - public LayoutMode getHeightMode() { - if (!layout.isSetHMode()) { - return defaultLayoutMode; - } - return toLayoutMode(layout.getHMode()); - } - - public void setHeightMode(LayoutMode mode) { - if (!layout.isSetHMode()) { - layout.addNewHMode(); - } - layout.getHMode().setVal(fromLayoutMode(mode)); - } - - private void initLayout(CTLayout ctLayout) { - if (ctLayout.isSetManualLayout()) { - this.layout = ctLayout.getManualLayout(); - } else { - this.layout = ctLayout.addNewManualLayout(); - } - } - - private STLayoutMode.Enum fromLayoutMode(LayoutMode mode) { - switch (mode) { - case EDGE: return STLayoutMode.EDGE; - case FACTOR: return STLayoutMode.FACTOR; - default: - throw new IllegalArgumentException(); - } - } - - private LayoutMode toLayoutMode(CTLayoutMode ctLayoutMode) { - switch (ctLayoutMode.getVal().intValue()) { - case STLayoutMode.INT_EDGE: return LayoutMode.EDGE; - case STLayoutMode.INT_FACTOR: return LayoutMode.FACTOR; - default: - throw new IllegalArgumentException(); - } - } - - private STLayoutTarget.Enum fromLayoutTarget(LayoutTarget target) { - switch (target) { - case INNER: return STLayoutTarget.INNER; - case OUTER: return STLayoutTarget.OUTER; - default: - throw new IllegalArgumentException(); - } - } - - private LayoutTarget toLayoutTarget(CTLayoutTarget ctLayoutTarget) { - switch (ctLayoutTarget.getVal().intValue()) { - case STLayoutTarget.INT_INNER: return LayoutTarget.INNER; - case STLayoutTarget.INT_OUTER: return LayoutTarget.OUTER; - default: - throw new IllegalArgumentException(); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java deleted file mode 100644 index f31b35503..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.ScatterChartData; -import org.apache.poi.ss.usermodel.charts.ScatterChartSeries; -import org.apache.poi.util.Beta; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterStyle; -import org.openxmlformats.schemas.drawingml.x2006.chart.STScatterStyle; - - -/** - * Represents DrawingML scatter charts. - */ -@Beta -public class XSSFScatterChartData implements ScatterChartData { - - /** - * List of all data series. - */ - private List series; - - public XSSFScatterChartData() { - series = new ArrayList(); - } - - /** - * Package private ScatterChartSerie implementation. - */ - static class Series extends AbstractXSSFChartSeries implements ScatterChartSeries { - private int id; - private int order; - private ChartDataSource xs; - private ChartDataSource ys; - - protected Series(int id, int order, - ChartDataSource xs, - ChartDataSource ys) { - super(); - this.id = id; - this.order = order; - this.xs = xs; - this.ys = ys; - } - - /** - * Returns data source used for X axis values. - * @return data source used for X axis values - */ - public ChartDataSource getXValues() { - return xs; - } - - /** - * Returns data source used for Y axis values. - * @return data source used for Y axis values - */ - public ChartDataSource getYValues() { - return ys; - } - - protected void addToChart(CTScatterChart ctScatterChart) { - CTScatterSer scatterSer = ctScatterChart.addNewSer(); - scatterSer.addNewIdx().setVal(this.id); - scatterSer.addNewOrder().setVal(this.order); - - CTAxDataSource xVal = scatterSer.addNewXVal(); - XSSFChartUtil.buildAxDataSource(xVal, xs); - - CTNumDataSource yVal = scatterSer.addNewYVal(); - XSSFChartUtil.buildNumDataSource(yVal, ys); - - if (isTitleSet()) { - scatterSer.setTx(getCTSerTx()); - } - } - } - - public ScatterChartSeries addSerie(ChartDataSource xs, - ChartDataSource ys) { - if (!ys.isNumeric()) { - throw new IllegalArgumentException("Y axis data source must be numeric."); - } - int numOfSeries = series.size(); - Series newSerie = new Series(numOfSeries, numOfSeries, xs, ys); - series.add(newSerie); - return newSerie; - } - - public void fillChart(Chart chart, ChartAxis... axis) { - if (!(chart instanceof XSSFChart)) { - throw new IllegalArgumentException("Chart must be instance of XSSFChart"); - } - - XSSFChart xssfChart = (XSSFChart) chart; - CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea(); - CTScatterChart scatterChart = plotArea.addNewScatterChart(); - addStyle(scatterChart); - - for (Series s : series) { - s.addToChart(scatterChart); - } - - for (ChartAxis ax : axis) { - scatterChart.addNewAxId().setVal(ax.getId()); - } - } - - public List getSeries() { - return series; - } - - private void addStyle(CTScatterChart ctScatterChart) { - CTScatterStyle scatterStyle = ctScatterChart.addNewScatterStyle(); - scatterStyle.setVal(STScatterStyle.LINE_MARKER); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java deleted file mode 100644 index 7fc0718a9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java +++ /dev/null @@ -1,153 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ValueAxis; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.AxisOrientation; -import org.apache.poi.ss.usermodel.charts.AxisCrossBetween; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisTickMark; - -import org.apache.poi.util.Beta; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTTickMark; -import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween; -import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; - -/** - * Value axis type. - * - * @author Roman Kashitsyn - */ -@Beta -public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis { - - private CTValAx ctValAx; - - public XSSFValueAxis(XSSFChart chart, long id, AxisPosition pos) { - super(chart); - createAxis(id, pos); - } - - public XSSFValueAxis(XSSFChart chart, CTValAx ctValAx) { - super(chart); - this.ctValAx = ctValAx; - } - - public long getId() { - return ctValAx.getAxId().getVal(); - } - - public void setCrossBetween(AxisCrossBetween crossBetween) { - ctValAx.getCrossBetween().setVal(fromCrossBetween(crossBetween)); - } - - public AxisCrossBetween getCrossBetween() { - return toCrossBetween(ctValAx.getCrossBetween().getVal()); - } - - @Override - protected CTAxPos getCTAxPos() { - return ctValAx.getAxPos(); - } - - @Override - protected CTNumFmt getCTNumFmt() { - if (ctValAx.isSetNumFmt()) { - return ctValAx.getNumFmt(); - } - return ctValAx.addNewNumFmt(); - } - - @Override - protected CTScaling getCTScaling() { - return ctValAx.getScaling(); - } - - @Override - protected CTCrosses getCTCrosses() { - return ctValAx.getCrosses(); - } - - @Override - protected CTBoolean getDelete() { - return ctValAx.getDelete(); - } - - @Override - protected CTTickMark getMajorCTTickMark() { - return ctValAx.getMajorTickMark(); - } - - @Override - protected CTTickMark getMinorCTTickMark() { - return ctValAx.getMinorTickMark(); - } - - public void crossAxis(ChartAxis axis) { - ctValAx.getCrossAx().setVal(axis.getId()); - } - - private void createAxis(long id, AxisPosition pos) { - ctValAx = chart.getCTChart().getPlotArea().addNewValAx(); - ctValAx.addNewAxId().setVal(id); - ctValAx.addNewAxPos(); - ctValAx.addNewScaling(); - ctValAx.addNewCrossBetween(); - ctValAx.addNewCrosses(); - ctValAx.addNewCrossAx(); - ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); - ctValAx.addNewDelete(); - ctValAx.addNewMajorTickMark(); - ctValAx.addNewMinorTickMark(); - - setPosition(pos); - setOrientation(AxisOrientation.MIN_MAX); - setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); - setCrosses(AxisCrosses.AUTO_ZERO); - setVisible(true); - setMajorTickMark(AxisTickMark.CROSS); - setMinorTickMark(AxisTickMark.NONE); - } - - private static STCrossBetween.Enum fromCrossBetween(AxisCrossBetween crossBetween) { - switch (crossBetween) { - case BETWEEN: return STCrossBetween.BETWEEN; - case MIDPOINT_CATEGORY: return STCrossBetween.MID_CAT; - default: - throw new IllegalArgumentException(); - } - } - - private static AxisCrossBetween toCrossBetween(STCrossBetween.Enum ctCrossBetween) { - switch (ctCrossBetween.intValue()) { - case STCrossBetween.INT_BETWEEN: return AxisCrossBetween.BETWEEN; - case STCrossBetween.INT_MID_CAT: return AxisCrossBetween.MIDPOINT_CATEGORY; - default: - throw new IllegalArgumentException(); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellAlignment.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellAlignment.java deleted file mode 100644 index 06e5d0bf6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellAlignment.java +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellAlignment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STHorizontalAlignment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignment; - - -/** - * Cell settings available in the Format/Alignment tab - */ -public class XSSFCellAlignment { - private CTCellAlignment cellAlignement; - - /** - * Creates a Cell Alignment from the supplied XML definition - * - * @param cellAlignment - */ - public XSSFCellAlignment(CTCellAlignment cellAlignment) { - this.cellAlignement = cellAlignment; - } - - /** - * Get the type of vertical alignment for the cell - * - * @return the type of aligment - * @see VerticalAlignment - */ - public VerticalAlignment getVertical() { - STVerticalAlignment.Enum align = cellAlignement.getVertical(); - if (align == null) align = STVerticalAlignment.BOTTOM; - - return VerticalAlignment.values()[align.intValue() - 1]; - } - - /** - * Set the type of vertical alignment for the cell - * - * @param align - the type of alignment - * @see VerticalAlignment - */ - public void setVertical(VerticalAlignment align) { - cellAlignement.setVertical(STVerticalAlignment.Enum.forInt(align.ordinal() + 1)); - } - - /** - * Get the type of horizontal alignment for the cell - * - * @return the type of aligment - * @see HorizontalAlignment - */ - public HorizontalAlignment getHorizontal() { - STHorizontalAlignment.Enum align = cellAlignement.getHorizontal(); - if (align == null) align = STHorizontalAlignment.GENERAL; - - return HorizontalAlignment.values()[align.intValue() - 1]; - } - - /** - * Set the type of horizontal alignment for the cell - * - * @param align - the type of alignment - * @see HorizontalAlignment - */ - public void setHorizontal(HorizontalAlignment align) { - cellAlignement.setHorizontal(STHorizontalAlignment.Enum.forInt(align.ordinal() + 1)); - } - - /** - * Get the number of spaces to indent the text in the cell - * - * @return indent - number of spaces - */ - public long getIndent() { - return cellAlignement.getIndent(); - } - - /** - * Set the number of spaces to indent the text in the cell - * - * @param indent - number of spaces - */ - public void setIndent(long indent) { - cellAlignement.setIndent(indent); - } - - /** - * Get the degree of rotation for the text in the cell - *

        - * Expressed in degrees. Values range from 0 to 180. The first letter of - * the text is considered the center-point of the arc. - *
        - * For 0 - 90, the value represents degrees above horizon. For 91-180 the degrees below the - * horizon is calculated as: - *
        - * [degrees below horizon] = 90 - textRotation. - *

        - * - * @return rotation degrees (between 0 and 180 degrees) - */ - public long getTextRotation() { - return cellAlignement.getTextRotation(); - } - - /** - * Set the degree of rotation for the text in the cell - *

        - * Expressed in degrees. Values range from 0 to 180. The first letter of - * the text is considered the center-point of the arc. - *
        - * For 0 - 90, the value represents degrees above horizon. For 91-180 the degrees below the - * horizon is calculated as: - *
        - * [degrees below horizon] = 90 - textRotation. - *

        - * - * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF - * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges - * accordingly, however the corresponding getter is returning values in the range mandated by the current type - * of Excel file-format that this CellStyle is applied to. - * - * @param rotation - the rotation degrees (between 0 and 180 degrees) - */ - public void setTextRotation(long rotation) { - if(rotation < 0 && rotation >= -90) { - rotation = 90 + ((-1)*rotation); - } - cellAlignement.setTextRotation(rotation); - } - - /** - * Whether the text should be wrapped - * - * @return a boolean value indicating if the text in a cell should be line-wrapped within the cell. - */ - public boolean getWrapText() { - return cellAlignement.getWrapText(); - } - - /** - * Set whether the text should be wrapped - * - * @param wrapped a boolean value indicating if the text in a cell should be line-wrapped within the cell. - */ - public void setWrapText(boolean wrapped) { - cellAlignement.setWrapText(wrapped); - } - - public boolean getShrinkToFit() { - return cellAlignement.getShrinkToFit(); - } - - public void setShrinkToFit(boolean shrink) { - cellAlignement.setShrinkToFit(shrink); - } - - /** - * Access to low-level data - */ - @Internal - public CTCellAlignment getCTCellAlignment() { - return cellAlignement; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellBorder.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellBorder.java deleted file mode 100644 index b100bc210..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellBorder.java +++ /dev/null @@ -1,185 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.xssf.model.ThemesTable; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; - -/** - * This element contains border formatting information, specifying border definition formats (left, right, top, bottom, diagonal) - * for cells in the workbook. - * Color is optional. - */ -public class XSSFCellBorder { - private ThemesTable _theme; - private CTBorder border; - - /** - * Creates a Cell Border from the supplied XML definition - */ - public XSSFCellBorder(CTBorder border, ThemesTable theme) { - this(border); - this._theme = theme; - } - - /** - * Creates a Cell Border from the supplied XML definition - */ - public XSSFCellBorder(CTBorder border) { - this.border = border; - } - - /** - * Creates a new, empty Cell Border. - * You need to attach this to the Styles Table - */ - public XSSFCellBorder() { - border = CTBorder.Factory.newInstance(); - } - - /** - * Records the Themes Table that is associated with - * the current font, used when looking up theme - * based colours and properties. - */ - public void setThemesTable(ThemesTable themes) { - this._theme = themes; - } - - /** - * The enumeration value indicating the side being used for a cell border. - */ - public static enum BorderSide { - TOP, RIGHT, BOTTOM, LEFT - } - - /** - * Returns the underlying XML bean. - * - * @return CTBorder - */ - @Internal - public CTBorder getCTBorder() { - return border; - } - - /** - * Get the type of border to use for the selected border - * - * @param side - - where to apply the color definition - * @return borderstyle - the type of border to use. default value is NONE if border style is not set. - * @see BorderStyle - */ - public BorderStyle getBorderStyle(BorderSide side) { - CTBorderPr ctBorder = getBorder(side); - STBorderStyle.Enum border = ctBorder == null ? STBorderStyle.NONE : ctBorder.getStyle(); - return BorderStyle.values()[border.intValue() - 1]; - } - - /** - * Set the type of border to use for the selected border - * - * @param side - - where to apply the color definition - * @param style - border style - * @see BorderStyle - */ - public void setBorderStyle(BorderSide side, BorderStyle style) { - getBorder(side, true).setStyle(STBorderStyle.Enum.forInt(style.ordinal() + 1)); - } - - /** - * Get the color to use for the selected border - * - * @param side - where to apply the color definition - * @return color - color to use as XSSFColor. null if color is not set - */ - public XSSFColor getBorderColor(BorderSide side) { - CTBorderPr borderPr = getBorder(side); - - if(borderPr != null && borderPr.isSetColor()) { - XSSFColor clr = new XSSFColor(borderPr.getColor()); - if(_theme != null) { - _theme.inheritFromThemeAsRequired(clr); - } - return clr; - } else { - // No border set - return null; - } - } - - /** - * Set the color to use for the selected border - * - * @param side - where to apply the color definition - * @param color - the color to use - */ - public void setBorderColor(BorderSide side, XSSFColor color) { - CTBorderPr borderPr = getBorder(side, true); - if (color == null) borderPr.unsetColor(); - else - borderPr.setColor(color.getCTColor()); - } - - private CTBorderPr getBorder(BorderSide side) { - return getBorder(side, false); - } - - - private CTBorderPr getBorder(BorderSide side, boolean ensure) { - CTBorderPr borderPr; - switch (side) { - case TOP: - borderPr = border.getTop(); - if (ensure && borderPr == null) borderPr = border.addNewTop(); - break; - case RIGHT: - borderPr = border.getRight(); - if (ensure && borderPr == null) borderPr = border.addNewRight(); - break; - case BOTTOM: - borderPr = border.getBottom(); - if (ensure && borderPr == null) borderPr = border.addNewBottom(); - break; - case LEFT: - borderPr = border.getLeft(); - if (ensure && borderPr == null) borderPr = border.addNewLeft(); - break; - default: - throw new IllegalArgumentException("No suitable side specified for the border"); - } - return borderPr; - } - - - public int hashCode() { - return border.toString().hashCode(); - } - - public boolean equals(Object o) { - if (!(o instanceof XSSFCellBorder)) return false; - - XSSFCellBorder cf = (XSSFCellBorder) o; - return border.toString().equals(cf.getCTBorder().toString()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellFill.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellFill.java deleted file mode 100644 index fd6a70ef4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellFill.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.util.Internal; - -/** - * This element specifies fill formatting. - * A cell fill consists of a background color, foreground color, and pattern to be applied across the cell. - */ -public final class XSSFCellFill { - - private CTFill _fill; - - /** - * Creates a CellFill from the supplied parts - * - * @param fill - fill - */ - public XSSFCellFill(CTFill fill) { - _fill = fill; - } - - /** - * Creates an empty CellFill - */ - public XSSFCellFill() { - _fill = CTFill.Factory.newInstance(); - } - - /** - * Get the background fill color. - * - * @return fill color, null if color is not set - */ - public XSSFColor getFillBackgroundColor() { - CTPatternFill ptrn = _fill.getPatternFill(); - if (ptrn == null) return null; - - CTColor ctColor = ptrn.getBgColor(); - return ctColor == null ? null : new XSSFColor(ctColor); - } - - /** - * Set the background fill color represented as a indexed color value. - * - * @param index - */ - public void setFillBackgroundColor(int index) { - CTPatternFill ptrn = ensureCTPatternFill(); - CTColor ctColor = ptrn.isSetBgColor() ? ptrn.getBgColor() : ptrn.addNewBgColor(); - ctColor.setIndexed(index); - } - - /** - * Set the background fill color represented as a {@link XSSFColor} value. - * - * @param color - */ - public void setFillBackgroundColor(XSSFColor color) { - CTPatternFill ptrn = ensureCTPatternFill(); - ptrn.setBgColor(color.getCTColor()); - } - - /** - * Get the foreground fill color. - * - * @return XSSFColor - foreground color. null if color is not set - */ - public XSSFColor getFillForegroundColor() { - CTPatternFill ptrn = _fill.getPatternFill(); - if (ptrn == null) return null; - - CTColor ctColor = ptrn.getFgColor(); - return ctColor == null ? null : new XSSFColor(ctColor); - } - - /** - * Set the foreground fill color as a indexed color value - * - * @param index - the color to use - */ - public void setFillForegroundColor(int index) { - CTPatternFill ptrn = ensureCTPatternFill(); - CTColor ctColor = ptrn.isSetFgColor() ? ptrn.getFgColor() : ptrn.addNewFgColor(); - ctColor.setIndexed(index); - } - - /** - * Set the foreground fill color represented as a {@link XSSFColor} value. - * - * @param color - the color to use - */ - public void setFillForegroundColor(XSSFColor color) { - CTPatternFill ptrn = ensureCTPatternFill(); - ptrn.setFgColor(color.getCTColor()); - } - - /** - * get the fill pattern - * - * @return fill pattern type. null if fill pattern is not set - */ - public STPatternType.Enum getPatternType() { - CTPatternFill ptrn = _fill.getPatternFill(); - return ptrn == null ? null : ptrn.getPatternType(); - } - - /** - * set the fill pattern - * - * @param patternType fill pattern to use - */ - public void setPatternType(STPatternType.Enum patternType) { - CTPatternFill ptrn = ensureCTPatternFill(); - ptrn.setPatternType(patternType); - } - - private CTPatternFill ensureCTPatternFill() { - CTPatternFill patternFill = _fill.getPatternFill(); - if (patternFill == null) { - patternFill = _fill.addNewPatternFill(); - } - return patternFill; - } - - /** - * Returns the underlying XML bean. - * - * @return CTFill - */ - @Internal - public CTFill getCTFill() { - return _fill; - } - - - public int hashCode() { - return _fill.toString().hashCode(); - } - - public boolean equals(Object o) { - if (!(o instanceof XSSFCellFill)) return false; - - XSSFCellFill cf = (XSSFCellFill) o; - return _fill.toString().equals(cf.getCTFill().toString()); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFHeaderFooter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFHeaderFooter.java deleted file mode 100644 index 62267f2c7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFHeaderFooter.java +++ /dev/null @@ -1,237 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - -import org.apache.poi.ss.usermodel.HeaderFooter; -import org.apache.poi.xssf.usermodel.helpers.HeaderFooterHelper; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -/** - * Parent class of all XSSF headers and footers. - * - * For a list of all the different fields that can be placed into a header or - * footer, such as page number, bold, underline etc, see the follow formatting - * syntax - * - * Header/Footer Formatting Syntax - *

        - * There are a number of formatting codes that can be written inline with the - * actual header / footer text, which affect the formatting in the header or - * footer. - *

        - * - * This example shows the text "Center Bold Header" on the first line (center - * section), and the date on the second line (center section). &CCenter - * &"-,Bold"Bold &"-,Regular"Header_x000A_&D - * - * General Rules: There is no required order in which these codes must - * appear. The first occurrence of the following codes turns the formatting ON, - * the second occurrence turns it OFF again: - * - *
        - *
        &L
        - *
        code for "left section" (there are three header / footer locations, - * "left", "center", and "right"). When two or more occurrences of this section - * marker exist, the contents from all markers are concatenated, in the order of - * appearance, and placed into the left section.
        - *
        &P
        - *
        code for "current page #"
        - *
        &N
        - *
        code for "total pages"
        - *
        &font size
        - *
        code for "text font size", where font size is a font size in points.
        - *
        &K
        - *
        code for "text font color" RGB Color is specified as RRGGBB Theme Color - * is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" - * of the tint/shade value, NN is the tint/shade value.
        - *
        &S
        - *
        code for "text strikethrough" on / off
        - *
        &X
        - *
        code for "text super script" on / off
        - *
        &Y
        - *
        code for "text subscript" on / off
        - *
        &C
        - *
        code for "center section". When two or more occurrences of this section - * marker exist, the contents from all markers are concatenated, in the order of - * appearance, and placed into the center section. SpreadsheetML Reference - * Material - Worksheets 1966
        - *
        &D
        - *
        code for "date"
        - *
        &T
        - *
        code for "time"
        - *
        &G
        - *
        code for "picture as background"
        - *
        &U
        - *
        code for "text single underline"
        - *
        &E
        - *
        code for "double underline"
        - *
        &R
        - *
        code for "right section". When two or more occurrences of this section - * marker exist, the contents from all markers are concatenated, in the order of - * appearance, and placed into the right section.
        - *
        &Z
        - *
        code for "this workbook's file path"
        - *
        &F
        - *
        code for "this workbook's file name"
        - *
        &A
        - *
        code for "sheet tab name"
        - *
        &+
        - *
        code for add to page #.
        - *
        &-
        - *
        code for subtract from page #.
        - *
        &"font name,font type" - code for "text font name" and "text font type", - * where font name and font type are strings specifying the name and type of the - * font, separated by a comma. When a hyphen appears in font name, it means - * "none specified". Both of font name and font type can be localized - * values. - *
        &"-,Bold"
        - *
        code for "bold font style"
        - *
        &B
        - *
        also means "bold font style"
        - *
        &"-,Regular"
        - *
        code for "regular font style"
        - *
        &"-,Italic"
        - *
        code for "italic font style"
        - *
        &I
        - *
        also means "italic font style"
        - *
        &"-,Bold Italic"
        - *
        code for "bold italic font style"
        - *
        &O
        - *
        code for "outline style"
        - *
        &H
        - *
        code for "shadow style"
        - *
        - * - * - */ -public abstract class XSSFHeaderFooter implements HeaderFooter { - private HeaderFooterHelper helper; - private CTHeaderFooter headerFooter; - - private boolean stripFields = false; - - /** - * Create an instance of XSSFHeaderFooter from the supplied XML bean - * - * @param headerFooter - */ - public XSSFHeaderFooter(CTHeaderFooter headerFooter) { - this.headerFooter = headerFooter; - this.helper = new HeaderFooterHelper(); - } - - /** - * Returns the underlying CTHeaderFooter xml bean - * - * @return the underlying CTHeaderFooter xml bean - */ - @Internal - public CTHeaderFooter getHeaderFooter() { - return this.headerFooter; - } - - public String getValue() { - String value = getText(); - if (value == null) - return ""; - return value; - } - - /** - * Are fields currently being stripped from the text that this - * {@link XSSFHeaderFooter} returns? Default is false, but can be changed - */ - public boolean areFieldsStripped() { - return stripFields; - } - - /** - * Should fields (eg macros) be stripped from the text that this class - * returns? Default is not to strip. - * - * @param stripFields - */ - public void setAreFieldsStripped(boolean stripFields) { - this.stripFields = stripFields; - } - - /** - * Removes any fields (eg macros, page markers etc) from the string. - * Normally used to make some text suitable for showing to humans, and the - * resultant text should not normally be saved back into the document! - */ - public static String stripFields(String text) { - return org.apache.poi.hssf.usermodel.HeaderFooter.stripFields(text); - } - - public abstract String getText(); - - protected abstract void setText(String text); - - /** - * get the text representing the center part of this element - */ - public String getCenter() { - String text = helper.getCenterSection(getText()); - if (stripFields) - return stripFields(text); - return text; - } - - /** - * get the text representing the left part of this element - */ - public String getLeft() { - String text = helper.getLeftSection(getText()); - if (stripFields) - return stripFields(text); - return text; - } - - /** - * get the text representing the right part of this element - */ - public String getRight() { - String text = helper.getRightSection(getText()); - if (stripFields) - return stripFields(text); - return text; - } - - /** - * set a centered string value for this element - */ - public void setCenter(String newCenter) { - setText(helper.setCenterSection(getText(), newCenter)); - } - - /** - * set a left string value for this element - */ - public void setLeft(String newLeft) { - setText(helper.setLeftSection(getText(), newLeft)); - } - - /** - * set a right string value for this element - */ - public void setRight(String newRight) { - setText(helper.setRightSection(getText(), newRight)); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java deleted file mode 100644 index b27100656..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java +++ /dev/null @@ -1,332 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.NavigableSet; -import java.util.TreeSet; - -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.xssf.util.CTColComparator; -import org.apache.poi.xssf.util.NumericRanges; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; - -/** - * Helper class for dealing with the Column settings on - * a CTWorksheet (the data part of a sheet). - * Note - within POI, we use 0 based column indexes, but - * the column definitions in the XML are 1 based! - */ -public class ColumnHelper { - - private CTWorksheet worksheet; - - public ColumnHelper(CTWorksheet worksheet) { - super(); - this.worksheet = worksheet; - cleanColumns(); - } - - public void cleanColumns() { - TreeSet trackedCols = new TreeSet(CTColComparator.BY_MIN_MAX); - CTCols newCols = CTCols.Factory.newInstance(); - CTCols[] colsArray = worksheet.getColsArray(); - int i = 0; - for (i = 0; i < colsArray.length; i++) { - CTCols cols = colsArray[i]; - CTCol[] colArray = cols.getColArray(); - for (CTCol col : colArray) { - addCleanColIntoCols(newCols, col, trackedCols); - } - } - for (int y = i - 1; y >= 0; y--) { - worksheet.removeCols(y); - } - - newCols.setColArray(trackedCols.toArray(new CTCol[trackedCols.size()])); - worksheet.addNewCols(); - worksheet.setColsArray(0, newCols); - } - - public CTCols addCleanColIntoCols(CTCols cols, CTCol newCol) { - // Performance issue. If we encapsulated management of min/max in this - // class then we could keep trackedCols as state, - // making this log(N) rather than Nlog(N). We do this for the initial - // read above. - TreeSet trackedCols = new TreeSet( - CTColComparator.BY_MIN_MAX); - trackedCols.addAll(cols.getColList()); - addCleanColIntoCols(cols, newCol, trackedCols); - cols.setColArray(trackedCols.toArray(new CTCol[0])); - return cols; - } - - private void addCleanColIntoCols(final CTCols cols, final CTCol newCol, final TreeSet trackedCols) { - List overlapping = getOverlappingCols(newCol, trackedCols); - if (overlapping.isEmpty()) { - trackedCols.add(cloneCol(cols, newCol)); - return; - } - - trackedCols.removeAll(overlapping); - for (CTCol existing : overlapping) { - // We add up to three columns for each existing one: non-overlap - // before, overlap, non-overlap after. - long[] overlap = getOverlap(newCol, existing); - - CTCol overlapCol = cloneCol(cols, existing, overlap); - setColumnAttributes(newCol, overlapCol); - trackedCols.add(overlapCol); - - CTCol beforeCol = existing.getMin() < newCol.getMin() ? existing - : newCol; - long[] before = new long[] { - Math.min(existing.getMin(), newCol.getMin()), - overlap[0] - 1 }; - if (before[0] <= before[1]) { - trackedCols.add(cloneCol(cols, beforeCol, before)); - } - - CTCol afterCol = existing.getMax() > newCol.getMax() ? existing - : newCol; - long[] after = new long[] { overlap[1] + 1, - Math.max(existing.getMax(), newCol.getMax()) }; - if (after[0] <= after[1]) { - trackedCols.add(cloneCol(cols, afterCol, after)); - } - } - } - - private CTCol cloneCol(final CTCols cols, final CTCol col, final long[] newRange) { - CTCol cloneCol = cloneCol(cols, col); - cloneCol.setMin(newRange[0]); - cloneCol.setMax(newRange[1]); - return cloneCol; - } - - private long[] getOverlap(final CTCol col1, final CTCol col2) { - return getOverlappingRange(col1, col2); - } - - private List getOverlappingCols(final CTCol newCol, final TreeSet trackedCols) { - CTCol lower = trackedCols.lower(newCol); - NavigableSet potentiallyOverlapping = lower == null ? trackedCols : trackedCols.tailSet(lower, overlaps(lower, newCol)); - List overlapping = new ArrayList(); - for (CTCol existing : potentiallyOverlapping) { - if (overlaps(newCol, existing)) { - overlapping.add(existing); - } else { - break; - } - } - return overlapping; - } - - private boolean overlaps(final CTCol col1, final CTCol col2) { - return NumericRanges.getOverlappingType(toRange(col1), toRange(col2)) != NumericRanges.NO_OVERLAPS; - } - - private long[] getOverlappingRange(final CTCol col1, final CTCol col2) { - return NumericRanges.getOverlappingRange(toRange(col1), toRange(col2)); - } - - private long[] toRange(final CTCol col) { - return new long[] { col.getMin(), col.getMax() }; - } - - public static void sortColumns(CTCols newCols) { - CTCol[] colArray = newCols.getColArray(); - Arrays.sort(colArray, CTColComparator.BY_MIN_MAX); - newCols.setColArray(colArray); - } - - public CTCol cloneCol(CTCols cols, CTCol col) { - CTCol newCol = cols.addNewCol(); - newCol.setMin(col.getMin()); - newCol.setMax(col.getMax()); - setColumnAttributes(col, newCol); - return newCol; - } - - /** - * Returns the Column at the given 0 based index - */ - public CTCol getColumn(long index, boolean splitColumns) { - return getColumn1Based(index+1, splitColumns); - } - - /** - * Returns the Column at the given 1 based index. - * POI default is 0 based, but the file stores - * as 1 based. - */ - public CTCol getColumn1Based(long index1, boolean splitColumns) { - CTCols cols = worksheet.getColsArray(0); - - // Fetching the array is quicker than working on the new style - // list, assuming we need to read many of them (which we often do), - // and assuming we're not making many changes (which we're not) - CTCol[] colArray = cols.getColArray(); - - for (CTCol col : colArray) { - long colMin = col.getMin(); - long colMax = col.getMax(); - if (colMin <= index1 && colMax >= index1) { - if (splitColumns) { - if (colMin < index1) { - insertCol(cols, colMin, (index1 - 1), new CTCol[]{col}); - } - if (colMax > index1) { - insertCol(cols, (index1 + 1), colMax, new CTCol[]{col}); - } - col.setMin(index1); - col.setMax(index1); - } - return col; - } - } - return null; - } - - /* - * Insert a new CTCol at position 0 into cols, setting min=min, max=max and - * copying all the colsWithAttributes array cols attributes into newCol - */ - private CTCol insertCol(CTCols cols, long min, long max, CTCol[] colsWithAttributes) { - return insertCol(cols, min, max, colsWithAttributes, false, null); - } - - private CTCol insertCol(CTCols cols, long min, long max, - CTCol[] colsWithAttributes, boolean ignoreExistsCheck, CTCol overrideColumn) { - if(ignoreExistsCheck || !columnExists(cols,min,max)){ - CTCol newCol = cols.insertNewCol(0); - newCol.setMin(min); - newCol.setMax(max); - for (CTCol col : colsWithAttributes) { - setColumnAttributes(col, newCol); - } - if (overrideColumn != null) setColumnAttributes(overrideColumn, newCol); - return newCol; - } - return null; - } - - /** - * Does the column at the given 0 based index exist - * in the supplied list of column definitions? - */ - public boolean columnExists(CTCols cols, long index) { - return columnExists1Based(cols, index+1); - } - - private boolean columnExists1Based(CTCols cols, long index1) { - for (CTCol col : cols.getColArray()) { - if (col.getMin() == index1) { - return true; - } - } - return false; - } - - public void setColumnAttributes(CTCol fromCol, CTCol toCol) { - if(fromCol.isSetBestFit()) toCol.setBestFit(fromCol.getBestFit()); - if(fromCol.isSetCustomWidth()) toCol.setCustomWidth(fromCol.getCustomWidth()); - if(fromCol.isSetHidden()) toCol.setHidden(fromCol.getHidden()); - if(fromCol.isSetStyle()) toCol.setStyle(fromCol.getStyle()); - if(fromCol.isSetWidth()) toCol.setWidth(fromCol.getWidth()); - if(fromCol.isSetCollapsed()) toCol.setCollapsed(fromCol.getCollapsed()); - if(fromCol.isSetPhonetic()) toCol.setPhonetic(fromCol.getPhonetic()); - if(fromCol.isSetOutlineLevel()) toCol.setOutlineLevel(fromCol.getOutlineLevel()); - toCol.setCollapsed(fromCol.isSetCollapsed()); - } - - public void setColBestFit(long index, boolean bestFit) { - CTCol col = getOrCreateColumn1Based(index+1, false); - col.setBestFit(bestFit); - } - public void setCustomWidth(long index, boolean bestFit) { - CTCol col = getOrCreateColumn1Based(index+1, true); - col.setCustomWidth(bestFit); - } - - public void setColWidth(long index, double width) { - CTCol col = getOrCreateColumn1Based(index+1, true); - col.setWidth(width); - } - - public void setColHidden(long index, boolean hidden) { - CTCol col = getOrCreateColumn1Based(index+1, true); - col.setHidden(hidden); - } - - /** - * Return the CTCol at the given (0 based) column index, - * creating it if required. - */ - protected CTCol getOrCreateColumn1Based(long index1, boolean splitColumns) { - CTCol col = getColumn1Based(index1, splitColumns); - if (col == null) { - col = worksheet.getColsArray(0).addNewCol(); - col.setMin(index1); - col.setMax(index1); - } - return col; - } - - public void setColDefaultStyle(long index, CellStyle style) { - setColDefaultStyle(index, style.getIndex()); - } - - public void setColDefaultStyle(long index, int styleId) { - CTCol col = getOrCreateColumn1Based(index+1, true); - col.setStyle(styleId); - } - - // Returns -1 if no column is found for the given index - public int getColDefaultStyle(long index) { - if (getColumn(index, false) != null) { - return (int) getColumn(index, false).getStyle(); - } - return -1; - } - - private boolean columnExists(CTCols cols, long min, long max) { - for (CTCol col : cols.getColArray()) { - if (col.getMin() == min && col.getMax() == max) { - return true; - } - } - return false; - } - - public int getIndexOfColumn(CTCols cols, CTCol searchCol) { - if (cols == null || searchCol == null) return -1; - int i = 0; - for (CTCol col : cols.getColArray()) { - if (col.getMin() == searchCol.getMin() && col.getMax() == searchCol.getMax()) { - return i; - } - i++; - } - return -1; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/HeaderFooterHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/HeaderFooterHelper.java deleted file mode 100644 index 41e3ea462..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/HeaderFooterHelper.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - - -public class HeaderFooterHelper { - // Note - XmlBeans handles entity encoding for us, - // so these should be & forms, not the & ones! - private static final String HeaderFooterEntity_L = "&L"; - private static final String HeaderFooterEntity_C = "&C"; - private static final String HeaderFooterEntity_R = "&R"; - - // These are other entities that may be used in the - // left, center or right. Not exhaustive - public static final String HeaderFooterEntity_File = "&F"; - public static final String HeaderFooterEntity_Date = "&D"; - public static final String HeaderFooterEntity_Time = "&T"; - - public String getLeftSection(String string) { - return getParts(string)[0]; - } - public String getCenterSection(String string) { - return getParts(string)[1]; - } - public String getRightSection(String string) { - return getParts(string)[2]; - } - - public String setLeftSection(String string, String newLeft) { - String[] parts = getParts(string); - parts[0] = newLeft; - return joinParts(parts); - } - public String setCenterSection(String string, String newCenter) { - String[] parts = getParts(string); - parts[1] = newCenter; - return joinParts(parts); - } - public String setRightSection(String string, String newRight) { - String[] parts = getParts(string); - parts[2] = newRight; - return joinParts(parts); - } - - /** - * Split into left, center, right - */ - private String[] getParts(String string) { - String[] parts = new String[] { "", "", "" }; - if(string == null) - return parts; - - // They can come in any order, which is just nasty - // Work backwards from the end, picking the last - // on off each time as we go - int lAt = 0; - int cAt = 0; - int rAt = 0; - - while( - // Ensure all indicies get updated, then -1 tested - (lAt = string.indexOf(HeaderFooterEntity_L)) > -2 && - (cAt = string.indexOf(HeaderFooterEntity_C)) > -2 && - (rAt = string.indexOf(HeaderFooterEntity_R)) > -2 && - (lAt > -1 || cAt > -1 || rAt > -1) - ) { - // Pick off the last one - if(rAt > cAt && rAt > lAt) { - parts[2] = string.substring(rAt + HeaderFooterEntity_R.length()); - string = string.substring(0, rAt); - } else if(cAt > rAt && cAt > lAt) { - parts[1] = string.substring(cAt + HeaderFooterEntity_C.length()); - string = string.substring(0, cAt); - } else { - parts[0] = string.substring(lAt + HeaderFooterEntity_L.length()); - string = string.substring(0, lAt); - } - } - - return parts; - } - private String joinParts(String[] parts) { - return joinParts(parts[0], parts[1], parts[2]); - } - private String joinParts(String l, String c, String r) { - StringBuffer ret = new StringBuffer(); - - // Join as c, l, r - if(c.length() > 0) { - ret.append(HeaderFooterEntity_C); - ret.append(c); - } - if(l.length() > 0) { - ret.append(HeaderFooterEntity_L); - ret.append(l); - } - if(r.length() > 0) { - ret.append(HeaderFooterEntity_R); - ret.append(r); - } - - return ret.toString(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java deleted file mode 100644 index ef0c5ea63..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaRenderer; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Pxg; -import org.apache.poi.ss.formula.ptg.Pxg3D; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook; -import org.apache.poi.xssf.usermodel.XSSFName; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; - -/** - * Utility to update formulas and named ranges when a sheet name was changed - * - * @author Yegor Kozlov - */ -public final class XSSFFormulaUtils { - private final XSSFWorkbook _wb; - private final XSSFEvaluationWorkbook _fpwb; - - public XSSFFormulaUtils(XSSFWorkbook wb) { - _wb = wb; - _fpwb = XSSFEvaluationWorkbook.create(_wb); - } - - /** - * Update sheet name in all formulas and named ranges. - * Called from {@link XSSFWorkbook#setSheetName(int, String)} - *

        - *

        - * The idea is to parse every formula and render it back to string - * with the updated sheet name. This is done by parsing into Ptgs, - * looking for ones with sheet references in them, and changing those - *

        - * - * @param sheetIndex the 0-based index of the sheet being changed - * @param oldName the old sheet name - * @param newName the new sheet name - */ - public void updateSheetName(final int sheetIndex, final String oldName, final String newName) { - // update named ranges - for (XSSFName nm : _wb.getAllNames()) { - if (nm.getSheetIndex() == -1 || nm.getSheetIndex() == sheetIndex) { - updateName(nm, oldName, newName); - } - } - - // update formulas - for (Sheet sh : _wb) { - for (Row row : sh) { - for (Cell cell : row) { - if (cell.getCellTypeEnum() == CellType.FORMULA) { - updateFormula((XSSFCell) cell, oldName, newName); - } - } - } - } - } - - /** - * Parse cell formula and re-assemble it back using the new sheet name - * - * @param cell the cell to update - */ - private void updateFormula(XSSFCell cell, String oldName, String newName) { - CTCellFormula f = cell.getCTCell().getF(); - if (f != null) { - String formula = f.getStringValue(); - if (formula != null && formula.length() > 0) { - int sheetIndex = _wb.getSheetIndex(cell.getSheet()); - Ptg[] ptgs = FormulaParser.parse(formula, _fpwb, FormulaType.CELL, sheetIndex, cell.getRowIndex()); - for (Ptg ptg : ptgs) { - updatePtg(ptg, oldName, newName); - } - String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs); - if (!formula.equals(updatedFormula)) f.setStringValue(updatedFormula); - } - } - } - - /** - * Parse formula in the named range and re-assemble it back using the new sheet name. - * - * @param name the name to update - */ - private void updateName(XSSFName name, String oldName, String newName) { - String formula = name.getRefersToFormula(); - if (formula != null) { - int sheetIndex = name.getSheetIndex(); - int rowIndex = -1; //don't care - Ptg[] ptgs = FormulaParser.parse(formula, _fpwb, FormulaType.NAMEDRANGE, sheetIndex, rowIndex); - for (Ptg ptg : ptgs) { - updatePtg(ptg, oldName, newName); - } - String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs); - if (!formula.equals(updatedFormula)) name.setRefersToFormula(updatedFormula); - } - } - - private void updatePtg(Ptg ptg, String oldName, String newName) { - if (ptg instanceof Pxg) { - Pxg pxg = (Pxg)ptg; - if (pxg.getExternalWorkbookNumber() < 1) { - if (pxg.getSheetName() != null && - pxg.getSheetName().equals(oldName)) { - pxg.setSheetName(newName); - } - if (pxg instanceof Pxg3D) { - Pxg3D pxg3D = (Pxg3D)pxg; - if (pxg3D.getLastSheetName() != null && - pxg3D.getLastSheetName().equals(oldName)) { - pxg3D.setLastSheetName(newName); - } - } - } - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFIgnoredErrorHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFIgnoredErrorHelper.java deleted file mode 100644 index d0dc0b760..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFIgnoredErrorHelper.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.apache.poi.ss.usermodel.IgnoredErrorType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIgnoredError; - -/** - * XSSF-specific code for working with ignored errors - */ -public class XSSFIgnoredErrorHelper { - public static boolean isSet(IgnoredErrorType errorType, CTIgnoredError error) { - switch(errorType) { - case CALCULATED_COLUMN: - return error.isSetCalculatedColumn(); - case EMPTY_CELL_REFERENCE: - return error.isSetEmptyCellReference(); - case EVALUATION_ERROR: - return error.isSetEvalError(); - case FORMULA: - return error.isSetFormula(); - case FORMULA_RANGE: - return error.isSetFormulaRange(); - case LIST_DATA_VALIDATION: - return error.isSetListDataValidation(); - case NUMBER_STORED_AS_TEXT: - return error.isSetNumberStoredAsText(); - case TWO_DIGIT_TEXT_YEAR: - return error.isSetTwoDigitTextYear(); - case UNLOCKED_FORMULA: - return error.isSetUnlockedFormula(); - default: - throw new IllegalStateException(); - } - } - - public static void set(IgnoredErrorType errorType, CTIgnoredError error) { - switch(errorType) { - case CALCULATED_COLUMN: - error.setCalculatedColumn(true); - break; - case EMPTY_CELL_REFERENCE: - error.setEmptyCellReference(true); - break; - case EVALUATION_ERROR: - error.setEvalError(true); - break; - case FORMULA: - error.setFormula(true); - break; - case FORMULA_RANGE: - error.setFormulaRange(true); - break; - case LIST_DATA_VALIDATION: - error.setListDataValidation(true); - break; - case NUMBER_STORED_AS_TEXT: - error.setNumberStoredAsText(true); - break; - case TWO_DIGIT_TEXT_YEAR: - error.setTwoDigitTextYear(true); - break; - case UNLOCKED_FORMULA: - error.setUnlockedFormula(true); - break; - default: - throw new IllegalStateException(); - } - } - - public static void addIgnoredErrors(CTIgnoredError err, String ref, IgnoredErrorType... ignoredErrorTypes) { - err.setSqref(Arrays.asList(ref)); - for (IgnoredErrorType errType : ignoredErrorTypes) { - XSSFIgnoredErrorHelper.set(errType, err); - } - } - - public static Set getErrorTypes(CTIgnoredError err) { - Set result = new LinkedHashSet(); - for (IgnoredErrorType errType : IgnoredErrorType.values()) { - if (XSSFIgnoredErrorHelper.isSet(errType, err)) { - result.add(errType); - } - } - return result; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java deleted file mode 100644 index 46e47f688..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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 java.security.SecureRandom; -import java.util.Arrays; -import java.util.Locale; - -import javax.xml.bind.DatatypeConverter; -import javax.xml.namespace.QName; - -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; - -@Internal(since="3.15 beta 3") -public final class XSSFPasswordHelper { - private XSSFPasswordHelper() { - // no instances of this static class - } - - /** - * Sets the XORed or hashed password - * - * @param xobj the xmlbeans object which contains the password attributes - * @param password the password, if null, the password attributes will be removed - * @param hashAlgo the hash algorithm, if null the password will be XORed - * @param prefix the prefix of the password attributes, may be null - */ - public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) { - XmlCursor cur = xobj.newCursor(); - - if (password == null) { - cur.removeAttribute(getAttrName(prefix, "password")); - cur.removeAttribute(getAttrName(prefix, "algorithmName")); - cur.removeAttribute(getAttrName(prefix, "hashValue")); - cur.removeAttribute(getAttrName(prefix, "saltValue")); - cur.removeAttribute(getAttrName(prefix, "spinCount")); - return; - } - - cur.toFirstContentToken(); - if (hashAlgo == null) { - int hash = CryptoFunctions.createXorVerifier1(password); - cur.insertAttributeWithValue(getAttrName(prefix, "password"), - String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT)); - } else { - SecureRandom random = new SecureRandom(); - byte salt[] = random.generateSeed(16); - - // Iterations specifies the number of times the hashing function shall be iteratively run (using each - // iteration's result as the input for the next iteration). - int spinCount = 100000; - - // Implementation Notes List: - // --> In this third stage, the reversed byte order legacy hash from the second stage shall - // be converted to Unicode hex string representation - byte hash[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false); - - cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); - cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash)); - cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt)); - cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount); - } - cur.dispose(); - } - - /** - * Validates the password, i.e. - * calculates the hash of the given password and compares it against the stored hash - * - * @param xobj the xmlbeans object which contains the password attributes - * @param password the password, if null the method will always return false, - * even if there's no password set - * @param prefix the prefix of the password attributes, may be null - * - * @return true, if the hashes match - */ - public static boolean validatePassword(XmlObject xobj, String password, String prefix) { - // TODO: is "velvetSweatshop" the default password? - if (password == null) return false; - - XmlCursor cur = xobj.newCursor(); - String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password")); - String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName")); - String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue")); - String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue")); - String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount")); - cur.dispose(); - - if (xorHashVal != null) { - int hash1 = Integer.parseInt(xorHashVal, 16); - int hash2 = CryptoFunctions.createXorVerifier1(password); - return hash1 == hash2; - } else { - if (hashVal == null || algoName == null || saltVal == null || spinCount == null) { - return false; - } - - byte hash1[] = DatatypeConverter.parseBase64Binary(hashVal); - HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName); - byte salt[] = DatatypeConverter.parseBase64Binary(saltVal); - int spinCnt = Integer.parseInt(spinCount); - byte hash2[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false); - return Arrays.equals(hash1, hash2); - } - } - - - private static QName getAttrName(String prefix, String name) { - if (prefix == null || "".equals(prefix)) { - return new QName(name); - } else { - return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1)); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java deleted file mode 100644 index 4e3c90819..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.poifs.crypt.HashAlgorithm; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; -import org.apache.xmlbeans.XmlObject; - -/** - * @deprecated POI 3.15 beta 3. Use {@link XSSFPasswordHelper} instead. - */ -@Internal(since="3.15 beta 3") -@Deprecated -@Removal(version="3.17") -public class XSSFPaswordHelper { - /** - * Sets the XORed or hashed password - * - * @param xobj the xmlbeans object which contains the password attributes - * @param password the password, if null, the password attributes will be removed - * @param hashAlgo the hash algorithm, if null the password will be XORed - * @param prefix the prefix of the password attributes, may be null - */ - public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) { - XSSFPasswordHelper.setPassword(xobj, password, hashAlgo, prefix); - } - - /** - * Validates the password, i.e. - * calculates the hash of the given password and compares it against the stored hash - * - * @param xobj the xmlbeans object which contains the password attributes - * @param password the password, if null the method will always return false, - * even if there's no password set - * @param prefix the prefix of the password attributes, may be null - * - * @return true, if the hashes match - */ - public static boolean validatePassword(XmlObject xobj, String password, String prefix) { - return XSSFPasswordHelper.validatePassword(xobj, password, prefix); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java deleted file mode 100644 index e55b014a7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java +++ /dev/null @@ -1,295 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.formula.FormulaParseException; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaRenderer; -import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.ptg.AreaErrPtg; -import org.apache.poi.ss.formula.ptg.AreaPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.helpers.RowShifter; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook; -import org.apache.poi.xssf.usermodel.XSSFHyperlink; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; - -/** - * Helper for shifting rows up or down - * - * When possible, code should be implemented in the RowShifter abstract class to avoid duplication with {@link org.apache.poi.hssf.usermodel.helpers.HSSFRowShifter} - */ -public final class XSSFRowShifter extends RowShifter { - private static final POILogger logger = POILogFactory.getLogger(XSSFRowShifter.class); - - public XSSFRowShifter(XSSFSheet sh) { - super(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 merged cell regions - * @deprecated POI 3.15 beta 2. Use {@link #shiftMergedRegions(int, int, int)} instead. - */ - public List shiftMerged(int startRow, int endRow, int n) { - return shiftMergedRegions(startRow, endRow, n); - } - - /** - * Updated named ranges - */ - public void updateNamedRanges(FormulaShifter shifter) { - Workbook wb = sheet.getWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb); - for (Name name : wb.getAllNames()) { - String formula = name.getRefersToFormula(); - int sheetIndex = name.getSheetIndex(); - final int rowIndex = -1; //don't care, named ranges are not allowed to include structured references - - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.NAMEDRANGE, sheetIndex, rowIndex); - 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 - Workbook wb = sheet.getWorkbook(); - for (Sheet sh : wb) { - if (sheet == sh) continue; - updateSheetFormulas(sh, shifter); - } - } - - private void updateSheetFormulas(Sheet sh, FormulaShifter shifter) { - for (Row r : sh) { - XSSFRow row = (XSSFRow) r; - updateRowFormulas(row, shifter); - } - } - - /** - * Update the formulas in specified row using the formula shifting policy specified by shifter - * - * @param row the row to update the formulas on - * @param shifter the formula shifting policy - */ - @Internal - public void updateRowFormulas(Row row, FormulaShifter shifter) { - XSSFSheet sheet = (XSSFSheet) row.getSheet(); - 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.getT() == STCellFormulaType.SHARED){ - int si = (int)f.getSi(); - CTCellFormula sf = sheet.getSharedFormula(si); - sf.setStringValue(shiftedFormula); - } - } - - } - - //Range of cells which the formula applies to. - if (f.isSetRef()) { - 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, - * null if the formula wasn't modified - */ - private static String shiftFormula(Row row, String formula, FormulaShifter shifter) { - Sheet sheet = row.getSheet(); - Workbook wb = sheet.getWorkbook(); - int sheetIndex = wb.getSheetIndex(sheet); - final int rowIndex = row.getRowNum(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb); - - try { - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex); - String shiftedFmla = null; - if (shifter.adjustFormula(ptgs, sheetIndex)) { - shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); - } - return shiftedFmla; - } catch (FormulaParseException fpe) { - // Log, but don't change, rather than breaking - logger.log(POILogger.WARN, "Error shifting formula on row ", row.getRowNum(), fpe); - return formula; - } - } - - public void updateConditionalFormatting(FormulaShifter shifter) { - XSSFSheet xsheet = (XSSFSheet) sheet; - XSSFWorkbook wb = xsheet.getWorkbook(); - int sheetIndex = wb.getSheetIndex(sheet); - final int rowIndex = -1; //don't care, structured references not allowed in conditional formatting - - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - CTWorksheet ctWorksheet = xsheet.getCTWorksheet(); - CTConditionalFormatting[] conditionalFormattingArray = ctWorksheet.getConditionalFormattingArray(); - // iterate backwards due to possible calls to ctWorksheet.removeConditionalFormatting(j) - for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) { - CTConditionalFormatting cf = conditionalFormattingArray[j]; - - ArrayList cellRanges = new ArrayList(); - for (Object stRef : cf.getSqref()) { - String[] regions = stRef.toString().split(" "); - for (String region : regions) { - cellRanges.add(CellRangeAddress.valueOf(region)); - } - } - - boolean changed = false; - List temp = new ArrayList(); - for (CellRangeAddress craOld : cellRanges) { - CellRangeAddress craNew = shiftRange(shifter, craOld, sheetIndex); - if (craNew == null) { - changed = true; - continue; - } - temp.add(craNew); - if (craNew != craOld) { - changed = true; - } - } - - if (changed) { - int nRanges = temp.size(); - if (nRanges == 0) { - ctWorksheet.removeConditionalFormatting(j); - continue; - } - List refs = new ArrayList(); - for(CellRangeAddress a : temp) refs.add(a.formatAsString()); - cf.setSqref(refs); - } - - for(CTCfRule cfRule : cf.getCfRuleArray()){ - String[] formulaArray = cfRule.getFormulaArray(); - for (int i = 0; i < formulaArray.length; i++) { - String formula = formulaArray[i]; - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex); - if (shifter.adjustFormula(ptgs, sheetIndex)) { - String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); - cfRule.setFormulaArray(i, shiftedFmla); - } - } - } - } - } - - /** - * Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink - * is of type LINK_DOCUMENT and refers to a cell that was shifted). Hyperlinks - * do not track the content they point to. - * - * @param shifter - */ - public void updateHyperlinks(FormulaShifter shifter) { - int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet); - List hyperlinkList = sheet.getHyperlinkList(); - - for (Hyperlink hyperlink : hyperlinkList) { - XSSFHyperlink xhyperlink = (XSSFHyperlink) hyperlink; - String cellRef = xhyperlink.getCellRef(); - CellRangeAddress cra = CellRangeAddress.valueOf(cellRef); - CellRangeAddress shiftedRange = shiftRange(shifter, cra, sheetIndex); - if (shiftedRange != null && shiftedRange != cra) { - // shiftedRange should not be null. If shiftedRange is null, that means - // that a hyperlink wasn't deleted at the beginning of shiftRows when - // identifying rows that should be removed because they will be overwritten - xhyperlink.setCellReference(shiftedRange.formatAsString()); - } - } - } - - private static CellRangeAddress shiftRange(FormulaShifter shifter, CellRangeAddress cra, int currentExternSheetIx) { - // FormulaShifter works well in terms of Ptgs - so convert CellRangeAddress to AreaPtg (and back) here - AreaPtg aptg = new AreaPtg(cra.getFirstRow(), cra.getLastRow(), cra.getFirstColumn(), cra.getLastColumn(), false, false, false, false); - Ptg[] ptgs = { aptg, }; - - if (!shifter.adjustFormula(ptgs, currentExternSheetIx)) { - return cra; - } - Ptg ptg0 = ptgs[0]; - if (ptg0 instanceof AreaPtg) { - AreaPtg bptg = (AreaPtg) ptg0; - return new CellRangeAddress(bptg.getFirstRow(), bptg.getLastRow(), bptg.getFirstColumn(), bptg.getLastColumn()); - } - if (ptg0 instanceof AreaErrPtg) { - return null; - } - throw new IllegalStateException("Unexpected shifted ptg class (" + ptg0.getClass().getName() + ")"); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFSingleXmlCell.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFSingleXmlCell.java deleted file mode 100644 index b91b20b34..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFSingleXmlCell.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.util.CellReference; -import org.apache.poi.xssf.model.SingleXmlCells; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSingleXmlCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlCellPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum; - -/** - * - * This class is a wrapper around the CTSingleXmlCell (Open Office XML Part 4: - * chapter 3.5.2.1) - * - - * - * @author Roberto Manicardi - * - */ -public class XSSFSingleXmlCell { - - private CTSingleXmlCell singleXmlCell; - private SingleXmlCells parent; - - - public XSSFSingleXmlCell(CTSingleXmlCell singleXmlCell, SingleXmlCells parent){ - this.singleXmlCell = singleXmlCell; - this.parent = parent; - } - - /** - * Gets the XSSFCell referenced by the R attribute or creates a new one if cell doesn't exists - * @return the referenced XSSFCell, null if the cell reference is invalid - */ - public XSSFCell getReferencedCell(){ - XSSFCell cell = null; - - - CellReference cellReference = new CellReference(singleXmlCell.getR()); - - XSSFRow row = parent.getXSSFSheet().getRow(cellReference.getRow()); - if(row==null){ - row = parent.getXSSFSheet().createRow(cellReference.getRow()); - } - - cell = row.getCell(cellReference.getCol()); - if(cell==null){ - cell = row.createCell(cellReference.getCol()); - } - - - return cell; - } - - public String getXpath(){ - CTXmlCellPr xmlCellPr = singleXmlCell.getXmlCellPr(); - CTXmlPr xmlPr = xmlCellPr.getXmlPr(); - String xpath = xmlPr.getXpath(); - return xpath; - } - - public long getMapId(){ - return singleXmlCell.getXmlCellPr().getXmlPr().getMapId(); - } - - public Enum getXmlDataType() { - CTXmlCellPr xmlCellPr = singleXmlCell.getXmlCellPr(); - CTXmlPr xmlPr = xmlCellPr.getXmlPr(); - return xmlPr.getXmlDataType(); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFXmlColumnPr.java b/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFXmlColumnPr.java deleted file mode 100644 index 574d64013..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFXmlColumnPr.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.XSSFTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXmlColumnPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType.Enum; - - -/** - * - * This class is a wrapper around the CTXmlColumnPr (Open Office XML Part 4: - * chapter 3.5.1.7) - * - * - * @author Roberto Manicardi - */ -public class XSSFXmlColumnPr { - - private XSSFTable table; - private CTTableColumn ctTableColumn; - private CTXmlColumnPr ctXmlColumnPr; - - public XSSFXmlColumnPr(XSSFTable table ,CTTableColumn ctTableColum,CTXmlColumnPr ctXmlColumnPr){ - this.table = table; - this.ctTableColumn = ctTableColum; - this.ctXmlColumnPr = ctXmlColumnPr; - } - - public long getMapId(){ - return ctXmlColumnPr.getMapId(); - } - - public String getXPath(){ - return ctXmlColumnPr.getXpath(); - } - /** - * (see Open Office XML Part 4: chapter 3.5.1.3) - * @return An integer representing the unique identifier of this column. - */ - public long getId(){ - return ctTableColumn.getId(); - } - - - /** - * If the XPath is, for example, /Node1/Node2/Node3 and /Node1/Node2 is the common XPath for the table, the local XPath is /Node3 - * - * @return the local XPath - */ - public String getLocalXPath(){ - StringBuilder localXPath = new StringBuilder(); - int numberOfCommonXPathAxis = table.getCommonXpath().split("/").length-1; - - String[] xPathTokens = ctXmlColumnPr.getXpath().split("/"); - for(int i=numberOfCommonXPathAxis; i BY_MAX = new Comparator() { - @Override - public int compare(CTCol col1, CTCol col2) { - long col1max = col1.getMax(); - long col2max = col2.getMax(); - return col1max < col2max ? -1 : col1max > col2max ? 1 : 0; - } - }; - - public static final Comparator BY_MIN_MAX = new Comparator() { - @Override - public int compare(CTCol col1, CTCol col2) { - long col11min = col1.getMin(); - long col2min = col2.getMin(); - return col11min < col2min ? -1 : col11min > col2min ? 1 : BY_MAX.compare(col1, col2); - } - }; - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/util/EvilUnclosedBRFixingInputStream.java b/trunk/src/ooxml/java/org/apache/poi/xssf/util/EvilUnclosedBRFixingInputStream.java deleted file mode 100644 index 5fae1ea1c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/util/EvilUnclosedBRFixingInputStream.java +++ /dev/null @@ -1,209 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -/** - * This is a seriously sick fix for the fact that some .xlsx - * files contain raw bits of HTML, without being escaped - * or properly turned into XML. - * The result is that they contain things like >br<, - * which breaks the XML parsing. - * This very sick InputStream wrapper attempts to spot - * these go past, and fix them. - * Only works for UTF-8 and US-ASCII based streams! - * It should only be used where experience shows the problem - * can occur... - */ -public class EvilUnclosedBRFixingInputStream extends InputStream { - private InputStream source; - private byte[] spare; - - private static byte[] detect = new byte[] { - (byte)'<', (byte)'b', (byte)'r', (byte)'>' - }; - - public EvilUnclosedBRFixingInputStream(InputStream source) { - this.source = source; - } - - /** - * Warning - doesn't fix! - */ - @Override - public int read() throws IOException { - return source.read(); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - // Grab any data left from last time - int readA = readFromSpare(b, off, len); - - // Now read from the stream - int readB = source.read(b, off+readA, len-readA); - - // Figure out how much we've done - int read; - if(readB == -1 || readB == 0) { - if (readA == 0) { - return readB; - } - read = readA; - } else { - read = readA + readB; - } - - // Fix up our data - if(read > 0) { - read = fixUp(b, off, read); - } - - // All done - return read; - } - - @Override - public int read(byte[] b) throws IOException { - return this.read(b, 0, b.length); - } - - /** - * Reads into the buffer from the spare bytes - */ - private int readFromSpare(byte[] b, int offset, int len) { - if(spare == null) return 0; - if(len == 0) throw new IllegalArgumentException("Asked to read 0 bytes"); - - if(spare.length <= len) { - // All fits, good - System.arraycopy(spare, 0, b, offset, spare.length); - int read = spare.length; - spare = null; - return read; - } else { - // We have more spare than they can copy with... - byte[] newspare = new byte[spare.length-len]; - System.arraycopy(spare, 0, b, offset, len); - System.arraycopy(spare, len, newspare, 0, newspare.length); - spare = newspare; - return len; - } - } - private void addToSpare(byte[] b, int offset, int len, boolean atTheEnd) { - if(spare == null) { - spare = new byte[len]; - System.arraycopy(b, offset, spare, 0, len); - } else { - byte[] newspare = new byte[spare.length+len]; - if(atTheEnd) { - System.arraycopy(spare, 0, newspare, 0, spare.length); - System.arraycopy(b, offset, newspare, spare.length, len); - } else { - System.arraycopy(b, offset, newspare, 0, len); - System.arraycopy(spare, 0, newspare, len, spare.length); - } - spare = newspare; - } - } - - private int fixUp(byte[] b, int offset, int read) { - // Do we have any potential overhanging ones? - for(int i=0; i handing over the end, eg fixAt = new ArrayList(); - for(int i=offset; i<=offset+read-detect.length; i++) { - boolean going = true; - for(int j=0; j 0) { - // Make sure we don't loose part of a
        ! - int fixes = 0; - for(int at : fixAt) { - if(at > offset+read-detect.length-overshoot-fixes) { - overshoot = needed - at - 1 - fixes; - break; - } - fixes++; - } - - addToSpare(b, offset+read-overshoot, overshoot, false); - read -= overshoot; - } - - // Fix them, in reverse order so the - // positions are valid - for(int j=fixAt.size()-1; j>=0; j--) { - int i = fixAt.get(j); - if(i >= read+offset) { - // This one has moved into the overshoot - continue; - } - if(i > read-3) { - // This one has moved into the overshoot - continue; - } - - byte[] tmp = new byte[read-i-3]; - System.arraycopy(b, i+3, tmp, 0, tmp.length); - b[i+3] = (byte)'/'; - System.arraycopy(tmp, 0, b, i+4, tmp.length); - // It got one longer - read++; - } - return read; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xssf/util/NumericRanges.java b/trunk/src/ooxml/java/org/apache/poi/xssf/util/NumericRanges.java deleted file mode 100644 index 442e24a48..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xssf/util/NumericRanges.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util; - -public class NumericRanges { - - public static final int NO_OVERLAPS = -1; - public static final int OVERLAPS_1_MINOR = 0; - public static final int OVERLAPS_2_MINOR = 1; - public static final int OVERLAPS_1_WRAPS = 2; - public static final int OVERLAPS_2_WRAPS = 3; - - public static long[] getOverlappingRange(long[] range1, long[] range2) { - int overlappingType = getOverlappingType(range1, range2); - if (overlappingType == OVERLAPS_1_MINOR) { - return new long[]{range2[0], range1[1]}; - } - else if (overlappingType == OVERLAPS_2_MINOR) { - return new long[]{range1[0], range2[1]}; - } - else if (overlappingType == OVERLAPS_2_WRAPS) { - return range1; - } - else if (overlappingType == OVERLAPS_1_WRAPS) { - return range2; - } - return new long[]{-1, -1}; - } - - public static int getOverlappingType(long[] range1, long[] range2) { - long min1 = range1[0]; - long max1 = range1[1]; - long min2 = range2[0]; - long max2 = range2[1]; - if (min1 >= min2 && max1 <= max2) { - return OVERLAPS_2_WRAPS; - } - else if (min2 >= min1 && max2 <= max1) { - return OVERLAPS_1_WRAPS; - } - else if ((min2 >= min1 && min2 <= max1) && max2 >= max1) { - return OVERLAPS_1_MINOR; - } - else if ((min1 >= min2 && min1 <= max2) && max1 >= max2) { - return OVERLAPS_2_MINOR; - } - return NO_OVERLAPS; - - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java deleted file mode 100644 index 712e04b73..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java +++ /dev/null @@ -1,205 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xwpf.model.XWPFCommentsDecorator; -import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; -import org.apache.poi.xwpf.usermodel.IBodyElement; -import org.apache.poi.xwpf.usermodel.ICell; -import org.apache.poi.xwpf.usermodel.IRunElement; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFHyperlink; -import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRelation; -import org.apache.poi.xwpf.usermodel.XWPFSDT; -import org.apache.poi.xwpf.usermodel.XWPFSDTCell; -import org.apache.poi.xwpf.usermodel.XWPFTable; -import org.apache.poi.xwpf.usermodel.XWPFTableCell; -import org.apache.poi.xwpf.usermodel.XWPFTableRow; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; - -/** - * Helper class to extract text from an OOXML Word file - */ -public class XWPFWordExtractor extends POIXMLTextExtractor { - public static final XWPFRelation[] SUPPORTED_TYPES = { - XWPFRelation.DOCUMENT, XWPFRelation.TEMPLATE, - XWPFRelation.MACRO_DOCUMENT, - XWPFRelation.MACRO_TEMPLATE_DOCUMENT - }; - - private XWPFDocument document; - private boolean fetchHyperlinks = false; - - public XWPFWordExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException { - this(new XWPFDocument(container)); - } - - public XWPFWordExtractor(XWPFDocument document) { - super(document); - this.document = document; - } - - public static void main(String[] args) throws Exception { - if (args.length < 1) { - System.err.println("Use:"); - System.err.println(" XWPFWordExtractor "); - System.exit(1); - } - POIXMLTextExtractor extractor = - new XWPFWordExtractor(POIXMLDocument.openPackage( - args[0] - )); - System.out.println(extractor.getText()); - extractor.close(); - } - - /** - * Should we also fetch the hyperlinks, when fetching - * the text content? Default is to only output the - * hyperlink label, and not the contents - */ - public void setFetchHyperlinks(boolean fetch) { - fetchHyperlinks = fetch; - } - - public String getText() { - StringBuffer text = new StringBuffer(); - XWPFHeaderFooterPolicy hfPolicy = document.getHeaderFooterPolicy(); - - // Start out with all headers - extractHeaders(text, hfPolicy); - - // Process all body elements - for (IBodyElement e : document.getBodyElements()) { - appendBodyElementText(text, e); - text.append('\n'); - } - - // Finish up with all the footers - extractFooters(text, hfPolicy); - - return text.toString(); - } - - public void appendBodyElementText(StringBuffer text, IBodyElement e) { - if (e instanceof XWPFParagraph) { - appendParagraphText(text, (XWPFParagraph) e); - } else if (e instanceof XWPFTable) { - appendTableText(text, (XWPFTable) e); - } else if (e instanceof XWPFSDT) { - text.append(((XWPFSDT) e).getContent().getText()); - } - } - - public void appendParagraphText(StringBuffer text, XWPFParagraph paragraph) { - CTSectPr ctSectPr = null; - if (paragraph.getCTP().getPPr() != null) { - ctSectPr = paragraph.getCTP().getPPr().getSectPr(); - } - - XWPFHeaderFooterPolicy headerFooterPolicy = null; - - if (ctSectPr != null) { - headerFooterPolicy = new XWPFHeaderFooterPolicy(document, ctSectPr); - extractHeaders(text, headerFooterPolicy); - } - - - for (IRunElement run : paragraph.getRuns()) { - text.append(run.toString()); - if (run instanceof XWPFHyperlinkRun && fetchHyperlinks) { - XWPFHyperlink link = ((XWPFHyperlinkRun) run).getHyperlink(document); - if (link != null) - text.append(" <").append(link.getURL()).append(">"); - } - } - - // Add comments - XWPFCommentsDecorator decorator = new XWPFCommentsDecorator(paragraph, null); - String commentText = decorator.getCommentText(); - if (commentText.length() > 0) { - text.append(commentText).append('\n'); - } - - // Do endnotes and footnotes - String footnameText = paragraph.getFootnoteText(); - if (footnameText != null && footnameText.length() > 0) { - text.append(footnameText).append('\n'); - } - - if (ctSectPr != null) { - extractFooters(text, headerFooterPolicy); - } - } - - private void appendTableText(StringBuffer text, XWPFTable table) { - //this works recursively to pull embedded tables from tables - for (XWPFTableRow row : table.getRows()) { - List cells = row.getTableICells(); - for (int i = 0; i < cells.size(); i++) { - ICell cell = cells.get(i); - if (cell instanceof XWPFTableCell) { - text.append(((XWPFTableCell) cell).getTextRecursively()); - } else if (cell instanceof XWPFSDTCell) { - text.append(((XWPFSDTCell) cell).getContent().getText()); - } - if (i < cells.size() - 1) { - text.append("\t"); - } - } - text.append('\n'); - } - } - - private void extractFooters(StringBuffer text, XWPFHeaderFooterPolicy hfPolicy) { - if (hfPolicy == null) return; - - if (hfPolicy.getFirstPageFooter() != null) { - text.append(hfPolicy.getFirstPageFooter().getText()); - } - if (hfPolicy.getEvenPageFooter() != null) { - text.append(hfPolicy.getEvenPageFooter().getText()); - } - if (hfPolicy.getDefaultFooter() != null) { - text.append(hfPolicy.getDefaultFooter().getText()); - } - } - - private void extractHeaders(StringBuffer text, XWPFHeaderFooterPolicy hfPolicy) { - if (hfPolicy == null) return; - - if (hfPolicy.getFirstPageHeader() != null) { - text.append(hfPolicy.getFirstPageHeader().getText()); - } - if (hfPolicy.getEvenPageHeader() != null) { - text.append(hfPolicy.getEvenPageHeader().getText()); - } - if (hfPolicy.getDefaultHeader() != null) { - text.append(hfPolicy.getDefaultHeader().getText()); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java deleted file mode 100644 index 7c30d21b0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; - -public final class WMLHelper { - - public static boolean STOnOffToBoolean (STOnOff.Enum value) { - if (value == STOnOff.TRUE || value == STOnOff.ON || value == STOnOff.X_1) { - return true; - } - return false; - } - - public static STOnOff.Enum BooleanToSTOnOff (boolean value) { - return (value ? STOnOff.TRUE : STOnOff.FALSE); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java deleted file mode 100644 index 25aa7aab3..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; - -/** - * Base class for XWPF paragraphs - * - * @author Yury Batrakov (batrakov at gmail.com) - */ -public class XMLParagraph { - protected CTP paragraph; - - public XMLParagraph(CTP paragraph) { - this.paragraph = paragraph; - } - - public CTP getCTP() { - return paragraph; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java deleted file mode 100644 index 7b8356050..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.apache.poi.xwpf.usermodel.XWPFComment; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTMarkupRange; - -/** - * Decorator class for XWPFParagraph allowing to add comments - * found in paragraph to its text - * - * @author Yury Batrakov (batrakov at gmail.com) - */ -public class XWPFCommentsDecorator extends XWPFParagraphDecorator { - private StringBuffer commentText; - - public XWPFCommentsDecorator(XWPFParagraphDecorator nextDecorator) { - this(nextDecorator.paragraph, nextDecorator); - } - - public XWPFCommentsDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) { - super(paragraph, nextDecorator); - - XWPFComment comment; - commentText = new StringBuffer(); - - for (CTMarkupRange anchor : paragraph.getCTP().getCommentRangeStartArray()) { - if ((comment = paragraph.getDocument().getCommentByID(anchor.getId().toString())) != null) - commentText.append("\tComment by " + comment.getAuthor() + ": " + comment.getText()); - } - } - - public String getCommentText() { - return commentText.toString(); - } - - public String getText() { - return super.getText() + commentText; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java deleted file mode 100644 index 68799fdca..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java +++ /dev/null @@ -1,494 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLDocumentPart.RelationPart; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFFactory; -import org.apache.poi.xwpf.usermodel.XWPFFooter; -import org.apache.poi.xwpf.usermodel.XWPFHeader; -import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRelation; -import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPicture; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr.Enum; - -import com.microsoft.schemas.office.office.CTLock; -import com.microsoft.schemas.office.office.STConnectType; -import com.microsoft.schemas.vml.CTFormulas; -import com.microsoft.schemas.vml.CTGroup; -import com.microsoft.schemas.vml.CTH; -import com.microsoft.schemas.vml.CTHandles; -import com.microsoft.schemas.vml.CTPath; -import com.microsoft.schemas.vml.CTShape; -import com.microsoft.schemas.vml.CTShapetype; -import com.microsoft.schemas.vml.CTTextPath; -import com.microsoft.schemas.vml.STExt; -import com.microsoft.schemas.vml.STTrueFalse; - -/** - * A .docx file can have no headers/footers, the same header/footer - * on each page, odd/even page footers, and optionally also - * a different header/footer on the first page. - * This class handles sorting out what there is, and giving you - * the right headers and footers for the document. - */ -public class XWPFHeaderFooterPolicy { - public static final Enum DEFAULT = STHdrFtr.DEFAULT; - public static final Enum EVEN = STHdrFtr.EVEN; - public static final Enum FIRST = STHdrFtr.FIRST; - - private XWPFDocument doc; - - private XWPFHeader firstPageHeader; - private XWPFFooter firstPageFooter; - - private XWPFHeader evenPageHeader; - private XWPFFooter evenPageFooter; - - private XWPFHeader defaultHeader; - private XWPFFooter defaultFooter; - - /** - * Figures out the policy for the given document, - * and creates any header and footer objects - * as required. - */ - public XWPFHeaderFooterPolicy(XWPFDocument doc) { - this(doc, null); - } - - /** - * Figures out the policy for the given document, - * and creates any header and footer objects - * as required. - */ - public XWPFHeaderFooterPolicy(XWPFDocument doc, CTSectPr sectPr) { - // Grab what headers and footers have been defined - // For now, we don't care about different ranges, as it - // doesn't seem that .docx properly supports that - // feature of the file format yet - if (sectPr == null) { - CTBody ctBody = doc.getDocument().getBody(); - sectPr = ctBody.isSetSectPr() - ? ctBody.getSectPr() - : ctBody.addNewSectPr(); - } - this.doc = doc; - for (int i = 0; i < sectPr.sizeOfHeaderReferenceArray(); i++) { - // Get the header - CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i); - POIXMLDocumentPart relatedPart = doc.getRelationById(ref.getId()); - XWPFHeader hdr = null; - if (relatedPart != null && relatedPart instanceof XWPFHeader) { - hdr = (XWPFHeader) relatedPart; - } - // Assign it; treat invalid options as "default" POI-60293 - Enum type; - try { - type = ref.getType(); - } catch (XmlValueOutOfRangeException e) { - type = STHdrFtr.DEFAULT; - } - - assignHeader(hdr, type); - } - for (int i = 0; i < sectPr.sizeOfFooterReferenceArray(); i++) { - // Get the footer - CTHdrFtrRef ref = sectPr.getFooterReferenceArray(i); - POIXMLDocumentPart relatedPart = doc.getRelationById(ref.getId()); - XWPFFooter ftr = null; - if (relatedPart != null && relatedPart instanceof XWPFFooter) { - ftr = (XWPFFooter) relatedPart; - } - // Assign it; treat invalid options as "default" POI-60293 - Enum type; - try { - type = ref.getType(); - } catch (XmlValueOutOfRangeException e) { - type = STHdrFtr.DEFAULT; - } - assignFooter(ftr, type); - } - } - - private void assignFooter(XWPFFooter ftr, Enum type) { - if (type == STHdrFtr.FIRST) { - firstPageFooter = ftr; - } else if (type == STHdrFtr.EVEN) { - evenPageFooter = ftr; - } else { - defaultFooter = ftr; - } - } - - private void assignHeader(XWPFHeader hdr, Enum type) { - if (type == STHdrFtr.FIRST) { - firstPageHeader = hdr; - } else if (type == STHdrFtr.EVEN) { - evenPageHeader = hdr; - } else { - defaultHeader = hdr; - } - } - - /** - * Creates an empty header of the specified type, containing a single - * empty paragraph, to which you can then set text, add more paragraphs etc. - */ - public XWPFHeader createHeader(Enum type) { - return createHeader(type, null); - } - - /** - * Creates a new header of the specified type, to which the - * supplied (and previously unattached!) paragraphs are - * added to. - */ - public XWPFHeader createHeader(Enum type, XWPFParagraph[] pars) { - XWPFHeader header = getHeader(type); - - if (header == null) { - HdrDocument hdrDoc = HdrDocument.Factory.newInstance(); - - XWPFRelation relation = XWPFRelation.HEADER; - int i = getRelationIndex(relation); - - XWPFHeader wrapper = (XWPFHeader) doc.createRelationship(relation, - XWPFFactory.getInstance(), i); - wrapper.setXWPFDocument(doc); - - String pStyle = "Header"; - CTHdrFtr hdr = buildHdr(type, pStyle, wrapper, pars); - wrapper.setHeaderFooter(hdr); - hdrDoc.setHdr(hdr); - assignHeader(wrapper, type); - header = wrapper; - } - - return header; - } - - /** - * Creates an empty footer of the specified type, containing a single - * empty paragraph, to which you can then set text, add more paragraphs etc. - */ - public XWPFFooter createFooter(Enum type) { - return createFooter(type, null); - } - - /** - * Creates a new footer of the specified type, to which the - * supplied (and previously unattached!) paragraphs are - * added to. - */ - public XWPFFooter createFooter(Enum type, XWPFParagraph[] pars) { - XWPFFooter footer = getFooter(type); - - if (footer == null) { - FtrDocument ftrDoc = FtrDocument.Factory.newInstance(); - - XWPFRelation relation = XWPFRelation.FOOTER; - int i = getRelationIndex(relation); - - XWPFFooter wrapper = (XWPFFooter) doc.createRelationship(relation, - XWPFFactory.getInstance(), i); - wrapper.setXWPFDocument(doc); - - String pStyle = "Footer"; - CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars); - wrapper.setHeaderFooter(ftr); - ftrDoc.setFtr(ftr); - assignFooter(wrapper, type); - footer = wrapper; - } - - return footer; - } - - private int getRelationIndex(XWPFRelation relation) { - int i = 1; - for (RelationPart rp : doc.getRelationParts()) { - if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) { - i++; - } - } - return i; - } - - private CTHdrFtr buildFtr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) { - //CTHdrFtr ftr = buildHdrFtr(pStyle, pars); // MB 24 May 2010 - CTHdrFtr ftr = buildHdrFtr(pStyle, pars, wrapper); // MB 24 May 2010 - setFooterReference(type, wrapper); - return ftr; - } - - private CTHdrFtr buildHdr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) { - //CTHdrFtr hdr = buildHdrFtr(pStyle, pars); // MB 24 May 2010 - CTHdrFtr hdr = buildHdrFtr(pStyle, pars, wrapper); // MB 24 May 2010 - setHeaderReference(type, wrapper); - return hdr; - } - - /** - * MB 24 May 2010. Created this overloaded buildHdrFtr() method because testing demonstrated - * that the XWPFFooter or XWPFHeader object returned by calls to the createHeader(int, XWPFParagraph[]) - * and createFooter(int, XWPFParagraph[]) methods or the getXXXXXHeader/Footer methods where - * headers or footers had been added to a document since it had been created/opened, returned - * an object that contained no XWPFParagraph objects even if the header/footer itself did contain - * text. The reason was that this line of code; CTHdrFtr ftr = CTHdrFtr.Factory.newInstance(); - * created a brand new instance of the CTHDRFtr class which was then populated with data when - * it should have recovered the CTHdrFtr object encapsulated within the XWPFHeaderFooter object - * that had previoulsy been instantiated in the createHeader(int, XWPFParagraph[]) or - * createFooter(int, XWPFParagraph[]) methods. - */ - private CTHdrFtr buildHdrFtr(String pStyle, XWPFParagraph[] paragraphs, XWPFHeaderFooter wrapper) { - CTHdrFtr ftr = wrapper._getHdrFtr(); - if (paragraphs != null) { - for (int i = 0; i < paragraphs.length; i++) { - CTP p = ftr.addNewP(); - ftr.setPArray(i, paragraphs[i].getCTP()); - } -// } else { -// CTP p = ftr.addNewP(); -// CTBody body = doc.getDocument().getBody(); -// if (body.sizeOfPArray() > 0) { -// CTP p0 = body.getPArray(0); -// if (p0.isSetRsidR()) { -// byte[] rsidr = p0.getRsidR(); -// byte[] rsidrdefault = p0.getRsidRDefault(); -// p.setRsidP(rsidr); -// p.setRsidRDefault(rsidrdefault); -// } -// } -// CTPPr pPr = p.addNewPPr(); -// pPr.addNewPStyle().setVal(pStyle); - } - return ftr; - } - - - private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) { - CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewFooterReference(); - ref.setType(type); - ref.setId(doc.getRelationId(wrapper)); - } - - - private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) { - CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewHeaderReference(); - ref.setType(type); - ref.setId(doc.getRelationId(wrapper)); - } - - public XWPFHeader getFirstPageHeader() { - return firstPageHeader; - } - - public XWPFFooter getFirstPageFooter() { - return firstPageFooter; - } - - /** - * Returns the odd page header. This is - * also the same as the default one... - */ - public XWPFHeader getOddPageHeader() { - return defaultHeader; - } - - /** - * Returns the odd page footer. This is - * also the same as the default one... - */ - public XWPFFooter getOddPageFooter() { - return defaultFooter; - } - - public XWPFHeader getEvenPageHeader() { - return evenPageHeader; - } - - public XWPFFooter getEvenPageFooter() { - return evenPageFooter; - } - - public XWPFHeader getDefaultHeader() { - return defaultHeader; - } - - public XWPFFooter getDefaultFooter() { - return defaultFooter; - } - - /** - * Get the header that applies to the given - * (1 based) page. - * - * @param pageNumber The one based page number - */ - public XWPFHeader getHeader(int pageNumber) { - if (pageNumber == 1 && firstPageHeader != null) { - return firstPageHeader; - } - if (pageNumber % 2 == 0 && evenPageHeader != null) { - return evenPageHeader; - } - return defaultHeader; - } - - /** - * Get this section header for the given type - * - * @param type of header to return - * @return {@link XWPFHeader} object - */ - public XWPFHeader getHeader(Enum type) { - if (type == STHdrFtr.EVEN) { - return evenPageHeader; - } else if (type == STHdrFtr.FIRST) { - return firstPageHeader; - } - return defaultHeader; - } - - /** - * Get the footer that applies to the given - * (1 based) page. - * - * @param pageNumber The one based page number - */ - public XWPFFooter getFooter(int pageNumber) { - if (pageNumber == 1 && firstPageFooter != null) { - return firstPageFooter; - } - if (pageNumber % 2 == 0 && evenPageFooter != null) { - return evenPageFooter; - } - return defaultFooter; - } - - /** - * Get this section footer for the given type - * - * @param type of footer to return - * @return {@link XWPFFooter} object - */ - public XWPFFooter getFooter(Enum type) { - if (type == STHdrFtr.EVEN) { - return evenPageFooter; - } else if (type == STHdrFtr.FIRST) { - return firstPageFooter; - } - return defaultFooter; - } - - - public void createWatermark(String text) { - XWPFParagraph[] pars = new XWPFParagraph[1]; - pars[0] = getWatermarkParagraph(text, 1); - createHeader(DEFAULT, pars); - pars[0] = getWatermarkParagraph(text, 2); - createHeader(FIRST, pars); - pars[0] = getWatermarkParagraph(text, 3); - createHeader(EVEN, pars); - } - - /* - * This is the default Watermark paragraph; the only variable is the text message - * TODO: manage all the other variables - */ - private XWPFParagraph getWatermarkParagraph(String text, int idx) { - CTP p = CTP.Factory.newInstance(); - byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR(); - byte[] rsidrdefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault(); - p.setRsidP(rsidr); - p.setRsidRDefault(rsidrdefault); - CTPPr pPr = p.addNewPPr(); - pPr.addNewPStyle().setVal("Header"); - // start watermark paragraph - CTR r = p.addNewR(); - CTRPr rPr = r.addNewRPr(); - rPr.addNewNoProof(); - CTPicture pict = r.addNewPict(); - CTGroup group = CTGroup.Factory.newInstance(); - CTShapetype shapetype = group.addNewShapetype(); - shapetype.setId("_x0000_t136"); - shapetype.setCoordsize("1600,21600"); - shapetype.setSpt(136); - shapetype.setAdj("10800"); - shapetype.setPath2("m@7,0l@8,0m@5,21600l@6,21600e"); - CTFormulas formulas = shapetype.addNewFormulas(); - formulas.addNewF().setEqn("sum #0 0 10800"); - formulas.addNewF().setEqn("prod #0 2 1"); - formulas.addNewF().setEqn("sum 21600 0 @1"); - formulas.addNewF().setEqn("sum 0 0 @2"); - formulas.addNewF().setEqn("sum 21600 0 @3"); - formulas.addNewF().setEqn("if @0 @3 0"); - formulas.addNewF().setEqn("if @0 21600 @1"); - formulas.addNewF().setEqn("if @0 0 @2"); - formulas.addNewF().setEqn("if @0 @4 21600"); - formulas.addNewF().setEqn("mid @5 @6"); - formulas.addNewF().setEqn("mid @8 @5"); - formulas.addNewF().setEqn("mid @7 @8"); - formulas.addNewF().setEqn("mid @6 @7"); - formulas.addNewF().setEqn("sum @6 0 @5"); - CTPath path = shapetype.addNewPath(); - path.setTextpathok(STTrueFalse.T); - path.setConnecttype(STConnectType.CUSTOM); - path.setConnectlocs("@9,0;@10,10800;@11,21600;@12,10800"); - path.setConnectangles("270,180,90,0"); - CTTextPath shapeTypeTextPath = shapetype.addNewTextpath(); - shapeTypeTextPath.setOn(STTrueFalse.T); - shapeTypeTextPath.setFitshape(STTrueFalse.T); - CTHandles handles = shapetype.addNewHandles(); - CTH h = handles.addNewH(); - h.setPosition("#0,bottomRight"); - h.setXrange("6629,14971"); - CTLock lock = shapetype.addNewLock(); - lock.setExt(STExt.EDIT); - CTShape shape = group.addNewShape(); - shape.setId("PowerPlusWaterMarkObject" + idx); - shape.setSpid("_x0000_s102" + (4 + idx)); - shape.setType("#_x0000_t136"); - shape.setStyle("position:absolute;margin-left:0;margin-top:0;width:415pt;height:207.5pt;z-index:-251654144;mso-wrap-edited:f;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"); - shape.setWrapcoords("616 5068 390 16297 39 16921 -39 17155 7265 17545 7186 17467 -39 17467 18904 17467 10507 17467 8710 17545 18904 17077 18787 16843 18358 16297 18279 12554 19178 12476 20701 11774 20779 11228 21131 10059 21248 8811 21248 7563 20975 6316 20935 5380 19490 5146 14022 5068 2616 5068"); - shape.setFillcolor("black"); - shape.setStroked(STTrueFalse.FALSE); - CTTextPath shapeTextPath = shape.addNewTextpath(); - shapeTextPath.setStyle("font-family:"Cambria";font-size:1pt"); - shapeTextPath.setString(text); - pict.set(group); - // end watermark paragraph - return new XWPFParagraph(p, doc); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java deleted file mode 100644 index 46636c3ef..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.apache.poi.xwpf.usermodel.XWPFParagraph; - -/** - * Base decorator class for XWPFParagraph - */ -public abstract class XWPFParagraphDecorator { - protected XWPFParagraph paragraph; - protected XWPFParagraphDecorator nextDecorator; - - public XWPFParagraphDecorator(XWPFParagraph paragraph) { - this(paragraph, null); - } - - public XWPFParagraphDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) { - this.paragraph = paragraph; - this.nextDecorator = nextDecorator; - } - - public String getText() { - if (nextDecorator != null) { - return nextDecorator.getText(); - } - return paragraph.getText(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/package.html b/trunk/src/ooxml/java/org/apache/poi/xwpf/package.html deleted file mode 100644 index 0a5955646..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/package.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - -

        This package contains classes for handling Microsoft .docx - Word Processing files, known in POI as XWPF (XML Word Processing - Format). -

        - - diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java deleted file mode 100644 index 4db163de2..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java +++ /dev/null @@ -1,107 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.POIXMLDocumentPart; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString; - -/** - * Experimental abstract class that is a base for XWPFSDT and XWPFSDTCell - *

        - * WARNING - APIs expected to change rapidly. - *

        - * These classes have so far been built only for read-only processing. - */ -public abstract class AbstractXWPFSDT implements ISDTContents { - private final String title; - private final String tag; - private final IBody part; - - public AbstractXWPFSDT(CTSdtPr pr, IBody part) { - if (pr == null) { - title = ""; - tag = ""; - } else { - CTString[] aliases = pr.getAliasArray(); - if (aliases != null && aliases.length > 0) { - title = aliases[0].getVal(); - } else { - title = ""; - } - CTString[] tags = pr.getTagArray(); - if (tags != null && tags.length > 0) { - tag = tags[0].getVal(); - } else { - tag = ""; - } - } - this.part = part; - - } - - /** - * @return first SDT Title - */ - public String getTitle() { - return title; - } - - /** - * @return first SDT Tag - */ - public String getTag() { - return tag; - } - - /** - * @return the content object - */ - public abstract ISDTContent getContent(); - - /** - * @return null - */ - public IBody getBody() { - return null; - } - - /** - * @return document part - */ - public POIXMLDocumentPart getPart() { - return part.getPart(); - } - - /** - * @return partType - */ - public BodyType getPartType() { - return BodyType.CONTENTCONTROL; - } - - /** - * @return element type - */ - public BodyElementType getElementType() { - return BodyElementType.CONTENTCONTROL; - } - - public XWPFDocument getDocument() { - return part.getXWPFDocument(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java deleted file mode 100644 index 5a1df0e21..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - *

        - * 9 Jan 2010 - *

        - *

        - * // TODO insert Javadoc here! - *

        - * - * @author epp - */ -public enum BodyElementType { - CONTENTCONTROL, - PARAGRAPH, - TABLE, -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java deleted file mode 100644 index 39e4758b6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * The different kinds of {@link IBody} that exist - */ -public enum BodyType { - CONTENTCONTROL, - DOCUMENT, - HEADER, - FOOTER, - FOOTNOTE, - TABLECELL -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java deleted file mode 100644 index b7937e528..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java +++ /dev/null @@ -1,628 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies all types of borders which can be specified for WordprocessingML - * objects which have a border. Borders can be separated into two types: - *
          - *
        • Line borders: which specify a pattern to be used when drawing a line around the - * specified object. - *
        • - *
        • Art borders: which specify a repeated image to be used - * when drawing a border around the specified object. Line borders may be - * specified on any object which allows a border, however, art borders may only - * be used as a border at the page level - the borders under the pgBorders - * element - *
        • - *
        - * - * @author Gisella Bronzetti - */ -public enum Borders { - - NIL(1), - - NONE(2), - - /** - * Specifies a line border consisting of a single line around the parent - * object. - */ - SINGLE(3), - - THICK(4), - - DOUBLE(5), - - DOTTED(6), - - DASHED(7), - - DOT_DASH(8), - - DOT_DOT_DASH(9), - - TRIPLE(10), - - THIN_THICK_SMALL_GAP(11), - - THICK_THIN_SMALL_GAP(12), - - THIN_THICK_THIN_SMALL_GAP(13), - - THIN_THICK_MEDIUM_GAP(14), - - THICK_THIN_MEDIUM_GAP(15), - - THIN_THICK_THIN_MEDIUM_GAP(16), - - THIN_THICK_LARGE_GAP(17), - - THICK_THIN_LARGE_GAP(18), - - THIN_THICK_THIN_LARGE_GAP(19), - - WAVE(20), - - DOUBLE_WAVE(21), - - DASH_SMALL_GAP(22), - - DASH_DOT_STROKED(23), - - THREE_D_EMBOSS(24), - - THREE_D_ENGRAVE(25), - - OUTSET(26), - - INSET(27), - - /** - * Specifies an art border consisting of a repeated image of an apple - */ - APPLES(28), - - /** - * Specifies an art border consisting of a repeated image of a shell pattern - */ - ARCHED_SCALLOPS(29), - - /** - * Specifies an art border consisting of a repeated image of a baby pacifier - */ - BABY_PACIFIER(30), - - /** - * Specifies an art border consisting of a repeated image of a baby rattle - */ - BABY_RATTLE(31), - - /** - * Specifies an art border consisting of a repeated image of a set of - * balloons - */ - BALLOONS_3_COLORS(32), - - /** - * Specifies an art border consisting of a repeated image of a hot air - * balloon - */ - BALLOONS_HOT_AIR(33), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background. - */ - BASIC_BLACK_DASHES(34), - - /** - * Specifies an art border consisting of a repeating image of a black dot on - * a white background. - */ - BASIC_BLACK_DOTS(35), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background - */ - BASIC_BLACK_SQUARES(36), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background. - */ - BASIC_THIN_LINES(37), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background. - */ - BASIC_WHITE_DASHES(38), - - /** - * Specifies an art border consisting of a repeating image of a white dot on - * a black background. - */ - BASIC_WHITE_DOTS(39), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background. - */ - BASIC_WHITE_SQUARES(40), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background. - */ - BASIC_WIDE_INLINE(41), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background - */ - BASIC_WIDE_MIDLINE(42), - - /** - * Specifies an art border consisting of a repeating image of a black and - * white background - */ - BASIC_WIDE_OUTLINE(43), - - /** - * Specifies an art border consisting of a repeated image of bats - */ - BATS(44), - - /** - * Specifies an art border consisting of repeating images of birds - */ - BIRDS(45), - - /** - * Specifies an art border consisting of a repeated image of birds flying - */ - BIRDS_FLIGHT(46), - - /** - * Specifies an art border consisting of a repeated image of a cabin - */ - CABINS(47), - - /** - * Specifies an art border consisting of a repeated image of a piece of cake - */ - CAKE_SLICE(48), - - /** - * Specifies an art border consisting of a repeated image of candy corn - */ - CANDY_CORN(49), - - /** - * Specifies an art border consisting of a repeated image of a knot work - * pattern - */ - CELTIC_KNOTWORK(50), - - /** - * Specifies an art border consisting of a banner. - *

        - * If the border is on the left or right, no border is displayed. - *

        - */ - CERTIFICATE_BANNER(51), - - /** - * Specifies an art border consisting of a repeating image of a chain link - * pattern. - */ - CHAIN_LINK(52), - - /** - * Specifies an art border consisting of a repeated image of a champagne - * bottle - */ - CHAMPAGNE_BOTTLE(53), - - /** - * Specifies an art border consisting of repeating images of a compass - */ - CHECKED_BAR_BLACK(54), - - /** - * Specifies an art border consisting of a repeating image of a colored - * pattern. - */ - CHECKED_BAR_COLOR(55), - - /** - * Specifies an art border consisting of a repeated image of a checkerboard - */ - CHECKERED(56), - - /** - * Specifies an art border consisting of a repeated image of a Christmas - * tree - */ - CHRISTMAS_TREE(57), - - /** - * Specifies an art border consisting of repeating images of lines and - * circles - */ - CIRCLES_LINES(58), - - /** - * Specifies an art border consisting of a repeated image of a rectangular - * pattern - */ - CIRCLES_RECTANGLES(59), - - /** - * Specifies an art border consisting of a repeated image of a wave - */ - CLASSICAL_WAVE(60), - - /** - * Specifies an art border consisting of a repeated image of a clock - */ - CLOCKS(61), - - /** - * Specifies an art border consisting of repeating images of a compass - */ - COMPASS(62), - - /** - * Specifies an art border consisting of a repeated image of confetti - */ - CONFETTI(63), - - /** - * Specifies an art border consisting of a repeated image of confetti - */ - CONFETTI_GRAYS(64), - - /** - * Specifies an art border consisting of a repeated image of confetti - */ - CONFETTI_OUTLINE(65), - - /** - * Specifies an art border consisting of a repeated image of confetti - * streamers - */ - CONFETTI_STREAMERS(66), - - /** - * Specifies an art border consisting of a repeated image of confetti - */ - CONFETTI_WHITE(67), - - /** - * Specifies an art border consisting of a repeated image - */ - CORNER_TRIANGLES(68), - - /** - * Specifies an art border consisting of a dashed line - */ - COUPON_CUTOUT_DASHES(69), - - /** - * Specifies an art border consisting of a dotted line - */ - COUPON_CUTOUT_DOTS(70), - - /** - * Specifies an art border consisting of a repeated image of a maze-like - * pattern - */ - CRAZY_MAZE(71), - - /** - * Specifies an art border consisting of a repeated image of a butterfly - */ - CREATURES_BUTTERFLY(72), - - /** - * Specifies an art border consisting of a repeated image of a fish - */ - CREATURES_FISH(73), - - /** - * Specifies an art border consisting of repeating images of insects. - */ - CREATURES_INSECTS(74), - - /** - * Specifies an art border consisting of a repeated image of a ladybug - */ - CREATURES_LADY_BUG(75), - - /** - * Specifies an art border consisting of repeating images of a cross-stitch - * pattern - */ - CROSS_STITCH(76), - - /** - * Specifies an art border consisting of a repeated image of Cupid - */ - CUP(77), - - DECO_ARCH(78), - - DECO_ARCH_COLOR(79), - - DECO_BLOCKS(80), - - DIAMONDS_GRAY(81), - - DOUBLE_D(82), - - DOUBLE_DIAMONDS(83), - - EARTH_1(84), - - EARTH_2(85), - - ECLIPSING_SQUARES_1(86), - - ECLIPSING_SQUARES_2(87), - - EGGS_BLACK(88), - - FANS(89), - - FILM(90), - - FIRECRACKERS(91), - - FLOWERS_BLOCK_PRINT(92), - - FLOWERS_DAISIES(93), - - FLOWERS_MODERN_1(94), - - FLOWERS_MODERN_2(95), - - FLOWERS_PANSY(96), - - FLOWERS_RED_ROSE(97), - - FLOWERS_ROSES(98), - - FLOWERS_TEACUP(99), - - FLOWERS_TINY(100), - - GEMS(101), - - GINGERBREAD_MAN(102), - - GRADIENT(103), - - HANDMADE_1(104), - - HANDMADE_2(105), - - HEART_BALLOON(106), - - HEART_GRAY(107), - - HEARTS(108), - - HEEBIE_JEEBIES(109), - - HOLLY(110), - - HOUSE_FUNKY(111), - - HYPNOTIC(112), - - ICE_CREAM_CONES(113), - - LIGHT_BULB(114), - - LIGHTNING_1(115), - - LIGHTNING_2(116), - - MAP_PINS(117), - - MAPLE_LEAF(118), - - MAPLE_MUFFINS(119), - - MARQUEE(120), - - MARQUEE_TOOTHED(121), - - MOONS(122), - - MOSAIC(123), - - MUSIC_NOTES(124), - - NORTHWEST(125), - - OVALS(126), - - PACKAGES(127), - - PALMS_BLACK(128), - - PALMS_COLOR(129), - - PAPER_CLIPS(130), - - PAPYRUS(131), - - PARTY_FAVOR(132), - - PARTY_GLASS(133), - - PENCILS(134), - - PEOPLE(135), - - PEOPLE_WAVING(136), - - PEOPLE_HATS(137), - - POINSETTIAS(138), - - POSTAGE_STAMP(139), - - PUMPKIN_1(140), - - PUSH_PIN_NOTE_2(141), - - PUSH_PIN_NOTE_1(142), - - PYRAMIDS(143), - - PYRAMIDS_ABOVE(144), - - QUADRANTS(145), - - RINGS(146), - - SAFARI(147), - - SAWTOOTH(148), - - SAWTOOTH_GRAY(149), - - SCARED_CAT(150), - - SEATTLE(151), - - SHADOWED_SQUARES(152), - - SHARKS_TEETH(153), - - SHOREBIRD_TRACKS(154), - - SKYROCKET(155), - - SNOWFLAKE_FANCY(156), - - SNOWFLAKES(157), - - SOMBRERO(158), - - SOUTHWEST(159), - - STARS(160), - - STARS_TOP(161), - - STARS_3_D(162), - - STARS_BLACK(163), - - STARS_SHADOWED(164), - - SUN(165), - - SWIRLIGIG(166), - - TORN_PAPER(167), - - TORN_PAPER_BLACK(168), - - TREES(169), - - TRIANGLE_PARTY(170), - - TRIANGLES(171), - - TRIBAL_1(172), - - TRIBAL_2(173), - - TRIBAL_3(174), - - TRIBAL_4(175), - - TRIBAL_5(176), - - TRIBAL_6(177), - - TWISTED_LINES_1(178), - - TWISTED_LINES_2(179), - - VINE(180), - - WAVELINE(181), - - WEAVING_ANGLES(182), - - WEAVING_BRAID(183), - - WEAVING_RIBBON(184), - - WEAVING_STRIPS(185), - - WHITE_FLOWERS(186), - - WOODWORK(187), - - X_ILLUSIONS(188), - - ZANY_TRIANGLES(189), - - ZIG_ZAG(190), - - ZIG_ZAG_STITCH(191); - - private static Map imap = new HashMap(); - - static { - for (Borders p : values()) { - imap.put(Integer.valueOf(p.getValue()), p); - } - } - - private final int value; - - private Borders(int val) { - value = val; - } - - public static Borders valueOf(int type) { - Borders pBorder = imap.get(Integer.valueOf(type)); - if (pBorder == null) { - throw new IllegalArgumentException("Unknown paragraph border: " + type); - } - return pBorder; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java deleted file mode 100644 index e44bb3b0f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies the set of possible restart locations which may be used as to - * determine the next available line when a break's type attribute has a value - * of textWrapping. - * - * @author Gisella Bronzetti - */ -public enum BreakClear { - - /** - * Specifies that the text wrapping break shall advance the text to the next - * line in the WordprocessingML document, regardless of its position left to - * right or the presence of any floating objects which intersect with the - * line, - *

        - * This is the setting for a typical line break in a document. - */ - - NONE(1), - - /** - * Specifies that the text wrapping break shall behave as follows: - *

          - *
        • If this line is broken into multiple regions (a floating object in - * the center of the page has text wrapping on both sides: - *
            - *
          • If this is the leftmost region of text flow on this line, advance - * the text to the next position on the line
          • - *
          • Otherwise, treat this as a text wrapping break of type all.
          • - *
          - *
        • - *
        • If this line is not broken into multiple regions, then treat this - * break as a text wrapping break of type none.
        • - *
        - *
      • If the parent paragraph is right to left, then these behaviors are - * also reversed.
      • - */ - LEFT(2), - - /** - * Specifies that the text wrapping break shall behave as follows: - *
          - *
        • If this line is broken into multiple regions (a floating object in - * the center of the page has text wrapping on both sides: - *
            - *
          • If this is the rightmost region of text flow on this line, advance - * the text to the next position on the next line
          • - *
          • Otherwise, treat this as a text wrapping break of type all.
          • - *
          - *
        • If this line is not broken into multiple regions, then treat this - * break as a text wrapping break of type none.
        • - *
        • If the parent paragraph is right to left, then these beha viors are - * also reversed.
        • - *
        - */ - RIGHT(3), - - /** - * Specifies that the text wrapping break shall advance the text to the next - * line in the WordprocessingML document which spans the full width of the - * line. - */ - ALL(4); - - private static Map imap = new HashMap(); - - static { - for (BreakClear p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private BreakClear(int val) { - value = val; - } - - public static BreakClear valueOf(int type) { - BreakClear bType = imap.get(type); - if (bType == null) - throw new IllegalArgumentException("Unknown break clear type: " - + type); - return bType; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java deleted file mode 100644 index 30fc939cb..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies the possible types of break characters in a WordprocessingML - * document. - * The break type determines the next location where text shall be - * placed after this manual break is applied to the text contents - * - * @author Gisella Bronzetti - */ -public enum BreakType { - - - /** - * Specifies that the current break shall restart itself on the next page of - * the document when the document is displayed in page view. - */ - PAGE(1), - - /** - * Specifies that the current break shall restart itself on the next column - * available on the current page when the document is displayed in page - * view. - *

        - * If the current section is not divided into columns, or the column break - * occurs in the last column on the current page when displayed, then the - * restart location for text shall be the next page in the document. - *

        - */ - COLUMN(2), - - /** - * Specifies that the current break shall restart itself on the next line in - * the document when the document is displayed in page view. - * The determine of the next line shall be done subject to the value of the clear - * attribute on the specified break character. - */ - TEXT_WRAPPING(3); - - private static Map imap = new HashMap(); - - static { - for (BreakType p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private BreakType(int val) { - value = val; - } - - public static BreakType valueOf(int type) { - BreakType bType = imap.get(type); - if (bType == null) - throw new IllegalArgumentException("Unknown break type: " - + type); - return bType; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java deleted file mode 100644 index 077697a16..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -public interface Document { - /** - * Extended windows meta file - */ - public static final int PICTURE_TYPE_EMF = 2; - - /** - * Windows Meta File - */ - public static final int PICTURE_TYPE_WMF = 3; - - /** - * Mac PICT format - */ - public static final int PICTURE_TYPE_PICT = 4; - - /** - * JPEG format - */ - public static final int PICTURE_TYPE_JPEG = 5; - - /** - * PNG format - */ - public static final int PICTURE_TYPE_PNG = 6; - - /** - * Device independent bitmap - */ - public static final int PICTURE_TYPE_DIB = 7; - - /** - * GIF image format - */ - public static final int PICTURE_TYPE_GIF = 8; - - /** - * Tag Image File (.tiff) - */ - public static final int PICTURE_TYPE_TIFF = 9; - - /** - * Encapsulated Postscript (.eps) - */ - public static final int PICTURE_TYPE_EPS = 10; - - - /** - * Windows Bitmap (.bmp) - */ - public static final int PICTURE_TYPE_BMP = 11; - - /** - * WordPerfect graphics (.wpg) - */ - public static final int PICTURE_TYPE_WPG = 12; -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java deleted file mode 100644 index 6e9ce05e4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.xmlbeans.XmlCursor; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; - -/** - *

        An IBody represents the different parts of the document which - * can contain collections of Paragraphs and Tables. It provides a - * common way to work with these and their contents.

        - *

        Typically, this is something like a XWPFDocument, or one of - * the parts in it like XWPFHeader, XWPFFooter, XWPFTableCell - *

        - */ -public interface IBody { - /** - * returns the Part, to which the body belongs, which you need for adding relationship to other parts - * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell - * belongs. - * - * @return the Part, to which the body belongs - */ - public POIXMLDocumentPart getPart(); - - /** - * get the PartType of the body, for example - * DOCUMENT, HEADER, FOOTER, FOOTNOTE, - * - * @return the PartType of the body - */ - public BodyType getPartType(); - - /** - * Returns an Iterator with paragraphs and tables, - * in the order that they occur in the text. - */ - public List getBodyElements(); - - /** - * Returns the paragraph(s) that holds - * the text of the header or footer. - */ - public List getParagraphs(); - - /** - * Return the table(s) that holds the text - * of the IBodyPart, for complex cases - * where a paragraph isn't used. - */ - public List getTables(); - - /** - * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer - * the method will return this paragraph - * if there is no corresponding {@link XWPFParagraph} the method will return null - * - * @param p is instance of CTP and is searching for an XWPFParagraph - * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer - * XWPFParagraph with the correspondig CTP p - */ - public XWPFParagraph getParagraph(CTP p); - - /** - * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header - * the method will return this table - * if there is no corresponding {@link XWPFTable} the method will return null - * - * @param ctTable - */ - public XWPFTable getTable(CTTbl ctTable); - - /** - * Returns the paragraph that of position pos - */ - public XWPFParagraph getParagraphArray(int pos); - - /** - * Returns the table at position pos - */ - public XWPFTable getTableArray(int pos); - - /** - * inserts a new paragraph at position of the cursor - * - * @param cursor - */ - public XWPFParagraph insertNewParagraph(XmlCursor cursor); - - /** - * inserts a new Table at the cursor position. - * - * @param cursor - */ - public XWPFTable insertNewTbl(XmlCursor cursor); - - /** - * inserts a new Table at position pos - * - * @param pos - * @param table - */ - void insertTable(int pos, XWPFTable table); - - /** - * returns the TableCell to which the Table belongs - * - * @param cell - */ - public XWPFTableCell getTableCell(CTTc cell); - - /** - * Return XWPFDocument - */ - public XWPFDocument getXWPFDocument(); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java deleted file mode 100644 index 312ea493f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.POIXMLDocumentPart; - -/** - * 9 Jan 2010 - * - * @author Philipp Epp - */ -public interface IBodyElement { - IBody getBody(); - - POIXMLDocumentPart getPart(); - - BodyType getPartType(); - - BodyElementType getElementType(); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java deleted file mode 100644 index 0ac12c793..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Interface for anything that can be at a table cell level: - * {@link XWPFTableCell}, {@link XWPFSDTCell} - *

        - * Schematically something like this: - * <tr><tc/><tc/><sdt><tc/></sdt></tr> - */ -public interface ICell { -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java deleted file mode 100644 index fea7856d1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.POIXMLDocumentPart; -import org.apache.poi.wp.usermodel.Paragraph; - -/** - * Simple interface describing both {@link XWPFParagraph} - * and {@link XWPFSDT} - *

        - * TODO Should this be based on / extend {@link Paragraph}? - */ -public interface IRunBody { - public XWPFDocument getDocument(); - - public POIXMLDocumentPart getPart(); -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java deleted file mode 100644 index e8d1b83e7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.wp.usermodel.CharacterRun; - -/** - * Common interface for things that can occur - * where a run (text with common stylings) can, - * eg {@link XWPFRun} or {@link XWPFSDT}. - * TODO More methods to follow shortly! - *

        - * TODO Make this based on {@link CharacterRun} - */ -public interface IRunElement {} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java deleted file mode 100644 index 5493ff3bd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - - -/** - * Experimental interface to offer rudimentary read-only processing of - * of the contentblock of an SDT/ContentControl. - *

        - *

        - *

        - * WARNING - APIs expected to change rapidly - */ -public interface ISDTContent { - - public String getText(); - - public String toString(); - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java deleted file mode 100644 index 66922b837..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Interface for anything that can be within an SDT: - * {@link XWPFRun}, {@link XWPFTable}, {@link XWPFParagraph}, - * {@link XWPFSDT} etc - */ -public interface ISDTContents { -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java deleted file mode 100644 index b52d2c34f..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies the logic which shall be used to calculate the line spacing of the - * parent object when it is displayed in the document. - * - * @author Gisella Bronzetti - */ -public enum LineSpacingRule { - - /** - * Specifies that the line spacing of the parent object shall be - * automatically determined by the size of its contents, with no - * predetermined minimum or maximum size. - */ - - AUTO(1), - - /** - * Specifies that the height of the line shall be exactly the value - * specified, regardless of the size of the contents If the contents are too - * large for the specified height, then they shall be clipped as necessary. - */ - EXACT(2), - - /** - * Specifies that the height of the line shall be at least the value - * specified, but may be expanded to fit its content as needed. - */ - AT_LEAST(3); - - - private static Map imap = new HashMap(); - - static { - for (LineSpacingRule p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private LineSpacingRule(int val) { - value = val; - } - - public static LineSpacingRule valueOf(int type) { - LineSpacingRule lineType = imap.get(type); - if (lineType == null) - throw new IllegalArgumentException("Unknown line type: " + type); - return lineType; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java deleted file mode 100644 index 7cffb30a5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies all types of 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 static Map imap = new HashMap(); - - static { - for (ParagraphAlignment p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private ParagraphAlignment(int val) { - value = val; - } - - public static ParagraphAlignment valueOf(int type) { - ParagraphAlignment err = imap.get(type); - if (err == null) throw new IllegalArgumentException("Unknown paragraph alignment: " + type); - return err; - } - - public int getValue() { - return value; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java deleted file mode 100644 index 4eebe412e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - - -/** - * postion of a character in a paragrapho - * 1st RunPositon - * 2nd TextPosition - * 3rd CharacterPosition - */ -public class PositionInParagraph { - private int posRun = 0, posText = 0, posChar = 0; - - public PositionInParagraph() { - } - - public PositionInParagraph(int posRun, int posText, int posChar) { - this.posRun = posRun; - this.posChar = posChar; - this.posText = posText; - } - - public int getRun() { - return posRun; - } - - public void setRun(int beginRun) { - this.posRun = beginRun; - } - - public int getText() { - return posText; - } - - public void setText(int beginText) { - this.posText = beginText; - } - - public int getChar() { - return posChar; - } - - public void setChar(int beginChar) { - this.posChar = beginChar; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java deleted file mode 100644 index a75fc8485..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java +++ /dev/null @@ -1,123 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.math.BigInteger; - -import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; -import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute.Space; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtEndPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabs; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabTlc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTheme; - -public class TOC { - - CTSdtBlock block; - - public TOC() { - this(CTSdtBlock.Factory.newInstance()); - } - - public TOC(CTSdtBlock block) { - this.block = block; - CTSdtPr sdtPr = block.addNewSdtPr(); - CTDecimalNumber id = sdtPr.addNewId(); - id.setVal(new BigInteger("4844945")); - sdtPr.addNewDocPartObj().addNewDocPartGallery().setVal("Table of contents"); - CTSdtEndPr sdtEndPr = block.addNewSdtEndPr(); - CTRPr rPr = sdtEndPr.addNewRPr(); - CTFonts fonts = rPr.addNewRFonts(); - fonts.setAsciiTheme(STTheme.MINOR_H_ANSI); - fonts.setEastAsiaTheme(STTheme.MINOR_H_ANSI); - fonts.setHAnsiTheme(STTheme.MINOR_H_ANSI); - fonts.setCstheme(STTheme.MINOR_BIDI); - rPr.addNewB().setVal(STOnOff.OFF); - rPr.addNewBCs().setVal(STOnOff.OFF); - rPr.addNewColor().setVal("auto"); - rPr.addNewSz().setVal(new BigInteger("24")); - rPr.addNewSzCs().setVal(new BigInteger("24")); - CTSdtContentBlock content = block.addNewSdtContent(); - CTP p = content.addNewP(); - p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252)); - p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252)); - p.addNewPPr().addNewPStyle().setVal("TOCHeading"); - p.addNewR().addNewT().setStringValue("Table of Contents"); - } - - @Internal - public CTSdtBlock getBlock() { - return this.block; - } - - public void addRow(int level, String title, int page, String bookmarkRef) { - CTSdtContentBlock contentBlock = this.block.getSdtContent(); - CTP p = contentBlock.addNewP(); - p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252)); - p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252)); - CTPPr pPr = p.addNewPPr(); - pPr.addNewPStyle().setVal("TOC" + level); - CTTabs tabs = pPr.addNewTabs(); - CTTabStop tab = tabs.addNewTab(); - tab.setVal(STTabJc.RIGHT); - tab.setLeader(STTabTlc.DOT); - tab.setPos(new BigInteger("8290")); - pPr.addNewRPr().addNewNoProof(); - CTR run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - run.addNewT().setStringValue(title); - run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - run.addNewTab(); - run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - run.addNewFldChar().setFldCharType(STFldCharType.BEGIN); - // pageref run - run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - CTText text = run.addNewInstrText(); - text.setSpace(Space.PRESERVE); - // bookmark reference - text.setStringValue(" PAGEREF _Toc" + bookmarkRef + " \\h "); - p.addNewR().addNewRPr().addNewNoProof(); - run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - run.addNewFldChar().setFldCharType(STFldCharType.SEPARATE); - // page number run - run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - run.addNewT().setStringValue(Integer.toString(page)); - run = p.addNewR(); - run.addNewRPr().addNewNoProof(); - run.addNewFldChar().setFldCharType(STFldCharType.END); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java deleted file mode 100644 index 1cc6434c9..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies all types of vertical alignment which are available to be applied to of all text - * on each line displayed within a paragraph. - * - * @author Gisella Bronzetti - */ -public enum TextAlignment { - /** - * Specifies that all text in the parent object shall be - * aligned to the top of each character when displayed - */ - TOP(1), - /** - * Specifies that all text in the parent object shall be - * aligned to the center of each character when displayed. - */ - CENTER(2), - /** - * Specifies that all text in the parent object shall be - * aligned to the baseline of each character when displayed. - */ - BASELINE(3), - /** - * Specifies that all text in the parent object shall be - * aligned to the bottom of each character when displayed. - */ - BOTTOM(4), - /** - * Specifies that all text in the parent object shall be - * aligned automatically when displayed. - */ - AUTO(5); - - private static Map imap = new HashMap(); - - static { - for (TextAlignment p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private TextAlignment(int val) { - value = val; - } - - public static TextAlignment valueOf(int type) { - TextAlignment align = imap.get(type); - if (align == null) throw new IllegalArgumentException("Unknown text alignment: " + type); - return align; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java deleted file mode 100644 index 44477daf8..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - - -/** - * saves the begin and end position of a text in a Paragraph - */ -public class TextSegement { - private PositionInParagraph beginPos; - private PositionInParagraph endPos; - - public TextSegement() { - this.beginPos = new PositionInParagraph(); - this.endPos = new PositionInParagraph(); - } - - public TextSegement(int beginRun, int endRun, int beginText, int endText, int beginChar, int endChar) { - PositionInParagraph beginPos = new PositionInParagraph(beginRun, beginText, beginChar); - PositionInParagraph endPos = new PositionInParagraph(endRun, endText, endChar); - this.beginPos = beginPos; - this.endPos = endPos; - } - - public TextSegement(PositionInParagraph beginPos, PositionInParagraph endPos) { - this.beginPos = beginPos; - this.endPos = endPos; - } - - public PositionInParagraph getBeginPos() { - return beginPos; - } - - public PositionInParagraph getEndPos() { - return endPos; - } - - public int getBeginRun() { - return beginPos.getRun(); - } - - public void setBeginRun(int beginRun) { - beginPos.setRun(beginRun); - } - - public int getBeginText() { - return beginPos.getText(); - } - - public void setBeginText(int beginText) { - beginPos.setText(beginText); - } - - public int getBeginChar() { - return beginPos.getChar(); - } - - public void setBeginChar(int beginChar) { - beginPos.setChar(beginChar); - } - - public int getEndRun() { - return endPos.getRun(); - } - - public void setEndRun(int endRun) { - endPos.setRun(endRun); - } - - public int getEndText() { - return endPos.getText(); - } - - public void setEndText(int endText) { - endPos.setText(endText); - } - - public int getEndChar() { - return endPos.getChar(); - } - - public void setEndChar(int endChar) { - endPos.setChar(endChar); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java deleted file mode 100644 index c99b17bd7..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java +++ /dev/null @@ -1,163 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies the types of patterns which may be used to create the underline - * applied beneath the text in a run. - * - * @author Gisella Bronzetti - */ -public enum UnderlinePatterns { - - /** - * Specifies an underline consisting of a single line beneath all characters - * in this run. - */ - SINGLE(1), - - /** - * Specifies an underline consisting of a single line beneath all non-space - * characters in the run. There shall be no underline beneath any space - * character (breaking or non-breaking). - */ - WORDS(2), - - /** - * Specifies an underline consisting of two lines beneath all characters in - * this run - */ - DOUBLE(3), - - /** - * Specifies an underline consisting of a single thick line beneath all - * characters in this run. - */ - THICK(4), - - /** - * Specifies an underline consisting of a series of dot characters beneath - * all characters in this run. - */ - DOTTED(5), - - /** - * Specifies an underline consisting of a series of thick dot characters - * beneath all characters in this run. - */ - DOTTED_HEAVY(6), - - /** - * Specifies an underline consisting of a dashed line beneath all characters - * in this run. - */ - DASH(7), - - /** - * Specifies an underline consisting of a series of thick dashes beneath all - * characters in this run. - */ - DASHED_HEAVY(8), - - /** - * Specifies an underline consisting of long dashed characters beneath all - * characters in this run. - */ - DASH_LONG(9), - - /** - * Specifies an underline consisting of thick long dashed characters beneath - * all characters in this run. - */ - DASH_LONG_HEAVY(10), - - /** - * Specifies an underline consisting of a series of dash, dot characters - * beneath all characters in this run. - */ - DOT_DASH(11), - - /** - * Specifies an underline consisting of a series of thick dash, dot - * characters beneath all characters in this run. - */ - DASH_DOT_HEAVY(12), - - /** - * Specifies an underline consisting of a series of dash, dot, dot - * characters beneath all characters in this run. - */ - DOT_DOT_DASH(13), - - /** - * Specifies an underline consisting of a series of thick dash, dot, dot - * characters beneath all characters in this run. - */ - DASH_DOT_DOT_HEAVY(14), - - /** - * Specifies an underline consisting of a single wavy line beneath all - * characters in this run. - */ - WAVE(15), - - /** - * Specifies an underline consisting of a single thick wavy line beneath all - * characters in this run. - */ - WAVY_HEAVY(16), - - /** - * Specifies an underline consisting of a pair of wavy lines beneath all - * characters in this run. - */ - WAVY_DOUBLE(17), - - /** - * Specifies no underline beneath this run. - */ - NONE(18); - - private static Map imap = new HashMap(); - - static { - for (UnderlinePatterns p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private UnderlinePatterns(int val) { - value = val; - } - - public static UnderlinePatterns valueOf(int type) { - UnderlinePatterns align = imap.get(type); - if (align == null) - throw new IllegalArgumentException("Unknown underline pattern: " - + type); - return align; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java deleted file mode 100644 index 7b7538d19..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -/** - * Specifies possible values for the alignment of the contents of this run in - * relation to the default appearance of the run's text. This allows the text to - * be repositioned as subscript or superscript without altering the font size of - * the run properties. - * - * @author Gisella Bronzetti - */ -public enum VerticalAlign { - - /** - * Specifies that the text in the parent run shall be located at the - * baseline and presented in the same size as surrounding text. - */ - BASELINE(1), - /** - * Specifies that this text should be subscript. This setting shall lower - * the text in this run below the baseline and change it to a smaller size, - * if a smaller size is available. - */ - SUPERSCRIPT(2), - /** - * Specifies that this text should be superscript. This setting shall raise - * the text in this run above the baseline and change it to a smaller size, - * if a smaller size is available. - */ - SUBSCRIPT(3); - - private static Map imap = new HashMap(); - - static { - for (VerticalAlign p : values()) { - imap.put(p.getValue(), p); - } - } - - private final int value; - - private VerticalAlign(int val) { - value = val; - } - - public static VerticalAlign valueOf(int type) { - VerticalAlign align = imap.get(type); - if (align == null) - throw new IllegalArgumentException("Unknown vertical alignment: " - + type); - return align; - } - - public int getValue() { - return value; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java deleted file mode 100644 index 8d4886b90..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum; - -/** - * @author Philipp Epp - */ -public class XWPFAbstractNum { - protected XWPFNumbering numbering; - private CTAbstractNum ctAbstractNum; - - protected XWPFAbstractNum() { - this.ctAbstractNum = null; - this.numbering = null; - - } - - public XWPFAbstractNum(CTAbstractNum abstractNum) { - this.ctAbstractNum = abstractNum; - } - - public XWPFAbstractNum(CTAbstractNum ctAbstractNum, XWPFNumbering numbering) { - this.ctAbstractNum = ctAbstractNum; - this.numbering = numbering; - } - - public CTAbstractNum getAbstractNum() { - return ctAbstractNum; - } - - public XWPFNumbering getNumbering() { - return numbering; - } - - public void setNumbering(XWPFNumbering numbering) { - this.numbering = numbering; - } - - public CTAbstractNum getCTAbstractNum() { - return ctAbstractNum; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java deleted file mode 100644 index 5f7fa5d8d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; - -/** - * Sketch of XWPF comment class - * - * @author Yury Batrakov (batrakov at gmail.com) - */ -public class XWPFComment { - protected String id; - protected String author; - protected StringBuffer text; - - public XWPFComment(CTComment comment, XWPFDocument document) { - text = new StringBuffer(); - id = comment.getId().toString(); - author = comment.getAuthor(); - - for (CTP ctp : comment.getPArray()) { - XWPFParagraph p = new XWPFParagraph(ctp, document); - text.append(p.getText()); - } - } - - public String getId() { - return id; - } - - public String getAuthor() { - return author; - } - - public String getText() { - return text.toString(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultParagraphStyle.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultParagraphStyle.java deleted file mode 100644 index a430c87e5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultParagraphStyle.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; - -/** - * Default Paragraph style, from which other styles will override - * TODO Share logic with {@link XWPFParagraph} which also uses CTPPr - */ -public class XWPFDefaultParagraphStyle { - private CTPPr ppr; - - public XWPFDefaultParagraphStyle(CTPPr ppr) { - this.ppr = ppr; - } - - protected CTPPr getPPr() { - return ppr; - } - - public int getSpacingAfter() { - if (ppr.isSetSpacing()) - return ppr.getSpacing().getAfter().intValue(); - return -1; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultRunStyle.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultRunStyle.java deleted file mode 100644 index 459335de6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultRunStyle.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; - -/** - * Default Character Run style, from which other styles will override - * TODO Share logic with {@link XWPFRun} which also uses CTRPr - */ -public class XWPFDefaultRunStyle { - private CTRPr rpr; - - public XWPFDefaultRunStyle(CTRPr rpr) { - this.rpr = rpr; - } - - protected CTRPr getRPr() { - return rpr; - } - - public int getFontSize() { - if (rpr.isSetSz()) - return rpr.getSz().getVal().intValue() / 2; - return -1; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java deleted file mode 100644 index 9afde2caf..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java +++ /dev/null @@ -1,1564 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocument; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.POIXMLProperties; -import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.IdentifierManager; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.PackageHelper; -import org.apache.poi.wp.usermodel.HeaderFooterType; -import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; - -/** - *

        High(ish) level class for working with .docx files.

        - *

        - *

        This class tries to hide some of the complexity - * of the underlying file format, but as it's not a - * mature and stable API yet, certain parts of the - * XML structure come through. You'll therefore almost - * certainly need to refer to the OOXML specifications - * from - * http://www.ecma-international.org/publications/standards/Ecma-376.htm - * at some point in your use.

        - */ -public class XWPFDocument extends POIXMLDocument implements Document, IBody { - private static final POILogger LOG = POILogFactory.getLogger(XWPFDocument.class); - - protected List footers = new ArrayList(); - protected List headers = new ArrayList(); - protected List comments = new ArrayList(); - protected List hyperlinks = new ArrayList(); - protected List paragraphs = new ArrayList(); - protected List tables = new ArrayList(); - protected List contentControls = new ArrayList(); - protected List bodyElements = new ArrayList(); - protected List pictures = new ArrayList(); - protected Map> packagePictures = new HashMap>(); - protected Map endnotes = new HashMap(); - protected XWPFNumbering numbering; - protected XWPFStyles styles; - protected XWPFFootnotes footnotes; - private CTDocument1 ctDocument; - private XWPFSettings settings; - /** - * Keeps track on all id-values used in this document and included parts, like headers, footers, etc. - */ - private IdentifierManager drawingIdManager = new IdentifierManager(0L, 4294967295L); - /** - * Handles the joy of different headers/footers for different pages - */ - private XWPFHeaderFooterPolicy headerFooterPolicy; - - public XWPFDocument(OPCPackage pkg) throws IOException { - super(pkg); - - //build a tree of POIXMLDocumentParts, this document being the root - load(XWPFFactory.getInstance()); - } - - public XWPFDocument(InputStream is) throws IOException { - super(PackageHelper.open(is)); - - //build a tree of POIXMLDocumentParts, this workbook being the root - load(XWPFFactory.getInstance()); - } - - public XWPFDocument() { - super(newPackage()); - onDocumentCreate(); - } - - /** - * Create a new WordProcessingML package and setup the default minimal content - */ - protected static OPCPackage newPackage() { - try { - OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream()); - // Main part - PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName()); - // Create main part relationship - pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT); - // Create main document part - pkg.createPart(corePartName, XWPFRelation.DOCUMENT.getContentType()); - - pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR); - - return pkg; - } catch (Exception e) { - throw new POIXMLException(e); - } - } - - @SuppressWarnings("deprecation") - @Override - protected void onDocumentRead() throws IOException { - try { - DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - ctDocument = doc.getDocument(); - - initFootnotes(); - - // parse the document with cursor and add - // the XmlObject to its lists - XmlCursor cursor = ctDocument.getBody().newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - bodyElements.add(p); - paragraphs.add(p); - } else if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - bodyElements.add(t); - tables.add(t); - } else if (o instanceof CTSdtBlock) { - XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this); - bodyElements.add(c); - contentControls.add(c); - } - } - cursor.dispose(); - - // Sort out headers and footers - if (doc.getDocument().getBody().getSectPr() != null) - headerFooterPolicy = new XWPFHeaderFooterPolicy(this); - - // Create for each XML-part in the Package a PartClass - for (RelationPart rp : getRelationParts()) { - POIXMLDocumentPart p = rp.getDocumentPart(); - String relation = rp.getRelationship().getRelationshipType(); - if (relation.equals(XWPFRelation.STYLES.getRelation())) { - this.styles = (XWPFStyles) p; - this.styles.onDocumentRead(); - } else if (relation.equals(XWPFRelation.NUMBERING.getRelation())) { - this.numbering = (XWPFNumbering) p; - this.numbering.onDocumentRead(); - } else if (relation.equals(XWPFRelation.FOOTER.getRelation())) { - XWPFFooter footer = (XWPFFooter) p; - footers.add(footer); - footer.onDocumentRead(); - } else if (relation.equals(XWPFRelation.HEADER.getRelation())) { - XWPFHeader header = (XWPFHeader) p; - headers.add(header); - header.onDocumentRead(); - } else if (relation.equals(XWPFRelation.COMMENT.getRelation())) { - // TODO Create according XWPFComment class, extending POIXMLDocumentPart - CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - for (CTComment ctcomment : cmntdoc.getComments().getCommentArray()) { - comments.add(new XWPFComment(ctcomment, this)); - } - } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) { - settings = (XWPFSettings) p; - settings.onDocumentRead(); - } else if (relation.equals(XWPFRelation.IMAGES.getRelation())) { - XWPFPictureData picData = (XWPFPictureData) p; - picData.onDocumentRead(); - registerPackagePictureData(picData); - pictures.add(picData); - } else if (relation.equals(XWPFRelation.GLOSSARY_DOCUMENT.getRelation())) { - // We don't currently process the glossary itself - // Until we do, we do need to load the glossary child parts of it - for (POIXMLDocumentPart gp : p.getRelations()) { - // Trigger the onDocumentRead for all the child parts - // Otherwise we'll hit issues on Styles, Settings etc on save - // TODO: Refactor this to not need to access protected method - // from other package! Remove the static helper method once fixed!!! - POIXMLDocumentPart._invokeOnDocumentRead(gp); - } - } - } - initHyperlinks(); - } catch (XmlException e) { - throw new POIXMLException(e); - } - } - - private void initHyperlinks() { - // Get the hyperlinks - // TODO: make me optional/separated in private function - try { - Iterator relIter = - getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator(); - while (relIter.hasNext()) { - PackageRelationship rel = relIter.next(); - hyperlinks.add(new XWPFHyperlink(rel.getId(), rel.getTargetURI().toString())); - } - } catch (InvalidFormatException e) { - throw new POIXMLException(e); - } - } - - private void initFootnotes() throws XmlException, IOException { - for (RelationPart rp : getRelationParts()) { - POIXMLDocumentPart p = rp.getDocumentPart(); - String relation = rp.getRelationship().getRelationshipType(); - if (relation.equals(XWPFRelation.FOOTNOTE.getRelation())) { - this.footnotes = (XWPFFootnotes) p; - this.footnotes.onDocumentRead(); - } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())) { - EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); - - for (CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteArray()) { - endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn)); - } - } - } - } - - /** - * Create a new CTWorkbook with all values set to default - */ - @Override - protected void onDocumentCreate() { - ctDocument = CTDocument1.Factory.newInstance(); - ctDocument.addNewBody(); - - settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS, XWPFFactory.getInstance()); - - POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties(); - expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR); - } - - /** - * Returns the low level document base object - */ - @Internal - public CTDocument1 getDocument() { - return ctDocument; - } - - IdentifierManager getDrawingIdManager() { - return drawingIdManager; - } - - /** - * returns an Iterator with paragraphs and tables - * - * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements() - */ - @Override - public List getBodyElements() { - return Collections.unmodifiableList(bodyElements); - } - - public Iterator getBodyElementsIterator() { - return bodyElements.iterator(); - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphs() - */ - @Override - public List getParagraphs() { - return Collections.unmodifiableList(paragraphs); - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getTables() - */ - @Override - public List getTables() { - return Collections.unmodifiableList(tables); - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) - */ - @Override - public XWPFTable getTableArray(int pos) { - if (pos >= 0 && pos < tables.size()) { - return tables.get(pos); - } - return null; - } - - /** - * @return the list of footers - */ - public List getFooterList() { - return Collections.unmodifiableList(footers); - } - - public XWPFFooter getFooterArray(int pos) { - if(pos >=0 && pos < footers.size()) { - return footers.get(pos); - } - return null; - } - - /** - * @return the list of headers - */ - public List getHeaderList() { - return Collections.unmodifiableList(headers); - } - - public XWPFHeader getHeaderArray(int pos) { - if(pos >=0 && pos < headers.size()) { - return headers.get(pos); - } - return null; - } - - public String getTblStyle(XWPFTable table) { - return table.getStyleID(); - } - - public XWPFHyperlink getHyperlinkByID(String id) { - for (XWPFHyperlink link : hyperlinks) { - if (link.getId().equals(id)) - return link; - } - - return null; - } - - public XWPFFootnote getFootnoteByID(int id) { - if (footnotes == null) return null; - return footnotes.getFootnoteById(id); - } - - public XWPFFootnote getEndnoteByID(int id) { - if (endnotes == null) return null; - return endnotes.get(id); - } - - public List getFootnotes() { - if (footnotes == null) { - return Collections.emptyList(); - } - return footnotes.getFootnotesList(); - } - - public XWPFHyperlink[] getHyperlinks() { - return hyperlinks.toArray(new XWPFHyperlink[hyperlinks.size()]); - } - - public XWPFComment getCommentByID(String id) { - for (XWPFComment comment : comments) { - if (comment.getId().equals(id)) - return comment; - } - - return null; - } - - public XWPFComment[] getComments() { - return comments.toArray(new XWPFComment[comments.size()]); - } - - /** - * Get the document part that's defined as the - * given relationship of the core document. - */ - public PackagePart getPartById(String id) { - try { - PackagePart corePart = getCorePart(); - return corePart.getRelatedPart(corePart.getRelationship(id)); - } catch (InvalidFormatException e) { - throw new IllegalArgumentException(e); - } - } - - /** - * Returns the policy on headers and footers, which - * also provides a way to get at them. - */ - public XWPFHeaderFooterPolicy getHeaderFooterPolicy() { - return headerFooterPolicy; - } - public XWPFHeaderFooterPolicy createHeaderFooterPolicy() { - if (headerFooterPolicy == null) { -// if (! ctDocument.getBody().isSetSectPr()) { -// ctDocument.getBody().addNewSectPr(); -// } - headerFooterPolicy = new XWPFHeaderFooterPolicy(this); - } - return headerFooterPolicy; - } - - /** - * Create a header of the given type - * - * @param type {@link HeaderFooterType} enum - * @return object of type {@link XWPFHeader} - */ - public XWPFHeader createHeader(HeaderFooterType type) { - XWPFHeaderFooterPolicy hfPolicy = createHeaderFooterPolicy(); - // TODO this needs to be migrated out into section code - if (type == HeaderFooterType.FIRST) { - CTSectPr ctSectPr = getSection(); - if (ctSectPr.isSetTitlePg() == false) { - CTOnOff titlePg = ctSectPr.addNewTitlePg(); - titlePg.setVal(STOnOff.ON); - } - // } else if (type == HeaderFooterType.EVEN) { - // TODO Add support for Even/Odd headings and footers - } - return hfPolicy.createHeader(STHdrFtr.Enum.forInt(type.toInt())); - } - - - /** - * Create a footer of the given type - * - * @param type {@link HeaderFooterType} enum - * @return object of type {@link XWPFFooter} - */ - public XWPFFooter createFooter(HeaderFooterType type) { - XWPFHeaderFooterPolicy hfPolicy = createHeaderFooterPolicy(); - // TODO this needs to be migrated out into section code - if (type == HeaderFooterType.FIRST) { - CTSectPr ctSectPr = getSection(); - if (ctSectPr.isSetTitlePg() == false) { - CTOnOff titlePg = ctSectPr.addNewTitlePg(); - titlePg.setVal(STOnOff.ON); - } - // } else if (type == HeaderFooterType.EVEN) { - // TODO Add support for Even/Odd headings and footers - } - return hfPolicy.createFooter(STHdrFtr.Enum.forInt(type.toInt())); - } - - /** - * Return the {@link CTSectPr} object that corresponds with the - * last section in this document. - * - * @return {@link CTSectPr} object - */ - private CTSectPr getSection() { - CTBody ctBody = getDocument().getBody(); - return (ctBody.isSetSectPr() ? - ctBody.getSectPr() : - ctBody.addNewSectPr()); - } - - /** - * Returns the styles object used - */ - @Internal - public CTStyles getStyle() throws XmlException, IOException { - PackagePart[] parts; - try { - parts = getRelatedByType(XWPFRelation.STYLES.getRelation()); - } catch (InvalidFormatException e) { - throw new IllegalStateException(e); - } - if (parts.length != 1) { - throw new IllegalStateException("Expecting one Styles document part, but found " + parts.length); - } - - StylesDocument sd = StylesDocument.Factory.parse(parts[0].getInputStream(), DEFAULT_XML_OPTIONS); - return sd.getStyles(); - } - - /** - * Get the document's embedded files. - */ - @Override - public List getAllEmbedds() throws OpenXML4JException { - List embedds = new LinkedList(); - - // Get the embeddings for the workbook - PackagePart part = getPackagePart(); - for (PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE)) { - embedds.add(part.getRelatedPart(rel)); - } - - for (PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE)) { - embedds.add(part.getRelatedPart(rel)); - } - - return embedds; - } - - /** - * Finds that for example the 2nd entry in the body list is the 1st paragraph - */ - private int getBodyElementSpecificPos(int pos, List list) { - // If there's nothing to find, skip it - if (list.size() == 0) { - return -1; - } - - if (pos >= 0 && pos < bodyElements.size()) { - // Ensure the type is correct - IBodyElement needle = bodyElements.get(pos); - if (needle.getElementType() != list.get(0).getElementType()) { - // Wrong type - return -1; - } - - // Work back until we find it - int startPos = Math.min(pos, list.size() - 1); - for (int i = startPos; i >= 0; i--) { - if (list.get(i) == needle) { - return i; - } - } - } - - // Couldn't be found - return -1; - } - - /** - * Look up the paragraph at the specified position in the body elements list - * and return this paragraphs position in the paragraphs list - * - * @param pos The position of the relevant paragraph in the body elements - * list - * @return the position of the paragraph in the paragraphs list, if there is - * a paragraph at the position in the bodyelements list. Else it - * will return -1 - */ - public int getParagraphPos(int pos) { - return getBodyElementSpecificPos(pos, paragraphs); - } - - /** - * get with the position of a table in the bodyelement array list - * the position of this table in the table array list - * - * @param pos position of the table in the bodyelement array list - * @return if there is a table at the position in the bodyelement array list, - * else it will return null. - */ - public int getTablePos(int pos) { - return getBodyElementSpecificPos(pos, tables); - } - - /** - * Add a new paragraph at position of the cursor. The cursor must be on the - * {@link org.apache.xmlbeans.XmlCursor.TokenType#START} tag of an subelement - * of the documents body. When this method is done, the cursor passed as - * parameter points to the {@link org.apache.xmlbeans.XmlCursor.TokenType#END} - * of the newly inserted paragraph. - * - * @param cursor - * @return the {@link XWPFParagraph} object representing the newly inserted - * CTP object - */ - @Override - public XWPFParagraph insertNewParagraph(XmlCursor cursor) { - if (isCursorInBody(cursor)) { - String uri = CTP.type.getName().getNamespaceURI(); - /* - * TODO DO not use a coded constant, find the constant in the OOXML - * classes instead, as the child of type CT_Paragraph is defined in the - * OOXML schema as 'p' - */ - String localPart = "p"; - // creates a new Paragraph, cursor is positioned inside the new - // element - cursor.beginElement(localPart, uri); - // move the cursor to the START token to the paragraph just created - cursor.toParent(); - CTP p = (CTP) cursor.getObject(); - XWPFParagraph newP = new XWPFParagraph(p, this); - XmlObject o = null; - /* - * move the cursor to the previous element until a) the next - * paragraph is found or b) all elements have been passed - */ - while (!(o instanceof CTP) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - /* - * if the object that has been found is a) not a paragraph or b) is - * the paragraph that has just been inserted, as the cursor in the - * while loop above was not moved as there were no other siblings, - * then the paragraph that was just inserted is the first paragraph - * in the body. Otherwise, take the previous paragraph and calculate - * the new index for the new paragraph. - */ - if ((!(o instanceof CTP)) || (CTP) o == p) { - paragraphs.add(0, newP); - } else { - int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1; - paragraphs.add(pos, newP); - } - - /* - * create a new cursor, that points to the START token of the just - * inserted paragraph - */ - XmlCursor newParaPos = p.newCursor(); - try { - /* - * Calculate the paragraphs index in the list of all body - * elements - */ - int i = 0; - cursor.toCursor(newParaPos); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newP); - cursor.toCursor(newParaPos); - cursor.toEndToken(); - return newP; - } finally { - newParaPos.dispose(); - } - } - return null; - } - - @Override - public XWPFTable insertNewTbl(XmlCursor cursor) { - if (isCursorInBody(cursor)) { - String uri = CTTbl.type.getName().getNamespaceURI(); - String localPart = "tbl"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTTbl t = (CTTbl) cursor.getObject(); - XWPFTable newT = new XWPFTable(t, this); - XmlObject o = null; - while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if (!(o instanceof CTTbl)) { - tables.add(0, newT); - } else { - int pos = tables.indexOf(getTable((CTTbl) o)) + 1; - tables.add(pos, newT); - } - int i = 0; - XmlCursor tableCursor = t.newCursor(); - try { - cursor.toCursor(tableCursor); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newT); - cursor.toCursor(tableCursor); - cursor.toEndToken(); - return newT; - } finally { - tableCursor.dispose(); - } - } - return null; - } - - /** - * verifies that cursor is on the right position - * - * @param cursor - */ - private boolean isCursorInBody(XmlCursor cursor) { - XmlCursor verify = cursor.newCursor(); - verify.toParent(); - boolean result = (verify.getObject() == this.ctDocument.getBody()); - verify.dispose(); - return result; - } - - private int getPosOfBodyElement(IBodyElement needle) { - BodyElementType type = needle.getElementType(); - IBodyElement current; - for (int i = 0; i < bodyElements.size(); i++) { - current = bodyElements.get(i); - if (current.getElementType() == type) { - if (current.equals(needle)) { - return i; - } - } - } - return -1; - } - - /** - * Get the position of the paragraph, within the list - * of all the body elements. - * - * @param p The paragraph to find - * @return The location, or -1 if the paragraph couldn't be found - */ - public int getPosOfParagraph(XWPFParagraph p) { - return getPosOfBodyElement(p); - } - - /** - * Get the position of the table, within the list of - * all the body elements. - * - * @param t The table to find - * @return The location, or -1 if the table couldn't be found - */ - public int getPosOfTable(XWPFTable t) { - return getPosOfBodyElement(t); - } - - /** - * commit and saves the document - */ - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDocument1.type.getName().getNamespaceURI(), "document")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - ctDocument.save(out, xmlOptions); - out.close(); - } - - /** - * Gets the index of the relation we're trying to create - * - * @param relation - * @return i - */ - private int getRelationIndex(XWPFRelation relation) { - int i = 1; - for (RelationPart rp : getRelationParts()) { - if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) { - i++; - } - } - return i; - } - - /** - * Appends a new paragraph to this document - * - * @return a new paragraph - */ - public XWPFParagraph createParagraph() { - XWPFParagraph p = new XWPFParagraph(ctDocument.getBody().addNewP(), this); - bodyElements.add(p); - paragraphs.add(p); - return p; - } - - /** - * Creates an empty numbering if one does not already exist and sets the numbering member - * - * @return numbering - */ - public XWPFNumbering createNumbering() { - if (numbering == null) { - NumberingDocument numberingDoc = NumberingDocument.Factory.newInstance(); - - XWPFRelation relation = XWPFRelation.NUMBERING; - int i = getRelationIndex(relation); - - XWPFNumbering wrapper = (XWPFNumbering) createRelationship(relation, XWPFFactory.getInstance(), i); - wrapper.setNumbering(numberingDoc.addNewNumbering()); - numbering = wrapper; - } - - return numbering; - } - - /** - * Creates an empty styles for the document if one does not already exist - * - * @return styles - */ - public XWPFStyles createStyles() { - if (styles == null) { - StylesDocument stylesDoc = StylesDocument.Factory.newInstance(); - - XWPFRelation relation = XWPFRelation.STYLES; - int i = getRelationIndex(relation); - - XWPFStyles wrapper = (XWPFStyles) createRelationship(relation, XWPFFactory.getInstance(), i); - wrapper.setStyles(stylesDoc.addNewStyles()); - styles = wrapper; - } - - return styles; - } - - /** - * Creates an empty footnotes element for the document if one does not already exist - * - * @return footnotes - */ - public XWPFFootnotes createFootnotes() { - if (footnotes == null) { - FootnotesDocument footnotesDoc = FootnotesDocument.Factory.newInstance(); - - XWPFRelation relation = XWPFRelation.FOOTNOTE; - int i = getRelationIndex(relation); - - XWPFFootnotes wrapper = (XWPFFootnotes) createRelationship(relation, XWPFFactory.getInstance(), i); - wrapper.setFootnotes(footnotesDoc.addNewFootnotes()); - footnotes = wrapper; - } - - return footnotes; - } - - public XWPFFootnote addFootnote(CTFtnEdn note) { - return footnotes.addFootnote(note); - } - - public XWPFFootnote addEndnote(CTFtnEdn note) { - XWPFFootnote endnote = new XWPFFootnote(this, note); - endnotes.put(note.getId().intValue(), endnote); - return endnote; - } - - /** - * remove a BodyElement from bodyElements array list - * - * @param pos - * @return true if removing was successfully, else return false - */ - public boolean removeBodyElement(int pos) { - if (pos >= 0 && pos < bodyElements.size()) { - BodyElementType type = bodyElements.get(pos).getElementType(); - if (type == BodyElementType.TABLE) { - int tablePos = getTablePos(pos); - tables.remove(tablePos); - ctDocument.getBody().removeTbl(tablePos); - } - if (type == BodyElementType.PARAGRAPH) { - int paraPos = getParagraphPos(pos); - paragraphs.remove(paraPos); - ctDocument.getBody().removeP(paraPos); - } - bodyElements.remove(pos); - return true; - } - return false; - } - - /** - * copies content of a paragraph to a existing paragraph in the list paragraphs at position pos - * - * @param paragraph - * @param pos - */ - public void setParagraph(XWPFParagraph paragraph, int pos) { - paragraphs.set(pos, paragraph); - ctDocument.getBody().setPArray(pos, paragraph.getCTP()); - /* TODO update body element, update xwpf element, verify that - * incoming paragraph belongs to this document or if not, XML was - * copied properly (namespace-abbreviations, etc.) - */ - } - - /** - * @return the LastParagraph of the document - */ - public XWPFParagraph getLastParagraph() { - int lastPos = paragraphs.toArray().length - 1; - return paragraphs.get(lastPos); - } - - /** - * Create an empty table with one row and one column as default. - * - * @return a new table - */ - public XWPFTable createTable() { - XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this); - bodyElements.add(table); - tables.add(table); - return table; - } - - /** - * Create an empty table with a number of rows and cols specified - * - * @param rows - * @param cols - * @return table - */ - public XWPFTable createTable(int rows, int cols) { - XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this, rows, cols); - bodyElements.add(table); - tables.add(table); - return table; - } - - /** - * - */ - public void createTOC() { - CTSdtBlock block = this.getDocument().getBody().addNewSdt(); - TOC toc = new TOC(block); - for (XWPFParagraph par : paragraphs) { - String parStyle = par.getStyle(); - if (parStyle != null && parStyle.startsWith("Heading")) { - try { - int level = Integer.parseInt(parStyle.substring("Heading".length())); - toc.addRow(level, par.getText(), 1, "112723803"); - } catch (NumberFormatException e) { - LOG.log(POILogger.ERROR, "can't format number in TOC heading", e); - } - } - } - } - - /** - * Replace content of table in array tables at position pos with a - * - * @param pos - * @param table - */ - public void setTable(int pos, XWPFTable table) { - tables.set(pos, table); - ctDocument.getBody().setTblArray(pos, table.getCTTbl()); - } - - /** - * Verifies that the documentProtection tag in settings.xml file
        - * specifies that the protection is enforced (w:enforcement="1")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option any - */ - public boolean isEnforcedProtection() { - return settings.isEnforcedWith(); - } - - /** - * Verifies that the documentProtection tag in settings.xml file
        - * specifies that the protection is enforced (w:enforcement="1")
        - * and that the kind of protection is readOnly (w:edit="readOnly")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option readOnly - */ - public boolean isEnforcedReadonlyProtection() { - return settings.isEnforcedWith(STDocProtect.READ_ONLY); - } - - /** - * Verifies that the documentProtection tag in settings.xml file
        - * specifies that the protection is enforced (w:enforcement="1")
        - * and that the kind of protection is forms (w:edit="forms")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="forms" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option forms - */ - public boolean isEnforcedFillingFormsProtection() { - return settings.isEnforcedWith(STDocProtect.FORMS); - } - - /** - * Verifies that the documentProtection tag in settings.xml file
        - * specifies that the protection is enforced (w:enforcement="1")
        - * and that the kind of protection is comments (w:edit="comments")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="comments" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option comments - */ - public boolean isEnforcedCommentsProtection() { - return settings.isEnforcedWith(STDocProtect.COMMENTS); - } - - /** - * Verifies that the documentProtection tag in settings.xml file
        - * specifies that the protection is enforced (w:enforcement="1")
        - * and that the kind of protection is trackedChanges (w:edit="trackedChanges")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="trackedChanges" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option trackedChanges - */ - public boolean isEnforcedTrackedChangesProtection() { - return settings.isEnforcedWith(STDocProtect.TRACKED_CHANGES); - } - - public boolean isEnforcedUpdateFields() { - return settings.isUpdateFields(); - } - - /** - * Enforces the readOnly protection.
        - * In the documentProtection tag inside settings.xml file,
        - * it sets the value of enforcement to "1" (w:enforcement="1")
        - * and the value of edit to readOnly (w:edit="readOnly")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
        -     * 
        - */ - public void enforceReadonlyProtection() { - settings.setEnforcementEditValue(STDocProtect.READ_ONLY); - } - - /** - * Enforces the readOnly protection with a password.
        - *
        - * sample snippet from settings.xml - *
        -     *   <w:documentProtection w:edit="readOnly" w:enforcement="1"
        -     *       w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
        -     *       w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
        -     *       w:cryptSpinCount="100000" w:hash="..." w:salt="...."
        -     *   />
        -     * 
        - * - * @param password the plaintext password, if null no password will be applied - * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported. - * if null, it will default default to sha1 - */ - public void enforceReadonlyProtection(String password, HashAlgorithm hashAlgo) { - settings.setEnforcementEditValue(STDocProtect.READ_ONLY, password, hashAlgo); - } - - /** - * Enforce the Filling Forms protection.
        - * In the documentProtection tag inside settings.xml file,
        - * it sets the value of enforcement to "1" (w:enforcement="1")
        - * and the value of edit to forms (w:edit="forms")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="forms" w:enforcement="1"/>
        -     * 
        - */ - public void enforceFillingFormsProtection() { - settings.setEnforcementEditValue(STDocProtect.FORMS); - } - - /** - * Enforce the Filling Forms protection.
        - *
        - * sample snippet from settings.xml - *
        -     *   <w:documentProtection w:edit="forms" w:enforcement="1"
        -     *       w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
        -     *       w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
        -     *       w:cryptSpinCount="100000" w:hash="..." w:salt="...."
        -     *   />
        -     * 
        - * - * @param password the plaintext password, if null no password will be applied - * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported. - * if null, it will default default to sha1 - */ - public void enforceFillingFormsProtection(String password, HashAlgorithm hashAlgo) { - settings.setEnforcementEditValue(STDocProtect.FORMS, password, hashAlgo); - } - - /** - * Enforce the Comments protection.
        - * In the documentProtection tag inside settings.xml file,
        - * it sets the value of enforcement to "1" (w:enforcement="1")
        - * and the value of edit to comments (w:edit="comments")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="comments" w:enforcement="1"/>
        -     * 
        - */ - public void enforceCommentsProtection() { - settings.setEnforcementEditValue(STDocProtect.COMMENTS); - } - - /** - * Enforce the Comments protection.
        - *
        - * sample snippet from settings.xml - *
        -     *   <w:documentProtection w:edit="comments" w:enforcement="1"
        -     *       w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
        -     *       w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
        -     *       w:cryptSpinCount="100000" w:hash="..." w:salt="...."
        -     *   />
        -     * 
        - * - * @param password the plaintext password, if null no password will be applied - * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported. - * if null, it will default default to sha1 - */ - public void enforceCommentsProtection(String password, HashAlgorithm hashAlgo) { - settings.setEnforcementEditValue(STDocProtect.COMMENTS, password, hashAlgo); - } - - /** - * Enforce the Tracked Changes protection.
        - * In the documentProtection tag inside settings.xml file,
        - * it sets the value of enforcement to "1" (w:enforcement="1")
        - * and the value of edit to trackedChanges (w:edit="trackedChanges")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="trackedChanges" w:enforcement="1"/>
        -     * 
        - */ - public void enforceTrackedChangesProtection() { - settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES); - } - - /** - * Enforce the Tracked Changes protection.
        - *
        - * sample snippet from settings.xml - *
        -     *   <w:documentProtection w:edit="trackedChanges" w:enforcement="1"
        -     *       w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
        -     *       w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
        -     *       w:cryptSpinCount="100000" w:hash="..." w:salt="...."
        -     *   />
        -     * 
        - * - * @param password the plaintext password, if null no password will be applied - * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported. - * if null, it will default default to sha1 - */ - public void enforceTrackedChangesProtection(String password, HashAlgorithm hashAlgo) { - settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES, password, hashAlgo); - } - - /** - * Validates the existing password - * - * @param password - * @return true, only if password was set and equals, false otherwise - */ - public boolean validateProtectionPassword(String password) { - return settings.validateProtectionPassword(password); - } - - /** - * Remove protection enforcement.
        - * In the documentProtection tag inside settings.xml file
        - * it sets the value of enforcement to "0" (w:enforcement="0")
        - */ - public void removeProtectionEnforcement() { - settings.removeEnforcement(); - } - - /** - * Enforces fields update on document open (in Word). - * In the settings.xml file
        - * sets the updateSettings value to true (w:updateSettings w:val="true") - *

        - * NOTICES: - *

          - *
        • Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?" - * (if "Update automatic links at open" is enabled)
        • - *
        • Flag is removed after saving with changes in Word
        • - *
        - */ - public void enforceUpdateFields() { - settings.setUpdateFields(); - } - - /** - * Check if revision tracking is turned on. - * - * @return true if revision tracking is turned on - */ - public boolean isTrackRevisions() { - return settings.isTrackRevisions(); - } - - /** - * Enable or disable revision tracking. - * - * @param enable true to turn on revision tracking, false to turn off revision tracking - */ - public void setTrackRevisions(boolean enable) { - settings.setTrackRevisions(enable); - } - - - /** - * Returns the current zoom factor in percent values, i.e. 100 is normal zoom. - * - * @return A percent value denoting the current zoom setting of this document. - */ - public long getZoomPercent() { - return settings.getZoomPercent(); - } - - /** - * Set the zoom setting as percent value, i.e. 100 is normal zoom. - * - * @param zoomPercent A percent value denoting the zoom setting for this document. - */ - public void setZoomPercent(long zoomPercent) { - settings.setZoomPercent(zoomPercent); - } - - /** - * inserts an existing XWPFTable to the arrays bodyElements and tables - * - * @param pos - * @param table - */ - @Override - public void insertTable(int pos, XWPFTable table) { - bodyElements.add(pos, table); - int i = 0; - for (CTTbl tbl : ctDocument.getBody().getTblArray()) { - if (tbl == table.getCTTbl()) { - break; - } - i++; - } - tables.add(i, table); - } - - /** - * Returns all Pictures, which are referenced from the document itself. - * - * @return a {@link List} of {@link XWPFPictureData}. The returned {@link List} is unmodifiable. Use #a - */ - public List getAllPictures() { - return Collections.unmodifiableList(pictures); - } - - /** - * @return all Pictures in this package - */ - public List getAllPackagePictures() { - List result = new ArrayList(); - Collection> values = packagePictures.values(); - for (List list : values) { - result.addAll(list); - } - return Collections.unmodifiableList(result); - } - - void registerPackagePictureData(XWPFPictureData picData) { - List list = packagePictures.get(picData.getChecksum()); - if (list == null) { - list = new ArrayList(1); - packagePictures.put(picData.getChecksum(), list); - } - if (!list.contains(picData)) { - list.add(picData); - } - } - - XWPFPictureData findPackagePictureData(byte[] pictureData, int format) { - long checksum = IOUtils.calculateChecksum(pictureData); - XWPFPictureData xwpfPicData = null; - /* - * Try to find PictureData with this checksum. Create new, if none - * exists. - */ - List xwpfPicDataList = packagePictures.get(checksum); - if (xwpfPicDataList != null) { - Iterator iter = xwpfPicDataList.iterator(); - while (iter.hasNext() && xwpfPicData == null) { - XWPFPictureData curElem = iter.next(); - if (Arrays.equals(pictureData, curElem.getData())) { - xwpfPicData = curElem; - } - } - } - return xwpfPicData; - } - - public String addPictureData(byte[] pictureData, int format) throws InvalidFormatException { - XWPFPictureData xwpfPicData = findPackagePictureData(pictureData, format); - POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format]; - - if (xwpfPicData == null) { - /* Part doesn't exist, create a new one */ - int idx = getNextPicNameNumber(format); - xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(), idx); - /* write bytes to new part */ - PackagePart picDataPart = xwpfPicData.getPackagePart(); - OutputStream out = null; - try { - out = picDataPart.getOutputStream(); - out.write(pictureData); - } catch (IOException e) { - throw new POIXMLException(e); - } finally { - try { - if (out != null) out.close(); - } catch (IOException e) { - // ignore - } - } - - registerPackagePictureData(xwpfPicData); - pictures.add(xwpfPicData); - - return getRelationId(xwpfPicData); - } else if (!getRelations().contains(xwpfPicData)) { - /* - * Part already existed, but was not related so far. Create - * relationship to the already existing part and update - * POIXMLDocumentPart data. - */ - // TODO add support for TargetMode.EXTERNAL relations. - RelationPart rp = addRelation(null, XWPFRelation.IMAGES, xwpfPicData); - return rp.getRelationship().getId(); - } else { - /* Part already existed, get relation id and return it */ - return getRelationId(xwpfPicData); - } - } - - public String addPictureData(InputStream is, int format) throws InvalidFormatException { - try { - byte[] data = IOUtils.toByteArray(is); - return addPictureData(data, format); - } catch (IOException e) { - throw new POIXMLException(e); - } - } - - /** - * get the next free ImageNumber - * - * @param format - * @return the next free ImageNumber - * @throws InvalidFormatException - */ - public int getNextPicNameNumber(int format) throws InvalidFormatException { - int img = getAllPackagePictures().size() + 1; - String proposal = XWPFPictureData.RELATIONS[format].getFileName(img); - PackagePartName createPartName = PackagingURIHelper.createPartName(proposal); - while (this.getPackage().getPart(createPartName) != null) { - img++; - proposal = XWPFPictureData.RELATIONS[format].getFileName(img); - createPartName = PackagingURIHelper.createPartName(proposal); - } - return img; - } - - /** - * returns the PictureData by blipID - * - * @param blipID - * @return XWPFPictureData of a specificID - */ - public XWPFPictureData getPictureDataByID(String blipID) { - POIXMLDocumentPart relatedPart = getRelationById(blipID); - if (relatedPart instanceof XWPFPictureData) { - XWPFPictureData xwpfPicData = (XWPFPictureData) relatedPart; - return xwpfPicData; - } - return null; - } - - /** - * getNumbering - * - * @return numbering - */ - public XWPFNumbering getNumbering() { - return numbering; - } - - /** - * get Styles - * - * @return styles for this document - */ - public XWPFStyles getStyles() { - return styles; - } - - /** - * get the paragraph with the CTP class p - * - * @param p - * @return the paragraph with the CTP class p - */ - @Override - public XWPFParagraph getParagraph(CTP p) { - for (int i = 0; i < getParagraphs().size(); i++) { - if (getParagraphs().get(i).getCTP() == p) { - return getParagraphs().get(i); - } - } - return null; - } - - /** - * get a table by its CTTbl-Object - * - * @param ctTbl - * @return a table by its CTTbl-Object or null - * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl) - */ - @Override - public XWPFTable getTable(CTTbl ctTbl) { - for (int i = 0; i < tables.size(); i++) { - if (getTables().get(i).getCTTbl() == ctTbl) { - return getTables().get(i); - } - } - return null; - } - - public Iterator getTablesIterator() { - return tables.iterator(); - } - - public Iterator getParagraphsIterator() { - return paragraphs.iterator(); - } - - /** - * Returns the paragraph that of position pos - * - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int) - */ - @Override - public XWPFParagraph getParagraphArray(int pos) { - if (pos >= 0 && pos < paragraphs.size()) { - return paragraphs.get(pos); - } - return null; - } - - /** - * returns the Part, to which the body belongs, which you need for adding relationship to other parts - * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell - * belongs. - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - @Override - public POIXMLDocumentPart getPart() { - return this; - } - - - /** - * get the PartType of the body, for example - * DOCUMENT, HEADER, FOOTER, FOOTNOTE, - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - @Override - public BodyType getPartType() { - return BodyType.DOCUMENT; - } - - /** - * get the TableCell which belongs to the TableCell - * - * @param cell - */ - @Override - public XWPFTableCell getTableCell(CTTc cell) { - XmlCursor cursor = cell.newCursor(); - cursor.toParent(); - XmlObject o = cursor.getObject(); - if (!(o instanceof CTRow)) { - return null; - } - CTRow row = (CTRow) o; - cursor.toParent(); - o = cursor.getObject(); - cursor.dispose(); - if (!(o instanceof CTTbl)) { - return null; - } - CTTbl tbl = (CTTbl) o; - XWPFTable table = getTable(tbl); - if (table == null) { - return null; - } - XWPFTableRow tableRow = table.getRow(row); - if (tableRow == null) { - return null; - } - return tableRow.getTableCell(cell); - } - - @Override - public XWPFDocument getXWPFDocument() { - return this; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java deleted file mode 100644 index bc5bbe4c0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLFactory; -import org.apache.poi.POIXMLRelation; - -/** - * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - */ -public final class XWPFFactory extends POIXMLFactory { - private XWPFFactory() { - - } - - private static final XWPFFactory inst = new XWPFFactory(); - - public static XWPFFactory getInstance() { - return inst; - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLRelation getDescriptor(String relationshipType) { - return XWPFRelation.getInstance(relationshipType); - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLDocumentPart createDocumentPart - (Class cls, Class[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Constructor constructor = cls.getDeclaredConstructor(classes); - return constructor.newInstance(values); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFieldRun.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFieldRun.java deleted file mode 100644 index 997c7d0cb..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFieldRun.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util.Internal; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField; - -/** - * A run of text which is part of a field, such as Title - * of Page number or Author. - * Any given Field may be made up of multiple of these. - */ -public class XWPFFieldRun extends XWPFRun { - private CTSimpleField field; - - public XWPFFieldRun(CTSimpleField field, CTR run, IRunBody p) { - super(run, p); - this.field = field; - } - - @Internal - public CTSimpleField getCTField() { - return field; - } - - public String getFieldInstruction() { - return field.getInstr(); - } - - public void setFieldInstruction(String instruction) { - field.setInstr(instruction); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java deleted file mode 100644 index dfe7462ce..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument; - -/** - * Sketch of XWPF footer class - */ -public class XWPFFooter extends XWPFHeaderFooter { - public XWPFFooter() { - super(); - } - - public XWPFFooter(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException { - super(doc, hdrFtr); - XmlCursor cursor = headerFooter.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - paragraphs.add(p); - bodyElements.add(p); - } - if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - tables.add(t); - bodyElements.add(t); - } - - } - cursor.dispose(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XWPFFooter(POIXMLDocumentPart parent, PackagePart part) throws IOException { - super(parent, part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { - this(parent, part); - } - - /** - * save and commit footer - */ - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "ftr")); - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - super._getHdrFtr().save(out, xmlOptions); - out.close(); - } - - @Override - protected void onDocumentRead() throws IOException { - super.onDocumentRead(); - FtrDocument ftrDocument = null; - InputStream is = null; - try { - is = getPackagePart().getInputStream(); - ftrDocument = FtrDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - headerFooter = ftrDocument.getFtr(); - // parse the document with cursor and add - // the XmlObject to its lists - XmlCursor cursor = headerFooter.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - paragraphs.add(p); - bodyElements.add(p); - } - if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - tables.add(t); - bodyElements.add(t); - } - if (o instanceof CTSdtBlock) { - XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this); - bodyElements.add(c); - } - } - cursor.dispose(); - } catch (Exception e) { - throw new POIXMLException(e); - } finally { - if (is != null) { - is.close(); - } - } - } - - /** - * get the PartType of the body - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - public BodyType getPartType() { - return BodyType.FOOTER; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java deleted file mode 100644 index b5f24dd71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java +++ /dev/null @@ -1,377 +0,0 @@ -/* ==================================================================== -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; - -public class XWPFFootnote implements Iterable, IBody { - private List paragraphs = new ArrayList(); - private List tables = new ArrayList(); - private List pictures = new ArrayList(); - private List bodyElements = new ArrayList(); - - private CTFtnEdn ctFtnEdn; - private XWPFFootnotes footnotes; - private XWPFDocument document; - - public XWPFFootnote(CTFtnEdn note, XWPFFootnotes xFootnotes) { - footnotes = xFootnotes; - ctFtnEdn = note; - document = xFootnotes.getXWPFDocument(); - init(); - } - - public XWPFFootnote(XWPFDocument document, CTFtnEdn body) { - ctFtnEdn = body; - this.document = document; - init(); - } - - private void init() { - XmlCursor cursor = ctFtnEdn.newCursor(); - //copied from XWPFDocument...should centralize this code - //to avoid duplication - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - bodyElements.add(p); - paragraphs.add(p); - } else if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - bodyElements.add(t); - tables.add(t); - } else if (o instanceof CTSdtBlock) { - XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this); - bodyElements.add(c); - } - - } - cursor.dispose(); - } - - public List getParagraphs() { - return paragraphs; - } - - public Iterator iterator() { - return paragraphs.iterator(); - } - - public List getTables() { - return tables; - } - - public List getPictures() { - return pictures; - } - - public List getBodyElements() { - return bodyElements; - } - - public CTFtnEdn getCTFtnEdn() { - return ctFtnEdn; - } - - public void setCTFtnEdn(CTFtnEdn footnote) { - ctFtnEdn = footnote; - } - - /** - * @param pos in table array - * @return The table at position pos - * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) - */ - public XWPFTable getTableArray(int pos) { - if (pos >= 0 && pos < tables.size()) { - return tables.get(pos); - } - return null; - } - - /** - * inserts an existing XWPFTable to the arrays bodyElements and tables - * - * @param pos - * @param table - * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table) - */ - public void insertTable(int pos, XWPFTable table) { - bodyElements.add(pos, table); - int i = 0; - for (CTTbl tbl : ctFtnEdn.getTblArray()) { - if (tbl == table.getCTTbl()) { - break; - } - i++; - } - tables.add(i, table); - - } - - /** - * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header - * the method will return this table - * if there is no corresponding {@link XWPFTable} the method will return null - * - * @param ctTable - * @see org.apache.poi.xwpf.usermodel.IBody#getTable(CTTbl ctTable) - */ - public XWPFTable getTable(CTTbl ctTable) { - for (XWPFTable table : tables) { - if (table == null) - return null; - if (table.getCTTbl().equals(ctTable)) - return table; - } - return null; - } - - /** - * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer - * the method will return this paragraph - * if there is no corresponding {@link XWPFParagraph} the method will return null - * - * @param p is instance of CTP and is searching for an XWPFParagraph - * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer - * XWPFParagraph with the correspondig CTP p - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraph(CTP p) - */ - public XWPFParagraph getParagraph(CTP p) { - for (XWPFParagraph paragraph : paragraphs) { - if (paragraph.getCTP().equals(p)) - return paragraph; - } - return null; - } - - /** - * Returns the paragraph that holds - * the text of the header or footer. - * - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int pos) - */ - public XWPFParagraph getParagraphArray(int pos) { - if(pos >=0 && pos < paragraphs.size()) { - return paragraphs.get(pos); - } - return null; - } - - /** - * get the TableCell which belongs to the TableCell - * - * @param cell - * @see org.apache.poi.xwpf.usermodel.IBody#getTableCell(CTTc cell) - */ - public XWPFTableCell getTableCell(CTTc cell) { - XmlCursor cursor = cell.newCursor(); - cursor.toParent(); - XmlObject o = cursor.getObject(); - if (!(o instanceof CTRow)) { - return null; - } - CTRow row = (CTRow) o; - cursor.toParent(); - o = cursor.getObject(); - cursor.dispose(); - if (!(o instanceof CTTbl)) { - return null; - } - CTTbl tbl = (CTTbl) o; - XWPFTable table = getTable(tbl); - if (table == null) { - return null; - } - XWPFTableRow tableRow = table.getRow(row); - if(tableRow == null){ - return null; - } - return tableRow.getTableCell(cell); - } - - /** - * verifies that cursor is on the right position - * - * @param cursor - */ - private boolean isCursorInFtn(XmlCursor cursor) { - XmlCursor verify = cursor.newCursor(); - verify.toParent(); - if (verify.getObject() == this.ctFtnEdn) { - return true; - } - return false; - } - - public POIXMLDocumentPart getOwner() { - return footnotes; - } - - /** - * @param cursor - * @return the inserted table - * @see org.apache.poi.xwpf.usermodel.IBody#insertNewTbl(XmlCursor cursor) - */ - public XWPFTable insertNewTbl(XmlCursor cursor) { - if (isCursorInFtn(cursor)) { - String uri = CTTbl.type.getName().getNamespaceURI(); - String localPart = "tbl"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTTbl t = (CTTbl) cursor.getObject(); - XWPFTable newT = new XWPFTable(t, this); - cursor.removeXmlContents(); - XmlObject o = null; - while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if (!(o instanceof CTTbl)) { - tables.add(0, newT); - } else { - int pos = tables.indexOf(getTable((CTTbl) o)) + 1; - tables.add(pos, newT); - } - int i = 0; - cursor = t.newCursor(); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newT); - XmlCursor c2 = t.newCursor(); - cursor.toCursor(c2); - cursor.toEndToken(); - c2.dispose(); - return newT; - } - return null; - } - - /** - * add a new paragraph at position of the cursor - * - * @param cursor - * @return the inserted paragraph - * @see org.apache.poi.xwpf.usermodel.IBody#insertNewParagraph(XmlCursor cursor) - */ - public XWPFParagraph insertNewParagraph(final XmlCursor cursor) { - if (isCursorInFtn(cursor)) { - String uri = CTP.type.getName().getNamespaceURI(); - String localPart = "p"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTP p = (CTP) cursor.getObject(); - XWPFParagraph newP = new XWPFParagraph(p, this); - XmlObject o = null; - while (!(o instanceof CTP) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if ((!(o instanceof CTP)) || (CTP) o == p) { - paragraphs.add(0, newP); - } else { - int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1; - paragraphs.add(pos, newP); - } - int i = 0; - XmlCursor p2 = p.newCursor(); - cursor.toCursor(p2); - p2.dispose(); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newP); - p2 = p.newCursor(); - cursor.toCursor(p2); - cursor.toEndToken(); - p2.dispose(); - return newP; - } - return null; - } - - /** - * add a new table to the end of the footnote - * - * @param table - * @return the added XWPFTable - */ - public XWPFTable addNewTbl(CTTbl table) { - CTTbl newTable = ctFtnEdn.addNewTbl(); - newTable.set(table); - XWPFTable xTable = new XWPFTable(newTable, this); - tables.add(xTable); - return xTable; - } - - /** - * add a new paragraph to the end of the footnote - * - * @param paragraph - * @return the added XWPFParagraph - */ - public XWPFParagraph addNewParagraph(CTP paragraph) { - CTP newPara = ctFtnEdn.addNewP(); - newPara.set(paragraph); - XWPFParagraph xPara = new XWPFParagraph(newPara, this); - paragraphs.add(xPara); - return xPara; - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getXWPFDocument() - */ - public XWPFDocument getXWPFDocument() { - return document; - } - - /** - * returns the Part, to which the body belongs, which you need for adding relationship to other parts - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - public POIXMLDocumentPart getPart() { - return footnotes; - } - - /** - * get the PartType of the body - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - public BodyType getPartType() { - return BodyType.FOOTNOTE; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java deleted file mode 100644 index defae4ac6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java +++ /dev/null @@ -1,169 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFootnotes; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument; - -/** - * Looks after the collection of Footnotes for a document - */ -public class XWPFFootnotes extends POIXMLDocumentPart { - protected XWPFDocument document; - private List listFootnote = new ArrayList(); - private CTFootnotes ctFootnotes; - - /** - * Construct XWPFFootnotes from a package part - * - * @param part the package part holding the data of the footnotes, - * - * @since POI 3.14-Beta1 - */ - public XWPFFootnotes(PackagePart part) throws IOException, OpenXML4JException { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFFootnotes(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { - this(part); - } - - /** - * Construct XWPFFootnotes from scratch for a new document. - */ - public XWPFFootnotes() { - } - - /** - * Read document - */ - @Override - protected void onDocumentRead() throws IOException { - FootnotesDocument notesDoc; - InputStream is = null; - try { - is = getPackagePart().getInputStream(); - notesDoc = FootnotesDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - ctFootnotes = notesDoc.getFootnotes(); - } catch (XmlException e) { - throw new POIXMLException(); - } finally { - if (is != null) { - is.close(); - } - } - - // Find our footnotes - for (CTFtnEdn note : ctFootnotes.getFootnoteArray()) { - listFootnote.add(new XWPFFootnote(note, this)); - } - } - - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTFootnotes.type.getName().getNamespaceURI(), "footnotes")); - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - ctFootnotes.save(out, xmlOptions); - out.close(); - } - - public List getFootnotesList() { - return listFootnote; - } - - public XWPFFootnote getFootnoteById(int id) { - for (XWPFFootnote note : listFootnote) { - if (note.getCTFtnEdn().getId().intValue() == id) - return note; - } - return null; - } - - /** - * Sets the ctFootnotes - * - * @param footnotes - */ - public void setFootnotes(CTFootnotes footnotes) { - ctFootnotes = footnotes; - } - - /** - * add an XWPFFootnote to the document - * - * @param footnote - * @throws IOException - */ - public void addFootnote(XWPFFootnote footnote) { - listFootnote.add(footnote); - ctFootnotes.addNewFootnote().set(footnote.getCTFtnEdn()); - } - - /** - * add a footnote to the document - * - * @param note - * @throws IOException - */ - public XWPFFootnote addFootnote(CTFtnEdn note) { - CTFtnEdn newNote = ctFootnotes.addNewFootnote(); - newNote.set(note); - XWPFFootnote xNote = new XWPFFootnote(newNote, this); - listFootnote.add(xNote); - return xNote; - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - public XWPFDocument getXWPFDocument() { - if (document != null) { - return document; - } else { - return (XWPFDocument) getParent(); - } - } - - public void setXWPFDocument(XWPFDocument doc) { - document = doc; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java deleted file mode 100644 index 0af8df4bd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument; - -/** - * Sketch of XWPF header class - */ -public class XWPFHeader extends XWPFHeaderFooter { - public XWPFHeader() { - super(); - } - - /** - * @since POI 3.14-Beta1 - */ - public XWPFHeader(POIXMLDocumentPart parent, PackagePart part) throws IOException { - super(parent, part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFHeader(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { - this(parent, part); - } - - public XWPFHeader(XWPFDocument doc, CTHdrFtr hdrFtr) { - super(doc, hdrFtr); - XmlCursor cursor = headerFooter.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - paragraphs.add(p); - } - if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - tables.add(t); - } - } - cursor.dispose(); - } - - /** - * save and commit footer - */ - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "hdr")); - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - super._getHdrFtr().save(out, xmlOptions); - out.close(); - } - - /** - * reads the document - * - * @throws IOException - */ - @Override - protected void onDocumentRead() throws IOException { - super.onDocumentRead(); - HdrDocument hdrDocument = null; - InputStream is = null; - try { - is = getPackagePart().getInputStream(); - hdrDocument = HdrDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - headerFooter = hdrDocument.getHdr(); - // parse the document with cursor and add - // the XmlObject to its lists - XmlCursor cursor = headerFooter.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - paragraphs.add(p); - bodyElements.add(p); - } - if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - tables.add(t); - bodyElements.add(t); - } - if (o instanceof CTSdtBlock) { - XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this); - bodyElements.add(c); - } - } - cursor.dispose(); - } catch (XmlException e) { - throw new POIXMLException(e); - } finally { - if (is != null) { - is.close(); - } - } - } - - /** - * get the PartType of the body - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - public BodyType getPartType() { - return BodyType.HEADER; - } -}//end class diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java deleted file mode 100644 index e8488b3d4..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java +++ /dev/null @@ -1,623 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; - -/** - * Parent of XWPF headers and footers - */ -public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody { - List paragraphs = new ArrayList(); - List tables = new ArrayList(); - List pictures = new ArrayList(); - List bodyElements = new ArrayList(); - - CTHdrFtr headerFooter; - XWPFDocument document; - - XWPFHeaderFooter(XWPFDocument doc, CTHdrFtr hdrFtr) { - if (doc == null) { - throw new NullPointerException(); - } - - document = doc; - headerFooter = hdrFtr; - readHdrFtr(); - } - - protected XWPFHeaderFooter() { - headerFooter = CTHdrFtr.Factory.newInstance(); - readHdrFtr(); - } - - /** - * @since by POI 3.14-Beta1 - */ - public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part) throws IOException { - super(parent, part); - this.document = (XWPFDocument) getParent(); - - if (this.document == null) { - throw new NullPointerException(); - } - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { - this(parent, part); - } - - @Override - protected void onDocumentRead() throws IOException { - for (POIXMLDocumentPart poixmlDocumentPart : getRelations()) { - if (poixmlDocumentPart instanceof XWPFPictureData) { - XWPFPictureData xwpfPicData = (XWPFPictureData) poixmlDocumentPart; - pictures.add(xwpfPicData); - document.registerPackagePictureData(xwpfPicData); - } - } - } - - @Internal - public CTHdrFtr _getHdrFtr() { - return headerFooter; - } - - public List getBodyElements() { - return Collections.unmodifiableList(bodyElements); - } - - /** - * Returns the paragraph(s) that holds - * the text of the header or footer. - * Normally there is only the one paragraph, but - * there could be more in certain cases, or - * a table. - */ - public List getParagraphs() { - return Collections.unmodifiableList(paragraphs); - } - - - /** - * Return the table(s) that holds the text - * of the header or footer, for complex cases - * where a paragraph isn't used. - * Normally there's just one paragraph, but some - * complex headers/footers have a table or two - * in addition. - */ - public List getTables() throws ArrayIndexOutOfBoundsException { - return Collections.unmodifiableList(tables); - } - - - /** - * Returns the textual content of the header/footer, - * by flattening out the text of its paragraph(s) - */ - public String getText() { - StringBuffer t = new StringBuffer(); - //TODO: simplify this to get ibody elements in order - for (int i = 0; i < paragraphs.size(); i++) { - if (!paragraphs.get(i).isEmpty()) { - String text = paragraphs.get(i).getText(); - if (text != null && text.length() > 0) { - t.append(text); - t.append('\n'); - } - } - } - - for (int i = 0; i < tables.size(); i++) { - String text = tables.get(i).getText(); - if (text != null && text.length() > 0) { - t.append(text); - t.append('\n'); - } - } - - for (IBodyElement bodyElement : getBodyElements()) { - if (bodyElement instanceof XWPFSDT) { - t.append(((XWPFSDT) bodyElement).getContent().getText() + '\n'); - } - } - return t.toString(); - } - - /** - * set a new headerFooter - */ - public void setHeaderFooter(CTHdrFtr headerFooter) { - this.headerFooter = headerFooter; - readHdrFtr(); - } - - /** - * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header - * the method will return this table - * if there is no corresponding {@link XWPFTable} the method will return null - * - * @param ctTable - */ - public XWPFTable getTable(CTTbl ctTable) { - for (XWPFTable table : tables) { - if (table == null) - return null; - if (table.getCTTbl().equals(ctTable)) - return table; - } - return null; - } - - /** - * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer - * the method will return this paragraph - * if there is no corresponding {@link XWPFParagraph} the method will return null - * - * @param p is instance of CTP and is searching for an XWPFParagraph - * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer - * XWPFParagraph with the correspondig CTP p - */ - public XWPFParagraph getParagraph(CTP p) { - for (XWPFParagraph paragraph : paragraphs) { - if (paragraph.getCTP().equals(p)) - return paragraph; - } - return null; - - } - - /** - * Returns the paragraph that holds - * the text of the header or footer. - */ - public XWPFParagraph getParagraphArray(int pos) { - if(pos >= 0 && pos getListParagraph() { - return paragraphs; - } - - public List getAllPictures() { - return Collections.unmodifiableList(pictures); - } - - /** - * get all Pictures in this package - * - * @return all Pictures in this package - */ - public List getAllPackagePictures() { - return document.getAllPackagePictures(); - - } - - /** - * Adds a picture to the document. - * - * @param pictureData The picture data - * @param format The format of the picture. - * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . - * @throws InvalidFormatException - */ - public String addPictureData(byte[] pictureData, int format) throws InvalidFormatException { - XWPFPictureData xwpfPicData = document.findPackagePictureData(pictureData, format); - POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format]; - - if (xwpfPicData == null) { - /* Part doesn't exist, create a new one */ - int idx = document.getNextPicNameNumber(format); - xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(), idx); - /* write bytes to new part */ - PackagePart picDataPart = xwpfPicData.getPackagePart(); - OutputStream out = null; - try { - out = picDataPart.getOutputStream(); - out.write(pictureData); - } catch (IOException e) { - throw new POIXMLException(e); - } finally { - try { - if (out != null) out.close(); - } catch (IOException e) { - // ignore - } - } - - document.registerPackagePictureData(xwpfPicData); - pictures.add(xwpfPicData); - return getRelationId(xwpfPicData); - } else if (!getRelations().contains(xwpfPicData)) { - /* - * Part already existed, but was not related so far. Create - * relationship to the already existing part and update - * POIXMLDocumentPart data. - */ - // TODO add support for TargetMode.EXTERNAL relations. - RelationPart rp = addRelation(null, XWPFRelation.IMAGES, xwpfPicData); - pictures.add(xwpfPicData); - return rp.getRelationship().getId(); - } else { - /* Part already existed, get relation id and return it */ - return getRelationId(xwpfPicData); - } - } - - /** - * Adds a picture to the document. - * - * @param is The stream to read image from - * @param format The format of the picture. - * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . - * @throws InvalidFormatException - * @throws IOException - */ - public String addPictureData(InputStream is, int format) throws InvalidFormatException, IOException { - byte[] data = IOUtils.toByteArray(is); - return addPictureData(data, format); - } - - /** - * returns the PictureData by blipID - * - * @param blipID - * @return XWPFPictureData of a specificID - * @throws Exception - */ - public XWPFPictureData getPictureDataByID(String blipID) { - POIXMLDocumentPart relatedPart = getRelationById(blipID); - if (relatedPart != null && relatedPart instanceof XWPFPictureData) { - return (XWPFPictureData) relatedPart; - } - return null; - } - - /** - * Adds a new paragraph at the end of the header or footer - * - * @return new {@link XWPFParagraph} object - */ - public XWPFParagraph createParagraph() { - XWPFParagraph paragraph = new XWPFParagraph(headerFooter.addNewP(), this); - paragraphs.add(paragraph); - bodyElements.add(paragraph); - return paragraph; - } - - /** - * Adds a new table at the end of the header or footer - * - * @param rows - number of rows in the table - * @param cols - number of columns in the table - * @return new {@link XWPFTable} object - */ - public XWPFTable createTable(int rows, int cols) { - XWPFTable table = new XWPFTable(headerFooter.addNewTbl(), this, rows, cols); - tables.add(table); - bodyElements.add(table); - return table; - } - - /** - * Removes a specific paragraph from this header / footer - * - * @param paragraph - {@link XWPFParagraph} object to remove - */ - public void removeParagraph(XWPFParagraph paragraph) { - if (paragraphs.contains(paragraph)) { - CTP ctP = paragraph.getCTP(); - XmlCursor c = ctP.newCursor(); - c.removeXml(); - c.dispose(); - paragraphs.remove(paragraph); - bodyElements.remove(paragraph); - } - } - - /** - * Removes a specific table from this header / footer - * - * @param table - {@link XWPFTable} object to remove - */ - public void removeTable(XWPFTable table) { - if (tables.contains(table)) { - CTTbl ctTbl = table.getCTTbl(); - XmlCursor c = ctTbl.newCursor(); - c.removeXml(); - c.dispose(); - tables.remove(table); - bodyElements.remove(table); - } - } - - /** - * Clears all paragraphs and tables from this header / footer - */ - public void clearHeaderFooter() { - XmlCursor c = headerFooter.newCursor(); - c.removeXmlContents(); - c.dispose(); - paragraphs.clear(); - tables.clear(); - bodyElements.clear(); - } - - /** - * add a new paragraph at position of the cursor - * - * @param cursor - * @return the inserted paragraph - */ - public XWPFParagraph insertNewParagraph(XmlCursor cursor) { - if (isCursorInHdrF(cursor)) { - String uri = CTP.type.getName().getNamespaceURI(); - String localPart = "p"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTP p = (CTP) cursor.getObject(); - XWPFParagraph newP = new XWPFParagraph(p, this); - XmlObject o = null; - while (!(o instanceof CTP) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if ((!(o instanceof CTP)) || (CTP) o == p) { - paragraphs.add(0, newP); - } else { - int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1; - paragraphs.add(pos, newP); - } - int i = 0; - XmlCursor p2 = p.newCursor(); - cursor.toCursor(p2); - p2.dispose(); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newP); - p2 = p.newCursor(); - cursor.toCursor(p2); - cursor.toEndToken(); - p2.dispose(); - return newP; - } - return null; - } - - - /** - * @param cursor - * @return the inserted table - */ - public XWPFTable insertNewTbl(final XmlCursor cursor) { - if (isCursorInHdrF(cursor)) { - String uri = CTTbl.type.getName().getNamespaceURI(); - String localPart = "tbl"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTTbl t = (CTTbl) cursor.getObject(); - XWPFTable newT = new XWPFTable(t, this); - cursor.removeXmlContents(); - XmlObject o = null; - while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if (!(o instanceof CTTbl)) { - tables.add(0, newT); - } else { - int pos = tables.indexOf(getTable((CTTbl) o)) + 1; - tables.add(pos, newT); - } - int i = 0; - XmlCursor cursor2 = t.newCursor(); - while (cursor2.toPrevSibling()) { - o = cursor2.getObject(); - if (o instanceof CTP || o instanceof CTTbl) { - i++; - } - } - cursor2.dispose(); - bodyElements.add(i, newT); - cursor2 = t.newCursor(); - cursor.toCursor(cursor2); - cursor.toEndToken(); - cursor2.dispose(); - return newT; - } - return null; - } - - /** - * verifies that cursor is on the right position - * - * @param cursor - */ - private boolean isCursorInHdrF(XmlCursor cursor) { - XmlCursor verify = cursor.newCursor(); - verify.toParent(); - boolean result = (verify.getObject() == this.headerFooter); - verify.dispose(); - return result; - } - - - public POIXMLDocumentPart getOwner() { - return this; - } - - /** - * Returns the table at position pos - * - * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) - */ - public XWPFTable getTableArray(int pos) { - if (pos >= 0 && pos < tables.size()) { - return tables.get(pos); - } - return null; - } - - /** - * inserts an existing XWPFTable to the arrays bodyElements and tables - * - * @param pos - * @param table - */ - public void insertTable(int pos, XWPFTable table) { - bodyElements.add(pos, table); - int i = 0; - for (CTTbl tbl : headerFooter.getTblArray()) { - if (tbl == table.getCTTbl()) { - break; - } - i++; - } - tables.add(i, table); - - } - - public void readHdrFtr() { - bodyElements = new ArrayList(); - paragraphs = new ArrayList(); - tables = new ArrayList(); - // parse the document with cursor and add - // the XmlObject to its lists - XmlCursor cursor = headerFooter.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - paragraphs.add(p); - bodyElements.add(p); - } - if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - tables.add(t); - bodyElements.add(t); - } - } - cursor.dispose(); - } - - /** - * get the TableCell which belongs to the TableCell - * - * @param cell - */ - public XWPFTableCell getTableCell(CTTc cell) { - XmlCursor cursor = cell.newCursor(); - cursor.toParent(); - XmlObject o = cursor.getObject(); - if (!(o instanceof CTRow)) { - cursor.dispose(); - return null; - } - CTRow row = (CTRow) o; - cursor.toParent(); - o = cursor.getObject(); - cursor.dispose(); - if (!(o instanceof CTTbl)) { - return null; - } - CTTbl tbl = (CTTbl) o; - XWPFTable table = getTable(tbl); - if (table == null) { - return null; - } - XWPFTableRow tableRow = table.getRow(row); - return tableRow.getTableCell(cell); - } - - public XWPFDocument getXWPFDocument() { - if (document != null) { - return document; - } else { - return (XWPFDocument) getParent(); - } - } - - public void setXWPFDocument(XWPFDocument doc) { - document = doc; - } - - /** - * returns the Part, to which the body belongs, which you need for adding relationship to other parts - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - public POIXMLDocumentPart getPart() { - return this; - } - - @Override - protected void prepareForCommit() { - // must contain at least an empty paragraph - if (bodyElements.size() == 0) { - createParagraph(); - } - - // Cells must contain at least an empty paragraph - for (XWPFTable tbl : tables) { - for (XWPFTableRow row : tbl.tableRows) { - for (XWPFTableCell cell : row.getTableCells()) { - if (cell.getBodyElements().size() == 0) { - cell.addParagraph(); - } - } - } - } - super.prepareForCommit(); - - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java deleted file mode 100644 index c00f75a89..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -/** - * Sketch of XWPF hyperlink class - * - * @author Yury Batrakov (batrakov at gmail.com) - */ -public class XWPFHyperlink { - String id, url; - - public XWPFHyperlink(String id, String url) { - this.id = id; - this.url = url; - } - - public String getId() { - return id; - } - - public String getURL() { - return url; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java deleted file mode 100644 index 9a79b20f0..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util.Internal; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; - -/** - * A run of text with a Hyperlink applied to it. - * Any given Hyperlink may be made up of multiple of these. - */ -public class XWPFHyperlinkRun extends XWPFRun { - private CTHyperlink hyperlink; - - public XWPFHyperlinkRun(CTHyperlink hyperlink, CTR run, IRunBody p) { - super(run, p); - this.hyperlink = hyperlink; - } - - @Internal - public CTHyperlink getCTHyperlink() { - return hyperlink; - } - - public String getAnchor() { - return hyperlink.getAnchor(); - } - - /** - * Returns the ID of the hyperlink, if one is set. - */ - public String getHyperlinkId() { - return hyperlink.getId(); - } - - public void setHyperlinkId(String id) { - hyperlink.setId(id); - } - - /** - * If this Hyperlink is an external reference hyperlink, - * return the object for it. - */ - public XWPFHyperlink getHyperlink(XWPFDocument document) { - String id = getHyperlinkId(); - if (id == null) - return null; - - return document.getHyperlinkByID(id); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java deleted file mode 100644 index da8b9836c..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException; - -public class XWPFLatentStyles { - // As of 2016-06-10, POI does not contain a LatentStyle class, nor was one included in the patch for bug 48574. - protected XWPFStyles styles; //LatentStyle shall know styles - private CTLatentStyles latentStyles; - - protected XWPFLatentStyles() { - } - - protected XWPFLatentStyles(CTLatentStyles latentStyles) { - this(latentStyles, null); - } - - protected XWPFLatentStyles(CTLatentStyles latentStyles, XWPFStyles styles) { - this.latentStyles = latentStyles; - this.styles = styles; - } - - public int getNumberOfStyles() { - return latentStyles.sizeOfLsdExceptionArray(); - } - - /** - * checks whether specific LatentStyleID is a latentStyle - */ - protected boolean isLatentStyle(String latentStyleID) { - for (CTLsdException lsd : latentStyles.getLsdExceptionArray()) { - if (lsd.getName().equals(latentStyleID)) { - return true; - } - } - return false; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java deleted file mode 100644 index 7674510c1..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum; - -/** - * TODO Bring more of the logic over from XWPFParagraph - */ -public class XWPFNum { - protected XWPFNumbering numbering; - private CTNum ctNum; - - public XWPFNum() { - this.ctNum = null; - this.numbering = null; - } - - public XWPFNum(CTNum ctNum) { - this.ctNum = ctNum; - this.numbering = null; - } - - public XWPFNum(XWPFNumbering numbering) { - this.ctNum = null; - this.numbering = numbering; - } - - public XWPFNum(CTNum ctNum, XWPFNumbering numbering) { - this.ctNum = ctNum; - this.numbering = numbering; - } - - public XWPFNumbering getNumbering() { - return numbering; - } - - public void setNumbering(XWPFNumbering numbering) { - this.numbering = numbering; - } - - public CTNum getCTNum() { - return ctNum; - } - - public void setCTNum(CTNum ctNum) { - this.ctNum = ctNum; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java deleted file mode 100644 index 10b42f8f6..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java +++ /dev/null @@ -1,293 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument; - -/** - * @author Philipp Epp - */ -public class XWPFNumbering extends POIXMLDocumentPart { - protected List abstractNums = new ArrayList(); - protected List nums = new ArrayList(); - boolean isNew; - private CTNumbering ctNumbering; - - /** - * create a new styles object with an existing document - * - * @since POI 3.14-Beta1 - */ - public XWPFNumbering(PackagePart part) throws IOException, OpenXML4JException { - super(part); - isNew = true; - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { - this(part); - } - - /** - * create a new XWPFNumbering object for use in a new document - */ - public XWPFNumbering() { - abstractNums = new ArrayList(); - nums = new ArrayList(); - isNew = true; - } - - /** - * read numbering form an existing package - */ - @Override - protected void onDocumentRead() throws IOException { - NumberingDocument numberingDoc = null; - InputStream is; - is = getPackagePart().getInputStream(); - try { - numberingDoc = NumberingDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - ctNumbering = numberingDoc.getNumbering(); - //get any Nums - for (CTNum ctNum : ctNumbering.getNumArray()) { - nums.add(new XWPFNum(ctNum, this)); - } - for (CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()) { - abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this)); - } - isNew = false; - } catch (XmlException e) { - throw new POIXMLException(); - } finally { - is.close(); - } - } - - /** - * save and commit numbering - */ - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering")); - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - ctNumbering.save(out, xmlOptions); - out.close(); - } - - - /** - * Sets the ctNumbering - * - * @param numbering - */ - public void setNumbering(CTNumbering numbering) { - ctNumbering = numbering; - } - - - /** - * Checks whether number with numID exists - * - * @param numID - * @return boolean true if num exist, false if num not exist - */ - public boolean numExist(BigInteger numID) { - for (XWPFNum num : nums) { - if (num.getCTNum().getNumId().equals(numID)) - return true; - } - return false; - } - - /** - * add a new number to the numbering document - * - * @param num - */ - public BigInteger addNum(XWPFNum num) { - ctNumbering.addNewNum(); - int pos = ctNumbering.sizeOfNumArray() - 1; - ctNumbering.setNumArray(pos, num.getCTNum()); - nums.add(num); - return num.getCTNum().getNumId(); - } - - /** - * Add a new num with an abstractNumID - * - * @return return NumId of the added num - */ - public BigInteger addNum(BigInteger abstractNumID) { - CTNum ctNum = this.ctNumbering.addNewNum(); - ctNum.addNewAbstractNumId(); - ctNum.getAbstractNumId().setVal(abstractNumID); - ctNum.setNumId(BigInteger.valueOf(nums.size() + 1)); - XWPFNum num = new XWPFNum(ctNum, this); - nums.add(num); - return ctNum.getNumId(); - } - - /** - * Add a new num with an abstractNumID and a numID - * - * @param abstractNumID - * @param numID - */ - public void addNum(BigInteger abstractNumID, BigInteger numID) { - CTNum ctNum = this.ctNumbering.addNewNum(); - ctNum.addNewAbstractNumId(); - ctNum.getAbstractNumId().setVal(abstractNumID); - ctNum.setNumId(numID); - XWPFNum num = new XWPFNum(ctNum, this); - nums.add(num); - } - - /** - * get Num by NumID - * - * @param numID - * @return abstractNum with NumId if no Num exists with that NumID - * null will be returned - */ - public XWPFNum getNum(BigInteger numID) { - for (XWPFNum num : nums) { - if (num.getCTNum().getNumId().equals(numID)) - return num; - } - return null; - } - - /** - * get AbstractNum by abstractNumID - * - * @param abstractNumID - * @return abstractNum with abstractNumId if no abstractNum exists with that abstractNumID - * null will be returned - */ - public XWPFAbstractNum getAbstractNum(BigInteger abstractNumID) { - for (XWPFAbstractNum abstractNum : abstractNums) { - if (abstractNum.getAbstractNum().getAbstractNumId().equals(abstractNumID)) { - return abstractNum; - } - } - return null; - } - - /** - * Compare AbstractNum with abstractNums of this numbering document. - * If the content of abstractNum equals with an abstractNum of the List in numbering - * the BigInteger Value of it will be returned. - * If no equal abstractNum is existing null will be returned - * - * @param abstractNum - * @return BigInteger - */ - public BigInteger getIdOfAbstractNum(XWPFAbstractNum abstractNum) { - CTAbstractNum copy = (CTAbstractNum) abstractNum.getCTAbstractNum().copy(); - XWPFAbstractNum newAbstractNum = new XWPFAbstractNum(copy, this); - int i; - for (i = 0; i < abstractNums.size(); i++) { - newAbstractNum.getCTAbstractNum().setAbstractNumId(BigInteger.valueOf(i)); - newAbstractNum.setNumbering(this); - if (newAbstractNum.getCTAbstractNum().valueEquals(abstractNums.get(i).getCTAbstractNum())) { - return newAbstractNum.getCTAbstractNum().getAbstractNumId(); - } - } - return null; - } - - - /** - * add a new AbstractNum and return its AbstractNumID - * - * @param abstractNum - */ - public BigInteger addAbstractNum(XWPFAbstractNum abstractNum) { - int pos = abstractNums.size(); - if (abstractNum.getAbstractNum() != null) { // Use the current CTAbstractNum if it exists - ctNumbering.addNewAbstractNum().set(abstractNum.getAbstractNum()); - } else { - ctNumbering.addNewAbstractNum(); - abstractNum.getAbstractNum().setAbstractNumId(BigInteger.valueOf(pos)); - ctNumbering.setAbstractNumArray(pos, abstractNum.getAbstractNum()); - } - abstractNums.add(abstractNum); - return abstractNum.getCTAbstractNum().getAbstractNumId(); - } - - /** - * remove an existing abstractNum - * - * @param abstractNumID - * @return true if abstractNum with abstractNumID exists in NumberingArray, - * false if abstractNum with abstractNumID not exists - */ - public boolean removeAbstractNum(BigInteger abstractNumID) { - if (abstractNumID.byteValue() < abstractNums.size()) { - ctNumbering.removeAbstractNum(abstractNumID.byteValue()); - abstractNums.remove(abstractNumID.byteValue()); - return true; - } - return false; - } - - /** - * return the abstractNumID - * If the AbstractNumID not exists - * return null - * - * @param numID - * @return abstractNumID - */ - public BigInteger getAbstractNumID(BigInteger numID) { - XWPFNum num = getNum(numID); - if (num == null) - return null; - if (num.getCTNum() == null) - return null; - if (num.getCTNum().getAbstractNumId() == null) - return null; - return num.getCTNum().getAbstractNumId().getVal(); - } -} - diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java deleted file mode 100644 index 4e2d3654d..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java +++ /dev/null @@ -1,1581 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.math.BigInteger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.util.Internal; -import org.apache.poi.wp.usermodel.Paragraph; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumLvl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTProofErr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRunTrackChange; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSmartTagRun; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment; - -/** - *

        A Paragraph within a Document, Table, Header etc.

        - *

        - *

        A paragraph has a lot of styling information, but the - * actual text (possibly along with more styling) is held on - * the child {@link XWPFRun}s.

        - */ -public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents, Paragraph { - private final CTP paragraph; - protected IBody part; - /** - * For access to the document's hyperlink, comments, tables etc - */ - protected XWPFDocument document; - protected List runs; - protected List iruns; - - private StringBuffer footnoteText = new StringBuffer(); - - public XWPFParagraph(CTP prgrph, IBody part) { - this.paragraph = prgrph; - this.part = part; - - this.document = part.getXWPFDocument(); - - if (document == null) { - throw new NullPointerException(); - } - - // Build up the character runs - runs = new ArrayList(); - iruns = new ArrayList(); - buildRunsInOrderFromXml(paragraph); - - // Look for bits associated with the runs - for (XWPFRun run : runs) { - CTR r = run.getCTR(); - - // Check for bits that only apply when attached to a core document - // TODO Make this nicer by tracking the XWPFFootnotes directly - XmlCursor c = r.newCursor(); - c.selectPath("child::*"); - while (c.toNextSelection()) { - XmlObject o = c.getObject(); - if (o instanceof CTFtnEdnRef) { - CTFtnEdnRef ftn = (CTFtnEdnRef) o; - footnoteText.append(" [").append(ftn.getId()).append(": "); - XWPFFootnote footnote = - ftn.getDomNode().getLocalName().equals("footnoteReference") ? - document.getFootnoteByID(ftn.getId().intValue()) : - document.getEndnoteByID(ftn.getId().intValue()); - - boolean first = true; - for (XWPFParagraph p : footnote.getParagraphs()) { - if (!first) { - footnoteText.append("\n"); - first = false; - } - footnoteText.append(p.getText()); - } - - footnoteText.append("] "); - } - } - c.dispose(); - } - } - - /** - * Identifies (in order) the parts of the paragraph / - * sub-paragraph that correspond to character text - * runs, and builds the appropriate runs for these. - */ - @SuppressWarnings("deprecation") - private void buildRunsInOrderFromXml(XmlObject object) { - XmlCursor c = object.newCursor(); - c.selectPath("child::*"); - while (c.toNextSelection()) { - XmlObject o = c.getObject(); - if (o instanceof CTR) { - XWPFRun r = new XWPFRun((CTR) o, this); - runs.add(r); - iruns.add(r); - } - if (o instanceof CTHyperlink) { - CTHyperlink link = (CTHyperlink)o; - for (CTR r : link.getRArray()) { - XWPFHyperlinkRun hr = new XWPFHyperlinkRun(link, r, this); - runs.add(hr); - iruns.add(hr); - } - } - if (o instanceof CTSimpleField) { - CTSimpleField field = (CTSimpleField)o; - for (CTR r : field.getRArray()) { - XWPFFieldRun fr = new XWPFFieldRun(field, r, this); - runs.add(fr); - iruns.add(fr); - } - } - if (o instanceof CTSdtBlock) { - XWPFSDT cc = new XWPFSDT((CTSdtBlock) o, part); - iruns.add(cc); - } - if (o instanceof CTSdtRun) { - XWPFSDT cc = new XWPFSDT((CTSdtRun) o, part); - iruns.add(cc); - } - if (o instanceof CTRunTrackChange) { - for (CTR r : ((CTRunTrackChange) o).getRArray()) { - XWPFRun cr = new XWPFRun(r, this); - runs.add(cr); - iruns.add(cr); - } - } - if (o instanceof CTSmartTagRun) { - // Smart Tags can be nested many times. - // This implementation does not preserve the tagging information - buildRunsInOrderFromXml(o); - } - } - c.dispose(); - } - - @Internal - public CTP getCTP() { - return paragraph; - } - - public List getRuns() { - return Collections.unmodifiableList(runs); - } - - /** - * Return literal runs and sdt/content control objects. - * - * @return List - */ - public List getIRuns() { - return Collections.unmodifiableList(iruns); - } - - public boolean isEmpty() { - return !paragraph.getDomNode().hasChildNodes(); - } - - public XWPFDocument getDocument() { - return document; - } - - /** - * Return the textual content of the paragraph, including text from pictures - * and sdt elements in it. - */ - public String getText() { - StringBuffer out = new StringBuffer(); - for (IRunElement run : iruns) { - if (run instanceof XWPFRun) { - XWPFRun xRun = (XWPFRun) run; - // don't include the text if reviewing is enabled and this is a deleted run - if (!xRun.getCTR().isSetRsidDel()) { - out.append(xRun.toString()); - } - } else if (run instanceof XWPFSDT) { - out.append(((XWPFSDT) run).getContent().getText()); - } else { - out.append(run.toString()); - } - } - out.append(footnoteText); - return out.toString(); - } - - /** - * Return styleID of the paragraph if style exist for this paragraph - * if not, null will be returned - * - * @return styleID as String - */ - public String getStyleID() { - if (paragraph.getPPr() != null) { - if (paragraph.getPPr().getPStyle() != null) { - if (paragraph.getPPr().getPStyle().getVal() != null) - return paragraph.getPPr().getPStyle().getVal(); - } - } - return null; - } - - /** - * If style exist for this paragraph - * NumId of the paragraph will be returned. - * If style not exist null will be returned - * - * @return NumID as BigInteger - */ - public BigInteger getNumID() { - if (paragraph.getPPr() != null) { - if (paragraph.getPPr().getNumPr() != null) { - if (paragraph.getPPr().getNumPr().getNumId() != null) - return paragraph.getPPr().getNumPr().getNumId().getVal(); - } - } - return null; - } - - /** - * setNumID of Paragraph - * - * @param numPos - */ - public void setNumID(BigInteger numPos) { - if (paragraph.getPPr() == null) - paragraph.addNewPPr(); - if (paragraph.getPPr().getNumPr() == null) - paragraph.getPPr().addNewNumPr(); - if (paragraph.getPPr().getNumPr().getNumId() == null) { - paragraph.getPPr().getNumPr().addNewNumId(); - } - paragraph.getPPr().getNumPr().getNumId().setVal(numPos); - } - - /** - * Returns Ilvl of the numeric style for this paragraph. - * Returns null if this paragraph does not have numeric style. - * - * @return Ilvl as BigInteger - */ - public BigInteger getNumIlvl() { - if (paragraph.getPPr() != null) { - if (paragraph.getPPr().getNumPr() != null) { - if (paragraph.getPPr().getNumPr().getIlvl() != null) - return paragraph.getPPr().getNumPr().getIlvl().getVal(); - } - } - return null; - } - - /** - * Returns numbering format for this paragraph, eg bullet or - * lowerLetter. - * Returns null if this paragraph does not have numeric style. - */ - public String getNumFmt() { - BigInteger numID = getNumID(); - XWPFNumbering numbering = document.getNumbering(); - if (numID != null && numbering != null) { - XWPFNum num = numbering.getNum(numID); - if (num != null) { - BigInteger ilvl = getNumIlvl(); - BigInteger abstractNumId = num.getCTNum().getAbstractNumId().getVal(); - CTAbstractNum anum = numbering.getAbstractNum(abstractNumId).getAbstractNum(); - CTLvl level = null; - for (int i = 0; i < anum.sizeOfLvlArray(); i++) { - CTLvl lvl = anum.getLvlArray(i); - if (lvl.getIlvl().equals(ilvl)) { - level = lvl; - break; - } - } - if (level != null && level.getNumFmt() != null - && level.getNumFmt().getVal() != null) - return level.getNumFmt().getVal().toString(); - } - } - return null; - } - - /** - * Returns the text that should be used around the paragraph level numbers. - * - * @return a string (e.g. "%1.") or null if the value is not found. - */ - public String getNumLevelText() { - BigInteger numID = getNumID(); - XWPFNumbering numbering = document.getNumbering(); - if (numID != null && numbering != null) { - XWPFNum num = numbering.getNum(numID); - if (num != null) { - BigInteger ilvl = getNumIlvl(); - CTNum ctNum = num.getCTNum(); - if (ctNum == null) - return null; - - CTDecimalNumber ctDecimalNumber = ctNum.getAbstractNumId(); - if (ctDecimalNumber == null) - return null; - - BigInteger abstractNumId = ctDecimalNumber.getVal(); - if (abstractNumId == null) - return null; - - XWPFAbstractNum xwpfAbstractNum = numbering.getAbstractNum(abstractNumId); - - if (xwpfAbstractNum == null) - return null; - - CTAbstractNum anum = xwpfAbstractNum.getCTAbstractNum(); - - if (anum == null) - return null; - - CTLvl level = null; - for (int i = 0; i < anum.sizeOfLvlArray(); i++) { - CTLvl lvl = anum.getLvlArray(i); - if (lvl != null && lvl.getIlvl() != null && lvl.getIlvl().equals(ilvl)) { - level = lvl; - break; - } - } - if (level != null && level.getLvlText() != null - && level.getLvlText().getVal() != null) - return level.getLvlText().getVal().toString(); - } - } - return null; - } - - /** - * Gets the numstartOverride for the paragraph numbering for this paragraph. - * - * @return returns the overridden start number or null if there is no override for this paragraph. - */ - public BigInteger getNumStartOverride() { - BigInteger numID = getNumID(); - XWPFNumbering numbering = document.getNumbering(); - if (numID != null && numbering != null) { - XWPFNum num = numbering.getNum(numID); - - if (num != null) { - CTNum ctNum = num.getCTNum(); - if (ctNum == null) { - return null; - } - BigInteger ilvl = getNumIlvl(); - CTNumLvl level = null; - for (int i = 0; i < ctNum.sizeOfLvlOverrideArray(); i++) { - CTNumLvl ctNumLvl = ctNum.getLvlOverrideArray(i); - if (ctNumLvl != null && ctNumLvl.getIlvl() != null && - ctNumLvl.getIlvl().equals(ilvl)) { - level = ctNumLvl; - break; - } - } - if (level != null && level.getStartOverride() != null) { - return level.getStartOverride().getVal(); - } - } - } - return null; - } - - /** - * Returns the text of the paragraph, but not of any objects in the - * paragraph - */ - public String getParagraphText() { - StringBuffer out = new StringBuffer(); - for (XWPFRun run : runs) { - out.append(run.toString()); - } - return out.toString(); - } - - /** - * Returns any text from any suitable pictures in the paragraph - */ - public String getPictureText() { - StringBuffer out = new StringBuffer(); - for (XWPFRun run : runs) { - out.append(run.getPictureText()); - } - return out.toString(); - } - - /** - * Returns the footnote text of the paragraph - * - * @return the footnote text or empty string if the paragraph does not have footnotes - */ - public String getFootnoteText() { - return footnoteText.toString(); - } - - /** - * Returns the paragraph alignment which shall be applied to text in this - * paragraph. - *

        - *

        - * If this element is not set on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no alignment is applied to the - * paragraph. - *

        - * - * @return the paragraph alignment of this paragraph. - */ - public ParagraphAlignment getAlignment() { - CTPPr pr = getCTPPr(); - return pr == null || !pr.isSetJc() ? ParagraphAlignment.LEFT - : ParagraphAlignment.valueOf(pr.getJc().getVal().intValue()); - } - - /** - * Specifies the paragraph alignment which shall be applied to text in this - * paragraph. - *

        - *

        - * If this element is not set on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no alignment is applied to the - * paragraph. - *

        - * - * @param align the paragraph alignment to apply to this paragraph. - */ - public void setAlignment(ParagraphAlignment align) { - CTPPr pr = getCTPPr(); - CTJc jc = pr.isSetJc() ? pr.getJc() : pr.addNewJc(); - STJc.Enum en = STJc.Enum.forInt(align.getValue()); - jc.setVal(en); - } - - /** - * @return The raw alignment value, {@link #getAlignment()} is suggested - */ - public int getFontAlignment() { - return getAlignment().getValue(); - } - - public void setFontAlignment(int align) { - ParagraphAlignment pAlign = ParagraphAlignment.valueOf(align); - setAlignment(pAlign); - } - - /** - * Returns the text vertical alignment which shall be applied to text in - * this paragraph. - *

        - * If the line height (before any added spacing) is larger than one or more - * characters on the line, all characters will be aligned to each other as - * specified by this element. - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then the vertical alignment of all - * characters on the line shall be automatically determined by the consumer. - *

        - * - * @return the vertical alignment of this paragraph. - */ - public TextAlignment getVerticalAlignment() { - CTPPr pr = getCTPPr(); - return (pr == null || !pr.isSetTextAlignment()) ? TextAlignment.AUTO - : TextAlignment.valueOf(pr.getTextAlignment().getVal() - .intValue()); - } - - /** - * Specifies the text vertical alignment which shall be applied to text in - * this paragraph. - *

        - * If the line height (before any added spacing) is larger than one or more - * characters on the line, all characters will be aligned to each other as - * specified by this element. - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then the vertical alignment of all - * characters on the line shall be automatically determined by the consumer. - *

        - * - * @param valign the paragraph vertical alignment to apply to this - * paragraph. - */ - public void setVerticalAlignment(TextAlignment valign) { - CTPPr pr = getCTPPr(); - CTTextAlignment textAlignment = pr.isSetTextAlignment() ? pr - .getTextAlignment() : pr.addNewTextAlignment(); - STTextAlignment.Enum en = STTextAlignment.Enum - .forInt(valign.getValue()); - textAlignment.setVal(en); - } - - /** - * Specifies the border which shall be displayed above a set of paragraphs - * which have the same set of paragraph border settings. - * - * @return paragraphBorder - the top border for the paragraph - * @see #setBorderTop(Borders) - * @see Borders a list of all types of borders - */ - public Borders getBorderTop() { - CTPBdr border = getCTPBrd(false); - CTBorder ct = null; - if (border != null) { - ct = border.getTop(); - } - STBorder.Enum ptrn = (ct != null) ? ct.getVal() : STBorder.NONE; - return Borders.valueOf(ptrn.intValue()); - } - - /** - * Specifies the border which shall be displayed above a set of paragraphs - * which have the same set of paragraph border settings. - *

        - *

        - * To determine if any two adjoining paragraphs shall have an individual top - * and bottom border or a between border, the set of borders on the two - * adjoining paragraphs are compared. If the border information on those two - * paragraphs is identical for all possible paragraphs borders, then the - * between border is displayed. Otherwise, the final paragraph shall use its - * bottom border and the following paragraph shall use its top border, - * respectively. If this border specifies a space attribute, that value - * determines the space above the text (ignoring any spacing above) which - * should be left before this border is drawn, specified in points. - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no between border shall be applied - * above identical paragraphs. - *

        - * This border can only be a line border. - * - * @param border - * @see Borders for a list of all types of borders - */ - public void setBorderTop(Borders border) { - CTPBdr ct = getCTPBrd(true); - if (ct == null) { - throw new RuntimeException("invalid paragraph state"); - } - - CTBorder pr = (ct.isSetTop()) ? ct.getTop() : ct.addNewTop(); - if (border.getValue() == Borders.NONE.getValue()) - ct.unsetTop(); - else - pr.setVal(STBorder.Enum.forInt(border.getValue())); - } - - /** - * Specifies the border which shall be displayed below a set of - * paragraphs which have the same set of paragraph border settings. - * - * @return paragraphBorder - the bottom border for the paragraph - * @see #setBorderBottom(Borders) - * @see Borders a list of all types of borders - */ - public Borders getBorderBottom() { - CTPBdr border = getCTPBrd(false); - CTBorder ct = null; - if (border != null) { - ct = border.getBottom(); - } - STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE; - return Borders.valueOf(ptrn.intValue()); - } - - /** - * Specifies the border which shall be displayed below a set of paragraphs - * which have the same set of paragraph border settings. - *

        - * To determine if any two adjoining paragraphs shall have an individual top - * and bottom border or a between border, the set of borders on the two - * adjoining paragraphs are compared. If the border information on those two - * paragraphs is identical for all possible paragraphs borders, then the - * between border is displayed. Otherwise, the final paragraph shall use its - * bottom border and the following paragraph shall use its top border, - * respectively. If this border specifies a space attribute, that value - * determines the space after the bottom of the text (ignoring any space - * below) which should be left before this border is drawn, specified in - * points. - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no between border shall be applied - * below identical paragraphs. - *

        - * This border can only be a line border. - * - * @param border - * @see Borders a list of all types of borders - */ - public void setBorderBottom(Borders border) { - CTPBdr ct = getCTPBrd(true); - CTBorder pr = ct.isSetBottom() ? ct.getBottom() : ct.addNewBottom(); - if (border.getValue() == Borders.NONE.getValue()) - ct.unsetBottom(); - else - pr.setVal(STBorder.Enum.forInt(border.getValue())); - } - - /** - * Specifies the border which shall be displayed on the left side of the - * page around the specified paragraph. - * - * @return ParagraphBorder - the left border for the paragraph - * @see #setBorderLeft(Borders) - * @see Borders for a list of all possible borders - */ - public Borders getBorderLeft() { - CTPBdr border = getCTPBrd(false); - CTBorder ct = null; - if (border != null) { - ct = border.getLeft(); - } - STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE; - return Borders.valueOf(ptrn.intValue()); - } - - /** - * Specifies the border which shall be displayed on the left side of the - * page around the specified paragraph. - *

        - * To determine if any two adjoining paragraphs should have a left border - * which spans the full line height or not, the left border shall be drawn - * between the top border or between border at the top (whichever would be - * rendered for the current paragraph), and the bottom border or between - * border at the bottom (whichever would be rendered for the current - * paragraph). - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no left border shall be applied. - *

        - * This border can only be a line border. - * - * @param border - * @see Borders for a list of all possible borders - */ - public void setBorderLeft(Borders border) { - CTPBdr ct = getCTPBrd(true); - CTBorder pr = ct.isSetLeft() ? ct.getLeft() : ct.addNewLeft(); - if (border.getValue() == Borders.NONE.getValue()) - ct.unsetLeft(); - else - pr.setVal(STBorder.Enum.forInt(border.getValue())); - } - - /** - * Specifies the border which shall be displayed on the right side of the - * page around the specified paragraph. - * - * @return ParagraphBorder - the right border for the paragraph - * @see #setBorderRight(Borders) - * @see Borders for a list of all possible borders - */ - public Borders getBorderRight() { - CTPBdr border = getCTPBrd(false); - CTBorder ct = null; - if (border != null) { - ct = border.getRight(); - } - STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE; - return Borders.valueOf(ptrn.intValue()); - } - - /** - * Specifies the border which shall be displayed on the right side of the - * page around the specified paragraph. - *

        - * To determine if any two adjoining paragraphs should have a right border - * which spans the full line height or not, the right border shall be drawn - * between the top border or between border at the top (whichever would be - * rendered for the current paragraph), and the bottom border or between - * border at the bottom (whichever would be rendered for the current - * paragraph). - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no right border shall be applied. - *

        - * This border can only be a line border. - * - * @param border - * @see Borders for a list of all possible borders - */ - public void setBorderRight(Borders border) { - CTPBdr ct = getCTPBrd(true); - CTBorder pr = ct.isSetRight() ? ct.getRight() : ct.addNewRight(); - if (border.getValue() == Borders.NONE.getValue()) - ct.unsetRight(); - else - pr.setVal(STBorder.Enum.forInt(border.getValue())); - } - - /** - * Specifies the border which shall be displayed between each paragraph in a - * set of paragraphs which have the same set of paragraph border settings. - * - * @return ParagraphBorder - the between border for the paragraph - * @see #setBorderBetween(Borders) - * @see Borders for a list of all possible borders - */ - public Borders getBorderBetween() { - CTPBdr border = getCTPBrd(false); - CTBorder ct = null; - if (border != null) { - ct = border.getBetween(); - } - STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE; - return Borders.valueOf(ptrn.intValue()); - } - - /** - * Specifies the border which shall be displayed between each paragraph in a - * set of paragraphs which have the same set of paragraph border settings. - *

        - * To determine if any two adjoining paragraphs should have a between border - * or an individual top and bottom border, the set of borders on the two - * adjoining paragraphs are compared. If the border information on those two - * paragraphs is identical for all possible paragraphs borders, then the - * between border is displayed. Otherwise, each paragraph shall use its - * bottom and top border, respectively. If this border specifies a space - * attribute, that value is ignored - this border is always located at the - * bottom of each paragraph with an identical following paragraph, taking - * into account any space after the line pitch. - *

        - *

        - * If this element is omitted on a given paragraph, its value is determined - * by the setting previously set at any level of the style hierarchy (i.e. - * that previous setting remains unchanged). If this setting is never - * specified in the style hierarchy, then no between border shall be applied - * between identical paragraphs. - *

        - * This border can only be a line border. - * - * @param border - * @see Borders for a list of all possible borders - */ - public void setBorderBetween(Borders border) { - CTPBdr ct = getCTPBrd(true); - CTBorder pr = ct.isSetBetween() ? ct.getBetween() : ct.addNewBetween(); - if (border.getValue() == Borders.NONE.getValue()) - ct.unsetBetween(); - else - pr.setVal(STBorder.Enum.forInt(border.getValue())); - } - - /** - * Specifies that when rendering this document in a paginated - * view, the contents of this paragraph are rendered on the start of a new - * page in the document. - *

        - * If this element is omitted on a given paragraph, - * its value is determined by the setting previously set at any level of the - * style hierarchy (i.e. that previous setting remains unchanged). If this - * setting is never specified in the style hierarchy, then this property - * shall not be applied. Since the paragraph is specified to start on a new - * page, it begins page two even though it could have fit on page one. - *

        - * - * @return boolean - if page break is set - */ - public boolean isPageBreak() { - CTPPr ppr = getCTPPr(); - CTOnOff ct_pageBreak = ppr.isSetPageBreakBefore() ? ppr - .getPageBreakBefore() : null; - if (ct_pageBreak != null - && ct_pageBreak.getVal().intValue() == STOnOff.INT_TRUE) { - return true; - } - return false; - } - - /** - * Specifies that when rendering this document in a paginated - * view, the contents of this paragraph are rendered on the start of a new - * page in the document. - *

        - * If this element is omitted on a given paragraph, - * its value is determined by the setting previously set at any level of the - * style hierarchy (i.e. that previous setting remains unchanged). If this - * setting is never specified in the style hierarchy, then this property - * shall not be applied. Since the paragraph is specified to start on a new - * page, it begins page two even though it could have fit on page one. - *

        - * - * @param pageBreak - - * boolean value - */ - public void setPageBreak(boolean pageBreak) { - CTPPr ppr = getCTPPr(); - CTOnOff ct_pageBreak = ppr.isSetPageBreakBefore() ? ppr - .getPageBreakBefore() : ppr.addNewPageBreakBefore(); - if (pageBreak) - ct_pageBreak.setVal(STOnOff.TRUE); - else - ct_pageBreak.setVal(STOnOff.FALSE); - } - - /** - * Specifies the spacing that should be added after the last line in this - * paragraph in the document in absolute units. - * - * @return int - value representing the spacing after the paragraph - */ - public int getSpacingAfter() { - CTSpacing spacing = getCTSpacing(false); - return (spacing != null && spacing.isSetAfter()) ? spacing.getAfter().intValue() : -1; - } - - /** - * Specifies the spacing that should be added after the last line in this - * paragraph in the document in absolute units. - *

        - * If the afterLines attribute or the afterAutoSpacing attribute is also - * specified, then this attribute value is ignored. - *

        - * - * @param spaces - - * a positive whole number, whose contents consist of a - * measurement in twentieths of a point. - */ - public void setSpacingAfter(int spaces) { - CTSpacing spacing = getCTSpacing(true); - if (spacing != null) { - BigInteger bi = new BigInteger("" + spaces); - spacing.setAfter(bi); - } - - } - - /** - * Specifies the spacing that should be added after the last line in this - * paragraph in the document in absolute units. - * - * @return bigInteger - value representing the spacing after the paragraph - * @see #setSpacingAfterLines(int) - */ - public int getSpacingAfterLines() { - CTSpacing spacing = getCTSpacing(false); - return (spacing != null && spacing.isSetAfterLines()) ? spacing.getAfterLines().intValue() : -1; - } - - /** - * Specifies the spacing that should be added after the last line in this - * paragraph in the document in line units. - * The value of this attribute is - * specified in one hundredths of a line. - * - *

        - * If the afterAutoSpacing attribute - * is also specified, then this attribute value is ignored. If this setting - * is never specified in the style hierarchy, then its value shall be zero - * (if needed) - *

        - * - * @param spaces - - * a positive whole number, whose contents consist of a - * measurement in twentieths of a - */ - public void setSpacingAfterLines(int spaces) { - CTSpacing spacing = getCTSpacing(true); - BigInteger bi = new BigInteger("" + spaces); - spacing.setAfterLines(bi); - } - - /** - * Specifies the spacing that should be added above the first line in this - * paragraph in the document in absolute units. - * - * @return the spacing that should be added above the first line - * @see #setSpacingBefore(int) - */ - public int getSpacingBefore() { - CTSpacing spacing = getCTSpacing(false); - return (spacing != null && spacing.isSetBefore()) ? spacing.getBefore().intValue() : -1; - } - - /** - * Specifies the spacing that should be added above the first line in this - * paragraph in the document in absolute units. - *

        - * If the beforeLines attribute or the beforeAutoSpacing attribute is also - * specified, then this attribute value is ignored. - *

        - * - * @param spaces - */ - public void setSpacingBefore(int spaces) { - CTSpacing spacing = getCTSpacing(true); - BigInteger bi = new BigInteger("" + spaces); - spacing.setBefore(bi); - } - - /** - * Specifies the spacing that should be added before the first line in this paragraph in the - * document in line units. - * The value of this attribute is specified in one hundredths of a line. - * - * @return the spacing that should be added before the first line in this paragraph - * @see #setSpacingBeforeLines(int) - */ - public int getSpacingBeforeLines() { - CTSpacing spacing = getCTSpacing(false); - return (spacing != null && spacing.isSetBeforeLines()) ? spacing.getBeforeLines().intValue() : -1; - } - - /** - * Specifies the spacing that should be added before the first line in this - * paragraph in the document in line units. The value of this attribute - * is specified in one hundredths of a line. - *

        - * If the beforeAutoSpacing attribute is also specified, then this attribute - * value is ignored. If this setting is never specified in the style - * hierarchy, then its value shall be zero. - *

        - * - * @param spaces - */ - public void setSpacingBeforeLines(int spaces) { - CTSpacing spacing = getCTSpacing(true); - BigInteger bi = new BigInteger("" + spaces); - spacing.setBeforeLines(bi); - } - - /** - * Specifies how the spacing between lines is calculated as stored in the - * line attribute. If this attribute is omitted, then it shall be assumed to - * be of a value auto if a line attribute value is present. - * - * @return rule - * @see LineSpacingRule - * @see #setSpacingLineRule(LineSpacingRule) - */ - public LineSpacingRule getSpacingLineRule() { - CTSpacing spacing = getCTSpacing(false); - return (spacing != null && spacing.isSetLineRule()) ? LineSpacingRule.valueOf(spacing - .getLineRule().intValue()) : LineSpacingRule.AUTO; - } - - /** - * Specifies how the spacing between lines is calculated as stored in the - * line attribute. If this attribute is omitted, then it shall be assumed to - * be of a value auto if a line attribute value is present. - * - * @param rule - * @see LineSpacingRule - */ - public void setSpacingLineRule(LineSpacingRule rule) { - CTSpacing spacing = getCTSpacing(true); - spacing.setLineRule(STLineSpacingRule.Enum.forInt(rule.getValue())); - } - - /** - * Specifies the indentation which shall be placed between the left text - * margin for this paragraph and the left edge of that paragraph's content - * in a left to right paragraph, and the right text margin and the right - * edge of that paragraph's text in a right to left paragraph - *

        - * If this attribute is omitted, its value shall be assumed to be zero. - * Negative values are defined such that the text is moved past the text margin, - * positive values move the text inside the text margin. - *

        - * - * @return indentation or null if indentation is not set - */ - public int getIndentationLeft() { - CTInd indentation = getCTInd(false); - return (indentation != null && indentation.isSetLeft()) ? indentation.getLeft().intValue() - : -1; - } - - /** - * Specifies the indentation which shall be placed between the left text - * margin for this paragraph and the left edge of that paragraph's content - * in a left to right paragraph, and the right text margin and the right - * edge of that paragraph's text in a right to left paragraph - *

        - * If this attribute is omitted, its value shall be assumed to be zero. - * Negative values are defined such that the text is moved past the text margin, - * positive values move the text inside the text margin. - *

        - * - * @param indentation - */ - public void setIndentationLeft(int indentation) { - CTInd indent = getCTInd(true); - BigInteger bi = new BigInteger("" + indentation); - indent.setLeft(bi); - } - - /** - * Specifies the indentation which shall be placed between the right text - * margin for this paragraph and the right edge of that paragraph's content - * in a left to right paragraph, and the right text margin and the right - * edge of that paragraph's text in a right to left paragraph - *

        - * If this attribute is omitted, its value shall be assumed to be zero. - * Negative values are defined such that the text is moved past the text margin, - * positive values move the text inside the text margin. - *

        - * - * @return indentation or null if indentation is not set - */ - - public int getIndentationRight() { - CTInd indentation = getCTInd(false); - return (indentation != null && indentation.isSetRight()) ? indentation.getRight().intValue() - : -1; - } - - /** - * Specifies the indentation which shall be placed between the right text - * margin for this paragraph and the right edge of that paragraph's content - * in a left to right paragraph, and the right text margin and the right - * edge of that paragraph's text in a right to left paragraph - *

        - * If this attribute is omitted, its value shall be assumed to be zero. - * Negative values are defined such that the text is moved past the text margin, - * positive values move the text inside the text margin. - *

        - * - * @param indentation - */ - public void setIndentationRight(int indentation) { - CTInd indent = getCTInd(true); - BigInteger bi = new BigInteger("" + indentation); - indent.setRight(bi); - } - - /** - * Specifies the indentation which shall be removed from the first line of - * the parent paragraph, by moving the indentation on the first line back - * towards the beginning of the direction of text flow. - * This indentation is - * specified relative to the paragraph indentation which is specified for - * all other lines in the parent paragraph. - * The firstLine and hanging - * attributes are mutually exclusive, if both are specified, then the - * firstLine value is ignored. - * - * @return indentation or null if indentation is not set - */ - public int getIndentationHanging() { - CTInd indentation = getCTInd(false); - return (indentation != null && indentation.isSetHanging()) ? indentation.getHanging().intValue() : -1; - } - - /** - * Specifies the indentation which shall be removed from the first line of - * the parent paragraph, by moving the indentation on the first line back - * towards the beginning of the direction of text flow. - * This indentation is specified relative to the paragraph indentation which is specified for - * all other lines in the parent paragraph. - *

        - * The firstLine and hanging attributes are mutually exclusive, if both are specified, then the - * firstLine value is ignored. - *

        - * - * @param indentation - */ - - public void setIndentationHanging(int indentation) { - CTInd indent = getCTInd(true); - BigInteger bi = new BigInteger("" + indentation); - indent.setHanging(bi); - } - - /** - * Specifies the additional indentation which shall be applied to the first - * line of the parent paragraph. This additional indentation is specified - * relative to the paragraph indentation which is specified for all other - * lines in the parent paragraph. - * The firstLine and hanging attributes are - * mutually exclusive, if both are specified, then the firstLine value is - * ignored. - * If the firstLineChars attribute is also specified, then this - * value is ignored. - * If this attribute is omitted, then its value shall be - * assumed to be zero (if needed). - * - * @return indentation or null if indentation is not set - */ - public int getIndentationFirstLine() { - CTInd indentation = getCTInd(false); - return (indentation != null && indentation.isSetFirstLine()) ? indentation.getFirstLine().intValue() - : -1; - } - - /** - * Specifies the additional indentation which shall be applied to the first - * line of the parent paragraph. This additional indentation is specified - * relative to the paragraph indentation which is specified for all other - * lines in the parent paragraph. - * The firstLine and hanging attributes are - * mutually exclusive, if both are specified, then the firstLine value is - * ignored. - * If the firstLineChars attribute is also specified, then this - * value is ignored. If this attribute is omitted, then its value shall be - * assumed to be zero (if needed). - * - * @param indentation - */ - public void setIndentationFirstLine(int indentation) { - CTInd indent = getCTInd(true); - BigInteger bi = new BigInteger("" + indentation); - indent.setFirstLine(bi); - } - - public int getIndentFromLeft() { - return getIndentationLeft(); - } - - public void setIndentFromLeft(int dxaLeft) { - setIndentationLeft(dxaLeft); - } - - public int getIndentFromRight() { - return getIndentationRight(); - } - - public void setIndentFromRight(int dxaRight) { - setIndentationRight(dxaRight); - } - - public int getFirstLineIndent() { - return getIndentationFirstLine(); - } - - public void setFirstLineIndent(int first) { - setIndentationFirstLine(first); - } - - /** - * This element specifies whether a consumer shall break Latin text which - * exceeds the text extents of a line by breaking the word across two lines - * (breaking on the character level) or by moving the word to the following - * line (breaking on the word level). - * - * @return boolean - */ - public boolean isWordWrapped() { - CTOnOff wordWrap = getCTPPr().isSetWordWrap() ? getCTPPr() - .getWordWrap() : null; - if (wordWrap != null) { - return (wordWrap.getVal() == STOnOff.ON - || wordWrap.getVal() == STOnOff.TRUE || wordWrap.getVal() == STOnOff.X_1) ? true - : false; - } - return false; - } - - /** - * This element specifies whether a consumer shall break Latin text which - * exceeds the text extents of a line by breaking the word across two lines - * (breaking on the character level) or by moving the word to the following - * line (breaking on the word level). - * - * @param wrap - boolean - */ - public void setWordWrapped(boolean wrap) { - CTOnOff wordWrap = getCTPPr().isSetWordWrap() ? getCTPPr() - .getWordWrap() : getCTPPr().addNewWordWrap(); - if (wrap) - wordWrap.setVal(STOnOff.TRUE); - else - wordWrap.unsetVal(); - } - - public boolean isWordWrap() { - return isWordWrapped(); - } - - @Deprecated - public void setWordWrap(boolean wrap) { - setWordWrapped(wrap); - } - - /** - * @return the style of the paragraph - */ - public String getStyle() { - CTPPr pr = getCTPPr(); - CTString style = pr.isSetPStyle() ? pr.getPStyle() : null; - return style != null ? style.getVal() : null; - } - - /** - * This method provides a style to the paragraph - * This is useful when, e.g. an Heading style has to be assigned - * - * @param newStyle - */ - public void setStyle(String newStyle) { - CTPPr pr = getCTPPr(); - CTString style = pr.getPStyle() != null ? pr.getPStyle() : pr.addNewPStyle(); - style.setVal(newStyle); - } - - /** - * Get a copy of the currently used CTPBrd, if none is used, return - * a new instance. - */ - private CTPBdr getCTPBrd(boolean create) { - CTPPr pr = getCTPPr(); - CTPBdr ct = pr.isSetPBdr() ? pr.getPBdr() : null; - if (create && ct == null) - ct = pr.addNewPBdr(); - return ct; - } - - /** - * Get a copy of the currently used CTSpacing, if none is used, - * return a new instance. - */ - private CTSpacing getCTSpacing(boolean create) { - CTPPr pr = getCTPPr(); - CTSpacing ct = pr.getSpacing() == null ? null : pr.getSpacing(); - if (create && ct == null) - ct = pr.addNewSpacing(); - return ct; - } - - /** - * Get a copy of the currently used CTPInd, if none is used, return - * a new instance. - */ - private CTInd getCTInd(boolean create) { - CTPPr pr = getCTPPr(); - CTInd ct = pr.getInd() == null ? null : pr.getInd(); - if (create && ct == null) - ct = pr.addNewInd(); - return ct; - } - - /** - * Get a copy of the currently used CTPPr, if none is used, return - * a new instance. - */ - private CTPPr getCTPPr() { - CTPPr pr = paragraph.getPPr() == null ? paragraph.addNewPPr() - : paragraph.getPPr(); - return pr; - } - - - /** - * add a new run at the end of the position of - * the content of parameter run - * - * @param run - */ - protected void addRun(CTR run) { - int pos; - pos = paragraph.sizeOfRArray(); - paragraph.addNewR(); - paragraph.setRArray(pos, run); - } - - /** - * Appends a new run to this paragraph - * - * @return a new text run - */ - public XWPFRun createRun() { - XWPFRun xwpfRun = new XWPFRun(paragraph.addNewR(), (IRunBody)this); - runs.add(xwpfRun); - iruns.add(xwpfRun); - return xwpfRun; - } - - /** - * insert a new Run in RunArray - * - * @param pos The position at which the new run should be added. - * - * @return the inserted run or null if the given pos is out of bounds. - */ - public XWPFRun insertNewRun(int pos) { - if (pos >= 0 && pos <= runs.size()) { - // calculate the correct pos as our run/irun list contains - // hyperlinks - // and fields so it is different to the paragraph R array. - int rPos = 0; - for (int i = 0; i < pos; i++) { - XWPFRun currRun = runs.get(i); - if (!(currRun instanceof XWPFHyperlinkRun - || currRun instanceof XWPFFieldRun)) { - rPos++; - } - } - - CTR ctRun = paragraph.insertNewR(rPos); - XWPFRun newRun = new XWPFRun(ctRun, (IRunBody) this); - - // To update the iruns, find where we're going - // in the normal runs, and go in there - int iPos = iruns.size(); - if (pos < runs.size()) { - XWPFRun oldAtPos = runs.get(pos); - int oldAt = iruns.indexOf(oldAtPos); - if (oldAt != -1) { - iPos = oldAt; - } - } - iruns.add(iPos, newRun); - - // Runs itself is easy to update - runs.add(pos, newRun); - - return newRun; - } - - return null; - } - // TODO Add methods to allow adding a HyperlinkRun or a FieldRun - - /** - * this methods parse the paragraph and search for the string searched. - * If it finds the string, it will return true and the position of the String - * will be saved in the parameter startPos. - * - * @param searched - * @param startPos - */ - public TextSegement searchText(String searched, PositionInParagraph startPos) { - int startRun = startPos.getRun(), - startText = startPos.getText(), - startChar = startPos.getChar(); - int beginRunPos = 0, candCharPos = 0; - boolean newList = false; - - CTR[] rArray = paragraph.getRArray(); - for (int runPos = startRun; runPos < rArray.length; runPos++) { - int beginTextPos = 0, beginCharPos = 0, textPos = 0, charPos = 0; - CTR ctRun = rArray[runPos]; - XmlCursor c = ctRun.newCursor(); - c.selectPath("./*"); - try { - while (c.toNextSelection()) { - XmlObject o = c.getObject(); - if (o instanceof CTText) { - if (textPos >= startText) { - String candidate = ((CTText) o).getStringValue(); - if (runPos == startRun) - charPos = startChar; - else - charPos = 0; - - for (; charPos < candidate.length(); charPos++) { - if ((candidate.charAt(charPos) == searched.charAt(0)) && (candCharPos == 0)) { - beginTextPos = textPos; - beginCharPos = charPos; - beginRunPos = runPos; - newList = true; - } - if (candidate.charAt(charPos) == searched.charAt(candCharPos)) { - if (candCharPos + 1 < searched.length()) - candCharPos++; - else if (newList) { - TextSegement segement = new TextSegement(); - segement.setBeginRun(beginRunPos); - segement.setBeginText(beginTextPos); - segement.setBeginChar(beginCharPos); - segement.setEndRun(runPos); - segement.setEndText(textPos); - segement.setEndChar(charPos); - return segement; - } - } else { - candCharPos = 0; - } - } - } - textPos++; - } else if (o instanceof CTProofErr) { - c.removeXml(); - } else if (o instanceof CTRPr) ; - //do nothing - else - candCharPos = 0; - } - } finally { - c.dispose(); - } - } - return null; - } - - /** - * get a Text - * - * @param segment - */ - public String getText(TextSegement segment) { - int runBegin = segment.getBeginRun(); - int textBegin = segment.getBeginText(); - int charBegin = segment.getBeginChar(); - int runEnd = segment.getEndRun(); - int textEnd = segment.getEndText(); - int charEnd = segment.getEndChar(); - StringBuilder out = new StringBuilder(); - CTR[] rArray = paragraph.getRArray(); - for (int i = runBegin; i <= runEnd; i++) { - CTText[] tArray = rArray[i].getTArray(); - int startText = 0, endText = tArray.length - 1; - if (i == runBegin) - startText = textBegin; - if (i == runEnd) - endText = textEnd; - for (int j = startText; j <= endText; j++) { - String tmpText = tArray[j].getStringValue(); - int startChar = 0, endChar = tmpText.length() - 1; - if ((j == textBegin) && (i == runBegin)) - startChar = charBegin; - if ((j == textEnd) && (i == runEnd)) { - endChar = charEnd; - } - out.append(tmpText.substring(startChar, endChar + 1)); - } - } - return out.toString(); - } - - /** - * removes a Run at the position pos in the paragraph - * - * @param pos - * @return true if the run was removed - */ - public boolean removeRun(int pos) { - if (pos >= 0 && pos < runs.size()) { - // Remove the run from our high level lists - XWPFRun run = runs.get(pos); - if (run instanceof XWPFHyperlinkRun || - run instanceof XWPFFieldRun) { - // TODO Add support for removing these kinds of nested runs, - // which aren't on the CTP -> R array, but CTP -> XXX -> R array - throw new IllegalArgumentException("Removing Field or Hyperlink runs not yet supported"); - } - runs.remove(pos); - iruns.remove(run); - // Remove the run from the low-level XML - //calculate the correct pos as our run/irun list contains hyperlinks and fields so is different to the paragraph R array. - int rPos = 0; - for(int i=0;i - * Note, that this call might be expensive since all the picture data is copied into a temporary byte array. - * You can grab the picture data directly from the underlying package part as follows: - *
        - * - * InputStream is = getPackagePart().getInputStream(); - * - *

        - * - * @return the Picture data. - */ - public byte[] getData() { - try { - return IOUtils.toByteArray(getPackagePart().getInputStream()); - } catch (IOException e) { - throw new POIXMLException(e); - } - } - - /** - * Returns the file name of the image, eg image7.jpg . The original filename - * isn't always available, but if it can be found it's likely to be in the - * CTDrawing - */ - public String getFileName() { - String name = getPackagePart().getPartName().getName(); - return name.substring(name.lastIndexOf('/') + 1); - } - - /** - * Suggests a file extension for this image. - * - * @return the file extension. - */ - public String suggestFileExtension() { - return getPackagePart().getPartName().getExtension(); - } - - /** - * Return an integer constant that specifies type of this picture - * - * @return an integer constant that specifies type of this picture - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB - */ - public int getPictureType() { - String contentType = getPackagePart().getContentType(); - for (int i = 0; i < RELATIONS.length; i++) { - if (RELATIONS[i] == null) { - continue; - } - - if (RELATIONS[i].getContentType().equals(contentType)) { - return i; - } - } - return 0; - } - - public Long getChecksum() { - if (this.checksum == null) { - InputStream is = null; - byte[] data; - try { - is = getPackagePart().getInputStream(); - data = IOUtils.toByteArray(is); - } catch (IOException e) { - throw new POIXMLException(e); - } finally { - try { - if (is != null) is.close(); - } catch (IOException e) { - throw new POIXMLException(e); - } - } - this.checksum = IOUtils.calculateChecksum(data); - } - return this.checksum; - } - - @Override - public boolean equals(Object obj) { - /** - * In case two objects ARE equal, but its not the same instance, this - * implementation will always run through the whole - * byte-array-comparison before returning true. If this will turn into a - * performance issue, two possible approaches are available:
        - * a) Use the checksum only and take the risk that two images might have - * the same CRC32 sum, although they are not the same.
        - * b) Use a second (or third) checksum algorithm to minimise the chance - * that two images have the same checksums but are not equal (e.g. - * CRC32, MD5 and SHA-1 checksums, additionally compare the - * data-byte-array lengths). - */ - if (obj == this) { - return true; - } - - if (obj == null) { - return false; - } - - if (!(obj instanceof XWPFPictureData)) { - return false; - } - - XWPFPictureData picData = (XWPFPictureData) obj; - PackagePart foreignPackagePart = picData.getPackagePart(); - PackagePart ownPackagePart = this.getPackagePart(); - - if ((foreignPackagePart != null && ownPackagePart == null) - || (foreignPackagePart == null && ownPackagePart != null)) { - return false; - } - - if (ownPackagePart != null) { - OPCPackage foreignPackage = foreignPackagePart.getPackage(); - OPCPackage ownPackage = ownPackagePart.getPackage(); - - if ((foreignPackage != null && ownPackage == null) - || (foreignPackage == null && ownPackage != null)) { - return false; - } - if (ownPackage != null) { - - if (!ownPackage.equals(foreignPackage)) { - return false; - } - } - } - - Long foreignChecksum = picData.getChecksum(); - Long localChecksum = getChecksum(); - - if (!(localChecksum.equals(foreignChecksum))) { - return false; - } - return Arrays.equals(this.getData(), picData.getData()); - } - - @Override - public int hashCode() { - return getChecksum().hashCode(); - } - - /** - * *PictureData objects store the actual content in the part directly without keeping a - * copy like all others therefore we need to handle them differently. - */ - @Override - protected void prepareForCommit() { - // do not clear the part here - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java deleted file mode 100644 index 0afaedc71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java +++ /dev/null @@ -1,230 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xwpf.usermodel; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLRelation; - -/** - * @author Yegor Kozlov - */ -public final class XWPFRelation extends POIXMLRelation { - - /** - * A map to lookup POIXMLRelation by its relation type - */ - private static final Map _table = new HashMap(); - - 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 TEMPLATE = new XWPFRelation( - "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", - "/word/document.xml", - null - ); - public static final XWPFRelation MACRO_DOCUMENT = new XWPFRelation( - "application/vnd.ms-word.document.macroEnabled.main+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", - "/word/document.xml", - null - ); - public static final XWPFRelation MACRO_TEMPLATE_DOCUMENT = new XWPFRelation( - "application/vnd.ms-word.template.macroEnabledTemplate.main+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", - "/word/document.xml", - null - ); - public static final XWPFRelation GLOSSARY_DOCUMENT = new XWPFRelation( - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument", - "/word/glossary/document.xml", - null - ); - public static final XWPFRelation NUMBERING = new XWPFRelation( - "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering", - "/word/numbering.xml", - XWPFNumbering.class - ); - 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", - XWPFSettings.class - ); - 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", - XWPFStyles.class - ); - 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", - XWPFHeader.class - ); - 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", - XWPFFooter.class - ); - public static final XWPFRelation THEME = new XWPFRelation( - "application/vnd.openxmlformats-officedocument.theme+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", - "/word/theme/theme#.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 - ); - public static final XWPFRelation FOOTNOTE = new XWPFRelation( - "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes", - "/word/footnotes.xml", - XWPFFootnotes.class - ); - public static final XWPFRelation ENDNOTE = new XWPFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes", - null, - null - ); - /** - * Supported image formats - */ - public static final XWPFRelation IMAGE_EMF = new XWPFRelation( - "image/x-emf", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.emf", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_WMF = new XWPFRelation( - "image/x-wmf", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.wmf", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_PICT = new XWPFRelation( - "image/pict", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.pict", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_JPEG = new XWPFRelation( - "image/jpeg", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.jpeg", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_PNG = new XWPFRelation( - "image/png", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.png", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_DIB = new XWPFRelation( - "image/dib", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.dib", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_GIF = new XWPFRelation( - "image/gif", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.gif", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_TIFF = new XWPFRelation( - "image/tiff", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.tiff", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_EPS = new XWPFRelation( - "image/x-eps", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.eps", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_BMP = new XWPFRelation( - "image/x-ms-bmp", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.bmp", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGE_WPG = new XWPFRelation( - "image/x-wpg", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.wpg", - XWPFPictureData.class - ); - public static final XWPFRelation IMAGES = new XWPFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - null, - XWPFPictureData.class - ); - - private XWPFRelation(String type, String rel, String defaultName, Class cls) { - super(type, rel, defaultName, cls); - _table.put(rel, this); - } - - /** - * Get POIXMLRelation by relation type - * - * @param rel relation type, for example, - * http://schemas.openxmlformats.org/officeDocument/2006/relationships/image - * @return registered POIXMLRelation or null if not found - */ - public static XWPFRelation getInstance(String rel) { - return _table.get(rel); - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java deleted file mode 100644 index c2718ab43..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java +++ /dev/null @@ -1,1140 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.Internal; -import org.apache.poi.wp.usermodel.CharacterRun; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlObject; -import org.apache.xmlbeans.XmlString; -import org.apache.xmlbeans.XmlToken; -import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualPictureProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture; -import org.openxmlformats.schemas.drawingml.x2006.picture.CTPictureNonVisual; -import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor; -import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColor; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFFCheckBox; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFldChar; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPTab; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSignedHpsMeasure; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSignedTwipsMeasure; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTUnderline; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalAlignRun; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrClear; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHighlightColor; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -/** - * XWPFRun object defines a region of text with a common set of properties - */ -public class XWPFRun implements ISDTContents, IRunElement, CharacterRun { - private CTR run; - private String pictureText; - private IRunBody parent; - private List pictures; - - /** - * @param r the CTR bean which holds the run attributes - * @param p the parent paragraph - */ - public XWPFRun(CTR r, IRunBody p) { - this.run = r; - this.parent = p; - - /** - * reserve already occupied drawing ids, so reserving new ids later will - * not corrupt the document - */ - for (CTDrawing ctDrawing : r.getDrawingArray()) { - for (CTAnchor anchor : ctDrawing.getAnchorArray()) { - if (anchor.getDocPr() != null) { - getDocument().getDrawingIdManager().reserve(anchor.getDocPr().getId()); - } - } - for (CTInline inline : ctDrawing.getInlineArray()) { - if (inline.getDocPr() != null) { - getDocument().getDrawingIdManager().reserve(inline.getDocPr().getId()); - } - } - } - - // Look for any text in any of our pictures or drawings - StringBuilder text = new StringBuilder(); - List pictTextObjs = new ArrayList(); - pictTextObjs.addAll(Arrays.asList(r.getPictArray())); - pictTextObjs.addAll(Arrays.asList(r.getDrawingArray())); - for (XmlObject o : pictTextObjs) { - XmlObject[] ts = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t"); - for (XmlObject t : ts) { - NodeList kids = t.getDomNode().getChildNodes(); - for (int n = 0; n < kids.getLength(); n++) { - if (kids.item(n) instanceof Text) { - if (text.length() > 0) - text.append("\n"); - text.append(kids.item(n).getNodeValue()); - } - } - } - } - pictureText = text.toString(); - - // Do we have any embedded pictures? - // (They're a different CTPicture, under the drawingml namespace) - pictures = new ArrayList(); - for (XmlObject o : pictTextObjs) { - for (CTPicture pict : getCTPictures(o)) { - XWPFPicture picture = new XWPFPicture(pict, this); - pictures.add(picture); - } - } - } - - /** - * @deprecated Use {@link XWPFRun#XWPFRun(CTR, IRunBody)} - */ - public XWPFRun(CTR r, XWPFParagraph p) { - this(r, (IRunBody) p); - } - - /** - * Add the xml:spaces="preserve" attribute if the string has leading or trailing white spaces - * - * @param xs the string to check - */ - static void preserveSpaces(XmlString xs) { - String text = xs.getStringValue(); - if (text != null && (text.startsWith(" ") || text.endsWith(" "))) { - XmlCursor c = xs.newCursor(); - c.toNextToken(); - c.insertAttributeWithValue(new QName("http://www.w3.org/XML/1998/namespace", "space"), "preserve"); - c.dispose(); - } - } - - private List getCTPictures(XmlObject o) { - List pics = new ArrayList(); - XmlObject[] picts = o.selectPath("declare namespace pic='" + CTPicture.type.getName().getNamespaceURI() + "' .//pic:pic"); - for (XmlObject pict : picts) { - if (pict instanceof XmlAnyTypeImpl) { - // Pesky XmlBeans bug - see Bugzilla #49934 - try { - pict = CTPicture.Factory.parse(pict.toString(), DEFAULT_XML_OPTIONS); - } catch (XmlException e) { - throw new POIXMLException(e); - } - } - if (pict instanceof CTPicture) { - pics.add((CTPicture) pict); - } - } - return pics; - } - - /** - * Get the currently used CTR object - * - * @return ctr object - */ - @Internal - public CTR getCTR() { - return run; - } - - /** - * Get the currently referenced paragraph/SDT object - * - * @return current parent - */ - public IRunBody getParent() { - return parent; - } - - /** - * Get the currently referenced paragraph, or null if a SDT object - * - * @deprecated use {@link XWPFRun#getParent()} instead - */ - public XWPFParagraph getParagraph() { - if (parent instanceof XWPFParagraph) - return (XWPFParagraph) parent; - return null; - } - - /** - * @return The {@link XWPFDocument} instance, this run belongs to, or - * null if parent structure (paragraph > document) is not properly set. - */ - public XWPFDocument getDocument() { - if (parent != null) { - return parent.getDocument(); - } - return null; - } - - /** - * For isBold, isItalic etc - */ - private static boolean isCTOnOff(CTOnOff onoff) { - if (!onoff.isSetVal()) - return true; - final STOnOff.Enum val = onoff.getVal(); - return ( - (STOnOff.TRUE == val) || - (STOnOff.X_1 == val) || - (STOnOff.ON == val) - ); - } - - /** - * Whether the bold property shall be applied to all non-complex script - * characters in the contents of this run when displayed in a document - * - * @return true if the bold property is applied - */ - public boolean isBold() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetB()) { - return false; - } - return isCTOnOff(pr.getB()); - } - - /** - * Whether the bold property shall be applied to all non-complex script - * characters in the contents of this run when displayed in a document. - *

        - * This formatting property is a toggle property, which specifies that its - * behavior differs between its use within a style definition and its use as - * direct formatting. When used as part of a style definition, setting this - * property shall toggle the current state of that property as specified up - * to this point in the hierarchy (i.e. applied to not applied, and vice - * versa). Setting it to false (or an equivalent) shall - * result in the current setting remaining unchanged. However, when used as - * direct formatting, setting this property to true or false shall set the - * absolute state of the resulting property. - *

        - *

        - * If this element is not present, the default value is to leave the - * formatting applied at previous level in the style hierarchy. If this - * element is never applied in the style hierarchy, then bold shall not be - * applied to non-complex script characters. - *

        - * - * @param value true if the bold property is applied to - * this run - */ - public void setBold(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff bold = pr.isSetB() ? pr.getB() : pr.addNewB(); - bold.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - /** - * Get text color. The returned value is a string in the hex form "RRGGBB". - */ - public String getColor() { - String color = null; - if (run.isSetRPr()) { - CTRPr pr = run.getRPr(); - if (pr.isSetColor()) { - CTColor clr = pr.getColor(); - color = clr.xgetVal().getStringValue(); - } - } - return color; - } - - /** - * Set text color. - * - * @param rgbStr - the desired color, in the hex form "RRGGBB". - */ - public void setColor(String rgbStr) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTColor color = pr.isSetColor() ? pr.getColor() : pr.addNewColor(); - color.setVal(rgbStr); - } - - /** - * Return the string content of this text run - * - * @return the text of this text run or null if not set - */ - public String getText(int pos) { - return run.sizeOfTArray() == 0 ? null : run.getTArray(pos) - .getStringValue(); - } - - /** - * Returns text embedded in pictures - */ - public String getPictureText() { - return pictureText; - } - - /** - * Sets the text of this text run - * - * @param value the literal text which shall be displayed in the document - */ - public void setText(String value) { - setText(value, run.sizeOfTArray()); - } - - /** - * Sets the text of this text run in the - * - * @param value the literal text which shall be displayed in the document - * @param pos - position in the text array (NB: 0 based) - */ - public void setText(String value, int pos) { - if (pos > run.sizeOfTArray()) - throw new ArrayIndexOutOfBoundsException("Value too large for the parameter position in XWPFRun.setText(String value,int pos)"); - CTText t = (pos < run.sizeOfTArray() && pos >= 0) ? run.getTArray(pos) : run.addNewT(); - t.setStringValue(value); - preserveSpaces(t); - } - - /** - * Whether the italic property should be applied to all non-complex script - * characters in the contents of this run when displayed in a document. - * - * @return true if the italic property is applied - */ - public boolean isItalic() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetI()) - return false; - return isCTOnOff(pr.getI()); - } - - /** - * Whether the bold property shall be applied to all non-complex script - * characters in the contents of this run when displayed in a document - *

        - *

        - * This formatting property is a toggle property, which specifies that its - * behavior differs between its use within a style definition and its use as - * direct formatting. When used as part of a style definition, setting this - * property shall toggle the current state of that property as specified up - * to this point in the hierarchy (i.e. applied to not applied, and vice - * versa). Setting it to false (or an equivalent) shall - * result in the current setting remaining unchanged. However, when used as - * direct formatting, setting this property to true or false shall set the - * absolute state of the resulting property. - *

        - *

        - * If this element is not present, the default value is to leave the - * formatting applied at previous level in the style hierarchy. If this - * element is never applied in the style hierarchy, then bold shall not be - * applied to non-complex script characters. - *

        - * - * @param value true if the italic property is applied to - * this run - */ - public void setItalic(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff italic = pr.isSetI() ? pr.getI() : pr.addNewI(); - italic.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - /** - * Specifies that the contents of this run should be displayed along with an - * underline appearing directly below the character heigh - * - * @return the Underline pattern applyed to this run - * @see UnderlinePatterns - */ - public UnderlinePatterns getUnderline() { - CTRPr pr = run.getRPr(); - return (pr != null && pr.isSetU() && pr.getU().getVal() != null) - ? UnderlinePatterns.valueOf(pr.getU().getVal().intValue()) - : UnderlinePatterns.NONE; - } - - /** - * Specifies that the contents of this run should be displayed along with an - * underline appearing directly below the character heigh - *

        - *

        - * If this element is not present, the default value is to leave the - * formatting applied at previous level in the style hierarchy. If this - * element is never applied in the style hierarchy, then an underline shall - * not be applied to the contents of this run. - *

        - * - * @param value - - * underline type - * @see UnderlinePatterns : all possible patterns that could be applied - */ - public void setUnderline(UnderlinePatterns value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTUnderline underline = (pr.getU() == null) ? pr.addNewU() : pr.getU(); - underline.setVal(STUnderline.Enum.forInt(value.getValue())); - } - - /** - * Specifies that the contents of this run shall be displayed with a single - * horizontal line through the center of the line. - * - * @return true if the strike property is applied - */ - public boolean isStrikeThrough() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetStrike()) - return false; - return isCTOnOff(pr.getStrike()); - } - - /** - * Specifies that the contents of this run shall be displayed with a single - * horizontal line through the center of the line. - *

        - * This formatting property is a toggle property, which specifies that its - * behaviour differs between its use within a style definition and its use as - * direct formatting. When used as part of a style definition, setting this - * property shall toggle the current state of that property as specified up - * to this point in the hierarchy (i.e. applied to not applied, and vice - * versa). Setting it to false (or an equivalent) shall result in the - * current setting remaining unchanged. However, when used as direct - * formatting, setting this property to true or false shall set the absolute - * state of the resulting property. - *

        - *

        - * If this element is not present, the default value is to leave the - * formatting applied at previous level in the style hierarchy. If this - * element is never applied in the style hierarchy, then strikethrough shall - * not be applied to the contents of this run. - *

        - * - * @param value true if the strike property is applied to - * this run - */ - public void setStrikeThrough(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff strike = pr.isSetStrike() ? pr.getStrike() : pr.addNewStrike(); - strike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - @Deprecated - public boolean isStrike() { - return isStrikeThrough(); - } - - @Deprecated - public void setStrike(boolean value) { - setStrikeThrough(value); - } - - /** - * Specifies that the contents of this run shall be displayed with a double - * horizontal line through the center of the line. - * - * @return true if the double strike property is applied - */ - public boolean isDoubleStrikeThrough() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetDstrike()) - return false; - return isCTOnOff(pr.getDstrike()); - } - - /** - * Specifies that the contents of this run shall be displayed with a - * double horizontal line through the center of the line. - * - * @see #setStrikeThrough(boolean) for the rules about this - */ - public void setDoubleStrikethrough(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff dstrike = pr.isSetDstrike() ? pr.getDstrike() : pr.addNewDstrike(); - dstrike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - public boolean isSmallCaps() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetSmallCaps()) - return false; - return isCTOnOff(pr.getSmallCaps()); - } - - public void setSmallCaps(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff caps = pr.isSetSmallCaps() ? pr.getSmallCaps() : pr.addNewSmallCaps(); - caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - public boolean isCapitalized() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetCaps()) - return false; - return isCTOnOff(pr.getCaps()); - } - - public void setCapitalized(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff caps = pr.isSetCaps() ? pr.getCaps() : pr.addNewCaps(); - caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - public boolean isShadowed() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetShadow()) - return false; - return isCTOnOff(pr.getShadow()); - } - - public void setShadow(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff shadow = pr.isSetShadow() ? pr.getShadow() : pr.addNewShadow(); - shadow.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - public boolean isImprinted() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetImprint()) - return false; - return isCTOnOff(pr.getImprint()); - } - - public void setImprinted(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff imprinted = pr.isSetImprint() ? pr.getImprint() : pr.addNewImprint(); - imprinted.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - public boolean isEmbossed() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetEmboss()) - return false; - return isCTOnOff(pr.getEmboss()); - } - - public void setEmbossed(boolean value) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTOnOff emboss = pr.isSetEmboss() ? pr.getEmboss() : pr.addNewEmboss(); - emboss.setVal(value ? STOnOff.TRUE : STOnOff.FALSE); - } - - /** - * Specifies the alignment which shall be applied to the contents of this - * run in relation to the default appearance of the run's text. - * This allows the text to be repositioned as subscript or superscript without - * altering the font size of the run properties. - * - * @return VerticalAlign - * @see VerticalAlign all possible value that could be applyed to this run - */ - public VerticalAlign getSubscript() { - CTRPr pr = run.getRPr(); - return (pr != null && pr.isSetVertAlign()) ? VerticalAlign.valueOf(pr.getVertAlign().getVal().intValue()) : VerticalAlign.BASELINE; - } - - /** - * Specifies the alignment which shall be applied to the contents of this - * run in relation to the default appearance of the run's text. This allows - * the text to be repositioned as subscript or superscript without altering - * the font size of the run properties. - *

        - * If this element is not present, the default value is to leave the - * formatting applied at previous level in the style hierarchy. If this - * element is never applied in the style hierarchy, then the text shall not - * be subscript or superscript relative to the default baseline location for - * the contents of this run. - *

        - * - * @param valign - * @see VerticalAlign - */ - public void setSubscript(VerticalAlign valign) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTVerticalAlignRun ctValign = pr.isSetVertAlign() ? pr.getVertAlign() : pr.addNewVertAlign(); - ctValign.setVal(STVerticalAlignRun.Enum.forInt(valign.getValue())); - } - - public int getKerning() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetKern()) - return 0; - return pr.getKern().getVal().intValue(); - } - - public void setKerning(int kern) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTHpsMeasure kernmes = pr.isSetKern() ? pr.getKern() : pr.addNewKern(); - kernmes.setVal(BigInteger.valueOf(kern)); - } - - public boolean isHighlighted() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetHighlight()) - return false; - if (pr.getHighlight().getVal() == STHighlightColor.NONE) - return false; - return true; - } - // TODO Provide a wrapper round STHighlightColor, then expose getter/setter - // for the highlight colour. Ideally also then add to CharacterRun interface - - public int getCharacterSpacing() { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetSpacing()) - return 0; - return pr.getSpacing().getVal().intValue(); - } - - public void setCharacterSpacing(int twips) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTSignedTwipsMeasure spc = pr.isSetSpacing() ? pr.getSpacing() : pr.addNewSpacing(); - spc.setVal(BigInteger.valueOf(twips)); - } - - /** - * Gets the fonts which shall be used to display the text contents of - * this run. Specifies a font which shall be used to format all characters - * in the ASCII range (0 - 127) within the parent run - * - * @return a string representing the font family - */ - public String getFontFamily() { - return getFontFamily(null); - } - - /** - * Specifies the fonts which shall be used to display the text contents of - * this run. Specifies a font which shall be used to format all characters - * in the ASCII range (0 - 127) within the parent run. - *

        - * Also sets the other font ranges, if they haven't been set before - * - * @param fontFamily - * @see FontCharRange - */ - public void setFontFamily(String fontFamily) { - setFontFamily(fontFamily, null); - } - - /** - * Alias for {@link #getFontFamily()} - */ - public String getFontName() { - return getFontFamily(); - } - - /** - * Gets the font family for the specified font char range. - * If fcr is null, the font char range "ascii" is used - * - * @param fcr the font char range, defaults to "ansi" - * @return a string representing the font famil - */ - public String getFontFamily(FontCharRange fcr) { - CTRPr pr = run.getRPr(); - if (pr == null || !pr.isSetRFonts()) return null; - - CTFonts fonts = pr.getRFonts(); - switch (fcr == null ? FontCharRange.ascii : fcr) { - default: - case ascii: - return fonts.getAscii(); - case cs: - return fonts.getCs(); - case eastAsia: - return fonts.getEastAsia(); - case hAnsi: - return fonts.getHAnsi(); - } - } - - /** - * Specifies the fonts which shall be used to display the text contents of - * this run. The default handling for fcr == null is to overwrite the - * ascii font char range with the given font family and also set all not - * specified font ranges - * - * @param fontFamily - * @param fcr FontCharRange or null for default handling - */ - public void setFontFamily(String fontFamily, FontCharRange fcr) { - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTFonts fonts = pr.isSetRFonts() ? pr.getRFonts() : pr.addNewRFonts(); - - if (fcr == null) { - fonts.setAscii(fontFamily); - if (!fonts.isSetHAnsi()) { - fonts.setHAnsi(fontFamily); - } - if (!fonts.isSetCs()) { - fonts.setCs(fontFamily); - } - if (!fonts.isSetEastAsia()) { - fonts.setEastAsia(fontFamily); - } - } else { - switch (fcr) { - case ascii: - fonts.setAscii(fontFamily); - break; - case cs: - fonts.setCs(fontFamily); - break; - case eastAsia: - fonts.setEastAsia(fontFamily); - break; - case hAnsi: - fonts.setHAnsi(fontFamily); - break; - } - } - } - - /** - * Specifies the font size which shall be applied to all non complex script - * characters in the contents of this run when displayed. - * - * @return value representing the font size - */ - public int getFontSize() { - CTRPr pr = run.getRPr(); - return (pr != null && pr.isSetSz()) ? pr.getSz().getVal().divide(new BigInteger("2")).intValue() : -1; - } - - /** - * Specifies the font size which shall be applied to all non complex script - * characters in the contents of this run when displayed. - *

        - * If this element is not present, the default value is to leave the value - * applied at previous level in the style hierarchy. If this element is - * never applied in the style hierarchy, then any appropriate font size may - * be used for non complex script characters. - *

        - * - * @param size - */ - public void setFontSize(int size) { - BigInteger bint = new BigInteger("" + size); - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTHpsMeasure ctSize = pr.isSetSz() ? pr.getSz() : pr.addNewSz(); - ctSize.setVal(bint.multiply(new BigInteger("2"))); - } - - /** - * This element specifies the amount by which text shall be raised or - * lowered for this run in relation to the default baseline of the - * surrounding non-positioned text. This allows the text to be repositioned - * without altering the font size of the contents. - * - * @return a big integer representing the amount of text shall be "moved" - */ - public int getTextPosition() { - CTRPr pr = run.getRPr(); - return (pr != null && pr.isSetPosition()) ? pr.getPosition().getVal().intValue() - : -1; - } - - /** - * This element specifies the amount by which text shall be raised or - * lowered for this run in relation to the default baseline of the - * surrounding non-positioned text. This allows the text to be repositioned - * without altering the font size of the contents. - *

        - * If the val attribute is positive, then the parent run shall be raised - * above the baseline of the surrounding text by the specified number of - * half-points. If the val attribute is negative, then the parent run shall - * be lowered below the baseline of the surrounding text by the specified - * number of half-points. - *

        - *

        - * If this element is not present, the default value is to leave the - * formatting applied at previous level in the style hierarchy. If this - * element is never applied in the style hierarchy, then the text shall not - * be raised or lowered relative to the default baseline location for the - * contents of this run. - *

        - * - * @param val - */ - public void setTextPosition(int val) { - BigInteger bint = new BigInteger("" + val); - CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); - CTSignedHpsMeasure position = pr.isSetPosition() ? pr.getPosition() : pr.addNewPosition(); - position.setVal(bint); - } - - /** - * - */ - public void removeBreak() { - // TODO - } - - /** - * Specifies that a break shall be placed at the current location in the run - * content. - * A break is a special character which is used to override the - * normal line breaking that would be performed based on the normal layout - * of the document's contents. - * - * @see #addCarriageReturn() - */ - public void addBreak() { - run.addNewBr(); - } - - /** - * Specifies that a break shall be placed at the current location in the run - * content. - * A break is a special character which is used to override the - * normal line breaking that would be performed based on the normal layout - * of the document's contents. - *

        - * The behavior of this break character (the - * location where text shall be restarted after this break) shall be - * determined by its type values. - *

        - * - * @see BreakType - */ - public void addBreak(BreakType type) { - CTBr br = run.addNewBr(); - br.setType(STBrType.Enum.forInt(type.getValue())); - } - - /** - * Specifies that a break shall be placed at the current location in the run - * content. A break is a special character which is used to override the - * normal line breaking that would be performed based on the normal layout - * of the document's contents. - *

        - * The behavior of this break character (the - * location where text shall be restarted after this break) shall be - * determined by its type (in this case is BreakType.TEXT_WRAPPING as default) and clear attribute values. - *

        - * - * @see BreakClear - */ - public void addBreak(BreakClear clear) { - CTBr br = run.addNewBr(); - br.setType(STBrType.Enum.forInt(BreakType.TEXT_WRAPPING.getValue())); - br.setClear(STBrClear.Enum.forInt(clear.getValue())); - } - - /** - * Specifies that a tab shall be placed at the current location in - * the run content. - */ - public void addTab() { - run.addNewTab(); - } - - public void removeTab() { - //TODO - } - - /** - * Specifies that a carriage return shall be placed at the - * current location in the run content. - * A carriage return is used to end the current line of text in - * Wordprocess. - * The behavior of a carriage return in run content shall be - * identical to a break character with null type and clear attributes, which - * shall end the current line and find the next available line on which to - * continue. - * The carriage return character forced the following text to be - * restarted on the next available line in the document. - */ - public void addCarriageReturn() { - run.addNewCr(); - } - - public void removeCarriageReturn() { - //TODO - } - - /** - * Adds a picture to the run. This method handles - * attaching the picture data to the overall file. - * - * @param pictureData The raw picture data - * @param pictureType The type of the picture, eg {@link Document#PICTURE_TYPE_JPEG} - * @param width width in EMUs. To convert to / from points use {@link org.apache.poi.util.Units} - * @param height height in EMUs. To convert to / from points use {@link org.apache.poi.util.Units} - * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException - * @throws IOException - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG - * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB - */ - public XWPFPicture addPicture(InputStream pictureData, int pictureType, String filename, int width, int height) - throws InvalidFormatException, IOException { - String relationId; - XWPFPictureData picData; - - // Work out what to add the picture to, then add both the - // picture and the relationship for it - // TODO Should we have an interface for this sort of thing? - if (parent.getPart() instanceof XWPFHeaderFooter) { - XWPFHeaderFooter headerFooter = (XWPFHeaderFooter)parent.getPart(); - relationId = headerFooter.addPictureData(pictureData, pictureType); - picData = (XWPFPictureData) headerFooter.getRelationById(relationId); - } else { - @SuppressWarnings("resource") - XWPFDocument doc = parent.getDocument(); - relationId = doc.addPictureData(pictureData, pictureType); - picData = (XWPFPictureData) doc.getRelationById(relationId); - } - - // Create the drawing entry for it - try { - CTDrawing drawing = run.addNewDrawing(); - CTInline inline = drawing.addNewInline(); - - // Do the fiddly namespace bits on the inline - // (We need full control of what goes where and as what) - String xml = - "" + - "" + - "" + - "" + - ""; - InputSource is = new InputSource(new StringReader(xml)); - org.w3c.dom.Document doc = DocumentHelper.readDocument(is); - inline.set(XmlToken.Factory.parse(doc.getDocumentElement(), DEFAULT_XML_OPTIONS)); - - // Setup the inline - inline.setDistT(0); - inline.setDistR(0); - inline.setDistB(0); - inline.setDistL(0); - - CTNonVisualDrawingProps docPr = inline.addNewDocPr(); - long id = getParent().getDocument().getDrawingIdManager().reserveNew(); - docPr.setId(id); - /* This name is not visible in Word 2010 anywhere. */ - docPr.setName("Drawing " + id); - docPr.setDescr(filename); - - CTPositiveSize2D extent = inline.addNewExtent(); - extent.setCx(width); - extent.setCy(height); - - // Grab the picture object - CTGraphicalObject graphic = inline.getGraphic(); - CTGraphicalObjectData graphicData = graphic.getGraphicData(); - CTPicture pic = getCTPictures(graphicData).get(0); - - // Set it up - CTPictureNonVisual nvPicPr = pic.addNewNvPicPr(); - - CTNonVisualDrawingProps cNvPr = nvPicPr.addNewCNvPr(); - /* use "0" for the id. See ECM-576, 20.2.2.3 */ - cNvPr.setId(0L); - /* This name is not visible in Word 2010 anywhere */ - cNvPr.setName("Picture " + id); - cNvPr.setDescr(filename); - - CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr(); - cNvPicPr.addNewPicLocks().setNoChangeAspect(true); - - CTBlipFillProperties blipFill = pic.addNewBlipFill(); - CTBlip blip = blipFill.addNewBlip(); - blip.setEmbed(parent.getDocument().getRelationId(picData)); - blipFill.addNewStretch().addNewFillRect(); - - CTShapeProperties spPr = pic.addNewSpPr(); - CTTransform2D xfrm = spPr.addNewXfrm(); - - CTPoint2D off = xfrm.addNewOff(); - off.setX(0); - off.setY(0); - - CTPositiveSize2D ext = xfrm.addNewExt(); - ext.setCx(width); - ext.setCy(height); - - CTPresetGeometry2D prstGeom = spPr.addNewPrstGeom(); - prstGeom.setPrst(STShapeType.RECT); - prstGeom.addNewAvLst(); - - // Finish up - XWPFPicture xwpfPicture = new XWPFPicture(pic, this); - pictures.add(xwpfPicture); - return xwpfPicture; - } catch (XmlException e) { - throw new IllegalStateException(e); - } catch (SAXException e) { - throw new IllegalStateException(e); - } - } - - /** - * Returns the embedded pictures of the run. These - * are pictures which reference an external, - * embedded picture image such as a .png or .jpg - */ - public List getEmbeddedPictures() { - return pictures; - } - - /** - * Returns the string version of the text - */ - public String toString() { - return text(); - } - - /** - * Returns the string version of the text, with tabs and - * carriage returns in place of their xml equivalents. - */ - public String text() { - StringBuffer text = new StringBuffer(); - - // Grab the text and tabs of the text run - // Do so in a way that preserves the ordering - XmlCursor c = run.newCursor(); - c.selectPath("./*"); - while (c.toNextSelection()) { - XmlObject o = c.getObject(); - if (o instanceof CTText) { - String tagName = o.getDomNode().getNodeName(); - // Field Codes (w:instrText, defined in spec sec. 17.16.23) - // come up as instances of CTText, but we don't want them - // in the normal text output - if (!"w:instrText".equals(tagName)) { - text.append(((CTText) o).getStringValue()); - } - } - - // Complex type evaluation (currently only for extraction of check boxes) - if (o instanceof CTFldChar) { - CTFldChar ctfldChar = ((CTFldChar) o); - if (ctfldChar.getFldCharType() == STFldCharType.BEGIN) { - if (ctfldChar.getFfData() != null) { - for (CTFFCheckBox checkBox : ctfldChar.getFfData().getCheckBoxList()) { - if (checkBox.getDefault() != null && checkBox.getDefault().getVal() == STOnOff.X_1) { - text.append("|X|"); - } else { - text.append("|_|"); - } - } - } - } - } - - if (o instanceof CTPTab) { - text.append("\t"); - } - if (o instanceof CTBr) { - text.append("\n"); - } - if (o instanceof CTEmpty) { - // Some inline text elements get returned not as - // themselves, but as CTEmpty, owing to some odd - // definitions around line 5642 of the XSDs - // This bit works around it, and replicates the above - // rules for that case - String tagName = o.getDomNode().getNodeName(); - if ("w:tab".equals(tagName) || "tab".equals(tagName)) { - text.append("\t"); - } - if ("w:br".equals(tagName) || "br".equals(tagName)) { - text.append("\n"); - } - if ("w:cr".equals(tagName) || "cr".equals(tagName)) { - text.append("\n"); - } - } - if (o instanceof CTFtnEdnRef) { - CTFtnEdnRef ftn = (CTFtnEdnRef) o; - String footnoteRef = ftn.getDomNode().getLocalName().equals("footnoteReference") ? - "[footnoteRef:" + ftn.getId().intValue() + "]" : "[endnoteRef:" + ftn.getId().intValue() + "]"; - text.append(footnoteRef); - } - } - - c.dispose(); - - // Any picture text? - if (pictureText != null && pictureText.length() > 0) { - text.append("\n").append(pictureText); - } - - return text.toString(); - } - - /** - * @see [MS-OI29500] Run Fonts - */ - public static enum FontCharRange { - ascii /* char 0-127 */, - cs /* complex symbol */, - eastAsia /* east asia */, - hAnsi /* high ansi */ - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java deleted file mode 100644 index fd8389ef5..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun; - -/** - * Experimental class to offer rudimentary read-only processing of - * of StructuredDocumentTags/ContentControl - *

        - * WARNING - APIs expected to change rapidly - */ -public class XWPFSDT extends AbstractXWPFSDT - implements IBodyElement, IRunBody, ISDTContents, IRunElement { - private final ISDTContent content; - - public XWPFSDT(CTSdtRun sdtRun, IBody part) { - super(sdtRun.getSdtPr(), part); - this.content = new XWPFSDTContent(sdtRun.getSdtContent(), part, this); - } - - public XWPFSDT(CTSdtBlock block, IBody part) { - super(block.getSdtPr(), part); - this.content = new XWPFSDTContent(block.getSdtContent(), part, this); - } - - public ISDTContent getContent() { - return content; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java deleted file mode 100644 index fb40955ef..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtCell; - -/** - * Experimental class to offer rudimentary read-only processing of - * of StructuredDocumentTags/ContentControl that can appear - * in a table row as if a table cell. - *

        - * These can contain one or more cells or other SDTs within them. - *

        - * WARNING - APIs expected to change rapidly - */ -public class XWPFSDTCell extends AbstractXWPFSDT implements ICell { - private final XWPFSDTContentCell cellContent; - - public XWPFSDTCell(CTSdtCell sdtCell, XWPFTableRow xwpfTableRow, IBody part) { - super(sdtCell.getSdtPr(), part); - cellContent = new XWPFSDTContentCell(sdtCell.getSdtContent(), xwpfTableRow, part); - } - - @Override - public ISDTContent getContent() { - return cellContent; - } - -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java deleted file mode 100644 index d160e662e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ArrayList; -import java.util.List; - -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; - -/** - * Experimental class to offer rudimentary read-only processing of - * of the contentblock of an SDT/ContentControl. - *

        - *

        - *

        - * WARNING - APIs expected to change rapidly - */ -public class XWPFSDTContent implements ISDTContent { - - // private final IBody part; - // private final XWPFDocument document; - private List paragraphs = new ArrayList(); - private List tables = new ArrayList(); - private List runs = new ArrayList(); - private List contentControls = new ArrayList(); - private List bodyElements = new ArrayList(); - - public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent) { - for (CTR ctr : sdtRun.getRArray()) { - XWPFRun run = new XWPFRun(ctr, parent); - runs.add(run); - bodyElements.add(run); - } - } - - public XWPFSDTContent(CTSdtContentBlock block, IBody part, IRunBody parent) { - XmlCursor cursor = block.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, part); - bodyElements.add(p); - paragraphs.add(p); - } else if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, part); - bodyElements.add(t); - tables.add(t); - } else if (o instanceof CTSdtBlock) { - XWPFSDT c = new XWPFSDT(((CTSdtBlock) o), part); - bodyElements.add(c); - contentControls.add(c); - } else if (o instanceof CTR) { - XWPFRun run = new XWPFRun((CTR) o, parent); - runs.add(run); - bodyElements.add(run); - } - } - cursor.dispose(); - } - - public String getText() { - StringBuilder text = new StringBuilder(); - boolean addNewLine = false; - for (int i = 0; i < bodyElements.size(); i++) { - Object o = bodyElements.get(i); - if (o instanceof XWPFParagraph) { - appendParagraph((XWPFParagraph) o, text); - addNewLine = true; - } else if (o instanceof XWPFTable) { - appendTable((XWPFTable) o, text); - addNewLine = true; - } else if (o instanceof XWPFSDT) { - text.append(((XWPFSDT) o).getContent().getText()); - addNewLine = true; - } else if (o instanceof XWPFRun) { - text.append(((XWPFRun) o).toString()); - addNewLine = false; - } - if (addNewLine == true && i < bodyElements.size() - 1) { - text.append("\n"); - } - } - return text.toString(); - } - - private void appendTable(XWPFTable table, StringBuilder text) { - //this works recursively to pull embedded tables from within cells - for (XWPFTableRow row : table.getRows()) { - List cells = row.getTableICells(); - for (int i = 0; i < cells.size(); i++) { - ICell cell = cells.get(i); - if (cell instanceof XWPFTableCell) { - text.append(((XWPFTableCell) cell).getTextRecursively()); - } else if (cell instanceof XWPFSDTCell) { - text.append(((XWPFSDTCell) cell).getContent().getText()); - } - if (i < cells.size() - 1) { - text.append("\t"); - } - } - text.append('\n'); - } - } - - private void appendParagraph(XWPFParagraph paragraph, StringBuilder text) { - for (IRunElement run : paragraph.getRuns()) { - text.append(run.toString()); - } - } - - public String toString() { - return getText(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java deleted file mode 100644 index c8246f6dd..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 javax.xml.namespace.QName; - -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlCursor.TokenType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentCell; - - -/** - * Experimental class to offer rudimentary read-only processing of - * of the XWPFSDTCellContent. - *

        - * WARNING - APIs expected to change rapidly - */ -public class XWPFSDTContentCell implements ISDTContent { - - //A full implementation would grab the icells - //that a content cell can contain. This would require - //significant changes, including changing the notion that the - //parent of a cell can be not just a row, but an sdt. - //For now we are just grabbing the text out of the text tokentypes. - - //private List cells = new ArrayList(). - - private String text = ""; - - public XWPFSDTContentCell(CTSdtContentCell sdtContentCell, - XWPFTableRow xwpfTableRow, IBody part) { - super(); - //sdtContentCell is allowed to be null: minOccurs="0" maxOccurs="1" - if (sdtContentCell == null) { - return; - } - StringBuilder sb = new StringBuilder(); - XmlCursor cursor = sdtContentCell.newCursor(); - - //keep track of the following, - //and add "\n" only before the start of a body - //element if it is not the first body element. - - //index of cell in row - int tcCnt = 0; - //count of body objects - int iBodyCnt = 0; - int depth = 1; - - while (cursor.hasNextToken() && depth > 0) { - TokenType t = cursor.toNextToken(); - if (t.isText()) { - sb.append(cursor.getTextValue()); - } else if (isStartToken(cursor, "tr")) { - tcCnt = 0; - iBodyCnt = 0; - } else if (isStartToken(cursor, "tc")) { - if (tcCnt++ > 0) { - sb.append("\t"); - } - iBodyCnt = 0; - } else if (isStartToken(cursor, "p") || - isStartToken(cursor, "tbl") || - isStartToken(cursor, "sdt")) { - if (iBodyCnt > 0) { - sb.append("\n"); - } - iBodyCnt++; - } - if (cursor.isStart()) { - depth++; - } else if (cursor.isEnd()) { - depth--; - } - } - text = sb.toString(); - cursor.dispose(); - } - - - private boolean isStartToken(XmlCursor cursor, String string) { - if (!cursor.isStart()) { - return false; - } - QName qName = cursor.getName(); - if (qName != null && qName.getLocalPart() != null && - qName.getLocalPart().equals(string)) { - return true; - } - return false; - } - - - public String getText() { - return text; - } - - public String toString() { - return getText(); - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java deleted file mode 100644 index d9d29a330..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java +++ /dev/null @@ -1,442 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Arrays; - -import javax.xml.namespace.QName; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocProtect; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSettings; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTZoom; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STAlgClass; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STAlgType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STCryptProv; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.SettingsDocument; - -public class XWPFSettings extends POIXMLDocumentPart { - - private CTSettings ctSettings; - - /** - * @since POI 3.14-Beta1 - */ - public XWPFSettings(PackagePart part) throws IOException { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException { - this(part); - } - - public XWPFSettings() { - super(); - ctSettings = CTSettings.Factory.newInstance(); - } - - @Override - protected void onDocumentRead() throws IOException { - super.onDocumentRead(); - readFrom(getPackagePart().getInputStream()); - } - - /** - * Set zoom.
        - * In the zoom tag inside settings.xml file
        - * it sets the value of zoom - *
        - * sample snippet from settings.xml - *

        -     *    <w:zoom w:percent="50" />
        -     * 
        -     *
        -     * @return percentage as an integer of zoom level
        -     */
        -    public long getZoomPercent() {
        -        CTZoom zoom;
        -        if (!ctSettings.isSetZoom()) {
        -            zoom = ctSettings.addNewZoom();
        -        } else {
        -            zoom = ctSettings.getZoom();
        -        }
        -
        -        
        -        BigInteger percent = zoom.getPercent();
        -        if(percent == null) {
        -            return 100;
        -        }
        -        return percent.longValue();
        -    }
        -
        -    /**
        -     * Set zoom.
        - * In the zoom tag inside settings.xml file
        - * it sets the value of zoom - *
        - * sample snippet from settings.xml - *
        -     *    <w:zoom w:percent="50" />
        -     * 
        -     */
        -    public void setZoomPercent(long zoomPercent) {
        -        if (!ctSettings.isSetZoom()) {
        -            ctSettings.addNewZoom();
        -        }
        -        CTZoom zoom = ctSettings.getZoom();
        -        zoom.setPercent(BigInteger.valueOf(zoomPercent));
        -    }
        -	
        -	/**
        -     * Verifies the documentProtection tag inside settings.xml file 
        - * if the protection is enforced (w:enforcement="1")
        - *

        - *
        - * sample snippet from settings.xml - *

        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option any - */ - public boolean isEnforcedWith() { - CTDocProtect ctDocProtect = ctSettings.getDocumentProtection(); - - if (ctDocProtect == null) { - return false; - } - - return ctDocProtect.getEnforcement().equals(STOnOff.X_1); - } - - /** - * Verifies the documentProtection tag inside settings.xml file
        - * if the protection is enforced (w:enforcement="1")
        - * and if the kind of protection equals to passed (STDocProtect.Enum editValue)
        - *

        - *
        - * sample snippet from settings.xml - *

        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
        -     * 
        - * - * @return true if documentProtection is enforced with option readOnly - */ - public boolean isEnforcedWith(STDocProtect.Enum editValue) { - CTDocProtect ctDocProtect = ctSettings.getDocumentProtection(); - - if (ctDocProtect == null) { - return false; - } - - return ctDocProtect.getEnforcement().equals(STOnOff.X_1) && ctDocProtect.getEdit().equals(editValue); - } - - /** - * Enforces the protection with the option specified by passed editValue.
        - *
        - * In the documentProtection tag inside settings.xml file
        - * it sets the value of enforcement to "1" (w:enforcement="1")
        - * and the value of edit to the passed editValue (w:edit="[passed editValue]")
        - *
        - * sample snippet from settings.xml - *
        -     *     <w:settings  ... >
        -     *         <w:documentProtection w:edit="[passed editValue]" w:enforcement="1"/>
        -     * 
        - */ - public void setEnforcementEditValue(org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect.Enum editValue) { - safeGetDocumentProtection().setEnforcement(STOnOff.X_1); - safeGetDocumentProtection().setEdit(editValue); - } - - /** - * Enforces the protection with the option specified by passed editValue and password.
        - *
        - * sample snippet from settings.xml - *
        -     *   <w:documentProtection w:edit="[passed editValue]" w:enforcement="1"
        -     *       w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
        -     *       w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
        -     *       w:cryptSpinCount="100000" w:hash="..." w:salt="...."
        -     *   />
        -     * 
        - * - * @param editValue the protection type - * @param password the plaintext password, if null no password will be applied - * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported. - * if null, it will default default to sha1 - */ - public void setEnforcementEditValue(org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect.Enum editValue, - String password, HashAlgorithm hashAlgo) { - safeGetDocumentProtection().setEnforcement(STOnOff.X_1); - safeGetDocumentProtection().setEdit(editValue); - - if (password == null) { - if (safeGetDocumentProtection().isSetCryptProviderType()) { - safeGetDocumentProtection().unsetCryptProviderType(); - } - - if (safeGetDocumentProtection().isSetCryptAlgorithmClass()) { - safeGetDocumentProtection().unsetCryptAlgorithmClass(); - } - - if (safeGetDocumentProtection().isSetCryptAlgorithmType()) { - safeGetDocumentProtection().unsetCryptAlgorithmType(); - } - - if (safeGetDocumentProtection().isSetCryptAlgorithmSid()) { - safeGetDocumentProtection().unsetCryptAlgorithmSid(); - } - - if (safeGetDocumentProtection().isSetSalt()) { - safeGetDocumentProtection().unsetSalt(); - } - - if (safeGetDocumentProtection().isSetCryptSpinCount()) { - safeGetDocumentProtection().unsetCryptSpinCount(); - } - - if (safeGetDocumentProtection().isSetHash()) { - safeGetDocumentProtection().unsetHash(); - } - } else { - final STCryptProv.Enum providerType; - final int sid; - if (hashAlgo == null) { - hashAlgo = HashAlgorithm.sha1; - } - - switch (hashAlgo) { - case md2: - providerType = STCryptProv.RSA_FULL; - sid = 1; - break; - case md4: - providerType = STCryptProv.RSA_FULL; - sid = 2; - break; - case md5: - providerType = STCryptProv.RSA_FULL; - sid = 3; - break; - case sha1: - providerType = STCryptProv.RSA_FULL; - sid = 4; - break; - case sha256: - providerType = STCryptProv.RSA_AES; - sid = 12; - break; - case sha384: - providerType = STCryptProv.RSA_AES; - sid = 13; - break; - case sha512: - providerType = STCryptProv.RSA_AES; - sid = 14; - break; - default: - throw new EncryptedDocumentException - ("Hash algorithm '" + hashAlgo + "' is not supported for document write protection."); - } - - - SecureRandom random = new SecureRandom(); - byte salt[] = random.generateSeed(16); - - // Iterations specifies the number of times the hashing function shall be iteratively run (using each - // iteration's result as the input for the next iteration). - int spinCount = 100000; - - String legacyHash = CryptoFunctions.xorHashPasswordReversed(password); - // Implementation Notes List: - // --> In this third stage, the reversed byte order legacy hash from the second stage shall - // be converted to Unicode hex string representation - byte hash[] = CryptoFunctions.hashPassword(legacyHash, hashAlgo, salt, spinCount, false); - - safeGetDocumentProtection().setSalt(salt); - safeGetDocumentProtection().setHash(hash); - safeGetDocumentProtection().setCryptSpinCount(BigInteger.valueOf(spinCount)); - safeGetDocumentProtection().setCryptAlgorithmType(STAlgType.TYPE_ANY); - safeGetDocumentProtection().setCryptAlgorithmClass(STAlgClass.HASH); - safeGetDocumentProtection().setCryptProviderType(providerType); - safeGetDocumentProtection().setCryptAlgorithmSid(BigInteger.valueOf(sid)); - } - } - - /** - * Validates the existing password - * - * @param password - * @return true, only if password was set and equals, false otherwise - */ - public boolean validateProtectionPassword(String password) { - BigInteger sid = safeGetDocumentProtection().getCryptAlgorithmSid(); - byte hash[] = safeGetDocumentProtection().getHash(); - byte salt[] = safeGetDocumentProtection().getSalt(); - BigInteger spinCount = safeGetDocumentProtection().getCryptSpinCount(); - - if (sid == null || hash == null || salt == null || spinCount == null) return false; - - HashAlgorithm hashAlgo; - switch (sid.intValue()) { - case 1: - hashAlgo = HashAlgorithm.md2; - break; - case 2: - hashAlgo = HashAlgorithm.md4; - break; - case 3: - hashAlgo = HashAlgorithm.md5; - break; - case 4: - hashAlgo = HashAlgorithm.sha1; - break; - case 12: - hashAlgo = HashAlgorithm.sha256; - break; - case 13: - hashAlgo = HashAlgorithm.sha384; - break; - case 14: - hashAlgo = HashAlgorithm.sha512; - break; - default: - return false; - } - - String legacyHash = CryptoFunctions.xorHashPasswordReversed(password); - // Implementation Notes List: - // --> In this third stage, the reversed byte order legacy hash from the second stage shall - // be converted to Unicode hex string representation - byte hash2[] = CryptoFunctions.hashPassword(legacyHash, hashAlgo, salt, spinCount.intValue(), false); - - return Arrays.equals(hash, hash2); - } - - /** - * Removes protection enforcement.
        - * In the documentProtection tag inside settings.xml file
        - * it sets the value of enforcement to "0" (w:enforcement="0")
        - */ - public void removeEnforcement() { - safeGetDocumentProtection().setEnforcement(STOnOff.X_0); - } - - /** - * Enforces fields update on document open (in Word). - * In the settings.xml file
        - * sets the updateSettings value to true (w:updateSettings w:val="true") - *

        - * NOTICES: - *

          - *
        • Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?" - * (if "Update automatic links at open" is enabled)
        • - *
        • Flag is removed after saving with changes in Word
        • - *
        - */ - public void setUpdateFields() { - CTOnOff onOff = CTOnOff.Factory.newInstance(); - onOff.setVal(STOnOff.TRUE); - ctSettings.setUpdateFields(onOff); - } - - boolean isUpdateFields() { - return ctSettings.isSetUpdateFields() && ctSettings.getUpdateFields().getVal() == STOnOff.TRUE; - } - - /** - * Check if revision tracking is turned on. - * - * @return true if revision tracking is turned on - */ - public boolean isTrackRevisions() { - return ctSettings.isSetTrackRevisions(); - } - - /** - * Enable or disable revision tracking. - * - * @param enable true to turn on revision tracking, false to turn off revision tracking - */ - public void setTrackRevisions(boolean enable) { - if (enable) { - if (!ctSettings.isSetTrackRevisions()) { - ctSettings.addNewTrackRevisions(); - } - } else { - if (ctSettings.isSetTrackRevisions()) { - ctSettings.unsetTrackRevisions(); - } - } - } - - @Override - protected void commit() throws IOException { - if (ctSettings == null) { - throw new IllegalStateException("Unable to write out settings that were never read in!"); - } - - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTSettings.type.getName().getNamespaceURI(), "settings")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - ctSettings.save(out, xmlOptions); - out.close(); - } - - private CTDocProtect safeGetDocumentProtection() { - CTDocProtect documentProtection = ctSettings.getDocumentProtection(); - if (documentProtection == null) { - documentProtection = CTDocProtect.Factory.newInstance(); - ctSettings.setDocumentProtection(documentProtection); - } - return ctSettings.getDocumentProtection(); - } - - private void readFrom(InputStream inputStream) { - try { - ctSettings = SettingsDocument.Factory.parse(inputStream, DEFAULT_XML_OPTIONS).getSettings(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java deleted file mode 100644 index a6ebdcc71..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java +++ /dev/null @@ -1,159 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType; - -/** - * @author Philipp Epp - */ -public class XWPFStyle { - - protected XWPFStyles styles; - private CTStyle ctStyle; - - /** - * constructor - * - * @param style - */ - public XWPFStyle(CTStyle style) { - this(style, null); - } - - /** - * constructor - * - * @param style - * @param styles - */ - public XWPFStyle(CTStyle style, XWPFStyles styles) { - this.ctStyle = style; - this.styles = styles; - } - - /** - * get StyleID of the style - * - * @return styleID StyleID of the style - */ - public String getStyleId() { - return ctStyle.getStyleId(); - } - - /** - * set styleID - * - * @param styleId - */ - public void setStyleId(String styleId) { - ctStyle.setStyleId(styleId); - } - - /** - * get Type of the Style - * - * @return ctType - */ - public STStyleType.Enum getType() { - return ctStyle.getType(); - } - - /** - * set styleType - * - * @param type - */ - public void setType(STStyleType.Enum type) { - ctStyle.setType(type); - } - - /** - * set style - * - * @param style - */ - public void setStyle(CTStyle style) { - this.ctStyle = style; - } - - /** - * get ctStyle - * - * @return ctStyle - */ - public CTStyle getCTStyle() { - return this.ctStyle; - } - - /** - * get styles - * - * @return styles the styles to which this style belongs - */ - public XWPFStyles getStyles() { - return styles; - } - - public String getBasisStyleID() { - if (ctStyle.getBasedOn() != null) - return ctStyle.getBasedOn().getVal(); - else - return null; - } - - - /** - * get StyleID of the linked Style - */ - public String getLinkStyleID() { - if (ctStyle.getLink() != null) - return ctStyle.getLink().getVal(); - else - return null; - } - - /** - * get StyleID of the next style - */ - public String getNextStyleID() { - if (ctStyle.getNext() != null) - return ctStyle.getNext().getVal(); - else - return null; - } - - public String getName() { - if (ctStyle.isSetName()) - return ctStyle.getName().getVal(); - return null; - } - - /** - * compares the names of the Styles - * - * @param compStyle - */ - public boolean hasSameName(XWPFStyle compStyle) { - CTStyle ctCompStyle = compStyle.getCTStyle(); - String name = ctCompStyle.getName().getVal(); - return name.equals(ctStyle.getName().getVal()); - } - -}//end class diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java deleted file mode 100644 index 55e1ca475..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java +++ /dev/null @@ -1,331 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.xmlbeans.XmlException; -import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLanguage; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPrDefault; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrDefault; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument; - -/** - * Holds details of built-in, default and user styles, which - * apply to tables / paragraphs / lists etc. - * Text within one of those with custom stylings has the style - * information stored in the {@link XWPFRun} - */ -public class XWPFStyles extends POIXMLDocumentPart { - private CTStyles ctStyles; - private List listStyle = new ArrayList(); - - private XWPFLatentStyles latentStyles; - private XWPFDefaultRunStyle defaultRunStyle; - private XWPFDefaultParagraphStyle defaultParaStyle; - - /** - * Construct XWPFStyles from a package part - * - * @param part the package part holding the data of the styles, - * - * @since POI 3.14-Beta1 - */ - public XWPFStyles(PackagePart part) throws IOException, OpenXML4JException { - super(part); - } - - /** - * @deprecated in POI 3.14, scheduled for removal in POI 3.16 - */ - @Deprecated - public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { - this(part); - } - - /** - * Construct XWPFStyles from scratch for a new document. - */ - public XWPFStyles() { - } - - /** - * Read document - */ - @Override - protected void onDocumentRead() throws IOException { - StylesDocument stylesDoc; - InputStream is = getPackagePart().getInputStream(); - try { - stylesDoc = StylesDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); - setStyles(stylesDoc.getStyles()); - latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this); - } catch (XmlException e) { - throw new POIXMLException("Unable to read styles", e); - } finally { - is.close(); - } - } - - @Override - protected void commit() throws IOException { - if (ctStyles == null) { - throw new IllegalStateException("Unable to write out styles that were never read in!"); - } - - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles")); - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - ctStyles.save(out, xmlOptions); - out.close(); - } - - protected void ensureDocDefaults() { - if (!ctStyles.isSetDocDefaults()) { - ctStyles.addNewDocDefaults(); - } - - CTDocDefaults docDefaults = ctStyles.getDocDefaults(); - if (!docDefaults.isSetPPrDefault()) - docDefaults.addNewPPrDefault(); - if (!docDefaults.isSetRPrDefault()) - docDefaults.addNewRPrDefault(); - - CTPPrDefault pprd = docDefaults.getPPrDefault(); - CTRPrDefault rprd = docDefaults.getRPrDefault(); - if (!pprd.isSetPPr()) pprd.addNewPPr(); - if (!rprd.isSetRPr()) rprd.addNewRPr(); - - defaultRunStyle = new XWPFDefaultRunStyle(rprd.getRPr()); - defaultParaStyle = new XWPFDefaultParagraphStyle(pprd.getPPr()); - } - - /** - * Sets the ctStyles - * - * @param styles - */ - public void setStyles(CTStyles styles) { - ctStyles = styles; - - // Build up all the style objects - for (CTStyle style : ctStyles.getStyleArray()) { - listStyle.add(new XWPFStyle(style, this)); - } - if (ctStyles.isSetDocDefaults()) { - CTDocDefaults docDefaults = ctStyles.getDocDefaults(); - if (docDefaults.isSetRPrDefault() && docDefaults.getRPrDefault().isSetRPr()) { - defaultRunStyle = new XWPFDefaultRunStyle( - docDefaults.getRPrDefault().getRPr()); - } - if (docDefaults.isSetPPrDefault() && docDefaults.getPPrDefault().isSetPPr()) { - defaultParaStyle = new XWPFDefaultParagraphStyle( - docDefaults.getPPrDefault().getPPr()); - } - } - } - - /** - * checks whether style with styleID exist - * - * @param styleID styleID of the Style in the style-Document - * @return true if style exist, false if style not exist - */ - public boolean styleExist(String styleID) { - for (XWPFStyle style : listStyle) { - if (style.getStyleId().equals(styleID)) - return true; - } - return false; - } - - /** - * add a style to the document - * - * @param style - * @throws IOException - */ - public void addStyle(XWPFStyle style) { - listStyle.add(style); - ctStyles.addNewStyle(); - int pos = ctStyles.sizeOfStyleArray() - 1; - ctStyles.setStyleArray(pos, style.getCTStyle()); - } - - /** - * Get style by a styleID - * - * @param styleID styleID of the searched style - * @return style - */ - public XWPFStyle getStyle(String styleID) { - for (XWPFStyle style : listStyle) { - if (style.getStyleId().equals(styleID)) - return style; - } - return null; - } - - public int getNumberOfStyles() { - return listStyle.size(); - } - - /** - * get the styles which are related to the parameter style and their relatives - * this method can be used to copy all styles from one document to another document - * - * @param style - * @return a list of all styles which were used by this method - */ - public List getUsedStyleList(XWPFStyle style) { - List usedStyleList = new ArrayList(); - usedStyleList.add(style); - return getUsedStyleList(style, usedStyleList); - } - - /** - * get the styles which are related to parameter style - * - * @param style - * @return all Styles of the parameterList - */ - private List getUsedStyleList(XWPFStyle style, List usedStyleList) { - String basisStyleID = style.getBasisStyleID(); - XWPFStyle basisStyle = getStyle(basisStyleID); - if ((basisStyle != null) && (!usedStyleList.contains(basisStyle))) { - usedStyleList.add(basisStyle); - getUsedStyleList(basisStyle, usedStyleList); - } - String linkStyleID = style.getLinkStyleID(); - XWPFStyle linkStyle = getStyle(linkStyleID); - if ((linkStyle != null) && (!usedStyleList.contains(linkStyle))) { - usedStyleList.add(linkStyle); - getUsedStyleList(linkStyle, usedStyleList); - } - - String nextStyleID = style.getNextStyleID(); - XWPFStyle nextStyle = getStyle(nextStyleID); - if ((nextStyle != null) && (!usedStyleList.contains(nextStyle))) { - usedStyleList.add(linkStyle); - getUsedStyleList(linkStyle, usedStyleList); - } - return usedStyleList; - } - - protected CTLanguage getCTLanguage() { - ensureDocDefaults(); - - CTLanguage lang = null; - if (defaultRunStyle.getRPr().isSetLang()) { - lang = defaultRunStyle.getRPr().getLang(); - } else { - lang = defaultRunStyle.getRPr().addNewLang(); - } - - return lang; - } - - /** - * Sets the default spelling language on ctStyles DocDefaults parameter - * - * @param strSpellingLanguage - */ - public void setSpellingLanguage(String strSpellingLanguage) { - CTLanguage lang = getCTLanguage(); - lang.setVal(strSpellingLanguage); - lang.setBidi(strSpellingLanguage); - } - - /** - * Sets the default East Asia spelling language on ctStyles DocDefaults parameter - * - * @param strEastAsia - */ - public void setEastAsia(String strEastAsia) { - CTLanguage lang = getCTLanguage(); - lang.setEastAsia(strEastAsia); - } - - /** - * Sets the default font on ctStyles DocDefaults parameter - * TODO Replace this with specific setters for each type, possibly - * on XWPFDefaultRunStyle - */ - public void setDefaultFonts(CTFonts fonts) { - ensureDocDefaults(); - - CTRPr runProps = defaultRunStyle.getRPr(); - runProps.setRFonts(fonts); - } - - /** - * get the style with the same name - * if this style is not existing, return null - */ - public XWPFStyle getStyleWithSameName(XWPFStyle style) { - for (XWPFStyle ownStyle : listStyle) { - if (ownStyle.hasSameName(style)) { - return ownStyle; - } - } - return null; - } - - /** - * Get the default style which applies text runs in the document - */ - public XWPFDefaultRunStyle getDefaultRunStyle() { - ensureDocDefaults(); - return defaultRunStyle; - } - - /** - * Get the default paragraph style which applies to the document - */ - public XWPFDefaultParagraphStyle getDefaultParagraphStyle() { - ensureDocDefaults(); - return defaultParaStyle; - } - - /** - * Get the definition of all the Latent Styles - */ - public XWPFLatentStyles getLatentStyles() { - return latentStyles; - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java deleted file mode 100644 index 2e4bb5c80..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java +++ /dev/null @@ -1,635 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.math.BigInteger; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblCellMar; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth; - -/** - *

        Sketch of XWPFTable class. Only table's text is being hold.

        - *

        Specifies the contents of a table present in the document. A table is a set - * of paragraphs (and other block-level content) arranged in rows and columns.

        - */ -public class XWPFTable implements IBodyElement, ISDTContents { - private static EnumMap xwpfBorderTypeMap; - // Create a map from the STBorder.Enum values to the XWPF-level enums - private static HashMap stBorderTypeMap; - - static { - // populate enum maps - xwpfBorderTypeMap = new EnumMap(XWPFBorderType.class); - xwpfBorderTypeMap.put(XWPFBorderType.NIL, STBorder.Enum.forInt(STBorder.INT_NIL)); - xwpfBorderTypeMap.put(XWPFBorderType.NONE, STBorder.Enum.forInt(STBorder.INT_NONE)); - xwpfBorderTypeMap.put(XWPFBorderType.SINGLE, STBorder.Enum.forInt(STBorder.INT_SINGLE)); - xwpfBorderTypeMap.put(XWPFBorderType.THICK, STBorder.Enum.forInt(STBorder.INT_THICK)); - xwpfBorderTypeMap.put(XWPFBorderType.DOUBLE, STBorder.Enum.forInt(STBorder.INT_DOUBLE)); - xwpfBorderTypeMap.put(XWPFBorderType.DOTTED, STBorder.Enum.forInt(STBorder.INT_DOTTED)); - xwpfBorderTypeMap.put(XWPFBorderType.DASHED, STBorder.Enum.forInt(STBorder.INT_DASHED)); - xwpfBorderTypeMap.put(XWPFBorderType.DOT_DASH, STBorder.Enum.forInt(STBorder.INT_DOT_DASH)); - - stBorderTypeMap = new HashMap(); - stBorderTypeMap.put(STBorder.INT_NIL, XWPFBorderType.NIL); - stBorderTypeMap.put(STBorder.INT_NONE, XWPFBorderType.NONE); - stBorderTypeMap.put(STBorder.INT_SINGLE, XWPFBorderType.SINGLE); - stBorderTypeMap.put(STBorder.INT_THICK, XWPFBorderType.THICK); - stBorderTypeMap.put(STBorder.INT_DOUBLE, XWPFBorderType.DOUBLE); - stBorderTypeMap.put(STBorder.INT_DOTTED, XWPFBorderType.DOTTED); - stBorderTypeMap.put(STBorder.INT_DASHED, XWPFBorderType.DASHED); - stBorderTypeMap.put(STBorder.INT_DOT_DASH, XWPFBorderType.DOT_DASH); - } - - protected StringBuffer text = new StringBuffer(); - protected List tableRows; - - // Unused: UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD - //protected List styleIDs; - protected IBody part; - private CTTbl ctTbl; - - public XWPFTable(CTTbl table, IBody part, int row, int col) { - this(table, part); - - for (int i = 0; i < row; i++) { - XWPFTableRow tabRow = (getRow(i) == null) ? createRow() : getRow(i); - for (int k = 0; k < col; k++) { - if (tabRow.getCell(k) == null) { - tabRow.createCell(); - } - } - } - } - - public XWPFTable(CTTbl table, IBody part) { - this.part = part; - this.ctTbl = table; - - tableRows = new ArrayList(); - - // is an empty table: I add one row and one column as default - if (table.sizeOfTrArray() == 0) - createEmptyTable(table); - - for (CTRow row : table.getTrArray()) { - StringBuilder rowText = new StringBuilder(); - XWPFTableRow tabRow = new XWPFTableRow(row, this); - tableRows.add(tabRow); - for (CTTc cell : row.getTcArray()) { - for (CTP ctp : cell.getPArray()) { - XWPFParagraph p = new XWPFParagraph(ctp, part); - if (rowText.length() > 0) { - rowText.append('\t'); - } - rowText.append(p.getText()); - } - } - if (rowText.length() > 0) { - this.text.append(rowText); - this.text.append('\n'); - } - } - } - - private void createEmptyTable(CTTbl table) { - // MINIMUM ELEMENTS FOR A TABLE - table.addNewTr().addNewTc().addNewP(); - - CTTblPr tblpro = table.addNewTblPr(); - tblpro.addNewTblW().setW(new BigInteger("0")); - tblpro.getTblW().setType(STTblWidth.AUTO); - - // layout - // tblpro.addNewTblLayout().setType(STTblLayoutType.AUTOFIT); - - // borders - CTTblBorders borders = tblpro.addNewTblBorders(); - borders.addNewBottom().setVal(STBorder.SINGLE); - borders.addNewInsideH().setVal(STBorder.SINGLE); - borders.addNewInsideV().setVal(STBorder.SINGLE); - borders.addNewLeft().setVal(STBorder.SINGLE); - borders.addNewRight().setVal(STBorder.SINGLE); - borders.addNewTop().setVal(STBorder.SINGLE); - - /* - * CTTblGrid tblgrid=table.addNewTblGrid(); - * tblgrid.addNewGridCol().setW(new BigInteger("2000")); - */ - getRows(); - } - - /** - * @return ctTbl object - */ - @Internal - public CTTbl getCTTbl() { - return ctTbl; - } - - /** - * Convenience method to extract text in cells. This - * does not extract text recursively in cells, and it does not - * currently include text in SDT (form) components. - *

        - * To get all text within a table, see XWPFWordExtractor's appendTableText - * as an example. - * - * @return text - */ - public String getText() { - return text.toString(); - } - - public void addNewRowBetween(int start, int end) { - // TODO - } - - /** - * add a new column for each row in this table - */ - public void addNewCol() { - if (ctTbl.sizeOfTrArray() == 0) { - createRow(); - } - for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) { - XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this); - tabRow.createCell(); - } - } - - /** - * create a new XWPFTableRow object with as many cells as the number of columns defined in that moment - * - * @return tableRow - */ - public XWPFTableRow createRow() { - int sizeCol = ctTbl.sizeOfTrArray() > 0 ? ctTbl.getTrArray(0) - .sizeOfTcArray() : 0; - XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr(), this); - addColumn(tabRow, sizeCol); - tableRows.add(tabRow); - return tabRow; - } - - /** - * @param pos - index of the row - * @return the row at the position specified or null if no rows is defined or if the position is greather than the max size of rows array - */ - public XWPFTableRow getRow(int pos) { - if (pos >= 0 && pos < ctTbl.sizeOfTrArray()) { - //return new XWPFTableRow(ctTbl.getTrArray(pos)); - return getRows().get(pos); - } - return null; - } - - /** - * @return width value - */ - public int getWidth() { - CTTblPr tblPr = getTrPr(); - return tblPr.isSetTblW() ? tblPr.getTblW().getW().intValue() : -1; - } - - /** - * @param width - */ - public void setWidth(int width) { - CTTblPr tblPr = getTrPr(); - CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW(); - tblWidth.setW(new BigInteger("" + width)); - } - - /** - * @return number of rows in table - */ - public int getNumberOfRows() { - return ctTbl.sizeOfTrArray(); - } - - private CTTblPr getTrPr() { - return (ctTbl.getTblPr() != null) ? ctTbl.getTblPr() : ctTbl - .addNewTblPr(); - } - - private void addColumn(XWPFTableRow tabRow, int sizeCol) { - if (sizeCol > 0) { - for (int i = 0; i < sizeCol; i++) { - tabRow.createCell(); - } - } - } - - /** - * get the StyleID of the table - * - * @return style-ID of the table - */ - public String getStyleID() { - String styleId = null; - CTTblPr tblPr = ctTbl.getTblPr(); - if (tblPr != null) { - CTString styleStr = tblPr.getTblStyle(); - if (styleStr != null) { - styleId = styleStr.getVal(); - } - } - return styleId; - } - - /** - * Set the table style. If the style is not defined in the document, MS Word - * will set the table style to "Normal". - * - * @param styleName - the style name to apply to this table - */ - public void setStyleID(String styleName) { - CTTblPr tblPr = getTrPr(); - CTString styleStr = tblPr.getTblStyle(); - if (styleStr == null) { - styleStr = tblPr.addNewTblStyle(); - } - styleStr.setVal(styleName); - } - - public XWPFBorderType getInsideHBorderType() { - XWPFBorderType bt = null; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideH()) { - CTBorder border = ctb.getInsideH(); - bt = stBorderTypeMap.get(border.getVal().intValue()); - } - } - return bt; - } - - public int getInsideHBorderSize() { - int size = -1; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideH()) { - CTBorder border = ctb.getInsideH(); - size = border.getSz().intValue(); - } - } - return size; - } - - public int getInsideHBorderSpace() { - int space = -1; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideH()) { - CTBorder border = ctb.getInsideH(); - space = border.getSpace().intValue(); - } - } - return space; - } - - public String getInsideHBorderColor() { - String color = null; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideH()) { - CTBorder border = ctb.getInsideH(); - color = border.xgetColor().getStringValue(); - } - } - return color; - } - - public XWPFBorderType getInsideVBorderType() { - XWPFBorderType bt = null; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideV()) { - CTBorder border = ctb.getInsideV(); - bt = stBorderTypeMap.get(border.getVal().intValue()); - } - } - return bt; - } - - public int getInsideVBorderSize() { - int size = -1; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideV()) { - CTBorder border = ctb.getInsideV(); - size = border.getSz().intValue(); - } - } - return size; - } - - public int getInsideVBorderSpace() { - int space = -1; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideV()) { - CTBorder border = ctb.getInsideV(); - space = border.getSpace().intValue(); - } - } - return space; - } - - public String getInsideVBorderColor() { - String color = null; - - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblBorders()) { - CTTblBorders ctb = tblPr.getTblBorders(); - if (ctb.isSetInsideV()) { - CTBorder border = ctb.getInsideV(); - color = border.xgetColor().getStringValue(); - } - } - return color; - } - - public int getRowBandSize() { - int size = 0; - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblStyleRowBandSize()) { - CTDecimalNumber rowSize = tblPr.getTblStyleRowBandSize(); - size = rowSize.getVal().intValue(); - } - return size; - } - - public void setRowBandSize(int size) { - CTTblPr tblPr = getTrPr(); - CTDecimalNumber rowSize = tblPr.isSetTblStyleRowBandSize() ? tblPr.getTblStyleRowBandSize() : tblPr.addNewTblStyleRowBandSize(); - rowSize.setVal(BigInteger.valueOf(size)); - } - - public int getColBandSize() { - int size = 0; - CTTblPr tblPr = getTrPr(); - if (tblPr.isSetTblStyleColBandSize()) { - CTDecimalNumber colSize = tblPr.getTblStyleColBandSize(); - size = colSize.getVal().intValue(); - } - return size; - } - - public void setColBandSize(int size) { - CTTblPr tblPr = getTrPr(); - CTDecimalNumber colSize = tblPr.isSetTblStyleColBandSize() ? tblPr.getTblStyleColBandSize() : tblPr.addNewTblStyleColBandSize(); - colSize.setVal(BigInteger.valueOf(size)); - } - - public void setInsideHBorder(XWPFBorderType type, int size, int space, String rgbColor) { - CTTblPr tblPr = getTrPr(); - CTTblBorders ctb = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders(); - CTBorder b = ctb.isSetInsideH() ? ctb.getInsideH() : ctb.addNewInsideH(); - b.setVal(xwpfBorderTypeMap.get(type)); - b.setSz(BigInteger.valueOf(size)); - b.setSpace(BigInteger.valueOf(space)); - b.setColor(rgbColor); - } - - public void setInsideVBorder(XWPFBorderType type, int size, int space, String rgbColor) { - CTTblPr tblPr = getTrPr(); - CTTblBorders ctb = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders(); - CTBorder b = ctb.isSetInsideV() ? ctb.getInsideV() : ctb.addNewInsideV(); - b.setVal(xwpfBorderTypeMap.get(type)); - b.setSz(BigInteger.valueOf(size)); - b.setSpace(BigInteger.valueOf(space)); - b.setColor(rgbColor); - } - - public int getCellMarginTop() { - int margin = 0; - CTTblPr tblPr = getTrPr(); - CTTblCellMar tcm = tblPr.getTblCellMar(); - if (tcm != null) { - CTTblWidth tw = tcm.getTop(); - if (tw != null) { - margin = tw.getW().intValue(); - } - } - return margin; - } - - public int getCellMarginLeft() { - int margin = 0; - CTTblPr tblPr = getTrPr(); - CTTblCellMar tcm = tblPr.getTblCellMar(); - if (tcm != null) { - CTTblWidth tw = tcm.getLeft(); - if (tw != null) { - margin = tw.getW().intValue(); - } - } - return margin; - } - - public int getCellMarginBottom() { - int margin = 0; - CTTblPr tblPr = getTrPr(); - CTTblCellMar tcm = tblPr.getTblCellMar(); - if (tcm != null) { - CTTblWidth tw = tcm.getBottom(); - if (tw != null) { - margin = tw.getW().intValue(); - } - } - return margin; - } - - public int getCellMarginRight() { - int margin = 0; - CTTblPr tblPr = getTrPr(); - CTTblCellMar tcm = tblPr.getTblCellMar(); - if (tcm != null) { - CTTblWidth tw = tcm.getRight(); - if (tw != null) { - margin = tw.getW().intValue(); - } - } - return margin; - } - - public void setCellMargins(int top, int left, int bottom, int right) { - CTTblPr tblPr = getTrPr(); - CTTblCellMar tcm = tblPr.isSetTblCellMar() ? tblPr.getTblCellMar() : tblPr.addNewTblCellMar(); - - CTTblWidth tw = tcm.isSetLeft() ? tcm.getLeft() : tcm.addNewLeft(); - tw.setType(STTblWidth.DXA); - tw.setW(BigInteger.valueOf(left)); - - tw = tcm.isSetTop() ? tcm.getTop() : tcm.addNewTop(); - tw.setType(STTblWidth.DXA); - tw.setW(BigInteger.valueOf(top)); - - tw = tcm.isSetBottom() ? tcm.getBottom() : tcm.addNewBottom(); - tw.setType(STTblWidth.DXA); - tw.setW(BigInteger.valueOf(bottom)); - - tw = tcm.isSetRight() ? tcm.getRight() : tcm.addNewRight(); - tw.setType(STTblWidth.DXA); - tw.setW(BigInteger.valueOf(right)); - } - - /** - * add a new Row to the table - * - * @param row the row which should be added - */ - public void addRow(XWPFTableRow row) { - ctTbl.addNewTr(); - ctTbl.setTrArray(getNumberOfRows() - 1, row.getCtRow()); - tableRows.add(row); - } - - /** - * add a new Row to the table - * at position pos - * - * @param row the row which should be added - */ - public boolean addRow(XWPFTableRow row, int pos) { - if (pos >= 0 && pos <= tableRows.size()) { - ctTbl.insertNewTr(pos); - ctTbl.setTrArray(pos, row.getCtRow()); - tableRows.add(pos, row); - return true; - } - return false; - } - - /** - * inserts a new tablerow - * - * @param pos - * @return the inserted row - */ - public XWPFTableRow insertNewTableRow(int pos) { - if (pos >= 0 && pos <= tableRows.size()) { - CTRow row = ctTbl.insertNewTr(pos); - XWPFTableRow tableRow = new XWPFTableRow(row, this); - tableRows.add(pos, tableRow); - return tableRow; - } - return null; - } - - /** - * Remove a row at position pos from the table - * - * @param pos position the Row in the Table - */ - public boolean removeRow(int pos) throws IndexOutOfBoundsException { - if (pos >= 0 && pos < tableRows.size()) { - if (ctTbl.sizeOfTrArray() > 0) { - ctTbl.removeTr(pos); - } - tableRows.remove(pos); - return true; - } - return false; - } - - public List getRows() { - return tableRows; - } - - /** - * returns the type of the BodyElement Table - * - * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType() - */ - public BodyElementType getElementType() { - return BodyElementType.TABLE; - } - - public IBody getBody() { - return part; - } - - /** - * returns the part of the bodyElement - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - public POIXMLDocumentPart getPart() { - if (part != null) { - return part.getPart(); - } - return null; - } - - /** - * returns the partType of the bodyPart which owns the bodyElement - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - public BodyType getPartType() { - return part.getPartType(); - } - - /** - * returns the XWPFRow which belongs to the CTRow row - * if this row is not existing in the table null will be returned - */ - public XWPFTableRow getRow(CTRow row) { - for (int i = 0; i < getRows().size(); i++) { - if (getRows().get(i).getCtRow() == row) return getRow(i); - } - return null; - } - - // Create a map from this XWPF-level enum to the STBorder.Enum values - public static enum XWPFBorderType { - NIL, NONE, SINGLE, THICK, DOUBLE, DOTTED, DASHED, DOT_DASH - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java deleted file mode 100644 index f070b095e..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java +++ /dev/null @@ -1,518 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ArrayList; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STShd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc; - -/** - * Represents a Cell within a {@link XWPFTable}. The - * Cell is the thing that holds the actual content (paragraphs etc) - */ -public class XWPFTableCell implements IBody, ICell { - private static EnumMap alignMap; - // Create a map from the STVerticalJc.Enum values to the XWPF-level enums - private static HashMap stVertAlignTypeMap; - - static { - // populate enum maps - alignMap = new EnumMap(XWPFVertAlign.class); - alignMap.put(XWPFVertAlign.TOP, STVerticalJc.Enum.forInt(STVerticalJc.INT_TOP)); - alignMap.put(XWPFVertAlign.CENTER, STVerticalJc.Enum.forInt(STVerticalJc.INT_CENTER)); - alignMap.put(XWPFVertAlign.BOTH, STVerticalJc.Enum.forInt(STVerticalJc.INT_BOTH)); - alignMap.put(XWPFVertAlign.BOTTOM, STVerticalJc.Enum.forInt(STVerticalJc.INT_BOTTOM)); - - stVertAlignTypeMap = new HashMap(); - stVertAlignTypeMap.put(STVerticalJc.INT_TOP, XWPFVertAlign.TOP); - stVertAlignTypeMap.put(STVerticalJc.INT_CENTER, XWPFVertAlign.CENTER); - stVertAlignTypeMap.put(STVerticalJc.INT_BOTH, XWPFVertAlign.BOTH); - stVertAlignTypeMap.put(STVerticalJc.INT_BOTTOM, XWPFVertAlign.BOTTOM); - - } - - private final CTTc ctTc; - protected List paragraphs = null; - protected List tables = null; - protected List bodyElements = null; - - protected IBody part; - private XWPFTableRow tableRow = null; - - /** - * If a table cell does not include at least one block-level element, then this document shall be considered corrupt - */ - public XWPFTableCell(CTTc cell, XWPFTableRow tableRow, IBody part) { - this.ctTc = cell; - this.part = part; - this.tableRow = tableRow; - // NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt. - if (cell.sizeOfPArray() < 1) - cell.addNewP(); - bodyElements = new ArrayList(); - paragraphs = new ArrayList(); - tables = new ArrayList(); - - XmlCursor cursor = ctTc.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTP) { - XWPFParagraph p = new XWPFParagraph((CTP) o, this); - paragraphs.add(p); - bodyElements.add(p); - } - if (o instanceof CTTbl) { - XWPFTable t = new XWPFTable((CTTbl) o, this); - tables.add(t); - bodyElements.add(t); - } - if (o instanceof CTSdtBlock) { - XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this); - bodyElements.add(c); - } - if (o instanceof CTSdtRun) { - XWPFSDT c = new XWPFSDT((CTSdtRun) o, this); - System.out.println(c.getContent().getText()); - bodyElements.add(c); - } - } - cursor.dispose(); - } - - @Internal - public CTTc getCTTc() { - return ctTc; - } - - /** - * returns an Iterator with paragraphs and tables - * - * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements() - */ - public List getBodyElements() { - return Collections.unmodifiableList(bodyElements); - } - - public void setParagraph(XWPFParagraph p) { - if (ctTc.sizeOfPArray() == 0) { - ctTc.addNewP(); - } - ctTc.setPArray(0, p.getCTP()); - } - - /** - * returns a list of paragraphs - */ - public List getParagraphs() { - return paragraphs; - } - - /** - * Add a Paragraph to this Table Cell - * - * @return The paragraph which was added - */ - public XWPFParagraph addParagraph() { - XWPFParagraph p = new XWPFParagraph(ctTc.addNewP(), this); - addParagraph(p); - return p; - } - - /** - * add a Paragraph to this TableCell - * - * @param p the paragaph which has to be added - */ - public void addParagraph(XWPFParagraph p) { - paragraphs.add(p); - } - - /** - * removes a paragraph of this tablecell - * - * @param pos The position in the list of paragraphs, 0-based - */ - public void removeParagraph(int pos) { - paragraphs.remove(pos); - ctTc.removeP(pos); - } - - /** - * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this table - * the method will return this paragraph - * if there is no corresponding {@link XWPFParagraph} the method will return null - * - * @param p is instance of CTP and is searching for an XWPFParagraph - * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this table - * XWPFParagraph with the correspondig CTP p - */ - public XWPFParagraph getParagraph(CTP p) { - for (XWPFParagraph paragraph : paragraphs) { - if (p.equals(paragraph.getCTP())) { - return paragraph; - } - } - return null; - } - - public XWPFTableRow getTableRow() { - return tableRow; - } - - /** - * Get cell color. Note that this method only returns the "fill" value. - * - * @return RGB string of cell color - */ - public String getColor() { - String color = null; - CTTcPr tcpr = ctTc.getTcPr(); - if (tcpr != null) { - CTShd ctshd = tcpr.getShd(); - if (ctshd != null) { - color = ctshd.xgetFill().getStringValue(); - } - } - return color; - } - - /** - * Set cell color. This sets some associated values; for finer control - * you may want to access these elements individually. - * - * @param rgbStr - the desired cell color, in the hex form "RRGGBB". - */ - public void setColor(String rgbStr) { - CTTcPr tcpr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr(); - CTShd ctshd = tcpr.isSetShd() ? tcpr.getShd() : tcpr.addNewShd(); - ctshd.setColor("auto"); - ctshd.setVal(STShd.CLEAR); - ctshd.setFill(rgbStr); - } - - /** - * Get the vertical alignment of the cell. - * - * @return the cell alignment enum value or null - * if no vertical alignment is set. - */ - public XWPFVertAlign getVerticalAlignment() { - XWPFVertAlign vAlign = null; - CTTcPr tcpr = ctTc.getTcPr(); - if (tcpr != null) { - CTVerticalJc va = tcpr.getVAlign(); - if(va != null) { - vAlign = stVertAlignTypeMap.get(va.getVal().intValue()); - } else { - vAlign = XWPFVertAlign.TOP; - } - if (va != null && va.getVal() != null) { - vAlign = stVertAlignTypeMap.get(va.getVal().intValue()); - } - } - return vAlign; - } - - /** - * Set the vertical alignment of the cell. - * - * @param vAlign - the desired alignment enum value - */ - public void setVerticalAlignment(XWPFVertAlign vAlign) { - CTTcPr tcpr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr(); - CTVerticalJc va = tcpr.addNewVAlign(); - va.setVal(alignMap.get(vAlign)); - } - - /** - * add a new paragraph at position of the cursor - * - * @param cursor The XmlCursor structure created with XmlBeans - * @return the inserted paragraph - */ - public XWPFParagraph insertNewParagraph(final XmlCursor cursor) { - if (!isCursorInTableCell(cursor)) { - return null; - } - - String uri = CTP.type.getName().getNamespaceURI(); - String localPart = "p"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTP p = (CTP) cursor.getObject(); - XWPFParagraph newP = new XWPFParagraph(p, this); - XmlObject o = null; - while (!(o instanceof CTP) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if ((!(o instanceof CTP)) || (CTP) o == p) { - paragraphs.add(0, newP); - } else { - int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1; - paragraphs.add(pos, newP); - } - int i = 0; - XmlCursor p2 = p.newCursor(); - cursor.toCursor(p2); - p2.dispose(); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newP); - p2 = p.newCursor(); - cursor.toCursor(p2); - p2.dispose(); - cursor.toEndToken(); - return newP; - } - - public XWPFTable insertNewTbl(final XmlCursor cursor) { - if (isCursorInTableCell(cursor)) { - String uri = CTTbl.type.getName().getNamespaceURI(); - String localPart = "tbl"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTTbl t = (CTTbl) cursor.getObject(); - XWPFTable newT = new XWPFTable(t, this); - cursor.removeXmlContents(); - XmlObject o = null; - while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if (!(o instanceof CTTbl)) { - tables.add(0, newT); - } else { - int pos = tables.indexOf(getTable((CTTbl) o)) + 1; - tables.add(pos, newT); - } - int i = 0; - XmlCursor cursor2 = t.newCursor(); - while (cursor2.toPrevSibling()) { - o = cursor2.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - cursor2.dispose(); - bodyElements.add(i, newT); - cursor2 = t.newCursor(); - cursor.toCursor(cursor2); - cursor.toEndToken(); - cursor2.dispose(); - return newT; - } - return null; - } - - /** - * verifies that cursor is on the right position - */ - private boolean isCursorInTableCell(XmlCursor cursor) { - XmlCursor verify = cursor.newCursor(); - verify.toParent(); - boolean result = (verify.getObject() == this.ctTc); - verify.dispose(); - return result; - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int) - */ - public XWPFParagraph getParagraphArray(int pos) { - if (pos >= 0 && pos < paragraphs.size()) { - return paragraphs.get(pos); - } - return null; - } - - /** - * get the to which the TableCell belongs - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - public POIXMLDocumentPart getPart() { - return tableRow.getTable().getPart(); - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - public BodyType getPartType() { - return BodyType.TABLECELL; - } - - /** - * get a table by its CTTbl-Object - * - * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl) - */ - public XWPFTable getTable(CTTbl ctTable) { - for (int i = 0; i < tables.size(); i++) { - if (getTables().get(i).getCTTbl() == ctTable) return getTables().get(i); - } - return null; - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) - */ - public XWPFTable getTableArray(int pos) { - if(pos >= 0 && pos < tables.size()) { - return tables.get(pos); - } - return null; - } - - /** - * @see org.apache.poi.xwpf.usermodel.IBody#getTables() - */ - public List getTables() { - return Collections.unmodifiableList(tables); - } - - /** - * inserts an existing XWPFTable to the arrays bodyElements and tables - * - * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable) - */ - public void insertTable(int pos, XWPFTable table) { - bodyElements.add(pos, table); - int i = 0; - for (CTTbl tbl : ctTc.getTblArray()) { - if (tbl == table.getCTTbl()) { - break; - } - i++; - } - tables.add(i, table); - } - - public String getText() { - StringBuilder text = new StringBuilder(); - for (XWPFParagraph p : paragraphs) { - text.append(p.getText()); - } - return text.toString(); - } - - public void setText(String text) { - CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0); - XWPFParagraph par = new XWPFParagraph(ctP, this); - par.createRun().setText(text); - } - - /** - * extracts all text recursively through embedded tables and embedded SDTs - */ - public String getTextRecursively() { - - StringBuffer text = new StringBuffer(); - for (int i = 0; i < bodyElements.size(); i++) { - boolean isLast = (i == bodyElements.size() - 1); - appendBodyElementText(text, bodyElements.get(i), isLast); - } - - return text.toString(); - } - - private void appendBodyElementText(StringBuffer text, IBodyElement e, boolean isLast) { - if (e instanceof XWPFParagraph) { - text.append(((XWPFParagraph) e).getText()); - if (!isLast) { - text.append('\t'); - } - } else if (e instanceof XWPFTable) { - XWPFTable eTable = (XWPFTable) e; - for (XWPFTableRow row : eTable.getRows()) { - for (XWPFTableCell cell : row.getTableCells()) { - List localBodyElements = cell.getBodyElements(); - for (int i = 0; i < localBodyElements.size(); i++) { - boolean localIsLast = (i == localBodyElements.size() - 1); - appendBodyElementText(text, localBodyElements.get(i), localIsLast); - } - } - } - - if (!isLast) { - text.append('\n'); - } - } else if (e instanceof XWPFSDT) { - text.append(((XWPFSDT) e).getContent().getText()); - if (!isLast) { - text.append('\t'); - } - } - } - - /** - * get the TableCell which belongs to the TableCell - */ - public XWPFTableCell getTableCell(CTTc cell) { - XmlCursor cursor = cell.newCursor(); - cursor.toParent(); - XmlObject o = cursor.getObject(); - if (!(o instanceof CTRow)) { - return null; - } - CTRow row = (CTRow) o; - cursor.toParent(); - o = cursor.getObject(); - cursor.dispose(); - if (!(o instanceof CTTbl)) { - return null; - } - CTTbl tbl = (CTTbl) o; - XWPFTable table = getTable(tbl); - if (table == null) { - return null; - } - XWPFTableRow tr = table.getRow(row); - if (tr == null) { - return null; - } - return tr.getTableCell(cell); - } - - public XWPFDocument getXWPFDocument() { - return part.getXWPFDocument(); - } - - // Create a map from this XWPF-level enum to the STVerticalJc.Enum values - public enum XWPFVertAlign { - TOP, CENTER, BOTH, BOTTOM - } -} diff --git a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java b/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java deleted file mode 100644 index 3f530df76..000000000 --- a/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java +++ /dev/null @@ -1,266 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.Internal; -import org.apache.poi.xwpf.model.WMLHelper; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtCell; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; - - -/** - * A row within an {@link XWPFTable}. Rows mostly just have - * sizings and stylings, the interesting content lives inside - * the child {@link XWPFTableCell}s - */ -public class XWPFTableRow { - private CTRow ctRow; - private XWPFTable table; - private List tableCells; - - public XWPFTableRow(CTRow row, XWPFTable table) { - this.table = table; - this.ctRow = row; - getTableCells(); - } - - @Internal - public CTRow getCtRow() { - return ctRow; - } - - /** - * create a new XWPFTableCell and add it to the tableCell-list of this tableRow - * - * @return the newly created XWPFTableCell - */ - public XWPFTableCell createCell() { - XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getBody()); - tableCells.add(tableCell); - return tableCell; - } - - public XWPFTableCell getCell(int pos) { - if (pos >= 0 && pos < ctRow.sizeOfTcArray()) { - return getTableCells().get(pos); - } - return null; - } - - public void removeCell(int pos) { - if (pos >= 0 && pos < ctRow.sizeOfTcArray()) { - tableCells.remove(pos); - } - } - - /** - * adds a new TableCell at the end of this tableRow - */ - public XWPFTableCell addNewTableCell() { - CTTc cell = ctRow.addNewTc(); - XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getBody()); - tableCells.add(tableCell); - return tableCell; - } - - /** - * This element specifies the height of the current table row within the - * current table. This height shall be used to determine the resulting - * height of the table row, which may be absolute or relative (depending on - * its attribute values). If omitted, then the table row shall automatically - * resize its height to the height required by its contents (the equivalent - * of an hRule value of auto). - * - * @return height - */ - public int getHeight() { - CTTrPr properties = getTrPr(); - return properties.sizeOfTrHeightArray() == 0 ? 0 : properties.getTrHeightArray(0).getVal().intValue(); - } - - /** - * This element specifies the height of the current table row within the - * current table. This height shall be used to determine the resulting - * height of the table row, which may be absolute or relative (depending on - * its attribute values). If omitted, then the table row shall automatically - * resize its height to the height required by its contents (the equivalent - * of an hRule value of auto). - * - * @param height - */ - public void setHeight(int height) { - CTTrPr properties = getTrPr(); - CTHeight h = properties.sizeOfTrHeightArray() == 0 ? properties.addNewTrHeight() : properties.getTrHeightArray(0); - h.setVal(new BigInteger("" + height)); - } - - private CTTrPr getTrPr() { - return (ctRow.isSetTrPr()) ? ctRow.getTrPr() : ctRow.addNewTrPr(); - } - - public XWPFTable getTable() { - return table; - } - - /** - * create and return a list of all XWPFTableCell - * who belongs to this row - * - * @return a list of {@link XWPFTableCell} - */ - public List getTableICells() { - - List cells = new ArrayList(); - //Can't use ctRow.getTcList because that only gets table cells - //Can't use ctRow.getSdtList because that only gets sdts that are at cell level - XmlCursor cursor = ctRow.newCursor(); - cursor.selectPath("./*"); - while (cursor.toNextSelection()) { - XmlObject o = cursor.getObject(); - if (o instanceof CTTc) { - cells.add(new XWPFTableCell((CTTc) o, this, table.getBody())); - } else if (o instanceof CTSdtCell) { - cells.add(new XWPFSDTCell((CTSdtCell) o, this, table.getBody())); - } - } - cursor.dispose(); - return cells; - } - - /** - * create and return a list of all XWPFTableCell - * who belongs to this row - * - * @return a list of {@link XWPFTableCell} - */ - public List getTableCells() { - if (tableCells == null) { - List cells = new ArrayList(); - for (CTTc tableCell : ctRow.getTcArray()) { - cells.add(new XWPFTableCell(tableCell, this, table.getBody())); - } - //TODO: it is possible to have an SDT that contains a cell in within a row - //need to modify this code so that it pulls out SDT wrappers around cells, too. - - this.tableCells = cells; - } - return tableCells; - } - - /** - * returns the XWPFTableCell which belongs to the CTTC cell - * if there is no XWPFTableCell which belongs to the parameter CTTc cell null will be returned - */ - public XWPFTableCell getTableCell(CTTc cell) { - for (int i = 0; i < tableCells.size(); i++) { - if (tableCells.get(i).getCTTc() == cell) - return tableCells.get(i); - } - return null; - } - - /** - * Return true if the "can't split row" value is true. The logic for this - * attribute is a little unusual: a TRUE value means DON'T allow rows to - * split, FALSE means allow rows to split. - * - * @return true if rows can't be split, false otherwise. - */ - public boolean isCantSplitRow() { - boolean isCant = false; - if (ctRow.isSetTrPr()) { - CTTrPr trpr = getTrPr(); - if (trpr.sizeOfCantSplitArray() > 0) { - CTOnOff onoff = trpr.getCantSplitArray(0); - isCant = (onoff.isSetVal() ? WMLHelper.STOnOffToBoolean(onoff.getVal()) : true); - } - } - return isCant; - } - - /** - * Controls whether to allow this table row to split across pages. - * The logic for this attribute is a little unusual: a true value means - * DON'T allow rows to split, false means allow rows to split. - * - * @param split - if true, don't allow row to be split. If false, allow - * row to be split. - */ - public void setCantSplitRow(boolean split) { - CTTrPr trpr = getTrPr(); - CTOnOff onoff = (trpr.sizeOfCantSplitArray() > 0 ? trpr.getCantSplitArray(0) : trpr.addNewCantSplit()); - onoff.setVal(WMLHelper.BooleanToSTOnOff(split)); - } - - /** - * Return true if a table's header row should be repeated at the top of a - * table split across pages. NOTE - Word will not repeat a table row unless - * all preceding rows of the table are also repeated. This function returns - * false if the row will not be repeated even if the repeat tag is present - * for this row. - * - * @return true if table's header row should be repeated at the top of each - * page of table, false otherwise. - */ - public boolean isRepeatHeader() { - boolean repeat = false; - for (XWPFTableRow row : table.getRows()) { - repeat = row.getRepeat(); - if (row == this || !repeat) { - break; - } - } - return repeat; - } - - private boolean getRepeat() { - boolean repeat = false; - if (ctRow.isSetTrPr()) { - CTTrPr trpr = getTrPr(); - if (trpr.sizeOfTblHeaderArray() > 0) { - CTOnOff rpt = trpr.getTblHeaderArray(0); - repeat = (rpt.isSetVal() ? WMLHelper.STOnOffToBoolean(rpt.getVal()) : true); - } - } - return repeat; - } - - /** - * This attribute controls whether to repeat a table's header row at the top - * of a table split across pages. NOTE - for a row to be repeated, all preceding - * rows in the table must also be repeated. - * - * @param repeat - if TRUE, repeat header row at the top of each page of table; - * if FALSE, don't repeat header row. - */ - public void setRepeatHeader(boolean repeat) { - CTTrPr trpr = getTrPr(); - CTOnOff onoff = (trpr.sizeOfTblHeaderArray() > 0 ? trpr.getTblHeaderArray(0) : trpr.addNewTblHeader()); - onoff.setVal(WMLHelper.BooleanToSTOnOff(repeat)); - } -} diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsd b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsd deleted file mode 100644 index 7423c85de..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsd +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - A base64-encoded value that specifies the encrypted form of the intermediate key, which is encrypted with the public key contained within the X509Certificate attribute. - - - A base64-encoded value that specifies a DER-encoded X.509 certificate (1) used to encrypt the intermediate key. The certificate (1) MUST contain only the public portion of the public-private key pair. - - - A base64-encoded value that specifies the HMAC of the binary data obtained by base64-decoding the X509Certificate attribute. The hashing algorithm used to derive the HMAC MUST be the hashing algorithm specified for the Encryption.keyData element. The secret key used to derive the HMAC MUST be the intermediate key. If the intermediate key is reset, any CertificateKeyEncryptor elements are also reset to contain the new intermediate key, except that the certVerifier attribute MUST match the value calculated using the current intermediate key, to verify that the CertificateKeyEncryptor element actually encrypted the current intermediate key. If a CertificateKeyEncryptor element does not have a correct certVerifier attribute, it MUST be discarded. - - - - diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsdconfig b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsdconfig deleted file mode 100644 index 73a27fa50..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionCertificate.xsdconfig +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsd b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsd deleted file mode 100644 index 5b08560c3..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsd +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - - An unsigned integer that specifies the number of bytes used by a salt. It MUST be at least 1 and no greater than 65,536. - - - - - - - - - An unsigned integer that specifies the number of bytes used to encrypt one block of data. It MUST be at least 2, no greater than 4096, and a multiple of 2. - - - - - - - - - An unsigned integer that specifies the number of bits used by an encryption algorithm. It MUST be at least 8 and a multiple of 8. - - - - - - - - An unsigned integer that specifies the number of bytes used by a hash value. It MUST be at least 1, no greater than 65,536, and the same number of bytes as the hash algorithm emits. - - - - - - - - - An unsigned integer that specifies the number of times to iterate on a hash of a password. It MUST NOT be greater than 10,000,000. - - - - - - - - - modified for poi - list is restricted to given list in [ms-offcrypto] - A string that specifies the cipher algorithm. Values that are not defined MAY be used, and a compliant implementation is not required to support all defined values. Any algorithm that can be resolved by name by the underlying operating system can be used for hashing or encryption. Only block algorithms are supported for encryption. AES-128 is the default encryption algorithm, and SHA-1 is the default hashing algorithm if no other algorithms have been configured. - - - - - MUST conform to the AES algorithm. - - - - - MUST conform to the algorithm as specified in [RFC2268] (http://tools.ietf.org/html/rfc2268). The use of RC2 is not recommended. If RC2 is used with a key length of less than 128 bits, documents could interoperate incorrectly across different versions of Windows. - - - - - MUST NOT be used. - - - - - MUST conform to the DES algorithm. The use of DES is not recommended. If DES is used, the key length specified in the KeyBits element is required to be set to 64 for 56-bit encryption, and the key decrypted from encryptedKeyValue of KeyEncryptor is required to include the DES parity bits. - - - - - MUST conform to the algorithm as specified in [DRAFT-DESX] (http://tools.ietf.org/html/draft-ietf-ipsec-ciph-desx-00). The use of DESX is not recommended. If DESX is used, documents could interoperate incorrectly across different versions of Windows. - - - - - MUST conform to the algorithm as specified in [RFC1851] (http://tools.ietf.org/html/rfc1851). If 3DES or 3DES_112 is used, the key length specified in the KeyBits element is required to be set to 192 for 168-bit encryption and 128 for 112-bit encryption, and the key decrypted from encryptedKeyValue of KeyEncryptor is required to include the DES parity bits. - - - - - see 3DES - - - - - - - A string that specifies the chaining mode used by CipherAlgorithm. For more details about chaining modes, see [BCMO800-38A] (http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf). - - - - - block chaining (CBC) - - - - - Cipher feedback chaining (CFB), with an 8-bit window - - - - - - - modified for poi - list is restricted to given list in [ms-offcrypto] - A string specifying a hashing algorithm. Values that are not defined MAY be used, and a compliant implementation is not required to support all defined values. - - - - - MUST conform to the algorithm as specified in [RFC4634] (http://tools.ietf.org/html/rfc4634). - - - - - see SHA1 - - - - - see SHA1 - - - - - see SHA1 - - - - - MUST conform to MD5. - - - - - MUST conform to the algorithm as specified in [RFC1320] (http://tools.ietf.org/html/rfc1320). - - - - - MUST conform to the algorithm as specified in [RFC1319] (http://tools.ietf.org/html/rfc1319). - - - - - MUST conform to the hash functions specified in [ISO/IEC 10118]. (https://en.wikipedia.org/wiki/RIPEMD) - - - - - see RIPEMD-128 (https://en.wikipedia.org/wiki/RIPEMD) - - - - - see RIPEMD-128 (https://en.wikipedia.org/wiki/ISO/IEC_10118-3) - - - - - - - A complex type that specifies the encryption used within this element. The saltValue attribute is a base64-encoded binary value that is randomly generated. The number of bytes required to decode the saltValue attribute MUST be equal to the value of the saltSize attribute. - - - - - - - - - - - - - A complex type that specifies data used to verify whether the encrypted data passes an integrity check. It MUST be generated using the method specified in section 2.3.4.14 (http://msdn.microsoft.com/en-us/library/dd924068(v=office.12).aspx). - - - - A base64-encoded value that specifies an encrypted key used in calculating the encryptedHmacValue. - - - - - A base64-encoded value that specifies an HMAC derived from encryptedHmacKey and the encrypted data. - - - - - - modified for POI - A complex type that specifies the parameters used to encrypt an intermediate key, which is used to perform the final encryption of the document. To ensure extensibility, arbitrary elements can be defined to encrypt the intermediate key. The intermediate key MUST be the same for all KeyEncryptor elements. - - - - - - - - modified for POI - - - - - - - - - - - - A sequence of KeyEncryptor elements. Exactly one KeyEncryptors element MUST be present, and the KeyEncryptors element MUST contain at least one KeyEncryptor. - - - - - - - - - - - modified for POI - All ECMA-376 documents [ECMA-376] encrypted by Microsoft Office using agile encryption will have a DataIntegrity element present. The schema allows for a DataIntegrity element to not be present because the encryption schema can be used by applications that do not create ECMA-376 documents [ECMA-376]. - - - - - The KeyEncryptor element, which MUST be used when encrypting password-protected agile encryption documents, is either a PasswordKeyEncryptor or a CertificateKeyEncryptor. Exactly one PasswordKeyEncryptor MUST be present. Zero or more CertificateKeyEncryptor elements are contained within the KeyEncryptors element. - - - - - - diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsdconfig b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsdconfig deleted file mode 100644 index c9474a0f3..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionInfo.xsdconfig +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsd b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsd deleted file mode 100644 index 79ae888a0..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsd +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - A SaltSize that specifies the size of the salt for a PasswordKeyEncryptor. - - - A BlockSize that specifies the block size for a PasswordKeyEncryptor. - - - A KeyBits that specifies the number of bits for a PasswordKeyEncryptor. - - - A HashSize that specifies the size of the binary form of the hash for a PasswordKeyEncryptor. - - - A CipherAlgorithm that specifies the cipher algorithm for a PasswordKeyEncryptor. The cipher algorithm specified MUST be the same as the cipher algorithm specified for the Encryption.keyData element. - - - A CipherChaining that specifies the cipher chaining mode for a PasswordKeyEncryptor. - - - A HashAlgorithm that specifies the hashing algorithm for a PasswordKeyEncryptor. The hashing algorithm specified MUST be the same as the hashing algorithm specified for the Encryption.keyData element. - - - A base64-encoded binary byte array that specifies the salt value for a PasswordKeyEncryptor. The number of bytes required by the decoded form of this element MUST be saltSize. - - - A SpinCount that specifies the spin count for a PasswordKeyEncryptor. - - - A base64-encoded value that specifies the encrypted verifier hash input for a PasswordKeyEncryptor used in password verification. - - - A base64-encoded value that specifies the encrypted verifier hash value for a PasswordKeyEncryptor used in password verification. - - - A base64-encoded value that specifies the encrypted form of the intermediate key. - - - - diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsdconfig b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsdconfig deleted file mode 100644 index 3a2bb2c8e..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/encryptionPassword.xsdconfig +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/signatureInfo.xsd b/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/signatureInfo.xsd deleted file mode 100644 index f7019f13f..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/poifs/crypt/signatureInfo.xsd +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/trunk/src/ooxml/resources/org/apache/poi/schemas/ooxmlSchemas.xsdconfig b/trunk/src/ooxml/resources/org/apache/poi/schemas/ooxmlSchemas.xsdconfig deleted file mode 100644 index 3121e451d..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/schemas/ooxmlSchemas.xsdconfig +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - com.microsoft.schemas.office.office - - - - com.microsoft.schemas.office.excel - - - - com.microsoft.schemas.office.word - - - - com.microsoft.schemas.office.powerpoint - - - - com.microsoft.schemas.vml - - - \ No newline at end of file diff --git a/trunk/src/ooxml/resources/org/apache/poi/xdgf/visio.xsd b/trunk/src/ooxml/resources/org/apache/poi/xdgf/visio.xsd deleted file mode 100644 index eec0b68c0..000000000 --- a/trunk/src/ooxml/resources/org/apache/poi/xdgf/visio.xsd +++ /dev/null @@ -1,829 +0,0 @@ - - - - - - - - Permission to copy, display and distribute the contents of this document (the - "Specification"), in any medium for any purpose without fee or royalty is - hereby granted, provided that you include the following notice on ALL copies of - the Specification, or portions thereof, that you make: - Copyright (c) Microsoft Corporation. All rights reserved. Permission to copy, - display and distribute this document is available at: - http://msdn.microsoft.com/library/en-us/odcXMLRef/html/odcXMLRefLegalNotice.asp?frame=true. - No right to create modifications or derivatives of this Specification is - granted herein. There is a separate patent license available to parties - interested in implementing software programs that can read and write files that - conform to the Specification. This patent license is available at this - location: http://www.microsoft.com/mscorp/ip/format/xmlpatentlicense.asp. - THE SPECIFICATION IS PROVIDED "AS IS" AND MICROSOFT MAKES NO REPRESENTATIONS OR - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; - THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT - THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. MICROSOFT WILL NOT BE LIABLE FOR ANY - DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF - OR RELATING TO ANY USE OR DISTRIBUTION OF THE SPECIFICATION. - The name and trademarks of Microsoft may NOT be used in any manner, including - advertising or publicity pertaining to the Specification or its contents - without specific, written prior permission. Title to copyright in the - Specification will at all times remain with Microsoft. No other rights are - granted by implication, estoppel or otherwise. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java b/trunk/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java deleted file mode 100644 index 137f631b5..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/TestDetectAsOOXML.java +++ /dev/null @@ -1,87 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.util.Arrays; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; - -/** - * Class to test that HXF correctly detects OOXML - * documents - */ -public class TestDetectAsOOXML extends TestCase -{ - public void testOpensProperly() throws Exception - { - OPCPackage.open(HSSFTestDataSamples.openSampleFileStream("sample.xlsx")); - } - - public void testDetectAsPOIFS() throws Exception { - InputStream in; - - // ooxml file is - in = new PushbackInputStream( - HSSFTestDataSamples.openSampleFileStream("SampleSS.xlsx"), 10 - ); - assertTrue(DocumentFactoryHelper.hasOOXMLHeader(in)); - in.close(); - - // xls file isn't - in = new PushbackInputStream( - HSSFTestDataSamples.openSampleFileStream("SampleSS.xls"), 10 - ); - assertFalse(DocumentFactoryHelper.hasOOXMLHeader(in)); - in.close(); - - // text file isn't - in = new PushbackInputStream( - HSSFTestDataSamples.openSampleFileStream("SampleSS.txt"), 10 - ); - assertFalse(DocumentFactoryHelper.hasOOXMLHeader(in)); - in.close(); - } - - public void testFileCorruption() throws Exception { - - // create test InputStream - byte[] testData = { (byte)1, (byte)2, (byte)3 }; - ByteArrayInputStream testInput = new ByteArrayInputStream(testData); - - // detect header - InputStream in = new PushbackInputStream(testInput, 10); - assertFalse(DocumentFactoryHelper.hasOOXMLHeader(in)); - //noinspection deprecation - assertFalse(POIXMLDocument.hasOOXMLHeader(in)); - - // check if InputStream is still intact - byte[] test = new byte[3]; - assertEquals(3, in.read(test)); - assertTrue(Arrays.equals(testData, test)); - assertEquals(-1, in.read()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/TestEmbeded.java b/trunk/src/ooxml/testcases/org/apache/poi/TestEmbeded.java deleted file mode 100644 index fb16b8a0e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/TestEmbeded.java +++ /dev/null @@ -1,70 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util.IOUtils; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; - -import junit.framework.TestCase; - -/** - * Class to test that we handle embeded bits in - * OOXML files properly - */ -public class TestEmbeded extends TestCase -{ - public void testExcel() throws Exception { - POIXMLDocument doc = new XSSFWorkbook( - POIDataSamples.getSpreadSheetInstance().openResourceAsStream("ExcelWithAttachments.xlsm") - ); - test(doc, 4); - } - - public void testWord() throws Exception { - POIXMLDocument doc = new XWPFDocument( - POIDataSamples.getDocumentInstance().openResourceAsStream("WordWithAttachments.docx") - ); - test(doc, 5); - } - - public void testPowerPoint() throws Exception { - POIXMLDocument doc = new XSLFSlideShow(OPCPackage.open( - POIDataSamples.getSlideShowInstance().openResourceAsStream("PPTWithAttachments.pptm")) - ); - test(doc, 4); - } - - private void test(POIXMLDocument doc, int expectedCount) throws Exception { - assertNotNull(doc.getAllEmbedds()); - assertEquals(expectedCount, doc.getAllEmbedds().size()); - - for(int i=0; i 0); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java b/trunk/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java deleted file mode 100644 index be63e2bf7..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java +++ /dev/null @@ -1,353 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.util.NullOutputStream; -import org.apache.poi.util.PackageHelper; -import org.apache.poi.util.TempFile; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.poi.xwpf.usermodel.XWPFRelation; -import org.junit.Test; - -/** - * Test recursive read and write of OPC packages - */ -public final class TestPOIXMLDocument { - - private static class OPCParser extends POIXMLDocument { - - public OPCParser(OPCPackage pkg) { - super(pkg); - } - - public OPCParser(OPCPackage pkg, String coreDocumentRel) { - super(pkg, coreDocumentRel); - } - - @Override - public List getAllEmbedds() { - throw new RuntimeException("not supported"); - } - - public void parse(POIXMLFactory factory) throws IOException{ - load(factory); - } - } - - private static final class TestFactory extends POIXMLFactory { - - public TestFactory() { - // - } - - @Override - protected POIXMLRelation getDescriptor(String relationshipType) { - return null; - } - - /** - * @since POI 3.14-Beta1 - */ - @Override - protected POIXMLDocumentPart createDocumentPart - (Class cls, Class[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - return null; - } - } - - /** - * Recursively traverse a OOXML document and assert that same logical parts have the same physical instances - */ - private static void traverse(POIXMLDocumentPart part, HashMap context) throws IOException{ - assertEquals(part.getPackageRelationship().getTargetURI().toString(), part.getPackagePart().getPartName().getName()); - - context.put(part.getPackagePart().getPartName().getName(), part); - for(POIXMLDocumentPart p : part.getRelations()){ - assertNotNull(p.toString()); - - String uri = p.getPackagePart().getPartName().getURI().toString(); - assertEquals(uri, p.getPackageRelationship().getTargetURI().toString()); - if (!context.containsKey(uri)) { - traverse(p, context); - } else { - POIXMLDocumentPart prev = context.get(uri); - assertSame("Duplicate POIXMLDocumentPart instance for targetURI=" + uri, prev, p); - } - } - } - - public void assertReadWrite(OPCPackage pkg1) throws Exception { - - OPCParser doc = new OPCParser(pkg1); - doc.parse(new TestFactory()); - - HashMap context = new HashMap(); - traverse(doc, context); - context.clear(); - - File tmp = TempFile.createTempFile("poi-ooxml", ".tmp"); - FileOutputStream out = new FileOutputStream(tmp); - doc.write(out); - out.close(); - - // Should not be able to write to an output stream that has been closed - try { - doc.write(out); - fail("Should not be able to write to an output stream that has been closed."); - } catch (final OpenXML4JRuntimeException e) { - // FIXME: A better exception class (IOException?) and message should be raised - // indicating that the document could not be written because the output stream is closed. - // see {@link org.apache.poi.openxml4j.opc.ZipPackage#saveImpl(java.io.OutputStream)} - if (e.getMessage().matches("Fail to save: an error occurs while saving the package : The part .+ fail to be saved in the stream with marshaller .+")) { - // expected - } else { - throw e; - } - } - - // Should not be able to write a document that has been closed - doc.close(); - try { - doc.write(new NullOutputStream()); - fail("Should not be able to write a document that has been closed."); - } catch (final IOException e) { - if (e.getMessage().equals("Cannot write data, document seems to have been closed already")) { - // expected - } else { - throw e; - } - } - - // Should be able to close a document multiple times, though subsequent closes will have no effect. - doc.close(); - - - @SuppressWarnings("resource") - OPCPackage pkg2 = OPCPackage.open(tmp.getAbsolutePath()); - doc = new OPCParser(pkg1); - try { - doc.parse(new TestFactory()); - context = new HashMap(); - traverse(doc, context); - context.clear(); - - assertEquals(pkg1.getRelationships().size(), pkg2.getRelationships().size()); - - ArrayList l1 = pkg1.getParts(); - ArrayList l2 = pkg2.getParts(); - - assertEquals(l1.size(), l2.size()); - for (int i=0; i < l1.size(); i++){ - PackagePart p1 = l1.get(i); - PackagePart p2 = l2.get(i); - - assertEquals(p1.getContentType(), p2.getContentType()); - assertEquals(p1.hasRelationships(), p2.hasRelationships()); - if(p1.hasRelationships()){ - assertEquals(p1.getRelationships().size(), p2.getRelationships().size()); - } - assertEquals(p1.getPartName(), p2.getPartName()); - } - } finally { - doc.close(); - pkg1.close(); - pkg2.close(); - } - } - - @Test - public void testPPTX() throws Exception { - POIDataSamples pds = POIDataSamples.getSlideShowInstance(); - assertReadWrite(PackageHelper.open(pds.openResourceAsStream("PPTWithAttachments.pptm"))); - } - - @Test - public void testXLSX() throws Exception { - POIDataSamples pds = POIDataSamples.getSpreadSheetInstance(); - assertReadWrite(PackageHelper.open(pds.openResourceAsStream("ExcelWithAttachments.xlsm"))); - } - - @Test - public void testDOCX() throws Exception { - POIDataSamples pds = POIDataSamples.getDocumentInstance(); - assertReadWrite(PackageHelper.open(pds.openResourceAsStream("WordWithAttachments.docx"))); - } - - @Test - public void testRelationOrder() throws Exception { - POIDataSamples pds = POIDataSamples.getDocumentInstance(); - @SuppressWarnings("resource") - OPCPackage pkg = PackageHelper.open(pds.openResourceAsStream("WordWithAttachments.docx")); - OPCParser doc = new OPCParser(pkg); - try { - doc.parse(new TestFactory()); - - for(POIXMLDocumentPart rel : doc.getRelations()){ - //TODO finish me - assertNotNull(rel); - } - } finally { - doc.close(); - } - } - - @Test - public void testGetNextPartNumber() throws Exception { - POIDataSamples pds = POIDataSamples.getDocumentInstance(); - @SuppressWarnings("resource") - OPCPackage pkg = PackageHelper.open(pds.openResourceAsStream("WordWithAttachments.docx")); - OPCParser doc = new OPCParser(pkg); - try { - doc.parse(new TestFactory()); - - // Non-indexed parts: Word is taken, Excel is not - assertEquals(-1, doc.getNextPartNumber(XWPFRelation.DOCUMENT, 0)); - assertEquals(-1, doc.getNextPartNumber(XWPFRelation.DOCUMENT, -1)); - assertEquals(-1, doc.getNextPartNumber(XWPFRelation.DOCUMENT, 99)); - assertEquals(0, doc.getNextPartNumber(XSSFRelation.WORKBOOK, 0)); - assertEquals(0, doc.getNextPartNumber(XSSFRelation.WORKBOOK, -1)); - assertEquals(0, doc.getNextPartNumber(XSSFRelation.WORKBOOK, 99)); - - // Indexed parts: - // Has 2 headers - assertEquals(0, doc.getNextPartNumber(XWPFRelation.HEADER, 0)); - assertEquals(3, doc.getNextPartNumber(XWPFRelation.HEADER, -1)); - assertEquals(3, doc.getNextPartNumber(XWPFRelation.HEADER, 1)); - assertEquals(8, doc.getNextPartNumber(XWPFRelation.HEADER, 8)); - - // Has no Excel Sheets - assertEquals(0, doc.getNextPartNumber(XSSFRelation.WORKSHEET, 0)); - assertEquals(1, doc.getNextPartNumber(XSSFRelation.WORKSHEET, -1)); - assertEquals(1, doc.getNextPartNumber(XSSFRelation.WORKSHEET, 1)); - } finally { - doc.close(); - } - } - - @Test - public void testCommitNullPart() throws IOException, InvalidFormatException { - POIXMLDocumentPart part = new POIXMLDocumentPart(); - part.prepareForCommit(); - part.commit(); - part.onSave(new HashSet()); - - assertNull(part.getRelationById(null)); - assertNull(part.getRelationId(null)); - assertFalse(part.removeRelation(null, true)); - part.removeRelation(null); - assertEquals("",part.toString()); - part.onDocumentCreate(); - //part.getTargetPart(null); - } - - @Test - public void testVSDX() throws Exception { - POIDataSamples pds = POIDataSamples.getDiagramInstance(); - @SuppressWarnings("resource") - OPCPackage open = PackageHelper.open(pds.openResourceAsStream("test.vsdx")); - POIXMLDocument part = new OPCParser(open, PackageRelationshipTypes.VISIO_CORE_DOCUMENT); - - assertNotNull(part); - assertEquals(0, part.getRelationCounter()); - part.close(); - } - - @Test - public void testVSDXPart() throws IOException { - POIDataSamples pds = POIDataSamples.getDiagramInstance(); - OPCPackage open = PackageHelper.open(pds.openResourceAsStream("test.vsdx")); - - POIXMLDocumentPart part = new POIXMLDocumentPart(open, PackageRelationshipTypes.VISIO_CORE_DOCUMENT); - - assertNotNull(part); - assertEquals(0, part.getRelationCounter()); - - open.close(); - } - - @Test(expected=POIXMLException.class) - public void testInvalidCoreRel() throws IOException { - POIDataSamples pds = POIDataSamples.getDiagramInstance(); - OPCPackage open = PackageHelper.open(pds.openResourceAsStream("test.vsdx")); - - try { - new POIXMLDocumentPart(open, "somethingillegal"); - } finally { - open.close(); - } - } - - @Test(expected=IllegalStateException.class) - public void testOSGIClassLoadingAsIs() throws IOException { - Thread thread = Thread.currentThread(); - ClassLoader cl = thread.getContextClassLoader(); - InputStream is = POIDataSamples.getSlideShowInstance().openResourceAsStream("table_test.pptx"); - try { - thread.setContextClassLoader(cl.getParent()); - XMLSlideShow ppt = new XMLSlideShow(is); - ppt.getSlides().get(0).getShapes(); - } finally { - thread.setContextClassLoader(cl); - is.close(); - } - } - - - @Test - public void testOSGIClassLoadingFixed() throws IOException { - Thread thread = Thread.currentThread(); - ClassLoader cl = thread.getContextClassLoader(); - InputStream is = POIDataSamples.getSlideShowInstance().openResourceAsStream("table_test.pptx"); - try { - thread.setContextClassLoader(cl.getParent()); - POIXMLTypeLoader.setClassLoader(cl); - XMLSlideShow ppt = new XMLSlideShow(is); - ppt.getSlides().get(0).getShapes(); - } finally { - thread.setContextClassLoader(cl); - POIXMLTypeLoader.setClassLoader(null); - is.close(); - } - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java b/trunk/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java deleted file mode 100644 index 86732836a..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java +++ /dev/null @@ -1,268 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.POIXMLProperties.CoreProperties; -import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Test setting extended and custom OOXML properties - */ -public final class TestPOIXMLProperties { - private XWPFDocument sampleDoc; - private XWPFDocument sampleNoThumb; - private POIXMLProperties _props; - private CoreProperties _coreProperties; - - @Before - public void setUp() throws IOException { - sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx"); - sampleNoThumb = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); - assertNotNull(sampleDoc); - assertNotNull(sampleNoThumb); - _props = sampleDoc.getProperties(); - _coreProperties = _props.getCoreProperties(); - assertNotNull(_props); - } - - @After - public void closeResources() throws Exception { - sampleDoc.close(); - sampleNoThumb.close(); - } - - @Test - public void testWorkbookExtendedProperties() throws Exception { - XSSFWorkbook workbook = new XSSFWorkbook(); - POIXMLProperties props = workbook.getProperties(); - assertNotNull(props); - - org.apache.poi.POIXMLProperties.ExtendedProperties properties = - props.getExtendedProperties(); - - org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties - ctProps = properties.getUnderlyingProperties(); - - - String appVersion = "3.5 beta"; - String application = "POI"; - - ctProps.setApplication(application); - ctProps.setAppVersion(appVersion); - - XSSFWorkbook newWorkbook = - XSSFTestDataSamples.writeOutAndReadBack(workbook); - workbook.close(); - assertTrue(workbook != newWorkbook); - - - POIXMLProperties newProps = newWorkbook.getProperties(); - assertNotNull(newProps); - org.apache.poi.POIXMLProperties.ExtendedProperties newProperties = - newProps.getExtendedProperties(); - - assertEquals(application, newProperties.getApplication()); - assertEquals(appVersion, newProperties.getAppVersion()); - - org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties - newCtProps = newProperties.getUnderlyingProperties(); - - assertEquals(application, newCtProps.getApplication()); - assertEquals(appVersion, newCtProps.getAppVersion()); - - newWorkbook.close(); - } - - - /** - * Test usermodel API for setting custom properties - */ - @Test - public void testCustomProperties() throws Exception { - POIXMLDocument wb1 = new XSSFWorkbook(); - - POIXMLProperties.CustomProperties customProps = wb1.getProperties().getCustomProperties(); - customProps.addProperty("test-1", "string val"); - customProps.addProperty("test-2", 1974); - customProps.addProperty("test-3", 36.6); - //adding a duplicate - try { - customProps.addProperty("test-3", 36.6); - fail("expected exception"); - } catch(IllegalArgumentException e){ - assertEquals("A property with this name already exists in the custom properties", e.getMessage()); - } - customProps.addProperty("test-4", true); - - POIXMLDocument wb2 = XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)wb1); - wb1.close(); - org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties ctProps = - wb2.getProperties().getCustomProperties().getUnderlyingProperties(); - assertEquals(4, ctProps.sizeOfPropertyArray()); - org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty p; - - p = ctProps.getPropertyArray(0); - assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid()); - assertEquals("test-1", p.getName()); - assertEquals("string val", p.getLpwstr()); - assertEquals(2, p.getPid()); - - p = ctProps.getPropertyArray(1); - assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid()); - assertEquals("test-2", p.getName()); - assertEquals(1974, p.getI4()); - assertEquals(3, p.getPid()); - - p = ctProps.getPropertyArray(2); - assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid()); - assertEquals("test-3", p.getName()); - assertEquals(36.6, p.getR8(), 0); - assertEquals(4, p.getPid()); - - p = ctProps.getPropertyArray(3); - assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid()); - assertEquals("test-4", p.getName()); - assertEquals(true, p.getBool()); - assertEquals(5, p.getPid()); - - wb2.close(); - } - - @Test - public void testDocumentProperties() { - String category = _coreProperties.getCategory(); - assertEquals("test", category); - String contentStatus = "Draft"; - _coreProperties.setContentStatus(contentStatus); - assertEquals("Draft", contentStatus); - Date created = _coreProperties.getCreated(); - // the original file contains a following value: 2009-07-20T13:12:00Z - assertTrue(dateTimeEqualToUTCString(created, "2009-07-20T13:12:00Z")); - String creator = _coreProperties.getCreator(); - assertEquals("Paolo Mottadelli", creator); - String subject = _coreProperties.getSubject(); - assertEquals("Greetings", subject); - String title = _coreProperties.getTitle(); - assertEquals("Hello World", title); - } - - @Test - public void testTransitiveSetters() throws IOException { - XWPFDocument doc = new XWPFDocument(); - CoreProperties cp = doc.getProperties().getCoreProperties(); - - - Date dateCreated = LocaleUtil.getLocaleCalendar(2010, 6, 15, 10, 0, 0).getTime(); - cp.setCreated(new Nullable(dateCreated)); - assertEquals(dateCreated, cp.getCreated()); - - XWPFDocument doc2 = XWPFTestDataSamples.writeOutAndReadBack(doc); - doc.close(); - cp = doc2.getProperties().getCoreProperties(); - Date dt3 = cp.getCreated(); - assertEquals(dateCreated, dt3); - doc2.close(); - } - - @Test - public void testGetSetRevision() { - String revision = _coreProperties.getRevision(); - assertTrue("Revision number is 1", Integer.parseInt(revision) > 1); - _coreProperties.setRevision("20"); - assertEquals("20", _coreProperties.getRevision()); - _coreProperties.setRevision("20xx"); - assertEquals("20", _coreProperties.getRevision()); - } - - @Test - public void testLastModifiedByUserProperty() { - String lastModifiedByUser = _coreProperties.getLastModifiedByUser(); - assertEquals("Paolo Mottadelli", lastModifiedByUser); - _coreProperties.setLastModifiedByUser("Test User"); - assertEquals("Test User", _coreProperties.getLastModifiedByUser()); - } - - public static boolean dateTimeEqualToUTCString(Date dateTime, String utcString) { - Calendar utcCalendar = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); - utcCalendar.setTimeInMillis(dateTime.getTime()); - String dateTimeUtcString = utcCalendar.get(Calendar.YEAR) + "-" + - zeroPad((utcCalendar.get(Calendar.MONTH)+1)) + "-" + - zeroPad(utcCalendar.get(Calendar.DAY_OF_MONTH)) + "T" + - zeroPad(utcCalendar.get(Calendar.HOUR_OF_DAY)) + ":" + - zeroPad(utcCalendar.get(Calendar.MINUTE)) + ":" + - zeroPad(utcCalendar.get(Calendar.SECOND)) + "Z"; - - return utcString.equals(dateTimeUtcString); - } - - public void testThumbnails() throws Exception { - POIXMLProperties noThumbProps = sampleNoThumb.getProperties(); - - assertNotNull(_props.getThumbnailPart()); - assertNull(noThumbProps.getThumbnailPart()); - - assertNotNull(_props.getThumbnailFilename()); - assertNull(noThumbProps.getThumbnailFilename()); - - assertNotNull(_props.getThumbnailImage()); - assertNull(noThumbProps.getThumbnailImage()); - - assertEquals("thumbnail.jpeg", _props.getThumbnailFilename()); - - - // Adding / changing - noThumbProps.setThumbnail("Testing.png", new ByteArrayInputStream(new byte[1])); - assertNotNull(noThumbProps.getThumbnailPart()); - assertEquals("Testing.png", noThumbProps.getThumbnailFilename()); - assertNotNull(noThumbProps.getThumbnailImage()); - assertEquals(1, noThumbProps.getThumbnailImage().available()); - - noThumbProps.setThumbnail("Testing2.png", new ByteArrayInputStream(new byte[2])); - assertNotNull(noThumbProps.getThumbnailPart()); - assertEquals("Testing.png", noThumbProps.getThumbnailFilename()); - assertNotNull(noThumbProps.getThumbnailImage()); - assertEquals(2, noThumbProps.getThumbnailImage().available()); - } - - private static String zeroPad(long i) { - if (i >= 0 && i <=9) { - return "0" + i; - } else { - return String.valueOf(i); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/TestXMLPropertiesTextExtractor.java b/trunk/src/ooxml/testcases/org/apache/poi/TestXMLPropertiesTextExtractor.java deleted file mode 100644 index 9ba1333c3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/TestXMLPropertiesTextExtractor.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.util.PackageHelper; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.poi.xssf.extractor.XSSFExcelExtractor; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public final class TestXMLPropertiesTextExtractor extends TestCase { - private static final POIDataSamples _ssSamples = POIDataSamples.getSpreadSheetInstance(); - private static final POIDataSamples _slSamples = POIDataSamples.getSlideShowInstance(); - - public void testGetFromMainExtractor() throws Exception { - OPCPackage pkg = PackageHelper.open(_ssSamples.openResourceAsStream("ExcelWithAttachments.xlsm")); - - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - XSSFExcelExtractor ext = new XSSFExcelExtractor(wb); - POIXMLPropertiesTextExtractor textExt = ext.getMetadataTextExtractor(); - - // Check basics - assertNotNull(textExt); - assertTrue(textExt.getText().length() > 0); - - // Check some of the content - String text = textExt.getText(); - String cText = textExt.getCorePropertiesText(); - - assertTrue(text.contains("LastModifiedBy = Yury Batrakov")); - assertTrue(cText.contains("LastModifiedBy = Yury Batrakov")); - - textExt.close(); - ext.close(); - } - - public void testCore() throws Exception { - OPCPackage pkg = PackageHelper.open( - _ssSamples.openResourceAsStream("ExcelWithAttachments.xlsm") - ); - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - POIXMLPropertiesTextExtractor ext = new POIXMLPropertiesTextExtractor(wb); - ext.getText(); - - // Now check - String text = ext.getText(); - String cText = ext.getCorePropertiesText(); - - assertTrue(text.contains("LastModifiedBy = Yury Batrakov")); - assertTrue(cText.contains("LastModifiedBy = Yury Batrakov")); - - ext.close(); - } - - public void testExtended() throws Exception { - OPCPackage pkg = OPCPackage.open( - _ssSamples.openResourceAsStream("ExcelWithAttachments.xlsm") - ); - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - POIXMLPropertiesTextExtractor ext = new POIXMLPropertiesTextExtractor(wb); - ext.getText(); - - // Now check - String text = ext.getText(); - String eText = ext.getExtendedPropertiesText(); - - assertTrue(text.contains("Application = Microsoft Excel")); - assertTrue(text.contains("Company = Mera")); - assertTrue(eText.contains("Application = Microsoft Excel")); - assertTrue(eText.contains("Company = Mera")); - - ext.close(); - } - - public void testCustom() throws Exception { - OPCPackage pkg = OPCPackage.open( - _ssSamples.openResourceAsStream("ExcelWithAttachments.xlsm") - ); - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - POIXMLPropertiesTextExtractor ext = new POIXMLPropertiesTextExtractor(wb); - ext.getText(); - - // Now check - String text = ext.getText(); - String cText = ext.getCustomPropertiesText(); - - assertTrue(text.contains("description = another value")); - assertTrue(cText.contains("description = another value")); - - ext.close(); - } - - /** - * Bug #49386 - some properties, especially - * dates can be null - */ - public void testWithSomeNulls() throws Exception { - OPCPackage pkg = OPCPackage.open( - _slSamples.openResourceAsStream("49386-null_dates.pptx") - ); - XSLFSlideShow sl = new XSLFSlideShow(pkg); - - POIXMLPropertiesTextExtractor ext = new POIXMLPropertiesTextExtractor(sl); - ext.getText(); - - String text = ext.getText(); - assertFalse(text.contains("Created =")); // With date is null - assertTrue(text.contains("CreatedString = ")); // Via string is blank - assertTrue(text.contains("LastModifiedBy = IT Client Services")); - - ext.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java b/trunk/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java deleted file mode 100644 index 0d7bc5a8a..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java +++ /dev/null @@ -1,1039 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.extractor; - -import static org.apache.poi.POITestCase.assertContains; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.POITextExtractor; -import org.apache.poi.POIXMLException; -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.UnsupportedFileFormatException; -import org.apache.poi.hdgf.extractor.VisioTextExtractor; -import org.apache.poi.hpbf.extractor.PublisherTextExtractor; -import org.apache.poi.hslf.extractor.PowerPointExtractor; -import org.apache.poi.hsmf.extractor.OutlookTextExtactor; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.hssf.extractor.EventBasedExcelExtractor; -import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.hwpf.extractor.Word6Extractor; -import org.apache.poi.hwpf.extractor.WordExtractor; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xdgf.extractor.XDGFVisioExtractor; -import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor; -import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; -import org.apache.poi.xssf.extractor.XSSFExcelExtractor; -import org.apache.poi.xwpf.extractor.XWPFWordExtractor; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Test that the extractor factory plays nicely - */ -public class TestExtractorFactory { - private static File txt; - - private static File xls; - private static File xlsx; - private static File xlsxStrict; - private static File xltx; - private static File xlsEmb; - - private static File doc; - private static File doc6; - private static File doc95; - private static File docx; - private static File dotx; - private static File docEmb; - private static File docEmbOOXML; - - private static File ppt; - private static File pptx; - - private static File msg; - private static File msgEmb; - private static File msgEmbMsg; - - private static File vsd; - private static File vsdx; - - private static File pub; - - private static File getFileAndCheck(POIDataSamples samples, String name) { - File file = samples.getFile(name); - - assertNotNull("Did not get a file for " + name, file); - assertTrue("Did not get a type file for " + name, file.isFile()); - assertTrue("File did not exist: " + name, file.exists()); - - return file; - } - - @BeforeClass - public static void setUp() throws Exception { - - POIDataSamples ssTests = POIDataSamples.getSpreadSheetInstance(); - xls = getFileAndCheck(ssTests, "SampleSS.xls"); - xlsx = getFileAndCheck(ssTests, "SampleSS.xlsx"); - xlsxStrict = getFileAndCheck(ssTests, "SampleSS.strict.xlsx"); - xltx = getFileAndCheck(ssTests, "test.xltx"); - xlsEmb = getFileAndCheck(ssTests, "excel_with_embeded.xls"); - - POIDataSamples wpTests = POIDataSamples.getDocumentInstance(); - doc = getFileAndCheck(wpTests, "SampleDoc.doc"); - doc6 = getFileAndCheck(wpTests, "Word6.doc"); - doc95 = getFileAndCheck(wpTests, "Word95.doc"); - docx = getFileAndCheck(wpTests, "SampleDoc.docx"); - dotx = getFileAndCheck(wpTests, "test.dotx"); - docEmb = getFileAndCheck(wpTests, "word_with_embeded.doc"); - docEmbOOXML = getFileAndCheck(wpTests, "word_with_embeded_ooxml.doc"); - - POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); - ppt = getFileAndCheck(slTests, "SampleShow.ppt"); - pptx = getFileAndCheck(slTests, "SampleShow.pptx"); - txt = getFileAndCheck(slTests, "SampleShow.txt"); - - POIDataSamples dgTests = POIDataSamples.getDiagramInstance(); - vsd = getFileAndCheck(dgTests, "Test_Visio-Some_Random_Text.vsd"); - vsdx = getFileAndCheck(dgTests, "test.vsdx"); - - POIDataSamples pubTests = POIDataSamples.getPublisherInstance(); - pub = getFileAndCheck(pubTests, "Simple.pub"); - - POIDataSamples olTests = POIDataSamples.getHSMFInstance(); - msg = getFileAndCheck(olTests, "quick.msg"); - msgEmb = getFileAndCheck(olTests, "attachment_test_msg.msg"); - msgEmbMsg = getFileAndCheck(olTests, "attachment_msg_pdf.msg"); - } - - @Test - public void testFile() throws Exception { - // Excel - POITextExtractor xlsExtractor = ExtractorFactory.createExtractor(xls); - assertNotNull("Had empty extractor for " + xls, xlsExtractor); - assertTrue("Expected instanceof ExcelExtractor, but had: " + xlsExtractor.getClass(), - xlsExtractor - instanceof ExcelExtractor - ); - assertTrue( - xlsExtractor.getText().length() > 200 - ); - xlsExtractor.close(); - - POITextExtractor extractor = ExtractorFactory.createExtractor(xlsx); - assertTrue( - extractor.getClass().getName(), - extractor - instanceof XSSFExcelExtractor - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(xlsx); - assertTrue( - extractor.getText().length() > 200 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(xltx); - assertTrue( - extractor.getClass().getName(), - extractor - instanceof XSSFExcelExtractor - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(xltx); - assertTrue( - extractor.getText().contains("test") - ); - extractor.close(); - - // TODO Support OOXML-Strict, see bug #57699 - try { - /*extractor =*/ ExtractorFactory.createExtractor(xlsxStrict); - fail("OOXML-Strict isn't yet supported"); - } catch (POIXMLException e) { - // Expected, for now - } -// extractor = ExtractorFactory.createExtractor(xlsxStrict); -// assertTrue( -// extractor -// instanceof XSSFExcelExtractor -// ); -// extractor.close(); -// -// extractor = ExtractorFactory.createExtractor(xlsxStrict); -// assertTrue( -// extractor.getText().contains("test") -// ); -// extractor.close(); - - - // Word - extractor = ExtractorFactory.createExtractor(doc); - assertTrue( - extractor - instanceof WordExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(doc6); - assertTrue( - extractor - instanceof Word6Extractor - ); - assertTrue( - extractor.getText().length() > 20 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(doc95); - assertTrue( - extractor - instanceof Word6Extractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(docx); - assertTrue( - extractor instanceof XWPFWordExtractor - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(docx); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(dotx); - assertTrue( - extractor instanceof XWPFWordExtractor - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(dotx); - assertTrue( - extractor.getText().contains("Test") - ); - extractor.close(); - - // PowerPoint (PPT) - extractor = ExtractorFactory.createExtractor(ppt); - assertTrue( - extractor - instanceof PowerPointExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - // PowerPoint (PPTX) - extractor = ExtractorFactory.createExtractor(pptx); - assertTrue( - extractor - instanceof XSLFPowerPointExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - // Visio - binary - extractor = ExtractorFactory.createExtractor(vsd); - assertTrue( - extractor - instanceof VisioTextExtractor - ); - assertTrue( - extractor.getText().length() > 50 - ); - extractor.close(); - - // Visio - vsdx - extractor = ExtractorFactory.createExtractor(vsdx); - assertTrue( - extractor - instanceof XDGFVisioExtractor - ); - assertTrue( - extractor.getText().length() > 20 - ); - extractor.close(); - - // Publisher - extractor = ExtractorFactory.createExtractor(pub); - assertTrue( - extractor - instanceof PublisherTextExtractor - ); - assertTrue( - extractor.getText().length() > 50 - ); - extractor.close(); - - // Outlook msg - extractor = ExtractorFactory.createExtractor(msg); - assertTrue( - extractor - instanceof OutlookTextExtactor - ); - assertTrue( - extractor.getText().length() > 50 - ); - extractor.close(); - - // Text - try { - ExtractorFactory.createExtractor(txt); - fail(); - } catch(IllegalArgumentException e) { - // Good - } - } - - @Test - public void testInputStream() throws Exception { - // Excel - POITextExtractor extractor = ExtractorFactory.createExtractor(new FileInputStream(xls)); - assertTrue( - extractor - instanceof ExcelExtractor - ); - assertTrue( - extractor.getText().length() > 200 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(new FileInputStream(xlsx)); - assertTrue( - extractor.getClass().getName(), - extractor - instanceof XSSFExcelExtractor - ); - assertTrue( - extractor.getText().length() > 200 - ); - // TODO Support OOXML-Strict, see bug #57699 -// assertTrue( -// ExtractorFactory.createExtractor(new FileInputStream(xlsxStrict)) -// instanceof XSSFExcelExtractor -// ); -// assertTrue( -// ExtractorFactory.createExtractor(new FileInputStream(xlsxStrict)).getText().length() > 200 -// ); - extractor.close(); - - // Word - extractor = ExtractorFactory.createExtractor(new FileInputStream(doc)); - assertTrue( - extractor.getClass().getName(), - extractor - instanceof WordExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(new FileInputStream(doc6)); - assertTrue( - extractor.getClass().getName(), - extractor - instanceof Word6Extractor - ); - assertTrue( - extractor.getText().length() > 20 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(new FileInputStream(doc95)); - assertTrue( - extractor.getClass().getName(), - extractor - instanceof Word6Extractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(new FileInputStream(docx)); - assertTrue( - extractor - instanceof XWPFWordExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - // PowerPoint - extractor = ExtractorFactory.createExtractor(new FileInputStream(ppt)); - assertTrue( - extractor - instanceof PowerPointExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(new FileInputStream(pptx)); - assertTrue( - extractor - instanceof XSLFPowerPointExtractor - ); - assertTrue( - extractor.getText().length() > 120 - ); - extractor.close(); - - // Visio - extractor = ExtractorFactory.createExtractor(new FileInputStream(vsd)); - assertTrue( - extractor - instanceof VisioTextExtractor - ); - assertTrue( - extractor.getText().length() > 50 - ); - extractor.close(); - - // Visio - vsdx - extractor = ExtractorFactory.createExtractor(new FileInputStream(vsdx)); - assertTrue( - extractor - instanceof XDGFVisioExtractor - ); - assertTrue( - extractor.getText().length() > 20 - ); - extractor.close(); - - // Publisher - extractor = ExtractorFactory.createExtractor(new FileInputStream(pub)); - assertTrue( - extractor - instanceof PublisherTextExtractor - ); - assertTrue( - extractor.getText().length() > 50 - ); - extractor.close(); - - // Outlook msg - extractor = ExtractorFactory.createExtractor(new FileInputStream(msg)); - assertTrue( - extractor - instanceof OutlookTextExtactor - ); - assertTrue( - extractor.getText().length() > 50 - ); - extractor.close(); - - // Text - try { - FileInputStream stream = new FileInputStream(txt); - try { - ExtractorFactory.createExtractor(stream); - fail(); - } finally { - IOUtils.closeQuietly(stream); - } - } catch(IllegalArgumentException e) { - // Good - } - } - - @Test - public void testPOIFS() throws Exception { - // Excel - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))) - instanceof ExcelExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))).getText().length() > 200 - ); - - // Word - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc))) - instanceof WordExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc))).getText().length() > 120 - ); - - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc6))) - instanceof Word6Extractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc6))).getText().length() > 20 - ); - - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc95))) - instanceof Word6Extractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc95))).getText().length() > 120 - ); - - // PowerPoint - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(ppt))) - instanceof PowerPointExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(ppt))).getText().length() > 120 - ); - - // Visio - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(vsd))) - instanceof VisioTextExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(vsd))).getText().length() > 50 - ); - - // Publisher - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(pub))) - instanceof PublisherTextExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(pub))).getText().length() > 50 - ); - - // Outlook msg - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(msg))) - instanceof OutlookTextExtactor - ); - assertTrue( - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(msg))).getText().length() > 50 - ); - - // Text - try { - ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(txt))); - fail(); - } catch(IOException e) { - // Good - } - } - - - @Test - public void testOPOIFS() throws Exception { - // Excel - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(xls))) - instanceof ExcelExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(xls))).getText().length() > 200 - ); - - // Word - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(doc))) - instanceof WordExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(doc))).getText().length() > 120 - ); - - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(doc6))) - instanceof Word6Extractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(doc6))).getText().length() > 20 - ); - - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(doc95))) - instanceof Word6Extractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(doc95))).getText().length() > 120 - ); - - // PowerPoint - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(ppt))) - instanceof PowerPointExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(ppt))).getText().length() > 120 - ); - - // Visio - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(vsd))) - instanceof VisioTextExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(vsd))).getText().length() > 50 - ); - - // Publisher - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(pub))) - instanceof PublisherTextExtractor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(pub))).getText().length() > 50 - ); - - // Outlook msg - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(msg))) - instanceof OutlookTextExtactor - ); - assertTrue( - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(msg))).getText().length() > 50 - ); - - // Text - try { - ExtractorFactory.createExtractor(new OPOIFSFileSystem(new FileInputStream(txt))); - fail(); - } catch(IOException e) { - // Good - } - } - - @Test - public void testPackage() throws Exception { - // Excel - POIXMLTextExtractor extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ)); - assertTrue(extractor instanceof XSSFExcelExtractor); - extractor.close(); - extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString())); - assertTrue(extractor.getText().length() > 200); - extractor.close(); - - // Word - extractor = ExtractorFactory.createExtractor(OPCPackage.open(docx.toString())); - assertTrue(extractor instanceof XWPFWordExtractor); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(OPCPackage.open(docx.toString())); - assertTrue(extractor.getText().length() > 120); - extractor.close(); - - // PowerPoint - extractor = ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString())); - assertTrue(extractor instanceof XSLFPowerPointExtractor); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString())); - assertTrue(extractor.getText().length() > 120); - extractor.close(); - - // Visio - extractor = ExtractorFactory.createExtractor(OPCPackage.open(vsdx.toString())); - assertTrue(extractor instanceof XDGFVisioExtractor); - assertTrue(extractor.getText().length() > 20); - extractor.close(); - - // Text - try { - ExtractorFactory.createExtractor(OPCPackage.open(txt.toString())); - fail("TestExtractorFactory.testPackage() failed on " + txt); - } catch(UnsupportedFileFormatException e) { - // Good - } catch (Exception e) { - System.out.println("TestExtractorFactory.testPackage() failed on " + txt); - throw e; - } - } - - @Test - public void testPreferEventBased() throws Exception { - assertFalse(ExtractorFactory.getPreferEventExtractor()); - assertFalse(ExtractorFactory.getThreadPrefersEventExtractors()); - assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors()); - - ExtractorFactory.setThreadPrefersEventExtractors(true); - - assertTrue(ExtractorFactory.getPreferEventExtractor()); - assertTrue(ExtractorFactory.getThreadPrefersEventExtractors()); - assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors()); - - ExtractorFactory.setAllThreadsPreferEventExtractors(false); - - assertFalse(ExtractorFactory.getPreferEventExtractor()); - assertTrue(ExtractorFactory.getThreadPrefersEventExtractors()); - assertEquals(Boolean.FALSE, ExtractorFactory.getAllThreadsPreferEventExtractors()); - - ExtractorFactory.setAllThreadsPreferEventExtractors(null); - - assertTrue(ExtractorFactory.getPreferEventExtractor()); - assertTrue(ExtractorFactory.getThreadPrefersEventExtractors()); - assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors()); - - - // Check we get the right extractors now - POITextExtractor extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))); - assertTrue( - extractor - instanceof EventBasedExcelExtractor - ); - extractor.close(); - extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))); - assertTrue( - extractor.getText().length() > 200 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ)); - assertTrue(extractor instanceof XSSFEventBasedExcelExtractor); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ)); - assertTrue( - extractor.getText().length() > 200 - ); - extractor.close(); - - - // Put back to normal - ExtractorFactory.setThreadPrefersEventExtractors(false); - assertFalse(ExtractorFactory.getPreferEventExtractor()); - assertFalse(ExtractorFactory.getThreadPrefersEventExtractors()); - assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors()); - - // And back - extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))); - assertTrue( - extractor - instanceof ExcelExtractor - ); - extractor.close(); - extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))); - assertTrue( - extractor.getText().length() > 200 - ); - extractor.close(); - - extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ)); - assertTrue( - extractor - instanceof XSSFExcelExtractor - ); - extractor.close(); - extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString())); - assertTrue( - extractor.getText().length() > 200 - ); - extractor.close(); - } - - /** - * Test embeded docs text extraction. For now, only - * does poifs embeded, but will do ooxml ones - * at some point. - */ - @Test - public void testEmbeded() throws Exception { - POIOLE2TextExtractor ext; - POITextExtractor[] embeds; - - // No embedings - ext = (POIOLE2TextExtractor) - ExtractorFactory.createExtractor(xls); - embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext); - assertEquals(0, embeds.length); - ext.close(); - - // Excel - ext = (POIOLE2TextExtractor) - ExtractorFactory.createExtractor(xlsEmb); - embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext); - - assertEquals(6, embeds.length); - int numWord = 0, numXls = 0, numPpt = 0, numMsg = 0, numWordX; - for (POITextExtractor embed : embeds) { - assertTrue(embed.getText().length() > 20); - - if (embed instanceof PowerPointExtractor) numPpt++; - else if (embed instanceof ExcelExtractor) numXls++; - else if (embed instanceof WordExtractor) numWord++; - else if (embed instanceof OutlookTextExtactor) numMsg++; - } - assertEquals(2, numPpt); - assertEquals(2, numXls); - assertEquals(2, numWord); - assertEquals(0, numMsg); - ext.close(); - - // Word - ext = (POIOLE2TextExtractor) - ExtractorFactory.createExtractor(docEmb); - embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext); - - numWord = 0; numXls = 0; numPpt = 0; numMsg = 0; - assertEquals(4, embeds.length); - for (POITextExtractor embed : embeds) { - assertTrue(embed.getText().length() > 20); - if (embed instanceof PowerPointExtractor) numPpt++; - else if (embed instanceof ExcelExtractor) numXls++; - else if (embed instanceof WordExtractor) numWord++; - else if (embed instanceof OutlookTextExtactor) numMsg++; - } - assertEquals(1, numPpt); - assertEquals(2, numXls); - assertEquals(1, numWord); - assertEquals(0, numMsg); - ext.close(); - - // Word which contains an OOXML file - ext = (POIOLE2TextExtractor) - ExtractorFactory.createExtractor(docEmbOOXML); - embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext); - - numWord = 0; numXls = 0; numPpt = 0; numMsg = 0; numWordX = 0; - assertEquals(3, embeds.length); - for (POITextExtractor embed : embeds) { - assertTrue(embed.getText().length() > 20); - if (embed instanceof PowerPointExtractor) numPpt++; - else if (embed instanceof ExcelExtractor) numXls++; - else if (embed instanceof WordExtractor) numWord++; - else if (embed instanceof OutlookTextExtactor) numMsg++; - else if (embed instanceof XWPFWordExtractor) numWordX++; - } - assertEquals(1, numPpt); - assertEquals(1, numXls); - assertEquals(0, numWord); - assertEquals(1, numWordX); - assertEquals(0, numMsg); - ext.close(); - - // Outlook - ext = (OutlookTextExtactor) - ExtractorFactory.createExtractor(msgEmb); - embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext); - - numWord = 0; numXls = 0; numPpt = 0; numMsg = 0; - assertEquals(1, embeds.length); - for (POITextExtractor embed : embeds) { - assertTrue(embed.getText().length() > 20); - if (embed instanceof PowerPointExtractor) numPpt++; - else if (embed instanceof ExcelExtractor) numXls++; - else if (embed instanceof WordExtractor) numWord++; - else if (embed instanceof OutlookTextExtactor) numMsg++; - } - assertEquals(0, numPpt); - assertEquals(0, numXls); - assertEquals(1, numWord); - assertEquals(0, numMsg); - ext.close(); - - // Outlook with another outlook file in it - ext = (OutlookTextExtactor) - ExtractorFactory.createExtractor(msgEmbMsg); - embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext); - - numWord = 0; numXls = 0; numPpt = 0; numMsg = 0; - assertEquals(1, embeds.length); - for (POITextExtractor embed : embeds) { - assertTrue(embed.getText().length() > 20); - if (embed instanceof PowerPointExtractor) numPpt++; - else if (embed instanceof ExcelExtractor) numXls++; - else if (embed instanceof WordExtractor) numWord++; - else if (embed instanceof OutlookTextExtactor) numMsg++; - } - assertEquals(0, numPpt); - assertEquals(0, numXls); - assertEquals(0, numWord); - assertEquals(1, numMsg); - ext.close(); - - // TODO - PowerPoint - // TODO - Publisher - // TODO - Visio - } - - private static final String[] EXPECTED_FAILURES = new String[] { - // password protected files - "spreadsheet/password.xls", - "spreadsheet/protected_passtika.xlsx", - "spreadsheet/51832.xls", - "document/PasswordProtected.doc", - "slideshow/Password_Protected-hello.ppt", - "slideshow/Password_Protected-56-hello.ppt", - "slideshow/Password_Protected-np-hello.ppt", - "slideshow/cryptoapi-proc2356.ppt", - //"document/bug53475-password-is-pass.docx", - //"document/bug53475-password-is-solrcell.docx", - "spreadsheet/xor-encryption-abc.xls", - "spreadsheet/35897-type4.xls", - //"poifs/protect.xlsx", - //"poifs/protected_sha512.xlsx", - //"poifs/extenxls_pwd123.xlsx", - //"poifs/protected_agile.docx", - "spreadsheet/58616.xlsx", - - // TODO: fails XMLExportTest, is this ok? - "spreadsheet/CustomXMLMapping-singleattributenamespace.xlsx", - "spreadsheet/55864.xlsx", - "spreadsheet/57890.xlsx", - - // TODO: these fail now with some NPE/file read error because we now try to compute every value via Cell.toString()! - "spreadsheet/44958.xls", - "spreadsheet/44958_1.xls", - "spreadsheet/testArraysAndTables.xls", - - // TODO: good to ignore? - "spreadsheet/sample-beta.xlsx", - - // This is actually a spreadsheet! - "hpsf/TestRobert_Flaherty.doc", - - // some files that are broken, eg Word 95, ... - "spreadsheet/43493.xls", - "spreadsheet/46904.xls", - "document/Bug50955.doc", - "slideshow/PPT95.ppt", - "openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx", - "openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx", - "openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_NotPresentFAIL.docx", - "openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx", - "openxml4j/OPCCompliance_CoreProperties_OnlyOneCorePropertiesPartFAIL.docx", - "openxml4j/OPCCompliance_CoreProperties_UnauthorizedXMLLangAttributeFAIL.docx", - "openxml4j/OPCCompliance_DerivedPartNameFAIL.docx", - "openxml4j/invalid.xlsx", - "spreadsheet/54764-2.xlsx", // see TestXSSFBugs.bug54764() - "spreadsheet/54764.xlsx", // see TestXSSFBugs.bug54764() - "spreadsheet/Simple.xlsb", - "poifs/unknown_properties.msg", // POIFS properties corrupted - "poifs/only-zero-byte-streams.ole2", // No actual contents - "spreadsheet/poc-xmlbomb.xlsx", // contains xml-entity-expansion - "spreadsheet/poc-shared-strings.xlsx", // contains shared-string-entity-expansion - - // old Excel files, which we only support simple text extraction of - "spreadsheet/testEXCEL_2.xls", - "spreadsheet/testEXCEL_3.xls", - "spreadsheet/testEXCEL_4.xls", - "spreadsheet/testEXCEL_5.xls", - "spreadsheet/testEXCEL_95.xls", - - // OOXML Strict is not yet supported, see bug #57699 - "spreadsheet/SampleSS.strict.xlsx", - "spreadsheet/SimpleStrict.xlsx", - "spreadsheet/sample.strict.xlsx", - - // non-TNEF files - "ddf/Container.dat", - "ddf/47143.dat", - - // sheet cloning errors - "spreadsheet/47813.xlsx", - "spreadsheet/56450.xls", - "spreadsheet/57231_MixedGasReport.xls", - "spreadsheet/OddStyleRecord.xls", - "spreadsheet/WithChartSheet.xlsx", - "spreadsheet/chart_sheet.xlsx", - }; - - @Test - public void testFileLeak() throws Exception { - // run a number of files that might fail in order to catch - // leaked file resources when using file-leak-detector while - // running the test - - for(String file : EXPECTED_FAILURES) { - try { - ExtractorFactory.createExtractor(POIDataSamples.getSpreadSheetInstance().getFile(file)); - } catch (Exception e) { - // catch all exceptions here as we are only interested in file-handle leaks - } - } - } - - /** - * #59074 - Excel 95 files should give a helpful message, not just - * "No supported documents found in the OLE2 stream" - */ - @Test - public void bug59074() throws Exception { - try { - ExtractorFactory.createExtractor( - POIDataSamples.getSpreadSheetInstance().getFile("59074.xls")); - fail("Old excel formats not supported via ExtractorFactory"); - } catch (OldExcelFormatException e) { - // expected here - } - } - - @Test - public void testGetEmbeddedFromXMLExtractor() { - try { - // currently not implemented - ExtractorFactory.getEmbededDocsTextExtractors((POIXMLTextExtractor)null); - fail("Unsupported currently"); - } catch (IllegalStateException e) { - // expected here - } - } - - // This bug is currently open. This test will fail with "expected error not thrown" when the bug has been fixed. - // When this happens, change this from @Test(expected=...) to @Test - // bug 45565: text within TextBoxes is extracted by ExcelExtractor and WordExtractor - @Test(expected=AssertionError.class) - public void test45565() throws Exception { - POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("45565.xls")); - try { - String text = extractor.getText(); - assertContains(text, "testdoc"); - assertContains(text, "test phrase"); - } finally { - extractor.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java deleted file mode 100644 index 1c6b942a5..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.util.TempFile; - -import java.io.File; -import java.io.InputStream; -import java.io.IOException; - -/** - * Centralises logic for finding/opening sample files for ooxml4j unit tests - */ -public final class OpenXML4JTestDataSamples { - private static final POIDataSamples _samples = POIDataSamples.getOpenXML4JInstance(); - - private OpenXML4JTestDataSamples() { - // no instances of this class - } - - public static InputStream openSampleStream(String sampleFileName) { - return _samples.openResourceAsStream(sampleFileName); - } - public static String getSampleFileName(String sampleFileName) { - return getSampleFile(sampleFileName).getAbsolutePath(); - } - - public static File getSampleFile(String sampleFileName) { - return _samples.getFile(sampleFileName); - } - - public static File getOutputFile(String outputFileName) throws IOException { - String suffix = outputFileName.substring(outputFileName.lastIndexOf('.')); - return TempFile.createTempFile(outputFileName, suffix); - } - - - public static InputStream openComplianceSampleStream(String sampleFileName) { - return _samples.openResourceAsStream(sampleFileName); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java deleted file mode 100644 index 7b98afd97..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TestContentType.class - , TestFileHelper.class - , TestListParts.class - , TestPackage.class - , TestPackageCoreProperties.class - , TestPackagePartName.class - , TestPackageThumbnail.class - , TestPackagingURIHelper.class - , TestRelationships.class -}) -public final class AllOpenXML4JTests { -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestContentType.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestContentType.java deleted file mode 100644 index 91187ceb9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestContentType.java +++ /dev/null @@ -1,242 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.internal.ContentType; -import org.apache.poi.xwpf.usermodel.XWPFRelation; - -/** - * Tests for content type (ContentType class). - * - * @author Julien Chable - */ -public final class TestContentType extends TestCase { - - /** - * Check 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, \u00A73.7. - */ - public void testContentTypeValidation() throws InvalidFormatException { - String[] contentTypesToTest = new String[] { "text/xml", - "application/pgp-key", "application/vnd.hp-PCLXL", - "application/vnd.lotus-1-2-3" }; - for (String contentType : contentTypesToTest) { - new ContentType(contentType); - } - } - - /** - * Check 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, \u00A3.7. - * - * Check 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. - */ - public void testContentTypeValidationFailure() { - String[] contentTypesToTest = new String[] { "text/xml/app", "", - "test", "text(xml/xml", "text)xml/xml", "text/xml", "text@/xml", "text,/xml", "text;/xml", - "text:/xml", "text\\/xml", "t/ext/xml", "t\"ext/xml", - "text[/xml", "text]/xml", "text?/xml", "tex=t/xml", - "te{xt/xml", "tex}t/xml", "te xt/xml", - "text" + (char) 9 + "/xml", "text xml", " text/xml " }; - for (String contentType : contentTypesToTest) { - try { - new ContentType(contentType); - } catch (InvalidFormatException e) { - continue; - } - fail("Must have fail for content type: '" + contentType + "' !"); - } - } - - /** - * Parameters are allowed, provides that they meet the - * criteria of rule [01.2] - * Invalid parameters are verified as incorrect in - * {@link #testContentTypeParameterFailure()} - */ - public void testContentTypeParam() throws InvalidFormatException { - String[] contentTypesToTest = new String[] { "mail/toto;titi=tata", - "text/xml;a=b;c=d", "text/xml;key1=param1;key2=param2", - "application/pgp-key;version=\"2\"", - "application/x-resqml+xml;version=2.0;type=obj_global2dCrs" - }; - for (String contentType : contentTypesToTest) { - new ContentType(contentType); - } - } - - /** - * Check rule [O1.2]: Format designers might restrict the usage of - * parameters for content types. - */ - public void testContentTypeParameterFailure() { - String[] contentTypesToTest = new String[] { - "mail/toto;\"titi=tata\"", // quotes not allowed like that - "mail/toto;titi = tata", // spaces not allowed - "text/\u0080" // characters above ASCII are not allowed - }; - for (String contentType : contentTypesToTest) { - try { - new ContentType(contentType); - } catch (InvalidFormatException e) { - continue; - } - fail("Must have fail for content type: '" + contentType + "' !"); - } - } - - /** - * Check 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. - */ - public void testContentTypeCommentFailure() { - String[] contentTypesToTest = new String[] { "text/xml(comment)" }; - for (String contentType : contentTypesToTest) { - try { - new ContentType(contentType); - } catch (InvalidFormatException e) { - continue; - } - fail("Must have fail for content type: '" + contentType + "' !"); - } - } - - /** - * OOXML content types don't need entities, but we shouldn't - * barf if we get one from a third party system that added them - */ - public void testFileWithContentTypeEntities() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("ContentTypeHasEntities.ooxml"); - OPCPackage p = OPCPackage.open(is); - - // Check we found the contents of it - boolean foundCoreProps = false, foundDocument = false, foundTheme1 = false; - for (PackagePart part : p.getParts()) { - if (part.getPartName().toString().equals("/docProps/core.xml")) { - assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType()); - foundCoreProps = true; - } - if (part.getPartName().toString().equals("/word/document.xml")) { - assertEquals(XWPFRelation.DOCUMENT.getContentType(), part.getContentType()); - foundDocument = true; - } - if (part.getPartName().toString().equals("/word/theme/theme1.xml")) { - assertEquals(XWPFRelation.THEME.getContentType(), part.getContentType()); - foundTheme1 = true; - } - } - assertTrue("Core not found in " + p.getParts(), foundCoreProps); - assertTrue("Document not found in " + p.getParts(), foundDocument); - assertTrue("Theme1 not found in " + p.getParts(), foundTheme1); - } - - /** - * Check that we can open a file where there are valid - * parameters on a content type - */ - public void testFileWithContentTypeParams() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("ContentTypeHasParameters.ooxml"); - - OPCPackage p = OPCPackage.open(is); - - final String typeResqml = "application/x-resqml+xml"; - - // Check the types on everything - for (PackagePart part : p.getParts()) { - final String contentType = part.getContentType(); - final ContentType details = part.getContentTypeDetails(); - final int length = details.getParameterKeys().length; - final boolean hasParameters = details.hasParameters(); - - // _rels type doesn't have any params - if (part.isRelationshipPart()) { - assertEquals(ContentTypes.RELATIONSHIPS_PART, contentType); - assertEquals(ContentTypes.RELATIONSHIPS_PART, details.toString()); - assertEquals(false, hasParameters); - assertEquals(0, length); - } - // Core type doesn't have any params - else if (part.getPartName().toString().equals("/docProps/core.xml")) { - assertEquals(ContentTypes.CORE_PROPERTIES_PART, contentType); - assertEquals(ContentTypes.CORE_PROPERTIES_PART, details.toString()); - assertEquals(false, hasParameters); - assertEquals(0, length); - } - // Global Crs types do have params - else if (part.getPartName().toString().equals("/global1dCrs.xml")) { - assertTrue(part.getContentType().startsWith(typeResqml)); - assertEquals(typeResqml, details.toString(false)); - assertEquals(true, hasParameters); - assertContains("version=2.0", details.toString()); - assertContains("type=obj_global1dCrs", details.toString()); - assertEquals(2, length); - assertEquals("2.0", details.getParameter("version")); - assertEquals("obj_global1dCrs", details.getParameter("type")); - } - else if (part.getPartName().toString().equals("/global2dCrs.xml")) { - assertTrue(part.getContentType().startsWith(typeResqml)); - assertEquals(typeResqml, details.toString(false)); - assertEquals(true, hasParameters); - assertContains("version=2.0", details.toString()); - assertContains("type=obj_global2dCrs", details.toString()); - assertEquals(2, length); - assertEquals("2.0", details.getParameter("version")); - assertEquals("obj_global2dCrs", details.getParameter("type")); - } - // Other thingy - else if (part.getPartName().toString().equals("/myTestingGuid.xml")) { - assertTrue(part.getContentType().startsWith(typeResqml)); - assertEquals(typeResqml, details.toString(false)); - assertEquals(true, hasParameters); - assertContains("version=2.0", details.toString()); - assertContains("type=obj_tectonicBoundaryFeature", details.toString()); - assertEquals(2, length); - assertEquals("2.0", details.getParameter("version")); - assertEquals("obj_tectonicBoundaryFeature", details.getParameter("type")); - } - // That should be it! - else { - fail("Unexpected part " + part); - } - } - } - - private static void assertContains(String needle, String haystack) { - assertTrue(haystack.contains(needle)); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestFileHelper.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestFileHelper.java deleted file mode 100644 index 72dc40cee..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestFileHelper.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertTrue; - -import java.io.File; -import java.util.TreeMap; - -import org.apache.poi.openxml4j.opc.internal.FileHelper; -import org.junit.Test; - -/** - * Test TestFileHelper class. - * - * @author Julien Chable - */ -public final class TestFileHelper { - - /** - * TODO - use simple JDK methods on {@link File} instead:
        - * {@link File#getParentFile()} instead of {@link FileHelper#getDirectory(File) - * {@link File#getName()} instead of {@link FileHelper#getFilename(File) - */ - @Test - public void testGetDirectory() { - TreeMap expectedValue = new TreeMap(); - expectedValue.put("/dir1/test.doc", "/dir1"); - expectedValue.put("/dir1/dir2/test.doc.xml", "/dir1/dir2"); - - for (String filename : expectedValue.keySet()) { - File f1 = new File(expectedValue.get(filename)); - File f2 = FileHelper.getDirectory(new File(filename)); - -// if (false) { -// // YK: The original version asserted expected values against File#getAbsolutePath(): -// assertTrue(expectedValue.get(filename).equalsIgnoreCase(f2.getAbsolutePath())); -// // This comparison is platform dependent. A better approach is below -// } - assertTrue(f1.equals(f2)); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestListParts.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestListParts.java deleted file mode 100644 index 78294e353..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestListParts.java +++ /dev/null @@ -1,104 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.IOException; -import java.io.InputStream; -import java.util.TreeMap; - -import junit.framework.TestCase; - -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.POILogFactory; - -public final class TestListParts extends TestCase { - private static final POILogger logger = POILogFactory.getLogger(TestListParts.class); - - private TreeMap expectedValues; - - private TreeMap values; - - @Override - protected void setUp() throws Exception { - values = new TreeMap(); - - // Expected values - expectedValues = new TreeMap(); - expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"), - "application/vnd.openxmlformats-package.relationships+xml"); - - expectedValues - .put(PackagingURIHelper.createPartName("/docProps/app.xml"), - "application/vnd.openxmlformats-officedocument.extended-properties+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/docProps/core.xml"), - "application/vnd.openxmlformats-package.core-properties+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/word/_rels/document.xml.rels"), - "application/vnd.openxmlformats-package.relationships+xml"); - expectedValues - .put( - PackagingURIHelper.createPartName("/word/document.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); - expectedValues - .put(PackagingURIHelper.createPartName("/word/fontTable.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/word/media/image1.gif"), "image/gif"); - expectedValues - .put(PackagingURIHelper.createPartName("/word/settings.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"); - expectedValues - .put(PackagingURIHelper.createPartName("/word/styles.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/word/theme/theme1.xml"), - "application/vnd.openxmlformats-officedocument.theme+xml"); - expectedValues - .put( - PackagingURIHelper - .createPartName("/word/webSettings.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"); - } - - /** - * List all parts of a package. - */ - public void testListParts() throws InvalidFormatException { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.docx"); - - OPCPackage p; - try { - p = OPCPackage.open(is); - } catch (IOException e) { - throw new RuntimeException(e); - } - for (PackagePart part : p.getParts()) { - values.put(part.getPartName(), part.getContentType()); - logger.log(POILogger.DEBUG, part.getPartName()); - } - - // Compare expected values with values return by the package - for (PackagePartName partName : expectedValues.keySet()) { - assertNotNull(values.get(partName)); - assertEquals(expectedValues.get(partName), values.get(partName)); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java deleted file mode 100644 index 5f83bc52d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ /dev/null @@ -1,964 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.TreeMap; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.POIDataSamples; -import org.apache.poi.POITestCase; -import org.apache.poi.POIXMLException; -import org.apache.poi.UnsupportedFileFormatException; -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException; -import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; -import org.apache.poi.openxml4j.opc.internal.FileHelper; -import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; -import org.apache.poi.openxml4j.opc.internal.ZipHelper; -import org.apache.poi.openxml4j.util.ZipSecureFile; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; -import org.junit.Ignore; -import org.junit.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -public final class TestPackage { - private static final POILogger logger = POILogFactory.getLogger(TestPackage.class); - - /** - * Test that just opening and closing the file doesn't alter the document. - */ - @Test - public void openSave() throws IOException, InvalidFormatException { - String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx"); - File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx"); - - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(originalFile, PackageAccess.READ_WRITE); - try { - p.save(targetFile.getAbsoluteFile()); - - // Compare the original and newly saved document - assertTrue(targetFile.exists()); - ZipFileAssert.assertEquals(new File(originalFile), targetFile); - assertTrue(targetFile.delete()); - } finally { - // use revert to not re-write the input file - p.revert(); - } - } - - /** - * Test that when we create a new Package, we give it - * the correct default content types - * @throws IllegalAccessException - * @throws NoSuchFieldException - * @throws IllegalArgumentException - * @throws SecurityException - */ - @Test - public void createGetsContentTypes() - throws IOException, InvalidFormatException, SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException { - File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx"); - - // Zap the target file, in case of an earlier run - if(targetFile.exists()) { - assertTrue(targetFile.delete()); - } - - @SuppressWarnings("resource") - OPCPackage pkg = OPCPackage.create(targetFile); - - // Check it has content types for rels and xml - ContentTypeManager ctm = getContentTypeManager(pkg); - assertEquals( - "application/xml", - ctm.getContentType( - PackagingURIHelper.createPartName("/foo.xml") - ) - ); - assertEquals( - ContentTypes.RELATIONSHIPS_PART, - ctm.getContentType( - PackagingURIHelper.createPartName("/foo.rels") - ) - ); - assertNull( - ctm.getContentType( - PackagingURIHelper.createPartName("/foo.txt") - ) - ); - - pkg.revert(); - } - - /** - * Test package creation. - */ - @Test - public void createPackageAddPart() throws IOException, InvalidFormatException { - File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx"); - - File expectedFile = OpenXML4JTestDataSamples.getSampleFile("TestCreatePackageOUTPUT.docx"); - - // Zap the target file, in case of an earlier run - if(targetFile.exists()) { - assertTrue(targetFile.delete()); - } - - // Create a package - OPCPackage pkg = OPCPackage.create(targetFile); - PackagePartName corePartName = PackagingURIHelper - .createPartName("/word/document.xml"); - - pkg.addRelationship(corePartName, TargetMode.INTERNAL, - PackageRelationshipTypes.CORE_DOCUMENT, "rId1"); - - PackagePart corePart = pkg - .createPart( - corePartName, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); - - Document doc = DocumentHelper.createDocument(); - Element elDocument = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:document"); - doc.appendChild(elDocument); - Element elBody = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:body"); - elDocument.appendChild(elBody); - Element elParagraph = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:p"); - elBody.appendChild(elParagraph); - Element elRun = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:r"); - elParagraph.appendChild(elRun); - Element elText = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:t"); - elRun.appendChild(elText); - elText.setTextContent("Hello Open XML !"); - - StreamHelper.saveXmlInStream(doc, corePart.getOutputStream()); - pkg.close(); - - ZipFileAssert.assertEquals(expectedFile, targetFile); - assertTrue(targetFile.delete()); - } - - /** - * Tests that we can create a new package, add a core - * document and another part, save and re-load and - * have everything setup as expected - * @throws SAXException - */ - @Test - public void createPackageWithCoreDocument() throws IOException, InvalidFormatException, URISyntaxException, SAXException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - OPCPackage pkg = OPCPackage.create(baos); - - // Add a core document - PackagePartName corePartName = PackagingURIHelper.createPartName("/xl/workbook.xml"); - // Create main part relationship - pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId1"); - // Create main document part - PackagePart corePart = pkg.createPart(corePartName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); - // Put in some dummy content - OutputStream coreOut = corePart.getOutputStream(); - coreOut.write("".getBytes("UTF-8")); - coreOut.close(); - - // And another bit - PackagePartName sheetPartName = PackagingURIHelper.createPartName("/xl/worksheets/sheet1.xml"); - PackageRelationship rel = - corePart.addRelationship(sheetPartName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", "rSheet1"); - assertNotNull(rel); - - PackagePart part = pkg.createPart(sheetPartName, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"); - assertNotNull(part); - - // Dummy content again - coreOut = corePart.getOutputStream(); - coreOut.write("".getBytes("UTF-8")); - coreOut.close(); - - //add a relationship with internal target: "#Sheet1!A1" - corePart.addRelationship(new URI("#Sheet1!A1"), TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", "rId2"); - - // Check things are as expected - PackageRelationshipCollection coreRels = - pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT); - assertEquals(1, coreRels.size()); - PackageRelationship coreRel = coreRels.getRelationship(0); - assertNotNull(coreRel); - assertEquals("/", coreRel.getSourceURI().toString()); - assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString()); - assertNotNull(pkg.getPart(coreRel)); - - - // Save and re-load - pkg.close(); - File tmp = TempFile.createTempFile("testCreatePackageWithCoreDocument", ".zip"); - OutputStream fout = new FileOutputStream(tmp); - try { - fout.write(baos.toByteArray()); - } finally { - fout.close(); - } - pkg = OPCPackage.open(tmp.getPath()); - //tmp.delete(); - - try { - // Check still right - coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT); - assertEquals(1, coreRels.size()); - coreRel = coreRels.getRelationship(0); - - assertNotNull(coreRel); - assertEquals("/", coreRel.getSourceURI().toString()); - assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString()); - corePart = pkg.getPart(coreRel); - assertNotNull(corePart); - - PackageRelationshipCollection rels = corePart.getRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"); - assertEquals(1, rels.size()); - rel = rels.getRelationship(0); - assertNotNull(rel); - assertEquals("Sheet1!A1", rel.getTargetURI().getRawFragment()); - - assertMSCompatibility(pkg); - } finally { - pkg.close(); - } - } - - private void assertMSCompatibility(OPCPackage pkg) throws IOException, InvalidFormatException, SAXException { - PackagePartName relName = PackagingURIHelper.createPartName(PackageRelationship.getContainerPartRelationship()); - PackagePart relPart = pkg.getPart(relName); - - Document xmlRelationshipsDoc = DocumentHelper.readDocument(relPart.getInputStream()); - - Element root = xmlRelationshipsDoc.getDocumentElement(); - NodeList nodeList = root.getElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME); - int nodeCount = nodeList.getLength(); - for (int i = 0; i < nodeCount; i++) { - Element element = (Element) nodeList.item(i); - String value = element.getAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME); - assertTrue("Root target must not start with a leading slash ('/'): " + value, value.charAt(0) != '/'); - } - - } - - /** - * Test package opening. - */ - @Test - public void openPackage() throws IOException, InvalidFormatException { - File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestOpenPackageTMP.docx"); - - File inputFile = OpenXML4JTestDataSamples.getSampleFile("TestOpenPackageINPUT.docx"); - - File expectedFile = OpenXML4JTestDataSamples.getSampleFile("TestOpenPackageOUTPUT.docx"); - - // Copy the input file in the output directory - FileHelper.copyFile(inputFile, targetFile); - - // Create a package - OPCPackage pkg = OPCPackage.open(targetFile.getAbsolutePath()); - - // Modify core part - PackagePartName corePartName = PackagingURIHelper - .createPartName("/word/document.xml"); - - PackagePart corePart = pkg.getPart(corePartName); - - // Delete some part to have a valid document - for (PackageRelationship rel : corePart.getRelationships()) { - corePart.removeRelationship(rel.getId()); - pkg.removePart(PackagingURIHelper.createPartName(PackagingURIHelper - .resolvePartUri(corePart.getPartName().getURI(), rel - .getTargetURI()))); - } - - // Create a content - Document doc = DocumentHelper.createDocument(); - Element elDocument = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:document"); - doc.appendChild(elDocument); - Element elBody = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:body"); - elDocument.appendChild(elBody); - Element elParagraph = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:p"); - elBody.appendChild(elParagraph); - Element elRun = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:r"); - elParagraph.appendChild(elRun); - Element elText = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:t"); - elRun.appendChild(elText); - elText.setTextContent("Hello Open XML !"); - - StreamHelper.saveXmlInStream(doc, corePart.getOutputStream()); - - // Save and close - try { - pkg.close(); - } catch (IOException e) { - fail(); - } - - ZipFileAssert.assertEquals(expectedFile, targetFile); - assertTrue(targetFile.delete()); - } - - /** - * Checks that we can write a package to a simple - * OutputStream, in addition to the normal writing - * to a file - */ - @Test - public void saveToOutputStream() throws IOException, InvalidFormatException { - String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx"); - File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx"); - - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(originalFile, PackageAccess.READ_WRITE); - try { - FileOutputStream fout = new FileOutputStream(targetFile); - try { - p.save(fout); - } finally { - fout.close(); - } - - // Compare the original and newly saved document - assertTrue(targetFile.exists()); - ZipFileAssert.assertEquals(new File(originalFile), targetFile); - assertTrue(targetFile.delete()); - } finally { - // use revert to not re-write the input file - p.revert(); - } - } - - /** - * Checks that we can open+read a package from a - * simple InputStream, in addition to the normal - * reading from a file - */ - @Test - public void openFromInputStream() throws IOException, InvalidFormatException { - String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx"); - - FileInputStream finp = new FileInputStream(originalFile); - - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(finp); - - assertNotNull(p); - assertNotNull(p.getRelationships()); - assertEquals(12, p.getParts().size()); - - // Check it has the usual bits - assertTrue(p.hasRelationships()); - assertTrue(p.containPart(PackagingURIHelper.createPartName("/_rels/.rels"))); - - p.revert(); - finp.close(); - } - - /** - * TODO: fix and enable - * @throws URISyntaxException - */ - @Test - @Ignore - public void removePartRecursive() throws IOException, InvalidFormatException, URISyntaxException { - String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx"); - File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveOUTPUT.docx"); - File tempFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveTMP.docx"); - - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(originalFile, PackageAccess.READ_WRITE); - p.removePartRecursive(PackagingURIHelper.createPartName(new URI( - "/word/document.xml"))); - p.save(tempFile.getAbsoluteFile()); - - // Compare the original and newly saved document - assertTrue(targetFile.exists()); - ZipFileAssert.assertEquals(targetFile, tempFile); - assertTrue(targetFile.delete()); - - p.revert(); - } - - @Test - public void deletePart() throws InvalidFormatException { - TreeMap expectedValues; - TreeMap values; - - values = new TreeMap(); - - // Expected values - expectedValues = new TreeMap(); - expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"), - "application/vnd.openxmlformats-package.relationships+xml"); - - expectedValues - .put(PackagingURIHelper.createPartName("/docProps/app.xml"), - "application/vnd.openxmlformats-officedocument.extended-properties+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/docProps/core.xml"), - "application/vnd.openxmlformats-package.core-properties+xml"); - expectedValues - .put(PackagingURIHelper.createPartName("/word/fontTable.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/word/media/image1.gif"), "image/gif"); - expectedValues - .put(PackagingURIHelper.createPartName("/word/settings.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"); - expectedValues - .put(PackagingURIHelper.createPartName("/word/styles.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/word/theme/theme1.xml"), - "application/vnd.openxmlformats-officedocument.theme+xml"); - expectedValues - .put( - PackagingURIHelper - .createPartName("/word/webSettings.xml"), - "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"); - - String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx"); - - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ_WRITE); - // Remove the core part - p.deletePart(PackagingURIHelper.createPartName("/word/document.xml")); - - for (PackagePart part : p.getParts()) { - values.put(part.getPartName(), part.getContentType()); - logger.log(POILogger.DEBUG, part.getPartName()); - } - - // Compare expected values with values return by the package - for (PackagePartName partName : expectedValues.keySet()) { - assertNotNull(values.get(partName)); - assertEquals(expectedValues.get(partName), values.get(partName)); - } - // Don't save modifications - p.revert(); - } - - @Test - public void deletePartRecursive() throws InvalidFormatException { - TreeMap expectedValues; - TreeMap values; - - values = new TreeMap(); - - // Expected values - expectedValues = new TreeMap(); - expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"), - "application/vnd.openxmlformats-package.relationships+xml"); - - expectedValues - .put(PackagingURIHelper.createPartName("/docProps/app.xml"), - "application/vnd.openxmlformats-officedocument.extended-properties+xml"); - expectedValues.put(PackagingURIHelper - .createPartName("/docProps/core.xml"), - "application/vnd.openxmlformats-package.core-properties+xml"); - - String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx"); - - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ_WRITE); - // Remove the core part - p.deletePartRecursive(PackagingURIHelper.createPartName("/word/document.xml")); - - for (PackagePart part : p.getParts()) { - values.put(part.getPartName(), part.getContentType()); - logger.log(POILogger.DEBUG, part.getPartName()); - } - - // Compare expected values with values return by the package - for (PackagePartName partName : expectedValues.keySet()) { - assertNotNull(values.get(partName)); - assertEquals(expectedValues.get(partName), values.get(partName)); - } - // Don't save modifications - p.revert(); - } - - /** - * Test that we can open a file by path, and then - * write changes to it. - */ - @Test - public void openFileThenOverwrite() throws IOException, InvalidFormatException { - File tempFile = TempFile.createTempFile("poiTesting","tmp"); - File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx"); - FileHelper.copyFile(origFile, tempFile); - - // Open the temp file - OPCPackage p = OPCPackage.open(tempFile.toString(), PackageAccess.READ_WRITE); - // Close it - p.close(); - // Delete it - assertTrue(tempFile.delete()); - - // Reset - FileHelper.copyFile(origFile, tempFile); - p = OPCPackage.open(tempFile.toString(), PackageAccess.READ_WRITE); - - // Save it to the same file - not allowed - try { - p.save(tempFile); - fail("You shouldn't be able to call save(File) to overwrite the current file"); - } catch(InvalidOperationException e) { - // expected here - } - - p.close(); - // Delete it - assertTrue(tempFile.delete()); - - - // Open it read only, then close and delete - allowed - FileHelper.copyFile(origFile, tempFile); - p = OPCPackage.open(tempFile.toString(), PackageAccess.READ); - p.close(); - assertTrue(tempFile.delete()); - } - /** - * Test that we can open a file by path, save it - * to another file, then delete both - */ - @Test - public void openFileThenSaveDelete() throws IOException, InvalidFormatException { - File tempFile = TempFile.createTempFile("poiTesting","tmp"); - File tempFile2 = TempFile.createTempFile("poiTesting","tmp"); - File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx"); - FileHelper.copyFile(origFile, tempFile); - - // Open the temp file - OPCPackage p = OPCPackage.open(tempFile.toString(), PackageAccess.READ_WRITE); - - // Save it to a different file - p.save(tempFile2); - p.close(); - - // Delete both the files - assertTrue(tempFile.delete()); - assertTrue(tempFile2.delete()); - } - - private static ContentTypeManager getContentTypeManager(OPCPackage pkg) { - return POITestCase.getFieldValue(OPCPackage.class, pkg, ContentTypeManager.class, "contentTypeManager"); - } - - @Test - public void getPartsByName() throws IOException, InvalidFormatException { - String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx"); - - @SuppressWarnings("resource") - OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ_WRITE); - try { - List rs = pkg.getPartsByName(Pattern.compile("/word/.*?\\.xml")); - HashMap selected = new HashMap(); - - for(PackagePart p : rs) - selected.put(p.getPartName().getName(), p); - - assertEquals(6, selected.size()); - assertTrue(selected.containsKey("/word/document.xml")); - assertTrue(selected.containsKey("/word/fontTable.xml")); - assertTrue(selected.containsKey("/word/settings.xml")); - assertTrue(selected.containsKey("/word/styles.xml")); - assertTrue(selected.containsKey("/word/theme/theme1.xml")); - assertTrue(selected.containsKey("/word/webSettings.xml")); - } finally { - // use revert to not re-write the input file - pkg.revert(); - } - } - - @Test - public void getPartSize() throws IOException, InvalidFormatException { - String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx"); - OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ); - try { - int checked = 0; - for (PackagePart part : pkg.getParts()) { - // Can get the size of zip parts - if (part.getPartName().getName().equals("/word/document.xml")) { - checked++; - assertEquals(ZipPackagePart.class, part.getClass()); - assertEquals(6031L, part.getSize()); - } - if (part.getPartName().getName().equals("/word/fontTable.xml")) { - checked++; - assertEquals(ZipPackagePart.class, part.getClass()); - assertEquals(1312L, part.getSize()); - } - - // But not from the others - if (part.getPartName().getName().equals("/docProps/core.xml")) { - checked++; - assertEquals(PackagePropertiesPart.class, part.getClass()); - assertEquals(-1, part.getSize()); - } - } - // Ensure we actually found the parts we want to check - assertEquals(3, checked); - } finally { - pkg.close(); - } - } - - @Test - public void replaceContentType() - throws IOException, InvalidFormatException, SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.xlsx"); - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(is); - - ContentTypeManager mgr = getContentTypeManager(p); - - assertTrue(mgr.isContentTypeRegister("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")); - assertFalse(mgr.isContentTypeRegister("application/vnd.ms-excel.sheet.macroEnabled.main+xml")); - - assertTrue( - p.replaceContentType( - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", - "application/vnd.ms-excel.sheet.macroEnabled.main+xml") - ); - - assertFalse(mgr.isContentTypeRegister("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")); - assertTrue(mgr.isContentTypeRegister("application/vnd.ms-excel.sheet.macroEnabled.main+xml")); - p.revert(); - is.close(); - } - - /** - * Verify we give helpful exceptions (or as best we can) when - * supplied with non-OOXML file types (eg OLE2, ODF) - */ - @Test - public void NonOOXMLFileTypes() throws Exception { - // Spreadsheet has a good mix of alternate file types - POIDataSamples files = POIDataSamples.getSpreadSheetInstance(); - - // OLE2 - Stream - try { - InputStream stream = files.openResourceAsStream("SampleSS.xls"); - try { - OPCPackage.open(stream); - } finally { - stream.close(); - } - fail("Shouldn't be able to open OLE2"); - } catch (OLE2NotOfficeXmlFileException e) { - assertTrue(e.getMessage().contains("The supplied data appears to be in the OLE2 Format")); - assertTrue(e.getMessage().contains("You are calling the part of POI that deals with OOXML")); - } - // OLE2 - File - try { - OPCPackage.open(files.getFile("SampleSS.xls")); - fail("Shouldn't be able to open OLE2"); - } catch (OLE2NotOfficeXmlFileException e) { - assertTrue(e.getMessage().contains("The supplied data appears to be in the OLE2 Format")); - assertTrue(e.getMessage().contains("You are calling the part of POI that deals with OOXML")); - } - - // Raw XML - Stream - try { - InputStream stream = files.openResourceAsStream("SampleSS.xml"); - try { - OPCPackage.open(stream); - } finally { - stream.close(); - } - fail("Shouldn't be able to open XML"); - } catch (NotOfficeXmlFileException e) { - assertTrue(e.getMessage().contains("The supplied data appears to be a raw XML file")); - assertTrue(e.getMessage().contains("Formats such as Office 2003 XML")); - } - // Raw XML - File - try { - OPCPackage.open(files.getFile("SampleSS.xml")); - fail("Shouldn't be able to open XML"); - } catch (NotOfficeXmlFileException e) { - assertTrue(e.getMessage().contains("The supplied data appears to be a raw XML file")); - assertTrue(e.getMessage().contains("Formats such as Office 2003 XML")); - } - - // ODF / ODS - Stream - try { - InputStream stream = files.openResourceAsStream("SampleSS.ods"); - try { - OPCPackage.open(stream); - } finally { - stream.close(); - } - fail("Shouldn't be able to open ODS"); - } catch (ODFNotOfficeXmlFileException e) { - assertTrue(e.toString().contains("The supplied data appears to be in ODF")); - assertTrue(e.toString().contains("Formats like these (eg ODS")); - } - // ODF / ODS - File - try { - OPCPackage.open(files.getFile("SampleSS.ods")); - fail("Shouldn't be able to open ODS"); - } catch (ODFNotOfficeXmlFileException e) { - assertTrue(e.toString().contains("The supplied data appears to be in ODF")); - assertTrue(e.toString().contains("Formats like these (eg ODS")); - } - - // Plain Text - Stream - try { - InputStream stream = files.openResourceAsStream("SampleSS.txt"); - try { - OPCPackage.open(stream); - } finally { - stream.close(); - } - fail("Shouldn't be able to open Plain Text"); - } catch (NotOfficeXmlFileException e) { - assertTrue(e.getMessage().contains("No valid entries or contents found")); - assertTrue(e.getMessage().contains("not a valid OOXML")); - } - // Plain Text - File - try { - OPCPackage.open(files.getFile("SampleSS.txt")); - fail("Shouldn't be able to open Plain Text"); - } catch (UnsupportedFileFormatException e) { - // Unhelpful low-level error, sorry - } - } - - @Test(expected=IOException.class) - public void zipBombCreateAndHandle() - throws IOException, EncryptedDocumentException, InvalidFormatException { - // #50090 / #56865 - ZipFile zipFile = ZipHelper.openZipFile(OpenXML4JTestDataSamples.getSampleFile("sample.xlsx")); - assertNotNull(zipFile); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(2500000); - ZipOutputStream append = new ZipOutputStream(bos); - // first, copy contents from existing war - Enumeration entries = zipFile.entries(); - while (entries.hasMoreElements()) { - ZipEntry e2 = entries.nextElement(); - ZipEntry e = new ZipEntry(e2.getName()); - e.setTime(e2.getTime()); - e.setComment(e2.getComment()); - e.setSize(e2.getSize()); - - append.putNextEntry(e); - if (!e.isDirectory()) { - InputStream is = zipFile.getInputStream(e); - if (e.getName().equals("[Content_Types].xml")) { - ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); - IOUtils.copy(is, bos2); - long size = bos2.size()-"".length(); - append.write(bos2.toByteArray(), 0, (int)size); - byte spam[] = new byte[0x7FFF]; - for (int i=0; i".getBytes("UTF-8")); - size += 8; - e.setSize(size); - } else { - IOUtils.copy(is, append); - } - is.close(); - } - append.closeEntry(); - } - - append.close(); - zipFile.close(); - - byte buf[] = bos.toByteArray(); - //noinspection UnusedAssignment - bos = null; - - Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(buf)); - wb.getSheetAt(0); - wb.close(); - zipFile.close(); - } - - @Test - public void zipBombCheckSizes() - throws IOException, EncryptedDocumentException, InvalidFormatException { - File file = OpenXML4JTestDataSamples.getSampleFile("sample.xlsx"); - - try { - double min_ratio = Double.MAX_VALUE; - long max_size = 0; - ZipFile zf = ZipHelper.openZipFile(file); - assertNotNull(zf); - Enumeration entries = zf.entries(); - while (entries.hasMoreElements()) { - ZipEntry ze = entries.nextElement(); - double ratio = (double)ze.getCompressedSize() / (double)ze.getSize(); - min_ratio = Math.min(min_ratio, ratio); - max_size = Math.max(max_size, ze.getSize()); - } - zf.close(); - - // use values close to, but within the limits - ZipSecureFile.setMinInflateRatio(min_ratio-0.002); - assertEquals(min_ratio-0.002, ZipSecureFile.getMinInflateRatio(), 0.00001); - ZipSecureFile.setMaxEntrySize(max_size+1); - assertEquals(max_size+1, ZipSecureFile.getMaxEntrySize()); - - WorkbookFactory.create(file, null, true).close(); - - // check ratio out of bounds - ZipSecureFile.setMinInflateRatio(min_ratio+0.002); - try { - WorkbookFactory.create(file, null, true).close(); - // this is a bit strange, as there will be different exceptions thrown - // depending if this executed via "ant test" or within eclipse - // maybe a difference in JDK ... - } catch (InvalidFormatException e) { - checkForZipBombException(e); - } catch (POIXMLException e) { - checkForZipBombException(e); - } - - // check max entry size ouf of bounds - ZipSecureFile.setMinInflateRatio(min_ratio-0.002); - ZipSecureFile.setMaxEntrySize(max_size-1); - try { - WorkbookFactory.create(file, null, true).close(); - } catch (InvalidFormatException e) { - checkForZipBombException(e); - } catch (POIXMLException e) { - checkForZipBombException(e); - } - } finally { - // reset otherwise a lot of ooxml tests will fail - ZipSecureFile.setMinInflateRatio(0.01d); - ZipSecureFile.setMaxEntrySize(0xFFFFFFFFL); - } - } - - private void checkForZipBombException(Throwable e) { - if(e instanceof InvocationTargetException) { - InvocationTargetException t = (InvocationTargetException)e; - IOException t2 = (IOException)t.getTargetException(); - if(t2.getMessage().startsWith("Zip bomb detected!")) { - return; - } - } - - String msg = e.getMessage(); - if(msg != null && msg.startsWith("Zip bomb detected!")) { - return; - } - - // recursively check the causes for the message as it can be nested further down in the exception-tree - if(e.getCause() != null && e.getCause() != e) { - checkForZipBombException(e.getCause()); - return; - } - - throw new IllegalStateException("Expected to catch an Exception because of a detected Zip Bomb, but did not find the related error message in the exception", e); - } - - @Test - public void testConstructors() throws IOException { - // verify the various ways to construct a ZipSecureFile - File file = OpenXML4JTestDataSamples.getSampleFile("sample.xlsx"); - ZipSecureFile zipFile = new ZipSecureFile(file); - assertNotNull(zipFile.getName()); - zipFile.close(); - - zipFile = new ZipSecureFile(file, ZipFile.OPEN_READ); - assertNotNull(zipFile.getName()); - zipFile.close(); - - zipFile = new ZipSecureFile(file.getAbsolutePath()); - assertNotNull(zipFile.getName()); - zipFile.close(); - } - - @Test - public void testMaxTextSize() { - long before = ZipSecureFile.getMaxTextSize(); - try { - ZipSecureFile.setMaxTextSize(12345); - assertEquals(12345, ZipSecureFile.getMaxTextSize()); - } finally { - ZipSecureFile.setMaxTextSize(before); - } - } - - // bug 60128 - @Test - public void testCorruptFile() throws IOException { - OPCPackage pkg = null; - File file = OpenXML4JTestDataSamples.getSampleFile("invalid.xlsx"); - try { - pkg = OPCPackage.open(file, PackageAccess.READ); - } catch (Exception e) { - System.out.println(e.getClass().getName()); - System.out.println(e.getMessage()); - e.printStackTrace(); - } finally { - if (pkg != null) { - pkg.close(); - } - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java deleted file mode 100644 index b29d21fc0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java +++ /dev/null @@ -1,327 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStream; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; -import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; -import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty; - -public final class TestPackageCoreProperties { - /** - * Test package core properties getters. - */ - @Test - public void testGetProperties() throws Exception { - // Open the package - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("TestPackageCoreProperiesGetters.docx")); - compareProperties(p); - p.revert(); - } - - /** - * Test package core properties setters. - */ - @Test - public void testSetProperties() throws Exception { - String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCoreProperiesSetters.docx"); - - File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageCoreProperiesSettersOUTPUT.docx"); - - // Open package - @SuppressWarnings("resource") - OPCPackage p = OPCPackage.open(inputPath, PackageAccess.READ_WRITE); - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - Date dateToInsert = df.parse("2007-05-12T08:00:00Z", new ParsePosition(0)); - - SimpleDateFormat msdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT); - msdf.setTimeZone(LocaleUtil.TIMEZONE_UTC); - - PackageProperties props = p.getPackageProperties(); - - //test various date formats - props.setCreatedProperty("2007-05-12T08:00:00Z"); - assertEquals(dateToInsert, props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2007-05-12T08:00:00"); //no Z, assume Z - assertEquals(dateToInsert, props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2007-05-12T08:00:00.123Z");//millis - assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2007-05-12T10:00:00+0200"); - assertEquals(dateToInsert, props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2007-05-12T10:00:00+02:00");//colon in tz - assertEquals(dateToInsert, props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2007-05-12T06:00:00-0200"); - assertEquals(dateToInsert, props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2015-07-27"); - assertEquals(msdf.parse("2015-07-27T00:00:00.000Z"), props.getCreatedProperty().getValue()); - - props.setCreatedProperty("2007-05-12T10:00:00.123+0200"); - assertEquals(msdf.parse("2007-05-12T08:00:00.123Z"), props.getCreatedProperty().getValue()); - - props.setCategoryProperty("MyCategory"); - props.setContentStatusProperty("MyContentStatus"); - props.setContentTypeProperty("MyContentType"); - props.setCreatorProperty("MyCreator"); - props.setDescriptionProperty("MyDescription"); - props.setIdentifierProperty("MyIdentifier"); - props.setKeywordsProperty("MyKeywords"); - props.setLanguageProperty("MyLanguage"); - props.setLastModifiedByProperty("Julien Chable"); - props.setLastPrintedProperty(new Nullable(dateToInsert)); - props.setModifiedProperty(new Nullable(dateToInsert)); - props.setRevisionProperty("2"); - props.setTitleProperty("MyTitle"); - props.setSubjectProperty("MySubject"); - props.setVersionProperty("2"); - // Save the package in the output directory - p.save(outputFile); - p.revert(); - - // Open the newly created file to check core properties saved values. - @SuppressWarnings("resource") - OPCPackage p2 = OPCPackage.open(outputFile.getAbsolutePath(), PackageAccess.READ); - compareProperties(p2); - p2.revert(); - outputFile.delete(); - } - - private void compareProperties(OPCPackage p) throws InvalidFormatException { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - Date expectedDate = df.parse("2007-05-12T08:00:00Z", new ParsePosition(0)); - - // Gets the core properties - PackageProperties props = p.getPackageProperties(); - assertEquals("MyCategory", props.getCategoryProperty().getValue()); - assertEquals("MyContentStatus", props.getContentStatusProperty().getValue()); - assertEquals("MyContentType", props.getContentTypeProperty().getValue()); - assertEquals(expectedDate, props.getCreatedProperty().getValue()); - assertEquals("MyCreator", props.getCreatorProperty().getValue()); - assertEquals("MyDescription", props.getDescriptionProperty().getValue()); - assertEquals("MyIdentifier", props.getIdentifierProperty().getValue()); - assertEquals("MyKeywords", props.getKeywordsProperty().getValue()); - assertEquals("MyLanguage", props.getLanguageProperty().getValue()); - assertEquals("Julien Chable", props.getLastModifiedByProperty().getValue()); - assertEquals(expectedDate, props.getLastPrintedProperty().getValue()); - assertEquals(expectedDate, props.getModifiedProperty().getValue()); - assertEquals("2", props.getRevisionProperty().getValue()); - assertEquals("MySubject", props.getSubjectProperty().getValue()); - assertEquals("MyTitle", props.getTitleProperty().getValue()); - assertEquals("2", props.getVersionProperty().getValue()); - } - - @Test - public void testCoreProperties_bug51374() throws Exception { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - String strDate = "2007-05-12T08:00:00Z"; - Date date = df.parse(strDate); - - OPCPackage pkg = new ZipPackage(); - PackagePropertiesPart props = (PackagePropertiesPart)pkg.getPackageProperties(); - - // created - assertEquals("", props.getCreatedPropertyString()); - assertNull(props.getCreatedProperty().getValue()); - props.setCreatedProperty((String)null); - assertEquals("", props.getCreatedPropertyString()); - assertNull(props.getCreatedProperty().getValue()); - props.setCreatedProperty(new Nullable()); - assertEquals("", props.getCreatedPropertyString()); - assertNull(props.getCreatedProperty().getValue()); - props.setCreatedProperty(new Nullable(date)); - assertEquals(strDate, props.getCreatedPropertyString()); - assertEquals(date, props.getCreatedProperty().getValue()); - props.setCreatedProperty(strDate); - assertEquals(strDate, props.getCreatedPropertyString()); - assertEquals(date, props.getCreatedProperty().getValue()); - - // lastPrinted - assertEquals("", props.getLastPrintedPropertyString()); - assertNull(props.getLastPrintedProperty().getValue()); - props.setLastPrintedProperty((String)null); - assertEquals("", props.getLastPrintedPropertyString()); - assertNull(props.getLastPrintedProperty().getValue()); - props.setLastPrintedProperty(new Nullable()); - assertEquals("", props.getLastPrintedPropertyString()); - assertNull(props.getLastPrintedProperty().getValue()); - props.setLastPrintedProperty(new Nullable(date)); - assertEquals(strDate, props.getLastPrintedPropertyString()); - assertEquals(date, props.getLastPrintedProperty().getValue()); - props.setLastPrintedProperty(strDate); - assertEquals(strDate, props.getLastPrintedPropertyString()); - assertEquals(date, props.getLastPrintedProperty().getValue()); - - // modified - assertNull(props.getModifiedProperty().getValue()); - props.setModifiedProperty((String)null); - assertNull(props.getModifiedProperty().getValue()); - props.setModifiedProperty(new Nullable()); - assertNull(props.getModifiedProperty().getValue()); - props.setModifiedProperty(new Nullable(date)); - assertEquals(strDate, props.getModifiedPropertyString()); - assertEquals(date, props.getModifiedProperty().getValue()); - props.setModifiedProperty(strDate); - assertEquals(strDate, props.getModifiedPropertyString()); - assertEquals(date, props.getModifiedProperty().getValue()); - - // Tidy - pkg.close(); - } - - @Test - public void testGetPropertiesLO() throws Exception { - // Open the package - OPCPackage pkg1 = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("51444.xlsx")); - PackageProperties props1 = pkg1.getPackageProperties(); - assertEquals(null, props1.getTitleProperty().getValue()); - props1.setTitleProperty("Bug 51444 fixed"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - pkg1.save(out); - out.close(); - pkg1.close(); - - OPCPackage pkg2 = OPCPackage.open(new ByteArrayInputStream(out.toByteArray())); - PackageProperties props2 = pkg2.getPackageProperties(); - props2.setTitleProperty("Bug 51444 fixed"); - pkg2.close(); - } - - @Test - public void testEntitiesInCoreProps_56164() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("CorePropertiesHasEntities.ooxml"); - OPCPackage p = OPCPackage.open(is); - is.close(); - - // Should have 3 root relationships - boolean foundDocRel = false, foundCorePropRel = false, foundExtPropRel = false; - for (PackageRelationship pr : p.getRelationships()) { - if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_DOCUMENT)) - foundDocRel = true; - if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) - foundCorePropRel = true; - if (pr.getRelationshipType().equals(PackageRelationshipTypes.EXTENDED_PROPERTIES)) - foundExtPropRel = true; - } - assertTrue("Core/Doc Relationship not found in " + p.getRelationships(), foundDocRel); - assertTrue("Core Props Relationship not found in " + p.getRelationships(), foundCorePropRel); - assertTrue("Ext Props Relationship not found in " + p.getRelationships(), foundExtPropRel); - - // Get the Core Properties - PackagePropertiesPart props = (PackagePropertiesPart)p.getPackageProperties(); - - // Check - assertEquals("Stefan Kopf", props.getCreatorProperty().getValue()); - - p.close(); - } - - @Test - public void testListOfCustomProperties() throws Exception { - File inp = POIDataSamples.getSpreadSheetInstance().getFile("ExcelWithAttachments.xlsm"); - OPCPackage pkg = OPCPackage.open(inp, PackageAccess.READ); - XSSFWorkbook wb = new XSSFWorkbook(pkg); - - assertNotNull(wb.getProperties()); - assertNotNull(wb.getProperties().getCustomProperties()); - - for (CTProperty prop : wb.getProperties().getCustomProperties().getUnderlyingProperties().getPropertyList()) { - assertNotNull(prop); - } - - wb.close(); - pkg.close(); - } - - @Test - public void testAlternateCorePropertyTimezones() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("OPCCompliance_CoreProperties_AlternateTimezones.docx"); - OPCPackage pkg = OPCPackage.open(is); - PackagePropertiesPart props = (PackagePropertiesPart)pkg.getPackageProperties(); - is.close(); - - // We need predictable dates for testing! - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - - // Check text properties first - assertEquals("Lorem Ipsum", props.getTitleProperty().getValue()); - assertEquals("Apache POI", props.getCreatorProperty().getValue()); - - // Created at has a +3 timezone and milliseconds - // 2006-10-13T18:06:00.123+03:00 - // = 2006-10-13T15:06:00.123+00:00 - assertEquals("2006-10-13T15:06:00Z", props.getCreatedPropertyString()); - assertEquals("2006-10-13T15:06:00.123Z", df.format(props.getCreatedProperty().getValue())); - - // Modified at has a -13 timezone but no milliseconds - // 2007-06-20T07:59:00-13:00 - // = 2007-06-20T20:59:00-13:00 - assertEquals("2007-06-20T20:59:00Z", props.getModifiedPropertyString()); - assertEquals("2007-06-20T20:59:00.000Z", df.format(props.getModifiedProperty().getValue())); - - - // Ensure we can change them with other timezones and still read back OK - props.setCreatedProperty("2007-06-20T20:57:00+13:00"); - props.setModifiedProperty("2007-06-20T20:59:00.123-13:00"); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - pkg.save(baos); - pkg = OPCPackage.open(new ByteArrayInputStream(baos.toByteArray())); - - // Check text properties first - should be unchanged - assertEquals("Lorem Ipsum", props.getTitleProperty().getValue()); - assertEquals("Apache POI", props.getCreatorProperty().getValue()); - - // Check the updated times - // 2007-06-20T20:57:00+13:00 - // = 2007-06-20T07:57:00Z - assertEquals("2007-06-20T07:57:00.000Z", df.format(props.getCreatedProperty().getValue())); - - // 2007-06-20T20:59:00.123-13:00 - // = 2007-06-21T09:59:00.123Z - assertEquals("2007-06-21T09:59:00.123Z", df.format(props.getModifiedProperty().getValue())); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagePartName.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagePartName.java deleted file mode 100644 index ed9b90093..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagePartName.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; - -import junit.framework.TestCase; - -public final class TestPackagePartName extends TestCase { - - /** - * Test method getExtension(). - */ - public void testGetExtension() throws Exception{ - PackagePartName name1 = PackagingURIHelper.createPartName("/doc/props/document.xml"); - PackagePartName name2 = PackagingURIHelper.createPartName("/root/document"); - assertEquals("xml", name1.getExtension()); - assertEquals("", name2.getExtension()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageThumbnail.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageThumbnail.java deleted file mode 100644 index 432bd896c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageThumbnail.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; - -/** - * Test the addition of thumbnail in a package. - * - * @author Julien Chable - */ -public final class TestPackageThumbnail extends TestCase { - - /** - * Test package addThumbnail() method. - */ - public void testSetProperties() throws Exception { - String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageThumbnail.docx"); - - String imagePath = OpenXML4JTestDataSamples.getSampleFileName("thumbnail.jpg"); - - File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageThumbnailOUTPUT.docx"); - - // Open package - OPCPackage p = OPCPackage.open(inputPath, PackageAccess.READ_WRITE); - try { - p.addThumbnail(imagePath); - // Save the package in the output directory - p.save(outputFile); - - // Open the newly created file to check core properties saved values. - OPCPackage p2 = OPCPackage.open(outputFile.getAbsolutePath(), PackageAccess.READ); - try { - if (p2.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL) - .size() == 0) - fail("Thumbnail not added to the package !"); - } finally { - p2.revert(); - p2.close(); - } - } finally { - p.revert(); - outputFile.delete(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagingURIHelper.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagingURIHelper.java deleted file mode 100644 index 39ab5ed4d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagingURIHelper.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.openxml4j.opc; - -import java.net.URI; -import java.net.URISyntaxException; - -import junit.framework.TestCase; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; - -public class TestPackagingURIHelper extends TestCase { - - /** - * Test relativizePartName() method. - */ - public void testRelativizeURI() throws Exception { - URI uri1 = new URI("/word/document.xml"); - URI uri2 = new URI("/word/media/image1.gif"); - URI uri3 = new URI("/word/media/image1.gif#Sheet1!A1"); - URI uri4 = new URI("#'My%20Sheet1'!A1"); - - // Document to image is down a directory - URI retURI1to2 = PackagingURIHelper.relativizeURI(uri1, uri2); - assertEquals("media/image1.gif", retURI1to2.getPath()); - // Image to document is up a directory - URI retURI2to1 = PackagingURIHelper.relativizeURI(uri2, uri1); - assertEquals("../document.xml", retURI2to1.getPath()); - - // Document and CustomXML parts totally different [Julien C.] - URI uriCustomXml = new URI("/customXml/item1.xml"); - URI uriRes = PackagingURIHelper.relativizeURI(uri1, uriCustomXml); - assertEquals("../customXml/item1.xml", uriRes.toString()); - - // Document to itself is the same place (empty URI) - URI retURI2 = PackagingURIHelper.relativizeURI(uri1, uri1); - // YK: the line below used to assert empty string which is wrong - // if source and target are the same they should be relaitivized as the last segment, - // see Bugzilla 51187 - assertEquals("document.xml", retURI2.getPath()); - - // relativization against root - URI root = new URI("/"); - uriRes = PackagingURIHelper.relativizeURI(root, uri1); - assertEquals("/word/document.xml", uriRes.toString()); - - //URI compatible with MS Office and OpenOffice: leading slash is removed - uriRes = PackagingURIHelper.relativizeURI(root, uri1, true); - assertEquals("word/document.xml", uriRes.toString()); - - //preserve URI fragments - uriRes = PackagingURIHelper.relativizeURI(uri1, uri3, true); - assertEquals("media/image1.gif#Sheet1!A1", uriRes.toString()); - uriRes = PackagingURIHelper.relativizeURI(root, uri4, true); - assertEquals("#'My%20Sheet1'!A1", uriRes.toString()); - } - - /** - * Test createPartName(String, y) - */ - public void testCreatePartNameRelativeString() - throws InvalidFormatException { - PackagePartName partNameToValid = PackagingURIHelper - .createPartName("/word/media/image1.gif"); - - OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx"); - // Base part - PackagePartName nameBase = PackagingURIHelper - .createPartName("/word/document.xml"); - PackagePart partBase = pkg.createPart(nameBase, ContentTypes.XML); - // Relative part name - PackagePartName relativeName = PackagingURIHelper.createPartName( - "media/image1.gif", partBase); - assertTrue("The part name must be equal to " - + partNameToValid.getName(), partNameToValid - .equals(relativeName)); - pkg.revert(); - } - - /** - * Test createPartName(URI, y) - */ - public void testCreatePartNameRelativeURI() throws Exception { - PackagePartName partNameToValid = PackagingURIHelper - .createPartName("/word/media/image1.gif"); - - OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx"); - // Base part - PackagePartName nameBase = PackagingURIHelper - .createPartName("/word/document.xml"); - PackagePart partBase = pkg.createPart(nameBase, ContentTypes.XML); - // Relative part name - PackagePartName relativeName = PackagingURIHelper.createPartName( - new URI("media/image1.gif"), partBase); - assertTrue("The part name must be equal to " - + partNameToValid.getName(), partNameToValid - .equals(relativeName)); - pkg.revert(); - } - - public void testCreateURIFromString() throws Exception { - String[] href = { - "..\\\\\\cygwin\\home\\yegor\\.vim\\filetype.vim", - "..\\Program%20Files\\AGEIA%20Technologies\\v2.3.3\\NxCooking.dll", - "file:///D:\\seva\\1981\\r810102ns.mp3", - "..\\cygwin\\home\\yegor\\dinom\\%5baccess%5d.2010-10-26.log", - "#'Instructions (Text)'!B21", - "javascript://" - }; - for(String s : href){ - try { - URI uri = PackagingURIHelper.toURI(s); - } catch (URISyntaxException e){ - fail("Failed to create URI from " + s); - } - } - } - - public void test53734() throws Exception { - URI uri = PackagingURIHelper.toURI("javascript://"); - // POI appends a trailing slash tpo avoid "Expected authority at index 13: javascript://" - // https://issues.apache.org/bugzilla/show_bug.cgi?id=53734 - assertEquals("javascript:///", uri.toASCIIString()); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java deleted file mode 100644 index cf485ed1f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java +++ /dev/null @@ -1,445 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.net.URI; -import java.util.regex.Pattern; - -import junit.framework.TestCase; - -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xwpf.usermodel.XWPFRelation; - - -public class TestRelationships extends TestCase { - private static final String HYPERLINK_REL_TYPE = - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; - private static final String COMMENTS_REL_TYPE = - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"; - private static final String SHEET_WITH_COMMENTS = - "/xl/worksheets/sheet1.xml"; - - private static final POILogger logger = POILogFactory.getLogger(TestPackageCoreProperties.class); - - /** - * Test relationships are correctly loaded. This at the moment fails (as of r499) - * whenever a document is loaded before its correspondig .rels file has been found. - * The code in this case assumes there are no relationships defined, but it should - * really look also for not yet loaded parts. - */ - public void testLoadRelationships() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.xlsx"); - OPCPackage pkg = OPCPackage.open(is); - logger.log(POILogger.DEBUG, "1: " + pkg); - PackageRelationshipCollection rels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT); - PackageRelationship coreDocRelationship = rels.getRelationship(0); - PackagePart corePart = pkg.getPart(coreDocRelationship); - String relIds[] = { "rId1", "rId2", "rId3" }; - for (String relId : relIds) { - PackageRelationship rel = corePart.getRelationship(relId); - assertNotNull(rel); - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - PackagePart sheetPart = pkg.getPart(relName); - assertEquals("Number of relationships1 for " + sheetPart.getPartName(), 1, sheetPart.getRelationships().size()); - } - } - - /** - * Checks that we can fetch a collection of relations by - * type, then grab from within there by id - */ - public void testFetchFromCollection() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("ExcelWithHyperlinks.xlsx"); - OPCPackage pkg = OPCPackage.open(is); - PackagePart sheet = pkg.getPart( - PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS)); - assertNotNull(sheet); - - assertTrue(sheet.hasRelationships()); - assertEquals(6, sheet.getRelationships().size()); - - // Should have three hyperlinks, and one comment - PackageRelationshipCollection hyperlinks = - sheet.getRelationshipsByType(HYPERLINK_REL_TYPE); - PackageRelationshipCollection comments = - sheet.getRelationshipsByType(COMMENTS_REL_TYPE); - assertEquals(3, hyperlinks.size()); - assertEquals(1, comments.size()); - - // Check we can get bits out by id - // Hyperlinks are rId1, rId2 and rId3 - // Comment is rId6 - assertNotNull(hyperlinks.getRelationshipByID("rId1")); - assertNotNull(hyperlinks.getRelationshipByID("rId2")); - assertNotNull(hyperlinks.getRelationshipByID("rId3")); - assertNull(hyperlinks.getRelationshipByID("rId6")); - - assertNull(comments.getRelationshipByID("rId1")); - assertNull(comments.getRelationshipByID("rId2")); - assertNull(comments.getRelationshipByID("rId3")); - assertNotNull(comments.getRelationshipByID("rId6")); - - assertNotNull(sheet.getRelationship("rId1")); - assertNotNull(sheet.getRelationship("rId2")); - assertNotNull(sheet.getRelationship("rId3")); - assertNotNull(sheet.getRelationship("rId6")); - } - - /** - * Excel uses relations on sheets to store the details of - * external hyperlinks. Check we can load these ok. - */ - public void testLoadExcelHyperlinkRelations() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("ExcelWithHyperlinks.xlsx"); - OPCPackage pkg = OPCPackage.open(is); - PackagePart sheet = pkg.getPart( - PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS)); - assertNotNull(sheet); - - // rId1 is url - PackageRelationship url = sheet.getRelationship("rId1"); - assertNotNull(url); - assertEquals("rId1", url.getId()); - assertEquals("/xl/worksheets/sheet1.xml", url.getSourceURI().toString()); - assertEquals("http://poi.apache.org/", url.getTargetURI().toString()); - - // rId2 is file - PackageRelationship file = sheet.getRelationship("rId2"); - assertNotNull(file); - assertEquals("rId2", file.getId()); - assertEquals("/xl/worksheets/sheet1.xml", file.getSourceURI().toString()); - assertEquals("WithVariousData.xlsx", file.getTargetURI().toString()); - - // rId3 is mailto - PackageRelationship mailto = sheet.getRelationship("rId3"); - assertNotNull(mailto); - assertEquals("rId3", mailto.getId()); - assertEquals("/xl/worksheets/sheet1.xml", mailto.getSourceURI().toString()); - assertEquals("mailto:dev@poi.apache.org?subject=XSSF%20Hyperlinks", mailto.getTargetURI().toString()); - } - - /* - * Excel uses relations on sheets to store the details of - * external hyperlinks. Check we can create these OK, - * then still read them later - */ - public void testCreateExcelHyperlinkRelations() throws Exception { - String filepath = OpenXML4JTestDataSamples.getSampleFileName("ExcelWithHyperlinks.xlsx"); - OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ_WRITE); - PackagePart sheet = pkg.getPart( - PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS)); - assertNotNull(sheet); - - assertEquals(3, sheet.getRelationshipsByType(HYPERLINK_REL_TYPE).size()); - - // Add three new ones - PackageRelationship openxml4j = - sheet.addExternalRelationship("http://www.openxml4j.org/", HYPERLINK_REL_TYPE); - PackageRelationship sf = - sheet.addExternalRelationship("http://openxml4j.sf.net/", HYPERLINK_REL_TYPE); - PackageRelationship file = - sheet.addExternalRelationship("MyDocument.docx", HYPERLINK_REL_TYPE); - - // Check they were added properly - assertNotNull(openxml4j); - assertNotNull(sf); - assertNotNull(file); - - assertEquals(6, sheet.getRelationshipsByType(HYPERLINK_REL_TYPE).size()); - - assertEquals("http://www.openxml4j.org/", openxml4j.getTargetURI().toString()); - assertEquals("/xl/worksheets/sheet1.xml", openxml4j.getSourceURI().toString()); - assertEquals(HYPERLINK_REL_TYPE, openxml4j.getRelationshipType()); - - assertEquals("http://openxml4j.sf.net/", sf.getTargetURI().toString()); - assertEquals("/xl/worksheets/sheet1.xml", sf.getSourceURI().toString()); - assertEquals(HYPERLINK_REL_TYPE, sf.getRelationshipType()); - - assertEquals("MyDocument.docx", file.getTargetURI().toString()); - assertEquals("/xl/worksheets/sheet1.xml", file.getSourceURI().toString()); - assertEquals(HYPERLINK_REL_TYPE, file.getRelationshipType()); - - // Will get ids 7, 8 and 9, as we already have 1-6 - assertEquals("rId7", openxml4j.getId()); - assertEquals("rId8", sf.getId()); - assertEquals("rId9", file.getId()); - - - // Write out and re-load - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - pkg.save(baos); - - // use revert to not re-write the input file - pkg.revert(); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - pkg = OPCPackage.open(bais); - - // Check again - sheet = pkg.getPart( - PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS)); - - assertEquals(6, sheet.getRelationshipsByType(HYPERLINK_REL_TYPE).size()); - - assertEquals("http://poi.apache.org/", - sheet.getRelationship("rId1").getTargetURI().toString()); - assertEquals("mailto:dev@poi.apache.org?subject=XSSF%20Hyperlinks", - sheet.getRelationship("rId3").getTargetURI().toString()); - - assertEquals("http://www.openxml4j.org/", - sheet.getRelationship("rId7").getTargetURI().toString()); - assertEquals("http://openxml4j.sf.net/", - sheet.getRelationship("rId8").getTargetURI().toString()); - assertEquals("MyDocument.docx", - sheet.getRelationship("rId9").getTargetURI().toString()); - } - - public void testCreateRelationsFromScratch() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - OPCPackage pkg = OPCPackage.create(baos); - - PackagePart partA = - pkg.createPart(PackagingURIHelper.createPartName("/partA"), "text/plain"); - PackagePart partB = - pkg.createPart(PackagingURIHelper.createPartName("/partB"), "image/png"); - assertNotNull(partA); - assertNotNull(partB); - - // Internal - partA.addRelationship(partB.getPartName(), TargetMode.INTERNAL, "http://example/Rel"); - - // External - partA.addExternalRelationship("http://poi.apache.org/", "http://example/poi"); - partB.addExternalRelationship("http://poi.apache.org/ss/", "http://example/poi/ss"); - - // Check as expected currently - assertEquals("/partB", partA.getRelationship("rId1").getTargetURI().toString()); - assertEquals("http://poi.apache.org/", - partA.getRelationship("rId2").getTargetURI().toString()); - assertEquals("http://poi.apache.org/ss/", - partB.getRelationship("rId1").getTargetURI().toString()); - - - // Save, and re-load - pkg.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - pkg = OPCPackage.open(bais); - - partA = pkg.getPart(PackagingURIHelper.createPartName("/partA")); - partB = pkg.getPart(PackagingURIHelper.createPartName("/partB")); - - - // Check the relations - assertEquals(2, partA.getRelationships().size()); - assertEquals(1, partB.getRelationships().size()); - - assertEquals("/partB", partA.getRelationship("rId1").getTargetURI().toString()); - assertEquals("http://poi.apache.org/", - partA.getRelationship("rId2").getTargetURI().toString()); - assertEquals("http://poi.apache.org/ss/", - partB.getRelationship("rId1").getTargetURI().toString()); - // Check core too - assertEquals("/docProps/core.xml", - pkg.getRelationshipsByType("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties").getRelationship(0).getTargetURI().toString()); - - - // Add some more - partB.addExternalRelationship("http://poi.apache.org/new", "http://example/poi/new"); - partB.addExternalRelationship("http://poi.apache.org/alt", "http://example/poi/alt"); - - // Check the relations - assertEquals(2, partA.getRelationships().size()); - assertEquals(3, partB.getRelationships().size()); - - assertEquals("/partB", partA.getRelationship("rId1").getTargetURI().toString()); - assertEquals("http://poi.apache.org/", - partA.getRelationship("rId2").getTargetURI().toString()); - assertEquals("http://poi.apache.org/ss/", - partB.getRelationship("rId1").getTargetURI().toString()); - assertEquals("http://poi.apache.org/new", - partB.getRelationship("rId2").getTargetURI().toString()); - assertEquals("http://poi.apache.org/alt", - partB.getRelationship("rId3").getTargetURI().toString()); - } - - - public void testTargetWithSpecialChars() throws Exception{ - OPCPackage pkg; - - String filepath = OpenXML4JTestDataSamples.getSampleFileName("50154.xlsx"); - pkg = OPCPackage.open(filepath); - assert_50154(pkg); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - pkg.save(baos); - - // use revert to not re-write the input file - pkg.revert(); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - pkg = OPCPackage.open(bais); - - assert_50154(pkg); - } - - public void assert_50154(OPCPackage pkg) throws Exception { - URI drawingURI = new URI("/xl/drawings/drawing1.xml"); - PackagePart drawingPart = pkg.getPart(PackagingURIHelper.createPartName(drawingURI)); - PackageRelationshipCollection drawingRels = drawingPart.getRelationships(); - - assertEquals(6, drawingRels.size()); - - // expected one image - assertEquals(1, drawingPart.getRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image").size()); - // and three hyperlinks - assertEquals(5, drawingPart.getRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink").size()); - - PackageRelationship rId1 = drawingPart.getRelationship("rId1"); - URI parent = drawingPart.getPartName().getURI(); - URI rel1 = parent.relativize(rId1.getTargetURI()); - URI rel11 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId1.getTargetURI()); - assertEquals("'Another Sheet'!A1", rel1.getFragment()); - assertEquals("'Another Sheet'!A1", rel11.getFragment()); - - PackageRelationship rId2 = drawingPart.getRelationship("rId2"); - URI rel2 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId2.getTargetURI()); - assertEquals("../media/image1.png", rel2.getPath()); - - PackageRelationship rId3 = drawingPart.getRelationship("rId3"); - URI rel3 = parent.relativize(rId3.getTargetURI()); - assertEquals("ThirdSheet!A1", rel3.getFragment()); - - PackageRelationship rId4 = drawingPart.getRelationship("rId4"); - URI rel4 = parent.relativize(rId4.getTargetURI()); - assertEquals("'\u0410\u043F\u0430\u0447\u0435 \u041F\u041E\u0418'!A1", rel4.getFragment()); - - PackageRelationship rId5 = drawingPart.getRelationship("rId5"); - URI rel5 = parent.relativize(rId5.getTargetURI()); - // back slashed have been replaced with forward - assertEquals("file:///D:/chan-chan.mp3", rel5.toString()); - - PackageRelationship rId6 = drawingPart.getRelationship("rId6"); - URI rel6 = parent.relativize(rId6.getTargetURI()); - assertEquals("../../../../../../../cygwin/home/yegor/dinom/&&&[access].2010-10-26.log", rel6.getPath()); - assertEquals("'\u0410\u043F\u0430\u0447\u0435 \u041F\u041E\u0418'!A5", rel6.getFragment()); - } - - public void testSelfRelations_bug51187() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - OPCPackage pkg = OPCPackage.create(baos); - - PackagePart partA = - pkg.createPart(PackagingURIHelper.createPartName("/partA"), "text/plain"); - assertNotNull(partA); - - // reference itself - PackageRelationship rel1 = partA.addRelationship(partA.getPartName(), TargetMode.INTERNAL, "partA"); - - - // Save, and re-load - pkg.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - pkg = OPCPackage.open(bais); - - partA = pkg.getPart(PackagingURIHelper.createPartName("/partA")); - - - // Check the relations - assertEquals(1, partA.getRelationships().size()); - - PackageRelationship rel2 = partA.getRelationships().getRelationship(0); - - assertEquals(rel1.getRelationshipType(), rel2.getRelationshipType()); - assertEquals(rel1.getId(), rel2.getId()); - assertEquals(rel1.getSourceURI(), rel2.getSourceURI()); - assertEquals(rel1.getTargetURI(), rel2.getTargetURI()); - assertEquals(rel1.getTargetMode(), rel2.getTargetMode()); - } - - public void testTrailingSpacesInURI_53282() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("53282.xlsx"); - OPCPackage pkg = OPCPackage.open(is); - is.close(); - - PackageRelationshipCollection sheetRels = pkg.getPartsByName(Pattern.compile("/xl/worksheets/sheet1.xml")).get(0).getRelationships(); - assertEquals(3, sheetRels.size()); - PackageRelationship rId1 = sheetRels.getRelationshipByID("rId1"); - assertEquals(TargetMode.EXTERNAL, rId1.getTargetMode()); - URI targetUri = rId1.getTargetURI(); - assertEquals("mailto:nobody@nowhere.uk%C2%A0", targetUri.toASCIIString()); - assertEquals("nobody@nowhere.uk\u00A0", targetUri.getSchemeSpecificPart()); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - pkg.save(out); - out.close(); - - pkg = OPCPackage.open(new ByteArrayInputStream(out.toByteArray())); - sheetRels = pkg.getPartsByName(Pattern.compile("/xl/worksheets/sheet1.xml")).get(0).getRelationships(); - assertEquals(3, sheetRels.size()); - rId1 = sheetRels.getRelationshipByID("rId1"); - assertEquals(TargetMode.EXTERNAL, rId1.getTargetMode()); - targetUri = rId1.getTargetURI(); - assertEquals("mailto:nobody@nowhere.uk%C2%A0", targetUri.toASCIIString()); - assertEquals("nobody@nowhere.uk\u00A0", targetUri.getSchemeSpecificPart()); - } - - public void testEntitiesInRels_56164() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("PackageRelsHasEntities.ooxml"); - OPCPackage p = OPCPackage.open(is); - is.close(); - - // Should have 3 root relationships - boolean foundDocRel = false, foundCorePropRel = false, foundExtPropRel = false; - for (PackageRelationship pr : p.getRelationships()) { - if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_DOCUMENT)) - foundDocRel = true; - if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) - foundCorePropRel = true; - if (pr.getRelationshipType().equals(PackageRelationshipTypes.EXTENDED_PROPERTIES)) - foundExtPropRel = true; - } - assertTrue("Core/Doc Relationship not found in " + p.getRelationships(), foundDocRel); - assertTrue("Core Props Relationship not found in " + p.getRelationships(), foundCorePropRel); - assertTrue("Ext Props Relationship not found in " + p.getRelationships(), foundExtPropRel); - - // Should have normal work parts - boolean foundCoreProps = false, foundDocument = false, foundTheme1 = false; - for (PackagePart part : p.getParts()) { - if (part.getPartName().toString().equals("/docProps/core.xml")) { - assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType()); - foundCoreProps = true; - } - if (part.getPartName().toString().equals("/word/document.xml")) { - assertEquals(XWPFRelation.DOCUMENT.getContentType(), part.getContentType()); - foundDocument = true; - } - if (part.getPartName().toString().equals("/word/theme/theme1.xml")) { - assertEquals(XWPFRelation.THEME.getContentType(), part.getContentType()); - foundTheme1 = true; - } - } - assertTrue("Core not found in " + p.getParts(), foundCoreProps); - assertTrue("Document not found in " + p.getParts(), foundDocument); - assertTrue("Theme1 not found in " + p.getParts(), foundTheme1); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java deleted file mode 100644 index 0989d10cb..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java +++ /dev/null @@ -1,255 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POITextExtractor; -import org.apache.poi.POIXMLException; -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; -import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFRelation; -import org.apache.xmlbeans.XmlException; -import org.junit.Test; - -public class TestZipPackage { - @Test - public void testBug56479() throws Exception { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("dcterms_bug_56479.zip"); - OPCPackage p = OPCPackage.open(is); - - // Check we found the contents of it - boolean foundCoreProps = false, foundDocument = false, foundTheme1 = false; - for (PackagePart part : p.getParts()) { - if (part.getPartName().toString().equals("/docProps/core.xml")) { - assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType()); - foundCoreProps = true; - } - if (part.getPartName().toString().equals("/word/document.xml")) { - assertEquals(XWPFRelation.DOCUMENT.getContentType(), part.getContentType()); - foundDocument = true; - } - if (part.getPartName().toString().equals("/word/theme/theme1.xml")) { - assertEquals(XWPFRelation.THEME.getContentType(), part.getContentType()); - foundTheme1 = true; - } - } - assertTrue("Core not found in " + p.getParts(), foundCoreProps); - assertFalse("Document should not be found in " + p.getParts(), foundDocument); - assertFalse("Theme1 should not found in " + p.getParts(), foundTheme1); - p.close(); - is.close(); - } - - @Test - public void testZipEntityExpansionTerminates() throws IOException { - try { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("poc-xmlbomb.xlsx"); - wb.close(); - fail("Should catch exception due to entity expansion limitations"); - } catch (POIXMLException e) { - assertEntityLimitReached(e); - } - } - - private void assertEntityLimitReached(Exception e) throws UnsupportedEncodingException { - ByteArrayOutputStream str = new ByteArrayOutputStream(); - PrintWriter writer = new PrintWriter(new OutputStreamWriter(str, "UTF-8")); - try { - e.printStackTrace(writer); - } finally { - writer.close(); - } - String string = new String(str.toByteArray(), "UTF-8"); - assertTrue("Had: " + string, string.contains("The parser has encountered more than")); - } - - @Test - public void testZipEntityExpansionExceedsMemory() throws Exception { - try { - Workbook wb = WorkbookFactory.create(XSSFTestDataSamples.openSamplePackage("poc-xmlbomb.xlsx")); - wb.close(); - fail("Should catch exception due to entity expansion limitations"); - } catch (POIXMLException e) { - assertEntityLimitReached(e); - } - - try { - POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("poc-xmlbomb.xlsx")); - try { - assertNotNull(extractor); - - try { - extractor.getText(); - } catch (IllegalStateException e) { - // expected due to shared strings expansion - } - } finally { - extractor.close(); - } - } catch (POIXMLException e) { - assertEntityLimitReached(e); - } - } - - @Test - public void testZipEntityExpansionSharedStringTable() throws Exception { - Workbook wb = WorkbookFactory.create(XSSFTestDataSamples.openSamplePackage("poc-shared-strings.xlsx")); - wb.close(); - - POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("poc-shared-strings.xlsx")); - try { - assertNotNull(extractor); - - try { - extractor.getText(); - } catch (IllegalStateException e) { - // expected due to shared strings expansion - } - } finally { - extractor.close(); - } - } - - @Test - public void testZipEntityExpansionSharedStringTableEvents() throws Exception { - boolean before = ExtractorFactory.getThreadPrefersEventExtractors(); - ExtractorFactory.setThreadPrefersEventExtractors(true); - try { - POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("poc-shared-strings.xlsx")); - try { - assertNotNull(extractor); - - try { - extractor.getText(); - } catch (IllegalStateException e) { - // expected due to shared strings expansion - } - } finally { - extractor.close(); - } - } catch (XmlException e) { - assertEntityLimitReached(e); - } finally { - ExtractorFactory.setThreadPrefersEventExtractors(before); - } - } - - @Test - public void unparseableCentralDirectory() throws IOException { - File f = OpenXML4JTestDataSamples.getSampleFile("at.pzp.www_uploads_media_PP_Scheinecker-jdk6error.pptx"); - SlideShow ppt = SlideShowFactory.create(f, null, true); - ppt.close(); - } - - @Test - public void testClosingStreamOnException() throws IOException { - InputStream is = OpenXML4JTestDataSamples.openSampleStream("dcterms_bug_56479.zip"); - File tmp = File.createTempFile("poi-test-truncated-zip", ""); - // create a corrupted zip file by truncating a valid zip file to the first 100 bytes - OutputStream os = new FileOutputStream(tmp); - for (int i = 0; i < 100; i++) { - os.write(is.read()); - } - os.flush(); - os.close(); - is.close(); - - // feed the corrupted zip file to OPCPackage - try { - OPCPackage.open(tmp, PackageAccess.READ); - } catch (Exception e) { - // expected: the zip file is invalid - // this test does not care if open() throws an exception or not. - } - // If the stream is not closed on exception, it will keep a file descriptor to tmp, - // and requests to the OS to delete the file will fail. - assertTrue("Can't delete tmp file", tmp.delete()); - } - - /** - * If ZipPackage is passed an invalid file, a call to close - * (eg from the OPCPackage open method) should tidy up the - * stream / file the broken file is being read from. - * See bug #60128 for more - */ - @Test - public void testTidyStreamOnInvalidFile() throws Exception { - // Spreadsheet has a good mix of alternate file types - POIDataSamples files = POIDataSamples.getSpreadSheetInstance(); - - File[] notValidF = new File[] { - files.getFile("SampleSS.ods"), files.getFile("SampleSS.txt") - }; - InputStream[] notValidS = new InputStream[] { - files.openResourceAsStream("SampleSS.ods"), files.openResourceAsStream("SampleSS.txt") - }; - - for (File notValid : notValidF) { - ZipPackage pkg = new ZipPackage(notValid, PackageAccess.READ); - assertNotNull(pkg.getZipArchive()); - assertFalse(pkg.getZipArchive().isClosed()); - try { - pkg.getParts(); - fail("Shouldn't work"); - } catch (ODFNotOfficeXmlFileException e) { - } catch (NotOfficeXmlFileException ne) {} - pkg.close(); - - assertNotNull(pkg.getZipArchive()); - assertTrue(pkg.getZipArchive().isClosed()); - } - for (InputStream notValid : notValidS) { - ZipPackage pkg = new ZipPackage(notValid, PackageAccess.READ); - assertNotNull(pkg.getZipArchive()); - assertFalse(pkg.getZipArchive().isClosed()); - try { - pkg.getParts(); - fail("Shouldn't work"); - } catch (ODFNotOfficeXmlFileException e) { - } catch (NotOfficeXmlFileException ne) {} - pkg.close(); - - assertNotNull(pkg.getZipArchive()); - assertTrue(pkg.getZipArchive().isClosed()); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/ZipFileAssert.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/ZipFileAssert.java deleted file mode 100644 index c59be4525..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/ZipFileAssert.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeMap; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import junit.framework.Assert; -import junit.framework.AssertionFailedError; - -/** - * Compare the contents of 2 zip files. - * - * @author CDubettier - */ -public class ZipFileAssert { - private ZipFileAssert() { - } - - static final int BUFFER_SIZE = 2048; - - protected static boolean equals( - TreeMap file1, - TreeMap file2) { - Set listFile1 = file1.keySet(); - if (listFile1.size() == file2.keySet().size()) { - for (Iterator iter = listFile1.iterator(); iter.hasNext();) { - String fileName = (String) iter.next(); - // extract the contents for both - ByteArrayOutputStream contain2 = file2.get(fileName); - ByteArrayOutputStream contain1 = file1.get(fileName); - - if (contain2 == null) { - // file not found in archive 2 - Assert.fail(fileName + " not found in 2nd zip"); - return false; - } - // no need to check for contain1. The key come from it - - if ((fileName.endsWith(".xml")) || fileName.endsWith(".rels")) { - // we have a xml file - // TODO - // YK: the original OpenXML4J version attempted to compare xml using xmlunit (http://xmlunit.sourceforge.net), - // but POI does not depend on this library - } else { - // not xml, may be an image or other binary format - if (contain2.size() != contain1.size()) { - // not the same size - Assert.fail(fileName - + " does not have the same size in both zip:" - + contain2.size() + "!=" + contain1.size()); - return false; - } - byte array1[] = contain1.toByteArray(); - byte array2[] = contain2.toByteArray(); - for (int i = 0; i < array1.length; i++) { - if (array1[i] != array2[i]) { - Assert.fail(fileName + " differ at index:" + i); - return false; - } - } - } - } - } else { - // not the same number of files -> cannot be equals - Assert.fail("not the same number of files in zip:" - + listFile1.size() + "!=" + file2.keySet().size()); - return false; - } - return true; - } - - protected static TreeMap decompress( - File filename) throws IOException { - // store the zip content in memory - // let s assume it is not Go ;-) - TreeMap zipContent = new TreeMap(); - - byte data[] = new byte[BUFFER_SIZE]; - /* Open file to decompress */ - FileInputStream file_decompress = new FileInputStream(filename); - - /* Create a buffer for the decompressed files */ - BufferedInputStream buffi = new BufferedInputStream(file_decompress); - - /* Open the file with the buffer */ - ZipInputStream zis = new ZipInputStream(buffi); - - /* Processing entries of the zip file */ - ZipEntry entree; - int count; - while ((entree = zis.getNextEntry()) != null) { - - /* Create a array for the current entry */ - ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); - zipContent.put(entree.getName(), byteArray); - - /* copy in memory */ - while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) { - byteArray.write(data, 0, count); - } - /* Flush the buffer */ - byteArray.flush(); - byteArray.close(); - } - - zis.close(); - - return zipContent; - } - - /** - * Asserts that two files are equal. Throws an AssertionFailedError - * if they are not. - *

        - * - */ - public static void assertEquals(File expected, File actual) { - Assert.assertNotNull(expected); - Assert.assertNotNull(actual); - - Assert.assertTrue("File does not exist [" + expected.getAbsolutePath() - + "]", expected.exists()); - Assert.assertTrue("File does not exist [" + actual.getAbsolutePath() - + "]", actual.exists()); - - Assert.assertTrue("Expected file not readable", expected.canRead()); - Assert.assertTrue("Actual file not readable", actual.canRead()); - - try { - TreeMap file1 = decompress(expected); - TreeMap file2 = decompress(actual); - equals(file1, file2); - } catch (IOException e) { - throw new AssertionFailedError(e.toString()); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java deleted file mode 100644 index 311db55c2..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java +++ /dev/null @@ -1,335 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.compliance; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.TempFile; -import org.junit.Test; - -import junit.framework.AssertionFailedError; - -/** - * Test core properties Open Packaging Convention compliance. - * - * M4.1: The format designer shall specify and the format producer shall create - * at most one core properties relationship for a package. A format consumer - * shall consider more than one core properties relationship for a package to be - * an error. If present, the relationship shall target the Core Properties part. - * (POI relaxes this on reading, as Office sometimes breaks this) - * - * M4.2: The format designer shall not specify and the format producer shall not - * create Core Properties that use the Markup Compatibility namespace as defined - * in Annex F, "Standard Namespaces and Content Types". A format consumer shall - * consider the use of the Markup Compatibility namespace to be an 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: - * and Consumers shall consider a document - * element that violates this constraint to be an 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. - * - * M4.5: Producers shall not create a document element that contains the - * xsi:type attribute, except for a or - * 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. - * - * @author Julien Chable - */ -public final class TestOPCComplianceCoreProperties { - - @Test - public void testCorePropertiesPart() { - OPCPackage pkg; - try { - InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx"); - pkg = OPCPackage.open(is); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - pkg.revert(); - } - - private static String extractInvalidFormatMessage(String sampleNameSuffix) { - InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_" + sampleNameSuffix); - OPCPackage pkg; - try { - pkg = OPCPackage.open(is); - } catch (InvalidFormatException e) { - // no longer required for successful test - return e.getMessage(); - } catch (IOException e) { - throw new RuntimeException(e); - } - pkg.revert(); - throw new AssertionFailedError("expected OPC compliance exception was not thrown"); - } - - /** - * Test M4.1 rule. - */ - @Test - public void testOnlyOneCorePropertiesPart() throws Exception { - // We have relaxed this check, so we can read the file anyway - try { - extractInvalidFormatMessage("OnlyOneCorePropertiesPartFAIL.docx"); - fail("M4.1 should be being relaxed"); - } catch (AssertionFailedError e) { - // expected here - } - - // We will use the first core properties, and ignore the others - InputStream is = OpenXML4JTestDataSamples.openSampleStream("MultipleCoreProperties.docx"); - OPCPackage pkg = OPCPackage.open(is); - - // We can see 2 by type - assertEquals(2, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - // But only the first one by relationship - assertEquals(1, pkg.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES).size()); - // It should be core.xml not the older core1.xml - assertEquals( - "/docProps/core.xml", - pkg.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES).get(0).getPartName().toString() - ); - } - - private static URI createURI(String text) { - try { - return new URI(text); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - /** - * Test M4.1 rule. - */ - @Test - public void testOnlyOneCorePropertiesPart_AddRelationship() { - InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx"); - OPCPackage pkg; - try { - pkg = OPCPackage.open(is); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - URI partUri = createURI("/docProps/core2.xml"); - try { - pkg.addRelationship(PackagingURIHelper.createPartName(partUri), TargetMode.INTERNAL, - PackageRelationshipTypes.CORE_PROPERTIES); - // no longer fail on compliance error - //fail("expected OPC compliance exception was not thrown"); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } catch (InvalidOperationException e) { - // expected during successful test - assertEquals("OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead.", e.getMessage()); - } - pkg.revert(); - } - - /** - * Test M4.1 rule. - */ - @Test - public void testOnlyOneCorePropertiesPart_AddPart() throws InvalidFormatException { - String sampleFileName = "OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx"; - OPCPackage pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath()); - - URI partUri = createURI("/docProps/core2.xml"); - try { - pkg.createPart(PackagingURIHelper.createPartName(partUri), - ContentTypes.CORE_PROPERTIES_PART); - // no longer fail on compliance error - //fail("expected OPC compliance exception was not thrown"); - } catch (InvalidOperationException e) { - // expected during successful test - assertEquals("OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !", e.getMessage()); - } - pkg.revert(); - } - - /** - * Test M4.2 rule. - */ - @Test - public void testDoNotUseCompatibilityMarkup() { - String msg = extractInvalidFormatMessage("DoNotUseCompatibilityMarkupFAIL.docx"); - assertEquals("OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.", msg); - } - - /** - * Test M4.3 rule. - */ - @Test - public void testDCTermsNamespaceLimitedUse() { - String msg = extractInvalidFormatMessage("DCTermsNamespaceLimitedUseFAIL.docx"); - assertEquals("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: and Consumers shall consider a document element that violates this constraint to be an error.", msg); - } - - /** - * Test M4.4 rule. - */ - @Test - public void testUnauthorizedXMLLangAttribute() { - String msg = extractInvalidFormatMessage("UnauthorizedXMLLangAttributeFAIL.docx"); - assertEquals("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.", msg); - } - - /** - * Test M4.5 rule. - */ - @Test - public void testLimitedXSITypeAttribute_NotPresent() { - String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_NotPresentFAIL.docx"); - assertEquals("The element 'created' must have the 'xsi:type' attribute present !", msg); - } - - /** - * Test M4.5 rule. - */ - @Test - public void testLimitedXSITypeAttribute_PresentWithUnauthorizedValue() { - String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx"); - assertEquals("The element 'modified' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF', but had 'W3CDTF' !", msg); - } - - /** - * Document with no core properties - testing at the OPC level, - * saving into a new stream - */ - @Test - public void testNoCoreProperties_saveNew() throws Exception { - String sampleFileName = "OPCCompliance_NoCoreProperties.xlsx"; - OPCPackage pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath()); - - // Verify it has empty properties - assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(pkg.getPackageProperties()); - assertNotNull(pkg.getPackageProperties().getLanguageProperty()); - assertNull(pkg.getPackageProperties().getLanguageProperty().getValue()); - - // Save and re-load - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - pkg.save(baos); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - pkg.revert(); - - pkg = OPCPackage.open(bais); - - // An Empty Properties part has been added in the save/load - assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(pkg.getPackageProperties()); - assertNotNull(pkg.getPackageProperties().getLanguageProperty()); - assertNull(pkg.getPackageProperties().getLanguageProperty().getValue()); - pkg.close(); - - // Open a new copy of it - pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath()); - - // Save and re-load, without having touched the properties yet - baos = new ByteArrayOutputStream(); - pkg.save(baos); - pkg.revert(); - - bais = new ByteArrayInputStream(baos.toByteArray()); - pkg = OPCPackage.open(bais); - - // Check that this too added empty properties without error - assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(pkg.getPackageProperties()); - assertNotNull(pkg.getPackageProperties().getLanguageProperty()); - assertNull(pkg.getPackageProperties().getLanguageProperty().getValue()); - } - - /** - * Document with no core properties - testing at the OPC level, - * from a temp-file, saving in-place - */ - @Test - public void testNoCoreProperties_saveInPlace() throws Exception { - String sampleFileName = "OPCCompliance_NoCoreProperties.xlsx"; - - // Copy this into a temp file, so we can play with it - File tmp = TempFile.createTempFile("poi-test", ".opc"); - FileOutputStream out = new FileOutputStream(tmp); - InputStream in = POIDataSamples.getOpenXML4JInstance().openResourceAsStream(sampleFileName); - IOUtils.copy( - in, - out); - out.close(); - in.close(); - - // Open it from that temp file - OPCPackage pkg = OPCPackage.open(tmp); - - // Empty properties - assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(pkg.getPackageProperties()); - assertNotNull(pkg.getPackageProperties().getLanguageProperty()); - assertNull(pkg.getPackageProperties().getLanguageProperty().getValue()); - - // Save and close - pkg.close(); - - // Re-open and check - pkg = OPCPackage.open(tmp); - - // An Empty Properties part has been added in the save/load - assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(pkg.getPackageProperties()); - assertNotNull(pkg.getPackageProperties().getLanguageProperty()); - assertNull(pkg.getPackageProperties().getLanguageProperty().getValue()); - - // Finish and tidy - pkg.revert(); - assertTrue(tmp.delete()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePackageModel.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePackageModel.java deleted file mode 100644 index 7cf9e4b95..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePackageModel.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.compliance; - -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.InvalidOperationException; -import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.junit.Test; - -/** - * Test Open Packaging Convention package model compliance. - * - * 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. - * - * @author Julien Chable - */ -public class TestOPCCompliancePackageModel { - - /** - * A package implementer shall neither create nor recognize a part with a - * part name derived from another part name by appending segments to it. - * [M1.11] - */ - @Test - public void testPartNameDerivationAdditionFailure() { - OPCPackage pkg = OPCPackage.create("TODELETEIFEXIST.docx"); - try { - PackagePartName name = PackagingURIHelper - .createPartName("/word/document.xml"); - PackagePartName nameDerived = PackagingURIHelper - .createPartName("/word/document.xml/image1.gif"); - pkg.createPart(name, ContentTypes.XML); - pkg.createPart(nameDerived, ContentTypes.EXTENSION_GIF); - } catch (InvalidOperationException e) { - pkg.revert(); - return; - } catch (InvalidFormatException e) { - fail(e.getMessage()); - } - fail("A package implementer shall neither create nor recognize a part with a" - + " part name derived from another part name by appending segments to it." - + " [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. - * [M1.11] - */ - @Test - public void testPartNameDerivationReadingFailure() throws IOException { - String filename = "OPCCompliance_DerivedPartNameFAIL.docx"; - try { - OPCPackage.open(POIDataSamples.getOpenXML4JInstance().openResourceAsStream(filename)); - } catch (InvalidFormatException e) { - return; - } - fail("A package implementer shall neither create nor recognize a part with a" - + " part name derived from another part name by appending segments to it." - + " [M1.11]"); - } - - /** - * Rule M1.12 : Packages shall not contain equivalent part names and package - * implementers shall neither create nor recognize packages with equivalent - * part names. - */ - @Test - public void testAddPackageAlreadyAddFailure() throws Exception { - OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx"); - PackagePartName name1 = null; - PackagePartName name2 = null; - try { - name1 = PackagingURIHelper.createPartName("/word/document.xml"); - name2 = PackagingURIHelper.createPartName("/word/document.xml"); - } catch (InvalidFormatException e) { - throw new Exception(e.getMessage()); - } - pkg.createPart(name1, ContentTypes.XML); - try { - pkg.createPart(name2, ContentTypes.XML); - } catch (PartAlreadyExistsException e) { - return; - } - fail("Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]"); - } - - /** - * Rule M1.12 : Packages shall not contain equivalent part names and package - * implementers shall neither create nor recognize packages with equivalent - * part names. - */ - @Test - public void testAddPackageAlreadyAddFailure2() throws Exception { - OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx"); - PackagePartName partName = null; - try { - partName = PackagingURIHelper.createPartName("/word/document.xml"); - } catch (InvalidFormatException e) { - throw new Exception(e.getMessage()); - } - pkg.createPart(partName, ContentTypes.XML); - try { - pkg.createPart(partName, ContentTypes.XML); - } catch (InvalidOperationException e) { - return; - } - fail("Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]"); - } - - /** - * Try to add a relationship to a relationship part. - * - * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - */ - @Test - public void testAddRelationshipRelationshipsPartFailure() { - OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx"); - PackagePartName name1 = null; - try { - name1 = PackagingURIHelper - .createPartName("/test/_rels/document.xml.rels"); - } catch (InvalidFormatException e) { - fail("This exception should never happen !"); - } - - try { - pkg.addRelationship(name1, TargetMode.INTERNAL, - PackageRelationshipTypes.CORE_DOCUMENT); - } catch (InvalidOperationException e) { - return; - } - fail("Fail test -> M1.25: The Relationships part shall not have relationships to any other part"); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePartName.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePartName.java deleted file mode 100644 index e7754ed57..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePartName.java +++ /dev/null @@ -1,252 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.compliance; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.junit.Test; - -/** - * Test part name Open Packaging Convention compliance. - * - * (Open Packaging Convention 8.1.1 Part names) : - * - * The part name grammar is defined as follows: - * - * part_name = 1*( "/" segment ) - * - * segment = 1*( pchar ) - * - * pchar is defined in RFC 3986. - * - * The part name grammar implies the following constraints. The package - * implementer shall neither create any part that violates these constraints nor - * retrieve any data from a package as a part if the purported part name - * violates these constraints. - * - * A part name shall not be empty. [M1.1] - * - * A part name shall not have empty segments. [M1.3] - * - * A part name shall start with a forward slash ("/") character. [M1.4] - * - * A part name shall not have a forward slash as the last character. [M1.5] - * - * A segment shall not hold any characters other than pchar characters. [M1.6] - * - * Part segments have the following additional constraints. The package - * implementer shall neither create any part with a part name comprised of a - * segment that violates these constraints nor retrieve any data from a package - * as a part if the purported part name contains a segment that violates these - * constraints. - * - * A segment shall not contain percent-encoded forward slash ("/"), or backward - * slash ("\") characters. [M1.7] - * - * A segment shall not contain percent-encoded unreserved characters. [M1.8] - * - * A segment shall not end with a dot (".") character. [M1.9] - * - * A segment shall include at least one non-dot character. [M1.10] - * - * A package implementer shall neither create nor recognize a part with a part - * name derived from another part name by appending segments to it. [M1.11] - * - * Part name equivalence is determined by comparing part names as - * case-insensitive ASCII strings. [M1.12] - * - * @author Julien Chable - */ -public final class TestOPCCompliancePartName { - - /** - * Test some common invalid names. - * - * A segment shall not contain percent-encoded unreserved characters. [M1.8] - */ - @Test - public void testInvalidPartNames() { - String[] invalidNames = { "/", "/xml./doc.xml", "[Content_Types].xml", "//xml/." }; - for (String s : invalidNames) { - URI uri = null; - try { - uri = new URI(s); - } catch (URISyntaxException e) { - assertTrue(s.equals("[Content_Types].xml")); - continue; - } - assertFalse("This part name SHOULD NOT be valid: " + s, - PackagingURIHelper.isValidPartName(uri)); - } - } - - /** - * Test some common valid names. - */ - @Test - public void testValidPartNames() throws URISyntaxException { - String[] validNames = { "/xml/item1.xml", "/document.xml", - "/a/%D1%86.xml" }; - for (String s : validNames) - assertTrue("This part name SHOULD be valid: " + s, - PackagingURIHelper.isValidPartName(new URI(s))); - } - - /** - * A part name shall not be empty. [M1.1] - */ - @Test - public void testEmptyPartNameFailure() throws URISyntaxException { - try { - PackagingURIHelper.createPartName(new URI("")); - fail("A part name shall not be empty. [M1.1]"); - } catch (InvalidFormatException e) { - // Normal behaviour - } - } - - /** - * A part name shall not have empty segments. [M1.3] - * - * A segment shall not end with a dot ('.') character. [M1.9] - * - * A segment shall include at least one non-dot character. [M1.10] - */ - @Test - public void testPartNameWithInvalidSegmentsFailure() { - String[] invalidNames = { "//document.xml", "//word/document.xml", - "/word//document.rels", "/word//rels//document.rels", - "/xml./doc.xml", "/document.", "/./document.xml", - "/word/./doc.rels", "/%2F/document.xml" }; - try { - for (String s : invalidNames) - assertFalse( - "A part name shall not have empty segments. [M1.3]", - PackagingURIHelper.isValidPartName(new URI(s))); - } catch (URISyntaxException e) { - fail(); - } - } - - /** - * A segment shall not hold any characters other than ipchar (RFC 3987) characters. - * [M1.6]. - */ - @Test - public void testPartNameWithNonPCharCharacters() { - String[] validNames = { "/doc&.xml" }; - try { - for (String s : validNames) - assertTrue( - "A segment shall not contain non pchar characters [M1.6] : " - + s, PackagingURIHelper - .isValidPartName(new URI(s))); - } catch (URISyntaxException e) { - fail(); - } - } - - /** - * A segment shall not contain percent-encoded unreserved characters [M1.8]. - */ - @Test - public void testPartNameWithUnreservedEncodedCharactersFailure() { - String[] invalidNames = { "/a/docum%65nt.xml" }; - try { - for (String s : invalidNames) - assertFalse( - "A segment shall not contain percent-encoded unreserved characters [M1.8] : " - + s, PackagingURIHelper - .isValidPartName(new URI(s))); - } catch (URISyntaxException e) { - fail(); - } - } - - /** - * A part name shall start with a forward slash ('/') character. [M1.4] - */ - @Test - public void testPartNameStartsWithAForwardSlashFailure() - throws URISyntaxException { - try { - PackagingURIHelper.createPartName(new URI("document.xml")); - fail("A part name shall start with a forward slash ('/') character. [M1.4]"); - } catch (InvalidFormatException e) { - // Normal behaviour - } - } - - /** - * A part name shall not have a forward slash as the last character. [M1.5] - */ - @Test - public void testPartNameEndsWithAForwardSlashFailure() - throws URISyntaxException { - try { - PackagingURIHelper.createPartName(new URI("/document.xml/")); - fail("A part name shall not have a forward slash as the last character. [M1.5]"); - } catch (InvalidFormatException e) { - // Normal behaviour - } - } - - /** - * Part name equivalence is determined by comparing part names as - * case-insensitive ASCII strings. [M1.12] - */ - @Test - public void testPartNameComparaison() throws Exception { - String[] partName1 = { "/word/document.xml", "/docProps/core.xml", "/rels/.rels" }; - String[] partName2 = { "/WORD/DocUment.XML", "/docProps/core.xml", "/rels/.rels" }; - for (int i = 0; i < partName1.length || i < partName2.length; ++i) { - PackagePartName p1 = PackagingURIHelper.createPartName(partName1[i]); - PackagePartName p2 = PackagingURIHelper.createPartName(partName2[i]); - assertTrue(p1.equals(p2)); - assertTrue(p1.compareTo(p2) == 0); - assertTrue(p1.hashCode() == p2.hashCode()); - } - } - - /** - * Part name equivalence is determined by comparing part names as - * case-insensitive ASCII strings. [M1.12]. - * - * All the comparisons MUST FAIL ! - */ - @Test - public void testPartNameComparaisonFailure() throws Exception { - String[] partName1 = { "/word/document.xml", "/docProps/core.xml", "/rels/.rels" }; - String[] partName2 = { "/WORD/DocUment.XML2", "/docProp/core.xml", "/rels/rels" }; - for (int i = 0; i < partName1.length || i < partName2.length; ++i) { - PackagePartName p1 = PackagingURIHelper.createPartName(partName1[i]); - PackagePartName p2 = PackagingURIHelper.createPartName(partName2[i]); - assertFalse(p1.equals(p2)); - assertFalse(p1.compareTo(p2) == 0); - assertFalse(p1.hashCode() == p2.hashCode()); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java deleted file mode 100644 index 936d0f9e8..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -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.PackageRelationshipTypes; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.junit.Ignore; -import org.junit.Test; - -public final class TestContentTypeManager { - - /** - * Test the properties part content parsing. - */ - @Test - public void testContentType() throws Exception { - String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx"); - - // Retrieves core properties part - OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ); - try { - PackageRelationshipCollection rels = p.getRelationshipsByType(PackageRelationshipTypes.CORE_PROPERTIES); - PackageRelationship corePropertiesRelationship = rels.getRelationship(0); - PackagePart coreDocument = p.getPart(corePropertiesRelationship); - - assertEquals("application/vnd.openxmlformats-package.core-properties+xml", coreDocument.getContentType()); - - // TODO - finish writing this test - assumeTrue("finish writing this test", false); - - ContentTypeManager ctm = new ZipContentTypeManager(coreDocument.getInputStream(), p); - assertNotNull(ctm); - } finally { - p.close(); - } - } - - /** - * Test the addition of several default and override content types. - */ - @Test - public void testContentTypeAddition() throws Exception { - ContentTypeManager ctm = new ZipContentTypeManager(null, null); - - PackagePartName name1 = PackagingURIHelper.createPartName("/foo/foo.XML"); - PackagePartName name2 = PackagingURIHelper.createPartName("/foo/foo2.xml"); - PackagePartName name3 = PackagingURIHelper.createPartName("/foo/doc.rels"); - PackagePartName name4 = PackagingURIHelper.createPartName("/foo/doc.RELS"); - - // Add content types - ctm.addContentType(name1, "foo-type1"); - ctm.addContentType(name2, "foo-type2"); - ctm.addContentType(name3, "text/xml+rel"); - ctm.addContentType(name4, "text/xml+rel"); - - assertEquals(ctm.getContentType(name1), "foo-type1"); - assertEquals(ctm.getContentType(name2), "foo-type2"); - assertEquals(ctm.getContentType(name3), "text/xml+rel"); - assertEquals(ctm.getContentType(name3), "text/xml+rel"); - } - - /** - * Test the addition then removal of content types. - */ - @Test - public void testContentTypeRemoval() throws Exception { - ContentTypeManager ctm = new ZipContentTypeManager(null, null); - - PackagePartName name1 = PackagingURIHelper.createPartName("/foo/foo.xml"); - PackagePartName name2 = PackagingURIHelper.createPartName("/foo/foo2.xml"); - PackagePartName name3 = PackagingURIHelper.createPartName("/foo/doc.rels"); - PackagePartName name4 = PackagingURIHelper.createPartName("/foo/doc.RELS"); - - // Add content types - ctm.addContentType(name1, "foo-type1"); - ctm.addContentType(name2, "foo-type2"); - ctm.addContentType(name3, "text/xml+rel"); - ctm.addContentType(name4, "text/xml+rel"); - ctm.removeContentType(name2); - ctm.removeContentType(name3); - - assertEquals(ctm.getContentType(name1), "foo-type1"); - assertEquals(ctm.getContentType(name2), "foo-type1"); - assertEquals(ctm.getContentType(name3), null); - - ctm.removeContentType(name1); - assertEquals(ctm.getContentType(name1), null); - assertEquals(ctm.getContentType(name2), null); - } - - /** - * Test the addition then removal of content types in a package. - */ - @Ignore - @Test - public void testContentTypeRemovalPackage() { - // TODO - fail("test not written"); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestZipPackagePropertiesMarshaller.java b/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestZipPackagePropertiesMarshaller.java deleted file mode 100644 index 1a4c0de4f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestZipPackagePropertiesMarshaller.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.OutputStream; - -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller; -import org.junit.Test; - -public class TestZipPackagePropertiesMarshaller { - - @Test(expected=IllegalArgumentException.class) - public void nonZipOutputStream() throws OpenXML4JException { - PartMarshaller marshaller = new ZipPackagePropertiesMarshaller(); - OutputStream notAZipOutputStream = new ByteArrayOutputStream(0); - marshaller.marshall(null, notAZipOutputStream); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/AllPOIFSCryptoTests.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/AllPOIFSCryptoTests.java deleted file mode 100644 index fd8e56a74..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/AllPOIFSCryptoTests.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - - -/** - * Tests for org.apache.poi.poifs.crypt - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TestEncryptionInfo.class - , TestDecryptor.class - , TestEncryptor.class - , TestAgileEncryptionParameters.class - , TestCertificateEncryption.class -}) -public final class AllPOIFSCryptoTests { -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java deleted file mode 100644 index afd70f08e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java +++ /dev/null @@ -1,317 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.math.BigInteger; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.cert.CRLException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.RSAKeyGenParameterSpec; -import java.util.Date; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.AuthorityInformationAccess; -import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; -import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.CRLNumber; -import org.bouncycastle.asn1.x509.CRLReason; -import org.bouncycastle.asn1.x509.DistributionPoint; -import org.bouncycastle.asn1.x509.DistributionPointName; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; -import org.bouncycastle.cert.X509CRLHolder; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.X509ExtensionUtils; -import org.bouncycastle.cert.X509v2CRLBuilder; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.ocsp.BasicOCSPResp; -import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; -import org.bouncycastle.cert.ocsp.CertificateID; -import org.bouncycastle.cert.ocsp.CertificateStatus; -import org.bouncycastle.cert.ocsp.OCSPReq; -import org.bouncycastle.cert.ocsp.OCSPReqBuilder; -import org.bouncycastle.cert.ocsp.OCSPResp; -import org.bouncycastle.cert.ocsp.OCSPRespBuilder; -import org.bouncycastle.cert.ocsp.Req; -import org.bouncycastle.cert.ocsp.RevokedStatus; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.DigestCalculator; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -public class PkiTestUtils { - - private PkiTestUtils() { - super(); - } - - static KeyPair generateKeyPair() throws Exception { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - SecureRandom random = new SecureRandom(); - keyPairGenerator.initialize(new RSAKeyGenParameterSpec(1024, - RSAKeyGenParameterSpec.F4), random); - KeyPair keyPair = keyPairGenerator.generateKeyPair(); - return keyPair; - } - - static X509Certificate generateCertificate(PublicKey subjectPublicKey, - String subjectDn, Date notBefore, Date notAfter, - X509Certificate issuerCertificate, PrivateKey issuerPrivateKey, - boolean caFlag, int pathLength, String crlUri, String ocspUri, - KeyUsage keyUsage) - throws IOException, OperatorCreationException, CertificateException - { - String signatureAlgorithm = "SHA1withRSA"; - X500Name issuerName; - if (issuerCertificate != null) { - issuerName = new X509CertificateHolder(issuerCertificate.getEncoded()).getIssuer(); - } else { - issuerName = new X500Name(subjectDn); - } - - RSAPublicKey rsaPubKey = (RSAPublicKey)subjectPublicKey; - RSAKeyParameters rsaSpec = new RSAKeyParameters(false, rsaPubKey.getModulus(), rsaPubKey.getPublicExponent()); - - SubjectPublicKeyInfo subjectPublicKeyInfo = - SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(rsaSpec); - - DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder() - .setProvider("BC").build().get(CertificateID.HASH_SHA1); - - X509v3CertificateBuilder certificateGenerator = new X509v3CertificateBuilder( - issuerName - , new BigInteger(128, new SecureRandom()) - , notBefore - , notAfter - , new X500Name(subjectDn) - , subjectPublicKeyInfo - ); - - X509ExtensionUtils exUtils = new X509ExtensionUtils(digestCalc); - SubjectKeyIdentifier subKeyId = exUtils.createSubjectKeyIdentifier(subjectPublicKeyInfo); - AuthorityKeyIdentifier autKeyId = (issuerCertificate != null) - ? exUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(issuerCertificate.getEncoded())) - : exUtils.createAuthorityKeyIdentifier(subjectPublicKeyInfo); - - certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, subKeyId); - certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, autKeyId); - - if (caFlag) { - BasicConstraints bc; - - if (-1 == pathLength) { - bc = new BasicConstraints(true); - } else { - bc = new BasicConstraints(pathLength); - } - certificateGenerator.addExtension(Extension.basicConstraints, false, bc); - } - - if (null != crlUri) { - int uri = GeneralName.uniformResourceIdentifier; - DERIA5String crlUriDer = new DERIA5String(crlUri); - GeneralName gn = new GeneralName(uri, crlUriDer); - - DERSequence gnDer = new DERSequence(gn); - GeneralNames gns = GeneralNames.getInstance(gnDer); - - DistributionPointName dpn = new DistributionPointName(0, gns); - DistributionPoint distp = new DistributionPoint(dpn, null, null); - DERSequence distpDer = new DERSequence(distp); - certificateGenerator.addExtension(Extension.cRLDistributionPoints, false, distpDer); - } - - if (null != ocspUri) { - int uri = GeneralName.uniformResourceIdentifier; - GeneralName ocspName = new GeneralName(uri, ocspUri); - - AuthorityInformationAccess authorityInformationAccess = - new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspName); - - certificateGenerator.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess); - } - - if (null != keyUsage) { - certificateGenerator.addExtension(Extension.keyUsage, true, keyUsage); - } - - JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm); - signerBuilder.setProvider("BC"); - - X509CertificateHolder certHolder = - certificateGenerator.build(signerBuilder.build(issuerPrivateKey)); - - /* - * Next certificate factory trick is needed to make sure that the - * certificate delivered to the caller is provided by the default - * security provider instead of BouncyCastle. If we don't do this trick - * we might run into trouble when trying to use the CertPath validator. - */ -// CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); -// certificate = (X509Certificate) certificateFactory -// .generateCertificate(new ByteArrayInputStream(certificate -// .getEncoded())); - return new JcaX509CertificateConverter().getCertificate(certHolder); - } - - static Document loadDocument(InputStream documentInputStream) - throws ParserConfigurationException, SAXException, IOException { - InputSource inputSource = new InputSource(documentInputStream); - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory - .newInstance(); - documentBuilderFactory.setNamespaceAware(true); - DocumentBuilder documentBuilder = documentBuilderFactory - .newDocumentBuilder(); - Document document = documentBuilder.parse(inputSource); - return document; - } - - static String toString(Node dom) throws TransformerException { - Source source = new DOMSource(dom); - StringWriter stringWriter = new StringWriter(); - Result result = new StreamResult(stringWriter); - TransformerFactory transformerFactory = TransformerFactory - .newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - /* - * We have to omit the ?xml declaration if we want to embed the - * document. - */ - transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - transformer.transform(source, result); - return stringWriter.getBuffer().toString(); - } - - public static X509CRL generateCrl(X509Certificate issuer, PrivateKey issuerPrivateKey) - throws CertificateEncodingException, IOException, CRLException, OperatorCreationException { - - X509CertificateHolder holder = new X509CertificateHolder(issuer.getEncoded()); - X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(holder.getIssuer(), new Date()); - crlBuilder.setNextUpdate(new Date(new Date().getTime() + 100000)); - JcaContentSignerBuilder contentBuilder = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC"); - - CRLNumber crlNumber = new CRLNumber(new BigInteger("1234")); - - crlBuilder.addExtension(Extension.cRLNumber, false, crlNumber); - X509CRLHolder x509Crl = crlBuilder.build(contentBuilder.build(issuerPrivateKey)); - return new JcaX509CRLConverter().setProvider("BC").getCRL(x509Crl); - } - - public static OCSPResp createOcspResp(X509Certificate certificate, - boolean revoked, X509Certificate issuerCertificate, - X509Certificate ocspResponderCertificate, - PrivateKey ocspResponderPrivateKey, String signatureAlgorithm, - long nonceTimeinMillis) - throws Exception { - DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder() - .setProvider("BC").build().get(CertificateID.HASH_SHA1); - X509CertificateHolder issuerHolder = new X509CertificateHolder(issuerCertificate.getEncoded()); - CertificateID certId = new CertificateID(digestCalc, issuerHolder, certificate.getSerialNumber()); - - // request - //create a nonce to avoid replay attack - BigInteger nonce = BigInteger.valueOf(nonceTimeinMillis); - DEROctetString nonceDer = new DEROctetString(nonce.toByteArray()); - Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, nonceDer); - Extensions exts = new Extensions(ext); - - OCSPReqBuilder ocspReqBuilder = new OCSPReqBuilder(); - ocspReqBuilder.addRequest(certId); - ocspReqBuilder.setRequestExtensions(exts); - OCSPReq ocspReq = ocspReqBuilder.build(); - - - SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo - (CertificateID.HASH_SHA1, ocspResponderCertificate.getPublicKey().getEncoded()); - - BasicOCSPRespBuilder basicOCSPRespBuilder = new BasicOCSPRespBuilder(keyInfo, digestCalc); - basicOCSPRespBuilder.setResponseExtensions(exts); - - // request processing - Req[] requestList = ocspReq.getRequestList(); - for (Req ocspRequest : requestList) { - CertificateID certificateID = ocspRequest.getCertID(); - CertificateStatus certificateStatus = CertificateStatus.GOOD; - if (revoked) { - certificateStatus = new RevokedStatus(new Date(), CRLReason.privilegeWithdrawn); - } - basicOCSPRespBuilder.addResponse(certificateID, certificateStatus); - } - - // basic response generation - X509CertificateHolder[] chain = null; - if (!ocspResponderCertificate.equals(issuerCertificate)) { - // TODO: HorribleProxy can't convert array input params yet - chain = new X509CertificateHolder[] { - new X509CertificateHolder(ocspResponderCertificate.getEncoded()), - issuerHolder - }; - } - - ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA") - .setProvider("BC").build(ocspResponderPrivateKey); - BasicOCSPResp basicOCSPResp = basicOCSPRespBuilder.build(contentSigner, chain, new Date(nonceTimeinMillis)); - - - OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder(); - OCSPResp ocspResp = ocspRespBuilder.build(OCSPRespBuilder.SUCCESSFUL, basicOCSPResp); - - return ocspResp; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java deleted file mode 100644 index 2cefa95cf..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.crypto.Cipher; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.junit.Assume; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -@RunWith(Parameterized.class) -public class TestAgileEncryptionParameters { - - static byte testData[]; - - @Parameter(value = 0) - public CipherAlgorithm ca; - @Parameter(value = 1) - public HashAlgorithm ha; - @Parameter(value = 2) - public ChainingMode cm; - - @Parameters(name="{0} {1} {2}") - public static Collection data() { - CipherAlgorithm caList[] = { CipherAlgorithm.aes128, CipherAlgorithm.aes192, CipherAlgorithm.aes256, CipherAlgorithm.rc2, CipherAlgorithm.des, CipherAlgorithm.des3 }; - HashAlgorithm haList[] = { HashAlgorithm.sha1, HashAlgorithm.sha256, HashAlgorithm.sha384, HashAlgorithm.sha512, HashAlgorithm.md5 }; - ChainingMode cmList[] = { ChainingMode.cbc, ChainingMode.cfb }; - - List data = new ArrayList(); - for (CipherAlgorithm ca : caList) { - for (HashAlgorithm ha : haList) { - for (ChainingMode cm : cmList) { - data.add(new Object[]{ca,ha,cm}); - } - } - } - - return data; - } - - @BeforeClass - public static void initTestData() throws Exception { - InputStream testFile = POIDataSamples.getDocumentInstance().openResourceAsStream("SampleDoc.docx"); - testData = IOUtils.toByteArray(testFile); - testFile.close(); - } - - @Test - public void testAgileEncryptionModes() throws Exception { - int maxKeyLen = Cipher.getMaxAllowedKeyLength(ca.jceId); - Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files", maxKeyLen >= ca.defaultKeySize); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - POIFSFileSystem fsEnc = new POIFSFileSystem(); - EncryptionInfo infoEnc = new EncryptionInfo(EncryptionMode.agile, ca, ha, -1, -1, cm); - Encryptor enc = infoEnc.getEncryptor(); - enc.confirmPassword("foobaa"); - OutputStream os = enc.getDataStream(fsEnc); - os.write(testData); - os.close(); - bos.reset(); - fsEnc.writeFilesystem(bos); - fsEnc.close(); - - POIFSFileSystem fsDec = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray())); - EncryptionInfo infoDec = new EncryptionInfo(fsDec); - Decryptor dec = infoDec.getDecryptor(); - boolean passed = dec.verifyPassword("foobaa"); - assertTrue(passed); - InputStream is = dec.getDataStream(fsDec); - byte actualData[] = IOUtils.toByteArray(is); - is.close(); - fsDec.close(); - assertArrayEquals("Failed roundtrip - "+ca+"-"+ha+"-"+cm, testData, actualData); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java deleted file mode 100644 index d48fb0da3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.X509Certificate; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.poifs.crypt.agile.AgileDecryptor; -import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.junit.Test; - -/* -import org.junit.BeforeClass; -import java.util.Date; -import java.math.BigInteger; -import java.security.KeyPairGenerator; -import java.security.SecureRandom; -import java.security.cert.Certificate; -import sun.security.x509.AlgorithmId; -import sun.security.x509.CertificateAlgorithmId; -import sun.security.x509.CertificateIssuerName; -import sun.security.x509.CertificateSerialNumber; -import sun.security.x509.CertificateSubjectName; -import sun.security.x509.CertificateValidity; -import sun.security.x509.CertificateVersion; -import sun.security.x509.CertificateX509Key; -import sun.security.x509.X500Name; -import sun.security.x509.X509CertImpl; -import sun.security.x509.X509CertInfo; -*/ - -/** - * @see creating a self-signed certificate - */ -public class TestCertificateEncryption { - /** - * how many days from now the Certificate is valid for - */ - static final int days = 1000; - /** - * the signing algorithm, eg "SHA1withRSA" - */ - static final String algorithm = "SHA1withRSA"; - static final String password = "foobaa"; - static final String certAlias = "poitest"; - /** - * the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB" - */ - static final String certDN = "CN=poitest"; - // static final File pfxFile = TempFile.createTempFile("poitest", ".pfx"); - static byte pfxFileBytes[]; - - static class CertData { - KeyPair keypair; - X509Certificate x509; - } - - /** - * Create a self-signed X.509 Certificate - * - * The keystore generation / loading is split, because normally the keystore would - * already exist. - */ - /* @BeforeClass - public static void initKeystore() throws GeneralSecurityException, IOException { - CertData certData = new CertData(); - - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(1024); - certData.keypair = keyGen.generateKeyPair(); - PrivateKey privkey = certData.keypair.getPrivate(); - PublicKey publkey = certData.keypair.getPublic(); - - X509CertInfo info = new X509CertInfo(); - Date from = new Date(); - Date to = new Date(from.getTime() + days * 86400000l); - CertificateValidity interval = new CertificateValidity(from, to); - BigInteger sn = new BigInteger(64, new SecureRandom()); - X500Name owner = new X500Name(certDN); - - info.set(X509CertInfo.VALIDITY, interval); - info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); - info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); - info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); - info.set(X509CertInfo.KEY, new CertificateX509Key(publkey)); - info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); - AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); - info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo)); - - // Sign the cert to identify the algorithm that's used. - X509CertImpl cert = new X509CertImpl(info); - cert.sign(privkey, algorithm); - - // Update the algorith, and resign. - algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG); - info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo); - cert = new X509CertImpl(info); - cert.sign(privkey, algorithm); - certData.x509 = cert; - - KeyStore keystore = KeyStore.getInstance("PKCS12"); - keystore.load(null, password.toCharArray()); - keystore.setKeyEntry(certAlias, certData.keypair.getPrivate(), password.toCharArray(), new Certificate[]{certData.x509}); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - keystore.store(bos, password.toCharArray()); - pfxFileBytes = bos.toByteArray(); - } */ - - public CertData loadKeystore() - throws GeneralSecurityException, IOException { - KeyStore keystore = KeyStore.getInstance("PKCS12"); - - // InputStream fis = new ByteArrayInputStream(pfxFileBytes); - InputStream fis = POIDataSamples.getPOIFSInstance().openResourceAsStream("poitest.pfx"); - keystore.load(fis, password.toCharArray()); - fis.close(); - - X509Certificate x509 = (X509Certificate)keystore.getCertificate(certAlias); - PrivateKey privateKey = (PrivateKey)keystore.getKey(certAlias, password.toCharArray()); - PublicKey publicKey = x509.getPublicKey(); - - CertData certData = new CertData(); - certData.keypair = new KeyPair(publicKey, privateKey); - certData.x509 = x509; - - return certData; - } - - @Test - public void testCertificateEncryption() throws Exception { - POIFSFileSystem fs = new POIFSFileSystem(); - EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile, CipherAlgorithm.aes128, HashAlgorithm.sha1, -1, -1, ChainingMode.cbc); - AgileEncryptionVerifier aev = (AgileEncryptionVerifier)info.getVerifier(); - CertData certData = loadKeystore(); - aev.addCertificate(certData.x509); - - Encryptor enc = info.getEncryptor(); - enc.confirmPassword("foobaa"); - - File file = POIDataSamples.getDocumentInstance().getFile("VariousPictures.docx"); - InputStream fis = new FileInputStream(file); - byte byteExpected[] = IOUtils.toByteArray(fis); - fis.close(); - - OutputStream os = enc.getDataStream(fs); - IOUtils.copy(new ByteArrayInputStream(byteExpected), os); - os.close(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - fs.writeFilesystem(bos); - bos.close(); - - fs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray())); - info = new EncryptionInfo(fs); - AgileDecryptor agDec = (AgileDecryptor)info.getDecryptor(); - boolean passed = agDec.verifyPassword(certData.keypair, certData.x509); - assertTrue("certificate verification failed", passed); - - fis = agDec.getDataStream(fs); - byte byteActual[] = IOUtils.toByteArray(fis); - fis.close(); - - assertThat(byteExpected, equalTo(byteActual)); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java deleted file mode 100644 index e17e2dcb8..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java +++ /dev/null @@ -1,185 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import javax.crypto.Cipher; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Assume; -import org.junit.Test; - -public class TestDecryptor { - @Test - public void passwordVerification() throws IOException, GeneralSecurityException { - POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - - EncryptionInfo info = new EncryptionInfo(fs); - - Decryptor d = Decryptor.getInstance(info); - - assertTrue(d.verifyPassword(Decryptor.DEFAULT_PASSWORD)); - } - - @Test - public void decrypt() throws IOException, GeneralSecurityException { - POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - - EncryptionInfo info = new EncryptionInfo(fs); - - Decryptor d = Decryptor.getInstance(info); - - d.verifyPassword(Decryptor.DEFAULT_PASSWORD); - - zipOk(fs.getRoot(), d); - } - - @Test - public void agile() throws IOException, GeneralSecurityException { - POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_agile.docx")); - - EncryptionInfo info = new EncryptionInfo(fs); - - assertTrue(info.getVersionMajor() == 4 && info.getVersionMinor() == 4); - - Decryptor d = Decryptor.getInstance(info); - - assertTrue(d.verifyPassword(Decryptor.DEFAULT_PASSWORD)); - - zipOk(fs.getRoot(), d); - } - - private void zipOk(DirectoryNode root, Decryptor d) throws IOException, GeneralSecurityException { - ZipInputStream zin = new ZipInputStream(d.getDataStream(root)); - - while (true) { - ZipEntry entry = zin.getNextEntry(); - if (entry==null) break; - // crc32 is checked within zip-stream - if (entry.isDirectory()) continue; - zin.skip(entry.getSize()); - byte buf[] = new byte[10]; - int readBytes = zin.read(buf); - // zin.available() doesn't work for entries - assertEquals("size failed for "+entry.getName(), -1, readBytes); - } - - zin.close(); - } - - @Test - public void dataLength() throws Exception { - POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_agile.docx")); - - EncryptionInfo info = new EncryptionInfo(fs); - - Decryptor d = Decryptor.getInstance(info); - - d.verifyPassword(Decryptor.DEFAULT_PASSWORD); - - InputStream is = d.getDataStream(fs); - - long len = d.getLength(); - assertEquals(12810, len); - - byte[] buf = new byte[(int)len]; - - is.read(buf); - - ZipInputStream zin = new ZipInputStream(new ByteArrayInputStream(buf)); - - while (true) { - ZipEntry entry = zin.getNextEntry(); - if (entry==null) { - break; - } - - while (zin.available()>0) { - zin.skip(zin.available()); - } - } - } - - @Test - public void bug57080() throws Exception { - // the test file contains a wrong ole entry size, produced by extenxls - // the fix limits the available size and tries to read all entries - File f = POIDataSamples.getPOIFSInstance().getFile("extenxls_pwd123.xlsx"); - NPOIFSFileSystem fs = new NPOIFSFileSystem(f, true); - EncryptionInfo info = new EncryptionInfo(fs); - Decryptor d = Decryptor.getInstance(info); - d.verifyPassword("pwd123"); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ZipInputStream zis = new ZipInputStream(d.getDataStream(fs)); - ZipEntry ze; - while ((ze = zis.getNextEntry()) != null) { - bos.reset(); - IOUtils.copy(zis, bos); - assertEquals(ze.getSize(), bos.size()); - } - - zis.close(); - fs.close(); - } - - @Test - public void test58616() throws IOException, GeneralSecurityException { - POIFSFileSystem pfs = new POIFSFileSystem(new FileInputStream(XSSFTestDataSamples.getSampleFile("58616.xlsx"))); - EncryptionInfo info = new EncryptionInfo(pfs); - Decryptor dec = Decryptor.getInstance(info); - //dec.verifyPassword(null); - dec.getDataStream(pfs); - } - - @Test - public void bug60320() throws IOException, GeneralSecurityException { - int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); - Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647); - - InputStream is = POIDataSamples.getPOIFSInstance().openResourceAsStream("60320-protected.xlsx"); - POIFSFileSystem fs = new POIFSFileSystem(is); - is.close(); - - EncryptionInfo info = new EncryptionInfo(fs); - - Decryptor d = Decryptor.getInstance(info); - - boolean b = d.verifyPassword("Test001!!"); - assertTrue(b); - - zipOk(fs.getRoot(), d); - - fs.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java deleted file mode 100644 index 204c2ed62..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.junit.Test; - -public class TestEncryptionInfo { - @Test - public void testEncryptionInfo() throws IOException { - POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - - EncryptionInfo info = new EncryptionInfo(fs); - - assertEquals(3, info.getVersionMajor()); - assertEquals(2, info.getVersionMinor()); - - assertEquals(CipherAlgorithm.aes128, info.getHeader().getCipherAlgorithm()); - assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithm()); - assertEquals(128, info.getHeader().getKeySize()); - assertEquals(32, info.getVerifier().getEncryptedVerifierHash().length); - assertEquals(CipherProvider.aes, info.getHeader().getCipherProvider()); - assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName()); - - fs.close(); - } - - @Test - public void testEncryptionInfoSHA512() throws Exception { - POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_sha512.xlsx")); - - EncryptionInfo info = new EncryptionInfo(fs); - - assertEquals(4, info.getVersionMajor()); - assertEquals(4, info.getVersionMinor()); - - assertEquals(CipherAlgorithm.aes256, info.getHeader().getCipherAlgorithm()); - assertEquals(HashAlgorithm.sha512, info.getHeader().getHashAlgorithm()); - assertEquals(256, info.getHeader().getKeySize()); - assertEquals(64, info.getVerifier().getEncryptedVerifierHash().length); - assertEquals(CipherProvider.aes, info.getHeader().getCipherProvider()); -// assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName()); - - fs.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java deleted file mode 100644 index 4a411cc3d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java +++ /dev/null @@ -1,525 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.poifs.crypt; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Iterator; - -import javax.crypto.Cipher; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.agile.AgileDecryptor; -import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader; -import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentNode; -import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.BoundedInputStream; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.TempFile; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.junit.Assume; -import org.junit.Ignore; -import org.junit.Test; - -public class TestEncryptor { - @Test - public void binaryRC4Encryption() throws Exception { - // please contribute a real sample file, which is binary rc4 encrypted - // ... at least the output can be opened in Excel Viewer - String password = "pass"; - - InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleMultiCell.xlsx"); - ByteArrayOutputStream payloadExpected = new ByteArrayOutputStream(); - IOUtils.copy(is, payloadExpected); - is.close(); - - POIFSFileSystem fs = new POIFSFileSystem(); - EncryptionInfo ei = new EncryptionInfo(EncryptionMode.binaryRC4); - Encryptor enc = ei.getEncryptor(); - enc.confirmPassword(password); - - OutputStream os = enc.getDataStream(fs.getRoot()); - payloadExpected.writeTo(os); - os.close(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - fs.writeFilesystem(bos); - - fs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray())); - ei = new EncryptionInfo(fs); - Decryptor dec = ei.getDecryptor(); - boolean b = dec.verifyPassword(password); - assertTrue(b); - - ByteArrayOutputStream payloadActual = new ByteArrayOutputStream(); - is = dec.getDataStream(fs.getRoot()); - IOUtils.copy(is,payloadActual); - is.close(); - - assertArrayEquals(payloadExpected.toByteArray(), payloadActual.toByteArray()); - } - - @Test - public void agileEncryption() throws Exception { - int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); - Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647); - - File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-pass.docx"); - String pass = "pass"; - NPOIFSFileSystem nfs = new NPOIFSFileSystem(file); - - // Check the encryption details - EncryptionInfo infoExpected = new EncryptionInfo(nfs); - Decryptor decExpected = Decryptor.getInstance(infoExpected); - boolean passed = decExpected.verifyPassword(pass); - assertTrue("Unable to process: document is encrypted", passed); - - // extract the payload - InputStream is = decExpected.getDataStream(nfs); - byte payloadExpected[] = IOUtils.toByteArray(is); - is.close(); - - long decPackLenExpected = decExpected.getLength(); - assertEquals(decPackLenExpected, payloadExpected.length); - - is = nfs.getRoot().createDocumentInputStream(Decryptor.DEFAULT_POIFS_ENTRY); - is = new BoundedInputStream(is, is.available()-16); // ignore padding block - byte encPackExpected[] = IOUtils.toByteArray(is); - is.close(); - - // listDir(nfs.getRoot(), "orig", ""); - - nfs.close(); - - // check that same verifier/salt lead to same hashes - byte verifierSaltExpected[] = infoExpected.getVerifier().getSalt(); - byte verifierExpected[] = decExpected.getVerifier(); - byte keySalt[] = infoExpected.getHeader().getKeySalt(); - byte keySpec[] = decExpected.getSecretKey().getEncoded(); - byte integritySalt[] = decExpected.getIntegrityHmacKey(); - // the hmacs of the file always differ, as we use PKCS5-padding to pad the bytes - // whereas office just uses random bytes - // byte integrityHash[] = d.getIntegrityHmacValue(); - - POIFSFileSystem fs = new POIFSFileSystem(); - EncryptionInfo infoActual = new EncryptionInfo( - EncryptionMode.agile - , infoExpected.getVerifier().getCipherAlgorithm() - , infoExpected.getVerifier().getHashAlgorithm() - , infoExpected.getHeader().getKeySize() - , infoExpected.getHeader().getBlockSize() - , infoExpected.getVerifier().getChainingMode() - ); - - Encryptor e = Encryptor.getInstance(infoActual); - e.confirmPassword(pass, keySpec, keySalt, verifierExpected, verifierSaltExpected, integritySalt); - - OutputStream os = e.getDataStream(fs); - IOUtils.copy(new ByteArrayInputStream(payloadExpected), os); - os.close(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - fs.writeFilesystem(bos); - - nfs = new NPOIFSFileSystem(new ByteArrayInputStream(bos.toByteArray())); - infoActual = new EncryptionInfo(nfs.getRoot()); - Decryptor decActual = Decryptor.getInstance(infoActual); - passed = decActual.verifyPassword(pass); - assertTrue("Unable to process: document is encrypted", passed); - - // extract the payload - is = decActual.getDataStream(nfs); - byte payloadActual[] = IOUtils.toByteArray(is); - is.close(); - - long decPackLenActual = decActual.getLength(); - - is = nfs.getRoot().createDocumentInputStream(Decryptor.DEFAULT_POIFS_ENTRY); - is = new BoundedInputStream(is, is.available()-16); // ignore padding block - byte encPackActual[] = IOUtils.toByteArray(is); - is.close(); - - // listDir(nfs.getRoot(), "copy", ""); - - nfs.close(); - - AgileEncryptionHeader aehExpected = (AgileEncryptionHeader)infoExpected.getHeader(); - AgileEncryptionHeader aehActual = (AgileEncryptionHeader)infoActual.getHeader(); - assertArrayEquals(aehExpected.getEncryptedHmacKey(), aehActual.getEncryptedHmacKey()); - assertEquals(decPackLenExpected, decPackLenActual); - assertArrayEquals(payloadExpected, payloadActual); - assertArrayEquals(encPackExpected, encPackActual); - } - - @Test - public void standardEncryption() throws Exception { - File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-solrcell.docx"); - String pass = "solrcell"; - - NPOIFSFileSystem nfs = new NPOIFSFileSystem(file); - - // Check the encryption details - EncryptionInfo infoExpected = new EncryptionInfo(nfs); - Decryptor d = Decryptor.getInstance(infoExpected); - boolean passed = d.verifyPassword(pass); - assertTrue("Unable to process: document is encrypted", passed); - - // extract the payload - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - InputStream is = d.getDataStream(nfs); - IOUtils.copy(is, bos); - is.close(); - nfs.close(); - byte payloadExpected[] = bos.toByteArray(); - - // check that same verifier/salt lead to same hashes - byte verifierSaltExpected[] = infoExpected.getVerifier().getSalt(); - byte verifierExpected[] = d.getVerifier(); - byte keySpec[] = d.getSecretKey().getEncoded(); - byte keySalt[] = infoExpected.getHeader().getKeySalt(); - - - EncryptionInfo infoActual = new EncryptionInfo( - EncryptionMode.standard - , infoExpected.getVerifier().getCipherAlgorithm() - , infoExpected.getVerifier().getHashAlgorithm() - , infoExpected.getHeader().getKeySize() - , infoExpected.getHeader().getBlockSize() - , infoExpected.getVerifier().getChainingMode() - ); - - Encryptor e = Encryptor.getInstance(infoActual); - e.confirmPassword(pass, keySpec, keySalt, verifierExpected, verifierSaltExpected, null); - - assertArrayEquals(infoExpected.getVerifier().getEncryptedVerifier(), infoActual.getVerifier().getEncryptedVerifier()); - assertArrayEquals(infoExpected.getVerifier().getEncryptedVerifierHash(), infoActual.getVerifier().getEncryptedVerifierHash()); - - // now we use a newly generated salt/verifier and check - // if the file content is still the same - - infoActual = new EncryptionInfo( - EncryptionMode.standard - , infoExpected.getVerifier().getCipherAlgorithm() - , infoExpected.getVerifier().getHashAlgorithm() - , infoExpected.getHeader().getKeySize() - , infoExpected.getHeader().getBlockSize() - , infoExpected.getVerifier().getChainingMode() - ); - - e = Encryptor.getInstance(infoActual); - e.confirmPassword(pass); - - POIFSFileSystem fs = new POIFSFileSystem(); - OutputStream os = e.getDataStream(fs); - IOUtils.copy(new ByteArrayInputStream(payloadExpected), os); - os.close(); - - bos.reset(); - fs.writeFilesystem(bos); - - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - - // FileOutputStream fos = new FileOutputStream("encrypted.docx"); - // IOUtils.copy(bis, fos); - // fos.close(); - // bis.reset(); - - nfs = new NPOIFSFileSystem(bis); - infoExpected = new EncryptionInfo(nfs); - d = Decryptor.getInstance(infoExpected); - passed = d.verifyPassword(pass); - assertTrue("Unable to process: document is encrypted", passed); - - bos.reset(); - is = d.getDataStream(nfs); - IOUtils.copy(is, bos); - is.close(); - nfs.close(); - byte payloadActual[] = bos.toByteArray(); - - assertArrayEquals(payloadExpected, payloadActual); - } - - /** - * Ensure we can encrypt a package that is missing the Core - * Properties, eg one from dodgy versions of Jasper Reports - * See https://github.com/nestoru/xlsxenc/ and - * http://stackoverflow.com/questions/28593223 - */ - @Test - public void encryptPackageWithoutCoreProperties() throws Exception { - // Open our file without core properties - File inp = POIDataSamples.getOpenXML4JInstance().getFile("OPCCompliance_NoCoreProperties.xlsx"); - OPCPackage pkg = OPCPackage.open(inp.getPath()); - - // It doesn't have any core properties yet - assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(pkg.getPackageProperties()); - assertNotNull(pkg.getPackageProperties().getLanguageProperty()); - assertNull(pkg.getPackageProperties().getLanguageProperty().getValue()); - - // Encrypt it - EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile); - NPOIFSFileSystem fs = new NPOIFSFileSystem(); - - Encryptor enc = info.getEncryptor(); - enc.confirmPassword("password"); - OutputStream os = enc.getDataStream(fs); - pkg.save(os); - pkg.revert(); - - // Save the resulting OLE2 document, and re-open it - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - fs.writeFilesystem(baos); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - NPOIFSFileSystem inpFS = new NPOIFSFileSystem(bais); - - // Check we can decrypt it - info = new EncryptionInfo(inpFS); - Decryptor d = Decryptor.getInstance(info); - assertEquals(true, d.verifyPassword("password")); - - OPCPackage inpPkg = OPCPackage.open(d.getDataStream(inpFS)); - - // Check it now has empty core properties - assertEquals(1, inpPkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size()); - assertNotNull(inpPkg.getPackageProperties()); - assertNotNull(inpPkg.getPackageProperties().getLanguageProperty()); - assertNull(inpPkg.getPackageProperties().getLanguageProperty().getValue()); - } - - @Test - @Ignore - public void inPlaceRewrite() throws Exception { - File f = TempFile.createTempFile("protected_agile", ".docx"); - // File f = new File("protected_agile.docx"); - FileOutputStream fos = new FileOutputStream(f); - InputStream fis = POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_agile.docx"); - IOUtils.copy(fis, fos); - fis.close(); - fos.close(); - - NPOIFSFileSystem fs = new NPOIFSFileSystem(f, false); - - // decrypt the protected file - in this case it was encrypted with the default password - EncryptionInfo encInfo = new EncryptionInfo(fs); - Decryptor d = encInfo.getDecryptor(); - boolean b = d.verifyPassword(Decryptor.DEFAULT_PASSWORD); - assertTrue(b); - - // do some strange things with it ;) - XWPFDocument docx = new XWPFDocument(d.getDataStream(fs)); - docx.getParagraphArray(0).insertNewRun(0).setText("POI was here! All your base are belong to us!"); - docx.getParagraphArray(0).insertNewRun(1).addBreak(); - - // and encrypt it again - Encryptor e = encInfo.getEncryptor(); - e.confirmPassword("AYBABTU"); - docx.write(e.getDataStream(fs)); - - fs.close(); - } - - - private void listEntry(DocumentNode de, String ext, String path) throws IOException { - path += "\\" + de.getName().replaceAll("[\\p{Cntrl}]", "_"); - System.out.println(ext+": "+path+" ("+de.getSize()+" bytes)"); - - String name = de.getName().replaceAll("[\\p{Cntrl}]", "_"); - - InputStream is = ((DirectoryNode)de.getParent()).createDocumentInputStream(de); - FileOutputStream fos = new FileOutputStream("solr."+name+"."+ext); - IOUtils.copy(is, fos); - fos.close(); - is.close(); - } - - @SuppressWarnings("unused") - private void listDir(DirectoryNode dn, String ext, String path) throws IOException { - path += "\\" + dn.getName().replace('\u0006', '_'); - System.out.println(ext+": "+path+" ("+dn.getStorageClsid()+")"); - - Iterator iter = dn.getEntries(); - while (iter.hasNext()) { - Entry ent = iter.next(); - if (ent instanceof DirectoryNode) { - listDir((DirectoryNode)ent, ext, path); - } else { - listEntry((DocumentNode)ent, ext, path); - } - } - } - - /* - * this test simulates the generation of bugs 60320 sample file - * as the padding bytes of the EncryptedPackage stream are random or in POIs case PKCS5-padded - * one would need to mock those bytes to get the same hmacValues - see diff below - * - * this use-case is experimental - for the time being the setters of the encryption classes - * are spreaded between two packages and are protected - so you would need to violate - * the packages rules and provide a helper class in the *poifs.crypt package-namespace. - * the default way of defining the encryption settings is via the EncryptionInfo class - */ - @Test - public void bug60320CustomEncrypt() throws Exception { - int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); - Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647); - - // --- src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java (revision 1766745) - // +++ src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java (working copy) - // @@ -208,6 +208,13 @@ - // protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException { - // byte plain[] = (_plainByteFlags.isEmpty()) ? null : _chunk.clone(); - // - // + if (posInChunk < 4096) { - // + _cipher.update(_chunk, 0, posInChunk, _chunk); - // + byte bla[] = { (byte)0x7A,(byte)0x0F,(byte)0x27,(byte)0xF0,(byte)0x17,(byte)0x6E,(byte)0x77,(byte)0x05,(byte)0xB9,(byte)0xDA,(byte)0x49,(byte)0xF9,(byte)0xD7,(byte)0x8E,(byte)0x03,(byte)0x1D }; - // + System.arraycopy(bla, 0, _chunk, posInChunk-2, bla.length); - // + return posInChunk-2+bla.length; - // + } - // + - // int ciLen = (doFinal) - // ? _cipher.doFinal(_chunk, 0, posInChunk, _chunk) - // : _cipher.update(_chunk, 0, posInChunk, _chunk); - // - // --- src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java (revision 1766745) - // +++ src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java (working copy) - // - // @@ -300,7 +297,7 @@ - // protected static Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk, EncryptionInfo encryptionInfo, SecretKey skey, int encryptionMode) - // throws GeneralSecurityException { - // EncryptionHeader header = encryptionInfo.getHeader(); - // - String padding = (lastChunk ? "PKCS5Padding" : "NoPadding"); - // + String padding = "NoPadding"; // (lastChunk ? "PKCS5Padding" : "NoPadding"); - // if (existing == null || !existing.getAlgorithm().endsWith(padding)) { - // existing = getCipher(skey, header.getCipherAlgorithm(), header.getChainingMode(), header.getKeySalt(), encryptionMode, padding); - // } - - InputStream is = POIDataSamples.getPOIFSInstance().openResourceAsStream("60320-protected.xlsx"); - POIFSFileSystem fsOrig = new POIFSFileSystem(is); - is.close(); - EncryptionInfo infoOrig = new EncryptionInfo(fsOrig); - Decryptor decOrig = infoOrig.getDecryptor(); - boolean b = decOrig.verifyPassword("Test001!!"); - assertTrue(b); - InputStream decIn = decOrig.getDataStream(fsOrig); - byte[] zipInput = IOUtils.toByteArray(decIn); - decIn.close(); - - InputStream epOrig = fsOrig.getRoot().createDocumentInputStream("EncryptedPackage"); - // ignore the 16 padding bytes - byte[] epOrigBytes = IOUtils.toByteArray(epOrig, 9400); - epOrig.close(); - - EncryptionInfo eiNew = new EncryptionInfo(EncryptionMode.agile); - AgileEncryptionHeader aehHeader = (AgileEncryptionHeader)eiNew.getHeader(); - aehHeader.setCipherAlgorithm(CipherAlgorithm.aes128); - aehHeader.setHashAlgorithm(HashAlgorithm.sha1); - AgileEncryptionVerifier aehVerifier = (AgileEncryptionVerifier)eiNew.getVerifier(); - - // this cast might look strange - if the setters would be public, it will become obsolete - // see http://stackoverflow.com/questions/5637650/overriding-protected-methods-in-java - ((EncryptionVerifier)aehVerifier).setCipherAlgorithm(CipherAlgorithm.aes256); - aehVerifier.setHashAlgorithm(HashAlgorithm.sha512); - - Encryptor enc = eiNew.getEncryptor(); - enc.confirmPassword("Test001!!", - infoOrig.getDecryptor().getSecretKey().getEncoded(), - infoOrig.getHeader().getKeySalt(), - infoOrig.getDecryptor().getVerifier(), - infoOrig.getVerifier().getSalt(), - infoOrig.getDecryptor().getIntegrityHmacKey() - ); - NPOIFSFileSystem fsNew = new NPOIFSFileSystem(); - OutputStream os = enc.getDataStream(fsNew); - os.write(zipInput); - os.close(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - fsNew.writeFilesystem(bos); - fsNew.close(); - - NPOIFSFileSystem fsReload = new NPOIFSFileSystem(new ByteArrayInputStream(bos.toByteArray())); - InputStream epReload = fsReload.getRoot().createDocumentInputStream("EncryptedPackage"); - byte[] epNewBytes = IOUtils.toByteArray(epReload, 9400); - epReload.close(); - - assertArrayEquals(epOrigBytes, epNewBytes); - - EncryptionInfo infoReload = new EncryptionInfo(fsOrig); - Decryptor decReload = infoReload.getDecryptor(); - b = decReload.verifyPassword("Test001!!"); - assertTrue(b); - - AgileEncryptionHeader aehOrig = (AgileEncryptionHeader)infoOrig.getHeader(); - AgileEncryptionHeader aehReload = (AgileEncryptionHeader)infoReload.getHeader(); - assertEquals(aehOrig.getBlockSize(), aehReload.getBlockSize()); - assertEquals(aehOrig.getChainingMode(), aehReload.getChainingMode()); - assertEquals(aehOrig.getCipherAlgorithm(), aehReload.getCipherAlgorithm()); - assertEquals(aehOrig.getCipherProvider(), aehReload.getCipherProvider()); - assertEquals(aehOrig.getCspName(), aehReload.getCspName()); - assertArrayEquals(aehOrig.getEncryptedHmacKey(), aehReload.getEncryptedHmacKey()); - // this only works, when the paddings are mocked to be the same ... - // assertArrayEquals(aehOrig.getEncryptedHmacValue(), aehReload.getEncryptedHmacValue()); - assertEquals(aehOrig.getFlags(), aehReload.getFlags()); - assertEquals(aehOrig.getHashAlgorithm(), aehReload.getHashAlgorithm()); - assertArrayEquals(aehOrig.getKeySalt(), aehReload.getKeySalt()); - assertEquals(aehOrig.getKeySize(), aehReload.getKeySize()); - - AgileEncryptionVerifier aevOrig = (AgileEncryptionVerifier)infoOrig.getVerifier(); - AgileEncryptionVerifier aevReload = (AgileEncryptionVerifier)infoReload.getVerifier(); - assertEquals(aevOrig.getBlockSize(), aevReload.getBlockSize()); - assertEquals(aevOrig.getChainingMode(), aevReload.getChainingMode()); - assertEquals(aevOrig.getCipherAlgorithm(), aevReload.getCipherAlgorithm()); - assertArrayEquals(aevOrig.getEncryptedKey(), aevReload.getEncryptedKey()); - assertArrayEquals(aevOrig.getEncryptedVerifier(), aevReload.getEncryptedVerifier()); - assertArrayEquals(aevOrig.getEncryptedVerifierHash(), aevReload.getEncryptedVerifierHash()); - assertEquals(aevOrig.getHashAlgorithm(), aevReload.getHashAlgorithm()); - assertEquals(aevOrig.getKeySize(), aevReload.getKeySize()); - assertArrayEquals(aevOrig.getSalt(), aevReload.getSalt()); - assertEquals(aevOrig.getSpinCount(), aevReload.getSpinCount()); - - AgileDecryptor adOrig = (AgileDecryptor)infoOrig.getDecryptor(); - AgileDecryptor adReload = (AgileDecryptor)infoReload.getDecryptor(); - - assertArrayEquals(adOrig.getIntegrityHmacKey(), adReload.getIntegrityHmacKey()); - // doesn't work without mocking ... see above - // assertArrayEquals(adOrig.getIntegrityHmacValue(), adReload.getIntegrityHmacValue()); - assertArrayEquals(adOrig.getSecretKey().getEncoded(), adReload.getSecretKey().getEncoded()); - assertArrayEquals(adOrig.getVerifier(), adReload.getVerifier()); - - fsReload.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java deleted file mode 100644 index e6224adf4..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.poifs.crypt; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; - -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.util.ZipEntrySource; -import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xmlbeans.XmlException; -import org.junit.Test; - -public class TestSecureTempZip { - /** - * Test case for #59841 - this is an example on how to use encrypted temp files, - * which are streamed into POI opposed to having everything in memory - */ - @Test - public void protectedTempZip() throws IOException, GeneralSecurityException, XmlException, OpenXML4JException { - File tikaProt = XSSFTestDataSamples.getSampleFile("protected_passtika.xlsx"); - FileInputStream fis = new FileInputStream(tikaProt); - POIFSFileSystem poifs = new POIFSFileSystem(fis); - EncryptionInfo ei = new EncryptionInfo(poifs); - Decryptor dec = ei.getDecryptor(); - boolean passOk = dec.verifyPassword("tika"); - assertTrue(passOk); - - // extract encrypted ooxml file and write to custom encrypted zip file - InputStream is = dec.getDataStream(poifs); - - // provide ZipEntrySource to poi which decrypts on the fly - ZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(is); - - // test the source - OPCPackage opc = OPCPackage.open(source); - String expected = "This is an Encrypted Excel spreadsheet."; - - XSSFEventBasedExcelExtractor extractor = new XSSFEventBasedExcelExtractor(opc); - extractor.setIncludeSheetNames(false); - String txt = extractor.getText(); - assertEquals(expected, txt.trim()); - - XSSFWorkbook wb = new XSSFWorkbook(opc); - txt = wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue(); - assertEquals(expected, txt); - - extractor.close(); - - wb.close(); - opc.close(); - source.close(); - poifs.close(); - fis.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java deleted file mode 100644 index 202b9e18e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java +++ /dev/null @@ -1,719 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/* ==================================================================== - This product contains an ASLv2 licensed version of the OOXML signer - package from the eID Applet project - http://code.google.com/p/eid-applet/source/browse/trunk/README.txt - Copyright (C) 2008-2014 FedICT. - ================================================================= */ -package org.apache.poi.poifs.crypt; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.*; -import java.security.Key; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POITestCase; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; -import org.apache.poi.poifs.crypt.dsig.DigestInfo; -import org.apache.poi.poifs.crypt.dsig.SignatureConfig; -import org.apache.poi.poifs.crypt.dsig.SignatureInfo; -import org.apache.poi.poifs.crypt.dsig.SignatureInfo.SignaturePart; -import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet; -import org.apache.poi.poifs.crypt.dsig.services.RevocationData; -import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService; -import org.apache.poi.poifs.crypt.dsig.services.TimeStampService; -import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.util.DocumentHelper; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xmlbeans.XmlObject; -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.cert.ocsp.OCSPResp; -import org.etsi.uri.x01903.v13.DigestAlgAndValueType; -import org.etsi.uri.x01903.v13.QualifyingPropertiesType; -import org.junit.Assume; -import org.junit.BeforeClass; -import org.junit.Test; -import org.w3.x2000.x09.xmldsig.ReferenceType; -import org.w3.x2000.x09.xmldsig.SignatureDocument; -import org.w3c.dom.Document; - -public class TestSignatureInfo { - private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class); - private static final POIDataSamples testdata = POIDataSamples.getXmlDSignInstance(); - - private static Calendar cal; - private KeyPair keyPair = null; - private X509Certificate x509 = null; - - @BeforeClass - public static void initBouncy() throws IOException { - CryptoFunctions.registerBouncyCastle(); - - // Set cal to now ... only set to fixed date for debugging ... - cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); - assertNotNull(cal); -// cal.set(2014, 7, 6, 21, 42, 12); -// cal.clear(Calendar.MILLISECOND); - - // don't run this test when we are using older Xerces as it triggers an XML Parser backwards compatibility issue - // in the xmlsec jar file - String additionalJar = System.getProperty("additionaljar"); - //System.out.println("Having: " + additionalJar); - Assume.assumeTrue("Not running TestSignatureInfo because we are testing with additionaljar set to " + additionalJar, - additionalJar == null || additionalJar.trim().length() == 0); - } - - @Test - public void office2007prettyPrintedRels() throws Exception { - OPCPackage pkg = OPCPackage.open(testdata.getFile("office2007prettyPrintedRels.docx"), PackageAccess.READ); - try { - SignatureConfig sic = new SignatureConfig(); - sic.setOpcPackage(pkg); - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(sic); - boolean isValid = si.verifySignature(); - assertTrue(isValid); - } finally { - pkg.close(); - } - } - - @Test - public void getSignerUnsigned() throws Exception { - String testFiles[] = { - "hello-world-unsigned.docx", - "hello-world-unsigned.pptx", - "hello-world-unsigned.xlsx", - "hello-world-office-2010-technical-preview-unsigned.docx" - }; - - for (String testFile : testFiles) { - OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ); - SignatureConfig sic = new SignatureConfig(); - sic.setOpcPackage(pkg); - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(sic); - List result = new ArrayList(); - for (SignaturePart sp : si.getSignatureParts()) { - if (sp.validate()) { - result.add(sp.getSigner()); - } - } - pkg.revert(); - pkg.close(); - assertNotNull(result); - assertTrue(result.isEmpty()); - } - } - - @Test - public void getSigner() throws Exception { - String testFiles[] = { - "hyperlink-example-signed.docx", - "hello-world-signed.docx", - "hello-world-signed.pptx", - "hello-world-signed.xlsx", - "hello-world-office-2010-technical-preview.docx", - "ms-office-2010-signed.docx", - "ms-office-2010-signed.pptx", - "ms-office-2010-signed.xlsx", - "Office2010-SP1-XAdES-X-L.docx", - "signed.docx", - }; - - for (String testFile : testFiles) { - OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ); - try { - SignatureConfig sic = new SignatureConfig(); - sic.setOpcPackage(pkg); - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(sic); - List result = new ArrayList(); - for (SignaturePart sp : si.getSignatureParts()) { - if (sp.validate()) { - result.add(sp.getSigner()); - } - } - - assertNotNull(result); - assertEquals("test-file: "+testFile, 1, result.size()); - X509Certificate signer = result.get(0); - LOG.log(POILogger.DEBUG, "signer: " + signer.getSubjectX500Principal()); - - boolean b = si.verifySignature(); - assertTrue("test-file: "+testFile, b); - pkg.revert(); - } finally { - pkg.close(); - } - } - } - - @Test - public void getMultiSigners() throws Exception { - String testFile = "hello-world-signed-twice.docx"; - OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ); - try { - SignatureConfig sic = new SignatureConfig(); - sic.setOpcPackage(pkg); - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(sic); - List result = new ArrayList(); - for (SignaturePart sp : si.getSignatureParts()) { - if (sp.validate()) { - result.add(sp.getSigner()); - } - } - - assertNotNull(result); - assertEquals("test-file: "+testFile, 2, result.size()); - X509Certificate signer1 = result.get(0); - X509Certificate signer2 = result.get(1); - LOG.log(POILogger.DEBUG, "signer 1: " + signer1.getSubjectX500Principal()); - LOG.log(POILogger.DEBUG, "signer 2: " + signer2.getSubjectX500Principal()); - - boolean b = si.verifySignature(); - assertTrue("test-file: "+testFile, b); - pkg.revert(); - } finally { - pkg.close(); - } - } - - @Test - public void testSignSpreadsheet() throws Exception { - String testFile = "hello-world-unsigned.xlsx"; - OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); - sign(pkg, "Test", "CN=Test", 1); - pkg.close(); - } - - @Test - public void testManipulation() throws Exception { - // sign & validate - String testFile = "hello-world-unsigned.xlsx"; - @SuppressWarnings("resource") - OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); - sign(pkg, "Test", "CN=Test", 1); - - // manipulate - XSSFWorkbook wb = new XSSFWorkbook(pkg); - wb.setSheetName(0, "manipulated"); - // ... I don't know, why commit is protected ... - POITestCase.callMethod(XSSFWorkbook.class, wb, Void.class, "commit", new Class[0], new Object[0]); - - // todo: test a manipulation on a package part, which is not signed - // ... maybe in combination with #56164 - - // validate - SignatureConfig sic = new SignatureConfig(); - sic.setOpcPackage(pkg); - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(sic); - boolean b = si.verifySignature(); - assertFalse("signature should be broken", b); - - wb.close(); - } - - @Test - public void testSignSpreadsheetWithSignatureInfo() throws Exception { - initKeyPair("Test", "CN=Test"); - String testFile = "hello-world-unsigned.xlsx"; - OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); - SignatureConfig sic = new SignatureConfig(); - sic.setOpcPackage(pkg); - sic.setKey(keyPair.getPrivate()); - sic.setSigningCertificateChain(Collections.singletonList(x509)); - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(sic); - // hash > sha1 doesn't work in excel viewer ... - si.confirmSignature(); - List result = new ArrayList(); - for (SignaturePart sp : si.getSignatureParts()) { - if (sp.validate()) { - result.add(sp.getSigner()); - } - } - assertEquals(1, result.size()); - pkg.close(); - } - - @Test - public void testSignEnvelopingDocument() throws Exception { - String testFile = "hello-world-unsigned.xlsx"; - OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); - - initKeyPair("Test", "CN=Test"); - final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate()); - - // setup - SignatureConfig signatureConfig = new SignatureConfig(); - signatureConfig.setOpcPackage(pkg); - signatureConfig.setKey(keyPair.getPrivate()); - - /* - * We need at least 2 certificates for the XAdES-C complete certificate - * refs construction. - */ - List certificateChain = new ArrayList(); - certificateChain.add(x509); - certificateChain.add(x509); - signatureConfig.setSigningCertificateChain(certificateChain); - - signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet()); - signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet()); - signatureConfig.addSignatureFacet(new XAdESSignatureFacet()); - signatureConfig.addSignatureFacet(new XAdESXLSignatureFacet()); - - // check for internet, no error means it works - boolean mockTsp = (getAccessError("http://timestamp.comodoca.com/rfc3161", true, 10000) != null); - - // http://timestamping.edelweb.fr/service/tsp - // http://tsa.belgium.be/connect - // http://timestamp.comodoca.com/authenticode - // http://timestamp.comodoca.com/rfc3161 - // http://services.globaltrustfinder.com/adss/tsa - signatureConfig.setTspUrl("http://timestamp.comodoca.com/rfc3161"); - signatureConfig.setTspRequestPolicy(null); // comodoca request fails, if default policy is set ... - signatureConfig.setTspOldProtocol(false); - - //set proxy info if any - String proxy = System.getProperty("http_proxy"); - if (proxy != null && proxy.trim().length() > 0) { - signatureConfig.setProxyUrl(proxy); - } - - if (mockTsp) { - TimeStampService tspService = new TimeStampService(){ - @Override - public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception { - revocationData.addCRL(crl); - return "time-stamp-token".getBytes(LocaleUtil.CHARSET_1252); - } - @Override - public void setSignatureConfig(SignatureConfig config) { - // empty on purpose - } - }; - signatureConfig.setTspService(tspService); - } else { - TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() { - @Override - public void validate(List validateChain, - RevocationData revocationData) throws Exception { - for (X509Certificate certificate : validateChain) { - LOG.log(POILogger.DEBUG, "certificate: " + certificate.getSubjectX500Principal()); - LOG.log(POILogger.DEBUG, "validity: " + certificate.getNotBefore() + " - " + certificate.getNotAfter()); - } - } - }; - signatureConfig.setTspValidator(tspValidator); - signatureConfig.setTspOldProtocol(signatureConfig.getTspUrl().contains("edelweb")); - } - - final RevocationData revocationData = new RevocationData(); - revocationData.addCRL(crl); - OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false, - x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis()); - revocationData.addOCSP(ocspResp.getEncoded()); - - RevocationDataService revocationDataService = new RevocationDataService(){ - @Override - public RevocationData getRevocationData(List revocationChain) { - return revocationData; - } - }; - signatureConfig.setRevocationDataService(revocationDataService); - - // operate - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(signatureConfig); - try { - si.confirmSignature(); - } catch (RuntimeException e) { - pkg.close(); - // only allow a ConnectException because of timeout, we see this in Jenkins from time to time... - if(e.getCause() == null) { - throw e; - } - if((e.getCause() instanceof ConnectException) || (e.getCause() instanceof SocketTimeoutException)) { - Assume.assumeTrue("Only allowing ConnectException with 'timed out' as message here, but had: " + e, - e.getCause().getMessage().contains("timed out")); - } else if (e.getCause() instanceof IOException) { - Assume.assumeTrue("Only allowing IOException with 'Error contacting TSP server' as message here, but had: " + e, - e.getCause().getMessage().contains("Error contacting TSP server")); - } else if (e.getCause() instanceof RuntimeException) { - Assume.assumeTrue("Only allowing RuntimeException with 'This site is cur' as message here, but had: " + e, - e.getCause().getMessage().contains("This site is cur")); - } else { - throw e; - } - } - - // verify - Iterator spIter = si.getSignatureParts().iterator(); - assertTrue("Had: " + si.getSignatureConfig().getOpcPackage(). - getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN), - spIter.hasNext()); - SignaturePart sp = spIter.next(); - boolean valid = sp.validate(); - assertTrue(valid); - - SignatureDocument sigDoc = sp.getSignatureDocument(); - String declareNS = - "declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; " - + "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; "; - - String digestValXQuery = declareNS + - "$this/ds:Signature/ds:SignedInfo/ds:Reference"; - for (ReferenceType rt : (ReferenceType[])sigDoc.selectPath(digestValXQuery)) { - assertNotNull(rt.getDigestValue()); - assertEquals(signatureConfig.getDigestMethodUri(), rt.getDigestMethod().getAlgorithm()); - } - - String certDigestXQuery = declareNS + - "$this//xades:SigningCertificate/xades:Cert/xades:CertDigest"; - XmlObject xoList[] = sigDoc.selectPath(certDigestXQuery); - assertEquals(xoList.length, 1); - DigestAlgAndValueType certDigest = (DigestAlgAndValueType)xoList[0]; - assertNotNull(certDigest.getDigestValue()); - - String qualPropXQuery = declareNS + - "$this/ds:Signature/ds:Object/xades:QualifyingProperties"; - xoList = sigDoc.selectPath(qualPropXQuery); - assertEquals(xoList.length, 1); - QualifyingPropertiesType qualProp = (QualifyingPropertiesType)xoList[0]; - boolean qualPropXsdOk = qualProp.validate(); - assertTrue(qualPropXsdOk); - - pkg.close(); - } - - public static String getAccessError(String destinationUrl, boolean fireRequest, int timeout) { - URL url; - try { - url = new URL(destinationUrl); - } catch (MalformedURLException e) { - throw new IllegalArgumentException("Invalid destination URL", e); - } - - HttpURLConnection conn = null; - try { - conn = (HttpURLConnection) url.openConnection(); - - // set specified timeout if non-zero - if(timeout != 0) { - conn.setConnectTimeout(timeout); - conn.setReadTimeout(timeout); - } - - conn.setDoOutput(false); - conn.setDoInput(true); - - /* if connecting is not possible this will throw a connection refused exception */ - conn.connect(); - - if (fireRequest) { - InputStream is = null; - try { - is = conn.getInputStream(); - } finally { - IOUtils.closeQuietly(is); - } - - } - /* if connecting is possible we return true here */ - return null; - - } catch (IOException e) { - /* exception is thrown -> server not available */ - return e.getClass().getName() + ": " + e.getMessage(); - } finally { - if (conn != null) { - conn.disconnect(); - } - } - } - - @Test - public void testCertChain() throws Exception { - KeyStore keystore = KeyStore.getInstance("PKCS12"); - String password = "test"; - InputStream is = testdata.openResourceAsStream("chaintest.pfx"); - keystore.load(is, password.toCharArray()); - is.close(); - - Key key = keystore.getKey("poitest", password.toCharArray()); - Certificate chainList[] = keystore.getCertificateChain("poitest"); - List certChain = new ArrayList(); - for (Certificate c : chainList) { - certChain.add((X509Certificate)c); - } - x509 = certChain.get(0); - keyPair = new KeyPair(x509.getPublicKey(), (PrivateKey)key); - - String testFile = "hello-world-unsigned.xlsx"; - OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); - - SignatureConfig signatureConfig = new SignatureConfig(); - signatureConfig.setKey(keyPair.getPrivate()); - signatureConfig.setSigningCertificateChain(certChain); - Calendar oldCal = LocaleUtil.getLocaleCalendar(2007, 7, 1); - signatureConfig.setExecutionTime(oldCal.getTime()); - signatureConfig.setDigestAlgo(HashAlgorithm.sha1); - signatureConfig.setOpcPackage(pkg); - - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(signatureConfig); - - si.confirmSignature(); - - for (SignaturePart sp : si.getSignatureParts()){ - assertTrue("Could not validate", sp.validate()); - X509Certificate signer = sp.getSigner(); - assertNotNull("signer undefined?!", signer); - List certChainRes = sp.getCertChain(); - assertEquals(3, certChainRes.size()); - } - - pkg.close(); - } - - @Test - public void testNonSha1() throws Exception { - String testFile = "hello-world-unsigned.xlsx"; - initKeyPair("Test", "CN=Test"); - - SignatureConfig signatureConfig = new SignatureConfig(); - signatureConfig.setKey(keyPair.getPrivate()); - signatureConfig.setSigningCertificateChain(Collections.singletonList(x509)); - - HashAlgorithm testAlgo[] = { HashAlgorithm.sha224, HashAlgorithm.sha256 - , HashAlgorithm.sha384, HashAlgorithm.sha512, HashAlgorithm.ripemd160 }; - - for (HashAlgorithm ha : testAlgo) { - OPCPackage pkg = null; - try { - signatureConfig.setDigestAlgo(ha); - pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE); - signatureConfig.setOpcPackage(pkg); - - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(signatureConfig); - - si.confirmSignature(); - boolean b = si.verifySignature(); - assertTrue("Signature not correctly calculated for " + ha, b); - } finally { - if (pkg != null) pkg.close(); - } - } - } - - @Test - public void bug58630() throws Exception { - // test deletion of sheet 0 and signing - File tpl = copy(testdata.getFile("bug58630.xlsx")); - SXSSFWorkbook wb1 = new SXSSFWorkbook((XSSFWorkbook)WorkbookFactory.create(tpl), 10); - wb1.setCompressTempFiles(true); - wb1.removeSheetAt(0); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - wb1.write(os); - wb1.close(); - OPCPackage pkg = OPCPackage.open(new ByteArrayInputStream(os.toByteArray())); - - initKeyPair("Test", "CN=Test"); - SignatureConfig signatureConfig = new SignatureConfig(); - signatureConfig.setKey(keyPair.getPrivate()); - signatureConfig.setSigningCertificateChain(Collections.singletonList(x509)); - signatureConfig.setOpcPackage(pkg); - - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(signatureConfig); - si.confirmSignature(); - assertTrue("invalid signature", si.verifySignature()); - - pkg.close(); - } - - @Test - public void testMultiSign() throws Exception { - initKeyPair("KeyA", "CN=KeyA"); - //KeyPair keyPairA = keyPair; - //X509Certificate x509A = x509; - initKeyPair("KeyB", "CN=KeyB"); - //KeyPair keyPairB = keyPair; - //X509Certificate x509B = x509; - - File tpl = copy(testdata.getFile("bug58630.xlsx")); - OPCPackage pkg = OPCPackage.open(tpl); - try { - //SignatureConfig signatureConfig = new SignatureConfig(); - assertNotNull(pkg); - } finally { - pkg.close(); - } - } - - private void sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception { - initKeyPair(alias, signerDn); - - SignatureConfig signatureConfig = new SignatureConfig(); - signatureConfig.setKey(keyPair.getPrivate()); - signatureConfig.setSigningCertificateChain(Collections.singletonList(x509)); - signatureConfig.setExecutionTime(cal.getTime()); - signatureConfig.setDigestAlgo(HashAlgorithm.sha1); - signatureConfig.setOpcPackage(pkgCopy); - - SignatureInfo si = new SignatureInfo(); - si.setSignatureConfig(signatureConfig); - - Document document = DocumentHelper.createDocument(); - - // operate - DigestInfo digestInfo = si.preSign(document, null); - - // verify - assertNotNull(digestInfo); - LOG.log(POILogger.DEBUG, "digest algo: " + digestInfo.hashAlgo); - LOG.log(POILogger.DEBUG, "digest description: " + digestInfo.description); - assertEquals("Office OpenXML Document", digestInfo.description); - assertNotNull(digestInfo.hashAlgo); - assertNotNull(digestInfo.digestValue); - - // setup: key material, signature value - byte[] signatureValue = si.signDigest(digestInfo.digestValue); - - // operate: postSign - si.postSign(document, signatureValue); - - // verify: signature - si.getSignatureConfig().setOpcPackage(pkgCopy); - List result = new ArrayList(); - for (SignaturePart sp : si.getSignatureParts()) { - if (sp.validate()) { - result.add(sp.getSigner()); - } - } - assertEquals(signerCount, result.size()); - } - - private void initKeyPair(String alias, String subjectDN) throws Exception { - final char password[] = "test".toCharArray(); - File file = new File("build/test.pfx"); - - KeyStore keystore = KeyStore.getInstance("PKCS12"); - - if (file.exists()) { - FileInputStream fis = new FileInputStream(file); - keystore.load(fis, password); - fis.close(); - } else { - keystore.load(null, password); - } - - if (keystore.isKeyEntry(alias)) { - Key key = keystore.getKey(alias, password); - x509 = (X509Certificate)keystore.getCertificate(alias); - keyPair = new KeyPair(x509.getPublicKey(), (PrivateKey)key); - } else { - keyPair = PkiTestUtils.generateKeyPair(); - Date notBefore = cal.getTime(); - Calendar cal2 = (Calendar)cal.clone(); - cal2.add(Calendar.YEAR, 1); - Date notAfter = cal2.getTime(); - KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature); - - x509 = PkiTestUtils.generateCertificate(keyPair.getPublic(), subjectDN - , notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage); - - keystore.setKeyEntry(alias, keyPair.getPrivate(), password, new Certificate[]{x509}); - FileOutputStream fos = new FileOutputStream(file); - keystore.store(fos, password); - fos.close(); - } - } - - private static File copy(File input) throws IOException { - String extension = input.getName().replaceAll(".*?(\\.[^.]+)?$", "$1"); - if (extension == null || "".equals(extension)) { - extension = ".zip"; - } - - // ensure that we create the "build" directory as it might not be existing - // in the Sonar Maven runs where we are at a different source directory - File buildDir = new File("build"); - if(!buildDir.exists()) { - assertTrue("Failed to create " + buildDir.getAbsolutePath(), - buildDir.mkdirs()); - } - File tmpFile = new File(buildDir, "sigtest"+extension); - - OutputStream fos = new FileOutputStream(tmpFile); - try { - InputStream fis = new FileInputStream(input); - try { - IOUtils.copy(fis, fos); - } finally { - fis.close(); - } - } finally { - fos.close(); - } - - return tmpFile; - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java b/trunk/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java deleted file mode 100644 index 8587b0e75..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.apache.poi.sl.TestTable.openSampleSlideshow; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.hslf.model.HeadersFooters; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.sl.usermodel.TextShape; -import org.junit.Test; - -public class TestHeadersFooters { - @Test - public void bug58144() throws IOException { - SlideShow ppt1 = openSampleSlideshow("bug58144-headers-footers-2003.ppt"); - HSLFSlide sl1 = (HSLFSlide)ppt1.getSlides().get(0); - HeadersFooters hfs1 = sl1.getHeadersFooters(); - assertNull(hfs1.getHeaderText()); - assertEquals("Confidential", hfs1.getFooterText()); - List> llp1 = sl1.getTextParagraphs(); - assertEquals("Test", HSLFTextParagraph.getText(llp1.get(0))); - assertFalse(llp1.get(0).get(0).isHeaderOrFooter()); - ppt1.close(); - - String ppt2007s[] = { - "bug58144-headers-footers-2007.ppt", "bug58144-headers-footers-2007.pptx" - }; - - for (String pptName : ppt2007s) { - SlideShow ppt2 = openSampleSlideshow(pptName); - Slide sl2 = ppt2.getSlides().get(0); - - if (ppt2 instanceof HSLFSlideShow) { - HeadersFooters hfs2 = ((HSLFSlide)sl2).getHeadersFooters(); - assertNull(hfs2.getHeaderText()); - assertEquals("Slide footer", hfs2.getFooterText()); - } - - List> shapes = sl2.getShapes(); - TextShape ts0 = (TextShape)shapes.get(0); - assertEquals("Test file", ts0.getText()); - TextShape ts1 = (TextShape)shapes.get(1); - assertEquals("Has some text in the headers and footers", ts1.getText()); - TextShape ts2 = (TextShape)shapes.get(2); - assertEquals("Slide footer", ts2.getText()); - List> ltp2 = ts2.getTextParagraphs(); - assertTrue(ltp2.get(0).isHeaderOrFooter()); - ppt2.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/sl/TestTable.java b/trunk/src/ooxml/testcases/org/apache/poi/sl/TestTable.java deleted file mode 100644 index 1dec172de..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/sl/TestTable.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.sl; - -import static org.junit.Assert.assertEquals; - -import java.awt.geom.Rectangle2D; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.sl.usermodel.TableCell; -import org.apache.poi.sl.usermodel.TableShape; -import org.apache.poi.sl.usermodel.TextShape.TextDirection; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.junit.Test; - -public class TestTable { - private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); - - /** a generic way to open a sample slideshow document **/ - public static SlideShow openSampleSlideshow(String sampleName) throws IOException { - InputStream is = _slTests.openResourceAsStream(sampleName); - try { - return SlideShowFactory.create(is); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - is.close(); - } - } - - @Test - public void testColWidthRowHeight() throws IOException { - // Test of table dimensions of same slideshow saved as ppt/x - // to check if both return similar (points) value - SlideShow ppt = openSampleSlideshow("table_test.ppt"); - TableShape ts = (TableShape)ppt.getSlides().get(0).getShapes().get(0); - - SlideShow pptx = openSampleSlideshow("table_test.pptx"); - TableShape tsx = (TableShape)pptx.getSlides().get(0).getShapes().get(0); - - // assume table shape should be equal to itself - confirmTableShapeEqual(ts, ts); - confirmTableShapeEqual(tsx, tsx); - - // assert ppt and pptx versions of the same table have the same shape - confirmTableShapeEqual(ts, tsx); - - pptx.close(); - ppt.close(); - } - - private void confirmTableShapeEqual(TableShape tableA, TableShape tableB) { - int cols = tableA.getNumberOfColumns(); - int rows = tableA.getNumberOfRows(); - - int colsx = tableB.getNumberOfColumns(); - int rowsx = tableB.getNumberOfRows(); - - assertEquals("tables should have same number of columns", cols, colsx); - assertEquals("tables should have same number of rows", rows, rowsx); - - for (int i=0; i ppt1 = (i == 0) ? new HSLFSlideShow() : new XMLSlideShow(); - TableShape tbl1 = ppt1.createSlide().createTable(1, 3); - tbl1.setAnchor(new Rectangle2D.Double(50, 50, 200, 200)); - - int col = 0; - for (TextDirection td : tds) { - TableCell c = tbl1.getCell(0, col++); - c.setTextDirection(td); - c.setText("bla"); - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ppt1.write(bos); - ppt1.close(); - - InputStream is = new ByteArrayInputStream(bos.toByteArray()); - SlideShow ppt2 = SlideShowFactory.create(is); - TableShape tbl2 = (TableShape)ppt2.getSlides().get(0).getShapes().get(0); - - col = 0; - for (TextDirection td : tds) { - TableCell c = tbl2.getCell(0, col++); - assertEquals(td, c.getTextDirection()); - } - ppt2.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/sl/draw/TestDrawPictureShape.java b/trunk/src/ooxml/testcases/org/apache/poi/sl/draw/TestDrawPictureShape.java deleted file mode 100644 index 303bc833f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/sl/draw/TestDrawPictureShape.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.sl.draw; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.awt.Dimension; -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.PictureShape; -import org.apache.poi.sl.usermodel.RectAlign; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.util.Units; -import org.junit.Test; - -public class TestDrawPictureShape { - final static POIDataSamples ssSamples = POIDataSamples.getSlideShowInstance(); - - /** a generic way to open a sample slideshow document **/ - public static SlideShow openSampleDocument(String sampleName) throws IOException { - InputStream is = ssSamples.openResourceAsStream(sampleName); - try { - return SlideShowFactory.create(is); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - is.close(); - } - } - - @Test - public void testResize() throws Exception { - String files[] = { "pictures.ppt", "shapes.pptx" }; - for (String file : files) { - SlideShow ss = openSampleDocument(file); - - Slide slide = ss.getSlides().get(0); - PictureShape picShape = null; - for (Shape shape : slide.getShapes()) { - if (shape instanceof PictureShape) { - picShape = (PictureShape)shape; - break; - } - } - assertNotNull(picShape); - PictureData pd = picShape.getPictureData(); - Dimension dimPd = pd.getImageDimension(); - new DrawPictureShape(picShape).resize(); - Dimension dimShape = new Dimension( - (int)picShape.getAnchor().getWidth(), - (int)picShape.getAnchor().getHeight() - ); - assertEquals(dimPd, dimShape); - - double newWidth = (dimPd.getWidth()*(100d/dimPd.getHeight())); - // ... -1 is a rounding error - Rectangle2D expRect = new Rectangle2D.Double(rbf(50+300-newWidth, picShape), 50, rbf(newWidth, picShape), 100); - Rectangle2D target = new Rectangle2D.Double(50,50,300,100); - new DrawPictureShape(picShape).resize(target, RectAlign.BOTTOM_RIGHT); - Rectangle2D actRect = picShape.getAnchor(); - assertEquals(expRect.getX(), actRect.getX(), .0001); - assertEquals(expRect.getY(), actRect.getY(), .0001); - assertEquals(expRect.getWidth(), actRect.getWidth(), .0001); - assertEquals(expRect.getHeight(), actRect.getHeight(), .0001); - ss.close(); - } - } - - // round back and forth - points -> master -> points - static double rbf(double val, PictureShape picShape) { - if (picShape.getClass().getName().contains("HSLF")) { - return Units.masterToPoints(Units.pointsToMaster(val)); - } else { - return val; - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java deleted file mode 100644 index 4b77e96be..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java +++ /dev/null @@ -1,385 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss; - -import static org.junit.Assert.*; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.FileNotFoundException; - -import org.apache.poi.EmptyFileException; -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.junit.Test; - -public final class TestWorkbookFactory { - private static final String xls = "SampleSS.xls"; - private static final String xlsx = "SampleSS.xlsx"; - private static final String[] xls_prot = new String[] {"password.xls", "password"}; - private static final String[] xlsx_prot = new String[]{"protected_passtika.xlsx", "tika"}; - private static final String txt = "SampleSS.txt"; - - private static final POILogger LOGGER = POILogFactory.getLogger(TestWorkbookFactory.class); - - /** - * Closes the sample workbook read in from filename. - * Throws an exception if closing the workbook results in the file on disk getting modified. - * - * @param filename the sample workbook to read in - * @param wb the workbook to close - * @throws IOException - */ - private static void assertCloseDoesNotModifyFile(String filename, Workbook wb) throws IOException { - final byte[] before = HSSFTestDataSamples.getTestDataFileContent(filename); - // FIXME: replace with wb.close() when bug 58779 is resolved - closeOrRevert(wb); - final byte[] after = HSSFTestDataSamples.getTestDataFileContent(filename); - assertArrayEquals(filename + " sample file was modified as a result of closing the workbook", - before, after); - } - - /** - * bug 58779: Closing an XSSFWorkbook that was created with WorkbookFactory modifies the file - * FIXME: replace this method with wb.close() when bug 58779 is resolved. - * - * @param wb the workbook to close or revert - */ - private static void closeOrRevert(Workbook wb) throws IOException { - if (wb instanceof HSSFWorkbook) { - wb.close(); - } - else if (wb instanceof XSSFWorkbook) { - final XSSFWorkbook xwb = (XSSFWorkbook) wb; - if (PackageAccess.READ == xwb.getPackage().getPackageAccess()) { - xwb.close(); - } - else { - // TODO: close() re-writes the sample-file?! Resort to revert() for now to close file handle... - LOGGER.log(POILogger.WARN, - "reverting XSSFWorkbook rather than closing it to avoid close() modifying the file on disk. " + - "Refer to bug 58779."); - xwb.getPackage().revert(); - } - } else { - throw new RuntimeException("Unsupported workbook type"); - } - } - - @Test - public void testCreateNative() throws Exception { - Workbook wb; - - // POIFS -> hssf - wb = WorkbookFactory.create( - new POIFSFileSystem(HSSFTestDataSamples.openSampleFileStream(xls)) - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - // Package -> xssf - wb = WorkbookFactory.create( - OPCPackage.open( - HSSFTestDataSamples.openSampleFileStream(xlsx)) - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - } - - @Test - public void testCreateReadOnly() throws Exception { - Workbook wb; - - // POIFS -> hssf - wb = WorkbookFactory.create(HSSFTestDataSamples.getSampleFile(xls), null, true); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - // Package -> xssf - wb = WorkbookFactory.create(HSSFTestDataSamples.getSampleFile(xlsx), null, true); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - } - - /** - * Creates the appropriate kind of Workbook, but - * checking the mime magic at the start of the - * InputStream, then creating what's required. - */ - @Test - public void testCreateGeneric() throws Exception { - Workbook wb; - - // InputStream -> either - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls) - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx) - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - - // File -> either - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls) - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx) - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - - // Invalid type -> exception - final byte[] before = HSSFTestDataSamples.getTestDataFileContent(txt); - try { - InputStream stream = HSSFTestDataSamples.openSampleFileStream(txt); - try { - wb = WorkbookFactory.create(stream); - } finally { - stream.close(); - } - fail(); - } catch(InvalidFormatException e) { - // Good - } - final byte[] after = HSSFTestDataSamples.getTestDataFileContent(txt); - assertArrayEquals("Invalid type file was modified after trying to open the file as a spreadsheet", - before, after); - } - - /** - * Check that the overloaded stream methods which take passwords work properly - */ - @Test - public void testCreateWithPasswordFromStream() throws Exception { - Workbook wb; - - - // Unprotected, no password given, opens normally - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls), null - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx), null - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - - - // Unprotected, wrong password, opens normally - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls), "wrong" - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx), "wrong" - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - - - // Protected, correct password, opens fine - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), xls_prot[1] - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls_prot[0], wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), xlsx_prot[1] - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); - - - // Protected, wrong password, throws Exception - try { - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), "wrong" - ); - assertCloseDoesNotModifyFile(xls_prot[0], wb); - fail("Shouldn't be able to open with the wrong password"); - } catch (EncryptedDocumentException e) {} - - try { - wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), "wrong" - ); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); - fail("Shouldn't be able to open with the wrong password"); - } catch (EncryptedDocumentException e) {} - } - - /** - * Check that the overloaded file methods which take passwords work properly - */ - @Test - public void testCreateWithPasswordFromFile() throws Exception { - Workbook wb; - - // Unprotected, no password given, opens normally - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls), null - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx), null - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - - // Unprotected, wrong password, opens normally - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls), "wrong" - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls, wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx), "wrong" - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx, wb); - - // Protected, correct password, opens fine - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls_prot[0]), xls_prot[1] - ); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls_prot[0], wb); - - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), xlsx_prot[1] - ); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); - assertTrue(wb.getNumberOfSheets() > 0); - assertNotNull(wb.getSheetAt(0)); - assertNotNull(wb.getSheetAt(0).getRow(0)); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); - - // Protected, wrong password, throws Exception - try { - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls_prot[0]), "wrong" - ); - assertCloseDoesNotModifyFile(xls_prot[0], wb); - fail("Shouldn't be able to open with the wrong password"); - } catch (EncryptedDocumentException e) { - // expected here - } - - try { - wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), "wrong" - ); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); - fail("Shouldn't be able to open with the wrong password"); - } catch (EncryptedDocumentException e) { - // expected here - } - } - - /** - * Check that a helpful exception is given on an empty input stream - */ - @Test - public void testEmptyInputStream() throws Exception { - InputStream emptyStream = new ByteArrayInputStream(new byte[0]); - try { - WorkbookFactory.create(emptyStream); - fail("Shouldn't be able to create for an empty stream"); - } catch (final EmptyFileException expected) {} - } - - /** - * Check that a helpful exception is given on an empty file - */ - @Test - public void testEmptyFile() throws Exception { - File emptyFile = TempFile.createTempFile("empty", ".poi"); - try { - WorkbookFactory.create(emptyFile); - fail("Shouldn't be able to create for an empty file"); - } catch (final EmptyFileException expected) {} - emptyFile.delete(); - } - - /** - * Check that a helpful exception is raised on a non-existing file - */ - @Test - public void testNonExistantFile() throws Exception { - File nonExistantFile = new File("notExistantFile"); - assertFalse(nonExistantFile.exists()); - - try { - WorkbookFactory.create(nonExistantFile, "password", true); - fail("Should not be able to create for a non-existant file"); - } catch (final FileNotFoundException e) { - // expected - } - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java deleted file mode 100644 index ea5192638..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java +++ /dev/null @@ -1,170 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.format; - -import static org.junit.Assert.assertEquals; - -import java.util.Locale; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -/** Test the individual CellFormatPart types. */ -public class TestCellFormatPart extends CellFormatTestBase { - - private static Locale userLocale; - - @BeforeClass - public static void setLocale() { - userLocale = LocaleUtil.getUserLocale(); - LocaleUtil.setUserLocale(Locale.ROOT); - } - - @AfterClass - public static void unsetLocale() { - LocaleUtil.setUserLocale(userLocale); - } - - private static final Pattern NUMBER_EXTRACT_FMT = Pattern.compile( - "([-+]?[0-9]+)(\\.[0-9]+)?.*(?:(e).*?([+-]?[0-9]+))", - Pattern.CASE_INSENSITIVE); - - public TestCellFormatPart() { - super(XSSFITestDataProvider.instance); - } - - @Test - public void testGeneralFormat() throws Exception { - runFormatTests("GeneralFormatTests.xlsx", new CellValue() { - @Override - public Object getValue(Cell cell) { - switch (CellFormat.ultimateTypeEnum(cell)) { - case BOOLEAN: - return cell.getBooleanCellValue(); - case NUMERIC: - return cell.getNumericCellValue(); - default: - return cell.getStringCellValue(); - } - } - }); - } - - public void testNumberFormat() throws Exception { - runFormatTests("NumberFormatTests.xlsx", new CellValue() { - @Override - public Object getValue(Cell cell) { - return cell.getNumericCellValue(); - } - }); - } - - @Test - public void testNumberApproxFormat() throws Exception { - runFormatTests("NumberFormatApproxTests.xlsx", new CellValue() { - @Override - public Object getValue(Cell cell) { - return cell.getNumericCellValue(); - } - - @Override - void equivalent(String expected, String actual, - CellFormatPart format) { - double expectedVal = extractNumber(expected); - double actualVal = extractNumber(actual); - // equal within 1% - double delta = expectedVal / 100; - assertEquals("format \"" + format + "\"," + expected + " ~= " + - actual, expectedVal, actualVal, delta); - } - }); - } - - @Test - public void testDateFormat() throws Exception { - TimeZone tz = LocaleUtil.getUserTimeZone(); - LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); - try { - runFormatTests("DateFormatTests.xlsx", new CellValue() { - @Override - public Object getValue(Cell cell) { - return cell.getDateCellValue(); - } - }); - } finally { - LocaleUtil.setUserTimeZone(tz); - } - } - - @Test - public void testElapsedFormat() throws Exception { - runFormatTests("ElapsedFormatTests.xlsx", new CellValue() { - @Override - public Object getValue(Cell cell) { - return cell.getNumericCellValue(); - } - }); - } - - @Test - public void testTextFormat() throws Exception { - runFormatTests("TextFormatTests.xlsx", new CellValue() { - @Override - public Object getValue(Cell cell) { - switch(CellFormat.ultimateTypeEnum(cell)) { - case BOOLEAN: - return cell.getBooleanCellValue(); - default: - return cell.getStringCellValue(); - } - } - }); - } - - @Test - public void testConditions() throws Exception { - runFormatTests("FormatConditionTests.xlsx", new CellValue() { - @Override - Object getValue(Cell cell) { - return cell.getNumericCellValue(); - } - }); - } - - private double extractNumber(String str) { - Matcher m = NUMBER_EXTRACT_FMT.matcher(str); - if (!m.find()) - throw new IllegalArgumentException( - "Cannot find numer in \"" + str + "\""); - - StringBuffer sb = new StringBuffer(); - // The groups in the pattern are the parts of the number - for (int i = 1; i <= m.groupCount(); i++) { - String part = m.group(i); - if (part != null) - sb.append(part); - } - return Double.valueOf(sb.toString()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/TestFormulaParser.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/TestFormulaParser.java deleted file mode 100644 index dfbbd4281..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/TestFormulaParser.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.ss.formula; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg; -import org.apache.poi.ss.formula.ptg.NameXPxg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPxg; -import org.apache.poi.ss.formula.ptg.StringPtg; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Ignore; -import org.junit.Test; - -/** - * Test {@link FormulaParser}'s handling of row numbers at the edge of the - * HSSF/XSSF ranges. - * - * @author David North - */ -public class TestFormulaParser { - - @Test - public void testHSSFFailsForOver65536() { - FormulaParsingWorkbook workbook = HSSFEvaluationWorkbook.create(new HSSFWorkbook()); - try { - FormulaParser.parse("Sheet1!1:65537", workbook, FormulaType.CELL, 0); - fail("Expected exception"); - } - catch (FormulaParseException expected) { - // expected here - } - } - - @Test - public void testHSSFPassCase() { - FormulaParsingWorkbook workbook = HSSFEvaluationWorkbook.create(new HSSFWorkbook()); - FormulaParser.parse("Sheet1!1:65536", workbook, FormulaType.CELL, 0); - } - - @Test - public void testXSSFWorksForOver65536() { - FormulaParsingWorkbook workbook = XSSFEvaluationWorkbook.create(new XSSFWorkbook()); - FormulaParser.parse("Sheet1!1:65537", workbook, FormulaType.CELL, 0); - } - - @Test - public void testXSSFFailCase() { - FormulaParsingWorkbook workbook = XSSFEvaluationWorkbook.create(new XSSFWorkbook()); - try { - FormulaParser.parse("Sheet1!1:1048577", workbook, FormulaType.CELL, 0); // one more than max rows. - fail("Expected exception"); - } - catch (FormulaParseException expected) { - // expected here - } - } - - // copied from org.apache.poi.hssf.model.TestFormulaParser - @Test - public void testMacroFunction() throws Exception { - // testNames.xlsm contains a VB function called 'myFunc' - final String testFile = "testNames.xlsm"; - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook(testFile); - try { - XSSFEvaluationWorkbook workbook = XSSFEvaluationWorkbook.create(wb); - - //Expected ptg stack: [NamePtg(myFunc), StringPtg(arg), (additional operands would go here...), FunctionPtg(myFunc)] - Ptg[] ptg = FormulaParser.parse("myFunc(\"arg\")", workbook, FormulaType.CELL, -1); - assertEquals(3, ptg.length); - - // the name gets encoded as the first operand on the stack - NameXPxg tname = (NameXPxg) ptg[0]; - assertEquals("myFunc", tname.toFormulaString()); - - // the function's arguments are pushed onto the stack from left-to-right as OperandPtgs - StringPtg arg = (StringPtg) ptg[1]; - assertEquals("arg", arg.getValue()); - - // The external FunctionPtg is the last Ptg added to the stack - // During formula evaluation, this Ptg pops off the the appropriate number of - // arguments (getNumberOfOperands()) and pushes the result on the stack - AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[2]; - assertTrue(tfunc.isExternalFunction()); - - // confirm formula parsing is case-insensitive - FormulaParser.parse("mYfUnC(\"arg\")", workbook, FormulaType.CELL, -1); - - // confirm formula parsing doesn't care about argument count or type - // this should only throw an error when evaluating the formula. - FormulaParser.parse("myFunc()", workbook, FormulaType.CELL, -1); - FormulaParser.parse("myFunc(\"arg\", 0, TRUE)", workbook, FormulaType.CELL, -1); - - // A completely unknown formula name (not saved in workbook) should still be parseable and renderable - // but will throw an NotImplementedFunctionException or return a #NAME? error value if evaluated. - FormulaParser.parse("yourFunc(\"arg\")", workbook, FormulaType.CELL, -1); - - // Make sure workbook can be written and read - XSSFTestDataSamples.writeOutAndReadBack(wb).close(); - - // Manually check to make sure file isn't corrupted - // TODO: develop a process for occasionally manually reviewing workbooks - // to verify workbooks are not corrupted - /* - final File fileIn = XSSFTestDataSamples.getSampleFile(testFile); - final File reSavedFile = new File(fileIn.getParentFile(), fileIn.getName().replace(".xlsm", "-saved.xlsm")); - final FileOutputStream fos = new FileOutputStream(reSavedFile); - wb.write(fos); - fos.close(); - */ - } finally { - wb.close(); - } - } - - @Test - public void testParserErrors() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("testNames.xlsm"); - try { - XSSFEvaluationWorkbook workbook = XSSFEvaluationWorkbook.create(wb); - - parseExpectedException("("); - parseExpectedException(")"); - parseExpectedException("+"); - parseExpectedException("42+"); - parseExpectedException("IF()"); - parseExpectedException("IF("); //no closing paren - parseExpectedException("myFunc(", workbook); //no closing paren - } finally { - wb.close(); - } - } - - private static void parseExpectedException(String formula) { - parseExpectedException(formula, null); - } - - /** confirm formula has invalid syntax and parsing the formula results in FormulaParseException - */ - private static void parseExpectedException(String formula, FormulaParsingWorkbook wb) { - try { - FormulaParser.parse(formula, wb, FormulaType.CELL, -1); - fail("Expected FormulaParseException: " + formula); - } catch (final FormulaParseException e) { - // expected during successful test - assertNotNull(e.getMessage()); - } - } - - // trivial case for bug 60219: FormulaParser can't parse external references when sheet name is quoted - @Test - public void testParseExternalReferencesWithUnquotedSheetName() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpwb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs = FormulaParser.parse("[1]Sheet1!A1", fpwb, FormulaType.CELL, -1); - // org.apache.poi.ss.formula.ptg.Ref3DPxg [ [workbook=1] sheet=Sheet 1 ! A1] - assertEquals("Ptgs length", 1, ptgs.length); - assertTrue("Ptg class", ptgs[0] instanceof Ref3DPxg); - Ref3DPxg pxg = (Ref3DPxg) ptgs[0]; - assertEquals("External workbook number", 1, pxg.getExternalWorkbookNumber()); - assertEquals("Sheet name", "Sheet1", pxg.getSheetName()); - assertEquals("Row", 0, pxg.getRow()); - assertEquals("Column", 0, pxg.getColumn()); - wb.close(); - } - - // bug 60219: FormulaParser can't parse external references when sheet name is quoted - @Ignore - @Test - public void testParseExternalReferencesWithQuotedSheetName() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpwb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs = FormulaParser.parse("'[1]Sheet 1'!A1", fpwb, FormulaType.CELL, -1); - // org.apache.poi.ss.formula.ptg.Ref3DPxg [ [workbook=1] sheet=Sheet 1 ! A1] - assertEquals("Ptgs length", 1, ptgs.length); - assertTrue("Ptg class", ptgs[0] instanceof Ref3DPxg); - Ref3DPxg pxg = (Ref3DPxg) ptgs[0]; - assertEquals("External workbook number", 1, pxg.getExternalWorkbookNumber()); - assertEquals("Sheet name", "Sheet 1", pxg.getSheetName()); - assertEquals("Row", 0, pxg.getRow()); - assertEquals("Column", 0, pxg.getColumn()); - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java deleted file mode 100644 index b60664ad0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Table; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFTable; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; - -/** - * Tests Excel Table expressions (structured references) - * @see - * Excel Structured Reference Syntax - * - */ -public class TestStructuredReferences { - - /** - * Test the regular expression used in INDIRECT() evaluation to recognize structured references - */ - @Test - public void testTableExpressionSyntax() { - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("abc[col1]").matches()); - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("_abc[col1]").matches()); - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("_[col1]").matches()); - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[col1]").matches()); - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[col1]").matches()); - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[#This Row]").matches()); - assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[ [col1], [col2] ]").matches()); - - // can't have a space between the table name and open bracket - assertFalse("Invalid structured reference syntax didn't fail expression", Table.isStructuredReference.matcher("\\abc [ [col1], [col2] ]").matches()); - } - - @Test - public void testTableFormulas() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - try { - - final FormulaEvaluator eval = new XSSFFormulaEvaluator(wb); - final XSSFSheet tableSheet = wb.getSheet("Table"); - final XSSFSheet formulaSheet = wb.getSheet("Formulas"); - - confirm(eval, tableSheet.getRow(5).getCell(0), 49); - confirm(eval, formulaSheet.getRow(0).getCell(0), 209); - confirm(eval, formulaSheet.getRow(1).getCell(0), "one"); - - // test changing a table value, to see if the caches are properly cleared - // Issue 59814 - - // this test passes before the fix for 59814 - tableSheet.getRow(1).getCell(1).setCellValue("ONEA"); - confirm(eval, formulaSheet.getRow(1).getCell(0), "ONEA"); - - // test adding a row to a table, issue 59814 - Row newRow = tableSheet.getRow(7); - if (newRow == null) newRow = tableSheet.createRow(7); - newRow.createCell(0, CellType.FORMULA).setCellFormula("\\_Prime.1[[#This Row],[@Number]]*\\_Prime.1[[#This Row],[@Number]]"); - newRow.createCell(1, CellType.STRING).setCellValue("thirteen"); - newRow.createCell(2, CellType.NUMERIC).setCellValue(13); - - // update Table - final XSSFTable table = wb.getTable("\\_Prime.1"); - final AreaReference newArea = new AreaReference(table.getStartCellReference(), new CellReference(table.getEndRowIndex() + 1, table.getEndColIndex())); - String newAreaStr = newArea.formatAsString(); - table.getCTTable().setRef(newAreaStr); - table.getCTTable().getAutoFilter().setRef(newAreaStr); - table.updateHeaders(); - table.updateReferences(); - - // these fail before the fix for 59814 - confirm(eval, tableSheet.getRow(7).getCell(0), 13*13); - confirm(eval, formulaSheet.getRow(0).getCell(0), 209 + 13*13); - - } finally { - wb.close(); - } - } - - private static void confirm(FormulaEvaluator fe, Cell cell, double expectedResult) { - fe.clearAllCachedResultValues(); - CellValue cv = fe.evaluate(cell); - if (cv.getCellTypeEnum() != CellType.NUMERIC) { - fail("expected numeric cell type but got " + cv.formatAsString()); - } - assertEquals(expectedResult, cv.getNumberValue(), 0.0); - } - - private static void confirm(FormulaEvaluator fe, Cell cell, String expectedResult) { - fe.clearAllCachedResultValues(); - CellValue cv = fe.evaluate(cell); - if (cv.getCellTypeEnum() != CellType.STRING) { - fail("expected String cell type but got " + cv.formatAsString()); - } - assertEquals(expectedResult, cv.getStringValue()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java deleted file mode 100644 index 0b8c9fcb1..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.xssf.XSSFITestDataProvider; - -/** - * Tests XSSFFormulaEvaluator for its handling of cell formula circular references. - * - * @author Josh Micich - */ -public final class TestXSSFCircularReferences extends BaseTestCircularReferences { - public TestXSSFCircularReferences() { - super(XSSFITestDataProvider.instance); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java deleted file mode 100644 index 921dc445e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.functions; - -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.eval.StringEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import junit.framework.AssertionFailedError; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public final class TestProper { - private Cell cell11; - private FormulaEvaluator evaluator; - - @Test - public void testValidHSSF() { - HSSFWorkbook wb = new HSSFWorkbook(); - evaluator = new HSSFFormulaEvaluator(wb); - - confirm(wb); - } - - @Test - public void testValidXSSF() { - XSSFWorkbook wb = new XSSFWorkbook(); - evaluator = new XSSFFormulaEvaluator(wb); - - confirm(wb); - } - - private void confirm(Workbook wb) { - Sheet sheet = wb.createSheet("new sheet"); - cell11 = sheet.createRow(0).createCell(0); - cell11.setCellType(CellType.FORMULA); - - confirm("PROPER(\"hi there\")", "Hi There"); //simple case - confirm("PROPER(\"what's up\")", "What'S Up"); //apostrophes are treated as word breaks - confirm("PROPER(\"I DON'T TH!NK SO!\")", "I Don'T Th!Nk So!"); //capitalization is ignored, special punctuation is treated as a word break - confirm("PROPER(\"dr\u00dcb\u00f6'\u00e4 \u00e9lo\u015f|\u00eb\u00e8 \")", "Dr\u00fcb\u00f6'\u00c4 \u00c9lo\u015f|\u00cb\u00e8 "); - confirm("PROPER(\"hi123 the123re\")", "Hi123 The123Re"); //numbers are treated as word breaks - confirm("PROPER(\"-\")", "-"); //nothing happens with ascii punctuation that is not upper or lower case - confirm("PROPER(\"!\u00a7$\")", "!\u00a7$"); //nothing happens with unicode punctuation (section sign) that is not upper or lower case - confirm("PROPER(\"/&%\")", "/&%"); //nothing happens with ascii punctuation that is not upper or lower case - confirm("PROPER(\"Apache POI\")", "Apache Poi"); //acronyms are not special - confirm("PROPER(\" hello world\")", " Hello World"); //leading whitespace is ignored - - final String scharfes = "\u00df"; //German lowercase eszett, scharfes s, sharp s - confirm("PROPER(\"stra"+scharfes+"e\")", "Stra"+scharfes+"e"); - assertTrue(Character.isLetter(scharfes.charAt(0))); - - // CURRENTLY FAILS: result: "SSUnd"+scharfes - // LibreOffice 5.0.3.2 behavior: "Sund"+scharfes - // Excel 2013 behavior: ??? - confirm("PROPER(\""+scharfes+"und"+scharfes+"\")", "SSund"+scharfes); - - // also test longer string - StringBuilder builder = new StringBuilder("A"); - StringBuilder expected = new StringBuilder("A"); - for(int i = 1;i < 254;i++) { - builder.append((char)(65 + (i % 26))); - expected.append((char)(97 + (i % 26))); - } - confirm("PROPER(\"" + builder.toString() + "\")", expected.toString()); - } - - private void confirm(String formulaText, String expectedResult) { - cell11.setCellFormula(formulaText); - evaluator.clearAllCachedResultValues(); - CellValue cv = evaluator.evaluate(cell11); - if (cv.getCellTypeEnum() != CellType.STRING) { - throw new AssertionFailedError("Wrong result type: " + cv.formatAsString()); - } - String actualValue = cv.getStringValue(); - assertEquals(expectedResult, actualValue); - } - - @Test - public void test() { - checkProper("", ""); - checkProper("a", "A"); - checkProper("abc", "Abc"); - checkProper("abc abc", "Abc Abc"); - checkProper("abc/abc", "Abc/Abc"); - checkProper("ABC/ABC", "Abc/Abc"); - checkProper("aBc/ABC", "Abc/Abc"); - checkProper("aBc@#$%^&*()_+=-ABC", "Abc@#$%^&*()_+=-Abc"); - checkProper("aBc25aerg/ABC", "Abc25Aerg/Abc"); - checkProper("aBc/\u00C4\u00F6\u00DF\u00FC/ABC", "Abc/\u00C4\u00F6\u00DF\u00FC/Abc"); // Some German umlauts with uppercase first letter is not changed - checkProper("\u00FC", "\u00DC"); - checkProper("\u00DC", "\u00DC"); - checkProper("\u00DF", "SS"); // German "scharfes s" is uppercased to "SS" - checkProper("\u00DFomesing", "SSomesing"); // German "scharfes s" is uppercased to "SS" - checkProper("aBc/\u00FC\u00C4\u00F6\u00DF\u00FC/ABC", "Abc/\u00DC\u00E4\u00F6\u00DF\u00FC/Abc"); // Some German umlauts with lowercase first letter is changed to uppercase - } - - @Test - public void testMicroBenchmark() { - ValueEval strArg = new StringEval("some longer text that needs a number of replacements to check for runtime of different implementations"); - long start = System.currentTimeMillis(); - for(int i = 0;i < 300000;i++) { - final ValueEval ret = TextFunction.PROPER.evaluate(new ValueEval[]{strArg}, 0, 0); - assertEquals("Some Longer Text That Needs A Number Of Replacements To Check For Runtime Of Different Implementations", ((StringEval)ret).getStringValue()); - } - // Took aprox. 600ms on a decent Laptop in July 2016 - System.out.println("Took: " + (System.currentTimeMillis() - start) + "ms"); - } - - private void checkProper(String input, String expected) { - ValueEval strArg = new StringEval(input); - final ValueEval ret = TextFunction.PROPER.evaluate(new ValueEval[]{strArg}, 0, 0); - assertEquals(expected, ((StringEval)ret).getStringValue()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java deleted file mode 100644 index 0a471419c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.xssf.streaming.SXSSFCell; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.junit.Test; - -/** - * Class for combined testing of XML-specific functionality of - * {@link XSSFCell} and {@link SXSSFCell}. - * - * Any test that is applicable for {@link HSSFCell} as well should go into - * the common base class {@link BaseTestCell}. - */ -public abstract class BaseTestXCell extends BaseTestCell { - protected BaseTestXCell(ITestDataProvider testDataProvider) { - super(testDataProvider); - } - - @Test - public void testXmlEncoding() throws IOException { - Workbook wb1 = _testDataProvider.createWorkbook(); - Sheet sh = wb1.createSheet(); - Row row = sh.createRow(0); - Cell cell = row.createCell(0); - String sval = "\u0000\u0002\u0012<>\t\n\u00a0 &\"POI\'\u2122"; - cell.setCellValue(sval); - - Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1); - wb1.close(); - - // invalid characters are replaced with question marks - assertEquals("???<>\t\n\u00a0 &\"POI\'\u2122", wb2.getSheetAt(0).getRow(0).getCell(0).getStringCellValue()); - wb2.close(); - } - - @Test - public void testSetNullValues() throws IOException { - Workbook wb = _testDataProvider.createWorkbook(); - Cell cell = wb.createSheet("test").createRow(0).createCell(0); - - cell.setCellValue((Calendar)null); - cell.setCellValue((Date)null); - cell.setCellValue((String)null); - cell.setCellValue((RichTextString) null); - cell.setCellValue((String)null); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXRow.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXRow.java deleted file mode 100644 index a4b21001e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXRow.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import java.io.IOException; - -import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.xssf.streaming.SXSSFRow; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.junit.Test; - -/** - * Class for combined testing of XML-specific functionality of - * {@link XSSFRow} and {@link SXSSFRow}. - * - * Any test that is applicable for {@link org.apache.poi.hssf.usermodel.HSSFRow} as well should go into - * the common base class {@link BaseTestRow}. - */ -public abstract class BaseTestXRow extends BaseTestRow { - protected BaseTestXRow(ITestDataProvider testDataProvider) { - super(testDataProvider); - } - - @Test - public void testRowBounds() throws IOException { - baseTestRowBounds(_testDataProvider.getSpreadsheetVersion().getLastRowIndex()); - } - - @Test - public void testCellBounds() throws IOException { - baseTestCellBounds(_testDataProvider.getSpreadsheetVersion().getLastColumnIndex()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXSheet.java deleted file mode 100644 index f6e1bffde..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXSheet.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.xssf.streaming.SXSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFSheet; - -/** - * Class for combined testing of XML-specific functionality of - * {@link XSSFSheet} and {@link SXSSFSheet}. - * - * Any test that is applicable for {@link org.apache.poi.hssf.usermodel.HSSFSheet} as well should go into - * the common base class {@link BaseTestSheet}. - */ -public abstract class BaseTestXSheet extends BaseTestSheet { - protected BaseTestXSheet(ITestDataProvider testDataProvider) { - super(testDataProvider); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXWorkbook.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXWorkbook.java deleted file mode 100644 index 9c7fe3a09..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXWorkbook.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Class for combined testing of XML-specific functionality of - * {@link XSSFWorkbook} and {@link SXSSFWorkbook}. - * - * Any test that is applicable for {@link org.apache.poi.hssf.usermodel.HSSFWorkbook} as well should go into - * the common base class {@link BaseTestWorkbook}. - */ -public abstract class BaseTestXWorkbook extends BaseTestWorkbook { - protected BaseTestXWorkbook(ITestDataProvider testDataProvider) { - super(testDataProvider); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestXSSFBorderStyle.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestXSSFBorderStyle.java deleted file mode 100644 index 2e9334b1a..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestXSSFBorderStyle.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -import org.apache.poi.xssf.XSSFITestDataProvider; - -/** - * @author Yegor Kozlov - */ -public final class TestXSSFBorderStyle extends BaseTestBorderStyle { - - public TestXSSFBorderStyle() { - super(XSSFITestDataProvider.instance); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestSXSSFCellUtil.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestSXSSFCellUtil.java deleted file mode 100644 index 70c5fae44..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestSXSSFCellUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== */ - -package org.apache.poi.ss.util; - -import org.apache.poi.xssf.SXSSFITestDataProvider; - -public class TestSXSSFCellUtil extends BaseTestCellUtil { - public TestSXSSFCellUtil() { - super(SXSSFITestDataProvider.instance); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestXSSFCellUtil.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestXSSFCellUtil.java deleted file mode 100644 index c58ebe90d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestXSSFCellUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ==================================================================== */ - -package org.apache.poi.ss.util; - -import org.apache.poi.xssf.XSSFITestDataProvider; - -public class TestXSSFCellUtil extends BaseTestCellUtil { - public TestXSSFCellUtil() { - super(XSSFITestDataProvider.instance); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestXSSFPropertyTemplate.java b/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestXSSFPropertyTemplate.java deleted file mode 100644 index 1c4b7adc3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/ss/util/TestXSSFPropertyTemplate.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BorderExtent; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; - -public class TestXSSFPropertyTemplate { - - @Test - public void applyBorders() throws IOException { - CellRangeAddress a1c3 = new CellRangeAddress(0, 2, 0, 2); - CellRangeAddress b2 = new CellRangeAddress(1, 1, 1, 1); - PropertyTemplate pt = new PropertyTemplate(); - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - pt.drawBorders(a1c3, BorderStyle.THIN, IndexedColors.RED.getIndex(), BorderExtent.ALL); - pt.applyBorders(sheet); - - for (Row row: sheet) { - for (Cell cell: row) { - CellStyle cs = cell.getCellStyle(); - assertEquals(BorderStyle.THIN, cs.getBorderTopEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); - assertEquals(BorderStyle.THIN, cs.getBorderBottomEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); - assertEquals(BorderStyle.THIN, cs.getBorderLeftEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); - assertEquals(BorderStyle.THIN, cs.getBorderRightEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); - } - } - - pt.drawBorders(b2, BorderStyle.NONE, BorderExtent.ALL); - pt.applyBorders(sheet); - - for (Row row: sheet) { - for (Cell cell: row) { - CellStyle cs = cell.getCellStyle(); - if (cell.getColumnIndex() != 1 || row.getRowNum() == 0) { - assertEquals(BorderStyle.THIN, cs.getBorderTopEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderTopEnum()); - } - if (cell.getColumnIndex() != 1 || row.getRowNum() == 2) { - assertEquals(BorderStyle.THIN, cs.getBorderBottomEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderBottomEnum()); - } - if (cell.getColumnIndex() == 0 || row.getRowNum() != 1) { - assertEquals(BorderStyle.THIN, cs.getBorderLeftEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderLeftEnum()); - } - if (cell.getColumnIndex() == 2 || row.getRowNum() != 1) { - assertEquals(BorderStyle.THIN, cs.getBorderRightEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderRightEnum()); - } - } - } - - wb.close(); - } - - @Test - public void clonePropertyTemplate() throws IOException { - CellRangeAddress a1c3 = new CellRangeAddress(0, 2, 0, 2); - PropertyTemplate pt = new PropertyTemplate(); - pt.drawBorders(a1c3, BorderStyle.MEDIUM, IndexedColors.RED.getIndex(), BorderExtent.ALL); - PropertyTemplate pt2 = new PropertyTemplate(pt); - assertNotSame(pt2, pt); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, pt2.getNumBorderColors(i, j)); - assertEquals(4, pt2.getNumBorderColors(i, j)); - } - } - - CellRangeAddress b2 = new CellRangeAddress(1,1,1,1); - pt2.drawBorders(b2, BorderStyle.THIN, BorderExtent.ALL); - - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - pt.applyBorders(sheet); - - for (Row row : sheet) { - for (Cell cell : row) { - CellStyle cs = cell.getCellStyle(); - assertEquals(BorderStyle.MEDIUM, cs.getBorderTopEnum()); - assertEquals(BorderStyle.MEDIUM, cs.getBorderBottomEnum()); - assertEquals(BorderStyle.MEDIUM, cs.getBorderLeftEnum()); - assertEquals(BorderStyle.MEDIUM, cs.getBorderRightEnum()); - assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); - assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); - assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); - assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); - } - } - - wb.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/util/TestIdentifierManager.java b/trunk/src/ooxml/testcases/org/apache/poi/util/TestIdentifierManager.java deleted file mode 100644 index db062f411..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/util/TestIdentifierManager.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.util; - -import junit.framework.TestCase; - -public class TestIdentifierManager extends TestCase -{ - public void testBasic() - { - IdentifierManager manager = new IdentifierManager(0L,100L); - assertEquals(101L,manager.getRemainingIdentifiers()); - assertEquals(0L,manager.reserveNew()); - assertEquals(100L,manager.getRemainingIdentifiers()); - assertEquals(1L,manager.reserve(0L)); - assertEquals(99L,manager.getRemainingIdentifiers()); - } - - public void testLongLimits() - { - long min = IdentifierManager.MIN_ID; - long max = IdentifierManager.MAX_ID; - IdentifierManager manager = new IdentifierManager(min,max); - assertTrue("Limits lead to a long variable overflow", max - min + 1 > 0); - assertTrue("Limits lead to a long variable overflow", manager.getRemainingIdentifiers() > 0); - assertEquals(min,manager.reserveNew()); - assertEquals(max,manager.reserve(max)); - assertEquals(max - min -1, manager.getRemainingIdentifiers()); - manager.release(max); - manager.release(min); - } - - public void testReserve() - { - IdentifierManager manager = new IdentifierManager(10L,30L); - assertEquals(12L,manager.reserve(12L)); - long reserve = manager.reserve(12L); - assertFalse("Same id must be reserved twice!",reserve == 12L); - assertTrue(manager.release(12L)); - assertTrue(manager.release(reserve)); - assertFalse(manager.release(12L)); - assertFalse(manager.release(reserve)); - - manager = new IdentifierManager(0L,2L); - assertEquals(0L,manager.reserve(0L)); - assertEquals(1L,manager.reserve(1L)); - assertEquals(2L,manager.reserve(2L)); - try - { - manager.reserve(0L); - fail("Exception expected"); - } - catch(IllegalStateException e) - { - // expected - } - try - { - manager.reserve(1L); - fail("Exception expected"); - } - catch(IllegalStateException e) - { - // expected - } - try - { - manager.reserve(2L); - fail("Exception expected"); - } - catch(IllegalStateException e) - { - // expected - } - } - - public void testReserveNew() - { - IdentifierManager manager = new IdentifierManager(10L,12L); - assertSame(10L,manager.reserveNew()); - assertSame(11L,manager.reserveNew()); - assertSame(12L,manager.reserveNew()); - try { - manager.reserveNew(); - fail("IllegalStateException expected"); - } - catch (IllegalStateException e) - { - // expected - } - } - - public void testRelease() { - IdentifierManager manager = new IdentifierManager(10L,20L); - assertEquals(10L,manager.reserve(10L)); - assertEquals(11L,manager.reserve(11L)); - assertEquals(12L,manager.reserve(12L)); - assertEquals(13L,manager.reserve(13L)); - assertEquals(14L,manager.reserve(14L)); - - assertTrue(manager.release(10L)); - assertEquals(10L,manager.reserve(10L)); - assertTrue(manager.release(10L)); - - assertTrue(manager.release(11L)); - assertEquals(11L,manager.reserve(11L)); - assertTrue(manager.release(11L)); - assertFalse(manager.release(11L)); - assertFalse(manager.release(10L)); - - assertEquals(10L,manager.reserve(10L)); - assertEquals(11L,manager.reserve(11L)); - assertTrue(manager.release(12L)); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java b/trunk/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java deleted file mode 100644 index 43a6036ba..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xdgf.extractor; - -import java.io.IOException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xdgf.usermodel.XmlVisioDocument; - -import junit.framework.TestCase; - -public class TestXDGFVisioExtractor extends TestCase { - - private POIDataSamples diagrams; - private OPCPackage pkg; - private XmlVisioDocument xml; - - @Override - protected void setUp() throws Exception { - diagrams = POIDataSamples.getDiagramInstance(); - - pkg = OPCPackage.open(diagrams.openResourceAsStream("test_text_extraction.vsdx")); - xml = new XmlVisioDocument(pkg); - } - - public void testGetSimpleText() throws IOException { - new XDGFVisioExtractor(xml).close(); - new XDGFVisioExtractor(pkg).close(); - - XDGFVisioExtractor extractor = new XDGFVisioExtractor(xml); - extractor.getText(); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - assertEquals("Text here\nText there\nText, text, everywhere!\nRouter here\n", - text); - - extractor.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xdgf/usermodel/section/CombinedIteratorTest.java b/trunk/src/ooxml/testcases/org/apache/poi/xdgf/usermodel/section/CombinedIteratorTest.java deleted file mode 100644 index 447684ca9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xdgf/usermodel/section/CombinedIteratorTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xdgf.usermodel.section; - -import java.util.Iterator; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.junit.Assert; -import org.junit.Test; - -public class CombinedIteratorTest { - - void testIteration(CombinedIterable iterable, String... expected) { - - Iterator iter = iterable.iterator(); - - for (String element : expected) { - Assert.assertEquals(true, iter.hasNext()); - Assert.assertEquals(element, iter.next()); - } - - Assert.assertEquals(false, iter.hasNext()); - } - - @Test - public void testNullMaster() { - - SortedMap base = new TreeMap(); - base.put(1L, "B1"); - base.put(2L, "B2"); - base.put(3L, "B3"); - - testIteration(new CombinedIterable(base, null), "B1", "B2", - "B3"); - } - - @Test - public void testNoMatchesBaseFirst() { - - SortedMap base = new TreeMap(); - base.put(1L, "B1"); - base.put(2L, "B2"); - base.put(3L, "B3"); - - SortedMap master = new TreeMap(); - master.put(4L, "M4"); - master.put(5L, "M5"); - master.put(6L, "M6"); - - testIteration(new CombinedIterable(base, master), "B1", "B2", - "B3", "M4", "M5", "M6"); - } - - @Test - public void testNoMatchesMasterFirst() { - - SortedMap base = new TreeMap(); - base.put(4L, "B4"); - base.put(5L, "B5"); - base.put(6L, "B6"); - - SortedMap master = new TreeMap(); - master.put(1L, "M1"); - master.put(2L, "M2"); - master.put(3L, "M3"); - - testIteration(new CombinedIterable(base, master), "M1", "M2", - "M3", "B4", "B5", "B6"); - } - - @Test - public void testInterleaved1() { - - SortedMap base = new TreeMap(); - base.put(1L, "B1"); - base.put(3L, "B3"); - base.put(5L, "B5"); - - SortedMap master = new TreeMap(); - master.put(2L, "M2"); - master.put(4L, "M4"); - master.put(6L, "M6"); - - testIteration(new CombinedIterable(base, master), "B1", "M2", - "B3", "M4", "B5", "M6"); - } - - @Test - public void testInterleaved2() { - - SortedMap base = new TreeMap(); - base.put(1L, "B1"); - base.put(2L, "B2"); - base.put(5L, "B5"); - base.put(6L, "B6"); - - SortedMap master = new TreeMap(); - master.put(3L, "M3"); - master.put(4L, "M4"); - master.put(7L, "M7"); - master.put(8L, "M8"); - - testIteration(new CombinedIterable(base, master), "B1", "B2", - "M3", "M4", "B5", "B6", "M7", "M8"); - } - - @Test - public void testAllMatching() { - - SortedMap base = new TreeMap(); - base.put(1L, "B1"); - base.put(2L, "B2"); - base.put(3L, "B3"); - - SortedMap master = new TreeMap(); - master.put(1L, "M1"); - master.put(2L, "M2"); - master.put(3L, "M3"); - - testIteration(new CombinedIterable(base, master), "B1", "B2", - "B3"); - } - - @Test - public void testAllMatching2() { - - SortedMap base = new TreeMap(); - base.put(1L, "B1"); - base.put(2L, "B2"); - base.put(3L, "B3"); - - SortedMap master = new TreeMap(); - master.put(1L, "M1"); - master.put(2L, "M2"); - master.put(3L, "M3"); - master.put(4L, "M4"); - - testIteration(new CombinedIterable(base, master), "B1", "B2", - "B3", "M4"); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java deleted file mode 100644 index 7c02ba282..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java +++ /dev/null @@ -1,559 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf; - -import static org.apache.poi.POITestCase.assertContains; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.util.Collection; - -import javax.imageio.ImageIO; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLDocumentPart.RelationPart; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFAutoShape; -import org.apache.poi.xslf.usermodel.XSLFHyperlink; -import org.apache.poi.xslf.usermodel.XSLFPictureData; -import org.apache.poi.xslf.usermodel.XSLFPictureShape; -import org.apache.poi.xslf.usermodel.XSLFRelation; -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.poi.xslf.usermodel.XSLFSlide; -import org.apache.poi.xslf.usermodel.XSLFSlideLayout; -import org.apache.poi.xslf.usermodel.XSLFSlideMaster; -import org.apache.poi.xslf.usermodel.XSLFTextRun; -import org.junit.Ignore; -import org.junit.Test; - - -public class TestXSLFBugs { - private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); - - @Test - public void bug51187() throws Exception { - XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("51187.pptx"); - - assertEquals(1, ss1.getSlides().size()); - - // Check the relations on it - // Note - rId3 is a self reference - XSLFSlide slide0 = ss1.getSlides().get(0); - - assertRelation(slide0, "/ppt/slides/slide1.xml", null); - assertRelation(slide0, "/ppt/slideLayouts/slideLayout12.xml", "rId1"); - assertRelation(slide0, "/ppt/notesSlides/notesSlide1.xml", "rId2"); - assertRelation(slide0, "/ppt/slides/slide1.xml", "rId3"); - assertRelation(slide0, "/ppt/media/image1.png", "rId4"); - - // Save and re-load - XMLSlideShow ss2 = XSLFTestDataSamples.writeOutAndReadBack(ss1); - ss1.close(); - assertEquals(1, ss2.getSlides().size()); - - slide0 = ss2.getSlides().get(0); - assertRelation(slide0, "/ppt/slides/slide1.xml", null); - assertRelation(slide0, "/ppt/slideLayouts/slideLayout12.xml", "rId1"); - assertRelation(slide0, "/ppt/notesSlides/notesSlide1.xml", "rId2"); - // TODO Fix this - assertRelation(slide0, "/ppt/slides/slide1.xml", "rId3"); - assertRelation(slide0, "/ppt/media/image1.png", "rId4"); - - ss2.close(); - } - - private static void assertRelation(XSLFSlide slide, String exp, String rId) { - POIXMLDocumentPart pd = (rId != null) ? slide.getRelationById(rId) : slide; - assertEquals(exp, pd.getPackagePart().getPartName().getName()); - } - - /** - * Slide relations with anchors in them - */ - @Test - public void tika705() throws Exception { - XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("with_japanese.pptx"); - - // Should have one slide - assertEquals(1, ss.getSlides().size()); - XSLFSlide slide = ss.getSlides().get(0); - - // Check the relations from this - Collection rels = slide.getRelationParts(); - - // Should have 6 relations: - // 1 external hyperlink (skipped from list) - // 4 internal hyperlinks - // 1 slide layout - assertEquals(5, rels.size()); - int layouts = 0; - int hyperlinks = 0; - for(RelationPart p : rels) { - if(p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) { - hyperlinks++; - } else if(p.getDocumentPart() instanceof XSLFSlideLayout) { - layouts++; - } - } - assertEquals(1, layouts); - assertEquals(4, hyperlinks); - - // Hyperlinks should all be to #_ftn1 or #ftnref1 - for(RelationPart p : rels) { - if(p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) { - URI target = p.getRelationship().getTargetURI(); - - if(target.getFragment().equals("_ftn1") || - target.getFragment().equals("_ftnref1")) { - // Good - } else { - fail("Invalid target " + target.getFragment() + " on " + target); - } - } - } - ss.close(); - } - - /** - * A slideshow can have more than one rID pointing to a given - * slide, eg presentation.xml rID1 -> slide1.xml, but slide1.xml - * rID2 -> slide3.xml - */ - @Test - public void bug54916() throws Exception { - XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("OverlappingRelations.pptx"); - XSLFSlide slide; - - // Should find 4 slides - assertEquals(4, ss.getSlides().size()); - - // Check the text, to see we got them in order - slide = ss.getSlides().get(0); - assertContains(getSlideText(slide), "POI cannot read this"); - - slide = ss.getSlides().get(1); - assertContains(getSlideText(slide), "POI can read this"); - assertContains(getSlideText(slide), "Has a relationship to another slide"); - - slide = ss.getSlides().get(2); - assertContains(getSlideText(slide), "POI can read this"); - - slide = ss.getSlides().get(3); - assertContains(getSlideText(slide), "POI can read this"); - - ss.close(); - } - - /** - * When the picture is not embedded but inserted only as a "link to file", - * there is no data available and XSLFPictureShape.getPictureData() - * gives a NPE, see bug #56812 - */ - @Test - public void bug56812() throws Exception { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("56812.pptx"); - - int internalPictures = 0; - int externalPictures = 0; - for (XSLFSlide slide : ppt.getSlides()){ - for (XSLFShape shape : slide.getShapes()){ - assertNotNull(shape); - - if (shape instanceof XSLFPictureShape) { - XSLFPictureShape picture = (XSLFPictureShape)shape; - if (picture.isExternalLinkedPicture()) { - externalPictures++; - - assertNotNull(picture.getPictureLink()); - } else { - internalPictures++; - - XSLFPictureData data = picture.getPictureData(); - assertNotNull(data); - assertNotNull(data.getFileName()); - } - } - } - } - - assertEquals(2, internalPictures); - assertEquals(1, externalPictures); - ppt.close(); - } - - @Test - @Ignore("Similar to TestFontRendering it doesn't make sense to compare images because of tiny rendering differences in windows/unix") - public void bug54542() throws Exception { - XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("54542_cropped_bitmap.pptx"); - - Dimension pgsize = ss.getPageSize(); - - XSLFSlide slide = ss.getSlides().get(0); - - // render it - double zoom = 1; - AffineTransform at = new AffineTransform(); - at.setToScale(zoom, zoom); - - BufferedImage imgActual = new BufferedImage((int)Math.ceil(pgsize.width*zoom), (int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_3BYTE_BGR); - Graphics2D graphics = imgActual.createGraphics(); - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - graphics.setTransform(at); - graphics.setPaint(Color.white); - graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height)); - slide.draw(graphics); - - ImageIO.write(imgActual, "PNG", new File("bug54542.png")); - ss.close(); - } - - protected String getSlideText(XSLFSlide slide) { - return XSLFPowerPointExtractor.getText(slide, true, false, false); - } - - @Test - public void bug57250() throws Exception { - XMLSlideShow ss = new XMLSlideShow(); - for (String s : new String[]{"Slide1","Slide2"}) { - ss.createSlide().createTextBox().setText(s); - } - validateSlides(ss, false, "Slide1","Slide2"); - - XSLFSlide slide = ss.createSlide(); - slide.createTextBox().setText("New slide"); - validateSlides(ss, true, "Slide1","Slide2","New slide"); - - // Move backward - ss.setSlideOrder(slide, 0); - validateSlides(ss, true, "New slide","Slide1","Slide2"); - - // Move forward - ss.setSlideOrder(slide, 1); - validateSlides(ss, true, "Slide1","New slide","Slide2"); - - // Move to end - ss.setSlideOrder(slide, 0); - ss.setSlideOrder(slide, 2); - validateSlides(ss, true, "Slide1","Slide2","New slide"); - ss.close(); - } - - /** - * When working with >9 images, make sure the sorting ensures - * that image10.foo isn't between image1.foo and image2.foo - */ - @Test - public void test57552() throws Exception { - XMLSlideShow ss = new XMLSlideShow(); - for (String s : new String[]{"Slide1","Slide2"}) { - ss.createSlide().createTextBox().setText(s); - } - - // Slide starts with just layout relation - XSLFSlide slide = ss.getSlides().get(0); - assertEquals(0, ss.getPictureData().size()); - assertEquals(1, slide.getShapes().size()); - - assertEquals(1, slide.getRelations().size()); - assertRelationEquals(XSLFRelation.SLIDE_LAYOUT, slide.getRelations().get(0)); - - // Some dummy pictures - byte[][] pics = new byte[15][3]; - for (int i=0; i 1); - ppt.removeSlide(1); - assertNotNull(ppt.createSlide()); - } - - @Test - public void blibFillAlternateContent() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("2411-Performance_Up.pptx"); - XSLFPictureShape ps = (XSLFPictureShape)ppt.getSlides().get(4).getShapes().get(0); - assertNotNull(ps.getPictureData()); - ppt.close(); - } - - @Test - public void bug59434() throws IOException { - String url1 = "http://poi.apache.org/changes.html"; - String url2 = "http://poi.apache.org/faq.html"; - XMLSlideShow ppt1 = new XMLSlideShow(); - PictureData pd1 = ppt1.addPicture(slTests.readFile("tomcat.png"), PictureType.PNG); - PictureData pd2 = ppt1.addPicture(slTests.readFile("santa.wmf"), PictureType.WMF); - XSLFSlide slide = ppt1.createSlide(); - XSLFPictureShape ps1 = slide.createPicture(pd1); - ps1.setAnchor(new Rectangle2D.Double(20, 20, 100, 100)); - XSLFHyperlink hl1 = ps1.createHyperlink(); - hl1.linkToUrl(url1); - XSLFPictureShape ps2 = slide.createPicture(pd2); - ps2.setAnchor(new Rectangle2D.Double(120, 120, 100, 100)); - XSLFHyperlink hl2 = ps2.createHyperlink(); - hl2.linkToUrl(url2); - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1); - ppt1.close(); - slide = ppt2.getSlides().get(0); - ps1 = (XSLFPictureShape)slide.getShapes().get(0); - ps2 = (XSLFPictureShape)slide.getShapes().get(1); - assertEquals(url1, ps1.getHyperlink().getAddress()); - assertEquals(url2, ps2.getHyperlink().getAddress()); - - ppt2.close(); - } - - @Test - public void bug58217() throws IOException { - Color fillColor = new Color(1f,1f,0f,0.1f); - Color lineColor = new Color(25.3f/255f,1f,0f,0.4f); - Color textColor = new Color(1f,1f,0f,0.6f); - - XMLSlideShow ppt1 = new XMLSlideShow(); - XSLFSlide sl = ppt1.createSlide(); - XSLFAutoShape as = sl.createAutoShape(); - as.setShapeType(ShapeType.STAR_10); - as.setAnchor(new Rectangle2D.Double(100,100,300,300)); - as.setFillColor(fillColor); - as.setLineColor(lineColor); - as.setText("Alpha"); - as.setVerticalAlignment(VerticalAlignment.MIDDLE); - as.setHorizontalCentered(true); - XSLFTextRun tr = as.getTextParagraphs().get(0).getTextRuns().get(0); - tr.setFontSize(32d); - tr.setFontColor(textColor); - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1); - ppt1.close(); - sl = ppt2.getSlides().get(0); - as = (XSLFAutoShape)sl.getShapes().get(0); - checkColor(fillColor, as.getFillStyle().getPaint()); - checkColor(lineColor, as.getStrokeStyle().getPaint()); - checkColor(textColor, as.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor()); - ppt2.close(); - } - - private static void checkColor(Color expected, PaintStyle actualStyle) { - assertTrue(actualStyle instanceof SolidPaint); - SolidPaint ps = (SolidPaint)actualStyle; - Color actual = DrawPaint.applyColorTransform(ps.getSolidColor()); - float expRGB[] = expected.getRGBComponents(null); - float actRGB[] = actual.getRGBComponents(null); - assertArrayEquals(expRGB, actRGB, 0.0001f); - } - - @Test - public void bug55714() throws IOException { - XMLSlideShow srcPptx = XSLFTestDataSamples.openSampleDocument("pptx2svg.pptx"); - XMLSlideShow newPptx = new XMLSlideShow(); - XSLFSlide srcSlide = srcPptx.getSlides().get(0); - XSLFSlide newSlide = newPptx.createSlide(); - - XSLFSlideLayout srcSlideLayout = srcSlide.getSlideLayout(); - XSLFSlideLayout newSlideLayout = newSlide.getSlideLayout(); - newSlideLayout.importContent(srcSlideLayout); - - XSLFSlideMaster srcSlideMaster = srcSlide.getSlideMaster(); - XSLFSlideMaster newSlideMaster = newSlide.getSlideMaster(); - newSlideMaster.importContent(srcSlideMaster); - - newSlide.importContent(srcSlide); - XMLSlideShow rwPptx = XSLFTestDataSamples.writeOutAndReadBack(newPptx); - - PaintStyle ps = rwPptx.getSlides().get(0).getBackground().getFillStyle().getPaint(); - assertTrue(ps instanceof TexturePaint); - - rwPptx.close(); - newPptx.close(); - srcPptx.close(); - } - - @Test - public void bug59273() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("bug59273.potx"); - ppt.getPackage().replaceContentType( - XSLFRelation.PRESENTATIONML_TEMPLATE.getContentType(), - XSLFRelation.MAIN.getContentType() - ); - - XMLSlideShow rwPptx = XSLFTestDataSamples.writeOutAndReadBack(ppt); - OPCPackage pkg = rwPptx.getPackage(); - int size = pkg.getPartsByContentType(XSLFRelation.MAIN.getContentType()).size(); - assertEquals(1, size); - size = pkg.getPartsByContentType(XSLFRelation.PRESENTATIONML_TEMPLATE.getContentType()).size(); - assertEquals(0, size); - - rwPptx.close(); - ppt.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java deleted file mode 100644 index 95dd57d15..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIXMLProperties.CoreProperties; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFAutoShape; -import org.apache.poi.xslf.usermodel.XSLFBackground; -import org.apache.poi.xslf.usermodel.XSLFRelation; -import org.apache.poi.xslf.usermodel.XSLFSlide; -import org.apache.poi.xslf.usermodel.XSLFSlideShow; -import org.apache.xmlbeans.XmlException; -import org.junit.Before; -import org.junit.Test; -import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry; -import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry; - -public class TestXSLFSlideShow { - private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); - private OPCPackage pack; - - @Before - public void setUp() throws Exception { - pack = OPCPackage.open(slTests.openResourceAsStream("sample.pptx")); - } - - @Test - public void testContainsMainContentType() throws Exception { - boolean found = false; - for(PackagePart part : pack.getParts()) { - if(part.getContentType().equals(XSLFRelation.MAIN.getContentType())) { - found = true; - } - } - assertTrue(found); - } - - @Test - public void testOpen() throws IOException, OpenXML4JException, XmlException { - // With the finalized uri, should be fine - XSLFSlideShow xml = new XSLFSlideShow(pack); - // Check the core - assertNotNull(xml.getPresentation()); - - // Check it has some slides - assertNotEquals(0, xml.getSlideReferences().sizeOfSldIdArray()); - assertNotEquals(0, xml.getSlideMasterReferences().sizeOfSldMasterIdArray()); - - xml.close(); - } - - @Test - public void testSlideBasics() throws IOException, OpenXML4JException, XmlException { - XSLFSlideShow xml = new XSLFSlideShow(pack); - - // Should have 1 master - assertEquals(1, xml.getSlideMasterReferences().sizeOfSldMasterIdArray()); - - // Should have three sheets - assertEquals(2, xml.getSlideReferences().sizeOfSldIdArray()); - - // Check they're as expected - CTSlideIdListEntry[] slides = xml.getSlideReferences().getSldIdArray(); - - assertEquals(256, slides[0].getId()); - assertEquals(257, slides[1].getId()); - assertEquals("rId2", slides[0].getId2()); - assertEquals("rId3", slides[1].getId2()); - - // Now get those objects - assertNotNull(xml.getSlide(slides[0])); - assertNotNull(xml.getSlide(slides[1])); - - // And check they have notes as expected - assertNotNull(xml.getNotes(slides[0])); - assertNotNull(xml.getNotes(slides[1])); - - // And again for the master - CTSlideMasterIdListEntry[] masters = xml.getSlideMasterReferences().getSldMasterIdArray(); - - assertEquals(2147483648l, masters[0].getId()); - assertEquals("rId1", masters[0].getId2()); - assertNotNull(xml.getSlideMaster(masters[0])); - - xml.close(); - } - - @Test - public void testMetadataBasics() throws IOException, OpenXML4JException, XmlException { - XSLFSlideShow xml = new XSLFSlideShow(pack); - - assertNotNull(xml.getProperties().getCoreProperties()); - assertNotNull(xml.getProperties().getExtendedProperties()); - - CTProperties props = xml.getProperties().getExtendedProperties().getUnderlyingProperties(); - assertEquals("Microsoft Office PowerPoint", props.getApplication()); - assertEquals(0, props.getCharacters()); - assertEquals(0, props.getLines()); - - CoreProperties cprops = xml.getProperties().getCoreProperties(); - assertNull(cprops.getTitle()); - assertNull(cprops.getUnderlyingProperties().getSubjectProperty().getValue()); - - xml.close(); - } - - @Test - public void testMasterBackground() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFBackground b = ppt.getSlideMasters().get(0).getBackground(); - b.setFillColor(Color.RED); - - XSLFSlide sl = ppt.createSlide(); - XSLFAutoShape as = sl.createAutoShape(); - as.setAnchor(new Rectangle2D.Double(100,100,100,100)); - as.setShapeType(ShapeType.CLOUD); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt); - ppt.close(); - - XSLFBackground b2 = ppt2.getSlideMasters().get(0).getBackground(); - assertEquals(Color.RED, b2.getFillColor()); - - ppt2.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/XSLFTestDataSamples.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/XSLFTestDataSamples.java deleted file mode 100644 index 550c4d8b9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/XSLFTestDataSamples.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xslf.usermodel.XMLSlideShow; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Yegor Kozlov - */ -public class XSLFTestDataSamples { - - public static XMLSlideShow openSampleDocument(String sampleName) { - InputStream is = POIDataSamples.getSlideShowInstance().openResourceAsStream(sampleName); - try { - return new XMLSlideShow(OPCPackage.open(is)); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - try { - is.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - public static XMLSlideShow writeOutAndReadBack(XMLSlideShow doc) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); - try { - doc.write(baos); - } catch (IOException e) { - throw new RuntimeException(e); - } - - InputStream bais; - bais = new ByteArrayInputStream(baos.toByteArray()); - try { - return new XMLSlideShow(OPCPackage.open(bais)); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - try { - baos.close(); - bais.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestXSLFPowerPointExtractor.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestXSLFPowerPointExtractor.java deleted file mode 100644 index f76e084f9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/extractor/TestXSLFPowerPointExtractor.java +++ /dev/null @@ -1,328 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.extractor; - -import static org.apache.poi.POITestCase.assertContains; -import static org.apache.poi.POITestCase.assertNotContained; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POITextExtractor; -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.xmlbeans.XmlException; -import org.junit.Test; - -/** - * Tests for XSLFPowerPointExtractor - */ -public class TestXSLFPowerPointExtractor { - private static POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); - - /** - * Get text out of the simple file - * @throws XmlException - * @throws OpenXML4JException - */ - @Test - public void testGetSimpleText() - throws IOException, XmlException, OpenXML4JException { - XMLSlideShow xmlA = openPPTX("sample.pptx"); - @SuppressWarnings("resource") - OPCPackage pkg = xmlA.getPackage(); - - new XSLFPowerPointExtractor(xmlA).close(); - new XSLFPowerPointExtractor(pkg).close(); - - XSLFPowerPointExtractor extractor = - new XSLFPowerPointExtractor(xmlA); - extractor.getText(); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check Basics - assertTrue(text.startsWith("Lorem ipsum dolor sit amet\n")); - assertContains(text, "amet\n\n"); - - // Our placeholder master text - // This shouldn't show up in the output - // String masterText = - // "Click to edit Master title style\n" + - // "Click to edit Master subtitle style\n" + - // "\n\n\n\n\n\n" + - // "Click to edit Master title style\n" + - // "Click to edit Master text styles\n" + - // "Second level\n" + - // "Third level\n" + - // "Fourth level\n" + - // "Fifth level\n"; - - // Just slides, no notes - text = extractor.getText(true, false, false); - String slideText = - "Lorem ipsum dolor sit amet\n" + - "Nunc at risus vel erat tempus posuere. Aenean non ante.\n" + - "\n" + - "Lorem ipsum dolor sit amet\n" + - "Lorem\n" + - "ipsum\n" + - "dolor\n" + - "sit\n" + - "amet\n" + - "\n"; - assertEquals(slideText, text); - - // Just notes, no slides - text = extractor.getText(false, true); - assertEquals("\n\n1\n\n\n2\n", text); - - // Both - text = extractor.getText(true, true, false); - String bothText = - "Lorem ipsum dolor sit amet\n" + - "Nunc at risus vel erat tempus posuere. Aenean non ante.\n" + - "\n\n\n1\n" + - "Lorem ipsum dolor sit amet\n" + - "Lorem\n" + - "ipsum\n" + - "dolor\n" + - "sit\n" + - "amet\n" + - "\n\n\n2\n"; - assertEquals(bothText, text); - - // With Slides and Master Text - text = extractor.getText(true, false, true); - String smText = - "Lorem ipsum dolor sit amet\n" + - "Nunc at risus vel erat tempus posuere. Aenean non ante.\n" + - "\n" + - "Lorem ipsum dolor sit amet\n" + - "Lorem\n" + - "ipsum\n" + - "dolor\n" + - "sit\n" + - "amet\n" + - "\n"; - assertEquals(smText, text); - - // With Slides, Notes and Master Text - text = extractor.getText(true, true, true); - String snmText = - "Lorem ipsum dolor sit amet\n" + - "Nunc at risus vel erat tempus posuere. Aenean non ante.\n" + - "\n\n\n1\n" + - "Lorem ipsum dolor sit amet\n" + - "Lorem\n" + - "ipsum\n" + - "dolor\n" + - "sit\n" + - "amet\n" + - "\n\n\n2\n"; - assertEquals(snmText, text); - - // Via set defaults - extractor.setSlidesByDefault(false); - extractor.setNotesByDefault(true); - text = extractor.getText(); - assertEquals("\n\n1\n\n\n2\n", text); - - extractor.close(); - xmlA.close(); - } - - public void testGetComments() throws IOException { - XMLSlideShow xml = openPPTX("45545_Comment.pptx"); - XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(xml); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check comments are there - assertContains(text, "testdoc"); - assertContains(text, "test phrase"); - - // Check the authors came through too - assertContains(text, "XPVMWARE01"); - - extractor.close(); - xml.close(); - } - - public void testGetMasterText() throws Exception { - XMLSlideShow xml = openPPTX("WithMaster.pptx"); - XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(xml); - extractor.setSlidesByDefault(true); - extractor.setNotesByDefault(false); - extractor.setMasterByDefault(true); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check master text is there - assertContains(text, "Footer from the master slide"); - - // Theme text shouldn't show up - // String themeText = - // "Theme Master Title\n" + - // "Theme Master first level\n" + - // "And the 2nd level\n" + - // "Our 3rd level goes here\n" + - // "And onto the 4th, such fun....\n" + - // "Finally is the Fifth level\n"; - - // Check the whole text - String wholeText = - "First page title\n" + - "First page subtitle\n" + - "This is the Master Title\n" + - "This text comes from the Master Slide\n" + - "\n" + - // TODO Detect we didn't have a title, and include the master one - "2nd page subtitle\n" + - "Footer from the master slide\n" + - "This is the Master Title\n" + - "This text comes from the Master Slide\n"; - assertEquals(wholeText, text); - - extractor.close(); - xml.close(); - } - - @Test - public void testTable() throws Exception { - XMLSlideShow xml = openPPTX("present1.pptx"); - XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(xml); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check comments are there - assertTrue("Unable to find expected word in text\n" + text, text.contains("TEST")); - - extractor.close(); - xml.close(); - } - - /** - * Test that we can get the text from macro enabled, - * template, theme, slide enabled etc formats, as - * well as from the normal file - */ - @Test - public void testDifferentSubformats() throws Exception { - String[] extensions = new String[] { - "pptx", "pptm", "ppsm", "ppsx", "thmx", - // "xps" - Doesn't have a core document - }; - for(String extension : extensions) { - String filename = "testPPT." + extension; - XMLSlideShow xml = openPPTX(filename); - XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(xml); - - String text = extractor.getText(); - if (extension.equals("thmx")) { - // Theme file doesn't have any textual content - assertEquals(0, text.length()); - continue; - } - - assertTrue(text.length() > 0); - assertTrue( - "Text missing for " + filename + "\n" + text, - text.contains("Attachment Test") - ); - assertTrue( - "Text missing for " + filename + "\n" + text, - text.contains("This is a test file data with the same content") - ); - assertTrue( - "Text missing for " + filename + "\n" + text, - text.contains("content parsing") - ); - assertTrue( - "Text missing for " + filename + "\n" + text, - text.contains("Different words to test against") - ); - assertTrue( - "Text missing for " + filename + "\n" + text, - text.contains("Mystery") - ); - - extractor.close(); - xml.close(); - } - } - - @Test - public void test45541() throws Exception { - // extract text from a powerpoint that has a header in the notes-element - POITextExtractor extr = ExtractorFactory.createExtractor( - slTests.getFile("45541_Header.pptx")); - String text = extr.getText(); - assertNotNull(text); - assertFalse("Had: " + text, text.contains("testdoc")); - - text = ((XSLFPowerPointExtractor)extr).getText(false, true); - assertContains(text, "testdoc"); - extr.close(); - assertNotNull(text); - - // extract text from a powerpoint that has a footer in the master-slide - extr = ExtractorFactory.createExtractor( - slTests.getFile("45541_Footer.pptx")); - text = extr.getText(); - assertNotContained(text, "testdoc"); - - text = ((XSLFPowerPointExtractor)extr).getText(false, true); - assertNotContained(text, "testdoc"); - - text = ((XSLFPowerPointExtractor)extr).getText(false, false, true); - assertNotContained(text, "testdoc"); - - extr.close(); - } - - - @Test - public void bug54570() throws IOException { - XMLSlideShow xml = openPPTX("bug54570.pptx"); - XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(xml); - String text = extractor.getText(); - assertNotNull(text); - extractor.close(); - xml.close(); - } - - private XMLSlideShow openPPTX(String file) throws IOException { - InputStream is = slTests.openResourceAsStream(file); - try { - return new XMLSlideShow(is); - } finally { - is.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java deleted file mode 100644 index 36d42471c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.xslf.geom; - -import static org.junit.Assert.assertEquals; - -import org.apache.poi.sl.draw.binding.CTCustomGeometry2D; -import org.apache.poi.sl.draw.geom.*; -import org.junit.Test; - -/** - * Date: 10/24/11 - * - * @author Yegor Kozlov - */ -public class TestFormulaParser { - @Test - public void testParse(){ - - Formula[] ops = { - new Guide("adj1", "val 100"), - new Guide("adj2", "val 200"), - new Guide("adj3", "val -1"), - new Guide("a1", "*/ adj1 2 adj2"), // a1 = 100*2 / 200 - new Guide("a2", "+- adj2 a1 adj1"), // a2 = 200 + a1 - 100 - new Guide("a3", "+/ adj1 adj2 adj2"), // a3 = (100 + 200) / 200 - new Guide("a4", "?: adj3 adj1 adj2"), // a4 = adj3 > 0 ? adj1 : adj2 - new Guide("a5", "abs -2"), - }; - - CustomGeometry geom = new CustomGeometry(new CTCustomGeometry2D()); - Context ctx = new Context(geom, null, null); - for(Formula fmla : ops) { - ctx.evaluate(fmla); - } - - assertEquals(100.0, ctx.getValue("adj1"), 0.0); - assertEquals(200.0, ctx.getValue("adj2"), 0.0); - assertEquals(1.0, ctx.getValue("a1"), 0.0); - assertEquals(101.0, ctx.getValue("a2"), 0.0); - assertEquals(1.5, ctx.getValue("a3"), 0.0); - assertEquals(200.0, ctx.getValue("a4"), 0.0); - assertEquals(2.0, ctx.getValue("a5"), 0.0); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java deleted file mode 100644 index 9ad888da4..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.io.File; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.xslf.util.PPTX2PNG; -import org.junit.Test; - -/** - * Date: 10/26/11 - * - * @author Yegor Kozlov - */ -public class TestPPTX2PNG { - - @Test - public void render() throws Exception { - POIDataSamples samples = POIDataSamples.getSlideShowInstance(); - -// File testFilesX[] = new File("tmp_ppt").listFiles(new FileFilter() { -// public boolean accept(File pathname) { -// return pathname.getName().toLowerCase().contains("ppt"); -// } -// }); -// String testFiles[] = new String[testFilesX.length]; -// for (int i=0; i pieModel = new LinkedHashMap(); - pieModel.put("First", 1.0); - pieModel.put("Second", 3.0); - pieModel.put("Third", 4.0); - - // set model - int idx = 0; - int rownum = 1; - for(String key : pieModel.keySet()){ - double val = pieModel.get(key); - - CTNumVal numVal = numData.addNewPt(); - numVal.setIdx(idx); - numVal.setV("" + val); - - CTStrVal sVal = strData.addNewPt(); - sVal.setIdx(idx); - sVal.setV(key); - - idx++; - XSSFRow row = sheet.createRow(rownum++); - row.createCell(0).setCellValue(key); - row.createCell(1).setCellValue(val); - } - numData.getPtCount().setVal(idx); - strData.getPtCount().setVal(idx); - - String numDataRange = new CellRangeAddress(1, rownum-1, 1, 1).formatAsString(sheet.getSheetName(), true); - valSrc.getNumRef().setF(numDataRange); - String axisDataRange = new CellRangeAddress(1, rownum-1, 0, 0).formatAsString(sheet.getSheetName(), true); - cat.getStrRef().setF(axisDataRange); - - // updated the embedded workbook with the data - OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream(); - wb.write(xlsOut); - xlsOut.close(); - - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java deleted file mode 100644 index 659f4beae..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java +++ /dev/null @@ -1,184 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.PresetColor; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSystemColor; -import org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal; -import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal; -import org.openxmlformats.schemas.drawingml.x2006.main.STSystemColorVal; - -public class TestXSLFColor { - - @Test - public void testGetters() { - CTColor xml = CTColor.Factory.newInstance(); - CTSRgbColor c = xml.addNewSrgbClr(); - c.setVal(new byte[]{(byte)0xFF, 0, 0}); - - XSLFColor color = new XSLFColor(xml, null, null); - - assertEquals(-1, color.getAlpha()); - c.addNewAlpha().setVal(50000); - assertEquals(50, color.getAlpha()); - - assertEquals(-1, color.getAlphaMod()); - c.addNewAlphaMod().setVal(50000); - assertEquals(50, color.getAlphaMod()); - - assertEquals(-1, color.getAlphaOff()); - c.addNewAlphaOff().setVal(50000); - assertEquals(50, color.getAlphaOff()); - - assertEquals(-1, color.getLumMod()); - c.addNewLumMod().setVal(50000); - assertEquals(50, color.getLumMod()); - - assertEquals(-1, color.getLumOff()); - c.addNewLumOff().setVal(50000); - assertEquals(50, color.getLumOff()); - - assertEquals(-1, color.getSat()); - c.addNewSat().setVal(50000); - assertEquals(50, color.getSat()); - - assertEquals(-1, color.getSatMod()); - c.addNewSatMod().setVal(50000); - assertEquals(50, color.getSatMod()); - - assertEquals(-1, color.getSatOff()); - c.addNewSatOff().setVal(50000); - assertEquals(50, color.getSatOff()); - - assertEquals(-1, color.getRed()); - c.addNewRed().setVal(50000); - assertEquals(50, color.getRed()); - - assertEquals(-1, color.getGreen()); - c.addNewGreen().setVal(50000); - assertEquals(50, color.getGreen()); - - assertEquals(-1, color.getBlue()); - c.addNewBlue().setVal(50000); - assertEquals(50, color.getRed()); - - assertEquals(-1, color.getShade()); - c.addNewShade().setVal(50000); - assertEquals(50, color.getShade()); - - assertEquals(-1, color.getTint()); - c.addNewTint().setVal(50000); - assertEquals(50, color.getTint()); - } - - @Test - public void testHSL() { - CTColor xml = CTColor.Factory.newInstance(); - CTHslColor c = xml.addNewHslClr(); - c.setHue2(14400000); - c.setSat2(100000); - c.setLum2(50000); - - XSLFColor color = new XSLFColor(xml, null, null); - assertEquals(Color.BLUE, color.getColor()); - } - - @Test - public void testSRgb() { - CTColor xml = CTColor.Factory.newInstance(); - xml.addNewSrgbClr().setVal(new byte[]{ (byte)0xFF, (byte)0xFF, 0}); - - XSLFColor color = new XSLFColor(xml, null, null); - assertEquals(new Color(0xFF, 0xFF, 0), color.getColor()); - } - - @Test - public void testSchemeColor() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFTheme theme = ppt.createSlide().getTheme(); - - CTColor xml = CTColor.Factory.newInstance(); - xml.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_2); - - XSLFColor color = new XSLFColor(xml, theme, null); - // accent2 is theme1.xml is - assertEquals(Color.decode("0xC0504D"), color.getColor()); - - xml = CTColor.Factory.newInstance(); - xml.addNewSchemeClr().setVal(STSchemeColorVal.LT_1); - color = new XSLFColor(xml, theme, null); - // - assertEquals(Color.decode("0xFFFFFF"), color.getColor()); - - xml = CTColor.Factory.newInstance(); - xml.addNewSchemeClr().setVal(STSchemeColorVal.DK_1); - color = new XSLFColor(xml, theme, null); - // - assertEquals(Color.decode("0x000000"), color.getColor()); - - ppt.close(); - } - - @Test - public void testPresetColor() { - CTColor xml = CTColor.Factory.newInstance(); - xml.addNewPrstClr().setVal(STPresetColorVal.AQUAMARINE); - XSLFColor color = new XSLFColor(xml, null, null); - assertEquals(new Color(127, 255, 212), color.getColor()); - - - for(PresetColor pc : PresetColor.values()) { - if (pc.ooxmlId == null) continue; - xml = CTColor.Factory.newInstance(); - STPresetColorVal.Enum preVal = STPresetColorVal.Enum.forString(pc.ooxmlId); - STSystemColorVal.Enum sysVal = STSystemColorVal.Enum.forString(pc.ooxmlId); - assertTrue(pc.ooxmlId, preVal != null || sysVal != null); - if (preVal != null) { - xml.addNewPrstClr().setVal(preVal); - } else { - xml.addNewSysClr().setVal(sysVal); - } - color = new XSLFColor(xml, null, null); - assertEquals(pc.color, color.getColor()); - } - } - - @Test - public void testSys() { - CTColor xml = CTColor.Factory.newInstance(); - CTSystemColor sys = xml.addNewSysClr(); - sys.setVal(STSystemColorVal.CAPTION_TEXT); - XSLFColor color = new XSLFColor(xml, null, null); - assertEquals(Color.black, color.getColor()); - - xml = CTColor.Factory.newInstance(); - sys = xml.addNewSysClr(); - sys.setLastClr(new byte[]{(byte)0xFF, 0, 0}); - color = new XSLFColor(xml, null, null); - assertEquals(Color.red, color.getColor()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java deleted file mode 100644 index 059856242..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java +++ /dev/null @@ -1,159 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; - -import java.awt.Color; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; -import org.apache.poi.sl.usermodel.ShapeType; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTConnection; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualConnectorProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; - -public class TestXSLFConnectorShape { - - @Test - public void testLineDecorations() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFConnectorShape shape = slide.createConnector(); - assertEquals(1, slide.getShapes().size()); - - assertFalse(getSpPr(shape).getLn().isSetHeadEnd()); - assertFalse(getSpPr(shape).getLn().isSetTailEnd()); - - // line decorations - assertEquals(DecorationShape.NONE, shape.getLineHeadDecoration()); - assertEquals(DecorationShape.NONE, shape.getLineTailDecoration()); - shape.setLineHeadDecoration(null); - shape.setLineTailDecoration(null); - assertEquals(DecorationShape.NONE, shape.getLineHeadDecoration()); - assertEquals(DecorationShape.NONE, shape.getLineTailDecoration()); - assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetType()); - assertFalse(getSpPr(shape).getLn().getTailEnd().isSetType()); - - shape.setLineHeadDecoration(DecorationShape.ARROW); - shape.setLineTailDecoration(DecorationShape.DIAMOND); - assertEquals(DecorationShape.ARROW, shape.getLineHeadDecoration()); - assertEquals(DecorationShape.DIAMOND, shape.getLineTailDecoration()); - assertEquals(STLineEndType.ARROW, getSpPr(shape).getLn().getHeadEnd().getType()); - assertEquals(STLineEndType.DIAMOND, getSpPr(shape).getLn().getTailEnd().getType()); - - shape.setLineHeadDecoration(DecorationShape.DIAMOND); - shape.setLineTailDecoration(DecorationShape.ARROW); - assertEquals(DecorationShape.DIAMOND, shape.getLineHeadDecoration()); - assertEquals(DecorationShape.ARROW, shape.getLineTailDecoration()); - assertEquals(STLineEndType.DIAMOND, getSpPr(shape).getLn().getHeadEnd().getType()); - assertEquals(STLineEndType.ARROW, getSpPr(shape).getLn().getTailEnd().getType()); - - // line end width - assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth()); - assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth()); - shape.setLineHeadWidth(null); - shape.setLineHeadWidth(null); - assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth()); - assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth()); - assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetW()); - assertFalse(getSpPr(shape).getLn().getTailEnd().isSetW()); - shape.setLineHeadWidth(DecorationSize.LARGE); - shape.setLineTailWidth(DecorationSize.MEDIUM); - assertEquals(DecorationSize.LARGE, shape.getLineHeadWidth()); - assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth()); - assertEquals(STLineEndWidth.LG, getSpPr(shape).getLn().getHeadEnd().getW()); - assertEquals(STLineEndWidth.MED, getSpPr(shape).getLn().getTailEnd().getW()); - shape.setLineHeadWidth(DecorationSize.MEDIUM); - shape.setLineTailWidth(DecorationSize.LARGE); - assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth()); - assertEquals(DecorationSize.LARGE, shape.getLineTailWidth()); - assertEquals(STLineEndWidth.MED, getSpPr(shape).getLn().getHeadEnd().getW()); - assertEquals(STLineEndWidth.LG, getSpPr(shape).getLn().getTailEnd().getW()); - - // line end length - assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength()); - assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength()); - shape.setLineHeadLength(null); - shape.setLineTailLength(null); - assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength()); - assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength()); - assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetLen()); - assertFalse(getSpPr(shape).getLn().getTailEnd().isSetLen()); - shape.setLineHeadLength(DecorationSize.LARGE); - shape.setLineTailLength(DecorationSize.MEDIUM); - assertEquals(DecorationSize.LARGE, shape.getLineHeadLength()); - assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength()); - assertEquals(STLineEndLength.LG, getSpPr(shape).getLn().getHeadEnd().getLen()); - assertEquals(STLineEndLength.MED, getSpPr(shape).getLn().getTailEnd().getLen()); - shape.setLineHeadLength(DecorationSize.MEDIUM); - shape.setLineTailLength(DecorationSize.LARGE); - assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength()); - assertEquals(DecorationSize.LARGE, shape.getLineTailLength()); - assertEquals(STLineEndLength.MED, getSpPr(shape).getLn().getHeadEnd().getLen()); - assertEquals(STLineEndLength.LG, getSpPr(shape).getLn().getTailEnd().getLen()); - - ppt.close(); - } - - @Test - public void testAddConnector() throws IOException { - XMLSlideShow pptx = new XMLSlideShow(); - XSLFSlide slide = pptx.createSlide(); - - XSLFAutoShape rect1 = slide.createAutoShape(); - rect1.setShapeType(ShapeType.RECT); - rect1.setAnchor(new Rectangle2D.Double(100, 100, 100, 100)); - rect1.setFillColor(Color.blue); - - XSLFAutoShape rect2 = slide.createAutoShape(); - rect2.setShapeType(ShapeType.RECT); - rect2.setAnchor(new Rectangle2D.Double(300, 300, 100, 100)); - rect2.setFillColor(Color.red); - - - XSLFConnectorShape connector1 = slide.createConnector(); - connector1.setAnchor(new Rectangle2D.Double(200, 150, 100, 200)); - - CTConnector ctConnector = (CTConnector)connector1.getXmlObject(); - ctConnector.getSpPr().getPrstGeom().setPrst(STShapeType.BENT_CONNECTOR_3); - CTNonVisualConnectorProperties cx = ctConnector.getNvCxnSpPr().getCNvCxnSpPr(); - // connection start - CTConnection stCxn = cx.addNewStCxn(); - stCxn.setId(rect1.getShapeId()); - // side of the rectangle to attach the connector: left=1, bottom=2,right=3, top=4 - stCxn.setIdx(2); - - CTConnection end = cx.addNewEndCxn(); - end.setId(rect2.getShapeId()); - // side of the rectangle to attach the connector: left=1, bottom=2,right=3, top=4 - end.setIdx(3); - - pptx.close(); - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java deleted file mode 100644 index 5a4e100e6..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - - -import static org.junit.Assert.assertEquals; -import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; - -import java.awt.geom.Ellipse2D; -import java.awt.geom.Path2D; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -import org.junit.Test; - -public class TestXSLFFreeformShape { - - @Test - public void testSetPath() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - XSLFFreeformShape shape1 = slide.createFreeform(); - // comples path consisting of a rectangle and an ellipse inside it - Path2D.Double path1 = new Path2D.Double(new Rectangle2D.Double(150, 150, 300, 300)); - path1.append(new Ellipse2D.Double(200, 200, 100, 50), false); - shape1.setPath(path1); - - Path2D.Double path2 = shape1.getPath(); - - // YK: how to compare the original path1 and the value returned by XSLFFreeformShape.getPath() ? - // one way is to create another XSLFFreeformShape from path2 and compare the resulting xml - assertEquals(path1.getBounds2D(), path2.getBounds2D()); - - XSLFFreeformShape shape2 = slide.createFreeform(); - shape2.setPath(path2); - - assertEquals(getSpPr(shape1).getCustGeom().toString(), getSpPr(shape2).getCustGeom().toString()); - - ppt.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFGroupShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFGroupShape.java deleted file mode 100644 index ff06d5107..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFGroupShape.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.awt.Dimension; -import java.awt.geom.Rectangle2D; - -import org.junit.Test; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFGroupShape { - - @Test - public void testCreateShapes() throws Exception { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - ppt.setPageSize(new Dimension(792, 612)); - - XSLFGroupShape group = slide.createGroup(); - assertEquals(1, slide.getShapes().size()); - - Rectangle2D interior = new Rectangle2D.Double(-10, -10, 20, 20); - group.setInteriorAnchor(interior); - assertEquals(interior, group.getInteriorAnchor()); - - Rectangle2D anchor = new Rectangle2D.Double(0, 0, 792, 612); - group.setAnchor(anchor); - assertEquals(anchor, group.getAnchor()); - - assertTrue(group.getShapes().isEmpty()); - - XSLFTextBox shape1 = group.createTextBox(); - assertEquals(1, group.getShapes().size()); - assertSame(shape1, group.getShapes().get(0)); - assertEquals(3, shape1.getShapeId()); - - XSLFAutoShape shape2 = group.createAutoShape(); - assertEquals(2, group.getShapes().size()); - assertSame(shape1, group.getShapes().get(0)); - assertSame(shape2, group.getShapes().get(1)); - assertEquals(4, shape2.getShapeId()); - - XSLFConnectorShape shape3 = group.createConnector(); - assertEquals(3, group.getShapes().size()); - assertSame(shape3, group.getShapes().get(2)); - assertEquals(5, shape3.getShapeId()); - - XSLFGroupShape shape4 = group.createGroup(); - assertEquals(4, group.getShapes().size()); - assertSame(shape4, group.getShapes().get(3)); - assertEquals(6, shape4.getShapeId()); - - group.removeShape(shape2); - assertEquals(3, group.getShapes().size()); - assertSame(shape1, group.getShapes().get(0)); - assertSame(shape3, group.getShapes().get(1)); - assertSame(shape4, group.getShapes().get(2)); - - group.removeShape(shape3); - assertEquals(2, group.getShapes().size()); - assertSame(shape1, group.getShapes().get(0)); - assertSame(shape4, group.getShapes().get(1)); - - group.removeShape(shape1); - group.removeShape(shape4); - assertTrue(group.getShapes().isEmpty()); - - ppt.close(); - } - - @Test - public void testRemoveShapes() throws Exception { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFGroupShape group1 = slide.createGroup(); - group1.createTextBox(); - XSLFGroupShape group2 = slide.createGroup(); - group2.createTextBox(); - XSLFGroupShape group3 = slide.createGroup(); - slide.removeShape(group1); - slide.removeShape(group2); - slide.removeShape(group3); - - ppt.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java deleted file mode 100644 index 0ff02d085..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java +++ /dev/null @@ -1,177 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; - -public class TestXSLFHyperlink { - - @Test - public void testRead() throws IOException{ - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - - XSLFSlide slide = ppt.getSlides().get(4); - List shapes = slide.getShapes(); - XSLFTable tbl = (XSLFTable)shapes.get(0); - XSLFTableCell cell1 = tbl.getRows().get(1).getCells().get(0); - assertEquals("Web Page", cell1.getText()); - XSLFHyperlink link1 = cell1.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink(); - assertNotNull(link1); - assertEquals("http://poi.apache.org/", link1.getAddress()); - - XSLFTableCell cell2 = tbl.getRows().get(2).getCells().get(0); - assertEquals("Place in this document", cell2.getText()); - XSLFHyperlink link2 = cell2.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink(); - assertNotNull(link2); - assertEquals("/ppt/slides/slide2.xml", link2.getAddress()); - - XSLFTableCell cell3 = tbl.getRows().get(3).getCells().get(0); - assertEquals("Email", cell3.getText()); - XSLFHyperlink link3 = cell3.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink(); - assertNotNull(link3); - assertEquals("mailto:dev@poi.apache.org?subject=Hi%20There", link3.getAddress()); - - ppt.close(); - } - - @Test - public void testCreate() throws IOException, InvalidFormatException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide1 = ppt.createSlide(); - XSLFSlide slide2 = ppt.createSlide(); - - int numRel = slide1.getPackagePart().getRelationships().size(); - assertEquals(1, numRel); - XSLFTextBox sh1 = slide1.createTextBox(); - XSLFTextRun r1 = sh1.addNewTextParagraph().addNewTextRun(); - r1.setText("Web Page"); - XSLFHyperlink link1 = r1.createHyperlink(); - link1.setAddress("http://poi.apache.org/"); - assertEquals("http://poi.apache.org/", link1.getAddress()); - assertEquals(numRel + 1, slide1.getPackagePart().getRelationships().size()); - - String id1 = link1.getXmlObject().getId(); - assertNotNull(id1); - PackageRelationship rel1 = slide1.getPackagePart().getRelationship(id1); - assertNotNull(rel1); - assertEquals(id1, rel1.getId()); - assertEquals(TargetMode.EXTERNAL, rel1.getTargetMode()); - assertEquals(XSLFRelation.HYPERLINK.getRelation(), rel1.getRelationshipType()); - - XSLFTextBox sh2 = slide1.createTextBox(); - XSLFTextRun r2 = sh2.addNewTextParagraph().addNewTextRun(); - r2.setText("Place in this document"); - XSLFHyperlink link2 = r2.createHyperlink(); - link2.linkToSlide(slide2); - assertEquals("/ppt/slides/slide2.xml", link2.getAddress()); - assertEquals(numRel + 2, slide1.getPackagePart().getRelationships().size()); - - String id2 = link2.getXmlObject().getId(); - assertNotNull(id2); - PackageRelationship rel2 = slide1.getPackagePart().getRelationship(id2); - assertNotNull(rel2); - assertEquals(id2, rel2.getId()); - assertEquals(TargetMode.INTERNAL, rel2.getTargetMode()); - assertEquals(XSLFRelation.SLIDE.getRelation(), rel2.getRelationshipType()); - - ppt.close(); - } - - - @Test - public void bug47291() throws IOException { - Rectangle2D anchor = new Rectangle2D.Double(100,100,100,100); - XMLSlideShow ppt1 = new XMLSlideShow(); - XSLFSlide slide1 = ppt1.createSlide(); - XSLFTextBox tb1 = slide1.createTextBox(); - tb1.setAnchor(anchor); - XSLFTextRun r1 = tb1.setText("page1"); - XSLFHyperlink hl1 = r1.createHyperlink(); - hl1.linkToEmail("dev@poi.apache.org"); - XSLFTextBox tb2 = ppt1.createSlide().createTextBox(); - tb2.setAnchor(anchor); - XSLFTextRun r2 = tb2.setText("page2"); - XSLFHyperlink hl2 = r2.createHyperlink(); - hl2.linkToLastSlide(); - XSLFSlide sl3 = ppt1.createSlide(); - XSLFTextBox tb3 = sl3.createTextBox(); - tb3.setAnchor(anchor); - tb3.setText("text1 "); - XSLFTextRun r3 = tb3.appendText("lin\u000bk", false); - tb3.appendText(" text2", false); - XSLFHyperlink hl3 = r3.createHyperlink(); - hl3.linkToSlide(slide1); - XSLFTextBox tb4 = ppt1.createSlide().createTextBox(); - tb4.setAnchor(anchor); - XSLFTextRun r4 = tb4.setText("page4"); - XSLFHyperlink hl4 = r4.createHyperlink(); - hl4.linkToUrl("http://poi.apache.org"); - XSLFTextBox tb5 = ppt1.createSlide().createTextBox(); - tb5.setAnchor(anchor); - tb5.setText("page5"); - XSLFHyperlink hl5 = tb5.createHyperlink(); - hl5.linkToFirstSlide(); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1); - ppt1.close(); - - List slides = ppt2.getSlides(); - tb1 = (XSLFTextBox)slides.get(0).getShapes().get(0); - hl1 = tb1.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink(); - assertNotNull(hl1); - assertEquals("dev@poi.apache.org", hl1.getLabel()); - assertEquals(HyperlinkType.EMAIL, hl1.getTypeEnum()); - - tb2 = (XSLFTextBox)slides.get(1).getShapes().get(0); - hl2 = tb2.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink(); - assertNotNull(hl2); - assertEquals("lastslide", hl2.getXmlObject().getAction().split("=")[1]); - assertEquals(HyperlinkType.DOCUMENT, hl2.getTypeEnum()); - - tb3 = (XSLFTextBox)slides.get(2).getShapes().get(0); - hl3 = tb3.getTextParagraphs().get(0).getTextRuns().get(3).getHyperlink(); - assertNotNull(hl3); - assertEquals("/ppt/slides/slide1.xml", hl3.getAddress()); - assertEquals(HyperlinkType.DOCUMENT, hl3.getTypeEnum()); - - tb4 = (XSLFTextBox)slides.get(3).getShapes().get(0); - hl4 = tb4.getTextParagraphs().get(0).getTextRuns().get(0).getHyperlink(); - assertNotNull(hl4); - assertEquals("http://poi.apache.org", hl4.getLabel()); - assertEquals(HyperlinkType.URL, hl4.getTypeEnum()); - - tb5 = (XSLFTextBox)slides.get(4).getShapes().get(0); - hl5 = tb5.getHyperlink(); - assertNotNull(hl5); - assertEquals("firstslide", hl5.getXmlObject().getAction().split("=")[1]); - assertEquals(HyperlinkType.DOCUMENT, hl5.getTypeEnum()); - - ppt2.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java deleted file mode 100644 index ae18fc70c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import java.io.IOException; - -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; - -public class TestXSLFNotes { - - @Test - public void createNewNote() throws IOException { - - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide1 = ppt.createSlide(); - - assertNull(ppt.getNotesMaster()); - assertNull(slide1.getNotes()); - - XSLFNotes notesSlide = ppt.getNotesSlide(slide1); - assertNotNull(ppt.getNotesMaster()); - assertNotNull(notesSlide); - - String note = null; - for (XSLFTextShape shape : notesSlide.getPlaceholders()) { - if (shape.getTextType() == Placeholder.BODY) { - shape.setText("New Note"); - note = shape.getText(); - break; - } - } - assertNotNull(note); - assertEquals("New Note", note); - - ppt.close(); - } - - @Test - public void addNote() throws IOException { - - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx"); - - XSLFSlide slide = ppt.createSlide(); - XSLFNotes notesSlide = ppt.getNotesSlide(slide); - assertNotNull(notesSlide); - - String note = null; - for (XSLFTextShape shape : notesSlide.getPlaceholders()) { - if (shape.getTextType() == Placeholder.BODY) { - shape.setText("New Note"); - note = shape.getText(); - break; - } - } - assertNotNull(note); - assertEquals("New Note", note); - - ppt.close(); - } - - @Test - public void replaceNotes() throws IOException { - - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx"); - - for (XSLFSlide slide : ppt.getSlides()) { - assertNotNull(slide.getNotes()); - - XSLFNotes notesSlide = ppt.getNotesSlide(slide); - assertNotNull(notesSlide); - - String note = null; - for (XSLFTextShape shape : notesSlide.getPlaceholders()) { - if (shape.getTextType() == Placeholder.BODY) { - shape.setText("New Note"); - note = shape.getText(); - break; - } - } - assertNotNull(note); - assertEquals("New Note", note); - } - - ppt.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java deleted file mode 100644 index 95d407a02..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; - -public class TestXSLFPictureShape { - private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); - - @Test - public void testCreate() throws Exception { - XMLSlideShow ppt1 = new XMLSlideShow(); - assertEquals(0, ppt1.getPictureData().size()); - byte[] data1 = new byte[100]; - for(int i = 0;i < 100;i++) { data1[i] = (byte)i; } - XSLFPictureData pdata1 = ppt1.addPicture(data1, PictureType.JPEG); - assertEquals(0, pdata1.getIndex()); - assertEquals(1, ppt1.getPictureData().size()); - - XSLFSlide slide = ppt1.createSlide(); - XSLFPictureShape shape1 = slide.createPicture(pdata1); - assertNotNull(shape1.getPictureData()); - assertArrayEquals(data1, shape1.getPictureData().getData()); - - byte[] data2 = new byte[200]; - for(int i = 0;i < 200;i++) { data2[i] = (byte)i; } - XSLFPictureData pdata2 = ppt1.addPicture(data2, PictureType.PNG); - XSLFPictureShape shape2 = slide.createPicture(pdata2); - assertNotNull(shape2.getPictureData()); - assertEquals(1, pdata2.getIndex()); - assertEquals(2, ppt1.getPictureData().size()); - assertArrayEquals(data2, shape2.getPictureData().getData()); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1); - ppt1.close(); - List pics = ppt2.getPictureData(); - assertEquals(2, pics.size()); - assertArrayEquals(data1, pics.get(0).getData()); - assertArrayEquals(data2, pics.get(1).getData()); - - List shapes = ppt2.getSlides().get(0).getShapes(); - assertArrayEquals(data1, ((XSLFPictureShape) shapes.get(0)).getPictureData().getData()); - assertArrayEquals(data2, ((XSLFPictureShape) shapes.get(1)).getPictureData().getData()); - ppt2.close(); - } - - @Test - public void testCreateMultiplePictures() throws Exception { - XMLSlideShow ppt1 = new XMLSlideShow(); - XSLFSlide slide1 = ppt1.createSlide(); - XSLFGroupShape group1 = slide1.createGroup(); - - - int pictureIndex = 0; - // first add 20 images to the slide - for (int i = 0; i < 20; i++, pictureIndex++) { - byte[] data = new byte[]{(byte)pictureIndex}; - XSLFPictureData elementData = ppt1.addPicture(data, PictureType.PNG); - assertEquals(pictureIndex, elementData.getIndex()); // added images have indexes 0,1,2....19 - XSLFPictureShape picture = slide1.createPicture(elementData); - // POI saves images as image1.png, image2.png, etc. - String fileName = "image" + (elementData.getIndex()+1) + ".png"; - assertEquals(fileName, picture.getPictureData().getFileName()); - assertArrayEquals(data, picture.getPictureData().getData()); - } - - // and then add next 20 images to a group - for (int i = 0; i < 20; i++, pictureIndex++) { - byte[] data = new byte[]{(byte)pictureIndex}; - XSLFPictureData elementData = ppt1.addPicture(data, PictureType.PNG); - XSLFPictureShape picture = group1.createPicture(elementData); - // POI saves images as image1.png, image2.png, etc. - assertEquals(pictureIndex, elementData.getIndex()); // added images have indexes 0,1,2....19 - String fileName = "image" + (pictureIndex + 1) + ".png"; - assertEquals(fileName, picture.getPictureData().getFileName()); - assertArrayEquals(data, picture.getPictureData().getData()); - } - - // serialize, read back and check that all images are there - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1); - ppt1.close(); - // pictures keyed by file name - Map pics = new HashMap(); - for(XSLFPictureData p : ppt2.getPictureData()){ - pics.put(p.getFileName(), p); - } - assertEquals(40, pics.size()); - for (int i = 0; i < 40; i++) { - byte[] data1 = new byte[]{(byte)i}; - String fileName = "image" + (i + 1) + ".png"; - XSLFPictureData data = pics.get(fileName); - assertNotNull(data); - assertEquals(fileName, data.getFileName()); - assertArrayEquals(data1, data.getData()); - } - ppt2.close(); - } - - @Test - public void testImageCaching() throws Exception { - XMLSlideShow ppt = new XMLSlideShow(); - byte[] img1 = new byte[]{1,2,3}; - byte[] img2 = new byte[]{3,4,5}; - XSLFPictureData pdata1 = ppt.addPicture(img1, PictureType.PNG); - assertEquals(0, pdata1.getIndex()); - assertEquals(0, ppt.addPicture(img1, PictureType.PNG).getIndex()); - - XSLFPictureData idx2 = ppt.addPicture(img2, PictureType.PNG); - assertEquals(1, idx2.getIndex()); - assertEquals(1, ppt.addPicture(img2, PictureType.PNG).getIndex()); - - XSLFSlide slide1 = ppt.createSlide(); - assertNotNull(slide1); - XSLFSlide slide2 = ppt.createSlide(); - assertNotNull(slide2); - - ppt.close(); - } - - @Test - public void testMerge() throws Exception { - XMLSlideShow ppt1 = new XMLSlideShow(); - byte[] data1 = new byte[100]; - XSLFPictureData pdata1 = ppt1.addPicture(data1, PictureType.JPEG); - - XSLFSlide slide1 = ppt1.createSlide(); - XSLFPictureShape shape1 = slide1.createPicture(pdata1); - CTPicture ctPic1 = (CTPicture)shape1.getXmlObject(); - ctPic1.getNvPicPr().getNvPr().addNewCustDataLst().addNewTags().setId("rId99"); - - XMLSlideShow ppt2 = new XMLSlideShow(); - - XSLFSlide slide2 = ppt2.createSlide().importContent(slide1); - XSLFPictureShape shape2 = (XSLFPictureShape)slide2.getShapes().get(0); - - assertArrayEquals(data1, shape2.getPictureData().getData()); - - CTPicture ctPic2 = (CTPicture)shape2.getXmlObject(); - assertFalse(ctPic2.getNvPicPr().getNvPr().isSetCustDataLst()); - - ppt1.close(); - ppt2.close(); - } - - @Test - public void bug58663() throws IOException { - InputStream is = _slTests.openResourceAsStream("shapes.pptx"); - XMLSlideShow ppt = new XMLSlideShow(is); - is.close(); - - XSLFSlide slide = ppt.getSlides().get(0); - XSLFPictureShape ps = (XSLFPictureShape)slide.getShapes().get(3); - slide.removeShape(ps); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ppt.write(bos); - ppt.close(); - - XMLSlideShow ppt2 = new XMLSlideShow(new ByteArrayInputStream(bos.toByteArray())); - assertTrue(ppt2.getPictureData().isEmpty()); - ppt2.close(); - } - - @Test - public void testTiffImageBug59742() throws Exception { - XMLSlideShow slideShow = new XMLSlideShow(); - final InputStream tiffStream = _slTests.openResourceAsStream("testtiff.tif"); - final byte[] pictureData = IOUtils.toByteArray(tiffStream); - IOUtils.closeQuietly(tiffStream); - - XSLFPictureData pic = slideShow.addPicture(pictureData, PictureType.TIFF); - assertEquals("image/tiff", pic.getContentType()); - assertEquals("image1.tiff", pic.getFileName()); - - slideShow.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java deleted file mode 100644 index fa5611789..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.*; - -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; - -import java.io.IOException; -import java.util.List; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFShape { - - @Test - public void testReadTextShapes() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - List slides = ppt.getSlides(); - - XSLFSlide slide1 = slides.get(0); - List shapes1 = slide1.getShapes(); - assertEquals(7, shapes1.size()); - assertEquals("TextBox 3", shapes1.get(0).getShapeName()); - XSLFAutoShape sh0 = (XSLFAutoShape) shapes1.get(0); - assertEquals("Learning PPTX", sh0.getText()); - List paragraphs0 = sh0.getTextParagraphs(); - assertEquals(1, paragraphs0.size()); - XSLFTextParagraph p0 = paragraphs0.get(0); - assertEquals("Learning PPTX", p0.getText()); - assertEquals(1, p0.getTextRuns().size()); - XSLFTextRun r0 = p0.getTextRuns().get(0); - assertEquals("Learning PPTX", r0.getRawText()); - - XSLFSlide slide2 = slides.get(1); - List shapes2 = slide2.getShapes(); - assertTrue(shapes2.get(0) instanceof XSLFAutoShape); - assertEquals("PPTX Title", ((XSLFAutoShape) shapes2.get(0)).getText()); - XSLFAutoShape sh1 = (XSLFAutoShape) shapes2.get(0); - List paragraphs1 = sh1.getTextParagraphs(); - assertEquals(1, paragraphs1.size()); - XSLFTextParagraph p1 = paragraphs1.get(0); - assertEquals("PPTX Title", p1.getText()); - List r2 = paragraphs1.get(0).getTextRuns(); - assertEquals(2, r2.size()); - assertEquals("PPTX ", r2.get(0).getRawText()); - assertEquals("Title", r2.get(1).getRawText()); - // Title is underlined - assertEquals(STTextUnderlineType.SNG, r2.get(1).getXmlObject().getRPr().getU()); - - - assertTrue(shapes2.get(1) instanceof XSLFAutoShape); - assertEquals("Subtitle\nAnd second line", ((XSLFAutoShape) shapes2.get(1)).getText()); - XSLFAutoShape sh2 = (XSLFAutoShape) shapes2.get(1); - List paragraphs2 = sh2.getTextParagraphs(); - assertEquals(2, paragraphs2.size()); - assertEquals("Subtitle", paragraphs2.get(0).getText()); - assertEquals("And second line", paragraphs2.get(1).getText()); - - assertEquals(1, paragraphs2.get(0).getTextRuns().size()); - assertEquals(1, paragraphs2.get(1).getTextRuns().size()); - - assertEquals("Subtitle", paragraphs2.get(0).getTextRuns().get(0).getRawText()); - assertTrue(paragraphs2.get(0).getTextRuns().get(0).getXmlObject().getRPr().getB()); - assertEquals("And second line", paragraphs2.get(1).getTextRuns().get(0).getRawText()); - - ppt.close(); - } - - @Test - public void testCreateShapes() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - assertTrue(slide.getShapes().isEmpty()); - - XSLFTextBox textBox = slide.createTextBox(); - - assertEquals(1, slide.getShapes().size()); - assertSame(textBox, slide.getShapes().get(0)); - - assertEquals("", textBox.getText()); - // FIXME: is this correct? Should it be starting out with 0 or 1 text paragraphs? - assertEquals(1, textBox.getTextParagraphs().size()); - textBox.addNewTextParagraph().addNewTextRun().setText("Apache"); - textBox.addNewTextParagraph().addNewTextRun().setText("POI"); - assertEquals("Apache\nPOI", textBox.getText()); - assertEquals(3, textBox.getTextParagraphs().size()); - - ppt.close(); - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShapeContainer.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShapeContainer.java deleted file mode 100644 index 22bab7c5d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShapeContainer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * test common operations on containers of shapes (sheets and groups of shapes) - * - * @author Yegor Kozlov - */ -public class TestXSLFShapeContainer { - - @SuppressWarnings("unused") - public void verifyContainer(XSLFShapeContainer container) { - container.clear(); - assertEquals(0, container.getShapes().size()); - - XSLFGroupShape shape1 = container.createGroup(); - assertEquals(1, container.getShapes().size()); - - XSLFTextBox shape2 = container.createTextBox(); - assertEquals(2, container.getShapes().size()); - - XSLFAutoShape shape3 = container.createAutoShape(); - assertEquals(3, container.getShapes().size()); - - XSLFConnectorShape shape4 = container.createConnector(); - assertEquals(4, container.getShapes().size()); - - container.clear(); - assertEquals(0, container.getShapes().size()); - } - - @Test - public void testSheet() { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSheet sheet = ppt.createSlide(); - verifyContainer(sheet); - - - XSLFGroupShape group = sheet.createGroup(); - verifyContainer(group); - - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSheet.java deleted file mode 100644 index a307eaab7..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSheet.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.*; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; - -/** - * test common properties for sheets (slides, masters, layouts, etc.) - * - * @author Yegor Kozlov - */ -public class TestXSLFSheet { - - @Test - public void testCreateShapes() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - assertTrue(slide.getShapes().isEmpty()); - - XSLFSimpleShape shape1 = slide.createAutoShape(); - assertEquals(1, slide.getShapes().size()); - assertSame(shape1, slide.getShapes().get(0)); - - XSLFTextBox shape2 = slide.createTextBox(); - assertEquals(2, slide.getShapes().size()); - assertSame(shape1, slide.getShapes().get(0)); - assertSame(shape2, slide.getShapes().get(1)); - - XSLFConnectorShape shape3 = slide.createConnector(); - assertEquals(3, slide.getShapes().size()); - assertSame(shape1, slide.getShapes().get(0)); - assertSame(shape2, slide.getShapes().get(1)); - assertSame(shape3, slide.getShapes().get(2)); - - XSLFGroupShape shape4 = slide.createGroup(); - assertEquals(4, slide.getShapes().size()); - assertSame(shape1, slide.getShapes().get(0)); - assertSame(shape2, slide.getShapes().get(1)); - assertSame(shape3, slide.getShapes().get(2)); - assertSame(shape4, slide.getShapes().get(3)); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt); - slide = ppt2.getSlides().get(0); - List shapes = slide.getShapes(); - assertEquals(4, shapes.size()); - - assertTrue(shapes.get(0) instanceof XSLFAutoShape); - assertTrue(shapes.get(1) instanceof XSLFTextBox); - assertTrue(shapes.get(2) instanceof XSLFConnectorShape); - assertTrue(shapes.get(3) instanceof XSLFGroupShape); - - ppt.close(); - ppt2.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java deleted file mode 100644 index c000da8a4..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java +++ /dev/null @@ -1,386 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.geom.TestPresetGeometries; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; -import org.apache.poi.util.Units; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.apache.xmlbeans.XmlObject; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem; -import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleList; -import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; -import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; -import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; - -public class TestXSLFSimpleShape { - - @Test - public void testLineStyles() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFSimpleShape shape = slide.createAutoShape(); - assertEquals(1, slide.getShapes().size()); - // line properties are not set by default - assertFalse(getSpPr(shape).isSetLn()); - - assertEquals(0., shape.getLineWidth(), 0); - assertEquals(null, shape.getLineColor()); - assertEquals(null, shape.getLineDash()); - assertEquals(null, shape.getLineCap()); - - shape.setLineWidth(0); - shape.setLineColor(null); - shape.setLineDash(null); - shape.setLineCap(null); - - assertTrue(getSpPr(shape).isSetLn()); - assertTrue(getSpPr(shape).getLn().isSetNoFill()); - - // line width - shape.setLineWidth(1.0); - assertEquals(1.0, shape.getLineWidth(), 0); - assertEquals(Units.EMU_PER_POINT, getSpPr(shape).getLn().getW()); - shape.setLineWidth(5.5); - assertEquals(5.5, shape.getLineWidth(), 0); - assertEquals(Units.toEMU(5.5), getSpPr(shape).getLn().getW()); - shape.setLineWidth(0.0); - // setting line width to zero unsets the W attribute - assertFalse(getSpPr(shape).getLn().isSetW()); - - // line cap - shape.setLineCap(LineCap.FLAT); - assertEquals(LineCap.FLAT, shape.getLineCap()); - assertEquals(STLineCap.FLAT, getSpPr(shape).getLn().getCap()); - shape.setLineCap(LineCap.SQUARE); - assertEquals(LineCap.SQUARE, shape.getLineCap()); - assertEquals(STLineCap.SQ, getSpPr(shape).getLn().getCap()); - shape.setLineCap(LineCap.ROUND); - assertEquals(LineCap.ROUND, shape.getLineCap()); - assertEquals(STLineCap.RND, getSpPr(shape).getLn().getCap()); - shape.setLineCap(null); - // setting cap to null unsets the Cap attribute - assertFalse(getSpPr(shape).getLn().isSetCap()); - - // line dash - shape.setLineDash(LineDash.SOLID); - assertEquals(LineDash.SOLID, shape.getLineDash()); - assertEquals(STPresetLineDashVal.SOLID, getSpPr(shape).getLn().getPrstDash().getVal()); - shape.setLineDash(LineDash.DASH_DOT); - assertEquals(LineDash.DASH_DOT, shape.getLineDash()); - assertEquals(STPresetLineDashVal.DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal()); - shape.setLineDash(LineDash.LG_DASH_DOT); - assertEquals(LineDash.LG_DASH_DOT, shape.getLineDash()); - assertEquals(STPresetLineDashVal.LG_DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal()); - shape.setLineDash(null); - // setting dash width to null unsets the Dash element - assertFalse(getSpPr(shape).getLn().isSetPrstDash()); - - // line color - assertFalse(getSpPr(shape).getLn().isSetSolidFill()); - shape.setLineColor(Color.RED); - assertEquals(Color.RED, shape.getLineColor()); - assertTrue(getSpPr(shape).getLn().isSetSolidFill()); - shape.setLineColor(Color.BLUE); - assertEquals(Color.BLUE, shape.getLineColor()); - assertTrue(getSpPr(shape).getLn().isSetSolidFill()); - shape.setLineColor(null); - assertEquals(null, shape.getLineColor()); - // setting dash width to null unsets the SolidFill element - assertFalse(getSpPr(shape).getLn().isSetSolidFill()); - - XSLFSimpleShape ln2 = slide.createAutoShape(); - ln2.setLineDash(LineDash.DOT); - assertEquals(LineDash.DOT, ln2.getLineDash()); - ln2.setLineWidth(0.); - assertEquals(0., ln2.getLineWidth(), 0); - - XSLFSimpleShape ln3 = slide.createAutoShape(); - ln3.setLineWidth(1.); - assertEquals(1., ln3.getLineWidth(), 0); - ln3.setLineDash(null); - assertEquals(null, ln3.getLineDash()); - ln3.setLineCap(null); - assertEquals(null, ln3.getLineDash()); - - ppt.close(); - } - - @Test - public void testFill() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFAutoShape shape = slide.createAutoShape(); - // line properties are not set by default - assertFalse(getSpPr(shape).isSetSolidFill()); - - assertNull(shape.getFillColor()); - shape.setFillColor(null); - assertNull(shape.getFillColor()); - assertFalse(getSpPr(shape).isSetSolidFill()); - - shape.setFillColor(Color.RED); - assertEquals(Color.RED, shape.getFillColor()); - shape.setFillColor(Color.DARK_GRAY); - assertEquals(Color.DARK_GRAY, shape.getFillColor()); - assertTrue(getSpPr(shape).isSetSolidFill()); - - shape.setFillColor(null); - assertNull(shape.getFillColor()); - assertFalse(getSpPr(shape).isSetSolidFill()); - ppt.close(); - } - - @Test - public void testDefaultProperties() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - - XSLFSlide slide6 = ppt.getSlides().get(5); - List shapes = slide6.getShapes(); - for(XSLFShape xs : shapes){ - XSLFSimpleShape s = (XSLFSimpleShape)xs; - // all shapes have a theme color="accent1" - assertEquals("accent1", s.getSpStyle().getFillRef().getSchemeClr().getVal().toString()); - assertEquals(2.0, s.getLineWidth(), 0); - assertEquals(LineCap.FLAT, s.getLineCap()); - assertEquals(new Color(79,129,189), s.getLineColor()); - } - - XSLFSimpleShape s0 = (XSLFSimpleShape) shapes.get(0); - // fill is not set - assertNull(getSpPr(s0).getSolidFill()); - //assertEquals(slide6.getTheme().getColor("accent1").getColor(), s0.getFillColor()); - assertEquals(new Color(79, 129, 189), s0.getFillColor()); - - // lighter 80% - XSLFSimpleShape s1 = (XSLFSimpleShape)shapes.get(1); - CTSchemeColor ref1 = getSpPr(s1).getSolidFill().getSchemeClr(); - assertEquals(1, ref1.sizeOfLumModArray()); - assertEquals(1, ref1.sizeOfLumOffArray()); - assertEquals(20000, ref1.getLumModArray(0).getVal()); - assertEquals(80000, ref1.getLumOffArray(0).getVal()); - assertEquals("accent1", ref1.getVal().toString()); - assertEquals(new Color(220, 230, 242), s1.getFillColor()); - - // lighter 60% - XSLFSimpleShape s2 = (XSLFSimpleShape)shapes.get(2); - CTSchemeColor ref2 = getSpPr(s2).getSolidFill().getSchemeClr(); - assertEquals(1, ref2.sizeOfLumModArray()); - assertEquals(1, ref2.sizeOfLumOffArray()); - assertEquals(40000, ref2.getLumModArray(0).getVal()); - assertEquals(60000, ref2.getLumOffArray(0).getVal()); - assertEquals("accent1", ref2.getVal().toString()); - assertEquals(new Color(185, 205, 229), s2.getFillColor()); - - // lighter 40% - XSLFSimpleShape s3 = (XSLFSimpleShape)shapes.get(3); - CTSchemeColor ref3 = getSpPr(s3).getSolidFill().getSchemeClr(); - assertEquals(1, ref3.sizeOfLumModArray()); - assertEquals(1, ref3.sizeOfLumOffArray()); - assertEquals(60000, ref3.getLumModArray(0).getVal()); - assertEquals(40000, ref3.getLumOffArray(0).getVal()); - assertEquals("accent1", ref3.getVal().toString()); - assertEquals(new Color(149, 179, 215), s3.getFillColor()); - - // darker 25% - XSLFSimpleShape s4 = (XSLFSimpleShape)shapes.get(4); - CTSchemeColor ref4 = getSpPr(s4).getSolidFill().getSchemeClr(); - assertEquals(1, ref4.sizeOfLumModArray()); - assertEquals(0, ref4.sizeOfLumOffArray()); - assertEquals(75000, ref4.getLumModArray(0).getVal()); - assertEquals("accent1", ref3.getVal().toString()); - assertEquals(new Color(55, 96, 146), s4.getFillColor()); - - XSLFSimpleShape s5 = (XSLFSimpleShape)shapes.get(5); - CTSchemeColor ref5 = getSpPr(s5).getSolidFill().getSchemeClr(); - assertEquals(1, ref5.sizeOfLumModArray()); - assertEquals(0, ref5.sizeOfLumOffArray()); - assertEquals(50000, ref5.getLumModArray(0).getVal()); - assertEquals("accent1", ref5.getVal().toString()); - assertEquals(new Color(37, 64, 97), s5.getFillColor()); - - ppt.close(); - } - - @Test - public void testAnchor() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - List slide = ppt.getSlides(); - - XSLFSlide slide2 = slide.get(1); - XSLFSlideLayout layout2 = slide2.getSlideLayout(); - List shapes2 = slide2.getShapes(); - XSLFTextShape sh1 = (XSLFTextShape)shapes2.get(0); - assertEquals(Placeholder.CENTERED_TITLE, sh1.getTextType()); - assertEquals("PPTX Title", sh1.getText()); - assertFalse(getSpPr(sh1).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout - assertEquals(sh1.getAnchor(), layout2.getTextShapeByType(Placeholder.CENTERED_TITLE).getAnchor()); - - XSLFTextShape sh2 = (XSLFTextShape)shapes2.get(1); - assertEquals("Subtitle\nAnd second line", sh2.getText()); - assertEquals(Placeholder.SUBTITLE, sh2.getTextType()); - assertFalse(getSpPr(sh2).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout - assertEquals(sh2.getAnchor(), layout2.getTextShapeByType(Placeholder.SUBTITLE).getAnchor()); - - XSLFSlide slide5 = slide.get(4); - XSLFSlideLayout layout5 = slide5.getSlideLayout(); - XSLFTextShape shTitle = slide5.getTextShapeByType(Placeholder.TITLE); - assertEquals("Hyperlinks", shTitle.getText()); - // xfrm is not set, the query is delegated to the slide layout - assertFalse(getSpPr(shTitle).isSetXfrm()); - // xfrm is not set, the query is delegated to the slide master - assertFalse(getSpPr(layout5.getTextShapeByType(Placeholder.TITLE)).isSetXfrm()); - assertTrue(getSpPr(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE)).isSetXfrm()); - assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor()); - - ppt.close(); - } - - @SuppressWarnings("unused") - @Test - public void testShadowEffects() throws IOException{ - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - CTStyleMatrix styleMatrix = slide.getTheme().getXmlObject().getThemeElements().getFmtScheme(); - CTEffectStyleList lst = styleMatrix.getEffectStyleLst(); - assertNotNull(lst); - for(CTEffectStyleItem ef : lst.getEffectStyleArray()){ - CTOuterShadowEffect obj = ef.getEffectLst().getOuterShdw(); - } - ppt.close(); - } - - @Test - public void testValidGeometry() throws Exception { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFSimpleShape shape = slide.createAutoShape(); - CTShapeProperties spPr = getSpPr(shape); - - CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance(); - prstGeom.setPrst(STShapeType.Enum.forInt(1)); - - assertNotNull(prstGeom.getPrst()); - assertNotNull(prstGeom.getPrst().toString()); - assertNotNull(spPr.getPrstGeom()); - spPr.setPrstGeom(prstGeom); - assertNotNull(spPr.getPrstGeom().getPrst()); - assertNotNull(spPr.getPrstGeom().getPrst().toString()); - - assertNotNull(shape.getGeometry()); - - ppt.close(); - } - - - @Test - public void testInvalidGeometry() throws Exception { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFSimpleShape shape = slide.createAutoShape(); - CTShapeProperties spPr = getSpPr(shape); - - CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance(); - prstGeom.setPrst(STShapeType.Enum.forInt(1)); - - assertNotNull(prstGeom.getPrst()); - assertNotNull(prstGeom.getPrst().toString()); - assertNotNull(spPr.getPrstGeom()); - spPr.setPrstGeom(prstGeom); - assertNotNull(spPr.getPrstGeom().getPrst()); - assertNotNull(spPr.getPrstGeom().getPrst().toString()); - - try { - // cause the geometries to be not found - TestPresetGeometries.clearPreset(); - try { - shape.getGeometry(); - fail("Should fail without the geometry"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage(), e.getMessage().contains("line")); - } - } finally { - // reset to not affect other tests - TestPresetGeometries.resetPreset(); - } - - ppt.close(); - } - - @SuppressWarnings("Duplicates") - @Test - public void testArrayStoreException() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("aascu.org_workarea_downloadasset.aspx_id=5864.pptx"); - Dimension pgsize = ppt.getPageSize(); - - for (Slide s : ppt.getSlides()) { - //System.out.println("Slide: " + s); - - BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = img.createGraphics(); - DrawFactory.getInstance(graphics).fixFonts(graphics); - - // default rendering options - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - // draw stuff - s.draw(graphics); - - graphics.dispose(); - img.flush(); - } - ppt.close(); - } - - static CTShapeProperties getSpPr(XSLFShape shape) { - XmlObject xo = shape.getShapeProperties(); - assertTrue(xo instanceof CTShapeProperties); - return (CTShapeProperties)xo; - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java deleted file mode 100644 index 0af1347ab..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.sl.TestCommonSL.sameColor; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFSlide { - - @Test - public void testReadShapes() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - List slides = ppt.getSlides(); - - XSLFSlide slide1 = slides.get(0); - List shapes1 = slide1.getShapes(); - assertEquals(7, shapes1.size()); - assertEquals("TextBox 3", shapes1.get(0).getShapeName()); - assertTrue(shapes1.get(0) instanceof XSLFTextBox); - XSLFAutoShape sh0 = (XSLFAutoShape)shapes1.get(0); - assertEquals("Learning PPTX", sh0.getText()); - - - assertEquals("Straight Connector 5", shapes1.get(1).getShapeName()); - assertTrue(shapes1.get(1) instanceof XSLFConnectorShape); - - assertEquals("Freeform 6", shapes1.get(2).getShapeName()); - assertTrue(shapes1.get(2) instanceof XSLFFreeformShape); - XSLFAutoShape sh2 = (XSLFAutoShape)shapes1.get(2); - assertEquals("Cloud", sh2.getText()); - - assertEquals("Picture 1", shapes1.get(3).getShapeName()); - assertTrue(shapes1.get(3) instanceof XSLFPictureShape); - - assertEquals("Table 2", shapes1.get(4).getShapeName()); - assertTrue(shapes1.get(4) instanceof XSLFGraphicFrame); - - assertEquals("Straight Arrow Connector 7", shapes1.get(5).getShapeName()); - assertTrue(shapes1.get(5) instanceof XSLFConnectorShape); - - assertEquals("Elbow Connector 9", shapes1.get(6).getShapeName()); - assertTrue(shapes1.get(6) instanceof XSLFConnectorShape); - - // titles on slide2 - XSLFSlide slide2 = slides.get(1); - List shapes2 = slide2.getShapes(); - assertEquals(2, shapes2.size()); - assertTrue(shapes2.get(0) instanceof XSLFAutoShape); - assertEquals("PPTX Title", ((XSLFAutoShape)shapes2.get(0)).getText()); - assertTrue(shapes2.get(1) instanceof XSLFAutoShape); - assertEquals("Subtitle\nAnd second line", ((XSLFAutoShape)shapes2.get(1)).getText()); - - // group shape on slide3 - XSLFSlide slide3 = slides.get(2); - List shapes3 = slide3.getShapes(); - assertEquals(1, shapes3.size()); - assertTrue(shapes3.get(0) instanceof XSLFGroupShape); - List groupShapes = ((XSLFGroupShape)shapes3.get(0)).getShapes(); - assertEquals(3, groupShapes.size()); - assertTrue(groupShapes.get(0) instanceof XSLFAutoShape); - assertEquals("Rectangle 1", groupShapes.get(0).getShapeName()); - - assertTrue(groupShapes.get(1) instanceof XSLFAutoShape); - assertEquals("Oval 2", groupShapes.get(1).getShapeName()); - - assertTrue(groupShapes.get(2) instanceof XSLFAutoShape); - assertEquals("Right Arrow 3", groupShapes.get(2).getShapeName()); - - XSLFSlide slide4 = slides.get(3); - List shapes4 = slide4.getShapes(); - assertEquals(1, shapes4.size()); - assertTrue(shapes4.get(0) instanceof XSLFTable); - XSLFTable tbl = (XSLFTable)shapes4.get(0); - assertEquals(3, tbl.getNumberOfColumns()); - assertEquals(6, tbl.getNumberOfRows()); - - ppt.close(); - } - - @Test - public void testCreateSlide() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - assertEquals(0, ppt.getSlides().size()); - - XSLFSlide slide = ppt.createSlide(); - assertFalse(slide.getFollowMasterGraphics()); - slide.setFollowMasterGraphics(false); - assertFalse(slide.getFollowMasterGraphics()); - slide.setFollowMasterGraphics(true); - assertTrue(slide.getFollowMasterGraphics()); - - ppt.close(); - } - - @Test - public void testImportContent() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - - XMLSlideShow src = XSLFTestDataSamples.openSampleDocument("themes.pptx"); - - // create a blank slide and import content from the 4th slide of themes.pptx - XSLFSlide slide1 = ppt.createSlide().importContent(src.getSlides().get(3)); - List shapes1 = slide1.getShapes(); - assertEquals(2, shapes1.size()); - - XSLFTextShape sh1 = (XSLFTextShape)shapes1.get(0); - assertEquals("Austin Theme", sh1.getText()); - XSLFTextRun r1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals("Century Gothic", r1.getFontFamily()); - assertEquals(40.0, r1.getFontSize(), 0); - assertTrue(r1.isBold()); - assertTrue(r1.isItalic()); - assertTrue(sameColor(new Color(148, 198, 0), r1.getFontColor())); - assertNull(sh1.getFillColor()); - assertNull(sh1.getLineColor()); - - XSLFTextShape sh2 = (XSLFTextShape)shapes1.get(1); - assertEquals( - "Text in a autoshape is white\n" + - "Fill: RGB(148, 198,0)", sh2.getText()); - XSLFTextRun r2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals("Century Gothic", r2.getFontFamily()); - assertEquals(18.0, r2.getFontSize(), 0); - assertFalse(r2.isBold()); - assertFalse(r2.isItalic()); - assertTrue(sameColor(Color.white, r2.getFontColor())); - assertEquals(new Color(148, 198, 0), sh2.getFillColor()); - assertEquals(new Color(148, 198, 0), sh2.getLineColor()); // slightly different from PowerPoint! - - // the 5th slide has a picture and a texture fill - XSLFSlide slide2 = ppt.createSlide().importContent(src.getSlides().get(4)); - List shapes2 = slide2.getShapes(); - assertEquals(2, shapes2.size()); - - XSLFTextShape sh3 = (XSLFTextShape)shapes2.get(0); - assertEquals("This slide overrides master background with a texture fill", sh3.getText()); - XSLFTextRun r3 = sh3.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals("Century Gothic", r3.getFontFamily()); - //assertEquals(32.4.0, r3.getFontSize()); - assertTrue(r3.isBold()); - assertTrue(r3.isItalic()); - assertTrue(sameColor(new Color(148, 198, 0), r3.getFontColor())); - assertNull(sh3.getFillColor()); - assertNull(sh3.getLineColor()); - - XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1); - XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1); - assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData()); - - ppt.close(); - } - - @Test - public void testMergeSlides() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - String[] pptx = {"shapes.pptx", "themes.pptx", "layouts.pptx", "backgrounds.pptx"}; - - for(String arg : pptx){ - XMLSlideShow src = XSLFTestDataSamples.openSampleDocument(arg); - - for(XSLFSlide srcSlide : src.getSlides()){ - ppt.createSlide().importContent(srcSlide); - } - } - assertEquals(30, ppt.getSlides().size()); - - ppt.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java deleted file mode 100644 index 0f0f0bc22..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java +++ /dev/null @@ -1,149 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; - -import java.awt.Dimension; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFSlideShow { - @Test - public void testCreateSlide() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - assertEquals(0, ppt.getSlides().size()); - - XSLFSlide slide1 = ppt.createSlide(); - assertEquals(1, ppt.getSlides().size()); - assertSame(slide1, ppt.getSlides().get(0)); - - List rels = slide1.getRelations(); - assertEquals(1, rels.size()); - assertEquals(slide1.getSlideMaster().getLayout(SlideLayout.BLANK), rels.get(0)); - - XSLFSlide slide2 = ppt.createSlide(); - assertEquals(2, ppt.getSlides().size()); - assertSame(slide2, ppt.getSlides().get(1)); - - ppt.setSlideOrder(slide2, 0); - assertSame(slide2, ppt.getSlides().get(0)); - assertSame(slide1, ppt.getSlides().get(1)); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt); - assertEquals(2, ppt2.getSlides().size()); - rels = ppt2.getSlides().get(0).getRelations(); - - ppt2.close(); - ppt.close(); - } - - @Test - public void testRemoveSlide() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - assertEquals(0, ppt.getSlides().size()); - - XSLFSlide slide1 = ppt.createSlide(); - XSLFSlide slide2 = ppt.createSlide(); - - assertEquals(2, ppt.getSlides().size()); - assertSame(slide1, ppt.getSlides().get(0)); - assertSame(slide2, ppt.getSlides().get(1)); - - XSLFSlide removedSlide = ppt.removeSlide(0); - assertSame(slide1, removedSlide); - - assertEquals(1, ppt.getSlides().size()); - assertSame(slide2, ppt.getSlides().get(0)); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt); - assertEquals(1, ppt2.getSlides().size()); - - ppt2.close(); - ppt.close(); - } - - @Test - public void testDimension() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - Dimension sz = ppt.getPageSize(); - assertEquals(720, sz.width); - assertEquals(540, sz.height); - ppt.setPageSize(new Dimension(792, 612)); - sz = ppt.getPageSize(); - assertEquals(792, sz.width); - assertEquals(612, sz.height); - ppt.close(); - } - - @Test - public void testSlideMasters() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - List masters = ppt.getSlideMasters(); - assertEquals(1, masters.size()); - - XSLFSlide slide = ppt.createSlide(); - assertSame(masters.get(0), slide.getSlideMaster()); - ppt.close(); - } - - @Test - public void testSlideLayout() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - List masters = ppt.getSlideMasters(); - assertEquals(1, masters.size()); - - XSLFSlide slide = ppt.createSlide(); - XSLFSlideLayout layout = slide.getSlideLayout(); - assertNotNull(layout); - - assertSame(masters.get(0), layout.getSlideMaster()); - ppt.close(); - } - - @Test - public void testSlideLayoutNames() throws IOException { - final String names[] = { - "Blank", "Title Only", "Section Header", "Picture with Caption", "Title and Content" - , "Title Slide", "Title and Vertical Text", "Vertical Title and Text", "Comparison" - , "Two Content", "Content with Caption" - }; - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx"); - for (String name : names) { - assertNotNull(ppt.findLayout(name)); - } - final SlideLayout layTypes[] = { - SlideLayout.BLANK, SlideLayout.TITLE_ONLY, SlideLayout.SECTION_HEADER - , SlideLayout.PIC_TX, SlideLayout.TITLE_AND_CONTENT, SlideLayout.TITLE - , SlideLayout.VERT_TX, SlideLayout.VERT_TITLE_AND_TX, SlideLayout.TWO_TX_TWO_OBJ - , SlideLayout.TWO_OBJ, SlideLayout.OBJ_TX - }; - for (SlideLayout sl : layTypes){ - assertNotNull(ppt.getSlideMasters().get(0).getLayout(sl)); - } - ppt.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java deleted file mode 100644 index 9bfc695a8..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.xslf.usermodel; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.GeneralSecurityException; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionMode; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.sl.usermodel.BaseTestSlideShowFactory; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.TempFile; -import org.junit.Test; -import org.junit.Rule; -import org.junit.rules.ExpectedException; - -public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory { - private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); - private static final String filename = "SampleShow.pptx"; - private static final String password = "opensesame"; - private static final String removeExpectedExceptionMsg = - "This functionality this unit test is trying to test is now passing. " + - "The unit test needs to be updated by deleting the expected exception code. Status and close any related bugs."; - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void testFactoryFromFile() throws Exception { - // Remove thrown.* when bug 58779 is resolved - // In the mean time, this function will modify SampleShow.pptx on disk. - thrown.expect(AssertionError.class); - // thrown.expectCause(Matcher); - thrown.expectMessage("SampleShow.pptx sample file was modified as a result of closing the slideshow"); - thrown.reportMissingExceptionWithMessage("Bug 58779: " + removeExpectedExceptionMsg); - - testFactoryFromFile(filename); - } - - @Test - public void testFactoryFromStream() throws Exception { - testFactoryFromStream(filename); - } - - @Test - public void testFactoryFromNative() throws Exception { - // Remove thrown.* when unit test for XSLF SlideShowFactory.create(OPCPackage) is implemented - thrown.expect(UnsupportedOperationException.class); - thrown.expectMessage("Test not implemented"); - thrown.reportMissingExceptionWithMessage(removeExpectedExceptionMsg); - - testFactoryFromNative(filename); - } - - @Test - public void testFactoryFromProtectedFile() throws Exception { - File pFile = createProtected(); - testFactoryFromProtectedFile(pFile.getAbsolutePath(), password); - } - - @Test - public void testFactoryFromProtectedStream() throws Exception { - File pFile = createProtected(); - testFactoryFromProtectedStream(pFile.getAbsolutePath(), password); - } - - @Test - public void testFactoryFromProtectedNative() throws Exception { - File pFile = createProtected(); - testFactoryFromProtectedNative(pFile.getAbsolutePath(), password); - } - - private static File createProtected() throws IOException, GeneralSecurityException { - return createProtected(filename, password); - } - - private static File createProtected(String basefile, String password) - throws IOException, GeneralSecurityException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(); - EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile); - Encryptor enc = info.getEncryptor(); - enc.confirmPassword(password); - InputStream fis = _slTests.openResourceAsStream(basefile); - OutputStream os = enc.getDataStream(fs); - IOUtils.copy(fis, os); - os.close(); - fis.close(); - - File tf = TempFile.createTempFile("test-xslf-slidefactory", ".pptx"); - FileOutputStream fos = new FileOutputStream(tf); - fs.writeFilesystem(fos); - fos.close(); - fs.close(); - - return tf; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java deleted file mode 100644 index 1d77a019d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java +++ /dev/null @@ -1,218 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.TableCell.BorderEdge; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; -import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; - -public class TestXSLFTable { - @Test - public void testRead() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - - XSLFSlide slide = ppt.getSlides().get(3); - List shapes = slide.getShapes(); - assertEquals(1, shapes.size()); - assertTrue(shapes.get(0) instanceof XSLFTable); - XSLFTable tbl = (XSLFTable)shapes.get(0); - assertEquals(3, tbl.getNumberOfColumns()); - assertEquals(6, tbl.getNumberOfRows()); - assertNotNull(tbl.getCTTable()); - - List rows = tbl.getRows(); - assertEquals(6, rows.size()); - - assertEquals(90.0, tbl.getColumnWidth(0), 0); - assertEquals(240.0, tbl.getColumnWidth(1), 0); - assertEquals(150.0, tbl.getColumnWidth(2), 0); - - for(XSLFTableRow row : tbl){ - // all rows have the same height - assertEquals(29.2, row.getHeight(), 0); - } - - XSLFTableRow row0 = rows.get(0); - List cells0 = row0.getCells(); - assertEquals(3, cells0.size()); - assertEquals("header1", cells0.get(0).getText()); - assertEquals("header2", cells0.get(1).getText()); - assertEquals("header3", cells0.get(2).getText()); - - XSLFTableRow row1 = rows.get(1); - List cells1 = row1.getCells(); - assertEquals(3, cells1.size()); - assertEquals("A1", cells1.get(0).getText()); - assertEquals("B1", cells1.get(1).getText()); - assertEquals("C1", cells1.get(2).getText()); - - ppt.close(); - } - - @Test - public void testCreate() throws IOException { - XMLSlideShow ppt1 = new XMLSlideShow(); - XSLFSlide slide = ppt1.createSlide(); - - XSLFTable tbl = slide.createTable(); - assertNotNull(tbl.getCTTable()); - assertNotNull(tbl.getCTTable().getTblGrid()); - assertNotNull(tbl.getCTTable().getTblPr()); - assertTrue(tbl.getXmlObject() instanceof CTGraphicalObjectFrame); - assertEquals("Table 1", tbl.getShapeName()); - assertEquals(2, tbl.getShapeId()); - assertEquals(0, tbl.getRows().size()); - assertEquals(0, tbl.getCTTable().sizeOfTrArray()); - assertEquals(0, tbl.getCTTable().getTblGrid().sizeOfGridColArray()); - - assertEquals(0, tbl.getNumberOfColumns()); - assertEquals(0, tbl.getNumberOfRows()); - - XSLFTableRow row0 = tbl.addRow(); - assertNotNull(row0.getXmlObject()); - assertEquals(1, tbl.getNumberOfRows()); - assertSame(row0, tbl.getRows().get(0)); - assertEquals(20.0, row0.getHeight(), 0); - row0.setHeight(30.0); - assertEquals(30.0, row0.getHeight(), 0); - - assertEquals(0, row0.getCells().size()); - XSLFTableCell cell0 = row0.addCell(); - assertNotNull(cell0.getXmlObject()); - // by default table cell has no borders - CTTableCell tc = (CTTableCell)cell0.getXmlObject(); - assertTrue(tc.getTcPr().getLnB().isSetNoFill()); - assertTrue(tc.getTcPr().getLnT().isSetNoFill()); - assertTrue(tc.getTcPr().getLnL().isSetNoFill()); - assertTrue(tc.getTcPr().getLnR().isSetNoFill()); - - assertSame(cell0, row0.getCells().get(0)); - assertEquals(1, tbl.getNumberOfColumns()); - assertEquals(100.0, tbl.getColumnWidth(0), 0); - cell0.addNewTextParagraph().addNewTextRun().setText("POI"); - assertEquals("POI", cell0.getText()); - - XSLFTableCell cell1 = row0.addCell(); - assertSame(cell1, row0.getCells().get(1)); - assertEquals(2, tbl.getNumberOfColumns()); - assertEquals(100.0, tbl.getColumnWidth(1), 0); - cell1.addNewTextParagraph().addNewTextRun().setText("Apache"); - assertEquals("Apache", cell1.getText()); - - for (BorderEdge edge : BorderEdge.values()) { - assertNull(cell1.getBorderWidth(edge)); - cell1.setBorderWidth(edge, 2.0); - assertEquals(2.0, cell1.getBorderWidth(edge), 0); - assertNull(cell1.getBorderColor(edge)); - cell1.setBorderColor(edge, Color.yellow); - assertEquals(Color.yellow, cell1.getBorderColor(edge)); - } - - assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment()); - cell1.setVerticalAlignment(VerticalAlignment.MIDDLE); - assertEquals(VerticalAlignment.MIDDLE, cell1.getVerticalAlignment()); - cell1.setVerticalAlignment(null); - assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment()); - - XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1); - ppt1.close(); - - slide = ppt2.getSlides().get(0); - tbl = (XSLFTable)slide.getShapes().get(0); - assertEquals(2, tbl.getNumberOfColumns()); - assertEquals(1, tbl.getNumberOfRows()); - assertEquals("POI", tbl.getCell(0, 0).getText()); - assertEquals("Apache", tbl.getCell(0, 1).getText()); - - ppt2.close(); - } - - @Test - public void removeTable() throws IOException { - XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - XSLFSlide sl = ss.getSlides().get(0); - XSLFTable tab = (XSLFTable)sl.getShapes().get(4); - sl.removeShape(tab); - - XMLSlideShow ss2 = XSLFTestDataSamples.writeOutAndReadBack(ss); - ss.close(); - - sl = ss2.getSlides().get(0); - for (XSLFShape s : sl.getShapes()) { - assertFalse(s instanceof XSLFTable); - } - - ss2.close(); - } - - @Test - public void checkTextHeight() throws IOException { - // from bug 59686 - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide sl = ppt.createSlide(); - XSLFTable tab = sl.createTable(); - tab.setAnchor(new Rectangle2D.Double(50,50,300,50)); - XSLFTableRow tr = tab.addRow(); - XSLFTableCell tc0 = tr.addCell(); - tc0.setText("bla bla bla bla"); - tab.setColumnWidth(0, 50); - - // usually text height == 88, but font rendering is plattform dependent - // so we use something more reliable - assertTrue(tc0.getTextHeight() > 50); - assertEquals(0, tc0.getLineWidth(), 0); - - ppt.close(); - } - - @Test - public void checkNullPointerException() { - XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("au.asn.aes.www_conferences_2011_presentations_Fri_20Room4Level4_20930_20Maloney.pptx"); - Dimension pgsize = ss.getPageSize(); - for (Slide s : ss.getSlides()) { - BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = img.createGraphics(); - - // draw stuff - s.draw(graphics); - - graphics.dispose(); - img.flush(); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java deleted file mode 100644 index 8a0892819..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java +++ /dev/null @@ -1,131 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; - -public class TestXSLFTableRow { - - private static XMLSlideShow ppt; - private static XSLFTable tbl; - private static XSLFTableRow row; - - /** Copied from {@link TestXSLFTable#testRead()} */ - @Before - public void setUp() throws IOException { - ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); - - XSLFSlide slide = ppt.getSlides().get(3); - List shapes = slide.getShapes(); - tbl = (XSLFTable)shapes.get(0); - List rows = tbl.getRows(); - row = rows.get(0); - } - - @After - public void tearDown() throws IOException { - ppt.getPackage().revert(); - ppt.close(); - } - - - @Test - public void constructor() { - XSLFTableRow row2 = new XSLFTableRow(row.getXmlObject(), tbl); - assertSame(row.getXmlObject(), row2.getXmlObject()); - assertEquals(row.getHeight(), row2.getHeight(), 1e-16); - } - - @Test - public void testHeight() { - final double h = 10.0; - row.setHeight(h); - assertEquals(h, row.getHeight(), 1e-16); - } - - /** copied from {@link TestXSLFTable#testCreate()} */ - @Test - public void getCells() { - List cells = row.getCells(); - assertNotNull(cells); - assertEquals(3, cells.size()); - } - - @Test - public void testIterator() { - int i = 0; - for (XSLFTableCell cell : row) { - i++; - assertEquals("header"+i, cell.getText()); - } - assertEquals(3, i); - } - - /** copied from {@link TestXSLFTable#testCreate()} */ - @Test - public void addCell() { - XSLFTableCell cell = row.addCell(); - assertNotNull(cell); - - assertNotNull(cell.getXmlObject()); - // by default table cell has no borders - CTTableCell tc = (CTTableCell)cell.getXmlObject(); - assertTrue(tc.getTcPr().getLnB().isSetNoFill()); - assertTrue(tc.getTcPr().getLnT().isSetNoFill()); - assertTrue(tc.getTcPr().getLnL().isSetNoFill()); - assertTrue(tc.getTcPr().getLnR().isSetNoFill()); - } - - @Test - public void mergeCells() { - try { - row.mergeCells(0, 0); - fail("expected IllegalArgumentException when merging fewer than 2 columns"); - } catch (final IllegalArgumentException e) { - // expected - } - - row.mergeCells(0, 1); - List cells = row.getCells(); - //the top-left cell of a merged region is not regarded as merged - assertFalse("top-left cell of merged region", cells.get(0).isMerged()); - assertTrue("inside merged region", cells.get(1).isMerged()); - assertFalse("outside merged region", cells.get(2).isMerged()); - } - - @Test - public void getXmlObject() { - CTTableRow ctrow = row.getXmlObject(); - assertNotNull(ctrow); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableStyles.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableStyles.java deleted file mode 100644 index 12369937e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableStyles.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; - -import org.junit.Test; - -public class TestXSLFTableStyles { - - @Test - public void testRead() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFTableStyles tblStyles = ppt.getTableStyles(); - assertNotNull(tblStyles); - - assertEquals(0, tblStyles.getStyles().size()); - - ppt.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java deleted file mode 100644 index 15352b448..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.io.IOException; - -import org.apache.poi.sl.usermodel.Placeholder; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFTextBox { - - @Test - public void testPlaceholder() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - XSLFTextBox shape = slide.createTextBox(); - assertNull(shape.getTextType()); - shape.setPlaceholder(Placeholder.TITLE); - assertEquals(Placeholder.TITLE, shape.getTextType()); - shape.setPlaceholder(null); - assertNull(shape.getTextType()); - shape.setText("Apache POI"); - - ppt.close(); - } - - /** - * text box inherits default text proeprties from presentation.xml - */ - @Test - public void testDefaultTextStyle() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - - // default character properties for paragraphs with level=1 - CTTextCharacterProperties pPr = ppt.getCTPresentation().getDefaultTextStyle().getLvl1PPr().getDefRPr(); - - XSLFTextBox shape = slide.createTextBox(); - shape.setText("Apache POI"); - assertEquals(1, shape.getTextParagraphs().size()); - assertEquals(1, shape.getTextParagraphs().get(0).getTextRuns().size()); - - XSLFTextRun r = shape.getTextParagraphs().get(0).getTextRuns().get(0); - - assertEquals(1800, pPr.getSz()); - assertEquals(18.0, r.getFontSize(), 0); - assertEquals("Calibri", r.getFontFamily()); - - pPr.setSz(900); - pPr.getLatin().setTypeface("Arial"); - assertEquals(9.0, r.getFontSize(), 0); - assertEquals("Arial", r.getFontFamily()); - - // unset font size in presentation.xml. The value should be taken from master slide - // from /p:sldMaster/p:txStyles/p:otherStyle/a:lvl1pPr/a:defRPr - ppt.getCTPresentation().getDefaultTextStyle().getLvl1PPr().getDefRPr().unsetSz(); - pPr = slide.getSlideMaster().getXmlObject().getTxStyles().getOtherStyle().getLvl1PPr().getDefRPr(); - assertEquals(1800, pPr.getSz()); - assertEquals(18.0, r.getFontSize(), 0); - pPr.setSz(2000); - assertEquals(20.0, r.getFontSize(), 0); - - pPr.unsetSz(); // Should never be - assertNull(r.getFontSize()); - - ppt.close(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java deleted file mode 100644 index 9d710cd70..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java +++ /dev/null @@ -1,394 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.sl.TestCommonSL.sameColor; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.sl.draw.DrawTextFragment; -import org.apache.poi.sl.draw.DrawTextParagraph; -import org.apache.poi.sl.usermodel.AutoNumberingScheme; -import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Assume; -import org.junit.Test; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFTextParagraph { - // private static POILogger _logger = POILogFactory.getLogger(XSLFTextParagraph.class); - - static class DrawTextParagraphProxy extends DrawTextParagraph { - DrawTextParagraphProxy(XSLFTextParagraph p) { - super(p); - } - - @Override - public void breakText(Graphics2D graphics) { - super.breakText(graphics); - } - - @Override - public double getWrappingWidth(boolean firstLine, Graphics2D graphics) { - return super.getWrappingWidth(firstLine, graphics); - } - - public List getLines() { - return lines; - } - } - - @Test - public void testWrappingWidth() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - XSLFTextShape sh = slide.createAutoShape(); - sh.setLineColor(Color.black); - - XSLFTextParagraph p = sh.addNewTextParagraph(); - p.addNewTextRun().setText( - "Paragraph formatting allows for more granular control " + - "of text within a shape. Properties here apply to all text " + - "residing within the corresponding paragraph."); - - Rectangle2D anchor = new Rectangle2D.Double(50, 50, 300, 200); - sh.setAnchor(anchor); - - DrawTextParagraphProxy dtp = new DrawTextParagraphProxy(p); - - Double leftInset = sh.getLeftInset(); - Double rightInset = sh.getRightInset(); - assertEquals(7.2, leftInset, 0); - assertEquals(7.2, rightInset, 0); - - Double leftMargin = p.getLeftMargin(); - assertEquals(0.0, leftMargin, 0); - - Double indent = p.getIndent(); - assertNull(indent); // default - - double expectedWidth; - - // Case 1: bullet=false, leftMargin=0, indent=0. - expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin; - assertEquals(285.6, expectedWidth, 0); // 300 - 7.2 - 7.2 - 0 - assertEquals(expectedWidth, dtp.getWrappingWidth(true, null), 0); - assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0); - - p.setLeftMargin(36d); // 0.5" - leftMargin = p.getLeftMargin(); - assertEquals(36.0, leftMargin, 0); - expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin; - assertEquals(249.6, expectedWidth, 1E-5); // 300 - 7.2 - 7.2 - 36 - assertEquals(expectedWidth, dtp.getWrappingWidth(true, null), 0); - assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0); - - // increase insets, the wrapping width should get smaller - sh.setLeftInset(10); - sh.setRightInset(10); - leftInset = sh.getLeftInset(); - rightInset = sh.getRightInset(); - assertEquals(10.0, leftInset, 0); - assertEquals(10.0, rightInset, 0); - expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin; - assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36 - assertEquals(expectedWidth, dtp.getWrappingWidth(true, null), 0); - assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0); - - // set a positive indent of a 0.5 inch. This means "First Line" indentation: - // |<--- indent -->|Here goes first line of the text - // Here go other lines (second and subsequent) - - p.setIndent(36.0); // 0.5" - indent = p.getIndent(); - assertEquals(36.0, indent, 0); - expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin - indent; - assertEquals(208.0, expectedWidth, 0); // 300 - 10 - 10 - 36 - 6.4 - assertEquals(expectedWidth, dtp.getWrappingWidth(true, null), 0); // first line is indented - // other lines are not indented - expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin; - assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36 - assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0); - - // set a negative indent of a 1 inch. This means "Hanging" indentation: - // Here goes first line of the text - // |<--- indent -->|Here go other lines (second and subsequent) - p.setIndent(-72.0); // 1" - indent = p.getIndent(); - assertEquals(-72.0, indent, 0); - expectedWidth = anchor.getWidth() - leftInset - rightInset; - assertEquals(280.0, expectedWidth, 0); // 300 - 10 - 10 - assertEquals(expectedWidth, dtp.getWrappingWidth(true, null), 0); // first line is NOT indented - // other lines are indented by leftMargin (the value of indent is not used) - expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin; - assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36 - assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0); - - ppt.close(); - } - - /** - * test breaking test into lines. - * This test requires that the Arial font is available and will run only on windows - */ - @Test - public void testBreakLines() throws IOException { - String os = System.getProperty("os.name"); - Assume.assumeTrue("Skipping testBreakLines(), it is executed only on Windows machines", (os != null && os.contains("Windows"))); - - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - XSLFTextShape sh = slide.createAutoShape(); - - XSLFTextParagraph p = sh.addNewTextParagraph(); - XSLFTextRun r = p.addNewTextRun(); - r.setFontFamily("Arial"); // this should always be available - r.setFontSize(12d); - r.setText( - "Paragraph formatting allows for more granular control " + - "of text within a shape. Properties here apply to all text " + - "residing within the corresponding paragraph."); - - sh.setAnchor(new Rectangle2D.Double(50, 50, 300, 200)); - DrawTextParagraphProxy dtp = new DrawTextParagraphProxy(p); - - BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); - Graphics2D graphics = img.createGraphics(); - - List lines; - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(4, lines.size()); - - // decrease the shape width from 300 pt to 100 pt - sh.setAnchor(new Rectangle2D.Double(50, 50, 100, 200)); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(12, lines.size()); - - // decrease the shape width from 300 pt to 100 pt - sh.setAnchor(new Rectangle2D.Double(50, 50, 600, 200)); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(2, lines.size()); - - // set left and right margins to 200pt. This leaves 200pt for wrapping text - sh.setLeftInset(200); - sh.setRightInset(200); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(5, lines.size()); - - r.setText("Apache POI"); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(1, lines.size()); - assertEquals("Apache POI", lines.get(0).getString()); - - r.setText("Apache\nPOI"); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(2, lines.size()); - assertEquals("Apache", lines.get(0).getString()); - assertEquals("POI", lines.get(1).getString()); - - // trailing newlines are ignored - r.setText("Apache\nPOI\n"); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(2, lines.size()); - assertEquals("Apache", lines.get(0).getString()); - assertEquals("POI", lines.get(1).getString()); - - XSLFAutoShape sh2 = slide.createAutoShape(); - sh2.setAnchor(new Rectangle2D.Double(50, 50, 300, 200)); - XSLFTextParagraph p2 = sh2.addNewTextParagraph(); - XSLFTextRun r2 = p2.addNewTextRun(); - r2.setFontFamily("serif"); // this should always be available - r2.setFontSize(30d); - r2.setText("Apache\n"); - XSLFTextRun r3 = p2.addNewTextRun(); - r3.setFontFamily("serif"); // this should always be available - r3.setFontSize(10d); - r3.setText("POI"); - dtp = new DrawTextParagraphProxy(p2); - dtp.breakText(graphics); - lines = dtp.getLines(); - assertEquals(2, lines.size()); - assertEquals("Apache", lines.get(0).getString()); - assertEquals("POI", lines.get(1).getString()); - // the first line is at least two times higher than the second - assertTrue(lines.get(0).getHeight() > lines.get(1).getHeight()*2); - - ppt.close(); - } - - @Test - public void testThemeInheritance() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx"); - List shapes = ppt.getSlides().get(0).getShapes(); - XSLFTextShape sh1 = (XSLFTextShape)shapes.get(0); - assertEquals("Apache", sh1.getText()); - assertEquals(TextAlign.CENTER, sh1.getTextParagraphs().get(0).getTextAlign()); - XSLFTextShape sh2 = (XSLFTextShape)shapes.get(1); - assertEquals("Software", sh2.getText()); - assertEquals(TextAlign.CENTER, sh2.getTextParagraphs().get(0).getTextAlign()); - XSLFTextShape sh3 = (XSLFTextShape)shapes.get(2); - assertEquals("Foundation", sh3.getText()); - assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign()); - ppt.close(); - } - - @Test - public void testParagraphProperties() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - XSLFTextShape sh = slide.createAutoShape(); - - XSLFTextParagraph p = sh.addNewTextParagraph(); - assertFalse(p.isBullet()); - p.setBullet(true); - assertTrue(p.isBullet()); - - assertEquals("\u2022", p.getBulletCharacter()); - p.setBulletCharacter("*"); - assertEquals("*", p.getBulletCharacter()); - - assertEquals("Arial", p.getBulletFont()); - p.setBulletFont("Calibri"); - assertEquals("Calibri", p.getBulletFont()); - - assertEquals(null, p.getBulletFontColor()); - p.setBulletFontColor(Color.red); - assertTrue(sameColor(Color.red, p.getBulletFontColor())); - - assertNull(p.getBulletFontSize()); - p.setBulletFontSize(200.); - assertEquals(200., p.getBulletFontSize(), 0); - p.setBulletFontSize(-20.); - assertEquals(-20.0, p.getBulletFontSize(), 0); - - assertEquals(72.0, p.getDefaultTabSize(), 0); - - assertNull(p.getIndent()); - p.setIndent(72.0); - assertEquals(72.0, p.getIndent(), 0); - p.setIndent(-1d); // the value of -1.0 resets to the defaults (not any more ...) - assertEquals(-1d, p.getIndent(), 0); - p.setIndent(null); - assertNull(p.getIndent()); - - assertEquals(0.0, p.getLeftMargin(), 0); - p.setLeftMargin(72.0); - assertEquals(72.0, p.getLeftMargin(), 0); - p.setLeftMargin(-1.0); // the value of -1.0 resets to the defaults - assertEquals(-1.0, p.getLeftMargin(), 0); - p.setLeftMargin(null); - assertEquals(0d, p.getLeftMargin(), 0); // default will be taken from master - - assertEquals(0, p.getIndentLevel()); - p.setIndentLevel(1); - assertEquals(1, p.getIndentLevel()); - p.setIndentLevel(2); - assertEquals(2, p.getIndentLevel()); - - assertNull(p.getLineSpacing()); - p.setLineSpacing(200.); - assertEquals(200.0, p.getLineSpacing(), 0); - p.setLineSpacing(-15.); - assertEquals(-15.0, p.getLineSpacing(), 0); - - assertNull(p.getSpaceAfter()); - p.setSpaceAfter(200.); - assertEquals(200.0, p.getSpaceAfter(), 0); - p.setSpaceAfter(-15.); - assertEquals(-15.0, p.getSpaceAfter(), 0); - p.setSpaceAfter(null); - assertNull(p.getSpaceAfter()); - p.setSpaceAfter(null); - assertNull(p.getSpaceAfter()); - - assertNull(p.getSpaceBefore()); - p.setSpaceBefore(200.); - assertEquals(200.0, p.getSpaceBefore(), 0); - p.setSpaceBefore(-15.); - assertEquals(-15.0, p.getSpaceBefore(), 0); - p.setSpaceBefore(null); - assertNull(p.getSpaceBefore()); - p.setSpaceBefore(null); - assertNull(p.getSpaceBefore()); - - assertEquals(TextAlign.LEFT, p.getTextAlign()); - p.setTextAlign(TextAlign.RIGHT); - assertEquals(TextAlign.RIGHT, p.getTextAlign()); - - p.setBullet(false); - assertFalse(p.isBullet()); - - p.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenBoth, 1); - - double tabStop = p.getTabStop(0); - assertEquals(0.0, tabStop, 0); - - p.addTabStop(100.); - assertEquals(100., p.getTabStop(0), 0); - - assertEquals(72.0, p.getDefaultTabSize(), 0); - - ppt.close(); - } - - @Test(expected = IllegalStateException.class) - public void testLineBreak() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - try { - XSLFSlide slide = ppt.createSlide(); - XSLFTextShape sh = slide.createAutoShape(); - - XSLFTextParagraph p = sh.addNewTextParagraph(); - XSLFTextRun r1 = p.addNewTextRun(); - r1.setText("Hello,"); - XSLFTextRun r2 = p.addLineBreak(); - assertEquals("\n", r2.getRawText()); - r2.setFontSize(10.0); - assertEquals(10.0, r2.getFontSize(), 0); - XSLFTextRun r3 = p.addNewTextRun(); - r3.setText("World!"); - r3.setFontSize(20.0); - XSLFTextRun r4 = p.addLineBreak(); - assertEquals(20.0, r4.getFontSize(), 0); - - assertEquals("Hello,\nWorld!\n",sh.getText()); - - // "You cannot change text of a line break, it is always '\\n'" - r2.setText("aaa"); - } finally { - ppt.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java deleted file mode 100644 index 5b2fa7b2a..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.sl.TestCommonSL.sameColor; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.io.IOException; - -import org.junit.Test; - -/** - * @author Yegor Kozlov - */ -public class TestXSLFTextRun { - - @Test - public void testRunProperties() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - XSLFSlide slide = ppt.createSlide(); - XSLFTextShape sh = slide.createAutoShape(); - - XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun(); - assertEquals("en-US", r.getRPr(true).getLang()); - - assertEquals(0., r.getCharacterSpacing(), 0); - r.setCharacterSpacing(3); - assertEquals(3., r.getCharacterSpacing(), 0); - r.setCharacterSpacing(-3); - assertEquals(-3., r.getCharacterSpacing(), 0); - r.setCharacterSpacing(0); - assertEquals(0., r.getCharacterSpacing(), 0); - assertFalse(r.getRPr(true).isSetSpc()); - - assertTrue(sameColor(Color.black, r.getFontColor())); - r.setFontColor(Color.red); - assertTrue(sameColor(Color.red, r.getFontColor())); - - assertEquals("Calibri", r.getFontFamily()); - r.setFontFamily("Arial"); - assertEquals("Arial", r.getFontFamily()); - - assertEquals(18.0, r.getFontSize(), 0); - r.setFontSize(13.0); - assertEquals(13.0, r.getFontSize(), 0); - - assertEquals(false, r.isSuperscript()); - r.setSuperscript(true); - assertEquals(true, r.isSuperscript()); - r.setSuperscript(false); - assertEquals(false, r.isSuperscript()); - - assertEquals(false, r.isSubscript()); - r.setSubscript(true); - assertEquals(true, r.isSubscript()); - r.setSubscript(false); - assertEquals(false, r.isSubscript()); - - ppt.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java deleted file mode 100644 index 8ae19f265..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ /dev/null @@ -1,931 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.sl.TestCommonSL.sameColor; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; - -import java.awt.Color; -import java.io.File; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.hslf.usermodel.HSLFTextShape; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; - -public class TestXSLFTextShape { - - @Test - public void testLayouts() throws IOException { - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx"); - - List slide = ppt.getSlides(); - - verifySlide1(slide.get(0)); - verifySlide2(slide.get(1)); - verifySlide3(slide.get(2)); - verifySlide4(slide.get(3)); - verifySlide7(slide.get(6)); - verifySlide8(slide.get(7)); - verifySlide10(slide.get(9)); - - ppt.close(); - } - - void verifySlide1(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - assertEquals("Title Slide",layout.getName()); - - XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); - CTPlaceholder ph1 = shape1.getCTPlaceholder(); - assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape1).getXfrm()); - - XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - assertNotNull(getSpPr(masterShape1).getXfrm()); - assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); - - CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && - !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && - !bodyPr1.isSetAnchor() - ); - assertEquals(7.2, shape1.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape1.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); - - // now check text properties - assertEquals("Centered Title", shape1.getText()); - XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(44.0, r1.getFontSize(), 0); - assertTrue(sameColor(Color.black, r1.getFontColor())); - - XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); - CTPlaceholder ph2 = shape2.getCTPlaceholder(); - assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape2).getXfrm()); - - XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(getSpPr(masterShape2).getXfrm()); - assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); - - CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && - !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && - !bodyPr2.isSetAnchor() - ); - assertEquals(7.2, shape2.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape2.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); - - assertEquals("subtitle", shape2.getText()); - XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals("Calibri", r2.getFontFamily()); - assertEquals(32.0, r2.getFontSize(), 0); - // TODO fix calculation of tint - //assertEquals(new Color(137, 137, 137), r2.getFontColor()); - } - - void verifySlide2(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - assertEquals("Title and Content",layout.getName()); - - XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); - CTPlaceholder ph1 = shape1.getCTPlaceholder(); - assertEquals(STPlaceholderType.TITLE, ph1.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape1).getXfrm()); - - XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - // layout does not have anchor info either, it is in the slide master - assertNull(getSpPr(masterShape1).getXfrm()); - masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1); - assertNotNull(getSpPr(masterShape1).getXfrm()); - assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); - - CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && - !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && - !bodyPr1.isSetAnchor() - ); - assertEquals(7.2, shape1.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape1.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); - - // now check text properties - assertEquals("Title", shape1.getText()); - XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(44.0, r1.getFontSize(), 0); - assertTrue(sameColor(Color.black, r1.getFontColor())); - - XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); - CTPlaceholder ph2 = shape2.getCTPlaceholder(); - assertFalse(ph2.isSetType()); // - assertTrue(ph2.isSetIdx()); - assertEquals(1, ph2.getIdx()); - // anchor is not defined in the shape - assertNull(getSpPr(shape2).getXfrm()); - - XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - // anchor of the body text is missing in the slide layout, llokup in the slide master - assertNull(getSpPr(masterShape2).getXfrm()); - masterShape2 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph2); - assertNotNull(getSpPr(masterShape2).getXfrm()); - assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); - - CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && - !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && - !bodyPr2.isSetAnchor() - ); - assertEquals(7.2, shape2.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape2.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); - - XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(0, pr1.getParentParagraph().getIndentLevel()); - assertEquals("Content", pr1.getRawText()); - assertEquals("Calibri", pr1.getFontFamily()); - assertEquals(32.0, pr1.getFontSize(), 0); - assertEquals(27.0, pr1.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr1.getParentParagraph().getBulletFont()); - - XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0); - assertEquals(1, pr2.getParentParagraph().getIndentLevel()); - assertEquals("Level 2", pr2.getRawText()); - assertEquals("Calibri", pr2.getFontFamily()); - assertEquals(28.0, pr2.getFontSize(), 0); - assertEquals(58.5, pr2.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr2.getParentParagraph().getBulletFont()); - - XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0); - assertEquals(2, pr3.getParentParagraph().getIndentLevel()); - assertEquals("Level 3", pr3.getRawText()); - assertEquals("Calibri", pr3.getFontFamily()); - assertEquals(24.0, pr3.getFontSize(), 0); - assertEquals(90.0, pr3.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr3.getParentParagraph().getBulletFont()); - - XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0); - assertEquals(3, pr4.getParentParagraph().getIndentLevel()); - assertEquals("Level 4", pr4.getRawText()); - assertEquals("Calibri", pr4.getFontFamily()); - assertEquals(20.0, pr4.getFontSize(), 0); - assertEquals(126.0, pr4.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr4.getParentParagraph().getBulletFont()); - - XSLFTextRun pr5 = shape2.getTextParagraphs().get(4).getTextRuns().get(0); - assertEquals(4, pr5.getParentParagraph().getIndentLevel()); - assertEquals("Level 5", pr5.getRawText()); - assertEquals("Calibri", pr5.getFontFamily()); - assertEquals(20.0, pr5.getFontSize(), 0); - assertEquals(162.0, pr5.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u00bb", pr5.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr5.getParentParagraph().getBulletFont()); - - } - - void verifySlide3(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - assertEquals("Section Header",layout.getName()); - - XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); - CTPlaceholder ph1 = shape1.getCTPlaceholder(); - assertEquals(STPlaceholderType.TITLE, ph1.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape1).getXfrm()); - - XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - assertNotNull(getSpPr(masterShape1).getXfrm()); - assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); - - CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && - !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && - !bodyPr1.isSetAnchor() - ); - assertEquals(7.2, shape1.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape1.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.TOP, shape1.getVerticalAlignment()); - - // now check text properties - assertEquals("Section Title", shape1.getText()); - XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign()); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(40.0, r1.getFontSize(), 0); - assertTrue(sameColor(Color.black, r1.getFontColor())); - assertTrue(r1.isBold()); - assertFalse(r1.isItalic()); - assertFalse(r1.isUnderlined()); - - XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); - CTPlaceholder ph2 = shape2.getCTPlaceholder(); - assertEquals(STPlaceholderType.BODY, ph2.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape2).getXfrm()); - - XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(getSpPr(masterShape2).getXfrm()); - assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); - - CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && - !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && - !bodyPr2.isSetAnchor() - ); - assertEquals(7.2, shape2.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape2.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.BOTTOM, shape2.getVerticalAlignment()); - - assertEquals("Section Header", shape2.getText()); - XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(TextAlign.LEFT, r2.getParentParagraph().getTextAlign()); - assertEquals("Calibri", r2.getFontFamily()); - assertEquals(20.0, r2.getFontSize(), 0); - // TODO fix calculation of tint - //assertEquals(new Color(137, 137, 137), r2.getFontColor()); - } - - void verifySlide4(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - assertEquals("Two Content",layout.getName()); - - XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); - CTPlaceholder ph1 = shape1.getCTPlaceholder(); - assertEquals(STPlaceholderType.TITLE, ph1.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape1).getXfrm()); - - XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - // layout does not have anchor info either, it is in the slide master - assertNull(getSpPr(masterShape1).getXfrm()); - masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1); - assertNotNull(getSpPr(masterShape1).getXfrm()); - assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); - - CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && - !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && - !bodyPr1.isSetAnchor() - ); - assertEquals(7.2, shape1.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape1.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); - - // now check text properties - assertEquals("Title", shape1.getText()); - XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign()); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(44.0, r1.getFontSize(), 0); - assertTrue(sameColor(Color.black, r1.getFontColor())); - - XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); - CTPlaceholder ph2 = shape2.getCTPlaceholder(); - assertFalse(ph2.isSetType()); - assertTrue(ph2.isSetIdx()); - assertEquals(1, ph2.getIdx()); // - // anchor is not defined in the shape - assertNull(getSpPr(shape2).getXfrm()); - - XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(getSpPr(masterShape2).getXfrm()); - assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); - - CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && - !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && - !bodyPr2.isSetAnchor() - ); - assertEquals(7.2, shape2.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape2.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); - - XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(0, pr1.getParentParagraph().getIndentLevel()); - assertEquals("Left", pr1.getRawText()); - assertEquals("Calibri", pr1.getFontFamily()); - assertEquals(28.0, pr1.getFontSize(), 0); - assertEquals(27.0, pr1.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr1.getParentParagraph().getBulletFont()); - - XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0); - assertEquals(1, pr2.getParentParagraph().getIndentLevel()); - assertEquals("Level 2", pr2.getParentParagraph().getText()); - assertEquals("Calibri", pr2.getFontFamily()); - assertEquals(24.0, pr2.getFontSize(), 0); - assertEquals(58.5, pr2.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr2.getParentParagraph().getBulletFont()); - - XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0); - assertEquals(2, pr3.getParentParagraph().getIndentLevel()); - assertEquals("Level 3", pr3.getParentParagraph().getText()); - assertEquals("Calibri", pr3.getFontFamily()); - assertEquals(20.0, pr3.getFontSize(), 0); - assertEquals(90.0, pr3.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr3.getParentParagraph().getBulletFont()); - - XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0); - assertEquals(3, pr4.getParentParagraph().getIndentLevel()); - assertEquals("Level 4", pr4.getParentParagraph().getText()); - assertEquals("Calibri", pr4.getFontFamily()); - assertEquals(18.0, pr4.getFontSize(), 0); - assertEquals(126.0, pr4.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr4.getParentParagraph().getBulletFont()); - - XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2); - XSLFTextRun pr5 = shape3.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(0, pr5.getParentParagraph().getIndentLevel()); - assertEquals("Right", pr5.getRawText()); - assertEquals("Calibri", pr5.getFontFamily()); - assertTrue(sameColor(Color.black, pr5.getFontColor())); - } - - @SuppressWarnings("unused") - void verifySlide5(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - // TODO - } - - void verifySlide7(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - assertEquals("Blank",layout.getName()); - - XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); - CTPlaceholder ph1 = shape1.getCTPlaceholder(); - assertEquals(STPlaceholderType.TITLE, ph1.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape1).getXfrm()); - - CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && - !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && - !bodyPr1.isSetAnchor() - ); - assertEquals(7.2, shape1.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape1.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); - - // now check text properties - assertEquals("Blank with Default Title", shape1.getText()); - XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign()); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(44.0, r1.getFontSize(), 0); - assertTrue(sameColor(Color.black, r1.getFontColor())); - assertFalse(r1.isBold()); - - XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); - - CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && - !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && - !bodyPr2.isSetAnchor() - ); - assertEquals(7.2, shape2.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape2.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); - - XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(0, pr1.getParentParagraph().getIndentLevel()); - assertEquals("Default Text", pr1.getRawText()); - assertEquals("Calibri", pr1.getFontFamily()); - assertEquals(18.0, pr1.getFontSize(), 0); - - XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2); - assertEquals("Default", shape3.getTextParagraphs().get(0).getText()); - assertEquals("Text with levels", shape3.getTextParagraphs().get(1).getText()); - assertEquals("Level 1", shape3.getTextParagraphs().get(2).getText()); - assertEquals("Level 2", shape3.getTextParagraphs().get(3).getText()); - assertEquals("Level 3", shape3.getTextParagraphs().get(4).getText()); - - for(int p = 0; p < 5; p++) { - XSLFTextParagraph pr = shape3.getTextParagraphs().get(p); - assertEquals("Calibri", pr.getTextRuns().get(0).getFontFamily()); - assertEquals(18.0, pr.getTextRuns().get(0).getFontSize(), 0); - } - } - - void verifySlide8(XSLFSlide slide){ - XSLFSlideLayout layout = slide.getSlideLayout(); - List shapes = slide.getShapes(); - assertEquals("Content with Caption",layout.getName()); - - XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); - CTPlaceholder ph1 = shape1.getCTPlaceholder(); - assertEquals(STPlaceholderType.TITLE, ph1.getType()); - // anchor is not defined in the shape - assertNull(getSpPr(shape1).getXfrm()); - - XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - // layout does not have anchor info either, it is in the slide master - assertNotNull(getSpPr(masterShape1).getXfrm()); - assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); - - CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && - !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && - !bodyPr1.isSetAnchor() - ); - assertEquals(7.2, shape1.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape1.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.BOTTOM, shape1.getVerticalAlignment()); - - // now check text properties - assertEquals("Caption", shape1.getText()); - XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign()); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(20.0, r1.getFontSize(), 0); - assertTrue(sameColor(Color.black, r1.getFontColor())); - assertTrue(r1.isBold()); - - XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); - CTPlaceholder ph2 = shape2.getCTPlaceholder(); - assertFalse(ph2.isSetType()); - assertTrue(ph2.isSetIdx()); - assertEquals(1, ph2.getIdx()); - // anchor is not defined in the shape - assertNull(getSpPr(shape2).getXfrm()); - - XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(getSpPr(masterShape2).getXfrm()); - assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); - - CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); - // none of the following properties are set in the shapes and fetched from the master shape - assertTrue( - !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && - !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && - !bodyPr2.isSetAnchor() - ); - assertEquals(7.2, shape2.getLeftInset(), 0); // 0.1" - assertEquals(7.2, shape2.getRightInset(), 0); // 0.1" - assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" - assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" - assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); - - XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(0, pr1.getParentParagraph().getIndentLevel()); - assertEquals("Level 1", pr1.getRawText()); - assertEquals("Calibri", pr1.getFontFamily()); - assertEquals(32.0, pr1.getFontSize(), 0); - assertEquals(27.0, pr1.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr1.getParentParagraph().getBulletFont()); - - XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0); - assertEquals(1, pr2.getParentParagraph().getIndentLevel()); - assertEquals("Level 2", pr2.getParentParagraph().getText()); - assertEquals("Calibri", pr2.getFontFamily()); - assertEquals(28.0, pr2.getFontSize(), 0); - assertEquals(58.5, pr2.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr2.getParentParagraph().getBulletFont()); - - XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0); - assertEquals(2, pr3.getParentParagraph().getIndentLevel()); - assertEquals("Level 3", pr3.getParentParagraph().getText()); - assertEquals("Calibri", pr3.getFontFamily()); - assertEquals(24.0, pr3.getFontSize(), 0); - assertEquals(90.0, pr3.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr3.getParentParagraph().getBulletFont()); - - XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0); - assertEquals(3, pr4.getParentParagraph().getIndentLevel()); - assertEquals("Level 4", pr4.getParentParagraph().getText()); - assertEquals("Calibri", pr4.getFontFamily()); - assertEquals(20.0, pr4.getFontSize(), 0); - assertEquals(126.0, pr4.getParentParagraph().getLeftMargin(), 0); - assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter()); - assertEquals("Arial", pr4.getParentParagraph().getBulletFont()); - - XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2); - assertEquals(VerticalAlignment.TOP, shape3.getVerticalAlignment()); - assertEquals("Content with caption", shape3.getText()); - - pr1 = shape3.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(0, pr1.getParentParagraph().getIndentLevel()); - assertEquals("Content with caption", pr1.getRawText()); - assertEquals("Calibri", pr1.getFontFamily()); - assertEquals(14.0, pr1.getFontSize(), 0); - - } - - void verifySlide10(XSLFSlide slide){ - XSLFTextShape footer = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_FTR); - - // now check text properties - assertEquals("Apache Software Foundation", footer.getText()); - assertEquals(VerticalAlignment.MIDDLE, footer.getVerticalAlignment()); - - XSLFTextRun r1 = footer.getTextParagraphs().get(0).getTextRuns().get(0); - assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign()); - assertEquals("Calibri", r1.getFontFamily()); - assertEquals(12.0, r1.getFontSize(), 0); - // TODO calculation of tint is incorrect - assertTrue(sameColor(new Color(64,64,64), r1.getFontColor())); - - XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT); - assertEquals("Friday, October 21, 2011", dt.getText()); - - XSLFTextShape sldNum = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_SLD_NUM); - assertEquals("10", sldNum.getText()); - } - - @Test - public void testTitleStyles() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlideMaster master = ppt.getSlideMasters().get(0); - XSLFTheme theme = master.getTheme(); - XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE); - XSLFSlide slide = ppt.createSlide(layout) ; - assertSame(layout, slide.getSlideLayout()); - assertSame(master, slide.getSlideMaster()); - - XSLFTextShape titleShape = slide.getPlaceholder(0); - titleShape.setText("Apache POI"); - XSLFTextParagraph paragraph = titleShape.getTextParagraphs().get(0); - XSLFTextRun textRun = paragraph.getTextRuns().get(0); - - // level 1 : default title style on the master slide - // /p:sldMaster/p:txStyles/p:titleStyle/a:lvl1pPr - CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getTitleStyle().getLvl1PPr(); - CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr(); - assertEquals(4400, lv1CPr.getSz()); - assertEquals(44.0, textRun.getFontSize(), 0); - assertEquals("+mj-lt", lv1CPr.getLatin().getTypeface()); - assertEquals("Calibri", theme.getMajorFont()); - assertEquals("Calibri", textRun.getFontFamily()); - lv1CPr.setSz(3200); - assertEquals(32.0, textRun.getFontSize(), 0); - lv1CPr.getLatin().setTypeface("Arial"); - assertEquals("Arial", textRun.getFontFamily()); - assertEquals(STTextAlignType.CTR, lv1PPr.getAlgn()); - assertEquals(TextAlign.CENTER, paragraph.getTextAlign()); - lv1PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, paragraph.getTextAlign()); - - // level 2: title placeholder on the master slide - // /p:sldMaster/p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="title"] - XSLFTextShape tx2 = master.getPlaceholder(0); - CTTextParagraphProperties lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr(); - CTTextCharacterProperties lv2CPr = lv2PPr.addNewDefRPr(); - lv2CPr.setSz(3300); - assertEquals(33.0, textRun.getFontSize(), 0); - lv2CPr.addNewLatin().setTypeface("Times"); - assertEquals("Times", textRun.getFontFamily()); - lv2PPr.setAlgn(STTextAlignType.R); - assertEquals(TextAlign.RIGHT, paragraph.getTextAlign()); - - - // level 3: title placeholder on the slide layout - // /p:sldLayout /p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="ctrTitle"] - XSLFTextShape tx3 = layout.getPlaceholder(0); - CTTextParagraphProperties lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr(); - CTTextCharacterProperties lv3CPr = lv3PPr.addNewDefRPr(); - lv3CPr.setSz(3400); - assertEquals(34.0, textRun.getFontSize(), 0); - lv3CPr.addNewLatin().setTypeface("Courier New"); - assertEquals("Courier New", textRun.getFontFamily()); - lv3PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, paragraph.getTextAlign()); - - // level 4: default text properties in the shape itself - // ./p:sp/p:txBody/a:lstStyle/a:lvl1pPr - CTTextParagraphProperties lv4PPr = titleShape.getTextBody(true).getLstStyle().addNewLvl1PPr(); - CTTextCharacterProperties lv4CPr = lv4PPr.addNewDefRPr(); - lv4CPr.setSz(3500); - assertEquals(35.0, textRun.getFontSize(), 0); - lv4CPr.addNewLatin().setTypeface("Arial"); - assertEquals("Arial", textRun.getFontFamily()); - lv4PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, paragraph.getTextAlign()); - - // level 5: text properties are defined in the text run - CTTextParagraphProperties lv5PPr = paragraph.getXmlObject().addNewPPr(); - CTTextCharacterProperties lv5CPr = textRun.getXmlObject().getRPr(); - lv5CPr.setSz(3600); - assertEquals(36.0, textRun.getFontSize(), 0); - lv5CPr.addNewLatin().setTypeface("Calibri"); - assertEquals("Calibri", textRun.getFontFamily()); - lv5PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, paragraph.getTextAlign()); - - ppt.close(); - } - - @Test - public void testBodyStyles() throws IOException { - XMLSlideShow ppt = new XMLSlideShow(); - - XSLFSlideMaster master = ppt.getSlideMasters().get(0); - XSLFTheme theme = master.getTheme(); - XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE_AND_CONTENT); - XSLFSlide slide = ppt.createSlide(layout) ; - assertSame(layout, slide.getSlideLayout()); - assertSame(master, slide.getSlideMaster()); - - XSLFTextShape tx1 = slide.getPlaceholder(1); - tx1.clearText(); - - XSLFTextParagraph p1 = tx1.addNewTextParagraph(); - assertEquals(0, p1.getIndentLevel()); - XSLFTextRun r1 = p1.addNewTextRun(); - r1.setText("Apache POI"); - - XSLFTextParagraph p2 = tx1.addNewTextParagraph(); - p2.setIndentLevel(1); - assertEquals(1, p2.getIndentLevel()); - XSLFTextRun r2 = p2.addNewTextRun(); - r2.setText("HSLF"); - - XSLFTextParagraph p3 = tx1.addNewTextParagraph(); - p3.setIndentLevel(2); - assertEquals(2, p3.getIndentLevel()); - XSLFTextRun r3 = p3.addNewTextRun(); - r3.setText("XSLF"); - - // level 1 : default title style on the master slide - // /p:sldMaster/p:txStyles/p:bodyStyle/a:lvl1pPr - CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl1PPr(); - CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr(); - CTTextParagraphProperties lv2PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl2PPr(); - CTTextCharacterProperties lv2CPr = lv2PPr.getDefRPr(); - CTTextParagraphProperties lv3PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl3PPr(); - CTTextCharacterProperties lv3CPr = lv3PPr.getDefRPr(); - // lv1 - assertEquals(3200, lv1CPr.getSz()); - assertEquals(32.0, r1.getFontSize(), 0); - assertEquals("+mn-lt", lv1CPr.getLatin().getTypeface()); - assertEquals("Calibri", theme.getMinorFont()); - assertEquals("Calibri", r1.getFontFamily()); - lv1CPr.setSz(3300); - assertEquals(33.0, r1.getFontSize(), 0); - lv1CPr.getLatin().setTypeface("Arial"); - assertEquals("Arial", r1.getFontFamily()); - assertEquals(STTextAlignType.L, lv1PPr.getAlgn()); - assertEquals(TextAlign.LEFT, p1.getTextAlign()); - lv1PPr.setAlgn(STTextAlignType.R); - assertEquals(TextAlign.RIGHT, p1.getTextAlign()); - //lv2 - assertEquals(2800, lv2CPr.getSz()); - assertEquals(28.0, r2.getFontSize(), 0); - lv2CPr.setSz(3300); - assertEquals(33.0, r2.getFontSize(), 0); - lv2CPr.getLatin().setTypeface("Times"); - assertEquals("Times", r2.getFontFamily()); - assertEquals(STTextAlignType.L, lv2PPr.getAlgn()); - assertEquals(TextAlign.LEFT, p2.getTextAlign()); - lv2PPr.setAlgn(STTextAlignType.R); - assertEquals(TextAlign.RIGHT, p2.getTextAlign()); - //lv3 - assertEquals(2400, lv3CPr.getSz()); - assertEquals(24.0, r3.getFontSize(), 0); - lv3CPr.setSz(2500); - assertEquals(25.0, r3.getFontSize(), 0); - lv3CPr.getLatin().setTypeface("Courier New"); - assertEquals("Courier New", r3.getFontFamily()); - assertEquals(STTextAlignType.L, lv3PPr.getAlgn()); - assertEquals(TextAlign.LEFT, p3.getTextAlign()); - lv3PPr.setAlgn(STTextAlignType.R); - assertEquals(TextAlign.RIGHT, p3.getTextAlign()); - - - // level 2: body placeholder on the master slide - // /p:sldMaster/p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="body"] - XSLFTextShape tx2 = master.getPlaceholder(1); - assertEquals(Placeholder.BODY, tx2.getTextType()); - - lv1PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr(); - lv1CPr = lv1PPr.addNewDefRPr(); - lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl2PPr(); - lv2CPr = lv2PPr.addNewDefRPr(); - lv3PPr = tx2.getTextBody(true).getLstStyle().addNewLvl3PPr(); - lv3CPr = lv3PPr.addNewDefRPr(); - - lv1CPr.setSz(3300); - assertEquals(33.0, r1.getFontSize(), 0); - lv1CPr.addNewLatin().setTypeface("Times"); - assertEquals("Times", r1.getFontFamily()); - lv1PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, p1.getTextAlign()); - - lv2CPr.setSz(3300); - assertEquals(33.0, r2.getFontSize(), 0); - lv2CPr.addNewLatin().setTypeface("Times"); - assertEquals("Times", r2.getFontFamily()); - lv2PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, p2.getTextAlign()); - - lv3CPr.setSz(3300); - assertEquals(33.0, r3.getFontSize(), 0); - lv3CPr.addNewLatin().setTypeface("Times"); - assertEquals("Times", r3.getFontFamily()); - lv3PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, p3.getTextAlign()); - - // level 3: body placeholder on the slide layout - // /p:sldLayout /p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="ctrTitle"] - XSLFTextShape tx3 = layout.getPlaceholder(1); - assertEquals(Placeholder.BODY, tx2.getTextType()); - lv1PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr(); - lv1CPr = lv1PPr.addNewDefRPr(); - lv2PPr = tx3.getTextBody(true).getLstStyle().addNewLvl2PPr(); - lv2CPr = lv2PPr.addNewDefRPr(); - lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl3PPr(); - lv3CPr = lv3PPr.addNewDefRPr(); - - lv1CPr.setSz(3400); - assertEquals(34.0, r1.getFontSize(), 0); - lv1CPr.addNewLatin().setTypeface("Courier New"); - assertEquals("Courier New", r1.getFontFamily()); - lv1PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, p1.getTextAlign()); - - lv2CPr.setSz(3400); - assertEquals(34.0, r2.getFontSize(), 0); - lv2CPr.addNewLatin().setTypeface("Courier New"); - assertEquals("Courier New", r2.getFontFamily()); - lv2PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, p2.getTextAlign()); - - lv3CPr.setSz(3400); - assertEquals(34.0, r3.getFontSize(), 0); - lv3CPr.addNewLatin().setTypeface("Courier New"); - assertEquals("Courier New", r3.getFontFamily()); - lv3PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, p3.getTextAlign()); - - // level 4: default text properties in the shape itself - // ./p:sp/p:txBody/a:lstStyle/a:lvl1pPr - lv1PPr = tx1.getTextBody(true).getLstStyle().addNewLvl1PPr(); - lv1CPr = lv1PPr.addNewDefRPr(); - lv2PPr = tx1.getTextBody(true).getLstStyle().addNewLvl2PPr(); - lv2CPr = lv2PPr.addNewDefRPr(); - lv3PPr = tx1.getTextBody(true).getLstStyle().addNewLvl3PPr(); - lv3CPr = lv3PPr.addNewDefRPr(); - - lv1CPr.setSz(3500); - assertEquals(35.0, r1.getFontSize(), 0); - lv1CPr.addNewLatin().setTypeface("Arial"); - assertEquals("Arial", r1.getFontFamily()); - lv1PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, p1.getTextAlign()); - - lv2CPr.setSz(3500); - assertEquals(35.0, r2.getFontSize(), 0); - lv2CPr.addNewLatin().setTypeface("Arial"); - assertEquals("Arial", r2.getFontFamily()); - lv2PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, p2.getTextAlign()); - - lv3CPr.setSz(3500); - assertEquals(35.0, r3.getFontSize(), 0); - lv3CPr.addNewLatin().setTypeface("Arial"); - assertEquals("Arial", r3.getFontFamily()); - lv3PPr.setAlgn(STTextAlignType.L); - assertEquals(TextAlign.LEFT, p3.getTextAlign()); - - // level 5: text properties are defined in the text run - lv1PPr = p1.getXmlObject().isSetPPr() ? p1.getXmlObject().getPPr() : p1.getXmlObject().addNewPPr(); - lv1CPr = r1.getXmlObject().getRPr(); - lv2PPr = p2.getXmlObject().isSetPPr() ? p2.getXmlObject().getPPr() : p2.getXmlObject().addNewPPr(); - lv2CPr = r2.getXmlObject().getRPr(); - lv3PPr = p3.getXmlObject().isSetPPr() ? p3.getXmlObject().getPPr() : p3.getXmlObject().addNewPPr(); - lv3CPr = r3.getXmlObject().getRPr(); - - lv1CPr.setSz(3600); - assertEquals(36.0, r1.getFontSize(), 0); - lv1CPr.addNewLatin().setTypeface("Calibri"); - assertEquals("Calibri", r1.getFontFamily()); - lv1PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, p1.getTextAlign()); - - lv2CPr.setSz(3600); - assertEquals(36.0, r2.getFontSize(), 0); - lv2CPr.addNewLatin().setTypeface("Calibri"); - assertEquals("Calibri", r2.getFontFamily()); - lv2PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, p2.getTextAlign()); - - lv3CPr.setSz(3600); - assertEquals(36.0, r3.getFontSize(), 0); - lv3CPr.addNewLatin().setTypeface("Calibri"); - assertEquals("Calibri", r3.getFontFamily()); - lv3PPr.setAlgn(STTextAlignType.CTR); - assertEquals(TextAlign.CENTER, p3.getTextAlign()); - - ppt.close(); - } - - @Test - public void metroBlob() throws IOException { - File f = POIDataSamples.getSlideShowInstance().getFile("bug52297.ppt"); - SlideShow ppt = SlideShowFactory.create(f); - HSLFTextShape sh = (HSLFTextShape)ppt.getSlides().get(1).getShapes().get(3); - XSLFAutoShape xsh = (XSLFAutoShape)sh.getMetroShape(); - String textExp = " ___ ___ ___ ________ __ _______ ___ ___________ __________ __ _____ ___ ___ ___ _______ ____ ______ ___________ _____________ ___ _______ ______ ____ ______ __ ___________ __________ ___ _________ _____ ________ __________ ___ _______ __________ "; - String textAct = xsh.getText(); - ppt.close(); - assertEquals(textExp, textAct); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java b/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java deleted file mode 100644 index 912ecc0f3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java +++ /dev/null @@ -1,166 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -import static org.apache.poi.sl.TestCommonSL.sameColor; -import static org.junit.Assert.*; - -import java.awt.Color; -import java.util.List; - -import org.apache.poi.sl.usermodel.*; -import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; -import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.Test; - -/** - * test reading properties from a multi-theme and multi-master document - * - * @author Yegor Kozlov - */ -public class TestXSLFTheme { - @Test - public void testRead(){ - XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("themes.pptx"); - List slides = ppt.getSlides(); - - slide1(slides.get(0)); - slide2(slides.get(1)); - slide3(slides.get(2)); - slide4(slides.get(3)); - slide5(slides.get(4)); - slide6(slides.get(5)); - slide7(slides.get(6)); - slide8(slides.get(7)); - slide9(slides.get(8)); - slide10(slides.get(9)); - } - - private XSLFShape getShape(XSLFSheet sheet, String name){ - for(XSLFShape sh : sheet.getShapes()){ - if(sh.getShapeName().equals(name)) return sh; - } - throw new IllegalArgumentException("Shape not found: " + name); - } - - void slide1(XSLFSlide slide){ - assertEquals(Color.WHITE, slide.getBackground().getFillColor()); - - XSLFTheme theme = slide.getTheme(); - assertEquals("Office Theme", theme.getName()); - - XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 3"); - XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(Color.white, run1.getFontColor())); - assertEquals(new Color(79, 129, 189), sh1.getFillColor()); - assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill - - } - - void slide2(XSLFSlide slide){ - // Background 2, darker 10% - // YK: PPT shows slightly different color: new Color(221, 217, 195) - assertEquals(new Color(221, 217, 195), slide.getBackground().getFillColor()); - } - - void slide3(XSLFSlide slide){ - PaintStyle fs = slide.getBackground().getFillStyle().getPaint(); - assertTrue(fs instanceof GradientPaint); - } - - void slide4(XSLFSlide slide){ - PaintStyle fs = slide.getBackground().getFillStyle().getPaint(); - assertTrue(fs instanceof GradientPaint); - - XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 4"); - XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(Color.white, run1.getFontColor())); - assertEquals(new Color(148, 198, 0), sh1.getFillColor()); - assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ; // solid fill - - XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 3"); - XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor())); - assertNull(sh2.getFillColor()); // no fill - - assertFalse(slide.getSlideLayout().getFollowMasterGraphics()); - } - - void slide5(XSLFSlide slide){ - PaintStyle fs = slide.getBackground().getFillStyle().getPaint(); - assertTrue(fs instanceof TexturePaint); - - XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 1"); - XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor())); - assertNull(sh2.getFillColor()); // no fill - // font size is 40pt and scale factor is 90% - assertEquals(36.0, run2.getFontSize(), 0); - - assertFalse(slide.getSlideLayout().getFollowMasterGraphics()); - } - - void slide6(XSLFSlide slide){ - - XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Subtitle 3"); - XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(new Color(66, 66, 66), run1.getFontColor())); - assertNull(sh1.getFillColor()); // no fill - - XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 2"); - XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor())); - assertNull(sh2.getFillColor()); // no fill - - assertFalse(slide.getSlideLayout().getFollowMasterGraphics()); - } - - void slide7(XSLFSlide slide){ - - //YK: PPT reports a slightly different color: r=189,g=239,b=87 - assertEquals(new Color(189, 239, 87), slide.getBackground().getFillColor()); - - assertFalse(slide.getFollowMasterGraphics()); - } - - void slide8(XSLFSlide slide){ - PaintStyle fs = slide.getBackground().getFillStyle().getPaint(); - assertTrue(fs instanceof TexturePaint); - } - - void slide9(XSLFSlide slide){ - PaintStyle fs = slide.getBackground().getFillStyle().getPaint(); - assertTrue(fs instanceof TexturePaint); - } - - void slide10(XSLFSlide slide){ - PaintStyle fs = slide.getBackground().getFillStyle().getPaint(); - assertTrue(fs instanceof GradientPaint); - - XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Title 3"); - XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(Color.white, run1.getFontColor())); - assertNull(sh1.getFillColor()); // no fill - - XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Subtitle 4"); - XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0); - assertTrue(sameColor(Color.white, run2.getFontColor())); - assertNull(sh2.getFillColor()); // no fill - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/AllXSSFTests.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/AllXSSFTests.java deleted file mode 100644 index c6e2f7eca..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/AllXSSFTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import org.apache.poi.ss.format.TestCellFormatPart; -import org.apache.poi.xssf.eventusermodel.TestXSSFReader; -import org.apache.poi.xssf.extractor.TestXSSFExcelExtractor; -import org.apache.poi.xssf.io.TestLoadSaveXSSF; -import org.apache.poi.xssf.model.TestCommentsTable; -import org.apache.poi.xssf.model.TestSharedStringsTable; -import org.apache.poi.xssf.usermodel.AllXSSFUsermodelTests; -import org.apache.poi.xssf.util.TestCTColComparator; -import org.apache.poi.xssf.util.TestNumericRanges; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - - -/** - * Collects all tests for org.apache.poi.xssf and sub-packages. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - AllXSSFUsermodelTests.class, - TestXSSFReader.class, - TestXSSFExcelExtractor.class, - TestLoadSaveXSSF.class, - TestCommentsTable.class, - TestSharedStringsTable.class, - //TestStylesTable.class, //converted to junit4 - //TestCellReference.class, //converted to junit4 - TestCTColComparator.class, - TestNumericRanges.class, - TestCellFormatPart.class, - TestXSSFCloneSheet.class -}) -public final class AllXSSFTests { -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java deleted file mode 100644 index 4f2eb40f9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.streaming.SXSSFSheet; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * @author Yegor Kozlov - */ -public final class SXSSFITestDataProvider implements ITestDataProvider { - public static final SXSSFITestDataProvider instance = new SXSSFITestDataProvider(); - - // an instance of all SXSSFWorkbooks opened by this TestDataProvider, - // so that the temporary files created can be disposed up by cleanup() - private final Collection instances = new ArrayList(); - - private SXSSFITestDataProvider() { - // enforce singleton - } - - @Override - public Workbook openSampleWorkbook(String sampleFileName) { - XSSFWorkbook xssfWorkbook = XSSFITestDataProvider.instance.openSampleWorkbook(sampleFileName); - SXSSFWorkbook swb = new SXSSFWorkbook(xssfWorkbook); - instances.add(swb); - return swb; - } - - /** - * Returns an XSSFWorkbook since SXSSFWorkbook is write-only - */ - @Override - public XSSFWorkbook writeOutAndReadBack(Workbook wb) { - if(!(wb instanceof SXSSFWorkbook)) { - throw new IllegalArgumentException("Expected an instance of SXSSFWorkbook"); - } - - XSSFWorkbook result; - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(8192); - wb.write(baos); - InputStream is = new ByteArrayInputStream(baos.toByteArray()); - result = new XSSFWorkbook(is); - } catch (IOException e) { - throw new RuntimeException(e); - } - return result; - } - - @Override - public SXSSFWorkbook createWorkbook() { - SXSSFWorkbook wb = new SXSSFWorkbook(); - instances.add(wb); - return wb; - } - - //************ SXSSF-specific methods ***************// - @Override - public SXSSFWorkbook createWorkbook(int rowAccessWindowSize) { - SXSSFWorkbook wb = new SXSSFWorkbook(rowAccessWindowSize); - instances.add(wb); - return wb; - } - - @Override - public void trackAllColumnsForAutosizing(Sheet sheet) { - ((SXSSFSheet)sheet).trackAllColumnsForAutoSizing(); - } - //************ End SXSSF-specific methods ***************// - - @Override - public FormulaEvaluator createFormulaEvaluator(Workbook wb) { - return new XSSFFormulaEvaluator(((SXSSFWorkbook) wb).getXSSFWorkbook()); - } - - @Override - public byte[] getTestDataFileContent(String fileName) { - return POIDataSamples.getSpreadSheetInstance().readFile(fileName); - } - - @Override - public SpreadsheetVersion getSpreadsheetVersion() { - return SpreadsheetVersion.EXCEL2007; - } - - @Override - public String getStandardFileNameExtension() { - return "xlsx"; - } - - public synchronized boolean cleanup() { - boolean ok = true; - for(final SXSSFWorkbook wb : instances) { - ok = ok && wb.dispose(); - } - instances.clear(); - return ok; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java deleted file mode 100644 index 9e126097c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java +++ /dev/null @@ -1,260 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import junit.framework.TestCase; - -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public class TestSheetProtection extends TestCase { - private XSSFSheet sheet; - - @Override - protected void setUp() throws Exception { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("sheetProtection_not_protected.xlsx"); - sheet = workbook.getSheetAt(0); - } - - public void testShouldReadWorkbookProtection() throws Exception { - assertFalse(sheet.isAutoFilterLocked()); - assertFalse(sheet.isDeleteColumnsLocked()); - assertFalse(sheet.isDeleteRowsLocked()); - assertFalse(sheet.isFormatCellsLocked()); - assertFalse(sheet.isFormatColumnsLocked()); - assertFalse(sheet.isFormatRowsLocked()); - assertFalse(sheet.isInsertColumnsLocked()); - assertFalse(sheet.isInsertHyperlinksLocked()); - assertFalse(sheet.isInsertRowsLocked()); - assertFalse(sheet.isPivotTablesLocked()); - assertFalse(sheet.isSortLocked()); - assertFalse(sheet.isObjectsLocked()); - assertFalse(sheet.isScenariosLocked()); - assertFalse(sheet.isSelectLockedCellsLocked()); - assertFalse(sheet.isSelectUnlockedCellsLocked()); - assertFalse(sheet.isSheetLocked()); - - sheet = XSSFTestDataSamples.openSampleWorkbook("sheetProtection_allLocked.xlsx").getSheetAt(0); - - assertTrue(sheet.isAutoFilterLocked()); - assertTrue(sheet.isDeleteColumnsLocked()); - assertTrue(sheet.isDeleteRowsLocked()); - assertTrue(sheet.isFormatCellsLocked()); - assertTrue(sheet.isFormatColumnsLocked()); - assertTrue(sheet.isFormatRowsLocked()); - assertTrue(sheet.isInsertColumnsLocked()); - assertTrue(sheet.isInsertHyperlinksLocked()); - assertTrue(sheet.isInsertRowsLocked()); - assertTrue(sheet.isPivotTablesLocked()); - assertTrue(sheet.isSortLocked()); - assertTrue(sheet.isObjectsLocked()); - assertTrue(sheet.isScenariosLocked()); - assertTrue(sheet.isSelectLockedCellsLocked()); - assertTrue(sheet.isSelectUnlockedCellsLocked()); - assertTrue(sheet.isSheetLocked()); - } - - public void testWriteAutoFilter() throws Exception { - assertFalse(sheet.isAutoFilterLocked()); - sheet.lockAutoFilter(true); - assertFalse(sheet.isAutoFilterLocked()); - sheet.enableLocking(); - assertTrue(sheet.isAutoFilterLocked()); - sheet.lockAutoFilter(false); - assertFalse(sheet.isAutoFilterLocked()); - } - - public void testWriteDeleteColumns() throws Exception { - assertFalse(sheet.isDeleteColumnsLocked()); - sheet.lockDeleteColumns(true); - assertFalse(sheet.isDeleteColumnsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isDeleteColumnsLocked()); - sheet.lockDeleteColumns(false); - assertFalse(sheet.isDeleteColumnsLocked()); - } - - public void testWriteDeleteRows() throws Exception { - assertFalse(sheet.isDeleteRowsLocked()); - sheet.lockDeleteRows(true); - assertFalse(sheet.isDeleteRowsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isDeleteRowsLocked()); - sheet.lockDeleteRows(false); - assertFalse(sheet.isDeleteRowsLocked()); - } - - public void testWriteFormatCells() throws Exception { - assertFalse(sheet.isFormatCellsLocked()); - sheet.lockFormatCells(true); - assertFalse(sheet.isFormatCellsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isFormatCellsLocked()); - sheet.lockFormatCells(false); - assertFalse(sheet.isFormatCellsLocked()); - } - - public void testWriteFormatColumns() throws Exception { - assertFalse(sheet.isFormatColumnsLocked()); - sheet.lockFormatColumns(true); - assertFalse(sheet.isFormatColumnsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isFormatColumnsLocked()); - sheet.lockFormatColumns(false); - assertFalse(sheet.isFormatColumnsLocked()); - } - - public void testWriteFormatRows() throws Exception { - assertFalse(sheet.isFormatRowsLocked()); - sheet.lockFormatRows(true); - assertFalse(sheet.isFormatRowsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isFormatRowsLocked()); - sheet.lockFormatRows(false); - assertFalse(sheet.isFormatRowsLocked()); - } - - public void testWriteInsertColumns() throws Exception { - assertFalse(sheet.isInsertColumnsLocked()); - sheet.lockInsertColumns(true); - assertFalse(sheet.isInsertColumnsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isInsertColumnsLocked()); - sheet.lockInsertColumns(false); - assertFalse(sheet.isInsertColumnsLocked()); - } - - public void testWriteInsertHyperlinks() throws Exception { - assertFalse(sheet.isInsertHyperlinksLocked()); - sheet.lockInsertHyperlinks(true); - assertFalse(sheet.isInsertHyperlinksLocked()); - sheet.enableLocking(); - assertTrue(sheet.isInsertHyperlinksLocked()); - sheet.lockInsertHyperlinks(false); - assertFalse(sheet.isInsertHyperlinksLocked()); - } - - public void testWriteInsertRows() throws Exception { - assertFalse(sheet.isInsertRowsLocked()); - sheet.lockInsertRows(true); - assertFalse(sheet.isInsertRowsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isInsertRowsLocked()); - sheet.lockInsertRows(false); - assertFalse(sheet.isInsertRowsLocked()); - } - - public void testWritePivotTables() throws Exception { - assertFalse(sheet.isPivotTablesLocked()); - sheet.lockPivotTables(true); - assertFalse(sheet.isPivotTablesLocked()); - sheet.enableLocking(); - assertTrue(sheet.isPivotTablesLocked()); - sheet.lockPivotTables(false); - assertFalse(sheet.isPivotTablesLocked()); - } - - public void testWriteSort() throws Exception { - assertFalse(sheet.isSortLocked()); - sheet.lockSort(true); - assertFalse(sheet.isSortLocked()); - sheet.enableLocking(); - assertTrue(sheet.isSortLocked()); - sheet.lockSort(false); - assertFalse(sheet.isSortLocked()); - } - - public void testWriteObjects() throws Exception { - assertFalse(sheet.isObjectsLocked()); - sheet.lockObjects(true); - assertFalse(sheet.isObjectsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isObjectsLocked()); - sheet.lockObjects(false); - assertFalse(sheet.isObjectsLocked()); - } - - public void testWriteScenarios() throws Exception { - assertFalse(sheet.isScenariosLocked()); - sheet.lockScenarios(true); - assertFalse(sheet.isScenariosLocked()); - sheet.enableLocking(); - assertTrue(sheet.isScenariosLocked()); - sheet.lockScenarios(false); - assertFalse(sheet.isScenariosLocked()); - } - - public void testWriteSelectLockedCells() throws Exception { - assertFalse(sheet.isSelectLockedCellsLocked()); - sheet.lockSelectLockedCells(true); - assertFalse(sheet.isSelectLockedCellsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isSelectLockedCellsLocked()); - sheet.lockSelectLockedCells(false); - assertFalse(sheet.isSelectLockedCellsLocked()); - } - - public void testWriteSelectUnlockedCells() throws Exception { - assertFalse(sheet.isSelectUnlockedCellsLocked()); - sheet.lockSelectUnlockedCells(true); - assertFalse(sheet.isSelectUnlockedCellsLocked()); - sheet.enableLocking(); - assertTrue(sheet.isSelectUnlockedCellsLocked()); - sheet.lockSelectUnlockedCells(false); - assertFalse(sheet.isSelectUnlockedCellsLocked()); - } - - public void testWriteSelectEnableLocking() throws Exception { - sheet = XSSFTestDataSamples.openSampleWorkbook("sheetProtection_allLocked.xlsx").getSheetAt(0); - - assertTrue(sheet.isAutoFilterLocked()); - assertTrue(sheet.isDeleteColumnsLocked()); - assertTrue(sheet.isDeleteRowsLocked()); - assertTrue(sheet.isFormatCellsLocked()); - assertTrue(sheet.isFormatColumnsLocked()); - assertTrue(sheet.isFormatRowsLocked()); - assertTrue(sheet.isInsertColumnsLocked()); - assertTrue(sheet.isInsertHyperlinksLocked()); - assertTrue(sheet.isInsertRowsLocked()); - assertTrue(sheet.isPivotTablesLocked()); - assertTrue(sheet.isSortLocked()); - assertTrue(sheet.isObjectsLocked()); - assertTrue(sheet.isScenariosLocked()); - assertTrue(sheet.isSelectLockedCellsLocked()); - assertTrue(sheet.isSelectUnlockedCellsLocked()); - assertTrue(sheet.isSheetLocked()); - - sheet.disableLocking(); - - assertFalse(sheet.isAutoFilterLocked()); - assertFalse(sheet.isDeleteColumnsLocked()); - assertFalse(sheet.isDeleteRowsLocked()); - assertFalse(sheet.isFormatCellsLocked()); - assertFalse(sheet.isFormatColumnsLocked()); - assertFalse(sheet.isFormatRowsLocked()); - assertFalse(sheet.isInsertColumnsLocked()); - assertFalse(sheet.isInsertHyperlinksLocked()); - assertFalse(sheet.isInsertRowsLocked()); - assertFalse(sheet.isPivotTablesLocked()); - assertFalse(sheet.isSortLocked()); - assertFalse(sheet.isObjectsLocked()); - assertFalse(sheet.isScenariosLocked()); - assertFalse(sheet.isSelectLockedCellsLocked()); - assertFalse(sheet.isSelectUnlockedCellsLocked()); - assertFalse(sheet.isSheetLocked()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java deleted file mode 100644 index 9c7e9355d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java +++ /dev/null @@ -1,236 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook; -import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.OutputStream; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionMode; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Ignore; -import org.junit.Test; - -public class TestWorkbookProtection { - - @Test - public void workbookAndRevisionPassword() throws Exception { - XSSFWorkbook workbook; - String password = "test"; - - // validate password with an actual office file (Excel 2010) - workbook = openSampleWorkbook("workbookProtection-workbook_password_user_range-2010.xlsx"); - assertTrue(workbook.validateWorkbookPassword(password)); - - // validate with another office file (Excel 2013) - workbook = openSampleWorkbook("workbookProtection-workbook_password-2013.xlsx"); - assertTrue(workbook.validateWorkbookPassword(password)); - - - workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx"); - - // setting a null password shouldn't introduce the protection element - workbook.setWorkbookPassword(null, null); - assertNull(workbook.getCTWorkbook().getWorkbookProtection()); - - // compare the hashes - workbook.setWorkbookPassword(password, null); - int hashVal = CryptoFunctions.createXorVerifier1(password); - int actualVal = Integer.parseInt(workbook.getCTWorkbook().getWorkbookProtection().xgetWorkbookPassword().getStringValue(),16); - assertEquals(hashVal, actualVal); - assertTrue(workbook.validateWorkbookPassword(password)); - - // removing the password again - workbook.setWorkbookPassword(null, null); - assertFalse(workbook.getCTWorkbook().getWorkbookProtection().isSetWorkbookPassword()); - - // removing the whole protection structure - workbook.unLock(); - assertNull(workbook.getCTWorkbook().getWorkbookProtection()); - - // setting a null password shouldn't introduce the protection element - workbook.setRevisionsPassword(null, null); - assertNull(workbook.getCTWorkbook().getWorkbookProtection()); - - // compare the hashes - password = "T\u0400ST\u0100passwordWhichIsLongerThan15Chars"; - workbook.setRevisionsPassword(password, null); - hashVal = CryptoFunctions.createXorVerifier1(password); - actualVal = Integer.parseInt(workbook.getCTWorkbook().getWorkbookProtection().xgetRevisionsPassword().getStringValue(),16); - assertEquals(hashVal, actualVal); - assertTrue(workbook.validateRevisionsPassword(password)); - } - - @Test - public void shouldReadWorkbookProtection() throws Exception { - XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx"); - assertFalse(workbook.isStructureLocked()); - assertFalse(workbook.isWindowsLocked()); - assertFalse(workbook.isRevisionLocked()); - - workbook = openSampleWorkbook("workbookProtection_workbook_structure_protected.xlsx"); - assertTrue(workbook.isStructureLocked()); - assertFalse(workbook.isWindowsLocked()); - assertFalse(workbook.isRevisionLocked()); - - workbook = openSampleWorkbook("workbookProtection_workbook_windows_protected.xlsx"); - assertTrue(workbook.isWindowsLocked()); - assertFalse(workbook.isStructureLocked()); - assertFalse(workbook.isRevisionLocked()); - - workbook = openSampleWorkbook("workbookProtection_workbook_revision_protected.xlsx"); - assertTrue(workbook.isRevisionLocked()); - assertFalse(workbook.isWindowsLocked()); - assertFalse(workbook.isStructureLocked()); - } - - @Test - public void shouldWriteStructureLock() throws Exception { - XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx"); - assertFalse(workbook.isStructureLocked()); - - workbook.lockStructure(); - - assertTrue(workbook.isStructureLocked()); - - workbook.unLockStructure(); - - assertFalse(workbook.isStructureLocked()); - } - - @Test - public void shouldWriteWindowsLock() throws Exception { - XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx"); - assertFalse(workbook.isWindowsLocked()); - - workbook.lockWindows(); - - assertTrue(workbook.isWindowsLocked()); - - workbook.unLockWindows(); - - assertFalse(workbook.isWindowsLocked()); - } - - @Test - public void shouldWriteRevisionLock() throws Exception { - XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx"); - assertFalse(workbook.isRevisionLocked()); - - workbook.lockRevision(); - - assertTrue(workbook.isRevisionLocked()); - - workbook.unLockRevision(); - - assertFalse(workbook.isRevisionLocked()); - } - - @SuppressWarnings("resource") - @Test - public void testHashPassword() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - wb.lockRevision(); - wb.setRevisionsPassword("test", HashAlgorithm.sha1); - - wb = writeOutAndReadBack(wb); - - assertTrue(wb.isRevisionLocked()); - assertTrue(wb.validateRevisionsPassword("test")); - } - - @SuppressWarnings("resource") - @Test - public void testIntegration() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - wb.createSheet("Testing purpose sheet"); - assertFalse(wb.isRevisionLocked()); - - wb.lockRevision(); - wb.setRevisionsPassword("test", null); - - wb = writeOutAndReadBack(wb); - - assertTrue(wb.isRevisionLocked()); - assertTrue(wb.validateRevisionsPassword("test")); - } - - @Test - public void testEncryptDecrypt() throws Exception { - final String password = "abc123"; - final String sheetName = "TestSheet1"; - final String cellValue = "customZipEntrySource"; - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet1 = workbook.createSheet(sheetName); - XSSFRow row1 = sheet1.createRow(1); - XSSFCell cell1 = row1.createCell(1); - cell1.setCellValue(cellValue); - File tf1 = TempFile.createTempFile("poitest", ".xlsx"); - FileOutputStream fos1 = new FileOutputStream(tf1); - workbook.write(fos1); - IOUtils.closeQuietly(fos1); - POIFSFileSystem poiFileSystem = new POIFSFileSystem(); - EncryptionInfo encryptionInfo = new EncryptionInfo(EncryptionMode.agile); - Encryptor enc = encryptionInfo.getEncryptor(); - enc.confirmPassword(password); - FileInputStream fis = new FileInputStream(tf1); - OPCPackage opc = OPCPackage.open(fis); - IOUtils.closeQuietly(fis); - try { - OutputStream os = enc.getDataStream(poiFileSystem); - opc.save(os); - IOUtils.closeQuietly(os); - } finally { - IOUtils.closeQuietly(opc); - } - tf1.delete(); - FileOutputStream fos2 = new FileOutputStream(tf1); - poiFileSystem.writeFilesystem(fos2); - IOUtils.closeQuietly(fos2); - workbook.close(); - fis = new FileInputStream(tf1); - POIFSFileSystem poiFileSystem2 = new POIFSFileSystem(fis); - IOUtils.closeQuietly(fis); - EncryptionInfo encryptionInfo2 = new EncryptionInfo(poiFileSystem2); - Decryptor decryptor = encryptionInfo2.getDecryptor(); - decryptor.verifyPassword(password); - XSSFWorkbook workbook2 = new XSSFWorkbook(decryptor.getDataStream(poiFileSystem2)); - workbook2.close(); - tf1.delete(); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestXSSFCloneSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestXSSFCloneSheet.java deleted file mode 100644 index 91883a3df..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/TestXSSFCloneSheet.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import org.apache.poi.hssf.HSSFITestDataProvider; -import org.apache.poi.ss.usermodel.BaseTestCloneSheet; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Before; -import org.junit.Test; - -public class TestXSSFCloneSheet extends BaseTestCloneSheet { - public TestXSSFCloneSheet() { - super(HSSFITestDataProvider.instance); - } - - private static final String OTHER_SHEET_NAME = "Another"; - private static final String VALID_SHEET_NAME = "Sheet01"; - private XSSFWorkbook wb; - - @Before - public void setUp() { - wb = new XSSFWorkbook(); - wb.createSheet(VALID_SHEET_NAME); - } - - @Test - public void testCloneSheetIntStringValidName() { - XSSFSheet cloned = wb.cloneSheet(0, OTHER_SHEET_NAME); - assertEquals(OTHER_SHEET_NAME, cloned.getSheetName()); - assertEquals(2, wb.getNumberOfSheets()); - } - - @Test - public void testCloneSheetIntStringInvalidName() { - try { - wb.cloneSheet(0, VALID_SHEET_NAME); - fail("Should fail"); - } catch (IllegalArgumentException e) { - // expected here - } - assertEquals(1, wb.getNumberOfSheets()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java deleted file mode 100644 index e0ba6617c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * @author Yegor Kozlov - */ -public final class XSSFITestDataProvider implements ITestDataProvider { - public static final XSSFITestDataProvider instance = new XSSFITestDataProvider(); - - private XSSFITestDataProvider() { - // enforce singleton - } - - @Override - public XSSFWorkbook openSampleWorkbook(String sampleFileName) { - return XSSFTestDataSamples.openSampleWorkbook(sampleFileName); - } - - @Override - public XSSFWorkbook writeOutAndReadBack(Workbook original) { - if(!(original instanceof XSSFWorkbook)) { - throw new IllegalArgumentException("Expected an instance of XSSFWorkbook, but had " + original.getClass()); - } - return XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)original); - } - - @Override - public XSSFWorkbook createWorkbook() { - return new XSSFWorkbook(); - } - - //************ SXSSF-specific methods ***************// - @Override - public XSSFWorkbook createWorkbook(int rowAccessWindowSize) { - return createWorkbook(); - } - - @Override - public void trackAllColumnsForAutosizing(Sheet sheet) {} - //************ End SXSSF-specific methods ***************// - - @Override - public FormulaEvaluator createFormulaEvaluator(Workbook wb) { - return new XSSFFormulaEvaluator((XSSFWorkbook) wb); - } - - @Override - public byte[] getTestDataFileContent(String fileName) { - return POIDataSamples.getSpreadSheetInstance().readFile(fileName); - } - - @Override - public SpreadsheetVersion getSpreadsheetVersion(){ - return SpreadsheetVersion.EXCEL2007; - } - - @Override - public String getStandardFileNameExtension() { - return "xlsx"; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java deleted file mode 100644 index 68188cb22..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java +++ /dev/null @@ -1,289 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Centralises logic for finding/opening sample files in the test-data/spreadsheet folder. - * - * @author Josh Micich - */ -public class XSSFTestDataSamples { - /** - * Used by {@link writeOutAndReadBack(R wb, String testName)}. If a - * value is set for this in the System Properties, the xlsx file - * will be written out to that directory. - */ - public static final String TEST_OUTPUT_DIR = "poi.test.xssf.output.dir"; - - public static File getSampleFile(String sampleFileName) { - return HSSFTestDataSamples.getSampleFile(sampleFileName); - } - public static OPCPackage openSamplePackage(String sampleName) { - try { - return OPCPackage.open(HSSFTestDataSamples.openSampleFileStream(sampleName)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - public static XSSFWorkbook openSampleWorkbook(String sampleName) { - InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleName); - try { - return new XSSFWorkbook(is); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Write out workbook wb to {@link #TEST_OUTPUT_DIR}/testName.xlsx - * (or create a temporary file if TEST_OUTPUT_DIR is not defined). - * - * @param wb the workbook to write - * @param testName a fragment of the filename - * @return the location where the workbook was saved - * @throws IOException - */ - public static File writeOut(R wb, String testName) throws IOException { - final String testOutputDir = System.getProperty(TEST_OUTPUT_DIR); - final File file; - if (testOutputDir != null) { - file = new File(testOutputDir, testName + ".xlsx"); - } - else { - file = TempFile.createTempFile(testName, ".xlsx"); - } - if (file.exists()) { - file.delete(); - } - final OutputStream out = new FileOutputStream(file); - try { - wb.write(out); - } finally { - out.close(); - } - return file; - } - - /** - * Write out workbook wb to a memory buffer - * - * @param wb the workbook to write - * @return the memory buffer - * @throws IOException - */ - public static ByteArrayOutputStream writeOut(R wb) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(8192); - wb.write(out); - return out; - } - - /** - * Write out the workbook then closes the workbook. - * This should be used when there is insufficient memory to have - * both workbooks open. - * - * Make sure there are no references to any objects in the workbook - * so that garbage collection may free the workbook. - * - * After calling this method, null the reference to wb, - * then call {@link #readBack(File)} or {@link #readBackAndDelete(File)} to re-read the file. - * - * Alternatively, use {@link #writeOutAndClose(Workbook)} to use a ByteArrayOutputStream/ByteArrayInputStream - * to avoid creating a temporary file. However, this may complicate the calling - * code to avoid having the workbook, BAOS, and BAIS open at the same time. - * - * @param wb - * @param testName file name to be used to write to a file. This file will be cleaned up by a call to readBack(String) - * @return workbook location - * @throws RuntimeException if {@link #TEST_OUTPUT_DIR} System property is not set - */ - public static File writeOutAndClose(R wb, String testName) { - try { - File file = writeOut(wb, testName); - // Do not close the workbook if there was a problem writing the workbook - wb.close(); - return file; - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - - /** - * Write out workbook wb to a memory buffer, - * then close the workbook - * - * @param wb the workbook to write - * @return the memory buffer - * @throws IOException - */ - public static ByteArrayOutputStream writeOutAndClose(R wb) { - try { - ByteArrayOutputStream out = writeOut(wb); - // Do not close the workbook if there was a problem writing the workbook - wb.close(); - return out; - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Read back a workbook that was written out to a file with - * {@link #writeOut(Workbook, String))} or {@link #writeOutAndClose(Workbook, String)}. - * Deletes the file after reading back the file. - * Does not delete the file if an exception is raised. - * - * @param file the workbook file to read and delete - * @return the read back workbook - * @throws IOException - */ - public static XSSFWorkbook readBackAndDelete(File file) throws IOException { - XSSFWorkbook wb = readBack(file); - // do not delete the file if there's an error--might be helpful for debugging - file.delete(); - return wb; - } - - /** - * Read back a workbook that was written out to a file with - * {@link #writeOut(Workbook, String)} or {@link #writeOutAndClose(Workbook, String)}. - * - * @param file the workbook file to read - * @return the read back workbook - * @throws IOException - */ - public static XSSFWorkbook readBack(File file) throws IOException { - InputStream in = new FileInputStream(file); - try { - return new XSSFWorkbook(in); - } - finally { - in.close(); - } - } - - /** - * Read back a workbook that was written out to a memory buffer with - * {@link #writeOut(Workbook)} or {@link #writeOutAndClose(Workbook)}. - * - * @param file the workbook file to read - * @return the read back workbook - * @throws IOException - */ - public static XSSFWorkbook readBack(ByteArrayOutputStream out) throws IOException { - InputStream is = new ByteArrayInputStream(out.toByteArray()); - out.close(); - try { - return new XSSFWorkbook(is); - } - finally { - is.close(); - } - } - - /** - * Write out and read back using a memory buffer to avoid disk I/O. - * If there is not enough memory to have two workbooks open at the same time, - * consider using: - * - * Workbook wb = new XSSFWorkbook(); - * String testName = "example"; - * - * - * File file = writeOutAndClose(wb, testName); - * // clear all references that would prevent the workbook from getting garbage collected - * wb = null; - * Workbook wbBack = readBackAndDelete(file); - * - * - * @param wb the workbook to write out - * @return the read back workbook - */ - public static R writeOutAndReadBack(R wb) { - Workbook result; - try { - result = readBack(writeOut(wb)); - } catch (IOException e) { - throw new RuntimeException(e); - } - @SuppressWarnings("unchecked") - R r = (R) result; - return r; - } - - /** - * Write out, close, and read back the workbook using a memory buffer to avoid disk I/O. - * - * @param wb the workbook to write out and close - * @return the read back workbook - */ - public static R writeOutCloseAndReadBack(R wb) { - Workbook result; - try { - result = readBack(writeOutAndClose(wb)); - } catch (IOException e) { - throw new RuntimeException(e); - } - @SuppressWarnings("unchecked") - R r = (R) result; - return r; - - } - - /** - * Writes the Workbook either into a file or into a byte array, depending on presence of - * the system property {@value #TEST_OUTPUT_DIR}, and reads it in a new instance of the Workbook back. - * If TEST_OUTPUT_DIR is set, the file will NOT be deleted at the end of this function. - * @param wb workbook to write - * @param testName file name to be used if writing into a file. The old file with the same name will be overridden. - * @return new instance read from the stream written by the wb parameter. - */ - - public static R writeOutAndReadBack(R wb, String testName) { - if (System.getProperty(TEST_OUTPUT_DIR) == null) { - return writeOutAndReadBack(wb); - } else { - try { - Workbook result = readBack(writeOut(wb, testName)); - @SuppressWarnings("unchecked") - R r = (R) result; - return r; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java deleted file mode 100644 index ad8470bab..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel; - -import junit.framework.TestCase; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.List; -import java.util.regex.Pattern; - -/** - * Tests for {@link org.apache.poi.xssf.eventusermodel.XSSFReader} - */ -public final class TestReadOnlySharedStringsTable extends TestCase { - private static POIDataSamples _ssTests = POIDataSamples.getSpreadSheetInstance(); - - public void testParse() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx")); - List parts = pkg.getPartsByName(Pattern.compile("/xl/sharedStrings.xml")); - assertEquals(1, parts.size()); - - SharedStringsTable stbl = new SharedStringsTable(parts.get(0), null); - ReadOnlySharedStringsTable rtbl = new ReadOnlySharedStringsTable(parts.get(0), null); - - assertEquals(stbl.getCount(), rtbl.getCount()); - assertEquals(stbl.getUniqueCount(), rtbl.getUniqueCount()); - - assertEquals(stbl.getItems().size(), stbl.getUniqueCount()); - assertEquals(rtbl.getItems().size(), rtbl.getUniqueCount()); - for(int i=0; i < stbl.getUniqueCount(); i++){ - CTRst i1 = stbl.getEntryAt(i); - String i2 = rtbl.getEntryAt(i); - assertEquals(i1.getT(), i2); - } - - } - - public void testEmptySSTOnPackageObtainedViaWorkbook() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(_ssTests.openResourceAsStream("noSharedStringTable.xlsx")); - OPCPackage pkg = wb.getPackage(); - assertEmptySST(pkg); - wb.close(); - } - - public void testEmptySSTOnPackageDirect() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("noSharedStringTable.xlsx")); - assertEmptySST(pkg); - } - - private void assertEmptySST(OPCPackage pkg) throws IOException, SAXException { - ReadOnlySharedStringsTable sst = new ReadOnlySharedStringsTable(pkg); - assertEquals(0, sst.getCount()); - assertEquals(0, sst.getUniqueCount()); - assertNull(sst.getItems()); // same state it's left in if fed a package which has no SST part. - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFReader.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFReader.java deleted file mode 100644 index 49742dc9d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFReader.java +++ /dev/null @@ -1,268 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.eventusermodel; - -import java.io.InputStream; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.apache.poi.xssf.usermodel.XSSFShape; -import org.apache.poi.xssf.usermodel.XSSFSimpleShape; - -import junit.framework.TestCase; - -/** - * Tests for {@link XSSFReader} - */ -public final class TestXSSFReader extends TestCase { - private static POIDataSamples _ssTests = POIDataSamples.getSpreadSheetInstance(); - - public void testGetBits() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx")); - - XSSFReader r = new XSSFReader(pkg); - - assertNotNull(r.getWorkbookData()); - assertNotNull(r.getSharedStringsData()); - assertNotNull(r.getStylesData()); - - assertNotNull(r.getSharedStringsTable()); - assertNotNull(r.getStylesTable()); - } - - public void testStyles() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx")); - - XSSFReader r = new XSSFReader(pkg); - - assertEquals(3, r.getStylesTable().getFonts().size()); - assertEquals(0, r.getStylesTable().getNumDataFormats()); - - // The Styles Table should have the themes associated with it too - assertNotNull(r.getStylesTable().getTheme()); - - // Check we get valid data for the two - assertNotNull(r.getStylesData()); - assertNotNull(r.getThemesData()); - } - - public void testStrings() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx")); - - XSSFReader r = new XSSFReader(pkg); - - assertEquals(11, r.getSharedStringsTable().getItems().size()); - assertEquals("Test spreadsheet", new XSSFRichTextString(r.getSharedStringsTable().getEntryAt(0)).toString()); - } - - public void testSheets() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx")); - - XSSFReader r = new XSSFReader(pkg); - byte[] data = new byte[4096]; - - // By r:id - assertNotNull(r.getSheet("rId2")); - int read = IOUtils.readFully(r.getSheet("rId2"), data); - assertEquals(974, read); - - // All - Iterator it = r.getSheetsData(); - - int count = 0; - while(it.hasNext()) { - count++; - InputStream inp = it.next(); - assertNotNull(inp); - read = IOUtils.readFully(inp, data); - inp.close(); - - assertTrue(read > 400); - assertTrue(read < 1500); - } - assertEquals(3, count); - } - - /** - * Check that the sheet iterator returns sheets in the logical order - * (as they are defined in the workbook.xml) - */ - public void testOrderOfSheets() throws Exception { - OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("reordered_sheets.xlsx")); - - XSSFReader r = new XSSFReader(pkg); - - String[] sheetNames = {"Sheet4", "Sheet2", "Sheet3", "Sheet1"}; - XSSFReader.SheetIterator it = (XSSFReader.SheetIterator)r.getSheetsData(); - - int count = 0; - while(it.hasNext()) { - InputStream inp = it.next(); - assertNotNull(inp); - inp.close(); - - assertEquals(sheetNames[count], it.getSheetName()); - count++; - } - assertEquals(4, count); - } - - public void testComments() throws Exception { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("comments.xlsx"); - XSSFReader r = new XSSFReader(pkg); - XSSFReader.SheetIterator it = (XSSFReader.SheetIterator)r.getSheetsData(); - - int count = 0; - while(it.hasNext()) { - count++; - InputStream inp = it.next(); - inp.close(); - - if(count == 1) { - assertNotNull(it.getSheetComments()); - CommentsTable ct = it.getSheetComments(); - assertEquals(1, ct.getNumberOfAuthors()); - assertEquals(3, ct.getNumberOfComments()); - } else { - assertNull(it.getSheetComments()); - } - } - assertEquals(3, count); - } - - /** - * Iterating over a workbook with chart sheets in it, using the - * XSSFReader method - * @throws Exception - */ - public void test50119() throws Exception { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("WithChartSheet.xlsx"); - XSSFReader r = new XSSFReader(pkg); - XSSFReader.SheetIterator it = (XSSFReader.SheetIterator)r.getSheetsData(); - - while(it.hasNext()) - { - InputStream stream = it.next(); - stream.close(); - } - } - - /** - * Test text extraction from text box using getShapes() - * - * @throws Exception - */ - public void testShapes() throws Exception { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("WithTextBox.xlsx"); - XSSFReader r = new XSSFReader(pkg); - XSSFReader.SheetIterator it = (XSSFReader.SheetIterator) r.getSheetsData(); - - String text = getShapesString(it); - assertTrue(text.contains("Line 1")); - assertTrue(text.contains("Line 2")); - assertTrue(text.contains("Line 3")); - } - - private String getShapesString(XSSFReader.SheetIterator it) { - StringBuilder sb = new StringBuilder(); - while (it.hasNext()) { - it.next(); - List shapes = it.getShapes(); - if (shapes != null) { - for (XSSFShape shape : shapes) { - if (shape instanceof XSSFSimpleShape) { - String t = ((XSSFSimpleShape) shape).getText(); - sb.append(t).append('\n'); - } - } - } - } - return sb.toString(); - } - - public void testBug57914() throws Exception { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("57914.xlsx"); - final XSSFReader r; - - // for now expect this to fail, when we fix 57699, this one should fail so we know we should adjust - // this test as well - try { - r = new XSSFReader(pkg); - fail("This will fail until bug 57699 is fixed"); - } catch (POIXMLException e) { - assertTrue("Had " + e, e.getMessage().contains("57699")); - return; - } - - XSSFReader.SheetIterator it = (XSSFReader.SheetIterator) r.getSheetsData(); - - String text = getShapesString(it); - assertTrue(text.contains("Line 1")); - assertTrue(text.contains("Line 2")); - assertTrue(text.contains("Line 3")); - } - - /** - * NPE from XSSFReader$SheetIterator. on XLSX files generated by - * the openpyxl library - */ - public void test58747() throws Exception { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("58747.xlsx"); - ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg); - assertNotNull(strings); - XSSFReader reader = new XSSFReader(pkg); - StylesTable styles = reader.getStylesTable(); - assertNotNull(styles); - - XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) reader.getSheetsData(); - assertEquals(true, iter.hasNext()); - iter.next(); - - assertEquals(false, iter.hasNext()); - assertEquals("Orders", iter.getSheetName()); - - pkg.close(); - } - - /** - * NPE when sheet has no relationship id in the workbook - * 60825 - */ - public void testSheetWithNoRelationshipId() throws Exception { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("60825.xlsx"); - ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg); - assertNotNull(strings); - XSSFReader reader = new XSSFReader(pkg); - StylesTable styles = reader.getStylesTable(); - assertNotNull(styles); - - XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) reader.getSheetsData(); - assertNotNull(iter.next()); - assertFalse(iter.hasNext()); - - pkg.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java deleted file mode 100644 index b223804e9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java +++ /dev/null @@ -1,347 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import junit.framework.TestCase; - -import org.apache.poi.POITextExtractor; -import org.apache.poi.POIXMLTextExtractor; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.xssf.XSSFTestDataSamples; - -/** - * Tests for {@link XSSFEventBasedExcelExtractor} - */ -public class TestXSSFEventBasedExcelExtractor extends TestCase { - protected XSSFEventBasedExcelExtractor getExtractor(String sampleName) throws Exception { - return new XSSFEventBasedExcelExtractor(XSSFTestDataSamples. - openSamplePackage(sampleName)); - } - - /** - * Get text out of the simple file - */ - public void testGetSimpleText() throws Exception { - // a very simple file - XSSFEventBasedExcelExtractor extractor = getExtractor("sample.xlsx"); - extractor.getText(); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check sheet names - assertTrue(text.startsWith("Sheet1")); - assertTrue(text.endsWith("Sheet3\n")); - - // Now without, will have text - extractor.setIncludeSheetNames(false); - text = extractor.getText(); - String CHUNK1 = - "Lorem\t111\n" + - "ipsum\t222\n" + - "dolor\t333\n" + - "sit\t444\n" + - "amet\t555\n" + - "consectetuer\t666\n" + - "adipiscing\t777\n" + - "elit\t888\n" + - "Nunc\t999\n"; - String CHUNK2 = - "The quick brown fox jumps over the lazy dog\n" + - "hello, xssf hello, xssf\n" + - "hello, xssf hello, xssf\n" + - "hello, xssf hello, xssf\n" + - "hello, xssf hello, xssf\n"; - assertEquals( - CHUNK1 + - "at\t4995\n" + - CHUNK2 - , text); - - // Now get formulas not their values - extractor.setFormulasNotResults(true); - text = extractor.getText(); - assertEquals( - CHUNK1 + - "at\tSUM(B1:B9)\n" + - CHUNK2, text); - - // With sheet names too - extractor.setIncludeSheetNames(true); - text = extractor.getText(); - assertEquals( - "Sheet1\n" + - CHUNK1 + - "at\tSUM(B1:B9)\n" + - "rich test\n" + - CHUNK2 + - "Sheet3\n" - , text); - - extractor.close(); - } - - public void testGetComplexText() throws Exception { - // A fairly complex file - XSSFEventBasedExcelExtractor extractor = getExtractor("AverageTaxRates.xlsx"); - extractor.getText(); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Might not have all formatting it should do! - assertTrue(text.startsWith( - "Avgtxfull\n" + - "(iii) AVERAGE TAX RATES ON ANNUAL" - )); - - extractor.close(); - } - - public void testInlineStrings() throws Exception { - XSSFEventBasedExcelExtractor extractor = getExtractor("InlineStrings.xlsx"); - extractor.setFormulasNotResults(true); - String text = extractor.getText(); - - // Numbers - assertTrue("Unable to find expected word in text\n" + text, text.contains("43")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("22")); - - // Strings - assertTrue("Unable to find expected word in text\n" + text, text.contains("ABCDE")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("Long Text")); - - // Inline Strings - assertTrue("Unable to find expected word in text\n" + text, text.contains("1st Inline String")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("And More")); - - // Formulas - assertTrue("Unable to find expected word in text\n" + text, text.contains("A2")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("A5-A$2")); - - extractor.close(); - } - - /** - * Test that we return pretty much the same as - * ExcelExtractor does, when we're both passed - * the same file, just saved as xls and xlsx - */ - public void testComparedToOLE2() throws Exception { - // A fairly simple file - ooxml - XSSFEventBasedExcelExtractor ooxmlExtractor = getExtractor("SampleSS.xlsx"); - - ExcelExtractor ole2Extractor = - new ExcelExtractor(HSSFTestDataSamples.openSampleWorkbook("SampleSS.xls")); - - POITextExtractor[] extractors = - new POITextExtractor[] { ooxmlExtractor, ole2Extractor }; - for (POITextExtractor extractor : extractors) { - String text = extractor.getText().replaceAll("[\r\t]", ""); - assertTrue(text.startsWith("First Sheet\nTest spreadsheet\n2nd row2nd row 2nd column\n")); - Pattern pattern = Pattern.compile(".*13(\\.0+)?\\s+Sheet3.*", Pattern.DOTALL); - Matcher m = pattern.matcher(text); - assertTrue(m.matches()); - } - - ole2Extractor.close(); - ooxmlExtractor.close(); - } - - /** - * Test text extraction from text box using getShapes() - * @throws Exception - */ - public void testShapes() throws Exception{ - XSSFEventBasedExcelExtractor ooxmlExtractor = getExtractor("WithTextBox.xlsx"); - - try { - String text = ooxmlExtractor.getText(); - - assertTrue(text.indexOf("Line 1") > -1); - assertTrue(text.indexOf("Line 2") > -1); - assertTrue(text.indexOf("Line 3") > -1); - } finally { - ooxmlExtractor.close(); - } - } - - /** - * Test that we return the same output for unstyled numbers as the - * non-event-based XSSFExcelExtractor. - */ - public void testUnstyledNumbersComparedToNonEventBasedExtractor() - throws Exception { - - String expectedOutput = "Sheet1\n99.99\n"; - - XSSFExcelExtractor extractor = new XSSFExcelExtractor( - XSSFTestDataSamples.openSampleWorkbook("56011.xlsx")); - try { - assertEquals(expectedOutput, extractor.getText().replace(",", ".")); - } finally { - extractor.close(); - } - - XSSFEventBasedExcelExtractor fixture = - new XSSFEventBasedExcelExtractor( - XSSFTestDataSamples.openSamplePackage("56011.xlsx")); - try { - assertEquals(expectedOutput, fixture.getText().replace(",", ".")); - } finally { - fixture.close(); - } - } - - /** - * Test that we return the same output headers and footers as the - * non-event-based XSSFExcelExtractor. - */ - public void testHeadersAndFootersComparedToNonEventBasedExtractor() - throws Exception { - - String expectedOutputWithHeadersAndFooters = - "Sheet1\n" + - "&\"Calibri,Regular\"&K000000top left\t&\"Calibri,Regular\"&K000000top center\t&\"Calibri,Regular\"&K000000top right\n" + - "abc\t123\n" + - "&\"Calibri,Regular\"&K000000bottom left\t&\"Calibri,Regular\"&K000000bottom center\t&\"Calibri,Regular\"&K000000bottom right\n"; - - String expectedOutputWithoutHeadersAndFooters = - "Sheet1\n" + - "abc\t123\n"; - - XSSFExcelExtractor extractor = new XSSFExcelExtractor( - XSSFTestDataSamples.openSampleWorkbook("headerFooterTest.xlsx")); - try { - assertEquals(expectedOutputWithHeadersAndFooters, extractor.getText()); - extractor.setIncludeHeadersFooters(false); - assertEquals(expectedOutputWithoutHeadersAndFooters, extractor.getText()); - } finally { - extractor.close(); - } - - XSSFEventBasedExcelExtractor fixture = - new XSSFEventBasedExcelExtractor( - XSSFTestDataSamples.openSamplePackage("headerFooterTest.xlsx")); - try { - assertEquals(expectedOutputWithHeadersAndFooters, fixture.getText()); - fixture.setIncludeHeadersFooters(false); - assertEquals(expectedOutputWithoutHeadersAndFooters, fixture.getText()); - } finally { - fixture.close(); - } - } - - /** - * Test that XSSFEventBasedExcelExtractor outputs comments when specified. - * The output will contain two improvements over the output from - * XSSFExcelExtractor in that (1) comments from empty cells will be - * outputted, and (2) the author will not be outputted twice. - *

        - * This test will need to be modified if these improvements are ported to - * XSSFExcelExtractor. - */ - public void testCommentsComparedToNonEventBasedExtractor() - throws Exception { - - String expectedOutputWithoutComments = - "Sheet1\n" + - "\n" + - "abc\n" + - "\n" + - "123\n" + - "\n" + - "\n" + - "\n"; - - String nonEventBasedExtractorOutputWithComments = - "Sheet1\n" + - "\n" + - "abc Comment by Shaun Kalley: Shaun Kalley: Comment A2\n" + - "\n" + - "123 Comment by Shaun Kalley: Shaun Kalley: Comment B4\n" + - "\n" + - "\n" + - "\n"; - - String eventBasedExtractorOutputWithComments = - "Sheet1\n" + - "Comment by Shaun Kalley: Comment A1\tComment by Shaun Kalley: Comment B1\n" + - "abc Comment by Shaun Kalley: Comment A2\tComment by Shaun Kalley: Comment B2\n" + - "Comment by Shaun Kalley: Comment A3\tComment by Shaun Kalley: Comment B3\n" + - "Comment by Shaun Kalley: Comment A4\t123 Comment by Shaun Kalley: Comment B4\n" + - "Comment by Shaun Kalley: Comment A5\tComment by Shaun Kalley: Comment B5\n" + - "Comment by Shaun Kalley: Comment A7\tComment by Shaun Kalley: Comment B7\n" + - "Comment by Shaun Kalley: Comment A8\tComment by Shaun Kalley: Comment B8\n"; - - XSSFExcelExtractor extractor = new XSSFExcelExtractor( - XSSFTestDataSamples.openSampleWorkbook("commentTest.xlsx")); - try { - assertEquals(expectedOutputWithoutComments, extractor.getText()); - extractor.setIncludeCellComments(true); - assertEquals(nonEventBasedExtractorOutputWithComments, extractor.getText()); - } finally { - extractor.close(); - } - - XSSFEventBasedExcelExtractor fixture = - new XSSFEventBasedExcelExtractor( - XSSFTestDataSamples.openSamplePackage("commentTest.xlsx")); - try { - assertEquals(expectedOutputWithoutComments, fixture.getText()); - fixture.setIncludeCellComments(true); - assertEquals(eventBasedExtractorOutputWithComments, fixture.getText()); - } finally { - fixture.close(); - } - } - - public void testFile56278_normal() throws Exception { - // first with normal Text Extractor - POIXMLTextExtractor extractor = new XSSFExcelExtractor( - XSSFTestDataSamples.openSampleWorkbook("56278.xlsx")); - try { - assertNotNull(extractor.getText()); - } finally { - extractor.close(); - } - } - - public void testFile56278_event() throws Exception { - // then with event based one - POIXMLTextExtractor extractor = getExtractor("56278.xlsx"); - try { - assertNotNull(extractor.getText()); - } finally { - extractor.close(); - } - } - - public void test59021() throws Exception { - XSSFEventBasedExcelExtractor ex = - new XSSFEventBasedExcelExtractor( - XSSFTestDataSamples.openSamplePackage("59021.xlsx")); - String text = ex.getText(); - assertTrue("can't find Abhkazia", text.contains("Abkhazia - Fixed")); - assertTrue("can't find 10/02/2016", text.contains("10/02/2016")); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractorUsingFactory.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractorUsingFactory.java deleted file mode 100644 index 34478a909..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractorUsingFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.hssf.HSSFTestDataSamples; - - -public class TestXSSFEventBasedExcelExtractorUsingFactory extends TestXSSFEventBasedExcelExtractor { - @Override - protected final XSSFEventBasedExcelExtractor getExtractor(String sampleName) throws Exception { - ExtractorFactory.setAllThreadsPreferEventExtractors(true); - return (XSSFEventBasedExcelExtractor) ExtractorFactory.createExtractor(HSSFTestDataSamples.openSampleFileStream(sampleName)); - } - - @Override - public void tearDown() { - // reset setting to not affect other tests - ExtractorFactory.setAllThreadsPreferEventExtractors(null); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExcelExtractor.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExcelExtractor.java deleted file mode 100644 index 89a4e4047..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExcelExtractor.java +++ /dev/null @@ -1,229 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import junit.framework.TestCase; - -import org.apache.poi.POITextExtractor; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.xssf.XSSFTestDataSamples; - -/** - * Tests for {@link XSSFExcelExtractor} - */ -public class TestXSSFExcelExtractor extends TestCase { - protected XSSFExcelExtractor getExtractor(String sampleName) { - return new XSSFExcelExtractor(XSSFTestDataSamples.openSampleWorkbook(sampleName)); - } - - /** - * Get text out of the simple file - * @throws IOException - */ - public void testGetSimpleText() throws IOException { - // a very simple file - XSSFExcelExtractor extractor = getExtractor("sample.xlsx"); - extractor.getText(); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check sheet names - assertTrue(text.startsWith("Sheet1")); - assertTrue(text.endsWith("Sheet3\n")); - - // Now without, will have text - extractor.setIncludeSheetNames(false); - text = extractor.getText(); - String CHUNK1 = - "Lorem\t111\n" + - "ipsum\t222\n" + - "dolor\t333\n" + - "sit\t444\n" + - "amet\t555\n" + - "consectetuer\t666\n" + - "adipiscing\t777\n" + - "elit\t888\n" + - "Nunc\t999\n"; - String CHUNK2 = - "The quick brown fox jumps over the lazy dog\n" + - "hello, xssf hello, xssf\n" + - "hello, xssf hello, xssf\n" + - "hello, xssf hello, xssf\n" + - "hello, xssf hello, xssf\n"; - assertEquals( - CHUNK1 + - "at\t4995\n" + - CHUNK2 - , text); - - // Now get formulas not their values - extractor.setFormulasNotResults(true); - text = extractor.getText(); - assertEquals( - CHUNK1 + - "at\tSUM(B1:B9)\n" + - CHUNK2, text); - - // With sheet names too - extractor.setIncludeSheetNames(true); - text = extractor.getText(); - assertEquals( - "Sheet1\n" + - CHUNK1 + - "at\tSUM(B1:B9)\n" + - "rich test\n" + - CHUNK2 + - "Sheet3\n" - , text); - - extractor.close(); - } - - public void testGetComplexText() throws IOException { - // A fairly complex file - XSSFExcelExtractor extractor = getExtractor("AverageTaxRates.xlsx"); - extractor.getText(); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Might not have all formatting it should do! - // TODO decide if we should really have the "null" in there - assertTrue(text.startsWith( - "Avgtxfull\n" + - "null\t(iii) AVERAGE TAX RATES ON ANNUAL" - )); - - extractor.close(); - } - - /** - * Test that we return pretty much the same as - * ExcelExtractor does, when we're both passed - * the same file, just saved as xls and xlsx - * @throws IOException - */ - public void testComparedToOLE2() throws IOException { - // A fairly simple file - ooxml - XSSFExcelExtractor ooxmlExtractor = getExtractor("SampleSS.xlsx"); - - ExcelExtractor ole2Extractor = - new ExcelExtractor(HSSFTestDataSamples.openSampleWorkbook("SampleSS.xls")); - - POITextExtractor[] extractors = - new POITextExtractor[] { ooxmlExtractor, ole2Extractor }; - - for (POITextExtractor extractor : extractors) { - String text = extractor.getText().replaceAll("[\r\t]", ""); - assertTrue(text.startsWith("First Sheet\nTest spreadsheet\n2nd row2nd row 2nd column\n")); - Pattern pattern = Pattern.compile(".*13(\\.0+)?\\s+Sheet3.*", Pattern.DOTALL); - Matcher m = pattern.matcher(text); - assertTrue(m.matches()); - } - - ole2Extractor.close(); - ooxmlExtractor.close(); - } - - /** - * From bug #45540 - * @throws IOException - */ - public void testHeaderFooter() throws IOException { - String[] files = new String[] { - "45540_classic_Header.xlsx", "45540_form_Header.xlsx", - "45540_classic_Footer.xlsx", "45540_form_Footer.xlsx", - }; - for(String sampleName : files) { - XSSFExcelExtractor extractor = getExtractor(sampleName); - String text = extractor.getText(); - - assertTrue("Unable to find expected word in text from " + sampleName + "\n" + text, text.contains("testdoc")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("test phrase")); - - extractor.close(); - } - } - - /** - * From bug #45544 - * @throws IOException - */ - public void testComments() throws IOException { - XSSFExcelExtractor extractor = getExtractor("45544.xlsx"); - String text = extractor.getText(); - - // No comments there yet - assertFalse("Unable to find expected word in text\n" + text, text.contains("testdoc")); - assertFalse("Unable to find expected word in text\n" + text, text.contains("test phrase")); - - // Turn on comment extraction, will then be - extractor.setIncludeCellComments(true); - text = extractor.getText(); - assertTrue("Unable to find expected word in text\n" + text, text.contains("testdoc")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("test phrase")); - - extractor.close(); - } - - public void testInlineStrings() throws IOException { - XSSFExcelExtractor extractor = getExtractor("InlineStrings.xlsx"); - extractor.setFormulasNotResults(true); - String text = extractor.getText(); - - // Numbers - assertTrue("Unable to find expected word in text\n" + text, text.contains("43")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("22")); - - // Strings - assertTrue("Unable to find expected word in text\n" + text, text.contains("ABCDE")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("Long Text")); - - // Inline Strings - assertTrue("Unable to find expected word in text\n" + text, text.contains("1st Inline String")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("And More")); - - // Formulas - assertTrue("Unable to find expected word in text\n" + text, text.contains("A2")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("A5-A$2")); - - extractor.close(); - } - /** - * Simple test for text box text - * @throws IOException - */ - public void testTextBoxes() throws IOException { - XSSFExcelExtractor extractor = getExtractor("WithTextBox.xlsx"); - try { - extractor.setFormulasNotResults(true); - String text = extractor.getText(); - assertTrue(text.indexOf("Line 1") > -1); - assertTrue(text.indexOf("Line 2") > -1); - assertTrue(text.indexOf("Line 3") > -1); - } finally { - extractor.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExcelExtractorUsingFactory.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExcelExtractorUsingFactory.java deleted file mode 100644 index 57983be00..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExcelExtractorUsingFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.hssf.HSSFTestDataSamples; - -/** - * Tests for {@link XSSFExcelExtractor} - */ -public final class TestXSSFExcelExtractorUsingFactory extends TestXSSFExcelExtractor { - @Override - protected final XSSFExcelExtractor getExtractor(String sampleName) { - ExtractorFactory.setAllThreadsPreferEventExtractors(false); - ExtractorFactory.setThreadPrefersEventExtractors(false); - try { - return (XSSFExcelExtractor) ExtractorFactory.createExtractor(HSSFTestDataSamples.openSampleFileStream(sampleName)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public void tearDown() { - // reset setting to not affect other tests - ExtractorFactory.setAllThreadsPreferEventExtractors(null); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java deleted file mode 100644 index 783b7a0b2..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java +++ /dev/null @@ -1,637 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import junit.framework.TestCase; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.util.XMLHelper; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.MapInfo; -import org.apache.poi.xssf.usermodel.XSSFMap; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Collection; -import java.util.Date; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author Roberto Manicardi - */ -public final class TestXSSFExportToXML extends TestCase { - - public void testExportToXML() throws Exception { - - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xml = os.toString("UTF-8"); - - assertNotNull(xml); - assertFalse(xml.equals("")); - - String docente = xml.split("")[1].split("")[0].trim(); - String nome = xml.split("")[1].split("")[0].trim(); - String tutor = xml.split("")[1].split("")[0].trim(); - String cdl = xml.split("")[1].split("")[0].trim(); - String durata = xml.split("")[1].split("")[0].trim(); - String argomento = xml.split("")[1].split("")[0].trim(); - String progetto = xml.split("")[1].split("")[0].trim(); - String crediti = xml.split("")[1].split("")[0].trim(); - - assertEquals("ro", docente); - assertEquals("ro", nome); - assertEquals("ds", tutor); - assertEquals("gs", cdl); - assertEquals("g", durata); - assertEquals("gvvv", argomento); - assertEquals("aaaa", progetto); - assertEquals("aa", crediti); - - parseXML(xml); - - found = true; - } - assertTrue(found); - } - - public void testExportToXMLInverseOrder() throws Exception { - - XSSFWorkbook wb = XSSFTestDataSamples - .openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xml = os.toString("UTF-8"); - - assertNotNull(xml); - assertFalse(xml.equals("")); - - String docente = xml.split("")[1].split("")[0].trim(); - String nome = xml.split("")[1].split("")[0].trim(); - String tutor = xml.split("")[1].split("")[0].trim(); - String cdl = xml.split("")[1].split("")[0].trim(); - String durata = xml.split("")[1].split("")[0].trim(); - String argomento = xml.split("")[1].split("")[0].trim(); - String progetto = xml.split("")[1].split("")[0].trim(); - String crediti = xml.split("")[1].split("")[0].trim(); - - assertEquals("aa", nome); - assertEquals("aaaa", docente); - assertEquals("gvvv", tutor); - assertEquals("g", cdl); - assertEquals("gs", durata); - assertEquals("ds", argomento); - assertEquals("ro", progetto); - assertEquals("ro", crediti); - - parseXML(xml); - - found = true; - } - assertTrue(found); - } - - public void testXPathOrdering() { - - XSSFWorkbook wb = XSSFTestDataSamples - .openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (p instanceof MapInfo) { - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - XSSFExportToXml exporter = new XSSFExportToXml(map); - - assertEquals(1, exporter.compare("/CORSO/DOCENTE", "/CORSO/NOME")); - assertEquals(-1, exporter.compare("/CORSO/NOME", "/CORSO/DOCENTE")); - } - - found = true; - } - assertTrue(found); - } - - public void testMultiTable() throws Exception { - - XSSFWorkbook wb = XSSFTestDataSamples - .openSampleWorkbook("CustomXMLMappings-complex-type.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (p instanceof MapInfo) { - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(2); - - assertNotNull(map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xml = os.toString("UTF-8"); - - assertNotNull(xml); - - String[] regexConditions = { - "", - "", - "", - "DataBinding", - "Map Append=\"false\" AutoFit=\"false\" ID=\"1\"", - "Map Append=\"false\" AutoFit=\"false\" ID=\"5\"", - }; - - for (String condition : regexConditions) { - Pattern pattern = Pattern.compile(condition); - Matcher matcher = pattern.matcher(xml); - assertTrue(matcher.find()); - } - } - - found = true; - } - assertTrue(found); - } - - public void testExportToXMLSingleAttributeNamespace() throws Exception { - // TODO: Fails, but I don't know if it is ok or not... - -// XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMapping-singleattributenamespace.xlsx"); -// -// for (XSSFMap map : wb.getCustomXMLMappings()) { -// XSSFExportToXml exporter = new XSSFExportToXml(map); -// -// ByteArrayOutputStream os = new ByteArrayOutputStream(); -// exporter.exportToXML(os, true); -// } - } - - public void test55850ComplexXmlExport() throws Exception { - - XSSFWorkbook wb = XSSFTestDataSamples - .openSampleWorkbook("55850.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(2); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - String a = xmlData.split("")[1].split("")[0].trim(); - String b = a.split("")[1].split("")[0].trim(); - String c = b.split("")[1].split("")[0].trim(); - String d = c.split("")[1].split("")[0].trim(); - String e = d.split("")[1].split("")[0].trim(); - - String euro = e.split("")[1].split("")[0].trim(); - String chf = e.split("")[1].split("")[0].trim(); - - assertEquals("15", euro); - assertEquals("19", chf); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testFormulaCells_Bugzilla_55927() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55927.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - assertEquals("2012-01-13", xmlData.split("")[1].split("")[0].trim()); - assertEquals("2012-02-16", xmlData.split("")[1].split("")[0].trim()); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testFormulaCells_Bugzilla_55926() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55926.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - String a = xmlData.split("")[1].split("")[0].trim(); - String doubleValue = a.split("")[1].split("")[0].trim(); - String stringValue = a.split("")[1].split("")[0].trim(); - - assertEquals("Hello World", stringValue); - assertEquals("5.1", doubleValue); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testXmlExportIgnoresEmptyCells_Bugzilla_55924() throws Exception { - - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55924.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - String a = xmlData.split("")[1].split("")[0].trim(); - String euro = a.split("")[1].split("")[0].trim(); - assertEquals("1",euro); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testXmlExportSchemaWithXSAllTag_Bugzilla_56169() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56169.xlsx"); - - for (XSSFMap map : wb.getCustomXMLMappings()) { - XSSFExportToXml exporter = new XSSFExportToXml(map); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertTrue(!xmlData.equals("")); - - String a = xmlData.split("")[1].split("")[0].trim(); - String a_b = a.split("")[1].split("")[0].trim(); - String a_b_c = a_b.split("")[1].split("")[0].trim(); - String a_b_c_e = a_b_c.split("")[1].split("")[0].trim(); - String a_b_c_e_euro = a_b_c_e.split("")[1].split("")[0].trim(); - String a_b_c_e_chf = a_b_c_e.split("")[1].split("")[0].trim(); - - assertEquals("1", a_b_c_e_euro); - assertEquals("2", a_b_c_e_chf); - - String a_b_d = a_b.split("")[1].split("")[0].trim(); - String a_b_d_e = a_b_d.split("")[1].split("")[0].trim(); - - String a_b_d_e_euro = a_b_d_e.split("")[1].split("")[0].trim(); - String a_b_d_e_chf = a_b_d_e.split("")[1].split("")[0].trim(); - - assertEquals("3", a_b_d_e_euro); - assertEquals("4", a_b_d_e_chf); - } - } - - public void testXmlExportCompare_Bug_55923() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(4); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - assertEquals(0, exporter.compare("", "")); - assertEquals(0, exporter.compare("/", "/")); - assertEquals(0, exporter.compare("//", "//")); - assertEquals(0, exporter.compare("/a/", "/b/")); - - assertEquals(-1, exporter.compare("/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:EUR", - "/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:CHF")); - - found = true; - } - assertTrue(found); - } - - public void testXmlExportSchemaOrderingBug_Bugzilla_55923() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(4); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - String a = xmlData.split("")[1].split("")[0].trim(); - String a_b = a.split("")[1].split("")[0].trim(); - String a_b_c = a_b.split("")[1].split("")[0].trim(); - String a_b_c_e = a_b_c.split("")[1].split("")[0].trim(); - String a_b_c_e_euro = a_b_c_e.split("")[1].split("")[0].trim(); - String a_b_c_e_chf = a_b_c_e.split("")[1].split("")[0].trim(); - - assertEquals("1",a_b_c_e_euro); - assertEquals("2",a_b_c_e_chf); - - String a_b_d = a_b.split("")[1].split("")[0].trim(); - String a_b_d_e = a_b_d.split("")[1].split("")[0].trim(); - - String a_b_d_e_euro = a_b_d_e.split("")[1].split("")[0].trim(); - String a_b_d_e_chf = a_b_d_e.split("")[1].split("")[0].trim(); - - assertEquals("3",a_b_d_e_euro); - assertEquals("4",a_b_d_e_chf); - - found = true; - } - assertTrue(found); - } - - private void parseXML(String xmlData) throws IOException, SAXException, ParserConfigurationException { - DocumentBuilderFactory docBuilderFactory = XMLHelper.getDocumentBuilderFactory(); - docBuilderFactory.setNamespaceAware(true); - docBuilderFactory.setValidating(false); - DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); - docBuilder.setEntityResolver(new DummyEntityResolver()); - - docBuilder.parse(new ByteArrayInputStream(xmlData.getBytes("UTF-8"))); - } - - private static class DummyEntityResolver implements EntityResolver - { - @Override - public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException - { - return null; - } - } - - public void testExportDataTypes() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx"); - - Sheet sheet = wb.getSheetAt(0); - Row row = sheet.getRow(0); - - Cell cString = row.createCell(0); - cString.setCellValue("somestring"); - cString.setCellType(CellType.STRING); - - Cell cBoolean = row.createCell(1); - cBoolean.setCellValue(true); - cBoolean.setCellType(CellType.BOOLEAN); - - Cell cError = row.createCell(2); - cError.setCellType(CellType.ERROR); - - Cell cFormulaString = row.createCell(3); - cFormulaString.setCellFormula("A1"); - cFormulaString.setCellType(CellType.FORMULA); - - Cell cFormulaNumeric = row.createCell(4); - cFormulaNumeric.setCellFormula("F1"); - cFormulaNumeric.setCellType(CellType.FORMULA); - - Cell cNumeric = row.createCell(5); - cNumeric.setCellValue(1.2); - cNumeric.setCellType(CellType.NUMERIC); - - Cell cDate = row.createCell(6); - cDate.setCellValue(new Date()); - cDate.setCellType(CellType.NUMERIC); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(4); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testValidateFalse() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(4); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, false); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testRefElementsInXmlSchema_Bugzilla_56730() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56730.xlsx"); - - boolean found = false; - for (POIXMLDocumentPart p : wb.getRelations()) { - - if (!(p instanceof MapInfo)) { - continue; - } - MapInfo mapInfo = (MapInfo) p; - - XSSFMap map = mapInfo.getXSSFMapById(1); - - assertNotNull("XSSFMap is null", map); - - XSSFExportToXml exporter = new XSSFExportToXml(map); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, true); - String xmlData = os.toString("UTF-8"); - - assertNotNull(xmlData); - assertFalse(xmlData.equals("")); - - assertEquals("2014-12-31", xmlData.split("")[1].split("")[0].trim()); - assertEquals("12.5", xmlData.split("")[1].split("")[0].trim()); - - parseXML(xmlData); - - found = true; - } - assertTrue(found); - } - - public void testBug59026() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("59026.xlsx"); - - Collection mappings = wb.getCustomXMLMappings(); - assertTrue(mappings.size() > 0); - for (XSSFMap map : mappings) { - XSSFExportToXml exporter = new XSSFExportToXml(map); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - exporter.exportToXML(os, false); - assertNotNull(os.toString("UTF-8")); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFImportFromXML.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFImportFromXML.java deleted file mode 100644 index 626e104a0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFImportFromXML.java +++ /dev/null @@ -1,241 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.text.DateFormatSymbols; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import javax.xml.xpath.XPathExpressionException; - -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFMap; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; -import org.xml.sax.SAXException; - -public class TestXSSFImportFromXML { - - @Test - public void testImportFromXML() throws IOException, XPathExpressionException, SAXException{ - - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx"); - try { - String name = "name"; - String teacher = "teacher"; - String tutor = "tutor"; - String cdl = "cdl"; - String duration = "duration"; - String topic = "topic"; - String project = "project"; - String credits = "credits"; - - String testXML = ""+ - ""+name+""+ - ""+teacher+""+ - ""+tutor+""+ - ""+cdl+""+ - ""+duration+""+ - ""+topic+""+ - ""+project+""+ - ""+credits+""+ - "\u0000"; - - XSSFMap map = wb.getMapInfo().getXSSFMapByName("CORSO_mapping"); - assertNotNull(map); - XSSFImportFromXML importer = new XSSFImportFromXML(map); - - importer.importFromXML(testXML); - - XSSFSheet sheet=wb.getSheetAt(0); - - XSSFRow row = sheet.getRow(0); - assertTrue(row.getCell(0).getStringCellValue().equals(name)); - assertTrue(row.getCell(1).getStringCellValue().equals(teacher)); - assertTrue(row.getCell(2).getStringCellValue().equals(tutor)); - assertTrue(row.getCell(3).getStringCellValue().equals(cdl)); - assertTrue(row.getCell(4).getStringCellValue().equals(duration)); - assertTrue(row.getCell(5).getStringCellValue().equals(topic)); - assertTrue(row.getCell(6).getStringCellValue().equals(project)); - assertTrue(row.getCell(7).getStringCellValue().equals(credits)); - } finally { - wb.close(); - } - } - - @Test - public void testMultiTable() throws IOException, XPathExpressionException, SAXException{ - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx"); - try { - String cellC6 = "c6"; - String cellC7 = "c7"; - String cellC8 = "c8"; - String cellC9 = "c9"; - - String testXML = "" + - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - ""+ - "\u0000"; - - XSSFMap map = wb.getMapInfo().getXSSFMapByName("MapInfo_mapping"); - assertNotNull(map); - XSSFImportFromXML importer = new XSSFImportFromXML(map); - - importer.importFromXML(testXML); - - //Check for Schema element - XSSFSheet sheet=wb.getSheetAt(1); - - assertEquals(cellC6,sheet.getRow(5).getCell(2).getStringCellValue()); - assertEquals(cellC7,sheet.getRow(6).getCell(2).getStringCellValue()); - assertEquals(cellC8,sheet.getRow(7).getCell(2).getStringCellValue()); - assertEquals(cellC9,sheet.getRow(8).getCell(2).getStringCellValue()); - } finally { - wb.close(); - } - } - - - @Test - public void testSingleAttributeCellWithNamespace() throws IOException, XPathExpressionException, SAXException{ - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMapping-singleattributenamespace.xlsx"); - try { - int id = 1; - String displayName = "dispName"; - String ref="19"; - int count = 21; - - String testXML = ""+ - ""+ - ""+ - "\u0000"; - XSSFMap map = wb.getMapInfo().getXSSFMapByName("table_mapping"); - assertNotNull(map); - XSSFImportFromXML importer = new XSSFImportFromXML(map); - importer.importFromXML(testXML); - - //Check for Schema element - XSSFSheet sheet=wb.getSheetAt(0); - - assertEquals(new Double(id), sheet.getRow(28).getCell(1).getNumericCellValue(), 0); - assertEquals(displayName, sheet.getRow(11).getCell(5).getStringCellValue()); - assertEquals(ref, sheet.getRow(14).getCell(7).getStringCellValue()); - assertEquals(new Double(count), sheet.getRow(18).getCell(3).getNumericCellValue(), 0); - } finally { - wb.close(); - } - } - - @Test - public void testOptionalFields_Bugzilla_55864() throws IOException, XPathExpressionException, SAXException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55864.xlsx"); - try { - String testXML = "" + - "" + - "" + - "Albert" + - "Einstein" + - "1879-03-14" + - "" + - ""; - - XSSFMap map = wb.getMapInfo().getXSSFMapByName("PersonInfoRoot_Map"); - assertNotNull(map); - XSSFImportFromXML importer = new XSSFImportFromXML(map); - - importer.importFromXML(testXML); - - XSSFSheet sheet=wb.getSheetAt(0); - - XSSFRow rowHeadings = sheet.getRow(0); - XSSFRow rowData = sheet.getRow(1); - - assertEquals("FirstName", rowHeadings.getCell(0).getStringCellValue()); - assertEquals("Albert", rowData.getCell(0).getStringCellValue()); - - assertEquals("LastName", rowHeadings.getCell(1).getStringCellValue()); - assertEquals("Einstein", rowData.getCell(1).getStringCellValue()); - - assertEquals("BirthDate", rowHeadings.getCell(2).getStringCellValue()); - assertEquals("1879-03-14", rowData.getCell(2).getStringCellValue()); - - // Value for OptionalRating is declared optional (minOccurs=0) in 55864.xlsx - assertEquals("OptionalRating", rowHeadings.getCell(3).getStringCellValue()); - assertNull("", rowData.getCell(3)); - } finally { - wb.close(); - } - } - - @Test - public void testOptionalFields_Bugzilla_57890() throws IOException, ParseException, XPathExpressionException, SAXException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57890.xlsx"); - - String testXML = "" + "" - + "" + "" + Integer.MIN_VALUE + "" + "12345" - + "1.0000123" + "1991-03-14" + "" + ""; - - XSSFMap map = wb.getMapInfo().getXSSFMapByName("TestInfoRoot_Map"); - assertNotNull(map); - XSSFImportFromXML importer = new XSSFImportFromXML(map); - - importer.importFromXML(testXML); - - XSSFSheet sheet = wb.getSheetAt(0); - - XSSFRow rowHeadings = sheet.getRow(0); - XSSFRow rowData = sheet.getRow(1); - - assertEquals("Date", rowHeadings.getCell(0).getStringCellValue()); - Date date = new SimpleDateFormat("yyyy-MM-dd", DateFormatSymbols.getInstance(Locale.ROOT)).parse("1991-3-14"); - assertEquals(date, rowData.getCell(0).getDateCellValue()); - - assertEquals("Amount Int", rowHeadings.getCell(1).getStringCellValue()); - assertEquals(new Double(Integer.MIN_VALUE), rowData.getCell(1).getNumericCellValue(), 0); - - assertEquals("Amount Double", rowHeadings.getCell(2).getStringCellValue()); - assertEquals(1.0000123, rowData.getCell(2).getNumericCellValue(), 0); - - assertEquals("Amount UnsignedInt", rowHeadings.getCell(3).getStringCellValue()); - assertEquals(new Double(12345), rowData.getCell(3).getNumericCellValue(), 0); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/io/TestLoadSaveXSSF.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/io/TestLoadSaveXSSF.java deleted file mode 100644 index 366d853f7..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/io/TestLoadSaveXSSF.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io; - -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFPictureData; -import org.apache.poi.POIDataSamples; - - -public class TestLoadSaveXSSF extends TestCase { - private static final POIDataSamples _ssSampels = POIDataSamples.getSpreadSheetInstance(); - - public void testLoadSample() throws Exception { - XSSFWorkbook workbook = new XSSFWorkbook(_ssSampels.openResourceAsStream("sample.xlsx")); - assertEquals(3, workbook.getNumberOfSheets()); - assertEquals("Sheet1", workbook.getSheetName(0)); - Sheet sheet = workbook.getSheetAt(0); - Row row = sheet.getRow(0); - Cell cell = row.getCell((short) 1); - assertNotNull(cell); - assertEquals(111.0, cell.getNumericCellValue(), 0.0); - cell = row.getCell((short) 0); - assertEquals("Lorem", cell.getRichStringCellValue().getString()); - } - - // TODO filename string hard coded in XSSFWorkbook constructor in order to make ant test-ooxml target be successful. - public void testLoadStyles() throws Exception { - XSSFWorkbook workbook = new XSSFWorkbook(_ssSampels.openResourceAsStream("styles.xlsx")); - Sheet sheet = workbook.getSheetAt(0); - Row row = sheet.getRow(0); - Cell cell = row.getCell((short) 0); - CellStyle style = cell.getCellStyle(); - // assertNotNull(style); - } - - // TODO filename string hard coded in XSSFWorkbook constructor in order to make ant test-ooxml target be successful. - public void testLoadPictures() throws Exception { - XSSFWorkbook workbook = new XSSFWorkbook(_ssSampels.openResourceAsStream("picture.xlsx")); - List pictures = workbook.getAllPictures(); - assertEquals(1, pictures.size()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestCalculationChain.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestCalculationChain.java deleted file mode 100644 index d2fd60f3e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestCalculationChain.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell; - -import junit.framework.TestCase; - - -public final class TestCalculationChain extends TestCase { - - public void test46535() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("46535.xlsx"); - - CalculationChain chain = wb.getCalculationChain(); - //the bean holding the reference to the formula to be deleted - CTCalcCell c = chain.getCTCalcChain().getCArray(0); - int cnt = chain.getCTCalcChain().sizeOfCArray(); - assertEquals(10, c.getI()); - assertEquals("E1", c.getR()); - - XSSFSheet sheet = wb.getSheet("Test"); - XSSFCell cell = sheet.getRow(0).getCell(4); - - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - cell.setCellFormula(null); - - //the count of items is less by one - c = chain.getCTCalcChain().getCArray(0); - int cnt2 = chain.getCTCalcChain().sizeOfCArray(); - assertEquals(cnt - 1, cnt2); - //the first item in the calculation chain is the former second one - assertEquals(10, c.getI()); - assertEquals("C1", c.getR()); - - assertEquals(CellType.STRING, cell.getCellTypeEnum()); - cell.setCellValue("ABC"); - assertEquals(CellType.STRING, cell.getCellTypeEnum()); - } - - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestCommentsTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestCommentsTable.java deleted file mode 100644 index 1c03b9731..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestCommentsTable.java +++ /dev/null @@ -1,321 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFClientAnchor; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; - - -public class TestCommentsTable { - - private static final String TEST_A2_TEXT = "test A2 text"; - private static final String TEST_A1_TEXT = "test A1 text"; - private static final String TEST_AUTHOR = "test author"; - - @Test - public void findAuthor() throws Exception { - CommentsTable sheetComments = new CommentsTable(); - assertEquals(1, sheetComments.getNumberOfAuthors()); - assertEquals(0, sheetComments.findAuthor("")); - assertEquals("", sheetComments.getAuthor(0)); - - assertEquals(1, sheetComments.findAuthor(TEST_AUTHOR)); - assertEquals(2, sheetComments.findAuthor("another author")); - assertEquals(1, sheetComments.findAuthor(TEST_AUTHOR)); - assertEquals(3, sheetComments.findAuthor("YAA")); - assertEquals(2, sheetComments.findAuthor("another author")); - } - - @Test - public void getCellComment() throws Exception { - CommentsTable sheetComments = new CommentsTable(); - - CTComments comments = sheetComments.getCTComments(); - CTCommentList commentList = comments.getCommentList(); - - // Create 2 comments for A1 and A" cells - CTComment comment0 = commentList.insertNewComment(0); - comment0.setRef("A1"); - CTRst ctrst0 = CTRst.Factory.newInstance(); - ctrst0.setT(TEST_A1_TEXT); - comment0.setText(ctrst0); - CTComment comment1 = commentList.insertNewComment(0); - comment1.setRef("A2"); - CTRst ctrst1 = CTRst.Factory.newInstance(); - ctrst1.setT(TEST_A2_TEXT); - comment1.setText(ctrst1); - - // test finding the right comment for a cell - assertSame(comment0, sheetComments.getCTComment(new CellAddress("A1"))); - assertSame(comment1, sheetComments.getCTComment(new CellAddress("A2"))); - assertNull(sheetComments.getCTComment(new CellAddress("A3"))); - } - - - @Test - public void existing() { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithVariousData.xlsx"); - Sheet sheet1 = workbook.getSheetAt(0); - Sheet sheet2 = workbook.getSheetAt(1); - - assertTrue( ((XSSFSheet)sheet1).hasComments() ); - assertFalse( ((XSSFSheet)sheet2).hasComments() ); - - // Comments should be in C5 and C7 - Row r5 = sheet1.getRow(4); - Row r7 = sheet1.getRow(6); - assertNotNull( r5.getCell(2).getCellComment() ); - assertNotNull( r7.getCell(2).getCellComment() ); - - // Check they have what we expect - // TODO: Rich text formatting - Comment cc5 = r5.getCell(2).getCellComment(); - Comment cc7 = r7.getCell(2).getCellComment(); - - assertEquals("Nick Burch", cc5.getAuthor()); - assertEquals("Nick Burch:\nThis is a comment", cc5.getString().getString()); - assertEquals(4, cc5.getRow()); - assertEquals(2, cc5.getColumn()); - - assertEquals("Nick Burch", cc7.getAuthor()); - assertEquals("Nick Burch:\nComment #1\n", cc7.getString().getString()); - assertEquals(6, cc7.getRow()); - assertEquals(2, cc7.getColumn()); - } - - @Test - public void writeRead() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithVariousData.xlsx"); - XSSFSheet sheet1 = workbook.getSheetAt(0); - XSSFSheet sheet2 = workbook.getSheetAt(1); - - assertTrue( sheet1.hasComments() ); - assertFalse( sheet2.hasComments() ); - - // Change on comment on sheet 1, and add another into - // sheet 2 - Row r5 = sheet1.getRow(4); - Comment cc5 = r5.getCell(2).getCellComment(); - cc5.setAuthor("Apache POI"); - cc5.setString(new XSSFRichTextString("Hello!")); - - Row r2s2 = sheet2.createRow(2); - Cell c1r2s2 = r2s2.createCell(1); - assertNull(c1r2s2.getCellComment()); - - Drawing dg = sheet2.createDrawingPatriarch(); - Comment cc2 = dg.createCellComment(new XSSFClientAnchor()); - cc2.setAuthor("Also POI"); - cc2.setString(new XSSFRichTextString("A new comment")); - c1r2s2.setCellComment(cc2); - - - // Save, and re-load the file - workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); - - // Check we still have comments where we should do - sheet1 = workbook.getSheetAt(0); - sheet2 = workbook.getSheetAt(1); - assertNotNull(sheet1.getRow(4).getCell(2).getCellComment()); - assertNotNull(sheet1.getRow(6).getCell(2).getCellComment()); - assertNotNull(sheet2.getRow(2).getCell(1).getCellComment()); - - // And check they still have the contents they should do - assertEquals("Apache POI", - sheet1.getRow(4).getCell(2).getCellComment().getAuthor()); - assertEquals("Nick Burch", - sheet1.getRow(6).getCell(2).getCellComment().getAuthor()); - assertEquals("Also POI", - sheet2.getRow(2).getCell(1).getCellComment().getAuthor()); - - assertEquals("Hello!", - sheet1.getRow(4).getCell(2).getCellComment().getString().getString()); - } - - @Test - public void readWriteMultipleAuthors() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithMoreVariousData.xlsx"); - XSSFSheet sheet1 = workbook.getSheetAt(0); - XSSFSheet sheet2 = workbook.getSheetAt(1); - - assertTrue( sheet1.hasComments() ); - assertFalse( sheet2.hasComments() ); - - assertEquals("Nick Burch", - sheet1.getRow(4).getCell(2).getCellComment().getAuthor()); - assertEquals("Nick Burch", - sheet1.getRow(6).getCell(2).getCellComment().getAuthor()); - assertEquals("Torchbox", - sheet1.getRow(12).getCell(2).getCellComment().getAuthor()); - - // Save, and re-load the file - workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); - - // Check we still have comments where we should do - sheet1 = workbook.getSheetAt(0); - assertNotNull(sheet1.getRow(4).getCell(2).getCellComment()); - assertNotNull(sheet1.getRow(6).getCell(2).getCellComment()); - assertNotNull(sheet1.getRow(12).getCell(2).getCellComment()); - - // And check they still have the contents they should do - assertEquals("Nick Burch", - sheet1.getRow(4).getCell(2).getCellComment().getAuthor()); - assertEquals("Nick Burch", - sheet1.getRow(6).getCell(2).getCellComment().getAuthor()); - assertEquals("Torchbox", - sheet1.getRow(12).getCell(2).getCellComment().getAuthor()); - - // Todo - check text too, once bug fixed - } - - @Test - public void removeComment() throws Exception { - final CellAddress addrA1 = new CellAddress("A1"); - final CellAddress addrA2 = new CellAddress("A2"); - final CellAddress addrA3 = new CellAddress("A3"); - - CommentsTable sheetComments = new CommentsTable(); - CTComment a1 = sheetComments.newComment(addrA1); - CTComment a2 = sheetComments.newComment(addrA2); - CTComment a3 = sheetComments.newComment(addrA3); - - assertSame(a1, sheetComments.getCTComment(addrA1)); - assertSame(a2, sheetComments.getCTComment(addrA2)); - assertSame(a3, sheetComments.getCTComment(addrA3)); - assertEquals(3, sheetComments.getNumberOfComments()); - - assertTrue(sheetComments.removeComment(addrA1)); - assertEquals(2, sheetComments.getNumberOfComments()); - assertNull(sheetComments.getCTComment(addrA1)); - assertSame(a2, sheetComments.getCTComment(addrA2)); - assertSame(a3, sheetComments.getCTComment(addrA3)); - - assertTrue(sheetComments.removeComment(addrA2)); - assertEquals(1, sheetComments.getNumberOfComments()); - assertNull(sheetComments.getCTComment(addrA1)); - assertNull(sheetComments.getCTComment(addrA2)); - assertSame(a3, sheetComments.getCTComment(addrA3)); - - assertTrue(sheetComments.removeComment(addrA3)); - assertEquals(0, sheetComments.getNumberOfComments()); - assertNull(sheetComments.getCTComment(addrA1)); - assertNull(sheetComments.getCTComment(addrA2)); - assertNull(sheetComments.getCTComment(addrA3)); - } - - @Test - public void bug54920() throws IOException { - final Workbook workbook = new XSSFWorkbook(); - final Sheet sheet = workbook.createSheet("sheet01"); - // create anchor - CreationHelper helper = sheet.getWorkbook().getCreationHelper(); - ClientAnchor anchor = helper.createClientAnchor(); - - // place comment in A1 - // NOTE - only occurs if a comment is placed in A1 first - Cell A1 = getCell(sheet, 0, 0); - //Cell A1 = getCell(sheet, 2, 2); - Drawing drawing = sheet.createDrawingPatriarch(); - setComment(sheet, A1, drawing, "for A1", helper, anchor); - - // find comment in A1 before we set the comment in B2 - Comment commentA1 = A1.getCellComment(); - assertNotNull("Should still find the previous comment in A1, but had null", commentA1); - assertEquals("should find correct comment in A1, but had null: " + commentA1, "for A1", commentA1.getString().getString()); - - // place comment in B2, according to Bug 54920 this removes the comment in A1! - Cell B2 = getCell(sheet, 1, 1); - setComment(sheet, B2, drawing, "for B2", helper, anchor); - - // find comment in A1 - Comment commentB2 = B2.getCellComment(); - assertEquals("should find correct comment in B2, but had null: " + commentB2, "for B2", commentB2.getString().getString()); - - // find comment in A1 - commentA1 = A1.getCellComment(); - assertNotNull("Should still find the previous comment in A1, but had null", commentA1); - assertEquals("should find correct comment in A1, but had null: " + commentA1, "for A1", commentA1.getString().getString()); - - workbook.close(); - } - - // Set the comment on a sheet - // - private static void setComment(Sheet sheet, Cell cell, Drawing drawing, String commentText, CreationHelper helper, ClientAnchor anchor) { - System.out.println("Setting col: " + cell.getColumnIndex() + " and row " + cell.getRowIndex()); - anchor.setCol1(cell.getColumnIndex()); - anchor.setCol2(cell.getColumnIndex()); - anchor.setRow1(cell.getRowIndex()); - anchor.setRow2(cell.getRowIndex()); - - // get comment, or create if it does not exist - // NOTE - only occurs if getCellComment is called first - Comment comment = cell.getCellComment(); - //Comment comment = null; - if (comment == null) { - comment = drawing.createCellComment(anchor); - } - comment.setAuthor("Test"); - - // attach the comment to the cell - comment.setString(helper.createRichTextString(commentText)); - cell.setCellComment(comment); - } - - // Get a cell, create as needed - // - private static Cell getCell(Sheet sheet, int rowIndex, int colIndex) { - Row row = sheet.getRow(rowIndex); - if (row == null) { - row = sheet.createRow(rowIndex); - } - - Cell cell = row.getCell(colIndex); - if (cell == null) { - cell = row.createCell(colIndex); - } - - return cell; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestExternalLinksTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestExternalLinksTable.java deleted file mode 100644 index 1fbf86a33..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestExternalLinksTable.java +++ /dev/null @@ -1,144 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.apache.poi.ss.usermodel.Name; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; - -public final class TestExternalLinksTable { - @Test - public void none() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("SampleSS.xlsx"); - assertNotNull(wb.getExternalLinksTable()); - assertEquals(0, wb.getExternalLinksTable().size()); - } - - @Test - public void basicRead() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ref-56737.xlsx"); - assertNotNull(wb.getExternalLinksTable()); - Name name = null; - - assertEquals(1, wb.getExternalLinksTable().size()); - - ExternalLinksTable links = wb.getExternalLinksTable().get(0); - assertEquals(3, links.getSheetNames().size()); - assertEquals(2, links.getDefinedNames().size()); - - assertEquals("Uses", links.getSheetNames().get(0)); - assertEquals("Defines", links.getSheetNames().get(1)); - assertEquals("56737", links.getSheetNames().get(2)); - - name = links.getDefinedNames().get(0); - assertEquals("NR_Global_B2", name.getNameName()); - assertEquals(-1, name.getSheetIndex()); - assertEquals(null, name.getSheetName()); - assertEquals("'Defines'!$B$2", name.getRefersToFormula()); - - name = links.getDefinedNames().get(1); - assertEquals("NR_To_A1", name.getNameName()); - assertEquals(1, name.getSheetIndex()); - assertEquals("Defines", name.getSheetName()); - assertEquals("'Defines'!$A$1", name.getRefersToFormula()); - - assertEquals("56737.xlsx", links.getLinkedFileName()); - } - - @Test - public void basicReadWriteRead() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ref-56737.xlsx"); - Name name = wb.getExternalLinksTable().get(0).getDefinedNames().get(1); - name.setNameName("Testing"); - name.setRefersToFormula("$A$1"); - - wb = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertEquals(1, wb.getExternalLinksTable().size()); - ExternalLinksTable links = wb.getExternalLinksTable().get(0); - - name = links.getDefinedNames().get(0); - assertEquals("NR_Global_B2", name.getNameName()); - assertEquals(-1, name.getSheetIndex()); - assertEquals(null, name.getSheetName()); - assertEquals("'Defines'!$B$2", name.getRefersToFormula()); - - name = links.getDefinedNames().get(1); - assertEquals("Testing", name.getNameName()); - assertEquals(1, name.getSheetIndex()); - assertEquals("Defines", name.getSheetName()); - assertEquals("$A$1", name.getRefersToFormula()); - } - - @Test - public void readWithReferencesToTwoExternalBooks() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ref2-56737.xlsx"); - - assertNotNull(wb.getExternalLinksTable()); - Name name = null; - - assertEquals(2, wb.getExternalLinksTable().size()); - - // Check the first one, links to 56737.xlsx - ExternalLinksTable links = wb.getExternalLinksTable().get(0); - assertEquals("56737.xlsx", links.getLinkedFileName()); - assertEquals(3, links.getSheetNames().size()); - assertEquals(2, links.getDefinedNames().size()); - - assertEquals("Uses", links.getSheetNames().get(0)); - assertEquals("Defines", links.getSheetNames().get(1)); - assertEquals("56737", links.getSheetNames().get(2)); - - name = links.getDefinedNames().get(0); - assertEquals("NR_Global_B2", name.getNameName()); - assertEquals(-1, name.getSheetIndex()); - assertEquals(null, name.getSheetName()); - assertEquals("'Defines'!$B$2", name.getRefersToFormula()); - - name = links.getDefinedNames().get(1); - assertEquals("NR_To_A1", name.getNameName()); - assertEquals(1, name.getSheetIndex()); - assertEquals("Defines", name.getSheetName()); - assertEquals("'Defines'!$A$1", name.getRefersToFormula()); - - - // Check the second one, links to 56737.xls, slightly differently - links = wb.getExternalLinksTable().get(1); - assertEquals("56737.xls", links.getLinkedFileName()); - assertEquals(2, links.getSheetNames().size()); - assertEquals(2, links.getDefinedNames().size()); - - assertEquals("Uses", links.getSheetNames().get(0)); - assertEquals("Defines", links.getSheetNames().get(1)); - - name = links.getDefinedNames().get(0); - assertEquals("NR_Global_B2", name.getNameName()); - assertEquals(-1, name.getSheetIndex()); - assertEquals(null, name.getSheetName()); - assertEquals("'Defines'!$B$2", name.getRefersToFormula()); - - name = links.getDefinedNames().get(1); - assertEquals("NR_To_A1", name.getNameName()); - assertEquals(1, name.getSheetIndex()); - assertEquals("Defines", name.getSheetName()); - assertEquals("'Defines'!$A$1", name.getRefersToFormula()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestMapInfo.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestMapInfo.java deleted file mode 100644 index 33e91e8d3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestMapInfo.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import junit.framework.TestCase; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFMap; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMapInfo; -import org.w3c.dom.Node; - -/** - * @author Roberto Manicardi - */ -public final class TestMapInfo extends TestCase { - - - public void testMapInfoExists() { - - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx"); - - MapInfo mapInfo = null; - SingleXmlCells singleXMLCells = null; - - for (POIXMLDocumentPart p : wb.getRelations()) { - - - if (p instanceof MapInfo) { - mapInfo = (MapInfo) p; - - - CTMapInfo ctMapInfo = mapInfo.getCTMapInfo(); - - assertNotNull(ctMapInfo); - - assertEquals(1, ctMapInfo.sizeOfSchemaArray()); - - for (XSSFMap map : mapInfo.getAllXSSFMaps()) { - Node xmlSchema = map.getSchema(); - assertNotNull(xmlSchema); - } - } - } - - XSSFSheet sheet1 = wb.getSheetAt(0); - - for (POIXMLDocumentPart p : sheet1.getRelations()) { - - if (p instanceof SingleXmlCells) { - singleXMLCells = (SingleXmlCells) p; - } - - } - assertNotNull(mapInfo); - assertNotNull(singleXMLCells); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestSharedStringsTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestSharedStringsTable.java deleted file mode 100644 index ef87a9fd0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestSharedStringsTable.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; - -import junit.framework.TestCase; - -/** - * Test {@link SharedStringsTable}, the cache of strings in a workbook - * - * @author Yegor Kozlov - */ -public final class TestSharedStringsTable extends TestCase { - - public void testCreateNew() { - SharedStringsTable sst = new SharedStringsTable(); - - CTRst st; - int idx; - - // Check defaults - assertNotNull(sst.getItems()); - assertEquals(0, sst.getItems().size()); - assertEquals(0, sst.getCount()); - assertEquals(0, sst.getUniqueCount()); - - st = CTRst.Factory.newInstance(); - st.setT("Hello, World!"); - - idx = sst.addEntry(st); - assertEquals(0, idx); - assertEquals(1, sst.getCount()); - assertEquals(1, sst.getUniqueCount()); - - //add the same entry again - idx = sst.addEntry(st); - assertEquals(0, idx); - assertEquals(2, sst.getCount()); - assertEquals(1, sst.getUniqueCount()); - - //and again - idx = sst.addEntry(st); - assertEquals(0, idx); - assertEquals(3, sst.getCount()); - assertEquals(1, sst.getUniqueCount()); - - st = CTRst.Factory.newInstance(); - st.setT("Second string"); - - idx = sst.addEntry(st); - assertEquals(1, idx); - assertEquals(4, sst.getCount()); - assertEquals(2, sst.getUniqueCount()); - - //add the same entry again - idx = sst.addEntry(st); - assertEquals(1, idx); - assertEquals(5, sst.getCount()); - assertEquals(2, sst.getUniqueCount()); - - st = CTRst.Factory.newInstance(); - CTRElt r = st.addNewR(); - CTRPrElt pr = r.addNewRPr(); - pr.addNewColor().setRgb(new byte[]{(byte)0xFF, 0, 0}); //red - pr.addNewI().setVal(true); //bold - pr.addNewB().setVal(true); //italic - r.setT("Second string"); - - idx = sst.addEntry(st); - assertEquals(2, idx); - assertEquals(6, sst.getCount()); - assertEquals(3, sst.getUniqueCount()); - - idx = sst.addEntry(st); - assertEquals(2, idx); - assertEquals(7, sst.getCount()); - assertEquals(3, sst.getUniqueCount()); - - //OK. the sst table is filled, check the contents - assertEquals(3, sst.getItems().size()); - assertEquals("Hello, World!", new XSSFRichTextString(sst.getEntryAt(0)).toString()); - assertEquals("Second string", new XSSFRichTextString(sst.getEntryAt(1)).toString()); - assertEquals("Second string", new XSSFRichTextString(sst.getEntryAt(2)).toString()); - } - - public void testReadWrite() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx"); - SharedStringsTable sst1 = wb1.getSharedStringSource(); - - //serialize, read back and compare with the original - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - SharedStringsTable sst2 = wb2.getSharedStringSource(); - - assertEquals(sst1.getCount(), sst2.getCount()); - assertEquals(sst1.getUniqueCount(), sst2.getUniqueCount()); - - List items1 = sst1.getItems(); - List items2 = sst2.getItems(); - assertEquals(items1.size(), items2.size()); - for (int i = 0; i < items1.size(); i++) { - CTRst st1 = items1.get(i); - CTRst st2 = items2.get(i); - assertEquals(st1.toString(), st2.toString()); - } - - XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - assertNotNull(wb3); - wb3.close(); - wb2.close(); - wb1.close(); - } - - /** - * Test for Bugzilla 48936 - * - * A specific sequence of strings can result in broken CDATA section in sharedStrings.xml file. - * - * @author Philippe Laflamme - */ - public void testBug48936() throws IOException { - Workbook w1 = new XSSFWorkbook(); - Sheet s = w1.createSheet(); - int i = 0; - List lst = readStrings("48936-strings.txt"); - for (String str : lst) { - s.createRow(i++).createCell(0).setCellValue(str); - } - - Workbook w2 = XSSFTestDataSamples.writeOutAndReadBack(w1); - w1.close(); - s = w2.getSheetAt(0); - i = 0; - for (String str : lst) { - String val = s.getRow(i++).getCell(0).getStringCellValue(); - assertEquals(str, val); - } - - Workbook w3 = XSSFTestDataSamples.writeOutAndReadBack(w2); - w2.close(); - assertNotNull(w3); - w3.close(); - } - - private List readStrings(String filename) throws IOException { - List strs = new ArrayList(); - POIDataSamples samples = POIDataSamples.getSpreadSheetInstance(); - BufferedReader br = new BufferedReader( - new InputStreamReader(samples.openResourceAsStream(filename), "UTF-8")); - String s; - while ((s = br.readLine()) != null) { - if (s.trim().length() > 0) { - strs.add(s.trim()); - } - } - br.close(); - return strs; - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestStylesTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestStylesTable.java deleted file mode 100644 index 9d29fc453..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestStylesTable.java +++ /dev/null @@ -1,359 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import org.junit.BeforeClass; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.util.Map; - -import org.apache.poi.ss.usermodel.BuiltinFormats; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -public final class TestStylesTable { - private static final String testFile = "Formatting.xlsx"; - private static final String customDataFormat = "YYYY-mm-dd"; - - @BeforeClass - public static void assumeCustomDataFormatIsNotBuiltIn() { - assertEquals(-1, BuiltinFormats.getBuiltinFormat(customDataFormat)); - } - - @Test - public void testCreateNew() { - StylesTable st = new StylesTable(); - - // Check defaults - assertNotNull(st.getCTStylesheet()); - assertEquals(1, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(0, st.getNumDataFormats()); - } - - @Test - public void testCreateSaveLoad() { - XSSFWorkbook wb = new XSSFWorkbook(); - StylesTable st = wb.getStylesSource(); - - assertNotNull(st.getCTStylesheet()); - assertEquals(1, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(0, st.getNumDataFormats()); - - st = XSSFTestDataSamples.writeOutAndReadBack(wb).getStylesSource(); - - assertNotNull(st.getCTStylesheet()); - assertEquals(1, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(0, st.getNumDataFormats()); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - } - - @Test - public void testLoadExisting() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook(testFile); - assertNotNull(workbook.getStylesSource()); - - StylesTable st = workbook.getStylesSource(); - - doTestExisting(st); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(workbook)); - } - - @Test - public void testLoadSaveLoad() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook(testFile); - assertNotNull(workbook.getStylesSource()); - - StylesTable st = workbook.getStylesSource(); - doTestExisting(st); - - st = XSSFTestDataSamples.writeOutAndReadBack(workbook).getStylesSource(); - doTestExisting(st); - } - - public void doTestExisting(StylesTable st) { - // Check contents - assertNotNull(st.getCTStylesheet()); - assertEquals(11, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(8, st.getNumDataFormats()); - - assertEquals(2, st.getFonts().size()); - assertEquals(2, st.getFills().size()); - assertEquals(1, st.getBorders().size()); - - assertEquals("yyyy/mm/dd", st.getNumberFormatAt((short)165)); - assertEquals("yy/mm/dd", st.getNumberFormatAt((short)167)); - - assertNotNull(st.getStyleAt(0)); - assertNotNull(st.getStyleAt(1)); - assertNotNull(st.getStyleAt(2)); - - assertEquals(0, st.getStyleAt(0).getDataFormat()); - assertEquals(14, st.getStyleAt(1).getDataFormat()); - assertEquals(0, st.getStyleAt(2).getDataFormat()); - assertEquals(165, st.getStyleAt(3).getDataFormat()); - - assertEquals("yyyy/mm/dd", st.getStyleAt(3).getDataFormatString()); - } - - @Test - public void populateNew() { - XSSFWorkbook wb = new XSSFWorkbook(); - StylesTable st = wb.getStylesSource(); - - assertNotNull(st.getCTStylesheet()); - assertEquals(1, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(0, st.getNumDataFormats()); - - int nf1 = st.putNumberFormat("yyyy-mm-dd"); - int nf2 = st.putNumberFormat("yyyy-mm-DD"); - assertEquals(nf1, st.putNumberFormat("yyyy-mm-dd")); - - st.putStyle(new XSSFCellStyle(st)); - - // Save and re-load - st = XSSFTestDataSamples.writeOutAndReadBack(wb).getStylesSource(); - - assertNotNull(st.getCTStylesheet()); - assertEquals(2, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(2, st.getNumDataFormats()); - - assertEquals("yyyy-mm-dd", st.getNumberFormatAt((short)nf1)); - assertEquals(nf1, st.putNumberFormat("yyyy-mm-dd")); - assertEquals(nf2, st.putNumberFormat("yyyy-mm-DD")); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - } - - @Test - public void populateExisting() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook(testFile); - assertNotNull(workbook.getStylesSource()); - - StylesTable st = workbook.getStylesSource(); - assertEquals(11, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(8, st.getNumDataFormats()); - - int nf1 = st.putNumberFormat("YYYY-mm-dd"); - int nf2 = st.putNumberFormat("YYYY-mm-DD"); - assertEquals(nf1, st.putNumberFormat("YYYY-mm-dd")); - - st = XSSFTestDataSamples.writeOutAndReadBack(workbook).getStylesSource(); - - assertEquals(11, st._getXfsSize()); - assertEquals(1, st._getStyleXfsSize()); - assertEquals(10, st.getNumDataFormats()); - - assertEquals("YYYY-mm-dd", st.getNumberFormatAt((short)nf1)); - assertEquals(nf1, st.putNumberFormat("YYYY-mm-dd")); - assertEquals(nf2, st.putNumberFormat("YYYY-mm-DD")); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(workbook)); - } - - @Test - public void exceedNumberFormatLimit() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - StylesTable styles = wb.getStylesSource(); - for (int i = 0; i < styles.getMaxNumberOfDataFormats(); i++) { - wb.getStylesSource().putNumberFormat("\"test" + i + " \"0"); - } - try { - wb.getStylesSource().putNumberFormat("\"anotherformat \"0"); - } catch (final IllegalStateException e) { - if (e.getMessage().startsWith("The maximum number of Data Formats was exceeded.")) { - //expected - } - else { - throw e; - } - } - } finally { - wb.close(); - } - } - - private static final void assertNotContainsKey(Map map, K key) { - assertFalse(map.containsKey(key)); - } - private static final void assertNotContainsValue(Map map, V value) { - assertFalse(map.containsValue(value)); - } - - @Test - public void removeNumberFormat() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - try { - final String fmt = customDataFormat; - final short fmtIdx = (short) wb1.getStylesSource().putNumberFormat(fmt); - - Cell cell = wb1.createSheet("test").createRow(0).createCell(0); - cell.setCellValue(5.25); - CellStyle style = wb1.createCellStyle(); - style.setDataFormat(fmtIdx); - cell.setCellStyle(style); - - assertEquals(fmt, cell.getCellStyle().getDataFormatString()); - assertEquals(fmt, wb1.getStylesSource().getNumberFormatAt(fmtIdx)); - - // remove the number format from the workbook - wb1.getStylesSource().removeNumberFormat(fmt); - - // number format in CellStyles should be restored to default number format - final short defaultFmtIdx = 0; - final String defaultFmt = BuiltinFormats.getBuiltinFormat(0); - assertEquals(defaultFmtIdx, style.getDataFormat()); - assertEquals(defaultFmt, style.getDataFormatString()); - - // The custom number format should be entirely removed from the workbook - Map numberFormats = wb1.getStylesSource().getNumberFormats(); - assertNotContainsKey(numberFormats, fmtIdx); - assertNotContainsValue(numberFormats, fmt); - - // The default style shouldn't be added back to the styles source because it's built-in - assertEquals(0, wb1.getStylesSource().getNumDataFormats()); - - cell = null; style = null; numberFormats = null; - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutCloseAndReadBack(wb1); - - cell = wb2.getSheet("test").getRow(0).getCell(0); - style = cell.getCellStyle(); - - // number format in CellStyles should be restored to default number format - assertEquals(defaultFmtIdx, style.getDataFormat()); - assertEquals(defaultFmt, style.getDataFormatString()); - - // The custom number format should be entirely removed from the workbook - numberFormats = wb2.getStylesSource().getNumberFormats(); - assertNotContainsKey(numberFormats, fmtIdx); - assertNotContainsValue(numberFormats, fmt); - - // The default style shouldn't be added back to the styles source because it's built-in - assertEquals(0, wb2.getStylesSource().getNumDataFormats()); - - wb2.close(); - - } finally { - wb1.close(); - } - } - - @Test - public void maxNumberOfDataFormats() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - - try { - StylesTable styles = wb.getStylesSource(); - - // Check default limit - int n = styles.getMaxNumberOfDataFormats(); - // https://support.office.com/en-us/article/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 - assertTrue(200 <= n); - assertTrue(n <= 250); - - // Check upper limit - n = Integer.MAX_VALUE; - styles.setMaxNumberOfDataFormats(n); - assertEquals(n, styles.getMaxNumberOfDataFormats()); - - // Check negative (illegal) limits - try { - styles.setMaxNumberOfDataFormats(-1); - fail("Expected to get an IllegalArgumentException(\"Maximum Number of Data Formats must be greater than or equal to 0\")"); - } catch (final IllegalArgumentException e) { - if (e.getMessage().startsWith("Maximum Number of Data Formats must be greater than or equal to 0")) { - // expected - } else { - throw e; - } - } - } - finally { - wb.close(); - } - } - - @Test - public void addDataFormatsBeyondUpperLimit() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - - try { - StylesTable styles = wb.getStylesSource(); - styles.setMaxNumberOfDataFormats(0); - - // Try adding a format beyond the upper limit - try { - styles.putNumberFormat("\"test \"0"); - fail("Expected to raise IllegalStateException"); - } catch (final IllegalStateException e) { - if (e.getMessage().startsWith("The maximum number of Data Formats was exceeded.")) { - // expected - } else { - throw e; - } - } - } - finally { - wb.close(); - } - } - - @Test - public void decreaseUpperLimitBelowCurrentNumDataFormats() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - - try { - StylesTable styles = wb.getStylesSource(); - styles.putNumberFormat(customDataFormat); - - // Try decreasing the upper limit below the current number of formats - try { - styles.setMaxNumberOfDataFormats(0); - fail("Expected to raise IllegalStateException"); - } catch (final IllegalStateException e) { - if (e.getMessage().startsWith("Cannot set the maximum number of data formats less than the current quantity.")) { - // expected - } else { - throw e; - } - } - } - finally { - wb.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestThemesTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestThemesTable.java deleted file mode 100644 index ffeceb289..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/model/TestThemesTable.java +++ /dev/null @@ -1,263 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.FileOutputStream; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Map; - -import org.apache.commons.codec.binary.Hex; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.ThemesTable.ThemeElement; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.xssf.usermodel.XSSFFont; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; - -public class TestThemesTable { - private final String testFileSimple = "Themes.xlsx"; - private final String testFileComplex = "Themes2.xlsx"; - // TODO .xls version available too, add HSSF support then check - - // What colours they should show up as - private static String rgbExpected[] = { - "ffffff", // Lt1 - "000000", // Dk1 - "eeece1", // Lt2 - "1f497d", // DK2 - "4f81bd", // Accent1 - "c0504d", // Accent2 - "9bbb59", // Accent3 - "8064a2", // Accent4 - "4bacc6", // Accent5 - "f79646", // Accent6 - "0000ff", // Hlink - "800080" // FolHlink - }; - - @Test - public void testThemesTableColors() throws Exception { - // Load our two test workbooks - XSSFWorkbook simple = XSSFTestDataSamples.openSampleWorkbook(testFileSimple); - XSSFWorkbook complex = XSSFTestDataSamples.openSampleWorkbook(testFileComplex); - // Save and re-load them, to check for stability across that - XSSFWorkbook simpleRS = XSSFTestDataSamples.writeOutAndReadBack(simple); - XSSFWorkbook complexRS = XSSFTestDataSamples.writeOutAndReadBack(complex); - // Fetch fresh copies to test with - simple = XSSFTestDataSamples.openSampleWorkbook(testFileSimple); - complex = XSSFTestDataSamples.openSampleWorkbook(testFileComplex); - // Files and descriptions - Map workbooks = new LinkedHashMap(); - workbooks.put(testFileSimple, simple); - workbooks.put("Re-Saved_" + testFileSimple, simpleRS); - workbooks.put(testFileComplex, complex); - workbooks.put("Re-Saved_" + testFileComplex, complexRS); - - // Sanity check - assertEquals(rgbExpected.length, rgbExpected.length); - - // For offline testing - boolean createFiles = false; - - // Check each workbook in turn, and verify that the colours - // for the theme-applied cells in Column A are correct - for (String whatWorkbook : workbooks.keySet()) { - XSSFWorkbook workbook = workbooks.get(whatWorkbook); - XSSFSheet sheet = workbook.getSheetAt(0); - int startRN = 0; - if (whatWorkbook.endsWith(testFileComplex)) startRN++; - - for (int rn=startRN; rn tempFiles = new ArrayList(); - - List getTempFiles() { - return new ArrayList(tempFiles); - } - - @Override - protected SheetDataWriter createSheetDataWriter() throws IOException { - return new TempFileRecordingSheetDataWriterWithDecorator(); - } - - class TempFileRecordingSheetDataWriterWithDecorator extends SheetDataWriterWithDecorator { - - TempFileRecordingSheetDataWriterWithDecorator() throws IOException { - super(); - tempFiles.add(getTempFile()); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestAutoSizeColumnTracker.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestAutoSizeColumnTracker.java deleted file mode 100644 index a6a2dde5e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestAutoSizeColumnTracker.java +++ /dev/null @@ -1,219 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.SheetUtil; -import org.junit.After; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Test; - - -/** - * Tests the auto-sizing behaviour of {@link SXSSFSheet} when not all - * rows fit into the memory window size etc. - * - * @see Bug #57450 which reported the original mis-behaviour - */ -public class TestAutoSizeColumnTracker { - - private SXSSFSheet sheet; - private SXSSFWorkbook workbook; - private AutoSizeColumnTracker tracker; - private static final SortedSet columns; - static { - SortedSet_columns = new TreeSet(); - _columns.add(0); - _columns.add(1); - _columns.add(3); - columns = Collections.unmodifiableSortedSet(_columns); - } - private final static String SHORT_MESSAGE = "short"; - private final static String LONG_MESSAGE = "This is a test of a long message! This is a test of a long message!"; - - @Before - public void setUpSheetAndWorkbook() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - tracker = new AutoSizeColumnTracker(sheet); - } - - @After - public void tearDownSheetAndWorkbook() throws IOException { - if (sheet != null) { - sheet.dispose(); - } - if (workbook != null) { - workbook.close(); - } - } - - @Test - public void trackAndUntrackColumn() { - assumeTrue(tracker.getTrackedColumns().isEmpty()); - tracker.trackColumn(0); - Set expected = new HashSet(); - expected.add(0); - assertEquals(expected, tracker.getTrackedColumns()); - tracker.untrackColumn(0); - assertTrue(tracker.getTrackedColumns().isEmpty()); - } - - @Test - public void trackAndUntrackColumns() { - assumeTrue(tracker.getTrackedColumns().isEmpty()); - tracker.trackColumns(columns); - assertEquals(columns, tracker.getTrackedColumns()); - tracker.untrackColumn(3); - tracker.untrackColumn(0); - tracker.untrackColumn(1); - assertTrue(tracker.getTrackedColumns().isEmpty()); - tracker.trackColumn(0); - tracker.trackColumns(columns); - tracker.untrackColumn(4); - assertEquals(columns, tracker.getTrackedColumns()); - tracker.untrackColumns(columns); - assertTrue(tracker.getTrackedColumns().isEmpty()); - } - - @Test - public void trackAndUntrackAllColumns() { - assumeTrue(tracker.getTrackedColumns().isEmpty()); - tracker.trackAllColumns(); - assertTrue(tracker.getTrackedColumns().isEmpty()); - - Row row = sheet.createRow(0); - for (int column : columns) { - row.createCell(column); - } - // implicitly track the columns - tracker.updateColumnWidths(row); - assertEquals(columns, tracker.getTrackedColumns()); - - tracker.untrackAllColumns(); - assertTrue(tracker.getTrackedColumns().isEmpty()); - } - - @Test - public void isColumnTracked() { - assumeFalse(tracker.isColumnTracked(0)); - tracker.trackColumn(0); - assertTrue(tracker.isColumnTracked(0)); - tracker.untrackColumn(0); - assertFalse(tracker.isColumnTracked(0)); - } - - @Test - public void getTrackedColumns() { - assumeTrue(tracker.getTrackedColumns().isEmpty()); - - for (int column : columns) { - tracker.trackColumn(column); - } - - assertEquals(3, tracker.getTrackedColumns().size()); - assertEquals(columns, tracker.getTrackedColumns()); - } - - @Test - public void isAllColumnsTracked() { - assertFalse(tracker.isAllColumnsTracked()); - tracker.trackAllColumns(); - assertTrue(tracker.isAllColumnsTracked()); - tracker.untrackAllColumns(); - assertFalse(tracker.isAllColumnsTracked()); - } - - @Test - public void updateColumnWidths_and_getBestFitColumnWidth() { - tracker.trackAllColumns(); - Row row1 = sheet.createRow(0); - Row row2 = sheet.createRow(1); - // A1, B1, D1 - for (int column : columns) { - row1.createCell(column).setCellValue(LONG_MESSAGE); - row2.createCell(column+1).setCellValue(SHORT_MESSAGE); - } - tracker.updateColumnWidths(row1); - tracker.updateColumnWidths(row2); - sheet.addMergedRegion(CellRangeAddress.valueOf("D1:E1")); - - assumeRequiredFontsAreInstalled(workbook, row1.getCell(columns.iterator().next())); - - // Excel 2013 and LibreOffice 4.2.8.2 both treat columns with merged regions as blank - /** A B C D E - * 1 LONG LONG LONGMERGE - * 2 SHORT SHORT SHORT - */ - - // measured in Excel 2013. Sizes may vary. - final int longMsgWidth = (int) (57.43*256); - final int shortMsgWidth = (int) (4.86*256); - - checkColumnWidth(longMsgWidth, 0, true); - checkColumnWidth(longMsgWidth, 0, false); - checkColumnWidth(longMsgWidth, 1, true); - checkColumnWidth(longMsgWidth, 1, false); - checkColumnWidth(shortMsgWidth, 2, true); - checkColumnWidth(shortMsgWidth, 2, false); - checkColumnWidth(-1, 3, true); - checkColumnWidth(longMsgWidth, 3, false); - checkColumnWidth(shortMsgWidth, 4, true); //but is it really? shouldn't autosizing column E use "" from E1 and SHORT from E2? - checkColumnWidth(shortMsgWidth, 4, false); - } - - private void checkColumnWidth(int expectedWidth, int column, boolean useMergedCells) { - final int bestFitWidth = tracker.getBestFitColumnWidth(column, useMergedCells); - if (bestFitWidth < 0 && expectedWidth < 0) return; - final double abs_error = Math.abs(bestFitWidth-expectedWidth); - final double rel_error = abs_error / expectedWidth; - if (rel_error > 0.25) { - fail("check column width: " + - rel_error + ", " + abs_error + ", " + - expectedWidth + ", " + bestFitWidth); - } - - } - - private static void assumeRequiredFontsAreInstalled(final Workbook workbook, final Cell cell) { - // autoSize will fail if required fonts are not installed, skip this test then - Font font = workbook.getFontAt(cell.getCellStyle().getFontIndex()); - System.out.println(font.getFontHeightInPoints()); - System.out.println(font.getFontName()); - Assume.assumeTrue("Cannot verify autoSizeColumn() because the necessary Fonts are not installed on this machine: " + font, - SheetUtil.canComputeColumnWidth(font)); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestOutlining.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestOutlining.java deleted file mode 100644 index 7ce130d54..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestOutlining.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; - -public final class TestOutlining { - @Test - public void testSetRowGroupCollapsed() throws IOException { - SXSSFWorkbook wb2 = new SXSSFWorkbook(100); - wb2.setCompressTempFiles(true); - SXSSFSheet sheet2 = wb2.createSheet("new sheet"); - - int rowCount = 20; - for (int i = 0; i < rowCount; i++) { - sheet2.createRow(i); - } - - sheet2.groupRow(4, 9); - sheet2.groupRow(11, 19); - - sheet2.setRowGroupCollapsed(4, true); - - SXSSFRow r = sheet2.getRow(8); - assertTrue(r.getHidden()); - r = sheet2.getRow(10); - assertTrue(r.getCollapsed()); - r = sheet2.getRow(12); - assertNull(r.getHidden()); - wb2.dispose(); - - wb2.close(); - } - - @Test - public void testSetRowGroupCollapsedError() throws IOException { - SXSSFWorkbook wb2 = new SXSSFWorkbook(100); - wb2.setCompressTempFiles(true); - SXSSFSheet sheet2 = wb2.createSheet("new sheet"); - - int rowCount = 20; - for (int i = 0; i < rowCount; i++) { - sheet2.createRow(i); - } - - sheet2.groupRow(4, 9); - sheet2.groupRow(11, 19); - - try { - sheet2.setRowGroupCollapsed(3, true); - fail("Should fail with an exception"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("row (3)")); - } - - try { - sheet2.setRowGroupCollapsed(10, true); - fail("Should fail with an exception"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("row (10)")); - } - - try { - sheet2.setRowGroupCollapsed(0, true); - fail("Should fail with an exception"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("row (0)")); - } - - try { - sheet2.setRowGroupCollapsed(20, true); - fail("Should fail with an exception"); - } catch (IllegalArgumentException e) { - assertTrue("Had: " + e.getMessage(), - e.getMessage().contains("Row does not exist")); - } - - SXSSFRow r = sheet2.getRow(8); - assertNotNull(r); - assertNull(r.getHidden()); - r = sheet2.getRow(10); - assertNull(r.getCollapsed()); - r = sheet2.getRow(12); - assertNull(r.getHidden()); - wb2.dispose(); - - wb2.close(); - } - - @Test - public void testOutlineGettersHSSF() throws IOException { - HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); - HSSFSheet hssfSheet = hssfWorkbook.createSheet(); - hssfSheet.createRow(0); - hssfSheet.createRow(1); - hssfSheet.createRow(2); - hssfSheet.createRow(3); - hssfSheet.createRow(4); - hssfSheet.groupRow(1, 3); - hssfSheet.groupRow(2, 3); - - assertEquals(0, hssfSheet.getRow(0).getOutlineLevel()); - assertEquals(1, hssfSheet.getRow(1).getOutlineLevel()); - assertEquals(2, hssfSheet.getRow(2).getOutlineLevel()); - assertEquals(2, hssfSheet.getRow(3).getOutlineLevel()); - assertEquals(0, hssfSheet.getRow(4).getOutlineLevel()); - hssfWorkbook.close(); - } - - @Test - public void testOutlineGettersXSSF() throws IOException { - XSSFWorkbook xssfWorkbook = new XSSFWorkbook(); - XSSFSheet xssfSheet = xssfWorkbook.createSheet(); - xssfSheet.createRow(0); - xssfSheet.createRow(1); - xssfSheet.createRow(2); - xssfSheet.createRow(3); - xssfSheet.createRow(4); - xssfSheet.groupRow(1, 3); - xssfSheet.groupRow(2, 3); - - assertEquals(0, xssfSheet.getRow(0).getOutlineLevel()); - assertEquals(1, xssfSheet.getRow(1).getOutlineLevel()); - assertEquals(2, xssfSheet.getRow(2).getOutlineLevel()); - assertEquals(2, xssfSheet.getRow(3).getOutlineLevel()); - assertEquals(0, xssfSheet.getRow(4).getOutlineLevel()); - xssfWorkbook.close(); - } - - @Test - public void testOutlineGettersSXSSF() throws IOException { - SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(); - Sheet sxssfSheet = sxssfWorkbook.createSheet(); - sxssfSheet.createRow(0); - sxssfSheet.createRow(1); - sxssfSheet.createRow(2); - sxssfSheet.createRow(3); - sxssfSheet.createRow(4); - sxssfSheet.createRow(5); - - // nothing happens with empty row-area - sxssfSheet.groupRow(1, 0); - assertEquals(0, sxssfSheet.getRow(0).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(1).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(2).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(3).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(4).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(5).getOutlineLevel()); - - sxssfSheet.groupRow(1, 3); - sxssfSheet.groupRow(2, 3); - - assertEquals(0, sxssfSheet.getRow(0).getOutlineLevel()); - assertEquals(1, sxssfSheet.getRow(1).getOutlineLevel()); - assertEquals(2, sxssfSheet.getRow(2).getOutlineLevel()); - assertEquals(2, sxssfSheet.getRow(3).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(4).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(5).getOutlineLevel()); - - // add tests for direct setting - add row 4 to deepest group - ((SXSSFSheet)sxssfSheet).setRowOutlineLevel(4, 2); - assertEquals(0, sxssfSheet.getRow(0).getOutlineLevel()); - assertEquals(1, sxssfSheet.getRow(1).getOutlineLevel()); - assertEquals(2, sxssfSheet.getRow(2).getOutlineLevel()); - assertEquals(2, sxssfSheet.getRow(3).getOutlineLevel()); - assertEquals(2, sxssfSheet.getRow(4).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(5).getOutlineLevel()); - - sxssfWorkbook.dispose(); - sxssfWorkbook.close(); - } - - @Test - public void testOutlineGettersSXSSFSetOutlineLevel() throws IOException { - SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(); - Sheet sxssfSheet = sxssfWorkbook.createSheet(); - sxssfSheet.createRow(0); - sxssfSheet.createRow(1); - sxssfSheet.createRow(2); - sxssfSheet.createRow(3); - sxssfSheet.createRow(4); - sxssfSheet.createRow(5); - - // what happens with level below 1 - ((SXSSFSheet)sxssfSheet).setRowOutlineLevel(0, -2); - assertEquals(-2, sxssfSheet.getRow(0).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(1).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(2).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(3).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(4).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(5).getOutlineLevel()); - - // add tests for direct setting - ((SXSSFSheet)sxssfSheet).setRowOutlineLevel(4, 2); - assertEquals(-2, sxssfSheet.getRow(0).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(1).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(2).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(3).getOutlineLevel()); - assertEquals(2, sxssfSheet.getRow(4).getOutlineLevel()); - assertEquals(0, sxssfSheet.getRow(5).getOutlineLevel()); - - sxssfWorkbook.dispose(); - sxssfWorkbook.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java deleted file mode 100644 index b84b06bb3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import javax.xml.namespace.QName; - -import org.apache.poi.ss.usermodel.BaseTestXCell; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xmlbeans.XmlCursor; -import org.junit.AfterClass; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; - -/** - * Tests various functionality having to do with {@link SXSSFCell}. For instance support for - * particular datatypes, etc. - */ -public class TestSXSSFCell extends BaseTestXCell { - - public TestSXSSFCell() { - super(SXSSFITestDataProvider.instance); - } - - @AfterClass - public static void tearDownClass(){ - SXSSFITestDataProvider.instance.cleanup(); - } - - @Test - public void testPreserveSpaces() throws IOException { - String[] samplesWithSpaces = { - " POI", - "POI ", - " POI ", - "\nPOI", - "\n\nPOI \n", - }; - for(String str : samplesWithSpaces){ - Workbook swb = _testDataProvider.createWorkbook(); - Cell sCell = swb.createSheet().createRow(0).createCell(0); - sCell.setCellValue(str); - assertEquals(sCell.getStringCellValue(), str); - - // read back as XSSF and check that xml:spaces="preserve" is set - XSSFWorkbook xwb = (XSSFWorkbook)_testDataProvider.writeOutAndReadBack(swb); - XSSFCell xCell = xwb.getSheetAt(0).getRow(0).getCell(0); - - CTRst is = xCell.getCTCell().getIs(); - XmlCursor c = is.newCursor(); - c.toNextToken(); - String t = c.getAttributeText(new QName("http://www.w3.org/XML/1998/namespace", "space")); - c.dispose(); - assertEquals("expected xml:spaces=\"preserve\" \"" + str + "\"", "preserve", t); - xwb.close(); - swb.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFDataValidation.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFDataValidation.java deleted file mode 100644 index 2ee465b7c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFDataValidation.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.apache.poi.ss.usermodel.BaseTestDataValidation; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.junit.Test; - -public class TestSXSSFDataValidation extends BaseTestDataValidation { - - public TestSXSSFDataValidation(){ - super(SXSSFITestDataProvider.instance); - } - - @Test - public void test53965() throws Exception { - SXSSFWorkbook wb = new SXSSFWorkbook(); - try { - Sheet sheet = wb.createSheet(); - List lst = sheet.getDataValidations(); //<-- works - assertEquals(0, lst.size()); - - //create the cell that will have the validation applied - sheet.createRow(0).createCell(0); - - DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); - DataValidationConstraint constraint = dataValidationHelper.createCustomConstraint("SUM($A$1:$A$1) <= 3500"); - CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0); - DataValidation validation = dataValidationHelper.createValidation(constraint, addressList); - sheet.addValidationData(validation); - - // this line caused XmlValueOutOfRangeException , see Bugzilla 3965 - lst = sheet.getDataValidations(); - assertEquals(1, lst.size()); - } finally { - wb.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFFormulaEvaluation.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFFormulaEvaluation.java deleted file mode 100644 index 0839fe801..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFFormulaEvaluation.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; - -/** - * Formula Evaluation with SXSSF. - * - * Note that SXSSF can only evaluate formulas where the - * cell is in the current window, and all references - * from the cell are in the current window - */ -public final class TestSXSSFFormulaEvaluation { - public static final SXSSFITestDataProvider _testDataProvider = SXSSFITestDataProvider.instance; - - /** - * EvaluateAll will normally fail, as any reference or - * formula outside of the window will fail, and any - * non-active sheets will fail - */ - @Test - public void testEvaluateAllFails() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(5); - SXSSFSheet s = wb.createSheet(); - - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - - s.createRow(0).createCell(0).setCellFormula("1+2"); - s.createRow(1).createCell(0).setCellFormula("A21"); - for (int i=2; i<19; i++) { s.createRow(i); } - - // Cells outside window will fail, whether referenced or not - s.createRow(19).createCell(0).setCellFormula("A1+A2"); - s.createRow(20).createCell(0).setCellFormula("A1+A11+100"); - try { - eval.evaluateAll(); - fail("Evaluate All shouldn't work, as some cells outside the window"); - } catch(SXSSFFormulaEvaluator.RowFlushedException e) { - // Expected - } - - - // Inactive sheets will fail - XSSFWorkbook xwb = new XSSFWorkbook(); - xwb.createSheet("Open"); - xwb.createSheet("Closed"); - - wb.close(); - wb = new SXSSFWorkbook(xwb, 5); - s = wb.getSheet("Closed"); - s.flushRows(); - s = wb.getSheet("Open"); - s.createRow(0).createCell(0).setCellFormula("1+2"); - - eval = wb.getCreationHelper().createFormulaEvaluator(); - try { - eval.evaluateAll(); - fail("Evaluate All shouldn't work, as sheets flushed"); - } catch (SXSSFFormulaEvaluator.SheetsFlushedException e) {} - - wb.close(); - } - - @Test - public void testEvaluateRefOutsideWindowFails() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(5); - SXSSFSheet s = wb.createSheet(); - - s.createRow(0).createCell(0).setCellFormula("1+2"); - assertEquals(false, s.areAllRowsFlushed()); - assertEquals(-1, s.getLastFlushedRowNum()); - - for (int i=1; i<=19; i++) { s.createRow(i); } - Cell c = s.createRow(20).createCell(0); - c.setCellFormula("A1+100"); - - assertEquals(false, s.areAllRowsFlushed()); - assertEquals(15, s.getLastFlushedRowNum()); - - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - try { - eval.evaluateFormulaCellEnum(c); - fail("Evaluate shouldn't work, as reference outside the window"); - } catch(SXSSFFormulaEvaluator.RowFlushedException e) { - // Expected - } - - wb.close(); - } - - /** - * If all formula cells + their references are inside the window, - * then evaluation works - * @throws IOException - */ - @Test - public void testEvaluateAllInWindow() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(5); - SXSSFSheet s = wb.createSheet(); - s.createRow(0).createCell(0).setCellFormula("1+2"); - s.createRow(1).createCell(1).setCellFormula("A1+10"); - s.createRow(2).createCell(2).setCellFormula("B2+100"); - - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - eval.evaluateAll(); - - assertEquals(3, (int)s.getRow(0).getCell(0).getNumericCellValue()); - assertEquals(13, (int)s.getRow(1).getCell(1).getNumericCellValue()); - assertEquals(113, (int)s.getRow(2).getCell(2).getNumericCellValue()); - - wb.close(); - } - - @Test - public void testEvaluateRefInsideWindow() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(5); - SXSSFSheet s = wb.createSheet(); - - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - - SXSSFCell c = s.createRow(0).createCell(0); - c.setCellValue(1.5); - - c = s.createRow(1).createCell(0); - c.setCellFormula("A1*2"); - - assertEquals(0, (int)c.getNumericCellValue()); - eval.evaluateFormulaCellEnum(c); - assertEquals(3, (int)c.getNumericCellValue()); - - wb.close(); - } - - @Test - public void testEvaluateSimple() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(5); - SXSSFSheet s = wb.createSheet(); - - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - - SXSSFCell c = s.createRow(0).createCell(0); - c.setCellFormula("1+2"); - assertEquals(0, (int)c.getNumericCellValue()); - eval.evaluateFormulaCellEnum(c); - assertEquals(3, (int)c.getNumericCellValue()); - - c = s.createRow(1).createCell(0); - c.setCellFormula("CONCATENATE(\"hello\",\" \",\"world\")"); - eval.evaluateFormulaCellEnum(c); - assertEquals("hello world", c.getStringCellValue()); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFHyperlink.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFHyperlink.java deleted file mode 100644 index e1e237b68..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFHyperlink.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.junit.After; - -import org.apache.poi.ss.usermodel.BaseTestHyperlink; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.usermodel.XSSFHyperlink; - -/** - * Test setting hyperlinks in SXSSF - * - * @author Yegor Kozlov - */ -public class TestSXSSFHyperlink extends BaseTestHyperlink { - - public TestSXSSFHyperlink() { - super(SXSSFITestDataProvider.instance); - } - - - @After - public void tearDown(){ - SXSSFITestDataProvider.instance.cleanup(); - } - - @Override - public XSSFHyperlink copyHyperlink(Hyperlink link) { - // FIXME: replace with SXSSFHyperlink if it ever gets created - return new XSSFHyperlink(link); - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFRow.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFRow.java deleted file mode 100644 index 90a730d19..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFRow.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import org.apache.poi.ss.usermodel.BaseTestXRow; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.junit.After; - -/** - * Tests for XSSFRow - */ -public final class TestSXSSFRow extends BaseTestXRow { - - public TestSXSSFRow() { - super(SXSSFITestDataProvider.instance); - } - - - @After - public void tearDown() { - ((SXSSFITestDataProvider) _testDataProvider).cleanup(); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java deleted file mode 100644 index d5be11e2f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestXSheet; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.After; -import org.junit.Test; - - -public final class TestSXSSFSheet extends BaseTestXSheet { - - public TestSXSSFSheet() { - super(SXSSFITestDataProvider.instance); - } - - - @After - public void tearDown(){ - SXSSFITestDataProvider.instance.cleanup(); - } - - @Override - protected void trackColumnsForAutoSizingIfSXSSF(Sheet sheet) { - SXSSFSheet sxSheet = (SXSSFSheet) sheet; - sxSheet.trackAllColumnsForAutoSizing(); - } - - - /** - * cloning of sheets is not supported in SXSSF - */ - @Override - @Test - public void cloneSheet() throws IOException { - thrown.expect(RuntimeException.class); - thrown.expectMessage("NotImplemented"); - super.cloneSheet(); - } - - @Override - @Test - public void cloneSheetMultipleTimes() throws IOException { - thrown.expect(RuntimeException.class); - thrown.expectMessage("NotImplemented"); - super.cloneSheetMultipleTimes(); - } - - /** - * shifting rows is not supported in SXSSF - */ - @Override - @Test - public void shiftMerged() throws IOException { - thrown.expect(RuntimeException.class); - thrown.expectMessage("NotImplemented"); - super.shiftMerged(); - } - - /** - * Bug 35084: cloning cells with formula - * - * The test is disabled because cloning of sheets is not supported in SXSSF - */ - @Override - @Test - public void bug35084() throws IOException { - thrown.expect(RuntimeException.class); - thrown.expectMessage("NotImplemented"); - super.bug35084(); - } - - @Override - @Test - public void getCellComment() throws IOException { - // TODO: reading cell comments via Sheet does not work currently as it tries - // to access the underlying sheet for this, but comments are stored as - // properties on Cells... - } - - @Override - @Test - public void defaultColumnStyle() { - //TODO column styles are not yet supported by XSSF - } - - @Test - public void overrideFlushedRows() throws IOException { - Workbook wb = new SXSSFWorkbook(3); - try { - Sheet sheet = wb.createSheet(); - - sheet.createRow(1); - sheet.createRow(2); - sheet.createRow(3); - sheet.createRow(4); - - thrown.expect(Throwable.class); - thrown.expectMessage("Attempting to write a row[1] in the range [0,1] that is already written to disk."); - sheet.createRow(1); - } finally { - wb.close(); - } - } - - @Test - public void overrideRowsInTemplate() throws IOException { - XSSFWorkbook template = new XSSFWorkbook(); - template.createSheet().createRow(1); - - Workbook wb = new SXSSFWorkbook(template); - try { - Sheet sheet = wb.getSheetAt(0); - - try { - sheet.createRow(1); - fail("expected exception"); - } catch (Throwable e){ - assertEquals("Attempting to write a row[1] in the range [0,1] that is already written to disk.", e.getMessage()); - } - try { - sheet.createRow(0); - fail("expected exception"); - } catch (Throwable e){ - assertEquals("Attempting to write a row[0] in the range [0,1] that is already written to disk.", e.getMessage()); - } - sheet.createRow(2); - } finally { - wb.close(); - template.close(); - } - } - - @Test - public void changeRowNum() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(3); - SXSSFSheet sheet = wb.createSheet(); - SXSSFRow row0 = sheet.createRow(0); - SXSSFRow row1 = sheet.createRow(1); - sheet.changeRowNum(row0, 2); - - assertEquals("Row 1 knows its row number", 1, row1.getRowNum()); - assertEquals("Row 2 knows its row number", 2, row0.getRowNum()); - assertEquals("Sheet knows Row 1's row number", 1, sheet.getRowNum(row1)); - assertEquals("Sheet knows Row 2's row number", 2, sheet.getRowNum(row0)); - assertEquals("Sheet row iteratation order should be ascending", row1, sheet.iterator().next()); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java deleted file mode 100644 index 15acbfca0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java +++ /dev/null @@ -1,379 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.SheetUtil; -import org.junit.After; -import org.junit.Assume; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - - -/** - * Tests the auto-sizing behaviour of {@link SXSSFSheet} when not all - * rows fit into the memory window size etc. - * - * @see Bug #57450 which reported the original mis-behaviour - */ -@RunWith(Parameterized.class) -public class TestSXSSFSheetAutoSizeColumn { - - private static final String SHORT_CELL_VALUE = "Ben"; - private static final String LONG_CELL_VALUE = "B Be Ben Beni Benif Benify Benif Beni Ben Be B"; - - // Approximative threshold to decide whether test is PASS or FAIL: - // shortCellValue ends up with approx column width 1_000 (on my machine), - // longCellValue ends up with approx. column width 10_000 (on my machine) - // so shortCellValue can be expected to be < 5000 for all fonts - // and longCellValue can be expected to be > 5000 for all fonts - private static final int COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG = 4000; - private static final int MAX_COLUMN_WIDTH = 255*256; - - private static final SortedSet columns; - static { - SortedSet_columns = new TreeSet(); - _columns.add(0); - _columns.add(1); - _columns.add(3); - columns = Collections.unmodifiableSortedSet(_columns); - } - - - private SXSSFSheet sheet; - private SXSSFWorkbook workbook; - - @Parameter(0) - public boolean useMergedCells; - - @Parameters(name="{index}: useMergedCells={0}") - public static Collection data() { - return Arrays.asList(new Object[][] { - {false}, - {true}, - }); - } - - @After - public void tearDownSheetAndWorkbook() throws IOException { - if (sheet != null) { - sheet.dispose(); - } - if (workbook != null) { - workbook.close(); - } - } - - @Test - public void test_EmptySheet_NoException() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - sheet.trackAllColumnsForAutoSizing(); - - for (int i = 0; i < 10; i++) { - sheet.autoSizeColumn(i, useMergedCells); - } - } - - @Test - public void test_WindowSizeDefault_AllRowsFitIntoWindowSize() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - sheet.trackAllColumnsForAutoSizing(); - - final Cell cellRow0 = createRowWithCellValues(sheet, 0, LONG_CELL_VALUE); - - assumeRequiredFontsAreInstalled(workbook, cellRow0); - - createRowWithCellValues(sheet, 1, SHORT_CELL_VALUE); - - sheet.autoSizeColumn(0, useMergedCells); - - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(0), COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG, MAX_COLUMN_WIDTH); - } - - @Test - public void test_WindowSizeEqualsOne_ConsiderFlushedRows() { - workbook = new SXSSFWorkbook(null, 1); // Window size 1 so only last row will be in memory - sheet = workbook.createSheet(); - sheet.trackAllColumnsForAutoSizing(); - - final Cell cellRow0 = createRowWithCellValues(sheet, 0, LONG_CELL_VALUE); - - assumeRequiredFontsAreInstalled(workbook, cellRow0); - - createRowWithCellValues(sheet, 1, SHORT_CELL_VALUE); - - sheet.autoSizeColumn(0, useMergedCells); - - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(0), COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG, MAX_COLUMN_WIDTH); - } - - @Test - public void test_WindowSizeEqualsOne_lastRowIsNotWidest() { - workbook = new SXSSFWorkbook(null, 1); // Window size 1 so only last row will be in memory - sheet = workbook.createSheet(); - sheet.trackAllColumnsForAutoSizing(); - - final Cell cellRow0 = createRowWithCellValues(sheet, 0, LONG_CELL_VALUE); - - assumeRequiredFontsAreInstalled(workbook, cellRow0); - - createRowWithCellValues(sheet, 1, SHORT_CELL_VALUE); - - sheet.autoSizeColumn(0, useMergedCells); - - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(0), COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG, MAX_COLUMN_WIDTH); - } - - @Test - public void test_WindowSizeEqualsOne_lastRowIsWidest() { - workbook = new SXSSFWorkbook(null, 1); // Window size 1 so only last row will be in memory - sheet = workbook.createSheet(); - sheet.trackAllColumnsForAutoSizing(); - - final Cell cellRow0 = createRowWithCellValues(sheet, 0, SHORT_CELL_VALUE); - - assumeRequiredFontsAreInstalled(workbook, cellRow0); - - createRowWithCellValues(sheet, 1, LONG_CELL_VALUE); - - sheet.autoSizeColumn(0, useMergedCells); - - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(0), COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG, MAX_COLUMN_WIDTH); - } - - // fails only for useMergedCell=true - @Test - public void test_WindowSizeEqualsOne_flushedRowHasMergedCell() { - workbook = new SXSSFWorkbook(null, 1); // Window size 1 so only last row will be in memory - sheet = workbook.createSheet(); - sheet.trackAllColumnsForAutoSizing(); - - Cell a1 = createRowWithCellValues(sheet, 0, LONG_CELL_VALUE); - - assumeRequiredFontsAreInstalled(workbook, a1); - sheet.addMergedRegion(CellRangeAddress.valueOf("A1:B1")); - - createRowWithCellValues(sheet, 1, SHORT_CELL_VALUE, SHORT_CELL_VALUE); - - /** - * A B - * 1 LONGMERGED - * 2 SHORT SHORT - */ - - sheet.autoSizeColumn(0, useMergedCells); - sheet.autoSizeColumn(1, useMergedCells); - - if (useMergedCells) { - // Excel and LibreOffice behavior: ignore merged cells for auto-sizing. - // POI behavior: evenly distribute the column width among the merged columns. - // each column must be auto-sized in order for the column widths - // to add up to the best fit width. - final int colspan = 2; - final int expectedWidth = (10000 + 1000)/colspan; //average of 1_000 and 10_000 - final int minExpectedWidth = expectedWidth / 2; - final int maxExpectedWidth = expectedWidth * 3 / 2; - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(0), minExpectedWidth, maxExpectedWidth); //short - } else { - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(0), COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG, MAX_COLUMN_WIDTH); //long - } - assertColumnWidthStrictlyWithinRange(sheet.getColumnWidth(1), 0, COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG); //short - } - - @Test - public void autoSizeColumn_trackColumnForAutoSizing() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - sheet.trackColumnForAutoSizing(0); - - SortedSet expected = new TreeSet(); - expected.add(0); - assertEquals(expected, sheet.getTrackedColumnsForAutoSizing()); - - sheet.autoSizeColumn(0, useMergedCells); - try { - sheet.autoSizeColumn(1, useMergedCells); - fail("Should not be able to auto-size an untracked column"); - } - catch (final IllegalStateException e) { - // expected - } - } - - @Test - public void autoSizeColumn_trackColumnsForAutoSizing() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - - sheet.trackColumnsForAutoSizing(columns); - SortedSet sorted = new TreeSet(columns); - assertEquals(sorted, sheet.getTrackedColumnsForAutoSizing()); - - sheet.autoSizeColumn(sorted.first(), useMergedCells); - try { - assumeFalse(columns.contains(5)); - sheet.autoSizeColumn(5, useMergedCells); - fail("Should not be able to auto-size an untracked column"); - } - catch (final IllegalStateException e) { - // expected - } - } - - @Test - public void autoSizeColumn_untrackColumnForAutoSizing() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - - sheet.trackColumnsForAutoSizing(columns); - sheet.untrackColumnForAutoSizing(columns.first()); - - assumeTrue(sheet.getTrackedColumnsForAutoSizing().contains(columns.last())); - sheet.autoSizeColumn(columns.last(), useMergedCells); - try { - assumeFalse(sheet.getTrackedColumnsForAutoSizing().contains(columns.first())); - sheet.autoSizeColumn(columns.first(), useMergedCells); - fail("Should not be able to auto-size an untracked column"); - } - catch (final IllegalStateException e) { - // expected - } - } - - @Test - public void autoSizeColumn_untrackColumnsForAutoSizing() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - - sheet.trackColumnForAutoSizing(15); - sheet.trackColumnsForAutoSizing(columns); - sheet.untrackColumnsForAutoSizing(columns); - - assumeTrue(sheet.getTrackedColumnsForAutoSizing().contains(15)); - sheet.autoSizeColumn(15, useMergedCells); - try { - assumeFalse(sheet.getTrackedColumnsForAutoSizing().contains(columns.first())); - sheet.autoSizeColumn(columns.first(), useMergedCells); - fail("Should not be able to auto-size an untracked column"); - } - catch (final IllegalStateException e) { - // expected - } - } - - @Test - public void autoSizeColumn_isColumnTrackedForAutoSizing() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - - sheet.trackColumnsForAutoSizing(columns); - for (int column : columns) { - assertTrue(sheet.isColumnTrackedForAutoSizing(column)); - - assumeFalse(columns.contains(column+10)); - assertFalse(sheet.isColumnTrackedForAutoSizing(column+10)); - } - } - - @Test - public void autoSizeColumn_trackAllColumns() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - - sheet.trackAllColumnsForAutoSizing(); - sheet.autoSizeColumn(0, useMergedCells); - - sheet.untrackAllColumnsForAutoSizing(); - try { - sheet.autoSizeColumn(0, useMergedCells); - fail("Should not be able to auto-size an implicitly untracked column"); - } catch (final IllegalStateException e) { - // expected - } - } - - @Test - public void autoSizeColumn_trackAllColumns_explicitUntrackColumn() { - workbook = new SXSSFWorkbook(); - sheet = workbook.createSheet(); - - sheet.trackColumnsForAutoSizing(columns); - sheet.trackAllColumnsForAutoSizing(); - - sheet.untrackColumnForAutoSizing(0); - try { - sheet.autoSizeColumn(0, useMergedCells); - fail("Should not be able to auto-size an explicitly untracked column"); - } catch (final IllegalStateException e) { - // expected - } - } - - - private static void assumeRequiredFontsAreInstalled(final Workbook workbook, final Cell cell) { - // autoSize will fail if required fonts are not installed, skip this test then - Font font = workbook.getFontAt(cell.getCellStyle().getFontIndex()); - Assume.assumeTrue("Cannot verify autoSizeColumn() because the necessary Fonts are not installed on this machine: " + font, - SheetUtil.canComputeColumnWidth(font)); - } - - private static Cell createRowWithCellValues(final Sheet sheet, final int rowNumber, final String... cellValues) { - Row row = sheet.createRow(rowNumber); - int cellIndex = 0; - Cell firstCell = null; - for (final String cellValue : cellValues) { - Cell cell = row.createCell(cellIndex++); - if (firstCell == null) { - firstCell = cell; - } - cell.setCellValue(cellValue); - } - return firstCell; - } - - private static void assertColumnWidthStrictlyWithinRange(final int actualColumnWidth, final int lowerBoundExclusive, final int upperBoundExclusive) { - assertTrue("Expected a column width greater than " + lowerBoundExclusive + " but found " + actualColumnWidth, - actualColumnWidth > lowerBoundExclusive); - assertTrue("Expected column width less than " + upperBoundExclusive + " but found " + actualColumnWidth, actualColumnWidth < upperBoundExclusive); - - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java deleted file mode 100644 index 7b5a67de5..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Arrays; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POITestCase; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.ss.usermodel.BaseTestXWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.NullOutputStream; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.After; -import org.junit.Assume; -import org.junit.Ignore; -import org.junit.Test; - -public final class TestSXSSFWorkbook extends BaseTestXWorkbook { - - public TestSXSSFWorkbook() { - super(SXSSFITestDataProvider.instance); - } - - @After - public void tearDown(){ - ((SXSSFITestDataProvider)_testDataProvider).cleanup(); - } - - /** - * cloning of sheets is not supported in SXSSF - */ - @Override - @Test - public void cloneSheet() throws IOException { - try { - super.cloneSheet(); - fail("expected exception"); - } catch (RuntimeException e){ - assertEquals("NotImplemented", e.getMessage()); - } - } - - /** - * cloning of sheets is not supported in SXSSF - */ - @Override - @Test - public void sheetClone() throws IOException { - try { - super.sheetClone(); - fail("expected exception"); - } catch (RuntimeException e){ - assertEquals("NotImplemented", e.getMessage()); - } - } - - /** - * Skip this test, as SXSSF doesn't update formulas on sheet name - * changes. - */ - @Override - @Test - public void setSheetName() { - Assume.assumeTrue("SXSSF doesn't update formulas on sheet name changes, as most cells probably aren't in memory at the time", false); - } - - @Test - public void existingWorkbook() throws IOException { - XSSFWorkbook xssfWb1 = new XSSFWorkbook(); - xssfWb1.createSheet("S1"); - SXSSFWorkbook wb1 = new SXSSFWorkbook(xssfWb1); - XSSFWorkbook xssfWb2 = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb1); - assertTrue(wb1.dispose()); - - SXSSFWorkbook wb2 = new SXSSFWorkbook(xssfWb2); - assertEquals(1, wb2.getNumberOfSheets()); - Sheet sheet = wb2.getSheetAt(0); - assertNotNull(sheet); - assertEquals("S1", sheet.getSheetName()); - assertTrue(wb2.dispose()); - xssfWb2.close(); - xssfWb1.close(); - - wb2.close(); - wb1.close(); - } - - @Test - public void useSharedStringsTable() throws Exception { - SXSSFWorkbook wb = new SXSSFWorkbook(null, 10, false, true); - - SharedStringsTable sss = POITestCase.getFieldValue(SXSSFWorkbook.class, wb, SharedStringsTable.class, "_sharedStringSource"); - - assertNotNull(sss); - - Row row = wb.createSheet("S1").createRow(0); - - row.createCell(0).setCellValue("A"); - row.createCell(1).setCellValue("B"); - row.createCell(2).setCellValue("A"); - - XSSFWorkbook xssfWorkbook = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb); - sss = POITestCase.getFieldValue(SXSSFWorkbook.class, wb, SharedStringsTable.class, "_sharedStringSource"); - assertEquals(2, sss.getUniqueCount()); - assertTrue(wb.dispose()); - - Sheet sheet1 = xssfWorkbook.getSheetAt(0); - assertEquals("S1", sheet1.getSheetName()); - assertEquals(1, sheet1.getPhysicalNumberOfRows()); - row = sheet1.getRow(0); - assertNotNull(row); - Cell cell = row.getCell(0); - assertNotNull(cell); - assertEquals("A", cell.getStringCellValue()); - cell = row.getCell(1); - assertNotNull(cell); - assertEquals("B", cell.getStringCellValue()); - cell = row.getCell(2); - assertNotNull(cell); - assertEquals("A", cell.getStringCellValue()); - - xssfWorkbook.close(); - wb.close(); - } - - @Test - public void addToExistingWorkbook() throws IOException { - XSSFWorkbook xssfWb1 = new XSSFWorkbook(); - xssfWb1.createSheet("S1"); - Sheet sheet = xssfWb1.createSheet("S2"); - Row row = sheet.createRow(1); - Cell cell = row.createCell(1); - cell.setCellValue("value 2_1_1"); - SXSSFWorkbook wb1 = new SXSSFWorkbook(xssfWb1); - XSSFWorkbook xssfWb2 = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb1); - assertTrue(wb1.dispose()); - xssfWb1.close(); - - SXSSFWorkbook wb2 = new SXSSFWorkbook(xssfWb2); - // Add a row to the existing empty sheet - Sheet sheet1 = wb2.getSheetAt(0); - Row row1_1 = sheet1.createRow(1); - Cell cell1_1_1 = row1_1.createCell(1); - cell1_1_1.setCellValue("value 1_1_1"); - - // Add a row to the existing non-empty sheet - Sheet sheet2 = wb2.getSheetAt(1); - Row row2_2 = sheet2.createRow(2); - Cell cell2_2_1 = row2_2.createCell(1); - cell2_2_1.setCellValue("value 2_2_1"); - - // Add a sheet with one row - Sheet sheet3 = wb2.createSheet("S3"); - Row row3_1 = sheet3.createRow(1); - Cell cell3_1_1 = row3_1.createCell(1); - cell3_1_1.setCellValue("value 3_1_1"); - - XSSFWorkbook xssfWb3 = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb2); - wb2.close(); - - assertEquals(3, xssfWb3.getNumberOfSheets()); - // Verify sheet 1 - sheet1 = xssfWb3.getSheetAt(0); - assertEquals("S1", sheet1.getSheetName()); - assertEquals(1, sheet1.getPhysicalNumberOfRows()); - row1_1 = sheet1.getRow(1); - assertNotNull(row1_1); - cell1_1_1 = row1_1.getCell(1); - assertNotNull(cell1_1_1); - assertEquals("value 1_1_1", cell1_1_1.getStringCellValue()); - // Verify sheet 2 - sheet2 = xssfWb3.getSheetAt(1); - assertEquals("S2", sheet2.getSheetName()); - assertEquals(2, sheet2.getPhysicalNumberOfRows()); - Row row2_1 = sheet2.getRow(1); - assertNotNull(row2_1); - Cell cell2_1_1 = row2_1.getCell(1); - assertNotNull(cell2_1_1); - assertEquals("value 2_1_1", cell2_1_1.getStringCellValue()); - row2_2 = sheet2.getRow(2); - assertNotNull(row2_2); - cell2_2_1 = row2_2.getCell(1); - assertNotNull(cell2_2_1); - assertEquals("value 2_2_1", cell2_2_1.getStringCellValue()); - // Verify sheet 3 - sheet3 = xssfWb3.getSheetAt(2); - assertEquals("S3", sheet3.getSheetName()); - assertEquals(1, sheet3.getPhysicalNumberOfRows()); - row3_1 = sheet3.getRow(1); - assertNotNull(row3_1); - cell3_1_1 = row3_1.getCell(1); - assertNotNull(cell3_1_1); - assertEquals("value 3_1_1", cell3_1_1.getStringCellValue()); - - xssfWb2.close(); - xssfWb3.close(); - wb1.close(); - } - - @Test - public void sheetdataWriter() throws IOException{ - SXSSFWorkbook wb = new SXSSFWorkbook(); - SXSSFSheet sh = wb.createSheet(); - SheetDataWriter wr = sh.getSheetDataWriter(); - assertTrue(wr.getClass() == SheetDataWriter.class); - File tmp = wr.getTempFile(); - assertTrue(tmp.getName().startsWith("poi-sxssf-sheet")); - assertTrue(tmp.getName().endsWith(".xml")); - assertTrue(wb.dispose()); - wb.close(); - - wb = new SXSSFWorkbook(); - wb.setCompressTempFiles(true); - sh = wb.createSheet(); - wr = sh.getSheetDataWriter(); - assertTrue(wr.getClass() == GZIPSheetDataWriter.class); - tmp = wr.getTempFile(); - assertTrue(tmp.getName().startsWith("poi-sxssf-sheet-xml")); - assertTrue(tmp.getName().endsWith(".gz")); - assertTrue(wb.dispose()); - wb.close(); - - //Test escaping of Unicode control characters - wb = new SXSSFWorkbook(); - wb.createSheet("S1").createRow(0).createCell(0).setCellValue("value\u0019"); - XSSFWorkbook xssfWorkbook = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb); - Cell cell = xssfWorkbook.getSheet("S1").getRow(0).getCell(0); - assertEquals("value?", cell.getStringCellValue()); - - assertTrue(wb.dispose()); - wb.close(); - xssfWorkbook.close(); - } - - @Test - public void gzipSheetdataWriter() throws IOException { - SXSSFWorkbook wb = new SXSSFWorkbook(); - wb.setCompressTempFiles(true); - int rowNum = 1000; - int sheetNum = 5; - for(int i = 0; i < sheetNum; i++){ - Sheet sh = wb.createSheet("sheet" + i); - for(int j = 0; j < rowNum; j++){ - Row row = sh.createRow(j); - Cell cell1 = row.createCell(0); - cell1.setCellValue(new CellReference(cell1).formatAsString()); - - Cell cell2 = row.createCell(1); - cell2.setCellValue(i); - - Cell cell3 = row.createCell(2); - cell3.setCellValue(j); - } - } - - XSSFWorkbook xwb = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb); - for(int i = 0; i < sheetNum; i++){ - Sheet sh = xwb.getSheetAt(i); - assertEquals("sheet" + i, sh.getSheetName()); - for(int j = 0; j < rowNum; j++){ - Row row = sh.getRow(j); - assertNotNull("row[" + j + "]", row); - Cell cell1 = row.getCell(0); - assertEquals(new CellReference(cell1).formatAsString(), cell1.getStringCellValue()); - - Cell cell2 = row.getCell(1); - assertEquals(i, (int)cell2.getNumericCellValue()); - - Cell cell3 = row.getCell(2); - assertEquals(j, (int)cell3.getNumericCellValue()); - } - } - - assertTrue(wb.dispose()); - xwb.close(); - wb.close(); - } - - protected static void assertWorkbookDispose(SXSSFWorkbook wb) - { - int rowNum = 1000; - int sheetNum = 5; - for(int i = 0; i < sheetNum; i++){ - Sheet sh = wb.createSheet("sheet" + i); - for(int j = 0; j < rowNum; j++){ - Row row = sh.createRow(j); - Cell cell1 = row.createCell(0); - cell1.setCellValue(new CellReference(cell1).formatAsString()); - - Cell cell2 = row.createCell(1); - cell2.setCellValue(i); - - Cell cell3 = row.createCell(2); - cell3.setCellValue(j); - } - } - - for (Sheet sheet : wb) { - SXSSFSheet sxSheet = (SXSSFSheet) sheet; - assertTrue(sxSheet.getSheetDataWriter().getTempFile().exists()); - } - - assertTrue(wb.dispose()); - - for (Sheet sheet : wb) { - SXSSFSheet sxSheet = (SXSSFSheet) sheet; - assertFalse(sxSheet.getSheetDataWriter().getTempFile().exists()); - } - } - - @Test - public void workbookDispose() throws IOException { - SXSSFWorkbook wb1 = new SXSSFWorkbook(); - // the underlying writer is SheetDataWriter - assertWorkbookDispose(wb1); - wb1.close(); - - SXSSFWorkbook wb2 = new SXSSFWorkbook(); - wb2.setCompressTempFiles(true); - // the underlying writer is GZIPSheetDataWriter - assertWorkbookDispose(wb2); - wb2.close(); - } - - @Ignore("currently writing the same sheet multiple times is not supported...") - @Test - public void bug53515() throws Exception { - Workbook wb1 = new SXSSFWorkbook(10); - populateWorkbook(wb1); - saveTwice(wb1); - Workbook wb2 = new XSSFWorkbook(); - populateWorkbook(wb2); - saveTwice(wb2); - wb2.close(); - wb1.close(); - } - - @Ignore("Crashes the JVM because of documented JVM behavior with concurrent writing/reading of zip-files, " - + "see http://www.oracle.com/technetwork/java/javase/documentation/overview-156328.html") - @Test - public void bug53515a() throws Exception { - File out = new File("Test.xlsx"); - out.delete(); - for (int i = 0; i < 2; i++) { - System.out.println("Iteration " + i); - final SXSSFWorkbook wb; - if (out.exists()) { - wb = new SXSSFWorkbook( - (XSSFWorkbook) WorkbookFactory.create(out)); - } else { - wb = new SXSSFWorkbook(10); - } - - try { - FileOutputStream outSteam = new FileOutputStream(out); - if (i == 0) { - populateWorkbook(wb); - } else { - System.gc(); - System.gc(); - System.gc(); - } - - wb.write(outSteam); - // assertTrue(wb.dispose()); - outSteam.close(); - } finally { - assertTrue(wb.dispose()); - } - wb.close(); - } - out.delete(); - } - - private static void populateWorkbook(Workbook wb) { - Sheet sh = wb.createSheet(); - for (int rownum = 0; rownum < 100; rownum++) { - Row row = sh.createRow(rownum); - for (int cellnum = 0; cellnum < 10; cellnum++) { - Cell cell = row.createCell(cellnum); - String address = new CellReference(cell).formatAsString(); - cell.setCellValue(address); - } - } - } - - private static void saveTwice(Workbook wb) throws Exception { - for (int i = 0; i < 2; i++) { - try { - NullOutputStream out = new NullOutputStream(); - wb.write(out); - out.close(); - } catch (Exception e) { - throw new Exception("ERROR: failed on " + (i + 1) - + "th time calling " + wb.getClass().getName() - + ".write() with exception " + e.getMessage(), e); - } - } - } - - @Ignore("Just a local test for http://stackoverflow.com/questions/33627329/apache-poi-streaming-api-using-xssf-template") - @Test - public void testTemplateFile() throws IOException { - XSSFWorkbook workBook = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx"); - SXSSFWorkbook streamingWorkBook = new SXSSFWorkbook(workBook,10); - Sheet sheet = streamingWorkBook.getSheet("Sheet1"); - for(int rowNum = 10;rowNum < 1000000;rowNum++) { - Row row = sheet.createRow(rowNum); - for(int cellNum = 0;cellNum < 700;cellNum++) { - Cell cell = row.createCell(cellNum); - cell.setCellValue("somevalue"); - } - - if(rowNum % 100 == 0) { - System.out.print("."); - if(rowNum % 10000 == 0) { - System.out.println(rowNum); - } - } - } - - FileOutputStream fos = new FileOutputStream("C:\\temp\\streaming.xlsx"); - streamingWorkBook.write(fos); - fos.close(); - - streamingWorkBook.close(); - workBook.close(); - } - - - @Test - public void closeDoesNotModifyWorkbook() throws IOException, InvalidFormatException { - final String filename = "SampleSS.xlsx"; - final File file = POIDataSamples.getSpreadSheetInstance().getFile(filename); - SXSSFWorkbook wb = null; - XSSFWorkbook xwb = null; - - // Some tests commented out because close() modifies the file - // See bug 58779 - - // String - //wb = new SXSSFWorkbook(new XSSFWorkbook(file.getPath())); - //assertCloseDoesNotModifyFile(filename, wb); - - // File - //wb = new SXSSFWorkbook(new XSSFWorkbook(file)); - //assertCloseDoesNotModifyFile(filename, wb); - - // InputStream - FileInputStream fis = new FileInputStream(file); - try { - xwb = new XSSFWorkbook(fis); - wb = new SXSSFWorkbook(xwb); - assertCloseDoesNotModifyFile(filename, wb); - } finally { - if (xwb != null) { - xwb.close(); - } - if (wb != null) { - wb.close(); - } - fis.close(); - } - - // OPCPackage - //wb = new SXSSFWorkbook(new XSSFWorkbook(OPCPackage.open(file))); - //assertCloseDoesNotModifyFile(filename, wb); - } - - /** - * Bug #59743 - * - * this is only triggered on other files apart of sheet[1,2,...].xml - * as those are either copied uncompressed or with the use of GZIPInputStream - * so we use shared strings - */ - @Test - public void testZipBombNotTriggeredOnUselessContent() throws IOException { - SXSSFWorkbook swb = new SXSSFWorkbook(null, 1, true, true); - SXSSFSheet s = swb.createSheet(); - char useless[] = new char[32767]; - Arrays.fill(useless, ' '); - - for (int row=0; row<1; row++) { - Row r = s.createRow(row); - for (int col=0; col<10; col++) { - char prefix[] = Integer.toHexString(row*1000+col).toCharArray(); - Arrays.fill(useless, 0, 10, ' '); - System.arraycopy(prefix, 0, useless, 0, prefix.length); - String ul = new String(useless); - r.createCell(col, CellType.STRING).setCellValue(ul); - ul = null; - } - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - swb.write(bos); - swb.dispose(); - swb.close(); - } - - /** - * To avoid accident changes to the template, you should be able - * to create a SXSSFWorkbook from a read-only XSSF one, then - * change + save that (only). See bug #60010 - * TODO Fix this to work! - */ - @Test - @Ignore - public void createFromReadOnlyWorkbook() throws Exception { - File input = XSSFTestDataSamples.getSampleFile("sample.xlsx"); - OPCPackage pkg = OPCPackage.open(input, PackageAccess.READ); - XSSFWorkbook xssf = new XSSFWorkbook(pkg); - SXSSFWorkbook wb = new SXSSFWorkbook(xssf, 2); - - String sheetName = "Test SXSSF"; - Sheet s = wb.createSheet(sheetName); - for (int i=0; i<10; i++) { - Row r = s.createRow(i); - r.createCell(0).setCellValue(true); - r.createCell(1).setCellValue(2.4); - r.createCell(2).setCellValue("Test Row " + i); - } - assertEquals(10, s.getLastRowNum()); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - wb.write(bos); - wb.dispose(); - wb.close(); - - xssf = new XSSFWorkbook(new ByteArrayInputStream(bos.toByteArray())); - s = xssf.getSheet(sheetName); - assertEquals(10, s.getLastRowNum()); - assertEquals(true, s.getRow(0).getCell(0).getBooleanCellValue()); - assertEquals("Test Row 9", s.getRow(9).getCell(2).getStringCellValue()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java deleted file mode 100644 index b477c8b10..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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.streaming; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.security.GeneralSecurityException; -import java.util.List; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.util.ZipEntrySource; -import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; -import org.apache.poi.poifs.crypt.temp.EncryptedTempData; -import org.apache.poi.poifs.crypt.temp.SXSSFWorkbookWithCustomZipEntrySource; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; - -/** - * This class tests that an SXSSFWorkbook can be written and read where all temporary disk I/O - * is encrypted, but the final saved workbook is not encrypted - */ -public final class TestSXSSFWorkbookWithCustomZipEntrySource { - - final String sheetName = "TestSheet1"; - final String cellValue = "customZipEntrySource"; - - // write an unencrypted workbook to disk, but any temporary files are encrypted - @Test - public void customZipEntrySource() throws IOException { - SXSSFWorkbookWithCustomZipEntrySource workbook = new SXSSFWorkbookWithCustomZipEntrySource(); - SXSSFSheet sheet1 = workbook.createSheet(sheetName); - SXSSFRow row1 = sheet1.createRow(1); - SXSSFCell cell1 = row1.createCell(1); - cell1.setCellValue(cellValue); - ByteArrayOutputStream os = new ByteArrayOutputStream(8192); - workbook.write(os); - workbook.close(); - workbook.dispose(); - XSSFWorkbook xwb = new XSSFWorkbook(new ByteArrayInputStream(os.toByteArray())); - XSSFSheet xs1 = xwb.getSheetAt(0); - assertEquals(sheetName, xs1.getSheetName()); - XSSFRow xr1 = xs1.getRow(1); - XSSFCell xc1 = xr1.getCell(1); - assertEquals(cellValue, xc1.getStringCellValue()); - xwb.close(); - } - - // write an encrypted workbook to disk, and encrypt any temporary files as well - @Test - public void customZipEntrySourceForWriteAndRead() throws IOException, GeneralSecurityException, InvalidFormatException { - SXSSFWorkbookWithCustomZipEntrySource workbook = new SXSSFWorkbookWithCustomZipEntrySource(); - SXSSFSheet sheet1 = workbook.createSheet(sheetName); - SXSSFRow row1 = sheet1.createRow(1); - SXSSFCell cell1 = row1.createCell(1); - cell1.setCellValue(cellValue); - EncryptedTempData tempData = new EncryptedTempData(); - workbook.write(tempData.getOutputStream()); - workbook.close(); - workbook.dispose(); - ZipEntrySource zipEntrySource = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream()); - tempData.dispose(); - OPCPackage opc = OPCPackage.open(zipEntrySource); - XSSFWorkbook xwb = new XSSFWorkbook(opc); - zipEntrySource.close(); - XSSFSheet xs1 = xwb.getSheetAt(0); - assertEquals(sheetName, xs1.getSheetName()); - XSSFRow xr1 = xs1.getRow(1); - XSSFCell xc1 = xr1.getCell(1); - assertEquals(cellValue, xc1.getStringCellValue()); - xwb.close(); - opc.close(); - } - - // Java 7 and above: - // import static java.nio.charset.StandardCharsets.UTF_8; - // Java 6 and below: - private static final Charset UTF_8 = Charset.forName("UTF-8"); - - @Test - public void validateTempFilesAreEncrypted() throws IOException { - TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource workbook = new TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource(); - SXSSFSheet sheet1 = workbook.createSheet(sheetName); - SXSSFRow row1 = sheet1.createRow(1); - SXSSFCell cell1 = row1.createCell(1); - cell1.setCellValue(cellValue); - ByteArrayOutputStream os = new ByteArrayOutputStream(8192); - workbook.write(os); - workbook.close(); - List tempFiles = workbook.getTempFiles(); - assertEquals(1, tempFiles.size()); - File tempFile = tempFiles.get(0); - assertTrue("tempFile exists?", tempFile.exists()); - InputStream stream = new FileInputStream(tempFile); - try { - byte[] data = IOUtils.toByteArray(stream); - String text = new String(data, UTF_8); - assertFalse(text.contains(sheetName)); - assertFalse(text.contains(cellValue)); - } finally { - stream.close(); - } - workbook.dispose(); - assertFalse("tempFile deleted after dispose?", tempFile.exists()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java deleted file mode 100644 index 6ecad0a74..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.eval.forked.TestForkedEvaluator; -import org.apache.poi.xssf.usermodel.extensions.TestXSSFBorder; -import org.apache.poi.xssf.usermodel.extensions.TestXSSFCellFill; -import org.apache.poi.xssf.usermodel.extensions.TestXSSFSheetComments; -import org.apache.poi.xssf.usermodel.helpers.TestColumnHelper; -import org.apache.poi.xssf.usermodel.helpers.TestHeaderFooterHelper; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Collects all tests for org.apache.poi.xssf.usermodel and sub-packages. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TestFormulaEvaluatorOnXSSF.class, - TestMultiSheetFormulaEvaluatorOnXSSF.class, - TestSheetHiding.class, - TestXSSFBugs.class, - TestXSSFDataFormat.class, - TestXSSFCellStyle.class, - TestXSSFComment.class, - TestXSSFDialogSheet.class, - TestXSSFDrawing.class, - TestXSSFFont.class, - TestXSSFFormulaEvaluation.class, - TestXSSFHeaderFooter.class, - TestXSSFHyperlink.class, - TestXSSFName.class, - TestXSSFPicture.class, - TestXSSFPictureData.class, - TestXSSFPrintSetup.class, - TestXSSFRichTextString.class, - TestXSSFRow.class, - TestXSSFSheet.class, - TestXSSFSheetUpdateArrayFormulas.class, - TestXSSFTable.class, - TestXSSFWorkbook.class, - TestXSSFBorder.class, - TestXSSFCellFill.class, - TestXSSFSheetComments.class, - TestColumnHelper.class, - TestHeaderFooterHelper.class, - //TestXSSFPivotTable.class, //converted to junit4 - TestForkedEvaluator.class -}) -public final class AllXSSFUsermodelTests { -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/BaseTestXSSFPivotTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/BaseTestXSSFPivotTable.java deleted file mode 100644 index 445812566..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/BaseTestXSSFPivotTable.java +++ /dev/null @@ -1,299 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DataConsolidateFunction; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageField; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageFields; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFields; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotTableDefinition; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataConsolidateFunction; - -public abstract class BaseTestXSSFPivotTable { - private static final XSSFITestDataProvider _testDataProvider = XSSFITestDataProvider.instance; - protected XSSFWorkbook wb; - protected XSSFPivotTable pivotTable; - protected XSSFPivotTable offsetPivotTable; - protected Cell offsetOuterCell; - - /** - * required to set up the test pivot tables and cell reference, either by name or reference. - * @see junit.framework.TestCase#setUp() - */ - @Before - public abstract void setUp(); - - @After - public void tearDown() throws IOException { - if (wb != null) { - XSSFWorkbook wb2 = _testDataProvider.writeOutAndReadBack(wb); - wb.close(); - wb2.close(); - } - } - - /** - * Verify that when creating a row label it's created on the correct row - * and the count is increased by one. - */ - @Test - public void testAddRowLabelToPivotTable() { - int columnIndex = 0; - - assertEquals(0, pivotTable.getRowLabelColumns().size()); - - pivotTable.addRowLabel(columnIndex); - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getRowFields().getFieldArray(0).getX(), columnIndex); - assertEquals(defintion.getRowFields().getCount(), 1); - assertEquals(1, pivotTable.getRowLabelColumns().size()); - - columnIndex = 1; - pivotTable.addRowLabel(columnIndex); - assertEquals(2, pivotTable.getRowLabelColumns().size()); - - assertEquals(0, (int)pivotTable.getRowLabelColumns().get(0)); - assertEquals(1, (int)pivotTable.getRowLabelColumns().get(1)); - } - - /** - * Verify that it's not possible to create a row label outside of the referenced area. - */ - @Test - public void testAddRowLabelOutOfRangeThrowsException() { - int columnIndex = 5; - - try { - pivotTable.addRowLabel(columnIndex); - } catch(IndexOutOfBoundsException e) { - return; - } - fail(); - } - - /** - * Verify that when creating one column label, no col fields are being created. - */ - @Test - public void testAddOneColumnLabelToPivotTableDoesNotCreateColField() { - int columnIndex = 0; - - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnIndex); - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getColFields(), null); - } - - /** - * Verify that it's possible to create three column labels with different DataConsolidateFunction - */ - @Test - public void testAddThreeDifferentColumnLabelsToPivotTable() { - int columnOne = 0; - int columnTwo = 1; - int columnThree = 2; - - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnOne); - pivotTable.addColumnLabel(DataConsolidateFunction.MAX, columnTwo); - pivotTable.addColumnLabel(DataConsolidateFunction.MIN, columnThree); - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getDataFields().getDataFieldList().size(), 3); - } - - - /** - * Verify that it's possible to create three column labels with the same DataConsolidateFunction - */ - @Test - public void testAddThreeSametColumnLabelsToPivotTable() { - int columnOne = 0; - int columnTwo = 1; - int columnThree = 2; - - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnOne); - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnTwo); - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnThree); - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getDataFields().getDataFieldList().size(), 3); - } - - /** - * Verify that when creating two column labels, a col field is being created and X is set to -2. - */ - @Test - public void testAddTwoColumnLabelsToPivotTable() { - int columnOne = 0; - int columnTwo = 1; - - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnOne); - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnTwo); - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getColFields().getFieldArray(0).getX(), -2); - } - - /** - * Verify that a data field is created when creating a data column - */ - @Test - public void testColumnLabelCreatesDataField() { - int columnIndex = 0; - - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnIndex); - - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getDataFields().getDataFieldArray(0).getFld(), columnIndex); - assertEquals(defintion.getDataFields().getDataFieldArray(0).getSubtotal(), - STDataConsolidateFunction.Enum.forInt(DataConsolidateFunction.SUM.getValue())); - } - - /** - * Verify that it's possible to set a custom name when creating a data column - */ - @Test - public void testColumnLabelSetCustomName() { - int columnIndex = 0; - - String customName = "Custom Name"; - - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnIndex, customName); - - CTPivotTableDefinition defintion = pivotTable.getCTPivotTableDefinition(); - - assertEquals(defintion.getDataFields().getDataFieldArray(0).getFld(), columnIndex); - assertEquals(defintion.getDataFields().getDataFieldArray(0).getName(), customName); - } - - /** - * Verify that it's not possible to create a column label outside of the referenced area. - */ - @Test - public void testAddColumnLabelOutOfRangeThrowsException() { - int columnIndex = 5; - - try { - pivotTable.addColumnLabel(DataConsolidateFunction.SUM, columnIndex); - } catch(IndexOutOfBoundsException e) { - return; - } - fail(); - } - - /** - * Verify when creating a data column set to a data field, the data field with the corresponding - * column index will be set to true. - */ - @Test - public void testAddDataColumn() { - int columnIndex = 0; - boolean isDataField = true; - - pivotTable.addDataColumn(columnIndex, isDataField); - CTPivotFields pivotFields = pivotTable.getCTPivotTableDefinition().getPivotFields(); - assertEquals(pivotFields.getPivotFieldArray(columnIndex).getDataField(), isDataField); - } - - /** - * Verify that it's not possible to create a data column outside of the referenced area. - */ - @Test - public void testAddDataColumnOutOfRangeThrowsException() { - int columnIndex = 5; - boolean isDataField = true; - - try { - pivotTable.addDataColumn(columnIndex, isDataField); - } catch(IndexOutOfBoundsException e) { - return; - } - fail(); - } - - /** - * Verify that it's possible to create a new filter - */ - @Test - public void testAddReportFilter() { - int columnIndex = 0; - - pivotTable.addReportFilter(columnIndex); - CTPageFields fields = pivotTable.getCTPivotTableDefinition().getPageFields(); - CTPageField field = fields.getPageFieldArray(0); - assertEquals(field.getFld(), columnIndex); - assertEquals(field.getHier(), -1); - assertEquals(fields.getCount(), 1); - } - - /** - * Verify that it's not possible to create a new filter outside of the referenced area. - */ - @Test - public void testAddReportFilterOutOfRangeThrowsException() { - int columnIndex = 5; - try { - pivotTable.addReportFilter(columnIndex); - } catch(IndexOutOfBoundsException e) { - return; - } - fail(); - } - - /** - * Verify that the Pivot Table operates only within the referenced area, even when the - * first column of the referenced area is not index 0. - */ - @Test - public void testAddDataColumnWithOffsetData() { - offsetPivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1); - assertEquals(CellType.NUMERIC, offsetOuterCell.getCellTypeEnum()); - - offsetPivotTable.addColumnLabel(DataConsolidateFunction.SUM, 0); - } - - @Test - public void testPivotTableSheetNamesAreCaseInsensitive() { - wb.setSheetName(0, "original"); - wb.setSheetName(1, "offset"); - XSSFSheet original = wb.getSheet("OriginaL"); - XSSFSheet offset = wb.getSheet("OffseT"); - // assume sheets are accessible via case-insensitive name - assertNotNull(original); - assertNotNull(offset); - - AreaReference source = new AreaReference("ORIGinal!A1:C2", _testDataProvider.getSpreadsheetVersion()); - // create a pivot table on the same sheet, case insensitive - original.createPivotTable(source, new CellReference("W1")); - // create a pivot table on a different sheet, case insensitive - offset.createPivotTable(source, new CellReference("W1")); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java deleted file mode 100644 index ad8b49028..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java +++ /dev/null @@ -1,277 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeNotNull; -import static org.junit.Assume.assumeTrue; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.ss.formula.eval.TestFormulasFromSpreadsheet; -import org.apache.poi.ss.formula.functions.TestMathX; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.junit.AfterClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -/** - * Performs much the same role as {@link TestFormulasFromSpreadsheet}, - * except for a XSSF spreadsheet, not a HSSF one. - * This allows us to check that all our Formula Evaluation code - * is able to work for XSSF, as well as for HSSF. - * - * Periodically, you should open FormulaEvalTestData.xls in - * Excel 2007, and re-save it as FormulaEvalTestData_Copy.xlsx - * - */ -@RunWith(Parameterized.class) -public final class TestFormulaEvaluatorOnXSSF { - private static final POILogger logger = POILogFactory.getLogger(TestFormulaEvaluatorOnXSSF.class); - - private static XSSFWorkbook workbook; - private static Sheet sheet; - private static FormulaEvaluator evaluator; - private static Locale userLocale; - - /** - * This class defines constants for navigating around the test data spreadsheet used for these tests. - */ - private static interface SS { - - /** - * Name of the test spreadsheet (found in the standard test data folder) - */ - String FILENAME = "FormulaEvalTestData_Copy.xlsx"; - /** - * Row (zero-based) in the test spreadsheet where the operator examples start. - */ - int START_OPERATORS_ROW_INDEX = 22; // Row '23' - /** - * Row (zero-based) in the test spreadsheet where the function examples start. - */ - int START_FUNCTIONS_ROW_INDEX = 95; // Row '96' - /** - * Index of the column that contains the function names - */ - int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' - - /** - * Used to indicate when there are no more functions left - */ - String FUNCTION_NAMES_END_SENTINEL = ""; - - /** - * Index of the column where the test values start (for each function) - */ - short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' - - /** - * Each function takes 4 rows in the test spreadsheet - */ - int NUMBER_OF_ROWS_PER_FUNCTION = 4; - } - - @Parameter(value = 0) - public String targetFunctionName; - @Parameter(value = 1) - public int formulasRowIdx; - @Parameter(value = 2) - public int expectedValuesRowIdx; - - @AfterClass - public static void closeResource() throws Exception { - LocaleUtil.setUserLocale(userLocale); - workbook.close(); - } - - @Parameters(name="{0}") - public static Collection data() throws Exception { - // Function "Text" uses custom-formats which are locale specific - // can't set the locale on a per-testrun execution, as some settings have been - // already set, when we would try to change the locale by then - userLocale = LocaleUtil.getUserLocale(); - LocaleUtil.setUserLocale(Locale.ROOT); - - workbook = new XSSFWorkbook( OPCPackage.open(HSSFTestDataSamples.getSampleFile(SS.FILENAME), PackageAccess.READ) ); - sheet = workbook.getSheetAt( 0 ); - evaluator = new XSSFFormulaEvaluator(workbook); - - List data = new ArrayList(); - - processFunctionGroup(data, SS.START_OPERATORS_ROW_INDEX, null); - processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, null); - // example for debugging individual functions/operators: - // processFunctionGroup(data, SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); - // processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, "Text"); - - return data; - } - - /** - * @param startRowIndex row index in the spreadsheet where the first function/operator is found - * @param testFocusFunctionName name of a single function/operator to test alone. - * Typically pass null to test all functions - */ - private static void processFunctionGroup(List data, int startRowIndex, String testFocusFunctionName) { - for (int rowIndex = startRowIndex; true; rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION) { - Row r = sheet.getRow(rowIndex); - - // only evaluate non empty row - if(r == null) continue; - - String targetFunctionName = getTargetFunctionName(r); - assertNotNull("Test spreadsheet cell empty on row (" - + (rowIndex+1) + "). Expected function name or '" - + SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName); - - if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { - // found end of functions list - break; - } - if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { - - // expected results are on the row below - Row expectedValuesRow = sheet.getRow(rowIndex + 1); - // +1 for 1-based, +1 for next row - assertNotNull("Missing expected values row for function '" - + targetFunctionName + " (row " + rowIndex + 2 + ")" - , expectedValuesRow); - - data.add(new Object[]{targetFunctionName, rowIndex, rowIndex + 1}); - } - } - } - - - @Test - public void processFunctionRow() { - Row formulasRow = sheet.getRow(formulasRowIdx); - Row expectedValuesRow = sheet.getRow(expectedValuesRowIdx); - - short endcolnum = formulasRow.getLastCellNum(); - - // iterate across the row for all the evaluation cases - for (short colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) { - Cell c = formulasRow.getCell(colnum); - assumeNotNull(c); - assumeTrue(c.getCellTypeEnum() == CellType.FORMULA); - ignoredFormulaTestCase(c.getCellFormula()); - - CellValue actValue = evaluator.evaluate(c); - Cell expValue = (expectedValuesRow == null) ? null : expectedValuesRow.getCell(colnum); - - String msg = String.format(Locale.ROOT, "Function '%s': Formula: %s @ %d:%d" - , targetFunctionName, c.getCellFormula(), formulasRow.getRowNum(), colnum); - - assertNotNull(msg + " - Bad setup data expected value is null", expValue); - assertNotNull(msg + " - actual value was null", actValue); - - final CellType expectedCellType = expValue.getCellTypeEnum(); - switch (expectedCellType) { - case BLANK: - assertEquals(msg, CellType.BLANK, actValue.getCellTypeEnum()); - break; - case BOOLEAN: - assertEquals(msg, CellType.BOOLEAN, actValue.getCellTypeEnum()); - assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue()); - break; - case ERROR: - assertEquals(msg, CellType.ERROR, actValue.getCellTypeEnum()); -// if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values -// assertEquals(msg, expValue.getErrorCellValue(), actValue.getErrorValue()); -// } - break; - case FORMULA: // will never be used, since we will call method after formula evaluation - fail("Cannot expect formula as result of formula evaluation: " + msg); - case NUMERIC: - assertEquals(msg, CellType.NUMERIC, actValue.getCellTypeEnum()); - TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); -// double delta = Math.abs(expValue.getNumericCellValue()-actValue.getNumberValue()); -// double pctExpValue = Math.abs(0.00001*expValue.getNumericCellValue()); -// assertTrue(msg, delta <= pctExpValue); - break; - case STRING: - assertEquals(msg, CellType.STRING, actValue.getCellTypeEnum()); - assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue()); - break; - default: - fail("Unexpected cell type: " + expectedCellType); - } - } - } - - /* - * TODO - these are all formulas which currently (Apr-2008) break on ooxml - */ - private static void ignoredFormulaTestCase(String cellFormula) { - // full row ranges are not parsed properly yet. - // These cases currently work in svn trunk because of another bug which causes the - // formula to get rendered as COLUMN($A$1:$IV$2) or ROW($A$2:$IV$3) - assumeFalse("COLUMN(1:2)".equals(cellFormula)); - assumeFalse("ROW(2:3)".equals(cellFormula)); - - // currently throws NPE because unknown function "currentcell" causes name lookup - // Name lookup requires some equivalent object of the Workbook within xSSFWorkbook. - assumeFalse("ISREF(currentcell())".equals(cellFormula)); - } - - /** - * @return null if cell is missing, empty or blank - */ - private static String getTargetFunctionName(Row r) { - if(r == null) { - logger.log(POILogger.WARN, "Warning - given null row, can't figure out function name"); - return null; - } - Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME); - if(cell == null) { - logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name"); - return null; - } - if(cell.getCellTypeEnum() == CellType.BLANK) { - return null; - } - if(cell.getCellTypeEnum() == CellType.STRING) { - return cell.getRichStringCellValue().getString(); - } - - fail("Bad cell type for 'function name' column: ("+cell.getColumnIndex()+") row ("+(r.getRowNum()+1)+")"); - return null; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMissingWorkbookOnXSSF.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMissingWorkbookOnXSSF.java deleted file mode 100644 index 2427dd1d8..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMissingWorkbookOnXSSF.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.HSSFTestDataSamples; -import org.apache.poi.ss.formula.TestMissingWorkbook; -import org.apache.poi.xssf.XSSFTestDataSamples; - -/** - * XSSF Specific version of the Missing Workbooks test - */ -public final class TestMissingWorkbookOnXSSF extends TestMissingWorkbook { - public TestMissingWorkbookOnXSSF() { - super("52575_main.xlsx", "source_dummy.xlsx", "52575_source.xls"); - } - - @Override - protected void setUp() throws Exception { - mainWorkbook = XSSFTestDataSamples.openSampleWorkbook(MAIN_WORKBOOK_FILENAME); - sourceWorkbook = HSSFTestDataSamples.openSampleWorkbook(SOURCE_WORKBOOK_FILENAME); - - assertNotNull(mainWorkbook); - assertNotNull(sourceWorkbook); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java deleted file mode 100644 index b8926a3cf..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java +++ /dev/null @@ -1,270 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeNotNull; -import static org.junit.Assume.assumeTrue; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.ss.formula.eval.TestFormulasFromSpreadsheet; -import org.apache.poi.ss.formula.functions.TestMathX; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.junit.AfterClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -/** - * Tests formulas for multi sheet reference (i.e. SUM(Sheet1:Sheet5!A1)) - */ -@RunWith(Parameterized.class) -public final class TestMultiSheetFormulaEvaluatorOnXSSF { - private static final POILogger logger = POILogFactory.getLogger(TestFormulasFromSpreadsheet.class); - - private static XSSFWorkbook workbook; - private static Sheet sheet; - private static FormulaEvaluator evaluator; - - /** - * This class defines constants for navigating around the test data spreadsheet used for these tests. - */ - interface SS { - - /** - * Name of the test spreadsheet (found in the standard test data folder) - */ - String FILENAME = "FormulaSheetRange.xlsx"; - /** - * Row (zero-based) in the test spreadsheet where the function examples start. - */ - int START_FUNCTIONS_ROW_INDEX = 10; // Row '11' - /** - * Index of the column that contains the function names - */ - int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A' - /** - * Index of the column that contains the test names - */ - int COLUMN_INDEX_TEST_NAME = 1; // Column 'B' - /** - * Used to indicate when there are no more functions left - */ - String FUNCTION_NAMES_END_SENTINEL = ""; - - /** - * Index of the column where the test expected value is present - */ - short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C' - /** - * Index of the column where the test actual value is present - */ - short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D' - /** - * Test sheet name (sheet with all test formulae) - */ - String TEST_SHEET_NAME = "test"; - } - - @Parameter(value = 0) - public String targetTestName; - @Parameter(value = 1) - public String targetFunctionName; - @Parameter(value = 2) - public int formulasRowIdx; - - @AfterClass - public static void closeResource() throws Exception { - workbook.close(); - } - - @Parameters(name="{0}") - public static Collection data() throws Exception { - workbook = new XSSFWorkbook( OPCPackage.open(HSSFTestDataSamples.getSampleFile(SS.FILENAME), PackageAccess.READ) ); - sheet = workbook.getSheet( SS.TEST_SHEET_NAME ); - evaluator = new XSSFFormulaEvaluator(workbook); - - List data = new ArrayList(); - - processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, null); - - return data; - } - - /** - * @param startRowIndex row index in the spreadsheet where the first function/operator is found - * @param testFocusFunctionName name of a single function/operator to test alone. - * Typically pass null to test all functions - */ - private static void processFunctionGroup(List data, int startRowIndex, String testFocusFunctionName) { - for (int rowIndex = startRowIndex; true; rowIndex++) { - Row r = sheet.getRow(rowIndex); - - // only evaluate non empty row - if(r == null) continue; - - String targetFunctionName = getTargetFunctionName(r); - assertNotNull("Test spreadsheet cell empty on row (" - + (rowIndex+1) + "). Expected function name or '" - + SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName); - - if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { - // found end of functions list - break; - } - - String targetTestName = getTargetTestName(r); - if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { - - // expected results are on the row below - Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE); - assertNotNull("Missing expected values cell for function '" - + targetFunctionName + ", test" + targetTestName + " (row " + - rowIndex + 1 + ")", expectedValueCell); - - data.add(new Object[]{targetTestName, targetFunctionName, rowIndex}); - } - } - } - - /** - * - * @return a constant from the local Result class denoting whether there were any evaluation - * cases, and whether they all succeeded. - */ - @Test - public void processFunctionRow() { - Row r = sheet.getRow(formulasRowIdx); - - Cell expValue = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE); - assertNotNull("Missing expected values cell for function '" - + targetFunctionName + ", test" + targetTestName + " (row " + - formulasRowIdx + 1 + ")", expValue); - - Cell c = r.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE); - assumeNotNull(c); - assumeTrue(c.getCellTypeEnum() == CellType.FORMULA); - - CellValue actValue = evaluator.evaluate(c); - - String msg = String.format(Locale.ROOT, "Function '%s': Test: '%s': Formula: %s @ %d:%d", - targetFunctionName, targetTestName, c.getCellFormula(), formulasRowIdx, SS.COLUMN_INDEX_ACTUAL_VALUE); - - assertNotNull(msg + " - actual value was null", actValue); - - final CellType expectedCellType = expValue.getCellTypeEnum(); - switch (expectedCellType) { - case BLANK: - assertEquals(msg, CellType.BLANK, actValue.getCellTypeEnum()); - break; - case BOOLEAN: - assertEquals(msg, CellType.BOOLEAN, actValue.getCellTypeEnum()); - assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue()); - break; - case ERROR: - assertEquals(msg, CellType.ERROR, actValue.getCellTypeEnum()); -// if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values -// assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue()); -// } - break; - case FORMULA: // will never be used, since we will call method after formula evaluation - fail("Cannot expect formula as result of formula evaluation: " + msg); - case NUMERIC: - assertEquals(msg, CellType.NUMERIC, actValue.getCellTypeEnum()); - TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); -// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue()); -// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue()); -// assertTrue(msg, delta <= pctExpected); - break; - case STRING: - assertEquals(msg, CellType.STRING, actValue.getCellTypeEnum()); - assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue()); - break; - default: - fail("Unexpected cell type: " + expectedCellType); - } - } - - /** - * @return null if cell is missing, empty or blank - */ - private static String getTargetFunctionName(Row r) { - if(r == null) { - logger.log(POILogger.WARN, "Warning - given null row, can't figure out function name"); - return null; - } - Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME); - if(cell == null) { - logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name"); - return null; - } - if(cell.getCellTypeEnum() == CellType.BLANK) { - return null; - } - if(cell.getCellTypeEnum() == CellType.STRING) { - return cell.getRichStringCellValue().getString(); - } - - fail("Bad cell type for 'function name' column: (" - + cell.getCellTypeEnum() + ") row (" + (r.getRowNum() +1) + ")"); - return ""; - } - /** - * @return null if cell is missing, empty or blank - */ - private static String getTargetTestName(Row r) { - if(r == null) { - logger.log(POILogger.WARN, "Warning - given null row, can't figure out test name"); - return null; - } - Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME); - if(cell == null) { - logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name"); - return null; - } - if(cell.getCellTypeEnum() == CellType.BLANK) { - return null; - } - if(cell.getCellTypeEnum() == CellType.STRING) { - return cell.getRichStringCellValue().getString(); - } - - fail("Bad cell type for 'test name' column: (" - + cell.getCellTypeEnum() + ") row (" + (r.getRowNum() +1) + ")"); - return ""; - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java deleted file mode 100644 index af58706a7..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.fail; -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; -import org.apache.poi.ss.usermodel.PrintSetup; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.junit.Ignore; -import org.junit.Test; - -public final class TestSXSSFBugs extends BaseTestBugzillaIssues { - public TestSXSSFBugs() { - super(SXSSFITestDataProvider.instance); - } - - // override some tests which do not work for SXSSF - @Override @Ignore("cloneSheet() not implemented") @Test public void bug18800() { /* cloneSheet() not implemented */ } - @Override @Ignore("cloneSheet() not implemented") @Test public void bug22720() { /* cloneSheet() not implemented */ } - @Override @Ignore("Evaluation is not fully supported") @Test public void bug47815() { /* Evaluation is not supported */ } - @Override @Ignore("Evaluation is not fully supported") @Test public void test58113() { /* Evaluation is not supported */ } - @Override @Ignore("Evaluation is not fully supported") @Test public void bug46729_testMaxFunctionArguments() { /* Evaluation is not supported */ } - @Override @Ignore("Reading data is not supported") @Test public void bug57798() { /* Reading data is not supported */ } - - /** - * Setting repeating rows and columns shouldn't break - * any print settings that were there before - */ - @Test - public void bug49253() throws Exception { - Workbook wb1 = new SXSSFWorkbook(); - Workbook wb2 = new SXSSFWorkbook(); - CellRangeAddress cra = CellRangeAddress.valueOf("C2:D3"); - - // No print settings before repeating - Sheet s1 = wb1.createSheet(); - s1.setRepeatingColumns(cra); - s1.setRepeatingRows(cra); - - PrintSetup ps1 = s1.getPrintSetup(); - assertEquals(false, ps1.getValidSettings()); - assertEquals(false, ps1.getLandscape()); - - - // Had valid print settings before repeating - Sheet s2 = wb2.createSheet(); - PrintSetup ps2 = s2.getPrintSetup(); - - ps2.setLandscape(false); - assertEquals(true, ps2.getValidSettings()); - assertEquals(false, ps2.getLandscape()); - s2.setRepeatingColumns(cra); - s2.setRepeatingRows(cra); - - ps2 = s2.getPrintSetup(); - assertEquals(true, ps2.getValidSettings()); - assertEquals(false, ps2.getLandscape()); - - wb1.close(); - wb2.close(); - } - - // bug 60197: setSheetOrder should update sheet-scoped named ranges to maintain references to the sheets before the re-order - @Test - @Override - public void bug60197_NamedRangesReferToCorrectSheetWhenSheetOrderIsChanged() throws Exception { - try { - super.bug60197_NamedRangesReferToCorrectSheetWhenSheetOrderIsChanged(); - } catch (final RuntimeException e) { - final Throwable cause = e.getCause(); - if (cause instanceof IOException && cause.getMessage().equals("Stream closed")) { - // expected on the second time that _testDataProvider.writeOutAndReadBack(SXSSFWorkbook) is called - // if the test makes it this far, then we know that XSSFName sheet indices are updated when sheet - // order is changed, which is the purpose of this test. Therefore, consider this a passing test. - } else { - throw e; - } - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetHiding.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetHiding.java deleted file mode 100644 index f6b4e632b..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetHiding.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.xssf.XSSFITestDataProvider; -import org.apache.poi.ss.usermodel.BaseTestSheetHiding; - -public final class TestSheetHiding extends BaseTestSheetHiding { - public TestSheetHiding() { - super(XSSFITestDataProvider.instance, - "TwoSheetsOneHidden.xlsx", "TwoSheetsNoneHidden.xlsx"); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java deleted file mode 100644 index 874db823d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java +++ /dev/null @@ -1,400 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.Calendar; -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellUtil; -import org.apache.poi.ss.util.RegionUtil; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; - -/** - * @author centic - * - * This testcase contains tests for bugs that are yet to be fixed. Therefore, - * the standard ant test target does not run these tests. Run this testcase with - * the single-test target. The names of the tests usually correspond to the - * Bugzilla id's PLEASE MOVE tests from this class to TestBugs once the bugs are - * fixed, so that they are then run automatically. - */ -public final class TestUnfixedBugs { - @Test - public void testBug54084Unicode() throws IOException { - // sample XLSX with the same text-contents as the text-file above - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("54084 - Greek - beyond BMP.xlsx"); - - verifyBug54084Unicode(wb); - -// OutputStream baos = new FileOutputStream("/tmp/test.xlsx"); -// try { -// wb.write(baos); -// } finally { -// baos.close(); -// } - - // now write the file and read it back in - XSSFWorkbook wbWritten = XSSFTestDataSamples.writeOutAndReadBack(wb); - verifyBug54084Unicode(wbWritten); - - // finally also write it out via the streaming interface and verify that we still can read it back in - SXSSFWorkbook swb = new SXSSFWorkbook(wb); - Workbook wbStreamingWritten = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb); - verifyBug54084Unicode(wbStreamingWritten); - - wbWritten.close(); - swb.close(); - wbStreamingWritten.close(); - wb.close(); - } - - private void verifyBug54084Unicode(Workbook wb) { - // expected data is stored in UTF-8 in a text-file - byte data[] = HSSFTestDataSamples.getTestDataFileContent("54084 - Greek - beyond BMP.txt"); - String testData = new String(data, Charset.forName("UTF-8")).trim(); - - Sheet sheet = wb.getSheetAt(0); - Row row = sheet.getRow(0); - Cell cell = row.getCell(0); - - String value = cell.getStringCellValue(); - //System.out.println(value); - - assertEquals("The data in the text-file should exactly match the data that we read from the workbook", testData, value); - } - - @Test - public void test54071() throws Exception { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("54071.xlsx"); - Sheet sheet = workbook.getSheetAt(0); - int rows = sheet.getPhysicalNumberOfRows(); - System.out.println(">> file rows is:"+(rows-1)+" <<"); - Row title = sheet.getRow(0); - - Date prev = null; - for (int row = 1; row < rows; row++) { - Row rowObj = sheet.getRow(row); - for (int col = 0; col < 1; col++) { - String titleName = title.getCell(col).toString(); - Cell cell = rowObj.getCell(col); - if (titleName.startsWith("time")) { - // here the output will produce ...59 or ...58 for the rows, probably POI is - // doing some different rounding or some other small difference... - System.out.println("==Time:"+cell.getDateCellValue()); - if(prev != null) { - assertEquals(prev, cell.getDateCellValue()); - } - - prev = cell.getDateCellValue(); - } - } - } - - workbook.close(); - } - - @Test - public void test54071Simple() { - double value1 = 41224.999988425923; - double value2 = 41224.999988368058; - - int wholeDays1 = (int)Math.floor(value1); - int millisecondsInDay1 = (int)((value1 - wholeDays1) * DateUtil.DAY_MILLISECONDS + 0.5); - - int wholeDays2 = (int)Math.floor(value2); - int millisecondsInDay2 = (int)((value2 - wholeDays2) * DateUtil.DAY_MILLISECONDS + 0.5); - - assertEquals(wholeDays1, wholeDays2); - // here we see that the time-value is 5 milliseconds apart, one is 86399000 and the other is 86398995, - // thus one is one second higher than the other - assertEquals("The time-values are 5 milliseconds apart", - millisecondsInDay1, millisecondsInDay2); - - // when we do the calendar-stuff, there is a boolean which determines if - // the milliseconds are rounded or not, having this at "false" causes the - // second to be different here! - int startYear = 1900; - int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't - Calendar calendar1 = LocaleUtil.getLocaleCalendar(startYear,0, wholeDays1 + dayAdjust); - calendar1.set(Calendar.MILLISECOND, millisecondsInDay1); - // this is the rounding part: - calendar1.add(Calendar.MILLISECOND, 500); - calendar1.clear(Calendar.MILLISECOND); - - Calendar calendar2 = LocaleUtil.getLocaleCalendar(startYear,0, wholeDays2 + dayAdjust); - calendar2.set(Calendar.MILLISECOND, millisecondsInDay2); - // this is the rounding part: - calendar2.add(Calendar.MILLISECOND, 500); - calendar2.clear(Calendar.MILLISECOND); - - // now the calendars are equal - assertEquals(calendar1, calendar2); - - assertEquals(DateUtil.getJavaDate(value1, false), DateUtil.getJavaDate(value2, false)); - } - - // When this is fixed, the test case should go to BaseTestXCell with - // adjustments to use _testDataProvider to also verify this for XSSF - @Test - public void testBug57294() throws IOException { - Workbook wb = SXSSFITestDataProvider.instance.createWorkbook(); - - Sheet sheet = wb.createSheet(); - Row row = sheet.createRow(0); - Cell cell = row.createCell(0); - - RichTextString str = new XSSFRichTextString("Test rich text string"); - str.applyFont(2, 4, (short)0); - assertEquals(3, str.numFormattingRuns()); - cell.setCellValue(str); - - Workbook wbBack = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb); - wb.close(); - - // re-read after serializing and reading back - Cell cellBack = wbBack.getSheetAt(0).getRow(0).getCell(0); - assertNotNull(cellBack); - RichTextString strBack = cellBack.getRichStringCellValue(); - assertNotNull(strBack); - assertEquals(3, strBack.numFormattingRuns()); - assertEquals(0, strBack.getIndexOfFormattingRun(0)); - assertEquals(2, strBack.getIndexOfFormattingRun(1)); - assertEquals(4, strBack.getIndexOfFormattingRun(2)); - - wbBack.close(); - } - - @Test - public void testBug55752() throws IOException { - Workbook wb = new XSSFWorkbook(); - try { - Sheet sheet = wb.createSheet("test"); - - for (int i = 0; i < 4; i++) { - Row row = sheet.createRow(i); - for (int j = 0; j < 2; j++) { - Cell cell = row.createCell(j); - cell.setCellStyle(wb.createCellStyle()); - } - } - - // set content - Row row1 = sheet.getRow(0); - row1.getCell(0).setCellValue("AAA"); - Row row2 = sheet.getRow(1); - row2.getCell(0).setCellValue("BBB"); - Row row3 = sheet.getRow(2); - row3.getCell(0).setCellValue("CCC"); - Row row4 = sheet.getRow(3); - row4.getCell(0).setCellValue("DDD"); - - // merge cells - CellRangeAddress range1 = new CellRangeAddress(0, 0, 0, 1); - sheet.addMergedRegion(range1); - CellRangeAddress range2 = new CellRangeAddress(1, 1, 0, 1); - sheet.addMergedRegion(range2); - CellRangeAddress range3 = new CellRangeAddress(2, 2, 0, 1); - sheet.addMergedRegion(range3); - assertEquals(0, range3.getFirstColumn()); - assertEquals(1, range3.getLastColumn()); - assertEquals(2, range3.getLastRow()); - CellRangeAddress range4 = new CellRangeAddress(3, 3, 0, 1); - sheet.addMergedRegion(range4); - - // set border - RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, range1, sheet, wb); - - row2.getCell(0).getCellStyle().setBorderBottom(CellStyle.BORDER_THIN); - row2.getCell(1).getCellStyle().setBorderBottom(CellStyle.BORDER_THIN); - - Cell cell0 = CellUtil.getCell(row3, 0); - CellUtil.setCellStyleProperty(cell0, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN); - Cell cell1 = CellUtil.getCell(row3, 1); - CellUtil.setCellStyleProperty(cell1, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN); - - RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, range4, sheet, wb); - - // write to file - OutputStream stream = new FileOutputStream(new File("C:/temp/55752.xlsx")); - try { - wb.write(stream); - } finally { - stream.close(); - } - } finally { - wb.close(); - } - } - - @Test - public void test57423() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57423.xlsx"); - - Sheet testSheet = wb.getSheetAt(0); - - // row shift (negative or positive) causes corrupted output xlsx file when the shift value is bigger - // than the number of rows being shifted - // Excel 2010 on opening the output file says: - // "Excel found unreadable content" and offers recovering the file by removing the unreadable content - // This can be observed in cases like the following: - // negative shift of 1 row by less than -1 - // negative shift of 2 rows by less than -2 - // positive shift of 1 row by 2 or more - // positive shift of 2 rows by 3 or more - - //testSheet.shiftRows(4, 5, -3); - testSheet.shiftRows(10, 10, 2); - - checkRows57423(testSheet); - - Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - - /*FileOutputStream stream = new FileOutputStream("C:\\temp\\57423.xlsx"); - try { - wb.write(stream); - } finally { - stream.close(); - }*/ - - wb.close(); - - checkRows57423(wbBack.getSheetAt(0)); - - wbBack.close(); - } - - private void checkRows57423(Sheet testSheet) throws IOException { - checkRow57423(testSheet, 0, "0"); - checkRow57423(testSheet, 1, "1"); - checkRow57423(testSheet, 2, "2"); - checkRow57423(testSheet, 3, "3"); - checkRow57423(testSheet, 4, "4"); - checkRow57423(testSheet, 5, "5"); - checkRow57423(testSheet, 6, "6"); - checkRow57423(testSheet, 7, "7"); - checkRow57423(testSheet, 8, "8"); - checkRow57423(testSheet, 9, "9"); - - assertNull("Row number 10 should be gone after the shift", - testSheet.getRow(10)); - - checkRow57423(testSheet, 11, "11"); - checkRow57423(testSheet, 12, "10"); - checkRow57423(testSheet, 13, "13"); - checkRow57423(testSheet, 14, "14"); - checkRow57423(testSheet, 15, "15"); - checkRow57423(testSheet, 16, "16"); - checkRow57423(testSheet, 17, "17"); - checkRow57423(testSheet, 18, "18"); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - ((XSSFSheet)testSheet).write(stream); - } finally { - stream.close(); - } - - // verify that the resulting XML has the rows in correct order as required by Excel - String xml = new String(stream.toByteArray(), "UTF-8"); - int posR12 = xml.indexOf(" shapes = drawing.getShapes(); - str.append("drawing.getShapes().size() = " + shapes.size()); - Iterator it = shapes.iterator(); - while(it.hasNext()) { - XSSFShape shape = it.next(); - str.append(", " + shape.toString()); - str.append(", Col1:"+((XSSFClientAnchor)shape.getAnchor()).getCol1()); - str.append(", Col2:"+((XSSFClientAnchor)shape.getAnchor()).getCol2()); - str.append(", Row1:"+((XSSFClientAnchor)shape.getAnchor()).getRow1()); - str.append(", Row2:"+((XSSFClientAnchor)shape.getAnchor()).getRow2()); - } - - assertEquals("Having shapes: " + str, - expectedShapes, shapes.size()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java deleted file mode 100644 index 6cf7003ce..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ /dev/null @@ -1,3190 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.*; -import java.util.Arrays; -import java.util.Calendar; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeMap; - -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLDocumentPart.RelationPart; -import org.apache.poi.POIXMLException; -import org.apache.poi.POIXMLProperties; -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -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.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.util.ZipSecureFile; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.formula.eval.ErrorEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; -import org.apache.poi.ss.formula.functions.Function; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.CellUtil; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.XLSBUnsupportedException; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.CalculationChain; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; -import org.apache.xmlbeans.XmlException; -import org.junit.Ignore; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl; - -@SuppressWarnings("deprecation") -public final class TestXSSFBugs extends BaseTestBugzillaIssues { - public TestXSSFBugs() { - super(XSSFITestDataProvider.instance); - } - - /** - * test writing a file with large number of unique strings, - * open resulting file in Excel to check results! - */ - @Test - public void bug15375_2() throws IOException { - bug15375(1000); - } - - /** - * Named ranges had the right reference, but - * the wrong sheet name - */ - @Test - public void bug45430() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("45430.xlsx"); - assertFalse(wb.isMacroEnabled()); - assertEquals(3, wb.getNumberOfNames()); - - assertEquals(0, wb.getName("SheetAA1").getCTName().getLocalSheetId()); - assertFalse(wb.getName("SheetAA1").getCTName().isSetLocalSheetId()); - assertEquals("SheetA!$A$1", wb.getName("SheetAA1").getRefersToFormula()); - assertEquals("SheetA", wb.getName("SheetAA1").getSheetName()); - - assertEquals(0, wb.getName("SheetBA1").getCTName().getLocalSheetId()); - assertFalse(wb.getName("SheetBA1").getCTName().isSetLocalSheetId()); - assertEquals("SheetB!$A$1", wb.getName("SheetBA1").getRefersToFormula()); - assertEquals("SheetB", wb.getName("SheetBA1").getSheetName()); - - assertEquals(0, wb.getName("SheetCA1").getCTName().getLocalSheetId()); - assertFalse(wb.getName("SheetCA1").getCTName().isSetLocalSheetId()); - assertEquals("SheetC!$A$1", wb.getName("SheetCA1").getRefersToFormula()); - assertEquals("SheetC", wb.getName("SheetCA1").getSheetName()); - - // Save and re-load, still there - XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertEquals(3, nwb.getNumberOfNames()); - assertEquals("SheetA!$A$1", nwb.getName("SheetAA1").getRefersToFormula()); - - nwb.close(); - wb.close(); - } - - /** - * We should carry vba macros over after save - */ - @Test - public void bug45431() throws IOException, InvalidFormatException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("45431.xlsm"); - OPCPackage pkg1 = wb1.getPackage(); - assertTrue(wb1.isMacroEnabled()); - - // Check the various macro related bits can be found - PackagePart vba = pkg1.getPart( - PackagingURIHelper.createPartName("/xl/vbaProject.bin") - ); - assertNotNull(vba); - // And the drawing bit - PackagePart drw = pkg1.getPart( - PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") - ); - assertNotNull(drw); - - - // Save and re-open, both still there - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - pkg1.close(); - wb1.close(); - - OPCPackage pkg2 = wb2.getPackage(); - assertTrue(wb2.isMacroEnabled()); - - vba = pkg2.getPart( - PackagingURIHelper.createPartName("/xl/vbaProject.bin") - ); - assertNotNull(vba); - drw = pkg2.getPart( - PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") - ); - assertNotNull(drw); - - // And again, just to be sure - XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - pkg2.close(); - wb2.close(); - OPCPackage pkg3 = wb3.getPackage(); - assertTrue(wb3.isMacroEnabled()); - - vba = pkg3.getPart( - PackagingURIHelper.createPartName("/xl/vbaProject.bin") - ); - assertNotNull(vba); - drw = pkg3.getPart( - PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") - ); - assertNotNull(drw); - - pkg3.close(); - wb3.close(); - } - - @Test - public void bug47504() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("47504.xlsx"); - assertEquals(1, wb1.getNumberOfSheets()); - XSSFSheet sh = wb1.getSheetAt(0); - XSSFDrawing drawing = sh.createDrawingPatriarch(); - List rels = drawing.getRelationParts(); - assertEquals(1, rels.size()); - assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment()); - - // And again, just to be sure - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - assertEquals(1, wb2.getNumberOfSheets()); - sh = wb2.getSheetAt(0); - drawing = sh.createDrawingPatriarch(); - rels = drawing.getRelationParts(); - assertEquals(1, rels.size()); - assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment()); - wb2.close(); - } - - /** - * Excel will sometimes write a button with a textbox - * containing >br< (not closed!). - * Clearly Excel shouldn't do this, but test that we can - * read the file despite the naughtyness - */ - @Test - public void bug49020() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx"); - wb.close(); - } - - /** - * ensure that CTPhoneticPr is loaded by the ooxml test suite so that it is included in poi-ooxml-schemas - */ - @Test - public void bug49325() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49325.xlsx"); - CTWorksheet sh = wb.getSheetAt(0).getCTWorksheet(); - assertNotNull(sh.getPhoneticPr()); - wb.close(); - } - - /** - * Names which are defined with a Sheet - * should return that sheet index properly - */ - @Test - public void bug48923() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48923.xlsx"); - assertEquals(4, wb.getNumberOfNames()); - - Name b1 = wb.getName("NameB1"); - Name b2 = wb.getName("NameB2"); - Name sheet2 = wb.getName("NameSheet2"); - Name test = wb.getName("Test"); - - assertNotNull(b1); - assertEquals("NameB1", b1.getNameName()); - assertEquals("Sheet1", b1.getSheetName()); - assertEquals(-1, b1.getSheetIndex()); - - assertNotNull(b2); - assertEquals("NameB2", b2.getNameName()); - assertEquals("Sheet1", b2.getSheetName()); - assertEquals(-1, b2.getSheetIndex()); - - assertNotNull(sheet2); - assertEquals("NameSheet2", sheet2.getNameName()); - assertEquals("Sheet2", sheet2.getSheetName()); - assertEquals(-1, sheet2.getSheetIndex()); - - assertNotNull(test); - assertEquals("Test", test.getNameName()); - assertEquals("Sheet1", test.getSheetName()); - assertEquals(-1, test.getSheetIndex()); - - wb.close(); - } - - /** - * Problem with evaluation formulas due to - * NameXPtgs. - * Blows up on: - * IF(B6= (ROUNDUP(B6,0) + ROUNDDOWN(B6,0))/2, MROUND(B6,2),ROUND(B6,0)) - * - * TODO: delete this test case when MROUND and VAR are implemented - */ - @Test - public void bug48539() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48539.xlsx"); - try { - assertEquals(3, wb.getNumberOfSheets()); - assertEquals(0, wb.getNumberOfNames()); - - // Try each cell individually - XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb); - for(int i=0; i rels0 = sh0.getRelationParts(); - List rels1 = sh1.getRelationParts(); - assertEquals(1, rels0.size()); - assertEquals(1, rels1.size()); - - PackageRelationship pr0 = rels0.get(0).getRelationship(); - PackageRelationship pr1 = rels1.get(0).getRelationship(); - - assertEquals(pr0.getTargetMode(), pr1.getTargetMode()); - assertEquals(pr0.getTargetURI(), pr1.getTargetURI()); - POIXMLDocumentPart doc0 = rels0.get(0).getDocumentPart(); - POIXMLDocumentPart doc1 = rels1.get(0).getDocumentPart(); - - assertEquals(doc0, doc1); - wb.close(); - } - - /** - * Add comments to Sheet 1, when Sheet 2 already has - * comments (so /xl/comments1.xml is taken) - */ - @Test - public void bug51850() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("51850.xlsx"); - XSSFSheet sh1 = wb1.getSheetAt(0); - XSSFSheet sh2 = wb1.getSheetAt(1); - - // Sheet 2 has comments - assertNotNull(sh2.getCommentsTable(false)); - assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments()); - - // Sheet 1 doesn't (yet) - assertNull(sh1.getCommentsTable(false)); - - // Try to add comments to Sheet 1 - CreationHelper factory = wb1.getCreationHelper(); - Drawing drawing = sh1.createDrawingPatriarch(); - - ClientAnchor anchor = factory.createClientAnchor(); - anchor.setCol1(0); - anchor.setCol2(4); - anchor.setRow1(0); - anchor.setRow2(1); - - Comment comment1 = drawing.createCellComment(anchor); - comment1.setString( - factory.createRichTextString("I like this cell. It's my favourite.")); - comment1.setAuthor("Bob T. Fish"); - - anchor = factory.createClientAnchor(); - anchor.setCol1(0); - anchor.setCol2(4); - anchor.setRow1(1); - anchor.setRow2(1); - Comment comment2 = drawing.createCellComment(anchor); - comment2.setString( - factory.createRichTextString("This is much less fun...")); - comment2.setAuthor("Bob T. Fish"); - - Cell c1 = sh1.getRow(0).createCell(4); - c1.setCellValue(2.3); - c1.setCellComment(comment1); - - Cell c2 = sh1.getRow(0).createCell(5); - c2.setCellValue(2.1); - c2.setCellComment(comment2); - - - // Save and re-load - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sh1 = wb2.getSheetAt(0); - sh2 = wb2.getSheetAt(1); - - // Check the comments - assertNotNull(sh2.getCommentsTable(false)); - assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments()); - - assertNotNull(sh1.getCommentsTable(false)); - assertEquals(2, sh1.getCommentsTable(false).getNumberOfComments()); - wb2.close(); - } - - /** - * Sheet names with a , in them - */ - @Test - public void bug51963() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51963.xlsx"); - Sheet sheet = wb.getSheetAt(0); - assertEquals("Abc,1", sheet.getSheetName()); - - Name name = wb.getName("Intekon.ProdCodes"); - assertEquals("'Abc,1'!$A$1:$A$2", name.getRefersToFormula()); - - @SuppressWarnings("deprecation") - AreaReference ref = new AreaReference(name.getRefersToFormula()); - assertEquals(0, ref.getFirstCell().getRow()); - assertEquals(0, ref.getFirstCell().getCol()); - assertEquals(1, ref.getLastCell().getRow()); - assertEquals(0, ref.getLastCell().getCol()); - wb.close(); - } - - /** - * Sum across multiple workbooks - * eg =SUM($Sheet1.C1:$Sheet4.C1) - */ - @Test - public void bug48703() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48703.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - - // Contains two forms, one with a range and one a list - XSSFRow r1 = sheet.getRow(0); - XSSFRow r2 = sheet.getRow(1); - XSSFCell c1 = r1.getCell(1); - XSSFCell c2 = r2.getCell(1); - - assertEquals(20.0, c1.getNumericCellValue(), 0); - assertEquals("SUM(Sheet1!C1,Sheet2!C1,Sheet3!C1,Sheet4!C1)", c1.getCellFormula()); - - assertEquals(20.0, c2.getNumericCellValue(), 0); - assertEquals("SUM(Sheet1:Sheet4!C1)", c2.getCellFormula()); - - // Try evaluating both - XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb); - eval.evaluateFormulaCellEnum(c1); - eval.evaluateFormulaCellEnum(c2); - - assertEquals(20.0, c1.getNumericCellValue(), 0); - assertEquals(20.0, c2.getNumericCellValue(), 0); - wb.close(); - } - - /** - * Bugzilla 51710: problems reading shared formuals from .xlsx - */ - @Test - public void bug51710() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51710.xlsx"); - - final String[] columns = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N"}; - final int rowMax = 500; // bug triggers on row index 59 - - Sheet sheet = wb.getSheetAt(0); - - - // go through all formula cells - for (int rInd = 2; rInd <= rowMax; rInd++) { - Row row = sheet.getRow(rInd); - - for (int cInd = 1; cInd <= 12; cInd++) { - Cell cell = row.getCell(cInd); - String formula = cell.getCellFormula(); - CellReference ref = new CellReference(cell); - - //simulate correct answer - String correct = "$A" + (rInd + 1) + "*" + columns[cInd] + "$2"; - - assertEquals("Incorrect formula in " + ref.formatAsString(), correct, formula); - } - - } - wb.close(); - } - - /** - * Bug 53101: - */ - @Test - public void bug5301() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53101.xlsx"); - FormulaEvaluator evaluator = - wb.getCreationHelper().createFormulaEvaluator(); - // A1: SUM(B1: IZ1) - double a1Value = - evaluator.evaluate(wb.getSheetAt(0).getRow(0).getCell(0)).getNumberValue(); - - // Assert - assertEquals(259.0, a1Value, 0.0); - - // KY: SUM(B1: IZ1) - /*double ky1Value =*/ - evaluator.evaluate(wb.getSheetAt(0).getRow(0).getCell(310)).getNumberValue(); - - // Assert - assertEquals(259.0, a1Value, 0.0); - wb.close(); - } - - @Test - public void bug54436() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("54436.xlsx"); - if(!WorkbookEvaluator.getSupportedFunctionNames().contains("GETPIVOTDATA")){ - Function func = new Function() { - @Override - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - return ErrorEval.NA; - } - }; - - WorkbookEvaluator.registerFunction("GETPIVOTDATA", func); - } - wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); - wb.close(); - } - - /** - * Password Protected .xlsx files should give a helpful - * error message when called via WorkbookFactory with no password - */ - @Test(expected=EncryptedDocumentException.class) - public void bug55692_poifs() throws IOException { - // Via a POIFSFileSystem - POIFSFileSystem fsP = new POIFSFileSystem( - POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - try { - WorkbookFactory.create(fsP); - } finally { - fsP.close(); - } - } - - @Test - public void bug55692_stream() throws IOException, InvalidFormatException { - // Directly on a Stream, will go via NPOIFS and spot it's - // actually a .xlsx file encrypted with the default password, and open - Workbook wb = WorkbookFactory.create( - POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - assertNotNull(wb); - assertEquals(3, wb.getNumberOfSheets()); - wb.close(); - } - - @Test - public void bug55692_npoifs() throws IOException { - // Via a NPOIFSFileSystem, will spot it's actually a .xlsx file - // encrypted with the default password, and open - NPOIFSFileSystem fsNP = new NPOIFSFileSystem( - POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - Workbook wb = WorkbookFactory.create(fsNP); - assertNotNull(wb); - assertEquals(3, wb.getNumberOfSheets()); - wb.close(); - fsNP.close(); - } - - @Test - public void bug53282() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53282b.xlsx"); - Cell c = wb.getSheetAt(0).getRow(1).getCell(0); - assertEquals("#@_#", c.getStringCellValue()); - assertEquals("http://invalid.uri", c.getHyperlink().getAddress()); - wb.close(); - } - - /** - * Was giving NullPointerException - * at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead - * due to a lack of Styles Table - */ - @Test - public void bug56278() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56278.xlsx"); - assertEquals(0, wb.getSheetIndex("Market Rates")); - - // Save and re-check - Workbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertEquals(0, nwb.getSheetIndex("Market Rates")); - nwb.close(); - wb.close(); - } - - @Test - public void bug56315() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56315.xlsx"); - Cell c = wb.getSheetAt(0).getRow(1).getCell(0); - CellValue cv = wb.getCreationHelper().createFormulaEvaluator().evaluate(c); - double rounded = cv.getNumberValue(); - assertEquals(0.1, rounded, 0.0); - wb.close(); - } - - @Test - public void bug56468() throws IOException, InterruptedException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFRow row = sheet.createRow(0); - XSSFCell cell = row.createCell(0); - cell.setCellValue("Hi"); - sheet.setRepeatingRows(new CellRangeAddress(0, 0, 0, 0)); - - // small hack to try to make this test stable, previously it failed whenever the two written ZIP files had different file-creation - // dates stored. - // We try to do a loop until the current second changes in order to avoid problems with some date information that is written to the ZIP and thus - // causes differences - long start = System.currentTimeMillis()/1000; - while(System.currentTimeMillis()/1000 == start) { - Thread.sleep(10); - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(8096); - wb.write(bos); - byte firstSave[] = bos.toByteArray(); - bos.reset(); - wb.write(bos); - byte secondSave[] = bos.toByteArray(); - - /*OutputStream stream = new FileOutputStream("C:\\temp\\poi.xlsx"); - try { - wb.write(stream); - } finally { - stream.close(); - }*/ - - assertArrayEquals("Had: \n" + Arrays.toString(firstSave) + " and \n" + Arrays.toString(secondSave), - firstSave, secondSave); - - wb.close(); - } - - /** - * ISO-8601 style cell formats with a T in them, eg - * cell format of "yyyy-MM-ddTHH:mm:ss" - */ - @Test - public void bug54034() throws IOException { - TimeZone tz = LocaleUtil.getUserTimeZone(); - LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); - try { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("54034.xlsx"); - Sheet sheet = wb.getSheet("Sheet1"); - Row row = sheet.getRow(1); - Cell cell = row.getCell(2); - assertTrue(DateUtil.isCellDateFormatted(cell)); - - DataFormatter fmt = new DataFormatter(); - assertEquals("yyyy\\-mm\\-dd\\Thh:mm", cell.getCellStyle().getDataFormatString()); - assertEquals("2012-08-08T22:59", fmt.formatCellValue(cell)); - - wb.close(); - } finally { - LocaleUtil.setUserTimeZone(tz); - } - } - - - @Test - public void testBug53798XLSX() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xlsx"); - File xlsOutput = TempFile.createTempFile("testBug53798", ".xlsx"); - bug53798Work(wb, xlsOutput); - wb.close(); - } - - @Ignore("Shifting rows is not yet implemented in SXSSFSheet") - @Test - public void testBug53798XLSXStream() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xlsx"); - File xlsOutput = TempFile.createTempFile("testBug53798", ".xlsx"); - SXSSFWorkbook wb2 = new SXSSFWorkbook(wb); - bug53798Work(wb2, xlsOutput); - wb2.close(); - wb.close(); - } - - @Test - public void testBug53798XLS() throws IOException { - Workbook wb = HSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xls"); - File xlsOutput = TempFile.createTempFile("testBug53798", ".xls"); - bug53798Work(wb, xlsOutput); - wb.close(); - } - - /** - * SUMIF was throwing a NPE on some formulas - */ - @Test - public void testBug56420SumIfNPE() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56420.xlsx"); - - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - - Sheet sheet = wb.getSheetAt(0); - Row r = sheet.getRow(2); - Cell c = r.getCell(2); - assertEquals("SUMIF($A$1:$A$4,A3,$B$1:$B$4)", c.getCellFormula()); - Cell eval = evaluator.evaluateInCell(c); - assertEquals(0.0, eval.getNumericCellValue(), 0.0001); - wb.close(); - } - - private void bug53798Work(Workbook wb, File xlsOutput) throws IOException { - Sheet testSheet = wb.getSheetAt(0); - - testSheet.shiftRows(2, 2, 1); - - saveAndReloadReport(wb, xlsOutput); - - // 1) corrupted xlsx (unreadable data in the first row of a shifted group) already comes about - // when shifted by less than -1 negative amount (try -2) - testSheet.shiftRows(3, 3, -1); - - saveAndReloadReport(wb, xlsOutput); - - testSheet.shiftRows(2, 2, 1); - - saveAndReloadReport(wb, xlsOutput); - - // 2) attempt to create a new row IN PLACE of a removed row by a negative shift causes corrupted - // xlsx file with unreadable data in the negative shifted row. - // NOTE it's ok to create any other row. - Row newRow = testSheet.createRow(3); - - saveAndReloadReport(wb, xlsOutput); - - Cell newCell = newRow.createCell(0); - - saveAndReloadReport(wb, xlsOutput); - - newCell.setCellValue("new Cell in row "+newRow.getRowNum()); - - saveAndReloadReport(wb, xlsOutput); - - // 3) once a negative shift has been made any attempt to shift another group of rows - // (note: outside of previously negative shifted rows) by a POSITIVE amount causes POI exception: - // org.apache.xmlbeans.impl.values.XmlValueDisconnectedException. - // NOTE: another negative shift on another group of rows is successful, provided no new rows in - // place of previously shifted rows were attempted to be created as explained above. - testSheet.shiftRows(6, 7, 1); // -- CHANGE the shift to positive once the behaviour of - // the above has been tested - - saveAndReloadReport(wb, xlsOutput); - } - - /** - * XSSFCell.typeMismatch on certain blank cells when formatting - * with DataFormatter - */ - @Test - public void bug56702() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56702.xlsx"); - - Sheet sheet = wb.getSheetAt(0); - - // Get wrong cell by row 8 & column 7 - Cell cell = sheet.getRow(8).getCell(7); - assertEquals(CellType.NUMERIC, cell.getCellTypeEnum()); - - // Check the value - will be zero as it is - assertEquals(0.0, cell.getNumericCellValue(), 0.001); - - // Try to format - DataFormatter formatter = new DataFormatter(); - formatter.formatCellValue(cell); - - // Check the formatting - assertEquals("0", formatter.formatCellValue(cell)); - wb.close(); - } - - /** - * Formulas which reference named ranges, either in other - * sheets, or workbook scoped but in other workbooks. - * Used to fail with with errors like - * org.apache.poi.ss.formula.FormulaParseException: Cell reference expected after sheet name at index 9 - * org.apache.poi.ss.formula.FormulaParseException: Parse error near char 0 '[' in specified formula '[0]!NR_Global_B2'. Expected number, string, or defined name - */ - @Test - public void bug56737() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx"); - - // Check the named range definitions - Name nSheetScope = wb.getName("NR_To_A1"); - Name nWBScope = wb.getName("NR_Global_B2"); - - assertNotNull(nSheetScope); - assertNotNull(nWBScope); - - assertEquals("Defines!$A$1", nSheetScope.getRefersToFormula()); - assertEquals("Defines!$B$2", nWBScope.getRefersToFormula()); - - // Check the different kinds of formulas - Sheet s = wb.getSheetAt(0); - Cell cRefSName = s.getRow(1).getCell(3); - Cell cRefWName = s.getRow(2).getCell(3); - - assertEquals("Defines!NR_To_A1", cRefSName.getCellFormula()); - // Note the formula, as stored in the file, has the external name index not filename - // TODO Provide a way to get the one with the filename - assertEquals("[0]!NR_Global_B2", cRefWName.getCellFormula()); - - // Try to evaluate them - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - assertEquals("Test A1", eval.evaluate(cRefSName).getStringValue()); - assertEquals(142, (int)eval.evaluate(cRefWName).getNumberValue()); - - // Try to evaluate everything - eval.evaluateAll(); - wb.close(); - } - - private void saveAndReloadReport(Workbook wb, File outFile) throws IOException { - // run some method on the font to verify if it is "disconnected" already - //for(short i = 0;i < 256;i++) - { - Font font = wb.getFontAt((short)0); - if(font instanceof XSSFFont) { - XSSFFont xfont = (XSSFFont) wb.getFontAt((short)0); - CTFontImpl ctFont = (CTFontImpl) xfont.getCTFont(); - assertEquals(0, ctFont.sizeOfBArray()); - } - } - - FileOutputStream fileOutStream = new FileOutputStream(outFile); - try { - wb.write(fileOutStream); - } finally { - fileOutStream.close(); - } - - FileInputStream is = new FileInputStream(outFile); - try { - Workbook newWB = null; - try { - if(wb instanceof XSSFWorkbook) { - newWB = new XSSFWorkbook(is); - } else if(wb instanceof HSSFWorkbook) { - newWB = new HSSFWorkbook(is); - } else if(wb instanceof SXSSFWorkbook) { - newWB = new SXSSFWorkbook(new XSSFWorkbook(is)); - } else { - throw new IllegalStateException("Unknown workbook: " + wb); - } - assertNotNull(newWB.getSheet("test")); - } finally { - if (newWB != null) { - newWB.close(); - } - } - } finally { - is.close(); - } - } - - @Test - public void testBug56688_1() throws IOException { - XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_1.xlsx"); - checkValue(excel, "-1.0"); /* Not 0.0 because POI sees date "0" minus one month as invalid date, which is -1! */ - excel.close(); - } - - @Test - public void testBug56688_2() throws IOException { - XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_2.xlsx"); - checkValue(excel, "#VALUE!"); - excel.close(); - } - - @Test - public void testBug56688_3() throws IOException { - XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_3.xlsx"); - checkValue(excel, "#VALUE!"); - excel.close(); - } - - @Test - public void testBug56688_4() throws IOException { - XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_4.xlsx"); - - Calendar calendar = LocaleUtil.getLocaleCalendar(); - calendar.add(Calendar.MONTH, 2); - double excelDate = DateUtil.getExcelDate(calendar.getTime()); - NumberEval eval = new NumberEval(Math.floor(excelDate)); - checkValue(excel, eval.getStringValue() + ".0"); - - excel.close(); - } - - /** - * New hyperlink with no initial cell reference, still need - * to be able to change it - */ - @Test - public void testBug56527() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFCreationHelper creationHelper = wb.getCreationHelper(); - XSSFHyperlink hyperlink; - - // Try with a cell reference - hyperlink = creationHelper.createHyperlink(HyperlinkType.URL); - sheet.addHyperlink(hyperlink); - hyperlink.setAddress("http://myurl"); - hyperlink.setCellReference("B4"); - assertEquals(3, hyperlink.getFirstRow()); - assertEquals(1, hyperlink.getFirstColumn()); - assertEquals(3, hyperlink.getLastRow()); - assertEquals(1, hyperlink.getLastColumn()); - - // Try with explicit rows / columns - hyperlink = creationHelper.createHyperlink(HyperlinkType.URL); - sheet.addHyperlink(hyperlink); - hyperlink.setAddress("http://myurl"); - hyperlink.setFirstRow(5); - hyperlink.setFirstColumn(3); - - assertEquals(5, hyperlink.getFirstRow()); - assertEquals(3, hyperlink.getFirstColumn()); - assertEquals(5, hyperlink.getLastRow()); - assertEquals(3, hyperlink.getLastColumn()); - wb.close(); - } - - /** - * Shifting rows with a formula that references a - * function in another file - */ - @Test - public void bug56502() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56502.xlsx"); - Sheet sheet = wb.getSheetAt(0); - - Cell cFunc = sheet.getRow(3).getCell(0); - assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula()); - Cell cRef = sheet.getRow(3).createCell(1); - cRef.setCellFormula("A3"); - - // Shift it down one row - sheet.shiftRows(1, sheet.getLastRowNum(), 1); - - // Check the new formulas: Function won't change, Reference will - cFunc = sheet.getRow(4).getCell(0); - assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula()); - cRef = sheet.getRow(4).getCell(1); - assertEquals("A4", cRef.getCellFormula()); - wb.close(); - } - - @Test - public void bug54764() throws IOException, OpenXML4JException, XmlException { - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("54764.xlsx"); - - // Check the core properties - will be found but empty, due - // to the expansion being too much to be considered valid - POIXMLProperties props = new POIXMLProperties(pkg); - assertEquals(null, props.getCoreProperties().getTitle()); - assertEquals(null, props.getCoreProperties().getSubject()); - assertEquals(null, props.getCoreProperties().getDescription()); - - // Now check the spreadsheet itself - try { - new XSSFWorkbook(pkg).close(); - fail("Should fail as too much expansion occurs"); - } catch(POIXMLException e) { - // Expected - } - pkg.close(); - - // Try with one with the entities in the Content Types - try { - XSSFTestDataSamples.openSamplePackage("54764-2.xlsx").close(); - fail("Should fail as too much expansion occurs"); - } catch(Exception e) { - // Expected - } - - // Check we can still parse valid files after all that - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx"); - assertEquals(3, wb.getNumberOfSheets()); - wb.close(); - } - - /** - * CTDefinedNamesImpl should be included in the smaller - * poi-ooxml-schemas jar - */ - @Test - public void bug57176() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57176.xlsx"); - CTDefinedNames definedNames = wb.getCTWorkbook().getDefinedNames(); - List definedNameList = definedNames.getDefinedNameList(); - for (CTDefinedName defName : definedNameList) { - assertNotNull(defName.getName()); - assertNotNull(defName.getStringValue()); - } - assertEquals("TestDefinedName", definedNameList.get(0).getName()); - wb.close(); - } - - /** - * .xlsb files are not supported, but we should generate a helpful - * error message if given one - */ - @Test - public void bug56800_xlsb() throws IOException, InvalidFormatException { - // Can be opened at the OPC level - OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("Simple.xlsb"); - - // XSSF Workbook gives helpful error - try { - new XSSFWorkbook(pkg).close(); - fail(".xlsb files not supported"); - } catch (XLSBUnsupportedException e) { - // Good, detected and warned - } - - // Workbook Factory gives helpful error on package - try { - WorkbookFactory.create(pkg).close(); - fail(".xlsb files not supported"); - } catch (XLSBUnsupportedException e) { - // Good, detected and warned - } - - // Workbook Factory gives helpful error on file - File xlsbFile = HSSFTestDataSamples.getSampleFile("Simple.xlsb"); - try { - WorkbookFactory.create(xlsbFile).close(); - fail(".xlsb files not supported"); - } catch (XLSBUnsupportedException e) { - // Good, detected and warned - } - - pkg.close(); - } - - private void checkValue(XSSFWorkbook excel, String expect) { - XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel); - evaluator.evaluateAll(); - - XSSFCell cell = excel.getSheetAt(0).getRow(1).getCell(1); - CellValue value = evaluator.evaluate(cell); - - assertEquals(expect, value.formatAsString()); - } - - @Test - public void testBug57196() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57196.xlsx"); - Sheet sheet = wb.getSheet("Feuil1"); - Row mod=sheet.getRow(1); - mod.getCell(1).setCellValue(3); - HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); -// FileOutputStream fileOutput = new FileOutputStream("/tmp/57196.xlsx"); -// wb.write(fileOutput); -// fileOutput.close(); - wb.close(); - } - - @Test - public void test57196_Detail() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet("Sheet1"); - XSSFRow row = sheet.createRow(0); - XSSFCell cell = row.createCell(0); - cell.setCellFormula("DEC2HEX(HEX2DEC(O8)-O2+D2)"); - XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb); - CellValue cv = fe.evaluate(cell); - - assertNotNull(cv); - wb.close(); - } - - @Test - public void test57196_Detail2() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet("Sheet1"); - XSSFRow row = sheet.createRow(0); - XSSFCell cell = row.createCell(0); - cell.setCellFormula("DEC2HEX(O2+D2)"); - XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb); - CellValue cv = fe.evaluate(cell); - - assertNotNull(cv); - wb.close(); - } - - @Test - public void test57196_WorkbookEvaluator() throws IOException { - String previousLogger = System.getProperty("org.apache.poi.util.POILogger"); - //System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.SystemOutLogger"); - //System.setProperty("poi.log.level", "3"); - try { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet("Sheet1"); - XSSFRow row = sheet.createRow(0); - XSSFCell cell = row.createCell(0); - cell.setCellValue("0"); - cell = row.createCell(1); - cell.setCellValue(0); - cell = row.createCell(2); - cell.setCellValue(0); - - // simple formula worked - cell.setCellFormula("DEC2HEX(O2+D2)"); - - WorkbookEvaluator workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - // this already failed! Hex2Dec did not correctly handle RefEval - cell.setCellFormula("HEX2DEC(O8)"); - workbookEvaluator.clearAllCachedResultValues(); - - workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - // slightly more complex one failed - cell.setCellFormula("HEX2DEC(O8)-O2+D2"); - workbookEvaluator.clearAllCachedResultValues(); - - workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - // more complicated failed - cell.setCellFormula("DEC2HEX(HEX2DEC(O8)-O2+D2)"); - workbookEvaluator.clearAllCachedResultValues(); - - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - // what other similar functions - cell.setCellFormula("DEC2BIN(O8)-O2+D2"); - workbookEvaluator.clearAllCachedResultValues(); - - workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - // what other similar functions - cell.setCellFormula("DEC2BIN(A1)"); - workbookEvaluator.clearAllCachedResultValues(); - - workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - // what other similar functions - cell.setCellFormula("BIN2DEC(B1)"); - workbookEvaluator.clearAllCachedResultValues(); - - workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); - workbookEvaluator.setDebugEvaluationOutputForNextEval(true); - workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - - wb.close(); - } finally { - if(previousLogger == null) { - System.clearProperty("org.apache.poi.util.POILogger"); - } else { - System.setProperty("org.apache.poi.util.POILogger", previousLogger); - } - System.clearProperty("poi.log.level"); - } - } - - /** - * A .xlsx file with no Shared Strings table should open fine - * in read-only mode - */ - @SuppressWarnings("resource") - @Test - public void bug57482() throws IOException, InvalidFormatException { - for (PackageAccess access : new PackageAccess[] { - PackageAccess.READ_WRITE, PackageAccess.READ - }) { - File file = HSSFTestDataSamples.getSampleFile("57482-OnlyNumeric.xlsx"); - OPCPackage pkg = OPCPackage.open(file, access); - try { - // Try to open it and read the contents - XSSFWorkbook wb1 = new XSSFWorkbook(pkg); - assertNotNull(wb1.getSharedStringSource()); - assertEquals(0, wb1.getSharedStringSource().getCount()); - - DataFormatter fmt = new DataFormatter(); - XSSFSheet s = wb1.getSheetAt(0); - assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0))); - assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1))); - assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0))); - - // Add a text cell - s.getRow(0).createCell(3).setCellValue("Testing"); - assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3))); - - // Try to write-out and read again, should only work - // in read-write mode, not read-only mode - XSSFWorkbook wb2 = null; - try { - wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - if (access == PackageAccess.READ) { - fail("Shouln't be able to write from read-only mode"); - } - - // Check again - s = wb2.getSheetAt(0); - assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0))); - assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1))); - assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0))); - assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3))); - - } catch (InvalidOperationException e) { - if (access == PackageAccess.READ_WRITE) { - // Shouldn't occur in write-mode - throw e; - } - } finally { - if (wb2 != null) { - wb2.getPackage().revert(); - } - } - - wb1.getPackage().revert(); - } finally { - pkg.revert(); - } - } - } - - /** - * "Unknown error type: -60" fetching formula error value - */ - @Test - public void bug57535() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57535.xlsx"); - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - evaluator.clearAllCachedResultValues(); - - Sheet sheet = wb.getSheet("Sheet1"); - Cell cell = sheet.getRow(5).getCell(4); - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("E4+E5", cell.getCellFormula()); - - CellValue value = evaluator.evaluate(cell); - assertEquals(CellType.ERROR, value.getCellTypeEnum()); - assertEquals(-60, value.getErrorValue()); - assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString()); - assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString()); - - wb.close(); - } - - - @Test - public void test57165() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - try { - removeAllSheetsBut(3, wb); - wb.cloneSheet(0); // Throws exception here - wb.setSheetName(1, "New Sheet"); - //saveWorkbook(wb, fileName); - - XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - wbBack.close(); - } finally { - wb.close(); - } - } - - @Test - public void test57165_create() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - try { - removeAllSheetsBut(3, wb); - wb.createSheet("newsheet"); // Throws exception here - wb.setSheetName(1, "New Sheet"); - //saveWorkbook(wb, fileName); - - XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - wbBack.close(); - } finally { - wb.close(); - } - } - - private static void removeAllSheetsBut(int sheetIndex, Workbook wb) - { - int sheetNb = wb.getNumberOfSheets(); - // Move this sheet at the first position - wb.setSheetOrder(wb.getSheetName(sheetIndex), 0); - for (int sn = sheetNb - 1; sn > 0; sn--) - { - wb.removeSheetAt(sn); - } - } - - /** - * Sums 2 plus the cell at the left, indirectly to avoid reference - * problems when deleting columns, conditionally to stop recursion - */ - private static final String FORMULA1 = - "IF( INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) = 0, 0," - + "INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) ) + 2"; - - /** - * Sums 2 plus the upper cell, indirectly to avoid reference - * problems when deleting rows, conditionally to stop recursion - */ - private static final String FORMULA2 = - "IF( INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) = 0, 0," - + "INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) ) + 2"; - - /** - * Expected: - - * [ 0][ 2][ 4] - */ - @Test - public void testBug56820_Formula1() throws IOException { - Workbook wb = new XSSFWorkbook(); - try { - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - Sheet sh = wb.createSheet(); - - sh.createRow(0).createCell(0).setCellValue(0.0d); - Cell formulaCell1 = sh.getRow(0).createCell(1); - Cell formulaCell2 = sh.getRow(0).createCell(2); - formulaCell1.setCellFormula(FORMULA1); - formulaCell2.setCellFormula(FORMULA1); - - double A1 = evaluator.evaluate(formulaCell1).getNumberValue(); - double A2 = evaluator.evaluate(formulaCell2).getNumberValue(); - - assertEquals(2, A1, 0); - assertEquals(4, A2, 0); //<-- FAILS EXPECTATIONS - } finally { - wb.close(); - } - } - - /** - * Expected: - - * [ 0] <- number - * [ 2] <- formula - * [ 4] <- formula - */ - @Test - public void testBug56820_Formula2() throws IOException { - Workbook wb = new XSSFWorkbook(); - try { - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - Sheet sh = wb.createSheet(); - - sh.createRow(0).createCell(0).setCellValue(0.0d); - Cell formulaCell1 = sh.createRow(1).createCell(0); - Cell formulaCell2 = sh.createRow(2).createCell(0); - formulaCell1.setCellFormula(FORMULA2); - formulaCell2.setCellFormula(FORMULA2); - - double A1 = evaluator.evaluate(formulaCell1).getNumberValue(); - double A2 = evaluator.evaluate(formulaCell2).getNumberValue(); //<-- FAILS EVALUATION - - assertEquals(2, A1, 0); - assertEquals(4, A2, 0); - } finally { - wb.close(); - } - } - - @Test - public void test56467() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("picture.xlsx"); - try { - Sheet orig = wb.getSheetAt(0); - assertNotNull(orig); - - Sheet sheet = wb.cloneSheet(0); - Drawing drawing = sheet.createDrawingPatriarch(); - for (XSSFShape shape : ((XSSFDrawing) drawing).getShapes()) { - if (shape instanceof XSSFPicture) { - XSSFPictureData pictureData = ((XSSFPicture) shape).getPictureData(); - assertNotNull(pictureData); - } - } - - } finally { - wb.close(); - } - } - - /** - * OOXML-Strict files - * Not currently working - namespace mis-match from XMLBeans - */ - @Test - @Ignore("XMLBeans namespace mis-match on ooxml-strict files") - public void test57699() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.strict.xlsx"); - assertEquals(3, wb.getNumberOfSheets()); - // TODO Check sheet contents - // TODO Check formula evaluation - - XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertEquals(3, wbBack.getNumberOfSheets()); - // TODO Re-check sheet contents - // TODO Re-check formula evaluation - - wb.close(); - wbBack.close(); - } - - @Test - public void testBug56295_MergeXlslsWithStyles() throws IOException { - XSSFWorkbook xlsToAppendWorkbook = XSSFTestDataSamples.openSampleWorkbook("56295.xlsx"); - XSSFSheet sheet = xlsToAppendWorkbook.getSheetAt(0); - XSSFRow srcRow = sheet.getRow(0); - XSSFCell oldCell = srcRow.getCell(0); - XSSFCellStyle cellStyle = oldCell.getCellStyle(); - - checkStyle(cellStyle); - -// StylesTable table = xlsToAppendWorkbook.getStylesSource(); -// List fills = table.getFills(); -// System.out.println("Having " + fills.size() + " fills"); -// for(XSSFCellFill fill : fills) { -// System.out.println("Fill: " + fill.getFillBackgroundColor() + "/" + fill.getFillForegroundColor()); -// } - xlsToAppendWorkbook.close(); - - XSSFWorkbook targetWorkbook = new XSSFWorkbook(); - XSSFSheet newSheet = targetWorkbook.createSheet(sheet.getSheetName()); - XSSFRow destRow = newSheet.createRow(0); - XSSFCell newCell = destRow.createCell(0); - - //newCell.getCellStyle().cloneStyleFrom(cellStyle); - CellStyle newCellStyle = targetWorkbook.createCellStyle(); - newCellStyle.cloneStyleFrom(cellStyle); - newCell.setCellStyle(newCellStyle); - checkStyle(newCell.getCellStyle()); - newCell.setCellValue(oldCell.getStringCellValue()); - -// OutputStream os = new FileOutputStream("output.xlsm"); -// try { -// targetWorkbook.write(os); -// } finally { -// os.close(); -// } - - XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(targetWorkbook); - XSSFCellStyle styleBack = wbBack.getSheetAt(0).getRow(0).getCell(0).getCellStyle(); - checkStyle(styleBack); - - targetWorkbook.close(); - wbBack.close(); - } - - /** - * Paragraph with property BuFont but none of the properties - * BuNone, BuChar, and BuAutoNum, used to trigger a NPE - * Excel treats this as not-bulleted, so now do we - */ - @Test - public void testBug57826() throws IOException { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("57826.xlsx"); - - assertTrue("no sheets in workbook", workbook.getNumberOfSheets() >= 1); - XSSFSheet sheet = workbook.getSheetAt(0); - - XSSFDrawing drawing = sheet.getDrawingPatriarch(); - assertNotNull(drawing); - - List shapes = drawing.getShapes(); - assertEquals(1, shapes.size()); - assertTrue(shapes.get(0) instanceof XSSFSimpleShape); - - XSSFSimpleShape shape = (XSSFSimpleShape)shapes.get(0); - - // Used to throw a NPE - String text = shape.getText(); - - // No bulleting info included - assertEquals("test ok", text); - - workbook.close(); - } - - private void checkStyle(XSSFCellStyle cellStyle) { - assertNotNull(cellStyle); - assertEquals(0, cellStyle.getFillForegroundColor()); - assertNotNull(cellStyle.getFillForegroundXSSFColor()); - XSSFColor fgColor = cellStyle.getFillForegroundColorColor(); - assertNotNull(fgColor); - assertEquals("FF00FFFF", fgColor.getARGBHex()); - - assertEquals(0, cellStyle.getFillBackgroundColor()); - assertNotNull(cellStyle.getFillBackgroundXSSFColor()); - XSSFColor bgColor = cellStyle.getFillBackgroundColorColor(); - assertNotNull(bgColor); - assertEquals("FF00FFFF", fgColor.getARGBHex()); - } - - @Test - public void bug57642() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet s = wb.createSheet("TestSheet"); - XSSFCell c = s.createRow(0).createCell(0); - c.setCellFormula("ISERROR(TestSheet!A1)"); - c = s.createRow(1).createCell(1); - c.setCellFormula("ISERROR(B2)"); - - wb.setSheetName(0, "CSN"); - c = s.getRow(0).getCell(0); - assertEquals("ISERROR(CSN!A1)", c.getCellFormula()); - c = s.getRow(1).getCell(1); - assertEquals("ISERROR(B2)", c.getCellFormula()); - - wb.close(); - } - - /** - * .xlsx supports 64000 cell styles, the style indexes after - * 32,767 must not be -32,768, then -32,767, -32,766 - */ - @SuppressWarnings("resource") - @Test - public void bug57880() throws IOException { - int numStyles = 33000; - XSSFWorkbook wb = new XSSFWorkbook(); - for (int i=1; i data; - data = new TreeMap(); - data.put("1", new Object[] {"ID", "NAME", "LASTNAME"}); - data.put("2", new Object[] {2, "Amit", "Shukla"}); - data.put("3", new Object[] {1, "Lokesh", "Gupta"}); - data.put("4", new Object[] {4, "John", "Adwards"}); - data.put("5", new Object[] {2, "Brian", "Schultz"}); - - int rownum = 1; - for (Map.Entry me : data.entrySet()) { - final Row row; - if(createRow) { - row = sheet.createRow(rownum++); - } else { - row = sheet.getRow(rownum++); - } - assertNotNull(row); - - int cellnum = 0; - for (Object obj : me.getValue()) { - Cell cell = row.getCell(cellnum); - if(cell == null){ - cell = row.createCell(cellnum); - } else { - if(cell.getCellTypeEnum() == CellType.FORMULA) { - cell.setCellFormula(null); - cell.getCellStyle().setDataFormat((short) 0); - } - } - if(obj instanceof String) { - cell.setCellValue((String)obj); - } else if(obj instanceof Integer) { - cell.setCellValue((Integer)obj); - } - cellnum++; - } - } - - XSSFFormulaEvaluator.evaluateAllFormulaCells((XSSFWorkbook) wb); - wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); - - CalculationChain chain = ((XSSFWorkbook)wb).getCalculationChain(); - for(CTCalcCell calc : chain.getCTCalcChain().getCList()) { - // A2 to A6 should be gone - assertFalse(calc.getR().equals("A2")); - assertFalse(calc.getR().equals("A3")); - assertFalse(calc.getR().equals("A4")); - assertFalse(calc.getR().equals("A5")); - assertFalse(calc.getR().equals("A6")); - } - - Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - Sheet sheetBack = wbBack.getSheet("Func"); - assertNotNull(sheetBack); - - chain = ((XSSFWorkbook)wbBack).getCalculationChain(); - for(CTCalcCell calc : chain.getCTCalcChain().getCList()) { - // A2 to A6 should be gone - assertFalse(calc.getR().equals("A2")); - assertFalse(calc.getR().equals("A3")); - assertFalse(calc.getR().equals("A4")); - assertFalse(calc.getR().equals("A5")); - assertFalse(calc.getR().equals("A6")); - } - - wbBack.close(); - wb.close(); - } - - /** - * Excel 2007 generated Macro-Enabled .xlsm file - */ - @Test - public void bug57181() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57181.xlsm"); - assertEquals(9, wb.getNumberOfSheets()); - wb.close(); - } - - @Test - public void bug52111() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("Intersection-52111-xssf.xlsx"); - Sheet s = wb.getSheetAt(0); - assertFormula(wb, s.getRow(2).getCell(0), "(C2:D3 D3:E4)", "4.0"); - assertFormula(wb, s.getRow(6).getCell(0), "Tabelle2!E:E Tabelle2!11:11", "5.0"); - assertFormula(wb, s.getRow(8).getCell(0), "Tabelle2!E:F Tabelle2!11:12", null); - wb.close(); - } - - private void assertFormula(Workbook wb, Cell intF, String expectedFormula, String expectedResultOrNull) { - assertEquals(CellType.FORMULA, intF.getCellTypeEnum()); - if (null == expectedResultOrNull) { - assertEquals(CellType.ERROR, intF.getCachedFormulaResultTypeEnum()); - expectedResultOrNull = "#VALUE!"; - } - else { - assertEquals(CellType.NUMERIC, intF.getCachedFormulaResultTypeEnum()); - } - - assertEquals(expectedFormula, intF.getCellFormula()); - - // Check we can evaluate it correctly - FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); - assertEquals(expectedResultOrNull, eval.evaluate(intF).formatAsString()); - } - - @Test - public void test48962() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("48962.xlsx"); - Sheet sh = wb.getSheetAt(0); - Row row = sh.getRow(1); - Cell cell = row.getCell(0); - - CellStyle style = cell.getCellStyle(); - assertNotNull(style); - - // color index - assertEquals(64, style.getFillBackgroundColor()); - XSSFColor color = ((XSSFCellStyle)style).getFillBackgroundXSSFColor(); - assertNotNull(color); - - // indexed color - assertEquals(64, color.getIndexed()); - assertEquals(64, color.getIndex()); - - // not an RGB color - assertFalse(color.isRGB()); - assertNull(color.getRGB()); - wb.close(); - } - - @Test - public void test50755_workday_formula_example() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50755_workday_formula_example.xlsx"); - Sheet sheet = wb.getSheet("Sheet1"); - for(Row aRow : sheet) { - Cell cell = aRow.getCell(1); - if(cell.getCellTypeEnum() == CellType.FORMULA) { - String formula = cell.getCellFormula(); - //System.out.println("formula: " + formula); - assertNotNull(formula); - assertTrue(formula.contains("WORKDAY")); - } else { - assertNotNull(cell.toString()); - } - } - wb.close(); - } - - @Test - public void test51626() throws IOException, InvalidFormatException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51626.xlsx"); - assertNotNull(wb); - wb.close(); - - InputStream stream = HSSFTestDataSamples.openSampleFileStream("51626.xlsx"); - wb = WorkbookFactory.create(stream); - stream.close(); - wb.close(); - - wb = XSSFTestDataSamples.openSampleWorkbook("51626_contact.xlsx"); - assertNotNull(wb); - wb.close(); - - stream = HSSFTestDataSamples.openSampleFileStream("51626_contact.xlsx"); - wb = WorkbookFactory.create(stream); - stream.close(); - wb.close(); - } - - @Test - public void test51451() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sh = wb.createSheet(); - - Row row = sh.createRow(0); - Cell cell = row.createCell(0); - cell.setCellValue(239827342); - - CellStyle style = wb.createCellStyle(); - //style.setHidden(false); - DataFormat excelFormat = wb.createDataFormat(); - style.setDataFormat(excelFormat.getFormat("#,##0")); - sh.setDefaultColumnStyle(0, style); - -// FileOutputStream out = new FileOutputStream("/tmp/51451.xlsx"); -// wb.write(out); -// out.close(); - - wb.close(); - } - - @Test - public void test53105() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53105.xlsx"); - assertNotNull(wb); - - - // Act - // evaluate SUM('Skye Lookup Input'!A4:XFD4), cells in range each contain "1" - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - double numericValue = evaluator.evaluate(wb.getSheetAt(0).getRow(1).getCell(0)).getNumberValue(); - - // Assert - assertEquals(16384.0, numericValue, 0.0); - - wb.close(); - } - - - @Test - public void test58315() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("58315.xlsx"); - Cell cell = wb.getSheetAt(0).getRow(0).getCell(0); - assertNotNull(cell); - StringBuilder tmpCellContent = new StringBuilder(cell.getStringCellValue()); - XSSFRichTextString richText = (XSSFRichTextString) cell.getRichStringCellValue(); - - for (int i = richText.length() - 1; i >= 0; i--) { - Font f = richText.getFontAtIndex(i); - if (f != null && f.getStrikeout()) { - tmpCellContent.deleteCharAt(i); - } - } - String result = tmpCellContent.toString(); - assertEquals("320 350", result); - - wb.close(); - } - - @Test - public void test55406() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("55406_Conditional_formatting_sample.xlsx"); - Sheet sheet = wb.getSheetAt(0); - Cell cellA1 = sheet.getRow(0).getCell(0); - Cell cellA2 = sheet.getRow(1).getCell(0); - - assertEquals(0, cellA1.getCellStyle().getFillForegroundColor()); - assertEquals("FFFDFDFD", ((XSSFColor)cellA1.getCellStyle().getFillForegroundColorColor()).getARGBHex()); - assertEquals(0, cellA2.getCellStyle().getFillForegroundColor()); - assertEquals("FFFDFDFD", ((XSSFColor)cellA2.getCellStyle().getFillForegroundColorColor()).getARGBHex()); - - SheetConditionalFormatting cond = sheet.getSheetConditionalFormatting(); - assertEquals(2, cond.getNumConditionalFormattings()); - - assertEquals(1, cond.getConditionalFormattingAt(0).getNumberOfRules()); - assertEquals(64, cond.getConditionalFormattingAt(0).getRule(0).getPatternFormatting().getFillForegroundColor()); - assertEquals("ISEVEN(ROW())", cond.getConditionalFormattingAt(0).getRule(0).getFormula1()); - assertNull(((XSSFColor)cond.getConditionalFormattingAt(0).getRule(0).getPatternFormatting().getFillForegroundColorColor()).getARGBHex()); - - assertEquals(1, cond.getConditionalFormattingAt(1).getNumberOfRules()); - assertEquals(64, cond.getConditionalFormattingAt(1).getRule(0).getPatternFormatting().getFillForegroundColor()); - assertEquals("ISEVEN(ROW())", cond.getConditionalFormattingAt(1).getRule(0).getFormula1()); - assertNull(((XSSFColor)cond.getConditionalFormattingAt(1).getRule(0).getPatternFormatting().getFillForegroundColorColor()).getARGBHex()); - - wb.close(); - } - - @Test - public void test51998() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51998.xlsx"); - - Set sheetNames = new HashSet(); - - for (int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) - { - sheetNames.add(wb.getSheetName(sheetNum)); - } - - for (String sheetName : sheetNames) - { - int sheetIndex = wb.getSheetIndex(sheetName); - - wb.removeSheetAt(sheetIndex); - - Sheet newSheet = wb.createSheet(); - //Sheet newSheet = wb.createSheet(sheetName); - int newSheetIndex = wb.getSheetIndex(newSheet); - //System.out.println(newSheetIndex); - wb.setSheetName(newSheetIndex, sheetName); - wb.setSheetOrder(sheetName, sheetIndex); - } - - Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - wb.close(); - - assertNotNull(wbBack); - wbBack.close(); - } - - @Test - public void test58731() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("58731.xlsx"); - Sheet sheet = wb.createSheet("Java Books"); - - Object[][] bookData = { - {"Head First Java", "Kathy Serria", 79}, - {"Effective Java", "Joshua Bloch", 36}, - {"Clean Code", "Robert martin", 42}, - {"Thinking in Java", "Bruce Eckel", 35}, - }; - - int rowCount = 0; - for (Object[] aBook : bookData) { - Row row = sheet.createRow(rowCount++); - - int columnCount = 0; - for (Object field : aBook) { - Cell cell = row.createCell(columnCount++); - if (field instanceof String) { - cell.setCellValue((String) field); - } else if (field instanceof Integer) { - cell.setCellValue((Integer) field); - } - } - } - - Workbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb); - sheet = wb2.getSheet("Java Books"); - assertNotNull(sheet.getRow(0)); - assertNotNull(sheet.getRow(0).getCell(0)); - assertEquals(bookData[0][0], sheet.getRow(0).getCell(0).getStringCellValue()); - - wb2.close(); - wb.close(); - } - - /** - * Regression between 3.10.1 and 3.13 - - * org.apache.poi.openxml4j.exceptions.InvalidFormatException: - * The part /xl/sharedStrings.xml does not have any content type - * ! Rule: Package require content types when retrieving a part from a package. [M.1.14] - */ - @Test - public void test58760() throws IOException { - Workbook wb1 = XSSFTestDataSamples.openSampleWorkbook("58760.xlsx"); - assertEquals(1, wb1.getNumberOfSheets()); - assertEquals("Sheet1", wb1.getSheetName(0)); - Workbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - assertEquals(1, wb2.getNumberOfSheets()); - assertEquals("Sheet1", wb2.getSheetName(0)); - wb2.close(); - wb1.close(); - } - - @Test - public void test57236() throws IOException { - // Having very small numbers leads to different formatting, Excel uses the scientific notation, but POI leads to "0" - - /* - DecimalFormat format = new DecimalFormat("#.##########", new DecimalFormatSymbols(Locale.getDefault())); - double d = 3.0E-104; - assertEquals("3.0E-104", format.format(d)); - */ - - DataFormatter formatter = new DataFormatter(true); - - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57236.xlsx"); - for(int sheetNum = 0;sheetNum < wb.getNumberOfSheets();sheetNum++) { - Sheet sheet = wb.getSheetAt(sheetNum); - for(int rowNum = sheet.getFirstRowNum();rowNum < sheet.getLastRowNum();rowNum++) { - Row row = sheet.getRow(rowNum); - for(int cellNum = row.getFirstCellNum();cellNum < row.getLastCellNum();cellNum++) { - Cell cell = row.getCell(cellNum); - String fmtCellValue = formatter.formatCellValue(cell); - - System.out.println("Cell: " + fmtCellValue); - assertNotNull(fmtCellValue); - assertFalse(fmtCellValue.equals("0")); - } - } - } - - wb.close(); - } - - private void createXls() throws IOException - { - Workbook workbook = new HSSFWorkbook(); - FileOutputStream fileOut = new FileOutputStream("/tmp/rotated.xls"); - Sheet sheet1 = workbook.createSheet(); - Row row1 = sheet1.createRow((short) 0); - - Cell cell1 = row1.createCell(0); - - cell1.setCellValue("Successful rotated text."); - - CellStyle style = workbook.createCellStyle(); - style.setRotation((short) -90); - - cell1.setCellStyle(style); - - workbook.write(fileOut); - fileOut.close(); - workbook.close(); - } - - private void createXlsx() throws IOException { - Workbook workbook = new XSSFWorkbook(); - FileOutputStream fileOut = new FileOutputStream("/tmp/rotated.xlsx"); - Sheet sheet1 = workbook.createSheet(); - Row row1 = sheet1.createRow((short) 0); - - Cell cell1 = row1.createCell(0); - - cell1.setCellValue("Unsuccessful rotated text."); - - CellStyle style = workbook.createCellStyle(); - style.setRotation((short) -90); - - cell1.setCellStyle(style); - - workbook.write(fileOut); - fileOut.close(); - workbook.close(); - } - - @Ignore("Creates files for checking results manually, actual values are tested in Test*CellStyle") - @Test - public void test58043() throws IOException { - createXls(); - createXlsx(); - } - - @Test - public void test59132() throws IOException { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("59132.xlsx"); - Sheet worksheet = workbook.getSheet("sheet1"); - - // B3 - Row row = worksheet.getRow(2); - Cell cell = row.getCell(1); - - cell.setCellValue((String)null); - - FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); - - // B3 - row = worksheet.getRow(2); - cell = row.getCell(1); - - assertEquals(CellType.BLANK, cell.getCellTypeEnum()); - assertEquals(CellType._NONE, evaluator.evaluateFormulaCellEnum(cell)); - - // A3 - row = worksheet.getRow(2); - cell = row.getCell(0); - - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("IF(ISBLANK(B3),\"\",B3)", cell.getCellFormula()); - assertEquals(CellType.STRING, evaluator.evaluateFormulaCellEnum(cell)); - CellValue value = evaluator.evaluate(cell); - assertEquals("", value.getStringValue()); - - // A5 - row = worksheet.getRow(4); - cell = row.getCell(0); - - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("COUNTBLANK(A1:A4)", cell.getCellFormula()); - assertEquals(CellType.NUMERIC, evaluator.evaluateFormulaCellEnum(cell)); - value = evaluator.evaluate(cell); - assertEquals(1.0, value.getNumberValue(), 0.1); - - /*FileOutputStream output = new FileOutputStream("C:\\temp\\59132.xlsx"); - try { - workbook.write(output); - } finally { - output.close(); - }*/ - - workbook.close(); - } - - @Ignore("bug 59442") - @Test - public void testSetRGBBackgroundColor() throws IOException { - - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFCell cell = workbook.createSheet().createRow(0).createCell(0); - - XSSFColor color = new XSSFColor(java.awt.Color.RED); - XSSFCellStyle style = workbook.createCellStyle(); - style.setFillForegroundColor(color); - style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); - cell.setCellStyle(style); - - // Everything is fine at this point, cell is red - - Map properties = new HashMap(); - properties.put(CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN); //or BorderStyle.THIN - CellUtil.setCellStyleProperties(cell, properties); - - // Now the cell is all black - XSSFColor actual = cell.getCellStyle().getFillBackgroundColorColor(); - assertNotNull(actual); - assertEquals(color.getARGBHex(), actual.getARGBHex()); - - XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(workbook); - workbook.close(); - XSSFCell ncell = nwb.getSheetAt(0).getRow(0).getCell(0); - XSSFColor ncolor = new XSSFColor(java.awt.Color.RED); - - // Now the cell is all black - XSSFColor nactual = ncell.getCellStyle().getFillBackgroundColorColor(); - assertNotNull(nactual); - assertEquals(ncolor.getARGBHex(), nactual.getARGBHex()); - - nwb.close(); - } - - @Ignore("currently fails on POI 3.15 beta 2") - @Test - public void test55273() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("ExcelTables.xlsx"); - Sheet sheet = wb.getSheet("ExcelTable"); - - Name name = wb.getName("TableAsRangeName"); - assertEquals("TableName[#All]", name.getRefersToFormula()); - // POI 3.15-beta 2 (2016-06-15): getSheetName throws IllegalArgumentException: Invalid CellReference: TableName[#All] - assertEquals("TableName", name.getSheetName()); - - XSSFSheet xsheet = (XSSFSheet) sheet; - List tables = xsheet.getTables(); - assertEquals(2, tables.size()); //FIXME: how many tables are there in this spreadsheet? - assertEquals("Table1", tables.get(0).getName()); //FIXME: what is the table name? - assertEquals("Table2", tables.get(1).getName()); //FIXME: what is the table name? - } - - @Test - public void test57523() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57523.xlsx"); - Sheet sheet = wb.getSheet("Attribute Master"); - Row row = sheet.getRow(15); - - int N = CellReference.convertColStringToIndex("N"); - Cell N16 = row.getCell(N); - assertEquals(500.0, N16.getNumericCellValue(), 0.00001); - - int P = CellReference.convertColStringToIndex("P"); - Cell P16 = row.getCell(P); - assertEquals(10.0, P16.getNumericCellValue(), 0.00001); - } - - /** - * Files produced by some scientific equipment neglect - * to include the row number on the row tags - */ - @Test - public void noRowNumbers59746() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("59746_NoRowNums.xlsx"); - Sheet sheet = wb.getSheetAt(0); - assertTrue("Last row num: "+sheet.getLastRowNum(), sheet.getLastRowNum()>20); - assertEquals("Checked", sheet.getRow(0).getCell(0).getStringCellValue()); - assertEquals("Checked", sheet.getRow(9).getCell(2).getStringCellValue()); - assertEquals(false, sheet.getRow(70).getCell(8).getBooleanCellValue()); - assertEquals(71, sheet.getPhysicalNumberOfRows()); - assertEquals(70, sheet.getLastRowNum()); - assertEquals(70, sheet.getRow(sheet.getLastRowNum()).getRowNum()); - } - - @Test - public void testWorkdayFunction() throws IOException { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("59106.xlsx"); - XSSFSheet sheet = workbook.getSheet("Test"); - Row row = sheet.getRow(1); - Cell cell = row.getCell(0); - DataFormatter form = new DataFormatter(); - FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator(); - String result = form.formatCellValue(cell, evaluator); - - assertEquals("09 Mar 2016", result); - } - - // This bug is currently open. When this bug is fixed, it should not throw an AssertionError - @Test(expected=AssertionError.class) - public void test55076_collapseColumnGroups() throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - // this column collapsing bug only occurs when the grouped columns are different widths - sheet.setColumnWidth(1, 400); - sheet.setColumnWidth(2, 600); - sheet.setColumnWidth(3, 800); - - assertEquals(400, sheet.getColumnWidth(1)); - assertEquals(600, sheet.getColumnWidth(2)); - assertEquals(800, sheet.getColumnWidth(3)); - - sheet.groupColumn(1, 3); - sheet.setColumnGroupCollapsed(1, true); - - assertEquals(0, sheet.getColumnOutlineLevel(0)); - assertEquals(1, sheet.getColumnOutlineLevel(1)); - assertEquals(1, sheet.getColumnOutlineLevel(2)); - assertEquals(1, sheet.getColumnOutlineLevel(3)); - assertEquals(0, sheet.getColumnOutlineLevel(4)); - - // none of the columns should be hidden - // column group collapsing is a different concept - for (int c=0; c<5; c++) { - assertFalse("Column " + c, sheet.isColumnHidden(c)); - } - - assertEquals(400, sheet.getColumnWidth(1)); - assertEquals(600, sheet.getColumnWidth(2)); - assertEquals(800, sheet.getColumnWidth(3)); - - wb.close(); - } - - /** - * Other things, including charts, may end up taking drawing part - * numbers. (Uses a test file hand-crafted with an extra non-drawing - * part with a part number) - */ - @Test - public void drawingNumbersAlreadyTaken_60255() throws Exception { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("60255_extra_drawingparts.xlsx"); - assertEquals(4, wb.getNumberOfSheets()); - - // Sheet 3 starts with a drawing - Sheet sheet = wb.getSheetAt(0); - assertNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(1); - assertNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(2); - assertNotNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(3); - assertNull(sheet.getDrawingPatriarch()); - - // Add another sheet, and give it a drawing - sheet = wb.createSheet(); - assertNull(sheet.getDrawingPatriarch()); - sheet.createDrawingPatriarch(); - assertNotNull(sheet.getDrawingPatriarch()); - - // Save and check - wb = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertEquals(5, wb.getNumberOfSheets()); - - // Sheets 3 and 5 now - sheet = wb.getSheetAt(0); - assertNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(1); - assertNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(2); - assertNotNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(3); - assertNull(sheet.getDrawingPatriarch()); - sheet = wb.getSheetAt(4); - assertNotNull(sheet.getDrawingPatriarch()); - } - - @Test - public void test53611() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("test"); - Row row = sheet.createRow(1); - Cell cell = row.createCell(1); - cell.setCellValue("blabla"); - - row = sheet.createRow(4); - cell = row.createCell(7); - cell.setCellValue("blabla"); - - // we currently only populate the dimension during writing out - // to avoid having to iterate all rows/cells in each add/remove of a row or cell - //OutputStream str = new FileOutputStream("/tmp/53611.xlsx"); - OutputStream str = new ByteArrayOutputStream(); - try { - wb.write(str); - } finally { - str.close(); - } - - assertEquals("B2:I5", ((XSSFSheet)sheet).getCTWorksheet().getDimension().getRef()); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java deleted file mode 100644 index bbca6625e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java +++ /dev/null @@ -1,667 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.hssf.HSSFITestDataProvider; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.BaseTestXCell; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellCopyPolicy; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.SharedStringsTable; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; - -public final class TestXSSFCell extends BaseTestXCell { - - public TestXSSFCell() { - super(XSSFITestDataProvider.instance); - } - - /** - * Bug 47026: trouble changing cell type when workbook doesn't contain - * Shared String Table - */ - @Test - public void test47026_1() throws IOException { - Workbook wb = _testDataProvider.openSampleWorkbook("47026.xlsm"); - Sheet sheet = wb.getSheetAt(0); - Row row = sheet.getRow(0); - Cell cell = row.getCell(0); - cell.setCellType(CellType.STRING); - cell.setCellValue("456"); - wb.close(); - } - - @Test - public void test47026_2() throws IOException { - Workbook wb = _testDataProvider.openSampleWorkbook("47026.xlsm"); - Sheet sheet = wb.getSheetAt(0); - Row row = sheet.getRow(0); - Cell cell = row.getCell(0); - cell.setCellFormula(null); - cell.setCellValue("456"); - wb.close(); - } - - /** - * Test that we can read inline strings that are expressed directly in the cell definition - * instead of implementing the shared string table. - * - * Some programs, for example, Microsoft Excel Driver for .xlsx insert inline string - * instead of using the shared string table. See bug 47206 - */ - @Test - public void testInlineString() throws IOException { - XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("xlsx-jdbc.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - XSSFRow row = sheet.getRow(1); - - XSSFCell cell_0 = row.getCell(0); - assertEquals(STCellType.INT_INLINE_STR, cell_0.getCTCell().getT().intValue()); - assertTrue(cell_0.getCTCell().isSetIs()); - assertEquals("A Very large string in column 1 AAAAAAAAAAAAAAAAAAAAA", cell_0.getStringCellValue()); - - XSSFCell cell_1 = row.getCell(1); - assertEquals(STCellType.INT_INLINE_STR, cell_1.getCTCell().getT().intValue()); - assertTrue(cell_1.getCTCell().isSetIs()); - assertEquals("foo", cell_1.getStringCellValue()); - - XSSFCell cell_2 = row.getCell(2); - assertEquals(STCellType.INT_INLINE_STR, cell_2.getCTCell().getT().intValue()); - assertTrue(cell_2.getCTCell().isSetIs()); - assertEquals("bar", row.getCell(2).getStringCellValue()); - wb.close(); - } - - /** - * Bug 47278 - xsi:nil attribute for tag caused Excel 2007 to fail to open workbook - */ - @Test - public void test47278() throws IOException { - XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.createWorkbook(); - Sheet sheet = wb.createSheet(); - Row row = sheet.createRow(0); - SharedStringsTable sst = wb.getSharedStringSource(); - assertEquals(0, sst.getCount()); - - //case 1. cell.setCellValue(new XSSFRichTextString((String)null)); - Cell cell_0 = row.createCell(0); - RichTextString str = new XSSFRichTextString((String)null); - assertNull(str.getString()); - cell_0.setCellValue(str); - assertEquals(0, sst.getCount()); - assertEquals(CellType.BLANK, cell_0.getCellTypeEnum()); - - //case 2. cell.setCellValue((String)null); - Cell cell_1 = row.createCell(1); - cell_1.setCellValue((String)null); - assertEquals(0, sst.getCount()); - assertEquals(CellType.BLANK, cell_1.getCellTypeEnum()); - wb.close(); - } - - @Test - public void testFormulaString() throws IOException { - XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.createWorkbook(); - try { - XSSFCell cell = wb.createSheet().createRow(0).createCell(0); - CTCell ctCell = cell.getCTCell(); //low-level bean holding cell's xml - - cell.setCellFormula("A2"); - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("A2", cell.getCellFormula()); - //the value is not set and cell's type='N' which means blank - assertEquals(STCellType.N, ctCell.getT()); - - //set cached formula value - cell.setCellValue("t='str'"); - //we are still of 'formula' type - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("A2", cell.getCellFormula()); - //cached formula value is set and cell's type='STR' - assertEquals(STCellType.STR, ctCell.getT()); - assertEquals("t='str'", cell.getStringCellValue()); - - //now remove the formula, the cached formula result remains - cell.setCellFormula(null); - assertEquals(CellType.STRING, cell.getCellTypeEnum()); - assertEquals(STCellType.STR, ctCell.getT()); - //the line below failed prior to fix of Bug #47889 - assertEquals("t='str'", cell.getStringCellValue()); - - //revert to a blank cell - cell.setCellValue((String)null); - assertEquals(CellType.BLANK, cell.getCellTypeEnum()); - assertEquals(STCellType.N, ctCell.getT()); - assertEquals("", cell.getStringCellValue()); - } finally { - wb.close(); - } - } - - /** - * Bug 47889: problems when calling XSSFCell.getStringCellValue() on a workbook created in Gnumeric - */ - @Test - public void test47889() throws IOException { - XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("47889.xlsx"); - XSSFSheet sh = wb.getSheetAt(0); - - XSSFCell cell; - - //try a string cell - cell = sh.getRow(0).getCell(0); - assertEquals(CellType.STRING, cell.getCellTypeEnum()); - assertEquals("a", cell.getStringCellValue()); - assertEquals("a", cell.toString()); - //Gnumeric produces spreadsheets without styles - //make sure we return null for that instead of throwing OutOfBounds - assertEquals(null, cell.getCellStyle()); - - //try a numeric cell - cell = sh.getRow(1).getCell(0); - assertEquals(CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals(1.0, cell.getNumericCellValue(), 0); - assertEquals("1.0", cell.toString()); - //Gnumeric produces spreadsheets without styles - //make sure we return null for that instead of throwing OutOfBounds - assertEquals(null, cell.getCellStyle()); - wb.close(); - } - - @Test - public void testMissingRAttribute() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet(); - XSSFRow row = sheet.createRow(0); - XSSFCell a1 = row.createCell(0); - a1.setCellValue("A1"); - XSSFCell a2 = row.createCell(1); - a2.setCellValue("B1"); - XSSFCell a4 = row.createCell(4); - a4.setCellValue("E1"); - XSSFCell a6 = row.createCell(5); - a6.setCellValue("F1"); - - assertCellsWithMissingR(row); - - a2.getCTCell().unsetR(); - a6.getCTCell().unsetR(); - - assertCellsWithMissingR(row); - - XSSFWorkbook wb2 = (XSSFWorkbook)_testDataProvider.writeOutAndReadBack(wb1); - row = wb2.getSheetAt(0).getRow(0); - assertCellsWithMissingR(row); - - wb2.close(); - wb1.close(); - } - - private void assertCellsWithMissingR(XSSFRow row){ - XSSFCell a1 = row.getCell(0); - assertNotNull(a1); - XSSFCell a2 = row.getCell(1); - assertNotNull(a2); - XSSFCell a5 = row.getCell(4); - assertNotNull(a5); - XSSFCell a6 = row.getCell(5); - assertNotNull(a6); - - assertEquals(6, row.getLastCellNum()); - assertEquals(4, row.getPhysicalNumberOfCells()); - - assertEquals("A1", a1.getStringCellValue()); - assertEquals("B1", a2.getStringCellValue()); - assertEquals("E1", a5.getStringCellValue()); - assertEquals("F1", a6.getStringCellValue()); - - // even if R attribute is not set, - // POI is able to re-construct it from column and row indexes - assertEquals("A1", a1.getReference()); - assertEquals("B1", a2.getReference()); - assertEquals("E1", a5.getReference()); - assertEquals("F1", a6.getReference()); - } - - @Test - public void testMissingRAttributeBug54288() throws IOException { - // workbook with cells missing the R attribute - XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("54288.xlsx"); - // same workbook re-saved in Excel 2010, the R attribute is updated for every cell with the right value. - XSSFWorkbook wbRef = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("54288-ref.xlsx"); - - XSSFSheet sheet = wb.getSheetAt(0); - XSSFSheet sheetRef = wbRef.getSheetAt(0); - assertEquals(sheetRef.getPhysicalNumberOfRows(), sheet.getPhysicalNumberOfRows()); - - // Test idea: iterate over cells in the reference worksheet, they all have the R attribute set. - // For each cell from the reference sheet find the corresponding cell in the problematic file (with missing R) - // and assert that POI reads them equally: - DataFormatter formater = new DataFormatter(); - for(Row r : sheetRef){ - XSSFRow rowRef = (XSSFRow)r; - XSSFRow row = sheet.getRow(rowRef.getRowNum()); - - assertEquals("number of cells in row["+row.getRowNum()+"]", - rowRef.getPhysicalNumberOfCells(), row.getPhysicalNumberOfCells()); - - for(Cell c : rowRef){ - XSSFCell cellRef = (XSSFCell)c; - XSSFCell cell = row.getCell(cellRef.getColumnIndex()); - - assertEquals(cellRef.getColumnIndex(), cell.getColumnIndex()); - assertEquals(cellRef.getReference(), cell.getReference()); - - if(!cell.getCTCell().isSetR()){ - assertTrue("R must e set in cellRef", cellRef.getCTCell().isSetR()); - - String valRef = formater.formatCellValue(cellRef); - String val = formater.formatCellValue(cell); - assertEquals(valRef, val); - } - - } - } - wbRef.close(); - wb.close(); - } - - @Test - public void test56170() throws IOException { - final Workbook wb1 = XSSFTestDataSamples.openSampleWorkbook("56170.xlsx"); - final XSSFSheet sheet = (XSSFSheet) wb1.getSheetAt(0); - - Workbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - Cell cell; - - // add some contents to table so that the table will need expansion - Row row = sheet.getRow(0); - Workbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - cell = row.createCell(0); - Workbook wb4 = XSSFTestDataSamples.writeOutAndReadBack(wb3); - cell.setCellValue("demo1"); - Workbook wb5 = XSSFTestDataSamples.writeOutAndReadBack(wb4); - cell = row.createCell(1); - Workbook wb6 = XSSFTestDataSamples.writeOutAndReadBack(wb5); - cell.setCellValue("demo2"); - Workbook wb7 = XSSFTestDataSamples.writeOutAndReadBack(wb6); - cell = row.createCell(2); - Workbook wb8 = XSSFTestDataSamples.writeOutAndReadBack(wb7); - cell.setCellValue("demo3"); - - Workbook wb9 = XSSFTestDataSamples.writeOutAndReadBack(wb8); - - row = sheet.getRow(1); - cell = row.createCell(0); - cell.setCellValue("demo1"); - cell = row.createCell(1); - cell.setCellValue("demo2"); - cell = row.createCell(2); - cell.setCellValue("demo3"); - - Workbook wb10 = XSSFTestDataSamples.writeOutAndReadBack(wb9); - - // expand table - XSSFTable table = sheet.getTables().get(0); - final CellReference startRef = table.getStartCellReference(); - final CellReference endRef = table.getEndCellReference(); - table.getCTTable().setRef(new CellRangeAddress(startRef.getRow(), 1, startRef.getCol(), endRef.getCol()).formatAsString()); - - Workbook wb11 = XSSFTestDataSamples.writeOutAndReadBack(wb10); - assertNotNull(wb11); - - wb11.close(); - wb10.close(); - wb9.close(); - wb8.close(); - wb7.close(); - wb6.close(); - wb5.close(); - wb4.close(); - wb3.close(); - wb2.close(); - wb1.close(); - } - - @Test - public void test56170Reproduce() throws IOException { - final Workbook wb = new XSSFWorkbook(); - try { - final Sheet sheet = wb.createSheet(); - Row row = sheet.createRow(0); - - // by creating Cells out of order we trigger the handling in onDocumentWrite() - Cell cell1 = row.createCell(1); - Cell cell2 = row.createCell(0); - - validateRow(row); - - validateRow(row); - - // once again with removing one cell - row.removeCell(cell1); - - validateRow(row); - - // once again with removing one cell - row.removeCell(cell1); - - // now check again - validateRow(row); - - // once again with removing one cell - row.removeCell(cell2); - - // now check again - validateRow(row); - } finally { - wb.close(); - } - } - - private void validateRow(Row row) { - // trigger bug with CArray handling - ((XSSFRow)row).onDocumentWrite(); - - for(Cell cell : row) { - assertNotNull(cell.toString()); - } - } - - @Test - public void testBug56644ReturnNull() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56644.xlsx"); - try { - wb.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL); - Sheet sheet = wb.getSheet("samplelist"); - Row row = sheet.getRow(20); - row.createCell(2); - } finally { - wb.close(); - } - } - - @Test - public void testBug56644ReturnBlank() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56644.xlsx"); - try { - wb.setMissingCellPolicy(MissingCellPolicy.RETURN_NULL_AND_BLANK); - Sheet sheet = wb.getSheet("samplelist"); - Row row = sheet.getRow(20); - row.createCell(2); - } finally { - wb.close(); - } - } - - @Test - public void testBug56644CreateBlank() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56644.xlsx"); - try { - wb.setMissingCellPolicy(MissingCellPolicy.CREATE_NULL_AS_BLANK); - Sheet sheet = wb.getSheet("samplelist"); - Row row = sheet.getRow(20); - row.createCell(2); - } finally { - wb.close(); - } - } - - @Test - public void testEncodingBelowAscii() throws IOException { - StringBuilder sb = new StringBuilder(); - // test all possible characters - for(int i = 0; i < Character.MAX_VALUE; i++) { - sb.append((char)i); - } - - String strAll = sb.toString(); - - // process in chunks as we have a limit on size of column now - int pos = 0; - while(pos < strAll.length()) { - String str = strAll.substring(pos, Math.min(strAll.length(), pos+SpreadsheetVersion.EXCEL2007.getMaxTextLength())); - - Workbook wb = HSSFITestDataProvider.instance.createWorkbook(); - Cell cell = wb.createSheet().createRow(0).createCell(0); - - Workbook xwb = XSSFITestDataProvider.instance.createWorkbook(); - Cell xCell = xwb.createSheet().createRow(0).createCell(0); - - Workbook swb = SXSSFITestDataProvider.instance.createWorkbook(); - Cell sCell = swb.createSheet().createRow(0).createCell(0); - - cell.setCellValue(str); - assertEquals(str, cell.getStringCellValue()); - xCell.setCellValue(str); - assertEquals(str, xCell.getStringCellValue()); - sCell.setCellValue(str); - assertEquals(str, sCell.getStringCellValue()); - - Workbook wbBack = HSSFITestDataProvider.instance.writeOutAndReadBack(wb); - Workbook xwbBack = XSSFITestDataProvider.instance.writeOutAndReadBack(xwb); - Workbook swbBack = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb); - cell = wbBack.getSheetAt(0).createRow(0).createCell(0); - xCell = xwbBack.getSheetAt(0).createRow(0).createCell(0); - sCell = swbBack.getSheetAt(0).createRow(0).createCell(0); - - assertEquals(cell.getStringCellValue(), xCell.getStringCellValue()); - assertEquals(cell.getStringCellValue(), sCell.getStringCellValue()); - - pos += SpreadsheetVersion.EXCEL97.getMaxTextLength(); - - swbBack.close(); - xwbBack.close(); - wbBack.close(); - swb.close(); - xwb.close(); - wb.close(); - } - } - - private XSSFCell srcCell, destCell; //used for testCopyCellFrom_CellCopyPolicy - - @Test - public final void testCopyCellFrom_CellCopyPolicy_default() { - setUp_testCopyCellFrom_CellCopyPolicy(); - - // default copy policy - final CellCopyPolicy policy = new CellCopyPolicy(); - destCell.copyCellFrom(srcCell, policy); - - assertEquals(CellType.FORMULA, destCell.getCellTypeEnum()); - assertEquals("2+3", destCell.getCellFormula()); - assertEquals(srcCell.getCellStyle(), destCell.getCellStyle()); - } - - @Test - public final void testCopyCellFrom_CellCopyPolicy_value() { - setUp_testCopyCellFrom_CellCopyPolicy(); - - // Paste values only - final CellCopyPolicy policy = new CellCopyPolicy.Builder().cellFormula(false).build(); - destCell.copyCellFrom(srcCell, policy); - assertEquals(CellType.NUMERIC, destCell.getCellTypeEnum()); - } - - @Test - public final void testCopyCellFrom_CellCopyPolicy_formulaWithUnregisteredUDF() { - setUp_testCopyCellFrom_CellCopyPolicy(); - - srcCell.setCellFormula("MYFUNC2(123, $A5, Sheet1!$B7)"); - - // Copy formula verbatim (no shifting). This is okay because copyCellFrom is Internal. - // Users should use higher-level copying functions to row- or column-shift formulas. - final CellCopyPolicy policy = new CellCopyPolicy.Builder().cellFormula(true).build(); - destCell.copyCellFrom(srcCell, policy); - assertEquals("MYFUNC2(123, $A5, Sheet1!$B7)", destCell.getCellFormula()); - } - - @Test - public final void testCopyCellFrom_CellCopyPolicy_style() { - setUp_testCopyCellFrom_CellCopyPolicy(); - srcCell.setCellValue((String) null); - - // Paste styles only - final CellCopyPolicy policy = new CellCopyPolicy.Builder().cellValue(false).build(); - destCell.copyCellFrom(srcCell, policy); - assertEquals(srcCell.getCellStyle(), destCell.getCellStyle()); - - // Old cell value should not have been overwritten - assertNotEquals(CellType.BLANK, destCell.getCellTypeEnum()); - assertEquals(CellType.BOOLEAN, destCell.getCellTypeEnum()); - assertEquals(true, destCell.getBooleanCellValue()); - } - - @Test - public final void testCopyCellFrom_CellCopyPolicy_copyHyperlink() throws IOException { - setUp_testCopyCellFrom_CellCopyPolicy(); - final Workbook wb = srcCell.getSheet().getWorkbook(); - final CreationHelper createHelper = wb.getCreationHelper(); - - srcCell.setCellValue("URL LINK"); - Hyperlink link = createHelper.createHyperlink(HyperlinkType.URL); - link.setAddress("http://poi.apache.org/"); - srcCell.setHyperlink(link); - - // Set link cell style (optional) - CellStyle hlinkStyle = wb.createCellStyle(); - Font hlinkFont = wb.createFont(); - hlinkFont.setUnderline(Font.U_SINGLE); - hlinkFont.setColor(IndexedColors.BLUE.getIndex()); - hlinkStyle.setFont(hlinkFont); - srcCell.setCellStyle(hlinkStyle); - - // Copy hyperlink - final CellCopyPolicy policy = new CellCopyPolicy.Builder().copyHyperlink(true).mergeHyperlink(false).build(); - destCell.copyCellFrom(srcCell, policy); - assertNotNull(destCell.getHyperlink()); - - assertSame("unit test assumes srcCell and destCell are on the same sheet", - srcCell.getSheet(), destCell.getSheet()); - - final List links = srcCell.getSheet().getHyperlinkList(); - assertEquals("number of hyperlinks on sheet", 2, links.size()); - assertEquals("source hyperlink", - new CellReference(srcCell).formatAsString(), links.get(0).getCellRef()); - assertEquals("destination hyperlink", - new CellReference(destCell).formatAsString(), links.get(1).getCellRef()); - - wb.close(); - } - - @Test - public final void testCopyCellFrom_CellCopyPolicy_mergeHyperlink() throws IOException { - setUp_testCopyCellFrom_CellCopyPolicy(); - final Workbook wb = srcCell.getSheet().getWorkbook(); - final CreationHelper createHelper = wb.getCreationHelper(); - - srcCell.setCellValue("URL LINK"); - Hyperlink link = createHelper.createHyperlink(HyperlinkType.URL); - link.setAddress("http://poi.apache.org/"); - destCell.setHyperlink(link); - - // Set link cell style (optional) - CellStyle hlinkStyle = wb.createCellStyle(); - Font hlinkFont = wb.createFont(); - hlinkFont.setUnderline(Font.U_SINGLE); - hlinkFont.setColor(IndexedColors.BLUE.getIndex()); - hlinkStyle.setFont(hlinkFont); - destCell.setCellStyle(hlinkStyle); - - // Pre-condition assumptions. This test is broken if either of these fail. - assertSame("unit test assumes srcCell and destCell are on the same sheet", - srcCell.getSheet(), destCell.getSheet()); - assertNull(srcCell.getHyperlink()); - - // Merge hyperlink - since srcCell doesn't have a hyperlink, destCell's hyperlink is not overwritten (cleared). - final CellCopyPolicy policy = new CellCopyPolicy.Builder().mergeHyperlink(true).copyHyperlink(false).build(); - destCell.copyCellFrom(srcCell, policy); - assertNull(srcCell.getHyperlink()); - assertNotNull(destCell.getHyperlink()); - assertSame(link, destCell.getHyperlink()); - - List links; - links = srcCell.getSheet().getHyperlinkList(); - assertEquals("number of hyperlinks on sheet", 1, links.size()); - assertEquals("source hyperlink", - new CellReference(destCell).formatAsString(), links.get(0).getCellRef()); - - // Merge destCell's hyperlink to srcCell. Since destCell does have a hyperlink, this should copy destCell's hyperlink to srcCell. - srcCell.copyCellFrom(destCell, policy); - assertNotNull(srcCell.getHyperlink()); - assertNotNull(destCell.getHyperlink()); - - links = srcCell.getSheet().getHyperlinkList(); - assertEquals("number of hyperlinks on sheet", 2, links.size()); - assertEquals("dest hyperlink", - new CellReference(destCell).formatAsString(), links.get(0).getCellRef()); - assertEquals("source hyperlink", - new CellReference(srcCell).formatAsString(), links.get(1).getCellRef()); - - wb.close(); - } - - private void setUp_testCopyCellFrom_CellCopyPolicy() { - @SuppressWarnings("resource") - final XSSFWorkbook wb = new XSSFWorkbook(); - final XSSFRow row = wb.createSheet("Sheet1").createRow(0); - srcCell = row.createCell(0); - destCell = row.createCell(1); - - srcCell.setCellFormula("2+3"); - - final CellStyle style = wb.createCellStyle(); - style.setBorderTop(BorderStyle.THICK); - style.setFillBackgroundColor((short) 5); - srcCell.setCellStyle(style); - - destCell.setCellValue(true); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java deleted file mode 100644 index c907d40db..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java +++ /dev/null @@ -1,1065 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; -import org.junit.Before; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellXfs; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STHorizontalAlignment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignment; - -public class TestXSSFCellStyle { - private StylesTable stylesTable; - private CTBorder ctBorderA; - private CTFill ctFill; - private CTFont ctFont; - private CTXf cellStyleXf; - private CTXf cellXf; - private CTCellXfs cellXfs; - private XSSFCellStyle cellStyle; - private CTStylesheet ctStylesheet; - - @Before - public void setUp() { - stylesTable = new StylesTable(); - - ctStylesheet = stylesTable.getCTStylesheet(); - - ctBorderA = CTBorder.Factory.newInstance(); - XSSFCellBorder borderA = new XSSFCellBorder(ctBorderA); - long borderId = stylesTable.putBorder(borderA); - assertEquals(1, borderId); - - XSSFCellBorder borderB = new XSSFCellBorder(); - assertEquals(1, stylesTable.putBorder(borderB)); - - ctFill = CTFill.Factory.newInstance(); - XSSFCellFill fill = new XSSFCellFill(ctFill); - long fillId = stylesTable.putFill(fill); - assertEquals(2, fillId); - - ctFont = CTFont.Factory.newInstance(); - XSSFFont font = new XSSFFont(ctFont); - long fontId = stylesTable.putFont(font); - assertEquals(1, fontId); - - cellStyleXf = ctStylesheet.addNewCellStyleXfs().addNewXf(); - cellStyleXf.setBorderId(1); - cellStyleXf.setFillId(1); - cellStyleXf.setFontId(1); - - cellXfs = ctStylesheet.addNewCellXfs(); - cellXf = cellXfs.addNewXf(); - cellXf.setXfId(1); - cellXf.setBorderId(1); - cellXf.setFillId(1); - cellXf.setFontId(1); - stylesTable.putCellStyleXf(cellStyleXf); - stylesTable.putCellXf(cellXf); - cellStyle = new XSSFCellStyle(1, 1, stylesTable, null); - - assertNotNull(stylesTable.getFillAt(1).getCTFill().getPatternFill()); - assertEquals(STPatternType.INT_DARK_GRAY, stylesTable.getFillAt(1).getCTFill().getPatternFill().getPatternType().intValue()); - } - - @Test - public void testGetSetBorderBottom() { - //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderBottomEnum()); - - int num = stylesTable.getBorders().size(); - cellStyle.setBorderBottom(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderBottomEnum()); - //a new border has been added - assertEquals(num + 1, stylesTable.getBorders().size()); - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(STBorderStyle.MEDIUM, ctBorder.getBottom().getStyle()); - - num = stylesTable.getBorders().size(); - //setting the same border multiple times should not change borderId - for (int i = 0; i < 3; i++) { - cellStyle.setBorderBottom(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderBottomEnum()); - } - assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); - assertEquals(num, stylesTable.getBorders().size()); - assertSame(ctBorder, stylesTable.getBorderAt(borderId).getCTBorder()); - - //setting border to none removes the element - cellStyle.setBorderBottom(BorderStyle.NONE); - assertEquals(num, stylesTable.getBorders().size()); - borderId = (int)cellStyle.getCoreXf().getBorderId(); - ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertFalse(ctBorder.isSetBottom()); - } - - @Test - public void testGetSetBorderRight() { - //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderRightEnum()); - - int num = stylesTable.getBorders().size(); - cellStyle.setBorderRight(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderRightEnum()); - //a new border has been added - assertEquals(num + 1, stylesTable.getBorders().size()); - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(STBorderStyle.MEDIUM, ctBorder.getRight().getStyle()); - - num = stylesTable.getBorders().size(); - //setting the same border multiple times should not change borderId - for (int i = 0; i < 3; i++) { - cellStyle.setBorderRight(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderRightEnum()); - } - assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); - assertEquals(num, stylesTable.getBorders().size()); - assertSame(ctBorder, stylesTable.getBorderAt(borderId).getCTBorder()); - - //setting border to none removes the element - cellStyle.setBorderRight(BorderStyle.NONE); - assertEquals(num, stylesTable.getBorders().size()); - borderId = (int)cellStyle.getCoreXf().getBorderId(); - ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertFalse(ctBorder.isSetRight()); - } - - @Test - public void testGetSetBorderLeft() { - //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderLeftEnum()); - - int num = stylesTable.getBorders().size(); - cellStyle.setBorderLeft(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderLeftEnum()); - //a new border has been added - assertEquals(num + 1, stylesTable.getBorders().size()); - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(STBorderStyle.MEDIUM, ctBorder.getLeft().getStyle()); - - num = stylesTable.getBorders().size(); - //setting the same border multiple times should not change borderId - for (int i = 0; i < 3; i++) { - cellStyle.setBorderLeft(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderLeftEnum()); - } - assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); - assertEquals(num, stylesTable.getBorders().size()); - assertSame(ctBorder, stylesTable.getBorderAt(borderId).getCTBorder()); - - //setting border to none removes the element - cellStyle.setBorderLeft(BorderStyle.NONE); - assertEquals(num, stylesTable.getBorders().size()); - borderId = (int)cellStyle.getCoreXf().getBorderId(); - ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertFalse(ctBorder.isSetLeft()); - } - - @Test - public void testGetSetBorderTop() { - //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderTopEnum()); - - int num = stylesTable.getBorders().size(); - cellStyle.setBorderTop(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderTopEnum()); - //a new border has been added - assertEquals(num + 1, stylesTable.getBorders().size()); - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(STBorderStyle.MEDIUM, ctBorder.getTop().getStyle()); - - num = stylesTable.getBorders().size(); - //setting the same border multiple times should not change borderId - for (int i = 0; i < 3; i++) { - cellStyle.setBorderTop(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderTopEnum()); - } - assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); - assertEquals(num, stylesTable.getBorders().size()); - assertSame(ctBorder, stylesTable.getBorderAt(borderId).getCTBorder()); - - //setting border to none removes the element - cellStyle.setBorderTop(BorderStyle.NONE); - assertEquals(num, stylesTable.getBorders().size()); - borderId = (int)cellStyle.getCoreXf().getBorderId(); - ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertFalse(ctBorder.isSetTop()); - } - - private void testGetSetBorderXMLBean(BorderStyle border, STBorderStyle.Enum expected) { - cellStyle.setBorderTop(border); - assertEquals(border, cellStyle.getBorderTopEnum()); - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(expected, ctBorder.getTop().getStyle()); - } - - - // Border Styles, in BorderStyle/STBorderStyle enum order - @Test - public void testGetSetBorderNone() { - cellStyle.setBorderTop(BorderStyle.NONE); - assertEquals(BorderStyle.NONE, cellStyle.getBorderTopEnum()); - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertNull(ctBorder.getTop()); - // no border style and STBorderStyle.NONE are equivalent - // POI prefers to unset the border style than explicitly set it STBorderStyle.NONE - } - - @Test - public void testGetSetBorderThin() { - testGetSetBorderXMLBean(BorderStyle.THIN, STBorderStyle.THIN); - } - - @Test - public void testGetSetBorderMedium() { - testGetSetBorderXMLBean(BorderStyle.MEDIUM, STBorderStyle.MEDIUM); - } - - @Test - public void testGetSetBorderDashed() { - testGetSetBorderXMLBean(BorderStyle.DASHED, STBorderStyle.DASHED); - } - - @Test - public void testGetSetBorderDotted() { - testGetSetBorderXMLBean(BorderStyle.DOTTED, STBorderStyle.DOTTED); - } - - @Test - public void testGetSetBorderThick() { - testGetSetBorderXMLBean(BorderStyle.THICK, STBorderStyle.THICK); - } - - @Test - public void testGetSetBorderDouble() { - testGetSetBorderXMLBean(BorderStyle.DOUBLE, STBorderStyle.DOUBLE); - } - - @Test - public void testGetSetBorderHair() { - testGetSetBorderXMLBean(BorderStyle.HAIR, STBorderStyle.HAIR); - } - - @Test - public void testGetSetBorderMediumDashed() { - testGetSetBorderXMLBean(BorderStyle.MEDIUM_DASHED, STBorderStyle.MEDIUM_DASHED); - } - - @Test - public void testGetSetBorderDashDot() { - testGetSetBorderXMLBean(BorderStyle.DASH_DOT, STBorderStyle.DASH_DOT); - } - - @Test - public void testGetSetBorderMediumDashDot() { - testGetSetBorderXMLBean(BorderStyle.MEDIUM_DASH_DOT, STBorderStyle.MEDIUM_DASH_DOT); - } - - @Test - public void testGetSetBorderDashDotDot() { - testGetSetBorderXMLBean(BorderStyle.DASH_DOT_DOT, STBorderStyle.DASH_DOT_DOT); - } - - @Test - public void testGetSetBorderMediumDashDotDot() { - testGetSetBorderXMLBean(BorderStyle.MEDIUM_DASH_DOT_DOT, STBorderStyle.MEDIUM_DASH_DOT_DOT); - } - - @Test - public void testGetSetBorderSlantDashDot() { - testGetSetBorderXMLBean(BorderStyle.SLANTED_DASH_DOT, STBorderStyle.SLANT_DASH_DOT); - } - - @Test - public void testGetSetBottomBorderColor() { - //defaults - assertEquals(IndexedColors.BLACK.getIndex(), cellStyle.getBottomBorderColor()); - assertNull(cellStyle.getBottomBorderXSSFColor()); - - int num = stylesTable.getBorders().size(); - - XSSFColor clr; - - //setting indexed color - cellStyle.setBottomBorderColor(IndexedColors.BLUE_GREY.getIndex()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), cellStyle.getBottomBorderColor()); - clr = cellStyle.getBottomBorderXSSFColor(); - assertTrue(clr.getCTColor().isSetIndexed()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), clr.getIndexed()); - //a new border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), ctBorder.getBottom().getColor().getIndexed()); - - //setting XSSFColor - num = stylesTable.getBorders().size(); - clr = new XSSFColor(java.awt.Color.CYAN); - cellStyle.setBottomBorderColor(clr); - assertEquals(clr.getCTColor().toString(), cellStyle.getBottomBorderXSSFColor().getCTColor().toString()); - byte[] rgb = cellStyle.getBottomBorderXSSFColor().getRGB(); - assertEquals(java.awt.Color.CYAN, new java.awt.Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); - //another border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //passing null unsets the color - cellStyle.setBottomBorderColor(null); - assertNull(cellStyle.getBottomBorderXSSFColor()); - } - - @Test - public void testGetSetTopBorderColor() { - //defaults - assertEquals(IndexedColors.BLACK.getIndex(), cellStyle.getTopBorderColor()); - assertNull(cellStyle.getTopBorderXSSFColor()); - - int num = stylesTable.getBorders().size(); - - XSSFColor clr; - - //setting indexed color - cellStyle.setTopBorderColor(IndexedColors.BLUE_GREY.getIndex()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), cellStyle.getTopBorderColor()); - clr = cellStyle.getTopBorderXSSFColor(); - assertTrue(clr.getCTColor().isSetIndexed()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), clr.getIndexed()); - //a new border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), ctBorder.getTop().getColor().getIndexed()); - - //setting XSSFColor - num = stylesTable.getBorders().size(); - clr = new XSSFColor(java.awt.Color.CYAN); - cellStyle.setTopBorderColor(clr); - assertEquals(clr.getCTColor().toString(), cellStyle.getTopBorderXSSFColor().getCTColor().toString()); - byte[] rgb = cellStyle.getTopBorderXSSFColor().getRGB(); - assertEquals(java.awt.Color.CYAN, new java.awt.Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); - //another border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //passing null unsets the color - cellStyle.setTopBorderColor(null); - assertNull(cellStyle.getTopBorderXSSFColor()); - } - - @Test - public void testGetSetLeftBorderColor() { - //defaults - assertEquals(IndexedColors.BLACK.getIndex(), cellStyle.getLeftBorderColor()); - assertNull(cellStyle.getLeftBorderXSSFColor()); - - int num = stylesTable.getBorders().size(); - - XSSFColor clr; - - //setting indexed color - cellStyle.setLeftBorderColor(IndexedColors.BLUE_GREY.getIndex()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), cellStyle.getLeftBorderColor()); - clr = cellStyle.getLeftBorderXSSFColor(); - assertTrue(clr.getCTColor().isSetIndexed()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), clr.getIndexed()); - //a new border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), ctBorder.getLeft().getColor().getIndexed()); - - //setting XSSFColor - num = stylesTable.getBorders().size(); - clr = new XSSFColor(java.awt.Color.CYAN); - cellStyle.setLeftBorderColor(clr); - assertEquals(clr.getCTColor().toString(), cellStyle.getLeftBorderXSSFColor().getCTColor().toString()); - byte[] rgb = cellStyle.getLeftBorderXSSFColor().getRGB(); - assertEquals(java.awt.Color.CYAN, new java.awt.Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); - //another border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //passing null unsets the color - cellStyle.setLeftBorderColor(null); - assertNull(cellStyle.getLeftBorderXSSFColor()); - } - - @Test - public void testGetSetRightBorderColor() { - //defaults - assertEquals(IndexedColors.BLACK.getIndex(), cellStyle.getRightBorderColor()); - assertNull(cellStyle.getRightBorderXSSFColor()); - - int num = stylesTable.getBorders().size(); - - XSSFColor clr; - - //setting indexed color - cellStyle.setRightBorderColor(IndexedColors.BLUE_GREY.getIndex()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), cellStyle.getRightBorderColor()); - clr = cellStyle.getRightBorderXSSFColor(); - assertTrue(clr.getCTColor().isSetIndexed()); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), clr.getIndexed()); - //a new border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //id of the created border - int borderId = (int)cellStyle.getCoreXf().getBorderId(); - assertTrue(borderId > 0); - //check changes in the underlying xml bean - CTBorder ctBorder = stylesTable.getBorderAt(borderId).getCTBorder(); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), ctBorder.getRight().getColor().getIndexed()); - - //setting XSSFColor - num = stylesTable.getBorders().size(); - clr = new XSSFColor(java.awt.Color.CYAN); - cellStyle.setRightBorderColor(clr); - assertEquals(clr.getCTColor().toString(), cellStyle.getRightBorderXSSFColor().getCTColor().toString()); - byte[] rgb = cellStyle.getRightBorderXSSFColor().getRGB(); - assertEquals(java.awt.Color.CYAN, new java.awt.Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); - //another border was added to the styles table - assertEquals(num + 1, stylesTable.getBorders().size()); - - //passing null unsets the color - cellStyle.setRightBorderColor(null); - assertNull(cellStyle.getRightBorderXSSFColor()); - } - - @Test - public void testGetSetFillBackgroundColor() { - - assertEquals(IndexedColors.AUTOMATIC.getIndex(), cellStyle.getFillBackgroundColor()); - assertNull(cellStyle.getFillBackgroundXSSFColor()); - - XSSFColor clr; - - int num = stylesTable.getFills().size(); - - //setting indexed color - cellStyle.setFillBackgroundColor(IndexedColors.RED.getIndex()); - assertEquals(IndexedColors.RED.getIndex(), cellStyle.getFillBackgroundColor()); - clr = cellStyle.getFillBackgroundXSSFColor(); - assertTrue(clr.getCTColor().isSetIndexed()); - assertEquals(IndexedColors.RED.getIndex(), clr.getIndexed()); - //a new fill was added to the styles table - assertEquals(num + 1, stylesTable.getFills().size()); - - //id of the created border - int fillId = (int)cellStyle.getCoreXf().getFillId(); - assertTrue(fillId > 0); - //check changes in the underlying xml bean - CTFill ctFill2 = stylesTable.getFillAt(fillId).getCTFill(); - assertEquals(IndexedColors.RED.getIndex(), ctFill2.getPatternFill().getBgColor().getIndexed()); - - //setting XSSFColor - num = stylesTable.getFills().size(); - clr = new XSSFColor(java.awt.Color.CYAN); - cellStyle.setFillBackgroundColor(clr); - assertEquals(clr.getCTColor().toString(), cellStyle.getFillBackgroundXSSFColor().getCTColor().toString()); - byte[] rgb = cellStyle.getFillBackgroundXSSFColor().getRGB(); - assertEquals(java.awt.Color.CYAN, new java.awt.Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); - //another border was added to the styles table - assertEquals(num + 1, stylesTable.getFills().size()); - - //passing null unsets the color - cellStyle.setFillBackgroundColor(null); - assertNull(cellStyle.getFillBackgroundXSSFColor()); - assertEquals(IndexedColors.AUTOMATIC.getIndex(), cellStyle.getFillBackgroundColor()); - } - - @Test - public void testDefaultStyles() throws IOException { - - XSSFWorkbook wb1 = new XSSFWorkbook(); - - XSSFCellStyle style1 = wb1.createCellStyle(); - assertEquals(IndexedColors.AUTOMATIC.getIndex(), style1.getFillBackgroundColor()); - assertNull(style1.getFillBackgroundXSSFColor()); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb1)); - wb1.close(); - - //compatibility with HSSF - HSSFWorkbook wb2 = new HSSFWorkbook(); - HSSFCellStyle style2 = wb2.createCellStyle(); - assertEquals(style2.getFillBackgroundColor(), style1.getFillBackgroundColor()); - assertEquals(style2.getFillForegroundColor(), style1.getFillForegroundColor()); - assertEquals(style2.getFillPatternEnum(), style1.getFillPatternEnum()); - assertEquals(style2.getFillPattern(), style1.getFillPattern()); - - assertEquals(style2.getLeftBorderColor(), style1.getLeftBorderColor()); - assertEquals(style2.getTopBorderColor(), style1.getTopBorderColor()); - assertEquals(style2.getRightBorderColor(), style1.getRightBorderColor()); - assertEquals(style2.getBottomBorderColor(), style1.getBottomBorderColor()); - - assertEquals(style2.getBorderBottomEnum(), style1.getBorderBottomEnum()); - assertEquals(style2.getBorderLeftEnum(), style1.getBorderLeftEnum()); - assertEquals(style2.getBorderRightEnum(), style1.getBorderRightEnum()); - assertEquals(style2.getBorderTopEnum(), style1.getBorderTopEnum()); - wb2.close(); - } - - @Test - public void testGetFillForegroundColor() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - StylesTable styles = wb.getStylesSource(); - assertEquals(1, wb.getNumCellStyles()); - assertEquals(2, styles.getFills().size()); - - XSSFCellStyle defaultStyle = wb.getCellStyleAt((short)0); - assertEquals(IndexedColors.AUTOMATIC.getIndex(), defaultStyle.getFillForegroundColor()); - assertEquals(null, defaultStyle.getFillForegroundXSSFColor()); - assertEquals(FillPatternType.NO_FILL, defaultStyle.getFillPatternEnum()); - assertEquals(CellStyle.NO_FILL, defaultStyle.getFillPattern()); - - XSSFCellStyle customStyle = wb.createCellStyle(); - - customStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - assertEquals(FillPatternType.SOLID_FOREGROUND, customStyle.getFillPatternEnum()); - assertEquals(CellStyle.SOLID_FOREGROUND, customStyle.getFillPattern()); - assertEquals(3, styles.getFills().size()); - - customStyle.setFillForegroundColor(IndexedColors.BRIGHT_GREEN.getIndex()); - assertEquals(IndexedColors.BRIGHT_GREEN.getIndex(), customStyle.getFillForegroundColor()); - assertEquals(4, styles.getFills().size()); - - for (int i = 0; i < 3; i++) { - XSSFCellStyle style = wb.createCellStyle(); - - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); - assertEquals(FillPatternType.SOLID_FOREGROUND, style.getFillPatternEnum()); - assertEquals(CellStyle.SOLID_FOREGROUND, style.getFillPattern()); - assertEquals(4, styles.getFills().size()); - - style.setFillForegroundColor(IndexedColors.BRIGHT_GREEN.getIndex()); - assertEquals(IndexedColors.BRIGHT_GREEN.getIndex(), style.getFillForegroundColor()); - assertEquals(4, styles.getFills().size()); - } - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - wb.close(); - } - - @Test - public void testGetFillPattern() { - - assertEquals(STPatternType.INT_DARK_GRAY-1, cellStyle.getFillPatternEnum().getCode()); - assertEquals(STPatternType.INT_DARK_GRAY-1, cellStyle.getFillPattern()); - - int num = stylesTable.getFills().size(); - cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - assertEquals(FillPatternType.SOLID_FOREGROUND, cellStyle.getFillPatternEnum()); - assertEquals(CellStyle.SOLID_FOREGROUND, cellStyle.getFillPattern()); - assertEquals(num + 1, stylesTable.getFills().size()); - int fillId = (int)cellStyle.getCoreXf().getFillId(); - assertTrue(fillId > 0); - //check changes in the underlying xml bean - CTFill ctFill2 = stylesTable.getFillAt(fillId).getCTFill(); - assertEquals(STPatternType.SOLID, ctFill2.getPatternFill().getPatternType()); - - //setting the same fill multiple time does not update the styles table - for (int i = 0; i < 3; i++) { - cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - } - assertEquals(num + 1, stylesTable.getFills().size()); - - cellStyle.setFillPattern(FillPatternType.NO_FILL); - assertEquals(FillPatternType.NO_FILL, cellStyle.getFillPatternEnum()); - assertEquals(CellStyle.NO_FILL, cellStyle.getFillPattern()); - fillId = (int)cellStyle.getCoreXf().getFillId(); - ctFill2 = stylesTable.getFillAt(fillId).getCTFill(); - assertFalse(ctFill2.getPatternFill().isSetPatternType()); - - } - - @Test - public void testGetFont() { - assertNotNull(cellStyle.getFont()); - } - - @Test - public void testGetSetHidden() { - assertFalse(cellStyle.getHidden()); - cellStyle.setHidden(true); - assertTrue(cellStyle.getHidden()); - cellStyle.setHidden(false); - assertFalse(cellStyle.getHidden()); - } - - @Test - public void testGetSetLocked() { - assertTrue(cellStyle.getLocked()); - cellStyle.setLocked(true); - assertTrue(cellStyle.getLocked()); - cellStyle.setLocked(false); - assertFalse(cellStyle.getLocked()); - } - - @Test - public void testGetSetIndent() { - assertEquals((short)0, cellStyle.getIndention()); - cellStyle.setIndention((short)3); - assertEquals((short)3, cellStyle.getIndention()); - cellStyle.setIndention((short) 13); - assertEquals((short)13, cellStyle.getIndention()); - } - - @Test - public void testGetSetAlignement() { - assertNull(cellStyle.getCellAlignment().getCTCellAlignment().getHorizontal()); - assertEquals(HorizontalAlignment.GENERAL, cellStyle.getAlignmentEnum()); - - cellStyle.setAlignment(XSSFCellStyle.ALIGN_LEFT); - assertEquals(XSSFCellStyle.ALIGN_LEFT, cellStyle.getAlignment()); - assertEquals(HorizontalAlignment.LEFT, cellStyle.getAlignmentEnum()); - assertEquals(STHorizontalAlignment.LEFT, cellStyle.getCellAlignment().getCTCellAlignment().getHorizontal()); - - cellStyle.setAlignment(HorizontalAlignment.JUSTIFY); - assertEquals(XSSFCellStyle.ALIGN_JUSTIFY, cellStyle.getAlignment()); - assertEquals(HorizontalAlignment.JUSTIFY, cellStyle.getAlignmentEnum()); - assertEquals(STHorizontalAlignment.JUSTIFY, cellStyle.getCellAlignment().getCTCellAlignment().getHorizontal()); - - cellStyle.setAlignment(HorizontalAlignment.CENTER); - assertEquals(XSSFCellStyle.ALIGN_CENTER, cellStyle.getAlignment()); - assertEquals(HorizontalAlignment.CENTER, cellStyle.getAlignmentEnum()); - assertEquals(STHorizontalAlignment.CENTER, cellStyle.getCellAlignment().getCTCellAlignment().getHorizontal()); - } - - @Test - public void testGetSetVerticalAlignment() { - assertEquals(VerticalAlignment.BOTTOM, cellStyle.getVerticalAlignmentEnum()); - assertEquals(XSSFCellStyle.VERTICAL_BOTTOM, cellStyle.getVerticalAlignment()); - assertNull(cellStyle.getCellAlignment().getCTCellAlignment().getVertical()); - - cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER); - assertEquals(XSSFCellStyle.VERTICAL_CENTER, cellStyle.getVerticalAlignment()); - assertEquals(VerticalAlignment.CENTER, cellStyle.getVerticalAlignmentEnum()); - assertEquals(STVerticalAlignment.CENTER, cellStyle.getCellAlignment().getCTCellAlignment().getVertical()); - - cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_JUSTIFY); - assertEquals(XSSFCellStyle.VERTICAL_JUSTIFY, cellStyle.getVerticalAlignment()); - assertEquals(VerticalAlignment.JUSTIFY, cellStyle.getVerticalAlignmentEnum()); - assertEquals(STVerticalAlignment.JUSTIFY, cellStyle.getCellAlignment().getCTCellAlignment().getVertical()); - } - - @Test - public void testGetSetWrapText() { - assertFalse(cellStyle.getWrapText()); - cellStyle.setWrapText(true); - assertTrue(cellStyle.getWrapText()); - cellStyle.setWrapText(false); - assertFalse(cellStyle.getWrapText()); - } - - /** - * Cloning one XSSFCellStyle onto Another, same XSSFWorkbook - */ - @Test - public void testCloneStyleSameWB() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - assertEquals(1, wb.getNumberOfFonts()); - - XSSFFont fnt = wb.createFont(); - fnt.setFontName("TestingFont"); - assertEquals(2, wb.getNumberOfFonts()); - - XSSFCellStyle orig = wb.createCellStyle(); - orig.setAlignment(CellStyle.ALIGN_RIGHT); - orig.setFont(fnt); - orig.setDataFormat((short)18); - - assertTrue(CellStyle.ALIGN_RIGHT == orig.getAlignment()); - assertTrue(fnt == orig.getFont()); - assertTrue(18 == orig.getDataFormat()); - - XSSFCellStyle clone = wb.createCellStyle(); - assertFalse(CellStyle.ALIGN_RIGHT == clone.getAlignment()); - assertFalse(fnt == clone.getFont()); - assertFalse(18 == clone.getDataFormat()); - - clone.cloneStyleFrom(orig); - assertTrue(CellStyle.ALIGN_RIGHT == clone.getAlignment()); - assertTrue(fnt == clone.getFont()); - assertTrue(18 == clone.getDataFormat()); - assertEquals(2, wb.getNumberOfFonts()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertNotNull(wb2); - wb2.close(); - - wb.close(); - } - - /** - * Cloning one XSSFCellStyle onto Another, different XSSFWorkbooks - */ - @Test - public void testCloneStyleDiffWB() throws IOException { - XSSFWorkbook wbOrig = new XSSFWorkbook(); - assertEquals(1, wbOrig.getNumberOfFonts()); - assertEquals(0, wbOrig.getStylesSource().getNumberFormats().size()); - - XSSFFont fnt = wbOrig.createFont(); - fnt.setFontName("TestingFont"); - assertEquals(2, wbOrig.getNumberOfFonts()); - assertEquals(0, wbOrig.getStylesSource().getNumberFormats().size()); - - XSSFDataFormat fmt = wbOrig.createDataFormat(); - fmt.getFormat("MadeUpOne"); - fmt.getFormat("MadeUpTwo"); - - XSSFCellStyle orig = wbOrig.createCellStyle(); - orig.setAlignment(HSSFCellStyle.ALIGN_RIGHT); - orig.setFont(fnt); - orig.setDataFormat(fmt.getFormat("Test##")); - - assertTrue(XSSFCellStyle.ALIGN_RIGHT == orig.getAlignment()); - assertTrue(fnt == orig.getFont()); - assertTrue(fmt.getFormat("Test##") == orig.getDataFormat()); - - assertEquals(2, wbOrig.getNumberOfFonts()); - assertEquals(3, wbOrig.getStylesSource().getNumberFormats().size()); - - - // Now a style on another workbook - XSSFWorkbook wbClone = new XSSFWorkbook(); - assertEquals(1, wbClone.getNumberOfFonts()); - assertEquals(0, wbClone.getStylesSource().getNumberFormats().size()); - assertEquals(1, wbClone.getNumCellStyles()); - - XSSFDataFormat fmtClone = wbClone.createDataFormat(); - XSSFCellStyle clone = wbClone.createCellStyle(); - - assertEquals(1, wbClone.getNumberOfFonts()); - assertEquals(0, wbClone.getStylesSource().getNumberFormats().size()); - - assertFalse(HSSFCellStyle.ALIGN_RIGHT == clone.getAlignment()); - assertNotEquals("TestingFont", clone.getFont().getFontName()); - - clone.cloneStyleFrom(orig); - - assertEquals(2, wbClone.getNumberOfFonts()); - assertEquals(2, wbClone.getNumCellStyles()); - assertEquals(1, wbClone.getStylesSource().getNumberFormats().size()); - - assertEquals(HSSFCellStyle.ALIGN_RIGHT, clone.getAlignment()); - assertEquals("TestingFont", clone.getFont().getFontName()); - assertEquals(fmtClone.getFormat("Test##"), clone.getDataFormat()); - assertFalse(fmtClone.getFormat("Test##") == fmt.getFormat("Test##")); - - // Save it and re-check - XSSFWorkbook wbReload = XSSFTestDataSamples.writeOutAndReadBack(wbClone); - assertEquals(2, wbReload.getNumberOfFonts()); - assertEquals(2, wbReload.getNumCellStyles()); - assertEquals(1, wbReload.getStylesSource().getNumberFormats().size()); - - XSSFCellStyle reload = wbReload.getCellStyleAt((short)1); - assertEquals(HSSFCellStyle.ALIGN_RIGHT, reload.getAlignment()); - assertEquals("TestingFont", reload.getFont().getFontName()); - assertEquals(fmtClone.getFormat("Test##"), reload.getDataFormat()); - assertFalse(fmtClone.getFormat("Test##") == fmt.getFormat("Test##")); - - XSSFWorkbook wbOrig2 = XSSFTestDataSamples.writeOutAndReadBack(wbOrig); - assertNotNull(wbOrig2); - wbOrig2.close(); - - XSSFWorkbook wbClone2 = XSSFTestDataSamples.writeOutAndReadBack(wbClone); - assertNotNull(wbClone2); - wbClone2.close(); - - wbReload.close(); - wbClone.close(); - wbOrig.close(); - } - - /** - * Avoid ArrayIndexOutOfBoundsException when creating cell style - * in a workbook that has an empty xf table. - */ - @Test - public void testBug52348() throws IOException { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("52348.xlsx"); - StylesTable st = workbook.getStylesSource(); - assertEquals(0, st._getStyleXfsSize()); - - XSSFCellStyle style = workbook.createCellStyle(); // no exception at this point - assertNull(style.getStyleXf()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertNotNull(wb2); - wb2.close(); - workbook.close(); - } - - /** - * Avoid ArrayIndexOutOfBoundsException when getting cell style - * in a workbook that has an empty xf table. - */ - @Test - public void testBug55650() throws IOException { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("52348.xlsx"); - StylesTable st = workbook.getStylesSource(); - assertEquals(0, st._getStyleXfsSize()); - - // no exception at this point - XSSFCellStyle style = workbook.getSheetAt(0).getRow(0).getCell(0).getCellStyle(); - assertNull(style.getStyleXf()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertNotNull(wb2); - wb2.close(); - - workbook.close(); - } - - @Test - public void testShrinkToFit() throws IOException { - // Existing file - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("ShrinkToFit.xlsx"); - Sheet s = wb1.getSheetAt(0); - Row r = s.getRow(0); - CellStyle cs = r.getCell(0).getCellStyle(); - - assertEquals(true, cs.getShrinkToFit()); - - // New file - XSSFWorkbook wb2 = new XSSFWorkbook(); - s = wb2.createSheet(); - r = s.createRow(0); - - cs = wb2.createCellStyle(); - cs.setShrinkToFit(false); - r.createCell(0).setCellStyle(cs); - - cs = wb2.createCellStyle(); - cs.setShrinkToFit(true); - r.createCell(1).setCellStyle(cs); - - // Write out, read, and check - XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - s = wb3.getSheetAt(0); - r = s.getRow(0); - assertEquals(false, r.getCell(0).getCellStyle().getShrinkToFit()); - assertEquals(true, r.getCell(1).getCellStyle().getShrinkToFit()); - - XSSFWorkbook wb4 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - assertNotNull(wb4); - wb4.close(); - - XSSFWorkbook wb5 = XSSFTestDataSamples.writeOutAndReadBack(wb3); - assertNotNull(wb5); - wb5.close(); - - wb3.close(); - wb2.close(); - wb1.close(); - - } - - @Test - public void testSetColor() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - Row row = sheet.createRow(0); - - DataFormat format = wb.createDataFormat(); - Cell cell = row.createCell(1); - cell.setCellValue("somevalue"); - CellStyle cellStyle2 = wb.createCellStyle(); - - - cellStyle2.setDataFormat(format.getFormat("###0")); - - cellStyle2.setFillBackgroundColor(IndexedColors.DARK_BLUE.getIndex()); - cellStyle2.setFillForegroundColor(IndexedColors.DARK_BLUE.getIndex()); - cellStyle2.setFillPattern(FillPatternType.SOLID_FOREGROUND); - - cellStyle2.setAlignment(CellStyle.ALIGN_RIGHT); - cellStyle2.setVerticalAlignment(CellStyle.VERTICAL_TOP); - - cell.setCellStyle(cellStyle2); - - Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - Cell cellBack = wbBack.getSheetAt(0).getRow(0).getCell(1); - assertNotNull(cellBack); - CellStyle styleBack = cellBack.getCellStyle(); - assertEquals(IndexedColors.DARK_BLUE.getIndex(), styleBack.getFillBackgroundColor()); - assertEquals(IndexedColors.DARK_BLUE.getIndex(), styleBack.getFillForegroundColor()); - assertEquals(CellStyle.ALIGN_RIGHT, styleBack.getAlignment()); - assertEquals(CellStyle.VERTICAL_TOP, styleBack.getVerticalAlignment()); - assertEquals(FillPatternType.SOLID_FOREGROUND, styleBack.getFillPatternEnum()); - assertEquals(CellStyle.SOLID_FOREGROUND, styleBack.getFillPattern()); - - wbBack.close(); - - wb.close(); - } - - public static void copyStyles(Workbook reference, Workbook target) { - final int numberOfStyles = reference.getNumCellStyles(); - // don't copy default style (style index 0) - for (int i = 1; i < numberOfStyles; i++) { - final CellStyle referenceStyle = reference.getCellStyleAt(i); - final CellStyle targetStyle = target.createCellStyle(); - targetStyle.cloneStyleFrom(referenceStyle); - } - /*System.out.println("Reference : "+reference.getNumCellStyles()); - System.out.println("Target : "+target.getNumCellStyles());*/ - } - - @Test - public void test58084() throws IOException { - Workbook reference = XSSFTestDataSamples.openSampleWorkbook("template.xlsx"); - Workbook target = new XSSFWorkbook(); - copyStyles(reference, target); - - assertEquals(reference.getNumCellStyles(), target.getNumCellStyles()); - final Sheet sheet = target.createSheet(); - final Row row = sheet.createRow(0); - int col = 0; - for (short i = 1; i < target.getNumCellStyles(); i++) { - final Cell cell = row.createCell(col++); - cell.setCellValue("Coucou"+i); - cell.setCellStyle(target.getCellStyleAt(i)); - } - /*OutputStream out = new FileOutputStream("C:\\temp\\58084.xlsx"); - target.write(out); - out.close();*/ - - Workbook copy = XSSFTestDataSamples.writeOutAndReadBack(target); - - // previously this failed because the border-element was not copied over - copy.getCellStyleAt((short)1).getBorderBottomEnum(); - - copy.close(); - - target.close(); - reference.close(); - } - - @Test - public void test58043() { - assertEquals(0, cellStyle.getRotation()); - - cellStyle.setRotation((short)89); - assertEquals(89, cellStyle.getRotation()); - - cellStyle.setRotation((short)90); - assertEquals(90, cellStyle.getRotation()); - - cellStyle.setRotation((short)179); - assertEquals(179, cellStyle.getRotation()); - - cellStyle.setRotation((short)180); - assertEquals(180, cellStyle.getRotation()); - - // negative values are mapped to the correct values for compatibility between HSSF and XSSF - cellStyle.setRotation((short)-1); - assertEquals(91, cellStyle.getRotation()); - - cellStyle.setRotation((short)-89); - assertEquals(179, cellStyle.getRotation()); - - cellStyle.setRotation((short)-90); - assertEquals(180, cellStyle.getRotation()); - } - - @Test - public void bug58996_UsedToWorkIn3_11_ButNotIn3_13() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - - XSSFCellStyle cellStyle = workbook.createCellStyle(); - cellStyle.setFillForegroundColor(null); - assertNull(cellStyle.getFillForegroundColorColor()); - - cellStyle.setFillBackgroundColor(null); - assertNull(cellStyle.getFillBackgroundColorColor()); - - cellStyle.setFillPattern(FillPatternType.NO_FILL); - assertEquals(FillPatternType.NO_FILL, cellStyle.getFillPatternEnum()); - - cellStyle.setBottomBorderColor(null); - assertNull(cellStyle.getBottomBorderXSSFColor()); - - cellStyle.setTopBorderColor(null); - assertNull(cellStyle.getTopBorderXSSFColor()); - - cellStyle.setLeftBorderColor(null); - assertNull(cellStyle.getLeftBorderXSSFColor()); - - cellStyle.setRightBorderColor(null); - assertNull(cellStyle.getRightBorderXSSFColor()); - - workbook.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java deleted file mode 100644 index 1c8732402..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.xssf.XSSFTestDataSamples; - -public final class TestXSSFChart extends TestCase { - - public void testGetAccessors() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithThreeCharts.xlsx"); - XSSFSheet s1 = wb.getSheetAt(0); - XSSFSheet s2 = wb.getSheetAt(1); - XSSFSheet s3 = wb.getSheetAt(2); - - assertEquals(0, s1.getRelations().size()); - assertEquals(1, s2.getRelations().size()); - assertEquals(1, s3.getRelations().size()); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - } - - public void testGetCharts() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithThreeCharts.xlsx"); - - XSSFSheet s1 = wb.getSheetAt(0); - XSSFSheet s2 = wb.getSheetAt(1); - XSSFSheet s3 = wb.getSheetAt(2); - - assertEquals(0, s1.createDrawingPatriarch().getCharts().size()); - assertEquals(2, s2.createDrawingPatriarch().getCharts().size()); - assertEquals(1, s3.createDrawingPatriarch().getCharts().size()); - - // Check the titles - XSSFChart chart = s2.createDrawingPatriarch().getCharts().get(0); - assertEquals(null, chart.getTitle()); - - chart = s2.createDrawingPatriarch().getCharts().get(1); - assertEquals("Pie Chart Title Thingy", chart.getTitle().getString()); - - chart = s3.createDrawingPatriarch().getCharts().get(0); - assertEquals("Sheet 3 Chart with Title", chart.getTitle().getString()); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - } - - public void testAddChartsToNewWorkbook() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet s1 = wb.createSheet(); - XSSFDrawing d1 = s1.createDrawingPatriarch(); - XSSFClientAnchor a1 = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); - XSSFChart c1 = d1.createChart(a1); - - assertEquals(1, d1.getCharts().size()); - assertNotNull(c1.getGraphicFrame()); - assertNotNull(c1.getOrCreateLegend()); - - XSSFClientAnchor a2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60); - XSSFChart c2 = d1.createChart(a2); - assertNotNull(c2); - assertEquals(2, d1.getCharts().size()); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java deleted file mode 100644 index 2eb4fc3e0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.util.CellAddress; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTChartsheet; - -import static org.junit.Assert.*; - -public final class TestXSSFChartSheet { - - @Test - public void testXSSFFactory() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chart_sheet.xlsx"); - assertEquals(4, wb.getNumberOfSheets()); - - //the third sheet is of type 'chartsheet' - assertEquals("Chart1", wb.getSheetName(2)); - assertTrue(wb.getSheetAt(2) instanceof XSSFChartSheet); - assertEquals("Chart1", wb.getSheetAt(2).getSheetName()); - - final CTChartsheet ctChartsheet = ((XSSFChartSheet) wb.getSheetAt(2)).getCTChartsheet(); - assertNotNull(ctChartsheet); - } - - @Test - public void testGetAccessors() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chart_sheet.xlsx"); - XSSFChartSheet sheet = (XSSFChartSheet)wb.getSheetAt(2); - - assertFalse("Row iterator for charts sheets should return zero rows", - sheet.iterator().hasNext()); - - //access to a arbitrary row - assertNull(sheet.getRow(1)); - - //some basic get* accessors - assertEquals(0, sheet.getNumberOfComments()); - assertEquals(0, sheet.getNumHyperlinks()); - assertEquals(0, sheet.getNumMergedRegions()); - assertNull(sheet.getActiveCell()); - assertTrue(sheet.getAutobreaks()); - //noinspection deprecation - assertNull(sheet.getCellComment(0, 0)); - assertNull(sheet.getCellComment(new CellAddress(0, 0))); - assertEquals(0, sheet.getColumnBreaks().length); - assertTrue(sheet.getRowSumsBelow()); - assertNotNull(sheet.createDrawingPatriarch()); - assertNotNull(sheet.getDrawingPatriarch()); - assertNotNull(sheet.getCTChartsheet()); - } - - @Test - public void testGetCharts() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chart_sheet.xlsx"); - - XSSFSheet ns = wb.getSheetAt(0); - XSSFChartSheet cs = (XSSFChartSheet)wb.getSheetAt(2); - - assertEquals(0, ns.createDrawingPatriarch().getCharts().size()); - assertEquals(1, cs.createDrawingPatriarch().getCharts().size()); - - XSSFChart chart = cs.createDrawingPatriarch().getCharts().get(0); - assertNull(chart.getTitle()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColGrouping.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColGrouping.java deleted file mode 100644 index 1d3f97ff8..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColGrouping.java +++ /dev/null @@ -1,303 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; - -/** - * Test asserts the POI produces <cols> element that could be read and properly interpreted by the MS Excel. - * For specification of the "cols" element see the chapter 3.3.1.16 of the "Office Open XML Part 4 - Markup Language Reference.pdf". - * The specification can be downloaded at http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%201st%20edition%20Part%204%20(PDF).zip. - * - *

        - * The test saves xlsx file on a disk if the system property is set: - * -Dpoi.test.xssf.output.dir=${workspace_loc}/poi/build/xssf-output - * - * - */ -public class TestXSSFColGrouping { - - private static final POILogger logger = POILogFactory.getLogger(TestXSSFColGrouping.class); - - - /** - * Tests that POI doesn't produce "col" elements without "width" attribute. - * POI-52186 - */ - @Test - public void testNoColsWithoutWidthWhenGrouping() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("test"); - - sheet.setColumnWidth(4, 5000); - sheet.setColumnWidth(5, 5000); - - sheet.groupColumn((short) 4, (short) 7); - sheet.groupColumn((short) 9, (short) 12); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testNoColsWithoutWidthWhenGrouping"); - sheet = wb2.getSheet("test"); - - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - logger.log(POILogger.DEBUG, "test52186/cols:" + cols); - for (CTCol col : cols.getColArray()) { - assertTrue("Col width attribute is unset: " + col.toString(), col.isSetWidth()); - } - - wb2.close(); - wb1.close(); - } - - /** - * Tests that POI doesn't produce "col" elements without "width" attribute. - * POI-52186 - */ - @Test - public void testNoColsWithoutWidthWhenGroupingAndCollapsing() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("test"); - - sheet.setColumnWidth(4, 5000); - sheet.setColumnWidth(5, 5000); - - sheet.groupColumn((short) 4, (short) 5); - - sheet.setColumnGroupCollapsed(4, true); - - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - logger.log(POILogger.DEBUG, "test52186_2/cols:" + cols); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testNoColsWithoutWidthWhenGroupingAndCollapsing"); - sheet = wb2.getSheet("test"); - - for (int i = 4; i <= 5; i++) { - assertEquals("Unexpected width of column "+ i, 5000, sheet.getColumnWidth(i)); - } - cols = sheet.getCTWorksheet().getColsArray(0); - for (CTCol col : cols.getColArray()) { - assertTrue("Col width attribute is unset: " + col.toString(), col.isSetWidth()); - } - wb2.close(); - wb1.close(); - } - - /** - * Test the cols element is correct in case of NumericRanges.OVERLAPS_2_WRAPS - */ - @Test - public void testMergingOverlappingCols_OVERLAPS_2_WRAPS() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("test"); - - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - CTCol col = cols.addNewCol(); - col.setMin(1 + 1); - col.setMax(4 + 1); - col.setWidth(20); - col.setCustomWidth(true); - - sheet.groupColumn((short) 2, (short) 3); - - sheet.getCTWorksheet().getColsArray(0); - logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_2_WRAPS/cols:" + cols); - - assertEquals(0, cols.getColArray(0).getOutlineLevel()); - assertEquals(2, cols.getColArray(0).getMin()); // 1 based - assertEquals(2, cols.getColArray(0).getMax()); // 1 based - assertEquals(true, cols.getColArray(0).getCustomWidth()); - - assertEquals(1, cols.getColArray(1).getOutlineLevel()); - assertEquals(3, cols.getColArray(1).getMin()); // 1 based - assertEquals(4, cols.getColArray(1).getMax()); // 1 based - assertEquals(true, cols.getColArray(1).getCustomWidth()); - - assertEquals(0, cols.getColArray(2).getOutlineLevel()); - assertEquals(5, cols.getColArray(2).getMin()); // 1 based - assertEquals(5, cols.getColArray(2).getMax()); // 1 based - assertEquals(true, cols.getColArray(2).getCustomWidth()); - - assertEquals(3, cols.sizeOfColArray()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_2_WRAPS"); - sheet = wb2.getSheet("test"); - - for (int i = 1; i <= 4; i++) { - assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i)); - } - - wb2.close(); - wb1.close(); - } - - /** - * Test the cols element is correct in case of NumericRanges.OVERLAPS_1_WRAPS - */ - @Test - public void testMergingOverlappingCols_OVERLAPS_1_WRAPS() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("test"); - - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - CTCol col = cols.addNewCol(); - col.setMin(2 + 1); - col.setMax(4 + 1); - col.setWidth(20); - col.setCustomWidth(true); - - sheet.groupColumn((short) 1, (short) 5); - - cols = sheet.getCTWorksheet().getColsArray(0); - logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_1_WRAPS/cols:" + cols); - - assertEquals(1, cols.getColArray(0).getOutlineLevel()); - assertEquals(2, cols.getColArray(0).getMin()); // 1 based - assertEquals(2, cols.getColArray(0).getMax()); // 1 based - assertEquals(false, cols.getColArray(0).getCustomWidth()); - - assertEquals(1, cols.getColArray(1).getOutlineLevel()); - assertEquals(3, cols.getColArray(1).getMin()); // 1 based - assertEquals(5, cols.getColArray(1).getMax()); // 1 based - assertEquals(true, cols.getColArray(1).getCustomWidth()); - - assertEquals(1, cols.getColArray(2).getOutlineLevel()); - assertEquals(6, cols.getColArray(2).getMin()); // 1 based - assertEquals(6, cols.getColArray(2).getMax()); // 1 based - assertEquals(false, cols.getColArray(2).getCustomWidth()); - - assertEquals(3, cols.sizeOfColArray()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_1_WRAPS"); - sheet = wb2.getSheet("test"); - - for (int i = 2; i <= 4; i++) { - assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i)); - } - - wb2.close(); - wb1.close(); - } - - /** - * Test the cols element is correct in case of NumericRanges.OVERLAPS_1_MINOR - */ - @Test - public void testMergingOverlappingCols_OVERLAPS_1_MINOR() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("test"); - - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - CTCol col = cols.addNewCol(); - col.setMin(2 + 1); - col.setMax(4 + 1); - col.setWidth(20); - col.setCustomWidth(true); - - sheet.groupColumn((short) 3, (short) 5); - - cols = sheet.getCTWorksheet().getColsArray(0); - logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_1_MINOR/cols:" + cols); - - assertEquals(0, cols.getColArray(0).getOutlineLevel()); - assertEquals(3, cols.getColArray(0).getMin()); // 1 based - assertEquals(3, cols.getColArray(0).getMax()); // 1 based - assertEquals(true, cols.getColArray(0).getCustomWidth()); - - assertEquals(1, cols.getColArray(1).getOutlineLevel()); - assertEquals(4, cols.getColArray(1).getMin()); // 1 based - assertEquals(5, cols.getColArray(1).getMax()); // 1 based - assertEquals(true, cols.getColArray(1).getCustomWidth()); - - assertEquals(1, cols.getColArray(2).getOutlineLevel()); - assertEquals(6, cols.getColArray(2).getMin()); // 1 based - assertEquals(6, cols.getColArray(2).getMax()); // 1 based - assertEquals(false, cols.getColArray(2).getCustomWidth()); - - assertEquals(3, cols.sizeOfColArray()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_1_MINOR"); - sheet = wb2.getSheet("test"); - - for (int i = 2; i <= 4; i++) { - assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i)); - } - assertEquals("Unexpected width of column "+ 5, sheet.getDefaultColumnWidth() * 256, sheet.getColumnWidth(5)); - - wb2.close(); - wb1.close(); - } - - /** - * Test the cols element is correct in case of NumericRanges.OVERLAPS_2_MINOR - */ - @Test - public void testMergingOverlappingCols_OVERLAPS_2_MINOR() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("test"); - - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - CTCol col = cols.addNewCol(); - col.setMin(2 + 1); - col.setMax(4 + 1); - col.setWidth(20); - col.setCustomWidth(true); - - sheet.groupColumn((short) 1, (short) 3); - - cols = sheet.getCTWorksheet().getColsArray(0); - logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_2_MINOR/cols:" + cols); - - assertEquals(1, cols.getColArray(0).getOutlineLevel()); - assertEquals(2, cols.getColArray(0).getMin()); // 1 based - assertEquals(2, cols.getColArray(0).getMax()); // 1 based - assertEquals(false, cols.getColArray(0).getCustomWidth()); - - assertEquals(1, cols.getColArray(1).getOutlineLevel()); - assertEquals(3, cols.getColArray(1).getMin()); // 1 based - assertEquals(4, cols.getColArray(1).getMax()); // 1 based - assertEquals(true, cols.getColArray(1).getCustomWidth()); - - assertEquals(0, cols.getColArray(2).getOutlineLevel()); - assertEquals(5, cols.getColArray(2).getMin()); // 1 based - assertEquals(5, cols.getColArray(2).getMax()); // 1 based - assertEquals(true, cols.getColArray(2).getCustomWidth()); - - assertEquals(3, cols.sizeOfColArray()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_2_MINOR"); - sheet = wb2.getSheet("test"); - - for (int i = 2; i <= 4; i++) { - assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i)); - } - assertEquals("Unexpected width of column "+ 1, sheet.getDefaultColumnWidth() * 256, sheet.getColumnWidth(1)); - - wb2.close(); - wb1.close(); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java deleted file mode 100644 index 38406c30a..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.io.IOException; - -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -public final class TestXSSFColor { - - @Test - public void testIndexedColour() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx"); - - // Check the CTColor is as expected - XSSFColor indexed = wb.getCellStyleAt((short)1).getFillBackgroundXSSFColor(); - assertEquals(true, indexed.getCTColor().isSetIndexed()); - assertEquals(64, indexed.getCTColor().getIndexed()); - assertEquals(false, indexed.getCTColor().isSetRgb()); - assertEquals(null, indexed.getCTColor().getRgb()); - - // Now check the XSSFColor - // Note - 64 is a special "auto" one with no rgb equiv - assertEquals(64, indexed.getIndexed()); - assertEquals(null, indexed.getRGB()); - assertEquals(null, indexed.getRGBWithTint()); - assertEquals(null, indexed.getARGBHex()); - assertFalse(indexed.hasAlpha()); - assertFalse(indexed.hasTint()); - - // Now move to one with indexed rgb values - indexed.setIndexed(59); - assertEquals(true, indexed.getCTColor().isSetIndexed()); - assertEquals(59, indexed.getCTColor().getIndexed()); - assertEquals(false, indexed.getCTColor().isSetRgb()); - assertEquals(null, indexed.getCTColor().getRgb()); - - assertEquals(59, indexed.getIndexed()); - assertEquals("FF333300", indexed.getARGBHex()); - - assertEquals(3, indexed.getRGB().length); - assertEquals(0x33, indexed.getRGB()[0]); - assertEquals(0x33, indexed.getRGB()[1]); - assertEquals(0x00, indexed.getRGB()[2]); - - assertEquals(4, indexed.getARGB().length); - assertEquals(-1, indexed.getARGB()[0]); - assertEquals(0x33, indexed.getARGB()[1]); - assertEquals(0x33, indexed.getARGB()[2]); - assertEquals(0x00, indexed.getARGB()[3]); - - // You don't get tinted indexed colours, sorry... - assertEquals(null, indexed.getRGBWithTint()); - - wb.close(); - } - - @Test - public void testRGBColour() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx"); - - // Check the CTColor is as expected - XSSFColor rgb3 = wb.getCellStyleAt((short)25).getFillForegroundXSSFColor(); - assertEquals(false, rgb3.getCTColor().isSetIndexed()); - assertEquals(0, rgb3.getCTColor().getIndexed()); - assertEquals(true, rgb3.getCTColor().isSetTint()); - assertEquals(-0.34999, rgb3.getCTColor().getTint(), 0.00001); - assertEquals(true, rgb3.getCTColor().isSetRgb()); - assertEquals(3, rgb3.getCTColor().getRgb().length); - - // Now check the XSSFColor - assertEquals(0, rgb3.getIndexed()); - assertEquals(-0.34999, rgb3.getTint(), 0.00001); - assertFalse(rgb3.hasAlpha()); - assertTrue(rgb3.hasTint()); - - assertEquals("FFFFFFFF", rgb3.getARGBHex()); - assertEquals(3, rgb3.getRGB().length); - assertEquals(-1, rgb3.getRGB()[0]); - assertEquals(-1, rgb3.getRGB()[1]); - assertEquals(-1, rgb3.getRGB()[2]); - - assertEquals(4, rgb3.getARGB().length); - assertEquals(-1, rgb3.getARGB()[0]); - assertEquals(-1, rgb3.getARGB()[1]); - assertEquals(-1, rgb3.getARGB()[2]); - assertEquals(-1, rgb3.getARGB()[3]); - - // Tint doesn't have the alpha - // tint = -0.34999 - // 255 * (1 + tint) = 165 truncated - // or (byte) -91 (which is 165 - 256) - assertEquals(3, rgb3.getRGBWithTint().length); - assertEquals(-91, rgb3.getRGBWithTint()[0]); - assertEquals(-91, rgb3.getRGBWithTint()[1]); - assertEquals(-91, rgb3.getRGBWithTint()[2]); - - // Set the color to black (no theme). - rgb3.setRGB(new byte[] {0, 0, 0}); - assertEquals("FF000000", rgb3.getARGBHex()); - assertEquals(0, rgb3.getCTColor().getRgb()[0]); - assertEquals(0, rgb3.getCTColor().getRgb()[1]); - assertEquals(0, rgb3.getCTColor().getRgb()[2]); - - // Set another, is fine - rgb3.setRGB(new byte[] {16,17,18}); - assertFalse(rgb3.hasAlpha()); - assertEquals("FF101112", rgb3.getARGBHex()); - assertEquals(0x10, rgb3.getCTColor().getRgb()[0]); - assertEquals(0x11, rgb3.getCTColor().getRgb()[1]); - assertEquals(0x12, rgb3.getCTColor().getRgb()[2]); - - wb.close(); - } - - @Test - public void testARGBColour() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx"); - - // Check the CTColor is as expected - XSSFColor rgb4 = wb.getCellStyleAt((short)1).getFillForegroundXSSFColor(); - assertEquals(false, rgb4.getCTColor().isSetIndexed()); - assertEquals(0, rgb4.getCTColor().getIndexed()); - assertEquals(true, rgb4.getCTColor().isSetRgb()); - assertEquals(4, rgb4.getCTColor().getRgb().length); - - // Now check the XSSFColor - assertEquals(0, rgb4.getIndexed()); - assertEquals(0.0, rgb4.getTint(), 0); - assertFalse(rgb4.hasTint()); - assertTrue(rgb4.hasAlpha()); - - assertEquals("FFFF0000", rgb4.getARGBHex()); - assertEquals(3, rgb4.getRGB().length); - assertEquals(-1, rgb4.getRGB()[0]); - assertEquals(0, rgb4.getRGB()[1]); - assertEquals(0, rgb4.getRGB()[2]); - - assertEquals(4, rgb4.getARGB().length); - assertEquals(-1, rgb4.getARGB()[0]); - assertEquals(-1, rgb4.getARGB()[1]); - assertEquals(0, rgb4.getARGB()[2]); - assertEquals(0, rgb4.getARGB()[3]); - - // Tint doesn't have the alpha - assertEquals(3, rgb4.getRGBWithTint().length); - assertEquals(-1, rgb4.getRGBWithTint()[0]); - assertEquals(0, rgb4.getRGBWithTint()[1]); - assertEquals(0, rgb4.getRGBWithTint()[2]); - - - // Turn on tinting, and check it behaves - // TODO These values are suspected to be wrong... - rgb4.setTint(0.4); - assertTrue(rgb4.hasTint()); - assertEquals(0.4, rgb4.getTint(), 0); - - assertEquals(3, rgb4.getRGBWithTint().length); - assertEquals(-1, rgb4.getRGBWithTint()[0]); - assertEquals(102, rgb4.getRGBWithTint()[1]); - assertEquals(102, rgb4.getRGBWithTint()[2]); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFComment.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFComment.java deleted file mode 100644 index dac2095ae..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFComment.java +++ /dev/null @@ -1,336 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML; -import static org.junit.Assert.*; - -import java.io.*; - -import org.apache.poi.hssf.usermodel.HSSFRichTextString; -import org.apache.poi.ss.usermodel.BaseTestCellComment; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.xmlbeans.XmlObject; -import org.junit.Ignore; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt; - -import com.microsoft.schemas.vml.CTShape; - -/** - * @author Yegor Kozlov - */ -public final class TestXSSFComment extends BaseTestCellComment { - - private static final String TEST_RICHTEXTSTRING = "test richtextstring"; - - public TestXSSFComment() { - super(XSSFITestDataProvider.instance); - } - - /** - * test properties of a newly constructed comment - */ - @Test - public void constructor() { - CommentsTable sheetComments = new CommentsTable(); - assertNotNull(sheetComments.getCTComments().getCommentList()); - assertNotNull(sheetComments.getCTComments().getAuthors()); - assertEquals(1, sheetComments.getCTComments().getAuthors().sizeOfAuthorArray()); - assertEquals(1, sheetComments.getNumberOfAuthors()); - - CTComment ctComment = sheetComments.newComment(CellAddress.A1); - CTShape vmlShape = CTShape.Factory.newInstance(); - - XSSFComment comment = new XSSFComment(sheetComments, ctComment, vmlShape); - assertEquals(null, comment.getString()); - assertEquals(0, comment.getRow()); - assertEquals(0, comment.getColumn()); - assertEquals("", comment.getAuthor()); - assertEquals(false, comment.isVisible()); - } - - @Test - public void getSetCol() { - CommentsTable sheetComments = new CommentsTable(); - XSSFVMLDrawing vml = new XSSFVMLDrawing(); - CTComment ctComment = sheetComments.newComment(CellAddress.A1); - CTShape vmlShape = vml.newCommentShape(); - - XSSFComment comment = new XSSFComment(sheetComments, ctComment, vmlShape); - comment.setColumn(1); - assertEquals(1, comment.getColumn()); - assertEquals(1, new CellReference(ctComment.getRef()).getCol()); - assertEquals(1, vmlShape.getClientDataArray(0).getColumnArray(0).intValue()); - - comment.setColumn(5); - assertEquals(5, comment.getColumn()); - assertEquals(5, new CellReference(ctComment.getRef()).getCol()); - assertEquals(5, vmlShape.getClientDataArray(0).getColumnArray(0).intValue()); - } - - @Test - public void getSetRow() { - CommentsTable sheetComments = new CommentsTable(); - XSSFVMLDrawing vml = new XSSFVMLDrawing(); - CTComment ctComment = sheetComments.newComment(CellAddress.A1); - CTShape vmlShape = vml.newCommentShape(); - - XSSFComment comment = new XSSFComment(sheetComments, ctComment, vmlShape); - comment.setRow(1); - assertEquals(1, comment.getRow()); - assertEquals(1, new CellReference(ctComment.getRef()).getRow()); - assertEquals(1, vmlShape.getClientDataArray(0).getRowArray(0).intValue()); - - comment.setRow(5); - assertEquals(5, comment.getRow()); - assertEquals(5, new CellReference(ctComment.getRef()).getRow()); - assertEquals(5, vmlShape.getClientDataArray(0).getRowArray(0).intValue()); - } - - @Test - public void setString() { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sh = wb.createSheet(); - XSSFComment comment = sh.createDrawingPatriarch().createCellComment(new XSSFClientAnchor()); - - //passing HSSFRichTextString is incorrect - try { - comment.setString(new HSSFRichTextString(TEST_RICHTEXTSTRING)); - fail("expected exception"); - } catch (IllegalArgumentException e){ - assertEquals("Only XSSFRichTextString argument is supported", e.getMessage()); - } - - //simple string argument - comment.setString(TEST_RICHTEXTSTRING); - assertEquals(TEST_RICHTEXTSTRING, comment.getString().getString()); - - //if the text is already set, it should be overridden, not added twice! - comment.setString(TEST_RICHTEXTSTRING); - - CTComment ctComment = comment.getCTComment(); - XmlObject[] obj = ctComment.selectPath( - "declare namespace w='"+NS_SPREADSHEETML+"' .//w:text"); - assertEquals(1, obj.length); - assertEquals(TEST_RICHTEXTSTRING, comment.getString().getString()); - - //sequential call of comment.getString() should return the same XSSFRichTextString object - assertSame(comment.getString(), comment.getString()); - - XSSFRichTextString richText = new XSSFRichTextString(TEST_RICHTEXTSTRING); - XSSFFont font1 = wb.createFont(); - font1.setFontName("Tahoma"); - font1.setFontHeight(8.5); - font1.setItalic(true); - font1.setColor(IndexedColors.BLUE_GREY.getIndex()); - richText.applyFont(0, 5, font1); - - //check the low-level stuff - comment.setString(richText); - obj = ctComment.selectPath( - "declare namespace w='"+NS_SPREADSHEETML+"' .//w:text"); - assertEquals(1, obj.length); - assertSame(comment.getString(), richText); - //check that the rich text is set in the comment - CTRPrElt rPr = richText.getCTRst().getRArray(0).getRPr(); - assertEquals(true, rPr.getIArray(0).getVal()); - assertEquals(8.5, rPr.getSzArray(0).getVal(), 0); - assertEquals(IndexedColors.BLUE_GREY.getIndex(), rPr.getColorArray(0).getIndexed()); - assertEquals("Tahoma", rPr.getRFontArray(0).getVal()); - - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); - } - - @Test - public void author() { - CommentsTable sheetComments = new CommentsTable(); - CTComment ctComment = sheetComments.newComment(CellAddress.A1); - - assertEquals(1, sheetComments.getNumberOfAuthors()); - XSSFComment comment = new XSSFComment(sheetComments, ctComment, null); - assertEquals("", comment.getAuthor()); - comment.setAuthor("Apache POI"); - assertEquals("Apache POI", comment.getAuthor()); - assertEquals(2, sheetComments.getNumberOfAuthors()); - comment.setAuthor("Apache POI"); - assertEquals(2, sheetComments.getNumberOfAuthors()); - comment.setAuthor(""); - assertEquals("", comment.getAuthor()); - assertEquals(2, sheetComments.getNumberOfAuthors()); - } - - @Test - public void testBug58175() throws IOException { - Workbook wb = new SXSSFWorkbook(); - try { - Sheet sheet = wb.createSheet(); - - Row row = sheet.createRow(1); - Cell cell = row.createCell(3); - - cell.setCellValue("F4"); - - CreationHelper factory = wb.getCreationHelper(); - - // When the comment box is visible, have it show in a 1x3 space - ClientAnchor anchor = factory.createClientAnchor(); - anchor.setCol1(cell.getColumnIndex()); - anchor.setCol2(cell.getColumnIndex() + 1); - anchor.setRow1(row.getRowNum()); - anchor.setRow2(row.getRowNum() + 3); - - XSSFClientAnchor ca = (XSSFClientAnchor) anchor; - - // create comments and vmlDrawing parts if they don't exist - CommentsTable comments = ((SXSSFWorkbook) wb).getXSSFWorkbook() - .getSheetAt(0).getCommentsTable(true); - XSSFVMLDrawing vml = ((SXSSFWorkbook) wb).getXSSFWorkbook() - .getSheetAt(0).getVMLDrawing(true); - CTShape vmlShape1 = vml.newCommentShape(); - if (ca.isSet()) { - String position = ca.getCol1() + ", 0, " + ca.getRow1() - + ", 0, " + ca.getCol2() + ", 0, " + ca.getRow2() - + ", 0"; - vmlShape1.getClientDataArray(0).setAnchorArray(0, position); - } - - // create the comment in two different ways and verify that there is no difference - XSSFComment shape1 = new XSSFComment(comments, comments.newComment(CellAddress.A1), vmlShape1); - shape1.setColumn(ca.getCol1()); - shape1.setRow(ca.getRow1()); - - CTShape vmlShape2 = vml.newCommentShape(); - if (ca.isSet()) { - String position = ca.getCol1() + ", 0, " + ca.getRow1() - + ", 0, " + ca.getCol2() + ", 0, " + ca.getRow2() - + ", 0"; - vmlShape2.getClientDataArray(0).setAnchorArray(0, position); - } - - CellAddress ref = new CellAddress(ca.getRow1(), ca.getCol1()); - XSSFComment shape2 = new XSSFComment(comments, comments.newComment(ref), vmlShape2); - - assertEquals(shape1.getAuthor(), shape2.getAuthor()); - assertEquals(shape1.getClientAnchor(), shape2.getClientAnchor()); - assertEquals(shape1.getColumn(), shape2.getColumn()); - assertEquals(shape1.getRow(), shape2.getRow()); - assertEquals(shape1.getCTComment().toString(), shape2.getCTComment().toString()); - assertEquals(shape1.getCTComment().getRef(), shape2.getCTComment().getRef()); - - /*CommentsTable table1 = shape1.getCommentsTable(); - CommentsTable table2 = shape2.getCommentsTable(); - assertEquals(table1.getCTComments().toString(), table2.getCTComments().toString()); - assertEquals(table1.getNumberOfComments(), table2.getNumberOfComments()); - assertEquals(table1.getRelations(), table2.getRelations());*/ - - assertEquals("The vmlShapes should have equal content afterwards", - vmlShape1.toString().replaceAll("_x0000_s\\d+", "_x0000_s0000"), vmlShape2.toString().replaceAll("_x0000_s\\d+", "_x0000_s0000")); - } finally { - wb.close(); - } - } - - @Ignore("Used for manual testing with opening the resulting Workbook in Excel") - @Test - public void testBug58175a() throws IOException { - Workbook wb = new SXSSFWorkbook(); - try { - Sheet sheet = wb.createSheet(); - - Row row = sheet.createRow(1); - Cell cell = row.createCell(3); - - cell.setCellValue("F4"); - - Drawing drawing = sheet.createDrawingPatriarch(); - - CreationHelper factory = wb.getCreationHelper(); - - // When the comment box is visible, have it show in a 1x3 space - ClientAnchor anchor = factory.createClientAnchor(); - anchor.setCol1(cell.getColumnIndex()); - anchor.setCol2(cell.getColumnIndex() + 1); - anchor.setRow1(row.getRowNum()); - anchor.setRow2(row.getRowNum() + 3); - - // Create the comment and set the text+author - Comment comment = drawing.createCellComment(anchor); - RichTextString str = factory.createRichTextString("Hello, World!"); - comment.setString(str); - comment.setAuthor("Apache POI"); - - /* fixed the problem as well - * comment.setColumn(cell.getColumnIndex()); - * comment.setRow(cell.getRowIndex()); - */ - - // Assign the comment to the cell - cell.setCellComment(comment); - - OutputStream out = new FileOutputStream("C:\\temp\\58175.xlsx"); - try { - wb.write(out); - } finally { - out.close(); - } - } finally { - wb.close(); - } - } - - @Test - public void bug57838DeleteRowsWthCommentsBug() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57838.xlsx"); - Sheet sheet=wb.getSheetAt(0); - Comment comment1 = sheet.getCellComment(new CellAddress(2, 1)); - assertNotNull(comment1); - Comment comment2 = sheet.getCellComment(new CellAddress(2, 2)); - assertNotNull(comment2); - Row row=sheet.getRow(2); - assertNotNull(row); - - sheet.removeRow(row); // Remove row from index 2 - - row=sheet.getRow(2); - assertNull(row); // Row is null since we deleted it. - - comment1 = sheet.getCellComment(new CellAddress(2, 1)); - assertNull(comment1); // comment should be null but will fail due to bug - comment2 = sheet.getCellComment(new CellAddress(2, 2)); - assertNull(comment2); // comment should be null but will fail due to bug - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java deleted file mode 100644 index a73a0cf7c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestConditionalFormatting; -import org.apache.poi.ss.usermodel.Color; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.junit.Test; - -/** - * XSSF-specific Conditional Formatting tests - */ -public class TestXSSFConditionalFormatting extends BaseTestConditionalFormatting { - public TestXSSFConditionalFormatting(){ - super(XSSFITestDataProvider.instance); - } - - @Override - protected void assertColour(String hexExpected, Color actual) { - assertNotNull("Colour must be given", actual); - XSSFColor colour = (XSSFColor)actual; - if (hexExpected.length() == 8) { - assertEquals(hexExpected, colour.getARGBHex()); - } else { - assertEquals(hexExpected, colour.getARGBHex().substring(2)); - } - } - - @Test - public void testRead() throws IOException { - testRead("WithConditionalFormatting.xlsx"); - } - - @Test - public void testReadOffice2007() throws IOException { - testReadOffice2007("NewStyleConditionalFormattings.xlsx"); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataFormat.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataFormat.java deleted file mode 100644 index c7179531d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataFormat.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestDataFormat; -import org.apache.poi.ss.usermodel.BuiltinFormats; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.DataFormat; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -/** - * Tests for {@link XSSFDataFormat} - */ -public final class TestXSSFDataFormat extends BaseTestDataFormat { - - public TestXSSFDataFormat() { - super(XSSFITestDataProvider.instance); - } - - /** - * [Bug 49928] formatCellValue returns incorrect value for \u00a3 formatted cells - */ - @Override - @Test - public void test49928() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49928.xlsx"); - doTest49928Core(wb); - - DataFormat dataFormat = wb.createDataFormat(); - - // As of 2015-12-27, there is no way to override a built-in number format with POI XSSFWorkbook - // 49928.xlsx has been saved with a poundFmt that overrides the default value (dollar) - short poundFmtIdx = wb.getSheetAt(0).getRow(0).getCell(0).getCellStyle().getDataFormat(); - assertEquals(poundFmtIdx, dataFormat.getFormat(poundFmt)); - - // now create a custom format with Pound (\u00a3) - - String customFmt = "\u00a3##.00[Yellow]"; - assertNotBuiltInFormat(customFmt); - short customFmtIdx = dataFormat.getFormat(customFmt); - assertTrue(customFmtIdx >= BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX); - assertEquals(customFmt, dataFormat.getFormat(customFmtIdx)); - - wb.close(); - } - - /** - * [Bug 58532] Handle formats that go numnum, numK, numM etc - */ - @Override - @Test - public void test58532() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("FormatKM.xlsx"); - doTest58532Core(wb); - wb.close(); - } - - /** - * [Bug 58778] Built-in number formats can be overridden with XSSFDataFormat.putFormat(int id, String fmt) - */ - @Test - public void test58778() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - Cell cell = wb1.createSheet("bug58778").createRow(0).createCell(0); - cell.setCellValue(5.25); - CellStyle style = wb1.createCellStyle(); - - XSSFDataFormat dataFormat = wb1.createDataFormat(); - - short poundFmtIdx = 6; - dataFormat.putFormat(poundFmtIdx, poundFmt); - style.setDataFormat(poundFmtIdx); - cell.setCellStyle(style); - // Cell should appear as "5" - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutCloseAndReadBack(wb1); - cell = wb2.getSheet("bug58778").getRow(0).getCell(0); - assertEquals(5.25, cell.getNumericCellValue(), 0); - - style = cell.getCellStyle(); - assertEquals(poundFmt, style.getDataFormatString()); - assertEquals(poundFmtIdx, style.getDataFormat()); - - // manually check the file to make sure the cell is rendered as "5" - // Verified with LibreOffice 4.2.8.2 on 2015-12-28 - wb2.close(); - wb1.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataValidation.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataValidation.java deleted file mode 100644 index e0da16ba2..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataValidation.java +++ /dev/null @@ -1,344 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.math.BigDecimal; -import java.util.List; - -import org.apache.poi.ss.usermodel.BaseTestDataValidation; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType; -import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -public class TestXSSFDataValidation extends BaseTestDataValidation { - - public TestXSSFDataValidation(){ - super(XSSFITestDataProvider.instance); - } - - @Test - public void testAddValidations() throws Exception { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("DataValidations-49244.xlsx"); - Sheet sheet = wb1.getSheetAt(0); - List dataValidations = ((XSSFSheet)sheet).getDataValidations(); - -/** - * For each validation type, there are two cells with the same validation. This tests - * application of a single validation definition to multiple cells. - * - * For list ( 3 validations for explicit and 3 for formula ) - * - one validation that allows blank. - * - one that does not allow blank. - * - one that does not show the drop down arrow. - * = 2 - * - * For number validations ( integer/decimal and text length ) with 8 different types of operators. - * = 50 - * - * = 52 ( Total ) - */ - assertEquals(52,dataValidations.size()); - - DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); - int[] validationTypes = new int[]{ValidationType.INTEGER,ValidationType.DECIMAL,ValidationType.TEXT_LENGTH}; - - int[] singleOperandOperatorTypes = new int[]{ - OperatorType.LESS_THAN,OperatorType.LESS_OR_EQUAL, - OperatorType.GREATER_THAN,OperatorType.GREATER_OR_EQUAL, - OperatorType.EQUAL,OperatorType.NOT_EQUAL - } ; - int[] doubleOperandOperatorTypes = new int[]{ - OperatorType.BETWEEN,OperatorType.NOT_BETWEEN - }; - - BigDecimal value = new BigDecimal("10"),value2 = new BigDecimal("20"); - BigDecimal dvalue = new BigDecimal("10.001"),dvalue2 = new BigDecimal("19.999"); - final int lastRow = sheet.getLastRowNum(); - int offset = lastRow + 3; - - int lastKnownNumValidations = dataValidations.size(); - - Row row = sheet.createRow(offset++); - Cell cell = row.createCell(0); - DataValidationConstraint explicitListValidation = dataValidationHelper.createExplicitListConstraint(new String[]{"MA","MI","CA"}); - CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(cell.getRowIndex(), cell.getColumnIndex(), cell.getRowIndex(), cell.getColumnIndex()); - DataValidation dataValidation = dataValidationHelper.createValidation(explicitListValidation, cellRangeAddressList); - setOtherValidationParameters(dataValidation); - sheet.addValidationData(dataValidation); - lastKnownNumValidations++; - - row = sheet.createRow(offset++); - cell = row.createCell(0); - - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(cell.getRowIndex(), cell.getColumnIndex(), cell.getRowIndex(), cell.getColumnIndex()); - - Cell firstCell = row.createCell(1);firstCell.setCellValue("UT"); - Cell secondCell = row.createCell(2);secondCell.setCellValue("MN"); - Cell thirdCell = row.createCell(3);thirdCell.setCellValue("IL"); - - int rowNum = row.getRowNum() + 1; - String listFormula = new StringBuilder("$B$").append(rowNum).append(":").append("$D$").append(rowNum).toString(); - DataValidationConstraint formulaListValidation = dataValidationHelper.createFormulaListConstraint(listFormula); - - dataValidation = dataValidationHelper.createValidation(formulaListValidation, cellRangeAddressList); - setOtherValidationParameters(dataValidation); - sheet.addValidationData(dataValidation); - lastKnownNumValidations++; - - offset++; - offset++; - - for (int i = 0; i < validationTypes.length; i++) { - int validationType = validationTypes[i]; - offset = offset + 2; - final Row row0 = sheet.createRow(offset++); - Cell cell_10 = row0.createCell(0); - cell_10.setCellValue(validationType==ValidationType.DECIMAL ? "Decimal " : validationType==ValidationType.INTEGER ? "Integer" : "Text Length"); - offset++; - for (int j = 0; j < singleOperandOperatorTypes.length; j++) { - int operatorType = singleOperandOperatorTypes[j]; - final Row row1 = sheet.createRow(offset++); - - //For Integer (> and >=) we add 1 extra cell for validations whose formulae reference other cells. - final Row row2 = i==0 && j < 2 ? sheet.createRow(offset++) : null; - - cell_10 = row1.createCell(0); - cell_10.setCellValue(XSSFDataValidation.operatorTypeMappings.get(operatorType).toString()); - Cell cell_11 = row1.createCell(1); - Cell cell_21 = row1.createCell(2); - Cell cell_22 = i==0 && j < 2 ? row2.createCell(2) : null; - - Cell cell_13 = row1.createCell(3); - - - cell_13.setCellType(CellType.NUMERIC); - cell_13.setCellValue(validationType==ValidationType.DECIMAL ? dvalue.doubleValue() : value.intValue()); - - - //First create value based validation; - DataValidationConstraint constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, value.toString(), null); - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_11.getRowIndex(),cell_11.getRowIndex(),cell_11.getColumnIndex(),cell_11.getColumnIndex())); - DataValidation validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - setOtherValidationParameters(validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations,((XSSFSheet)sheet).getDataValidations().size()); - - //Now create real formula based validation. - String formula1 = new CellReference(cell_13.getRowIndex(),cell_13.getColumnIndex()).formatAsString(); - constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, formula1, null); - if (i==0 && j==0) { - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex())); - validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - setOtherValidationParameters(validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); - - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex())); - validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - setOtherValidationParameters( validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); - } else if(i==0 && j==1 ){ - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex())); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex())); - validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - setOtherValidationParameters( validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); - } else { - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex())); - validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - setOtherValidationParameters(validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); - } - } - - for (int operatorType : doubleOperandOperatorTypes) { - final Row row1 = sheet.createRow(offset++); - - cell_10 = row1.createCell(0); - cell_10.setCellValue(XSSFDataValidation.operatorTypeMappings.get(operatorType).toString()); - - Cell cell_11 = row1.createCell(1); - Cell cell_21 = row1.createCell(2); - - Cell cell_13 = row1.createCell(3); - Cell cell_14 = row1.createCell(4); - - - String value1String = validationType==ValidationType.DECIMAL ? dvalue.toString() : value.toString(); - cell_13.setCellType(CellType.NUMERIC); - cell_13.setCellValue(validationType==ValidationType.DECIMAL ? dvalue.doubleValue() : value.intValue()); - - String value2String = validationType==ValidationType.DECIMAL ? dvalue2.toString() : value2.toString(); - cell_14.setCellType(CellType.NUMERIC); - cell_14.setCellValue(validationType==ValidationType.DECIMAL ? dvalue2.doubleValue() : value2.intValue()); - - - //First create value based validation; - DataValidationConstraint constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, value1String, value2String); - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_11.getRowIndex(),cell_11.getRowIndex(),cell_11.getColumnIndex(),cell_11.getColumnIndex())); - DataValidation validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - setOtherValidationParameters(validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations,((XSSFSheet)sheet).getDataValidations().size()); - - - //Now create real formula based validation. - String formula1 = new CellReference(cell_13.getRowIndex(),cell_13.getColumnIndex()).formatAsString(); - String formula2 = new CellReference(cell_14.getRowIndex(),cell_14.getColumnIndex()).formatAsString(); - constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, formula1, formula2); - cellRangeAddressList = new CellRangeAddressList(); - cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(),cell_21.getRowIndex(),cell_21.getColumnIndex(),cell_21.getColumnIndex())); - validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); - - setOtherValidationParameters(validation); - sheet.addValidationData(validation); - assertEquals(++lastKnownNumValidations,((XSSFSheet)sheet).getDataValidations().size()); - } - } - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - Sheet sheetAt = wb2.getSheetAt(0); - assertEquals(lastKnownNumValidations,((XSSFSheet)sheetAt).getDataValidations().size()); - wb2.close(); - } - - protected void setOtherValidationParameters(DataValidation validation) { - boolean yesNo = true; - validation.setEmptyCellAllowed(yesNo); - validation.setShowErrorBox(yesNo); - validation.setShowPromptBox(yesNo); - validation.createErrorBox("Error Message Title", "Error Message"); - validation.createPromptBox("Prompt", "Enter some value"); - validation.setSuppressDropDownArrow(yesNo); - } - - @Test - public void test53965() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - List lst = sheet.getDataValidations(); //<-- works - assertEquals(0, lst.size()); - - //create the cell that will have the validation applied - sheet.createRow(0).createCell(0); - - DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); - DataValidationConstraint constraint = dataValidationHelper.createCustomConstraint("SUM($A$1:$A$1) <= 3500"); - CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0); - DataValidation validation = dataValidationHelper.createValidation(constraint, addressList); - sheet.addValidationData(validation); - - // this line caused XmlValueOutOfRangeException , see Bugzilla 3965 - lst = sheet.getDataValidations(); - assertEquals(1, lst.size()); - } finally { - wb.close(); - } - } - - @Test - public void testDefaultAllowBlank() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - - final XSSFDataValidation validation = createValidation(sheet); - sheet.addValidationData(validation); - - final List dataValidations = sheet.getDataValidations(); - assertEquals(true, dataValidations.get(0).getCtDdataValidation().getAllowBlank()); - } finally { - wb.close(); - } - } - - @Test - public void testSetAllowBlankToFalse() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - - final XSSFDataValidation validation = createValidation(sheet); - validation.getCtDdataValidation().setAllowBlank(false); - - sheet.addValidationData(validation); - - final List dataValidations = sheet.getDataValidations(); - assertEquals(false, dataValidations.get(0).getCtDdataValidation().getAllowBlank()); - } finally { - wb.close(); - } - } - - @Test - public void testSetAllowBlankToTrue() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - - final XSSFDataValidation validation = createValidation(sheet); - validation.getCtDdataValidation().setAllowBlank(true); - - sheet.addValidationData(validation); - - final List dataValidations = sheet.getDataValidations(); - assertEquals(true, dataValidations.get(0).getCtDdataValidation().getAllowBlank()); - } finally { - wb.close(); - } - } - - private XSSFDataValidation createValidation(XSSFSheet sheet) { - //create the cell that will have the validation applied - final Row row = sheet.createRow(0); - row.createCell(0); - - DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); - - DataValidationConstraint constraint = dataValidationHelper.createCustomConstraint("true"); - final XSSFDataValidation validation = (XSSFDataValidation) dataValidationHelper.createValidation(constraint, new CellRangeAddressList(0, 0, 0, 0)); - return validation; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataValidationConstraint.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataValidationConstraint.java deleted file mode 100644 index a3475f4a5..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDataValidationConstraint.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; -import org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType; -import org.junit.Test; - -public class TestXSSFDataValidationConstraint { - static final int listType = ValidationType.LIST; - static final int ignoredType = OperatorType.IGNORED; - - // See bug 59719 - @Test - public void listLiteralsQuotesAreStripped_formulaConstructor() { - // literal list, using formula constructor - String literal = "\"one, two, three\""; - String[] expected = new String[] { "one", "two", "three" }; - DataValidationConstraint constraint = new XSSFDataValidationConstraint(listType, ignoredType, literal, null); - assertArrayEquals(expected, constraint.getExplicitListValues()); - // Excel and DataValidationConstraint parser ignore (strip) whitespace; quotes should still be intact - // FIXME: whitespace wasn't stripped - assertEquals(literal, constraint.getFormula1()); - } - - @Test - public void listLiteralsQuotesAreStripped_arrayConstructor() { - // literal list, using array constructor - String literal = "\"one, two, three\""; - String[] expected = new String[] { "one", "two", "three" }; - DataValidationConstraint constraint = new XSSFDataValidationConstraint(expected); - assertArrayEquals(expected, constraint.getExplicitListValues()); - // Excel and DataValidationConstraint parser ignore (strip) whitespace; quotes should still be intact - assertEquals(literal.replace(" ", ""), constraint.getFormula1()); - } - - @Test - public void rangeReference() { - // (unnamed range) reference list - String reference = "A1:A5"; - DataValidationConstraint constraint = new XSSFDataValidationConstraint(listType, ignoredType, reference, null); - assertNull(constraint.getExplicitListValues()); - assertEquals("A1:A5", constraint.getFormula1()); - } - - @Test - public void namedRangeReference() { - // named range list - String namedRange = "MyNamedRange"; - DataValidationConstraint constraint = new XSSFDataValidationConstraint(listType, ignoredType, namedRange, null); - assertNull(constraint.getExplicitListValues()); - assertEquals("MyNamedRange", constraint.getFormula1()); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDialogSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDialogSheet.java deleted file mode 100644 index 8a72b4105..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDialogSheet.java +++ /dev/null @@ -1,173 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet; - - -public class TestXSSFDialogSheet extends TestCase { - - - public void testCreateDialogSheet() { - XSSFWorkbook workbook = new XSSFWorkbook(); - Sheet dialogsheet = workbook.createDialogsheet("Dialogsheet 1", CTDialogsheet.Factory.newInstance()); - assertNotNull(dialogsheet); - } - - public void testGetDialog() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet dialogsheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertTrue(dialogsheet.getDialog()); - - } - - public void testAddRow() { - XSSFWorkbook workbook = new XSSFWorkbook(); - Sheet dialogsheet = workbook.createDialogsheet("Dialogsheet 1", CTDialogsheet.Factory.newInstance()); - assertNotNull(dialogsheet); - Row row = dialogsheet.createRow(0); - assertNull(row); - } - - public void testGetSetAutoBreaks() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertTrue(sheet.getAutobreaks()); - sheet.setAutobreaks(false); - assertFalse(sheet.getAutobreaks()); - } - - public void testIsSetFitToPage() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertFalse(sheet.getFitToPage()); - sheet.setFitToPage(true); - assertTrue(sheet.getFitToPage()); - sheet.setFitToPage(false); - assertFalse(sheet.getFitToPage()); - } - - - public void testGetFooter() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertNotNull(sheet.getFooter()); - sheet.getFooter().setCenter("test center footer"); - assertEquals("test center footer", sheet.getFooter().getCenter()); - } - - public void testGetAllHeadersFooters() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertNotNull(sheet); - assertNotNull(sheet.getOddFooter()); - assertNotNull(sheet.getEvenFooter()); - assertNotNull(sheet.getFirstFooter()); - assertNotNull(sheet.getOddHeader()); - assertNotNull(sheet.getEvenHeader()); - assertNotNull(sheet.getFirstHeader()); - - assertEquals("", sheet.getOddFooter().getLeft()); - sheet.getOddFooter().setLeft("odd footer left"); - assertEquals("odd footer left", sheet.getOddFooter().getLeft()); - - assertEquals("", sheet.getEvenFooter().getLeft()); - sheet.getEvenFooter().setLeft("even footer left"); - assertEquals("even footer left", sheet.getEvenFooter().getLeft()); - - assertEquals("", sheet.getFirstFooter().getLeft()); - sheet.getFirstFooter().setLeft("first footer left"); - assertEquals("first footer left", sheet.getFirstFooter().getLeft()); - - assertEquals("", sheet.getOddHeader().getLeft()); - sheet.getOddHeader().setLeft("odd header left"); - assertEquals("odd header left", sheet.getOddHeader().getLeft()); - - assertEquals("", sheet.getOddHeader().getRight()); - sheet.getOddHeader().setRight("odd header right"); - assertEquals("odd header right", sheet.getOddHeader().getRight()); - - assertEquals("", sheet.getOddHeader().getCenter()); - sheet.getOddHeader().setCenter("odd header center"); - assertEquals("odd header center", sheet.getOddHeader().getCenter()); - - } - - public void testGetSetHorizontallyCentered() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertFalse(sheet.getHorizontallyCenter()); - sheet.setHorizontallyCenter(true); - assertTrue(sheet.getHorizontallyCenter()); - sheet.setHorizontallyCenter(false); - assertFalse(sheet.getHorizontallyCenter()); - } - - public void testGetSetVerticallyCentered() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertFalse(sheet.getVerticallyCenter()); - sheet.setVerticallyCenter(true); - assertTrue(sheet.getVerticallyCenter()); - sheet.setVerticallyCenter(false); - assertFalse(sheet.getVerticallyCenter()); - } - - public void testIsSetPrintGridlines() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertFalse(sheet.isPrintGridlines()); - sheet.setPrintGridlines(true); - assertTrue(sheet.isPrintGridlines()); - } - - public void testIsSetDisplayFormulas() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertFalse(sheet.isDisplayFormulas()); - sheet.setDisplayFormulas(true); - assertTrue(sheet.isDisplayFormulas()); - } - - public void testIsSetDisplayGridLines() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertTrue(sheet.isDisplayGridlines()); - sheet.setDisplayGridlines(false); - assertFalse(sheet.isDisplayGridlines()); - } - - public void testIsSetDisplayRowColHeadings() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertTrue(sheet.isDisplayRowColHeadings()); - sheet.setDisplayRowColHeadings(false); - assertFalse(sheet.isDisplayRowColHeadings()); - } - - public void testGetScenarioProtect() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFDialogsheet sheet = workbook.createDialogsheet("Dialogsheet 1", null); - assertFalse(sheet.getScenarioProtect()); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java deleted file mode 100644 index 8bcce73e3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java +++ /dev/null @@ -1,786 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.awt.Color; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLDocumentPart.RelationPart; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.FontUnderline; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing; - -public class TestXSSFDrawing { - @Test - public void testRead() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - //the sheet has one relationship and it is XSSFDrawing - List rels = sheet.getRelationParts(); - assertEquals(1, rels.size()); - RelationPart rp = rels.get(0); - assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - - XSSFDrawing drawing = (XSSFDrawing)rp.getDocumentPart(); - //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing - assertSame(drawing, sheet.createDrawingPatriarch()); - String drawingId = rp.getRelationship().getId(); - - //there should be a relation to this drawing in the worksheet - assertTrue(sheet.getCTWorksheet().isSetDrawing()); - assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId()); - - List shapes = drawing.getShapes(); - assertEquals(6, shapes.size()); - - assertTrue(shapes.get(0) instanceof XSSFPicture); - assertTrue(shapes.get(1) instanceof XSSFPicture); - assertTrue(shapes.get(2) instanceof XSSFPicture); - assertTrue(shapes.get(3) instanceof XSSFPicture); - assertTrue(shapes.get(4) instanceof XSSFSimpleShape); - assertTrue(shapes.get(5) instanceof XSSFPicture); - - for(XSSFShape sh : shapes) assertNotNull(sh.getAnchor()); - - checkRewrite(wb); - wb.close(); - } - - @Test - public void testNew() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet(); - //multiple calls of createDrawingPatriarch should return the same instance of XSSFDrawing - XSSFDrawing dr1 = sheet.createDrawingPatriarch(); - XSSFDrawing dr2 = sheet.createDrawingPatriarch(); - assertSame(dr1, dr2); - - List rels = sheet.getRelationParts(); - assertEquals(1, rels.size()); - RelationPart rp = rels.get(0); - assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - - XSSFDrawing drawing = rp.getDocumentPart(); - String drawingId = rp.getRelationship().getId(); - - //there should be a relation to this drawing in the worksheet - assertTrue(sheet.getCTWorksheet().isSetDrawing()); - assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId()); - - XSSFConnector c1= drawing.createConnector(new XSSFClientAnchor(0,0,0,0,0,0,2,2)); - c1.setLineWidth(2.5); - c1.setLineStyle(1); - - XSSFShapeGroup c2 = drawing.createGroup(new XSSFClientAnchor(0,0,0,0,0,0,5,5)); - assertNotNull(c2); - - XSSFSimpleShape c3 = drawing.createSimpleShape(new XSSFClientAnchor(0,0,0,0,2,2,3,4)); - c3.setText(new XSSFRichTextString("Test String")); - c3.setFillColor(128, 128, 128); - - XSSFTextBox c4 = drawing.createTextbox(new XSSFClientAnchor(0,0,0,0,4,4,5,6)); - XSSFRichTextString rt = new XSSFRichTextString("Test String"); - rt.applyFont(0, 5, wb1.createFont()); - rt.applyFont(5, 6, wb1.createFont()); - c4.setText(rt); - - c4.setNoFill(true); - assertEquals(4, drawing.getCTDrawing().sizeOfTwoCellAnchorArray()); - - List shapes = drawing.getShapes(); - assertEquals(4, shapes.size()); - assertTrue(shapes.get(0) instanceof XSSFConnector); - assertTrue(shapes.get(1) instanceof XSSFShapeGroup); - assertTrue(shapes.get(2) instanceof XSSFSimpleShape); - assertTrue(shapes.get(3) instanceof XSSFSimpleShape); // - - // Save and re-load it - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - - // Check - dr1 = sheet.createDrawingPatriarch(); - CTDrawing ctDrawing = dr1.getCTDrawing(); - - // Connector, shapes and text boxes are all two cell anchors - assertEquals(0, ctDrawing.sizeOfAbsoluteAnchorArray()); - assertEquals(0, ctDrawing.sizeOfOneCellAnchorArray()); - assertEquals(4, ctDrawing.sizeOfTwoCellAnchorArray()); - - shapes = dr1.getShapes(); - assertEquals(4, shapes.size()); - assertTrue(shapes.get(0) instanceof XSSFConnector); - assertTrue(shapes.get(1) instanceof XSSFShapeGroup); - assertTrue(shapes.get(2) instanceof XSSFSimpleShape); - assertTrue(shapes.get(3) instanceof XSSFSimpleShape); // - - // Ensure it got the right namespaces - String xml = ctDrawing.toString(); - assertTrue(xml.contains("xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"")); - assertTrue(xml.contains("xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"")); - - checkRewrite(wb2); - wb2.close(); - } - - @Test - public void testMultipleDrawings() throws IOException{ - XSSFWorkbook wb = new XSSFWorkbook(); - for (int i = 0; i < 3; i++) { - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - assertNotNull(drawing); - } - OPCPackage pkg = wb.getPackage(); - try { - assertEquals(3, pkg.getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size()); - checkRewrite(wb); - } finally { - pkg.close(); - } - wb.close(); - } - - @Test - public void testClone() throws Exception{ - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx"); - XSSFSheet sheet1 = wb.getSheetAt(0); - - XSSFSheet sheet2 = wb.cloneSheet(0); - - //the source sheet has one relationship and it is XSSFDrawing - List rels1 = sheet1.getRelations(); - assertEquals(1, rels1.size()); - assertTrue(rels1.get(0) instanceof XSSFDrawing); - - List rels2 = sheet2.getRelations(); - assertEquals(1, rels2.size()); - assertTrue(rels2.get(0) instanceof XSSFDrawing); - - XSSFDrawing drawing1 = (XSSFDrawing)rels1.get(0); - XSSFDrawing drawing2 = (XSSFDrawing)rels2.get(0); - assertNotSame(drawing1, drawing2); // drawing2 is a clone of drawing1 - - List shapes1 = drawing1.getShapes(); - List shapes2 = drawing2.getShapes(); - assertEquals(shapes1.size(), shapes2.size()); - - for(int i = 0; i < shapes1.size(); i++){ - XSSFShape sh1 = shapes1.get(i); - XSSFShape sh2 = shapes2.get(i); - - assertTrue(sh1.getClass() == sh2.getClass()); - assertEquals(sh1.getShapeProperties().toString(), sh2.getShapeProperties().toString()); - } - - checkRewrite(wb); - wb.close(); - } - - /** - * ensure that rich text attributes defined in a XSSFRichTextString - * are passed to XSSFSimpleShape. - * - * See Bugzilla 52219. - */ - @Test - public void testRichText() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - XSSFRichTextString rt = new XSSFRichTextString("Test String"); - - XSSFFont font = wb.createFont(); - font.setColor(new XSSFColor(new Color(0, 128, 128))); - font.setItalic(true); - font.setBold(true); - font.setUnderline(FontUnderline.SINGLE); - rt.applyFont(font); - - shape.setText(rt); - - CTTextParagraph pr = shape.getCTShape().getTxBody().getPArray(0); - assertEquals(1, pr.sizeOfRArray()); - - CTTextCharacterProperties rPr = pr.getRArray(0).getRPr(); - assertEquals(true, rPr.getB()); - assertEquals(true, rPr.getI()); - assertEquals(STTextUnderlineType.SNG, rPr.getU()); - assertArrayEquals( - new byte[]{0, (byte)128, (byte)128} , - rPr.getSolidFill().getSrgbClr().getVal()); - - checkRewrite(wb); - wb.close(); - } - - /** - * test that anchor is not null when reading shapes from existing drawings - */ - @Test - public void testReadAnchors() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4); - XSSFShape shape1 = drawing.createTextbox(anchor1); - assertNotNull(shape1); - - XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 5); - XSSFShape shape2 = drawing.createTextbox(anchor2); - assertNotNull(shape2); - - int pictureIndex= wb1.addPicture(new byte[]{}, XSSFWorkbook.PICTURE_TYPE_PNG); - XSSFClientAnchor anchor3 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 6); - XSSFShape shape3 = drawing.createPicture(anchor3, pictureIndex); - assertNotNull(shape3); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - drawing = sheet.createDrawingPatriarch(); - List shapes = drawing.getShapes(); - assertEquals(shapes.get(0).getAnchor(), anchor1); - assertEquals(shapes.get(1).getAnchor(), anchor2); - assertEquals(shapes.get(2).getAnchor(), anchor3); - - checkRewrite(wb2); - wb2.close(); - } - - /** - * ensure that font and color rich text attributes defined in a XSSFRichTextString - * are passed to XSSFSimpleShape. - * - * See Bugzilla 54969. - */ - @Test - public void testRichTextFontAndColor() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - XSSFRichTextString rt = new XSSFRichTextString("Test String"); - - XSSFFont font = wb.createFont(); - font.setColor(new XSSFColor(new Color(0, 128, 128))); - font.setFontName("Arial"); - rt.applyFont(font); - - shape.setText(rt); - - CTTextParagraph pr = shape.getCTShape().getTxBody().getPArray(0); - assertEquals(1, pr.sizeOfRArray()); - - CTTextCharacterProperties rPr = pr.getRArray(0).getRPr(); - assertEquals("Arial", rPr.getLatin().getTypeface()); - assertArrayEquals( - new byte[]{0, (byte)128, (byte)128} , - rPr.getSolidFill().getSrgbClr().getVal()); - checkRewrite(wb); - wb.close(); - } - - /** - * Test setText single paragraph to ensure backwards compatibility - */ - @Test - public void testSetTextSingleParagraph() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - XSSFRichTextString rt = new XSSFRichTextString("Test String"); - - XSSFFont font = wb.createFont(); - font.setColor(new XSSFColor(new Color(0, 255, 255))); - font.setFontName("Arial"); - rt.applyFont(font); - - shape.setText(rt); - - List paras = shape.getTextParagraphs(); - assertEquals(1, paras.size()); - assertEquals("Test String", paras.get(0).getText()); - - List runs = paras.get(0).getTextRuns(); - assertEquals(1, runs.size()); - assertEquals("Arial", runs.get(0).getFontFamily()); - - Color clr = runs.get(0).getFontColor(); - assertArrayEquals( - new int[] { 0, 255, 255 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - checkRewrite(wb); - wb.close(); - } - - /** - * Test addNewTextParagraph - */ - @Test - public void testAddNewTextParagraph() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - - XSSFTextParagraph para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 1"); - - List paras = shape.getTextParagraphs(); - assertEquals(2, paras.size()); // this should be 2 as XSSFSimpleShape creates a default paragraph (no text), and then we add a string to that. - - List runs = para.getTextRuns(); - assertEquals(1, runs.size()); - assertEquals("Line 1", runs.get(0).getText()); - - checkRewrite(wb); - wb.close(); - } - - /** - * Test addNewTextParagraph using RichTextString - */ - @Test - public void testAddNewTextParagraphWithRTS() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - XSSFRichTextString rt = new XSSFRichTextString("Test Rich Text String"); - - XSSFFont font = wb1.createFont(); - font.setColor(new XSSFColor(new Color(0, 255, 255))); - font.setFontName("Arial"); - rt.applyFont(font); - - XSSFFont midfont = wb1.createFont(); - midfont.setColor(new XSSFColor(new Color(0, 255, 0))); - rt.applyFont(5, 14, midfont); // set the text "Rich Text" to be green and the default font - - XSSFTextParagraph para = shape.addNewTextParagraph(rt); - - // Save and re-load it - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - - // Check - drawing = sheet.createDrawingPatriarch(); - - List shapes = drawing.getShapes(); - assertEquals(1, shapes.size()); - assertTrue(shapes.get(0) instanceof XSSFSimpleShape); - - XSSFSimpleShape sshape = (XSSFSimpleShape) shapes.get(0); - - List paras = sshape.getTextParagraphs(); - assertEquals(2, paras.size()); // this should be 2 as XSSFSimpleShape creates a default paragraph (no text), and then we add a string to that. - - List runs = para.getTextRuns(); - assertEquals(3, runs.size()); - - // first run properties - assertEquals("Test ", runs.get(0).getText()); - assertEquals("Arial", runs.get(0).getFontFamily()); - - Color clr = runs.get(0).getFontColor(); - assertArrayEquals( - new int[] { 0, 255, 255 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - // second run properties - assertEquals("Rich Text", runs.get(1).getText()); - assertEquals(XSSFFont.DEFAULT_FONT_NAME, runs.get(1).getFontFamily()); - - clr = runs.get(1).getFontColor(); - assertArrayEquals( - new int[] { 0, 255, 0 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - // third run properties - assertEquals(" String", runs.get(2).getText()); - assertEquals("Arial", runs.get(2).getFontFamily()); - clr = runs.get(2).getFontColor(); - assertArrayEquals( - new int[] { 0, 255, 255 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - checkRewrite(wb2); - wb2.close(); - } - - /** - * Test add multiple paragraphs and retrieve text - */ - @Test - public void testAddMultipleParagraphs() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - - XSSFTextParagraph para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 1"); - - para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 2"); - - para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 3"); - - List paras = shape.getTextParagraphs(); - assertEquals(4, paras.size()); // this should be 4 as XSSFSimpleShape creates a default paragraph (no text), and then we added 3 paragraphs - assertEquals("Line 1\nLine 2\nLine 3", shape.getText()); - - checkRewrite(wb); - wb.close(); - } - - /** - * Test setting the text, then adding multiple paragraphs and retrieve text - */ - @Test - public void testSetAddMultipleParagraphs() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - - shape.setText("Line 1"); - - XSSFTextParagraph para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 2"); - - para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 3"); - - List paras = shape.getTextParagraphs(); - assertEquals(3, paras.size()); // this should be 3 as we overwrote the default paragraph with setText, then added 2 new paragraphs - assertEquals("Line 1\nLine 2\nLine 3", shape.getText()); - - checkRewrite(wb); - wb.close(); - } - - /** - * Test reading text from a textbox in an existing file - */ - @Test - public void testReadTextBox() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - //the sheet has one relationship and it is XSSFDrawing - List rels = sheet.getRelationParts(); - assertEquals(1, rels.size()); - RelationPart rp = rels.get(0); - assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - - XSSFDrawing drawing = rp.getDocumentPart(); - //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing - assertSame(drawing, sheet.createDrawingPatriarch()); - String drawingId = rp.getRelationship().getId(); - - //there should be a relation to this drawing in the worksheet - assertTrue(sheet.getCTWorksheet().isSetDrawing()); - assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId()); - - List shapes = drawing.getShapes(); - assertEquals(6, shapes.size()); - - assertTrue(shapes.get(4) instanceof XSSFSimpleShape); - - XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(4); - assertEquals("Sheet with various pictures\n(jpeg, png, wmf, emf and pict)", textbox.getText()); - - checkRewrite(wb); - wb.close(); - } - - - /** - * Test reading multiple paragraphs from a textbox in an existing file - */ - @Test - public void testReadTextBoxParagraphs() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTextBox.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - //the sheet has one relationship and it is XSSFDrawing - List rels = sheet.getRelationParts(); - assertEquals(1, rels.size()); - RelationPart rp = rels.get(0); - - assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - - XSSFDrawing drawing = rp.getDocumentPart(); - - //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing - assertSame(drawing, sheet.createDrawingPatriarch()); - String drawingId = rp.getRelationship().getId(); - - //there should be a relation to this drawing in the worksheet - assertTrue(sheet.getCTWorksheet().isSetDrawing()); - assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId()); - - List shapes = drawing.getShapes(); - assertEquals(1, shapes.size()); - - assertTrue(shapes.get(0) instanceof XSSFSimpleShape); - - XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(0); - - List paras = textbox.getTextParagraphs(); - assertEquals(3, paras.size()); - - assertEquals("Line 2", paras.get(1).getText()); // check content of second paragraph - - assertEquals("Line 1\nLine 2\nLine 3", textbox.getText()); // check content of entire textbox - - // check attributes of paragraphs - assertEquals(TextAlign.LEFT, paras.get(0).getTextAlign()); - assertEquals(TextAlign.CENTER, paras.get(1).getTextAlign()); - assertEquals(TextAlign.RIGHT, paras.get(2).getTextAlign()); - - Color clr = paras.get(0).getTextRuns().get(0).getFontColor(); - assertArrayEquals( - new int[] { 255, 0, 0 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - clr = paras.get(1).getTextRuns().get(0).getFontColor(); - assertArrayEquals( - new int[] { 0, 255, 0 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - clr = paras.get(2).getTextRuns().get(0).getFontColor(); - assertArrayEquals( - new int[] { 0, 0, 255 } , - new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }); - - checkRewrite(wb); - wb.close(); - } - - /** - * Test adding and reading back paragraphs as bullet points - */ - @Test - public void testAddBulletParagraphs() throws IOException { - - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 10, 20)); - - String paraString1 = "A normal paragraph"; - String paraString2 = "First bullet"; - String paraString3 = "Second bullet (level 1)"; - String paraString4 = "Third bullet"; - String paraString5 = "Another normal paragraph"; - String paraString6 = "First numbered bullet"; - String paraString7 = "Second bullet (level 1)"; - String paraString8 = "Third bullet (level 1)"; - String paraString9 = "Fourth bullet (level 1)"; - String paraString10 = "Fifth Bullet"; - - XSSFTextParagraph para = shape.addNewTextParagraph(paraString1); - para = shape.addNewTextParagraph(paraString2); - para.setBullet(true); - - para = shape.addNewTextParagraph(paraString3); - para.setBullet(true); - para.setLevel(1); - - para = shape.addNewTextParagraph(paraString4); - para.setBullet(true); - - para = shape.addNewTextParagraph(paraString5); - para = shape.addNewTextParagraph(paraString6); - para.setBullet(ListAutoNumber.ARABIC_PERIOD); - - para = shape.addNewTextParagraph(paraString7); - para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3); - para.setLevel(1); - - para = shape.addNewTextParagraph(paraString8); - para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3); - para.setLevel(1); - - para = shape.addNewTextParagraph(""); - para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3); - para.setLevel(1); - - para = shape.addNewTextParagraph(paraString9); - para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3); - para.setLevel(1); - - para = shape.addNewTextParagraph(paraString10); - para.setBullet(ListAutoNumber.ARABIC_PERIOD); - - // Save and re-load it - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - - // Check - drawing = sheet.createDrawingPatriarch(); - - List shapes = drawing.getShapes(); - assertEquals(1, shapes.size()); - assertTrue(shapes.get(0) instanceof XSSFSimpleShape); - - XSSFSimpleShape sshape = (XSSFSimpleShape) shapes.get(0); - - List paras = sshape.getTextParagraphs(); - assertEquals(12, paras.size()); // this should be 12 as XSSFSimpleShape creates a default paragraph (no text), and then we added to that - - StringBuilder builder = new StringBuilder(); - - builder.append(paraString1); - builder.append("\n"); - builder.append("\u2022 "); - builder.append(paraString2); - builder.append("\n"); - builder.append("\t\u2022 "); - builder.append(paraString3); - builder.append("\n"); - builder.append("\u2022 "); - builder.append(paraString4); - builder.append("\n"); - builder.append(paraString5); - builder.append("\n"); - builder.append("1. "); - builder.append(paraString6); - builder.append("\n"); - builder.append("\t3. "); - builder.append(paraString7); - builder.append("\n"); - builder.append("\t4. "); - builder.append(paraString8); - builder.append("\n"); - builder.append("\t"); // should be empty - builder.append("\n"); - builder.append("\t5. "); - builder.append(paraString9); - builder.append("\n"); - builder.append("2. "); - builder.append(paraString10); - - assertEquals(builder.toString(), sshape.getText()); - - checkRewrite(wb2); - wb2.close(); - } - - /** - * Test reading bullet numbering from a textbox in an existing file - */ - @Test - public void testReadTextBox2() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTextBox2.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - List shapes = drawing.getShapes(); - XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(0); - String extracted = textbox.getText(); - StringBuilder sb = new StringBuilder(); - sb.append("1. content1A\n"); - sb.append("\t1. content1B\n"); - sb.append("\t2. content2B\n"); - sb.append("\t3. content3B\n"); - sb.append("2. content2A\n"); - sb.append("\t3. content2BStartAt3\n"); - sb.append("\t\n\t\n\t"); - sb.append("4. content2BStartAt3Incremented\n"); - sb.append("\t\n\t\n\t\n\t"); - - assertEquals(sb.toString(), extracted); - checkRewrite(wb); - wb.close(); - } - - @Test - public void testXSSFSimpleShapeCausesNPE56514() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("56514.xlsx"); - XSSFSheet sheet = wb1.getSheetAt(0); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - List shapes = drawing.getShapes(); - assertEquals(4, shapes.size()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - drawing = sheet.createDrawingPatriarch(); - - shapes = drawing.getShapes(); - assertEquals(4, shapes.size()); - wb2.close(); - - } - - @Test(expected=IllegalArgumentException.class) - public void testBug56835CellComment() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - // first comment works - ClientAnchor anchor = new XSSFClientAnchor(1, 1, 2, 2, 3, 3, 4, 4); - XSSFComment comment = drawing.createCellComment(anchor); - assertNotNull(comment); - - // Should fail if we try to add the same comment for the same cell - try { - drawing.createCellComment(anchor); - } finally { - wb.close(); - } - } - - private static void checkRewrite(XSSFWorkbook wb) throws IOException { - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertNotNull(wb2); - wb2.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFEvaluationSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFEvaluationSheet.java deleted file mode 100644 index 1b1417fbb..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFEvaluationSheet.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.junit.Test; - -import static org.junit.Assert.*; - -public class TestXSSFEvaluationSheet { - - @Test - public void test() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - row.createCell(0); - XSSFEvaluationSheet evalsheet = new XSSFEvaluationSheet(sheet); - - assertNotNull("Cell 0,0 is found", evalsheet.getCell(0, 0)); - assertNull("Cell 0,1 is not found", evalsheet.getCell(0, 1)); - assertNull("Cell 1,0 is not found", evalsheet.getCell(1, 0)); - - // now add Cell 0,1 - row.createCell(1); - - assertNotNull("Cell 0,0 is found", evalsheet.getCell(0, 0)); - assertNotNull("Cell 0,1 is now also found", evalsheet.getCell(0, 1)); - assertNull("Cell 1,0 is not found", evalsheet.getCell(1, 0)); - - // after clearing all values it also works - row.createCell(2); - evalsheet.clearAllCachedResultValues(); - - assertNotNull("Cell 0,0 is found", evalsheet.getCell(0, 0)); - assertNotNull("Cell 0,2 is now also found", evalsheet.getCell(0, 2)); - assertNull("Cell 1,0 is not found", evalsheet.getCell(1, 0)); - - // other things - assertEquals(sheet, evalsheet.getXSSFSheet()); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFExternalFunctions.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFExternalFunctions.java deleted file mode 100644 index 219b8423c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFExternalFunctions.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.BaseTestExternalFunctions; -import org.apache.poi.xssf.XSSFITestDataProvider; - -/** - * Tests setting and evaluating user-defined functions in HSSF - */ -public final class TestXSSFExternalFunctions extends BaseTestExternalFunctions { - public TestXSSFExternalFunctions() { - super(XSSFITestDataProvider.instance, "atp.xlsx"); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java deleted file mode 100644 index 2eeb5e8bb..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java +++ /dev/null @@ -1,340 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.POIXMLException; -import org.apache.poi.ss.usermodel.BaseTestFont; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.FontCharset; -import org.apache.poi.ss.usermodel.FontFamily; -import org.apache.poi.ss.usermodel.FontScheme; -import org.apache.poi.ss.usermodel.FontUnderline; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.SheetUtil; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontScheme; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIntProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFontScheme; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun; - -public final class TestXSSFFont extends BaseTestFont{ - - public TestXSSFFont() { - super(XSSFITestDataProvider.instance); - } - - @Test - public void testDefaultFont() throws IOException { - baseTestDefaultFont("Calibri", (short) 220, IndexedColors.BLACK.getIndex()); - } - - @Test - public void testConstructor() { - XSSFFont xssfFont=new XSSFFont(); - assertNotNull(xssfFont.getCTFont()); - } - - @Test - public void testBold() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTBooleanProperty bool=ctFont.addNewB(); - bool.setVal(false); - ctFont.setBArray(0,bool); - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(false, xssfFont.getBold()); - - - xssfFont.setBold(true); - assertEquals(ctFont.sizeOfBArray(),1); - assertEquals(true, ctFont.getBArray(0).getVal()); - } - - @Test - public void testCharSet() throws IOException { - CTFont ctFont=CTFont.Factory.newInstance(); - CTIntProperty prop=ctFont.addNewCharset(); - prop.setVal(FontCharset.ANSI.getValue()); - - ctFont.setCharsetArray(0,prop); - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(Font.ANSI_CHARSET,xssfFont.getCharSet()); - - xssfFont.setCharSet(FontCharset.DEFAULT); - assertEquals(FontCharset.DEFAULT.getValue(),ctFont.getCharsetArray(0).getVal()); - - // Try with a few less usual ones: - // Set with the Charset itself - xssfFont.setCharSet(FontCharset.RUSSIAN); - assertEquals(FontCharset.RUSSIAN.getValue(), xssfFont.getCharSet()); - // And set with the Charset index - xssfFont.setCharSet(FontCharset.ARABIC.getValue()); - assertEquals(FontCharset.ARABIC.getValue(), xssfFont.getCharSet()); - xssfFont.setCharSet((byte)(FontCharset.ARABIC.getValue())); - assertEquals(FontCharset.ARABIC.getValue(), xssfFont.getCharSet()); - - // This one isn't allowed - assertEquals(null, FontCharset.valueOf(9999)); - try { - xssfFont.setCharSet(9999); - fail("Shouldn't be able to set an invalid charset"); - } catch(POIXMLException e) {} - - - // Now try with a few sample files - - // Normal charset - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx"); - assertEquals(0, - wb1.getSheetAt(0).getRow(0).getCell(0).getCellStyle().getFont().getCharSet() - ); - wb1.close(); - - // GB2312 charact set - XSSFWorkbook wb2 = XSSFTestDataSamples.openSampleWorkbook("49273.xlsx"); - assertEquals(134, - wb2.getSheetAt(0).getRow(0).getCell(0).getCellStyle().getFont().getCharSet() - ); - wb2.close(); - } - - @Test - public void testFontName() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTFontName fname=ctFont.addNewName(); - fname.setVal("Arial"); - ctFont.setNameArray(0,fname); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals("Arial", xssfFont.getFontName()); - - xssfFont.setFontName("Courier"); - assertEquals("Courier",ctFont.getNameArray(0).getVal()); - } - - @Test - public void testItalic() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTBooleanProperty bool=ctFont.addNewI(); - bool.setVal(false); - ctFont.setIArray(0,bool); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(false, xssfFont.getItalic()); - - xssfFont.setItalic(true); - assertEquals(ctFont.sizeOfIArray(),1); - assertEquals(true, ctFont.getIArray(0).getVal()); - assertEquals(true,ctFont.getIArray(0).getVal()); - } - - @Test - public void testStrikeout() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTBooleanProperty bool=ctFont.addNewStrike(); - bool.setVal(false); - ctFont.setStrikeArray(0,bool); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(false, xssfFont.getStrikeout()); - - xssfFont.setStrikeout(true); - assertEquals(ctFont.sizeOfStrikeArray(),1); - assertEquals(true, ctFont.getStrikeArray(0).getVal()); - assertEquals(true,ctFont.getStrikeArray(0).getVal()); - } - - @Test - public void testFontHeight() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTFontSize size=ctFont.addNewSz(); - size.setVal(11); - ctFont.setSzArray(0,size); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(11,xssfFont.getFontHeightInPoints()); - - xssfFont.setFontHeight(20); - assertEquals(20.0, ctFont.getSzArray(0).getVal(), 0.0); - } - - @Test - public void testFontHeightInPoint() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTFontSize size=ctFont.addNewSz(); - size.setVal(14); - ctFont.setSzArray(0,size); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(14,xssfFont.getFontHeightInPoints()); - - xssfFont.setFontHeightInPoints((short)20); - assertEquals(20.0, ctFont.getSzArray(0).getVal(), 0.0); - } - - @Test - public void testUnderline() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTUnderlineProperty underlinePropr=ctFont.addNewU(); - underlinePropr.setVal(STUnderlineValues.SINGLE); - ctFont.setUArray(0,underlinePropr); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(Font.U_SINGLE, xssfFont.getUnderline()); - - xssfFont.setUnderline(Font.U_DOUBLE); - assertEquals(ctFont.sizeOfUArray(),1); - assertEquals(STUnderlineValues.DOUBLE,ctFont.getUArray(0).getVal()); - - xssfFont.setUnderline(FontUnderline.DOUBLE_ACCOUNTING); - assertEquals(ctFont.sizeOfUArray(),1); - assertEquals(STUnderlineValues.DOUBLE_ACCOUNTING,ctFont.getUArray(0).getVal()); - } - - @Test - public void testColor() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTColor color=ctFont.addNewColor(); - color.setIndexed(XSSFFont.DEFAULT_FONT_COLOR); - ctFont.setColorArray(0,color); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(IndexedColors.BLACK.getIndex(),xssfFont.getColor()); - - xssfFont.setColor(IndexedColors.RED.getIndex()); - assertEquals(IndexedColors.RED.getIndex(), ctFont.getColorArray(0).getIndexed()); - } - - @Test - public void testRgbColor() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTColor color=ctFont.addNewColor(); - - color.setRgb(Integer.toHexString(0xFFFFFF).getBytes(LocaleUtil.CHARSET_1252)); - ctFont.setColorArray(0,color); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(ctFont.getColorArray(0).getRgb()[0],xssfFont.getXSSFColor().getRGB()[0]); - assertEquals(ctFont.getColorArray(0).getRgb()[1],xssfFont.getXSSFColor().getRGB()[1]); - assertEquals(ctFont.getColorArray(0).getRgb()[2],xssfFont.getXSSFColor().getRGB()[2]); - assertEquals(ctFont.getColorArray(0).getRgb()[3],xssfFont.getXSSFColor().getRGB()[3]); - - xssfFont.setColor((short)23); - - byte[] bytes = Integer.toHexString(0xF1F1F1).getBytes(LocaleUtil.CHARSET_1252); - color.setRgb(bytes); - XSSFColor newColor=new XSSFColor(color); - xssfFont.setColor(newColor); - assertEquals(ctFont.getColorArray(0).getRgb()[2],newColor.getRGB()[2]); - - assertArrayEquals(bytes, xssfFont.getXSSFColor().getRGB()); - assertEquals(0, xssfFont.getColor()); - } - - @Test - public void testThemeColor() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTColor color=ctFont.addNewColor(); - color.setTheme(1); - ctFont.setColorArray(0,color); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(ctFont.getColorArray(0).getTheme(),xssfFont.getThemeColor()); - - xssfFont.setThemeColor(IndexedColors.RED.getIndex()); - assertEquals(IndexedColors.RED.getIndex(),ctFont.getColorArray(0).getTheme()); - } - - @Test - public void testFamily() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTIntProperty family=ctFont.addNewFamily(); - family.setVal(FontFamily.MODERN.getValue()); - ctFont.setFamilyArray(0,family); - - XSSFFont xssfFont=new XSSFFont(ctFont); - assertEquals(FontFamily.MODERN.getValue(),xssfFont.getFamily()); - } - - @Test - public void testScheme() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTFontScheme scheme=ctFont.addNewScheme(); - scheme.setVal(STFontScheme.MAJOR); - ctFont.setSchemeArray(0,scheme); - - XSSFFont font=new XSSFFont(ctFont); - assertEquals(FontScheme.MAJOR,font.getScheme()); - - font.setScheme(FontScheme.NONE); - assertEquals(STFontScheme.NONE,ctFont.getSchemeArray(0).getVal()); - } - - @Test - public void testTypeOffset() { - CTFont ctFont=CTFont.Factory.newInstance(); - CTVerticalAlignFontProperty valign=ctFont.addNewVertAlign(); - valign.setVal(STVerticalAlignRun.BASELINE); - ctFont.setVertAlignArray(0,valign); - - XSSFFont font=new XSSFFont(ctFont); - assertEquals(Font.SS_NONE,font.getTypeOffset()); - - font.setTypeOffset(XSSFFont.SS_SUPER); - assertEquals(STVerticalAlignRun.SUPERSCRIPT,ctFont.getVertAlignArray(0).getVal()); - } - - // store test from TestSheetUtil here as it uses XSSF - @Test - public void testCanComputeWidthXSSF() throws IOException { - Workbook wb = new XSSFWorkbook(); - - // cannot check on result because on some machines we get back false here! - SheetUtil.canComputeColumnWidth(wb.getFontAt((short)0)); - - wb.close(); - } - - // store test from TestSheetUtil here as it uses XSSF - @Test - public void testCanComputeWidthInvalidFont() throws IOException { - Font font = new XSSFFont(CTFont.Factory.newInstance()); - font.setFontName("some non existing font name"); - - // Even with invalid fonts we still get back useful data most of the time... - SheetUtil.canComputeColumnWidth(font); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFForkedEvaluator.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFForkedEvaluator.java deleted file mode 100644 index 4da863faf..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFForkedEvaluator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.formula.eval.forked.TestForkedEvaluator; -import org.apache.poi.ss.usermodel.Workbook; - -public class TestXSSFForkedEvaluator extends TestForkedEvaluator { - - @Override - protected Workbook newWorkbook() { - return new XSSFWorkbook(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java deleted file mode 100644 index 84a4aa680..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java +++ /dev/null @@ -1,696 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Ignore; -import org.junit.Test; - -public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator { - - public TestXSSFFormulaEvaluation() { - super(XSSFITestDataProvider.instance); - } - - @Test - public void testSharedFormulas() throws IOException { - baseTestSharedFormulas("shared_formulas.xlsx"); - } - - @Test - public void testSharedFormulas_evaluateInCell() throws IOException { - XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("49872.xlsx"); - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - XSSFSheet sheet = wb.getSheetAt(0); - - double result = 3.0; - - // B3 is a master shared formula, C3 and D3 don't have the formula written in their f element. - // Instead, the attribute si for a particular cell is used to figure what the formula expression - // should be based on the cell's relative location to the master formula, e.g. - // B3: B1+B2 - // C3 and D3: - - // get B3 and evaluate it in the cell - XSSFCell b3 = sheet.getRow(2).getCell(1); - assertEquals(result, evaluator.evaluateInCell(b3).getNumericCellValue(), 0); - - //at this point the master formula is gone, but we are still able to evaluate dependent cells - XSSFCell c3 = sheet.getRow(2).getCell(2); - assertEquals(result, evaluator.evaluateInCell(c3).getNumericCellValue(), 0); - - XSSFCell d3 = sheet.getRow(2).getCell(3); - assertEquals(result, evaluator.evaluateInCell(d3).getNumericCellValue(), 0); - - wb.close(); - } - - /** - * Evaluation of cell references with column indexes greater than 255. See bugzilla 50096 - */ - @Test - public void testEvaluateColumnGreaterThan255() throws IOException { - XSSFWorkbook wb = (XSSFWorkbook) _testDataProvider.openSampleWorkbook("50096.xlsx"); - XSSFFormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - - /** - * The first row simply contains the numbers 1 - 300. - * The second row simply refers to the cell value above in the first row by a simple formula. - */ - for (int i = 245; i < 265; i++) { - XSSFCell cell_noformula = wb.getSheetAt(0).getRow(0).getCell(i); - XSSFCell cell_formula = wb.getSheetAt(0).getRow(1).getCell(i); - - CellReference ref_noformula = new CellReference(cell_noformula.getRowIndex(), cell_noformula.getColumnIndex()); - CellReference ref_formula = new CellReference(cell_noformula.getRowIndex(), cell_noformula.getColumnIndex()); - String fmla = cell_formula.getCellFormula(); - // assure that the formula refers to the cell above. - // the check below is 'deep' and involves conversion of the shared formula: - // in the sample file a shared formula in GN1 is spanned in the range GN2:IY2, - assertEquals(ref_noformula.formatAsString(), fmla); - - CellValue cv_noformula = evaluator.evaluate(cell_noformula); - CellValue cv_formula = evaluator.evaluate(cell_formula); - assertEquals("Wrong evaluation result in " + ref_formula.formatAsString(), - cv_noformula.getNumberValue(), cv_formula.getNumberValue(), 0); - } - - wb.close(); - } - - /** - * Related to bugs #56737 and #56752 - XSSF workbooks which have - * formulas that refer to cells and named ranges in multiple other - * workbooks, both HSSF and XSSF ones - */ - @Test - public void testReferencesToOtherWorkbooks() throws Exception { - XSSFWorkbook wb = (XSSFWorkbook) _testDataProvider.openSampleWorkbook("ref2-56737.xlsx"); - XSSFFormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - XSSFSheet s = wb.getSheetAt(0); - - // References to a .xlsx file - Row rXSLX = s.getRow(2); - Cell cXSLX_cell = rXSLX.getCell(4); - Cell cXSLX_sNR = rXSLX.getCell(6); - Cell cXSLX_gNR = rXSLX.getCell(8); - assertEquals("[1]Uses!$A$1", cXSLX_cell.getCellFormula()); - assertEquals("[1]Defines!NR_To_A1", cXSLX_sNR.getCellFormula()); - assertEquals("[1]!NR_Global_B2", cXSLX_gNR.getCellFormula()); - - assertEquals("Hello!", cXSLX_cell.getStringCellValue()); - assertEquals("Test A1", cXSLX_sNR.getStringCellValue()); - assertEquals(142.0, cXSLX_gNR.getNumericCellValue(), 0); - - // References to a .xls file - Row rXSL = s.getRow(4); - Cell cXSL_cell = rXSL.getCell(4); - Cell cXSL_sNR = rXSL.getCell(6); - Cell cXSL_gNR = rXSL.getCell(8); - assertEquals("[2]Uses!$C$1", cXSL_cell.getCellFormula()); - assertEquals("[2]Defines!NR_To_A1", cXSL_sNR.getCellFormula()); - assertEquals("[2]!NR_Global_B2", cXSL_gNR.getCellFormula()); - - assertEquals("Hello!", cXSL_cell.getStringCellValue()); - assertEquals("Test A1", cXSL_sNR.getStringCellValue()); - assertEquals(142.0, cXSL_gNR.getNumericCellValue(), 0); - - // Try to evaluate without references, won't work - // (At least, not unit we fix bug #56752 that is) - try { - evaluator.evaluate(cXSL_cell); - fail("Without a fix for #56752, shouldn't be able to evaluate a " + - "reference to a non-provided linked workbook"); - } catch(Exception e) { - // expected here - } - - // Setup the environment - Map evaluators = new HashMap(); - evaluators.put("ref2-56737.xlsx", evaluator); - evaluators.put("56737.xlsx", - _testDataProvider.openSampleWorkbook("56737.xlsx").getCreationHelper().createFormulaEvaluator()); - evaluators.put("56737.xls", - HSSFTestDataSamples.openSampleWorkbook("56737.xls").getCreationHelper().createFormulaEvaluator()); - evaluator.setupReferencedWorkbooks(evaluators); - - // Try evaluating all of them, ensure we don't blow up - for(Row r : s) { - for (Cell c : r) { - evaluator.evaluate(c); - } - } - // And evaluate the other way too - evaluator.evaluateAll(); - - // Static evaluator won't work, as no references passed in - try { - XSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - fail("Static method lacks references, shouldn't work"); - } catch(Exception e) { - // expected here - } - - - // Evaluate specific cells and check results - assertEquals("\"Hello!\"", evaluator.evaluate(cXSLX_cell).formatAsString()); - assertEquals("\"Test A1\"", evaluator.evaluate(cXSLX_sNR).formatAsString()); - assertEquals("142.0", evaluator.evaluate(cXSLX_gNR).formatAsString()); - - assertEquals("\"Hello!\"", evaluator.evaluate(cXSL_cell).formatAsString()); - assertEquals("\"Test A1\"", evaluator.evaluate(cXSL_sNR).formatAsString()); - assertEquals("142.0", evaluator.evaluate(cXSL_gNR).formatAsString()); - - - // Add another formula referencing these workbooks - Cell cXSL_cell2 = rXSL.createCell(40); - cXSL_cell2.setCellFormula("[56737.xls]Uses!$C$1"); - // TODO Shouldn't it become [2] like the others? - assertEquals("[56737.xls]Uses!$C$1", cXSL_cell2.getCellFormula()); - assertEquals("\"Hello!\"", evaluator.evaluate(cXSL_cell2).formatAsString()); - - - // Now add a formula that refers to yet another (different) workbook - // Won't work without the workbook being linked - Cell cXSLX_nw_cell = rXSLX.createCell(42); - try { - cXSLX_nw_cell.setCellFormula("[alt.xlsx]Sheet1!$A$1"); - fail("New workbook not linked, shouldn't be able to add"); - } catch (Exception e) { - // expected here - } - - // Link and re-try - Workbook alt = new XSSFWorkbook(); - try { - alt.createSheet().createRow(0).createCell(0).setCellValue("In another workbook"); - // TODO Implement the rest of this, see bug #57184 -/* - wb.linkExternalWorkbook("alt.xlsx", alt); - - cXSLX_nw_cell.setCellFormula("[alt.xlsx]Sheet1!$A$1"); - // Check it - TODO Is this correct? Or should it become [3]Sheet1!$A$1 ? - assertEquals("[alt.xlsx]Sheet1!$A$1", cXSLX_nw_cell.getCellFormula()); - - // Evaluate it, without a link to that workbook - try { - evaluator.evaluate(cXSLX_nw_cell); - fail("No cached value and no link to workbook, shouldn't evaluate"); - } catch(Exception e) {} - - // Add a link, check it does - evaluators.put("alt.xlsx", alt.getCreationHelper().createFormulaEvaluator()); - evaluator.setupReferencedWorkbooks(evaluators); - - evaluator.evaluate(cXSLX_nw_cell); - assertEquals("In another workbook", cXSLX_nw_cell.getStringCellValue()); -*/ - } finally { - alt.close(); - } - - wb.close(); - } - - /** - * If a formula references cells or named ranges in another workbook, - * but that isn't available at evaluation time, the cached values - * should be used instead - * TODO Add the support then add a unit test - * See bug #56752 - */ - @Test - @Ignore - public void testCachedReferencesToOtherWorkbooks() throws Exception { - // TODO - } - - /** - * A handful of functions (such as SUM, COUNTA, MIN) support - * multi-sheet references (eg Sheet1:Sheet3!A1 = Cell A1 from - * Sheets 1 through Sheet 3). - * This test, based on common test files for HSSF and XSSF, checks - * that we can correctly evaluate these - */ - @Test - public void testMultiSheetReferencesHSSFandXSSF() throws Exception { - Workbook wb1 = HSSFTestDataSamples.openSampleWorkbook("55906-MultiSheetRefs.xls"); - Workbook wb2 = XSSFTestDataSamples.openSampleWorkbook("55906-MultiSheetRefs.xlsx"); - - for (Workbook wb : new Workbook[] {wb1,wb2}) { - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - Sheet s1 = wb.getSheetAt(0); - - - // Simple SUM over numbers - Cell sumF = s1.getRow(2).getCell(0); - assertNotNull(sumF); - assertEquals("SUM(Sheet1:Sheet3!A1)", sumF.getCellFormula()); - assertEquals("Failed for " + wb.getClass(), "66.0", evaluator.evaluate(sumF).formatAsString()); - - - // Various Stats formulas on numbers - Cell avgF = s1.getRow(2).getCell(1); - assertNotNull(avgF); - assertEquals("AVERAGE(Sheet1:Sheet3!A1)", avgF.getCellFormula()); - assertEquals("22.0", evaluator.evaluate(avgF).formatAsString()); - - Cell minF = s1.getRow(3).getCell(1); - assertNotNull(minF); - assertEquals("MIN(Sheet1:Sheet3!A$1)", minF.getCellFormula()); - assertEquals("11.0", evaluator.evaluate(minF).formatAsString()); - - Cell maxF = s1.getRow(4).getCell(1); - assertNotNull(maxF); - assertEquals("MAX(Sheet1:Sheet3!A$1)", maxF.getCellFormula()); - assertEquals("33.0", evaluator.evaluate(maxF).formatAsString()); - - Cell countF = s1.getRow(5).getCell(1); - assertNotNull(countF); - assertEquals("COUNT(Sheet1:Sheet3!A$1)", countF.getCellFormula()); - assertEquals("3.0", evaluator.evaluate(countF).formatAsString()); - - - // Various CountAs on Strings - Cell countA_1F = s1.getRow(2).getCell(2); - assertNotNull(countA_1F); - assertEquals("COUNTA(Sheet1:Sheet3!C1)", countA_1F.getCellFormula()); - assertEquals("3.0", evaluator.evaluate(countA_1F).formatAsString()); - - Cell countA_2F = s1.getRow(2).getCell(3); - assertNotNull(countA_2F); - assertEquals("COUNTA(Sheet1:Sheet3!D1)", countA_2F.getCellFormula()); - assertEquals("0.0", evaluator.evaluate(countA_2F).formatAsString()); - - Cell countA_3F = s1.getRow(2).getCell(4); - assertNotNull(countA_3F); - assertEquals("COUNTA(Sheet1:Sheet3!E1)", countA_3F.getCellFormula()); - assertEquals("3.0", evaluator.evaluate(countA_3F).formatAsString()); - } - - wb2.close(); - wb1.close(); - } - - /** - * A handful of functions (such as SUM, COUNTA, MIN) support - * multi-sheet areas (eg Sheet1:Sheet3!A1:B2 = Cell A1 to Cell B2, - * from Sheets 1 through Sheet 3). - * This test, based on common test files for HSSF and XSSF, checks - * that we can correctly evaluate these - */ - @Test - public void testMultiSheetAreasHSSFandXSSF() throws IOException { - Workbook wb1 = HSSFTestDataSamples.openSampleWorkbook("55906-MultiSheetRefs.xls"); - Workbook wb2 = XSSFTestDataSamples.openSampleWorkbook("55906-MultiSheetRefs.xlsx"); - - for (Workbook wb : new Workbook[]{wb1,wb2}) { - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - Sheet s1 = wb.getSheetAt(0); - - - // SUM over a range - Cell sumFA = s1.getRow(2).getCell(7); - assertNotNull(sumFA); - assertEquals("SUM(Sheet1:Sheet3!A1:B2)", sumFA.getCellFormula()); - assertEquals("Failed for " + wb.getClass(), "110.0", evaluator.evaluate(sumFA).formatAsString()); - - - // Various Stats formulas on ranges of numbers - Cell avgFA = s1.getRow(2).getCell(8); - assertNotNull(avgFA); - assertEquals("AVERAGE(Sheet1:Sheet3!A1:B2)", avgFA.getCellFormula()); - assertEquals("27.5", evaluator.evaluate(avgFA).formatAsString()); - - Cell minFA = s1.getRow(3).getCell(8); - assertNotNull(minFA); - assertEquals("MIN(Sheet1:Sheet3!A$1:B$2)", minFA.getCellFormula()); - assertEquals("11.0", evaluator.evaluate(minFA).formatAsString()); - - Cell maxFA = s1.getRow(4).getCell(8); - assertNotNull(maxFA); - assertEquals("MAX(Sheet1:Sheet3!A$1:B$2)", maxFA.getCellFormula()); - assertEquals("44.0", evaluator.evaluate(maxFA).formatAsString()); - - Cell countFA = s1.getRow(5).getCell(8); - assertNotNull(countFA); - assertEquals("COUNT(Sheet1:Sheet3!$A$1:$B$2)", countFA.getCellFormula()); - assertEquals("4.0", evaluator.evaluate(countFA).formatAsString()); - } - - wb2.close(); - wb1.close(); - } - - @Test - public void testMultisheetFormulaEval() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet1 = wb.createSheet("Sheet1"); - XSSFSheet sheet2 = wb.createSheet("Sheet2"); - XSSFSheet sheet3 = wb.createSheet("Sheet3"); - - // sheet1 A1 - XSSFCell cell = sheet1.createRow(0).createCell(0); - cell.setCellType(CellType.NUMERIC); - cell.setCellValue(1.0); - - // sheet2 A1 - cell = sheet2.createRow(0).createCell(0); - cell.setCellType(CellType.NUMERIC); - cell.setCellValue(1.0); - - // sheet2 B1 - cell = sheet2.getRow(0).createCell(1); - cell.setCellType(CellType.NUMERIC); - cell.setCellValue(1.0); - - // sheet3 A1 - cell = sheet3.createRow(0).createCell(0); - cell.setCellType(CellType.NUMERIC); - cell.setCellValue(1.0); - - // sheet1 A2 formulae - cell = sheet1.createRow(1).createCell(0); - cell.setCellType(CellType.FORMULA); - cell.setCellFormula("SUM(Sheet1:Sheet3!A1)"); - - // sheet1 A3 formulae - cell = sheet1.createRow(2).createCell(0); - cell.setCellType(CellType.FORMULA); - cell.setCellFormula("SUM(Sheet1:Sheet3!A1:B1)"); - - wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); - - cell = sheet1.getRow(1).getCell(0); - assertEquals(3.0, cell.getNumericCellValue(), 0); - - cell = sheet1.getRow(2).getCell(0); - assertEquals(4.0, cell.getNumericCellValue(), 0); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - cellA2.setCellFormula("IF(B1=0,\"\",((ROW()-ROW(A$1))*12))"); - CellValue evaluate = formulaEvaluator.evaluate(cellA2); - assertEquals("12.0", evaluate.formatAsString()); - - cellA2.setCellFormula("IF(NOT(B1=0),((ROW()-ROW(A$1))*12),\"\")"); - CellValue evaluateN = formulaEvaluator.evaluate(cellA2); - - assertEquals(evaluate.toString(), evaluateN.toString()); - assertEquals("12.0", evaluateN.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843a() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - cellA2.setCellFormula("IF(B1=0,\"\",((ROW(A$1))))"); - CellValue evaluate = formulaEvaluator.evaluate(cellA2); - assertEquals("1.0", evaluate.formatAsString()); - - cellA2.setCellFormula("IF(NOT(B1=0),((ROW(A$1))),\"\")"); - CellValue evaluateN = formulaEvaluator.evaluate(cellA2); - - assertEquals(evaluate.toString(), evaluateN.toString()); - assertEquals("1.0", evaluateN.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843b() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - - cellA2.setCellFormula("IF(B1=0,\"\",((ROW())))"); - CellValue evaluate = formulaEvaluator.evaluate(cellA2); - assertEquals("2.0", evaluate.formatAsString()); - - cellA2.setCellFormula("IF(NOT(B1=0),((ROW())),\"\")"); - CellValue evaluateN = formulaEvaluator.evaluate(cellA2); - - assertEquals(evaluate.toString(), evaluateN.toString()); - assertEquals("2.0", evaluateN.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843c() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - - cellA2.setCellFormula("IF(NOT(B1=0),((ROW())))"); - CellValue evaluateN = formulaEvaluator.evaluate(cellA2); - assertEquals("2.0", evaluateN.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843d() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - - cellA2.setCellFormula("IF(NOT(B1=0),((ROW())),\"\")"); - CellValue evaluateN = formulaEvaluator.evaluate(cellA2); - assertEquals("2.0", evaluateN.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843e() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - - cellA2.setCellFormula("IF(B1=0,\"\",((ROW())))"); - CellValue evaluate = formulaEvaluator.evaluate(cellA2); - assertEquals("2.0", evaluate.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug55843f() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet("test"); - XSSFRow row = sheet.createRow(0); - XSSFRow row2 = sheet.createRow(1); - XSSFCell cellA2 = row2.createCell(0, CellType.FORMULA); - XSSFCell cellB1 = row.createCell(1, CellType.NUMERIC); - cellB1.setCellValue(10); - XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); - - cellA2.setCellFormula("IF(B1=0,\"\",IF(B1=10,3,4))"); - CellValue evaluate = formulaEvaluator.evaluate(cellA2); - assertEquals("3.0", evaluate.formatAsString()); - } finally { - wb.close(); - } - } - - @Test - public void testBug56655() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - setCellFormula(sheet, 0, 0, "#VALUE!"); - setCellFormula(sheet, 0, 1, "SUMIFS(A:A,A:A,#VALUE!)"); - - wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); - - assertEquals(CellType.ERROR, getCell(sheet, 0,0).getCachedFormulaResultTypeEnum()); - assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0,0).getErrorCellValue()); - assertEquals(CellType.ERROR, getCell(sheet, 0,1).getCachedFormulaResultTypeEnum()); - assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0,1).getErrorCellValue()); - - wb.close(); - } - - @Test - public void testBug56655a() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - setCellFormula(sheet, 0, 0, "B1*C1"); - sheet.getRow(0).createCell(1).setCellValue("A"); - setCellFormula(sheet, 1, 0, "B1*C1"); - sheet.getRow(1).createCell(1).setCellValue("A"); - setCellFormula(sheet, 0, 3, "SUMIFS(A:A,A:A,A2)"); - - wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); - - assertEquals(CellType.ERROR, getCell(sheet, 0, 0).getCachedFormulaResultTypeEnum()); - assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0, 0).getErrorCellValue()); - assertEquals(CellType.ERROR, getCell(sheet, 1, 0).getCachedFormulaResultTypeEnum()); - assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 1, 0).getErrorCellValue()); - assertEquals(CellType.ERROR, getCell(sheet, 0, 3).getCachedFormulaResultTypeEnum()); - assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0, 3).getErrorCellValue()); - - wb.close(); - } - - // bug 57721 - @Test - public void structuredReferences() throws IOException { - verifyAllFormulasInWorkbookCanBeEvaluated("evaluate_formula_with_structured_table_references.xlsx"); - } - - // bug 57840 - @Ignore("Takes over a minute to evaluate all formulas in this large workbook. Run this test when profiling for formula evaluation speed.") - @Test - public void testLotsOfFormulasWithStructuredReferencesToCalculatedTableColumns() throws IOException { - verifyAllFormulasInWorkbookCanBeEvaluated("StructuredRefs-lots-with-lookups.xlsx"); - } - - // FIXME: use junit4 parameterization - private static void verifyAllFormulasInWorkbookCanBeEvaluated(String sampleWorkbook) throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook(sampleWorkbook); - XSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - wb.close(); - } - - /** - * @param row 0-based - * @param column 0-based - */ - private void setCellFormula(Sheet sheet, int row, int column, String formula) { - Row r = sheet.getRow(row); - if (r == null) { - r = sheet.createRow(row); - } - Cell cell = r.getCell(column); - if (cell == null) { - cell = r.createCell(column); - } - cell.setCellType(CellType.FORMULA); - cell.setCellFormula(formula); - } - - /** - * @param rowNo 0-based - * @param column 0-based - */ - private Cell getCell(Sheet sheet, int rowNo, int column) { - return sheet.getRow(rowNo).getCell(column); - } - - @Test - public void test59736() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("59736.xlsx"); - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - Cell cell = wb.getSheetAt(0).getRow(0).getCell(0); - assertEquals(1, cell.getNumericCellValue(), 0.001); - - cell = wb.getSheetAt(0).getRow(1).getCell(0); - CellValue value = evaluator.evaluate(cell); - assertEquals(1, value.getNumberValue(), 0.001); - - cell = wb.getSheetAt(0).getRow(2).getCell(0); - value = evaluator.evaluate(cell); - assertEquals(1, value.getNumberValue(), 0.001); - } - - @Test - public void evaluateInCellReturnsSameDataType() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - wb.createSheet().createRow(0).createCell(0); - XSSFFormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0); - XSSFCell same = evaluator.evaluateInCell(cell); - assertSame(cell, same); - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java deleted file mode 100644 index 88677c347..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java +++ /dev/null @@ -1,746 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.util.Arrays; - -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.FormulaParseException; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaParsingWorkbook; -import org.apache.poi.ss.formula.FormulaRenderingWorkbook; -import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.WorkbookDependentFormula; -import org.apache.poi.ss.formula.ptg.Area3DPtg; -import org.apache.poi.ss.formula.ptg.Area3DPxg; -import org.apache.poi.ss.formula.ptg.AreaPtg; -import org.apache.poi.ss.formula.ptg.AttrPtg; -import org.apache.poi.ss.formula.ptg.ErrPtg; -import org.apache.poi.ss.formula.ptg.FuncPtg; -import org.apache.poi.ss.formula.ptg.FuncVarPtg; -import org.apache.poi.ss.formula.ptg.IntPtg; -import org.apache.poi.ss.formula.ptg.IntersectionPtg; -import org.apache.poi.ss.formula.ptg.MemAreaPtg; -import org.apache.poi.ss.formula.ptg.MemFuncPtg; -import org.apache.poi.ss.formula.ptg.NamePtg; -import org.apache.poi.ss.formula.ptg.NameXPxg; -import org.apache.poi.ss.formula.ptg.ParenthesisPtg; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.Ref3DPtg; -import org.apache.poi.ss.formula.ptg.Ref3DPxg; -import org.apache.poi.ss.formula.ptg.RefPtg; -import org.apache.poi.ss.formula.ptg.StringPtg; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.FormulaEvaluator; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -public final class TestXSSFFormulaParser { - private static Ptg[] parse(FormulaParsingWorkbook fpb, String fmla) { - return FormulaParser.parse(fmla, fpb, FormulaType.CELL, -1); - } - private static Ptg[] parse(FormulaParsingWorkbook fpb, String fmla, int rowIndex) { - return FormulaParser.parse(fmla, fpb, FormulaType.CELL, -1, rowIndex); - } - - @Test - public void basicParsing() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - ptgs = parse(fpb, "ABC10"); - assertEquals(1, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - - ptgs = parse(fpb, "A500000"); - assertEquals(1, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - - ptgs = parse(fpb, "ABC500000"); - assertEquals(1, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - - //highest allowed rows and column (XFD and 0x100000) - ptgs = parse(fpb, "XFD1048576"); - assertEquals(1, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - - - //column greater than XFD - try { - /*ptgs =*/ parse(fpb, "XFE10"); - fail("expected exception"); - } catch (FormulaParseException e){ - assertEquals("Specified named range 'XFE10' does not exist in the current workbook.", e.getMessage()); - } - - //row greater than 0x100000 - try { - /*ptgs =*/ parse(fpb, "XFD1048577"); - fail("expected exception"); - } catch (FormulaParseException e){ - assertEquals("Specified named range 'XFD1048577' does not exist in the current workbook.", e.getMessage()); - } - - // Formula referencing one cell - ptgs = parse(fpb, "ISEVEN(A1)"); - assertEquals(3, ptgs.length); - assertEquals(NameXPxg.class, ptgs[0].getClass()); - assertEquals(RefPtg.class, ptgs[1].getClass()); - assertEquals(FuncVarPtg.class, ptgs[2].getClass()); - assertEquals("ISEVEN", ptgs[0].toFormulaString()); - assertEquals("A1", ptgs[1].toFormulaString()); - assertEquals("#external#", ptgs[2].toFormulaString()); - - // Formula referencing an area - ptgs = parse(fpb, "SUM(A1:B3)"); - assertEquals(2, ptgs.length); - assertEquals(AreaPtg.class, ptgs[0].getClass()); - assertEquals(AttrPtg.class, ptgs[1].getClass()); - assertEquals("A1:B3", ptgs[0].toFormulaString()); - assertEquals("SUM", ptgs[1].toFormulaString()); - - // Formula referencing one cell in a different sheet - ptgs = parse(fpb, "SUM(Sheet1!A1)"); - assertEquals(2, ptgs.length); - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - assertEquals(AttrPtg.class, ptgs[1].getClass()); - assertEquals("Sheet1!A1", ptgs[0].toFormulaString()); - assertEquals("SUM", ptgs[1].toFormulaString()); - - // Formula referencing an area in a different sheet - ptgs = parse(fpb, "SUM(Sheet1!A1:B3)"); - assertEquals(2, ptgs.length); - assertEquals(Area3DPxg.class,ptgs[0].getClass()); - assertEquals(AttrPtg.class, ptgs[1].getClass()); - assertEquals("Sheet1!A1:B3", ptgs[0].toFormulaString()); - assertEquals("SUM", ptgs[1].toFormulaString()); - - wb.close(); - } - - @Test - public void builtInFormulas() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - ptgs = parse(fpb, "LOG10"); - assertEquals(1, ptgs.length); - assertTrue("",(ptgs[0] instanceof RefPtg)); - - ptgs = parse(fpb, "LOG10(100)"); - assertEquals(2, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof IntPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof FuncPtg); - - wb.close(); - } - - @Test - public void formulaReferencesSameWorkbook() throws IOException { - // Use a test file with "other workbook" style references - // to itself - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx"); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - // Reference to a named range in our own workbook, as if it - // were defined in a different workbook - ptgs = parse(fpb, "[0]!NR_Global_B2"); - assertEquals(1, ptgs.length); - assertEquals(NameXPxg.class, ptgs[0].getClass()); - assertEquals(0, ((NameXPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals(null, ((NameXPxg)ptgs[0]).getSheetName()); - assertEquals("NR_Global_B2",((NameXPxg)ptgs[0]).getNameName()); - assertEquals("[0]!NR_Global_B2",((NameXPxg)ptgs[0]).toFormulaString()); - - wb.close(); - } - - @Test - public void formulaReferencesOtherSheets() throws IOException { - // Use a test file with the named ranges in place - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx"); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - // Reference to a single cell in a different sheet - ptgs = parse(fpb, "Uses!A1"); - assertEquals(1, ptgs.length); - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - assertEquals(-1, ((Ref3DPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals("A1", ((Ref3DPxg)ptgs[0]).format2DRefAsString()); - assertEquals("Uses!A1", ((Ref3DPxg)ptgs[0]).toFormulaString()); - - // Reference to a single cell in a different sheet, which needs quoting - ptgs = parse(fpb, "'Testing 47100'!A1"); - assertEquals(1, ptgs.length); - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - assertEquals(-1, ((Ref3DPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals("Testing 47100", ((Ref3DPxg)ptgs[0]).getSheetName()); - assertEquals("A1", ((Ref3DPxg)ptgs[0]).format2DRefAsString()); - assertEquals("'Testing 47100'!A1", ((Ref3DPxg)ptgs[0]).toFormulaString()); - - // Reference to a sheet scoped named range from another sheet - ptgs = parse(fpb, "Defines!NR_To_A1"); - assertEquals(1, ptgs.length); - assertEquals(NameXPxg.class, ptgs[0].getClass()); - assertEquals(-1, ((NameXPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals("Defines", ((NameXPxg)ptgs[0]).getSheetName()); - assertEquals("NR_To_A1",((NameXPxg)ptgs[0]).getNameName()); - assertEquals("Defines!NR_To_A1",((NameXPxg)ptgs[0]).toFormulaString()); - - // Reference to a workbook scoped named range - ptgs = parse(fpb, "NR_Global_B2"); - assertEquals(1, ptgs.length); - assertEquals(NamePtg.class, ptgs[0].getClass()); - assertEquals("NR_Global_B2",((NamePtg)ptgs[0]).toFormulaString(fpb)); - - wb.close(); - } - - @Test - public void formulaReferencesOtherWorkbook() throws IOException { - // Use a test file with the external linked table in place - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ref-56737.xlsx"); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - // Reference to a single cell in a different workbook - ptgs = parse(fpb, "[1]Uses!$A$1"); - assertEquals(1, ptgs.length); - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - assertEquals(1, ((Ref3DPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals("Uses",((Ref3DPxg)ptgs[0]).getSheetName()); - assertEquals("$A$1",((Ref3DPxg)ptgs[0]).format2DRefAsString()); - assertEquals("[1]Uses!$A$1",((Ref3DPxg)ptgs[0]).toFormulaString()); - - // Reference to a sheet-scoped named range in a different workbook - ptgs = parse(fpb, "[1]Defines!NR_To_A1"); - assertEquals(1, ptgs.length); - assertEquals(NameXPxg.class, ptgs[0].getClass()); - assertEquals(1, ((NameXPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals("Defines", ((NameXPxg)ptgs[0]).getSheetName()); - assertEquals("NR_To_A1",((NameXPxg)ptgs[0]).getNameName()); - assertEquals("[1]Defines!NR_To_A1",((NameXPxg)ptgs[0]).toFormulaString()); - - // Reference to a global named range in a different workbook - ptgs = parse(fpb, "[1]!NR_Global_B2"); - assertEquals(1, ptgs.length); - assertEquals(NameXPxg.class, ptgs[0].getClass()); - assertEquals(1, ((NameXPxg)ptgs[0]).getExternalWorkbookNumber()); - assertEquals(null, ((NameXPxg)ptgs[0]).getSheetName()); - assertEquals("NR_Global_B2",((NameXPxg)ptgs[0]).getNameName()); - assertEquals("[1]!NR_Global_B2",((NameXPxg)ptgs[0]).toFormulaString()); - - wb.close(); - } - - /** - * A handful of functions (such as SUM, COUNTA, MIN) support - * multi-sheet references (eg Sheet1:Sheet3!A1 = Cell A1 from - * Sheets 1 through Sheet 3) and multi-sheet area references - * (eg Sheet1:Sheet3!A1:B2 = Cells A1 through B2 from Sheets - * 1 through Sheet 3). - * This test, based on common test files for HSSF and XSSF, checks - * that we can read and parse these kinds of references - * (but not evaluate - that's elsewhere in the test suite) - */ - @Test - public void multiSheetReferencesHSSFandXSSF() throws IOException { - Workbook[] wbs = new Workbook[] { - HSSFTestDataSamples.openSampleWorkbook("55906-MultiSheetRefs.xls"), - XSSFTestDataSamples.openSampleWorkbook("55906-MultiSheetRefs.xlsx") - }; - for (Workbook wb : wbs) { - Sheet s1 = wb.getSheetAt(0); - Ptg[] ptgs; - - // Check the contents - Cell sumF = s1.getRow(2).getCell(0); - assertNotNull(sumF); - assertEquals("SUM(Sheet1:Sheet3!A1)", sumF.getCellFormula()); - - Cell avgF = s1.getRow(2).getCell(1); - assertNotNull(avgF); - assertEquals("AVERAGE(Sheet1:Sheet3!A1)", avgF.getCellFormula()); - - Cell countAF = s1.getRow(2).getCell(2); - assertNotNull(countAF); - assertEquals("COUNTA(Sheet1:Sheet3!C1)", countAF.getCellFormula()); - - Cell maxF = s1.getRow(4).getCell(1); - assertNotNull(maxF); - assertEquals("MAX(Sheet1:Sheet3!A$1)", maxF.getCellFormula()); - - - Cell sumFA = s1.getRow(2).getCell(7); - assertNotNull(sumFA); - assertEquals("SUM(Sheet1:Sheet3!A1:B2)", sumFA.getCellFormula()); - - Cell avgFA = s1.getRow(2).getCell(8); - assertNotNull(avgFA); - assertEquals("AVERAGE(Sheet1:Sheet3!A1:B2)", avgFA.getCellFormula()); - - Cell maxFA = s1.getRow(4).getCell(8); - assertNotNull(maxFA); - assertEquals("MAX(Sheet1:Sheet3!A$1:B$2)", maxFA.getCellFormula()); - - Cell countFA = s1.getRow(5).getCell(8); - assertNotNull(countFA); - assertEquals("COUNT(Sheet1:Sheet3!$A$1:$B$2)", countFA.getCellFormula()); - - - // Create a formula parser - final FormulaParsingWorkbook fpb; - if (wb instanceof HSSFWorkbook) - fpb = HSSFEvaluationWorkbook.create((HSSFWorkbook)wb); - else - fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook)wb); - - // Check things parse as expected: - - // SUM to one cell over 3 workbooks, relative reference - ptgs = parse(fpb, "SUM(Sheet1:Sheet3!A1)"); - assertEquals(2, ptgs.length); - if (wb instanceof HSSFWorkbook) { - assertEquals(Ref3DPtg.class, ptgs[0].getClass()); - } else { - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - } - assertEquals("Sheet1:Sheet3!A1", toFormulaString(ptgs[0], fpb)); - assertEquals(AttrPtg.class, ptgs[1].getClass()); - assertEquals("SUM", toFormulaString(ptgs[1], fpb)); - - // MAX to one cell over 3 workbooks, absolute row reference - ptgs = parse(fpb, "MAX(Sheet1:Sheet3!A$1)"); - assertEquals(2, ptgs.length); - if (wb instanceof HSSFWorkbook) { - assertEquals(Ref3DPtg.class, ptgs[0].getClass()); - } else { - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - } - assertEquals("Sheet1:Sheet3!A$1", toFormulaString(ptgs[0], fpb)); - assertEquals(FuncVarPtg.class, ptgs[1].getClass()); - assertEquals("MAX", toFormulaString(ptgs[1], fpb)); - - // MIN to one cell over 3 workbooks, absolute reference - ptgs = parse(fpb, "MIN(Sheet1:Sheet3!$A$1)"); - assertEquals(2, ptgs.length); - if (wb instanceof HSSFWorkbook) { - assertEquals(Ref3DPtg.class, ptgs[0].getClass()); - } else { - assertEquals(Ref3DPxg.class, ptgs[0].getClass()); - } - assertEquals("Sheet1:Sheet3!$A$1", toFormulaString(ptgs[0], fpb)); - assertEquals(FuncVarPtg.class, ptgs[1].getClass()); - assertEquals("MIN", toFormulaString(ptgs[1], fpb)); - - // SUM to a range of cells over 3 workbooks - ptgs = parse(fpb, "SUM(Sheet1:Sheet3!A1:B2)"); - assertEquals(2, ptgs.length); - if (wb instanceof HSSFWorkbook) { - assertEquals(Area3DPtg.class, ptgs[0].getClass()); - } else { - assertEquals(Area3DPxg.class, ptgs[0].getClass()); - } - assertEquals("Sheet1:Sheet3!A1:B2", toFormulaString(ptgs[0], fpb)); - assertEquals(AttrPtg.class, ptgs[1].getClass()); - assertEquals("SUM", toFormulaString(ptgs[1], fpb)); - - // MIN to a range of cells over 3 workbooks, absolute reference - ptgs = parse(fpb, "MIN(Sheet1:Sheet3!$A$1:$B$2)"); - assertEquals(2, ptgs.length); - if (wb instanceof HSSFWorkbook) { - assertEquals(Area3DPtg.class, ptgs[0].getClass()); - } else { - assertEquals(Area3DPxg.class, ptgs[0].getClass()); - } - assertEquals("Sheet1:Sheet3!$A$1:$B$2", toFormulaString(ptgs[0], fpb)); - assertEquals(FuncVarPtg.class, ptgs[1].getClass()); - assertEquals("MIN", toFormulaString(ptgs[1], fpb)); - - // Check we can round-trip - try to set a new one to a new single cell - Cell newF = s1.getRow(0).createCell(10, CellType.FORMULA); - newF.setCellFormula("SUM(Sheet2:Sheet3!A1)"); - assertEquals("SUM(Sheet2:Sheet3!A1)", newF.getCellFormula()); - - // Check we can round-trip - try to set a new one to a cell range - newF = s1.getRow(0).createCell(11, CellType.FORMULA); - newF.setCellFormula("MIN(Sheet1:Sheet2!A1:B2)"); - assertEquals("MIN(Sheet1:Sheet2!A1:B2)", newF.getCellFormula()); - - wb.close(); - } - } - - private static String toFormulaString(Ptg ptg, FormulaParsingWorkbook wb) { - if (ptg instanceof WorkbookDependentFormula) { - return ((WorkbookDependentFormula)ptg).toFormulaString((FormulaRenderingWorkbook)wb); - } - return ptg.toFormulaString(); - } - - @Test - public void test58648Single() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - ptgs = parse(fpb, "(ABC10 )"); - assertEquals("Had: " + Arrays.toString(ptgs), - 2, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - - wb.close(); - } - - @Test - public void test58648Basic() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - // verify whitespaces in different places - ptgs = parse(fpb, "(ABC10)"); - assertEquals("Had: " + Arrays.toString(ptgs), - 2, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - - ptgs = parse(fpb, "( ABC10)"); - assertEquals("Had: " + Arrays.toString(ptgs), - 2, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - - ptgs = parse(fpb, "(ABC10 )"); - assertEquals("Had: " + Arrays.toString(ptgs), - 2, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - - ptgs = parse(fpb, "((ABC10))"); - assertEquals("Had: " + Arrays.toString(ptgs), - 3, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof ParenthesisPtg); - - ptgs = parse(fpb, "((ABC10) )"); - assertEquals("Had: " + Arrays.toString(ptgs), - 3, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof ParenthesisPtg); - - ptgs = parse(fpb, "( (ABC10))"); - assertEquals("Had: " + Arrays.toString(ptgs), - 3, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof ParenthesisPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof ParenthesisPtg); - - wb.close(); - } - - @Test - public void test58648FormulaParsing() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("58648.xlsx"); - - FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); - - for (int i = 0; i < wb.getNumberOfSheets(); i++) { - Sheet xsheet = wb.getSheetAt(i); - - for (Row row : xsheet) { - for (Cell cell : row) { - if (cell.getCellTypeEnum() == CellType.FORMULA) { - try { - evaluator.evaluateFormulaCellEnum(cell); - } catch (Exception e) { - CellReference cellRef = new CellReference(cell.getRowIndex(), cell.getColumnIndex()); - throw new RuntimeException("error at: " + cellRef.toString(), e); - } - } - } - } - } - - Sheet sheet = wb.getSheet("my-sheet"); - Cell cell = sheet.getRow(1).getCell(4); - - assertEquals(5d, cell.getNumericCellValue(), 0d); - - wb.close(); - } - - @Test - public void testWhitespaceInFormula() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - // verify whitespaces in different places - ptgs = parse(fpb, "INTERCEPT(A2:A5, B2:B5)"); - assertEquals("Had: " + Arrays.toString(ptgs), - 3, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof FuncPtg); - - ptgs = parse(fpb, " INTERCEPT ( \t \r A2 : \nA5 , B2 : B5 ) \t"); - assertEquals("Had: " + Arrays.toString(ptgs), - 3, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof FuncPtg); - - ptgs = parse(fpb, "(VLOOKUP(\"item1\", A2:B3, 2, FALSE) - VLOOKUP(\"item2\", A2:B3, 2, FALSE) )"); - assertEquals("Had: " + Arrays.toString(ptgs), - 12, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof StringPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof IntPtg); - - ptgs = parse(fpb, "A1:B1 B1:B2"); - assertEquals("Had: " + Arrays.toString(ptgs), - 4, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof MemAreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[3] instanceof IntersectionPtg); - - ptgs = parse(fpb, "A1:B1 B1:B2"); - assertEquals("Had: " + Arrays.toString(ptgs), - 4, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof MemAreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[3] instanceof IntersectionPtg); - - wb.close(); - } - - @Test - public void testWhitespaceInComplexFormula() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - // verify whitespaces in different places - ptgs = parse(fpb, "SUM(A1:INDEX(1:1048576,MAX(IFERROR(MATCH(99^99,B:B,1),0),IFERROR(MATCH(\"zzzz\",B:B,1),0)),MAX(IFERROR(MATCH(99^99,1:1,1),0),IFERROR(MATCH(\"zzzz\",1:1,1),0))))"); - assertEquals("Had: " + Arrays.toString(ptgs), - 40, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof MemFuncPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[3] instanceof NameXPxg); - - ptgs = parse(fpb, "SUM ( A1 : INDEX( 1 : 1048576 , MAX( IFERROR ( MATCH ( 99 ^ 99 , B : B , 1 ) , 0 ) , IFERROR ( MATCH ( \"zzzz\" , B:B , 1 ) , 0 ) ) , MAX ( IFERROR ( MATCH ( 99 ^ 99 , 1 : 1 , 1 ) , 0 ) , IFERROR ( MATCH ( \"zzzz\" , 1 : 1 , 1 ) , 0 ) ) ) )"); - assertEquals("Had: " + Arrays.toString(ptgs), - 40, ptgs.length); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[0] instanceof MemFuncPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[1] instanceof RefPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[2] instanceof AreaPtg); - assertTrue("Had " + Arrays.toString(ptgs), ptgs[3] instanceof NameXPxg); - - wb.close(); - } - - @Test - public void parseStructuredReferences() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - - XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs; - - /* - The following cases are tested (copied from FormulaParser.parseStructuredReference) - 1 Table1[col] - 2 Table1[[#Totals],[col]] - 3 Table1[#Totals] - 4 Table1[#All] - 5 Table1[#Data] - 6 Table1[#Headers] - 7 Table1[#Totals] - 8 Table1[#This Row] - 9 Table1[[#All],[col]] - 10 Table1[[#Headers],[col]] - 11 Table1[[#Totals],[col]] - 12 Table1[[#All],[col1]:[col2]] - 13 Table1[[#Data],[col1]:[col2]] - 14 Table1[[#Headers],[col1]:[col2]] - 15 Table1[[#Totals],[col1]:[col2]] - 16 Table1[[#Headers],[#Data],[col2]] - 17 Table1[[#This Row], [col1]] - 18 Table1[ [col1]:[col2] ] - */ - - final String tbl = "\\_Prime.1"; - final String noTotalsRowReason = ": Tables without a Totals row should return #REF! on [#Totals]"; - - ////// Case 1: Evaluate Table1[col] with apostrophe-escaped #-signs //////// - ptgs = parse(fpb, "SUM("+tbl+"[calc='#*'#])"); - assertEquals(2, ptgs.length); - - // Area3DPxg [sheet=Table ! A2:A7] - assertTrue(ptgs[0] instanceof Area3DPxg); - Area3DPxg ptg0 = (Area3DPxg) ptgs[0]; - assertEquals("Table", ptg0.getSheetName()); - assertEquals("A2:A7", ptg0.format2DRefAsString()); - // Note: structured references are evaluated and resolved to regular 3D area references. - assertEquals("Table!A2:A7", ptg0.toFormulaString()); - - // AttrPtg [sum ] - assertTrue(ptgs[1] instanceof AttrPtg); - AttrPtg ptg1 = (AttrPtg) ptgs[1]; - assertTrue(ptg1.isSum()); - - ////// Case 1: Evaluate "Table1[col]" //////// - ptgs = parse(fpb, tbl+"[Name]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[col]", "Table!B2:B7", ptgs[0].toFormulaString()); - - ////// Case 2: Evaluate "Table1[[#Totals],[col]]" //////// - ptgs = parse(fpb, tbl+"[[#Totals],[col]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Totals],[col]]" + noTotalsRowReason, ErrPtg.REF_INVALID, ptgs[0]); - - ////// Case 3: Evaluate "Table1[#Totals]" //////// - ptgs = parse(fpb, tbl+"[#Totals]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[#Totals]" + noTotalsRowReason, ErrPtg.REF_INVALID, ptgs[0]); - - ////// Case 4: Evaluate "Table1[#All]" //////// - ptgs = parse(fpb, tbl+"[#All]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[#All]", "Table!A1:C7", ptgs[0].toFormulaString()); - - ////// Case 5: Evaluate "Table1[#Data]" (excludes Header and Data rows) //////// - ptgs = parse(fpb, tbl+"[#Data]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[#Data]", "Table!A2:C7", ptgs[0].toFormulaString()); - - ////// Case 6: Evaluate "Table1[#Headers]" //////// - ptgs = parse(fpb, tbl+"[#Headers]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[#Headers]", "Table!A1:C1", ptgs[0].toFormulaString()); - - ////// Case 7: Evaluate "Table1[#Totals]" //////// - ptgs = parse(fpb, tbl+"[#Totals]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[#Totals]" + noTotalsRowReason, ErrPtg.REF_INVALID, ptgs[0]); - - ////// Case 8: Evaluate "Table1[#This Row]" //////// - ptgs = parse(fpb, tbl+"[#This Row]", 2); - assertEquals(1, ptgs.length); - assertEquals("Table1[#This Row]", "Table!A3:C3", ptgs[0].toFormulaString()); - - ////// Evaluate "Table1[@]" (equivalent to "Table1[#This Row]") //////// - ptgs = parse(fpb, tbl+"[@]", 2); - assertEquals(1, ptgs.length); - assertEquals("Table!A3:C3", ptgs[0].toFormulaString()); - - ////// Evaluate "Table1[#This Row]" when rowIndex is outside Table //////// - ptgs = parse(fpb, tbl+"[#This Row]", 10); - assertEquals(1, ptgs.length); - assertEquals("Table1[#This Row]", ErrPtg.VALUE_INVALID, ptgs[0]); - - ////// Evaluate "Table1[@]" when rowIndex is outside Table //////// - ptgs = parse(fpb, tbl+"[@]", 10); - assertEquals(1, ptgs.length); - assertEquals("Table1[@]", ErrPtg.VALUE_INVALID, ptgs[0]); - - ////// Evaluate "Table1[[#Data],[col]]" //////// - ptgs = parse(fpb, tbl+"[[#Data], [Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Data],[col]]", "Table!C2:C7", ptgs[0].toFormulaString()); - - - ////// Case 9: Evaluate "Table1[[#All],[col]]" //////// - ptgs = parse(fpb, tbl+"[[#All], [Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#All],[col]]", "Table!C1:C7", ptgs[0].toFormulaString()); - - ////// Case 10: Evaluate "Table1[[#Headers],[col]]" //////// - ptgs = parse(fpb, tbl+"[[#Headers], [Number]]"); - assertEquals(1, ptgs.length); - // also acceptable: Table1!B1 - assertEquals("Table1[[#Headers],[col]]", "Table!C1:C1", ptgs[0].toFormulaString()); - - ////// Case 11: Evaluate "Table1[[#Totals],[col]]" //////// - ptgs = parse(fpb, tbl+"[[#Totals],[Name]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Totals],[col]]" + noTotalsRowReason, ErrPtg.REF_INVALID, ptgs[0]); - - ////// Case 12: Evaluate "Table1[[#All],[col1]:[col2]]" //////// - ptgs = parse(fpb, tbl+"[[#All], [Name]:[Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#All],[col1]:[col2]]", "Table!B1:C7", ptgs[0].toFormulaString()); - - ////// Case 13: Evaluate "Table1[[#Data],[col]:[col2]]" //////// - ptgs = parse(fpb, tbl+"[[#Data], [Name]:[Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Data],[col]:[col2]]", "Table!B2:C7", ptgs[0].toFormulaString()); - - ////// Case 14: Evaluate "Table1[[#Headers],[col1]:[col2]]" //////// - ptgs = parse(fpb, tbl+"[[#Headers], [Name]:[Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Headers],[col1]:[col2]]", "Table!B1:C1", ptgs[0].toFormulaString()); - - ////// Case 15: Evaluate "Table1[[#Totals],[col]:[col2]]" //////// - ptgs = parse(fpb, tbl+"[[#Totals], [Name]:[Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Totals],[col]:[col2]]" + noTotalsRowReason, ErrPtg.REF_INVALID, ptgs[0]); - - ////// Case 16: Evaluate "Table1[[#Headers],[#Data],[col]]" //////// - ptgs = parse(fpb, tbl+"[[#Headers],[#Data],[Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[#Headers],[#Data],[col]]", "Table!C1:C7", ptgs[0].toFormulaString()); - - ////// Case 17: Evaluate "Table1[[#This Row], [col1]]" //////// - ptgs = parse(fpb, tbl+"[[#This Row], [Number]]", 2); - assertEquals(1, ptgs.length); - // also acceptable: Table!C3 - assertEquals("Table1[[#This Row], [col1]]", "Table!C3:C3", ptgs[0].toFormulaString()); - - ////// Case 18: Evaluate "Table1[[col]:[col2]]" //////// - ptgs = parse(fpb, tbl+"[[Name]:[Number]]"); - assertEquals(1, ptgs.length); - assertEquals("Table1[[col]:[col2]]", "Table!B2:C7", ptgs[0].toFormulaString()); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHeaderFooter.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHeaderFooter.java deleted file mode 100644 index 7c50d6aed..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHeaderFooter.java +++ /dev/null @@ -1,90 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.xssf.usermodel.extensions.XSSFHeaderFooter; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; - -import junit.framework.TestCase; - -/** - * Tests for {@link XSSFHeaderFooter} - */ -public class TestXSSFHeaderFooter extends TestCase { - public void testStripFields() { - String simple = "I am a test header"; - String withPage = "I am a&P test header"; - String withLots = "I&A am&N a&P test&T header&U"; - String withFont = "I&22 am a&\"Arial,bold\" test header"; - String withOtherAnds = "I am a&P test header&&"; - String withOtherAnds2 = "I am a&P test header&a&b"; - - assertEquals(simple, XSSFOddHeader.stripFields(simple)); - assertEquals(simple, XSSFOddHeader.stripFields(withPage)); - assertEquals(simple, XSSFOddHeader.stripFields(withLots)); - assertEquals(simple, XSSFOddHeader.stripFields(withFont)); - assertEquals(simple + "&&", XSSFOddHeader.stripFields(withOtherAnds)); - assertEquals(simple + "&a&b", XSSFOddHeader.stripFields(withOtherAnds2)); - - // Now test the default strip flag - XSSFEvenHeader head = new XSSFEvenHeader(CTHeaderFooter.Factory.newInstance()); - head.setCenter("Center"); - head.setLeft("In the left"); - - assertEquals("In the left", head.getLeft()); - assertEquals("Center", head.getCenter()); - assertEquals("", head.getRight()); - - head.setLeft("Top &P&F&D Left"); - assertEquals("Top &P&F&D Left", head.getLeft()); - assertFalse(head.areFieldsStripped()); - - head.setAreFieldsStripped(true); - assertEquals("Top Left", head.getLeft()); - assertTrue(head.areFieldsStripped()); - - // Now even more complex - head.setCenter("HEADER TEXT &P&N&D&T&Z&F&F&A&V"); - assertEquals("HEADER TEXT &V", head.getCenter()); - } - - public void testGetSetCenterLeftRight() { - - XSSFOddFooter footer = new XSSFOddFooter(CTHeaderFooter.Factory.newInstance()); - assertEquals("", footer.getCenter()); - footer.setCenter("My first center section"); - assertEquals("My first center section", footer.getCenter()); - footer.setCenter("No, let's update the center section"); - assertEquals("No, let's update the center section", footer.getCenter()); - footer.setLeft("And add a left one"); - footer.setRight("Finally the right section is added"); - assertEquals("And add a left one", footer.getLeft()); - assertEquals("Finally the right section is added", footer.getRight()); - - // Test changing the three sections value - footer.setCenter("Second center version"); - footer.setLeft("Second left version"); - footer.setRight("Second right version"); - assertEquals("Second center version", footer.getCenter()); - assertEquals("Second left version", footer.getLeft()); - assertEquals("Second right version", footer.getRight()); - - } - - // TODO Rest of tests -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHyperlink.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHyperlink.java deleted file mode 100644 index e03edcdd6..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHyperlink.java +++ /dev/null @@ -1,336 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.hssf.usermodel.HSSFHyperlink; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.ss.usermodel.BaseTestHyperlink; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -public final class TestXSSFHyperlink extends BaseTestHyperlink { - public TestXSSFHyperlink() { - super(XSSFITestDataProvider.instance); - } - - @Test - public void testLoadExisting() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithMoreVariousData.xlsx"); - assertEquals(3, workbook.getNumberOfSheets()); - - XSSFSheet sheet = workbook.getSheetAt(0); - - // Check the hyperlinks - assertEquals(4, sheet.getNumHyperlinks()); - doTestHyperlinkContents(sheet); - } - - @Test - public void testCreate() throws Exception { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - XSSFRow row = sheet.createRow(0); - XSSFCreationHelper createHelper = workbook.getCreationHelper(); - - String[] urls = { - "http://apache.org", - "www.apache.org", - "/temp", - "c:/temp", - "http://apache.org/default.php?s=isTramsformed&submit=Search&la=*&li=*"}; - for(int i = 0; i < urls.length; i++){ - String s = urls[i]; - XSSFHyperlink link = createHelper.createHyperlink(HyperlinkType.URL); - link.setAddress(s); - - XSSFCell cell = row.createCell(i); - cell.setHyperlink(link); - } - workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); - sheet = workbook.getSheetAt(0); - PackageRelationshipCollection rels = sheet.getPackagePart().getRelationships(); - assertEquals(urls.length, rels.size()); - for(int i = 0; i < rels.size(); i++){ - PackageRelationship rel = rels.getRelationship(i); - // there should be a relationship for each URL - assertEquals(urls[i], rel.getTargetURI().toString()); - } - - // Bugzilla 53041: Hyperlink relations are duplicated when saving XSSF file - workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); - sheet = workbook.getSheetAt(0); - rels = sheet.getPackagePart().getRelationships(); - assertEquals(urls.length, rels.size()); - for(int i = 0; i < rels.size(); i++){ - PackageRelationship rel = rels.getRelationship(i); - // there should be a relationship for each URL - assertEquals(urls[i], rel.getTargetURI().toString()); - } - } - - @Test - public void testInvalidURLs() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFCreationHelper createHelper = workbook.getCreationHelper(); - - String[] invalidURLs = { - "http:\\apache.org", - "www.apache .org", - "c:\\temp", - "\\poi"}; - for(String s : invalidURLs){ - try { - createHelper.createHyperlink(HyperlinkType.URL).setAddress(s); - fail("expected IllegalArgumentException: " + s); - } catch (IllegalArgumentException e){ - - } - } - workbook.close(); - } - - @Test - public void testLoadSave() { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithMoreVariousData.xlsx"); - CreationHelper createHelper = workbook.getCreationHelper(); - assertEquals(3, workbook.getNumberOfSheets()); - XSSFSheet sheet = workbook.getSheetAt(0); - - // Check hyperlinks - assertEquals(4, sheet.getNumHyperlinks()); - doTestHyperlinkContents(sheet); - - - // Write out, and check - - // Load up again, check all links still there - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertEquals(3, wb2.getNumberOfSheets()); - assertNotNull(wb2.getSheetAt(0)); - assertNotNull(wb2.getSheetAt(1)); - assertNotNull(wb2.getSheetAt(2)); - - sheet = wb2.getSheetAt(0); - - - // Check hyperlinks again - assertEquals(4, sheet.getNumHyperlinks()); - doTestHyperlinkContents(sheet); - - - // Add one more, and re-check - Row r17 = sheet.createRow(17); - Cell r17c = r17.createCell(2); - - Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL); - hyperlink.setAddress("http://poi.apache.org/spreadsheet/"); - hyperlink.setLabel("POI SS Link"); - r17c.setHyperlink(hyperlink); - - assertEquals(5, sheet.getNumHyperlinks()); - doTestHyperlinkContents(sheet); - - assertEquals(HyperlinkType.URL, - sheet.getRow(17).getCell(2).getHyperlink().getTypeEnum()); - assertEquals("POI SS Link", - sheet.getRow(17).getCell(2).getHyperlink().getLabel()); - assertEquals("http://poi.apache.org/spreadsheet/", - sheet.getRow(17).getCell(2).getHyperlink().getAddress()); - - - // Save and re-load once more - - XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - assertEquals(3, wb3.getNumberOfSheets()); - assertNotNull(wb3.getSheetAt(0)); - assertNotNull(wb3.getSheetAt(1)); - assertNotNull(wb3.getSheetAt(2)); - - sheet = wb3.getSheetAt(0); - - assertEquals(5, sheet.getNumHyperlinks()); - doTestHyperlinkContents(sheet); - - assertEquals(HyperlinkType.URL, - sheet.getRow(17).getCell(2).getHyperlink().getTypeEnum()); - assertEquals("POI SS Link", - sheet.getRow(17).getCell(2).getHyperlink().getLabel()); - assertEquals("http://poi.apache.org/spreadsheet/", - sheet.getRow(17).getCell(2).getHyperlink().getAddress()); - } - - /** - * Only for WithMoreVariousData.xlsx ! - */ - private static void doTestHyperlinkContents(XSSFSheet sheet) { - assertNotNull(sheet.getRow(3).getCell(2).getHyperlink()); - assertNotNull(sheet.getRow(14).getCell(2).getHyperlink()); - assertNotNull(sheet.getRow(15).getCell(2).getHyperlink()); - assertNotNull(sheet.getRow(16).getCell(2).getHyperlink()); - - // First is a link to poi - assertEquals(HyperlinkType.URL, - sheet.getRow(3).getCell(2).getHyperlink().getTypeEnum()); - assertEquals(null, - sheet.getRow(3).getCell(2).getHyperlink().getLabel()); - assertEquals("http://poi.apache.org/", - sheet.getRow(3).getCell(2).getHyperlink().getAddress()); - - // Next is an internal doc link - assertEquals(HyperlinkType.DOCUMENT, - sheet.getRow(14).getCell(2).getHyperlink().getTypeEnum()); - assertEquals("Internal hyperlink to A2", - sheet.getRow(14).getCell(2).getHyperlink().getLabel()); - assertEquals("Sheet1!A2", - sheet.getRow(14).getCell(2).getHyperlink().getAddress()); - - // Next is a file - assertEquals(HyperlinkType.FILE, - sheet.getRow(15).getCell(2).getHyperlink().getTypeEnum()); - assertEquals(null, - sheet.getRow(15).getCell(2).getHyperlink().getLabel()); - assertEquals("WithVariousData.xlsx", - sheet.getRow(15).getCell(2).getHyperlink().getAddress()); - - // Last is a mailto - assertEquals(HyperlinkType.EMAIL, - sheet.getRow(16).getCell(2).getHyperlink().getTypeEnum()); - assertEquals(null, - sheet.getRow(16).getCell(2).getHyperlink().getLabel()); - assertEquals("mailto:dev@poi.apache.org?subject=XSSF%20Hyperlinks", - sheet.getRow(16).getCell(2).getHyperlink().getAddress()); - } - - @Test - public void test52716() { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("52716.xlsx"); - XSSFSheet sh1 = wb1.getSheetAt(0); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - XSSFSheet sh2 = wb2.getSheetAt(0); - - assertEquals(sh1.getNumberOfComments(), sh2.getNumberOfComments()); - XSSFHyperlink l1 = sh1.getHyperlink(0, 1); - assertEquals(HyperlinkType.DOCUMENT, l1.getTypeEnum()); - assertEquals("B1", l1.getCellRef()); - assertEquals("Sort on Titel", l1.getTooltip()); - - XSSFHyperlink l2 = sh2.getHyperlink(0, 1); - assertEquals(l1.getTooltip(), l2.getTooltip()); - assertEquals(HyperlinkType.DOCUMENT, l2.getTypeEnum()); - assertEquals("B1", l2.getCellRef()); - } - - @Test - public void test53734() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53734.xlsx"); - XSSFHyperlink link = wb.getSheetAt(0).getRow(0).getCell(0).getHyperlink(); - assertEquals("javascript:///", link.getAddress()); - - wb = XSSFTestDataSamples.writeOutAndReadBack(wb); - link = wb.getSheetAt(0).getRow(0).getCell(0).getHyperlink(); - assertEquals("javascript:///", link.getAddress()); - } - - @Test - public void test53282() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53282.xlsx"); - XSSFHyperlink link = wb.getSheetAt(0).getRow(0).getCell(14).getHyperlink(); - assertEquals("mailto:nobody@nowhere.uk%C2%A0", link.getAddress()); - - wb = XSSFTestDataSamples.writeOutAndReadBack(wb); - link = wb.getSheetAt(0).getRow(0).getCell(14).getHyperlink(); - assertEquals("mailto:nobody@nowhere.uk%C2%A0", link.getAddress()); - } - - @Override - public XSSFHyperlink copyHyperlink(Hyperlink link) { - return new XSSFHyperlink(link); - } - - @Test - public void testCopyHSSFHyperlink() throws IOException { - HSSFWorkbook hssfworkbook = new HSSFWorkbook(); - HSSFHyperlink hlink = hssfworkbook.getCreationHelper().createHyperlink(HyperlinkType.URL); - hlink.setAddress("http://poi.apache.org/"); - hlink.setFirstColumn(3); - hlink.setFirstRow(2); - hlink.setLastColumn(5); - hlink.setLastRow(6); - hlink.setLabel("label"); - XSSFHyperlink xlink = new XSSFHyperlink(hlink); - - assertEquals("http://poi.apache.org/", xlink.getAddress()); - assertEquals(new CellReference(2, 3), new CellReference(xlink.getCellRef())); - // Are HSSFHyperlink.label and XSSFHyperlink.tooltip the same? If so, perhaps one of these needs renamed for a consistent Hyperlink interface - // assertEquals("label", xlink.getTooltip()); - - hssfworkbook.close(); - } - - /* bug 59775: XSSFHyperlink has wrong type if it contains a location (CTHyperlink#getLocation) - * URLs with a hash mark (#) are still URL hyperlinks, not document links - */ - @Test - public void testURLsWithHashMark() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("59775.xlsx"); - XSSFSheet sh = wb.getSheetAt(0); - CellAddress A2 = new CellAddress("A2"); - CellAddress A3 = new CellAddress("A3"); - CellAddress A4 = new CellAddress("A4"); - CellAddress A7 = new CellAddress("A7"); - - XSSFHyperlink link = sh.getHyperlink(A2); - assertEquals("address", "A2", link.getCellRef()); - assertEquals("link type", HyperlinkType.URL, link.getTypeEnum()); - assertEquals("link target", "http://twitter.com/#!/apacheorg", link.getAddress()); - - link = sh.getHyperlink(A3); - assertEquals("address", "A3", link.getCellRef()); - assertEquals("link type", HyperlinkType.URL, link.getTypeEnum()); - assertEquals("link target", "http://www.bailii.org/databases.html#ie", link.getAddress()); - - link = sh.getHyperlink(A4); - assertEquals("address", "A4", link.getCellRef()); - assertEquals("link type", HyperlinkType.URL, link.getTypeEnum()); - assertEquals("link target", "https://en.wikipedia.org/wiki/Apache_POI#See_also", link.getAddress()); - - link = sh.getHyperlink(A7); - assertEquals("address", "A7", link.getCellRef()); - assertEquals("link type", HyperlinkType.DOCUMENT, link.getTypeEnum()); - assertEquals("link target", "Sheet1", link.getAddress()); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java deleted file mode 100644 index a188a11ed..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.xssf.XSSFTestDataSamples; -import org.junit.Test; -import org.apache.poi.xssf.XSSFITestDataProvider; - -import static org.junit.Assert.*; - -import org.apache.poi.ss.usermodel.BaseTestNamedRange; -import org.apache.poi.ss.util.CellRangeAddress; - -/** - * @author Yegor Kozlov - */ -public final class TestXSSFName extends BaseTestNamedRange { - - public TestXSSFName() { - super(XSSFITestDataProvider.instance); - } - - //TODO combine testRepeatingRowsAndColums() for HSSF and XSSF - @Test - public void testRepeatingRowsAndColums() throws Exception { - // First test that setting RR&C for same sheet more than once only creates a - // single Print_Titles built-in record - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet1 = wb.createSheet("First Sheet"); - - sheet1.setRepeatingRows(null); - sheet1.setRepeatingColumns(null); - - // set repeating rows and columns twice for the first sheet - for (int i = 0; i < 2; i++) { - sheet1.setRepeatingRows(CellRangeAddress.valueOf("1:4")); - sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:A")); - //sheet.createFreezePane(0, 3); - } - assertEquals(1, wb.getNumberOfNames()); - XSSFName nr1 = wb.getName(XSSFName.BUILTIN_PRINT_TITLE); - - assertEquals("'First Sheet'!$A:$A,'First Sheet'!$1:$4", nr1.getRefersToFormula()); - - //remove the columns part - sheet1.setRepeatingColumns(null); - assertEquals("'First Sheet'!$1:$4", nr1.getRefersToFormula()); - - //revert - sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:A")); - - //remove the rows part - sheet1.setRepeatingRows(null); - assertEquals("'First Sheet'!$A:$A", nr1.getRefersToFormula()); - - //revert - sheet1.setRepeatingRows(CellRangeAddress.valueOf("1:4")); - - // Save and re-open - XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb); - wb.close(); - - assertEquals(1, nwb.getNumberOfNames()); - nr1 = nwb.getName(XSSFName.BUILTIN_PRINT_TITLE); - - assertEquals("'First Sheet'!$A:$A,'First Sheet'!$1:$4", nr1.getRefersToFormula()); - - // check that setting RR&C on a second sheet causes a new Print_Titles built-in - // name to be created - XSSFSheet sheet2 = nwb.createSheet("SecondSheet"); - sheet2.setRepeatingRows(CellRangeAddress.valueOf("1:1")); - sheet2.setRepeatingColumns(CellRangeAddress.valueOf("B:C")); - - assertEquals(2, nwb.getNumberOfNames()); - XSSFName nr2 = nwb.getNames(XSSFName.BUILTIN_PRINT_TITLE).get(1); - - assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr2.getNameName()); - assertEquals("SecondSheet!$B:$C,SecondSheet!$1:$1", nr2.getRefersToFormula()); - - sheet2.setRepeatingRows(null); - sheet2.setRepeatingColumns(null); - nwb.close(); - } - - @Test - public void testSetNameName() throws Exception { - // Test that renaming named ranges doesn't break our new named range map - XSSFWorkbook wb = new XSSFWorkbook(); - wb.createSheet("First Sheet"); - - // Two named ranges called "name1", one scoped to sheet1 and one globally - XSSFName nameSheet1 = wb.createName(); - nameSheet1.setNameName("name1"); - nameSheet1.setRefersToFormula("'First Sheet'!$A$1"); - nameSheet1.setSheetIndex(0); - - XSSFName nameGlobal = wb.createName(); - nameGlobal.setNameName("name1"); - nameGlobal.setRefersToFormula("'First Sheet'!$B$1"); - - // Rename sheet-scoped name to "name2", check everything is updated properly - // and that the other name is unaffected - nameSheet1.setNameName("name2"); - assertEquals(1, wb.getNames("name1").size()); - assertEquals(1, wb.getNames("name2").size()); - assertEquals(nameGlobal, wb.getName("name1")); - assertEquals(nameSheet1, wb.getName("name2")); - - // Rename the other name to "name" and check everything again - nameGlobal.setNameName("name2"); - assertEquals(0, wb.getNames("name1").size()); - assertEquals(2, wb.getNames("name2").size()); - assertTrue(wb.getNames("name2").contains(nameGlobal)); - assertTrue(wb.getNames("name2").contains(nameSheet1)); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java deleted file mode 100644 index edaa974a2..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java +++ /dev/null @@ -1,163 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.ss.usermodel.BaseTestPicture; -import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs; - -/** - * @author Yegor Kozlov - */ -public final class TestXSSFPicture extends BaseTestPicture { - - public TestXSSFPicture() { - super(XSSFITestDataProvider.instance); - } - - @Test - public void resize() throws Exception { - XSSFWorkbook wb = XSSFITestDataProvider.instance.openSampleWorkbook("resize_compare.xlsx"); - XSSFDrawing dp = wb.getSheetAt(0).createDrawingPatriarch(); - List pics = dp.getShapes(); - XSSFPicture inpPic = (XSSFPicture)pics.get(0); - XSSFPicture cmpPic = (XSSFPicture)pics.get(0); - - baseTestResize(inpPic, cmpPic, 2.0, 2.0); - wb.close(); - } - - - @Test - public void create() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - byte[] jpegData = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); - - List pictures = wb.getAllPictures(); - assertEquals(0, pictures.size()); - - int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); - assertEquals(1, pictures.size()); - assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); - assertArrayEquals(jpegData, pictures.get(jpegIdx).getData()); - - XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); - assertEquals(AnchorType.MOVE_AND_RESIZE, anchor.getAnchorType()); - anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE); - assertEquals(AnchorType.DONT_MOVE_AND_RESIZE, anchor.getAnchorType()); - - XSSFPicture shape = drawing.createPicture(anchor, jpegIdx); - assertTrue(anchor.equals(shape.getAnchor())); - assertNotNull(shape.getPictureData()); - assertArrayEquals(jpegData, shape.getPictureData().getData()); - - CTTwoCellAnchor ctShapeHolder = drawing.getCTDrawing().getTwoCellAnchorArray(0); - // STEditAs.ABSOLUTE corresponds to ClientAnchor.DONT_MOVE_AND_RESIZE - assertEquals(STEditAs.ABSOLUTE, ctShapeHolder.getEditAs()); - - wb.close(); - } - - /** - * test that ShapeId in CTNonVisualDrawingProps is incremented - * - * See Bugzilla 50458 - */ - @Test - public void incrementShapeId() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); - byte[] jpegData = "picture1".getBytes(LocaleUtil.CHARSET_1252); - int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); - - XSSFPicture shape1 = drawing.createPicture(anchor, jpegIdx); - assertEquals(1, shape1.getCTPicture().getNvPicPr().getCNvPr().getId()); - - jpegData = "picture2".getBytes(LocaleUtil.CHARSET_1252); - jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); - XSSFPicture shape2 = drawing.createPicture(anchor, jpegIdx); - assertEquals(2, shape2.getCTPicture().getNvPicPr().getCNvPr().getId()); - wb.close(); - } - - /** - * same image refrerred by mulitple sheets - */ - @SuppressWarnings("resource") - @Test - public void multiRelationShips() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - - byte[] pic1Data = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); - byte[] pic2Data = "test png data".getBytes(LocaleUtil.CHARSET_1252); - - List pictures = wb.getAllPictures(); - assertEquals(0, pictures.size()); - - int pic1 = wb.addPicture(pic1Data, XSSFWorkbook.PICTURE_TYPE_JPEG); - int pic2 = wb.addPicture(pic2Data, XSSFWorkbook.PICTURE_TYPE_PNG); - - XSSFSheet sheet1 = wb.createSheet(); - XSSFDrawing drawing1 = sheet1.createDrawingPatriarch(); - XSSFPicture shape1 = drawing1.createPicture(new XSSFClientAnchor(), pic1); - XSSFPicture shape2 = drawing1.createPicture(new XSSFClientAnchor(), pic2); - - XSSFSheet sheet2 = wb.createSheet(); - XSSFDrawing drawing2 = sheet2.createDrawingPatriarch(); - XSSFPicture shape3 = drawing2.createPicture(new XSSFClientAnchor(), pic2); - XSSFPicture shape4 = drawing2.createPicture(new XSSFClientAnchor(), pic1); - - assertEquals(2, pictures.size()); - - wb = XSSFTestDataSamples.writeOutAndReadBack(wb); - pictures = wb.getAllPictures(); - assertEquals(2, pictures.size()); - - sheet1 = wb.getSheetAt(0); - drawing1 = sheet1.createDrawingPatriarch(); - XSSFPicture shape11 = (XSSFPicture)drawing1.getShapes().get(0); - assertArrayEquals(shape1.getPictureData().getData(), shape11.getPictureData().getData()); - XSSFPicture shape22 = (XSSFPicture)drawing1.getShapes().get(1); - assertArrayEquals(shape2.getPictureData().getData(), shape22.getPictureData().getData()); - - sheet2 = wb.getSheetAt(1); - drawing2 = sheet2.createDrawingPatriarch(); - XSSFPicture shape33 = (XSSFPicture)drawing2.getShapes().get(0); - assertArrayEquals(shape3.getPictureData().getData(), shape33.getPictureData().getData()); - XSSFPicture shape44 = (XSSFPicture)drawing2.getShapes().get(1); - assertArrayEquals(shape4.getPictureData().getData(), shape44.getPictureData().getData()); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java deleted file mode 100644 index db2801fc3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -/** - * @author Yegor Kozlov - */ -public final class TestXSSFPictureData { - @Test - public void testRead() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx"); - List pictures = wb.getAllPictures(); - //wb.getAllPictures() should return the same instance across multiple calls - assertSame(pictures, wb.getAllPictures()); - - assertEquals(5, pictures.size()); - String[] ext = {"jpeg", "emf", "png", "emf", "wmf"}; - String[] mimetype = {"image/jpeg", "image/x-emf", "image/png", "image/x-emf", "image/x-wmf"}; - for (int i = 0; i < pictures.size(); i++) { - assertEquals(ext[i], pictures.get(i).suggestFileExtension()); - assertEquals(mimetype[i], pictures.get(i).getMimeType()); - } - - int num = pictures.size(); - - byte[] pictureData = {0xA, 0xB, 0XC, 0xD, 0xE, 0xF}; - - int idx = wb.addPicture(pictureData, XSSFWorkbook.PICTURE_TYPE_JPEG); - assertEquals(num + 1, pictures.size()); - //idx is 0-based index in the #pictures array - assertEquals(pictures.size() - 1, idx); - XSSFPictureData pict = pictures.get(idx); - assertEquals("jpeg", pict.suggestFileExtension()); - assertArrayEquals(pictureData, pict.getData()); - wb.close(); - } - - @Test - public void testNew() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - byte[] jpegData = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252); - byte[] wmfData = "test wmf data".getBytes(LocaleUtil.CHARSET_1252); - byte[] pngData = "test png data".getBytes(LocaleUtil.CHARSET_1252); - - List pictures = wb.getAllPictures(); - assertEquals(0, pictures.size()); - - int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG); - assertEquals(1, pictures.size()); - assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); - assertArrayEquals(jpegData, pictures.get(jpegIdx).getData()); - - int wmfIdx = wb.addPicture(wmfData, XSSFWorkbook.PICTURE_TYPE_WMF); - assertEquals(2, pictures.size()); - assertEquals("wmf", pictures.get(wmfIdx).suggestFileExtension()); - assertArrayEquals(wmfData, pictures.get(wmfIdx).getData()); - - int pngIdx = wb.addPicture(pngData, XSSFWorkbook.PICTURE_TYPE_PNG); - assertEquals(3, pictures.size()); - assertEquals("png", pictures.get(pngIdx).suggestFileExtension()); - assertArrayEquals(pngData, pictures.get(pngIdx).getData()); - - //TODO finish usermodel API for XSSFPicture - XSSFPicture p1 = drawing.createPicture(new XSSFClientAnchor(), jpegIdx); - assertNotNull(p1); - XSSFPicture p2 = drawing.createPicture(new XSSFClientAnchor(), wmfIdx); - assertNotNull(p2); - XSSFPicture p3 = drawing.createPicture(new XSSFClientAnchor(), pngIdx); - assertNotNull(p3); - - //check that the added pictures are accessible after write - XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - List pictures2 = wbBack.getAllPictures(); - assertEquals(3, pictures2.size()); - - assertEquals("jpeg", pictures2.get(jpegIdx).suggestFileExtension()); - assertArrayEquals(jpegData, pictures2.get(jpegIdx).getData()); - - assertEquals("wmf", pictures2.get(wmfIdx).suggestFileExtension()); - assertArrayEquals(wmfData, pictures2.get(wmfIdx).getData()); - - assertEquals("png", pictures2.get(pngIdx).suggestFileExtension()); - assertArrayEquals(pngData, pictures2.get(pngIdx).getData()); - wbBack.close(); - wb.close(); - } - - /** - * Bug 53568: XSSFPicture.getPictureData() can return null. - */ - @Test - public void test53568() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53568.xlsx"); - List pictures = wb.getAllPictures(); - assertNotNull(pictures); - assertEquals(4, pictures.size()); - - XSSFSheet sheet1 = wb.getSheetAt(0); - List shapes1 = sheet1.createDrawingPatriarch().getShapes(); - assertNotNull(shapes1); - assertEquals(5, shapes1.size()); - - for(int i = 0; i < wb.getNumberOfSheets(); i++){ - XSSFSheet sheet = wb.getSheetAt(i); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - for(XSSFShape shape : drawing.getShapes()){ - if(shape instanceof XSSFPicture){ - XSSFPicture pic = (XSSFPicture)shape; - XSSFPictureData picData = pic.getPictureData(); - assertNotNull(picData); - } - } - } - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java deleted file mode 100644 index 8df2a663d..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.CellReference; -import org.junit.Before; - -/** - * Test pivot tables created by named range - */ -public class TestXSSFPivotTableName extends BaseTestXSSFPivotTable { - - @Override - @Before - public void setUp(){ - wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - - Row row1 = sheet.createRow(0); - // Create a cell and put a value in it. - Cell cell = row1.createCell(0); - cell.setCellValue("Names"); - Cell cell2 = row1.createCell(1); - cell2.setCellValue("#"); - Cell cell7 = row1.createCell(2); - cell7.setCellValue("Data"); - Cell cell10 = row1.createCell(3); - cell10.setCellValue("Value"); - - Row row2 = sheet.createRow(1); - Cell cell3 = row2.createCell(0); - cell3.setCellValue("Jan"); - Cell cell4 = row2.createCell(1); - cell4.setCellValue(10); - Cell cell8 = row2.createCell(2); - cell8.setCellValue("Apa"); - Cell cell11 = row1.createCell(3); - cell11.setCellValue(11.11); - - Row row3 = sheet.createRow(2); - Cell cell5 = row3.createCell(0); - cell5.setCellValue("Ben"); - Cell cell6 = row3.createCell(1); - cell6.setCellValue(9); - Cell cell9 = row3.createCell(2); - cell9.setCellValue("Bepa"); - Cell cell12 = row1.createCell(3); - cell12.setCellValue(12.12); - - XSSFName namedRange = sheet.getWorkbook().createName(); - namedRange.setRefersToFormula(sheet.getSheetName() + "!" + "A1:C2"); - pivotTable = sheet.createPivotTable(namedRange, new CellReference("H5")); - - XSSFSheet offsetSheet = wb.createSheet(); - - Row tableRow_1 = offsetSheet.createRow(1); - offsetOuterCell = tableRow_1.createCell(1); - offsetOuterCell.setCellValue(-1); - Cell tableCell_1_1 = tableRow_1.createCell(2); - tableCell_1_1.setCellValue("Row #"); - Cell tableCell_1_2 = tableRow_1.createCell(3); - tableCell_1_2.setCellValue("Exponent"); - Cell tableCell_1_3 = tableRow_1.createCell(4); - tableCell_1_3.setCellValue("10^Exponent"); - - Row tableRow_2 = offsetSheet.createRow(2); - Cell tableCell_2_1 = tableRow_2.createCell(2); - tableCell_2_1.setCellValue(0); - Cell tableCell_2_2 = tableRow_2.createCell(3); - tableCell_2_2.setCellValue(0); - Cell tableCell_2_3 = tableRow_2.createCell(4); - tableCell_2_3.setCellValue(1); - - Row tableRow_3= offsetSheet.createRow(3); - Cell tableCell_3_1 = tableRow_3.createCell(2); - tableCell_3_1.setCellValue(1); - Cell tableCell_3_2 = tableRow_3.createCell(3); - tableCell_3_2.setCellValue(1); - Cell tableCell_3_3 = tableRow_3.createCell(4); - tableCell_3_3.setCellValue(10); - - Row tableRow_4 = offsetSheet.createRow(4); - Cell tableCell_4_1 = tableRow_4.createCell(2); - tableCell_4_1.setCellValue(2); - Cell tableCell_4_2 = tableRow_4.createCell(3); - tableCell_4_2.setCellValue(2); - Cell tableCell_4_3 = tableRow_4.createCell(4); - tableCell_4_3.setCellValue(100); - - namedRange = sheet.getWorkbook().createName(); - namedRange.setRefersToFormula("C2:E4"); - namedRange.setSheetIndex(sheet.getWorkbook().getSheetIndex(sheet)); - offsetPivotTable = offsetSheet.createPivotTable(namedRange, new CellReference("C6")); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java deleted file mode 100644 index ec0c5c6c1..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java +++ /dev/null @@ -1,111 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.junit.Before; - -/** - * Test pivot tables created by area reference - */ -public class TestXSSFPivotTableRef extends BaseTestXSSFPivotTable { - - @Override - @Before - public void setUp(){ - wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - - Row row1 = sheet.createRow(0); - // Create a cell and put a value in it. - Cell cell = row1.createCell(0); - cell.setCellValue("Names"); - Cell cell2 = row1.createCell(1); - cell2.setCellValue("#"); - Cell cell7 = row1.createCell(2); - cell7.setCellValue("Data"); - Cell cell10 = row1.createCell(3); - cell10.setCellValue("Value"); - - Row row2 = sheet.createRow(1); - Cell cell3 = row2.createCell(0); - cell3.setCellValue("Jan"); - Cell cell4 = row2.createCell(1); - cell4.setCellValue(10); - Cell cell8 = row2.createCell(2); - cell8.setCellValue("Apa"); - Cell cell11 = row1.createCell(3); - cell11.setCellValue(11.11); - - Row row3 = sheet.createRow(2); - Cell cell5 = row3.createCell(0); - cell5.setCellValue("Ben"); - Cell cell6 = row3.createCell(1); - cell6.setCellValue(9); - Cell cell9 = row3.createCell(2); - cell9.setCellValue("Bepa"); - Cell cell12 = row1.createCell(3); - cell12.setCellValue(12.12); - - AreaReference source = new AreaReference("A1:C2", SpreadsheetVersion.EXCEL2007); - pivotTable = sheet.createPivotTable(source, new CellReference("H5")); - - XSSFSheet offsetSheet = wb.createSheet(); - - Row tableRow_1 = offsetSheet.createRow(1); - offsetOuterCell = tableRow_1.createCell(1); - offsetOuterCell.setCellValue(-1); - Cell tableCell_1_1 = tableRow_1.createCell(2); - tableCell_1_1.setCellValue("Row #"); - Cell tableCell_1_2 = tableRow_1.createCell(3); - tableCell_1_2.setCellValue("Exponent"); - Cell tableCell_1_3 = tableRow_1.createCell(4); - tableCell_1_3.setCellValue("10^Exponent"); - - Row tableRow_2 = offsetSheet.createRow(2); - Cell tableCell_2_1 = tableRow_2.createCell(2); - tableCell_2_1.setCellValue(0); - Cell tableCell_2_2 = tableRow_2.createCell(3); - tableCell_2_2.setCellValue(0); - Cell tableCell_2_3 = tableRow_2.createCell(4); - tableCell_2_3.setCellValue(1); - - Row tableRow_3= offsetSheet.createRow(3); - Cell tableCell_3_1 = tableRow_3.createCell(2); - tableCell_3_1.setCellValue(1); - Cell tableCell_3_2 = tableRow_3.createCell(3); - tableCell_3_2.setCellValue(1); - Cell tableCell_3_3 = tableRow_3.createCell(4); - tableCell_3_3.setCellValue(10); - - Row tableRow_4 = offsetSheet.createRow(4); - Cell tableCell_4_1 = tableRow_4.createCell(2); - tableCell_4_1.setCellValue(2); - Cell tableCell_4_2 = tableRow_4.createCell(3); - tableCell_4_2.setCellValue(2); - Cell tableCell_4_3 = tableRow_4.createCell(4); - tableCell_4_3.setCellValue(100); - - AreaReference offsetSource = new AreaReference(new CellReference("C2"), new CellReference("E4")); - offsetPivotTable = offsetSheet.createPivotTable(offsetSource, new CellReference("C6")); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java deleted file mode 100644 index 6cda3aff2..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java +++ /dev/null @@ -1,285 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.PageOrder; -import org.apache.poi.ss.usermodel.PaperSize; -import org.apache.poi.ss.usermodel.PrintCellComments; -import org.apache.poi.ss.usermodel.PrintOrientation; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetup; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellComments; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STOrientation; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPageOrder; - -/** - * Tests for {@link XSSFPrintSetup} - */ -public class TestXSSFPrintSetup extends TestCase { - public void testSetGetPaperSize() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setPaperSize(9); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(PaperSize.A4_PAPER, printSetup.getPaperSizeEnum()); - assertEquals(9, printSetup.getPaperSize()); - - printSetup.setPaperSize(PaperSize.A3_PAPER); - assertEquals(8, pSetup.getPaperSize()); - } - - - public void testSetGetScale() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setScale(9); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(9, printSetup.getScale()); - - printSetup.setScale((short) 100); - assertEquals(100, pSetup.getScale()); - } - - public void testSetGetPageStart() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setFirstPageNumber(9); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(9, printSetup.getPageStart()); - - printSetup.setPageStart((short) 1); - assertEquals(1, pSetup.getFirstPageNumber()); - } - - - public void testSetGetFitWidthHeight() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setFitToWidth(50); - pSetup.setFitToHeight(99); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(50, printSetup.getFitWidth()); - assertEquals(99, printSetup.getFitHeight()); - - printSetup.setFitWidth((short) 66); - printSetup.setFitHeight((short) 80); - assertEquals(66, pSetup.getFitToWidth()); - assertEquals(80, pSetup.getFitToHeight()); - - } - - public void testSetGetLeftToRight() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setPageOrder(STPageOrder.DOWN_THEN_OVER); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(false, printSetup.getLeftToRight()); - - printSetup.setLeftToRight(true); - assertEquals(PageOrder.OVER_THEN_DOWN.getValue(), pSetup.getPageOrder().intValue()); - } - - public void testSetGetOrientation() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setOrientation(STOrientation.PORTRAIT); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(PrintOrientation.PORTRAIT, printSetup.getOrientation()); - assertEquals(false, printSetup.getLandscape()); - assertEquals(false, printSetup.getNoOrientation()); - - printSetup.setOrientation(PrintOrientation.LANDSCAPE); - assertEquals(pSetup.getOrientation().intValue(), printSetup.getOrientation().getValue()); - assertEquals(true, printSetup.getLandscape()); - assertEquals(false, printSetup.getNoOrientation()); - } - - - public void testSetGetValidSettings() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setUsePrinterDefaults(false); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(false, printSetup.getValidSettings()); - - printSetup.setValidSettings(true); - assertEquals(true, pSetup.getUsePrinterDefaults()); - } - - public void testSetGetNoColor() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setBlackAndWhite(false); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(false, printSetup.getNoColor()); - - printSetup.setNoColor(true); - assertEquals(true, pSetup.getBlackAndWhite()); - } - - public void testSetGetDraft() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setDraft(false); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(false, printSetup.getDraft()); - - printSetup.setDraft(true); - assertEquals(true, pSetup.getDraft()); - } - - public void testSetGetNotes() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setCellComments(STCellComments.NONE); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(false, printSetup.getNotes()); - - printSetup.setNotes(true); - assertEquals(PrintCellComments.AS_DISPLAYED.getValue(), pSetup.getCellComments().intValue()); - } - - - public void testSetGetUsePage() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setUseFirstPageNumber(false); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(false, printSetup.getUsePage()); - - printSetup.setUsePage(true); - assertEquals(true, pSetup.getUseFirstPageNumber()); - } - - public void testSetGetHVResolution() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setHorizontalDpi(120); - pSetup.setVerticalDpi(100); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(120, printSetup.getHResolution()); - assertEquals(100, printSetup.getVResolution()); - - printSetup.setHResolution((short) 150); - printSetup.setVResolution((short) 130); - assertEquals(150, pSetup.getHorizontalDpi()); - assertEquals(130, pSetup.getVerticalDpi()); - } - - public void testSetGetHeaderFooterMargin() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageMargins pMargins = worksheet.addNewPageMargins(); - pMargins.setHeader(1.5); - pMargins.setFooter(2); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(1.5, printSetup.getHeaderMargin(), 0.0); - assertEquals(2.0, printSetup.getFooterMargin(), 0.0); - - printSetup.setHeaderMargin(5); - printSetup.setFooterMargin(3.5); - assertEquals(5.0, pMargins.getHeader(), 0.0); - assertEquals(3.5, pMargins.getFooter(), 0.0); - } - - public void testSetGetCopies() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - CTPageSetup pSetup = worksheet.addNewPageSetup(); - pSetup.setCopies(9); - XSSFPrintSetup printSetup = new XSSFPrintSetup(worksheet); - assertEquals(9, printSetup.getCopies()); - - printSetup.setCopies((short) 15); - assertEquals(15, pSetup.getCopies()); - } - - public void testSetSaveRead() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet s1 = wb.createSheet(); - assertEquals(false, s1.getCTWorksheet().isSetPageSetup()); - assertEquals(true, s1.getCTWorksheet().isSetPageMargins()); - - XSSFPrintSetup print = s1.getPrintSetup(); - assertEquals(true, s1.getCTWorksheet().isSetPageSetup()); - assertEquals(true, s1.getCTWorksheet().isSetPageMargins()); - - print.setCopies((short)3); - print.setLandscape(true); - assertEquals(3, print.getCopies()); - assertEquals(true, print.getLandscape()); - - XSSFSheet s2 = wb.createSheet(); - assertEquals(false, s2.getCTWorksheet().isSetPageSetup()); - assertEquals(true, s2.getCTWorksheet().isSetPageMargins()); - - // Round trip and check - XSSFWorkbook wbBack = XSSFITestDataProvider.instance.writeOutAndReadBack(wb); - - s1 = wbBack.getSheetAt(0); - s2 = wbBack.getSheetAt(1); - - assertEquals(true, s1.getCTWorksheet().isSetPageSetup()); - assertEquals(true, s1.getCTWorksheet().isSetPageMargins()); - assertEquals(false, s2.getCTWorksheet().isSetPageSetup()); - assertEquals(true, s2.getCTWorksheet().isSetPageMargins()); - - print = s1.getPrintSetup(); - assertEquals(3, print.getCopies()); - assertEquals(true, print.getLandscape()); - - wb.close(); - } - - /** - * Open a file with print settings, save and check. - * Then, change, save, read, check - */ - public void testRoundTrip() { - // TODO - } - - @Test - public void testSetLandscapeFalse() throws Exception { - XSSFPrintSetup ps = new XSSFPrintSetup(CTWorksheet.Factory.newInstance()); - - assertFalse(ps.getLandscape()); - - ps.setLandscape(true); - assertTrue(ps.getLandscape()); - - ps.setLandscape(false); - assertFalse(ps.getLandscape()); - } - - @Test - public void testSetLeftToRight() throws Exception { - XSSFPrintSetup ps = new XSSFPrintSetup(CTWorksheet.Factory.newInstance()); - - assertFalse(ps.getLeftToRight()); - - ps.setLeftToRight(true); - assertTrue(ps.getLeftToRight()); - - ps.setLeftToRight(false); - assertFalse(ps.getLeftToRight()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java deleted file mode 100644 index 9adc5312f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java +++ /dev/null @@ -1,542 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.StylesTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXstring; - -import java.io.IOException; -import java.util.TreeMap; - -/** - * Tests functionality of the XSSFRichTextRun object - * - * @author Yegor Kozlov - */ -public final class TestXSSFRichTextString extends TestCase { - - public void testCreate() { - XSSFRichTextString rt = new XSSFRichTextString("Apache POI"); - assertEquals("Apache POI", rt.getString()); - assertEquals(false, rt.hasFormatting()); - - CTRst st = rt.getCTRst(); - assertTrue(st.isSetT()); - assertEquals("Apache POI", st.getT()); - assertEquals(false, rt.hasFormatting()); - - rt.append(" is cool stuff"); - assertEquals(2, st.sizeOfRArray()); - assertFalse(st.isSetT()); - - assertEquals("Apache POI is cool stuff", rt.getString()); - assertEquals(false, rt.hasFormatting()); - } - - public void testEmpty() { - XSSFRichTextString rt = new XSSFRichTextString(); - assertEquals(0, rt.getIndexOfFormattingRun(9999)); - assertEquals(-1, rt.getLengthOfFormattingRun(9999)); - assertNull(rt.getFontAtIndex(9999)); - } - - public void testApplyFont() { - XSSFRichTextString rt = new XSSFRichTextString(); - rt.append("123"); - rt.append("4567"); - rt.append("89"); - - assertEquals("123456789", rt.getString()); - assertEquals(false, rt.hasFormatting()); - - XSSFFont font1 = new XSSFFont(); - font1.setBold(true); - - rt.applyFont(2, 5, font1); - assertEquals(true, rt.hasFormatting()); - - assertEquals(4, rt.numFormattingRuns()); - assertEquals(0, rt.getIndexOfFormattingRun(0)); - assertEquals("12", rt.getCTRst().getRArray(0).getT()); - - assertEquals(2, rt.getIndexOfFormattingRun(1)); - assertEquals("345", rt.getCTRst().getRArray(1).getT()); - - assertEquals(5, rt.getIndexOfFormattingRun(2)); - assertEquals(2, rt.getLengthOfFormattingRun(2)); - assertEquals("67", rt.getCTRst().getRArray(2).getT()); - - assertEquals(7, rt.getIndexOfFormattingRun(3)); - assertEquals(2, rt.getLengthOfFormattingRun(3)); - assertEquals("89", rt.getCTRst().getRArray(3).getT()); - - - assertEquals(-1, rt.getIndexOfFormattingRun(9999)); - assertEquals(-1, rt.getLengthOfFormattingRun(9999)); - assertNull(rt.getFontAtIndex(9999)); - } - - public void testApplyFontIndex() { - XSSFRichTextString rt = new XSSFRichTextString("Apache POI"); - rt.applyFont(0, 10, (short)1); - - rt.applyFont((short)1); - - assertNotNull(rt.getFontAtIndex(0)); - } - - public void testApplyFontWithStyles() { - XSSFRichTextString rt = new XSSFRichTextString("Apache POI"); - - StylesTable tbl = new StylesTable(); - rt.setStylesTableReference(tbl); - - try { - rt.applyFont(0, 10, (short)1); - fail("Fails without styles in the table"); - } catch (IndexOutOfBoundsException e) { - // expected - } - - tbl.putFont(new XSSFFont()); - rt.applyFont(0, 10, (short)1); - rt.applyFont((short)1); - } - - public void testApplyFontException() { - XSSFRichTextString rt = new XSSFRichTextString("Apache POI"); - - rt.applyFont(0, 0, (short)1); - - try { - rt.applyFont(11, 10, (short)1); - fail("Should catch Exception here"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("11")); - } - - try { - rt.applyFont(-1, 10, (short)1); - fail("Should catch Exception here"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("-1")); - } - - try { - rt.applyFont(0, 555, (short)1); - fail("Should catch Exception here"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("555")); - } - } - - public void testClearFormatting() { - - XSSFRichTextString rt = new XSSFRichTextString("Apache POI"); - assertEquals("Apache POI", rt.getString()); - assertEquals(false, rt.hasFormatting()); - - rt.clearFormatting(); - - CTRst st = rt.getCTRst(); - assertTrue(st.isSetT()); - assertEquals("Apache POI", rt.getString()); - assertEquals(0, rt.numFormattingRuns()); - assertEquals(false, rt.hasFormatting()); - - XSSFFont font = new XSSFFont(); - font.setBold(true); - - rt.applyFont(7, 10, font); - assertEquals(2, rt.numFormattingRuns()); - assertEquals(true, rt.hasFormatting()); - - rt.clearFormatting(); - - assertEquals("Apache POI", rt.getString()); - assertEquals(0, rt.numFormattingRuns()); - assertEquals(false, rt.hasFormatting()); - } - - public void testGetFonts() { - - XSSFRichTextString rt = new XSSFRichTextString(); - - XSSFFont font1 = new XSSFFont(); - font1.setFontName("Arial"); - font1.setItalic(true); - rt.append("The quick", font1); - - XSSFFont font1$ = rt.getFontOfFormattingRun(0); - assertEquals(font1.getItalic(), font1$.getItalic()); - assertEquals(font1.getFontName(), font1$.getFontName()); - - XSSFFont font2 = new XSSFFont(); - font2.setFontName("Courier"); - font2.setBold(true); - rt.append(" brown fox", font2); - - XSSFFont font2$ = rt.getFontOfFormattingRun(1); - assertEquals(font2.getBold(), font2$.getBold()); - assertEquals(font2.getFontName(), font2$.getFontName()); - } - - /** - * make sure we insert xml:space="preserve" attribute - * if a string has leading or trailing white spaces - */ - public void testPreserveSpaces() { - XSSFRichTextString rt = new XSSFRichTextString("Apache"); - CTRst ct = rt.getCTRst(); - STXstring xs = ct.xgetT(); - assertEquals("Apache", xs.xmlText()); - rt.setString(" Apache"); - assertEquals(" Apache", xs.xmlText()); - - rt.append(" POI"); - rt.append(" "); - assertEquals(" Apache POI ", rt.getString()); - assertEquals(" Apache", rt.getCTRst().getRArray(0).xgetT().xmlText()); - assertEquals(" POI", rt.getCTRst().getRArray(1).xgetT().xmlText()); - assertEquals(" ", rt.getCTRst().getRArray(2).xgetT().xmlText()); - } - - /** - * test that unicode representation_ xHHHH_ is properly processed - */ - public void testUtfDecode() throws IOException { - CTRst st = CTRst.Factory.newInstance(); - st.setT("abc_x000D_2ef_x000D_"); - XSSFRichTextString rt = new XSSFRichTextString(st); - //_x000D_ is converted into carriage return - assertEquals("abc\r2ef\r", rt.getString()); - - // Test Lowercase case - CTRst st2 = CTRst.Factory.newInstance(); - st2.setT("abc_x000d_2ef_x000d_"); - XSSFRichTextString rt2 = new XSSFRichTextString(st2); - assertEquals("abc\r2ef\r", rt2.getString()); - } - - public void testApplyFont_lowlevel(){ - CTRst st = CTRst.Factory.newInstance(); - String text = "Apache Software Foundation"; - XSSFRichTextString str = new XSSFRichTextString(text); - assertEquals(26, text.length()); - - st.addNewR().setT(text); - - TreeMap formats = str.getFormatMap(st); - assertEquals(1, formats.size()); - assertEquals(26, (int)formats.firstKey()); - assertNull(formats.get( formats.firstKey() )); - - CTRPrElt fmt1 = CTRPrElt.Factory.newInstance(); - str.applyFont(formats, 0, 6, fmt1); - assertEquals(2, formats.size()); - assertEquals("[6, 26]", formats.keySet().toString()); - Object[] runs1 = formats.values().toArray(); - assertSame(fmt1, runs1[0]); - assertSame(null, runs1[1]); - - CTRPrElt fmt2 = CTRPrElt.Factory.newInstance(); - str.applyFont(formats, 7, 15, fmt2); - assertEquals(4, formats.size()); - assertEquals("[6, 7, 15, 26]", formats.keySet().toString()); - Object[] runs2 = formats.values().toArray(); - assertSame(fmt1, runs2[0]); - assertSame(null, runs2[1]); - assertSame(fmt2, runs2[2]); - assertSame(null, runs2[3]); - - CTRPrElt fmt3 = CTRPrElt.Factory.newInstance(); - str.applyFont(formats, 6, 7, fmt3); - assertEquals(4, formats.size()); - assertEquals("[6, 7, 15, 26]", formats.keySet().toString()); - Object[] runs3 = formats.values().toArray(); - assertSame(fmt1, runs3[0]); - assertSame(fmt3, runs3[1]); - assertSame(fmt2, runs3[2]); - assertSame(null, runs3[3]); - - CTRPrElt fmt4 = CTRPrElt.Factory.newInstance(); - str.applyFont(formats, 0, 7, fmt4); - assertEquals(3, formats.size()); - assertEquals("[7, 15, 26]", formats.keySet().toString()); - Object[] runs4 = formats.values().toArray(); - assertSame(fmt4, runs4[0]); - assertSame(fmt2, runs4[1]); - assertSame(null, runs4[2]); - - CTRPrElt fmt5 = CTRPrElt.Factory.newInstance(); - str.applyFont(formats, 0, 26, fmt5); - assertEquals(1, formats.size()); - assertEquals("[26]", formats.keySet().toString()); - Object[] runs5 = formats.values().toArray(); - assertSame(fmt5, runs5[0]); - - CTRPrElt fmt6 = CTRPrElt.Factory.newInstance(); - str.applyFont(formats, 15, 26, fmt6); - assertEquals(2, formats.size()); - assertEquals("[15, 26]", formats.keySet().toString()); - Object[] runs6 = formats.values().toArray(); - assertSame(fmt5, runs6[0]); - assertSame(fmt6, runs6[1]); - - str.applyFont(formats, 0, 26, null); - assertEquals(1, formats.size()); - assertEquals("[26]", formats.keySet().toString()); - Object[] runs7 = formats.values().toArray(); - assertSame(null, runs7[0]); - - str.applyFont(formats, 15, 26, fmt6); - assertEquals(2, formats.size()); - assertEquals("[15, 26]", formats.keySet().toString()); - Object[] runs8 = formats.values().toArray(); - assertSame(null, runs8[0]); - assertSame(fmt6, runs8[1]); - - str.applyFont(formats, 15, 26, fmt5); - assertEquals(2, formats.size()); - assertEquals("[15, 26]", formats.keySet().toString()); - Object[] runs9 = formats.values().toArray(); - assertSame(null, runs9[0]); - assertSame(fmt5, runs9[1]); - - str.applyFont(formats, 2, 20, fmt6); - assertEquals(3, formats.size()); - assertEquals("[2, 20, 26]", formats.keySet().toString()); - Object[] runs10 = formats.values().toArray(); - assertSame(null, runs10[0]); - assertSame(fmt6, runs10[1]); - assertSame(fmt5, runs10[2]); - - str.applyFont(formats, 22, 24, fmt4); - assertEquals(5, formats.size()); - assertEquals("[2, 20, 22, 24, 26]", formats.keySet().toString()); - Object[] runs11 = formats.values().toArray(); - assertSame(null, runs11[0]); - assertSame(fmt6, runs11[1]); - assertSame(fmt5, runs11[2]); - assertSame(fmt4, runs11[3]); - assertSame(fmt5, runs11[4]); - - str.applyFont(formats, 0, 10, fmt1); - assertEquals(5, formats.size()); - assertEquals("[10, 20, 22, 24, 26]", formats.keySet().toString()); - Object[] runs12 = formats.values().toArray(); - assertSame(fmt1, runs12[0]); - assertSame(fmt6, runs12[1]); - assertSame(fmt5, runs12[2]); - assertSame(fmt4, runs12[3]); - assertSame(fmt5, runs12[4]); - } - - public void testApplyFont_usermodel(){ - String text = "Apache Software Foundation"; - XSSFRichTextString str = new XSSFRichTextString(text); - XSSFFont font1 = new XSSFFont(); - XSSFFont font2 = new XSSFFont(); - XSSFFont font3 = new XSSFFont(); - str.applyFont(font1); - assertEquals(1, str.numFormattingRuns()); - - str.applyFont(0, 6, font1); - str.applyFont(6, text.length(), font2); - assertEquals(2, str.numFormattingRuns()); - assertEquals("Apache", str.getCTRst().getRArray(0).getT()); - assertEquals(" Software Foundation", str.getCTRst().getRArray(1).getT()); - - str.applyFont(15, 26, font3); - assertEquals(3, str.numFormattingRuns()); - assertEquals("Apache", str.getCTRst().getRArray(0).getT()); - assertEquals(" Software", str.getCTRst().getRArray(1).getT()); - assertEquals(" Foundation", str.getCTRst().getRArray(2).getT()); - - str.applyFont(6, text.length(), font2); - assertEquals(2, str.numFormattingRuns()); - assertEquals("Apache", str.getCTRst().getRArray(0).getT()); - assertEquals(" Software Foundation", str.getCTRst().getRArray(1).getT()); - } - - public void testLineBreaks_bug48877() throws IOException{ - - XSSFFont font = new XSSFFont(); - //noinspection deprecation - font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD); - font.setFontHeightInPoints((short) 14); - XSSFRichTextString str; - STXstring t1, t2, t3; - - str = new XSSFRichTextString("Incorrect\nLine-Breaking"); - str.applyFont(0, 8, font); - t1 = str.getCTRst().getRArray(0).xgetT(); - t2 = str.getCTRst().getRArray(1).xgetT(); - assertEquals("Incorrec", t1.xmlText()); - assertEquals("t\nLine-Breaking", t2.xmlText()); - - str = new XSSFRichTextString("Incorrect\nLine-Breaking"); - str.applyFont(0, 9, font); - t1 = str.getCTRst().getRArray(0).xgetT(); - t2 = str.getCTRst().getRArray(1).xgetT(); - assertEquals("Incorrect", t1.xmlText()); - assertEquals("\nLine-Breaking", t2.xmlText()); - - str = new XSSFRichTextString("Incorrect\n Line-Breaking"); - str.applyFont(0, 9, font); - t1 = str.getCTRst().getRArray(0).xgetT(); - t2 = str.getCTRst().getRArray(1).xgetT(); - assertEquals("Incorrect", t1.xmlText()); - assertEquals("\n Line-Breaking", t2.xmlText()); - - str = new XSSFRichTextString("Tab\tseparated\n"); - t1 = str.getCTRst().xgetT(); - // trailing \n causes must be preserved - assertEquals("Tab\tseparated\n", t1.xmlText()); - - str.applyFont(0, 3, font); - t1 = str.getCTRst().getRArray(0).xgetT(); - t2 = str.getCTRst().getRArray(1).xgetT(); - assertEquals("Tab", t1.xmlText()); - assertEquals("\tseparated\n", t2.xmlText()); - - str = new XSSFRichTextString("Tab\tseparated\n"); - str.applyFont(0, 4, font); - t1 = str.getCTRst().getRArray(0).xgetT(); - t2 = str.getCTRst().getRArray(1).xgetT(); - assertEquals("Tab\t", t1.xmlText()); - assertEquals("separated\n", t2.xmlText()); - - str = new XSSFRichTextString("\n\n\nNew Line\n\n"); - str.applyFont(0, 3, font); - str.applyFont(11, 13, font); - t1 = str.getCTRst().getRArray(0).xgetT(); - t2 = str.getCTRst().getRArray(1).xgetT(); - t3 = str.getCTRst().getRArray(2).xgetT(); - // YK: don't know why, but XmlBeans converts leading tab characters to spaces - assertEquals("\n\n\n", t1.xmlText()); - assertEquals("New Line", t2.xmlText()); - assertEquals("\n\n", t3.xmlText()); - } - - public void testBug56511() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56511.xlsx"); - for (Sheet sheet : wb) { - int lastRow = sheet.getLastRowNum(); - for (int rowIdx = sheet.getFirstRowNum(); rowIdx <= lastRow; rowIdx++) { - Row row = sheet.getRow(rowIdx); - if(row != null) { - int lastCell = row.getLastCellNum(); - - for (int cellIdx = row.getFirstCellNum(); cellIdx <= lastCell; cellIdx++) { - - Cell cell = row.getCell(cellIdx); - if (cell != null) { - //System.out.println("row " + rowIdx + " column " + cellIdx + ": " + cell.getCellType() + ": " + cell.toString()); - - XSSFRichTextString richText = (XSSFRichTextString) cell.getRichStringCellValue(); - int anzFormattingRuns = richText.numFormattingRuns(); - for (int run = 0; run < anzFormattingRuns; run++) { - /*XSSFFont font =*/ richText.getFontOfFormattingRun(run); - //System.out.println(" run " + run - // + " font " + (font == null ? "" : font.getFontName())); - } - } - } - } - } - } - } - - public void testBug56511_values() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56511.xlsx"); - Sheet sheet = wb.getSheetAt(0); - Row row = sheet.getRow(0); - - // verify the values to ensure future changes keep the returned information equal - XSSFRichTextString rt = (XSSFRichTextString) row.getCell(0).getRichStringCellValue(); - assertEquals(0, rt.numFormattingRuns()); - assertNull(rt.getFontOfFormattingRun(0)); - assertEquals(-1, rt.getLengthOfFormattingRun(0)); - - rt = (XSSFRichTextString) row.getCell(1).getRichStringCellValue(); - assertEquals(0, row.getCell(1).getRichStringCellValue().numFormattingRuns()); - assertNull(rt.getFontOfFormattingRun(1)); - assertEquals(-1, rt.getLengthOfFormattingRun(1)); - - rt = (XSSFRichTextString) row.getCell(2).getRichStringCellValue(); - assertEquals(2, rt.numFormattingRuns()); - assertNotNull(rt.getFontOfFormattingRun(0)); - assertEquals(4, rt.getLengthOfFormattingRun(0)); - - assertNotNull(rt.getFontOfFormattingRun(1)); - assertEquals(9, rt.getLengthOfFormattingRun(1)); - - assertNull(rt.getFontOfFormattingRun(2)); - - rt = (XSSFRichTextString) row.getCell(3).getRichStringCellValue(); - assertEquals(3, rt.numFormattingRuns()); - assertNull(rt.getFontOfFormattingRun(0)); - assertEquals(1, rt.getLengthOfFormattingRun(0)); - - assertNotNull(rt.getFontOfFormattingRun(1)); - assertEquals(3, rt.getLengthOfFormattingRun(1)); - - assertNotNull(rt.getFontOfFormattingRun(2)); - assertEquals(9, rt.getLengthOfFormattingRun(2)); - } - - public void testToString() { - XSSFRichTextString rt = new XSSFRichTextString("Apache POI"); - assertNotNull(rt.toString()); - - // TODO: normally toString() should never return null, should we adjust this? - rt = new XSSFRichTextString(); - assertNull(rt.toString()); - } - - public void test59008Font() { - XSSFFont font = new XSSFFont(CTFont.Factory.newInstance()); - - XSSFRichTextString rts = new XSSFRichTextString(); - rts.append("This is correct "); - int s1 = rts.length(); - rts.append("This is Bold Red", font); - int s2 = rts.length(); - rts.append(" This uses the default font rather than the cell style font"); - int s3 = rts.length(); - - assertEquals("", rts.getFontAtIndex(s1-1).toString()); - assertEquals(font, rts.getFontAtIndex(s2-1)); - assertEquals("", rts.getFontAtIndex(s3-1).toString()); - } - - public void test60289UtfDecode() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("60289.xlsx"); - assertEquals("Rich Text\r\nTest", wb.getSheetAt(0).getRow(1).getCell(1).getRichStringCellValue().getString()); - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java deleted file mode 100644 index 6b49d81c9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java +++ /dev/null @@ -1,196 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestXRow; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellCopyPolicy; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.junit.Test; - -/** - * Tests for XSSFRow - */ -public final class TestXSSFRow extends BaseTestXRow { - - public TestXSSFRow() { - super(XSSFITestDataProvider.instance); - } - - @Test - public void testCopyRowFrom() throws IOException { - final XSSFWorkbook workbook = new XSSFWorkbook(); - final XSSFSheet sheet = workbook.createSheet("test"); - final XSSFRow srcRow = sheet.createRow(0); - srcRow.createCell(0).setCellValue("Hello"); - final XSSFRow destRow = sheet.createRow(1); - - destRow.copyRowFrom(srcRow, new CellCopyPolicy()); - assertNotNull(destRow.getCell(0)); - assertEquals("Hello", destRow.getCell(0).getStringCellValue()); - - workbook.close(); - } - - @Test - public void testCopyRowFromExternalSheet() throws IOException { - final XSSFWorkbook workbook = new XSSFWorkbook(); - final Sheet srcSheet = workbook.createSheet("src"); - final XSSFSheet destSheet = workbook.createSheet("dest"); - workbook.createSheet("other"); - - final Row srcRow = srcSheet.createRow(0); - int col = 0; - //Test 2D and 3D Ref Ptgs (Pxg for OOXML Workbooks) - srcRow.createCell(col++).setCellFormula("B5"); - srcRow.createCell(col++).setCellFormula("src!B5"); - srcRow.createCell(col++).setCellFormula("dest!B5"); - srcRow.createCell(col++).setCellFormula("other!B5"); - - //Test 2D and 3D Ref Ptgs with absolute row - srcRow.createCell(col++).setCellFormula("B$5"); - srcRow.createCell(col++).setCellFormula("src!B$5"); - srcRow.createCell(col++).setCellFormula("dest!B$5"); - srcRow.createCell(col++).setCellFormula("other!B$5"); - - //Test 2D and 3D Area Ptgs (Pxg for OOXML Workbooks) - srcRow.createCell(col++).setCellFormula("SUM(B5:D$5)"); - srcRow.createCell(col++).setCellFormula("SUM(src!B5:D$5)"); - srcRow.createCell(col++).setCellFormula("SUM(dest!B5:D$5)"); - srcRow.createCell(col++).setCellFormula("SUM(other!B5:D$5)"); - - ////////////////// - - final XSSFRow destRow = destSheet.createRow(1); - destRow.copyRowFrom(srcRow, new CellCopyPolicy()); - - ////////////////// - - //Test 2D and 3D Ref Ptgs (Pxg for OOXML Workbooks) - col = 0; - Cell cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("RefPtg", "B6", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Ref3DPtg", "src!B6", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Ref3DPtg", "dest!B6", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Ref3DPtg", "other!B6", cell.getCellFormula()); - - ///////////////////////////////////////////// - - //Test 2D and 3D Ref Ptgs with absolute row (Ptg row number shouldn't change) - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("RefPtg", "B$5", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Ref3DPtg", "src!B$5", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Ref3DPtg", "dest!B$5", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Ref3DPtg", "other!B$5", cell.getCellFormula()); - - ////////////////////////////////////////// - - //Test 2D and 3D Area Ptgs (Pxg for OOXML Workbooks) - // Note: absolute row changes from last cell to first cell in order - // to maintain topLeft:bottomRight order - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Area2DPtg", "SUM(B$5:D6)", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(cell); - assertEquals("Area3DPtg", "SUM(src!B$5:D6)", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(destRow.getCell(6)); - assertEquals("Area3DPtg", "SUM(dest!B$5:D6)", cell.getCellFormula()); - - cell = destRow.getCell(col++); - assertNotNull(destRow.getCell(7)); - assertEquals("Area3DPtg", "SUM(other!B$5:D6)", cell.getCellFormula()); - - workbook.close(); - } - - @Test - public void testCopyRowOverwritesExistingRow() throws IOException { - final XSSFWorkbook workbook = new XSSFWorkbook(); - final XSSFSheet sheet1 = workbook.createSheet("Sheet1"); - final Sheet sheet2 = workbook.createSheet("Sheet2"); - - final Row srcRow = sheet1.createRow(0); - final XSSFRow destRow = sheet1.createRow(1); - final Row observerRow = sheet1.createRow(2); - final Row externObserverRow = sheet2.createRow(0); - - srcRow.createCell(0).setCellValue("hello"); - srcRow.createCell(1).setCellValue("world"); - destRow.createCell(0).setCellValue(5.0); //A2 -> 5.0 - destRow.createCell(1).setCellFormula("A1"); // B2 -> A1 -> "hello" - observerRow.createCell(0).setCellFormula("A2"); // A3 -> A2 -> 5.0 - observerRow.createCell(1).setCellFormula("B2"); // B3 -> B2 -> A1 -> "hello" - externObserverRow.createCell(0).setCellFormula("Sheet1!A2"); //Sheet2!A1 -> Sheet1!A2 -> 5.0 - - // overwrite existing destRow with row-copy of srcRow - destRow.copyRowFrom(srcRow, new CellCopyPolicy()); - - // copyRowFrom should update existing destRow, rather than creating a new row and reassigning the destRow pointer - // to the new row (and allow the old row to be garbage collected) - // this is mostly so existing references to rows that are overwritten are updated - // rather than allowing users to continue updating rows that are no longer part of the sheet - assertSame("existing references to srcRow are still valid", srcRow, sheet1.getRow(0)); - assertSame("existing references to destRow are still valid", destRow, sheet1.getRow(1)); - assertSame("existing references to observerRow are still valid", observerRow, sheet1.getRow(2)); - assertSame("existing references to externObserverRow are still valid", externObserverRow, sheet2.getRow(0)); - - // Make sure copyRowFrom actually copied row (this is tested elsewhere) - assertEquals(CellType.STRING, destRow.getCell(0).getCellTypeEnum()); - assertEquals("hello", destRow.getCell(0).getStringCellValue()); - - // We don't want #REF! errors if we copy a row that contains cells that are referred to by other cells outside of copied region - assertEquals("references to overwritten cells are unmodified", "A2", observerRow.getCell(0).getCellFormula()); - assertEquals("references to overwritten cells are unmodified", "B2", observerRow.getCell(1).getCellFormula()); - assertEquals("references to overwritten cells are unmodified", "Sheet1!A2", externObserverRow.getCell(0).getCellFormula()); - - workbook.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java deleted file mode 100644 index 24c1d7237..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ /dev/null @@ -1,2040 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook; -import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.POIXMLException; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.AutoFilter; -import org.apache.poi.ss.usermodel.BaseTestXSheet; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellCopyPolicy; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.FormulaError; -import org.apache.poi.ss.usermodel.IgnoredErrorType; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.CellUtil; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.CalculationChain; -import org.apache.poi.xssf.model.CommentsTable; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIgnoredError; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnsignedShortHex; - - -public final class TestXSSFSheet extends BaseTestXSheet { - - public TestXSSFSheet() { - super(XSSFITestDataProvider.instance); - } - - //TODO column styles are not yet supported by XSSF - @Override - @Test - public void defaultColumnStyle() { - //super.defaultColumnStyle(); - } - - @Test - public void getSetMargin() throws IOException { - baseTestGetSetMargin(new double[]{0.7, 0.7, 0.75, 0.75, 0.3, 0.3}); - } - - @Test - public void existingHeaderFooter() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("45540_classic_Header.xlsx"); - XSSFOddHeader hdr; - XSSFOddFooter ftr; - - // Sheet 1 has a header with center and right text - XSSFSheet s1 = wb1.getSheetAt(0); - assertNotNull(s1.getHeader()); - assertNotNull(s1.getFooter()); - hdr = (XSSFOddHeader) s1.getHeader(); - ftr = (XSSFOddFooter) s1.getFooter(); - - assertEquals("&Ctestdoc&Rtest phrase", hdr.getText()); - assertEquals(null, ftr.getText()); - - assertEquals("", hdr.getLeft()); - assertEquals("testdoc", hdr.getCenter()); - assertEquals("test phrase", hdr.getRight()); - - assertEquals("", ftr.getLeft()); - assertEquals("", ftr.getCenter()); - assertEquals("", ftr.getRight()); - - // Sheet 2 has a footer, but it's empty - XSSFSheet s2 = wb1.getSheetAt(1); - assertNotNull(s2.getHeader()); - assertNotNull(s2.getFooter()); - hdr = (XSSFOddHeader) s2.getHeader(); - ftr = (XSSFOddFooter) s2.getFooter(); - - assertEquals(null, hdr.getText()); - assertEquals("&L&F", ftr.getText()); - - assertEquals("", hdr.getLeft()); - assertEquals("", hdr.getCenter()); - assertEquals("", hdr.getRight()); - - assertEquals("&F", ftr.getLeft()); - assertEquals("", ftr.getCenter()); - assertEquals("", ftr.getRight()); - - // Save and reload - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - - hdr = (XSSFOddHeader) wb2.getSheetAt(0).getHeader(); - ftr = (XSSFOddFooter) wb2.getSheetAt(0).getFooter(); - - assertEquals("", hdr.getLeft()); - assertEquals("testdoc", hdr.getCenter()); - assertEquals("test phrase", hdr.getRight()); - - assertEquals("", ftr.getLeft()); - assertEquals("", ftr.getCenter()); - assertEquals("", ftr.getRight()); - - wb2.close(); - } - - @Test - public void getAllHeadersFooters() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet("Sheet 1"); - assertNotNull(sheet.getOddFooter()); - assertNotNull(sheet.getEvenFooter()); - assertNotNull(sheet.getFirstFooter()); - assertNotNull(sheet.getOddHeader()); - assertNotNull(sheet.getEvenHeader()); - assertNotNull(sheet.getFirstHeader()); - - assertEquals("", sheet.getOddFooter().getLeft()); - sheet.getOddFooter().setLeft("odd footer left"); - assertEquals("odd footer left", sheet.getOddFooter().getLeft()); - - assertEquals("", sheet.getEvenFooter().getLeft()); - sheet.getEvenFooter().setLeft("even footer left"); - assertEquals("even footer left", sheet.getEvenFooter().getLeft()); - - assertEquals("", sheet.getFirstFooter().getLeft()); - sheet.getFirstFooter().setLeft("first footer left"); - assertEquals("first footer left", sheet.getFirstFooter().getLeft()); - - assertEquals("", sheet.getOddHeader().getLeft()); - sheet.getOddHeader().setLeft("odd header left"); - assertEquals("odd header left", sheet.getOddHeader().getLeft()); - - assertEquals("", sheet.getOddHeader().getRight()); - sheet.getOddHeader().setRight("odd header right"); - assertEquals("odd header right", sheet.getOddHeader().getRight()); - - assertEquals("", sheet.getOddHeader().getCenter()); - sheet.getOddHeader().setCenter("odd header center"); - assertEquals("odd header center", sheet.getOddHeader().getCenter()); - - // Defaults are odd - assertEquals("odd footer left", sheet.getFooter().getLeft()); - assertEquals("odd header center", sheet.getHeader().getCenter()); - - workbook.close(); - } - - @Test - public void autoSizeColumn() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet("Sheet 1"); - sheet.createRow(0).createCell(13).setCellValue("test"); - - sheet.autoSizeColumn(13); - - ColumnHelper columnHelper = sheet.getColumnHelper(); - CTCol col = columnHelper.getColumn(13, false); - assertTrue(col.getBestFit()); - workbook.close(); - } - - - @Test - public void setCellComment() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - - XSSFDrawing dg = sheet.createDrawingPatriarch(); - XSSFComment comment = dg.createCellComment(new XSSFClientAnchor()); - - Cell cell = sheet.createRow(0).createCell(0); - CommentsTable comments = sheet.getCommentsTable(false); - CTComments ctComments = comments.getCTComments(); - - cell.setCellComment(comment); - assertEquals("A1", ctComments.getCommentList().getCommentArray(0).getRef()); - comment.setAuthor("test A1 author"); - assertEquals("test A1 author", comments.getAuthor((int) ctComments.getCommentList().getCommentArray(0).getAuthorId())); - workbook.close(); - } - - @Test - public void getActiveCell() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CellAddress R5 = new CellAddress("R5"); - sheet.setActiveCell(R5); - - assertEquals(R5, sheet.getActiveCell()); - workbook.close(); - } - - @Test - public void createFreezePane_XSSF() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CTWorksheet ctWorksheet = sheet.getCTWorksheet(); - - sheet.createFreezePane(2, 4); - assertEquals(2.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getXSplit(), 0.0); - assertEquals(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane()); - sheet.createFreezePane(3, 6, 10, 10); - assertEquals(3.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getXSplit(), 0.0); - // assertEquals(10, sheet.getTopRow()); - // assertEquals(10, sheet.getLeftCol()); - sheet.createSplitPane(4, 8, 12, 12, 1); - assertEquals(8.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getYSplit(), 0.0); - assertEquals(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane()); - - workbook.close(); - } - - @Test - public void removeMergedRegion_lowlevel() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CTWorksheet ctWorksheet = sheet.getCTWorksheet(); - CellRangeAddress region_1 = CellRangeAddress.valueOf("A1:B2"); - CellRangeAddress region_2 = CellRangeAddress.valueOf("C3:D4"); - CellRangeAddress region_3 = CellRangeAddress.valueOf("E5:F6"); - CellRangeAddress region_4 = CellRangeAddress.valueOf("G7:H8"); - sheet.addMergedRegion(region_1); - sheet.addMergedRegion(region_2); - sheet.addMergedRegion(region_3); - assertEquals("C3:D4", ctWorksheet.getMergeCells().getMergeCellArray(1).getRef()); - assertEquals(3, sheet.getNumMergedRegions()); - sheet.removeMergedRegion(1); - assertEquals("E5:F6", ctWorksheet.getMergeCells().getMergeCellArray(1).getRef()); - assertEquals(2, sheet.getNumMergedRegions()); - sheet.removeMergedRegion(1); - sheet.removeMergedRegion(0); - assertEquals(0, sheet.getNumMergedRegions()); - assertNull(" CTMergeCells should be deleted after removing the last merged " + - "region on the sheet.", sheet.getCTWorksheet().getMergeCells()); - sheet.addMergedRegion(region_1); - sheet.addMergedRegion(region_2); - sheet.addMergedRegion(region_3); - sheet.addMergedRegion(region_4); - // test invalid indexes OOBE - Set rmIdx = new HashSet(Arrays.asList(5,6)); - sheet.removeMergedRegions(rmIdx); - rmIdx = new HashSet(Arrays.asList(1,3)); - sheet.removeMergedRegions(rmIdx); - assertEquals("A1:B2", ctWorksheet.getMergeCells().getMergeCellArray(0).getRef()); - assertEquals("E5:F6", ctWorksheet.getMergeCells().getMergeCellArray(1).getRef()); - workbook.close(); - } - - @Test - public void setDefaultColumnStyle() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CTWorksheet ctWorksheet = sheet.getCTWorksheet(); - StylesTable stylesTable = workbook.getStylesSource(); - XSSFFont font = new XSSFFont(); - font.setFontName("Cambria"); - stylesTable.putFont(font); - CTXf cellStyleXf = CTXf.Factory.newInstance(); - cellStyleXf.setFontId(1); - cellStyleXf.setFillId(0); - cellStyleXf.setBorderId(0); - cellStyleXf.setNumFmtId(0); - stylesTable.putCellStyleXf(cellStyleXf); - CTXf cellXf = CTXf.Factory.newInstance(); - cellXf.setXfId(1); - stylesTable.putCellXf(cellXf); - XSSFCellStyle cellStyle = new XSSFCellStyle(1, 1, stylesTable, null); - assertEquals(1, cellStyle.getFontIndex()); - - sheet.setDefaultColumnStyle(3, cellStyle); - assertEquals(1, ctWorksheet.getColsArray(0).getColArray(0).getStyle()); - workbook.close(); - } - - - @Test - public void groupUngroupColumn() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - - //one level - sheet.groupColumn(2, 7); - sheet.groupColumn(10, 11); - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - assertEquals(2, cols.sizeOfColArray()); - CTCol[] colArray = cols.getColArray(); - assertNotNull(colArray); - assertEquals(2 + 1, colArray[0].getMin()); // 1 based - assertEquals(7 + 1, colArray[0].getMax()); // 1 based - assertEquals(1, colArray[0].getOutlineLevel()); - assertEquals(0, sheet.getColumnOutlineLevel(0)); - - //two level - sheet.groupColumn(1, 2); - cols = sheet.getCTWorksheet().getColsArray(0); - assertEquals(4, cols.sizeOfColArray()); - colArray = cols.getColArray(); - assertEquals(2, colArray[1].getOutlineLevel()); - - //three level - sheet.groupColumn(6, 8); - sheet.groupColumn(2, 3); - cols = sheet.getCTWorksheet().getColsArray(0); - assertEquals(7, cols.sizeOfColArray()); - colArray = cols.getColArray(); - assertEquals(3, colArray[1].getOutlineLevel()); - assertEquals(3, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelCol()); - - sheet.ungroupColumn(8, 10); - colArray = cols.getColArray(); - //assertEquals(3, colArray[1].getOutlineLevel()); - - sheet.ungroupColumn(4, 6); - sheet.ungroupColumn(2, 2); - colArray = cols.getColArray(); - assertEquals(4, colArray.length); - assertEquals(2, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelCol()); - - workbook.close(); - } - - @Test - public void groupUngroupRow() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - - //one level - sheet.groupRow(9, 10); - assertEquals(2, sheet.getPhysicalNumberOfRows()); - CTRow ctrow = sheet.getRow(9).getCTRow(); - - assertNotNull(ctrow); - assertEquals(10, ctrow.getR()); - assertEquals(1, ctrow.getOutlineLevel()); - assertEquals(1, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelRow()); - - //two level - sheet.groupRow(10, 13); - assertEquals(5, sheet.getPhysicalNumberOfRows()); - ctrow = sheet.getRow(10).getCTRow(); - assertNotNull(ctrow); - assertEquals(11, ctrow.getR()); - assertEquals(2, ctrow.getOutlineLevel()); - assertEquals(2, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelRow()); - - - sheet.ungroupRow(8, 10); - assertEquals(4, sheet.getPhysicalNumberOfRows()); - assertEquals(1, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelRow()); - - sheet.ungroupRow(10, 10); - assertEquals(3, sheet.getPhysicalNumberOfRows()); - - assertEquals(1, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelRow()); - - workbook.close(); - } - - @Test(expected=IllegalArgumentException.class) - public void setZoom() throws IOException { - XSSFWorkbook workBook = new XSSFWorkbook(); - XSSFSheet sheet1 = workBook.createSheet("new sheet"); - sheet1.setZoom(75); // 75 percent magnification - long zoom = sheet1.getCTWorksheet().getSheetViews().getSheetViewArray(0).getZoomScale(); - assertEquals(zoom, 75); - - sheet1.setZoom(200); - zoom = sheet1.getCTWorksheet().getSheetViews().getSheetViewArray(0).getZoomScale(); - assertEquals(zoom, 200); - - // Valid scale values range from 10 to 400 - try { - sheet1.setZoom(500); - } finally { - workBook.close(); - } - } - - /** - * TODO - while this is internally consistent, I'm not - * completely clear in all cases what it's supposed to - * be doing... Someone who understands the goals a little - * better should really review this! - */ - @Test - public void setColumnGroupCollapsed() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet1 = wb1.createSheet(); - - CTCols cols=sheet1.getCTWorksheet().getColsArray(0); - assertEquals(0,cols.sizeOfColArray()); - - sheet1.groupColumn( (short)4, (short)7 ); - sheet1.groupColumn( (short)9, (short)12 ); - - assertEquals(2,cols.sizeOfColArray()); - - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(true, cols.getColArray(1).isSetCollapsed()); - assertEquals(10, cols.getColArray(1).getMin()); // 1 based - assertEquals(13, cols.getColArray(1).getMax()); // 1 based - - sheet1.groupColumn( (short)10, (short)11 ); - assertEquals(4,cols.sizeOfColArray()); - - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(true, cols.getColArray(1).isSetCollapsed()); - assertEquals(10, cols.getColArray(1).getMin()); // 1 based - assertEquals(10, cols.getColArray(1).getMax()); // 1 based - assertEquals(false,cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(11, cols.getColArray(2).getMin()); // 1 based - assertEquals(12, cols.getColArray(2).getMax()); // 1 based - assertEquals(false,cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(13, cols.getColArray(3).getMin()); // 1 based - assertEquals(13, cols.getColArray(3).getMax()); // 1 based - - // collapse columns - 1 - sheet1.setColumnGroupCollapsed( (short)5, true ); - assertEquals(5,cols.sizeOfColArray()); - - assertEquals(true, cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(true, cols.getColArray(1).isSetCollapsed()); - assertEquals(9, cols.getColArray(1).getMin()); // 1 based - assertEquals(9, cols.getColArray(1).getMax()); // 1 based - assertEquals(false,cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(10, cols.getColArray(2).getMin()); // 1 based - assertEquals(10, cols.getColArray(2).getMax()); // 1 based - assertEquals(false,cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(11, cols.getColArray(3).getMin()); // 1 based - assertEquals(12, cols.getColArray(3).getMax()); // 1 based - assertEquals(false,cols.getColArray(4).isSetHidden()); - assertEquals(true, cols.getColArray(4).isSetCollapsed()); - assertEquals(13, cols.getColArray(4).getMin()); // 1 based - assertEquals(13, cols.getColArray(4).getMax()); // 1 based - - - // expand columns - 1 - sheet1.setColumnGroupCollapsed( (short)5, false ); - - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(false,cols.getColArray(1).isSetCollapsed()); - assertEquals(9, cols.getColArray(1).getMin()); // 1 based - assertEquals(9, cols.getColArray(1).getMax()); // 1 based - assertEquals(false,cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(10, cols.getColArray(2).getMin()); // 1 based - assertEquals(10, cols.getColArray(2).getMax()); // 1 based - assertEquals(false,cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(11, cols.getColArray(3).getMin()); // 1 based - assertEquals(12, cols.getColArray(3).getMax()); // 1 based - assertEquals(false,cols.getColArray(4).isSetHidden()); - assertEquals(true, cols.getColArray(4).isSetCollapsed()); - assertEquals(13, cols.getColArray(4).getMin()); // 1 based - assertEquals(13, cols.getColArray(4).getMax()); // 1 based - - - //collapse - 2 - sheet1.setColumnGroupCollapsed( (short)9, true ); - assertEquals(6,cols.sizeOfColArray()); - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(false,cols.getColArray(1).isSetCollapsed()); - assertEquals(9, cols.getColArray(1).getMin()); // 1 based - assertEquals(9, cols.getColArray(1).getMax()); // 1 based - assertEquals(true, cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(10, cols.getColArray(2).getMin()); // 1 based - assertEquals(10, cols.getColArray(2).getMax()); // 1 based - assertEquals(true, cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(11, cols.getColArray(3).getMin()); // 1 based - assertEquals(12, cols.getColArray(3).getMax()); // 1 based - assertEquals(true, cols.getColArray(4).isSetHidden()); - assertEquals(true, cols.getColArray(4).isSetCollapsed()); - assertEquals(13, cols.getColArray(4).getMin()); // 1 based - assertEquals(13, cols.getColArray(4).getMax()); // 1 based - assertEquals(false,cols.getColArray(5).isSetHidden()); - assertEquals(true, cols.getColArray(5).isSetCollapsed()); - assertEquals(14, cols.getColArray(5).getMin()); // 1 based - assertEquals(14, cols.getColArray(5).getMax()); // 1 based - - - //expand - 2 - sheet1.setColumnGroupCollapsed( (short)9, false ); - assertEquals(6,cols.sizeOfColArray()); - assertEquals(14,cols.getColArray(5).getMin()); - - //outline level 2: the line under ==> collapsed==True - assertEquals(2,cols.getColArray(3).getOutlineLevel()); - assertEquals(true,cols.getColArray(4).isSetCollapsed()); - - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(false,cols.getColArray(1).isSetCollapsed()); - assertEquals(9, cols.getColArray(1).getMin()); // 1 based - assertEquals(9, cols.getColArray(1).getMax()); // 1 based - assertEquals(false,cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(10, cols.getColArray(2).getMin()); // 1 based - assertEquals(10, cols.getColArray(2).getMax()); // 1 based - assertEquals(true, cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(11, cols.getColArray(3).getMin()); // 1 based - assertEquals(12, cols.getColArray(3).getMax()); // 1 based - assertEquals(false,cols.getColArray(4).isSetHidden()); - assertEquals(true, cols.getColArray(4).isSetCollapsed()); - assertEquals(13, cols.getColArray(4).getMin()); // 1 based - assertEquals(13, cols.getColArray(4).getMax()); // 1 based - assertEquals(false,cols.getColArray(5).isSetHidden()); - assertEquals(false,cols.getColArray(5).isSetCollapsed()); - assertEquals(14, cols.getColArray(5).getMin()); // 1 based - assertEquals(14, cols.getColArray(5).getMax()); // 1 based - - //DOCUMENTARE MEGLIO IL DISCORSO DEL LIVELLO - //collapse - 3 - sheet1.setColumnGroupCollapsed( (short)10, true ); - assertEquals(6,cols.sizeOfColArray()); - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(false,cols.getColArray(1).isSetCollapsed()); - assertEquals(9, cols.getColArray(1).getMin()); // 1 based - assertEquals(9, cols.getColArray(1).getMax()); // 1 based - assertEquals(false,cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(10, cols.getColArray(2).getMin()); // 1 based - assertEquals(10, cols.getColArray(2).getMax()); // 1 based - assertEquals(true, cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(11, cols.getColArray(3).getMin()); // 1 based - assertEquals(12, cols.getColArray(3).getMax()); // 1 based - assertEquals(false,cols.getColArray(4).isSetHidden()); - assertEquals(true, cols.getColArray(4).isSetCollapsed()); - assertEquals(13, cols.getColArray(4).getMin()); // 1 based - assertEquals(13, cols.getColArray(4).getMax()); // 1 based - assertEquals(false,cols.getColArray(5).isSetHidden()); - assertEquals(false,cols.getColArray(5).isSetCollapsed()); - assertEquals(14, cols.getColArray(5).getMin()); // 1 based - assertEquals(14, cols.getColArray(5).getMax()); // 1 based - - - //expand - 3 - sheet1.setColumnGroupCollapsed( (short)10, false ); - assertEquals(6,cols.sizeOfColArray()); - assertEquals(false,cols.getColArray(0).getHidden()); - assertEquals(false,cols.getColArray(5).getHidden()); - assertEquals(false,cols.getColArray(4).isSetCollapsed()); - -// write out and give back - // Save and re-load - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet1 = wb2.getSheetAt(0); - assertEquals(6,cols.sizeOfColArray()); - - assertEquals(false,cols.getColArray(0).isSetHidden()); - assertEquals(true, cols.getColArray(0).isSetCollapsed()); - assertEquals(5, cols.getColArray(0).getMin()); // 1 based - assertEquals(8, cols.getColArray(0).getMax()); // 1 based - assertEquals(false,cols.getColArray(1).isSetHidden()); - assertEquals(false,cols.getColArray(1).isSetCollapsed()); - assertEquals(9, cols.getColArray(1).getMin()); // 1 based - assertEquals(9, cols.getColArray(1).getMax()); // 1 based - assertEquals(false,cols.getColArray(2).isSetHidden()); - assertEquals(true, cols.getColArray(2).isSetCollapsed()); - assertEquals(10, cols.getColArray(2).getMin()); // 1 based - assertEquals(10, cols.getColArray(2).getMax()); // 1 based - assertEquals(false,cols.getColArray(3).isSetHidden()); - assertEquals(true, cols.getColArray(3).isSetCollapsed()); - assertEquals(11, cols.getColArray(3).getMin()); // 1 based - assertEquals(12, cols.getColArray(3).getMax()); // 1 based - assertEquals(false,cols.getColArray(4).isSetHidden()); - assertEquals(false,cols.getColArray(4).isSetCollapsed()); - assertEquals(13, cols.getColArray(4).getMin()); // 1 based - assertEquals(13, cols.getColArray(4).getMax()); // 1 based - assertEquals(false,cols.getColArray(5).isSetHidden()); - assertEquals(false,cols.getColArray(5).isSetCollapsed()); - assertEquals(14, cols.getColArray(5).getMin()); // 1 based - assertEquals(14, cols.getColArray(5).getMax()); // 1 based - - wb2.close(); - } - - /** - * TODO - while this is internally consistent, I'm not - * completely clear in all cases what it's supposed to - * be doing... Someone who understands the goals a little - * better should really review this! - */ - @Test - public void setRowGroupCollapsed() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet1 = wb1.createSheet(); - - sheet1.groupRow( 5, 14 ); - sheet1.groupRow( 7, 14 ); - sheet1.groupRow( 16, 19 ); - - assertEquals(14,sheet1.getPhysicalNumberOfRows()); - assertFalse(sheet1.getRow(6).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(6).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(7).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(7).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(9).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(9).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(14).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(14).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(16).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(16).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(18).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(18).getCTRow().isSetHidden()); - - //collapsed - sheet1.setRowGroupCollapsed( 7, true ); - - assertFalse(sheet1.getRow(6).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(6).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(7).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(7).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(9).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(9).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(14).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(14).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(16).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(16).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(18).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(18).getCTRow().isSetHidden()); - - //expanded - sheet1.setRowGroupCollapsed( 7, false ); - - assertFalse(sheet1.getRow(6).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(6).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(7).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(7).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(9).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(9).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(14).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(14).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(16).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(16).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(18).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(18).getCTRow().isSetHidden()); - - - // Save and re-load - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet1 = wb2.getSheetAt(0); - - assertFalse(sheet1.getRow(6).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(6).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(7).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(7).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(9).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(9).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(14).getCTRow().isSetCollapsed()); - assertTrue (sheet1.getRow(14).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(16).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(16).getCTRow().isSetHidden()); - assertFalse(sheet1.getRow(18).getCTRow().isSetCollapsed()); - assertFalse(sheet1.getRow(18).getCTRow().isSetHidden()); - - wb2.close(); - } - - /** - * Get / Set column width and check the actual values of the underlying XML beans - */ - @Test - public void columnWidth_lowlevel() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet("Sheet 1"); - sheet.setColumnWidth(1, 22 * 256); - assertEquals(22 * 256, sheet.getColumnWidth(1)); - - // Now check the low level stuff, and check that's all - // been set correctly - XSSFSheet xs = sheet; - CTWorksheet cts = xs.getCTWorksheet(); - - assertEquals(1, cts.sizeOfColsArray()); - CTCols cols = cts.getColsArray(0); - assertEquals(1, cols.sizeOfColArray()); - CTCol col = cols.getColArray(0); - - // XML is 1 based, POI is 0 based - assertEquals(2, col.getMin()); - assertEquals(2, col.getMax()); - assertEquals(22.0, col.getWidth(), 0.0); - assertTrue(col.getCustomWidth()); - - // Now set another - sheet.setColumnWidth(3, 33 * 256); - - assertEquals(1, cts.sizeOfColsArray()); - cols = cts.getColsArray(0); - assertEquals(2, cols.sizeOfColArray()); - - col = cols.getColArray(0); - assertEquals(2, col.getMin()); // POI 1 - assertEquals(2, col.getMax()); - assertEquals(22.0, col.getWidth(), 0.0); - assertTrue(col.getCustomWidth()); - - col = cols.getColArray(1); - assertEquals(4, col.getMin()); // POI 3 - assertEquals(4, col.getMax()); - assertEquals(33.0, col.getWidth(), 0.0); - assertTrue(col.getCustomWidth()); - - workbook.close(); - } - - /** - * Setting width of a column included in a column span - */ - @Test - public void bug47862() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("47862.xlsx"); - XSSFSheet sheet = wb1.getSheetAt(0); - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - // - // - // - - //a span of columns [1,5] - assertEquals(1, cols.sizeOfColArray()); - CTCol col = cols.getColArray(0); - assertEquals(1, col.getMin()); - assertEquals(5, col.getMax()); - double swidth = 15.77734375; //width of columns in the span - assertEquals(swidth, col.getWidth(), 0.0); - - for (int i = 0; i < 5; i++) { - assertEquals((int)(swidth*256), sheet.getColumnWidth(i)); - } - - int[] cw = new int[]{10, 15, 20, 25, 30}; - for (int i = 0; i < 5; i++) { - sheet.setColumnWidth(i, cw[i]*256); - } - - //the check below failed prior to fix of Bug #47862 - ColumnHelper.sortColumns(cols); - // - // - // - // - // - // - // - - //now the span is splitted into 5 individual columns - assertEquals(5, cols.sizeOfColArray()); - for (int i = 0; i < 5; i++) { - assertEquals(cw[i]*256, sheet.getColumnWidth(i)); - assertEquals(cw[i], cols.getColArray(i).getWidth(), 0.0); - } - - //serialize and check again - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - cols = sheet.getCTWorksheet().getColsArray(0); - assertEquals(5, cols.sizeOfColArray()); - for (int i = 0; i < 5; i++) { - assertEquals(cw[i]*256, sheet.getColumnWidth(i)); - assertEquals(cw[i], cols.getColArray(i).getWidth(), 0.0); - } - - wb2.close(); - } - - /** - * Hiding a column included in a column span - */ - @Test - public void bug47804() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("47804.xlsx"); - XSSFSheet sheet = wb1.getSheetAt(0); - CTCols cols = sheet.getCTWorksheet().getColsArray(0); - assertEquals(2, cols.sizeOfColArray()); - CTCol col; - // - // - // - // - - //a span of columns [2,4] - col = cols.getColArray(0); - assertEquals(2, col.getMin()); - assertEquals(4, col.getMax()); - //individual column - col = cols.getColArray(1); - assertEquals(7, col.getMin()); - assertEquals(7, col.getMax()); - - sheet.setColumnHidden(2, true); // Column C - sheet.setColumnHidden(6, true); // Column G - - assertTrue(sheet.isColumnHidden(2)); - assertTrue(sheet.isColumnHidden(6)); - - //other columns but C and G are not hidden - assertFalse(sheet.isColumnHidden(1)); - assertFalse(sheet.isColumnHidden(3)); - assertFalse(sheet.isColumnHidden(4)); - assertFalse(sheet.isColumnHidden(5)); - - //the check below failed prior to fix of Bug #47804 - ColumnHelper.sortColumns(cols); - //the span is now splitted into three parts - // - // - // - // - // - // - - assertEquals(4, cols.sizeOfColArray()); - col = cols.getColArray(0); - assertEquals(2, col.getMin()); - assertEquals(2, col.getMax()); - col = cols.getColArray(1); - assertEquals(3, col.getMin()); - assertEquals(3, col.getMax()); - col = cols.getColArray(2); - assertEquals(4, col.getMin()); - assertEquals(4, col.getMax()); - col = cols.getColArray(3); - assertEquals(7, col.getMin()); - assertEquals(7, col.getMax()); - - //serialize and check again - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - assertTrue(sheet.isColumnHidden(2)); - assertTrue(sheet.isColumnHidden(6)); - assertFalse(sheet.isColumnHidden(1)); - assertFalse(sheet.isColumnHidden(3)); - assertFalse(sheet.isColumnHidden(4)); - assertFalse(sheet.isColumnHidden(5)); - - wb2.close(); - } - - @Test - public void commentsTable() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet1 = wb1.createSheet(); - CommentsTable comment1 = sheet1.getCommentsTable(false); - assertNull(comment1); - - comment1 = sheet1.getCommentsTable(true); - assertNotNull(comment1); - assertEquals("/xl/comments1.xml", comment1.getPackagePart().getPartName().getName()); - - assertSame(comment1, sheet1.getCommentsTable(true)); - - //second sheet - XSSFSheet sheet2 = wb1.createSheet(); - CommentsTable comment2 = sheet2.getCommentsTable(false); - assertNull(comment2); - - comment2 = sheet2.getCommentsTable(true); - assertNotNull(comment2); - - assertSame(comment2, sheet2.getCommentsTable(true)); - assertEquals("/xl/comments2.xml", comment2.getPackagePart().getPartName().getName()); - - //comment1 and comment2 are different objects - assertNotSame(comment1, comment2); - wb1.close(); - - //now test against a workbook containing cell comments - XSSFWorkbook wb2 = XSSFTestDataSamples.openSampleWorkbook("WithMoreVariousData.xlsx"); - sheet1 = wb2.getSheetAt(0); - comment1 = sheet1.getCommentsTable(true); - assertNotNull(comment1); - assertEquals("/xl/comments1.xml", comment1.getPackagePart().getPartName().getName()); - assertSame(comment1, sheet1.getCommentsTable(true)); - - wb2.close(); - } - - /** - * Rows and cells can be created in random order, - * but CTRows are kept in ascending order - */ - @Override - @Test - public void createRow() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet(); - CTWorksheet wsh = sheet.getCTWorksheet(); - CTSheetData sheetData = wsh.getSheetData(); - assertEquals(0, sheetData.sizeOfRowArray()); - - XSSFRow row1 = sheet.createRow(2); - row1.createCell(2); - row1.createCell(1); - - XSSFRow row2 = sheet.createRow(1); - row2.createCell(2); - row2.createCell(1); - row2.createCell(0); - - XSSFRow row3 = sheet.createRow(0); - row3.createCell(3); - row3.createCell(0); - row3.createCell(2); - row3.createCell(5); - - - CTRow[] xrow = sheetData.getRowArray(); - assertEquals(3, xrow.length); - - //rows are sorted: {0, 1, 2} - assertEquals(4, xrow[0].sizeOfCArray()); - assertEquals(1, xrow[0].getR()); - assertTrue(xrow[0].equals(row3.getCTRow())); - - assertEquals(3, xrow[1].sizeOfCArray()); - assertEquals(2, xrow[1].getR()); - assertTrue(xrow[1].equals(row2.getCTRow())); - - assertEquals(2, xrow[2].sizeOfCArray()); - assertEquals(3, xrow[2].getR()); - assertTrue(xrow[2].equals(row1.getCTRow())); - - CTCell[] xcell = xrow[0].getCArray(); - assertEquals("D1", xcell[0].getR()); - assertEquals("A1", xcell[1].getR()); - assertEquals("C1", xcell[2].getR()); - assertEquals("F1", xcell[3].getR()); - - //re-creating a row does NOT add extra data to the parent - row2 = sheet.createRow(1); - assertEquals(3, sheetData.sizeOfRowArray()); - //existing cells are invalidated - assertEquals(0, sheetData.getRowArray(1).sizeOfCArray()); - assertEquals(0, row2.getPhysicalNumberOfCells()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheetAt(0); - wsh = sheet.getCTWorksheet(); - xrow = sheetData.getRowArray(); - assertEquals(3, xrow.length); - - //rows are sorted: {0, 1, 2} - assertEquals(4, xrow[0].sizeOfCArray()); - assertEquals(1, xrow[0].getR()); - //cells are now sorted - xcell = xrow[0].getCArray(); - assertEquals("A1", xcell[0].getR()); - assertEquals("C1", xcell[1].getR()); - assertEquals("D1", xcell[2].getR()); - assertEquals("F1", xcell[3].getR()); - - - assertEquals(0, xrow[1].sizeOfCArray()); - assertEquals(2, xrow[1].getR()); - - assertEquals(2, xrow[2].sizeOfCArray()); - assertEquals(3, xrow[2].getR()); - - wb2.close(); - } - - @Test - public void setAutoFilter() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet("new sheet"); - sheet.setAutoFilter(CellRangeAddress.valueOf("A1:D100")); - - assertEquals("A1:D100", sheet.getCTWorksheet().getAutoFilter().getRef()); - - // auto-filter must be registered in workboook.xml, see Bugzilla 50315 - XSSFName nm = wb.getBuiltInName(XSSFName.BUILTIN_FILTER_DB, 0); - assertNotNull(nm); - - assertEquals(0, nm.getCTName().getLocalSheetId()); - assertEquals(true, nm.getCTName().getHidden()); - assertEquals("_xlnm._FilterDatabase", nm.getCTName().getName()); - assertEquals("'new sheet'!$A$1:$D$100", nm.getCTName().getStringValue()); - - wb.close(); - } - - @Test - public void protectSheet_lowlevel() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - CTSheetProtection pr = sheet.getCTWorksheet().getSheetProtection(); - assertNull("CTSheetProtection should be null by default", pr); - String password = "Test"; - sheet.protectSheet(password); - pr = sheet.getCTWorksheet().getSheetProtection(); - assertNotNull("CTSheetProtection should be not null", pr); - assertTrue("sheet protection should be on", pr.isSetSheet()); - assertTrue("object protection should be on", pr.isSetObjects()); - assertTrue("scenario protection should be on", pr.isSetScenarios()); - int hashVal = CryptoFunctions.createXorVerifier1(password); - int actualVal = Integer.parseInt(pr.xgetPassword().getStringValue(),16); - assertEquals("well known value for top secret hash should match", hashVal, actualVal); - - sheet.protectSheet(null); - assertNull("protectSheet(null) should unset CTSheetProtection", sheet.getCTWorksheet().getSheetProtection()); - - wb.close(); - } - - @Test - public void protectSheet_emptyPassword() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - CTSheetProtection pr = sheet.getCTWorksheet().getSheetProtection(); - assertNull("CTSheetProtection should be null by default", pr); - String password = ""; - sheet.protectSheet(password); - pr = sheet.getCTWorksheet().getSheetProtection(); - assertNotNull("CTSheetProtection should be not null", pr); - assertTrue("sheet protection should be on", pr.isSetSheet()); - assertTrue("object protection should be on", pr.isSetObjects()); - assertTrue("scenario protection should be on", pr.isSetScenarios()); - int hashVal = CryptoFunctions.createXorVerifier1(password); - STUnsignedShortHex xpassword = pr.xgetPassword(); - int actualVal = Integer.parseInt(xpassword.getStringValue(),16); - assertEquals("well known value for top secret hash should match", hashVal, actualVal); - - sheet.protectSheet(null); - assertNull("protectSheet(null) should unset CTSheetProtection", sheet.getCTWorksheet().getSheetProtection()); - - wb.close(); - } - - @Test - public void protectSheet_lowlevel_2013() throws IOException { - String password = "test"; - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet xs = wb1.createSheet(); - xs.setSheetPassword(password, HashAlgorithm.sha384); - XSSFWorkbook wb2 = writeOutAndReadBack(wb1); - wb1.close(); - assertTrue(wb2.getSheetAt(0).validateSheetPassword(password)); - wb2.close(); - - XSSFWorkbook wb3 = openSampleWorkbook("workbookProtection-sheet_password-2013.xlsx"); - assertTrue(wb3.getSheetAt(0).validateSheetPassword("pwd")); - wb3.close(); - } - - - @Test - public void bug49966() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("49966.xlsx"); - CalculationChain calcChain = wb1.getCalculationChain(); - assertNotNull(wb1.getCalculationChain()); - assertEquals(3, calcChain.getCTCalcChain().sizeOfCArray()); - - XSSFSheet sheet = wb1.getSheetAt(0); - XSSFRow row = sheet.getRow(0); - - sheet.removeRow(row); - assertEquals("XSSFSheet#removeRow did not clear calcChain entries", - 0, calcChain.getCTCalcChain().sizeOfCArray()); - - //calcChain should be gone - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - assertNull(wb2.getCalculationChain()); - wb2.close(); - } - - /** - * See bug #50829 test data tables - */ - @Test - public void tables() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTable.xlsx"); - assertEquals(3, wb.getNumberOfSheets()); - - // Check the table sheet - XSSFSheet s1 = wb.getSheetAt(0); - assertEquals("a", s1.getRow(0).getCell(0).getRichStringCellValue().toString()); - assertEquals(1.0, s1.getRow(1).getCell(0).getNumericCellValue(), 0); - - List tables = s1.getTables(); - assertNotNull(tables); - assertEquals(1, tables.size()); - - XSSFTable table = tables.get(0); - assertEquals("Tabella1", table.getName()); - assertEquals("Tabella1", table.getDisplayName()); - - // And the others - XSSFSheet s2 = wb.getSheetAt(1); - assertEquals(0, s2.getTables().size()); - XSSFSheet s3 = wb.getSheetAt(2); - assertEquals(0, s3.getTables().size()); - wb.close(); - } - - /** - * Test to trigger OOXML-LITE generating to include org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetCalcPr - */ - @Test - public void setForceFormulaRecalculation() throws IOException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("Sheet 1"); - - assertFalse(sheet.getForceFormulaRecalculation()); - - // Set - sheet.setForceFormulaRecalculation(true); - assertEquals(true, sheet.getForceFormulaRecalculation()); - - // calcMode="manual" is unset when forceFormulaRecalculation=true - CTCalcPr calcPr = wb1.getCTWorkbook().addNewCalcPr(); - calcPr.setCalcMode(STCalcMode.MANUAL); - sheet.setForceFormulaRecalculation(true); - assertEquals(STCalcMode.AUTO, calcPr.getCalcMode()); - - // Check - sheet.setForceFormulaRecalculation(false); - assertEquals(false, sheet.getForceFormulaRecalculation()); - - - // Save, re-load, and re-check - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - sheet = wb2.getSheet("Sheet 1"); - assertEquals(false, sheet.getForceFormulaRecalculation()); - wb2.close(); - } - - @Test - public void bug54607() throws IOException { - // run with the file provided in the Bug-Report - runGetTopRow("54607.xlsx", true, 1, 0, 0); - runGetLeftCol("54607.xlsx", true, 0, 0, 0); - - // run with some other flie to see - runGetTopRow("54436.xlsx", true, 0); - runGetLeftCol("54436.xlsx", true, 0); - runGetTopRow("TwoSheetsNoneHidden.xlsx", true, 0, 0); - runGetLeftCol("TwoSheetsNoneHidden.xlsx", true, 0, 0); - runGetTopRow("TwoSheetsNoneHidden.xls", false, 0, 0); - runGetLeftCol("TwoSheetsNoneHidden.xls", false, 0, 0); - } - - private void runGetTopRow(String file, boolean isXSSF, int... topRows) throws IOException { - final Workbook wb = (isXSSF) - ? XSSFTestDataSamples.openSampleWorkbook(file) - : HSSFTestDataSamples.openSampleWorkbook(file); - - for (int si = 0; si < wb.getNumberOfSheets(); si++) { - Sheet sh = wb.getSheetAt(si); - assertNotNull(sh.getSheetName()); - assertEquals("Did not match for sheet " + si, topRows[si], sh.getTopRow()); - } - - // for XSSF also test with SXSSF - if (isXSSF) { - Workbook swb = new SXSSFWorkbook((XSSFWorkbook) wb); - for (int si = 0; si < swb.getNumberOfSheets(); si++) { - Sheet sh = swb.getSheetAt(si); - assertNotNull(sh.getSheetName()); - assertEquals("Did not match for sheet " + si, topRows[si], sh.getTopRow()); - } - swb.close(); - } - - wb.close(); - } - - private void runGetLeftCol(String file, boolean isXSSF, int... topRows) throws IOException { - final Workbook wb = (isXSSF) - ? XSSFTestDataSamples.openSampleWorkbook(file) - : HSSFTestDataSamples.openSampleWorkbook(file); - - for (int si = 0; si < wb.getNumberOfSheets(); si++) { - Sheet sh = wb.getSheetAt(si); - assertNotNull(sh.getSheetName()); - assertEquals("Did not match for sheet " + si, topRows[si], sh.getLeftCol()); - } - - // for XSSF also test with SXSSF - if(isXSSF) { - Workbook swb = new SXSSFWorkbook((XSSFWorkbook) wb); - for (int si = 0; si < swb.getNumberOfSheets(); si++) { - Sheet sh = swb.getSheetAt(si); - assertNotNull(sh.getSheetName()); - assertEquals("Did not match for sheet " + si, topRows[si], sh.getLeftCol()); - } - swb.close(); - } - - wb.close(); - } - - @Test - public void bug55745() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55745.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - List tables = sheet.getTables(); - /*System.out.println(tables.size()); - - for(XSSFTable table : tables) { - System.out.println("XPath: " + table.getCommonXpath()); - System.out.println("Name: " + table.getName()); - System.out.println("Mapped Cols: " + table.getNumberOfMappedColumns()); - System.out.println("Rowcount: " + table.getRowCount()); - System.out.println("End Cell: " + table.getEndCellReference()); - System.out.println("Start Cell: " + table.getStartCellReference()); - }*/ - assertEquals("Sheet should contain 8 tables", 8, tables.size()); - assertNotNull("Sheet should contain a comments table", sheet.getCommentsTable(false)); - wb.close(); - } - - @Test - public void bug55723b() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - // stored with a special name - assertNull(wb.getBuiltInName(XSSFName.BUILTIN_FILTER_DB, 0)); - - CellRangeAddress range = CellRangeAddress.valueOf("A:B"); - AutoFilter filter = sheet.setAutoFilter(range); - assertNotNull(filter); - - // stored with a special name - XSSFName name = wb.getBuiltInName(XSSFName.BUILTIN_FILTER_DB, 0); - assertNotNull(name); - assertEquals("Sheet0!$A:$B", name.getRefersToFormula()); - - range = CellRangeAddress.valueOf("B:C"); - filter = sheet.setAutoFilter(range); - assertNotNull(filter); - - // stored with a special name - name = wb.getBuiltInName(XSSFName.BUILTIN_FILTER_DB, 0); - assertNotNull(name); - assertEquals("Sheet0!$B:$C", name.getRefersToFormula()); - - wb.close(); - } - - @Test(timeout=180000) - public void bug51585() throws IOException { - XSSFTestDataSamples.openSampleWorkbook("51585.xlsx").close(); - } - - private XSSFWorkbook setupSheet(){ - //set up workbook - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - - Row row1 = sheet.createRow((short) 0); - Cell cell = row1.createCell((short) 0); - cell.setCellValue("Names"); - Cell cell2 = row1.createCell((short) 1); - cell2.setCellValue("#"); - - Row row2 = sheet.createRow((short) 1); - Cell cell3 = row2.createCell((short) 0); - cell3.setCellValue("Jane"); - Cell cell4 = row2.createCell((short) 1); - cell4.setCellValue(3); - - Row row3 = sheet.createRow((short) 2); - Cell cell5 = row3.createCell((short) 0); - cell5.setCellValue("John"); - Cell cell6 = row3.createCell((short) 1); - cell6.setCellValue(3); - - return wb; - } - - @Test - public void testCreateTwoPivotTablesInOneSheet() throws IOException { - XSSFWorkbook wb = setupSheet(); - XSSFSheet sheet = wb.getSheetAt(0); - - assertNotNull(wb); - assertNotNull(sheet); - XSSFPivotTable pivotTable = sheet.createPivotTable(new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007), new CellReference("H5")); - assertNotNull(pivotTable); - assertTrue(wb.getPivotTables().size() > 0); - XSSFPivotTable pivotTable2 = sheet.createPivotTable(new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007), new CellReference("L5"), sheet); - assertNotNull(pivotTable2); - assertTrue(wb.getPivotTables().size() > 1); - wb.close(); - } - - @Test - public void testCreateTwoPivotTablesInTwoSheets() throws IOException { - XSSFWorkbook wb = setupSheet(); - XSSFSheet sheet = wb.getSheetAt(0); - - assertNotNull(wb); - assertNotNull(sheet); - XSSFPivotTable pivotTable = sheet.createPivotTable(new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007), new CellReference("H5")); - assertNotNull(pivotTable); - assertTrue(wb.getPivotTables().size() > 0); - assertNotNull(wb); - XSSFSheet sheet2 = wb.createSheet(); - XSSFPivotTable pivotTable2 = sheet2.createPivotTable(new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007), new CellReference("H5"), sheet); - assertNotNull(pivotTable2); - assertTrue(wb.getPivotTables().size() > 1); - wb.close(); - } - - @Test - public void testCreatePivotTable() throws IOException { - XSSFWorkbook wb = setupSheet(); - XSSFSheet sheet = wb.getSheetAt(0); - - assertNotNull(wb); - assertNotNull(sheet); - XSSFPivotTable pivotTable = sheet.createPivotTable(new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007), new CellReference("H5")); - assertNotNull(pivotTable); - assertTrue(wb.getPivotTables().size() > 0); - wb.close(); - } - - @Test - public void testCreatePivotTableInOtherSheetThanDataSheet() throws IOException { - XSSFWorkbook wb = setupSheet(); - XSSFSheet sheet1 = wb.getSheetAt(0); - XSSFSheet sheet2 = wb.createSheet(); - - XSSFPivotTable pivotTable = sheet2.createPivotTable - (new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007), new CellReference("H5"), sheet1); - assertEquals(0, pivotTable.getRowLabelColumns().size()); - - assertEquals(1, wb.getPivotTables().size()); - assertEquals(0, sheet1.getPivotTables().size()); - assertEquals(1, sheet2.getPivotTables().size()); - wb.close(); - } - - @Test - public void testCreatePivotTableInOtherSheetThanDataSheetUsingAreaReference() throws IOException { - XSSFWorkbook wb = setupSheet(); - XSSFSheet sheet = wb.getSheetAt(0); - XSSFSheet sheet2 = wb.createSheet("TEST"); - - XSSFPivotTable pivotTable = sheet2.createPivotTable( - new AreaReference(sheet.getSheetName()+"!A$1:B$2", SpreadsheetVersion.EXCEL2007), - new CellReference("H5")); - assertEquals(0, pivotTable.getRowLabelColumns().size()); - wb.close(); - } - - @Test(expected=IllegalArgumentException.class) - public void testCreatePivotTableWithConflictingDataSheets() throws IOException { - XSSFWorkbook wb = setupSheet(); - XSSFSheet sheet = wb.getSheetAt(0); - XSSFSheet sheet2 = wb.createSheet("TEST"); - - sheet2.createPivotTable( - new AreaReference(sheet.getSheetName()+"!A$1:B$2", SpreadsheetVersion.EXCEL2007), - new CellReference("H5"), - sheet2); - wb.close(); - } - - @Test(expected=POIXMLException.class) - public void testReadFails() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - - // Throws exception because we cannot read here - try { - sheet.onDocumentRead(); - } finally { - wb.close(); - } - } - - /** - * This would be better off as a testable example rather than a simple unit test - * since Sheet.createComment() was deprecated and removed. - * https://poi.apache.org/spreadsheet/quick-guide.html#CellComments - * Feel free to relocated or delete this unit test if it doesn't belong here. - */ - @Test - public void testCreateComment() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - ClientAnchor anchor = wb.getCreationHelper().createClientAnchor(); - XSSFSheet sheet = wb.createSheet(); - XSSFComment comment = sheet.createDrawingPatriarch().createCellComment(anchor); - assertNotNull(comment); - wb.close(); - } - - protected void testCopyOneRow(String copyRowsTestWorkbook) throws IOException { - final double FLOAT_PRECISION = 1e-9; - final XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook(copyRowsTestWorkbook); - final XSSFSheet sheet = wb.getSheetAt(0); - final CellCopyPolicy defaultCopyPolicy = new CellCopyPolicy(); - sheet.copyRows(1, 1, 6, defaultCopyPolicy); - - final Row srcRow = sheet.getRow(1); - final Row destRow = sheet.getRow(6); - int col = 0; - Cell cell; - - cell = CellUtil.getCell(destRow, col++); - assertEquals("Source row ->", cell.getStringCellValue()); - - // Style - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Style] B7 cell value", "Red", cell.getStringCellValue()); - assertEquals("[Style] B7 cell style", CellUtil.getCell(srcRow, 1).getCellStyle(), cell.getCellStyle()); - - // Blank - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Blank] C7 cell type", CellType.BLANK, cell.getCellTypeEnum()); - - // Error - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Error] D7 cell type", CellType.ERROR, cell.getCellTypeEnum()); - final FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); - assertEquals("[Error] D7 cell value", FormulaError.NA, error); //FIXME: XSSFCell and HSSFCell expose different interfaces. getErrorCellString would be helpful here - - // Date - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Date] E7 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - final Date date = LocaleUtil.getLocaleCalendar(2000, Calendar.JANUARY, 1).getTime(); - assertEquals("[Date] E7 cell value", date, cell.getDateCellValue()); - - // Boolean - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Boolean] F7 cell type", CellType.BOOLEAN, cell.getCellTypeEnum()); - assertEquals("[Boolean] F7 cell value", true, cell.getBooleanCellValue()); - - // String - cell = CellUtil.getCell(destRow, col++); - assertEquals("[String] G7 cell type", CellType.STRING, cell.getCellTypeEnum()); - assertEquals("[String] G7 cell value", "Hello", cell.getStringCellValue()); - - // Int - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Int] H7 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Int] H7 cell value", 15, (int) cell.getNumericCellValue()); - - // Float - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Float] I7 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Float] I7 cell value", 12.5, cell.getNumericCellValue(), FLOAT_PRECISION); - - // Cell Formula - cell = CellUtil.getCell(destRow, col++); - assertEquals("J7", new CellReference(cell).formatAsString()); - assertEquals("[Cell Formula] J7 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula] J7 cell formula", "5+2", cell.getCellFormula()); - System.out.println("Cell formula evaluation currently unsupported"); - - // Cell Formula with Reference - // Formula row references should be adjusted by destRowNum-srcRowNum - cell = CellUtil.getCell(destRow, col++); - assertEquals("K7", new CellReference(cell).formatAsString()); - assertEquals("[Cell Formula with Reference] K7 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Reference] K7 cell formula", - "J7+H$2", cell.getCellFormula()); - - // Cell Formula with Reference spanning multiple rows - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Cell Formula with Reference spanning multiple rows] L7 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Reference spanning multiple rows] L7 cell formula", - "G7&\" \"&G8", cell.getCellFormula()); - - // Cell Formula with Reference spanning multiple rows - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Cell Formula with Area Reference] M7 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Area Reference] M7 cell formula", - "SUM(H7:I8)", cell.getCellFormula()); - - // Array Formula - cell = CellUtil.getCell(destRow, col++); - System.out.println("Array formulas currently unsupported"); - // FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula() - /* - assertEquals("[Array Formula] N7 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Array Formula] N7 cell formula", "{SUM(H7:J7*{1,2,3})}", cell.getCellFormula()); - */ - - // Data Format - cell = CellUtil.getCell(destRow, col++); - assertEquals("[Data Format] O7 cell type;", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Data Format] O7 cell value", 100.20, cell.getNumericCellValue(), FLOAT_PRECISION); - //FIXME: currently fails - final String moneyFormat = "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)"; - assertEquals("[Data Format] O7 data format", moneyFormat, cell.getCellStyle().getDataFormatString()); - - // Merged - cell = CellUtil.getCell(destRow, col); - assertEquals("[Merged] P7:Q7 cell value", - "Merged cells", cell.getStringCellValue()); - assertTrue("[Merged] P7:Q7 merged region", - sheet.getMergedRegions().contains(CellRangeAddress.valueOf("P7:Q7"))); - - // Merged across multiple rows - // Microsoft Excel 2013 does not copy a merged region unless all rows of - // the source merged region are selected - // POI's behavior should match this behavior - col += 2; - cell = CellUtil.getCell(destRow, col); - // Note: this behavior deviates from Microsoft Excel, - // which will not overwrite a cell in destination row if merged region extends beyond the copied row. - // The Excel way would require: - //assertEquals("[Merged across multiple rows] R7:S8 merged region", "Should NOT be overwritten", cell.getStringCellValue()); - //assertFalse("[Merged across multiple rows] R7:S8 merged region", - // sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R7:S8"))); - // As currently implemented, cell value is copied but merged region is not copied - assertEquals("[Merged across multiple rows] R7:S8 cell value", - "Merged cells across multiple rows", cell.getStringCellValue()); - assertFalse("[Merged across multiple rows] R7:S7 merged region (one row)", - sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R7:S7"))); //shouldn't do 1-row merge - assertFalse("[Merged across multiple rows] R7:S8 merged region", - sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R7:S8"))); //shouldn't do 2-row merge - - // Make sure other rows are blank (off-by-one errors) - assertNull(sheet.getRow(5)); - assertNull(sheet.getRow(7)); - - wb.close(); - } - - protected void testCopyMultipleRows(String copyRowsTestWorkbook) throws IOException { - final double FLOAT_PRECISION = 1e-9; - final XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook(copyRowsTestWorkbook); - final XSSFSheet sheet = wb.getSheetAt(0); - final CellCopyPolicy defaultCopyPolicy = new CellCopyPolicy(); - sheet.copyRows(0, 3, 8, defaultCopyPolicy); - - @SuppressWarnings("unused") - final Row srcHeaderRow = sheet.getRow(0); - final Row srcRow1 = sheet.getRow(1); - final Row srcRow2 = sheet.getRow(2); - final Row srcRow3 = sheet.getRow(3); - final Row destHeaderRow = sheet.getRow(8); - final Row destRow1 = sheet.getRow(9); - final Row destRow2 = sheet.getRow(10); - final Row destRow3 = sheet.getRow(11); - int col = 0; - Cell cell; - - // Header row should be copied - assertNotNull(destHeaderRow); - - // Data rows - cell = CellUtil.getCell(destRow1, col); - assertEquals("Source row ->", cell.getStringCellValue()); - - // Style - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Style] B10 cell value", "Red", cell.getStringCellValue()); - assertEquals("[Style] B10 cell style", CellUtil.getCell(srcRow1, 1).getCellStyle(), cell.getCellStyle()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Style] B11 cell value", "Blue", cell.getStringCellValue()); - assertEquals("[Style] B11 cell style", CellUtil.getCell(srcRow2, 1).getCellStyle(), cell.getCellStyle()); - - // Blank - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Blank] C10 cell type", CellType.BLANK, cell.getCellTypeEnum()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Blank] C11 cell type", CellType.BLANK, cell.getCellTypeEnum()); - - // Error - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Error] D10 cell type", CellType.ERROR, cell.getCellTypeEnum()); - FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); - assertEquals("[Error] D10 cell value", FormulaError.NA, error); //FIXME: XSSFCell and HSSFCell expose different interfaces. getErrorCellString would be helpful here - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Error] D11 cell type", CellType.ERROR, cell.getCellTypeEnum()); - error = FormulaError.forInt(cell.getErrorCellValue()); - assertEquals("[Error] D11 cell value", FormulaError.NAME, error); //FIXME: XSSFCell and HSSFCell expose different interfaces. getErrorCellString would be helpful here - - // Date - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Date] E10 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - Date date = LocaleUtil.getLocaleCalendar(2000, Calendar.JANUARY, 1).getTime(); - assertEquals("[Date] E10 cell value", date, cell.getDateCellValue()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Date] E11 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - date = LocaleUtil.getLocaleCalendar(2000, Calendar.JANUARY, 2).getTime(); - assertEquals("[Date] E11 cell value", date, cell.getDateCellValue()); - - // Boolean - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Boolean] F10 cell type", CellType.BOOLEAN, cell.getCellTypeEnum()); - assertEquals("[Boolean] F10 cell value", true, cell.getBooleanCellValue()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Boolean] F11 cell type", CellType.BOOLEAN, cell.getCellTypeEnum()); - assertEquals("[Boolean] F11 cell value", false, cell.getBooleanCellValue()); - - // String - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[String] G10 cell type", CellType.STRING, cell.getCellTypeEnum()); - assertEquals("[String] G10 cell value", "Hello", cell.getStringCellValue()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[String] G11 cell type", CellType.STRING, cell.getCellTypeEnum()); - assertEquals("[String] G11 cell value", "World", cell.getStringCellValue()); - - // Int - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Int] H10 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Int] H10 cell value", 15, (int) cell.getNumericCellValue()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Int] H11 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Int] H11 cell value", 42, (int) cell.getNumericCellValue()); - - // Float - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Float] I10 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Float] I10 cell value", 12.5, cell.getNumericCellValue(), FLOAT_PRECISION); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Float] I11 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Float] I11 cell value", 5.5, cell.getNumericCellValue(), FLOAT_PRECISION); - - // Cell Formula - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Cell Formula] J10 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula] J10 cell formula", "5+2", cell.getCellFormula()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Cell Formula] J11 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula] J11 cell formula", "6+18", cell.getCellFormula()); - - // Cell Formula with Reference - col++; - // Formula row references should be adjusted by destRowNum-srcRowNum - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Cell Formula with Reference] K10 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Reference] K10 cell formula", - "J10+H$2", cell.getCellFormula()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Cell Formula with Reference] K11 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Reference] K11 cell formula", "J11+H$2", cell.getCellFormula()); - - // Cell Formula with Reference spanning multiple rows - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Cell Formula with Reference spanning multiple rows] L10 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Reference spanning multiple rows] L10 cell formula", - "G10&\" \"&G11", cell.getCellFormula()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Cell Formula with Reference spanning multiple rows] L11 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Reference spanning multiple rows] L11 cell formula", - "G11&\" \"&G12", cell.getCellFormula()); - - // Cell Formula with Area Reference - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Cell Formula with Area Reference] M10 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Area Reference] M10 cell formula", - "SUM(H10:I11)", cell.getCellFormula()); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Cell Formula with Area Reference] M11 cell type", - CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Cell Formula with Area Reference] M11 cell formula", - "SUM($H$3:I10)", cell.getCellFormula()); //Also acceptable: SUM($H10:I$3), but this AreaReference isn't in ascending order - - // Array Formula - col++; - cell = CellUtil.getCell(destRow1, col); - // System.out.println("Array formulas currently unsupported"); - /* - // FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula() - assertEquals("[Array Formula] N10 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Array Formula] N10 cell formula", "{SUM(H10:J10*{1,2,3})}", cell.getCellFormula()); - - cell = CellUtil.getCell(destRow2, col); - // FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula() - assertEquals("[Array Formula] N11 cell type", CellType.FORMULA, cell.getCellTypeEnum()); - assertEquals("[Array Formula] N11 cell formula", "{SUM(H11:J11*{1,2,3})}", cell.getCellFormula()); - */ - - // Data Format - col++; - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Data Format] O10 cell type", CellType.NUMERIC, cell.getCellTypeEnum()); - assertEquals("[Data Format] O10 cell value", 100.20, cell.getNumericCellValue(), FLOAT_PRECISION); - final String moneyFormat = "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)"; - assertEquals("[Data Format] O10 cell data format", moneyFormat, cell.getCellStyle().getDataFormatString()); - - // Merged - col++; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Merged] P10:Q10 cell value", - "Merged cells", cell.getStringCellValue()); - assertTrue("[Merged] P10:Q10 merged region", - sheet.getMergedRegions().contains(CellRangeAddress.valueOf("P10:Q10"))); - - cell = CellUtil.getCell(destRow2, col); - assertEquals("[Merged] P11:Q11 cell value", "Merged cells", cell.getStringCellValue()); - assertTrue("[Merged] P11:Q11 merged region", - sheet.getMergedRegions().contains(CellRangeAddress.valueOf("P11:Q11"))); - - // Should Q10/Q11 be checked? - - // Merged across multiple rows - // Microsoft Excel 2013 does not copy a merged region unless all rows of - // the source merged region are selected - // POI's behavior should match this behavior - col += 2; - cell = CellUtil.getCell(destRow1, col); - assertEquals("[Merged across multiple rows] R10:S11 cell value", - "Merged cells across multiple rows", cell.getStringCellValue()); - assertTrue("[Merged across multiple rows] R10:S11 merged region", - sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R10:S11"))); - - // Row 3 (zero-based) was empty, so Row 11 (zero-based) should be empty too. - if (srcRow3 == null) { - assertNull("Row 3 was empty, so Row 11 should be empty", destRow3); - } - - // Make sure other rows are blank (off-by-one errors) - assertNull("Off-by-one lower edge case", sheet.getRow(7)); //one row above destHeaderRow - assertNull("Off-by-one upper edge case", sheet.getRow(12)); //one row below destRow3 - - wb.close(); - } - - @Test - public void testCopyOneRow() throws IOException { - testCopyOneRow("XSSFSheet.copyRows.xlsx"); - } - - @Test - public void testCopyMultipleRows() throws IOException { - testCopyMultipleRows("XSSFSheet.copyRows.xlsx"); - } - - @Test - public void testIgnoredErrors() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CellRangeAddress region = CellRangeAddress.valueOf("B2:D4"); - sheet.addIgnoredErrors(region, IgnoredErrorType.NUMBER_STORED_AS_TEXT); - final CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0); - assertEquals(1, ignoredError.getSqref().size()); - assertEquals("B2:D4", ignoredError.getSqref().get(0)); - assertTrue(ignoredError.getNumberStoredAsText()); - - Map> ignoredErrors = sheet.getIgnoredErrors(); - assertEquals(1, ignoredErrors.size()); - assertEquals(1, ignoredErrors.get(IgnoredErrorType.NUMBER_STORED_AS_TEXT).size()); - assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.NUMBER_STORED_AS_TEXT).iterator().next().formatAsString()); - - workbook.close(); - } - - @Test - public void testIgnoredErrorsMultipleTypes() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CellRangeAddress region = CellRangeAddress.valueOf("B2:D4"); - sheet.addIgnoredErrors(region, IgnoredErrorType.FORMULA, IgnoredErrorType.EVALUATION_ERROR); - final CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0); - assertEquals(1, ignoredError.getSqref().size()); - assertEquals("B2:D4", ignoredError.getSqref().get(0)); - assertFalse(ignoredError.getNumberStoredAsText()); - assertTrue(ignoredError.getFormula()); - assertTrue(ignoredError.getEvalError()); - - Map> ignoredErrors = sheet.getIgnoredErrors(); - assertEquals(2, ignoredErrors.size()); - assertEquals(1, ignoredErrors.get(IgnoredErrorType.FORMULA).size()); - assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.FORMULA).iterator().next().formatAsString()); - assertEquals(1, ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).size()); - assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).iterator().next().formatAsString()); - workbook.close(); - } - - @Test - public void testIgnoredErrorsMultipleCalls() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CellRangeAddress region = CellRangeAddress.valueOf("B2:D4"); - // Two calls means two elements, no clever collapsing just yet. - sheet.addIgnoredErrors(region, IgnoredErrorType.EVALUATION_ERROR); - sheet.addIgnoredErrors(region, IgnoredErrorType.FORMULA); - - CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0); - assertEquals(1, ignoredError.getSqref().size()); - assertEquals("B2:D4", ignoredError.getSqref().get(0)); - assertFalse(ignoredError.getFormula()); - assertTrue(ignoredError.getEvalError()); - - ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(1); - assertEquals(1, ignoredError.getSqref().size()); - assertEquals("B2:D4", ignoredError.getSqref().get(0)); - assertTrue(ignoredError.getFormula()); - assertFalse(ignoredError.getEvalError()); - - Map> ignoredErrors = sheet.getIgnoredErrors(); - assertEquals(2, ignoredErrors.size()); - assertEquals(1, ignoredErrors.get(IgnoredErrorType.FORMULA).size()); - assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.FORMULA).iterator().next().formatAsString()); - assertEquals(1, ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).size()); - assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).iterator().next().formatAsString()); - workbook.close(); - } - - @Test - public void setTabColor() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sh = wb.createSheet(); - assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor()); - sh.setTabColor(new XSSFColor(IndexedColors.RED)); - assertTrue(sh.getCTWorksheet().getSheetPr().isSetTabColor()); - assertEquals(IndexedColors.RED.index, - sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed()); - } finally { - wb.close(); - } - } - - @Test - public void getTabColor() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sh = wb.createSheet(); - assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor()); - assertNull(sh.getTabColor()); - sh.setTabColor(new XSSFColor(IndexedColors.RED)); - XSSFColor expected = new XSSFColor(IndexedColors.RED); - assertEquals(expected, sh.getTabColor()); - } finally { - wb.close(); - } - } - - // Test using an existing workbook saved by Excel - @Test - public void tabColor() throws IOException { - XSSFWorkbook wb = openSampleWorkbook("SheetTabColors.xlsx"); - try { - // non-colored sheets do not have a color - assertNull(wb.getSheet("default").getTabColor()); - - // test indexed-colored sheet - XSSFColor expected = new XSSFColor(IndexedColors.RED); - assertEquals(expected, wb.getSheet("indexedRed").getTabColor()); - - // test regular-colored (non-indexed, ARGB) sheet - expected = new XSSFColor(); - expected.setARGBHex("FF7F2700"); - assertEquals(expected, wb.getSheet("customOrange").getTabColor()); - } finally { - wb.close(); - } - } - - /** - * See bug #52425 - */ - @Test - public void testInsertCommentsToClonedSheet() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("52425.xlsx"); - CreationHelper helper = wb.getCreationHelper(); - Sheet sheet2 = wb.createSheet("Sheet 2"); - Sheet sheet3 = wb.cloneSheet(0); - wb.setSheetName(2, "Sheet 3"); - - // Adding Comment to new created Sheet 2 - addComments(helper, sheet2); - // Adding Comment to cloned Sheet 3 - addComments(helper, sheet3); - } - - private void addComments(CreationHelper helper, Sheet sheet) { - Drawing drawing = sheet.createDrawingPatriarch(); - - for (int i = 0; i < 2; i++) { - ClientAnchor anchor = helper.createClientAnchor(); - anchor.setCol1(0); - anchor.setRow1(0 + i); - anchor.setCol2(2); - anchor.setRow2(3 + i); - - Comment comment = drawing.createCellComment(anchor); - comment.setString(helper.createRichTextString("BugTesting")); - - Row row = sheet.getRow(0 + i); - if (row == null) - row = sheet.createRow(0 + i); - Cell cell = row.getCell(0); - if (cell == null) - cell = row.createCell(0); - - cell.setCellComment(comment); - } - - } - - // bug 59687: XSSFSheet.RemoveRow doesn't handle row gaps properly when removing row comments - @Test - public void testRemoveRowWithCommentAndGapAbove() throws IOException { - final Workbook wb = _testDataProvider.openSampleWorkbook("59687.xlsx"); - final Sheet sheet = wb.getSheetAt(0); - - // comment exists - CellAddress commentCellAddress = new CellAddress("A4"); - assertNotNull(sheet.getCellComment(commentCellAddress)); - - assertEquals("Wrong starting # of comments", 1, sheet.getCellComments().size()); - - sheet.removeRow(sheet.getRow(commentCellAddress.getRow())); - - assertEquals("There should not be any comments left!", 0, sheet.getCellComments().size()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetAutosizeColumn.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetAutosizeColumn.java deleted file mode 100644 index 031aadfc3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetAutosizeColumn.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.ss.usermodel.BaseTestSheetAutosizeColumn; -import org.apache.poi.xssf.XSSFITestDataProvider; - -/** - * @author Yegor Kozlov - */ -public final class TestXSSFSheetAutosizeColumn extends BaseTestSheetAutosizeColumn { - - public TestXSSFSheetAutosizeColumn(){ - super(XSSFITestDataProvider.instance); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetMergeRegions.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetMergeRegions.java deleted file mode 100644 index fb7a9c0b0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetMergeRegions.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.io.IOException; -import java.util.List; - -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.junit.Test; - -public class TestXSSFSheetMergeRegions { - @Test - public void testMergeRegionsSpeed() throws IOException { - final XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57893-many-merges.xlsx"); - try { - long millis = Long.MAX_VALUE; - - // in order to reduce the number of false positives we run it a few times before we fail, - // sometimes it fails on machines that are busy at the moment. - for(int i = 0;i < 5;i++) { - millis = runTest(wb); - if(millis < 2000) { - break; - } - System.out.println("Retry " + i + " because run-time is too high: " + millis); - } - - boolean inGump = false; - String version = System.getProperty("version.id"); - if(version != null && version.startsWith("gump-")) { - inGump = true; - } - - // This time is typically ~800ms, versus ~7800ms to iterate getMergedRegion(int). - // when running in Gump, the VM is very slow, so we should allow much more time - assertTrue("Should have taken <2000 ms to iterate 50k merged regions but took " + millis, - inGump ? millis < 8000 : millis < 2000); - } finally { - wb.close(); - } - } - - private long runTest(final XSSFWorkbook wb) { - final long start = System.currentTimeMillis(); - final XSSFSheet sheet = wb.getSheetAt(0); - final List mergedRegions = sheet.getMergedRegions(); - assertEquals(50000, mergedRegions.size()); - for (CellRangeAddress cellRangeAddress : mergedRegions) { - assertEquals(cellRangeAddress.getFirstRow(), cellRangeAddress.getLastRow()); - assertEquals(2, cellRangeAddress.getNumberOfCells()); - } - return System.currentTimeMillis() - start; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetRowGrouping.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetRowGrouping.java deleted file mode 100644 index cb8fc60c0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetRowGrouping.java +++ /dev/null @@ -1,441 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.IOException; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.XSSFTestDataSamples; - -public final class TestXSSFSheetRowGrouping extends TestCase { - - private static final int ROWS_NUMBER = 200; - private static final int GROUP_SIZE = 5; - - //private int o_groupsNumber = 0; - - public void test55640() throws IOException { - //long startTime = System.currentTimeMillis(); - Workbook wb = new XSSFWorkbook(); - fillData(wb); - writeToFile(wb); - - //System.out.println("Number of groups: " + o_groupsNumber); - //System.out.println("Execution time: " + (System.currentTimeMillis()-startTime) + " ms"); - } - - - private void fillData(Workbook p_wb) { - Sheet sheet = p_wb.createSheet("sheet123"); - sheet.setRowSumsBelow(false); - - for (int i = 0; i < ROWS_NUMBER; i++) { - Row row = sheet.createRow(i); - Cell cell = row.createCell(0); - cell.setCellValue(i+1); - } - - int i = 1; - while (i < ROWS_NUMBER) { - int end = i+(GROUP_SIZE-2); - int start = i; // natural order -// int start = end - 1; // reverse order - while (start < end) { // natural order -// while (start >= i) { // reverse order - sheet.groupRow(start, end); - //o_groupsNumber++; - boolean collapsed = isCollapsed(); - //System.out.println("Set group " + start + "->" + end + " to " + collapsed); - sheet.setRowGroupCollapsed(start, collapsed); - start++; // natural order -// start--; // reverse order - } - i += GROUP_SIZE; - } - } - - private boolean isCollapsed() { - return Math.random() > 0.5d; - } - - private void writeToFile(Workbook p_wb) throws IOException { -// FileOutputStream fileOut = new FileOutputStream("/tmp/55640.xlsx"); -// try { -// p_wb.write(fileOut); -// } finally { -// fileOut.close(); -// } - assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(p_wb)); - } - - public void test55640reduce1() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("sheet123"); - sheet.setRowSumsBelow(false); - - for (int i = 0; i < ROWS_NUMBER; i++) { - Row row = sheet.createRow(i); - Cell cell = row.createCell(0); - cell.setCellValue(i+1); - } - - int i = 1; - while (i < ROWS_NUMBER) { - int end = i+(GROUP_SIZE-2); - int start = i; // natural order - while (start < end) { // natural order - sheet.groupRow(start, end); - //o_groupsNumber++; - boolean collapsed = start % 2 == 0 ? false : true; - //System.out.println("Set group " + start + "->" + end + " to " + collapsed); - sheet.setRowGroupCollapsed(start, collapsed); - start++; // natural order - } - i += GROUP_SIZE; - } - writeToFile(wb); - } - - - public void test55640_VerifyCases() throws IOException { - // NOTE: This is currently based on current behavior of POI, somehow - // what POI returns in the calls to collapsed/hidden is not fully matching - // the examples in the spec or I did not fully understand how POI stores the data internally... - - // all expanded - verifyGroupCollapsed( - // level1, level2, level3 - false, false, false, - // collapsed: - new Boolean[] { false, false, false, false, false}, - // hidden: - new boolean[] { false, false, false, false, false}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3 } - ); - - - // Level 1 collapsed, others expanded, should only have 4 rows, all hidden: - verifyGroupCollapsed( - // level1, level2, level3 - true, false, false, - // collapsed: - new Boolean[] { false, false, false, false, false}, - // hidden: - new boolean[] { true, true, true, true, true}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3 } - ); - - // Level 1 and 2 collapsed, Level 3 expanded, - verifyGroupCollapsed( - // level1, level2, level3 - true, true, false, - // collapsed: - new Boolean[] { false, false, false, false, true, false}, - // hidden: - new boolean[] { true, true, true, true, true, false}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3, 0 } - ); - - // Level 1 collapsed, Level 2 expanded, Level 3 collapsed - verifyGroupCollapsed( - // level1, level2, level3 - true, false, true, - // collapsed: - new Boolean[] { false, false, false, false, false, true}, - // hidden: - new boolean[] { true, true, true, true, true, false}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3, 0 } - ); - - // Level 2 collapsed, others expanded: - verifyGroupCollapsed( - // level1, level2, level3 - false, true, false, - // collapsed: - new Boolean[] { false, false, false, false, false, false}, - // hidden: - new boolean[] { false, true, true, true, true, false}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3, 0 } - ); - - // Level 3 collapsed, others expanded - verifyGroupCollapsed( - // level1, level2, level3 - false, false, true, - // collapsed: - new Boolean[] { false, false, false, false, false, true}, - // hidden: - new boolean[] { false, false, true, true, true, false}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3, 0 } - ); - - // All collapsed - verifyGroupCollapsed( - // level1, level2, level3 - true, true, true, - // collapsed: - new Boolean[] { false, false, false, false, true, true}, - // hidden: - new boolean[] { true, true, true, true, true, false}, - // outlineLevel - new int[] { 1, 2, 3, 3, 3, 0 } - ); - } - - - private void verifyGroupCollapsed(boolean level1, boolean level2, boolean level3, - Boolean[] collapsed, boolean[] hidden, int[] outlineLevel) throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("sheet123"); - - for (int i = 0; i < 4; i++) { - sheet.createRow(i); - } - - sheet.groupRow(0, 4); - sheet.groupRow(1, 4); - sheet.groupRow(2, 4); - - sheet.setRowGroupCollapsed(0, level1); - sheet.setRowGroupCollapsed(1, level2); - sheet.setRowGroupCollapsed(2, level3); - - checkWorkbookGrouping(wb, collapsed, hidden, outlineLevel); - } - - public void test55640_VerifyCasesSpec() throws IOException { - // NOTE: This is currently based on current behavior of POI, somehow - // what POI returns in the calls to collapsed/hidden is not fully matching - // the examples in the spec or I did not fully understand how POI stores the data internally... - - // all expanded - verifyGroupCollapsedSpec( - // level3, level2, level1 - false, false, false, - // collapsed: - new Boolean[] { false, false, false, false}, - // hidden: - new boolean[] { false, false, false, false}, - // outlineLevel - new int[] { 3, 3, 2, 1 } - ); - - - verifyGroupCollapsedSpec( - // level3, level2, level1 - false, false, true, - // collapsed: - new Boolean[] { false, false, false, true}, - // hidden: - new boolean[] { true, true, true, false}, - // outlineLevel - new int[] { 3, 3, 2, 1 } - ); - - verifyGroupCollapsedSpec( - // level3, level2, level1 - false, true, false, - // collapsed: - new Boolean[] { false, false, true, false}, - // hidden: - new boolean[] { true, true, true, false}, - // outlineLevel - new int[] { 3, 3, 2, 1 } - ); - - verifyGroupCollapsedSpec( - // level3, level2, level1 - false, true, true, - // collapsed: - new Boolean[] { false, false, true, true}, - // hidden: - new boolean[] { true, true, true, false}, - // outlineLevel - new int[] { 3, 3, 2, 1 } - ); - } - - private void verifyGroupCollapsedSpec(boolean level1, boolean level2, boolean level3, - Boolean[] collapsed, boolean[] hidden, int[] outlineLevel) throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("sheet123"); - - for (int i = 5; i < 9; i++) { - sheet.createRow(i); - } - - sheet.groupRow(5, 6); - sheet.groupRow(5, 7); - sheet.groupRow(5, 8); - - sheet.setRowGroupCollapsed(6, level1); - sheet.setRowGroupCollapsed(7, level2); - sheet.setRowGroupCollapsed(8, level3); - - checkWorkbookGrouping(wb, collapsed, hidden, outlineLevel); - } - - private void checkWorkbookGrouping(Workbook wb, Boolean[] collapsed, boolean[] hidden, int[] outlineLevel) throws IOException { - printWorkbook(wb); - Sheet sheet = wb.getSheetAt(0); - - assertEquals(collapsed.length, hidden.length); - assertEquals(collapsed.length, outlineLevel.length); - assertEquals("Expected " + collapsed.length + " rows with collapsed state, but had " + (sheet.getLastRowNum()-sheet.getFirstRowNum()+1) + " rows (" - + sheet.getFirstRowNum() + "-" + sheet.getLastRowNum() + ")", - collapsed.length, sheet.getLastRowNum()-sheet.getFirstRowNum()+1); - for(int i = sheet.getFirstRowNum(); i < sheet.getLastRowNum();i++) { - if(collapsed[i-sheet.getFirstRowNum()] == null) { - continue; - } - XSSFRow row = (XSSFRow) sheet.getRow(i); - assertNotNull("Could not read row " + i, row); - assertNotNull("Could not read row " + i, row.getCTRow()); - assertEquals("Row: " + i + ": collapsed", collapsed[i-sheet.getFirstRowNum()].booleanValue(), row.getCTRow().getCollapsed()); - assertEquals("Row: " + i + ": hidden", hidden[i-sheet.getFirstRowNum()], row.getCTRow().getHidden()); - - assertEquals("Row: " + i + ": level", outlineLevel[i-sheet.getFirstRowNum()], row.getCTRow().getOutlineLevel()); - } - - writeToFile(wb); - } - - - public void test55640working() throws IOException { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("sheet123"); - - sheet.groupRow(1, 4); - sheet.groupRow(2, 5); - sheet.groupRow(3, 6); - - sheet.setRowGroupCollapsed(1, true); - sheet.setRowGroupCollapsed(2, false); - sheet.setRowGroupCollapsed(3, false); - - writeToFile(wb); - } - - // just used for printing out contents of spreadsheets - public void notRuntest55640printSample() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55640.xlsx"); - printWorkbook(wb); - - wb = XSSFTestDataSamples.openSampleWorkbook("GroupTest.xlsx"); - printWorkbook(wb); - } - - private void printWorkbook(Workbook wb) { - // disable all output for now... -// Sheet sheet = wb.getSheetAt(0); -// -// for(Iterator it = sheet.rowIterator();it.hasNext();) { -// XSSFRow row = (XSSFRow) it.next(); -// boolean collapsed = row.getCTRow().getCollapsed(); -// boolean hidden = row.getCTRow().getHidden(); -// short level = row.getCTRow().getOutlineLevel(); -// -// System.out.println("Row: " + row.getRowNum() + ": Level: " + level + " Collapsed: " + collapsed + " Hidden: " + hidden); -// } - } - - public void testGroupingTest() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("GroupTest.xlsx"); - - assertEquals(31, wb.getSheetAt(0).getLastRowNum()); - - // NOTE: This is currently based on current behavior of POI, somehow - // what POI returns in the calls to collapsed/hidden is not fully matching - // the examples in the spec or I did not fully understand how POI stores the data internally... - checkWorkbookGrouping(wb, - new Boolean [] { - // 0-4 - false, false, false, false, false, null, null, - // 7-11 - false, false, true, true, true, null, null, - // 14-18 - false, false, true, false, false, null, - // 20-24 - false, false, true, true, false, null, null, - // 27-31 - false, false, false, true, false }, - new boolean[] { - // 0-4 - false, false, false, false, false, false, false, - // 7-11 - true, true, true, true, false, false, false, - // 14-18 - true, true, false, false, false, false, - // 20-24 - true, true, true, false, false, false, false, - // 27-31 - true, true, true, true, false }, - // outlineLevel - new int[] { - // 0-4 - 3, 3, 2, 1, 0, 0, 0, - // 7-11 - 3, 3, 2, 1, 0, 0, 0, - // 14-18 - 3, 3, 2, 1, 0, 0, - // 20-24 - 3, 3, 2, 1, 0, 0, 0, - // 27-31 - 3, 3, 2, 1, 0, - } - ); - /* -Row: 0: Level: 3 Collapsed: false Hidden: false -Row: 1: Level: 3 Collapsed: false Hidden: false -Row: 2: Level: 2 Collapsed: false Hidden: false -Row: 3: Level: 1 Collapsed: false Hidden: false -Row: 4: Level: 0 Collapsed: false Hidden: false -Row: 7: Level: 3 Collapsed: false Hidden: true -Row: 8: Level: 3 Collapsed: false Hidden: true -Row: 9: Level: 2 Collapsed: true Hidden: true -Row: 10: Level: 1 Collapsed: true Hidden: true -Row: 11: Level: 0 Collapsed: true Hidden: false -Row: 14: Level: 3 Collapsed: false Hidden: true -Row: 15: Level: 3 Collapsed: false Hidden: true -Row: 16: Level: 2 Collapsed: true Hidden: false -Row: 17: Level: 1 Collapsed: false Hidden: false -Row: 18: Level: 0 Collapsed: false Hidden: false -Row: 20: Level: 3 Collapsed: false Hidden: true -Row: 21: Level: 3 Collapsed: false Hidden: true -Row: 22: Level: 2 Collapsed: true Hidden: true -Row: 23: Level: 1 Collapsed: true Hidden: false -Row: 24: Level: 0 Collapsed: false Hidden: false -Row: 27: Level: 3 Collapsed: false Hidden: true -Row: 28: Level: 3 Collapsed: false Hidden: true -Row: 29: Level: 2 Collapsed: false Hidden: true -Row: 30: Level: 1 Collapsed: true Hidden: true -Row: 31: Level: 0 Collapsed: true Hidden: false - */ - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java deleted file mode 100644 index fa4c77fbf..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java +++ /dev/null @@ -1,452 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.poi.POITestCase.skipTest; -import static org.apache.poi.POITestCase.testPassesNow; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellUtil; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.xmlbeans.impl.values.XmlValueDisconnectedException; -import org.junit.Test; - -public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { - - public TestXSSFSheetShiftRows(){ - super(XSSFITestDataProvider.instance); - } - - @Override - @Test - public void testShiftRowBreaks() { - // disabled test from superclass - // TODO - support shifting of page breaks - } - - /** Error occurred at FormulaShifter#rowMoveAreaPtg while shift rows upward. */ - @Test - public void testBug54524() throws IOException { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("54524.xlsx"); - XSSFSheet sheet = workbook.getSheetAt(0); - sheet.shiftRows(3, 5, -1); - - Cell cell = CellUtil.getCell(sheet.getRow(1), 0); - assertEquals(1.0, cell.getNumericCellValue(), 0); - cell = CellUtil.getCell(sheet.getRow(2), 0); - assertEquals("SUM(A2:A2)", cell.getCellFormula()); - cell = CellUtil.getCell(sheet.getRow(3), 0); - assertEquals("X", cell.getStringCellValue()); - workbook.close(); - } - - /** negative row shift causes corrupted data or throws exception */ - @Test - public void testBug53798() throws IOException { - // NOTE that for HSSF (.xls) negative shifts combined with positive ones do work as expected - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53798.xlsx"); - - Sheet testSheet = wb.getSheetAt(0); - // 1) corrupted xlsx (unreadable data in the first row of a shifted group) already comes about - // when shifted by less than -1 negative amount (try -2) - testSheet.shiftRows(3, 3, -2); - - // 2) attempt to create a new row IN PLACE of a removed row by a negative shift causes corrupted - // xlsx file with unreadable data in the negative shifted row. - // NOTE it's ok to create any other row. - Row newRow = testSheet.createRow(3); - Cell newCell = newRow.createCell(0); - newCell.setCellValue("new Cell in row "+newRow.getRowNum()); - - // 3) once a negative shift has been made any attempt to shift another group of rows - // (note: outside of previously negative shifted rows) by a POSITIVE amount causes POI exception: - // org.apache.xmlbeans.impl.values.XmlValueDisconnectedException. - // NOTE: another negative shift on another group of rows is successful, provided no new rows in - // place of previously shifted rows were attempted to be created as explained above. - - // -- CHANGE the shift to positive once the behaviour of the above has been tested - testSheet.shiftRows(6, 7, 1); - - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(wb); - wb.close(); - assertNotNull(read); - - Sheet readSheet = read.getSheetAt(0); - verifyCellContent(readSheet, 0, "0.0"); - verifyCellContent(readSheet, 1, "3.0"); - verifyCellContent(readSheet, 2, "2.0"); - verifyCellContent(readSheet, 3, "new Cell in row 3"); - verifyCellContent(readSheet, 4, "4.0"); - verifyCellContent(readSheet, 5, "5.0"); - verifyCellContent(readSheet, 6, null); - verifyCellContent(readSheet, 7, "6.0"); - verifyCellContent(readSheet, 8, "7.0"); - read.close(); - } - - private void verifyCellContent(Sheet readSheet, int row, String expect) { - Row readRow = readSheet.getRow(row); - if(expect == null) { - assertNull(readRow); - return; - } - Cell readCell = readRow.getCell(0); - //noinspection deprecation - if(readCell.getCellTypeEnum() == CellType.NUMERIC) { - assertEquals(expect, Double.toString(readCell.getNumericCellValue())); - } else { - assertEquals(expect, readCell.getStringCellValue()); - } - } - - /** negative row shift causes corrupted data or throws exception */ - @Test - public void testBug53798a() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53798.xlsx"); - - Sheet testSheet = wb.getSheetAt(0); - testSheet.shiftRows(3, 3, -1); - for (Row r : testSheet) { - r.getRowNum(); - } - testSheet.shiftRows(6, 6, 1); - - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(wb); - wb.close(); - assertNotNull(read); - - Sheet readSheet = read.getSheetAt(0); - verifyCellContent(readSheet, 0, "0.0"); - verifyCellContent(readSheet, 1, "1.0"); - verifyCellContent(readSheet, 2, "3.0"); - verifyCellContent(readSheet, 3, null); - verifyCellContent(readSheet, 4, "4.0"); - verifyCellContent(readSheet, 5, "5.0"); - verifyCellContent(readSheet, 6, null); - verifyCellContent(readSheet, 7, "6.0"); - verifyCellContent(readSheet, 8, "8.0"); - read.close(); - } - - /** Shifting rows with comment result - Unreadable content error and comment deletion */ - @Test - public void testBug56017() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56017.xlsx"); - - Sheet sheet = wb.getSheetAt(0); - - Comment comment = sheet.getCellComment(new CellAddress(0, 0)); - assertNotNull(comment); - assertEquals("Amdocs", comment.getAuthor()); - assertEquals("Amdocs:\ntest\n", comment.getString().getString()); - - sheet.shiftRows(0, 1, 1); - - // comment in row 0 is gone - comment = sheet.getCellComment(new CellAddress(0, 0)); - assertNull(comment); - - // comment is now in row 1 - comment = sheet.getCellComment(new CellAddress(1, 0)); - assertNotNull(comment); - assertEquals("Amdocs", comment.getAuthor()); - assertEquals("Amdocs:\ntest\n", comment.getString().getString()); - - Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); - wb.close(); - assertNotNull(wbBack); - - Sheet sheetBack = wbBack.getSheetAt(0); - - // comment in row 0 is gone - comment = sheetBack.getCellComment(new CellAddress(0, 0)); - assertNull(comment); - - // comment is now in row 1 - comment = sheetBack.getCellComment(new CellAddress(1, 0)); - assertNotNull(comment); - assertEquals("Amdocs", comment.getAuthor()); - assertEquals("Amdocs:\ntest\n", comment.getString().getString()); - wbBack.close(); - } - - /** Moving the active sheet and deleting the others results in a corrupted file */ - @Test - public void test57171() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - assertEquals(5, wb.getActiveSheetIndex()); - removeAllSheetsBut(5, wb); // 5 is the active / selected sheet - assertEquals(0, wb.getActiveSheetIndex()); - - Workbook wbRead = XSSFTestDataSamples.writeOutAndReadBack(wb); - wb.close(); - assertEquals(0, wbRead.getActiveSheetIndex()); - - wbRead.removeSheetAt(0); - assertEquals(0, wbRead.getActiveSheetIndex()); - - wbRead.close(); - } - - /** Cannot delete an arbitrary sheet in an XLS workbook (only the last one) */ - @Test - public void test57163() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - assertEquals(5, wb.getActiveSheetIndex()); - wb.removeSheetAt(0); - assertEquals(4, wb.getActiveSheetIndex()); - - wb.close(); - } - - @Test - public void testSetSheetOrderAndAdjustActiveSheet() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - - assertEquals(5, wb.getActiveSheetIndex()); - - // move the sheets around in all possible combinations to check that the active sheet - // is set correctly in all cases - wb.setSheetOrder(wb.getSheetName(5), 4); - assertEquals(4, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(5), 5); - assertEquals(4, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(3), 5); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(4), 5); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(2), 2); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(2), 1); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(3), 5); - assertEquals(5, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(0), 5); - assertEquals(4, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(0), 5); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(0), 5); - assertEquals(2, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(0), 5); - assertEquals(1, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(0), 5); - assertEquals(0, wb.getActiveSheetIndex()); - - wb.setSheetOrder(wb.getSheetName(0), 5); - assertEquals(5, wb.getActiveSheetIndex()); - - wb.close(); - } - - @Test - public void testRemoveSheetAndAdjustActiveSheet() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - - assertEquals(5, wb.getActiveSheetIndex()); - - wb.removeSheetAt(0); - assertEquals(4, wb.getActiveSheetIndex()); - - wb.setActiveSheet(3); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.removeSheetAt(4); - assertEquals(3, wb.getActiveSheetIndex()); - - wb.removeSheetAt(3); - assertEquals(2, wb.getActiveSheetIndex()); - - wb.removeSheetAt(0); - assertEquals(1, wb.getActiveSheetIndex()); - - wb.removeSheetAt(1); - assertEquals(0, wb.getActiveSheetIndex()); - - wb.removeSheetAt(0); - assertEquals(0, wb.getActiveSheetIndex()); - - try { - wb.removeSheetAt(0); - fail("Should catch exception as no more sheets are there"); - } catch (IllegalArgumentException e) { - // expected - } - assertEquals(0, wb.getActiveSheetIndex()); - - wb.createSheet(); - assertEquals(0, wb.getActiveSheetIndex()); - - wb.removeSheetAt(0); - assertEquals(0, wb.getActiveSheetIndex()); - - wb.close(); - } - - /** Failed to clone a sheet from an Excel 2010 */ - @Test - public void test57165() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); - assertEquals(5, wb.getActiveSheetIndex()); - removeAllSheetsBut(3, wb); - assertEquals(0, wb.getActiveSheetIndex()); - wb.createSheet("New Sheet1"); - assertEquals(0, wb.getActiveSheetIndex()); - wb.cloneSheet(0); // Throws exception here - wb.setSheetName(1, "New Sheet"); - assertEquals(0, wb.getActiveSheetIndex()); - - wb.close(); - } - - private static void removeAllSheetsBut(int sheetIndex, Workbook wb) { - int sheetNb = wb.getNumberOfSheets(); - // Move this sheet at the first position - wb.setSheetOrder(wb.getSheetName(sheetIndex), 0); - // Must make this sheet active (otherwise, for XLSX, Excel might protest that active sheet no longer exists) - // I think POI should automatically handle this case when deleting sheets... - // wb.setActiveSheet(0); - for (int sn = sheetNb - 1; sn > 0; sn--) { - wb.removeSheetAt(sn); - } - } - - /** Shifting rows with cell comments only shifts comments from first such cell. Other cell comments not shifted */ - @Test - public void testBug57828_OnlyOneCommentShiftedInRow() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57828.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - - Comment comment1 = sheet.getCellComment(new CellAddress(2, 1)); - assertNotNull(comment1); - - Comment comment2 = sheet.getCellComment(new CellAddress(2, 2)); - assertNotNull(comment2); - - Comment comment3 = sheet.getCellComment(new CellAddress(1, 1)); - assertNull("NO comment in (1,1) and it should be null", comment3); - - sheet.shiftRows(2, 2, -1); - - comment3 = sheet.getCellComment(new CellAddress(1, 1)); - assertNotNull("Comment in (2,1) moved to (1,1) so its not null now.", comment3); - - comment1 = sheet.getCellComment(new CellAddress(2, 1)); - assertNull("No comment currently in (2,1) and hence it is null", comment1); - - comment2 = sheet.getCellComment(new CellAddress(1, 2)); - assertNotNull("Comment in (2,2) should have moved as well because of shift rows. But its not", comment2); - - wb.close(); - } - - // This test is written as expected-to-fail and should be rewritten - // as expected-to-pass when the bug is fixed. - //@Ignore("Bug 59733 - shiftRows() causes org.apache.xmlbeans.impl.values.XmlValueDisconnectedException") - @Test - public void bug59733() throws IOException { - Workbook workbook = new XSSFWorkbook(); - Sheet sheet = workbook.createSheet(); - for (int r=0; r<4; r++) { - sheet.createRow(r); - } - - // Shift the 2nd row on top of the 0th row - sheet.shiftRows(2, 2, -2); - - /* - * The following error is thrown when shifting the 3rd row on top of the 0th row - * If the rows are not created, the error does not occur - - org.apache.xmlbeans.impl.values.XmlValueDisconnectedException - at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258) - at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.getR(Unknown Source) - at org.apache.poi.xssf.usermodel.XSSFRow.getRowNum(XSSFRow.java:363) - at org.apache.poi.xssf.usermodel.TestXSSFSheetShiftRows.bug59733(TestXSSFSheetShiftRows.java:393) - */ - // FIXME: remove try, catch, and testPassesNow, skipTest when test passes - try { - sheet.removeRow(sheet.getRow(0)); - assertEquals(1, sheet.getRow(1).getRowNum()); - testPassesNow(59733); - } catch (XmlValueDisconnectedException e) { - skipTest(e); - } - - - workbook.close(); - } - - private static String getCellFormula(Sheet sheet, String address) { - CellAddress cellAddress = new CellAddress(address); - Row row = sheet.getRow(cellAddress.getRow()); - assertNotNull(row); - Cell cell = row.getCell(cellAddress.getColumn()); - assertNotNull(cell); - assertEquals(CellType.FORMULA, cell.getCellTypeEnum()); - return cell.getCellFormula(); - } - - // This test is written as expected-to-fail and should be rewritten - // as expected-to-pass when the bug is fixed. - @Test - public void testSharedFormulas() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("TestShiftRowSharedFormula.xlsx"); - XSSFSheet sheet = wb.getSheetAt(0); - assertEquals("SUM(C2:C4)", getCellFormula(sheet, "C5")); - assertEquals("SUM(D2:D4)", getCellFormula(sheet, "D5")); - assertEquals("SUM(E2:E4)", getCellFormula(sheet, "E5")); - - sheet.shiftRows(3, sheet.getLastRowNum(), 1); - // FIXME: remove try, catch, and testPassesNow, skipTest when test passes - try { - assertEquals("SUM(C2:C5)", getCellFormula(sheet, "C6")); - assertEquals("SUM(D2:D5)", getCellFormula(sheet, "D6")); - assertEquals("SUM(E2:E5)", getCellFormula(sheet, "E6")); - testPassesNow(59983); - } catch (AssertionError e) { - skipTest(e); - } - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetUpdateArrayFormulas.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetUpdateArrayFormulas.java deleted file mode 100644 index 85378ec2b..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetUpdateArrayFormulas.java +++ /dev/null @@ -1,122 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.BaseTestSheetUpdateArrayFormulas; -import org.apache.poi.ss.usermodel.CellRange; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; - -import junit.framework.AssertionFailedError; -/** - * Test array formulas in XSSF - * - * @author Yegor Kozlov - * @author Josh Micich - */ -public final class TestXSSFSheetUpdateArrayFormulas extends BaseTestSheetUpdateArrayFormulas { - - public TestXSSFSheetUpdateArrayFormulas() { - super(XSSFITestDataProvider.instance); - } - - // Test methods common with HSSF are in superclass - // Local methods here test XSSF-specific details of updating array formulas - @Test - public void testXSSFSetArrayFormula_singleCell() throws IOException { - CellRange cells; - - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - - // 1. single-cell array formula - String formula1 = "123"; - CellRangeAddress range = CellRangeAddress.valueOf("C3:C3"); - cells = sheet.setArrayFormula(formula1, range); - assertEquals(1, cells.size()); - - // check getFirstCell... - XSSFCell firstCell = cells.getTopLeftCell(); - assertSame(firstCell, sheet.getFirstCellInArrayFormula(firstCell)); - //retrieve the range and check it is the same - assertEquals(range.formatAsString(), firstCell.getArrayFormulaRange().formatAsString()); - confirmArrayFormulaCell(firstCell, "C3", formula1, "C3"); - - workbook.close(); - } - - @Test - public void testXSSFSetArrayFormula_multiCell() throws IOException { - CellRange cells; - - String formula2 = "456"; - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - - CellRangeAddress range = CellRangeAddress.valueOf("C4:C6"); - cells = sheet.setArrayFormula(formula2, range); - assertEquals(3, cells.size()); - - // sheet.setArrayFormula creates rows and cells for the designated range - /* - * From the spec: - * For a multi-cell formula, the c elements for all cells except the top-left - * cell in that range shall not have an f element; - */ - // Check that each cell exists and that the formula text is set correctly on the first cell - XSSFCell firstCell = cells.getTopLeftCell(); - confirmArrayFormulaCell(firstCell, "C4", formula2, "C4:C6"); - confirmArrayFormulaCell(cells.getCell(1, 0), "C5"); - confirmArrayFormulaCell(cells.getCell(2, 0), "C6"); - - assertSame(firstCell, sheet.getFirstCellInArrayFormula(firstCell)); - workbook.close(); - } - - private static void confirmArrayFormulaCell(XSSFCell c, String cellRef) { - confirmArrayFormulaCell(c, cellRef, null, null); - } - private static void confirmArrayFormulaCell(XSSFCell c, String cellRef, String formulaText, String arrayRangeRef) { - if (c == null) { - throw new AssertionFailedError("Cell should not be null."); - } - CTCell ctCell = c.getCTCell(); - assertEquals(cellRef, ctCell.getR()); - if (formulaText == null) { - assertFalse(ctCell.isSetF()); - assertNull(ctCell.getF()); - } else { - CTCellFormula f = ctCell.getF(); - assertEquals(arrayRangeRef, f.getRef()); - assertEquals(formulaText, f.getStringValue()); - assertEquals(STCellFormulaType.ARRAY, f.getT()); - } - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java deleted file mode 100644 index e9eebe68e..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSimpleShape.java +++ /dev/null @@ -1,172 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.awt.Color; -import java.io.IOException; - -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.junit.Test; - -public class TestXSSFSimpleShape { - @Test - public void testXSSFTextParagraph() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - - XSSFRichTextString rt = new XSSFRichTextString("Test String"); - - XSSFFont font = wb.createFont(); - Color color = new Color(0, 255, 255); - font.setColor(new XSSFColor(color)); - font.setFontName("Arial"); - rt.applyFont(font); - - shape.setText(rt); - - assertNotNull(shape.getCTShape()); - assertNotNull(shape.iterator()); - assertNotNull(XSSFSimpleShape.prototype()); - - for(ListAutoNumber nr : ListAutoNumber.values()) { - shape.getTextParagraphs().get(0).setBullet(nr); - assertNotNull(shape.getText()); - } - - shape.getTextParagraphs().get(0).setBullet(false); - assertNotNull(shape.getText()); - - shape.setText("testtext"); - assertEquals("testtext", shape.getText()); - - shape.setText(new XSSFRichTextString()); - assertEquals("null", shape.getText()); - - shape.addNewTextParagraph(); - shape.addNewTextParagraph("test-other-text"); - shape.addNewTextParagraph(new XSSFRichTextString("rtstring")); - shape.addNewTextParagraph(new XSSFRichTextString()); - assertEquals("null\n\ntest-other-text\nrtstring\nnull", shape.getText()); - - assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); - shape.setTextHorizontalOverflow(TextHorizontalOverflow.CLIP); - assertEquals(TextHorizontalOverflow.CLIP, shape.getTextHorizontalOverflow()); - shape.setTextHorizontalOverflow(TextHorizontalOverflow.OVERFLOW); - assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); - shape.setTextHorizontalOverflow(null); - assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); - shape.setTextHorizontalOverflow(null); - assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); - - assertEquals(TextVerticalOverflow.OVERFLOW, shape.getTextVerticalOverflow()); - shape.setTextVerticalOverflow(TextVerticalOverflow.CLIP); - assertEquals(TextVerticalOverflow.CLIP, shape.getTextVerticalOverflow()); - shape.setTextVerticalOverflow(TextVerticalOverflow.OVERFLOW); - assertEquals(TextVerticalOverflow.OVERFLOW, shape.getTextVerticalOverflow()); - shape.setTextVerticalOverflow(null); - assertEquals(TextVerticalOverflow.OVERFLOW, shape.getTextVerticalOverflow()); - shape.setTextVerticalOverflow(null); - assertEquals(TextVerticalOverflow.OVERFLOW, shape.getTextVerticalOverflow()); - - assertEquals(VerticalAlignment.TOP, shape.getVerticalAlignment()); - shape.setVerticalAlignment(VerticalAlignment.BOTTOM); - assertEquals(VerticalAlignment.BOTTOM, shape.getVerticalAlignment()); - shape.setVerticalAlignment(VerticalAlignment.TOP); - assertEquals(VerticalAlignment.TOP, shape.getVerticalAlignment()); - shape.setVerticalAlignment(null); - assertEquals(VerticalAlignment.TOP, shape.getVerticalAlignment()); - shape.setVerticalAlignment(null); - assertEquals(VerticalAlignment.TOP, shape.getVerticalAlignment()); - - assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection()); - shape.setTextDirection(TextDirection.STACKED); - assertEquals(TextDirection.STACKED, shape.getTextDirection()); - shape.setTextDirection(TextDirection.HORIZONTAL); - assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection()); - shape.setTextDirection(null); - assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection()); - shape.setTextDirection(null); - assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection()); - - assertEquals(3.6, shape.getBottomInset(), 0.01); - shape.setBottomInset(12.32); - assertEquals(12.32, shape.getBottomInset(), 0.01); - shape.setBottomInset(-1); - assertEquals(3.6, shape.getBottomInset(), 0.01); - shape.setBottomInset(-1); - assertEquals(3.6, shape.getBottomInset(), 0.01); - - assertEquals(3.6, shape.getLeftInset(), 0.01); - shape.setLeftInset(12.31); - assertEquals(12.31, shape.getLeftInset(), 0.01); - shape.setLeftInset(-1); - assertEquals(3.6, shape.getLeftInset(), 0.01); - shape.setLeftInset(-1); - assertEquals(3.6, shape.getLeftInset(), 0.01); - - assertEquals(3.6, shape.getRightInset(), 0.01); - shape.setRightInset(13.31); - assertEquals(13.31, shape.getRightInset(), 0.01); - shape.setRightInset(-1); - assertEquals(3.6, shape.getRightInset(), 0.01); - shape.setRightInset(-1); - assertEquals(3.6, shape.getRightInset(), 0.01); - - assertEquals(3.6, shape.getTopInset(), 0.01); - shape.setTopInset(23.31); - assertEquals(23.31, shape.getTopInset(), 0.01); - shape.setTopInset(-1); - assertEquals(3.6, shape.getTopInset(), 0.01); - shape.setTopInset(-1); - assertEquals(3.6, shape.getTopInset(), 0.01); - - assertTrue(shape.getWordWrap()); - shape.setWordWrap(false); - assertFalse(shape.getWordWrap()); - shape.setWordWrap(true); - assertTrue(shape.getWordWrap()); - - assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); - shape.setTextAutofit(TextAutofit.NORMAL); - assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); - shape.setTextAutofit(TextAutofit.SHAPE); - assertEquals(TextAutofit.SHAPE, shape.getTextAutofit()); - shape.setTextAutofit(TextAutofit.NONE); - assertEquals(TextAutofit.NONE, shape.getTextAutofit()); - - assertEquals(5, shape.getShapeType()); - shape.setShapeType(23); - assertEquals(23, shape.getShapeType()); - - // TODO: should this be supported? -// shape.setShapeType(-1); -// assertEquals(-1, shape.getShapeType()); -// shape.setShapeType(-1); -// assertEquals(-1, shape.getShapeType()); - - assertNotNull(shape.getShapeProperties()); - } finally { - wb.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java deleted file mode 100644 index 69b412a51..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ /dev/null @@ -1,290 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleInfo; - -public final class TestXSSFTable { - - @Test - public void bug56274() throws IOException { - // read sample file - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("56274.xlsx"); - - // read the original sheet header order - XSSFRow row = wb1.getSheetAt(0).getRow(0); - List headers = new ArrayList(); - for (Cell cell : row) { - headers.add(cell.getStringCellValue()); - } - - // save the worksheet as-is using SXSSF - File outputFile = TempFile.createTempFile("poi-56274", ".xlsx"); - SXSSFWorkbook outputWorkbook = new SXSSFWorkbook(wb1); - FileOutputStream fos = new FileOutputStream(outputFile); - outputWorkbook.write(fos); - fos.close(); - outputWorkbook.close(); - - // re-read the saved file and make sure headers in the xml are in the original order - FileInputStream fis = new FileInputStream(outputFile); - XSSFWorkbook wb2 = new XSSFWorkbook(fis); - fis.close(); - CTTable ctTable = wb2.getSheetAt(0).getTables().get(0).getCTTable(); - CTTableColumn[] ctTableColumnArray = ctTable.getTableColumns().getTableColumnArray(); - - assertEquals("number of headers in xml table should match number of header cells in worksheet", - headers.size(), ctTableColumnArray.length); - for (int i = 0; i < headers.size(); i++) { - assertEquals("header name in xml table should match number of header cells in worksheet", - headers.get(i), ctTableColumnArray[i].getName()); - } - assertTrue(outputFile.delete()); - wb2.close(); - wb1.close(); - } - - @Test - public void testCTTableStyleInfo() throws IOException { - XSSFWorkbook outputWorkbook = new XSSFWorkbook(); - XSSFSheet sheet = outputWorkbook.createSheet(); - - //Create - XSSFTable outputTable = sheet.createTable(); - outputTable.setDisplayName("Test"); - CTTable outputCTTable = outputTable.getCTTable(); - - //Style configurations - CTTableStyleInfo outputStyleInfo = outputCTTable.addNewTableStyleInfo(); - outputStyleInfo.setName("TableStyleLight1"); - outputStyleInfo.setShowColumnStripes(false); - outputStyleInfo.setShowRowStripes(true); - - XSSFWorkbook inputWorkbook = XSSFTestDataSamples.writeOutAndReadBack(outputWorkbook); - List tables = inputWorkbook.getSheetAt(0).getTables(); - assertEquals("Tables number", 1, tables.size()); - - XSSFTable inputTable = tables.get(0); - assertEquals("Table display name", outputTable.getDisplayName(), inputTable.getDisplayName()); - - CTTableStyleInfo inputStyleInfo = inputTable.getCTTable().getTableStyleInfo(); - assertEquals("Style name", outputStyleInfo.getName(), inputStyleInfo.getName()); - assertEquals("Show column stripes", - outputStyleInfo.getShowColumnStripes(), inputStyleInfo.getShowColumnStripes()); - assertEquals("Show row stripes", - outputStyleInfo.getShowRowStripes(), inputStyleInfo.getShowRowStripes()); - - inputWorkbook.close(); - outputWorkbook.close(); - } - - @Test - public void findColumnIndex() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - - XSSFTable table = wb.getTable("\\_Prime.1"); - assertNotNull(table); - assertEquals("column header has special escaped characters", - 0, table.findColumnIndex("calc='#*'#")); - assertEquals(1, table.findColumnIndex("Name")); - assertEquals(2, table.findColumnIndex("Number")); - - assertEquals("case insensitive", 2, table.findColumnIndex("NuMbEr")); - - // findColumnIndex should return -1 if no column header name matches - assertEquals(-1, table.findColumnIndex(null)); - assertEquals(-1, table.findColumnIndex("")); - assertEquals(-1, table.findColumnIndex("one")); - - wb.close(); - } - - @Test - public void findColumnIndexIsRelativeToTableNotSheet() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("DataTableCities.xlsx"); - XSSFTable table = wb.getTable("SmallCity"); - - // Make sure that XSSFTable.findColumnIndex returns the column index relative to the first - // column in the table, not the column number in the sheet - assertEquals(0, table.findColumnIndex("City")); // column I in worksheet but 0th column in table - assertEquals(1, table.findColumnIndex("Latitude")); - assertEquals(2, table.findColumnIndex("Longitude")); - assertEquals(3, table.findColumnIndex("Population")); - - wb.close(); - } - - @Test - public void getSheetName() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals("Table", table.getSheetName()); - wb.close(); - } - - @Test - public void isHasTotalsRow() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertFalse(table.isHasTotalsRow()); - wb.close(); - } - - @Test - public void getStartColIndex() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(0, table.getStartColIndex()); - wb.close(); - } - - @Test - public void getEndColIndex() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(2, table.getEndColIndex()); - wb.close(); - } - - @Test - public void getStartRowIndex() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(0, table.getStartRowIndex()); - wb.close(); - } - - @Test - public void getEndRowIndex() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(6, table.getEndRowIndex()); - wb.close(); - } - - @Test - public void getStartCellReference() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(new CellReference("A1"), table.getStartCellReference()); - wb.close(); - } - - @Test - public void getEndCellReference() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(new CellReference("C7"), table.getEndCellReference()); - wb.close(); - } - - @Test - public void getNumberOfMappedColumns() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals(3, table.getNumberOfMappedColumns()); - wb.close(); - } - - @Test - public void getAndSetDisplayName() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx"); - XSSFTable table = wb.getTable("\\_Prime.1"); - assertEquals("\\_Prime.1", table.getDisplayName()); - - table.setDisplayName(null); - assertNull(table.getDisplayName()); - assertEquals("\\_Prime.1", table.getName()); // name and display name are different - - table.setDisplayName("Display name"); - assertEquals("Display name", table.getDisplayName()); - assertEquals("\\_Prime.1", table.getName()); // name and display name are different - - wb.close(); - } - - @Test - public void getCellReferences() { - // make sure that cached start and end cell references - // can be synchronized with the underlying CTTable - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sh = wb.createSheet(); - XSSFTable table = sh.createTable(); - CTTable ctTable = table.getCTTable(); - ctTable.setRef("B2:E8"); - - assertEquals(new CellReference("B2"), table.getStartCellReference()); - assertEquals(new CellReference("E8"), table.getEndCellReference()); - - // At this point start and end cell reference are cached - // and may not follow changes to the underlying CTTable - ctTable.setRef("C1:M3"); - - assertEquals(new CellReference("B2"), table.getStartCellReference()); - assertEquals(new CellReference("E8"), table.getEndCellReference()); - - // Force a synchronization between CTTable and XSSFTable - // start and end cell references - table.updateReferences(); - - assertEquals(new CellReference("C1"), table.getStartCellReference()); - assertEquals(new CellReference("M3"), table.getEndCellReference()); - - } - - @Test - public void getRowCount() { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sh = wb.createSheet(); - XSSFTable table = sh.createTable(); - CTTable ctTable = table.getCTTable(); - - assertEquals(0, table.getRowCount()); - - ctTable.setRef("B2:B2"); - // update cell references to clear the cache - table.updateReferences(); - assertEquals(1, table.getRowCount()); - - ctTable.setRef("B2:B12"); - // update cell references to clear the cache - table.updateReferences(); - assertEquals(11, table.getRowCount()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTextParagraph.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTextParagraph.java deleted file mode 100644 index 7952f1f01..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTextParagraph.java +++ /dev/null @@ -1,198 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.awt.Color; -import java.io.IOException; -import java.util.List; - -import org.junit.Test; - -public class TestXSSFTextParagraph { - @Test - public void testXSSFTextParagraph() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - XSSFRichTextString rt = new XSSFRichTextString("Test String"); - - XSSFFont font = wb.createFont(); - Color color = new Color(0, 255, 255); - font.setColor(new XSSFColor(color)); - font.setFontName("Arial"); - rt.applyFont(font); - - shape.setText(rt); - - List paras = shape.getTextParagraphs(); - assertEquals(1, paras.size()); - - XSSFTextParagraph text = paras.get(0); - assertEquals("Test String", text.getText()); - - assertFalse(text.isBullet()); - assertNotNull(text.getXmlObject()); - assertEquals(shape.getCTShape(), text.getParentShape()); - assertNotNull(text.iterator()); - assertNotNull(text.addLineBreak()); - - assertNotNull(text.getTextRuns()); - assertEquals(2, text.getTextRuns().size()); - text.addNewTextRun(); - assertEquals(3, text.getTextRuns().size()); - - assertEquals(TextAlign.LEFT, text.getTextAlign()); - text.setTextAlign(null); - assertEquals(TextAlign.LEFT, text.getTextAlign()); - text.setTextAlign(TextAlign.CENTER); - assertEquals(TextAlign.CENTER, text.getTextAlign()); - text.setTextAlign(TextAlign.RIGHT); - assertEquals(TextAlign.RIGHT, text.getTextAlign()); - text.setTextAlign(null); - assertEquals(TextAlign.LEFT, text.getTextAlign()); - - text.setTextFontAlign(TextFontAlign.BASELINE); - assertEquals(TextFontAlign.BASELINE, text.getTextFontAlign()); - text.setTextFontAlign(TextFontAlign.BOTTOM); - assertEquals(TextFontAlign.BOTTOM, text.getTextFontAlign()); - text.setTextFontAlign(null); - assertEquals(TextFontAlign.BASELINE, text.getTextFontAlign()); - text.setTextFontAlign(null); - assertEquals(TextFontAlign.BASELINE, text.getTextFontAlign()); - - assertNull(text.getBulletFont()); - text.setBulletFont("Arial"); - assertEquals("Arial", text.getBulletFont()); - - assertNull(text.getBulletCharacter()); - text.setBulletCharacter("."); - assertEquals(".", text.getBulletCharacter()); - - assertNull(text.getBulletFontColor()); - text.setBulletFontColor(color); - assertEquals(color, text.getBulletFontColor()); - - assertEquals(100.0, text.getBulletFontSize(), 0.01); - text.setBulletFontSize(1.0); - assertEquals(1.0, text.getBulletFontSize(), 0.01); - text.setBulletFontSize(1.0); - assertEquals(1.0, text.getBulletFontSize(), 0.01); - text.setBulletFontSize(-9.0); - assertEquals(-9.0, text.getBulletFontSize(), 0.01); - text.setBulletFontSize(-9.0); - assertEquals(-9.0, text.getBulletFontSize(), 0.01); - text.setBulletFontSize(1.0); - assertEquals(1.0, text.getBulletFontSize(), 0.01); - text.setBulletFontSize(-9.0); - assertEquals(-9.0, text.getBulletFontSize(), 0.01); - - assertEquals(0.0, text.getIndent(), 0.01); - text.setIndent(2.0); - assertEquals(2.0, text.getIndent(), 0.01); - text.setIndent(-1.0); - assertEquals(0.0, text.getIndent(), 0.01); - text.setIndent(-1.0); - assertEquals(0.0, text.getIndent(), 0.01); - - assertEquals(0.0, text.getLeftMargin(), 0.01); - text.setLeftMargin(3.0); - assertEquals(3.0, text.getLeftMargin(), 0.01); - text.setLeftMargin(-1.0); - assertEquals(0.0, text.getLeftMargin(), 0.01); - text.setLeftMargin(-1.0); - assertEquals(0.0, text.getLeftMargin(), 0.01); - - assertEquals(0.0, text.getRightMargin(), 0.01); - text.setRightMargin(4.5); - assertEquals(4.5, text.getRightMargin(), 0.01); - text.setRightMargin(-1.0); - assertEquals(0.0, text.getRightMargin(), 0.01); - text.setRightMargin(-1.0); - assertEquals(0.0, text.getRightMargin(), 0.01); - - assertEquals(0.0, text.getDefaultTabSize(), 0.01); - - assertEquals(0.0, text.getTabStop(0), 0.01); - text.addTabStop(3.14); - assertEquals(3.14, text.getTabStop(0), 0.01); - - assertEquals(100.0, text.getLineSpacing(), 0.01); - text.setLineSpacing(3.15); - assertEquals(3.15, text.getLineSpacing(), 0.01); - text.setLineSpacing(-2.13); - assertEquals(-2.13, text.getLineSpacing(), 0.01); - - assertEquals(0.0, text.getSpaceBefore(), 0.01); - text.setSpaceBefore(3.17); - assertEquals(3.17, text.getSpaceBefore(), 0.01); - text.setSpaceBefore(-4.7); - assertEquals(-4.7, text.getSpaceBefore(), 0.01); - - assertEquals(0.0, text.getSpaceAfter(), 0.01); - text.setSpaceAfter(6.17); - assertEquals(6.17, text.getSpaceAfter(), 0.01); - text.setSpaceAfter(-8.17); - assertEquals(-8.17, text.getSpaceAfter(), 0.01); - - assertEquals(0, text.getLevel()); - text.setLevel(1); - assertEquals(1, text.getLevel()); - text.setLevel(4); - assertEquals(4, text.getLevel()); - - assertTrue(text.isBullet()); - assertFalse(text.isBulletAutoNumber()); - text.setBullet(false); - text.setBullet(false); - assertFalse(text.isBullet()); - assertFalse(text.isBulletAutoNumber()); - text.setBullet(true); - assertTrue(text.isBullet()); - assertFalse(text.isBulletAutoNumber()); - assertEquals(0, text.getBulletAutoNumberStart()); - assertEquals(ListAutoNumber.ARABIC_PLAIN, text.getBulletAutoNumberScheme()); - - text.setBullet(false); - assertFalse(text.isBullet()); - text.setBullet(ListAutoNumber.CIRCLE_NUM_DB_PLAIN); - assertTrue(text.isBullet()); - assertTrue(text.isBulletAutoNumber()); - assertEquals(0, text.getBulletAutoNumberStart()); - assertEquals(ListAutoNumber.CIRCLE_NUM_DB_PLAIN, text.getBulletAutoNumberScheme()); - text.setBullet(false); - assertFalse(text.isBullet()); - assertFalse(text.isBulletAutoNumber()); - text.setBullet(ListAutoNumber.CIRCLE_NUM_WD_BLACK_PLAIN, 10); - assertTrue(text.isBullet()); - assertTrue(text.isBulletAutoNumber()); - assertEquals(10, text.getBulletAutoNumberStart()); - assertEquals(ListAutoNumber.CIRCLE_NUM_WD_BLACK_PLAIN, text.getBulletAutoNumberScheme()); - - - assertNotNull(text.toString()); - - new XSSFTextParagraph(text.getXmlObject(), shape.getCTShape()); - } finally { - wb.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTextRun.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTextRun.java deleted file mode 100644 index e599e1761..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTextRun.java +++ /dev/null @@ -1,142 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.*; - -import java.awt.Color; -import java.io.IOException; -import java.util.List; - -import org.junit.Test; - -public class TestXSSFTextRun { - @Test - public void testXSSFTextParagraph() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); - - XSSFTextParagraph para = shape.addNewTextParagraph(); - para.addNewTextRun().setText("Line 1"); - - List runs = para.getTextRuns(); - assertEquals(1, runs.size()); - XSSFTextRun run = runs.get(0); - assertEquals("Line 1", run.getText()); - - assertNotNull(run.getParentParagraph()); - assertNotNull(run.getXmlObject()); - assertNotNull(run.getRPr()); - - assertEquals(new Color(0,0,0), run.getFontColor()); - - Color color = new Color(0, 255, 255); - run.setFontColor(color); - assertEquals(color, run.getFontColor()); - - assertEquals(11.0, run.getFontSize(), 0.01); - run.setFontSize(12.32); - assertEquals(12.32, run.getFontSize(), 0.01); - run.setFontSize(-1.0); - assertEquals(11.0, run.getFontSize(), 0.01); - run.setFontSize(-1.0); - assertEquals(11.0, run.getFontSize(), 0.01); - try { - run.setFontSize(0.9); - fail("Should fail"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("0.9")); - } - assertEquals(11.0, run.getFontSize(), 0.01); - - assertEquals(0.0, run.getCharacterSpacing(), 0.01); - run.setCharacterSpacing(12.31); - assertEquals(12.31, run.getCharacterSpacing(), 0.01); - run.setCharacterSpacing(0.0); - assertEquals(0.0, run.getCharacterSpacing(), 0.01); - run.setCharacterSpacing(0.0); - assertEquals(0.0, run.getCharacterSpacing(), 0.01); - - assertEquals("Calibri", run.getFontFamily()); - run.setFontFamily("Arial", (byte)1, (byte)1, false); - assertEquals("Arial", run.getFontFamily()); - run.setFontFamily("Arial", (byte)-1, (byte)1, false); - assertEquals("Arial", run.getFontFamily()); - run.setFontFamily("Arial", (byte)1, (byte)-1, false); - assertEquals("Arial", run.getFontFamily()); - run.setFontFamily("Arial", (byte)1, (byte)1, true); - assertEquals("Arial", run.getFontFamily()); - run.setFontFamily(null, (byte)1, (byte)1, false); - assertEquals("Calibri", run.getFontFamily()); - run.setFontFamily(null, (byte)1, (byte)1, false); - assertEquals("Calibri", run.getFontFamily()); - - run.setFont("Arial"); - assertEquals("Arial", run.getFontFamily()); - - assertEquals((byte)0, run.getPitchAndFamily()); - run.setFont(null); - assertEquals((byte)0, run.getPitchAndFamily()); - - assertFalse(run.isStrikethrough()); - run.setStrikethrough(true); - assertTrue(run.isStrikethrough()); - run.setStrikethrough(false); - assertFalse(run.isStrikethrough()); - - assertFalse(run.isSuperscript()); - run.setSuperscript(true); - assertTrue(run.isSuperscript()); - run.setSuperscript(false); - assertFalse(run.isSuperscript()); - - assertFalse(run.isSubscript()); - run.setSubscript(true); - assertTrue(run.isSubscript()); - run.setSubscript(false); - assertFalse(run.isSubscript()); - - assertEquals(TextCap.NONE, run.getTextCap()); - - assertFalse(run.isBold()); - run.setBold(true); - assertTrue(run.isBold()); - run.setBold(false); - assertFalse(run.isBold()); - - assertFalse(run.isItalic()); - run.setItalic(true); - assertTrue(run.isItalic()); - run.setItalic(false); - assertFalse(run.isItalic()); - - assertFalse(run.isUnderline()); - run.setUnderline(true); - assertTrue(run.isUnderline()); - run.setUnderline(false); - assertFalse(run.isUnderline()); - - assertNotNull(run.toString()); - } finally { - wb.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java deleted file mode 100644 index 4ae2b8b05..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java +++ /dev/null @@ -1,159 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.math.BigInteger; -import java.util.List; - -import com.microsoft.schemas.office.excel.STTrueFalseBlank; -import org.apache.poi.POIDataSamples; -import org.apache.xmlbeans.XmlObject; - -import com.microsoft.schemas.office.excel.CTClientData; -import com.microsoft.schemas.office.excel.STObjectType; -import com.microsoft.schemas.office.office.CTShapeLayout; -import com.microsoft.schemas.office.office.STConnectType; -import com.microsoft.schemas.office.office.STInsetMode; -import com.microsoft.schemas.vml.CTShadow; -import com.microsoft.schemas.vml.CTShape; -import com.microsoft.schemas.vml.CTShapetype; -import com.microsoft.schemas.vml.STExt; -import com.microsoft.schemas.vml.STTrueFalse; - -import junit.framework.TestCase; - -/** - * @author Yegor Kozlov - */ -public class TestXSSFVMLDrawing extends TestCase { - - public void testNew() throws Exception { - XSSFVMLDrawing vml = new XSSFVMLDrawing(); - List items = vml.getItems(); - assertEquals(2, items.size()); - assertTrue(items.get(0) instanceof CTShapeLayout); - CTShapeLayout layout = (CTShapeLayout)items.get(0); - assertEquals(STExt.EDIT, layout.getExt()); - assertEquals(STExt.EDIT, layout.getIdmap().getExt()); - assertEquals("1", layout.getIdmap().getData()); - - assertTrue(items.get(1) instanceof CTShapetype); - CTShapetype type = (CTShapetype)items.get(1); - assertEquals("21600,21600", type.getCoordsize()); - assertEquals(202.0f, type.getSpt()); - assertEquals("m,l,21600r21600,l21600,xe", type.getPath2()); - assertEquals("_x0000_t202", type.getId()); - assertEquals(STTrueFalse.T, type.getPathArray(0).getGradientshapeok()); - assertEquals(STConnectType.RECT, type.getPathArray(0).getConnecttype()); - - CTShape shape = vml.newCommentShape(); - assertEquals(3, items.size()); - assertSame(items.get(2), shape); - assertEquals("#_x0000_t202", shape.getType()); - assertEquals("position:absolute; visibility:hidden", shape.getStyle()); - assertEquals("#ffffe1", shape.getFillcolor()); - assertEquals(STInsetMode.AUTO, shape.getInsetmode()); - assertEquals("#ffffe1", shape.getFillArray(0).getColor()); - CTShadow shadow = shape.getShadowArray(0); - assertEquals(STTrueFalse.T, shadow.getOn()); - assertEquals("black", shadow.getColor()); - assertEquals(STTrueFalse.T, shadow.getObscured()); - assertEquals(STConnectType.NONE, shape.getPathArray(0).getConnecttype()); - assertEquals("mso-direction-alt:auto", shape.getTextboxArray(0).getStyle()); - CTClientData cldata = shape.getClientDataArray(0); - assertEquals(STObjectType.NOTE, cldata.getObjectType()); - assertEquals(1, cldata.sizeOfMoveWithCellsArray()); - assertEquals(1, cldata.sizeOfSizeWithCellsArray()); - assertEquals("1, 15, 0, 2, 3, 15, 3, 16", cldata.getAnchorArray(0)); - assertEquals("False", cldata.getAutoFillArray(0).toString()); - assertEquals(0, cldata.getRowArray(0).intValue()); - assertEquals(0, cldata.getColumnArray(0).intValue()); - assertEquals("[]", cldata.getVisibleList().toString()); - cldata.setVisibleArray(new STTrueFalseBlank.Enum[] { STTrueFalseBlank.Enum.forString("True") }); - assertEquals("[True]", cldata.getVisibleList().toString()); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - vml.write(out); - - XSSFVMLDrawing vml2 = new XSSFVMLDrawing(); - vml2.read(new ByteArrayInputStream(out.toByteArray())); - List items2 = vml2.getItems(); - assertEquals(3, items2.size()); - assertTrue(items2.get(0) instanceof CTShapeLayout); - assertTrue(items2.get(1) instanceof CTShapetype); - assertTrue(items2.get(2) instanceof CTShape); - } - - public void testFindCommentShape() throws Exception { - - XSSFVMLDrawing vml = new XSSFVMLDrawing(); - InputStream stream = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("vmlDrawing1.vml"); - try { - vml.read(stream); - } finally { - stream.close(); - } - - CTShape sh_a1 = vml.findCommentShape(0, 0); - assertNotNull(sh_a1); - assertEquals("_x0000_s1025", sh_a1.getId()); - - CTShape sh_b1 = vml.findCommentShape(0, 1); - assertNotNull(sh_b1); - assertEquals("_x0000_s1026", sh_b1.getId()); - - CTShape sh_c1 = vml.findCommentShape(0, 2); - assertNull(sh_c1); - - CTShape sh_d1 = vml.newCommentShape(); - assertEquals("_x0000_s1027", sh_d1.getId()); - sh_d1.getClientDataArray(0).setRowArray(0, new BigInteger("0")); - sh_d1.getClientDataArray(0).setColumnArray(0, new BigInteger("3")); - assertSame(sh_d1, vml.findCommentShape(0, 3)); - - //newly created drawing - XSSFVMLDrawing newVml = new XSSFVMLDrawing(); - assertNull(newVml.findCommentShape(0, 0)); - - sh_a1 = newVml.newCommentShape(); - assertEquals("_x0000_s1025", sh_a1.getId()); - sh_a1.getClientDataArray(0).setRowArray(0, new BigInteger("0")); - sh_a1.getClientDataArray(0).setColumnArray(0, new BigInteger("1")); - assertSame(sh_a1, newVml.findCommentShape(0, 1)); - } - - public void testRemoveCommentShape() throws Exception { - XSSFVMLDrawing vml = new XSSFVMLDrawing(); - InputStream stream = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("vmlDrawing1.vml"); - try { - vml.read(stream); - } finally { - stream.close(); - } - - CTShape sh_a1 = vml.findCommentShape(0, 0); - assertNotNull(sh_a1); - - assertTrue(vml.removeCommentShape(0, 0)); - assertNull(vml.findCommentShape(0, 0)); - - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java deleted file mode 100644 index 7f832c4d9..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java +++ /dev/null @@ -1,1183 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.zip.CRC32; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIXMLProperties; -import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.ContentTypes; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.internal.FileHelper; -import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart; -import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.BaseTestXWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.RichTextString; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; -import org.apache.poi.ss.util.AreaReference; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.TempFile; -import org.apache.poi.xssf.XSSFITestDataProvider; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.model.StylesTable; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCache; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode; - -public final class TestXSSFWorkbook extends BaseTestXWorkbook { - - public TestXSSFWorkbook() { - super(XSSFITestDataProvider.instance); - } - - /** - * Tests that we can save, and then re-load a new document - */ - @Test - public void saveLoadNew() throws IOException, InvalidFormatException { - XSSFWorkbook wb1 = new XSSFWorkbook(); - - //check that the default date system is set to 1900 - CTWorkbookPr pr = wb1.getCTWorkbook().getWorkbookPr(); - assertNotNull(pr); - assertTrue(pr.isSetDate1904()); - assertFalse("XSSF must use the 1900 date system", pr.getDate1904()); - - Sheet sheet1 = wb1.createSheet("sheet1"); - Sheet sheet2 = wb1.createSheet("sheet2"); - wb1.createSheet("sheet3"); - - RichTextString rts = wb1.getCreationHelper().createRichTextString("hello world"); - - sheet1.createRow(0).createCell((short)0).setCellValue(1.2); - sheet1.createRow(1).createCell((short)0).setCellValue(rts); - sheet2.createRow(0); - - assertEquals(0, wb1.getSheetAt(0).getFirstRowNum()); - assertEquals(1, wb1.getSheetAt(0).getLastRowNum()); - assertEquals(0, wb1.getSheetAt(1).getFirstRowNum()); - assertEquals(0, wb1.getSheetAt(1).getLastRowNum()); - assertEquals(0, wb1.getSheetAt(2).getFirstRowNum()); - assertEquals(0, wb1.getSheetAt(2).getLastRowNum()); - - File file = TempFile.createTempFile("poi-", ".xlsx"); - OutputStream out = new FileOutputStream(file); - wb1.write(out); - out.close(); - - // Check the package contains what we'd expect it to - OPCPackage pkg = OPCPackage.open(file.toString()); - PackagePart wbRelPart = - pkg.getPart(PackagingURIHelper.createPartName("/xl/_rels/workbook.xml.rels")); - assertNotNull(wbRelPart); - assertTrue(wbRelPart.isRelationshipPart()); - assertEquals(ContentTypes.RELATIONSHIPS_PART, wbRelPart.getContentType()); - - PackagePart wbPart = - pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml")); - // Links to the three sheets, shared strings and styles - assertTrue(wbPart.hasRelationships()); - assertEquals(5, wbPart.getRelationships().size()); - wb1.close(); - - // Load back the XSSFWorkbook - @SuppressWarnings("resource") - XSSFWorkbook wb2 = new XSSFWorkbook(pkg); - assertEquals(3, wb2.getNumberOfSheets()); - assertNotNull(wb2.getSheetAt(0)); - assertNotNull(wb2.getSheetAt(1)); - assertNotNull(wb2.getSheetAt(2)); - - assertNotNull(wb2.getSharedStringSource()); - assertNotNull(wb2.getStylesSource()); - - assertEquals(0, wb2.getSheetAt(0).getFirstRowNum()); - assertEquals(1, wb2.getSheetAt(0).getLastRowNum()); - assertEquals(0, wb2.getSheetAt(1).getFirstRowNum()); - assertEquals(0, wb2.getSheetAt(1).getLastRowNum()); - assertEquals(0, wb2.getSheetAt(2).getFirstRowNum()); - assertEquals(0, wb2.getSheetAt(2).getLastRowNum()); - - sheet1 = wb2.getSheetAt(0); - assertEquals(1.2, sheet1.getRow(0).getCell(0).getNumericCellValue(), 0.0001); - assertEquals("hello world", sheet1.getRow(1).getCell(0).getRichStringCellValue().getString()); - - pkg.close(); - } - - @Test - public void existing() throws Exception { - - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx"); - assertNotNull(workbook.getSharedStringSource()); - assertNotNull(workbook.getStylesSource()); - - // And check a few low level bits too - OPCPackage pkg = OPCPackage.open(HSSFTestDataSamples.openSampleFileStream("Formatting.xlsx")); - PackagePart wbPart = - pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml")); - - // Links to the three sheets, shared, styles and themes - assertTrue(wbPart.hasRelationships()); - assertEquals(6, wbPart.getRelationships().size()); - - pkg.close(); - workbook.close(); - } - - @Test - public void getCellStyleAt() throws IOException{ - XSSFWorkbook workbook = new XSSFWorkbook(); - try { - short i = 0; - //get default style - CellStyle cellStyleAt = workbook.getCellStyleAt(i); - assertNotNull(cellStyleAt); - - //get custom style - StylesTable styleSource = workbook.getStylesSource(); - XSSFCellStyle customStyle = new XSSFCellStyle(styleSource); - XSSFFont font = new XSSFFont(); - font.setFontName("Verdana"); - customStyle.setFont(font); - int x = styleSource.putStyle(customStyle); - cellStyleAt = workbook.getCellStyleAt((short)x); - assertNotNull(cellStyleAt); - } finally { - workbook.close(); - } - } - - @Test - public void getFontAt() throws IOException{ - XSSFWorkbook workbook = new XSSFWorkbook(); - try { - StylesTable styleSource = workbook.getStylesSource(); - short i = 0; - //get default font - Font fontAt = workbook.getFontAt(i); - assertNotNull(fontAt); - - //get customized font - XSSFFont customFont = new XSSFFont(); - customFont.setItalic(true); - int x = styleSource.putFont(customFont); - fontAt = workbook.getFontAt((short)x); - assertNotNull(fontAt); - } finally { - workbook.close(); - } - } - - @Test - public void getNumCellStyles() throws IOException{ - XSSFWorkbook workbook = new XSSFWorkbook(); - try { - //get default cellStyles - assertEquals(1, workbook.getNumCellStyles()); - } finally { - workbook.close(); - } - } - - @Test - public void loadSave() throws IOException { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx"); - assertEquals(3, workbook.getNumberOfSheets()); - assertEquals("dd/mm/yyyy", workbook.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString()); - assertNotNull(workbook.getSharedStringSource()); - assertNotNull(workbook.getStylesSource()); - - // Write out, and check - // Load up again, check all still there - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertEquals(3, wb2.getNumberOfSheets()); - assertNotNull(wb2.getSheetAt(0)); - assertNotNull(wb2.getSheetAt(1)); - assertNotNull(wb2.getSheetAt(2)); - - assertEquals("dd/mm/yyyy", wb2.getSheetAt(0).getRow(1).getCell(0).getRichStringCellValue().getString()); - assertEquals("yyyy/mm/dd", wb2.getSheetAt(0).getRow(2).getCell(0).getRichStringCellValue().getString()); - assertEquals("yyyy-mm-dd", wb2.getSheetAt(0).getRow(3).getCell(0).getRichStringCellValue().getString()); - assertEquals("yy/mm/dd", wb2.getSheetAt(0).getRow(4).getCell(0).getRichStringCellValue().getString()); - assertNotNull(wb2.getSharedStringSource()); - assertNotNull(wb2.getStylesSource()); - - workbook.close(); - wb2.close(); - } - - @Test - public void styles() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("Formatting.xlsx"); - - StylesTable ss = wb1.getStylesSource(); - assertNotNull(ss); - StylesTable st = ss; - - // Has 8 number formats - assertEquals(8, st.getNumDataFormats()); - // Has 2 fonts - assertEquals(2, st.getFonts().size()); - // Has 2 fills - assertEquals(2, st.getFills().size()); - // Has 1 border - assertEquals(1, st.getBorders().size()); - - // Add two more styles - assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8, - st.putNumberFormat("testFORMAT")); - assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8, - st.putNumberFormat("testFORMAT")); - assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 9, - st.putNumberFormat("testFORMAT2")); - assertEquals(10, st.getNumDataFormats()); - - - // Save, load back in again, and check - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - wb1.close(); - - ss = wb2.getStylesSource(); - assertNotNull(ss); - - assertEquals(10, st.getNumDataFormats()); - assertEquals(2, st.getFonts().size()); - assertEquals(2, st.getFills().size()); - assertEquals(1, st.getBorders().size()); - wb2.close(); - } - - @Test - public void incrementSheetId() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - int sheetId = (int)wb.createSheet().sheet.getSheetId(); - assertEquals(1, sheetId); - sheetId = (int)wb.createSheet().sheet.getSheetId(); - assertEquals(2, sheetId); - - //test file with gaps in the sheetId sequence - XSSFWorkbook wbBack = XSSFTestDataSamples.openSampleWorkbook("47089.xlsm"); - try { - int lastSheetId = (int)wbBack.getSheetAt(wbBack.getNumberOfSheets() - 1).sheet.getSheetId(); - sheetId = (int)wbBack.createSheet().sheet.getSheetId(); - assertEquals(lastSheetId+1, sheetId); - } finally { - wbBack.close(); - } - } finally { - wb.close(); - } - } - - /** - * Test setting of core properties such as Title and Author - * @throws IOException - */ - @Test - public void workbookProperties() throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(); - try { - POIXMLProperties props = workbook.getProperties(); - assertNotNull(props); - //the Application property must be set for new workbooks, see Bugzilla #47559 - assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication()); - - PackagePropertiesPart opcProps = props.getCoreProperties().getUnderlyingProperties(); - assertNotNull(opcProps); - - opcProps.setTitleProperty("Testing Bugzilla #47460"); - assertEquals("Apache POI", opcProps.getCreatorProperty().getValue()); - opcProps.setCreatorProperty("poi-dev@poi.apache.org"); - - XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertEquals("Apache POI", wbBack.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication()); - opcProps = wbBack.getProperties().getCoreProperties().getUnderlyingProperties(); - assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().getValue()); - assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().getValue()); - wbBack.close(); - } finally { - workbook.close(); - } - } - - /** - * Verify that the attached test data was not modified. If this test method - * fails, the test data is not working properly. - */ - @Test - public void bug47668() throws Exception { - XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("47668.xlsx"); - List allPictures = workbook.getAllPictures(); - assertEquals(1, allPictures.size()); - - PackagePartName imagePartName = PackagingURIHelper - .createPartName("/xl/media/image1.jpeg"); - PackagePart imagePart = workbook.getPackage().getPart(imagePartName); - assertNotNull(imagePart); - - for (XSSFPictureData pictureData : allPictures) { - PackagePart picturePart = pictureData.getPackagePart(); - assertSame(imagePart, picturePart); - } - - XSSFSheet sheet0 = workbook.getSheetAt(0); - XSSFDrawing drawing0 = sheet0.createDrawingPatriarch(); - XSSFPictureData pictureData0 = (XSSFPictureData) drawing0.getRelations().get(0); - byte[] data0 = pictureData0.getData(); - CRC32 crc0 = new CRC32(); - crc0.update(data0); - - XSSFSheet sheet1 = workbook.getSheetAt(1); - XSSFDrawing drawing1 = sheet1.createDrawingPatriarch(); - XSSFPictureData pictureData1 = (XSSFPictureData) drawing1.getRelations().get(0); - byte[] data1 = pictureData1.getData(); - CRC32 crc1 = new CRC32(); - crc1.update(data1); - - assertEquals(crc0.getValue(), crc1.getValue()); - workbook.close(); - } - - /** - * When deleting a sheet make sure that we adjust sheet indices of named ranges - */ - @Test - public void bug47737() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47737.xlsx"); - assertEquals(2, wb.getNumberOfNames()); - assertNotNull(wb.getCalculationChain()); - - XSSFName nm0 = wb.getNameAt(0); - assertTrue(nm0.getCTName().isSetLocalSheetId()); - assertEquals(0, nm0.getCTName().getLocalSheetId()); - - XSSFName nm1 = wb.getNameAt(1); - assertTrue(nm1.getCTName().isSetLocalSheetId()); - assertEquals(1, nm1.getCTName().getLocalSheetId()); - - wb.removeSheetAt(0); - assertEquals(1, wb.getNumberOfNames()); - XSSFName nm2 = wb.getNameAt(0); - assertTrue(nm2.getCTName().isSetLocalSheetId()); - assertEquals(0, nm2.getCTName().getLocalSheetId()); - //calculation chain is removed as well - assertNull(wb.getCalculationChain()); - wb.close(); - - } - - /** - * Problems with XSSFWorkbook.removeSheetAt when workbook contains charts - */ - @Test - public void bug47813() throws IOException { - XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx"); - assertEquals(3, wb1.getNumberOfSheets()); - assertNotNull(wb1.getCalculationChain()); - - assertEquals("Numbers", wb1.getSheetName(0)); - //the second sheet is of type 'chartsheet' - assertEquals("Chart", wb1.getSheetName(1)); - assertTrue(wb1.getSheetAt(1) instanceof XSSFChartSheet); - assertEquals("SomeJunk", wb1.getSheetName(2)); - - wb1.removeSheetAt(2); - assertEquals(2, wb1.getNumberOfSheets()); - assertNull(wb1.getCalculationChain()); - - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - assertEquals(2, wb2.getNumberOfSheets()); - assertNull(wb2.getCalculationChain()); - - assertEquals("Numbers", wb2.getSheetName(0)); - assertEquals("Chart", wb2.getSheetName(1)); - wb2.close(); - wb1.close(); - } - - /** - * Problems with the count of the number of styles - * coming out wrong - */ - @Test - public void bug49702() throws IOException { - // First try with a new file - XSSFWorkbook wb1 = new XSSFWorkbook(); - - // Should have one style - assertEquals(1, wb1.getNumCellStyles()); - wb1.getCellStyleAt((short)0); - try { - wb1.getCellStyleAt((short)1); - fail("Shouldn't be able to get style at 1 that doesn't exist"); - } catch(IndexOutOfBoundsException e) {} - - // Add another one - CellStyle cs = wb1.createCellStyle(); - cs.setDataFormat((short)11); - - // Re-check - assertEquals(2, wb1.getNumCellStyles()); - wb1.getCellStyleAt((short)0); - wb1.getCellStyleAt((short)1); - try { - wb1.getCellStyleAt((short)2); - fail("Shouldn't be able to get style at 2 that doesn't exist"); - } catch(IndexOutOfBoundsException e) {} - - // Save and reload - XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb1); - assertEquals(2, nwb.getNumCellStyles()); - nwb.getCellStyleAt((short)0); - nwb.getCellStyleAt((short)1); - try { - nwb.getCellStyleAt((short)2); - fail("Shouldn't be able to get style at 2 that doesn't exist"); - } catch(IndexOutOfBoundsException e) {} - - // Now with an existing file - XSSFWorkbook wb2 = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx"); - assertEquals(3, wb2.getNumCellStyles()); - wb2.getCellStyleAt((short)0); - wb2.getCellStyleAt((short)1); - wb2.getCellStyleAt((short)2); - try { - wb2.getCellStyleAt((short)3); - fail("Shouldn't be able to get style at 3 that doesn't exist"); - } catch(IndexOutOfBoundsException e) {} - - wb2.close(); - wb1.close(); - nwb.close(); - } - - @Test - public void recalcId() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - try { - assertFalse(wb.getForceFormulaRecalculation()); - CTWorkbook ctWorkbook = wb.getCTWorkbook(); - assertFalse(ctWorkbook.isSetCalcPr()); - - wb.setForceFormulaRecalculation(true); // resets the EngineId flag to zero - - CTCalcPr calcPr = ctWorkbook.getCalcPr(); - assertNotNull(calcPr); - assertEquals(0, (int) calcPr.getCalcId()); - - calcPr.setCalcId(100); - assertTrue(wb.getForceFormulaRecalculation()); - - wb.setForceFormulaRecalculation(true); // resets the EngineId flag to zero - assertEquals(0, (int) calcPr.getCalcId()); - assertFalse(wb.getForceFormulaRecalculation()); - - // calcMode="manual" is unset when forceFormulaRecalculation=true - calcPr.setCalcMode(STCalcMode.MANUAL); - wb.setForceFormulaRecalculation(true); - assertEquals(STCalcMode.AUTO, calcPr.getCalcMode()); - } finally { - wb.close(); - } - } - - @Test - public void changeSheetNameWithSharedFormulas() throws IOException { - changeSheetNameWithSharedFormulas("shared_formulas.xlsx"); - } - - @Test - public void columnWidthPOI52233() throws Exception { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - XSSFRow row = sheet.createRow(0); - XSSFCell cell = row.createCell(0); - cell.setCellValue("hello world"); - - sheet = workbook.createSheet(); - sheet.setColumnWidth(4, 5000); - sheet.setColumnWidth(5, 5000); - - sheet.groupColumn((short) 4, (short) 5); - - accessWorkbook(workbook); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - workbook.write(stream); - } finally { - stream.close(); - } - - accessWorkbook(workbook); - workbook.close(); - } - - private void accessWorkbook(XSSFWorkbook workbook) { - workbook.getSheetAt(1).setColumnGroupCollapsed(4, true); - workbook.getSheetAt(1).setColumnGroupCollapsed(4, false); - - assertEquals("hello world", workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue()); - assertEquals(2048, workbook.getSheetAt(0).getColumnWidth(0)); // <-works - } - - @Test - public void bug48495() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("48495.xlsx"); - - assertSheetOrder(wb, "Sheet1"); - - Sheet sheet = wb.getSheetAt(0); - sheet.shiftRows(2, sheet.getLastRowNum(), 1, true, false); - Row newRow = sheet.getRow(2); - if (newRow == null) newRow = sheet.createRow(2); - newRow.createCell(0).setCellValue(" Another Header"); - wb.cloneSheet(0); - - assertSheetOrder(wb, "Sheet1", "Sheet1 (2)"); - - // FileOutputStream fileOut = new FileOutputStream("/tmp/bug48495.xlsx"); -// try { -// wb.write(fileOut); -// } finally { -// fileOut.close(); -// } - - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertNotNull(read); - assertSheetOrder(read, "Sheet1", "Sheet1 (2)"); - read.close(); - wb.close(); - } - - @Test - public void bug47090a() throws IOException { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx"); - assertSheetOrder(workbook, "Sheet1", "Sheet2"); - workbook.removeSheetAt(0); - assertSheetOrder(workbook, "Sheet2"); - workbook.createSheet(); - assertSheetOrder(workbook, "Sheet2", "Sheet1"); - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertSheetOrder(read, "Sheet2", "Sheet1"); - read.close(); - workbook.close(); - } - - @Test - public void bug47090b() throws IOException { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx"); - assertSheetOrder(workbook, "Sheet1", "Sheet2"); - workbook.removeSheetAt(1); - assertSheetOrder(workbook, "Sheet1"); - workbook.createSheet(); - assertSheetOrder(workbook, "Sheet1", "Sheet0"); // Sheet0 because it uses "Sheet" + sheets.size() as starting point! - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertSheetOrder(read, "Sheet1", "Sheet0"); - read.close(); - workbook.close(); - } - - @Test - public void bug47090c() throws IOException { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx"); - assertSheetOrder(workbook, "Sheet1", "Sheet2"); - workbook.removeSheetAt(0); - assertSheetOrder(workbook, "Sheet2"); - workbook.cloneSheet(0); - assertSheetOrder(workbook, "Sheet2", "Sheet2 (2)"); - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertSheetOrder(read, "Sheet2", "Sheet2 (2)"); - read.close(); - workbook.close(); - } - - @Test - public void bug47090d() throws IOException { - Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("47090.xlsx"); - assertSheetOrder(workbook, "Sheet1", "Sheet2"); - workbook.createSheet(); - assertSheetOrder(workbook, "Sheet1", "Sheet2", "Sheet0"); - workbook.removeSheetAt(0); - assertSheetOrder(workbook, "Sheet2", "Sheet0"); - workbook.createSheet(); - assertSheetOrder(workbook, "Sheet2", "Sheet0", "Sheet1"); - Workbook read = XSSFTestDataSamples.writeOutAndReadBack(workbook); - assertSheetOrder(read, "Sheet2", "Sheet0", "Sheet1"); - read.close(); - workbook.close(); - } - - @Test - public void bug51158() throws IOException { - // create a workbook - final XSSFWorkbook wb1 = new XSSFWorkbook(); - XSSFSheet sheet = wb1.createSheet("Test Sheet"); - XSSFRow row = sheet.createRow(2); - XSSFCell cell = row.createCell(3); - cell.setCellValue("test1"); - - //XSSFCreationHelper helper = workbook.getCreationHelper(); - //cell.setHyperlink(helper.createHyperlink(0)); - - XSSFComment comment = sheet.createDrawingPatriarch().createCellComment(new XSSFClientAnchor()); - assertNotNull(comment); - comment.setString("some comment"); - -// CellStyle cs = workbook.createCellStyle(); -// cs.setShrinkToFit(false); -// row.createCell(0).setCellStyle(cs); - - // write the first excel file - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); - assertNotNull(wb2); - sheet = wb2.getSheetAt(0); - row = sheet.getRow(2); - assertEquals("test1", row.getCell(3).getStringCellValue()); - assertNull(row.getCell(4)); - - // add a new cell to the sheet - cell = row.createCell(4); - cell.setCellValue("test2"); - - // write the second excel file - XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); - assertNotNull(wb3); - sheet = wb3.getSheetAt(0); - row = sheet.getRow(2); - - assertEquals("test1", row.getCell(3).getStringCellValue()); - assertEquals("test2", row.getCell(4).getStringCellValue()); - wb3.close(); - wb2.close(); - wb1.close(); - } - - @Test - public void bug51158a() throws IOException { - // create a workbook - final XSSFWorkbook workbook = new XSSFWorkbook(); - try { - workbook.createSheet("Test Sheet"); - - XSSFSheet sheetBack = workbook.getSheetAt(0); - - // committing twice did add the XML twice without clearing the part in between - sheetBack.commit(); - - // ensure that a memory based package part does not have lingering data from previous commit() calls - if(sheetBack.getPackagePart() instanceof MemoryPackagePart) { - ((MemoryPackagePart)sheetBack.getPackagePart()).clear(); - } - - sheetBack.commit(); - - String str = new String(IOUtils.toByteArray(sheetBack.getPackagePart().getInputStream()), "UTF-8"); - - assertEquals(1, countMatches(str, " XSSFWorkbook.iterator was committed in r700472 on 2008-09-30 - * and has been replaced with Iterator XSSFWorkbook.iterator - * - * In order to make code for looping over sheets in workbooks standard, regardless - * of the type of workbook (HSSFWorkbook, XSSFWorkbook, SXSSFWorkbook), the previously - * available Iterator iterator and Iterator sheetIterator - * have been replaced with Iterator {@link #iterator} and - * Iterator {@link #sheetIterator}. This makes iterating over sheets in a workbook - * similar to iterating over rows in a sheet and cells in a row. - * - * Note: this breaks backwards compatibility! Existing codebases will need to - * upgrade their code with either of the following options presented in this test case. - * - */ - @SuppressWarnings("unchecked") - @Test - public void bug58245_XSSFSheetIterator() throws IOException { - final XSSFWorkbook wb = new XSSFWorkbook(); - wb.createSheet(); - - // ===================================================================== - // Case 1: Existing code uses XSSFSheet for-each loop - // ===================================================================== - // Original code (no longer valid) - /* - for (XSSFSheet sh : wb) { - sh.createRow(0); - } - */ - - // Option A: - for (XSSFSheet sh : (Iterable) (Iterable) wb) { - sh.createRow(0); - } - - // Option B (preferred for new code): - for (Sheet sh : wb) { - sh.createRow(0); - } - - // ===================================================================== - // Case 2: Existing code creates an iterator variable - // ===================================================================== - // Original code (no longer valid) - /* - Iterator it = wb.iterator(); - XSSFSheet sh = it.next(); - sh.createRow(0); - */ - - // Option A: - { - Iterator it = (Iterator) (Iterator) wb.iterator(); - XSSFSheet sh = it.next(); - sh.createRow(0); - } - - // Option B: - { - @SuppressWarnings("deprecation") - Iterator it = wb.xssfSheetIterator(); - XSSFSheet sh = it.next(); - sh.createRow(0); - } - - // Option C (preferred for new code): - { - Iterator it = wb.iterator(); - Sheet sh = it.next(); - sh.createRow(0); - } - wb.close(); - } - - @Test - public void testBug56957CloseWorkbook() throws Exception { - File file = TempFile.createTempFile("TestBug56957_", ".xlsx"); - final Date dateExp = LocaleUtil.getLocaleCalendar(2014, 10, 9).getTime(); - - try { - // as the file is written to, we make a copy before actually working on it - FileHelper.copyFile(HSSFTestDataSamples.getSampleFile("56957.xlsx"), file); - - assertTrue(file.exists()); - - // read-only mode works! - Workbook workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ)); - Date dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue(); - assertEquals(dateExp, dateAct); - workbook.close(); - workbook = null; - - workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ)); - dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue(); - assertEquals(dateExp, dateAct); - workbook.close(); - workbook = null; - - // now check read/write mode - workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ_WRITE)); - dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue(); - assertEquals(dateExp, dateAct); - workbook.close(); - workbook = null; - - workbook = WorkbookFactory.create(OPCPackage.open(file, PackageAccess.READ_WRITE)); - dateAct = workbook.getSheetAt(0).getRow(0).getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getDateCellValue(); - assertEquals(dateExp, dateAct); - workbook.close(); - workbook = null; - } finally { - assertTrue(file.exists()); - assertTrue(file.delete()); - } - } - - @Test - public void closeDoesNotModifyWorkbook() throws IOException, InvalidFormatException { - final String filename = "SampleSS.xlsx"; - final File file = POIDataSamples.getSpreadSheetInstance().getFile(filename); - Workbook wb; - - // Some tests commented out because close() modifies the file - // See bug 58779 - - // String - //wb = new XSSFWorkbook(file.getPath()); - //assertCloseDoesNotModifyFile(filename, wb); - - // File - //wb = new XSSFWorkbook(file); - //assertCloseDoesNotModifyFile(filename, wb); - - // InputStream - wb = new XSSFWorkbook(new FileInputStream(file)); - assertCloseDoesNotModifyFile(filename, wb); - - // OPCPackage - //wb = new XSSFWorkbook(OPCPackage.open(file)); - //assertCloseDoesNotModifyFile(filename, wb); - } - - @Test - public void testCloseBeforeWrite() throws IOException { - Workbook wb = new XSSFWorkbook(); - wb.createSheet("somesheet"); - - // test what happens if we close the Workbook before we write it out - wb.close(); - - try { - XSSFTestDataSamples.writeOutAndReadBack(wb); - fail("Expecting IOException here"); - } catch (RuntimeException e) { - // expected here - assertTrue("Had: " + e.getCause(), e.getCause() instanceof IOException); - } - } - - /** - * See bug #57840 test data tables - */ - @Test - public void getTable() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTable.xlsx"); - XSSFTable table1 = wb.getTable("Tabella1"); - assertNotNull("Tabella1 was not found in workbook", table1); - assertEquals("Table name", "Tabella1", table1.getName()); - assertEquals("Sheet name", "Foglio1", table1.getSheetName()); - - // Table lookup should be case-insensitive - assertSame("Case insensitive table name lookup", table1, wb.getTable("TABELLA1")); - - // If workbook does not contain any data tables matching the provided name, getTable should return null - assertNull("Null table name should not throw NPE", wb.getTable(null)); - assertNull("Should not be able to find non-existent table", wb.getTable("Foglio1")); - - // If a table is added after getTable is called it should still be reachable by XSSFWorkbook.getTable - // This test makes sure that if any caching is done that getTable never uses a stale cache - XSSFTable table2 = wb.getSheet("Foglio2").createTable(); - table2.setName("Table2"); - assertSame("Did not find Table2", table2, wb.getTable("Table2")); - - // If table name is modified after getTable is called, the table can only be found by its new name - // This test makes sure that if any caching is done that getTable never uses a stale cache - table1.setName("Table1"); - assertSame("Did not find Tabella1 renamed to Table1", table1, wb.getTable("TABLE1")); - - wb.close(); - } - - @Test - public void testRemoveSheet() throws IOException { - // Test removing a sheet maintains the named ranges correctly - XSSFWorkbook wb = new XSSFWorkbook(); - wb.createSheet("Sheet1"); - wb.createSheet("Sheet2"); - - XSSFName sheet1Name = wb.createName(); - sheet1Name.setNameName("name1"); - sheet1Name.setSheetIndex(0); - sheet1Name.setRefersToFormula("Sheet1!$A$1"); - - XSSFName sheet2Name = wb.createName(); - sheet2Name.setNameName("name1"); - sheet2Name.setSheetIndex(1); - sheet2Name.setRefersToFormula("Sheet2!$A$1"); - - assertTrue(wb.getAllNames().contains(sheet1Name)); - assertTrue(wb.getAllNames().contains(sheet2Name)); - - assertEquals(2, wb.getNames("name1").size()); - assertEquals(sheet1Name, wb.getNames("name1").get(0)); - assertEquals(sheet2Name, wb.getNames("name1").get(1)); - - // Remove sheet1, we should only have sheet2Name now - wb.removeSheetAt(0); - - assertFalse(wb.getAllNames().contains(sheet1Name)); - assertTrue(wb.getAllNames().contains(sheet2Name)); - assertEquals(1, wb.getNames("name1").size()); - assertEquals(sheet2Name, wb.getNames("name1").get(0)); - - // Check by index as well for sanity - assertEquals(1, wb.getNumberOfNames()); - assertEquals(0, wb.getNameIndex("name1")); - assertEquals(sheet2Name, wb.getNameAt(0)); - - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java deleted file mode 100644 index 64ce92b57..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.usermodel.*; - -public final class TestXSSFCategoryAxis extends TestCase { - - public void testAccessMethods() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - XSSFChart chart = drawing.createChart(anchor); - XSSFCategoryAxis axis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); - - axis.setCrosses(AxisCrosses.AUTO_ZERO); - assertEquals(axis.getCrosses(), AxisCrosses.AUTO_ZERO); - - assertEquals(chart.getAxis().size(), 1); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java deleted file mode 100644 index 41e02b12f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.*; - -public final class TestXSSFChartAxis extends TestCase { - - private static final double EPSILON = 1E-7; - private final XSSFChartAxis axis; - - public TestXSSFChartAxis() { - super(); - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - XSSFChart chart = drawing.createChart(anchor); - axis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM); - } - - public void testLogBaseIllegalArgument() throws Exception { - IllegalArgumentException iae = null; - try { - axis.setLogBase(0.0); - } catch (IllegalArgumentException e) { - iae = e; - } - assertNotNull(iae); - - iae = null; - try { - axis.setLogBase(30000.0); - } catch (IllegalArgumentException e) { - iae = e; - } - assertNotNull(iae); - } - - public void testLogBaseLegalArgument() throws Exception { - axis.setLogBase(Math.E); - assertTrue(Math.abs(axis.getLogBase() - Math.E) < EPSILON); - } - - public void testNumberFormat() throws Exception { - final String numberFormat = "General"; - axis.setNumberFormat(numberFormat); - assertEquals(numberFormat, axis.getNumberFormat()); - } - - public void testMaxAndMinAccessMethods() { - final double newValue = 10.0; - - axis.setMinimum(newValue); - assertTrue(Math.abs(axis.getMinimum() - newValue) < EPSILON); - - axis.setMaximum(newValue); - assertTrue(Math.abs(axis.getMaximum() - newValue) < EPSILON); - } - - public void testVisibleAccessMethods() { - axis.setVisible(true); - assertTrue(axis.isVisible()); - - axis.setVisible(false); - assertFalse(axis.isVisible()); - } - - public void testMajorTickMarkAccessMethods() { - axis.setMajorTickMark(AxisTickMark.NONE); - assertEquals(AxisTickMark.NONE, axis.getMajorTickMark()); - - axis.setMajorTickMark(AxisTickMark.IN); - assertEquals(AxisTickMark.IN, axis.getMajorTickMark()); - - axis.setMajorTickMark(AxisTickMark.OUT); - assertEquals(AxisTickMark.OUT, axis.getMajorTickMark()); - - axis.setMajorTickMark(AxisTickMark.CROSS); - assertEquals(AxisTickMark.CROSS, axis.getMajorTickMark()); - } - - public void testMinorTickMarkAccessMethods() { - axis.setMinorTickMark(AxisTickMark.NONE); - assertEquals(AxisTickMark.NONE, axis.getMinorTickMark()); - - axis.setMinorTickMark(AxisTickMark.IN); - assertEquals(AxisTickMark.IN, axis.getMinorTickMark()); - - axis.setMinorTickMark(AxisTickMark.OUT); - assertEquals(AxisTickMark.OUT, axis.getMinorTickMark()); - - axis.setMinorTickMark(AxisTickMark.CROSS); - assertEquals(AxisTickMark.CROSS, axis.getMinorTickMark()); - } - - public void testGetChartAxisBug57362() { - //Load existing excel with some chart on it having primary and secondary axis. - final Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("57362.xlsx"); - final Sheet sh = workbook.getSheetAt(0); - final XSSFSheet xsh = (XSSFSheet) sh; - final XSSFDrawing drawing = xsh.createDrawingPatriarch(); - final XSSFChart chart = drawing.getCharts().get(0); - - final List axisList = chart.getAxis(); - - assertEquals(4, axisList.size()); - assertNotNull(axisList.get(0)); - assertNotNull(axisList.get(1)); - assertNotNull(axisList.get(2)); - assertNotNull(axisList.get(3)); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java deleted file mode 100644 index 02aabad05..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.LegendPosition; -import org.apache.poi.xssf.usermodel.*; - -/** - * Tests ChartLegend - * - * @author Martin Andersson - * @author Cedric dot Walter at gmail dot com - */ -public final class TestXSSFChartLegend extends TestCase { - - public void testLegendPositionAccessMethods() throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - - legend.setPosition(LegendPosition.TOP_RIGHT); - assertEquals(LegendPosition.TOP_RIGHT, legend.getPosition()); - } - - public void test_setOverlay_defaultChartLegend_expectOverlayInitialValueSetToFalse() { - // Arrange - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - - // Act - - // Assert - assertFalse(legend.isOverlay()); - } - - public void test_setOverlay_chartLegendSetToTrue_expectOverlayInitialValueSetToTrue() { - // Arrange - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - - // Act - legend.setOverlay(true); - - // Assert - assertTrue(legend.isOverlay()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java deleted file mode 100644 index de0574930..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.*; - -import java.util.List; - -/** - * Test get/set chart title. - */ -public class TestXSSFChartTitle extends TestCase { - private Workbook createWorkbookWithChart() { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("linechart"); - final int NUM_OF_ROWS = 3; - final int NUM_OF_COLUMNS = 10; - - // Create a row and put some cells in it. Rows are 0 based. - Row row; - Cell cell; - for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) { - row = sheet.createRow((short) rowIndex); - for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) { - cell = row.createCell((short) colIndex); - cell.setCellValue(colIndex * (rowIndex + 1)); - } - } - - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); - - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - legend.setPosition(LegendPosition.TOP_RIGHT); - - LineChartData data = chart.getChartDataFactory().createLineChartData(); - - // Use a category axis for the bottom axis. - ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); - ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); - leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); - - ChartDataSource xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); - ChartDataSource ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); - ChartDataSource ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); - - data.addSeries(xs, ys1); - data.addSeries(xs, ys2); - - chart.plot(data, bottomAxis, leftAxis); - - return wb; - } - - /** - * Gets the first chart from the named sheet in the workbook. - */ - private XSSFChart getChartFromWorkbook(Workbook wb, String sheetName) { - Sheet sheet = wb.getSheet(sheetName); - if (sheet instanceof XSSFSheet) { - XSSFSheet xsheet = (XSSFSheet) sheet; - XSSFDrawing drawing = xsheet.getDrawingPatriarch(); - if (drawing != null) { - List charts = drawing.getCharts(); - if (charts != null && charts.size() > 0) { - return charts.get(0); - } - } - } - return null; - } - - public void testNewChart() { - Workbook wb = createWorkbookWithChart(); - XSSFChart chart = getChartFromWorkbook(wb, "linechart"); - assertNotNull(chart); - assertNull(chart.getTitle()); - final String myTitle = "My chart title"; - chart.setTitle(myTitle); - XSSFRichTextString queryTitle = chart.getTitle(); - assertNotNull(queryTitle); - assertEquals(myTitle, queryTitle.toString()); - } - - public void testExistingChartWithTitle() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_withTitle.xlsx"); - XSSFChart chart = getChartFromWorkbook(wb, "Sheet1"); - assertNotNull(chart); - XSSFRichTextString originalTitle = chart.getTitle(); - assertNotNull(originalTitle); - final String myTitle = "My chart title"; - assertFalse(myTitle.equals(originalTitle.toString())); - chart.setTitle(myTitle); - XSSFRichTextString queryTitle = chart.getTitle(); - assertNotNull(queryTitle); - assertEquals(myTitle, queryTitle.toString()); - } - - public void testExistingChartNoTitle() { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_noTitle.xlsx"); - XSSFChart chart = getChartFromWorkbook(wb, "Sheet1"); - assertNotNull(chart); - assertNull(chart.getTitle()); - final String myTitle = "My chart title"; - chart.setTitle(myTitle); - XSSFRichTextString queryTitle = chart.getTitle(); - assertNotNull(queryTitle); - assertEquals(myTitle, queryTitle.toString()); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java deleted file mode 100644 index cf7fd78ed..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.LineChartData; -import org.apache.poi.ss.usermodel.charts.LineChartSeries; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.SheetBuilder; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Tests for XSSF Line Charts - */ -public class TestXSSFLineChartData extends TestCase { - - private static final Object[][] plotData = { - {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}, - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - }; - - public void testOneSeriePlot() throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = new SheetBuilder(wb, plotData).build(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - Chart chart = drawing.createChart(anchor); - - ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); - ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); - - LineChartData lineChartData = - chart.getChartDataFactory().createLineChartData(); - - ChartDataSource xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); - ChartDataSource ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); - LineChartSeries series = lineChartData.addSeries(xs, ys); - - assertNotNull(series); - assertEquals(1, lineChartData.getSeries().size()); - assertTrue(lineChartData.getSeries().contains(series)); - - chart.plot(lineChartData, bottomAxis, leftAxis); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java deleted file mode 100644 index 8b5e8d92a..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.ManualLayout; -import org.apache.poi.ss.usermodel.charts.LayoutMode; -import org.apache.poi.ss.usermodel.charts.LayoutTarget; -import org.apache.poi.xssf.usermodel.*; - -public final class TestXSSFManualLayout extends TestCase { - - /* - * Accessor methods are not trivial. They use lazy underlying bean - * initialization so there can be some errors (NPE, for example). - */ - public void testAccessorMethods() throws Exception { - final double newRatio = 1.1; - final double newCoordinate = 0.3; - final LayoutMode nonDefaultMode = LayoutMode.FACTOR; - final LayoutTarget nonDefaultTarget = LayoutTarget.OUTER; - - ManualLayout layout = getEmptyLayout(); - - layout.setWidthRatio(newRatio); - assertTrue(layout.getWidthRatio() == newRatio); - - layout.setHeightRatio(newRatio); - assertTrue(layout.getHeightRatio() == newRatio); - - layout.setX(newCoordinate); - assertTrue(layout.getX() == newCoordinate); - - layout.setY(newCoordinate); - assertTrue(layout.getY() == newCoordinate); - - layout.setXMode(nonDefaultMode); - assertTrue(layout.getXMode() == nonDefaultMode); - - layout.setYMode(nonDefaultMode); - assertTrue(layout.getYMode() == nonDefaultMode); - - layout.setWidthMode(nonDefaultMode); - assertTrue(layout.getWidthMode() == nonDefaultMode); - - layout.setHeightMode(nonDefaultMode); - assertTrue(layout.getHeightMode() == nonDefaultMode); - - layout.setTarget(nonDefaultTarget); - assertTrue(layout.getTarget() == nonDefaultTarget); - - } - - /* - * Layout must have reasonable default values and must not throw - * any exceptions. - */ - public void testDefaultValues() throws Exception { - ManualLayout layout = getEmptyLayout(); - - assertNotNull(layout.getTarget()); - assertNotNull(layout.getXMode()); - assertNotNull(layout.getYMode()); - assertNotNull(layout.getHeightMode()); - assertNotNull(layout.getWidthMode()); - /* - * According to interface, 0.0 should be returned for - * uninitialized double properties. - */ - assertTrue(layout.getX() == 0.0); - assertTrue(layout.getY() == 0.0); - assertTrue(layout.getWidthRatio() == 0.0); - assertTrue(layout.getHeightRatio() == 0.0); - } - - private ManualLayout getEmptyLayout() { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); - return legend.getManualLayout(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java deleted file mode 100644 index e041e891c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.ScatterChartData; -import org.apache.poi.ss.usermodel.charts.ScatterChartSeries; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.SheetBuilder; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Tests for XSSFScatterChartData. - */ -public final class TestXSSFScatterChartData extends TestCase { - - private static final Object[][] plotData = { - {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - }; - - public void testOneSeriePlot() throws Exception { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = new SheetBuilder(wb, plotData).build(); - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - Chart chart = drawing.createChart(anchor); - - ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM); - ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); - - ScatterChartData scatterChartData = - chart.getChartDataFactory().createScatterChartData(); - - ChartDataSource xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); - ChartDataSource ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); - ScatterChartSeries series = scatterChartData.addSerie(xs, ys); - - assertNotNull(series); - assertEquals(1, scatterChartData.getSeries().size()); - assertTrue(scatterChartData.getSeries().contains(series)); - - chart.plot(scatterChartData, bottomAxis, leftAxis); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java deleted file mode 100644 index db8ded370..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.charts; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.usermodel.*; - -public final class TestXSSFValueAxis extends TestCase { - - public void testAccessMethods() throws Exception { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); - XSSFChart chart = drawing.createChart(anchor); - XSSFValueAxis axis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM); - - axis.setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); - assertEquals(axis.getCrossBetween(), AxisCrossBetween.MIDPOINT_CATEGORY); - - axis.setCrosses(AxisCrosses.AUTO_ZERO); - assertEquals(axis.getCrosses(), AxisCrosses.AUTO_ZERO); - - assertEquals(chart.getAxis().size(), 1); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFBorder.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFBorder.java deleted file mode 100644 index e7233c227..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFBorder.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder.BorderSide; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; - - -public class TestXSSFBorder extends TestCase { - - public void testGetBorderStyle() { - CTStylesheet stylesheet = CTStylesheet.Factory.newInstance(); - CTBorder border = stylesheet.addNewBorders().addNewBorder(); - CTBorderPr top = border.addNewTop(); - CTBorderPr right = border.addNewRight(); - CTBorderPr bottom = border.addNewBottom(); - - top.setStyle(STBorderStyle.DASH_DOT); - right.setStyle(STBorderStyle.NONE); - bottom.setStyle(STBorderStyle.THIN); - - XSSFCellBorder cellBorderStyle = new XSSFCellBorder(border); - assertEquals("DASH_DOT", cellBorderStyle.getBorderStyle(BorderSide.TOP).toString()); - - assertEquals("NONE", cellBorderStyle.getBorderStyle(BorderSide.RIGHT).toString()); - assertEquals(BorderStyle.NONE.ordinal(), cellBorderStyle.getBorderStyle(BorderSide.RIGHT).ordinal()); - - assertEquals("THIN", cellBorderStyle.getBorderStyle(BorderSide.BOTTOM).toString()); - - assertEquals(BorderStyle.THIN.ordinal(), cellBorderStyle.getBorderStyle(BorderSide.BOTTOM).ordinal()); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java deleted file mode 100644 index 832d6bfb2..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java +++ /dev/null @@ -1,101 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; - -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Test; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; - - -public class TestXSSFCellFill { - - @Test - public void testGetFillBackgroundColor() { - CTFill ctFill = CTFill.Factory.newInstance(); - XSSFCellFill cellFill = new XSSFCellFill(ctFill); - CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); - CTColor bgColor = ctPatternFill.addNewBgColor(); - assertNotNull(cellFill.getFillBackgroundColor()); - bgColor.setIndexed(2); - assertEquals(2, cellFill.getFillBackgroundColor().getIndexed()); - } - - @Test - public void testGetFillForegroundColor() { - CTFill ctFill = CTFill.Factory.newInstance(); - XSSFCellFill cellFill = new XSSFCellFill(ctFill); - CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); - CTColor fgColor = ctPatternFill.addNewFgColor(); - assertNotNull(cellFill.getFillForegroundColor()); - fgColor.setIndexed(8); - assertEquals(8, cellFill.getFillForegroundColor().getIndexed()); - } - - @Test - public void testGetSetPatternType() { - CTFill ctFill = CTFill.Factory.newInstance(); - XSSFCellFill cellFill = new XSSFCellFill(ctFill); - CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); - ctPatternFill.setPatternType(STPatternType.SOLID); - assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().intValue()-1); - } - - @Test - public void testGetNotModifies() { - CTFill ctFill = CTFill.Factory.newInstance(); - XSSFCellFill cellFill = new XSSFCellFill(ctFill); - CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); - ctPatternFill.setPatternType(STPatternType.DARK_DOWN); - assertEquals(8, cellFill.getPatternType().intValue()); - } - - @Test - public void testColorFromTheme() throws IOException { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("styles.xlsx"); - XSSFCell cellWithThemeColor = wb.getSheetAt(0).getRow(10).getCell(0); - //color RGB will be extracted from theme - XSSFColor foregroundColor = cellWithThemeColor.getCellStyle().getFillForegroundXSSFColor(); - byte[] rgb = foregroundColor.getRGB(); - byte[] rgbWithTint = foregroundColor.getRGBWithTint(); - // Dk2 - assertEquals(rgb[0],31); - assertEquals(rgb[1],73); - assertEquals(rgb[2],125); - // Dk2, lighter 40% (tint is about 0.39998) - // 31 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 120.59552 => 120 (byte) - // 73 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 145.79636 => -111 (byte) - // 125 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 176.99740 => -80 (byte) - assertEquals(rgbWithTint[0],120); - assertEquals(rgbWithTint[1],-111); - assertEquals(rgbWithTint[2],-80); - wb.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFSheetComments.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFSheetComments.java deleted file mode 100644 index b58078f06..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFSheetComments.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions; - -import junit.framework.TestCase; - -public class TestXSSFSheetComments extends TestCase { - // So eclipse doesn't moan - public void testTODO() { - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestColumnHelper.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestColumnHelper.java deleted file mode 100644 index 1ca8fb8be..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestColumnHelper.java +++ /dev/null @@ -1,379 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; - -/** - * Tests for {@link ColumnHelper} - * - */ -public final class TestColumnHelper extends TestCase { - - public void testCleanColumns() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - - CTCols cols1 = worksheet.addNewCols(); - CTCol col1 = cols1.addNewCol(); - col1.setMin(1); - col1.setMax(1); - col1.setWidth(88); - col1.setHidden(true); - CTCol col2 = cols1.addNewCol(); - col2.setMin(2); - col2.setMax(3); - CTCols cols2 = worksheet.addNewCols(); - CTCol col4 = cols2.addNewCol(); - col4.setMin(13); - col4.setMax(16384); - - // Test cleaning cols - assertEquals(2, worksheet.sizeOfColsArray()); - int count = countColumns(worksheet); - assertEquals(16375, count); - // Clean columns and test a clean worksheet - ColumnHelper helper = new ColumnHelper(worksheet); - assertEquals(1, worksheet.sizeOfColsArray()); - count = countColumns(worksheet); - assertEquals(16375, count); - // Remember - POI column 0 == OOXML column 1 - assertEquals(88.0, helper.getColumn(0, false).getWidth(), 0.0); - assertTrue(helper.getColumn(0, false).getHidden()); - assertEquals(0.0, helper.getColumn(1, false).getWidth(), 0.0); - assertFalse(helper.getColumn(1, false).getHidden()); - } - - public void testSortColumns() { - CTCols cols1 = CTCols.Factory.newInstance(); - CTCol col1 = cols1.addNewCol(); - col1.setMin(1); - col1.setMax(1); - col1.setWidth(88); - col1.setHidden(true); - CTCol col2 = cols1.addNewCol(); - col2.setMin(2); - col2.setMax(3); - CTCol col3 = cols1.addNewCol(); - col3.setMin(13); - col3.setMax(16750); - assertEquals(3, cols1.sizeOfColArray()); - CTCol col4 = cols1.addNewCol(); - col4.setMin(8); - col4.setMax(11); - assertEquals(4, cols1.sizeOfColArray()); - CTCol col5 = cols1.addNewCol(); - col5.setMin(4); - col5.setMax(5); - assertEquals(5, cols1.sizeOfColArray()); - CTCol col6 = cols1.addNewCol(); - col6.setMin(8); - col6.setMax(9); - col6.setHidden(true); - CTCol col7 = cols1.addNewCol(); - col7.setMin(6); - col7.setMax(8); - col7.setWidth(17.0); - CTCol col8 = cols1.addNewCol(); - col8.setMin(25); - col8.setMax(27); - CTCol col9 = cols1.addNewCol(); - col9.setMin(20); - col9.setMax(30); - assertEquals(9, cols1.sizeOfColArray()); - assertEquals(20, cols1.getColArray(8).getMin()); - assertEquals(30, cols1.getColArray(8).getMax()); - ColumnHelper.sortColumns(cols1); - assertEquals(9, cols1.sizeOfColArray()); - assertEquals(25, cols1.getColArray(8).getMin()); - assertEquals(27, cols1.getColArray(8).getMax()); - } - - public void testCloneCol() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - ColumnHelper helper = new ColumnHelper(worksheet); - - CTCols cols = CTCols.Factory.newInstance(); - CTCol col = CTCol.Factory.newInstance(); - col.setMin(2); - col.setMax(8); - col.setHidden(true); - col.setWidth(13.4); - CTCol newCol = helper.cloneCol(cols, col); - assertEquals(2, newCol.getMin()); - assertEquals(8, newCol.getMax()); - assertTrue(newCol.getHidden()); - assertEquals(13.4, newCol.getWidth(), 0.0); - } - - public void testAddCleanColIntoCols() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - ColumnHelper helper = new ColumnHelper(worksheet); - - CTCols cols1 = CTCols.Factory.newInstance(); - CTCol col1 = cols1.addNewCol(); - col1.setMin(1); - col1.setMax(1); - col1.setWidth(88); - col1.setHidden(true); - CTCol col2 = cols1.addNewCol(); - col2.setMin(2); - col2.setMax(3); - CTCol col3 = cols1.addNewCol(); - col3.setMin(13); - col3.setMax(16750); - assertEquals(3, cols1.sizeOfColArray()); - CTCol col4 = cols1.addNewCol(); - col4.setMin(8); - col4.setMax(9); - assertEquals(4, cols1.sizeOfColArray()); - - // No overlap - helper.addCleanColIntoCols(cols1, createCol(4, 5)); - assertEquals(5, cols1.sizeOfColArray()); - - // Overlaps with 8 - 9 (overlap and after replacements required) - CTCol col6 = createCol(8, 11); - col6.setHidden(true); - helper.addCleanColIntoCols(cols1, col6); - assertEquals(6, cols1.sizeOfColArray()); - - // Overlaps with 8 - 9 (before and overlap replacements required) - CTCol col7 = createCol(6, 8); - col7.setWidth(17.0); - helper.addCleanColIntoCols(cols1, col7); - assertEquals(8, cols1.sizeOfColArray()); - - // Overlaps with 13 - 16750 (before, overlap and after replacements required) - helper.addCleanColIntoCols(cols1, createCol(20, 30)); - assertEquals(10, cols1.sizeOfColArray()); - - // Overlaps with 20 - 30 (before, overlap and after replacements required) - helper.addCleanColIntoCols(cols1, createCol(25, 27)); - - // TODO - assert something interesting - assertEquals(12, cols1.sizeOfColArray()); - assertEquals(1, cols1.getColArray(0).getMin()); - assertEquals(16750, cols1.getColArray(11).getMax()); - } - - public void testAddCleanColIntoColsExactOverlap() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(1, 1, 1, 1); - assertEquals(1, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 1, true, true); - } - - public void testAddCleanColIntoColsOverlapsOverhangingBothSides() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(2, 2, 1, 3); - assertEquals(3, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 1, false, true); - assertMinMaxHiddenBestFit(cols, 1, 2, 2, true, true); - assertMinMaxHiddenBestFit(cols, 2, 3, 3, false, true); - } - - public void testAddCleanColIntoColsOverlapsCompletelyNested() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(1, 3, 2, 2); - assertEquals(3, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 1, true, false); - assertMinMaxHiddenBestFit(cols, 1, 2, 2, true, true); - assertMinMaxHiddenBestFit(cols, 2, 3, 3, true, false); - } - - public void testAddCleanColIntoColsNewOverlapsOverhangingLeftNotRightExactRight() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(2, 3, 1, 3); - assertEquals(2, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 1, false, true); - assertMinMaxHiddenBestFit(cols, 1, 2, 3, true, true); - } - - public void testAddCleanColIntoColsNewOverlapsOverhangingRightNotLeftExactLeft() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(1, 2, 1, 3); - assertEquals(2, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 2, true, true); - assertMinMaxHiddenBestFit(cols, 1, 3, 3, false, true); - } - - public void testAddCleanColIntoColsNewOverlapsOverhangingLeftNotRight() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(2, 3, 1, 2); - assertEquals(3, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 1, false, true); - assertMinMaxHiddenBestFit(cols, 1, 2, 2, true, true); - assertMinMaxHiddenBestFit(cols, 2, 3, 3, true, false); - } - - public void testAddCleanColIntoColsNewOverlapsOverhangingRightNotLeft() throws Exception { - CTCols cols = createHiddenAndBestFitColsWithHelper(1, 2, 2, 3); - assertEquals(3, cols.sizeOfColArray()); - assertMinMaxHiddenBestFit(cols, 0, 1, 1, true, false); - assertMinMaxHiddenBestFit(cols, 1, 2, 2, true, true); - assertMinMaxHiddenBestFit(cols, 2, 3, 3, false, true); - } - - /** - * Creates and adds a hidden column and then a best fit column with the given min/max pairs. - * Suitable for testing handling of overlap. - */ - private CTCols createHiddenAndBestFitColsWithHelper(int hiddenMin, int hiddenMax, int bestFitMin, int bestFitMax) { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - ColumnHelper helper = new ColumnHelper(worksheet); - CTCols cols = worksheet.getColsArray(0); - - CTCol hidden = createCol(hiddenMin, hiddenMax); - hidden.setHidden(true); - helper.addCleanColIntoCols(cols, hidden); - - CTCol bestFit = createCol(bestFitMin, bestFitMax); - bestFit.setBestFit(true); - helper.addCleanColIntoCols(cols, bestFit); - return cols; - } - - private void assertMinMaxHiddenBestFit(CTCols cols, int index, int min, int max, boolean hidden, boolean bestFit) { - CTCol col = cols.getColArray(index); - assertEquals(min, col.getMin()); - assertEquals(max, col.getMax()); - assertEquals(hidden, col.getHidden()); - assertEquals(bestFit, col.getBestFit()); - } - - private CTCol createCol(int min, int max) { - CTCol col = CTCol.Factory.newInstance(); - col.setMin(min); - col.setMax(max); - return col; - } - - public void testGetColumn() { - CTWorksheet worksheet = CTWorksheet.Factory.newInstance(); - - CTCols cols1 = worksheet.addNewCols(); - CTCol col1 = cols1.addNewCol(); - col1.setMin(1); - col1.setMax(1); - col1.setWidth(88); - col1.setHidden(true); - CTCol col2 = cols1.addNewCol(); - col2.setMin(2); - col2.setMax(3); - CTCols cols2 = worksheet.addNewCols(); - CTCol col4 = cols2.addNewCol(); - col4.setMin(3); - col4.setMax(6); - - // Remember - POI column 0 == OOXML column 1 - ColumnHelper helper = new ColumnHelper(worksheet); - assertNotNull(helper.getColumn(0, false)); - assertNotNull(helper.getColumn(1, false)); - assertEquals(88.0, helper.getColumn(0, false).getWidth(), 0.0); - assertEquals(0.0, helper.getColumn(1, false).getWidth(), 0.0); - assertTrue(helper.getColumn(0, false).getHidden()); - assertFalse(helper.getColumn(1, false).getHidden()); - assertNull(helper.getColumn(99, false)); - assertNotNull(helper.getColumn(5, false)); - } - - public void testSetColumnAttributes() { - CTCol col = CTCol.Factory.newInstance(); - col.setWidth(12); - col.setHidden(true); - CTCol newCol = CTCol.Factory.newInstance(); - assertEquals(0.0, newCol.getWidth(), 0.0); - assertFalse(newCol.getHidden()); - ColumnHelper helper = new ColumnHelper(CTWorksheet.Factory - .newInstance()); - helper.setColumnAttributes(col, newCol); - assertEquals(12.0, newCol.getWidth(), 0.0); - assertTrue(newCol.getHidden()); - } - - public void testGetOrCreateColumn() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet("Sheet 1"); - ColumnHelper columnHelper = sheet.getColumnHelper(); - - // Check POI 0 based, OOXML 1 based - CTCol col = columnHelper.getOrCreateColumn1Based(3, false); - assertNotNull(col); - assertNull(columnHelper.getColumn(1, false)); - assertNotNull(columnHelper.getColumn(2, false)); - assertNotNull(columnHelper.getColumn1Based(3, false)); - assertNull(columnHelper.getColumn(3, false)); - - CTCol col2 = columnHelper.getOrCreateColumn1Based(30, false); - assertNotNull(col2); - assertNull(columnHelper.getColumn(28, false)); - assertNotNull(columnHelper.getColumn(29, false)); - assertNotNull(columnHelper.getColumn1Based(30, false)); - assertNull(columnHelper.getColumn(30, false)); - } - - public void testGetSetColDefaultStyle() { - XSSFWorkbook workbook = new XSSFWorkbook(); - XSSFSheet sheet = workbook.createSheet(); - CTWorksheet ctWorksheet = sheet.getCTWorksheet(); - ColumnHelper columnHelper = sheet.getColumnHelper(); - - // POI column 3, OOXML column 4 - CTCol col = columnHelper.getOrCreateColumn1Based(4, false); - - assertNotNull(col); - assertNotNull(columnHelper.getColumn(3, false)); - columnHelper.setColDefaultStyle(3, 2); - assertEquals(2, columnHelper.getColDefaultStyle(3)); - assertEquals(-1, columnHelper.getColDefaultStyle(4)); - StylesTable stylesTable = workbook.getStylesSource(); - CTXf cellXf = CTXf.Factory.newInstance(); - cellXf.setFontId(0); - cellXf.setFillId(0); - cellXf.setBorderId(0); - cellXf.setNumFmtId(0); - cellXf.setXfId(0); - stylesTable.putCellXf(cellXf); - CTCol col_2 = ctWorksheet.getColsArray(0).addNewCol(); - col_2.setMin(10); - col_2.setMax(12); - col_2.setStyle(1); - assertEquals(1, columnHelper.getColDefaultStyle(11)); - XSSFCellStyle cellStyle = new XSSFCellStyle(0, 0, stylesTable, null); - columnHelper.setColDefaultStyle(11, cellStyle); - assertEquals(0, col_2.getStyle()); - assertEquals(1, columnHelper.getColDefaultStyle(10)); - } - - private static int countColumns(CTWorksheet worksheet) { - int count; - count = 0; - for (int i = 0; i < worksheet.sizeOfColsArray(); i++) { - for (int y = 0; y < worksheet.getColsArray(i).sizeOfColArray(); y++) { - for (long k = worksheet.getColsArray(i).getColArray(y).getMin(); k <= worksheet - .getColsArray(i).getColArray(y).getMax(); k++) { - count++; - } - } - } - return count; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestHeaderFooterHelper.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestHeaderFooterHelper.java deleted file mode 100644 index 2d25e3e95..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestHeaderFooterHelper.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; - -import org.apache.poi.xssf.usermodel.helpers.HeaderFooterHelper; - -/** - * Test the header and footer helper. - * As we go through XmlBeans, should always use &, - * and not & - */ -public class TestHeaderFooterHelper extends TestCase { - - public void testGetCenterLeftRightSection() { - HeaderFooterHelper helper = new HeaderFooterHelper(); - - String headerFooter = "&CTest the center section"; - assertEquals("Test the center section", helper.getCenterSection(headerFooter)); - - headerFooter = "&CTest the center section<he left one&RAnd the right one"; - assertEquals("Test the center section", helper.getCenterSection(headerFooter)); - assertEquals("The left one", helper.getLeftSection(headerFooter)); - assertEquals("And the right one", helper.getRightSection(headerFooter)); - } - - public void testSetCenterLeftRightSection() { - HeaderFooterHelper helper = new HeaderFooterHelper(); - String headerFooter = ""; - headerFooter = helper.setCenterSection(headerFooter, "First added center section"); - assertEquals("First added center section", helper.getCenterSection(headerFooter)); - headerFooter = helper.setLeftSection(headerFooter, "First left"); - assertEquals("First left", helper.getLeftSection(headerFooter)); - - headerFooter = helper.setRightSection(headerFooter, "First right"); - assertEquals("First right", helper.getRightSection(headerFooter)); - assertEquals("&CFirst added center section&LFirst left&RFirst right", headerFooter); - - headerFooter = helper.setRightSection(headerFooter, "First right&F"); - assertEquals("First right&F", helper.getRightSection(headerFooter)); - assertEquals("&CFirst added center section&LFirst left&RFirst right&F", headerFooter); - - headerFooter = helper.setRightSection(headerFooter, "First right&"); - assertEquals("First right&", helper.getRightSection(headerFooter)); - assertEquals("&CFirst added center section&LFirst left&RFirst right&", headerFooter); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/MemoryUsage.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/MemoryUsage.java deleted file mode 100644 index 812a92125..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/MemoryUsage.java +++ /dev/null @@ -1,217 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util; - -import junit.framework.TestCase; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.util.CellReference; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; - -import java.util.List; -import java.util.ArrayList; - -/** - * Mixed utilities for testing memory usage in XSSF - * - * @author Yegor Kozlov - */ -public class MemoryUsage extends TestCase { - private static final int NUM_COLUMNS = 255; - - private static void printMemoryUsage(String msg) { - System.out.println(" Memory (" + msg + "): " + Runtime.getRuntime().totalMemory()/(1024*1024) + "MB"); - } - - /** - * Generate a spreadsheet until OutOfMemoryError - *

        - * cells in even columns are numbers, cells in odd columns are strings - *

        - * - * @param wb the workbook to write to - * @param numCols the number of columns in a row - */ - public static void mixedSpreadsheet(Workbook wb, int numCols){ - - System.out.println("Testing " + wb.getClass().getName()); - printMemoryUsage("before"); - int i=0, cnt=0; - try { - Sheet sh = wb.createSheet(); - for(i=0; ; i++){ - Row row = sh.createRow(i); - for(int j=0; j < numCols; j++){ - Cell cell = row.createCell(j); - if(j % 2 == 0) cell.setCellValue(j); - else cell.setCellValue(new CellReference(j, i).formatAsString()); - cnt++; - } - } - } catch (OutOfMemoryError er){ - System.out.println("Failed at row=" + i + ", objects : " + cnt); - } catch (final Exception e) { - System.out.println("Unable to reach an OutOfMemoryError"); - System.out.println(e.getClass().getName() + ": " + e.getMessage()); - } - printMemoryUsage("after"); - } - - /** - * Generate a spreadsheet who's all cell values are numbers. - * The data is generated until OutOfMemoryError. - *

        - * as compared to {@link #mixedSpreadsheet(org.apache.poi.ss.usermodel.Workbook, int)}, - * this method does not set string values and, hence, does not involve the Shared Strings Table. - *

        - * - * @param wb the workbook to write to - * @param numCols the number of columns in a row - */ - public static void numberSpreadsheet(Workbook wb, int numCols){ - - System.out.println("Testing " + wb.getClass().getName()); - printMemoryUsage("before"); - int i=0, cnt=0; - try { - Sheet sh = wb.createSheet(); - for(i=0; ; i++){ - Row row = sh.createRow(i); - for(int j=0; j < numCols; j++){ - Cell cell = row.createCell(j); - cell.setCellValue(j); - cnt++; - } - } - } catch (OutOfMemoryError er){ - System.out.println("Failed at row=" + i + ", objects : " + cnt); - } catch (final Exception e) { - System.out.println("Unable to reach an OutOfMemoryError"); - System.out.println(e.getClass().getName() + ": " + e.getMessage()); - } - printMemoryUsage("after"); - } - - /** - * Generate a spreadsheet until OutOfMemoryError using low-level OOXML XmlBeans. - * Similar to {@link #numberSpreadsheet(org.apache.poi.ss.usermodel.Workbook, int)} - * - *

        - * - * @param numCols the number of columns in a row - */ - public static void xmlBeans(int numCols) { - int i = 0, cnt = 0; - printMemoryUsage("before"); - - CTWorksheet sh = CTWorksheet.Factory.newInstance(); - CTSheetData data = sh.addNewSheetData(); - try { - for (i = 0; ; i++) { - CTRow row = data.addNewRow(); - row.setR(i); - for (int j = 0; j < numCols; j++) { - CTCell cell = row.addNewC(); - cell.setT(STCellType.N); - cell.setV(String.valueOf(j)); - cnt++; - } - } - } catch (OutOfMemoryError er) { - System.out.println("Failed at row=" + i + ", objects: " + cnt); - } catch (final Exception e) { - System.out.println("Unable to reach an OutOfMemoryError"); - System.out.println(e.getClass().getName() + ": " + e.getMessage()); - } - printMemoryUsage("after"); - } - - /** - * Generate detached (parentless) Xml beans until OutOfMemoryError - * - * @see #testXmlAttached() - */ - public void testXmlDetached(){ - List rows = new ArrayList(); - int i = 0; - try { - for(;;){ - //create a standalone CTRow bean - CTRow r = CTRow.Factory.newInstance(); - r.setR(++i); - rows.add(r); - } - } catch (OutOfMemoryError er) { - System.out.println("Failed at row=" + i); - } catch (final Exception e) { - System.out.println("Unable to reach an OutOfMemoryError"); - System.out.println(e.getClass().getName() + ": " + e.getMessage()); - } - printMemoryUsage("after"); - } - - /** - * Generate attached (having a parent bean) Xml beans until OutOfMemoryError. - * This is MUCH more memory-efficient than {@link #testXmlDetached()} - * - * @see #testXmlAttached() - */ - public void testXmlAttached(){ - printMemoryUsage("before"); - List rows = new ArrayList(); - int i = 0; - //top-level element in sheet.xml - CTWorksheet sh = CTWorksheet.Factory.newInstance(); - CTSheetData data = sh.addNewSheetData(); - try { - for(;;){ - //create CTRow attached to the parent object - CTRow r = data.addNewRow(); - r.setR(++i); - rows.add(r); - } - } catch (OutOfMemoryError er) { - System.out.println("Failed at row=" + i); - } catch (final Exception e) { - System.out.println("Unable to reach an OutOfMemoryError"); - System.out.println(e.getClass().getName() + ": " + e.getMessage()); - } - printMemoryUsage("after"); - } - - public void testMixedHSSF(){ - numberSpreadsheet(new HSSFWorkbook(), NUM_COLUMNS); - } - - public void testMixedXSSF(){ - numberSpreadsheet(new XSSFWorkbook(), NUM_COLUMNS); - } - - public void testNumberHSSF(){ - numberSpreadsheet(new HSSFWorkbook(), NUM_COLUMNS); - } - - public void testNumberXSSF(){ - numberSpreadsheet(new XSSFWorkbook(), NUM_COLUMNS); - } - -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/TestCTColComparator.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/TestCTColComparator.java deleted file mode 100644 index 9fa8320bb..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/TestCTColComparator.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util; - -import java.util.Arrays; - -import junit.framework.TestCase; - -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; - - -public final class TestCTColComparator extends TestCase { - - public void testCompare() { - CTCol o1 = CTCol.Factory.newInstance(); - o1.setMin(1); - o1.setMax(10); - CTCol o2 = CTCol.Factory.newInstance(); - o2.setMin(11); - o2.setMax(12); - assertEquals(-1, CTColComparator.BY_MIN_MAX.compare(o1, o2)); - CTCol o3 = CTCol.Factory.newInstance(); - o3.setMin(5); - o3.setMax(8); - CTCol o4 = CTCol.Factory.newInstance(); - o4.setMin(5); - o4.setMax(80); - assertEquals(-1, CTColComparator.BY_MIN_MAX.compare(o3, o4)); - } - - public void testArraysSort() { - CTCol o1 = CTCol.Factory.newInstance(); - o1.setMin(1); - o1.setMax(10); - CTCol o2 = CTCol.Factory.newInstance(); - o2.setMin(11); - o2.setMax(12); - assertEquals(-1, CTColComparator.BY_MIN_MAX.compare(o1, o2)); - CTCol o3 = CTCol.Factory.newInstance(); - o3.setMin(5); - o3.setMax(80); - CTCol o4 = CTCol.Factory.newInstance(); - o4.setMin(5); - o4.setMax(8); - assertEquals(1, CTColComparator.BY_MIN_MAX.compare(o3, o4)); - CTCol[] cols = new CTCol[4]; - cols[0] = o1; - cols[1] = o2; - cols[2] = o3; - cols[3] = o4; - assertEquals(80, cols[2].getMax()); - assertEquals(8, cols[3].getMax()); - Arrays.sort(cols, CTColComparator.BY_MIN_MAX); - assertEquals(12, cols[3].getMax()); - assertEquals(8, cols[1].getMax()); - assertEquals(80, cols[2].getMax()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/TestEvilUnclosedBRFixingInputStream.java b/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/TestEvilUnclosedBRFixingInputStream.java deleted file mode 100644 index a15b22c1c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xssf/util/TestEvilUnclosedBRFixingInputStream.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import junit.framework.TestCase; - -public final class TestEvilUnclosedBRFixingInputStream extends TestCase { - public void testOK() throws Exception { - byte[] ok = "

        Hello There!
        Tags!

        ".getBytes("UTF-8"); - - EvilUnclosedBRFixingInputStream inp = new EvilUnclosedBRFixingInputStream( - new ByteArrayInputStream(ok) - ); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - boolean going = true; - while(going) { - byte[] b = new byte[1024]; - int r = inp.read(b); - if(r > 0) { - bout.write(b, 0, r); - } else { - going = false; - } - } - - byte[] result = bout.toByteArray(); - assertEquals(ok, result); - } - - public void testProblem() throws Exception { - byte[] orig = "

        Hello
        There!
        Tags!

        ".getBytes("UTF-8"); - byte[] fixed = "

        Hello
        There!
        Tags!

        ".getBytes("UTF-8"); - - EvilUnclosedBRFixingInputStream inp = new EvilUnclosedBRFixingInputStream( - new ByteArrayInputStream(orig) - ); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - boolean going = true; - while(going) { - byte[] b = new byte[1024]; - int r = inp.read(b); - if(r > 0) { - bout.write(b, 0, r); - } else { - going = false; - } - } - - byte[] result = bout.toByteArray(); - assertEquals(fixed, result); - } - - /** - * Checks that we can copy with br tags around the buffer boundaries - */ - public void testBufferSize() throws Exception { - byte[] orig = "

        Hello

        There!
        Tags!

        ".getBytes("UTF-8"); - byte[] fixed = "

        Hello

        There!
        Tags!

        ".getBytes("UTF-8"); - - // Vary the buffer size, so that we can end up with the br in the - // overflow or only part in the buffer - for(int i=5; i 0) { - bout.write(b, 0, r); - } else { - going = false; - } - } - - byte[] result = bout.toByteArray(); - assertEquals(fixed, result); - } - } - - protected void assertEquals(byte[] a, byte[] b) { - assertEquals(a.length, b.length); - for(int i=0; iorg.apache.poi.xwpf and sub-packages. - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - TestXWPFBugs.class, - org.apache.poi.xwpf.usermodel.TestXWPFBugs.class, - TestXWPFDocument.class, - TestXWPFWordExtractor.class, - TestXWPFHeaderFooterPolicy.class, - TestXWPFHeader.class, - TestXWPFHeadings.class, - TestXWPFParagraph.class, - TestXWPFRun.class, - TestXWPFTable.class, - TestXWPFStyles.class, - TestXWPFPictureData.class, - TestXWPFNumbering.class, - TestAllExtendedProperties.class, - TestPackageCorePropertiesGetKeywords.class -}) -public final class AllXWPFTests { -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java deleted file mode 100644 index ff955dadb..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.IOException; - -import junit.framework.TestCase; -import org.apache.poi.POIXMLProperties.CoreProperties; -import org.apache.poi.openxml4j.opc.PackageProperties; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTDigSigBlob; -import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties; -import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTVectorLpstr; -import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTVectorVariant; - -/** - * Tests if the {@link CoreProperties#getKeywords()} method. This test has been - * submitted because even though the - * {@link PackageProperties#getKeywordsProperty()} had been present before, the - * {@link CoreProperties#getKeywords()} had been missing. - *

        - * The author of this has added {@link CoreProperties#getKeywords()} and - * {@link CoreProperties#setKeywords(String)} and this test is supposed to test - * them. - * - * @author Antoni Mylka - */ -public final class TestAllExtendedProperties extends TestCase { - public void testGetAllExtendedProperties() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx"); - CTProperties ctProps = doc.getProperties().getExtendedProperties().getUnderlyingProperties(); - assertEquals("Microsoft Office Word", ctProps.getApplication()); - assertEquals("14.0000", ctProps.getAppVersion()); - assertEquals(57, ctProps.getCharacters()); - assertEquals(66, ctProps.getCharactersWithSpaces()); - assertEquals("", ctProps.getCompany()); - assertNull(ctProps.getDigSig()); - assertEquals(0, ctProps.getDocSecurity()); - assertNotNull(ctProps.getDomNode()); - - CTVectorVariant vec = ctProps.getHeadingPairs(); - assertEquals(2, vec.getVector().sizeOfVariantArray()); - assertEquals("Title", vec.getVector().getVariantArray(0).getLpstr()); - assertEquals(1, vec.getVector().getVariantArray(1).getI4()); - - assertFalse(ctProps.isSetHiddenSlides()); - assertEquals(0, ctProps.getHiddenSlides()); - assertFalse(ctProps.isSetHLinks()); - assertNull(ctProps.getHLinks()); - assertNull(ctProps.getHyperlinkBase()); - assertTrue(ctProps.isSetHyperlinksChanged()); - assertFalse(ctProps.getHyperlinksChanged()); - assertEquals(1, ctProps.getLines()); - assertTrue(ctProps.isSetLinksUpToDate()); - assertFalse(ctProps.getLinksUpToDate()); - assertNull(ctProps.getManager()); - assertFalse(ctProps.isSetMMClips()); - assertEquals(0, ctProps.getMMClips()); - assertFalse(ctProps.isSetNotes()); - assertEquals(0, ctProps.getNotes()); - assertEquals(1, ctProps.getPages()); - assertEquals(1, ctProps.getParagraphs()); - assertNull(ctProps.getPresentationFormat()); - assertTrue(ctProps.isSetScaleCrop()); - assertFalse(ctProps.getScaleCrop()); - assertTrue(ctProps.isSetSharedDoc()); - assertFalse(ctProps.getSharedDoc()); - assertFalse(ctProps.isSetSlides()); - assertEquals(0, ctProps.getSlides()); - assertEquals("Normal.dotm", ctProps.getTemplate()); - - CTVectorLpstr vec2 = ctProps.getTitlesOfParts(); - assertEquals(1, vec2.getVector().sizeOfLpstrArray()); - assertEquals("Example Word 2010 Document", vec2.getVector().getLpstrArray(0)); - - assertEquals(3, ctProps.getTotalTime()); - assertEquals(10, ctProps.getWords()); - - // Check the digital signature part - // Won't be there in this file, but we - // need to do this check so that the - // appropriate parts end up in the - // smaller ooxml schemas file - CTDigSigBlob blob = ctProps.getDigSig(); - assertNull(blob); - - blob = CTDigSigBlob.Factory.newInstance(); - blob.setBlob(new byte[]{2, 6, 7, 2, 3, 4, 5, 1, 2, 3}); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java deleted file mode 100644 index 67ad79422..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestDocumentProtection.java +++ /dev/null @@ -1,182 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.util.TempFile; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; -import org.junit.Test; - -public class TestDocumentProtection { - - @Test - public void testShouldReadEnforcementProperties() throws Exception { - - XWPFDocument documentWithoutDocumentProtectionTag = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx"); - assertFalse(documentWithoutDocumentProtectionTag.isEnforcedReadonlyProtection()); - assertFalse(documentWithoutDocumentProtectionTag.isEnforcedFillingFormsProtection()); - assertFalse(documentWithoutDocumentProtectionTag.isEnforcedCommentsProtection()); - assertFalse(documentWithoutDocumentProtectionTag.isEnforcedTrackedChangesProtection()); - - XWPFDocument documentWithoutEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection_tag_existing.docx"); - assertFalse(documentWithoutEnforcement.isEnforcedReadonlyProtection()); - assertFalse(documentWithoutEnforcement.isEnforcedFillingFormsProtection()); - assertFalse(documentWithoutEnforcement.isEnforcedCommentsProtection()); - assertFalse(documentWithoutEnforcement.isEnforcedTrackedChangesProtection()); - - XWPFDocument documentWithReadonlyEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_readonly_no_password.docx"); - assertTrue(documentWithReadonlyEnforcement.isEnforcedReadonlyProtection()); - assertFalse(documentWithReadonlyEnforcement.isEnforcedFillingFormsProtection()); - assertFalse(documentWithReadonlyEnforcement.isEnforcedCommentsProtection()); - assertFalse(documentWithReadonlyEnforcement.isEnforcedTrackedChangesProtection()); - - XWPFDocument documentWithFillingFormsEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_forms_no_password.docx"); - assertTrue(documentWithFillingFormsEnforcement.isEnforcedFillingFormsProtection()); - assertFalse(documentWithFillingFormsEnforcement.isEnforcedReadonlyProtection()); - assertFalse(documentWithFillingFormsEnforcement.isEnforcedCommentsProtection()); - assertFalse(documentWithFillingFormsEnforcement.isEnforcedTrackedChangesProtection()); - - XWPFDocument documentWithCommentsEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_comments_no_password.docx"); - assertFalse(documentWithCommentsEnforcement.isEnforcedFillingFormsProtection()); - assertFalse(documentWithCommentsEnforcement.isEnforcedReadonlyProtection()); - assertTrue(documentWithCommentsEnforcement.isEnforcedCommentsProtection()); - assertFalse(documentWithCommentsEnforcement.isEnforcedTrackedChangesProtection()); - - XWPFDocument documentWithTrackedChangesEnforcement = XWPFTestDataSamples.openSampleDocument("documentProtection_trackedChanges_no_password.docx"); - assertFalse(documentWithTrackedChangesEnforcement.isEnforcedFillingFormsProtection()); - assertFalse(documentWithTrackedChangesEnforcement.isEnforcedReadonlyProtection()); - assertFalse(documentWithTrackedChangesEnforcement.isEnforcedCommentsProtection()); - assertTrue(documentWithTrackedChangesEnforcement.isEnforcedTrackedChangesProtection()); - - } - - @Test - public void testShouldEnforceForReadOnly() throws Exception { - // XWPFDocument document = createDocumentFromSampleFile("test-data/document/documentProtection_no_protection.docx"); - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx"); - assertFalse(document.isEnforcedReadonlyProtection()); - - document.enforceReadonlyProtection(); - - assertTrue(document.isEnforcedReadonlyProtection()); - } - - @Test - public void testShouldEnforceForFillingForms() throws Exception { - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx"); - assertFalse(document.isEnforcedFillingFormsProtection()); - - document.enforceFillingFormsProtection(); - - assertTrue(document.isEnforcedFillingFormsProtection()); - } - - @Test - public void testShouldEnforceForComments() throws Exception { - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx"); - assertFalse(document.isEnforcedCommentsProtection()); - - document.enforceCommentsProtection(); - - assertTrue(document.isEnforcedCommentsProtection()); - } - - @Test - public void testShouldEnforceForTrackedChanges() throws Exception { - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("documentProtection_no_protection.docx"); - assertFalse(document.isEnforcedTrackedChangesProtection()); - - document.enforceTrackedChangesProtection(); - - assertTrue(document.isEnforcedTrackedChangesProtection()); - } - - @Test - public void testShouldUnsetEnforcement() throws Exception { - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("documentProtection_readonly_no_password.docx"); - assertTrue(document.isEnforcedReadonlyProtection()); - - document.removeProtectionEnforcement(); - - assertFalse(document.isEnforcedReadonlyProtection()); - } - - @Test - public void testIntegration() throws Exception { - XWPFDocument doc = new XWPFDocument(); - - XWPFParagraph p1 = doc.createParagraph(); - - XWPFRun r1 = p1.createRun(); - r1.setText("Lorem ipsum dolor sit amet."); - doc.enforceCommentsProtection(); - - File tempFile = TempFile.createTempFile("documentProtectionFile", ".docx"); - FileOutputStream out = new FileOutputStream(tempFile); - - doc.write(out); - out.close(); - - FileInputStream inputStream = new FileInputStream(tempFile); - XWPFDocument document = new XWPFDocument(inputStream); - inputStream.close(); - - assertTrue(document.isEnforcedCommentsProtection()); - } - - @Test - public void testUpdateFields() throws Exception { - XWPFDocument doc = new XWPFDocument(); - assertFalse(doc.isEnforcedUpdateFields()); - doc.enforceUpdateFields(); - assertTrue(doc.isEnforcedUpdateFields()); - } - - @Test - public void bug56076_read() throws Exception { - // test legacy xored-hashed password - assertEquals("64CEED7E", CryptoFunctions.xorHashPassword("Example")); - // check leading 0 - assertEquals("0005CB00", CryptoFunctions.xorHashPassword("34579")); - - // test document write protection with password - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("bug56076.docx"); - boolean isValid = document.validateProtectionPassword("Example"); - assertTrue(isValid); - } - - @Test - public void bug56076_write() throws Exception { - // test document write protection with password - XWPFDocument document = new XWPFDocument(); - document.enforceCommentsProtection("Example", HashAlgorithm.sha512); - document = XWPFTestDataSamples.writeOutAndReadBack(document); - boolean isValid = document.validateProtectionPassword("Example"); - assertTrue(isValid); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java deleted file mode 100644 index 85a21f12b..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.IOException; - -import junit.framework.TestCase; -import org.apache.poi.POIXMLProperties.CoreProperties; -import org.apache.poi.openxml4j.opc.PackageProperties; -import org.apache.poi.xwpf.usermodel.XWPFDocument; - -/** - * Tests if the {@link CoreProperties#getKeywords()} method. This test has been - * submitted because even though the - * {@link PackageProperties#getKeywordsProperty()} had been present before, the - * {@link CoreProperties#getKeywords()} had been missing. - *

        - * The author of this has added {@link CoreProperties#getKeywords()} and - * {@link CoreProperties#setKeywords(String)} and this test is supposed to test - * them. - * - * @author Antoni Mylka - */ -public final class TestPackageCorePropertiesGetKeywords extends TestCase { - public void testGetSetKeywords() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx"); - String keywords = doc.getProperties().getCoreProperties().getKeywords(); - assertEquals("extractor, test, rdf", keywords); - - doc.getProperties().getCoreProperties().setKeywords("test, keywords"); - doc = XWPFTestDataSamples.writeOutAndReadBack(doc); - keywords = doc.getProperties().getCoreProperties().getKeywords(); - assertEquals("test, keywords", keywords); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java deleted file mode 100644 index 92f738ce1..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import javax.crypto.Cipher; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.xwpf.extractor.XWPFWordExtractor; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.xmlbeans.XmlException; -import org.junit.Assume; -import org.junit.Test; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument; - -public class TestXWPFBugs { - /** - * A word document that's encrypted with non-standard - * Encryption options, and no cspname section. See bug 53475 - */ - @Test - public void bug53475NoCSPName() throws Exception { - File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-solrcell.docx"); - NPOIFSFileSystem filesystem = new NPOIFSFileSystem(file, true); - - // Check the encryption details - EncryptionInfo info = new EncryptionInfo(filesystem); - assertEquals(128, info.getHeader().getKeySize()); - assertEquals(CipherAlgorithm.aes128, info.getHeader().getCipherAlgorithm()); - assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx()); - - // Check it can be decoded - Decryptor d = Decryptor.getInstance(info); - assertTrue("Unable to process: document is encrypted", d.verifyPassword("solrcell")); - - // Check we can read the word document in that - InputStream dataStream = d.getDataStream(filesystem); - OPCPackage opc = OPCPackage.open(dataStream); - XWPFDocument doc = new XWPFDocument(opc); - XWPFWordExtractor ex = new XWPFWordExtractor(doc); - String text = ex.getText(); - assertNotNull(text); - assertEquals("This is password protected Word document.", text.trim()); - ex.close(); - - filesystem.close(); - } - - /** - * A word document with aes-256, i.e. aes is always 128 bit (= 128 bit block size), - * but the key can be 128/192/256 bits - */ - @Test - public void bug53475_aes256() throws Exception { - int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); - Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647); - - File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-pass.docx"); - NPOIFSFileSystem filesystem = new NPOIFSFileSystem(file, true); - - // Check the encryption details - EncryptionInfo info = new EncryptionInfo(filesystem); - assertEquals(16, info.getHeader().getBlockSize()); - assertEquals(256, info.getHeader().getKeySize()); - assertEquals(CipherAlgorithm.aes256, info.getHeader().getCipherAlgorithm()); - assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx()); - - // Check it can be decoded - Decryptor d = Decryptor.getInstance(info); - assertTrue("Unable to process: document is encrypted", d.verifyPassword("pass")); - - // Check we can read the word document in that - InputStream dataStream = d.getDataStream(filesystem); - OPCPackage opc = OPCPackage.open(dataStream); - XWPFDocument doc = new XWPFDocument(opc); - XWPFWordExtractor ex = new XWPFWordExtractor(doc); - String text = ex.getText(); - assertNotNull(text); - // I know ... a stupid typo, maybe next time ... - assertEquals("The is a password protected document.", text.trim()); - ex.close(); - - filesystem.close(); - } - - - @Test - public void bug59058() throws IOException, XmlException { - String files[] = { "bug57031.docx", "bug59058.docx" }; - for (String f : files) { - ZipFile zf = new ZipFile(POIDataSamples.getDocumentInstance().getFile(f)); - ZipEntry entry = zf.getEntry("word/document.xml"); - DocumentDocument document = DocumentDocument.Factory.parse(zf.getInputStream(entry)); - assertNotNull(document); - zf.close(); - } - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/XWPFTestDataSamples.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/XWPFTestDataSamples.java deleted file mode 100644 index d7f222240..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/XWPFTestDataSamples.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.util.IOUtils; -import org.apache.poi.xwpf.usermodel.XWPFDocument; - -/** - * @author Yegor Kozlov - */ -public class XWPFTestDataSamples { - - public static XWPFDocument openSampleDocument(String sampleName) throws IOException { - InputStream is = POIDataSamples.getDocumentInstance().openResourceAsStream(sampleName); - return new XWPFDocument(is); - } - - public static XWPFDocument writeOutAndReadBack(XWPFDocument doc) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); - doc.write(baos); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - return new XWPFDocument(bais); - } - - public static byte[] getImage(String filename) throws IOException { - InputStream is = POIDataSamples.getDocumentInstance().openResourceAsStream(filename); - try { - return IOUtils.toByteArray(is); - } finally { - is.close(); - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java deleted file mode 100644 index 929d43041..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFDocument; - -public class TestExternalEntities extends TestCase { - - /** - * Get text out of the simple file - * - * @throws IOException - */ - public void testFile() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ExternalEntityInText.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - String text = extractor.getText(); - - assertTrue(text.length() > 0); - - // Check contents, they should not contain the text from POI web site after colon! - assertEquals("Here should not be the POI web site: \"\"", text.trim()); - - extractor.close(); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java deleted file mode 100644 index cf1ba0a6b..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java +++ /dev/null @@ -1,411 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.extractor; - -import java.io.IOException; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import junit.framework.TestCase; - -import org.apache.poi.util.StringUtil; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFDocument; - -/** - * Tests for HXFWordExtractor - */ -public class TestXWPFWordExtractor extends TestCase { - - /** - * Get text out of the simple file - * - * @throws IOException - */ - public void testGetSimpleText() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - // Check contents - assertTrue(text.startsWith( - "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc at risus vel erat tempus posuere. Aenean non ante. Suspendisse vehicula dolor sit amet odio." - )); - assertTrue(text.endsWith( - "Phasellus ultricies mi nec leo. Sed tempus. In sit amet lorem at velit faucibus vestibulum.\n" - )); - - // Check number of paragraphs by counting number of newlines - int numberOfParagraphs = StringUtil.countMatches(text, '\n'); - assertEquals(3, numberOfParagraphs); - - extractor.close(); - } - - /** - * Tests getting the text out of a complex file - * - * @throws IOException - */ - public void testGetComplexText() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - String text = extractor.getText(); - assertTrue(text.length() > 0); - - char euro = '\u20ac'; -// System.err.println("'"+text.substring(text.length() - 40) + "'"); - - // Check contents - assertTrue(text.startsWith( - " \n(V) ILLUSTRATIVE CASES\n\n" - )); - assertTrue(text.contains( - "As well as gaining " + euro + "90 from child benefit increases, he will also receive the early childhood supplement of " + euro + "250 per quarter for Vincent for the full four quarters of the year.\n\n\n\n"// \n\n\n" - )); - assertTrue(text.endsWith( - "11.4%\t\t90\t\t\t\t\t250\t\t1,310\t\n\n \n\n\n" - )); - - // Check number of paragraphs by counting number of newlines - int numberOfParagraphs = StringUtil.countMatches(text, '\n'); - assertEquals(134, numberOfParagraphs); - - extractor.close(); - } - - public void testGetWithHyperlinks() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - // Now check contents - extractor.setFetchHyperlinks(false); - assertEquals( - "This is a test document.\nThis bit is in bold and italic\n" + - "Back to normal\n" + - "This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.\n" + - "We have a hyperlink here, and another.\n", - extractor.getText() - ); - - // One hyperlink is a real one, one is just to the top of page - extractor.setFetchHyperlinks(true); - assertEquals( - "This is a test document.\nThis bit is in bold and italic\n" + - "Back to normal\n" + - "This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.\n" + - "We have a hyperlink here, and another.\n", - extractor.getText() - ); - - extractor.close(); - } - - public void testHeadersFooters() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ThreeColHeadFoot.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - assertEquals( - "First header column!\tMid header\tRight header!\n" + - "This is a sample word document. It has two pages. It has a three column heading, and a three column footer\n" + - "\n" + - "HEADING TEXT\n" + - "\n" + - "More on page one\n" + - "\n\n" + - "End of page 1\n\n\n" + - "This is page two. It also has a three column heading, and a three column footer.\n" + - "Footer Left\tFooter Middle\tFooter Right\n", - extractor.getText() - ); - - // Now another file, expect multiple headers - // and multiple footers - doc = XWPFTestDataSamples.openSampleDocument("DiffFirstPageHeadFoot.docx"); - extractor.close(); - - extractor = new XWPFWordExtractor(doc); - extractor.close(); - - extractor = - new XWPFWordExtractor(doc); - extractor.getText(); - - assertEquals( - "I am the header on the first page, and I" + '\u2019' + "m nice and simple\n" + - "First header column!\tMid header\tRight header!\n" + - "This is a sample word document. It has two pages. It has a simple header and footer, which is different to all the other pages.\n" + - "\n" + - "HEADING TEXT\n" + - "\n" + - "More on page one\n" + - "\n\n" + - "End of page 1\n\n\n" + - "This is page two. It also has a three column heading, and a three column footer.\n" + - "The footer of the first page\n" + - "Footer Left\tFooter Middle\tFooter Right\n", - extractor.getText() - ); - - extractor.close(); - } - - public void testFootnotes() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("footnotes.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - String text = extractor.getText(); - assertTrue(text.contains("snoska")); - assertTrue(text.contains("Eto ochen prostoy[footnoteRef:1] text so snoskoy")); - - extractor.close(); - } - - - public void testTableFootnotes() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("table_footnotes.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - assertTrue(extractor.getText().contains("snoska")); - - extractor.close(); - } - - public void testFormFootnotes() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("form_footnotes.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - String text = extractor.getText(); - assertTrue("Unable to find expected word in text\n" + text, text.contains("testdoc")); - assertTrue("Unable to find expected word in text\n" + text, text.contains("test phrase")); - - extractor.close(); - } - - public void testEndnotes() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("endnotes.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - String text = extractor.getText(); - assertTrue(text.contains("XXX")); - assertTrue(text.contains("tilaka [endnoteRef:2]or 'tika'")); - - extractor.close(); - } - - public void testInsertedDeletedText() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("delins.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - assertTrue(extractor.getText().contains("pendant worn")); - assertTrue(extractor.getText().contains("extremely well")); - - extractor.close(); - } - - public void testParagraphHeader() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Headers.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - assertTrue(extractor.getText().contains("Section 1")); - assertTrue(extractor.getText().contains("Section 2")); - assertTrue(extractor.getText().contains("Section 3")); - - extractor.close(); - } - - /** - * Test that we can open and process .docm - * (macro enabled) docx files (bug #45690) - * - * @throws IOException - */ - public void testDOCMFiles() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("45690.docm"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - assertTrue(extractor.getText().contains("2004")); - assertTrue(extractor.getText().contains("2008")); - assertTrue(extractor.getText().contains("(120 ")); - - extractor.close(); - } - - /** - * Test that we handle things like tabs and - * carriage returns properly in the text that - * we're extracting (bug #49189) - * - * @throws IOException - */ - public void testDocTabs() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithTabs.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - // Check bits - assertTrue(extractor.getText().contains("a")); - assertTrue(extractor.getText().contains("\t")); - assertTrue(extractor.getText().contains("b")); - - // Now check the first paragraph in total - assertTrue(extractor.getText().contains("a\tb\n")); - - extractor.close(); - } - - /** - * The output should not contain field codes, e.g. those specified in the - * w:instrText tag (spec sec. 17.16.23) - * - * @throws IOException - */ - public void testNoFieldCodes() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FieldCodes.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - String text = extractor.getText(); - assertTrue(text.length() > 0); - assertFalse(text.contains("AUTHOR")); - assertFalse(text.contains("CREATEDATE")); - - extractor.close(); - } - - /** - * The output should contain the values of simple fields, those specified - * with the fldSimple element (spec sec. 17.16.19) - * - * @throws IOException - */ - public void testFldSimpleContent() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FldSimple.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - String text = extractor.getText(); - assertTrue(text.length() > 0); - assertTrue(text.contains("FldSimple.docx")); - - extractor.close(); - } - - /** - * Test for parsing document with drawings to prevent - * NoClassDefFoundError for CTAnchor in XWPFRun - */ - public void testDrawings() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("drawing.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - String text = extractor.getText(); - assertTrue(text.length() > 0); - - extractor.close(); - } - - /** - * Test for basic extraction of SDT content - * - * @throws IOException - */ - public void testSimpleControlContent() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx"); - String[] targs = new String[]{ - "header_rich_text", - "rich_text", - "rich_text_pre_table\nrich_text_cell1\t\t\t\n\t\t\t\n\t\t\t\n\nrich_text_post_table", - "plain_text_no_newlines", - "plain_text_with_newlines1\nplain_text_with_newlines2\n", - "watermelon\n", - "dirt\n", - "4/16/2013\n", - "rich_text_in_cell", - "abc", - "rich_text_in_paragraph_in_cell", - "footer_rich_text", - "footnote_sdt", - "endnote_sdt" - }; - XWPFWordExtractor ex = new XWPFWordExtractor(doc); - String s = ex.getText().toLowerCase(Locale.ROOT); - int hits = 0; - - for (String targ : targs) { - boolean hit = false; - if (s.contains(targ)) { - hit = true; - hits++; - } - assertEquals("controlled content loading-" + targ, true, hit); - } - assertEquals("controlled content loading hit count", targs.length, hits); - ex.close(); - - - doc = XWPFTestDataSamples.openSampleDocument("Bug54771a.docx"); - targs = new String[]{ - "bb", - "test subtitle\n", - "test user\n", - }; - ex = new XWPFWordExtractor(doc); - s = ex.getText().toLowerCase(Locale.ROOT); - - //At one point in development there were three copies of the text. - //This ensures that there is only one copy. - for (String targ : targs) { - Matcher m = Pattern.compile(targ).matcher(s); - int hit = 0; - while (m.find()) { - hit++; - } - assertEquals("controlled content loading-" + targ, 1, hit); - } - //"test\n" appears twice: once as the "title" and once in the text. - //This also happens when you save this document as text from MSWord. - Matcher m = Pattern.compile("test\n").matcher(s); - int hit = 0; - while (m.find()) { - hit++; - } - assertEquals("test", 2, hit); - ex.close(); - } - - /** - * No Header or Footer in document - */ - public void testBug55733() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("55733.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - // Check it gives text without error - extractor.getText(); - extractor.close(); - } - - public void testCheckboxes() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("checkboxes.docx"); - XWPFWordExtractor extractor = new XWPFWordExtractor(doc); - - assertEquals("This is a small test for checkboxes \nunchecked: |_| \n" + - "Or checked: |X|\n\n\n\n\n" + - "Test a checkbox within a textbox: |_| -> |X|\n\n\n" + - "In Table:\n|_|\t|X|\n\n\n" + - "In Sequence:\n|X||_||X|\n", extractor.getText()); - extractor.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java deleted file mode 100644 index d12020b51..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java +++ /dev/null @@ -1,80 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import java.io.IOException; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; - -/** - * Tests for the various XWPF decorators - */ -public class TestXWPFDecorators extends TestCase { - private XWPFDocument simple; - private XWPFDocument hyperlink; - private XWPFDocument comments; - - @Override - protected void setUp() throws IOException { - simple = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); - hyperlink = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); - comments = XWPFTestDataSamples.openSampleDocument("WordWithAttachments.docx"); - } - - public void testHyperlink() { - XWPFParagraph ps; - XWPFParagraph ph; - assertEquals(7, simple.getParagraphs().size()); - assertEquals(5, hyperlink.getParagraphs().size()); - - // Simple text - ps = simple.getParagraphs().get(0); - assertEquals("I am a test document", ps.getParagraphText()); - assertEquals(1, ps.getRuns().size()); - - ph = hyperlink.getParagraphs().get(4); - assertEquals("We have a hyperlink here, and another.", ph.getParagraphText()); - assertEquals(3, ph.getRuns().size()); - - - // The proper way to do hyperlinks(!) - assertFalse(ps.getRuns().get(0) instanceof XWPFHyperlinkRun); - assertFalse(ph.getRuns().get(0) instanceof XWPFHyperlinkRun); - assertTrue(ph.getRuns().get(1) instanceof XWPFHyperlinkRun); - assertFalse(ph.getRuns().get(2) instanceof XWPFHyperlinkRun); - - XWPFHyperlinkRun link = (XWPFHyperlinkRun) ph.getRuns().get(1); - assertEquals("http://poi.apache.org/", link.getHyperlink(hyperlink).getURL()); - } - - public void testComments() { - int numComments = 0; - for (XWPFParagraph p : comments.getParagraphs()) { - XWPFCommentsDecorator d = new XWPFCommentsDecorator(p, null); - if (d.getCommentText().length() > 0) { - numComments++; - assertEquals("\tComment by", d.getCommentText().substring(0, 11)); - } - } - assertEquals(3, numComments); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java deleted file mode 100644 index 0596a941f..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java +++ /dev/null @@ -1,188 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.model; - -import java.io.IOException; - -import junit.framework.TestCase; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFFooter; -import org.apache.poi.xwpf.usermodel.XWPFHeader; - -/** - * Tests for XWPF Header Footer Stuff - */ -public class TestXWPFHeaderFooterPolicy extends TestCase { - private XWPFDocument noHeader; - private XWPFDocument header; - private XWPFDocument headerFooter; - private XWPFDocument footer; - private XWPFDocument oddEven; - private XWPFDocument diffFirst; - - @Override - protected void setUp() throws IOException { - noHeader = XWPFTestDataSamples.openSampleDocument("NoHeadFoot.docx"); - header = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); - headerFooter = XWPFTestDataSamples.openSampleDocument("SimpleHeadThreeColFoot.docx"); - footer = XWPFTestDataSamples.openSampleDocument("FancyFoot.docx"); - oddEven = XWPFTestDataSamples.openSampleDocument("PageSpecificHeadFoot.docx"); - diffFirst = XWPFTestDataSamples.openSampleDocument("DiffFirstPageHeadFoot.docx"); - } - - public void testPolicy() { - XWPFHeaderFooterPolicy policy; - - policy = noHeader.getHeaderFooterPolicy(); - assertNull(policy.getDefaultHeader()); - assertNull(policy.getDefaultFooter()); - - assertNull(policy.getHeader(1)); - assertNull(policy.getHeader(2)); - assertNull(policy.getHeader(3)); - assertNull(policy.getFooter(1)); - assertNull(policy.getFooter(2)); - assertNull(policy.getFooter(3)); - - - policy = header.getHeaderFooterPolicy(); - assertNotNull(policy.getDefaultHeader()); - assertNull(policy.getDefaultFooter()); - - assertEquals(policy.getDefaultHeader(), policy.getHeader(1)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(2)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(3)); - assertNull(policy.getFooter(1)); - assertNull(policy.getFooter(2)); - assertNull(policy.getFooter(3)); - - - policy = footer.getHeaderFooterPolicy(); - assertNull(policy.getDefaultHeader()); - assertNotNull(policy.getDefaultFooter()); - - assertNull(policy.getHeader(1)); - assertNull(policy.getHeader(2)); - assertNull(policy.getHeader(3)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(1)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(2)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(3)); - - - policy = headerFooter.getHeaderFooterPolicy(); - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getDefaultFooter()); - - assertEquals(policy.getDefaultHeader(), policy.getHeader(1)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(2)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(3)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(1)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(2)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(3)); - - - policy = oddEven.getHeaderFooterPolicy(); - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getDefaultFooter()); - assertNotNull(policy.getEvenPageHeader()); - assertNotNull(policy.getEvenPageFooter()); - - assertEquals(policy.getDefaultHeader(), policy.getHeader(1)); - assertEquals(policy.getEvenPageHeader(), policy.getHeader(2)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(3)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(1)); - assertEquals(policy.getEvenPageFooter(), policy.getFooter(2)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(3)); - - - policy = diffFirst.getHeaderFooterPolicy(); - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getDefaultFooter()); - assertNotNull(policy.getFirstPageHeader()); - assertNotNull(policy.getFirstPageFooter()); - assertNull(policy.getEvenPageHeader()); - assertNull(policy.getEvenPageFooter()); - - assertEquals(policy.getFirstPageHeader(), policy.getHeader(1)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(2)); - assertEquals(policy.getDefaultHeader(), policy.getHeader(3)); - assertEquals(policy.getFirstPageFooter(), policy.getFooter(1)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(2)); - assertEquals(policy.getDefaultFooter(), policy.getFooter(3)); - } - - @SuppressWarnings("resource") - public void testCreate() throws Exception { - XWPFDocument doc = new XWPFDocument(); - assertEquals(null, doc.getHeaderFooterPolicy()); - assertEquals(0, doc.getHeaderList().size()); - assertEquals(0, doc.getFooterList().size()); - - XWPFHeaderFooterPolicy policy = doc.createHeaderFooterPolicy(); - assertNotNull(doc.getHeaderFooterPolicy()); - assertEquals(0, doc.getHeaderList().size()); - assertEquals(0, doc.getFooterList().size()); - - // Create a header and a footer - XWPFHeader header = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT); - XWPFFooter footer = policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT); - header.createParagraph().createRun().setText("Header Hello"); - footer.createParagraph().createRun().setText("Footer Bye"); - - - // Save, re-load, and check - doc = XWPFTestDataSamples.writeOutAndReadBack(doc); - assertNotNull(doc.getHeaderFooterPolicy()); - assertEquals(1, doc.getHeaderList().size()); - assertEquals(1, doc.getFooterList().size()); - - assertEquals("Header Hello\n", doc.getHeaderList().get(0).getText()); - assertEquals("Footer Bye\n", doc.getFooterList().get(0).getText()); - } - - public void testContents() { - XWPFHeaderFooterPolicy policy; - - // Test a few simple bits off a simple header - policy = diffFirst.getHeaderFooterPolicy(); - - assertEquals( - "I am the header on the first page, and I" + '\u2019' + "m nice and simple\n", - policy.getFirstPageHeader().getText() - ); - assertEquals( - "First header column!\tMid header\tRight header!\n", - policy.getDefaultHeader().getText() - ); - - - // And a few bits off a more complex header - policy = oddEven.getHeaderFooterPolicy(); - - assertEquals( - "[ODD Page Header text]\n\n", - policy.getDefaultHeader().getText() - ); - assertEquals( - "[This is an Even Page, with a Header]\n\n", - policy.getEvenPageHeader().getText() - ); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java deleted file mode 100644 index 47ec76524..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.junit.Test; - -public class TestChangeTracking { - @Test - public void detection() throws Exception { - XWPFDocument documentWithoutChangeTracking = XWPFTestDataSamples.openSampleDocument("bug56075-changeTracking_off.docx"); - assertFalse(documentWithoutChangeTracking.isTrackRevisions()); - - XWPFDocument documentWithChangeTracking = XWPFTestDataSamples.openSampleDocument("bug56075-changeTracking_on.docx"); - assertTrue(documentWithChangeTracking.isTrackRevisions()); - } - - @Test - public void activateChangeTracking() throws Exception { - XWPFDocument document = XWPFTestDataSamples.openSampleDocument("bug56075-changeTracking_off.docx"); - assertFalse(document.isTrackRevisions()); - - document.setTrackRevisions(true); - - assertTrue(document.isTrackRevisions()); - } - - @Test - @SuppressWarnings("resource") - public void integration() throws Exception { - XWPFDocument doc = new XWPFDocument(); - - XWPFParagraph p1 = doc.createParagraph(); - - XWPFRun r1 = p1.createRun(); - r1.setText("Lorem ipsum dolor sit amet."); - doc.setTrackRevisions(true); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - doc.write(out); - - ByteArrayInputStream inputStream = new ByteArrayInputStream(out.toByteArray()); - XWPFDocument document = new XWPFDocument(inputStream); - inputStream.close(); - - assertTrue(document.isTrackRevisions()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java deleted file mode 100644 index 28980da91..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java +++ /dev/null @@ -1,172 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.apache.poi.util.Units; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFRun.FontCharRange; -import org.junit.Test; - -public class TestXWPFBugs { - @Test - public void bug55802() throws Exception { - String blabla = - "Bir, iki, \u00fc\u00e7, d\u00f6rt, be\u015f,\n" + - "\nalt\u0131, yedi, sekiz, dokuz, on.\n" + - "\nK\u0131rm\u0131z\u0131 don,\n" + - "\ngel bizim bah\u00e7eye kon,\n" + - "\nsar\u0131 limon"; - XWPFDocument doc = new XWPFDocument(); - XWPFRun run = doc.createParagraph().createRun(); - - for (String str : blabla.split("\n")) { - run.setText(str); - run.addBreak(); - } - - run.setFontFamily("Times New Roman"); - run.setFontSize(20); - assertEquals(run.getFontFamily(), "Times New Roman"); - assertEquals(run.getFontFamily(FontCharRange.cs), "Times New Roman"); - assertEquals(run.getFontFamily(FontCharRange.eastAsia), "Times New Roman"); - assertEquals(run.getFontFamily(FontCharRange.hAnsi), "Times New Roman"); - run.setFontFamily("Arial", FontCharRange.hAnsi); - assertEquals(run.getFontFamily(FontCharRange.hAnsi), "Arial"); - - doc.close(); - } - - @Test - public void bug57312_NullPointException() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("57312.docx"); - assertNotNull(doc); - - for (IBodyElement bodyElement : doc.getBodyElements()) { - BodyElementType elementType = bodyElement.getElementType(); - - if (elementType == BodyElementType.PARAGRAPH) { - XWPFParagraph paragraph = (XWPFParagraph) bodyElement; - - for (IRunElement iRunElem : paragraph.getIRuns()) { - - if (iRunElem instanceof XWPFRun) { - XWPFRun runElement = (XWPFRun) iRunElem; - - UnderlinePatterns underline = runElement.getUnderline(); - assertNotNull(underline); - - //System.out.println("Found: " + underline + ": " + runElement.getText(0)); - } - } - } - } - } - - @Test - public void bug57495_getTableArrayInDoc() { - XWPFDocument doc =new XWPFDocument(); - //let's create a few tables for the test - for(int i=0;i<3;i++) { - doc.createTable(2, 2); - } - XWPFTable table = doc.getTableArray(0); - assertNotNull(table); - //let's check also that returns the correct table - XWPFTable same = doc.getTables().get(0); - assertEquals(table, same); - } - - @Test - public void bug57495_getParagraphArrayInTableCell() { - XWPFDocument doc =new XWPFDocument(); - //let's create a table for the test - XWPFTable table = doc.createTable(2, 2); - assertNotNull(table); - XWPFParagraph p = table.getRow(0).getCell(0).getParagraphArray(0); - assertNotNull(p); - //let's check also that returns the correct paragraph - XWPFParagraph same = table.getRow(0).getCell(0).getParagraphs().get(0); - assertEquals(p, same); - } - - @Test - public void bug57495_convertPixelsToEMUs() { - int pixels = 100; - int expectedEMU = 952500; - int result = Units.pixelToEMU(pixels); - assertEquals(expectedEMU, result); - } - - @Test - public void test56392() throws IOException, OpenXML4JException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("56392.docx"); - assertNotNull(doc); - } - - /** - * Removing a run needs to remove it from both Runs and IRuns - */ - @Test - public void test57829() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - assertNotNull(doc); - assertEquals(3, doc.getParagraphs().size()); - - for (XWPFParagraph paragraph : doc.getParagraphs()) { - paragraph.removeRun(0); - assertNotNull(paragraph.getText()); - } - } - - /** - * Removing a run needs to take into account position of run if paragraph contains hyperlink runs - */ - @Test - public void test58618() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("58618.docx"); - XWPFParagraph para = (XWPFParagraph)doc.getBodyElements().get(0); - assertNotNull(para); - assertEquals("Some text some hyper links link link and some text.....", para.getText()); - XWPFRun run = para.insertNewRun(para.getRuns().size()); - run.setText("New Text"); - assertEquals("Some text some hyper links link link and some text.....New Text", para.getText()); - para.removeRun(para.getRuns().size() -2); - assertEquals("Some text some hyper links link linkNew Text", para.getText()); - } - - @Test - public void test59378() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("59378.docx"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - doc.write(out); - out.close(); - - XWPFDocument doc2 = new XWPFDocument(new ByteArrayInputStream(out.toByteArray())); - doc2.close(); - - XWPFDocument docBack = XWPFTestDataSamples.writeOutAndReadBack(doc); - docBack.close(); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java deleted file mode 100644 index 0d8143795..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java +++ /dev/null @@ -1,452 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.List; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLProperties; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -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.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.extractor.XWPFWordExtractor; -import org.apache.xmlbeans.XmlCursor; -import org.junit.Ignore; -import org.junit.Test; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; - -public final class TestXWPFDocument { - - @Test - public void testContainsMainContentType() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - OPCPackage pack = doc.getPackage(); - - boolean found = false; - for (PackagePart part : pack.getParts()) { - if (part.getContentType().equals(XWPFRelation.DOCUMENT.getContentType())) { - found = true; - } -// if (false) { -// // successful tests should be silent -// System.out.println(part); -// } - } - assertTrue(found); - - pack.close(); - doc.close(); - } - - @Test - public void testOpen() throws Exception { - // Simple file - XWPFDocument xml1 = XWPFTestDataSamples.openSampleDocument("sample.docx"); - // Check it has key parts - assertNotNull(xml1.getDocument()); - assertNotNull(xml1.getDocument().getBody()); - assertNotNull(xml1.getStyle()); - xml1.close(); - - // Complex file - XWPFDocument xml2 = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx"); - assertNotNull(xml2.getDocument()); - assertNotNull(xml2.getDocument().getBody()); - assertNotNull(xml2.getStyle()); - xml2.close(); - } - - @Test - public void testMetadataBasics() throws IOException { - XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx"); - assertNotNull(xml.getProperties().getCoreProperties()); - assertNotNull(xml.getProperties().getExtendedProperties()); - - assertEquals("Microsoft Office Word", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication()); - assertEquals(1315, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters()); - assertEquals(10, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines()); - - assertEquals(null, xml.getProperties().getCoreProperties().getTitle()); - assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue()); - xml.close(); - } - - @Test - public void testMetadataComplex() throws IOException { - XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx"); - assertNotNull(xml.getProperties().getCoreProperties()); - assertNotNull(xml.getProperties().getExtendedProperties()); - - assertEquals("Microsoft Office Outlook", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication()); - assertEquals(5184, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters()); - assertEquals(0, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines()); - - assertEquals(" ", xml.getProperties().getCoreProperties().getTitle()); - assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue()); - xml.close(); - } - - @Test - public void testWorkbookProperties() throws Exception { - XWPFDocument doc = new XWPFDocument(); - POIXMLProperties props = doc.getProperties(); - assertNotNull(props); - assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication()); - doc.close(); - } - - @Test - public void testAddParagraph() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - assertEquals(3, doc.getParagraphs().size()); - - XWPFParagraph p = doc.createParagraph(); - assertEquals(p, doc.getParagraphs().get(3)); - assertEquals(4, doc.getParagraphs().size()); - - assertEquals(3, doc.getParagraphPos(3)); - assertEquals(3, doc.getPosOfParagraph(p)); - - CTP ctp = p.getCTP(); - XWPFParagraph newP = doc.getParagraph(ctp); - assertSame(p, newP); - XmlCursor cursor = doc.getDocument().getBody().getPArray(0).newCursor(); - XWPFParagraph cP = doc.insertNewParagraph(cursor); - assertSame(cP, doc.getParagraphs().get(0)); - assertEquals(5, doc.getParagraphs().size()); - doc.close(); - } - - @Test - public void testAddPicture() throws IOException, InvalidFormatException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - byte[] jpeg = XWPFTestDataSamples.getImage("nature1.jpg"); - String relationId = doc.addPictureData(jpeg, XWPFDocument.PICTURE_TYPE_JPEG); - - byte[] newJpeg = ((XWPFPictureData) doc.getRelationById(relationId)).getData(); - assertEquals(newJpeg.length, jpeg.length); - for (int i = 0; i < jpeg.length; i++) { - assertEquals(newJpeg[i], jpeg[i]); - } - doc.close(); - } - - @Test - public void testAllPictureFormats() throws IOException, InvalidFormatException { - XWPFDocument doc = new XWPFDocument(); - - doc.addPictureData(new byte[10], XWPFDocument.PICTURE_TYPE_EMF); - doc.addPictureData(new byte[11], XWPFDocument.PICTURE_TYPE_WMF); - doc.addPictureData(new byte[12], XWPFDocument.PICTURE_TYPE_PICT); - doc.addPictureData(new byte[13], XWPFDocument.PICTURE_TYPE_JPEG); - doc.addPictureData(new byte[14], XWPFDocument.PICTURE_TYPE_PNG); - doc.addPictureData(new byte[15], XWPFDocument.PICTURE_TYPE_DIB); - doc.addPictureData(new byte[16], XWPFDocument.PICTURE_TYPE_GIF); - doc.addPictureData(new byte[17], XWPFDocument.PICTURE_TYPE_TIFF); - doc.addPictureData(new byte[18], XWPFDocument.PICTURE_TYPE_EPS); - doc.addPictureData(new byte[19], XWPFDocument.PICTURE_TYPE_BMP); - doc.addPictureData(new byte[20], XWPFDocument.PICTURE_TYPE_WPG); - - assertEquals(11, doc.getAllPictures().size()); - - XWPFDocument doc2 = XWPFTestDataSamples.writeOutAndReadBack(doc); - assertEquals(11, doc2.getAllPictures().size()); - doc2.close(); - doc.close(); - } - - @Test - public void testRemoveBodyElement() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - assertEquals(3, doc.getParagraphs().size()); - assertEquals(3, doc.getBodyElements().size()); - - XWPFParagraph p1 = doc.getParagraphs().get(0); - XWPFParagraph p2 = doc.getParagraphs().get(1); - XWPFParagraph p3 = doc.getParagraphs().get(2); - - assertEquals(p1, doc.getBodyElements().get(0)); - assertEquals(p1, doc.getParagraphs().get(0)); - assertEquals(p2, doc.getBodyElements().get(1)); - assertEquals(p2, doc.getParagraphs().get(1)); - assertEquals(p3, doc.getBodyElements().get(2)); - assertEquals(p3, doc.getParagraphs().get(2)); - - // Add another - XWPFParagraph p4 = doc.createParagraph(); - - assertEquals(4, doc.getParagraphs().size()); - assertEquals(4, doc.getBodyElements().size()); - assertEquals(p1, doc.getBodyElements().get(0)); - assertEquals(p1, doc.getParagraphs().get(0)); - assertEquals(p2, doc.getBodyElements().get(1)); - assertEquals(p2, doc.getParagraphs().get(1)); - assertEquals(p3, doc.getBodyElements().get(2)); - assertEquals(p3, doc.getParagraphs().get(2)); - assertEquals(p4, doc.getBodyElements().get(3)); - assertEquals(p4, doc.getParagraphs().get(3)); - - // Remove the 2nd - assertEquals(true, doc.removeBodyElement(1)); - assertEquals(3, doc.getParagraphs().size()); - assertEquals(3, doc.getBodyElements().size()); - - assertEquals(p1, doc.getBodyElements().get(0)); - assertEquals(p1, doc.getParagraphs().get(0)); - assertEquals(p3, doc.getBodyElements().get(1)); - assertEquals(p3, doc.getParagraphs().get(1)); - assertEquals(p4, doc.getBodyElements().get(2)); - assertEquals(p4, doc.getParagraphs().get(2)); - - // Remove the 1st - assertEquals(true, doc.removeBodyElement(0)); - assertEquals(2, doc.getParagraphs().size()); - assertEquals(2, doc.getBodyElements().size()); - - assertEquals(p3, doc.getBodyElements().get(0)); - assertEquals(p3, doc.getParagraphs().get(0)); - assertEquals(p4, doc.getBodyElements().get(1)); - assertEquals(p4, doc.getParagraphs().get(1)); - - // Remove the last - assertEquals(true, doc.removeBodyElement(1)); - assertEquals(1, doc.getParagraphs().size()); - assertEquals(1, doc.getBodyElements().size()); - - assertEquals(p3, doc.getBodyElements().get(0)); - assertEquals(p3, doc.getParagraphs().get(0)); - doc.close(); - } - - @Test - public void testRegisterPackagePictureData() throws IOException, InvalidFormatException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx"); - - /* manually assemble a new image package part*/ - OPCPackage opcPckg = doc.getPackage(); - XWPFRelation jpgRelation = XWPFRelation.IMAGE_JPEG; - PackagePartName partName = PackagingURIHelper.createPartName(jpgRelation.getDefaultFileName().replace('#', '2')); - PackagePart newImagePart = opcPckg.createPart(partName, jpgRelation.getContentType()); - byte[] nature1 = XWPFTestDataSamples.getImage("abstract4.jpg"); - OutputStream os = newImagePart.getOutputStream(); - os.write(nature1); - os.close(); - XWPFHeader xwpfHeader = doc.getHeaderArray(0); - PackageRelationship relationship = xwpfHeader.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, jpgRelation.getRelation()); - XWPFPictureData newPicData = new XWPFPictureData(newImagePart, relationship); - /* new part is now ready to rumble */ - - assertFalse(xwpfHeader.getAllPictures().contains(newPicData)); - assertFalse(doc.getAllPictures().contains(newPicData)); - assertFalse(doc.getAllPackagePictures().contains(newPicData)); - - doc.registerPackagePictureData(newPicData); - - assertFalse(xwpfHeader.getAllPictures().contains(newPicData)); - assertFalse(doc.getAllPictures().contains(newPicData)); - assertTrue(doc.getAllPackagePictures().contains(newPicData)); - - doc.getPackage().revert(); - opcPckg.close(); - doc.close(); - } - - @Test - public void testFindPackagePictureData() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx"); - byte[] nature1 = XWPFTestDataSamples.getImage("nature1.gif"); - XWPFPictureData part = doc.findPackagePictureData(nature1, Document.PICTURE_TYPE_GIF); - assertNotNull(part); - assertTrue(doc.getAllPictures().contains(part)); - assertTrue(doc.getAllPackagePictures().contains(part)); - doc.getPackage().revert(); - doc.close(); - } - - @Test - public void testGetAllPictures() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx"); - List allPictures = doc.getAllPictures(); - List allPackagePictures = doc.getAllPackagePictures(); - - assertNotNull(allPictures); - assertEquals(3, allPictures.size()); - for (XWPFPictureData xwpfPictureData : allPictures) { - assertTrue(allPackagePictures.contains(xwpfPictureData)); - } - - try { - allPictures.add(allPictures.get(0)); - fail("This list must be unmodifiable!"); - } catch (UnsupportedOperationException e) { - // all ok - } - - doc.getPackage().revert(); - doc.close(); - } - - @Test - public void testGetAllPackagePictures() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx"); - List allPackagePictures = doc.getAllPackagePictures(); - - assertNotNull(allPackagePictures); - assertEquals(5, allPackagePictures.size()); - - try { - allPackagePictures.add(allPackagePictures.get(0)); - fail("This list must be unmodifiable!"); - } catch (UnsupportedOperationException e) { - // all ok - } - - doc.getPackage().revert(); - doc.close(); - } - - @Test - public void testPictureHandlingSimpleFile() throws IOException, InvalidFormatException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx"); - assertEquals(1, doc.getAllPackagePictures().size()); - byte[] newPic = XWPFTestDataSamples.getImage("abstract4.jpg"); - String id1 = doc.addPictureData(newPic, Document.PICTURE_TYPE_JPEG); - assertEquals(2, doc.getAllPackagePictures().size()); - /* copy data, to avoid instance-equality */ - byte[] newPicCopy = Arrays.copyOf(newPic, newPic.length); - String id2 = doc.addPictureData(newPicCopy, Document.PICTURE_TYPE_JPEG); - assertEquals(id1, id2); - doc.getPackage().revert(); - doc.close(); - } - - @Test - public void testPictureHandlingHeaderDocumentImages() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_2.docx"); - assertEquals(1, doc.getAllPictures().size()); - assertEquals(1, doc.getAllPackagePictures().size()); - assertEquals(1, doc.getHeaderArray(0).getAllPictures().size()); - doc.getPackage().revert(); - doc.close(); - } - - @Test - public void testPictureHandlingComplex() throws IOException, InvalidFormatException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx"); - XWPFHeader xwpfHeader = doc.getHeaderArray(0); - - assertEquals(3, doc.getAllPictures().size()); - assertEquals(3, xwpfHeader.getAllPictures().size()); - assertEquals(5, doc.getAllPackagePictures().size()); - - byte[] nature1 = XWPFTestDataSamples.getImage("nature1.jpg"); - String id = doc.addPictureData(nature1, Document.PICTURE_TYPE_JPEG); - POIXMLDocumentPart part1 = xwpfHeader.getRelationById("rId1"); - XWPFPictureData part2 = (XWPFPictureData) doc.getRelationById(id); - assertSame(part1, part2); - - doc.getPackage().revert(); - doc.close(); - } - - @Test - public void testZeroLengthLibreOfficeDocumentWithWaterMarkHeader() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("zero-length.docx"); - POIXMLProperties properties = doc.getProperties(); - - assertNotNull(properties.getCoreProperties()); - - XWPFHeader headerArray = doc.getHeaderArray(0); - assertEquals(1, headerArray.getAllPictures().size()); - assertEquals("image1.png", headerArray.pictures.get(0).getFileName()); - assertEquals("", headerArray.getText()); - - POIXMLProperties.ExtendedProperties extendedProperties = properties.getExtendedProperties(); - assertNotNull(extendedProperties); - assertEquals(0, extendedProperties.getUnderlyingProperties().getCharacters()); - doc.close(); - } - - @Test - public void testSettings() throws IOException { - XWPFSettings settings = new XWPFSettings(); - assertEquals(100, settings.getZoomPercent()); - settings.setZoomPercent(50); - assertEquals(50, settings.getZoomPercent()); - - XWPFDocument doc = new XWPFDocument(); - assertEquals(100, doc.getZoomPercent()); - - doc.setZoomPercent(50); - assertEquals(50, doc.getZoomPercent()); - - doc.setZoomPercent(200); - assertEquals(200, doc.getZoomPercent()); - - XWPFDocument back = XWPFTestDataSamples.writeOutAndReadBack(doc); - assertEquals(200, back.getZoomPercent()); - back.close(); - -// OutputStream out = new FileOutputStream("/tmp/testZoom.docx"); -// doc.write(out); -// out.close(); - - doc.close(); - } - - @Test - public void testEnforcedWith() throws IOException { - XWPFDocument docx = XWPFTestDataSamples.openSampleDocument("EnforcedWith.docx"); - assertTrue(docx.isEnforcedProtection()); - docx.close(); - } - - @Test - @Ignore("XWPF should be able to write to a new Stream when opened Read-Only") - public void testWriteFromReadOnlyOPC() throws Exception { - OPCPackage opc = OPCPackage.open( - POIDataSamples.getDocumentInstance().getFile("SampleDoc.docx"), - PackageAccess.READ - ); - XWPFDocument doc = new XWPFDocument(opc); - XWPFWordExtractor ext = new XWPFWordExtractor(doc); - String origText = ext.getText(); - - doc = XWPFTestDataSamples.writeOutAndReadBack(doc); - ext = new XWPFWordExtractor(doc); - - assertEquals(origText, ext.getText()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java deleted file mode 100644 index 7025a266c..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io.IOException; -import java.math.BigInteger; -import java.util.List; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFtnEdn; - -public class TestXWPFFootnotes extends TestCase { - - public void testAddFootnotesToDocument() throws IOException { - XWPFDocument docOut = new XWPFDocument(); - - BigInteger noteId = BigInteger.valueOf(1); - - XWPFFootnotes footnotes = docOut.createFootnotes(); - CTFtnEdn ctNote = CTFtnEdn.Factory.newInstance(); - ctNote.setId(noteId); - ctNote.setType(STFtnEdn.NORMAL); - footnotes.addFootnote(ctNote); - - XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut); - - XWPFFootnote note = docIn.getFootnoteByID(noteId.intValue()); - assertEquals(note.getCTFtnEdn().getType(), STFtnEdn.NORMAL); - } - - /** - * Bug 55066 - avoid double loading the footnotes - */ - public void testLoadFootnotesOnce() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx"); - List footnotes = doc.getFootnotes(); - int hits = 0; - for (XWPFFootnote fn : footnotes) { - for (IBodyElement e : fn.getBodyElements()) { - if (e instanceof XWPFParagraph) { - String txt = ((XWPFParagraph) e).getText(); - if (txt.indexOf("Footnote_sdt") > -1) { - hits++; - } - } - } - } - assertEquals("Load footnotes once", 1, hits); - } -} - diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java deleted file mode 100644 index fbb24f506..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java +++ /dev/null @@ -1,230 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import java.io.IOException; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; -import org.junit.Test; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; - -public final class TestXWPFHeader { - - @Test - public void testSimpleHeader() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerFooter.docx"); - - XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); - - XWPFHeader header = policy.getDefaultHeader(); - XWPFFooter footer = policy.getDefaultFooter(); - assertNotNull(header); - assertNotNull(footer); - } - - @Test - public void testImageInHeader() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx"); - - XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); - - XWPFHeader header = policy.getDefaultHeader(); - - assertNotNull(header.getRelations()); - assertEquals(1, header.getRelations().size()); - } - - @Test - public void testSetHeader() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); - // no header is set (yet) - XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); - assertNull(policy.getDefaultHeader()); - assertNull(policy.getFirstPageHeader()); - assertNull(policy.getDefaultFooter()); - assertNull(policy.getFirstPageFooter()); - - CTP ctP1 = CTP.Factory.newInstance(); - CTR ctR1 = ctP1.addNewR(); - CTText t = ctR1.addNewT(); - String tText = "Paragraph in header"; - t.setStringValue(tText); - - // Commented MB 23 May 2010 - //CTP ctP2 = CTP.Factory.newInstance(); - //CTR ctR2 = ctP2.addNewR(); - //CTText t2 = ctR2.addNewT(); - //t2.setStringValue("Second paragraph.. for footer"); - - // Create two paragraphs for insertion into the footer. - // Previously only one was inserted MB 23 May 2010 - CTP ctP2 = CTP.Factory.newInstance(); - CTR ctR2 = ctP2.addNewR(); - CTText t2 = ctR2.addNewT(); - t2.setStringValue("First paragraph for the footer"); - - CTP ctP3 = CTP.Factory.newInstance(); - CTR ctR3 = ctP3.addNewR(); - CTText t3 = ctR3.addNewT(); - t3.setStringValue("Second paragraph for the footer"); - - XWPFParagraph p1 = new XWPFParagraph(ctP1, sampleDoc); - XWPFParagraph[] pars = new XWPFParagraph[1]; - pars[0] = p1; - - XWPFParagraph p2 = new XWPFParagraph(ctP2, sampleDoc); - XWPFParagraph p3 = new XWPFParagraph(ctP3, sampleDoc); - XWPFParagraph[] pars2 = new XWPFParagraph[2]; - pars2[0] = p2; - pars2[1] = p3; - - // Set headers - XWPFHeader headerD = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, pars); - XWPFHeader headerF = policy.createHeader(XWPFHeaderFooterPolicy.FIRST); - // Set a default footer and capture the returned XWPFFooter object. - XWPFFooter footerD = policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, pars2); - XWPFFooter footerF = policy.createFooter(XWPFHeaderFooterPolicy.FIRST); - - // Ensure the headers and footer were set correctly.... - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getFirstPageHeader()); - assertNotNull(policy.getDefaultFooter()); - assertNotNull(policy.getFirstPageFooter()); - // ....and that the footer object captured above contains two - // paragraphs of text. - assertEquals(2, footerD.getParagraphs().size()); - assertEquals(0, footerF.getParagraphs().size()); - - // Check the header created with the paragraph got them, and the one - // created without got none - assertEquals(1, headerD.getParagraphs().size()); - assertEquals(tText, headerD.getParagraphs().get(0).getText()); - - assertEquals(0, headerF.getParagraphs().size()); - - // As an additional check, recover the defauls footer and - // make sure that it contains two paragraphs of text and that - // both do hold what is expected. - footerD = policy.getDefaultFooter(); - XWPFParagraph[] paras = footerD.getParagraphs().toArray(new XWPFParagraph[0]); - - assertEquals(2, paras.length); - assertEquals("First paragraph for the footer", paras[0].getText()); - assertEquals("Second paragraph for the footer", paras[1].getText()); - - - // Add some text to the empty header - String fText1 = "New Text!"; - String fText2 = "More Text!"; - headerF.createParagraph().insertNewRun(0).setText(fText1); - headerF.createParagraph().insertNewRun(0).setText(fText2); -// headerF.getParagraphs().get(0).insertNewRun(0).setText(fText1); - - // Check it - assertEquals(tText, headerD.getParagraphs().get(0).getText()); - assertEquals(fText1, headerF.getParagraphs().get(0).getText()); - assertEquals(fText2, headerF.getParagraphs().get(1).getText()); - - - // Save, re-open, ensure it's all still there - XWPFDocument reopened = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc); - policy = reopened.getHeaderFooterPolicy(); - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getFirstPageHeader()); - assertNull(policy.getEvenPageHeader()); - assertNotNull(policy.getDefaultFooter()); - assertNotNull(policy.getFirstPageFooter()); - assertNull(policy.getEvenPageFooter()); - - // Check the new headers still have their text - headerD = policy.getDefaultHeader(); - headerF = policy.getFirstPageHeader(); - assertEquals(tText, headerD.getParagraphs().get(0).getText()); - assertEquals(fText1, headerF.getParagraphs().get(0).getText()); - assertEquals(fText2, headerF.getParagraphs().get(1).getText()); - - // Check the new footers have their new text too - footerD = policy.getDefaultFooter(); - paras = footerD.getParagraphs().toArray(new XWPFParagraph[0]); - footerF = policy.getFirstPageFooter(); - - assertEquals(2, paras.length); - assertEquals("First paragraph for the footer", paras[0].getText()); - assertEquals("Second paragraph for the footer", paras[1].getText()); - assertEquals(1, footerF.getParagraphs().size()); - } - - @Test - public void testSetWatermark() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); - - // No header is set (yet) - XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); - assertNull(policy.getDefaultHeader()); - assertNull(policy.getFirstPageHeader()); - assertNull(policy.getDefaultFooter()); - - policy.createWatermark("DRAFT"); - - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getFirstPageHeader()); - assertNotNull(policy.getEvenPageHeader()); - - // Re-open, and check - XWPFDocument reopened = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc); - policy = reopened.getHeaderFooterPolicy(); - - assertNotNull(policy.getDefaultHeader()); - assertNotNull(policy.getFirstPageHeader()); - assertNotNull(policy.getEvenPageHeader()); - } - - @Test - public void testAddPictureData() { - // TODO - } - - @Test - public void testGetAllPictures() { - // TODO - } - - @Test - public void testGetAllPackagePictures() { - // TODO - } - - @Test - public void testGetPictureDataById() { - // TODO - } - - @Test - public void bug60293() throws Exception { - //test handling of non-standard header/footer options - XWPFDocument xwpf = XWPFTestDataSamples.openSampleDocument("60293.docx"); - assertEquals(3, xwpf.getHeaderList().size()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java deleted file mode 100644 index ef7620eee..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io.IOException; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.xmlbeans.XmlException; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; - -/** - * @author Paolo Mottadelli - */ -public final class TestXWPFHeadings extends TestCase { - private static final String HEADING1 = "Heading1"; - - public void testSetParagraphStyle() throws IOException, XmlException { - //new clean instance of paragraph - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("heading123.docx"); - XWPFParagraph p = doc.createParagraph(); - XWPFRun run = p.createRun(); - run.setText("Heading 1"); - - CTSdtBlock block = doc.getDocument().getBody().addNewSdt(); - - assertNull(p.getStyle()); - p.setStyle(HEADING1); - assertEquals(HEADING1, p.getCTP().getPPr().getPStyle().getVal()); - - doc.createTOC(); - /* - // TODO - finish this test - if (false) { - CTStyles styles = doc.getStyle(); - CTStyle style = styles.addNewStyle(); - style.setType(STStyleType.PARAGRAPH); - style.setStyleId("Heading1"); - } - - if (false) { - File file = TempFile.createTempFile("testHeaders", ".docx"); - OutputStream out = new FileOutputStream(file); - doc.write(out); - out.close(); - } - */ - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java deleted file mode 100644 index 5a5ce78f5..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java +++ /dev/null @@ -1,102 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io.IOException; -import java.math.BigInteger; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumLvl; - -public class TestXWPFNumbering extends TestCase { - - public void testCompareAbstractNum() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx"); - XWPFNumbering numbering = doc.getNumbering(); - BigInteger numId = BigInteger.valueOf(1); - assertTrue(numbering.numExist(numId)); - XWPFNum num = numbering.getNum(numId); - BigInteger abstrNumId = num.getCTNum().getAbstractNumId().getVal(); - XWPFAbstractNum abstractNum = numbering.getAbstractNum(abstrNumId); - BigInteger compareAbstractNum = numbering.getIdOfAbstractNum(abstractNum); - assertEquals(abstrNumId, compareAbstractNum); - } - - public void testAddNumberingToDoc() throws IOException { - BigInteger abstractNumId = BigInteger.valueOf(1); - BigInteger numId = BigInteger.valueOf(1); - - XWPFDocument docOut = new XWPFDocument(); - XWPFNumbering numbering = docOut.createNumbering(); - numId = numbering.addNum(abstractNumId); - - XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut); - - numbering = docIn.getNumbering(); - assertTrue(numbering.numExist(numId)); - XWPFNum num = numbering.getNum(numId); - - BigInteger compareAbstractNum = num.getCTNum().getAbstractNumId().getVal(); - assertEquals(abstractNumId, compareAbstractNum); - } - - public void testGetNumIlvl() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx"); - BigInteger numIlvl = BigInteger.valueOf(0); - assertEquals(numIlvl, doc.getParagraphs().get(0).getNumIlvl()); - numIlvl = BigInteger.valueOf(1); - assertEquals(numIlvl, doc.getParagraphs().get(5).getNumIlvl()); - } - - public void testGetNumFmt() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx"); - assertEquals("bullet", doc.getParagraphs().get(0).getNumFmt()); - assertEquals("bullet", doc.getParagraphs().get(1).getNumFmt()); - assertEquals("bullet", doc.getParagraphs().get(2).getNumFmt()); - assertEquals("bullet", doc.getParagraphs().get(3).getNumFmt()); - assertEquals("decimal", doc.getParagraphs().get(4).getNumFmt()); - assertEquals("lowerLetter", doc.getParagraphs().get(5).getNumFmt()); - assertEquals("lowerRoman", doc.getParagraphs().get(6).getNumFmt()); - } - - public void testLvlText() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx"); - - assertEquals("%1.%2.%3.", doc.getParagraphs().get(12).getNumLevelText()); - - assertEquals("NEW-%1-FORMAT", doc.getParagraphs().get(14).getNumLevelText()); - - XWPFParagraph p = doc.getParagraphs().get(18); - assertEquals("%1.", p.getNumLevelText()); - //test that null doesn't throw NPE - assertNull(p.getNumFmt()); - } - - public void testOverrideList() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("NumberingWOverrides.docx"); - XWPFParagraph p = doc.getParagraphs().get(4); - XWPFNumbering numbering = doc.getNumbering(); - CTNum ctNum = numbering.getNum(p.getNumID()).getCTNum(); - assertEquals(9, ctNum.sizeOfLvlOverrideArray()); - CTNumLvl ctNumLvl = ctNum.getLvlOverrideArray(0); - assertEquals("upperLetter", ctNumLvl.getLvl().getNumFmt().getVal().toString()); - } - -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java deleted file mode 100644 index 756aeef55..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java +++ /dev/null @@ -1,679 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.List; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture; -import org.openxmlformats.schemas.drawingml.x2006.picture.PicDocument; -import org.openxmlformats.schemas.drawingml.x2006.picture.impl.PicDocumentImpl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment; - -/** - * Tests for XWPF Paragraphs - */ -public final class TestXWPFParagraph { - - /** - * Check that we get the right paragraph from the header - * - * @throws IOException - */ - @Test - public void testHeaderParagraph() throws IOException { - XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); - - XWPFHeader hdr = xml.getHeaderFooterPolicy().getDefaultHeader(); - assertNotNull(hdr); - - List ps = hdr.getParagraphs(); - assertEquals(1, ps.size()); - XWPFParagraph p = ps.get(0); - - assertEquals(5, p.getCTP().sizeOfRArray()); - assertEquals("First header column!\tMid header\tRight header!", p.getText()); - - xml.close(); - } - - /** - * Check that we get the right paragraphs from the document - * - * @throws IOException - */ - @Test - public void testDocumentParagraph() throws IOException { - XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); - List ps = xml.getParagraphs(); - assertEquals(10, ps.size()); - - assertFalse(ps.get(0).isEmpty()); - assertEquals( - "This is a sample word document. It has two pages. It has a three column heading, but no footer.", - ps.get(0).getText()); - - assertTrue(ps.get(1).isEmpty()); - assertEquals("", ps.get(1).getText()); - - assertFalse(ps.get(2).isEmpty()); - assertEquals("HEADING TEXT", ps.get(2).getText()); - - assertTrue(ps.get(3).isEmpty()); - assertEquals("", ps.get(3).getText()); - - assertFalse(ps.get(4).isEmpty()); - assertEquals("More on page one", ps.get(4).getText()); - - xml.close(); - } - - @Test - public void testSetGetBorderTop() throws IOException { - //new clean instance of paragraph - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - assertEquals(STBorder.NONE.intValue(), p.getBorderTop().getValue()); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - //bordi - CTPBdr bdr = ppr.addNewPBdr(); - CTBorder borderTop = bdr.addNewTop(); - borderTop.setVal(STBorder.DOUBLE); - bdr.setTop(borderTop); - - assertEquals(Borders.DOUBLE, p.getBorderTop()); - p.setBorderTop(Borders.SINGLE); - assertEquals(STBorder.SINGLE, borderTop.getVal()); - - doc.close(); - } - - @Test - public void testSetGetAlignment() throws IOException { - //new clean instance of paragraph - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - assertEquals(STJc.LEFT.intValue(), p.getAlignment().getValue()); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - CTJc align = ppr.addNewJc(); - align.setVal(STJc.CENTER); - assertEquals(ParagraphAlignment.CENTER, p.getAlignment()); - - p.setAlignment(ParagraphAlignment.BOTH); - assertEquals(STJc.BOTH, ppr.getJc().getVal()); - - doc.close(); - } - - @Test - public void testSetGetSpacing() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - assertEquals(-1, p.getSpacingAfter()); - - CTSpacing spacing = ppr.addNewSpacing(); - spacing.setAfter(new BigInteger("10")); - assertEquals(10, p.getSpacingAfter()); - - p.setSpacingAfter(100); - assertEquals(100, spacing.getAfter().intValue()); - - doc.close(); - } - - @Test - public void testSetGetSpacingLineRule() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - assertEquals(STLineSpacingRule.INT_AUTO, p.getSpacingLineRule().getValue()); - - CTSpacing spacing = ppr.addNewSpacing(); - spacing.setLineRule(STLineSpacingRule.AT_LEAST); - assertEquals(LineSpacingRule.AT_LEAST, p.getSpacingLineRule()); - - p.setSpacingAfter(100); - assertEquals(100, spacing.getAfter().intValue()); - - doc.close(); - } - - @Test - public void testSetGetIndentation() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - assertEquals(-1, p.getIndentationLeft()); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - assertEquals(-1, p.getIndentationLeft()); - - CTInd ind = ppr.addNewInd(); - ind.setLeft(new BigInteger("10")); - assertEquals(10, p.getIndentationLeft()); - - p.setIndentationLeft(100); - assertEquals(100, ind.getLeft().intValue()); - - doc.close(); - } - - @Test - public void testSetGetVerticalAlignment() throws IOException { - //new clean instance of paragraph - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - CTTextAlignment txtAlign = ppr.addNewTextAlignment(); - txtAlign.setVal(STTextAlignment.CENTER); - assertEquals(TextAlignment.CENTER, p.getVerticalAlignment()); - - p.setVerticalAlignment(TextAlignment.BOTTOM); - assertEquals(STTextAlignment.BOTTOM, ppr.getTextAlignment().getVal()); - - doc.close(); - } - - @Test - public void testSetGetWordWrap() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - CTOnOff wordWrap = ppr.addNewWordWrap(); - wordWrap.setVal(STOnOff.FALSE); - assertEquals(false, p.isWordWrap()); - - p.setWordWrapped(true); - assertEquals(STOnOff.TRUE, ppr.getWordWrap().getVal()); - - doc.close(); - } - - @Test - public void testSetGetPageBreak() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - CTP ctp = p.getCTP(); - CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr(); - - CTOnOff pageBreak = ppr.addNewPageBreakBefore(); - pageBreak.setVal(STOnOff.FALSE); - assertEquals(false, p.isPageBreak()); - - p.setPageBreak(true); - assertEquals(STOnOff.TRUE, ppr.getPageBreakBefore().getVal()); - doc.close(); - } - - @Test - public void testBookmarks() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("bookmarks.docx"); - XWPFParagraph paragraph = doc.getParagraphs().get(0); - assertEquals("Sample Word Document", paragraph.getText()); - assertEquals(1, paragraph.getCTP().sizeOfBookmarkStartArray()); - assertEquals(0, paragraph.getCTP().sizeOfBookmarkEndArray()); - CTBookmark ctBookmark = paragraph.getCTP().getBookmarkStartArray(0); - assertEquals("poi", ctBookmark.getName()); - for (CTBookmark bookmark : paragraph.getCTP().getBookmarkStartList()) { - assertEquals("poi", bookmark.getName()); - } - doc.close(); - } - - @Test - public void testGetSetNumID() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - p.setNumID(new BigInteger("10")); - assertEquals("10", p.getNumID().toString()); - doc.close(); - } - - @Test - public void testAddingRuns() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - - XWPFParagraph p = doc.getParagraphs().get(0); - assertEquals(2, p.getRuns().size()); - - XWPFRun r = p.createRun(); - assertEquals(3, p.getRuns().size()); - assertEquals(2, p.getRuns().indexOf(r)); - - XWPFRun r2 = p.insertNewRun(1); - assertEquals(4, p.getRuns().size()); - assertEquals(1, p.getRuns().indexOf(r2)); - assertEquals(3, p.getRuns().indexOf(r)); - - doc.close(); - } - - @Test - public void testPictures() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx"); - assertEquals(7, doc.getParagraphs().size()); - - XWPFParagraph p; - XWPFRun r; - - // Text paragraphs - assertEquals("Sheet with various pictures", doc.getParagraphs().get(0).getText()); - assertEquals("(jpeg, png, wmf, emf and pict) ", doc.getParagraphs().get(1).getText()); - - // Spacer ones - assertEquals("", doc.getParagraphs().get(2).getText()); - assertEquals("", doc.getParagraphs().get(3).getText()); - assertEquals("", doc.getParagraphs().get(4).getText()); - - // Image one - p = doc.getParagraphs().get(5); - assertEquals(6, p.getRuns().size()); - - r = p.getRuns().get(0); - assertEquals("", r.toString()); - assertEquals(1, r.getEmbeddedPictures().size()); - assertNotNull(r.getEmbeddedPictures().get(0).getPictureData()); - assertEquals("image1.wmf", r.getEmbeddedPictures().get(0).getPictureData().getFileName()); - - r = p.getRuns().get(1); - assertEquals("", r.toString()); - assertEquals(1, r.getEmbeddedPictures().size()); - assertNotNull(r.getEmbeddedPictures().get(0).getPictureData()); - assertEquals("image2.png", r.getEmbeddedPictures().get(0).getPictureData().getFileName()); - - r = p.getRuns().get(2); - assertEquals("", r.toString()); - assertEquals(1, r.getEmbeddedPictures().size()); - assertNotNull(r.getEmbeddedPictures().get(0).getPictureData()); - assertEquals("image3.emf", r.getEmbeddedPictures().get(0).getPictureData().getFileName()); - - r = p.getRuns().get(3); - assertEquals("", r.toString()); - assertEquals(1, r.getEmbeddedPictures().size()); - assertNotNull(r.getEmbeddedPictures().get(0).getPictureData()); - assertEquals("image4.emf", r.getEmbeddedPictures().get(0).getPictureData().getFileName()); - - r = p.getRuns().get(4); - assertEquals("", r.toString()); - assertEquals(1, r.getEmbeddedPictures().size()); - assertNotNull(r.getEmbeddedPictures().get(0).getPictureData()); - assertEquals("image5.jpeg", r.getEmbeddedPictures().get(0).getPictureData().getFileName()); - - r = p.getRuns().get(5); - assertEquals(" ", r.toString()); - assertEquals(0, r.getEmbeddedPictures().size()); - - // Final spacer - assertEquals("", doc.getParagraphs().get(6).getText()); - - - // Look in detail at one - r = p.getRuns().get(4); - XWPFPicture pict = r.getEmbeddedPictures().get(0); - CTPicture picture = pict.getCTPicture(); - assertEquals("rId8", picture.getBlipFill().getBlip().getEmbed()); - - // Ensure that the ooxml compiler finds everything we need - r.getCTR().getDrawingArray(0); - r.getCTR().getDrawingArray(0).getInlineArray(0); - r.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic(); - r.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic().getGraphicData(); - PicDocument pd = new PicDocumentImpl(null); - assertTrue(pd.isNil()); - - doc.close(); - } - - @Test - public void testTika792() throws Exception { - //This test forces the loading of CTMoveBookmark and - //CTMoveBookmarkImpl into ooxml-lite. - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Tika-792.docx"); - XWPFParagraph paragraph = doc.getParagraphs().get(0); - assertEquals("s", paragraph.getText()); - doc.close(); - } - - @Test - public void testSettersGetters() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - assertTrue(p.isEmpty()); - assertFalse(p.removeRun(0)); - - p.setBorderTop(Borders.BABY_PACIFIER); - p.setBorderBetween(Borders.BABY_PACIFIER); - p.setBorderBottom(Borders.BABY_RATTLE); - - assertNotNull(p.getIRuns()); - assertEquals(0, p.getIRuns().size()); - assertFalse(p.isEmpty()); - assertNull(p.getStyleID()); - assertNull(p.getStyle()); - - assertNull(p.getNumID()); - p.setNumID(BigInteger.valueOf(12)); - assertEquals(BigInteger.valueOf(12), p.getNumID()); - p.setNumID(BigInteger.valueOf(13)); - assertEquals(BigInteger.valueOf(13), p.getNumID()); - - assertNull(p.getNumFmt()); - - assertNull(p.getNumIlvl()); - - assertEquals("", p.getParagraphText()); - assertEquals("", p.getPictureText()); - assertEquals("", p.getFootnoteText()); - - p.setBorderBetween(Borders.NONE); - assertEquals(Borders.NONE, p.getBorderBetween()); - p.setBorderBetween(Borders.BASIC_BLACK_DASHES); - assertEquals(Borders.BASIC_BLACK_DASHES, p.getBorderBetween()); - - p.setBorderBottom(Borders.NONE); - assertEquals(Borders.NONE, p.getBorderBottom()); - p.setBorderBottom(Borders.BABY_RATTLE); - assertEquals(Borders.BABY_RATTLE, p.getBorderBottom()); - - p.setBorderLeft(Borders.NONE); - assertEquals(Borders.NONE, p.getBorderLeft()); - p.setBorderLeft(Borders.BASIC_WHITE_SQUARES); - assertEquals(Borders.BASIC_WHITE_SQUARES, p.getBorderLeft()); - - p.setBorderRight(Borders.NONE); - assertEquals(Borders.NONE, p.getBorderRight()); - p.setBorderRight(Borders.BASIC_WHITE_DASHES); - assertEquals(Borders.BASIC_WHITE_DASHES, p.getBorderRight()); - - p.setBorderBottom(Borders.NONE); - assertEquals(Borders.NONE, p.getBorderBottom()); - p.setBorderBottom(Borders.BASIC_WHITE_DOTS); - assertEquals(Borders.BASIC_WHITE_DOTS, p.getBorderBottom()); - - assertFalse(p.isPageBreak()); - p.setPageBreak(true); - assertTrue(p.isPageBreak()); - p.setPageBreak(false); - assertFalse(p.isPageBreak()); - - assertEquals(-1, p.getSpacingAfter()); - p.setSpacingAfter(12); - assertEquals(12, p.getSpacingAfter()); - - assertEquals(-1, p.getSpacingAfterLines()); - p.setSpacingAfterLines(14); - assertEquals(14, p.getSpacingAfterLines()); - - assertEquals(-1, p.getSpacingBefore()); - p.setSpacingBefore(16); - assertEquals(16, p.getSpacingBefore()); - - assertEquals(-1, p.getSpacingBeforeLines()); - p.setSpacingBeforeLines(18); - assertEquals(18, p.getSpacingBeforeLines()); - - assertEquals(LineSpacingRule.AUTO, p.getSpacingLineRule()); - p.setSpacingLineRule(LineSpacingRule.EXACT); - assertEquals(LineSpacingRule.EXACT, p.getSpacingLineRule()); - - assertEquals(-1, p.getIndentationLeft()); - p.setIndentationLeft(21); - assertEquals(21, p.getIndentationLeft()); - - assertEquals(-1, p.getIndentationRight()); - p.setIndentationRight(25); - assertEquals(25, p.getIndentationRight()); - - assertEquals(-1, p.getIndentationHanging()); - p.setIndentationHanging(25); - assertEquals(25, p.getIndentationHanging()); - - assertEquals(-1, p.getIndentationFirstLine()); - p.setIndentationFirstLine(25); - assertEquals(25, p.getIndentationFirstLine()); - - assertFalse(p.isWordWrap()); - p.setWordWrapped(true); - assertTrue(p.isWordWrap()); - p.setWordWrapped(false); - assertFalse(p.isWordWrap()); - - assertNull(p.getStyle()); - p.setStyle("teststyle"); - assertEquals("teststyle", p.getStyle()); - - p.addRun(CTR.Factory.newInstance()); - - //assertTrue(p.removeRun(0)); - - assertNotNull(p.getBody()); - assertEquals(BodyElementType.PARAGRAPH, p.getElementType()); - assertEquals(BodyType.DOCUMENT, p.getPartType()); - - doc.close(); - } - - @Test - public void testSearchTextNotFound() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - assertNull(p.searchText("test", new PositionInParagraph())); - assertEquals("", p.getText()); - doc.close(); - } - - @Test - public void testSearchTextFound() throws IOException { - XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); - - List ps = xml.getParagraphs(); - assertEquals(10, ps.size()); - - XWPFParagraph p = ps.get(0); - - TextSegement segment = p.searchText("sample word document", new PositionInParagraph()); - assertNotNull(segment); - - assertEquals("sample word document", p.getText(segment)); - - assertTrue(p.removeRun(0)); - xml.close(); - } - - @Test - public void testFieldRuns() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FldSimple.docx"); - List ps = doc.getParagraphs(); - assertEquals(1, ps.size()); - - XWPFParagraph p = ps.get(0); - assertEquals(1, p.getRuns().size()); - assertEquals(1, p.getIRuns().size()); - - XWPFRun r = p.getRuns().get(0); - assertEquals(XWPFFieldRun.class, r.getClass()); - - XWPFFieldRun fr = (XWPFFieldRun)r; - assertEquals(" FILENAME \\* MERGEFORMAT ", fr.getFieldInstruction()); - assertEquals("FldSimple.docx", fr.text()); - assertEquals("FldSimple.docx", p.getText()); - doc.close(); - } - - @SuppressWarnings("deprecation") - @Test - public void testRuns() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFParagraph p = doc.createParagraph(); - - CTR run = CTR.Factory.newInstance(); - XWPFRun r = new XWPFRun(run, doc.createParagraph()); - p.addRun(r); - p.addRun(r); - - assertNotNull(p.getRun(run)); - assertNull(p.getRun(null)); - doc.close(); - } - - @Test - public void test58067() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("58067.docx"); - - StringBuilder str = new StringBuilder(); - for(XWPFParagraph par : doc.getParagraphs()) { - str.append(par.getText()).append("\n"); - } - assertEquals("This is a test.\n\n\n\n3\n4\n5\n\n\n\nThis is a whole paragraph where one word is deleted.\n", str.toString()); - } - - @Test - public void testNumberedLists() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ComplexNumberedLists.docx"); - XWPFParagraph p; - - p = doc.getParagraphArray(0); - assertEquals("This is a document with numbered lists", p.getText()); - assertEquals(null, p.getNumID()); - assertEquals(null, p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(1); - assertEquals("Entry #1", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(2); - assertEquals("Entry #2, with children", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(3); - assertEquals("2-a", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(1), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(4); - assertEquals("2-b", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(1), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(5); - assertEquals("2-c", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(1), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(6); - assertEquals("Entry #3", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(7); - assertEquals("Entry #4", p.getText()); - assertEquals(BigInteger.valueOf(1), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - // New list - p = doc.getParagraphArray(8); - assertEquals("Restarted to 1 from 5", p.getText()); - assertEquals(BigInteger.valueOf(2), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(9); - assertEquals("Restarted @ 2", p.getText()); - assertEquals(BigInteger.valueOf(2), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - p = doc.getParagraphArray(10); - assertEquals("Restarted @ 3", p.getText()); - assertEquals(BigInteger.valueOf(2), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - assertEquals(null, p.getNumStartOverride()); - - // New list starting at 10 - p = doc.getParagraphArray(11); - assertEquals("Jump to new list at 10", p.getText()); - assertEquals(BigInteger.valueOf(6), p.getNumID()); - assertEquals(BigInteger.valueOf(0), p.getNumIlvl()); - // TODO Why isn't this seen as 10? - assertEquals(null, p.getNumStartOverride()); - - // TODO Shouldn't we use XWPFNumbering or similar here? - // TODO Make it easier to change - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java deleted file mode 100644 index f4c0a49c0..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java +++ /dev/null @@ -1,179 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertArrayEquals; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; - -public class TestXWPFPictureData extends TestCase { - - public void testRead() throws InvalidFormatException, IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx"); - List pictures = sampleDoc.getAllPictures(); - - assertEquals(5, pictures.size()); - String[] ext = {"wmf", "png", "emf", "emf", "jpeg"}; - for (int i = 0; i < pictures.size(); i++) { - assertEquals(ext[i], pictures.get(i).suggestFileExtension()); - } - - int num = pictures.size(); - - byte[] pictureData = XWPFTestDataSamples.getImage("nature1.jpg"); - - String relationId = sampleDoc.addPictureData(pictureData, XWPFDocument.PICTURE_TYPE_JPEG); - // picture list was updated - assertEquals(num + 1, pictures.size()); - XWPFPictureData pict = (XWPFPictureData) sampleDoc.getRelationById(relationId); - assertEquals("jpeg", pict.suggestFileExtension()); - assertArrayEquals(pictureData, pict.getData()); - } - - public void testPictureInHeader() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx"); - verifyOneHeaderPicture(sampleDoc); - - XWPFDocument readBack = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc); - verifyOneHeaderPicture(readBack); - } - - public void testCreateHeaderPicture() throws Exception { - XWPFDocument doc = new XWPFDocument(); - - // Starts with no header - XWPFHeaderFooterPolicy policy = doc.getHeaderFooterPolicy(); - assertNull(policy); - - // Add a default header - policy = doc.createHeaderFooterPolicy(); - XWPFHeader header = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT); - header.createParagraph().createRun().setText("Hello, Header World!"); - header.createParagraph().createRun().setText("Paragraph 2"); - assertEquals(0, header.getAllPictures().size()); - assertEquals(2, header.getParagraphs().size()); - - // Add a picture to the first paragraph - header.getParagraphs().get(0).getRuns().get(0).addPicture( - new ByteArrayInputStream(new byte[] {1,2,3,4}), - Document.PICTURE_TYPE_JPEG, "test.jpg", 2, 2); - - // Check - verifyOneHeaderPicture(doc); - - // Save, re-load, re-check - XWPFDocument readBack = XWPFTestDataSamples.writeOutAndReadBack(doc); - verifyOneHeaderPicture(readBack); - } - - private void verifyOneHeaderPicture(XWPFDocument sampleDoc) { - XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); - - XWPFHeader header = policy.getDefaultHeader(); - - List pictures = header.getAllPictures(); - assertEquals(1, pictures.size()); - } - - public void testNew() throws InvalidFormatException, IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx"); - byte[] jpegData = XWPFTestDataSamples.getImage("nature1.jpg"); - assertNotNull(jpegData); - byte[] gifData = XWPFTestDataSamples.getImage("nature1.gif"); - assertNotNull(gifData); - byte[] pngData = XWPFTestDataSamples.getImage("nature1.png"); - assertNotNull(pngData); - - List pictures = doc.getAllPictures(); - assertEquals(0, pictures.size()); - - // Document shouldn't have any image relationships - assertEquals(13, doc.getPackagePart().getRelationships().size()); - for (PackageRelationship rel : doc.getPackagePart().getRelationships()) { - if (rel.getRelationshipType().equals(XSSFRelation.IMAGE_JPEG.getRelation())) { - fail("Shouldn't have JPEG yet"); - } - } - - // Add the image - String relationId = doc.addPictureData(jpegData, XWPFDocument.PICTURE_TYPE_JPEG); - assertEquals(1, pictures.size()); - XWPFPictureData jpgPicData = (XWPFPictureData) doc.getRelationById(relationId); - assertEquals("jpeg", jpgPicData.suggestFileExtension()); - assertArrayEquals(jpegData, jpgPicData.getData()); - - // Ensure it now has one - assertEquals(14, doc.getPackagePart().getRelationships().size()); - PackageRelationship jpegRel = null; - for (PackageRelationship rel : doc.getPackagePart().getRelationships()) { - if (rel.getRelationshipType().equals(XWPFRelation.IMAGE_JPEG.getRelation())) { - if (jpegRel != null) - fail("Found 2 jpegs!"); - jpegRel = rel; - } - } - assertNotNull("JPEG Relationship not found", jpegRel); - - // Check the details - assertNotNull(jpegRel); - assertEquals(XWPFRelation.IMAGE_JPEG.getRelation(), jpegRel.getRelationshipType()); - assertEquals("/word/document.xml", jpegRel.getSource().getPartName().toString()); - assertEquals("/word/media/image1.jpeg", jpegRel.getTargetURI().getPath()); - - XWPFPictureData pictureDataByID = doc.getPictureDataByID(jpegRel.getId()); - assertArrayEquals(jpegData, pictureDataByID.getData()); - - // Save an re-load, check it appears - doc = XWPFTestDataSamples.writeOutAndReadBack(doc); - assertEquals(1, doc.getAllPictures().size()); - assertEquals(1, doc.getAllPackagePictures().size()); - - // verify the picture that we read back in - pictureDataByID = doc.getPictureDataByID(jpegRel.getId()); - assertArrayEquals(jpegData, pictureDataByID.getData()); - - } - - public void testBug51770() throws InvalidFormatException, IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug51170.docx"); - XWPFHeaderFooterPolicy policy = doc.getHeaderFooterPolicy(); - XWPFHeader header = policy.getDefaultHeader(); - for (XWPFParagraph paragraph : header.getParagraphs()) { - for (XWPFRun run : paragraph.getRuns()) { - for (XWPFPicture picture : run.getEmbeddedPictures()) { - if (paragraph.getDocument() != null) { - //System.out.println(picture.getCTPicture()); - XWPFPictureData data = picture.getPictureData(); - if (data != null) System.out.println(data.getFileName()); - } - } - } - } - - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java deleted file mode 100644 index 419402709..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java +++ /dev/null @@ -1,577 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.util.Units; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.util.Iterator; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * Tests for XWPF Run - */ -@SuppressWarnings("deprecation") -public class TestXWPFRun { - private CTR ctRun; - private XWPFParagraph p; - private XWPFDocument doc; - - @Before - public void setUp() { - doc = new XWPFDocument(); - p = doc.createParagraph(); - - this.ctRun = CTR.Factory.newInstance(); - } - - @After - public void tearDown() throws Exception { - doc.close(); - } - - @Test - public void testSetGetText() { - ctRun.addNewT().setStringValue("TEST STRING"); - ctRun.addNewT().setStringValue("TEST2 STRING"); - ctRun.addNewT().setStringValue("TEST3 STRING"); - - assertEquals(3, ctRun.sizeOfTArray()); - XWPFRun run = new XWPFRun(ctRun, p); - - assertEquals("TEST2 STRING", run.getText(1)); - - run.setText("NEW STRING", 0); - assertEquals("NEW STRING", run.getText(0)); - - //run.setText("xxx",14); - //fail("Position wrong"); - } - - /* - * bug 59208 - * Purpose: test all valid boolean-like values - * exercise isCTOnOff(CTOnOff) through all valid permutations - */ - @Test - public void testCTOnOff() { - CTRPr rpr = ctRun.addNewRPr(); - CTOnOff bold = rpr.addNewB(); - XWPFRun run = new XWPFRun(ctRun, p); - - // True values: "true", "1", "on" - bold.setVal(STOnOff.TRUE); - assertEquals(true, run.isBold()); - - bold.setVal(STOnOff.X_1); - assertEquals(true, run.isBold()); - - bold.setVal(STOnOff.ON); - assertEquals(true, run.isBold()); - - // False values: "false", "0", "off" - bold.setVal(STOnOff.FALSE); - assertEquals(false, run.isBold()); - - bold.setVal(STOnOff.X_0); - assertEquals(false, run.isBold()); - - bold.setVal(STOnOff.OFF); - assertEquals(false, run.isBold()); - } - - @Test - public void testSetGetBold() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewB().setVal(STOnOff.TRUE); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(true, run.isBold()); - - run.setBold(false); - // Implementation detail: POI natively prefers , - // but should correctly read val="0" and val="off" - assertEquals(STOnOff.FALSE, rpr.getB().getVal()); - } - - @Test - public void testSetGetItalic() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewI().setVal(STOnOff.TRUE); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(true, run.isItalic()); - - run.setItalic(false); - assertEquals(STOnOff.FALSE, rpr.getI().getVal()); - } - - @Test - public void testSetGetStrike() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewStrike().setVal(STOnOff.TRUE); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(true, run.isStrike()); - - run.setStrike(false); - assertEquals(STOnOff.FALSE, rpr.getStrike().getVal()); - } - - @Test - public void testSetGetUnderline() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewU().setVal(STUnderline.DASH); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(UnderlinePatterns.DASH.getValue(), run.getUnderline() - .getValue()); - - run.setUnderline(UnderlinePatterns.NONE); - assertEquals(STUnderline.NONE.intValue(), rpr.getU().getVal() - .intValue()); - } - - @Test - public void testSetGetVAlign() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewVertAlign().setVal(STVerticalAlignRun.SUBSCRIPT); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(VerticalAlign.SUBSCRIPT, run.getSubscript()); - - run.setSubscript(VerticalAlign.BASELINE); - assertEquals(STVerticalAlignRun.BASELINE, rpr.getVertAlign().getVal()); - } - - @Test - public void testSetGetFontFamily() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewRFonts().setAscii("Times New Roman"); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals("Times New Roman", run.getFontFamily()); - - run.setFontFamily("Verdana"); - assertEquals("Verdana", rpr.getRFonts().getAscii()); - } - - @Test - public void testSetGetFontSize() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewSz().setVal(new BigInteger("14")); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(7, run.getFontSize()); - - run.setFontSize(24); - assertEquals(48, rpr.getSz().getVal().longValue()); - } - - @Test - public void testSetGetTextForegroundBackground() { - CTRPr rpr = ctRun.addNewRPr(); - rpr.addNewPosition().setVal(new BigInteger("4000")); - - XWPFRun run = new XWPFRun(ctRun, p); - assertEquals(4000, run.getTextPosition()); - - run.setTextPosition(2400); - assertEquals(2400, rpr.getPosition().getVal().longValue()); - } - - @Test - public void testSetGetColor() { - XWPFRun run = new XWPFRun(ctRun, p); - run.setColor("0F0F0F"); - String clr = run.getColor(); - assertEquals("0F0F0F", clr); - } - - @Test - public void testAddCarriageReturn() { - ctRun.addNewT().setStringValue("TEST STRING"); - ctRun.addNewCr(); - ctRun.addNewT().setStringValue("TEST2 STRING"); - ctRun.addNewCr(); - ctRun.addNewT().setStringValue("TEST3 STRING"); - assertEquals(2, ctRun.sizeOfCrArray()); - - XWPFRun run = new XWPFRun(CTR.Factory.newInstance(), p); - run.setText("T1"); - run.addCarriageReturn(); - run.addCarriageReturn(); - run.setText("T2"); - run.addCarriageReturn(); - assertEquals(3, run.getCTR().sizeOfCrArray()); - - assertEquals("T1\n\nT2\n", run.toString()); - } - - @Test - public void testAddTabsAndLineBreaks() { - ctRun.addNewT().setStringValue("TEST STRING"); - ctRun.addNewCr(); - ctRun.addNewT().setStringValue("TEST2 STRING"); - ctRun.addNewTab(); - ctRun.addNewT().setStringValue("TEST3 STRING"); - assertEquals(1, ctRun.sizeOfCrArray()); - assertEquals(1, ctRun.sizeOfTabArray()); - - XWPFRun run = new XWPFRun(CTR.Factory.newInstance(), p); - run.setText("T1"); - run.addCarriageReturn(); - run.setText("T2"); - run.addTab(); - run.setText("T3"); - assertEquals(1, run.getCTR().sizeOfCrArray()); - assertEquals(1, run.getCTR().sizeOfTabArray()); - - assertEquals("T1\nT2\tT3", run.toString()); - } - - @Test - public void testAddPageBreak() { - ctRun.addNewT().setStringValue("TEST STRING"); - ctRun.addNewBr(); - ctRun.addNewT().setStringValue("TEST2 STRING"); - CTBr breac = ctRun.addNewBr(); - breac.setClear(STBrClear.LEFT); - ctRun.addNewT().setStringValue("TEST3 STRING"); - assertEquals(2, ctRun.sizeOfBrArray()); - - XWPFRun run = new XWPFRun(CTR.Factory.newInstance(), p); - run.setText("TEXT1"); - run.addBreak(); - run.setText("TEXT2"); - run.addBreak(BreakType.TEXT_WRAPPING); - assertEquals(2, run.getCTR().sizeOfBrArray()); - } - - /** - * Test that on an existing document, we do the - * right thing with it - * - * @throws IOException - */ - @Test - public void testExisting() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); - XWPFParagraph p; - XWPFRun run; - - - // First paragraph is simple - p = doc.getParagraphArray(0); - assertEquals("This is a test document.", p.getText()); - assertEquals(2, p.getRuns().size()); - - run = p.getRuns().get(0); - assertEquals("This is a test document", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - run = p.getRuns().get(1); - assertEquals(".", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - - // Next paragraph is all in one style, but a different one - p = doc.getParagraphArray(1); - assertEquals("This bit is in bold and italic", p.getText()); - assertEquals(1, p.getRuns().size()); - - run = p.getRuns().get(0); - assertEquals("This bit is in bold and italic", run.toString()); - assertEquals(true, run.isBold()); - assertEquals(true, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(true, run.getCTR().getRPr().isSetB()); - assertEquals(false, run.getCTR().getRPr().getB().isSetVal()); - - - // Back to normal - p = doc.getParagraphArray(2); - assertEquals("Back to normal", p.getText()); - assertEquals(1, p.getRuns().size()); - - run = p.getRuns().get(0); - assertEquals("Back to normal", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - - // Different styles in one paragraph - p = doc.getParagraphArray(3); - assertEquals("This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.", p.getText()); - assertEquals(11, p.getRuns().size()); - - run = p.getRuns().get(0); - assertEquals("This contains ", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - run = p.getRuns().get(1); - assertEquals("BOLD", run.toString()); - assertEquals(true, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - - run = p.getRuns().get(2); - assertEquals(", ", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - run = p.getRuns().get(3); - assertEquals("ITALIC", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(true, run.isItalic()); - assertEquals(false, run.isStrike()); - - run = p.getRuns().get(4); - assertEquals(" and ", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - run = p.getRuns().get(5); - assertEquals("BOTH", run.toString()); - assertEquals(true, run.isBold()); - assertEquals(true, run.isItalic()); - assertEquals(false, run.isStrike()); - - run = p.getRuns().get(6); - assertEquals(", as well as ", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - run = p.getRuns().get(7); - assertEquals("RED", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - - run = p.getRuns().get(8); - assertEquals(" and ", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - - run = p.getRuns().get(9); - assertEquals("YELLOW", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - - run = p.getRuns().get(10); - assertEquals(" text.", run.toString()); - assertEquals(false, run.isBold()); - assertEquals(false, run.isItalic()); - assertEquals(false, run.isStrike()); - assertEquals(null, run.getCTR().getRPr()); - } - - @Test - public void testPictureInHeader() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx"); - XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); - - XWPFHeader header = policy.getDefaultHeader(); - - int count = 0; - - for (XWPFParagraph p : header.getParagraphs()) { - for (XWPFRun r : p.getRuns()) { - List pictures = r.getEmbeddedPictures(); - - for (XWPFPicture pic : pictures) { - assertNotNull(pic.getPictureData()); - assertEquals("DOZOR", pic.getDescription()); - } - - count += pictures.size(); - } - } - - assertEquals(1, count); - } - - @Test - public void testSetGetHighlight() throws Exception { - XWPFRun run = p.createRun(); - assertEquals(false, run.isHighlighted()); - - // TODO Do this using XWPFRun methods - run.getCTR().addNewRPr().addNewHighlight().setVal(STHighlightColor.NONE); - assertEquals(false, run.isHighlighted()); - run.getCTR().getRPr().getHighlight().setVal(STHighlightColor.CYAN); - assertEquals(true, run.isHighlighted()); - run.getCTR().getRPr().getHighlight().setVal(STHighlightColor.NONE); - assertEquals(false, run.isHighlighted()); - } - - @Test - public void testAddPicture() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); - XWPFParagraph p = doc.getParagraphArray(2); - XWPFRun r = p.getRuns().get(0); - - assertEquals(0, doc.getAllPictures().size()); - assertEquals(0, r.getEmbeddedPictures().size()); - - r.addPicture(new ByteArrayInputStream(new byte[0]), Document.PICTURE_TYPE_JPEG, "test.jpg", 21, 32); - - assertEquals(1, doc.getAllPictures().size()); - assertEquals(1, r.getEmbeddedPictures().size()); - - XWPFDocument docBack = XWPFTestDataSamples.writeOutAndReadBack(doc); - XWPFParagraph pBack = docBack.getParagraphArray(2); - XWPFRun rBack = pBack.getRuns().get(0); - - assertEquals(1, docBack.getAllPictures().size()); - assertEquals(1, rBack.getEmbeddedPictures().size()); - } - - /** - * Bugzilla #52288 - setting the font family on the - * run mustn't NPE - */ - @Test - public void testSetFontFamily_52288() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("52288.docx"); - final Iterator paragraphs = doc.getParagraphsIterator(); - while (paragraphs.hasNext()) { - final XWPFParagraph paragraph = paragraphs.next(); - for (final XWPFRun run : paragraph.getRuns()) { - if (run != null) { - final String text = run.getText(0); - if (text != null) { - run.setFontFamily("Times New Roman"); - } - } - } - } - } - - @Test - public void testBug55476() throws IOException, InvalidFormatException { - byte[] image = XWPFTestDataSamples.getImage("abstract1.jpg"); - XWPFDocument document = new XWPFDocument(); - - document.createParagraph().createRun().addPicture( - new ByteArrayInputStream(image), Document.PICTURE_TYPE_JPEG, "test.jpg", Units.toEMU(300), Units.toEMU(100)); - - XWPFDocument docBack = XWPFTestDataSamples.writeOutAndReadBack(document); - List pictures = docBack.getParagraphArray(0).getRuns().get(0).getEmbeddedPictures(); - assertEquals(1, pictures.size()); - docBack.close(); - - /*OutputStream stream = new FileOutputStream("c:\\temp\\55476.docx"); - try { - document.write(stream); - } finally { - stream.close(); - }*/ - - document.close(); - } - - @Test - public void testBug58922() { - XWPFDocument document = new XWPFDocument(); - - final XWPFRun run = document.createParagraph().createRun(); - - - assertEquals(-1, run.getFontSize()); - - run.setFontSize(10); - assertEquals(10, run.getFontSize()); - - run.setFontSize(Short.MAX_VALUE-1); - assertEquals(Short.MAX_VALUE-1, run.getFontSize()); - - run.setFontSize(Short.MAX_VALUE); - assertEquals(Short.MAX_VALUE, run.getFontSize()); - - run.setFontSize(Short.MAX_VALUE+1); - assertEquals(Short.MAX_VALUE+1, run.getFontSize()); - - run.setFontSize(Integer.MAX_VALUE-1); - assertEquals(Integer.MAX_VALUE-1, run.getFontSize()); - - run.setFontSize(Integer.MAX_VALUE); - assertEquals(Integer.MAX_VALUE, run.getFontSize()); - - run.setFontSize(-1); - assertEquals(-1, run.getFontSize()); - - - assertEquals(-1, run.getTextPosition()); - - run.setTextPosition(10); - assertEquals(10, run.getTextPosition()); - - run.setTextPosition(Short.MAX_VALUE-1); - assertEquals(Short.MAX_VALUE-1, run.getTextPosition()); - - run.setTextPosition(Short.MAX_VALUE); - assertEquals(Short.MAX_VALUE, run.getTextPosition()); - - run.setTextPosition(Short.MAX_VALUE+1); - assertEquals(Short.MAX_VALUE+1, run.getTextPosition()); - - run.setTextPosition(Short.MAX_VALUE+1); - assertEquals(Short.MAX_VALUE+1, run.getTextPosition()); - - run.setTextPosition(Integer.MAX_VALUE-1); - assertEquals(Integer.MAX_VALUE-1, run.getTextPosition()); - - run.setTextPosition(Integer.MAX_VALUE); - assertEquals(Integer.MAX_VALUE, run.getTextPosition()); - - run.setTextPosition(-1); - assertEquals(-1, run.getTextPosition()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java deleted file mode 100644 index 9cba17e36..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java +++ /dev/null @@ -1,213 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.junit.Ignore; -import org.junit.Test; - -public final class TestXWPFSDT { - - /** - * Test simple tag and title extraction from SDT - * - * @throws Exception - */ - @Test - public void testTagTitle() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx"); - String tag = null; - String title = null; - List sdts = extractAllSDTs(doc); - for (AbstractXWPFSDT sdt : sdts) { - if (sdt.getContent().toString().equals("Rich_text")) { - tag = "MyTag"; - title = "MyTitle"; - break; - } - - } - assertEquals("controls size", 13, sdts.size()); - - assertEquals("tag", "MyTag", tag); - assertEquals("title", "MyTitle", title); - } - - @Test - public void testGetSDTs() throws Exception { - String[] contents = new String[]{ - "header_rich_text", - "Rich_text", - "Rich_text_pre_table\nRich_text_cell1\t\t\t\n\t\t\t\n\t\t\t\n\nRich_text_post_table", - "Plain_text_no_newlines", - "Plain_text_with_newlines1\nplain_text_with_newlines2", - "Watermelon", - "Dirt", - "4/16/2013", - "Rich_text_in_cell", - "rich_text_in_paragraph_in_cell", - "Footer_rich_text", - "Footnote_sdt", - "Endnote_sdt" - - }; - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx"); - List sdts = extractAllSDTs(doc); - - assertEquals("number of sdts", contents.length, sdts.size()); - - for (int i = 0; i < contents.length; i++) { - AbstractXWPFSDT sdt = sdts.get(i); - assertEquals(i + ": " + contents[i], contents[i], sdt.getContent().toString()); - } - } - - /** - * POI-54771 and TIKA-1317 - */ - @Test - public void testSDTAsCell() throws Exception { - //Bug54771a.docx and Bug54771b.docx test slightly - //different recursion patterns. Keep both! - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54771a.docx"); - List sdts = extractAllSDTs(doc); - String text = sdts.get(0).getContent().getText(); - assertEquals(2, sdts.size()); - assertTrue(text.indexOf("Test") > -1); - - text = sdts.get(1).getContent().getText(); - assertTrue(text.indexOf("Test Subtitle") > -1); - assertTrue(text.indexOf("Test User") > -1); - assertTrue(text.indexOf("Test") < text.indexOf("Test Subtitle")); - - doc = XWPFTestDataSamples.openSampleDocument("Bug54771b.docx"); - sdts = extractAllSDTs(doc); - assertEquals(3, sdts.size()); - assertTrue(sdts.get(0).getContent().getText().indexOf("Test") > -1); - - assertTrue(sdts.get(1).getContent().getText().indexOf("Test Subtitle") > -1); - assertTrue(sdts.get(2).getContent().getText().indexOf("Test User") > -1); - - } - - /** - * POI-55142 and Tika 1130 - */ - @Test - public void testNewLinesBetweenRuns() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug55142.docx"); - List sdts = extractAllSDTs(doc); - List targs = new ArrayList(); - //these test newlines and tabs in paragraphs/body elements - targs.add("Rich-text1 abcdefghi"); - targs.add("Rich-text2 abcd\t\tefgh"); - targs.add("Rich-text3 abcd\nefg"); - targs.add("Rich-text4 abcdefg"); - targs.add("Rich-text5 abcdefg\nhijk"); - targs.add("Plain-text1 abcdefg"); - targs.add("Plain-text2 abcdefg\nhijk\nlmnop"); - //this tests consecutive runs within a cell (not a paragraph) - //this test case was triggered by Tika-1130 - targs.add("sdt_incell2 abcdefg"); - - for (int i = 0; i < sdts.size(); i++) { - AbstractXWPFSDT sdt = sdts.get(i); - assertEquals(targs.get(i), targs.get(i), sdt.getContent().getText()); - } - } - - @Test - public void test60341() throws IOException { - //handle sdtbody without an sdtpr - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug60341.docx"); - List sdts = extractAllSDTs(doc); - assertEquals(1, sdts.size()); - assertEquals("", sdts.get(0).getTag()); - assertEquals("", sdts.get(0).getTitle()); - } - - private List extractAllSDTs(XWPFDocument doc) { - - List sdts = new ArrayList(); - - List headers = doc.getHeaderList(); - for (XWPFHeader header : headers) { - sdts.addAll(extractSDTsFromBodyElements(header.getBodyElements())); - } - sdts.addAll(extractSDTsFromBodyElements(doc.getBodyElements())); - - List footers = doc.getFooterList(); - for (XWPFFooter footer : footers) { - sdts.addAll(extractSDTsFromBodyElements(footer.getBodyElements())); - } - - for (XWPFFootnote footnote : doc.getFootnotes()) { - sdts.addAll(extractSDTsFromBodyElements(footnote.getBodyElements())); - } - for (Map.Entry e : doc.endnotes.entrySet()) { - sdts.addAll(extractSDTsFromBodyElements(e.getValue().getBodyElements())); - } - return sdts; - } - - private List extractSDTsFromBodyElements(List elements) { - List sdts = new ArrayList(); - for (IBodyElement e : elements) { - if (e instanceof XWPFSDT) { - XWPFSDT sdt = (XWPFSDT) e; - sdts.add(sdt); - } else if (e instanceof XWPFParagraph) { - - XWPFParagraph p = (XWPFParagraph) e; - for (IRunElement e2 : p.getIRuns()) { - if (e2 instanceof XWPFSDT) { - XWPFSDT sdt = (XWPFSDT) e2; - sdts.add(sdt); - } - } - } else if (e instanceof XWPFTable) { - XWPFTable table = (XWPFTable) e; - sdts.addAll(extractSDTsFromTable(table)); - } - } - return sdts; - } - - private List extractSDTsFromTable(XWPFTable table) { - - List sdts = new ArrayList(); - for (XWPFTableRow r : table.getRows()) { - for (ICell c : r.getTableICells()) { - if (c instanceof XWPFSDTCell) { - sdts.add((XWPFSDTCell) c); - } else if (c instanceof XWPFTableCell) { - sdts.addAll(extractSDTsFromBodyElements(((XWPFTableCell) c).getBodyElements())); - } - } - } - return sdts; - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java deleted file mode 100644 index 7adc0d0f3..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io.IOException; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; - -/** - * Tests for reading SmartTags from Word docx. - * - * @author Fabian Lange - */ -public final class TestXWPFSmartTag extends TestCase { - - public void testSmartTags() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("smarttag-snippet.docx"); - XWPFParagraph p = doc.getParagraphArray(0); - assertTrue(p.getText().contains("Carnegie Mellon University School of Computer Science")); - p = doc.getParagraphArray(2); - assertTrue(p.getText().contains("Alice's Adventures")); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java deleted file mode 100644 index 3773b2998..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java +++ /dev/null @@ -1,191 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType; - -public class TestXWPFStyles extends TestCase { - public void testGetUsedStyles() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx"); - List testUsedStyleList = new ArrayList(); - XWPFStyles styles = sampleDoc.getStyles(); - XWPFStyle style = styles.getStyle("berschrift1"); - testUsedStyleList.add(style); - testUsedStyleList.add(styles.getStyle("Standard")); - testUsedStyleList.add(styles.getStyle("berschrift1Zchn")); - testUsedStyleList.add(styles.getStyle("Absatz-Standardschriftart")); - style.hasSameName(style); - - List usedStyleList = styles.getUsedStyleList(style); - assertEquals(usedStyleList, testUsedStyleList); - } - - public void testAddStylesToDocument() throws IOException { - XWPFDocument docOut = new XWPFDocument(); - XWPFStyles styles = docOut.createStyles(); - - String strStyleId = "headline1"; - CTStyle ctStyle = CTStyle.Factory.newInstance(); - - ctStyle.setStyleId(strStyleId); - XWPFStyle s = new XWPFStyle(ctStyle); - styles.addStyle(s); - - assertTrue(styles.styleExist(strStyleId)); - - XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut); - - styles = docIn.getStyles(); - assertTrue(styles.styleExist(strStyleId)); - } - - /** - * Bug #52449 - We should be able to write a file containing - * both regular and glossary styles without error - */ - public void test52449() throws Exception { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("52449.docx"); - XWPFStyles styles = doc.getStyles(); - assertNotNull(styles); - - XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(doc); - styles = docIn.getStyles(); - assertNotNull(styles); - } - - - /** - * YK: tests below don't make much sense, - * they exist only to copy xml beans to pi-ooxml-schemas.jar - */ - @SuppressWarnings("resource") - public void testLanguages() { - XWPFDocument docOut = new XWPFDocument(); - XWPFStyles styles = docOut.createStyles(); - styles.setEastAsia("Chinese"); - - styles.setSpellingLanguage("English"); - - CTFonts def = CTFonts.Factory.newInstance(); - styles.setDefaultFonts(def); - } - - public void testType() { - CTStyle ctStyle = CTStyle.Factory.newInstance(); - XWPFStyle style = new XWPFStyle(ctStyle); - - style.setType(STStyleType.PARAGRAPH); - assertEquals(STStyleType.PARAGRAPH, style.getType()); - } - - public void testLatentStyles() { - CTLatentStyles latentStyles = CTLatentStyles.Factory.newInstance(); - CTLsdException ex = latentStyles.addNewLsdException(); - ex.setName("ex1"); - XWPFLatentStyles ls = new XWPFLatentStyles(latentStyles); - assertEquals(true, ls.isLatentStyle("ex1")); - assertEquals(false, ls.isLatentStyle("notex1")); - } - - public void testSetStyles_Bug57254() throws IOException { - XWPFDocument docOut = new XWPFDocument(); - XWPFStyles styles = docOut.createStyles(); - - CTStyles ctStyles = CTStyles.Factory.newInstance(); - String strStyleId = "headline1"; - CTStyle ctStyle = ctStyles.addNewStyle(); - - ctStyle.setStyleId(strStyleId); - styles.setStyles(ctStyles); - - assertTrue(styles.styleExist(strStyleId)); - - XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut); - - styles = docIn.getStyles(); - assertTrue(styles.styleExist(strStyleId)); - } - - public void testEasyAccessToStyles() throws IOException { - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); - XWPFStyles styles = doc.getStyles(); - assertNotNull(styles); - - // Has 3 paragraphs on page one, a break, and 3 on page 2 - assertEquals(7, doc.getParagraphs().size()); - - // Check the first three have no run styles, just default paragraph style - for (int i = 0; i < 3; i++) { - XWPFParagraph p = doc.getParagraphs().get(i); - assertEquals(null, p.getStyle()); - assertEquals(null, p.getStyleID()); - assertEquals(1, p.getRuns().size()); - - XWPFRun r = p.getRuns().get(0); - assertEquals(null, r.getColor()); - assertEquals(null, r.getFontFamily()); - assertEquals(null, r.getFontName()); - assertEquals(-1, r.getFontSize()); - } - - // On page two, has explicit styles, but on runs not on - // the paragraph itself - for (int i = 4; i < 7; i++) { - XWPFParagraph p = doc.getParagraphs().get(i); - assertEquals(null, p.getStyle()); - assertEquals(null, p.getStyleID()); - assertEquals(1, p.getRuns().size()); - - XWPFRun r = p.getRuns().get(0); - assertEquals("Arial Black", r.getFontFamily()); - assertEquals("Arial Black", r.getFontName()); - assertEquals(16, r.getFontSize()); - assertEquals("548DD4", r.getColor()); - } - - // Check the document styles - // Should have a style defined for each type - assertEquals(4, styles.getNumberOfStyles()); - assertNotNull(styles.getStyle("Normal")); - assertNotNull(styles.getStyle("DefaultParagraphFont")); - assertNotNull(styles.getStyle("TableNormal")); - assertNotNull(styles.getStyle("NoList")); - - // We can't do much yet with latent styles - assertEquals(137, styles.getLatentStyles().getNumberOfStyles()); - - // Check the default styles - assertNotNull(styles.getDefaultRunStyle()); - assertNotNull(styles.getDefaultParagraphStyle()); - - assertEquals(11, styles.getDefaultRunStyle().getFontSize()); - assertEquals(200, styles.getDefaultParagraphStyle().getSpacingAfter()); - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java deleted file mode 100644 index 449f6b6b8..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java +++ /dev/null @@ -1,258 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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.math.BigInteger; -import java.util.List; - -import junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFTable.XWPFBorderType; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblCellMar; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder; - -/** - * Tests for XWPF Tables - */ -public class TestXWPFTable extends TestCase { - @Override - protected void setUp() { - /* - XWPFDocument doc = new XWPFDocument(); - p = doc.createParagraph(); - - this.ctRun = CTR.Factory.newInstance(); - */ - } - - public void testConstructor() { - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable xtab = new XWPFTable(ctTable, doc); - assertNotNull(xtab); - assertEquals(1, ctTable.sizeOfTrArray()); - assertEquals(1, ctTable.getTrArray(0).sizeOfTcArray()); - assertNotNull(ctTable.getTrArray(0).getTcArray(0).getPArray(0)); - - ctTable = CTTbl.Factory.newInstance(); - xtab = new XWPFTable(ctTable, doc, 3, 2); - assertNotNull(xtab); - assertEquals(3, ctTable.sizeOfTrArray()); - assertEquals(2, ctTable.getTrArray(0).sizeOfTcArray()); - assertNotNull(ctTable.getTrArray(0).getTcArray(0).getPArray(0)); - } - - public void testTblGrid() { - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - CTTblGrid cttblgrid = ctTable.addNewTblGrid(); - cttblgrid.addNewGridCol().setW(new BigInteger("123")); - cttblgrid.addNewGridCol().setW(new BigInteger("321")); - - XWPFTable xtab = new XWPFTable(ctTable, doc); - assertEquals(123, xtab.getCTTbl().getTblGrid().getGridColArray(0).getW().intValue()); - assertEquals(321, xtab.getCTTbl().getTblGrid().getGridColArray(1).getW().intValue()); - } - - public void testGetText() { - XWPFDocument doc = new XWPFDocument(); - CTTbl table = CTTbl.Factory.newInstance(); - CTRow row = table.addNewTr(); - CTTc cell = row.addNewTc(); - CTP paragraph = cell.addNewP(); - CTR run = paragraph.addNewR(); - CTText text = run.addNewT(); - text.setStringValue("finally I can write!"); - - XWPFTable xtab = new XWPFTable(table, doc); - assertEquals("finally I can write!\n", xtab.getText()); - } - - - public void testCreateRow() { - XWPFDocument doc = new XWPFDocument(); - - CTTbl table = CTTbl.Factory.newInstance(); - CTRow r1 = table.addNewTr(); - r1.addNewTc().addNewP(); - r1.addNewTc().addNewP(); - CTRow r2 = table.addNewTr(); - r2.addNewTc().addNewP(); - r2.addNewTc().addNewP(); - CTRow r3 = table.addNewTr(); - r3.addNewTc().addNewP(); - r3.addNewTc().addNewP(); - - XWPFTable xtab = new XWPFTable(table, doc); - assertEquals(3, xtab.getNumberOfRows()); - assertNotNull(xtab.getRow(2)); - - //add a new row - xtab.createRow(); - assertEquals(4, xtab.getNumberOfRows()); - - //check number of cols - assertEquals(2, table.getTrArray(0).sizeOfTcArray()); - - //check creation of first row - xtab = new XWPFTable(CTTbl.Factory.newInstance(), doc); - assertEquals(1, xtab.getCTTbl().getTrArray(0).sizeOfTcArray()); - } - - - public void testSetGetWidth() { - XWPFDocument doc = new XWPFDocument(); - - CTTbl table = CTTbl.Factory.newInstance(); - table.addNewTblPr().addNewTblW().setW(new BigInteger("1000")); - - XWPFTable xtab = new XWPFTable(table, doc); - - assertEquals(1000, xtab.getWidth()); - - xtab.setWidth(100); - assertEquals(100, table.getTblPr().getTblW().getW().intValue()); - } - - public void testSetGetHeight() { - XWPFDocument doc = new XWPFDocument(); - - CTTbl table = CTTbl.Factory.newInstance(); - - XWPFTable xtab = new XWPFTable(table, doc); - XWPFTableRow row = xtab.createRow(); - row.setHeight(20); - assertEquals(20, row.getHeight()); - } - - public void testSetGetMargins() { - // instantiate the following class so it'll get picked up by - // the XmlBean process and added to the jar file. it's required - // for the following XWPFTable methods. - CTTblCellMar ctm = CTTblCellMar.Factory.newInstance(); - assertNotNull(ctm); - // create a table - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - // set margins - table.setCellMargins(50, 50, 250, 450); - // get margin components - int t = table.getCellMarginTop(); - assertEquals(50, t); - int l = table.getCellMarginLeft(); - assertEquals(50, l); - int b = table.getCellMarginBottom(); - assertEquals(250, b); - int r = table.getCellMarginRight(); - assertEquals(450, r); - } - - public void testSetGetHBorders() { - // instantiate the following classes so they'll get picked up by - // the XmlBean process and added to the jar file. they are required - // for the following XWPFTable methods. - CTTblBorders cttb = CTTblBorders.Factory.newInstance(); - assertNotNull(cttb); - STBorder stb = STBorder.Factory.newInstance(); - assertNotNull(stb); - // create a table - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - // set inside horizontal border - table.setInsideHBorder(XWPFBorderType.SINGLE, 4, 0, "FF0000"); - // get inside horizontal border components - int s = table.getInsideHBorderSize(); - assertEquals(4, s); - int sp = table.getInsideHBorderSpace(); - assertEquals(0, sp); - String clr = table.getInsideHBorderColor(); - assertEquals("FF0000", clr); - XWPFBorderType bt = table.getInsideHBorderType(); - assertEquals(XWPFBorderType.SINGLE, bt); - } - - public void testSetGetVBorders() { - // create a table - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - // set inside vertical border - table.setInsideVBorder(XWPFBorderType.DOUBLE, 4, 0, "00FF00"); - // get inside vertical border components - XWPFBorderType bt = table.getInsideVBorderType(); - assertEquals(XWPFBorderType.DOUBLE, bt); - int sz = table.getInsideVBorderSize(); - assertEquals(4, sz); - int sp = table.getInsideVBorderSpace(); - assertEquals(0, sp); - String clr = table.getInsideVBorderColor(); - assertEquals("00FF00", clr); - } - - public void testSetGetRowBandSize() { - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - table.setRowBandSize(12); - int sz = table.getRowBandSize(); - assertEquals(12, sz); - } - - public void testSetGetColBandSize() { - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - table.setColBandSize(16); - int sz = table.getColBandSize(); - assertEquals(16, sz); - } - - public void testCreateTable() throws Exception { - // open an empty document - XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); - - // create a table with 5 rows and 7 columns - int noRows = 5; - int noCols = 7; - XWPFTable table = doc.createTable(noRows, noCols); - - // assert the table is empty - List rows = table.getRows(); - assertEquals("Table has less rows than requested.", noRows, rows.size()); - for (XWPFTableRow xwpfRow : rows) { - assertNotNull(xwpfRow); - for (int i = 0; i < 7; i++) { - XWPFTableCell xwpfCell = xwpfRow.getCell(i); - assertNotNull(xwpfCell); - assertEquals("Empty cells should not have one paragraph.", 1, xwpfCell.getParagraphs().size()); - xwpfCell = xwpfRow.getCell(i); - assertEquals("Calling 'getCell' must not modify cells content.", 1, xwpfCell.getParagraphs().size()); - } - } - doc.getPackage().revert(); - } -} \ No newline at end of file diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java deleted file mode 100644 index 00e34e241..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF 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 junit.framework.TestCase; -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.apache.poi.xwpf.usermodel.XWPFTableCell.XWPFVertAlign; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; - -import java.util.List; - -public class TestXWPFTableCell extends TestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testSetGetVertAlignment() throws Exception { - // instantiate the following classes so they'll get picked up by - // the XmlBean process and added to the jar file. they are required - // for the following XWPFTableCell methods. - CTShd ctShd = CTShd.Factory.newInstance(); - assertNotNull(ctShd); - CTVerticalJc ctVjc = CTVerticalJc.Factory.newInstance(); - assertNotNull(ctVjc); - STShd stShd = STShd.Factory.newInstance(); - assertNotNull(stShd); - STVerticalJc stVjc = STVerticalJc.Factory.newInstance(); - assertNotNull(stVjc); - - // create a table - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - // table has a single row by default; grab it - XWPFTableRow tr = table.getRow(0); - assertNotNull(tr); - // row has a single cell by default; grab it - XWPFTableCell cell = tr.getCell(0); - - cell.setVerticalAlignment(XWPFVertAlign.BOTH); - XWPFVertAlign al = cell.getVerticalAlignment(); - assertEquals(XWPFVertAlign.BOTH, al); - } - - public void testSetGetColor() throws Exception { - // create a table - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - // table has a single row by default; grab it - XWPFTableRow tr = table.getRow(0); - assertNotNull(tr); - // row has a single cell by default; grab it - XWPFTableCell cell = tr.getCell(0); - - cell.setColor("F0000F"); - String clr = cell.getColor(); - assertEquals("F0000F", clr); - } - - /** - * ensure that CTHMerge & CTTcBorders go in poi-ooxml.jar - */ - @SuppressWarnings("unused") - public void test54099() { - XWPFDocument doc = new XWPFDocument(); - CTTbl ctTable = CTTbl.Factory.newInstance(); - XWPFTable table = new XWPFTable(ctTable, doc); - XWPFTableRow tr = table.getRow(0); - XWPFTableCell cell = tr.getCell(0); - - CTTc ctTc = cell.getCTTc(); - CTTcPr tcPr = ctTc.addNewTcPr(); - CTHMerge hMerge = tcPr.addNewHMerge(); - hMerge.setVal(STMerge.RESTART); - - CTTcBorders tblBorders = tcPr.addNewTcBorders(); - CTVMerge vMerge = tcPr.addNewVMerge(); - } - - public void testCellVerticalAlign() throws Exception{ - XWPFDocument docx = XWPFTestDataSamples.openSampleDocument("59030.docx"); - List tables = docx.getTables(); - assertEquals(1, tables.size()); - - XWPFTable table = tables.get(0); - - List tableRows = table.getRows(); - assertEquals(2, tableRows.size()); - - assertEquals(XWPFVertAlign.TOP, tableRows.get(0).getCell(0).getVerticalAlignment()); - assertEquals(XWPFVertAlign.BOTTOM, tableRows.get(0).getCell(1).getVerticalAlignment()); - assertEquals(XWPFVertAlign.CENTER, tableRows.get(1).getCell(0).getVerticalAlignment()); - assertEquals(XWPFVertAlign.TOP, tableRows.get(1).getCell(1).getVerticalAlignment()); - } - - public void testCellVerticalAlign2() throws Exception{ - XWPFDocument docx = XWPFTestDataSamples.openSampleDocument("TestTableCellAlign.docx"); - List tables = docx.getTables(); - for (XWPFTable table : tables) { - List tableRows = table.getRows(); - for (XWPFTableRow tableRow : tableRows) { - List tableCells = tableRow.getTableCells(); - for (XWPFTableCell tableCell : tableCells) { - assertNotNull(tableCell.getVerticalAlignment()); - } - } - } - } -} diff --git a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java b/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java deleted file mode 100644 index 57ed43532..000000000 --- a/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; - -import org.apache.poi.xwpf.XWPFTestDataSamples; -import org.junit.Test; - -public class TestXWPFTableRow { - - @Test - public void testCreateRow() throws IOException { - XWPFDocument doc = new XWPFDocument(); - XWPFTable table = doc.createTable(1, 1); - XWPFTableRow tr = table.createRow(); - assertNotNull(tr); - doc.close(); - } - - @Test - public void testSetGetCantSplitRow() throws IOException { - // create a table - XWPFDocument doc = new XWPFDocument(); - XWPFTable table = doc.createTable(1, 1); - // table has a single row by default; grab it - XWPFTableRow tr = table.getRow(0); - assertNotNull(tr); - - // Assert the repeat header is false by default - boolean isCantSplit = tr.isCantSplitRow(); - assertFalse(isCantSplit); - - // Repeat the header - tr.setCantSplitRow(true); - isCantSplit = tr.isCantSplitRow(); - assertTrue(isCantSplit); - - // Make the header no longer repeating - tr.setCantSplitRow(false); - isCantSplit = tr.isCantSplitRow(); - assertFalse(isCantSplit); - - doc.close(); - } - - @Test - public void testSetGetRepeatHeader() throws IOException { - // create a table - XWPFDocument doc = new XWPFDocument(); - XWPFTable table = doc.createTable(3, 1); - // table has a single row by default; grab it - XWPFTableRow tr = table.getRow(0); - assertNotNull(tr); - - // Assert the repeat header is false by default - boolean isRpt = tr.isRepeatHeader(); - assertFalse(isRpt); - - // Repeat the header - tr.setRepeatHeader(true); - isRpt = tr.isRepeatHeader(); - assertTrue(isRpt); - - // Make the header no longer repeating - tr.setRepeatHeader(false); - isRpt = tr.isRepeatHeader(); - assertFalse(isRpt); - - // If the third row is set to repeat, but not the second, - // isRepeatHeader should report false because Word will - // ignore it. - tr = table.getRow(2); - tr.setRepeatHeader(true); - isRpt = tr.isRepeatHeader(); - assertFalse(isRpt); - - doc.close(); - } - - // Test that validates the table header value can be parsed from a document - // generated in Word - @Test - public void testIsRepeatHeader() throws Exception { - XWPFDocument doc = XWPFTestDataSamples - .openSampleDocument("Bug60337.docx"); - XWPFTable table = doc.getTables().get(0); - XWPFTableRow tr = table.getRow(0); - boolean isRpt = tr.isRepeatHeader(); - assertTrue(isRpt); - - tr = table.getRow(1); - isRpt = tr.isRepeatHeader(); - assertFalse(isRpt); - - tr = table.getRow(2); - isRpt = tr.isRepeatHeader(); - assertFalse(isRpt); - } - - - // Test that validates the table header value can be parsed from a document - // generated in Word - @Test - public void testIsCantSplit() throws Exception { - XWPFDocument doc = XWPFTestDataSamples - .openSampleDocument("Bug60337.docx"); - XWPFTable table = doc.getTables().get(0); - XWPFTableRow tr = table.getRow(0); - boolean isCantSplit = tr.isCantSplitRow(); - assertFalse(isCantSplit); - - tr = table.getRow(1); - isCantSplit = tr.isCantSplitRow(); - assertFalse(isCantSplit); - - tr = table.getRow(2); - isCantSplit = tr.isCantSplitRow(); - assertTrue(isCantSplit); - } -} diff --git a/trunk/src/records/definitions/area_format_record.xml b/trunk/src/records/definitions/area_format_record.xml deleted file mode 100644 index 3fc2a9c18..000000000 --- a/trunk/src/records/definitions/area_format_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - The area format record is used to define the colours and patterns for an area. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/area_record.xml b/trunk/src/records/definitions/area_record.xml deleted file mode 100644 index 16f04e15f..000000000 --- a/trunk/src/records/definitions/area_record.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - Record - Record - The area record is used to define a area chart. - Glen Stampoultzis (glens at apache.org) - - - - - - - - diff --git a/trunk/src/records/definitions/attached_label_record.xml b/trunk/src/records/definitions/attached_label_record.xml deleted file mode 100644 index e2e59e8e8..000000000 --- a/trunk/src/records/definitions/attached_label_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - The series label record defines the type of label associated with the data format record. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - diff --git a/trunk/src/records/definitions/axes_used_record.xml b/trunk/src/records/definitions/axes_used_record.xml deleted file mode 100644 index cd8cf1065..000000000 --- a/trunk/src/records/definitions/axes_used_record.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - Record - Record - The number of axes used on a chart. - Glen Stampoultzis (glens at apache.org) - - - - diff --git a/trunk/src/records/definitions/axis_line_format_record.xml b/trunk/src/records/definitions/axis_line_format_record.xml deleted file mode 100644 index ff0fc4d39..000000000 --- a/trunk/src/records/definitions/axis_line_format_record.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - Record - Record - The axis line format record defines the axis type details. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - diff --git a/trunk/src/records/definitions/axis_options_record.xml b/trunk/src/records/definitions/axis_options_record.xml deleted file mode 100644 index 0100f6e1a..000000000 --- a/trunk/src/records/definitions/axis_options_record.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - Record - Record - The axis options record provides unit information and other various tidbits about the axis. - Andrew C. Oliver(acoliver at apache.org) - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/axis_parent_record.xml b/trunk/src/records/definitions/axis_parent_record.xml deleted file mode 100644 index 22532a81c..000000000 --- a/trunk/src/records/definitions/axis_parent_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - The axis size and location - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - diff --git a/trunk/src/records/definitions/axis_record.xml b/trunk/src/records/definitions/axis_record.xml deleted file mode 100644 index b03c23f77..000000000 --- a/trunk/src/records/definitions/axis_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - The axis record defines the type of an axis. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/bar_record.xml b/trunk/src/records/definitions/bar_record.xml deleted file mode 100644 index 9fffd79fa..000000000 --- a/trunk/src/records/definitions/bar_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - The bar record is used to define a bar chart. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - diff --git a/trunk/src/records/definitions/category_series_axis_record.xml b/trunk/src/records/definitions/category_series_axis_record.xml deleted file mode 100644 index 94088b5a7..000000000 --- a/trunk/src/records/definitions/category_series_axis_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - This record refers to a category or series axis and is used to specify label/tickmark frequency. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - diff --git a/trunk/src/records/definitions/chart_record.xml b/trunk/src/records/definitions/chart_record.xml deleted file mode 100644 index f1bd8fc9d..000000000 --- a/trunk/src/records/definitions/chart_record.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - Record - Record - The chart record is used to define the location and size of a chart. - Glen Stampoultzis (glens at apache.org) - - - - - - - diff --git a/trunk/src/records/definitions/common_object_data_record.xml b/trunk/src/records/definitions/common_object_data_record.xml deleted file mode 100644 index ad7ebfd18..000000000 --- a/trunk/src/records/definitions/common_object_data_record.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - SubRecord - SubRecord - The common object data record is used to store all common preferences for an excel object. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/dat_record.xml b/trunk/src/records/definitions/dat_record.xml deleted file mode 100644 index bda909ea5..000000000 --- a/trunk/src/records/definitions/dat_record.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - Record - Record - The dat record is used to store options for the chart. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - diff --git a/trunk/src/records/definitions/dataformat_record.xml b/trunk/src/records/definitions/dataformat_record.xml deleted file mode 100644 index 3720e24ff..000000000 --- a/trunk/src/records/definitions/dataformat_record.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - Record - Record - The data format record is used to index into a series. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - diff --git a/trunk/src/records/definitions/default_data_label_text_properties_record.xml b/trunk/src/records/definitions/default_data_label_text_properties_record.xml deleted file mode 100644 index 9a0e755bd..000000000 --- a/trunk/src/records/definitions/default_data_label_text_properties_record.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - Record - Record - The default data label text properties record identifies the text characteristics of the preceeding text record. - Glen Stampoultzis (glens at apache.org) - - - - - - - - diff --git a/trunk/src/records/definitions/font_basis_record.xml b/trunk/src/records/definitions/font_basis_record.xml deleted file mode 100644 index e16b292fe..000000000 --- a/trunk/src/records/definitions/font_basis_record.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - Record - Record - The font basis record stores various font metrics. - Glen Stampoultzis (glens at apache.org) - - - - - - - - diff --git a/trunk/src/records/definitions/font_example.xml b/trunk/src/records/definitions/font_example.xml deleted file mode 100644 index 9bf54470a..000000000 --- a/trunk/src/records/definitions/font_example.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - Record - Record - Describes a font record. In Excel a font belongs in the font table. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/font_index_record.xml b/trunk/src/records/definitions/font_index_record.xml deleted file mode 100644 index bac26e2cb..000000000 --- a/trunk/src/records/definitions/font_index_record.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - Record - Record - The font index record indexes into the font table for the text record. - Glen Stampoultzis (glens at apache.org) - - - - diff --git a/trunk/src/records/definitions/frame_record.xml b/trunk/src/records/definitions/frame_record.xml deleted file mode 100644 index b3b033998..000000000 --- a/trunk/src/records/definitions/frame_record.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Record - Record - The frame record indicates whether there is a border around the displayed text of a chart. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - diff --git a/trunk/src/records/definitions/ftend_record.xml b/trunk/src/records/definitions/ftend_record.xml deleted file mode 100644 index 45f9d59bf..000000000 --- a/trunk/src/records/definitions/ftend_record.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - SubRecord - SubRecord - The end data record is used to denote the end of the subrecords. - Glen Stampoultzis (glens at apache.org) - - - diff --git a/trunk/src/records/definitions/legend_record.xml b/trunk/src/records/definitions/legend_record.xml deleted file mode 100644 index 577443e96..000000000 --- a/trunk/src/records/definitions/legend_record.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - Record - Record - Defines a legend for a chart. - Andrew C. Oliver (acoliver at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 76 0E 00 00 86 07 00 00 19 01 00 00 8B 00 00 00 03 01 1F 00 - - 24 - diff --git a/trunk/src/records/definitions/line_format_record.xml b/trunk/src/records/definitions/line_format_record.xml deleted file mode 100644 index f55679fce..000000000 --- a/trunk/src/records/definitions/line_format_record.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - Record - Record - Describes a line format record. The line format record controls how a line on a chart appears. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/linked_data_record.xml b/trunk/src/records/definitions/linked_data_record.xml deleted file mode 100644 index bd247bd63..000000000 --- a/trunk/src/records/definitions/linked_data_record.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - Record - Record - Describes a linked data record. This record refers to the series data or text. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/number_format_index_record.xml b/trunk/src/records/definitions/number_format_index_record.xml deleted file mode 100644 index 08d5f5c7f..000000000 --- a/trunk/src/records/definitions/number_format_index_record.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - Record - Record - The number format index record indexes format table. This applies to an axis. - Glen Stampoultzis (glens at apache.org) - - - - diff --git a/trunk/src/records/definitions/object_link_record.xml b/trunk/src/records/definitions/object_link_record.xml deleted file mode 100644 index 03848bb8f..000000000 --- a/trunk/src/records/definitions/object_link_record.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - Record - Record - Links text to an object on the chart or identifies it as the title. - Andrew C. Oliver (acoliver at apache.org) - - - - - - - - - - - - - - - - - - 03 00 00 00 00 00 - - 10 - diff --git a/trunk/src/records/definitions/pane_record.xml b/trunk/src/records/definitions/pane_record.xml deleted file mode 100644 index 436443113..000000000 --- a/trunk/src/records/definitions/pane_record.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - Record - Record - Describes the frozen and unfozen panes. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/plot_area_record.xml b/trunk/src/records/definitions/plot_area_record.xml deleted file mode 100644 index 300492a4c..000000000 --- a/trunk/src/records/definitions/plot_area_record.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Record - Record - preceeds and identifies a frame as belonging to the plot area. - Andrew C. Oliver (acoliver at apache.org) - 4 - diff --git a/trunk/src/records/definitions/plotgrowth_record.xml b/trunk/src/records/definitions/plotgrowth_record.xml deleted file mode 100644 index 469b9816b..000000000 --- a/trunk/src/records/definitions/plotgrowth_record.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - Record - Record - The plot growth record specifies the scaling factors used when a font is scaled. - Glen Stampoultzis (glens at apache.org) - - - - - diff --git a/trunk/src/records/definitions/scl_record.xml b/trunk/src/records/definitions/scl_record.xml deleted file mode 100644 index abe21b15b..000000000 --- a/trunk/src/records/definitions/scl_record.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - Record - Record - Specifies the window's zoom magnification. If this record isn't present then the windows zoom is 100%. see p384 Excel Dev Kit - Andrew C. Oliver (acoliver at apache.org) - - - - - diff --git a/trunk/src/records/definitions/series_chart_group_record.xml b/trunk/src/records/definitions/series_chart_group_record.xml deleted file mode 100644 index 84338f144..000000000 --- a/trunk/src/records/definitions/series_chart_group_record.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - Record - Record - The series chart group index record stores the index to the CHARTFORMAT record (0 based). - Glen Stampoultzis (glens at apache.org) - - - - diff --git a/trunk/src/records/definitions/series_index_record.xml b/trunk/src/records/definitions/series_index_record.xml deleted file mode 100644 index a35e01925..000000000 --- a/trunk/src/records/definitions/series_index_record.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - Record - Record - links a series to its position in the series list. - Andrew C. Oliver (acoliver at apache.org) - - - - - - - 03 00 - - 6 - diff --git a/trunk/src/records/definitions/series_list_record.xml b/trunk/src/records/definitions/series_list_record.xml deleted file mode 100644 index 88eeb6704..000000000 --- a/trunk/src/records/definitions/series_list_record.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - Record - Record - The series list record defines the series displayed as an overlay to the main chart record. - Glen Stampoultzis (glens at apache.org) - - - - diff --git a/trunk/src/records/definitions/series_record.xml b/trunk/src/records/definitions/series_record.xml deleted file mode 100644 index e6d516410..000000000 --- a/trunk/src/records/definitions/series_record.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - Record - Record - The series record describes the overall data for a series. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/series_text_record.xml b/trunk/src/records/definitions/series_text_record.xml deleted file mode 100644 index f86aa2da8..000000000 --- a/trunk/src/records/definitions/series_text_record.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - Record - Record - Defines a series name - Andrew C. Oliver (acoliver at apache.org) - - - - - - - - - - - - - - - 00 00 0C 01 56 00 61 00 6C 00 75 00 65 00 20 00 4E 00 75 00 6D 00 62 00 65 00 72 00 - 32 - diff --git a/trunk/src/records/definitions/sertocrt_record.xml b/trunk/src/records/definitions/sertocrt_record.xml deleted file mode 100644 index a904e96c8..000000000 --- a/trunk/src/records/definitions/sertocrt_record.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - Record - Record - Indicates the chart-group index for a series. The order probably defines the mapping. So the 0th record probably means the 0th series. The only field in this of course defines which chart group the 0th series (for instance) would map to. Confusing? Well thats because it is. (p 522 BCG) - Andrew C. Oliver (acoliver at apache.org) - - - - diff --git a/trunk/src/records/definitions/sheet_properties_record.xml b/trunk/src/records/definitions/sheet_properties_record.xml deleted file mode 100644 index 97c5300e7..000000000 --- a/trunk/src/records/definitions/sheet_properties_record.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - Record - Record - Describes a chart sheet properties record. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/subrecord.xsl b/trunk/src/records/definitions/subrecord.xsl deleted file mode 100644 index 01016bc6b..000000000 --- a/trunk/src/records/definitions/subrecord.xsl +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - -package ; - - - -import org.apache.poi.util.*; - -/** - * - * NOTE: This source is automatically generated please do not modify this file. Either subclass or - * remove the record in src/records/definitions. - - */ -public class SubRecord - extends SubRecord -{ - public final static short sid = ; - private ; - - - - public SubRecord() - { - - - = ; - - } - - /** - * Constructs a record and sets its fields appropriately. - * - * @param id id must be or an exception - * will be throw upon validation - * @param size size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - */ - - public SubRecord(short id, short size, byte [] data) - { - super(id, size, data); - - - - = - ; - - - - } - - /** - * Constructs a record and sets its fields appropriately. - * - * @param id id must be or an exception - * will be throw upon validation - * @param size size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - * @param offset of the record's data - */ - - public SubRecord(short id, short size, byte [] data, int offset) - { - super(id, size, data, offset); - - - - = - ; - - - - } - - /** - * Checks the sid matches the expected side for this record - * - * @param id the expected sid. - */ - protected void validateSid(short id) - { - if (id != sid) - { - throw new RecordFormatException("Not a record"); - } - } - - protected void fillFields(byte [] data, short size, int offset) - { - - int pos = 0; - - - - - ; - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[]\n"); - - buffer.append("[/]\n"); - return buffer.toString(); - } - - public int serialize(int offset, byte[] data) - { - int pos = 0; - - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4)); - - - - - - return getRecordSize(); - } - - /** - * Size of record (exluding 4 byte header) - */ - public int getRecordSize() - { - - return 4 - - -; - } - - public short getSid() - { - return this.sid; - } - - public Object clone() { - SubRecord rec = new SubRecord(); - - - ; - - return rec; - } - - - - -} // END OF CLASS - - - - - - - - - /** - * Sets the field value. - * - */ - public void set(boolean value) - { - = .setBoolean(, value); - } - - /** - * - * @return the field value. - */ - public boolean is() - { - return .isSet(); - } - - - /** - * Sets the field value. - * - */ - public void set(short value) - { - = .setValue(, value); - } - - /** - * - * @return the field value. - */ - public short get() - { - return .getShortValue(); - } - - - - - private BitField = new BitField(); - private BitField = new BitField(); - - - public final static = ; - - - - - * - - - /** - * Get the field for the record. - * - * @return One of - */ - public get() - { - return ; - } - - /** - * Set the field for the record. - * - * @param - * One of - */ - public void set( ) - { - this. = ; - } - - - - - - buffer.append(System.getProperty("line.separator")); - - - - - - - buffer.append(" . - - = ").append(is - - ()).append('\n'); - - - buffer.append(" . - - = ").append(get - - ()).append('\n'); - - - - - * @author - - - diff --git a/trunk/src/records/definitions/subrecord_test.xsl b/trunk/src/records/definitions/subrecord_test.xsl deleted file mode 100644 index c729b4130..000000000 --- a/trunk/src/records/definitions/subrecord_test.xsl +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - -package ; - - -import junit.framework.TestCase; - -/** - * Tests the serialization and deserialization of the SubRecord - * class works correctly. Test data taken directly from a real - * Excel file. - * - - */ -public class TestSubRecord - extends TestCase -{ - byte[] data = new byte[] { - - }; - - public TestSubRecord(String name) - { - super(name); - } - - public void testLoad() - throws Exception - { - SubRecord record = new SubRecord((short), (short)data.length, data); - - - - assertEquals( "", record.get()); - - assertEquals( (byte), record.get()); - - assertEquals( (short), record.get()); - - assertEquals( (int), record.get()); - - assertEquals( (double), record.get()); - - - - - assertEquals( , record.getRecordSize() ); - - record.validateSid((short)); - } - - public void testStore() - { - SubRecord record = new SubRecord(); - - - - - record.set( "" ); - - record.set( (byte) ); - - record.set( (short) ); - - record.set( (int) ); - - record.set( (double) ); - - - - - - byte [] recordBytes = record.serialize(); - assertEquals(recordBytes.length - 4, data.length); - for (int i = 0; i < data.length; i++) - assertEquals("At offset " + i, data[i], recordBytes[i+4]); - } -} - - - - * @author - - - - assertEquals( , record.is() ); - - - - - record.set( ); - - - - diff --git a/trunk/src/records/definitions/text_record.xml b/trunk/src/records/definitions/text_record.xml deleted file mode 100644 index c486a7fd9..000000000 --- a/trunk/src/records/definitions/text_record.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - Record - Record - The text record is used to define text stored on a chart. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/textobject_record.xml b/trunk/src/records/definitions/textobject_record.xml deleted file mode 100644 index 8e7e6e83c..000000000 --- a/trunk/src/records/definitions/textobject_record.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - Record - Record - The TXO record is used to define the properties of a text box. It is followed - by two continue records unless there is no actual text. The first continue record contains - the text data and the next continue record contains the formatting runs. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/tick_record.xml b/trunk/src/records/definitions/tick_record.xml deleted file mode 100644 index d1f704a7c..000000000 --- a/trunk/src/records/definitions/tick_record.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - Record - Record - The Tick record defines how tick marks and label positioning/formatting - Andrew C. Oliver(acoliver at apache.org) - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/definitions/units_record.xml b/trunk/src/records/definitions/units_record.xml deleted file mode 100644 index ff281265a..000000000 --- a/trunk/src/records/definitions/units_record.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - Record - Record - The units record describes units. - Glen Stampoultzis (glens at apache.org) - - - - diff --git a/trunk/src/records/definitions/value_range_record.xml b/trunk/src/records/definitions/value_range_record.xml deleted file mode 100644 index c5be1d819..000000000 --- a/trunk/src/records/definitions/value_range_record.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - Record - Record - The value range record defines the range of the value axis. - Glen Stampoultzis (glens at apache.org) - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/records/styles/record.xsl b/trunk/src/records/styles/record.xsl deleted file mode 100644 index dae346b5d..000000000 --- a/trunk/src/records/styles/record.xsl +++ /dev/null @@ -1,570 +0,0 @@ -<<<<<<< record.xsl - - - - - - - -package ; - - - -import org.apache.poi.util.*; - -/** - * - * NOTE: This source is automatically generated please do not modify this file. Either subclass or - * remove the record in src/records/definitions. - - */ -public class Record - extends Record -{ - public final static short sid = ; - private ; - - - - public Record() - { - - - = ; - - } - - /** - * Constructs a record and sets its fields appropriately. - * - * @param id id must be or an exception - * will be throw upon validation - * @param size size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - */ - - public Record(RecordInputStream in) - { - super(in); - - - - = - ; - - - - } - - /** - * Checks the sid matches the expected side for this record - * - * @param id the expected sid. - */ - protected void validateSid(short id) - { - if (id != sid) - { - throw new RecordFormatException("Not a record"); - } - } - - protected void fillFields(RecordInputStream in) - { - - int pos = 0; - - - - - ; - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[]\n"); - - buffer.append("[/]\n"); - return buffer.toString(); - } - - public int serialize(int offset, byte[] data) - { - int pos = 0; - - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4)); - - - - - - return getRecordSize(); - } - - /** - * Size of record (exluding 4 byte header) - */ - public int getRecordSize() - { - - return 4 - - -; - } - - public short getSid() - { - return this.sid; - } - - public Object clone() { - Record rec = new Record(); - - - ; - - return rec; - } - - - - - - -} // END OF CLASS - - - - - - - - - - - /** - * Sets the field value. - * - */ - public void set(boolean value) - { - = .setBoolean(, value); - } - - /** - * - * @return the field value. - */ - public boolean is() - { - return .isSet(); - } - - - /** - * Sets the field value. - * - */ - public void set(short value) - { - = .setValue(, value); - } - - /** - * - * @return the field value. - */ - public short get() - { - return .getShortValue(); - } - - - - - private BitField = new BitField(); - private BitField = new BitField(); - - - public final static = ; - - - - - * - - - /** - * Get the field for the record. - * - * @return One of - */ - public get() - { - return ; - } - - /** - * Set the field for the record. - * - * @param - * One of - */ - public void set( ) - { - this. = ; - } - - - - - - buffer.append(System.getProperty("line.separator")); - - - - - - - buffer.append(" . - - = ").append(is - - ()).append('\n'); - - - buffer.append(" . - - = ").append(get - - ()).append('\n'); - - - - - * @author - - - -======= - - - - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package ; - - - -import org.apache.poi.util.*; - -/** - * - * NOTE: This source is automatically generated please do not modify this file. Either subclass or - * remove the record in src/records/definitions. - - */ -public class Record - extends Record -{ - public final static short sid = ; - private ; - - - - public Record() - { - - - = ; - - } - - /** - * Constructs a record and sets its fields appropriately. - * - * @param id id must be or an exception - * will be throw upon validation - * @param size size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - */ - - public Record(short id, short size, byte [] data) - { - super(id, size, data); - - - - = - ; - - - - } - - /** - * Constructs a record and sets its fields appropriately. - * - * @param id id must be or an exception - * will be throw upon validation - * @param size size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - * @param offset of the record's data - */ - - public Record(short id, short size, byte [] data, int offset) - { - super(id, size, data, offset); - - - - = - ; - - - - } - - /** - * Checks the sid matches the expected side for this record - * - * @param id the expected sid. - */ - protected void validateSid(short id) - { - if (id != sid) - { - throw new RecordFormatException("Not a record"); - } - } - - protected void fillFields(byte [] data, short size, int offset) - { - - int pos = 0; - - - - - ; - - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[]\n"); - - buffer.append("[/]\n"); - return buffer.toString(); - } - - public int serialize(int offset, byte[] data) - { - int pos = 0; - - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4)); - - - - - - return getRecordSize(); - } - - /** - * Size of record (exluding 4 byte header) - */ - public int getRecordSize() - { - - return 4 - - -; - } - - public short getSid() - { - return this.sid; - } - - public Object clone() { - Record rec = new Record(); - - - ; - - return rec; - } - - - - - - -} // END OF CLASS - - - - - - - - - - - /** - * Sets the field value. - * - */ - public void set(boolean value) - { - = .setBoolean(, value); - } - - /** - * - * @return the field value. - */ - public boolean is() - { - return .isSet(); - } - - - /** - * Sets the field value. - * - */ - public void set(short value) - { - = .setValue(, value); - } - - /** - * - * @return the field value. - */ - public short get() - { - return .getShortValue(); - } - - - - - private BitField = new BitField(); - private BitField = new BitField(); - - - public final static = ; - - - - - * - - - /** - * Get the field for the record. - * - * @return One of - */ - public get() - { - return ; - } - - /** - * Set the field for the record. - * - * @param - * One of - */ - public void set( ) - { - this. = ; - } - - - - - - buffer.append(System.getProperty("line.separator")); - - - - - - - buffer.append(" . - - = ").append(is - - ()).append('\n'); - - - buffer.append(" . - - = ").append(get - - ()).append('\n'); - - - - - * @author - - - ->>>>>>> 1.11 diff --git a/trunk/src/records/styles/record_document.xsl b/trunk/src/records/styles/record_document.xsl deleted file mode 100644 index 7895c661b..000000000 --- a/trunk/src/records/styles/record_document.xsl +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - -

        - <xsl:value-of select="@name"/> Record Documentation -
        - - - -

        -

        -
        - - - - - - - - - - -
        NameSizeOffsetDescriptionDefault Value
        -
        - -
        - - Copyright (c) @year@ The Poi Project All rights reserved. - -
        - - - - - - - - - - - - - - - diff --git a/trunk/src/records/styles/record_test.xsl b/trunk/src/records/styles/record_test.xsl deleted file mode 100644 index a70a9491b..000000000 --- a/trunk/src/records/styles/record_test.xsl +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - -package ; - - -import junit.framework.TestCase; - -/** - * Tests the serialization and deserialization of the Record - * class works correctly. Test data taken directly from a real - * Excel file. - * - - */ -public class TestRecord - extends TestCase -{ - byte[] data = new byte[] { - - }; - - public TestRecord(String name) - { - super(name); - } - - public void testLoad() - throws Exception - { - Record record = new Record((short), (short)data.length, data); - - - - assertEquals( "", record.get()); - - assertEquals( (byte), record.get()); - - assertEquals( (short), record.get()); - - assertEquals( (int), record.get()); - - assertEquals( (double), record.get()); - - - - - assertEquals( , record.getRecordSize() ); - - record.validateSid((short)); - } - - public void testStore() - { - Record record = new Record(); - - - - - record.set( "" ); - - record.set( (byte) ); - - record.set( (short) ); - - record.set( (int) ); - - record.set( (double) ); - - - - - - byte [] recordBytes = record.serialize(); - assertEquals(recordBytes.length - 4, data.length); - for (int i = 0; i < data.length; i++) - assertEquals("At offset " + i, data[i], recordBytes[i+4]); - } -} - - - - * @author - - - - assertEquals( , record.is() ); - - - - - record.set( ); - - - - diff --git a/trunk/src/resources/devtools/complete-log4j.properties b/trunk/src/resources/devtools/complete-log4j.properties deleted file mode 100644 index 0959ec27d..000000000 --- a/trunk/src/resources/devtools/complete-log4j.properties +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#log4j.rootCategory=debug, globalLog -log4j.category.org.apache.poi.hssf=debug, hssfLog -log4j.category.org.apache.poi.hdf=debug, hdfLog -log4j.category.org.apache.poi.hpsf=debug, hpsfLog -log4j.category.org.apache.poi.poifs=debug, poifsLog -log4j.category.org.apache.poi.util=debug, utilLog - -log4j.appender.hssfLog=org.apache.log4j.FileAppender -log4j.appender.hssfLog.File=build/hssf.log -log4j.appender.hssfLog.layout=org.apache.log4j.PatternLayout -log4j.appender.hssfLog.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n - -log4j.appender.hdfLog=org.apache.log4j.FileAppender -log4j.appender.hdfLog.File=build/hdf.log -log4j.appender.hdfLog.layout=org.apache.log4j.PatternLayout -log4j.appender.hdfLog.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n - -log4j.appender.hpsfLog=org.apache.log4j.FileAppender -log4j.appender.hpsfLog.File=build/hpsf.log -log4j.appender.hpsfLog.layout=org.apache.log4j.PatternLayout -log4j.appender.hpsfLog.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n - -log4j.appender.poifsLog=org.apache.log4j.FileAppender -log4j.appender.poifsLog.File=build/poifs.log -log4j.appender.poifsLog.layout=org.apache.log4j.PatternLayout -log4j.appender.poifsLog.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n - -log4j.appender.utilLog=org.apache.log4j.FileAppender -log4j.appender.utilLog.File=build/util.log -log4j.appender.utilLog.layout=org.apache.log4j.PatternLayout -log4j.appender.utilLog.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n diff --git a/trunk/src/resources/devtools/fatal-only-log4j.properties b/trunk/src/resources/devtools/fatal-only-log4j.properties deleted file mode 100644 index c1e023ae6..000000000 --- a/trunk/src/resources/devtools/fatal-only-log4j.properties +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Set root logger level to FATAL and its only appender to stdout -log4j.rootLogger=FATAL, stdout -log4j.category.org=FATAL, stdout - -# stdout is set to be a ConsoleAppender. -log4j.appender.stdout=org.apache.log4j.ConsoleAppender - -# stdout uses PatternLayout. -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n - - diff --git a/trunk/src/resources/devtools/findbugs-filters.xml b/trunk/src/resources/devtools/findbugs-filters.xml deleted file mode 100644 index 98c2ffb1c..000000000 --- a/trunk/src/resources/devtools/findbugs-filters.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/resources/devtools/forbidden-signatures-prod.txt b/trunk/src/resources/devtools/forbidden-signatures-prod.txt deleted file mode 100644 index 59dcf4789..000000000 --- a/trunk/src/resources/devtools/forbidden-signatures-prod.txt +++ /dev/null @@ -1,32 +0,0 @@ -# (C) Copyright Uwe Schindler (Generics Policeman) and others. -# Parts of this work are licensed to the Apache Software Foundation (ASF) -# under one or more contributor license agreements. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# This file contains API signatures which are specific to POI. -# The goal is to minimize implicit defaults - -@defaultMessage POI forbidden APIs which are tolerated in non-production code, e.g. in tests and examples - -# We have applications which use this to return error codes on invalid commandline parameters... -#@defaultMessage Please do not terminate the application -#java.lang.System#exit(int) -#java.lang.Runtime#exit(int) -#java.lang.Runtime#halt(int) - - -java.lang.System#gc() @ Please do not try to stop the world -java.lang.Throwable#printStackTrace() @ Please use POILogger for exceptions -java.lang.Throwable#printStackTrace(java.io.PrintStream) @ Please use POILogger for exceptions -java.lang.Throwable#printStackTrace(java.io.PrintWriter) @ Please use POILogger for exceptions \ No newline at end of file diff --git a/trunk/src/resources/devtools/forbidden-signatures.txt b/trunk/src/resources/devtools/forbidden-signatures.txt deleted file mode 100644 index 54b285678..000000000 --- a/trunk/src/resources/devtools/forbidden-signatures.txt +++ /dev/null @@ -1,111 +0,0 @@ -# (C) Copyright Uwe Schindler (Generics Policeman) and others. -# Parts of this work are licensed to the Apache Software Foundation (ASF) -# under one or more contributor license agreements. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# This file contains API signatures which are specific to POI. -# The goal is to minimize implicit defaults - -@ignoreUnresolvable -@defaultMessage POI forbidden APIs - -# Locale related interfaces which we want to avoid to not have code which depends on the locale of the current machine -java.util.Locale#getDefault() @ Do not use methods that depend on the current Local, either use Locale.ROOT or let the user define the local, see class LocaleUtil for details -java.util.Locale#setDefault(java.util.Locale) @ Do not use methods that depend on the current Local, either use Locale.ROOT or let the user define the local, see class LocaleUtil for details -java.util.TimeZone#getDefault() @ Do not use methods that depend on the current Local, either use Locale.ROOT or let the user define the local, see class LocaleUtil for details -java.util.Date#toString() @ Do not use methods that depend on the current Local, either use Locale.ROOT or let the user define the local, see class LocaleUtil for details - -java.text.DecimalFormatSymbols#() @ use DecimalFormatSymbols.getInstance() -java.text.DecimalFormatSymbols#(java.util.Locale) @ use DecimalFormatSymbols.getInstance() - -# the following are taken from the Elasticsearch source at https://github.com/elastic/elasticsearch/tree/master/buildSrc/src/main/resources/forbidden - -@defaultMessage Convert to URI -java.net.URL#getPath() -java.net.URL#getFile() - -@defaultMessage Usage of getLocalHost is discouraged -java.net.InetAddress#getLocalHost() - -@defaultMessage Specify a location for the temp file/directory instead. -java.nio.file.Files#createTempDirectory(java.lang.String,java.nio.file.attribute.FileAttribute[]) -java.nio.file.Files#createTempFile(java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute[]) - -@defaultMessage Specify a location for the temp file/directory instead. -java.nio.file.Files#createTempDirectory(java.lang.String,java.nio.file.attribute.FileAttribute[]) -java.nio.file.Files#createTempFile(java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute[]) - -@defaultMessage Don't use java serialization - this can break BWC without noticing it -java.io.ObjectOutputStream -java.io.ObjectOutput -java.io.ObjectInputStream -java.io.ObjectInput - -@defaultMessage Resolve hosts explicitly to the address(es) you want with InetAddress. -java.net.InetSocketAddress#(java.lang.String,int) -java.net.Socket#(java.lang.String,int) -java.net.Socket#(java.lang.String,int,java.net.InetAddress,int) - -@defaultMessage Don't bind to wildcard addresses. Be specific. -java.net.DatagramSocket#() -java.net.DatagramSocket#(int) -java.net.InetSocketAddress#(int) -java.net.MulticastSocket#() -java.net.MulticastSocket#(int) -java.net.ServerSocket#(int) -java.net.ServerSocket#(int,int) - -@defaultMessage use NetworkAddress format/formatAddress to print IP or IP+ports -java.net.InetAddress#toString() -java.net.InetAddress#getHostAddress() -java.net.Inet4Address#getHostAddress() -java.net.Inet6Address#getHostAddress() -java.net.InetSocketAddress#toString() - -@defaultMessage avoid DNS lookups by accident: if you have a valid reason, then @SuppressWarnings with that reason so its completely clear -java.net.InetAddress#getHostName() -java.net.InetAddress#getCanonicalHostName() - -java.net.InetSocketAddress#getHostName() @ Use getHostString() instead, which avoids a DNS lookup - -@defaultMessage this method needs special permission -java.lang.Thread#getAllStackTraces() - -@defaultMessage Avoid unchecked warnings by using Collections#empty(List|Map|Set) methods -java.util.Collections#EMPTY_LIST -java.util.Collections#EMPTY_MAP -java.util.Collections#EMPTY_SET - - -@defaultMessage spawns threads with vague names; use a custom thread factory and name threads so that you can tell (by its name) which executor it is associated with -java.util.concurrent.Executors#newFixedThreadPool(int) -java.util.concurrent.Executors#newSingleThreadExecutor() -java.util.concurrent.Executors#newCachedThreadPool() -java.util.concurrent.Executors#newSingleThreadScheduledExecutor() -java.util.concurrent.Executors#newScheduledThreadPool(int) -java.util.concurrent.Executors#defaultThreadFactory() -java.util.concurrent.Executors#privilegedThreadFactory() - -java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars -java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars - -@defaultMessage Only use wait / notify when really needed try to use concurrency primitives, latches or callbacks instead. -java.lang.Object#wait() -java.lang.Object#wait(long) -java.lang.Object#wait(long,int) -java.lang.Object#notify() -java.lang.Object#notifyAll() - -@defaultMessage Don't interrupt threads use FutureUtils#cancel(Future) instead -java.util.concurrent.Future#cancel(boolean) diff --git a/trunk/src/resources/devtools/poi.jin b/trunk/src/resources/devtools/poi.jin deleted file mode 100644 index c52acef80..000000000 --- a/trunk/src/resources/devtools/poi.jin +++ /dev/null @@ -1,284 +0,0 @@ -### -### Jindent 3.2x property file -- http://www.jindent.de -### -### this encapsulates my preferred style, plus project-specific style ... -### -### author: Marc Johnson -### - -### General -- Convention - -conventionName = "" -conventionString = "" -conventionNotePosition = "none" -blankLinesToSeparateConventionNote = 2 - -### General -- Jindent Note - -jindentNotePosition = "none" -blankLinesToSeparateJindentNote = 2 - -### Header/Footer -- Header Template - -headerSmartMode = infinite -headerIdentifyKey = "Copyright (c) 2002-2006 The Apache Software Foundation" -blankLinesBeforeHeader = 1 -header[00]="/* ===================================================================" -header[01]=" * Licensed to the Apache Software Foundation (ASF) under one" -header[02]=" * or more contributor license agreements. See the NOTICE file" -header[03]=" * distributed with this work for additional information" -header[04]=" * regarding copyright ownership. The ASF licenses this file" -header[05]=" * to you under the Apache License, Version 2.0 (the" -header[06]=" * \"License\"); you may not use this file except in compliance" -header[07]=" * with the License. You may obtain a copy of the License at" -header[08]=" * " -header[09]=" * http://www.apache.org/licenses/LICENSE-2.0" -header[10]=" * " -header[11]=" * Unless required by applicable law or agreed to in writing," -header[12]=" * software distributed under the License is distributed on an" -header[13]=" * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY" -header[14]=" * KIND, either express or implied. See the License for the" -header[15]=" * specific language governing permissions and limitations" -header[16]=" * under the License" -header[17]=" */" -blankLinesAfterHeader = 1 - -### Header/Footer -- Footer Template - -footerSmartMode = infinite -footerIdentifyKey = "" -blankLinesBeforeFooter = 0 -footer[00] = "" -blankLinesAfterFooter = 0 - -### Indentation -- Misc - -tabulatorSize = 8 -indentSize = 4 -firstLevelIndent = 0 -indentCaseFromSwitch = true -labelNewLine = true -indentLabels = true -minimumCommentIndent = 3 -indentLeadingsByTabs = false -indentCommentsByTabs = false -indentDeclarationsByTabs = false -indentAssignmentsByTabs = false - -### Indentation -- Alignment - -alignComments = true -alignDeclarations = true -alignAssignments = true -alignTernaryConditions = false -alignTernaryExpressions = true -alignTooLongComments = true - -### Braces -- Style - -leftBraceNewLineGeneral = true -rightBraceNewLineGeneral = true -indentLeftBraceGeneral = 0 -indentRightBraceGeneral = 0 -indentAfterRightBraceGeneral = 0 -cuddleEmptyBracesGeneral = false -indentCuddledBracesGeneral = 0 - -leftBraceNewLineClassInterface = true -rightBraceNewLineClassInterface = true -indentLeftBraceClassInterface = 0 -indentRightBraceClassInterface = 0 -indentAfterRightBraceClassInterface = 0 -cuddleEmptyBracesClassInterface = false -indentCuddledBracesClassInterface = 0 - -leftBraceNewLineMethod = true -rightBraceNewLineMethod = true -indentLeftBraceMethod = 0 -indentRightBraceMethod = 0 -indentAfterRightBraceMethod = 0 -cuddleEmptyBracesMethod = false -indentCuddledBracesMethod = 0 - -leftBraceNewLineTryCatch = true -rightBraceNewLineTryCatch = true -indentLeftBraceTryCatch = 0 -indentRightBraceTryCatch = 0 -indentAfterRightBraceTryCatch = 0 -cuddleEmptyBracesTryCatch = false -indentCuddledBracesTryCatch = 0 - -### Braces -- Insert At - -insertBracesAtIfElse = true -insertBracesAtFor = true -insertBracesAtWhile = true -insertBracesAtDoWhile = true -insertParenthesisAtConditions = true - -### Braces -- If-Else - -singleIfStatementInOneLine = false -singleElseStatementInOneLine = false -specialElseIfTreatment = true - -### JavaDoc -- Misc - -deleteJavaDocComments = false -formatJavaDocComments = true -insertMissingJavaDocTags = true -deleteObsoleteJavaDocTags = false -createPublicClassInterfaceJavaDocs = true -createFriendlyClassInterfaceJavaDocs = false -createPrivateClassInterfaceJavaDocs = false -createProtectedClassInterfaceJavaDocs = false -createPublicMethodJavaDocs = false -createFriendlyMethodJavaDocs = false -createPrivateMethodJavaDocs = false -createProtectedMethodJavaDocs = false -createPublicFieldJavaDocs = false -createFriendlyFieldJavaDocs = false -createPrivateFieldJavaDocs = false -createProtectedFieldJavaDocs = false - -### JavaDoc -- Templates - -sortExceptionsInTemplates = true -javaDocMethodTop[00] = "/**" -javaDocMethodTop[01] = " * Method $objectName$" -javaDocMethodTop[02] = " *" -javaDocMethodParamSeparator[00] = " *" -javaDocMethodParam[00] = " * @param $paramName$" -javaDocMethodReturn[00] = " *" -javaDocMethodReturn[01] = " * @return" -javaDocMethodExceptionSeparator[00] = " *" -javaDocMethodException[00] = " * @exception $exceptionName$" -javaDocMethodBottom[00] = " *" -javaDocMethodBottom[01] = " */" -javaDocConstructorTop[00] = "/**" -javaDocConstructorTop[01] = " * Constructor $objectName$" -javaDocConstructorTop[02] = " *" -javaDocConstructorParamSeparator[00] = " *" -javaDocConstructorParam[00] = " * @param $paramName$" -javaDocConstructorExceptionSeparator[00] = " *" -javaDocConstructorException[00] = " * @exception $exceptionName$" -javaDocConstructorBottom[00] = " *" -javaDocConstructorBottom[01] = " */" -javaDocClass[00] = "/**" -javaDocClass[01] = " * Class $objectName$" -javaDocClass[02] = " *" -javaDocClass[03] = " *" -javaDocClass[04] = " * @author" -javaDocClass[05] = " * @version %I%, %G%" -javaDocClass[06] = " */" -javaDocInterface[00] = "/**" -javaDocInterface[01] = " * Interface $objectName$" -javaDocInterface[02] = " *" -javaDocInterface[03] = " *" -javaDocInterface[04] = " * @author" -javaDocInterface[05] = " * @version %I%, %G%" -javaDocInterface[06] = " */" -javaDocField[00] = "/** Field $objectName$ */" - -### Comments -- Format/Delete - -deleteBlockComments = false -deleteSingleLineComments = false -deleteTrailingComments = false -deleteEndOfLineComments = false -formatBlockComments = true -formatSingleLineComments = true -formatTrailingComments = true -formatEndOfLineComments = true - -### Comments -- Exceptions - -neverIndentFirstColumnComments = true -neverFormatFirstColumnComments = true -neverFormatHeader = false -neverFormatFooter = false - -### Separation -- Misc - -keepBlankLines = 0 -minLinesToInsertBlankLineInClasses = infinite -minLinesToInsertBlankLineInMethods = infinite - -### Separation -- Separate - -separateChunksByComments = false -allowBreakSeparatedFromCaseBlock = false -blankLinesBetweenCaseBlocks = 1 -blankLinesBetweenChunks = 0 -comparableImportDepth = 2 -blankLinesToSeparateImports = 1 -blankLinesBetweenClassInterface = 2 - -### Separation -- Insert Blank Lines - -blankLinesAfterDeclarations = 1 -blankLinesAfterMethods = 1 -blankLinesAfterClasses = 1 -blankLinesAfterInterfaces = 1 -blankLinesBeforeJavaDocComments = 1 -blankLinesAfterJavaDocComments = 1 -blankLinesBeforeBlockComments = 1 -blankLinesAfterBlockComments = 0 -blankLinesBeforeSingleLineComments = 1 -blankLinesAfterSingleLineComments = 0 -blankLinesBeforeEndOfLineComments = 1 -blankLinesAfterEndOfLineComments = 0 -blankLinesAfterSwitch = 1 -blankLinesAfterPackage = 1 -blankLinesAfterLastImport = 1 - -### Whitespaces -- Padding - -separateAssignmentOperators = true -separateConditionalOperators = true -separateComparisonOperators = true -separateNumericalOperators = true -paddingCastParenthesis = true -paddingParenthesis = false -paddingBrackets = true -paddingBraces = true - -### Whitespaces -- Space Before - -spaceBeforeMethodDeclarationParenthesis = false -spaceBeforeMethodCallParenthesis = false -spaceBeforeBrackets = false -spaceBeforeBracketsInTypes = true -spaceBeforeStatementParenthesis = true -spaceBeforeConditionBang = true -spaceBeforeCaseColon = true - -### Whitespaces -- Space After - -spaceAfterComma = true -spaceAfterSemicolon = true -spaceAfterCasting = true - -### Whitespaces -- No Spaces - -noSpacesInEmptyForExpressions = true - -### Line Wrapping -- Misc - -maxFieldElementsPerLine = 0 -wrapLines = true -wrapBecauseOfComments = true -wrapLongMethodNames = true -maxLineLength = 78 -deepIndent = 45 -forceIndent = 8 -forceIndentTolerance = 4 -allowWrappingAfterAssignments = true -allowWrappingAfterParenthesis = true -preferWrappingAfterThrows = true -alwaysWrapThrows = true -alwaysWrapExtends = true -alwaysWrapImplements = true -indentWrappedThrows = 4 -indentWrappedExtends = 4 -indentWrappedImplements = 4 diff --git a/trunk/src/resources/devtools/unpack_ooxml.sh b/trunk/src/resources/devtools/unpack_ooxml.sh deleted file mode 100755 index a4b8703a8..000000000 --- a/trunk/src/resources/devtools/unpack_ooxml.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -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. - -# basename it - -FILENAME="$1" -BASENAME="${FILENAME##*/}" -OUTDIR="${BASENAME%.*}" - -if [ ! -f "$FILENAME" ]; then - echo "File $FILENAME does not exist" - exit 1 -fi - -# if dir exists, fail -if [ -d "$OUTDIR" ]; then - echo "Directory '$OUTDIR' already exists!" - exit 1 -fi - -mkdir "$OUTDIR" -unzip -d "$OUTDIR" "$FILENAME" - -pushd "$OUTDIR" - -find . -type f \( -iname "*.xml" -or -iname "*.rels" \) -exec python -c "import os, sys, xml.dom.minidom -with open('{}', 'r') as fp: - s = fp.read() -with open('{}.bak', 'w') as fp: - fp.write(xml.dom.minidom.parseString(s).toprettyxml().encode('utf-8')) -os.rename('{}.bak', '{}')" \; diff --git a/trunk/src/resources/logos/logoKarmokar4.png b/trunk/src/resources/logos/logoKarmokar4.png deleted file mode 100644 index 90a915a3a..000000000 Binary files a/trunk/src/resources/logos/logoKarmokar4.png and /dev/null differ diff --git a/trunk/src/resources/logos/logoKarmokar4edited.png b/trunk/src/resources/logos/logoKarmokar4edited.png deleted file mode 100644 index 73c02a560..000000000 Binary files a/trunk/src/resources/logos/logoKarmokar4edited.png and /dev/null differ diff --git a/trunk/src/resources/logos/logoKarmokar4s.png b/trunk/src/resources/logos/logoKarmokar4s.png deleted file mode 100644 index 33391cd96..000000000 Binary files a/trunk/src/resources/logos/logoKarmokar4s.png and /dev/null differ diff --git a/trunk/src/resources/logos/logoKarmokar5.png b/trunk/src/resources/logos/logoKarmokar5.png deleted file mode 100644 index e2d1f3f85..000000000 Binary files a/trunk/src/resources/logos/logoKarmokar5.png and /dev/null differ diff --git a/trunk/src/resources/logos/project-alt-logo.jpg b/trunk/src/resources/logos/project-alt-logo.jpg deleted file mode 100644 index 073175151..000000000 Binary files a/trunk/src/resources/logos/project-alt-logo.jpg and /dev/null differ diff --git a/trunk/src/resources/logos/project-feather-logo.jpg b/trunk/src/resources/logos/project-feather-logo.jpg deleted file mode 100644 index 24c9e06dd..000000000 Binary files a/trunk/src/resources/logos/project-feather-logo.jpg and /dev/null differ diff --git a/trunk/src/resources/main/font_metrics.properties b/trunk/src/resources/main/font_metrics.properties deleted file mode 100644 index e521b0c51..000000000 --- a/trunk/src/resources/main/font_metrics.properties +++ /dev/null @@ -1,927 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#Font Metrics -#Sun Sep 07 21:54:47 EST 2003 -font.Lucida\ Sans\ Demibold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Medium\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Jokerman.height=16 -font.Harrington.height=13 -font.Curlz\ MT.height=14 -font.Garamond\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Wide\ Latin.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Colonna\ MT.widths=5, 6, 5, 6, 6, 4, 7, 6, 4, 4, 6, 4, 9, 6, 6, 6, 6, 5, 5, 5, 6, 6, 8, 6, 6, 5, 8, 6, 7, 8, 6, 6, 7, 8, 4, 4, 7, 6, 9, 9, 7, 7, 7, 8, 5, 7, 8, 7, 9, 7, 8, 6, 6, 4, 5, 5, 6, 5, 6, 5, 5, 6, -font.Gill\ Sans\ MT\ Ext\ Condensed\ Bold.height=12 -font.Beesknees\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Freestyle\ Script.height=13 -font.Palace\ Script\ MT.widths=4, 3, 3, 4, 3, 3, 4, 4, 3, 3, 4, 3, 6, 4, 3, 4, 3, 3, 3, 3, 4, 4, 5, 4, 4, 3, 8, 8, 6, 8, 5, 7, 6, 8, 6, 6, 8, 7, 8, 7, 5, 7, 6, 8, 6, 7, 5, 5, 6, 7, 5, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -font.Lucida\ Sans\ Demibold\ Roman.height=14 -font.Franklin\ Gothic\ Book\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Serif.widths=7, 7, 6, 7, 6, 4, 7, 7, 5, 5, 8, 5, 11, 7, 6, 6, 7, 6, 6, 5, 7, 6, 9, 6, 6, 6, 8, 9, 8, 9, 8, 8, 8, 10, 5, 5, 9, 7, 11, 9, 9, 8, 9, 8, 7, 7, 9, 7, 10, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bitstream\ Vera\ Sans\ Mono.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Matisse\ ITC.height=14 -font.Arial\ Special\ G2\ Bold\ Italic.height=14 -font.Lucida\ Fax\ Demibold.height=14 -font.Arial\ Special\ G1\ Bold\ Italic.height=14 -font.Tempus\ Sans\ ITC.height=14 -font.Impact.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Algerian.widths=9, 7, 7, 7, 7, 7, 8, 7, 4, 6, 8, 6, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 8, 7, 7, 9, 7, 7, 7, 7, 7, 8, 7, 4, 6, 8, 6, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Gill\ Sans\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Special\ G1\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.OCR\ A\ Extended.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Cooper\ Black.widths=7, 7, 6, 8, 6, 5, 7, 8, 6, 6, 8, 6, 11, 8, 7, 8, 7, 6, 6, 6, 8, 7, 11, 7, 7, 6, 9, 8, 8, 9, 8, 8, 9, 9, 4, 7, 9, 7, 10, 9, 9, 8, 9, 9, 7, 8, 9, 9, 11, 9, 9, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Century\ Gothic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bauhaus\ 93.widths=7, 7, 7, 7, 7, 4, 7, 6, 4, 5, 6, 4, 9, 6, 7, 7, 7, 4, 5, 4, 6, 5, 9, 6, 6, 6, 7, 7, 9, 8, 6, 6, 7, 7, 4, 4, 7, 4, 9, 7, 9, 7, 9, 7, 5, 6, 7, 6, 9, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bernard\ MT\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Old\ English\ Text\ MT.widths=5, 5, 4, 5, 4, 3, 5, 5, 3, 3, 6, 3, 7, 5, 5, 5, 5, 4, 5, 3, 5, 5, 7, 6, 5, 4, 9, 10, 10, 10, 10, 10, 9, 10, 8, 8, 10, 9, 12, 11, 10, 10, 10, 9, 10, 9, 11, 9, 10, 8, 9, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Century\ Schoolbook.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Fax\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Rounded\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Informal\ Roman.widths=5, 5, 4, 6, 5, 4, 5, 5, 3, 3, 5, 3, 7, 5, 4, 5, 5, 5, 4, 4, 5, 5, 7, 5, 5, 6, 7, 7, 6, 7, 6, 6, 7, 7, 4, 6, 6, 6, 8, 7, 6, 6, 6, 6, 5, 7, 7, 7, 9, 7, 7, 7, 5, 4, 6, 6, 6, 7, 6, 6, 6, 6, -font.Lucida\ Sans\ Demibold.height=14 -font.Ravie.height=14 -font.Perpetua.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.MT\ Extra.height=13 -font.Bitstream\ Vera\ Sans\ Mono\ Bold\ Oblique.height=14 -font.Book\ Antiqua\ Bold\ Italic.height=14 -font.Eras\ Medium\ ITC.height=12 -font.Rockwell\ Bold.height=14 -font.Snap\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.dialog.italic.widths=7, 7, 6, 7, 7, 4, 7, 7, 4, 3, 6, 4, 8, 7, 7, 7, 7, 4, 6, 4, 7, 6, 9, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 3, 6, 8, 7, 9, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Century\ Gothic\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Demi\ Italic.height=14 -font.Franklin\ Gothic\ Book.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G1\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Desdemona.height=12 -font.Franklin\ Gothic\ Demi\ Cond.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Wingdings\ 3.height=13 -font.High\ Tower\ Text.height=13 -font.Edwardian\ Script\ ITC.widths=4, 4, 3, 4, 3, 2, 4, 4, 3, 3, 4, 3, 6, 5, 4, 4, 4, 4, 3, 3, 4, 4, 5, 4, 4, 4, 10, 10, 9, 9, 9, 8, 8, 10, 7, 7, 10, 9, 11, 10, 9, 9, 8, 10, 8, 7, 10, 8, 10, 11, 10, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Gigi.widths=6, 5, 5, 5, 6, 5, 6, 5, 5, 4, 6, 6, 9, 6, 4, 6, 5, 5, 4, 5, 6, 5, 8, 6, 6, 4, 10, 8, 7, 10, 5, 9, 7, 9, 6, 6, 9, 8, 11, 9, 6, 8, 8, 7, 6, 7, 8, 9, 13, 9, 9, 7, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, -font.Engravers\ MT.height=13 -font.Californian\ FB\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Calligraphy\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G1\ Italic.height=14 -font.Book\ Antiqua\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Heavy.widths=7, 7, 6, 7, 7, 5, 7, 7, 4, 4, 7, 4, 10, 7, 7, 7, 7, 5, 6, 5, 7, 6, 8, 7, 6, 6, 7, 7, 7, 8, 7, 6, 8, 8, 4, 5, 8, 6, 9, 8, 8, 7, 8, 8, 7, 6, 8, 7, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Typewriter\ Regular.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Ransom\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.High\ Tower\ Text\ Italic.height=14 -font.dialog.bold.height=14 -font.Times\ New\ Roman\ Special\ G2\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Trebuchet\ MS\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G1\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ Ultra\ Bold\ Condensed.widths=5, 5, 4, 5, 5, 4, 5, 5, 3, 3, 5, 3, 8, 5, 5, 5, 5, 5, 4, 4, 5, 5, 7, 6, 5, 4, 7, 6, 5, 6, 5, 5, 6, 7, 3, 4, 6, 5, 7, 6, 6, 6, 6, 6, 5, 5, 6, 6, 8, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Monotype\ Sorts\ 2.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Condensed.height=13 -font.Bell\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G2\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G1\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Gill\ Sans\ Ultra\ Bold.height=13 -font.American\ Uncial.height=13 -font.Kino\ MT.widths=5, 5, 5, 5, 5, 4, 5, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 4, 4, 4, 5, 5, 7, 4, 5, 4, 6, 5, 6, 6, 5, 5, 6, 6, 4, 5, 5, 5, 8, 6, 7, 5, 7, 5, 5, 5, 6, 6, 7, 5, 6, 4, 7, 4, 5, 5, 5, 5, 5, 4, 5, 5, -font.Wingdings.height=12 -font.Mistral.widths=5, 4, 4, 5, 3, 3, 4, 5, 4, 4, 5, 4, 7, 6, 5, 4, 4, 4, 4, 4, 5, 4, 6, 5, 5, 4, 5, 6, 6, 6, 5, 5, 6, 6, 5, 4, 6, 4, 7, 6, 6, 5, 6, 6, 4, 4, 6, 5, 7, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 4, 5, 5, -font.Bitstream\ Vera\ Sans\ Bold\ Oblique.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Harrington.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Console.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 1.widths=5, 5, 5, 7, 7, 9, 7, 7, 3, 3, 4, 3, 10, 5, 7, 9, 9, 4, 6, 4, 9, 6, 6, 4, 4, 5, 8, 9, 6, 7, 9, 9, 7, 8, 4, 9, 5, 3, 10, 7, 9, 9, 9, 4, 6, 4, 9, 9, 9, 9, 9, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -font.Lucida\ Fax\ Demibold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eras\ Demi\ ITC.height=12 -font.Calisto\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Blackadder\ ITC.height=13 -font.Arial\ Narrow\ Special\ G2\ Italic.height=14 -font.Century\ Gothic.widths=7, 7, 6, 7, 6, 3, 7, 6, 2, 3, 6, 2, 10, 6, 6, 7, 7, 3, 4, 3, 6, 6, 8, 6, 6, 5, 7, 6, 8, 7, 5, 5, 8, 7, 3, 5, 6, 4, 9, 7, 8, 6, 8, 6, 5, 4, 6, 7, 9, 7, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Ransom\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Monotype\ Sorts.widths=9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -font.Vivaldi\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Typewriter\ Bold\ Oblique.height=14 -font.Lucida\ Handwriting\ Italic.height=14 -font.Castellar.widths=9, 8, 9, 10, 7, 7, 9, 10, 5, 6, 9, 7, 12, 10, 10, 7, 10, 9, 6, 8, 10, 9, 12, 10, 9, 8, 9, 8, 9, 10, 7, 7, 9, 10, 5, 6, 9, 7, 12, 10, 10, 7, 10, 9, 6, 8, 10, 9, 12, 10, 9, 8, 8, 5, 6, 6, 7, 6, 7, 6, 7, 7, -font.Forte.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Medium.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Abadi\ MT\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Regular.height=14 -font.Bradley\ Hand\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eurostile.height=10 -font.Perpetua\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Rockwell\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 2.height=13 -font.Calisto\ MT\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.serif.plain.height=14 -font.Lucida\ Bright\ Regular.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bell\ MT\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tw\ Cen\ MT\ Condensed.widths=4, 4, 3, 4, 4, 3, 4, 4, 2, 2, 4, 2, 7, 4, 4, 4, 4, 3, 3, 3, 4, 4, 6, 4, 4, 3, 5, 5, 4, 5, 4, 4, 5, 5, 3, 4, 5, 4, 6, 5, 5, 4, 5, 5, 4, 4, 5, 5, 7, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -font.dialog.bolditalic.height=14 -font.Palatino\ Linotype\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.dialoginput.italic.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Georgia\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Rockwell\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Demi.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Goudy\ Old\ Style\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Perpetua\ Titling\ MT\ Light.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Parchment.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Symbol.height=14 -font.Abadi\ MT\ Condensed.widths=5, 5, 5, 5, 5, 3, 5, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 4, 5, 3, 5, 5, 7, 5, 5, 5, 5, 6, 5, 6, 6, 5, 6, 6, 3, 4, 5, 5, 7, 6, 6, 6, 6, 5, 5, 5, 6, 5, 7, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Palatino\ Linotype\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G1.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana\ Ref.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Gothic\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Vladimir\ Script.widths=5, 5, 4, 5, 4, 4, 5, 5, 4, 3, 5, 4, 6, 5, 5, 5, 5, 4, 4, 4, 5, 5, 6, 5, 5, 4, 9, 9, 7, 8, 7, 7, 8, 9, 7, 8, 7, 7, 10, 8, 7, 7, 7, 8, 7, 7, 8, 8, 10, 7, 8, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Franklin\ Gothic\ Demi\ Cond.widths=5, 5, 4, 5, 5, 3, 5, 5, 2, 2, 5, 2, 7, 5, 5, 5, 5, 3, 4, 3, 5, 4, 6, 4, 4, 4, 5, 6, 5, 6, 5, 4, 6, 6, 3, 3, 5, 4, 8, 6, 6, 5, 6, 5, 5, 4, 6, 5, 7, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.OCR\ A\ Extended.height=11 -font.Arial\ Narrow\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Runic\ MT\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Wide\ Latin.widths=11, 11, 10, 11, 10, 8, 10, 12, 7, 7, 13, 7, 18, 12, 11, 11, 11, 10, 10, 7, 12, 12, 16, 13, 11, 10, 15, 15, 14, 16, 15, 14, 16, 17, 10, 11, 16, 14, 18, 15, 14, 15, 14, 16, 13, 13, 16, 14, 19, 15, 14, 13, 13, 10, 13, 12, 13, 12, 13, 11, 13, 13, -font.Arial\ Special\ G2\ Bold.height=14 -font.Lucida\ Console.height=11 -font.Lucida\ Sans\ Typewriter\ Regular.height=14 -font.Bookman\ Old\ Style\ Bold.height=14 -font.Copperplate\ Gothic\ Light.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Trebuchet\ MS\ Bold.height=14 -font.Garamond\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Serif\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Viner\ Hand\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Book.widths=6, 6, 6, 6, 6, 4, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 4, 6, 6, 8, 5, 5, 5, 6, 7, 7, 7, 6, 6, 7, 7, 4, 5, 7, 6, 9, 8, 7, 7, 7, 7, 7, 6, 7, 6, 9, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookman\ Old\ Style\ Bold\ Italic.height=14 -font.Ransom\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Pacmania.height=12 -font.Arial\ Narrow\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Fax\ Demibold\ Italic.height=14 -font.monospaced.italic.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Book\ Antiqua\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Demibold\ Roman.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial.height=13 -font.Lucida\ Bright\ Demibold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Special\ G2.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Mistral.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana\ Ref.height=14 -font.Papyrus.height=17 -font.Lucida\ Sans\ Unicode.widths=7, 7, 6, 7, 6, 5, 7, 7, 4, 4, 7, 4, 9, 7, 7, 7, 7, 6, 6, 5, 7, 7, 9, 7, 7, 7, 8, 7, 8, 8, 6, 6, 8, 8, 4, 4, 8, 6, 10, 8, 9, 7, 9, 7, 6, 7, 8, 8, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Bold\ Italic.height=14 -font.Century\ Schoolbook\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G2\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Special\ G1.widths=8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.Arial\ Narrow\ Special\ G1.widths=10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -font.Marlett.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Gothic\ Italic.height=14 -font.Century\ Gothic\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Georgia\ Bold.height=14 -font.Lucida\ Sans\ Typewriter\ Bold.height=14 -font.MS\ Outlook.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Fax\ Demibold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Bold\ Italic.height=14 -font.Parchment.widths=3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3, 2, 4, 3, 3, 3, 3, 3, 3, 2, 3, 3, 4, 3, 3, 2, 10, 9, 8, 8, 8, 7, 11, 9, 7, 7, 9, 9, 10, 10, 10, 9, 9, 8, 8, 8, 9, 8, 10, 8, 8, 9, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, -font.Palatino\ Linotype\ Bold\ Italic.height=14 -font.Verdana\ Bold\ Italic.height=14 -font.Juice\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Typewriter\ Oblique.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G2\ Bold.height=14 -font.Ransom.height=16 -font.Rockwell\ Condensed\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Californian\ FB\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana\ Italic.height=14 -font.French\ Script\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Garamond\ Bold.height=14 -font.Lucida\ Calligraphy\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Narrow\ Special\ G2\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eras\ Light\ ITC.height=12 -font.Franklin\ Gothic\ Book\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Broadway.widths=8, 8, 7, 8, 7, 5, 7, 9, 5, 5, 8, 5, 13, 9, 7, 8, 8, 6, 6, 5, 9, 7, 10, 8, 7, 8, 9, 8, 8, 9, 8, 8, 9, 9, 5, 7, 8, 8, 10, 8, 9, 9, 9, 9, 7, 8, 9, 9, 11, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Californian\ FB\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Courier\ New\ Bold\ Italic.height=14 -font.Marlett.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Trebuchet\ MS.widths=5, 6, 5, 6, 6, 4, 6, 6, 3, 4, 6, 3, 9, 6, 6, 6, 6, 5, 4, 4, 6, 6, 9, 6, 5, 5, 7, 6, 6, 6, 6, 6, 7, 7, 3, 5, 6, 6, 8, 7, 7, 6, 7, 6, 5, 6, 7, 7, 10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Tw\ Cen\ MT\ Medium\ Italic.height=14 -font.Microsoft\ Sans\ Serif.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Brush\ Script\ MT\ Italic.height=14 -font.Baskerville\ Old\ Face.widths=5, 6, 5, 6, 6, 4, 5, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 5, 4, 6, 5, 7, 5, 5, 5, 8, 8, 8, 9, 7, 6, 9, 9, 5, 4, 8, 7, 10, 9, 9, 7, 9, 7, 6, 8, 9, 8, 12, 8, 8, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Edda.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Bold.height=14 -font.Rage\ Italic.widths=5, 4, 4, 6, 4, 3, 5, 5, 4, 3, 5, 4, 7, 6, 5, 6, 6, 5, 4, 4, 6, 5, 6, 5, 6, 4, 7, 8, 6, 8, 7, 6, 6, 8, 5, 6, 8, 7, 10, 8, 7, 7, 6, 8, 7, 6, 8, 7, 9, 7, 8, 7, 6, 4, 6, 6, 6, 5, 6, 5, 6, 6, -font.Franklin\ Gothic\ Medium\ Italic.height=14 -font.Century\ Schoolbook\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Braggadocio.widths=9, 9, 7, 9, 8, 6, 9, 9, 5, 5, 10, 5, 13, 9, 9, 9, 9, 8, 7, 6, 9, 8, 11, 8, 10, 9, 10, 12, 10, 11, 10, 10, 10, 12, 7, 8, 13, 10, 13, 10, 11, 11, 11, 12, 9, 11, 10, 11, 13, 10, 11, 12, 11, 7, 10, 11, 12, 11, 10, 11, 11, 11, -font.Wingdings\ 2.height=12 -font.Britannic\ Bold.height=11 -font.Bitstream\ Vera\ Sans\ Mono\ Bold\ Oblique.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 5.widths=9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -font.Playbill.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Bold\ Italic.height=14 -font.Georgia\ Ref.widths=7, 7, 6, 7, 6, 5, 7, 8, 5, 4, 7, 5, 11, 8, 6, 7, 6, 6, 6, 5, 8, 7, 9, 7, 7, 6, 9, 8, 7, 8, 8, 7, 8, 9, 5, 6, 8, 7, 10, 10, 8, 8, 8, 9, 7, 7, 9, 9, 11, 9, 9, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, -font.Georgia.widths=7, 7, 5, 7, 6, 5, 6, 8, 5, 4, 7, 5, 11, 8, 6, 7, 6, 5, 5, 5, 8, 7, 8, 7, 7, 5, 8, 8, 7, 8, 7, 7, 8, 9, 5, 6, 8, 7, 10, 8, 8, 7, 8, 8, 6, 7, 8, 8, 11, 8, 8, 7, 7, 6, 6, 6, 6, 6, 7, 6, 7, 7, -font.Arial\ Black\ Italic.height=14 -font.Franklin\ Gothic\ Medium\ Cond.widths=6, 6, 5, 6, 5, 4, 5, 6, 3, 3, 5, 3, 8, 6, 6, 6, 6, 4, 5, 4, 6, 5, 7, 5, 5, 4, 6, 6, 6, 7, 6, 5, 7, 6, 3, 4, 6, 5, 8, 7, 7, 6, 7, 6, 6, 5, 6, 6, 8, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Bauhaus\ 93.height=15 -font.Old\ English\ Text\ MT.height=11 -font.Verdana\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Augsburger\ Initials.widths=8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.monospaced.bold.height=14 -font.Bell\ MT.widths=5, 6, 5, 6, 5, 4, 6, 6, 4, 4, 6, 4, 8, 6, 6, 6, 6, 5, 5, 4, 6, 6, 8, 6, 6, 5, 8, 7, 7, 9, 8, 7, 8, 9, 5, 5, 8, 7, 10, 9, 8, 7, 8, 8, 6, 8, 9, 8, 11, 8, 8, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Rockwell\ Italic.height=14 -font.Lucida\ Sans\ Unicode.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Castellar.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Stencil.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Chiller.widths=4, 4, 4, 4, 4, 3, 4, 4, 3, 3, 4, 3, 6, 4, 4, 4, 4, 3, 4, 4, 4, 4, 5, 4, 5, 5, 6, 6, 6, 5, 5, 4, 5, 5, 4, 5, 6, 5, 7, 6, 6, 5, 6, 5, 4, 5, 5, 5, 7, 6, 5, 6, 6, 4, 5, 5, 5, 5, 5, 5, 6, 5, -font.Gill\ Sans\ MT\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.dialog.italic.height=14 -font.Perpetua\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.ProFont.widths=8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.dialog.bolditalic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Trebuchet\ MS\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Bold.height=14 -font.Californian\ FB\ Bold.height=14 -font.Rockwell\ Condensed\ Bold.height=14 -font.Georgia\ Bold\ Italic.height=14 -font.Trebuchet\ MS\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G1\ Bold.height=14 -font.Harlow\ Solid\ Italic\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Poor\ Richard.widths=6, 6, 5, 6, 5, 4, 6, 6, 4, 3, 6, 4, 8, 6, 5, 6, 6, 4, 4, 4, 6, 6, 7, 5, 6, 4, 8, 7, 8, 8, 6, 6, 8, 8, 4, 5, 7, 6, 9, 8, 9, 6, 9, 7, 6, 6, 8, 8, 11, 7, 8, 6, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, -font.serif.bolditalic.widths=5, 5, 4, 5, 4, 3, 5, 6, 3, 3, 5, 3, 8, 6, 5, 5, 5, 4, 4, 3, 6, 4, 7, 5, 4, 4, 7, 7, 7, 7, 7, 7, 7, 8, 4, 5, 7, 6, 9, 7, 7, 6, 7, 7, 6, 6, 7, 7, 9, 7, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Gill\ Sans\ Ultra\ Bold\ Condensed.height=13 -font.Verdana.widths=7, 7, 6, 7, 7, 5, 7, 7, 3, 4, 7, 3, 11, 7, 7, 7, 7, 5, 6, 5, 7, 7, 9, 7, 7, 6, 9, 8, 7, 9, 7, 7, 8, 8, 6, 6, 8, 6, 9, 8, 9, 8, 9, 8, 7, 6, 8, 8, 12, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Gill\ Sans\ Ultra\ Bold\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G2\ Bold\ Italic.height=14 -font.Courier\ New\ Italic.height=14 -font.Goudy\ Old\ Style.widths=5, 6, 5, 6, 5, 4, 5, 6, 4, 4, 6, 4, 8, 7, 6, 6, 6, 4, 4, 4, 6, 5, 7, 5, 5, 4, 8, 7, 8, 8, 7, 6, 9, 9, 4, 4, 8, 6, 10, 8, 9, 6, 9, 8, 6, 7, 9, 8, 11, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.dialog.plain.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Bold.height=14 -font.Bitstream\ Vera\ Sans\ Mono\ Oblique.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Trebuchet\ MS.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Modern\ No.\ 20.widths=6, 6, 5, 6, 5, 5, 5, 7, 4, 4, 6, 4, 9, 6, 5, 6, 6, 5, 4, 4, 6, 5, 8, 6, 6, 5, 8, 8, 6, 8, 8, 7, 8, 9, 5, 6, 8, 8, 10, 8, 7, 7, 7, 8, 6, 7, 8, 8, 11, 8, 8, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Kino\ MT.height=12 -font.Viner\ Hand\ ITC.widths=7, 6, 5, 6, 5, 5, 6, 7, 5, 5, 8, 5, 10, 8, 5, 6, 7, 5, 4, 6, 8, 7, 9, 6, 7, 6, 9, 9, 8, 9, 8, 7, 7, 9, 5, 6, 10, 8, 10, 9, 6, 8, 9, 8, 8, 7, 8, 8, 12, 7, 8, 8, 5, 4, 8, 6, 7, 5, 6, 6, 6, 6, -font.Forte.widths=7, 6, 5, 7, 5, 5, 7, 6, 4, 4, 6, 6, 9, 6, 6, 7, 6, 4, 5, 4, 6, 5, 8, 6, 6, 5, 8, 8, 7, 8, 7, 6, 7, 9, 7, 6, 8, 5, 12, 9, 7, 7, 8, 7, 6, 6, 7, 6, 9, 8, 8, 7, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, -font.dialoginput.bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Impact.height=14 -font.Showcard\ Gothic.widths=7, 8, 7, 10, 7, 6, 8, 9, 5, 6, 8, 6, 10, 9, 9, 8, 9, 8, 7, 7, 9, 7, 11, 8, 7, 7, 7, 8, 7, 10, 7, 6, 8, 9, 5, 6, 8, 6, 10, 9, 9, 8, 9, 8, 7, 7, 9, 7, 11, 8, 7, 7, 7, 5, 6, 6, 7, 6, 6, 6, 7, 7, -font.Felix\ Titling.widths=8, 7, 9, 9, 6, 6, 9, 8, 4, 4, 9, 6, 10, 9, 9, 6, 9, 9, 6, 7, 9, 8, 11, 8, 7, 8, 8, 7, 9, 9, 6, 6, 9, 8, 4, 4, 9, 6, 10, 9, 9, 6, 9, 9, 6, 7, 9, 8, 11, 8, 7, 8, 7, 4, 6, 7, 6, 7, 7, 6, 7, 7, -font.Arial\ Black.height=15 -font.Comic\ Sans\ MS\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Stencil.height=11 -font.Gill\ Sans\ MT\ Condensed.height=13 -font.Tw\ Cen\ MT\ Medium\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.French\ Script\ MT.widths=4, 4, 4, 4, 4, 3, 5, 5, 3, 3, 5, 3, 6, 4, 4, 4, 4, 3, 4, 3, 4, 4, 5, 4, 4, 4, 6, 8, 6, 8, 6, 7, 6, 9, 6, 6, 9, 7, 11, 10, 7, 6, 7, 8, 7, 6, 8, 8, 9, 7, 8, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Symbol.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Book\ Antiqua\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G1.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Felix\ Titling.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Bold\ Italic.height=14 -font.Arial\ Special\ G1\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Condensed\ Extra\ Bold.height=12 -font.Century\ Schoolbook\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Calisto\ MT.widths=4, 6, 4, 5, 4, 3, 5, 6, 3, 3, 5, 3, 9, 6, 6, 6, 5, 4, 4, 3, 6, 6, 8, 5, 5, 5, 8, 7, 8, 8, 6, 6, 9, 8, 3, 5, 8, 6, 10, 8, 9, 5, 9, 7, 6, 5, 8, 7, 11, 7, 8, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.dialoginput.bolditalic.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Pristina.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G1\ Bold.height=14 -font.serif.bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Kristen\ ITC.height=15 -font.Lucida\ Bright\ Demibold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G2.widths=8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.Palatino\ Linotype.height=14 -font.dialoginput.plain.height=14 -font.Times\ New\ Roman\ Special\ G2.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Kunstler\ Script.height=12 -font.Book\ Antiqua.widths=5, 6, 4, 6, 5, 4, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 4, 3, 6, 6, 8, 5, 6, 5, 8, 7, 7, 8, 6, 6, 8, 8, 4, 4, 8, 6, 10, 8, 8, 6, 8, 7, 6, 7, 8, 8, 10, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Times\ New\ Roman.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Medium.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Mercurius\ Script\ MT\ Bold.height=12 -font.Tw\ Cen\ MT\ Condensed.height=12 -font.Monotype\ Sorts\ 2.widths=11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -font.sansserif.bold.height=14 -font.Elephant\ Italic.height=14 -font.dialoginput.italic.height=14 -font.Tahoma\ Bold.height=14 -font.Rockwell\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT\ Italic.height=14 -font.serif.bold.widths=5, 6, 4, 6, 4, 4, 5, 6, 3, 3, 5, 3, 8, 6, 5, 6, 6, 4, 4, 3, 6, 5, 7, 6, 5, 3, 7, 7, 7, 7, 7, 6, 8, 8, 4, 5, 8, 7, 9, 7, 8, 6, 9, 7, 6, 7, 7, 7, 10, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Baskerville\ Old\ Face.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Abadi\ MT\ Condensed.height=12 -font.Copperplate\ Gothic\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Snap\ ITC.widths=7, 7, 7, 7, 7, 7, 8, 7, 6, 5, 8, 5, 9, 7, 7, 7, 7, 7, 7, 7, 8, 8, 11, 9, 8, 7, 10, 9, 9, 9, 9, 9, 10, 10, 6, 9, 9, 8, 12, 10, 9, 9, 9, 9, 9, 8, 9, 9, 12, 10, 10, 9, 9, 6, 9, 9, 10, 9, 9, 9, 10, 9, -font.Rockwell\ Extra\ Bold.widths=8, 8, 7, 8, 7, 5, 8, 8, 4, 4, 7, 4, 12, 8, 8, 8, 8, 5, 6, 5, 8, 7, 10, 7, 7, 7, 8, 9, 8, 9, 8, 7, 8, 9, 5, 4, 9, 7, 11, 9, 9, 8, 9, 9, 6, 8, 7, 8, 11, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bradley\ Hand\ ITC.height=13 -font.Imprint\ MT\ Shadow.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G2.height=16 -font.Arial\ Narrow\ Special\ G2.height=16 -font.Bitstream\ Vera\ Sans\ Oblique.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Elephant.widths=7, 7, 6, 7, 6, 5, 6, 7, 4, 4, 7, 4, 10, 8, 7, 7, 7, 6, 6, 5, 8, 6, 9, 6, 6, 6, 8, 10, 9, 10, 10, 9, 10, 11, 6, 8, 10, 9, 12, 10, 10, 9, 10, 10, 8, 9, 10, 8, 13, 9, 8, 9, 9, 6, 8, 8, 8, 8, 8, 7, 8, 8, -font.Eurostile\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Gigi.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Imprint\ MT\ Shadow.height=13 -font.Monotype\ Corsiva.widths=5, 5, 4, 5, 4, 4, 6, 5, 3, 3, 5, 3, 7, 6, 5, 5, 5, 4, 4, 4, 6, 5, 8, 5, 5, 5, 7, 7, 6, 8, 7, 7, 7, 8, 5, 5, 8, 7, 9, 8, 7, 7, 7, 7, 6, 6, 8, 7, 10, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Matisse\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookman\ Old\ Style.widths=6, 6, 6, 6, 6, 5, 6, 7, 4, 4, 7, 4, 10, 7, 7, 7, 6, 5, 5, 5, 7, 6, 10, 6, 6, 6, 7, 8, 7, 8, 7, 7, 8, 8, 4, 7, 8, 7, 11, 8, 8, 7, 8, 8, 7, 8, 8, 8, 11, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Perpetua.height=13 -font.Franklin\ Gothic\ Book.height=13 -font.Gloucester\ MT\ Extra\ Condensed.widths=4, 5, 4, 5, 4, 3, 4, 5, 3, 3, 5, 3, 6, 5, 5, 5, 5, 4, 4, 3, 5, 4, 6, 5, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 3, 4, 5, 4, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Ransom\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Mono.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Garamond\ Italic.height=14 -font.Colonna\ MT.height=12 -font.Gill\ Sans\ MT\ Ext\ Condensed\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Calisto\ MT\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Edda.widths=9, 10, 9, 10, 8, 9, 9, 10, 5, 5, 9, 8, 13, 9, 8, 10, 9, 9, 8, 8, 9, 9, 14, 9, 10, 9, 9, 9, 9, 10, 9, 9, 10, 10, 5, 6, 10, 8, 11, 10, 10, 9, 10, 9, 9, 9, 10, 9, 12, 9, 8, 9, 9, 5, 8, 8, 8, 8, 8, 7, 8, 8, -font.Palace\ Script\ MT.height=10 -font.Bitstream\ Vera\ Serif.height=13 -font.Onyx.widths=5, 5, 5, 5, 5, 3, 5, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 5, 4, 4, 5, 5, 7, 5, 5, 4, 5, 5, 5, 5, 4, 4, 5, 5, 3, 4, 5, 4, 7, 6, 5, 5, 5, 6, 5, 5, 5, 5, 7, 5, 5, 5, 5, 3, 4, 4, 5, 5, 5, 4, 5, 5, -font.Playbill.widths=4, 4, 3, 4, 3, 3, 3, 4, 2, 2, 4, 2, 5, 4, 3, 4, 4, 3, 3, 3, 4, 4, 5, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 6, 5, 4, 4, 4, 5, 4, 4, 4, 4, 5, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Bookman\ Old\ Style\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Vladimir\ Script.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tempus\ Sans\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Algerian.height=14 -font.Arial\ Narrow\ Special\ G1\ Italic.height=14 -font.Cooper\ Black.height=13 -font.Chiller.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Fax\ Italic.height=14 -font.Bitstream\ Vera\ Sans\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Informal\ Roman.height=13 -font.Kunstler\ Script.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.monospaced.plain.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Script\ MT\ Bold.widths=5, 4, 4, 5, 4, 4, 5, 5, 2, 4, 5, 3, 7, 5, 4, 6, 5, 4, 4, 3, 5, 4, 7, 6, 5, 5, 7, 8, 6, 8, 5, 6, 6, 9, 6, 5, 8, 6, 10, 9, 6, 7, 6, 8, 6, 7, 8, 7, 10, 7, 8, 6, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, -font.Juice\ ITC.widths=5, 5, 4, 5, 4, 4, 4, 5, 3, 3, 4, 3, 6, 5, 4, 5, 5, 4, 4, 4, 5, 4, 6, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 3, 4, 4, 4, 5, 5, 5, 4, 5, 4, 4, 4, 5, 5, 5, 5, 4, 4, 5, 3, 4, 4, 4, 4, 5, 4, 4, 5, -font.Calisto\ MT\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Georgia\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tahoma.widths=6, 6, 5, 6, 6, 4, 6, 6, 3, 4, 7, 3, 9, 6, 6, 6, 6, 5, 5, 4, 6, 6, 9, 6, 6, 5, 8, 7, 7, 8, 6, 6, 7, 8, 5, 5, 7, 6, 9, 7, 8, 7, 8, 7, 6, 7, 7, 7, 10, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Special\ G2\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookshelf\ Symbol\ 4.widths=9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -font.Tw\ Cen\ MT\ Bold\ Italic.height=14 -font.High\ Tower\ Text\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Demibold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Enviro.widths=5, 5, 6, 5, 6, 4, 6, 5, 3, 3, 5, 4, 9, 5, 5, 5, 6, 4, 5, 4, 6, 5, 7, 4, 5, 6, 7, 8, 7, 7, 8, 6, 7, 7, 3, 7, 8, 8, 8, 7, 8, 8, 8, 8, 9, 7, 7, 7, 9, 6, 8, 7, 7, 3, 8, 8, 8, 8, 8, 8, 8, 8, -font.Edwardian\ Script\ ITC.height=13 -font.Gigi.height=15 -font.Abadi\ MT\ Condensed\ Light.widths=5, 5, 5, 5, 5, 3, 5, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 4, 5, 3, 5, 5, 6, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 6, 3, 4, 5, 5, 7, 6, 6, 6, 6, 6, 5, 5, 6, 5, 7, 6, 6, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, -font.Goudy\ Old\ Style\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Heavy.height=13 -font.Stop.widths=7, 6, 6, 7, 6, 6, 7, 6, 4, 5, 6, 5, 9, 7, 8, 6, 8, 6, 6, 6, 7, 7, 9, 7, 7, 6, 7, 6, 6, 7, 6, 6, 7, 6, 4, 5, 6, 5, 9, 7, 8, 6, 8, 6, 6, 6, 7, 7, 9, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Andy\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Haettenschweiler.widths=5, 5, 5, 5, 5, 4, 5, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 5, 5, 4, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 4, 4, 5, 5, 3, 5, 5, 4, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, -font.Maiandra\ GD.widths=5, 6, 5, 6, 5, 4, 5, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 4, 4, 6, 6, 9, 5, 6, 5, 8, 7, 7, 8, 6, 6, 8, 9, 4, 5, 7, 5, 10, 8, 9, 6, 9, 7, 5, 7, 8, 7, 11, 7, 7, 6, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, -font.Franklin\ Gothic\ Heavy\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.sansserif.bolditalic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.dialoginput.italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Ransom\ Bold.height=14 -font.Britannic\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Edwardian\ Script\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Trebuchet\ MS\ Italic.height=14 -font.Californian\ FB.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Baskerville\ Old\ Face.height=11 -font.Times\ New\ Roman\ Special\ G1\ Bold\ Italic.height=14 -font.Californian\ FB\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Book\ Antiqua\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bernard\ MT\ Condensed.widths=6, 6, 5, 6, 5, 4, 6, 6, 4, 4, 6, 4, 8, 6, 6, 6, 6, 5, 4, 4, 6, 5, 7, 5, 5, 5, 6, 6, 5, 6, 5, 5, 6, 7, 4, 4, 6, 5, 7, 6, 6, 6, 6, 6, 5, 6, 5, 6, 8, 6, 6, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, -font.Lucida\ Bright\ Demibold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Mono\ Oblique.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Freestyle\ Script.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Schoolbook.widths=7, 7, 5, 7, 6, 4, 6, 7, 4, 4, 7, 4, 10, 7, 6, 7, 7, 5, 6, 5, 7, 6, 9, 6, 6, 6, 8, 8, 8, 9, 8, 8, 9, 9, 5, 7, 9, 8, 10, 9, 9, 8, 9, 8, 7, 8, 9, 8, 11, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Typewriter\ Oblique.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Mistral.height=11 -font.Bitstream\ Vera\ Sans\ Bold\ Oblique.height=14 -font.Arial\ Special\ G2\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Georgia\ Ref.height=13 -font.Bitstream\ Vera\ Sans\ Mono\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Ransom.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 1.height=13 -font.Century\ Gothic\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Gothic.height=14 -font.Wingdings\ 2.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT.widths=5, 6, 5, 6, 6, 3, 5, 6, 3, 3, 6, 3, 10, 6, 6, 6, 6, 4, 4, 4, 6, 5, 8, 6, 5, 5, 8, 7, 8, 8, 6, 6, 8, 8, 3, 3, 7, 6, 9, 8, 9, 7, 9, 7, 6, 7, 8, 7, 12, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Ransom\ Bold\ Italic.height=14 -font.Times\ New\ Roman\ Special\ G1\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Monotype\ Sorts.height=10 -font.Book\ Antiqua.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Maiandra\ GD\ Demi\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Franklin\ Gothic\ Heavy\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Castellar.height=13 -font.sansserif.plain.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.OpenSymbol.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G1\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Gradl.widths=4, 4, 3, 4, 3, 2, 4, 4, 2, 2, 4, 2, 5, 4, 4, 4, 4, 3, 3, 3, 4, 3, 4, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 6, 4, 5, 4, 4, 4, 4, 4, 5, 4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -font.Arial\ Narrow\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Parade.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.ProFont.height=14 -font.Perpetua\ Bold.height=14 -font.Wingdings\ 3.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Calisto\ MT\ Italic.height=14 -font.Lucida\ Bright\ Regular.height=14 -font.Bell\ MT\ Italic.height=14 -font.Kristen\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Typewriter\ Bold\ Oblique.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Demi\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rage\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Georgia\ Italic.height=14 -font.MS\ Outlook.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Goudy\ Old\ Style\ Italic.height=14 -font.Lucida\ Sans\ Typewriter\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Titling\ MT\ Light.height=14 -font.Footlight\ MT\ Light.widths=6, 6, 5, 6, 5, 4, 6, 7, 4, 4, 6, 4, 9, 7, 6, 6, 6, 5, 5, 4, 7, 6, 9, 6, 6, 5, 7, 6, 7, 8, 6, 5, 8, 8, 4, 4, 7, 6, 10, 8, 8, 6, 8, 6, 5, 6, 8, 7, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Augsburger\ Initials.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Courier\ New\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.monospaced.bolditalic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookman\ Old\ Style\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Gothic\ Bold.height=14 -font.Vladimir\ Script.height=13 -font.Franklin\ Gothic\ Demi\ Cond.height=13 -font.Century\ Schoolbook\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Narrow\ Bold.height=14 -font.Times\ New\ Roman\ Special\ G1.widths=8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.OpenSymbol.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Wide\ Latin.height=11 -font.Showcard\ Gothic.height=14 -font.Californian\ FB.widths=4, 6, 5, 5, 5, 4, 6, 5, 3, 3, 6, 3, 7, 5, 5, 6, 5, 5, 4, 4, 5, 5, 8, 5, 5, 5, 7, 6, 7, 7, 7, 6, 7, 8, 4, 4, 7, 6, 10, 8, 7, 6, 7, 7, 5, 6, 8, 7, 11, 7, 6, 7, 5, 4, 5, 5, 6, 5, 5, 5, 5, 5, -font.Tw\ Cen\ MT\ Bold.height=14 -font.Bitstream\ Vera\ Sans.widths=7, 7, 6, 7, 7, 4, 7, 7, 3, 3, 7, 3, 11, 7, 7, 7, 7, 5, 6, 5, 7, 7, 9, 7, 7, 5, 9, 7, 7, 8, 6, 6, 8, 8, 3, 3, 7, 6, 9, 8, 8, 7, 8, 8, 7, 7, 8, 9, 11, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Palatino\ Linotype\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.sansserif.italic.widths=7, 7, 6, 7, 7, 4, 7, 7, 4, 3, 6, 4, 8, 7, 7, 7, 7, 4, 6, 4, 7, 6, 9, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 3, 6, 8, 7, 9, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Footlight\ MT\ Light.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Italic.height=14 -font.monospaced.italic.height=14 -font.Book\ Antiqua\ Italic.height=14 -font.Arial\ Narrow.widths=5, 5, 5, 5, 5, 3, 5, 5, 2, 2, 5, 2, 7, 5, 5, 5, 5, 4, 5, 3, 5, 5, 6, 5, 5, 4, 6, 6, 6, 6, 5, 5, 6, 6, 2, 5, 6, 5, 7, 6, 6, 5, 6, 6, 5, 5, 6, 5, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Lucida\ Bright\ Demibold\ Italic.height=14 -font.Times\ New\ Roman.widths=5, 6, 4, 6, 4, 4, 5, 6, 3, 3, 5, 3, 8, 6, 5, 6, 6, 4, 4, 3, 6, 5, 7, 6, 5, 3, 7, 7, 7, 7, 7, 6, 8, 8, 4, 5, 8, 7, 9, 7, 8, 6, 9, 7, 6, 7, 7, 7, 10, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Arial.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Handwriting\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Unicode.height=16 -font.Ravie.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.serif.italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Andy\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Schoolbook\ Bold.height=14 -font.Times\ New\ Roman\ Special\ G2\ Italic.height=14 -font.Arial\ Special\ G1.height=16 -font.Arial\ Narrow\ Special\ G1.height=16 -font.Bookman\ Old\ Style\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G2.height=16 -font.Rockwell\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Gothic\ Bold\ Italic.height=14 -font.sansserif.plain.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tw\ Cen\ MT\ Medium.height=14 -font.Parchment.height=12 -font.Bitstream\ Vera\ Serif\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Informal\ Roman.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Fax\ Regular.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Ransom\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Special\ G1\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Showcard\ Gothic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.OCRB.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Jokerman.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Colonna\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eras\ Light\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Fax\ Regular.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Copperplate\ Gothic\ Bold.widths=7, 7, 7, 7, 6, 6, 7, 7, 4, 5, 7, 6, 9, 7, 7, 7, 7, 7, 6, 4, 7, 7, 9, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 9, 4, 6, 8, 7, 9, 9, 9, 8, 9, 8, 7, 6, 8, 7, 13, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Pepita\ MT.widths=5, 5, 4, 6, 4, 4, 6, 5, 3, 4, 5, 4, 7, 5, 4, 6, 5, 4, 4, 4, 5, 5, 8, 6, 5, 6, 10, 9, 8, 11, 6, 9, 10, 9, 5, 5, 11, 8, 12, 9, 9, 9, 12, 9, 9, 9, 10, 9, 12, 9, 9, 11, 5, 4, 6, 5, 7, 6, 5, 6, 6, 7, -font.Eras\ Bold\ ITC.widths=6, 7, 5, 7, 6, 4, 7, 7, 3, 3, 6, 3, 9, 7, 6, 7, 7, 4, 5, 4, 7, 6, 9, 6, 6, 5, 8, 7, 7, 8, 7, 6, 8, 8, 3, 5, 8, 6, 9, 8, 9, 6, 9, 7, 6, 6, 8, 8, 11, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Franklin\ Gothic\ Demi.widths=5, 5, 5, 5, 5, 3, 6, 5, 3, 3, 5, 3, 8, 5, 5, 5, 5, 3, 5, 4, 5, 5, 7, 5, 4, 4, 6, 7, 6, 6, 6, 6, 6, 6, 3, 4, 6, 5, 9, 6, 6, 6, 6, 7, 6, 5, 7, 6, 9, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Rockwell\ Extra\ Bold.height=13 -font.monospaced.plain.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Centaur.widths=5, 6, 5, 6, 5, 4, 5, 6, 3, 3, 6, 3, 8, 6, 6, 6, 6, 4, 4, 4, 6, 5, 7, 5, 5, 5, 7, 6, 7, 8, 7, 6, 8, 9, 5, 5, 7, 7, 10, 9, 8, 6, 8, 8, 6, 8, 8, 8, 11, 8, 8, 7, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, -font.Tw\ Cen\ MT\ Condensed\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Harlow\ Solid\ Italic\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Calligraphy\ Italic.height=14 -font.Palatino\ Linotype\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Courier\ New\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.dialoginput.bold.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Broadway.height=13 -font.Franklin\ Gothic\ Book\ Italic.height=14 -font.Marlett.height=10 -font.Trebuchet\ MS.height=13 -font.Arial\ Narrow\ Special\ G2\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Webdings.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Monotype\ Corsiva.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.High\ Tower\ Text.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gloucester\ MT\ Extra\ Condensed.height=13 -font.Rage\ Italic.height=14 -font.Abadi\ MT\ Condensed\ Extra\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 3.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Braggadocio.height=10 -font.Microsoft\ Sans\ Serif.widths=7, 7, 6, 7, 7, 4, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 6, 4, 7, 7, 9, 6, 6, 6, 8, 8, 8, 9, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 6, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Curlz\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Goudy\ Stout.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.sansserif.bolditalic.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 3, 6, 6, 8, 6, 6, 5, 7, 7, 7, 7, 7, 6, 8, 7, 3, 6, 7, 6, 9, 7, 8, 7, 8, 7, 7, 6, 7, 7, 9, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Bookshelf\ Symbol\ 5.height=13 -font.Edda.height=16 -font.Vivaldi\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookshelf\ Symbol\ 1.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Georgia.height=13 -font.Bell\ MT\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Franklin\ Gothic\ Medium\ Cond.height=13 -font.Bookman\ Old\ Style.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Augsburger\ Initials.height=12 -font.Beesknees\ ITC.widths=7, 7, 6, 7, 6, 6, 7, 7, 4, 4, 7, 5, 8, 7, 8, 6, 8, 7, 5, 5, 7, 7, 9, 7, 7, 7, 9, 8, 7, 8, 7, 7, 8, 8, 5, 5, 8, 6, 10, 8, 9, 7, 9, 8, 6, 6, 8, 9, 10, 9, 8, 8, 9, 5, 7, 6, 7, 6, 8, 6, 7, 8, -font.Perpetua\ Titling\ MT\ Light.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bell\ MT.height=12 -font.Arial\ Narrow\ Special\ G1\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G2\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Juice\ ITC.height=13 -font.Trebuchet\ MS\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Rounded\ MT\ Bold.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 5, 4, 6, 5, 8, 5, 5, 5, 7, 7, 7, 7, 7, 6, 8, 8, 3, 6, 7, 6, 8, 8, 8, 7, 8, 7, 7, 6, 8, 7, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Arial\ Special\ G2\ Italic.height=14 -font.Chiller.height=13 -font.Gill\ Sans\ MT\ Bold\ Italic.height=14 -font.Bookshelf\ Symbol\ 2.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Abadi\ MT\ Condensed\ Light.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Demibold\ Italic.height=14 -font.Ransom\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Goudy\ Stout.widths=14, 13, 11, 12, 13, 13, 13, 16, 11, 12, 16, 13, 18, 13, 13, 12, 11, 15, 11, 14, 14, 13, 18, 14, 14, 14, 14, 13, 11, 12, 13, 13, 13, 16, 11, 12, 16, 13, 18, 13, 13, 12, 11, 15, 11, 14, 14, 13, 18, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -font.Trebuchet\ MS\ Bold\ Italic.height=14 -font.Elephant\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Special\ G2\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Pacmania.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Broadway.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Pristina.widths=5, 5, 4, 5, 4, 3, 5, 5, 3, 2, 5, 2, 7, 5, 4, 5, 5, 4, 4, 3, 5, 5, 6, 5, 5, 4, 7, 8, 7, 8, 8, 7, 7, 9, 6, 6, 9, 6, 11, 8, 8, 7, 8, 8, 6, 7, 9, 8, 11, 8, 8, 6, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, -font.Courier\ New.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Abadi\ MT\ Condensed\ Extra\ Bold.widths=4, 5, 4, 5, 5, 3, 5, 5, 3, 3, 4, 3, 7, 5, 5, 5, 5, 3, 4, 3, 5, 4, 6, 4, 4, 4, 5, 5, 4, 5, 5, 4, 5, 5, 3, 3, 5, 4, 6, 5, 6, 5, 6, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Copperplate\ Gothic\ Light.widths=7, 7, 8, 8, 7, 7, 8, 8, 4, 6, 7, 7, 8, 8, 9, 7, 9, 7, 7, 6, 8, 7, 10, 7, 6, 6, 8, 9, 9, 9, 8, 8, 9, 9, 4, 7, 8, 8, 10, 9, 10, 8, 10, 9, 8, 8, 9, 8, 12, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.dialog.plain.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Poor\ Richard.height=13 -font.Franklin\ Gothic\ Medium.widths=6, 6, 6, 6, 6, 4, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 4, 6, 5, 8, 5, 5, 5, 7, 7, 7, 8, 6, 6, 7, 7, 4, 5, 7, 6, 9, 8, 7, 7, 7, 7, 7, 6, 7, 6, 10, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.serif.bolditalic.height=14 -font.Bookshelf\ Symbol\ 3.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Comic\ Sans\ MS\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Bright\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Runic\ MT\ Condensed.widths=5, 5, 5, 5, 5, 3, 5, 5, 3, 3, 4, 3, 7, 5, 5, 5, 5, 5, 5, 3, 5, 5, 7, 5, 5, 4, 5, 6, 6, 6, 6, 4, 6, 6, 3, 5, 5, 6, 7, 6, 6, 6, 6, 5, 5, 5, 6, 5, 7, 5, 5, 5, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, -font.Perpetua\ Titling\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ Ultra\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana.height=14 -font.Goudy\ Old\ Style.height=13 -font.monospaced.bolditalic.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Goudy\ Old\ Style.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Mono\ Oblique.height=14 -font.Modern\ No.\ 20.height=12 -font.Matura\ MT\ Script\ Capitals.widths=6, 6, 5, 6, 5, 5, 6, 6, 4, 4, 6, 4, 8, 6, 6, 6, 6, 5, 6, 4, 6, 6, 9, 6, 6, 6, 14, 12, 10, 14, 9, 13, 9, 9, 9, 13, 13, 13, 16, 15, 13, 10, 12, 11, 10, 10, 12, 13, 15, 15, 12, 14, 8, 5, 6, 5, 7, 6, 6, 6, 6, 6, -font.Viner\ Hand\ ITC.height=17 -font.Forte.height=15 -font.Placard\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Medium.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Placard\ Condensed.widths=5, 5, 5, 5, 5, 3, 5, 5, 3, 3, 5, 3, 6, 5, 5, 5, 5, 3, 4, 3, 5, 4, 6, 5, 4, 3, 5, 5, 5, 5, 4, 4, 5, 5, 3, 3, 5, 4, 6, 5, 5, 5, 5, 5, 5, 4, 5, 5, 6, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Jokerman.widths=7, 7, 6, 7, 7, 4, 7, 8, 4, 4, 7, 4, 9, 7, 7, 7, 7, 6, 5, 5, 7, 6, 8, 7, 7, 7, 9, 8, 8, 8, 7, 6, 9, 8, 4, 7, 8, 8, 10, 10, 9, 8, 9, 8, 7, 8, 9, 8, 12, 9, 8, 8, 8, 5, 7, 8, 8, 7, 7, 7, 7, 8, -font.Franklin\ Gothic\ Heavy.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Black.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Harrington.widths=6, 6, 6, 7, 6, 4, 6, 6, 4, 4, 6, 4, 8, 6, 7, 7, 6, 5, 6, 4, 7, 6, 8, 5, 7, 6, 8, 8, 7, 8, 8, 7, 8, 8, 4, 4, 7, 7, 9, 8, 8, 8, 8, 8, 7, 6, 8, 7, 10, 7, 7, 7, 7, 4, 6, 6, 7, 6, 6, 5, 6, 6, -font.Felix\ Titling.height=13 -font.Comic\ Sans\ MS\ Bold.height=14 -font.Papyrus.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Curlz\ MT.widths=5, 5, 5, 5, 5, 4, 5, 6, 3, 3, 5, 3, 8, 6, 6, 6, 6, 5, 4, 4, 6, 5, 8, 5, 5, 5, 7, 7, 6, 8, 6, 6, 7, 8, 4, 5, 7, 6, 9, 9, 8, 7, 8, 7, 6, 6, 8, 7, 10, 7, 8, 6, 6, 4, 5, 5, 6, 6, 6, 5, 5, 6, -font.Century\ Schoolbook\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT\ Ext\ Condensed\ Bold.widths=3, 3, 2, 3, 3, 2, 3, 3, 1, 2, 3, 2, 4, 3, 3, 3, 3, 2, 2, 2, 3, 3, 4, 3, 3, 2, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 4, 3, 3, 3, 3, 3, 2, 3, 3, 3, 5, 3, 3, 2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 3, -font.French\ Script\ MT.height=13 -font.Tw\ Cen\ MT\ Condensed\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Freestyle\ Script.widths=3, 3, 4, 4, 4, 5, 6, 6, 2, 3, 5, 4, 4, 4, 4, 3, 5, 3, 4, 4, 5, 4, 6, 3, 4, 3, 5, 4, 5, 6, 5, 5, 5, 6, 4, 5, 6, 4, 6, 6, 5, 5, 5, 6, 5, 6, 6, 6, 7, 5, 5, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 4, -font.Lucida\ Sans\ Demibold\ Roman.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookshelf\ Symbol\ 4.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Goudy\ Old\ Style\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Braggadocio.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Regular.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gloucester\ MT\ Extra\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G2\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Fax\ Demibold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Special\ G1\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Perpetua\ Titling\ MT\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Century\ Schoolbook\ Bold\ Italic.height=14 -font.Calisto\ MT.height=13 -font.Lucida\ Sans\ Demibold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.dialoginput.bolditalic.height=14 -font.Poor\ Richard.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Ravie.widths=9, 9, 8, 9, 8, 8, 9, 9, 6, 8, 9, 5, 13, 9, 8, 9, 9, 9, 8, 9, 9, 9, 12, 9, 10, 9, 10, 9, 8, 9, 10, 9, 9, 10, 6, 9, 11, 9, 14, 9, 9, 9, 9, 12, 9, 10, 10, 11, 14, 10, 10, 10, 8, 6, 9, 9, 11, 9, 9, 8, 8, 9, -font.Arial\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.MT\ Extra.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Bitstream\ Vera\ Sans\ Mono\ Bold\ Oblique.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Eras\ Medium\ ITC.widths=6, 7, 6, 7, 6, 4, 7, 7, 3, 3, 6, 3, 10, 7, 7, 7, 7, 5, 5, 4, 7, 6, 9, 6, 6, 5, 8, 7, 7, 8, 7, 6, 8, 8, 3, 5, 7, 6, 10, 9, 9, 6, 9, 7, 6, 6, 8, 8, 11, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Bright\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Bright\ Demibold.height=14 -font.Pepita\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Wingdings.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 5.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.dialoginput.bolditalic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Book\ Antiqua.height=13 -font.Franklin\ Gothic\ Demi\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Comic\ Sans\ MS.widths=6, 6, 5, 6, 6, 5, 5, 6, 3, 4, 5, 3, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 6, 5, 7, 6, 6, 7, 6, 6, 7, 8, 5, 7, 6, 6, 9, 8, 8, 5, 9, 6, 7, 7, 7, 7, 10, 7, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Desdemona.widths=6, 6, 6, 6, 6, 6, 7, 7, 3, 5, 6, 6, 8, 7, 8, 6, 7, 6, 6, 6, 7, 6, 7, 6, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 3, 5, 6, 6, 8, 7, 8, 6, 7, 6, 6, 6, 7, 6, 7, 6, 5, 6, 5, 3, 5, 6, 5, 5, 5, 5, 5, 6, -font.sansserif.italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Wingdings\ 3.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.High\ Tower\ Text.widths=5, 7, 5, 6, 5, 5, 6, 7, 4, 4, 6, 4, 10, 7, 6, 7, 6, 5, 6, 4, 7, 6, 9, 6, 6, 6, 9, 7, 9, 9, 7, 6, 9, 8, 4, 5, 8, 7, 10, 9, 10, 7, 10, 7, 7, 8, 9, 9, 11, 8, 8, 9, 6, 4, 5, 5, 6, 5, 6, 6, 6, 6, -font.Monotype\ Sorts\ 2.height=13 -font.Bookman\ Old\ Style\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Engravers\ MT.widths=10, 10, 10, 11, 9, 9, 11, 11, 6, 8, 11, 9, 12, 11, 11, 9, 11, 11, 9, 10, 11, 10, 13, 11, 11, 9, 10, 10, 10, 11, 9, 9, 11, 11, 6, 8, 11, 9, 12, 11, 11, 9, 11, 11, 9, 10, 11, 10, 13, 11, 11, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G1\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Maiandra\ GD.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G1\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Eurostile.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.serif.bold.height=14 -font.High\ Tower\ Text\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.dialog.bold.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 4, 6, 3, 9, 6, 6, 6, 6, 4, 6, 3, 6, 7, 9, 6, 5, 5, 7, 7, 7, 7, 7, 6, 8, 7, 3, 6, 7, 6, 9, 7, 8, 7, 8, 7, 7, 5, 7, 7, 9, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Book\ Antiqua\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Snap\ ITC.height=14 -font.Trebuchet\ MS\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Condensed.widths=5, 5, 4, 5, 4, 3, 5, 5, 3, 3, 5, 3, 8, 5, 5, 5, 5, 3, 4, 3, 5, 4, 6, 4, 4, 4, 6, 5, 5, 6, 5, 5, 5, 6, 4, 3, 6, 5, 7, 6, 6, 5, 5, 5, 4, 5, 5, 6, 7, 6, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -font.Cooper\ Black.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G2\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ Ultra\ Bold.widths=7, 8, 6, 8, 7, 6, 8, 8, 4, 5, 8, 4, 12, 8, 7, 8, 8, 7, 6, 6, 8, 7, 10, 8, 7, 7, 10, 9, 8, 9, 7, 7, 9, 10, 4, 6, 9, 7, 11, 9, 9, 8, 9, 9, 7, 7, 9, 8, 12, 10, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -font.Bitstream\ Vera\ Serif.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Oblique.height=14 -font.Elephant.height=13 -font.Eurostile\ Bold.height=14 -font.American\ Uncial.widths=8, 7, 7, 9, 8, 8, 8, 8, 4, 6, 7, 5, 13, 8, 8, 8, 8, 8, 6, 7, 8, 8, 12, 9, 8, 8, 8, 7, 7, 9, 8, 8, 8, 8, 4, 6, 7, 5, 13, 8, 8, 8, 8, 8, 6, 7, 8, 8, 12, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.Arial\ Narrow\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Centaur.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Monotype\ Corsiva.height=12 -font.Bookman\ Old\ Style.height=13 -font.Wingdings.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Lucida\ Sans\ Demibold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT\ Condensed.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Mono.height=13 -font.Times\ New\ Roman.height=13 -font.Arial\ Narrow\ Special\ G2\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Matura\ MT\ Script\ Capitals.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Calisto\ MT\ Bold.height=14 -font.Bitstream\ Vera\ Sans\ Mono\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.serif.italic.widths=6, 6, 5, 6, 5, 4, 6, 6, 4, 4, 5, 4, 8, 6, 6, 6, 6, 5, 5, 4, 6, 5, 8, 5, 5, 5, 7, 7, 8, 8, 7, 7, 8, 8, 4, 5, 8, 7, 9, 8, 8, 7, 8, 7, 6, 7, 8, 7, 10, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Bauhaus\ 93.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.dialog.bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Onyx.height=11 -font.Playbill.height=11 -font.Tahoma\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Handwriting\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tahoma.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.monospaced.italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Calisto\ MT\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Georgia\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Georgia\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Kino\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.monospaced.plain.height=14 -font.Eurostile.widths=6, 6, 6, 6, 6, 4, 6, 6, 3, 3, 5, 3, 9, 6, 6, 6, 6, 5, 6, 4, 6, 5, 8, 5, 5, 5, 7, 7, 7, 8, 6, 6, 7, 8, 3, 6, 7, 6, 10, 8, 7, 7, 8, 7, 7, 6, 8, 7, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Regular.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Script\ MT\ Bold.height=13 -font.Tahoma.height=13 -font.Bookshelf\ Symbol\ 4.height=13 -font.dialog.bolditalic.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 3, 6, 6, 8, 6, 6, 5, 7, 7, 7, 7, 7, 6, 8, 7, 3, 6, 7, 6, 9, 7, 8, 7, 8, 7, 7, 6, 7, 7, 9, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Rockwell\ Extra\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Maiandra\ GD\ Demi\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Enviro.height=13 -font.Abadi\ MT\ Condensed\ Light.height=12 -font.Centaur.height=12 -font.Tw\ Cen\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Garamond.widths=5, 6, 5, 5, 5, 3, 5, 6, 3, 3, 5, 3, 8, 6, 5, 6, 5, 3, 4, 3, 6, 5, 7, 5, 5, 5, 7, 7, 7, 8, 7, 6, 7, 8, 4, 4, 7, 6, 9, 7, 8, 6, 8, 7, 5, 6, 7, 6, 9, 6, 7, 7, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, -font.Bell\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Maiandra\ GD\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Stop.height=9 -font.Andy\ Bold.height=14 -font.Palatino\ Linotype.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Symbol.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Courier\ New\ Bold.height=14 -font.Haettenschweiler.height=12 -font.Maiandra\ GD.height=13 -font.Franklin\ Gothic\ Heavy\ Italic.height=14 -font.dialoginput.bold.height=14 -font.OCR\ A\ Extended.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Verdana\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.MT\ Extra.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Italic.height=14 -font.Script\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Georgia\ Ref.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Sans\ Typewriter\ Regular.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookman\ Old\ Style\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.sansserif.bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Trebuchet\ MS\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Californian\ FB\ Italic.height=14 -font.Bernard\ MT\ Condensed.height=13 -font.Arial\ Special\ G1\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Comic\ Sans\ MS.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Parade.widths=6, 7, 6, 7, 6, 4, 6, 7, 4, 4, 6, 4, 9, 7, 6, 6, 7, 5, 5, 4, 7, 7, 9, 7, 8, 6, 8, 7, 7, 8, 7, 7, 8, 8, 4, 7, 7, 6, 10, 8, 8, 7, 7, 7, 7, 7, 8, 9, 11, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookman\ Old\ Style\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Jester\ Regular.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Century\ Schoolbook.height=13 -font.Lucida\ Sans\ Typewriter\ Oblique.height=14 -font.Eurostile\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans\ Mono\ Bold.height=14 -font.Garamond\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Medium\ Cond.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.dialoginput.plain.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana\ Ref.widths=8, 8, 6, 8, 8, 5, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 8, 5, 7, 5, 8, 7, 8, 8, 7, 7, 8, 8, 9, 9, 7, 7, 9, 9, 6, 6, 8, 7, 10, 8, 10, 8, 10, 9, 8, 8, 9, 8, 12, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.Papyrus.widths=6, 8, 6, 7, 7, 5, 6, 7, 4, 4, 6, 4, 10, 7, 7, 6, 7, 5, 5, 5, 7, 5, 6, 5, 6, 5, 11, 10, 11, 11, 11, 8, 11, 11, 4, 8, 10, 8, 11, 10, 13, 8, 12, 9, 11, 11, 11, 9, 12, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.OCRB.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Matisse\ ITC.widths=5, 5, 6, 5, 5, 5, 5, 5, 3, 5, 7, 5, 12, 8, 5, 5, 5, 5, 5, 5, 6, 9, 10, 5, 5, 5, 5, 5, 4, 5, 4, 5, 5, 5, 3, 5, 6, 5, 9, 7, 5, 6, 6, 6, 4, 6, 5, 5, 7, 7, 8, 5, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, -font.Arial\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Special\ G2\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tempus\ Sans\ ITC.widths=5, 6, 5, 6, 6, 4, 6, 6, 4, 4, 6, 4, 10, 7, 7, 6, 6, 4, 4, 5, 7, 6, 8, 6, 6, 5, 9, 6, 7, 8, 6, 6, 8, 9, 4, 5, 8, 6, 10, 9, 9, 7, 9, 7, 5, 6, 8, 8, 11, 7, 7, 7, 8, 5, 7, 6, 7, 6, 6, 6, 6, 6, -font.Gill\ Sans\ MT.height=13 -font.Arial\ Narrow\ Special\ G1\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gill\ Sans\ MT\ Bold.height=14 -font.Century\ Gothic\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Onyx.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Modern\ No.\ 20.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Maiandra\ GD\ Demi\ Bold.height=14 -font.Garamond.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Condensed\ Extra\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Georgia\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Italic.height=14 -font.Bitstream\ Vera\ Sans\ Bold\ Oblique.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.serif.plain.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Special\ G1\ Italic.height=14 -font.Gradl.height=11 -font.Book\ Antiqua\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Calisto\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Palatino\ Linotype\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Goudy\ Stout.height=15 -font.Algerian.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eras\ Bold\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Stop.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Engravers\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Courier\ New\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Ransom.widths=6, 7, 5, 7, 5, 4, 3, 5, 5, 3, 6, 3, 6, 6, 7, 6, 5, 4, 4, 3, 6, 4, 8, 16, 4, 9, 6, 6, 8, 8, 4, 11, 7, 8, 5, 6, 8, 7, 6, 9, 6, 3, 9, 5, 7, 8, 5, 5, 11, 8, 5, 9, 8, 4, 4, 5, 4, 4, 3, 8, 10, 7, -font.Gill\ Sans\ MT\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Pristina.height=13 -font.Old\ English\ Text\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Courier\ New.height=12 -font.Arial\ Narrow\ Special\ G1.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Verdana\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Eras\ Medium\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Garamond\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.MS\ Outlook.height=12 -font.serif.bolditalic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Gradl.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eras\ Light\ ITC.widths=6, 7, 6, 7, 6, 4, 7, 7, 3, 3, 5, 3, 9, 7, 7, 7, 7, 4, 5, 4, 7, 6, 9, 5, 5, 5, 7, 7, 7, 8, 6, 6, 8, 8, 3, 5, 6, 6, 9, 8, 9, 6, 9, 6, 5, 6, 8, 7, 11, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Palace\ Script\ MT.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Footlight\ MT\ Light.height=10 -font.Courier\ New\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tw\ Cen\ MT\ Medium\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Brush\ Script\ MT\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Century\ Schoolbook\ Italic.height=14 -font.Times\ New\ Roman\ Special\ G1.height=16 -font.OpenSymbol.height=14 -font.Bitstream\ Vera\ Sans\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Placard\ Condensed.height=14 -font.Californian\ FB.height=13 -font.Bell\ MT\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Century\ Gothic\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Wingdings\ 2.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Britannic\ Bold.widths=5, 5, 5, 5, 5, 3, 5, 6, 3, 3, 5, 3, 8, 6, 5, 5, 5, 4, 5, 3, 6, 4, 7, 5, 5, 4, 5, 6, 6, 7, 5, 5, 6, 7, 3, 4, 6, 5, 7, 6, 6, 6, 6, 6, 5, 5, 6, 5, 8, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.dialog.italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bitstream\ Vera\ Sans.height=13 -font.Arial\ Narrow\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Palatino\ Linotype\ Bold.height=14 -font.Goudy\ Old\ Style\ Bold.height=14 -font.sansserif.italic.height=14 -font.Arial\ Black\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Perpetua\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Enviro.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Titling\ MT\ Bold.height=14 -font.Eras\ Demi\ ITC.widths=6, 6, 5, 6, 6, 3, 6, 6, 3, 3, 5, 3, 9, 6, 6, 6, 6, 4, 4, 4, 6, 5, 9, 6, 5, 5, 8, 7, 6, 8, 6, 6, 8, 8, 3, 5, 7, 5, 9, 8, 8, 6, 8, 6, 5, 6, 8, 7, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Arial\ Narrow.height=13 -font.Blackadder\ ITC.widths=5, 5, 4, 5, 4, 4, 5, 5, 3, 4, 5, 3, 6, 5, 4, 5, 5, 4, 4, 4, 6, 5, 6, 5, 5, 5, 9, 9, 9, 9, 9, 7, 9, 10, 6, 7, 11, 8, 13, 9, 9, 8, 11, 10, 8, 6, 11, 10, 12, 11, 9, 10, 5, 4, 4, 4, 5, 5, 5, 5, 5, 5, -font.Times\ New\ Roman\ Bold\ Italic.height=14 -font.monospaced.bold.widths=6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.monospaced.bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Lucida\ Sans\ Typewriter\ Bold\ Oblique.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Haettenschweiler.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.American\ Uncial.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookman\ Old\ Style\ Italic.height=14 -font.Calisto\ MT\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.sansserif.plain.height=14 -font.Comic\ Sans\ MS.height=14 -font.Bitstream\ Vera\ Serif\ Bold.height=14 -font.Arial\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tw\ Cen\ MT\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Rockwell\ Condensed\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Georgia\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bookshelf\ Symbol\ 2.widths=5, 5, 5, 7, 7, 9, 7, 7, 3, 3, 4, 3, 10, 5, 9, 9, 9, 9, 6, 4, 7, 9, 6, 4, 4, 5, 7, 9, 6, 7, 7, 9, 7, 8, 9, 9, 5, 7, 10, 7, 9, 9, 9, 4, 6, 8, 8, 9, 9, 9, 9, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -font.serif.plain.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Narrow\ Special\ G1\ Bold.height=14 -font.Arial\ Special\ G1\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.OCRB.height=15 -font.Lucida\ Fax\ Regular.height=14 -font.Copperplate\ Gothic\ Bold.height=12 -font.Maiandra\ GD\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Special\ G2\ Bold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Brush\ Script\ MT\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Book\ Antiqua\ Bold.height=14 -font.Pepita\ MT.height=12 -font.Eras\ Bold\ ITC.height=13 -font.Franklin\ Gothic\ Demi.height=13 -font.Courier\ New\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Tw\ Cen\ MT\ Condensed\ Bold.height=14 -font.Harlow\ Solid\ Italic\ Italic.height=14 -font.Century\ Schoolbook\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Courier\ New\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Times\ New\ Roman\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Palatino\ Linotype\ Italic.height=14 -font.Monotype\ Sorts.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Fax\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Franklin\ Gothic\ Medium\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Impact.widths=6, 6, 6, 6, 6, 4, 6, 6, 4, 4, 6, 4, 8, 6, 6, 6, 6, 5, 6, 4, 6, 6, 8, 4, 5, 5, 6, 7, 7, 7, 5, 5, 7, 7, 4, 4, 6, 5, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 5, 6, 5, 6, 6, 6, 6, 6, 5, 6, 6, -font.Arial\ Special\ G2\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Courier\ New.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Arial\ Narrow\ Special\ G2\ Bold.height=14 -font.Times\ New\ Roman\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Lucida\ Bright\ Demibold\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Webdings.height=10 -font.Arial\ Black.widths=8, 8, 8, 8, 8, 5, 8, 8, 4, 4, 8, 4, 11, 8, 8, 8, 8, 5, 7, 5, 8, 7, 10, 8, 7, 7, 9, 9, 9, 9, 8, 8, 9, 9, 5, 8, 9, 8, 10, 9, 9, 8, 9, 9, 8, 8, 9, 9, 11, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.Lucida\ Console.widths=7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Elephant.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Stencil.widths=7, 8, 7, 7, 7, 7, 7, 9, 5, 6, 8, 6, 9, 8, 7, 7, 7, 8, 7, 7, 8, 7, 9, 7, 7, 6, 7, 8, 7, 7, 7, 7, 7, 9, 5, 6, 8, 6, 9, 8, 7, 7, 7, 8, 7, 7, 8, 7, 9, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Gill\ Sans\ MT\ Condensed.widths=4, 5, 4, 5, 4, 3, 4, 5, 3, 3, 4, 3, 6, 5, 4, 5, 5, 4, 4, 3, 5, 4, 5, 4, 4, 4, 5, 5, 4, 5, 5, 4, 5, 5, 3, 3, 5, 4, 6, 5, 5, 5, 5, 5, 4, 4, 5, 4, 7, 5, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Georgia.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Eras\ Demi\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bookshelf\ Symbol\ 3.height=14 -font.Microsoft\ Sans\ Serif.height=13 -font.Arial\ Italic.height=14 -font.Mercurius\ Script\ MT\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.sansserif.bolditalic.height=14 -font.serif.italic.height=14 -font.Vivaldi\ Italic.height=14 -font.Pacmania.widths=9, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, -font.Lucida\ Fax\ Demibold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.ProFont.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tw\ Cen\ MT\ Condensed\ Extra\ Bold.widths=5, 5, 3, 5, 4, 3, 5, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 3, 4, 3, 5, 4, 6, 5, 4, 4, 5, 5, 4, 5, 4, 4, 6, 6, 3, 4, 5, 4, 7, 6, 6, 5, 6, 5, 4, 4, 6, 6, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Arial.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 4, 6, 3, 9, 6, 6, 6, 6, 4, 6, 3, 6, 7, 9, 6, 5, 5, 7, 7, 7, 7, 7, 6, 8, 7, 3, 6, 7, 6, 9, 7, 8, 7, 8, 7, 7, 5, 7, 7, 9, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Bell\ MT\ Bold.height=14 -font.Calisto\ MT\ Bold\ Italic.height=14 -font.Times\ New\ Roman\ Special\ G1\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Beesknees\ ITC.height=13 -font.Verdana\ Bold.height=14 -font.Kristen\ ITC.widths=7, 7, 7, 7, 7, 6, 6, 7, 4, 4, 7, 4, 9, 7, 7, 7, 7, 5, 6, 6, 7, 6, 9, 7, 5, 6, 10, 8, 9, 10, 8, 7, 9, 10, 5, 7, 9, 8, 12, 10, 10, 8, 10, 8, 7, 8, 10, 8, 11, 8, 8, 10, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Palatino\ Linotype.widths=5, 6, 5, 6, 5, 4, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 4, 3, 6, 5, 8, 5, 5, 5, 8, 7, 7, 8, 6, 6, 8, 8, 4, 4, 8, 6, 10, 8, 8, 7, 8, 7, 6, 8, 8, 8, 10, 7, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.dialoginput.plain.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Kunstler\ Script.widths=4, 4, 3, 4, 3, 3, 4, 5, 3, 3, 4, 3, 7, 5, 3, 5, 4, 3, 3, 3, 4, 4, 6, 4, 5, 4, 9, 10, 9, 10, 8, 8, 11, 9, 7, 6, 9, 9, 9, 9, 8, 8, 8, 10, 7, 8, 9, 8, 10, 8, 8, 8, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, -font.Lucida\ Sans\ Typewriter\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Arial\ Rounded\ MT\ Bold.height=13 -font.Arial\ Black\ Italic.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Mercurius\ Script\ MT\ Bold.widths=6, 6, 4, 6, 4, 4, 6, 5, 4, 4, 5, 4, 8, 5, 5, 6, 6, 4, 4, 4, 6, 5, 8, 6, 6, 5, 8, 8, 7, 8, 7, 7, 7, 9, 5, 7, 8, 7, 11, 9, 7, 8, 7, 8, 6, 8, 9, 7, 11, 8, 8, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Webdings.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Jester\ Regular.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.sansserif.bold.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 4, 6, 3, 9, 6, 6, 6, 6, 4, 6, 3, 6, 7, 9, 6, 5, 5, 7, 7, 7, 7, 7, 6, 8, 7, 3, 6, 7, 6, 9, 7, 8, 7, 8, 7, 7, 5, 7, 7, 9, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -font.Desdemona.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Ransom\ Italic.height=14 -font.Elephant\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Verdana\ Bold\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Tahoma\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Palatino\ Linotype\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Times\ New\ Roman\ Special\ G2\ Bold.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Garamond.height=12 -font.Gill\ Sans\ MT\ Italic.widths=7, 7, 7, 7, 7, 4, 7, 7, 4, 4, 5, 4, 10, 7, 7, 7, 7, 4, 5, 4, 7, 6, 8, 6, 6, 6, 8, 8, 8, 8, 8, 7, 9, 8, 4, 6, 8, 7, 10, 8, 9, 8, 9, 8, 8, 8, 8, 8, 10, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -font.Bitstream\ Vera\ Sans\ Oblique.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Maiandra\ GD\ Italic.height=14 -font.Abadi\ MT\ Condensed\ Extra\ Bold.height=12 -font.Copperplate\ Gothic\ Light.height=12 -font.Lucida\ Bright\ Regular.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Bradley\ Hand\ ITC.widths=6, 6, 5, 6, 5, 5, 7, 6, 4, 4, 7, 4, 10, 7, 5, 6, 7, 5, 5, 4, 7, 6, 8, 6, 7, 6, 8, 8, 7, 7, 7, 6, 8, 8, 4, 4, 8, 7, 10, 9, 8, 7, 8, 8, 8, 7, 8, 7, 11, 7, 8, 10, 6, 6, 7, 7, 7, 7, 7, 7, 6, 6, -font.dialog.plain.height=14 -font.Arial\ Special\ G2.widths=8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -font.Franklin\ Gothic\ Medium.height=13 -font.Arial\ Narrow\ Special\ G2.widths=10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -font.Lucida\ Bright\ Italic.height=14 -font.Runic\ MT\ Condensed.height=12 -font.Imprint\ MT\ Shadow.widths=5, 7, 5, 7, 5, 4, 6, 7, 4, 4, 6, 4, 10, 7, 6, 7, 7, 5, 5, 4, 7, 6, 9, 6, 6, 5, 8, 8, 8, 10, 8, 8, 9, 10, 5, 5, 9, 8, 10, 9, 9, 8, 9, 9, 7, 8, 9, 8, 11, 9, 8, 8, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, -font.monospaced.bolditalic.height=14 -font.Verdana\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua.widths=5, 6, 5, 6, 5, 3, 5, 6, 3, 3, 6, 3, 8, 6, 6, 6, 6, 4, 4, 3, 6, 5, 8, 6, 5, 5, 7, 6, 6, 7, 5, 5, 7, 8, 4, 4, 7, 5, 9, 7, 7, 5, 7, 7, 5, 6, 7, 6, 9, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -font.Matura\ MT\ Script\ Capitals.height=14 -font.Parade.height=12 -font.Jester\ Regular.height=14 -font.Blackadder\ ITC.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Goudy\ Old\ Style\ Bold.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Perpetua\ Italic.height=14 -font.Arial\ Narrow\ Special\ G2.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - -font.Something.height=13 -font.Something.characters=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -font.Something.widths=6, 6, 6, 6, 6, 3, 6, 6, 3, 4, 6, 3, 9, 6, 6, 6, 6, 4, 6, 3, 6, 7, 9, 6, 5, 5, 7, 7, 7, 7, 7, 6, 8, 7, 3, 6, 7, 6, 9, 7, 8, 7, 8, 7, 7, 5, 7, 7, 9, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, diff --git a/trunk/src/resources/main/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml b/trunk/src/resources/main/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml deleted file mode 100644 index 4a3a0701d..000000000 --- a/trunk/src/resources/main/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml +++ /dev/null @@ -1,19906 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/src/resources/main/org/apache/poi/ss/formula/function/functionMetadata-asGenerated.txt b/trunk/src/resources/main/org/apache/poi/ss/formula/function/functionMetadata-asGenerated.txt deleted file mode 100644 index b56f65e23..000000000 --- a/trunk/src/resources/main/org/apache/poi/ss/formula/function/functionMetadata-asGenerated.txt +++ /dev/null @@ -1,285 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Created by (org.apache.poi.hssf.record.formula.function.ExcelFileFormatDocFunctionExtractor) -# from source file 'excelfileformat.odt' (size=356107, md5=0x8f789cb6e75594caf068f8e193004ef4) -# -#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote ) - -# Built-In Sheet Functions in BIFF2 -0 COUNT 0 30 V R -1 IF 2 3 R V R R -2 ISNA 1 1 V V -3 ISERROR 1 1 V V -4 SUM 0 30 V R -5 AVERAGE 1 30 V R -6 MIN 1 30 V R -7 MAX 1 30 V R -8 ROW 0 1 V R -9 COLUMN 0 1 V R -10 NA 0 0 V - -11 NPV 2 30 V V R -12 STDEV 1 30 V R -13 DOLLAR 1 2 V V V -14 FIXED 2 2 V V V x -15 SIN 1 1 V V -16 COS 1 1 V V -17 TAN 1 1 V V -18 ATAN 1 1 V V -19 PI 0 0 V - -20 SQRT 1 1 V V -21 EXP 1 1 V V -22 LN 1 1 V V -23 LOG10 1 1 V V -24 ABS 1 1 V V -25 INT 1 1 V V -26 SIGN 1 1 V V -27 ROUND 2 2 V V V -28 LOOKUP 2 3 V V R R -29 INDEX 2 4 R R V V V -30 REPT 2 2 V V V -31 MID 3 3 V V V V -32 LEN 1 1 V V -33 VALUE 1 1 V V -34 TRUE 0 0 V - -35 FALSE 0 0 V - -36 AND 1 30 V R -37 OR 1 30 V R -38 NOT 1 1 V V -39 MOD 2 2 V V V -40 DCOUNT 3 3 V R R R -41 DSUM 3 3 V R R R -42 DAVERAGE 3 3 V R R R -43 DMIN 3 3 V R R R -44 DMAX 3 3 V R R R -45 DSTDEV 3 3 V R R R -46 VAR 1 30 V R -47 DVAR 3 3 V R R R -48 TEXT 2 2 V V V -49 LINEST 1 2 A R R x -50 TREND 1 3 A R R R x -51 LOGEST 1 2 A R R x -52 GROWTH 1 3 A R R R x -56 PV 3 5 V V V V V V -# Built-In Sheet Functions in BIFF2 -57 FV 3 5 V V V V V V -58 NPER 3 5 V V V V V V -59 PMT 3 5 V V V V V V -60 RATE 3 6 V V V V V V V -61 MIRR 3 3 V R V V -62 IRR 1 2 V R V -63 RAND 0 0 V - x -64 MATCH 2 3 V V R R -65 DATE 3 3 V V V V -66 TIME 3 3 V V V V -67 DAY 1 1 V V -68 MONTH 1 1 V V -69 YEAR 1 1 V V -70 WEEKDAY 1 1 V V x -71 HOUR 1 1 V V -72 MINUTE 1 1 V V -73 SECOND 1 1 V V -74 NOW 0 0 V - x -75 AREAS 1 1 V R -76 ROWS 1 1 V R -77 COLUMNS 1 1 V R -78 OFFSET 3 5 R R V V V V x -82 SEARCH 2 3 V V V V -83 TRANSPOSE 1 1 A A -86 TYPE 1 1 V V -97 ATAN2 2 2 V V V -98 ASIN 1 1 V V -99 ACOS 1 1 V V -100 CHOOSE 2 30 R V R -101 HLOOKUP 3 3 V V R R x -102 VLOOKUP 3 3 V V R R x -105 ISREF 1 1 V R -109 LOG 1 2 V V V -111 CHAR 1 1 V V -112 LOWER 1 1 V V -113 UPPER 1 1 V V -114 PROPER 1 1 V V -115 LEFT 1 2 V V V -116 RIGHT 1 2 V V V -117 EXACT 2 2 V V V -118 TRIM 1 1 V V -119 REPLACE 4 4 V V V V V -120 SUBSTITUTE 3 4 V V V V V -121 CODE 1 1 V V -124 FIND 2 3 V V V V -125 CELL 1 2 V V R x -126 ISERR 1 1 V V -127 ISTEXT 1 1 V V -128 ISNUMBER 1 1 V V -129 ISBLANK 1 1 V V -130 T 1 1 V R -131 N 1 1 V R -140 DATEVALUE 1 1 V V -141 TIMEVALUE 1 1 V V -142 SLN 3 3 V V V V -143 SYD 4 4 V V V V V -144 DDB 4 5 V V V V V V -148 INDIRECT 1 2 R V V x -162 CLEAN 1 1 V V -163 MDETERM 1 1 V A -164 MINVERSE 1 1 A A -165 MMULT 2 2 A A A -167 IPMT 4 6 V V V V V V V -168 PPMT 4 6 V V V V V V V -169 COUNTA 0 30 V R -183 PRODUCT 0 30 V R -184 FACT 1 1 V V -189 DPRODUCT 3 3 V R R R -190 ISNONTEXT 1 1 V V -193 STDEVP 1 30 V R -194 VARP 1 30 V R -195 DSTDEVP 3 3 V R R R -196 DVARP 3 3 V R R R -197 TRUNC 1 1 V V x -198 ISLOGICAL 1 1 V V -199 DCOUNTA 3 3 V R R R -# New Built-In Sheet Functions in BIFF3 -49 LINEST 1 4 A R R V V x -50 TREND 1 4 A R R R V x -51 LOGEST 1 4 A R R V V x -52 GROWTH 1 4 A R R R V x -197 TRUNC 1 2 V V V x -204 YEN 1 2 V V V x -205 FINDB 2 3 V V V V -206 SEARCHB 2 3 V V V V -207 REPLACEB 4 4 V V V V V -208 LEFTB 1 2 V V V -209 RIGHTB 1 2 V V V -210 MIDB 3 3 V V V V -211 LENB 1 1 V V -212 ROUNDUP 2 2 V V V -213 ROUNDDOWN 2 2 V V V -214 ASC 1 1 V V -215 JIS 1 1 V V x -219 ADDRESS 2 5 V V V V V V -220 DAYS360 2 2 V V V x -221 TODAY 0 0 V - x -222 VDB 5 7 V V V V V V V V -227 MEDIAN 1 30 V R ... -228 SUMPRODUCT 1 30 V A ... -229 SINH 1 1 V V -230 COSH 1 1 V V -231 TANH 1 1 V V -232 ASINH 1 1 V V -233 ACOSH 1 1 V V -234 ATANH 1 1 V V -235 DGET 3 3 V R R R -244 INFO 1 1 V V -# New Built-In Sheet Functions in BIFF4 -14 FIXED 2 3 V V V V x -204 USDOLLAR 1 2 V V V x -215 DBCS 1 1 V V x -216 RANK 2 3 V V R V -247 DB 4 5 V V V V V V -252 FREQUENCY 2 2 A R R -261 ERROR.TYPE 1 1 V V -269 AVEDEV 1 30 V R ... -270 BETADIST 3 5 V V V V V V -271 GAMMALN 1 1 V V -272 BETAINV 3 5 V V V V V V -273 BINOMDIST 4 4 V V V V V -274 CHIDIST 2 2 V V V -275 CHIINV 2 2 V V V -276 COMBIN 2 2 V V V -277 CONFIDENCE 3 3 V V V V -278 CRITBINOM 3 3 V V V V -279 EVEN 1 1 V V -280 EXPONDIST 3 3 V V V V -281 FDIST 3 3 V V V V -282 FINV 3 3 V V V V -283 FISHER 1 1 V V -284 FISHERINV 1 1 V V -285 FLOOR 2 2 V V V -286 GAMMADIST 4 4 V V V V V -287 GAMMAINV 3 3 V V V V -288 CEILING 2 2 V V V -289 HYPGEOMDIST 4 4 V V V V V -290 LOGNORMDIST 3 3 V V V V -291 LOGINV 3 3 V V V V -292 NEGBINOMDIST 3 3 V V V V -293 NORMDIST 4 4 V V V V V -294 NORMSDIST 1 1 V V -295 NORMINV 3 3 V V V V -296 NORMSINV 1 1 V V -297 STANDARDIZE 3 3 V V V V -298 ODD 1 1 V V -299 PERMUT 2 2 V V V -300 POISSON 3 3 V V V V -301 TDIST 3 3 V V V V -302 WEIBULL 4 4 V V V V V -303 SUMXMY2 2 2 V A A -304 SUMX2MY2 2 2 V A A -305 SUMX2PY2 2 2 V A A -306 CHITEST 2 2 V A A -307 CORREL 2 2 V A A -308 COVAR 2 2 V A A -309 FORECAST 3 3 V V A A -310 FTEST 2 2 V A A -311 INTERCEPT 2 2 V A A -312 PEARSON 2 2 V A A -313 RSQ 2 2 V A A -314 STEYX 2 2 V A A -315 SLOPE 2 2 V A A -316 TTEST 4 4 V A A V V -317 PROB 3 4 V A A V V -318 DEVSQ 1 30 V R ... -319 GEOMEAN 1 30 V R ... -320 HARMEAN 1 30 V R ... -321 SUMSQ 0 30 V R ... -322 KURT 1 30 V R ... -323 SKEW 1 30 V R ... -324 ZTEST 2 3 V R V V -325 LARGE 2 2 V R V -326 SMALL 2 2 V R V -327 QUARTILE 2 2 V R V -328 PERCENTILE 2 2 V R V -329 PERCENTRANK 2 3 V R V V -330 MODE 1 30 V A -331 TRIMMEAN 2 2 V R V -332 TINV 2 2 V V V -# New Built-In Sheet Functions in BIFF5 -70 WEEKDAY 1 2 V V V x -101 HLOOKUP 3 4 V V R R V x -102 VLOOKUP 3 4 V V R R V x -220 DAYS360 2 3 V V V V x -336 CONCATENATE 0 30 V V -337 POWER 2 2 V V V -342 RADIANS 1 1 V V -343 DEGREES 1 1 V V -344 SUBTOTAL 2 30 V V R -345 SUMIF 2 3 V R V R -346 COUNTIF 2 2 V R V -347 COUNTBLANK 1 1 V R -350 ISPMT 4 4 V V V V V -351 DATEDIF 3 3 V V V V -352 DATESTRING 1 1 V V -353 NUMBERSTRING 2 2 V V V -354 ROMAN 1 2 V V V -# New Built-In Sheet Functions in BIFF8 -358 GETPIVOTDATA 2 30 -359 HYPERLINK 1 2 V V V -360 PHONETIC 1 1 V R -361 AVERAGEA 1 30 V R ... -362 MAXA 1 30 V R ... -363 MINA 1 30 V R ... -364 STDEVPA 1 30 V R ... -365 VARPA 1 30 V R ... -366 STDEVA 1 30 V R ... -367 VARA 1 30 V R ... diff --git a/trunk/src/resources/main/org/apache/poi/ss/formula/function/functionMetadata.txt b/trunk/src/resources/main/org/apache/poi/ss/formula/function/functionMetadata.txt deleted file mode 100644 index f9e91a1e3..000000000 --- a/trunk/src/resources/main/org/apache/poi/ss/formula/function/functionMetadata.txt +++ /dev/null @@ -1,287 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Created by (org.apache.poi.hssf.record.formula.function.ExcelFileFormatDocFunctionExtractor) -# from source file 'excelfileformat.odt' (size=356107, md5=0x8f789cb6e75594caf068f8e193004ef4) -# ! + some manual edits ! -# See https://issues.apache.org/ooo/show_bug.cgi?id=125837 for difference in "FIXED" -# -#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote ) - -# Built-In Sheet Functions in BIFF2 -0 COUNT 0 30 V R -1 IF 2 3 R V R R -2 ISNA 1 1 V V -3 ISERROR 1 1 V V -4 SUM 0 30 V R -5 AVERAGE 1 30 V R -6 MIN 1 30 V R -7 MAX 1 30 V R -8 ROW 0 1 V R -9 COLUMN 0 1 V R -10 NA 0 0 V - -11 NPV 2 30 V V R -12 STDEV 1 30 V R -13 DOLLAR 1 2 V V V -14 FIXED 2 2 V V V x -15 SIN 1 1 V V -16 COS 1 1 V V -17 TAN 1 1 V V -18 ATAN 1 1 V V -19 PI 0 0 V - -20 SQRT 1 1 V V -21 EXP 1 1 V V -22 LN 1 1 V V -23 LOG10 1 1 V V -24 ABS 1 1 V V -25 INT 1 1 V V -26 SIGN 1 1 V V -27 ROUND 2 2 V V V -28 LOOKUP 2 3 V V R R -29 INDEX 2 4 R R V V V -30 REPT 2 2 V V V -31 MID 3 3 V V V V -32 LEN 1 1 V V -33 VALUE 1 1 V V -34 TRUE 0 0 V - -35 FALSE 0 0 V - -36 AND 1 30 V R -37 OR 1 30 V R -38 NOT 1 1 V V -39 MOD 2 2 V V V -40 DCOUNT 3 3 V R R R -41 DSUM 3 3 V R R R -42 DAVERAGE 3 3 V R R R -43 DMIN 3 3 V R R R -44 DMAX 3 3 V R R R -45 DSTDEV 3 3 V R R R -46 VAR 1 30 V R -47 DVAR 3 3 V R R R -48 TEXT 2 2 V V V -49 LINEST 1 2 A R R x -50 TREND 1 3 A R R R x -51 LOGEST 1 2 A R R x -52 GROWTH 1 3 A R R R x -56 PV 3 5 V V V V V V -# Built-In Sheet Functions in BIFF2 -57 FV 3 5 V V V V V V -58 NPER 3 5 V V V V V V -59 PMT 3 5 V V V V V V -60 RATE 3 6 V V V V V V V -61 MIRR 3 3 V A V V -62 IRR 1 2 V A V -63 RAND 0 0 V - x -64 MATCH 2 3 V V R R -65 DATE 3 3 V V V V -66 TIME 3 3 V V V V -67 DAY 1 1 V V -68 MONTH 1 1 V V -69 YEAR 1 1 V V -70 WEEKDAY 1 1 V V x -71 HOUR 1 1 V V -72 MINUTE 1 1 V V -73 SECOND 1 1 V V -74 NOW 0 0 V - x -75 AREAS 1 1 V R -76 ROWS 1 1 V A -77 COLUMNS 1 1 V A -78 OFFSET 3 5 R R V V V V x -82 SEARCH 2 3 V V V V -83 TRANSPOSE 1 1 A A -86 TYPE 1 1 V V -97 ATAN2 2 2 V V V -98 ASIN 1 1 V V -99 ACOS 1 1 V V -100 CHOOSE 2 30 R V R -101 HLOOKUP 3 3 V V R R x -102 VLOOKUP 3 3 V V R R x -105 ISREF 1 1 V R -109 LOG 1 2 V V V -111 CHAR 1 1 V V -112 LOWER 1 1 V V -113 UPPER 1 1 V V -114 PROPER 1 1 V V -115 LEFT 1 2 V V V -116 RIGHT 1 2 V V V -117 EXACT 2 2 V V V -118 TRIM 1 1 V V -119 REPLACE 4 4 V V V V V -120 SUBSTITUTE 3 4 V V V V V -121 CODE 1 1 V V -124 FIND 2 3 V V V V -125 CELL 1 2 V V R x -126 ISERR 1 1 V V -127 ISTEXT 1 1 V V -128 ISNUMBER 1 1 V V -129 ISBLANK 1 1 V V -130 T 1 1 V R -131 N 1 1 V R -140 DATEVALUE 1 1 V V -141 TIMEVALUE 1 1 V V -142 SLN 3 3 V V V V -143 SYD 4 4 V V V V V -144 DDB 4 5 V V V V V V -148 INDIRECT 1 2 R V V x -162 CLEAN 1 1 V V -163 MDETERM 1 1 V A -164 MINVERSE 1 1 A A -165 MMULT 2 2 A A A -167 IPMT 4 6 V V V V V V V -168 PPMT 4 6 V V V V V V V -169 COUNTA 0 30 V R -183 PRODUCT 0 30 V R -184 FACT 1 1 V V -189 DPRODUCT 3 3 V R R R -190 ISNONTEXT 1 1 V V -193 STDEVP 1 30 V R -194 VARP 1 30 V R -195 DSTDEVP 3 3 V R R R -196 DVARP 3 3 V R R R -197 TRUNC 1 1 V V x -198 ISLOGICAL 1 1 V V -199 DCOUNTA 3 3 V R R R -# New Built-In Sheet Functions in BIFF3 -49 LINEST 1 4 A R R V V x -50 TREND 1 4 A R R R V x -51 LOGEST 1 4 A R R V V x -52 GROWTH 1 4 A R R R V x -197 TRUNC 1 2 V V V x -204 YEN 1 2 V V V x -205 FINDB 2 3 V V V V -206 SEARCHB 2 3 V V V V -207 REPLACEB 4 4 V V V V V -208 LEFTB 1 2 V V V -209 RIGHTB 1 2 V V V -210 MIDB 3 3 V V V V -211 LENB 1 1 V V -212 ROUNDUP 2 2 V V V -213 ROUNDDOWN 2 2 V V V -214 ASC 1 1 V V -215 JIS 1 1 V V x -219 ADDRESS 2 5 V V V V V V -220 DAYS360 2 2 V V V x -221 TODAY 0 0 V - x -222 VDB 5 7 V V V V V V V V -227 MEDIAN 1 30 V R ... -228 SUMPRODUCT 1 30 V A ... -229 SINH 1 1 V V -230 COSH 1 1 V V -231 TANH 1 1 V V -232 ASINH 1 1 V V -233 ACOSH 1 1 V V -234 ATANH 1 1 V V -235 DGET 3 3 V R R R -244 INFO 1 1 V V -# New Built-In Sheet Functions in BIFF4 -14 FIXED 1 3 V V V V x -204 USDOLLAR 1 2 V V V x -215 DBCS 1 1 V V x -216 RANK 2 3 V V R V -247 DB 4 5 V V V V V V -252 FREQUENCY 2 2 A R R -261 ERROR.TYPE 1 1 V V -269 AVEDEV 1 30 V R ... -270 BETADIST 3 5 V V V V V V -271 GAMMALN 1 1 V V -272 BETAINV 3 5 V V V V V V -273 BINOMDIST 4 4 V V V V V -274 CHIDIST 2 2 V V V -275 CHIINV 2 2 V V V -276 COMBIN 2 2 V V V -277 CONFIDENCE 3 3 V V V V -278 CRITBINOM 3 3 V V V V -279 EVEN 1 1 V V -280 EXPONDIST 3 3 V V V V -281 FDIST 3 3 V V V V -282 FINV 3 3 V V V V -283 FISHER 1 1 V V -284 FISHERINV 1 1 V V -285 FLOOR 2 2 V V V -286 GAMMADIST 4 4 V V V V V -287 GAMMAINV 3 3 V V V V -288 CEILING 2 2 V V V -289 HYPGEOMDIST 4 4 V V V V V -290 LOGNORMDIST 3 3 V V V V -291 LOGINV 3 3 V V V V -292 NEGBINOMDIST 3 3 V V V V -293 NORMDIST 4 4 V V V V V -294 NORMSDIST 1 1 V V -295 NORMINV 3 3 V V V V -296 NORMSINV 1 1 V V -297 STANDARDIZE 3 3 V V V V -298 ODD 1 1 V V -299 PERMUT 2 2 V V V -300 POISSON 3 3 V V V V -301 TDIST 3 3 V V V V -302 WEIBULL 4 4 V V V V V -303 SUMXMY2 2 2 V A A -304 SUMX2MY2 2 2 V A A -305 SUMX2PY2 2 2 V A A -306 CHITEST 2 2 V A A -307 CORREL 2 2 V A A -308 COVAR 2 2 V A A -309 FORECAST 3 3 V V A A -310 FTEST 2 2 V A A -311 INTERCEPT 2 2 V A A -312 PEARSON 2 2 V A A -313 RSQ 2 2 V A A -314 STEYX 2 2 V A A -315 SLOPE 2 2 V A A -316 TTEST 4 4 V A A V V -317 PROB 3 4 V A A V V -318 DEVSQ 1 30 V R ... -319 GEOMEAN 1 30 V R ... -320 HARMEAN 1 30 V R ... -321 SUMSQ 0 30 V R ... -322 KURT 1 30 V R ... -323 SKEW 1 30 V R ... -324 ZTEST 2 3 V R V V -325 LARGE 2 2 V R V -326 SMALL 2 2 V R V -327 QUARTILE 2 2 V R V -328 PERCENTILE 2 2 V R V -329 PERCENTRANK 2 3 V R V V -330 MODE 1 30 V A -331 TRIMMEAN 2 2 V R V -332 TINV 2 2 V V V -# New Built-In Sheet Functions in BIFF5 -70 WEEKDAY 1 2 V V V x -101 HLOOKUP 3 4 V V R R V x -102 VLOOKUP 3 4 V V R R V x -220 DAYS360 2 3 V V V V x -336 CONCATENATE 0 30 V V -337 POWER 2 2 V V V -342 RADIANS 1 1 V V -343 DEGREES 1 1 V V -344 SUBTOTAL 2 30 V V R -345 SUMIF 2 3 V R V R -346 COUNTIF 2 2 V R V -347 COUNTBLANK 1 1 V R -350 ISPMT 4 4 V V V V V -351 DATEDIF 3 3 V V V V -352 DATESTRING 1 1 V V -353 NUMBERSTRING 2 2 V V V -354 ROMAN 1 2 V V V -# New Built-In Sheet Functions in BIFF8 -358 GETPIVOTDATA 2 30 V V R ... -359 HYPERLINK 1 2 V V V -360 PHONETIC 1 1 V R -361 AVERAGEA 1 30 V R ... -362 MAXA 1 30 V R ... -363 MINA 1 30 V R ... -364 STDEVPA 1 30 V R ... -365 VARPA 1 30 V R ... -366 STDEVA 1 30 V R ... -367 VARA 1 30 V R ... diff --git a/trunk/src/resources/ooxml/org/apache/poi/xslf/usermodel/empty.pptx b/trunk/src/resources/ooxml/org/apache/poi/xslf/usermodel/empty.pptx deleted file mode 100644 index ababa9379..000000000 Binary files a/trunk/src/resources/ooxml/org/apache/poi/xslf/usermodel/empty.pptx and /dev/null differ diff --git a/trunk/src/resources/ooxml/org/apache/poi/xslf/usermodel/notesMaster.xml b/trunk/src/resources/ooxml/org/apache/poi/xslf/usermodel/notesMaster.xml deleted file mode 100644 index 0a8db65bd..000000000 --- a/trunk/src/resources/ooxml/org/apache/poi/xslf/usermodel/notesMaster.xml +++ /dev/null @@ -1,2 +0,0 @@ - -1.7.2013Click to edit Master text stylesSecond levelThird levelFourth levelFifth level‹#› \ No newline at end of file diff --git a/trunk/src/resources/scratchpad/org/apache/poi/hdgf/chunks_parse_cmds.tbl b/trunk/src/resources/scratchpad/org/apache/poi/hdgf/chunks_parse_cmds.tbl deleted file mode 100644 index 7cb715abd..000000000 --- a/trunk/src/resources/scratchpad/org/apache/poi/hdgf/chunks_parse_cmds.tbl +++ /dev/null @@ -1,993 +0,0 @@ -# vsdump: test program to dump and parse content of vsd file -# -# Copyright (C) 2006-2007 Valek Filippov (frob@df.ru) -# -# This file is dual-licensed (GPLv3 and ASLv2). -# -# ======================================================================= -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ======================================================================= -# This program is free software; you can redistribute it and/or -# modify it under the terms of version 3 or later of the GNU General Public -# License as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 -# USA -# ======================================================================= -# -# version 0.0.45 -# -# Need to extend with 'format' field for conversion length (inch->mm), angles(rad->degree) and enums (e.g. -# for aligns -- left/right/justify etc. -# -# The Format description for .tbl file. -# Lines start with # are comments. -# Every list of commands starts with 'start ch_type' -# and ends with 'end'. -# In between start and end are space-separeted lines -# with 'type', 'offset', 'name' values. -# Atm I use 'atoi', so only decimal value is allowed for ch_type, type and offset. -# The possible values for 'type' are: -# 0..7 - flag at bit 0..7 at offset 'offset' -# 8 - 1 byte value -# 9 - 8 bytes IEEE-754 fraction -# 10(a) - name of chunk (we must start with a name atm, because with parse for printing) -# 11(b) - offset to start of blocks -# 12(c) - text block -# 13(d) - some "name" from the list -# 14(e) - one byte "function" from the list -# 15(f) - some "function" from the list -# 16 - string, next byte is length terminating '0' wasn't added to length -# 17 - 'ForeignData' -# 18 - Dump it to file as-is -# 25 - 2 bytes LE -# 26 - 4 bytes LE -# 27 - Tabs? [experimental] -# 21 - offset to start of blocks in version 11 -# 28 - extension for image files [experimental] -# 29 - num of parts and type for OLE [experimental] -# 30 - 3 bytes RGB-color -# 31 - 9 bytes -- 1st is 'Unit', + 8 bytes IEEE-754 fraction - -# Quick workaround for losing of 1st table -start 10 -end - -start 12 -17 0 ForeignData -end - -start 13 -10 0 OLE_Info -29 0 0 -18 0 0 -end - -start 14 -10 0 Text -12 8 0 -18 0 0 -end - -start 16 -10 0 Data1 -12 0 0 -end - -start 17 -10 0 Data2 -12 0 0 -end - -start 18 -10 0 Data3 -12 0 0 -end - -start 21 -10 0 Stream15 -9 53 Center X -9 61 Center Y -18 0 0 -end - -start 24 -10 0 Stream18 -18 0 0 -end - -start 25 -10 0 FaceName -16 24 0 -end - -start 26 -10 0 Stream1a -18 0 0 -end - -start 31 -17 0 OLEData -end - -start 40 -10 0 Unknown 0x28 -9 39 Unknown1 -9 47 Unknown2 -18 0 0 -end - -start 44 -10 0 Unknown 0x2c -18 0 0 -end - -#seems to be text string -start 45 -10 0 Unknown 0x2d -12 0 0 -end - -start 49 -10 0 Stream31 -18 0 0 -end - -start 66 -10 0 Unknown 0x42 -18 0 0 -end - -start 70 -10 0 PageSheet -18 0 0 -end - -start 71 -10 0 Shape ID Type="Group" -18 0 0 -end - -start 72 -10 0 Shape ID Type="Shape" -26 53 LineStyle -26 61 FillStyle -26 69 TextStyle -18 0 0 -end - -start 74 -10 0 StyleSheet -26 53 LineStyle -26 61 FillStyle -26 69 TextStyle -18 0 0 -end - -start 77 -10 0 Shape ID Type="Guide" -18 0 0 -end - - -start 78 -10 0 Shape ID Type="Foreign" -18 0 0 -end - -start 79 -10 0 DocumentSheet -26 53 LineStyle -26 61 FillStyle -26 69 TextStyle -18 0 0 -end - -start 100 -10 0 Unknown 0x64 -18 0 0 -end - -start 101 -10 0 ShapeList -18 0 0 -end - -start 102 -10 0 Unknown 0x66 -18 0 0 -end - -start 103 -10 0 Unknown 0x67 -18 0 0 -end - -start 104 -10 0 PropList -18 0 0 -end - -start 105 -10 0 CharList -18 0 0 -end - -start 106 -10 0 ParaList -18 0 0 -end - -start 107 -10 0 Unknown 0x6b -18 0 0 -end - -start 108 -10 0 GeomList -18 0 0 -end - -start 109 -10 0 Unknown 0x6d -18 0 0 -end - -start 110 -10 0 Unknown 0x6e -18 0 0 -end - -start 111 -10 0 Unknown 0x6f -18 0 0 -end - -start 112 -10 0 Unknown 0x70 -18 0 0 -end - -start 113 -10 0 ConnectionList -18 0 0 -end - -start 114 -10 0 Unknown 0x72 -18 0 0 -end - -start 115 -10 0 Unknown 0x73 -18 0 0 -end - -start 116 -10 0 Unknown 0x74 -18 0 0 -end - -start 117 -10 0 Unknown 0x75 -18 0 0 -end - -start 118 -10 0 Unknown 0x76 -18 0 0 -end - -start 130 -10 0 Unknown 0x82 -18 0 0 -end - -start 131 -10 0 ShapeID -18 0 0 -end - -start 132 -10 0 Event -8 20 TheText -11 36 BlockStarts -21 36 BlockStarts -18 0 0 -end - -start 133 -10 0 Line -31 19 LineWeight -8 28 LineColor -8 33 LinePattern -9 35 Rounding -8 43 EndArrowSize -8 44 BeginArrow -8 45 EndArrow -8 47 BeginArrowSize -1 50 Color -2 50 Pattern -3 50 RoundingCap -4 50 LineEndEnd -5 50 LineEndBegin -6 50 EndSize -7 50 SqueareCap -0 51 BeginSize -11 54 BlockStarts -21 54 BlockStarts -18 0 0 -end - -start 134 -10 0 Fill -8 19 FillForegnd -30 25 FillBkgnd -8 29 FillPattern -30 31 ShdwForegnd -8 35 ShdwBkgnd -8 40 ShdwPattern -31 42 ShapeShdwOffsetX -31 51 ShapeShdwOffsetY -9 69 ShapeShdwScaleFactor -11 44 BlockStarts -21 80 BlockStarts -18 0 0 -end - -start 135 -10 0 TextBlock -31 19 LeftMargin -31 28 RightMargin -31 37 TopMargin -31 46 BottomMargin -8 55 VerticalAlign -30 56 TextBkgnd -9 62 DefaultTabStop -8 82 TextDirection -11 90 BlockStarts -21 111 BlockStarts -18 0 0 -end - -start 136 -10 0 Tabs -11 26 BlocksStart -21 26 BlocksStart -18 0 0 -end - -start 137 -10 0 Geometry -0 19 NoFill -1 19 NoLine -2 19 NoShow -3 19 NoSnap -21 22 BlocksStart -18 0 0 -end - -start 138 -10 0 MoveTo -9 20 X -9 29 Y -11 39 BlocksStart -21 39 BlocksStart -end - -start 139 -10 0 LineTo -9 20 X -9 29 Y -11 39 BlocksStart -21 39 BlocksStart -end - -start 140 -10 0 ArcTo -9 20 X -9 29 Y -9 38 A -11 48 BlocksStart -18 0 0 -end - -start 141 -10 0 InfiniteLine -9 20 X -9 29 Y -9 37 A -9 45 B -11 57 BlocksStart -18 0 0 -end - -start 143 -10 0 Ellipse -9 20 X -9 29 Y -9 38 A -9 47 B -9 56 C -9 65 D -11 75 BlocksStart -18 0 0 -end - -start 144 -10 0 EllipticalArcTo -31 19 X -31 28 Y -31 37 A -31 46 B -31 55 C -31 64 D -11 75 BlocksStart -18 0 0 -end - -start 146 -10 0 PageProps -9 20 PageWidth -9 29 PageHeight -9 38 ShdwOffsetX -9 47 ShdwOffsetY -9 56 PageScale -9 65 DrawingScale -8 73 DrawingSizeType -8 74 DrawingScaleType -0 93 InhibitSnap -11 150 BlockStarts -18 0 0 -end - -start 147 -10 0 StyleProp -8 19 EnableLineProps -8 20 EnableFillProps -8 21 EnableTextProps -8 22 HideForApply -11 26 BlocksStart -21 26 BlocksStart -18 0 0 -end - -start 148 -10 0 Char -25 23 FontNum -30 26 Color -8 29 Transparency*255/100% -0 30 Bold -1 30 Italic -2 30 Underline -3 30 Smallcaps -0 31 AllCaps -1 31 InitCaps -0 32 Subscript -1 32 Superscipt -25 33 Scale*100 % -8 35 LangCode -31 36 Size -25 46 Spacing pt*200 -25 56 AsianFont -25 58 ComplexScriptFont -8 60 LocalizeFont -25 88 LangID -11 54 BlocksStart -21 107 BlocksStart -18 0 0 -end - -start 149 -10 0 Para -31 23 IndFirst -31 32 IndLeft -31 41 IndRight -31 50 SpLine -31 59 SpBefore -31 68 SpAfter -8 77 HorizAlign -8 78 Bullet -11 92 BlockStarts -21 142 BlockStarts -18 0 0 -end - -start 150 -10 0 Tabs -27 0 TabsID -11 48 BlockStarts -18 0 0 -end - -start 151 -10 0 Tabs -27 0 TabsID -11 139 BlockStarts -18 0 0 -end - -start 181 -10 0 Tabs -27 0 TabsID -11 708 BlockStarts -18 0 0 -end - -start 152 -10 0 Foreign -9 20 IndFirst -9 29 IndLeft -9 38 IndRight -9 47 SpLine -28 68 Ext -18 0 0 -end - -start 153 -10 0 Connection -31 19 Width -31 28 Height -31 37 DirX/A -31 46 DirY/B -8 55 Type/C -11 67 BlockStarts -21 67 BlockStarts -18 0 0 -end - -start 155 -10 0 XForm -9 20 PinX -9 29 PinY -9 38 Width -9 47 Height -9 56 LocPinX -9 65 LocPinY -9 74 Angle -8 82 FlipX -8 83 FlipY -8 84 ResizeMode -11 88 BlockStarts -21 88 BlockStarts -18 0 0 -end - -start 156 -10 0 TextXForm -9 20 TxtPinX -9 29 TxtPinY -31 37 TxtWidth -9 47 TxtHeight -9 56 TxtLocPinX -9 65 TxtLocPinY -9 74 TxtAngle -11 88 BlockStarts -21 88 BlockStarts -18 0 0 -end - -start 157 -10 0 XForm1D -9 20 BeginX -9 29 BeginY -9 38 EndX -9 47 EndY -11 57 BlockStarts -21 57 BlockStarts -end - -start 158 -10 0 Scratch -9 20 X -9 29 Y -9 38 A -9 47 B -9 56 C -9 65 D -11 75 BlockStarts -18 0 0 -end - -start 159 -10 0 Alignment -9 20 AlignLeft -9 29 AlignCenter -9 38 AlignRight -9 47 AlignTop -9 56 AlignMiddle -9 65 AlignBottom -11 75 BlockStarts -21 79 BlockStarts -18 0 0 -end - -start 160 -10 0 Protection -8 19 LockWidth -8 20 LockHeight -8 21 LockMoveX -8 22 LockMoveY -8 23 LockAspect -8 24 LockDelete -8 25 LockBegin -8 26 LockEnd -8 27 LockRotate -8 28 LockCrop -8 29 LockVtxEdit -8 30 LockTextEdit -8 31 LockFormat -8 32 LockGroup -8 33 LockCalcWH -8 34 LockSelect -8 35 LockCustProp -11 43 BlockStarts -21 43 BlockStarts -18 0 0 -end - -start 161 -10 0 TextFields -18 0 0 -end - -start 162 -10 0 Control -9 20 X -9 29 Y -9 38 XDyn -9 47 YDyn -8 55 XCon -8 56 YCon -0 57 CanGlue -11 60 BlockStarts -21 60 BlockStarts -18 0 0 -end - -start 163 -10 0 Help -11 49 BlockStarts -21 49 BlockStarts -18 0 0 -end - -start 164 -10 0 Misc -0 19 NoObjHandles -1 19 NonPrinting -2 19 NoCtlHandles -3 19 NoAlignBox -4 19 UpdateAlignBox -5 19 HideText -8 20 DynFeedback -8 21 GlueType -8 22 WalkPreference -25 25 ObjType -0 35 IsDropSource -1 35 NoLiveDynamics -25 37 LangID -11 42 BlockStarts -21 64 BlockStarts -18 0 0 -end - -start 165 -10 0 SplineStart -9 20 X -9 29 Y -9 37 A -9 45 B -9 53 C -8 61 D -11 65 BlockStarts -18 0 0 -end - -start 166 -10 0 SplineKnot -9 20 X -9 29 Y -9 37 A -11 47 BlockStarts -18 0 0 -end - -start 167 -10 0 LayerMem -11 25 BlockStarts -21 25 BlockStarts -18 0 0 -end - -# Transparency 255 - 100% -start 168 -10 0 Layer -30 27 Color -8 31 Transparency -8 33 Visible -8 34 Print -8 35 Active -8 36 Lock -8 37 Snap -8 38 Glue -11 52 BlockStarts -21 52 BlockStarts -18 0 0 -end - -start 169 -10 0 Act -8 40 Checked -8 41 Disabled -0 42 ReadOnly -1 42 Invisible -2 42 BeginGroup -11 47 BlockStarts -21 76 BlockStarts -18 0 0 -end - -start 170 -10 0 Control -9 20 X -9 29 Y -9 38 XDyn -9 47 YDyn -8 55 XBehavior -8 56 YBehavior -0 57 CanGlue -11 66 BlockStarts -21 66 BlockStarts -18 0 0 -end - -start 180 -10 0 User-defined Cells -9 20 Value -11 34 BlockStarts -21 34 BlockStarts -18 0 0 -end - -start 182 -10 0 CustomProps -9 20 Value -8 44 Type -0 46 Invisible -1 46 Ask -11 55 BlockStarts -18 0 0 -end - -start 183 -10 0 RulerGrid -8 19 XRulerDensity -8 20 XRulerDensity -31 21 Unknown1 -31 30 Unknown2 -31 39 XRulerOrigin -31 48 YRulerOrigin -8 57 XGridDensity -8 58 YGridDensity -31 59 XGridSpacing -31 68 YGridSpacing -31 77 XGridOrigin -31 86 YGridOrigin -11 98 BlockStarts -21 98 BlockStarts -18 0 0 -end - -start 185 -10 0 Connection -31 19 Width -31 28 Height -31 37 DirX/A -31 46 DirY/B -8 55 Type/C -11 67 BlockStarts -21 67 BlockStarts -18 0 0 -end - -start 186 -10 0 ConnectionPoints -9 20 Width -9 29 Height -11 79 BlockStarts -18 0 0 -end - -start 188 -10 0 DocProps -25 24 DocLangID -18 0 0 -end - -start 189 -10 0 Image -9 19 Gamma -25 27 Contrast*100 (%) -25 29 Brightness*100 (%) -25 31 Sharpen*100 (%) -25 33 Blur*100 (%) -25 35 Denoise*100 (%) -25 37 Transparency*100 (%) -11 64 BlockStarts -21 64 BlockStarts -18 0 0 -end - -start 190 -10 0 Group -8 19 SelectMode -8 20 DisplayMode -0 21 IsDropTarget -1 21 IsSnapTarget -2 21 IsTextEditTarget -3 21 DontMoveChildren -11 44 BlocksStart -21 44 BlocksStart -end - -start 191 -10 0 Layout -0 19 ShapePermeableX -1 19 ShapePermeableY -2 19 ShapePermeablePlace -8 20 ShapeFixedCode -8 21 ShapePlowCode -8 22 ShapeRouteStyle -8 24 ConFixedCode -8 25 ConLineJumpCode -8 26 ConLineJumpStyle -8 28 ConLineJumpDirX -8 29 ConLineJumpDirY -11 57 BlockStarts -21 57 BlockStarts -18 0 0 -end - -start 192 -10 0 PageLayout -0 19 ResizePage -1 19 EnableGrid -2 19 DynamicOff -3 19 CtrlAsInput -8 20 PlaceStyle -8 21 RouteStyle -8 22 PlaceDepth -8 23 PlowCode -8 24 LineJumpCode -8 25 LineJumpStyle -8 26 PageLineJumpDirX -8 27 PageLineJumpDirY -9 29 LineToNodeX -9 38 LineToNodeY -9 47 BlockSizeX -9 56 BlockSizeY -9 65 AvenueSizeX -9 74 AvenueSizeY -9 83 LineToLineX -9 92 LineToLineY -9 100 LineJumpFactorX -9 108 LineJumpFactorY -8 116 LineAdjustFrom -8 117 LineAdjustTo -11 163 Blocks start -21 163 Blocks start -end - -start 193 -10 0 PolylineTo -9 20 X -9 29 Y -18 0 0 -end - - -start 195 -10 0 NURBSTo -9 20 X -9 29 Y -9 37 A -9 45 B -9 53 C -9 61 D -11 80 BlocksStart -21 80 BlocksStart -18 0 0 -end - -start 196 -10 0 Hyperlink -0 39 NewWindow -2 39 Default -11 65 BlocksStart -18 0 0 -end - -start 197 -10 0 Reviewer -8 28 ColorRed -8 29 ColorGreen -8 30 ColorBlue -26 31 ReviewerID -26 35 CurrentIndex -11 57 BlocksStart -21 57 BlocksStart -18 0 0 -end - -start 198 -10 0 Annotation -18 0 0 -end - -start 199 -10 0 SmartTagDef -18 0 0 -end - -start 200 -10 0 PrintProps -31 19 PageLeftMargin -31 28 PageRightMargin -31 37 PageTopMargin -31 46 PageBottomMargin -9 55 ScaleX -9 63 ScaleY -25 71 PagesX -25 73 PagesY -8 76 PrintPageOrientation -25 77 PaperKind -25 79 PaperSource -11 91 BlocksStart -21 91 BlocksStart -18 0 0 -end - -start 201 -10 0 Unknown 0xc9 -18 0 0 -end - -start 209 -10 0 NURBSTo E-cell -9 35 1st fr of NURBSTo -9 43 3 bytes are here, need to map -9 51 2nd fr -9 59 3rd fr -9 67 4th byte -9 75 5th byte -9 83 4th fr -9 91 5th fr -9 99 6th byte -9 107 7th byte -9 115 6th fr -9 123 7th fr -9 131 8th byte -9 139 9th byte -18 0 0 -end diff --git a/trunk/src/resources/scratchpad/org/apache/poi/hslf/data/empty.ppt b/trunk/src/resources/scratchpad/org/apache/poi/hslf/data/empty.ppt deleted file mode 100644 index 20d2398e3..000000000 Binary files a/trunk/src/resources/scratchpad/org/apache/poi/hslf/data/empty.ppt and /dev/null differ diff --git a/trunk/src/resources/version/Version.java.template b/trunk/src/resources/version/Version.java.template deleted file mode 100644 index 716ec916b..000000000 --- a/trunk/src/resources/version/Version.java.template +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi; - -/** - * Administrative class to keep track of the version number of the - * POI release. - * - * This class implements the upcoming standard of having - * org.apache.project-name.Version.getVersion() be a standard - * way to get version information. - */ -public class Version { - private static final String VERSION_STRING = "@VERSION@"; - private static final String RELEASE_DATE = "@DSTAMP@"; - - /** - * Return the basic version string, of the form - * nn.nn(.nn) - */ - public static String getVersion() { - return VERSION_STRING; - } - - /** - * Return the date of the release / build - */ - public static String getReleaseDate() { - return RELEASE_DATE; - } - - /** - * Name of product: POI - */ - public static String getProduct() { - return "POI"; - } - /** - * Implementation Language: Java - */ - public static String getImplementationLanguage() { - return "Java"; - } - - /** - * Prints the version to the command line - */ - public static void main(String[] args) { - System.out.println( - "Apache " + getProduct() + " " + - getVersion() + " (" + getReleaseDate() + ")" - ); - } -} diff --git a/trunk/src/scratchpad/models/poi-hdf.zargo b/trunk/src/scratchpad/models/poi-hdf.zargo deleted file mode 100644 index dde113285..000000000 Binary files a/trunk/src/scratchpad/models/poi-hdf.zargo and /dev/null differ diff --git a/trunk/src/scratchpad/src/org/apache/poi/POIReadOnlyDocument.java b/trunk/src/scratchpad/src/org/apache/poi/POIReadOnlyDocument.java deleted file mode 100644 index 3b3eca588..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/POIReadOnlyDocument.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF 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 java.io.File; -import java.io.OutputStream; - -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - - -/** - * This holds the common functionality for all read-only - * POI Document classes, i.e. ones which don't support writing. - * - * @since POI 3.15 beta 3 - */ -public abstract class POIReadOnlyDocument extends POIDocument { - public POIReadOnlyDocument(DirectoryNode dir) { - super(dir); - } - public POIReadOnlyDocument(NPOIFSFileSystem fs) { - super(fs); - } - public POIReadOnlyDocument(OPOIFSFileSystem fs) { - super(fs); - } - public POIReadOnlyDocument(POIFSFileSystem fs) { - super(fs); - } - - /** - * Note - writing is not yet supported for this file format, sorry. - * - * @throws IllegalStateException If you call the method, as writing is not supported - */ - @Override - public void write() { - throw new IllegalStateException("Writing is not yet implemented for this Document Format"); - } - /** - * Note - writing is not yet supported for this file format, sorry. - * - * @throws IllegalStateException If you call the method, as writing is not supported - */ - @Override - public void write(File file) { - throw new IllegalStateException("Writing is not yet implemented for this Document Format"); - } - /** - * Note - writing is not yet supported for this file format, sorry. - * - * @throws IllegalStateException If you call the method, as writing is not supported - */ - @Override - public void write(OutputStream out) { - throw new IllegalStateException("Writing is not yet implemented for this Document Format"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/extractor/OLE2ScratchpadExtractorFactory.java b/trunk/src/scratchpad/src/org/apache/poi/extractor/OLE2ScratchpadExtractorFactory.java deleted file mode 100644 index 115b74a39..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/extractor/OLE2ScratchpadExtractorFactory.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.extractor; - -import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.POITextExtractor; -import org.apache.poi.hdgf.extractor.VisioTextExtractor; -import org.apache.poi.hpbf.extractor.PublisherTextExtractor; -import org.apache.poi.hslf.extractor.PowerPointExtractor; -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.hsmf.datatypes.AttachmentChunks; -import org.apache.poi.hsmf.extractor.OutlookTextExtactor; -import org.apache.poi.hwpf.OldWordFileFormatException; -import org.apache.poi.hwpf.extractor.Word6Extractor; -import org.apache.poi.hwpf.extractor.WordExtractor; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.Entry; - -/** - * Scratchpad-specific logic for {@link OLE2ExtractorFactory} and - * {@link org.apache.poi.extractor.ExtractorFactory}, which permit the other two to run with - * no Scratchpad jar (though without functionality!) - *

        Note - should not be used standalone, always use via the other - * two classes

        - */ -@SuppressWarnings("WeakerAccess") -public class OLE2ScratchpadExtractorFactory { - /** - * Look for certain entries in the stream, to figure it - * out what format is desired - * Note - doesn't check for core-supported formats! - * Note - doesn't check for OOXML-supported formats - */ - public static POITextExtractor createExtractor(DirectoryNode poifsDir) throws IOException { - if (poifsDir.hasEntry("WordDocument")) { - // Old or new style word document? - try { - return new WordExtractor(poifsDir); - } catch (OldWordFileFormatException e) { - return new Word6Extractor(poifsDir); - } - } - - if (poifsDir.hasEntry("PowerPoint Document")) { - return new PowerPointExtractor(poifsDir); - } - - if (poifsDir.hasEntry("VisioDocument")) { - return new VisioTextExtractor(poifsDir); - } - - if (poifsDir.hasEntry("Quill")) { - return new PublisherTextExtractor(poifsDir); - } - - final String[] outlookEntryNames = new String[] { - // message bodies, saved as plain text (PtypString) - // The first short (0x1000, 0x0047, 0x0037) refer to the Property ID (see [MS-OXPROPS].pdf) - // the second short (0x001e, 0x001f, 0x0102) refer to the type of data stored in this entry - // https://msdn.microsoft.com/endatatypes.Ex-us/library/cc433490(v=exchg.80).aspx - // @see org.apache.poi.hsmf.Types.MAPIType - "__substg1.0_1000001E", //PidTagBody ASCII - "__substg1.0_1000001F", //PidTagBody Unicode - "__substg1.0_0047001E", //PidTagMessageSubmissionId ASCII - "__substg1.0_0047001F", //PidTagMessageSubmissionId Unicode - "__substg1.0_0037001E", //PidTagSubject ASCII - "__substg1.0_0037001F", //PidTagSubject Unicode - }; - for (String entryName : outlookEntryNames) { - if (poifsDir.hasEntry(entryName)) { - return new OutlookTextExtactor(poifsDir); - } - } - - throw new IllegalArgumentException("No supported documents found in the OLE2 stream"); - } - - /** - * Returns an array of text extractors, one for each of - * the embedded documents in the file (if there are any). - * If there are no embedded documents, you'll get back an - * empty array. Otherwise, you'll get one open - * {@link POITextExtractor} for each embedded file. - */ - public static void identifyEmbeddedResources(POIOLE2TextExtractor ext, List dirs, List nonPOIFS) throws IOException { - // Find all the embedded directories - DirectoryEntry root = ext.getRoot(); - if (root == null) { - throw new IllegalStateException("The extractor didn't know which POIFS it came from!"); - } - - if (ext instanceof WordExtractor) { - // These are in ObjectPool -> _... under the root - try { - DirectoryEntry op = (DirectoryEntry) - root.getEntry("ObjectPool"); - Iterator it = op.getEntries(); - while(it.hasNext()) { - Entry entry = it.next(); - if(entry.getName().startsWith("_")) { - dirs.add(entry); - } - } - } catch(FileNotFoundException e) { - // ignored here - } - //} else if(ext instanceof PowerPointExtractor) { - // Tricky, not stored directly in poifs - // TODO - } else if (ext instanceof OutlookTextExtactor) { - // Stored in the Attachment blocks - MAPIMessage msg = ((OutlookTextExtactor)ext).getMAPIMessage(); - for (AttachmentChunks attachment : msg.getAttachmentFiles()) { - if (attachment.attachData != null) { - byte[] data = attachment.attachData.getValue(); - nonPOIFS.add( new ByteArrayInputStream(data) ); - } else if (attachment.attachmentDirectory != null) { - dirs.add(attachment.attachmentDirectory.getDirectory()); - } - } - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java deleted file mode 100644 index c85278882..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIReadOnlyDocument; -import org.apache.poi.hdgf.chunks.ChunkFactory; -import org.apache.poi.hdgf.pointers.Pointer; -import org.apache.poi.hdgf.pointers.PointerFactory; -import org.apache.poi.hdgf.streams.PointerContainingStream; -import org.apache.poi.hdgf.streams.Stream; -import org.apache.poi.hdgf.streams.StringsStream; -import org.apache.poi.hdgf.streams.TrailerStream; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LocaleUtil; - -/** - * See - * http://www.redferni.uklinux.net/visio/ - * http://www.gnome.ru/projects/docs/vsdocs.html - * http://www.gnome.ru/projects/docs/slide1.png - * http://www.gnome.ru/projects/docs/slide2.png - */ -public final class HDGFDiagram extends POIReadOnlyDocument { - private static final String VISIO_HEADER = "Visio (TM) Drawing\r\n"; - - private byte[] _docstream; - - private short version; - private long docSize; - - private Pointer trailerPointer; - private TrailerStream trailer; - - private ChunkFactory chunkFactory; - private PointerFactory ptrFactory; - - public HDGFDiagram(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public HDGFDiagram(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public HDGFDiagram(DirectoryNode dir) throws IOException { - super(dir); - - // Grab the document stream - InputStream is = dir.createDocumentInputStream("VisioDocument"); - _docstream = IOUtils.toByteArray(is); - is.close(); - - // Check it's really visio - String typeString = new String(_docstream, 0, 20, LocaleUtil.CHARSET_1252 ); - if(! typeString.equals(VISIO_HEADER)) { - throw new IllegalArgumentException("Wasn't a valid visio document, started with " + typeString); - } - - // Grab the version number, 0x1a -> 0x1b - version = LittleEndian.getShort(_docstream, 0x1a); - // Grab the document size, 0x1c -> 0x1f - docSize = LittleEndian.getUInt(_docstream, 0x1c); - // ??? 0x20 -> 0x23 - - // Create the Chunk+Pointer Factories for the document version - ptrFactory = new PointerFactory(version); - chunkFactory = new ChunkFactory(version); - - // Grab the pointer to the trailer - trailerPointer = ptrFactory.createPointer(_docstream, 0x24); - - // Now grab the trailer - trailer = (TrailerStream) - Stream.createStream(trailerPointer, _docstream, chunkFactory, ptrFactory); - - // Finally, find all our streams - trailer.findChildren(_docstream); - } - - /** - * Returns the TrailerStream, which is at the root of the - * tree of Streams. - */ - public TrailerStream getTrailerStream() { return trailer; } - /** - * Returns all the top level streams, which are the streams - * pointed to by the TrailerStream. - */ - public Stream[] getTopLevelStreams() { return trailer.getPointedToStreams(); } - public long getDocumentSize() { return docSize; } - - /** - * Prints out some simple debug on the base contents of the file. - * @see org.apache.poi.hdgf.dev.VSDDumper - */ - public void debug() { - System.err.println("Trailer is at " + trailerPointer.getOffset()); - System.err.println("Trailer has type " + trailerPointer.getType()); - System.err.println("Trailer has length " + trailerPointer.getLength()); - System.err.println("Trailer has format " + trailerPointer.getFormat()); - - for(int i=0; i 0) { - System.err.println("\tContains " + pcs.getPointedToStreams().length + " other pointers/streams"); - for(int j=0; j 4078) { - pntr = pntr - 4078; - } else { - pntr = pntr + 18; - } - return pntr; - } - - /** - * We want an empty dictionary, so do nothing - */ - @Override - protected int populateDictionary(byte[] dict) { - return 0; - } - - /** - * Performs the Visio compatible streaming LZW compression. - */ - public void compress(InputStream src, OutputStream res) throws IOException { - HDGFLZWCompressor c = new HDGFLZWCompressor(); - c.compress(src, res); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/HDGFLZWCompressor.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/HDGFLZWCompressor.java deleted file mode 100644 index 53215de88..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/HDGFLZWCompressor.java +++ /dev/null @@ -1,258 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Helper class to handle the Visio compatible - * streaming LZW compression. - * Need our own class to handle keeping track of the - * code buffer, pending bytes to write out etc. - * - * TODO Fix this, as it starts to go wrong on - * large streams - */ -final class HDGFLZWCompressor { - // We use 12 bit codes: - // * 0-255 are real bytes - // * 256-4095 are the substring codes - // Java handily initialises our buffer / dictionary - // to all zeros - byte[] dict = new byte[4096]; - - // The next block of data to be written out, minus - // its mask byte - byte[] buffer = new byte[16]; - // And how long it is - // (Un-compressed codes are 1 byte each, compressed codes - // are two) - int bufferLen = 0; - - // The raw length of a code is limited to 4 bits + 2 - byte[] rawCode = new byte[18]; - // And how much we're using - int rawCodeLen = 0; - - // How far through the input and output streams we are - int posInp = 0; - int posOut = 0; - - // What the next mask byte to output will be - int nextMask = 0; - // And how many bits we've already set - int maskBitsSet = 0; - - public HDGFLZWCompressor() {} - -/** - * Returns the last place that the bytes from rawCode are found - * at in the buffer, or -1 if they can't be found - */ -private int findRawCodeInBuffer() { - // Work our way through all the codes until we - // find the right one. Visio starts from the end - for(int i=4096-rawCodeLen; i>0; i--) { - boolean matches = true; - for(int j=0; matches && j> 4); - buffer[bufferLen] = HDGFLZW.fromInt(bp1); - bufferLen++; - buffer[bufferLen] = HDGFLZW.fromInt(bp2); - bufferLen++; - - // Copy the data to the dictionary in the new place - for(int i=0; i 0) { - outputCompressed(res); - if(maskBitsSet > 0) { - output8Codes(res); - } - } - break; - } - - // Try adding this new byte onto rawCode, and - // see if all of that is still found in the - // buffer dictionary or not - rawCode[rawCodeLen] = dataB; - rawCodeLen++; - int rawAt = findRawCodeInBuffer(); - - // If we found it and are now at 18 bytes, - // we need to output our pending code block - if(rawCodeLen == 18 && rawAt > -1) { - outputCompressed(res); - rawCodeLen = 0; - continue; - } - - // If we did find all of rawCode with our new - // byte added on, we can wait to see what happens - // with the next byte - if(rawAt > -1) { - continue; - } - - // If we get here, then the rawCode + this byte weren't - // found in the dictionary - - // If there was something in rawCode before, then that was - // found in the dictionary, so output that compressed - rawCodeLen--; - if(rawCodeLen > 0) { - // Output the old rawCode - outputCompressed(res); - - // Can this byte start a new rawCode, or does - // it need outputting itself? - rawCode[0] = dataB; - rawCodeLen = 1; - if(findRawCodeInBuffer() > -1) { - // Fits in, wait for next byte - continue; - } - // Doesn't fit, output - outputUncompressed(dataB,res); - rawCodeLen = 0; - } else { - // Nothing in rawCode before, so this byte - // isn't in the buffer dictionary - // Output it un-compressed - outputUncompressed(dataB,res); - } - } -} -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java deleted file mode 100644 index 23ec35278..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java +++ /dev/null @@ -1,290 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -import java.util.ArrayList; - -import org.apache.poi.hdgf.chunks.ChunkFactory.CommandDefinition; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Base of all chunks, which hold data, flags etc - */ -public final class Chunk { - /** - * The contents of the chunk, excluding the header, - * trailer and separator - */ - private byte[] contents; - private ChunkHeader header; - /** May be null */ - private ChunkTrailer trailer; - /** May be null */ - private ChunkSeparator separator; - /** The possible different commands we can hold */ - protected CommandDefinition[] commandDefinitions; - /** The command+value pairs we hold */ - private Command[] commands; - /** The blocks (if any) we hold */ - //private Block[] blocks - /** The name of the chunk, as found from the commandDefinitions */ - private String name; - - /** For logging warnings about the structure of the file */ - private POILogger logger = POILogFactory.getLogger(Chunk.class); - - public Chunk(ChunkHeader header, ChunkTrailer trailer, ChunkSeparator separator, byte[] contents) { - this.header = header; - this.trailer = trailer; - this.separator = separator; - this.contents = contents.clone(); - } - - public byte[] _getContents() { - return contents; - } - public ChunkHeader getHeader() { - return header; - } - /** Gets the separator between this chunk and the next, if it exists */ - public ChunkSeparator getSeparator() { - return separator; - } - /** Gets the trailer for this chunk, if it exists */ - public ChunkTrailer getTrailer() { - return trailer; - } - /** - * Gets the command definitions, which define and describe much - * of the data held by the chunk. - */ - public CommandDefinition[] getCommandDefinitions() { - return commandDefinitions; - } - public Command[] getCommands() { - return commands; - } - /** - * Get the name of the chunk, as found from the CommandDefinitions - */ - public String getName() { - return name; - } - - /** - * Returns the size of the chunk, including any - * headers, trailers and separators. - */ - public int getOnDiskSize() { - int size = header.getSizeInBytes() + contents.length; - if(trailer != null) { - size += trailer.trailerData.length; - } - if(separator != null) { - size += separator.separatorData.length; - } - return size; - } - - /** - * Uses our CommandDefinitions to process the commands - * our chunk type has, and figure out the - * values for them. - */ - protected void processCommands() { - if(commandDefinitions == null) { - throw new IllegalStateException("You must supply the command definitions before calling processCommands!"); - } - - // Loop over the definitions, building the commands - // and getting their values - ArrayList commandList = new ArrayList(); - for(CommandDefinition cdef : commandDefinitions) { - int type = cdef.getType(); - int offset = cdef.getOffset(); - - // Handle virtual commands - if(type == 10) { - name = cdef.getName(); - continue; - } else if(type == 18) { - continue; - } - - - // Build the appropriate command for the type - Command command; - if(type == 11 || type == 21) { - command = new BlockOffsetCommand(cdef); - } else { - command = new Command(cdef); - } - - // Bizarely, many of the offsets are from the start of the - // header, not from the start of the chunk body - switch(type) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - case 11: case 21: - case 12: case 16: case 17: case 18: case 28: case 29: - // Offset is from start of chunk - break; - default: - // Offset is from start of header! - if(offset >= 19) { - offset -= 19; - } - } - - // Check we seem to have enough data - if(offset >= contents.length) { - logger.log(POILogger.WARN, - "Command offset " + offset + " past end of data at " + contents.length - ); - continue; - } - - try { - // Process - switch(type) { - // Types 0->7 = a flat at bit 0->7 - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - int val = contents[offset] & (1< 0); - break; - case 8: - command.value = Byte.valueOf(contents[offset]); - break; - case 9: - command.value = new Double( - LittleEndian.getDouble(contents, offset) - ); - break; - case 12: - // A Little Endian String - // Starts 8 bytes into the data segment - // Ends at end of data, or 00 00 - - // Ensure we have enough data - if(contents.length < 8) { - command.value = ""; - break; - } - - // Find the end point - int startsAt = 8; - int endsAt = startsAt; - for(int j=startsAt; j chunkCommandDefinitions = - new HashMap(); - /** - * What the name is of the chunk table definitions file? - * This file comes from the scratchpad resources directory. - */ - private static final String chunkTableName = - "/org/apache/poi/hdgf/chunks_parse_cmds.tbl"; - - /** For logging problems we spot with the file */ - private static final POILogger logger = POILogFactory.getLogger(ChunkFactory.class); - - public ChunkFactory(int version) throws IOException { - this.version = version; - - processChunkParseCommands(); - } - - /** - * Open chunks_parse_cmds.tbl and process it, to get the definitions - * of all the different possible chunk commands. - */ - private void processChunkParseCommands() throws IOException { - String line; - InputStream cpd = null; - BufferedReader inp = null; - try { - cpd = ChunkFactory.class.getResourceAsStream(chunkTableName); - if(cpd == null) { - throw new IllegalStateException("Unable to find HDGF chunk definition on the classpath - " + chunkTableName); - } - - inp = new BufferedReader(new InputStreamReader(cpd, LocaleUtil.CHARSET_1252)); - - while( (line = inp.readLine()) != null ) { - if (line.isEmpty() || "# \t".contains(line.substring(0,1))) { - continue; - } - - // Start xxx - if(!line.matches("^start [0-9]+$")) { - throw new IllegalStateException("Expecting start xxx, found " + line); - } - int chunkType = Integer.parseInt(line.substring(6)); - ArrayList defsL = new ArrayList(); - - // Data entries - while( (line = inp.readLine()) != null ) { - if (line.startsWith("end")) { - break; - } - StringTokenizer st = new StringTokenizer(line, " "); - int defType = Integer.parseInt(st.nextToken()); - int offset = Integer.parseInt(st.nextToken()); - String name = st.nextToken("\uffff").substring(1); - - CommandDefinition def = new CommandDefinition(defType,offset,name); - defsL.add(def); - } - - CommandDefinition[] defs = defsL.toArray(new CommandDefinition[defsL.size()]); - - // Add to the map - chunkCommandDefinitions.put(Integer.valueOf(chunkType), defs); - } - } finally { - if (inp != null) { - inp.close(); - } - if (cpd != null) { - cpd.close(); - } - } - } - - public int getVersion() { return version; } - - /** - * Creates the appropriate chunk at the given location. - * @param data - * @param offset - */ - public Chunk createChunk(byte[] data, int offset) { - // Create the header - ChunkHeader header = - ChunkHeader.createChunkHeader(version, data, offset); - // Sanity check - if(header.length < 0) { - throw new IllegalArgumentException("Found a chunk with a negative length, which isn't allowed"); - } - - // How far up to look - int endOfDataPos = offset + header.getLength() + header.getSizeInBytes(); - - // Check we have enough data, and tweak the header size - // as required - if(endOfDataPos > data.length) { - logger.log(POILogger.WARN, - "Header called for " + header.getLength() +" bytes, but that would take us past the end of the data!"); - - endOfDataPos = data.length; - header.length = data.length - offset - header.getSizeInBytes(); - - if(header.hasTrailer()) { - header.length -= 8; - endOfDataPos -= 8; - } - if(header.hasSeparator()) { - header.length -= 4; - endOfDataPos -= 4; - } - } - - - // Create the trailer and separator, if required - ChunkTrailer trailer = null; - ChunkSeparator separator = null; - if(header.hasTrailer()) { - if(endOfDataPos <= data.length-8) { - trailer = new ChunkTrailer( - data, endOfDataPos); - endOfDataPos += 8; - } else { - logger.log(POILogger.ERROR, "Header claims a length to " + endOfDataPos + " there's then no space for the trailer in the data (" + data.length + ")"); - } - } - if(header.hasSeparator()) { - if(endOfDataPos <= data.length-4) { - separator = new ChunkSeparator( - data, endOfDataPos); - } else { - logger.log(POILogger.ERROR, "Header claims a length to " + endOfDataPos + " there's then no space for the separator in the data (" + data.length + ")"); - } - } - - // Now, create the chunk - byte[] contents = new byte[header.getLength()]; - System.arraycopy(data, offset+header.getSizeInBytes(), contents, 0, contents.length); - Chunk chunk = new Chunk(header, trailer, separator, contents); - - // Feed in the stuff from chunks_parse_cmds.tbl - CommandDefinition[] defs = chunkCommandDefinitions.get(Integer.valueOf(header.getType())); - if (defs == null) { - defs = new CommandDefinition[0]; - } - chunk.commandDefinitions = defs; - - // Now get the chunk to process its commands - chunk.processCommands(); - - // All done - return chunk; - } - - /** - * The definition of a Command, which a chunk may hold. - * The Command holds the value, this describes it. - */ - public static class CommandDefinition { - private int type; - private int offset; - private String name; - public CommandDefinition(int type, int offset, String name) { - this.type = type; - this.offset = offset; - this.name = name; - } - - public String getName() { - return name; - } - public int getOffset() { - return offset; - } - public int getType() { - return type; - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java deleted file mode 100644 index 4b38366f7..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -import org.apache.poi.util.LittleEndian; - -import java.nio.charset.Charset; - -/** - * A chunk header - */ -public abstract class ChunkHeader { - protected int type; - protected int id; - protected int length; - protected int unknown1; - - /** - * Creates the appropriate ChunkHeader for the Chunk Header at - * the given location, for the given document version. - */ - public static ChunkHeader createChunkHeader(int documentVersion, byte[] data, int offset) { - if(documentVersion >= 6) { - ChunkHeaderV6 ch; - if(documentVersion > 6) { - ch = new ChunkHeaderV11(); - } else { - ch = new ChunkHeaderV6(); - } - ch.type = (int)LittleEndian.getUInt(data, offset + 0); - ch.id = (int)LittleEndian.getUInt(data, offset + 4); - ch.unknown1 = (int)LittleEndian.getUInt(data, offset + 8); - ch.length = (int)LittleEndian.getUInt(data, offset + 12); - ch.unknown2 = LittleEndian.getShort(data, offset + 16); - ch.unknown3 = LittleEndian.getUByte(data, offset + 18); - - return ch; - } else if(documentVersion == 5 || documentVersion == 4) { - ChunkHeaderV4V5 ch = new ChunkHeaderV4V5(); - - ch.type = LittleEndian.getShort(data, offset + 0); - ch.id = LittleEndian.getShort(data, offset + 2); - ch.unknown2 = LittleEndian.getUByte(data, offset + 4); - ch.unknown3 = LittleEndian.getUByte(data, offset + 5); - ch.unknown1 = LittleEndian.getShort(data, offset + 6); - ch.length = (int)LittleEndian.getUInt(data, offset + 8); - - return ch; - } else { - throw new IllegalArgumentException("Visio files with versions below 4 are not supported, yours was " + documentVersion); - } - } - - /** - * Returns the size of a chunk header for the given document version. - */ - public static int getHeaderSize(int documentVersion) { - if(documentVersion > 6) { - return ChunkHeaderV11.getHeaderSize(); - } else if(documentVersion == 6) { - return ChunkHeaderV6.getHeaderSize(); - } else { - return ChunkHeaderV4V5.getHeaderSize(); - } - } - - public abstract int getSizeInBytes(); - public abstract boolean hasTrailer(); - public abstract boolean hasSeparator(); - public abstract Charset getChunkCharset(); - - /** - * Returns the ID/IX of the chunk - */ - public int getId() { - return id; - } - /** - * Returns the length of the trunk, excluding the length - * of the header, trailer or separator. - */ - public int getLength() { - return length; - } - /** - * Returns the type of the chunk, which affects the - * mandatory information - */ - public int getType() { - return type; - } - public int getUnknown1() { - return unknown1; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java deleted file mode 100644 index b3d84aa50..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -import java.nio.charset.Charset; - -/** - * A chunk header from v11+ - */ -public final class ChunkHeaderV11 extends ChunkHeaderV6 { - /** - * Does the chunk have a separator? - */ - public boolean hasSeparator() { - // For some reason, there are two types that don't have a - // separator despite the flags that indicate they do - if(type == 0x1f || type == 0xc9) { return false; } - - // If there's a trailer, there's a separator - if(hasTrailer()) { return true; } - - if(unknown2 == 2 && unknown3 == 0x55) { return true; } - if(unknown2 == 2 && unknown3 == 0x54 && type == 0xa9) { return true; } - if(unknown2 == 2 && unknown3 == 0x54 && type == 0xaa) { return true; } - if(unknown2 == 2 && unknown3 == 0x54 && type == 0xb4) { return true; } - if(unknown2 == 2 && unknown3 == 0x54 && type == 0xb6) { return true; } - if(unknown2 == 3 && unknown3 != 0x50) { return true; } - if(type == 0x69) { return true; } - - return false; - } - - @Override - public Charset getChunkCharset() { - return Charset.forName("UTF-16LE"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java deleted file mode 100644 index bba6a87dd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -import java.nio.charset.Charset; - -/** - * A chunk header from v4 or v5 - */ -public final class ChunkHeaderV4V5 extends ChunkHeader { - protected short unknown2; - protected short unknown3; - - public short getUnknown2() { - return unknown2; - } - public short getUnknown3() { - return unknown3; - } - - protected static int getHeaderSize() { - return 12; - } - - public int getSizeInBytes() { - return getHeaderSize(); - } - - /** - * Does the chunk have a trailer? - */ - public boolean hasTrailer() { - // V4 and V5 never has trailers - return false; - } - - /** - * Does the chunk have a separator? - */ - public boolean hasSeparator() { - // V4 and V5 never has separators - return false; - } - - @Override - public Charset getChunkCharset() { - return Charset.forName("ASCII"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java deleted file mode 100644 index 96546c780..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -import java.nio.charset.Charset; - -/** - * A chunk header from v6 - */ -public class ChunkHeaderV6 extends ChunkHeader { - protected short unknown2; - protected short unknown3; - - public short getUnknown2() { - return unknown2; - } - public short getUnknown3() { - return unknown3; - } - - protected static int getHeaderSize() { - // Looks like it ought to be 19... - return 19; - } - public int getSizeInBytes() { - return getHeaderSize(); - } - - /** - * Does the chunk have a trailer? - */ - public boolean hasTrailer() { - if(unknown1 != 0 || type == 0x71 || type == 0x70) { - return true; - } - if(type == 0x6b || type == 0x6a || type == 0x69 || type == 0x66 - || type == 0x65 || type == 0x2c) { - return true; - } - return false; - } - /** - * Does the chunk have a separator? - */ - public boolean hasSeparator() { - // V6 never has separators - return false; - } - - @Override - public Charset getChunkCharset() { - return Charset.forName("ASCII"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkSeparator.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkSeparator.java deleted file mode 100644 index bf49ceac4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkSeparator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -/** - * A separator between the trailer of one chunk, and the - * header of the next one - */ -public final class ChunkSeparator { - protected byte[] separatorData; - - public ChunkSeparator(byte[] data, int offset) { - separatorData = new byte[4]; - System.arraycopy(data, offset, separatorData, 0, 4); - } - - public String toString() { - return ""; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkTrailer.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkTrailer.java deleted file mode 100644 index ad3441d88..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkTrailer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.chunks; - -/** - * A trailer that follows a chunk - */ -public final class ChunkTrailer { - protected byte[] trailerData; - - public ChunkTrailer(byte[] data, int offset) { - trailerData = new byte[8]; - System.arraycopy(data, offset, trailerData, 0, 8); - } - - public String toString() { - return ""; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java deleted file mode 100644 index 62f2b36e5..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.dev; - -import java.io.File; -import java.io.PrintStream; -import java.util.Arrays; - -import org.apache.poi.hdgf.HDGFDiagram; -import org.apache.poi.hdgf.chunks.Chunk; -import org.apache.poi.hdgf.chunks.Chunk.Command; -import org.apache.poi.hdgf.pointers.Pointer; -import org.apache.poi.hdgf.streams.ChunkStream; -import org.apache.poi.hdgf.streams.PointerContainingStream; -import org.apache.poi.hdgf.streams.Stream; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; - -/** - * Developer helper class to dump out the pointer+stream structure - * of a Visio file - */ -public final class VSDDumper { - final static String tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; - - final PrintStream ps; - final HDGFDiagram hdgf; - VSDDumper(PrintStream ps, HDGFDiagram hdgf) { - this.ps = ps; - this.hdgf = hdgf; - } - - public static void main(String[] args) throws Exception { - if(args.length == 0) { - System.err.println("Use:"); - System.err.println(" VSDDumper "); - System.exit(1); - } - - NPOIFSFileSystem poifs = new NPOIFSFileSystem(new File(args[0])); - HDGFDiagram hdgf = new HDGFDiagram(poifs); - - PrintStream ps = System.out; - ps.println("Opened " + args[0]); - VSDDumper vd = new VSDDumper(ps, hdgf); - vd.dumpFile(); - - poifs.close(); - } - - public void dumpFile() { - dumpVal("Claimed document size", hdgf.getDocumentSize(), 0); - ps.println(); - dumpStream(hdgf.getTrailerStream(), 0); - } - - private void dumpStream(Stream stream, int indent) { - Pointer ptr = stream.getPointer(); - dumpVal("Stream at", ptr.getOffset(), indent); - dumpVal("Type is", ptr.getType(), indent+1); - dumpVal("Format is", ptr.getFormat(), indent+1); - dumpVal("Length is", ptr.getLength(), indent+1); - if(ptr.destinationCompressed()) { - dumpVal("DC.Length is", stream._getContentsLength(), indent+1); - } - dumpVal("Compressed is", ptr.destinationCompressed(), indent+1); - dumpVal("Stream is", stream.getClass().getName(), indent+1); - - byte[] db = stream._getStore()._getContents(); - String ds = (db.length >= 8) ? Arrays.toString(db) : "[]"; - dumpVal("First few bytes are", ds, indent+1); - - if (stream instanceof PointerContainingStream) { - Stream streams[] = ((PointerContainingStream)stream).getPointedToStreams(); - dumpVal("Nbr of children", streams.length, indent+1); - - for(Stream s : streams) { - dumpStream(s, indent+1); - } - } - if(stream instanceof ChunkStream) { - Chunk chunks[] = ((ChunkStream)stream).getChunks(); - dumpVal("Nbr of chunks", chunks.length, indent+1); - - for(Chunk chunk : chunks) { - dumpChunk(chunk, indent+1); - } - } - } - - private void dumpChunk(Chunk chunk, int indent) { - dumpVal(chunk.getName(), "", indent); - dumpVal("Length is", chunk._getContents().length, indent); - dumpVal("OD Size is", chunk.getOnDiskSize(), indent); - dumpVal("T / S is", chunk.getTrailer() + " / " + chunk.getSeparator(), indent); - Command commands[] = chunk.getCommands(); - dumpVal("Nbr of commands", commands.length, indent); - for(Command command : commands) { - dumpVal(command.getDefinition().getName(), ""+command.getValue(), indent+1); - } - } - - private void dumpVal(String label, long value, int indent) { - ps.print(tabs.substring(0,indent)); - ps.print(label); - ps.print('\t'); - ps.print(value); - ps.print(" (0x"); - ps.print(Long.toHexString(value)); - ps.println(")"); - } - - private void dumpVal(String label, boolean value, int indent) { - dumpVal(label, Boolean.toString(value), indent); - } - - private void dumpVal(String label, String value, int indent) { - ps.print(tabs.substring(0,indent)); - ps.print(label); - ps.print('\t'); - ps.println(value); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/exceptions/HDGFException.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/exceptions/HDGFException.java deleted file mode 100644 index c893bd2df..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/exceptions/HDGFException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.exceptions; - -/** - * The superclass of all HDGF exceptions - * - * @author Yegor Kozlov - */ -public final class HDGFException extends RuntimeException { - - public HDGFException() { - super(); - } - - public HDGFException(String message) { - super(message); - } - - public HDGFException(String message, Throwable cause) { - super(message, cause); - } - - public HDGFException(Throwable cause) { - super(cause); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java deleted file mode 100644 index fae6e3f5c..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.extractor; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.hdgf.HDGFDiagram; -import org.apache.poi.hdgf.chunks.Chunk; -import org.apache.poi.hdgf.chunks.Chunk.Command; -import org.apache.poi.hdgf.streams.ChunkStream; -import org.apache.poi.hdgf.streams.PointerContainingStream; -import org.apache.poi.hdgf.streams.Stream; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * Class to find all the text in a Visio file, and return it. - * Can operate on the command line (outputs to stdout), or - * can return the text for you (example: for use with Lucene). - */ -public final class VisioTextExtractor extends POIOLE2TextExtractor { - private HDGFDiagram hdgf; - - public VisioTextExtractor(HDGFDiagram hdgf) { - super(hdgf); - this.hdgf = hdgf; - } - public VisioTextExtractor(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public VisioTextExtractor(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public VisioTextExtractor(DirectoryNode dir) throws IOException { - this(new HDGFDiagram(dir)); - } - public VisioTextExtractor(InputStream inp) throws IOException { - this(new NPOIFSFileSystem(inp)); - } - - /** - * Locates all the text entries in the file, and returns their - * contents. - * - * @return An array of each Text item in the document - */ - public String[] getAllText() { - ArrayList text = new ArrayList(); - for(Stream stream : hdgf.getTopLevelStreams()) { - findText(stream, text); - } - return text.toArray( new String[text.size()] ); - } - private void findText(Stream stream, ArrayList text) { - if(stream instanceof PointerContainingStream) { - PointerContainingStream ps = (PointerContainingStream)stream; - for(int i=0; i 0) { - - // First command - Command cmd = chunk.getCommands()[0]; - if(cmd != null && cmd.getValue() != null) { - // Capture the text, as long as it isn't - // simply an empty string - String str = cmd.getValue().toString(); - if(str.equals("") || str.equals("\n")) { - // Ignore empty strings - } else { - text.add( str ); - } - } - } - } - } - } - - /** - * Returns the textual contents of the file. - * Each textual object's text will be separated - * by a newline - * - * @return All text contained in this document, separated by \n - */ - @Override - public String getText() { - StringBuffer text = new StringBuffer(); - for(String t : getAllText()) { - text.append(t); - if(!t.endsWith("\r") && !t.endsWith("\n")) { - text.append('\n'); - } - } - return text.toString(); - } - - public static void main(String[] args) throws Exception { - if(args.length == 0) { - System.err.println("Use:"); - System.err.println(" VisioTextExtractor "); - System.exit(1); - } - - VisioTextExtractor extractor = - new VisioTextExtractor(new FileInputStream(args[0])); - - // Print not PrintLn as already has \n added to it - System.out.print(extractor.getText()); - - extractor.close(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java deleted file mode 100644 index 69704f24e..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.pointers; - -/** - * Base class of pointers, which hold metadata and offsets about - * blocks elsewhere in the file - */ -public abstract class Pointer { - protected int type; - protected int address; - protected int offset; - protected int length; - protected short format; - - public int getAddress() { - return address; - } - public short getFormat() { - return format; - } - public int getLength() { - return length; - } - public int getOffset() { - return offset; - } - public int getType() { - return type; - } - - public abstract int getSizeInBytes(); - public abstract int getNumPointersOffset(byte[] data); - public abstract int getNumPointers(int offset, byte[] data); - public abstract int getPostNumPointersSkip(); - - public abstract boolean destinationHasStrings(); - public abstract boolean destinationHasPointers(); - public abstract boolean destinationHasChunks(); - public abstract boolean destinationCompressed(); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java deleted file mode 100644 index a151334fe..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.pointers; - -import org.apache.poi.hdgf.streams.PointerContainingStream; -import org.apache.poi.util.LittleEndian; - -/** - * Factor class to create the appropriate pointers, based on the version - * of the file - */ -public final class PointerFactory { - private int version; - public PointerFactory(int version) { - this.version = version; - } - public int getVersion() { return version; } - - /** - * Creates a single Pointer from the data at the given offset - */ - public Pointer createPointer(byte[] data, int offset) { - Pointer p; - if(version >= 6) { - p = new PointerV6(); - p.type = LittleEndian.getInt(data, offset+0); - p.address = (int)LittleEndian.getUInt(data, offset+4); - p.offset = (int)LittleEndian.getUInt(data, offset+8); - p.length = (int)LittleEndian.getUInt(data, offset+12); - p.format = LittleEndian.getShort(data, offset+16); - - return p; - } else if(version == 5) { - p = new PointerV5(); - p.type = LittleEndian.getShort(data, offset+0); - p.format = LittleEndian.getShort(data, offset+2); - p.address = (int)LittleEndian.getUInt(data, offset+4); - p.offset = (int)LittleEndian.getUInt(data, offset+8); - p.length = (int)LittleEndian.getUInt(data, offset+12); - - return p; - } else { - throw new IllegalArgumentException("Visio files with versions below 5 are not supported, yours was " + version); - } - } - - /** - * Parsers the {@link PointerContainingStream} contents and - * creates all the child Pointers for it - */ - public Pointer[] createContainerPointers(Pointer parent, byte[] data) { - // Where in the stream does the "number of pointers" offset live? - int numPointersOffset = parent.getNumPointersOffset(data); - // How many do we have? - int numPointers = parent.getNumPointers(numPointersOffset, data); - // How much to skip for the num pointers + any extra data? - int skip = parent.getPostNumPointersSkip(); - - // Create - int pos = numPointersOffset + skip; - Pointer[] childPointers = new Pointer[numPointers]; - for(int i=0; i 0; - } - - /** - * With v6 pointers, the on-disk size is 16 bytes - */ - public int getSizeInBytes() { return 16; } - - /** - * Depends on the type only, not stored - */ - public int getNumPointersOffset(byte[] data) { - switch (type) { - case 0x1d: - case 0x4e: - return 30; - case 0x1e: - return 54; - case 0x14: - return 130; - } - return 10; - } - /** - * 16 bit int at the given offset - */ - public int getNumPointers(int offset, byte[] data) { - // V5 stores it as a 16 bit number at the offset - return LittleEndian.getShort(data, offset); - } - /** - * Just the 2 bytes of the number of pointers - */ - public int getPostNumPointersSkip() { - return 2; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java deleted file mode 100644 index b240a0c9b..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.pointers; - -import org.apache.poi.util.LittleEndian; - -/** - * A Pointer from v6+ - */ -public final class PointerV6 extends Pointer { - public boolean destinationHasStrings() { - return (0x40 <= format && format < 0x50); - } - public boolean destinationHasPointers() { - if(type == 20) return true; - if(format == 0x1d || format == 0x1e) return true; - return (0x50 <= format && format < 0x60); - } - public boolean destinationHasChunks() { - return (0xd0 <= format && format < 0xdf); - } - - public boolean destinationCompressed() { - // Apparently, it's the second least significant bit - return (format & 2) > 0; - } - - /** - * With v6 pointers, the on-disk size is 18 bytes - */ - public int getSizeInBytes() { return 18; } - - /** - * Stored within the data - */ - public int getNumPointersOffset(byte[] data) { - return getNumPointersOffsetV6(data); - } - public static int getNumPointersOffsetV6(byte[] data) { - // V6 stores it as the first value in the stream - return (int)LittleEndian.getUInt(data, 0); - } - /** - * 32 bit int at the given offset - */ - public int getNumPointers(int offset, byte[] data) { - return getNumPointersV6(offset, data); - } - public static int getNumPointersV6(int offset, byte[] data) { - // V6 stores it a 32 bit number at the offset - return (int)LittleEndian.getUInt(data, offset); - } - /** - * 4 bytes of the number, and 4 more unknown bytes - */ - public int getPostNumPointersSkip() { - return getPostNumPointersSkipV6(); - } - public static int getPostNumPointersSkipV6() { - return 8; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java deleted file mode 100644 index 9f15e40b9..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.streams; - -import java.util.ArrayList; - -import org.apache.poi.hdgf.chunks.Chunk; -import org.apache.poi.hdgf.chunks.ChunkFactory; -import org.apache.poi.hdgf.chunks.ChunkHeader; -import org.apache.poi.hdgf.pointers.Pointer; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -public final class ChunkStream extends Stream { - private static POILogger logger = POILogFactory.getLogger(ChunkStream.class); - - private ChunkFactory chunkFactory; - /** All the Chunks we contain */ - private Chunk[] chunks; - - protected ChunkStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory) { - super(pointer, store); - this.chunkFactory = chunkFactory; - - // For compressed stores, we require all of the data - store.copyBlockHeaderToContents(); - } - - public Chunk[] getChunks() { return chunks; } - - /** - * Process the contents of the stream out into chunks - */ - public void findChunks() { - ArrayList chunksA = new ArrayList(); - - if(getPointer().getOffset() == 0x64b3) { - int i = 0; - i++; - } - - int pos = 0; - byte[] contents = getStore().getContents(); - try { - while(pos < contents.length) { - // Ensure we have enough data to create a chunk from - int headerSize = ChunkHeader.getHeaderSize(chunkFactory.getVersion()); - if(pos+headerSize <= contents.length) { - Chunk chunk = chunkFactory.createChunk(contents, pos); - chunksA.add(chunk); - - pos += chunk.getOnDiskSize(); - } else { - logger.log(POILogger.WARN, "Needed " + headerSize + " bytes to create the next chunk header, but only found " + (contents.length-pos) + " bytes, ignoring rest of data"); - pos = contents.length; - } - } - } - catch (Exception e) - { - logger.log(POILogger.ERROR, "Failed to create chunk at " + pos + ", ignoring rest of data." + e); - } - - chunks = chunksA.toArray(new Chunk[chunksA.size()]); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/CompressedStreamStore.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/CompressedStreamStore.java deleted file mode 100644 index 2fae8888d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/CompressedStreamStore.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.streams; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.apache.poi.hdgf.HDGFLZW; - -/** - * A StreamStore where the data on-disk is compressed, - * using the crazy Visio LZW - */ -public final class CompressedStreamStore extends StreamStore { - /** The raw, compressed contents */ - private byte[] compressedContents; - /** - * We're not sure what this is, but it comes before the - * real contents in the de-compressed data - */ - private byte[] blockHeader = new byte[4]; - private boolean blockHeaderInContents = false; - - protected byte[] _getCompressedContents() { return compressedContents; } - protected byte[] _getBlockHeader() { return blockHeader; } - - /** - * Creates a new compressed StreamStore, which will handle - * the decompression. - */ - protected CompressedStreamStore(byte[] data, int offset, int length) throws IOException { - this(decompress(data,offset,length)); - - compressedContents = new byte[length]; - System.arraycopy(data, offset, compressedContents, 0, length); - } - /** - * Handles passing the de-compressed data onto our superclass. - */ - private CompressedStreamStore(byte[][] decompressedData) { - super(decompressedData[1], 0, decompressedData[1].length); - blockHeader = decompressedData[0]; - } - - /** - * Some kinds of streams expect their 4 byte header to be - * on the front of the contents. - * They can call this to have it sorted. - */ - protected void copyBlockHeaderToContents() { - if(blockHeaderInContents) return; - - prependContentsWith(blockHeader); - blockHeaderInContents = true; - } - - - /** - * Decompresses the given data, returning it as header + contents - */ - public static byte[][] decompress(byte[] data, int offset, int length) throws IOException { - ByteArrayInputStream bais = new ByteArrayInputStream(data, offset, length); - - // Decompress - HDGFLZW lzw = new HDGFLZW(); - byte[] decompressed = lzw.decompress(bais); - - // Split into header and contents - byte[][] ret = new byte[2][]; - ret[0] = new byte[4]; - ret[1] = new byte[decompressed.length - 4]; - - System.arraycopy(decompressed, 0, ret[0], 0, 4); - System.arraycopy(decompressed, 4, ret[1], 0, ret[1].length); - - // All done - return ret; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java b/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java deleted file mode 100644 index e7f3cf39d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hdgf.streams; - -import org.apache.poi.hdgf.chunks.ChunkFactory; -import org.apache.poi.hdgf.pointers.Pointer; -import org.apache.poi.hdgf.pointers.PointerFactory; - -/** - * A stream that holds pointers, possibly in addition to some - * other data too. - */ -public class PointerContainingStream extends Stream { // TODO - instantiable superclass - private Pointer[] childPointers; - private Stream[] childStreams; - - private ChunkFactory chunkFactory; - private PointerFactory pointerFactory; - - protected PointerContainingStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory, PointerFactory pointerFactory) { - super(pointer, store); - this.chunkFactory = chunkFactory; - this.pointerFactory = pointerFactory; - - // Have the child pointers identified and created - childPointers = pointerFactory.createContainerPointers(pointer, store.getContents()); - } - - /** - * Returns all the pointers that we contain - */ - protected Pointer[] getChildPointers() { return childPointers; } - /** - * Returns all the "child" streams. - * These are all the streams pointed to by the pointers - * that we contain. - */ - public Stream[] getPointedToStreams() { return childStreams; } - - /** - * Performs a recursive search, identifying the pointers we contain, - * creating the Streams for where they point to, then searching - * those if appropriate. - */ - public void findChildren(byte[] documentData) { - // For each pointer, generate the Stream it points to - childStreams = new Stream[childPointers.length]; - for(int i=0; i attributes = new ArrayList(); - private final List mapiAttributes = new ArrayList(); - - protected void addAttribute(TNEFAttribute attr) { - attributes.add(attr); - - if(attr instanceof TNEFMAPIAttribute) { - TNEFMAPIAttribute tnefMAPI = (TNEFMAPIAttribute)attr; - mapiAttributes.addAll( tnefMAPI.getMAPIAttributes() ); - } - } - - /** - * Return the attachment attribute with the given ID, - * or null if there isn't one. - */ - public TNEFAttribute getAttribute(TNEFProperty id) { - for(TNEFAttribute attr : attributes) { - if(attr.getProperty() == id) { - return attr; - } - } - return null; - } - - /** - * Return the attachment MAPI Attribute with the given ID, - * or null if there isn't one. - */ - public MAPIAttribute getMAPIAttribute(MAPIProperty id) { - for(MAPIAttribute attr : mapiAttributes) { - if(attr.getProperty() == id) { - return attr; - } - } - return null; - } - - /** - * Returns all HMEF/TNEF attributes of the attachment, - * such as filename, icon and contents - */ - public List getAttributes() { - return attributes; - } - - /** - * Returns all MAPI attributes of the attachment, - * such as extension, encoding, size and position - */ - public List getMAPIAttributes() { - return mapiAttributes; - } - - - /** - * Return the string value of the mapi property, or null - * if it isn't set - */ - private String getString(MAPIProperty id) { - return MAPIStringAttribute.getAsString( getMAPIAttribute(id) ); - } - /** - * Returns the string value of the TNEF property, or - * null if it isn't set - */ - private String getString(TNEFProperty id) { - return TNEFStringAttribute.getAsString( getAttribute(id) ); - } - - /** - * Returns the short filename - */ - public String getFilename() { - return getString(TNEFProperty.ID_ATTACHTITLE); - } - /** - * Returns the long filename - */ - public String getLongFilename() { - return getString(MAPIProperty.ATTACH_LONG_FILENAME); - } - /** - * Returns the file extension - */ - public String getExtension() { - return getString(MAPIProperty.ATTACH_EXTENSION); - } - - /** - * Return when the file was last modified, if known. - */ - public Date getModifiedDate() { - return TNEFDateAttribute.getAsDate( - getAttribute(TNEFProperty.ID_ATTACHMODIFYDATE) - ); - } - - /** - * Returns the contents of the attachment. - * - * @throws IllegalArgumentException if there is no AttachmentData available in this Attachment - */ - public byte[] getContents() { - TNEFAttribute contents = getAttribute(TNEFProperty.ID_ATTACHDATA); - if(contents == null) { - throw new IllegalArgumentException("Attachment corrupt - no Data section"); - } - return contents.getData(); - } - - /** - * Returns the Meta File rendered representation - * of the attachment, or null if not set. - */ - public byte[] getRenderedMetaFile() { - TNEFAttribute meta = getAttribute(TNEFProperty.ID_ATTACHMETAFILE); - if(meta == null) return null; - return meta.getData(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/CompressedRTF.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/CompressedRTF.java deleted file mode 100644 index ad38755a0..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/CompressedRTF.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; - -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LZWDecompresser; -import org.apache.poi.util.LittleEndian; - - -/** - * Within a {@link HMEFMessage}, the content is often - * stored in as RTF, but LZW compressed. This class - * handles decompressing it for you. - */ -public final class CompressedRTF extends LZWDecompresser { - public static final byte[] COMPRESSED_SIGNATURE = - new byte[] { (byte)'L', (byte)'Z', (byte)'F', (byte)'u' }; - public static final byte[] UNCOMPRESSED_SIGNATURE = - new byte[] { (byte)'M', (byte)'E', (byte)'L', (byte)'A' }; - public static final int COMPRESSED_SIGNATURE_INT = - LittleEndian.getInt(COMPRESSED_SIGNATURE); - public static final int UNCOMPRESSED_SIGNATURE_INT = - LittleEndian.getInt(UNCOMPRESSED_SIGNATURE); - - // The 4096 byte LZW dictionary is pre-loaded with some common - // RTF fragments. These come from RTFLIB32.LIB, which ships - // with older versions of Visual Studio or the EDK - public static final String LZW_RTF_PRELOAD = - "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss " + - "\\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier" + - "{\\colortbl\\red0\\green0\\blue0\n\r\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx"; - - private int compressedSize; - private int decompressedSize; - - public CompressedRTF() { - // Out flag has the normal meaning - // Length wise, we're 2 longer than we say, so the max len is 18 - // Endian wise, we're big endian, so 0x1234 is pos 0x123 - super(true, 2, true); - } - - /** - * Decompresses the whole of the compressed RTF - * stream, outputting the resulting RTF bytes. - * Note - will decompress any padding at the end of - * the input, if present, use {@link #getDeCompressedSize()} - * if you need to know how much of the result is - * real. (Padding may be up to 7 bytes). - */ - public void decompress(InputStream src, OutputStream res) throws IOException { - // Validate the header on the front of the RTF - compressedSize = LittleEndian.readInt(src); - decompressedSize = LittleEndian.readInt(src); - int compressionType = LittleEndian.readInt(src); - /* int dataCRC = */ LittleEndian.readInt(src); - - // TODO - Handle CRC checking on the output side - - // Do we need to do anything? - if(compressionType == UNCOMPRESSED_SIGNATURE_INT) { - // Nope, nothing fancy to do - IOUtils.copy(src, res); - } else if(compressionType == COMPRESSED_SIGNATURE_INT) { - // We need to decompress it below - } else { - throw new IllegalArgumentException("Invalid compression signature " + compressionType); - } - - // Have it processed - super.decompress(src, res); - } - - /** - * Returns how big the compressed version was. - */ - public int getCompressedSize() { - // Return the size less the header - return compressedSize - 12; - } - - /** - * Returns how big the decompressed version was. - */ - public int getDeCompressedSize() { - return decompressedSize; - } - - /** - * We use regular dictionary offsets, so no - * need to change anything - */ - @Override - protected int adjustDictionaryOffset(int offset) { - return offset; - } - - @Override - protected int populateDictionary(byte[] dict) { - // Copy in the RTF constants - byte[] preload = LZW_RTF_PRELOAD.getBytes(Charset.forName("US-ASCII")); - System.arraycopy(preload, 0, dict, 0, preload.length); - - // Start adding new codes after the constants - return preload.length; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java deleted file mode 100644 index 5dd7a827f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java +++ /dev/null @@ -1,199 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.hmef.attribute.MAPIAttribute; -import org.apache.poi.hmef.attribute.MAPIStringAttribute; -import org.apache.poi.hmef.attribute.TNEFAttribute; -import org.apache.poi.hmef.attribute.TNEFMAPIAttribute; -import org.apache.poi.hmef.attribute.TNEFProperty; -import org.apache.poi.hsmf.datatypes.MAPIProperty; -import org.apache.poi.util.LittleEndian; - -/** - * HMEF - Implementation of the Microsoft TNEF message - * encoding format (aka winmail.dat) - * See: - * http://support.microsoft.com/kb/241538 - * http://en.wikipedia.org/wiki/Transport_Neutral_Encapsulation_Format - * http://search.cpan.org/dist/Convert-TNEF/ - */ -public final class HMEFMessage { - public static final int HEADER_SIGNATURE = 0x223e9f78; - - @SuppressWarnings("unused") - private int fileId; - private final List messageAttributes = new ArrayList(); - private final List mapiAttributes = new ArrayList(); - private final List attachments = new ArrayList(); - - public HMEFMessage(InputStream inp) throws IOException { - try { - // Check the signature matches - int sig = LittleEndian.readInt(inp); - if (sig != HEADER_SIGNATURE) { - throw new IllegalArgumentException( - "TNEF signature not detected in file, " + - "expected " + HEADER_SIGNATURE + " but got " + sig - ); - } - - // Read the File ID - fileId = LittleEndian.readUShort(inp); - - // Now begin processing the contents - process(inp); - } finally { - inp.close(); - } - } - - private void process(InputStream inp) throws IOException { - int level; - do { - // Fetch the level - level = inp.read(); - - // Decide what to attach it to, based on the levels and IDs - switch (level) { - case TNEFProperty.LEVEL_MESSAGE: - processMessage(inp); - break; - case TNEFProperty.LEVEL_ATTACHMENT: - processAttachment(inp); - break; - // ignore trailing newline - case '\r': - case '\n': - case TNEFProperty.LEVEL_END_OF_FILE: - break; - default: - throw new IllegalStateException("Unhandled level " + level); - } - } while (level != TNEFProperty.LEVEL_END_OF_FILE); - } - - void processMessage(InputStream inp) throws IOException { - // Build the attribute - TNEFAttribute attr = TNEFAttribute.create(inp); - - messageAttributes.add(attr); - - if (attr instanceof TNEFMAPIAttribute) { - TNEFMAPIAttribute tnefMAPI = (TNEFMAPIAttribute) attr; - mapiAttributes.addAll(tnefMAPI.getMAPIAttributes()); - } - } - - void processAttachment(InputStream inp) throws IOException { - // Build the attribute - TNEFAttribute attr = TNEFAttribute.create(inp); - - // Previous attachment or a new one? - if (attachments.isEmpty() - || attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) { - attachments.add(new Attachment()); - } - - // Save the attribute for it - Attachment attach = attachments.get(attachments.size() - 1); - attach.addAttribute(attr); - } - - /** - * Returns all HMEF/TNEF attributes of the message. - * Note - In a typical message, most of the interesting properties - * are stored as {@link MAPIAttribute}s - see {@link #getMessageMAPIAttributes()} - */ - public List getMessageAttributes() { - return Collections.unmodifiableList(messageAttributes); - } - - /** - * Returns all MAPI attributes of the message. - * Note - A small number of HMEF/TNEF specific attributes normally - * apply to most messages, see {@link #getMessageAttributes()} - */ - public List getMessageMAPIAttributes() { - return Collections.unmodifiableList(mapiAttributes); - } - - /** - * Returns all the Attachments of the message. - */ - public List getAttachments() { - return Collections.unmodifiableList(attachments); - } - - /** - * Return the message attribute with the given ID, - * or null if there isn't one. - */ - public TNEFAttribute getMessageAttribute(TNEFProperty id) { - for (TNEFAttribute attr : messageAttributes) { - if (attr.getProperty() == id) { - return attr; - } - } - return null; - } - - /** - * Return the message MAPI Attribute with the given ID, - * or null if there isn't one. - */ - public MAPIAttribute getMessageMAPIAttribute(MAPIProperty id) { - for (MAPIAttribute attr : mapiAttributes) { - // Because of custom properties, match on ID not literal property object - if (attr.getProperty().id == id.id) { - return attr; - } - } - return null; - } - - /** - * Return the string value of the mapi property, or null - * if it isn't set - */ - private String getString(MAPIProperty id) { - return MAPIStringAttribute.getAsString( getMessageMAPIAttribute(id) ); - } - - /** - * Returns the Message Subject, or null if the mapi property - * for this isn't set - */ - public String getSubject() { - return getString(MAPIProperty.CONVERSATION_TOPIC); - } - - /** - * Returns the Message Body, as RTF, or null if the mapi property - * for this isn't set - */ - public String getBody() { - return getString(MAPIProperty.RTF_COMPRESSED); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java deleted file mode 100644 index 84161f848..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hsmf.datatypes.MAPIProperty; -import org.apache.poi.hsmf.datatypes.Types; -import org.apache.poi.hsmf.datatypes.Types.MAPIType; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - -/** - * A pure-MAPI attribute which applies to a {@link HMEFMessage} - * or one of its {@link Attachment}s. - */ -public class MAPIAttribute { - private final MAPIProperty property; - private final int type; - private final byte[] data; - - /** - * Constructs a single new attribute from - * the contents of the stream - */ - public MAPIAttribute(MAPIProperty property, int type, byte[] data) { - this.property = property; - this.type = type; - this.data = data.clone(); - } - - public MAPIProperty getProperty() { - return property; - } - - public int getType() { - return type; - } - - public byte[] getData() { - return data; - } - - public String toString() { - String hex; - if(data.length <= 16) { - hex = HexDump.toHex(data); - } else { - byte[] d = new byte[16]; - System.arraycopy(data, 0, d, 0, 16); - hex = HexDump.toHex(d); - hex = hex.substring(0, hex.length()-1) + ", ....]"; - } - - return property.toString() + " " + hex; - } - - /** - * Parses a MAPI Properties TNEF Attribute, and returns - * the list of MAPI Attributes contained within it - */ - public static List create(TNEFAttribute parent) throws IOException { - if(parent.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) { - // Regular MAPI Properties, normally on the message - } - else if(parent.getProperty() == TNEFProperty.ID_ATTACHMENT) { - // MAPI Properties for an attachment - } - else { - // Something else, oh dear... - throw new IllegalArgumentException( - "Can only create from a MAPIProperty attribute, " + - "instead received a " + parent.getProperty() + " one" - ); - } - ByteArrayInputStream inp = new ByteArrayInputStream(parent.getData()); - - // First up, get the number of attributes - int count = LittleEndian.readInt(inp); - List attrs = new ArrayList(); - - // Now, read each one in in turn - for(int i=0; i= 0x8000 && id <= 0xFFFF) { - byte[] guid = new byte[16]; - IOUtils.readFully(inp, guid); - int mptype = LittleEndian.readInt(inp); - - // Get the name of it - String name; - if(mptype == 0) { - // It's based on a normal one - int mpid = LittleEndian.readInt(inp); - MAPIProperty base = MAPIProperty.get(mpid); - name = base.name; - } else { - // Custom name was stored - int mplen = LittleEndian.readInt(inp); - byte[] mpdata = new byte[mplen]; - IOUtils.readFully(inp, mpdata); - name = StringUtil.getFromUnicodeLE(mpdata, 0, (mplen/2)-1); - skipToBoundary(mplen, inp); - } - - // Now create - prop = MAPIProperty.createCustom(id, type, name); - } - if(prop == MAPIProperty.UNKNOWN) { - prop = MAPIProperty.createCustom(id, type, "(unknown " + Integer.toHexString(id) + ")"); - } - - // Now read in the value(s) - int values = 1; - if(isMV || isVL) { - values = LittleEndian.readInt(inp); - } - for(int j=0; j[MS-OXOMSG]: Email Object Protocol - * @see [MS-OXPROPS]: Exchange Server Protocols Master Property List - */ -public final class MAPIDateAttribute extends MAPIAttribute { - private static POILogger logger = POILogFactory.getLogger(MAPIDateAttribute.class); - private Date data; - - /** - * Constructs a single new date attribute from the id, type, - * and the contents of the stream - */ - protected MAPIDateAttribute(MAPIProperty property, int type, byte[] data) { - super(property, type, data); - - // The value is a 64 bit Windows Filetime - this.data = Util.filetimeToDate( - LittleEndian.getLong(data, 0) - ); - } - - public Date getDate() { - return this.data; - } - - public String toString() { - DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ROOT); - DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dfs); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - return getProperty().toString() + " " + df.format(data); - } - - /** - * Returns the Date of a Attribute, converting as appropriate - */ - public static Date getAsDate(MAPIAttribute attr) { - if(attr == null) { - return null; - } - if(attr instanceof MAPIDateAttribute) { - return ((MAPIDateAttribute)attr).getDate(); - } - - logger.log(POILogger.WARN, "Warning, non date property found: " + attr.toString()); - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIRtfAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIRtfAttribute.java deleted file mode 100644 index cd773838c..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIRtfAttribute.java +++ /dev/null @@ -1,78 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.CompressedRTF; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hsmf.datatypes.MAPIProperty; -import org.apache.poi.util.StringUtil; - -/** - * A pure-MAPI attribute holding RTF (compressed or not), which applies - * to a {@link HMEFMessage} or one of its {@link Attachment}s. - */ -public final class MAPIRtfAttribute extends MAPIAttribute { - private final byte[] decompressed; - private final String data; - - public MAPIRtfAttribute(MAPIProperty property, int type, byte[] data) throws IOException { - super(property, type, data); - - // Decompress it, removing any trailing padding as needed - CompressedRTF rtf = new CompressedRTF(); - byte[] tmp = rtf.decompress(new ByteArrayInputStream(data)); - if(tmp.length > rtf.getDeCompressedSize()) { - this.decompressed = new byte[rtf.getDeCompressedSize()]; - System.arraycopy(tmp, 0, decompressed, 0, decompressed.length); - } else { - this.decompressed = tmp; - } - - // Turn the RTF data into a more useful string - this.data = StringUtil.getFromCompressedUnicode(decompressed, 0, decompressed.length); - } - - /** - * Returns the original, compressed RTF - */ - public byte[] getRawData() { - return super.getData(); - } - - /** - * Returns the raw uncompressed RTF data - */ - public byte[] getData() { - return decompressed; - } - - /** - * Returns the uncompressed RTF as a string - */ - public String getDataString() { - return data; - } - - public String toString() { - return getProperty().toString() + " " + data; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java deleted file mode 100644 index 5307e71c7..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.nio.charset.Charset; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hsmf.datatypes.MAPIProperty; -import org.apache.poi.hsmf.datatypes.Types; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * A pure-MAPI attribute holding a String, which applies - * to a {@link HMEFMessage} or one of its {@link Attachment}s. - */ -public final class MAPIStringAttribute extends MAPIAttribute { - private static POILogger logger = POILogFactory.getLogger(MAPIStringAttribute.class); - private static final String CODEPAGE = "CP1252"; - private final String data; - - public MAPIStringAttribute(MAPIProperty property, int type, byte[] data) { - super(property, type, data); - - String tmpData = null; - if(type == Types.ASCII_STRING.getId()) { - tmpData = new String(data, Charset.forName(CODEPAGE)); - } else if(type == Types.UNICODE_STRING.getId()) { - tmpData = StringUtil.getFromUnicodeLE(data); - } else { - throw new IllegalArgumentException("Not a string type " + type); - } - - // Strip off the null terminator if present - if(tmpData.endsWith("\0")) { - tmpData = tmpData.substring(0, tmpData.length()-1); - } - this.data = tmpData; - } - - public String getDataString() { - return data; - } - - public String toString() { - return getProperty().toString() + " " + data; - } - - /** - * Returns the string of a Attribute, converting as appropriate - */ - public static String getAsString(MAPIAttribute attr) { - if(attr == null) { - return null; - } - if(attr instanceof MAPIStringAttribute) { - return ((MAPIStringAttribute)attr).getDataString(); - } - if(attr instanceof MAPIRtfAttribute) { - return ((MAPIRtfAttribute)attr).getDataString(); - } - - logger.log(POILogger.WARN, "Warning, non string property found: " + attr.toString()); - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFAttribute.java deleted file mode 100644 index af0ac3dcb..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFAttribute.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; - - -/** - * An attribute which applies to a {@link HMEFMessage} - * or one of its {@link Attachment}s. - * Note - the types and IDs differ from standard Outlook/MAPI - * ones, so we can't just re-use the HSMF ones. - */ -public class TNEFAttribute { - private final TNEFProperty property; - private final int type; - private final byte[] data; - private final int checksum; - - /** - * Constructs a single new attribute from the id, type, - * and the contents of the stream - */ - protected TNEFAttribute(int id, int type, InputStream inp) throws IOException { - this.type = type; - int length = LittleEndian.readInt(inp); - - property = TNEFProperty.getBest(id, type); - data = new byte[length]; - IOUtils.readFully(inp, data); - - checksum = LittleEndian.readUShort(inp); - } - - /** - * Creates a new TNEF Attribute by reading data from - * the stream within a {@link HMEFMessage} - */ - public static TNEFAttribute create(InputStream inp) throws IOException { - int id = LittleEndian.readUShort(inp); - int type = LittleEndian.readUShort(inp); - - // Create as appropriate - if(id == TNEFProperty.ID_MAPIPROPERTIES.id || - id == TNEFProperty.ID_ATTACHMENT.id) { - return new TNEFMAPIAttribute(id, type, inp); - } - if(type == TNEFProperty.TYPE_STRING || - type == TNEFProperty.TYPE_TEXT) { - return new TNEFStringAttribute(id, type, inp); - } - if(type == TNEFProperty.TYPE_DATE) { - return new TNEFDateAttribute(id, type, inp); - } - return new TNEFAttribute(id, type, inp); - } - - public TNEFProperty getProperty() { - return property; - } - - public int getType() { - return type; - } - - public byte[] getData() { - return data; - } - - public String toString() { - return "Attribute " + property.toString() + ", type=" + type + - ", data length=" + data.length; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java deleted file mode 100644 index 1df0d9691..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java +++ /dev/null @@ -1,101 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.io.IOException; -import java.io.InputStream; -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hpsf.Util; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * A Date attribute which applies to a {@link HMEFMessage} - * or one of its {@link Attachment}s. - */ -public final class TNEFDateAttribute extends TNEFAttribute { - private static POILogger logger = POILogFactory.getLogger(TNEFDateAttribute.class); - private Date data; - - /** - * Constructs a single new date attribute from the id, type, - * and the contents of the stream - */ - protected TNEFDateAttribute(int id, int type, InputStream inp) throws IOException { - super(id, type, inp); - - byte[] binData = getData(); - if(binData.length == 8) { - // The value is a 64 bit Windows Filetime - this.data = Util.filetimeToDate( - LittleEndian.getLong(getData(), 0) - ); - } else if(binData.length == 14) { - // It's the 7 date fields. We think it's in UTC... - Calendar c = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); - c.set(Calendar.YEAR, LittleEndian.getUShort(binData, 0)); - c.set(Calendar.MONTH, LittleEndian.getUShort(binData, 2) - 1); // Java months are 0 based! - c.set(Calendar.DAY_OF_MONTH, LittleEndian.getUShort(binData, 4)); - c.set(Calendar.HOUR_OF_DAY, LittleEndian.getUShort(binData, 6)); - c.set(Calendar.MINUTE, LittleEndian.getUShort(binData, 8)); - c.set(Calendar.SECOND, LittleEndian.getUShort(binData, 10)); - // The 7th field is day of week, which we don't require - c.clear(Calendar.MILLISECOND); // Not set in the file - this.data = c.getTime(); - } else { - throw new IllegalArgumentException("Invalid date, found " + binData.length + " bytes"); - } - } - - public Date getDate() { - return this.data; - } - - public String toString() { - DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ROOT); - DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dfs); - df.setTimeZone(LocaleUtil.TIMEZONE_UTC); - return "Attribute " + getProperty().toString() + ", type=" + getType() + - ", date=" + df.format(data); - } - - /** - * Returns the Date of a Attribute, converting as appropriate - */ - public static Date getAsDate(TNEFAttribute attr) { - if(attr == null) { - return null; - } - if(attr instanceof TNEFDateAttribute) { - return ((TNEFDateAttribute)attr).getDate(); - } - - logger.log(POILogger.WARN, "Warning, non date property found: " + attr.toString()); - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFMAPIAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFMAPIAttribute.java deleted file mode 100644 index 3144981fe..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFMAPIAttribute.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; - -/** - * A TNEF Attribute holding MAPI Attributes, which applies to a - * {@link HMEFMessage} or one of its {@link Attachment}s. - */ -public final class TNEFMAPIAttribute extends TNEFAttribute { - private final List attributes; - - /** - * Constructs a single new mapi containing attribute from the - * id, type, and the contents of the stream - */ - protected TNEFMAPIAttribute(int id, int type, InputStream inp) throws IOException { - super(id, type, inp); - - attributes = MAPIAttribute.create(this); - } - - public List getMAPIAttributes() { - return attributes; - } - - public String toString() { - return "Attribute " + getProperty().toString() + ", type=" + getType() + - ", " + attributes.size() + " MAPI Attributes"; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFProperty.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFProperty.java deleted file mode 100644 index de4d8a5fc..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFProperty.java +++ /dev/null @@ -1,216 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Holds the list of TNEF Attributes, and allows lookup - * by friendly name, ID and MAPI Property Name. - * - * Note - the types and IDs differ from standard Outlook/MAPI - * ones, so we can't just re-use the HSMF ones. - */ -public final class TNEFProperty { - private static Map> properties = new HashMap>(); - - // Types taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributetype%28v=EXCHG.140%29.aspx - public static final int TYPE_TRIPLES = 0x0000; - public static final int TYPE_STRING = 0x0001; - public static final int TYPE_TEXT = 0x0002; - public static final int TYPE_DATE = 0x0003; - public static final int TYPE_SHORT = 0x0004; - public static final int TYPE_LONG = 0x0005; - public static final int TYPE_BYTE = 0x0006; - public static final int TYPE_WORD = 0x0007; - public static final int TYPE_DWORD = 0x0008; - public static final int TYPE_MAX = 0x0009; - - // Types taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertytype%28v=EXCHG.140%29.aspx - /** AppTime - application time value */ - public static final int PTYPE_APPTIME = 0x0007; - /** Binary - counted byte array */ - public static final int PTYPE_BINARY = 0x0102; - /** Boolean - 16-bit Boolean value. '0' is false. Non-zero is true */ - public static final int PTYPE_BOOLEAN = 0x000B; - /** ClassId - OLE GUID */ - public static final int PTYPE_CLASSID = 0x0048; - /** Currency - signed 64-bit integer that represents a base ten decimal with four digits to the right of the decimal point */ - public static final int PTYPE_CURRENCY = 0x0006; - /** Double - floating point double */ - public static final int PTYPE_DOUBLE = 0x0005; - /** Error - 32-bit error value */ - public static final int PTYPE_ERROR = 0x000A; - /** I2 - signed 16-bit value */ - public static final int PTYPE_I2 = 0x0002; - /** I8 - 8-byte signed integer */ - public static final int PTYPE_I8 = 0x0014; - /** Long - signed 32-bit value */ - public static final int PTYPE_LONG = 0x0003; - /** MultiValued - Value part contains multiple values */ - public static final int PTYPE_MULTIVALUED = 0x1000; - /** Null - NULL property value */ - public static final int PTYPE_NULL = 0x0001; - /** Object - embedded object in a property */ - public static final int PTYPE_OBJECT = 0x000D; - /** R4 - 4-byte floating point value */ - public static final int PTYPE_R4 = 0x0004; - /** String8 - null-terminated 8-bit character string */ - public static final int PTYPE_STRING8 = 0x001E; - /** SysTime - FILETIME 64-bit integer specifying the number of 100ns periods since Jan 1, 1601 */ - public static final int PTYPE_SYSTIME = 0x0040; - /** Unicode - null-terminated Unicode string */ - public static final int PTYPE_UNICODE = 0x001F; - /** Unspecified */ - public static final int PTYPE_UNSPECIFIED = 0x0000; - - - // Levels taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributelevel%28v=EXCHG.140%29.aspx - public static final int LEVEL_MESSAGE = 0x01; - public static final int LEVEL_ATTACHMENT = 0x02; - public static final int LEVEL_END_OF_FILE = -0x01; - - // ID information taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributetag%28v=EXCHG.140%29.aspx - public static final TNEFProperty ID_AIDOWNER = - new TNEFProperty(0x0008, TYPE_LONG, "AidOwner", "PR_OWNER_APPT_ID"); - public static final TNEFProperty ID_ATTACHCREATEDATE = - new TNEFProperty(0x8012, TYPE_DATE, "AttachCreateDate", "PR_CREATION_TIME"); - public static final TNEFProperty ID_ATTACHDATA = - new TNEFProperty(0x800F, TYPE_BYTE, "AttachData", "PR_ATTACH_DATA_BIN"); - public static final TNEFProperty ID_ATTACHMENT = - new TNEFProperty(0x9005, TYPE_BYTE, "Attachment", null); - public static final TNEFProperty ID_ATTACHMETAFILE = - new TNEFProperty(0x8011, TYPE_BYTE, "AttachMetaFile", "PR_ATTACH_RENDERING"); - public static final TNEFProperty ID_ATTACHMODIFYDATE = - new TNEFProperty(0x8013, TYPE_DATE, "AttachModifyDate", "PR_LAST_MODIFICATION_TIME"); - public static final TNEFProperty ID_ATTACHRENDERDATA = - new TNEFProperty(0x9002, TYPE_BYTE, "AttachRenderData", "attAttachRenddata"); - public static final TNEFProperty ID_ATTACHTITLE = - new TNEFProperty(0x8010, TYPE_STRING, "AttachTitle", "PR_ATTACH_FILENAME"); - public static final TNEFProperty ID_ATTACHTRANSPORTFILENAME = - new TNEFProperty(0x9001, TYPE_BYTE, "AttachTransportFilename", "PR_ATTACH_TRANSPORT_NAME"); - public static final TNEFProperty ID_BODY = - new TNEFProperty(0x800C, TYPE_TEXT, "Body", "PR_BODY"); - public static final TNEFProperty ID_CONVERSATIONID = - new TNEFProperty(0x800B, TYPE_STRING, "ConversationId", "PR_CONVERSATION_KEY"); - public static final TNEFProperty ID_DATEEND = - new TNEFProperty(0x0007, TYPE_DATE, "DateEnd", "PR_END_DATE"); - public static final TNEFProperty ID_DATEMODIFIED = - new TNEFProperty(0x8020, TYPE_DATE, "DateModified", "PR_LAST_MODIFICATION_TIME "); - public static final TNEFProperty ID_DATERECEIVED = - new TNEFProperty(0x8006, TYPE_DATE, "DateReceived", "PR_MESSAGE_DELIVERY_TIME "); - public static final TNEFProperty ID_DATESENT = - new TNEFProperty(0x8005, TYPE_DATE, "DateSent", "PR_CLIENT_SUBMIT_TIME "); - public static final TNEFProperty ID_DATESTART = - new TNEFProperty(0x0006, TYPE_DATE, "DateStart", "PR_START_DATE "); - public static final TNEFProperty ID_DELEGATE = - new TNEFProperty(0x0002, TYPE_BYTE, "Delegate", "PR_RCVD_REPRESENTING_xxx "); - public static final TNEFProperty ID_FROM = - new TNEFProperty(0x8000, TYPE_STRING, "From", "PR_SENDER_ENTRYID"); - public static final TNEFProperty ID_MAPIPROPERTIES = - new TNEFProperty(0x9003, TYPE_BYTE, "MapiProperties", null); - public static final TNEFProperty ID_MESSAGECLASS = - new TNEFProperty(0x8008, TYPE_WORD, "MessageClass", "PR_MESSAGE_CLASS "); - public static final TNEFProperty ID_MESSAGEID = - new TNEFProperty(0x8009, TYPE_STRING, "MessageId", "PR_SEARCH_KEY"); - public static final TNEFProperty ID_MESSAGESTATUS = - new TNEFProperty(0x8007, TYPE_BYTE, "MessageStatus", "PR_MESSAGE_FLAGS"); - public static final TNEFProperty ID_NULL = - new TNEFProperty(0x0000, -1, "Null", null); - public static final TNEFProperty ID_OEMCODEPAGE = - new TNEFProperty(0x9007, TYPE_BYTE, "OemCodepage", "AttOemCodepage"); - public static final TNEFProperty ID_ORIGINALMESSAGECLASS = - new TNEFProperty(0x0006, TYPE_WORD, "OriginalMessageClass", "PR_ORIG_MESSAGE_CLASS"); - public static final TNEFProperty ID_OWNER = - new TNEFProperty(0x0000, TYPE_BYTE, "Owner", "PR_RCVD_REPRESENTING_xxx"); - public static final TNEFProperty ID_PARENTID = - new TNEFProperty(0x800A, TYPE_STRING, "ParentId", "PR_PARENT_KEY"); - public static final TNEFProperty ID_PRIORITY = - new TNEFProperty(0x800D, TYPE_SHORT, "Priority", "PR_IMPORTANCE"); - public static final TNEFProperty ID_RECIPIENTTABLE = - new TNEFProperty(0x9004, TYPE_BYTE, "RecipientTable", "PR_MESSAGE_RECIPIENTS"); - public static final TNEFProperty ID_REQUESTRESPONSE = - new TNEFProperty(0x009, TYPE_SHORT, "RequestResponse", "PR_RESPONSE_REQUESTED"); - public static final TNEFProperty ID_SENTFOR = - new TNEFProperty(0x0001, TYPE_BYTE, "SentFor", "PR_SENT_REPRESENTING_xxx"); - public static final TNEFProperty ID_SUBJECT = - new TNEFProperty(0x8004, TYPE_STRING, "Subject", "PR_SUBJECT"); - public static final TNEFProperty ID_TNEFVERSION = - new TNEFProperty(0x9006, TYPE_DWORD, "TnefVersion", "attTnefVersion"); - public static final TNEFProperty ID_UNKNOWN = - new TNEFProperty(-1, -1, "Unknown", null); - - /** The TNEF Property ID */ - public final int id; - /** Usual Type */ - public final int usualType; - /** Property Name */ - public final String name; - /** Equivalent MAPI Property */ - public final String mapiProperty; - - private TNEFProperty(int id, int usualType, String name, String mapiProperty) { - this.id = id; - this.usualType = usualType; - this.name = name; - this.mapiProperty = mapiProperty; - - // Store it for lookup - if(! properties.containsKey(id)) { - properties.put(id, new ArrayList()); - } - properties.get(id).add(this); - } - - public static TNEFProperty getBest(int id, int type) { - List attrs = properties.get(id); - if(attrs == null) { - return ID_UNKNOWN; - } - - // If there's only one, it's easy - if(attrs.size() == 1) { - return attrs.get(0); - } - - // Try by type - for(TNEFProperty attr : attrs) { - if(attr.usualType == type) return attr; - } - - // Go for the first if we can't otherwise decide... - return attrs.get(0); - } - - public String toString() { - StringBuffer str = new StringBuffer(); - str.append(name); - str.append(" ["); - str.append(id); - str.append("]"); - if(mapiProperty != null) { - str.append(" ("); - str.append(mapiProperty); - str.append(")"); - } - return str.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFStringAttribute.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFStringAttribute.java deleted file mode 100644 index 34e1ef369..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFStringAttribute.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.attribute; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * A String attribute which applies to a {@link HMEFMessage} - * or one of its {@link Attachment}s. - */ -public final class TNEFStringAttribute extends TNEFAttribute { - private static POILogger logger = POILogFactory.getLogger(TNEFStringAttribute.class); - private String data; - - /** - * Constructs a single new string attribute from the id, type, - * and the contents of the stream - */ - protected TNEFStringAttribute(int id, int type, InputStream inp) throws IOException { - super(id, type, inp); - - String tmpData = null; - byte[] data = getData(); - if(getType() == TNEFProperty.TYPE_TEXT) { - tmpData = StringUtil.getFromUnicodeLE(data); - } else { - tmpData = StringUtil.getFromCompressedUnicode( - data, 0, data.length - ); - } - - // Strip off the null terminator if present - if(tmpData.endsWith("\0")) { - tmpData = tmpData.substring(0, tmpData.length()-1); - } - this.data = tmpData; - } - - public String getString() { - return this.data; - } - - public String toString() { - return "Attribute " + getProperty().toString() + ", type=" + getType() + - ", data=" + getString(); - } - - /** - * Returns the string of a Attribute, converting as appropriate - */ - public static String getAsString(TNEFAttribute attr) { - if(attr == null) { - return null; - } - if(attr instanceof TNEFStringAttribute) { - return ((TNEFStringAttribute)attr).getString(); - } - - logger.log(POILogger.WARN, "Warning, non string property found: " + attr.toString()); - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java deleted file mode 100644 index 3d7bcfefe..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java +++ /dev/null @@ -1,158 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.dev; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hmef.attribute.MAPIAttribute; -import org.apache.poi.hmef.attribute.TNEFAttribute; -import org.apache.poi.hmef.attribute.TNEFDateAttribute; -import org.apache.poi.hmef.attribute.TNEFProperty; -import org.apache.poi.hmef.attribute.TNEFStringAttribute; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; - -/** - * Developer focused raw dumper - */ -public final class HMEFDumper { - public static void main(String[] args) throws Exception { - if(args.length < 1) { - throw new IllegalArgumentException("Filename must be given"); - } - - boolean truncatePropData = true; - for(int i=0; i 0) { - int len = attr.getData().length; - if(truncatePropertyData) { - len = Math.min( attr.getData().length, 48 ); - } - - int loops = len/16; - if(loops == 0) loops = 1; - - for(int i=0; i attrs = MAPIAttribute.create(attr); - for(MAPIAttribute ma : attrs) { - System.out.println(indent + indent + ma); - } - System.out.println(); - } - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java b/trunk/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java deleted file mode 100644 index e945cbae4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef.extractor; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.hmef.Attachment; -import org.apache.poi.hmef.HMEFMessage; -import org.apache.poi.hmef.attribute.MAPIAttribute; -import org.apache.poi.hmef.attribute.MAPIRtfAttribute; -import org.apache.poi.hmef.attribute.MAPIStringAttribute; -import org.apache.poi.hsmf.datatypes.MAPIProperty; -import org.apache.poi.hsmf.datatypes.Types; -import org.apache.poi.util.StringUtil; - -/** - * A utility for extracting out the message body, and all attachments - * from a HMEF/TNEF/winmail.dat file - */ -public final class HMEFContentsExtractor { - /** - * Usage: HMEFContentsExtractor <filename> <output dir> - */ - public static void main(String[] args) throws IOException { - if(args.length < 2) { - System.err.println("Use:"); - System.err.println(" HMEFContentsExtractor "); - System.err.println(""); - System.err.println(""); - System.err.println("Where is the winmail.dat file to extract,"); - System.err.println(" and is where to place the extracted files"); - System.exit(2); - } - - final String filename = args[0]; - final String outputDir = args[1]; - - HMEFContentsExtractor ext = new HMEFContentsExtractor(new File(filename)); - - File dir = new File(outputDir); - File rtf = new File(dir, "message.rtf"); - if(! dir.exists()) { - throw new FileNotFoundException("Output directory " + dir.getName() + " not found"); - } - - System.out.println("Extracting..."); - ext.extractMessageBody(rtf); - ext.extractAttachments(dir); - System.out.println("Extraction completed"); - } - - private final HMEFMessage message; - public HMEFContentsExtractor(File filename) throws IOException { - this(new HMEFMessage(new FileInputStream(filename))); - } - public HMEFContentsExtractor(HMEFMessage message) { - this.message = message; - } - - /** - * Extracts the RTF message body to the supplied file - */ - public void extractMessageBody(File dest) throws IOException { - MAPIAttribute body = getBodyAttribute(); - if (body == null) { - System.err.println("No message body found, " + dest + " not created"); - return; - } - if (body instanceof MAPIStringAttribute) { - String name = dest.toString(); - if (name.endsWith(".rtf")) { - name = name.substring(0, name.length()-4); - } - dest = new File(name + ".txt"); - } - - OutputStream fout = new FileOutputStream(dest); - try { - if (body instanceof MAPIStringAttribute) { - // Save in a predictable encoding, not raw bytes - String text = ((MAPIStringAttribute)body).getDataString(); - fout.write(text.getBytes(StringUtil.UTF8)); - } else { - // Save the raw bytes, should be raw RTF - fout.write(body.getData()); - } - } finally { - fout.close(); - } - } - - protected MAPIAttribute getBodyAttribute() { - MAPIAttribute body = message.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - if (body != null) return body; - - // See bug #59786 - we'd really like a test file to confirm if this - // is the right properties + if this is truely general or not! - MAPIProperty uncompressedBody = - MAPIProperty.createCustom(0x3fd9, Types.ASCII_STRING, "Uncompressed Body"); - // Return this uncompressed one, or null if that isn't their either - return message.getMessageMAPIAttribute(uncompressedBody); - } - - /** - * Extracts the RTF message body to the supplied stream. If there is no - * RTF message body, nothing will be written to the stream, but no - * errors or exceptions will be raised. - */ - public void extractMessageBody(OutputStream out) throws IOException { - MAPIRtfAttribute body = (MAPIRtfAttribute) - message.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - if (body != null) { - out.write(body.getData()); - } - } - - /** - * Extracts all the message attachments to the supplied directory - */ - public void extractAttachments(File dir) throws IOException { - int count = 0; - for(Attachment att : message.getAttachments()) { - count++; - - // Decide what to call it - String filename = att.getLongFilename(); - if(filename == null || filename.length() == 0) { - filename = att.getFilename(); - } - if(filename == null || filename.length() == 0) { - filename = "attachment" + count; - if(att.getExtension() != null) { - filename += att.getExtension(); - } - } - - // Save it - File file = new File(dir, filename); - OutputStream fout = new FileOutputStream(file); - try { - fout.write( att.getContents() ); - } finally { - fout.close(); - } - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java b/trunk/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java deleted file mode 100644 index 764fa2150..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpbf; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.POIReadOnlyDocument; -import org.apache.poi.hpbf.model.EscherDelayStm; -import org.apache.poi.hpbf.model.EscherStm; -import org.apache.poi.hpbf.model.MainContents; -import org.apache.poi.hpbf.model.QuillContents; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -/** - * This class provides the basic functionality - * for HPBF, our implementation of the publisher - * file format. - */ -public final class HPBFDocument extends POIReadOnlyDocument { - private MainContents mainContents; - private QuillContents quillContents; - private EscherStm escherStm; - private EscherDelayStm escherDelayStm; - - /** - * Opens a new publisher document - */ - public HPBFDocument(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public HPBFDocument(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - public HPBFDocument(InputStream inp) throws IOException { - this(new NPOIFSFileSystem(inp)); - } - - /** - * Opens an embedded publisher document, - * at the given directory. - */ - public HPBFDocument(DirectoryNode dir) throws IOException { - super(dir); - - // Go looking for our interesting child - // streams - mainContents = new MainContents(dir); - quillContents = new QuillContents(dir); - - // Now the Escher bits - escherStm = new EscherStm(dir); - escherDelayStm = new EscherDelayStm(dir); - } - - public MainContents getMainContents() { - return mainContents; - } - public QuillContents getQuillContents() { - return quillContents; - } - public EscherStm getEscherStm() { - return escherStm; - } - public EscherDelayStm getEscherDelayStm() { - return escherDelayStm; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java b/trunk/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java deleted file mode 100644 index 48ad50973..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java +++ /dev/null @@ -1,354 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpbf.dev; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.ddf.DefaultEscherRecordFactory; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.StringUtil; - -/** - * For dumping out the contents of HPBF (Publisher) - * files, while we try to figure out how they're - * constructed. - */ -public final class HPBFDumper { - private NPOIFSFileSystem fs; - public HPBFDumper(NPOIFSFileSystem fs) { - this.fs = fs; - } - - @SuppressWarnings("resource") - public HPBFDumper(InputStream inp) throws IOException { - this(new NPOIFSFileSystem(inp)); - } - - private static byte[] getData(DirectoryNode dir, String name) throws IOException { - // Grab the document stream - InputStream is = dir.createDocumentInputStream(name); - byte[] d = IOUtils.toByteArray(is); - is.close(); - - // All done - return d; - } - - /** - * Dumps out the given number of bytes as hex, - * two chars - */ - private String dumpBytes(byte[] data, int offset, int len) { - StringBuffer ret = new StringBuffer(); - for(int i=0; i"); - System.exit(1); - } - HPBFDumper dump = new HPBFDumper(new NPOIFSFileSystem(new File(args[0]))); - - System.out.println("Dumping " + args[0]); - dump.dumpContents(); - dump.dumpEnvelope(); - dump.dumpEscher(); - dump.dump001CompObj(dump.fs.getRoot()); - dump.dumpQuill(); - - // Still to go: - // (0x03)Internal - // Objects - } - - /** - * Dump out the escher parts of the file. - * Escher -> EscherStm and EscherDelayStm - */ - public void dumpEscher() throws IOException { - DirectoryNode escherDir = (DirectoryNode) - fs.getRoot().getEntry("Escher"); - - dumpEscherStm(escherDir); - dumpEscherDelayStm(escherDir); - } - private void dumpEscherStream(byte[] data) { - DefaultEscherRecordFactory erf = - new DefaultEscherRecordFactory(); - - // Dump - int left = data.length; - while(left > 0) { - EscherRecord er = erf.createRecord(data, 0); - er.fillFields(data, 0, erf); - left -= er.getRecordSize(); - - System.out.println(er.toString()); - } - } - protected void dumpEscherStm(DirectoryNode escherDir) throws IOException { - byte[] data = getData(escherDir, "EscherStm"); - System.out.println(""); - System.out.println("EscherStm - " + data.length + " bytes long:"); - if(data.length > 0) - dumpEscherStream(data); - } - protected void dumpEscherDelayStm(DirectoryNode escherDir) throws IOException { - byte[] data = getData(escherDir, "EscherDelayStm"); - System.out.println(""); - System.out.println("EscherDelayStm - " + data.length + " bytes long:"); - if(data.length > 0) - dumpEscherStream(data); - } - - public void dumpEnvelope() throws IOException { - byte[] data = getData(fs.getRoot(), "Envelope"); - - System.out.println(""); - System.out.println("Envelope - " + data.length + " bytes long:"); - } - - public void dumpContents() throws IOException { - byte[] data = getData(fs.getRoot(), "Contents"); - - System.out.println(""); - System.out.println("Contents - " + data.length + " bytes long:"); - - // 8 bytes, always seems to be - // E8 AC 2C 00 E8 03 05 01 - // E8 AC 2C 00 E8 03 05 01 - - // 4 bytes - size of contents - // 13/15 00 00 01 - - // .... - - // E8 03 08 08 0C 20 03 00 00 00 00 88 16 00 00 00 ..... .......... - - // 01 18 27 00 03 20 00 00 E8 03 08 08 0C 20 03 00 ..'.. ....... .. - - // 01 18 30 00 03 20 00 00 - // E8 03 06 08 07 08 08 08 09 10 01 00 0C 20 04 00 - // 00 00 00 88 1E 00 00 00 - - // 01 18 31 00 03 20 00 00 - // E8 03 06 08 07 08 08 08 09 10 01 00 0C 20 04 00 - // 00 00 00 88 1E 00 00 00 - - // 01 18 32 00 03 20 00 00 - // E8 03 06 08 07 08 08 08 09 10 01 00 0C 20 04 00 - // 00 00 00 88 1E 00 00 00 - } - - public void dumpCONTENTSraw(DirectoryNode dir) throws IOException { - byte[] data = getData(dir, "CONTENTS"); - - System.out.println(""); - System.out.println("CONTENTS - " + data.length + " bytes long:"); - - // Between the start and 0x200 we have - // CHNKINK(space) + 24 bytes - // 0x1800 - // TEXT + 6 bytes - // TEXT + 8 bytes - // 0x1800 - // STSH + 6 bytes - // STSH + 8 bytes - // 0x1800 - // STSH + 6 bytes - // STSH + 8 bytes - // but towards 0x200 the pattern may - // break down a little bit - - // After the second of a given type, - // it seems to be 4 bytes giving the start, - // then 4 bytes giving the length, then - // 18 00 - System.out.println( - new String(data, 0, 8, LocaleUtil.CHARSET_1252) + - dumpBytes(data, 8, 0x20-8) - ); - - int pos = 0x20; - boolean sixNotEight = true; - while(pos < 0x200) { - if(sixNotEight) { - System.out.println( - dumpBytes(data, pos, 2) - ); - pos += 2; - } - String text = new String(data, pos, 4, LocaleUtil.CHARSET_1252); - int blen = 8; - if(sixNotEight) - blen = 6; - System.out.println( - text + " " + dumpBytes(data, pos+4, blen) - ); - - pos += 4 + blen; - sixNotEight = ! sixNotEight; - } - - // Text from 0x200 onwards until we get - // to \r(00)\n(00)(00)(00) - int textStop = -1; - for(int i=0x200; i 0) { - int len = (textStop - 0x200) / 2; - System.out.println(""); - System.out.println( - StringUtil.getFromUnicodeLE(data, 0x200, len) - ); - } - - // The font list comes slightly later - - // The hyperlinks may come before the fonts, - // or slightly in front - } - public void dumpCONTENTSguessed(DirectoryNode dir) throws IOException { - byte[] data = getData(dir, "CONTENTS"); - - System.out.println(""); - System.out.println("CONTENTS - " + data.length + " bytes long:"); - - String[] startType = new String[20]; - String[] endType = new String[20]; - int[] optA = new int[20]; - int[] optB = new int[20]; - int[] optC = new int[20]; - int[] from = new int[20]; - int[] len = new int[20]; - - for(int i=0; i<20; i++) { - int offset = 0x20 + i*24; - if(data[offset] == 0x18 && data[offset+1] == 0x00) { - // Has data - startType[i] = new String(data, offset+2, 4, LocaleUtil.CHARSET_1252); - optA[i] = LittleEndian.getUShort(data, offset+6); - optB[i] = LittleEndian.getUShort(data, offset+8); - optC[i] = LittleEndian.getUShort(data, offset+10); - endType[i] = new String(data, offset+12, 4, LocaleUtil.CHARSET_1252); - from[i] = (int)LittleEndian.getUInt(data, offset+16); - len[i] = (int)LittleEndian.getUInt(data, offset+20); - } else { - // Doesn't have data - } - } - - String text = StringUtil.getFromUnicodeLE( - data, from[0], len[0]/2 - ); - - // Dump - for(int i=0; i<20; i++) { - String num = Integer.toString(i); - if(i < 10) { - num = "0" + i; - } - System.out.print(num + " "); - - if(startType[i] == null) { - System.out.println("(not present)"); - } else { - System.out.println( - "\t" + - startType[i] + " " + - optA[i] + " " + - optB[i] + " " + - optC[i] - ); - System.out.println( - "\t" + - endType[i] + " " + - "from: " + - Integer.toHexString(from[i]) + - " (" + from[i] + ")" + - ", len: " + - Integer.toHexString(len[i]) + - " (" + len[i] + ")" - ); - } - } - - // Text - System.out.println(""); - System.out.println("TEXT:"); - System.out.println(text); - System.out.println(""); - - // All the others - for(int i=0; i<20; i++) { - if(startType[i] == null) { - continue; - } - int start = from[i]; - - System.out.println( - startType[i] + " -> " + endType[i] + - " @ " + Integer.toHexString(start) + - " (" + start + ")" - ); - System.out.println("\t" + dumpBytes(data, start, 4)); - System.out.println("\t" + dumpBytes(data, start+4, 4)); - System.out.println("\t" + dumpBytes(data, start+8, 4)); - System.out.println("\t(etc)"); - } - } - - protected void dump001CompObj(DirectoryNode dir) { - // TODO - } - - public void dumpQuill() throws IOException { - DirectoryNode quillDir = (DirectoryNode) - fs.getRoot().getEntry("Quill"); - DirectoryNode quillSubDir = (DirectoryNode) - quillDir.getEntry("QuillSub"); - - dump001CompObj(quillSubDir); - dumpCONTENTSraw(quillSubDir); - dumpCONTENTSguessed(quillSubDir); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java b/trunk/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java deleted file mode 100644 index 7625a08b8..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpbf.dev; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hpbf.HPBFDocument; -import org.apache.poi.hpbf.model.QuillContents; -import org.apache.poi.hpbf.model.qcbits.QCBit; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.util.HexDump; - -/** - * For dumping out the PLC contents of QC Bits of a - * HPBF (Publisher) file, while we try to figure out - * what the format of them is. - */ -public final class PLCDumper { - private HPBFDocument doc; - private QuillContents qc; - - public PLCDumper(HPBFDocument hpbfDoc) { - doc = hpbfDoc; - qc = doc.getQuillContents(); - } - public PLCDumper(NPOIFSFileSystem fs) throws IOException { - this(new HPBFDocument(fs)); - } - public PLCDumper(InputStream inp) throws IOException { - this(new NPOIFSFileSystem(inp)); - } - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" PLCDumper "); - System.exit(1); - } - PLCDumper dump = new PLCDumper( - new FileInputStream(args[0]) - ); - - System.out.println("Dumping " + args[0]); - dump.dumpPLC(); - } - - private void dumpPLC() { - QCBit[] bits = qc.getBits(); - - for(int i=0; i\n"); - } - } - } - } - - // Get more text - // TODO - - return text.toString(); - } - - - public static void main(String[] args) throws Exception { - if(args.length == 0) { - System.err.println("Use:"); - System.err.println(" PublisherTextExtractor "); - } - - for(int i=0; i ec = new ArrayList(); - int left = data.length; - while(left > 0) { - EscherRecord er = erf.createRecord(data, 0); - er.fillFields(data, 0, erf); - left -= er.getRecordSize(); - - ec.add(er); - } - - records = ec.toArray(new EscherRecord[ec.size()]); - } - - public EscherRecord[] getEscherRecords() { - return records; - } - - /** - * Serialises our Escher children back - * into bytes. - */ - protected void generateData() { - int size = 0; - for(int i=0; i QuillSub -> CONTENTS - */ -public final class QuillContents extends HPBFPart { - private static final String[] PATH = { "Quill", "QuillSub", "CONTENTS", }; - private QCBit[] bits; - - public QuillContents(DirectoryNode baseDir) throws IOException { - super(baseDir, PATH); - - // Now parse the first 512 bytes, and produce - // all our bits - - // Check first 8 bytes - String f8 = new String(data, 0, 8, LocaleUtil.CHARSET_1252); - if(! f8.equals("CHNKINK ")) { - throw new IllegalArgumentException("Expecting 'CHNKINK ' but was '"+f8+"'"); - } - // Ignore the next 24, for now at least - - // Now, parse all our QC Bits - bits = new QCBit[20]; - for(int i=0; i<20; i++) { - int offset = 0x20 + i*24; - if(data[offset] == 0x18 && data[offset+1] == 0x00) { - // Has some data - String thingType = new String(data, offset+2, 4, LocaleUtil.CHARSET_1252); - int optA = LittleEndian.getUShort(data, offset+6); - int optB = LittleEndian.getUShort(data, offset+8); - int optC = LittleEndian.getUShort(data, offset+10); - String bitType = new String(data, offset+12, 4, LocaleUtil.CHARSET_1252); - int from = (int)LittleEndian.getUInt(data, offset+16); - int len = (int)LittleEndian.getUInt(data, offset+20); - - byte[] bitData = new byte[len]; - System.arraycopy(data, from, bitData, 0, len); - - // Create - if(bitType.equals("TEXT")) { - bits[i] = new QCTextBit(thingType, bitType, bitData); - } else if(bitType.equals("PLC ")) { - bits[i] = QCPLCBit.createQCPLCBit(thingType, bitType, bitData); - } else { - bits[i] = new UnknownQCBit(thingType, bitType, bitData); - } - bits[i].setOptA(optA); - bits[i].setOptB(optB); - bits[i].setOptC(optC); - bits[i].setDataOffset(from); - } else { - // Doesn't have data - } - } - } - - public QCBit[] getBits() { - return bits; - } - - protected void generateData() { - // TODO - throw new IllegalStateException("Not done yet!"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCBit.java b/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCBit.java deleted file mode 100644 index c2e5334f0..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCBit.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpbf.model.qcbits; - -/** - * Parent of all Quill CONTENTS bits - */ -public abstract class QCBit { - protected String thingType; - protected String bitType; - protected byte[] data; - - protected int optA; - protected int optB; - protected int optC; - - protected int dataOffset; - - public QCBit(String thingType, String bitType, byte[] data) { - this.thingType = thingType; - this.bitType = bitType; - this.data = data.clone(); - } - - /** - * Returns the type of the thing, eg TEXT, FONT - * or TOKN - */ - public String getThingType() { return thingType; } - /** - * Returns the type of the bit data, eg TEXT - * or PLC - */ - public String getBitType() { return bitType; } - public byte[] getData() { return data; } - - public int getOptA() { - return optA; - } - public void setOptA(int optA) { - this.optA = optA; - } - - public int getOptB() { - return optB; - } - public void setOptB(int optB) { - this.optB = optB; - } - - public int getOptC() { - return optC; - } - public void setOptC(int optC) { - this.optC = optC; - } - - public int getDataOffset() { - return dataOffset; - } - public void setDataOffset(int offset) { - this.dataOffset = offset; - } - - public int getLength() { - return data.length; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java b/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java deleted file mode 100644 index 3b7975505..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java +++ /dev/null @@ -1,275 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hpbf.model.qcbits; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - - -/** - * A "PLC " (PLC) based bit of Quill Contents. The exact - * format is determined by the type of the PLCs. - */ -public abstract class QCPLCBit extends QCBit { - protected int numberOfPLCs; - protected int typeOfPLCS; - /** - * The data which goes before the main PLC entries. - * This is apparently always made up of 2 byte - * un-signed ints.. - */ - protected int[] preData; - /** The first value of each PLC, normally 4 bytes */ - protected long[] plcValA; - /** The second value of each PLC, normally 4 bytes */ - protected long[] plcValB; - - - private QCPLCBit(String thingType, String bitType, byte[] data) { - super(thingType, bitType, data); - - // First four bytes are the number - numberOfPLCs = (int)LittleEndian.getUInt(data, 0); - - // Next four bytes are the type - typeOfPLCS = (int)LittleEndian.getUInt(data, 4); - - // Init the arrays that we can - plcValA = new long[numberOfPLCs]; - plcValB = new long[numberOfPLCs]; - } - - - - public int getNumberOfPLCs() { - return numberOfPLCs; - } - public int getTypeOfPLCS() { - return typeOfPLCS; - } - - public int[] getPreData() { - return preData; - } - - public long[] getPlcValA() { - return plcValA; - } - public long[] getPlcValB() { - return plcValB; - } - - - - public static QCPLCBit createQCPLCBit(String thingType, String bitType, byte[] data) { - // Grab the type - int type = (int)LittleEndian.getUInt(data, 4); - switch(type) { - case 0: - return new Type0(thingType, bitType, data); - case 4: - return new Type4(thingType, bitType, data); - case 8: - return new Type8(thingType, bitType, data); - case 12: // 0xc - return new Type12(thingType, bitType, data); - default: - throw new IllegalArgumentException("Sorry, I don't know how to deal with PLCs of type " + type); - } - } - - - /** - * Type 0 seem to be somewhat rare. They have 8 bytes of pre-data, - * then 2x 2 byte values. - */ - public static class Type0 extends QCPLCBit { - private Type0(String thingType, String bitType, byte[] data) { - super(thingType, bitType, data); - - // Grab our 4x pre-data - preData = new int[4]; - preData[0] = LittleEndian.getUShort(data, 8+0); - preData[1] = LittleEndian.getUShort(data, 8+2); - preData[2] = LittleEndian.getUShort(data, 8+4); - preData[3] = LittleEndian.getUShort(data, 8+6); - - // And grab the 2 byte values - for(int i=0; i= 2) { - until = twoStartsAt + (numberOfPLCs-2)*threePlusIncrement; - } - - plcValA = new long[(until-at)/2]; - plcValB = new long[0]; - for(int i=0; i=0 ) { - out.write(chunk,0,count); - } - inflater.close(); - return out.toByteArray(); - } catch (IOException e){ - throw new HSLFException(e); - } - } - - @Override - public void setData(byte[] data) throws IOException { - byte[] compressed = compress(data, 0, data.length); - - NativeHeader nHeader = new NativeHeader(data, 0); - - Header header = new Header(); - header.wmfsize = data.length; - header.bounds = nHeader.deviceBounds; - Dimension nDim = nHeader.getSize(); - header.size = new Dimension(Units.toEMU(nDim.getWidth()), Units.toEMU(nDim.getHeight())); - header.zipsize = compressed.length; - - byte[] checksum = getChecksum(data); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(checksum); - if (uidInstanceCount == 2) { - out.write(checksum); - } - header.write(out); - out.write(compressed); - - setRawData(out.toByteArray()); - } - - @Override - public PictureType getType(){ - return PictureType.EMF; - } - - /** - * EMF signature is {@code 0x3D40} or {@code 0x3D50} - * - * @return EMF signature ({@code 0x3D40} or {@code 0x3D50}) - */ - public int getSignature(){ - return (uidInstanceCount == 1 ? 0x3D40 : 0x3D50); - } - - /** - * Sets the EMF signature - either {@code 0x3D40} or {@code 0x3D50} - */ - public void setSignature(int signature) { - switch (signature) { - case 0x3D40: - uidInstanceCount = 1; - break; - case 0x3D50: - uidInstanceCount = 2; - break; - default: - throw new IllegalArgumentException(signature+" is not a valid instance/signature value for EMF"); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java deleted file mode 100644 index 72cac5f90..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.blip; - - -/** - * Represents a JPEG picture data in a PPT file - */ -public final class JPEG extends Bitmap { - - public enum ColorSpace { rgb, cymk } - - private ColorSpace colorSpace = ColorSpace.rgb; - - @Override - public PictureType getType(){ - return PictureType.JPEG; - } - - public ColorSpace getColorSpace() { - return colorSpace; - } - - public void setColorSpace(ColorSpace colorSpace) { - this.colorSpace = colorSpace; - } - - /** - * JPEG signature is one of {@code 0x46A0, 0x46B0, 0x6E20, 0x6E30} - * - * @return JPEG signature ({@code 0x46A0, 0x46B0, 0x6E20, 0x6E30}) - */ - public int getSignature(){ - return (colorSpace == ColorSpace.rgb) - ? (uidInstanceCount == 1 ? 0x46A0 : 0x46B0) - : (uidInstanceCount == 1 ? 0x6E20 : 0x6E30); - } - - /** - * Sets the PICT signature - either {@code 0x5420} or {@code 0x5430} - */ - public void setSignature(int signature) { - switch (signature) { - case 0x46A0: - uidInstanceCount = 1; - colorSpace = ColorSpace.rgb; - break; - case 0x46B0: - uidInstanceCount = 2; - colorSpace = ColorSpace.rgb; - break; - case 0x6E20: - uidInstanceCount = 1; - colorSpace = ColorSpace.cymk; - break; - case 0x6E30: - uidInstanceCount = 2; - colorSpace = ColorSpace.cymk; - break; - default: - throw new IllegalArgumentException(signature+" is not a valid instance/signature value for JPEG"); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java deleted file mode 100644 index 4a6c3839a..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.blip; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.zip.DeflaterOutputStream; - -import org.apache.poi.hslf.usermodel.HSLFPictureData; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.Units; - -/** - * Represents a metafile picture which can be one of the following types: EMF, WMF, or PICT. - * A metafile is stored compressed using the ZIP deflate/inflate algorithm. - * - * @author Yegor Kozlov - */ -public abstract class Metafile extends HSLFPictureData { - - /** - * A structure which represents a 34-byte header preceding the compressed metafile data - * - * @author Yegor Kozlov - */ - public static class Header{ - - /** - * size of the original file - */ - public int wmfsize; - - /** - * Boundary of the metafile drawing commands - */ - public Rectangle bounds; - - /** - * Size of the metafile in EMUs - */ - public Dimension size; - - /** - * size of the compressed metafile data - */ - public int zipsize; - - /** - * Reserved. Always 0. - */ - public int compression = 0; - - /** - * Reserved. Always 254. - */ - public int filter = 254; - - public void read(byte[] data, int offset){ - int pos = offset; - wmfsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - int left = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int top = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int right = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int bottom = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - bounds = new Rectangle(left, top, right-left, bottom-top); - int width = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int height = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - size = new Dimension(width, height); - - zipsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - compression = LittleEndian.getUByte(data, pos); pos++; - filter = LittleEndian.getUByte(data, pos); pos++; - } - - public void write(OutputStream out) throws IOException { - byte[] header = new byte[34]; - int pos = 0; - LittleEndian.putInt(header, pos, wmfsize); pos += LittleEndian.INT_SIZE; //hmf - - LittleEndian.putInt(header, pos, bounds.x); pos += LittleEndian.INT_SIZE; //left - LittleEndian.putInt(header, pos, bounds.y); pos += LittleEndian.INT_SIZE; //top - LittleEndian.putInt(header, pos, bounds.x + bounds.width); pos += LittleEndian.INT_SIZE; //right - LittleEndian.putInt(header, pos, bounds.y + bounds.height); pos += LittleEndian.INT_SIZE; //bottom - LittleEndian.putInt(header, pos, size.width); pos += LittleEndian.INT_SIZE; //inch - LittleEndian.putInt(header, pos, size.height); pos += LittleEndian.INT_SIZE; //inch - LittleEndian.putInt(header, pos, zipsize); pos += LittleEndian.INT_SIZE; //inch - - header[pos] = 0; pos ++; - header[pos] = (byte)filter; pos ++; - - out.write(header); - } - - public int getSize(){ - return 34; - } - - public int getWmfSize() { - return wmfsize; - } - } - - protected static byte[] compress(byte[] bytes, int offset, int length) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - DeflaterOutputStream deflater = new DeflaterOutputStream( out ); - deflater.write(bytes, offset, length); - deflater.close(); - return out.toByteArray(); - } - - @Override - public Dimension getImageDimension() { - int prefixLen = 16*uidInstanceCount; - Header header = new Header(); - header.read(getRawData(), prefixLen); - return new Dimension( - (int)Math.round(Units.toPoints((long)header.size.getWidth())), - (int)Math.round(Units.toPoints((long)header.size.getHeight())) - ); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java deleted file mode 100644 index d68b4f701..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java +++ /dev/null @@ -1,236 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.blip; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.zip.InflaterInputStream; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * Represents Macintosh PICT picture data. - */ -public final class PICT extends Metafile { - private static final POILogger LOG = POILogFactory.getLogger(PICT.class); - - public static class NativeHeader { - /** - * skip the first 512 bytes - they are MAC specific crap - */ - public static final int PICT_HEADER_OFFSET = 512; - - public static final double DEFAULT_RESOLUTION = Units.POINT_DPI; - - private static final byte V2_HEADER[] = { - 0x00, 0x11, // v2 version opcode - 0x02, (byte)0xFF, // version number of new picture - 0x0C, 0x00, // header opcode - (byte)0xFF, (byte)0xFE, 0x00, 0x00 // pic size dummy - }; - - public final Rectangle bounds; - public final double hRes, vRes; - - public NativeHeader(byte data[], int offset) { - // http://mirrors.apple2.org.za/apple.cabi.net/Graphics/PICT.and_QT.INFO/PICT.file.format.TI.txt - - // low order 16 bits of picture size - can be ignored - offset += 2; - // rectangular bounding box of picture, at 72 dpi - // rect : 8 bytes (top, left, bottom, right: integer) - int y1 = readUnsignedShort(data, offset); offset += 2; - int x1 = readUnsignedShort(data, offset); offset += 2; - int y2 = readUnsignedShort(data, offset); offset += 2; - int x2 = readUnsignedShort(data, offset); offset += 2; - - // check for version 2 ... otherwise we don't read any further - boolean isV2 = true; - for (byte b : V2_HEADER) { - if (b != data[offset++]) { - isV2 = false; - break; - } - } - - if (isV2) { - // 4 bytes - fixed, horizontal resolution (dpi) of source data - hRes = readFixedPoint(data, offset); offset += 4; - // 4 bytes - fixed, vertical resolution (dpi) of source data - vRes = readFixedPoint(data, offset); offset += 4; - } else { - hRes = DEFAULT_RESOLUTION; - vRes = DEFAULT_RESOLUTION; - } - - bounds = new Rectangle(x1,y1,x2-x1,y2-y1); - } - - public Dimension getSize() { - int height = (int)Math.round(bounds.height*DEFAULT_RESOLUTION/vRes); - int width = (int)Math.round(bounds.width*DEFAULT_RESOLUTION/hRes); - return new Dimension(width, height); - } - - private static int readUnsignedShort(byte data[], int offset) { - int b0 = data[offset] & 0xFF; - int b1 = data[offset+1] & 0xFF; - return b0 << 8 | b1; - } - - private static double readFixedPoint(byte data[], int offset) { - int b0 = data[offset] & 0xFF; - int b1 = data[offset+1] & 0xFF; - int b2 = data[offset+2] & 0xFF; - int b3 = data[offset+3] & 0xFF; - int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; - return i / (double)0x10000; - } - } - - @Override - public byte[] getData(){ - byte[] rawdata = getRawData(); - try { - byte[] macheader = new byte[512]; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(macheader); - int pos = CHECKSUM_SIZE*uidInstanceCount; - byte[] pict = read(rawdata, pos); - out.write(pict); - return out.toByteArray(); - } catch (IOException e){ - throw new HSLFException(e); - } - } - - private byte[] read(byte[] data, int pos) throws IOException { - ByteArrayInputStream bis = new ByteArrayInputStream(data); - Header header = new Header(); - header.read(data, pos); - bis.skip(pos + header.getSize()); - byte[] chunk = new byte[4096]; - ByteArrayOutputStream out = new ByteArrayOutputStream(header.getWmfSize()); - InflaterInputStream inflater = new InflaterInputStream( bis ); - try { - int count; - while ((count = inflater.read(chunk)) >=0 ) { - out.write(chunk,0,count); - // PICT zip-stream can be erroneous, so we clear the array to determine - // the maximum of read bytes, after the inflater crashed - bytefill(chunk, (byte)0); - } - } catch (Exception e) { - int lastLen; - for (lastLen=chunk.length-1; lastLen>=0 && chunk[lastLen] == 0; lastLen--); - if (++lastLen > 0) { - if (header.getWmfSize() > out.size()) { - // sometimes the wmfsize is smaller than the amount of already successfully read bytes - // in this case we take the lastLen as-is, otherwise we truncate it to the given size - lastLen = Math.min(lastLen, header.getWmfSize() - out.size()); - } - out.write(chunk,0,lastLen); - } - // End of picture marker for PICT is 0x00 0xFF - LOG.log(POILogger.ERROR, "PICT zip-stream is invalid, read as much as possible. Uncompressed length of header: "+header.getWmfSize()+" / Read bytes: "+out.size(), e); - } finally { - inflater.close(); - } - return out.toByteArray(); - } - - @Override - public void setData(byte[] data) throws IOException { - // skip the first 512 bytes - they are MAC specific crap - final int nOffset = NativeHeader.PICT_HEADER_OFFSET; - NativeHeader nHeader = new NativeHeader(data, nOffset); - - Header header = new Header(); - header.wmfsize = data.length - nOffset; - byte[] compressed = compress(data, nOffset, header.wmfsize); - header.zipsize = compressed.length; - header.bounds = nHeader.bounds; - Dimension nDim = nHeader.getSize(); - header.size = new Dimension(Units.toEMU(nDim.getWidth()), Units.toEMU(nDim.getHeight())); - - byte[] checksum = getChecksum(data); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(checksum); - if (uidInstanceCount == 2) { - out.write(checksum); - } - header.write(out); - out.write(compressed); - - setRawData(out.toByteArray()); - } - - @Override - public PictureType getType(){ - return PictureType.PICT; - } - - /** - * PICT signature is {@code 0x5420} or {@code 0x5430} - * - * @return PICT signature ({@code 0x5420} or {@code 0x5430}) - */ - public int getSignature(){ - return (uidInstanceCount == 1 ? 0x5420 : 0x5430); - } - - /** - * Sets the PICT signature - either {@code 0x5420} or {@code 0x5430} - */ - public void setSignature(int signature) { - switch (signature) { - case 0x5420: - uidInstanceCount = 1; - break; - case 0x5430: - uidInstanceCount = 2; - break; - default: - throw new IllegalArgumentException(signature+" is not a valid instance/signature value for PICT"); - } - } - - - /* - * initialize a smaller piece of the array and use the System.arraycopy - * call to fill in the rest of the array in an expanding binary fashion - */ - private static void bytefill(byte[] array, byte value) { - // http://stackoverflow.com/questions/9128737/fastest-way-to-set-all-values-of-an-array - int len = array.length; - - if (len > 0){ - array[0] = value; - } - - for (int i = 1; i < len; i += i) { - System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java deleted file mode 100644 index b338d9d17..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.blip; - -import org.apache.poi.util.PngUtils; - -/** - * Represents a PNG picture data in a PPT file - */ -public final class PNG extends Bitmap { - - @Override - public byte[] getData() { - byte[] data = super.getData(); - - //PNG created on MAC may have a 16-byte prefix which prevents successful reading. - //Just cut it off!. - if (PngUtils.matchesPngHeader(data, 16)) { - byte[] png = new byte[data.length-16]; - System.arraycopy(data, 16, png, 0, png.length); - data = png; - } - - return data; - } - - @Override - public PictureType getType(){ - return PictureType.PNG; - } - - /** - * PNG signature is {@code 0x6E00} or {@code 0x6E10} - * - * @return PNG signature ({@code 0x6E00} or {@code 0x6E10}) - */ - public int getSignature(){ - return (uidInstanceCount == 1 ? 0x6E00 : 0x6E10); - } - - /** - * Sets the PNG signature - either {@code 0x6E00} or {@code 0x6E10} - */ - public void setSignature(int signature) { - switch (signature) { - case 0x6E00: - uidInstanceCount = 1; - break; - case 0x6E10: - uidInstanceCount = 2; - break; - default: - throw new IllegalArgumentException(signature+" is not a valid instance/signature value for PNG"); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java deleted file mode 100644 index 9dbc7f3bc..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java +++ /dev/null @@ -1,239 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.blip; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.zip.InflaterInputStream; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * Represents a WMF (Windows Metafile) picture data. - */ -public final class WMF extends Metafile { - - @Override - public byte[] getData(){ - try { - byte[] rawdata = getRawData(); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream is = new ByteArrayInputStream( rawdata ); - Header header = new Header(); - header.read(rawdata, CHECKSUM_SIZE*uidInstanceCount); - long len = is.skip(header.getSize() + CHECKSUM_SIZE*uidInstanceCount); - assert(len == header.getSize() + CHECKSUM_SIZE*uidInstanceCount); - - NativeHeader aldus = new NativeHeader(header.bounds); - aldus.write(out); - - InflaterInputStream inflater = new InflaterInputStream( is ); - byte[] chunk = new byte[4096]; - int count; - while ((count = inflater.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - inflater.close(); - return out.toByteArray(); - } catch (IOException e){ - throw new HSLFException(e); - } - } - - @Override - public void setData(byte[] data) throws IOException { - int pos = 0; - NativeHeader nHeader = new NativeHeader(data, pos); - pos += nHeader.getLength(); - - byte[] compressed = compress(data, pos, data.length-pos); - - Header header = new Header(); - header.wmfsize = data.length - nHeader.getLength(); - header.bounds = new Rectangle((short)nHeader.left, (short)nHeader.top, (short)nHeader.right-(short)nHeader.left, (short)nHeader.bottom-(short)nHeader.top); - Dimension nDim = nHeader.getSize(); - header.size = new Dimension(Units.toEMU(nDim.getWidth()), Units.toEMU(nDim.getHeight())); - header.zipsize = compressed.length; - - byte[] checksum = getChecksum(data); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - for (int i=0; i - *
      • int Key; Magic number (always 9AC6CDD7h) - *
      • short Handle; Metafile HANDLE number (always 0) - *
      • short Left; Left coordinate in metafile units - *
      • short Top; Top coordinate in metafile units - *
      • short Right; Right coordinate in metafile units - *
      • short Bottom; Bottom coordinate in metafile units - *
      • short Inch; Number of metafile units per inch - *
      • int Reserved; Reserved (always 0) - *
      • short Checksum; Checksum value for previous 10 shorts - * - */ - @SuppressWarnings("unused") - public static class NativeHeader { - public static final int APMHEADER_KEY = 0x9AC6CDD7; - private static POILogger logger = POILogFactory.getLogger(NativeHeader.class); - - private final int handle; - private final int left, top, right, bottom; - - /** - * The number of logical units per inch used to represent the image. - * This value can be used to scale an image. By convention, an image is - * considered to be recorded at 1440 logical units (twips) per inch. - * Thus, a value of 720 specifies that the image SHOULD be rendered at - * twice its normal size, and a value of 2880 specifies that the image - * SHOULD be rendered at half its normal size. - */ - private final int inch; - private final int reserved; - private int checksum; - - public NativeHeader(Rectangle dim) { - handle = 0; - left = dim.x; - top = dim.y; - right = dim.x + dim.width; - bottom = dim.y + dim.height; - inch = Units.POINT_DPI; //default resolution is 72 dpi - reserved = 0; - } - - public NativeHeader(byte[] data, int pos) { - int key = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; //header key - if (key != APMHEADER_KEY) { - logger.log(POILogger.WARN, "WMF file doesn't contain a placeable header - ignore parsing"); - handle = 0; - left = 0; - top = 0; - right = 200; - bottom = 200; - inch = Units.POINT_DPI; //default resolution is 72 dpi - reserved = 0; - return; - } - - handle = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - left = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; - top = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; - right = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; - bottom = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; - - inch = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; - if (checksum != getChecksum()){ - logger.log(POILogger.WARN, "WMF checksum does not match the header data"); - } - } - - /** - * Returns a checksum value for the previous 10 shorts in the header. - * The checksum is calculated by XORing each short value to an initial value of 0: - */ - public int getChecksum(){ - int cs = 0; - cs ^= (APMHEADER_KEY & 0x0000FFFF); - cs ^= ((APMHEADER_KEY & 0xFFFF0000) >> 16); - cs ^= left; - cs ^= top; - cs ^= right; - cs ^= bottom; - cs ^= inch; - return cs; - } - - public void write(OutputStream out) throws IOException { - byte[] header = new byte[22]; - int pos = 0; - LittleEndian.putInt(header, pos, APMHEADER_KEY); pos += LittleEndian.INT_SIZE; //header key - LittleEndian.putUShort(header, pos, 0); pos += LittleEndian.SHORT_SIZE; //hmf - LittleEndian.putUShort(header, pos, left); pos += LittleEndian.SHORT_SIZE; //left - LittleEndian.putUShort(header, pos, top); pos += LittleEndian.SHORT_SIZE; //top - LittleEndian.putUShort(header, pos, right); pos += LittleEndian.SHORT_SIZE; //right - LittleEndian.putUShort(header, pos, bottom); pos += LittleEndian.SHORT_SIZE; //bottom - LittleEndian.putUShort(header, pos, inch); pos += LittleEndian.SHORT_SIZE; //inch - LittleEndian.putInt(header, pos, 0); pos += LittleEndian.INT_SIZE; //reserved - - checksum = getChecksum(); - LittleEndian.putUShort(header, pos, checksum); - - out.write(header); - } - - public Dimension getSize() { - //coefficient to translate from WMF dpi to 72dpi - double coeff = ((double)Units.POINT_DPI)/inch; - return new Dimension((int)Math.round((right-left)*coeff), (int)Math.round((bottom-top)*coeff)); - } - - public int getLength(){ - return 22; - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/PPDrawingTextListing.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/PPDrawingTextListing.java deleted file mode 100644 index af05efa7d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/PPDrawingTextListing.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.dev; - -import org.apache.poi.hslf.record.EscherTextboxWrapper; -import org.apache.poi.hslf.record.PPDrawing; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.TextBytesAtom; -import org.apache.poi.hslf.record.TextCharsAtom; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; - - -/** - * Uses record level code to locate PPDrawing entries. - * Having found them, it sees if they have DDF Textbox records, and if so, - * searches those for text. Prints out any text it finds - */ -public final class PPDrawingTextListing { - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Need to give a filename"); - System.exit(1); - } - - HSLFSlideShowImpl ss = new HSLFSlideShowImpl(args[0]); - - // Find PPDrawings at any second level position - Record[] records = ss.getRecords(); - for(int i=0; iWriter to write out - * @throws java.io.IOException - */ - public void dump(Writer outWriter) throws IOException { - this.out = outWriter; - - int padding = 0; - write(out, "" + CR, padding); - padding++; - if (pictstream != null){ - write(out, "" + CR, padding); - dumpPictures(pictstream, padding); - write(out, "" + CR, padding); - } - //dump the structure of the powerpoint document - write(out, "" + CR, padding); - padding++; - dump(docstream, 0, docstream.length, padding); - padding--; - write(out, "" + CR, padding); - padding--; - write(out, "", padding); - } - - /** - * Dump a part of the document stream into XML - * @param data PPT binary data - * @param offset offset from the beginning of the document - * @param length of the document - * @param padding used for formatting results - * @throws java.io.IOException - */ - public void dump(byte[] data, int offset, int length, int padding) throws IOException { - int pos = offset; - while (pos <= (offset + length - HEADER_SIZE)){ - if (pos < 0) { - break; - } - - //read record header - int info = LittleEndian.getUShort(data, pos); - pos += LittleEndian.SHORT_SIZE; - int type = LittleEndian.getUShort(data, pos); - pos += LittleEndian.SHORT_SIZE; - int size = (int)LittleEndian.getUInt(data, pos); - pos += LittleEndian.INT_SIZE; - - //get name of the record by type - String recname = RecordTypes.forTypeID(type).name(); - write(out, "<"+recname + " info=\""+info+"\" type=\""+type+"\" size=\""+size+"\" offset=\""+(pos-8)+"\"", padding); - if (hexHeader){ - out.write(" header=\""); - dump(out, data, pos-8, 8, 0, false); - out.write("\""); - } - out.write(">" + CR); - padding++; - //this check works both for Escher and PowerPoint records - boolean isContainer = (info & 0x000F) == 0x000F; - if (isContainer) { - //continue to dump child records - dump(data, pos, size, padding); - } else { - //dump first 100 bytes of the atom data - dump(out, data, pos, Math.min(size, data.length-pos), padding, true); - } - padding--; - write(out, "" + CR, padding); - - pos += size; - } - } - - /** - * Dumps the Pictures OLE stream into XML. - * - * @param data from the Pictures OLE data stream - * @param padding - * @throws java.io.IOException - */ - public void dumpPictures(byte[] data, int padding) throws IOException { - int pos = 0; - while (pos < data.length) { - byte[] header = new byte[PICT_HEADER_SIZE]; - - System.arraycopy(data, pos, header, 0, header.length); - int size = LittleEndian.getInt(header, 4) - 17; - byte[] pictdata = new byte[size]; - System.arraycopy(data, pos + PICT_HEADER_SIZE, pictdata, 0, pictdata.length); - pos += PICT_HEADER_SIZE + size; - - padding++; - write(out, "" + CR, padding); - padding++; - write(out, "
        " + CR, padding); - dump(out, header, 0, header.length, padding, true); - write(out, "
        " + CR, padding); - write(out, "" + CR, padding); - dump(out, pictdata, 0, Math.min(pictdata.length, 100), padding, true); - write(out, "" + CR, padding); - padding--; - write(out, "
        " + CR, padding); - padding--; - - } - } - - public static void main(String[] args) throws Exception { - if (args.length == 0){ - System.out.println( - "Usage: PPTXMLDump (options) pptfile\n" + - "Where options include:\n" + - " -f write output to .xml file in the current directory" - ); - return; - } - boolean outFile = false; - for (int i = 0; i < args.length; i++){ - - if (args[i].startsWith("-")) { - if ("-f".equals(args[i])){ - //write ouput to a file - outFile = true; - } - } else { - File ppt = new File(args[i]); - PPTXMLDump dump = new PPTXMLDump(ppt); - System.out.println("Dumping " + args[i]); - - if (outFile){ - FileOutputStream fos = new FileOutputStream(ppt.getName() + ".xml"); - OutputStreamWriter out = new OutputStreamWriter(fos, Charset.forName("UTF8")); - dump.dump(out); - out.close(); - } else { - StringWriter out = new StringWriter(); - dump.dump(out); - System.out.println(out.toString()); - } - } - - } - } - - - /** - * write a string to out with the specified padding - */ - private static void write(Writer out, String str, int padding) throws IOException { - for (int i = 0; i < padding; i++) out.write(" "); - out.write(str); - } - - private String getPictureType(byte[] header){ - String type; - int meta = LittleEndian.getUShort(header, 0); - - switch(meta){ - case 0x46A0: type = "jpeg"; break; - case 0x2160: type = "wmf"; break; - case 0x6E00: type = "png"; break; - default: type = "unknown"; break; - } - return type; - } - - /** - * dump binary data to out with the specified padding - */ - private static void dump(Writer out, byte[] data, int offset, int length, int padding, boolean nl) throws IOException { - int linesize = 25; - for (int i = 0; i < padding; i++) out.write(" "); - int i; - for (i = offset; i < (offset + length); i++) { - int c = data[i]; - out.write((char) hexval[(c & 0xF0) >> 4]); - out.write((char) hexval[(c & 0x0F) >> 0]); - out.write(' '); - if((i+1-offset) % linesize == 0 && i != (offset + length-1)) { - out.write(CR); - for (int j = 0; j < padding; j++) out.write(" "); - } - } - if(nl && length > 0)out.write(CR); - } - - private static final byte hexval[] = - {(byte) '0', (byte) '1', (byte) '2', (byte) '3', - (byte) '4', (byte) '5', (byte) '6', (byte) '7', - (byte) '8', (byte) '9', (byte) 'A', (byte) 'B', - (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F'}; - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java deleted file mode 100644 index 90f404b1e..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.dev; - -import org.apache.poi.hslf.record.Document; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.SlideListWithText; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; - -/** - * Uses record level code to Documents. - * Having found them, it sees if they have any SlideListWithTexts, - * and reports how many, and what sorts of things they contain - */ -public final class SLWTListing { - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Need to give a filename"); - System.exit(1); - } - - HSLFSlideShowImpl ss = new HSLFSlideShowImpl(args[0]); - - // Find the documents, and then their SLWT - Record[] records = ss.getRecords(); - for(int i=0; i 3) { - System.err.println("** Warning: Shouldn't have more than 3!"); - } - - // Check the SLWTs contain what we'd expect - for(int j=0; j 0) { - System.err.println(" ** SLWT " + j + " had " + numSAS + " SlideAtomSets! (expected 0)"); - } - } - - // Report the first 5 children, to give a flavour - int upTo = 5; - if(children.length < 5) { upTo = children.length; } - for(int k=0; k sheetOffsets = pph.getSlideLocationsLookup(); - for(int j=0; j"); - return; - } - - String filename = args[0]; - if(args.length > 1) { - filename = args[1]; - } - - NPOIFSFileSystem poifs = new NPOIFSFileSystem(new File(filename)); - SlideShowDumper foo = new SlideShowDumper(poifs, System.out); - poifs.close(); - - if(args.length > 1) { - if(args[0].equalsIgnoreCase("-escher")) { - foo.setDDFEscher(true); - } else { - foo.setBasicEscher(true); - } - } - - foo.printDump(); - } - - /** - * Constructs a Powerpoint dump from a POIFS Filesystem. Parses the - * document and dumps out the contents - * - * @param filesystem the POIFS FileSystem to read from - * @throws IOException if there is a problem while parsing the document. - */ - public SlideShowDumper(NPOIFSFileSystem filesystem, PrintStream out) throws IOException { - // Grab the document stream - InputStream is = filesystem.createDocumentInputStream("PowerPoint Document"); - docstream = IOUtils.toByteArray(is); - is.close(); - this.out = out; - } - - /** - * Control dumping of any Escher records found - should DDF be used? - */ - public void setDDFEscher(boolean grok) { - ddfEscher = grok; - basicEscher = !(grok); - } - - /** - * Control dumping of any Escher records found - should our built in - * basic groker be used? - */ - public void setBasicEscher(boolean grok) { - basicEscher = grok; - ddfEscher = !(grok); - } - - public void printDump() throws IOException { - // The format of records in a powerpoint file are: - // - // - // - // If it has a zero length, following it will be another record - // - // If it has a length, depending on its type it may have children or data - // If it has children, these will follow straight away - // > - // If it has data, this will come straigh after, and run for the length - // - // All lengths given exclude the 8 byte record header - // (Data records are known as Atoms) - - // Document should start with: - // 0F 00 E8 03 ## ## ## ## - // (type 1000 = document, info 00 0f is normal, rest is document length) - // 01 00 E9 03 28 00 00 00 - // (type 1001 = document atom, info 00 01 normal, 28 bytes long) - - // When parsing a document, look to see if you know about that type - // of the current record. If you know it's a type that has children, - // process the record's data area looking for more records - // If you know about the type and it doesn't have children, either do - // something with the data (eg TextRun) or skip over it - // Otherwise, check the first byte. If you do a BINARY_AND on it with - // 0x0f (15) and get back 0x0f, you know it has children. Otherwise - // it doesn't - - walkTree(0,0,docstream.length); -} - -public void walkTree(int depth, int startPos, int maxLen) throws IOException { - int pos = startPos; - int endPos = startPos + maxLen; - final String ind = (depth == 0) ? "%1$s" : "%1$"+depth+"s"; - while(pos <= endPos - 8) { - long type = LittleEndian.getUShort(docstream,pos+2); - long len = LittleEndian.getUInt(docstream,pos+4); - byte opt = docstream[pos]; - - String fmt = ind+"At position %2$d (%2$04x): type is %3$d (%3$04x), len is %4$d (%4$04x)"; - out.println(String.format(Locale.ROOT, fmt, "", pos, type, len)); - - // See if we know about the type of it - String recordName = RecordTypes.forTypeID((short)type).name(); - - // Jump over header, and think about going on more - pos += 8; - out.println(String.format(Locale.ROOT, ind+"That's a %2$s", "", recordName)); - - // Now check if it's a container or not - int container = opt & 0x0f; - - // BinaryTagData seems to contain records, but it - // isn't tagged as doing so. Try stepping in anyway - if(type == 5003L && opt == 0L) { - container = 0x0f; - } - - out.println(); - if (type != 0L && container == 0x0f) { - if (type == 1035l || type == 1036l) { - // Special Handling of 1035=PPDrawingGroup and 1036=PPDrawing - if(ddfEscher) { - // Seems to be: - walkEscherDDF((depth+3),pos+8,(int)len-8); - } else if(basicEscher) { - walkEscherBasic((depth+3),pos+8,(int)len-8); - } - } else { - // General container record handling code - walkTree((depth+2),pos,(int)len); - } - } - - pos += (int)len; - } - } - - /** - * Use the DDF code to walk the Escher records - */ - public void walkEscherDDF(int indent, int pos, int len) { - if(len < 8) { return; } - - final String ind = (indent == 0) ? "%1$s" : "%1$"+indent+"s"; - - byte[] contents = new byte[len]; - System.arraycopy(docstream,pos,contents,0,len); - DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory(); - EscherRecord record = erf.createRecord(contents,0); - - // For now, try filling in the fields - record.fillFields(contents,0,erf); - - long atomType = LittleEndian.getUShort(contents,2); - // This lacks the 8 byte header size - long atomLen = LittleEndian.getUShort(contents,4); - // This (should) include the 8 byte header size - int recordLen = record.getRecordSize(); - - String fmt = ind+"At position %2$d (%2$04x): type is %3$d (%3$04x), len is %4$d (%4$04x) (%5$d) - record claims %6$d"; - out.println(String.format(Locale.ROOT, fmt, "", pos, atomType, atomLen, atomLen+8, recordLen)); - - - // Check for corrupt / lying ones - if(recordLen != 8 && (recordLen != (atomLen+8))) { - out.println(String.format(Locale.ROOT, ind+"** Atom length of $2d ($3d) doesn't match record length of %4d", "", atomLen, atomLen+8, recordLen)); - } - - // Print the record's details - String recordStr = record.toString().replace("\n", String.format(Locale.ROOT, "\n"+ind, "")); - out.println(String.format(Locale.ROOT, ind+"%2$s", "", recordStr)); - - if(record instanceof EscherContainerRecord) { - walkEscherDDF((indent+3), pos + 8, (int)atomLen ); - } - - // Handle records that seem to lie - if(atomType == 61451l) { - // Normally claims a size of 8 - recordLen = (int)atomLen + 8; - } - if(atomType == 61453l) { - // Returns EscherContainerRecord, but really msofbtClientTextbox - recordLen = (int)atomLen + 8; - record.fillFields( contents, 0, erf ); - if(! (record instanceof EscherTextboxRecord)) { - out.println(String.format(Locale.ROOT, ind+"%2$s", "", "** Really a msofbtClientTextbox !")); - } - } - - // Decide on what to do, based on how the lenghts match up - if(recordLen == 8 && atomLen > 8 ) { - // Assume it has children, rather than being corrupted - walkEscherDDF((indent+3), pos + 8, (int)atomLen ); - - // Wind on our length + our header - pos += atomLen; - pos += 8; - len -= atomLen; - len -= 8; - } else { - // No children, wind on our real length - pos += atomLen; - pos += 8; - len -= atomLen; - len -= 8; - } - - // Move on to the next one, if we're not at the end yet - if(len >= 8) { - walkEscherDDF(indent, pos, len ); - } - } - - /** - * Use the basic record format groking code to walk the Escher records - */ - public void walkEscherBasic(int indent, int pos, int len) throws IOException { - if(len < 8) { return; } - - final String ind = (indent == 0) ? "%1$s" : "%1$"+indent+"s"; - - long type = LittleEndian.getUShort(docstream,pos+2); - long atomlen = LittleEndian.getUInt(docstream,pos+4); - - String fmt = ind+"At position %2$d ($2$04x): type is %3$d (%3$04x), len is %4$d (%4$04x)"; - out.println(String.format(Locale.ROOT, fmt, "", pos, type, atomlen)); - - String typeName = RecordTypes.forTypeID((short)type).name(); - out.println(String.format(Locale.ROOT, ind+"%2$s", "That's an Escher Record: ", typeName)); - - // Record specific dumps - if(type == 61453l) { - // Text Box. Print out first 8 bytes of data, then 8 4 later - HexDump.dump(docstream, 0, out, pos+8, 8); - HexDump.dump(docstream, 0, out, pos+20, 8); - out.println(); - } - - - // Blank line before next entry - out.println(); - - // Look in children if we are a container - if(type == 61443l || type == 61444l) { - walkEscherBasic((indent+3), pos+8, (int)atomlen); - } - - // Keep going if not yet at end - if(atomlen < len) { - int atomleni = (int)atomlen; - walkEscherBasic(indent, pos+atomleni+8, len-atomleni-8); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java deleted file mode 100644 index cb3fe817f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java +++ /dev/null @@ -1,290 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.dev; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.List; -import java.util.Locale; - -import org.apache.poi.ddf.DefaultEscherRecordFactory; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherTextboxRecord; -import org.apache.poi.hslf.record.EscherTextboxWrapper; -import org.apache.poi.hslf.record.HSLFEscherRecordFactory; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.StyleTextPropAtom; -import org.apache.poi.hslf.record.TextBytesAtom; -import org.apache.poi.hslf.record.TextCharsAtom; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; -import org.apache.poi.util.HexDump; - -/** - * This class provides a way to view the contents of a powerpoint file. - * It will use the recored layer to grok the contents of the file, and - * will print out what it finds. - * - * @author Nick Burch - */ -public final class SlideShowRecordDumper { - final static String tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; - - private boolean optVerbose; - private boolean optEscher; - private HSLFSlideShowImpl doc; - private final PrintStream ps; - - /** - * right now this function takes one parameter: a ppt file, and outputs a - * dump of what it contains - */ - public static void main(String args[]) throws IOException { - String filename = ""; - boolean verbose = false; - boolean escher = false; - - int ndx = 0; - for (; ndx < args.length; ndx++) { - if (!args[ndx].substring(0, 1).equals("-")) - break; - - if (args[ndx].equals("-escher")) { - escher = true; - } else if (args[ndx].equals("-verbose")) { - verbose = true; - } else { - printUsage(); - return; - } - } - - // parsed any options, expect exactly one remaining arg (filename) - if (ndx != args.length - 1) { - printUsage(); - return; - } - - filename = args[ndx]; - - SlideShowRecordDumper foo = new SlideShowRecordDumper(System.out, - filename, verbose, escher); - - foo.printDump(); - } - - public static void printUsage() { - System.err.println("Usage: SlideShowRecordDumper [-escher] [-verbose] "); - System.err.println("Valid Options:"); - System.err.println("-escher\t\t: dump contents of escher records"); - System.err.println("-verbose\t: dump binary contents of each record"); - } - - /** - * Constructs a Powerpoint dump from fileName. Parses the document - * and dumps out the contents - * - * @param fileName The name of the file to read. - * @throws IOException if there is a problem while parsing the document. - */ - public SlideShowRecordDumper(PrintStream ps, String fileName, boolean verbose, boolean escher) - throws IOException { - this.ps = ps; - optVerbose = verbose; - optEscher = escher; - doc = new HSLFSlideShowImpl(fileName); - } - - - public void printDump() throws IOException { - // Prints out the records in the tree - walkTree(0, 0, doc.getRecords(), 0); - } - - public String makeHex(int number, int padding) { - String hex = Integer.toHexString(number).toUpperCase(Locale.ROOT); - while (hex.length() < padding) { - hex = "0" + hex; - } - return hex; - } - - public String reverseHex(String s) { - StringBuilder ret = new StringBuilder(); - - // Get to a multiple of two - int pos = 0; - if ((s.length() & 1) == 1) { - ret.append(0); - pos++; - } - for (char c : s.toCharArray()) { - if (pos > 0 && (pos & 1) == 0) { - ret.append(' '); - } - ret.append(c); - pos++; - } - - return ret.toString(); - } - - public int getDiskLen(Record r) throws IOException { - int diskLen = 0; - if (r != null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - r.writeOut(baos); - diskLen = baos.size(); - } - return diskLen; - } - - public String getPrintableRecordContents(Record r) throws IOException { - if (r == null) { - return "<>"; - } - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - r.writeOut(baos); - byte[] b = baos.toByteArray(); - return HexDump.dump(b, 0, 0); - } - - public void printEscherRecord(EscherRecord er, int indent) { - if (er instanceof EscherContainerRecord) { - printEscherContainerRecord( (EscherContainerRecord)er, indent ); - } else if (er instanceof EscherTextboxRecord) { - printEscherTextBox( (EscherTextboxRecord)er, indent ); - } else { - ps.print( tabs.substring(0, indent) ); - ps.println( er.toString() ); - } - } - - private void printEscherTextBox( EscherTextboxRecord tbRecord, int indent ) { - String ind = tabs.substring(0, indent); - ps.println(ind+"EscherTextboxRecord:"); - - EscherTextboxWrapper etw = new EscherTextboxWrapper(tbRecord); - Record prevChild = null; - for (Record child : etw.getChildRecords()) { - if (child instanceof StyleTextPropAtom) { - // need preceding Text[Chars|Bytes]Atom to initialize the data structure - String text = null; - if (prevChild instanceof TextCharsAtom) { - text = ((TextCharsAtom)prevChild).getText(); - } else if (prevChild instanceof TextBytesAtom) { - text = ((TextBytesAtom)prevChild).getText(); - } else { - ps.println(ind+"Error! Couldn't find preceding TextAtom for style"); - continue; - } - - StyleTextPropAtom tsp = (StyleTextPropAtom)child; - tsp.setParentTextSize(text.length()); - } - ps.println(ind+child.toString()); - prevChild = child; - } - - } - - private void printEscherContainerRecord( EscherContainerRecord ecr, int indent ) { - String ind = tabs.substring(0, indent); - ps.println(ind + ecr.getClass().getName() + " (" + ecr.getRecordName() + "):"); - ps.println(ind + " isContainer: " + ecr.isContainerRecord()); - ps.println(ind + " options: 0x" + HexDump.toHex( ecr.getOptions() )); - ps.println(ind + " recordId: 0x" + HexDump.toHex( ecr.getRecordId() )); - - List childRecords = ecr.getChildRecords(); - ps.println(ind + " numchildren: " + childRecords.size()); - ps.println(ind + " children: "); - int count = 0; - for ( EscherRecord record : childRecords ) { - ps.println(ind + " Child " + count + ":"); - printEscherRecord(record, indent+1); - count++; - } - } - - - public void walkTree(int depth, int pos, Record[] records, int indent) throws IOException { - String ind = tabs.substring(0, indent); - - for (int i = 0; i < records.length; i++) { - Record r = records[i]; - if (r == null) { - ps.println(ind + "At position " + pos + " (" + makeHex(pos, 6) + "):"); - ps.println(ind + "Warning! Null record found."); - continue; - } - - // Figure out how big it is - int len = getDiskLen(r); - - // Grab the type as hex - String hexType = makeHex((int) r.getRecordType(), 4); - String rHexType = reverseHex(hexType); - - // Grab the hslf.record type - Class c = r.getClass(); - String cname = c.toString(); - if(cname.startsWith("class ")) { - cname = cname.substring(6); - } - if(cname.startsWith("org.apache.poi.hslf.record.")) { - cname = cname.substring(27); - } - - // Display the record - ps.println(ind + "At position " + pos + " (" + makeHex(pos,6) + "):"); - ps.println(ind + " Record is of type " + cname); - ps.println(ind + " Type is " + r.getRecordType() + " (" + hexType + " -> " + rHexType + " )"); - ps.println(ind + " Len is " + (len-8) + " (" + makeHex((len-8),8) + "), on disk len is " + len ); - - // print additional information for drawings and atoms - if (optEscher && cname.equals("PPDrawing")) { - DefaultEscherRecordFactory factory = new HSLFEscherRecordFactory(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - r.writeOut(baos); - byte[] b = baos.toByteArray(); - - EscherRecord er = factory.createRecord(b, 0); - er.fillFields(b, 0, factory); - - printEscherRecord( er, indent+1 ); - - } else if(optVerbose && r.getChildRecords() == null) { - String recData = getPrintableRecordContents(r); - ps.println(ind + recData ); - } - - ps.println(); - - // If it has children, show them - if(r.getChildRecords() != null) { - walkTree((depth+3),pos+8,r.getChildRecords(), indent+1); - } - - // Wind on the position marker - pos += len; - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/TextStyleListing.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/TextStyleListing.java deleted file mode 100644 index 14b7706fb..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/TextStyleListing.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.dev; - -import java.util.List; - -import org.apache.poi.hslf.model.textproperties.*; -import org.apache.poi.hslf.record.*; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; - -/** - * Uses record level code to locate StyleTextPropAtom entries. - * Having found them, it shows the contents - */ -public final class TextStyleListing { - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Need to give a filename"); - System.exit(1); - } - - HSLFSlideShowImpl ss = new HSLFSlideShowImpl(args[0]); - - // Find the documents, and then their SLWT - Record[] records = ss.getRecords(); - for(int i=0; i paragraphStyles = stpa.getParagraphStyles(); - System.out.println("Contains " + paragraphStyles.size() + " paragraph styles:"); - for(int i=0; i charStyles = stpa.getCharacterStyles(); - System.out.println("Contains " + charStyles.size() + " character styles:"); - for(int i=0; i textProps = tpc.getTextPropList(); - System.out.println(" Contains " + textProps.size() + " TextProps"); - for(int i=0; i " + j + " - " + subPropNames[j]); - System.out.println(" " + j + " = " + subPropMatches[j]); - } - } - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/UserEditAndPersistListing.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/UserEditAndPersistListing.java deleted file mode 100644 index 34759eaa6..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/UserEditAndPersistListing.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.dev; - -import java.io.ByteArrayOutputStream; -import java.util.Map; - -import org.apache.poi.hslf.record.CurrentUserAtom; -import org.apache.poi.hslf.record.PersistPtrHolder; -import org.apache.poi.hslf.record.PositionDependentRecord; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.UserEditAtom; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; -import org.apache.poi.util.LittleEndian; - -/** - * Uses record level code to locate UserEditAtom records, and other - * persistence related atoms. Tries to match them together, to help - * illuminate quite what all the offsets mean - */ -public final class UserEditAndPersistListing { - private static byte[] fileContents; - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Need to give a filename"); - System.exit(1); - } - - - // Create the slideshow object, for normal working with - HSLFSlideShowImpl ss = new HSLFSlideShowImpl(args[0]); - fileContents = ss.getUnderlyingBytes(); - System.out.println(""); - - // Find any persist ones first - Record[] records = ss.getRecords(); - int pos = 0; - for(int i=0; i sheetOffsets = pph.getSlideLocationsLookup(); - for(int j=0; j"); - return; - } - HSLFSlideShow ppt = new HSLFSlideShow(new HSLFSlideShowImpl(args[0])); - - //extract all pictures contained in the presentation - List pdata = ppt.getPictureData(); - for (int i = 0; i < pdata.size(); i++) { - HSLFPictureData pict = pdata.get(i); - - // picture data - byte[] data = pict.getData(); - - PictureType type = pict.getType(); - FileOutputStream out = new FileOutputStream("pict_" + i + type.extension); - out.write(data); - out.close(); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java deleted file mode 100644 index 8085482ec..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java +++ /dev/null @@ -1,376 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.extractor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.poi.POIOLE2TextExtractor; -import org.apache.poi.hslf.model.Comment; -import org.apache.poi.hslf.model.HSLFMetroShape; -import org.apache.poi.hslf.model.HeadersFooters; -import org.apache.poi.hslf.model.OLEShape; -import org.apache.poi.hslf.usermodel.HSLFMasterSheet; -import org.apache.poi.hslf.usermodel.HSLFNotes; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFSlideMaster; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; -import org.apache.poi.hslf.usermodel.HSLFTable; -import org.apache.poi.hslf.usermodel.HSLFTableCell; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.hslf.usermodel.HSLFTextShape; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This class can be used to extract text from a PowerPoint file. Can optionally - * also get the notes from one. - */ -public final class PowerPointExtractor extends POIOLE2TextExtractor { - private static final POILogger LOG = POILogFactory.getLogger(PowerPointExtractor.class); - - private final HSLFSlideShowImpl _hslfshow; - private final HSLFSlideShow _show; - private final List _slides; - - private boolean _slidesByDefault = true; - private boolean _notesByDefault = false; - private boolean _commentsByDefault = false; - private boolean _masterByDefault = false; - - /** - * Basic extractor. Returns all the text, and optionally all the notes - */ - public static void main(String args[]) throws IOException { - if (args.length < 1) { - System.err.println("Useage:"); - System.err.println("\tPowerPointExtractor [-notes] "); - System.exit(1); - } - - boolean notes = false; - boolean comments = false; - boolean master = true; - - String file; - if (args.length > 1) { - notes = true; - file = args[1]; - if (args.length > 2) { - comments = true; - } - } else { - file = args[0]; - } - - PowerPointExtractor ppe = new PowerPointExtractor(file); - System.out.println(ppe.getText(true, notes, comments, master)); - ppe.close(); - } - - /** - * Creates a PowerPointExtractor, from a file - * - * @param fileName The name of the file to extract from - */ - public PowerPointExtractor(String fileName) throws IOException { - this(new NPOIFSFileSystem(new File(fileName))); - } - - /** - * Creates a PowerPointExtractor, from an Input Stream - * - * @param iStream The input stream containing the PowerPoint document - */ - public PowerPointExtractor(InputStream iStream) throws IOException { - this(new POIFSFileSystem(iStream)); - } - - /** - * Creates a PowerPointExtractor, from an open POIFSFileSystem - * - * @param fs the POIFSFileSystem containing the PowerPoint document - */ - public PowerPointExtractor(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - - /** - * Creates a PowerPointExtractor, from an open NPOIFSFileSystem - * - * @param fs the NPOIFSFileSystem containing the PowerPoint document - */ - public PowerPointExtractor(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - setFilesystem(fs); - } - - /** - * Creates a PowerPointExtractor, from a specific place - * inside an open NPOIFSFileSystem - * - * @param dir the POIFS Directory containing the PowerPoint document - */ - public PowerPointExtractor(DirectoryNode dir) throws IOException { - this(new HSLFSlideShowImpl(dir)); - } - - /** - * Creates a PowerPointExtractor, from a HSLFSlideShow - * - * @param ss the HSLFSlideShow to extract text from - */ - public PowerPointExtractor(HSLFSlideShowImpl ss) { - super(ss); - _hslfshow = ss; - _show = new HSLFSlideShow(_hslfshow); - _slides = _show.getSlides(); - } - - /** - * Should a call to getText() return slide text? Default is yes - */ - public void setSlidesByDefault(boolean slidesByDefault) { - this._slidesByDefault = slidesByDefault; - } - - /** - * Should a call to getText() return notes text? Default is no - */ - public void setNotesByDefault(boolean notesByDefault) { - this._notesByDefault = notesByDefault; - } - - /** - * Should a call to getText() return comments text? Default is no - */ - public void setCommentsByDefault(boolean commentsByDefault) { - this._commentsByDefault = commentsByDefault; - } - - /** - * Should a call to getText() return text from master? Default is no - */ - public void setMasterByDefault(boolean masterByDefault) { - this._masterByDefault = masterByDefault; - } - - /** - * Fetches all the slide text from the slideshow, but not the notes, unless - * you've called setSlidesByDefault() and setNotesByDefault() to change this - */ - public String getText() { - return getText(_slidesByDefault, _notesByDefault, _commentsByDefault, _masterByDefault); - } - - /** - * Fetches all the notes text from the slideshow, but not the slide text - */ - public String getNotes() { - return getText(false, true); - } - - public List getOLEShapes() { - List list = new ArrayList(); - - for (HSLFSlide slide : _slides) { - for (HSLFShape shape : slide.getShapes()) { - if (shape instanceof OLEShape) { - list.add((OLEShape) shape); - } - } - } - - return list; - } - - /** - * Fetches text from the slideshow, be it slide text or note text. Because - * the final block of text in a TextRun normally have their last \n - * stripped, we add it back - * - * @param getSlideText fetch slide text - * @param getNoteText fetch note text - */ - public String getText(boolean getSlideText, boolean getNoteText) { - return getText(getSlideText, getNoteText, _commentsByDefault, _masterByDefault); - } - - public String getText(boolean getSlideText, boolean getNoteText, boolean getCommentText, boolean getMasterText) { - StringBuffer ret = new StringBuffer(); - - if (getSlideText) { - if (getMasterText) { - for (HSLFSlideMaster master : _show.getSlideMasters()) { - for(HSLFShape sh : master.getShapes()){ - if(sh instanceof HSLFTextShape){ - HSLFTextShape hsh = (HSLFTextShape)sh; - final String text = hsh.getText(); - if (text == null || "".equals(text) || "*".equals(text)) { - continue; - } - - if (HSLFMasterSheet.isPlaceholder(sh)) { - // check for metro shape of complex placeholder - boolean isMetro = new HSLFMetroShape(sh).hasMetroBlob(); - - if (!isMetro) { - // don't bother about boiler plate text on master sheets - LOG.log(POILogger.INFO, "Ignoring boiler plate (placeholder) text on slide master:", text); - continue; - } - } - - ret.append(text); - if (!text.endsWith("\n")) { - ret.append("\n"); - } - } - } - } - } - - for (HSLFSlide slide : _slides) { - String headerText = ""; - String footerText = ""; - HeadersFooters hf = slide.getHeadersFooters(); - if (hf != null) { - if (hf.isHeaderVisible()) { - headerText = safeLine(hf.getHeaderText()); - } - if (hf.isFooterVisible()) { - footerText = safeLine(hf.getFooterText()); - } - } - - // Slide header, if set - ret.append(headerText); - - // Slide text - textRunsToText(ret, slide.getTextParagraphs()); - - // Table text - for (HSLFShape shape : slide.getShapes()){ - if (shape instanceof HSLFTable){ - extractTableText(ret, (HSLFTable)shape); - } - } - // Slide footer, if set - ret.append(footerText); - - // Comments, if requested and present - if (getCommentText) { - for (Comment comment : slide.getComments()) { - ret.append(comment.getAuthor() + " - " + comment.getText() + "\n"); - } - } - } - if (getNoteText) { - ret.append('\n'); - } - } - - if (getNoteText) { - // Not currently using _notes, as that can have the notes of - // master sheets in. Grab Slide list, then work from there, - // but ensure no duplicates - Set seenNotes = new HashSet(); - String headerText = ""; - String footerText = ""; - HeadersFooters hf = _show.getNotesHeadersFooters(); - if (hf != null) { - if (hf.isHeaderVisible()) { - headerText = safeLine(hf.getHeaderText()); - } - if (hf.isFooterVisible()) { - footerText = safeLine(hf.getFooterText()); - } - } - - - for (HSLFSlide slide : _slides) { - HSLFNotes notes = slide.getNotes(); - if (notes == null) { - continue; - } - Integer id = Integer.valueOf(notes._getSheetNumber()); - if (seenNotes.contains(id)) { - continue; - } - seenNotes.add(id); - - // Repeat the Notes header, if set - ret.append(headerText); - - // Notes text - textRunsToText(ret, notes.getTextParagraphs()); - - // Repeat the notes footer, if set - ret.append(footerText); - } - } - - return ret.toString(); - } - - private static String safeLine(String text) { - return (text == null) ? "" : (text+'\n'); - } - - private void extractTableText(StringBuffer ret, HSLFTable table) { - final int nrows = table.getNumberOfRows(); - final int ncols = table.getNumberOfColumns(); - for (int row = 0; row < nrows; row++){ - for (int col = 0; col < ncols; col++){ - HSLFTableCell cell = table.getCell(row, col); - //defensive null checks; don't know if they're necessary - if (cell != null){ - String txt = cell.getText(); - txt = (txt == null) ? "" : txt; - ret.append(txt); - if (col < ncols-1){ - ret.append('\t'); - } - } - } - ret.append('\n'); - } - } - private void textRunsToText(StringBuffer ret, List> paragraphs) { - if (paragraphs==null) { - return; - } - - for (List lp : paragraphs) { - ret.append(HSLFTextParagraph.getText(lp)); - if (ret.length() > 0 && ret.charAt(ret.length()-1) != '\n') { - ret.append('\n'); - } - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java deleted file mode 100644 index 1ecc49a94..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java +++ /dev/null @@ -1,210 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.extractor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.record.CString; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.TextBytesAtom; -import org.apache.poi.hslf.record.TextCharsAtom; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; - -/** - * This class will get all the text from a Powerpoint Document, including - * all the bits you didn't want, and in a somewhat random order, but will - * do it very fast. - * The class ignores most of the hslf classes, and doesn't use - * HSLFSlideShow. Instead, it just does a very basic scan through the - * file, grabbing all the text records as it goes. It then returns the - * text, either as a single string, or as a vector of all the individual - * strings. - * Because of how it works, it will return a lot of "crud" text that you - * probably didn't want! It will return text from master slides. It will - * return duplicate text, and some mangled text (powerpoint files often - * have duplicate copies of slide text in them). You don't get any idea - * what the text was associated with. - * Almost everyone will want to use @see PowerPointExtractor instead. There - * are only a very small number of cases (eg some performance sensitive - * lucene indexers) that would ever want to use this! - */ -public final class QuickButCruddyTextExtractor { - private NPOIFSFileSystem fs; - private InputStream is; - private byte[] pptContents; - - /** - * Really basic text extractor, that will also return lots of crud text. - * Takes a single argument, the file to extract from - */ - public static void main(String args[]) throws IOException - { - if(args.length < 1) { - System.err.println("Useage:"); - System.err.println("\tQuickButCruddyTextExtractor "); - System.exit(1); - } - - String file = args[0]; - - QuickButCruddyTextExtractor ppe = new QuickButCruddyTextExtractor(file); - System.out.println(ppe.getTextAsString()); - ppe.close(); - } - - /** - * Creates an extractor from a given file name - * @param fileName - */ - @SuppressWarnings("resource") - public QuickButCruddyTextExtractor(String fileName) throws IOException { - this(new NPOIFSFileSystem(new File(fileName))); - } - - /** - * Creates an extractor from a given input stream - * @param iStream - */ - @SuppressWarnings("resource") - public QuickButCruddyTextExtractor(InputStream iStream) throws IOException { - this(new NPOIFSFileSystem(iStream)); - is = iStream; - } - - /** - * Creates an extractor from a POIFS Filesystem - * @param poifs - */ - public QuickButCruddyTextExtractor(NPOIFSFileSystem poifs) throws IOException { - fs = poifs; - - // Find the PowerPoint bit, and get out the bytes - InputStream pptIs = fs.createDocumentInputStream("PowerPoint Document"); - pptContents = IOUtils.toByteArray(pptIs); - pptIs.close(); - } - - - /** - * Shuts down the underlying streams - */ - public void close() throws IOException { - if(is != null) { is.close(); } - fs = null; - } - - /** - * Fetches the ALL the text of the powerpoint file, as a single string - */ - public String getTextAsString() { - StringBuffer ret = new StringBuffer(); - List textV = getTextAsVector(); - for(String text : textV) { - ret.append(text); - if(! text.endsWith("\n")) { - ret.append('\n'); - } - } - return ret.toString(); - } - - /** - * Fetches the ALL the text of the powerpoint file, in a List of - * strings, one per text record - */ - public List getTextAsVector() { - List textV = new ArrayList(); - - // Set to the start of the file - int walkPos = 0; - - // Start walking the file, looking for the records - while(walkPos != -1) { - int newPos = findTextRecords(walkPos,textV); - walkPos = newPos; - } - - // Return what we find - return textV; - } - - /** - * For the given position, look if the record is a text record, and wind - * on after. - * If it is a text record, grabs out the text. Whatever happens, returns - * the position of the next record, or -1 if no more. - */ - public int findTextRecords(int startPos, List textV) { - // Grab the length, and the first option byte - // Note that the length doesn't include the 8 byte atom header - int len = (int)LittleEndian.getUInt(pptContents,startPos+4); - byte opt = pptContents[startPos]; - - // If it's a container, step into it and return - // (If it's a container, option byte 1 BINARY_AND 0x0f will be 0x0f) - int container = opt & 0x0f; - if(container == 0x0f) { - return (startPos+8); - } - - // Otherwise, check the type to see if it's text - int type = LittleEndian.getUShort(pptContents,startPos+2); - - // TextBytesAtom - if(type == RecordTypes.TextBytesAtom.typeID) { - TextBytesAtom tba = (TextBytesAtom)Record.createRecordForType(type, pptContents, startPos, len+8); - String text = HSLFTextParagraph.toExternalString(tba.getText(), -1); - textV.add(text); - } - // TextCharsAtom - if(type == RecordTypes.TextCharsAtom.typeID) { - TextCharsAtom tca = (TextCharsAtom)Record.createRecordForType(type, pptContents, startPos, len+8); - String text = HSLFTextParagraph.toExternalString(tca.getText(), -1); - textV.add(text); - } - - // CString (doesn't go via a TextRun) - if(type == RecordTypes.CString.typeID) { - CString cs = (CString)Record.createRecordForType(type, pptContents, startPos, len+8); - String text = cs.getText(); - - // Ignore the ones we know to be rubbish - if(text.equals("___PPT10")) { - } else if(text.equals("Default Design")) { - } else { - textV.add(text); - } - } - - - // Wind on by the atom length, and check we're not at the end - int newPos = (startPos + 8 + len); - if(newPos > (pptContents.length - 8)) { - newPos = -1; - } - return newPos; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java deleted file mode 100644 index 3ba8f6f2d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherComplexProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.record.Document; -import org.apache.poi.hslf.record.ExControl; -import org.apache.poi.hslf.record.ExObjList; -import org.apache.poi.hslf.record.ExObjRefAtom; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.usermodel.HSLFPictureData; -import org.apache.poi.hslf.usermodel.HSLFPictureShape; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSheet; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.StringUtil; - -/** - * Represents an ActiveX control in a PowerPoint document. - * - * TODO: finish - * @author Yegor Kozlov - */ -public final class ActiveXShape extends HSLFPictureShape { - public static final int DEFAULT_ACTIVEX_THUMBNAIL = -1; - - /** - * Create a new Picture - * - * @param pictureData the picture data - */ - public ActiveXShape(int movieIdx, HSLFPictureData pictureData){ - super(pictureData, null); - setActiveXIndex(movieIdx); - } - - /** - * Create a Picture object - * - * @param escherRecord the EscherSpContainer record which holds information about - * this picture in the Slide - * @param parent the parent shape of this picture - */ - protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * Create a new Placeholder and initialize internal structures - * - * @return the created EscherContainerRecord which holds shape data - */ - protected EscherContainerRecord createSpContainer(int idx, boolean isChild) { - _escherContainer = super.createSpContainer(idx, isChild); - - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE | EscherSpRecord.FLAG_OLESHAPE); - - setShapeType(ShapeType.HOST_CONTROL); - setEscherProperty(EscherProperties.BLIP__PICTUREID, idx); - setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001); - setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008); - setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); - setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, -1); - - HSLFEscherClientDataRecord cldata = getClientData(true); - cldata.addChild(new ExObjRefAtom()); - - return _escherContainer; - } - - /** - * Assign a control to this shape - * - * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#addMovie(String, int) - * @param idx the index of the movie - */ - public void setActiveXIndex(int idx) { - ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID); - if (oe == null) { - throw new HSLFException("OEShapeAtom for ActiveX doesn't exist"); - } - oe.setExObjIdRef(idx); - } - - public int getControlIndex(){ - int idx = -1; - ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID); - if(oe != null) idx = oe.getExObjIdRef(); - return idx; - } - - /** - * Set a property of this ActiveX control - * @param key - * @param value - */ - public void setProperty(String key, String value){ - - } - - /** - * Document-level container that specifies information about an ActiveX control - * - * @return container that specifies information about an ActiveX control - */ - public ExControl getExControl(){ - int idx = getControlIndex(); - ExControl ctrl = null; - Document doc = getSheet().getSlideShow().getDocumentRecord(); - ExObjList lst = (ExObjList)doc.findFirstOfType(RecordTypes.ExObjList.typeID); - if(lst != null){ - Record[] ch = lst.getChildRecords(); - for (int i = 0; i < ch.length; i++) { - if(ch[i] instanceof ExControl){ - ExControl c = (ExControl)ch[i]; - if(c.getExOleObjAtom().getObjID() == idx){ - ctrl = c; - break; - } - } - } - } - return ctrl; - } - - protected void afterInsert(HSLFSheet sheet){ - ExControl ctrl = getExControl(); - ctrl.getExControlAtom().setSlideId(sheet._getSheetNumber()); - - String name = ctrl.getProgId() + "-" + getControlIndex() + '\u0000'; - byte[] data = StringUtil.getToUnicodeLE(name); - EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.GROUPSHAPE__SHAPENAME, false, data); - AbstractEscherOptRecord opt = getEscherOptRecord(); - opt.addEscherProperty(prop); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Comment.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Comment.java deleted file mode 100644 index 27afa47c8..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Comment.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.hslf.record.Comment2000; - -/** - * - * @author Nick Burch - */ -public final class Comment { - private Comment2000 _comment2000; - - public Comment(Comment2000 comment2000) { - _comment2000 = comment2000; - } - - protected Comment2000 getComment2000() { - return _comment2000; - } - - /** - * Get the Author of this comment - */ - public String getAuthor() { - return _comment2000.getAuthor(); - } - /** - * Set the Author of this comment - */ - public void setAuthor(String author) { - _comment2000.setAuthor(author); - } - - /** - * Get the Author's Initials of this comment - */ - public String getAuthorInitials() { - return _comment2000.getAuthorInitials(); - } - /** - * Set the Author's Initials of this comment - */ - public void setAuthorInitials(String initials) { - _comment2000.setAuthorInitials(initials); - } - - /** - * Get the text of this comment - */ - public String getText() { - return _comment2000.getText(); - } - /** - * Set the text of this comment - */ - public void setText(String text) { - _comment2000.setText(text); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.java deleted file mode 100644 index 894818eb4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import java.lang.reflect.Method; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherComplexProperty; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherTertiaryOptRecord; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Experimental class for metro blobs, i.e. an alternative escher property - * containing an ooxml representation of the shape - */ -@Internal -public class HSLFMetroShape> { - private static final POILogger LOGGER = POILogFactory.getLogger(HSLFMetroShape.class); - - private final HSLFShape shape; - - public HSLFMetroShape(HSLFShape shape) { - this.shape = shape; - } - - /** - * @return the bytes of the metro blob, which are bytes of an OPCPackage, i.e. a zip stream - */ - public byte[] getMetroBytes() { - EscherComplexProperty ep = getMetroProp(); - return (ep == null) ? null : ep.getComplexData(); - } - - /** - * @return if there's a metro blob to extract - */ - public boolean hasMetroBlob() { - return getMetroProp() != null; - } - - private EscherComplexProperty getMetroProp() { - AbstractEscherOptRecord opt = shape.getEscherChild(EscherTertiaryOptRecord.RECORD_ID); - return (opt == null) ? null : (EscherComplexProperty)opt.lookup(EscherProperties.GROUPSHAPE__METROBLOB); - } - - /** - * @return the metro blob shape or null if either there's no metro blob or the ooxml classes - * aren't in the classpath - */ - @SuppressWarnings("unchecked") - public T getShape() { - byte metroBytes[] = getMetroBytes(); - if (metroBytes == null) { - return null; - } - - // org.apache.poi.xslf.usermodel.XSLFMetroShape - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - try { - Class ms = cl.loadClass("org.apache.poi.xslf.usermodel.XSLFMetroShape"); - Method m = ms.getMethod("parseShape", byte[].class); - return (T)m.invoke(null, new Object[]{metroBytes}); - } catch (Exception e) { - LOGGER.log(POILogger.ERROR, "can't process metro blob, check if all dependencies for POI OOXML are in the classpath.", e); - return null; - } - } -} - diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java deleted file mode 100644 index 9bfa5f325..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java +++ /dev/null @@ -1,279 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.hslf.record.CString; -import org.apache.poi.hslf.record.Document; -import org.apache.poi.hslf.record.HeadersFootersAtom; -import org.apache.poi.hslf.record.HeadersFootersContainer; -import org.apache.poi.hslf.record.OEPlaceholderAtom; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.SheetContainer; -import org.apache.poi.hslf.usermodel.HSLFSheet; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextShape; - -/** - * Header / Footer settings. - * - * You can get these on slides, or across all notes - */ -public final class HeadersFooters { - - private static final String _ppt2007tag = "___PPT12"; - - private final HeadersFootersContainer _container; - private final HSLFSheet _sheet; - private final boolean _ppt2007; - - - public HeadersFooters(HSLFSlideShow ppt, short headerFooterType) { - this(ppt.getSlideMasters().get(0), headerFooterType); - } - - public HeadersFooters(HSLFSheet sheet, short headerFooterType) { - _sheet = sheet; - - @SuppressWarnings("resource") - HSLFSlideShow ppt = _sheet.getSlideShow(); - Document doc = ppt.getDocumentRecord(); - - // detect if this ppt was saved in Office2007 - String tag = ppt.getSlideMasters().get(0).getProgrammableTag(); - _ppt2007 = _ppt2007tag.equals(tag); - - SheetContainer sc = _sheet.getSheetContainer(); - HeadersFootersContainer hdd = (HeadersFootersContainer)sc.findFirstOfType(RecordTypes.HeadersFooters.typeID); - // boolean ppt2007 = sc.findFirstOfType(RecordTypes.RoundTripContentMasterId.typeID) != null; - - if (hdd == null) { - for (Record ch : doc.getChildRecords()) { - if (ch instanceof HeadersFootersContainer - && ((HeadersFootersContainer) ch).getOptions() == headerFooterType) { - hdd = (HeadersFootersContainer) ch; - break; - } - } - } - - if (hdd == null) { - hdd = new HeadersFootersContainer(headerFooterType); - Record lst = doc.findFirstOfType(RecordTypes.List.typeID); - doc.addChildAfter(hdd, lst); - } - _container = hdd; - } - - /** - * Headers's text - * - * @return Headers's text - */ - public String getHeaderText(){ - CString cs = _container == null ? null : _container.getHeaderAtom(); - return getPlaceholderText(OEPlaceholderAtom.MasterHeader, cs); - } - - /** - * Sets headers's text - * - * @param text headers's text - */ - public void setHeaderText(String text){ - setHeaderVisible(true); - CString cs = _container.getHeaderAtom(); - if (cs == null) { - cs = _container.addHeaderAtom(); - } - - cs.setText(text); - } - - /** - * Footer's text - * - * @return Footer's text - */ - public String getFooterText(){ - CString cs = _container == null ? null : _container.getFooterAtom(); - return getPlaceholderText(OEPlaceholderAtom.MasterFooter, cs); - } - - /** - * Sets footers's text - * - * @param text footers's text - */ - public void setFootersText(String text){ - setFooterVisible(true); - CString cs = _container.getFooterAtom(); - if (cs == null) { - cs = _container.addFooterAtom(); - } - - cs.setText(text); - } - - /** - * This is the date that the user wants in the footers, instead of today's date. - * - * @return custom user date - */ - public String getDateTimeText(){ - CString cs = _container == null ? null : _container.getUserDateAtom(); - return getPlaceholderText(OEPlaceholderAtom.MasterDate, cs); - } - - /** - * Sets custom user date to be displayed instead of today's date. - * - * @param text custom user date - */ - public void setDateTimeText(String text){ - setUserDateVisible(true); - setDateTimeVisible(true); - CString cs = _container.getUserDateAtom(); - if (cs == null) { - cs = _container.addUserDateAtom(); - } - - cs.setText(text); - } - - /** - * whether the footer text is displayed. - */ - public boolean isFooterVisible(){ - return isVisible(HeadersFootersAtom.fHasFooter, OEPlaceholderAtom.MasterFooter); - } - - /** - * whether the footer text is displayed. - */ - public void setFooterVisible(boolean flag){ - setFlag(HeadersFootersAtom.fHasFooter, flag); - } - - /** - * whether the header text is displayed. - */ - public boolean isHeaderVisible(){ - return isVisible(HeadersFootersAtom.fHasHeader, OEPlaceholderAtom.MasterHeader); - } - - /** - * whether the header text is displayed. - */ - public void setHeaderVisible(boolean flag){ - setFlag(HeadersFootersAtom.fHasHeader, flag); - } - - /** - * whether the date is displayed in the footer. - */ - public boolean isDateTimeVisible(){ - return isVisible(HeadersFootersAtom.fHasDate, OEPlaceholderAtom.MasterDate); - } - - /** - * whether the date is displayed in the footer. - */ - public void setDateTimeVisible(boolean flag){ - setFlag(HeadersFootersAtom.fHasDate, flag); - } - - /** - * whether the custom user date is used instead of today's date. - */ - public boolean isUserDateVisible(){ - return isVisible(HeadersFootersAtom.fHasUserDate, OEPlaceholderAtom.MasterDate); - } - - /** - * whether the date is displayed in the footer. - */ - public void setUserDateVisible(boolean flag){ - setFlag(HeadersFootersAtom.fHasUserDate, flag); - } - - /** - * whether the slide number is displayed in the footer. - */ - public boolean isSlideNumberVisible(){ - return isVisible(HeadersFootersAtom.fHasSlideNumber, OEPlaceholderAtom.MasterSlideNumber); - } - - /** - * whether the slide number is displayed in the footer. - */ - public void setSlideNumberVisible(boolean flag){ - setFlag(HeadersFootersAtom.fHasSlideNumber, flag); - } - - /** - * An integer that specifies the format ID to be used to style the datetime. - * - * @return an integer that specifies the format ID to be used to style the datetime. - */ - public int getDateTimeFormat(){ - return _container.getHeadersFootersAtom().getFormatId(); - } - - /** - * An integer that specifies the format ID to be used to style the datetime. - * - * @param formatId an integer that specifies the format ID to be used to style the datetime. - */ - public void setDateTimeFormat(int formatId){ - _container.getHeadersFootersAtom().setFormatId(formatId); - } - - private boolean isVisible(int flag, int placeholderId){ - boolean visible; - if(_ppt2007){ - HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId); - visible = placeholder != null && placeholder.getText() != null; - } else { - visible = _container.getHeadersFootersAtom().getFlag(flag); - } - return visible; - } - - private String getPlaceholderText(int placeholderId, CString cs){ - String text = null; - if (_ppt2007) { - HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId); - if (placeholder != null) { - text = placeholder.getText(); - } - - // default text in master placeholders is not visible - if("*".equals(text)) { - text = null; - } - } else { - text = cs == null ? null : cs.getText(); - } - return text; - } - - private void setFlag(int type, boolean flag) { - _container.getHeadersFootersAtom().setFlag(type, flag); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java deleted file mode 100644 index 5650b2b2d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java +++ /dev/null @@ -1,177 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.hslf.record.AnimationInfo; -import org.apache.poi.hslf.record.AnimationInfoAtom; -import org.apache.poi.hslf.record.ExMCIMovie; -import org.apache.poi.hslf.record.ExObjList; -import org.apache.poi.hslf.record.ExObjRefAtom; -import org.apache.poi.hslf.record.ExVideoContainer; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.InteractiveInfo; -import org.apache.poi.hslf.record.InteractiveInfoAtom; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.usermodel.HSLFPictureData; -import org.apache.poi.hslf.usermodel.HSLFPictureShape; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.sl.usermodel.ShapeContainer; - -/** - * Represents a movie in a PowerPoint document. - * - * @author Yegor Kozlov - */ -public final class MovieShape extends HSLFPictureShape { - public static final int DEFAULT_MOVIE_THUMBNAIL = -1; - - public static final int MOVIE_MPEG = 1; - public static final int MOVIE_AVI = 2; - - /** - * Create a new Picture - * - * @param pictureData the picture data - */ - public MovieShape(int movieIdx, HSLFPictureData pictureData){ - super(pictureData, null); - setMovieIndex(movieIdx); - setAutoPlay(true); - } - - /** - * Create a new Picture - * - * @param pictureData the picture data - * @param parent the parent shape - */ - public MovieShape(int movieIdx, HSLFPictureData pictureData, ShapeContainer parent) { - super(pictureData, parent); - setMovieIndex(movieIdx); - } - - /** - * Create a Picture object - * - * @param escherRecord the EscherSpContainer record which holds information about - * this picture in the Slide - * @param parent the parent shape of this picture - */ - public MovieShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * Create a new Placeholder and initialize internal structures - * - * @return the created EscherContainerRecord which holds shape data - */ - protected EscherContainerRecord createSpContainer(int idx, boolean isChild) { - _escherContainer = super.createSpContainer(idx, isChild); - - setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x1000100); - setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x10001); - - ExObjRefAtom oe = new ExObjRefAtom(); - InteractiveInfo info = new InteractiveInfo(); - InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom(); - infoAtom.setAction(InteractiveInfoAtom.ACTION_MEDIA); - infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_NULL); - - AnimationInfo an = new AnimationInfo(); - AnimationInfoAtom anAtom = an.getAnimationInfoAtom(); - anAtom.setFlag(AnimationInfoAtom.Automatic, true); - - HSLFEscherClientDataRecord cldata = getClientData(true); - cldata.addChild(oe); - cldata.addChild(an); - cldata.addChild(info); - - return _escherContainer; - } - - /** - * Assign a movie to this shape - * - * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#addMovie(String, int) - * @param idx the index of the movie - */ - public void setMovieIndex(int idx){ - ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID); - oe.setExObjIdRef(idx); - - AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID); - if(an != null) { - AnimationInfoAtom ai = an.getAnimationInfoAtom(); - ai.setDimColor(0x07000000); - ai.setFlag(AnimationInfoAtom.Automatic, true); - ai.setFlag(AnimationInfoAtom.Play, true); - ai.setFlag(AnimationInfoAtom.Synchronous, true); - ai.setOrderID(idx + 1); - } - } - - public void setAutoPlay(boolean flag){ - AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID); - if(an != null){ - an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag); - } - } - - public boolean isAutoPlay(){ - AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID); - if(an != null){ - return an.getAnimationInfoAtom().getFlag(AnimationInfoAtom.Automatic); - } - return false; - } - - /** - * @return UNC or local path to a video file - */ - @SuppressWarnings("resource") - public String getPath(){ - ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID); - int idx = oe.getExObjIdRef(); - - HSLFSlideShow ppt = getSheet().getSlideShow(); - ExObjList lst = (ExObjList)ppt.getDocumentRecord().findFirstOfType(RecordTypes.ExObjList.typeID); - if(lst == null) { - return null; - } - - Record[] r = lst.getChildRecords(); - for (int i = 0; i < r.length; i++) { - if(r[i] instanceof ExMCIMovie){ - ExMCIMovie mci = (ExMCIMovie)r[i]; - ExVideoContainer exVideo = mci.getExVideo(); - int objectId = exVideo.getExMediaAtom().getObjectId(); - if(objectId == idx){ - return exVideo.getPathAtom().getText(); - } - } - - } - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java deleted file mode 100644 index 32780264f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java +++ /dev/null @@ -1,210 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.hslf.record.ExEmbed; -import org.apache.poi.hslf.record.ExObjList; -import org.apache.poi.hslf.record.ExObjRefAtom; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.usermodel.HSLFObjectData; -import org.apache.poi.hslf.usermodel.HSLFPictureData; -import org.apache.poi.hslf.usermodel.HSLFPictureShape; -import org.apache.poi.hslf.usermodel.HSLFShape; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.util.POILogger; - - -/** - * A shape representing embedded OLE obejct. - * - * @author Yegor Kozlov - */ -public final class OLEShape extends HSLFPictureShape { - protected ExEmbed _exEmbed; - - /** - * Create a new OLEShape - * - * @param data the picture data - */ - public OLEShape(HSLFPictureData data){ - super(data); - } - - /** - * Create a new OLEShape - * - * @param data the picture data - * @param parent the parent shape - */ - public OLEShape(HSLFPictureData data, ShapeContainer parent) { - super(data, parent); - } - - /** - * Create a OLEShape object - * - * @param escherRecord the EscherSpContainer record which holds information about - * this picture in the Slide - * @param parent the parent shape of this picture - */ - public OLEShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * Returns unique identifier for the OLE object. - * - * @return the unique identifier for the OLE object - */ - public int getObjectID(){ - return getEscherProperty(EscherProperties.BLIP__PICTUREID); - } - - /** - * Set the unique identifier for the OLE object and - * register it in the necessary structures - * - * @param objectId the unique identifier for the OLE object - */ - public void setObjectID(int objectId){ - setEscherProperty(EscherProperties.BLIP__PICTUREID, objectId); - - EscherContainerRecord ecr = getSpContainer(); - EscherSpRecord spRecord = ecr.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setFlags(spRecord.getFlags()|EscherSpRecord.FLAG_OLESHAPE); - - HSLFEscherClientDataRecord cldata = getClientData(true); - ExObjRefAtom uer = null; - for (Record r : cldata.getHSLFChildRecords()) { - if (r.getRecordType() == RecordTypes.ExObjRefAtom.typeID) { - uer = (ExObjRefAtom)r; - break; - } - } - if (uer == null) { - uer = new ExObjRefAtom(); - cldata.addChild(uer); - } - uer.setExObjIdRef(objectId); - } - - - /** - * Returns unique identifier for the OLE object. - * - * @return the unique identifier for the OLE object - */ - @SuppressWarnings("resource") - public HSLFObjectData getObjectData(){ - HSLFSlideShow ppt = getSheet().getSlideShow(); - HSLFObjectData[] ole = ppt.getEmbeddedObjects(); - - //persist reference - ExEmbed exEmbed = getExEmbed(); - HSLFObjectData data = null; - if(exEmbed != null) { - int ref = exEmbed.getExOleObjAtom().getObjStgDataRef(); - - for (int i = 0; i < ole.length; i++) { - if(ole[i].getExOleObjStg().getPersistId() == ref) { - data=ole[i]; - } - } - } - if (data==null) { - logger.log(POILogger.WARN, "OLE data not found"); - } - - return data; - } - - /** - * Return the record container for this embedded object. - * - *

        - * It contains: - * 1. ExEmbedAtom.(4045) - * 2. ExOleObjAtom (4035) - * 3. CString (4026), Instance MenuName (1) used for menus and the Links dialog box. - * 4. CString (4026), Instance ProgID (2) that stores the OLE Programmatic Identifier. - * A ProgID is a string that uniquely identifies a given object. - * 5. CString (4026), Instance ClipboardName (3) that appears in the paste special dialog. - * 6. MetaFile( 4033), optional - *

        - */ - @SuppressWarnings("resource") - public ExEmbed getExEmbed(){ - if(_exEmbed == null){ - HSLFSlideShow ppt = getSheet().getSlideShow(); - - ExObjList lst = ppt.getDocumentRecord().getExObjList(false); - if(lst == null){ - logger.log(POILogger.WARN, "ExObjList not found"); - return null; - } - - int id = getObjectID(); - Record[] ch = lst.getChildRecords(); - for (int i = 0; i < ch.length; i++) { - if(ch[i] instanceof ExEmbed){ - ExEmbed embd = (ExEmbed)ch[i]; - if( embd.getExOleObjAtom().getObjID() == id) _exEmbed = embd; - } - } - } - return _exEmbed; - } - - /** - * Returns the instance name of the embedded object, e.g. "Document" or "Workbook". - * - * @return the instance name of the embedded object - */ - public String getInstanceName(){ - return getExEmbed().getMenuName(); - } - - /** - * Returns the full name of the embedded object, - * e.g. "Microsoft Word Document" or "Microsoft Office Excel Worksheet". - * - * @return the full name of the embedded object - */ - public String getFullName(){ - return getExEmbed().getClipboardName(); - } - - /** - * Returns the ProgID that stores the OLE Programmatic Identifier. - * A ProgID is a string that uniquely identifies a given object, for example, - * "Word.Document.8" or "Excel.Sheet.8". - * - * @return the ProgID - */ - public String getProgID(){ - return getExEmbed().getProgId(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPFont.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPFont.java deleted file mode 100644 index e6f7a9ded..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPFont.java +++ /dev/null @@ -1,243 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.hslf.record.FontEntityAtom; - -/** - * Represents a Font used in a presenation. - *

        - * In PowerPoint Font is a shared resource and can be shared among text object in the presentation. - *

        - * Some commonly used fonts are predefined in static constants. - * - * @author Yegor Kozlov - */ -public final class PPFont { - /** - * ANSI character set - */ - public final static byte ANSI_CHARSET = 0; - - /** - * Default character set. - */ - public final static byte DEFAULT_CHARSET = 1; - - /** - * Symbol character set - */ - public final static byte SYMBOL_CHARSET = 2; - - - /** - * Constants for the pitch and family of the font. - * The two low-order bits specify the pitch of the font and can be one of the following values - */ - public final static byte DEFAULT_PITCH = 0; - public final static byte FIXED_PITCH = 1; - public final static byte VARIABLE_PITCH = 2; - - /** - * Don't care or don't know. - */ - public final static byte FF_DONTCARE = 0; - /** - * Fonts with variable stroke width (proportional) and with serifs. Times New Roman is an example. - */ - public final static byte FF_ROMAN = 16; - /** - * Fonts with variable stroke width (proportional) and without serifs. Arial is an example. - */ - public final static byte FF_SWISS = 32; - /** - * Fonts designed to look like handwriting. Script and Cursive are examples. - */ - public final static byte FF_SCRIPT = 64; - /** - * Fonts with constant stroke width (monospace), with or without serifs. - * Monospace fonts are usually modern. CourierNew is an example - */ - public final static byte FF_MODERN = 48; - /** - * Novelty fonts. Old English is an example - */ - public final static byte FF_DECORATIVE = 80; - - - protected int charset; - protected int type; - protected int flags; - protected int pitch; - protected String name; - - /** - * Creates a new instance of PPFont - */ - public PPFont(){ - - } - - /** - * Creates a new instance of PPFont and initialize it from the supplied font atom - */ - public PPFont(FontEntityAtom fontAtom){ - name = fontAtom.getFontName(); - charset = fontAtom.getCharSet(); - type = fontAtom.getFontType(); - flags = fontAtom.getFontFlags(); - pitch = fontAtom.getPitchAndFamily(); - } - - /** - * set the name for the font (i.e. Arial) - * - * @param val String representing the name of the font to use - */ - public void setFontName(String val){ - name = val; - } - - /** - * get the name for the font (i.e. Arial) - * - * @return String representing the name of the font to use - */ - public String getFontName(){ - return name; - } - - /** - * set the character set - * - * @param val - characterset - */ - public void setCharSet(int val){ - charset = val; - } - - /** - * get the character set - * - * @return charset - characterset - */ - public int getCharSet(){ - return charset; - } - - /** - * set the font flags - * Bit 1: If set, font is subsetted - * - * @param val - the font flags - */ - public void setFontFlags(int val){ - flags = val; - } - - /** - * get the character set - * Bit 1: If set, font is subsetted - * - * @return the font flags - */ - public int getFontFlags(){ - return flags; - } - - /** - * set the font type - *

        - * Bit 1: Raster Font - * Bit 2: Device Font - * Bit 3: TrueType Font - *

        - * - * @param val - the font type - */ - public void setFontType(int val){ - type = val; - } - - /** - * get the font type - *

        - * Bit 1: Raster Font - * Bit 2: Device Font - * Bit 3: TrueType Font - *

        - * - * @return the font type - */ - public int getFontType(){ - return type; - } - - /** - * set lfPitchAndFamily - * - * - * @param val - Corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure - */ - public void setPitchAndFamily(int val){ - pitch = val; - } - - /** - * get lfPitchAndFamily - * - * @return corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure - */ - public int getPitchAndFamily(){ - return pitch; - } - - public static final PPFont ARIAL; - public static final PPFont TIMES_NEW_ROMAN ; - public static final PPFont COURIER_NEW; - public static final PPFont WINGDINGS; - static { - ARIAL = new PPFont(); - ARIAL.setFontName("Arial"); - ARIAL.setCharSet(ANSI_CHARSET); - ARIAL.setFontType(4); - ARIAL.setFontFlags(0); - ARIAL.setPitchAndFamily(VARIABLE_PITCH | FF_SWISS); - - TIMES_NEW_ROMAN = new PPFont(); - TIMES_NEW_ROMAN.setFontName("Times New Roman"); - TIMES_NEW_ROMAN.setCharSet(ANSI_CHARSET); - TIMES_NEW_ROMAN.setFontType(4); - TIMES_NEW_ROMAN.setFontFlags(0); - TIMES_NEW_ROMAN.setPitchAndFamily(VARIABLE_PITCH | FF_ROMAN); - - COURIER_NEW = new PPFont(); - COURIER_NEW.setFontName("Courier New"); - COURIER_NEW.setCharSet(ANSI_CHARSET); - COURIER_NEW.setFontType(4); - COURIER_NEW.setFontFlags(0); - COURIER_NEW.setPitchAndFamily(FIXED_PITCH | FF_MODERN); - - WINGDINGS = new PPFont(); - WINGDINGS.setFontName("Wingdings"); - WINGDINGS.setCharSet(SYMBOL_CHARSET); - WINGDINGS.setFontType(4); - WINGDINGS.setFontFlags(0); - WINGDINGS.setPitchAndFamily(VARIABLE_PITCH | FF_DONTCARE); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java deleted file mode 100644 index 74047674c..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java +++ /dev/null @@ -1,1856 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.Toolkit; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Ellipse2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Path2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.text.AttributedCharacterIterator; -import java.util.Map; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.usermodel.HSLFFreeformShape; -import org.apache.poi.hslf.usermodel.HSLFGroupShape; -import org.apache.poi.hslf.usermodel.HSLFSimpleShape; -import org.apache.poi.hslf.usermodel.HSLFTextBox; -import org.apache.poi.hslf.usermodel.HSLFTextRun; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.util.NotImplemented; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.SuppressForbidden; - -/** - * Translates Graphics2D calls into PowerPoint. - * - * @author Yegor Kozlov - */ -public final class PPGraphics2D extends Graphics2D implements Cloneable { - - protected POILogger log = POILogFactory.getLogger(this.getClass()); - - //The ppt object to write into. - private HSLFGroupShape _group; - - private AffineTransform _transform; - private Stroke _stroke; - private Paint _paint; - private Font _font; - private Color _foreground; - private Color _background; - private RenderingHints _hints; - - /** - * Construct Java Graphics object which translates graphic calls in ppt drawing layer. - * - * @param group The shape group to write the graphics calls into. - */ - public PPGraphics2D(HSLFGroupShape group){ - this._group = group; - - _transform = new AffineTransform(); - _stroke = new BasicStroke(); - _paint = Color.black; - _font = new Font("Arial", Font.PLAIN, 12); - _background = Color.black; - _foreground = Color.white; - _hints = new RenderingHints(null); - } - - /** - * @return the shape group being used for drawing - */ - public HSLFGroupShape getShapeGroup(){ - return _group; - } - - /** - * Gets the current font. - * @return this graphics context's current font. - * @see java.awt.Font - * @see java.awt.Graphics#setFont(Font) - */ - public Font getFont(){ - return _font; - } - - /** - * Sets this graphics context's font to the specified font. - * All subsequent text operations using this graphics context - * use this font. - * @param font the font. - * @see java.awt.Graphics#getFont - * @see java.awt.Graphics#drawString(java.lang.String, int, int) - * @see java.awt.Graphics#drawBytes(byte[], int, int, int, int) - * @see java.awt.Graphics#drawChars(char[], int, int, int, int) - */ - public void setFont(Font font){ - this._font = font; - } - - /** - * Gets this graphics context's current color. - * @return this graphics context's current color. - * @see java.awt.Color - * @see java.awt.Graphics#setColor - */ - public Color getColor(){ - return _foreground; - } - - /** - * Sets this graphics context's current color to the specified - * color. All subsequent graphics operations using this graphics - * context use this specified color. - * @param c the new rendering color. - * @see java.awt.Color - * @see java.awt.Graphics#getColor - */ - public void setColor(Color c) { - setPaint(c); - } - - /** - * Returns the current Stroke in the - * Graphics2D context. - * @return the current Graphics2D Stroke, - * which defines the line style. - * @see #setStroke - */ - public Stroke getStroke(){ - return _stroke; - } - - /** - * Sets the Stroke for the Graphics2D context. - * @param s the Stroke object to be used to stroke a - * Shape during the rendering process - */ - public void setStroke(Stroke s){ - this._stroke = s; - } - - /** - * Returns the current Paint of the - * Graphics2D context. - * @return the current Graphics2D Paint, - * which defines a color or pattern. - * @see #setPaint - * @see java.awt.Graphics#setColor - */ - public Paint getPaint(){ - return _paint; - } - - /** - * Sets the Paint attribute for the - * Graphics2D context. Calling this method - * with a null Paint object does - * not have any effect on the current Paint attribute - * of this Graphics2D. - * @param paint the Paint object to be used to generate - * color during the rendering process, or null - * @see java.awt.Graphics#setColor - */ - public void setPaint(Paint paint){ - if(paint == null) return; - - this._paint = paint; - if (paint instanceof Color) _foreground = (Color)paint; - } - - /** - * Returns a copy of the current Transform in the - * Graphics2D context. - * @return the current AffineTransform in the - * Graphics2D context. - * @see #_transform - * @see #setTransform - */ - public AffineTransform getTransform(){ - return new AffineTransform(_transform); - } - - /** - * Sets the Transform in the Graphics2D - * context. - * @param Tx the AffineTransform object to be used in the - * rendering process - * @see #_transform - * @see AffineTransform - */ - public void setTransform(AffineTransform Tx) { - _transform = new AffineTransform(Tx); - } - - /** - * Strokes the outline of a Shape using the settings of the - * current Graphics2D context. The rendering attributes - * applied include the Clip, Transform, - * Paint, Composite and - * Stroke attributes. - * @param shape the Shape to be rendered - * @see #setStroke - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #_transform - * @see #setTransform - * @see #clip - * @see #setClip - * @see #setComposite - */ - public void draw(Shape shape){ - Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape)); - HSLFFreeformShape p = new HSLFFreeformShape(_group); - p.setPath(path); - p.getFill().setForegroundColor(null); - applyStroke(p); - if (_paint instanceof Color) { - p.setLineColor((Color)_paint); - } - _group.addShape(p); - } - - /** - * Renders the text specified by the specified String, - * using the current text attribute state in the Graphics2D context. - * The baseline of the first character is at position - * (xy) in the User Space. - * The rendering attributes applied include the Clip, - * Transform, Paint, Font and - * Composite attributes. For characters in script systems - * such as Hebrew and Arabic, the glyphs can be rendered from right to - * left, in which case the coordinate supplied is the location of the - * leftmost character on the baseline. - * @param s the String to be rendered - * @param x the x coordinate of the location where the - * String should be rendered - * @param y the y coordinate of the location where the - * String should be rendered - * @throws NullPointerException if str is - * null - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see java.awt.Graphics#setFont - * @see #setTransform - * @see #setComposite - * @see #setClip - */ - public void drawString(String s, float x, float y) { - HSLFTextBox txt = new HSLFTextBox(_group); - txt.setSheet(_group.getSheet()); - txt.setText(s); - - HSLFTextRun rt = txt.getTextParagraphs().get(0).getTextRuns().get(0); - rt.setFontSize((double)_font.getSize()); - rt.setFontFamily(_font.getFamily()); - - if (getColor() != null) rt.setFontColor(DrawPaint.createSolidPaint(getColor())); - if (_font.isBold()) rt.setBold(true); - if (_font.isItalic()) rt.setItalic(true); - - txt.setBottomInset(0); - txt.setTopInset(0); - txt.setLeftInset(0); - txt.setRightInset(0); - txt.setWordWrap(false); - txt.setHorizontalCentered(false); - txt.setVerticalAlignment(VerticalAlignment.MIDDLE); - - - TextLayout layout = new TextLayout(s, _font, getFontRenderContext()); - float ascent = layout.getAscent(); - - float width = (float) Math.floor(layout.getAdvance()); - /** - * Even if top and bottom margins are set to 0 PowerPoint - * always sets extra space between the text and its bounding box. - * - * The approximation height = ascent*2 works good enough in most cases - */ - float height = ascent * 2; - - /* - In powerpoint anchor of a shape is its top left corner. - Java graphics sets string coordinates by the baseline of the first character - so we need to shift up by the height of the textbox - */ - y -= height / 2 + ascent / 2; - - /* - In powerpoint anchor of a shape is its top left corner. - Java graphics sets string coordinates by the baseline of the first character - so we need to shift down by the height of the textbox - */ - txt.setAnchor(new Rectangle((int)x, (int)y, (int)width, (int)height)); - - _group.addShape(txt); - } - - /** - * Fills the interior of a Shape using the settings of the - * Graphics2D context. The rendering attributes applied - * include the Clip, Transform, - * Paint, and Composite. - * @param shape the Shape to be filled - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - */ - public void fill(Shape shape){ - Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape)); - HSLFFreeformShape p = new HSLFFreeformShape(_group); - p.setPath(path); - applyPaint(p); - p.setLineColor(null); //Fills must be "No Line" - _group.addShape(p); - } - - /** - * Translates the origin of the graphics context to the point - * (xy) in the current coordinate system. - * Modifies this graphics context so that its new origin corresponds - * to the point (xy) in this graphics context's - * original coordinate system. All coordinates used in subsequent - * rendering operations on this graphics context will be relative - * to this new origin. - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void translate(int x, int y){ - _transform.translate(x, y); - } - - /** - * Intersects the current Clip with the interior of the - * specified Shape and sets the Clip to the - * resulting intersection. The specified Shape is - * transformed with the current Graphics2D - * Transform before being intersected with the current - * Clip. This method is used to make the current - * Clip smaller. - * To make the Clip larger, use setClip. - * The user clip modified by this method is independent of the - * clipping associated with device bounds and visibility. If no clip has - * previously been set, or if the clip has been cleared using - * {@link java.awt.Graphics#setClip(Shape) setClip} with a - * null argument, the specified Shape becomes - * the new user clip. - * @param s the Shape to be intersected with the current - * Clip. If s is null, - * this method clears the current Clip. - */ - @NotImplemented - public void clip(Shape s){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Gets the current clipping area. - * This method returns the user clip, which is independent of the - * clipping associated with device bounds and window visibility. - * If no clip has previously been set, or if the clip has been - * cleared using setClip(null), this method returns - * null. - * @return a Shape object representing the - * current clipping area, or null if - * no clip is set. - * @see java.awt.Graphics#getClipBounds() - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(int, int, int, int) - * @see java.awt.Graphics#setClip(Shape) - * @since JDK1.1 - */ - @NotImplemented - public Shape getClip(){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return null; - } - - /** - * Concatenates the current Graphics2D - * Transform with a scaling transformation - * Subsequent rendering is resized according to the specified scaling - * factors relative to the previous scaling. - * This is equivalent to calling transform(S), where S is an - * AffineTransform represented by the following matrix: - *
        -     *          [   sx   0    0   ]
        -     *          [   0    sy   0   ]
        -     *          [   0    0    1   ]
        -     * 
        - * @param sx the amount by which X coordinates in subsequent - * rendering operations are multiplied relative to previous - * rendering operations. - * @param sy the amount by which Y coordinates in subsequent - * rendering operations are multiplied relative to previous - * rendering operations. - */ - public void scale(double sx, double sy){ - _transform.scale(sx, sy); - } - - /** - * Draws an outlined round-cornered rectangle using this graphics - * context's current color. The left and right edges of the rectangle - * are at x and x + width, - * respectively. The top and bottom edges of the rectangle are at - * y and y + height. - * @param x the x coordinate of the rectangle to be drawn. - * @param y the y coordinate of the rectangle to be drawn. - * @param width the width of the rectangle to be drawn. - * @param height the height of the rectangle to be drawn. - * @param arcWidth the horizontal diameter of the arc - * at the four corners. - * @param arcHeight the vertical diameter of the arc - * at the four corners. - * @see java.awt.Graphics#fillRoundRect - */ - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight){ - RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight); - draw(rect); - } - - /** - * Draws the text given by the specified string, using this - * graphics context's current font and color. The baseline of the - * first character is at position (xy) in this - * graphics context's coordinate system. - * @param str the string to be drawn. - * @param x the x coordinate. - * @param y the y coordinate. - * @see java.awt.Graphics#drawBytes - * @see java.awt.Graphics#drawChars - */ - public void drawString(String str, int x, int y){ - drawString(str, (float)x, (float)y); - } - - /** - * Fills an oval bounded by the specified rectangle with the - * current color. - * @param x the x coordinate of the upper left corner - * of the oval to be filled. - * @param y the y coordinate of the upper left corner - * of the oval to be filled. - * @param width the width of the oval to be filled. - * @param height the height of the oval to be filled. - * @see java.awt.Graphics#drawOval - */ - public void fillOval(int x, int y, int width, int height){ - Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); - fill(oval); - } - - /** - * Fills the specified rounded corner rectangle with the current color. - * The left and right edges of the rectangle - * are at x and x + width - 1, - * respectively. The top and bottom edges of the rectangle are at - * y and y + height - 1. - * @param x the x coordinate of the rectangle to be filled. - * @param y the y coordinate of the rectangle to be filled. - * @param width the width of the rectangle to be filled. - * @param height the height of the rectangle to be filled. - * @param arcWidth the horizontal diameter - * of the arc at the four corners. - * @param arcHeight the vertical diameter - * of the arc at the four corners. - * @see java.awt.Graphics#drawRoundRect - */ - public void fillRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight){ - - RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight); - fill(rect); - } - - /** - * Fills a circular or elliptical arc covering the specified rectangle. - *

        - * The resulting arc begins at startAngle and extends - * for arcAngle degrees. - * Angles are interpreted such that 0 degrees - * is at the 3 o'clock position. - * A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - *

        - * The center of the arc is the center of the rectangle whose origin - * is (xy) and whose size is specified by the - * width and height arguments. - *

        - * The resulting arc covers an area - * width + 1 pixels wide - * by height + 1 pixels tall. - *

        - * The angles are specified relative to the non-square extents of - * the bounding rectangle such that 45 degrees always falls on the - * line from the center of the ellipse to the upper right corner of - * the bounding rectangle. As a result, if the bounding rectangle is - * noticeably longer in one axis than the other, the angles to the - * start and end of the arc segment will be skewed farther along the - * longer axis of the bounds. - * @param x the x coordinate of the - * upper-left corner of the arc to be filled. - * @param y the y coordinate of the - * upper-left corner of the arc to be filled. - * @param width the width of the arc to be filled. - * @param height the height of the arc to be filled. - * @param startAngle the beginning angle. - * @param arcAngle the angular extent of the arc, - * relative to the start angle. - * @see java.awt.Graphics#drawArc - */ - public void fillArc(int x, int y, int width, int height, - int startAngle, int arcAngle){ - Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE); - fill(arc); - } - - /** - * Draws the outline of a circular or elliptical arc - * covering the specified rectangle. - *

        - * The resulting arc begins at startAngle and extends - * for arcAngle degrees, using the current color. - * Angles are interpreted such that 0 degrees - * is at the 3 o'clock position. - * A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - *

        - * The center of the arc is the center of the rectangle whose origin - * is (xy) and whose size is specified by the - * width and height arguments. - *

        - * The resulting arc covers an area - * width + 1 pixels wide - * by height + 1 pixels tall. - *

        - * The angles are specified relative to the non-square extents of - * the bounding rectangle such that 45 degrees always falls on the - * line from the center of the ellipse to the upper right corner of - * the bounding rectangle. As a result, if the bounding rectangle is - * noticeably longer in one axis than the other, the angles to the - * start and end of the arc segment will be skewed farther along the - * longer axis of the bounds. - * @param x the x coordinate of the - * upper-left corner of the arc to be drawn. - * @param y the y coordinate of the - * upper-left corner of the arc to be drawn. - * @param width the width of the arc to be drawn. - * @param height the height of the arc to be drawn. - * @param startAngle the beginning angle. - * @param arcAngle the angular extent of the arc, - * relative to the start angle. - * @see java.awt.Graphics#fillArc - */ - public void drawArc(int x, int y, int width, int height, - int startAngle, int arcAngle) { - Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN); - draw(arc); - } - - - /** - * Draws a sequence of connected lines defined by - * arrays of x and y coordinates. - * Each pair of (xy) coordinates defines a point. - * The figure is not closed if the first point - * differs from the last point. - * @param xPoints an array of x points - * @param yPoints an array of y points - * @param nPoints the total number of points - * @see java.awt.Graphics#drawPolygon(int[], int[], int) - * @since JDK1.1 - */ - public void drawPolyline(int[] xPoints, int[] yPoints, - int nPoints){ - if(nPoints > 0){ - GeneralPath path = new GeneralPath(); - path.moveTo(xPoints[0], yPoints[0]); - for(int i=1; ix, y, - * width, and height arguments. - *

        - * The oval covers an area that is - * width + 1 pixels wide - * and height + 1 pixels tall. - * @param x the x coordinate of the upper left - * corner of the oval to be drawn. - * @param y the y coordinate of the upper left - * corner of the oval to be drawn. - * @param width the width of the oval to be drawn. - * @param height the height of the oval to be drawn. - * @see java.awt.Graphics#fillOval - */ - public void drawOval(int x, int y, int width, int height){ - Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); - draw(oval); - } - - /** - * Draws as much of the specified image as is currently available. - * The image is drawn with its top-left corner at - * (xy) in this graphics context's coordinate - * space. Transparent pixels are drawn in the specified - * background color. - *

        - * This operation is equivalent to filling a rectangle of the - * width and height of the specified image with the given color and then - * drawing the image on top of it, but possibly more efficient. - *

        - * This method returns immediately in all cases, even if the - * complete image has not yet been loaded, and it has not been dithered - * and converted for the current output device. - *

        - * If the image has not yet been completely loaded, then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - * @param img the specified image to be drawn. - * @param x the x coordinate. - * @param y the y coordinate. - * @param bgcolor the background color to paint under the - * non-opaque portions of the image. - * @param observer object to be notified as more of - * the image is converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - Color bgcolor, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - - return false; - } - - /** - * Draws as much of the specified image as has already been scaled - * to fit inside the specified rectangle. - *

        - * The image is drawn inside the specified rectangle of this - * graphics context's coordinate space, and is scaled if - * necessary. Transparent pixels are drawn in the specified - * background color. - * This operation is equivalent to filling a rectangle of the - * width and height of the specified image with the given color and then - * drawing the image on top of it, but possibly more efficient. - *

        - * This method returns immediately in all cases, even if the - * entire image has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - *

        - * A scaled version of an image will not necessarily be - * available immediately just because an unscaled version of the - * image has been constructed for this output device. Each size of - * the image may be cached separately and generated from the original - * data in a separate image production sequence. - * @param img the specified image to be drawn. - * @param x the x coordinate. - * @param y the y coordinate. - * @param width the width of the rectangle. - * @param height the height of the rectangle. - * @param bgcolor the background color to paint under the - * non-opaque portions of the image. - * @param observer object to be notified as more of - * the image is converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - int width, int height, - Color bgcolor, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - - return false; - } - - - /** - * Draws as much of the specified area of the specified image as is - * currently available, scaling it on the fly to fit inside the - * specified area of the destination drawable surface. Transparent pixels - * do not affect whatever pixels are already there. - *

        - * This method returns immediately in all cases, even if the - * image area to be drawn has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - *

        - * This method always uses the unscaled version of the image - * to render the scaled rectangle and performs the required - * scaling on the fly. It does not use a cached, scaled version - * of the image for this operation. Scaling of the image from source - * to destination is performed such that the first coordinate - * of the source rectangle is mapped to the first coordinate of - * the destination rectangle, and the second source coordinate is - * mapped to the second destination coordinate. The subimage is - * scaled and flipped as needed to preserve those mappings. - * @param img the specified image to be drawn - * @param dx1 the x coordinate of the first corner of the - * destination rectangle. - * @param dy1 the y coordinate of the first corner of the - * destination rectangle. - * @param dx2 the x coordinate of the second corner of the - * destination rectangle. - * @param dy2 the y coordinate of the second corner of the - * destination rectangle. - * @param sx1 the x coordinate of the first corner of the - * source rectangle. - * @param sy1 the y coordinate of the first corner of the - * source rectangle. - * @param sx2 the x coordinate of the second corner of the - * source rectangle. - * @param sy2 the y coordinate of the second corner of the - * source rectangle. - * @param observer object to be notified as more of the image is - * scaled and converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - * @since JDK1.1 - */ - @NotImplemented - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Draws as much of the specified area of the specified image as is - * currently available, scaling it on the fly to fit inside the - * specified area of the destination drawable surface. - *

        - * Transparent pixels are drawn in the specified background color. - * This operation is equivalent to filling a rectangle of the - * width and height of the specified image with the given color and then - * drawing the image on top of it, but possibly more efficient. - *

        - * This method returns immediately in all cases, even if the - * image area to be drawn has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete then - * drawImage returns false. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - *

        - * This method always uses the unscaled version of the image - * to render the scaled rectangle and performs the required - * scaling on the fly. It does not use a cached, scaled version - * of the image for this operation. Scaling of the image from source - * to destination is performed such that the first coordinate - * of the source rectangle is mapped to the first coordinate of - * the destination rectangle, and the second source coordinate is - * mapped to the second destination coordinate. The subimage is - * scaled and flipped as needed to preserve those mappings. - * @param img the specified image to be drawn - * @param dx1 the x coordinate of the first corner of the - * destination rectangle. - * @param dy1 the y coordinate of the first corner of the - * destination rectangle. - * @param dx2 the x coordinate of the second corner of the - * destination rectangle. - * @param dy2 the y coordinate of the second corner of the - * destination rectangle. - * @param sx1 the x coordinate of the first corner of the - * source rectangle. - * @param sy1 the y coordinate of the first corner of the - * source rectangle. - * @param sx2 the x coordinate of the second corner of the - * source rectangle. - * @param sy2 the y coordinate of the second corner of the - * source rectangle. - * @param bgcolor the background color to paint under the - * non-opaque portions of the image. - * @param observer object to be notified as more of the image is - * scaled and converted. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - * @since JDK1.1 - */ - @NotImplemented - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - Color bgcolor, - ImageObserver observer){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Draws as much of the specified image as is currently available. - * The image is drawn with its top-left corner at - * (xy) in this graphics context's coordinate - * space. Transparent pixels in the image do not affect whatever - * pixels are already there. - *

        - * This method returns immediately in all cases, even if the - * complete image has not yet been loaded, and it has not been dithered - * and converted for the current output device. - *

        - * If the image has completely loaded and its pixels are - * no longer being changed, then - * drawImage returns true. - * Otherwise, drawImage returns false - * and as more of - * the image becomes available - * or it is time to draw another frame of animation, - * the process that loads the image notifies - * the specified image observer. - * @param img the specified image to be drawn. This method does - * nothing if img is null. - * @param x the x coordinate. - * @param y the y coordinate. - * @param observer object to be notified as more of - * the image is converted. - * @return false if the image pixels are still changing; - * true otherwise. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - ImageObserver observer) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Disposes of this graphics context and releases - * any system resources that it is using. - * A Graphics object cannot be used after - * disposehas been called. - *

        - * When a Java program runs, a large number of Graphics - * objects can be created within a short time frame. - * Although the finalization process of the garbage collector - * also disposes of the same system resources, it is preferable - * to manually free the associated resources by calling this - * method rather than to rely on a finalization process which - * may not run to completion for a long period of time. - *

        - * Graphics objects which are provided as arguments to the - * paint and update methods - * of components are automatically released by the system when - * those methods return. For efficiency, programmers should - * call dispose when finished using - * a Graphics object only if it was created - * directly from a component or another Graphics object. - * @see java.awt.Graphics#finalize - * @see java.awt.Component#paint - * @see java.awt.Component#update - * @see java.awt.Component#getGraphics - * @see java.awt.Graphics#create - */ - public void dispose() { - } - - /** - * Draws a line, using the current color, between the points - * (x1, y1) and (x2, y2) - * in this graphics context's coordinate system. - * @param x1 the first point's x coordinate. - * @param y1 the first point's y coordinate. - * @param x2 the second point's x coordinate. - * @param y2 the second point's y coordinate. - */ - public void drawLine(int x1, int y1, int x2, int y2){ - Line2D line = new Line2D.Float(x1, y1, x2, y2); - draw(line); - } - - /** - * Fills a closed polygon defined by - * arrays of x and y coordinates. - *

        - * This method draws the polygon defined by nPoint line - * segments, where the first nPoint - 1 - * line segments are line segments from - * (xPoints[i - 1], yPoints[i - 1]) - * to (xPoints[i], yPoints[i]), for - * 1 ≤ i ≤ nPoints. - * The figure is automatically closed by drawing a line connecting - * the final point to the first point, if those points are different. - *

        - * The area inside the polygon is defined using an - * even-odd fill rule, also known as the alternating rule. - * @param xPoints a an array of x coordinates. - * @param yPoints a an array of y coordinates. - * @param nPoints a the total number of points. - * @see java.awt.Graphics#drawPolygon(int[], int[], int) - */ - public void fillPolygon(int[] xPoints, int[] yPoints, - int nPoints){ - java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints); - fill(polygon); - } - - /** - * Fills the specified rectangle. - * The left and right edges of the rectangle are at - * x and x + width - 1. - * The top and bottom edges are at - * y and y + height - 1. - * The resulting rectangle covers an area - * width pixels wide by - * height pixels tall. - * The rectangle is filled using the graphics context's current color. - * @param x the x coordinate - * of the rectangle to be filled. - * @param y the y coordinate - * of the rectangle to be filled. - * @param width the width of the rectangle to be filled. - * @param height the height of the rectangle to be filled. - * @see java.awt.Graphics#clearRect - * @see java.awt.Graphics#drawRect - */ - public void fillRect(int x, int y, int width, int height){ - Rectangle rect = new Rectangle(x, y, width, height); - fill(rect); - } - - /** - * Draws the outline of the specified rectangle. - * The left and right edges of the rectangle are at - * x and x + width. - * The top and bottom edges are at - * y and y + height. - * The rectangle is drawn using the graphics context's current color. - * @param x the x coordinate - * of the rectangle to be drawn. - * @param y the y coordinate - * of the rectangle to be drawn. - * @param width the width of the rectangle to be drawn. - * @param height the height of the rectangle to be drawn. - * @see java.awt.Graphics#fillRect - * @see java.awt.Graphics#clearRect - */ - public void drawRect(int x, int y, int width, int height) { - Rectangle rect = new Rectangle(x, y, width, height); - draw(rect); - } - - /** - * Draws a closed polygon defined by - * arrays of x and y coordinates. - * Each pair of (xy) coordinates defines a point. - *

        - * This method draws the polygon defined by nPoint line - * segments, where the first nPoint - 1 - * line segments are line segments from - * (xPoints[i - 1], yPoints[i - 1]) - * to (xPoints[i], yPoints[i]), for - * 1 ≤ i ≤ nPoints. - * The figure is automatically closed by drawing a line connecting - * the final point to the first point, if those points are different. - * @param xPoints a an array of x coordinates. - * @param yPoints a an array of y coordinates. - * @param nPoints a the total number of points. - * @see java.awt.Graphics#fillPolygon(int[],int[],int) - * @see java.awt.Graphics#drawPolyline - */ - public void drawPolygon(int[] xPoints, int[] yPoints, - int nPoints){ - java.awt.Polygon polygon = new java.awt.Polygon(xPoints, yPoints, nPoints); - draw(polygon); - } - - /** - * Intersects the current clip with the specified rectangle. - * The resulting clipping area is the intersection of the current - * clipping area and the specified rectangle. If there is no - * current clipping area, either because the clip has never been - * set, or the clip has been cleared using setClip(null), - * the specified rectangle becomes the new clip. - * This method sets the user clip, which is independent of the - * clipping associated with device bounds and window visibility. - * This method can only be used to make the current clip smaller. - * To set the current clip larger, use any of the setClip methods. - * Rendering operations have no effect outside of the clipping area. - * @param x the x coordinate of the rectangle to intersect the clip with - * @param y the y coordinate of the rectangle to intersect the clip with - * @param width the width of the rectangle to intersect the clip with - * @param height the height of the rectangle to intersect the clip with - * @see #setClip(int, int, int, int) - * @see #setClip(Shape) - */ - public void clipRect(int x, int y, int width, int height){ - clip(new Rectangle(x, y, width, height)); - } - - /** - * Sets the current clipping area to an arbitrary clip shape. - * Not all objects that implement the Shape - * interface can be used to set the clip. The only - * Shape objects that are guaranteed to be - * supported are Shape objects that are - * obtained via the getClip method and via - * Rectangle objects. This method sets the - * user clip, which is independent of the clipping associated - * with device bounds and window visibility. - * @param clip the Shape to use to set the clip - * @see java.awt.Graphics#getClip() - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(int, int, int, int) - * @since JDK1.1 - */ - @NotImplemented - public void setClip(Shape clip) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Returns the bounding rectangle of the current clipping area. - * This method refers to the user clip, which is independent of the - * clipping associated with device bounds and window visibility. - * If no clip has previously been set, or if the clip has been - * cleared using setClip(null), this method returns - * null. - * The coordinates in the rectangle are relative to the coordinate - * system origin of this graphics context. - * @return the bounding rectangle of the current clipping area, - * or null if no clip is set. - * @see java.awt.Graphics#getClip - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(int, int, int, int) - * @see java.awt.Graphics#setClip(Shape) - * @since JDK1.1 - */ - public Rectangle getClipBounds(){ - Shape c = getClip(); - if (c==null) { - return null; - } - return c.getBounds(); - } - - /** - * Draws the text given by the specified iterator, using this - * graphics context's current color. The iterator has to specify a font - * for each character. The baseline of the - * first character is at position (xy) in this - * graphics context's coordinate system. - * @param iterator the iterator whose text is to be drawn - * @param x the x coordinate. - * @param y the y coordinate. - * @see java.awt.Graphics#drawBytes - * @see java.awt.Graphics#drawChars - */ - public void drawString(AttributedCharacterIterator iterator, - int x, int y){ - drawString(iterator, (float)x, (float)y); - } - - /** - * Clears the specified rectangle by filling it with the background - * color of the current drawing surface. This operation does not - * use the current paint mode. - *

        - * Beginning with Java 1.1, the background color - * of offscreen images may be system dependent. Applications should - * use setColor followed by fillRect to - * ensure that an offscreen image is cleared to a specific color. - * @param x the x coordinate of the rectangle to clear. - * @param y the y coordinate of the rectangle to clear. - * @param width the width of the rectangle to clear. - * @param height the height of the rectangle to clear. - * @see java.awt.Graphics#fillRect(int, int, int, int) - * @see java.awt.Graphics#drawRect - * @see java.awt.Graphics#setColor(java.awt.Color) - * @see java.awt.Graphics#setPaintMode - * @see java.awt.Graphics#setXORMode(java.awt.Color) - */ - public void clearRect(int x, int y, int width, int height) { - Paint paint = getPaint(); - setColor(getBackground()); - fillRect(x, y, width, height); - setPaint(paint); - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - } - - /** - * Sets the current clip to the rectangle specified by the given - * coordinates. This method sets the user clip, which is - * independent of the clipping associated with device bounds - * and window visibility. - * Rendering operations have no effect outside of the clipping area. - * @param x the x coordinate of the new clip rectangle. - * @param y the y coordinate of the new clip rectangle. - * @param width the width of the new clip rectangle. - * @param height the height of the new clip rectangle. - * @see java.awt.Graphics#clipRect - * @see java.awt.Graphics#setClip(Shape) - * @since JDK1.1 - */ - public void setClip(int x, int y, int width, int height){ - setClip(new Rectangle(x, y, width, height)); - } - - /** - * Concatenates the current Graphics2D - * Transform with a rotation transform. - * Subsequent rendering is rotated by the specified radians relative - * to the previous origin. - * This is equivalent to calling transform(R), where R is an - * AffineTransform represented by the following matrix: - *

        -     *          [   cos(theta)    -sin(theta)    0   ]
        -     *          [   sin(theta)     cos(theta)    0   ]
        -     *          [       0              0         1   ]
        -     * 
        - * Rotating with a positive angle theta rotates points on the positive - * x axis toward the positive y axis. - * @param theta the angle of rotation in radians - */ - public void rotate(double theta){ - _transform.rotate(theta); - } - - /** - * Concatenates the current Graphics2D - * Transform with a translated rotation - * transform. Subsequent rendering is transformed by a transform - * which is constructed by translating to the specified location, - * rotating by the specified radians, and translating back by the same - * amount as the original translation. This is equivalent to the - * following sequence of calls: - *
        -     *          translate(x, y);
        -     *          rotate(theta);
        -     *          translate(-x, -y);
        -     * 
        - * Rotating with a positive angle theta rotates points on the positive - * x axis toward the positive y axis. - * @param theta the angle of rotation in radians - * @param x x coordinate of the origin of the rotation - * @param y y coordinate of the origin of the rotation - */ - public void rotate(double theta, double x, double y){ - _transform.rotate(theta, x, y); - } - - /** - * Concatenates the current Graphics2D - * Transform with a shearing transform. - * Subsequent renderings are sheared by the specified - * multiplier relative to the previous position. - * This is equivalent to calling transform(SH), where SH - * is an AffineTransform represented by the following - * matrix: - *
        -     *          [   1   shx   0   ]
        -     *          [  shy   1    0   ]
        -     *          [   0    0    1   ]
        -     * 
        - * @param shx the multiplier by which coordinates are shifted in - * the positive X axis direction as a function of their Y coordinate - * @param shy the multiplier by which coordinates are shifted in - * the positive Y axis direction as a function of their X coordinate - */ - public void shear(double shx, double shy){ - _transform.shear(shx, shy); - } - - /** - * Get the rendering context of the Font within this - * Graphics2D context. - * The {@link FontRenderContext} - * encapsulates application hints such as anti-aliasing and - * fractional metrics, as well as target device specific information - * such as dots-per-inch. This information should be provided by the - * application when using objects that perform typographical - * formatting, such as Font and - * TextLayout. This information should also be provided - * by applications that perform their own layout and need accurate - * measurements of various characteristics of glyphs such as advance - * and line height when various rendering hints have been applied to - * the text rendering. - * - * @return a reference to an instance of FontRenderContext. - * @see java.awt.font.FontRenderContext - * @see java.awt.Font#createGlyphVector(FontRenderContext,char[]) - * @see java.awt.font.TextLayout - * @since JDK1.2 - */ - public FontRenderContext getFontRenderContext() { - boolean isAntiAliased = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals( - getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING)); - boolean usesFractionalMetrics = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals( - getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS)); - - - return new FontRenderContext(new AffineTransform(), isAntiAliased, usesFractionalMetrics); - } - - /** - * Composes an AffineTransform object with the - * Transform in this Graphics2D according - * to the rule last-specified-first-applied. If the current - * Transform is Cx, the result of composition - * with Tx is a new Transform Cx'. Cx' becomes the - * current Transform for this Graphics2D. - * Transforming a point p by the updated Transform Cx' is - * equivalent to first transforming p by Tx and then transforming - * the result by the original Transform Cx. In other - * words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary, - * so further modifications to Tx do not affect rendering. - * @param Tx the AffineTransform object to be composed with - * the current Transform - * @see #setTransform - * @see AffineTransform - */ - public void transform(AffineTransform Tx) { - _transform.concatenate(Tx); - } - - /** - * Renders a BufferedImage that is - * filtered with a - * {@link BufferedImageOp}. - * The rendering attributes applied include the Clip, - * Transform - * and Composite attributes. This is equivalent to: - *
        -     * img1 = op.filter(img, null);
        -     * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
        -     * 
        - * @param img the BufferedImage to be rendered - * @param op the filter to be applied to the image before rendering - * @param x the x coordinate in user space where the image is rendered - * @param y the y coordinate in user space where the image is rendered - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip(Shape) - */ - public void drawImage(BufferedImage img, - BufferedImageOp op, - int x, - int y){ - img = op.filter(img, null); - drawImage(img, x, y, null); - } - - /** - * Sets the background color for the Graphics2D context. - * The background color is used for clearing a region. - * When a Graphics2D is constructed for a - * Component, the background color is - * inherited from the Component. Setting the background color - * in the Graphics2D context only affects the subsequent - * clearRect calls and not the background color of the - * Component. To change the background - * of the Component, use appropriate methods of - * the Component. - * @param color the background color that isused in - * subsequent calls to clearRect - * @see #getBackground - * @see java.awt.Graphics#clearRect - */ - public void setBackground(Color color) { - if(color == null) - return; - - _background = color; - } - - /** - * Returns the background color used for clearing a region. - * @return the current Graphics2D Color, - * which defines the background color. - * @see #setBackground - */ - public Color getBackground(){ - return _background; - } - - /** - * Sets the Composite for the Graphics2D context. - * The Composite is used in all drawing methods such as - * drawImage, drawString, draw, - * and fill. It specifies how new pixels are to be combined - * with the existing pixels on the graphics device during the rendering - * process. - *

        If this Graphics2D context is drawing to a - * Component on the display screen and the - * Composite is a custom object rather than an - * instance of the AlphaComposite class, and if - * there is a security manager, its checkPermission - * method is called with an AWTPermission("readDisplayPixels") - * permission. - * - * @param comp the Composite object to be used for rendering - * @throws SecurityException - * if a custom Composite object is being - * used to render to the screen and a security manager - * is set and its checkPermission method - * does not allow the operation. - * @see java.awt.Graphics#setXORMode - * @see java.awt.Graphics#setPaintMode - * @see java.awt.AlphaComposite - */ - @NotImplemented - public void setComposite(Composite comp){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Returns the current Composite in the - * Graphics2D context. - * @return the current Graphics2D Composite, - * which defines a compositing style. - * @see #setComposite - */ - @NotImplemented - public Composite getComposite(){ - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return null; - } - - /** - * Returns the value of a single preference for the rendering algorithms. - * Hint categories include controls for rendering quality and overall - * time/quality trade-off in the rendering process. Refer to the - * RenderingHints class for definitions of some common - * keys and values. - * @param hintKey the key corresponding to the hint to get. - * @return an object representing the value for the specified hint key. - * Some of the keys and their associated values are defined in the - * RenderingHints class. - * @see RenderingHints - */ - public Object getRenderingHint(RenderingHints.Key hintKey){ - return _hints.get(hintKey); - } - - /** - * Sets the value of a single preference for the rendering algorithms. - * Hint categories include controls for rendering quality and overall - * time/quality trade-off in the rendering process. Refer to the - * RenderingHints class for definitions of some common - * keys and values. - * @param hintKey the key of the hint to be set. - * @param hintValue the value indicating preferences for the specified - * hint category. - * @see RenderingHints - */ - public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue){ - _hints.put(hintKey, hintValue); - } - - - /** - * Renders the text of the specified - * {@link GlyphVector} using - * the Graphics2D context's rendering attributes. - * The rendering attributes applied include the Clip, - * Transform, Paint, and - * Composite attributes. The GlyphVector - * specifies individual glyphs from a {@link Font}. - * The GlyphVector can also contain the glyph positions. - * This is the fastest way to render a set of characters to the - * screen. - * - * @param g the GlyphVector to be rendered - * @param x the x position in user space where the glyphs should be - * rendered - * @param y the y position in user space where the glyphs should be - * rendered - * - * @see java.awt.Font#createGlyphVector(FontRenderContext, char[]) - * @see java.awt.font.GlyphVector - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #setTransform - * @see #setComposite - * @see #setClip(Shape) - */ - public void drawGlyphVector(GlyphVector g, float x, float y) { - Shape glyphOutline = g.getOutline(x, y); - fill(glyphOutline); - } - - /** - * Returns the device configuration associated with this - * Graphics2D. - * @return the device configuration - */ - public GraphicsConfiguration getDeviceConfiguration() { - return GraphicsEnvironment.getLocalGraphicsEnvironment(). - getDefaultScreenDevice().getDefaultConfiguration(); - } - - /** - * Sets the values of an arbitrary number of preferences for the - * rendering algorithms. - * Only values for the rendering hints that are present in the - * specified Map object are modified. - * All other preferences not present in the specified - * object are left unmodified. - * Hint categories include controls for rendering quality and - * overall time/quality trade-off in the rendering process. - * Refer to the RenderingHints class for definitions of - * some common keys and values. - * @param hints the rendering hints to be set - * @see RenderingHints - */ - public void addRenderingHints(Map hints){ - this._hints.putAll(hints); - } - - /** - * Concatenates the current - * Graphics2D Transform - * with a translation transform. - * Subsequent rendering is translated by the specified - * distance relative to the previous position. - * This is equivalent to calling transform(T), where T is an - * AffineTransform represented by the following matrix: - *

        -     *          [   1    0    tx  ]
        -     *          [   0    1    ty  ]
        -     *          [   0    0    1   ]
        -     * 
        - * @param tx the distance to translate along the x-axis - * @param ty the distance to translate along the y-axis - */ - public void translate(double tx, double ty){ - _transform.translate(tx, ty); - } - - /** - * Renders the text of the specified iterator, using the - * Graphics2D context's current Paint. The - * iterator must specify a font - * for each character. The baseline of the - * first character is at position (xy) in the - * User Space. - * The rendering attributes applied include the Clip, - * Transform, Paint, and - * Composite attributes. - * For characters in script systems such as Hebrew and Arabic, - * the glyphs can be rendered from right to left, in which case the - * coordinate supplied is the location of the leftmost character - * on the baseline. - * @param iterator the iterator whose text is to be rendered - * @param x the x coordinate where the iterator's text is to be - * rendered - * @param y the y coordinate where the iterator's text is to be - * rendered - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #setTransform - * @see #setComposite - * @see #setClip - */ - @NotImplemented - public void drawString(AttributedCharacterIterator iterator, float x, float y) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Checks whether or not the specified Shape intersects - * the specified {@link Rectangle}, which is in device - * space. If onStroke is false, this method checks - * whether or not the interior of the specified Shape - * intersects the specified Rectangle. If - * onStroke is true, this method checks - * whether or not the Stroke of the specified - * Shape outline intersects the specified - * Rectangle. - * The rendering attributes taken into account include the - * Clip, Transform, and Stroke - * attributes. - * @param rect the area in device space to check for a hit - * @param s the Shape to check for a hit - * @param onStroke flag used to choose between testing the - * stroked or the filled shape. If the flag is true, the - * Stroke oultine is tested. If the flag is - * false, the filled Shape is tested. - * @return true if there is a hit; false - * otherwise. - * @see #setStroke - * @see #fill(Shape) - * @see #draw(Shape) - * @see #_transform - * @see #setTransform - * @see #clip - * @see #setClip(Shape) - */ - public boolean hit(Rectangle rect, - Shape s, - boolean onStroke){ - if (onStroke) { - s = getStroke().createStrokedShape(s); - } - - s = getTransform().createTransformedShape(s); - - return s.intersects(rect); - } - - /** - * Gets the preferences for the rendering algorithms. Hint categories - * include controls for rendering quality and overall time/quality - * trade-off in the rendering process. - * Returns all of the hint key/value pairs that were ever specified in - * one operation. Refer to the - * RenderingHints class for definitions of some common - * keys and values. - * @return a reference to an instance of RenderingHints - * that contains the current preferences. - * @see RenderingHints - */ - public RenderingHints getRenderingHints(){ - return _hints; - } - - /** - * Replaces the values of all preferences for the rendering - * algorithms with the specified hints. - * The existing values for all rendering hints are discarded and - * the new set of known hints and values are initialized from the - * specified {@link Map} object. - * Hint categories include controls for rendering quality and - * overall time/quality trade-off in the rendering process. - * Refer to the RenderingHints class for definitions of - * some common keys and values. - * @param hints the rendering hints to be set - * @see RenderingHints - */ - public void setRenderingHints(Map hints){ - this._hints = new RenderingHints(null); - this._hints.putAll(hints); - } - - /** - * Renders an image, applying a transform from image space into user space - * before drawing. - * The transformation from user space into device space is done with - * the current Transform in the Graphics2D. - * The specified transformation is applied to the image before the - * transform attribute in the Graphics2D context is applied. - * The rendering attributes applied include the Clip, - * Transform, and Composite attributes. - * Note that no rendering is done if the specified transform is - * noninvertible. - * @param img the Image to be rendered - * @param xform the transformation from image space into user space - * @param obs the {@link ImageObserver} - * to be notified as more of the Image - * is converted - * @return true if the Image is - * fully loaded and completely rendered; - * false if the Image is still being loaded. - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip(Shape) - */ - @NotImplemented - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Draws as much of the specified image as has already been scaled - * to fit inside the specified rectangle. - *

        - * The image is drawn inside the specified rectangle of this - * graphics context's coordinate space, and is scaled if - * necessary. Transparent pixels do not affect whatever pixels - * are already there. - *

        - * This method returns immediately in all cases, even if the - * entire image has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete, then - * drawImage returns false. As more of - * the image becomes available, the process that loads the image notifies - * the image observer by calling its imageUpdate method. - *

        - * A scaled version of an image will not necessarily be - * available immediately just because an unscaled version of the - * image has been constructed for this output device. Each size of - * the image may be cached separately and generated from the original - * data in a separate image production sequence. - * @param img the specified image to be drawn. This method does - * nothing if img is null. - * @param x the x coordinate. - * @param y the y coordinate. - * @param width the width of the rectangle. - * @param height the height of the rectangle. - * @param observer object to be notified as more of - * the image is converted. - * @return false if the image pixels are still changing; - * true otherwise. - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - @NotImplemented - public boolean drawImage(Image img, int x, int y, - int width, int height, - ImageObserver observer) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - return false; - } - - /** - * Creates a new Graphics object that is - * a copy of this Graphics object. - * @return a new graphics context that is a copy of - * this graphics context. - */ - public Graphics create() { - try { - return (Graphics)clone(); - } catch (CloneNotSupportedException e){ - throw new HSLFException(e); - } - } - - /** - * Gets the font metrics for the specified font. - * @return the font metrics for the specified font. - * @param f the specified font - * @see java.awt.Graphics#getFont - * @see java.awt.FontMetrics - * @see java.awt.Graphics#getFontMetrics() - */ - @SuppressWarnings("deprecation") - @SuppressForbidden - public FontMetrics getFontMetrics(Font f) { - return Toolkit.getDefaultToolkit().getFontMetrics(f); - } - - /** - * Sets the paint mode of this graphics context to alternate between - * this graphics context's current color and the new specified color. - * This specifies that logical pixel operations are performed in the - * XOR mode, which alternates pixels between the current color and - * a specified XOR color. - *

        - * When drawing operations are performed, pixels which are the - * current color are changed to the specified color, and vice versa. - *

        - * Pixels that are of colors other than those two colors are changed - * in an unpredictable but reversible manner; if the same figure is - * drawn twice, then all pixels are restored to their original values. - * @param c1 the XOR alternation color - */ - @NotImplemented - public void setXORMode(Color c1) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Sets the paint mode of this graphics context to overwrite the - * destination with this graphics context's current color. - * This sets the logical pixel operation function to the paint or - * overwrite mode. All subsequent rendering operations will - * overwrite the destination with the current color. - */ - @NotImplemented - public void setPaintMode() { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Renders a - * {@link RenderableImage}, - * applying a transform from image space into user space before drawing. - * The transformation from user space into device space is done with - * the current Transform in the Graphics2D. - * The specified transformation is applied to the image before the - * transform attribute in the Graphics2D context is applied. - * The rendering attributes applied include the Clip, - * Transform, and Composite attributes. Note - * that no rendering is done if the specified transform is - * noninvertible. - *

        - * Rendering hints set on the Graphics2D object might - * be used in rendering the RenderableImage. - * If explicit control is required over specific hints recognized by a - * specific RenderableImage, or if knowledge of which hints - * are used is required, then a RenderedImage should be - * obtained directly from the RenderableImage - * and rendered using - *{@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. - * @param img the image to be rendered. This method does - * nothing if img is null. - * @param xform the transformation from image space into user space - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - * @see #drawRenderedImage - */ - @NotImplemented - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - /** - * Renders a {@link RenderedImage}, - * applying a transform from image - * space into user space before drawing. - * The transformation from user space into device space is done with - * the current Transform in the Graphics2D. - * The specified transformation is applied to the image before the - * transform attribute in the Graphics2D context is applied. - * The rendering attributes applied include the Clip, - * Transform, and Composite attributes. Note - * that no rendering is done if the specified transform is - * noninvertible. - * @param img the image to be rendered. This method does - * nothing if img is null. - * @param xform the transformation from image space into user space - * @see #_transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - */ - @NotImplemented - public void drawRenderableImage(RenderableImage img, AffineTransform xform) { - if (log.check(POILogger.WARN)) { - log.log(POILogger.WARN, "Not implemented"); - } - } - - protected void applyStroke(HSLFSimpleShape shape) { - if (_stroke instanceof BasicStroke){ - BasicStroke bs = (BasicStroke)_stroke; - shape.setLineWidth(bs.getLineWidth()); - float[] dash = bs.getDashArray(); - if (dash != null) { - //TODO: implement more dashing styles - shape.setLineDash(StrokeStyle.LineDash.DASH); - } - } - } - - protected void applyPaint(HSLFSimpleShape shape) { - if (_paint instanceof Color) { - shape.getFill().setForegroundColor((Color)_paint); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java deleted file mode 100644 index 9c2cb24ed..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.usermodel.*; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.Units; - -import java.awt.geom.Point2D; - -/** - * A simple closed polygon shape - * - * @author Yegor Kozlov - */ -public final class Polygon extends HSLFAutoShape { - /** - * Create a Polygon object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected Polygon(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - - } - - /** - * Create a new Polygon. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public Polygon(ShapeContainer parent){ - super((EscherContainerRecord)null, parent); - _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape); - } - - /** - * Create a new Polygon. This constructor is used when a new shape is created. - * - */ - public Polygon(){ - this(null); - } - - /** - * Set the polygon vertices - * - * @param xPoints - * @param yPoints - */ - public void setPoints(float[] xPoints, float[] yPoints) - { - float right = findBiggest(xPoints); - float bottom = findBiggest(yPoints); - float left = findSmallest(xPoints); - float top = findSmallest(yPoints); - - AbstractEscherOptRecord opt = getEscherOptRecord(); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, Units.pointsToMaster(right - left))); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, Units.pointsToMaster(bottom - top))); - - for (int i = 0; i < xPoints.length; i++) { - xPoints[i] += -left; - yPoints[i] += -top; - } - - int numpoints = xPoints.length; - - EscherArrayProperty verticesProp = new EscherArrayProperty(EscherProperties.GEOMETRY__VERTICES, false, new byte[0] ); - verticesProp.setNumberOfElementsInArray(numpoints+1); - verticesProp.setNumberOfElementsInMemory(numpoints+1); - verticesProp.setSizeOfElements(0xFFF0); - for (int i = 0; i < numpoints; i++) - { - byte[] data = new byte[4]; - LittleEndian.putShort(data, 0, (short)Units.pointsToMaster(xPoints[i])); - LittleEndian.putShort(data, 2, (short)Units.pointsToMaster(yPoints[i])); - verticesProp.setElement(i, data); - } - byte[] data = new byte[4]; - LittleEndian.putShort(data, 0, (short)Units.pointsToMaster(xPoints[0])); - LittleEndian.putShort(data, 2, (short)Units.pointsToMaster(yPoints[0])); - verticesProp.setElement(numpoints, data); - opt.addEscherProperty(verticesProp); - - EscherArrayProperty segmentsProp = new EscherArrayProperty(EscherProperties.GEOMETRY__SEGMENTINFO, false, null ); - segmentsProp.setSizeOfElements(0x0002); - segmentsProp.setNumberOfElementsInArray(numpoints * 2 + 4); - segmentsProp.setNumberOfElementsInMemory(numpoints * 2 + 4); - segmentsProp.setElement(0, new byte[] { (byte)0x00, (byte)0x40 } ); - segmentsProp.setElement(1, new byte[] { (byte)0x00, (byte)0xAC } ); - for (int i = 0; i < numpoints; i++) - { - segmentsProp.setElement(2 + i * 2, new byte[] { (byte)0x01, (byte)0x00 } ); - segmentsProp.setElement(3 + i * 2, new byte[] { (byte)0x00, (byte)0xAC } ); - } - segmentsProp.setElement(segmentsProp.getNumberOfElementsInArray() - 2, new byte[] { (byte)0x01, (byte)0x60 } ); - segmentsProp.setElement(segmentsProp.getNumberOfElementsInArray() - 1, new byte[] { (byte)0x00, (byte)0x80 } ); - opt.addEscherProperty(segmentsProp); - - opt.sortProperties(); - } - - /** - * Set the polygon vertices - * - * @param points the polygon vertices - */ - public void setPoints(Point2D[] points) - { - float[] xpoints = new float[points.length]; - float[] ypoints = new float[points.length]; - for (int i = 0; i < points.length; i++) { - xpoints[i] = (float)points[i].getX(); - ypoints[i] = (float)points[i].getY(); - - } - - setPoints(xpoints, ypoints); - } - - private float findBiggest( float[] values ) - { - float result = Float.MIN_VALUE; - for ( int i = 0; i < values.length; i++ ) - { - if (values[i] > result) - result = values[i]; - } - return result; - } - - private float findSmallest( float[] values ) - { - float result = Float.MAX_VALUE; - for ( int i = 0; i < values.length; i++ ) - { - if (values[i] < result) - result = values[i]; - } - return result; - } - - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java deleted file mode 100644 index a8847d072..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java +++ /dev/null @@ -1,181 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Definition of a special kind of property of some text, or its - * paragraph. For these properties, a flag in the "contains" header - * field tells you the data property family will exist. The value - * of the property is itself a mask, encoding several different - * (but related) properties - */ -public abstract class BitMaskTextProp extends TextProp implements Cloneable { - protected static final POILogger logger = POILogFactory.getLogger(BitMaskTextProp.class); - - private String[] subPropNames; - private int[] subPropMasks; - private boolean[] subPropMatches; - - /** Fetch the list of the names of the sub properties */ - public String[] getSubPropNames() { return subPropNames; } - /** Fetch the list of if the sub properties match or not */ - public boolean[] getSubPropMatches() { return subPropMatches; } - - protected BitMaskTextProp(int sizeOfDataBlock, int maskInHeader, String overallName, String... subPropNames) { - super(sizeOfDataBlock,maskInHeader,"bitmask"); - this.subPropNames = subPropNames; - this.propName = overallName; - subPropMasks = new int[subPropNames.length]; - subPropMatches = new boolean[subPropNames.length]; - - int LSB = Integer.lowestOneBit(maskInHeader); - - // Initialise the masks list - for(int i=0; i= TxMasterStyleAtom.MAX_INDENT || - indentLevel < 0) { - throw new IllegalArgumentException("Indent must be between 0 and 4"); - } - this.indentLevel = (short)indentLevel; - } - - /** - * Update the size of the text that this set of properties - * applies to - */ - public void updateTextSize(int textSize) { - charactersCovered = textSize; - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java deleted file mode 100644 index d7c6072ee..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -/** - * Definition for the common paragraph text property bitset. - * - * @author Yegor Kozlov - */ -public final class ParagraphFlagsTextProp extends BitMaskTextProp { - public static final int BULLET_IDX = 0; - public static final int BULLET_HARDFONT_IDX = 1; - public static final int BULLET_HARDCOLOR_IDX = 2; - public static final int BULLET_HARDSIZE_IDX = 4; - - public static final String NAME = "paragraph_flags"; - - public ParagraphFlagsTextProp() { - super(2, 0xF, NAME, - "bullet", - "bullet.hardfont", - "bullet.hardcolor", - "bullet.hardsize" - ); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java deleted file mode 100644 index d1046a1f0..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java +++ /dev/null @@ -1,123 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; - -/** - * Container for tabstop lists - */ -public class TabStopPropCollection extends TextProp { - public enum TabStopType { - LEFT(0), CENTER(1), RIGHT(2), DECIMAL(3); - private final int val; - TabStopType(int val) { - this.val = val; - } - public static TabStopType fromRecordVal(int val) { - for (TabStopType tst : values()) { - if (tst.val == val) return tst; - } - return LEFT; - } - } - - public static class TabStop { - /** - * If the TextPFException record that contains this TabStop structure also contains a - * leftMargin, then the value of position is relative to the left margin of the paragraph; - * otherwise, the value is relative to the left side of the paragraph. - * - * If a TextRuler record contains this TabStop structure, the value is relative to the - * left side of the text ruler. - */ - private int position; - - /** - * A enumeration that specifies how text aligns at the tab stop. - */ - private TabStopType type; - - public TabStop(int position, TabStopType type) { - this.position = position; - this.type = type; - } - - public int getPosition() { - return position; - } - - public void setPosition(int position) { - this.position = position; - } - - public TabStopType getType() { - return type; - } - - public void setType(TabStopType type) { - this.type = type; - } - } - - private List tabStops = new ArrayList(); - - public TabStopPropCollection() { - super(0, 0x100000, "tabStops"); - } - - /** - * Parses the tabstops from TxMasterStyle record - * - * @param data the data stream - * @param offset the offset within the data - */ - public void parseProperty(byte data[], int offset) { - int count = LittleEndian.getUShort(data, offset); - int off = offset + LittleEndianConsts.SHORT_SIZE; - for (int i=0; i(); - for (TabStop ts : tabStops) { - TabStop tso = new TabStop(ts.getPosition(), ts.getType()); - other.tabStops.add(tso); - } - return other; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextAlignmentProp.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextAlignmentProp.java deleted file mode 100644 index 82430f0de..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextAlignmentProp.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -/** - * Definition for the text alignment property. - */ -public class TextAlignmentProp extends TextProp { - /** - * For horizontal text, left aligned. - * For vertical text, top aligned. - */ - public static final int LEFT = 0; - - /** - * For horizontal text, centered. - * For vertical text, middle aligned. - */ - public static final int CENTER = 1; - - /** - * For horizontal text, right aligned. - * For vertical text, bottom aligned. - */ - public static final int RIGHT = 2; - - /** - * For horizontal text, flush left and right. - * For vertical text, flush top and bottom. - */ - public static final int JUSTIFY = 3; - - /** - * Distribute space between characters. - */ - public static final int DISTRIBUTED = 4; - - /** - * Thai distribution justification. - */ - public static final int THAIDISTRIBUTED = 5; - - /** - * Kashida justify low. - */ - public static final int JUSTIFYLOW = 6; - - public TextAlignmentProp() { - super(2, 0x800, "alignment"); - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPFException9.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPFException9.java deleted file mode 100644 index 128bc8365..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPFException9.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -/** - * A structure that specifies additional paragraph-level formatting - * such as Bullet Auto Number Scheme. - */ -package org.apache.poi.hslf.model.textproperties; - -import org.apache.poi.sl.usermodel.AutoNumberingScheme; -import org.apache.poi.util.LittleEndian; - -/** - * This structure store text autonumber scheme and start number. - * If a paragraph has an autonumber(fBulletHasAutoNumber = 0x0001) but start number and scheme are empty, - * this means the default values will be used: statNumber=1 and sheme=ANM_ArabicPeriod - * @see - * http://social.msdn.microsoft.com/Forums/mr-IN/os_binaryfile/thread/650888db-fabd-4b95-88dc-f0455f6e2d28 - * - * @author Alex Nikiforov [mailto:anikif@gmail.com] - * - */ -public class TextPFException9 { - //private final byte mask1; - //private final byte mask2; - private final byte mask3; - private final byte mask4; - private final Short bulletBlipRef; - private final Short fBulletHasAutoNumber; - private final AutoNumberingScheme autoNumberScheme; - private final static AutoNumberingScheme DEFAULT_AUTONUMBER_SHEME = AutoNumberingScheme.arabicPeriod; - private final Short autoNumberStartNumber; - private final static Short DEFAULT_START_NUMBER = 1; - private final int recordLength; - public TextPFException9(final byte[] source, final int startIndex) { // NOSONAR - //this.mask1 = source[startIndex]; - //this.mask2 = source[startIndex + 1]; - this.mask3 = source[startIndex + 2]; - this.mask4 = source[startIndex + 3]; - int length = 4; - int index = startIndex + 4; - if (0 == (mask3 & (byte)0x80 )) { - this.bulletBlipRef = null; - } else { - this.bulletBlipRef = LittleEndian.getShort(source, index); - index +=2; - length = 6; - } - if (0 == (mask4 & 2)) { - this.fBulletHasAutoNumber = null; - } else { - this.fBulletHasAutoNumber = LittleEndian.getShort(source, index); - index +=2; - length +=2; - } - if (0 == (mask4 & 1)) { - this.autoNumberScheme = null; - this.autoNumberStartNumber = null; - } else { - this.autoNumberScheme = AutoNumberingScheme.forNativeID(LittleEndian.getShort(source, index)); - index +=2; - this.autoNumberStartNumber = LittleEndian.getShort(source, index); - index +=2; - length +=4; - } - this.recordLength = length; - } - public Short getBulletBlipRef() { - return bulletBlipRef; - } - public Short getfBulletHasAutoNumber() { - return fBulletHasAutoNumber; - } - public AutoNumberingScheme getAutoNumberScheme() { - if (null != this.autoNumberScheme) { - return this.autoNumberScheme; - } - if (null != this.fBulletHasAutoNumber && 1 == this.fBulletHasAutoNumber.shortValue()) { - return DEFAULT_AUTONUMBER_SHEME; - } - return null; - } - public Short getAutoNumberStartNumber() { - if (null != this.autoNumberStartNumber) { - return this.autoNumberStartNumber; - } - if (null != this.fBulletHasAutoNumber && 1 == this.fBulletHasAutoNumber.shortValue()) { - return DEFAULT_START_NUMBER; - } - return null; - } - public int getRecordLength() { - return recordLength; - } - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Record length: ").append(this.recordLength).append(" bytes\n"); - sb.append("bulletBlipRef: ").append(this.bulletBlipRef).append("\n"); - sb.append("fBulletHasAutoNumber: ").append(this.fBulletHasAutoNumber).append("\n"); - sb.append("autoNumberScheme: ").append(this.autoNumberScheme).append("\n"); - sb.append("autoNumberStartNumber: ").append(this.autoNumberStartNumber).append("\n"); - return sb.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java deleted file mode 100644 index c6d1589d0..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -import java.util.Locale; - -/** - * Definition of a property of some text, or its paragraph. Defines - * how to find out if it's present (via the mask on the paragraph or - * character "contains" header field), how long the value of it is, - * and how to get and set the value. - * - * As the exact form of these (such as mask value, size of data - * block etc) is different for StyleTextProps and - * TxMasterTextProps, the definitions of the standard - * TextProps is stored in the different record classes - */ -public class TextProp implements Cloneable { - protected int sizeOfDataBlock; // Number of bytes the data part uses - protected String propName; - protected int dataValue; - protected int maskInHeader; - - /** - * Generate the definition of a given type of text property. - */ - public TextProp(int sizeOfDataBlock, int maskInHeader, String propName) { - this.sizeOfDataBlock = sizeOfDataBlock; - this.maskInHeader = maskInHeader; - this.propName = propName; - this.dataValue = 0; - } - - /** - * Clones the property - */ - public TextProp(TextProp other) { - this.sizeOfDataBlock = other.sizeOfDataBlock; - this.maskInHeader = other.maskInHeader; - this.propName = other.propName; - this.dataValue = other.dataValue; - } - - /** - * Name of the text property - */ - public String getName() { return propName; } - - /** - * Size of the data section of the text property (2 or 4 bytes) - */ - public int getSize() { return sizeOfDataBlock; } - - /** - * Mask in the paragraph or character "contains" header field - * that indicates that this text property is present. - */ - public int getMask() { return maskInHeader; } - /** - * Get the mask that's used at write time. Only differs from - * the result of getMask() for the mask based properties - */ - public int getWriteMask() { return getMask(); } - - /** - * Fetch the value of the text property (meaning is specific to - * each different kind of text property) - */ - public int getValue() { return dataValue; } - - /** - * Set the value of the text property. - */ - public void setValue(int val) { dataValue = val; } - - /** - * Clone, eg when you want to actually make use of one of these. - */ - @Override - public TextProp clone(){ - try { - return (TextProp)super.clone(); - } catch(CloneNotSupportedException e) { - throw new InternalError(e.getMessage()); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + dataValue; - result = prime * result + maskInHeader; - result = prime * result + ((propName == null) ? 0 : propName.hashCode()); - result = prime * result + sizeOfDataBlock; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TextProp other = (TextProp) obj; - if (dataValue != other.dataValue) { - return false; - } - if (maskInHeader != other.maskInHeader) { - return false; - } - if (propName == null) { - if (other.propName != null) { - return false; - } - } else if (!propName.equals(other.propName)) { - return false; - } - if (sizeOfDataBlock != other.sizeOfDataBlock) { - return false; - } - return true; - } - - @Override - public String toString() { - int len; - switch (sizeOfDataBlock) { - case 1: len = 4; break; - case 2: len = 6; break; - default: len = 10; break; - } - return String.format(Locale.ROOT, "%s = %d (%0#"+len+"X mask / %d bytes)", propName, dataValue, maskInHeader, sizeOfDataBlock); - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java deleted file mode 100644 index e82b966e6..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java +++ /dev/null @@ -1,389 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.record.StyleTextPropAtom; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * For a given run of characters, holds the properties (which could - * be paragraph properties or character properties). - * Used to hold the number of characters affected, the list of active - * properties, and the indent level if required. - */ -public class TextPropCollection { - private static final POILogger LOG = POILogFactory.getLogger(TextPropCollection.class); - - /** All the different kinds of paragraph properties we might handle */ - private static final TextProp[] paragraphTextPropTypes = { - // TextProp order is according to 2.9.20 TextPFException, - // bitmask order can be different - new ParagraphFlagsTextProp(), - new TextProp(2, 0x80, "bullet.char"), - new TextProp(2, 0x10, "bullet.font"), - new TextProp(2, 0x40, "bullet.size"), - new TextProp(4, 0x20, "bullet.color"), - new TextAlignmentProp(), - new TextProp(2, 0x1000, "linespacing"), - new TextProp(2, 0x2000, "spacebefore"), - new TextProp(2, 0x4000, "spaceafter"), - new TextProp(2, 0x100, "text.offset"), // left margin - // 0x200 - Undefined and MUST be ignored - new TextProp(2, 0x400, "bullet.offset"), // indent - new TextProp(2, 0x8000, "defaultTabSize"), - new TabStopPropCollection(), // tabstops size is variable! - new FontAlignmentProp(), - new WrapFlagsTextProp(), - new TextProp(2, 0x200000, "textDirection"), - // 0x400000 MUST be zero and MUST be ignored - new TextProp(0, 0x800000, "bullet.blip"), // TODO: check size - new TextProp(0, 0x1000000, "bullet.scheme"), // TODO: check size - new TextProp(0, 0x2000000, "hasBulletScheme"), // TODO: check size - // 0xFC000000 MUST be zero and MUST be ignored - }; - - /** All the different kinds of character properties we might handle */ - private static final TextProp[] characterTextPropTypes = new TextProp[] { - new TextProp(0, 0x100000, "pp10ext"), - new TextProp(0, 0x1000000, "newAsian.font.index"), // A bit that specifies whether the newEAFontRef field of the TextCFException10 structure that contains this CFMasks exists. - new TextProp(0, 0x2000000, "cs.font.index"), // A bit that specifies whether the csFontRef field of the TextCFException10 structure that contains this CFMasks exists. - new TextProp(0, 0x4000000, "pp11ext"), // A bit that specifies whether the pp11ext field of the TextCFException10 structure that contains this CFMasks exists. - new CharFlagsTextProp(), - new TextProp(2, 0x10000, "font.index"), - new TextProp(2, 0x200000, "asian.font.index"), - new TextProp(2, 0x400000, "ansi.font.index"), - new TextProp(2, 0x800000, "symbol.font.index"), - new TextProp(2, 0x20000, "font.size"), - new TextProp(4, 0x40000, "font.color"), - new TextProp(2, 0x80000, "superscript") - }; - - public enum TextPropType { - paragraph, character - } - - private int charactersCovered; - - // indentLevel is only valid for paragraph collection - // if it's set to -1, it must be omitted - see 2.9.36 TextMasterStyleLevel - private short indentLevel = 0; - private final Map textProps = new HashMap(); - private int maskSpecial = 0; - private final TextPropType textPropType; - - /** - * Create a new collection of text properties (be they paragraph - * or character) which will be groked via a subsequent call to - * buildTextPropList(). - */ - public TextPropCollection(int charactersCovered, TextPropType textPropType) { - this.charactersCovered = charactersCovered; - this.textPropType = textPropType; - } - - public int getSpecialMask() { - return maskSpecial; - } - - /** Fetch the number of characters this styling applies to */ - public int getCharactersCovered() { - return charactersCovered; - } - - /** Fetch the TextProps that define this styling in the record order */ - public List getTextPropList() { - List orderedList = new ArrayList(); - for (TextProp potProp : getPotentialProperties()) { - TextProp textProp = textProps.get(potProp.getName()); - if (textProp != null) { - orderedList.add(textProp); - } - } - return orderedList; - } - - /** Fetch the TextProp with this name, or null if it isn't present */ - public final TextProp findByName(String textPropName) { - return textProps.get(textPropName); - } - - public final TextProp removeByName(String name) { - return textProps.remove(name); - } - - public final TextPropType getTextPropType() { - return textPropType; - } - - private TextProp[] getPotentialProperties() { - return (textPropType == TextPropType.paragraph) ? paragraphTextPropTypes : characterTextPropTypes; - } - - /** - * Checks the paragraph or character properties for the given property name. - * Throws a HSLFException, if the name doesn't belong into this set of properties - * - * @param name the property name - * @return if found, the property template to copy from - */ - private TextProp validatePropName(String name) { - for (TextProp tp : getPotentialProperties()) { - if (tp.getName().equals(name)) { - return tp; - } - } - String errStr = - "No TextProp with name " + name + " is defined to add from. " + - "Character and paragraphs have their own properties/names."; - throw new HSLFException(errStr); - } - - /** Add the TextProp with this name to the list */ - public final TextProp addWithName(String name) { - // Find the base TextProp to base on - TextProp existing = findByName(name); - if (existing != null) return existing; - - // Add a copy of this property - TextProp textProp = validatePropName(name).clone(); - textProps.put(name,textProp); - return textProp; - } - - /** - * Add the property at the correct position. Replaces an existing property with the same name. - * - * @param textProp the property to be added - */ - public final void addProp(TextProp textProp) { - if (textProp == null) { - throw new HSLFException("TextProp must not be null"); - } - - String propName = textProp.getName(); - validatePropName(propName); - - textProps.put(propName, textProp); - } - - /** - * For an existing set of text properties, build the list of - * properties coded for in a given run of properties. - * @return the number of bytes that were used encoding the properties list - */ - public int buildTextPropList(int containsField, byte[] data, int dataOffset) { - int bytesPassed = 0; - - // For each possible entry, see if we match the mask - // If we do, decode that, save it, and shuffle on - for(TextProp tp : getPotentialProperties()) { - // Check there's still data left to read - - // Check if this property is found in the mask - if((containsField & tp.getMask()) != 0) { - if(dataOffset+bytesPassed >= data.length) { - // Out of data, can't be any more properties to go - // remember the mask and return - maskSpecial |= tp.getMask(); - return bytesPassed; - } - - // Bingo, data contains this property - TextProp prop = tp.clone(); - int val = 0; - if (prop.getSize() == 2) { - val = LittleEndian.getShort(data,dataOffset+bytesPassed); - } else if(prop.getSize() == 4) { - val = LittleEndian.getInt(data,dataOffset+bytesPassed); - } else if (prop.getSize() == 0 && !(prop instanceof TabStopPropCollection)) { - //remember "special" bits. - maskSpecial |= tp.getMask(); - continue; - } - - if (prop instanceof BitMaskTextProp) { - ((BitMaskTextProp)prop).setValueWithMask(val, containsField); - } else if (prop instanceof TabStopPropCollection) { - ((TabStopPropCollection)prop).parseProperty(data, dataOffset+bytesPassed); - } else { - prop.setValue(val); - } - bytesPassed += prop.getSize(); - addProp(prop); - } - } - - // Return how many bytes were used - return bytesPassed; - } - - /** - * Clones the given text properties - */ - public void copy(TextPropCollection other) { - if (other == null) { - throw new HSLFException("trying to copy null TextPropCollection"); - } - if (this == other) return; - this.charactersCovered = other.charactersCovered; - this.indentLevel = other.indentLevel; - this.maskSpecial = other.maskSpecial; - this.textProps.clear(); - for (TextProp tp : other.textProps.values()) { - TextProp tpCopy = (tp instanceof BitMaskTextProp) - ? ((BitMaskTextProp)tp).cloneAll() - : tp.clone(); - addProp(tpCopy); - } - } - - /** - * Update the size of the text that this set of properties - * applies to - */ - public void updateTextSize(int textSize) { - charactersCovered = textSize; - } - - /** - * Writes out to disk the header, and then all the properties - */ - public void writeOut(OutputStream o) throws IOException { - writeOut(o, false); - } - - /** - * Writes out to disk the header, and then all the properties - */ - public void writeOut(OutputStream o, boolean isMasterStyle) throws IOException { - if (!isMasterStyle) { - // First goes the number of characters we affect - // MasterStyles don't have this field - StyleTextPropAtom.writeLittleEndian(charactersCovered,o); - } - - // Then we have the indentLevel field if it's a paragraph collection - if (textPropType == TextPropType.paragraph && indentLevel > -1) { - StyleTextPropAtom.writeLittleEndian(indentLevel, o); - } - - // Then the mask field - int mask = maskSpecial; - for (TextProp textProp : textProps.values()) { - mask |= textProp.getWriteMask(); - } - StyleTextPropAtom.writeLittleEndian(mask,o); - - // Then the contents of all the properties - for (TextProp textProp : getTextPropList()) { - int val = textProp.getValue(); - if (textProp instanceof BitMaskTextProp && textProp.getWriteMask() == 0) { - // don't add empty properties, as they can't be recognized while reading - continue; - } else if (textProp.getSize() == 2) { - StyleTextPropAtom.writeLittleEndian((short)val,o); - } else if (textProp.getSize() == 4) { - StyleTextPropAtom.writeLittleEndian(val,o); - } - } - } - - public short getIndentLevel(){ - return indentLevel; - } - - public void setIndentLevel(short indentLevel) { - if (textPropType == TextPropType.character) { - throw new RuntimeException("trying to set an indent on a character collection."); - } - this.indentLevel = indentLevel; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + charactersCovered; - result = prime * result + maskSpecial; - result = prime * result + indentLevel; - result = prime * result + ((textProps == null) ? 0 : textProps.hashCode()); - return result; - } - /** - * compares most properties apart of the covered characters length - */ - public boolean equals(Object other) { - if (this == other) return true; - if (other == null) return false; - if (getClass() != other.getClass()) return false; - - TextPropCollection o = (TextPropCollection)other; - if (o.maskSpecial != this.maskSpecial || o.indentLevel != this.indentLevel) { - return false; - } - - return textProps.equals(o.textProps); - } - - public String toString() { - StringBuilder out = new StringBuilder(); - out.append(" chars covered: " + getCharactersCovered()); - out.append(" special mask flags: 0x" + HexDump.toHex(getSpecialMask()) + "\n"); - if (textPropType == TextPropType.paragraph) { - out.append(" indent level: "+getIndentLevel()+"\n"); - } - for(TextProp p : getTextPropList()) { - out.append(" " + p.getName() + " = " + p.getValue() ); - out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n"); - if (p instanceof BitMaskTextProp) { - BitMaskTextProp bm = (BitMaskTextProp)p; - int i = 0; - for (String s : bm.getSubPropNames()) { - if (bm.getSubPropMatches()[i]) { - out.append(" " + s + " = " + bm.getSubValue(i) + "\n"); - } - i++; - } - } - } - - out.append(" bytes that would be written: \n"); - - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeOut(baos); - byte[] b = baos.toByteArray(); - out.append(HexDump.dump(b, 0, 0)); - } catch (IOException e ) { - LOG.log(POILogger.ERROR, "can't dump TextPropCollection", e); - } - - return out.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/WrapFlagsTextProp.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/WrapFlagsTextProp.java deleted file mode 100644 index eaacbff57..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/WrapFlagsTextProp.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.model.textproperties; - -public class WrapFlagsTextProp extends BitMaskTextProp { - public static final int CHAR_WRAP_IDX = 0; - public static final int WORD_WRAO_IDX = 1; - public static final int OVERFLOW_IDX = 2; - - public static final String NAME = "wrapFlags"; - - public WrapFlagsTextProp() { - super(2, 0xE0000, NAME, "charWrap", "wordWrap", "overflow"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java deleted file mode 100644 index e9dc5cd95..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * A container record that specifies information about animation information for a shape. - * - * @author Yegor Kozlov - */ -public final class AnimationInfo extends RecordContainer { - private byte[] _header; - - // Links to our more interesting children - private AnimationInfoAtom animationAtom; - - /** - * Set things up, and find our more interesting children - */ - protected AnimationInfo(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - // First child should be the ExMediaAtom - if(_children[0] instanceof AnimationInfoAtom) { - animationAtom = (AnimationInfoAtom)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a AnimationInfoAtom, was of type " + _children[0].getRecordType()); - } - } - - /** - * Create a new AnimationInfo, with blank fields - */ - public AnimationInfo() { - // Setup our header block - _header = new byte[8]; - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)getRecordType()); - - _children = new Record[1]; - _children[0] = animationAtom = new AnimationInfoAtom(); - } - - /** - * We are of type 4103 - */ - public long getRecordType() { return RecordTypes.AnimationInfo.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } - - /** - * Returns the AnimationInfo - */ - public AnimationInfoAtom getAnimationInfoAtom() { - return animationAtom; - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java deleted file mode 100644 index a2ed09c79..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java +++ /dev/null @@ -1,274 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * An atom record that specifies the animation information for a shape. - * - * @author Yegor Kozlov - */ -public final class AnimationInfoAtom extends RecordAtom { - - /** - * whether the animation plays in the reverse direction - */ - public static final int Reverse = 1; - /** - * whether the animation starts automatically - */ - public static final int Automatic = 4; - /** - * whether the animation has an associated sound - */ - public static final int Sound = 16; - /** - * whether all playing sounds are stopped when this animation begins - */ - public static final int StopSound = 64; - /** - * whether an associated sound, media or action verb is activated when the shape is clicked. - */ - public static final int Play = 256; - /** - * specifies that the animation, while playing, stops other slide show actions. - */ - public static final int Synchronous = 1024; - /** - * whether the shape is hidden while the animation is not playing - */ - public static final int Hide = 4096; - /** - * whether the background of the shape is animated - */ - public static final int AnimateBg = 16384; - - /** - * Record header. - */ - private byte[] _header; - - /** - * record data - */ - private byte[] _recdata; - - /** - * Constructs a brand new link related atom record. - */ - protected AnimationInfoAtom() { - _recdata = new byte[28]; - - _header = new byte[8]; - LittleEndian.putShort(_header, 0, (short)0x01); - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _recdata.length); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected AnimationInfoAtom(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the record data - _recdata = new byte[len-8]; - System.arraycopy(source,start+8,_recdata,0,len-8); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.AnimationInfoAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_recdata); - } - - /** - * A rgb structure that specifies a color for the dim effect after the animation is complete. - * - * @return color for the dim effect after the animation is complete - */ - public int getDimColor(){ - return LittleEndian.getInt(_recdata, 0); - } - - /** - * A rgb structure that specifies a color for the dim effect after the animation is complete. - * - * @param rgb color for the dim effect after the animation is complete - */ - public void setDimColor(int rgb){ - LittleEndian.putInt(_recdata, 0, rgb); - } - - /** - * A bit mask specifying options for displaying headers and footers - * - * @return A bit mask specifying options for displaying headers and footers - */ - public int getMask(){ - return LittleEndian.getInt(_recdata, 4); - } - - /** - * A bit mask specifying options for displaying video - * - * @param mask A bit mask specifying options for displaying video - */ - public void setMask(int mask){ - LittleEndian.putInt(_recdata, 4, mask); - } - - /** - * @param bit the bit to check - * @return whether the specified flag is set - */ - public boolean getFlag(int bit){ - return (getMask() & bit) != 0; - } - - /** - * @param bit the bit to set - * @param value whether the specified bit is set - */ - public void setFlag(int bit, boolean value){ - int mask = getMask(); - if(value) mask |= bit; - else mask &= ~bit; - setMask(mask); - } - - /** - * A 4-byte unsigned integer that specifies a reference to a sound - * in the SoundCollectionContainer record to locate the embedded audio - * - * @return reference to a sound - */ - public int getSoundIdRef(){ - return LittleEndian.getInt(_recdata, 8); - } - - /** - * A 4-byte unsigned integer that specifies a reference to a sound - * in the SoundCollectionContainer record to locate the embedded audio - * - * @param id reference to a sound - */ - public void setSoundIdRef(int id){ - LittleEndian.putInt(_recdata, 8, id); - } - - /** - * A signed integer that specifies the delay time, in milliseconds, before the animation starts to play. - * If {@link #Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored. - */ - public int getDelayTime(){ - return LittleEndian.getInt(_recdata, 12); - } - /** - * A signed integer that specifies the delay time, in milliseconds, before the animation starts to play. - * If {@link #Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored. - */ - public void setDelayTime(int id){ - LittleEndian.putInt(_recdata, 12, id); - } - - /** - * A signed integer that specifies the order of the animation in the slide. - * It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of - * the corresponding placeholder shape on the main master slide or title master slide. - * The value -1 SHOULD NOT <105> be used. - */ - public int getOrderID(){ - return LittleEndian.getInt(_recdata, 16); - } - - /** - * A signed integer that specifies the order of the animation in the slide. - * It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of - * the corresponding placeholder shape on the main master slide or title master slide. - * The value -1 SHOULD NOT <105> be used. - */ - public void setOrderID(int id){ - LittleEndian.putInt(_recdata, 16, id); - } - - /** - * An unsigned integer that specifies the number of slides that this animation continues playing. - * This field is utilized only in conjunction with media. - * The value 0xFFFFFFFF specifies that the animation plays for one slide. - */ - public int getSlideCount(){ - return LittleEndian.getInt(_recdata, 18); - } - - /** - * An unsigned integer that specifies the number of slides that this animation continues playing. - * This field is utilized only in conjunction with media. - * The value 0xFFFFFFFF specifies that the animation plays for one slide. - */ - public void setSlideCount(int id){ - LittleEndian.putInt(_recdata, 18, id); - } - - public String toString(){ - StringBuffer buf = new StringBuffer(); - buf.append("AnimationInfoAtom\n"); - buf.append("\tDimColor: " + getDimColor() + "\n"); - int mask = getMask(); - buf.append("\tMask: " + mask + ", 0x"+Integer.toHexString(mask)+"\n"); - buf.append("\t Reverse: " + getFlag(Reverse)+"\n"); - buf.append("\t Automatic: " + getFlag(Automatic)+"\n"); - buf.append("\t Sound: " + getFlag(Sound)+"\n"); - buf.append("\t StopSound: " + getFlag(StopSound)+"\n"); - buf.append("\t Play: " + getFlag(Play)+"\n"); - buf.append("\t Synchronous: " + getFlag(Synchronous)+"\n"); - buf.append("\t Hide: " + getFlag(Hide)+"\n"); - buf.append("\t AnimateBg: " + getFlag(AnimateBg)+"\n"); - buf.append("\tSoundIdRef: " + getSoundIdRef() + "\n"); - buf.append("\tDelayTime: " + getDelayTime() + "\n"); - buf.append("\tOrderID: " + getOrderID() + "\n"); - buf.append("\tSlideCount: " + getSlideCount() + "\n"); - return buf.toString(); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/BinaryTagDataBlob.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/BinaryTagDataBlob.java deleted file mode 100644 index 160e2bdbd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/BinaryTagDataBlob.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * If we come across a record we know has children of (potential) - * interest, but where the record itself is boring, but where other - * records may care about where this one lives, we create one - * of these. It allows us to get at the children, and track where on - * disk this is, but not much else. - * Anything done using this should quite quickly be transitioned to its - * own proper record class! - * - * @author Nick Burch - */ - -public final class BinaryTagDataBlob extends PositionDependentRecordContainer -{ - private byte[] _header; - private long _type; - - /** - * Create a new holder for a boring record with children, but with - * position dependent characteristics - */ - protected BinaryTagDataBlob(byte[] source, int start, int len) { - // Just grab the header, not the whole contents - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - _type = LittleEndian.getUShort(_header,2); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - } - - /** - * Return the value we were given at creation - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/CString.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/CString.java deleted file mode 100644 index 0115438d2..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/CString.java +++ /dev/null @@ -1,123 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - -/** - * A CString (type 4026). Holds a unicode string, and the first two bytes - * of the record header normally encode the count. Typically attached to - * some complex sequence of records, eg Commetns. - * - * @author Nick Burch - */ - -public final class CString extends RecordAtom { - private byte[] _header; - private static long _type = 4026l; - - /** The bytes that make up the text */ - private byte[] _text; - - /** Grabs the text. Never null */ - public String getText() { - return StringUtil.getFromUnicodeLE(_text); - } - - /** Updates the text in the Atom. */ - public void setText(String text) { - // Convert to little endian unicode - _text = new byte[text.length()*2]; - StringUtil.putUnicodeLE(text,_text,0); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header,4,_text.length); - } - - /** - * Grabs the count, from the first two bytes of the header. - * The meaning of the count is specific to the type of the parent record - */ - public int getOptions() { - return LittleEndian.getShort(_header); - } - - /** - * Sets the count - * The meaning of the count is specific to the type of the parent record - */ - public void setOptions(int count) { - LittleEndian.putShort(_header, 0, (short)count); - } - - /* *************** record code follows ********************** */ - - /** - * For the CStrubg Atom - */ - protected CString(byte[] source, int start, int len) { - // Sanity Checking - if(len < 8) { len = 8; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the text - _text = new byte[len-8]; - System.arraycopy(source,start+8,_text,0,len-8); - } - /** - * Create an empty CString - */ - public CString() { - // 0 length header - _header = new byte[] { 0, 0, 0xBA-256, 0x0f, 0, 0, 0, 0 }; - // Empty text - _text = new byte[0]; - } - - /** - * We are of type 4026 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - - // Write out our text - out.write(_text); - } - - /** - * Gets a string representation of this object, primarily for debugging. - * @return a string representation of this object. - */ - public String toString() { - return getText(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java deleted file mode 100644 index 9d14b7bff..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ColorSchemeAtom.java +++ /dev/null @@ -1,217 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; - -/** - * A ColorSchemeAtom (type 2032). Holds the 8 RGB values for the different - * colours of bits of text, that makes up a given colour scheme. - * Slides (presumably) link to a given colour scheme atom, and that - * defines the colours to be used - * - * @author Nick Burch - */ -public final class ColorSchemeAtom extends RecordAtom { - private byte[] _header; - private static long _type = 2032l; - - private int backgroundColourRGB; - private int textAndLinesColourRGB; - private int shadowsColourRGB; - private int titleTextColourRGB; - private int fillsColourRGB; - private int accentColourRGB; - private int accentAndHyperlinkColourRGB; - private int accentAndFollowingHyperlinkColourRGB; - - /** Fetch the RGB value for Background Colour */ - public int getBackgroundColourRGB() { return backgroundColourRGB; } - /** Set the RGB value for Background Colour */ - public void setBackgroundColourRGB(int rgb) { backgroundColourRGB = rgb; } - - /** Fetch the RGB value for Text And Lines Colour */ - public int getTextAndLinesColourRGB() { return textAndLinesColourRGB; } - /** Set the RGB value for Text And Lines Colour */ - public void setTextAndLinesColourRGB(int rgb) { textAndLinesColourRGB = rgb; } - - /** Fetch the RGB value for Shadows Colour */ - public int getShadowsColourRGB() { return shadowsColourRGB; } - /** Set the RGB value for Shadows Colour */ - public void setShadowsColourRGB(int rgb) { shadowsColourRGB = rgb; } - - /** Fetch the RGB value for Title Text Colour */ - public int getTitleTextColourRGB() { return titleTextColourRGB; } - /** Set the RGB value for Title Text Colour */ - public void setTitleTextColourRGB(int rgb) { titleTextColourRGB = rgb; } - - /** Fetch the RGB value for Fills Colour */ - public int getFillsColourRGB() { return fillsColourRGB; } - /** Set the RGB value for Fills Colour */ - public void setFillsColourRGB(int rgb) { fillsColourRGB = rgb; } - - /** Fetch the RGB value for Accent Colour */ - public int getAccentColourRGB() { return accentColourRGB; } - /** Set the RGB value for Accent Colour */ - public void setAccentColourRGB(int rgb) { accentColourRGB = rgb; } - - /** Fetch the RGB value for Accent And Hyperlink Colour */ - public int getAccentAndHyperlinkColourRGB() - { return accentAndHyperlinkColourRGB; } - /** Set the RGB value for Accent And Hyperlink Colour */ - public void setAccentAndHyperlinkColourRGB(int rgb) - { accentAndHyperlinkColourRGB = rgb; } - - /** Fetch the RGB value for Accent And Following Hyperlink Colour */ - public int getAccentAndFollowingHyperlinkColourRGB() - { return accentAndFollowingHyperlinkColourRGB; } - /** Set the RGB value for Accent And Following Hyperlink Colour */ - public void setAccentAndFollowingHyperlinkColourRGB(int rgb) - { accentAndFollowingHyperlinkColourRGB = rgb; } - - /* *************** record code follows ********************** */ - - /** - * For the Colour Scheme (ColorSchem) Atom - */ - protected ColorSchemeAtom(byte[] source, int start, int len) { - // Sanity Checking - we're always 40 bytes long - if(len < 40) { - len = 40; - if(source.length - start < 40) { - throw new RuntimeException("Not enough data to form a ColorSchemeAtom (always 40 bytes long) - found " + (source.length - start)); - } - } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the rgb values - backgroundColourRGB = LittleEndian.getInt(source,start+8+0); - textAndLinesColourRGB = LittleEndian.getInt(source,start+8+4); - shadowsColourRGB = LittleEndian.getInt(source,start+8+8); - titleTextColourRGB = LittleEndian.getInt(source,start+8+12); - fillsColourRGB = LittleEndian.getInt(source,start+8+16); - accentColourRGB = LittleEndian.getInt(source,start+8+20); - accentAndHyperlinkColourRGB = LittleEndian.getInt(source,start+8+24); - accentAndFollowingHyperlinkColourRGB = LittleEndian.getInt(source,start+8+28); - } - - /** - * Create a new ColorSchemeAtom, to go with a new Slide - */ - public ColorSchemeAtom(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 16); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 32); - - // Setup the default rgb values - backgroundColourRGB = 16777215; - textAndLinesColourRGB = 0; - shadowsColourRGB = 8421504; - titleTextColourRGB = 0; - fillsColourRGB = 10079232; - accentColourRGB = 13382451; - accentAndHyperlinkColourRGB = 16764108; - accentAndFollowingHyperlinkColourRGB = 11711154; - } - - - /** - * We are of type 3999 - */ - public long getRecordType() { return _type; } - - - /** - * Convert from an integer RGB value to individual R, G, B 0-255 values - */ - public static byte[] splitRGB(int rgb) { - byte[] ret = new byte[3]; - - // Serialise to bytes, then grab the right ones out - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - writeLittleEndian(rgb,baos); - } catch(IOException ie) { - // Should never happen - throw new RuntimeException(ie); - } - byte[] b = baos.toByteArray(); - System.arraycopy(b,0,ret,0,3); - - return ret; - } - - /** - * Convert from split R, G, B values to an integer RGB value - */ - public static int joinRGB(byte r, byte g, byte b) { - return joinRGB(new byte[] { r,g,b }); - } - /** - * Convert from split R, G, B values to an integer RGB value - */ - public static int joinRGB(byte[] rgb) { - if(rgb.length != 3) { - throw new RuntimeException("joinRGB accepts a byte array of 3 values, but got one of " + rgb.length + " values!"); - } - byte[] with_zero = new byte[4]; - System.arraycopy(rgb,0,with_zero,0,3); - with_zero[3] = 0; - int ret = LittleEndian.getInt(with_zero,0); - return ret; - } - - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - - // Write out the rgb values - writeLittleEndian(backgroundColourRGB,out); - writeLittleEndian(textAndLinesColourRGB,out); - writeLittleEndian(shadowsColourRGB,out); - writeLittleEndian(titleTextColourRGB,out); - writeLittleEndian(fillsColourRGB,out); - writeLittleEndian(accentColourRGB,out); - writeLittleEndian(accentAndHyperlinkColourRGB,out); - writeLittleEndian(accentAndFollowingHyperlinkColourRGB,out); - } - - /** - * Returns color by its index - * - * @param idx 0-based color index - * @return color by its index - */ - public int getColor(int idx){ - int[] clr = {backgroundColourRGB, textAndLinesColourRGB, shadowsColourRGB, titleTextColourRGB, - fillsColourRGB, accentColourRGB, accentAndHyperlinkColourRGB, accentAndFollowingHyperlinkColourRGB}; - return clr[idx]; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java deleted file mode 100644 index b64134b0d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java +++ /dev/null @@ -1,176 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * This class represents a comment on a slide, in the format used by - * PPT 2000/XP/etc. (PPT 97 uses plain Escher Text Boxes for comments) - * @author Nick Burch - */ -public final class Comment2000 extends RecordContainer { - private byte[] _header; - private static long _type = 12000; - - // Links to our more interesting children - - /** - * An optional string that specifies the name of the author of the presentation comment. - */ - private CString authorRecord; - /** - * An optional string record that specifies the text of the presentation comment - */ - private CString authorInitialsRecord; - /** - * An optional string record that specifies the initials of the author of the presentation comment - */ - private CString commentRecord; - - /** - * A Comment2000Atom record that specifies the settings for displaying the presentation comment - */ - private Comment2000Atom commentAtom; - - /** - * Returns the Comment2000Atom of this Comment - */ - public Comment2000Atom getComment2000Atom() { return commentAtom; } - - /** - * Get the Author of this comment - */ - public String getAuthor() { - return authorRecord == null ? null : authorRecord.getText(); - } - /** - * Set the Author of this comment - */ - public void setAuthor(String author) { - authorRecord.setText(author); - } - - /** - * Get the Author's Initials of this comment - */ - public String getAuthorInitials() { - return authorInitialsRecord == null ? null : authorInitialsRecord.getText(); - } - /** - * Set the Author's Initials of this comment - */ - public void setAuthorInitials(String initials) { - authorInitialsRecord.setText(initials); - } - - /** - * Get the text of this comment - */ - public String getText() { - return commentRecord == null ? null : commentRecord.getText(); - } - /** - * Set the text of this comment - */ - public void setText(String text) { - commentRecord.setText(text); - } - - /** - * Set things up, and find our more interesting children - */ - protected Comment2000(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - for(Record r : _children){ - if (r instanceof CString){ - CString cs = (CString)r; - int recInstance = cs.getOptions() >> 4; - switch(recInstance){ - case 0: authorRecord = cs; break; - case 1: commentRecord = cs; break; - case 2: authorInitialsRecord = cs; break; - default: break; - } - } else if (r instanceof Comment2000Atom){ - commentAtom = (Comment2000Atom)r; - } else { - logger.log(POILogger.WARN, "Unexpected record with type="+r.getRecordType()+" in Comment2000: " + r.getClass().getName()); - } - } - - } - - /** - * Create a new Comment2000, with blank fields - */ - public Comment2000() { - _header = new byte[8]; - _children = new Record[4]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)_type); - - // Setup our child records - CString csa = new CString(); - CString csb = new CString(); - CString csc = new CString(); - csa.setOptions(0x00); - csb.setOptions(0x10); - csc.setOptions(0x20); - _children[0] = csa; - _children[1] = csb; - _children[2] = csc; - _children[3] = new Comment2000Atom(); - findInterestingChildren(); - } - - /** - * We are of type 1200 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000Atom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000Atom.java deleted file mode 100644 index ab38e88d1..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000Atom.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Date; - -import org.apache.poi.hslf.util.SystemTimeUtils; -import org.apache.poi.util.LittleEndian; - -/** - * An atomic record containing information about a comment. - * - * @author Daniel Noll - */ - -public final class Comment2000Atom extends RecordAtom -{ - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new comment atom record. - */ - protected Comment2000Atom() { - _header = new byte[8]; - _data = new byte[28]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - - // It is fine for the other values to be zero - } - - /** - * Constructs the comment atom record from its source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected Comment2000Atom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - } - - /** - * Gets the comment number (note - each user normally has their own count). - * @return the comment number. - */ - public int getNumber() { - return LittleEndian.getInt(_data,0); - } - - /** - * Sets the comment number (note - each user normally has their own count). - * @param number the comment number. - */ - public void setNumber(int number) { - LittleEndian.putInt(_data,0,number); - } - - /** - * Gets the date the comment was made. - * @return the comment date. - */ - public Date getDate() { - return SystemTimeUtils.getDate(_data,4); - } - - /** - * Sets the date the comment was made. - * @param date the comment date. - */ - public void setDate(Date date) { - SystemTimeUtils.storeDate(date, _data, 4); - } - - /** - * Gets the X offset of the comment on the page. - * @return the X offset. - */ - public int getXOffset() { - return LittleEndian.getInt(_data,20); - } - - /** - * Sets the X offset of the comment on the page. - * @param xOffset the X offset. - */ - public void setXOffset(int xOffset) { - LittleEndian.putInt(_data,20,xOffset); - } - - /** - * Gets the Y offset of the comment on the page. - * @return the Y offset. - */ - public int getYOffset() { - return LittleEndian.getInt(_data,24); - } - - /** - * Sets the Y offset of the comment on the page. - * @param yOffset the Y offset. - */ - public void setYOffset(int yOffset) { - LittleEndian.putInt(_data,24,yOffset); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.Comment2000Atom.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java deleted file mode 100644 index 2d688603a..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java +++ /dev/null @@ -1,284 +0,0 @@ - -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; -import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentEntry; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; - -/** - * This is a special kind of Atom, because it doesn't live inside the - * PowerPoint document. Instead, it lives in a separate stream in the - * document. As such, it has to be treated specially - */ -public class CurrentUserAtom -{ - private static POILogger logger = POILogFactory.getLogger(CurrentUserAtom.class); - - /** Standard Atom header */ - public static final byte[] atomHeader = new byte[] { 0, 0, -10, 15 }; - /** The PowerPoint magic number for a non-encrypted file */ - public static final byte[] headerToken = new byte[] { 95, -64, -111, -29 }; - /** The PowerPoint magic number for an encrypted file */ - public static final byte[] encHeaderToken = new byte[] { -33, -60, -47, -13 }; - /** The Powerpoint 97 version, major and minor numbers */ - public static final byte[] ppt97FileVer = new byte[] { 8, 00, -13, 03, 03, 00 }; - - /** The version, major and minor numbers */ - private int docFinalVersion; - private byte docMajorNo; - private byte docMinorNo; - - /** The Offset into the file for the current edit */ - private long currentEditOffset; - /** The Username of the last person to edit the file */ - private String lastEditUser; - /** The document release version. Almost always 8 */ - private long releaseVersion; - - /** Only correct after reading in or writing out */ - private byte[] _contents; - - /** Flag for encryption state of the whole file */ - private boolean isEncrypted; - - - /* ********************* getter/setter follows *********************** */ - - public int getDocFinalVersion() { return docFinalVersion; } - public byte getDocMajorNo() { return docMajorNo; } - public byte getDocMinorNo() { return docMinorNo; } - - public long getReleaseVersion() { return releaseVersion; } - public void setReleaseVersion(long rv) { releaseVersion = rv; } - - /** Points to the UserEditAtom */ - public long getCurrentEditOffset() { return currentEditOffset; } - public void setCurrentEditOffset(long id ) { currentEditOffset = id; } - - public String getLastEditUsername() { return lastEditUser; } - public void setLastEditUsername(String u) { lastEditUser = u; } - - public boolean isEncrypted() { return isEncrypted; } - public void setEncrypted(boolean isEncrypted) { this.isEncrypted = isEncrypted; } - - - /* ********************* real code follows *************************** */ - - /** - * Create a new Current User Atom - */ - public CurrentUserAtom() { - _contents = new byte[0]; - - // Initialise to empty - docFinalVersion = 0x03f4; - docMajorNo = 3; - docMinorNo = 0; - releaseVersion = 8; - currentEditOffset = 0; - lastEditUser = "Apache POI"; - isEncrypted = false; - } - - - /** - * Find the Current User in the filesystem, and create from that - */ - public CurrentUserAtom(DirectoryNode dir) throws IOException { - // Decide how big it is - DocumentEntry docProps = - (DocumentEntry)dir.getEntry("Current User"); - - // If it's clearly junk, bail out - if(docProps.getSize() > 131072) { - throw new CorruptPowerPointFileException("The Current User stream is implausably long. It's normally 28-200 bytes long, but was " + docProps.getSize() + " bytes"); - } - - // Grab the contents - int len = docProps.getSize(); - _contents = new byte[len]; - InputStream in = dir.createDocumentInputStream("Current User"); - int readLen = in.read(_contents); - in.close(); - - if (len != readLen) { - throw new IOException("Current User input stream ended prematurely - expected "+len+" bytes - received "+readLen+" bytes"); - } - - - // See how long it is. If it's under 28 bytes long, we can't - // read it - if(_contents.length < 28) { - boolean isPP95 = dir.hasEntry("PP40"); - // PPT95 has 4 byte size, then data - if (!isPP95 && _contents.length >= 4) { - int size = LittleEndian.getInt(_contents); - isPP95 = (size + 4 == _contents.length); - } - - if (isPP95) { - throw new OldPowerPointFormatException("Based on the Current User stream, you seem to have supplied a PowerPoint95 file, which isn't supported"); - } else { - throw new CorruptPowerPointFileException("The Current User stream must be at least 28 bytes long, but was only " + _contents.length); - } - } - - // Set everything up - init(); - } - - /** - * Actually do the creation from a block of bytes - */ - private void init() { - // First up is the size, in 4 bytes, which is fixed - // Then is the header - - isEncrypted = (LittleEndian.getInt(encHeaderToken) == LittleEndian.getInt(_contents,12)); - - // Grab the edit offset - currentEditOffset = LittleEndian.getUInt(_contents,16); - - // Grab the versions - docFinalVersion = LittleEndian.getUShort(_contents,22); - docMajorNo = _contents[24]; - docMinorNo = _contents[25]; - - // Get the username length - long usernameLen = LittleEndian.getUShort(_contents,20); - if(usernameLen > 512) { - // Handle the case of it being garbage - logger.log(POILogger.WARN, "Warning - invalid username length " + usernameLen + " found, treating as if there was no username set"); - usernameLen = 0; - } - - // Now we know the length of the username, - // use this to grab the revision - if(_contents.length >= 28+(int)usernameLen + 4) { - releaseVersion = LittleEndian.getUInt(_contents,28+(int)usernameLen); - } else { - // No revision given, as not enough data. Odd - releaseVersion = 0; - } - - // Grab the unicode username, if stored - int start = 28+(int)usernameLen+4; - int len = 2*(int)usernameLen; - - if(_contents.length >= start+len) { - byte[] textBytes = new byte[len]; - System.arraycopy(_contents,start,textBytes,0,len); - lastEditUser = StringUtil.getFromUnicodeLE(textBytes); - } else { - // Fake from the 8 bit version - byte[] textBytes = new byte[(int)usernameLen]; - System.arraycopy(_contents,28,textBytes,0,(int)usernameLen); - lastEditUser = StringUtil.getFromCompressedUnicode(textBytes,0,(int)usernameLen); - } - } - - - /** - * Writes ourselves back out - */ - public void writeOut(OutputStream out) throws IOException { - // Decide on the size - // 8 = atom header - // 20 = up to name - // 4 = revision - // 3 * len = ascii + unicode - int size = 8 + 20 + 4 + (3 * lastEditUser.length()); - _contents = new byte[size]; - - // First we have a 8 byte atom header - System.arraycopy(atomHeader,0,_contents,0,4); - // Size is 20+user len + revision len(4) - int atomSize = 20+4+lastEditUser.length(); - LittleEndian.putInt(_contents,4,atomSize); - - // Now we have the size of the details, which is 20 - LittleEndian.putInt(_contents,8,20); - - // Now the ppt un-encrypted header token (4 bytes) - System.arraycopy((isEncrypted ? encHeaderToken : headerToken),0,_contents,12,4); - - // Now the current edit offset - LittleEndian.putInt(_contents,16,(int)currentEditOffset); - - // The username gets stored twice, once as US - // ascii, and again as unicode laster on - byte[] asciiUN = new byte[lastEditUser.length()]; - StringUtil.putCompressedUnicode(lastEditUser,asciiUN,0); - - // Now we're able to do the length of the last edited user - LittleEndian.putShort(_contents,20,(short)asciiUN.length); - - // Now the file versions, 2+1+1 - LittleEndian.putShort(_contents,22,(short)docFinalVersion); - _contents[24] = docMajorNo; - _contents[25] = docMinorNo; - - // 2 bytes blank - _contents[26] = 0; - _contents[27] = 0; - - // At this point we have the username as us ascii - System.arraycopy(asciiUN,0,_contents,28,asciiUN.length); - - // 4 byte release version - LittleEndian.putInt(_contents,28+asciiUN.length,(int)releaseVersion); - - // username in unicode - byte [] ucUN = new byte[lastEditUser.length()*2]; - StringUtil.putUnicodeLE(lastEditUser,ucUN,0); - System.arraycopy(ucUN,0,_contents,28+asciiUN.length+4,ucUN.length); - - // Write out - out.write(_contents); - } - - /** - * Writes ourselves back out to a filesystem - */ - public void writeToFS(NPOIFSFileSystem fs) throws IOException { - // Grab contents - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeOut(baos); - ByteArrayInputStream bais = - new ByteArrayInputStream(baos.toByteArray()); - - // Write out - fs.createOrUpdateDocument(bais,"Current User"); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java deleted file mode 100644 index eed1de23f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * A container record that specifies information about the document and document display settings. - */ -public final class DocInfoListContainer extends RecordContainer { - private byte[] _header; - private static long _type = RecordTypes.List.typeID; - - // Links to our more interesting children - - /** - * Set things up, and find our more interesting children - */ - protected DocInfoListContainer(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - } - - /** - * Create a new DocInfoListContainer, with blank fields - not yet supported - */ - private DocInfoListContainer() { - _header = new byte[8]; - _children = new Record[0]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)_type); - - // Setup our child records - findInterestingChildren(); - } - - /** - * We are of type 0x7D0 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Document.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Document.java deleted file mode 100644 index 0c74ae2b4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Document.java +++ /dev/null @@ -1,231 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.POILogger; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; - -/** - * Master container for Document. There is one of these for every - * slideshow, and it holds lots of definitions, and some summaries. - * - * @author Nick Burch - */ - -public final class Document extends PositionDependentRecordContainer -{ - private byte[] _header; - private static long _type = 1000; - - // Links to our more interesting children - private DocumentAtom documentAtom; - private Environment environment; - private PPDrawingGroup ppDrawing; - private SlideListWithText[] slwts; - private ExObjList exObjList; // Can be null - - /** - * Returns the DocumentAtom of this Document - */ - public DocumentAtom getDocumentAtom() { return documentAtom; } - - /** - * Returns the Environment of this Notes, which lots of - * settings for the document in it - */ - public Environment getEnvironment() { return environment; } - - /** - * Returns the PPDrawingGroup, which holds an Escher Structure - * that contains information on pictures in the slides. - */ - public PPDrawingGroup getPPDrawingGroup() { return ppDrawing; } - - /** - * Returns the ExObjList, which holds the references to - * external objects used in the slides. This may be null, if - * there are no external references. - * - * @param create if true, create an ExObjList if it doesn't exist - */ - public ExObjList getExObjList(boolean create) { - if (exObjList == null && create) { - exObjList = new ExObjList(); - addChildAfter(exObjList, getDocumentAtom()); - } - return exObjList; - } - - /** - * Returns all the SlideListWithTexts that are defined for - * this Document. They hold the text, and some of the text - * properties, which are referred to by the slides. - * This will normally return an array of size 2 or 3 - */ - public SlideListWithText[] getSlideListWithTexts() { return slwts; } - - /** - * Returns the SlideListWithText that deals with the - * Master Slides - */ - public SlideListWithText getMasterSlideListWithText() { - for (int i = 0; i < slwts.length; i++) { - if(slwts[i].getInstance() == SlideListWithText.MASTER) { - return slwts[i]; - } - } - return null; - } - - /** - * Returns the SlideListWithText that deals with the - * Slides, or null if there isn't one - */ - public SlideListWithText getSlideSlideListWithText() { - for (int i = 0; i < slwts.length; i++) { - if(slwts[i].getInstance() == SlideListWithText.SLIDES) { - return slwts[i]; - } - } - return null; - } - /** - * Returns the SlideListWithText that deals with the - * notes, or null if there isn't one - */ - public SlideListWithText getNotesSlideListWithText() { - for (int i = 0; i < slwts.length; i++) { - if(slwts[i].getInstance() == SlideListWithText.NOTES) { - return slwts[i]; - } - } - return null; - } - - - /** - * Set things up, and find our more interesting children - */ - protected Document(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - - // Our first one should be a document atom - if(! (_children[0] instanceof DocumentAtom)) { - throw new IllegalStateException("The first child of a Document must be a DocumentAtom"); - } - documentAtom = (DocumentAtom)_children[0]; - - // Find how many SlideListWithTexts we have - // Also, grab the Environment and PPDrawing records - // on our way past - int slwtcount = 0; - for(int i=1; i<_children.length; i++) { - if(_children[i] instanceof SlideListWithText) { - slwtcount++; - } - if(_children[i] instanceof Environment) { - environment = (Environment)_children[i]; - } - if(_children[i] instanceof PPDrawingGroup) { - ppDrawing = (PPDrawingGroup)_children[i]; - } - if(_children[i] instanceof ExObjList) { - exObjList = (ExObjList)_children[i]; - } - } - - // You should only every have 1, 2 or 3 SLWTs - // (normally it's 2, or 3 if you have notes) - // Complain if it's not - if(slwtcount == 0) { - logger.log(POILogger.WARN, "No SlideListWithText's found - there should normally be at least one!"); - } - if(slwtcount > 3) { - logger.log(POILogger.WARN, "Found " + slwtcount + " SlideListWithTexts - normally there should only be three!"); - } - - // Now grab all the SLWTs - slwts = new SlideListWithText[slwtcount]; - slwtcount = 0; - for(int i=1; i<_children.length; i++) { - if(_children[i] instanceof SlideListWithText) { - slwts[slwtcount] = (SlideListWithText)_children[i]; - slwtcount++; - } - } - } - - /** - * Adds a new SlideListWithText record, at the appropriate - * point in the child records. - */ - public void addSlideListWithText(SlideListWithText slwt) { - // The new SlideListWithText should go in - // just before the EndDocumentRecord - Record endDoc = _children[_children.length - 1]; - if(endDoc.getRecordType() == RecordTypes.RoundTripCustomTableStyles12Atom.typeID) { - // last record can optionally be a RoundTripCustomTableStyles12Atom - endDoc = _children[_children.length - 2]; - } - if(endDoc.getRecordType() != RecordTypes.EndDocument.typeID) { - throw new IllegalStateException("The last child record of a Document should be EndDocument, but it was " + endDoc); - } - - // Add in the record - addChildBefore(slwt, endDoc); - - // Updated our cached list of SlideListWithText records - int newSize = slwts.length + 1; - SlideListWithText[] nl = new SlideListWithText[newSize]; - System.arraycopy(slwts, 0, nl, 0, slwts.length); - nl[nl.length-1] = slwt; - slwts = nl; - } - - public void removeSlideListWithText(SlideListWithText slwt) { - ArrayList lst = new ArrayList(); - for(SlideListWithText s : slwts) { - if(s != slwt) lst.add(s); - else { - removeChild(slwt); - } - } - slwts = lst.toArray(new SlideListWithText[lst.size()]); - } - - /** - * We are of type 1000 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocumentAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocumentAtom.java deleted file mode 100644 index 22a9b7c3e..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocumentAtom.java +++ /dev/null @@ -1,197 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A Document Atom (type 1001). Holds misc information on the PowerPoint - * document, lots of them size and scale related. - * - * @author Nick Burch - */ - -public final class DocumentAtom extends RecordAtom -{ - private byte[] _header; - private static long _type = 1001l; - - private long slideSizeX; // PointAtom, assume 1st 4 bytes = X - private long slideSizeY; // PointAtom, assume 2nd 4 bytes = Y - private long notesSizeX; // PointAtom, assume 1st 4 bytes = X - private long notesSizeY; // PointAtom, assume 2nd 4 bytes = Y - private long serverZoomFrom; // RatioAtom, assume 1st 4 bytes = from - private long serverZoomTo; // RatioAtom, assume 2nd 4 bytes = to - - private long notesMasterPersist; // ref to NotesMaster, 0 if none - private long handoutMasterPersist; // ref to HandoutMaster, 0 if none - - private int firstSlideNum; - private int slideSizeType; // see DocumentAtom.SlideSize - - private byte saveWithFonts; - private byte omitTitlePlace; - private byte rightToLeft; - private byte showComments; - - private byte[] reserved; - - - public long getSlideSizeX() { return slideSizeX; } - public long getSlideSizeY() { return slideSizeY; } - public long getNotesSizeX() { return notesSizeX; } - public long getNotesSizeY() { return notesSizeY; } - public void setSlideSizeX(long x) { slideSizeX = x; } - public void setSlideSizeY(long y) { slideSizeY = y; } - public void setNotesSizeX(long x) { notesSizeX = x; } - public void setNotesSizeY(long y) { notesSizeY = y; } - - public long getServerZoomFrom() { return serverZoomFrom; } - public long getServerZoomTo() { return serverZoomTo; } - public void setServerZoomFrom(long zoom) { serverZoomFrom = zoom; } - public void setServerZoomTo(long zoom) { serverZoomTo = zoom; } - - /** Returns a reference to the NotesMaster, or 0 if none */ - public long getNotesMasterPersist() { return notesMasterPersist; } - /** Returns a reference to the HandoutMaster, or 0 if none */ - public long getHandoutMasterPersist() { return handoutMasterPersist; } - - public int getFirstSlideNum() { return firstSlideNum; } - - /** The Size of the Document's slides, @see DocumentAtom.SlideSize for values */ - public int getSlideSizeType() { return slideSizeType; } - - /** Was the document saved with True Type fonts embeded? */ - public boolean getSaveWithFonts() { - return saveWithFonts != 0; - } - - /** Have the placeholders on the title slide been omitted? */ - public boolean getOmitTitlePlace() { - return omitTitlePlace != 0; - } - - /** Is this a Bi-Directional PPT Doc? */ - public boolean getRightToLeft() { - return rightToLeft != 0; - } - - /** Are comment shapes visible? */ - public boolean getShowComments() { - return showComments != 0; - } - - - /* *************** record code follows ********************** */ - - /** - * For the Document Atom - */ - protected DocumentAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 48) { len = 48; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the sizes and zoom ratios - slideSizeX = LittleEndian.getInt(source,start+0+8); - slideSizeY = LittleEndian.getInt(source,start+4+8); - notesSizeX = LittleEndian.getInt(source,start+8+8); - notesSizeY = LittleEndian.getInt(source,start+12+8); - serverZoomFrom = LittleEndian.getInt(source,start+16+8); - serverZoomTo = LittleEndian.getInt(source,start+20+8); - - // Get the master persists - notesMasterPersist = LittleEndian.getInt(source,start+24+8); - handoutMasterPersist = LittleEndian.getInt(source,start+28+8); - - // Get the ID of the first slide - firstSlideNum = LittleEndian.getShort(source,start+32+8); - - // Get the slide size type - slideSizeType = LittleEndian.getShort(source,start+34+8); - - // Get the booleans as bytes - saveWithFonts = source[start+36+8]; - omitTitlePlace = source[start+37+8]; - rightToLeft = source[start+38+8]; - showComments = source[start+39+8]; - - // If there's any other bits of data, keep them about - reserved = new byte[len-40-8]; - System.arraycopy(source,start+48,reserved,0,reserved.length); - } - - /** - * We are of type 1001 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - out.write(_header); - - // The sizes and zoom ratios - writeLittleEndian((int)slideSizeX,out); - writeLittleEndian((int)slideSizeY,out); - writeLittleEndian((int)notesSizeX,out); - writeLittleEndian((int)notesSizeY,out); - writeLittleEndian((int)serverZoomFrom,out); - writeLittleEndian((int)serverZoomTo,out); - - // The master persists - writeLittleEndian((int)notesMasterPersist,out); - writeLittleEndian((int)handoutMasterPersist,out); - - // The ID of the first slide - writeLittleEndian((short)firstSlideNum,out); - - // The slide size type - writeLittleEndian((short)slideSizeType,out); - - // The booleans as bytes - out.write(saveWithFonts); - out.write(omitTitlePlace); - out.write(rightToLeft); - out.write(showComments); - - // Reserved data - out.write(reserved); - } - - /** - * Holds the different Slide Size values - */ - public static final class SlideSize { - public static final int ON_SCREEN = 0; - public static final int LETTER_SIZED_PAPER = 1; - public static final int A4_SIZED_PAPER = 2; - public static final int ON_35MM = 3; - public static final int OVERHEAD = 4; - public static final int BANNER = 5; - public static final int CUSTOM = 6; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocumentEncryptionAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocumentEncryptionAtom.java deleted file mode 100644 index 57f0f31ed..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DocumentEncryptionAtom.java +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Map; - -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionMode; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptionHeader; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptionVerifier; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianInputStream; - -/** - * A Document Encryption Atom (type 12052). Holds information - * on the Encryption of a Document - * - * @author Nick Burch - */ -public final class DocumentEncryptionAtom extends PositionDependentRecordAtom { - private static final long _type = 12052l; - private final byte[] _header; - private EncryptionInfo ei; - - /** - * For the Document Encryption Atom - */ - protected DocumentEncryptionAtom(byte[] source, int start, int len) throws IOException { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - ByteArrayInputStream bis = new ByteArrayInputStream(source, start+8, len-8); - LittleEndianInputStream leis = new LittleEndianInputStream(bis); - ei = new EncryptionInfo(leis, EncryptionMode.cryptoAPI); - leis.close(); - } - - public DocumentEncryptionAtom() { - _header = new byte[8]; - LittleEndian.putShort(_header, 0, (short)0x000F); - LittleEndian.putShort(_header, 2, (short)_type); - // record length not yet known ... - - ei = new EncryptionInfo(EncryptionMode.cryptoAPI); - } - - /** - * Initializes the encryption settings - * - * @param keyBits see {@link CipherAlgorithm#rc4} for allowed values, use -1 for default size - */ - public void initializeEncryptionInfo(int keyBits) { - ei = new EncryptionInfo(EncryptionMode.cryptoAPI, CipherAlgorithm.rc4, HashAlgorithm.sha1, keyBits, -1, null); - } - - /** - * Return the length of the encryption key, in bits - */ - public int getKeyLength() { - return ei.getHeader().getKeySize(); - } - - /** - * Return the name of the encryption provider used - */ - public String getEncryptionProviderName() { - return ei.getHeader().getCspName(); - } - - /** - * @return the {@link EncryptionInfo} object for details about encryption settings - */ - public EncryptionInfo getEncryptionInfo() { - return ei; - } - - - /** - * We are of type 12052 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - - // Data - byte data[] = new byte[1024]; - LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(data, 0); - bos.writeShort(ei.getVersionMajor()); - bos.writeShort(ei.getVersionMinor()); - bos.writeInt(ei.getEncryptionFlags()); - - ((CryptoAPIEncryptionHeader)ei.getHeader()).write(bos); - ((CryptoAPIEncryptionVerifier)ei.getVerifier()).write(bos); - - // Header - LittleEndian.putInt(_header, 4, bos.getWriteIndex()); - out.write(_header); - out.write(data, 0, bos.getWriteIndex()); - bos.close(); - } - - @Override - public void updateOtherRecordReferences(Map oldToNewReferencesLookup) { - // nothing to update - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java deleted file mode 100644 index 285f824b4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DummyPositionSensitiveRecordWithChildren.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * If we come across a record we know has children of (potential) - * interest, but where the record itself is boring, but where other - * records may care about where this one lives, we create one - * of these. It allows us to get at the children, and track where on - * disk this is, but not much else. - * Anything done using this should quite quickly be transitioned to its - * own proper record class! - * - * @author Nick Burch - */ - -public final class DummyPositionSensitiveRecordWithChildren extends PositionDependentRecordContainer -{ - private byte[] _header; - private long _type; - - /** - * Create a new holder for a boring record with children, but with - * position dependent characteristics - */ - protected DummyPositionSensitiveRecordWithChildren(byte[] source, int start, int len) { - // Just grab the header, not the whole contents - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - _type = LittleEndian.getUShort(_header,2); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - } - - /** - * Return the value we were given at creation - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DummyRecordWithChildren.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DummyRecordWithChildren.java deleted file mode 100644 index 18dea5892..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/DummyRecordWithChildren.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * If we come across a record we know has children of (potential) - * interest, but where the record itself is boring, we create one - * of these. It allows us to get at the children, but not much else - * - * @author Nick Burch - */ - -public final class DummyRecordWithChildren extends RecordContainer -{ - private byte[] _header; - private long _type; - - /** - * Create a new holder for a boring record with children - */ - protected DummyRecordWithChildren(byte[] source, int start, int len) { - // Just grab the header, not the whole contents - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - _type = LittleEndian.getUShort(_header,2); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - } - - /** - * Return the value we were given at creation - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java deleted file mode 100644 index eb66f2a28..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Environment.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Environment, which contains lots of settings for the document. - * - * @author Nick Burch - */ - -public final class Environment extends PositionDependentRecordContainer -{ - private byte[] _header; - private static long _type = 1010; - - // Links to our more interesting children - private FontCollection fontCollection; - //master style for text with type=TextHeaderAtom.OTHER_TYPE - private TxMasterStyleAtom txmaster; - - /** - * Returns the FontCollection of this Environment - */ - public FontCollection getFontCollection() { return fontCollection; } - - - /** - * Set things up, and find our more interesting children - */ - protected Environment(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - - // Find our FontCollection record - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof FontCollection) { - fontCollection = (FontCollection)_children[i]; - } else if (_children[i] instanceof TxMasterStyleAtom){ - txmaster = (TxMasterStyleAtom)_children[i]; - } - } - - if(fontCollection == null) { - throw new IllegalStateException("Environment didn't contain a FontCollection record!"); - } - } - - public TxMasterStyleAtom getTxMasterStyleAtom(){ - return txmaster; - } - - /** - * We are of type 1010 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java deleted file mode 100644 index 6aa09b936..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.ddf.*; -import org.apache.poi.util.*; - -/** - * An atom record that specifies whether a shape is a placeholder shape. - * The number, position, and type of placeholder shapes are determined by - * the slide layout as specified in the SlideAtom record. - */ -public class EscherPlaceholder extends EscherRecord { - public static final short RECORD_ID = (short)RecordTypes.OEPlaceholderAtom.typeID; - public static final String RECORD_DESCRIPTION = "msofbtClientTextboxPlaceholder"; - - int position = -1; - byte placementId = 0; - byte size = 0; - short unused = 0; - - public EscherPlaceholder() {} - - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - - position = LittleEndian.getInt(data, offset+8); - placementId = data[offset+12]; - size = data[offset+13]; - unused = LittleEndian.getShort(data, offset+14); - - assert(bytesRemaining + 8 == 16); - return bytesRemaining + 8; - } - - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort(data, offset, getOptions()); - LittleEndian.putShort(data, offset+2, getRecordId()); - LittleEndian.putInt(data, offset+4, 8); - LittleEndian.putInt(data, offset+8, position); - LittleEndian.putByte(data, offset+12, placementId); - LittleEndian.putByte(data, offset+13, size); - LittleEndian.putShort(data, offset+14, unused); - - listener.afterRecordSerialize( offset+getRecordSize(), getRecordId(), getRecordSize(), this ); - return getRecordSize(); - } - - public int getRecordSize() { - return 8 + 8; - } - - public String getRecordName() { - return "ClientTextboxPlaceholder"; - } - - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java deleted file mode 100644 index 10744e49d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.ddf.*; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; - -/** - * A wrapper around a DDF (Escher) EscherTextbox Record. Causes the DDF - * Record to be accessible as if it were a HSLF record. - * Note: when asked to write out, will simply put any child records correctly - * into the Escher layer. A call to the escher layer to write out (by the - * parent PPDrawing) will do the actual write out - * - * @author Nick Burch - */ -public final class EscherTextboxWrapper extends RecordContainer { - private EscherTextboxRecord _escherRecord; - private long _type; - private int shapeId; - private StyleTextPropAtom styleTextPropAtom; - private StyleTextProp9Atom styleTextProp9Atom; - - /** - * Returns the underlying DDF Escher Record - */ - public EscherTextboxRecord getEscherRecord() { return _escherRecord; } - - /** - * Creates the wrapper for the given DDF Escher Record and children - */ - public EscherTextboxWrapper(EscherTextboxRecord textbox) { - _escherRecord = textbox; - _type = _escherRecord.getRecordId(); - - // Find the child records in the escher data - byte[] data = _escherRecord.getData(); - _children = Record.findChildRecords(data,0,data.length); - for (Record r : this._children) { - if (r instanceof StyleTextPropAtom) { this.styleTextPropAtom = (StyleTextPropAtom) r; } - } - } - - /** - * Creates a new, empty wrapper for DDF Escher Records and their children - */ - public EscherTextboxWrapper() { - _escherRecord = new EscherTextboxRecord(); - _escherRecord.setRecordId(EscherTextboxRecord.RECORD_ID); - _escherRecord.setOptions((short)15); - - _children = new Record[0]; - } - - - /** - * Return the type of the escher record (normally in the 0xFnnn range) - */ - public long getRecordType() { return _type; } - - /** - * Stores the data for the child records back into the Escher layer. - * Doesn't actually do the writing out, that's left to the Escher - * layer to do. Must be called before writeOut/serialize is called - * on the underlying Escher object! - */ - public void writeOut(OutputStream out) throws IOException { - // Write out our children, and stuff them into the Escher layer - - // Grab the children's data - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (Record r : _children) r.writeOut(baos); - byte[] data = baos.toByteArray(); - - // Save in the escher layer - _escherRecord.setData(data); - } - - /** - * @return Shape ID - */ - public int getShapeId(){ - return shapeId; - } - - /** - * @param id Shape ID - */ - public void setShapeId(int id){ - shapeId = id; - } - - public StyleTextPropAtom getStyleTextPropAtom() { - return styleTextPropAtom; - } - - public void setStyleTextProp9Atom(final StyleTextProp9Atom nineAtom) { - this.styleTextProp9Atom = nineAtom; - } - public StyleTextProp9Atom getStyleTextProp9Atom() { - return this.styleTextProp9Atom; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExAviMovie.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExAviMovie.java deleted file mode 100644 index 62a5c4bbe..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExAviMovie.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - - -/** - * A container record that specifies information about a movie stored externally. - * - * @author Yegor Kozlov - */ -public final class ExAviMovie extends ExMCIMovie { - - /** - * Set things up, and find our more interesting children - */ - protected ExAviMovie(byte[] source, int start, int len) { - super(source, start, len); - } - - /** - * Create a new ExAviMovie, with blank fields - */ - public ExAviMovie() { - super(); - - } - /** - * We are of type 4102 - */ - public long getRecordType() { - return RecordTypes.ExAviMovie.typeID; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java deleted file mode 100644 index 2b0d1e2c3..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - - -/** - * A container record that specifies information about an ActiveX control. It contains: - *

        - * 1. ExControlAtom (4091) - * 2. ExOleObjAtom (4035) - * 3. CString (4026), Instance MenuName (1) used for menus and the Links dialog box. - * 4. CString (4026), Instance ProgID (2) that stores the OLE Programmatic Identifier. - * A ProgID is a string that uniquely identifies a given object. - * 5. CString (4026), Instance ClipboardName (3) that appears in the paste special dialog. - * 6. MetaFile( 4033), optional - *

        - * - * - * @author Yegor kozlov - */ -public final class ExControl extends ExEmbed { - - /** - * Set things up, and find our more interesting children - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExControl(byte[] source, int start, int len) { - super(source, start, len); - } - - /** - * Create a new ExEmbed, with blank fields - */ - public ExControl() { - super(); - - _children[0] = embedAtom = new ExControlAtom(); - } - - /** - * Gets the {@link ExControlAtom}. - * - * @return the {@link ExControlAtom}. - */ - public ExControlAtom getExControlAtom() - { - return (ExControlAtom)_children[0]; - } - - /** - * Returns the type (held as a little endian in bytes 3 and 4) - * that this class handles. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.ExControl.typeID; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java deleted file mode 100644 index b5540cee5..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * An atom record that specifies an ActiveX control. - * - * @author Yegor Kozlov - */ -public final class ExControlAtom extends RecordAtom { - - - /** - * Record header. - */ - private byte[] _header; - - /** - * slideId. - */ - private int _id; - - /** - * Constructs a brand new embedded object atom record. - */ - protected ExControlAtom() { - _header = new byte[8]; - - LittleEndian.putShort(_header, 2, (short) getRecordType()); - LittleEndian.putInt(_header, 4, 4); - - } - - /** - * Constructs the ExControlAtom record from its source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExControlAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source, start, _header, 0, 8); - - _id = LittleEndian.getInt(source, start + 8); - } - - /** - * An integer that specifies which presentation slide is associated with the ActiveX control. - *

        - * It MUST be 0x00000000 or equal to the value of the slideId field of a SlidePersistAtom record. - * The value 0x00000000 specifies a null reference. - *

        - * - * @return an integer that specifies which presentation slide is associated with the ActiveX control - */ - public int getSlideId() { - return _id; - } - - /** - * Sets which presentation slide is associated with the ActiveX control. - * - * @param id an integer that specifies which presentation slide is associated with the ActiveX control - *

        - * It MUST be 0x00000000 or equal to the value of the slideId field of a SlidePersistAtom record. - * The value 0x00000000 specifies a null reference. - *

        - */ - public void setSlideId(int id) { - _id = id; - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.ExControlAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - byte[] data = new byte[4]; - LittleEndian.putInt(data, 0, _id); - out.write(data); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java deleted file mode 100644 index 7580450cd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java +++ /dev/null @@ -1,205 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.OutputStream; -import java.io.IOException; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * This data represents an embedded object in the document. - * - * @author Daniel Noll - */ -public class ExEmbed extends RecordContainer { - - /** - * Record header data. - */ - private byte[] _header; - - // Links to our more interesting children - protected RecordAtom embedAtom; - private ExOleObjAtom oleObjAtom; - private CString menuName; - private CString progId; - private CString clipboardName; - - /** - * Set things up, and find our more interesting children - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExEmbed(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Create a new ExEmbed, with blank fields - */ - public ExEmbed() { - _header = new byte[8]; - _children = new Record[5]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)getRecordType()); - - // Setup our child records - CString cs1 = new CString(); - cs1.setOptions(0x1 << 4); - CString cs2 = new CString(); - cs2.setOptions(0x2 << 4); - CString cs3 = new CString(); - cs3.setOptions(0x3 << 4); - _children[0] = new ExEmbedAtom(); - _children[1] = new ExOleObjAtom(); - _children[2] = cs1; - _children[3] = cs2; - _children[4] = cs3; - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper methods. - */ - private void findInterestingChildren() { - - // First child should be the ExHyperlinkAtom - if(_children[0] instanceof ExEmbedAtom) { - embedAtom = (ExEmbedAtom)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType()); - } - - // Second child should be the ExOleObjAtom - if (_children[1] instanceof ExOleObjAtom) { - oleObjAtom = (ExOleObjAtom)_children[1]; - } else { - logger.log(POILogger.ERROR, "Second child record wasn't a ExOleObjAtom, was of type " + _children[1].getRecordType()); - } - - for (int i = 2; i < _children.length; i++) { - if (_children[i] instanceof CString){ - CString cs = (CString)_children[i]; - int opts = cs.getOptions() >> 4; - switch(opts){ - case 0x1: menuName = cs; break; - case 0x2: progId = cs; break; - case 0x3: clipboardName = cs; break; - default: break; - } - } - } - } - - /** - * Gets the {@link ExEmbedAtom}. - * - * @return the {@link ExEmbedAtom}. - */ - public ExEmbedAtom getExEmbedAtom() - { - return (ExEmbedAtom)embedAtom; - } - - /** - * Gets the {@link ExOleObjAtom}. - * - * @return the {@link ExOleObjAtom}. - */ - public ExOleObjAtom getExOleObjAtom() - { - return oleObjAtom; - } - - /** - * Gets the name used for menus and the Links dialog box. - * - * @return the name used for menus and the Links dialog box. - */ - public String getMenuName() - { - return menuName == null ? null : menuName.getText(); - } - - public void setMenuName(String s) - { - if(menuName != null) menuName.setText(s); - } - - /** - * Gets the OLE Programmatic Identifier. - * - * @return the OLE Programmatic Identifier. - */ - public String getProgId() - { - return progId == null ? null : progId.getText(); - } - - public void setProgId(String s) - { - if(progId != null) progId.setText(s); - } - /** - * Gets the name that appears in the paste special dialog. - * - * @return the name that appears in the paste special dialog. - */ - public String getClipboardName() - { - return clipboardName == null ? null : clipboardName.getText(); - } - - public void setClipboardName(String s) - { - if(clipboardName != null) clipboardName.setText(s); - } - /** - * Returns the type (held as a little endian in bytes 3 and 4) - * that this class handles. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.ExEmbed.typeID; - } - - /** - * Have the contents printer out into an OutputStream, used when - * writing a file back out to disk. - * - * @param out the output stream. - * @throws IOException if there was an error writing to the stream. - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java deleted file mode 100644 index 94aba471d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java +++ /dev/null @@ -1,165 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * The atom that holds metadata on a specific embedded object in the document. - * - * - * - * @author Daniel Noll - */ -public class ExEmbedAtom extends RecordAtom { - - /** - * Embedded document does not follow the color scheme. - */ - public static final int DOES_NOT_FOLLOW_COLOR_SCHEME = 0; - - /** - * Embedded document follows the entire color scheme. - */ - public static final int FOLLOWS_ENTIRE_COLOR_SCHEME = 1; - - /** - * Embedded document follows the text and background scheme. - */ - public static final int FOLLOWS_TEXT_AND_BACKGROUND_SCHEME = 2; - - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new embedded object atom record. - */ - protected ExEmbedAtom() { - _header = new byte[8]; - _data = new byte[8]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - - // It is fine for the other values to be zero - } - - /** - * Constructs the embedded object atom record from its source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExEmbedAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - // Must be at least 8 bytes long - if(_data.length < 8) { - throw new IllegalArgumentException("The length of the data for a ExEmbedAtom must be at least 4 bytes, but was only " + _data.length); - } - } - - /** - * Gets whether the object follows the color scheme. - * - * @return one of {@link #DOES_NOT_FOLLOW_COLOR_SCHEME}, - * {@link #FOLLOWS_ENTIRE_COLOR_SCHEME}, or - * {@link #FOLLOWS_TEXT_AND_BACKGROUND_SCHEME}. - */ - public int getFollowColorScheme() { - return LittleEndian.getInt(_data, 0); - } - - /** - * Gets whether the embedded server cannot be locked. - * - * @return {@code true} if the embedded server cannot be locked. - */ - public boolean getCantLockServerB() { - return _data[4] != 0; - } - - public void setCantLockServerB(boolean cantBeLocked) { - _data[4] = (byte)(cantBeLocked ? 1 : 0); - } - - /** - * Gets whether it is not required to send the dimensions to the embedded object. - * - * @return {@code true} if the embedded server does not require the object dimensions. - */ - public boolean getNoSizeToServerB() { - return _data[5] != 0; - } - - /** - * Getswhether the object is a Word table. - * - * @return {@code true} if the object is a Word table. - */ - public boolean getIsTable() { - return _data[6] != 0; - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.ExEmbedAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java deleted file mode 100644 index ca9d68d78..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java +++ /dev/null @@ -1,168 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * This class represents the data of a link in the document. - * @author Nick Burch - */ -public class ExHyperlink extends RecordContainer { - private byte[] _header; - private static long _type = 4055; - - // Links to our more interesting children - private ExHyperlinkAtom linkAtom; - private CString linkDetailsA; - private CString linkDetailsB; - - /** - * Returns the ExHyperlinkAtom of this link - */ - public ExHyperlinkAtom getExHyperlinkAtom() { return linkAtom; } - - /** - * Returns the URL of the link. - * - * @return the URL of the link - */ - public String getLinkURL() { - return linkDetailsB == null ? null : linkDetailsB.getText(); - } - - /** - * Returns the hyperlink's user-readable name - * - * @return the hyperlink's user-readable name - */ - public String getLinkTitle() { - return linkDetailsA == null ? null : linkDetailsA.getText(); - } - - /** - * Sets the URL of the link - * TODO: Figure out if we should always set both - */ - public void setLinkURL(String url) { - if(linkDetailsB != null) { - linkDetailsB.setText(url); - } - } - - public void setLinkOptions(int options) { - if(linkDetailsB != null) { - linkDetailsB.setOptions(options); - } - } - - public void setLinkTitle(String title) { - if(linkDetailsA != null) { - linkDetailsA.setText(title); - } - } - - /** - * Get the link details (field A) - */ - public String _getDetailsA() { - return linkDetailsA == null ? null : linkDetailsA.getText(); - } - /** - * Get the link details (field B) - */ - public String _getDetailsB() { - return linkDetailsB == null ? null : linkDetailsB.getText(); - } - - /** - * Set things up, and find our more interesting children - */ - protected ExHyperlink(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - // First child should be the ExHyperlinkAtom - if(_children[0] instanceof ExHyperlinkAtom) { - linkAtom = (ExHyperlinkAtom)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a ExHyperlinkAtom, was of type " + _children[0].getRecordType()); - } - - for (int i = 1; i < _children.length; i++) { - if (_children[i] instanceof CString){ - if ( linkDetailsA == null) linkDetailsA = (CString)_children[i]; - else linkDetailsB = (CString)_children[i]; - } else { - logger.log(POILogger.ERROR, "Record after ExHyperlinkAtom wasn't a CString, was of type " + _children[1].getRecordType()); - } - - } - } - - /** - * Create a new ExHyperlink, with blank fields - */ - public ExHyperlink() { - _header = new byte[8]; - _children = new Record[3]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)_type); - - // Setup our child records - CString csa = new CString(); - CString csb = new CString(); - csa.setOptions(0x00); - csb.setOptions(0x10); - _children[0] = new ExHyperlinkAtom(); - _children[1] = csa; - _children[2] = csb; - findInterestingChildren(); - } - - /** - * We are of type 4055 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlinkAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlinkAtom.java deleted file mode 100644 index 99deafdbf..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlinkAtom.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * Tne atom that holds metadata on a specific Link in the document. - * (The actual link is held in a sibling CString record) - * - * @author Nick Burch - */ -public final class ExHyperlinkAtom extends RecordAtom { - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new link related atom record. - */ - protected ExHyperlinkAtom() { - _header = new byte[8]; - _data = new byte[4]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - - // It is fine for the other values to be zero - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExHyperlinkAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - // Must be at least 4 bytes long - if(_data.length < 4) { - throw new IllegalArgumentException("The length of the data for a ExHyperlinkAtom must be at least 4 bytes, but was only " + _data.length); - } - } - - /** - * Gets the link number. This will match the one in the - * InteractiveInfoAtom which uses the link. - * @return the link number - */ - public int getNumber() { - return LittleEndian.getInt(_data,0); - } - - /** - * Sets the link number - * @param number the link number. - */ - public void setNumber(int number) { - LittleEndian.putInt(_data,0,number); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.ExHyperlinkAtom.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExMCIMovie.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExMCIMovie.java deleted file mode 100644 index 7d2417587..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExMCIMovie.java +++ /dev/null @@ -1,101 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * A container record that specifies information about a movie stored externally. - * - * @author Yegor Kozlov - */ -public class ExMCIMovie extends RecordContainer { // TODO - instantiable superclass - private byte[] _header; - - //An ExVideoContainer record that specifies information about the MCI movie - private ExVideoContainer exVideo; - - /** - * Set things up, and find our more interesting children - */ - protected ExMCIMovie(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source, start, _header, 0, 8); - - // Find our children - _children = Record.findChildRecords(source, start + 8, len - 8); - findInterestingChildren(); - } - - /** - * Create a new ExMCIMovie, with blank fields - */ - public ExMCIMovie() { - _header = new byte[8]; - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short) getRecordType()); - - exVideo = new ExVideoContainer(); - _children = new Record[]{exVideo}; - - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - // First child should be the ExVideoContainer - if (_children[0] instanceof ExVideoContainer) { - exVideo = (ExVideoContainer) _children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a ExVideoContainer, was of type " + _children[0].getRecordType()); - } - } - - /** - * We are of type 4103 - */ - public long getRecordType() { - return RecordTypes.ExMCIMovie.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0], _header[1], getRecordType(), _children, out); - } - - /** - * Returns the ExVideoContainer that specifies information about the MCI movie - */ - public ExVideoContainer getExVideo() { - return exVideo; } - - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExMediaAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExMediaAtom.java deleted file mode 100644 index 058f27ea5..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExMediaAtom.java +++ /dev/null @@ -1,169 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * An atom record that specifies information about external audio or video data. - * - * @author Yegor Kozlov - */ -public final class ExMediaAtom extends RecordAtom -{ - - /** - * A bit that specifies whether the audio or video data is repeated continuously during playback. - */ - public static final int fLoop = 1; - /** - * A bit that specifies whether the audio or video data is rewound after playing. - */ - public static final int fRewind = 2; - /** - * A bit that specifies whether the audio data is recorded narration for the slide show. It MUST be FALSE if this ExMediaAtom record is contained by an ExVideoContainer record. - */ - public static final int fNarration = 4; - - /** - * Record header. - */ - private byte[] _header; - - /** - * record data - */ - private byte[] _recdata; - - /** - * Constructs a brand new link related atom record. - */ - protected ExMediaAtom() { - _recdata = new byte[8]; - - _header = new byte[8]; - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _recdata.length); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExMediaAtom(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the record data - _recdata = new byte[len-8]; - System.arraycopy(source,start+8,_recdata,0,len-8); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.ExMediaAtom.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_recdata); - } - - /** - * A 4-byte unsigned integer that specifies an ID for an external object. - * - * @return A 4-byte unsigned integer that specifies an ID for an external object. - */ - public int getObjectId(){ - return LittleEndian.getInt(_recdata, 0); - } - - /** - * A 4-byte unsigned integer that specifies an ID for an external object. - * - * @param id A 4-byte unsigned integer that specifies an ID for an external object. - */ - public void setObjectId(int id){ - LittleEndian.putInt(_recdata, 0, id); - } - - /** - * A bit mask specifying options for displaying headers and footers - * - * @return A bit mask specifying options for displaying headers and footers - */ - public int getMask(){ - return LittleEndian.getInt(_recdata, 4); - } - - /** - * A bit mask specifying options for displaying video - * - * @param mask A bit mask specifying options for displaying video - */ - public void setMask(int mask){ - LittleEndian.putInt(_recdata, 4, mask); - } - - /** - * @param bit the bit to check - * @return whether the specified flag is set - */ - public boolean getFlag(int bit){ - return (getMask() & bit) != 0; - } - - /** - * @param bit the bit to set - * @param value whether the specified bit is set - */ - public void setFlag(int bit, boolean value){ - int mask = getMask(); - if(value) mask |= bit; - else mask &= ~bit; - setMask(mask); - } - - public String toString(){ - StringBuffer buf = new StringBuffer(); - buf.append("ExMediaAtom\n"); - buf.append("\tObjectId: " + getObjectId() + "\n"); - buf.append("\tMask : " + getMask() + "\n"); - buf.append("\t fLoop : " + getFlag(fLoop) + "\n"); - buf.append("\t fRewind : " + getFlag(fRewind) + "\n"); - buf.append("\t fNarration : " + getFlag(fNarration) + "\n"); - return buf.toString(); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java deleted file mode 100644 index 6c40ecf18..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java +++ /dev/null @@ -1,129 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; - -import org.apache.poi.util.LittleEndian; - -/** - * This class holds the links to exernal objects referenced - * from the document. - * @author Nick Burch - */ -public class ExObjList extends RecordContainer { - private byte[] _header; - private static long _type = 1033; - - // Links to our more interesting children - private ExObjListAtom exObjListAtom; - - /** - * Returns the ExObjListAtom of this list - */ - public ExObjListAtom getExObjListAtom() { return exObjListAtom; } - - /** - * Returns all the ExHyperlinks - */ - public ExHyperlink[] getExHyperlinks() { - ArrayList links = new ArrayList(); - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof ExHyperlink) { - links.add( (ExHyperlink)_children[i] ); - } - } - - return links.toArray(new ExHyperlink[links.size()]); - } - - /** - * Set things up, and find our more interesting children - */ - protected ExObjList(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - // First child should be the atom - if(_children[0] instanceof ExObjListAtom) { - exObjListAtom = (ExObjListAtom)_children[0]; - } else { - throw new IllegalStateException("First child record wasn't a ExObjListAtom, was of type " + _children[0].getRecordType()); - } - } - - /** - * Create a new ExObjList, with blank fields - */ - public ExObjList() { - _header = new byte[8]; - _children = new Record[1]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)_type); - - // Setup our child records - _children[0] = new ExObjListAtom(); - findInterestingChildren(); - } - - /** - * We are of type 1033 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - - /** - * Lookup a hyperlink by its unique id - * - * @param id hyperlink id - * @return found ExHyperlink or null - */ - public ExHyperlink get(int id){ - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof ExHyperlink) { - ExHyperlink rec = (ExHyperlink)_children[i]; - if (rec.getExHyperlinkAtom().getNumber() == id){ - return rec; - } - } - } - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java deleted file mode 100644 index 51bb5b4ee..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * Tne atom that holds the seed info used by a ExObjList - * - * @author Nick Burch - */ - -public class ExObjListAtom extends RecordAtom -{ - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new link related atom record. - */ - protected ExObjListAtom() { - _header = new byte[8]; - _data = new byte[4]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - - // It is fine for the other values to be zero - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExObjListAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - // Must be at least 4 bytes long - if(_data.length < 4) { - throw new IllegalArgumentException("The length of the data for a ExObjListAtom must be at least 4 bytes, but was only " + _data.length); - } - } - - /** - * Gets the object ID seed, which will be used as the unique - * OLE identifier for the next OLE object added - * @return the object ID seed - */ - public long getObjectIDSeed() { - return LittleEndian.getUInt(_data,0); - } - - /** - * Sets the object ID seed - * @param seed the new ID seed - */ - public void setObjectIDSeed(int seed) { - LittleEndian.putInt(_data,0,seed); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.ExObjListAtom.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjRefAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjRefAtom.java deleted file mode 100644 index fa362c8dd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjRefAtom.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * ExObjRefAtom (3009). - *

        - * An atom record that specifies a reference to an external object. - *

        - */ - -public final class ExObjRefAtom extends RecordAtom { - private byte[] _header; - - /** - * A 4-byte unsigned integer that specifies a reference to an external object. - * It MUST be equal to the value of the exObjId field of an ExMediaAtom record - * or the value of the exObjId field of an ExOleObjAtom record. - */ - private int exObjIdRef; - - /** - * Create a new instance of ExObjRefAtom - */ - public ExObjRefAtom() { - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)getRecordType()); - LittleEndian.putInt(_header, 4, 4); - exObjIdRef = 0; - } - - /** - * Build an instance of ExObjRefAtom from on-disk data - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExObjRefAtom(byte[] source, int start, int len) { - _header = new byte[8]; - int offset = start; - System.arraycopy(source,start,_header,0,8); - offset += _header.length; - exObjIdRef = (int)LittleEndian.getUInt(source, offset); - } - - /** - * @return type of this record {@link RecordTypes#ExObjRefAtom}. - */ - public long getRecordType() { - return RecordTypes.ExObjRefAtom.typeID; - } - - public int getExObjIdRef(){ - return exObjIdRef; - } - - public void setExObjIdRef(int id){ - exObjIdRef = id; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - - byte[] recdata = new byte[4]; - LittleEndian.putUInt(recdata, 0, exObjIdRef); - - out.write(recdata); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjAtom.java deleted file mode 100644 index 9f412d249..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjAtom.java +++ /dev/null @@ -1,313 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * Atom storing information for an OLE object. - * - * - * - * @author Daniel Noll - */ -public class ExOleObjAtom extends RecordAtom { - - /** - * The object) is displayed as an embedded object inside of a container, - */ - public static final int DRAW_ASPECT_VISIBLE = 1; - /** - * The object is displayed as a thumbnail image. - */ - public static final int DRAW_ASPECT_THUMBNAIL = 2; - /** - * The object is displayed as an icon. - */ - public static final int DRAW_ASPECT_ICON = 4; - /** - * The object is displayed on the screen as though it were printed to a printer. - */ - public static final int DRAW_ASPECT_DOCPRINT = 8; - - /** - * An embedded OLE object; the object is serialized and saved within the file. - */ - public static final int TYPE_EMBEDDED = 0; - /** - * A linked OLE object; the object is saved outside of the file. - */ - public static final int TYPE_LINKED = 1; - /** - * The OLE object is an ActiveX control. - */ - public static final int TYPE_CONTROL = 2; - - public static final int SUBTYPE_DEFAULT = 0; - public static final int SUBTYPE_CLIPART_GALLERY = 1; - public static final int SUBTYPE_WORD_TABLE = 2; - public static final int SUBTYPE_EXCEL = 3; - public static final int SUBTYPE_GRAPH = 4; - public static final int SUBTYPE_ORGANIZATION_CHART = 5; - public static final int SUBTYPE_EQUATION = 6; - public static final int SUBTYPE_WORDART = 7; - public static final int SUBTYPE_SOUND = 8; - public static final int SUBTYPE_IMAGE = 9; - public static final int SUBTYPE_POWERPOINT_PRESENTATION = 10; - public static final int SUBTYPE_POWERPOINT_SLIDE = 11; - public static final int SUBTYPE_PROJECT = 12; - public static final int SUBTYPE_NOTEIT = 13; - public static final int SUBTYPE_EXCEL_CHART = 14; - public static final int SUBTYPE_MEDIA_PLAYER = 15; - - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new link related atom record. - */ - public ExOleObjAtom() { - _header = new byte[8]; - _data = new byte[24]; - - LittleEndian.putShort(_header, 0, (short)1); //MUST be 0x1 - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExOleObjAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - // Must be at least 24 bytes long - if(_data.length < 24) { - throw new IllegalArgumentException("The length of the data for a ExOleObjAtom must be at least 24 bytes, but was only " + _data.length); - } - } - - /** - * Gets whether the object can be completely seen, or if only the - * icon is visible. - * - * @return the draw aspect, one of the {@code DRAW_ASPECT_*} constants. - */ - public int getDrawAspect() { - return LittleEndian.getInt(_data, 0); - } - - /** - * Sets whether the object can be completely seen, or if only the - * icon is visible. - * - * @param aspect the draw aspect, one of the {@code DRAW_ASPECT_*} constants. - */ - public void setDrawAspect(int aspect) { - LittleEndian.putInt(_data, 0, aspect); - } - - /** - * Gets whether the object is embedded or linked. - * - * @return the type, one of the {@code TYPE_EMBEDDED_*} constants. - */ - public int getType() { - return LittleEndian.getInt(_data, 4); - } - - /** - * Sets whether the object is embedded or linked. - * - * @param type the type, one of the {@code TYPE_EMBEDDED_*} constants. - */ - public void setType(int type) { - LittleEndian.putInt(_data, 4, type); - } - - /** - * Gets the unique identifier for the OLE object. - * - * @return the object ID. - */ - public int getObjID() { - return LittleEndian.getInt(_data, 8); - } - - /** - * Sets the unique identifier for the OLE object. - * - * @param id the object ID. - */ - public void setObjID(int id) { - LittleEndian.putInt(_data, 8, id); - } - - /** - * Gets the type of OLE object. - * - * @return the sub-type, one of the {@code SUBTYPE_*} constants. - */ - public int getSubType() { - return LittleEndian.getInt(_data, 12); - } - - /** - * Sets the type of OLE object. - * - * @param type the sub-type, one of the {@code SUBTYPE_*} constants. - */ - public void setSubType(int type) { - LittleEndian.putInt(_data, 12, type); - } - - /** - * Gets the reference to the persistent object - * - * @return the reference to the persistent object, corresponds with an - * {@code ExOleObjStg} storage container. - */ - public int getObjStgDataRef() { - return LittleEndian.getInt(_data, 16); - } - - /** - * Sets the reference to the persistent object - * - * @param ref the reference to the persistent object, corresponds with an - * {@code ExOleObjStg} storage container. - */ - public void setObjStgDataRef(int ref) { - LittleEndian.putInt(_data, 16, ref); - } - - /** - * Gets whether the object's image is blank. - * - * @return {@code true} if the object's image is blank. - */ - public boolean getIsBlank() { - // Even though this is a mere boolean, KOffice's code says it's an int. - return LittleEndian.getInt(_data, 20) != 0; - } - - /** - * Gets misc options (the last four bytes in the atom). - * - * @return {@code true} if the object's image is blank. - */ - public int getOptions() { - // Even though this is a mere boolean, KOffice's code says it's an int. - return LittleEndian.getInt(_data, 20); - } - - /** - * Sets misc options (the last four bytes in the atom). - */ - public void setOptions(int opts) { - // Even though this is a mere boolean, KOffice's code says it's an int. - LittleEndian.putInt(_data, 20, opts); - } - - /** - * Returns the type (held as a little endian in bytes 3 and 4) - * that this class handles. - */ - public long getRecordType() { - return RecordTypes.ExOleObjAtom.typeID; - } - - /** - * Have the contents printer out into an OutputStream, used when - * writing a file back out to disk - * (Normally, atom classes will keep their bytes around, but - * non atom classes will just request the bytes from their - * children, then chuck on their header and return) - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } - - public String toString(){ - StringBuffer buf = new StringBuffer(); - buf.append("ExOleObjAtom\n"); - buf.append(" drawAspect: " + getDrawAspect() + "\n"); - buf.append(" type: " + getType() + "\n"); - buf.append(" objID: " + getObjID() + "\n"); - buf.append(" subType: " + getSubType() + "\n"); - buf.append(" objStgDataRef: " + getObjStgDataRef() + "\n"); - buf.append(" options: " + getOptions() + "\n"); - return buf.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java deleted file mode 100644 index e705d24db..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java +++ /dev/null @@ -1,200 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Map; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.InflaterInputStream; - -import org.apache.poi.util.BoundedInputStream; -import org.apache.poi.util.LittleEndian; - -/** - * Storage for embedded OLE objects. - * - * @author Daniel Noll - */ -public class ExOleObjStg extends RecordAtom implements PositionDependentRecord, PersistRecord { - - private int _persistId; // Found from PersistPtrHolder - - /** - * Record header. - */ - private final byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a new empty storage container. - */ - public ExOleObjStg() { - _header = new byte[8]; - _data = new byte[0]; - - LittleEndian.putShort(_header, 0, (short)0x10); - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected ExOleObjStg(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - } - - public boolean isCompressed() { - return LittleEndian.getShort(_header, 0)!=0; - } - - /** - * Gets the uncompressed length of the data. - * - * @return the uncompressed length of the data. - */ - public int getDataLength() { - if (isCompressed()) { - return LittleEndian.getInt(_data, 0); - } else { - return _data.length; - } - } - - /** - * Opens an input stream which will decompress the data on the fly. - * - * @return the data input stream. - */ - public InputStream getData() { - if (isCompressed()) { - int size = LittleEndian.getInt(_data); - - InputStream compressedStream = new ByteArrayInputStream(_data, 4, _data.length); - return new BoundedInputStream(new InflaterInputStream(compressedStream), size); - } else { - return new ByteArrayInputStream(_data, 0, _data.length); - } - } - - public byte[] getRawData() { - return _data; - } - - /** - * Sets the embedded data. - * - * @param data the embedded data. - */ - public void setData(byte[] data) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - //first four bytes is the length of the raw data - byte[] b = new byte[4]; - LittleEndian.putInt(b, 0, data.length); - out.write(b); - - DeflaterOutputStream def = new DeflaterOutputStream(out); - def.write(data, 0, data.length); - def.finish(); - _data = out.toByteArray(); - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Gets the record type. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.ExOleObjStg.typeID; - } - - /** - * Gets the record instance from the header - * - * @return record instance - */ - public int getRecordInstance() { - return (LittleEndian.getUShort(_header, 0) >>> 4); - } - - /** - * Write the contents of the record back, so it can be written - * to disk. - * - * @param out the output stream to write to. - * @throws IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } - - /** - * Fetch our sheet ID, as found from a PersistPtrHolder. - * Should match the RefId of our matching SlidePersistAtom - */ - public int getPersistId() { - return _persistId; - } - - /** - * Set our sheet ID, as found from a PersistPtrHolder - */ - public void setPersistId(int id) { - _persistId = id; - } - - /** Our location on the disk, as of the last write out */ - protected int myLastOnDiskOffset; - - /** Fetch our location on the disk, as of the last write out */ - public int getLastOnDiskOffset() { return myLastOnDiskOffset; } - - /** - * Update the Record's idea of where on disk it lives, after a write out. - * Use with care... - */ - public void setLastOnDiskOffset(int offset) { - myLastOnDiskOffset = offset; - } - - @Override - public void updateOtherRecordReferences(Map oldToNewReferencesLookup) { - // nothing to update - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExVideoContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExVideoContainer.java deleted file mode 100644 index 473201f26..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExVideoContainer.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * A container record that specifies information about external video data. - * - * @author Yegor Kozlov - */ -public final class ExVideoContainer extends RecordContainer { - private byte[] _header; - - // Links to our more interesting children - private ExMediaAtom mediaAtom; - //the UNC or local path to a video file. - private CString pathAtom; - - /** - * Set things up, and find our more interesting children - */ - protected ExVideoContainer(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - // First child should be the ExMediaAtom - if(_children[0] instanceof ExMediaAtom) { - mediaAtom = (ExMediaAtom)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a ExMediaAtom, was of type " + _children[0].getRecordType()); - } - if(_children[1] instanceof CString) { - pathAtom = (CString)_children[1]; - } else { - logger.log(POILogger.ERROR, "Second child record wasn't a CString, was of type " + _children[1].getRecordType()); - } - } - - /** - * Create a new ExVideoContainer, with blank fields - */ - public ExVideoContainer() { - // Setup our header block - _header = new byte[8]; - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)getRecordType()); - - _children = new Record[2]; - _children[0] = mediaAtom = new ExMediaAtom(); - _children[1] = pathAtom = new CString(); - } - - /** - * We are of type 4103 - */ - public long getRecordType() { return RecordTypes.ExVideoContainer.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } - - /** - * Returns the ExMediaAtom of this link - */ - public ExMediaAtom getExMediaAtom() { return mediaAtom; } - - /** - * Returns the Path Atom (CString) of this link - */ - public CString getPathAtom() { return pathAtom; } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java deleted file mode 100644 index b90c698dd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.hslf.model.PPFont; -import org.apache.poi.util.POILogger; - -import java.io.*; -import java.util.*; - -/** - * FontCollection ia a container that holds information - * about all the fonts in the presentation. - * - * @author Yegor Kozlov - */ - -public final class FontCollection extends RecordContainer { - private List fonts; - private byte[] _header; - - protected FontCollection(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - _children = Record.findChildRecords(source,start+8,len-8); - - // Save font names into List - fonts = new ArrayList(); - for (int i = 0; i < _children.length; i++){ - if(_children[i] instanceof FontEntityAtom) { - FontEntityAtom atom = (FontEntityAtom)_children[i]; - fonts.add(atom.getFontName()); - } else { - logger.log(POILogger.WARN, "Warning: FontCollection child wasn't a FontEntityAtom, was " + _children[i]); - } - } - } - - /** - * Return the type, which is 2005 - */ - public long getRecordType() { - return RecordTypes.FontCollection.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } - - /** - * Add font with the specified name to the font collection. - * If the font is already present return its index. - * @param name of the font - * @return zero based index of the font in the collection - */ - public int addFont(String name) { - int idx = getFontIndex(name); - if (idx != -1) return idx; - - return addFont(name, 0, 0, 4, PPFont.FF_SWISS | PPFont.VARIABLE_PITCH); - } - - public int addFont(String name, int charset, int flags, int type, int pitch) { - FontEntityAtom fnt = new FontEntityAtom(); - fnt.setFontIndex(fonts.size() << 4); - fnt.setFontName(name); - fnt.setCharSet(charset); - fnt.setFontFlags(flags); - fnt.setFontType(type); - fnt.setPitchAndFamily(pitch); - fonts.add(name); - - // Append new child to the end - appendChildRecord(fnt); - - return fonts.size()-1; //the added font is the last in the list - } - - /** - * @return zero based index of the font in the collection or -1 if not found - */ - public int getFontIndex(String name) { - for (int i = 0; i < fonts.size(); i++) { - if(fonts.get(i).equals(name)){ - //if the font is already present return its index - return i; - } - } - return -1; - } - - public int getNumberOfFonts() { - return fonts.size(); - } - - /** - * Get the name of the font at the given ID, or null if there is - * no font at that ID. - * @param id - */ - public String getFontWithId(int id) { - if(id >= fonts.size()) { - // No font with that id - return null; - } - return fonts.get(id); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java deleted file mode 100644 index 23a7fe1e4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java +++ /dev/null @@ -1,214 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - -/** - * This atom corresponds exactly to a Windows Logical Font (LOGFONT) structure. - * It keeps all the information needed to define the attributes of a font, - * such as height, width, etc. For more information, consult the - * Windows API Programmer's reference. - * - * @author Yegor Kozlov - */ - -public final class FontEntityAtom extends RecordAtom { - /** - * record header - */ - private byte[] _header; - - /** - * record data - */ - private byte[] _recdata; - - /** - * Build an instance of FontEntityAtom from on-disk data - */ - protected FontEntityAtom(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the record data - _recdata = new byte[len-8]; - System.arraycopy(source,start+8,_recdata,0,len-8); - } - - /** - * Create a new instance of FontEntityAtom - */ - public FontEntityAtom() { - _recdata = new byte[68]; - - _header = new byte[8]; - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _recdata.length); - } - - public long getRecordType() { - return RecordTypes.FontEntityAtom.typeID; - } - - /** - * A null-terminated string that specifies the typeface name of the font. - * The length of this string must not exceed 32 characters - * including the null terminator. - * @return font name - */ - public String getFontName(){ - int maxLen = Math.min(_recdata.length,64); - for(int i = 0; i < maxLen; i+=2){ - //loop until find null-terminated end of the font name - if(_recdata[i] == 0 && _recdata[i + 1] == 0) { - return StringUtil.getFromUnicodeLE(_recdata, 0, i/2); - } - } - return null; - } - - /** - * Set the name of the font. - * The length of this string must not exceed 32 characters - * including the null terminator. - * Will be converted to null-terminated if not already - * @param name of the font - */ - public void setFontName(String name){ - // Add a null termination if required - if(! name.endsWith("\u0000")) { - name += '\u0000'; - } - - // Ensure it's not now too long - if(name.length() > 32) { - throw new RuntimeException("The length of the font name, including null termination, must not exceed 32 characters"); - } - - // Everything's happy, so save the name - byte[] bytes = StringUtil.getToUnicodeLE(name); - System.arraycopy(bytes, 0, _recdata, 0, bytes.length); - } - - public void setFontIndex(int idx){ - LittleEndian.putShort(_header, 0, (short)idx); - } - - public int getFontIndex(){ - return LittleEndian.getShort(_header, 0) >> 4; - } - - /** - * set the character set - * - * @param charset - characterset - */ - public void setCharSet(int charset){ - _recdata[64] = (byte)charset; - } - - /** - * get the character set - * - * @return charset - characterset - */ - public int getCharSet(){ - return _recdata[64]; - } - - /** - * set the font flags - * Bit 1: If set, font is subsetted - * - * @param flags - the font flags - */ - public void setFontFlags(int flags){ - _recdata[65] = (byte)flags; - } - - /** - * get the character set - * Bit 1: If set, font is subsetted - * - * @return the font flags - */ - public int getFontFlags(){ - return _recdata[65]; - } - - /** - * set the font type - *

        - * Bit 1: Raster Font - * Bit 2: Device Font - * Bit 3: TrueType Font - *

        - * - * @param type - the font type - */ - public void setFontType(int type){ - _recdata[66] = (byte)type; - } - - /** - * get the font type - *

        - * Bit 1: Raster Font - * Bit 2: Device Font - * Bit 3: TrueType Font - *

        - * - * @return the font type - */ - public int getFontType(){ - return _recdata[66]; - } - - /** - * set lfPitchAndFamily - * - * - * @param val - Corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure - */ - public void setPitchAndFamily(int val){ - _recdata[67] = (byte)val; - } - - /** - * get lfPitchAndFamily - * - * @return corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure - */ - public int getPitchAndFamily(){ - return _recdata[67]; - } - - /** - * Write the contents of the record back, so it can be written to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_recdata); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java deleted file mode 100644 index e6a2cdcac..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java +++ /dev/null @@ -1,120 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ddf.EscherClientDataRecord; -import org.apache.poi.ddf.EscherRecordFactory; -import org.apache.poi.ddf.EscherSerializationListener; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.util.LittleEndian; - -/** - * An atom record that specifies whether a shape is a placeholder shape. - * The number, position, and type of placeholder shapes are determined by - * the slide layout as specified in the SlideAtom record. - * - * @since POI 3.14-Beta2 - */ -public class HSLFEscherClientDataRecord extends EscherClientDataRecord { - - private final List _childRecords = new ArrayList(); - - public List getHSLFChildRecords() { - return _childRecords; - } - - public void removeChild(Class childClass) { - Iterator iter = _childRecords.iterator(); - while (iter.hasNext()) { - if (childClass.isInstance(iter.next())) { - iter.remove(); - } - } - } - - public void addChild(Record childRecord) { - _childRecords.add(childRecord); - } - - @Override - public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { - int bytesRemaining = readHeader( data, offset ); - byte remainingData[] = new byte[bytesRemaining]; - System.arraycopy(data, offset+8, remainingData, 0, bytesRemaining); - setRemainingData(remainingData); - return bytesRemaining + 8; - } - - @Override - public int serialize(int offset, byte[] data, EscherSerializationListener listener) { - listener.beforeRecordSerialize( offset, getRecordId(), this ); - - LittleEndian.putShort(data, offset, getOptions()); - LittleEndian.putShort(data, offset+2, getRecordId()); - - byte childBytes[] = getRemainingData(); - - LittleEndian.putInt(data, offset+4, childBytes.length); - System.arraycopy(childBytes, 0, data, offset+8, childBytes.length); - int recordSize = 8+childBytes.length; - listener.afterRecordSerialize( offset+recordSize, getRecordId(), recordSize, this ); - return recordSize; - } - - @Override - public int getRecordSize() { - return 8 + getRemainingData().length; - } - - @Override - public byte[] getRemainingData() { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - for (Record r : _childRecords) { - r.writeOut(bos); - } - } catch (IOException e) { - throw new HSLFException(e); - } - return bos.toByteArray(); - } - - @Override - public void setRemainingData( byte[] remainingData ) { - _childRecords.clear(); - int offset = 0; - while (offset < remainingData.length) { - Record r = Record.buildRecordAtOffset(remainingData, offset); - _childRecords.add(r); - long rlen = LittleEndian.getUInt(remainingData,offset+4); - offset += 8 + rlen; - } - } - - public String getRecordName() { - return "HSLFClientData"; - } - - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java deleted file mode 100644 index bd8d507cb..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.lang.reflect.Constructor; -import java.util.Map; - -import org.apache.poi.ddf.*; -import org.apache.poi.util.LittleEndian; - -/** - * Generates escher records when provided the byte array containing those records. - * - * @see EscherRecordFactory - */ -public class HSLFEscherRecordFactory extends DefaultEscherRecordFactory { - private static Class[] escherRecordClasses = { EscherPlaceholder.class, HSLFEscherClientDataRecord.class }; - private static Map> recordsMap = recordsToMap( escherRecordClasses ); - - - /** - * Creates an instance of the escher record factory - */ - public HSLFEscherRecordFactory() { - // no instance initialisation - } - - @Override - public EscherRecord createRecord(byte[] data, int offset) { - short options = LittleEndian.getShort( data, offset ); - short recordId = LittleEndian.getShort( data, offset + 2 ); - // int remainingBytes = LittleEndian.getInt( data, offset + 4 ); - - Constructor recordConstructor = recordsMap.get(Short.valueOf(recordId)); - if (recordConstructor == null) { - return super.createRecord(data, offset); - } - EscherRecord escherRecord = null; - try { - escherRecord = recordConstructor.newInstance(new Object[] {}); - } catch (Exception e) { - return super.createRecord(data, offset); - } - escherRecord.setRecordId(recordId); - escherRecord.setOptions(options); - if (escherRecord instanceof EscherContainerRecord) { - ((EscherContainerRecord)escherRecord).fillFields(data, offset, this); - } - - return escherRecord; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersAtom.java deleted file mode 100644 index b9006051d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersAtom.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * An atom record that specifies options for displaying headers and footers - * on a presentation slide or notes slide. - * - * @author Yegor Kozlov - */ - -public final class HeadersFootersAtom extends RecordAtom { - - /** - * A bit that specifies whether the date is displayed in the footer. - * @see #getMask() - * @see #setMask(int) - */ - public static final int fHasDate = 1; - - /** - * A bit that specifies whether the current datetime is used for displaying the datetime. - * @see #getMask() - * @see #setMask(int) - */ - public static final int fHasTodayDate = 2; - - /** - * A bit that specifies whether the date specified in UserDateAtom record - * is used for displaying the datetime. - * - * @see #getMask() - * @see #setMask(int) - */ - public static final int fHasUserDate = 4; - - /** - * A bit that specifies whether the slide number is displayed in the footer. - * - * @see #getMask() - * @see #setMask(int) - */ - public static final int fHasSlideNumber = 8; - - /** - * bit that specifies whether the header text is displayed. - * - * @see #getMask() - * @see #setMask(int) - */ - public static final int fHasHeader = 16; - - /** - * bit that specifies whether the footer text is displayed. - * - * @see #getMask() - * @see #setMask(int) - */ - public static final int fHasFooter = 32; - - /** - * record header - */ - private byte[] _header; - - /** - * record data - */ - private byte[] _recdata; - - /** - * Build an instance of HeadersFootersAtom from on-disk data - */ - protected HeadersFootersAtom(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the record data - _recdata = new byte[len-8]; - System.arraycopy(source,start+8,_recdata,0,len-8); - } - - /** - * Create a new instance of HeadersFootersAtom - */ - public HeadersFootersAtom() { - _recdata = new byte[4]; - - _header = new byte[8]; - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _recdata.length); - } - - public long getRecordType() { - return RecordTypes.HeadersFootersAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_recdata); - } - - /** - * A signed integer that specifies the format ID to be used to style the datetime. - *

        - * It MUST be in the range [0, 12].
        - * This value is converted into a string as specified by the index field of the DateTimeMCAtom record. - * It MUST be ignored unless fHasTodayDate is TRUE. - * - * - * @return A signed integer that specifies the format ID to be used to style the datetime. - */ - public int getFormatId(){ - return LittleEndian.getShort(_recdata, 0); - } - - /** - * A signed integer that specifies the format ID to be used to style the datetime. - * - * @param formatId A signed integer that specifies the format ID to be used to style the datetime. - */ - public void setFormatId(int formatId){ - LittleEndian.putUShort(_recdata, 0, formatId); - } - - /** - * A bit mask specifying options for displaying headers and footers - * - *

      • A - {@link #fHasDate} (1 bit): A bit that specifies whether the date is displayed in the footer. - *
      • B - {@link #fHasTodayDate} (1 bit): A bit that specifies whether the current datetime is used for - * displaying the datetime. - *
      • C - {@link #fHasUserDate} (1 bit): A bit that specifies whether the date specified in UserDateAtom record - * is used for displaying the datetime. - *
      • D - {@link #fHasSlideNumber} (1 bit): A bit that specifies whether the slide number is displayed in the footer. - *
      • E - {@link #fHasHeader} (1 bit): A bit that specifies whether the header text specified by HeaderAtom - * record is displayed. - *
      • F - {@link #fHasFooter} (1 bit): A bit that specifies whether the footer text specified by FooterAtom - * record is displayed. - *
      • reserved (10 bits): MUST be zero and MUST be ignored. - * - * @return A bit mask specifying options for displaying headers and footers - */ - public int getMask(){ - return LittleEndian.getShort(_recdata, 2); - } - - /** - * A bit mask specifying options for displaying headers and footers - * - * @param mask A bit mask specifying options for displaying headers and footers - */ - public void setMask(int mask){ - LittleEndian.putUShort(_recdata, 2, mask); - } - - /** - * @param bit the bit to check - * @return whether the specified flag is set - */ - public boolean getFlag(int bit){ - return (getMask() & bit) != 0; - } - - /** - * @param bit the bit to set - * @param value whether the specified bit is set - */ - public void setFlag(int bit, boolean value){ - int mask = getMask(); - if(value) mask |= bit; - else mask &= ~bit; - setMask(mask); - } - - public String toString(){ - StringBuffer buf = new StringBuffer(); - buf.append("HeadersFootersAtom\n"); - buf.append("\tFormatId: " + getFormatId() + "\n"); - buf.append("\tMask : " + getMask() + "\n"); - buf.append("\t fHasDate : " + getFlag(fHasDate) + "\n"); - buf.append("\t fHasTodayDate : " + getFlag(fHasTodayDate) + "\n"); - buf.append("\t fHasUserDate : " + getFlag(fHasUserDate) + "\n"); - buf.append("\t fHasSlideNumber : " + getFlag(fHasSlideNumber) + "\n"); - buf.append("\t fHasHeader : " + getFlag(fHasHeader) + "\n"); - buf.append("\t fHasFooter : " + getFlag(fHasFooter) + "\n"); - return buf.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersContainer.java deleted file mode 100644 index 9f2a0eecd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersContainer.java +++ /dev/null @@ -1,211 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * A container record that specifies information about the footers on a presentation slide. - *

        - * It contains:
        - *

      • 1. {@link HeadersFootersAtom} - *
      • 2. {@link CString }, Instance UserDate (0), optional: Stores the user's date. - * This is the date that the user wants in the footers, instead of today's date. - *
      • 3. {@link CString }, Instance Header (1), optional: Stores the Header's contents. - *
      • 4. {@link CString }, Instance Footer (2), optional: Stores the Footer's contents. - *

        - * - * @author Yegor Kozlov - */ -public final class HeadersFootersContainer extends RecordContainer { - - /** - * "instance" field in the record header indicating that this HeadersFootersContaine - * is applied for slides - */ - public static final short SlideHeadersFootersContainer = 0x3F; - /** - * "instance" field in the record header indicating that this HeadersFootersContaine - * is applied for notes and handouts - */ - public static final short NotesHeadersFootersContainer = 0x4F; - - public static final int USERDATEATOM = 0; - public static final int HEADERATOM = 1; - public static final int FOOTERATOM = 2; - - private byte[] _header; - private HeadersFootersAtom hdAtom; - private CString csDate, csHeader, csFooter; - - protected HeadersFootersContainer(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - _children = Record.findChildRecords(source,start+8,len-8); - for(int i=0; i < _children.length; i++){ - if(_children[i] instanceof HeadersFootersAtom) hdAtom = (HeadersFootersAtom)_children[i]; - else if(_children[i] instanceof CString) { - CString cs = (CString)_children[i]; - int opts = cs.getOptions() >> 4; - switch(opts){ - case USERDATEATOM: csDate = cs; break; - case HEADERATOM: csHeader = cs; break; - case FOOTERATOM: csFooter = cs; break; - default: - logger.log(POILogger.WARN, "Unexpected CString.Options in HeadersFootersContainer: " + opts); - break; - } - } else { - logger.log(POILogger.WARN, "Unexpected record in HeadersFootersContainer: " + _children[i]); - } - } - - } - - public HeadersFootersContainer(short options) { - _header = new byte[8]; - LittleEndian.putShort(_header, 0, options); - LittleEndian.putShort(_header, 2, (short)getRecordType()); - - hdAtom = new HeadersFootersAtom(); - _children = new Record[]{ - hdAtom - }; - csDate = csHeader = csFooter = null; - - } - - /** - * Return the type, which is {@link RecordTypes#HeadersFooters} - */ - public long getRecordType() { - return RecordTypes.HeadersFooters.typeID; - } - - /** - * Must be either {@link #SlideHeadersFootersContainer} or {@link #NotesHeadersFootersContainer} - * - * @return "instance" field in the record header - */ - public int getOptions(){ - return LittleEndian.getShort(_header, 0); - } - - /** - * Write the contents of the record back, so it can be written to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } - - /** - * HeadersFootersAtom stores the basic information of the header and footer structure. - * - * @return HeadersFootersAtom - */ - public HeadersFootersAtom getHeadersFootersAtom(){ - return hdAtom; - } - - /** - * A {@link CString} record that stores the user's date. - *

        This is the date that the user wants in the footers, instead of today's date.

        - * - * @return A {@link CString} record that stores the user's date or null - */ - public CString getUserDateAtom(){ - return csDate; - } - - /** - * A {@link CString} record that stores the Header's contents. - * - * @return A {@link CString} record that stores the Header's contents or null - */ - public CString getHeaderAtom(){ - return csHeader; - } - - /** - * A {@link CString} record that stores the Footers's contents. - * - * @return A {@link CString} record that stores the Footers's contents or null - */ - public CString getFooterAtom(){ - return csFooter; - } - - /** - * Insert a {@link CString} record that stores the user's date. - * - * @return the created {@link CString} record that stores the user's date. - */ - public CString addUserDateAtom(){ - if(csDate != null) return csDate; - - csDate = new CString(); - csDate.setOptions(USERDATEATOM << 4); - - addChildAfter(csDate, hdAtom); - - return csDate; - } - - /** - * Insert a {@link CString} record that stores the user's date. - * - * @return the created {@link CString} record that stores the user's date. - */ - public CString addHeaderAtom(){ - if(csHeader != null) return csHeader; - - csHeader = new CString(); - csHeader.setOptions(HEADERATOM << 4); - - Record r = hdAtom; - if(csDate != null) r = hdAtom; - addChildAfter(csHeader, r); - - return csHeader; - } - - /** - * Insert a {@link CString} record that stores the user's date. - * - * @return the created {@link CString} record that stores the user's date. - */ - public CString addFooterAtom(){ - if(csFooter != null) return csFooter; - - csFooter = new CString(); - csFooter.setOptions(FOOTERATOM << 4); - - Record r = hdAtom; - if(csHeader != null) r = csHeader; - else if(csDate != null) r = csDate; - addChildAfter(csFooter, r); - - return csFooter; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java deleted file mode 100644 index 8ca722d85..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java +++ /dev/null @@ -1,99 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * This class represents the metadata of a link in a slide/notes/etc. - * It normally just holds a InteractiveInfoAtom, with the metadata - * in it. - * @author Nick Burch - */ -public class InteractiveInfo extends RecordContainer { - private byte[] _header; - private static long _type = 4082; - - // Links to our more interesting children - private InteractiveInfoAtom infoAtom; - - /** - * Returns the InteractiveInfoAtom of this InteractiveInfo - */ - public InteractiveInfoAtom getInteractiveInfoAtom() { return infoAtom; } - - /** - * Set things up, and find our more interesting children - */ - protected InteractiveInfo(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - // First child should be the InteractiveInfoAtom - if (_children == null || _children.length == 0 || !(_children[0] instanceof InteractiveInfoAtom)) { - logger.log(POILogger.WARN, "First child record wasn't a InteractiveInfoAtom - leaving this atom in an invalid state..."); - return; - } - - infoAtom = (InteractiveInfoAtom)_children[0]; - } - - /** - * Create a new InteractiveInfo, with blank fields - */ - public InteractiveInfo() { - _header = new byte[8]; - _children = new Record[1]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short)_type); - - // Setup our child records - infoAtom = new InteractiveInfoAtom(); - _children[0] = infoAtom; - } - - /** - * We are of type 4802 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java deleted file mode 100644 index 6dd8fccf6..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java +++ /dev/null @@ -1,278 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * Tne atom that holds metadata on Links in the document. - * (The actual link is held Document.ExObjList.ExHyperlink) - * - * @author Nick Burch - * @author Yegor Kozlov - */ -public class InteractiveInfoAtom extends RecordAtom { - - /** - * Action Table - */ - public static final byte ACTION_NONE = 0; - public static final byte ACTION_MACRO = 1; - public static final byte ACTION_RUNPROGRAM = 2; - public static final byte ACTION_JUMP = 3; - public static final byte ACTION_HYPERLINK = 4; - public static final byte ACTION_OLE = 5; - public static final byte ACTION_MEDIA = 6; - public static final byte ACTION_CUSTOMSHOW = 7; - - /** - * Jump Table - */ - public static final byte JUMP_NONE = 0; - public static final byte JUMP_NEXTSLIDE = 1; - public static final byte JUMP_PREVIOUSSLIDE = 2; - public static final byte JUMP_FIRSTSLIDE = 3; - public static final byte JUMP_LASTSLIDE = 4; - public static final byte JUMP_LASTSLIDEVIEWED = 5; - public static final byte JUMP_ENDSHOW = 6; - - /** - * Types of hyperlinks - */ - public static final byte LINK_NextSlide = 0x00; - public static final byte LINK_PreviousSlide = 0x01; - public static final byte LINK_FirstSlide = 0x02; - public static final byte LINK_LastSlide = 0x03; - public static final byte LINK_CustomShow = 0x06; - public static final byte LINK_SlideNumber = 0x07; - public static final byte LINK_Url = 0x08; - public static final byte LINK_OtherPresentation = 0x09; - public static final byte LINK_OtherFile = 0x0A; - public static final byte LINK_NULL = (byte)0xFF; - - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new link related atom record. - */ - protected InteractiveInfoAtom() { - _header = new byte[8]; - _data = new byte[16]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - - // It is fine for the other values to be zero - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected InteractiveInfoAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - // Must be at least 16 bytes long - if(_data.length < 16) { - throw new IllegalArgumentException("The length of the data for a InteractiveInfoAtom must be at least 16 bytes, but was only " + _data.length); - } - - // First 4 bytes - no idea, normally 0 - // Second 4 bytes - the id of the link (from 1 onwards) - // Third 4 bytes - no idea, normally 4 - // Fourth 4 bytes - no idea, normally 8 - } - - /** - * Gets the link number. You will normally look the - * ExHyperlink with this number to get the details. - * @return the link number - */ - public int getHyperlinkID() { - return LittleEndian.getInt(_data,4); - } - - /** - * Sets the persistent unique identifier of the link - * - * @param number the persistent unique identifier of the link - */ - public void setHyperlinkID(int number) { - LittleEndian.putInt(_data,4,number); - } - - /** - * a reference to a sound in the sound collection. - */ - public int getSoundRef() { - return LittleEndian.getInt(_data,0); - } - /** - * a reference to a sound in the sound collection. - * - * @param val a reference to a sound in the sound collection - */ - public void setSoundRef(int val) { - LittleEndian.putInt(_data, 0, val); - } - - /** - * Hyperlink Action. - *

        - * see ACTION_* constants for the list of actions - *

        - * - * @return hyperlink action. - */ - public byte getAction() { - return _data[8]; - } - - /** - * Hyperlink Action - *

        - * see ACTION_* constants for the list of actions - *

        - * - * @param val hyperlink action. - */ - public void setAction(byte val) { - _data[8] = val; - } - - /** - * Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc. - */ - public byte getOleVerb() { - return _data[9]; - } - - /** - * Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc. - */ - public void setOleVerb(byte val) { - _data[9] = val; - } - - /** - * Jump - *

        - * see JUMP_* constants for the list of actions - *

        - * - * @return jump - */ - public byte getJump() { - return _data[10]; - } - - /** - * Jump - *

        - * see JUMP_* constants for the list of actions - *

        - * - * @param val jump - */ - public void setJump(byte val) { - _data[10] = val; - } - - /** - * Flags - *

        - *

      • Bit 1: Animated. If 1, then button is animated - *
      • Bit 2: Stop sound. If 1, then stop current sound when button is pressed. - *
      • Bit 3: CustomShowReturn. If 1, and this is a jump to custom show, - * then return to this slide after custom show. - *

        - */ - public byte getFlags() { - return _data[11]; - } - - /** - * Flags - *

        - *

      • Bit 1: Animated. If 1, then button is animated - *
      • Bit 2: Stop sound. If 1, then stop current sound when button is pressed. - *
      • Bit 3: CustomShowReturn. If 1, and this is a jump to custom show, - * then return to this slide after custom show. - *

        - */ - public void setFlags(byte val) { - _data[11] = val; - } - - /** - * hyperlink type - * - * @return hyperlink type - */ - public byte getHyperlinkType() { - return _data[12]; - } - - /** - * hyperlink type - * - * @param val hyperlink type - */ - public void setHyperlinkType(byte val) { - _data[12] = val; - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.InteractiveInfoAtom.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java deleted file mode 100644 index eb1dade78..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; - -/** - * Master slide - * - * @author Yegor Kozlov - */ -public final class MainMaster extends SheetContainer { - private byte[] _header; - private static long _type = 1016; - - // Links to our more interesting children - private SlideAtom slideAtom; - private PPDrawing ppDrawing; - private TxMasterStyleAtom[] txmasters; - private ColorSchemeAtom[] clrscheme; - private ColorSchemeAtom _colorScheme; - - /** - * Returns the SlideAtom of this Slide - */ - public SlideAtom getSlideAtom() { return slideAtom; } - - /** - * Returns the PPDrawing of this Slide, which has all the - * interesting data in it - */ - public PPDrawing getPPDrawing() { return ppDrawing; } - - public TxMasterStyleAtom[] getTxMasterStyleAtoms() { return txmasters; } - - public ColorSchemeAtom[] getColorSchemeAtoms() { return clrscheme; } - - /** - * Set things up, and find our more interesting children - */ - protected MainMaster(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - - ArrayList tx = new ArrayList(); - ArrayList clr = new ArrayList(); - // Find the interesting ones in there - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof SlideAtom) { - slideAtom = (SlideAtom)_children[i]; - } else if(_children[i] instanceof PPDrawing) { - ppDrawing = (PPDrawing)_children[i]; - } else if(_children[i] instanceof TxMasterStyleAtom) { - tx.add( (TxMasterStyleAtom)_children[i] ); - } else if(_children[i] instanceof ColorSchemeAtom) { - clr.add( (ColorSchemeAtom)_children[i] ); - } - - if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) { - _colorScheme = (ColorSchemeAtom)_children[i]; - } - - } - txmasters = tx.toArray(new TxMasterStyleAtom[tx.size()]); - clrscheme = clr.toArray(new ColorSchemeAtom[clr.size()]); - } - - /** - * We are of type 1016 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - - public ColorSchemeAtom getColorScheme(){ - return _colorScheme; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/MasterTextPropAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/MasterTextPropAtom.java deleted file mode 100644 index d38b390af..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/MasterTextPropAtom.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.hslf.model.textproperties.IndentProp; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * Specifies the Indent Level for the text - */ -public final class MasterTextPropAtom extends RecordAtom { - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - // indent details - private List indents; - - /** - * Constructs a new empty master text prop atom. - */ - public MasterTextPropAtom() { - _header = new byte[8]; - _data = new byte[0]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - - indents = new ArrayList(); - } - - /** - * Constructs the ruler atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected MasterTextPropAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - try { - read(); - } catch (Exception e){ - logger.log(POILogger.ERROR, "Failed to parse MasterTextPropAtom", e); - } - } - - /** - * Gets the record type. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.MasterTextPropAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk. - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - write(); - out.write(_header); - out.write(_data); - } - - /** - * Write the internal variables to the record bytes - */ - private void write() { - int pos = 0; - _data = new byte[indents.size()*6]; - for (IndentProp prop : indents) { - LittleEndian.putInt(_data, pos, prop.getCharactersCovered()); - LittleEndian.putShort(_data, pos+4, (short)prop.getIndentLevel()); - pos += 6; - } - } - - /** - * Read the record bytes and initialize the internal variables - */ - private void read() { - int pos = 0; - indents = new ArrayList(_data.length/6); - - while (pos <= _data.length - 6) { - int count = LittleEndian.getInt(_data, pos); - short indent = LittleEndian.getShort(_data, pos+4); - indents.add(new IndentProp(count, indent)); - pos += 6; - } - } - - /** - * Returns the indent that applies at the given text offset - */ - public int getIndentAt(int offset) { - int charsUntil = 0; - for (IndentProp prop : indents) { - charsUntil += prop.getCharactersCovered(); - if (offset < charsUntil) { - return prop.getIndentLevel(); - } - } - return -1; - } - - public List getIndents() { - return Collections.unmodifiableList(indents); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java deleted file mode 100644 index 80ee6039f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Master container for Notes. There is one of these for every page of - * notes, and they have certain specific children - * - * @author Nick Burch - */ - -public final class Notes extends SheetContainer -{ - private byte[] _header; - private static long _type = 1008l; - - // Links to our more interesting children - private NotesAtom notesAtom; - private PPDrawing ppDrawing; - private ColorSchemeAtom _colorScheme; - - /** - * Returns the NotesAtom of this Notes - */ - public NotesAtom getNotesAtom() { return notesAtom; } - /** - * Returns the PPDrawing of this Notes, which has all the - * interesting data in it - */ - public PPDrawing getPPDrawing() { return ppDrawing; } - - - /** - * Set things up, and find our more interesting children - */ - protected Notes(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - - // Find the interesting ones in there - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof NotesAtom) { - notesAtom = (NotesAtom)_children[i]; - //System.out.println("Found notes for sheet " + notesAtom.getSlideID()); - } - if(_children[i] instanceof PPDrawing) { - ppDrawing = (PPDrawing)_children[i]; - } - if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) { - _colorScheme = (ColorSchemeAtom)_children[i]; - } - } - } - - - /** - * We are of type 1008 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - - public ColorSchemeAtom getColorScheme(){ - return _colorScheme; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/NotesAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/NotesAtom.java deleted file mode 100644 index 7aace8063..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/NotesAtom.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A Notes Atom (type 1009). Holds information on the parent Notes, such - * as what slide it is tied to - * - * @author Nick Burch - */ - -public final class NotesAtom extends RecordAtom -{ - private byte[] _header; - private static long _type = 1009l; - - private int slideID; - private boolean followMasterObjects; - private boolean followMasterScheme; - private boolean followMasterBackground; - private byte[] reserved; - - - public int getSlideID() { return slideID; } - public void setSlideID(int id) { slideID = id; } - - public boolean getFollowMasterObjects() { return followMasterObjects; } - public boolean getFollowMasterScheme() { return followMasterScheme; } - public boolean getFollowMasterBackground() { return followMasterBackground; } - public void setFollowMasterObjects(boolean flag) { followMasterObjects = flag; } - public void setFollowMasterScheme(boolean flag) { followMasterScheme = flag; } - public void setFollowMasterBackground(boolean flag) { followMasterBackground = flag; } - - - /* *************** record code follows ********************** */ - - /** - * For the Notes Atom - */ - protected NotesAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 8) { len = 8; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the slide ID - slideID = LittleEndian.getInt(source,start+8); - - // Grok the flags, stored as bits - int flags = LittleEndian.getUShort(source,start+12); - if((flags&4) == 4) { - followMasterBackground = true; - } else { - followMasterBackground = false; - } - if((flags&2) == 2) { - followMasterScheme = true; - } else { - followMasterScheme = false; - } - if((flags&1) == 1) { - followMasterObjects = true; - } else { - followMasterObjects = false; - } - - // There might be 2 more bytes, which are a reserved field - reserved = new byte[len-14]; - System.arraycopy(source,start+14,reserved,0,reserved.length); - } - - /** - * We are of type 1009 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - out.write(_header); - - // Slide ID - writeLittleEndian(slideID,out); - - // Flags - short flags = 0; - if(followMasterObjects) { flags += 1; } - if(followMasterScheme) { flags += 2; } - if(followMasterBackground) { flags += 4; } - writeLittleEndian(flags,out); - - // Reserved fields - out.write(reserved); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java deleted file mode 100644 index 54d5d8622..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java +++ /dev/null @@ -1,331 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * OEPlaceholderAtom (3011). - *

        - * An atom record that specifies whether a shape is a placeholder shape. - *

        - * - * @author Yegor Kozlov - */ - -public final class OEPlaceholderAtom extends RecordAtom{ - - /** - * The full size of the master body text placeholder shape. - */ - public static final int PLACEHOLDER_FULLSIZE = 0; - - /** - * Half of the size of the master body text placeholder shape. - */ - public static final int PLACEHOLDER_HALFSIZE = 1; - - /** - * A quarter of the size of the master body text placeholder shape. - */ - public static final int PLACEHOLDER_QUARTSIZE = 2; - - /** - * MUST NOT be used for this field. - */ - public static final byte None = 0; - - /** - * The corresponding shape contains the master title text. - * The corresponding slide MUST be a main master slide. - */ - public static final byte MasterTitle = 1; - - /** - * The corresponding shape contains the master body text. - * The corresponding slide MUST be a main master slide. - */ - public static final byte MasterBody = 2; - - /** - * The corresponding shape contains the master center title text. - * The corresponding slide MUST be a title master slide. - */ - public static final byte MasterCenteredTitle = 3; - - /** - * The corresponding shape contains the master sub-title text. - * The corresponding slide MUST be a title master slide. - */ - public static final byte MasterSubTitle = 4; - - /** - * The corresponding shape contains the shared properties for slide image shapes. - * The corresponding slide MUST be a notes master slide. - */ - public static final byte MasterNotesSlideImage = 5; - - /** - * The corresponding shape contains the master body text. - * The corresponding slide MUST be a notes master slide. - */ - public static final byte MasterNotesBody = 6; - - /** - * The corresponding shape contains the date text field. - * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide. - */ - public static final byte MasterDate = 7; - - /** - * The corresponding shape contains a slide number text field. - * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide. - */ - public static final byte MasterSlideNumber = 8; - - /** - * The corresponding shape contains a footer text field. - * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide. - */ - public static final byte MasterFooter = 9; - - /** - * The corresponding shape contains a header text field. - * The corresponding slide must be a notes master slide or handout master slide. - */ - public static final byte MasterHeader = 10; - - /** - * The corresponding shape contains a presentation slide image. - * The corresponding slide MUST be a notes slide. - */ - public static final byte NotesSlideImage = 11; - - /** - * The corresponding shape contains the notes text. - * The corresponding slide MUST be a notes slide. - */ - public static final byte NotesBody = 12; - - /** - * The corresponding shape contains the title text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Title = 13; - - /** - * The corresponding shape contains the body text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Body = 14; - - /** - * The corresponding shape contains the title text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte CenteredTitle = 15; - - /** - * The corresponding shape contains the sub-title text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Subtitle = 16; - - /** - * The corresponding shape contains the title text with vertical text flow. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte VerticalTextTitle = 17; - - /** - * The corresponding shape contains the body text with vertical text flow. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte VerticalTextBody = 18; - - /** - * The corresponding shape contains a generic object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Object = 19; - - /** - * The corresponding shape contains a chart object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Graph = 20; - - /** - * The corresponding shape contains a table object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Table = 21; - - /** - * The corresponding shape contains a clipart object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte ClipArt = 22; - - /** - * The corresponding shape contains an organization chart object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte OrganizationChart = 23; - - /** - * The corresponding shape contains a media object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte MediaClip = 24; - - private byte[] _header; - - private int placementId; - private int placeholderId; - private int placeholderSize; - private short unusedShort = 0; - - - /** - * Create a new instance of OEPlaceholderAtom - */ - public OEPlaceholderAtom(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)getRecordType()); - LittleEndian.putInt(_header, 4, 8); - - placementId = 0; - placeholderId = 0; - placeholderSize = 0; - } - - /** - * Build an instance of OEPlaceholderAtom from on-disk data - */ - protected OEPlaceholderAtom(byte[] source, int start, int len) { - _header = new byte[8]; - int offset = start; - System.arraycopy(source,start,_header,0,8); - offset += _header.length; - - placementId = LittleEndian.getInt(source, offset); offset += 4; - placeholderId = LittleEndian.getUByte(source, offset); offset++; - placeholderSize = LittleEndian.getUByte(source, offset); offset++; - unusedShort = LittleEndian.getShort(source, offset); - } - - /** - * @return type of this record {@link RecordTypes#OEPlaceholderAtom}. - */ - public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; } - - /** - * Returns the placement Id. - *

        - * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders. - * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide. - * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape. - *

        - * - * @return the placement Id. - */ - public int getPlacementId(){ - return placementId; - } - - /** - * Sets the placement Id. - *

        - * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders. - * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide. - * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape. - *

        - * - * @param id the placement Id. - */ - public void setPlacementId(int id){ - placementId = id; - } - - /** - * Returns the placeholder Id. - * - *

        - * placeholder Id specifies the type of the placeholder shape. - * The value MUST be one of the static constants defined in this class - *

        - * - * @return the placeholder Id. - */ - public int getPlaceholderId(){ - return placeholderId; - } - - /** - * Sets the placeholder Id. - * - *

        - * placeholder Id specifies the type of the placeholder shape. - * The value MUST be one of the static constants defined in this class - *

        - * @param id the placeholder Id. - */ - public void setPlaceholderId(byte id){ - placeholderId = id; - } - - /** - * Returns the placeholder size. - * Must be one of the PLACEHOLDER_* static constants defined in this class. - * - * @return the placeholder size. - */ - public int getPlaceholderSize(){ - return placeholderSize; - } - - /** - * Sets the placeholder size. - * Must be one of the PLACEHOLDER_* static constants defined in this class. - * - * @param size the placeholder size. - */ - public void setPlaceholderSize(byte size){ - placeholderSize = size; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - - byte[] recdata = new byte[8]; - LittleEndian.putInt(recdata, 0, placementId); - recdata[4] = (byte)placeholderId; - recdata[5] = (byte)placeholderSize; - LittleEndian.putShort(recdata, 6, unusedShort); - - out.write(recdata); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java deleted file mode 100644 index e44b360a5..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * OEPlaceholderAtom (3998). - *
        - * What MSDN says about OutlineTextRefAtom: - *

        - * Appears in a slide to indicate a text that is already contained in the document, - * in a SlideListWithText containter. Sometimes slide texts are not contained - * within the slide container to be able to delay loading a slide and still display - * the title and body text in outline view. - *

        - * - * @author Yegor Kozlov - */ - -public final class OutlineTextRefAtom extends RecordAtom { - /** - * record header - */ - private byte[] _header; - - /** - * the text's index within the SlideListWithText (0 for title, 1..n for the nth body) - */ - private int _index; - - /** - * Build an instance of OutlineTextRefAtom from on-disk data - */ - protected OutlineTextRefAtom(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the record data - _index = LittleEndian.getInt(source, start+8); - } - - /** - * Create a new instance of FontEntityAtom - */ - protected OutlineTextRefAtom() { - _index = 0; - - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)getRecordType()); - LittleEndian.putInt(_header, 4, 4); - } - - public long getRecordType() { - return RecordTypes.OutlineTextRefAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - - byte[] recdata = new byte[4]; - LittleEndian.putInt(recdata, 0, _index); - out.write(recdata); - } - - /** - * Sets text's index within the SlideListWithText container - * (0 for title, 1..n for the nth body). - * - * @param idx 0-based text's index - */ - public void setTextIndex(int idx){ - _index = idx; - } - - /** - * Return text's index within the SlideListWithText container - * (0 for title, 1..n for the nth body). - * - * @return idx text's index - */ - public int getTextIndex(){ - return _index; - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java deleted file mode 100644 index ba36989bc..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java +++ /dev/null @@ -1,429 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import org.apache.poi.ddf.DefaultEscherRecordFactory; -import org.apache.poi.ddf.EscherBoolProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherDgRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherRGBProperty; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.ddf.EscherSpgrRecord; -import org.apache.poi.ddf.EscherTextboxRecord; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * These are actually wrappers onto Escher drawings. Make use of - * the DDF classes to do useful things with them. - * For now, creates a tree of the Escher records, and then creates any - * PowerPoint (hslf) records found within the EscherTextboxRecord - * (msofbtClientTextbox) records. - * Also provides easy access to the EscherTextboxRecords, so that their - * text may be extracted and used in Sheets - */ - -// For now, pretending to be an atom. Might not always be, but that -// would require a wrapping class -public final class PPDrawing extends RecordAtom { - private byte[] _header; - private long _type; - - private final List childRecords = new ArrayList(); - private EscherTextboxWrapper[] textboxWrappers; - - //cached EscherDgRecord - private EscherDgRecord dg; - - /** - * Get access to the underlying Escher Records - */ - public List getEscherRecords() { return childRecords; } - - /** - * Get access to the atoms inside Textboxes - */ - public EscherTextboxWrapper[] getTextboxWrappers() { return textboxWrappers; } - - - /* ******************** record stuff follows ********************** */ - - /** - * Creates a new, empty, PPDrawing (typically for use with a new Slide - * or Notes) - */ - public PPDrawing() { - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 15); - LittleEndian.putUShort(_header, 2, RecordTypes.PPDrawing.typeID); - LittleEndian.putInt(_header, 4, 0); - - textboxWrappers = new EscherTextboxWrapper[]{}; - create(); - } - - /** - * Sets everything up, groks the escher etc - */ - protected PPDrawing(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the type - _type = LittleEndian.getUShort(_header,2); - - // Get the contents for now - final byte[] contents = new byte[len]; - System.arraycopy(source,start,contents,0,len); - - // Build up a tree of Escher records contained within - final DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory(); - findEscherChildren(erf, contents, 8, len-8, childRecords); - EscherContainerRecord dgContainer = getDgContainer(); - - if (dgContainer != null) { - textboxWrappers = findInDgContainer(dgContainer); - } else { - // Find and EscherTextboxRecord's, and wrap them up - final List textboxes = new ArrayList(); - findEscherTextboxRecord(childRecords, textboxes); - this.textboxWrappers = textboxes.toArray(new EscherTextboxWrapper[textboxes.size()]); - } - } - private EscherTextboxWrapper[] findInDgContainer(final EscherContainerRecord dgContainer) { - final List found = new LinkedList(); - final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType(RecordTypes.EscherSpgrContainer, dgContainer); - final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType(RecordTypes.EscherSpContainer, spgrContainer); - for (EscherContainerRecord spContainer : spContainers) { - EscherSpRecord sp = (EscherSpRecord)findFirstEscherRecordOfType(RecordTypes.EscherSp, spContainer); - EscherTextboxRecord clientTextbox = (EscherTextboxRecord)findFirstEscherRecordOfType(RecordTypes.EscherClientTextbox, spContainer); - if (null == clientTextbox) { continue; } - - EscherTextboxWrapper w = new EscherTextboxWrapper(clientTextbox); - StyleTextProp9Atom nineAtom = findInSpContainer(spContainer); - w.setStyleTextProp9Atom(nineAtom); - if (null != sp) { - w.setShapeId(sp.getShapeId()); - } - found.add(w); - } - return found.toArray(new EscherTextboxWrapper[found.size()]); - } - - private StyleTextProp9Atom findInSpContainer(final EscherContainerRecord spContainer) { - HSLFEscherClientDataRecord cldata = spContainer.getChildById(RecordTypes.EscherClientData.typeID); - if (cldata == null) { - return null; - } - DummyPositionSensitiveRecordWithChildren progTags = - getChildRecord(cldata.getHSLFChildRecords(), RecordTypes.ProgTags); - if (progTags == null) { - return null; - } - DummyPositionSensitiveRecordWithChildren progBinaryTag = - (DummyPositionSensitiveRecordWithChildren)progTags.findFirstOfType(RecordTypes.ProgBinaryTag.typeID); - if (progBinaryTag == null) { - return null; - } - int size = progBinaryTag.getChildRecords().length; - if (2 != size) { return null; } - - final Record r0 = progBinaryTag.getChildRecords()[0]; - final Record r1 = progBinaryTag.getChildRecords()[1]; - - if (!(r0 instanceof CString)) { return null; } - if (!("___PPT9".equals(((CString) r0).getText()))) { return null; } - if (!(r1 instanceof BinaryTagDataBlob )) { return null; } - final BinaryTagDataBlob blob = (BinaryTagDataBlob) r1; - if (1 != blob.getChildRecords().length) { return null; } - return (StyleTextProp9Atom) blob.findFirstOfType(RecordTypes.StyleTextProp9Atom.typeID); - } - - /** - * Tree walking way of finding Escher Child Records - */ - private void findEscherChildren(DefaultEscherRecordFactory erf, byte[] source, int startPos, int lenToGo, List found) { - - int escherBytes = LittleEndian.getInt( source, startPos + 4 ) + 8; - - // Find the record - EscherRecord r = erf.createRecord(source,startPos); - // Fill it in - r.fillFields( source, startPos, erf ); - // Save it - found.add(r); - - // Wind on - int size = r.getRecordSize(); - if(size < 8) { - logger.log(POILogger.WARN, "Hit short DDF record at " + startPos + " - " + size); - } - - /** - * Sanity check. Always advance the cursor by the correct value. - * - * getRecordSize() must return exactly the same number of bytes that was written in fillFields. - * Sometimes it is not so, see an example in bug #44770. Most likely reason is that one of ddf records calculates wrong size. - */ - if(size != escherBytes){ - logger.log(POILogger.WARN, "Record length=" + escherBytes + " but getRecordSize() returned " + r.getRecordSize() + "; record: " + r.getClass()); - size = escherBytes; - } - startPos += size; - lenToGo -= size; - if(lenToGo >= 8) { - findEscherChildren(erf, source, startPos, lenToGo, found); - } - } - - /** - * Look for EscherTextboxRecords - */ - private void findEscherTextboxRecord(List toSearch, List found) { - EscherSpRecord sp = null; - for (EscherRecord r : toSearch) { - if (r instanceof EscherSpRecord) { - sp = (EscherSpRecord)r; - } else if (r instanceof EscherTextboxRecord) { - EscherTextboxRecord tbr = (EscherTextboxRecord)r; - EscherTextboxWrapper w = new EscherTextboxWrapper(tbr); - if (sp != null) { - w.setShapeId(sp.getShapeId()); - } - found.add(w); - } else if (r.isContainerRecord()) { - // If it has children, walk them - List children = r.getChildRecords(); - findEscherTextboxRecord(children,found); - } - } - } - - /** - * We are type 1036 - */ - public long getRecordType() { return _type; } - - /** - * We're pretending to be an atom, so return null - */ - public Record[] getChildRecords() { return null; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * Walks the escher layer to get the contents - */ - public void writeOut(OutputStream out) throws IOException { - // Ensure the escher layer reflects the text changes - for (EscherTextboxWrapper w : textboxWrappers) { - w.writeOut(null); - } - - // Find the new size of the escher children; - int newSize = 0; - for(EscherRecord er : childRecords) { - newSize += er.getRecordSize(); - } - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header,4,newSize); - - // Write out our header - out.write(_header); - - // Now grab the children's data - byte[] b = new byte[newSize]; - int done = 0; - for(EscherRecord r : childRecords) { - done += r.serialize( done, b ); - } - - // Finally, write out the children - out.write(b); - } - - /** - * Create the Escher records associated with a new PPDrawing - */ - private void create(){ - EscherContainerRecord dgContainer = new EscherContainerRecord(); - dgContainer.setRecordId( EscherContainerRecord.DG_CONTAINER ); - dgContainer.setOptions((short)15); - - dg = new EscherDgRecord(); - dg.setOptions((short)16); - dg.setNumShapes(1); - dgContainer.addChildRecord(dg); - - EscherContainerRecord spgrContainer = new EscherContainerRecord(); - spgrContainer.setOptions((short)15); - spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); - - EscherContainerRecord spContainer = new EscherContainerRecord(); - spContainer.setOptions((short)15); - spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER); - - EscherSpgrRecord spgr = new EscherSpgrRecord(); - spgr.setOptions((short)1); - spContainer.addChildRecord(spgr); - - EscherSpRecord sp = new EscherSpRecord(); - sp.setOptions((short)((ShapeType.NOT_PRIMITIVE.nativeId << 4) + 2)); - sp.setFlags(EscherSpRecord.FLAG_PATRIARCH | EscherSpRecord.FLAG_GROUP); - spContainer.addChildRecord(sp); - spgrContainer.addChildRecord(spContainer); - dgContainer.addChildRecord(spgrContainer); - - spContainer = new EscherContainerRecord(); - spContainer.setOptions((short)15); - spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER); - sp = new EscherSpRecord(); - sp.setOptions((short)((ShapeType.RECT.nativeId << 4) + 2)); - sp.setFlags(EscherSpRecord.FLAG_BACKGROUND | EscherSpRecord.FLAG_HASSHAPETYPE); - spContainer.addChildRecord(sp); - - EscherOptRecord opt = new EscherOptRecord(); - opt.setRecordId(EscherOptRecord.RECORD_ID); - opt.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, 134217728)); - opt.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLBACKCOLOR, 134217733)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__RECTRIGHT, 10064750)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__RECTBOTTOM, 7778750)); - opt.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 1179666)); - opt.addEscherProperty(new EscherBoolProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 524288)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHAPE__BLACKANDWHITESETTINGS, 9)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHAPE__BACKGROUNDSHAPE, 65537)); - spContainer.addChildRecord(opt); - - dgContainer.addChildRecord(spContainer); - - childRecords.add(dgContainer); - } - - /** - * Add a new EscherTextboxWrapper to this PPDrawing. - */ - public void addTextboxWrapper(EscherTextboxWrapper txtbox){ - EscherTextboxWrapper[] tw = new EscherTextboxWrapper[textboxWrappers.length + 1]; - System.arraycopy(textboxWrappers, 0, tw, 0, textboxWrappers.length); - - tw[textboxWrappers.length] = txtbox; - textboxWrappers = tw; - } - - /** - * @return the container record for drawings - * @since POI 3.14-Beta2 - */ - public EscherContainerRecord getDgContainer() { - if (childRecords.isEmpty()) { - return null; - } - EscherRecord r = childRecords.get(0); - if (r instanceof EscherContainerRecord && r.getRecordId() == RecordTypes.EscherDgContainer.typeID) { - return (EscherContainerRecord)r; - } else { - return null; - } - } - - /** - * Return EscherDgRecord which keeps track of the number of shapes and shapeId in this drawing group - * - * @return EscherDgRecord - */ - public EscherDgRecord getEscherDgRecord(){ - if(dg == null){ - for(EscherRecord r : getDgContainer().getChildRecords()){ - if(r instanceof EscherDgRecord){ - dg = (EscherDgRecord)r; - break; - } - } - } - return dg; - } - - protected EscherContainerRecord findFirstEscherContainerRecordOfType(RecordTypes type, EscherContainerRecord parent) { - if (null == parent) { return null; } - final List children = parent.getChildContainers(); - for (EscherContainerRecord child : children) { - if (type.typeID == child.getRecordId()) { - return child; - } - } - return null; - } - protected EscherRecord findFirstEscherRecordOfType(RecordTypes type, EscherContainerRecord parent) { - if (null == parent) { return null; } - final List children = parent.getChildRecords(); - for (EscherRecord child : children) { - if (type.typeID == child.getRecordId()) { - return child; - } - } - return null; - } - protected EscherContainerRecord[] findAllEscherContainerRecordOfType(RecordTypes type, EscherContainerRecord parent) { - if (null == parent) { return new EscherContainerRecord[0]; } - final List children = parent.getChildContainers(); - final List result = new LinkedList(); - for (EscherContainerRecord child : children) { - if (type.typeID == child.getRecordId()) { - result.add(child); - } - } - return result.toArray(new EscherContainerRecord[result.size()]); - } - - public StyleTextProp9Atom[] getNumberedListInfo() { - final List result = new LinkedList(); - EscherContainerRecord dgContainer = getDgContainer(); - final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType(RecordTypes.EscherSpgrContainer, dgContainer); - final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType(RecordTypes.EscherSpContainer, spgrContainer); - for (EscherContainerRecord spContainer : spContainers) { - StyleTextProp9Atom prop9 = findInSpContainer(spContainer); - if (prop9 != null) { - result.add(prop9); - } - } - return result.toArray(new StyleTextProp9Atom[result.size()]); - } - - @SuppressWarnings("unchecked") - private static T getChildRecord(List children, RecordTypes type) { - for (Record r : children) { - if (r.getRecordType() == type.typeID) { - return (T)r; - } - } - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java deleted file mode 100644 index 0cdb1f627..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.ddf.*; -import org.apache.poi.util.LittleEndian; - -import java.io.OutputStream; -import java.io.IOException; -import java.io.ByteArrayOutputStream; -import java.util.Iterator; - -/** - * Container records which always exists inside Document. - * It always acts as a holder for escher DGG container - * which may contain which Escher BStore container information - * about pictures containes in the presentation (if any). - * - * @author Yegor Kozlov - */ -public final class PPDrawingGroup extends RecordAtom { - - private byte[] _header; - private EscherContainerRecord dggContainer; - //cached dgg - private EscherDggRecord dgg; - - protected PPDrawingGroup(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the contents for now - byte[] contents = new byte[len]; - System.arraycopy(source,start,contents,0,len); - - DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory(); - EscherRecord child = erf.createRecord(contents, 0); - child.fillFields( contents, 0, erf ); - dggContainer = (EscherContainerRecord)child.getChild(0); - } - - /** - * We are type 1035 - */ - public long getRecordType() { - return RecordTypes.PPDrawingGroup.typeID; - } - - /** - * We're pretending to be an atom, so return null - */ - public Record[] getChildRecords() { - return null; - } - - public void writeOut(OutputStream out) throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - Iterator iter = dggContainer.getChildIterator(); - while (iter.hasNext()) { - EscherRecord r = iter.next(); - if (r.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER){ - EscherContainerRecord bstore = (EscherContainerRecord)r; - - ByteArrayOutputStream b2 = new ByteArrayOutputStream(); - for (Iterator it= bstore.getChildIterator(); it.hasNext();) { - EscherBSERecord bse = (EscherBSERecord)it.next(); - byte[] b = new byte[36+8]; - bse.serialize(0, b); - b2.write(b); - } - byte[] bstorehead = new byte[8]; - LittleEndian.putShort(bstorehead, 0, bstore.getOptions()); - LittleEndian.putShort(bstorehead, 2, bstore.getRecordId()); - LittleEndian.putInt(bstorehead, 4, b2.size()); - bout.write(bstorehead); - bout.write(b2.toByteArray()); - - } else { - bout.write(r.serialize()); - } - } - int size = bout.size(); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header,4,size+8); - - // Write out our header - out.write(_header); - - byte[] dgghead = new byte[8]; - LittleEndian.putShort(dgghead, 0, dggContainer.getOptions()); - LittleEndian.putShort(dgghead, 2, dggContainer.getRecordId()); - LittleEndian.putInt(dgghead, 4, size); - out.write(dgghead); - - // Finally, write out the children - out.write(bout.toByteArray()); - - } - - public EscherContainerRecord getDggContainer(){ - return dggContainer; - } - - public EscherDggRecord getEscherDggRecord(){ - if(dgg == null){ - for(Iterator it = dggContainer.getChildIterator(); it.hasNext();){ - EscherRecord r = it.next(); - if(r instanceof EscherDggRecord){ - dgg = (EscherDggRecord)r; - break; - } - } - } - return dgg; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ParentAwareRecord.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ParentAwareRecord.java deleted file mode 100644 index c71699f35..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ParentAwareRecord.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -/** - * Interface to define how a record can indicate it cares about what its - * parent is, and how it wants to be told which record is its parent. - * - * @author Nick Burch (nick at torchbox dot com) - */ -public interface ParentAwareRecord { - public RecordContainer getParentRecord(); - public void setParentRecord(RecordContainer parentRecord); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java deleted file mode 100644 index b800f3e21..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java +++ /dev/null @@ -1,243 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; -import org.apache.poi.util.BitField; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * General holder for PersistPtrFullBlock and PersistPtrIncrementalBlock - * records. We need to handle them specially, since we have to go around - * updating UserEditAtoms if they shuffle about on disk - * These hold references to where slides "live". If the position of a slide - * moves, then we have update all of these. If we come up with a new version - * of a slide, then we have to add one of these to the end of the chain - * (via CurrentUserAtom and UserEditAtom) pointing to the new slide location - * - * @author Nick Burch - */ - -public final class PersistPtrHolder extends PositionDependentRecordAtom -{ - private final byte[] _header; - private byte[] _ptrData; // Will need to update this once we allow updates to _slideLocations - private long _type; - - /** - * Holds the lookup for slides to their position on disk. - * You always need to check the most recent PersistPtrHolder - * that knows about a given slide to find the right location - */ - private Map _slideLocations; - - private static final BitField persistIdFld = new BitField(0X000FFFFF); - private static final BitField cntPersistFld = new BitField(0XFFF00000); - - /** - * Return the value we were given at creation, be it 6001 or 6002 - */ - public long getRecordType() { return _type; } - - /** - * Get the list of slides that this PersistPtrHolder knows about. - * (They will be the keys in the map for looking up the positions - * of these slides) - */ - public int[] getKnownSlideIDs() { - int[] ids = new int[_slideLocations.size()]; - int i = 0; - for (Integer slideId : _slideLocations.keySet()) { - ids[i++] = slideId; - } - return ids; - } - - /** - * Get the lookup from slide numbers to byte offsets, for the slides - * known about by this PersistPtrHolder. - */ - public Map getSlideLocationsLookup() { - return Collections.unmodifiableMap(_slideLocations); - } - - /** - * Create a new holder for a PersistPtr record - */ - protected PersistPtrHolder(byte[] source, int start, int len) { - // Sanity Checking - including whole header, so treat - // length as based of 0, not 8 (including header size based) - if(len < 8) { len = 8; } - - // Treat as an atom, grab and hold everything - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - _type = LittleEndian.getUShort(_header,2); - - // Try to make sense of the data part: - // Data part is made up of a number of these sets: - // 32 bit info value - // 12 bits count of # of entries - // base number for these entries - // count * 32 bit offsets - // Repeat as many times as you have data - _slideLocations = new HashMap(); - _ptrData = new byte[len-8]; - System.arraycopy(source,start+8,_ptrData,0,_ptrData.length); - - int pos = 0; - while(pos < _ptrData.length) { - // Grab the info field - int info = LittleEndian.getInt(_ptrData,pos); - - // First 20 bits = offset number - // Remaining 12 bits = offset count - int offset_no = persistIdFld.getValue(info); - int offset_count = cntPersistFld.getValue(info); - - // Wind on by the 4 byte info header - pos += 4; - - // Grab the offsets for each of the sheets - for(int i=0; i oldToNewReferencesLookup) { - // Loop over all the slides we know about - // Find where they used to live, and where they now live - for (Entry me : _slideLocations.entrySet()) { - Integer oldPos = me.getValue(); - Integer newPos = oldToNewReferencesLookup.get(oldPos); - - if (newPos == null) { - Integer id = me.getKey(); - logger.log(POILogger.WARN, "Couldn't find the new location of the \"slide\" with id " + id + " that used to be at " + oldPos); - logger.log(POILogger.WARN, "Not updating the position of it, you probably won't be able to find it any more (if you ever could!)"); - } else { - me.setValue(newPos); - } - } - } - - private void normalizePersistDirectory() { - TreeMap orderedSlideLocations = new TreeMap(_slideLocations); - - @SuppressWarnings("resource") - BufAccessBAOS bos = new BufAccessBAOS(); - byte intbuf[] = new byte[4]; - int lastPersistEntry = -1; - int lastSlideId = -1; - for (Entry me : orderedSlideLocations.entrySet()) { - int nextSlideId = me.getKey(); - int offset = me.getValue(); - try { - // Building the info block - // First 20 bits = offset number = slide ID (persistIdFld, i.e. first slide ID of a continuous group) - // Remaining 12 bits = offset count = 1 (cntPersistFld, i.e. continuous entries in a group) - - if (lastSlideId+1 == nextSlideId) { - // use existing PersistDirectoryEntry, need to increase entry count - assert(lastPersistEntry != -1); - int infoBlock = LittleEndian.getInt(bos.getBuf(), lastPersistEntry); - int entryCnt = cntPersistFld.getValue(infoBlock); - infoBlock = cntPersistFld.setValue(infoBlock, entryCnt+1); - LittleEndian.putInt(bos.getBuf(), lastPersistEntry, infoBlock); - } else { - // start new PersistDirectoryEntry - lastPersistEntry = bos.size(); - int infoBlock = persistIdFld.setValue(0, nextSlideId); - infoBlock = cntPersistFld.setValue(infoBlock, 1); - LittleEndian.putInt(intbuf, 0, infoBlock); - bos.write(intbuf); - } - // Add to the ptrData offset lookup hash - LittleEndian.putInt(intbuf, 0, offset); - bos.write(intbuf); - lastSlideId = nextSlideId; - } catch (IOException e) { - // ByteArrayOutputStream is very unlikely throwing a IO exception (maybe because of OOM ...) - throw new RuntimeException(e); - } - } - - // Save the new ptr data - _ptrData = bos.toByteArray(); - - // Update the atom header - LittleEndian.putInt(_header,4,bos.size()); - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - normalizePersistDirectory(); - out.write(_header); - out.write(_ptrData); - } - - private static class BufAccessBAOS extends ByteArrayOutputStream { - public byte[] getBuf() { - return buf; - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PersistRecord.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PersistRecord.java deleted file mode 100644 index 339331865..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PersistRecord.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -/** - * A record that can be referenced in PersistPtr storage. - * - * @author Yegor Kozlov - */ -public interface PersistRecord { - - /** - * Fetch the persist ID - */ - public int getPersistId(); - - /** - * Set the persist ID - */ - public void setPersistId(int id); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecord.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecord.java deleted file mode 100644 index 844c14d45..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecord.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; -import java.util.Map; - -/** - * Records which either care about where they are on disk, or have other - * records who care about where they are, will implement this interface. - * Normally, they'll subclass PositionDependentRecordAtom or - * PositionDependentRecordContainer, which will do the work of providing - * the setting and updating interfaces for them. - * This is a special (and dangerous) kind of Record. When created, they - * need to be pinged with their current location. When written out, they - * need to be given their new location, and offered the list of records - * which have changed their location. - * - * @author Nick Burch - */ - -public interface PositionDependentRecord -{ - /** Fetch our location on the disk, as of the last write out */ - public int getLastOnDiskOffset(); - - /** - * Update the Record's idea of where on disk it lives, after a write out. - * Use with care... - */ - public void setLastOnDiskOffset(int offset); - - /** - * Offer the record the list of records that have changed their - * location as part of the writeout. - */ - public void updateOtherRecordReferences(Map oldToNewReferencesLookup); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordAtom.java deleted file mode 100644 index 76d8f49eb..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordAtom.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; -import java.util.Map; - -/** - * A special (and dangerous) kind of Record Atom that cares about where - * it lives on the disk, or who has other Atoms that care about where - * this is on the disk. - * - * @author Nick Burch - */ - -public abstract class PositionDependentRecordAtom extends RecordAtom implements PositionDependentRecord -{ - /** Our location on the disk, as of the last write out */ - protected int myLastOnDiskOffset; - - /** Fetch our location on the disk, as of the last write out */ - public int getLastOnDiskOffset() { return myLastOnDiskOffset; } - - /** - * Update the Record's idea of where on disk it lives, after a write out. - * Use with care... - */ - public void setLastOnDiskOffset(int offset) { - myLastOnDiskOffset = offset; - } - - /** - * Offer the record the list of records that have changed their - * location as part of the writeout. - * Allows records to update their internal pointers to other records - * locations - */ - public abstract void updateOtherRecordReferences(Map oldToNewReferencesLookup); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordContainer.java deleted file mode 100644 index 14b1932fb..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PositionDependentRecordContainer.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; -import java.util.Map; - -/** - * A special (and dangerous) kind of Record Container, for which other - * Atoms care about where this one lives on disk. - * Will track its position on disk. - * - * @author Nick Burch - */ - -public abstract class PositionDependentRecordContainer extends RecordContainer implements PositionDependentRecord -{ - private int sheetId; // Found from PersistPtrHolder - - /** - * Fetch our sheet ID, as found from a PersistPtrHolder. - * Should match the RefId of our matching SlidePersistAtom - */ - public int getSheetId() { return sheetId; } - - /** - * Set our sheet ID, as found from a PersistPtrHolder - */ - public void setSheetId(int id) { sheetId = id; } - - - /** Our location on the disk, as of the last write out */ - protected int myLastOnDiskOffset; - - /** Fetch our location on the disk, as of the last write out */ - public int getLastOnDiskOffset() { return myLastOnDiskOffset; } - - /** - * Update the Record's idea of where on disk it lives, after a write out. - * Use with care... - */ - public void setLastOnDiskOffset(int offset) { - myLastOnDiskOffset = offset; - } - - /** - * Since we're a container, we don't mind if other records move about. - * If we're told they have, just return straight off. - */ - public void updateOtherRecordReferences(Map oldToNewReferencesLookup) { - return; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java deleted file mode 100644 index e2987b3d6..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java +++ /dev/null @@ -1,203 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This abstract class represents a record in the PowerPoint document. - * Record classes should extend with RecordContainer or RecordAtom, which - * extend this in turn. - * - * @author Nick Burch - */ - -public abstract class Record -{ - // For logging - protected static final POILogger logger = POILogFactory.getLogger(Record.class); - - /** - * Is this record type an Atom record (only has data), - * or is it a non-Atom record (has other records)? - */ - public abstract boolean isAnAtom(); - - /** - * Returns the type (held as a little endian in bytes 3 and 4) - * that this class handles - */ - public abstract long getRecordType(); - - /** - * Fetch all the child records of this record - * If this record is an atom, will return null - * If this record is a non-atom, but has no children, will return - * an empty array - */ - public abstract Record[] getChildRecords(); - - /** - * Have the contents printer out into an OutputStream, used when - * writing a file back out to disk - * (Normally, atom classes will keep their bytes around, but - * non atom classes will just request the bytes from their - * children, then chuck on their header and return) - */ - public abstract void writeOut(OutputStream o) throws IOException; - - /** - * When writing out, write out a signed int (32bit) in Little Endian format - */ - public static void writeLittleEndian(int i,OutputStream o) throws IOException { - byte[] bi = new byte[4]; - LittleEndian.putInt(bi,0,i); - o.write(bi); - } - /** - * When writing out, write out a signed short (16bit) in Little Endian format - */ - public static void writeLittleEndian(short s,OutputStream o) throws IOException { - byte[] bs = new byte[2]; - LittleEndian.putShort(bs,0,s); - o.write(bs); - } - - /** - * Build and return the Record at the given offset. - * Note - does less error checking and handling than findChildRecords - * @param b The byte array to build from - * @param offset The offset to build at - */ - public static Record buildRecordAtOffset(byte[] b, int offset) { - long type = LittleEndian.getUShort(b,offset+2); - long rlen = LittleEndian.getUInt(b,offset+4); - - // Sanity check the length - int rleni = (int)rlen; - if(rleni < 0) { rleni = 0; } - - return createRecordForType(type,b,offset,8+rleni); - } - - /** - * Default method for finding child records of a container record - */ - public static Record[] findChildRecords(byte[] b, int start, int len) { - List children = new ArrayList(5); - - // Jump our little way along, creating records as we go - int pos = start; - while(pos <= (start+len-8)) { - long type = LittleEndian.getUShort(b,pos+2); - long rlen = LittleEndian.getUInt(b,pos+4); - - // Sanity check the length - int rleni = (int)rlen; - if(rleni < 0) { rleni = 0; } - - // Abort if first record is of type 0000 and length FFFF, - // as that's a sign of a screwed up record - if(pos == 0 && type == 0l && rleni == 0xffff) { - throw new CorruptPowerPointFileException("Corrupt document - starts with record of type 0000 and length 0xFFFF"); - } - - Record r = createRecordForType(type,b,pos,8+rleni); - if(r != null) { - children.add(r); - } else { - // Record was horribly corrupt - } - pos += 8; - pos += rleni; - } - - // Turn the vector into an array, and return - Record[] cRecords = children.toArray( new Record[children.size()] ); - return cRecords; - } - - /** - * For a given type (little endian bytes 3 and 4 in record header), - * byte array, start position and length: - * will return a Record object that will handle that record - * - * Remember that while PPT stores the record lengths as 8 bytes short - * (not including the size of the header), this code assumes you're - * passing in corrected lengths - */ - public static Record createRecordForType(long type, byte[] b, int start, int len) { - Record toReturn = null; - - // Handle case of a corrupt last record, whose claimed length - // would take us passed the end of the file - if(start + len > b.length) { - logger.log(POILogger.WARN, "Warning: Skipping record of type " + type + " at position " + start + " which claims to be longer than the file! (" + len + " vs " + (b.length-start) + ")"); - return null; - } - - // We use the RecordTypes class to provide us with the right - // class to use for a given type - // A spot of reflection gets us the (byte[],int,int) constructor - // From there, we instanciate the class - // Any special record handling occurs once we have the class - Class c = null; - try { - c = RecordTypes.forTypeID((short)type).handlingClass; - if(c == null) { - // How odd. RecordTypes normally substitutes in - // a default handler class if it has heard of the record - // type but there's no support for it. Explicitly request - // that now - c = RecordTypes.UnknownRecordPlaceholder.handlingClass; - } - - // Grab the right constructor - java.lang.reflect.Constructor con = c.getDeclaredConstructor(new Class[] { byte[].class, Integer.TYPE, Integer.TYPE }); - // Instantiate - toReturn = con.newInstance(new Object[] { b, start, len }); - } catch(InstantiationException ie) { - throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ie, ie); - } catch(java.lang.reflect.InvocationTargetException ite) { - throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ite + "\nCause was : " + ite.getCause(), ite); - } catch(IllegalAccessException iae) { - throw new RuntimeException("Couldn't access the constructor for type with id " + type + " on class " + c + " : " + iae, iae); - } catch(NoSuchMethodException nsme) { - throw new RuntimeException("Couldn't access the constructor for type with id " + type + " on class " + c + " : " + nsme, nsme); - } - - // Handling for special kinds of records follow - - // If it's a position aware record, tell it where it is - if(toReturn instanceof PositionDependentRecord) { - PositionDependentRecord pdr = (PositionDependentRecord)toReturn; - pdr.setLastOnDiskOffset(start); - } - - // Return the created record - return toReturn; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordAtom.java deleted file mode 100644 index 964d3d1c4..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordAtom.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -/** - * Abstract class which all atom records will extend. - * - * @author Nick Burch - */ - -public abstract class RecordAtom extends Record -{ - /** - * We are an atom - */ - public boolean isAnAtom() { return true; } - - /** - * We're an atom, returns null - */ - public Record[] getChildRecords() { return null; } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java deleted file mode 100644 index 3ad7b086c..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java +++ /dev/null @@ -1,344 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.ArrayUtil; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hslf.util.MutableByteArrayOutputStream; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; - -/** - * Abstract class which all container records will extend. Providers - * helpful methods for writing child records out to disk - * - * @author Nick Burch - */ - -public abstract class RecordContainer extends Record -{ - protected Record[] _children; - - /** - * Return any children - */ - public Record[] getChildRecords() { return _children; } - - /** - * We're not an atom - */ - public boolean isAnAtom() { return false; } - - - /* =============================================================== - * Internal Move Helpers - * =============================================================== - */ - - /** - * Finds the location of the given child record - */ - private int findChildLocation(Record child) { - int i=0; - for(Record r : _children) { - if (r.equals(child)) { - return i; - } - i++; - } - return -1; - } - - /** - * Adds a child record, at the very end. - * @param newChild The child record to add - */ - private void appendChild(Record newChild) { - // Copy over, and pop the child in at the end - Record[] nc = new Record[(_children.length + 1)]; - System.arraycopy(_children, 0, nc, 0, _children.length); - // Switch the arrays - nc[_children.length] = newChild; - _children = nc; - } - - /** - * Adds the given new Child Record at the given location, - * shuffling everything from there on down by one - * @param newChild - * @param position - */ - private void addChildAt(Record newChild, int position) { - // Firstly, have the child added in at the end - appendChild(newChild); - - // Now, have them moved to the right place - moveChildRecords( (_children.length-1), position, 1 ); - } - - /** - * Moves {@code number} child records from {@code oldLoc} to {@code newLoc}. - * @param oldLoc the current location of the records to move - * @param newLoc the new location for the records - * @param number the number of records to move - */ - private void moveChildRecords(int oldLoc, int newLoc, int number) { - if(oldLoc == newLoc) { return; } - if(number == 0) { return; } - - // Check that we're not asked to move too many - if(oldLoc+number > _children.length) { - throw new IllegalArgumentException("Asked to move more records than there are!"); - } - - // Do the move - ArrayUtil.arrayMoveWithin(_children, oldLoc, newLoc, number); - } - - - /** - * Finds the first child record of the given type, - * or null if none of the child records are of the - * given type. Does not descend. - */ - public Record findFirstOfType(long type) { - for (Record r : _children) { - if (r.getRecordType() == type) { - return r; - } - } - return null; - } - - /** - * Remove a child record from this record container - * - * @param ch the child to remove - * @return the removed record - */ - public Record removeChild(Record ch) { - Record rm = null; - ArrayList lst = new ArrayList(); - for(Record r : _children) { - if(r != ch) lst.add(r); - else rm = r; - } - _children = lst.toArray(new Record[lst.size()]); - return rm; - } - - /* =============================================================== - * External Move Methods - * =============================================================== - */ - - /** - * Add a new child record onto a record's list of children. - */ - public void appendChildRecord(Record newChild) { - appendChild(newChild); - } - - /** - * Adds the given Child Record after the supplied record - * @param newChild - * @param after - */ - public void addChildAfter(Record newChild, Record after) { - // Decide where we're going to put it - int loc = findChildLocation(after); - if(loc == -1) { - throw new IllegalArgumentException("Asked to add a new child after another record, but that record wasn't one of our children!"); - } - - // Add one place after the supplied record - addChildAt(newChild, loc+1); - } - - /** - * Adds the given Child Record before the supplied record - * @param newChild - * @param before - */ - public void addChildBefore(Record newChild, Record before) { - // Decide where we're going to put it - int loc = findChildLocation(before); - if(loc == -1) { - throw new IllegalArgumentException("Asked to add a new child before another record, but that record wasn't one of our children!"); - } - - // Add at the place of the supplied record - addChildAt(newChild, loc); - } - - /** - * Moves the given Child Record to before the supplied record - */ - public void moveChildBefore(Record child, Record before) { - moveChildrenBefore(child, 1, before); - } - - /** - * Moves the given Child Records to before the supplied record - */ - public void moveChildrenBefore(Record firstChild, int number, Record before) { - if(number < 1) { return; } - - // Decide where we're going to put them - int newLoc = findChildLocation(before); - if(newLoc == -1) { - throw new IllegalArgumentException("Asked to move children before another record, but that record wasn't one of our children!"); - } - - // Figure out where they are now - int oldLoc = findChildLocation(firstChild); - if(oldLoc == -1) { - throw new IllegalArgumentException("Asked to move a record that wasn't a child!"); - } - - // Actually move - moveChildRecords(oldLoc, newLoc, number); - } - - /** - * Moves the given Child Records to after the supplied record - */ - public void moveChildrenAfter(Record firstChild, int number, Record after) { - if(number < 1) { return; } - // Decide where we're going to put them - int newLoc = findChildLocation(after); - if(newLoc == -1) { - throw new IllegalArgumentException("Asked to move children before another record, but that record wasn't one of our children!"); - } - // We actually want after this though - newLoc++; - - // Figure out where they are now - int oldLoc = findChildLocation(firstChild); - if(oldLoc == -1) { - throw new IllegalArgumentException("Asked to move a record that wasn't a child!"); - } - - // Actually move - moveChildRecords(oldLoc, newLoc, number); - } - - /** - * Set child records. - * - * @param records the new child records - */ - public void setChildRecord(Record[] records) { - this._children = records.clone(); - } - - /* =============================================================== - * External Serialisation Methods - * =============================================================== - */ - - /** - * Write out our header, and our children. - * @param headerA the first byte of the header - * @param headerB the second byte of the header - * @param type the record type - * @param children our child records - * @param out the stream to write to - */ - public void writeOut(byte headerA, byte headerB, long type, Record[] children, OutputStream out) throws IOException { - // If we have a mutable output stream, take advantage of that - if(out instanceof MutableByteArrayOutputStream) { - MutableByteArrayOutputStream mout = - (MutableByteArrayOutputStream)out; - - // Grab current size - int oldSize = mout.getBytesWritten(); - - // Write out our header, less the size - mout.write(new byte[] {headerA,headerB}); - byte[] typeB = new byte[2]; - LittleEndian.putShort(typeB, 0, (short)type); - mout.write(typeB); - mout.write(new byte[4]); - - // Write out the children - for(int i=0; i PowerPoint records: 0 <= info <= 10002 (will carry class info) - *
      • Escher records: info >= 0xF000 (handled by DDF, so no class info) - */ -public enum RecordTypes { - Unknown(0,null), - UnknownRecordPlaceholder(-1, UnknownRecordPlaceholder.class), - Document(1000,Document.class), - DocumentAtom(1001,DocumentAtom.class), - EndDocument(1002,null), - Slide(1006,Slide.class), - SlideAtom(1007,SlideAtom.class), - Notes(1008,Notes.class), - NotesAtom(1009,NotesAtom.class), - Environment(1010,Environment.class), - SlidePersistAtom(1011,SlidePersistAtom.class), - SSlideLayoutAtom(1015,null), - MainMaster(1016,MainMaster.class), - SSSlideInfoAtom(1017,SSSlideInfoAtom.class), - SlideViewInfo(1018,null), - GuideAtom(1019,null), - ViewInfo(1020,null), - ViewInfoAtom(1021,null), - SlideViewInfoAtom(1022,null), - VBAInfo(1023,VBAInfoContainer.class), - VBAInfoAtom(1024,VBAInfoAtom.class), - SSDocInfoAtom(1025,null), - Summary(1026,null), - DocRoutingSlip(1030,null), - OutlineViewInfo(1031,null), - SorterViewInfo(1032,null), - ExObjList(1033,ExObjList.class), - ExObjListAtom(1034,ExObjListAtom.class), - PPDrawingGroup(1035,PPDrawingGroup.class), - PPDrawing(1036,PPDrawing.class), - NamedShows(1040,null), - NamedShow(1041,null), - NamedShowSlides(1042,null), - SheetProperties(1044,null), - RoundTripCustomTableStyles12Atom(1064,null), - List(2000,DocInfoListContainer.class), - FontCollection(2005,FontCollection.class), - BookmarkCollection(2019,null), - SoundCollection(2020,SoundCollection.class), - SoundCollAtom(2021,null), - Sound(2022,Sound.class), - SoundData(2023,SoundData.class), - BookmarkSeedAtom(2025,null), - ColorSchemeAtom(2032,ColorSchemeAtom.class), - ExObjRefAtom(3009,ExObjRefAtom.class), - OEPlaceholderAtom(3011,OEPlaceholderAtom.class), - GPopublicintAtom(3024,null), - GRatioAtom(3031,null), - OutlineTextRefAtom(3998,OutlineTextRefAtom.class), - TextHeaderAtom(3999,TextHeaderAtom.class), - TextCharsAtom(4000,TextCharsAtom.class), - StyleTextPropAtom(4001, StyleTextPropAtom.class),//0x0fa1 RT_StyleTextPropAtom - MasterTextPropAtom(4002, MasterTextPropAtom.class), - TxMasterStyleAtom(4003,TxMasterStyleAtom.class), - TxCFStyleAtom(4004,null), - TxPFStyleAtom(4005,null), - TextRulerAtom(4006,TextRulerAtom.class), - TextBookmarkAtom(4007,null), - TextBytesAtom(4008,TextBytesAtom.class), - TxSIStyleAtom(4009,null), - TextSpecInfoAtom(4010, TextSpecInfoAtom.class), - DefaultRulerAtom(4011,null), - StyleTextProp9Atom(4012, StyleTextProp9Atom.class), //0x0FAC RT_StyleTextProp9Atom - FontEntityAtom(4023,FontEntityAtom.class), - FontEmbeddedData(4024,null), - CString(4026,CString.class), - MetaFile(4033,null), - ExOleObjAtom(4035,ExOleObjAtom.class), - SrKinsoku(4040,null), - HandOut(4041,DummyPositionSensitiveRecordWithChildren.class), - ExEmbed(4044,ExEmbed.class), - ExEmbedAtom(4045,ExEmbedAtom.class), - ExLink(4046,null), - BookmarkEntityAtom(4048,null), - ExLinkAtom(4049,null), - SrKinsokuAtom(4050,null), - ExHyperlinkAtom(4051,ExHyperlinkAtom.class), - ExHyperlink(4055,ExHyperlink.class), - SlideNumberMCAtom(4056,null), - HeadersFooters(4057,HeadersFootersContainer.class), - HeadersFootersAtom(4058,HeadersFootersAtom.class), - TxInteractiveInfoAtom(4063,TxInteractiveInfoAtom.class), - CharFormatAtom(4066,null), - ParaFormatAtom(4067,null), - RecolorInfoAtom(4071,null), - ExQuickTimeMovie(4074,null), - ExQuickTimeMovieData(4075,null), - ExControl(4078,ExControl.class), - SlideListWithText(4080,SlideListWithText.class), - InteractiveInfo(4082,InteractiveInfo.class), - InteractiveInfoAtom(4083,InteractiveInfoAtom.class), - UserEditAtom(4085,UserEditAtom.class), - CurrentUserAtom(4086,null), - DateTimeMCAtom(4087,null), - GenericDateMCAtom(4088,null), - FooterMCAtom(4090,null), - ExControlAtom(4091,ExControlAtom.class), - ExMediaAtom(4100,ExMediaAtom.class), - ExVideoContainer(4101,ExVideoContainer.class), - ExAviMovie(4102,ExAviMovie.class), - ExMCIMovie(4103,ExMCIMovie.class), - ExMIDIAudio(4109,null), - ExCDAudio(4110,null), - ExWAVAudioEmbedded(4111,null), - ExWAVAudioLink(4112,null), - ExOleObjStg(4113,ExOleObjStg.class), - ExCDAudioAtom(4114,null), - ExWAVAudioEmbeddedAtom(4115,null), - AnimationInfo(4116,AnimationInfo.class), - AnimationInfoAtom(4081,AnimationInfoAtom.class), - RTFDateTimeMCAtom(4117,null), - ProgTags(5000,DummyPositionSensitiveRecordWithChildren.class), - ProgStringTag(5001,null), - ProgBinaryTag(5002,DummyPositionSensitiveRecordWithChildren.class), - BinaryTagData(5003, BinaryTagDataBlob.class),//0x138b RT_BinaryTagDataBlob - PrpublicintOptions(6000,null), - PersistPtrFullBlock(6001,PersistPtrHolder.class), - PersistPtrIncrementalBlock(6002,PersistPtrHolder.class), - GScalingAtom(10001,null), - GRColorAtom(10002,null), - - // Records ~12000 seem to be related to the Comments used in PPT 2000/XP - // (Comments in PPT97 are normal Escher text boxes) - Comment2000(12000,Comment2000.class), - Comment2000Atom(12001,Comment2000Atom.class), - Comment2000Summary(12004,null), - Comment2000SummaryAtom(12005,null), - - // Records ~12050 seem to be related to Document Encryption - DocumentEncryptionAtom(12052,DocumentEncryptionAtom.class), - - OriginalMainMasterId(1052,null), - CompositeMasterId(1052,null), - RoundTripContentMasterInfo12(1054,null), - RoundTripShapeId12(1055,null), - RoundTripHFPlaceholder12(1056,RoundTripHFPlaceholder12.class), - RoundTripContentMasterId(1058,null), - RoundTripOArtTextStyles12(1059,null), - RoundTripShapeCheckSumForCustomLayouts12(1062,null), - RoundTripNotesMasterTextStyles12(1063,null), - RoundTripCustomTableStyles12(1064,null), - - // records greater then 0xF000 belong to with Microsoft Office Drawing format also known as Escher - EscherDggContainer(0xF000,null), - EscherDgg(0xf006,null), - EscherCLSID(0xf016,null), - EscherOPT(0xf00b,null), - EscherBStoreContainer(0xf001,null), - EscherBSE(0xf007,null), - EscherBlip_START(0xf018,null), - EscherBlip_END(0xf117,null), - EscherDgContainer(0xf002,null), - EscherDg(0xf008,null), - EscherRegroupItems(0xf118,null), - EscherColorScheme(0xf120,null), - EscherSpgrContainer(0xf003,null), - EscherSpContainer(0xf004,null), - EscherSpgr(0xf009,null), - EscherSp(0xf00a,null), - EscherTextbox(0xf00c,null), - EscherClientTextbox(0xf00d,null), - EscherAnchor(0xf00e,null), - EscherChildAnchor(0xf00f,null), - EscherClientAnchor(0xf010,null), - EscherClientData(0xf011,null), - EscherSolverContainer(0xf005,null), - EscherConnectorRule(0xf012,null), - EscherAlignRule(0xf013,null), - EscherArcRule(0xf014,null), - EscherClientRule(0xf015,null), - EscherCalloutRule(0xf017,null), - EscherSelection(0xf119,null), - EscherColorMRU(0xf11a,null), - EscherDeletedPspl(0xf11d,null), - EscherSplitMenuColors(0xf11e,null), - EscherOleObject(0xf11f,null), - EscherUserDefined(0xf122,null); - - private static final Map LOOKUP; - - static { - LOOKUP = new HashMap(); - for(RecordTypes s : values()) { - LOOKUP.put(s.typeID, s); - } - } - - public final short typeID; - public final Class handlingClass; - - private RecordTypes(int typeID, Class handlingClass) { - this.typeID = (short)typeID; - this.handlingClass = handlingClass; - } - - public static RecordTypes forTypeID(int typeID) { - RecordTypes rt = LOOKUP.get((short)typeID); - return (rt != null) ? rt : UnknownRecordPlaceholder; - } - - - - /** - * Returns name of the record by its type - * - * @param type section of the record header - * @return name of the record - */ -// public static String recordName(int type) { -// String name = typeToName.get(Integer.valueOf(type)); -// return (name == null) ? ("Unknown" + type) : name; -// } - - /** - * Returns the class handling a record by its type. - * If given an un-handled PowerPoint record, will return a dummy - * placeholder class. If given an unknown PowerPoint record, or - * and Escher record, will return null. - * - * @param type section of the record header - * @return class to handle the record, or null if an unknown (eg Escher) record - */ -// public static Class recordHandlingClass(int type) { -// Class c = typeToClass.get(Integer.valueOf(type)); -// return c; -// } -// -// static { -// typeToName = new HashMap(); -// typeToClass = new HashMap>(); -// try { -// Field[] f = RecordTypes.class.getFields(); -// for (int i = 0; i < f.length; i++){ -// Object val = f[i].get(null); -// -// // Escher record, only store ID -> Name -// if (val instanceof Integer) { -// typeToName.put((Integer)val, f[i].getName()); -// } -// // PowerPoint record, store ID -> Name and ID -> Class -// if (val instanceof Type) { -// Type t = (Type)val; -// Class c = t.handlingClass; -// Integer id = Integer.valueOf(t.typeID); -// if(c == null) { c = UnknownRecordPlaceholder.class; } -// -// typeToName.put(id, f[i].getName()); -// typeToClass.put(id, c); -// } -// } -// } catch (IllegalAccessException e){ -// throw new RuntimeException("Failed to initialize records types"); -// } -// } - - - /** - * Wrapper for the details of a PowerPoint or Escher record type. - * Contains both the type, and the handling class (if any), and - * offers methods to get either back out. - */ -// public static class Type { -// public final int typeID; -// public final Class handlingClass; -// public Type(int typeID, Class handlingClass) { -// this.typeID = typeID; -// this.handlingClass = handlingClass; -// } -// } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java deleted file mode 100644 index e843f1dd7..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * An atom record that specifies that a shape is a header or footer placeholder shape - * - * @since PowerPoint 2007 - * @author Yegor Kozlov - */ -public final class RoundTripHFPlaceholder12 extends RecordAtom { - /** - * Record header. - */ - private byte[] _header; - - /** - * Specifies the placeholder shape ID. - * - * MUST be {@link OEPlaceholderAtom#MasterDate}, {@link OEPlaceholderAtom#MasterSlideNumber}, - * {@link OEPlaceholderAtom#MasterFooter}, or {@link OEPlaceholderAtom#MasterHeader} - */ - private byte _placeholderId; - - /** - * Create a new instance of RoundTripHFPlaceholder12 - */ - public RoundTripHFPlaceholder12(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)getRecordType()); - LittleEndian.putInt(_header, 4, 8); - _placeholderId = 0; - } - - /** - * Constructs the comment atom record from its source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected RoundTripHFPlaceholder12(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _placeholderId = source[start+8]; - } - - /** - * Gets the comment number (note - each user normally has their own count). - * @return the comment number. - */ - public int getPlaceholderId() { - return _placeholderId; - } - - /** - * Sets the comment number (note - each user normally has their own count). - * @param number the comment number. - */ - public void setPlaceholderId(int number) { - _placeholderId = (byte)number; - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.RoundTripHFPlaceholder12.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_placeholderId); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SSSlideInfoAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SSSlideInfoAtom.java deleted file mode 100644 index 931f5dc70..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SSSlideInfoAtom.java +++ /dev/null @@ -1,289 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; - -/** - * A SlideShowSlideInfo Atom (type 1017).
        - *
        - * - * An atom record that specifies which transition effects to perform - * during a slide show, and how to advance to the next presentation slide.
        - *
        - * - * Combination of effectType and effectDirection: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
        typedescriptiondirection
        0cut0x00 = no transition, 0x01 = black transition
        1random0x00
        2blinds0x00 = vertical, 0x01 = horizontal
        3checkerlike blinds
        4cover0x00 = left, 0x01 = up, 0x02 = right, 0x03 = down, 0x04 = left/up, 0x05 = right/up, 0x06 left/down, 0x07 = left/down
        5dissolve0x00
        6fade0x00
        7uncoverlike cover
        8random barslike blinds
        9stripslike 0x04 - 0x07 of cover
        10wipelike 0x00 - 0x03 of cover
        11box in/out0x00 = out, 0x01 = in
        13split0x00 = horizontally out, 0x01 = horizontally in, 0x02 = vertically out, 0x03 = vertically in
        17diamond0x00
        18plus0x00
        19wedge0x00
        20pushlike 0x00 - 0x03 of cover
        21comblike blinds
        22newsflash0x00
        23alphafade0x00
        26wheelnumber of radial divisions (0x01,0x02,0x03,0x04,0x08)
        27circle0x00
        255undefined0x00
        - */ -public class SSSlideInfoAtom extends RecordAtom { - /** - * A bit that specifies whether the presentation slide can be - * manually advanced by the user during the slide show. - */ - public static final int MANUAL_ADVANCE_BIT = 1 << 0; - - /** - * A bit that specifies whether the corresponding slide is - * hidden and is not displayed during the slide show. - */ - public static final int HIDDEN_BIT = 1 << 2; - - /** - * A bit that specifies whether to play the sound specified by soundIfRef. - */ - public static final int SOUND_BIT = 1 << 4; - - /** - * A bit that specifies whether the sound specified by soundIdRef is - * looped continuously when playing until the next sound plays. - */ - public static final int LOOP_SOUND_BIT = 1 << 6; - - /** - * A bit that specifies whether to stop any currently playing - * sound when the transition starts. - */ - public static final int STOP_SOUND_BIT = 1 << 8; - - /** - * A bit that specifies whether the slide will automatically - * advance after slideTime milliseconds during the slide show. - */ - public static final int AUTO_ADVANCE_BIT = 1 << 10; - - /** - * A bit that specifies whether to display the cursor during - * the slide show. - */ - public static final int CURSOR_VISIBLE_BIT = 1 << 12; - - // public static int RESERVED1_BIT = 1 << 1; - // public static int RESERVED2_BIT = 1 << 3; - // public static int RESERVED3_BIT = 1 << 5; - // public static int RESERVED4_BIT = 1 << 7; - // public static int RESERVED5_BIT = 1 << 9; - // public static int RESERVED6_BIT = 1 << 11; - // public static int RESERVED7_BIT = 1 << 13 | 1 << 14 | 1 << 15; - - private static final long _type = RecordTypes.SSSlideInfoAtom.typeID; - - private byte[] _header; - - /** - * A signed integer that specifies an amount of time, in milliseconds, to wait - * before advancing to the next presentation slide. It MUST be greater than or equal to 0 and - * less than or equal to 86399000. It MUST be ignored unless AUTO_ADVANCE_BIT is TRUE. - */ - private int _slideTime = 0; - - /** - * A SoundIdRef that specifies which sound to play when the transition starts. - */ - private int _soundIdRef = 0; - - /** - * A byte that specifies the variant of effectType. In combination of the effectType - * there are further restriction and specification of this field. - */ - private short _effectDirection = 0; // byte - - /** - * A byte that specifies which transition is used when transitioning to the - * next presentation slide during a slide show. Exact rendering of any transition is - * determined by the rendering application. As such, the same transition can have - * many variations depending on the implementation. - */ - private short _effectType = 0; // byte - - /** - * Various flags - see bitmask for more details - */ - private short _effectTransitionFlags = 0; - - /** - * A byte value that specifies how long the transition takes to run. - * (0x00 = 0.75 seconds, 0x01 = 0.5 seconds, 0x02 = 0.25 seconds) - */ - private short _speed = 0; // byte - private byte[] _unused; // 3-byte - - public SSSlideInfoAtom() { - _header = new byte[8]; - LittleEndian.putShort(_header, 0, (short)0); - LittleEndian.putShort(_header, 2, (short)_type); - LittleEndian.putShort(_header, 4, (short)0x10); - LittleEndian.putShort(_header, 6, (short)0); - _unused = new byte[3]; - } - - public SSSlideInfoAtom(byte[] source, int offset, int len) { - int ofs = offset; - - // Sanity Checking - if(len != 24) len = 24; - assert(source.length >= offset+len); - - // Get the header - _header = LittleEndian.getByteArray(source,ofs,8); - ofs += _header.length; - - assert(LittleEndian.getShort(_header, 0) == 0); - assert(LittleEndian.getShort(_header, 2) == RecordTypes.SSSlideInfoAtom.typeID); - assert(LittleEndian.getShort(_header, 4) == 0x10); - assert(LittleEndian.getShort(_header, 6) == 0); - - _slideTime = LittleEndian.getInt(source, ofs); - assert(0 <= _slideTime && _slideTime <= 86399000); - ofs += LittleEndianConsts.INT_SIZE; - _soundIdRef = LittleEndian.getInt(source, ofs); - ofs += LittleEndianConsts.INT_SIZE; - _effectDirection = LittleEndian.getUByte(source, ofs); - ofs += LittleEndianConsts.BYTE_SIZE; - _effectType = LittleEndian.getUByte(source, ofs); - ofs += LittleEndianConsts.BYTE_SIZE; - _effectTransitionFlags = LittleEndian.getShort(source, ofs); - ofs += LittleEndianConsts.SHORT_SIZE; - _speed = LittleEndian.getUByte(source, ofs); - ofs += LittleEndianConsts.BYTE_SIZE; - _unused = LittleEndian.getByteArray(source,ofs,3); - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - writeLittleEndian(_slideTime, out); - writeLittleEndian(_soundIdRef, out); - - byte byteBuf[] = new byte[LittleEndianConsts.BYTE_SIZE]; - LittleEndian.putUByte(byteBuf, 0, _effectDirection); - out.write(byteBuf); - LittleEndian.putUByte(byteBuf, 0, _effectType); - out.write(byteBuf); - - writeLittleEndian(_effectTransitionFlags, out); - LittleEndian.putUByte(byteBuf, 0, _speed); - out.write(byteBuf); - - assert(_unused.length == 3); - out.write(_unused); - } - - /** - * We are of type 1017 - */ - public long getRecordType() { return _type; } - - - public int getSlideTime() { - return _slideTime; - } - - public void setSlideTime(int slideTime) { - this._slideTime = slideTime; - } - - public int getSoundIdRef() { - return _soundIdRef; - } - - public void setSoundIdRef(int soundIdRef) { - this._soundIdRef = soundIdRef; - } - - public short getEffectDirection() { - return _effectDirection; - } - - public void setEffectDirection(short effectDirection) { - this._effectDirection = effectDirection; - } - - public short getEffectType() { - return _effectType; - } - - public void setEffectType(short effectType) { - this._effectType = effectType; - } - - public short getEffectTransitionFlags() { - return _effectTransitionFlags; - } - - public void setEffectTransitionFlags(short effectTransitionFlags) { - this._effectTransitionFlags = effectTransitionFlags; - } - - /** - * Use one of the bitmasks MANUAL_ADVANCE_BIT ... CURSOR_VISIBLE_BIT - * @param bitmask - * @param enabled - */ - public void setEffectTransitionFlagByBit(int bitmask, boolean enabled) { - if (enabled) { - _effectTransitionFlags |= bitmask; - } else { - _effectTransitionFlags &= (0xFFFF ^ bitmask); - } - } - - public boolean getEffectTransitionFlagByBit(int bitmask) { - return ((_effectTransitionFlags & bitmask) != 0); - } - - public short getSpeed() { - return _speed; - } - - public void setSpeed(short speed) { - this._speed = speed; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SheetContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SheetContainer.java deleted file mode 100644 index 08c05c46a..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SheetContainer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -/** - * The superclass of all sheet container records - Slide, Notes, MainMaster, etc. - */ -public abstract class SheetContainer extends PositionDependentRecordContainer { - - /** - * Returns the PPDrawing of this sheet, which has all the - * interesting data in it - */ - public abstract PPDrawing getPPDrawing(); - - public abstract ColorSchemeAtom getColorScheme(); - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java deleted file mode 100644 index a833c4016..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * Master container for Slides. There is one of these for every slide, - * and they have certain specific children - * - * @author Nick Burch - */ - -public final class Slide extends SheetContainer -{ - private byte[] _header; - private static long _type = 1006l; - - // Links to our more interesting children - private SlideAtom slideAtom; - private PPDrawing ppDrawing; - private ColorSchemeAtom _colorScheme; - - /** - * Returns the SlideAtom of this Slide - */ - public SlideAtom getSlideAtom() { return slideAtom; } - - /** - * Returns the PPDrawing of this Slide, which has all the - * interesting data in it - */ - public PPDrawing getPPDrawing() { return ppDrawing; } - - - /** - * Set things up, and find our more interesting children - */ - protected Slide(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - - // Find the interesting ones in there - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof SlideAtom) { - slideAtom = (SlideAtom)_children[i]; - } - else if(_children[i] instanceof PPDrawing) { - ppDrawing = (PPDrawing)_children[i]; - } - - if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) { - _colorScheme = (ColorSchemeAtom)_children[i]; - } - } - } - - /** - * Create a new, empty, Slide, along with its required - * child records. - */ - public Slide(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 15); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 0); - - slideAtom = new SlideAtom(); - ppDrawing = new PPDrawing(); - - ColorSchemeAtom colorAtom = new ColorSchemeAtom(); - - _children = new Record[] { - slideAtom, - ppDrawing, - colorAtom - }; - } - - /** - * We are of type 1006 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - - public ColorSchemeAtom getColorScheme(){ - return _colorScheme; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java deleted file mode 100644 index 68f75c09b..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java +++ /dev/null @@ -1,234 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * A Slide Atom (type 1007). Holds information on the parent Slide, what - * Master Slide it uses, what Notes is attached to it, that sort of thing. - * It also has a SSlideLayoutAtom embeded in it, but without the Atom header - * - * @author Nick Burch - */ - -public final class SlideAtom extends RecordAtom -{ - private byte[] _header; - private static long _type = 1007l; - public static final int MASTER_SLIDE_ID = 0; - public static final int USES_MASTER_SLIDE_ID = -2147483648; - - private int masterID; - private int notesID; - - private boolean followMasterObjects; - private boolean followMasterScheme; - private boolean followMasterBackground; - private SSlideLayoutAtom layoutAtom; - private byte[] reserved; - - - /** Get the ID of the master slide used. 0 if this is a master slide, otherwise -2147483648 */ - public int getMasterID() { return masterID; } - /** Change slide master. */ - public void setMasterID(int id) { masterID = id; } - /** Get the ID of the notes for this slide. 0 if doesn't have one */ - public int getNotesID() { return notesID; } - /** Get the embeded SSlideLayoutAtom */ - public SSlideLayoutAtom getSSlideLayoutAtom() { return layoutAtom; } - - /** Change the ID of the notes for this slide. 0 if it no longer has one */ - public void setNotesID(int id) { notesID = id; } - - public boolean getFollowMasterObjects() { return followMasterObjects; } - public boolean getFollowMasterScheme() { return followMasterScheme; } - public boolean getFollowMasterBackground() { return followMasterBackground; } - public void setFollowMasterObjects(boolean flag) { followMasterObjects = flag; } - public void setFollowMasterScheme(boolean flag) { followMasterScheme = flag; } - public void setFollowMasterBackground(boolean flag) { followMasterBackground = flag; } - - - /* *************** record code follows ********************** */ - - /** - * For the Slide Atom - */ - protected SlideAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 30) { len = 30; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the 12 bytes that is "SSlideLayoutAtom" - byte[] SSlideLayoutAtomData = new byte[12]; - System.arraycopy(source,start+8,SSlideLayoutAtomData,0,12); - // Use them to build up the SSlideLayoutAtom - layoutAtom = new SSlideLayoutAtom(SSlideLayoutAtomData); - - // Get the IDs of the master and notes - masterID = LittleEndian.getInt(source,start+12+8); - notesID = LittleEndian.getInt(source,start+16+8); - - // Grok the flags, stored as bits - int flags = LittleEndian.getUShort(source,start+20+8); - if((flags&4) == 4) { - followMasterBackground = true; - } else { - followMasterBackground = false; - } - if((flags&2) == 2) { - followMasterScheme = true; - } else { - followMasterScheme = false; - } - if((flags&1) == 1) { - followMasterObjects = true; - } else { - followMasterObjects = false; - } - - // If there's any other bits of data, keep them about - // 8 bytes header + 20 bytes to flags + 2 bytes flags = 30 bytes - reserved = new byte[len-30]; - System.arraycopy(source,start+30,reserved,0,reserved.length); - } - - /** - * Create a new SlideAtom, to go with a new Slide - */ - public SlideAtom(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 2); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 24); - - byte[] ssdate = new byte[12]; - layoutAtom = new SSlideLayoutAtom(ssdate); - layoutAtom.setGeometryType(SSlideLayoutAtom.BLANK_SLIDE); - - followMasterObjects = true; - followMasterScheme = true; - followMasterBackground = true; - masterID = -2147483648; - notesID = 0; - reserved = new byte[2]; - } - - /** - * We are of type 1007 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - out.write(_header); - - // SSSlideLayoutAtom stuff - layoutAtom.writeOut(out); - - // IDs - writeLittleEndian(masterID,out); - writeLittleEndian(notesID,out); - - // Flags - short flags = 0; - if(followMasterObjects) { flags += 1; } - if(followMasterScheme) { flags += 2; } - if(followMasterBackground) { flags += 4; } - writeLittleEndian(flags,out); - - // Reserved data - out.write(reserved); - } - - - /** - * Holds the geometry of the Slide, and the ID of the placeholders - * on the slide. - * (Embeded inside SlideAtom is a SSlideLayoutAtom, without the - * usual record header. Since it's a fixed size and tied to - * the SlideAtom, we'll hold it here.) - */ - public static class SSlideLayoutAtom { - // The different kinds of geometry - public static final int TITLE_SLIDE = 0; - public static final int TITLE_BODY_SLIDE = 1; - public static final int TITLE_MASTER_SLIDE = 2; - public static final int MASTER_SLIDE = 3; - public static final int MASTER_NOTES = 4; - public static final int NOTES_TITLE_BODY = 5; - public static final int HANDOUT = 6; // Only header, footer and date placeholders - public static final int TITLE_ONLY = 7; - public static final int TITLE_2_COLUMN_BODY = 8; - public static final int TITLE_2_ROW_BODY = 9; - public static final int TITLE_2_COLUNM_RIGHT_2_ROW_BODY = 10; - public static final int TITLE_2_COLUNM_LEFT_2_ROW_BODY = 11; - public static final int TITLE_2_ROW_BOTTOM_2_COLUMN_BODY = 12; - public static final int TITLE_2_ROW_TOP_2_COLUMN_BODY = 13; - public static final int FOUR_OBJECTS = 14; - public static final int BIG_OBJECT = 15; - public static final int BLANK_SLIDE = 16; - public static final int VERTICAL_TITLE_BODY_LEFT = 17; - public static final int VERTICAL_TITLE_2_ROW_BODY_LEFT = 17; - - /** What geometry type we are */ - private int geometry; - /** What placeholder IDs we have */ - private byte[] placeholderIDs; - - /** Retrieve the geometry type */ - public int getGeometryType() { return geometry; } - /** Set the geometry type */ - public void setGeometryType(int geom) { geometry = geom; } - - /** - * Create a new Embeded SSlideLayoutAtom, from 12 bytes of data - */ - public SSlideLayoutAtom(byte[] data) { - if(data.length != 12) { - throw new RuntimeException("SSlideLayoutAtom created with byte array not 12 bytes long - was " + data.length + " bytes in size"); - } - - // Grab out our data - geometry = LittleEndian.getInt(data,0); - placeholderIDs = new byte[8]; - System.arraycopy(data,4,placeholderIDs,0,8); - } - - /** - * Write the contents of the record back, so it can be written - * to disk. Skips the record header - */ - public void writeOut(OutputStream out) throws IOException { - // Write the geometry - writeLittleEndian(geometry,out); - // Write the placeholder IDs - out.write(placeholderIDs); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlideListWithText.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlideListWithText.java deleted file mode 100644 index deeee6fe6..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlideListWithText.java +++ /dev/null @@ -1,202 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.util.LittleEndian; - -/** - * These are tricky beasts. They contain the text of potentially - * many (normal) slides. They are made up of several sets of - * - SlidePersistAtom - * - TextHeaderAtom - * - TextBytesAtom / TextCharsAtom - * - StyleTextPropAtom (optional) - * - TextSpecInfoAtom (optional) - * - InteractiveInfo (optional) - * - TxInteractiveInfoAtom (optional) - * and then the next SlidePersistAtom. - * - * Eventually, Slides will find the blocks that interest them from all - * the SlideListWithText entries, and refere to them - * - * For now, we scan through looking for interesting bits, then creating - * the helpful Sheet from model for them - * - * @author Nick Burch - */ - -// For now, pretend to be an atom -public final class SlideListWithText extends RecordContainer { - - /** - * Instance filed of the record header indicates that this SlideListWithText stores - * references to slides - */ - public static final int SLIDES = 0; - /** - * Instance filed of the record header indicates that this SlideListWithText stores - * references to master slides - */ - public static final int MASTER = 1; - /** - * Instance filed of the record header indicates that this SlideListWithText stores - * references to notes - */ - public static final int NOTES = 2; - - private byte[] _header; - private static long _type = 4080; - - private SlideAtomsSet[] slideAtomsSets; - - /** - * Create a new holder for slide records - */ - protected SlideListWithText(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - - // Group our children together into SlideAtomsSets - // That way, model layer code can just grab the sets to use, - // without having to try to match the children together - List sets = new ArrayList(); - for(int i=0; i<_children.length; i++) { - if(_children[i] instanceof SlidePersistAtom) { - // Find where the next SlidePersistAtom is - int endPos = i+1; - while(endPos < _children.length && !(_children[endPos] instanceof SlidePersistAtom)) { - endPos += 1; - } - - int clen = endPos - i - 1; - - // Create a SlideAtomsSets, not caring if they're empty - //if(emptySet) { continue; } - Record[] spaChildren = new Record[clen]; - System.arraycopy(_children,i+1,spaChildren,0,clen); - SlideAtomsSet set = new SlideAtomsSet((SlidePersistAtom)_children[i],spaChildren); - sets.add(set); - - // Wind on - i += clen; - } - } - - // Turn the list into an array - slideAtomsSets = sets.toArray( new SlideAtomsSet[sets.size()] ); - } - - /** - * Create a new, empty, SlideListWithText - */ - public SlideListWithText(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 15); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 0); - - // We have no children to start with - _children = new Record[0]; - slideAtomsSets = new SlideAtomsSet[0]; - } - - /** - * Add a new SlidePersistAtom, to the end of the current list, - * and update the internal list of SlidePersistAtoms - * @param spa - */ - public void addSlidePersistAtom(SlidePersistAtom spa) { - // Add the new SlidePersistAtom at the end - appendChildRecord(spa); - - SlideAtomsSet newSAS = new SlideAtomsSet(spa, new Record[0]); - - // Update our SlideAtomsSets with this - SlideAtomsSet[] sas = new SlideAtomsSet[slideAtomsSets.length+1]; - System.arraycopy(slideAtomsSets, 0, sas, 0, slideAtomsSets.length); - sas[sas.length-1] = newSAS; - slideAtomsSets = sas; - } - - public int getInstance(){ - return LittleEndian.getShort(_header, 0) >> 4; - } - - public void setInstance(int inst){ - LittleEndian.putShort(_header, 0, (short)((inst << 4) | 0xF)); - } - - /** - * Get access to the SlideAtomsSets of the children of this record - */ - public SlideAtomsSet[] getSlideAtomsSets() { - return slideAtomsSets; - } - - /** - * Get access to the SlideAtomsSets of the children of this record - */ - public void setSlideAtomsSets( SlideAtomsSet[] sas ) { - slideAtomsSets = sas.clone(); - } - - /** - * Return the value we were given at creation - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],_type,_children,out); - } - - /** - * Inner class to wrap up a matching set of records that hold the - * text for a given sheet. Contains the leading SlidePersistAtom, - * and all of the records until the next SlidePersistAtom. This - * includes sets of TextHeaderAtom and TextBytesAtom/TextCharsAtom, - * along with some others. - */ - public static class SlideAtomsSet { - private SlidePersistAtom slidePersistAtom; - private Record[] slideRecords; - - /** Get the SlidePersistAtom, which gives details on the Slide this text is associated with */ - public SlidePersistAtom getSlidePersistAtom() { return slidePersistAtom; } - /** Get the Text related records for this slide */ - public Record[] getSlideRecords() { return slideRecords; } - - /** Create one to hold the Records for one Slide's text */ - public SlideAtomsSet(SlidePersistAtom s, Record[] r) { - slidePersistAtom = s; - slideRecords = r.clone(); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlidePersistAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlidePersistAtom.java deleted file mode 100644 index 0ac22adf3..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SlidePersistAtom.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A SlidePersist Atom (type 1011). Holds information on the text of a - * given slide, which are stored in the same SlideListWithText - * - * @author Nick Burch - */ -public final class SlidePersistAtom extends RecordAtom { - private byte[] _header; - private static long _type = 1011l; - - /** - * Slide reference ID. Should correspond to the PersistPtr - * "sheet ID" of the matching slide/notes record - */ - private int refID; - private boolean hasShapesOtherThanPlaceholders; - /** Number of placeholder texts that will follow in the SlideListWithText */ - private int numPlaceholderTexts; - /** - * The internal identifier (256+), which is used to tie slides - * and notes together - */ - private int slideIdentifier; - /** Reserved fields. Who knows what they do */ - private byte[] reservedFields; - - public int getRefID() { return refID; } - public int getSlideIdentifier() { return slideIdentifier; } - public int getNumPlaceholderTexts() { return numPlaceholderTexts; } - public boolean getHasShapesOtherThanPlaceholders() { return hasShapesOtherThanPlaceholders; } - - // Only set these if you know what you're doing! - public void setRefID(int id) { - refID = id; - } - public void setSlideIdentifier(int id) { - slideIdentifier = id; - } - - /* *************** record code follows ********************** */ - - /** - * For the SlidePersist Atom - */ - protected SlidePersistAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 8) { len = 8; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the reference ID - refID = LittleEndian.getInt(source,start+8); - - // Next up is a set of flags, but only bit 3 is used! - int flags = LittleEndian.getInt(source,start+12); - if(flags == 4) { - hasShapesOtherThanPlaceholders = true; - } else { - hasShapesOtherThanPlaceholders = false; - } - - // Now the number of Placeholder Texts - numPlaceholderTexts = LittleEndian.getInt(source,start+16); - - // Last useful one is the unique slide identifier - slideIdentifier = LittleEndian.getInt(source,start+20); - - // Finally you have typically 4 or 8 bytes of reserved fields, - // all zero running from 24 bytes in to the end - reservedFields = new byte[len-24]; - System.arraycopy(source,start+24,reservedFields,0,reservedFields.length); - } - - /** - * Create a new SlidePersistAtom, for use with a new Slide - */ - public SlidePersistAtom(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 20); - - hasShapesOtherThanPlaceholders = true; - reservedFields = new byte[4]; - } - - /** - * We are of type 1011 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - - // Compute the flags part - only bit 3 is used - int flags = 0; - if(hasShapesOtherThanPlaceholders) { - flags = 4; - } - - // Write out our fields - writeLittleEndian(refID,out); - writeLittleEndian(flags,out); - writeLittleEndian(numPlaceholderTexts,out); - writeLittleEndian(slideIdentifier,out); - out.write(reservedFields); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Sound.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Sound.java deleted file mode 100644 index f454e4d20..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Sound.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.POILogger; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * A container holding information about a sound. It contains: - *

        - *

      • 1. CString (4026), Instance 0: Name of sound (e.g. "crash") - *
      • 2. CString (4026), Instance 1: Type of sound (e.g. ".wav") - *
      • 3. CString (4026), Instance 2: Reference id of sound in sound collection - *
      • 4. CString (4026), Instance 3, optional: Built-in id of sound, for sounds we ship. This is the id that?s in the reg file. - *
      • 5. SoundData (2023), optional - *

        - * - * @author Yegor Kozlov - */ -public final class Sound extends RecordContainer { - /** - * Record header data. - */ - private byte[] _header; - - // Links to our more interesting children - private CString _name; - private CString _type; - private SoundData _data; - - - /** - * Set things up, and find our more interesting children - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected Sound(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - findInterestingChildren(); - } - - private void findInterestingChildren() { - // First child should be the ExHyperlinkAtom - if(_children[0] instanceof CString) { - _name = (CString)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a CString, was of type " + _children[0].getRecordType()); - } - - // Second child should be the ExOleObjAtom - if (_children[1] instanceof CString) { - _type = (CString)_children[1]; - } else { - logger.log(POILogger.ERROR, "Second child record wasn't a CString, was of type " + _children[1].getRecordType()); - } - - for (int i = 2; i < _children.length; i++) { - if(_children[i] instanceof SoundData){ - _data = (SoundData)_children[i]; - break; - } - } - - } - - /** - * Returns the type (held as a little endian in bytes 3 and 4) - * that this class handles. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.Sound.typeID; - } - - /** - * Have the contents printer out into an OutputStream, used when - * writing a file back out to disk. - * - * @param out the output stream. - * @throws java.io.IOException if there was an error writing to the stream. - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } - - /** - * Name of the sound (e.g. "crash") - * - * @return name of the sound - */ - public String getSoundName(){ - return _name.getText(); - } - - /** - * Type of the sound (e.g. ".wav") - * - * @return type of the sound - */ - public String getSoundType(){ - return _type.getText(); - } - - /** - * The sound data - * - * @return the sound data. - */ - public byte[] getSoundData(){ - return _data == null ? null : _data.getData(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java deleted file mode 100644 index abea3887f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * Is a container for all sound related atoms and containers. It contains: - *
      • 1. SoundCollAtom (2021) - *
      • 2. Sound (2022), for each sound, if any - * - * @author Yegor Kozlov - */ -public final class SoundCollection extends RecordContainer { - /** - * Record header data. - */ - private byte[] _header; - - /** - * Set things up, and find our more interesting children - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected SoundCollection(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Find our children - _children = Record.findChildRecords(source,start+8,len-8); - } - - /** - * Returns the type (held as a little endian in bytes 3 and 4) - * that this class handles. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.SoundCollection.typeID; - } - - /** - * Have the contents printer out into an OutputStream, used when - * writing a file back out to disk. - * - * @param out the output stream. - * @throws java.io.IOException if there was an error writing to the stream. - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0],_header[1],getRecordType(),_children,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java deleted file mode 100644 index 32aa9592d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * Storage for embedded sounds. - * - * @author Yegor Kozlov - */ -public final class SoundData extends RecordAtom { - - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a new empty sound container. - */ - protected SoundData() { - _header = new byte[8]; - _data = new byte[0]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected SoundData(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - } - - /** - * Returns the sound data. - * - * @return the sound data - */ - public byte[] getData() { - return _data; - } - - /** - * Gets the record type. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.SoundData.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk. - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextProp9Atom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextProp9Atom.java deleted file mode 100644 index 9a5cc7b48..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextProp9Atom.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.LinkedList; -import java.util.List; - -import org.apache.poi.hslf.model.textproperties.TextPFException9; -import org.apache.poi.util.LittleEndian; - -/** - * The atom record that specifies additional text formatting. - */ -public final class StyleTextProp9Atom extends RecordAtom { - private final TextPFException9[] autoNumberSchemes; - /** Record header. */ - private byte[] header; - /** Record data. */ - private byte[] data; - private short version; - private short recordId; - private int length; - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected StyleTextProp9Atom(byte[] source, int start, int len) { - // Get the header. - final List schemes = new LinkedList(); - header = new byte[8]; - System.arraycopy(source,start, header,0,8); - this.version = LittleEndian.getShort(header, 0); - this.recordId = LittleEndian.getShort(header, 2); - this.length = LittleEndian.getInt(header, 4); - - // Get the record data. - data = new byte[len-8]; - System.arraycopy(source, start+8, data, 0, len-8); - for (int i = 0; i < data.length; ) { - final TextPFException9 item = new TextPFException9(data, i); - schemes.add(item); - i += item.getRecordLength(); - - if (i+4 >= data.length) { - break; - } - int textCfException9 = LittleEndian.getInt(data, i ); - i += 4; - //TODO analyze textCfException when have some test data - - if (i+4 >= data.length) { - break; - } - int textSiException = LittleEndian.getInt(data, i ); - i += 4;//TextCFException9 + SIException - - if (0 != (textSiException & 0x40)) { - i += 2; //skip fBidi - } - if (i+4 >= data.length) { - break; - } - } - this.autoNumberSchemes = schemes.toArray(new TextPFException9[schemes.size()]); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return this.recordId; } - - public short getVersion() { - return version; - } - - public int getLength() { - return length; - } - public TextPFException9[] getAutoNumberTypes() { - return this.autoNumberSchemes; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(header); - out.write(data); - } - - /** - * Update the text length - * - * @param size the text length - */ - public void setTextSize(int size){ - LittleEndian.putInt(data, 0, size); - } - - /** - * Reset the content to one info run with the default values - * @param size the site of parent text - */ - public void reset(int size){ - data = new byte[10]; - // 01 00 00 00 - LittleEndian.putInt(data, 0, size); - // 01 00 00 00 - LittleEndian.putInt(data, 4, 1); //mask - // 00 00 - LittleEndian.putShort(data, 8, (short)0); //langId - - // Update the size (header bytes 5-8) - LittleEndian.putInt(header, 4, data.length); - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java deleted file mode 100644 index bfb9d741a..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java +++ /dev/null @@ -1,399 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.model.textproperties.*; -import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; -import org.apache.poi.util.*; - -/** - * A StyleTextPropAtom (type 4001). Holds basic character properties - * (bold, italic, underline, font size etc) and paragraph properties - * (alignment, line spacing etc) for the block of text (TextBytesAtom - * or TextCharsAtom) that this record follows. - * You will find two lists within this class. - * 1 - Paragraph style list (paragraphStyles) - * 2 - Character style list (charStyles) - * Both are lists of TextPropCollections. These define how many characters - * the style applies to, and what style elements make up the style (another - * list, this time of TextProps). Each TextProp has a value, which somehow - * encapsulates a property of the style - * - * @author Nick Burch - * @author Yegor Kozlov - */ - -public final class StyleTextPropAtom extends RecordAtom -{ - private byte[] _header; - private static final long _type = RecordTypes.StyleTextPropAtom.typeID; - private byte[] reserved; - - private byte[] rawContents; // Holds the contents between write-outs - - /** - * Only set to true once setParentTextSize(int) is called. - * Until then, no stylings will have been decoded - */ - private boolean initialised = false; - - /** - * The list of all the different paragraph stylings we code for. - * Each entry is a TextPropCollection, which tells you how many - * Characters the paragraph covers, and also contains the TextProps - * that actually define the styling of the paragraph. - */ - private List paragraphStyles; - public List getParagraphStyles() { return paragraphStyles; } - /** - * Updates the link list of TextPropCollections which make up the - * paragraph stylings - */ - public void setParagraphStyles(List ps) { paragraphStyles = ps; } - /** - * The list of all the different character stylings we code for. - * Each entry is a TextPropCollection, which tells you how many - * Characters the character styling covers, and also contains the - * TextProps that actually define the styling of the characters. - */ - private List charStyles; - public List getCharacterStyles() { return charStyles; } - /** - * Updates the link list of TextPropCollections which make up the - * character stylings - */ - public void setCharacterStyles(List cs) { charStyles = cs; } - - /** - * Returns how many characters the paragraph's - * TextPropCollections cover. - * (May be one or two more than the underlying text does, - * due to having extra characters meaning something - * special to powerpoint) - */ - public int getParagraphTextLengthCovered() { - return getCharactersCovered(paragraphStyles); - } - /** - * Returns how many characters the character's - * TextPropCollections cover. - * (May be one or two more than the underlying text does, - * due to having extra characters meaning something - * special to powerpoint) - */ - public int getCharacterTextLengthCovered() { - return getCharactersCovered(charStyles); - } - private int getCharactersCovered(List styles) { - int length = 0; - for(TextPropCollection tpc : styles) { - length += tpc.getCharactersCovered(); - } - return length; - } - - /* *************** record code follows ********************** */ - - /** - * For the Text Style Properties (StyleTextProp) Atom - */ - public StyleTextPropAtom(byte[] source, int start, int len) { - // Sanity Checking - we're always at least 8+10 bytes long - if(len < 18) { - len = 18; - if(source.length - start < 18) { - throw new RuntimeException("Not enough data to form a StyleTextPropAtom (min size 18 bytes long) - found " + (source.length - start)); - } - } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Save the contents of the atom, until we're asked to go and - // decode them (via a call to setParentTextSize(int) - rawContents = new byte[len-8]; - System.arraycopy(source,start+8,rawContents,0,rawContents.length); - reserved = new byte[0]; - - // Set empty lists, ready for when they call setParentTextSize - paragraphStyles = new ArrayList(); - charStyles = new ArrayList(); - } - - - /** - * A new set of text style properties for some text without any. - */ - public StyleTextPropAtom(int parentTextSize) { - _header = new byte[8]; - rawContents = new byte[0]; - reserved = new byte[0]; - - // Set our type - LittleEndian.putInt(_header,2,(short)_type); - // Our initial size is 10 - LittleEndian.putInt(_header,4,10); - - // Set empty paragraph and character styles - paragraphStyles = new ArrayList(); - charStyles = new ArrayList(); - - addParagraphTextPropCollection(parentTextSize); - addCharacterTextPropCollection(parentTextSize); - - // Set us as now initialised - initialised = true; - - try { - updateRawContents(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - - /** - * We are of type 4001 - */ - public long getRecordType() { return _type; } - - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // First thing to do is update the raw bytes of the contents, based - // on the properties - updateRawContents(); - - // Write out the (new) header - out.write(_header); - - // Write out the styles - out.write(rawContents); - - // Write out any extra bits - out.write(reserved); - } - - - /** - * Tell us how much text the parent TextCharsAtom or TextBytesAtom - * contains, so we can go ahead and initialise ourselves. - */ - public void setParentTextSize(int size) { - if (initialised) return; - - int pos = 0; - int textHandled = 0; - - paragraphStyles.clear(); - charStyles.clear(); - - // While we have text in need of paragraph stylings, go ahead and - // grok the contents as paragraph formatting data - int prsize = size; - while(pos < rawContents.length && textHandled < prsize) { - // First up, fetch the number of characters this applies to - int textLen = LittleEndian.getInt(rawContents,pos); - textLen = checkTextLength(textLen, textHandled, size); - textHandled += textLen; - pos += 4; - - short indent = LittleEndian.getShort(rawContents,pos); - pos += 2; - - // Grab the 4 byte value that tells us what properties follow - int paraFlags = LittleEndian.getInt(rawContents,pos); - pos += 4; - - // Now make sense of those properties - TextPropCollection thisCollection = new TextPropCollection(textLen, TextPropType.paragraph); - thisCollection.setIndentLevel(indent); - int plSize = thisCollection.buildTextPropList(paraFlags, rawContents, pos); - pos += plSize; - - // Save this properties set - paragraphStyles.add(thisCollection); - - // Handle extra 1 paragraph styles at the end - if(pos < rawContents.length && textHandled == size) { - prsize++; - } - - } - if (rawContents.length > 0 && textHandled != (size+1)){ - logger.log(POILogger.WARN, "Problem reading paragraph style runs: textHandled = " + textHandled + ", text.size+1 = " + (size+1)); - } - - // Now do the character stylings - textHandled = 0; - int chsize = size; - while(pos < rawContents.length && textHandled < chsize) { - // First up, fetch the number of characters this applies to - int textLen = LittleEndian.getInt(rawContents,pos); - textLen = checkTextLength(textLen, textHandled, size); - textHandled += textLen; - pos += 4; - - // Grab the 4 byte value that tells us what properties follow - int charFlags = LittleEndian.getInt(rawContents,pos); - pos += 4; - - // Now make sense of those properties - // (Assuming we actually have some) - TextPropCollection thisCollection = new TextPropCollection(textLen, TextPropType.character); - int chSize = thisCollection.buildTextPropList(charFlags, rawContents, pos); - pos += chSize; - - // Save this properties set - charStyles.add(thisCollection); - - // Handle extra 1 char styles at the end - if(pos < rawContents.length && textHandled == size) { - chsize++; - } - } - if (rawContents.length > 0 && textHandled != (size+1)){ - logger.log(POILogger.WARN, "Problem reading character style runs: textHandled = " + textHandled + ", text.size+1 = " + (size+1)); - } - - // Handle anything left over - if(pos < rawContents.length) { - reserved = new byte[rawContents.length-pos]; - System.arraycopy(rawContents,pos,reserved,0,reserved.length); - } - - initialised = true; - } - - private int checkTextLength(int readLength, int handledSoFar, int overallSize) { - if (readLength + handledSoFar > overallSize + 1) { - logger.log(POILogger.WARN, "Style length of " + readLength + " at " + handledSoFar + - " larger than stated size of " + overallSize + ", truncating"); - return overallSize + 1 - handledSoFar; - } - return readLength; - } - - - /** - * Updates the cache of the raw contents. Serialised the styles out. - */ - private void updateRawContents() throws IOException { - if (initialised) { - // Only update the style bytes, if the styles have been potentially - // changed - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - // First up, we need to serialise the paragraph properties - for(TextPropCollection tpc : paragraphStyles) { - tpc.writeOut(baos); - } - - // Now, we do the character ones - for(TextPropCollection tpc : charStyles) { - tpc.writeOut(baos); - } - - rawContents = baos.toByteArray(); - } - - // Now ensure that the header size is correct - int newSize = rawContents.length + reserved.length; - LittleEndian.putInt(_header,4,newSize); - } - - /** - * Clear styles, so new collections can be added - */ - public void clearStyles() { - paragraphStyles.clear(); - charStyles.clear(); - reserved = new byte[0]; - initialised = true; - } - - /** - * Create a new Paragraph TextPropCollection, and add it to the list - * @param charactersCovered The number of characters this TextPropCollection will cover - * @return the new TextPropCollection, which will then be in the list - */ - public TextPropCollection addParagraphTextPropCollection(int charactersCovered) { - TextPropCollection tpc = new TextPropCollection(charactersCovered, TextPropType.paragraph); - paragraphStyles.add(tpc); - return tpc; - } - /** - * Create a new Character TextPropCollection, and add it to the list - * @param charactersCovered The number of characters this TextPropCollection will cover - * @return the new TextPropCollection, which will then be in the list - */ - public TextPropCollection addCharacterTextPropCollection(int charactersCovered) { - TextPropCollection tpc = new TextPropCollection(charactersCovered, TextPropType.character); - charStyles.add(tpc); - return tpc; - } - - /* ************************************************************************ */ - - - /** - * Dump the record content into StringBuffer - * - * @return the string representation of the record data - */ - public String toString(){ - StringBuffer out = new StringBuffer(); - - out.append("StyleTextPropAtom:\n"); - if (!initialised) { - out.append("Uninitialised, dumping Raw Style Data\n"); - } else { - - out.append("Paragraph properties\n"); - for(TextPropCollection pr : getParagraphStyles()) { - out.append(pr); - } - - out.append("Character properties\n"); - for(TextPropCollection pr : getCharacterStyles()) { - out.append(pr); - } - - out.append("Reserved bytes\n"); - out.append( HexDump.dump(reserved, 0, 0) ); - } - - out.append(" original byte stream \n"); - - byte buf[] = new byte[rawContents.length+reserved.length]; - System.arraycopy(rawContents, 0, buf, 0, rawContents.length); - System.arraycopy(reserved, 0, buf, rawContents.length, reserved.length); - out.append( HexDump.dump(buf, 0, 0) ); - - return out.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java deleted file mode 100644 index 43a5abf8a..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A TextBytesAtom (type 4008). Holds text in ascii form (unknown - * code page, for now assumed to be the default of - * org.apache.poi.util.StringUtil, which is the Excel default). - * The trailing return character is always stripped from this - * - * @author Nick Burch - */ - -public final class TextBytesAtom extends RecordAtom -{ - private byte[] _header; - private static long _type = RecordTypes.TextBytesAtom.typeID; - - /** The bytes that make up the text */ - private byte[] _text; - - /** Grabs the text. Uses the default codepage */ - public String getText() { - return StringUtil.getFromCompressedUnicode(_text,0,_text.length); - } - - /** Updates the text in the Atom. Must be 8 bit ascii */ - public void setText(byte[] b) { - // Set the text - _text = b.clone(); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header,4,_text.length); - } - - /* *************** record code follows ********************** */ - - /** - * For the TextBytes Atom - */ - protected TextBytesAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 8) { len = 8; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the text - _text = new byte[len-8]; - System.arraycopy(source,start+8,_text,0,len-8); - } - - /** - * Create an empty TextBytes Atom - */ - public TextBytesAtom() { - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 0); - - _text = new byte[]{}; - } - - /** - * We are of type 4008 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - - // Write out our text - out.write(_text); - } - - /** - * dump debug info; use getText() to return a string - * representation of the atom - */ - public String toString() { - StringBuffer out = new StringBuffer(); - out.append( "TextBytesAtom:\n"); - out.append( HexDump.dump(_text, 0, 0) ); - return out.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java deleted file mode 100644 index 3449250ad..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java +++ /dev/null @@ -1,110 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A TextCharsAtom (type 4000). Holds text in byte swapped unicode form. - * The trailing return character is always stripped from this - * - * @author Nick Burch - */ - -public final class TextCharsAtom extends RecordAtom -{ - private byte[] _header; - private static long _type = RecordTypes.TextCharsAtom.typeID; - - /** The bytes that make up the text */ - private byte[] _text; - - /** Grabs the text. */ - public String getText() { - return StringUtil.getFromUnicodeLE(_text); - } - - /** Updates the text in the Atom. */ - public void setText(String text) { - // Convert to little endian unicode - _text = new byte[text.length()*2]; - StringUtil.putUnicodeLE(text,_text,0); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header,4,_text.length); - } - - /* *************** record code follows ********************** */ - - /** - * For the TextChars Atom - */ - protected TextCharsAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 8) { len = 8; } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the text - _text = new byte[len-8]; - System.arraycopy(source,start+8,_text,0,len-8); - } - /** - * Create an empty TextCharsAtom - */ - public TextCharsAtom() { - // 0 length header - _header = new byte[] { 0, 0, 0xA0-256, 0x0f, 0, 0, 0, 0 }; - // Empty text - _text = new byte[0]; - } - - /** - * We are of type 4000 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - - // Write out our text - out.write(_text); - } - - /** - * dump debug info; use getText() to return a string - * representation of the atom - */ - public String toString() { - StringBuffer out = new StringBuffer(); - out.append( "TextCharsAtom:\n"); - out.append( HexDump.dump(_text, 0, 0) ); - return out.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java deleted file mode 100644 index 3fab236a1..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * A TextHeaderAtom (type 3999). Holds information on what kind of - * text is contained in the TextBytesAtom / TextCharsAtom that follows - * straight after - * - * @author Nick Burch - */ - -public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecord -{ - private byte[] _header; - private static long _type = RecordTypes.TextHeaderAtom.typeID; - private RecordContainer parentRecord; - - public static final int TITLE_TYPE = 0; - public static final int BODY_TYPE = 1; - public static final int NOTES_TYPE = 2; - public static final int OTHER_TYPE = 4; - public static final int CENTRE_BODY_TYPE = 5; - public static final int CENTER_TITLE_TYPE = 6; - public static final int HALF_BODY_TYPE = 7; - public static final int QUARTER_BODY_TYPE = 8; - - /** The kind of text it is */ - private int textType; - /** position in the owning SlideListWithText */ - private int index = -1; - - public int getTextType() { return textType; } - public void setTextType(int type) { textType = type; } - - /** - * @return 0-based index of the text run in the SLWT container - */ - public int getIndex() { return index; } - - /** - * @param index 0-based index of the text run in the SLWT container - */ - public void setIndex(int index) { this.index = index; } - - public RecordContainer getParentRecord() { return parentRecord; } - public void setParentRecord(RecordContainer record) { this.parentRecord = record; } - - /* *************** record code follows ********************** */ - - /** - * For the TextHeader Atom - */ - protected TextHeaderAtom(byte[] source, int start, int len) { - // Sanity Checking - we're always 12 bytes long - if(len < 12) { - len = 12; - if(source.length - start < 12) { - throw new RuntimeException("Not enough data to form a TextHeaderAtom (always 12 bytes long) - found " + (source.length - start)); - } - } - - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the type - textType = LittleEndian.getInt(source,start+8); - } - - /** - * Create a new TextHeader Atom, for an unknown type of text - */ - public TextHeaderAtom() { - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)_type); - LittleEndian.putInt(_header, 4, 4); - - textType = OTHER_TYPE; - } - - /** - * We are of type 3999 - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - size or type unchanged - out.write(_header); - - // Write out our type - writeLittleEndian(textType,out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java deleted file mode 100644 index 9b40a9893..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java +++ /dev/null @@ -1,204 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; - -/** - * Ruler of a text as it differs from the style's ruler settings. - */ -public final class TextRulerAtom extends RecordAtom { - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - //ruler internals - private int defaultTabSize; - private int numLevels; - private int[] tabStops; - private int[] bulletOffsets = new int[5]; - private int[] textOffsets = new int[5]; - - /** - * Constructs a new empty ruler atom. - */ - public TextRulerAtom() { - _header = new byte[8]; - _data = new byte[0]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Constructs the ruler atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected TextRulerAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - try { - read(); - } catch (Exception e){ - logger.log(POILogger.ERROR, "Failed to parse TextRulerAtom: " + e.getMessage()); - } - } - - /** - * Gets the record type. - * - * @return the record type. - */ - public long getRecordType() { - return RecordTypes.TextRulerAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written - * to disk. - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } - - /** - * Read the record bytes and initialize the internal variables - */ - private void read(){ - int pos = 0; - short mask = LittleEndian.getShort(_data); pos += 4; - short val; - int[] bits = {1, 0, 2, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12}; - for (int i = 0; i < bits.length; i++) { - if((mask & 1 << bits[i]) != 0){ - switch (bits[i]){ - case 0: - //defaultTabSize - defaultTabSize = LittleEndian.getShort(_data, pos); pos += 2; - break; - case 1: - //numLevels - numLevels = LittleEndian.getShort(_data, pos); pos += 2; - break; - case 2: - //tabStops - val = LittleEndian.getShort(_data, pos); pos += 2; - tabStops = new int[val*2]; - for (int j = 0; j < tabStops.length; j++) { - tabStops[j] = LittleEndian.getUShort(_data, pos); pos += 2; - } - break; - case 3: - case 4: - case 5: - case 6: - case 7: - //bullet.offset - val = LittleEndian.getShort(_data, pos); pos += 2; - bulletOffsets[bits[i]-3] = val; - break; - case 8: - case 9: - case 10: - case 11: - case 12: - //text.offset - val = LittleEndian.getShort(_data, pos); pos += 2; - textOffsets[bits[i]-8] = val; - break; - default: - break; - } - } - } - } - - /** - * Default distance between tab stops, in master coordinates (576 dpi). - */ - public int getDefaultTabSize(){ - return defaultTabSize; - } - - /** - * Number of indent levels (maximum 5). - */ - public int getNumberOfLevels(){ - return numLevels; - } - - /** - * Default distance between tab stops, in master coordinates (576 dpi). - */ - public int[] getTabStops(){ - return tabStops; - } - - /** - * Paragraph's distance from shape's left margin, in master coordinates (576 dpi). - */ - public int[] getTextOffsets(){ - return textOffsets; - } - - /** - * First line of paragraph's distance from shape's left margin, in master coordinates (576 dpi). - */ - public int[] getBulletOffsets(){ - return bulletOffsets; - } - - public static TextRulerAtom getParagraphInstance(){ - byte[] data = new byte[] { - 0x00, 0x00, (byte)0xA6, 0x0F, 0x0A, 0x00, 0x00, 0x00, - 0x10, 0x03, 0x00, 0x00, (byte)0xF9, 0x00, 0x41, 0x01, 0x41, 0x01 - }; - TextRulerAtom ruler = new TextRulerAtom(data, 0, data.length); - return ruler; - } - - public void setParagraphIndent(short tetxOffset, short bulletOffset){ - LittleEndian.putShort(_data, 4, tetxOffset); - LittleEndian.putShort(_data, 6, bulletOffset); - LittleEndian.putShort(_data, 8, bulletOffset); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java deleted file mode 100644 index df0b323f2..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java +++ /dev/null @@ -1,171 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayInputStream; - -/** - * The special info runs contained in this text. - * Special info runs consist of character properties which don?t follow styles. - * - * @author Yegor Kozlov - */ -public final class TextSpecInfoAtom extends RecordAtom { - private static final long _type = RecordTypes.TextSpecInfoAtom.typeID; - - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs an empty atom, with a default run of size 1 - */ - public TextSpecInfoAtom() { - _header = new byte[8]; - LittleEndian.putUInt(_header, 4, _type); - reset(1); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - public TextSpecInfoAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - } - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } - - /** - * Update the text length - * - * @param size the text length - */ - public void setTextSize(int size){ - LittleEndian.putInt(_data, 0, size); - } - - /** - * Reset the content to one info run with the default values - * @param size the site of parent text - */ - public void reset(int size){ - TextSpecInfoRun sir = new TextSpecInfoRun(size); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - sir.writeOut(bos); - } catch (IOException e) { - throw new RuntimeException(e); - } - _data = bos.toByteArray(); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Adapts the size by enlarging the last {@link TextSpecInfoRun} - * or chopping the runs to the given length - * - * @param size - */ - public void setParentSize(int size) { - assert(size > 0); - int covered = 0; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - TextSpecInfoRun runs[] = getTextSpecInfoRuns(); - assert(runs.length > 0); - for (int i=0; i size || i == runs.length-1) { - run.setLength(size-covered); - } - covered += run.getLength(); - try { - run.writeOut(bos); - } catch (IOException e) { - throw new HSLFException(e); - } - } - _data = bos.toByteArray(); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Get the number of characters covered by this records - * - * @return the number of characters covered by this records - */ - public int getCharactersCovered(){ - int covered = 0; - for (TextSpecInfoRun r : getTextSpecInfoRuns()) covered += r.length; - return covered; - } - - public TextSpecInfoRun[] getTextSpecInfoRuns(){ - LittleEndianByteArrayInputStream bis = new LittleEndianByteArrayInputStream(_data); - List lst = new ArrayList(); - while (bis.available() > 0) { - lst.add(new TextSpecInfoRun(bis)); - } - return lst.toArray(new TextSpecInfoRun[lst.size()]); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoRun.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoRun.java deleted file mode 100644 index 7b4150a4f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoRun.java +++ /dev/null @@ -1,346 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.*; - -public class TextSpecInfoRun { - /** - * A enum that specifies the spelling status of a run of text. - */ - public enum SpellInfoEnum { - /** the text is spelled incorrectly. */ - error(new BitField(1)), - /** the text needs rechecking. */ - clean(new BitField(2)), - /** the text has a grammar error. */ - grammar(new BitField(4)), - /** the text is spelled correct */ - correct(new BitField(0)); - - final BitField bitField; - - SpellInfoEnum(BitField bitField) { - this.bitField = bitField; - } - } - - /** A bit that specifies whether the spellInfo field exists. */ - private static final BitField spellFld = new BitField(0X00000001); - /** A bit that specifies whether the lid field exists. */ - private static final BitField langFld = new BitField(0X00000002); - /** A bit that specifies whether the altLid field exists. */ - private static final BitField altLangFld = new BitField(0X00000004); - // unused1, unused2 - Undefined and MUST be ignored. - /** A bit that specifies whether the pp10runid, reserved3, and grammarError fields exist. */ - private static final BitField pp10extFld = new BitField(0X00000020); - /** A bit that specifies whether the bidi field exists. */ - private static final BitField bidiFld = new BitField(0X00000040); - // unused3 - Undefined and MUST be ignored. - // reserved1 - MUST be zero and MUST be ignored. - /** A bit that specifies whether the smartTags field exists. */ - private static final BitField smartTagFld = new BitField(0X00000200); - // reserved2 - MUST be zero and MUST be ignored. - - /** - * An optional unsigned integer that specifies an identifier for a character - * run that contains StyleTextProp11 data. It MUST exist if and only if pp10ext is TRUE. - **/ - private static final BitField pp10runidFld = new BitField(0X0000000F); - // reserved3 - An optional unsigned integer that MUST be zero, and MUST be ignored. It - // MUST exist if and only if fPp10ext is TRUE. - /** - * An optional bit that specifies a grammar error. It MUST exist if and - * only if fPp10ext is TRUE. - **/ - private static final BitField grammarErrorFld = new BitField(0X80000000); - - //Length of special info run. - protected int length; - - //Special info mask of this run; - protected int mask; - - // info fields as indicated by the mask. - // -1 means the bit is not set - - /** - * An optional SpellingFlags structure that specifies the spelling status of this - * text. It MUST exist if and only if spell is TRUE. - * The spellInfo.grammar sub-field MUST be zero. - *
        - * error (1 bit): A bit that specifies whether the text is spelled incorrectly.
        - * clean (1 bit): A bit that specifies whether the text needs rechecking.
        - * grammar (1 bit): A bit that specifies whether the text has a grammar error.
        - * reserved (13 bits): MUST be zero and MUST be ignored. - */ - protected short spellInfo = -1; - - /** - * An optional TxLCID that specifies the language identifier of this text. - * It MUST exist if and only if lang is TRUE. - *
        - * 0x0000 = No language.
        - * 0x0013 = Any Dutch language is preferred over non-Dutch languages when proofing the text.
        - * 0x0400 = No proofing is performed on the text.
        - * > 0x0400 = A valid LCID as specified by [MS-LCID]. - */ - protected short langId = -1; - - /** - * An optional TxLCID that specifies the alternate language identifier of this text. - * It MUST exist if and only if altLang is TRUE. - */ - protected short altLangId = -1; - - /** - * An optional signed integer that specifies whether the text contains bidirectional - * characters. It MUST exist if and only if fBidi is TRUE. - * 0x0000 = Contains no bidirectional characters, - * 0x0001 = Contains bidirectional characters. - */ - protected short bidi = -1; - - protected int pp10extMask = -1; - protected byte[] smartTagsBytes = null; - - /** - * Inits a TextSpecInfoRun with default values - * - * @param len the length of the one and only run - */ - public TextSpecInfoRun(int len) { - setLength(len); - setLangId((short)0); - } - - public TextSpecInfoRun(LittleEndianByteArrayInputStream source) { - length = source.readInt(); - mask = source.readInt(); - if (spellFld.isSet(mask)) { - spellInfo = source.readShort(); - } - if (langFld.isSet(mask)) { - langId = source.readShort(); - } - if (altLangFld.isSet(mask)) { - altLangId = source.readShort(); - } - if (bidiFld.isSet(mask)) { - bidi = source.readShort(); - } - if (pp10extFld.isSet(mask)) { - pp10extMask = source.readInt(); - } - if (smartTagFld.isSet(mask)) { - // An unsigned integer specifies the count of items in rgSmartTagIndex. - int count = source.readInt(); - smartTagsBytes = new byte[4+count*4]; - LittleEndian.putInt(smartTagsBytes, 0, count); - // An array of SmartTagIndex that specifies the indices. - // The count of items in the array is specified by count. - source.readFully(smartTagsBytes, 4, count*4); - } - } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - final byte buf[] = new byte[4]; - LittleEndian.putInt(buf, 0, length); - out.write(buf); - LittleEndian.putInt(buf, 0, mask); - out.write(buf); - Object flds[] = { - spellFld, spellInfo, "spell info", - langFld, langId, "lang id", - altLangFld, altLangId, "alt lang id", - bidiFld, bidi, "bidi", - pp10extFld, pp10extMask, "pp10 extension field", - smartTagFld, smartTagsBytes, "smart tags" - }; - - for (int i=0; i 0; - out.write(bufB); - } else if (valO instanceof Integer) { - int valI = ((Integer)valO); - valid = (valI != -1); - LittleEndian.putInt(buf, 0, valI); - out.write(buf); - } else if (valO instanceof Short) { - short valS = ((Short)valO); - valid = (valS != -1); - LittleEndian.putShort(buf, 0, valS); - out.write(buf, 0, 2); - } else { - valid = false; - } - if (!valid) { - throw new IOException(flds[i+2]+" is activated, but its value is invalid"); - } - } - } - - /** - * @return Spelling status of this text. null if not defined. - */ - public SpellInfoEnum getSpellInfo(){ - if (spellInfo == -1) return null; - for (SpellInfoEnum si : new SpellInfoEnum[]{SpellInfoEnum.clean,SpellInfoEnum.error,SpellInfoEnum.grammar}) { - if (si.bitField.isSet(spellInfo)) return si; - } - return SpellInfoEnum.correct; - } - - /** - * @param spellInfo Spelling status of this text. null if not defined. - */ - public void setSpellInfo(SpellInfoEnum spellInfo) { - this.spellInfo = (spellInfo == null) - ? -1 - : (short)spellInfo.bitField.set(0); - mask = spellFld.setBoolean(mask, spellInfo != null); - } - - /** - * Windows LANGID for this text. - * - * @return Windows LANGID for this text, -1 if it's not set - */ - public short getLangId(){ - return langId; - } - - /** - * @param langId Windows LANGID for this text, -1 to unset - */ - public void setLangId(short langId) { - this.langId = langId; - mask = langFld.setBoolean(mask, langId != -1); - } - - /** - * Alternate Windows LANGID of this text; - * must be a valid non-East Asian LANGID if the text has an East Asian language, - * otherwise may be an East Asian LANGID or language neutral (zero). - * - * @return Alternate Windows LANGID of this text, -1 if it's not set - */ - public short getAltLangId(){ - return altLangId; - } - - public void setAltLangId(short altLangId) { - this.altLangId = altLangId; - mask = altLangFld.setBoolean(mask, altLangId != -1); - } - - /** - * @return Length of special info run. - */ - public int getLength() { - return length; - } - - /** - * @param length Length of special info run. - */ - public void setLength(int length) { - this.length = length; - } - - /** - * @return the bidirectional characters flag. false = not bidi, true = is bidi, null = not set - */ - public Boolean getBidi() { - return (bidi == -1 ? null : bidi != 0); - } - - /** - * @param bidi the bidirectional characters flag. false = not bidi, true = is bidi, null = not set - */ - public void setBidi(Boolean bidi) { - this.bidi = (bidi == null) ? -1 : (short)(bidi ? 1 : 0); - mask = bidiFld.setBoolean(mask, bidi != null); - } - - /** - * @return the unparsed smart tags - */ - public byte[] getSmartTagsBytes() { - return smartTagsBytes; - } - - /** - * @param smartTagsBytes the unparsed smart tags, null to unset - */ - public void setSmartTagsBytes(byte[] smartTagsBytes) { - this.smartTagsBytes = (smartTagsBytes == null) ? null : smartTagsBytes.clone(); - mask = smartTagFld.setBoolean(mask, smartTagsBytes != null); - } - - /** - * @return an identifier for a character run that contains StyleTextProp11 data. - */ - public int getPP10RunId() { - return (pp10extMask == -1 || !pp10extFld.isSet(mask)) ? -1 : pp10runidFld.getValue(pp10extMask); - - } - - /** - * @param pp10RunId an identifier for a character run that contains StyleTextProp11 data, -1 to unset - */ - public void setPP10RunId(int pp10RunId) { - if (pp10RunId == -1) { - pp10extMask = (getGrammarError() == null) ? -1 : pp10runidFld.clear(pp10extMask); - } else { - pp10extMask = pp10runidFld.setValue(pp10extMask, pp10RunId); - } - // if both parameters are invalid, remove the extension mask - mask = pp10extFld.setBoolean(mask, pp10extMask != -1); - } - - public Boolean getGrammarError() { - return (pp10extMask == -1 || !pp10extFld.isSet(mask)) ? null : grammarErrorFld.isSet(pp10extMask); - } - - public void getGrammarError(Boolean grammarError) { - if (grammarError == null) { - pp10extMask = (getPP10RunId() == -1) ? -1 : grammarErrorFld.clear(pp10extMask); - } else { - pp10extMask = grammarErrorFld.set(pp10extMask); - } - // if both parameters are invalid, remove the extension mask - mask = pp10extFld.setBoolean(mask, pp10extMask != -1); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java deleted file mode 100644 index eb9dd8e0c..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java +++ /dev/null @@ -1,123 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * Tne atom that holds starting and ending character positions of a hyperlink - * - * @author Yegor Kozlov - */ -public final class TxInteractiveInfoAtom extends RecordAtom { - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private byte[] _data; - - /** - * Constructs a brand new link related atom record. - */ - public TxInteractiveInfoAtom() { - _header = new byte[8]; - _data = new byte[8]; - - LittleEndian.putShort(_header, 2, (short)getRecordType()); - LittleEndian.putInt(_header, 4, _data.length); - } - - /** - * Constructs the link related atom record from its - * source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - protected TxInteractiveInfoAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,len-8); - - } - - /** - * Gets the beginning character position - * - * @return the beginning character position - */ - public int getStartIndex() { - return LittleEndian.getInt(_data, 0); - } - - /** - * Sets the beginning character position - * @param idx the beginning character position - */ - public void setStartIndex(int idx) { - LittleEndian.putInt(_data, 0, idx); - } - - /** - * Gets the ending character position - * - * @return the ending character position - */ - public int getEndIndex() { - return LittleEndian.getInt(_data, 4); - } - - /** - * Sets the ending character position - * - * @param idx the ending character position - */ - public void setEndIndex(int idx) { - LittleEndian.putInt(_data, 4, idx); - } - - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return RecordTypes.TxInteractiveInfoAtom.typeID; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - out.write(_data); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java deleted file mode 100644 index b4b8e8004..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java +++ /dev/null @@ -1,213 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianOutputStream; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * TxMasterStyleAtom atom (4003). - *

        - * Stores default character and paragraph styles. - * The atom instance value is the text type and is encoded like the txstyle field in - * TextHeaderAtom. The text styles are located in the MainMaster container, - * except for the "other" style, which is in the Document.Environment container. - *

        - *

        - * This atom can store up to 5 pairs of paragraph+character styles, - * each pair describes an indent level. The first pair describes - * first-level paragraph with no indentation. - *

        - * - * @author Yegor Kozlov - */ -public final class TxMasterStyleAtom extends RecordAtom { - private static final POILogger LOG = POILogFactory.getLogger(TxMasterStyleAtom.class); - - /** - * Maximum number of indentation levels allowed in PowerPoint documents - */ - public static final int MAX_INDENT = 5; - - private byte[] _header; - private static long _type = 4003; - private byte[] _data; - - private List paragraphStyles; - private List charStyles; - - protected TxMasterStyleAtom(byte[] source, int start, int len) { - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - _data = new byte[len-8]; - System.arraycopy(source,start+8,_data,0,_data.length); - - //read available styles - try { - init(); - } catch (Exception e){ - LOG.log(POILogger.WARN, "Exception when reading available styles", e); - } - } - - /** - * We are of type 4003 - * - * @return type of this record - * @see RecordTypes#TxMasterStyleAtom - */ - public long getRecordType() { - return _type; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Write out the (new) header - out.write(_header); - - // Write out the record data - out.write(_data); - - } - - /** - * Returns array of character styles defined in this record. - * - * @return character styles defined in this record - */ - public List getCharacterStyles(){ - return charStyles; - } - - /** - * Returns array of paragraph styles defined in this record. - * - * @return paragraph styles defined in this record - */ - public List getParagraphStyles(){ - return paragraphStyles; - } - - /** - * Return type of the text. - * Must be a constant defined in TextHeaderAtom - * - * @return type of the text - * @see TextHeaderAtom - */ - public int getTextType(){ - //The atom instance value is the text type - return LittleEndian.getShort(_header, 0) >> 4; - } - - /** - * parse the record data and initialize styles - */ - protected void init(){ - //type of the text - int type = getTextType(); - - int head; - int pos = 0; - - //number of indentation levels - short levels = LittleEndian.getShort(_data, 0); - pos += LittleEndian.SHORT_SIZE; - - paragraphStyles = new ArrayList(levels); - charStyles = new ArrayList(levels); - - for(short i = 0; i < levels; i++) { - TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph); - if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) { - // Fetch the 2 byte value, that is safe to ignore for some types of text - short indentLevel = LittleEndian.getShort(_data, pos); - prprops.setIndentLevel(indentLevel); - pos += LittleEndian.SHORT_SIZE; - } else { - prprops.setIndentLevel((short)-1); - } - - head = LittleEndian.getInt(_data, pos); - pos += LittleEndian.INT_SIZE; - - pos += prprops.buildTextPropList( head, _data, pos); - paragraphStyles.add(prprops); - - head = LittleEndian.getInt(_data, pos); - pos += LittleEndian.INT_SIZE; - TextPropCollection chprops = new TextPropCollection(0, TextPropType.character); - pos += chprops.buildTextPropList( head, _data, pos); - charStyles.add(chprops); - } - } - - /** - * Updates the rawdata from the modified paragraph/character styles - * - * @since POI 3.14-beta1 - */ - public void updateStyles() { - int type = getTextType(); - - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - LittleEndianOutputStream leos = new LittleEndianOutputStream(bos); - int levels = paragraphStyles.size(); - leos.writeShort(levels); - - TextPropCollection prdummy = new TextPropCollection(0, TextPropType.paragraph); - TextPropCollection chdummy = new TextPropCollection(0, TextPropType.character); - - for (int i=0; i= TextHeaderAtom.CENTRE_BODY_TYPE) { - leos.writeShort(prdummy.getIndentLevel()); - } - - // Indent level is not written for master styles - prdummy.setIndentLevel((short)-1); - prdummy.writeOut(bos, true); - chdummy.writeOut(bos, true); - } - - _data = bos.toByteArray(); - leos.close(); - - LittleEndian.putInt(_header, 4, _data.length); - } catch (IOException e) { - throw new HSLFException("error in updating master style properties", e); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/UnknownRecordPlaceholder.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/UnknownRecordPlaceholder.java deleted file mode 100644 index 6df2aa919..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/UnknownRecordPlaceholder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * If we come across a record we don't know about, we create one of - * these. It allows us to keep track of what it contains, so we can - * write it back out to disk unchanged - * - * @author Nick Burch - */ - -public final class UnknownRecordPlaceholder extends RecordAtom -{ - private byte[] _contents; - private long _type; - - /** - * Create a new holder for a record we don't grok - */ - protected UnknownRecordPlaceholder(byte[] source, int start, int len) { - // Sanity Checking - including whole header, so treat - // length as based of 0, not 8 (including header size based) - if(len < 0) { len = 0; } - - // Treat as an atom, grab and hold everything - _contents = new byte[len]; - System.arraycopy(source,start,_contents,0,len); - _type = LittleEndian.getUShort(_contents,2); - } - - /** - * Return the value we were given at creation - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_contents); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/UserEditAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/UserEditAtom.java deleted file mode 100644 index b1bd6bba3..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/UserEditAtom.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianConsts; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Map; - -/** - * A UserEdit Atom (type 4085). Holds information which bits of the file - * were last used by powerpoint, the version of powerpoint last used etc. - * - * ** WARNING ** stores byte offsets from the start of the PPT stream to - * other records! If you change the size of any elements before one of - * these, you'll need to update the offsets! - * - * @author Nick Burch - */ - -public final class UserEditAtom extends PositionDependentRecordAtom -{ - public static final int LAST_VIEW_NONE = 0; - public static final int LAST_VIEW_SLIDE_VIEW = 1; - public static final int LAST_VIEW_OUTLINE_VIEW = 2; - public static final int LAST_VIEW_NOTES = 3; - - private byte[] _header; - private static long _type = 4085l; - private short unused; - - private int lastViewedSlideID; - private int pptVersion; - private int lastUserEditAtomOffset; - private int persistPointersOffset; - private int docPersistRef; - private int maxPersistWritten; - private short lastViewType; - private int encryptSessionPersistIdRef = -1; - - // Somewhat user facing getters - public int getLastViewedSlideID() { return lastViewedSlideID; } - public short getLastViewType() { return lastViewType; } - - // Scary internal getters - public int getLastUserEditAtomOffset() { return lastUserEditAtomOffset; } - public int getPersistPointersOffset() { return persistPointersOffset; } - public int getDocPersistRef() { return docPersistRef; } - public int getMaxPersistWritten() { return maxPersistWritten; } - public int getEncryptSessionPersistIdRef() { return encryptSessionPersistIdRef; } - - // More scary internal setters - public void setLastUserEditAtomOffset(int offset) { lastUserEditAtomOffset = offset; } - public void setPersistPointersOffset(int offset) { persistPointersOffset = offset; } - public void setLastViewType(short type) { lastViewType=type; } - public void setMaxPersistWritten(int max) { maxPersistWritten=max; } - public void setEncryptSessionPersistIdRef(int id) { - encryptSessionPersistIdRef=id; - LittleEndian.putInt(_header,4,(id == -1 ? 28 : 32)); - } - - /* *************** record code follows ********************** */ - - /** - * For the UserEdit Atom - */ - protected UserEditAtom(byte[] source, int start, int len) { - // Sanity Checking - if(len < 34) { len = 34; } - - int offset = start; - // Get the header - _header = new byte[8]; - System.arraycopy(source,offset,_header,0,8); - offset += 8; - - // Get the last viewed slide ID - lastViewedSlideID = LittleEndian.getInt(source,offset); - offset += LittleEndianConsts.INT_SIZE; - - // Get the PPT version - pptVersion = LittleEndian.getInt(source,offset); - offset += LittleEndianConsts.INT_SIZE; - - // Get the offset to the previous incremental save's UserEditAtom - // This will be the byte offset on disk where the previous one - // starts, or 0 if this is the first one - lastUserEditAtomOffset = LittleEndian.getInt(source,offset); - offset += LittleEndianConsts.INT_SIZE; - - // Get the offset to the persist pointers - // This will be the byte offset on disk where the preceding - // PersistPtrFullBlock or PersistPtrIncrementalBlock starts - persistPointersOffset = LittleEndian.getInt(source,offset); - offset += LittleEndianConsts.INT_SIZE; - - // Get the persist reference for the document persist object - // Normally seems to be 1 - docPersistRef = LittleEndian.getInt(source,offset); - offset += LittleEndianConsts.INT_SIZE; - - // Maximum number of persist objects written - maxPersistWritten = LittleEndian.getInt(source,offset); - offset += LittleEndianConsts.INT_SIZE; - - // Last view type - lastViewType = LittleEndian.getShort(source,offset); - offset += LittleEndianConsts.SHORT_SIZE; - - // unused - unused = LittleEndian.getShort(source,offset); - offset += LittleEndianConsts.SHORT_SIZE; - - // There might be a few more bytes, which are a reserved field - if (offset-start oldToNewReferencesLookup) { - // Look up the new positions of our preceding UserEditAtomOffset - if(lastUserEditAtomOffset != 0) { - Integer newLocation = oldToNewReferencesLookup.get(Integer.valueOf(lastUserEditAtomOffset)); - if(newLocation == null) { - throw new RuntimeException("Couldn't find the new location of the UserEditAtom that used to be at " + lastUserEditAtomOffset); - } - lastUserEditAtomOffset = newLocation.intValue(); - } - - // Ditto for our PersistPtr - Integer newLocation = oldToNewReferencesLookup.get(Integer.valueOf(persistPointersOffset)); - if(newLocation == null) { - throw new RuntimeException("Couldn't find the new location of the PersistPtr that used to be at " + persistPointersOffset); - } - persistPointersOffset = newLocation.intValue(); - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - // Header - out.write(_header); - - // Write out the values - writeLittleEndian(lastViewedSlideID,out); - writeLittleEndian(pptVersion,out); - writeLittleEndian(lastUserEditAtomOffset,out); - writeLittleEndian(persistPointersOffset,out); - writeLittleEndian(docPersistRef,out); - writeLittleEndian(maxPersistWritten,out); - writeLittleEndian(lastViewType,out); - writeLittleEndian(unused,out); - if (encryptSessionPersistIdRef != -1) { - // optional field - writeLittleEndian(encryptSessionPersistIdRef,out); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java deleted file mode 100644 index d847c3853..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * An atom record that specifies a reference to the VBA project storage. - */ -public final class VBAInfoAtom extends RecordAtom { - private static final long _type = RecordTypes.VBAInfoAtom.typeID; - - /** - * Record header. - */ - private byte[] _header; - - /** - * Record data. - */ - private long persistIdRef; - private boolean hasMacros; - private long version; - - /** - * Constructs an empty atom - not yet supported - */ - private VBAInfoAtom() { - _header = new byte[8]; - // TODO: fix me - LittleEndian.putUInt(_header, 0, _type); - persistIdRef = 0; - hasMacros = true; - version = 2; - } - - /** - * Constructs the vba atom record from its source data. - * - * @param source the source data as a byte array. - * @param start the start offset into the byte array. - * @param len the length of the slice in the byte array. - */ - public VBAInfoAtom(byte[] source, int start, int len) { - // Get the header. - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the record data. - persistIdRef = LittleEndian.getUInt(source, start+8); - hasMacros = (LittleEndian.getUInt(source, start+12) == 1); - version = LittleEndian.getUInt(source, start+16); - } - /** - * Gets the record type. - * @return the record type. - */ - public long getRecordType() { return _type; } - - /** - * Write the contents of the record back, so it can be written - * to disk - * - * @param out the output stream to write to. - * @throws java.io.IOException if an error occurs. - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - LittleEndian.putUInt(persistIdRef, out); - LittleEndian.putUInt(hasMacros ? 1 : 0, out); - LittleEndian.putUInt(version, out); - } - - public long getPersistIdRef() { - return persistIdRef; - } - - public void setPersistIdRef(long persistIdRef) { - this.persistIdRef = persistIdRef; - } - - public boolean isHasMacros() { - return hasMacros; - } - - public void setHasMacros(boolean hasMacros) { - this.hasMacros = hasMacros; - } - - public long getVersion() { - return version; - } - - public void setVersion(long version) { - this.version = version; - } - - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java deleted file mode 100644 index 03577653e..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.record; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * A container record that specifies VBA information for the document. - */ -public final class VBAInfoContainer extends RecordContainer { - private byte[] _header; - private static long _type = RecordTypes.VBAInfo.typeID; - - // Links to our more interesting children - - /** - * Set things up, and find our more interesting children - */ - protected VBAInfoContainer(byte[] source, int start, int len) { - // Grab the header - _header = new byte[8]; - System.arraycopy(source, start, _header, 0, 8); - - // Find our children - _children = Record.findChildRecords(source, start + 8, len - 8); - - findInterestingChildren(); - } - - /** - * Go through our child records, picking out the ones that are - * interesting, and saving those for use by the easy helper - * methods. - */ - private void findInterestingChildren() { - - } - - /** - * Create a new VBAInfoContainer, with blank fields - not yet supported - */ - private VBAInfoContainer() { - _header = new byte[8]; - _children = new Record[0]; - - // Setup our header block - _header[0] = 0x0f; // We are a container record - LittleEndian.putShort(_header, 2, (short) _type); - - // Setup our child records - findInterestingChildren(); - } - - /** - * We are of type 0x3FF - */ - public long getRecordType() { - return _type; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - writeOut(_header[0], _header[1], _type, _children, out); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java deleted file mode 100644 index 329f78f42..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.sl.usermodel.*; -import org.apache.poi.ss.usermodel.ShapeTypes; - -/** - * Represents an AutoShape. - *

        - * AutoShapes are drawing objects with a particular shape that may be customized through smart resizing and adjustments. - * See {@link ShapeTypes} - *

        - * - * @author Yegor Kozlov - */ -public class HSLFAutoShape extends HSLFTextShape implements AutoShape { - - protected HSLFAutoShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - public HSLFAutoShape(ShapeType type, ShapeContainer parent){ - super(null, parent); - _escherContainer = createSpContainer(type, parent instanceof HSLFGroupShape); - } - - public HSLFAutoShape(ShapeType type){ - this(type, null); - } - - protected EscherContainerRecord createSpContainer(ShapeType shapeType, boolean isChild){ - _escherContainer = super.createSpContainer(isChild); - - setShapeType(shapeType); - - //set default properties for an autoshape - setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000); - setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004); - setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004); - setEscherProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000); - setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100010); - setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001); - setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008); - setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); - - return _escherContainer; - } - - protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){ - setVerticalAlignment(VerticalAlignment.MIDDLE); - setHorizontalCentered(true); - setWordWrap(false); - } - - /** - * Gets adjust value which controls smart resizing of the auto-shape. - * - *

        - * The adjustment values are given in shape coordinates: - * the origin is at the top-left, positive-x is to the right, positive-y is down. - * The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant). - *

        - * - * @param idx the adjust index in the [0, 9] range - * @return the adjustment value - */ - public int getAdjustmentValue(int idx){ - if(idx < 0 || idx > 9) throw new IllegalArgumentException("The index of an adjustment value must be in the [0, 9] range"); - - return getEscherProperty((short)(EscherProperties.GEOMETRY__ADJUSTVALUE + idx)); - } - - /** - * Sets adjust value which controls smart resizing of the auto-shape. - * - *

        - * The adjustment values are given in shape coordinates: - * the origin is at the top-left, positive-x is to the right, positive-y is down. - * The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant). - *

        - * - * @param idx the adjust index in the [0, 9] range - * @param val the adjustment value - */ - public void setAdjustmentValue(int idx, int val){ - if(idx < 0 || idx > 9) throw new IllegalArgumentException("The index of an adjustment value must be in the [0, 9] range"); - - setEscherProperty((short)(EscherProperties.GEOMETRY__ADJUSTVALUE + idx), val); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFBackground.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFBackground.java deleted file mode 100644 index 8f477f956..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFBackground.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.sl.usermodel.Background; -import org.apache.poi.sl.usermodel.ShapeContainer; - -/** - * Background shape - * - * @author Yegor Kozlov - */ -public final class HSLFBackground extends HSLFShape implements Background { - - protected HSLFBackground(EscherContainerRecord escherRecord, ShapeContainer parent) { - super(escherRecord, parent); - } - - protected EscherContainerRecord createSpContainer(boolean isChild) { - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFConnectorShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFConnectorShape.java deleted file mode 100644 index 3c26c5a22..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFConnectorShape.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.sl.usermodel.ConnectorShape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.util.Beta; - -/** - * Specifies a connection shape. - * - * This is currently only a dummy implementation. - */ -@Beta -public class HSLFConnectorShape extends HSLFSimpleShape -implements ConnectorShape { - - /** - * Create a ConnectorShape object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFConnectorShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - - } - - /** - * Create a new ConnectorShape. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public HSLFConnectorShape(ShapeContainer parent){ - super(null, parent); - _escherContainer = createSpContainer(parent instanceof HSLFGroupShape); - } - - /** - * Create a new ConnectorShape. This constructor is used when a new shape is created. - * - */ - public HSLFConnectorShape(){ - this(null); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java deleted file mode 100644 index 4d6899548..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java +++ /dev/null @@ -1,392 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Color; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherArrayProperty; -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherColorRef; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.hslf.record.Document; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.ColorStyle; -import org.apache.poi.sl.usermodel.FillStyle; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; -import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint.GradientType; -import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * Represents functionality provided by the 'Fill Effects' dialog in PowerPoint. - */ -public final class HSLFFill { - // For logging - protected POILogger logger = POILogFactory.getLogger(this.getClass()); - - /** - * Fill with a solid color - */ - public static final int FILL_SOLID = 0; - - /** - * Fill with a pattern (bitmap) - */ - public static final int FILL_PATTERN = 1; - - /** - * A texture (pattern with its own color map) - */ - public static final int FILL_TEXTURE = 2; - - /** - * Center a picture in the shape - */ - public static final int FILL_PICTURE = 3; - - /** - * Shade from start to end points - */ - public static final int FILL_SHADE = 4; - - /** - * Shade from bounding rectangle to end point - */ - public static final int FILL_SHADE_CENTER = 5; - - /** - * Shade from shape outline to end point - */ - public static final int FILL_SHADE_SHAPE = 6; - - /** - * Similar to FILL_SHADE, but the fill angle - * is additionally scaled by the aspect ratio of - * the shape. If shape is square, it is the same as FILL_SHADE - */ - public static final int FILL_SHADE_SCALE = 7; - - /** - * shade to title - */ - public static final int FILL_SHADE_TITLE = 8; - - /** - * Use the background fill color/pattern - */ - public static final int FILL_BACKGROUND = 9; - - - - /** - * The shape this background applies to - */ - protected HSLFShape shape; - - /** - * Construct a Fill object for a shape. - * Fill information will be read from shape's escher properties. - * - * @param shape the shape this background applies to - */ - public HSLFFill(HSLFShape shape){ - this.shape = shape; - } - - - public FillStyle getFillStyle() { - return new FillStyle() { - public PaintStyle getPaint() { - final int fillType = getFillType(); - // TODO: fix gradient types, this mismatches with the MS-ODRAW definition ... - // need to handle (not only) the type (radial,rectangular,linear), - // the direction, e.g. top right, and bounds (e.g. for rectangular boxes) - switch (fillType) { - case FILL_SOLID: - return DrawPaint.createSolidPaint(getForegroundColor()); - case FILL_SHADE_SHAPE: - return getGradientPaint(GradientType.shape); - case FILL_SHADE_CENTER: - case FILL_SHADE_TITLE: - return getGradientPaint(GradientType.circular); - case FILL_SHADE: - case FILL_SHADE_SCALE: - return getGradientPaint(GradientType.linear); - case FILL_PICTURE: - return getTexturePaint(); - default: - logger.log(POILogger.WARN, "unsuported fill type: " + fillType); - return null; - } - } - }; - } - - - - private GradientPaint getGradientPaint(final GradientType gradientType) { - final AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - final EscherArrayProperty ep = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__SHADECOLORS); - final int colorCnt = (ep == null) ? 0 : ep.getNumberOfElementsInArray(); - - return new GradientPaint() { - public double getGradientAngle() { - // A value of type FixedPoint, as specified in [MS-OSHARED] section 2.2.1.6, - // that specifies the angle of the gradient fill. Zero degrees represents a vertical vector from - // bottom to top. The default value for this property is 0x00000000. - int rot = shape.getEscherProperty(EscherProperties.FILL__ANGLE); - return 90-Units.fixedPointToDouble(rot); - } - public ColorStyle[] getGradientColors() { - ColorStyle cs[]; - if (colorCnt == 0) { - cs = new ColorStyle[2]; - cs[0] = wrapColor(getBackgroundColor()); - cs[1] = wrapColor(getForegroundColor()); - } else { - cs = new ColorStyle[colorCnt]; - int idx = 0; - // TODO: handle palette colors and alpha(?) value - for (byte data[] : ep) { - EscherColorRef ecr = new EscherColorRef(data, 0, 4); - cs[idx++] = wrapColor(shape.getColor(ecr)); - } - } - return cs; - } - private ColorStyle wrapColor(Color col) { - return (col == null) ? null : DrawPaint.createSolidPaint(col).getSolidColor(); - } - public float[] getGradientFractions() { - float frc[]; - if (colorCnt == 0) { - frc = new float[]{0, 1}; - } else { - frc = new float[colorCnt]; - int idx = 0; - for (byte data[] : ep) { - double pos = Units.fixedPointToDouble(LittleEndian.getInt(data, 4)); - frc[idx++] = (float)pos; - } - } - return frc; - } - public boolean isRotatedWithShape() { - return false; - } - public GradientType getGradientType() { - return gradientType; - } - }; - } - - private TexturePaint getTexturePaint() { - final HSLFPictureData pd = getPictureData(); - if (pd == null) { - return null; - } - - return new TexturePaint() { - public InputStream getImageData() { - return new ByteArrayInputStream(pd.getData()); - } - - public String getContentType() { - return pd.getContentType(); - } - - public int getAlpha() { - return (int)(shape.getAlpha(EscherProperties.FILL__FILLOPACITY)*100000.0); - } - }; - } - - /** - * Returns fill type. - * Must be one of the FILL_* constants defined in this class. - * - * @return type of fill - */ - public int getFillType(){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - EscherSimpleProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE); - return prop == null ? FILL_SOLID : prop.getPropertyValue(); - } - - /** - */ - protected void afterInsert(HSLFSheet sh){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE); - if(p != null) { - int idx = p.getPropertyValue(); - EscherBSERecord bse = getEscherBSERecord(idx); - bse.setRef(bse.getRef() + 1); - } - } - - @SuppressWarnings("resource") - protected EscherBSERecord getEscherBSERecord(int idx){ - HSLFSheet sheet = shape.getSheet(); - if(sheet == null) { - logger.log(POILogger.DEBUG, "Fill has not yet been assigned to a sheet"); - return null; - } - HSLFSlideShow ppt = sheet.getSlideShow(); - Document doc = ppt.getDocumentRecord(); - EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); - EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); - if(bstore == null) { - logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found "); - return null; - } - List lst = bstore.getChildRecords(); - return (EscherBSERecord)lst.get(idx-1); - } - - /** - * Sets fill type. - * Must be one of the FILL_* constants defined in this class. - * - * @param type type of the fill - */ - public void setFillType(int type){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type); - } - - /** - * Foreground color - */ - public Color getForegroundColor(){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); - - if(p != null && (p.getPropertyValue() & 0x10) == 0) return null; - - return shape.getColor(EscherProperties.FILL__FILLCOLOR, EscherProperties.FILL__FILLOPACITY, -1); - - } - - /** - * Foreground color - */ - public void setForegroundColor(Color color){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - if (color == null) { - opt.removeEscherProperty(EscherProperties.FILL__FILLCOLOR); - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000); - } - else { - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); - int alpha = color.getAlpha(); - if (alpha == 255) { - opt.removeEscherProperty(EscherProperties.FILL__FILLOPACITY); - } else { - int alphaFP = Units.doubleToFixedPoint(alpha/255d); - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLOPACITY, alphaFP); - } - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011); - } - } - - /** - * Background color - */ - public Color getBackgroundColor(){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); - - if(p != null && (p.getPropertyValue() & 0x10) == 0) return null; - - return shape.getColor(EscherProperties.FILL__FILLBACKCOLOR, EscherProperties.FILL__FILLOPACITY, -1); - } - - /** - * Background color - */ - public void setBackgroundColor(Color color){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - if (color == null) { - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1); - } - else { - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb); - } - } - - /** - * PictureData object used in a texture, pattern of picture fill. - */ - @SuppressWarnings("resource") - public HSLFPictureData getPictureData(){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE); - if (p == null) return null; - - HSLFSlideShow ppt = shape.getSheet().getSlideShow(); - List pict = ppt.getPictureData(); - Document doc = ppt.getDocumentRecord(); - - EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); - EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); - - java.util.List lst = bstore.getChildRecords(); - int idx = p.getPropertyValue(); - if (idx == 0){ - logger.log(POILogger.WARN, "no reference to picture data found "); - } else { - EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1); - for (HSLFPictureData pd : pict) { - if (pd.getOffset() == bse.getOffset()){ - return pd; - } - } - } - - return null; - } - - /** - * Assign picture used to fill the underlying shape. - * - * @param data the picture data added to this ppt by {@link HSLFSlideShow#addPicture(byte[], org.apache.poi.sl.usermodel.PictureData.PictureType)} method. - */ - public void setPictureData(HSLFPictureData data){ - AbstractEscherOptRecord opt = shape.getEscherOptRecord(); - HSLFShape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), (data == null ? 0 : data.getIndex())); - if(data != null && shape.getSheet() != null) { - EscherBSERecord bse = getEscherBSERecord(data.getIndex()); - bse.setRef(bse.getRef() + 1); - } - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java deleted file mode 100644 index 740d9532d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java +++ /dev/null @@ -1,444 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherArrayProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherProperty; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.sl.usermodel.FreeformShape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * A "Freeform" shape. - * - *

        - * Shapes drawn with the "Freeform" tool have cubic bezier curve segments in the smooth sections - * and straight-line segments in the straight sections. This object closely corresponds to java.awt.geom.GeneralPath. - *

        - */ -public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformShape { - - public static final byte[] SEGMENTINFO_MOVETO = new byte[]{0x00, 0x40}; - public static final byte[] SEGMENTINFO_LINETO = new byte[]{0x00, (byte)0xAC}; - public static final byte[] SEGMENTINFO_ESCAPE = new byte[]{0x01, 0x00}; - public static final byte[] SEGMENTINFO_ESCAPE2 = new byte[]{0x01, 0x20}; - public static final byte[] SEGMENTINFO_CUBICTO = new byte[]{0x00, (byte)0xAD}; - public static final byte[] SEGMENTINFO_CUBICTO2 = new byte[]{0x00, (byte)0xB3}; //OpenOffice inserts 0xB3 instead of 0xAD. - public static final byte[] SEGMENTINFO_CLOSE = new byte[]{0x01, (byte)0x60}; - public static final byte[] SEGMENTINFO_END = new byte[]{0x00, (byte)0x80}; - - private static BitField PATH_INFO = BitFieldFactory.getInstance(0xE000); - private static BitField ESCAPE_INFO = BitFieldFactory.getInstance(0x1F00); - - enum PathInfo { - lineTo(0),curveTo(1),moveTo(2),close(3),end(4),escape(5),clientEscape(6); - int flag; - PathInfo(int flag) { - this.flag = flag; - } - static PathInfo valueOf(int flag) { - for (PathInfo v : values()) { - if (v.flag == flag) { - return v; - } - } - return null; - } - } - - enum EscapeInfo { - EXTENSION(0x0000), - ANGLE_ELLIPSE_TO(0x0001), - ANGLE_ELLIPSE(0x0002), - ARC_TO(0x0003), - ARC(0x0004), - CLOCKWISE_ARC_TO(0x0005), - CLOCKWISE_ARC(0x0006), - ELLIPTICAL_QUADRANT_X(0x0007), - ELLIPTICAL_QUADRANT_Y(0x0008), - QUADRATIC_BEZIER(0x0009), - NO_FILL(0X000A), - NO_LINE(0X000B), - AUTO_LINE(0X000C), - AUTO_CURVE(0X000D), - CORNER_LINE(0X000E), - CORNER_CURVE(0X000F), - SMOOTH_LINE(0X0010), - SMOOTH_CURVE(0X0011), - SYMMETRIC_LINE(0X0012), - SYMMETRIC_CURVE(0X0013), - FREEFORM(0X0014), - FILL_COLOR(0X0015), - LINE_COLOR(0X0016); - - int flag; - EscapeInfo(int flag) { - this.flag = flag; - } - static EscapeInfo valueOf(int flag) { - for (EscapeInfo v : values()) { - if (v.flag == flag) { - return v; - } - } - return null; - } - } - - enum ShapePath { - LINES(0), - LINES_CLOSED(1), - CURVES(2), - CURVES_CLOSED(3), - COMPLEX(4); - - int flag; - ShapePath(int flag) { - this.flag = flag; - } - static ShapePath valueOf(int flag) { - for (ShapePath v : values()) { - if (v.flag == flag) { - return v; - } - } - return null; - } - } - - /** - * Create a Freeform object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFFreeformShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - - } - - /** - * Create a new Freeform. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public HSLFFreeformShape(ShapeContainer parent){ - super((EscherContainerRecord)null, parent); - _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape); - } - - /** - * Create a new Freeform. This constructor is used when a new shape is created. - * - */ - public HSLFFreeformShape(){ - this(null); - } - - @Override - public int setPath(Path2D.Double path) { - Rectangle2D bounds = path.getBounds2D(); - PathIterator it = path.getPathIterator(new AffineTransform()); - - List segInfo = new ArrayList(); - List pntInfo = new ArrayList(); - boolean isClosed = false; - int numPoints = 0; - while (!it.isDone()) { - double[] vals = new double[6]; - int type = it.currentSegment(vals); - switch (type) { - case PathIterator.SEG_MOVETO: - pntInfo.add(new Point2D.Double(vals[0], vals[1])); - segInfo.add(SEGMENTINFO_MOVETO); - numPoints++; - break; - case PathIterator.SEG_LINETO: - pntInfo.add(new Point2D.Double(vals[0], vals[1])); - segInfo.add(SEGMENTINFO_LINETO); - segInfo.add(SEGMENTINFO_ESCAPE); - numPoints++; - break; - case PathIterator.SEG_CUBICTO: - pntInfo.add(new Point2D.Double(vals[0], vals[1])); - pntInfo.add(new Point2D.Double(vals[2], vals[3])); - pntInfo.add(new Point2D.Double(vals[4], vals[5])); - segInfo.add(SEGMENTINFO_CUBICTO); - segInfo.add(SEGMENTINFO_ESCAPE2); - numPoints++; - break; - case PathIterator.SEG_QUADTO: - //TODO: figure out how to convert SEG_QUADTO into SEG_CUBICTO - logger.log(POILogger.WARN, "SEG_QUADTO is not supported"); - break; - case PathIterator.SEG_CLOSE: - pntInfo.add(pntInfo.get(0)); - segInfo.add(SEGMENTINFO_LINETO); - segInfo.add(SEGMENTINFO_ESCAPE); - segInfo.add(SEGMENTINFO_LINETO); - segInfo.add(SEGMENTINFO_CLOSE); - isClosed = true; - numPoints++; - break; - default: - logger.log(POILogger.WARN, "Ignoring invalid segment type "+type); - break; - } - - it.next(); - } - if(!isClosed) segInfo.add(SEGMENTINFO_LINETO); - segInfo.add(new byte[]{0x00, (byte)0x80}); - - AbstractEscherOptRecord opt = getEscherOptRecord(); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4)); - - EscherArrayProperty verticesProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__VERTICES + 0x4000), false, null); - verticesProp.setNumberOfElementsInArray(pntInfo.size()); - verticesProp.setNumberOfElementsInMemory(pntInfo.size()); - verticesProp.setSizeOfElements(8); - for (int i = 0; i < pntInfo.size(); i++) { - Point2D.Double pnt = pntInfo.get(i); - byte[] data = new byte[8]; - LittleEndian.putInt(data, 0, Units.pointsToMaster(pnt.getX() - bounds.getX())); - LittleEndian.putInt(data, 4, Units.pointsToMaster(pnt.getY() - bounds.getY())); - verticesProp.setElement(i, data); - } - opt.addEscherProperty(verticesProp); - - EscherArrayProperty segmentsProp = new EscherArrayProperty((short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000), false, null); - segmentsProp.setNumberOfElementsInArray(segInfo.size()); - segmentsProp.setNumberOfElementsInMemory(segInfo.size()); - segmentsProp.setSizeOfElements(0x2); - for (int i = 0; i < segInfo.size(); i++) { - byte[] seg = segInfo.get(i); - segmentsProp.setElement(i, seg); - } - opt.addEscherProperty(segmentsProp); - - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, Units.pointsToMaster(bounds.getWidth()))); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, Units.pointsToMaster(bounds.getHeight()))); - - opt.sortProperties(); - - setAnchor(bounds); - - return numPoints; - } - - @Override - public Path2D.Double getPath(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - - EscherArrayProperty verticesProp = getShapeProp(opt, EscherProperties.GEOMETRY__VERTICES); - EscherArrayProperty segmentsProp = getShapeProp(opt, EscherProperties.GEOMETRY__SEGMENTINFO); - - // return empty path if either GEOMETRY__VERTICES or GEOMETRY__SEGMENTINFO is missing, see Bugzilla 54188 - Path2D.Double path = new Path2D.Double(); - - //sanity check - if(verticesProp == null) { - logger.log(POILogger.WARN, "Freeform is missing GEOMETRY__VERTICES "); - return path; - } - if(segmentsProp == null) { - logger.log(POILogger.WARN, "Freeform is missing GEOMETRY__SEGMENTINFO "); - return path; - } - - Iterator vertIter = verticesProp.iterator(); - Iterator segIter = segmentsProp.iterator(); - double xyPoints[] = new double[2]; - - while (vertIter.hasNext() && segIter.hasNext()) { - byte[] segElem = segIter.next(); - PathInfo pi = getPathInfo(segElem); - switch (pi) { - case escape: { - handleEscapeInfo(path, segElem, vertIter); - break; - } - case moveTo: { - fillPoint(vertIter.next(), xyPoints); - double x = xyPoints[0]; - double y = xyPoints[1]; - path.moveTo(x,y); - break; - } - case curveTo: { - fillPoint(vertIter.next(), xyPoints); - double x1 = xyPoints[0]; - double y1 = xyPoints[1]; - fillPoint(vertIter.next(), xyPoints); - double x2 = xyPoints[0]; - double y2 = xyPoints[1]; - fillPoint(vertIter.next(), xyPoints); - double x3 = xyPoints[0]; - double y3 = xyPoints[1]; - path.curveTo(x1,y1,x2,y2,x3,y3); - break; - } - case lineTo: - if (vertIter.hasNext()) { - fillPoint(vertIter.next(), xyPoints); - double x = xyPoints[0]; - double y = xyPoints[1]; - path.lineTo(x,y); - } - break; - case close: - path.closePath(); - break; - default: - break; - } - } - - EscherSimpleProperty shapePath = getShapeProp(opt, EscherProperties.GEOMETRY__SHAPEPATH); - ShapePath sp = ShapePath.valueOf(shapePath == null ? 1 : shapePath.getPropertyValue()); - if (sp == ShapePath.LINES_CLOSED || sp == ShapePath.CURVES_CLOSED) { - path.closePath(); - } - - Rectangle2D anchor = getAnchor(); - Rectangle2D bounds = path.getBounds2D(); - AffineTransform at = new AffineTransform(); - at.translate(anchor.getX(), anchor.getY()); - at.scale( - anchor.getWidth()/bounds.getWidth(), - anchor.getHeight()/bounds.getHeight() - ); - return new Path2D.Double(at.createTransformedShape(path)); - } - - private void fillPoint(byte xyMaster[], double xyPoints[]) { - int masterCnt = (xyMaster == null) ? 0 : xyMaster.length; - int pointCnt = (xyPoints == null) ? 0 : xyPoints.length; - if ((masterCnt != 4 && masterCnt != 8) || pointCnt != 2) { - logger.log(POILogger.WARN, "Invalid number of master bytes for a single point - ignore point"); - return; - } - - int x, y; - if (xyMaster.length == 4) { - x = LittleEndian.getShort(xyMaster, 0); - y = LittleEndian.getShort(xyMaster, 2); - } else { - x = LittleEndian.getInt(xyMaster, 0); - y = LittleEndian.getInt(xyMaster, 4); - } - - xyPoints[0] = Units.masterToPoints(x); - xyPoints[1] = Units.masterToPoints(y); - } - - private static T getShapeProp(AbstractEscherOptRecord opt, int propId) { - T prop = getEscherProperty(opt, (short)(propId + 0x4000)); - if (prop == null) { - prop = getEscherProperty(opt, propId); - } - return prop; - } - - // FIXME: FindBugs-JDK8 identified that this method does nothing - private void handleEscapeInfo(Path2D path, byte segElem[], Iterator vertIter) { - EscapeInfo ei = getEscapeInfo(segElem); - switch (ei) { - case EXTENSION: - break; - case ANGLE_ELLIPSE_TO: - break; - case ANGLE_ELLIPSE: - break; - case ARC_TO: - break; - case ARC: - break; - case CLOCKWISE_ARC_TO: - break; - case CLOCKWISE_ARC: - break; - case ELLIPTICAL_QUADRANT_X: - break; - case ELLIPTICAL_QUADRANT_Y: - break; - case QUADRATIC_BEZIER: - break; - case NO_FILL: - break; - case NO_LINE: - break; - case AUTO_LINE: - break; - case AUTO_CURVE: - break; - case CORNER_LINE: - break; - case CORNER_CURVE: - break; - case SMOOTH_LINE: - break; - case SMOOTH_CURVE: - break; - case SYMMETRIC_LINE: - break; - case SYMMETRIC_CURVE: - break; - case FREEFORM: - break; - case FILL_COLOR: - break; - case LINE_COLOR: - break; - default: - break; - } - } - - - private static PathInfo getPathInfo(byte elem[]) { - int elemUS = LittleEndian.getUShort(elem, 0); - int pathInfo = PATH_INFO.getValue(elemUS); - return PathInfo.valueOf(pathInfo); - } - - private static EscapeInfo getEscapeInfo(byte elem[]) { - int elemUS = LittleEndian.getUShort(elem, 0); - int escInfo = ESCAPE_INFO.getValue(elemUS); - return EscapeInfo.valueOf(escInfo); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java deleted file mode 100644 index bae325a0f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java +++ /dev/null @@ -1,358 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.ddf.EscherSpgrRecord; -import org.apache.poi.sl.usermodel.GroupShape; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * Represents a group of shapes. - * - * @author Yegor Kozlov - */ -public class HSLFGroupShape extends HSLFShape -implements HSLFShapeContainer, GroupShape { - /** - * Create a new ShapeGroup. This constructor is used when a new shape is created. - * - */ - public HSLFGroupShape(){ - this(null, null); - _escherContainer = createSpContainer(false); - } - - /** - * Create a new ShapeGroup. This constructor is used when a new shape is created. - * - * @param parent the parent of the shape - */ - public HSLFGroupShape(ShapeContainer parent){ - this(null, parent); - _escherContainer = createSpContainer(parent instanceof HSLFGroupShape); - } - - /** - * Create a ShapeGroup object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFGroupShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - @Override - public void setAnchor(Rectangle2D anchor) { - EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID); - boolean isInitialized = !(clientAnchor.getDx1() == 0 && clientAnchor.getRow1() == 0); - - if (isInitialized) { - moveAndScale(anchor); - } else { - setExteriorAnchor(anchor); - } - } - - @Override - public void setInteriorAnchor(Rectangle2D anchor){ - EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID); - - int x1 = Units.pointsToMaster(anchor.getX()); - int y1 = Units.pointsToMaster(anchor.getY()); - int x2 = Units.pointsToMaster(anchor.getX() + anchor.getWidth()); - int y2 = Units.pointsToMaster(anchor.getY() + anchor.getHeight()); - - spgr.setRectX1(x1); - spgr.setRectY1(y1); - spgr.setRectX2(x2); - spgr.setRectY2(y2); - } - - @Override - public Rectangle2D getInteriorAnchor(){ - EscherSpgrRecord rec = getEscherChild(EscherSpgrRecord.RECORD_ID); - double x1 = Units.masterToPoints(rec.getRectX1()); - double y1 = Units.masterToPoints(rec.getRectY1()); - double x2 = Units.masterToPoints(rec.getRectX2()); - double y2 = Units.masterToPoints(rec.getRectY2()); - return new Rectangle2D.Double(x1,y1,x2-x1,y2-y1); - } - - protected void setExteriorAnchor(Rectangle2D anchor) { - EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID); - - //hack. internal variable EscherClientAnchorRecord.shortRecord can be - //initialized only in fillFields(). We need to set shortRecord=false; - byte[] header = new byte[16]; - LittleEndian.putUShort(header, 0, 0); - LittleEndian.putUShort(header, 2, 0); - LittleEndian.putInt(header, 4, 8); - clientAnchor.fillFields(header, 0, null); - - // All coordinates need to be converted to Master units (576 dpi) - clientAnchor.setFlag((short)Units.pointsToMaster(anchor.getY())); - clientAnchor.setCol1((short)Units.pointsToMaster(anchor.getX())); - clientAnchor.setDx1((short)Units.pointsToMaster(anchor.getWidth() + anchor.getX())); - clientAnchor.setRow1((short)Units.pointsToMaster(anchor.getHeight() + anchor.getY())); - - // TODO: does this make sense? - setInteriorAnchor(anchor); - } - - /** - * Create a new ShapeGroup and create an instance of EscherSpgrContainer which represents a group of shapes - */ - protected EscherContainerRecord createSpContainer(boolean isChild) { - EscherContainerRecord spgr = new EscherContainerRecord(); - spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER); - spgr.setOptions((short)15); - - //The group itself is a shape, and always appears as the first EscherSpContainer in the group container. - EscherContainerRecord spcont = new EscherContainerRecord(); - spcont.setRecordId(EscherContainerRecord.SP_CONTAINER); - spcont.setOptions((short)15); - - EscherSpgrRecord spg = new EscherSpgrRecord(); - spg.setOptions((short)1); - spcont.addChildRecord(spg); - - EscherSpRecord sp = new EscherSpRecord(); - short type = (short)((ShapeType.NOT_PRIMITIVE.nativeId << 4) + 2); - sp.setOptions(type); - sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP); - spcont.addChildRecord(sp); - - EscherClientAnchorRecord anchor = new EscherClientAnchorRecord(); - spcont.addChildRecord(anchor); - - spgr.addChildRecord(spcont); - return spgr; - } - - /** - * Add a shape to this group. - * - * @param shape - the Shape to add - */ - public void addShape(HSLFShape shape){ - _escherContainer.addChildRecord(shape.getSpContainer()); - - HSLFSheet sheet = getSheet(); - shape.setSheet(sheet); - shape.setShapeId(sheet.allocateShapeId()); - shape.afterInsert(sheet); - } - - /** - * Moves and scales this ShapeGroup to the specified anchor. - */ - protected void moveAndScale(Rectangle2D anchorDest){ - Rectangle2D anchorSrc = getAnchor(); - double scaleX = (anchorSrc.getWidth() == 0) ? 0 : anchorDest.getWidth() / anchorSrc.getWidth(); - double scaleY = (anchorSrc.getHeight() == 0) ? 0 : anchorDest.getHeight() / anchorSrc.getHeight(); - - setExteriorAnchor(anchorDest); - - for (HSLFShape shape : getShapes()) { - Rectangle2D chanchor = shape.getAnchor(); - double x = anchorDest.getX()+(chanchor.getX()-anchorSrc.getX())*scaleX; - double y = anchorDest.getY()+(chanchor.getY()-anchorSrc.getY())*scaleY; - double width = chanchor.getWidth()*scaleX; - double height = chanchor.getHeight()*scaleY; - shape.setAnchor(new Rectangle2D.Double(x, y, width, height)); - } - } - - /** - * Returns the anchor (the bounding box rectangle) of this shape group. - * All coordinates are expressed in points (72 dpi). - * - * @return the anchor of this shape group - */ - public Rectangle2D getAnchor(){ - EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID); - int x1,y1,x2,y2; - if(clientAnchor == null){ - logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord."); - EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID); - x1 = rec.getDx1(); - y1 = rec.getDy1(); - x2 = rec.getDx2(); - y2 = rec.getDy2(); - } else { - x1 = clientAnchor.getCol1(); - y1 = clientAnchor.getFlag(); - x2 = clientAnchor.getDx1(); - y2 = clientAnchor.getRow1(); - } - Rectangle2D anchor= new Rectangle2D.Double( - (x1 == -1 ? -1 : Units.masterToPoints(x1)), - (y1 == -1 ? -1 : Units.masterToPoints(y1)), - (x2 == -1 ? -1 : Units.masterToPoints(x2-x1)), - (y2 == -1 ? -1 : Units.masterToPoints(y2-y1)) - ); - - return anchor; - } - - /** - * Return type of the shape. - * In most cases shape group type is {@link org.apache.poi.sl.usermodel.ShapeType#NOT_PRIMITIVE} - * - * @return type of the shape. - */ - public ShapeType getShapeType(){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - int nativeId = spRecord.getOptions() >> 4; - return ShapeType.forId(nativeId, false); - } - - /** - * Returns null - shape groups can't have hyperlinks - * - * @return null. - */ - public HSLFHyperlink getHyperlink(){ - return null; - } - - @Override - public T getEscherChild(int recordId){ - EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0); - return groupInfoContainer.getChildById((short)recordId); - } - - public Iterator iterator() { - return getShapes().iterator(); - } - - public boolean removeShape(HSLFShape shape) { - // TODO: implement! - throw new UnsupportedOperationException(); - } - - @Override - public List getShapes() { - // Out escher container record should contain several - // SpContainers, the first of which is the group shape itself - Iterator iter = _escherContainer.getChildIterator(); - - // Don't include the first SpContainer, it is always NotPrimitive - if (iter.hasNext()) { - iter.next(); - } - List shapeList = new ArrayList(); - while (iter.hasNext()) { - EscherRecord r = iter.next(); - if(r instanceof EscherContainerRecord) { - // Create the Shape for it - EscherContainerRecord container = (EscherContainerRecord)r; - HSLFShape shape = HSLFShapeFactory.createShape(container, this); - shape.setSheet(getSheet()); - shapeList.add( shape ); - } else { - // Should we do anything special with these non - // Container records? - logger.log(POILogger.ERROR, "Shape contained non container escher record, was " + r.getClass().getName()); - } - } - - return shapeList; - } - - @Override - public HSLFTextBox createTextBox() { - HSLFTextBox s = new HSLFTextBox(this); - s.setHorizontalCentered(true); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFAutoShape createAutoShape() { - HSLFAutoShape s = new HSLFAutoShape(ShapeType.RECT, this); - s.setHorizontalCentered(true); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFFreeformShape createFreeform() { - HSLFFreeformShape s = new HSLFFreeformShape(this); - s.setHorizontalCentered(true); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFConnectorShape createConnector() { - HSLFConnectorShape s = new HSLFConnectorShape(this); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFGroupShape createGroup() { - HSLFGroupShape s = new HSLFGroupShape(this); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFPictureShape createPicture(PictureData pictureData) { - if (!(pictureData instanceof HSLFPictureData)) { - throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData"); - } - HSLFPictureShape s = new HSLFPictureShape((HSLFPictureData)pictureData, this); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFTable createTable(int numRows, int numCols) { - if (numRows < 1 || numCols < 1) { - throw new IllegalArgumentException("numRows and numCols must be greater than 0"); - } - HSLFTable s = new HSLFTable(numRows,numCols,this); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java deleted file mode 100644 index 033f3bbeb..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java +++ /dev/null @@ -1,402 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.ListIterator; - -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.hslf.record.ExHyperlink; -import org.apache.poi.hslf.record.ExHyperlinkAtom; -import org.apache.poi.hslf.record.ExObjList; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.InteractiveInfo; -import org.apache.poi.hslf.record.InteractiveInfoAtom; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.TxInteractiveInfoAtom; -import org.apache.poi.sl.usermodel.Hyperlink; -import org.apache.poi.sl.usermodel.Slide; - -/** - * Represents a hyperlink in a PowerPoint document - */ -public final class HSLFHyperlink implements Hyperlink { - private final ExHyperlink exHyper; - private final InteractiveInfo info; - private TxInteractiveInfoAtom txinfo; - - protected HSLFHyperlink(ExHyperlink exHyper, InteractiveInfo info) { - this.info = info; - this.exHyper = exHyper; - } - - public ExHyperlink getExHyperlink() { - return exHyper; - } - - public InteractiveInfo getInfo() { - return info; - } - - public TxInteractiveInfoAtom getTextRunInfo() { - return txinfo; - } - - protected void setTextRunInfo(TxInteractiveInfoAtom txinfo) { - this.txinfo = txinfo; - } - - /** - * Creates a new Hyperlink and assign it to a shape - * This is only a helper method - use {@link HSLFSimpleShape#createHyperlink()} instead! - * - * @param shape the shape which receives the hyperlink - * @return the new hyperlink - * - * @see HSLFSimpleShape#createHyperlink() - */ - /* package */ static HSLFHyperlink createHyperlink(HSLFSimpleShape shape) { - // TODO: check if a hyperlink already exists - ExHyperlink exHyper = new ExHyperlink(); - int linkId = shape.getSheet().getSlideShow().addToObjListAtom(exHyper); - ExHyperlinkAtom obj = exHyper.getExHyperlinkAtom(); - obj.setNumber(linkId); - InteractiveInfo info = new InteractiveInfo(); - info.getInteractiveInfoAtom().setHyperlinkID(linkId); - HSLFEscherClientDataRecord cldata = shape.getClientData(true); - cldata.addChild(info); - HSLFHyperlink hyper = new HSLFHyperlink(exHyper, info); - hyper.linkToNextSlide(); - shape.setHyperlink(hyper); - return hyper; - } - - /** - * Creates a new Hyperlink for a textrun. - * This is only a helper method - use {@link HSLFTextRun#createHyperlink()} instead! - * - * @param run the run which receives the hyperlink - * @return the new hyperlink - * - * @see HSLFTextRun#createHyperlink() - */ - /* package */ static HSLFHyperlink createHyperlink(HSLFTextRun run) { - // TODO: check if a hyperlink already exists - ExHyperlink exHyper = new ExHyperlink(); - int linkId = run.getTextParagraph().getSheet().getSlideShow().addToObjListAtom(exHyper); - ExHyperlinkAtom obj = exHyper.getExHyperlinkAtom(); - obj.setNumber(linkId); - InteractiveInfo info = new InteractiveInfo(); - info.getInteractiveInfoAtom().setHyperlinkID(linkId); - // don't add the hyperlink now to text paragraph records - // this will be done, when the paragraph is saved - HSLFHyperlink hyper = new HSLFHyperlink(exHyper, info); - hyper.linkToNextSlide(); - - TxInteractiveInfoAtom txinfo = new TxInteractiveInfoAtom(); - int startIdx = run.getTextParagraph().getStartIdxOfTextRun(run); - int endIdx = startIdx + run.getLength(); - txinfo.setStartIndex(startIdx); - txinfo.setEndIndex(endIdx); - hyper.setTextRunInfo(txinfo); - - run.setHyperlink(hyper); - return hyper; - } - - - /** - * Gets the type of the hyperlink action. - * Must be a LINK_* constant - * - * @return the hyperlink URL - * @see InteractiveInfoAtom - * @deprecated POI 3.15 beta 3. Use {@link #getTypeEnum()} - */ - @Override - public int getType() { - return getTypeEnum().getCode(); - } - - /** - * Gets the type of the hyperlink action. - * Must be a LINK_* constant - * - * @return the hyperlink URL - * @see InteractiveInfoAtom - */ - @Override - public HyperlinkType getTypeEnum() { - switch (info.getInteractiveInfoAtom().getHyperlinkType()) { - case InteractiveInfoAtom.LINK_Url: - return (exHyper.getLinkURL().startsWith("mailto:")) ? HyperlinkType.EMAIL : HyperlinkType.URL; - case InteractiveInfoAtom.LINK_NextSlide: - case InteractiveInfoAtom.LINK_PreviousSlide: - case InteractiveInfoAtom.LINK_FirstSlide: - case InteractiveInfoAtom.LINK_LastSlide: - case InteractiveInfoAtom.LINK_SlideNumber: - return HyperlinkType.DOCUMENT; - case InteractiveInfoAtom.LINK_CustomShow: - case InteractiveInfoAtom.LINK_OtherPresentation: - case InteractiveInfoAtom.LINK_OtherFile: - return HyperlinkType.FILE; - default: - case InteractiveInfoAtom.LINK_NULL: - return HyperlinkType.NONE; - } - } - - @Override - public void linkToEmail(String emailAddress) { - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_HYPERLINK); - iia.setJump(InteractiveInfoAtom.JUMP_NONE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_Url); - exHyper.setLinkURL("mailto:"+emailAddress); - exHyper.setLinkTitle(emailAddress); - exHyper.setLinkOptions(0x10); - } - - @Override - public void linkToUrl(String url) { - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_HYPERLINK); - iia.setJump(InteractiveInfoAtom.JUMP_NONE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_Url); - exHyper.setLinkURL(url); - exHyper.setLinkTitle(url); - exHyper.setLinkOptions(0x10); - } - - @Override - public void linkToSlide(Slide slide) { - assert(slide instanceof HSLFSlide); - HSLFSlide sl = (HSLFSlide)slide; - int slideNum = slide.getSlideNumber(); - String alias = "Slide "+slideNum; - - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_HYPERLINK); - iia.setJump(InteractiveInfoAtom.JUMP_NONE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_SlideNumber); - - linkToDocument(sl._getSheetNumber(),slideNum,alias,0x30); - } - - @Override - public void linkToNextSlide() { - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_JUMP); - iia.setJump(InteractiveInfoAtom.JUMP_NEXTSLIDE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_NextSlide); - - linkToDocument(1,-1,"NEXT",0x10); - } - - @Override - public void linkToPreviousSlide() { - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_JUMP); - iia.setJump(InteractiveInfoAtom.JUMP_PREVIOUSSLIDE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_PreviousSlide); - - linkToDocument(1,-1,"PREV",0x10); - } - - @Override - public void linkToFirstSlide() { - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_JUMP); - iia.setJump(InteractiveInfoAtom.JUMP_FIRSTSLIDE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_FirstSlide); - - linkToDocument(1,-1,"FIRST",0x10); - } - - @Override - public void linkToLastSlide() { - InteractiveInfoAtom iia = info.getInteractiveInfoAtom(); - iia.setAction(InteractiveInfoAtom.ACTION_JUMP); - iia.setJump(InteractiveInfoAtom.JUMP_LASTSLIDE); - iia.setHyperlinkType(InteractiveInfoAtom.LINK_LastSlide); - - linkToDocument(1,-1,"LAST",0x10); - } - - private void linkToDocument(int sheetNumber, int slideNumber, String alias, int options) { - exHyper.setLinkURL(sheetNumber+","+slideNumber+","+alias); - exHyper.setLinkTitle(alias); - exHyper.setLinkOptions(options); - } - - @Override - public String getAddress() { - return exHyper.getLinkURL(); - } - - @Override - public void setAddress(String str) { - exHyper.setLinkURL(str); - } - - public int getId() { - return exHyper.getExHyperlinkAtom().getNumber(); - } - - @Override - public String getLabel() { - return exHyper.getLinkTitle(); - } - - @Override - public void setLabel(String label) { - exHyper.setLinkTitle(label); - } - - /** - * Gets the beginning character position - * - * @return the beginning character position - */ - public int getStartIndex() { - return (txinfo == null) ? -1 : txinfo.getStartIndex(); - } - - /** - * Sets the beginning character position - * - * @param startIndex the beginning character position - */ - public void setStartIndex(int startIndex) { - if (txinfo != null) { - txinfo.setStartIndex(startIndex); - } - } - - /** - * Gets the ending character position - * - * @return the ending character position - */ - public int getEndIndex() { - return (txinfo == null) ? -1 : txinfo.getEndIndex(); - } - - /** - * Sets the ending character position - * - * @param endIndex the ending character position - */ - public void setEndIndex(int endIndex) { - if (txinfo != null) { - txinfo.setEndIndex(endIndex); - } - } - - /** - * Find hyperlinks in a text shape - * - * @param shape TextRun to lookup hyperlinks in - * @return found hyperlinks or null if not found - */ - public static List find(HSLFTextShape shape){ - return find(shape.getTextParagraphs()); - } - - /** - * Find hyperlinks in a text paragraph - * - * @param paragraphs List of TextParagraph to lookup hyperlinks - * @return found hyperlinks - */ - @SuppressWarnings("resource") - protected static List find(List paragraphs){ - List lst = new ArrayList(); - if (paragraphs == null || paragraphs.isEmpty()) return lst; - - HSLFTextParagraph firstPara = paragraphs.get(0); - - HSLFSlideShow ppt = firstPara.getSheet().getSlideShow(); - //document-level container which stores info about all links in a presentation - ExObjList exobj = ppt.getDocumentRecord().getExObjList(false); - if (exobj != null) { - Record[] records = firstPara.getRecords(); - find(Arrays.asList(records), exobj, lst); - } - - return lst; - } - - /** - * Find hyperlink assigned to the supplied shape - * - * @param shape Shape to lookup hyperlink in - * @return found hyperlink or null - */ - @SuppressWarnings("resource") - protected static HSLFHyperlink find(HSLFShape shape){ - HSLFSlideShow ppt = shape.getSheet().getSlideShow(); - //document-level container which stores info about all links in a presentation - ExObjList exobj = ppt.getDocumentRecord().getExObjList(false); - HSLFEscherClientDataRecord cldata = shape.getClientData(false); - - if (exobj != null && cldata != null) { - List lst = new ArrayList(); - find(cldata.getHSLFChildRecords(), exobj, lst); - return lst.isEmpty() ? null : (HSLFHyperlink)lst.get(0); - } - - return null; - } - - private static void find(List records, ExObjList exobj, List out){ - ListIterator iter = records.listIterator(); - while (iter.hasNext()) { - Record r = iter.next(); - // see if we have InteractiveInfo in the textrun's records - if (!(r instanceof InteractiveInfo)) { - continue; - } - - InteractiveInfo hldr = (InteractiveInfo)r; - InteractiveInfoAtom info = hldr.getInteractiveInfoAtom(); - if (info == null) { - continue; - } - int id = info.getHyperlinkID(); - ExHyperlink exHyper = exobj.get(id); - if (exHyper == null) { - continue; - } - - HSLFHyperlink link = new HSLFHyperlink(exHyper, hldr); - out.add(link); - - if (iter.hasNext()) { - r = iter.next(); - if (!(r instanceof TxInteractiveInfoAtom)) { - iter.previous(); - continue; - } - link.setTextRunInfo((TxInteractiveInfoAtom)r); - } - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFLine.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFLine.java deleted file mode 100644 index 21706db40..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFLine.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.sl.usermodel.Line; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; - -/** - * Represents a line in a PowerPoint drawing - * - * @author Yegor Kozlov - */ -public final class HSLFLine extends HSLFTextShape implements Line { - public HSLFLine(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - public HSLFLine(ShapeContainer parent){ - super(null, parent); - _escherContainer = createSpContainer(parent instanceof HSLFGroupShape); - } - - public HSLFLine(){ - this(null); - } - - protected EscherContainerRecord createSpContainer(boolean isChild){ - _escherContainer = super.createSpContainer(isChild); - - setShapeType(ShapeType.LINE); - - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - short type = (short)((ShapeType.LINE.nativeId << 4) | 0x2); - spRecord.setOptions(type); - - //set default properties for a line - AbstractEscherOptRecord opt = getEscherOptRecord(); - - //default line properties - setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, 4); - setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, 0x10000); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); - setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0xA0008); - setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); - - return _escherContainer; - } - -// /** -// * Sets the orientation of the line, if inverse is false, then line goes -// * from top-left to bottom-right, otherwise use inverse equals true -// * -// * @param inverse the orientation of the line -// */ -// public void setInverse(boolean inverse) { -// setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE); -// } -// -// /** -// * Gets the orientation of the line, if inverse is false, then line goes -// * from top-left to bottom-right, otherwise inverse equals true -// * -// * @return inverse the orientation of the line -// */ -// public boolean isInverse() { -// return (getShapeType() == ShapeType.LINE_INV); -// } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java deleted file mode 100644 index d73374620..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.hslf.record.SheetContainer; -import org.apache.poi.hslf.model.textproperties.TextProp; -import org.apache.poi.sl.usermodel.MasterSheet; - -/** - * The superclass of all master sheets - Slide masters, Notes masters, etc. - * - * For now it's empty. When we understand more about masters in ppt we will add the common functionality here. - * - * @author Yegor Kozlov - */ -public abstract class HSLFMasterSheet extends HSLFSheet implements MasterSheet { - public HSLFMasterSheet(SheetContainer container, int sheetNo){ - super(container, sheetNo); - } - - /** - * Pickup a style attribute from the master. - * This is the "workhorse" which returns the default style attrubutes. - */ - public abstract TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) ; - - - /** - * Checks if the shape is a placeholder. - * (placeholders aren't normal shapes, they are visible only in the Edit Master mode) - * - * - * @return true if the shape is a placeholder - */ - public static boolean isPlaceholder(HSLFShape shape){ - if(!(shape instanceof HSLFTextShape)) return false; - - HSLFTextShape tx = (HSLFTextShape)shape; - return tx.getPlaceholderAtom() != null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java deleted file mode 100644 index d64775e11..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFNotes.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.sl.usermodel.Notes; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This class represents a slide's notes in a PowerPoint Document. It - * allows access to the text within, and the layout. For now, it only - * does the text side of things though - * - * @author Nick Burch - */ - -public final class HSLFNotes extends HSLFSheet implements Notes { - protected static final POILogger logger = POILogFactory.getLogger(HSLFNotes.class); - - private List> _paragraphs = new ArrayList>(); - - /** - * Constructs a Notes Sheet from the given Notes record. - * Initialises TextRuns, to provide easier access to the text - * - * @param notes the Notes record to read from - */ - public HSLFNotes(org.apache.poi.hslf.record.Notes notes) { - super(notes, notes.getNotesAtom().getSlideID()); - - // Now, build up TextRuns from pairs of TextHeaderAtom and - // one of TextBytesAtom or TextCharsAtom, found inside - // EscherTextboxWrapper's in the PPDrawing - for (List l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { - if (!_paragraphs.contains(l)) _paragraphs.add(l); - } - - if (_paragraphs.isEmpty()) { - logger.log(POILogger.WARN, "No text records found for notes sheet"); - } - } - - /** - * Returns an array of all the TextParagraphs found - */ - @Override - public List> getTextParagraphs() { - return _paragraphs; - } - - /** - * Return null - Notes Masters are not yet supported - */ - public HSLFMasterSheet getMasterSheet() { - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java deleted file mode 100644 index f02ddbe78..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hslf.usermodel; - -import java.io.InputStream; -import java.io.IOException; - -import org.apache.poi.hslf.record.ExOleObjStg; - -/** - * A class that represents object data embedded in a slide show. - * - * @author Daniel Noll - */ -public class HSLFObjectData { - /** - * The record that contains the object data. - */ - private ExOleObjStg storage; - - /** - * Creates the object data wrapping the record that contains the object data. - * - * @param storage the record that contains the object data. - */ - public HSLFObjectData(ExOleObjStg storage) { - this.storage = storage; - } - - /** - * Gets an input stream which returns the binary of the embedded data. - * - * @return the input stream which will contain the binary of the embedded data. - */ - public InputStream getData() { - return storage.getData(); - } - - /** - * Sets the embedded data. - * - * @param data the embedded data. - */ - public void setData(byte[] data) throws IOException { - storage.setData(data); - } - - /** - * Return the record that contains the object data. - * - * @return the record that contains the object data. - */ - public ExOleObjStg getExOleObjStg() { - return storage; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java deleted file mode 100644 index f3da76097..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java +++ /dev/null @@ -1,222 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Dimension; -import java.io.IOException; -import java.io.OutputStream; -import java.security.MessageDigest; - -import org.apache.poi.hslf.blip.*; -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.util.*; - -/** - * A class that represents image data contained in a slide show. - * - * @author Yegor Kozlov - */ -public abstract class HSLFPictureData implements PictureData { - - /** - * Size of the image checksum calculated using MD5 algorithm. - */ - protected static final int CHECKSUM_SIZE = 16; - - /** - * Binary data of the picture - */ - private byte[] rawdata; - /** - * The offset to the picture in the stream - */ - protected int offset; - - /** - * The instance type/signatures defines if one or two UID instances will be included - */ - protected int uidInstanceCount = 1; - - /** - * The 1-based index within the pictures stream - */ - protected int index = -1; - - /** - * Blip signature. - */ - protected abstract int getSignature(); - - public abstract void setSignature(int signature); - - /** - * The instance type/signatures defines if one or two UID instances will be included - */ - protected int getUIDInstanceCount() { - return uidInstanceCount; - } - - /** - * Returns the raw binary data of this Picture excluding the first 8 bytes - * which hold image signature and size of the image data. - * - * @return picture data - */ - public byte[] getRawData(){ - return rawdata; - } - - public void setRawData(byte[] data){ - rawdata = (data == null) ? null : data.clone(); - } - - /** - * File offset in the 'Pictures' stream - * - * @return offset in the 'Pictures' stream - */ - public int getOffset(){ - return offset; - } - - /** - * Set offset of this picture in the 'Pictures' stream. - * We need to set it when a new picture is created. - * - * @param offset in the 'Pictures' stream - */ - public void setOffset(int offset){ - this.offset = offset; - } - - /** - * Returns 16-byte checksum of this picture - */ - public byte[] getUID(){ - byte[] uid = new byte[16]; - System.arraycopy(rawdata, 0, uid, 0, uid.length); - return uid; - } - - @Override - public byte[] getChecksum() { - return getChecksum(getData()); - } - - /** - * Compute 16-byte checksum of this picture using MD5 algorithm. - */ - public static byte[] getChecksum(byte[] data) { - MessageDigest md5 = CryptoFunctions.getMessageDigest(HashAlgorithm.md5); - md5.update(data); - return md5.digest(); - } - - /** - * Write this picture into OutputStream - */ - public void write(OutputStream out) throws IOException { - byte[] data; - - data = new byte[LittleEndian.SHORT_SIZE]; - LittleEndian.putUShort(data, 0, getSignature()); - out.write(data); - - data = new byte[LittleEndian.SHORT_SIZE]; - PictureType pt = getType(); - LittleEndian.putUShort(data, 0, pt.nativeId + 0xF018); - out.write(data); - - byte[] rd = getRawData(); - - data = new byte[LittleEndian.INT_SIZE]; - LittleEndian.putInt(data, 0, rd.length); - out.write(data); - - out.write(rd); - } - - /** - * Create an instance of PictureData by type. - * - * @param type type of the picture data. - * Must be one of the static constants defined in the Picture class. - * @return concrete instance of PictureData - */ - public static HSLFPictureData create(PictureType type){ - HSLFPictureData pict; - switch (type){ - case EMF: pict = new EMF(); break; - case WMF: pict = new WMF(); break; - case PICT: pict = new PICT(); break; - case JPEG: pict = new JPEG(); break; - case PNG: pict = new PNG(); break; - case DIB: pict = new DIB(); break; - default: - throw new IllegalArgumentException("Unsupported picture type: " + type); - } - return pict; - } - - /** - * Return 24 byte header which preceeds the actual picture data. - *

        - * The header consists of 2-byte signature, 2-byte type, - * 4-byte image size and 16-byte checksum of the image data. - *

        - * - * @return the 24 byte header which preceeds the actual picture data. - */ - public byte[] getHeader() { - byte[] header = new byte[16 + 8]; - LittleEndian.putInt(header, 0, getSignature()); - LittleEndian.putInt(header, 4, getRawData().length); - System.arraycopy(rawdata, 0, header, 8, 16); - return header; - } - - /** - * @return the 1-based index of this pictures within the pictures stream - */ - public int getIndex() { - return index; - } - - /** - * @param index sets the 1-based index of this pictures within the pictures stream - */ - public void setIndex(int index) { - this.index = index; - } - - @Override - public final String getContentType() { - return getType().contentType; - } - - @Override - public Dimension getImageDimensionInPixels() { - Dimension dim = getImageDimension(); - return new Dimension( - Units.pointsToPixel(dim.getWidth()), - Units.pointsToPixel(dim.getHeight()) - ); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java deleted file mode 100644 index 6f8802d31..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java +++ /dev/null @@ -1,229 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Insets; -import java.awt.geom.Rectangle2D; -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherComplexProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.hslf.record.Document; -import org.apache.poi.sl.draw.DrawPictureShape; -import org.apache.poi.sl.usermodel.PictureShape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; -import org.apache.poi.util.Units; - - -/** - * Represents a picture in a PowerPoint document. - * - * @author Yegor Kozlov - */ -public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape { - - /** - * Create a new Picture - * - * @param data the picture data - */ - public HSLFPictureShape(HSLFPictureData data){ - this(data, null); - } - - /** - * Create a new Picture - * - * @param data the picture data - * @param parent the parent shape - */ - public HSLFPictureShape(HSLFPictureData data, ShapeContainer parent) { - super(null, parent); - _escherContainer = createSpContainer(data.getIndex(), parent instanceof HSLFGroupShape); - } - - /** - * Create a Picture object - * - * @param escherRecord the EscherSpContainer record which holds information about - * this picture in the Slide - * @param parent the parent shape of this picture - */ - protected HSLFPictureShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * Returns index associated with this picture. - * Index starts with 1 and points to a EscherBSE record which - * holds information about this picture. - * - * @return the index to this picture (1 based). - */ - public int getPictureIndex(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY); - return prop == null ? 0 : prop.getPropertyValue(); - } - - /** - * Create a new Picture and populate the inital structure of the EscherSp record which holds information about this picture. - - * @param idx the index of the picture which refers to EscherBSE container. - * @return the create Picture object - */ - protected EscherContainerRecord createSpContainer(int idx, boolean isChild) { - _escherContainer = super.createSpContainer(isChild); - _escherContainer.setOptions((short)15); - - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setOptions((short)((ShapeType.FRAME.nativeId << 4) | 0x2)); - - //set default properties for a picture - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x800080); - - //another weird feature of powerpoint: for picture id we must add 0x4000. - setEscherProperty(opt, (short)(EscherProperties.BLIP__BLIPTODISPLAY + 0x4000), idx); - - return _escherContainer; - } - - @SuppressWarnings("resource") - @Override - public HSLFPictureData getPictureData(){ - HSLFSlideShow ppt = getSheet().getSlideShow(); - List pict = ppt.getPictureData(); - - EscherBSERecord bse = getEscherBSERecord(); - if (bse == null){ - logger.log(POILogger.ERROR, "no reference to picture data found "); - } else { - for (HSLFPictureData pd : pict) { - if (pd.getOffset() == bse.getOffset()){ - return pd; - } - } - logger.log(POILogger.ERROR, "no picture found for our BSE offset " + bse.getOffset()); - } - return null; - } - - @SuppressWarnings("resource") - protected EscherBSERecord getEscherBSERecord(){ - HSLFSlideShow ppt = getSheet().getSlideShow(); - Document doc = ppt.getDocumentRecord(); - EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); - EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); - if(bstore == null) { - logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found "); - return null; - } - List lst = bstore.getChildRecords(); - int idx = getPictureIndex(); - if (idx == 0){ - logger.log(POILogger.DEBUG, "picture index was not found, returning "); - return null; - } - return (EscherBSERecord)lst.get(idx-1); - } - - /** - * Name of this picture. - * - * @return name of this picture - */ - public String getPictureName(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherComplexProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPFILENAME); - if (prop == null) return null; - String name = StringUtil.getFromUnicodeLE(prop.getComplexData()); - return name.trim(); - } - - /** - * Name of this picture. - * - * @param name of this picture - */ - public void setPictureName(String name){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - byte[] data = StringUtil.getToUnicodeLE(name + '\u0000'); - EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.BLIP__BLIPFILENAME, false, data); - opt.addEscherProperty(prop); - } - - /** - * By default set the orininal image size - */ - protected void afterInsert(HSLFSheet sh){ - super.afterInsert(sh); - - EscherBSERecord bse = getEscherBSERecord(); - bse.setRef(bse.getRef() + 1); - - Rectangle2D anchor = getAnchor(); - if (anchor.isEmpty()){ - new DrawPictureShape(this).resize(); - } - } - - - @Override - public Insets getClipping() { - // The anchor specified by the escher properties is the displayed size, - // i.e. the size of the already clipped image - AbstractEscherOptRecord opt = getEscherOptRecord(); - - double top = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP); - double bottom = getFractProp(opt, EscherProperties.BLIP__CROPFROMBOTTOM); - double left = getFractProp(opt, EscherProperties.BLIP__CROPFROMLEFT); - double right = getFractProp(opt, EscherProperties.BLIP__CROPFROMRIGHT); - - // if all crop values are zero (the default) then no crop rectangle is set, return null - return (top==0 && bottom==0 && left==0 && right==0) - ? null - : new Insets((int)(top*100000), (int)(left*100000), (int)(bottom*100000), (int)(right*100000)); - } - - @Override - public ShapeType getShapeType() { - // this is kind of a hack, as picture/ole shapes can have a shape type of "frame" - // but rendering is handled like a rectangle - return ShapeType.RECT; - } - - /** - * @return the fractional property or 0 if not defined - */ - private static double getFractProp(AbstractEscherOptRecord opt, short propertyId) { - EscherSimpleProperty prop = getEscherProperty(opt, propertyId); - if (prop == null) return 0; - int fixedPoint = prop.getPropertyValue(); - return Units.fixedPointToDouble(fixedPoint); - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java deleted file mode 100644 index 22b1d90ab..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.ShapeContainer; - -/** - * Represents a Placeholder in PowerPoint. - * - * @author Yegor Kozlov - */ -public final class HSLFPlaceholder extends HSLFTextBox { - - protected HSLFPlaceholder(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - public HSLFPlaceholder(ShapeContainer parent){ - super(parent); - } - - public HSLFPlaceholder(){ - super(); - } - - /** - * Create a new Placeholder and initialize internal structures - * - * @return the created EscherContainerRecord which holds shape data - */ - protected EscherContainerRecord createSpContainer(boolean isChild){ - _escherContainer = super.createSpContainer(isChild); - - setPlaceholder(Placeholder.BODY); - - return _escherContainer; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java deleted file mode 100644 index 51fc33b70..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java +++ /dev/null @@ -1,651 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherColorRef; -import org.apache.poi.ddf.EscherColorRef.SysIndexProcedure; -import org.apache.poi.ddf.EscherColorRef.SysIndexSource; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherProperty; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.ddf.EscherTextboxRecord; -import org.apache.poi.hslf.record.ColorSchemeAtom; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.usermodel.FillStyle; -import org.apache.poi.sl.usermodel.PresetColor; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - *

        - * Represents a Shape which is the elemental object that composes a drawing. - * This class is a wrapper around EscherSpContainer which holds all information - * about a shape in PowerPoint document. - *

        - *

        - * When you add a shape, you usually specify the dimensions of the shape and the position - * of the upper'left corner of the bounding box for the shape relative to the upper'left - * corner of the page, worksheet, or slide. Distances in the drawing layer are measured - * in points (72 points = 1 inch). - *

        - *

        - */ -public abstract class HSLFShape implements Shape { - - // For logging - protected POILogger logger = POILogFactory.getLogger(this.getClass()); - - /** - * Either EscherSpContainer or EscheSpgrContainer record - * which holds information about this shape. - */ - protected EscherContainerRecord _escherContainer; - - /** - * Parent of this shape. - * null for the topmost shapes. - */ - protected ShapeContainer _parent; - - /** - * The Sheet this shape belongs to - */ - protected HSLFSheet _sheet; - - /** - * Fill - */ - protected HSLFFill _fill; - - /** - * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of this Shape - */ - protected HSLFShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - _escherContainer = escherRecord; - _parent = parent; - } - - /** - * Creates the lowerlevel escher records for this shape. - */ - protected abstract EscherContainerRecord createSpContainer(boolean isChild); - - /** - * @return the parent of this shape - */ - public ShapeContainer getParent(){ - return _parent; - } - - /** - * @return name of the shape. - */ - public String getShapeName(){ - return getShapeType().nativeName; - } - - public ShapeType getShapeType(){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - return ShapeType.forId(spRecord.getShapeType(), false); - } - - public void setShapeType(ShapeType type){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - spRecord.setShapeType( (short) type.nativeId ); - spRecord.setVersion( (short) 0x2 ); - } - - /** - * Returns the anchor (the bounding box rectangle) of this shape. - * All coordinates are expressed in points (72 dpi). - * - * @return the anchor of this shape - */ - public Rectangle2D getAnchor() { - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - int flags = spRecord.getFlags(); - int x1,y1,x2,y2; - EscherChildAnchorRecord childRec = getEscherChild(EscherChildAnchorRecord.RECORD_ID); - boolean useChildRec = ((flags & EscherSpRecord.FLAG_CHILD) != 0); - if (useChildRec && childRec != null){ - x1 = childRec.getDx1(); - y1 = childRec.getDy1(); - x2 = childRec.getDx2(); - y2 = childRec.getDy2(); - } else { - if (useChildRec) { - logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found"); - } - EscherClientAnchorRecord clientRec = getEscherChild(EscherClientAnchorRecord.RECORD_ID); - x1 = clientRec.getCol1(); - y1 = clientRec.getFlag(); - x2 = clientRec.getDx1(); - y2 = clientRec.getRow1(); - } - - // TODO: find out where this -1 value comes from at #57820 (link to ms docs?) - Rectangle2D anchor = new Rectangle2D.Double( - (x1 == -1 ? -1 : Units.masterToPoints(x1)), - (y1 == -1 ? -1 : Units.masterToPoints(y1)), - (x2 == -1 ? -1 : Units.masterToPoints(x2-x1)), - (y2 == -1 ? -1 : Units.masterToPoints(y2-y1)) - ); - - return anchor; - } - - /** - * Sets the anchor (the bounding box rectangle) of this shape. - * All coordinates should be expressed in points (72 dpi). - * - * @param anchor new anchor - */ - public void setAnchor(Rectangle2D anchor){ - int x = Units.pointsToMaster(anchor.getX()); - int y = Units.pointsToMaster(anchor.getY()); - int w = Units.pointsToMaster(anchor.getWidth() + anchor.getX()); - int h = Units.pointsToMaster(anchor.getHeight() + anchor.getY()); - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - int flags = spRecord.getFlags(); - if ((flags & EscherSpRecord.FLAG_CHILD) != 0){ - EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(EscherChildAnchorRecord.RECORD_ID); - rec.setDx1(x); - rec.setDy1(y); - rec.setDx2(w); - rec.setDy2(h); - } else { - EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(EscherClientAnchorRecord.RECORD_ID); - rec.setCol1((short)x); - rec.setFlag((short)y); - rec.setDx1((short)w); - rec.setRow1((short)h); - } - - } - - /** - * Moves the top left corner of the shape to the specified point. - * - * @param x the x coordinate of the top left corner of the shape - * @param y the y coordinate of the top left corner of the shape - */ - public final void moveTo(double x, double y) { - // This convenience method should be implemented via setAnchor in subclasses - // see HSLFGroupShape.setAnchor() for a reference - Rectangle2D anchor = getAnchor(); - anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight()); - setAnchor(anchor); - } - - /** - * Helper method to return escher child by record ID - * - * @return escher record or null if not found. - */ - public static T getEscherChild(EscherContainerRecord owner, int recordId){ - return owner.getChildById((short)recordId); - } - - /** - * @since POI 3.14-Beta2 - */ - public static T getEscherChild(EscherContainerRecord owner, RecordTypes recordId){ - return getEscherChild(owner, recordId.typeID); - } - - public T getEscherChild(int recordId){ - return _escherContainer.getChildById((short)recordId); - } - - /** - * @since POI 3.14-Beta2 - */ - public T getEscherChild(RecordTypes recordId){ - return getEscherChild(recordId.typeID); - } - - /** - * Returns escher property by id. - * - * @return escher property or null if not found. - */ - public static T getEscherProperty(AbstractEscherOptRecord opt, int propId){ - return (opt == null) ? null : opt.lookup(propId); - } - - /** - * Set an escher property for this shape. - * - * @param opt The opt record to set the properties to. - * @param propId The id of the property. One of the constants defined in EscherOptRecord. - * @param value value of the property. If value = -1 then the property is removed. - */ - public static void setEscherProperty(AbstractEscherOptRecord opt, short propId, int value){ - java.util.List props = opt.getEscherProperties(); - for ( Iterator iterator = props.iterator(); iterator.hasNext(); ) { - if (iterator.next().getPropertyNumber() == propId){ - iterator.remove(); - break; - } - } - if (value != -1) { - opt.addEscherProperty(new EscherSimpleProperty(propId, value)); - opt.sortProperties(); - } - } - - /** - * Set an simple escher property for this shape. - * - * @param propId The id of the property. One of the constants defined in EscherOptRecord. - * @param value value of the property. If value = -1 then the property is removed. - */ - public void setEscherProperty(short propId, int value){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, propId, value); - } - - /** - * Get the value of a simple escher property for this shape. - * - * @param propId The id of the property. One of the constants defined in EscherOptRecord. - */ - public int getEscherProperty(short propId){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, propId); - return prop == null ? 0 : prop.getPropertyValue(); - } - - /** - * Get the value of a simple escher property for this shape. - * - * @param propId The id of the property. One of the constants defined in EscherOptRecord. - */ - public int getEscherProperty(short propId, int defaultValue){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, propId); - return prop == null ? defaultValue : prop.getPropertyValue(); - } - - /** - * @return The shape container and it's children that can represent this - * shape. - */ - public EscherContainerRecord getSpContainer(){ - return _escherContainer; - } - - /** - * Event which fires when a shape is inserted in the sheet. - * In some cases we need to propagate changes to upper level containers. - *
        - * Default implementation does nothing. - * - * @param sh - owning shape - */ - protected void afterInsert(HSLFSheet sh){ - if(_fill != null) { - _fill.afterInsert(sh); - } - } - - /** - * @return the SlideShow this shape belongs to - */ - public HSLFSheet getSheet(){ - return _sheet; - } - - /** - * Assign the SlideShow this shape belongs to - * - * @param sheet owner of this shape - */ - public void setSheet(HSLFSheet sheet){ - _sheet = sheet; - } - - Color getColor(short colorProperty, short opacityProperty, int defaultColor){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty p = getEscherProperty(opt, colorProperty); - if(p == null && defaultColor == -1) return null; - - int val = (p == null) ? defaultColor : p.getPropertyValue(); - - EscherColorRef ecr = new EscherColorRef(val); - Color col = getColor(ecr); - if (col == null) { - return null; - } - - double alpha = getAlpha(opacityProperty); - return new Color(col.getRed(), col.getGreen(), col.getBlue(), (int)(alpha*255.0)); - } - - Color getColor(EscherColorRef ecr) { - boolean fPaletteIndex = ecr.hasPaletteIndexFlag(); - boolean fPaletteRGB = ecr.hasPaletteRGBFlag(); - boolean fSystemRGB = ecr.hasSystemRGBFlag(); - boolean fSchemeIndex = ecr.hasSchemeIndexFlag(); - boolean fSysIndex = ecr.hasSysIndexFlag(); - - int rgb[] = ecr.getRGB(); - - HSLFSheet sheet = getSheet(); - if (fSchemeIndex && sheet != null) { - //red is the index to the color scheme - ColorSchemeAtom ca = sheet.getColorScheme(); - int schemeColor = ca.getColor(ecr.getSchemeIndex()); - - rgb[0] = (schemeColor >> 0) & 0xFF; - rgb[1] = (schemeColor >> 8) & 0xFF; - rgb[2] = (schemeColor >> 16) & 0xFF; - } else if (fPaletteIndex) { - //TODO - } else if (fPaletteRGB) { - //TODO - } else if (fSystemRGB) { - //TODO - } else if (fSysIndex) { - Color col = getSysIndexColor(ecr); - col = applySysIndexProcedure(ecr, col); - return col; - } - - return new Color(rgb[0], rgb[1], rgb[2]); - } - - private Color getSysIndexColor(EscherColorRef ecr) { - SysIndexSource sis = ecr.getSysIndexSource(); - if (sis == null) { - int sysIdx = ecr.getSysIndex(); - PresetColor pc = PresetColor.valueOfNativeId(sysIdx); - return (pc != null) ? pc.color : null; - } - - // TODO: check for recursive loops, when color getter also reference - // a different color type - switch (sis) { - case FILL_COLOR: { - return getFill().getForegroundColor(); - } - case LINE_OR_FILL_COLOR: { - Color col = null; - if (this instanceof HSLFSimpleShape) { - col = ((HSLFSimpleShape)this).getLineColor(); - } - if (col == null) { - col = getFill().getForegroundColor(); - } - return col; - } - case LINE_COLOR: { - if (this instanceof HSLFSimpleShape) { - return ((HSLFSimpleShape)this).getLineColor(); - } - break; - } - case SHADOW_COLOR: { - if (this instanceof HSLFSimpleShape) { - return ((HSLFSimpleShape)this).getShadowColor(); - } - break; - } - case CURRENT_OR_LAST_COLOR: { - // TODO ... read from graphics context??? - break; - } - case FILL_BACKGROUND_COLOR: { - return getFill().getBackgroundColor(); - } - case LINE_BACKGROUND_COLOR: { - if (this instanceof HSLFSimpleShape) { - return ((HSLFSimpleShape)this).getLineBackgroundColor(); - } - break; - } - case FILL_OR_LINE_COLOR: { - Color col = getFill().getForegroundColor(); - if (col == null && this instanceof HSLFSimpleShape) { - col = ((HSLFSimpleShape)this).getLineColor(); - } - return col; - } - default: - break; - } - - return null; - } - - private Color applySysIndexProcedure(EscherColorRef ecr, Color col) { - - final SysIndexProcedure sip = ecr.getSysIndexProcedure(); - if (col == null || sip == null) { - return col; - } - - switch (sip) { - case DARKEN_COLOR: { - // see java.awt.Color#darken() - double FACTOR = (ecr.getRGB()[2])/255.; - int r = (int)Math.rint(col.getRed()*FACTOR); - int g = (int)Math.rint(col.getGreen()*FACTOR); - int b = (int)Math.rint(col.getBlue()*FACTOR); - return new Color(r,g,b); - } - case LIGHTEN_COLOR: { - double FACTOR = (0xFF-ecr.getRGB()[2])/255.; - - int r = col.getRed(); - int g = col.getGreen(); - int b = col.getBlue(); - - r += Math.rint((0xFF-r)*FACTOR); - g += Math.rint((0xFF-g)*FACTOR); - b += Math.rint((0xFF-b)*FACTOR); - - return new Color(r,g,b); - } - default: - // TODO ... - break; - } - - return col; - } - - double getAlpha(short opacityProperty) { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty op = getEscherProperty(opt, opacityProperty); - int defaultOpacity = 0x00010000; - int opacity = (op == null) ? defaultOpacity : op.getPropertyValue(); - return Units.fixedPointToDouble(opacity); - } - - Color toRGB(int val){ - int a = (val >> 24) & 0xFF; - int b = (val >> 16) & 0xFF; - int g = (val >> 8) & 0xFF; - int r = (val >> 0) & 0xFF; - - if(a == 0xFE){ - // Color is an sRGB value specified by red, green, and blue fields. - } else if (a == 0xFF){ - // Color is undefined. - } else { - // index in the color scheme - ColorSchemeAtom ca = getSheet().getColorScheme(); - int schemeColor = ca.getColor(a); - - r = (schemeColor >> 0) & 0xFF; - g = (schemeColor >> 8) & 0xFF; - b = (schemeColor >> 16) & 0xFF; - } - return new Color(r, g, b); - } - - /** - * @return id for the shape. - */ - public int getShapeId(){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - return spRecord == null ? 0 : spRecord.getShapeId(); - } - - /** - * Sets shape ID - * - * @param id of the shape - */ - public void setShapeId(int id){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - if(spRecord != null) spRecord.setShapeId(id); - } - - /** - * Fill properties of this shape - * - * @return fill properties of this shape - */ - public HSLFFill getFill(){ - if(_fill == null) { - _fill = new HSLFFill(this); - } - return _fill; - } - - public FillStyle getFillStyle() { - return getFill().getFillStyle(); - } - - @Override - public void draw(Graphics2D graphics, Rectangle2D bounds){ - DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); - } - - public AbstractEscherOptRecord getEscherOptRecord() { - AbstractEscherOptRecord opt = getEscherChild(RecordTypes.EscherOPT); - if (opt == null) { - opt = getEscherChild(RecordTypes.EscherUserDefined); - } - return opt; - } - - public boolean getFlipHorizontal(){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0; - } - - public void setFlipHorizontal(boolean flip) { - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ; - spRecord.setFlags(flag); - } - - public boolean getFlipVertical(){ - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0; - } - - public void setFlipVertical(boolean flip) { - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPVERT; - spRecord.setFlags(flag); - } - - public double getRotation(){ - int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION); - return Units.fixedPointToDouble(rot); - } - - public void setRotation(double theta){ - int rot = Units.doubleToFixedPoint(theta % 360.0); - setEscherProperty(EscherProperties.TRANSFORM__ROTATION, rot); - } - - public boolean isPlaceholder() { - return false; - } - - /** - * Find a record in the underlying EscherClientDataRecord - * - * @param recordType type of the record to search - */ - @SuppressWarnings("unchecked") - public T getClientDataRecord(int recordType) { - - List records = getClientRecords(); - if (records != null) for (Record r : records) { - if (r.getRecordType() == recordType){ - return (T)r; - } - } - return null; - } - - /** - * Search for EscherClientDataRecord, if found, convert its contents into an array of HSLF records - * - * @return an array of HSLF records contained in the shape's EscherClientDataRecord or null - */ - protected List getClientRecords() { - HSLFEscherClientDataRecord clientData = getClientData(false); - return (clientData == null) ? null : clientData.getHSLFChildRecords(); - } - - /** - * Create a new HSLF-specific EscherClientDataRecord - * - * @param create if true, create the missing record - * @return the client record or null if it was missing and create wasn't activated - */ - protected HSLFEscherClientDataRecord getClientData(boolean create) { - HSLFEscherClientDataRecord clientData = getEscherChild(HSLFEscherClientDataRecord.RECORD_ID); - if (clientData == null && create) { - clientData = new HSLFEscherClientDataRecord(); - clientData.setOptions((short)15); - clientData.setRecordId(HSLFEscherClientDataRecord.RECORD_ID); - getSpContainer().addChildBefore(clientData, EscherTextboxRecord.RECORD_ID); - } - return clientData; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeContainer.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeContainer.java deleted file mode 100644 index c09e2d6dd..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeContainer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.ShapeContainer; - -/** - * Common interface for shape containers, e.g. sheets or groups of shapes - */ -public interface HSLFShapeContainer extends ShapeContainer { - - @Override - HSLFAutoShape createAutoShape(); - - @Override - HSLFFreeformShape createFreeform(); - - @Override - HSLFTextBox createTextBox(); - - @Override - HSLFConnectorShape createConnector(); - - @Override - HSLFGroupShape createGroup(); - - @Override - HSLFPictureShape createPicture(PictureData pictureData); - - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java deleted file mode 100644 index 4797ff5f5..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java +++ /dev/null @@ -1,173 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherClientDataRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherProperty; -import org.apache.poi.ddf.EscherPropertyFactory; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.ddf.EscherTextboxRecord; -import org.apache.poi.hslf.model.MovieShape; -import org.apache.poi.hslf.model.OLEShape; -import org.apache.poi.hslf.record.ExObjRefAtom; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.InteractiveInfo; -import org.apache.poi.hslf.record.InteractiveInfoAtom; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Create a Shape object depending on its type - * - * @author Yegor Kozlov - */ -public final class HSLFShapeFactory { - // For logging - protected static final POILogger logger = POILogFactory.getLogger(HSLFShapeFactory.class); - - /** - * Create a new shape from the data provided. - */ - public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer parent){ - if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){ - return createShapeGroup(spContainer, parent); - } - return createSimpleShape(spContainer, parent); - } - - public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer parent){ - boolean isTable = false; - EscherContainerRecord ecr = (EscherContainerRecord)spContainer.getChild(0); - EscherRecord opt = HSLFShape.getEscherChild(ecr, RecordTypes.EscherUserDefined); - - if (opt != null) { - EscherPropertyFactory f = new EscherPropertyFactory(); - List props = f.createProperties( opt.serialize(), 8, opt.getInstance() ); - for (EscherProperty ep : props) { - if (ep.getPropertyNumber() == EscherProperties.GROUPSHAPE__TABLEPROPERTIES - && ep instanceof EscherSimpleProperty - && (((EscherSimpleProperty)ep).getPropertyValue() & 1) == 1) { - isTable = true; - break; - } - } - } - - HSLFGroupShape group; - if (isTable) { - group = new HSLFTable(spContainer, parent); - - } else { - group = new HSLFGroupShape(spContainer, parent); - } - - return group; - } - - public static HSLFShape createSimpleShape(EscherContainerRecord spContainer, ShapeContainer parent){ - HSLFShape shape = null; - EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID); - - ShapeType type = ShapeType.forId(spRecord.getShapeType(), false); - switch (type){ - case TEXT_BOX: - shape = new HSLFTextBox(spContainer, parent); - break; - case HOST_CONTROL: - case FRAME: - shape = createFrame(spContainer, parent); - break; - case LINE: - shape = new HSLFLine(spContainer, parent); - break; - case NOT_PRIMITIVE: - shape = createNonPrimitive(spContainer, parent); - break; - default: - if (parent instanceof HSLFTable) { - EscherTextboxRecord etr = spContainer.getChildById(EscherTextboxRecord.RECORD_ID); - if (etr == null) { - logger.log(POILogger.WARN, "invalid ppt - add EscherTextboxRecord to cell"); - etr = new EscherTextboxRecord(); - etr.setRecordId(EscherTextboxRecord.RECORD_ID); - etr.setOptions((short)15); - spContainer.addChildRecord(etr); - } - shape = new HSLFTableCell(spContainer, (HSLFTable)parent); - } else { - shape = new HSLFAutoShape(spContainer, parent); - } - break; - } - return shape; - } - - private static HSLFShape createFrame(EscherContainerRecord spContainer, ShapeContainer parent) { - InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID); - if(info != null && info.getInteractiveInfoAtom() != null){ - switch(info.getInteractiveInfoAtom().getAction()){ - case InteractiveInfoAtom.ACTION_OLE: - return new OLEShape(spContainer, parent); - case InteractiveInfoAtom.ACTION_MEDIA: - return new MovieShape(spContainer, parent); - default: - break; - } - } - - ExObjRefAtom oes = getClientDataRecord(spContainer, RecordTypes.ExObjRefAtom.typeID); - return (oes != null) - ? new OLEShape(spContainer, parent) - : new HSLFPictureShape(spContainer, parent); - } - - private static HSLFShape createNonPrimitive(EscherContainerRecord spContainer, ShapeContainer parent) { - AbstractEscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID); - EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES); - if(prop != null) { - return new HSLFFreeformShape(spContainer, parent); - } - - logger.log(POILogger.INFO, "Creating AutoShape for a NotPrimitive shape"); - return new HSLFAutoShape(spContainer, parent); - } - - @SuppressWarnings("unchecked") - protected static T getClientDataRecord(EscherContainerRecord spContainer, int recordType) { - HSLFEscherClientDataRecord cldata = spContainer.getChildById(EscherClientDataRecord.RECORD_ID); - if (cldata != null) for (Record r : cldata.getHSLFChildRecords()) { - if (r.getRecordType() == recordType) { - return (T)r; - } - } - return null; - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java deleted file mode 100644 index 72042769d..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java +++ /dev/null @@ -1,471 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherDgRecord; -import org.apache.poi.ddf.EscherDggRecord; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.record.CString; -import org.apache.poi.hslf.record.ColorSchemeAtom; -import org.apache.poi.hslf.record.OEPlaceholderAtom; -import org.apache.poi.hslf.record.PPDrawing; -import org.apache.poi.hslf.record.RecordContainer; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; -import org.apache.poi.hslf.record.SheetContainer; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.Drawable; -import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.Sheet; -import org.apache.poi.util.Internal; - -/** - * This class defines the common format of "Sheets" in a powerpoint - * document. Such sheets could be Slides, Notes, Master etc - * - * @author Nick Burch - * @author Yegor Kozlov - */ - -public abstract class HSLFSheet implements HSLFShapeContainer, Sheet { - /** - * The SlideShow we belong to - */ - private HSLFSlideShow _slideShow; - - /** - * Sheet background - */ - private HSLFBackground _background; - - /** - * Record container that holds sheet data. - * For slides it is org.apache.poi.hslf.record.Slide, - * for notes it is org.apache.poi.hslf.record.Notes, - * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc. - */ - private SheetContainer _container; - - private int _sheetNo; - - public HSLFSheet(SheetContainer container, int sheetNo) { - _container = container; - _sheetNo = sheetNo; - } - - /** - * Returns an array of all the TextRuns in the sheet. - */ - public abstract List> getTextParagraphs(); - - /** - * Returns the (internal, RefID based) sheet number, as used - * to in PersistPtr stuff. - */ - public int _getSheetRefId() { - return _container.getSheetId(); - } - - /** - * Returns the (internal, SlideIdentifier based) sheet number, as used - * to reference this sheet from other records. - */ - public int _getSheetNumber() { - return _sheetNo; - } - - /** - * Fetch the PPDrawing from the underlying record - */ - public PPDrawing getPPDrawing() { - return _container.getPPDrawing(); - } - - /** - * Fetch the SlideShow we're attached to - */ - public HSLFSlideShow getSlideShow() { - return _slideShow; - } - - /** - * Return record container for this sheet - */ - public SheetContainer getSheetContainer() { - return _container; - } - - /** - * Set the SlideShow we're attached to. - * Also passes it on to our child text paragraphs - */ - @Internal - protected void setSlideShow(HSLFSlideShow ss) { - if (_slideShow != null) { - throw new HSLFException("Can't change existing slideshow reference"); - } - - _slideShow = ss; - List> trs = getTextParagraphs(); - if (trs == null) return; - for (List ltp : trs) { - HSLFTextParagraph.supplySheet(ltp, this); - HSLFTextParagraph.applyHyperlinks(ltp); - } - } - - - /** - * Returns all shapes contained in this Sheet - * - * @return all shapes contained in this Sheet (Slide or Notes) - */ - @Override - public List getShapes() { - PPDrawing ppdrawing = getPPDrawing(); - - EscherContainerRecord dg = ppdrawing.getDgContainer(); - EscherContainerRecord spgr = null; - - for (Iterator it = dg.getChildIterator(); it.hasNext();) { - EscherRecord rec = it.next(); - if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) { - spgr = (EscherContainerRecord) rec; - break; - } - } - if (spgr == null) { - throw new IllegalStateException("spgr not found"); - } - - List shapeList = new ArrayList(); - Iterator it = spgr.getChildIterator(); - if (it.hasNext()) { - // skip first item - it.next(); - } - for (; it.hasNext();) { - EscherContainerRecord sp = (EscherContainerRecord) it.next(); - HSLFShape sh = HSLFShapeFactory.createShape(sp, null); - sh.setSheet(this); - - if (sh instanceof HSLFSimpleShape) { - HSLFHyperlink link = HSLFHyperlink.find(sh); - if (link != null) { - ((HSLFSimpleShape)sh).setHyperlink(link); - } - } - - shapeList.add(sh); - } - - return shapeList; - } - - /** - * Add a new Shape to this Slide - * - * @param shape - the Shape to add - */ - public void addShape(HSLFShape shape) { - PPDrawing ppdrawing = getPPDrawing(); - - EscherContainerRecord dgContainer = ppdrawing.getDgContainer(); - EscherContainerRecord spgr = (EscherContainerRecord) HSLFShape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER); - spgr.addChildRecord(shape.getSpContainer()); - - shape.setSheet(this); - shape.setShapeId(allocateShapeId()); - shape.afterInsert(this); - } - - /** - * Allocates new shape id for the new drawing group id. - * - * @return a new shape id. - */ - public int allocateShapeId() - { - EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord(); - EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord(); - - dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 ); - - // Add to existing cluster if space available - for (int i = 0; i < dgg.getFileIdClusters().length; i++) - { - EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i]; - if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024) - { - int result = c.getNumShapeIdsUsed() + (1024 * (i+1)); - c.incrementShapeId(); - dg.setNumShapes( dg.getNumShapes() + 1 ); - dg.setLastMSOSPID( result ); - if (result >= dgg.getShapeIdMax()) - dgg.setShapeIdMax( result + 1 ); - return result; - } - } - - // Create new cluster - dgg.addCluster( dg.getDrawingGroupId(), 0, false ); - dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId(); - dg.setNumShapes( dg.getNumShapes() + 1 ); - int result = (1024 * dgg.getFileIdClusters().length); - dg.setLastMSOSPID( result ); - if (result >= dgg.getShapeIdMax()) - dgg.setShapeIdMax( result + 1 ); - return result; - } - - /** - * Removes the specified shape from this sheet. - * - * @param shape shape to be removed from this sheet, if present. - * @return true if the shape was deleted. - */ - public boolean removeShape(HSLFShape shape) { - PPDrawing ppdrawing = getPPDrawing(); - - EscherContainerRecord dg = ppdrawing.getDgContainer(); - EscherContainerRecord spgr = dg.getChildById(EscherContainerRecord.SPGR_CONTAINER); - if(spgr == null) { - return false; - } - - List lst = spgr.getChildRecords(); - boolean result = lst.remove(shape.getSpContainer()); - spgr.setChildRecords(lst); - return result; - } - - /** - * Called by SlideShow ater a new sheet is created - */ - public void onCreate(){ - - } - - /** - * Return the master sheet . - */ - public abstract HSLFMasterSheet getMasterSheet(); - - /** - * Color scheme for this sheet. - */ - public ColorSchemeAtom getColorScheme() { - return _container.getColorScheme(); - } - - /** - * Returns the background shape for this sheet. - * - * @return the background shape for this sheet. - */ - public HSLFBackground getBackground() { - if (_background == null) { - PPDrawing ppdrawing = getPPDrawing(); - - EscherContainerRecord dg = ppdrawing.getDgContainer(); - EscherContainerRecord spContainer = dg.getChildById(EscherContainerRecord.SP_CONTAINER); - _background = new HSLFBackground(spContainer, null); - _background.setSheet(this); - } - return _background; - } - - @Override - public void draw(Graphics2D graphics) { - DrawFactory drawFact = DrawFactory.getInstance(graphics); - Drawable draw = drawFact.getDrawable(this); - draw.draw(graphics); - } - - /** - * Subclasses should call this method and update the array of text runs - * when a text shape is added - * - * @param shape - */ - protected void onAddTextShape(HSLFTextShape shape) { - } - - /** - * Return placeholder by text type - * - * @param type type of text, See {@link org.apache.poi.hslf.record.TextHeaderAtom} - * @return TextShape or null - */ - public HSLFTextShape getPlaceholderByTextType(int type){ - for (HSLFShape shape : getShapes()) { - if(shape instanceof HSLFTextShape){ - HSLFTextShape tx = (HSLFTextShape)shape; - if (tx.getRunType() == type) { - return tx; - } - } - } - return null; - } - - /** - * Search text placeholer by its type - * - * @param type type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom} - * @return TextShape or null - */ - public HSLFTextShape getPlaceholder(int type){ - for (HSLFShape shape : getShapes()) { - if(shape instanceof HSLFTextShape){ - HSLFTextShape tx = (HSLFTextShape)shape; - int placeholderId = 0; - OEPlaceholderAtom oep = tx.getPlaceholderAtom(); - if(oep != null) { - placeholderId = oep.getPlaceholderId(); - } else { - //special case for files saved in Office 2007 - RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID); - if(hldr != null) placeholderId = hldr.getPlaceholderId(); - } - if(placeholderId == type){ - return tx; - } - } - } - return null; - } - - /** - * Return programmable tag associated with this sheet, e.g. ___PPT12. - * - * @return programmable tag associated with this sheet. - */ - public String getProgrammableTag(){ - String tag = null; - RecordContainer progTags = (RecordContainer) - getSheetContainer().findFirstOfType( - RecordTypes.ProgTags.typeID - ); - if(progTags != null) { - RecordContainer progBinaryTag = (RecordContainer) - progTags.findFirstOfType( - RecordTypes.ProgBinaryTag.typeID - ); - if(progBinaryTag != null) { - CString binaryTag = (CString) - progBinaryTag.findFirstOfType( - RecordTypes.CString.typeID - ); - if(binaryTag != null) tag = binaryTag.getText(); - } - } - - return tag; - - } - - public Iterator iterator() { - return getShapes().iterator(); - } - - - /** - * @return whether shapes on the master sheet should be shown. By default master graphics is turned off. - * Sheets that support the notion of master (slide, slideLayout) should override it and - * check this setting - */ - public boolean getFollowMasterGraphics() { - return false; - } - - - @Override - public HSLFTextBox createTextBox() { - HSLFTextBox s = new HSLFTextBox(); - s.setHorizontalCentered(true); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFAutoShape createAutoShape() { - HSLFAutoShape s = new HSLFAutoShape(ShapeType.RECT); - s.setHorizontalCentered(true); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFFreeformShape createFreeform() { - HSLFFreeformShape s = new HSLFFreeformShape(); - s.setHorizontalCentered(true); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFConnectorShape createConnector() { - HSLFConnectorShape s = new HSLFConnectorShape(); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFGroupShape createGroup() { - HSLFGroupShape s = new HSLFGroupShape(); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFPictureShape createPicture(PictureData pictureData) { - if (!(pictureData instanceof HSLFPictureData)) { - throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData"); - } - HSLFPictureShape s = new HSLFPictureShape((HSLFPictureData)pictureData); - s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100)); - addShape(s); - return s; - } - - @Override - public HSLFTable createTable(int numRows, int numCols) { - if (numRows < 1 || numCols < 1) { - throw new IllegalArgumentException("numRows and numCols must be greater than 0"); - } - HSLFTable s = new HSLFTable(numRows,numCols); - // anchor is set in constructor based on numRows/numCols - addShape(s); - return s; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java deleted file mode 100644 index 8ca4678a2..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java +++ /dev/null @@ -1,670 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Color; -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherProperty; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; -import org.apache.poi.hslf.record.OEPlaceholderAtom; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.draw.geom.CustomGeometry; -import org.apache.poi.sl.draw.geom.Guide; -import org.apache.poi.sl.draw.geom.PresetGeometries; -import org.apache.poi.sl.usermodel.LineDecoration; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape; -import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.Shadow; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.SimpleShape; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * An abstract simple (non-group) shape. - * This is the parent class for all primitive shapes like Line, Rectangle, etc. - * - * @author Yegor Kozlov - */ -public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape { - - public final static double DEFAULT_LINE_WIDTH = 0.75; - - /** - * Hyperlink - */ - protected HSLFHyperlink _hyperlink; - - /** - * Create a SimpleShape object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFSimpleShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * Create a new Shape - * - * @param isChild true if the Line is inside a group, false otherwise - * @return the record container which holds this shape - */ - protected EscherContainerRecord createSpContainer(boolean isChild) { - _escherContainer = new EscherContainerRecord(); - _escherContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); - _escherContainer.setOptions((short)15); - - EscherSpRecord sp = new EscherSpRecord(); - int flags = EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE; - if (isChild) flags |= EscherSpRecord.FLAG_CHILD; - sp.setFlags(flags); - _escherContainer.addChildRecord(sp); - - AbstractEscherOptRecord opt = new EscherOptRecord(); - opt.setRecordId(EscherOptRecord.RECORD_ID); - _escherContainer.addChildRecord(opt); - - EscherRecord anchor; - if(isChild) { - anchor = new EscherChildAnchorRecord(); - } else { - anchor = new EscherClientAnchorRecord(); - - //hack. internal variable EscherClientAnchorRecord.shortRecord can be - //initialized only in fillFields(). We need to set shortRecord=false; - byte[] header = new byte[16]; - LittleEndian.putUShort(header, 0, 0); - LittleEndian.putUShort(header, 2, 0); - LittleEndian.putInt(header, 4, 8); - anchor.fillFields(header, 0, null); - } - _escherContainer.addChildRecord(anchor); - - return _escherContainer; - } - - /** - * Returns width of the line in in points - */ - public double getLineWidth(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH); - double width = (prop == null) ? DEFAULT_LINE_WIDTH : Units.toPoints(prop.getPropertyValue()); - return width; - } - - /** - * Sets the width of line in in points - * @param width the width of line in in points - */ - public void setLineWidth(double width){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH, Units.toEMU(width)); - } - - /** - * Sets the color of line - * - * @param color new color of the line - */ - public void setLineColor(Color color){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - if (color == null) { - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000); - } else { - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, rgb); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x180018); - } - } - - /** - * @return color of the line. If color is not set returns {@code null} - */ - public Color getLineColor(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - - EscherSimpleProperty p = getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH); - if(p != null && (p.getPropertyValue() & 0x8) == 0) return null; - - Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1); - return clr == null ? null : clr; - } - - /** - * @return background color of the line. If color is not set returns {@code null} - */ - public Color getLineBackgroundColor(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - - EscherSimpleProperty p = getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH); - if(p != null && (p.getPropertyValue() & 0x8) == 0) return null; - - Color clr = getColor(EscherProperties.LINESTYLE__BACKCOLOR, EscherProperties.LINESTYLE__OPACITY, -1); - return clr == null ? null : clr; - } - - /** - * Sets the background color of line - * - * @param color new background color of the line - */ - public void setLineBackgroundColor(Color color){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - if (color == null) { - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000); - opt.removeEscherProperty(EscherProperties.LINESTYLE__BACKCOLOR); - } else { - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - setEscherProperty(opt, EscherProperties.LINESTYLE__BACKCOLOR, rgb); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x180018); - } - } - - /** - * Gets line cap. - * - * @return cap of the line. - */ - public LineCap getLineCap(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE); - return (prop == null) ? LineCap.FLAT : LineCap.fromNativeId(prop.getPropertyValue()); - } - - /** - * Sets line cap. - * - * @param pen new style of the line. - */ - public void setLineCap(LineCap pen){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE, pen == LineCap.FLAT ? -1 : pen.nativeId); - } - - /** - * Gets line dashing. - * - * @return dashing of the line. - */ - public LineDash getLineDash(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING); - return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue()); - } - - /** - * Sets line dashing. - * - * @param pen new style of the line. - */ - public void setLineDash(LineDash pen){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId); - } - - /** - * Gets the line compound style - * - * @return the compound style of the line. - */ - public LineCompound getLineCompound() { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE); - return (prop == null) ? LineCompound.SINGLE : LineCompound.fromNativeId(prop.getPropertyValue()); - } - - /** - * Sets the line compound style - * - * @param style new compound style of the line. - */ - public void setLineCompound(LineCompound style){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE, style == LineCompound.SINGLE ? -1 : style.nativeId); - } - - /** - * Returns line style. One of the constants defined in this class. - * - * @return style of the line. - */ - public StrokeStyle getStrokeStyle(){ - return new StrokeStyle() { - public PaintStyle getPaint() { - return DrawPaint.createSolidPaint(HSLFSimpleShape.this.getLineColor()); - } - - public LineCap getLineCap() { - return null; - } - - public LineDash getLineDash() { - return HSLFSimpleShape.this.getLineDash(); - } - - public LineCompound getLineCompound() { - return HSLFSimpleShape.this.getLineCompound(); - } - - public double getLineWidth() { - return HSLFSimpleShape.this.getLineWidth(); - } - - }; - } - - @Override - public Color getFillColor() { - return getFill().getForegroundColor(); - } - - @Override - public void setFillColor(Color color) { - getFill().setForegroundColor(color); - } - - public Guide getAdjustValue(String name) { - if (name == null || !name.matches("adj([1-9]|10)?")) { - logger.log(POILogger.INFO, "Adjust value '"+name+"' not supported. Using default value."); - return null; - } - - name = name.replace("adj", ""); - if ("".equals(name)) name = "1"; - - short escherProp; - switch (Integer.parseInt(name)) { - case 1: escherProp = EscherProperties.GEOMETRY__ADJUSTVALUE; break; - case 2: escherProp = EscherProperties.GEOMETRY__ADJUST2VALUE; break; - case 3: escherProp = EscherProperties.GEOMETRY__ADJUST3VALUE; break; - case 4: escherProp = EscherProperties.GEOMETRY__ADJUST4VALUE; break; - case 5: escherProp = EscherProperties.GEOMETRY__ADJUST5VALUE; break; - case 6: escherProp = EscherProperties.GEOMETRY__ADJUST6VALUE; break; - case 7: escherProp = EscherProperties.GEOMETRY__ADJUST7VALUE; break; - case 8: escherProp = EscherProperties.GEOMETRY__ADJUST8VALUE; break; - case 9: escherProp = EscherProperties.GEOMETRY__ADJUST9VALUE; break; - case 10: escherProp = EscherProperties.GEOMETRY__ADJUST10VALUE; break; - default: throw new RuntimeException(); - } - - // TODO: the adjust values need to be corrected somehow depending on the shape width/height - // see https://social.msdn.microsoft.com/Forums/en-US/3f69ebb3-62a0-4fdd-b367-64790dfb2491/presetshapedefinitionsxml-does-not-specify-width-and-height-form-some-autoshapes?forum=os_binaryfile - - // the adjust value can be format dependent, e.g. hexagon has different values, - // other shape types have the same adjust values in OOXML and native - int adjval = getEscherProperty(escherProp, -1); - - return (adjval == -1) ? null : new Guide(name, "val "+adjval); - } - - public CustomGeometry getGeometry() { - PresetGeometries dict = PresetGeometries.getInstance(); - ShapeType st = getShapeType(); - String name = (st != null) ? st.getOoxmlName() : null; - CustomGeometry geom = dict.get(name); - if (geom == null) { - if (name == null) { - name = (st != null) ? st.toString() : ""; - } - logger.log(POILogger.WARN, "No preset shape definition for shapeType: "+name); - } - - return geom; - } - - - public double getShadowAngle() { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX); - int offX = (prop == null) ? 0 : prop.getPropertyValue(); - prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETY); - int offY = (prop == null) ? 0 : prop.getPropertyValue(); - return Math.toDegrees(Math.atan2(offY, offX)); - } - - public double getShadowDistance() { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETX); - int offX = (prop == null) ? 0 : prop.getPropertyValue(); - prop = getEscherProperty(opt, EscherProperties.SHADOWSTYLE__OFFSETY); - int offY = (prop == null) ? 0 : prop.getPropertyValue(); - return Units.toPoints((long)Math.hypot(offX, offY)); - } - - /** - * @return color of the line. If color is not set returns java.awt.Color.black - */ - public Color getShadowColor(){ - Color clr = getColor(EscherProperties.SHADOWSTYLE__COLOR, EscherProperties.SHADOWSTYLE__OPACITY, -1); - return clr == null ? Color.black : clr; - } - - public Shadow getShadow() { - AbstractEscherOptRecord opt = getEscherOptRecord(); - if (opt == null) return null; - EscherProperty shadowType = opt.lookup(EscherProperties.SHADOWSTYLE__TYPE); - if (shadowType == null) return null; - - return new Shadow(){ - public SimpleShape getShadowParent() { - return HSLFSimpleShape.this; - } - - public double getDistance() { - return getShadowDistance(); - } - - public double getAngle() { - return getShadowAngle(); - } - - public double getBlur() { - // TODO Auto-generated method stub - return 0; - } - - public SolidPaint getFillStyle() { - return DrawPaint.createSolidPaint(getShadowColor()); - } - - }; - } - - public DecorationShape getLineHeadDecoration(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWHEAD); - return (prop == null) ? null : DecorationShape.fromNativeId(prop.getPropertyValue()); - } - - public void setLineHeadDecoration(DecorationShape decoShape){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWHEAD, decoShape == null ? -1 : decoShape.nativeId); - } - - public DecorationSize getLineHeadWidth(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWWIDTH); - return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); - } - - public void setLineHeadWidth(DecorationSize decoSize){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId); - } - - public DecorationSize getLineHeadLength(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWLENGTH); - return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); - } - - public void setLineHeadLength(DecorationSize decoSize){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId); - } - - public DecorationShape getLineTailDecoration(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWHEAD); - return (prop == null) ? null : DecorationShape.fromNativeId(prop.getPropertyValue()); - } - - public void setLineTailDecoration(DecorationShape decoShape){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWHEAD, decoShape == null ? -1 : decoShape.nativeId); - } - - public DecorationSize getLineTailWidth(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWWIDTH); - return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); - } - - public void setLineTailWidth(DecorationSize decoSize){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId); - } - - public DecorationSize getLineTailLength(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWLENGTH); - return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); - } - - public void setLineTailLength(DecorationSize decoSize){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId); - } - - - - public LineDecoration getLineDecoration() { - return new LineDecoration() { - - public DecorationShape getHeadShape() { - return HSLFSimpleShape.this.getLineHeadDecoration(); - } - - public DecorationSize getHeadWidth() { - return HSLFSimpleShape.this.getLineHeadWidth(); - } - - public DecorationSize getHeadLength() { - return HSLFSimpleShape.this.getLineHeadLength(); - } - - public DecorationShape getTailShape() { - return HSLFSimpleShape.this.getLineTailDecoration(); - } - - public DecorationSize getTailWidth() { - return HSLFSimpleShape.this.getLineTailWidth(); - } - - public DecorationSize getTailLength() { - return HSLFSimpleShape.this.getLineTailLength(); - } - }; - } - - @Override - public Placeholder getPlaceholder() { - List clRecords = getClientRecords(); - if (clRecords == null) { - return null; - } - for (Record r : clRecords) { - if (r instanceof OEPlaceholderAtom) { - OEPlaceholderAtom oep = (OEPlaceholderAtom)r; - return Placeholder.lookupNative(oep.getPlaceholderId()); - } else if (r instanceof RoundTripHFPlaceholder12) { - RoundTripHFPlaceholder12 rtp = (RoundTripHFPlaceholder12)r; - return Placeholder.lookupNative(rtp.getPlaceholderId()); - } - } - - return null; - } - - @Override - public void setPlaceholder(Placeholder placeholder) { - EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); - int flags = spRecord.getFlags(); - if (placeholder == null) { - flags ^= EscherSpRecord.FLAG_HAVEMASTER; - } else { - flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER; - } - spRecord.setFlags(flags); - - // Placeholders can't be grouped - setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144)); - - HSLFEscherClientDataRecord clientData = getClientData(false); - if (placeholder == null) { - if (clientData != null) { - clientData.removeChild(OEPlaceholderAtom.class); - clientData.removeChild(RoundTripHFPlaceholder12.class); - // remove client data if the placeholder was the only child to be carried - if (clientData.getChildRecords().isEmpty()) { - getSpContainer().removeChildRecord(clientData); - } - } - return; - } - - if (clientData == null) { - clientData = getClientData(true); - } - - // OEPlaceholderAtom tells powerpoint that this shape is a placeholder - OEPlaceholderAtom oep = null; - RoundTripHFPlaceholder12 rtp = null; - for (Record r : clientData.getHSLFChildRecords()) { - if (r instanceof OEPlaceholderAtom) { - oep = (OEPlaceholderAtom)r; - break; - } - if (r instanceof RoundTripHFPlaceholder12) { - rtp = (RoundTripHFPlaceholder12)r; - break; - } - } - - /** - * Extract from MSDN: - * - * There is a special case when the placeholder does not have a position in the layout. - * This occurs when the user has moved the placeholder from its original position. - * In this case the placeholder ID is -1. - */ - byte phId; - HSLFSheet sheet = getSheet(); - // TODO: implement/switch NotesMaster - if (sheet instanceof HSLFSlideMaster) { - phId = (byte)placeholder.nativeSlideMasterId; - } else if (sheet instanceof HSLFNotes) { - phId = (byte)placeholder.nativeNotesId; - } else { - phId = (byte)placeholder.nativeSlideId; - } - - if (phId == -2) { - throw new HSLFException("Placeholder "+placeholder.name()+" not supported for this sheet type ("+sheet.getClass()+")"); - } - - switch (placeholder) { - case HEADER: - case FOOTER: - if (rtp == null) { - rtp = new RoundTripHFPlaceholder12(); - rtp.setPlaceholderId(phId); - clientData.addChild(rtp); - } - if (oep != null) { - clientData.removeChild(OEPlaceholderAtom.class); - } - break; - default: - if (rtp != null) { - clientData.removeChild(RoundTripHFPlaceholder12.class); - } - if (oep == null) { - oep = new OEPlaceholderAtom(); - oep.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE); - // TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id - oep.setPlacementId(-1); - oep.setPlaceholderId(phId); - clientData.addChild(oep); - } - break; - } - } - - - @Override - public void setStrokeStyle(Object... styles) { - if (styles.length == 0) { - // remove stroke - setLineColor(null); - return; - } - - // TODO: handle PaintStyle - for (Object st : styles) { - if (st instanceof Number) { - setLineWidth(((Number)st).doubleValue()); - } else if (st instanceof LineCap) { - setLineCap((LineCap)st); - } else if (st instanceof LineDash) { - setLineDash((LineDash)st); - } else if (st instanceof LineCompound) { - setLineCompound((LineCompound)st); - } else if (st instanceof Color) { - setLineColor((Color)st); - } - } - } - - @Override - public HSLFHyperlink getHyperlink(){ - return _hyperlink; - } - - @Override - public HSLFHyperlink createHyperlink() { - if (_hyperlink == null) { - _hyperlink = HSLFHyperlink.createHyperlink(this); - } - return _hyperlink; - } - - /** - * Sets the hyperlink - used when the document is parsed - * - * @param link the hyperlink - */ - protected void setHyperlink(HSLFHyperlink link) { - _hyperlink = link; - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java deleted file mode 100644 index d3a613222..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java +++ /dev/null @@ -1,484 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Graphics2D; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherDgRecord; -import org.apache.poi.ddf.EscherDggRecord; -import org.apache.poi.ddf.EscherSpRecord; -import org.apache.poi.hslf.model.Comment; -import org.apache.poi.hslf.model.HeadersFooters; -import org.apache.poi.hslf.record.ColorSchemeAtom; -import org.apache.poi.hslf.record.Comment2000; -import org.apache.poi.hslf.record.EscherTextboxWrapper; -import org.apache.poi.hslf.record.HeadersFootersContainer; -import org.apache.poi.hslf.record.RecordContainer; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.SSSlideInfoAtom; -import org.apache.poi.hslf.record.SlideAtom; -import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; -import org.apache.poi.hslf.record.StyleTextProp9Atom; -import org.apache.poi.hslf.record.TextHeaderAtom; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.Drawable; -import org.apache.poi.sl.usermodel.Notes; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.Slide; - -/** - * This class represents a slide in a PowerPoint Document. It allows - * access to the text within, and the layout. For now, it only does - * the text side of things though - * - * @author Nick Burch - * @author Yegor Kozlov - */ - -public final class HSLFSlide extends HSLFSheet implements Slide { - private int _slideNo; - private SlideAtomsSet _atomSet; - private final List> _paragraphs = new ArrayList>(); - private HSLFNotes _notes; // usermodel needs to set this - - /** - * Constructs a Slide from the Slide record, and the SlideAtomsSet - * containing the text. - * Initializes TextRuns, to provide easier access to the text - * - * @param slide the Slide record we're based on - * @param notes the Notes sheet attached to us - * @param atomSet the SlideAtomsSet to get the text from - */ - public HSLFSlide(org.apache.poi.hslf.record.Slide slide, HSLFNotes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) { - super(slide, slideIdentifier); - - _notes = notes; - _atomSet = atomSet; - _slideNo = slideNumber; - - // For the text coming in from the SlideAtomsSet: - // Build up TextRuns from pairs of TextHeaderAtom and - // one of TextBytesAtom or TextCharsAtom - if (_atomSet != null && _atomSet.getSlideRecords().length > 0) { - // Grab text from SlideListWithTexts entries - _paragraphs.addAll(HSLFTextParagraph.findTextParagraphs(_atomSet.getSlideRecords())); - if (_paragraphs.isEmpty()) { - throw new RuntimeException("No text records found for slide"); - } - } else { - // No text on the slide, must just be pictures - } - - // Grab text from slide's PPDrawing - for (List l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { - if (!_paragraphs.contains(l)) _paragraphs.add(l); - } - } - - /** - * Create a new Slide instance - * @param sheetNumber The internal number of the sheet, as used by PersistPtrHolder - * @param slideNumber The user facing number of the sheet - */ - public HSLFSlide(int sheetNumber, int sheetRefId, int slideNumber){ - super(new org.apache.poi.hslf.record.Slide(), sheetNumber); - _slideNo = slideNumber; - getSheetContainer().setSheetId(sheetRefId); - } - - /** - * Returns the Notes Sheet for this slide, or null if there isn't one - */ - @Override - public HSLFNotes getNotes() { - return _notes; - } - - /** - * Sets the Notes that are associated with this. Updates the - * references in the records to point to the new ID - */ - @Override - public void setNotes(Notes notes) { - if (notes != null && !(notes instanceof HSLFNotes)) { - throw new IllegalArgumentException("notes needs to be of type HSLFNotes"); - } - _notes = (HSLFNotes)notes; - - // Update the Slide Atom's ID of where to point to - SlideAtom sa = getSlideRecord().getSlideAtom(); - - if(_notes == null) { - // Set to 0 - sa.setNotesID(0); - } else { - // Set to the value from the notes' sheet id - sa.setNotesID(_notes._getSheetNumber()); - } - } - - /** - * Changes the Slide's (external facing) page number. - * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#reorderSlide(int, int) - */ - public void setSlideNumber(int newSlideNumber) { - _slideNo = newSlideNumber; - } - - /** - * Called by SlideShow ater a new slide is created. - *

        - * For Slide we need to do the following: - *

      • set id of the drawing group. - *
      • set shapeId for the container descriptor and background - *

        - */ - public void onCreate(){ - //initialize drawing group id - EscherDggRecord dgg = getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord(); - EscherContainerRecord dgContainer = getSheetContainer().getPPDrawing().getDgContainer(); - EscherDgRecord dg = (EscherDgRecord) HSLFShape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID); - int dgId = dgg.getMaxDrawingGroupId() + 1; - dg.setOptions((short)(dgId << 4)); - dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1); - dgg.setMaxDrawingGroupId(dgId); - - for (EscherContainerRecord c : dgContainer.getChildContainers()) { - EscherSpRecord spr = null; - switch(c.getRecordId()){ - case EscherContainerRecord.SPGR_CONTAINER: - EscherContainerRecord dc = (EscherContainerRecord)c.getChild(0); - spr = dc.getChildById(EscherSpRecord.RECORD_ID); - break; - case EscherContainerRecord.SP_CONTAINER: - spr = c.getChildById(EscherSpRecord.RECORD_ID); - break; - default: - break; - } - if(spr != null) spr.setShapeId(allocateShapeId()); - } - - //PPT doen't increment the number of saved shapes for group descriptor and background - dg.setNumShapes(1); - } - - /** - * Create a TextBox object that represents the slide's title. - * - * @return TextBox object that represents the slide's title. - */ - public HSLFTextBox addTitle() { - HSLFPlaceholder pl = new HSLFPlaceholder(); - pl.setShapeType(ShapeType.RECT); - pl.setPlaceholder(Placeholder.TITLE); - pl.setRunType(TextHeaderAtom.TITLE_TYPE); - pl.setText("Click to edit title"); - pl.setAnchor(new java.awt.Rectangle(54, 48, 612, 90)); - addShape(pl); - return pl; - } - - - // Complex Accesser methods follow - - /** - *

        - * The title is a run of text of type TextHeaderAtom.CENTER_TITLE_TYPE or - * TextHeaderAtom.TITLE_TYPE - *

        - * - * @see TextHeaderAtom - */ - @Override - public String getTitle(){ - for (List tp : getTextParagraphs()) { - if (tp.isEmpty()) continue; - int type = tp.get(0).getRunType(); - switch (type) { - case TextHeaderAtom.CENTER_TITLE_TYPE: - case TextHeaderAtom.TITLE_TYPE: - String str = HSLFTextParagraph.getRawText(tp); - return HSLFTextParagraph.toExternalString(str, type); - } - } - return null; - } - - // Simple Accesser methods follow - - /** - * Returns an array of all the TextRuns found - */ - public List> getTextParagraphs() { return _paragraphs; } - - /** - * Returns the (public facing) page number of this slide - */ - @Override - public int getSlideNumber() { return _slideNo; } - - /** - * Returns the underlying slide record - */ - public org.apache.poi.hslf.record.Slide getSlideRecord() { - return (org.apache.poi.hslf.record.Slide)getSheetContainer(); - } - - /** - * @return set of records inside SlideListWithtext container - * which hold text data for this slide (typically for placeholders). - */ - protected SlideAtomsSet getSlideAtomsSet() { return _atomSet; } - - /** - * Returns master sheet associated with this slide. - * It can be either SlideMaster or TitleMaster objects. - * - * @return the master sheet associated with this slide. - */ - public HSLFMasterSheet getMasterSheet(){ - int masterId = getSlideRecord().getSlideAtom().getMasterID(); - for (HSLFSlideMaster sm : getSlideShow().getSlideMasters()) { - if (masterId == sm._getSheetNumber()) return sm; - } - for (HSLFTitleMaster tm : getSlideShow().getTitleMasters()) { - if (masterId == tm._getSheetNumber()) return tm; - } - return null; - } - - /** - * Change Master of this slide. - */ - public void setMasterSheet(HSLFMasterSheet master){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - int sheetNo = master._getSheetNumber(); - sa.setMasterID(sheetNo); - } - - /** - * Sets whether this slide follows master background - * - * @param flag true if the slide follows master, - * false otherwise - */ - public void setFollowMasterBackground(boolean flag){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - sa.setFollowMasterBackground(flag); - } - - /** - * Whether this slide follows master sheet background - * - * @return true if the slide follows master background, - * false otherwise - */ - public boolean getFollowMasterBackground(){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - return sa.getFollowMasterBackground(); - } - - /** - * Sets whether this slide draws master sheet objects - * - * @param flag true if the slide draws master sheet objects, - * false otherwise - */ - public void setFollowMasterObjects(boolean flag){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - sa.setFollowMasterObjects(flag); - } - - /** - * Whether this slide follows master color scheme - * - * @return true if the slide follows master color scheme, - * false otherwise - */ - public boolean getFollowMasterScheme(){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - return sa.getFollowMasterScheme(); - } - - /** - * Sets whether this slide draws master color scheme - * - * @param flag true if the slide draws master color scheme, - * false otherwise - */ - public void setFollowMasterScheme(boolean flag){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - sa.setFollowMasterScheme(flag); - } - - /** - * Whether this slide draws master sheet objects - * - * @return true if the slide draws master sheet objects, - * false otherwise - */ - public boolean getFollowMasterObjects(){ - SlideAtom sa = getSlideRecord().getSlideAtom(); - return sa.getFollowMasterObjects(); - } - - /** - * Background for this slide. - */ - public HSLFBackground getBackground() { - if(getFollowMasterBackground()) { - return getMasterSheet().getBackground(); - } - return super.getBackground(); - } - - /** - * Color scheme for this slide. - */ - public ColorSchemeAtom getColorScheme() { - if(getFollowMasterScheme()){ - return getMasterSheet().getColorScheme(); - } - return super.getColorScheme(); - } - - /** - * Get the comment(s) for this slide. - * Note - for now, only works on PPT 2000 and - * PPT 2003 files. Doesn't work for PPT 97 - * ones, as they do their comments oddly. - */ - public Comment[] getComments() { - // If there are any, they're in - // ProgTags -> ProgBinaryTag -> BinaryTagData - RecordContainer progTags = (RecordContainer) - getSheetContainer().findFirstOfType( - RecordTypes.ProgTags.typeID - ); - if(progTags != null) { - RecordContainer progBinaryTag = (RecordContainer) - progTags.findFirstOfType( - RecordTypes.ProgBinaryTag.typeID - ); - if(progBinaryTag != null) { - RecordContainer binaryTags = (RecordContainer) - progBinaryTag.findFirstOfType( - RecordTypes.BinaryTagData.typeID - ); - if(binaryTags != null) { - // This is where they'll be - int count = 0; - for(int i=0; i newParas = shape.getTextParagraphs(); - _paragraphs.add(newParas); - } - - /** This will return an atom per TextBox, so if the page has two text boxes the method should return two atoms. */ - public StyleTextProp9Atom[] getNumberedListInfo() { - return this.getPPDrawing().getNumberedListInfo(); - } - - public EscherTextboxWrapper[] getTextboxWrappers() { - return this.getPPDrawing().getTextboxWrappers(); - } - - public void setHidden(boolean hidden) { - org.apache.poi.hslf.record.Slide cont = getSlideRecord(); - - SSSlideInfoAtom slideInfo = - (SSSlideInfoAtom)cont.findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID); - if (slideInfo == null) { - slideInfo = new SSSlideInfoAtom(); - cont.addChildAfter(slideInfo, cont.findFirstOfType(RecordTypes.SlideAtom.typeID)); - } - - slideInfo.setEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT, hidden); - } - - public boolean getHidden() { - SSSlideInfoAtom slideInfo = - (SSSlideInfoAtom)getSlideRecord().findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID); - return (slideInfo == null) - ? false - : slideInfo.getEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT); - } - - @Override - public void draw(Graphics2D graphics) { - DrawFactory drawFact = DrawFactory.getInstance(graphics); - Drawable draw = drawFact.getDrawable(this); - draw.draw(graphics); - } - - public boolean getFollowMasterColourScheme() { - // TODO Auto-generated method stub - return false; - } - - public void setFollowMasterColourScheme(boolean follow) { - // TODO Auto-generated method stub - - } - - @Override - public boolean getFollowMasterGraphics() { - return getFollowMasterObjects(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java deleted file mode 100644 index 9b5668ffe..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.model.textproperties.TextProp; -import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.record.*; -import org.apache.poi.util.Internal; - -/** - * SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation. - * It stores information about default font styles, placeholder sizes and positions, - * background design, and color schemes. - * - * @author Yegor Kozlov - */ -public final class HSLFSlideMaster extends HSLFMasterSheet { - private final List> _paragraphs = new ArrayList>(); - - /** - * all TxMasterStyleAtoms available in this master - */ - private TxMasterStyleAtom[] _txmaster; - - /** - * Constructs a SlideMaster from the MainMaster record, - * - */ - public HSLFSlideMaster(MainMaster record, int sheetNo) { - super(record, sheetNo); - - for (List l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { - if (!_paragraphs.contains(l)) _paragraphs.add(l); - } - } - - /** - * Returns an array of all the TextRuns found - */ - public List> getTextParagraphs() { - return _paragraphs; - } - - /** - * Returns null since SlideMasters doen't have master sheet. - */ - public HSLFMasterSheet getMasterSheet() { - return null; - } - - /** - * Pickup a style attribute from the master. - * This is the "workhorse" which returns the default style attributes. - */ - public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) { - if (_txmaster.length <= txtype) return null; - TxMasterStyleAtom t = _txmaster[txtype]; - List styles = isCharacter ? t.getCharacterStyles() : t.getParagraphStyles(); - - TextProp prop = null; - for (int i = Math.min(level, styles.size()-1); prop == null && i >= 0; i--) { - prop = styles.get(i).findByName(name); - } - - if (prop != null) return prop; - - switch (txtype) { - case TextHeaderAtom.CENTRE_BODY_TYPE: - case TextHeaderAtom.HALF_BODY_TYPE: - case TextHeaderAtom.QUARTER_BODY_TYPE: - txtype = TextHeaderAtom.BODY_TYPE; - break; - case TextHeaderAtom.CENTER_TITLE_TYPE: - txtype = TextHeaderAtom.TITLE_TYPE; - break; - default: - return null; - } - - return getStyleAttribute(txtype, level, name, isCharacter); - } - - /** - * Assign SlideShow for this slide master. - */ - @Internal - @Override - protected void setSlideShow(HSLFSlideShow ss) { - super.setSlideShow(ss); - - //after the slide show is assigned collect all available style records - assert (_txmaster == null); - _txmaster = new TxMasterStyleAtom[9]; - - TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); - _txmaster[txdoc.getTextType()] = txdoc; - - TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms(); - for (int i = 0; i < txrec.length; i++) { - int txType = txrec[i].getTextType(); - if (txType < _txmaster.length && _txmaster[txType] == null) { - _txmaster[txType] = txrec[i]; - } - } - - for (List paras : getTextParagraphs()) { - for (HSLFTextParagraph htp : paras) { - int txType = htp.getRunType(); - if (txType >= _txmaster.length || _txmaster[txType] == null) { - throw new HSLFException("Master styles not initialized"); - } - - int level = htp.getIndentLevel(); - - List charStyles = _txmaster[txType].getCharacterStyles(); - List paragraphStyles = _txmaster[txType].getParagraphStyles(); - if (charStyles == null || paragraphStyles == null || - charStyles.size() <= level || paragraphStyles.size() <= level) { - throw new HSLFException("Master styles not initialized"); - } - - htp.setMasterStyleReference(paragraphStyles.get(level)); - for (HSLFTextRun htr : htp.getTextRuns()) { - htr.setMasterStyleReference(charStyles.get(level)); - } - } - } - } - - protected void onAddTextShape(HSLFTextShape shape) { - List runs = shape.getTextParagraphs(); - _paragraphs.add(runs); - } - - public TxMasterStyleAtom[] getTxMasterStyleAtoms(){ - return _txmaster; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java deleted file mode 100644 index a17c61143..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ /dev/null @@ -1,1132 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Dimension; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.hpsf.ClassID; -import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.model.HeadersFooters; -import org.apache.poi.hslf.model.MovieShape; -import org.apache.poi.hslf.model.PPFont; -import org.apache.poi.hslf.record.*; -import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.sl.usermodel.Resources; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * This class is a friendly wrapper on top of the more scary HSLFSlideShow. - * - * TODO: - figure out how to match notes to their correct sheet (will involve - * understanding DocSlideList and DocNotesList) - handle Slide creation cleaner - * - * @author Nick Burch - * @author Yegor kozlov - */ -public final class HSLFSlideShow implements SlideShow, Closeable { - enum LoadSavePhase { - INIT, LOADED - } - private static final ThreadLocal loadSavePhase = new ThreadLocal(); - - // What we're based on - private final HSLFSlideShowImpl _hslfSlideShow; - - // Pointers to the most recent versions of the core records - // (Document, Notes, Slide etc) - private Record[] _mostRecentCoreRecords; - // Lookup between the PersitPtr "sheet" IDs, and the position - // in the mostRecentCoreRecords array - private Map _sheetIdToCoreRecordsLookup; - - // Records that are interesting - private Document _documentRecord; - - // Friendly objects for people to deal with - private final List _masters = new ArrayList(); - private final List _titleMasters = new ArrayList(); - private final List _slides = new ArrayList(); - private final List _notes = new ArrayList(); - private FontCollection _fonts; - - // For logging - private static final POILogger logger = POILogFactory.getLogger(HSLFSlideShow.class); - - - /** - * Constructs a Powerpoint document from the underlying - * HSLFSlideShow object. Finds the model stuff from this - * - * @param hslfSlideShow the HSLFSlideShow to base on - */ - public HSLFSlideShow(HSLFSlideShowImpl hslfSlideShow) { - loadSavePhase.set(LoadSavePhase.INIT); - - // Get useful things from our base slideshow - _hslfSlideShow = hslfSlideShow; - - // Handle Parent-aware Records - for (Record record : _hslfSlideShow.getRecords()) { - if(record instanceof RecordContainer){ - RecordContainer.handleParentAwareRecords((RecordContainer)record); - } - } - - // Find the versions of the core records we'll want to use - findMostRecentCoreRecords(); - - // Build up the model level Slides and Notes - buildSlidesAndNotes(); - - loadSavePhase.set(LoadSavePhase.LOADED); - } - - /** - * Constructs a new, empty, Powerpoint document. - */ - public HSLFSlideShow() { - this(HSLFSlideShowImpl.create()); - } - - /** - * Constructs a Powerpoint document from an input stream. - */ - @SuppressWarnings("resource") - public HSLFSlideShow(InputStream inputStream) throws IOException { - this(new HSLFSlideShowImpl(inputStream)); - } - - /** - * Constructs a Powerpoint document from an POIFSFileSystem. - */ - @SuppressWarnings("resource") - public HSLFSlideShow(NPOIFSFileSystem npoifs) throws IOException { - this(new HSLFSlideShowImpl(npoifs)); - } - - /** - * Constructs a Powerpoint document from an DirectoryNode. - */ - @SuppressWarnings("resource") - public HSLFSlideShow(DirectoryNode root) throws IOException { - this(new HSLFSlideShowImpl(root)); - } - - /** - * @return the current loading/saving phase - */ - protected static LoadSavePhase getLoadSavePhase() { - return loadSavePhase.get(); - } - - /** - * Use the PersistPtrHolder entries to figure out what is the "most recent" - * version of all the core records (Document, Notes, Slide etc), and save a - * record of them. Do this by walking from the oldest PersistPtr to the - * newest, overwriting any references found along the way with newer ones - */ - private void findMostRecentCoreRecords() { - // To start with, find the most recent in the byte offset domain - Map mostRecentByBytes = new HashMap(); - for (Record record : _hslfSlideShow.getRecords()) { - if (record instanceof PersistPtrHolder) { - PersistPtrHolder pph = (PersistPtrHolder) record; - - // If we've already seen any of the "slide" IDs for this - // PersistPtr, remove their old positions - int[] ids = pph.getKnownSlideIDs(); - for (int id : ids) { - if (mostRecentByBytes.containsKey(id)) { - mostRecentByBytes.remove(id); - } - } - - // Now, update the byte level locations with their latest values - Map thisSetOfLocations = pph.getSlideLocationsLookup(); - for (int id : ids) { - mostRecentByBytes.put(id, thisSetOfLocations.get(id)); - } - } - } - - // We now know how many unique special records we have, so init - // the array - _mostRecentCoreRecords = new Record[mostRecentByBytes.size()]; - - // We'll also want to be able to turn the slide IDs into a position - // in this array - _sheetIdToCoreRecordsLookup = new HashMap(); - Integer[] allIDs = mostRecentByBytes.keySet().toArray(new Integer[mostRecentByBytes.size()]); - Arrays.sort(allIDs); - for (int i = 0; i < allIDs.length; i++) { - _sheetIdToCoreRecordsLookup.put(allIDs[i], i); - } - - Map mostRecentByBytesRev = new HashMap(mostRecentByBytes.size()); - for (Map.Entry me : mostRecentByBytes.entrySet()) { - mostRecentByBytesRev.put(me.getValue(), me.getKey()); - } - - // Now convert the byte offsets back into record offsets - for (Record record : _hslfSlideShow.getRecords()) { - if (!(record instanceof PositionDependentRecord)) continue; - - PositionDependentRecord pdr = (PositionDependentRecord) record; - int recordAt = pdr.getLastOnDiskOffset(); - - Integer thisID = mostRecentByBytesRev.get(recordAt); - - if (thisID == null) continue; - - // Bingo. Now, where do we store it? - int storeAt = _sheetIdToCoreRecordsLookup.get(thisID); - - // Tell it its Sheet ID, if it cares - if (pdr instanceof PositionDependentRecordContainer) { - PositionDependentRecordContainer pdrc = (PositionDependentRecordContainer) record; - pdrc.setSheetId(thisID); - } - - // Finally, save the record - _mostRecentCoreRecords[storeAt] = record; - } - - // Now look for the interesting records in there - for (Record record : _mostRecentCoreRecords) { - // Check there really is a record at this number - if (record != null) { - // Find the Document, and interesting things in it - if (record.getRecordType() == RecordTypes.Document.typeID) { - _documentRecord = (Document) record; - _fonts = _documentRecord.getEnvironment().getFontCollection(); - } - } /*else { - // No record at this number - // Odd, but not normally a problem - }*/ - } - } - - /** - * For a given SlideAtomsSet, return the core record, based on the refID - * from the SlidePersistAtom - */ - private Record getCoreRecordForSAS(SlideAtomsSet sas) { - SlidePersistAtom spa = sas.getSlidePersistAtom(); - int refID = spa.getRefID(); - return getCoreRecordForRefID(refID); - } - - /** - * For a given refID (the internal, 0 based numbering scheme), return the - * core record - * - * @param refID - * the refID - */ - private Record getCoreRecordForRefID(int refID) { - Integer coreRecordId = _sheetIdToCoreRecordsLookup.get(refID); - if (coreRecordId != null) { - return _mostRecentCoreRecords[coreRecordId]; - } - logger.log(POILogger.ERROR, - "We tried to look up a reference to a core record, but there was no core ID for reference ID " - + refID); - return null; - } - - /** - * Build up model level Slide and Notes objects, from the underlying - * records. - */ - private void buildSlidesAndNotes() { - // Ensure we really found a Document record earlier - // If we didn't, then the file is probably corrupt - if (_documentRecord == null) { - throw new CorruptPowerPointFileException( - "The PowerPoint file didn't contain a Document Record in its PersistPtr blocks. It is probably corrupt."); - } - - // Fetch the SlideListWithTexts in the most up-to-date Document Record - // - // As far as we understand it: - // * The first SlideListWithText will contain a SlideAtomsSet - // for each of the master slides - // * The second SlideListWithText will contain a SlideAtomsSet - // for each of the slides, in their current order - // These SlideAtomsSets will normally contain text - // * The third SlideListWithText (if present), will contain a - // SlideAtomsSet for each Notes - // These SlideAtomsSets will not normally contain text - // - // Having indentified the masters, slides and notes + their orders, - // we have to go and find their matching records - // We always use the latest versions of these records, and use the - // SlideAtom/NotesAtom to match them with the StyleAtomSet - - findMasterSlides(); - - // Having sorted out the masters, that leaves the notes and slides - Map slideIdToNotes = new HashMap(); - - // Start by finding the notes records - findNotesSlides(slideIdToNotes); - - // Now, do the same thing for our slides - findSlides(slideIdToNotes); - } - - /** - * Find master slides - * These can be MainMaster records, but oddly they can also be - * Slides or Notes, and possibly even other odd stuff.... - * About the only thing you can say is that the master details are in the first SLWT. - */ - private void findMasterSlides() { - SlideListWithText masterSLWT = _documentRecord.getMasterSlideListWithText(); - if (masterSLWT == null) { - return; - } - - for (SlideAtomsSet sas : masterSLWT.getSlideAtomsSets()) { - Record r = getCoreRecordForSAS(sas); - int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier(); - if (r instanceof Slide) { - HSLFTitleMaster master = new HSLFTitleMaster((Slide)r, sheetNo); - master.setSlideShow(this); - _titleMasters.add(master); - } else if (r instanceof MainMaster) { - HSLFSlideMaster master = new HSLFSlideMaster((MainMaster)r, sheetNo); - master.setSlideShow(this); - _masters.add(master); - } - } - } - - private void findNotesSlides(Map slideIdToNotes) { - SlideListWithText notesSLWT = _documentRecord.getNotesSlideListWithText(); - - if (notesSLWT == null) { - return; - } - - // Match up the records and the SlideAtomSets - int idx = -1; - for (SlideAtomsSet notesSet : notesSLWT.getSlideAtomsSets()) { - idx++; - // Get the right core record - Record r = getCoreRecordForSAS(notesSet); - SlidePersistAtom spa = notesSet.getSlidePersistAtom(); - - String loggerLoc = "A Notes SlideAtomSet at "+idx+" said its record was at refID "+spa.getRefID(); - - // we need to add null-records, otherwise the index references to other existing don't work anymore - if (r == null) { - logger.log(POILogger.WARN, loggerLoc+", but that record didn't exist - record ignored."); - continue; - } - - // Ensure it really is a notes record - if (!(r instanceof Notes)) { - logger.log(POILogger.ERROR, loggerLoc+", but that was actually a " + r); - continue; - } - - Notes notesRecord = (Notes) r; - - // Record the match between slide id and these notes - int slideId = spa.getSlideIdentifier(); - slideIdToNotes.put(slideId, idx); - - HSLFNotes hn = new HSLFNotes(notesRecord); - hn.setSlideShow(this); - _notes.add(hn); - } - } - - private void findSlides(Map slideIdToNotes) { - SlideListWithText slidesSLWT = _documentRecord.getSlideSlideListWithText(); - if (slidesSLWT == null) { - return; - } - - // Match up the records and the SlideAtomSets - int idx = -1; - for (SlideAtomsSet sas : slidesSLWT.getSlideAtomsSets()) { - idx++; - // Get the right core record - SlidePersistAtom spa = sas.getSlidePersistAtom(); - Record r = getCoreRecordForSAS(sas); - - // Ensure it really is a slide record - if (!(r instanceof Slide)) { - logger.log(POILogger.ERROR, "A Slide SlideAtomSet at " + idx - + " said its record was at refID " - + spa.getRefID() - + ", but that was actually a " + r); - continue; - } - - Slide slide = (Slide)r; - - // Do we have a notes for this? - HSLFNotes notes = null; - // Slide.SlideAtom.notesId references the corresponding notes slide. - // 0 if slide has no notes. - int noteId = slide.getSlideAtom().getNotesID(); - if (noteId != 0) { - Integer notesPos = slideIdToNotes.get(noteId); - if (notesPos != null && 0 <= notesPos && notesPos < _notes.size()) { - notes = _notes.get(notesPos); - } else { - logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId); - } - } - - // Now, build our slide - int slideIdentifier = spa.getSlideIdentifier(); - HSLFSlide hs = new HSLFSlide(slide, notes, sas, slideIdentifier, (idx + 1)); - hs.setSlideShow(this); - _slides.add(hs); - } - } - - @Override - public void write(OutputStream out) throws IOException { - // check for text paragraph modifications - for (HSLFSlide sl : getSlides()) { - writeDirtyParagraphs(sl); - } - - for (HSLFSlideMaster sl : getSlideMasters()) { - boolean isDirty = false; - for (List paras : sl.getTextParagraphs()) { - for (HSLFTextParagraph p : paras) { - isDirty |= p.isDirty(); - } - } - if (isDirty) { - for (TxMasterStyleAtom sa : sl.getTxMasterStyleAtoms()) { - if (sa != null) { - // not all master style atoms are set - index 3 is typically null - sa.updateStyles(); - } - } - } - } - - _hslfSlideShow.write(out); - } - - private void writeDirtyParagraphs(HSLFShapeContainer container) { - for (HSLFShape sh : container.getShapes()) { - if (sh instanceof HSLFShapeContainer) { - writeDirtyParagraphs((HSLFShapeContainer)sh); - } else if (sh instanceof HSLFTextShape) { - HSLFTextShape hts = (HSLFTextShape)sh; - boolean isDirty = false; - for (HSLFTextParagraph p : hts.getTextParagraphs()) { - isDirty |= p.isDirty(); - } - if (isDirty) hts.storeText(); - } - } - } - - /** - * Returns an array of the most recent version of all the interesting - * records - */ - public Record[] getMostRecentCoreRecords() { - return _mostRecentCoreRecords; - } - - /** - * Returns an array of all the normal Slides found in the slideshow - */ - @Override - public List getSlides() { - return _slides; - } - - /** - * Returns an array of all the normal Notes found in the slideshow - */ - public List getNotes() { - return _notes; - } - - /** - * Returns an array of all the normal Slide Masters found in the slideshow - */ - @Override - public List getSlideMasters() { - return _masters; - } - - /** - * Returns an array of all the normal Title Masters found in the slideshow - */ - public List getTitleMasters() { - return _titleMasters; - } - - @Override - public List getPictureData() { - return _hslfSlideShow.getPictureData(); - } - - /** - * Returns the data of all the embedded OLE object in the SlideShow - */ - public HSLFObjectData[] getEmbeddedObjects() { - return _hslfSlideShow.getEmbeddedObjects(); - } - - /** - * Returns the data of all the embedded sounds in the SlideShow - */ - public HSLFSoundData[] getSoundData() { - return HSLFSoundData.find(_documentRecord); - } - - @Override - public Dimension getPageSize() { - DocumentAtom docatom = _documentRecord.getDocumentAtom(); - int pgx = (int)Units.masterToPoints((int)docatom.getSlideSizeX()); - int pgy = (int)Units.masterToPoints((int)docatom.getSlideSizeY()); - return new Dimension(pgx, pgy); - } - - @Override - public void setPageSize(Dimension pgsize) { - DocumentAtom docatom = _documentRecord.getDocumentAtom(); - docatom.setSlideSizeX(Units.pointsToMaster(pgsize.width)); - docatom.setSlideSizeY(Units.pointsToMaster(pgsize.height)); - } - - /** - * Helper method for usermodel: Get the font collection - */ - protected FontCollection getFontCollection() { - return _fonts; - } - - /** - * Helper method for usermodel and model: Get the document record - */ - public Document getDocumentRecord() { - return _documentRecord; - } - - /** - * Re-orders a slide, to a new position. - * - * @param oldSlideNumber - * The old slide number (1 based) - * @param newSlideNumber - * The new slide number (1 based) - */ - public void reorderSlide(int oldSlideNumber, int newSlideNumber) { - // Ensure these numbers are valid - if (oldSlideNumber < 1 || newSlideNumber < 1) { - throw new IllegalArgumentException("Old and new slide numbers must be greater than 0"); - } - if (oldSlideNumber > _slides.size() || newSlideNumber > _slides.size()) { - throw new IllegalArgumentException( - "Old and new slide numbers must not exceed the number of slides (" - + _slides.size() + ")"); - } - - // The order of slides is defined by the order of slide atom sets in the - // SlideListWithText container. - SlideListWithText slwt = _documentRecord.getSlideSlideListWithText(); - SlideAtomsSet[] sas = slwt.getSlideAtomsSets(); - - SlideAtomsSet tmp = sas[oldSlideNumber - 1]; - sas[oldSlideNumber - 1] = sas[newSlideNumber - 1]; - sas[newSlideNumber - 1] = tmp; - - Collections.swap(_slides, oldSlideNumber - 1, newSlideNumber - 1); - _slides.get(newSlideNumber - 1).setSlideNumber(newSlideNumber); - _slides.get(oldSlideNumber - 1).setSlideNumber(oldSlideNumber); - - ArrayList lst = new ArrayList(); - for (SlideAtomsSet s : sas) { - lst.add(s.getSlidePersistAtom()); - lst.addAll(Arrays.asList(s.getSlideRecords())); - } - - Record[] r = lst.toArray(new Record[lst.size()]); - slwt.setChildRecord(r); - } - - /** - * Removes the slide at the given index (0-based). - *

        - * Shifts any subsequent slides to the left (subtracts one from their slide - * numbers). - *

        - * - * @param index - * the index of the slide to remove (0-based) - * @return the slide that was removed from the slide show. - */ - public HSLFSlide removeSlide(int index) { - int lastSlideIdx = _slides.size() - 1; - if (index < 0 || index > lastSlideIdx) { - throw new IllegalArgumentException("Slide index (" + index + ") is out of range (0.." - + lastSlideIdx + ")"); - } - - SlideListWithText slwt = _documentRecord.getSlideSlideListWithText(); - SlideAtomsSet[] sas = slwt.getSlideAtomsSets(); - - List records = new ArrayList(); - List sa = new ArrayList(Arrays.asList(sas)); - - HSLFSlide removedSlide = _slides.remove(index); - _notes.remove(removedSlide.getNotes()); - sa.remove(index); - - int i=0; - for (HSLFSlide s : _slides) s.setSlideNumber(i++); - - for (SlideAtomsSet s : sa) { - records.add(s.getSlidePersistAtom()); - records.addAll(Arrays.asList(s.getSlideRecords())); - } - if (sa.isEmpty()) { - _documentRecord.removeSlideListWithText(slwt); - } else { - slwt.setSlideAtomsSets(sa.toArray(new SlideAtomsSet[sa.size()])); - slwt.setChildRecord(records.toArray(new Record[records.size()])); - } - - // if the removed slide had notes - remove references to them too - - int notesId = removedSlide.getSlideRecord().getSlideAtom().getNotesID(); - if (notesId != 0) { - SlideListWithText nslwt = _documentRecord.getNotesSlideListWithText(); - records = new ArrayList(); - ArrayList na = new ArrayList(); - for (SlideAtomsSet ns : nslwt.getSlideAtomsSets()) { - if (ns.getSlidePersistAtom().getSlideIdentifier() == notesId) continue; - na.add(ns); - records.add(ns.getSlidePersistAtom()); - if (ns.getSlideRecords() != null) { - records.addAll(Arrays.asList(ns.getSlideRecords())); - } - } - if (na.isEmpty()) { - _documentRecord.removeSlideListWithText(nslwt); - } else { - nslwt.setSlideAtomsSets(na.toArray(new SlideAtomsSet[na.size()])); - nslwt.setChildRecord(records.toArray(new Record[records.size()])); - } - } - - return removedSlide; - } - - /** - * Create a blank Slide. - * - * @return the created Slide - */ - @Override - public HSLFSlide createSlide() { - // We need to add the records to the SLWT that deals - // with Slides. - // Add it, if it doesn't exist - SlideListWithText slist = _documentRecord.getSlideSlideListWithText(); - if (slist == null) { - // Need to add a new one - slist = new SlideListWithText(); - slist.setInstance(SlideListWithText.SLIDES); - _documentRecord.addSlideListWithText(slist); - } - - // Grab the SlidePersistAtom with the highest Slide Number. - // (Will stay as null if no SlidePersistAtom exists yet in - // the slide, or only master slide's ones do) - SlidePersistAtom prev = null; - for (SlideAtomsSet sas : slist.getSlideAtomsSets()) { - SlidePersistAtom spa = sas.getSlidePersistAtom(); - if (spa.getSlideIdentifier() < 0) { - // This is for a master slide - // Odd, since we only deal with the Slide SLWT - } else { - // Must be for a real slide - if (prev == null) { - prev = spa; - } - if (prev.getSlideIdentifier() < spa.getSlideIdentifier()) { - prev = spa; - } - } - } - - // Set up a new SlidePersistAtom for this slide - SlidePersistAtom sp = new SlidePersistAtom(); - - // First slideId is always 256 - sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1)); - - // Add this new SlidePersistAtom to the SlideListWithText - slist.addSlidePersistAtom(sp); - - // Create a new Slide - HSLFSlide slide = new HSLFSlide(sp.getSlideIdentifier(), sp.getRefID(), _slides.size() + 1); - slide.setSlideShow(this); - slide.onCreate(); - - // Add in to the list of Slides - _slides.add(slide); - logger.log(POILogger.INFO, "Added slide " + _slides.size() + " with ref " + sp.getRefID() - + " and identifier " + sp.getSlideIdentifier()); - - // Add the core records for this new Slide to the record tree - Slide slideRecord = slide.getSlideRecord(); - int psrId = addPersistentObject(slideRecord); - sp.setRefID(psrId); - slideRecord.setSheetId(psrId); - - slide.setMasterSheet(_masters.get(0)); - // All done and added - return slide; - } - - @Override - public HSLFPictureData addPicture(byte[] data, PictureType format) throws IOException { - if (format == null || format.nativeId == -1) { - throw new IllegalArgumentException("Unsupported picture format: " + format); - } - - HSLFPictureData pd = findPictureData(data); - if (pd != null) { - // identical picture was already added to the SlideShow - return pd; - } - - EscherContainerRecord bstore; - - EscherContainerRecord dggContainer = _documentRecord.getPPDrawingGroup().getDggContainer(); - bstore = (EscherContainerRecord) HSLFShape.getEscherChild(dggContainer, - EscherContainerRecord.BSTORE_CONTAINER); - if (bstore == null) { - bstore = new EscherContainerRecord(); - bstore.setRecordId(EscherContainerRecord.BSTORE_CONTAINER); - - dggContainer.addChildBefore(bstore, EscherOptRecord.RECORD_ID); - } - - HSLFPictureData pict = HSLFPictureData.create(format); - pict.setData(data); - - int offset = _hslfSlideShow.addPicture(pict); - - EscherBSERecord bse = new EscherBSERecord(); - bse.setRecordId(EscherBSERecord.RECORD_ID); - bse.setOptions((short) (0x0002 | (format.nativeId << 4))); - bse.setSize(pict.getRawData().length + 8); - byte[] uid = HSLFPictureData.getChecksum(data); - bse.setUid(uid); - - bse.setBlipTypeMacOS((byte) format.nativeId); - bse.setBlipTypeWin32((byte) format.nativeId); - - if (format == PictureType.EMF) { - bse.setBlipTypeMacOS((byte) PictureType.PICT.nativeId); - } else if (format == PictureType.WMF) { - bse.setBlipTypeMacOS((byte) PictureType.PICT.nativeId); - } else if (format == PictureType.PICT) { - bse.setBlipTypeWin32((byte) PictureType.WMF.nativeId); - } - - bse.setRef(0); - bse.setOffset(offset); - bse.setRemainingData(new byte[0]); - - bstore.addChildRecord(bse); - int count = bstore.getChildRecords().size(); - bstore.setOptions((short) ((count << 4) | 0xF)); - - return pict; - } - - /** - * Adds a picture to the presentation. - * - * @param is The stream to read the image from - * @param format The format of the picture. - * - * @return the picture data. - * @since 3.15 beta 2 - */ - @Override - public HSLFPictureData addPicture(InputStream is, PictureType format) throws IOException { - if (format == null || format.nativeId == -1) { // fail early - throw new IllegalArgumentException("Unsupported picture format: " + format); - } - return addPicture(IOUtils.toByteArray(is), format); - } - - /** - * Adds a picture to the presentation. - * - * @param pict - * the file containing the image to add - * @param format - * The format of the picture. - * - * @return the picture data. - * @since 3.15 beta 2 - */ - @Override - public HSLFPictureData addPicture(File pict, PictureType format) throws IOException { - if (format == null || format.nativeId == -1) { // fail early - throw new IllegalArgumentException("Unsupported picture format: " + format); - } - int length = (int) pict.length(); - byte[] data = new byte[length]; - FileInputStream is = new FileInputStream(pict); - try { - IOUtils.readFully(is, data); - } finally { - is.close(); - } - return addPicture(data, format); - } - - /** - * check if a picture with this picture data already exists in this presentation - * - * @param pictureData The picture data to find in the SlideShow - * @return {@code null} if picture data is not found in this slideshow - * @since 3.15 beta 3 - */ - @Override - public HSLFPictureData findPictureData(byte[] pictureData) { - byte[] uid = HSLFPictureData.getChecksum(pictureData); - - for (HSLFPictureData pic : getPictureData()) { - if (Arrays.equals(pic.getUID(), uid)) { - return pic; - } - } - return null; - } - - /** - * Add a font in this presentation - * - * @param font - * the font to add - * @return 0-based index of the font - */ - public int addFont(PPFont font) { - FontCollection fonts = getDocumentRecord().getEnvironment().getFontCollection(); - int idx = fonts.getFontIndex(font.getFontName()); - if (idx == -1) { - idx = fonts.addFont(font.getFontName(), font.getCharSet(), font.getFontFlags(), font - .getFontType(), font.getPitchAndFamily()); - } - return idx; - } - - /** - * Get a font by index - * - * @param idx - * 0-based index of the font - * @return of an instance of PPFont or null if not - * found - */ - public PPFont getFont(int idx) { - FontCollection fonts = getDocumentRecord().getEnvironment().getFontCollection(); - for (Record ch : fonts.getChildRecords()) { - if (ch instanceof FontEntityAtom) { - FontEntityAtom atom = (FontEntityAtom) ch; - if (atom.getFontIndex() == idx) { - return new PPFont(atom); - } - } - } - return null; - } - - /** - * get the number of fonts in the presentation - * - * @return number of fonts - */ - public int getNumberOfFonts() { - return getDocumentRecord().getEnvironment().getFontCollection().getNumberOfFonts(); - } - - /** - * Return Header / Footer settings for slides - * - * @return Header / Footer settings for slides - */ - public HeadersFooters getSlideHeadersFooters() { - return new HeadersFooters(this, HeadersFootersContainer.SlideHeadersFootersContainer); - } - - /** - * Return Header / Footer settings for notes - * - * @return Header / Footer settings for notes - */ - public HeadersFooters getNotesHeadersFooters() { - if (_notes.isEmpty()) { - return new HeadersFooters(this, HeadersFootersContainer.NotesHeadersFootersContainer); - } else { - return new HeadersFooters(_notes.get(0), HeadersFootersContainer.NotesHeadersFootersContainer); - } - } - - /** - * Add a movie in this presentation - * - * @param path - * the path or url to the movie - * @return 0-based index of the movie - */ - public int addMovie(String path, int type) { - ExMCIMovie mci; - switch (type) { - case MovieShape.MOVIE_MPEG: - mci = new ExMCIMovie(); - break; - case MovieShape.MOVIE_AVI: - mci = new ExAviMovie(); - break; - default: - throw new IllegalArgumentException("Unsupported Movie: " + type); - } - - ExVideoContainer exVideo = mci.getExVideo(); - exVideo.getExMediaAtom().setMask(0xE80000); - exVideo.getPathAtom().setText(path); - - int objectId = addToObjListAtom(mci); - exVideo.getExMediaAtom().setObjectId(objectId); - - return objectId; - } - - /** - * Add a control in this presentation - * - * @param name - * name of the control, e.g. "Shockwave Flash Object" - * @param progId - * OLE Programmatic Identifier, e.g. - * "ShockwaveFlash.ShockwaveFlash.9" - * @return 0-based index of the control - */ - public int addControl(String name, String progId) { - ExControl ctrl = new ExControl(); - ctrl.setProgId(progId); - ctrl.setMenuName(name); - ctrl.setClipboardName(name); - - ExOleObjAtom oleObj = ctrl.getExOleObjAtom(); - oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE); - oleObj.setType(ExOleObjAtom.TYPE_CONTROL); - oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT); - - int objectId = addToObjListAtom(ctrl); - oleObj.setObjID(objectId); - return objectId; - } - - /** - * Add a embedded object to this presentation - * - * @return 0-based index of the embedded object - */ - public int addEmbed(POIFSFileSystem poiData) { - DirectoryNode root = poiData.getRoot(); - - // prepare embedded data - if (new ClassID().equals(root.getStorageClsid())) { - // need to set class id - Map olemap = getOleMap(); - ClassID classID = null; - for (Map.Entry entry : olemap.entrySet()) { - if (root.hasEntry(entry.getKey())) { - classID = entry.getValue(); - break; - } - } - if (classID == null) { - throw new IllegalArgumentException("Unsupported embedded document"); - } - - root.setStorageClsid(classID); - } - - ExEmbed exEmbed = new ExEmbed(); - // remove unneccessary infos, so we don't need to specify the type - // of the ole object multiple times - Record children[] = exEmbed.getChildRecords(); - exEmbed.removeChild(children[2]); - exEmbed.removeChild(children[3]); - exEmbed.removeChild(children[4]); - - ExEmbedAtom eeEmbed = exEmbed.getExEmbedAtom(); - eeEmbed.setCantLockServerB(true); - - ExOleObjAtom eeAtom = exEmbed.getExOleObjAtom(); - eeAtom.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE); - eeAtom.setType(ExOleObjAtom.TYPE_EMBEDDED); - // eeAtom.setSubType(ExOleObjAtom.SUBTYPE_EXCEL); - // should be ignored?!?, see MS-PPT ExOleObjAtom, but Libre Office sets it ... - eeAtom.setOptions(1226240); - - ExOleObjStg exOleObjStg = new ExOleObjStg(); - try { - final String OLESTREAM_NAME = "\u0001Ole"; - if (!root.hasEntry(OLESTREAM_NAME)) { - // the following data was taken from an example libre office document - // beside this "\u0001Ole" record there were several other records, e.g. CompObj, - // OlePresXXX, but it seems, that they aren't neccessary - byte oleBytes[] = { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - poiData.createDocument(new ByteArrayInputStream(oleBytes), OLESTREAM_NAME); - } - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - poiData.writeFilesystem(bos); - exOleObjStg.setData(bos.toByteArray()); - } catch (IOException e) { - throw new HSLFException(e); - } - - int psrId = addPersistentObject(exOleObjStg); - exOleObjStg.setPersistId(psrId); - eeAtom.setObjStgDataRef(psrId); - - int objectId = addToObjListAtom(exEmbed); - eeAtom.setObjID(objectId); - return objectId; - } - - protected int addToObjListAtom(RecordContainer exObj) { - ExObjList lst = getDocumentRecord().getExObjList(true); - ExObjListAtom objAtom = lst.getExObjListAtom(); - // increment the object ID seed - int objectId = (int) objAtom.getObjectIDSeed() + 1; - objAtom.setObjectIDSeed(objectId); - - lst.addChildAfter(exObj, objAtom); - - return objectId; - } - - protected static Map getOleMap() { - Map olemap = new HashMap(); - olemap.put("PowerPoint Document", ClassID.PPT_SHOW); - olemap.put("Workbook", ClassID.EXCEL97); // as per BIFF8 spec - olemap.put("WORKBOOK", ClassID.EXCEL97); // Typically from third party programs - olemap.put("BOOK", ClassID.EXCEL97); // Typically odd Crystal Reports exports - // ... to be continued - return olemap; - } - - protected int addPersistentObject(PositionDependentRecord slideRecord) { - slideRecord.setLastOnDiskOffset(HSLFSlideShowImpl.UNSET_OFFSET); - _hslfSlideShow.appendRootLevelRecord((Record)slideRecord); - - // For position dependent records, hold where they were and now are - // As we go along, update, and hand over, to any Position Dependent - // records we happen across - Map interestingRecords = - new HashMap(); - - try { - _hslfSlideShow.updateAndWriteDependantRecords(null,interestingRecords); - } catch (IOException e) { - throw new HSLFException(e); - } - - PersistPtrHolder ptr = (PersistPtrHolder)interestingRecords.get(RecordTypes.PersistPtrIncrementalBlock); - UserEditAtom usr = (UserEditAtom)interestingRecords.get(RecordTypes.UserEditAtom); - - // persist ID is UserEditAtom.maxPersistWritten + 1 - int psrId = usr.getMaxPersistWritten() + 1; - - // Last view is now of the slide - usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW); - // increment the number of persistent objects - usr.setMaxPersistWritten(psrId); - - // Add the new slide into the last PersistPtr - // (Also need to tell it where it is) - int slideOffset = slideRecord.getLastOnDiskOffset(); - slideRecord.setLastOnDiskOffset(slideOffset); - ptr.addSlideLookup(psrId, slideOffset); - logger.log(POILogger.INFO, "New slide/object ended up at " + slideOffset); - - return psrId; - } - - public MasterSheet createMasterSheet() throws IOException { - // TODO Auto-generated method stub - return null; - } - - public Resources getResources() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void close() throws IOException { - _hslfSlideShow.close(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowEncrypted.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowEncrypted.java deleted file mode 100644 index c2dd42098..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowEncrypted.java +++ /dev/null @@ -1,580 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.io.Closeable; -import java.io.IOException; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.NavigableMap; -import java.util.TreeMap; - -import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; -import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException; -import org.apache.poi.hslf.record.DocumentEncryptionAtom; -import org.apache.poi.hslf.record.PersistPtrHolder; -import org.apache.poi.hslf.record.PositionDependentRecord; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.UserEditAtom; -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; -import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; -import org.apache.poi.poifs.crypt.Decryptor; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIDecryptor; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptor; -import org.apache.poi.util.BitField; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayInputStream; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; - -/** - * This class provides helper functions for encrypted PowerPoint documents. - */ -@Internal -public class HSLFSlideShowEncrypted implements Closeable { - DocumentEncryptionAtom dea; - CryptoAPIEncryptor enc = null; - CryptoAPIDecryptor dec = null; -// Cipher cipher = null; - ChunkedCipherOutputStream cyos = null; - - private static final BitField fieldRecInst = new BitField(0xFFF0); - - private static final int BLIB_STORE_ENTRY_PARTS[] = { - 1, // btWin32 - 1, // btMacOS - 16, // rgbUid - 2, // tag - 4, // size - 4, // cRef - 4, // foDelay - 1, // unused1 - 1, // cbName (@ index 33) - 1, // unused2 - 1, // unused3 - }; - - protected HSLFSlideShowEncrypted(DocumentEncryptionAtom dea) { - this.dea = dea; - } - - protected HSLFSlideShowEncrypted(byte[] docstream, NavigableMap recordMap) { - // check for DocumentEncryptionAtom, which would be at the last offset - // need to ignore already set UserEdit and PersistAtoms - UserEditAtom userEditAtomWithEncryption = null; - for (Map.Entry me : recordMap.descendingMap().entrySet()) { - Record r = me.getValue(); - if (!(r instanceof UserEditAtom)) { - continue; - } - UserEditAtom uea = (UserEditAtom)r; - if (uea.getEncryptSessionPersistIdRef() != -1) { - userEditAtomWithEncryption = uea; - break; - } - } - - if (userEditAtomWithEncryption == null) { - dea = null; - return; - } - - Record r = recordMap.get(userEditAtomWithEncryption.getPersistPointersOffset()); - assert(r instanceof PersistPtrHolder); - PersistPtrHolder ptr = (PersistPtrHolder)r; - - Integer encOffset = ptr.getSlideLocationsLookup().get(userEditAtomWithEncryption.getEncryptSessionPersistIdRef()); - if (encOffset == null) { - // encryption info doesn't exist anymore - // SoftMaker Freeoffice produces such invalid files - check for "SMNativeObjData" ole stream - dea = null; - return; - } - - r = recordMap.get(encOffset); - if (r == null) { - r = Record.buildRecordAtOffset(docstream, encOffset); - recordMap.put(encOffset, r); - } - assert(r instanceof DocumentEncryptionAtom); - this.dea = (DocumentEncryptionAtom)r; - decryptInit(); - - String pass = Biff8EncryptionKey.getCurrentUserPassword(); - if(!dec.verifyPassword(pass != null ? pass : Decryptor.DEFAULT_PASSWORD)) { - throw new EncryptedPowerPointFileException("PowerPoint file is encrypted. The correct password needs to be set via Biff8EncryptionKey.setCurrentUserPassword()"); - } - } - - public DocumentEncryptionAtom getDocumentEncryptionAtom() { - return dea; - } - - protected void decryptInit() { - if (dec != null) { - return; - } - EncryptionInfo ei = dea.getEncryptionInfo(); - dec = (CryptoAPIDecryptor)ei.getDecryptor(); - } - - protected void encryptInit() { - if (enc != null) { - return; - } - EncryptionInfo ei = dea.getEncryptionInfo(); - enc = (CryptoAPIEncryptor)ei.getEncryptor(); - } - - - - protected OutputStream encryptRecord(OutputStream plainStream, int persistId, Record record) { - boolean isPlain = (dea == null - || record instanceof UserEditAtom - || record instanceof PersistPtrHolder - || record instanceof DocumentEncryptionAtom - ); - - try { - if (isPlain) { - if (cyos != null) { - // write cached data to stream - cyos.flush(); - } - return plainStream; - } - - encryptInit(); - - if (cyos == null) { - enc.setChunkSize(-1); - cyos = enc.getDataStream(plainStream, 0); - } - cyos.initCipherForBlock(persistId, false); - } catch (Exception e) { - throw new EncryptedPowerPointFileException(e); - } - return cyos; - } - - private static void readFully(ChunkedCipherInputStream ccis, byte[] docstream, int offset, int len) throws IOException { - if (IOUtils.readFully(ccis, docstream, offset, len) == -1) { - throw new EncryptedPowerPointFileException("unexpected EOF"); - } - } - - protected void decryptRecord(byte[] docstream, int persistId, int offset) { - if (dea == null) { - return; - } - - decryptInit(); - dec.setChunkSize(-1); - LittleEndianByteArrayInputStream lei = new LittleEndianByteArrayInputStream(docstream, offset); - ChunkedCipherInputStream ccis = null; - try { - ccis = dec.getDataStream(lei, docstream.length-offset, 0); - ccis.initCipherForBlock(persistId); - - // decrypt header and read length to be decrypted - readFully(ccis, docstream, offset, 8); - // decrypt the rest of the record - int rlen = (int)LittleEndian.getUInt(docstream, offset+4); - readFully(ccis, docstream, offset+8, rlen); - - } catch (Exception e) { - throw new EncryptedPowerPointFileException(e); - } finally { - try { - if (ccis != null) { - ccis.close(); - } - lei.close(); - } catch (IOException e) { - throw new EncryptedPowerPointFileException(e); - } - } - } - - private void decryptPicBytes(byte[] pictstream, int offset, int len) - throws IOException, GeneralSecurityException { - // when reading the picture elements, each time a segment is read, the cipher needs - // to be reset (usually done when calling Cipher.doFinal) - LittleEndianByteArrayInputStream lei = new LittleEndianByteArrayInputStream(pictstream, offset); - ChunkedCipherInputStream ccis = dec.getDataStream(lei, len, 0); - readFully(ccis, pictstream, offset, len); - ccis.close(); - lei.close(); - } - - protected void decryptPicture(byte[] pictstream, int offset) { - if (dea == null) { - return; - } - - decryptInit(); - - try { - // decrypt header and read length to be decrypted - decryptPicBytes(pictstream, offset, 8); - int recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset)); - int recType = LittleEndian.getUShort(pictstream, offset+2); - int rlen = (int)LittleEndian.getUInt(pictstream, offset+4); - offset += 8; - int endOffset = offset + rlen; - - if (recType == 0xF007) { - // TOOD: get a real example file ... to actual test the FBSE entry - // not sure where the foDelay block is - - // File BLIP Store Entry (FBSE) - for (int part : BLIB_STORE_ENTRY_PARTS) { - decryptPicBytes(pictstream, offset, part); - } - offset += 36; - - int cbName = LittleEndian.getUShort(pictstream, offset-3); - if (cbName > 0) { - // read nameData - decryptPicBytes(pictstream, offset, cbName); - offset += cbName; - } - - if (offset == endOffset) { - return; // no embedded blip - } - // fall through, read embedded blip now - - // update header data - decryptPicBytes(pictstream, offset, 8); - recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset)); - recType = LittleEndian.getUShort(pictstream, offset+2); - // rlen = (int)LittleEndian.getUInt(pictstream, offset+4); - offset += 8; - } - - int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 || - recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1; - - // rgbUid 1/2 - for (int i=0; i 0) { - ccos.write(pictstream, offset, cbName); - ccos.flush(); - offset += cbName; - } - - if (offset == endOffset) { - return; // no embedded blip - } - // fall through, read embedded blip now - - // update header data - recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset)); - recType = LittleEndian.getUShort(pictstream, offset+2); - ccos.write(pictstream, offset, 8); - ccos.flush(); - offset += 8; - } - - int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 || - recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1; - - for (int i=0; i done - return records; - } else { - // need to remove password data - dea = null; - return removeEncryptionRecord(records); - } - } else { - // create password record - if (dea == null) { - dea = new DocumentEncryptionAtom(); - enc = null; - } - encryptInit(); - EncryptionInfo ei = dea.getEncryptionInfo(); - byte salt[] = ei.getVerifier().getSalt(); - if (salt == null) { - enc.confirmPassword(password); - } else { - byte verifier[] = ei.getDecryptor().getVerifier(); - enc.confirmPassword(password, null, null, verifier, salt, null); - } - - // move EncryptionRecord to last slide position - records = normalizeRecords(records); - return addEncryptionRecord(records, dea); - } - } - - /** - * remove duplicated UserEditAtoms and merge PersistPtrHolder. - * Before this method is called, make sure that the offsets are correct, - * i.e. call {@link HSLFSlideShowImpl#updateAndWriteDependantRecords(OutputStream, Map)} - */ - protected static Record[] normalizeRecords(Record records[]) { - // http://msdn.microsoft.com/en-us/library/office/gg615594(v=office.14).aspx - // repeated slideIds can be overwritten, i.e. ignored - - UserEditAtom uea = null; - PersistPtrHolder pph = null; - TreeMap slideLocations = new TreeMap(); - TreeMap recordMap = new TreeMap(); - List obsoleteOffsets = new ArrayList(); - int duplicatedCount = 0; - for (Record r : records) { - assert(r instanceof PositionDependentRecord); - PositionDependentRecord pdr = (PositionDependentRecord)r; - if (pdr instanceof UserEditAtom) { - uea = (UserEditAtom)pdr; - continue; - } - - if (pdr instanceof PersistPtrHolder) { - if (pph != null) { - duplicatedCount++; - } - pph = (PersistPtrHolder)pdr; - for (Map.Entry me : pph.getSlideLocationsLookup().entrySet()) { - Integer oldOffset = slideLocations.put(me.getKey(), me.getValue()); - if (oldOffset != null) { - obsoleteOffsets.add(oldOffset); - } - } - continue; - } - - recordMap.put(pdr.getLastOnDiskOffset(), r); - } - - assert(uea != null && pph != null && uea.getPersistPointersOffset() == pph.getLastOnDiskOffset()); - - recordMap.put(pph.getLastOnDiskOffset(), pph); - recordMap.put(uea.getLastOnDiskOffset(), uea); - - if (duplicatedCount == 0 && obsoleteOffsets.isEmpty()) { - return records; - } - - uea.setLastUserEditAtomOffset(0); - pph.clear(); - for (Map.Entry me : slideLocations.entrySet()) { - pph.addSlideLookup(me.getKey(), me.getValue()); - } - - for (Integer oldOffset : obsoleteOffsets) { - recordMap.remove(oldOffset); - } - - return recordMap.values().toArray(new Record[recordMap.size()]); - } - - - protected static Record[] removeEncryptionRecord(Record records[]) { - int deaSlideId = -1; - int deaOffset = -1; - PersistPtrHolder ptr = null; - UserEditAtom uea = null; - List recordList = new ArrayList(); - for (Record r : records) { - if (r instanceof DocumentEncryptionAtom) { - deaOffset = ((DocumentEncryptionAtom)r).getLastOnDiskOffset(); - continue; - } else if (r instanceof UserEditAtom) { - uea = (UserEditAtom)r; - deaSlideId = uea.getEncryptSessionPersistIdRef(); - uea.setEncryptSessionPersistIdRef(-1); - } else if (r instanceof PersistPtrHolder) { - ptr = (PersistPtrHolder)r; - } - recordList.add(r); - } - - assert(ptr != null); - if (deaSlideId == -1 && deaOffset == -1) { - return records; - } - - TreeMap tm = new TreeMap(ptr.getSlideLocationsLookup()); - ptr.clear(); - int maxSlideId = -1; - for (Map.Entry me : tm.entrySet()) { - if (me.getKey() == deaSlideId || me.getValue() == deaOffset) { - continue; - } - ptr.addSlideLookup(me.getKey(), me.getValue()); - maxSlideId = Math.max(me.getKey(), maxSlideId); - } - - uea.setMaxPersistWritten(maxSlideId); - - records = recordList.toArray(new Record[recordList.size()]); - - return records; - } - - - protected static Record[] addEncryptionRecord(Record records[], DocumentEncryptionAtom dea) { - assert(dea != null); - int ueaIdx = -1, ptrIdx = -1, deaIdx = -1, idx = -1; - for (Record r : records) { - idx++; - if (r instanceof UserEditAtom) { - ueaIdx = idx; - } else if (r instanceof PersistPtrHolder) { - ptrIdx = idx; - } else if (r instanceof DocumentEncryptionAtom) { - deaIdx = idx; - } - } - assert(ueaIdx != -1 && ptrIdx != -1 && ptrIdx < ueaIdx); - if (deaIdx != -1) { - DocumentEncryptionAtom deaOld = (DocumentEncryptionAtom)records[deaIdx]; - dea.setLastOnDiskOffset(deaOld.getLastOnDiskOffset()); - records[deaIdx] = dea; - return records; - } else { - PersistPtrHolder ptr = (PersistPtrHolder)records[ptrIdx]; - UserEditAtom uea = ((UserEditAtom)records[ueaIdx]); - dea.setLastOnDiskOffset(ptr.getLastOnDiskOffset()-1); - int nextSlideId = uea.getMaxPersistWritten()+1; - ptr.addSlideLookup(nextSlideId, ptr.getLastOnDiskOffset()-1); - uea.setEncryptSessionPersistIdRef(nextSlideId); - uea.setMaxPersistWritten(nextSlideId); - - Record newRecords[] = new Record[records.length+1]; - if (ptrIdx > 0) { - System.arraycopy(records, 0, newRecords, 0, ptrIdx); - } - if (ptrIdx < records.length-1) { - System.arraycopy(records, ptrIdx, newRecords, ptrIdx+1, records.length-ptrIdx); - } - newRecords[ptrIdx] = dea; - return newRecords; - } - } - - public void close() throws IOException { - if (cyos != null) { - cyos.close(); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java deleted file mode 100644 index 3ae91f775..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.io.IOException; - -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.util.Internal; - -@Internal -public class HSLFSlideShowFactory extends SlideShowFactory { - /** - * Creates a HSLFSlideShow from the given NPOIFSFileSystem - *

        Note that in order to properly release resources the - * SlideShow should be closed after use. - */ - public static SlideShow createSlideShow(NPOIFSFileSystem fs) throws IOException { - return new HSLFSlideShow(fs); - } - -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java deleted file mode 100644 index 493d46174..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java +++ /dev/null @@ -1,900 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.NavigableMap; -import java.util.TreeMap; - -import org.apache.poi.POIDocument; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.record.CurrentUserAtom; -import org.apache.poi.hslf.record.DocumentEncryptionAtom; -import org.apache.poi.hslf.record.ExOleObjStg; -import org.apache.poi.hslf.record.PersistPtrHolder; -import org.apache.poi.hslf.record.PersistRecord; -import org.apache.poi.hslf.record.PositionDependentRecord; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.UserEditAtom; -import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptor; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.DocumentEntry; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.EntryUtils; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * This class contains the main functionality for the Powerpoint file - * "reader". It is only a very basic class for now - */ -public final class HSLFSlideShowImpl extends POIDocument implements Closeable { - public static final int UNSET_OFFSET = -1; - - // For logging - private POILogger logger = POILogFactory.getLogger(this.getClass()); - - // Holds metadata on where things are in our document - private CurrentUserAtom currentUser; - - // Low level contents of the file - private byte[] _docstream; - - // Low level contents - private Record[] _records; - - // Raw Pictures contained in the pictures stream - private List _pictures; - - // Embedded objects stored in storage records in the document stream, lazily populated. - private HSLFObjectData[] _objects; - - /** - * Returns the directory in the underlying POIFSFileSystem for the - * document that is open. - */ - protected DirectoryNode getPOIFSDirectory() { - return directory; - } - - /** - * Constructs a Powerpoint document from fileName. Parses the document - * and places all the important stuff into data structures. - * - * @param fileName The name of the file to read. - * @throws IOException if there is a problem while parsing the document. - */ - @SuppressWarnings("resource") - public HSLFSlideShowImpl(String fileName) throws IOException { - this(new POIFSFileSystem(new File(fileName))); - } - - /** - * Constructs a Powerpoint document from an input stream. Parses the - * document and places all the important stuff into data structures. - * - * @param inputStream the source of the data - * @throws IOException if there is a problem while parsing the document. - */ - @SuppressWarnings("resource") - public HSLFSlideShowImpl(InputStream inputStream) throws IOException { - //do Ole stuff - this(new POIFSFileSystem(inputStream)); - } - - /** - * Constructs a Powerpoint document from a POIFS Filesystem. Parses the - * document and places all the important stuff into data structures. - * - * @param filesystem the POIFS FileSystem to read from - * @throws IOException if there is a problem while parsing the document. - */ - public HSLFSlideShowImpl(POIFSFileSystem filesystem) throws IOException { - this(filesystem.getRoot()); - } - - /** - * Constructs a Powerpoint document from a POIFS Filesystem. Parses the - * document and places all the important stuff into data structures. - * - * @param filesystem the POIFS FileSystem to read from - * @throws IOException if there is a problem while parsing the document. - */ - public HSLFSlideShowImpl(NPOIFSFileSystem filesystem) throws IOException { - this(filesystem.getRoot()); - } - - /** - * Constructs a Powerpoint document from a specific point in a - * POIFS Filesystem. Parses the document and places all the - * important stuff into data structures. - * - * @param dir the POIFS directory to read from - * @throws IOException if there is a problem while parsing the document. - */ - public HSLFSlideShowImpl(DirectoryNode dir) throws IOException { - super(handleDualStorage(dir)); - - // First up, grab the "Current User" stream - // We need this before we can detect Encrypted Documents - readCurrentUserStream(); - - // Next up, grab the data that makes up the - // PowerPoint stream - readPowerPointStream(); - - // Now, build records based on the PowerPoint stream - buildRecords(); - - // Look for any other streams - readOtherStreams(); - } - - private static DirectoryNode handleDualStorage(DirectoryNode dir) throws IOException { - // when there's a dual storage entry, use it, as the outer document can't be read quite probably ... - String dualName = "PP97_DUALSTORAGE"; - if (!dir.hasEntry(dualName)) return dir; - dir = (DirectoryNode) dir.getEntry(dualName); - return dir; - } - - /** - * Constructs a new, empty, Powerpoint document. - */ - public static final HSLFSlideShowImpl create() { - InputStream is = HSLFSlideShowImpl.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt"); - if (is == null) { - throw new HSLFException("Missing resource 'empty.ppt'"); - } - try { - try { - return new HSLFSlideShowImpl(is); - } finally { - is.close(); - } - } catch (IOException e) { - throw new HSLFException(e); - } - } - - /** - * Extracts the main PowerPoint document stream from the - * POI file, ready to be passed - * - * @throws IOException - */ - private void readPowerPointStream() throws IOException { - // Get the main document stream - DocumentEntry docProps = - (DocumentEntry) directory.getEntry("PowerPoint Document"); - - // Grab the document stream - int len = docProps.getSize(); - InputStream is = directory.createDocumentInputStream("PowerPoint Document"); - try { - _docstream = IOUtils.toByteArray(is, len); - } finally { - is.close(); - } - } - - /** - * Builds the list of records, based on the contents - * of the PowerPoint stream - */ - private void buildRecords() { - // The format of records in a powerpoint file are: - // - // - // - // If it has a zero length, following it will be another record - // - // If it has a length, depending on its type it may have children or data - // If it has children, these will follow straight away - // > - // If it has data, this will come straigh after, and run for the length - // - // All lengths given exclude the 8 byte record header - // (Data records are known as Atoms) - - // Document should start with: - // 0F 00 E8 03 ## ## ## ## - // (type 1000 = document, info 00 0f is normal, rest is document length) - // 01 00 E9 03 28 00 00 00 - // (type 1001 = document atom, info 00 01 normal, 28 bytes long) - // 80 16 00 00 E0 10 00 00 xx xx xx xx xx xx xx xx - // 05 00 00 00 0A 00 00 00 xx xx xx - // (the contents of the document atom, not sure what it means yet) - // (records then follow) - - // When parsing a document, look to see if you know about that type - // of the current record. If you know it's a type that has children, - // process the record's data area looking for more records - // If you know about the type and it doesn't have children, either do - // something with the data (eg TextRun) or skip over it - // If you don't know about the type, play safe and skip over it (using - // its length to know where the next record will start) - // - - _records = read(_docstream, (int) currentUser.getCurrentEditOffset()); - } - - private Record[] read(byte[] docstream, int usrOffset) { - //sort found records by offset. - //(it is not necessary but SlideShow.findMostRecentCoreRecords() expects them sorted) - NavigableMap records = new TreeMap(); // offset -> record - Map persistIds = new HashMap(); // offset -> persistId - initRecordOffsets(docstream, usrOffset, records, persistIds); - HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(docstream, records); - - for (Map.Entry entry : records.entrySet()) { - Integer offset = entry.getKey(); - Record record = entry.getValue(); - Integer persistId = persistIds.get(offset); - if (record == null) { - // all plain records have been already added, - // only new records need to be decrypted (tbd #35897) - decryptData.decryptRecord(docstream, persistId, offset); - record = Record.buildRecordAtOffset(docstream, offset); - entry.setValue(record); - } - - if (record instanceof PersistRecord) { - ((PersistRecord) record).setPersistId(persistId); - } - } - - return records.values().toArray(new Record[records.size()]); - } - - private void initRecordOffsets(byte[] docstream, int usrOffset, NavigableMap recordMap, Map offset2id) { - while (usrOffset != 0) { - UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset); - recordMap.put(usrOffset, usr); - - int psrOffset = usr.getPersistPointersOffset(); - PersistPtrHolder ptr = (PersistPtrHolder) Record.buildRecordAtOffset(docstream, psrOffset); - recordMap.put(psrOffset, ptr); - - for (Map.Entry entry : ptr.getSlideLocationsLookup().entrySet()) { - Integer offset = entry.getValue(); - Integer id = entry.getKey(); - recordMap.put(offset, null); // reserve a slot for the record - offset2id.put(offset, id); - } - - usrOffset = usr.getLastUserEditAtomOffset(); - - // check for corrupted user edit atom and try to repair it - // if the next user edit atom offset is already known, we would go into an endless loop - if (usrOffset > 0 && recordMap.containsKey(usrOffset)) { - // a user edit atom is usually located 36 byte before the smallest known record offset - usrOffset = recordMap.firstKey() - 36; - // check that we really are located on a user edit atom - int ver_inst = LittleEndian.getUShort(docstream, usrOffset); - int type = LittleEndian.getUShort(docstream, usrOffset + 2); - int len = LittleEndian.getInt(docstream, usrOffset + 4); - if (ver_inst == 0 && type == 4085 && (len == 0x1C || len == 0x20)) { - logger.log(POILogger.WARN, "Repairing invalid user edit atom"); - usr.setLastUserEditAtomOffset(usrOffset); - } else { - throw new CorruptPowerPointFileException("Powerpoint document contains invalid user edit atom"); - } - } - } - } - - public DocumentEncryptionAtom getDocumentEncryptionAtom() { - for (Record r : _records) { - if (r instanceof DocumentEncryptionAtom) { - return (DocumentEncryptionAtom) r; - } - } - return null; - } - - - /** - * Find the "Current User" stream, and load it - */ - private void readCurrentUserStream() { - try { - currentUser = new CurrentUserAtom(directory); - } catch (IOException ie) { - logger.log(POILogger.ERROR, "Error finding Current User Atom:\n" + ie); - currentUser = new CurrentUserAtom(); - } - } - - /** - * Find any other streams from the filesystem, and load them - */ - private void readOtherStreams() { - // Currently, there aren't any - } - - /** - * Find and read in pictures contained in this presentation. - * This is lazily called as and when we want to touch pictures. - */ - private void readPictures() throws IOException { - _pictures = new ArrayList(); - - // if the presentation doesn't contain pictures - will use a null set instead - if (!directory.hasEntry("Pictures")) return; - - HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom()); - - DocumentEntry entry = (DocumentEntry) directory.getEntry("Pictures"); - DocumentInputStream is = directory.createDocumentInputStream(entry); - byte[] pictstream = IOUtils.toByteArray(is, entry.getSize()); - is.close(); - - int pos = 0; - // An empty picture record (length 0) will take up 8 bytes - while (pos <= (pictstream.length - 8)) { - int offset = pos; - - decryptData.decryptPicture(pictstream, offset); - - // Image signature - int signature = LittleEndian.getUShort(pictstream, pos); - pos += LittleEndian.SHORT_SIZE; - // Image type + 0xF018 - int type = LittleEndian.getUShort(pictstream, pos); - pos += LittleEndian.SHORT_SIZE; - // Image size (excluding the 8 byte header) - int imgsize = LittleEndian.getInt(pictstream, pos); - pos += LittleEndian.INT_SIZE; - - // When parsing the BStoreDelay stream, [MS-ODRAW] says that we - // should terminate if the type isn't 0xf007 or 0xf018->0xf117 - if (!((type == 0xf007) || (type >= 0xf018 && type <= 0xf117))) - break; - - // The image size must be 0 or greater - // (0 is allowed, but odd, since we do wind on by the header each - // time, so we won't get stuck) - if (imgsize < 0) { - throw new CorruptPowerPointFileException("The file contains a picture, at position " + _pictures.size() + ", which has a negatively sized data length, so we can't trust any of the picture data"); - } - - // If they type (including the bonus 0xF018) is 0, skip it - PictureType pt = PictureType.forNativeID(type - 0xF018); - if (pt == null) { - logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!"); - logger.log(POILogger.ERROR, "" + pos); - } else { - //The pictstream can be truncated halfway through a picture. - //This is not a problem if the pictstream contains extra pictures - //that are not used in any slide -- BUG-60305 - if (pos+imgsize > pictstream.length) { - logger.log(POILogger.WARN, "\"Pictures\" stream may have ended early. In some circumstances, this is not a problem; " + - "in others, this could indicate a corrupt file"); - break; - } - // Build the PictureData object from the data - try { - HSLFPictureData pict = HSLFPictureData.create(pt); - pict.setSignature(signature); - - // Copy the data, ready to pass to PictureData - byte[] imgdata = new byte[imgsize]; - System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length); - pict.setRawData(imgdata); - - pict.setOffset(offset); - pict.setIndex(_pictures.size()); - _pictures.add(pict); - } catch (IllegalArgumentException e) { - logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!"); - } - } - - pos += imgsize; - } - } - - /** - * remove duplicated UserEditAtoms and merge PersistPtrHolder, i.e. - * remove document edit history - */ - public void normalizeRecords() { - try { - updateAndWriteDependantRecords(null, null); - } catch (IOException e) { - throw new CorruptPowerPointFileException(e); - } - _records = HSLFSlideShowEncrypted.normalizeRecords(_records); - } - - - /** - * This is a helper functions, which is needed for adding new position dependent records - * or finally write the slideshow to a file. - * - * @param os the stream to write to, if null only the references are updated - * @param interestingRecords a map of interesting records (PersistPtrHolder and UserEditAtom) - * referenced by their RecordType. Only the very last of each type will be saved to the map. - * May be null, if not needed. - * @throws IOException - */ - public void updateAndWriteDependantRecords(OutputStream os, Map interestingRecords) - throws IOException { - // For position dependent records, hold where they were and now are - // As we go along, update, and hand over, to any Position Dependent - // records we happen across - Map oldToNewPositions = new HashMap(); - - // First pass - figure out where all the position dependent - // records are going to end up, in the new scheme - // (Annoyingly, some powerpoint files have PersistPtrHolders - // that reference slides after the PersistPtrHolder) - UserEditAtom usr = null; - PersistPtrHolder ptr = null; - CountingOS cos = new CountingOS(); - for (Record record : _records) { - // all top level records are position dependent - assert (record instanceof PositionDependentRecord); - PositionDependentRecord pdr = (PositionDependentRecord) record; - int oldPos = pdr.getLastOnDiskOffset(); - int newPos = cos.size(); - pdr.setLastOnDiskOffset(newPos); - if (oldPos != UNSET_OFFSET) { - // new records don't need a mapping, as they aren't in a relation yet - oldToNewPositions.put(oldPos, newPos); - } - - // Grab interesting records as they come past - // this will only save the very last record of each type - RecordTypes saveme = null; - int recordType = (int) record.getRecordType(); - if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) { - saveme = RecordTypes.PersistPtrIncrementalBlock; - ptr = (PersistPtrHolder) pdr; - } else if (recordType == RecordTypes.UserEditAtom.typeID) { - saveme = RecordTypes.UserEditAtom; - usr = (UserEditAtom) pdr; - } - if (interestingRecords != null && saveme != null) { - interestingRecords.put(saveme, pdr); - } - - // Dummy write out, so the position winds on properly - record.writeOut(cos); - } - cos.close(); - - if (usr == null || ptr == null) { - throw new HSLFException("UserEditAtom or PersistPtr can't be determined."); - } - - Map persistIds = new HashMap(); - for (Map.Entry entry : ptr.getSlideLocationsLookup().entrySet()) { - persistIds.put(oldToNewPositions.get(entry.getValue()), entry.getKey()); - } - - HSLFSlideShowEncrypted encData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom()); - - for (Record record : _records) { - assert (record instanceof PositionDependentRecord); - // We've already figured out their new location, and - // told them that - // Tell them of the positions of the other records though - PositionDependentRecord pdr = (PositionDependentRecord) record; - Integer persistId = persistIds.get(pdr.getLastOnDiskOffset()); - if (persistId == null) persistId = 0; - - // For now, we're only handling PositionDependentRecord's that - // happen at the top level. - // In future, we'll need the handle them everywhere, but that's - // a bit trickier - pdr.updateOtherRecordReferences(oldToNewPositions); - - // Whatever happens, write out that record tree - if (os != null) { - record.writeOut(encData.encryptRecord(os, persistId, record)); - } - } - - encData.close(); - - // Update and write out the Current User atom - int oldLastUserEditAtomPos = (int) currentUser.getCurrentEditOffset(); - Integer newLastUserEditAtomPos = oldToNewPositions.get(oldLastUserEditAtomPos); - if (newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) { - throw new HSLFException("Couldn't find the new location of the last UserEditAtom that used to be at " + oldLastUserEditAtomPos); - } - currentUser.setCurrentEditOffset(usr.getLastOnDiskOffset()); - } - - /** - * Writes out the slideshow to the currently open file. - *

        - *

        This will fail (with an {@link IllegalStateException} if the - * slideshow was opened read-only, opened from an {@link InputStream} - * instead of a File, or if this is not the root document. For those cases, - * you must use {@link #write(OutputStream)} or {@link #write(File)} to - * write to a brand new document. - * - * @throws IOException thrown on errors writing to the file - * @throws IllegalStateException if this isn't from a writable File - * @since POI 3.15 beta 3 - */ - @Override - public void write() throws IOException { - validateInPlaceWritePossible(); - - // Write the PowerPoint streams to the current FileSystem - // No need to do anything to other streams, already there! - write(directory.getFileSystem(), false); - - // Sync with the File on disk - directory.getFileSystem().writeFilesystem(); - } - - /** - * Writes out the slideshow file the is represented by an instance - * of this class. - *

        This will write out only the common OLE2 streams. If you require all - * streams to be written out, use {@link #write(File, boolean)} - * with preserveNodes set to true. - * - * @param newFile The File to write to. - * @throws IOException If there is an unexpected IOException from writing to the File - */ - @Override - public void write(File newFile) throws IOException { - // Write out, but only the common streams - write(newFile, false); - } - - /** - * Writes out the slideshow file the is represented by an instance - * of this class. - * If you require all streams to be written out (eg Marcos, embeded - * documents), then set preserveNodes set to true - * - * @param newFile The File to write to. - * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones? - * @throws IOException If there is an unexpected IOException from writing to the File - */ - public void write(File newFile, boolean preserveNodes) throws IOException { - // Get a new FileSystem to write into - POIFSFileSystem outFS = POIFSFileSystem.create(newFile); - - try { - // Write into the new FileSystem - write(outFS, preserveNodes); - - // Send the POIFSFileSystem object out to the underlying stream - outFS.writeFilesystem(); - } finally { - outFS.close(); - } - } - - /** - * Writes out the slideshow file the is represented by an instance - * of this class. - *

        This will write out only the common OLE2 streams. If you require all - * streams to be written out, use {@link #write(OutputStream, boolean)} - * with preserveNodes set to true. - * - * @param out The OutputStream to write to. - * @throws IOException If there is an unexpected IOException from - * the passed in OutputStream - */ - @Override - public void write(OutputStream out) throws IOException { - // Write out, but only the common streams - write(out, false); - } - - /** - * Writes out the slideshow file the is represented by an instance - * of this class. - * If you require all streams to be written out (eg Marcos, embeded - * documents), then set preserveNodes set to true - * - * @param out The OutputStream to write to. - * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones? - * @throws IOException If there is an unexpected IOException from - * the passed in OutputStream - */ - public void write(OutputStream out, boolean preserveNodes) throws IOException { - // Get a new FileSystem to write into - POIFSFileSystem outFS = new POIFSFileSystem(); - - try { - // Write into the new FileSystem - write(outFS, preserveNodes); - - // Send the POIFSFileSystem object out to the underlying stream - outFS.writeFilesystem(out); - } finally { - outFS.close(); - } - } - - private void write(NPOIFSFileSystem outFS, boolean copyAllOtherNodes) throws IOException { - // read properties and pictures, with old encryption settings where appropriate - if (_pictures == null) { - readPictures(); - } - getDocumentSummaryInformation(); - - // set new encryption settings - HSLFSlideShowEncrypted encryptedSS = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom()); - _records = encryptedSS.updateEncryptionRecord(_records); - - // The list of entries we've written out - List writtenEntries = new ArrayList(1); - - // Write out the Property Streams - writeProperties(outFS, writtenEntries); - - BufAccessBAOS baos = new BufAccessBAOS(); - - // For position dependent records, hold where they were and now are - // As we go along, update, and hand over, to any Position Dependent - // records we happen across - updateAndWriteDependantRecords(baos, null); - - // Update our cached copy of the bytes that make up the PPT stream - _docstream = new byte[baos.size()]; - System.arraycopy(baos.getBuf(), 0, _docstream, 0, baos.size()); - baos.close(); - - // Write the PPT stream into the POIFS layer - ByteArrayInputStream bais = new ByteArrayInputStream(_docstream); - outFS.createOrUpdateDocument(bais, "PowerPoint Document"); - writtenEntries.add("PowerPoint Document"); - - currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null); - currentUser.writeToFS(outFS); - writtenEntries.add("Current User"); - - - if (_pictures.size() > 0) { - BufAccessBAOS pict = new BufAccessBAOS(); - for (HSLFPictureData p : _pictures) { - int offset = pict.size(); - p.write(pict); - encryptedSS.encryptPicture(pict.getBuf(), offset); - } - outFS.createOrUpdateDocument( - new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures" - ); - writtenEntries.add("Pictures"); - pict.close(); - } - - // If requested, copy over any other streams we spot, eg Macros - if (copyAllOtherNodes) { - EntryUtils.copyNodes(directory.getFileSystem(), outFS, writtenEntries); - } - } - - /** - * For a given named property entry, either return it or null if - * if it wasn't found - * - * @param setName The property to read - * @return The value of the given property or null if it wasn't found. - */ - protected PropertySet getPropertySet(String setName) { - DocumentEncryptionAtom dea = getDocumentEncryptionAtom(); - return (dea == null) - ? super.getPropertySet(setName) - : super.getPropertySet(setName, dea.getEncryptionInfo()); - } - - /** - * Writes out the standard Documment Information Properties (HPSF) - * - * @param outFS the POIFSFileSystem to write the properties into - * @param writtenEntries a list of POIFS entries to add the property names too - * @throws IOException if an error when writing to the - * {@link POIFSFileSystem} occurs - */ - protected void writeProperties(NPOIFSFileSystem outFS, List writtenEntries) throws IOException { - super.writeProperties(outFS, writtenEntries); - DocumentEncryptionAtom dea = getDocumentEncryptionAtom(); - if (dea != null) { - CryptoAPIEncryptor enc = (CryptoAPIEncryptor) dea.getEncryptionInfo().getEncryptor(); - try { - enc.getSummaryEntries(outFS.getRoot()); // ignore OutputStream - } catch (IOException e) { - throw e; - } catch (GeneralSecurityException e) { - throw new IOException(e); - } - } - } - - /* ******************* adding methods follow ********************* */ - - /** - * Adds a new root level record, at the end, but before the last - * PersistPtrIncrementalBlock. - */ - public synchronized int appendRootLevelRecord(Record newRecord) { - int addedAt = -1; - Record[] r = new Record[_records.length + 1]; - boolean added = false; - for (int i = (_records.length - 1); i >= 0; i--) { - if (added) { - // Just copy over - r[i] = _records[i]; - } else { - r[(i + 1)] = _records[i]; - if (_records[i] instanceof PersistPtrHolder) { - r[i] = newRecord; - added = true; - addedAt = i; - } - } - } - _records = r; - return addedAt; - } - - /** - * Add a new picture to this presentation. - * - * @return offset of this picture in the Pictures stream - */ - public int addPicture(HSLFPictureData img) { - // Process any existing pictures if we haven't yet - if (_pictures == null) { - try { - readPictures(); - } catch (IOException e) { - throw new CorruptPowerPointFileException(e.getMessage()); - } - } - - // Add the new picture in - int offset = 0; - if (_pictures.size() > 0) { - HSLFPictureData prev = _pictures.get(_pictures.size() - 1); - offset = prev.getOffset() + prev.getRawData().length + 8; - } - img.setOffset(offset); - img.setIndex(_pictures.size() + 1); - _pictures.add(img); - return offset; - } - - /* ******************* fetching methods follow ********************* */ - - - /** - * Returns an array of all the records found in the slideshow - */ - public Record[] getRecords() { - return _records; - } - - /** - * Returns an array of the bytes of the file. Only correct after a - * call to open or write - at all other times might be wrong! - */ - public byte[] getUnderlyingBytes() { - return _docstream; - } - - /** - * Fetch the Current User Atom of the document - */ - public CurrentUserAtom getCurrentUserAtom() { - return currentUser; - } - - /** - * Return list of pictures contained in this presentation - * - * @return list with the read pictures or an empty list if the - * presentation doesn't contain pictures. - */ - public List getPictureData() { - if (_pictures == null) { - try { - readPictures(); - } catch (IOException e) { - throw new CorruptPowerPointFileException(e.getMessage()); - } - } - - return Collections.unmodifiableList(_pictures); - } - - /** - * Gets embedded object data from the slide show. - * - * @return the embedded objects. - */ - public HSLFObjectData[] getEmbeddedObjects() { - if (_objects == null) { - List objects = new ArrayList(); - for (Record r : _records) { - if (r instanceof ExOleObjStg) { - objects.add(new HSLFObjectData((ExOleObjStg) r)); - } - } - _objects = objects.toArray(new HSLFObjectData[objects.size()]); - } - return _objects; - } - - @Override - public void close() throws IOException { - NPOIFSFileSystem fs = directory.getFileSystem(); - if (fs != null) { - fs.close(); - } - } - - - private static class BufAccessBAOS extends ByteArrayOutputStream { - public byte[] getBuf() { - return buf; - } - } - - private static class CountingOS extends OutputStream { - int count = 0; - - public void write(int b) throws IOException { - count++; - } - - public void write(byte[] b) throws IOException { - count += b.length; - } - - public void write(byte[] b, int off, int len) throws IOException { - count += len; - } - - public int size() { - return count; - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSoundData.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSoundData.java deleted file mode 100644 index 7750b25f1..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSoundData.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.hslf.record.*; - -import java.util.ArrayList; - -/** - * A class that represents sound data embedded in a slide show. - * - * @author Yegor Kozlov - */ -public final class HSLFSoundData { - /** - * The record that contains the object data. - */ - private Sound _container; - - /** - * Creates the object data wrapping the record that contains the sound data. - * - * @param container the record that contains the sound data. - */ - public HSLFSoundData(Sound container) { - this._container = container; - } - - /** - * Name of the sound (e.g. "crash") - * - * @return name of the sound - */ - public String getSoundName(){ - return _container.getSoundName(); - } - - /** - * Type of the sound (e.g. ".wav") - * - * @return type of the sound - */ - public String getSoundType(){ - return _container.getSoundType(); - } - - /** - * Gets an input stream which returns the binary of the sound data. - * - * @return the input stream which will contain the binary of the sound data. - */ - public byte[] getData() { - return _container.getSoundData(); - } - - /** - * Find all sound records in the supplied Document records - * - * @param document the document to find in - * @return the array with the sound data - */ - public static HSLFSoundData[] find(Document document){ - ArrayList lst = new ArrayList(); - Record[] ch = document.getChildRecords(); - for (int i = 0; i < ch.length; i++) { - if(ch[i].getRecordType() == RecordTypes.SoundCollection.typeID){ - RecordContainer col = (RecordContainer)ch[i]; - Record[] sr = col.getChildRecords(); - for (int j = 0; j < sr.length; j++) { - if(sr[j] instanceof Sound){ - lst.add(new HSLFSoundData((Sound)sr[j])); - } - } - } - - } - return lst.toArray(new HSLFSoundData[lst.size()]); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java deleted file mode 100644 index f007dd987..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java +++ /dev/null @@ -1,462 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherArrayProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.TableShape; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.Units; - -/** - * Represents a table in a PowerPoint presentation - * - * @author Yegor Kozlov - */ -public final class HSLFTable extends HSLFGroupShape -implements HSLFShapeContainer, TableShape { - - protected static final int BORDERS_ALL = 5; - protected static final int BORDERS_OUTSIDE = 6; - protected static final int BORDERS_INSIDE = 7; - protected static final int BORDERS_NONE = 8; - - - protected HSLFTableCell[][] cells; - private int columnCount = -1; - - /** - * Create a new Table of the given number of rows and columns - * - * @param numRows the number of rows - * @param numCols the number of columns - */ - protected HSLFTable(int numRows, int numCols) { - this(numRows, numCols, null); - } - - /** - * Create a new Table of the given number of rows and columns - * - * @param numRows the number of rows - * @param numCols the number of columns - * @param parent the parent shape, or null if table is added to sheet - */ - protected HSLFTable(int numRows, int numCols, ShapeContainer parent) { - super(parent); - - if(numRows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1"); - if(numCols < 1) throw new IllegalArgumentException("The number of columns must be greater than 1"); - - double x=0, y=0, tblWidth=0, tblHeight=0; - cells = new HSLFTableCell[numRows][numCols]; - for (int i = 0; i < cells.length; i++) { - x = 0; - for (int j = 0; j < cells[i].length; j++) { - cells[i][j] = new HSLFTableCell(this); - Rectangle2D anchor = new Rectangle2D.Double(x, y, HSLFTableCell.DEFAULT_WIDTH, HSLFTableCell.DEFAULT_HEIGHT); - cells[i][j].setAnchor(anchor); - x += HSLFTableCell.DEFAULT_WIDTH; - } - y += HSLFTableCell.DEFAULT_HEIGHT; - } - tblWidth = x; - tblHeight = y; - setExteriorAnchor(new Rectangle2D.Double(0, 0, tblWidth, tblHeight)); - - EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0); - AbstractEscherOptRecord opt = new EscherOptRecord(); - opt.setRecordId(RecordTypes.EscherUserDefined.typeID); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__TABLEPROPERTIES, 1)); - EscherArrayProperty p = new EscherArrayProperty((short)(0x4000 | EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES), false, null); - p.setSizeOfElements(0x0004); - p.setNumberOfElementsInArray(numRows); - p.setNumberOfElementsInMemory(numRows); - opt.addEscherProperty(p); - spCont.addChildBefore(opt, RecordTypes.EscherClientAnchor.typeID); - } - - /** - * Create a Table object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFTable(EscherContainerRecord escherRecord, ShapeContainer parent) { - super(escherRecord, parent); - } - - @Override - public HSLFTableCell getCell(int row, int col) { - if (row < 0 || cells.length <= row) { - return null; - } - HSLFTableCell[] r = cells[row]; - if (r == null || col < 0 || r.length <= col) { - // empty row - return null; - } - // cell can be potentially empty ... - return r[col]; - } - - @Override - public int getNumberOfColumns() { - if (columnCount == -1) { - // check all rows in case of merged rows - for (HSLFTableCell[] hc : cells) { - if (hc != null) { - columnCount = Math.max(columnCount, hc.length); - } - } - } - return columnCount; - } - - @Override - public int getNumberOfRows() { - return cells.length; - } - - protected void afterInsert(HSLFSheet sh){ - super.afterInsert(sh); - - Set lineSet = new HashSet(); - for (HSLFTableCell row[] : cells) { - for (HSLFTableCell c : row) { - addShape(c); - for (HSLFLine bt : new HSLFLine[]{ c.borderTop, c.borderRight, c.borderBottom, c.borderLeft }) { - if (bt != null) { - lineSet.add(bt); - } - } - } - } - - for (HSLFLine l : lineSet) { - addShape(l); - } - - updateRowHeightsProperty(); - } - - private void cellListToArray() { - List htc = new ArrayList(); - for (HSLFShape h : getShapes()) { - if (h instanceof HSLFTableCell) { - htc.add((HSLFTableCell)h); - } - } - - if (htc.isEmpty()) { - throw new IllegalStateException("HSLFTable without HSLFTableCells"); - } - - SortedSet colSet = new TreeSet(); - SortedSet rowSet = new TreeSet(); - - // #1 pass - determine cols and rows - for (HSLFTableCell sh : htc) { - Rectangle2D anchor = sh.getAnchor(); - colSet.add(anchor.getX()); - rowSet.add(anchor.getY()); - } - cells = new HSLFTableCell[rowSet.size()][colSet.size()]; - - List colLst = new ArrayList(colSet); - List rowLst = new ArrayList(rowSet); - - // #2 pass - assign shape to table cells - for (HSLFTableCell sh : htc) { - Rectangle2D anchor = sh.getAnchor(); - int row = rowLst.indexOf(anchor.getY()); - int col = colLst.indexOf(anchor.getX()); - assert(row != -1 && col != -1); - cells[row][col] = sh; - - // determine gridSpan / rowSpan - int gridSpan = calcSpan(colLst, anchor.getWidth(), col); - int rowSpan = calcSpan(rowLst, anchor.getHeight(), row); - - sh.setGridSpan(gridSpan); - sh.setRowSpan(rowSpan); - } - } - - private int calcSpan(List spaces, double totalSpace, int idx) { - if (idx == spaces.size()-1) { - return 1; - } - int span = 0; - double remainingSpace = totalSpace; - while (idx+1 < spaces.size() && remainingSpace > 0) { - remainingSpace -= spaces.get(idx+1)-spaces.get(idx); - span++; - idx++; - } - return span; - } - - static class LineRect { - final HSLFLine l; - final double lx1, lx2, ly1, ly2; - LineRect(HSLFLine l) { - this.l = l; - Rectangle2D r = l.getAnchor(); - lx1 = r.getMinX(); - lx2 = r.getMaxX(); - ly1 = r.getMinY(); - ly2 = r.getMaxY(); - } - int leftFit(double x1, double x2, double y1, double y2) { - return (int)(Math.abs(x1-lx1)+Math.abs(y1-ly1)+Math.abs(x1-lx2)+Math.abs(y2-ly2)); - } - int topFit(double x1, double x2, double y1, double y2) { - return (int)(Math.abs(x1-lx1)+Math.abs(y1-ly1)+Math.abs(x2-lx2)+Math.abs(y1-ly2)); - } - int rightFit(double x1, double x2, double y1, double y2) { - return (int)(Math.abs(x2-lx1)+Math.abs(y1-ly1)+Math.abs(x2-lx2)+Math.abs(y2-ly2)); - } - int bottomFit(double x1, double x2, double y1, double y2) { - return (int)(Math.abs(x1-lx1)+Math.abs(y2-ly1)+Math.abs(x2-lx2)+Math.abs(y2-ly2)); - } - } - - private void fitLinesToCells() { - List lines = new ArrayList(); - for (HSLFShape h : getShapes()) { - if (h instanceof HSLFLine) { - lines.add(new LineRect((HSLFLine)h)); - } - } - - final int threshold = 5; - - // TODO: this only works for non-rotated tables - for (HSLFTableCell[] tca : cells) { - for (HSLFTableCell tc : tca) { - if (tc == null) { - continue; - } - final Rectangle2D cellAnchor = tc.getAnchor(); - - /** - * x1/y1 --------+ - * | | - * +---------x2/y2 - */ - final double x1 = cellAnchor.getMinX(); - final double x2 = cellAnchor.getMaxX(); - final double y1 = cellAnchor.getMinY(); - final double y2 = cellAnchor.getMaxY(); - - LineRect lline = null, tline = null, rline = null, bline = null; - int lfit = Integer.MAX_VALUE, tfit = Integer.MAX_VALUE, rfit = Integer.MAX_VALUE, bfit = Integer.MAX_VALUE; - - for (LineRect lr : lines) { - // calculate border fit - int lfitx = lr.leftFit(x1, x2, y1, y2); - if (lfitx < lfit) { - lfit = lfitx; - lline = lr; - } - - int tfitx = lr.topFit(x1, x2, y1, y2); - if (tfitx < tfit) { - tfit = tfitx; - tline = lr; - } - - int rfitx = lr.rightFit(x1, x2, y1, y2); - if (rfitx < rfit) { - rfit = rfitx; - rline = lr; - } - - int bfitx = lr.bottomFit(x1, x2, y1, y2); - if (bfitx < bfit) { - bfit = bfitx; - bline = lr; - } - } - - if (lfit < threshold) { - tc.borderLeft = lline.l; - } - if (tfit < threshold) { - tc.borderTop = tline.l; - } - if (rfit < threshold) { - tc.borderRight = rline.l; - } - if (bfit < threshold) { - tc.borderBottom = bline.l; - } - } - } - } - - protected void initTable(){ - cellListToArray(); - fitLinesToCells(); - } - - /** - * Assign the SlideShow this shape belongs to - * - * @param sheet owner of this shape - */ - public void setSheet(HSLFSheet sheet){ - super.setSheet(sheet); - if (cells == null) { - initTable(); - } else { - for (HSLFTableCell cols[] : cells) { - for (HSLFTableCell col : cols) { - col.setSheet(sheet); - } - } - } - } - - @Override - public double getRowHeight(int row) { - if (row < 0 || row >= cells.length) { - throw new IllegalArgumentException("Row index '"+row+"' is not within range [0-"+(cells.length-1)+"]"); - } - - return cells[row][0].getAnchor().getHeight(); - } - - @Override - public void setRowHeight(int row, double height) { - if (row < 0 || row >= cells.length) { - throw new IllegalArgumentException("Row index '"+row+"' is not within range [0-"+(cells.length-1)+"]"); - } - - int pxHeight = Units.pointsToPixel(height); - double currentHeight = cells[row][0].getAnchor().getHeight(); - double dy = pxHeight - currentHeight; - - for (int i = row; i < cells.length; i++) { - for (int j = 0; j < cells[i].length; j++) { - Rectangle2D anchor = cells[i][j].getAnchor(); - if(i == row) { - anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), pxHeight); - } else { - anchor.setRect(anchor.getX(), anchor.getY()+dy, anchor.getWidth(), pxHeight); - } - cells[i][j].setAnchor(anchor); - } - } - Rectangle2D tblanchor = getAnchor(); - tblanchor.setRect(tblanchor.getX(), tblanchor.getY(), tblanchor.getWidth(), tblanchor.getHeight() + dy); - setExteriorAnchor(tblanchor); - - } - - @Override - public double getColumnWidth(int col) { - if (col < 0 || col >= cells[0].length) { - throw new IllegalArgumentException("Column index '"+col+"' is not within range [0-"+(cells[0].length-1)+"]"); - } - - // TODO: check for merged cols - double width = cells[0][col].getAnchor().getWidth(); - return width; - } - - @Override - public void setColumnWidth(int col, final double width){ - if (col < 0 || col >= cells[0].length) { - throw new IllegalArgumentException("Column index '"+col+"' is not within range [0-"+(cells[0].length-1)+"]"); - } - double currentWidth = cells[0][col].getAnchor().getWidth(); - double dx = width - currentWidth; - for (HSLFTableCell cols[] : cells) { - Rectangle2D anchor = cols[col].getAnchor(); - anchor.setRect(anchor.getX(), anchor.getY(), width, anchor.getHeight()); - cols[col].setAnchor(anchor); - - if (col < cols.length - 1) { - for (int j = col+1; j < cols.length; j++) { - anchor = cols[j].getAnchor(); - anchor.setRect(anchor.getX()+dx, anchor.getY(), anchor.getWidth(), anchor.getHeight()); - cols[j].setAnchor(anchor); - } - } - } - Rectangle2D tblanchor = getAnchor(); - tblanchor.setRect(tblanchor.getX(), tblanchor.getY(), tblanchor.getWidth() + dx, tblanchor.getHeight()); - setExteriorAnchor(tblanchor); - } - - protected HSLFTableCell getRelativeCell(HSLFTableCell origin, int row, int col) { - int thisRow = 0, thisCol = 0; - boolean found = false; - outer: for (HSLFTableCell[] tca : cells) { - thisCol = 0; - for (HSLFTableCell tc : tca) { - if (tc == origin) { - found = true; - break outer; - } - thisCol++; - } - thisRow++; - } - - int otherRow = thisRow + row; - int otherCol = thisCol + col; - return (found - && 0 <= otherRow && otherRow < cells.length - && 0 <= otherCol && otherCol < cells[otherRow].length) - ? cells[otherRow][otherCol] : null; - } - - @Override - protected void moveAndScale(Rectangle2D anchorDest){ - super.moveAndScale(anchorDest); - updateRowHeightsProperty(); - } - - private void updateRowHeightsProperty() { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherArrayProperty p = opt.lookup(EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES); - byte[] val = new byte[4]; - for (int rowIdx = 0; rowIdx < cells.length; rowIdx++) { - int rowHeight = Units.pointsToMaster(cells[rowIdx][0].getAnchor().getHeight()); - LittleEndian.putInt(val, 0, rowHeight); - p.setElement(rowIdx, val); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java deleted file mode 100644 index a8e3294d1..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java +++ /dev/null @@ -1,447 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.awt.Color; -import java.awt.geom.Rectangle2D; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.StrokeStyle; -import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; -import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; -import org.apache.poi.sl.usermodel.TableCell; - -/** - * Represents a cell in a ppt table - */ -public final class HSLFTableCell extends HSLFTextBox implements TableCell { - protected static final int DEFAULT_WIDTH = 100; - protected static final int DEFAULT_HEIGHT = 40; - - /* package */ HSLFLine borderLeft; - /* package */ HSLFLine borderRight; - /* package */ HSLFLine borderTop; - /* package */ HSLFLine borderBottom; - - /** - * The number of columns to be spanned/merged - */ - private int gridSpan = 1; - - /** - * The number of columns to be spanned/merged - */ - private int rowSpan = 1; - - /** - * Create a TableCell object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFTableCell(EscherContainerRecord escherRecord, HSLFTable parent){ - super(escherRecord, parent); - } - - /** - * Create a new TableCell. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public HSLFTableCell(HSLFTable parent){ - super(parent); - - setShapeType(ShapeType.RECT); - //_txtrun.setRunType(TextHeaderAtom.HALF_BODY_TYPE); - //_txtrun.getRichTextRuns()[0].setFlag(false, 0, false); - } - - protected EscherContainerRecord createSpContainer(boolean isChild){ - _escherContainer = super.createSpContainer(isChild); - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0); - setEscherProperty(opt, EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20000); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150001); - setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000); - setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000); - - return _escherContainer; - } - - private void anchorBorder(BorderEdge edge, final HSLFLine line) { - if (line == null) { - return; - } - Rectangle2D cellAnchor = getAnchor(); - double x,y,w,h; - switch(edge){ - case top: - x = cellAnchor.getX(); - y = cellAnchor.getY(); - w = cellAnchor.getWidth(); - h = 0; - break; - case right: - x = cellAnchor.getX() + cellAnchor.getWidth(); - y = cellAnchor.getY(); - w = 0; - h = cellAnchor.getHeight(); - break; - case bottom: - x = cellAnchor.getX(); - y = cellAnchor.getY() + cellAnchor.getHeight(); - w = cellAnchor.getWidth(); - h = 0; - break; - case left: - x = cellAnchor.getX(); - y = cellAnchor.getY(); - w = 0; - h = cellAnchor.getHeight(); - break; - default: - throw new IllegalArgumentException(); - } - line.setAnchor(new Rectangle2D.Double(x,y,w,h)); - } - - public void setAnchor(Rectangle2D anchor){ - super.setAnchor(anchor); - - anchorBorder(BorderEdge.top, borderTop); - anchorBorder(BorderEdge.right, borderRight); - anchorBorder(BorderEdge.bottom, borderBottom); - anchorBorder(BorderEdge.left, borderLeft); - } - - @Override - public StrokeStyle getBorderStyle(final BorderEdge edge) { - final Double width = getBorderWidth(edge); - return (width == null) ? null : new StrokeStyle() { - public PaintStyle getPaint() { - return DrawPaint.createSolidPaint(getBorderColor(edge)); - } - - public LineCap getLineCap() { - return null; - } - - public LineDash getLineDash() { - return getBorderDash(edge); - } - - public LineCompound getLineCompound() { - return getBorderCompound(edge); - } - - public double getLineWidth() { - return width; - } - }; - } - - @Override - public void setBorderStyle(BorderEdge edge, StrokeStyle style) { - if (style == null) { - throw new IllegalArgumentException("StrokeStyle needs to be specified."); - } - - // setting the line cap is not implemented, as the border lines aren't connected - - LineCompound compound = style.getLineCompound(); - if (compound != null) { - setBorderCompound(edge, compound); - } - - LineDash dash = style.getLineDash(); - if (dash != null) { - setBorderDash(edge, dash); - } - - double width = style.getLineWidth(); - setBorderWidth(edge, width); - } - - - public Double getBorderWidth(BorderEdge edge) { - HSLFLine l; - switch (edge) { - case bottom: l = borderBottom; break; - case top: l = borderTop; break; - case right: l = borderRight; break; - case left: l = borderLeft; break; - default: throw new IllegalArgumentException(); - } - return (l == null) ? null : l.getLineWidth(); - } - - @Override - public void setBorderWidth(BorderEdge edge, double width) { - HSLFLine l = addLine(edge); - l.setLineWidth(width); - } - - public Color getBorderColor(BorderEdge edge) { - HSLFLine l; - switch (edge) { - case bottom: l = borderBottom; break; - case top: l = borderTop; break; - case right: l = borderRight; break; - case left: l = borderLeft; break; - default: throw new IllegalArgumentException(); - } - return (l == null) ? null : l.getLineColor(); - } - - @Override - public void setBorderColor(BorderEdge edge, Color color) { - if (edge == null || color == null) { - throw new IllegalArgumentException("BorderEdge and/or Color need to be specified."); - } - - HSLFLine l = addLine(edge); - l.setLineColor(color); - } - - public LineDash getBorderDash(BorderEdge edge) { - HSLFLine l; - switch (edge) { - case bottom: l = borderBottom; break; - case top: l = borderTop; break; - case right: l = borderRight; break; - case left: l = borderLeft; break; - default: throw new IllegalArgumentException(); - } - return (l == null) ? null : l.getLineDash(); - } - - @Override - public void setBorderDash(BorderEdge edge, LineDash dash) { - if (edge == null || dash == null) { - throw new IllegalArgumentException("BorderEdge and/or LineDash need to be specified."); - } - - HSLFLine l = addLine(edge); - l.setLineDash(dash); - } - - public LineCompound getBorderCompound(BorderEdge edge) { - HSLFLine l; - switch (edge) { - case bottom: l = borderBottom; break; - case top: l = borderTop; break; - case right: l = borderRight; break; - case left: l = borderLeft; break; - default: throw new IllegalArgumentException(); - } - return (l == null) ? null : l.getLineCompound(); - } - - @Override - public void setBorderCompound(BorderEdge edge, LineCompound compound) { - if (edge == null || compound == null) { - throw new IllegalArgumentException("BorderEdge and/or LineCompound need to be specified."); - } - - HSLFLine l = addLine(edge); - l.setLineCompound(compound); - } - - - protected HSLFLine addLine(BorderEdge edge) { - switch (edge) { - case bottom: { - if (borderBottom == null) { - borderBottom = createBorder(edge); - HSLFTableCell c = getSiblingCell(1,0); - if (c != null) { - assert(c.borderTop == null); - c.borderTop = borderBottom; - } - } - return borderBottom; - } - case top: { - if (borderTop == null) { - borderTop = createBorder(edge); - HSLFTableCell c = getSiblingCell(-1,0); - if (c != null) { - assert(c.borderBottom == null); - c.borderBottom = borderTop; - } - } - return borderTop; - } - case right: { - if (borderRight == null) { - borderRight = createBorder(edge); - HSLFTableCell c = getSiblingCell(0,1); - if (c != null) { - assert(c.borderLeft == null); - c.borderLeft = borderRight; - } - } - return borderRight; - } - case left: { - if (borderLeft == null) { - borderLeft = createBorder(edge); - HSLFTableCell c = getSiblingCell(0,-1); - if (c != null) { - assert(c.borderRight == null); - c.borderRight = borderLeft; - } - } - return borderLeft; - } - default: - throw new IllegalArgumentException(); - } - } - - @Override - public void removeBorder(BorderEdge edge) { - switch (edge) { - case bottom: { - if (borderBottom == null) break; - getParent().removeShape(borderBottom); - borderBottom = null; - HSLFTableCell c = getSiblingCell(1,0); - if (c != null) { - c.borderTop = null; - } - break; - } - case top: { - if (borderTop == null) break; - getParent().removeShape(borderTop); - borderTop = null; - HSLFTableCell c = getSiblingCell(-1,0); - if (c != null) { - c.borderBottom = null; - } - break; - } - case right: { - if (borderRight == null) break; - getParent().removeShape(borderRight); - borderRight = null; - HSLFTableCell c = getSiblingCell(0,1); - if (c != null) { - c.borderLeft = null; - } - break; - } - case left: { - if (borderLeft == null) break; - getParent().removeShape(borderLeft); - borderLeft = null; - HSLFTableCell c = getSiblingCell(0,-1); - if (c != null) { - c.borderRight = null; - } - break; - } - default: - throw new IllegalArgumentException(); - } - } - - protected HSLFTableCell getSiblingCell(int row, int col) { - return getParent().getRelativeCell(this, row, col); - } - - /** - * Create a border to format this table - * - * @return the created border - */ - private HSLFLine createBorder(BorderEdge edge) { - HSLFTable table = getParent(); - HSLFLine line = new HSLFLine(table); - table.addShape(line); - - AbstractEscherOptRecord opt = getEscherOptRecord(); - setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1); - setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1); - setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000); - setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000); - - anchorBorder(edge, line); - - return line; - } - - protected void applyLineProperties(BorderEdge edge, HSLFLine other) { - HSLFLine line = addLine(edge); - line.setLineWidth(other.getLineWidth()); - line.setLineColor(other.getLineColor()); - // line.setLineCompound(other.getLineCompound()); - // line.setLineDashing(other.getLineDashing()); - } - - @Override - public HSLFTable getParent() { - return (HSLFTable)super.getParent(); - } - - /** - * Set the gridSpan (aka col-span) - * - * @param gridSpan the number of columns to be spanned/merged - * - * @since POI 3.15-beta2 - */ - protected void setGridSpan(int gridSpan) { - this.gridSpan = gridSpan; - } - - /** - * Set the rowSpan - * - * @param rowSpan the number of rows to be spanned/merged - * - * @since POI 3.15-beta2 - */ - protected void setRowSpan(int rowSpan) { - this.rowSpan = rowSpan; - } - - @Override - public int getGridSpan() { - return gridSpan; - } - - @Override - public int getRowSpan() { - return rowSpan; - } - - @Override - public boolean isMerged() { - // if a hslf cell is merged, it won't appear in the cell matrix, i.e. it doesn't exist - // therefore this is always false - return false; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java deleted file mode 100644 index 3872ecf5b..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.TextBox; -import org.apache.poi.sl.usermodel.VerticalAlignment; - -/** - * Represents a TextFrame shape in PowerPoint. - *

        - * Contains the text in a text frame as well as the properties and methods - * that control alignment and anchoring of the text. - *

        - * - * @author Yegor Kozlov - */ -public class HSLFTextBox extends HSLFTextShape implements TextBox { - - /** - * Create a TextBox object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFTextBox(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - - } - - /** - * Create a new TextBox. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public HSLFTextBox(ShapeContainer parent){ - super(parent); - } - - /** - * Create a new TextBox. This constructor is used when a new shape is created. - * - */ - public HSLFTextBox(){ - this(null); - } - - /** - * Create a new TextBox and initialize its internal structures - * - * @return the created EscherContainerRecord which holds shape data - */ - protected EscherContainerRecord createSpContainer(boolean isChild){ - _escherContainer = super.createSpContainer(isChild); - - setShapeType(ShapeType.TEXT_BOX); - - //set default properties for a TextBox - setEscherProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004); - setEscherProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000); - setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100000); - setEscherProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001); - setEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000); - setEscherProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); - - // init paragraphs - getTextParagraphs(); - - return _escherContainer; - } - - protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){ - setVerticalAlignment(VerticalAlignment.TOP); - setEscherProperty(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20002); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java deleted file mode 100644 index 322cb10d2..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java +++ /dev/null @@ -1,1603 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import static org.apache.poi.hslf.record.RecordTypes.OutlineTextRefAtom; - -import java.awt.Color; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.model.PPFont; -import org.apache.poi.hslf.model.textproperties.BitMaskTextProp; -import org.apache.poi.hslf.model.textproperties.FontAlignmentProp; -import org.apache.poi.hslf.model.textproperties.IndentProp; -import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp; -import org.apache.poi.hslf.model.textproperties.TextAlignmentProp; -import org.apache.poi.hslf.model.textproperties.TextPFException9; -import org.apache.poi.hslf.model.textproperties.TextProp; -import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; -import org.apache.poi.hslf.record.ColorSchemeAtom; -import org.apache.poi.hslf.record.EscherTextboxWrapper; -import org.apache.poi.hslf.record.FontCollection; -import org.apache.poi.hslf.record.InteractiveInfo; -import org.apache.poi.hslf.record.MasterTextPropAtom; -import org.apache.poi.hslf.record.OEPlaceholderAtom; -import org.apache.poi.hslf.record.OutlineTextRefAtom; -import org.apache.poi.hslf.record.PPDrawing; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordContainer; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; -import org.apache.poi.hslf.record.SlideListWithText; -import org.apache.poi.hslf.record.SlidePersistAtom; -import org.apache.poi.hslf.record.StyleTextProp9Atom; -import org.apache.poi.hslf.record.StyleTextPropAtom; -import org.apache.poi.hslf.record.TextBytesAtom; -import org.apache.poi.hslf.record.TextCharsAtom; -import org.apache.poi.hslf.record.TextHeaderAtom; -import org.apache.poi.hslf.record.TextRulerAtom; -import org.apache.poi.hslf.record.TextSpecInfoAtom; -import org.apache.poi.hslf.record.TxInteractiveInfoAtom; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.AutoNumberingScheme; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.StringUtil; -import org.apache.poi.util.Units; - -/** - * This class represents a run of text in a powerpoint document. That - * run could be text on a sheet, or text in a note. - * It is only a very basic class for now - * - * @author Nick Burch - */ - -public final class HSLFTextParagraph implements TextParagraph { - protected static final POILogger logger = POILogFactory.getLogger(HSLFTextParagraph.class); - - /** - * How to align the text - */ - /* package */static final int AlignLeft = 0; - /* package */static final int AlignCenter = 1; - /* package */static final int AlignRight = 2; - /* package */static final int AlignJustify = 3; - - // Note: These fields are protected to help with unit testing - // Other classes shouldn't really go playing with them! - private final TextHeaderAtom _headerAtom; - private TextBytesAtom _byteAtom; - private TextCharsAtom _charAtom; - private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph); - - protected TextRulerAtom _ruler; - protected final List _runs = new ArrayList(); - protected HSLFTextShape _parentShape; - private HSLFSheet _sheet; - private int shapeId; - - private StyleTextProp9Atom styleTextProp9Atom; - - private boolean _dirty = false; - - private final List parentList; - - /** - * Constructs a Text Run from a Unicode text block. - * Either a {@link TextCharsAtom} or a {@link TextBytesAtom} needs to be provided. - * - * @param tha the TextHeaderAtom that defines what's what - * @param tba the TextBytesAtom containing the text or null if {@link TextCharsAtom} is provided - * @param tca the TextCharsAtom containing the text or null if {@link TextBytesAtom} is provided - * @param parentList the list which contains this paragraph - */ - /* package */ HSLFTextParagraph( - TextHeaderAtom tha, - TextBytesAtom tba, - TextCharsAtom tca, - List parentList - ) { - if (tha == null) { - throw new IllegalArgumentException("TextHeaderAtom must be set."); - } - _headerAtom = tha; - _byteAtom = tba; - _charAtom = tca; - this.parentList = parentList; - } - - /* package */HSLFTextParagraph(HSLFTextParagraph other) { - _headerAtom = other._headerAtom; - _byteAtom = other._byteAtom; - _charAtom = other._charAtom; - _parentShape = other._parentShape; - _sheet = other._sheet; - _ruler = other._ruler; - shapeId = other.shapeId; - _paragraphStyle.copy(other._paragraphStyle); - parentList = other.parentList; - } - - public void addTextRun(HSLFTextRun run) { - _runs.add(run); - } - - @Override - public List getTextRuns() { - return _runs; - } - - public TextPropCollection getParagraphStyle() { - return _paragraphStyle; - } - - public void setParagraphStyle(TextPropCollection paragraphStyle) { - _paragraphStyle.copy(paragraphStyle); - } - - /** - * Setting a master style reference - * - * @param paragraphStyle the master style reference - * - * @since POI 3.14-Beta1 - */ - @Internal - /* package */ void setMasterStyleReference(TextPropCollection paragraphStyle) { - _paragraphStyle = paragraphStyle; - } - - /** - * Supply the Sheet we belong to, which might have an assigned SlideShow - * Also passes it on to our child RichTextRuns - */ - public static void supplySheet(List paragraphs, HSLFSheet sheet) { - if (paragraphs == null) { - return; - } - for (HSLFTextParagraph p : paragraphs) { - p.supplySheet(sheet); - } - - assert(sheet.getSlideShow() != null); - } - - /** - * Supply the Sheet we belong to, which might have an assigned SlideShow - * Also passes it on to our child RichTextRuns - */ - private void supplySheet(HSLFSheet sheet) { - this._sheet = sheet; - - if (_runs == null) return; - for (HSLFTextRun rt : _runs) { - rt.updateSheet(); - } - } - - public HSLFSheet getSheet() { - return this._sheet; - } - - /** - * @return Shape ID - */ - protected int getShapeId() { - return shapeId; - } - - /** - * @param id Shape ID - */ - protected void setShapeId(int id) { - shapeId = id; - } - - /** - * @return 0-based index of the text run in the SLWT container - */ - protected int getIndex() { - return (_headerAtom != null) ? _headerAtom.getIndex() : -1; - } - - /** - * Sets the index of the paragraph in the SLWT container - * - * @param index - */ - protected void setIndex(int index) { - if (_headerAtom != null) _headerAtom.setIndex(index); - } - - /** - * Returns the type of the text, from the TextHeaderAtom. - * Possible values can be seen from TextHeaderAtom - * @see org.apache.poi.hslf.record.TextHeaderAtom - */ - public int getRunType() { - return (_headerAtom != null) ? _headerAtom.getTextType() : -1; - } - - public void setRunType(int runType) { - if (_headerAtom != null) _headerAtom.setTextType(runType); - } - - /** - * Is this Text Run one from a {@link PPDrawing}, or is it - * one from the {@link SlideListWithText}? - */ - public boolean isDrawingBased() { - return (getIndex() == -1); - } - - public TextRulerAtom getTextRuler() { - return _ruler; - } - - public TextRulerAtom createTextRuler() { - _ruler = getTextRuler(); - if (_ruler == null) { - _ruler = TextRulerAtom.getParagraphInstance(); - Record childAfter = _byteAtom; - if (childAfter == null) childAfter = _charAtom; - if (childAfter == null) childAfter = _headerAtom; - _headerAtom.getParentRecord().addChildAfter(_ruler, childAfter); - } - return _ruler; - } - - /** - * Returns records that make up the list of text paragraphs - * (there can be misc InteractiveInfo, TxInteractiveInfo and other records) - * - * @return text run records - */ - public Record[] getRecords() { - Record r[] = _headerAtom.getParentRecord().getChildRecords(); - return getRecords(r, new int[] { 0 }, _headerAtom); - } - - private static Record[] getRecords(Record[] records, int[] startIdx, TextHeaderAtom headerAtom) { - if (records == null) { - throw new NullPointerException("records need to be set."); - } - - for (; startIdx[0] < records.length; startIdx[0]++) { - Record r = records[startIdx[0]]; - if (r instanceof TextHeaderAtom && (headerAtom == null || r == headerAtom)) break; - } - - if (startIdx[0] >= records.length) { - logger.log(POILogger.INFO, "header atom wasn't found - container might contain only an OutlineTextRefAtom"); - return new Record[0]; - } - - int length; - for (length = 1; startIdx[0] + length < records.length; length++) { - Record r = records[startIdx[0]+length]; - if (r instanceof TextHeaderAtom || r instanceof SlidePersistAtom) break; - } - - Record result[] = new Record[length]; - System.arraycopy(records, startIdx[0], result, 0, length); - startIdx[0] += length; - - return result; - } - - /** Numbered List info */ - public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) { - this.styleTextProp9Atom = styleTextProp9Atom; - } - - /** Numbered List info */ - public StyleTextProp9Atom getStyleTextProp9Atom() { - return this.styleTextProp9Atom; - } - - @Override - public Iterator iterator() { - return _runs.iterator(); - } - - @Override - public Double getLeftMargin() { - TextProp val = getPropVal(_paragraphStyle, "text.offset", this); - return (val == null) ? null : Units.masterToPoints(val.getValue()); - } - - @Override - public void setLeftMargin(Double leftMargin) { - Integer val = (leftMargin == null) ? null : Units.pointsToMaster(leftMargin); - setParagraphTextPropVal("text.offset", val); - } - - @Override - public Double getRightMargin() { - // TODO: find out, how to determine this value - return null; - } - - @Override - public void setRightMargin(Double rightMargin) { - // TODO: find out, how to set this value - } - - @Override - public Double getIndent() { - TextProp val = getPropVal(_paragraphStyle, "bullet.offset", this); - return (val == null) ? null : Units.masterToPoints(val.getValue()); - } - - @Override - public void setIndent(Double indent) { - Integer val = (indent == null) ? null : Units.pointsToMaster(indent); - setParagraphTextPropVal("bullet.offset", val); - } - - @Override - public String getDefaultFontFamily() { - String typeface = null; - if (!_runs.isEmpty()) { - typeface = _runs.get(0).getFontFamily(); - } - return (typeface != null) ? typeface : "Arial"; - } - - @Override - public Double getDefaultFontSize() { - Double d = null; - if (!_runs.isEmpty()) { - d = _runs.get(0).getFontSize(); - } - - return (d != null) ? d : 12d; - } - - @Override - public void setTextAlign(TextAlign align) { - Integer alignInt = null; - if (align != null) switch (align) { - default: - case LEFT: alignInt = TextAlignmentProp.LEFT;break; - case CENTER: alignInt = TextAlignmentProp.CENTER; break; - case RIGHT: alignInt = TextAlignmentProp.RIGHT; break; - case DIST: alignInt = TextAlignmentProp.DISTRIBUTED; break; - case JUSTIFY: alignInt = TextAlignmentProp.JUSTIFY; break; - case JUSTIFY_LOW: alignInt = TextAlignmentProp.JUSTIFYLOW; break; - case THAI_DIST: alignInt = TextAlignmentProp.THAIDISTRIBUTED; break; - } - setParagraphTextPropVal("alignment", alignInt); - } - - @Override - public TextAlign getTextAlign() { - TextProp tp = getPropVal(_paragraphStyle, "alignment", this); - if (tp == null) return null; - switch (tp.getValue()) { - default: - case TextAlignmentProp.LEFT: return TextAlign.LEFT; - case TextAlignmentProp.CENTER: return TextAlign.CENTER; - case TextAlignmentProp.RIGHT: return TextAlign.RIGHT; - case TextAlignmentProp.JUSTIFY: return TextAlign.JUSTIFY; - case TextAlignmentProp.JUSTIFYLOW: return TextAlign.JUSTIFY_LOW; - case TextAlignmentProp.DISTRIBUTED: return TextAlign.DIST; - case TextAlignmentProp.THAIDISTRIBUTED: return TextAlign.THAI_DIST; - } - } - - @Override - public FontAlign getFontAlign() { - TextProp tp = getPropVal(_paragraphStyle, FontAlignmentProp.NAME, this); - if (tp == null) return null; - - switch (tp.getValue()) { - case FontAlignmentProp.BASELINE: return FontAlign.BASELINE; - case FontAlignmentProp.TOP: return FontAlign.TOP; - case FontAlignmentProp.CENTER: return FontAlign.CENTER; - case FontAlignmentProp.BOTTOM: return FontAlign.BOTTOM; - default: return FontAlign.AUTO; - } - } - - public AutoNumberingScheme getAutoNumberingScheme() { - if (styleTextProp9Atom == null) return null; - TextPFException9[] ant = styleTextProp9Atom.getAutoNumberTypes(); - int level = getIndentLevel(); - if (ant == null || level == -1 || level >= ant.length) return null; - return ant[level].getAutoNumberScheme(); - } - - public Integer getAutoNumberingStartAt() { - if (styleTextProp9Atom == null) return null; - TextPFException9[] ant = styleTextProp9Atom.getAutoNumberTypes(); - int level = getIndentLevel(); - if (ant == null || level >= ant.length) return null; - Short startAt = ant[level].getAutoNumberStartNumber(); - assert(startAt != null); - return startAt.intValue(); - } - - - @Override - public BulletStyle getBulletStyle() { - if (!isBullet() && getAutoNumberingScheme() == null) return null; - - return new BulletStyle() { - @Override - public String getBulletCharacter() { - Character chr = HSLFTextParagraph.this.getBulletChar(); - return (chr == null || chr == 0) ? "" : "" + chr; - } - - @Override - public String getBulletFont() { - return HSLFTextParagraph.this.getBulletFont(); - } - - @Override - public Double getBulletFontSize() { - return HSLFTextParagraph.this.getBulletSize(); - } - - @Override - public void setBulletFontColor(Color color) { - setBulletFontColor(DrawPaint.createSolidPaint(color)); - } - - @Override - public void setBulletFontColor(PaintStyle color) { - if (!(color instanceof SolidPaint)) { - throw new IllegalArgumentException("HSLF only supports SolidPaint"); - } - SolidPaint sp = (SolidPaint)color; - Color col = DrawPaint.applyColorTransform(sp.getSolidColor()); - HSLFTextParagraph.this.setBulletColor(col); - } - - @Override - public PaintStyle getBulletFontColor() { - Color col = HSLFTextParagraph.this.getBulletColor(); - return DrawPaint.createSolidPaint(col); - } - - @Override - public AutoNumberingScheme getAutoNumberingScheme() { - return HSLFTextParagraph.this.getAutoNumberingScheme(); - } - - @Override - public Integer getAutoNumberingStartAt() { - return HSLFTextParagraph.this.getAutoNumberingStartAt(); - } - }; - } - - @Override - public void setBulletStyle(Object... styles) { - if (styles.length == 0) { - setBullet(false); - } else { - setBullet(true); - for (Object ostyle : styles) { - if (ostyle instanceof Number) { - setBulletSize(((Number)ostyle).doubleValue()); - } else if (ostyle instanceof Color) { - setBulletColor((Color)ostyle); - } else if (ostyle instanceof Character) { - setBulletChar((Character)ostyle); - } else if (ostyle instanceof String) { - setBulletFont((String)ostyle); - } else if (ostyle instanceof AutoNumberingScheme) { - throw new HSLFException("setting bullet auto-numberin scheme for HSLF not supported ... yet"); - } - } - } - } - - @Override - public HSLFTextShape getParentShape() { - return _parentShape; - } - - public void setParentShape(HSLFTextShape parentShape) { - _parentShape = parentShape; - } - - @Override - public int getIndentLevel() { - return _paragraphStyle == null ? 0 : _paragraphStyle.getIndentLevel(); - } - - @Override - public void setIndentLevel(int level) { - if( _paragraphStyle != null ) _paragraphStyle.setIndentLevel((short)level); - } - - /** - * Sets whether this rich text run has bullets - */ - public void setBullet(boolean flag) { - setFlag(ParagraphFlagsTextProp.BULLET_IDX, flag); - } - - /** - * Returns whether this rich text run has bullets - */ - public boolean isBullet() { - return getFlag(ParagraphFlagsTextProp.BULLET_IDX); - } - - /** - * Sets the bullet character - */ - public void setBulletChar(Character c) { - Integer val = (c == null) ? null : (int)c.charValue(); - setParagraphTextPropVal("bullet.char", val); - } - - /** - * Returns the bullet character - */ - public Character getBulletChar() { - TextProp tp = getPropVal(_paragraphStyle, "bullet.char", this); - return (tp == null) ? null : (char)tp.getValue(); - } - - /** - * Sets the bullet size - */ - public void setBulletSize(Double size) { - setPctOrPoints("bullet.size", size); - } - - /** - * Returns the bullet size, null if unset - */ - public Double getBulletSize() { - return getPctOrPoints("bullet.size"); - } - - /** - * Sets the bullet color - */ - public void setBulletColor(Color color) { - Integer val = (color == null) ? null : new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB(); - setParagraphTextPropVal("bullet.color", val); - setFlag(ParagraphFlagsTextProp.BULLET_HARDCOLOR_IDX, (color != null)); - } - - /** - * Returns the bullet color - */ - public Color getBulletColor() { - TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this); - boolean hasColor = getFlag(ParagraphFlagsTextProp.BULLET_HARDCOLOR_IDX); - if (tp == null || !hasColor) { - // if bullet color is undefined, return color of first run - if (_runs.isEmpty()) { - return null; - } - - SolidPaint sp = _runs.get(0).getFontColor(); - if(sp == null) { - return null; - } - - return DrawPaint.applyColorTransform(sp.getSolidColor()); - } - - return getColorFromColorIndexStruct(tp.getValue(), _sheet); - } - - /** - * Sets the bullet font - */ - public void setBulletFont(String typeface) { - if (typeface == null) { - setPropVal(_paragraphStyle, "bullet.font", null); - setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, false); - } - - FontCollection fc = getSheet().getSlideShow().getFontCollection(); - int idx = fc.addFont(typeface); - - setParagraphTextPropVal("bullet.font", idx); - setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, true); - } - - /** - * Returns the bullet font - */ - public String getBulletFont() { - TextProp tp = getPropVal(_paragraphStyle, "bullet.font", this); - boolean hasFont = getFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX); - if (tp == null || !hasFont) return getDefaultFontFamily(); - PPFont ppFont = getSheet().getSlideShow().getFont(tp.getValue()); - assert(ppFont != null); - return ppFont.getFontName(); - } - - @Override - public void setLineSpacing(Double lineSpacing) { - setPctOrPoints("linespacing", lineSpacing); - } - - @Override - public Double getLineSpacing() { - return getPctOrPoints("linespacing"); - } - - @Override - public void setSpaceBefore(Double spaceBefore) { - setPctOrPoints("spacebefore", spaceBefore); - } - - @Override - public Double getSpaceBefore() { - return getPctOrPoints("spacebefore"); - } - - @Override - public void setSpaceAfter(Double spaceAfter) { - setPctOrPoints("spaceafter", spaceAfter); - } - - @Override - public Double getSpaceAfter() { - return getPctOrPoints("spaceafter"); - } - - @Override - public Double getDefaultTabSize() { - // TODO: implement - return null; - } - - private Double getPctOrPoints(String propName) { - TextProp tp = getPropVal(_paragraphStyle, propName, this); - if (tp == null) return null; - int val = tp.getValue(); - return (val < 0) ? Units.masterToPoints(val) : val; - } - - private void setPctOrPoints(String propName, Double dval) { - Integer ival = null; - if (dval != null) { - ival = (dval < 0) ? Units.pointsToMaster(dval) : dval.intValue(); - } - setParagraphTextPropVal(propName, ival); - } - - private boolean getFlag(int index) { - BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, ParagraphFlagsTextProp.NAME, this); - return (tp == null) ? false : tp.getSubValue(index); - } - - private void setFlag(int index, boolean value) { - BitMaskTextProp tp = (BitMaskTextProp)_paragraphStyle.addWithName(ParagraphFlagsTextProp.NAME); - tp.setSubValue(value, index); - setDirty(); - } - - /** - * Fetch the value of the given Paragraph related TextProp. Returns null if - * that TextProp isn't present. If the TextProp isn't present, the value - * from the appropriate Master Sheet will apply. - * - * The propName can be a comma-separated list, in case multiple equivalent values - * are queried - */ - protected static TextProp getPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) { - String propNames[] = propName.split(","); - for (String pn : propNames) { - TextProp prop = props.findByName(pn); - if (prop == null) { - continue; - } - - // Font properties (maybe other too???) can have an index of -1 - // so we check the master for this font index then - if (pn.contains("font") && prop.getValue() == -1) { - return getMasterPropVal(props, pn, paragraph); - } - - return prop; - } - - return getMasterPropVal(props, propName, paragraph); - } - - private static TextProp getMasterPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) { - String propNames[] = propName.split(","); - - BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME); - boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0); - if (hardAttribute) return null; - - HSLFSheet sheet = paragraph.getSheet(); - int txtype = paragraph.getRunType(); - HSLFMasterSheet master = sheet.getMasterSheet(); - if (master == null) { - logger.log(POILogger.WARN, "MasterSheet is not available"); - return null; - } - - boolean isChar = props.getTextPropType() == TextPropType.character; - - for (String pn : propNames) { - TextProp prop = master.getStyleAttribute(txtype, paragraph.getIndentLevel(), pn, isChar); - if (prop != null) return prop; - } - - return null; - } - - /** - * Returns the named TextProp, either by fetching it (if it exists) or - * adding it (if it didn't) - * - * @param props the TextPropCollection to fetch from / add into - * @param name the name of the TextProp to fetch/add - * @param val the value, null if unset - */ - protected static void setPropVal(TextPropCollection props, String name, Integer val) { - if (val == null) { - props.removeByName(name); - return; - } - - // Fetch / Add the TextProp - TextProp tp = props.addWithName(name); - tp.setValue(val); - } - - /** - * Check and add linebreaks to text runs leading other paragraphs - * - * @param paragraphs - */ - protected static void fixLineEndings(List paragraphs) { - HSLFTextRun lastRun = null; - for (HSLFTextParagraph p : paragraphs) { - if (lastRun != null && !lastRun.getRawText().endsWith("\r")) { - lastRun.setText(lastRun.getRawText() + "\r"); - } - List ltr = p.getTextRuns(); - if (ltr.isEmpty()) { - throw new RuntimeException("paragraph without textruns found"); - } - lastRun = ltr.get(ltr.size() - 1); - assert (lastRun.getRawText() != null); - } - } - - /** - * Search for a StyleTextPropAtom is for this text header (list of paragraphs) - * - * @param header the header - * @param textLen the length of the rawtext, or -1 if the length is not known - */ - private static StyleTextPropAtom findStyleAtomPresent(TextHeaderAtom header, int textLen) { - boolean afterHeader = false; - StyleTextPropAtom style = null; - for (Record record : header.getParentRecord().getChildRecords()) { - long rt = record.getRecordType(); - if (afterHeader && rt == RecordTypes.TextHeaderAtom.typeID) { - // already on the next header, quit searching - break; - } - afterHeader |= (header == record); - if (afterHeader && rt == RecordTypes.StyleTextPropAtom.typeID) { - // found it - style = (StyleTextPropAtom) record; - } - } - - if (style == null) { - logger.log(POILogger.INFO, "styles atom doesn't exist. Creating dummy record for later saving."); - style = new StyleTextPropAtom((textLen < 0) ? 1 : textLen); - } else { - if (textLen >= 0) { - style.setParentTextSize(textLen); - } - } - - return style; - } - - /** - * Saves the modified paragraphs/textrun to the records. - * Also updates the styles to the correct text length. - */ - protected static void storeText(List paragraphs) { - fixLineEndings(paragraphs); - updateTextAtom(paragraphs); - updateStyles(paragraphs); - updateHyperlinks(paragraphs); - refreshRecords(paragraphs); - - for (HSLFTextParagraph p : paragraphs) { - p._dirty = false; - } - } - - /** - * Set the correct text atom depending on the multibyte usage - */ - private static void updateTextAtom(List paragraphs) { - final String rawText = toInternalString(getRawText(paragraphs)); - - // Will it fit in a 8 bit atom? - boolean isUnicode = StringUtil.hasMultibyte(rawText); - // isUnicode = true; - - TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom; - TextBytesAtom byteAtom = paragraphs.get(0)._byteAtom; - TextCharsAtom charAtom = paragraphs.get(0)._charAtom; - StyleTextPropAtom styleAtom = findStyleAtomPresent(headerAtom, rawText.length()); - - // Store in the appropriate record - Record oldRecord = null, newRecord = null; - if (isUnicode) { - if (byteAtom != null || charAtom == null) { - oldRecord = byteAtom; - charAtom = new TextCharsAtom(); - } - newRecord = charAtom; - charAtom.setText(rawText); - } else { - if (charAtom != null || byteAtom == null) { - oldRecord = charAtom; - byteAtom = new TextBytesAtom(); - } - newRecord = byteAtom; - byte[] byteText = new byte[rawText.length()]; - StringUtil.putCompressedUnicode(rawText, byteText, 0); - byteAtom.setText(byteText); - } - assert (newRecord != null); - - RecordContainer _txtbox = headerAtom.getParentRecord(); - Record[] cr = _txtbox.getChildRecords(); - int /* headerIdx = -1, */ textIdx = -1, styleIdx = -1; - for (int i = 0; i < cr.length; i++) { - Record r = cr[i]; - if (r == headerAtom) ; // headerIdx = i; - else if (r == oldRecord || r == newRecord) textIdx = i; - else if (r == styleAtom) styleIdx = i; - } - - if (textIdx == -1) { - // the old record was never registered, ignore it - _txtbox.addChildAfter(newRecord, headerAtom); - // textIdx = headerIdx + 1; - } else { - // swap not appropriated records - noop if unchanged - cr[textIdx] = newRecord; - } - - if (styleIdx == -1) { - // Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom - _txtbox.addChildAfter(styleAtom, newRecord); - } - - for (HSLFTextParagraph p : paragraphs) { - if (newRecord == byteAtom) { - p._byteAtom = byteAtom; - p._charAtom = null; - } else { - p._byteAtom = null; - p._charAtom = charAtom; - } - } - - } - - /** - * Update paragraph and character styles - merges them when subsequential styles match - */ - private static void updateStyles(List paragraphs) { - final String rawText = toInternalString(getRawText(paragraphs)); - TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom; - StyleTextPropAtom styleAtom = findStyleAtomPresent(headerAtom, rawText.length()); - - // Update the text length for its Paragraph and Character stylings - // * reset the length, to the new string's length - // * add on +1 if the last block - - styleAtom.clearStyles(); - - TextPropCollection lastPTPC = null, lastRTPC = null, ptpc = null, rtpc = null; - for (HSLFTextParagraph para : paragraphs) { - ptpc = para.getParagraphStyle(); - ptpc.updateTextSize(0); - if (!ptpc.equals(lastPTPC)) { - lastPTPC = styleAtom.addParagraphTextPropCollection(0); - lastPTPC.copy(ptpc); - } - for (HSLFTextRun tr : para.getTextRuns()) { - rtpc = tr.getCharacterStyle(); - rtpc.updateTextSize(0); - if (!rtpc.equals(lastRTPC)) { - lastRTPC = styleAtom.addCharacterTextPropCollection(0); - lastRTPC.copy(rtpc); - } - int len = tr.getLength(); - ptpc.updateTextSize(ptpc.getCharactersCovered() + len); - rtpc.updateTextSize(len); - lastPTPC.updateTextSize(lastPTPC.getCharactersCovered() + len); - lastRTPC.updateTextSize(lastRTPC.getCharactersCovered() + len); - } - } - - assert (lastPTPC != null && lastRTPC != null && ptpc != null && rtpc != null); - ptpc.updateTextSize(ptpc.getCharactersCovered() + 1); - rtpc.updateTextSize(rtpc.getCharactersCovered() + 1); - lastPTPC.updateTextSize(lastPTPC.getCharactersCovered() + 1); - lastRTPC.updateTextSize(lastRTPC.getCharactersCovered() + 1); - - /** - * If TextSpecInfoAtom is present, we must update the text size in it, - * otherwise the ppt will be corrupted - */ - for (Record r : paragraphs.get(0).getRecords()) { - if (r instanceof TextSpecInfoAtom) { - ((TextSpecInfoAtom) r).setParentSize(rawText.length() + 1); - break; - } - } - } - - private static void updateHyperlinks(List paragraphs) { - TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom; - RecordContainer _txtbox = headerAtom.getParentRecord(); - // remove existing hyperlink records - for (Record r : _txtbox.getChildRecords()) { - if (r instanceof InteractiveInfo || r instanceof TxInteractiveInfoAtom) { - _txtbox.removeChild(r); - } - } - // now go through all the textruns and check for hyperlinks - HSLFHyperlink lastLink = null; - for (HSLFTextParagraph para : paragraphs) { - for (HSLFTextRun run : para) { - HSLFHyperlink thisLink = run.getHyperlink(); - if (thisLink != null && thisLink == lastLink) { - // the hyperlink extends over this text run, increase its length - // TODO: the text run might be longer than the hyperlink - thisLink.setEndIndex(thisLink.getEndIndex()+run.getLength()); - } else { - if (lastLink != null) { - InteractiveInfo info = lastLink.getInfo(); - TxInteractiveInfoAtom txinfo = lastLink.getTextRunInfo(); - assert(info != null && txinfo != null); - _txtbox.appendChildRecord(info); - _txtbox.appendChildRecord(txinfo); - } - } - lastLink = thisLink; - } - } - - if (lastLink != null) { - InteractiveInfo info = lastLink.getInfo(); - TxInteractiveInfoAtom txinfo = lastLink.getTextRunInfo(); - assert(info != null && txinfo != null); - _txtbox.appendChildRecord(info); - _txtbox.appendChildRecord(txinfo); - } - } - - /** - * Writes the textbox records back to the document record - */ - private static void refreshRecords(List paragraphs) { - TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom; - RecordContainer _txtbox = headerAtom.getParentRecord(); - if (_txtbox instanceof EscherTextboxWrapper) { - try { - ((EscherTextboxWrapper) _txtbox).writeOut(null); - } catch (IOException e) { - throw new RuntimeException("failed dummy write", e); - } - } - } - - /** - * Adds the supplied text onto the end of the TextParagraphs, - * creating a new RichTextRun for it to sit in. - * - * @param text the text string used by this object. - */ - protected static HSLFTextRun appendText(List paragraphs, String text, boolean newParagraph) { - text = toInternalString(text); - - // check paragraphs - assert(!paragraphs.isEmpty() && !paragraphs.get(0).getTextRuns().isEmpty()); - - HSLFTextParagraph htp = paragraphs.get(paragraphs.size() - 1); - HSLFTextRun htr = htp.getTextRuns().get(htp.getTextRuns().size() - 1); - - boolean addParagraph = newParagraph; - for (String rawText : text.split("(?<=\r)")) { - // special case, if last text paragraph or run is empty, we will reuse it - boolean lastRunEmpty = (htr.getLength() == 0); - boolean lastParaEmpty = lastRunEmpty && (htp.getTextRuns().size() == 1); - - if (addParagraph && !lastParaEmpty) { - TextPropCollection tpc = htp.getParagraphStyle(); - HSLFTextParagraph prevHtp = htp; - htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom, paragraphs); - htp.getParagraphStyle().copy(tpc); - htp.setParentShape(prevHtp.getParentShape()); - htp.setShapeId(prevHtp.getShapeId()); - htp.supplySheet(prevHtp.getSheet()); - paragraphs.add(htp); - } - addParagraph = true; - - if (!lastRunEmpty) { - TextPropCollection tpc = htr.getCharacterStyle(); - htr = new HSLFTextRun(htp); - htr.getCharacterStyle().copy(tpc); - htp.addTextRun(htr); - } - htr.setText(rawText); - } - - storeText(paragraphs); - - return htr; - } - - /** - * Sets (overwrites) the current text. - * Uses the properties of the first paragraph / textrun - * - * @param text the text string used by this object. - */ - public static HSLFTextRun setText(List paragraphs, String text) { - // check paragraphs - assert(!paragraphs.isEmpty() && !paragraphs.get(0).getTextRuns().isEmpty()); - - Iterator paraIter = paragraphs.iterator(); - HSLFTextParagraph htp = paraIter.next(); // keep first - assert (htp != null); - while (paraIter.hasNext()) { - paraIter.next(); - paraIter.remove(); - } - - Iterator runIter = htp.getTextRuns().iterator(); - if (runIter.hasNext()) { - HSLFTextRun htr = runIter.next(); - htr.setText(""); - while (runIter.hasNext()) { - runIter.next(); - runIter.remove(); - } - } else { - HSLFTextRun trun = new HSLFTextRun(htp); - htp.addTextRun(trun); - } - - return appendText(paragraphs, text, false); - } - - public static String getText(List paragraphs) { - assert (!paragraphs.isEmpty()); - String rawText = getRawText(paragraphs); - return toExternalString(rawText, paragraphs.get(0).getRunType()); - } - - public static String getRawText(List paragraphs) { - StringBuilder sb = new StringBuilder(); - for (HSLFTextParagraph p : paragraphs) { - for (HSLFTextRun r : p.getTextRuns()) { - sb.append(r.getRawText()); - } - } - return sb.toString(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (HSLFTextRun r : getTextRuns()) { - sb.append(r.getRawText()); - } - return toExternalString(sb.toString(), getRunType()); - } - - /** - * Returns a new string with line breaks converted into internal ppt - * representation - */ - protected static String toInternalString(String s) { - String ns = s.replaceAll("\\r?\\n", "\r"); - return ns; - } - - /** - * Converts raw text from the text paragraphs to a formatted string, - * i.e. it converts certain control characters used in the raw txt - * - * @param rawText the raw text - * @param runType the run type of the shape, paragraph or headerAtom. - * use -1 if unknown - * @return the formatted string - */ - public static String toExternalString(String rawText, int runType) { - // PowerPoint seems to store files with \r as the line break - // The messes things up on everything but a Mac, so translate - // them to \n - String text = rawText.replace('\r', '\n'); - - switch (runType) { - // 0xB acts like cariage return in page titles and like blank in the - // others - case -1: - case org.apache.poi.hslf.record.TextHeaderAtom.TITLE_TYPE: - case org.apache.poi.hslf.record.TextHeaderAtom.CENTER_TITLE_TYPE: - text = text.replace((char) 0x0B, '\n'); - break; - default: - text = text.replace((char) 0x0B, ' '); - break; - } - - return text; - } - - /** - * For a given PPDrawing, grab all the TextRuns - */ - public static List> findTextParagraphs(PPDrawing ppdrawing, HSLFSheet sheet) { - List> runsV = new ArrayList>(); - for (EscherTextboxWrapper wrapper : ppdrawing.getTextboxWrappers()) { - List p = findTextParagraphs(wrapper, sheet); - if (p != null) runsV.add(p); - } - return runsV; - } - - /** - * Scans through the supplied record array, looking for - * a TextHeaderAtom followed by one of a TextBytesAtom or - * a TextCharsAtom. Builds up TextRuns from these - * - * @param wrapper an EscherTextboxWrapper - */ - protected static List findTextParagraphs(EscherTextboxWrapper wrapper, HSLFSheet sheet) { - // propagate parents to parent-aware records - RecordContainer.handleParentAwareRecords(wrapper); - int shapeId = wrapper.getShapeId(); - List rv = null; - - OutlineTextRefAtom ota = (OutlineTextRefAtom)wrapper.findFirstOfType(OutlineTextRefAtom.typeID); - if (ota != null) { - // if we are based on an outline, there are no further records to be parsed from the wrapper - if (sheet == null) { - throw new RuntimeException("Outline atom reference can't be solved without a sheet record"); - } - - List> sheetRuns = sheet.getTextParagraphs(); - assert (sheetRuns != null); - - int idx = ota.getTextIndex(); - for (List r : sheetRuns) { - if (r.isEmpty()) continue; - int ridx = r.get(0).getIndex(); - if (ridx > idx) break; - if (ridx == idx) { - if (rv == null) { - rv = r; - } else { - // create a new container - // TODO: ... is this case really happening? - rv = new ArrayList(rv); - rv.addAll(r); - } - } - } - if (rv == null || rv.isEmpty()) { - logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx); - } - } else { - if (sheet != null) { - // check sheet runs first, so we get exactly the same paragraph list - List> sheetRuns = sheet.getTextParagraphs(); - assert (sheetRuns != null); - - for (List paras : sheetRuns) { - if (!paras.isEmpty() && paras.get(0)._headerAtom.getParentRecord() == wrapper) { - rv = paras; - break; - } - } - } - - if (rv == null) { - // if we haven't found the wrapper in the sheet runs, create a new paragraph list from its record - List> rvl = findTextParagraphs(wrapper.getChildRecords()); - switch (rvl.size()) { - case 0: break; // nothing found - case 1: rv = rvl.get(0); break; // normal case - default: - throw new RuntimeException("TextBox contains more than one list of paragraphs."); - } - } - } - - if (rv != null) { - StyleTextProp9Atom styleTextProp9Atom = wrapper.getStyleTextProp9Atom(); - - for (HSLFTextParagraph htp : rv) { - htp.setShapeId(shapeId); - htp.setStyleTextProp9Atom(styleTextProp9Atom); - } - } - return rv; - } - - /** - * Scans through the supplied record array, looking for - * a TextHeaderAtom followed by one of a TextBytesAtom or - * a TextCharsAtom. Builds up TextRuns from these - * - * @param records the records to build from - */ - protected static List> findTextParagraphs(Record[] records) { - List> paragraphCollection = new ArrayList>(); - - int[] recordIdx = { 0 }; - - for (int slwtIndex = 0; recordIdx[0] < records.length; slwtIndex++) { - TextHeaderAtom header = null; - TextBytesAtom tbytes = null; - TextCharsAtom tchars = null; - TextRulerAtom ruler = null; - MasterTextPropAtom indents = null; - - for (Record r : getRecords(records, recordIdx, null)) { - long rt = r.getRecordType(); - if (RecordTypes.TextHeaderAtom.typeID == rt) { - header = (TextHeaderAtom) r; - } else if (RecordTypes.TextBytesAtom.typeID == rt) { - tbytes = (TextBytesAtom) r; - } else if (RecordTypes.TextCharsAtom.typeID == rt) { - tchars = (TextCharsAtom) r; - } else if (RecordTypes.TextRulerAtom.typeID == rt) { - ruler = (TextRulerAtom) r; - } else if (RecordTypes.MasterTextPropAtom.typeID == rt) { - indents = (MasterTextPropAtom) r; - } - // don't search for RecordTypes.StyleTextPropAtom.typeID here ... see findStyleAtomPresent below - } - - if (header == null) break; - - if (header.getParentRecord() instanceof SlideListWithText) { - // runs found in PPDrawing are not linked with SlideListWithTexts - header.setIndex(slwtIndex); - } - - if (tbytes == null && tchars == null) { - tbytes = new TextBytesAtom(); - // don't add record yet - set it in storeText - logger.log(POILogger.INFO, "bytes nor chars atom doesn't exist. Creating dummy record for later saving."); - } - - String rawText = (tchars != null) ? tchars.getText() : tbytes.getText(); - StyleTextPropAtom styles = findStyleAtomPresent(header, rawText.length()); - - List paragraphs = new ArrayList(); - paragraphCollection.add(paragraphs); - - // split, but keep delimiter - for (String para : rawText.split("(?<=\r)")) { - HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, paragraphs); - paragraphs.add(tpara); - tpara._ruler = ruler; - tpara.getParagraphStyle().updateTextSize(para.length()); - - HSLFTextRun trun = new HSLFTextRun(tpara); - tpara.addTextRun(trun); - trun.setText(para); - } - - applyCharacterStyles(paragraphs, styles.getCharacterStyles()); - applyParagraphStyles(paragraphs, styles.getParagraphStyles()); - if (indents != null) { - applyParagraphIndents(paragraphs, indents.getIndents()); - } - } - - if (paragraphCollection.isEmpty()) { - logger.log(POILogger.DEBUG, "No text records found."); - } - - return paragraphCollection; - } - - protected static void applyHyperlinks(List paragraphs) { - List links = HSLFHyperlink.find(paragraphs); - - for (HSLFHyperlink h : links) { - int csIdx = 0; - for (HSLFTextParagraph p : paragraphs) { - if (csIdx > h.getEndIndex()) break; - List runs = p.getTextRuns(); - for (int rlen=0,rIdx=0; rIdx < runs.size(); csIdx+=rlen, rIdx++) { - HSLFTextRun run = runs.get(rIdx); - rlen = run.getLength(); - if (csIdx < h.getEndIndex() && h.getStartIndex() < csIdx+rlen) { - String rawText = run.getRawText(); - int startIdx = h.getStartIndex()-csIdx; - if (startIdx > 0) { - // hyperlink starts within current textrun - HSLFTextRun newRun = new HSLFTextRun(p); - newRun.setCharacterStyle(run.getCharacterStyle()); - newRun.setText(rawText.substring(startIdx)); - run.setText(rawText.substring(0, startIdx)); - runs.add(rIdx+1, newRun); - rlen = startIdx; - continue; - } - int endIdx = Math.min(rlen, h.getEndIndex()-h.getStartIndex()); - if (endIdx < rlen) { - // hyperlink ends before end of current textrun - HSLFTextRun newRun = new HSLFTextRun(p); - newRun.setCharacterStyle(run.getCharacterStyle()); - newRun.setText(rawText.substring(0, endIdx)); - run.setText(rawText.substring(endIdx)); - runs.add(rIdx, newRun); - rlen = endIdx; - run = newRun; - } - run.setHyperlink(h); - } - } - } - } - } - - protected static void applyCharacterStyles(List paragraphs, List charStyles) { - int paraIdx = 0, runIdx = 0; - HSLFTextRun trun; - - for (int csIdx = 0; csIdx < charStyles.size(); csIdx++) { - TextPropCollection p = charStyles.get(csIdx); - for (int ccRun = 0, ccStyle = p.getCharactersCovered(); ccRun < ccStyle;) { - HSLFTextParagraph para = paragraphs.get(paraIdx); - List runs = para.getTextRuns(); - trun = runs.get(runIdx); - final int len = trun.getLength(); - - if (ccRun + len <= ccStyle) { - ccRun += len; - } else { - String text = trun.getRawText(); - trun.setText(text.substring(0, ccStyle - ccRun)); - - HSLFTextRun nextRun = new HSLFTextRun(para); - nextRun.setText(text.substring(ccStyle - ccRun)); - runs.add(runIdx + 1, nextRun); - - ccRun += ccStyle - ccRun; - } - - trun.setCharacterStyle(p); - - if (paraIdx == paragraphs.size()-1 && runIdx == runs.size()-1) { - if (csIdx < charStyles.size() - 1) { - // special case, empty trailing text run - HSLFTextRun nextRun = new HSLFTextRun(para); - nextRun.setText(""); - runs.add(nextRun); - ccRun++; - } else { - // need to add +1 to the last run of the last paragraph - trun.getCharacterStyle().updateTextSize(trun.getLength()+1); - ccRun++; - } - } - - // need to compare it again, in case a run has been added after - if (++runIdx == runs.size()) { - paraIdx++; - runIdx = 0; - } - } - } - } - - protected static void applyParagraphStyles(List paragraphs, List paraStyles) { - int paraIdx = 0; - for (TextPropCollection p : paraStyles) { - for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) { - if (paraIdx >= paragraphs.size()) return; - HSLFTextParagraph htp = paragraphs.get(paraIdx); - TextPropCollection pCopy = new TextPropCollection(0, TextPropType.paragraph); - pCopy.copy(p); - htp.setParagraphStyle(pCopy); - int len = 0; - for (HSLFTextRun trun : htp.getTextRuns()) { - len += trun.getLength(); - } - if (paraIdx == paragraphs.size()-1) len++; - pCopy.updateTextSize(len); - ccPara += len; - } - } - } - - protected static void applyParagraphIndents(List paragraphs, List paraStyles) { - int paraIdx = 0; - for (IndentProp p : paraStyles) { - for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) { - if (paraIdx >= paragraphs.size() || ccPara >= ccStyle-1) return; - HSLFTextParagraph para = paragraphs.get(paraIdx); - int len = 0; - for (HSLFTextRun trun : para.getTextRuns()) { - len += trun.getLength(); - } - para.setIndentLevel(p.getIndentLevel()); - ccPara += len + 1; - } - } - } - - protected static List createEmptyParagraph() { - EscherTextboxWrapper wrapper = new EscherTextboxWrapper(); - return createEmptyParagraph(wrapper); - } - - protected static List createEmptyParagraph(EscherTextboxWrapper wrapper) { - TextHeaderAtom tha = new TextHeaderAtom(); - tha.setParentRecord(wrapper); - wrapper.appendChildRecord(tha); - - TextBytesAtom tba = new TextBytesAtom(); - tba.setText("".getBytes(LocaleUtil.CHARSET_1252)); - wrapper.appendChildRecord(tba); - - StyleTextPropAtom sta = new StyleTextPropAtom(1); - TextPropCollection paraStyle = sta.addParagraphTextPropCollection(1); - TextPropCollection charStyle = sta.addCharacterTextPropCollection(1); - wrapper.appendChildRecord(sta); - - List paragraphs = new ArrayList(1); - HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, paragraphs); - htp.setParagraphStyle(paraStyle); - paragraphs.add(htp); - - HSLFTextRun htr = new HSLFTextRun(htp); - htr.setCharacterStyle(charStyle); - htr.setText(""); - htp.addTextRun(htr); - - return paragraphs; - } - - public EscherTextboxWrapper getTextboxWrapper() { - return (EscherTextboxWrapper) _headerAtom.getParentRecord(); - } - - protected static Color getColorFromColorIndexStruct(int rgb, HSLFSheet sheet) { - int cidx = rgb >>> 24; - Color tmp; - switch (cidx) { - // Background ... Accent 3 color - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - if (sheet == null) return null; - ColorSchemeAtom ca = sheet.getColorScheme(); - tmp = new Color(ca.getColor(cidx), true); - break; - // Color is an sRGB value specified by red, green, and blue fields. - case 0xFE: - tmp = new Color(rgb, true); - break; - // Color is undefined. - default: - case 0xFF: - return null; - } - return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); - } - - /** - * Sets the value of the given Paragraph TextProp, add if required - * @param propName The name of the Paragraph TextProp - * @param val The value to set for the TextProp - */ - public void setParagraphTextPropVal(String propName, Integer val) { - setPropVal(_paragraphStyle, propName, val); - setDirty(); - } - - /** - * marks this paragraph dirty, so its records will be renewed on save - */ - public void setDirty() { - _dirty = true; - } - - public boolean isDirty() { - return _dirty; - } - - /** - * Calculates the start index of the given text run - * - * @param textrun the text run to search for - * @return the start index with the paragraph collection or -1 if not found - */ - /* package */ int getStartIdxOfTextRun(HSLFTextRun textrun) { - int idx = 0; - for (HSLFTextParagraph p : parentList) { - for (HSLFTextRun r : p) { - if (r == textrun) { - return idx; - } - idx += r.getLength(); - } - } - return -1; - } - - /** - * {@inheritDoc} - * - * @see RoundTripHFPlaceholder12 - */ - @Override - public boolean isHeaderOrFooter() { - HSLFShape s = getParentShape(); - if (s == null) { - return false; - } - RoundTripHFPlaceholder12 hfPl = s.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID); - if (hfPl == null) { - return false; - } - - int plId = hfPl.getPlaceholderId(); - switch (plId) { - case OEPlaceholderAtom.MasterDate: - case OEPlaceholderAtom.MasterSlideNumber: - case OEPlaceholderAtom.MasterFooter: - case OEPlaceholderAtom.MasterHeader: - return true; - default: - return false; - } - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java deleted file mode 100644 index 427e2d2c5..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java +++ /dev/null @@ -1,417 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getPropVal; - -import java.awt.Color; - -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.model.textproperties.BitMaskTextProp; -import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp; -import org.apache.poi.hslf.model.textproperties.TextProp; -import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.TextRun; -import org.apache.poi.util.Internal; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - - -/** - * Represents a run of text, all with the same style - * - */ -public final class HSLFTextRun implements TextRun { - protected POILogger logger = POILogFactory.getLogger(this.getClass()); - - /** The TextRun we belong to */ - private HSLFTextParagraph parentParagraph; - private String _runText = ""; - private String _fontFamily; - private HSLFHyperlink link; - - /** - * Our paragraph and character style. - * Note - we may share these styles with other RichTextRuns - */ - private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character); - - /** - * Create a new wrapper around a rich text string - * @param parentParagraph the parent paragraph - */ - public HSLFTextRun(HSLFTextParagraph parentParagraph) { - this.parentParagraph = parentParagraph; - } - - public TextPropCollection getCharacterStyle() { - return characterStyle; - } - - public void setCharacterStyle(TextPropCollection characterStyle) { - this.characterStyle.copy(characterStyle); - this.characterStyle.updateTextSize(_runText.length()); - } - - /** - * Setting a master style reference - * - * @param characterStyle the master style reference - * - * @since POI 3.14-Beta1 - */ - @Internal - /* package */ void setMasterStyleReference(TextPropCollection characterStyle) { - this.characterStyle = characterStyle; - } - - - /** - * Supply the SlideShow we belong to - */ - public void updateSheet() { - if (_fontFamily != null) { - setFontFamily(_fontFamily); - _fontFamily = null; - } - } - - /** - * Get the length of the text - */ - public int getLength() { - return _runText.length(); - } - - /** - * Fetch the text, in raw storage form - */ - public String getRawText() { - return _runText; - } - - /** - * Change the text - */ - public void setText(String text) { - if (text == null) { - throw new HSLFException("text must not be null"); - } - String newText = HSLFTextParagraph.toInternalString(text); - if (!newText.equals(_runText)) { - _runText = newText; - if (HSLFSlideShow.getLoadSavePhase() == HSLFSlideShow.LoadSavePhase.LOADED) { - parentParagraph.setDirty(); - } - } - } - - // --------------- Internal helpers on rich text properties ------- - - /** - * Fetch the value of the given flag in the CharFlagsTextProp. - * Returns false if the CharFlagsTextProp isn't present, since the - * text property won't be set if there's no CharFlagsTextProp. - */ - private boolean isCharFlagsTextPropVal(int index) { - return getFlag(index); - } - - protected boolean getFlag(int index) { - if (characterStyle == null) return false; - - BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME); - - if (prop == null || !prop.getSubPropMatches()[index]) { - int txtype = parentParagraph.getRunType(); - HSLFSheet sheet = parentParagraph.getSheet(); - if (sheet != null) { - HSLFMasterSheet master = sheet.getMasterSheet(); - if (master != null){ - prop = (BitMaskTextProp)master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), CharFlagsTextProp.NAME, true); - } - } else { - logger.log(POILogger.WARN, "MasterSheet is not available"); - } - } - - return prop == null ? false : prop.getSubValue(index); - } - - /** - * Set the value of the given flag in the CharFlagsTextProp, adding - * it if required. - */ - private void setCharFlagsTextPropVal(int index, boolean value) { - // TODO: check if paragraph/chars can be handled the same ... - if (getFlag(index) != value) { - setFlag(index, value); - parentParagraph.setDirty(); - } - } - - /** - * Sets the value of the given Paragraph TextProp, add if required - * @param propName The name of the Paragraph TextProp - * @param val The value to set for the TextProp - */ - public void setCharTextPropVal(String propName, Integer val) { - HSLFTextParagraph.setPropVal(characterStyle, propName, val); - parentParagraph.setDirty(); - } - - - // --------------- Friendly getters / setters on rich text properties ------- - - @Override - public boolean isBold() { - return isCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX); - } - - @Override - public void setBold(boolean bold) { - setCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX, bold); - } - - @Override - public boolean isItalic() { - return isCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX); - } - - @Override - public void setItalic(boolean italic) { - setCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX, italic); - } - - @Override - public boolean isUnderlined() { - return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX); - } - - @Override - public void setUnderlined(boolean underlined) { - setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined); - } - - /** - * Does the text have a shadow? - */ - public boolean isShadowed() { - return isCharFlagsTextPropVal(CharFlagsTextProp.SHADOW_IDX); - } - - /** - * Does the text have a shadow? - */ - public void setShadowed(boolean flag) { - setCharFlagsTextPropVal(CharFlagsTextProp.SHADOW_IDX, flag); - } - - /** - * Is this text embossed? - */ - public boolean isEmbossed() { - return isCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX); - } - - /** - * Is this text embossed? - */ - public void setEmbossed(boolean flag) { - setCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX, flag); - } - - @Override - public boolean isStrikethrough() { - return isCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX); - } - - @Override - public void setStrikethrough(boolean flag) { - setCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX, flag); - } - - /** - * Gets the subscript/superscript option - * - * @return the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript - */ - public int getSuperscript() { - TextProp tp = getPropVal(characterStyle, "superscript", parentParagraph); - return tp == null ? 0 : tp.getValue(); - } - - /** - * Sets the subscript/superscript option - * - * @param val the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript - */ - public void setSuperscript(int val) { - setCharTextPropVal("superscript", val); - } - - @Override - public Double getFontSize() { - TextProp tp = getPropVal(characterStyle, "font.size", parentParagraph); - return tp == null ? null : (double)tp.getValue(); - } - - - @Override - public void setFontSize(Double fontSize) { - Integer iFontSize = (fontSize == null) ? null : fontSize.intValue(); - setCharTextPropVal("font.size", iFontSize); - } - - /** - * Gets the font index - */ - public int getFontIndex() { - TextProp tp = getPropVal(characterStyle, "font.index", parentParagraph); - return tp == null ? -1 : tp.getValue(); - } - - /** - * Sets the font index - */ - public void setFontIndex(int idx) { - setCharTextPropVal("font.index", idx); - } - - @Override - public void setFontFamily(String fontFamily) { - HSLFSheet sheet = parentParagraph.getSheet(); - @SuppressWarnings("resource") - HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow(); - if (sheet == null || slideShow == null) { - //we can't set font since slideshow is not assigned yet - _fontFamily = fontFamily; - return; - } - // Get the index for this font (adding if needed) - Integer fontIdx = (fontFamily == null) ? null : slideShow.getFontCollection().addFont(fontFamily); - setCharTextPropVal("font.index", fontIdx); - } - - @Override - public String getFontFamily() { - HSLFSheet sheet = parentParagraph.getSheet(); - @SuppressWarnings("resource") - HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow(); - if (sheet == null || slideShow == null) { - return _fontFamily; - } - TextProp tp = getPropVal(characterStyle, "font.index,asian.font.index,ansi.font.index,symbol.font.index", parentParagraph); - if (tp == null) { return null; } - return slideShow.getFontCollection().getFontWithId(tp.getValue()); - } - - /** - * @return font color as PaintStyle - */ - @Override - public SolidPaint getFontColor() { - TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph); - if (tp == null) return null; - Color color = HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet()); - SolidPaint ps = DrawPaint.createSolidPaint(color); - return ps; - } - - /** - * Sets color of the text, as a int bgr. - * (PowerPoint stores as BlueGreenRed, not the more - * usual RedGreenBlue) - * @see java.awt.Color - */ - public void setFontColor(int bgr) { - setCharTextPropVal("font.color", bgr); - } - - - @Override - public void setFontColor(Color color) { - setFontColor(DrawPaint.createSolidPaint(color)); - } - - @Override - public void setFontColor(PaintStyle color) { - if (!(color instanceof SolidPaint)) { - throw new IllegalArgumentException("HSLF only supports solid paint"); - } - // In PowerPont RGB bytes are swapped, as BGR - SolidPaint sp = (SolidPaint)color; - Color c = DrawPaint.applyColorTransform(sp.getSolidColor()); - int rgb = new Color(c.getBlue(), c.getGreen(), c.getRed(), 254).getRGB(); - setFontColor(rgb); - } - - protected void setFlag(int index, boolean value) { - BitMaskTextProp prop = (BitMaskTextProp)characterStyle.addWithName(CharFlagsTextProp.NAME); - prop.setSubValue(value, index); - } - - public HSLFTextParagraph getTextParagraph() { - return parentParagraph; - } - - public TextCap getTextCap() { - return TextCap.NONE; - } - - @Override - public boolean isSubscript() { - return getSuperscript() < 0; - } - - @Override - public boolean isSuperscript() { - return getSuperscript() > 0; - } - - public byte getPitchAndFamily() { - return 0; - } - - /** - * Sets the hyperlink - used when parsing the document - * - * @param link the hyperlink - */ - protected void setHyperlink(HSLFHyperlink link) { - this.link = link; - } - - @Override - public HSLFHyperlink getHyperlink() { - return link; - } - - @Override - public HSLFHyperlink createHyperlink() { - if (link == null) { - link = HSLFHyperlink.createHyperlink(this); - parentParagraph.setDirty(); - } - return link; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java deleted file mode 100644 index b26b3dfa2..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java +++ /dev/null @@ -1,851 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom; -import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12; - -import java.awt.font.FontRenderContext; -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.ddf.AbstractEscherOptRecord; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.ddf.EscherSimpleProperty; -import org.apache.poi.ddf.EscherTextboxRecord; -import org.apache.poi.hslf.exceptions.HSLFException; -import org.apache.poi.hslf.model.HSLFMetroShape; -import org.apache.poi.hslf.record.EscherTextboxWrapper; -import org.apache.poi.hslf.record.OEPlaceholderAtom; -import org.apache.poi.hslf.record.PPDrawing; -import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; -import org.apache.poi.hslf.record.TextHeaderAtom; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.DrawTextShape; -import org.apache.poi.sl.usermodel.Insets2D; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.ShapeContainer; -import org.apache.poi.sl.usermodel.TextShape; -import org.apache.poi.sl.usermodel.VerticalAlignment; -import org.apache.poi.util.POILogger; -import org.apache.poi.util.Units; - -/** - * A common superclass of all shapes that can hold text. - */ -public abstract class HSLFTextShape extends HSLFSimpleShape -implements TextShape { - - /** - * How to anchor the text - */ - private enum HSLFTextAnchor { - TOP (0, VerticalAlignment.TOP, false, false), - MIDDLE (1, VerticalAlignment.MIDDLE, false, false), - BOTTOM (2, VerticalAlignment.BOTTOM, false, false), - TOP_CENTER (3, VerticalAlignment.TOP, true, false), - MIDDLE_CENTER (4, VerticalAlignment.MIDDLE, true, false), - BOTTOM_CENTER (5, VerticalAlignment.BOTTOM, true, false), - TOP_BASELINE (6, VerticalAlignment.TOP, false, true), - BOTTOM_BASELINE (7, VerticalAlignment.BOTTOM, false, true), - TOP_CENTER_BASELINE (8, VerticalAlignment.TOP, true, true), - BOTTOM_CENTER_BASELINE(9, VerticalAlignment.BOTTOM, true, true); - - public final int nativeId; - public final VerticalAlignment vAlign; - public final boolean centered; - public final Boolean baseline; - - HSLFTextAnchor(int nativeId, VerticalAlignment vAlign, boolean centered, Boolean baseline) { - this.nativeId = nativeId; - this.vAlign = vAlign; - this.centered = centered; - this.baseline = baseline; - } - - static HSLFTextAnchor fromNativeId(int nativeId) { - for (HSLFTextAnchor ta : values()) { - if (ta.nativeId == nativeId) return ta; - } - return null; - } - } - - /** - * Specifies that a line of text will continue on subsequent lines instead - * of extending into or beyond a margin. - * Office Excel 2007, Excel 2010, PowerPoint 97, and PowerPoint 2010 read - * and use this value properly but do not write it. - */ - public static final int WrapSquare = 0; - /** - * Specifies a wrapping rule that is equivalent to that of WrapSquare - * Excel 97, Excel 2000, Excel 2002, and Office Excel 2003 use this value. - * All other product versions listed at the beginning of this appendix ignore this value. - */ - public static final int WrapByPoints = 1; - /** - * Specifies that a line of text will extend into or beyond a margin instead - * of continuing on subsequent lines. - * Excel 97, Word 97, Excel 2000, Word 2000, Excel 2002, - * and Office Excel 2003 do not use this value. - */ - public static final int WrapNone = 2; - /** - * Specifies a wrapping rule that is undefined and MUST be ignored. - */ - public static final int WrapTopBottom = 3; - /** - * Specifies a wrapping rule that is undefined and MUST be ignored. - */ - public static final int WrapThrough = 4; - - - /** - * TextRun object which holds actual text and format data - */ - protected List _paragraphs = new ArrayList(); - - /** - * Escher container which holds text attributes such as - * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc. - */ - protected EscherTextboxWrapper _txtbox; - - /** - * This setting is used for supporting a deprecated alignment - * - * @see - */ -// boolean alignToBaseline = false; - - /** - * Used to calculate text bounds - */ - protected static final FontRenderContext _frc = new FontRenderContext(null, true, true); - - /** - * Create a TextBox object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected HSLFTextShape(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * Create a new TextBox. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public HSLFTextShape(ShapeContainer parent){ - super(null, parent); - _escherContainer = createSpContainer(parent instanceof HSLFGroupShape); - } - - /** - * Create a new TextBox. This constructor is used when a new shape is created. - * - */ - public HSLFTextShape(){ - this(null); - } - - /** - * Set default properties for the TextRun. - * Depending on the text and shape type the defaults are different: - * TextBox: align=left, valign=top - * AutoShape: align=center, valign=middle - * - */ - protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){ - - } - - /** - * When a textbox is added to a sheet we need to tell upper-level - * PPDrawing about it. - * - * @param sh the sheet we are adding to - */ - protected void afterInsert(HSLFSheet sh){ - super.afterInsert(sh); - - storeText(); - - EscherTextboxWrapper thisTxtbox = getEscherTextboxWrapper(); - if(thisTxtbox != null){ - _escherContainer.addChildRecord(thisTxtbox.getEscherRecord()); - - PPDrawing ppdrawing = sh.getPPDrawing(); - ppdrawing.addTextboxWrapper(thisTxtbox); - // Ensure the escher layer knows about the added records - try { - thisTxtbox.writeOut(null); - } catch (IOException e){ - throw new HSLFException(e); - } - boolean isInitialAnchor = getAnchor().equals(new Rectangle2D.Double()); - boolean isFilledTxt = !"".equals(getText()); - if (isInitialAnchor && isFilledTxt) { - resizeToFitText(); - } - } - for (HSLFTextParagraph htp : _paragraphs) { - htp.setShapeId(getShapeId()); - } - sh.onAddTextShape(this); - } - - protected EscherTextboxWrapper getEscherTextboxWrapper(){ - if(_txtbox != null) return _txtbox; - - EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID); - if (textRecord == null) return null; - - HSLFSheet sheet = getSheet(); - if (sheet != null) { - PPDrawing drawing = sheet.getPPDrawing(); - if (drawing != null) { - EscherTextboxWrapper wrappers[] = drawing.getTextboxWrappers(); - if (wrappers != null) { - for (EscherTextboxWrapper w : wrappers) { - // check for object identity - if (textRecord == w.getEscherRecord()) { - _txtbox = w; - return _txtbox; - } - } - } - } - } - - _txtbox = new EscherTextboxWrapper(textRecord); - return _txtbox; - } - - /** - * Adjust the size of the shape so it encompasses the text inside it. - * - * @return a Rectangle2D that is the bounds of this shape. - */ - public Rectangle2D resizeToFitText(){ - Rectangle2D anchor = getAnchor(); - if(anchor.getWidth() == 0.) { - logger.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px"); - anchor.setRect(anchor.getX(), anchor.getY(), 200., anchor.getHeight()); - setAnchor(anchor); - } - double height = getTextHeight(); - height += 1; // add a pixel to compensate rounding errors - - anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height); - setAnchor(anchor); - - return anchor; - } - - /** - * Returns the type of the text, from the TextHeaderAtom. - * Possible values can be seen from TextHeaderAtom - * @see org.apache.poi.hslf.record.TextHeaderAtom - */ - public int getRunType() { - getEscherTextboxWrapper(); - if (_txtbox == null) return -1; - List paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); - return (paras.isEmpty()) ? -1 : paras.get(0).getRunType(); - } - - /** - * Changes the type of the text. Values should be taken - * from TextHeaderAtom. No checking is done to ensure you - * set this to a valid value! - * @see org.apache.poi.hslf.record.TextHeaderAtom - */ - public void setRunType(int type) { - getEscherTextboxWrapper(); - if (_txtbox == null) return; - List paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); - if (!paras.isEmpty()) { - paras.get(0).setRunType(type); - } - } - - /** - * Returns the type of vertical alignment for the text. - * One of the Anchor* constants defined in this class. - * - * @return the type of alignment - */ - /* package */ HSLFTextAnchor getAlignment(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT); - HSLFTextAnchor align = HSLFTextAnchor.TOP; - if (prop == null){ - /** - * If vertical alignment was not found in the shape properties then try to - * fetch the master shape and search for the align property there. - */ - int type = getRunType(); - HSLFSheet sh = getSheet(); - HSLFMasterSheet master = (sh != null) ? sh.getMasterSheet() : null; - HSLFTextShape masterShape = (master != null) ? master.getPlaceholderByTextType(type) : null; - if (masterShape != null && type != TextHeaderAtom.OTHER_TYPE) { - align = masterShape.getAlignment(); - } else { - //not found in the master sheet. Use the hardcoded defaults. - switch (type){ - case TextHeaderAtom.TITLE_TYPE: - case TextHeaderAtom.CENTER_TITLE_TYPE: - align = HSLFTextAnchor.MIDDLE; - break; - default: - align = HSLFTextAnchor.TOP; - break; - } - } - } else { - align = HSLFTextAnchor.fromNativeId(prop.getPropertyValue()); - } - - if (align == null) { - align = HSLFTextAnchor.TOP; - } - - return align; - } - - /** - * Sets the type of alignment for the text. - * One of the Anchor* constants defined in this class. - * - * @param isCentered horizontal centered? - * @param vAlign vertical alignment - * @param baseline aligned to baseline? - */ - /* package */ void setAlignment(Boolean isCentered, VerticalAlignment vAlign, boolean baseline) { - for (HSLFTextAnchor hta : HSLFTextAnchor.values()) { - if ( - (hta.centered == (isCentered != null && isCentered)) && - (hta.vAlign == vAlign) && - (hta.baseline == null || hta.baseline == baseline) - ) { - setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, hta.nativeId); - break; - } - } - } - - /** - * @return true, if vertical alignment is relative to baseline - * this is only used for older versions less equals Office 2003 - */ - public boolean isAlignToBaseline() { - return getAlignment().baseline; - } - - /** - * Sets the vertical alignment relative to the baseline - * - * @param alignToBaseline if true, vertical alignment is relative to baseline - */ - public void setAlignToBaseline(boolean alignToBaseline) { - setAlignment(isHorizontalCentered(), getVerticalAlignment(), alignToBaseline); - } - - @Override - public boolean isHorizontalCentered() { - return getAlignment().centered; - } - - @Override - public void setHorizontalCentered(Boolean isCentered) { - setAlignment(isCentered, getVerticalAlignment(), getAlignment().baseline); - } - - @Override - public VerticalAlignment getVerticalAlignment() { - return getAlignment().vAlign; - } - - @Override - public void setVerticalAlignment(VerticalAlignment vAlign) { - setAlignment(isHorizontalCentered(), vAlign, getAlignment().baseline); - } - - /** - * Returns the distance (in points) between the bottom of the text frame - * and the bottom of the inscribed rectangle of the shape that contains the text. - * Default value is 1/20 inch. - * - * @return the botom margin - */ - public double getBottomInset(){ - return getInset(EscherProperties.TEXT__TEXTBOTTOM, .05); - } - - /** - * Sets the botom margin. - * @see #getBottomInset() - * - * @param margin the bottom margin - */ - public void setBottomInset(double margin){ - setInset(EscherProperties.TEXT__TEXTBOTTOM, margin); - } - - /** - * Returns the distance (in points) between the left edge of the text frame - * and the left edge of the inscribed rectangle of the shape that contains - * the text. - * Default value is 1/10 inch. - * - * @return the left margin - */ - public double getLeftInset(){ - return getInset(EscherProperties.TEXT__TEXTLEFT, .1); - } - - /** - * Sets the left margin. - * @see #getLeftInset() - * - * @param margin the left margin - */ - public void setLeftInset(double margin){ - setInset(EscherProperties.TEXT__TEXTLEFT, margin); - } - - /** - * Returns the distance (in points) between the right edge of the - * text frame and the right edge of the inscribed rectangle of the shape - * that contains the text. - * Default value is 1/10 inch. - * - * @return the right margin - */ - public double getRightInset(){ - return getInset(EscherProperties.TEXT__TEXTRIGHT, .1); - } - - /** - * Sets the right margin. - * @see #getRightInset() - * - * @param margin the right margin - */ - public void setRightInset(double margin){ - setInset(EscherProperties.TEXT__TEXTRIGHT, margin); - } - - /** - * Returns the distance (in points) between the top of the text frame - * and the top of the inscribed rectangle of the shape that contains the text. - * Default value is 1/20 inch. - * - * @return the top margin - */ - public double getTopInset(){ - return getInset(EscherProperties.TEXT__TEXTTOP, .05); - } - - /** - * Sets the top margin. - * @see #getTopInset() - * - * @param margin the top margin - */ - public void setTopInset(double margin){ - setInset(EscherProperties.TEXT__TEXTTOP, margin); - } - - /** - * Returns the distance (in points) between the edge of the text frame - * and the edge of the inscribed rectangle of the shape that contains the text. - * Default value is 1/20 inch. - * - * @param propId the id of the inset edge - * @return the inset in points - */ - private double getInset(short propId, double defaultInch) { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, propId); - int val = prop == null ? (int)(Units.toEMU(Units.POINT_DPI)*defaultInch) : prop.getPropertyValue(); - return Units.toPoints(val); - } - - /** - * @param propId the id of the inset edge - * @param margin the inset in points - */ - private void setInset(short propId, double margin){ - setEscherProperty(propId, Units.toEMU(margin)); - } - - /** - * Returns the value indicating word wrap. - * - * @return the value indicating word wrap. - * Must be one of the Wrap* constants defined in this class. - * - * @see MSOWRAPMODE - */ - public int getWordWrapEx() { - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT); - return prop == null ? WrapSquare : prop.getPropertyValue(); - } - - /** - * Specifies how the text should be wrapped - * - * @param wrap the value indicating how the text should be wrapped. - * Must be one of the Wrap* constants defined in this class. - */ - public void setWordWrapEx(int wrap){ - setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap); - } - - @Override - public boolean getWordWrap(){ - int ww = getWordWrapEx(); - return (ww != WrapNone); - } - - @Override - public void setWordWrap(boolean wrap) { - setWordWrapEx(wrap ? WrapSquare : WrapNone); - } - - /** - * @return id for the text. - */ - public int getTextId(){ - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTID); - return prop == null ? 0 : prop.getPropertyValue(); - } - - /** - * Sets text ID - * - * @param id of the text - */ - public void setTextId(int id){ - setEscherProperty(EscherProperties.TEXT__TEXTID, id); - } - - @Override - public List getTextParagraphs(){ - if (!_paragraphs.isEmpty()) return _paragraphs; - - _txtbox = getEscherTextboxWrapper(); - if (_txtbox == null) { - _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph()); - _txtbox = _paragraphs.get(0).getTextboxWrapper(); - } else { - _paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); - if (_paragraphs == null) { - // there are actually TextBoxRecords without extra data - see #54722 - _paragraphs = HSLFTextParagraph.createEmptyParagraph(_txtbox); - } - - if (_paragraphs.isEmpty()) { - logger.log(POILogger.WARN, "TextRecord didn't contained any text lines"); - } - } - - for (HSLFTextParagraph p : _paragraphs) { - p.setParentShape(this); - } - - return _paragraphs; - } - - public void setSheet(HSLFSheet sheet) { - _sheet = sheet; - - // Initialize _txtrun object. - // (We can't do it in the constructor because the sheet - // is not assigned then, it's only built once we have - // all the records) - List ltp = getTextParagraphs(); - HSLFTextParagraph.supplySheet(ltp, sheet); - } - - /** - * Return {@link OEPlaceholderAtom}, the atom that describes a placeholder. - * - * @return {@link OEPlaceholderAtom} or {@code null} if not found - */ - public OEPlaceholderAtom getPlaceholderAtom(){ - return getClientDataRecord(OEPlaceholderAtom.typeID); - } - - /** - * Return {@link RoundTripHFPlaceholder12}, the atom that describes a header/footer placeholder. - * Compare the {@link RoundTripHFPlaceholder12#getPlaceholderId()} with - * {@link OEPlaceholderAtom#MasterHeader} or {@link OEPlaceholderAtom#MasterFooter}, to find out - * what kind of placeholder this is. - * - * @return {@link RoundTripHFPlaceholder12} or {@code null} if not found - * - * @since POI 3.14-Beta2 - */ - public RoundTripHFPlaceholder12 getHFPlaceholderAtom() { - // special case for files saved in Office 2007 - return getClientDataRecord(RoundTripHFPlaceholder12.typeID); - } - - @Override - public boolean isPlaceholder() { - OEPlaceholderAtom oep = getPlaceholderAtom(); - if (oep != null) return true; - - //special case for files saved in Office 2007 - RoundTripHFPlaceholder12 hldr = getHFPlaceholderAtom(); - if (hldr != null) return true; - - return false; - } - - - @Override - public Iterator iterator() { - return _paragraphs.iterator(); - } - - @Override - public Insets2D getInsets() { - Insets2D insets = new Insets2D(getTopInset(), getLeftInset(), getBottomInset(), getRightInset()); - return insets; - } - - @Override - public void setInsets(Insets2D insets) { - setTopInset(insets.top); - setLeftInset(insets.left); - setBottomInset(insets.bottom); - setRightInset(insets.right); - } - - @Override - public double getTextHeight(){ - DrawFactory drawFact = DrawFactory.getInstance(null); - DrawTextShape dts = drawFact.getDrawable(this); - return dts.getTextHeight(); - } - - @Override - public TextDirection getTextDirection() { - // see 2.4.5 MSOTXFL - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTFLOW); - int msotxfl = (prop == null) ? 0 : prop.getPropertyValue(); - switch (msotxfl) { - default: - case 0: // msotxflHorzN - case 4: // msotxflHorzA - return TextDirection.HORIZONTAL; - case 1: // msotxflTtoBA - case 3: // msotxflTtoBN - case 5: // msotxflVertN - return TextDirection.VERTICAL; - case 2: // msotxflBtoT - return TextDirection.VERTICAL_270; - // TextDirection.STACKED is not supported - } - } - - @Override - public void setTextDirection(TextDirection orientation) { - AbstractEscherOptRecord opt = getEscherOptRecord(); - int msotxfl; - if (orientation == null) { - msotxfl = -1; - } else { - switch (orientation) { - default: - case STACKED: - // not supported -> remove - msotxfl = -1; - break; - case HORIZONTAL: - msotxfl = 0; - break; - case VERTICAL: - msotxfl = 1; - break; - case VERTICAL_270: - // always interpreted as horizontal - msotxfl = 2; - break; - } - } - setEscherProperty(opt, EscherProperties.TEXT__TEXTFLOW, msotxfl); - } - - @Override - public Double getTextRotation() { - // see 2.4.6 MSOCDIR - AbstractEscherOptRecord opt = getEscherOptRecord(); - EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__FONTROTATION); - return (prop == null) ? null : (90. * prop.getPropertyValue()); - } - - @Override - public void setTextRotation(Double rotation) { - AbstractEscherOptRecord opt = getEscherOptRecord(); - if (rotation == null) { - opt.removeEscherProperty(EscherProperties.TEXT__FONTROTATION); - } else { - int rot = (int)(Math.round(rotation / 90.) % 4L); - setEscherProperty(EscherProperties.TEXT__FONTROTATION, rot); - } - } - - /** - * Returns the raw text content of the shape. This hasn't had any - * changes applied to it, and so is probably unlikely to print - * out nicely. - */ - public String getRawText() { - return HSLFTextParagraph.getRawText(getTextParagraphs()); - } - - @Override - public String getText() { - String rawText = getRawText(); - return HSLFTextParagraph.toExternalString(rawText, getRunType()); - } - - @Override - public HSLFTextRun appendText(String text, boolean newParagraph) { - // init paragraphs - List paras = getTextParagraphs(); - HSLFTextRun htr = HSLFTextParagraph.appendText(paras, text, newParagraph); - setTextId(getRawText().hashCode()); - return htr; - } - - @Override - public HSLFTextRun setText(String text) { - // init paragraphs - List paras = getTextParagraphs(); - HSLFTextRun htr = HSLFTextParagraph.setText(paras, text); - setTextId(getRawText().hashCode()); - return htr; - } - - /** - * Saves the modified paragraphs/textrun to the records. - * Also updates the styles to the correct text length. - */ - protected void storeText() { - List paras = getTextParagraphs(); - HSLFTextParagraph.storeText(paras); - } - - /** - * Returns the array of all hyperlinks in this text run - * - * @return the array of all hyperlinks in this text run or null - * if not found. - */ - public List getHyperlinks() { - return HSLFHyperlink.find(this); - } - - @Override - public void setTextPlaceholder(TextPlaceholder placeholder) { - // TOOD: check for correct placeholder handling - see org.apache.poi.hslf.model.Placeholder - Placeholder ph = null; - int runType; - switch (placeholder) { - default: - case BODY: - runType = TextHeaderAtom.BODY_TYPE; - ph = Placeholder.BODY; - break; - case TITLE: - runType = TextHeaderAtom.TITLE_TYPE; - ph = Placeholder.TITLE; - break; - case CENTER_BODY: - runType = TextHeaderAtom.CENTRE_BODY_TYPE; - ph = Placeholder.BODY; - break; - case CENTER_TITLE: - runType = TextHeaderAtom.CENTER_TITLE_TYPE; - ph = Placeholder.TITLE; - break; - case HALF_BODY: - runType = TextHeaderAtom.HALF_BODY_TYPE; - ph = Placeholder.BODY; - break; - case QUARTER_BODY: - runType = TextHeaderAtom.QUARTER_BODY_TYPE; - ph = Placeholder.BODY; - break; - case NOTES: - runType = TextHeaderAtom.NOTES_TYPE; - break; - case OTHER: - runType = TextHeaderAtom.OTHER_TYPE; - break; - } - setRunType(runType); - if (ph != null) { - setPlaceholder(ph); - } - } - - @Override - public TextPlaceholder getTextPlaceholder() { - switch (getRunType()) { - default: - case TextHeaderAtom.BODY_TYPE: return TextPlaceholder.BODY; - case TextHeaderAtom.TITLE_TYPE: return TextPlaceholder.TITLE; - case TextHeaderAtom.NOTES_TYPE: return TextPlaceholder.NOTES; - case TextHeaderAtom.OTHER_TYPE: return TextPlaceholder.OTHER; - case TextHeaderAtom.CENTRE_BODY_TYPE: return TextPlaceholder.CENTER_BODY; - case TextHeaderAtom.CENTER_TITLE_TYPE: return TextPlaceholder.CENTER_TITLE; - case TextHeaderAtom.HALF_BODY_TYPE: return TextPlaceholder.HALF_BODY; - case TextHeaderAtom.QUARTER_BODY_TYPE: return TextPlaceholder.QUARTER_BODY; - } - } - - - /** - * Get alternative representation of text shape stored as metro blob escher property. - * The returned shape is the first shape in stored group shape of the metro blob - * - * @return null, if there's no alternative representation, otherwise the text shape - */ - public TextShape getMetroShape() { - HSLFMetroShape> mbs = new HSLFMetroShape>(this); - return mbs.getShape(); - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java deleted file mode 100644 index b1e38d977..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.usermodel; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hslf.model.textproperties.TextProp; -import org.apache.poi.hslf.record.SlideAtom; - -/** - * Title masters define the design template for slides with a Title Slide layout. - * - * @author Yegor Kozlov - */ -public final class HSLFTitleMaster extends HSLFMasterSheet { - private final List> _paragraphs = new ArrayList>(); - - /** - * Constructs a TitleMaster - * - */ - public HSLFTitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) { - super(record, sheetNo); - - for (List l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { - if (!_paragraphs.contains(l)) _paragraphs.add(l); - } - } - - /** - * Returns an array of all the TextRuns found - */ - public List> getTextParagraphs() { - return _paragraphs; - } - - /** - * Delegate the call to the underlying slide master. - */ - public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) { - HSLFMasterSheet master = getMasterSheet(); - return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter); - } - - /** - * Returns the slide master for this title master. - */ - public HSLFMasterSheet getMasterSheet(){ - List master = getSlideShow().getSlideMasters(); - SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom(); - int masterId = sa.getMasterID(); - for (HSLFSlideMaster sm : master) { - if (masterId == sm._getSheetNumber()) return sm; - } - return null; - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/util/MutableByteArrayOutputStream.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/util/MutableByteArrayOutputStream.java deleted file mode 100644 index be7c04602..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/util/MutableByteArrayOutputStream.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.util; - -import java.io.ByteArrayOutputStream; - -/** - * This class doesn't work yet, but is here to show the idea of a - * ByteArrayOutputStream where you can track how many bytes you've - * already written, and go back and write over a previous part of the stream - * - * @author Nick Burch - */ - -public final class MutableByteArrayOutputStream extends ByteArrayOutputStream -{ - /** Return how many bytes we've stuffed in so far */ - public int getBytesWritten() { return -1; } - - /** Write some bytes to the array */ - public void write(byte[] b) {} - public void write(int b) {} - - /** Write some bytes to an earlier bit of the array */ - public void overwrite(byte[] b, int startPos) {} -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java b/trunk/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java deleted file mode 100644 index 10b566a8b..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hslf.util; - -import java.util.Calendar; -import java.util.Date; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LocaleUtil; - -/** - * A helper class for dealing with SystemTime Structs, as defined at - * http://msdn.microsoft.com/library/en-us/sysinfo/base/systemtime_str.asp . - * - * Discrepancies between Calendar and SYSTEMTIME: - * - that January = 1 in SYSTEMTIME, 0 in Calendar. - * - that the day of the week (0) starts on Sunday in SYSTEMTIME, and Monday in Calendar - * It is also the case that this does not store the timezone, and no... it is not - * stored as UTC either, but rather the local system time (yuck.) - */ -public final class SystemTimeUtils { - /** - * Get the date found in the byte array, as a java Data object - */ - public static Date getDate(byte[] data) { - return getDate(data,0); - } - /** - * Get the date found in the byte array, as a java Data object - */ - public static Date getDate(byte[] data, int offset) { - Calendar cal = LocaleUtil.getLocaleCalendar(); - - cal.set(Calendar.YEAR, LittleEndian.getShort(data,offset)); - cal.set(Calendar.MONTH, LittleEndian.getShort(data,offset+2)-1); - // Not actually needed - can be found from day of month - //cal.set(Calendar.DAY_OF_WEEK, LittleEndian.getShort(data,offset+4)+1); - cal.set(Calendar.DAY_OF_MONTH, LittleEndian.getShort(data,offset+6)); - cal.set(Calendar.HOUR_OF_DAY, LittleEndian.getShort(data,offset+8)); - cal.set(Calendar.MINUTE, LittleEndian.getShort(data,offset+10)); - cal.set(Calendar.SECOND, LittleEndian.getShort(data,offset+12)); - cal.set(Calendar.MILLISECOND, LittleEndian.getShort(data,offset+14)); - - return cal.getTime(); - } - - /** - * Convert the supplied java Date into a SystemTime struct, and write it - * into the supplied byte array. - */ - public static void storeDate(Date date, byte[] dest) { - storeDate(date, dest, 0); - } - /** - * Convert the supplied java Date into a SystemTime struct, and write it - * into the supplied byte array. - */ - public static void storeDate(Date date, byte[] dest, int offset) { - Calendar cal = LocaleUtil.getLocaleCalendar(); - cal.setTime(date); - - LittleEndian.putShort(dest, offset + 0, (short) cal.get(Calendar.YEAR)); - LittleEndian.putShort(dest, offset + 2, (short)(cal.get(Calendar.MONTH) + 1)); - LittleEndian.putShort(dest, offset + 4, (short)(cal.get(Calendar.DAY_OF_WEEK)-1)); - LittleEndian.putShort(dest, offset + 6, (short) cal.get(Calendar.DAY_OF_MONTH)); - LittleEndian.putShort(dest, offset + 8, (short) cal.get(Calendar.HOUR_OF_DAY)); - LittleEndian.putShort(dest, offset + 10,(short) cal.get(Calendar.MINUTE)); - LittleEndian.putShort(dest, offset + 12,(short) cal.get(Calendar.SECOND)); - LittleEndian.putShort(dest, offset + 14,(short) cal.get(Calendar.MILLISECOND)); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java deleted file mode 100644 index a1bf16264..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java +++ /dev/null @@ -1,640 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.POIReadOnlyDocument; -import org.apache.poi.hmef.attribute.MAPIRtfAttribute; -import org.apache.poi.hsmf.datatypes.AttachmentChunks; -import org.apache.poi.hsmf.datatypes.AttachmentChunks.AttachmentChunksSorter; -import org.apache.poi.hsmf.datatypes.ByteChunk; -import org.apache.poi.hsmf.datatypes.Chunk; -import org.apache.poi.hsmf.datatypes.ChunkGroup; -import org.apache.poi.hsmf.datatypes.Chunks; -import org.apache.poi.hsmf.datatypes.MAPIProperty; -import org.apache.poi.hsmf.datatypes.NameIdChunks; -import org.apache.poi.hsmf.datatypes.PropertyValue; -import org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue; -import org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue; -import org.apache.poi.hsmf.datatypes.RecipientChunks; -import org.apache.poi.hsmf.datatypes.RecipientChunks.RecipientChunksSorter; -import org.apache.poi.hsmf.datatypes.StringChunk; -import org.apache.poi.hsmf.datatypes.Types; -import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; -import org.apache.poi.hsmf.parsers.POIFSChunkParser; -import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.CodePageUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Reads an Outlook MSG File in and provides hooks into its data structure. - * - * If you want to develop with HSMF, you might find it worth getting - * some of the Microsoft public documentation, such as: - * - * [MS-OXCMSG]: Message and Attachment Object Protocol Specification - */ -public class MAPIMessage extends POIReadOnlyDocument { - /** For logging problems we spot with the file */ - private POILogger logger = POILogFactory.getLogger(MAPIMessage.class); - - private Chunks mainChunks; - private NameIdChunks nameIdChunks; - private RecipientChunks[] recipientChunks; - private AttachmentChunks[] attachmentChunks; - - private boolean returnNullOnMissingChunk = false; - - /** - * Constructor for creating new files. - */ - public MAPIMessage() { - // TODO - make writing possible - super(new NPOIFSFileSystem()); - } - - - /** - * Constructor for reading MSG Files from the file system. - * - * @param filename Name of the file to read - * @throws IOException - */ - public MAPIMessage(String filename) throws IOException { - this(new File(filename)); - } - /** - * Constructor for reading MSG Files from the file system. - * - * @param file The file to read from - * @throws IOException - */ - public MAPIMessage(File file) throws IOException { - this(new NPOIFSFileSystem(file)); - } - - /** - * Constructor for reading MSG Files from an input stream. - * - *

        Note - this will buffer the whole message into memory - * in order to process. For lower memory use, use {@link #MAPIMessage(File)} - * - * @param in The InputStream to buffer then read from - * @throws IOException - */ - public MAPIMessage(InputStream in) throws IOException { - this(new NPOIFSFileSystem(in)); - } - /** - * Constructor for reading MSG Files from a POIFS filesystem - * - * @param fs Open POIFS FileSystem containing the message - * @throws IOException - */ - public MAPIMessage(NPOIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } - /** - * @deprecated Use {@link #MAPIMessage(DirectoryNode)} instead - */ - @Deprecated - public MAPIMessage(DirectoryNode poifsDir, POIFSFileSystem fs) throws IOException { - this(poifsDir); - } - /** - * Constructor for reading MSG Files from a certain - * point within a POIFS filesystem - * @param poifsDir Directory containing the message - * @throws IOException - */ - public MAPIMessage(DirectoryNode poifsDir) throws IOException { - super(poifsDir); - - // Grab all the chunks - ChunkGroup[] chunkGroups = POIFSChunkParser.parse(poifsDir); - - // Grab interesting bits - ArrayList attachments = new ArrayList(); - ArrayList recipients = new ArrayList(); - for(ChunkGroup group : chunkGroups) { - // Should only ever be one of each of these - if(group instanceof Chunks) { - mainChunks = (Chunks)group; - } else if(group instanceof NameIdChunks) { - nameIdChunks = (NameIdChunks)group; - } else if(group instanceof RecipientChunks) { - recipients.add( (RecipientChunks)group ); - } - - // Can be multiple of these - add to list(s) - if(group instanceof AttachmentChunks) { - attachments.add( (AttachmentChunks)group ); - } - } - attachmentChunks = attachments.toArray(new AttachmentChunks[attachments.size()]); - recipientChunks = recipients.toArray(new RecipientChunks[recipients.size()]); - - // Now sort these chunks lists so they're in ascending order, - // rather than in random filesystem order - Arrays.sort(attachmentChunks, new AttachmentChunksSorter()); - Arrays.sort(recipientChunks, new RecipientChunksSorter()); - } - - - /** - * Gets a string value based on the passed chunk. - * @throws ChunkNotFoundException if the chunk isn't there - */ - public String getStringFromChunk(StringChunk chunk) throws ChunkNotFoundException { - if(chunk == null) { - if(returnNullOnMissingChunk) { - return null; - } else { - throw new ChunkNotFoundException(); - } - } - return chunk.getValue(); - } - - - /** - * Gets the plain text body of this Outlook Message - * @return The string representation of the 'text' version of the body, if available. - * @throws ChunkNotFoundException - */ - public String getTextBody() throws ChunkNotFoundException { - return getStringFromChunk(mainChunks.textBodyChunk); - } - - /** - * Gets the html body of this Outlook Message, if this email - * contains a html version. - * @return The string representation of the 'html' version of the body, if available. - * @throws ChunkNotFoundException - */ - public String getHtmlBody() throws ChunkNotFoundException { - if(mainChunks.htmlBodyChunkBinary != null) { - return mainChunks.htmlBodyChunkBinary.getAs7bitString(); - } - return getStringFromChunk(mainChunks.htmlBodyChunkString); - } - @Deprecated - public String getHmtlBody() throws ChunkNotFoundException { - return getHtmlBody(); - } - - /** - * Gets the RTF Rich Message body of this Outlook Message, if this email - * contains a RTF (rich) version. - * @return The string representation of the 'RTF' version of the body, if available. - * @throws ChunkNotFoundException - */ - public String getRtfBody() throws ChunkNotFoundException { - ByteChunk chunk = mainChunks.rtfBodyChunk; - if(chunk == null) { - if(returnNullOnMissingChunk) { - return null; - } else { - throw new ChunkNotFoundException(); - } - } - - try { - MAPIRtfAttribute rtf = new MAPIRtfAttribute( - MAPIProperty.RTF_COMPRESSED, Types.BINARY.getId(), chunk.getValue() - ); - return rtf.getDataString(); - } catch(IOException e) { - throw new RuntimeException("Shouldn't happen", e); - } - } - - /** - * Gets the subject line of the Outlook Message - * @throws ChunkNotFoundException - */ - public String getSubject() throws ChunkNotFoundException { - return getStringFromChunk(mainChunks.subjectChunk); - } - - /** - * Gets the display value of the "FROM" line of the outlook message - * This is not the actual address that was sent from but the formated display of the user name. - * @throws ChunkNotFoundException - */ - public String getDisplayFrom() throws ChunkNotFoundException { - return getStringFromChunk(mainChunks.displayFromChunk); - } - - /** - * Gets the display value of the "TO" line of the outlook message. - * If there are multiple recipients, they will be separated - * by semicolons. - * This is not the actual list of addresses/values that will be - * sent to if you click Reply in the email - those are stored - * in {@link RecipientChunks}. - * @throws ChunkNotFoundException - */ - public String getDisplayTo() throws ChunkNotFoundException { - return getStringFromChunk(mainChunks.displayToChunk); - } - - /** - * Gets the display value of the "CC" line of the outlook message. - * If there are multiple recipients, they will be separated - * by semicolons. - * This is not the actual list of addresses/values that will be - * sent to if you click Reply in the email - those are stored - * in {@link RecipientChunks}. - * @throws ChunkNotFoundException - */ - public String getDisplayCC() throws ChunkNotFoundException { - return getStringFromChunk(mainChunks.displayCCChunk); - } - - /** - * Gets the display value of the "BCC" line of the outlook message. - * If there are multiple recipients, they will be separated - * by semicolons. - * This is not the actual list of addresses/values that will be - * sent to if you click Reply in the email - those are stored - * in {@link RecipientChunks}. - * This will only be present in sent emails, not received ones! - * @throws ChunkNotFoundException - */ - public String getDisplayBCC() throws ChunkNotFoundException { - return getStringFromChunk(mainChunks.displayBCCChunk); - } - - /** - * Returns all the recipients' email address, separated by - * semicolons. Checks all the likely chunks in search of - * the addresses. - */ - public String getRecipientEmailAddress() throws ChunkNotFoundException { - return toSemicolonList(getRecipientEmailAddressList()); - } - /** - * Returns an array of all the recipient's email address, normally - * in TO then CC then BCC order. - * Checks all the likely chunks in search of the addresses. - */ - public String[] getRecipientEmailAddressList() throws ChunkNotFoundException { - if(recipientChunks == null || recipientChunks.length == 0) { - throw new ChunkNotFoundException("No recipients section present"); - } - - String[] emails = new String[recipientChunks.length]; - for(int i=0; iMany messages store their strings as unicode, which is - * nice and easy. Some use one-byte encodings for their - * strings, but don't always store the encoding anywhere - * helpful in the file.

        - *

        This method checks for codepage properties, and failing that - * looks at the headers for the message, and uses these to - * guess the correct encoding for your file.

        - *

        Bug #49441 has more on why this is needed

        - */ - public void guess7BitEncoding() { - // First choice is a codepage property - for (MAPIProperty prop : new MAPIProperty[] { - MAPIProperty.MESSAGE_CODEPAGE, - MAPIProperty.INTERNET_CPID - }) { - List val = mainChunks.getProperties().get(prop); - if (val != null && val.size() > 0) { - int codepage = ((LongPropertyValue)val.get(0)).getValue(); - try { - String encoding = CodePageUtil.codepageToEncoding(codepage, true); - set7BitEncoding(encoding); - return; - } catch(UnsupportedEncodingException e) { - logger.log(POILogger.WARN, "Invalid codepage ID ", codepage, - " set for the message via ", prop, ", ignoring"); - } - } - } - - - // Second choice is a charset on a content type header - try { - String[] headers = getHeaders(); - if(headers != null && headers.length > 0) { - // Look for a content type with a charset - Pattern p = Pattern.compile("Content-Type:.*?charset=[\"']?([^;'\"]+)[\"']?", Pattern.CASE_INSENSITIVE); - - for(String header : headers) { - if(header.startsWith("Content-Type")) { - Matcher m = p.matcher(header); - if(m.matches()) { - // Found it! Tell all the string chunks - String charset = m.group(1); - - if (!charset.equalsIgnoreCase("utf-8")) { - set7BitEncoding(charset); - } - return; - } - } - } - } - } catch(ChunkNotFoundException e) {} - - // Nothing suitable in the headers, try HTML - try { - String html = getHmtlBody(); - if(html != null && html.length() > 0) { - // Look for a content type in the meta headers - Pattern p = Pattern.compile( - " val = mainChunks.getProperties().get(prop); - if (val != null && val.size() > 0) { - return ((TimePropertyValue)val.get(0)).getValue(); - } - } - } - - if(returnNullOnMissingChunk) - return null; - throw new ChunkNotFoundException(); - } - - - /** - * Gets the main, core details chunks - */ - public Chunks getMainChunks() { - return mainChunks; - } - /** - * Gets all the recipient details chunks. - * These will normally be in the order of: - * * TO recipients, in the order returned by {@link #getDisplayTo()} - * * CC recipients, in the order returned by {@link #getDisplayCC()} - * * BCC recipients, in the order returned by {@link #getDisplayBCC()} - */ - public RecipientChunks[] getRecipientDetailsChunks() { - return recipientChunks; - } - /** - * Gets the Name ID chunks, or - * null if there aren't any - */ - public NameIdChunks getNameIdChunks() { - return nameIdChunks; - } - /** - * Gets the message attachments. - */ - public AttachmentChunks[] getAttachmentFiles() { - return attachmentChunks; - } - - - /** - * Will you get a null on a missing chunk, or a - * {@link ChunkNotFoundException} (default is the - * exception). - */ - public boolean isReturnNullOnMissingChunk() { - return returnNullOnMissingChunk; - } - - /** - * Sets whether on asking for a missing chunk, - * you get back null or a {@link ChunkNotFoundException} - * (default is the exception). - */ - public void setReturnNullOnMissingChunk(boolean returnNullOnMissingChunk) { - this.returnNullOnMissingChunk = returnNullOnMissingChunk; - } - - - private String toSemicolonList(String[] l) { - StringBuffer list = new StringBuffer(); - boolean first = true; - - for(String s : l) { - if(s == null) continue; - if(first) { - first = false; - } else { - list.append("; "); - } - list.append(s); - } - - return list.toString(); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java deleted file mode 100644 index 51adf8f74..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hsmf.datatypes; - -import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_DATA; -import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_EXTENSION; -import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_FILENAME; -import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_LONG_FILENAME; -import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_MIME_TAG; -import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_RENDERING; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * Collection of convenience chunks for standard parts of the MSG file attachment. - */ -public class AttachmentChunks implements ChunkGroup { - private static POILogger logger = POILogFactory.getLogger(AttachmentChunks.class); - public static final String PREFIX = "__attach_version1.0_#"; - - public ByteChunk attachData; - public StringChunk attachExtension; - public StringChunk attachFileName; - public StringChunk attachLongFileName; - public StringChunk attachMimeTag; - public DirectoryChunk attachmentDirectory; - - /** - * This is in WMF Format. You'll probably want to pass it - * to Apache Batik to turn it into a SVG that you can - * then display. - */ - public ByteChunk attachRenderingWMF; - - /** - * What the POIFS name of this attachment is. - */ - private String poifsName; - - /** Holds all the chunks that were found. */ - private List allChunks = new ArrayList(); - - - public AttachmentChunks(String poifsName) { - this.poifsName = poifsName; - } - - - /** - * Is this Attachment an embedded MAPI message? - */ - public boolean isEmbeddedMessage() { - return (attachmentDirectory != null); - } - /** - * Returns the embedded MAPI message, if the attachment - * is an embedded message, or null otherwise - */ - public MAPIMessage getEmbeddedMessage() throws IOException { - if (attachmentDirectory != null) { - return attachmentDirectory.getAsEmbededMessage(); - } - return null; - } - - /** - * Returns the embedded object, if the attachment is an - * object based embedding (image, document etc), or null - * if it's an embedded message - */ - public byte[] getEmbeddedAttachmentObject() { - if (attachData != null) { - return attachData.getValue(); - } - return null; - } - - public Chunk[] getAll() { - return allChunks.toArray(new Chunk[allChunks.size()]); - } - public Chunk[] getChunks() { - return getAll(); - } - - public String getPOIFSName() { - return poifsName; - } - - /** - * Called by the parser whenever a chunk is found. - */ - public void record(Chunk chunk) { - // TODO: add further members for other properties like: - // - ATTACH_ADDITIONAL_INFO - // - ATTACH_CONTENT_BASE - // - ATTACH_CONTENT_LOCATION - // - ATTACH_DISPOSITION - // - ATTACH_ENCODING - // - ATTACH_FLAGS - // - ATTACH_LONG_PATHNAME - // - ATTACH_SIZE - final int chunkId = chunk.getChunkId(); - if (chunkId == ATTACH_DATA.id) { - if(chunk instanceof ByteChunk) { - attachData = (ByteChunk)chunk; - } else if(chunk instanceof DirectoryChunk) { - attachmentDirectory = (DirectoryChunk)chunk; - } else { - logger.log(POILogger.ERROR, "Unexpected data chunk of type " + chunk); - } - } else if(chunkId == ATTACH_EXTENSION.id) { - attachExtension = (StringChunk)chunk; - } else if(chunkId == ATTACH_FILENAME.id) { - attachFileName = (StringChunk)chunk; - } else if(chunkId == ATTACH_LONG_FILENAME.id) { - attachLongFileName = (StringChunk)chunk; - } else if(chunkId == ATTACH_MIME_TAG.id) { - attachMimeTag = (StringChunk)chunk; - } else if(chunkId == ATTACH_RENDERING.id) { - attachRenderingWMF = (ByteChunk)chunk; - } - - // And add to the main list - allChunks.add(chunk); - } - - /** - * Used to flag that all the chunks of the attachment - * have now been located. - */ - public void chunksComplete() { - // Currently, we don't need to do anything special once - // all the chunks have been located - } - - - /** - * Orders by the attachment number. - */ - public static class AttachmentChunksSorter implements Comparator, Serializable { - public int compare(AttachmentChunks a, AttachmentChunks b) { - return a.poifsName.compareTo(b.poifsName); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java deleted file mode 100644 index 25a525ab6..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java +++ /dev/null @@ -1,112 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hsmf.datatypes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.poi.hsmf.datatypes.Types.MAPIType; -import org.apache.poi.util.IOUtils; - -/** - * A Chunk that holds binary data, normally unparsed. - * Generally as we know how to make sense of the - * contents, we create a new Chunk class and add - * a special case in the parser for them. - */ - -public class ByteChunk extends Chunk { - private byte[] value; - - /** - * Creates a Byte Chunk. - */ - public ByteChunk(String namePrefix, int chunkId, MAPIType type) { - super(namePrefix, chunkId, type); - } - /** - * Create a Byte Chunk, with the specified - * type. - */ - public ByteChunk(int chunkId, MAPIType type) { - super(chunkId, type); - } - - public void readValue(InputStream value) throws IOException { - this.value = IOUtils.toByteArray(value); - } - - public void writeValue(OutputStream out) throws IOException { - out.write(value); - } - - public byte[] getValue() { - return value; - } - public void setValue(byte[] value) { - this.value = value; - } - - /** - * Returns the data in a debug-friendly string format - */ - public String toString() { - return toDebugFriendlyString(value); - } - - /** - * Formats the byte array in a debug-friendly way, - * showing all of a short array, and the start of a - * longer one. - */ - protected static String toDebugFriendlyString(byte[] value) { - if (value == null) - return "(Null Byte Array)"; - - StringBuffer text = new StringBuffer(); - text.append("Bytes len=").append(value.length); - text.append(" ["); - - int limit = Math.min(value.length, 16); - if (value.length > 16) { - limit = 12; - } - for (int i=0; i 0) - text.append(','); - text.append(value[i]); - } - if (value.length > 16) { - text.append(",...."); - } - text.append("]"); - return text.toString(); - } - - /** - * Returns the data, formatted as a string assuming it - * was a non-unicode string. - * If your data isn't in fact stored as basically - * ASCII, don't expect this to return much of any - * sense.... - * @return the data formatted as a string - */ - public String getAs7bitString() { - return StringChunk.parseAs7BitData(value); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java deleted file mode 100644 index b6ef90d5a..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Locale; - -import org.apache.poi.hsmf.datatypes.Types.MAPIType; - -public abstract class Chunk { - public static final String DEFAULT_NAME_PREFIX = "__substg1.0_"; - - protected int chunkId; - protected MAPIType type; - protected String namePrefix; - - protected Chunk(String namePrefix, int chunkId, MAPIType type) { - this.namePrefix = namePrefix; - this.chunkId = chunkId; - this.type = type; - } - protected Chunk(int chunkId, MAPIType type) { - this(DEFAULT_NAME_PREFIX, chunkId, type); - } - - /** - * Gets the id of this chunk - */ - public int getChunkId() { - return this.chunkId; - } - - /** - * Gets the numeric type of this chunk. - */ - public MAPIType getType() { - return this.type; - } - - /** - * Creates a string to use to identify this chunk in the POI file system object. - */ - public String getEntryName() { - String type = this.type.asFileEnding(); - - String chunkId = Integer.toHexString(this.chunkId); - while(chunkId.length() < 4) chunkId = "0" + chunkId; - - return this.namePrefix + chunkId.toUpperCase(Locale.ROOT) - + type.toUpperCase(Locale.ROOT); - } - - /** - * Writes the value of this chunk back out again. - */ - public abstract void writeValue(OutputStream out) throws IOException; - - /** - * Reads the value of this chunk using an InputStream - */ - public abstract void readValue(InputStream value) throws IOException; -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java deleted file mode 100644 index 36c723bdf..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - - -/** - * A variable length {@link PropertyValue} that is - * backed by a {@link Chunk} - * TODO Provide a way to link these up with the chunks - */ -public class ChunkBasedPropertyValue extends PropertyValue { - public ChunkBasedPropertyValue(MAPIProperty property, long flags, byte[] offsetData) { - super(property, flags, offsetData); - } - - @Override - public Chunk getValue() { - // TODO Decode the value into an offset - // TODO Look up the chunk based on that - return null; - } - - /** - * Stores the offset of the chunk as the property value - */ - public void setValue(Chunk chunk) { - // TODO - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java deleted file mode 100644 index 0bd7dc0af..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - -/** - * A group of chunks, that are at the same point in the - * file structure. - */ -public interface ChunkGroup { - /** - * Returns the chunks that make up the group. - * Should certainly contain all the interesting Chunks, - * but needn't always contain all of the Chunks. - */ - public Chunk[] getChunks(); - - /** - * Called by the parser whenever a chunk is found. - */ - public void record(Chunk chunk); - - /** - * Called by the parser when all chunks have been found. - */ - public void chunksComplete(); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroupWithProperties.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroupWithProperties.java deleted file mode 100644 index 3d99ea345..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroupWithProperties.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - -import java.util.List; -import java.util.Map; - -/** - * A group of chunks which is indexable by {@link MAPIProperty} - * entries. - */ -public interface ChunkGroupWithProperties extends ChunkGroup { - /** - * Returns all the Properties contained in the Chunk, along - * with their Values. - * Normally, each property will have one value, sometimes - * none, and rarely multiple (normally for Unknown etc). - * For fixed sized properties, the value can be fetched - * straight from the {@link PropertyValue}. For variable - * sized properties, you'll need to go via the chunk. - */ - public Map> getProperties(); -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java deleted file mode 100644 index 19165a013..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java +++ /dev/null @@ -1,194 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - - -/** - * Collection of convenience chunks for standard parts of the MSG file. - * - * Not all of these will be present in any given file. - * - * A partial list is available at: - * http://msdn.microsoft.com/en-us/library/ms526356%28v=exchg.10%29.aspx - * - * TODO Deprecate the public Chunks in favour of Property Lookups - */ -public final class Chunks implements ChunkGroupWithProperties { - private static POILogger logger = POILogFactory.getLogger(Chunks.class); - - /** - * Holds all the chunks that were found, indexed by their MAPIProperty. - * Normally a property will have zero chunks (fixed sized) or one chunk - * (variable size), but in some cases (eg Unknown) you may get more. - */ - private Map> allChunks = new HashMap>(); - - /** Type of message that the MSG represents (ie. IPM.Note) */ - public StringChunk messageClass; - /** BODY Chunk, for plain/text messages */ - public StringChunk textBodyChunk; - /** BODY Html Chunk, for html messages */ - public StringChunk htmlBodyChunkString; - public ByteChunk htmlBodyChunkBinary; - /** BODY Rtf Chunk, for Rtf (Rich) messages */ - public ByteChunk rtfBodyChunk; - /** Subject link chunk, in plain/text */ - public StringChunk subjectChunk; - /** - * Value that is in the TO field (not actually the addresses as they are - * stored in recip directory nodes - */ - public StringChunk displayToChunk; - /** Value that is in the FROM field */ - public StringChunk displayFromChunk; - /** value that shows in the CC field */ - public StringChunk displayCCChunk; - /** Value that shows in the BCC field */ - public StringChunk displayBCCChunk; - /** Sort of like the subject line, but without the RE: and FWD: parts. */ - public StringChunk conversationTopic; - /** Type of server that the message originated from (SMTP, etc). */ - public StringChunk sentByServerType; - /** The email headers */ - public StringChunk messageHeaders; - /** TODO */ - public MessageSubmissionChunk submissionChunk; - /** TODO */ - public StringChunk emailFromChunk; - /** The message ID */ - public StringChunk messageId; - /** The message properties */ - private MessagePropertiesChunk messageProperties; - - public Map> getProperties() { - if (messageProperties != null) { - return messageProperties.getProperties(); - } - else return Collections.emptyMap(); - } - public Map getRawProperties() { - if (messageProperties != null) { - return messageProperties.getRawProperties(); - } - else return Collections.emptyMap(); - } - - public Map> getAll() { - return allChunks; - } - public Chunk[] getChunks() { - ArrayList chunks = new ArrayList(allChunks.size()); - for (List c : allChunks.values()) { - chunks.addAll(c); - } - return chunks.toArray(new Chunk[chunks.size()]); - } - - /** - * Called by the parser whenever a chunk is found. - */ - public void record(Chunk chunk) { - // Work out what MAPIProperty this corresponds to - MAPIProperty prop = MAPIProperty.get(chunk.getChunkId()); - - // Assign it for easy lookup, as best we can - if(prop == MAPIProperty.MESSAGE_CLASS) { - messageClass = (StringChunk)chunk; - } - else if(prop == MAPIProperty.INTERNET_MESSAGE_ID) { - messageId = (StringChunk)chunk; - } - else if(prop == MAPIProperty.MESSAGE_SUBMISSION_ID) { - // TODO - parse - submissionChunk = (MessageSubmissionChunk)chunk; - } - else if(prop == MAPIProperty.RECEIVED_BY_ADDRTYPE) { - sentByServerType = (StringChunk)chunk; - } - else if(prop == MAPIProperty.TRANSPORT_MESSAGE_HEADERS) { - messageHeaders = (StringChunk)chunk; - } - - else if(prop == MAPIProperty.CONVERSATION_TOPIC) { - conversationTopic = (StringChunk)chunk; - } - else if(prop == MAPIProperty.SUBJECT) { - subjectChunk = (StringChunk)chunk; - } - else if(prop == MAPIProperty.ORIGINAL_SUBJECT) { - // TODO - } - - else if(prop == MAPIProperty.DISPLAY_TO) { - displayToChunk = (StringChunk)chunk; - } - else if(prop == MAPIProperty.DISPLAY_CC) { - displayCCChunk = (StringChunk)chunk; - } - else if(prop == MAPIProperty.DISPLAY_BCC) { - displayBCCChunk = (StringChunk)chunk; - } - - else if(prop == MAPIProperty.SENDER_EMAIL_ADDRESS) { - emailFromChunk = (StringChunk)chunk; - } - else if(prop == MAPIProperty.SENDER_NAME) { - displayFromChunk = (StringChunk)chunk; - } - else if(prop == MAPIProperty.BODY) { - textBodyChunk = (StringChunk)chunk; - } - else if(prop == MAPIProperty.BODY_HTML) { - if(chunk instanceof StringChunk) { - htmlBodyChunkString = (StringChunk)chunk; - } - if(chunk instanceof ByteChunk) { - htmlBodyChunkBinary = (ByteChunk)chunk; - } - } - else if(prop == MAPIProperty.RTF_COMPRESSED) { - rtfBodyChunk = (ByteChunk)chunk; - } - else if(chunk instanceof MessagePropertiesChunk) { - messageProperties = (MessagePropertiesChunk) chunk; - } - - // And add to the main list - if (allChunks.get(prop) == null) { - allChunks.put(prop, new ArrayList()); - } - allChunks.get(prop).add(chunk); - } - - public void chunksComplete() { - if (messageProperties != null) { - messageProperties.matchVariableSizedPropertiesToChunks(); - } else { - logger.log(POILogger.WARN, "Message didn't contain a root list of properties!"); - } - } -} \ No newline at end of file diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java deleted file mode 100644 index 5365a6325..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hsmf.datatypes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.hsmf.datatypes.Types.MAPIType; -import org.apache.poi.poifs.filesystem.DirectoryNode; - -/** - * A Chunk that is just a placeholder in the - * MAPIMessage directory structure, which - * contains children. - * This is most commonly used with nested - * MAPIMessages - */ -public class DirectoryChunk extends Chunk { - private DirectoryNode dir; - - public DirectoryChunk(DirectoryNode dir, String namePrefix, int chunkId, MAPIType type) { - super(namePrefix, chunkId, type); - this.dir = dir; - } - - /** - * Returns the directory entry for this chunk. - * You can then use standard POIFS methods to - * enumerate the entries in it. - */ - public DirectoryNode getDirectory() { - return dir; - } - - /** - * Treats the directory as an embeded MAPIMessage - * (it normally is one), and returns a MAPIMessage - * object to process it with. - */ - public MAPIMessage getAsEmbededMessage() throws IOException { - return new MAPIMessage(dir); - } - - @Override - public void readValue(InputStream value) { - // DirectoryChunks have 0 byte contents - } - - @Override - public void writeValue(OutputStream out) { - // DirectoryChunks have 0 byte contents - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java deleted file mode 100644 index ae473983f..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java +++ /dev/null @@ -1,1106 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - -import static org.apache.poi.hsmf.datatypes.Types.ASCII_STRING; -import static org.apache.poi.hsmf.datatypes.Types.BINARY; -import static org.apache.poi.hsmf.datatypes.Types.BOOLEAN; -import static org.apache.poi.hsmf.datatypes.Types.CLS_ID; -import static org.apache.poi.hsmf.datatypes.Types.DIRECTORY; -import static org.apache.poi.hsmf.datatypes.Types.LONG; -import static org.apache.poi.hsmf.datatypes.Types.LONG_LONG; -import static org.apache.poi.hsmf.datatypes.Types.SHORT; -import static org.apache.poi.hsmf.datatypes.Types.TIME; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import org.apache.poi.hsmf.datatypes.Types.MAPIType; - -/** - * Holds the list of MAPI Attributes, and allows lookup - * by friendly name, ID and MAPI Property Name. - * - * These are taken from the following MSDN resources: - * https://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertyid(v=exchg.150).aspx - * http://msdn.microsoft.com/en-us/library/ms526356%28v=exchg.10%29.aspx - */ -public class MAPIProperty { - private static Map attributes = new HashMap(); - - public static final MAPIProperty AB_DEFAULT_DIR = - new MAPIProperty(0x3d06, BINARY, "AbDefaultDir", "PR_AB_DEFAULT_DIR"); - public static final MAPIProperty AB_DEFAULT_PAB = - new MAPIProperty(0x3d07, BINARY, "AbDefaultPab", "PR_AB_DEFAULT_PAB"); - public static final MAPIProperty AB_PROVIDER_ID = - new MAPIProperty(0x3615, BINARY, "AbProviderId", "PR_AB_PROVIDER_ID"); - public static final MAPIProperty AB_PROVIDERS = - new MAPIProperty(0x3d01, BINARY, "AbProviders", "PR_AB_PROVIDERS"); - public static final MAPIProperty AB_SEARCH_PATH = - new MAPIProperty(0x3d05, Types.createCustom(4354), "AbSearchPath", "PR_AB_SEARCH_PATH"); - public static final MAPIProperty AB_SEARCH_PATH_UPDATE = - new MAPIProperty(0x3d11, BINARY, "AbSearchPathUpdate", "PR_AB_SEARCH_PATH_UPDATE"); - public static final MAPIProperty ACCESS = - new MAPIProperty(0xff4, LONG, "Access", "PR_ACCESS"); - public static final MAPIProperty ACCESS_LEVEL = - new MAPIProperty(0xff7, LONG, "AccessLevel", "PR_ACCESS_LEVEL"); - public static final MAPIProperty ACCOUNT = - new MAPIProperty(0x3a00, ASCII_STRING, "Account", "PR_ACCOUNT"); - public static final MAPIProperty ADDRTYPE = - new MAPIProperty(0x3002, ASCII_STRING, "Addrtype", "PR_ADDRTYPE"); - public static final MAPIProperty ALTERNATE_RECIPIENT = - new MAPIProperty(0x3a01, BINARY, "AlternateRecipient", "PR_ALTERNATE_RECIPIENT"); - public static final MAPIProperty ALTERNATE_RECIPIENT_ALLOWED = - new MAPIProperty(2, BOOLEAN, "AlternateRecipientAllowed", "PR_ALTERNATE_RECIPIENT_ALLOWED"); - public static final MAPIProperty ANR = - new MAPIProperty(0x360c, ASCII_STRING, "Anr", "PR_ANR"); - public static final MAPIProperty ASSISTANT = - new MAPIProperty(0x3a30, ASCII_STRING, "Assistant", "PR_ASSISTANT"); - public static final MAPIProperty ASSISTANT_TELEPHONE_NUMBER = - new MAPIProperty(0x3a2e, ASCII_STRING, "AssistantTelephoneNumber", "PR_ASSISTANT_TELEPHONE_NUMBER"); - public static final MAPIProperty ASSOC_CONTENT_COUNT = - new MAPIProperty(0x3617, LONG, "AssocContentCount", "PR_ASSOC_CONTENT_COUNT"); - public static final MAPIProperty ATTACH_ADDITIONAL_INFO = - new MAPIProperty(0x370f, BINARY, "AttachAdditionalInfo", "PR_ATTACH_ADDITIONAL_INFO"); - public static final MAPIProperty ATTACH_CONTENT_BASE = - new MAPIProperty(0x3711, Types.UNKNOWN, "AttachContentBase", "PR_ATTACH_CONTENT_BASE"); - public static final MAPIProperty ATTACH_CONTENT_ID = - new MAPIProperty(0x3712, Types.UNKNOWN, "AttachContentId", "PR_ATTACH_CONTENT_ID"); - public static final MAPIProperty ATTACH_CONTENT_LOCATION = - new MAPIProperty(0x3713, Types.UNKNOWN, "AttachContentLocation", "PR_ATTACH_CONTENT_LOCATION"); - public static final MAPIProperty ATTACH_DATA = - new MAPIProperty(0x3701, BINARY, "AttachData", "PR_ATTACH_DATA_OBJ"); - public static final MAPIProperty ATTACH_DISPOSITION = - new MAPIProperty(0x3716, Types.UNKNOWN, "AttachDisposition", "PR_ATTACH_DISPOSITION"); - public static final MAPIProperty ATTACH_ENCODING = - new MAPIProperty(0x3702, BINARY, "AttachEncoding", "PR_ATTACH_ENCODING"); - public static final MAPIProperty ATTACH_EXTENSION = - new MAPIProperty(0x3703, ASCII_STRING, "AttachExtension", "PR_ATTACH_EXTENSION"); - public static final MAPIProperty ATTACH_FILENAME = - new MAPIProperty(0x3704, ASCII_STRING, "AttachFilename", "PR_ATTACH_FILENAME"); - public static final MAPIProperty ATTACH_FLAGS = - new MAPIProperty(0x3714, Types.UNKNOWN, "AttachFlags", "PR_ATTACH_FLAGS"); - public static final MAPIProperty ATTACH_LONG_FILENAME = - new MAPIProperty(0x3707, ASCII_STRING, "AttachLongFilename", "PR_ATTACH_LONG_FILENAME"); - public static final MAPIProperty ATTACH_LONG_PATHNAME = - new MAPIProperty(0x370d, ASCII_STRING, "AttachLongPathname", "PR_ATTACH_LONG_PATHNAME"); - public static final MAPIProperty ATTACH_METHOD = - new MAPIProperty(0x3705, LONG, "AttachMethod", "PR_ATTACH_METHOD"); - public static final MAPIProperty ATTACH_MIME_SEQUENCE = - new MAPIProperty(0x3710, Types.UNKNOWN, "AttachMimeSequence", "PR_ATTACH_MIME_SEQUENCE"); - public static final MAPIProperty ATTACH_MIME_TAG = - new MAPIProperty(0x370e, ASCII_STRING, "AttachMimeTag", "PR_ATTACH_MIME_TAG"); - public static final MAPIProperty ATTACH_NETSCAPE_MAC_INFO = - new MAPIProperty(0x3715, Types.UNKNOWN, "AttachNetscapeMacInfo", "PR_ATTACH_NETSCAPE_MAC_INFO"); - public static final MAPIProperty ATTACH_NUM = - new MAPIProperty(0xe21, LONG, "AttachNum", "PR_ATTACH_NUM"); - public static final MAPIProperty ATTACH_PATHNAME = - new MAPIProperty(0x3708, ASCII_STRING, "AttachPathname", "PR_ATTACH_PATHNAME"); - public static final MAPIProperty ATTACH_RENDERING = - new MAPIProperty(0x3709, BINARY, "AttachRendering", "PR_ATTACH_RENDERING"); - public static final MAPIProperty ATTACH_SIZE = - new MAPIProperty(0xe20, LONG, "AttachSize", "PR_ATTACH_SIZE"); - public static final MAPIProperty ATTACH_TAG = - new MAPIProperty(0x370a, BINARY, "AttachTag", "PR_ATTACH_TAG"); - public static final MAPIProperty ATTACH_TRANSPORT_NAME = - new MAPIProperty(0x370c, ASCII_STRING, "AttachTransportName", "PR_ATTACH_TRANSPORT_NAME"); - public static final MAPIProperty ATTACHMENT_X400_PARAMETERS = - new MAPIProperty(0x3700, BINARY, "AttachmentX400Parameters", "PR_ATTACHMENT_X400_PARAMETERS"); - public static final MAPIProperty AUTHORIZING_USERS = - new MAPIProperty(3, BINARY, "AuthorizingUsers", "PR_AUTHORIZING_USERS"); - public static final MAPIProperty AUTO_FORWARD_COMMENT = - new MAPIProperty(4, ASCII_STRING, "AutoForwardComment", "PR_AUTO_FORWARD_COMMENT"); - public static final MAPIProperty AUTO_FORWARDED = - new MAPIProperty(5, BOOLEAN, "AutoForwarded", "PR_AUTO_FORWARDED"); - public static final MAPIProperty AUTO_RESPONSE_SUPPRESS = - new MAPIProperty(0x3fdf, Types.UNKNOWN, "AutoResponseSuppress", "PR_AUTO_RESPONSE_SUPPRESS"); - public static final MAPIProperty BIRTHDAY = - new MAPIProperty(0x3a42, TIME, "Birthday", "PR_BIRTHDAY"); - public static final MAPIProperty BODY = - new MAPIProperty(0x1000, ASCII_STRING, "Body", "PR_BODY"); - public static final MAPIProperty BODY_CONTENT_ID = - new MAPIProperty(0x1015, Types.UNKNOWN, "BodyContentId", "PR_BODY_CONTENT_ID"); - public static final MAPIProperty BODY_CONTENT_LOCATION = - new MAPIProperty(0x1014, Types.UNKNOWN, "BodyContentLocation", "PR_BODY_CONTENT_LOCATION"); - public static final MAPIProperty BODY_CRC = - new MAPIProperty(0xe1c, LONG, "BodyCrc", "PR_BODY_CRC"); - public static final MAPIProperty BODY_HTML = - new MAPIProperty(0x1013, Types.UNKNOWN, "BodyHtml", "data"); - public static final MAPIProperty BUSINESS_FAX_NUMBER = - new MAPIProperty(0x3a24, ASCII_STRING, "BusinessFaxNumber", "PR_BUSINESS_FAX_NUMBER"); - public static final MAPIProperty BUSINESS_HOME_PAGE = - new MAPIProperty(0x3a51, ASCII_STRING, "BusinessHomePage", "PR_BUSINESS_HOME_PAGE"); - public static final MAPIProperty CALLBACK_TELEPHONE_NUMBER = - new MAPIProperty(0x3a02, ASCII_STRING, "CallbackTelephoneNumber", "PR_CALLBACK_TELEPHONE_NUMBER"); - public static final MAPIProperty CAR_TELEPHONE_NUMBER = - new MAPIProperty(0x3a1e, ASCII_STRING, "CarTelephoneNumber", "PR_CAR_TELEPHONE_NUMBER"); - public static final MAPIProperty CHILDRENS_NAMES = - new MAPIProperty(0x3a58, Types.createCustom(4126), "ChildrensNames", "PR_CHILDRENS_NAMES"); - public static final MAPIProperty CLIENT_SUBMIT_TIME = - new MAPIProperty(0x39, TIME, "ClientSubmitTime", "PR_CLIENT_SUBMIT_TIME"); - public static final MAPIProperty COMMENT = - new MAPIProperty(0x3004, ASCII_STRING, "Comment", "PR_COMMENT"); - public static final MAPIProperty COMMON_VIEWS_ENTRY_ID = - new MAPIProperty(0x35e6, BINARY, "CommonViewsEntryId", "PR_COMMON_VIEWS_ENTRYID"); - public static final MAPIProperty COMPANY_MAIN_PHONE_NUMBER = - new MAPIProperty(0x3a57, ASCII_STRING, "CompanyMainPhoneNumber", "PR_COMPANY_MAIN_PHONE_NUMBER"); - public static final MAPIProperty COMPANY_NAME = - new MAPIProperty(0x3a16, ASCII_STRING, "CompanyName", "PR_COMPANY_NAME"); - public static final MAPIProperty COMPUTER_NETWORK_NAME = - new MAPIProperty(0x3a49, ASCII_STRING, "ComputerNetworkName", "PR_COMPUTER_NETWORK_NAME"); - public static final MAPIProperty CONTACT_ADDRTYPES = - new MAPIProperty(0x3a54, Types.createCustom(4126), "ContactAddrtypes", "PR_CONTACT_ADDRTYPES"); - public static final MAPIProperty CONTACT_DEFAULT_ADDRESS_INDEX = - new MAPIProperty(0x3a55, LONG, "ContactDefaultAddressIndex", "PR_CONTACT_DEFAULT_ADDRESS_INDEX"); - public static final MAPIProperty CONTACT_EMAIL_ADDRESSES = - new MAPIProperty(0x3a56, Types.createCustom(4126), "ContactEmailAddresses", "PR_CONTACT_EMAIL_ADDRESSES"); - public static final MAPIProperty CONTACT_ENTRY_IDS = - new MAPIProperty(0x3a53, Types.createCustom(4354), "ContactEntryIds", "PR_CONTACT_ENTRYIDS"); - public static final MAPIProperty CONTACT_VERSION = - new MAPIProperty(0x3a52, CLS_ID, "ContactVersion", "PR_CONTACT_VERSION"); - public static final MAPIProperty CONTAINER_CLASS = - new MAPIProperty(0x3613, ASCII_STRING, "ContainerClass", "PR_CONTAINER_CLASS"); - public static final MAPIProperty CONTAINER_CONTENTS = - new MAPIProperty(0x360f, DIRECTORY, "ContainerContents", "PR_CONTAINER_CONTENTS"); - public static final MAPIProperty CONTAINER_FLAGS = - new MAPIProperty(0x3600, LONG, "ContainerFlags", "PR_CONTAINER_FLAGS"); - public static final MAPIProperty CONTAINER_HIERARCHY = - new MAPIProperty(0x360e, DIRECTORY, "ContainerHierarchy", "PR_CONTAINER_HIERARCHY"); - public static final MAPIProperty CONTAINER_MODIFY_VERSION = - new MAPIProperty(0x3614, LONG_LONG, "ContainerModifyVersion", "PR_CONTAINER_MODIFY_VERSION"); - public static final MAPIProperty CONTENT_CONFIDENTIALITY_ALGORITHM_ID = - new MAPIProperty(6, BINARY, "ContentConfidentialityAlgorithmId", "PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID"); - public static final MAPIProperty CONTENT_CORRELATOR = - new MAPIProperty(7, BINARY, "ContentCorrelator", "PR_CONTENT_CORRELATOR"); - public static final MAPIProperty CONTENT_COUNT = - new MAPIProperty(0x3602, LONG, "ContentCount", "PR_CONTENT_COUNT"); - public static final MAPIProperty CONTENT_IDENTIFIER = - new MAPIProperty(8, ASCII_STRING, "ContentIdentifier", "PR_CONTENT_IDENTIFIER"); - public static final MAPIProperty CONTENT_INTEGRITY_CHECK = - new MAPIProperty(0xc00, BINARY, "ContentIntegrityCheck", "PR_CONTENT_INTEGRITY_CHECK"); - public static final MAPIProperty CONTENT_LENGTH = - new MAPIProperty(9, LONG, "ContentLength", "PR_CONTENT_LENGTH"); - public static final MAPIProperty CONTENT_RETURN_REQUESTED = - new MAPIProperty(10, BOOLEAN, "ContentReturnRequested", "PR_CONTENT_RETURN_REQUESTED"); - public static final MAPIProperty CONTENT_UNREAD = - new MAPIProperty(0x3603, LONG, "ContentUnread", "PR_CONTENT_UNREAD"); - public static final MAPIProperty CONTENTS_SORT_ORDER = - new MAPIProperty(0x360d, Types.createCustom(4099), "ContentsSortOrder", "PR_CONTENTS_SORT_ORDER"); - public static final MAPIProperty CONTROL_FLAGS = - new MAPIProperty(0x3f00, LONG, "ControlFlags", "PR_CONTROL_FLAGS"); - public static final MAPIProperty CONTROL_ID = - new MAPIProperty(0x3f07, BINARY, "ControlId", "PR_CONTROL_ID"); - public static final MAPIProperty CONTROL_STRUCTURE = - new MAPIProperty(0x3f01, BINARY, "ControlStructure", "PR_CONTROL_STRUCTURE"); - public static final MAPIProperty CONTROL_TYPE = - new MAPIProperty(0x3f02, LONG, "ControlType", "PR_CONTROL_TYPE"); - public static final MAPIProperty CONVERSATION_INDEX = - new MAPIProperty(0x71, BINARY, "ConversationIndex", "PR_CONVERSATION_INDEX"); - public static final MAPIProperty CONVERSATION_KEY = - new MAPIProperty(11, BINARY, "ConversationKey", "PR_CONVERSATION_KEY"); - public static final MAPIProperty CONVERSATION_TOPIC = - new MAPIProperty(0x70, ASCII_STRING, "ConversationTopic", "PR_CONVERSATION_TOPIC"); - public static final MAPIProperty CONVERSION_EITS = - new MAPIProperty(12, BINARY, "ConversionEits", "PR_CONVERSION_EITS"); - public static final MAPIProperty CONVERSION_PROHIBITED = - new MAPIProperty(0x3a03, BOOLEAN, "ConversionProhibited", "PR_CONVERSION_PROHIBITED"); - public static final MAPIProperty CONVERSION_WITH_LOSS_PROHIBITED = - new MAPIProperty(13, BOOLEAN, "ConversionWithLossProhibited", "PR_CONVERSION_WITH_LOSS_PROHIBITED"); - public static final MAPIProperty CONVERTED_EITS = - new MAPIProperty(14, BINARY, "ConvertedEits", "PR_CONVERTED_EITS"); - public static final MAPIProperty CORRELATE = - new MAPIProperty(0xe0c, BOOLEAN, "Correlate", "PR_CORRELATE"); - public static final MAPIProperty CORRELATE_MTSID = - new MAPIProperty(0xe0d, BINARY, "CorrelateMtsid", "PR_CORRELATE_MTSID"); - public static final MAPIProperty COUNTRY = - new MAPIProperty(0x3a26, ASCII_STRING, "Country", "PR_COUNTRY"); - public static final MAPIProperty CREATE_TEMPLATES = - new MAPIProperty(0x3604, DIRECTORY, "CreateTemplates", "PR_CREATE_TEMPLATES"); - public static final MAPIProperty CREATION_TIME = - new MAPIProperty(0x3007, TIME, "CreationTime", "PR_CREATION_TIME"); - public static final MAPIProperty CREATION_VERSION = - new MAPIProperty(0xe19, LONG_LONG, "CreationVersion", "PR_CREATION_VERSION"); - public static final MAPIProperty CURRENT_VERSION = - new MAPIProperty(0xe00, LONG_LONG, "CurrentVersion", "PR_CURRENT_VERSION"); - public static final MAPIProperty CUSTOMER_ID = - new MAPIProperty(0x3a4a, ASCII_STRING, "CustomerId", "PR_CUSTOMER_ID"); - public static final MAPIProperty DEF_CREATE_DL = - new MAPIProperty(0x3611, BINARY, "DefCreateDl", "PR_DEF_CREATE_DL"); - public static final MAPIProperty DEF_CREATE_MAILUSER = - new MAPIProperty(0x3612, BINARY, "DefCreateMailuser", "PR_DEF_CREATE_MAILUSER"); - public static final MAPIProperty DEFAULT_PROFILE = - new MAPIProperty(0x3d04, BOOLEAN, "DefaultProfile", "PR_DEFAULT_PROFILE"); - public static final MAPIProperty DEFAULT_STORE = - new MAPIProperty(0x3400, BOOLEAN, "DefaultStore", "PR_DEFAULT_STORE"); - public static final MAPIProperty DEFAULT_VIEW_ENTRY_ID = - new MAPIProperty(0x3616, BINARY, "DefaultViewEntryId", "PR_DEFAULT_VIEW_ENTRYID"); - public static final MAPIProperty DEFERRED_DELIVERY_TIME = - new MAPIProperty(15, TIME, "DeferredDeliveryTime", "PR_DEFERRED_DELIVERY_TIME"); - public static final MAPIProperty DELEGATION = - new MAPIProperty(0x7e, BINARY, "Delegation", "PR_DELEGATION"); - public static final MAPIProperty DELETE_AFTER_SUBMIT = - new MAPIProperty(0xe01, BOOLEAN, "DeleteAfterSubmit", "PR_DELETE_AFTER_SUBMIT"); - public static final MAPIProperty DELIVER_TIME = - new MAPIProperty(0x10, TIME, "DeliverTime", "PR_DELIVER_TIME"); - public static final MAPIProperty DELIVERY_POINT = - new MAPIProperty(0xc07, LONG, "DeliveryPoint", "PR_DELIVERY_POINT"); - public static final MAPIProperty DELTAX = - new MAPIProperty(0x3f03, LONG, "Deltax", "PR_DELTAX"); - public static final MAPIProperty DELTAY = - new MAPIProperty(0x3f04, LONG, "Deltay", "PR_DELTAY"); - public static final MAPIProperty DEPARTMENT_NAME = - new MAPIProperty(0x3a18, ASCII_STRING, "DepartmentName", "PR_DEPARTMENT_NAME"); - public static final MAPIProperty DEPTH = - new MAPIProperty(0x3005, LONG, "Depth", "PR_DEPTH"); - public static final MAPIProperty DETAILS_TABLE = - new MAPIProperty(0x3605, DIRECTORY, "DetailsTable", "PR_DETAILS_TABLE"); - public static final MAPIProperty DISC_VAL = - new MAPIProperty(0x4a, BOOLEAN, "DiscVal", "PR_DISC_VAL"); - public static final MAPIProperty DISCARD_REASON = - new MAPIProperty(0x11, LONG, "DiscardReason", "PR_DISCARD_REASON"); - public static final MAPIProperty DISCLOSE_RECIPIENTS = - new MAPIProperty(0x3a04, BOOLEAN, "DiscloseRecipients", "PR_DISCLOSE_RECIPIENTS"); - public static final MAPIProperty DISCLOSURE_OF_RECIPIENTS = - new MAPIProperty(0x12, BOOLEAN, "DisclosureOfRecipients", "PR_DISCLOSURE_OF_RECIPIENTS"); - public static final MAPIProperty DISCRETE_VALUES = - new MAPIProperty(0xe0e, BOOLEAN, "DiscreteValues", "PR_DISCRETE_VALUES"); - public static final MAPIProperty DISPLAY_BCC = - new MAPIProperty(0xe02, ASCII_STRING, "DisplayBcc", "PR_DISPLAY_BCC"); - public static final MAPIProperty DISPLAY_CC = - new MAPIProperty(0xe03, ASCII_STRING, "DisplayCc", "PR_DISPLAY_CC"); - public static final MAPIProperty DISPLAY_NAME = - new MAPIProperty(0x3001, ASCII_STRING, "DisplayName", "PR_DISPLAY_NAME"); - public static final MAPIProperty DISPLAY_NAME_PREFIX = - new MAPIProperty(0x3a45, ASCII_STRING, "DisplayNamePrefix", "PR_DISPLAY_NAME_PREFIX"); - public static final MAPIProperty DISPLAY_TO = - new MAPIProperty(0xe04, ASCII_STRING, "DisplayTo", "PR_DISPLAY_TO"); - public static final MAPIProperty DISPLAY_TYPE = - new MAPIProperty(0x3900, LONG, "DisplayType", "PR_DISPLAY_TYPE"); - public static final MAPIProperty DL_EXPANSION_HISTORY = - new MAPIProperty(0x13, BINARY, "DlExpansionHistory", "PR_DL_EXPANSION_HISTORY"); - public static final MAPIProperty DL_EXPANSION_PROHIBITED = - new MAPIProperty(20, BOOLEAN, "DlExpansionProhibited", "PR_DL_EXPANSION_PROHIBITED"); - public static final MAPIProperty EMAIL_ADDRESS = - new MAPIProperty(0x3003, ASCII_STRING, "EmailAddress", "PR_EMAIL_ADDRESS"); - public static final MAPIProperty END_DATE = - new MAPIProperty(0x61, TIME, "EndDate", "PR_END_DATE"); - public static final MAPIProperty ENTRY_ID = - new MAPIProperty(0xfff, BINARY, "EntryId", "PR_ENTRYID"); - public static final MAPIProperty EXPAND_BEGIN_TIME = - new MAPIProperty(0x3618, Types.UNKNOWN, "ExpandBeginTime", "PR_EXPAND_BEGIN_TIME"); - public static final MAPIProperty EXPAND_END_TIME = - new MAPIProperty(0x3619, Types.UNKNOWN, "ExpandEndTime", "PR_EXPAND_END_TIME"); - public static final MAPIProperty EXPANDED_BEGIN_TIME = - new MAPIProperty(0x361a, Types.UNKNOWN, "ExpandedBeginTime", "PR_EXPANDED_BEGIN_TIME"); - public static final MAPIProperty EXPANDED_END_TIME = - new MAPIProperty(0x361b, Types.UNKNOWN, "ExpandedEndTime", "PR_EXPANDED_END_TIME"); - public static final MAPIProperty EXPIRY_TIME = - new MAPIProperty(0x15, TIME, "ExpiryTime", "PR_EXPIRY_TIME"); - public static final MAPIProperty EXPLICIT_CONVERSION = - new MAPIProperty(0xc01, LONG, "ExplicitConversion", "PR_EXPLICIT_CONVERSION"); - public static final MAPIProperty FILTERING_HOOKS = - new MAPIProperty(0x3d08, BINARY, "FilteringHooks", "PR_FILTERING_HOOKS"); - public static final MAPIProperty FINDER_ENTRY_ID = - new MAPIProperty(0x35e7, BINARY, "FinderEntryId", "PR_FINDER_ENTRYID"); - public static final MAPIProperty FOLDER_ASSOCIATED_CONTENTS = - new MAPIProperty(0x3610, DIRECTORY, "FolderAssociatedContents", "PR_FOLDER_ASSOCIATED_CONTENTS"); - public static final MAPIProperty FOLDER_TYPE = - new MAPIProperty(0x3601, LONG, "FolderType", "PR_FOLDER_TYPE"); - public static final MAPIProperty FORM_CATEGORY = - new MAPIProperty(0x3304, ASCII_STRING, "FormCategory", "PR_FORM_CATEGORY"); - public static final MAPIProperty FORM_CATEGORY_SUB = - new MAPIProperty(0x3305, ASCII_STRING, "FormCategorySub", "PR_FORM_CATEGORY_SUB"); - public static final MAPIProperty FORM_CLSID = - new MAPIProperty(0x3302, CLS_ID, "FormClsid", "PR_FORM_ClsID"); - public static final MAPIProperty FORM_CONTACT_NAME = - new MAPIProperty(0x3303, ASCII_STRING, "FormContactName", "PR_FORM_CONTACT_NAME"); - public static final MAPIProperty FORM_DESIGNER_GUID = - new MAPIProperty(0x3309, CLS_ID, "FormDesignerGuid", "PR_FORM_DESIGNER_GUID"); - public static final MAPIProperty FORM_DESIGNER_NAME = - new MAPIProperty(0x3308, ASCII_STRING, "FormDesignerName", "PR_FORM_DESIGNER_NAME"); - public static final MAPIProperty FORM_HIDDEN = - new MAPIProperty(0x3307, BOOLEAN, "FormHidden", "PR_FORM_HIDDEN"); - public static final MAPIProperty FORM_HOST_MAP = - new MAPIProperty(0x3306, Types.createCustom(4099), "FormHostMap", "PR_FORM_HOST_MAP"); - public static final MAPIProperty FORM_MESSAGE_BEHAVIOR = - new MAPIProperty(0x330a, LONG, "FormMessageBehavior", "PR_FORM_MESSAGE_BEHAVIOR"); - public static final MAPIProperty FORM_VERSION = - new MAPIProperty(0x3301, ASCII_STRING, "FormVersion", "PR_FORM_VERSION"); - public static final MAPIProperty FTP_SITE = - new MAPIProperty(0x3a4c, ASCII_STRING, "FtpSite", "PR_FTP_SITE"); - public static final MAPIProperty GENDER = - new MAPIProperty(0x3a4d, SHORT, "Gender", "PR_GENDER"); - public static final MAPIProperty GENERATION = - new MAPIProperty(0x3a05, ASCII_STRING, "Generation", "PR_GENERATION"); - public static final MAPIProperty GIVEN_NAME = - new MAPIProperty(0x3a06, ASCII_STRING, "GivenName", "PR_GIVEN_NAME"); - public static final MAPIProperty GOVERNMENT_ID_NUMBER = - new MAPIProperty(0x3a07, ASCII_STRING, "GovernmentIdNumber", "PR_GOVERNMENT_ID_NUMBER"); - public static final MAPIProperty HASATTACH = - new MAPIProperty(0xe1b, BOOLEAN, "Hasattach", "PR_HASATTACH"); - public static final MAPIProperty HEADER_FOLDER_ENTRY_ID = - new MAPIProperty(0x3e0a, BINARY, "HeaderFolderEntryId", "PR_HEADER_FOLDER_ENTRYID"); - public static final MAPIProperty HOBBIES = - new MAPIProperty(0x3a43, ASCII_STRING, "Hobbies", "PR_HOBBIES"); - public static final MAPIProperty HOME2_TELEPHONE_NUMBER = - new MAPIProperty(0x3a2f, ASCII_STRING, "Home2TelephoneNumber", "PR_HOME2_TELEPHONE_NUMBER"); - public static final MAPIProperty HOME_ADDRESS_CITY = - new MAPIProperty(0x3a59, ASCII_STRING, "HomeAddressCity", "PR_HOME_ADDRESS_CITY"); - public static final MAPIProperty HOME_ADDRESS_COUNTRY = - new MAPIProperty(0x3a5a, ASCII_STRING, "HomeAddressCountry", "PR_HOME_ADDRESS_COUNTRY"); - public static final MAPIProperty HOME_ADDRESS_POST_OFFICE_BOX = - new MAPIProperty(0x3a5e, ASCII_STRING, "HomeAddressPostOfficeBox", "PR_HOME_ADDRESS_POST_OFFICE_BOX"); - public static final MAPIProperty HOME_ADDRESS_POSTAL_CODE = - new MAPIProperty(0x3a5b, ASCII_STRING, "HomeAddressPostalCode", "PR_HOME_ADDRESS_POSTAL_CODE"); - public static final MAPIProperty HOME_ADDRESS_STATE_OR_PROVINCE = - new MAPIProperty(0x3a5c, ASCII_STRING, "HomeAddressStateOrProvince", "PR_HOME_ADDRESS_STATE_OR_PROVINCE"); - public static final MAPIProperty HOME_ADDRESS_STREET = - new MAPIProperty(0x3a5d, ASCII_STRING, "HomeAddressStreet", "PR_HOME_ADDRESS_STREET"); - public static final MAPIProperty HOME_FAX_NUMBER = - new MAPIProperty(0x3a25, ASCII_STRING, "HomeFaxNumber", "PR_HOME_FAX_NUMBER"); - public static final MAPIProperty HOME_TELEPHONE_NUMBER = - new MAPIProperty(0x3a09, ASCII_STRING, "HomeTelephoneNumber", "PR_HOME_TELEPHONE_NUMBER"); - public static final MAPIProperty INET_MAIL_OVERRIDE_CHARSET = - new MAPIProperty(0x5903, Types.UNKNOWN, "INetMailOverrideCharset", "Charset"); - public static final MAPIProperty INET_MAIL_OVERRIDE_FORMAT = - new MAPIProperty(0x5902, Types.UNKNOWN, "INetMailOverrideFormat", "Format"); - public static final MAPIProperty ICON = - new MAPIProperty(0xffd, BINARY, "Icon", "PR_ICON"); - public static final MAPIProperty IDENTITY_DISPLAY = - new MAPIProperty(0x3e00, ASCII_STRING, "IdentityDisplay", "PR_IDENTITY_DISPLAY"); - public static final MAPIProperty IDENTITY_ENTRY_ID = - new MAPIProperty(0x3e01, BINARY, "IdentityEntryId", "PR_IDENTITY_ENTRYID"); - public static final MAPIProperty IDENTITY_SEARCH_KEY = - new MAPIProperty(0x3e05, BINARY, "IdentitySearchKey", "PR_IDENTITY_SEARCH_KEY"); - public static final MAPIProperty IMPLICIT_CONVERSION_PROHIBITED = - new MAPIProperty(0x16, BOOLEAN, "ImplicitConversionProhibited", "PR_IMPLICIT_CONVERSION_PROHIBITED"); - public static final MAPIProperty IMPORTANCE = - new MAPIProperty(0x17, LONG, "Importance", "PR_IMPORTANCE"); - public static final MAPIProperty IN_REPLY_TO_ID = - new MAPIProperty(0x1042, Types.UNKNOWN, "InReplyToId", "PR_IN_REPLY_TO_ID"); - public static final MAPIProperty INCOMPLETE_COPY = - new MAPIProperty(0x35, BOOLEAN, "IncompleteCopy", "PR_INCOMPLETE_COPY"); - public static final MAPIProperty INITIAL_DETAILS_PANE = - new MAPIProperty(0x3f08, LONG, "InitialDetailsPane", "PR_INITIAL_DETAILS_PANE"); - public static final MAPIProperty INITIALS = - new MAPIProperty(0x3a0a, ASCII_STRING, "Initials", "PR_INITIALS"); - public static final MAPIProperty INSTANCE_KEY = - new MAPIProperty(0xff6, BINARY, "InstanceKey", "PR_INSTANCE_KEY"); - public static final MAPIProperty INTERNET_APPROVED = - new MAPIProperty(0x1030, ASCII_STRING, "InternetApproved", "PR_INTERNET_APPROVED"); - public static final MAPIProperty INTERNET_ARTICLE_NUMBER = - new MAPIProperty(0xe23, LONG, "InternetArticleNumber", "PR_INTERNET_ARTICLE_NUMBER"); - public static final MAPIProperty INTERNET_CPID = - new MAPIProperty(0x3fde, Types.LONG, "InternetCPID", "PR_INTERNET_CPID"); - public static final MAPIProperty INTERNET_CONTROL = - new MAPIProperty(0x1031, ASCII_STRING, "InternetControl", "PR_INTERNET_CONTROL"); - public static final MAPIProperty INTERNET_DISTRIBUTION = - new MAPIProperty(0x1032, ASCII_STRING, "InternetDistribution", "PR_INTERNET_DISTRIBUTION"); - public static final MAPIProperty INTERNET_FOLLOWUP_TO = - new MAPIProperty(0x1033, ASCII_STRING, "InternetFollowupTo", "PR_INTERNET_FOLLOWUP_TO"); - public static final MAPIProperty INTERNET_LINES = - new MAPIProperty(0x1034, LONG, "InternetLines", "PR_INTERNET_LINES"); - public static final MAPIProperty INTERNET_MESSAGE_ID = - new MAPIProperty(0x1035, ASCII_STRING, "InternetMessageId", "PR_INTERNET_MESSAGE_ID"); - public static final MAPIProperty INTERNET_NEWSGROUPS = - new MAPIProperty(0x1036, ASCII_STRING, "InternetNewsgroups", "PR_INTERNET_NEWSGROUPS"); - public static final MAPIProperty INTERNET_NNTP_PATH = - new MAPIProperty(0x1038, ASCII_STRING, "InternetNntpPath", "PR_INTERNET_NNTP_PATH"); - public static final MAPIProperty INTERNET_ORGANIZATION = - new MAPIProperty(0x1037, ASCII_STRING, "InternetOrganization", "PR_INTERNET_ORGANIZATION"); - public static final MAPIProperty INTERNET_PRECEDENCE = - new MAPIProperty(0x1041, ASCII_STRING, "InternetPrecedence", "PR_INTERNET_PRECEDENCE"); - public static final MAPIProperty INTERNET_REFERENCES = - new MAPIProperty(0x1039, ASCII_STRING, "InternetReferences", "PR_INTERNET_REFERENCES"); - public static final MAPIProperty IPM_ID = - new MAPIProperty(0x18, BINARY, "IpmId", "PR_IPM_ID"); - public static final MAPIProperty IPM_OUTBOX_ENTRY_ID = - new MAPIProperty(0x35e2, BINARY, "IpmOutboxEntryId", "PR_IPM_OUTBOX_ENTRYID"); - public static final MAPIProperty IPM_OUTBOX_SEARCH_KEY = - new MAPIProperty(0x3411, BINARY, "IpmOutboxSearchKey", "PR_IPM_OUTBOX_SEARCH_KEY"); - public static final MAPIProperty IPM_RETURN_REQUESTED = - new MAPIProperty(0xc02, BOOLEAN, "IpmReturnRequested", "PR_IPM_RETURN_REQUESTED"); - public static final MAPIProperty IPM_SENTMAIL_ENTRY_ID = - new MAPIProperty(0x35e4, BINARY, "IpmSentmailEntryId", "PR_IPM_SENTMAIL_ENTRYID"); - public static final MAPIProperty IPM_SENTMAIL_SEARCH_KEY = - new MAPIProperty(0x3413, BINARY, "IpmSentmailSearchKey", "PR_IPM_SENTMAIL_SEARCH_KEY"); - public static final MAPIProperty IPM_SUBTREE_ENTRY_ID = - new MAPIProperty(0x35e0, BINARY, "IpmSubtreeEntryId", "PR_IPM_SUBTREE_ENTRYID"); - public static final MAPIProperty IPM_SUBTREE_SEARCH_KEY = - new MAPIProperty(0x3410, BINARY, "IpmSubtreeSearchKey", "PR_IPM_SUBTREE_SEARCH_KEY"); - public static final MAPIProperty IPM_WASTEBASKET_ENTRY_ID = - new MAPIProperty(0x35e3, BINARY, "IpmWastebasketEntryId", "PR_IPM_WASTEBASKET_ENTRYID"); - public static final MAPIProperty IPM_WASTEBASKET_SEARCH_KEY = - new MAPIProperty(0x3412, BINARY, "IpmWastebasketSearchKey", "PR_IPM_WASTEBASKET_SEARCH_KEY"); - public static final MAPIProperty ISDN_NUMBER = - new MAPIProperty(0x3a2d, ASCII_STRING, "IsdnNumber", "PR_ISDN_NUMBER"); - public static final MAPIProperty KEYWORD = - new MAPIProperty(0x3a0b, ASCII_STRING, "Keyword", "PR_KEYWORD"); - public static final MAPIProperty LANGUAGE = - new MAPIProperty(0x3a0c, ASCII_STRING, "Language", "PR_LANGUAGE"); - public static final MAPIProperty LANGUAGES = - new MAPIProperty(0x2f, ASCII_STRING, "Languages", "PR_LANGUAGES"); - public static final MAPIProperty LAST_MODIFICATION_TIME = - new MAPIProperty(0x3008, TIME, "LastModificationTime", "PR_LAST_MODIFICATION_TIME"); - public static final MAPIProperty LATEST_DELIVERY_TIME = - new MAPIProperty(0x19, TIME, "LatestDeliveryTime", "PR_LATEST_DELIVERY_TIME"); - public static final MAPIProperty LIST_HELP = - new MAPIProperty(0x1043, Types.UNKNOWN, "ListHelp", "PR_LIST_HELP"); - public static final MAPIProperty LIST_SUBSCRIBE = - new MAPIProperty(0x1044, Types.UNKNOWN, "ListSubscribe", "PR_LIST_SUBSCRIBE"); - public static final MAPIProperty LIST_UNSUBSCRIBE = - new MAPIProperty(0x1045, Types.UNKNOWN, "ListUnsubscribe", "PR_LIST_UNSUBSCRIBE"); - public static final MAPIProperty LOCALITY = - new MAPIProperty(0x3a27, ASCII_STRING, "Locality", "PR_LOCALITY"); - public static final MAPIProperty LOCALLY_DELIVERED = - new MAPIProperty(0x6745, Types.UNKNOWN, "LocallyDelivered", "ptagLocallyDelivered"); - public static final MAPIProperty LOCATION = - new MAPIProperty(0x3a0d, ASCII_STRING, "Location", "PR_LOCATION"); - public static final MAPIProperty LOCK_BRANCH_ID = - new MAPIProperty(0x3800, Types.UNKNOWN, "LockBranchId", "PR_LOCK_BRANCH_ID"); - public static final MAPIProperty LOCK_DEPTH = - new MAPIProperty(0x3808, Types.UNKNOWN, "LockDepth", "PR_LOCK_DEPTH"); - public static final MAPIProperty LOCK_ENLISTMENT_CONTEXT = - new MAPIProperty(0x3804, Types.UNKNOWN, "LockEnlistmentContext", "PR_LOCK_ENLISTMENT_CONTEXT"); - public static final MAPIProperty LOCK_EXPIRY_TIME = - new MAPIProperty(0x380a, Types.UNKNOWN, "LockExpiryTime", "PR_LOCK_EXPIRY_TIME"); - public static final MAPIProperty LOCK_PERSISTENT = - new MAPIProperty(0x3807, Types.UNKNOWN, "LockPersistent", "PR_LOCK_PERSISTENT"); - public static final MAPIProperty LOCK_RESOURCE_DID = - new MAPIProperty(0x3802, Types.UNKNOWN, "LockResourceDid", "PR_LOCK_RESOURCE_DID"); - public static final MAPIProperty LOCK_RESOURCE_FID = - new MAPIProperty(0x3801, Types.UNKNOWN, "LockResourceFid", "PR_LOCK_RESOURCE_FID"); - public static final MAPIProperty LOCK_RESOURCE_MID = - new MAPIProperty(0x3803, Types.UNKNOWN, "LockResourceMid", "PR_LOCK_RESOURCE_MID"); - public static final MAPIProperty LOCK_SCOPE = - new MAPIProperty(0x3806, Types.UNKNOWN, "LockScope", "PR_LOCK_SCOPE"); - public static final MAPIProperty LOCK_TIMEOUT = - new MAPIProperty(0x3809, Types.UNKNOWN, "LockTimeout", "PR_LOCK_TIMEOUT"); - public static final MAPIProperty LOCK_TYPE = - new MAPIProperty(0x3805, Types.UNKNOWN, "LockType", "PR_LOCK_TYPE"); - public static final MAPIProperty MAIL_PERMISSION = - new MAPIProperty(0x3a0e, BOOLEAN, "MailPermission", "PR_MAIL_PERMISSION"); - public static final MAPIProperty MANAGER_NAME = - new MAPIProperty(0x3a4e, ASCII_STRING, "ManagerName", "PR_MANAGER_NAME"); - public static final MAPIProperty MAPPING_SIGNATURE = - new MAPIProperty(0xff8, BINARY, "MappingSignature", "PR_MAPPING_SIGNATURE"); - public static final MAPIProperty MDB_PROVIDER = - new MAPIProperty(0x3414, BINARY, "MdbProvider", "PR_MDB_PROVIDER"); - public static final MAPIProperty MESSAGE_ATTACHMENTS = - new MAPIProperty(0xe13, DIRECTORY, "MessageAttachments", "PR_MESSAGE_ATTACHMENTS"); - public static final MAPIProperty MESSAGE_CC_ME = - new MAPIProperty(0x58, BOOLEAN, "MessageCcMe", "PR_MESSAGE_CC_ME"); - public static final MAPIProperty MESSAGE_CLASS = - new MAPIProperty(0x1a, ASCII_STRING, "MessageClass", "PR_MESSAGE_CLASS"); - public static final MAPIProperty MESSAGE_CODEPAGE = - new MAPIProperty(0x3ffd, Types.LONG, "MessageCodepage", "PR_MESSAGE_CODEPAGE"); - public static final MAPIProperty MESSAGE_DELIVERY_ID = - new MAPIProperty(0x1b, BINARY, "MessageDeliveryId", "PR_MESSAGE_DELIVERY_ID"); - public static final MAPIProperty MESSAGE_DELIVERY_TIME = - new MAPIProperty(0xe06, TIME, "MessageDeliveryTime", "PR_MESSAGE_DELIVERY_TIME"); - public static final MAPIProperty MESSAGE_DOWNLOAD_TIME = - new MAPIProperty(0xe18, LONG, "MessageDownloadTime", "PR_MESSAGE_DOWNLOAD_TIME"); - public static final MAPIProperty MESSAGE_FLAGS = - new MAPIProperty(0xe07, LONG, "MessageFlags", "PR_MESSAGE_FLAGS"); - public static final MAPIProperty MESSAGE_RECIP_ME = - new MAPIProperty(0x59, BOOLEAN, "MessageRecipMe", "PR_MESSAGE_RECIP_ME"); - public static final MAPIProperty MESSAGE_RECIPIENTS = - new MAPIProperty(0xe12, DIRECTORY, "MessageRecipients", "PR_MESSAGE_RECIPIENTS"); - public static final MAPIProperty MESSAGE_SECURITY_LABEL = - new MAPIProperty(30, BINARY, "MessageSecurityLabel", "PR_MESSAGE_SECURITY_LABEL"); - public static final MAPIProperty MESSAGE_SIZE = - new MAPIProperty(0xe08, LONG, "MessageSize", "PR_MESSAGE_SIZE"); - public static final MAPIProperty MESSAGE_SUBMISSION_ID = - new MAPIProperty(0x47, BINARY, "MessageSubmissionId", "PR_MESSAGE_SUBMISSION_ID"); - public static final MAPIProperty MESSAGE_TO_ME = - new MAPIProperty(0x57, BOOLEAN, "MessageToMe", "PR_MESSAGE_TO_ME"); - public static final MAPIProperty MESSAGE_TOKEN = - new MAPIProperty(0xc03, BINARY, "MessageToken", "PR_MESSAGE_TOKEN"); - public static final MAPIProperty MHS_COMMON_NAME = - new MAPIProperty(0x3a0f, ASCII_STRING, "MhsCommonName", "PR_MHS_COMMON_NAME"); - public static final MAPIProperty MIDDLE_NAME = - new MAPIProperty(0x3a44, ASCII_STRING, "MiddleName", "PR_MIDDLE_NAME"); - public static final MAPIProperty MINI_ICON = - new MAPIProperty(0xffc, BINARY, "MiniIcon", "PR_MINI_ICON"); - public static final MAPIProperty MOBILE_TELEPHONE_NUMBER = - new MAPIProperty(0x3a1c, ASCII_STRING, "MobileTelephoneNumber", "PR_MOBILE_TELEPHONE_NUMBER"); - public static final MAPIProperty MODIFY_VERSION = - new MAPIProperty(0xe1a, LONG_LONG, "ModifyVersion", "PR_MODIFY_VERSION"); - public static final MAPIProperty MSG_STATUS = - new MAPIProperty(0xe17, LONG, "MsgStatus", "PR_MSG_STATUS"); - public static final MAPIProperty NDR_DIAG_CODE = - new MAPIProperty(0xc05, LONG, "NdrDiagCode", "PR_NDR_DIAG_CODE"); - public static final MAPIProperty NDR_REASON_CODE = - new MAPIProperty(0xc04, LONG, "NdrReasonCode", "PR_NDR_REASON_CODE"); - public static final MAPIProperty NDR_STATUS_CODE = - new MAPIProperty(0xc20, Types.UNKNOWN, "NdrStatusCode", "PR_NDR_STATUS_CODE"); - public static final MAPIProperty NEWSGROUP_NAME = - new MAPIProperty(0xe24, ASCII_STRING, "NewsgroupName", "PR_NEWSGROUP_NAME"); - public static final MAPIProperty NICKNAME = - new MAPIProperty(0x3a4f, ASCII_STRING, "Nickname", "PR_NICKNAME"); - public static final MAPIProperty NNTP_XREF = - new MAPIProperty(0x1040, ASCII_STRING, "NntpXref", "PR_NNTP_XREF"); - public static final MAPIProperty NON_RECEIPT_NOTIFICATION_REQUESTED = - new MAPIProperty(0xc06, BOOLEAN, "NonReceiptNotificationRequested", "PR_NON_RECEIPT_NOTIFICATION_REQUESTED"); - public static final MAPIProperty NON_RECEIPT_REASON = - new MAPIProperty(0x3e, LONG, "NonReceiptReason", "PR_NON_RECEIPT_REASON"); - public static final MAPIProperty NORMALIZED_SUBJECT = - new MAPIProperty(0xe1d, ASCII_STRING, "NormalizedSubject", "PR_NORMALIZED_SUBJECT"); - public static final MAPIProperty NT_SECURITY_DESCRIPTOR = - new MAPIProperty(0xe27, Types.UNKNOWN, "NtSecurityDescriptor", "PR_NT_SECURITY_DESCRIPTOR"); - public static final MAPIProperty NULL = - new MAPIProperty(1, LONG, "Null", "PR_NULL"); - public static final MAPIProperty OBJECT_TYPE = - new MAPIProperty(0xffe, LONG, "ObjectType", "PR_Object_TYPE"); - public static final MAPIProperty OBSOLETED_IPMS = - new MAPIProperty(0x1f, BINARY, "ObsoletedIpms", "PR_OBSOLETED_IPMS"); - public static final MAPIProperty OFFICE2_TELEPHONE_NUMBER = - new MAPIProperty(0x3a1b, ASCII_STRING, "Office2TelephoneNumber", "PR_OFFICE2_TELEPHONE_NUMBER"); - public static final MAPIProperty OFFICE_LOCATION = - new MAPIProperty(0x3a19, ASCII_STRING, "OfficeLocation", "PR_OFFICE_LOCATION"); - public static final MAPIProperty OFFICE_TELEPHONE_NUMBER = - new MAPIProperty(0x3a08, ASCII_STRING, "OfficeTelephoneNumber", "PR_OFFICE_TELEPHONE_NUMBER"); - public static final MAPIProperty OOF_REPLY_TYPE = - new MAPIProperty(0x4080, Types.UNKNOWN, "OofReplyType", "PR_OOF_REPLY_TYPE"); - public static final MAPIProperty ORGANIZATIONAL_ID_NUMBER = - new MAPIProperty(0x3a10, ASCII_STRING, "OrganizationalIdNumber", "PR_ORGANIZATIONAL_ID_NUMBER"); - public static final MAPIProperty ORIG_ENTRY_ID = - new MAPIProperty(0x300f, Types.UNKNOWN, "OrigEntryId", "PR_ORIG_ENTRYID"); - public static final MAPIProperty ORIG_MESSAGE_CLASS = - new MAPIProperty(0x4b, ASCII_STRING, "OrigMessageClass", "PR_ORIG_MESSAGE_CLASS"); - public static final MAPIProperty ORIGIN_CHECK = - new MAPIProperty(0x27, BINARY, "OriginCheck", "PR_ORIGIN_CHECK"); - public static final MAPIProperty ORIGINAL_AUTHOR_ADDRTYPE = - new MAPIProperty(0x79, ASCII_STRING, "OriginalAuthorAddrtype", "PR_ORIGINAL_AUTHOR_ADDRTYPE"); - public static final MAPIProperty ORIGINAL_AUTHOR_EMAIL_ADDRESS = - new MAPIProperty(0x7a, ASCII_STRING, "OriginalAuthorEmailAddress", "PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS"); - public static final MAPIProperty ORIGINAL_AUTHOR_ENTRY_ID = - new MAPIProperty(0x4c, BINARY, "OriginalAuthorEntryId", "PR_ORIGINAL_AUTHOR_ENTRYID"); - public static final MAPIProperty ORIGINAL_AUTHOR_NAME = - new MAPIProperty(0x4d, ASCII_STRING, "OriginalAuthorName", "PR_ORIGINAL_AUTHOR_NAME"); - public static final MAPIProperty ORIGINAL_AUTHOR_SEARCH_KEY = - new MAPIProperty(0x56, BINARY, "OriginalAuthorSearchKey", "PR_ORIGINAL_AUTHOR_SEARCH_KEY"); - public static final MAPIProperty ORIGINAL_DELIVERY_TIME = - new MAPIProperty(0x55, TIME, "OriginalDeliveryTime", "PR_ORIGINAL_DELIVERY_TIME"); - public static final MAPIProperty ORIGINAL_DISPLAY_BCC = - new MAPIProperty(0x72, ASCII_STRING, "OriginalDisplayBcc", "PR_ORIGINAL_DISPLAY_BCC"); - public static final MAPIProperty ORIGINAL_DISPLAY_CC = - new MAPIProperty(0x73, ASCII_STRING, "OriginalDisplayCc", "PR_ORIGINAL_DISPLAY_CC"); - public static final MAPIProperty ORIGINAL_DISPLAY_NAME = - new MAPIProperty(0x3a13, ASCII_STRING, "OriginalDisplayName", "PR_ORIGINAL_DISPLAY_NAME"); - public static final MAPIProperty ORIGINAL_DISPLAY_TO = - new MAPIProperty(0x74, ASCII_STRING, "OriginalDisplayTo", "PR_ORIGINAL_DISPLAY_TO"); - public static final MAPIProperty ORIGINAL_EITS = - new MAPIProperty(0x21, BINARY, "OriginalEits", "PR_ORIGINAL_EITS"); - public static final MAPIProperty ORIGINAL_ENTRY_ID = - new MAPIProperty(0x3a12, BINARY, "OriginalEntryId", "PR_ORIGINAL_ENTRYID"); - public static final MAPIProperty ORIGINAL_SEARCH_KEY = - new MAPIProperty(0x3a14, BINARY, "OriginalSearchKey", "PR_ORIGINAL_SEARCH_KEY"); - public static final MAPIProperty ORIGINAL_SENDER_ADDRTYPE = - new MAPIProperty(0x66, ASCII_STRING, "OriginalSenderAddrtype", "PR_ORIGINAL_SENDER_ADDRTYPE"); - public static final MAPIProperty ORIGINAL_SENDER_EMAIL_ADDRESS = - new MAPIProperty(0x67, ASCII_STRING, "OriginalSenderEmailAddress", "PR_ORIGINAL_SENDER_EMAIL_ADDRESS"); - public static final MAPIProperty ORIGINAL_SENDER_ENTRY_ID = - new MAPIProperty(0x5b, BINARY, "OriginalSenderEntryId", "PR_ORIGINAL_SENDER_ENTRYID"); - public static final MAPIProperty ORIGINAL_SENDER_NAME = - new MAPIProperty(90, ASCII_STRING, "OriginalSenderName", "PR_ORIGINAL_SENDER_NAME"); - public static final MAPIProperty ORIGINAL_SENDER_SEARCH_KEY = - new MAPIProperty(0x5c, BINARY, "OriginalSenderSearchKey", "PR_ORIGINAL_SENDER_SEARCH_KEY"); - public static final MAPIProperty ORIGINAL_SENSITIVITY = - new MAPIProperty(0x2e, LONG, "OriginalSensitivity", "PR_ORIGINAL_SENSITIVITY"); - public static final MAPIProperty ORIGINAL_SENT_REPRESENTING_ADDRTYPE = - new MAPIProperty(0x68, ASCII_STRING, "OriginalSentRepresentingAddrtype", "PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE"); - public static final MAPIProperty ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS = - new MAPIProperty(0x69, ASCII_STRING, "OriginalSentRepresentingEmailAddress", "PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS"); - public static final MAPIProperty ORIGINAL_SENT_REPRESENTING_ENTRY_ID = - new MAPIProperty(0x5e, BINARY, "OriginalSentRepresentingEntryId", "PR_ORIGINAL_SENT_REPRESENTING_ENTRYID"); - public static final MAPIProperty ORIGINAL_SENT_REPRESENTING_NAME = - new MAPIProperty(0x5d, ASCII_STRING, "OriginalSentRepresentingName", "PR_ORIGINAL_SENT_REPRESENTING_NAME"); - public static final MAPIProperty ORIGINAL_SENT_REPRESENTING_SEARCH_KEY = - new MAPIProperty(0x5f, BINARY, "OriginalSentRepresentingSearchKey", "PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY"); - public static final MAPIProperty ORIGINAL_SUBJECT = - new MAPIProperty(0x49, ASCII_STRING, "OriginalSubject", "PR_ORIGINAL_SUBJECT"); - public static final MAPIProperty ORIGINAL_SUBMIT_TIME = - new MAPIProperty(0x4e, TIME, "OriginalSubmitTime", "PR_ORIGINAL_SUBMIT_TIME"); - public static final MAPIProperty ORIGINALLY_INTENDED_RECIP_ADDRTYPE = - new MAPIProperty(0x7b, ASCII_STRING, "OriginallyIntendedRecipAddrtype", "PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE"); - public static final MAPIProperty ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS = - new MAPIProperty(0x7c, ASCII_STRING, "OriginallyIntendedRecipEmailAddress", "PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS"); - public static final MAPIProperty ORIGINALLY_INTENDED_RECIP_ENTRY_ID = - new MAPIProperty(0x1012, BINARY, "OriginallyIntendedRecipEntryId", "PR_ORIGINALLY_INTENDED_RECIP_ENTRYID"); - public static final MAPIProperty ORIGINALLY_INTENDED_RECIPIENT_NAME = - new MAPIProperty(0x20, BINARY, "OriginallyIntendedRecipientName", "PR_ORIGINALLY_INTENDED_RECIPIENT_NAME"); - public static final MAPIProperty ORIGINATING_MTA_CERTIFICATE = - new MAPIProperty(0xe25, BINARY, "OriginatingMtaCertificate", "PR_ORIGINATING_MTA_CERTIFICATE"); - public static final MAPIProperty ORIGINATOR_AND_DL_EXPANSION_HISTORY = - new MAPIProperty(0x1002, BINARY, "OriginatorAndDlExpansionHistory", "PR_ORIGINATOR_AND_DL_EXPANSION_HISTORY"); - public static final MAPIProperty ORIGINATOR_CERTIFICATE = - new MAPIProperty(0x22, BINARY, "OriginatorCertificate", "PR_ORIGINATOR_CERTIFICATE"); - public static final MAPIProperty ORIGINATOR_DELIVERY_REPORT_REQUESTED = - new MAPIProperty(0x23, BOOLEAN, "OriginatorDeliveryReportRequested", "PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED"); - public static final MAPIProperty ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED = - new MAPIProperty(0xc08, BOOLEAN, "OriginatorNonDeliveryReportRequested", "PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED"); - public static final MAPIProperty ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT = - new MAPIProperty(0xc09, BINARY, "OriginatorRequestedAlternateRecipient", "PR_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT"); - public static final MAPIProperty ORIGINATOR_RETURN_ADDRESS = - new MAPIProperty(0x24, BINARY, "OriginatorReturnAddress", "PR_ORIGINATOR_RETURN_ADDRESS"); - public static final MAPIProperty OTHER_ADDRESS_CITY = - new MAPIProperty(0x3a5f, ASCII_STRING, "OtherAddressCity", "PR_OTHER_ADDRESS_CITY"); - public static final MAPIProperty OTHER_ADDRESS_COUNTRY = - new MAPIProperty(0x3a60, ASCII_STRING, "OtherAddressCountry", "PR_OTHER_ADDRESS_COUNTRY"); - public static final MAPIProperty OTHER_ADDRESS_POST_OFFICE_BOX = - new MAPIProperty(0x3a64, ASCII_STRING, "OtherAddressPostOfficeBox", "PR_OTHER_ADDRESS_POST_OFFICE_BOX"); - public static final MAPIProperty OTHER_ADDRESS_POSTAL_CODE = - new MAPIProperty(0x3a61, ASCII_STRING, "OtherAddressPostalCode", "PR_OTHER_ADDRESS_POSTAL_CODE"); - public static final MAPIProperty OTHER_ADDRESS_STATE_OR_PROVINCE = - new MAPIProperty(0x3a62, ASCII_STRING, "OtherAddressStateOrProvince", "PR_OTHER_ADDRESS_STATE_OR_PROVINCE"); - public static final MAPIProperty OTHER_ADDRESS_STREET = - new MAPIProperty(0x3a63, ASCII_STRING, "OtherAddressStreet", "PR_OTHER_ADDRESS_STREET"); - public static final MAPIProperty OTHER_TELEPHONE_NUMBER = - new MAPIProperty(0x3a1f, ASCII_STRING, "OtherTelephoneNumber", "PR_OTHER_TELEPHONE_NUMBER"); - public static final MAPIProperty OWN_STORE_ENTRY_ID = - new MAPIProperty(0x3e06, BINARY, "OwnStoreEntryId", "PR_OWN_STORE_ENTRYID"); - public static final MAPIProperty OWNER_APPT_ID = - new MAPIProperty(0x62, LONG, "OwnerApptId", "PR_OWNER_APPT_ID"); - public static final MAPIProperty PAGER_TELEPHONE_NUMBER = - new MAPIProperty(0x3a21, ASCII_STRING, "PagerTelephoneNumber", "PR_PAGER_TELEPHONE_NUMBER"); - public static final MAPIProperty PARENT_DISPLAY = - new MAPIProperty(0xe05, ASCII_STRING, "ParentDisplay", "PR_PARENT_DISPLAY"); - public static final MAPIProperty PARENT_ENTRY_ID = - new MAPIProperty(0xe09, BINARY, "ParentEntryId", "PR_PARENT_ENTRYID"); - public static final MAPIProperty PARENT_KEY = - new MAPIProperty(0x25, BINARY, "ParentKey", "PR_PARENT_KEY"); - public static final MAPIProperty PERSONAL_HOME_PAGE = - new MAPIProperty(0x3a50, ASCII_STRING, "PersonalHomePage", "PR_PERSONAL_HOME_PAGE"); - public static final MAPIProperty PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY = - new MAPIProperty(0xc0a, BOOLEAN, "PhysicalDeliveryBureauFaxDelivery", "PR_PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY"); - public static final MAPIProperty PHYSICAL_DELIVERY_MODE = - new MAPIProperty(0xc0b, LONG, "PhysicalDeliveryMode", "PR_PHYSICAL_DELIVERY_MODE"); - public static final MAPIProperty PHYSICAL_DELIVERY_REPORT_REQUEST = - new MAPIProperty(0xc0c, LONG, "PhysicalDeliveryReportRequest", "PR_PHYSICAL_DELIVERY_REPORT_REQUEST"); - public static final MAPIProperty PHYSICAL_FORWARDING_ADDRESS = - new MAPIProperty(0xc0d, BINARY, "PhysicalForwardingAddress", "PR_PHYSICAL_FORWARDING_ADDRESS"); - public static final MAPIProperty PHYSICAL_FORWARDING_ADDRESS_REQUESTED = - new MAPIProperty(0xc0e, BOOLEAN, "PhysicalForwardingAddressRequested", "PR_PHYSICAL_FORWARDING_ADDRESS_REQUESTED"); - public static final MAPIProperty PHYSICAL_FORWARDING_PROHIBITED = - new MAPIProperty(0xc0f, BOOLEAN, "PhysicalForwardingProhibited", "PR_PHYSICAL_FORWARDING_PROHIBITED"); - public static final MAPIProperty PHYSICAL_RENDITION_ATTRIBUTES = - new MAPIProperty(0xc10, BINARY, "PhysicalRenditionAttributes", "PR_PHYSICAL_RENDITION_ATTRIBUTES"); - public static final MAPIProperty POST_FOLDER_ENTRIES = - new MAPIProperty(0x103b, BINARY, "PostFolderEntries", "PR_POST_FOLDER_ENTRIES"); - public static final MAPIProperty POST_FOLDER_NAMES = - new MAPIProperty(0x103c, ASCII_STRING, "PostFolderNames", "PR_POST_FOLDER_NAMES"); - public static final MAPIProperty POST_OFFICE_BOX = - new MAPIProperty(0x3a2b, ASCII_STRING, "PostOfficeBox", "PR_POST_OFFICE_BOX"); - public static final MAPIProperty POST_REPLY_DENIED = - new MAPIProperty(0x103f, BINARY, "PostReplyDenied", "PR_POST_REPLY_DENIED"); - public static final MAPIProperty POST_REPLY_FOLDER_ENTRIES = - new MAPIProperty(0x103d, BINARY, "PostReplyFolderEntries", "PR_POST_REPLY_FOLDER_ENTRIES"); - public static final MAPIProperty POST_REPLY_FOLDER_NAMES = - new MAPIProperty(0x103e, ASCII_STRING, "PostReplyFolderNames", "PR_POST_REPLY_FOLDER_NAMES"); - public static final MAPIProperty POSTAL_ADDRESS = - new MAPIProperty(0x3a15, ASCII_STRING, "PostalAddress", "PR_POSTAL_ADDRESS"); - public static final MAPIProperty POSTAL_CODE = - new MAPIProperty(0x3a2a, ASCII_STRING, "PostalCode", "PR_POSTAL_CODE"); - public static final MAPIProperty PREPROCESS = - new MAPIProperty(0xe22, BOOLEAN, "Preprocess", "PR_PREPROCESS"); - public static final MAPIProperty PRIMARY_CAPABILITY = - new MAPIProperty(0x3904, BINARY, "PrimaryCapability", "PR_PRIMARY_CAPABILITY"); - public static final MAPIProperty PRIMARY_FAX_NUMBER = - new MAPIProperty(0x3a23, ASCII_STRING, "PrimaryFaxNumber", "PR_PRIMARY_FAX_NUMBER"); - public static final MAPIProperty PRIMARY_TELEPHONE_NUMBER = - new MAPIProperty(0x3a1a, ASCII_STRING, "PrimaryTelephoneNumber", "PR_PRIMARY_TELEPHONE_NUMBER"); - public static final MAPIProperty PRIORITY = - new MAPIProperty(0x26, LONG, "Priority", "PR_PRIORITY"); - public static final MAPIProperty PROFESSION = - new MAPIProperty(0x3a46, ASCII_STRING, "Profession", "PR_PROFESSION"); - public static final MAPIProperty PROFILE_NAME = - new MAPIProperty(0x3d12, ASCII_STRING, "ProfileName", "PR_PROFILE_NAME"); - public static final MAPIProperty PROOF_OF_DELIVERY = - new MAPIProperty(0xc11, BINARY, "ProofOfDelivery", "PR_PROOF_OF_DELIVERY"); - public static final MAPIProperty PROOF_OF_DELIVERY_REQUESTED = - new MAPIProperty(0xc12, BOOLEAN, "ProofOfDeliveryRequested", "PR_PROOF_OF_DELIVERY_REQUESTED"); - public static final MAPIProperty PROOF_OF_SUBMISSION = - new MAPIProperty(0xe26, BINARY, "ProofOfSubmission", "PR_PROOF_OF_SUBMISSION"); - public static final MAPIProperty PROOF_OF_SUBMISSION_REQUESTED = - new MAPIProperty(40, BOOLEAN, "ProofOfSubmissionRequested", "PR_PROOF_OF_SUBMISSION_REQUESTED"); - public static final MAPIProperty PROP_ID_SECURE_MAX = - new MAPIProperty(0x67ff, Types.UNKNOWN, "PropIdSecureMax", "PROP_ID_SECURE_MAX"); - public static final MAPIProperty PROP_ID_SECURE_MIN = - new MAPIProperty(0x67f0, Types.UNKNOWN, "PropIdSecureMin", "PROP_ID_SECURE_MIN"); - public static final MAPIProperty PROVIDER_DISPLAY = - new MAPIProperty(0x3006, ASCII_STRING, "ProviderDisplay", "PR_PROVIDER_DISPLAY"); - public static final MAPIProperty PROVIDER_DLL_NAME = - new MAPIProperty(0x300a, ASCII_STRING, "ProviderDllName", "PR_PROVIDER_DLL_NAME"); - public static final MAPIProperty PROVIDER_ORDINAL = - new MAPIProperty(0x300d, LONG, "ProviderOrdinal", "PR_PROVIDER_ORDINAL"); - public static final MAPIProperty PROVIDER_SUBMIT_TIME = - new MAPIProperty(0x48, TIME, "ProviderSubmitTime", "PR_PROVIDER_SUBMIT_TIME"); - public static final MAPIProperty PROVIDER_UID = - new MAPIProperty(0x300c, BINARY, "ProviderUid", "PR_PROVIDER_UID"); - public static final MAPIProperty PUID = - new MAPIProperty(0x300e, Types.UNKNOWN, "Puid", "PR_PUID"); - public static final MAPIProperty RADIO_TELEPHONE_NUMBER = - new MAPIProperty(0x3a1d, ASCII_STRING, "RadioTelephoneNumber", "PR_RADIO_TELEPHONE_NUMBER"); - public static final MAPIProperty RCVD_REPRESENTING_ADDRTYPE = - new MAPIProperty(0x77, ASCII_STRING, "RcvdRepresentingAddrtype", "PR_RCVD_REPRESENTING_ADDRTYPE"); - public static final MAPIProperty RCVD_REPRESENTING_EMAIL_ADDRESS = - new MAPIProperty(120, ASCII_STRING, "RcvdRepresentingEmailAddress", "PR_RCVD_REPRESENTING_EMAIL_ADDRESS"); - public static final MAPIProperty RCVD_REPRESENTING_ENTRY_ID = - new MAPIProperty(0x43, BINARY, "RcvdRepresentingEntryId", "PR_RCVD_REPRESENTING_ENTRYID"); - public static final MAPIProperty RCVD_REPRESENTING_NAME = - new MAPIProperty(0x44, ASCII_STRING, "RcvdRepresentingName", "PR_RCVD_REPRESENTING_NAME"); - public static final MAPIProperty RCVD_REPRESENTING_SEARCH_KEY = - new MAPIProperty(0x52, BINARY, "RcvdRepresentingSearchKey", "PR_RCVD_REPRESENTING_SEARCH_KEY"); - public static final MAPIProperty READ_RECEIPT_ENTRY_ID = - new MAPIProperty(70, BINARY, "ReadReceiptEntryId", "PR_READ_RECEIPT_ENTRYID"); - public static final MAPIProperty READ_RECEIPT_REQUESTED = - new MAPIProperty(0x29, BOOLEAN, "ReadReceiptRequested", "PR_READ_RECEIPT_REQUESTED"); - public static final MAPIProperty READ_RECEIPT_SEARCH_KEY = - new MAPIProperty(0x53, BINARY, "ReadReceiptSearchKey", "PR_READ_RECEIPT_SEARCH_KEY"); - public static final MAPIProperty RECEIPT_TIME = - new MAPIProperty(0x2a, TIME, "ReceiptTime", "PR_RECEIPT_TIME"); - public static final MAPIProperty RECEIVE_FOLDER_SETTINGS = - new MAPIProperty(0x3415, DIRECTORY, "ReceiveFolderSettings", "PR_RECEIVE_FOLDER_SETTINGS"); - public static final MAPIProperty RECEIVED_BY_ADDRTYPE = - new MAPIProperty(0x75, ASCII_STRING, "ReceivedByAddrtype", "PR_RECEIVED_BY_ADDRTYPE"); - public static final MAPIProperty RECEIVED_BY_EMAIL_ADDRESS = - new MAPIProperty(0x76, ASCII_STRING, "ReceivedByEmailAddress", "PR_RECEIVED_BY_EMAIL_ADDRESS"); - public static final MAPIProperty RECEIVED_BY_ENTRY_ID = - new MAPIProperty(0x3f, BINARY, "ReceivedByEntryId", "PR_RECEIVED_BY_ENTRYID"); - public static final MAPIProperty RECEIVED_BY_NAME = - new MAPIProperty(0x40, ASCII_STRING, "ReceivedByName", "PR_RECEIVED_BY_NAME"); - public static final MAPIProperty RECIPIENT_DISPLAY_NAME = - new MAPIProperty(0x5ff6, Types.UNICODE_STRING, "RecipientDisplayName", null); - public static final MAPIProperty RECIPIENT_ENTRY_ID = - new MAPIProperty(0x5ff7, Types.UNKNOWN, "RecipientEntryId", null); - public static final MAPIProperty RECIPIENT_FLAGS = - new MAPIProperty(0x5ffd, Types.UNKNOWN, "RecipientFlags", null); - public static final MAPIProperty RECEIVED_BY_SEARCH_KEY = - new MAPIProperty(0x51, BINARY, "ReceivedBySearchKey", "PR_RECEIVED_BY_SEARCH_KEY"); - public static final MAPIProperty RECIPIENT_CERTIFICATE = - new MAPIProperty(0xc13, BINARY, "RecipientCertificate", "PR_RECIPIENT_CERTIFICATE"); - public static final MAPIProperty RECIPIENT_NUMBER_FOR_ADVICE = - new MAPIProperty(0xc14, ASCII_STRING, "RecipientNumberForAdvice", "PR_RECIPIENT_NUMBER_FOR_ADVICE"); - public static final MAPIProperty RECIPIENT_REASSIGNMENT_PROHIBITED = - new MAPIProperty(0x2b, BOOLEAN, "RecipientReassignmentProhibited", "PR_RECIPIENT_REASSIGNMENT_PROHIBITED"); - public static final MAPIProperty RECIPIENT_STATUS = - new MAPIProperty(0xe15, LONG, "RecipientStatus", "PR_RECIPIENT_STATUS"); - public static final MAPIProperty RECIPIENT_TYPE = - new MAPIProperty(0xc15, LONG, "RecipientType", "PR_RECIPIENT_TYPE"); - public static final MAPIProperty RECORD_KEY = - new MAPIProperty(0xff9, BINARY, "RecordKey", "PR_RECORD_KEY"); - public static final MAPIProperty REDIRECTION_HISTORY = - new MAPIProperty(0x2c, BINARY, "RedirectionHistory", "PR_REDIRECTION_HISTORY"); - public static final MAPIProperty REFERRED_BY_NAME = - new MAPIProperty(0x3a47, ASCII_STRING, "ReferredByName", "PR_REFERRED_BY_NAME"); - public static final MAPIProperty REGISTERED_MAIL_TYPE = - new MAPIProperty(0xc16, LONG, "RegisteredMailType", "PR_REGISTERED_MAIL_TYPE"); - public static final MAPIProperty RELATED_IPMS = - new MAPIProperty(0x2d, BINARY, "RelatedIpms", "PR_RELATED_IPMS"); - public static final MAPIProperty REMOTE_PROGRESS = - new MAPIProperty(0x3e0b, LONG, "RemoteProgress", "PR_REMOTE_PROGRESS"); - public static final MAPIProperty REMOTE_PROGRESS_TEXT = - new MAPIProperty(0x3e0c, ASCII_STRING, "RemoteProgressText", "PR_REMOTE_PROGRESS_TEXT"); - public static final MAPIProperty REMOTE_VALIDATE_OK = - new MAPIProperty(0x3e0d, BOOLEAN, "RemoteValidateOk", "PR_REMOTE_VALIDATE_OK"); - public static final MAPIProperty RENDERING_POSITION = - new MAPIProperty(0x370b, LONG, "RenderingPosition", "PR_RENDERING_POSITION"); - public static final MAPIProperty REPLY_RECIPIENT_ENTRIES = - new MAPIProperty(0x4f, BINARY, "ReplyRecipientEntries", "PR_REPLY_RECIPIENT_ENTRIES"); - public static final MAPIProperty REPLY_RECIPIENT_NAMES = - new MAPIProperty(80, ASCII_STRING, "ReplyRecipientNames", "PR_REPLY_RECIPIENT_NAMES"); - public static final MAPIProperty REPLY_REQUESTED = - new MAPIProperty(0xc17, BOOLEAN, "ReplyRequested", "PR_REPLY_REQUESTED"); - public static final MAPIProperty REPLY_TIME = - new MAPIProperty(0x30, TIME, "ReplyTime", "PR_REPLY_TIME"); - public static final MAPIProperty REPORT_ENTRY_ID = - new MAPIProperty(0x45, BINARY, "ReportEntryId", "PR_REPORT_ENTRYID"); - public static final MAPIProperty REPORT_NAME = - new MAPIProperty(0x3a, ASCII_STRING, "ReportName", "PR_REPORT_NAME"); - public static final MAPIProperty REPORT_SEARCH_KEY = - new MAPIProperty(0x54, BINARY, "ReportSearchKey", "PR_REPORT_SEARCH_KEY"); - public static final MAPIProperty REPORT_TAG = - new MAPIProperty(0x31, BINARY, "ReportTag", "PR_REPORT_TAG"); - public static final MAPIProperty REPORT_TEXT = - new MAPIProperty(0x1001, ASCII_STRING, "ReportText", "PR_REPORT_TEXT"); - public static final MAPIProperty REPORT_TIME = - new MAPIProperty(50, TIME, "ReportTime", "PR_REPORT_TIME"); - public static final MAPIProperty REPORTING_DL_NAME = - new MAPIProperty(0x1003, BINARY, "ReportingDlName", "PR_REPORTING_DL_NAME"); - public static final MAPIProperty REPORTING_MTA_CERTIFICATE = - new MAPIProperty(0x1004, BINARY, "ReportingMtaCertificate", "PR_REPORTING_MTA_CERTIFICATE"); - public static final MAPIProperty REQUESTED_DELIVERY_METHOD = - new MAPIProperty(0xc18, LONG, "RequestedDeliveryMethod", "PR_REQUESTED_DELIVERY_METHOD"); - public static final MAPIProperty RESOURCE_FLAGS = - new MAPIProperty(0x3009, LONG, "ResourceFlags", "PR_RESOURCE_FLAGS"); - public static final MAPIProperty RESOURCE_METHODS = - new MAPIProperty(0x3e02, LONG, "ResourceMethods", "PR_RESOURCE_METHODS"); - public static final MAPIProperty RESOURCE_PATH = - new MAPIProperty(0x3e07, ASCII_STRING, "ResourcePath", "PR_RESOURCE_PATH"); - public static final MAPIProperty RESOURCE_TYPE = - new MAPIProperty(0x3e03, LONG, "ResourceType", "PR_RESOURCE_TYPE"); - public static final MAPIProperty RESPONSE_REQUESTED = - new MAPIProperty(0x63, BOOLEAN, "ResponseRequested", "PR_RESPONSE_REQUESTED"); - public static final MAPIProperty RESPONSIBILITY = - new MAPIProperty(0xe0f, BOOLEAN, "Responsibility", "PR_RESPONSIBILITY"); - public static final MAPIProperty RETURNED_IPM = - new MAPIProperty(0x33, BOOLEAN, "ReturnedIpm", "PR_RETURNED_IPM"); - public static final MAPIProperty ROW_TYPE = - new MAPIProperty(0xff5, LONG, "RowType", "PR_ROW_TYPE"); - public static final MAPIProperty ROWID = - new MAPIProperty(0x3000, LONG, "Rowid", "PR_ROWID"); - public static final MAPIProperty RTF_COMPRESSED = - new MAPIProperty(0x1009, BINARY, "RtfCompressed", "PR_RTF_COMPRESSED"); - public static final MAPIProperty RTF_IN_SYNC = - new MAPIProperty(0xe1f, BOOLEAN, "RtfInSync", "PR_RTF_IN_SYNC"); - public static final MAPIProperty RTF_SYNC_BODY_COUNT = - new MAPIProperty(0x1007, LONG, "RtfSyncBodyCount", "PR_RTF_SYNC_BODY_COUNT"); - public static final MAPIProperty RTF_SYNC_BODY_CRC = - new MAPIProperty(0x1006, LONG, "RtfSyncBodyCrc", "PR_RTF_SYNC_BODY_CRC"); - public static final MAPIProperty RTF_SYNC_BODY_TAG = - new MAPIProperty(0x1008, ASCII_STRING, "RtfSyncBodyTag", "PR_RTF_SYNC_BODY_TAG"); - public static final MAPIProperty RTF_SYNC_PREFIX_COUNT = - new MAPIProperty(0x1010, LONG, "RtfSyncPrefixCount", "PR_RTF_SYNC_PREFIX_COUNT"); - public static final MAPIProperty RTF_SYNC_TRAILING_COUNT = - new MAPIProperty(0x1011, LONG, "RtfSyncTrailingCount", "PR_RTF_SYNC_TRAILING_COUNT"); - public static final MAPIProperty SEARCH = - new MAPIProperty(0x3607, DIRECTORY, "Search", "PR_SEARCH"); - public static final MAPIProperty SEARCH_KEY = - new MAPIProperty(0x300b, BINARY, "SearchKey", "PR_SEARCH_KEY"); - public static final MAPIProperty SECURITY = - new MAPIProperty(0x34, LONG, "Security", "PR_SECURITY"); - public static final MAPIProperty SELECTABLE = - new MAPIProperty(0x3609, BOOLEAN, "Selectable", "PR_SELECTABLE"); - public static final MAPIProperty SEND_INTERNET_ENCODING = - new MAPIProperty(0x3a71, LONG, "SendInternetEncoding", "PR_SEND_INTERNET_ENCODING"); - public static final MAPIProperty SEND_RECALL_REPORT = - new MAPIProperty(0x6803, Types.UNKNOWN, "SendRecallReport", "messages"); - public static final MAPIProperty SEND_RICH_INFO = - new MAPIProperty(0x3a40, BOOLEAN, "SendRichInfo", "PR_SEND_RICH_INFO"); - public static final MAPIProperty SENDER_ADDRTYPE = - new MAPIProperty(0xc1e, ASCII_STRING, "SenderAddrtype", "PR_SENDER_ADDRTYPE"); - public static final MAPIProperty SENDER_EMAIL_ADDRESS = - new MAPIProperty(0xc1f, ASCII_STRING, "SenderEmailAddress", "PR_SENDER_EMAIL_ADDRESS"); - public static final MAPIProperty SENDER_ENTRY_ID = - new MAPIProperty(0xc19, BINARY, "SenderEntryId", "PR_SENDER_ENTRYID"); - public static final MAPIProperty SENDER_NAME = - new MAPIProperty(0xc1a, ASCII_STRING, "SenderName", "PR_SENDER_NAME"); - public static final MAPIProperty SENDER_SEARCH_KEY = - new MAPIProperty(0xc1d, BINARY, "SenderSearchKey", "PR_SENDER_SEARCH_KEY"); - public static final MAPIProperty SENSITIVITY = - new MAPIProperty(0x36, LONG, "Sensitivity", "PR_SENSITIVITY"); - public static final MAPIProperty SENT_REPRESENTING_ADDRTYPE = - new MAPIProperty(100, ASCII_STRING, "SentRepresentingAddrtype", "PR_SENT_REPRESENTING_ADDRTYPE"); - public static final MAPIProperty SENT_REPRESENTING_EMAIL_ADDRESS = - new MAPIProperty(0x65, ASCII_STRING, "SentRepresentingEmailAddress", "PR_SENT_REPRESENTING_EMAIL_ADDRESS"); - public static final MAPIProperty SENT_REPRESENTING_ENTRY_ID = - new MAPIProperty(0x41, BINARY, "SentRepresentingEntryId", "PR_SENT_REPRESENTING_ENTRYID"); - public static final MAPIProperty SENT_REPRESENTING_NAME = - new MAPIProperty(0x42, ASCII_STRING, "SentRepresentingName", "PR_SENT_REPRESENTING_NAME"); - public static final MAPIProperty SENT_REPRESENTING_SEARCH_KEY = - new MAPIProperty(0x3b, BINARY, "SentRepresentingSearchKey", "PR_SENT_REPRESENTING_SEARCH_KEY"); - public static final MAPIProperty SENTMAIL_ENTRY_ID = - new MAPIProperty(0xe0a, BINARY, "SentmailEntryId", "PR_SENTMAIL_ENTRYID"); - public static final MAPIProperty SERVICE_DELETE_FILES = - new MAPIProperty(0x3d10, Types.createCustom(4126), "ServiceDeleteFiles", "PR_SERVICE_DELETE_FILES"); - public static final MAPIProperty SERVICE_DLL_NAME = - new MAPIProperty(0x3d0a, ASCII_STRING, "ServiceDllName", "PR_SERVICE_DLL_NAME"); - public static final MAPIProperty SERVICE_ENTRY_NAME = - new MAPIProperty(0x3d0b, ASCII_STRING, "ServiceEntryName", "PR_SERVICE_ENTRY_NAME"); - public static final MAPIProperty SERVICE_EXTRA_UIDS = - new MAPIProperty(0x3d0d, BINARY, "ServiceExtraUids", "PR_SERVICE_EXTRA_UIDS"); - public static final MAPIProperty SERVICE_NAME = - new MAPIProperty(0x3d09, ASCII_STRING, "ServiceName", "PR_SERVICE_NAME"); - public static final MAPIProperty SERVICE_SUPPORT_FILES = - new MAPIProperty(0x3d0f, Types.createCustom(4126), "ServiceSupportFiles", "PR_SERVICE_SUPPORT_FILES"); - public static final MAPIProperty SERVICE_UID = - new MAPIProperty(0x3d0c, BINARY, "ServiceUid", "PR_SERVICE_UID"); - public static final MAPIProperty SERVICES = - new MAPIProperty(0x3d0e, BINARY, "Services", "PR_SERVICES"); - public static final MAPIProperty SEVEN_BIT_DISPLAY_NAME = - new MAPIProperty(0x39ff, ASCII_STRING, "SevenBitDisplayName", "PR_SEVEN_BIT_DISPLAY_NAME"); - public static final MAPIProperty SMTP_ADDRESS = - new MAPIProperty(0x39fe, Types.UNICODE_STRING, "SmtpAddress", "PR_SMTP_ADDRESS"); - public static final MAPIProperty SPOOLER_STATUS = - new MAPIProperty(0xe10, LONG, "SpoolerStatus", "PR_SPOOLER_STATUS"); - public static final MAPIProperty SPOUSE_NAME = - new MAPIProperty(0x3a48, ASCII_STRING, "SpouseName", "PR_SPOUSE_NAME"); - public static final MAPIProperty START_DATE = - new MAPIProperty(0x60, TIME, "StartDate", "PR_START_DATE"); - public static final MAPIProperty STATE_OR_PROVINCE = - new MAPIProperty(0x3a28, ASCII_STRING, "StateOrProvince", "PR_STATE_OR_PROVINCE"); - public static final MAPIProperty STATUS = - new MAPIProperty(0x360b, LONG, "Status", "PR_STATUS"); - public static final MAPIProperty STATUS_CODE = - new MAPIProperty(0x3e04, LONG, "StatusCode", "PR_STATUS_CODE"); - public static final MAPIProperty STATUS_STRING = - new MAPIProperty(0x3e08, ASCII_STRING, "StatusString", "PR_STATUS_STRING"); - public static final MAPIProperty STORE_ENTRY_ID = - new MAPIProperty(0xffb, BINARY, "StoreEntryId", "PR_STORE_ENTRYID"); - public static final MAPIProperty STORE_PROVIDERS = - new MAPIProperty(0x3d00, BINARY, "StoreProviders", "PR_STORE_PROVIDERS"); - public static final MAPIProperty STORE_RECORD_KEY = - new MAPIProperty(0xffa, BINARY, "StoreRecordKey", "PR_STORE_RECORD_KEY"); - public static final MAPIProperty STORE_STATE = - new MAPIProperty(0x340e, LONG, "StoreState", "PR_STORE_STATE"); - public static final MAPIProperty STORE_SUPPORT_MASK = - new MAPIProperty(0x340d, LONG, "StoreSupportMask", "PR_STORE_SUPPORT_MASK"); - public static final MAPIProperty STREET_ADDRESS = - new MAPIProperty(0x3a29, ASCII_STRING, "StreetAddress", "PR_STREET_ADDRESS"); - public static final MAPIProperty SUBFOLDERS = - new MAPIProperty(0x360a, BOOLEAN, "Subfolders", "PR_SUBFOLDERS"); - public static final MAPIProperty SUBJECT = - new MAPIProperty(0x37, ASCII_STRING, "Subject", "PR_SUBJECT"); - public static final MAPIProperty SUBJECT_IPM = - new MAPIProperty(0x38, BINARY, "SubjectIpm", "PR_SUBJECT_IPM"); - public static final MAPIProperty SUBJECT_PREFIX = - new MAPIProperty(0x3d, ASCII_STRING, "SubjectPrefix", "PR_SUBJECT_PREFIX"); - public static final MAPIProperty SUBMIT_FLAGS = - new MAPIProperty(0xe14, LONG, "SubmitFlags", "PR_SUBMIT_FLAGS"); - public static final MAPIProperty SUPERSEDES = - new MAPIProperty(0x103a, ASCII_STRING, "Supersedes", "PR_SUPERSEDES"); - public static final MAPIProperty SUPPLEMENTARY_INFO = - new MAPIProperty(0xc1b, ASCII_STRING, "SupplementaryInfo", "PR_SUPPLEMENTARY_INFO"); - public static final MAPIProperty SURNAME = - new MAPIProperty(0x3a11, ASCII_STRING, "Surname", "PR_SURNAME"); - public static final MAPIProperty TELEX_NUMBER = - new MAPIProperty(0x3a2c, ASCII_STRING, "TelexNumber", "PR_TELEX_NUMBER"); - public static final MAPIProperty TEMPLATEID = - new MAPIProperty(0x3902, BINARY, "Templateid", "PR_TEMPLATEID"); - public static final MAPIProperty TITLE = - new MAPIProperty(0x3a17, ASCII_STRING, "Title", "PR_TITLE"); - public static final MAPIProperty TNEF_CORRELATION_KEY = - new MAPIProperty(0x7f, BINARY, "TnefCorrelationKey", "PR_TNEF_CORRELATION_KEY"); - public static final MAPIProperty TRANSMITABLE_DISPLAY_NAME = - new MAPIProperty(0x3a20, ASCII_STRING, "TransmitableDisplayName", "PR_TRANSMITABLE_DISPLAY_NAME"); - public static final MAPIProperty TRANSPORT_KEY = - new MAPIProperty(0xe16, LONG, "TransportKey", "PR_TRANSPORT_KEY"); - public static final MAPIProperty TRANSPORT_MESSAGE_HEADERS = - new MAPIProperty(0x7d, ASCII_STRING, "TransportMessageHeaders", "PR_TRANSPORT_MESSAGE_HEADERS"); - public static final MAPIProperty TRANSPORT_PROVIDERS = - new MAPIProperty(0x3d02, BINARY, "TransportProviders", "PR_TRANSPORT_PROVIDERS"); - public static final MAPIProperty TRANSPORT_STATUS = - new MAPIProperty(0xe11, LONG, "TransportStatus", "PR_TRANSPORT_STATUS"); - public static final MAPIProperty TTYTDD_PHONE_NUMBER = - new MAPIProperty(0x3a4b, ASCII_STRING, "TtytddPhoneNumber", "PR_TTYTDD_PHONE_NUMBER"); - public static final MAPIProperty TYPE_OF_MTS_USER = - new MAPIProperty(0xc1c, LONG, "TypeOfMtsUser", "PR_TYPE_OF_MTS_USER"); - public static final MAPIProperty USER_CERTIFICATE = - new MAPIProperty(0x3a22, BINARY, "UserCertificate", "PR_USER_CERTIFICATE"); - public static final MAPIProperty USER_X509_CERTIFICATE = - new MAPIProperty(0x3a70, Types.createCustom(4354), "UserX509Certificate", "PR_USER_X509_CERTIFICATE"); - public static final MAPIProperty VALID_FOLDER_MASK = - new MAPIProperty(0x35df, LONG, "ValidFolderMask", "PR_VALID_FOLDER_MASK"); - public static final MAPIProperty VIEWS_ENTRY_ID = - new MAPIProperty(0x35e5, BINARY, "ViewsEntryId", "PR_VIEWS_ENTRYID"); - public static final MAPIProperty WEDDING_ANNIVERSARY = - new MAPIProperty(0x3a41, TIME, "WeddingAnniversary", "PR_WEDDING_ANNIVERSARY"); - public static final MAPIProperty X400_CONTENT_TYPE = - new MAPIProperty(60, BINARY, "X400ContentType", "PR_X400_CONTENT_TYPE"); - public static final MAPIProperty X400_DEFERRED_DELIVERY_CANCEL = - new MAPIProperty(0x3e09, BOOLEAN, "X400DeferredDeliveryCancel", "PR_X400_DEFERRED_DELIVERY_CANCEL"); - public static final MAPIProperty XPOS = - new MAPIProperty(0x3f05, LONG, "Xpos", "PR_XPOS"); - public static final MAPIProperty YPOS = - new MAPIProperty(0x3f06, LONG, "Ypos", "PR_YPOS"); - - public static final MAPIProperty UNKNOWN = - new MAPIProperty(-1, Types.UNKNOWN, "Unknown", null); - - // 0x8??? ones are outlook specific, and not standard MAPI - // TODO See http://msdn.microsoft.com/en-us/library/ee157150%28v=exchg.80%29 for some - // info on how we might decode them properly in the future - private static final int ID_FIRST_CUSTOM = 0x8000; - private static final int ID_LAST_CUSTOM = 0xFFFE; - - /* --------------------------------------------------------------------- */ - - public final int id; - public final MAPIType usualType; - public final String name; - public final String mapiProperty; - - private MAPIProperty(int id, MAPIType usualType, String name, String mapiProperty) { - this.id = id; - this.usualType = usualType; - this.name = name; - this.mapiProperty = mapiProperty; - - // If it isn't unknown or custom, store it for lookup - if(id == -1 || (id >= ID_FIRST_CUSTOM && id <= ID_LAST_CUSTOM) - || (this instanceof CustomMAPIProperty)) { - // Custom/Unknown, skip - } else { - if(attributes.containsKey(id)) { - throw new IllegalArgumentException( - "Duplicate MAPI Property with ID " + id + " : " + - toString() + " vs " + attributes.get(id).toString() - ); - } - attributes.put(id, this); - } - } - - public String asFileName() { - String str = Integer.toHexString(id).toUpperCase(Locale.ROOT); - while(str.length() < 4) { - str = "0" + str; - } - return str + usualType.asFileEnding(); - } - - public String toString() { - StringBuffer str = new StringBuffer(); - str.append(name); - str.append(" ["); - str.append(id); - str.append("]"); - if(mapiProperty != null) { - str.append(" ("); - str.append(mapiProperty); - str.append(")"); - } - return str.toString(); - } - - public static MAPIProperty get(int id) { - MAPIProperty attr = attributes.get(id); - if(attr != null) { - return attr; - } else { - return UNKNOWN; - } - } - public static Collection getAll() { - return Collections.unmodifiableCollection( attributes.values() ); - } - - public static MAPIProperty createCustom(int id, MAPIType type, String name) { - return new CustomMAPIProperty(id, type, name, null); - } - - private static class CustomMAPIProperty extends MAPIProperty { - private CustomMAPIProperty(int id, MAPIType usualType, String name, String mapiProperty) { - super(id, usualType, name, mapiProperty); - } - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java deleted file mode 100644 index dbf77c51c..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hsmf.datatypes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.poi.util.LittleEndian; - -/** - * A {@link PropertiesChunk} for a Message or Embedded-Message. - * This has a 32 byte header - */ -public class MessagePropertiesChunk extends PropertiesChunk { - private long nextRecipientId; - private long nextAttachmentId; - private long recipientCount; - private long attachmentCount; - - public MessagePropertiesChunk(ChunkGroup parentGroup) { - super(parentGroup); - } - - public long getNextRecipientId() { - return nextRecipientId; - } - public long getNextAttachmentId() { - return nextAttachmentId; - } - - public long getRecipientCount() { - return recipientCount; - } - public long getAttachmentCount() { - return attachmentCount; - } - - @Override - public void readValue(InputStream stream) throws IOException { - // 8 bytes of reserved zeros - LittleEndian.readLong(stream); - - // Nexts and counts - nextRecipientId = LittleEndian.readUInt(stream); - nextAttachmentId = LittleEndian.readUInt(stream); - recipientCount = LittleEndian.readUInt(stream); - attachmentCount = LittleEndian.readUInt(stream); - - // 8 bytes of reserved zeros - LittleEndian.readLong(stream); - - // Now properties - readProperties(stream); - } - - @Override - public void writeValue(OutputStream out) throws IOException { - // 8 bytes of reserved zeros - out.write(new byte[8]); - - // Nexts and counts - LittleEndian.putUInt(nextRecipientId, out); - LittleEndian.putUInt(nextAttachmentId, out); - LittleEndian.putUInt(recipientCount, out); - LittleEndian.putUInt(attachmentCount, out); - - // 8 bytes of reserved zeros - out.write(new byte[8]); - - // Now properties - writeProperties(out); - } -} diff --git a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java b/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java deleted file mode 100644 index fa81d55f7..000000000 --- a/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java +++ /dev/null @@ -1,130 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hsmf.datatypes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.Calendar; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.poi.hsmf.datatypes.Types.MAPIType; -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -/** - * A Chunk that holds the details given back by the - * server at submission time. - * This includes the date the message was given to the - * server, and an ID that's used if you want to cancel - * a message or similar - */ -public class MessageSubmissionChunk extends Chunk { - private static POILogger logger = POILogFactory.getLogger(MessageSubmissionChunk.class); - private String rawId; - private Calendar date; - - private static final Pattern datePatern = - Pattern.compile("(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)Z?"); - - /** - * Creates a Byte Chunk. - */ - public MessageSubmissionChunk(String namePrefix, int chunkId, MAPIType type) { - super(namePrefix, chunkId, type); - } - - /** - * Create a Byte Chunk, with the specified - * type. - */ - public MessageSubmissionChunk(int chunkId, MAPIType type) { - super(chunkId, type); - } - - public void readValue(InputStream value) throws IOException { - // Stored in the file as us-ascii - byte[] data = IOUtils.toByteArray(value); - rawId = new String(data, Charset.forName("ASCII")); - - // Now process the date - String[] parts = rawId.split(";"); - for(String part : parts) { - if(part.startsWith("l=")) { - // Format of this bit appears to be l=-
      • - * Note - Excel also gives special treatment to expressions like "0.06-0.01-0.05" which - * evaluates to "0" (in java, rounding anomalies give a result of 6.9E-18). The special - * behaviour here is for different reasons to the example above: If the last operator in a - * cell formula is '+' or '-' and the result is less than 250 times smaller than - * first operand, the result is rounded to zero. - * Needless to say, the two rules are not consistent and it is relatively easy to find - * examples that satisfy
        - * "A=B" is "TRUE" but "A-B" is not "0"
        - * and
        - * "A=B" is "FALSE" but "A-B" is "0"
        - *
        - * This rule (for rounding the result of a final addition or subtraction), has not been - * implemented in POI (as of Jul-2009). - * - * @return negative, 0, or positive according to the standard Excel comparison - * of values a and b. - */ - public static int compare(double a, double b) { - long rawBitsA = Double.doubleToLongBits(a); - long rawBitsB = Double.doubleToLongBits(b); - - int biasedExponentA = getBiasedExponent(rawBitsA); - int biasedExponentB = getBiasedExponent(rawBitsB); - - if (biasedExponentA == BIASED_EXPONENT_SPECIAL_VALUE) { - throw new IllegalArgumentException("Special double values are not allowed: " + toHex(a)); - } - if (biasedExponentB == BIASED_EXPONENT_SPECIAL_VALUE) { - throw new IllegalArgumentException("Special double values are not allowed: " + toHex(a)); - } - - int cmp; - - // sign bit is in the same place for long and double: - boolean aIsNegative = rawBitsA < 0; - boolean bIsNegative = rawBitsB < 0; - - // compare signs - if (aIsNegative != bIsNegative) { - // Excel seems to have 'normal' comparison behaviour around zero (no rounding) - // even -0.0 < +0.0 (which is not quite the initial conclusion of bug 47198) - return aIsNegative ? -1 : +1; - } - - // then compare magnitudes (IEEE 754 has exponent bias specifically to allow this) - cmp = biasedExponentA - biasedExponentB; - int absExpDiff = Math.abs(cmp); - if (absExpDiff > 1) { - return aIsNegative ? -cmp : cmp; - } - - if (absExpDiff == 1) { - // special case exponent differs by 1. There is still a chance that with rounding the two quantities could end up the same - - } else { - // else - sign and exponents equal - if (rawBitsA == rawBitsB) { - // fully equal - exit here - return 0; - } - } - if (biasedExponentA == 0) { - if (biasedExponentB == 0) { - return compareSubnormalNumbers(rawBitsA & FRAC_MASK, rawBitsB & FRAC_MASK, aIsNegative); - } - // else biasedExponentB is 1 - return -compareAcrossSubnormalThreshold(rawBitsB, rawBitsA, aIsNegative); - } - if (biasedExponentB == 0) { - // else biasedExponentA is 1 - return +compareAcrossSubnormalThreshold(rawBitsA, rawBitsB, aIsNegative); - } - - // sign and exponents same, but fractional bits are different - - ExpandedDouble edA = ExpandedDouble.fromRawBitsAndExponent(rawBitsA, biasedExponentA - EXPONENT_BIAS); - ExpandedDouble edB = ExpandedDouble.fromRawBitsAndExponent(rawBitsB, biasedExponentB - EXPONENT_BIAS); - NormalisedDecimal ndA = edA.normaliseBaseTen().roundUnits(); - NormalisedDecimal ndB = edB.normaliseBaseTen().roundUnits(); - cmp = ndA.compareNormalised(ndB); - if (aIsNegative) { - return -cmp; - } - return cmp; - } - - /** - * If both numbers are subnormal, Excel seems to use standard comparison rules - */ - private static int compareSubnormalNumbers(long fracA, long fracB, boolean isNegative) { - int cmp = fracA > fracB ? +1 : fracA < fracB ? -1 : 0; - - return isNegative ? -cmp : cmp; - } - - - - /** - * Usually any normal number is greater (in magnitude) than any subnormal number. - * However there are some anomalous cases around the threshold where Excel produces screwy results - * @param isNegative both values are either negative or positive. This parameter affects the sign of the comparison result - * @return usually isNegative ? -1 : +1 - */ - private static int compareAcrossSubnormalThreshold(long normalRawBitsA, long subnormalRawBitsB, boolean isNegative) { - long fracB = subnormalRawBitsB & FRAC_MASK; - if (fracB == 0) { - // B is zero, so A is definitely greater than B - return isNegative ? -1 : +1; - } - long fracA = normalRawBitsA & FRAC_MASK; - if (fracA <= 0x0000000000000007L && fracB >= 0x000FFFFFFFFFFFFAL) { - // Both A and B close to threshold - weird results - if (fracA == 0x0000000000000007L && fracB == 0x000FFFFFFFFFFFFAL) { - // special case - return 0; - } - // exactly the opposite - return isNegative ? +1 : -1; - } - // else - typical case A and B is not close to threshold - return isNegative ? -1 : +1; - } - - - - /** - * for formatting double values in error messages - */ - private static String toHex(double a) { - return "0x" + Long.toHexString(Double.doubleToLongBits(a)).toUpperCase(Locale.ROOT); - } -} diff --git a/trunk/src/java/org/apache/poi/ss/util/NumberToTextConverter.java b/trunk/src/java/org/apache/poi/ss/util/NumberToTextConverter.java deleted file mode 100644 index c5b8d936b..000000000 --- a/trunk/src/java/org/apache/poi/ss/util/NumberToTextConverter.java +++ /dev/null @@ -1,259 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.util; - - -/** - * Excel converts numbers to text with different rules to those of java, so - * Double.toString(value)
        won't do. - *

    This calls {@link #HSSFWorkbook(InputStream, boolean)} with - * preserve nodes set to true. - * - * @see #HSSFWorkbook(InputStream, boolean) - * @see #HSSFWorkbook(POIFSFileSystem) - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @exception IOException if the stream cannot be read - */ - public HSSFWorkbook(InputStream s) throws IOException { - this(s,true); - } - - /** - * Companion to HSSFWorkbook(POIFSFileSystem), this constructs the - * POI filesystem around your {@link InputStream}. - * - * @param s the POI filesystem that contains the Workbook stream. - * @param preserveNodes whether to preserve other nodes, such as - * macros. This takes more memory, so only say yes if you - * need to. - * @see org.apache.poi.poifs.filesystem.POIFSFileSystem - * @see #HSSFWorkbook(POIFSFileSystem) - * @exception IOException if the stream cannot be read - */ - @SuppressWarnings("resource") // NPOIFSFileSystem always closes the stream - public HSSFWorkbook(InputStream s, boolean preserveNodes) - throws IOException - { - this(new NPOIFSFileSystem(s).getRoot(), preserveNodes); - } - - /** - * used internally to set the workbook properties. - */ - - private void setPropertiesFromWorkbook(InternalWorkbook book) - { - this.workbook = book; - - // none currently - } - - /** - * This is basically a kludge to deal with the now obsolete Label records. If - * you have to read in a sheet that contains Label records, be aware that the rest - * of the API doesn't deal with them, the low level structure only provides read-only - * semi-immutable structures (the sets are there for interface conformance with NO - * Implementation). In short, you need to call this function passing it a reference - * to the Workbook object. All labels will be converted to LabelSST records and their - * contained strings will be written to the Shared String table (SSTRecord) within - * the Workbook. - * - * @param records a collection of sheet's records. - * @param offset the offset to search at - * @see org.apache.poi.hssf.record.LabelRecord - * @see org.apache.poi.hssf.record.LabelSSTRecord - * @see org.apache.poi.hssf.record.SSTRecord - */ - - private void convertLabelRecords(List records, int offset) - { - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "convertLabelRecords called"); - for (int k = offset; k < records.size(); k++) - { - Record rec = records.get(k); - - if (rec.getSid() == LabelRecord.sid) - { - LabelRecord oldrec = ( LabelRecord ) rec; - - records.remove(k); - LabelSSTRecord newrec = new LabelSSTRecord(); - int stringid = - workbook.addSSTString(new UnicodeString(oldrec.getValue())); - - newrec.setRow(oldrec.getRow()); - newrec.setColumn(oldrec.getColumn()); - newrec.setXFIndex(oldrec.getXFIndex()); - newrec.setSSTIndex(stringid); - records.add(k, newrec); - } - } - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "convertLabelRecords exit"); - } - - /** - * Retrieves the current policy on what to do when - * getting missing or blank cells from a row. - * The default is to return blank and null cells. - * {@link MissingCellPolicy} - */ - @Override - public MissingCellPolicy getMissingCellPolicy() { - return missingCellPolicy; - } - - /** - * Sets the policy on what to do when - * getting missing or blank cells from a row. - * This will then apply to all calls to - * {@link HSSFRow#getCell(int)}}. See - * {@link MissingCellPolicy}. - * Note that this has no effect on any - * iterators, only on when fetching Cells - * by their column index. - */ - @Override - public void setMissingCellPolicy(MissingCellPolicy missingCellPolicy) { - this.missingCellPolicy = missingCellPolicy; - } - - /** - * sets the order of appearance for a given sheet. - * - * @param sheetname the name of the sheet to reorder - * @param pos the position that we want to insert the sheet into (0 based) - */ - - @Override - public void setSheetOrder(String sheetname, int pos ) { - int oldSheetIndex = getSheetIndex(sheetname); - _sheets.add(pos,_sheets.remove(oldSheetIndex)); - workbook.setSheetOrder(sheetname, pos); - - FormulaShifter shifter = FormulaShifter.createForSheetShift(oldSheetIndex, pos); - for (HSSFSheet sheet : _sheets) { - sheet.getSheet().updateFormulasAfterCellShift(shifter, /* not used */ -1 ); - } - - workbook.updateNamesAfterCellShift(shifter); - updateNamedRangesAfterSheetReorder(oldSheetIndex, pos); - - updateActiveSheetAfterSheetReorder(oldSheetIndex, pos); - } - - /** - * copy-pasted from XSSFWorkbook#updateNamedRangesAfterSheetReorder(int, int) - * - * update sheet-scoped named ranges in this workbook after changing the sheet order - * of a sheet at oldIndex to newIndex. - * Sheets between these indices will move left or right by 1. - * - * @param oldIndex the original index of the re-ordered sheet - * @param newIndex the new index of the re-ordered sheet - */ - private void updateNamedRangesAfterSheetReorder(int oldIndex, int newIndex) { - // update sheet index of sheet-scoped named ranges - for (final HSSFName name : names) { - final int i = name.getSheetIndex(); - // name has sheet-level scope - if (i != -1) { - // name refers to this sheet - if (i == oldIndex) { - name.setSheetIndex(newIndex); - } - // if oldIndex > newIndex then this sheet moved left and sheets between newIndex and oldIndex moved right - else if (newIndex <= i && i < oldIndex) { - name.setSheetIndex(i+1); - } - // if oldIndex < newIndex then this sheet moved right and sheets between oldIndex and newIndex moved left - else if (oldIndex < i && i <= newIndex) { - name.setSheetIndex(i-1); - } - } - } - } - - - private void updateActiveSheetAfterSheetReorder(int oldIndex, int newIndex) { - // adjust active sheet if necessary - int active = getActiveSheetIndex(); - if(active == oldIndex) { - // moved sheet was the active one - setActiveSheet(newIndex); - } else if ((active < oldIndex && active < newIndex) || - (active > oldIndex && active > newIndex)) { - // not affected - } else if (newIndex > oldIndex) { - // moved sheet was below before and is above now => active is one less - setActiveSheet(active-1); - } else { - // remaining case: moved sheet was higher than active before and is lower now => active is one more - setActiveSheet(active+1); - } - } - - private void validateSheetIndex(int index) { - int lastSheetIx = _sheets.size() - 1; - if (index < 0 || index > lastSheetIx) { - String range = "(0.." + lastSheetIx + ")"; - if (lastSheetIx == -1) { - range = "(no sheets)"; - } - throw new IllegalArgumentException("Sheet index (" - + index +") is out of range " + range); - } - } - - /** - * Selects a single sheet. This may be different to - * the 'active' sheet (which is the sheet with focus). - */ - @Override - public void setSelectedTab(int index) { - - validateSheetIndex(index); - int nSheets = _sheets.size(); - for (int i=0; iindexes. - * - * @param indexes Array of sheets to select, the index is 0-based. - */ - public void setSelectedTabs(int[] indexes) { - Collection list = new ArrayList(indexes.length); - for (int index : indexes) { - list.add(index); - } - setSelectedTabs(list); - } - - /** - * Selects multiple sheets as a group. This is distinct from - * the 'active' sheet (which is the sheet with focus). - * Unselects sheets that are not in indexes. - * - * @param indexes Collection of sheets to select, the index is 0-based. - */ - public void setSelectedTabs(Collection indexes) { - - for (int index : indexes) { - validateSheetIndex(index); - } - // ignore duplicates - Set set = new HashSet(indexes); - int nSheets = _sheets.size(); - for (int i=0; i getSelectedTabs() { - Collection indexes = new ArrayList(); - int nSheets = _sheets.size(); - for (int i=0; inot hide, select or focus sheets. - * It just sets the scroll position in the tab-bar. - * - * @param index the sheet index of the tab that will become the first in the tab-bar - */ - @Override - public void setFirstVisibleTab(int index) { - workbook.getWindowOne().setFirstVisibleTab(index); - } - - /** - * sets the first tab that is displayed in the list of tabs in excel. - */ - @Override - public int getFirstVisibleTab() { - return workbook.getWindowOne().getFirstVisibleTab(); - } - - /** - * Set the sheet name. - * - * @param sheetIx number (0 based) - * @throws IllegalArgumentException if the name is null or invalid - * or workbook already contains a sheet with this name - * @see #createSheet(String) - * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal) - */ - @Override - public void setSheetName(int sheetIx, String name) { - if (name == null) { - throw new IllegalArgumentException("sheetName must not be null"); - } - - if (workbook.doesContainsSheetName(name, sheetIx)) { - throw new IllegalArgumentException("The workbook already contains a sheet named '" + name + "'"); - } - validateSheetIndex(sheetIx); - workbook.setSheetName(sheetIx, name); - } - - /** - * @return Sheet name for the specified index - */ - @Override - public String getSheetName(int sheetIndex) { - validateSheetIndex(sheetIndex); - return workbook.getSheetName(sheetIndex); - } - - @Override - public boolean isHidden() { - return workbook.getWindowOne().getHidden(); - } - - @Override - public void setHidden(boolean hiddenFlag) { - workbook.getWindowOne().setHidden(hiddenFlag); - } - - @Override - public boolean isSheetHidden(int sheetIx) { - validateSheetIndex(sheetIx); - return workbook.isSheetHidden(sheetIx); - } - - @Override - public boolean isSheetVeryHidden(int sheetIx) { - validateSheetIndex(sheetIx); - return workbook.isSheetVeryHidden(sheetIx); - } - - - @Override - public void setSheetHidden(int sheetIx, boolean hidden) { - validateSheetIndex(sheetIx); - workbook.setSheetHidden(sheetIx, hidden); - } - - @Override - public void setSheetHidden(int sheetIx, int hidden) { - validateSheetIndex(sheetIx); - WorkbookUtil.validateSheetState(hidden); - workbook.setSheetHidden(sheetIx, hidden); - } - - /** Returns the index of the sheet by his name - * @param name the sheet name - * @return index of the sheet (0 based) - */ - @Override - public int getSheetIndex(String name){ - return workbook.getSheetIndex(name); - } - - /** Returns the index of the given sheet - * @param sheet the sheet to look up - * @return index of the sheet (0 based). -1 if not found - */ - @Override - public int getSheetIndex(org.apache.poi.ss.usermodel.Sheet sheet) { - for(int i=0; i<_sheets.size(); i++) { - if(_sheets.get(i) == sheet) { - return i; - } - } - return -1; - } - - /** - * create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and returns - * the high level representation. Use this to create new sheets. - * - * @return HSSFSheet representing the new sheet. - */ - - @Override - public HSSFSheet createSheet() - { - HSSFSheet sheet = new HSSFSheet(this); - - _sheets.add(sheet); - workbook.setSheetName(_sheets.size() - 1, "Sheet" + (_sheets.size() - 1)); - boolean isOnlySheet = _sheets.size() == 1; - sheet.setSelected(isOnlySheet); - sheet.setActive(isOnlySheet); - return sheet; - } - - /** - * create an HSSFSheet from an existing sheet in the HSSFWorkbook. - * - * @return HSSFSheet representing the cloned sheet. - */ - - @Override - public HSSFSheet cloneSheet(int sheetIndex) { - validateSheetIndex(sheetIndex); - HSSFSheet srcSheet = _sheets.get(sheetIndex); - String srcName = workbook.getSheetName(sheetIndex); - HSSFSheet clonedSheet = srcSheet.cloneSheet(this); - clonedSheet.setSelected(false); - clonedSheet.setActive(false); - - String name = getUniqueSheetName(srcName); - int newSheetIndex = _sheets.size(); - _sheets.add(clonedSheet); - workbook.setSheetName(newSheetIndex, name); - - // Check this sheet has an autofilter, (which has a built-in NameRecord at workbook level) - int filterDbNameIndex = findExistingBuiltinNameRecordIdx(sheetIndex, NameRecord.BUILTIN_FILTER_DB); - if (filterDbNameIndex != -1) { - NameRecord newNameRecord = workbook.cloneFilter(filterDbNameIndex, newSheetIndex); - HSSFName newName = new HSSFName(this, newNameRecord); - names.add(newName); - } - // TODO - maybe same logic required for other/all built-in name records -// workbook.cloneDrawings(clonedSheet.getSheet()); - - return clonedSheet; - } - - private String getUniqueSheetName(String srcName) { - int uniqueIndex = 2; - String baseName = srcName; - int bracketPos = srcName.lastIndexOf('('); - if (bracketPos > 0 && srcName.endsWith(")")) { - String suffix = srcName.substring(bracketPos + 1, srcName.length() - ")".length()); - try { - uniqueIndex = Integer.parseInt(suffix.trim()); - uniqueIndex++; - baseName=srcName.substring(0, bracketPos).trim(); - } catch (NumberFormatException e) { - // contents of brackets not numeric - } - } - while (true) { - // Try and find the next sheet name that is unique - String index = Integer.toString(uniqueIndex++); - String name; - if (baseName.length() + index.length() + 2 < 31) { - name = baseName + " (" + index + ")"; - } else { - name = baseName.substring(0, 31 - index.length() - 2) + "(" + index + ")"; - } - - //If the sheet name is unique, then set it otherwise move on to the next number. - if (workbook.getSheetIndex(name) == -1) { - return name; - } - } - } - - /** - * Create a new sheet for this Workbook and return the high level representation. - * Use this to create new sheets. - * - *